intentdna 1.7.4 → 1.7.5

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.
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "intentdna",
11
11
  "description": "Declarative policy layer for AI agent behavior with plugin-managed hook runtime for Claude Code.",
12
- "version": "1.7.4",
12
+ "version": "1.7.5",
13
13
  "author": {
14
14
  "name": "Samuel"
15
15
  },
@@ -25,5 +25,5 @@
25
25
  ]
26
26
  }
27
27
  ],
28
- "version": "1.7.4"
28
+ "version": "1.7.5"
29
29
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intentdna",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
4
4
  "description": "Declarative policy layer for AI agent behavior",
5
5
  "author": {
6
6
  "name": "Samuel"
package/dist/cli/index.js CHANGED
@@ -12,7 +12,10 @@
12
12
  * help Show this help message
13
13
  */
14
14
  import { parseArgs } from "node:util";
15
- const HELP = `Intent DNA CLI v1.7.0
15
+ import { getPackageVersion } from "./util/version.js";
16
+ const fallbackVersion = "unknown";
17
+ function helpText(version) {
18
+ return `Intent DNA CLI v${version}
16
19
 
17
20
  Usage: dna <command> [options]
18
21
 
@@ -69,6 +72,7 @@ Examples:
69
72
  dna evolve my_dna_id Preview marker changes without persisting
70
73
  dna evolve my_dna_id --apply Unsupported in this kernel; use sync --evolve for explicit mutation
71
74
  `;
75
+ }
72
76
  const COMMAND_HELP = {
73
77
  sync: `Usage: dna sync [files...] [options]\n\nOptions:\n --mode auto|plugin|bin Sync mode (default: auto)\n --dry-run Print planned outputs without writing files\n --post-summary Print registry-backed output summary\n --target <target> Markdown target for injection\n --inject <path> File to inject markdown into\n --agents <dir> Generate agent files\n --skills <dir> Generate skill files\n --workflow <dir> Generate workflow shell scripts\n --settings <path> Write hook settings in bin mode\n --lock <path> Write lock file (default .dna/lock)\n`,
74
78
  verify: `Usage: dna verify [--lock <path>] [--stats] [--health] [--strict]\n\nOptions:\n --health Comprehensive installation health check\n --stats Show hook call statistics\n --strict Require valid RuntimeDecisionEvent enterprise evidence\n --lock <path> Lock file path (default .dna/lock)\n`,
@@ -86,21 +90,27 @@ function commandHelp(command) {
86
90
  async function main() {
87
91
  const args = process.argv.slice(2);
88
92
  const command = args[0];
93
+ const version = await getPackageVersion() ?? fallbackVersion;
94
+ const help = helpText(version);
95
+ if (command === "--version" || command === "-v") {
96
+ process.stdout.write(`${version}\n`);
97
+ process.exit(0);
98
+ }
89
99
  if (!command || command === "--help" || command === "-h") {
90
- process.stderr.write(HELP);
100
+ process.stderr.write(help);
91
101
  process.exit(0);
92
102
  }
93
103
  if (command === "help") {
94
- const help = commandHelp(args[1]);
95
- process.stderr.write(help ?? HELP);
104
+ const commandSpecificHelp = commandHelp(args[1]);
105
+ process.stderr.write(commandSpecificHelp ?? help);
96
106
  process.exit(0);
97
107
  }
98
108
  // Parse remaining args (after command)
99
109
  const rest = args.slice(1);
100
110
  if (rest.includes("--help") || rest.includes("-h")) {
101
- const help = commandHelp(command);
102
- process.stderr.write(help ?? HELP);
103
- process.exit(help ? 0 : 2);
111
+ const commandSpecificHelp = commandHelp(command);
112
+ process.stderr.write(commandSpecificHelp ?? help);
113
+ process.exit(commandSpecificHelp ? 0 : 2);
104
114
  }
105
115
  switch (command) {
106
116
  case "sync": {
@@ -514,7 +524,7 @@ async function main() {
514
524
  }
515
525
  default:
516
526
  process.stderr.write(`Unknown command: ${command}\n\n`);
517
- process.stderr.write(HELP);
527
+ process.stderr.write(help);
518
528
  process.exit(2);
519
529
  }
520
530
  }
@@ -47,6 +47,7 @@ export interface RunHookEventOptions {
47
47
  sessionId?: string;
48
48
  roles?: Record<string, RoleDef>;
49
49
  }
50
+ export declare function normalizeHookOutputForEvent(output: HookOutput, event: HookEvent): HookOutput;
50
51
  export declare function runHookEvent(options: RunHookEventOptions): Promise<HookOutput>;
51
52
  declare function recordProducedArtifacts(projectDir: string, ir: ConstraintIR, wfState: {
52
53
  workflow: string;
package/dist/hooks/cli.js CHANGED
@@ -227,8 +227,20 @@ async function main() {
227
227
  const output = await runHookEvent({ event, ir, rawInput, projectDir, sessionId });
228
228
  writeOutput(output);
229
229
  }
230
+ export function normalizeHookOutputForEvent(output, event) {
231
+ if (!output.hookSpecificOutput)
232
+ return output;
233
+ return {
234
+ ...output,
235
+ hookSpecificOutput: {
236
+ ...output.hookSpecificOutput,
237
+ hookEventName: output.hookSpecificOutput.hookEventName ?? event,
238
+ },
239
+ };
240
+ }
230
241
  export async function runHookEvent(options) {
231
242
  const { event, ir, rawInput, projectDir, sessionId, roles } = options;
243
+ const finish = (output) => normalizeHookOutputForEvent(output, event);
232
244
  const state = {};
233
245
  const writeRuntimeDecision = async (output, result, wfState, traceId = randomUUID()) => {
234
246
  const decision = normalizeDecision(output);
@@ -253,7 +265,7 @@ export async function runHookEvent(options) {
253
265
  const workflowState = await readWorkflowStateForHook(projectDir, event, sessionId);
254
266
  if ("output" in workflowState) {
255
267
  await writeRuntimeDecision(workflowState.output, { output: workflowState.output, trace: { matched_rule: "workflow_boundary" } }, null);
256
- return workflowState.output;
268
+ return finish(workflowState.output);
257
269
  }
258
270
  wfStateRaw = workflowState.state;
259
271
  if (wfStateRaw && wfStateRaw.active) {
@@ -268,7 +280,7 @@ export async function runHookEvent(options) {
268
280
  if ("output" in artifactFacts) {
269
281
  appendArtifactResolverTrace(projectDir, event, wfStateRaw, artifactFacts.output, sessionId);
270
282
  await writeRuntimeDecision(artifactFacts.output, { output: artifactFacts.output, trace: { matched_rule: "handoff", step_id: wfStateRaw.current_step } }, wfStateRaw);
271
- return artifactFacts.output;
283
+ return finish(artifactFacts.output);
272
284
  }
273
285
  state.artifactFacts = artifactFacts.facts;
274
286
  }
@@ -298,7 +310,7 @@ export async function runHookEvent(options) {
298
310
  timestamp: new Date().toISOString(),
299
311
  }, sessionId).catch(() => { });
300
312
  await writeRuntimeDecision(gateResult.output, { output: gateResult.output, trace: { matched_rule: gateResult.matched_rule, step_id: wfStateRaw?.current_step } }, wfStateRaw, traceId);
301
- return gateResult.output;
313
+ return finish(gateResult.output);
302
314
  }
303
315
  }
304
316
  // Special handling for Stop — needs async workflow state read + session summary
@@ -306,7 +318,7 @@ export async function runHookEvent(options) {
306
318
  const workflowState = await readWorkflowStateForHook(projectDir, event, sessionId);
307
319
  if ("output" in workflowState) {
308
320
  await writeRuntimeDecision(workflowState.output, { output: workflowState.output, trace: { matched_rule: "workflow_boundary" } }, null);
309
- return workflowState.output;
321
+ return finish(workflowState.output);
310
322
  }
311
323
  const wfState = workflowState.state;
312
324
  let stopArtifactFacts = [];
@@ -315,7 +327,7 @@ export async function runHookEvent(options) {
315
327
  if ("output" in artifactFacts) {
316
328
  appendArtifactResolverTrace(projectDir, event, wfState, artifactFacts.output, sessionId);
317
329
  await writeRuntimeDecision(artifactFacts.output, { output: artifactFacts.output, trace: { matched_rule: "handoff", step_id: wfState.current_step } }, wfState);
318
- return artifactFacts.output;
330
+ return finish(artifactFacts.output);
319
331
  }
320
332
  stopArtifactFacts = artifactFacts.facts;
321
333
  }
@@ -375,7 +387,7 @@ export async function runHookEvent(options) {
375
387
  timestamp: new Date().toISOString(),
376
388
  }, sessionId).catch(() => { });
377
389
  await writeRuntimeDecision(stopOutput, { output: stopOutput, trace: { matched_rule: "validator", step_id: wfState?.current_step } }, wfState, traceId);
378
- return stopOutput;
390
+ return finish(stopOutput);
379
391
  }
380
392
  // Dispatch to enforcement engine with timing
381
393
  const start = Date.now();
@@ -488,7 +500,7 @@ export async function runHookEvent(options) {
488
500
  session_id: sessionId,
489
501
  }).catch(() => { }); // Fail-open
490
502
  }
491
- return output;
503
+ return finish(output);
492
504
  }
493
505
  // ── Dispatch ───────────────────────────────────────────────
494
506
  function dispatch(event, ir, input, state, roles) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intentdna",
3
- "version": "1.7.4",
3
+ "version": "1.7.5",
4
4
  "description": "Intent DNA — Declarative policy layer for AI agent behavior",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",