@nirnex/cli 2.0.3 → 4.0.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.
Files changed (54) hide show
  1. package/dist/commands/index.js +2 -2
  2. package/dist/commands/index.js.map +1 -1
  3. package/dist/commands/query.js +2 -2
  4. package/dist/commands/query.js.map +1 -1
  5. package/dist/commands/runtime.d.ts +2 -0
  6. package/dist/commands/runtime.d.ts.map +1 -0
  7. package/dist/commands/runtime.js +60 -0
  8. package/dist/commands/runtime.js.map +1 -0
  9. package/dist/commands/setup.d.ts +6 -0
  10. package/dist/commands/setup.d.ts.map +1 -0
  11. package/dist/commands/setup.js +395 -0
  12. package/dist/commands/setup.js.map +1 -0
  13. package/dist/commands/status.d.ts +1 -1
  14. package/dist/commands/status.d.ts.map +1 -1
  15. package/dist/commands/status.js +151 -20
  16. package/dist/commands/status.js.map +1 -1
  17. package/dist/commands/trace.d.ts.map +1 -1
  18. package/dist/commands/trace.js +74 -1
  19. package/dist/commands/trace.js.map +1 -1
  20. package/dist/index.js +21 -10
  21. package/dist/index.js.map +1 -1
  22. package/dist/runtime/bootstrap.d.ts +2 -0
  23. package/dist/runtime/bootstrap.d.ts.map +1 -0
  24. package/dist/runtime/bootstrap.js +90 -0
  25. package/dist/runtime/bootstrap.js.map +1 -0
  26. package/dist/runtime/entry.d.ts +2 -0
  27. package/dist/runtime/entry.d.ts.map +1 -0
  28. package/dist/runtime/entry.js +86 -0
  29. package/dist/runtime/entry.js.map +1 -0
  30. package/dist/runtime/envelope.d.ts +4 -0
  31. package/dist/runtime/envelope.d.ts.map +1 -0
  32. package/dist/runtime/envelope.js +113 -0
  33. package/dist/runtime/envelope.js.map +1 -0
  34. package/dist/runtime/guard.d.ts +2 -0
  35. package/dist/runtime/guard.d.ts.map +1 -0
  36. package/dist/runtime/guard.js +114 -0
  37. package/dist/runtime/guard.js.map +1 -0
  38. package/dist/runtime/session.d.ts +13 -0
  39. package/dist/runtime/session.d.ts.map +1 -0
  40. package/dist/runtime/session.js +111 -0
  41. package/dist/runtime/session.js.map +1 -0
  42. package/dist/runtime/trace-hook.d.ts +2 -0
  43. package/dist/runtime/trace-hook.d.ts.map +1 -0
  44. package/dist/runtime/trace-hook.js +102 -0
  45. package/dist/runtime/trace-hook.js.map +1 -0
  46. package/dist/runtime/types.d.ts +108 -0
  47. package/dist/runtime/types.d.ts.map +1 -0
  48. package/dist/runtime/types.js +3 -0
  49. package/dist/runtime/types.js.map +1 -0
  50. package/dist/runtime/validate.d.ts +2 -0
  51. package/dist/runtime/validate.d.ts.map +1 -0
  52. package/dist/runtime/validate.js +91 -0
  53. package/dist/runtime/validate.js.map +1 -0
  54. package/package.json +1 -1
@@ -1,31 +1,162 @@
1
- // Command: dev status
2
- // Reads the local .aidos.db (or path from AIDOS_DB env var)
3
- // and prints a one-line index summary.
1
+ // Command: nirnex status
2
+ // Shows project readiness, index health, and freshness.
4
3
  import { openDb, indexStats } from '@nirnex/core';
5
4
  import path from 'node:path';
6
- import { existsSync } from 'node:fs';
7
- export function statusCommand(args) {
8
- // Resolve db path: flag --db <path> > env var > cwd default
9
- let dbPath;
10
- const dbFlagIdx = args.indexOf('--db');
11
- if (dbFlagIdx !== -1 && args[dbFlagIdx + 1]) {
12
- dbPath = args[dbFlagIdx + 1];
5
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
6
+ import { execSync } from 'node:child_process';
7
+ function tick(msg) {
8
+ process.stdout.write(` \x1b[32m✔\x1b[0m ${msg}\n`);
9
+ }
10
+ function cross(msg) {
11
+ process.stdout.write(` \x1b[31m✘\x1b[0m ${msg}\n`);
12
+ }
13
+ function warn(msg) {
14
+ process.stdout.write(` \x1b[33m!\x1b[0m ${msg}\n`);
15
+ }
16
+ export function statusCommand(_args) {
17
+ const cwd = process.cwd();
18
+ const configPath = path.join(cwd, 'nirnex.config.json');
19
+ const dbPath = path.join(cwd, '.aidos.db');
20
+ console.log('\n\x1b[1mNirnex Status\x1b[0m\n');
21
+ // Check if project is Nirnex-enabled
22
+ const isEnabled = existsSync(configPath);
23
+ if (!isEnabled) {
24
+ cross('nirnex.config.json not found — project is not Nirnex-enabled');
25
+ console.log('\n Run \x1b[1mnirnex setup\x1b[0m to initialize this project.\n');
26
+ process.exit(1);
27
+ }
28
+ let config = {};
29
+ try {
30
+ config = JSON.parse(readFileSync(configPath, 'utf8'));
31
+ tick(`Project: \x1b[1m${config.projectName ?? path.basename(cwd)}\x1b[0m`);
32
+ }
33
+ catch {
34
+ warn('nirnex.config.json is malformed');
35
+ }
36
+ // Check .ai/ structure
37
+ const aiDir = path.join(cwd, '.ai');
38
+ existsSync(aiDir)
39
+ ? tick('.ai/ workspace present')
40
+ : cross('.ai/ workspace missing — re-run nirnex setup');
41
+ const promptsDir = path.join(aiDir, 'prompts');
42
+ existsSync(path.join(promptsDir, 'analyst.md')) && existsSync(path.join(promptsDir, 'implementer.md'))
43
+ ? tick('.ai/prompts/ configured')
44
+ : warn('.ai/prompts/ missing analyst.md or implementer.md');
45
+ // Check index
46
+ const dbExists = existsSync(dbPath);
47
+ if (!dbExists) {
48
+ cross('Index not found — run \x1b[1mnirnex index --rebuild\x1b[0m');
13
49
  }
14
- else if (process.env['AIDOS_DB']) {
15
- dbPath = process.env['AIDOS_DB'];
50
+ else {
51
+ try {
52
+ const db = openDb(dbPath);
53
+ const stats = indexStats(db);
54
+ db.close();
55
+ if (stats.moduleCount === 0) {
56
+ warn(`Index empty (0 modules) — run \x1b[1mnirnex index --rebuild\x1b[0m`);
57
+ }
58
+ else {
59
+ tick(`Index: ${stats.moduleCount} modules, ${stats.edgeCount} edges, schema v${stats.schemaVersion}`);
60
+ }
61
+ }
62
+ catch (e) {
63
+ warn(`Index read error: ${e instanceof Error ? e.message : String(e)}`);
64
+ }
65
+ }
66
+ // Check freshness
67
+ try {
68
+ const currentHead = execSync('git rev-parse HEAD', { cwd, encoding: 'utf8' }).trim();
69
+ if (dbExists) {
70
+ try {
71
+ const db = openDb(dbPath);
72
+ const meta = db.prepare('SELECT value FROM _meta WHERE key = ?').get('commit_hash');
73
+ db.close();
74
+ if (meta?.value === currentHead) {
75
+ tick('Index is fresh (matches current HEAD)');
76
+ }
77
+ else {
78
+ warn('Index is stale — run \x1b[1mnirnex index\x1b[0m to refresh');
79
+ }
80
+ }
81
+ catch { }
82
+ }
83
+ }
84
+ catch {
85
+ // not a git repo or git not available
86
+ }
87
+ // Check git hook
88
+ const hookPath = path.join(cwd, '.git', 'hooks', 'post-commit');
89
+ existsSync(hookPath)
90
+ ? tick('Git post-commit hook installed')
91
+ : warn('Git post-commit hook not installed (index may drift)');
92
+ // Check Claude hooks
93
+ console.log('');
94
+ console.log('\x1b[1mClaude Hooks\x1b[0m');
95
+ const claudeSettingsPath = path.join(cwd, '.claude', 'settings.json');
96
+ if (!existsSync(claudeSettingsPath)) {
97
+ warn('.claude/settings.json not found — run nirnex setup to install hooks');
16
98
  }
17
99
  else {
18
- dbPath = path.join(process.cwd(), '.aidos.db');
100
+ try {
101
+ const settings = JSON.parse(readFileSync(claudeSettingsPath, 'utf8'));
102
+ settings.hooks
103
+ ? tick('.claude/settings.json hook bindings present')
104
+ : warn('.claude/settings.json has no hooks section — re-run nirnex setup');
105
+ }
106
+ catch {
107
+ warn('.claude/settings.json is malformed');
108
+ }
109
+ }
110
+ const claudeHooks = [
111
+ 'nirnex-bootstrap.sh',
112
+ 'nirnex-entry.sh',
113
+ 'nirnex-guard.sh',
114
+ 'nirnex-trace.sh',
115
+ 'nirnex-validate.sh',
116
+ ];
117
+ const hooksDir = path.join(cwd, '.claude', 'hooks');
118
+ let hooksMissing = 0;
119
+ for (const h of claudeHooks) {
120
+ if (!existsSync(path.join(hooksDir, h)))
121
+ hooksMissing++;
19
122
  }
20
- const isNew = !existsSync(dbPath);
21
- const db = openDb(dbPath);
22
- const stats = indexStats(db);
23
- db.close();
24
- if (isNew || stats.moduleCount === 0) {
25
- console.log(`index empty, ${stats.moduleCount} modules, ${stats.edgeCount} edges [db: ${dbPath}]`);
123
+ hooksMissing === 0
124
+ ? tick('All 5 Claude hook scripts present')
125
+ : warn(`${hooksMissing} Claude hook script(s) missing in .claude/hooks/ — re-run nirnex setup`);
126
+ // Check runtime state
127
+ const runtimeDir = path.join(cwd, '.ai-index', 'runtime');
128
+ const sessionsDir = path.join(runtimeDir, 'sessions');
129
+ const envelopesDir = path.join(runtimeDir, 'envelopes');
130
+ if (existsSync(sessionsDir)) {
131
+ try {
132
+ const sessions = readdirSync(sessionsDir).filter(f => f.endsWith('.json'));
133
+ tick(`Runtime sessions: ${sessions.length} recorded`);
134
+ }
135
+ catch {
136
+ warn('Could not read runtime sessions dir');
137
+ }
26
138
  }
27
139
  else {
28
- console.log(`index ok ${stats.moduleCount} modules, ${stats.edgeCount} edges, schema v${stats.schemaVersion} [db: ${dbPath}]`);
140
+ tick('Runtime sessions: none yet (hooks not yet triggered)');
141
+ }
142
+ if (existsSync(envelopesDir)) {
143
+ try {
144
+ const envelopes = readdirSync(envelopesDir).filter(f => f.endsWith('.json'));
145
+ const activeCount = envelopes.filter(f => {
146
+ try {
147
+ const e = JSON.parse(readFileSync(path.join(envelopesDir, f), 'utf8'));
148
+ return e.status === 'active';
149
+ }
150
+ catch {
151
+ return false;
152
+ }
153
+ }).length;
154
+ tick(`Task envelopes: ${envelopes.length} total, ${activeCount} active`);
155
+ }
156
+ catch {
157
+ warn('Could not read envelopes dir');
158
+ }
29
159
  }
160
+ console.log('');
30
161
  }
31
162
  //# sourceMappingURL=status.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,4DAA4D;AAC5D,uCAAuC;AAEvC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,4DAA4D;IAC5D,IAAI,MAA0B,CAAC;IAE/B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,SAAS,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC;QAC5C,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IAC/B,CAAC;SAAM,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC7B,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,KAAK,IAAI,KAAK,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CACT,gBAAgB,KAAK,CAAC,WAAW,aAAa,KAAK,CAAC,SAAS,gBAAgB,MAAM,GAAG,CACvF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,cAAc,KAAK,CAAC,WAAW,aAAa,KAAK,CAAC,SAAS,mBAAmB,KAAK,CAAC,aAAa,UAAU,MAAM,GAAG,CACrH,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/commands/trace.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAEjD"}
1
+ {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/commands/trace.ts"],"names":[],"mappings":"AA6BA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiEjD"}
@@ -1,4 +1,77 @@
1
+ // Command: nirnex trace
2
+ // View execution traces from .ai-index/traces/
3
+ import path from 'node:path';
4
+ import { existsSync } from 'node:fs';
5
+ import { listTraces, readTrace } from '@nirnex/core/dist/trace.js';
6
+ function tick(msg) {
7
+ process.stdout.write(` \x1b[32m✔\x1b[0m ${msg}\n`);
8
+ }
9
+ function info(msg) {
10
+ process.stdout.write(` \x1b[90m·\x1b[0m ${msg}\n`);
11
+ }
12
+ function warn(msg) {
13
+ process.stdout.write(` \x1b[33m!\x1b[0m ${msg}\n`);
14
+ }
15
+ const TRACE_USAGE = `
16
+ nirnex trace [options]
17
+
18
+ Options:
19
+ --last Show the most recent trace in full
20
+ --list List recent traces (default)
21
+ --id <trace_id> Show a specific trace by ID
22
+ --limit <n> Number of traces to list (default: 20)
23
+ `.trimStart();
1
24
  export function traceCommand(args) {
2
- console.log('[dev trace] executing trace command');
25
+ const cwd = process.cwd();
26
+ const configPath = path.join(cwd, 'nirnex.config.json');
27
+ if (!existsSync(configPath)) {
28
+ warn('Not a Nirnex project. Run nirnex setup first.');
29
+ process.exit(1);
30
+ }
31
+ // Parse flags
32
+ const showLast = args.includes('--last');
33
+ const idIdx = args.indexOf('--id');
34
+ const traceId = idIdx !== -1 ? args[idIdx + 1] : undefined;
35
+ const limitIdx = args.indexOf('--limit');
36
+ const limit = limitIdx !== -1 ? parseInt(args[limitIdx + 1], 10) || 20 : 20;
37
+ const help = args.includes('--help') || args.includes('-h');
38
+ if (help) {
39
+ process.stdout.write(TRACE_USAGE + '\n');
40
+ return;
41
+ }
42
+ // Show specific trace by ID
43
+ if (traceId) {
44
+ const trace = readTrace(cwd, traceId);
45
+ if (!trace) {
46
+ warn(`Trace not found: ${traceId}`);
47
+ process.exit(1);
48
+ }
49
+ console.log(JSON.stringify(trace, null, 2));
50
+ return;
51
+ }
52
+ // List traces
53
+ const traces = listTraces(cwd, showLast ? 1 : limit);
54
+ if (traces.length === 0) {
55
+ info('No traces found in .ai-index/traces/');
56
+ info('Traces are written by nirnex plan and the runtime entry hook.');
57
+ return;
58
+ }
59
+ if (showLast) {
60
+ // Print full JSON of most recent trace
61
+ const full = readTrace(cwd, traces[0].trace_id);
62
+ console.log(JSON.stringify(full ?? traces[0], null, 2));
63
+ return;
64
+ }
65
+ // Print table
66
+ console.log('\n\x1b[1mNirnex Traces\x1b[0m\n');
67
+ console.log(` ${'Trace ID'.padEnd(34)} ${'Date'.padEnd(12)} ${'Intent'.padEnd(20)} ${'Conf'.padEnd(6)} ${'Lane'}`);
68
+ console.log(' ' + '─'.repeat(80));
69
+ for (const t of traces) {
70
+ const intent = (t.intent ?? 'unknown').slice(0, 18);
71
+ const score = t.confidence_score != null ? String(t.confidence_score) : '—';
72
+ const lane = t.lane ?? '—';
73
+ console.log(` ${t.trace_id.padEnd(34)} ${t.date.padEnd(12)} ${intent.padEnd(20)} ${score.padEnd(6)} ${lane}`);
74
+ }
75
+ console.log('');
3
76
  }
4
77
  //# sourceMappingURL=trace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/commands/trace.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/commands/trace.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,26 +1,34 @@
1
1
  #!/usr/bin/env node
2
- // nirnex dev CLI
3
- // Usage: dev <command> [args]
4
- // Commands: plan | query | status | replay
2
+ // Nirnex CLI — Decision Intelligence for software delivery
3
+ // Usage: nirnex <command> [args]
5
4
  import { planCommand } from './commands/plan.js';
6
5
  import { queryCommand } from './commands/query.js';
7
6
  import { statusCommand } from './commands/status.js';
8
7
  import { replayCommand } from './commands/replay.js';
9
8
  import { indexCommand } from './commands/index.js';
10
9
  import { traceCommand } from './commands/trace.js';
10
+ import { setupCommand } from './commands/setup.js';
11
+ import { runtimeCommand } from './commands/runtime.js';
11
12
  const [, , command = '', ...rest] = process.argv;
12
13
  const USAGE = `
13
- nirnex dev CLI
14
+ Nirnex Decision Intelligence for software delivery
14
15
 
15
16
  Usage:
16
- dev index [options] Run the indexer
17
- dev plan [options] Generate / update a delivery plan
18
- dev query [options] Query the knowledge index
19
- dev status [options] Show index status
20
- dev replay [options] Replay a past analysis run
21
- dev trace [options] Capture or view traces
17
+ nirnex setup [options] Initialize Nirnex in this repository
18
+ nirnex index [options] Index the codebase into the knowledge graph
19
+ nirnex plan [options] Generate a delivery plan from a spec or query
20
+ nirnex query [options] Query the knowledge graph
21
+ nirnex status [options] Show index and project health
22
+ nirnex trace [options] View execution traces
23
+ nirnex replay [options] Replay a past analysis run
24
+ nirnex runtime <sub> Claude hook pipeline commands (machine-facing)
25
+
26
+ Run \`nirnex setup\` to get started.
22
27
  `.trimStart();
23
28
  switch (command) {
29
+ case 'setup':
30
+ setupCommand(rest).catch(console.error);
31
+ break;
24
32
  case 'index':
25
33
  indexCommand(rest);
26
34
  break;
@@ -39,6 +47,9 @@ switch (command) {
39
47
  case 'trace':
40
48
  traceCommand(rest);
41
49
  break;
50
+ case 'runtime':
51
+ runtimeCommand(rest).catch(console.error);
52
+ break;
42
53
  default:
43
54
  console.log(USAGE);
44
55
  if (command && command !== '--help' && command !== '-h') {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,iBAAiB;AACjB,8BAA8B;AAC9B,2CAA2C;AAE3C,OAAO,EAAE,WAAW,EAAE,MAAQ,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAO,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAO,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAO,qBAAqB,CAAC;AAEpD,MAAM,CAAC,EAAE,AAAD,EAAG,OAAO,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAEjD,MAAM,KAAK,GAAG;;;;;;;;;;CAUb,CAAC,SAAS,EAAE,CAAC;AAEd,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,OAAO;QACV,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM;IACR,KAAK,MAAM;QACT,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM;IACR,KAAK,OAAO;QACV,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM;IACR,KAAK,QAAQ;QACX,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM;IACR,KAAK,QAAQ;QACX,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM;IACR,KAAK,OAAO;QACV,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM;IACR;QACE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,GAAG,CAAC,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM;AACV,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,2DAA2D;AAC3D,iCAAiC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAS,oBAAoB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAQ,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAO,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAO,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAQ,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAQ,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAQ,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,CAAC,EAAE,AAAD,EAAG,OAAO,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAEjD,MAAM,KAAK,GAAG;;;;;;;;;;;;;;CAcb,CAAC,SAAS,EAAE,CAAC;AAEd,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,OAAO;QACV,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM;IACR,KAAK,OAAO;QACV,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM;IACR,KAAK,MAAM;QACT,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM;IACR,KAAK,OAAO;QACV,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM;IACR,KAAK,QAAQ;QACX,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM;IACR,KAAK,QAAQ;QACX,aAAa,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM;IACR,KAAK,OAAO;QACV,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM;IACR,KAAK,SAAS;QACZ,cAAc,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM;IACR;QACE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,IAAI,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,GAAG,CAAC,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM;AACV,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runBootstrap(): Promise<void>;
2
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"AAsCA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CA8DlD"}
@@ -0,0 +1,90 @@
1
+ // SessionStart hook handler.
2
+ // Called by .claude/hooks/nirnex-bootstrap.sh at the start of each Claude session.
3
+ // Reads nirnex.config.json, checks index freshness, writes env vars to CLAUDE_ENV_FILE,
4
+ // and creates a session state file.
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { execSync } from 'node:child_process';
8
+ import { createSession, saveSession, loadSession } from './session.js';
9
+ function readStdin() {
10
+ return new Promise(resolve => {
11
+ let buf = '';
12
+ process.stdin.setEncoding('utf8');
13
+ process.stdin.on('data', chunk => { buf += chunk; });
14
+ process.stdin.on('end', () => resolve(buf));
15
+ });
16
+ }
17
+ function getIndexFreshness(repoRoot) {
18
+ try {
19
+ const head = execSync('git rev-parse HEAD', { cwd: repoRoot, encoding: 'utf8' }).trim();
20
+ const dbPath = path.join(repoRoot, '.aidos.db');
21
+ if (!fs.existsSync(dbPath))
22
+ return { freshness: 'unknown', head };
23
+ // Read stored commit hash from DB
24
+ const { openDb } = require('@nirnex/core/dist/db.js');
25
+ const db = openDb(dbPath);
26
+ const meta = db.prepare('SELECT value FROM _meta WHERE key = ?').get('commit_hash');
27
+ db.close();
28
+ return { freshness: meta?.value === head ? 'fresh' : 'stale', head };
29
+ }
30
+ catch {
31
+ return { freshness: 'unknown', head: '' };
32
+ }
33
+ }
34
+ export async function runBootstrap() {
35
+ const raw = await readStdin();
36
+ let hookData = { session_id: 'unknown' };
37
+ try {
38
+ hookData = JSON.parse(raw || '{}');
39
+ }
40
+ catch {
41
+ // Non-fatal: proceed with generated session id
42
+ }
43
+ const sessionId = hookData.session_id || `sess_${Date.now().toString(36)}`;
44
+ const repoRoot = process.cwd();
45
+ // Verify project is Nirnex-enabled
46
+ const configPath = path.join(repoRoot, 'nirnex.config.json');
47
+ if (!fs.existsSync(configPath)) {
48
+ // Not a Nirnex project — exit silently
49
+ process.exit(0);
50
+ }
51
+ let config = {};
52
+ try {
53
+ config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
54
+ }
55
+ catch {
56
+ process.exit(0);
57
+ }
58
+ const { freshness, head } = getIndexFreshness(repoRoot);
59
+ // Create or update session
60
+ const existing = loadSession(repoRoot, sessionId);
61
+ const session = existing ?? createSession(repoRoot, sessionId, {
62
+ index_freshness: freshness,
63
+ current_head: head,
64
+ policy_mode: config.hooks?.policyMode ?? 'standard',
65
+ });
66
+ if (!existing) {
67
+ saveSession(repoRoot, session);
68
+ }
69
+ // Write env vars to CLAUDE_ENV_FILE if set
70
+ const envFile = process.env.CLAUDE_ENV_FILE;
71
+ if (envFile) {
72
+ const envVars = [
73
+ `NIRNEX_REPO_ROOT=${repoRoot}`,
74
+ `NIRNEX_DB_PATH=${path.join(repoRoot, '.aidos.db')}`,
75
+ `NIRNEX_INDEX_FRESHNESS=${freshness}`,
76
+ `NIRNEX_CURRENT_HEAD=${head}`,
77
+ `NIRNEX_POLICY_MODE=${session.policy_mode}`,
78
+ `NIRNEX_SESSION_ID=${sessionId}`,
79
+ ].join('\n') + '\n';
80
+ try {
81
+ fs.writeFileSync(envFile, envVars, 'utf8');
82
+ }
83
+ catch {
84
+ // Non-fatal
85
+ }
86
+ }
87
+ // No JSON output needed for SessionStart (env vars are the output)
88
+ process.exit(0);
89
+ }
90
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runEntry(): Promise<void>;
2
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/runtime/entry.ts"],"names":[],"mappings":"AAoBA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CA6E9C"}
@@ -0,0 +1,86 @@
1
+ // UserPromptSubmit hook handler.
2
+ // Called before Claude processes each user prompt.
3
+ // Builds ECO from the prompt, creates a task envelope, writes session state,
4
+ // and returns additionalContext so Claude sees the envelope before acting.
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import { buildEnvelope, formatEnvelopeContext } from './envelope.js';
8
+ import { loadSession, saveSession, saveEnvelope } from './session.js';
9
+ function readStdin() {
10
+ return new Promise(resolve => {
11
+ let buf = '';
12
+ process.stdin.setEncoding('utf8');
13
+ process.stdin.on('data', chunk => { buf += chunk; });
14
+ process.stdin.on('end', () => resolve(buf));
15
+ });
16
+ }
17
+ export async function runEntry() {
18
+ const raw = await readStdin();
19
+ let hookData = {
20
+ session_id: 'unknown',
21
+ hook_event_name: 'UserPromptSubmit',
22
+ prompt: '',
23
+ };
24
+ try {
25
+ hookData = JSON.parse(raw || '{}');
26
+ }
27
+ catch {
28
+ // Non-fatal: proceed with empty prompt
29
+ }
30
+ const repoRoot = process.env.NIRNEX_REPO_ROOT ?? process.cwd();
31
+ const sessionId = hookData.session_id ?? process.env.NIRNEX_SESSION_ID ?? `sess_${Date.now().toString(36)}`;
32
+ const prompt = hookData.prompt ?? '';
33
+ // Skip if not a Nirnex project
34
+ if (!fs.existsSync(path.join(repoRoot, 'nirnex.config.json'))) {
35
+ process.exit(0);
36
+ }
37
+ // Skip very short or empty prompts (e.g. clarifications, single words)
38
+ if (prompt.trim().length < 10) {
39
+ process.exit(0);
40
+ }
41
+ let eco = {};
42
+ try {
43
+ const { buildECO } = await import('@nirnex/core/dist/eco.js');
44
+ eco = buildECO(null, repoRoot, { query: prompt });
45
+ }
46
+ catch {
47
+ // Degraded mode: use a minimal ECO
48
+ eco = {
49
+ recommended_lane: 'A',
50
+ forced_lane_minimum: 'A',
51
+ confidence_score: 50,
52
+ forced_unknown: false,
53
+ blocked: false,
54
+ intent: { primary: 'unknown' },
55
+ modules_touched: [],
56
+ penalties: [],
57
+ escalation_reasons: [],
58
+ boundary_warnings: [],
59
+ eco_dimensions: {},
60
+ evidence_checkpoints: {},
61
+ };
62
+ }
63
+ const envelope = buildEnvelope(eco, prompt, sessionId);
64
+ // Persist envelope and link to session
65
+ saveEnvelope(repoRoot, envelope);
66
+ const session = loadSession(repoRoot, sessionId);
67
+ if (session) {
68
+ session.active_task_id = envelope.task_id;
69
+ session.tasks.push(envelope.task_id);
70
+ saveSession(repoRoot, session);
71
+ }
72
+ // Block if ECO says blocked
73
+ if (eco.blocked) {
74
+ const output = {
75
+ blockMessage: `[Nirnex] Task blocked by ECO. Reasons: ${(eco.escalation_reasons ?? []).join('; ') || 'unknown'}. Please revise the spec or run nirnex plan for details.`,
76
+ };
77
+ process.stdout.write(JSON.stringify(output));
78
+ process.exit(0);
79
+ }
80
+ // Return envelope context to Claude
81
+ const contextText = formatEnvelopeContext(envelope);
82
+ const output = { additionalContext: contextText };
83
+ process.stdout.write(JSON.stringify(output));
84
+ process.exit(0);
85
+ }
86
+ //# sourceMappingURL=entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/runtime/entry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { TaskEnvelope } from './types.js';
2
+ export declare function buildEnvelope(eco: Record<string, any>, prompt: string, sessionId: string): TaskEnvelope;
3
+ export declare function formatEnvelopeContext(envelope: TaskEnvelope): string;
4
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/runtime/envelope.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAQ,MAAM,YAAY,CAAC;AAyBhD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAmEvG;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CA0BpE"}