@ai-coders/context 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +7 -2
  2. package/dist/commands/shared/agents.d.ts +2 -0
  3. package/dist/commands/shared/agents.d.ts.map +1 -0
  4. package/dist/commands/shared/agents.js +15 -0
  5. package/dist/commands/shared/agents.js.map +1 -0
  6. package/dist/commands/shared/selection.d.ts +12 -0
  7. package/dist/commands/shared/selection.d.ts.map +1 -0
  8. package/dist/commands/shared/selection.js +95 -0
  9. package/dist/commands/shared/selection.js.map +1 -0
  10. package/dist/generators/plans/templates/planTemplate.d.ts.map +1 -1
  11. package/dist/generators/plans/templates/planTemplate.js +22 -10
  12. package/dist/generators/plans/templates/planTemplate.js.map +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +98 -40
  15. package/dist/index.js.map +1 -1
  16. package/dist/prompts/defaults.d.ts +3 -0
  17. package/dist/prompts/defaults.d.ts.map +1 -0
  18. package/dist/prompts/defaults.js +95 -0
  19. package/dist/prompts/defaults.js.map +1 -0
  20. package/dist/services/fill/fillService.d.ts +50 -0
  21. package/dist/services/fill/fillService.d.ts.map +1 -0
  22. package/dist/services/fill/fillService.js +302 -0
  23. package/dist/services/fill/fillService.js.map +1 -0
  24. package/dist/services/init/initService.d.ts +37 -0
  25. package/dist/services/init/initService.d.ts.map +1 -0
  26. package/dist/services/init/initService.js +137 -0
  27. package/dist/services/init/initService.js.map +1 -0
  28. package/dist/services/plan/planService.d.ts +59 -0
  29. package/dist/services/plan/planService.d.ts.map +1 -0
  30. package/dist/services/plan/planService.js +343 -0
  31. package/dist/services/plan/planService.js.map +1 -0
  32. package/dist/services/shared/llmConfig.d.ts +22 -0
  33. package/dist/services/shared/llmConfig.d.ts.map +1 -0
  34. package/dist/services/shared/llmConfig.js +80 -0
  35. package/dist/services/shared/llmConfig.js.map +1 -0
  36. package/dist/utils/i18n.d.ts +12 -1
  37. package/dist/utils/i18n.d.ts.map +1 -1
  38. package/dist/utils/i18n.js +26 -4
  39. package/dist/utils/i18n.js.map +1 -1
  40. package/dist/utils/promptLoader.d.ts +12 -0
  41. package/dist/utils/promptLoader.d.ts.map +1 -0
  42. package/dist/utils/promptLoader.js +81 -0
  43. package/dist/utils/promptLoader.js.map +1 -0
  44. package/dist/utils/versionChecker.d.ts +15 -0
  45. package/dist/utils/versionChecker.d.ts.map +1 -0
  46. package/dist/utils/versionChecker.js +49 -0
  47. package/dist/utils/versionChecker.js.map +1 -0
  48. package/package.json +4 -2
package/README.md CHANGED
@@ -4,6 +4,9 @@
4
4
  [![CI](https://github.com/vinilana/ai-coders-context/actions/workflows/ci.yml/badge.svg)](https://github.com/vinilana/ai-coders-context/actions/workflows/ci.yml)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
+ <img width="663" height="192" alt="image" src="https://github.com/user-attachments/assets/4b07f61d-6800-420a-ae91-6e952cbc790d" />
8
+
9
+
7
10
  A lightweight CLI that scaffolds living documentation and AI-agent playbooks for any repository—no LLMs or API keys required. The generated structure gives teams a consistent starting point for knowledge sharing while keeping everything under version control.
8
11
 
9
12
  ## ⚙️ Requirements
@@ -54,6 +57,8 @@ npx @ai-coders/context plan release-readiness --output ./.context
54
57
  npx @ai-coders/context plan release-readiness --output ./.context --fill --dry-run
55
58
  ```
56
59
 
60
+ > ℹ️ The CLI pings npm for fresh releases at startup. Set `AI_CONTEXT_DISABLE_UPDATE_CHECK=true` to skip the check.
61
+
57
62
  After running the command, inspect the generated structure:
58
63
 
59
64
  ```
@@ -123,7 +128,7 @@ Options:
123
128
  -k, --api-key <key> API key for the selected LLM provider
124
129
  -m, --model <model> LLM model to use (default: google/gemini-2.5-flash-preview-05-20)
125
130
  -p, --provider <name> Provider (openrouter, openai, anthropic, gemini, grok)
126
- --prompt <file> Instruction prompt to follow (default: prompts/update_scaffold_prompt.md)
131
+ --prompt <file> Instruction prompt to follow (optional; uses bundled instructions when omitted)
127
132
  --docs <keys...> Doc keys to update (default: all)
128
133
  --agents <keys...> Agent types to update (default: all)
129
134
  --dry-run Preview changes without writing files
@@ -153,7 +158,7 @@ Options:
153
158
  -m, --model <model> LLM model to use (default: x-ai/grok-4-fast:free)
154
159
  -p, --provider <name> Provider (openrouter, openai, anthropic, gemini, grok)
155
160
  --base-url <url> Custom base URL for provider APIs
156
- --prompt <file> Instruction prompt to follow (default: prompts/update_plan_prompt.md)
161
+ --prompt <file> Instruction prompt to follow (optional; uses bundled instructions when omitted)
157
162
  --dry-run Preview changes without writing files
158
163
  --include <patterns...> Glob patterns to include during repository analysis
159
164
  --exclude <patterns...> Glob patterns to exclude from repository analysis
@@ -0,0 +1,2 @@
1
+ export declare function getAgentFilesByTypes(types?: string[]): Set<string> | undefined;
2
+ //# sourceMappingURL=agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/agents.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAW9E"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAgentFilesByTypes = getAgentFilesByTypes;
4
+ const agentTypes_1 = require("../../generators/agents/agentTypes");
5
+ function getAgentFilesByTypes(types) {
6
+ if (!types || types.length === 0) {
7
+ return undefined;
8
+ }
9
+ const allowed = new Set(agentTypes_1.AGENT_TYPES);
10
+ const files = types
11
+ .filter(type => allowed.has(type))
12
+ .map(type => `${type}.md`);
13
+ return files.length ? new Set(files) : undefined;
14
+ }
15
+ //# sourceMappingURL=agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../../src/commands/shared/agents.ts"],"names":[],"mappings":";;AAEA,oDAWC;AAbD,mEAAiE;AAEjE,SAAgB,oBAAoB,CAAC,KAAgB;IACnD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,wBAAW,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK;SAChB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAkC,CAAC,CAAC;SAC/D,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,KAAK,CAAC,CAAC;IAE7B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACnD,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface SelectionParseResult {
2
+ selected?: string[];
3
+ invalid: string[];
4
+ provided: boolean;
5
+ explicitNone: boolean;
6
+ }
7
+ export declare function parseDocSelection(input: unknown): SelectionParseResult;
8
+ export declare function parseAgentSelection(input: unknown): SelectionParseResult;
9
+ export declare function shouldGenerateDocs(resolvedType: 'docs' | 'agents' | 'both', selection: SelectionParseResult): boolean;
10
+ export declare function shouldGenerateAgents(resolvedType: 'docs' | 'agents' | 'both', selection: SelectionParseResult): boolean;
11
+ export declare function determineScaffoldType(docSelection?: string[], agentSelection?: string[]): 'docs' | 'agents' | 'both';
12
+ //# sourceMappingURL=selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/selection.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAmBtE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAoBxE;AAED,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,EAAE,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAkBrH;AAED,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,EAAE,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAkBvH;AAED,wBAAgB,qBAAqB,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAOpH"}
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseDocSelection = parseDocSelection;
4
+ exports.parseAgentSelection = parseAgentSelection;
5
+ exports.shouldGenerateDocs = shouldGenerateDocs;
6
+ exports.shouldGenerateAgents = shouldGenerateAgents;
7
+ exports.determineScaffoldType = determineScaffoldType;
8
+ const guideRegistry_1 = require("../../generators/documentation/guideRegistry");
9
+ const agentTypes_1 = require("../../generators/agents/agentTypes");
10
+ function parseDocSelection(input) {
11
+ if (input === undefined) {
12
+ return { selected: undefined, invalid: [], provided: false, explicitNone: false };
13
+ }
14
+ if (Array.isArray(input) && input.length === 0) {
15
+ return { selected: [], invalid: [], provided: true, explicitNone: true };
16
+ }
17
+ const values = toStringArray(input);
18
+ const normalized = values.map(value => value.toLowerCase().replace(/\.md$/, ''));
19
+ const valid = Array.from(new Set(normalized.filter(key => guideRegistry_1.DOCUMENT_GUIDE_KEYS.includes(key))));
20
+ const invalid = normalized.filter(key => !guideRegistry_1.DOCUMENT_GUIDE_KEYS.includes(key));
21
+ if (values.length > 0 && valid.length === 0 && invalid.length > 0) {
22
+ return { selected: undefined, invalid, provided: true, explicitNone: false };
23
+ }
24
+ return { selected: valid.length > 0 ? valid : undefined, invalid, provided: true, explicitNone: false };
25
+ }
26
+ function parseAgentSelection(input) {
27
+ if (input === undefined) {
28
+ return { selected: undefined, invalid: [], provided: false, explicitNone: false };
29
+ }
30
+ if (Array.isArray(input) && input.length === 0) {
31
+ return { selected: [], invalid: [], provided: true, explicitNone: true };
32
+ }
33
+ const values = toStringArray(input);
34
+ const normalized = values.map(value => value.toLowerCase().replace(/\.md$/, ''));
35
+ const allowed = new Set(agentTypes_1.AGENT_TYPES);
36
+ const valid = Array.from(new Set(normalized.filter(value => allowed.has(value))));
37
+ const invalid = normalized.filter(value => !allowed.has(value));
38
+ if (values.length > 0 && valid.length === 0 && invalid.length > 0) {
39
+ return { selected: undefined, invalid, provided: true, explicitNone: false };
40
+ }
41
+ return { selected: valid.length > 0 ? valid : undefined, invalid, provided: true, explicitNone: false };
42
+ }
43
+ function shouldGenerateDocs(resolvedType, selection) {
44
+ if (selection.explicitNone) {
45
+ return false;
46
+ }
47
+ if (resolvedType === 'agents') {
48
+ return false;
49
+ }
50
+ if (!selection.provided) {
51
+ return resolvedType === 'docs' || resolvedType === 'both';
52
+ }
53
+ if (selection.selected && selection.selected.length === 0) {
54
+ return false;
55
+ }
56
+ return resolvedType === 'docs' || resolvedType === 'both';
57
+ }
58
+ function shouldGenerateAgents(resolvedType, selection) {
59
+ if (selection.explicitNone) {
60
+ return false;
61
+ }
62
+ if (resolvedType === 'docs') {
63
+ return false;
64
+ }
65
+ if (!selection.provided) {
66
+ return resolvedType === 'agents' || resolvedType === 'both';
67
+ }
68
+ if (selection.selected && selection.selected.length === 0) {
69
+ return false;
70
+ }
71
+ return resolvedType === 'agents' || resolvedType === 'both';
72
+ }
73
+ function determineScaffoldType(docSelection, agentSelection) {
74
+ const docsSelected = docSelection === undefined ? true : docSelection.length > 0;
75
+ const agentsSelected = agentSelection === undefined ? true : agentSelection.length > 0;
76
+ if (docsSelected && agentsSelected)
77
+ return 'both';
78
+ if (docsSelected)
79
+ return 'docs';
80
+ return 'agents';
81
+ }
82
+ function toStringArray(input) {
83
+ if (Array.isArray(input)) {
84
+ return input.map(item => item.toString().trim()).filter(Boolean);
85
+ }
86
+ if (input === null || input === undefined) {
87
+ return [];
88
+ }
89
+ return input
90
+ .toString()
91
+ .split(',')
92
+ .map(part => part.trim())
93
+ .filter(Boolean);
94
+ }
95
+ //# sourceMappingURL=selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/commands/shared/selection.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"planTemplate.d.ts","sourceRoot":"","sources":["../../../../src/generators/plans/templates/planTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAkFvE"}
1
+ {"version":3,"file":"planTemplate.d.ts","sourceRoot":"","sources":["../../../../src/generators/plans/templates/planTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CA8FvE"}
@@ -54,18 +54,30 @@ ${agentTableRows}
54
54
  | --- | --- | --- | --- |
55
55
  ${docsTableRows}
56
56
 
57
- ## Working Stages
58
- ### Stage 1 — Discovery & Alignment
59
- - TODO: Outline discovery tasks and the agent/owner who leads them.
60
- - TODO: Capture open questions that require clarification.
57
+ ## Working Phases
58
+ ### Phase 1 — Discovery & Alignment
59
+ **Steps**
60
+ 1. TODO: Outline discovery tasks and assign the accountable owner.
61
+ 2. TODO: Capture open questions that require clarification.
61
62
 
62
- ### Stage 2 — Implementation & Iteration
63
- - TODO: Note build tasks, pairing expectations, and review cadence.
64
- - TODO: Reference docs or playbooks to keep changes aligned.
63
+ **Commit Checkpoint**
64
+ - After completing this phase, capture the agreed context and create a commit (for example, \`git commit -m "chore(plan): complete phase 1 discovery"\`).
65
65
 
66
- ### Stage 3Validation & Handoff
67
- - TODO: Detail testing, verification, and documentation updates.
68
- - TODO: Document evidence the team must capture for maintainers.
66
+ ### Phase 2Implementation & Iteration
67
+ **Steps**
68
+ 1. TODO: Note build tasks, pairing expectations, and review cadence.
69
+ 2. TODO: Reference docs or playbooks to keep changes aligned.
70
+
71
+ **Commit Checkpoint**
72
+ - Summarize progress, update cross-links, and create a commit documenting the outcomes of this phase (for example, \`git commit -m "chore(plan): complete phase 2 implementation"\`).
73
+
74
+ ### Phase 3 — Validation & Handoff
75
+ **Steps**
76
+ 1. TODO: Detail testing, verification, and documentation updates.
77
+ 2. TODO: Document evidence the team must capture for maintainers.
78
+
79
+ **Commit Checkpoint**
80
+ - Record the validation evidence and create a commit signalling the handoff completion (for example, \`git commit -m "chore(plan): complete phase 3 validation"\`).
69
81
 
70
82
  ## Agent Playbook Checklist
71
83
  1. Pick the agent that matches your task.
@@ -1 +1 @@
1
- {"version":3,"file":"planTemplate.js","sourceRoot":"","sources":["../../../../src/generators/plans/templates/planTemplate.ts"],"names":[],"mappings":";;AAEA,gDAkFC;AAlFD,SAAgB,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEvD,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM;QACjC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACvD,CAAC,CAAC,4BAA4B,CAAC;IAEjC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM;QAClC,CAAC,CAAC,MAAM;aACH,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,oDAAoD,KAAK,CAAC,KAAK,eAAe,KAAK,CAAC,IAAI,UAAU,KAAK,CAAC,cAAc,IAAI,CAAC;aACxJ,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,+KAA+K,CAAC;IAEpL,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM;QAC/B,CAAC,CAAC,IAAI;aACD,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,IAAI,aAAa,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,aAAa,IAAI,CAAC;aAC1G,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,gHAAgH,CAAC;IAErH,OAAO;WACE,IAAI;gFACiE,KAAK;;;;;;;;;;EAUnF,aAAa;;;oBAGK,IAAI;IACpB,KAAK;;IAEL,OAAO,EAAE,IAAI,EAAE,IAAI,0EAA0E;;;;;;;;;;;;;EAa/F,cAAc;;;;;EAKd,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;qBAyBM,IAAI;CACxB,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"planTemplate.js","sourceRoot":"","sources":["../../../../src/generators/plans/templates/planTemplate.ts"],"names":[],"mappings":";;AAEA,gDA8FC;AA9FD,SAAgB,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEvD,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM;QACjC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACvD,CAAC,CAAC,4BAA4B,CAAC;IAEjC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM;QAClC,CAAC,CAAC,MAAM;aACH,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,KAAK,oDAAoD,KAAK,CAAC,KAAK,eAAe,KAAK,CAAC,IAAI,UAAU,KAAK,CAAC,cAAc,IAAI,CAAC;aACxJ,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,+KAA+K,CAAC;IAEpL,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM;QAC/B,CAAC,CAAC,IAAI;aACD,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,KAAK,OAAO,GAAG,CAAC,IAAI,aAAa,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,aAAa,IAAI,CAAC;aAC1G,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,gHAAgH,CAAC;IAErH,OAAO;WACE,IAAI;gFACiE,KAAK;;;;;;;;;;EAUnF,aAAa;;;oBAGK,IAAI;IACpB,KAAK;;IAEL,OAAO,EAAE,IAAI,EAAE,IAAI,0EAA0E;;;;;;;;;;;;;EAa/F,cAAc;;;;;EAKd,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAqCM,IAAI;CACxB,CAAC;AACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAwNA,iBAAe,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFrF;AA6BD,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAa/E;AAED,wBAAsB,UAAU,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wBAAsB,SAAS,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE;AAED,wBAAsB,UAAU,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wBAAsB,aAAa,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA+OA,iBAAe,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFrF;AA6BD,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAa/E;AAED,wBAAsB,UAAU,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wBAAsB,SAAS,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE;AAED,wBAAsB,UAAU,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;AAED,wBAAsB,aAAa,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -56,6 +56,8 @@ const agentGenerator_1 = require("./generators/agents/agentGenerator");
56
56
  const planGenerator_1 = require("./generators/plans/planGenerator");
57
57
  const shared_1 = require("./generators/shared");
58
58
  const cliUI_1 = require("./utils/cliUI");
59
+ const promptLoader_1 = require("./utils/promptLoader");
60
+ const versionChecker_1 = require("./utils/versionChecker");
59
61
  const i18n_1 = require("./utils/i18n");
60
62
  const llmClientFactory_1 = require("./services/llmClientFactory");
61
63
  const guideRegistry_1 = require("./generators/documentation/guideRegistry");
@@ -71,7 +73,8 @@ const localeLabelKeys = {
71
73
  };
72
74
  const program = new commander_1.Command();
73
75
  const ui = new cliUI_1.CLIInterface(t);
74
- const VERSION = '0.3.0';
76
+ const VERSION = '0.3.1';
77
+ const PACKAGE_NAME = '@ai-coders/context';
75
78
  const DEFAULT_MODEL = 'x-ai/grok-4-fast:free';
76
79
  const DOC_CHOICES = guideRegistry_1.DOCUMENT_GUIDES.map(guide => ({
77
80
  name: `${guide.title} (${guide.key})`,
@@ -86,6 +89,22 @@ program
86
89
  .description(t('cli.description'))
87
90
  .version(VERSION);
88
91
  program.option('-l, --lang <locale>', t('global.options.lang'), initialLocale);
92
+ let versionCheckPromise = null;
93
+ function scheduleVersionCheck(force = false) {
94
+ if (!versionCheckPromise || force) {
95
+ versionCheckPromise = (0, versionChecker_1.checkForUpdates)({
96
+ packageName: PACKAGE_NAME,
97
+ currentVersion: VERSION,
98
+ ui,
99
+ t,
100
+ force
101
+ }).catch(() => { });
102
+ }
103
+ return versionCheckPromise;
104
+ }
105
+ program.hook('preAction', () => {
106
+ void scheduleVersionCheck();
107
+ });
89
108
  program
90
109
  .command('init')
91
110
  .description(t('commands.init.description'))
@@ -135,7 +154,7 @@ program
135
154
  .option('-m, --model <model>', t('commands.fill.options.model'), DEFAULT_MODEL)
136
155
  .option('-p, --provider <provider>', t('commands.fill.options.provider'))
137
156
  .option('--base-url <url>', t('commands.fill.options.baseUrl'))
138
- .option('--prompt <file>', t('commands.fill.options.prompt'), path.join(__dirname, '../prompts/update_scaffold_prompt.md'))
157
+ .option('--prompt <file>', t('commands.fill.options.prompt'))
139
158
  .option('--dry-run', t('commands.fill.options.dryRun'), false)
140
159
  .option('--all', t('commands.fill.options.all'), false)
141
160
  .option('--limit <number>', t('commands.fill.options.limit'), (value) => parseInt(value, 10))
@@ -169,7 +188,7 @@ program
169
188
  .option('-m, --model <model>', t('commands.plan.options.model'), DEFAULT_MODEL)
170
189
  .option('-p, --provider <provider>', t('commands.plan.options.provider'))
171
190
  .option('--base-url <url>', t('commands.plan.options.baseUrl'))
172
- .option('--prompt <file>', t('commands.plan.options.prompt'), path.join(__dirname, '../prompts/update_plan_prompt.md'))
191
+ .option('--prompt <file>', t('commands.plan.options.prompt'))
173
192
  .option('--dry-run', t('commands.plan.options.dryRun'), false)
174
193
  .option('--include <patterns...>', t('commands.plan.options.include'))
175
194
  .option('--exclude <patterns...>', t('commands.plan.options.exclude'))
@@ -329,10 +348,6 @@ async function runGuidelines(..._args) {
329
348
  throw new Error(t('errors.commands.guidelinesRemoved'));
330
349
  }
331
350
  async function resolveLlmConfig(rawOptions, defaults) {
332
- const promptPath = path.resolve(rawOptions.prompt || defaults.promptPath);
333
- if (!(await fs.pathExists(promptPath))) {
334
- throw new Error(t('errors.fill.promptMissing', { path: promptPath }));
335
- }
336
351
  const providerEnvMap = llmClientFactory_1.LLMClientFactory.getEnvironmentVariables();
337
352
  const defaultModels = llmClientFactory_1.LLMClientFactory.getDefaultModels();
338
353
  let provider = rawOptions.provider;
@@ -404,7 +419,6 @@ async function resolveLlmConfig(rawOptions, defaults) {
404
419
  provider,
405
420
  model: model || defaults.fallbackModel,
406
421
  apiKey,
407
- promptPath,
408
422
  baseUrl: rawOptions.baseUrl
409
423
  };
410
424
  }
@@ -423,10 +437,10 @@ async function runLlmFill(repoPath, rawOptions) {
423
437
  if (agentSelection.invalid.length > 0) {
424
438
  ui.displayWarning(t('warnings.agents.unknown', { values: agentSelection.invalid.join(', ') }));
425
439
  }
426
- const { provider, model, apiKey, promptPath, baseUrl } = await resolveLlmConfig(rawOptions, {
427
- promptPath: path.join(__dirname, '../prompts/update_scaffold_prompt.md'),
440
+ const { provider, model, apiKey, baseUrl } = await resolveLlmConfig(rawOptions, {
428
441
  fallbackModel: DEFAULT_MODEL
429
442
  });
443
+ const scaffoldPrompt = await (0, promptLoader_1.resolveScaffoldPrompt)(rawOptions.prompt, missingPath => t('errors.fill.promptMissing', { path: missingPath }));
430
444
  const docAllowlist = docSelection.explicitNone
431
445
  ? new Set()
432
446
  : (0, guideRegistry_1.getDocFilesByKeys)(docSelection.selected);
@@ -436,7 +450,6 @@ async function runLlmFill(repoPath, rawOptions) {
436
450
  const options = {
437
451
  repoPath: resolvedRepo,
438
452
  outputDir,
439
- promptPath,
440
453
  provider,
441
454
  model,
442
455
  apiKey,
@@ -452,6 +465,18 @@ async function runLlmFill(repoPath, rawOptions) {
452
465
  selectedDocFiles: docAllowlist,
453
466
  selectedAgentFiles: agentAllowlist
454
467
  };
468
+ const scaffoldPromptDisplayPath = scaffoldPrompt.path
469
+ ? path.relative(process.cwd(), scaffoldPrompt.path) || scaffoldPrompt.path
470
+ : undefined;
471
+ if (scaffoldPrompt.source === 'custom' && scaffoldPromptDisplayPath) {
472
+ ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingCustom', { path: scaffoldPromptDisplayPath }));
473
+ }
474
+ else if (scaffoldPrompt.source === 'package' && scaffoldPromptDisplayPath) {
475
+ ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingPackage', { path: scaffoldPromptDisplayPath }));
476
+ }
477
+ else {
478
+ ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingBundled'));
479
+ }
455
480
  ui.displayWelcome(VERSION);
456
481
  ui.displayProjectInfo(options.repoPath, options.outputDir, `fill:${options.provider}`);
457
482
  const fileMapper = new fileMapper_1.FileMapper(options.exclude);
@@ -462,7 +487,7 @@ async function runLlmFill(repoPath, rawOptions) {
462
487
  fileCount: repoStructure.totalFiles,
463
488
  directoryCount: repoStructure.directories.length
464
489
  }), 'success');
465
- const systemPrompt = await fs.readFile(options.promptPath, 'utf-8');
490
+ const systemPrompt = scaffoldPrompt.content;
466
491
  const llmClient = llmClientFactory_1.LLMClientFactory.createClient({
467
492
  apiKey: options.apiKey,
468
493
  model: options.model,
@@ -585,10 +610,10 @@ async function runPlanFill(planName, rawOptions) {
585
610
  if (!(await fs.pathExists(repoPath))) {
586
611
  throw new Error(t('errors.common.repoMissing', { path: repoPath }));
587
612
  }
588
- const { provider, model, apiKey, promptPath, baseUrl } = await resolveLlmConfig(rawOptions, {
589
- promptPath: path.join(__dirname, '../prompts/update_plan_prompt.md'),
613
+ const { provider, model, apiKey, baseUrl } = await resolveLlmConfig(rawOptions, {
590
614
  fallbackModel: DEFAULT_MODEL
591
615
  });
616
+ const planPrompt = await (0, promptLoader_1.resolvePlanPrompt)(rawOptions.prompt, missingPath => t('errors.fill.promptMissing', { path: missingPath }));
592
617
  const planContent = await fs.readFile(planPath, 'utf-8');
593
618
  const docsIndexPath = path.join(docsDir, 'README.md');
594
619
  const agentsIndexPath = path.join(agentsDir, 'README.md');
@@ -596,6 +621,18 @@ async function runPlanFill(planName, rawOptions) {
596
621
  const agentsIndex = (await fs.pathExists(agentsIndexPath)) ? await fs.readFile(agentsIndexPath, 'utf-8') : undefined;
597
622
  const referencedDocs = await loadReferencedMarkdown(docsDir, extractPlanReferences(planContent, 'docs'));
598
623
  const referencedAgents = await loadReferencedMarkdown(agentsDir, extractPlanReferences(planContent, 'agents'));
624
+ const planPromptDisplayPath = planPrompt.path
625
+ ? path.relative(process.cwd(), planPrompt.path) || planPrompt.path
626
+ : undefined;
627
+ if (planPrompt.source === 'custom' && planPromptDisplayPath) {
628
+ ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingCustom', { path: planPromptDisplayPath }));
629
+ }
630
+ else if (planPrompt.source === 'package' && planPromptDisplayPath) {
631
+ ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingPackage', { path: planPromptDisplayPath }));
632
+ }
633
+ else {
634
+ ui.displayInfo(t('info.prompt.title'), t('info.prompt.usingBundled'));
635
+ }
599
636
  ui.displayWelcome(VERSION);
600
637
  ui.displayProjectInfo(repoPath, outputDir, `plan-fill:${provider}`);
601
638
  const fileMapper = new fileMapper_1.FileMapper(rawOptions.exclude);
@@ -604,7 +641,7 @@ async function runPlanFill(planName, rawOptions) {
604
641
  const repoStructure = await fileMapper.mapRepository(repoPath, rawOptions.include);
605
642
  const contextSummary = buildContextSummary(repoStructure);
606
643
  ui.updateSpinner(t('spinner.planFill.summaryReady'), 'success');
607
- const systemPrompt = await fs.readFile(promptPath, 'utf-8');
644
+ const systemPrompt = planPrompt.content;
608
645
  const llmClient = llmClientFactory_1.LLMClientFactory.createClient({
609
646
  apiKey,
610
647
  model,
@@ -746,7 +783,7 @@ function buildPlanUserPrompt(context) {
746
783
  '- Preserve the YAML front matter and `ai-task` wrapper already in the plan.',
747
784
  '- Replace TODOs with concrete steps that align with the provided documentation and agent playbooks.',
748
785
  '- Keep the Agent Lineup and Documentation Touchpoints tables accurate and sorted.',
749
- '- Ensure stages include owners, deliverables, and evidence expectations.',
786
+ '- Ensure the work is segmented into phases, each with numbered steps, named owners, deliverables, evidence expectations, and a concluding Git commit checkpoint.',
750
787
  '- Return only the full updated Markdown for this plan.'
751
788
  ];
752
789
  const sections = [
@@ -926,7 +963,7 @@ function formatAgentLabel(value) {
926
963
  .map(segment => segment.charAt(0).toUpperCase() + segment.slice(1))
927
964
  .join(' ');
928
965
  }
929
- async function runInteractive() {
966
+ async function selectLocale(showWelcome) {
930
967
  const { locale } = await inquirer_1.default.prompt([
931
968
  {
932
969
  type: 'list',
@@ -942,28 +979,48 @@ async function runInteractive() {
942
979
  const normalizedLocale = (0, i18n_1.normalizeLocale)(locale);
943
980
  currentLocale = normalizedLocale;
944
981
  translateFn = (0, i18n_1.createTranslator)(normalizedLocale);
945
- ui.displayWelcome(VERSION);
946
- const { action } = await inquirer_1.default.prompt([
947
- {
948
- type: 'list',
949
- name: 'action',
950
- message: t('prompts.main.action'),
951
- choices: [
952
- { name: t('prompts.main.choice.scaffold'), value: 'scaffold' },
953
- { name: t('prompts.main.choice.fill'), value: 'fill' },
954
- { name: t('prompts.main.choice.plan'), value: 'plan' }
955
- ]
956
- }
957
- ]);
958
- if (action === 'scaffold') {
959
- await runInteractiveScaffold();
960
- }
961
- else if (action === 'fill') {
962
- await runInteractiveLlmFill();
982
+ if (showWelcome) {
983
+ ui.displayWelcome(VERSION);
963
984
  }
964
- else {
965
- await runInteractivePlan();
985
+ }
986
+ async function runInteractive() {
987
+ await selectLocale(true);
988
+ let exitRequested = false;
989
+ while (!exitRequested) {
990
+ const { action } = await inquirer_1.default.prompt([
991
+ {
992
+ type: 'list',
993
+ name: 'action',
994
+ message: t('prompts.main.action'),
995
+ choices: [
996
+ { name: t('prompts.main.choice.scaffold'), value: 'scaffold' },
997
+ { name: t('prompts.main.choice.fill'), value: 'fill' },
998
+ { name: t('prompts.main.choice.plan'), value: 'plan' },
999
+ { name: t('prompts.main.choice.changeLanguage'), value: 'changeLanguage' },
1000
+ { name: t('prompts.main.choice.exit'), value: 'exit' }
1001
+ ]
1002
+ }
1003
+ ]);
1004
+ if (action === 'changeLanguage') {
1005
+ await selectLocale(true);
1006
+ continue;
1007
+ }
1008
+ if (action === 'exit') {
1009
+ exitRequested = true;
1010
+ break;
1011
+ }
1012
+ if (action === 'scaffold') {
1013
+ await runInteractiveScaffold();
1014
+ }
1015
+ else if (action === 'fill') {
1016
+ await runInteractiveLlmFill();
1017
+ }
1018
+ else {
1019
+ await runInteractivePlan();
1020
+ }
1021
+ ui.displayInfo(t('info.interactive.returning.title'), t('info.interactive.returning.detail'));
966
1022
  }
1023
+ ui.displaySuccess(t('success.interactive.goodbye'));
967
1024
  }
968
1025
  async function runInteractiveScaffold() {
969
1026
  const { repoPath } = await inquirer_1.default.prompt([
@@ -1072,8 +1129,7 @@ async function runInteractiveLlmFill() {
1072
1129
  ]);
1073
1130
  const resolvedRepo = path.resolve(repoPath.trim() || '.');
1074
1131
  const defaultOutput = path.resolve(resolvedRepo, '.context');
1075
- const defaultPrompt = path.resolve(process.cwd(), 'prompts/update_scaffold_prompt.md');
1076
- const { outputDir, promptPath } = await inquirer_1.default.prompt([
1132
+ const { outputDir, promptPath: promptPathInput } = await inquirer_1.default.prompt([
1077
1133
  {
1078
1134
  type: 'input',
1079
1135
  name: 'outputDir',
@@ -1084,9 +1140,10 @@ async function runInteractiveLlmFill() {
1084
1140
  type: 'input',
1085
1141
  name: 'promptPath',
1086
1142
  message: t('prompts.fill.promptPath'),
1087
- default: defaultPrompt
1143
+ default: ''
1088
1144
  }
1089
1145
  ]);
1146
+ const promptPath = promptPathInput.trim() ? path.resolve(promptPathInput.trim()) : undefined;
1090
1147
  const { dryRun, processAll } = await inquirer_1.default.prompt([
1091
1148
  {
1092
1149
  type: 'confirm',
@@ -1451,6 +1508,7 @@ function filterOutLocaleArgs(args) {
1451
1508
  }
1452
1509
  async function main() {
1453
1510
  const userArgs = process.argv.slice(2);
1511
+ void scheduleVersionCheck();
1454
1512
  const meaningfulArgs = filterOutLocaleArgs(userArgs);
1455
1513
  if (meaningfulArgs.length === 0) {
1456
1514
  await runInteractive();