intentdna 1.7.5 → 1.8.1

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.
Files changed (154) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/LICENSE +201 -0
  4. package/README.md +143 -194
  5. package/dist/assets/candidates.d.ts +124 -0
  6. package/dist/assets/candidates.js +1249 -0
  7. package/dist/assets/catalog.d.ts +101 -0
  8. package/dist/assets/catalog.js +311 -0
  9. package/dist/assets/evidence.d.ts +93 -0
  10. package/dist/assets/evidence.js +391 -0
  11. package/dist/assets/index.d.ts +4 -0
  12. package/dist/assets/index.js +4 -0
  13. package/dist/assets/metadata.d.ts +19 -0
  14. package/dist/assets/metadata.js +227 -0
  15. package/dist/cli/commands/assets.d.ts +65 -0
  16. package/dist/cli/commands/assets.js +2871 -0
  17. package/dist/cli/commands/auth.d.ts +322 -0
  18. package/dist/cli/commands/auth.js +1592 -0
  19. package/dist/cli/commands/cloud-auth-guidance.d.ts +2 -0
  20. package/dist/cli/commands/cloud-auth-guidance.js +4 -0
  21. package/dist/cli/commands/cloud.d.ts +1359 -0
  22. package/dist/cli/commands/cloud.js +8364 -0
  23. package/dist/cli/commands/evolve.js +18 -2
  24. package/dist/cli/commands/generate.js +25 -2
  25. package/dist/cli/commands/guard.d.ts +1 -1
  26. package/dist/cli/commands/guard.js +1 -1
  27. package/dist/cli/commands/guide.d.ts +15 -0
  28. package/dist/cli/commands/guide.js +1747 -0
  29. package/dist/cli/commands/init.d.ts +12 -0
  30. package/dist/cli/commands/init.js +95 -60
  31. package/dist/cli/commands/org.d.ts +16 -0
  32. package/dist/cli/commands/org.js +2393 -0
  33. package/dist/cli/commands/release.d.ts +59 -0
  34. package/dist/cli/commands/release.js +716 -0
  35. package/dist/cli/commands/report.d.ts +82 -0
  36. package/dist/cli/commands/report.js +1516 -0
  37. package/dist/cli/commands/run.d.ts +8 -1
  38. package/dist/cli/commands/run.js +129 -57
  39. package/dist/cli/commands/sync.d.ts +8 -1
  40. package/dist/cli/commands/sync.js +436 -141
  41. package/dist/cli/commands/templates.d.ts +64 -0
  42. package/dist/cli/commands/templates.js +2151 -1
  43. package/dist/cli/commands/workflow.d.ts +26 -0
  44. package/dist/cli/commands/workflow.js +3053 -0
  45. package/dist/cli/index.js +703 -36
  46. package/dist/compiler/cascade.js +4 -9
  47. package/dist/compiler/compile.js +1 -0
  48. package/dist/governance/evidence-capture-attribution.d.ts +12 -0
  49. package/dist/governance/evidence-capture-attribution.js +46 -0
  50. package/dist/governance/index.d.ts +2 -0
  51. package/dist/governance/index.js +1 -0
  52. package/dist/hooks/cli.d.ts +9 -0
  53. package/dist/hooks/cli.js +170 -411
  54. package/dist/hooks/enforce.d.ts +1 -0
  55. package/dist/hooks/protocol.d.ts +1 -1
  56. package/dist/hooks/protocol.js +1 -1
  57. package/dist/hooks/state.d.ts +41 -0
  58. package/dist/hooks/state.js +126 -2
  59. package/dist/index.d.ts +3 -0
  60. package/dist/index.js +3 -0
  61. package/dist/mcp/tools-state.js +2 -0
  62. package/dist/organization/index.d.ts +121 -0
  63. package/dist/organization/index.js +413 -0
  64. package/dist/runtime/claude-sync-target.d.ts +49 -0
  65. package/dist/runtime/claude-sync-target.js +280 -0
  66. package/dist/runtime/codex-adapter.d.ts +254 -0
  67. package/dist/runtime/codex-adapter.js +1204 -0
  68. package/dist/runtime/codex-sync-target.d.ts +33 -0
  69. package/dist/runtime/codex-sync-target.js +241 -0
  70. package/dist/runtime/index.d.ts +8 -0
  71. package/dist/runtime/index.js +4 -0
  72. package/dist/runtime/output-artifact-registry.d.ts +1 -1
  73. package/dist/runtime/output-artifact-registry.js +2 -0
  74. package/dist/runtime/settings-adapter.d.ts +1 -1
  75. package/dist/runtime/settings-adapter.js +1 -1
  76. package/dist/runtime/skill-adapter.d.ts +5 -1
  77. package/dist/runtime/skill-adapter.js +164 -39
  78. package/dist/runtime/sync-artifact-registry.d.ts +99 -0
  79. package/dist/runtime/sync-artifact-registry.js +194 -0
  80. package/dist/runtime/sync-target-plan.d.ts +45 -0
  81. package/dist/runtime/sync-target-plan.js +19 -0
  82. package/dist/runtime/verifier.d.ts +51 -0
  83. package/dist/runtime/verifier.js +462 -0
  84. package/dist/schema/controller-registry.d.ts +8 -1
  85. package/dist/schema/controller-registry.js +8 -0
  86. package/dist/schema/types.d.ts +35 -23
  87. package/dist/schema/types.js +10 -1
  88. package/dist/schema/validate.js +22 -22
  89. package/dist/schema/validators/controllers.js +38 -20
  90. package/dist/schema/workflow-authoring-contract.d.ts +29 -0
  91. package/dist/schema/workflow-authoring-contract.js +109 -0
  92. package/dist/schema/yaml-parser.js +18 -0
  93. package/dist/templates/api-backend.dna.yaml +19 -0
  94. package/dist/templates/brainstorming-first.dna.yaml +19 -0
  95. package/dist/templates/code-cleanup.dna.yaml +19 -0
  96. package/dist/templates/code-review-pipeline.dna.yaml +18 -0
  97. package/dist/templates/documentation-writer.dna.yaml +19 -0
  98. package/dist/templates/flutter-behavior-lock.dna.yaml +19 -0
  99. package/dist/templates/flutter-refactoring-rescue.dna.yaml +19 -0
  100. package/dist/templates/flutter-rewrite-diagnosis-review.dna.yaml +210 -0
  101. package/dist/templates/flutter-rewrite-fix-review-loop.dna.yaml +260 -0
  102. package/dist/templates/flutter-rewrite-new.dna.yaml +506 -0
  103. package/dist/templates/flutter-rewrite.dna.yaml +100 -4
  104. package/dist/templates/frontend-quality.dna.yaml +19 -0
  105. package/dist/templates/full-pipeline.dna.yaml +20 -0
  106. package/dist/templates/marketplace.d.ts +92 -0
  107. package/dist/templates/marketplace.js +502 -0
  108. package/dist/templates/metadata.d.ts +25 -0
  109. package/dist/templates/metadata.js +136 -3
  110. package/dist/templates/mobile-dev.dna.yaml +19 -0
  111. package/dist/templates/multi-agent-handoff-coordination.dna.yaml +156 -0
  112. package/dist/templates/multi-perspective-review.dna.yaml +19 -0
  113. package/dist/templates/persistent-executor.dna.yaml +19 -0
  114. package/dist/templates/qa-loop.dna.yaml +18 -0
  115. package/dist/templates/release-evidence-gate.dna.yaml +131 -0
  116. package/dist/templates/requirements-gate.dna.yaml +19 -0
  117. package/dist/templates/research-orchestration.dna.yaml +19 -0
  118. package/dist/templates/root-cause-analysis.dna.yaml +19 -0
  119. package/dist/templates/safe-refactoring.dna.yaml +321 -0
  120. package/dist/templates/secure-dev.dna.yaml +19 -0
  121. package/dist/templates/subagent-parallel.dna.yaml +19 -0
  122. package/dist/templates/systematic-debugging.dna.yaml +19 -0
  123. package/dist/templates/tdd-strict.dna.yaml +19 -0
  124. package/dist/templates/ui-visual-regression-qa.dna.yaml +133 -0
  125. package/dist/templates/workflow-author.dna.yaml +302 -0
  126. package/dist/templates/workflow-blocked-scope-triage.dna.yaml +242 -0
  127. package/dist/templates/workflow-completion-audit.dna.yaml +254 -0
  128. package/dist/templates/workflow-cross-boundary-resource-approval.dna.yaml +249 -0
  129. package/dist/templates/workflow-evidence-review.dna.yaml +198 -0
  130. package/dist/templates/workflow-module-inventory.dna.yaml +257 -0
  131. package/dist/templates/workflow-runtime-smoke-review.dna.yaml +252 -0
  132. package/dist/templates/workflow-verification-command-routing.dna.yaml +278 -0
  133. package/dist/workflow/authoring-packet.d.ts +67 -0
  134. package/dist/workflow/authoring-packet.js +218 -0
  135. package/dist/workflow/draft.d.ts +159 -0
  136. package/dist/workflow/draft.js +800 -0
  137. package/dist/workflow/index.d.ts +3 -0
  138. package/dist/workflow/index.js +3 -0
  139. package/dist/workflow/suggestion-review.d.ts +65 -0
  140. package/dist/workflow/suggestion-review.js +245 -0
  141. package/package.json +1 -1
  142. package/spec/README.md +15 -48
  143. package/spec/codex-adapter-contract.md +176 -0
  144. package/spec/sync-target-plan.md +158 -0
  145. package/spec/workflow-capability-ir.md +153 -0
  146. package/spec/agent-dispatch-fix.md +0 -116
  147. package/spec/control-plane-convergence-handoff-2026-04-24.md +0 -432
  148. package/spec/flutter-rewrite-template-optimization.md +0 -301
  149. package/spec/foundation-hardening.md +0 -178
  150. package/spec/hooks-infra-harness-hardening.md +0 -741
  151. package/spec/multi-config.md +0 -172
  152. package/spec/parallel-isolation.md +0 -268
  153. package/spec/template-version-namespace-fix.md +0 -653
  154. package/spec/workflow-pipeline.md +0 -101
@@ -6,6 +6,7 @@
6
6
  * via `claude -p --agent` child processes.
7
7
  */
8
8
  import type { WorkflowStep, ParallelGroup, TransitionRule } from "../../schema/types.js";
9
+ import type { ConstraintIR } from "../../schema/types.js";
9
10
  export interface RunOptions {
10
11
  dnaFiles: string[];
11
12
  workflowName: string;
@@ -18,6 +19,7 @@ export interface RunOptions {
18
19
  permissionMode?: string;
19
20
  agentsDir?: string;
20
21
  hooksDir?: string;
22
+ projectDir?: string;
21
23
  }
22
24
  export interface StepResult {
23
25
  stepId: string;
@@ -30,6 +32,11 @@ interface StepExecOptions {
30
32
  maxBudget: number;
31
33
  permissionMode: string;
32
34
  logDir: string;
35
+ projectDir: string;
36
+ workflowName: string;
37
+ workflowAsset?: string;
38
+ inputs: Record<string, string>;
39
+ ir: Pick<ConstraintIR, "verifier_policy">;
33
40
  }
34
41
  /**
35
42
  * Replace {{var}} placeholders in a template string.
@@ -45,7 +52,7 @@ export declare function evaluateRunIf(condition: string | null, round: number):
45
52
  * Execute a single workflow step via `claude -p --agent`.
46
53
  * Returns StepResult with pass/fail status.
47
54
  */
48
- export declare function executeStep(step: WorkflowStep, vars: Record<string, string>, opts: StepExecOptions): Promise<StepResult>;
55
+ export declare function executeStep(step: WorkflowStep, vars: Record<string, string>, opts: StepExecOptions, iteration?: number): Promise<StepResult>;
49
56
  /**
50
57
  * Execute a parallel group of steps.
51
58
  */
@@ -7,13 +7,17 @@
7
7
  */
8
8
  import { spawn } from "node:child_process";
9
9
  import { mkdir, writeFile } from "node:fs/promises";
10
- import { join } from "node:path";
10
+ import { join, resolve } from "node:path";
11
11
  import { randomUUID } from "node:crypto";
12
12
  import { loadDNA, compileFromFiles, expandDNAInputFiles } from "../../compiler/index.js";
13
13
  import { cascadeDNA } from "../../compiler/cascade.js";
14
14
  import { compileWorkflow } from "../../compiler/workflow.js";
15
15
  import { compileAllRolesToAgentMD, writeAgentMDFiles, toKebabCase, } from "../../runtime/agent-md.js";
16
16
  import { createCompiledIR, writeCompiledIR } from "../../runtime/plugin-adapter.js";
17
+ import { trustedEvidenceCaptureAttribution } from "../../governance/index.js";
18
+ import { DNAStateManager } from "../../hooks/state-manager.js";
19
+ import { appendEvidenceCaptureEvent, EVIDENCE_CAPTURE_SCHEMA_VERSION, } from "../../hooks/state.js";
20
+ import { runCompletionVerifier, runCheckpointVerifier, } from "../../runtime/verifier.js";
17
21
  // ── Template & Condition Helpers ───────────────────────────
18
22
  /**
19
23
  * Replace {{var}} placeholders in a template string.
@@ -53,65 +57,75 @@ export function evaluateRunIf(condition, round) {
53
57
  * Run checkpoint assertions for a completed step.
54
58
  * Returns true if all checkpoints pass, false if any fail.
55
59
  */
56
- async function runCheckpoints(step) {
60
+ async function runCompletions(step, vars, opts) {
61
+ if (!step.completion)
62
+ return true;
63
+ for (const completion of step.completion) {
64
+ const result = await runCompletionVerifier(completion, opts.ir, {
65
+ projectDir: opts.projectDir,
66
+ variables: vars,
67
+ });
68
+ if (!result.passed) {
69
+ logVerifierFailure("Completion failed", step.id, result);
70
+ return false;
71
+ }
72
+ }
73
+ return true;
74
+ }
75
+ async function runCheckpoints(step, vars, opts) {
57
76
  if (!step.checkpoints)
58
77
  return true;
59
- const assertCommands = {
60
- clean_working_tree: 'git status --porcelain',
61
- lint_passing: 'npm run lint --silent 2>/dev/null',
62
- build_passing: 'npm run build --silent 2>/dev/null',
63
- };
64
78
  for (const cp of step.checkpoints) {
65
79
  const action = cp.action ?? "block";
66
- let passed = false;
67
- try {
68
- if (cp.command) {
69
- // Custom command — must exit 0
70
- await spawnAsync("bash", ["-c", cp.command], "");
71
- passed = true;
72
- }
73
- else if (cp.assert === "clean_working_tree") {
74
- const output = await spawnAsync("git", ["status", "--porcelain"], "");
75
- passed = output.trim() === "";
76
- }
77
- else if (cp.assert === "no_test_regression") {
78
- // Read baselines from .dna/
79
- const { readFile: rf } = await import("node:fs/promises");
80
- const baseline = parseInt(await rf(".dna/test-baseline", "utf-8").catch(() => "0"), 10);
81
- const current = parseInt(await rf(".dna/test-current", "utf-8").catch(() => "0"), 10);
82
- passed = current <= baseline;
83
- }
84
- else if (assertCommands[cp.assert]) {
85
- await spawnAsync("bash", ["-c", assertCommands[cp.assert]], "");
86
- passed = true;
87
- }
88
- else {
89
- log(`Unknown checkpoint assert: ${cp.assert} (step: ${step.id})`);
90
- passed = false;
91
- }
92
- }
93
- catch {
94
- passed = false;
95
- }
96
- if (!passed) {
97
- log(`Checkpoint failed: ${cp.assert} — ${cp.message} (step: ${step.id})`);
80
+ const result = await runCheckpointVerifier(cp, opts.ir, {
81
+ projectDir: opts.projectDir,
82
+ variables: vars,
83
+ });
84
+ if (!result.passed) {
85
+ logVerifierFailure(`Checkpoint failed: ${cp.assert}`, step.id, result);
98
86
  if (action === "block")
99
87
  return false;
100
88
  }
101
89
  }
102
90
  return true;
103
91
  }
92
+ function logVerifierFailure(prefix, stepId, result) {
93
+ const exitCode = result.exit_code === undefined ? "" : ` exit_code=${result.exit_code}`;
94
+ const target = result.target ? ` target=${result.target}` : "";
95
+ const message = result.message ? ` — ${result.message}` : "";
96
+ log(`${prefix}${target}${exitCode}${message} (step: ${stepId})`);
97
+ }
104
98
  // ── Step Execution ─────────────────────────────────────────
99
+ async function recordStepResultEvidence(step, opts, sessionId, status, durationMs) {
100
+ const result = status === "pass" ? "success" : "failure";
101
+ await appendEvidenceCaptureEvent(opts.projectDir, {
102
+ schema_version: EVIDENCE_CAPTURE_SCHEMA_VERSION,
103
+ event_id: `c5:${randomUUID()}`,
104
+ captured_at: new Date().toISOString(),
105
+ project_root: opts.projectDir,
106
+ source: "dna_cli",
107
+ workflow_asset: opts.workflowAsset ?? "unknown",
108
+ workflow_id: opts.workflowName,
109
+ run_id: sessionId,
110
+ step_id: step.id,
111
+ fact: "result",
112
+ summary: `dna run recorded ${result} for workflow step ${step.id}`,
113
+ result,
114
+ duration_ms: durationMs,
115
+ });
116
+ }
105
117
  /**
106
118
  * Execute a single workflow step via `claude -p --agent`.
107
119
  * Returns StepResult with pass/fail status.
108
120
  */
109
- export async function executeStep(step, vars, opts) {
121
+ export async function executeStep(step, vars, opts, iteration = 1) {
110
122
  const start = Date.now();
111
123
  const prompt = substituteTemplate(step.prompt ?? step.description, vars);
112
124
  const agentName = `${opts.agentPrefix}${toKebabCase(step.role)}`;
113
125
  const sessionId = randomUUID();
114
126
  const resultFile = join(opts.logDir, `${step.id}-result.json`);
127
+ const stateManager = new DNAStateManager(opts.projectDir, sessionId);
128
+ let stateWritten = false;
115
129
  const args = [
116
130
  "-p",
117
131
  "--agent",
@@ -128,7 +142,25 @@ export async function executeStep(step, vars, opts) {
128
142
  ];
129
143
  log(`Running step: ${step.id} (agent: ${agentName})`);
130
144
  try {
131
- const output = await spawnAsync("claude", args, prompt);
145
+ try {
146
+ await stateManager.writeWorkflowState({
147
+ active: true,
148
+ workflow_asset: opts.workflowAsset,
149
+ workflow: opts.workflowName,
150
+ current_step: step.id,
151
+ current_role: step.role,
152
+ iteration,
153
+ session_id: sessionId,
154
+ started_at: new Date(start).toISOString(),
155
+ inputs: opts.inputs,
156
+ resolved_variables: vars,
157
+ });
158
+ stateWritten = true;
159
+ }
160
+ catch (error) {
161
+ log(`Workflow evidence state unavailable for ${step.id}; continuing fail-open: ${error instanceof Error ? error.message : String(error)}`);
162
+ }
163
+ const output = await spawnAsync("claude", args, prompt, opts.projectDir);
132
164
  await writeFile(resultFile, output, "utf-8");
133
165
  // Check for error in JSON output
134
166
  let isError = false;
@@ -140,20 +172,44 @@ export async function executeStep(step, vars, opts) {
140
172
  // Non-JSON output → treat as success
141
173
  }
142
174
  const status = isError ? "fail" : "pass";
143
- // Run checkpoints if step passed and has checkpoints defined
175
+ if (status === "pass" && step.completion && step.completion.length > 0) {
176
+ const completionsPassed = await runCompletions(step, vars, opts);
177
+ if (!completionsPassed) {
178
+ const durationMs = Date.now() - start;
179
+ await recordStepResultEvidence(step, opts, sessionId, "fail", durationMs);
180
+ log(`Step ${step.id} COMPLETION_FAIL (${durationMs}ms)`);
181
+ return { stepId: step.id, status: "fail", durationMs, resultFile };
182
+ }
183
+ }
144
184
  if (status === "pass" && step.checkpoints && step.checkpoints.length > 0) {
145
- const checkpointsPassed = await runCheckpoints(step);
185
+ const checkpointsPassed = await runCheckpoints(step, vars, opts);
146
186
  if (!checkpointsPassed) {
147
- log(`Step ${step.id} CHECKPOINT_FAIL (${Date.now() - start}ms)`);
148
- return { stepId: step.id, status: "fail", durationMs: Date.now() - start, resultFile };
187
+ const durationMs = Date.now() - start;
188
+ await recordStepResultEvidence(step, opts, sessionId, "fail", durationMs);
189
+ log(`Step ${step.id} CHECKPOINT_FAIL (${durationMs}ms)`);
190
+ return { stepId: step.id, status: "fail", durationMs, resultFile };
149
191
  }
150
192
  }
151
- log(`Step ${step.id} ${status.toUpperCase()} (${Date.now() - start}ms)`);
152
- return { stepId: step.id, status, durationMs: Date.now() - start, resultFile };
193
+ const durationMs = Date.now() - start;
194
+ await recordStepResultEvidence(step, opts, sessionId, status, durationMs);
195
+ log(`Step ${step.id} ${status.toUpperCase()} (${durationMs}ms)`);
196
+ return { stepId: step.id, status, durationMs, resultFile };
153
197
  }
154
198
  catch {
155
- log(`Step ${step.id} FAIL (process error, ${Date.now() - start}ms)`);
156
- return { stepId: step.id, status: "fail", durationMs: Date.now() - start };
199
+ const durationMs = Date.now() - start;
200
+ await recordStepResultEvidence(step, opts, sessionId, "fail", durationMs);
201
+ log(`Step ${step.id} FAIL (process error, ${durationMs}ms)`);
202
+ return { stepId: step.id, status: "fail", durationMs };
203
+ }
204
+ finally {
205
+ if (stateWritten) {
206
+ try {
207
+ await stateManager.clearWorkflowState();
208
+ }
209
+ catch (error) {
210
+ log(`Workflow evidence state cleanup failed for ${step.id}; continuing fail-open: ${error instanceof Error ? error.message : String(error)}`);
211
+ }
212
+ }
157
213
  }
158
214
  }
159
215
  /**
@@ -180,13 +236,13 @@ export async function executeGroup(group, allSteps, round, vars, opts) {
180
236
  return results.filter((r) => r.status === "skipped");
181
237
  // Single step: sequential
182
238
  if (executable.length === 1) {
183
- const result = await executeStep(executable[0], vars, opts);
239
+ const result = await executeStep(executable[0], vars, opts, round);
184
240
  const skipped = results.filter((r) => r.status === "skipped");
185
241
  return [...skipped, result];
186
242
  }
187
243
  // Multiple steps: parallel
188
244
  log(`Running ${executable.length} steps in parallel`);
189
- const parallelResults = await Promise.all(executable.map((step) => executeStep(step, vars, opts)));
245
+ const parallelResults = await Promise.all(executable.map((step) => executeStep(step, vars, opts, round)));
190
246
  const skipped = results.filter((r) => r.status === "skipped");
191
247
  return [...skipped, ...parallelResults];
192
248
  }
@@ -205,10 +261,11 @@ export function checkRetryNeeded(stepResults, transitions) {
205
261
  return false;
206
262
  }
207
263
  // ── Spawn Helper ───────────────────────────────────────────
208
- function spawnAsync(command, args, stdinData) {
264
+ function spawnAsync(command, args, stdinData, cwd) {
209
265
  return new Promise((resolve, reject) => {
210
266
  const child = spawn(command, args, {
211
267
  stdio: ["pipe", "pipe", "pipe"],
268
+ cwd,
212
269
  });
213
270
  let stdout = "";
214
271
  let stderr = "";
@@ -255,11 +312,12 @@ export async function runRun(opts) {
255
312
  }
256
313
  const maxBudget = opts.maxBudget ?? 5;
257
314
  const permissionMode = opts.permissionMode ?? "default";
258
- const agentsDir = opts.agentsDir ?? ".claude/agents";
315
+ const projectDir = resolve(opts.projectDir ?? process.cwd());
316
+ const agentsDir = opts.agentsDir ? resolve(projectDir, opts.agentsDir) : join(projectDir, ".claude", "agents");
259
317
  try {
260
318
  // ── Step 1: Load & compile DNA ───────────────────────
261
319
  log("Loading DNA files...");
262
- const expandedDNAFiles = await expandDNAInputFiles(opts.dnaFiles);
320
+ const expandedDNAFiles = await expandDNAInputFiles(opts.dnaFiles, { cwd: projectDir });
263
321
  const dnas = await Promise.all(expandedDNAFiles.map(loadDNA));
264
322
  const cascaded = cascadeDNA(dnas);
265
323
  const ir = await compileFromFiles(expandedDNAFiles, {
@@ -283,9 +341,10 @@ export async function runRun(opts) {
283
341
  log(`Compiled workflow: ${plan.name} (${plan.steps.length} steps, ${plan.parallel_groups.length} groups)`);
284
342
  // ── Step 3: Build template variables ─────────────────
285
343
  const vars = {
344
+ ...(opts.vars ?? {}),
286
345
  task_id: opts.taskId,
346
+ ARGUMENTS: opts.taskId,
287
347
  workflow: opts.workflowName,
288
- ...(opts.vars ?? {}),
289
348
  };
290
349
  // ── Dry-run mode ─────────────────────────────────────
291
350
  if (opts.dryRun) {
@@ -297,17 +356,30 @@ export async function runRun(opts) {
297
356
  await writeAgentMDFiles(agentResults, agentsDir);
298
357
  log(`Generated ${agentResults.length} agent file(s) in ${agentsDir}`);
299
358
  const hookScripts = createCompiledIR(ir, cascaded.roles);
300
- await writeCompiledIR(process.cwd(), hookScripts);
359
+ await writeCompiledIR(projectDir, hookScripts);
301
360
  log("Synced compiled IR for dna-hook enforcement");
302
361
  // ── Step 5: Prepare log directory ────────────────────
303
362
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
304
- const logDir = opts.logDir ?? join(".intentdna", "runs", `${opts.workflowName}-${timestamp}`);
363
+ const logDir = opts.logDir
364
+ ? resolve(projectDir, opts.logDir)
365
+ : join(projectDir, ".intentdna", "runs", `${opts.workflowName}-${timestamp}`);
305
366
  await mkdir(logDir, { recursive: true });
367
+ const attribution = trustedEvidenceCaptureAttribution(ir, { workflowId: opts.workflowName });
306
368
  const execOpts = {
307
369
  agentPrefix: "dna-",
308
370
  maxBudget,
309
371
  permissionMode,
310
372
  logDir,
373
+ projectDir,
374
+ workflowName: opts.workflowName,
375
+ workflowAsset: attribution.workflowAsset === "unknown" ? undefined : attribution.workflowAsset,
376
+ inputs: {
377
+ ...(opts.vars ?? {}),
378
+ task_id: opts.taskId,
379
+ ARGUMENTS: opts.taskId,
380
+ workflow: opts.workflowName,
381
+ },
382
+ ir,
311
383
  };
312
384
  // ── Step 6: Execute workflow ──────────────────────────
313
385
  const maxRetries = plan.retry.max_retries;
@@ -10,9 +10,11 @@
10
10
  *
11
11
  * Targets: claude-md, soul-md, cursorrules, system-prompt
12
12
  */
13
+ import type { CodexHookInstallMode } from "../../runtime/codex-adapter.js";
13
14
  export type SyncMode = "auto" | "plugin" | "bin";
14
15
  export interface SyncOptions {
15
16
  files: string[];
17
+ action?: "run" | "status" | "doctor" | "remove-registry";
16
18
  target: string;
17
19
  inject: string;
18
20
  context?: string;
@@ -26,11 +28,16 @@ export interface SyncOptions {
26
28
  skillsDir?: string;
27
29
  settingsPath?: string;
28
30
  lockFile?: string;
31
+ codex?: boolean;
32
+ codexInstallMode?: CodexHookInstallMode;
33
+ codexDogfood?: boolean;
29
34
  remove: boolean;
30
35
  mode?: SyncMode;
31
36
  plugin?: boolean;
32
37
  dryRun?: boolean;
33
38
  postSummary?: boolean;
39
+ json?: boolean;
40
+ projectDir?: string;
34
41
  }
35
42
  /**
36
43
  * Detect whether intentdna is running as a Claude Code plugin or standalone binary.
@@ -54,7 +61,7 @@ export declare function cleanStaleDNAFiles(dir: string, type: "agents" | "skills
54
61
  * Auto-detect DNA config file in current directory (legacy single-config).
55
62
  * Priority: .dna/config.yaml > .dna/config.yml > .dna/config.json > .dna.yaml > .dna.yml > .dna.json
56
63
  */
57
- export declare function autoDetectConfigs(): Promise<string[]>;
64
+ export declare function autoDetectConfigs(projectDir?: string): Promise<string[]>;
58
65
  /**
59
66
  * Read the current package version from package.json.
60
67
  */