@runcofactor/cli 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -0
- package/dist/api-catalog-GFGCLVS4.js +401 -0
- package/dist/api-catalog-GFGCLVS4.js.map +1 -0
- package/dist/attachment-SJC7D7FY.js +276 -0
- package/dist/attachment-SJC7D7FY.js.map +1 -0
- package/dist/auth-EN6NQCJY.js +31 -0
- package/dist/auth-EN6NQCJY.js.map +1 -0
- package/dist/bin.js +7 -0
- package/dist/bin.js.map +1 -0
- package/dist/chunk-3CZU7XCS.js +272 -0
- package/dist/chunk-3CZU7XCS.js.map +1 -0
- package/dist/chunk-4NRDONSC.js +1048 -0
- package/dist/chunk-4NRDONSC.js.map +1 -0
- package/dist/chunk-4PNOV7OV.js +51980 -0
- package/dist/chunk-4PNOV7OV.js.map +1 -0
- package/dist/chunk-52IO7ACJ.js +2941 -0
- package/dist/chunk-52IO7ACJ.js.map +1 -0
- package/dist/chunk-6LEZCKKV.js +663 -0
- package/dist/chunk-6LEZCKKV.js.map +1 -0
- package/dist/chunk-A4OFTUVV.js +170 -0
- package/dist/chunk-A4OFTUVV.js.map +1 -0
- package/dist/chunk-B2VISN2V.js +2459 -0
- package/dist/chunk-B2VISN2V.js.map +1 -0
- package/dist/chunk-CLAWT7BJ.js +271 -0
- package/dist/chunk-CLAWT7BJ.js.map +1 -0
- package/dist/chunk-GKY2KXO5.js +281 -0
- package/dist/chunk-GKY2KXO5.js.map +1 -0
- package/dist/chunk-I4QLI3JO.js +413 -0
- package/dist/chunk-I4QLI3JO.js.map +1 -0
- package/dist/chunk-IMPZAX6L.js +180 -0
- package/dist/chunk-IMPZAX6L.js.map +1 -0
- package/dist/chunk-J6SH7GQT.js +241 -0
- package/dist/chunk-J6SH7GQT.js.map +1 -0
- package/dist/chunk-JDBCZ3Z2.js +298 -0
- package/dist/chunk-JDBCZ3Z2.js.map +1 -0
- package/dist/chunk-JICSYFRJ.js +46 -0
- package/dist/chunk-JICSYFRJ.js.map +1 -0
- package/dist/chunk-JWHYXEA2.js +32 -0
- package/dist/chunk-JWHYXEA2.js.map +1 -0
- package/dist/chunk-N7HFALX3.js +88 -0
- package/dist/chunk-N7HFALX3.js.map +1 -0
- package/dist/chunk-Q4BO4Z5V.js +178 -0
- package/dist/chunk-Q4BO4Z5V.js.map +1 -0
- package/dist/chunk-QFDOWABX.js +195 -0
- package/dist/chunk-QFDOWABX.js.map +1 -0
- package/dist/chunk-SJJW77WN.js +605 -0
- package/dist/chunk-SJJW77WN.js.map +1 -0
- package/dist/chunk-VKVL7WBN.js +50 -0
- package/dist/chunk-VKVL7WBN.js.map +1 -0
- package/dist/chunk-WOHL4FTB.js +353 -0
- package/dist/chunk-WOHL4FTB.js.map +1 -0
- package/dist/chunk-XQXVG7RA.js +426 -0
- package/dist/chunk-XQXVG7RA.js.map +1 -0
- package/dist/chunk-ZD3KHESI.js +94 -0
- package/dist/chunk-ZD3KHESI.js.map +1 -0
- package/dist/credential-COLTBV6D.js +450 -0
- package/dist/credential-COLTBV6D.js.map +1 -0
- package/dist/credential-template-EEPYFG7R.js +291 -0
- package/dist/credential-template-EEPYFG7R.js.map +1 -0
- package/dist/debug-workflow-KOVH5GOP.js +259 -0
- package/dist/debug-workflow-KOVH5GOP.js.map +1 -0
- package/dist/dist-44PZR7BQ.js +423 -0
- package/dist/dist-44PZR7BQ.js.map +1 -0
- package/dist/docs-3SSORHB5.js +366 -0
- package/dist/docs-3SSORHB5.js.map +1 -0
- package/dist/doctor-OTSIWV6G.js +132 -0
- package/dist/doctor-OTSIWV6G.js.map +1 -0
- package/dist/feature-flag-T2LRZME3.js +283 -0
- package/dist/feature-flag-T2LRZME3.js.map +1 -0
- package/dist/file-type-S3UUBVCT.js +4205 -0
- package/dist/file-type-S3UUBVCT.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +982 -0
- package/dist/index.js.map +1 -0
- package/dist/init-TGWRECT2.js +208 -0
- package/dist/init-TGWRECT2.js.map +1 -0
- package/dist/install-DXSNWZKO.js +295 -0
- package/dist/install-DXSNWZKO.js.map +1 -0
- package/dist/issues-XIZOPX6T.js +564 -0
- package/dist/issues-XIZOPX6T.js.map +1 -0
- package/dist/knobs-NBINZIUB.js +295 -0
- package/dist/knobs-NBINZIUB.js.map +1 -0
- package/dist/list-3TDHK637.js +59 -0
- package/dist/list-3TDHK637.js.map +1 -0
- package/dist/local-HICVD6PU.js +100 -0
- package/dist/local-HICVD6PU.js.map +1 -0
- package/dist/login-UOIUXVUK.js +315 -0
- package/dist/login-UOIUXVUK.js.map +1 -0
- package/dist/mcp-54IJEOUA.js +1956 -0
- package/dist/mcp-54IJEOUA.js.map +1 -0
- package/dist/pdf-extract-ABWV3L5X.js +13 -0
- package/dist/pdf-extract-ABWV3L5X.js.map +1 -0
- package/dist/pdfjs-DQ2YA5S3.js +41561 -0
- package/dist/pdfjs-DQ2YA5S3.js.map +1 -0
- package/dist/property-UXLOLPTD.js +701 -0
- package/dist/property-UXLOLPTD.js.map +1 -0
- package/dist/property-skill-guide.md +189 -0
- package/dist/psql-BYUUNLGG.js +115 -0
- package/dist/psql-BYUUNLGG.js.map +1 -0
- package/dist/record-4TR2UIIS.js +233 -0
- package/dist/record-4TR2UIIS.js.map +1 -0
- package/dist/redis-35VBUYW7.js +116 -0
- package/dist/redis-35VBUYW7.js.map +1 -0
- package/dist/release-OOLTUBUT.js +354 -0
- package/dist/release-OOLTUBUT.js.map +1 -0
- package/dist/sandbox-XGSUU6G7.js +2046 -0
- package/dist/sandbox-XGSUU6G7.js.map +1 -0
- package/dist/scenarios-GWLJEGHA.js +280 -0
- package/dist/scenarios-GWLJEGHA.js.map +1 -0
- package/dist/session-MYFNZPRP.js +2414 -0
- package/dist/session-MYFNZPRP.js.map +1 -0
- package/dist/skill-KM34LDMO.js +1839 -0
- package/dist/skill-KM34LDMO.js.map +1 -0
- package/dist/skills/debug-run/SKILL.md +262 -0
- package/dist/skills/debug-run/history/1.0.0.md +244 -0
- package/dist/skills/debug-run/history/1.0.1.md +245 -0
- package/dist/skills/debug-run/history/1.0.2.md +254 -0
- package/dist/skills/debug-run/history/1.1.0.md +262 -0
- package/dist/skills/debug-run/version.json +3 -0
- package/dist/spec-RA3CFEKG.js +951 -0
- package/dist/spec-RA3CFEKG.js.map +1 -0
- package/dist/src-LB4HBTJQ.js +1516 -0
- package/dist/src-LB4HBTJQ.js.map +1 -0
- package/dist/src-N3TPKGTY.js +244 -0
- package/dist/src-N3TPKGTY.js.map +1 -0
- package/dist/src-UVDX5UP6.js +17 -0
- package/dist/src-UVDX5UP6.js.map +1 -0
- package/dist/start-PSEQSQA3.js +151 -0
- package/dist/start-PSEQSQA3.js.map +1 -0
- package/dist/tag-YY6YAABQ.js +22 -0
- package/dist/tag-YY6YAABQ.js.map +1 -0
- package/dist/task-IQC3YR5K.js +922 -0
- package/dist/task-IQC3YR5K.js.map +1 -0
- package/dist/test-suite-DZNJFXDW.js +394 -0
- package/dist/test-suite-DZNJFXDW.js.map +1 -0
- package/dist/trace-HXIW7U2D.js +14 -0
- package/dist/trace-HXIW7U2D.js.map +1 -0
- package/dist/triage-ORG45R5W.js +16 -0
- package/dist/triage-ORG45R5W.js.map +1 -0
- package/dist/upgrade-L2VYMP2V.js +61 -0
- package/dist/upgrade-L2VYMP2V.js.map +1 -0
- package/dist/workflow-XYFH5LTP.js +3708 -0
- package/dist/workflow-XYFH5LTP.js.map +1 -0
- package/dist/workflow-cache-NQJQFWMV.js +253 -0
- package/dist/workflow-cache-NQJQFWMV.js.map +1 -0
- package/dist/workflow-debug-BGD4UIXU.js +927 -0
- package/dist/workflow-debug-BGD4UIXU.js.map +1 -0
- package/dist/workflow-proposals-MTUDX46O.js +382 -0
- package/dist/workflow-proposals-MTUDX46O.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/spec/index.ts","../src/spec/sync.ts"],"sourcesContent":["/**\n * `canary spec` subcommand entry points.\n *\n * Subcommands:\n * canary spec validate <file> — parse + lint, exit non-zero on errors\n * canary spec compile <file> — validate, then POST to /workflows/create-with-nodes\n * canary spec pull <id> — reverse: workflow → spec (TODO)\n * canary spec diff <file> <id> — what would compile change? (TODO)\n *\n * @module spec\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport process from 'node:process';\nimport { getArgValue, hasFlag, resolveAppUrl } from '../auth.js';\nimport { fetchOrExit } from '../api-fetch.js';\nimport {\n ApiSequenceFileSchema,\n diffWorkflow,\n emitSpec,\n extractPreservedFrontmatter,\n hasAnyChange,\n lintSpec,\n parseSpec,\n summarize,\n workflowToSpec,\n writeNodeIds,\n writeWorkflowId,\n type DiffResult,\n type LiveWorkflow,\n type PullWorkflow,\n type PullOptions,\n type SpecAst,\n type SpecIssue,\n} from '@chatsdet/canary-spec';\nimport { applyDiff } from './sync.js';\n\nexport async function handleSpec(argv: string[], apiUrl: string, token: string): Promise<void> {\n const sub = argv[0];\n switch (sub) {\n case 'validate':\n await handleValidate(argv.slice(1));\n return;\n case 'compile':\n await handleCompile(argv.slice(1), apiUrl, token);\n return;\n case 'pull':\n await handlePull(argv.slice(1), apiUrl, token);\n return;\n case 'diff':\n await handleDiff(argv.slice(1), apiUrl, token);\n return;\n default:\n printSpecHelp();\n process.exit(sub ? 1 : 0);\n }\n}\n\nfunction printSpecHelp(): void {\n console.log(\n [\n 'Usage: canary spec <subcommand> <file>',\n '',\n 'Subcommands:',\n ' validate <file> Parse + lint the spec offline',\n ' compile <file> Validate, then create the workflow',\n ' diff <file> Preview what `compile` would change (no writes)',\n ' pull <workflow-id> Reverse: workflow → round-trippable .canary.md',\n ' pull --all Sync a directory of specs down from all workflows',\n '',\n 'Compile flags:',\n ' --publish Create as published instead of draft',\n ' --run-and-publish After create, trigger a test run; publish if green',\n ' --allow-duplicate Fresh compile: create even when a same-named workflow exists',\n ' --create-with-duplicate-title',\n ' Alias for --allow-duplicate',\n ' --json Machine-readable output',\n '',\n 'Pull flags:',\n ' --output <path|dir> File (single) or directory (--all); default canary/specs/',\n ' --all Sync every workflow into the directory (add new, update matching by workflowId)',\n ' --status <s> With --all, filter workflows by status (draft|published|…)',\n ' --force Overwrite an existing file (single pull)',\n ].join('\\n')\n );\n}\n\nasync function handleValidate(argv: string[]): Promise<void> {\n const file = argv[0];\n if (!file) {\n console.error('Error: canary spec validate <file>');\n process.exit(1);\n }\n const json = hasFlag(argv, '--json');\n\n const result = await loadAndValidate(file);\n if (json) {\n console.log(\n JSON.stringify(\n {\n ok: result.ok,\n issues: result.issues,\n ...(result.ok ? { workflowName: result.ast.frontmatter.name } : {}),\n },\n null,\n 2\n )\n );\n process.exit(result.ok ? 0 : 1);\n }\n printIssues(result.issues, file);\n if (!result.ok) {\n process.exit(1);\n }\n console.log(`✓ ${file} validates`);\n}\n\nasync function handleCompile(argv: string[], apiUrl: string, token: string): Promise<void> {\n const file = argv[0];\n if (!file) {\n console.error('Error: canary spec compile <file>');\n process.exit(1);\n }\n const result = await loadAndValidate(file);\n printIssues(result.issues, file);\n if (!result.ok) {\n process.exit(1);\n }\n\n const ast = result.ast;\n // Append a default end node only on a fresh create; on recompile (spec\n // already bound to a workflow) suppress it so an end-less workflow doesn't\n // gain a phantom node on every round-trip.\n const emitted = emitSpec(ast, { appendDefaultEnd: !ast.frontmatter.workflowId });\n\n // Load any api_sequence sidecar referenced by a node. Multiple nodes pointing\n // at the same path share one sidecar (DB enforces one api_sequence row per\n // workflow); divergent paths produce a clear error before any state changes.\n try {\n emitted.apiSequenceConfig = await loadApiSequenceSidecar(emitted.nodes, file);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n // Branch: recompile (frontmatter has `workflowId`) vs fresh create.\n if (emitted.workflowId) {\n await runRecompile({ argv, apiUrl, token, file, emitted });\n return;\n }\n\n await runFreshCompile({ argv, apiUrl, token, file, emitted });\n}\n\n/**\n * Resolve and load the api_sequence sidecar(s) referenced by spec nodes.\n *\n * The DB enforces one api_sequence row per workflow, so a single workflow may\n * carry many `nodeType: 'api_sequence'` nodes but they all point at the same\n * sidecar. We accept multiple identical paths but reject divergent ones with\n * a clear error before any state mutation.\n */\nasync function loadApiSequenceSidecar(\n nodes: ReadonlyArray<{ nodeType: string; configJson: Record<string, unknown> }>,\n specFile: string\n): Promise<unknown> {\n const refs = nodes\n .filter((n) => n.nodeType === 'api_sequence')\n .map((n) => n.configJson['__apiSequenceSidecar'])\n .filter((p): p is string => typeof p === 'string' && p.length > 0);\n if (refs.length === 0) return undefined;\n const unique = Array.from(new Set(refs));\n if (unique.length > 1) {\n throw new Error(\n `Spec has divergent api_sequence sidecar paths: ${unique\n .map((p) => `\"${p}\"`)\n .join(', ')}. The DB stores one config per workflow — pick a single path.`\n );\n }\n const sidecarPath = path.resolve(path.dirname(specFile), unique[0]);\n let raw: string;\n try {\n raw = await fs.readFile(sidecarPath, 'utf-8');\n } catch (err) {\n throw new Error(\n `Could not read api_sequence sidecar at ${sidecarPath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n const yaml = await import('yaml');\n let parsed: unknown;\n try {\n parsed = yaml.parse(raw);\n } catch (err) {\n throw new Error(\n `Sidecar YAML at ${sidecarPath} is invalid: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n const validated = ApiSequenceFileSchema.safeParse(parsed);\n if (!validated.success) {\n throw new Error(\n `Sidecar at ${sidecarPath} doesn't match the api_sequence shape: ${validated.error.message}`\n );\n }\n return validated.data;\n}\n\nasync function handleDiff(argv: string[], apiUrl: string, token: string): Promise<void> {\n const file = argv[0];\n if (!file) {\n console.error('Error: canary spec diff <file>');\n process.exit(1);\n }\n const result = await loadAndValidate(file);\n printIssues(result.issues, file);\n if (!result.ok) process.exit(1);\n\n const emitted = emitSpec(result.ast, { appendDefaultEnd: false });\n if (!emitted.workflowId) {\n console.log(\n `ℹ ${file} has no workflowId in frontmatter — \\`canary spec compile\\` would create a new workflow.`\n );\n console.log(` Nodes that would be created: ${emitted.nodes.length}`);\n return;\n }\n\n const liveRes = await fetchOrExit(`${apiUrl}/workflows/${emitted.workflowId}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n token,\n });\n if (!liveRes.ok) {\n console.error(`Error: failed to fetch workflow ${emitted.workflowId} (${liveRes.status})`);\n process.exit(1);\n }\n const liveBody = (await liveRes.json().catch(() => ({}))) as { workflow?: LiveWorkflow };\n const live = liveBody.workflow;\n if (!live) {\n console.error(`Error: workflow ${emitted.workflowId} not found.`);\n process.exit(1);\n }\n\n let diff: DiffResult;\n try {\n diff = diffWorkflow(emitted, live);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify({ ok: true, summary: summarize(diff), diff }, null, 2));\n return;\n }\n\n if (!hasAnyChange(diff)) {\n console.log(`✓ ${file} — in sync with workflow ${emitted.workflowId}`);\n return;\n }\n const s = summarize(diff);\n console.log(`\\nPreview for \"${live.name}\" (${emitted.workflowId}):`);\n console.log(\n ` +${s.created} create · ~${s.updated} update · -${s.deleted} delete · ↻ ${s.moved} move`\n );\n if (diff.nameDrift) console.log(` ✎ rename: \"${diff.nameDrift.from}\" → \"${diff.nameDrift.to}\"`);\n const fieldKeys = Object.keys(diff.workflowFieldChanges).filter((k) => k !== 'name');\n if (fieldKeys.length > 0) console.log(` ✎ workflow fields: ${fieldKeys.join(', ')}`);\n console.log(`\\nRun \\`canary spec compile ${file}\\` to apply.`);\n}\n\nasync function handlePull(argv: string[], apiUrl: string, token: string): Promise<void> {\n if (hasFlag(argv, '--all')) {\n await handlePullAll(argv, apiUrl, token);\n return;\n }\n\n const workflowId = argv.find((a) => !a.startsWith('-'));\n if (!workflowId) {\n console.error('Error: canary spec pull <workflow-id> [--output <path>] [--force]');\n console.error(' canary spec pull --all [--output <dir>] [--status <s>] [--force]');\n process.exit(1);\n }\n const json = hasFlag(argv, '--json');\n const force = hasFlag(argv, '--force');\n\n const live = await fetchWorkflow(apiUrl, token, workflowId);\n if (!live) {\n console.error(`Error: workflow ${workflowId} not found (or no permission).`);\n process.exit(1);\n }\n\n const outPath =\n getArgValue(argv, '--output') ??\n path.join('canary', 'specs', `${slugify(live.name)}.canary.md`);\n\n // Preserve spec-source-only frontmatter from the prior file (requirementRef,\n // scenario skipReason). These have no live equivalent, so a naive overwrite\n // would silently drop the author's notes on re-pull.\n const preserved = await readPreservedFrontmatter(outPath);\n // When the workflow has an api_sequence config, fetch it + write a sidecar\n // file alongside the spec. Pull annotates each api_sequence node in the live\n // workflow with `__apiSequenceSidecar` so `workflowToSpec` can emit the\n // `- apiSequence:` bullet. The sidecar path lives next to the spec under a\n // sibling `sequences/` directory by convention.\n const sidecarPath = await fetchAndWriteApiSequenceSidecar(\n apiUrl,\n token,\n workflowId,\n live,\n outPath\n );\n if (sidecarPath) {\n for (const node of live.nodes) {\n if (node.nodeType === 'api_sequence') {\n node.configJson = {\n ...node.configJson,\n __apiSequenceSidecar: path.relative(path.dirname(outPath), sidecarPath),\n };\n }\n }\n }\n const source = workflowToSpec(live, preserved);\n\n // Validate the round-trip so a malformed pull surfaces immediately.\n const parsed = parseSpec(source);\n const lintIssues = parsed.ok ? lintSpec(parsed.ast) : [];\n const parseIssues = parsed.ok ? [] : parsed.issues;\n const issues = [...parseIssues, ...lintIssues];\n\n if (!force) {\n try {\n await fs.access(outPath);\n console.error(\n `Error: ${outPath} already exists. Use --output <path> or --force to overwrite.`\n );\n process.exit(1);\n } catch {\n // file does not exist — good.\n }\n }\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, source, 'utf-8');\n\n if (json) {\n console.log(JSON.stringify({ ok: true, file: outPath, workflowId, issues }, null, 2));\n return;\n }\n\n console.log(`\\n✓ Pulled \"${live.name}\" → ${outPath}`);\n console.log(` Nodes: ${live.nodes.length}`);\n console.log(` Edit the file, then \\`canary spec compile ${outPath}\\` to push changes back.`);\n if (issues.length > 0) {\n console.log('\\n Notes:');\n printIssues(issues, outPath);\n }\n}\n\n/**\n * `canary spec pull --all` — sync a directory of `.canary.md` files down from\n * the live workflows. Existing files are matched to a workflow by their\n * `workflowId:` frontmatter and rewritten in place; workflows with no matching\n * file get a fresh `<slug>.canary.md`. Files are only written when their\n * content actually changes, so an already-synced repo produces no churn.\n */\nasync function handlePullAll(argv: string[], apiUrl: string, token: string): Promise<void> {\n const json = hasFlag(argv, '--json');\n const dir =\n getArgValue(argv, '--output') ??\n argv.find((a) => !a.startsWith('-')) ??\n path.join('canary', 'specs');\n const status = getArgValue(argv, '--status');\n\n const workflows = await fetchWorkflowList(apiUrl, token, status);\n // Map existing files by their declared workflowId so re-pulls land in place.\n const byWorkflowId = await indexSpecFiles(dir);\n const usedNames = new Set<string>([...byWorkflowId.values()].map((p) => path.basename(p)));\n\n const results: Array<{\n id: string;\n name: string;\n file: string;\n action: 'added' | 'synced' | 'unchanged' | 'failed';\n note?: string;\n }> = [];\n\n for (const wf of workflows) {\n const live = await fetchWorkflow(apiUrl, token, wf.id);\n if (!live) {\n results.push({ id: wf.id, name: wf.name, file: '', action: 'failed', note: 'fetch failed' });\n continue;\n }\n const existing = byWorkflowId.get(wf.id);\n let target: string;\n let isNew = false;\n if (existing) {\n target = existing;\n } else {\n target = path.join(dir, uniqueName(slugify(live.name), wf.id, usedNames));\n usedNames.add(path.basename(target));\n isNew = true;\n }\n\n let prior: string | null = null;\n try {\n prior = await fs.readFile(target, 'utf-8');\n } catch {\n // no prior file\n }\n // Spec-source-only fields (requirementRef, scenario skipReason) have no\n // server-side representation — lift them from the prior file before\n // emitting, so re-pull doesn't drop them.\n const preserved = prior ? extractPreservedFrontmatter(prior) : {};\n const source = workflowToSpec(live, preserved);\n if (prior === source) {\n results.push({ id: wf.id, name: live.name, file: target, action: 'unchanged' });\n continue;\n }\n await fs.mkdir(path.dirname(target), { recursive: true });\n await fs.writeFile(target, source, 'utf-8');\n results.push({ id: wf.id, name: live.name, file: target, action: isNew ? 'added' : 'synced' });\n }\n\n if (json) {\n console.log(JSON.stringify({ ok: true, dir, results }, null, 2));\n return;\n }\n const count = (a: string) => results.filter((r) => r.action === a).length;\n console.log(`\\n✓ Synced ${results.length} workflow(s) → ${dir}`);\n console.log(\n ` +${count('added')} added · ~${count('synced')} synced · =${count('unchanged')} unchanged${count('failed') ? ` · ✗${count('failed')} failed` : ''}`\n );\n for (const r of results) {\n if (r.action === 'unchanged') continue;\n const mark = r.action === 'added' ? '+' : r.action === 'synced' ? '~' : '✗';\n console.log(\n ` ${mark} ${path.relative(process.cwd(), r.file) || r.file}${r.note ? ` (${r.note})` : ''}`\n );\n }\n}\n\n/** Fetch the full live workflow (with nodes + edges) for the diff/pull path. */\n/**\n * Fetch the workflow's api_sequence config (if any) and write it to a sidecar\n * YAML alongside the spec. Returns the absolute path to the sidecar, or null\n * when the workflow doesn't have an api_sequence row.\n *\n * The sidecar filename is derived from the workflow slug and lands in a\n * sibling `sequences/` directory: `canary/specs/sequences/<slug>.yaml`.\n * Re-pull overwrites the file in place.\n */\nasync function fetchAndWriteApiSequenceSidecar(\n apiUrl: string,\n token: string,\n workflowId: string,\n live: PullWorkflow,\n outPath: string\n): Promise<string | null> {\n // Skip when the workflow has no api_sequence nodes.\n if (!live.nodes.some((n) => n.nodeType === 'api_sequence')) return null;\n const res = await fetchOrExit(`${apiUrl}/api-sequences/by-workflow/${workflowId}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n token,\n });\n if (!res.ok) {\n // Workflow may have api_sequence nodes but no row yet (e.g. legacy state);\n // leave the sidecar off so the round-trip stays graceful.\n return null;\n }\n const body = (await res.json().catch(() => ({}))) as { data?: { config?: unknown } };\n const config = body.data?.config;\n if (!config) return null;\n\n const sequencesDir = path.join(path.dirname(outPath), 'sequences');\n const sidecarSlug = slugify(live.name);\n const sidecarPath = path.join(sequencesDir, `${sidecarSlug}.yaml`);\n await fs.mkdir(sequencesDir, { recursive: true });\n const yaml = await import('yaml');\n await fs.writeFile(sidecarPath, yaml.stringify(config), 'utf-8');\n return sidecarPath;\n}\n\n/**\n * Read spec-source-only frontmatter from the prior file at `target` (if any).\n * Returns an empty `PullOptions` when no prior file exists.\n */\nasync function readPreservedFrontmatter(target: string): Promise<PullOptions> {\n try {\n const prior = await fs.readFile(target, 'utf-8');\n return extractPreservedFrontmatter(prior);\n } catch {\n return {};\n }\n}\n\nasync function fetchWorkflow(\n apiUrl: string,\n token: string,\n workflowId: string\n): Promise<PullWorkflow | null> {\n const res = await fetchOrExit(`${apiUrl}/workflows/${workflowId}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n token,\n });\n if (!res.ok) return null;\n const body = (await res.json().catch(() => ({}))) as { workflow?: PullWorkflow };\n return body.workflow ?? null;\n}\n\n/** List workflows (paginated), optionally filtered by status. */\nasync function fetchWorkflowList(\n apiUrl: string,\n token: string,\n status: string | undefined\n): Promise<Array<{ id: string; name: string }>> {\n const out: Array<{ id: string; name: string }> = [];\n let page = 1;\n for (;;) {\n const params = new URLSearchParams({ page: String(page), pageSize: '100' });\n if (status) params.set('status', status);\n const res = await fetchOrExit(`${apiUrl}/workflows?${params.toString()}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n token,\n });\n if (!res.ok) {\n console.error(`Error: failed to list workflows (${res.status})`);\n process.exit(1);\n }\n const body = (await res.json().catch(() => ({}))) as {\n data?: Array<{ id: string; name: string }>;\n pagination?: { page: number; totalPages: number };\n };\n for (const w of body.data ?? []) out.push({ id: w.id, name: w.name });\n const pg = body.pagination;\n if (!pg || pg.page >= pg.totalPages || (body.data ?? []).length === 0) break;\n page += 1;\n }\n return out;\n}\n\n/** Build a map of `workflowId` → spec file path across a directory tree. */\nasync function indexSpecFiles(dir: string): Promise<Map<string, string>> {\n const map = new Map<string, string>();\n let entries: string[];\n try {\n entries = await fs.readdir(dir, { recursive: true });\n } catch {\n return map; // directory doesn't exist yet\n }\n const ID_RE = /^workflowId:\\s*([0-9a-f-]{36})\\s*$/im;\n for (const rel of entries) {\n if (!rel.endsWith('.canary.md')) continue;\n const full = path.join(dir, rel);\n try {\n const src = await fs.readFile(full, 'utf-8');\n const m = ID_RE.exec(src);\n if (m && !map.has(m[1])) map.set(m[1], full);\n } catch {\n // unreadable — skip\n }\n }\n return map;\n}\n\n/** Pick a collision-free filename, disambiguating with a short id when needed. */\nfunction uniqueName(slug: string, workflowId: string, used: Set<string>): string {\n let name = `${slug}.canary.md`;\n if (used.has(name)) name = `${slug}-${workflowId.slice(0, 8)}.canary.md`;\n return name;\n}\n\nasync function runFreshCompile(opts: {\n argv: string[];\n apiUrl: string;\n token: string;\n file: string;\n emitted: ReturnType<typeof emitSpec>;\n}): Promise<void> {\n const { argv, apiUrl, token, file, emitted } = opts;\n\n const duplicateMatches = await fetchFreshCompileDuplicateWorkflows({\n argv,\n apiUrl,\n token,\n workflowName: emitted.name,\n });\n if (duplicateMatches.length > 0) {\n const message = formatDuplicateWorkflowTitleWarning({\n file,\n workflowName: emitted.name,\n matches: duplicateMatches,\n });\n if (hasFlag(argv, '--json')) {\n console.log(\n JSON.stringify(\n {\n ok: false,\n error: 'duplicate_workflow_title',\n message,\n workflows: duplicateMatches,\n },\n null,\n 2\n )\n );\n } else {\n console.error(message);\n }\n process.exit(1);\n }\n\n // `--publish` opts a spec-created flow straight to published (default: draft). Reliability\n // is tracked separately by the workflow's `health` once it starts running in suites.\n const status = hasFlag(argv, '--publish') ? 'published' : (emitted.status ?? 'draft');\n\n const payload: Record<string, unknown> = {\n name: emitted.name,\n description: emitted.description,\n preflight: emitted.preflight,\n cleanup: emitted.cleanup,\n status,\n flowType: emitted.flowType,\n createdVia: 'cli-spec',\n // The route only knows about (nodeType, configJson) — strip our meta.\n nodes: emitted.nodes.map(({ nodeType, configJson }) => ({ nodeType, configJson })),\n ...(emitted.inputsJson.length > 0 ? { inputsJson: emitted.inputsJson } : {}),\n ...(emitted.scenariosJson.length > 0 ? { scenariosJson: emitted.scenariosJson } : {}),\n };\n\n const res = await fetchOrExit(`${apiUrl}/workflows/create-with-nodes`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n token,\n body: JSON.stringify(payload),\n });\n\n const body = (await res.json().catch(() => ({}))) as {\n ok: boolean;\n error?: string;\n warnings?: string[];\n workflow?: { id: string; name: string; status: string };\n nodes?: Array<{ id: string; nodeType: string; orderIndex: number }>;\n };\n\n if (!res.ok || !body.ok || !body.workflow) {\n console.error(`Error: ${body.error ?? `${res.status} ${res.statusText}`}`);\n process.exit(1);\n }\n\n // Write workflowId back to frontmatter + @id comments to each lead-in line.\n // Pair each emitted node with its sourceLine and the corresponding new\n // server-side node UUID (the route returns nodes in orderIndex order).\n const writebackPairs: Array<{ sourceLine: number; nodeId: string }> = [];\n if (body.nodes && body.nodes.length === emitted.nodes.length) {\n for (let i = 0; i < emitted.nodes.length; i++) {\n const sourceLine = emitted.nodes[i].sourceLine;\n if (sourceLine === undefined) continue;\n writebackPairs.push({ sourceLine, nodeId: body.nodes[i].id });\n }\n }\n\n try {\n const source = await fs.readFile(file, 'utf-8');\n const withWorkflowId = writeWorkflowId(source, body.workflow.id);\n // writeWorkflowId may insert a new frontmatter line, shifting all subsequent\n // line numbers by +1. Shift sourceLine accordingly so node @id markers land\n // on the lead-in (not on the blank line before it).\n const lineShift = withWorkflowId.split('\\n').length - source.split('\\n').length;\n const shiftedPairs = writebackPairs.map((p) => ({\n ...p,\n sourceLine: p.sourceLine + lineShift,\n }));\n const next = writeNodeIds(withWorkflowId, shiftedPairs);\n if (next !== source) {\n await fs.writeFile(file, next, 'utf-8');\n }\n } catch (err) {\n console.warn(\n `⚠ Workflow created, but failed to write IDs back to ${file}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify({ ok: true, workflow: body.workflow, writebackPairs }, null, 2));\n return;\n }\n\n const appUrl = resolveAppUrl(apiUrl);\n console.log(`\\n✓ Spec compiled: ${body.workflow.name}`);\n console.log(` ID: ${body.workflow.id}`);\n console.log(` Status: ${body.workflow.status}`);\n console.log(` Nodes: ${body.nodes?.length ?? 0}`);\n console.log(` URL: ${appUrl}/flows/${body.workflow.id}`);\n console.log(` → wrote workflowId + @id markers back to ${file}`);\n if (body.warnings && body.warnings.length > 0) {\n console.log('\\n Warnings:');\n for (const w of body.warnings) console.log(` ⚠ ${w}`);\n }\n\n if (hasFlag(argv, '--run-and-publish')) {\n console.log('\\nℹ --run-and-publish for spec compile is not wired in this MVP. Run:');\n console.log(` canary workflow run ${body.workflow.id} --publish-on-pass`);\n }\n}\n\nexport const DUPLICATE_WORKFLOW_TITLE_ALLOW_FLAGS = [\n '--allow-duplicate',\n '--create-with-duplicate-title',\n] as const;\n\nexport type WorkflowTitleMatch = {\n id: string;\n name: string;\n status?: string;\n flowType?: string;\n};\n\nexport function allowsDuplicateWorkflowTitle(argv: string[]): boolean {\n return DUPLICATE_WORKFLOW_TITLE_ALLOW_FLAGS.some((flag) => hasFlag(argv, flag));\n}\n\nexport function exactWorkflowTitleMatches(\n workflows: ReadonlyArray<WorkflowTitleMatch>,\n workflowName: string\n): WorkflowTitleMatch[] {\n return workflows.filter((workflow) => workflow.name === workflowName);\n}\n\nexport function formatDuplicateWorkflowTitleWarning(opts: {\n file: string;\n workflowName: string;\n matches: ReadonlyArray<WorkflowTitleMatch>;\n}): string {\n const first = opts.matches[0];\n const stampedFile = stampedSpecPath(opts.file);\n const workflowLines = opts.matches\n .map((workflow) => {\n const details = [workflow.status, workflow.flowType].filter(Boolean).join(', ');\n return ` - ${workflow.id}${details ? ` (${details})` : ''}`;\n })\n .join('\\n');\n return [\n `Error: fresh spec compile would create a duplicate workflow named \"${opts.workflowName}\".`,\n '',\n 'Existing workflow(s):',\n workflowLines,\n '',\n 'To update an existing workflow instead, pull a stamped spec, re-apply your edits, then compile it:',\n ` canary spec pull ${first.id} --output ${stampedFile}`,\n ` canary spec compile ${stampedFile}`,\n '',\n 'To intentionally create another workflow with the same title, re-run with:',\n ` canary spec compile ${opts.file} --allow-duplicate`,\n ].join('\\n');\n}\n\nasync function fetchFreshCompileDuplicateWorkflows(opts: {\n argv: string[];\n apiUrl: string;\n token: string;\n workflowName: string;\n}): Promise<WorkflowTitleMatch[]> {\n if (allowsDuplicateWorkflowTitle(opts.argv)) return [];\n const params = new URLSearchParams({\n search: opts.workflowName,\n pageSize: '50',\n });\n const res = await fetchOrExit(`${opts.apiUrl}/workflows?${params.toString()}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${opts.token}` },\n token: opts.token,\n });\n if (!res.ok) {\n console.error(`Error: failed to check for existing workflow titles (${res.status})`);\n process.exit(1);\n }\n const body = (await res.json().catch(() => ({}))) as {\n data?: WorkflowTitleMatch[];\n };\n return exactWorkflowTitleMatches(body.data ?? [], opts.workflowName);\n}\n\nfunction stampedSpecPath(file: string): string {\n if (file.endsWith('.canary.md')) {\n return `${file.slice(0, -'.canary.md'.length)}.stamped.canary.md`;\n }\n return `${file}.stamped.canary.md`;\n}\n\nasync function runRecompile(opts: {\n argv: string[];\n apiUrl: string;\n token: string;\n file: string;\n emitted: ReturnType<typeof emitSpec>;\n}): Promise<void> {\n const { argv, apiUrl, token, file, emitted } = opts;\n const workflowId = emitted.workflowId!;\n\n // 1. Fetch live workflow. GET /workflows/:id returns the workflow with\n // nodes + edges via getWorkflowWithDetails.\n const liveRes = await fetchOrExit(`${apiUrl}/workflows/${workflowId}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n token,\n });\n if (!liveRes.ok) {\n console.error(`Error: failed to fetch workflow ${workflowId} (${liveRes.status})`);\n process.exit(1);\n }\n const liveBody = (await liveRes.json().catch(() => ({}))) as {\n workflow?: LiveWorkflow & { snapshotVersion?: number };\n };\n const live = liveBody.workflow;\n if (!live) {\n console.error(`Error: workflow ${workflowId} not found (or no permission).`);\n process.exit(1);\n }\n\n // 2. Compute the diff.\n let diff: DiffResult;\n try {\n diff = diffWorkflow(emitted, live);\n } catch (err) {\n console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n if (!hasAnyChange(diff)) {\n console.log(`✓ ${file} — no changes (workflow ${workflowId} already in sync)`);\n return;\n }\n\n // 3. Apply.\n const ctx = { apiUrl, token, workflowId };\n const sync = await applyDiff(ctx, diff, emitted, live);\n\n // 4. Write back any new @id comments.\n if (sync.created.length > 0) {\n try {\n const source = await fs.readFile(file, 'utf-8');\n const next = writeNodeIds(source, sync.created);\n if (next !== source) await fs.writeFile(file, next, 'utf-8');\n } catch (err) {\n console.warn(\n `⚠ Recompile applied, but failed to write new @id markers to ${file}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // 5. Summary.\n const s = summarize(diff);\n const appUrl = resolveAppUrl(apiUrl);\n console.log(`\\n✓ Recompiled \"${live.name}\"`);\n console.log(\n ` +${s.created} created · ~${s.updated} updated · -${s.deleted} deleted · ↻ ${s.moved} moved`\n );\n console.log(` URL: ${appUrl}/flows/${workflowId}`);\n if (diff.nameDrift) {\n console.log(` ✎ renamed: \"${diff.nameDrift.from}\" → \"${diff.nameDrift.to}\"`);\n }\n if (live.status === 'published') {\n console.log(\n ` ⚠ workflow is published — changes land on draft state; next publish captures them.`\n );\n }\n if (diff.duplicateSpecIds.length > 0) {\n console.log(\n ` ⚠ duplicate @id in spec (treated as fresh creates): ${diff.duplicateSpecIds.join(', ')}`\n );\n }\n if (diff.orphanedSpecIds.length > 0) {\n console.log(\n ` ⚠ stale @id in spec (no matching node — rebound to new): ${diff.orphanedSpecIds.join(', ')}`\n );\n }\n\n if (hasFlag(argv, '--json')) {\n console.log(JSON.stringify({ ok: true, workflowId, summary: s, diff }, null, 2));\n }\n}\n\ntype LoadResult =\n | { ok: true; ast: SpecAst; issues: SpecIssue[] }\n | { ok: false; issues: SpecIssue[] };\n\nasync function loadAndValidate(file: string): Promise<LoadResult> {\n let source: string;\n try {\n source = await fs.readFile(file, 'utf-8');\n } catch (err) {\n return {\n ok: false,\n issues: [\n {\n severity: 'error',\n message: `Could not read ${file}: ${err instanceof Error ? err.message : String(err)}`,\n },\n ],\n };\n }\n const parsed = parseSpec(source);\n if (!parsed.ok) return { ok: false, issues: parsed.issues };\n const lintIssues = lintSpec(parsed.ast);\n const allIssues = [...lintIssues];\n const hasError = allIssues.some((i) => i.severity === 'error');\n if (hasError) return { ok: false, issues: allIssues };\n return { ok: true, ast: parsed.ast, issues: allIssues };\n}\n\n/** Kebab-case slug for the default pull filename. */\nfunction slugify(name: string): string {\n const slug = name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 60);\n return slug || 'workflow';\n}\n\nfunction printIssues(issues: SpecIssue[], file: string): void {\n if (issues.length === 0) return;\n for (const i of issues) {\n const prefix = i.severity === 'error' ? '✗ error' : '⚠ warn';\n const loc = i.line ? `${file}:${i.line}` : file;\n console.error(`${prefix} ${loc}: ${i.message}`);\n if (i.hint) console.error(` hint: ${i.hint}`);\n }\n}\n\nexport { handleValidate, handleCompile };\n\n// Used by tests.\nexport { emitSpec, lintSpec, parseSpec };\n","/**\n * Apply a DiffResult to a live workflow via the existing REST endpoints\n * (`POST /workflows/:id/nodes`, `PUT /workflows/:id/nodes/:nodeId`,\n * `POST /workflows/:id/nodes/bulk-delete`, edge routes, `PUT /workflows/:id`).\n *\n * Returns the set of `(sourceLine → newNodeId)` pairs the writeback step\n * needs to stamp the spec file with fresh `@id` comments.\n *\n * @module spec/sync\n */\n\nimport { fetchOrExit } from '../api-fetch.js';\nimport {\n reconcileLinearEdges,\n type DiffResult,\n type EmittedWorkflow,\n type LiveEdge,\n type LiveWorkflow,\n type SpecOp,\n type WorkflowFieldChanges,\n} from '@chatsdet/canary-spec';\n\nexport type SyncContext = {\n apiUrl: string;\n token: string;\n workflowId: string;\n};\n\nexport type SyncResult = {\n /** New nodes that were created — caller uses these to write `@id` back to the spec. */\n created: Array<{ sourceLine: number; nodeId: string }>;\n};\n\nexport async function applyDiff(\n ctx: SyncContext,\n diff: DiffResult,\n emitted: EmittedWorkflow,\n live: LiveWorkflow,\n): Promise<SyncResult> {\n // 1. Bulk-delete removed nodes (reconnect: true so adjacent edges heal).\n const deletes = diff.ops.filter((o): o is Extract<SpecOp, { kind: 'delete' }> => o.kind === 'delete');\n if (deletes.length > 0) {\n await postJson(ctx, `/workflows/${ctx.workflowId}/nodes/bulk-delete`, {\n nodeIds: deletes.map((o) => o.nodeId),\n reconnect: true,\n });\n }\n\n // 2. Create new nodes. The route assigns final orderIndex, but we send the\n // desired orderIndex so it lands at the right position. We need final IDs\n // back for both writeback and downstream edge reconciliation.\n const creates = diff.ops.filter((o): o is Extract<SpecOp, { kind: 'create' }> => o.kind === 'create');\n const createdIds = new Map<number, string>(); // specIndex → new node UUID\n const writebackPairs: SyncResult['created'] = [];\n for (const op of creates) {\n const res = await postJson<{ ok?: boolean; node?: { id: string }; error?: string }>(\n ctx,\n `/workflows/${ctx.workflowId}/nodes`,\n {\n nodeType: op.nodeType,\n configJson: op.configJson,\n orderIndex: op.orderIndex,\n },\n );\n const created = res.node;\n if (!created) {\n throw new Error(\n `Failed to create node at orderIndex ${op.orderIndex}: ${res.error ?? JSON.stringify(res)}`,\n );\n }\n createdIds.set(op.specIndex, created.id);\n if (op.sourceLine !== undefined) {\n writebackPairs.push({ sourceLine: op.sourceLine, nodeId: created.id });\n }\n }\n\n // 3. Update existing nodes whose config or orderIndex changed.\n const updates = diff.ops.filter((o): o is Extract<SpecOp, { kind: 'update' }> => o.kind === 'update');\n for (const op of updates) {\n if (!op.changes.configChanged && !op.changes.orderChanged) continue;\n await putJson(ctx, `/workflows/${ctx.workflowId}/nodes/${op.nodeId}`, {\n ...(op.changes.configChanged ? { configJson: op.configJson } : {}),\n ...(op.changes.orderChanged ? { orderIndex: op.orderIndex } : {}),\n });\n }\n\n // 4. Edge reconciliation. Spec authors a single linear default chain; we\n // re-derive the expected edges from final node order and DELETE+POST to\n // converge. Non-default edges (condition then/else) are left alone.\n if (diff.ops.length > 0) {\n const finalNodeIds = computeFinalNodeOrder(diff, live, createdIds);\n const fresh = await getJson<{ workflow?: { edges?: LiveEdge[] } }>(\n ctx,\n `/workflows/${ctx.workflowId}`,\n );\n const liveEdges = fresh.workflow?.edges ?? live.edges ?? [];\n const { ops: edgeOps } = reconcileLinearEdges(finalNodeIds, liveEdges);\n for (const op of edgeOps) {\n if (op.kind === 'delete') {\n await deleteJson(ctx, `/workflows/${ctx.workflowId}/edges/${op.edgeId}`);\n } else {\n await postJson(ctx, `/workflows/${ctx.workflowId}/edges`, {\n sourceNodeId: op.sourceNodeId,\n targetNodeId: op.targetNodeId,\n edgeType: 'default',\n });\n }\n }\n }\n\n // 5. Workflow-level fields. Some fields require name → id resolution against\n // org/property scope (tags, environments, sandboxTemplate); those land in\n // a follow-up PR. Surface a clear error rather than silently dropping the\n // edit, so the author isn't surprised by missing changes.\n rejectUnsupportedFieldEdits(diff.workflowFieldChanges);\n if (Object.keys(diff.workflowFieldChanges).length > 0) {\n const payload = await resolveFieldUpdatePayload(ctx, diff.workflowFieldChanges);\n await putJson(ctx, `/workflows/${ctx.workflowId}`, payload);\n }\n\n // 6. Optional api_sequence DSL upsert. The spec carries the full\n // ApiSequenceConfig in a YAML sidecar referenced from any api_sequence\n // node; here we POST it to `/api-sequences/save`, which upserts the\n // workflow-scoped row keyed by workflowId. Skipping when the sidecar is\n // absent leaves any existing live config untouched (no implicit clear).\n if (emitted.apiSequenceConfig) {\n await postJson(ctx, `/api-sequences/save`, {\n workflowId: ctx.workflowId,\n config: emitted.apiSequenceConfig,\n });\n }\n\n return { created: writebackPairs };\n}\n\n/**\n * Look up a teardown workflow by name in the org. Matches on (name, flowType\n * === 'teardown'); throws when missing so the author gets a clear \"compile the\n * teardown spec first\" message instead of a silent FK clear.\n */\nasync function resolveTeardownWorkflowId(\n ctx: SyncContext,\n specName: string,\n): Promise<string> {\n const res = await getJson<{\n ok?: boolean;\n data?: Array<{ id: string; name: string; flowType: string }>;\n }>(\n ctx,\n `/workflows?search=${encodeURIComponent(specName)}&flowType=teardown&pageSize=50`,\n );\n const match = (res.data ?? []).find(\n (w) => w.name === specName && w.flowType === 'teardown',\n );\n if (!match) {\n throw new Error(\n `Teardown workflow \"${specName}\" not found (flowType=teardown). ` +\n `Compile the teardown spec first so the seed can link to it by name.`,\n );\n }\n return match.id;\n}\n\n/**\n * Map name-form workflow fields to their wire shape. Currently only teardown\n * and seedOutputs need lookup; tags/environments/sandboxTemplate are gated by\n * `rejectUnsupportedFieldEdits` above and never reach here.\n */\nasync function resolveFieldUpdatePayload(\n ctx: SyncContext,\n changes: WorkflowFieldChanges,\n): Promise<Record<string, unknown>> {\n const payload = fieldUpdatePayload(changes);\n // teardownSpec carries the name; the API expects teardownWorkflowId.\n if ('teardownSpec' in payload) {\n const specName = payload.teardownSpec;\n delete payload.teardownSpec;\n if (specName === null) {\n payload.teardownWorkflowId = null;\n } else if (typeof specName === 'string') {\n payload.teardownWorkflowId = await resolveTeardownWorkflowId(ctx, specName);\n }\n }\n // teardownSnapshotVersion: 'latest' → null on the wire (DB convention).\n if ('teardownSnapshotVersion' in payload) {\n if (payload.teardownSnapshotVersion === 'latest') payload.teardownSnapshotVersion = null;\n }\n // seedOutputs: rename to `seedOutputsJson` and resolve propertyName → id.\n // The route's normalizeSeedOutputs accepts entries with propertyId set;\n // we ferry across credentialOutput/attributes verbatim per the diff layer.\n if ('seedOutputs' in payload) {\n const inputRows = payload.seedOutputs as\n | Array<{\n dataKey: string;\n label?: string;\n description?: string;\n propertyName?: string;\n credentialOutput?: unknown;\n attributes?: unknown;\n }>\n | undefined;\n delete payload.seedOutputs;\n if (inputRows) {\n const propIds = await resolvePropertyNameMap(\n ctx,\n Array.from(new Set(inputRows.map((r) => r.propertyName).filter((p): p is string => !!p))),\n );\n payload.seedOutputsJson = inputRows.map((r) => {\n const propertyId = r.propertyName ? propIds.get(r.propertyName) : undefined;\n if (r.propertyName && !propertyId) {\n throw new Error(\n `Declared output \"${r.dataKey}\": property \"${r.propertyName}\" not found in this org.`,\n );\n }\n return {\n dataKey: r.dataKey,\n name: r.dataKey,\n displayLabel: r.label ?? r.dataKey,\n ...(r.description ? { description: r.description } : {}),\n ...(propertyId ? { propertyId } : {}),\n ...(r.credentialOutput !== undefined ? { credentialOutput: r.credentialOutput } : {}),\n ...(r.attributes !== undefined ? { attributes: r.attributes } : {}),\n };\n });\n }\n }\n return payload;\n}\n\n/**\n * Look up property ids by name in a single round trip. Used for seed-output\n * declarations where the spec author writes `property: <name>` and sync needs\n * the propertyId for the wire payload.\n */\nasync function resolvePropertyNameMap(\n ctx: SyncContext,\n names: string[],\n): Promise<Map<string, string>> {\n const out = new Map<string, string>();\n if (names.length === 0) return out;\n const res = await getJson<{\n ok?: boolean;\n data?: Array<{ id: string; name: string }>;\n properties?: Array<{ id: string; name: string }>;\n }>(ctx, `/org/properties`);\n const all = res.data ?? res.properties ?? [];\n for (const want of names) {\n const match = all.find((p) => p.name === want);\n if (match) out.set(want, match.id);\n }\n return out;\n}\n\nexport class UnsupportedFieldEditError extends Error {\n constructor(fields: string[]) {\n super(\n `Editing ${fields.join(', ')} via .canary.md is not supported yet. ` +\n `These fields require name → id resolution that lands in a follow-up. ` +\n `Edit them in the Canary UI for now; the rest of your changes will still apply.`,\n );\n this.name = 'UnsupportedFieldEditError';\n }\n}\n\nexport function rejectUnsupportedFieldEdits(changes: WorkflowFieldChanges): void {\n const unsupported = (['tags', 'environmentConstraints', 'sandboxTemplate'] as const).filter(\n (k) => changes[k] !== undefined,\n );\n if (unsupported.length > 0) throw new UnsupportedFieldEditError(unsupported);\n}\n\n/**\n * Build the final ordered list of node UUIDs after applying the diff —\n * positions correspond to the spec's order, IDs resolved from either the live\n * workflow (for UPDATE) or the new-node map (for CREATE).\n */\nfunction computeFinalNodeOrder(\n diff: DiffResult,\n live: LiveWorkflow,\n createdIds: Map<number, string>,\n): string[] {\n const liveById = new Map(live.nodes.map((n) => [n.id, n] as const));\n const total = diff.ops.filter((o) => o.kind !== 'delete').length;\n const result: string[] = Array.from({ length: total });\n for (const op of diff.ops) {\n if (op.kind === 'create') {\n const id = createdIds.get(op.specIndex);\n if (!id) throw new Error(`Missing created node id for specIndex ${op.specIndex}`);\n result[op.specIndex] = id;\n } else if (op.kind === 'update') {\n if (!liveById.has(op.nodeId)) {\n throw new Error(`UPDATE references nodeId ${op.nodeId} not in live workflow`);\n }\n result[op.specIndex] = op.nodeId;\n }\n }\n return result;\n}\n\nfunction fieldUpdatePayload(changes: WorkflowFieldChanges): Record<string, unknown> {\n // PUT /workflows/:id accepts each field independently; pass through only\n // what changed. Scenario `skipReason` is spec-source-only — the API's\n // `normalizeScenarios` strips it, but stripping here keeps the wire payload\n // honest and the round-trip test deterministic.\n const payload: Record<string, unknown> = {};\n for (const k of Object.keys(changes) as (keyof WorkflowFieldChanges)[]) {\n if (k === 'scenariosJson' && Array.isArray(changes.scenariosJson)) {\n payload.scenariosJson = (changes.scenariosJson as Array<Record<string, unknown>>).map((s) => {\n const { skipReason: _skip, ...rest } = s;\n return rest;\n });\n } else {\n payload[k] = changes[k];\n }\n }\n return payload;\n}\n\nasync function postJson<T = unknown>(\n ctx: SyncContext,\n path: string,\n body: unknown,\n): Promise<T> {\n const res = await fetchOrExit(`${ctx.apiUrl}${path}`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${ctx.token}`,\n 'Content-Type': 'application/json',\n },\n token: ctx.token,\n body: JSON.stringify(body),\n });\n return (await res.json()) as T;\n}\n\nasync function putJson<T = unknown>(\n ctx: SyncContext,\n path: string,\n body: unknown,\n): Promise<T> {\n const res = await fetchOrExit(`${ctx.apiUrl}${path}`, {\n method: 'PUT',\n headers: {\n Authorization: `Bearer ${ctx.token}`,\n 'Content-Type': 'application/json',\n },\n token: ctx.token,\n body: JSON.stringify(body),\n });\n return (await res.json()) as T;\n}\n\nasync function getJson<T = unknown>(ctx: SyncContext, path: string): Promise<T> {\n const res = await fetchOrExit(`${ctx.apiUrl}${path}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${ctx.token}` },\n token: ctx.token,\n });\n return (await res.json()) as T;\n}\n\nasync function deleteJson<T = unknown>(ctx: SyncContext, path: string): Promise<T> {\n const res = await fetchOrExit(`${ctx.apiUrl}${path}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${ctx.token}` },\n token: ctx.token,\n });\n return (await res.json()) as T;\n}\n"],"mappings":"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","names":["path"]}
|