@abranjith/spec-lite 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -25
- package/dist/index.js +181 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/prompts/architect.md +495 -0
- package/prompts/brainstorm.md +8 -8
- package/prompts/code_review.md +11 -11
- package/prompts/devops.md +9 -9
- package/prompts/feature.md +23 -23
- package/prompts/fix.md +12 -12
- package/prompts/implement.md +20 -20
- package/prompts/integration_tests.md +8 -8
- package/prompts/memorize.md +41 -20
- package/prompts/orchestrator.md +48 -41
- package/prompts/performance_review.md +7 -7
- package/prompts/planner.md +24 -24
- package/prompts/readme.md +8 -8
- package/prompts/security_audit.md +9 -9
- package/prompts/spec_help.md +22 -19
- package/prompts/technical_docs.md +11 -11
- package/prompts/unit_tests.md +12 -12
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ spec-lite is a set of **modular prompt files** — each defining a specialist AI
|
|
|
14
14
|
- **Modular** — Use one sub-agent or all of them. Skip what you don't need.
|
|
15
15
|
- **Unopinionated** — Adapts to any project type (web, CLI, library, desktop, pipeline), any language, any stack.
|
|
16
16
|
- **Finite-scoped** — Each sub-agent has one job, clear inputs, and a concrete output artifact.
|
|
17
|
-
- **Memory-first** — Cross-cutting standards (coding conventions, architecture, testing, security) live in `.spec/memory.md` — the single source of truth read by every sub-agent.
|
|
17
|
+
- **Memory-first** — Cross-cutting standards (coding conventions, architecture, testing, security) live in `.spec-lite/memory.md` — the single source of truth read by every sub-agent.
|
|
18
18
|
- **Provider-agnostic** — Works with GitHub Copilot, Claude Code, or any LLM via generic mode.
|
|
19
19
|
|
|
20
20
|
---
|
|
@@ -22,7 +22,7 @@ spec-lite is a set of **modular prompt files** — each defining a specialist AI
|
|
|
22
22
|
## Installation
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
npm install -g spec-lite
|
|
25
|
+
npm install -g @abranjith/spec-lite
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Requires Node.js 18+.
|
|
@@ -47,7 +47,7 @@ The CLI will walk you through a short **project profile questionnaire** (languag
|
|
|
47
47
|
1. Write agent prompt files to the correct location for your AI tool
|
|
48
48
|
2. Inject your tech-stack context into every prompt's `<!-- project-context -->` block
|
|
49
49
|
3. Copy a curated **best-practice snippet** for your stack into `.spec-lite/stacks/`
|
|
50
|
-
4. Create the `.spec/` directory structure for agent outputs
|
|
50
|
+
4. Create the `.spec-lite/` directory structure for agent outputs
|
|
51
51
|
5. Save a `.spec-lite.json` config (including your project profile) to track your setup
|
|
52
52
|
|
|
53
53
|
After init completes, run **`/memorize bootstrap`** (see below) to let the LLM auto-generate a comprehensive `memory.md` from your codebase.
|
|
@@ -88,12 +88,12 @@ More providers (Cursor, Windsurf, Cline, Zed) coming soon.
|
|
|
88
88
|
|
|
89
89
|
## Memory-First Architecture
|
|
90
90
|
|
|
91
|
-
spec-lite uses a **memory-first** approach: cross-cutting concerns that every sub-agent needs — coding standards, architecture patterns, testing conventions, security guidelines, logging strategy — live in a single file: **`.spec/memory.md`**.
|
|
91
|
+
spec-lite uses a **memory-first** approach: cross-cutting concerns that every sub-agent needs — coding standards, architecture patterns, testing conventions, security guidelines, logging strategy — live in a single file: **`.spec-lite/memory.md`**.
|
|
92
92
|
|
|
93
93
|
| Source | Purpose | Authority |
|
|
94
94
|
|--------|---------|-----------|
|
|
95
|
-
| `.spec/memory.md` | Cross-cutting standards & conventions | **Primary** — authoritative for all sub-agents |
|
|
96
|
-
| `.spec/plan.md` or `.spec/plan_<name>.md` | Project-specific blueprint(s) & task breakdown | Overrides memory only with explicit justification |
|
|
95
|
+
| `.spec-lite/memory.md` | Cross-cutting standards & conventions | **Primary** — authoritative for all sub-agents |
|
|
96
|
+
| `.spec-lite/plan.md` or `.spec-lite/plan_<name>.md` | Project-specific blueprint(s) & task breakdown | Overrides memory only with explicit justification |
|
|
97
97
|
| User instruction | Ad-hoc guidance in chat | Highest priority (trumps both) |
|
|
98
98
|
|
|
99
99
|
### Bootstrap Flow
|
|
@@ -121,45 +121,47 @@ spec_help (anytime)
|
|
|
121
121
|
|
|
122
122
|
┌─ /memorize bootstrap (one-time setup)
|
|
123
123
|
▼
|
|
124
|
-
Brainstorm ─→ Planner ─→ Feature (×N) ─→ Reviews ─→ Tests ─→ DevOps ─→ Docs
|
|
124
|
+
Brainstorm ─→ Planner ─→ Architect ─→ Feature (×N) ─→ Reviews ─→ Tests ─→ DevOps ─→ Docs
|
|
125
125
|
│ ├─ Code Review
|
|
126
126
|
│ ├─ Security Audit
|
|
127
127
|
▼ └─ Performance Review
|
|
128
128
|
TODO.md (living backlog)
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
-
All sub-agents read `.spec/memory.md` first for standing instructions, then the relevant plan (`.spec/plan.md` or `.spec/plan_<name>.md`) for project-specific context. Complex projects can have multiple named plans — one per domain (e.g., `plan_order_management.md`, `plan_catalog.md`). Not every project needs every sub-agent. Start with the Planner if you already have requirements. Use `spec-lite list` or the spec_help sub-agent to understand the pipeline.
|
|
131
|
+
All sub-agents read `.spec-lite/memory.md` first for standing instructions, then the relevant plan (`.spec-lite/plan.md` or `.spec-lite/plan_<name>.md`) for project-specific context. Complex projects can have multiple named plans — one per domain (e.g., `plan_order_management.md`, `plan_catalog.md`). Not every project needs every sub-agent. Start with the Planner if you already have requirements. Use `spec-lite list` or the spec_help sub-agent to understand the pipeline.
|
|
132
132
|
|
|
133
133
|
## Sub-Agent Prompt Files
|
|
134
134
|
|
|
135
135
|
| File | Sub-Agent | What It Does | Output |
|
|
136
136
|
|------|-----------|-------------|--------|
|
|
137
137
|
| [spec_help.md](prompts/spec_help.md) | Spec Help | Navigator — explains which sub-agent to use and when | Interactive guidance |
|
|
138
|
-
| [brainstorm.md](prompts/brainstorm.md) | Brainstorm | Back-and-forth ideation partner that refines vague ideas | `.spec/brainstorm.md` |
|
|
139
|
-
| [planner.md](prompts/planner.md) | Planner | Creates a detailed technical blueprint (living document) | `.spec/plan.md` or `.spec/plan_<name>.md` |
|
|
140
|
-
| [
|
|
141
|
-
| [
|
|
142
|
-
| [
|
|
143
|
-
| [
|
|
144
|
-
| [
|
|
145
|
-
| [
|
|
146
|
-
| [
|
|
147
|
-
| [
|
|
138
|
+
| [brainstorm.md](prompts/brainstorm.md) | Brainstorm | Back-and-forth ideation partner that refines vague ideas | `.spec-lite/brainstorm.md` |
|
|
139
|
+
| [planner.md](prompts/planner.md) | Planner | Creates a detailed technical blueprint (living document) | `.spec-lite/plan.md` or `.spec-lite/plan_<name>.md` |
|
|
140
|
+
| [architect.md](prompts/architect.md) | Architect | Designs cloud infrastructure, database strategy, and scaling architecture | `.spec-lite/architect_<name>.md` |
|
|
141
|
+
| [feature.md](prompts/feature.md) | Feature | 3-phase lifecycle: explore → tasks → implement+test+docs | `.spec-lite/features/feature_<name>.md` |
|
|
142
|
+
| [code_review.md](prompts/code_review.md) | Code Review | Reviews code for correctness, architecture, readability | `.spec-lite/reviews/code_review_<name>.md` |
|
|
143
|
+
| [security_audit.md](prompts/security_audit.md) | Security Audit | Threat-models and scans for vulnerabilities | `.spec-lite/reviews/security_audit.md` |
|
|
144
|
+
| [performance_review.md](prompts/performance_review.md) | Performance Review | Identifies bottlenecks and optimization opportunities | `.spec-lite/reviews/performance_review.md` |
|
|
145
|
+
| [integration_tests.md](prompts/integration_tests.md) | Integration Tests | Writes traceable integration test scenarios from feature specs | `.spec-lite/features/integration_tests_<name>.md` |
|
|
146
|
+
| [unit_tests.md](prompts/unit_tests.md) | Unit Tests | Generates comprehensive unit tests with edge-case coverage and smart coverage exclusions | `.spec-lite/features/unit_tests_<name>.md` |
|
|
147
|
+
| [devops.md](prompts/devops.md) | DevOps | Sets up Docker, CI/CD, environments, and deployment | `.spec-lite/devops/` + infra files |
|
|
148
|
+
| [fix.md](prompts/fix.md) | Fix | Debugs issues with root cause analysis + regression tests | `.spec-lite/reviews/fix_<issue>.md` |
|
|
148
149
|
| [technical_docs.md](prompts/technical_docs.md) | Technical Docs | Creates architecture docs, API references, setup guides | Technical documentation |
|
|
149
150
|
| [readme.md](prompts/readme.md) | README | Writes the project README | `README.md` |
|
|
150
|
-
| [memorize.md](prompts/memorize.md) | Memorize | Manages `.spec/memory.md` — standing instructions for all agents. Use `/memorize bootstrap` to auto-generate. | `.spec/memory.md` |
|
|
151
|
+
| [memorize.md](prompts/memorize.md) | Memorize | Manages `.spec-lite/memory.md` — standing instructions for all agents. Use `/memorize bootstrap` to auto-generate. | `.spec-lite/memory.md` |
|
|
151
152
|
| [orchestrator.md](prompts/orchestrator.md) | — | Meta-document: pipeline, memory protocol, conflict resolution | Reference only |
|
|
152
153
|
|
|
153
154
|
## Output Directory Structure
|
|
154
155
|
|
|
155
|
-
spec-lite sub-agents produce artifacts in the `.spec/` directory (version-controlled project metadata):
|
|
156
|
+
spec-lite sub-agents produce artifacts in the `.spec-lite/` directory (version-controlled project metadata):
|
|
156
157
|
|
|
157
158
|
```
|
|
158
|
-
.spec/
|
|
159
|
+
.spec-lite/
|
|
159
160
|
├── memory.md # Cross-cutting standards — authoritative source
|
|
160
161
|
├── brainstorm.md
|
|
161
162
|
├── plan.md # Default plan (simple projects) — user-modifiable
|
|
162
163
|
├── plan_<name>.md # Named plans (complex projects, e.g., plan_order_management.md)
|
|
164
|
+
├── architect_<name>.md # Cloud & infrastructure architecture (e.g., architect_fintech_platform.md)
|
|
163
165
|
├── TODO.md # Enhancement backlog — maintained by planner + feature
|
|
164
166
|
├── features/
|
|
165
167
|
│ ├── feature_user_management.md
|
|
@@ -184,7 +186,7 @@ See [orchestrator.md](prompts/orchestrator.md) for the complete workflow documen
|
|
|
184
186
|
- The full sub-agent pipeline DAG
|
|
185
187
|
- Memory protocol — which artifacts each sub-agent reads
|
|
186
188
|
- Conflict resolution rules (user instruction > plan > sub-agent expertise)
|
|
187
|
-
- Enhancement tracking via `.spec/TODO.md`
|
|
189
|
+
- Enhancement tracking via `.spec-lite/TODO.md`
|
|
188
190
|
- Invocation patterns for different scenarios (new project, feature addition, bug fix)
|
|
189
191
|
|
|
190
192
|
## CLI Commands
|
|
@@ -228,13 +230,13 @@ spec-lite relies on **git** for artifact versioning. When a plan or review is up
|
|
|
228
230
|
|
|
229
231
|
spec-lite is designed to be forked and adapted:
|
|
230
232
|
|
|
231
|
-
- **Bootstrap memory first** — run `/memorize bootstrap` after init to populate `.spec/memory.md` with your project's standards.
|
|
232
|
-
- **Edit memory directly** — `.spec/memory.md` is the standing-instruction file. Your edits persist across all sub-agent invocations.
|
|
233
|
+
- **Bootstrap memory first** — run `/memorize bootstrap` after init to populate `.spec-lite/memory.md` with your project's standards.
|
|
234
|
+
- **Edit memory directly** — `.spec-lite/memory.md` is the standing-instruction file. Your edits persist across all sub-agent invocations.
|
|
233
235
|
- **Add project-specific conventions** to the Project Context blocks or directly to memory.
|
|
234
236
|
- **Remove sub-agents** you don't need.
|
|
235
237
|
- **Add new sub-agents** following the same pattern (Persona → Required Context → Process → Output Template → Constraints).
|
|
236
238
|
- **Modify output paths** to match your project's directory structure.
|
|
237
|
-
- **Edit the plan** — `.spec/plan.md` (or `.spec/plan_<name>.md` for named plans) is a living document. Your edits take priority over sub-agent defaults.
|
|
239
|
+
- **Edit the plan** — `.spec-lite/plan.md` (or `.spec-lite/plan_<name>.md` for named plans) is a living document. Your edits take priority over sub-agent defaults.
|
|
238
240
|
- **Add stack snippets** — drop a `<language>.md` file into `src/stacks/` to add best-practice snippets for additional languages.
|
|
239
241
|
|
|
240
242
|
Contributions welcome — especially for new sub-agent types, improvements to existing prompts, and real-world usage feedback.
|
package/dist/index.js
CHANGED
|
@@ -48,6 +48,13 @@ var CopilotProvider = class {
|
|
|
48
48
|
}
|
|
49
49
|
return existing;
|
|
50
50
|
}
|
|
51
|
+
async getMemorySeedSource(workspaceRoot) {
|
|
52
|
+
const p = path.join(workspaceRoot, ".github", "copilot-instructions.md");
|
|
53
|
+
if (await fs.pathExists(p)) {
|
|
54
|
+
return { path: ".github/copilot-instructions.md", label: "GitHub Copilot global instructions" };
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
51
58
|
getPostInitMessage() {
|
|
52
59
|
return [
|
|
53
60
|
"",
|
|
@@ -65,6 +72,42 @@ var CopilotProvider = class {
|
|
|
65
72
|
].join("\n");
|
|
66
73
|
}
|
|
67
74
|
};
|
|
75
|
+
var SPEC_LITE_MARKER_START = "<!-- spec-lite:start -->";
|
|
76
|
+
var SPEC_LITE_MARKER_END = "<!-- spec-lite:end -->";
|
|
77
|
+
function generateSpecLiteBlock(installedPrompts) {
|
|
78
|
+
const lines = [
|
|
79
|
+
SPEC_LITE_MARKER_START,
|
|
80
|
+
"## spec-lite Sub-Agents",
|
|
81
|
+
"",
|
|
82
|
+
"This project uses [spec-lite](https://github.com/ranjithab/spec-lite) sub-agent prompts",
|
|
83
|
+
"for structured software engineering workflows.",
|
|
84
|
+
"",
|
|
85
|
+
"The following specialist sub-agents are available in `.github/copilot/`:",
|
|
86
|
+
""
|
|
87
|
+
];
|
|
88
|
+
for (const name of installedPrompts) {
|
|
89
|
+
lines.push(`- [${name}](.github/copilot/${name}.prompt.md)`);
|
|
90
|
+
}
|
|
91
|
+
lines.push(
|
|
92
|
+
"",
|
|
93
|
+
"To invoke a sub-agent in Copilot Chat, use the `#` file reference or type `/` to browse prompt files.",
|
|
94
|
+
SPEC_LITE_MARKER_END
|
|
95
|
+
);
|
|
96
|
+
return lines.join("\n");
|
|
97
|
+
}
|
|
98
|
+
function mergeCopilotInstructions(existingContent, installedPrompts) {
|
|
99
|
+
const block = generateSpecLiteBlock(installedPrompts);
|
|
100
|
+
if (!existingContent) {
|
|
101
|
+
return block + "\n";
|
|
102
|
+
}
|
|
103
|
+
const startIdx = existingContent.indexOf(SPEC_LITE_MARKER_START);
|
|
104
|
+
const endIdx = existingContent.indexOf(SPEC_LITE_MARKER_END);
|
|
105
|
+
if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
|
|
106
|
+
return existingContent.slice(0, startIdx) + block + existingContent.slice(endIdx + SPEC_LITE_MARKER_END.length);
|
|
107
|
+
}
|
|
108
|
+
const separator = existingContent.endsWith("\n") ? "\n" : "\n\n";
|
|
109
|
+
return existingContent + separator + block + "\n";
|
|
110
|
+
}
|
|
68
111
|
|
|
69
112
|
// src/providers/claude-code.ts
|
|
70
113
|
import path2 from "path";
|
|
@@ -105,6 +148,13 @@ var ClaudeCodeProvider = class {
|
|
|
105
148
|
}
|
|
106
149
|
return existing;
|
|
107
150
|
}
|
|
151
|
+
async getMemorySeedSource(workspaceRoot) {
|
|
152
|
+
const p = path2.join(workspaceRoot, "CLAUDE.md");
|
|
153
|
+
if (await fs2.pathExists(p)) {
|
|
154
|
+
return { path: "CLAUDE.md", label: "Claude root instructions (CLAUDE.md)" };
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
108
158
|
getPostInitMessage() {
|
|
109
159
|
return [
|
|
110
160
|
"",
|
|
@@ -150,10 +200,10 @@ function generateClaudeRootMd(installedPrompts) {
|
|
|
150
200
|
"",
|
|
151
201
|
"## Output Directory",
|
|
152
202
|
"",
|
|
153
|
-
"Sub-agent outputs are written to the `.spec/` directory:",
|
|
203
|
+
"Sub-agent outputs are written to the `.spec-lite/` directory:",
|
|
154
204
|
"",
|
|
155
205
|
"```text",
|
|
156
|
-
".spec/",
|
|
206
|
+
".spec-lite/",
|
|
157
207
|
"\u251C\u2500\u2500 brainstorm.md",
|
|
158
208
|
"\u251C\u2500\u2500 plan.md # Default plan (simple projects)",
|
|
159
209
|
"\u251C\u2500\u2500 plan_<name>.md # Named plans (complex projects)",
|
|
@@ -197,6 +247,9 @@ var GenericProvider = class {
|
|
|
197
247
|
}
|
|
198
248
|
return existing;
|
|
199
249
|
}
|
|
250
|
+
async getMemorySeedSource(_workspaceRoot) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
200
253
|
getPostInitMessage() {
|
|
201
254
|
return [
|
|
202
255
|
"",
|
|
@@ -245,17 +298,17 @@ var PROMPT_CATALOG = {
|
|
|
245
298
|
brainstorm: {
|
|
246
299
|
title: "Brainstorm",
|
|
247
300
|
description: "Refines a vague idea into a clear, actionable vision",
|
|
248
|
-
output: ".spec/brainstorm.md"
|
|
301
|
+
output: ".spec-lite/brainstorm.md"
|
|
249
302
|
},
|
|
250
303
|
planner: {
|
|
251
304
|
title: "Planner",
|
|
252
305
|
description: "Creates a detailed technical blueprint from requirements",
|
|
253
|
-
output: ".spec/plan.md or .spec/plan_<name>.md"
|
|
306
|
+
output: ".spec-lite/plan.md or .spec-lite/plan_<name>.md"
|
|
254
307
|
},
|
|
255
308
|
feature: {
|
|
256
309
|
title: "Feature",
|
|
257
310
|
description: "Breaks one feature into granular, verifiable vertical slices",
|
|
258
|
-
output: ".spec/features/feature_<name>.md"
|
|
311
|
+
output: ".spec-lite/features/feature_<name>.md"
|
|
259
312
|
},
|
|
260
313
|
implement: {
|
|
261
314
|
title: "Implement",
|
|
@@ -265,17 +318,17 @@ var PROMPT_CATALOG = {
|
|
|
265
318
|
code_review: {
|
|
266
319
|
title: "Code Review",
|
|
267
320
|
description: "Reviews code for correctness, architecture, and readability",
|
|
268
|
-
output: ".spec/reviews/code_review_<name>.md"
|
|
321
|
+
output: ".spec-lite/reviews/code_review_<name>.md"
|
|
269
322
|
},
|
|
270
323
|
security_audit: {
|
|
271
324
|
title: "Security Audit",
|
|
272
325
|
description: "Scans for vulnerabilities, misconfigurations, and security risks",
|
|
273
|
-
output: ".spec/reviews/security_audit_<scope>.md"
|
|
326
|
+
output: ".spec-lite/reviews/security_audit_<scope>.md"
|
|
274
327
|
},
|
|
275
328
|
performance_review: {
|
|
276
329
|
title: "Performance Review",
|
|
277
330
|
description: "Identifies bottlenecks and optimization opportunities",
|
|
278
|
-
output: ".spec/reviews/performance_review_<scope>.md"
|
|
331
|
+
output: ".spec-lite/reviews/performance_review_<scope>.md"
|
|
279
332
|
},
|
|
280
333
|
integration_tests: {
|
|
281
334
|
title: "Integration Tests",
|
|
@@ -285,7 +338,7 @@ var PROMPT_CATALOG = {
|
|
|
285
338
|
unit_tests: {
|
|
286
339
|
title: "Unit Tests",
|
|
287
340
|
description: "Generates comprehensive unit tests with edge-case coverage and smart coverage exclusions",
|
|
288
|
-
output: ".spec/features/unit_tests_<name>.md"
|
|
341
|
+
output: ".spec-lite/features/unit_tests_<name>.md"
|
|
289
342
|
},
|
|
290
343
|
devops: {
|
|
291
344
|
title: "DevOps",
|
|
@@ -300,7 +353,7 @@ var PROMPT_CATALOG = {
|
|
|
300
353
|
memorize: {
|
|
301
354
|
title: "Memorize",
|
|
302
355
|
description: "Stores standing instructions that all sub-agents enforce. Use `/memorize bootstrap` to auto-generate from project analysis.",
|
|
303
|
-
output: ".spec/memory.md"
|
|
356
|
+
output: ".spec-lite/memory.md"
|
|
304
357
|
},
|
|
305
358
|
technical_docs: {
|
|
306
359
|
title: "Technical Docs",
|
|
@@ -311,6 +364,11 @@ var PROMPT_CATALOG = {
|
|
|
311
364
|
title: "README",
|
|
312
365
|
description: "Writes the project README and optional user guide",
|
|
313
366
|
output: "README.md + docs/user_guide.md"
|
|
367
|
+
},
|
|
368
|
+
architect: {
|
|
369
|
+
title: "Architect",
|
|
370
|
+
description: "Designs cloud infrastructure, database strategy, and scaling architecture with Mermaid diagrams",
|
|
371
|
+
output: ".spec-lite/architect_<name>.md"
|
|
314
372
|
}
|
|
315
373
|
};
|
|
316
374
|
var SKIP_FILES = /* @__PURE__ */ new Set(["orchestrator"]);
|
|
@@ -492,6 +550,34 @@ function buildProjectContextBlock(profile) {
|
|
|
492
550
|
lines.push("");
|
|
493
551
|
return lines.join("\n");
|
|
494
552
|
}
|
|
553
|
+
function buildSeededMemory(sourceContent, sourcePath, version) {
|
|
554
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
555
|
+
return [
|
|
556
|
+
`<!-- Generated by spec-lite v${version} | sub-agent: memorize | seeded-from: ${sourcePath} | updated: ${date} -->`,
|
|
557
|
+
"",
|
|
558
|
+
"# Memory \u2014 Standing Instructions",
|
|
559
|
+
"",
|
|
560
|
+
`> These instructions were **auto-seeded** from \`${sourcePath}\` during \`spec-lite init\`.`,
|
|
561
|
+
"> They have not yet been organized into sections.",
|
|
562
|
+
"> Run `/memorize bootstrap` in your AI assistant to review, reorganize, and refine them.",
|
|
563
|
+
">",
|
|
564
|
+
"> Memory is the **authoritative source** for coding standards, architecture, testing, logging, and security.",
|
|
565
|
+
"> Plans may contain plan-specific overrides but should not duplicate these rules.",
|
|
566
|
+
"> Managed by the Memorize sub-agent. Do not edit section headers manually.",
|
|
567
|
+
"> To add or change instructions, invoke: `/memorize <your instructions>`",
|
|
568
|
+
"> To override: `/memorize override <your instructions>`",
|
|
569
|
+
"> To generate from project analysis: `/memorize bootstrap`",
|
|
570
|
+
"",
|
|
571
|
+
`<!-- seed-start: raw content imported from ${sourcePath} -->`,
|
|
572
|
+
"",
|
|
573
|
+
`## Imported from \`${sourcePath}\``,
|
|
574
|
+
"",
|
|
575
|
+
sourceContent.trim(),
|
|
576
|
+
"",
|
|
577
|
+
"<!-- seed-end -->",
|
|
578
|
+
""
|
|
579
|
+
].join("\n");
|
|
580
|
+
}
|
|
495
581
|
async function initCommand(options) {
|
|
496
582
|
const cwd = process.cwd();
|
|
497
583
|
console.log(chalk.bold("\n\u26A1 spec-lite init\n"));
|
|
@@ -532,7 +618,16 @@ async function initCommand(options) {
|
|
|
532
618
|
if (exclude.length > 0) {
|
|
533
619
|
console.log(chalk.dim(` Excluding: ${exclude.join(", ")}`));
|
|
534
620
|
}
|
|
621
|
+
const memorySeedSource = await provider.getMemorySeedSource(cwd);
|
|
622
|
+
let preSeedContent = null;
|
|
623
|
+
if (memorySeedSource) {
|
|
624
|
+
const seedAbsPath = path6.join(cwd, memorySeedSource.path);
|
|
625
|
+
if (await fs6.pathExists(seedAbsPath)) {
|
|
626
|
+
preSeedContent = await fs6.readFile(seedAbsPath, "utf-8");
|
|
627
|
+
}
|
|
628
|
+
}
|
|
535
629
|
const existingFiles = await provider.detectExisting(cwd);
|
|
630
|
+
let globalAction = null;
|
|
536
631
|
if (existingFiles.length > 0 && !options.force) {
|
|
537
632
|
console.log(
|
|
538
633
|
chalk.yellow(
|
|
@@ -563,7 +658,8 @@ ${existingFiles.map((f) => ` - ${f}`).join("\n")}`
|
|
|
563
658
|
console.log(chalk.dim(" Aborted."));
|
|
564
659
|
return;
|
|
565
660
|
}
|
|
566
|
-
|
|
661
|
+
globalAction = answer.action;
|
|
662
|
+
if (globalAction === "skip") {
|
|
567
663
|
console.log(chalk.dim(" Skipping existing files."));
|
|
568
664
|
}
|
|
569
665
|
}
|
|
@@ -575,23 +671,10 @@ ${existingFiles.map((f) => ` - ${f}`).join("\n")}`
|
|
|
575
671
|
for (const prompt of prompts) {
|
|
576
672
|
const targetRelPath = provider.getTargetPath(prompt.name);
|
|
577
673
|
const targetAbsPath = path6.join(cwd, targetRelPath);
|
|
578
|
-
if (!options.force && existingFiles.includes(targetRelPath) &&
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
name: "action",
|
|
583
|
-
message: `How should we handle existing files?`,
|
|
584
|
-
choices: [
|
|
585
|
-
{ name: "Overwrite", value: "overwrite" },
|
|
586
|
-
{ name: "Skip", value: "skip" }
|
|
587
|
-
]
|
|
588
|
-
}
|
|
589
|
-
]);
|
|
590
|
-
if (answer.action === "skip") {
|
|
591
|
-
skipped++;
|
|
592
|
-
installedPrompts.push(prompt.name);
|
|
593
|
-
continue;
|
|
594
|
-
}
|
|
674
|
+
if (!options.force && existingFiles.includes(targetRelPath) && globalAction === "skip") {
|
|
675
|
+
skipped++;
|
|
676
|
+
installedPrompts.push(prompt.name);
|
|
677
|
+
continue;
|
|
595
678
|
}
|
|
596
679
|
let content = prompt.content;
|
|
597
680
|
if (contextBlock) {
|
|
@@ -615,10 +698,22 @@ ${existingFiles.map((f) => ` - ${f}`).join("\n")}`
|
|
|
615
698
|
console.log(chalk.green(` \u2713 CLAUDE.md`));
|
|
616
699
|
written++;
|
|
617
700
|
}
|
|
701
|
+
if (provider.alias === "copilot") {
|
|
702
|
+
const copilotInstructionsPath = path6.join(cwd, ".github", "copilot-instructions.md");
|
|
703
|
+
await fs6.ensureDir(path6.join(cwd, ".github"));
|
|
704
|
+
const existingContent = await fs6.pathExists(copilotInstructionsPath) ? await fs6.readFile(copilotInstructionsPath, "utf-8") : null;
|
|
705
|
+
const merged = mergeCopilotInstructions(existingContent, installedPrompts);
|
|
706
|
+
await fs6.writeFile(copilotInstructionsPath, merged, "utf-8");
|
|
707
|
+
if (existingContent) {
|
|
708
|
+
console.log(chalk.green(` \u2713 .github/copilot-instructions.md (updated with spec-lite block)`));
|
|
709
|
+
} else {
|
|
710
|
+
console.log(chalk.green(` \u2713 .github/copilot-instructions.md`));
|
|
711
|
+
}
|
|
712
|
+
written++;
|
|
713
|
+
}
|
|
618
714
|
const specDirs = [
|
|
619
|
-
".spec",
|
|
620
|
-
path6.join(".spec", "
|
|
621
|
-
path6.join(".spec", "reviews")
|
|
715
|
+
path6.join(".spec-lite", "features"),
|
|
716
|
+
path6.join(".spec-lite", "reviews")
|
|
622
717
|
];
|
|
623
718
|
for (const dir of specDirs) {
|
|
624
719
|
const absDir = path6.join(cwd, dir);
|
|
@@ -627,7 +722,7 @@ ${existingFiles.map((f) => ` - ${f}`).join("\n")}`
|
|
|
627
722
|
console.log(chalk.green(` \u2713 ${dir}/`));
|
|
628
723
|
}
|
|
629
724
|
}
|
|
630
|
-
const todoPath = path6.join(cwd, ".spec", "TODO.md");
|
|
725
|
+
const todoPath = path6.join(cwd, ".spec-lite", "TODO.md");
|
|
631
726
|
if (!await fs6.pathExists(todoPath)) {
|
|
632
727
|
const todoContent = [
|
|
633
728
|
"# TODO \u2014 Enhancements & Ideas",
|
|
@@ -649,7 +744,7 @@ ${existingFiles.map((f) => ` - ${f}`).join("\n")}`
|
|
|
649
744
|
""
|
|
650
745
|
].join("\n");
|
|
651
746
|
await fs6.writeFile(todoPath, todoContent, "utf-8");
|
|
652
|
-
console.log(chalk.green(` \u2713 .spec/TODO.md`));
|
|
747
|
+
console.log(chalk.green(` \u2713 .spec-lite/TODO.md`));
|
|
653
748
|
}
|
|
654
749
|
if (projectProfile) {
|
|
655
750
|
const snippet = getStackSnippet(projectProfile.language);
|
|
@@ -674,6 +769,32 @@ ${existingFiles.map((f) => ` - ${f}`).join("\n")}`
|
|
|
674
769
|
}
|
|
675
770
|
}
|
|
676
771
|
}
|
|
772
|
+
let memorySeedWritten = false;
|
|
773
|
+
const memoryPath = path6.join(cwd, ".spec-lite", "memory.md");
|
|
774
|
+
if (preSeedContent && memorySeedSource && !await fs6.pathExists(memoryPath)) {
|
|
775
|
+
console.log(
|
|
776
|
+
chalk.cyan(`
|
|
777
|
+
\u{1F4A1} Found existing ${memorySeedSource.label} (${memorySeedSource.path}).`)
|
|
778
|
+
);
|
|
779
|
+
const seedAnswer = await inquirer.prompt([
|
|
780
|
+
{
|
|
781
|
+
type: "confirm",
|
|
782
|
+
name: "seedMemory",
|
|
783
|
+
message: `Seed .spec-lite/memory.md from it so /memorize bootstrap can refine your existing conventions?`,
|
|
784
|
+
default: true
|
|
785
|
+
}
|
|
786
|
+
]);
|
|
787
|
+
if (seedAnswer.seedMemory) {
|
|
788
|
+
const seedPkg = await loadPackageVersion();
|
|
789
|
+
const seededContent = buildSeededMemory(preSeedContent, memorySeedSource.path, seedPkg);
|
|
790
|
+
await fs6.ensureDir(path6.join(cwd, ".spec-lite"));
|
|
791
|
+
await fs6.writeFile(memoryPath, seededContent, "utf-8");
|
|
792
|
+
memorySeedWritten = true;
|
|
793
|
+
written++;
|
|
794
|
+
console.log(chalk.green(` \u2713 .spec-lite/memory.md (seeded from ${memorySeedSource.path})`));
|
|
795
|
+
console.log(chalk.dim(" \u21B3 Run /memorize bootstrap to organize and refine into standing instructions"));
|
|
796
|
+
}
|
|
797
|
+
}
|
|
677
798
|
const pkg2 = await loadPackageVersion();
|
|
678
799
|
const config = {
|
|
679
800
|
version: pkg2,
|
|
@@ -693,14 +814,24 @@ ${existingFiles.map((f) => ` - ${f}`).join("\n")}`
|
|
|
693
814
|
)
|
|
694
815
|
);
|
|
695
816
|
console.log(provider.getPostInitMessage());
|
|
696
|
-
if (projectProfile) {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
817
|
+
if (projectProfile || memorySeedWritten) {
|
|
818
|
+
if (memorySeedWritten) {
|
|
819
|
+
console.log(
|
|
820
|
+
chalk.cyan(
|
|
821
|
+
"\n \u{1F4CC} Next step: Run "
|
|
822
|
+
) + chalk.bold("/memorize bootstrap") + chalk.cyan(
|
|
823
|
+
" in your AI assistant.\n It will see your seeded memory and offer to merge or refine it\n into properly organized standing instructions."
|
|
824
|
+
)
|
|
825
|
+
);
|
|
826
|
+
} else {
|
|
827
|
+
console.log(
|
|
828
|
+
chalk.cyan(
|
|
829
|
+
"\n \u{1F4CC} Next step: Run "
|
|
830
|
+
) + chalk.bold("/memorize bootstrap") + chalk.cyan(
|
|
831
|
+
" in your AI assistant to auto-generate\n coding standards, architecture guidelines, and best practices\n for your project based on the profile you just provided."
|
|
832
|
+
)
|
|
833
|
+
);
|
|
834
|
+
}
|
|
704
835
|
}
|
|
705
836
|
}
|
|
706
837
|
async function loadPackageVersion() {
|
|
@@ -710,7 +841,7 @@ async function loadPackageVersion() {
|
|
|
710
841
|
const pkg2 = require3("../../package.json");
|
|
711
842
|
return pkg2.version;
|
|
712
843
|
} catch {
|
|
713
|
-
return "
|
|
844
|
+
return "0.0.3";
|
|
714
845
|
}
|
|
715
846
|
}
|
|
716
847
|
|
|
@@ -810,6 +941,14 @@ async function updateCommand(options) {
|
|
|
810
941
|
await fs7.writeFile(claudeMdPath, claudeMdContent, "utf-8");
|
|
811
942
|
console.log(chalk2.green(` \u2713 CLAUDE.md (regenerated)`));
|
|
812
943
|
}
|
|
944
|
+
if (provider.alias === "copilot") {
|
|
945
|
+
const copilotInstructionsPath = path7.join(cwd, ".github", "copilot-instructions.md");
|
|
946
|
+
await fs7.ensureDir(path7.join(cwd, ".github"));
|
|
947
|
+
const existingContent = await fs7.pathExists(copilotInstructionsPath) ? await fs7.readFile(copilotInstructionsPath, "utf-8") : null;
|
|
948
|
+
const merged = mergeCopilotInstructions(existingContent, config.installedPrompts);
|
|
949
|
+
await fs7.writeFile(copilotInstructionsPath, merged, "utf-8");
|
|
950
|
+
console.log(chalk2.green(` \u2713 .github/copilot-instructions.md (updated)`));
|
|
951
|
+
}
|
|
813
952
|
config.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
814
953
|
try {
|
|
815
954
|
const { createRequire: createRequire2 } = await import("module");
|