intentdna 1.2.2 → 1.2.3

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 (180) hide show
  1. package/dist/audit/index.d.ts +0 -1
  2. package/dist/audit/index.js +0 -1
  3. package/dist/cli/commands/compile.d.ts +0 -1
  4. package/dist/cli/commands/compile.js +0 -1
  5. package/dist/cli/commands/epigenetic.d.ts +0 -1
  6. package/dist/cli/commands/epigenetic.js +0 -1
  7. package/dist/cli/commands/evolve.d.ts +0 -1
  8. package/dist/cli/commands/evolve.js +0 -1
  9. package/dist/cli/commands/guard.d.ts +0 -1
  10. package/dist/cli/commands/guard.js +0 -3
  11. package/dist/cli/commands/import.d.ts +0 -1
  12. package/dist/cli/commands/import.js +0 -1
  13. package/dist/cli/commands/init.d.ts +0 -1
  14. package/dist/cli/commands/init.js +0 -1
  15. package/dist/cli/commands/run.d.ts +0 -1
  16. package/dist/cli/commands/run.js +4 -27
  17. package/dist/cli/commands/show.d.ts +0 -1
  18. package/dist/cli/commands/show.js +0 -1
  19. package/dist/cli/commands/sync.d.ts +1 -1
  20. package/dist/cli/commands/sync.js +57 -32
  21. package/dist/cli/commands/validate.d.ts +0 -1
  22. package/dist/cli/commands/validate.js +0 -1
  23. package/dist/cli/commands/verify.d.ts +0 -1
  24. package/dist/cli/commands/verify.js +0 -1
  25. package/dist/cli/index.d.ts +0 -1
  26. package/dist/cli/index.js +2 -1
  27. package/dist/cli/util/format.d.ts +0 -1
  28. package/dist/cli/util/format.js +0 -1
  29. package/dist/cli/util/prompt.d.ts +0 -1
  30. package/dist/cli/util/prompt.js +0 -1
  31. package/dist/compiler/activate.d.ts +0 -1
  32. package/dist/compiler/activate.js +0 -1
  33. package/dist/compiler/cascade.d.ts +1 -3
  34. package/dist/compiler/cascade.js +1 -10
  35. package/dist/compiler/compile.d.ts +0 -1
  36. package/dist/compiler/compile.js +3 -17
  37. package/dist/compiler/index.d.ts +0 -1
  38. package/dist/compiler/index.js +0 -1
  39. package/dist/compiler/workflow.d.ts +0 -1
  40. package/dist/compiler/workflow.js +0 -2
  41. package/dist/evolution/collector.d.ts +0 -1
  42. package/dist/evolution/collector.js +0 -1
  43. package/dist/evolution/fitness.d.ts +0 -1
  44. package/dist/evolution/fitness.js +0 -1
  45. package/dist/evolution/index.d.ts +0 -1
  46. package/dist/evolution/index.js +0 -1
  47. package/dist/evolution/marker-gen.d.ts +0 -1
  48. package/dist/evolution/marker-gen.js +0 -1
  49. package/dist/evolution/store.d.ts +0 -1
  50. package/dist/evolution/store.js +0 -1
  51. package/dist/evolution/types.d.ts +0 -1
  52. package/dist/evolution/types.js +0 -1
  53. package/dist/hooks/cli.d.ts +17 -0
  54. package/dist/hooks/cli.js +134 -0
  55. package/dist/hooks/enforce.d.ts +68 -0
  56. package/dist/hooks/enforce.js +332 -0
  57. package/dist/hooks/index.d.ts +9 -0
  58. package/dist/hooks/index.js +12 -0
  59. package/dist/hooks/protocol.d.ts +70 -0
  60. package/dist/hooks/protocol.js +91 -0
  61. package/dist/hooks/state.d.ts +53 -0
  62. package/dist/hooks/state.js +93 -0
  63. package/dist/index.d.ts +0 -1
  64. package/dist/index.js +0 -1
  65. package/dist/log/logger.d.ts +0 -1
  66. package/dist/log/logger.js +0 -1
  67. package/dist/runtime/agent-md.d.ts +0 -1
  68. package/dist/runtime/agent-md.js +95 -105
  69. package/dist/runtime/claude-sdk.d.ts +0 -1
  70. package/dist/runtime/claude-sdk.js +0 -1
  71. package/dist/runtime/index.d.ts +3 -3
  72. package/dist/runtime/index.js +2 -2
  73. package/dist/runtime/markdown.d.ts +0 -1
  74. package/dist/runtime/markdown.js +0 -1
  75. package/dist/runtime/plugin-adapter.d.ts +42 -0
  76. package/dist/runtime/plugin-adapter.js +77 -0
  77. package/dist/runtime/settings-adapter.d.ts +8 -9
  78. package/dist/runtime/settings-adapter.js +57 -46
  79. package/dist/runtime/skill-adapter.d.ts +0 -1
  80. package/dist/runtime/skill-adapter.js +94 -71
  81. package/dist/runtime/workflow-runner.d.ts +0 -1
  82. package/dist/runtime/workflow-runner.js +0 -14
  83. package/dist/schema/index.d.ts +0 -1
  84. package/dist/schema/index.js +0 -1
  85. package/dist/schema/types.d.ts +14 -20
  86. package/dist/schema/types.js +0 -1
  87. package/dist/schema/validate.d.ts +0 -1
  88. package/dist/schema/validate.js +3 -19
  89. package/dist/schema/yaml-parser.d.ts +0 -1
  90. package/dist/schema/yaml-parser.js +0 -1
  91. package/dist/templates/code-review-pipeline.dna.yaml +0 -11
  92. package/dist/templates/flutter-behavior-lock.dna.yaml +0 -16
  93. package/dist/templates/flutter-refactoring-rescue.dna.yaml +0 -12
  94. package/dist/templates/flutter-rewrite.dna.yaml +0 -27
  95. package/dist/templates/full-pipeline.dna.yaml +0 -25
  96. package/dist/templates/multi-perspective-review.dna.yaml +0 -12
  97. package/dist/templates/subagent-parallel.dna.yaml +0 -16
  98. package/package.json +3 -2
  99. package/dist/audit/index.d.ts.map +0 -1
  100. package/dist/audit/index.js.map +0 -1
  101. package/dist/cli/commands/compile.d.ts.map +0 -1
  102. package/dist/cli/commands/compile.js.map +0 -1
  103. package/dist/cli/commands/epigenetic.d.ts.map +0 -1
  104. package/dist/cli/commands/epigenetic.js.map +0 -1
  105. package/dist/cli/commands/evolve.d.ts.map +0 -1
  106. package/dist/cli/commands/evolve.js.map +0 -1
  107. package/dist/cli/commands/guard.d.ts.map +0 -1
  108. package/dist/cli/commands/guard.js.map +0 -1
  109. package/dist/cli/commands/import.d.ts.map +0 -1
  110. package/dist/cli/commands/import.js.map +0 -1
  111. package/dist/cli/commands/init.d.ts.map +0 -1
  112. package/dist/cli/commands/init.js.map +0 -1
  113. package/dist/cli/commands/run.d.ts.map +0 -1
  114. package/dist/cli/commands/run.js.map +0 -1
  115. package/dist/cli/commands/show.d.ts.map +0 -1
  116. package/dist/cli/commands/show.js.map +0 -1
  117. package/dist/cli/commands/sync.d.ts.map +0 -1
  118. package/dist/cli/commands/sync.js.map +0 -1
  119. package/dist/cli/commands/validate.d.ts.map +0 -1
  120. package/dist/cli/commands/validate.js.map +0 -1
  121. package/dist/cli/commands/verify.d.ts.map +0 -1
  122. package/dist/cli/commands/verify.js.map +0 -1
  123. package/dist/cli/index.d.ts.map +0 -1
  124. package/dist/cli/index.js.map +0 -1
  125. package/dist/cli/util/format.d.ts.map +0 -1
  126. package/dist/cli/util/format.js.map +0 -1
  127. package/dist/cli/util/prompt.d.ts.map +0 -1
  128. package/dist/cli/util/prompt.js.map +0 -1
  129. package/dist/compiler/activate.d.ts.map +0 -1
  130. package/dist/compiler/activate.js.map +0 -1
  131. package/dist/compiler/cascade.d.ts.map +0 -1
  132. package/dist/compiler/cascade.js.map +0 -1
  133. package/dist/compiler/compile.d.ts.map +0 -1
  134. package/dist/compiler/compile.js.map +0 -1
  135. package/dist/compiler/index.d.ts.map +0 -1
  136. package/dist/compiler/index.js.map +0 -1
  137. package/dist/compiler/workflow.d.ts.map +0 -1
  138. package/dist/compiler/workflow.js.map +0 -1
  139. package/dist/evolution/collector.d.ts.map +0 -1
  140. package/dist/evolution/collector.js.map +0 -1
  141. package/dist/evolution/fitness.d.ts.map +0 -1
  142. package/dist/evolution/fitness.js.map +0 -1
  143. package/dist/evolution/index.d.ts.map +0 -1
  144. package/dist/evolution/index.js.map +0 -1
  145. package/dist/evolution/marker-gen.d.ts.map +0 -1
  146. package/dist/evolution/marker-gen.js.map +0 -1
  147. package/dist/evolution/store.d.ts.map +0 -1
  148. package/dist/evolution/store.js.map +0 -1
  149. package/dist/evolution/types.d.ts.map +0 -1
  150. package/dist/evolution/types.js.map +0 -1
  151. package/dist/index.d.ts.map +0 -1
  152. package/dist/index.js.map +0 -1
  153. package/dist/log/logger.d.ts.map +0 -1
  154. package/dist/log/logger.js.map +0 -1
  155. package/dist/runtime/agent-md.d.ts.map +0 -1
  156. package/dist/runtime/agent-md.js.map +0 -1
  157. package/dist/runtime/claude-sdk.d.ts.map +0 -1
  158. package/dist/runtime/claude-sdk.js.map +0 -1
  159. package/dist/runtime/hooks.d.ts +0 -67
  160. package/dist/runtime/hooks.d.ts.map +0 -1
  161. package/dist/runtime/hooks.js +0 -785
  162. package/dist/runtime/hooks.js.map +0 -1
  163. package/dist/runtime/index.d.ts.map +0 -1
  164. package/dist/runtime/index.js.map +0 -1
  165. package/dist/runtime/markdown.d.ts.map +0 -1
  166. package/dist/runtime/markdown.js.map +0 -1
  167. package/dist/runtime/settings-adapter.d.ts.map +0 -1
  168. package/dist/runtime/settings-adapter.js.map +0 -1
  169. package/dist/runtime/skill-adapter.d.ts.map +0 -1
  170. package/dist/runtime/skill-adapter.js.map +0 -1
  171. package/dist/runtime/workflow-runner.d.ts.map +0 -1
  172. package/dist/runtime/workflow-runner.js.map +0 -1
  173. package/dist/schema/index.d.ts.map +0 -1
  174. package/dist/schema/index.js.map +0 -1
  175. package/dist/schema/types.d.ts.map +0 -1
  176. package/dist/schema/types.js.map +0 -1
  177. package/dist/schema/validate.d.ts.map +0 -1
  178. package/dist/schema/validate.js.map +0 -1
  179. package/dist/schema/yaml-parser.d.ts.map +0 -1
  180. package/dist/schema/yaml-parser.js.map +0 -1
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Intent DNA — Settings Adapter
3
3
  *
4
- * Compiles DNA hook scripts into Claude Code settings.json
5
- * hook configurations for all supported hook events.
4
+ * Compiles DNA hook events into Claude Code settings.json
5
+ * hook configurations for the dna-hook binary.
6
6
  *
7
7
  * See docs/references/cc-source-analysis.md §2 for the full hook event catalog.
8
8
  */
9
- import type { HookScripts } from "./hooks.js";
9
+ export type HookEventKey = "preToolUse" | "postToolUse" | "userPromptSubmit" | "subagentStop" | "preCompact" | "notification";
10
10
  export interface SettingsHookEntry {
11
11
  matcher: string;
12
12
  hooks: Array<{
@@ -18,18 +18,17 @@ export interface DNASettings {
18
18
  hooks: Record<string, SettingsHookEntry[]>;
19
19
  }
20
20
  /**
21
- * Compile DNA hook scripts into settings.json hook configuration.
22
- * Registers all non-null hook scripts from HookScripts.
21
+ * Compile settings.json hook configuration for dna-hook binary.
22
+ * Uses `dna-hook <event>` commands.
23
23
  */
24
- export declare function compileSettingsFromHooks(hooksDir: string, scripts: HookScripts): DNASettings;
24
+ export declare function compilePluginSettings(enabledEvents: HookEventKey[], timeout?: number): DNASettings;
25
25
  /**
26
- * @deprecated Use compileSettingsFromHooks instead
26
+ * Determine which hook events are needed based on IR content.
27
27
  */
28
- export declare function compileSettings(hooksDir: string, hasPreHook: boolean, hasPostHook: boolean): DNASettings;
28
+ export declare function detectEnabledEvents(ir: import("../schema/types.js").ConstraintIR): HookEventKey[];
29
29
  /**
30
30
  * Merge DNA settings into existing settings.json.
31
31
  * Only touches the hooks section — preserves other settings.
32
32
  * Replaces DNA hooks (identified by "dna-" prefix), keeps user hooks.
33
33
  */
34
34
  export declare function mergeSettingsFile(dnaSettings: DNASettings, settingsPath: string): Promise<void>;
35
- //# sourceMappingURL=settings-adapter.d.ts.map
@@ -1,23 +1,14 @@
1
1
  /**
2
2
  * Intent DNA — Settings Adapter
3
3
  *
4
- * Compiles DNA hook scripts into Claude Code settings.json
5
- * hook configurations for all supported hook events.
4
+ * Compiles DNA hook events into Claude Code settings.json
5
+ * hook configurations for the dna-hook binary.
6
6
  *
7
7
  * See docs/references/cc-source-analysis.md §2 for the full hook event catalog.
8
8
  */
9
9
  import { readFile, writeFile } from "node:fs/promises";
10
- import { join } from "node:path";
11
- // Hook event → script filename mapping
12
- const HOOK_FILE_MAP = [
13
- ["preToolUse", "dna-pre-tool-use.sh"],
14
- ["postToolUse", "dna-post-tool-use.sh"],
15
- ["userPromptSubmit", "dna-user-prompt-submit.sh"],
16
- ["subagentStop", "dna-subagent-stop.sh"],
17
- ["preCompact", "dna-pre-compact.sh"],
18
- ["notification", "dna-notification.sh"],
19
- ];
20
- // HookScripts key → Claude Code settings event name
10
+ // ── Plugin Mode (Node.js hooks via dna-hook binary) ───────
11
+ /** Hook event key Claude Code settings event name */
21
12
  const HOOK_EVENT_MAP = {
22
13
  preToolUse: "PreToolUse",
23
14
  postToolUse: "PostToolUse",
@@ -26,44 +17,59 @@ const HOOK_EVENT_MAP = {
26
17
  preCompact: "PreCompact",
27
18
  notification: "Notification",
28
19
  };
29
- // ── Compile ────────────────────────────────────────────────
30
20
  /**
31
- * Compile DNA hook scripts into settings.json hook configuration.
32
- * Registers all non-null hook scripts from HookScripts.
21
+ * Compile settings.json hook configuration for dna-hook binary.
22
+ * Uses `dna-hook <event>` commands.
33
23
  */
34
- export function compileSettingsFromHooks(hooksDir, scripts) {
24
+ export function compilePluginSettings(enabledEvents, timeout = 10) {
35
25
  const settings = { hooks: {} };
36
- for (const [key, filename] of HOOK_FILE_MAP) {
37
- if (scripts[key]) {
38
- const eventName = HOOK_EVENT_MAP[key];
39
- settings.hooks[eventName] = [
40
- {
41
- matcher: "",
42
- hooks: [
43
- {
44
- type: "command",
45
- command: `bash ${join(hooksDir, filename)}`,
46
- },
47
- ],
48
- },
49
- ];
50
- }
26
+ for (const key of enabledEvents) {
27
+ const eventName = HOOK_EVENT_MAP[key];
28
+ if (!eventName)
29
+ continue;
30
+ settings.hooks[eventName] = [
31
+ {
32
+ matcher: "",
33
+ hooks: [
34
+ {
35
+ type: "command",
36
+ command: `dna-hook ${eventName}`,
37
+ ...(timeout > 0 ? { timeout } : {}),
38
+ },
39
+ ],
40
+ },
41
+ ];
51
42
  }
52
43
  return settings;
53
44
  }
54
45
  /**
55
- * @deprecated Use compileSettingsFromHooks instead
46
+ * Determine which hook events are needed based on IR content.
56
47
  */
57
- export function compileSettings(hooksDir, hasPreHook, hasPostHook) {
58
- const scripts = {
59
- preToolUse: hasPreHook ? "exists" : null,
60
- postToolUse: hasPostHook ? "exists" : null,
61
- userPromptSubmit: null,
62
- subagentStop: null,
63
- preCompact: null,
64
- notification: null,
65
- };
66
- return compileSettingsFromHooks(hooksDir, scripts);
48
+ export function detectEnabledEvents(ir) {
49
+ const events = [];
50
+ const hasGates = ir.pre_execution_gates.length > 0;
51
+ const hasFilters = ir.tool_filters.length > 0;
52
+ const hasRoleScope = ir.roles_scope_map && ir.roles_scope_map.length > 0;
53
+ const hasCheckpoints = ir.step_checkpoints && ir.step_checkpoints.length > 0;
54
+ if (hasGates || hasFilters || hasRoleScope || hasCheckpoints) {
55
+ events.push("preToolUse");
56
+ }
57
+ if (ir.post_execution_validators.length > 0) {
58
+ events.push("postToolUse");
59
+ }
60
+ if (ir.prompt_directives.some(d => d.priority === "high")) {
61
+ events.push("userPromptSubmit");
62
+ }
63
+ if (hasRoleScope) {
64
+ events.push("subagentStop");
65
+ }
66
+ if (ir.prompt_directives.length > 0) {
67
+ events.push("preCompact");
68
+ }
69
+ if (hasGates || hasFilters) {
70
+ events.push("notification");
71
+ }
72
+ return events;
67
73
  }
68
74
  // ── File Operations ────────────────────────────────────────
69
75
  /**
@@ -85,14 +91,20 @@ export async function mergeSettingsFile(dnaSettings, settingsPath) {
85
91
  for (const [eventName, entries] of Object.entries(dnaSettings.hooks)) {
86
92
  const existingEntries = (mergedHooks[eventName] ?? []);
87
93
  // Remove existing DNA hooks, keep user hooks
88
- const nonDNA = existingEntries.filter((h) => !JSON.stringify(h).includes("dna-"));
94
+ const nonDNA = existingEntries.filter((h) => {
95
+ const s = JSON.stringify(h);
96
+ return !s.includes("dna-") && !s.includes("dna-hook");
97
+ });
89
98
  mergedHooks[eventName] = [...nonDNA, ...entries];
90
99
  }
91
100
  // Remove DNA hook events that are no longer generated
92
101
  for (const eventName of Object.values(HOOK_EVENT_MAP)) {
93
102
  if (!dnaSettings.hooks[eventName] && mergedHooks[eventName]) {
94
103
  const entries = mergedHooks[eventName];
95
- const nonDNA = entries.filter((h) => !JSON.stringify(h).includes("dna-"));
104
+ const nonDNA = entries.filter((h) => {
105
+ const s = JSON.stringify(h);
106
+ return !s.includes("dna-") && !s.includes("dna-hook");
107
+ });
96
108
  if (nonDNA.length > 0) {
97
109
  mergedHooks[eventName] = nonDNA;
98
110
  }
@@ -104,4 +116,3 @@ export async function mergeSettingsFile(dnaSettings, settingsPath) {
104
116
  existing.hooks = mergedHooks;
105
117
  await writeFile(settingsPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
106
118
  }
107
- //# sourceMappingURL=settings-adapter.js.map
@@ -20,4 +20,3 @@ export interface SkillResult {
20
20
  export declare function compileWorkflowToSkill(plan: WorkflowPlan, roles: Record<string, RoleDef>, ir?: ConstraintIR, variables?: Record<string, string>): SkillResult;
21
21
  export declare function writeSkillFiles(results: SkillResult[], outputDir: string): Promise<string[]>;
22
22
  export declare function removeSkillFiles(outputDir: string): Promise<number>;
23
- //# sourceMappingURL=skill-adapter.d.ts.map
@@ -17,11 +17,15 @@ const SENTINEL = "<!-- intentdna:managed — do not edit manually -->";
17
17
  */
18
18
  export function compileWorkflowToSkill(plan, roles, ir, variables) {
19
19
  const lines = [];
20
+ const skillName = `dna-${toKebabCase(plan.name)}`;
20
21
  // Frontmatter
21
22
  lines.push("---");
22
- lines.push(`name: ${toKebabCase(plan.name)}`);
23
- lines.push(`description: "Use when user says /${toKebabCase(plan.name)}. ${escapeYaml(plan.description || plan.name)}"`);
23
+ lines.push(`name: ${skillName}`);
24
+ lines.push(`description: "Use when user says /${skillName}. ${escapeYaml(plan.description || plan.name)}"`);
24
25
  lines.push("user-invocable: true");
26
+ lines.push("triggers:");
27
+ lines.push(` - "${plan.name}"`);
28
+ lines.push(` - "run ${plan.name}"`);
25
29
  lines.push("---");
26
30
  lines.push("");
27
31
  // Sentinel
@@ -29,104 +33,106 @@ export function compileWorkflowToSkill(plan, roles, ir, variables) {
29
33
  lines.push(`<!-- Compiled: ${new Date().toISOString()} -->`);
30
34
  lines.push("");
31
35
  // Title
32
- lines.push(`# /${plan.name} [task-id]`);
36
+ lines.push(`# /${skillName} [task-id]`);
33
37
  lines.push("");
34
- lines.push(plan.description);
35
- lines.push("");
36
- // Roles table
37
- lines.push("## Roles");
38
- lines.push("");
39
- lines.push("| Role | Agent | Tools | Deny | Scope (write) |");
40
- lines.push("|------|-------|-------|------|---------------|");
41
- const usedRoles = new Set(plan.steps.map((s) => s.role));
42
- for (const roleName of usedRoles) {
43
- const role = roles[roleName];
44
- if (!role)
45
- continue;
46
- const agent = `dna-${toKebabCase(roleName)}`;
47
- const tools = role.tool_permissions?.allow?.join(", ") || "all";
48
- const deny = role.tool_permissions?.deny?.join(", ") || "—";
49
- const scope = role.scope?.write?.join(", ") || "—";
50
- lines.push(`| ${roleName} | ${agent} | ${tools} | ${deny} | ${scope} |`);
38
+ // Purpose
39
+ if (plan.description) {
40
+ lines.push("<Purpose>");
41
+ lines.push(plan.description);
42
+ lines.push("</Purpose>");
43
+ lines.push("");
51
44
  }
52
- lines.push("");
53
- // Process
54
- lines.push("## Process");
55
- lines.push("");
45
+ // Steps
46
+ const usedRoles = new Set(plan.steps.map((s) => s.role));
47
+ lines.push("<Steps>");
48
+ let stepNumber = 0;
56
49
  for (let i = 0; i < plan.parallel_groups.length; i++) {
57
50
  const group = plan.parallel_groups[i];
58
- const isParallel = group.step_ids.length > 1;
59
- if (isParallel) {
60
- lines.push(`### Group ${i + 1} (parallel)`);
61
- }
62
51
  for (const stepId of group.step_ids) {
52
+ stepNumber++;
63
53
  const step = plan.steps.find((s) => s.id === stepId);
64
54
  const agent = `@dna-${toKebabCase(step.role)}`;
65
55
  const runIf = step.run_if ? ` (${step.run_if})` : "";
66
56
  const optional = step.optional ? " (optional)" : "";
67
- const modeTag = step.mode ? ` [mode: ${step.mode}]` : "";
68
- lines.push(`${i + 1}. **${step.id}** → ${agent}${runIf}${optional}${modeTag}`);
69
- if (step.mode) {
70
- lines.push(` Before starting: \`echo '{"active_mode":"${step.mode}","set_at":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","set_by":"skill:${toKebabCase(plan.name)}:${step.id}"}' > .dna/mode\``);
71
- }
57
+ lines.push(`${stepNumber}. **${step.id}** ${agent}${runIf}${optional}`);
72
58
  lines.push(` ${step.description}`);
59
+ if (step.prompt) {
60
+ lines.push(` Prompt: ${step.prompt}`);
61
+ }
73
62
  }
74
63
  }
64
+ lines.push("</Steps>");
75
65
  lines.push("");
76
- // Retry
77
- if (plan.retry.max_retries > 0) {
78
- lines.push("## Retry Policy");
79
- lines.push("");
80
- lines.push(`- Max retries: ${plan.retry.max_retries}`);
81
- if (plan.retry.retry_from) {
82
- lines.push(`- Retry from: ${plan.retry.retry_from}`);
83
- }
84
- for (const t of plan.transitions) {
85
- if (t.condition === "fail") {
86
- lines.push(`- On **${t.from}** fail → go to **${t.to}**`);
87
- }
88
- }
66
+ // Tool_Usage — only if roles have permissions or scope
67
+ const toolUsageLines = [];
68
+ for (const roleName of usedRoles) {
69
+ const role = roles[roleName];
70
+ if (!role)
71
+ continue;
72
+ const allowed = role.tool_permissions?.allow?.join(", ") || "all";
73
+ const denied = role.tool_permissions?.deny?.join(", ") || "none";
74
+ const writeScope = role.scope?.write?.join(", ") || "none";
75
+ toolUsageLines.push(`### ${roleName}`);
76
+ toolUsageLines.push(`- Allowed: ${allowed}`);
77
+ toolUsageLines.push(`- Denied: ${denied}`);
78
+ toolUsageLines.push(`- Write scope: ${writeScope}`);
79
+ }
80
+ if (toolUsageLines.length > 0) {
81
+ lines.push("<Tool_Usage>");
82
+ lines.push(...toolUsageLines);
83
+ lines.push("</Tool_Usage>");
89
84
  lines.push("");
90
85
  }
91
- // Guidelines from IR
86
+ // Constraints IR prompt_directives grouped by priority
92
87
  if (ir && ir.prompt_directives.length > 0) {
93
- lines.push("## Guidelines");
94
- lines.push("");
88
+ lines.push("<Constraints>");
95
89
  const high = ir.prompt_directives.filter((d) => d.priority === "high");
96
90
  const medium = ir.prompt_directives.filter((d) => d.priority === "medium");
91
+ const low = ir.prompt_directives.filter((d) => d.priority !== "high" && d.priority !== "medium");
97
92
  if (high.length > 0) {
98
- lines.push("### Critical");
93
+ lines.push("## Critical");
99
94
  for (const d of high) {
100
95
  lines.push(`- **${d.text}**`);
101
96
  }
102
- lines.push("");
103
97
  }
104
98
  if (medium.length > 0) {
105
- lines.push("### Standard");
99
+ lines.push("## Standard");
106
100
  for (const d of medium) {
107
101
  lines.push(`- ${d.text}`);
108
102
  }
109
- lines.push("");
110
103
  }
111
- }
112
- // Role instructions
113
- lines.push("## Role Instructions");
114
- lines.push("");
115
- for (const roleName of usedRoles) {
116
- const role = roles[roleName];
117
- if (!role)
118
- continue;
119
- lines.push(`### ${roleName}`);
104
+ if (low.length > 0) {
105
+ lines.push("## Other");
106
+ for (const d of low) {
107
+ lines.push(`- ${d.text}`);
108
+ }
109
+ }
110
+ lines.push("</Constraints>");
120
111
  lines.push("");
121
- if (role.instructions && role.instructions.length > 0) {
122
- for (let j = 0; j < role.instructions.length; j++) {
123
- lines.push(`${j + 1}. ${role.instructions[j]}`);
112
+ }
113
+ // Checkpoints steps that have checkpoint conditions
114
+ const stepsWithCheckpoints = plan.steps.filter((s) => s.checkpoints && s.checkpoints.length > 0);
115
+ if (stepsWithCheckpoints.length > 0) {
116
+ lines.push("<Checkpoints>");
117
+ for (const step of stepsWithCheckpoints) {
118
+ lines.push(`### ${step.id}`);
119
+ for (const cp of step.checkpoints) {
120
+ const action = cp.action || "block";
121
+ lines.push(`- ${cp.assert}: ${cp.message} (${action})`);
124
122
  }
125
123
  }
126
- if (role.post_checks && role.post_checks.length > 0) {
127
- lines.push("");
128
- lines.push("Post checks: " + role.post_checks.join(", "));
124
+ lines.push("</Checkpoints>");
125
+ lines.push("");
126
+ }
127
+ // Variables — collect {{var_name}} references from the whole plan
128
+ const varRefs = collectVariableRefs(plan);
129
+ if (varRefs.size > 0) {
130
+ lines.push("<Variables>");
131
+ for (const varName of varRefs) {
132
+ const value = variables?.[varName];
133
+ lines.push(`- \`{{${varName}}}\`: ${value ?? varName}`);
129
134
  }
135
+ lines.push("</Variables>");
130
136
  lines.push("");
131
137
  }
132
138
  let content = lines.join("\n") + "\n";
@@ -136,9 +142,27 @@ export function compileWorkflowToSkill(plan, roles, ir, variables) {
136
142
  content = content.replaceAll(`{{${key}}}`, value);
137
143
  }
138
144
  }
139
- const dirName = toKebabCase(plan.name);
145
+ const dirName = skillName;
140
146
  const fileName = join(dirName, "SKILL.md");
141
- return { name: plan.name, fileName, dirName, content };
147
+ return { name: skillName, fileName, dirName, content };
148
+ }
149
+ /** Collect all {{var_name}} references from a workflow plan. */
150
+ function collectVariableRefs(plan) {
151
+ const refs = new Set();
152
+ const RE = /\{\{(\w+)\}\}/g;
153
+ const scan = (s) => {
154
+ if (!s)
155
+ return;
156
+ for (const m of s.matchAll(RE))
157
+ refs.add(m[1]);
158
+ };
159
+ scan(plan.name);
160
+ scan(plan.description);
161
+ for (const step of plan.steps) {
162
+ scan(step.description);
163
+ scan(step.prompt);
164
+ }
165
+ return refs;
142
166
  }
143
167
  // ── File Operations ────────────────────────────────────────
144
168
  export async function writeSkillFiles(results, outputDir) {
@@ -179,4 +203,3 @@ export async function removeSkillFiles(outputDir) {
179
203
  function escapeYaml(s) {
180
204
  return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
181
205
  }
182
- //# sourceMappingURL=skill-adapter.js.map
@@ -50,4 +50,3 @@ export declare function writeWorkflowScript(result: WorkflowShellResult, outputD
50
50
  * Returns number of files removed.
51
51
  */
52
52
  export declare function removeWorkflowScripts(outputDir: string): Promise<number>;
53
- //# sourceMappingURL=workflow-runner.d.ts.map
@@ -177,9 +177,6 @@ function generateStepExecution(step, options, plan, isParallel) {
177
177
  const condLabel = retrySkipGuard ? "round == 1 (retry_from skip)" : step.run_if;
178
178
  lines.push(` # Step: ${step.id} (run_if: ${condLabel})`);
179
179
  lines.push(` if ${effectiveCondition}; then`);
180
- if (step.mode) {
181
- lines.push(` echo '{"active_mode":"${step.mode}","set_at":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","set_by":"workflow:${plan.name}:${step.id}"}' > .dna/mode`);
182
- }
183
180
  lines.push(` ${agentCall}`);
184
181
  lines.push(" else");
185
182
  lines.push(` echo "[$(date '+%H:%M:%S')] Skipping step: ${step.id} (run_if: ${condLabel}, current round: $ROUND)"`);
@@ -187,9 +184,6 @@ function generateStepExecution(step, options, plan, isParallel) {
187
184
  }
188
185
  else {
189
186
  lines.push(` # Step: ${step.id}`);
190
- if (step.mode) {
191
- lines.push(` echo '{"active_mode":"${step.mode}","set_at":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","set_by":"workflow:${plan.name}:${step.id}"}' > .dna/mode`);
192
- }
193
187
  if (step.optional) {
194
188
  lines.push(` run_agent "${agent}" '${prompt}' "${step.id}" || {`);
195
189
  lines.push(` STEP_${varId}_STATUS=1`);
@@ -376,13 +370,6 @@ export function compileWorkflowToShell(plan, options) {
376
370
  lines.push('echo "All steps passed."');
377
371
  }
378
372
  lines.push("");
379
- // Clean up mode file after workflow completes
380
- const hasAnyMode = plan.steps.some((s) => s.mode !== null);
381
- if (hasAnyMode) {
382
- lines.push("# Clean up mode state");
383
- lines.push('rm -f .dna/mode');
384
- lines.push("");
385
- }
386
373
  const script = lines.join("\n") + "\n";
387
374
  const fileName = toKebabCase(plan.name) + ".sh";
388
375
  return { script, fileName };
@@ -430,4 +417,3 @@ export async function removeWorkflowScripts(outputDir) {
430
417
  }
431
418
  return removed;
432
419
  }
433
- //# sourceMappingURL=workflow-runner.js.map
@@ -1,2 +1 @@
1
1
  export * from "./types.js";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1 @@
1
1
  export * from "./types.js";
2
- //# sourceMappingURL=index.js.map
@@ -79,12 +79,8 @@ export interface RoleDef {
79
79
  suppresses_genes?: string[];
80
80
  post_checks?: string[];
81
81
  instructions?: string[];
82
- }
83
- /** Mode definition — coarse-grained enforcement layer above roles */
84
- export interface ModeDef {
85
- description: string;
86
- tool_permissions?: ToolPermissions;
87
- scope?: ScopeDef;
82
+ success_criteria?: string[];
83
+ failure_modes?: string[];
88
84
  }
89
85
  /** Transition condition between workflow steps */
90
86
  export interface TransitionDef {
@@ -121,7 +117,6 @@ export interface CompletionCheck {
121
117
  export interface WorkflowStepDef {
122
118
  id: string;
123
119
  role: string;
124
- mode?: string;
125
120
  description?: string;
126
121
  depends_on?: string[];
127
122
  optional?: boolean;
@@ -181,7 +176,6 @@ export interface IntentDNA {
181
176
  genes: Record<string, Gene>;
182
177
  contexts: Record<string, ContextRegion>;
183
178
  roles?: Record<string, RoleDef>;
184
- modes?: Record<string, ModeDef>;
185
179
  workflow?: WorkflowDef;
186
180
  workflows?: Record<string, WorkflowDef>;
187
181
  variables?: Record<string, string | VariableDef>;
@@ -225,19 +219,22 @@ export interface RoleScopeEntry {
225
219
  scope: ScopeDef;
226
220
  tool_permissions?: ToolPermissions;
227
221
  }
228
- /** Mode constraint compiled into IR — hook reads .dna/mode and enforces */
229
- export interface ModeConstraint {
230
- mode_name: string;
231
- description: string;
232
- tool_deny?: string[];
233
- scope_write?: string[];
234
- }
235
- /** Step checkpoint compiled into IR — hook enforces at mode transition */
222
+ /** Step checkpoint compiled into IR — hook enforces at step transition */
236
223
  export interface StepCheckpointIR {
237
- step_mode: string;
224
+ step_role: string;
238
225
  step_id: string;
239
226
  checkpoints: StepCheckpoint[];
240
227
  }
228
+ /** Runtime workflow state written to .dna/state/workflow.json */
229
+ export interface WorkflowState {
230
+ active: boolean;
231
+ workflow: string;
232
+ current_step: string;
233
+ current_role: string;
234
+ iteration: number;
235
+ session_id: string;
236
+ started_at: string;
237
+ }
241
238
  export interface ConstraintIR {
242
239
  prompt_directives: PromptDirective[];
243
240
  tool_filters: ToolFilter[];
@@ -251,14 +248,12 @@ export interface ConstraintIR {
251
248
  role_tool_permissions?: ToolPermissions;
252
249
  role_scope?: ScopeDef;
253
250
  roles_scope_map?: RoleScopeEntry[];
254
- mode_constraints?: ModeConstraint[];
255
251
  step_checkpoints?: StepCheckpointIR[];
256
252
  }
257
253
  /** A compiled workflow step with resolved metadata */
258
254
  export interface WorkflowStep {
259
255
  id: string;
260
256
  role: string;
261
- mode: string | null;
262
257
  description: string;
263
258
  optional: boolean;
264
259
  run_if: string | null;
@@ -313,4 +308,3 @@ export interface WorkflowPlan {
313
308
  compiled_at: string;
314
309
  source_workflow: string;
315
310
  }
316
- //# sourceMappingURL=types.d.ts.map
@@ -8,4 +8,3 @@
8
8
  * Layer 4: Epigenetic Markers (experience-driven modulation)
9
9
  */
10
10
  export {};
11
- //# sourceMappingURL=types.js.map
@@ -18,4 +18,3 @@ export interface ValidationResult {
18
18
  warnings?: ValidationError[];
19
19
  }
20
20
  export declare function validateDNA(dna: IntentDNA): ValidationResult;
21
- //# sourceMappingURL=validate.d.ts.map
@@ -186,7 +186,7 @@ function validateRole(name, role, geneNames) {
186
186
  }
187
187
  return errors;
188
188
  }
189
- function validateWorkflow(workflow, roleNames, pathPrefix, modeNames) {
189
+ function validateWorkflow(workflow, roleNames, pathPrefix) {
190
190
  const errors = [];
191
191
  const path = pathPrefix ?? "workflow";
192
192
  // name required
@@ -225,13 +225,6 @@ function validateWorkflow(workflow, roleNames, pathPrefix, modeNames) {
225
225
  message: `step references unknown role '${step.role}'`,
226
226
  });
227
227
  }
228
- // step.mode optional but must exist in modes if specified
229
- if (step.mode && modeNames && modeNames.size > 0 && !modeNames.has(step.mode)) {
230
- errors.push({
231
- path: `${stepPath}.mode`,
232
- message: `step references unknown mode '${step.mode}'`,
233
- });
234
- }
235
228
  // depends_on: check for empty strings in first pass
236
229
  for (const dep of step.depends_on ?? []) {
237
230
  if (!dep) {
@@ -384,13 +377,6 @@ export function validateDNA(dna) {
384
377
  for (const [name, role] of Object.entries(dna.roles ?? {})) {
385
378
  errors.push(...validateRole(name, role, geneNames));
386
379
  }
387
- // Validate modes
388
- for (const [name, mode] of Object.entries(dna.modes ?? {})) {
389
- const modePath = `modes.${name}`;
390
- if (!mode.description) {
391
- errors.push({ path: `${modePath}.description`, message: "mode requires 'description'" });
392
- }
393
- }
394
380
  // Validate workflow / workflows (mutually exclusive)
395
381
  if (dna.workflow !== undefined && dna.workflows !== undefined) {
396
382
  errors.push({
@@ -399,13 +385,12 @@ export function validateDNA(dna) {
399
385
  });
400
386
  }
401
387
  const roleNamesSet = new Set(Object.keys(dna.roles ?? {}));
402
- const modeNamesSet = new Set(Object.keys(dna.modes ?? {}));
403
388
  if (dna.workflow && !dna.workflows) {
404
- errors.push(...validateWorkflow(dna.workflow, roleNamesSet, "workflow", modeNamesSet));
389
+ errors.push(...validateWorkflow(dna.workflow, roleNamesSet, "workflow"));
405
390
  }
406
391
  if (dna.workflows && !dna.workflow) {
407
392
  for (const [wfName, wfDef] of Object.entries(dna.workflows)) {
408
- errors.push(...validateWorkflow(wfDef, roleNamesSet, `workflows.${wfName}`, modeNamesSet));
393
+ errors.push(...validateWorkflow(wfDef, roleNamesSet, `workflows.${wfName}`));
409
394
  }
410
395
  }
411
396
  // Validate epigenetic markers
@@ -429,4 +414,3 @@ export function validateDNA(dna) {
429
414
  }
430
415
  return { valid: errors.length === 0, errors, warnings: warnings.length > 0 ? warnings : undefined };
431
416
  }
432
- //# sourceMappingURL=validate.js.map
@@ -9,4 +9,3 @@
9
9
  * Zero external dependencies.
10
10
  */
11
11
  export declare function parseYAML(input: string): unknown;
12
- //# sourceMappingURL=yaml-parser.d.ts.map
@@ -295,4 +295,3 @@ function findNextNonEmptyLine(lines, from) {
295
295
  }
296
296
  return lines.length;
297
297
  }
298
- //# sourceMappingURL=yaml-parser.js.map