nimai-cli 0.4.9 → 0.5.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 (46) hide show
  1. package/dist/commands/new.d.ts +2 -0
  2. package/dist/commands/new.d.ts.map +1 -1
  3. package/dist/commands/new.js +3 -4
  4. package/dist/commands/new.js.map +1 -1
  5. package/dist/commands/review.d.ts +2 -1
  6. package/dist/commands/review.d.ts.map +1 -1
  7. package/dist/commands/review.js +4 -2
  8. package/dist/commands/review.js.map +1 -1
  9. package/dist/commands/spec.d.ts +0 -8
  10. package/dist/commands/spec.d.ts.map +1 -1
  11. package/dist/commands/spec.js +6 -157
  12. package/dist/commands/spec.js.map +1 -1
  13. package/dist/commands/validate.d.ts.map +1 -1
  14. package/dist/commands/validate.js +21 -17
  15. package/dist/commands/validate.js.map +1 -1
  16. package/dist/config.d.ts +1 -29
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +3 -29
  19. package/dist/config.js.map +1 -1
  20. package/dist/index.js +12 -30
  21. package/dist/index.js.map +1 -1
  22. package/package.json +4 -8
  23. package/dist/adapters/anthropic.d.ts +0 -9
  24. package/dist/adapters/anthropic.d.ts.map +0 -1
  25. package/dist/adapters/anthropic.js +0 -43
  26. package/dist/adapters/anthropic.js.map +0 -1
  27. package/dist/adapters/errors.d.ts +0 -5
  28. package/dist/adapters/errors.d.ts.map +0 -1
  29. package/dist/adapters/errors.js +0 -13
  30. package/dist/adapters/errors.js.map +0 -1
  31. package/dist/adapters/ollama.d.ts +0 -8
  32. package/dist/adapters/ollama.d.ts.map +0 -1
  33. package/dist/adapters/ollama.js +0 -34
  34. package/dist/adapters/ollama.js.map +0 -1
  35. package/dist/adapters/openai.d.ts +0 -9
  36. package/dist/adapters/openai.d.ts.map +0 -1
  37. package/dist/adapters/openai.js +0 -46
  38. package/dist/adapters/openai.js.map +0 -1
  39. package/dist/adapters/types.d.ts +0 -9
  40. package/dist/adapters/types.d.ts.map +0 -1
  41. package/dist/adapters/types.js +0 -3
  42. package/dist/adapters/types.js.map +0 -1
  43. package/dist/commands/spec-review.d.ts +0 -5
  44. package/dist/commands/spec-review.d.ts.map +0 -1
  45. package/dist/commands/spec-review.js +0 -85
  46. package/dist/commands/spec-review.js.map +0 -1
@@ -1,5 +1,7 @@
1
+ import type { Tier } from 'nimai-core';
1
2
  export interface NewOptions {
2
3
  force: boolean;
4
+ tier?: Tier;
3
5
  }
4
6
  export declare function runNew(outputPath: string, options: NewOptions): void;
5
7
  //# sourceMappingURL=new.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAkBpE"}
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI,CAkBpE"}
@@ -37,19 +37,18 @@ exports.runNew = runNew;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  const nimai_core_1 = require("nimai-core");
40
- const nimai_core_2 = require("nimai-core");
41
40
  function runNew(outputPath, options) {
42
41
  const resolved = path.resolve(outputPath);
43
42
  if (fs.existsSync(resolved) && !options.force) {
44
43
  console.error(`Error: "${resolved}" already exists. Use --force to overwrite.`);
45
44
  process.exit(1);
46
45
  }
47
- const templatePath = path.join(nimai_core_2.FORGE_ROOT, 'FORGE-spec-template.md');
48
- const template = (0, nimai_core_1.loadTemplate)(templatePath);
46
+ const tier = options.tier ?? 'lite';
47
+ const templateContent = (0, nimai_core_1.loadTierTemplate)(tier);
49
48
  const dir = path.dirname(resolved);
50
49
  if (!fs.existsSync(dir))
51
50
  fs.mkdirSync(dir, { recursive: true });
52
- fs.writeFileSync(resolved, template.raw, 'utf-8');
51
+ fs.writeFileSync(resolved, templateContent, 'utf-8');
53
52
  console.log(`Spec scaffolded at ${resolved}`);
54
53
  }
55
54
  //# sourceMappingURL=new.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,wBAkBC;AA3BD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAA0C;AAC1C,2CAAwC;AAMxC,SAAgB,MAAM,CAAC,UAAkB,EAAE,OAAmB;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE1C,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC9C,OAAO,CAAC,KAAK,CACX,WAAW,QAAQ,6CAA6C,CACjE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,uBAAU,EAAE,wBAAwB,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,IAAA,yBAAY,EAAC,YAAY,CAAC,CAAC;IAE5C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,wBAkBC;AA5BD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAA8C;AAQ9C,SAAgB,MAAM,CAAC,UAAkB,EAAE,OAAmB;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE1C,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC9C,OAAO,CAAC,KAAK,CACX,WAAW,QAAQ,6CAA6C,CACjE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAS,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC;IAC1C,MAAM,eAAe,GAAG,IAAA,6BAAgB,EAAC,IAAI,CAAC,CAAC;IAE/C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;AAChD,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export interface ReviewOptions {
2
+ target: 'spec' | 'implementation';
2
3
  out?: string;
3
4
  }
4
- export declare function runReview(specPath: string, options: ReviewOptions): void;
5
+ export declare function runReview(specPath: string, options?: ReviewOptions): void;
5
6
  //# sourceMappingURL=review.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CAsBxE"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkC,GAAG,IAAI,CAwB7F"}
@@ -37,7 +37,7 @@ exports.runReview = runReview;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  const nimai_core_1 = require("nimai-core");
40
- function runReview(specPath, options) {
40
+ function runReview(specPath, options = { target: 'spec' }) {
41
41
  const resolved = path.resolve(specPath);
42
42
  let specContent;
43
43
  try {
@@ -47,7 +47,9 @@ function runReview(specPath, options) {
47
47
  console.error(`Error: Cannot read spec at "${resolved}"`);
48
48
  process.exit(1);
49
49
  }
50
- const reviewerPrompt = (0, nimai_core_1.buildPrompt2)(specContent);
50
+ const reviewerPrompt = options.target === 'spec'
51
+ ? (0, nimai_core_1.buildPrompt15)(specContent)
52
+ : (0, nimai_core_1.buildPrompt2)(specContent);
51
53
  if (options.out) {
52
54
  const outPath = path.resolve(options.out);
53
55
  const dir = path.dirname(outPath);
@@ -1 +1 @@
1
- {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,8BAsBC;AA9BD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAA0C;AAM1C,SAAgB,SAAS,CAAC,QAAgB,EAAE,OAAsB;IAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAExC,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,+BAA+B,QAAQ,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,cAAc,GAAG,IAAA,yBAAY,EAAC,WAAW,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,8BAwBC;AAjCD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAAyD;AAOzD,SAAgB,SAAS,CAAC,QAAgB,EAAE,UAAyB,EAAE,MAAM,EAAE,MAAM,EAAE;IACrF,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAExC,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,+BAA+B,QAAQ,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,KAAK,MAAM;QAC9C,CAAC,CAAC,IAAA,0BAAa,EAAC,WAAW,CAAC;QAC5B,CAAC,CAAC,IAAA,yBAAY,EAAC,WAAW,CAAC,CAAC;IAE9B,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
@@ -1,14 +1,6 @@
1
- import type { ModelAdapter } from '../adapters/types';
2
1
  export interface SpecOptions {
3
- hosted: boolean;
4
- standalone: boolean;
5
2
  repoPath: string;
6
3
  out?: string;
7
- validate: boolean;
8
- allowInvalid: boolean;
9
- model?: string;
10
- /** Optional adapter for testing — if provided, skips adapter construction */
11
- adapter?: ModelAdapter;
12
4
  }
13
5
  export declare function runSpec(request: string, options: SpecOptions): Promise<void>;
14
6
  //# sourceMappingURL=spec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKtD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiElF"}
1
+ {"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlF"}
@@ -36,173 +36,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.runSpec = runSpec;
37
37
  const path = __importStar(require("path"));
38
38
  const fs = __importStar(require("fs"));
39
- const readline = __importStar(require("readline"));
40
39
  const nimai_core_1 = require("nimai-core");
41
- const anthropic_1 = require("../adapters/anthropic");
42
- const errors_1 = require("../adapters/errors");
43
- const config_1 = require("../config");
44
40
  async function runSpec(request, options) {
45
- // ── Flag validation ──────────────────────────────────────────────────────────
46
- if (!options.hosted && !options.standalone) {
47
- console.error('Error: specify --hosted or --standalone');
48
- process.exit(1);
49
- }
50
- if (options.hosted && options.validate) {
51
- console.error('Error: lint is only supported with --standalone.\n' +
52
- 'Use --standalone (and optionally --out) or run: nimai validate <file>');
53
- process.exit(1);
54
- }
55
- if (options.allowInvalid && !options.validate) {
56
- console.error('Error: --allow-invalid only applies when lint is enabled.\n' +
57
- 'In --standalone mode, lint runs by default. Pass --no-validate to disable it.');
58
- process.exit(1);
59
- }
60
- // ── Context + prompt building ─────────────────────────────────────────────────
61
41
  const repoPath = path.resolve(options.repoPath);
62
- const context = (0, nimai_core_1.extractContext)(repoPath, request);
63
- const contextSummary = context
64
- .map(item => `[${item.file}]\n${item.snippet}`)
65
- .join('\n\n---\n\n');
66
- const prompt = (0, nimai_core_1.buildPrompt1)(request, contextSummary);
67
- // ── Clarification heuristics ──────────────────────────────────────────────────
68
- const clarification = (0, nimai_core_1.detectClarifications)(request, context.length);
69
- const needsClarification = clarification.needed;
70
- const clarificationQuestions = clarification.questions;
71
- // ── --hosted: return deterministic bundle, no API call ───────────────────────
72
- if (options.hosted) {
73
- printBundle(prompt, context, clarificationQuestions);
74
- return;
75
- }
76
- // ── --standalone: interactive clarification via readline (if TTY) ───────────
77
- if (needsClarification && process.stdin.isTTY) {
78
- const answers = await promptClarifications(clarificationQuestions);
79
- const answerBlock = answers
80
- .map((a, i) => `Q: ${clarificationQuestions[i]}\nA: ${a}`)
81
- .join('\n\n');
82
- console.error(`\nClarifications captured. Proceeding with enriched context.\n`);
83
- const enrichedSummary = contextSummary
84
- ? `${contextSummary}\n\n--- CLARIFICATIONS ---\n${answerBlock}`
85
- : `--- CLARIFICATIONS ---\n${answerBlock}`;
86
- const enrichedPrompt = (0, nimai_core_1.buildPrompt1)(request, enrichedSummary);
87
- return runSpecWithPrompt(enrichedPrompt, options);
88
- }
89
- if (needsClarification) {
90
- // Non-TTY (scripted/piped): print clarifications as advisory warnings, then proceed
91
- console.error('\nAdvisory: the request may benefit from clarification:');
92
- clarificationQuestions.forEach((q, i) => console.error(` ${i + 1}. ${q}`));
93
- console.error('');
94
- }
95
- // ── --standalone: proceed with original prompt ────────────────────────────
96
- return runSpecWithPrompt(prompt, options);
97
- }
98
- function buildAdapter(adapterName, model, config) {
99
- if (adapterName === 'anthropic') {
100
- const apiKey = process.env['ANTHROPIC_API_KEY'];
101
- if (!apiKey) {
102
- console.error('Error: ANTHROPIC_API_KEY environment variable is not set.\n' +
103
- 'Set it and retry, or use --hosted to generate a prompt bundle without an API key.');
104
- process.exit(1);
105
- }
106
- return new anthropic_1.AnthropicAdapter(apiKey, model);
107
- }
108
- if (adapterName === 'openai') {
109
- const { OpenAIAdapter } = require('../adapters/openai');
110
- const apiKey = process.env['OPENAI_API_KEY'];
111
- if (!apiKey) {
112
- console.error('Error: OPENAI_API_KEY environment variable is not set.');
113
- process.exit(1);
114
- }
115
- return new OpenAIAdapter(apiKey, model, config.openaiBaseUrl);
116
- }
117
- if (adapterName === 'ollama') {
118
- const { OllamaAdapter } = require('../adapters/ollama');
119
- return new OllamaAdapter(config.ollamaUrl, model);
120
- }
121
- console.error(`Error: Unknown adapter "${adapterName}". Valid values: anthropic, openai, ollama`);
122
- process.exit(1);
123
- }
124
- /** Extract the standalone generation + output + validate logic into a helper so
125
- * it can be called with either the original prompt or an enriched (post-clarification) prompt. */
126
- async function runSpecWithPrompt(prompt, options) {
127
- let adapter;
128
- if (options.adapter) {
129
- adapter = options.adapter;
130
- }
131
- else {
132
- const fileConfig = (0, config_1.loadConfig)(process.cwd());
133
- const config = (0, config_1.resolveConfig)(fileConfig, { model: options.model });
134
- adapter = buildAdapter(config.adapter, config.model, config);
135
- if (!adapter)
136
- process.exit(1);
137
- }
138
- let specContent;
139
- try {
140
- specContent = await adapter.generate(prompt);
141
- }
142
- catch (err) {
143
- console.error(`Error: ${err instanceof errors_1.AdapterError ? err.message : err.message}`);
144
- process.exit(1);
145
- }
42
+ const liteTemplate = (0, nimai_core_1.loadTierTemplate)('lite');
43
+ const fullTemplate = (0, nimai_core_1.loadTierTemplate)('full');
44
+ const protocolPrompt = (0, nimai_core_1.buildSpecProtocol)(request, repoPath, liteTemplate, fullTemplate);
146
45
  if (options.out) {
147
46
  const outPath = path.resolve(options.out);
148
47
  const dir = path.dirname(outPath);
149
48
  if (!fs.existsSync(dir))
150
49
  fs.mkdirSync(dir, { recursive: true });
151
- fs.writeFileSync(outPath, specContent, 'utf-8');
152
- console.log(`Spec written to ${outPath}`);
50
+ fs.writeFileSync(outPath, protocolPrompt, 'utf-8');
51
+ console.log(`Protocol prompt written to ${outPath}`);
153
52
  }
154
53
  else {
155
- console.log(specContent);
156
- }
157
- if (options.validate) {
158
- const issues = (0, nimai_core_1.lintContent)(specContent);
159
- const hard = issues.filter(i => !i.advisory);
160
- const advisory = issues.filter(i => i.advisory);
161
- if (hard.length === 0 && advisory.length === 0) {
162
- console.error('✓ Validation passed — no issues found.');
163
- }
164
- else {
165
- if (hard.length > 0) {
166
- console.error(`\nValidation: ${hard.length} issue(s) found`);
167
- hard.forEach(i => console.error(` ${i.type === 'missing_section' ? '' : `Line ${i.line}: `}${i.message}`));
168
- }
169
- if (advisory.length > 0) {
170
- console.error(`\nAdvisory warnings: ${advisory.length}`);
171
- advisory.forEach(i => console.error(` warn: ${i.message}`));
172
- }
173
- if (hard.length > 0 && !options.allowInvalid) {
174
- process.exit(1);
175
- }
176
- }
177
- }
178
- }
179
- /** Prompts the user for answers to clarification questions via readline. */
180
- async function promptClarifications(questions) {
181
- const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
182
- const ask = (q) => new Promise(resolve => rl.question(` ${q}\n > `, resolve));
183
- console.error('\nClarifications needed before generating the spec:\n');
184
- const answers = [];
185
- for (const q of questions) {
186
- answers.push(await ask(q));
187
- }
188
- rl.close();
189
- return answers;
190
- }
191
- function printBundle(prompt, context, clarifications = []) {
192
- console.log('=== NIMAI SPEC BUNDLE ===');
193
- console.log('');
194
- if (clarifications.length > 0) {
195
- console.log('--- PREFLIGHT CLARIFICATIONS ---');
196
- console.log('The following questions may improve spec quality. Answer them and re-run, or proceed:');
197
- clarifications.forEach((q, i) => console.log(` ${i + 1}. ${q}`));
198
- console.log('');
199
- }
200
- console.log('--- PROMPT (paste into your AI agent) ---');
201
- console.log(prompt);
202
- if (context.length > 0) {
203
- console.log('');
204
- console.log(`--- CONTEXT FILES INCLUDED (${context.length}) ---`);
205
- context.forEach(item => console.log(` • ${item.file} (relevance: ${item.relevance})`));
54
+ console.log(protocolPrompt);
206
55
  }
207
56
  }
208
57
  //# sourceMappingURL=spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/commands/spec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,0BAiBC;AA1BD,2CAA6B;AAC7B,uCAAyB;AACzB,2CAAiE;AAO1D,KAAK,UAAU,OAAO,CAAC,OAAe,EAAE,OAAoB;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,YAAY,GAAG,IAAA,6BAAgB,EAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,IAAA,6BAAgB,EAAC,MAAM,CAAC,CAAC;IAE9C,MAAM,cAAc,GAAG,IAAA,8BAAiB,EAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;IAExF,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,IAAI,CA0DjF"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,IAAI,CA8DjF"}
@@ -13,42 +13,46 @@ function runValidate(specPath, options = {}) {
13
13
  }
14
14
  const hard = issues.filter(i => !i.advisory);
15
15
  const advisory = issues.filter(i => i.advisory);
16
- const PASS_ADVISORY = 'PASS (structural): required sections/fields are complete. Semantic quality is not guaranteed; review acceptance criteria and constraints before execution.';
17
16
  if (hard.length === 0 && advisory.length === 0) {
18
- console.log(PASS_ADVISORY);
17
+ console.log('no impurities found — the spec is clean');
19
18
  return;
20
19
  }
21
- const blanks = hard.filter(i => i.type === 'blank_field');
22
- const nhfi = hard.filter(i => i.type === 'needs_human_input');
23
- const missing = hard.filter(i => i.type === 'missing_section');
24
20
  if (hard.length > 0) {
25
- console.log(`nimai validate: ${hard.length} issue(s) found\n`);
21
+ console.log(`nimai validate: ${hard.length} impurities found\n`);
22
+ const blanks = hard.filter(i => i.type === 'blank_placeholder');
23
+ const missing = hard.filter(i => i.type === 'missing_required_section');
24
+ const preChecked = hard.filter(i => i.type === 'pre_checked_ac');
25
+ const convergence = hard.filter(i => i.type === 'unresolved_convergence' || i.type === 'missing_convergence_section');
26
26
  if (blanks.length > 0) {
27
- console.log(`Blank fields (${blanks.length}):`);
27
+ console.log(`Blank placeholders (${blanks.length}):`);
28
28
  blanks.forEach(i => console.log(` Line ${i.line}: ${i.message}`));
29
29
  console.log('');
30
30
  }
31
- if (nhfi.length > 0) {
32
- console.log(`[NEEDS HUMAN INPUT] flags (${nhfi.length}):`);
33
- nhfi.forEach(i => console.log(` Line ${i.line}: ${i.message}`));
34
- console.log('');
35
- }
36
31
  if (missing.length > 0) {
37
32
  console.log(`Missing required sections (${missing.length}):`);
38
33
  missing.forEach(i => console.log(` ${i.message}`));
39
34
  console.log('');
40
35
  }
36
+ if (preChecked.length > 0) {
37
+ console.log(`Pre-checked acceptance criteria (${preChecked.length}):`);
38
+ preChecked.forEach(i => console.log(` Line ${i.line}: ${i.message}`));
39
+ console.log('');
40
+ }
41
+ if (convergence.length > 0) {
42
+ console.log(`Spec convergence issues (${convergence.length}):`);
43
+ convergence.forEach(i => console.log(` ${i.line > 0 ? `Line ${i.line}: ` : ''}${i.message}`));
44
+ console.log('');
45
+ }
41
46
  }
42
47
  if (advisory.length > 0) {
43
- console.log(`Advisory warnings (${advisory.length})${options.strictArchitecture ? ' [--strict-architecture: treated as errors]' : ''}:`);
48
+ console.log(`Advisory (${advisory.length}):`);
44
49
  advisory.forEach(i => console.log(` warn: ${i.message}`));
45
50
  console.log('');
46
51
  }
47
- if (hard.length > 0 || options.strictArchitecture) {
52
+ if (hard.length > 0) {
48
53
  process.exit(1);
49
54
  }
50
- if (hard.length === 0) {
51
- console.log(PASS_ADVISORY);
52
- }
55
+ // Advisory-only: print pass message
56
+ console.log('no impurities found — the spec is clean');
53
57
  }
54
58
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":";;AAMA,kCA8DC;AApED,2CAAiD;AAMjD,SAAgB,WAAW,CAAC,QAAgB,EAAE,UAA2B,EAAE;IACzE,IAAI,MAAmB,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,IAAA,qBAAQ,EAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,UAAW,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEhD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,MAAM,qBAAqB,CAAC,CAAC;QAEjE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,0BAA0B,CAAC,CAAC;QACxE,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;QACjE,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAwB,IAAI,CAAC,CAAC,IAAI,KAAK,6BAA6B,CAAC,CAAC;QAEtH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;YACtD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;YAC9D,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,oCAAoC,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC;YACvE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,4BAA4B,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC;YAChE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YAC/F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,aAAa,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;QAC9C,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oCAAoC;IACpC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;AACzD,CAAC"}
package/dist/config.d.ts CHANGED
@@ -1,34 +1,6 @@
1
1
  import { z } from 'zod';
2
- declare const ForgeConfigSchema: z.ZodObject<{
3
- adapter: z.ZodOptional<z.ZodEnum<["anthropic", "openai", "ollama"]>>;
4
- model: z.ZodOptional<z.ZodString>;
5
- ollamaUrl: z.ZodOptional<z.ZodString>;
6
- openaiBaseUrl: z.ZodOptional<z.ZodString>;
7
- }, "strip", z.ZodTypeAny, {
8
- adapter?: "anthropic" | "openai" | "ollama" | undefined;
9
- model?: string | undefined;
10
- ollamaUrl?: string | undefined;
11
- openaiBaseUrl?: string | undefined;
12
- }, {
13
- adapter?: "anthropic" | "openai" | "ollama" | undefined;
14
- model?: string | undefined;
15
- ollamaUrl?: string | undefined;
16
- openaiBaseUrl?: string | undefined;
17
- }>;
2
+ declare const ForgeConfigSchema: z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>;
18
3
  export type ForgeConfig = z.infer<typeof ForgeConfigSchema>;
19
- export interface ResolvedConfig {
20
- adapter: 'anthropic' | 'openai' | 'ollama';
21
- model: string;
22
- ollamaUrl: string;
23
- openaiBaseUrl: string;
24
- }
25
4
  export declare function loadConfig(cwd: string): ForgeConfig;
26
- export interface ConfigOverrides {
27
- adapter?: string;
28
- model?: string;
29
- ollamaUrl?: string;
30
- openaiBaseUrl?: string;
31
- }
32
- export declare function resolveConfig(fileConfig: ForgeConfig, overrides?: ConfigOverrides): ResolvedConfig;
33
5
  export {};
34
6
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;EAKrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAWD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAmBnD;AAID,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,WAAW,EACvB,SAAS,GAAE,eAAoB,GAC9B,cAAc,CAehB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,QAAA,MAAM,iBAAiB,uJAA6B,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAmBnD"}
package/dist/config.js CHANGED
@@ -34,24 +34,14 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.loadConfig = loadConfig;
37
- exports.resolveConfig = resolveConfig;
38
37
  const fs = __importStar(require("fs"));
39
38
  const path = __importStar(require("path"));
40
39
  const yaml = __importStar(require("js-yaml"));
41
40
  const zod_1 = require("zod");
42
41
  // ─── Schema ───────────────────────────────────────────────────────────────────
43
- const ForgeConfigSchema = zod_1.z.object({
44
- adapter: zod_1.z.enum(['anthropic', 'openai', 'ollama']).optional(),
45
- model: zod_1.z.string().optional(),
46
- ollamaUrl: zod_1.z.string().url().optional(),
47
- openaiBaseUrl: zod_1.z.string().url().optional(),
48
- });
49
- const DEFAULTS = {
50
- adapter: 'anthropic',
51
- model: 'claude-sonnet-4-6',
52
- ollamaUrl: 'http://localhost:11434',
53
- openaiBaseUrl: 'https://api.openai.com/v1',
54
- };
42
+ // v0.5.0: no model/adapter config — all model interaction happens in the host.
43
+ // The config file is still loaded for forward compatibility; unknown keys are allowed.
44
+ const ForgeConfigSchema = zod_1.z.object({}).passthrough();
55
45
  // ─── Loader ───────────────────────────────────────────────────────────────────
56
46
  function loadConfig(cwd) {
57
47
  const configPath = path.join(cwd, '.nimai', 'config.yaml');
@@ -71,20 +61,4 @@ function loadConfig(cwd) {
71
61
  }
72
62
  return result.data;
73
63
  }
74
- function resolveConfig(fileConfig, overrides = {}) {
75
- return {
76
- adapter: overrides.adapter ??
77
- fileConfig.adapter ??
78
- DEFAULTS.adapter,
79
- model: overrides.model ??
80
- fileConfig.model ??
81
- DEFAULTS.model,
82
- ollamaUrl: overrides.ollamaUrl ??
83
- fileConfig.ollamaUrl ??
84
- DEFAULTS.ollamaUrl,
85
- openaiBaseUrl: overrides.openaiBaseUrl ??
86
- fileConfig.openaiBaseUrl ??
87
- DEFAULTS.openaiBaseUrl,
88
- };
89
- }
90
64
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,gCAmBC;AAWD,sCAkBC;AAhFD,uCAAyB;AACzB,2CAA6B;AAC7B,8CAAgC;AAChC,6BAAwB;AAExB,iFAAiF;AAEjF,MAAM,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IACjC,OAAO,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC7D,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IACtC,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAWH,MAAM,QAAQ,GAAmB;IAC/B,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE,mBAAmB;IAC1B,SAAS,EAAE,wBAAwB;IACnC,aAAa,EAAE,2BAA2B;CAC3C,CAAC;AAEF,iFAAiF;AAEjF,SAAgB,UAAU,CAAC,GAAW;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IAE1C,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,uCAAwC,GAAa,CAAC,OAAO,EAAE,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5G,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAWD,SAAgB,aAAa,CAC3B,UAAuB,EACvB,YAA6B,EAAE;IAE/B,OAAO;QACL,OAAO,EAAG,SAAS,CAAC,OAAqC;YAChD,UAAU,CAAC,OAAO;YAClB,QAAQ,CAAC,OAAO;QACzB,KAAK,EAAI,SAAS,CAAC,KAAK;YACf,UAAU,CAAC,KAAK;YAChB,QAAQ,CAAC,KAAK;QACvB,SAAS,EAAE,SAAS,CAAC,SAAS;YACnB,UAAU,CAAC,SAAS;YACpB,QAAQ,CAAC,SAAS;QAC7B,aAAa,EAAE,SAAS,CAAC,aAAa;YACvB,UAAU,CAAC,aAAa;YACxB,QAAQ,CAAC,aAAa;KACtC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAeA,gCAmBC;AAlCD,uCAAyB;AACzB,2CAA6B;AAC7B,8CAAgC;AAChC,6BAAwB;AAExB,iFAAiF;AACjF,+EAA+E;AAC/E,uFAAuF;AAEvF,MAAM,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAIrD,iFAAiF;AAEjF,SAAgB,UAAU,CAAC,GAAW;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC3D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IAE1C,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,uCAAwC,GAAa,CAAC,OAAO,EAAE,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5G,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
package/dist/index.js CHANGED
@@ -6,34 +6,23 @@ const spec_1 = require("./commands/spec");
6
6
  const validate_1 = require("./commands/validate");
7
7
  const review_1 = require("./commands/review");
8
8
  const new_1 = require("./commands/new");
9
- const spec_review_1 = require("./commands/spec-review");
10
9
  const resolve_spec_1 = require("./commands/resolve-spec");
11
10
  // eslint-disable-next-line @typescript-eslint/no-require-imports
12
11
  const { version } = require('../package.json');
13
12
  const program = new commander_1.Command();
14
13
  program
15
14
  .name('nimai')
16
- .description('Nimai — spec ops CLI for AI work\n\nCommands: spec, validate, review, spec-review, new\nPlanned (M3b): nimai run — execute a spec end-to-end (deferred pending usage data)')
15
+ .description('Nimai — spec ops CLI for AI work\n\nCommands: spec, validate, review, new\nPlanned (M3b): nimai run — execute a spec end-to-end (deferred pending usage data)')
17
16
  .version(version, '-v, --version');
18
17
  program
19
18
  .command('spec <request>')
20
- .description('Generate a FORGE spec from a loose request')
21
- .option('--hosted', 'Output a deterministic prompt+context bundle (no API key needed)')
22
- .option('--standalone', 'Call the model directly to generate the draft spec')
23
- .option('--repo <path>', 'Path to the repository root for context extraction', process.cwd())
19
+ .description('Generate a Nimai protocol prompt from a loose request')
20
+ .option('--repo <path>', 'Path to the repository root', process.cwd())
24
21
  .option('--out <file>', 'Write output to file instead of stdout')
25
- .option('--no-validate', 'Skip lint after --standalone generation (lint runs by default in --standalone mode)')
26
- .option('--allow-invalid', 'Exit 0 even when lint finds issues (only applies in --standalone mode)')
27
- .option('--model <id>', 'Model ID for --standalone mode (overrides .nimai/config.yaml)')
28
22
  .action((request, options) => {
29
23
  (0, spec_1.runSpec)(request, {
30
- hosted: !!options.hosted,
31
- standalone: !!options.standalone,
32
24
  repoPath: options.repo,
33
25
  out: options.out,
34
- validate: options.standalone ? options.validate !== false : false,
35
- allowInvalid: !!options.allowInvalid,
36
- model: options.model,
37
26
  }).catch(err => {
38
27
  console.error('Error:', err.message);
39
28
  process.exit(1);
@@ -41,34 +30,27 @@ program
41
30
  });
42
31
  program
43
32
  .command('validate [specPath]')
44
- .description('Lint a spec file for unresolved fields, NHFI flags, and missing sections')
45
- .option('--strict-architecture', 'Treat advisory architecture warnings as errors (exits 1)')
46
- .action(async (specPath, options) => {
33
+ .description('Lint a spec file for unresolved fields and missing required sections')
34
+ .action(async (specPath) => {
47
35
  const resolved = await (0, resolve_spec_1.resolveSpecPath)(specPath);
48
- (0, validate_1.runValidate)(resolved, { strictArchitecture: !!options.strictArchitecture });
36
+ (0, validate_1.runValidate)(resolved);
49
37
  });
50
38
  program
51
39
  .command('review [specPath]')
52
- .description('Generate a FORGE reviewer/validator prompt from an approved spec')
53
- .option('--out <file>', 'Write reviewer prompt to file instead of stdout')
54
- .action(async (specPath, options) => {
55
- const resolved = await (0, resolve_spec_1.resolveSpecPath)(specPath);
56
- (0, review_1.runReview)(resolved, { out: options.out });
57
- });
58
- program
59
- .command('spec-review [specPath]')
60
- .description('Generate a FORGE Prompt 1.5 (Spec-Quality Reviewer) for a draft spec')
40
+ .description('Generate a reviewer prompt from a spec (use --target to choose spec or implementation review)')
41
+ .option('--target <target>', 'What to review: "spec" (default) or "implementation"', 'spec')
61
42
  .option('--out <file>', 'Write reviewer prompt to file instead of stdout')
62
43
  .action(async (specPath, options) => {
63
44
  const resolved = await (0, resolve_spec_1.resolveSpecPath)(specPath);
64
- (0, spec_review_1.runSpecReview)(resolved, { out: options.out });
45
+ (0, review_1.runReview)(resolved, { target: options.target, out: options.out });
65
46
  });
66
47
  program
67
48
  .command('new <outputPath>')
68
- .description('Scaffold a new FORGE spec file from the canonical template')
49
+ .description('Scaffold a new Nimai spec file from the tier template')
69
50
  .option('--force', 'Overwrite if file already exists')
51
+ .option('--tier <tier>', 'Template tier: "lite" (default) or "full"', 'lite')
70
52
  .action((outputPath, options) => {
71
- (0, new_1.runNew)(outputPath, { force: !!options.force });
53
+ (0, new_1.runNew)(outputPath, { force: !!options.force, tier: options.tier });
72
54
  });
73
55
  program.parse(process.argv);
74
56
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,0CAA0C;AAC1C,kDAAkD;AAClD,8CAA8C;AAC9C,wCAAwC;AACxC,0DAA0D;AAE1D,iEAAiE;AACjE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtE,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,+JAA+J,CAAC;KAC5K,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAErC,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,eAAe,EAAE,6BAA6B,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KACrE,MAAM,CAAC,cAAc,EAAE,wCAAwC,CAAC;KAChE,MAAM,CAAC,CAAC,OAAe,EAAE,OAGzB,EAAE,EAAE;IACH,IAAA,cAAO,EAAC,OAAO,EAAE;QACf,QAAQ,EAAE,OAAO,CAAC,IAAI;QACtB,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,KAAK,EAAE,QAA4B,EAAE,EAAE;IAC7C,MAAM,QAAQ,GAAG,MAAM,IAAA,8BAAe,EAAC,QAAQ,CAAC,CAAC;IACjD,IAAA,sBAAW,EAAC,QAAQ,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,+FAA+F,CAAC;KAC5G,MAAM,CAAC,mBAAmB,EAAE,sDAAsD,EAAE,MAAM,CAAC;KAC3F,MAAM,CAAC,cAAc,EAAE,iDAAiD,CAAC;KACzE,MAAM,CAAC,KAAK,EAAE,QAA4B,EAAE,OAAyC,EAAE,EAAE;IACxF,MAAM,QAAQ,GAAG,MAAM,IAAA,8BAAe,EAAC,QAAQ,CAAC,CAAC;IACjD,IAAA,kBAAS,EAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAmC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AACjG,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,kBAAkB,CAAC;KAC3B,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,SAAS,EAAE,kCAAkC,CAAC;KACrD,MAAM,CAAC,eAAe,EAAE,2CAA2C,EAAE,MAAM,CAAC;KAC5E,MAAM,CAAC,CAAC,UAAkB,EAAE,OAA0C,EAAE,EAAE;IACzE,IAAA,YAAM,EAAC,UAAU,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAuB,EAAE,CAAC,CAAC;AACxF,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nimai-cli",
3
- "version": "0.4.9",
4
- "description": "Nimai CLI — spec ops for AI work. nimai spec, review, validate, and new.",
3
+ "version": "0.5.0",
4
+ "description": "Nimai CLI — turn a new idea in mind into a graded, build-ready spec. nimai spec, validate, review, new.",
5
5
  "keywords": [
6
6
  "nimai",
7
7
  "forge",
@@ -10,10 +10,7 @@
10
10
  "ai",
11
11
  "llm",
12
12
  "specification",
13
- "mcp",
14
- "anthropic",
15
- "openai",
16
- "ollama"
13
+ "mcp"
17
14
  ],
18
15
  "license": "MIT",
19
16
  "repository": {
@@ -36,11 +33,10 @@
36
33
  "vitest": "^1.6.0"
37
34
  },
38
35
  "dependencies": {
39
- "@anthropic-ai/sdk": "^0.78.0",
40
36
  "commander": "^12.1.0",
41
37
  "js-yaml": "^4.1.1",
42
38
  "zod": "^3.25.76",
43
- "nimai-core": "0.4.9"
39
+ "nimai-core": "0.5.0"
44
40
  },
45
41
  "scripts": {
46
42
  "build": "tsc",
@@ -1,9 +0,0 @@
1
- import type { ModelAdapter } from './types';
2
- export declare const DEFAULT_MODEL = "claude-sonnet-4-6";
3
- export declare class AnthropicAdapter implements ModelAdapter {
4
- private client;
5
- private model;
6
- constructor(apiKey: string, model?: string);
7
- generate(prompt: string): Promise<string>;
8
- }
9
- //# sourceMappingURL=anthropic.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAEjD,qBAAa,gBAAiB,YAAW,YAAY;IACnD,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAsB;IAKnD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA2BhD"}
@@ -1,43 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.AnthropicAdapter = exports.DEFAULT_MODEL = void 0;
7
- const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
8
- const errors_1 = require("./errors");
9
- exports.DEFAULT_MODEL = 'claude-sonnet-4-6';
10
- class AnthropicAdapter {
11
- client;
12
- model;
13
- constructor(apiKey, model = exports.DEFAULT_MODEL) {
14
- this.client = new sdk_1.default({ apiKey });
15
- this.model = model;
16
- }
17
- async generate(prompt) {
18
- try {
19
- const message = await this.client.messages.create({
20
- model: this.model,
21
- max_tokens: 4096,
22
- messages: [{ role: 'user', content: prompt }],
23
- });
24
- const block = message.content[0];
25
- if (block.type !== 'text') {
26
- throw new errors_1.AdapterError('Unexpected response type from Anthropic API');
27
- }
28
- return block.text;
29
- }
30
- catch (err) {
31
- if (err instanceof errors_1.AdapterError)
32
- throw err;
33
- const message = err instanceof Error ? err.message : String(err);
34
- // Surface auth errors clearly
35
- if (message.includes('401') || message.includes('authentication')) {
36
- throw new errors_1.AdapterError('Anthropic API authentication failed. Check your ANTHROPIC_API_KEY.', err);
37
- }
38
- throw new errors_1.AdapterError(`Anthropic API error: ${message}`, err);
39
- }
40
- }
41
- }
42
- exports.AnthropicAdapter = AnthropicAdapter;
43
- //# sourceMappingURL=anthropic.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/adapters/anthropic.ts"],"names":[],"mappings":";;;;;;AAAA,4DAA0C;AAE1C,qCAAwC;AAE3B,QAAA,aAAa,GAAG,mBAAmB,CAAC;AAEjD,MAAa,gBAAgB;IACnB,MAAM,CAAY;IAClB,KAAK,CAAS;IAEtB,YAAY,MAAc,EAAE,QAAgB,qBAAa;QACvD,IAAI,CAAC,MAAM,GAAG,IAAI,aAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAChD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI;gBAChB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,MAAM,IAAI,qBAAY,CAAC,6CAA6C,CAAC,CAAC;YACxE,CAAC;YACD,OAAO,KAAK,CAAC,IAAI,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,qBAAY;gBAAE,MAAM,GAAG,CAAC;YAE3C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,8BAA8B;YAC9B,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAClE,MAAM,IAAI,qBAAY,CACpB,oEAAoE,EACpE,GAAG,CACJ,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,qBAAY,CAAC,wBAAwB,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;CACF;AApCD,4CAoCC"}
@@ -1,5 +0,0 @@
1
- export declare class AdapterError extends Error {
2
- readonly cause?: unknown | undefined;
3
- constructor(message: string, cause?: unknown | undefined);
4
- }
5
- //# sourceMappingURL=errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/adapters/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,YAAa,SAAQ,KAAK;aAGnB,KAAK,CAAC,EAAE,OAAO;gBAD/B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC"}
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AdapterError = void 0;
4
- class AdapterError extends Error {
5
- cause;
6
- constructor(message, cause) {
7
- super(message);
8
- this.cause = cause;
9
- this.name = 'AdapterError';
10
- }
11
- }
12
- exports.AdapterError = AdapterError;
13
- //# sourceMappingURL=errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/adapters/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,YAAa,SAAQ,KAAK;IAGnB;IAFlB,YACE,OAAe,EACC,KAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,UAAK,GAAL,KAAK,CAAU;QAG/B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AARD,oCAQC"}
@@ -1,8 +0,0 @@
1
- import type { ModelAdapter } from './types';
2
- export declare class OllamaAdapter implements ModelAdapter {
3
- private baseUrl;
4
- private model;
5
- constructor(baseUrl?: string, model?: string);
6
- generate(prompt: string): Promise<string>;
7
- }
8
- //# sourceMappingURL=ollama.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/adapters/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,qBAAa,aAAc,YAAW,YAAY;IAE9C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK;gBADL,OAAO,GAAE,MAAiC,EAC1C,KAAK,GAAE,MAAiB;IAG5B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAwBhD"}
@@ -1,34 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OllamaAdapter = void 0;
4
- const errors_1 = require("./errors");
5
- class OllamaAdapter {
6
- baseUrl;
7
- model;
8
- constructor(baseUrl = 'http://localhost:11434', model = 'llama3') {
9
- this.baseUrl = baseUrl;
10
- this.model = model;
11
- }
12
- async generate(prompt) {
13
- let res;
14
- try {
15
- res = await fetch(`${this.baseUrl}/api/generate`, {
16
- method: 'POST',
17
- headers: { 'Content-Type': 'application/json' },
18
- body: JSON.stringify({ model: this.model, prompt, stream: false }),
19
- });
20
- }
21
- catch (err) {
22
- throw new errors_1.AdapterError(`Ollama connection failed at ${this.baseUrl}. Is Ollama running? (${err.message})`, err);
23
- }
24
- if (!res.ok) {
25
- throw new errors_1.AdapterError(`Ollama API error: ${res.status} ${res.statusText}`);
26
- }
27
- const data = await res.json();
28
- if (!data?.response)
29
- throw new errors_1.AdapterError('Unexpected response shape from Ollama API');
30
- return data.response;
31
- }
32
- }
33
- exports.OllamaAdapter = OllamaAdapter;
34
- //# sourceMappingURL=ollama.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/adapters/ollama.ts"],"names":[],"mappings":";;;AACA,qCAAwC;AAExC,MAAa,aAAa;IAEd;IACA;IAFV,YACU,UAAkB,wBAAwB,EAC1C,QAAgB,QAAQ;QADxB,YAAO,GAAP,OAAO,CAAmC;QAC1C,UAAK,GAAL,KAAK,CAAmB;IAC/B,CAAC;IAEJ,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC3B,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,eAAe,EAAE;gBAChD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;aACnE,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,qBAAY,CACpB,+BAA+B,IAAI,CAAC,OAAO,yBAA0B,GAAa,CAAC,OAAO,GAAG,EAC7F,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,qBAAY,CAAC,qBAAqB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9E,CAAC;QAGD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAoB,CAAC;QAChD,IAAI,CAAC,IAAI,EAAE,QAAQ;YAAE,MAAM,IAAI,qBAAY,CAAC,2CAA2C,CAAC,CAAC;QACzF,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AA9BD,sCA8BC"}
@@ -1,9 +0,0 @@
1
- import type { ModelAdapter } from './types';
2
- export declare class OpenAIAdapter implements ModelAdapter {
3
- private apiKey;
4
- private model;
5
- private baseUrl;
6
- constructor(apiKey: string, model?: string, baseUrl?: string);
7
- generate(prompt: string): Promise<string>;
8
- }
9
- //# sourceMappingURL=openai.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG5C,qBAAa,aAAc,YAAW,YAAY;IAE9C,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;gBAFP,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAiB,EACxB,OAAO,GAAE,MAAoC;IAGjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA+BhD"}
@@ -1,46 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OpenAIAdapter = void 0;
4
- const errors_1 = require("./errors");
5
- class OpenAIAdapter {
6
- apiKey;
7
- model;
8
- baseUrl;
9
- constructor(apiKey, model = 'gpt-4o', baseUrl = 'https://api.openai.com/v1') {
10
- this.apiKey = apiKey;
11
- this.model = model;
12
- this.baseUrl = baseUrl;
13
- }
14
- async generate(prompt) {
15
- let res;
16
- try {
17
- res = await fetch(`${this.baseUrl}/chat/completions`, {
18
- method: 'POST',
19
- headers: {
20
- 'Content-Type': 'application/json',
21
- Authorization: `Bearer ${this.apiKey}`,
22
- },
23
- body: JSON.stringify({
24
- model: this.model,
25
- messages: [{ role: 'user', content: prompt }],
26
- }),
27
- });
28
- }
29
- catch (err) {
30
- throw new errors_1.AdapterError(`OpenAI API network error: ${err.message}`, err);
31
- }
32
- if (!res.ok) {
33
- if (res.status === 401) {
34
- throw new errors_1.AdapterError('OpenAI API authentication failed. Check your OPENAI_API_KEY.');
35
- }
36
- throw new errors_1.AdapterError(`OpenAI API error: ${res.status} ${res.statusText}`);
37
- }
38
- const data = await res.json();
39
- const content = data?.choices?.[0]?.message?.content;
40
- if (!content)
41
- throw new errors_1.AdapterError('Unexpected response shape from OpenAI API');
42
- return content;
43
- }
44
- }
45
- exports.OpenAIAdapter = OpenAIAdapter;
46
- //# sourceMappingURL=openai.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":";;;AACA,qCAAwC;AAExC,MAAa,aAAa;IAEd;IACA;IACA;IAHV,YACU,MAAc,EACd,QAAgB,QAAQ,EACxB,UAAkB,2BAA2B;QAF7C,WAAM,GAAN,MAAM,CAAQ;QACd,UAAK,GAAL,KAAK,CAAmB;QACxB,YAAO,GAAP,OAAO,CAAsC;IACpD,CAAC;IAEJ,KAAK,CAAC,QAAQ,CAAC,MAAc;QAC3B,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,mBAAmB,EAAE;gBACpD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;iBACvC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;iBAC9C,CAAC;aACH,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,qBAAY,CAAC,6BAA8B,GAAa,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACvB,MAAM,IAAI,qBAAY,CAAC,8DAA8D,CAAC,CAAC;YACzF,CAAC;YACD,MAAM,IAAI,qBAAY,CAAC,qBAAqB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9E,CAAC;QAGD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAoB,CAAC;QAChD,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;QACrD,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,qBAAY,CAAC,2CAA2C,CAAC,CAAC;QAClF,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAtCD,sCAsCC"}
@@ -1,9 +0,0 @@
1
- /**
2
- * ModelAdapter interface — Milestone 2 stub.
3
- * Implement this to add --standalone mode with a specific LLM provider.
4
- */
5
- export interface ModelAdapter {
6
- /** Send a prompt and return the model's text response */
7
- generate(prompt: string): Promise<string>;
8
- }
9
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3C"}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":""}
@@ -1,5 +0,0 @@
1
- export interface SpecReviewOptions {
2
- out?: string;
3
- }
4
- export declare function runSpecReview(specPath: string, options: SpecReviewOptions): void;
5
- //# sourceMappingURL=spec-review.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec-review.d.ts","sourceRoot":"","sources":["../../src/commands/spec-review.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CA4ChF"}
@@ -1,85 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.runSpecReview = runSpecReview;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- const nimai_core_1 = require("nimai-core");
40
- function runSpecReview(specPath, options) {
41
- const resolved = path.resolve(specPath);
42
- let specContent;
43
- try {
44
- specContent = fs.readFileSync(resolved, 'utf-8');
45
- }
46
- catch {
47
- console.error(`Error: Cannot read spec at "${resolved}"`);
48
- process.exit(1);
49
- }
50
- const specReviewerPrompt = (0, nimai_core_1.buildPrompt15)(specContent);
51
- if (options.out) {
52
- const outPath = path.resolve(options.out);
53
- const dir = path.dirname(outPath);
54
- if (!fs.existsSync(dir))
55
- fs.mkdirSync(dir, { recursive: true });
56
- fs.writeFileSync(outPath, specReviewerPrompt, 'utf-8');
57
- console.log(`Spec reviewer prompt written to ${outPath}`);
58
- console.log('');
59
- console.log('⚠ INDEPENDENT REVIEW REQUIRED');
60
- console.log('Paste the contents of that file into a fresh session with a different model.');
61
- console.log('The reviewer must not be the same agent that created this spec.');
62
- }
63
- else {
64
- console.log('=== NIMAI SPEC REVIEW PROMPT ===');
65
- console.log('');
66
- console.log('⚠ INDEPENDENT REVIEW REQUIRED');
67
- console.log('The agent that built this spec must NOT be its own reviewer.');
68
- console.log('');
69
- console.log('Steps:');
70
- console.log('1. Copy the prompt below.');
71
- console.log('2. Open a fresh session with a different model or agent.');
72
- console.log('3. Paste the prompt — the reviewer will evaluate and end with:');
73
- console.log(' {"passed": true/false, "schema_version": "2", "issues": [...]}');
74
- console.log('4. Bring the verdict back to this session.');
75
- console.log('');
76
- console.log('--- PROMPT (copy everything below this line) ---');
77
- console.log('');
78
- console.log(specReviewerPrompt);
79
- console.log('');
80
- console.log('--- END PROMPT ---');
81
- console.log('');
82
- console.log('Tip: use --out <file> to save this prompt to a file instead.');
83
- }
84
- }
85
- //# sourceMappingURL=spec-review.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"spec-review.js","sourceRoot":"","sources":["../../src/commands/spec-review.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,sCA4CC;AApDD,uCAAyB;AACzB,2CAA6B;AAC7B,2CAA2C;AAM3C,SAAgB,aAAa,CAAC,QAAgB,EAAE,OAA0B;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAExC,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,+BAA+B,QAAQ,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,kBAAkB,GAAG,IAAA,0BAAa,EAAC,WAAW,CAAC,CAAC;IAEtD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,mCAAmC,OAAO,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;IACjF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC"}