mirror of
https://github.com/openclaw/lobster.git
synced 2026-08-14 00:48:09 +00:00
feat: migrate lobster to TypeScript and oxlint
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@
|
||||
"es2022": true
|
||||
},
|
||||
"rules": {
|
||||
"eslint/no-unused-vars": "error",
|
||||
"eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
|
||||
"eslint/no-undef": "error",
|
||||
"typescript/no-explicit-any": "off"
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||
"lint": "oxlint --tsconfig tsconfig.json src test",
|
||||
"fmt": "oxlint --tsconfig tsconfig.json --fix src test",
|
||||
"test": "pnpm build && node --test dist/test"
|
||||
"test": "pnpm build && node --test dist/test/*.test.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.0.0",
|
||||
|
||||
Generated
+122
@@ -0,0 +1,122 @@
|
||||
lockfileVersion: '9.0'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
specifier: ^22.0.0
|
||||
version: 22.19.7
|
||||
oxlint:
|
||||
specifier: ^0.15.0
|
||||
version: 0.15.15
|
||||
typescript:
|
||||
specifier: ^5.7.0
|
||||
version: 5.9.3
|
||||
|
||||
packages:
|
||||
|
||||
'@oxlint/darwin-arm64@0.15.15':
|
||||
resolution: {integrity: sha512-7GOyGM6D36lUhsOvavAVpF72SycPVG0Enunx0bzv8g0+9TklzOSFN3FJlZjLst14VPdZWujZMLgkQC7tOp+Rwg==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint/darwin-x64@0.15.15':
|
||||
resolution: {integrity: sha512-pbrnYFwMn/fuX0z3IeQ05Nvo/b1zGxjmmWgkrQSDwYHxBxP6NT41hk1pmqkcA+v53xk9wvOa/6vBBI/U30F8Ow==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxlint/linux-arm64-gnu@0.15.15':
|
||||
resolution: {integrity: sha512-QWjG3YVsDlIvDTBUPmtPiyqP34ZQpFJqQh2JO94pBih11lFxQ0IGVMEXDhmW3WdiSFPZSJsZGzWynalM9eg+RA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/linux-arm64-musl@0.15.15':
|
||||
resolution: {integrity: sha512-4W0YsmMSbNzzExOWhk+6zNfmJEmKFqSjFIn8CKLtYFvH8kF6KjoW4/0HNsDNYW5Fz+KOut/2JgkvxAiKH+r0zA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/linux-x64-gnu@0.15.15':
|
||||
resolution: {integrity: sha512-agP3e+eQ6tE5tqN6VI4Uukx2yvjwYFjtrDMcB19J7PmGOaFRwuMuT0sNWK/9guvhuS9aCINNZTi3kEhMy9Qgng==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/linux-x64-musl@0.15.15':
|
||||
resolution: {integrity: sha512-L2qE9NhhUafsJOO4pofLx/0hW5IB0sfJa6bS85q0j+ySaI0f3CxMaAadrZLFSuqHWB3oF18B5yvzaPWsc2ohbQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@oxlint/win32-arm64@0.15.15':
|
||||
resolution: {integrity: sha512-B7f4VAS/E78n8zy6XZlNeyYOtWTel4BJn/22Ap2yEAlNzO34ot8dGfpLk6MqTUWJrRnARwVBVmc3wRVrsOT5yg==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/win32-x64@0.15.15':
|
||||
resolution: {integrity: sha512-ZM9T3/OpaQ3qvrk/VuHO2EQmhNH4cOZdr/b/Ju9VKwBr+ahhqMn3W5srrplWQWxfsb0yd1yBj7iD0jdAps2iLg==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@types/node@22.19.7':
|
||||
resolution: {integrity: sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==}
|
||||
|
||||
oxlint@0.15.15:
|
||||
resolution: {integrity: sha512-oQNc1mAHrrbKiXyKJMGs9VCZfwGfLy7YiQKa4qupi71X/u4xyWqOh36YKXqWOXnmm2y7vfWFpGZlhJPAa9tMqA==}
|
||||
engines: {node: '>=8.*'}
|
||||
hasBin: true
|
||||
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@6.21.0:
|
||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||
|
||||
snapshots:
|
||||
|
||||
'@oxlint/darwin-arm64@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@oxlint/darwin-x64@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@oxlint/linux-arm64-gnu@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@oxlint/linux-arm64-musl@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@oxlint/linux-x64-gnu@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@oxlint/linux-x64-musl@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@oxlint/win32-arm64@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@oxlint/win32-x64@0.15.15':
|
||||
optional: true
|
||||
|
||||
'@types/node@22.19.7':
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
oxlint@0.15.15:
|
||||
optionalDependencies:
|
||||
'@oxlint/darwin-arm64': 0.15.15
|
||||
'@oxlint/darwin-x64': 0.15.15
|
||||
'@oxlint/linux-arm64-gnu': 0.15.15
|
||||
'@oxlint/linux-arm64-musl': 0.15.15
|
||||
'@oxlint/linux-x64-gnu': 0.15.15
|
||||
'@oxlint/linux-x64-musl': 0.15.15
|
||||
'@oxlint/win32-arm64': 0.15.15
|
||||
'@oxlint/win32-x64': 0.15.15
|
||||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
undici-types@6.21.0: {}
|
||||
@@ -74,6 +74,7 @@ async function handleRun({ argv, registry }) {
|
||||
const output = await runPipeline({
|
||||
pipeline,
|
||||
registry,
|
||||
input: [],
|
||||
stdin: process.stdin,
|
||||
stdout: process.stdout,
|
||||
stderr: process.stderr,
|
||||
@@ -223,7 +224,7 @@ async function readVersion() {
|
||||
const { dirname, join } = await import('node:path');
|
||||
|
||||
const here = dirname(fileURLToPath(import.meta.url));
|
||||
const pkgPath = join(here, '..', 'package.json');
|
||||
const pkgPath = join(here, '..', '..', 'package.json');
|
||||
const pkg = JSON.parse(await readFile(pkgPath, 'utf8'));
|
||||
return pkg.version ?? '0.0.0';
|
||||
}
|
||||
@@ -231,25 +232,29 @@ async function readVersion() {
|
||||
async function handleDoctor({ argv, registry }) {
|
||||
const mode = 'tool';
|
||||
const pipeline = "exec --json --shell 'echo [1]'";
|
||||
const output = await (async () => {
|
||||
const output: any = await (async () => {
|
||||
try {
|
||||
const parsed = parsePipeline(pipeline);
|
||||
return await runPipeline({
|
||||
pipeline: parsed,
|
||||
registry,
|
||||
input: [],
|
||||
stdin: process.stdin,
|
||||
stdout: process.stdout,
|
||||
stderr: process.stderr,
|
||||
env: process.env,
|
||||
mode,
|
||||
});
|
||||
} catch (err) {
|
||||
} catch (err: any) {
|
||||
return { error: err };
|
||||
}
|
||||
})();
|
||||
|
||||
if (output?.error) {
|
||||
writeToolEnvelope({ ok: false, error: { type: 'doctor_error', message: output.error?.message ?? String(output.error) } });
|
||||
writeToolEnvelope({
|
||||
ok: false,
|
||||
error: { type: 'doctor_error', message: output.error?.message ?? String(output.error) },
|
||||
});
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
@@ -14,7 +14,7 @@ export const clawdInvokeCommand = {
|
||||
},
|
||||
async run({ input, args, ctx }) {
|
||||
// Drain input: for now we don't stream input into clawd calls.
|
||||
for await (const _ of input) {
|
||||
for await (const _item of input) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export const clawdInvokeCommand = {
|
||||
if (args['args-json']) {
|
||||
try {
|
||||
toolArgs = JSON.parse(String(args['args-json']));
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
throw new Error('clawd.invoke --args-json must be valid JSON');
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ export const clawdInvokeCommand = {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = text ? JSON.parse(text) : null;
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
throw new Error('clawd.invoke expected JSON response');
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export const execCommand = {
|
||||
};
|
||||
|
||||
function runProcess(command, argv, { env, cwd }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
const child = spawn(command, argv, {
|
||||
env,
|
||||
cwd,
|
||||
@@ -1,5 +1,5 @@
|
||||
function parsePredicate(expr) {
|
||||
const m = expr.match(/^([a-zA-Z0-9_\.]+)\s*(==|=|!=|<=|>=|<|>)\s*(.+)$/);
|
||||
const m = expr.match(/^([a-zA-Z0-9_.]+)\s*(==|=|!=|<=|>=|<|>)\s*(.+)$/);
|
||||
if (!m) throw new Error(`Invalid where expression: ${expr}`);
|
||||
const [, path, op, rawValue] = m;
|
||||
|
||||
@@ -7,7 +7,7 @@ export const workflowsListCommand = {
|
||||
},
|
||||
async run({ input }) {
|
||||
// Drain input.
|
||||
for await (const _ of input) {
|
||||
for await (const _item of input) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ export const workflowsRunCommand = {
|
||||
},
|
||||
async run({ input, args, ctx }) {
|
||||
// Drain input.
|
||||
for await (const _ of input) {
|
||||
for await (const _item of input) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import { spawn } from 'node:child_process';
|
||||
* @returns {Promise<{stdout: string, stderr: string}>}
|
||||
*/
|
||||
function runGh(argv, { env, cwd }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
const child = spawn('gh', argv, {
|
||||
env,
|
||||
cwd,
|
||||
@@ -35,7 +35,7 @@ function runGh(argv, { env, cwd }) {
|
||||
child.stdout.on('data', (d) => { stdout += d; });
|
||||
child.stderr.on('data', (d) => { stderr += d; });
|
||||
|
||||
child.on('error', (err) => {
|
||||
child.on('error', (err: any) => {
|
||||
if (err?.code === 'ENOENT') {
|
||||
reject(new Error('gh not found on PATH (install GitHub CLI)'));
|
||||
return;
|
||||
@@ -80,7 +80,7 @@ export function ghPrView(options) {
|
||||
|
||||
async run({ input, ctx }) {
|
||||
// Drain input
|
||||
for await (const _ of input) {
|
||||
for await (const _item of input) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ export function ghPrView(options) {
|
||||
'--json', fields.join(','),
|
||||
];
|
||||
|
||||
const { stdout } = await runGh(argv, { env: ctx.env, cwd: process.cwd() });
|
||||
const { stdout } = (await runGh(argv, { env: ctx.env, cwd: process.cwd() })) as any;
|
||||
|
||||
let parsed;
|
||||
try {
|
||||
@@ -4,14 +4,21 @@
|
||||
|
||||
import { prMonitor, prMonitorNotify } from "./github/pr-monitor.js";
|
||||
|
||||
const recipes = {
|
||||
const recipes: Record<string, any> = {
|
||||
"github.pr.monitor": prMonitor,
|
||||
"github.pr.monitor.notify": prMonitorNotify,
|
||||
};
|
||||
|
||||
export function registerRecipe(fn) {
|
||||
const meta = fn?.meta ?? {};
|
||||
const name = meta.name;
|
||||
if (!name) throw new Error("Recipe is missing meta.name");
|
||||
recipes[name] = fn;
|
||||
}
|
||||
|
||||
export function listRecipes() {
|
||||
return Object.entries(recipes).map(([name, fn]) => {
|
||||
const meta = fn.meta ?? {};
|
||||
const meta: any = (fn as any).meta ?? {};
|
||||
return {
|
||||
name,
|
||||
description: meta.description ?? "",
|
||||
@@ -32,8 +32,8 @@ export class Lobster {
|
||||
/** @type {Array<Function|Object>} */
|
||||
#stages = [];
|
||||
|
||||
/** @type {LobsterOptions} */
|
||||
#options = {};
|
||||
/** @type {any} */
|
||||
#options: any = {} as any;
|
||||
|
||||
/** @type {Object|null} */
|
||||
#meta = null;
|
||||
@@ -42,7 +42,7 @@ export class Lobster {
|
||||
* Create a new Lobster workflow builder
|
||||
* @param {LobsterOptions} [options]
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
constructor(options: any = {}) {
|
||||
this.#options = {
|
||||
env: options.env ?? process.env,
|
||||
stateDir: options.stateDir,
|
||||
@@ -18,7 +18,7 @@
|
||||
* @param {boolean} [options.preview=true] - Include items in approval request
|
||||
* @returns {Object} Stage object with run method
|
||||
*/
|
||||
export function approve(options = {}) {
|
||||
export function approve(options: any = {}) {
|
||||
const prompt = options.prompt ?? 'Approve?';
|
||||
const preview = options.preview !== false;
|
||||
|
||||
@@ -26,7 +26,7 @@ export function approve(options = {}) {
|
||||
type: 'approve',
|
||||
prompt,
|
||||
|
||||
async run({ input, ctx }) {
|
||||
async run({ input, ctx: _ctx }) {
|
||||
// Collect all items
|
||||
const items = [];
|
||||
for await (const item of input) {
|
||||
@@ -72,7 +72,7 @@ function stableStringify(value) {
|
||||
* @param {boolean} [options.changesOnly=false] - If true, suppress output when unchanged
|
||||
* @returns {Object} Stage object with run method
|
||||
*/
|
||||
export function diffLast(key, options = {}) {
|
||||
export function diffLast(key, options: any = {}) {
|
||||
if (!key) throw new Error('diffLast requires a key');
|
||||
|
||||
const changesOnly = options.changesOnly === true;
|
||||
@@ -19,7 +19,7 @@ import { spawn } from 'node:child_process';
|
||||
* @returns {Promise<{stdout: string, stderr: string}>}
|
||||
*/
|
||||
function runProcess(command, argv, { env, cwd }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
const child = spawn(command, argv, {
|
||||
env,
|
||||
cwd,
|
||||
@@ -112,7 +112,7 @@ function parseCommand(cmdString) {
|
||||
* @param {string} [options.cwd] - Working directory
|
||||
* @returns {Object} Stage object with run method
|
||||
*/
|
||||
export function exec(cmdString, options = {}) {
|
||||
export function exec(cmdString, options: any = {}) {
|
||||
const parseJson = options.json !== false;
|
||||
const useShell = options.shell === true;
|
||||
const cwd = options.cwd ?? process.cwd();
|
||||
@@ -123,7 +123,7 @@ export function exec(cmdString, options = {}) {
|
||||
|
||||
async run({ input, ctx }) {
|
||||
// Drain input (exec doesn't use input stream)
|
||||
for await (const _ of input) {
|
||||
for await (const _item of input) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export function stateGet(key) {
|
||||
|
||||
async run({ input, ctx }) {
|
||||
// Drain input
|
||||
for await (const _ of input) {
|
||||
for await (const _item of input) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ export function decodeToken(token) {
|
||||
try {
|
||||
const json = Buffer.from(String(token), 'base64url').toString('utf8');
|
||||
return JSON.parse(json);
|
||||
} catch (err) {
|
||||
} catch (_err) {
|
||||
throw new Error('Invalid token');
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ function runProcess(command, argv, { env, cwd }) {
|
||||
child.stdout.on('data', (d) => { stdout += d; });
|
||||
child.stderr.on('data', (d) => { stderr += d; });
|
||||
|
||||
child.on('error', (err) => {
|
||||
child.on('error', (err: any) => {
|
||||
if (err?.code === 'ENOENT') {
|
||||
reject(new Error('gh not found on PATH (install GitHub CLI)'));
|
||||
return;
|
||||
@@ -97,7 +97,7 @@ export async function runGithubPrMonitorWorkflow({ args, ctx }) {
|
||||
'number,title,url,state,isDraft,mergeable,reviewDecision,author,baseRefName,headRefName,updatedAt',
|
||||
];
|
||||
|
||||
const { stdout } = await runProcess('gh', argv, { env: ctx.env, cwd: process.cwd() });
|
||||
const { stdout } = (await runProcess('gh', argv, { env: ctx.env, cwd: process.cwd() })) as any;
|
||||
|
||||
let current;
|
||||
try {
|
||||
@@ -112,7 +112,7 @@ export async function runGithubPrMonitorWorkflow({ args, ctx }) {
|
||||
return {
|
||||
kind: 'github.pr.monitor',
|
||||
repo,
|
||||
pr: Number(pr),
|
||||
prNumber: Number(pr),
|
||||
key,
|
||||
changed: false,
|
||||
suppressed: true,
|
||||
@@ -125,7 +125,7 @@ export async function runGithubPrMonitorWorkflow({ args, ctx }) {
|
||||
return {
|
||||
kind: 'github.pr.monitor',
|
||||
repo,
|
||||
pr: Number(pr),
|
||||
prNumber: Number(pr),
|
||||
key,
|
||||
changed,
|
||||
summary,
|
||||
@@ -142,7 +142,7 @@ export async function runGithubPrMonitorWorkflow({ args, ctx }) {
|
||||
return {
|
||||
kind: 'github.pr.monitor',
|
||||
repo,
|
||||
pr: Number(pr),
|
||||
prNumber: Number(pr),
|
||||
key,
|
||||
changed,
|
||||
summary,
|
||||
@@ -171,7 +171,7 @@ export async function runGithubPrMonitorNotifyWorkflow({ args, ctx }) {
|
||||
kind: 'github.pr.monitor.notify',
|
||||
changed: Boolean(base.changed),
|
||||
repo: args.repo,
|
||||
pr: Number(args.pr),
|
||||
prNumber: Number(args.pr),
|
||||
message: formatPrChangeMessage({
|
||||
repo: args.repo,
|
||||
pr: Number(args.pr),
|
||||
@@ -29,8 +29,9 @@ test('clawd.invoke posts to /tools/invoke and returns JSON', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise((resolve) => server.listen(0, resolve));
|
||||
const port = server.address().port;
|
||||
await new Promise<void>((resolve) => server.listen(0, () => resolve()));
|
||||
const addr = server.address();
|
||||
const port = typeof addr === "string" || addr == null ? 0 : addr.port;
|
||||
|
||||
try {
|
||||
const registry = createDefaultRegistry();
|
||||
@@ -29,8 +29,9 @@ test('clawd.invoke accepts legacy raw JSON response', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
await new Promise((resolve) => server.listen(0, resolve));
|
||||
const port = server.address().port;
|
||||
await new Promise<void>((resolve) => server.listen(0, () => resolve()));
|
||||
const addr = server.address();
|
||||
const port = typeof addr === "string" || addr == null ? 0 : addr.port;
|
||||
|
||||
try {
|
||||
const registry = createDefaultRegistry();
|
||||
@@ -5,7 +5,10 @@ import path from 'node:path';
|
||||
|
||||
test('doctor returns tool-mode ok with version', () => {
|
||||
const bin = path.join(process.cwd(), 'bin', 'lobster.js');
|
||||
const res = spawnSync('node', [bin, 'doctor'], { encoding: 'utf8' });
|
||||
const res = spawnSync('node', [bin, 'doctor'], {
|
||||
encoding: 'utf8',
|
||||
env: { ...process.env, LOBSTER_STATE_DIR: path.join(process.cwd(), '.tmp-test-state') },
|
||||
});
|
||||
assert.equal(res.status, 0);
|
||||
const out = JSON.parse(res.stdout);
|
||||
assert.equal(out.ok, true);
|
||||
@@ -2,6 +2,8 @@ import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { buildPrChangeSummary } from '../src/workflows/github_pr_monitor.js';
|
||||
|
||||
const build = buildPrChangeSummary as any;
|
||||
|
||||
test('buildPrChangeSummary reports all fields on first snapshot', () => {
|
||||
const after = {
|
||||
number: 1,
|
||||
@@ -16,7 +18,7 @@ test('buildPrChangeSummary reports all fields on first snapshot', () => {
|
||||
headRefName: 'feat',
|
||||
};
|
||||
|
||||
const res = buildPrChangeSummary(null, after);
|
||||
const res = build(null, after);
|
||||
assert.ok(res.changedFields.length > 0);
|
||||
assert.equal(res.changes.title.to, 'A');
|
||||
});
|
||||
@@ -36,7 +38,7 @@ test('buildPrChangeSummary only includes changed fields', () => {
|
||||
};
|
||||
const after = { ...before, title: 'B', updatedAt: 't2' };
|
||||
|
||||
const res = buildPrChangeSummary(before, after);
|
||||
const res = build(before, after);
|
||||
assert.deepEqual(res.changedFields.sort(), ['title', 'updatedAt'].sort());
|
||||
assert.equal(res.changes.title.from, 'A');
|
||||
assert.equal(res.changes.title.to, 'B');
|
||||
@@ -21,6 +21,7 @@ test('resume token roundtrip and resume pipeline continues', async () => {
|
||||
const first = await runPipeline({
|
||||
pipeline,
|
||||
registry,
|
||||
input: [],
|
||||
stdin: process.stdin,
|
||||
stdout: process.stdout,
|
||||
stderr: process.stderr,
|
||||
@@ -47,6 +47,7 @@ test('state.get returns null for missing key', async () => {
|
||||
const output = await runPipeline({
|
||||
pipeline: [{ name: 'state.get', args: { _: ['missing'] }, raw: 'state.get missing' }],
|
||||
registry,
|
||||
input: [],
|
||||
stdin: process.stdin,
|
||||
stdout: process.stdout,
|
||||
stderr: process.stderr,
|
||||
@@ -19,6 +19,7 @@ test('approve halts pipeline in tool mode', async () => {
|
||||
const output = await runPipeline({
|
||||
pipeline,
|
||||
registry,
|
||||
input: [],
|
||||
stdin: process.stdin,
|
||||
stdout: process.stdout,
|
||||
stderr: process.stderr,
|
||||
@@ -10,6 +10,8 @@
|
||||
"declaration": false,
|
||||
"sourceMap": true,
|
||||
"strict": false,
|
||||
"useUnknownInCatchVariables": false,
|
||||
"noImplicitAny": false,
|
||||
"skipLibCheck": true,
|
||||
"noEmitOnError": true
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user