@trieungoctam/speckit 0.2.0 → 0.3.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.
- package/README.md +37 -5
- package/dist/adapters/antigravity-adapter.js +5 -5
- package/dist/adapters/claude-code-adapter.js +10 -5
- package/dist/adapters/codex-adapter.js +7 -3
- package/dist/adapters/cursor-adapter.js +10 -3
- package/dist/adapters/opencode-adapter.js +1 -0
- package/dist/cli.js +32 -0
- package/dist/commands/context.js +56 -22
- package/dist/commands/doctor.js +2 -1
- package/dist/commands/graph.d.ts +7 -0
- package/dist/commands/graph.js +51 -0
- package/dist/commands/init.js +3 -1
- package/dist/commands/memory.d.ts +6 -0
- package/dist/commands/memory.js +11 -0
- package/dist/commands/plan.js +19 -2
- package/dist/commands/quick.js +20 -2
- package/dist/commands/ready.d.ts +7 -0
- package/dist/commands/ready.js +20 -0
- package/dist/commands/run.js +15 -2
- package/dist/commands/session.d.ts +9 -0
- package/dist/commands/session.js +49 -0
- package/dist/commands/sprint.d.ts +7 -0
- package/dist/commands/sprint.js +54 -0
- package/dist/commands/start.js +4 -3
- package/dist/commands/sync.js +5 -2
- package/dist/commands/triage.js +2 -15
- package/dist/core/agent-scaffold.d.ts +2 -0
- package/dist/core/agent-scaffold.js +57 -0
- package/dist/core/beads-mirror.d.ts +3 -0
- package/dist/core/beads-mirror.js +46 -0
- package/dist/core/memory.d.ts +1 -0
- package/dist/core/memory.js +47 -0
- package/dist/core/readiness.d.ts +13 -0
- package/dist/core/readiness.js +120 -0
- package/dist/core/scaffold.js +72 -43
- package/dist/core/session-manager.d.ts +15 -0
- package/dist/core/session-manager.js +139 -0
- package/dist/core/skill-catalog.d.ts +2 -0
- package/dist/core/skill-catalog.js +177 -0
- package/dist/core/story.d.ts +5 -0
- package/dist/core/story.js +34 -0
- package/dist/core/synced-stories.d.ts +8 -0
- package/dist/core/synced-stories.js +17 -0
- package/dist/core/templates.d.ts +2 -0
- package/dist/core/templates.js +54 -0
- package/docs/development-roadmap.md +9 -7
- package/docs/product-contract.md +7 -4
- package/docs/project-changelog.md +66 -0
- package/docs/release-checklist.md +1 -1
- package/docs/spec-enterprise-harness-plan.md +18 -1
- package/docs/workflow-model.md +23 -0
- package/package.json +1 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { slugify, timestamp } from "./slug.js";
|
|
4
|
+
export async function ensureSession(root, intent = "long session") {
|
|
5
|
+
const active = await readActiveSession(root);
|
|
6
|
+
if (active)
|
|
7
|
+
return active;
|
|
8
|
+
return createSession(root, intent);
|
|
9
|
+
}
|
|
10
|
+
export async function createSession(root, intent = "long session") {
|
|
11
|
+
const id = `${timestamp()}-${slugify(intent)}`;
|
|
12
|
+
const ref = { id, dir: `.speckit/sessions/${id}` };
|
|
13
|
+
await mkdir(join(root, ref.dir), { recursive: true });
|
|
14
|
+
await writeActiveSession(root, ref);
|
|
15
|
+
await writeFile(join(root, ref.dir, "events.jsonl"), "", "utf8");
|
|
16
|
+
await writeFile(join(root, ref.dir, "artifact-log.md"), "# Spec Artifact Log\n\n", "utf8");
|
|
17
|
+
await writeFile(join(root, ref.dir, "summary.md"), baseSummary(intent), "utf8");
|
|
18
|
+
await writeState(root, ref, { phase: "started", status: "active", story: "pending" });
|
|
19
|
+
await writeHandoff(root, ref, "Start from the active Speckit session state.");
|
|
20
|
+
return ref;
|
|
21
|
+
}
|
|
22
|
+
export async function checkpointSession(options) {
|
|
23
|
+
const ref = await ensureSession(options.root, options.note ?? "checkpoint");
|
|
24
|
+
const event = {
|
|
25
|
+
type: "checkpoint",
|
|
26
|
+
at: new Date().toISOString(),
|
|
27
|
+
note: options.note ?? "Manual checkpoint",
|
|
28
|
+
story: options.story,
|
|
29
|
+
};
|
|
30
|
+
await appendFile(join(options.root, ref.dir, "events.jsonl"), `${JSON.stringify(event)}\n`, "utf8");
|
|
31
|
+
await appendFile(join(options.root, ref.dir, "artifact-log.md"), `## ${event.at}\n- Note: ${event.note}\n${options.story ? `- Story: \`${options.story}\`\n` : ""}\n`, "utf8");
|
|
32
|
+
await writeState(options.root, ref, {
|
|
33
|
+
phase: "checkpointed",
|
|
34
|
+
status: "active",
|
|
35
|
+
story: options.story ?? "pending",
|
|
36
|
+
});
|
|
37
|
+
return ref;
|
|
38
|
+
}
|
|
39
|
+
export async function compactSession(root) {
|
|
40
|
+
const ref = await ensureSession(root, "compact");
|
|
41
|
+
const [state, context, handoff, artifactLog] = await Promise.all([
|
|
42
|
+
readOptional(root, `${ref.dir}/state.yaml`),
|
|
43
|
+
readOptional(root, ".speckit/context/current.md"),
|
|
44
|
+
readOptional(root, ".speckit/context/subagent-handoff.md"),
|
|
45
|
+
readOptional(root, `${ref.dir}/artifact-log.md`),
|
|
46
|
+
]);
|
|
47
|
+
const summary = `# Spec Session Summary
|
|
48
|
+
|
|
49
|
+
## Session Intent
|
|
50
|
+
Preserve the active Speckit workflow so another agent or compacted session can continue safely.
|
|
51
|
+
|
|
52
|
+
## Current State
|
|
53
|
+
${state || "- No state recorded yet."}
|
|
54
|
+
|
|
55
|
+
## Active Context
|
|
56
|
+
${extractCompactSection(context)}
|
|
57
|
+
|
|
58
|
+
## Files And Artifacts
|
|
59
|
+
${extractCompactSection(artifactLog)}
|
|
60
|
+
|
|
61
|
+
## Decisions Made
|
|
62
|
+
- Trust current files over stale memory.
|
|
63
|
+
- Keep implementation bounded by the selected story and readiness gate.
|
|
64
|
+
|
|
65
|
+
## Next Steps
|
|
66
|
+
1. Read \`.speckit/memory/project-context.md\`.
|
|
67
|
+
2. Read \`.speckit/context/current.md\` and \`.speckit/context/subagent-handoff.md\`.
|
|
68
|
+
3. Run \`speckit session status\`.
|
|
69
|
+
4. Run \`speckit ready <story>\` before implementation.
|
|
70
|
+
|
|
71
|
+
## Resume Handoff
|
|
72
|
+
${extractCompactSection(handoff)}
|
|
73
|
+
`;
|
|
74
|
+
await writeFile(join(root, ref.dir, "summary.md"), summary, "utf8");
|
|
75
|
+
await writeHandoff(root, ref, "Resume from the compacted session summary before loading task context.");
|
|
76
|
+
return ref;
|
|
77
|
+
}
|
|
78
|
+
export async function resumeSession(root, id) {
|
|
79
|
+
const ref = id ? { id, dir: `.speckit/sessions/${id}` } : await readActiveSession(root);
|
|
80
|
+
if (!ref)
|
|
81
|
+
return undefined;
|
|
82
|
+
await writeActiveSession(root, ref);
|
|
83
|
+
await writeHandoff(root, ref, "Resume this session and continue from summary, context, and artifact log.");
|
|
84
|
+
return ref;
|
|
85
|
+
}
|
|
86
|
+
export async function sessionStatus(root) {
|
|
87
|
+
const ref = await readActiveSession(root);
|
|
88
|
+
if (!ref)
|
|
89
|
+
return { status: "missing" };
|
|
90
|
+
return {
|
|
91
|
+
status: "active",
|
|
92
|
+
id: ref.id,
|
|
93
|
+
dir: ref.dir,
|
|
94
|
+
state: `${ref.dir}/state.yaml`,
|
|
95
|
+
summary: `${ref.dir}/summary.md`,
|
|
96
|
+
handoff: `${ref.dir}/handoff.md`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
async function readActiveSession(root) {
|
|
100
|
+
try {
|
|
101
|
+
const content = await readFile(join(root, ".speckit", "sessions", "active.md"), "utf8");
|
|
102
|
+
const id = content.match(/session:\s*([^\s]+)/)?.[1];
|
|
103
|
+
return id ? { id, dir: `.speckit/sessions/${id}` } : undefined;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async function writeActiveSession(root, ref) {
|
|
110
|
+
await writeText(root, ".speckit/sessions/active.md", `# Active Spec Session\n\nsession: ${ref.id}\n`);
|
|
111
|
+
}
|
|
112
|
+
async function writeState(root, ref, state) {
|
|
113
|
+
const body = Object.entries({ session: ref.id, updated: new Date().toISOString(), ...state })
|
|
114
|
+
.map(([key, value]) => `${key}: ${value}`)
|
|
115
|
+
.join("\n");
|
|
116
|
+
await writeText(root, `${ref.dir}/state.yaml`, `${body}\n`);
|
|
117
|
+
}
|
|
118
|
+
async function writeHandoff(root, ref, note) {
|
|
119
|
+
await writeText(root, `${ref.dir}/handoff.md`, `# Spec Session Handoff\n\n${note}\n\n## Load Order\n1. \`${ref.dir}/summary.md\`\n2. \`${ref.dir}/state.yaml\`\n3. \`${ref.dir}/artifact-log.md\`\n4. \`.speckit/context/current.md\`\n`);
|
|
120
|
+
}
|
|
121
|
+
async function writeText(root, path, content) {
|
|
122
|
+
const target = join(root, path);
|
|
123
|
+
await mkdir(dirname(target), { recursive: true });
|
|
124
|
+
await writeFile(target, content, "utf8");
|
|
125
|
+
}
|
|
126
|
+
async function readOptional(root, path) {
|
|
127
|
+
try {
|
|
128
|
+
return await readFile(join(root, path), "utf8");
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return "";
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function baseSummary(intent) {
|
|
135
|
+
return `# Spec Session Summary\n\n## Session Intent\n${intent}\n\n## Current State\n- Session started.\n\n## Next Steps\n1. Build context.\n2. Sync graph.\n3. Run readiness.\n`;
|
|
136
|
+
}
|
|
137
|
+
function extractCompactSection(content) {
|
|
138
|
+
return content.trim() ? content.trim().split("\n").slice(0, 40).join("\n") : "- Not recorded.";
|
|
139
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { json, markdown } from "./managed-files.js";
|
|
2
|
+
const selectedSources = [
|
|
3
|
+
"brainstorm",
|
|
4
|
+
"research",
|
|
5
|
+
"docs-seeker",
|
|
6
|
+
"plan",
|
|
7
|
+
"project-management",
|
|
8
|
+
"scout",
|
|
9
|
+
"context-engineering",
|
|
10
|
+
"kanban",
|
|
11
|
+
"implementation-runner",
|
|
12
|
+
"test",
|
|
13
|
+
"debug",
|
|
14
|
+
"fix",
|
|
15
|
+
"code-review",
|
|
16
|
+
"security-scan",
|
|
17
|
+
"docs",
|
|
18
|
+
"journal",
|
|
19
|
+
"git",
|
|
20
|
+
"ship",
|
|
21
|
+
];
|
|
22
|
+
const skills = [
|
|
23
|
+
skill("spec-shape", "shape", "Turn a rough request into a bounded Agile spec before planning.", [
|
|
24
|
+
"Clarify business goal, users, constraints, and non-goals.",
|
|
25
|
+
"Split large ideas into independent stories with acceptance criteria.",
|
|
26
|
+
"Challenge over-engineered scope before it reaches implementation.",
|
|
27
|
+
]),
|
|
28
|
+
skill("spec-research", "research", "Validate external tools, docs, or architecture choices before planning.", [
|
|
29
|
+
"Define recency and source-quality requirements before searching.",
|
|
30
|
+
"Prefer official docs, primary repos, and current release notes.",
|
|
31
|
+
"Summarize recommendations, risks, and rejected options in reports.",
|
|
32
|
+
]),
|
|
33
|
+
skill("spec-plan", "plan", "Create PRD, architecture, story, and evidence skeletons.", [
|
|
34
|
+
"Check unfinished plans before creating new work.",
|
|
35
|
+
"Write phases with files, dependencies, success criteria, and rollback.",
|
|
36
|
+
"Keep plan state durable so sessions can rehydrate tasks later.",
|
|
37
|
+
]),
|
|
38
|
+
skill("spec-context", "context", "Build the smallest useful story context and subagent handoff.", [
|
|
39
|
+
"Read project memory, active session, story, evidence, and relevant files.",
|
|
40
|
+
"List files to read and files to modify separately.",
|
|
41
|
+
"Avoid passing full chat history to implementation agents.",
|
|
42
|
+
]),
|
|
43
|
+
skill("spec-session", "session", "Manage checkpoint, compaction, resume, and artifact-log discipline.", [
|
|
44
|
+
"Checkpoint after red, green, refactor, review, and scope changes.",
|
|
45
|
+
"Compact noisy context into durable summaries before handoff.",
|
|
46
|
+
"Sync runtime task progress back to plan and story files.",
|
|
47
|
+
]),
|
|
48
|
+
skill("spec-graph", "graph", "Use sprint and graph robot outputs to choose safe, unblocked work.", [
|
|
49
|
+
"Run Beads Viewer through robot-safe commands only.",
|
|
50
|
+
"Prefer unblocked, high-value stories with clear evidence paths.",
|
|
51
|
+
"Mirror story state to graph artifacts before triage or next selection.",
|
|
52
|
+
]),
|
|
53
|
+
skill("spec-tdd", "run", "Run a ready story through red-green-refactor with evidence and checkpoints.", [
|
|
54
|
+
"Require ready-for-dev status and current context before code edits.",
|
|
55
|
+
"Write or run the smallest failing test before implementation.",
|
|
56
|
+
"Record red, green, and refactor evidence with session checkpoints.",
|
|
57
|
+
]),
|
|
58
|
+
skill("spec-test", "test", "Select and run verification after implementation.", [
|
|
59
|
+
"Map changed files to focused tests first, then broaden when risk is high.",
|
|
60
|
+
"Run typecheck or build before claiming code is valid.",
|
|
61
|
+
"Never ignore failing tests; report root cause or blocker.",
|
|
62
|
+
]),
|
|
63
|
+
skill("spec-debug", "debug", "Diagnose failures with evidence before changing code.", [
|
|
64
|
+
"Capture exact failing output and pre-fix state.",
|
|
65
|
+
"Trace root cause through callers, dependencies, and recent changes.",
|
|
66
|
+
"Fix the cause, then verify against the original failure.",
|
|
67
|
+
]),
|
|
68
|
+
skill("spec-review", "review", "Review acceptance coverage, TDD evidence, safety, docs, and session freshness.", [
|
|
69
|
+
"Review spec compliance before code quality opinions.",
|
|
70
|
+
"Prioritize correctness, security, regressions, and missing tests.",
|
|
71
|
+
"Block closure when evidence, context, or session state is stale.",
|
|
72
|
+
]),
|
|
73
|
+
skill("spec-docs", "docs", "Update durable docs, changelog, and lessons after behavior changes.", [
|
|
74
|
+
"Update roadmap and changelog when milestone or behavior changes.",
|
|
75
|
+
"Record decisions and lessons in project memory when reusable.",
|
|
76
|
+
"Keep docs aligned with actual implemented behavior.",
|
|
77
|
+
]),
|
|
78
|
+
skill("spec-ship", "ship", "Prepare clean release handoff after tests and review pass.", [
|
|
79
|
+
"Check git diff for unrelated changes and secrets before commit.",
|
|
80
|
+
"Use focused conventional commits and release notes.",
|
|
81
|
+
"Do not ship while tests, review, or evidence gates are failing.",
|
|
82
|
+
]),
|
|
83
|
+
];
|
|
84
|
+
function skill(name, phase, purpose, practices) {
|
|
85
|
+
return { name, phase, purpose, practices };
|
|
86
|
+
}
|
|
87
|
+
export function specSkillFiles() {
|
|
88
|
+
return [catalogFile(), schemaFile(), ...skills.map(skillFile)];
|
|
89
|
+
}
|
|
90
|
+
function catalogFile() {
|
|
91
|
+
return {
|
|
92
|
+
path: ".speckit/skills/catalog.md",
|
|
93
|
+
content: markdown(`# Spec Skill Catalog
|
|
94
|
+
|
|
95
|
+
This catalog is intentionally smaller than a broad general-purpose skill set. Speckit keeps only the skills required for enterprise Agile, TDD, long sessions, graph-guided work, and release hygiene.
|
|
96
|
+
|
|
97
|
+
## Core Skills
|
|
98
|
+
|
|
99
|
+
| Skill | Inspired By | Use When | Required Inputs |
|
|
100
|
+
| --- | --- | --- | --- |
|
|
101
|
+
| spec-shape | brainstorm, scenario | Turning rough intent into a bounded spec | user intent, project memory |
|
|
102
|
+
| spec-research | research, docs-seeker | Validating external choices and current docs | scope, source criteria |
|
|
103
|
+
| spec-plan | plan, project-management | Creating PRD, architecture, stories, and evidence skeletons | spec brief, project memory |
|
|
104
|
+
| spec-context | scout, context-engineering | Building current story context and handoff | story, evidence, session state |
|
|
105
|
+
| spec-graph | kanban, plans-kanban, gkg | Choosing and sequencing safe work | synced stories, robot graph output |
|
|
106
|
+
| spec-session | context-engineering, watzup | Preserving long-running work | active session, artifact log |
|
|
107
|
+
| spec-tdd | implementation-runner, test | Implementing code with red-green-refactor | ready story, context, evidence |
|
|
108
|
+
| spec-test | test, web-testing | Selecting and running verification | changed files, acceptance criteria |
|
|
109
|
+
| spec-debug | debug, fix, sequential-thinking | Diagnosing failures before changing code | failing output, impact scope |
|
|
110
|
+
| spec-review | code-review, security-scan | Reviewing code and artifacts | diff, story, evidence, session log |
|
|
111
|
+
| spec-docs | docs, journal, retro | Updating docs and durable decisions | changed behavior, release notes |
|
|
112
|
+
| spec-ship | git, ship, deploy | Preparing clean release handoff | passing tests, review result |
|
|
113
|
+
|
|
114
|
+
## Selection Policy
|
|
115
|
+
|
|
116
|
+
- Pick the smallest skill that covers the current phase.
|
|
117
|
+
- Load skill detail only when that phase is active.
|
|
118
|
+
- Never mix planning and implementation in the same skill invocation.
|
|
119
|
+
- Prefer file handoff over chat handoff for subagents.
|
|
120
|
+
- Do not import broad domain skills unless the current story explicitly needs that domain.
|
|
121
|
+
- Use \`spec-debug\` before fixes when the root cause is not proven.
|
|
122
|
+
- Use \`spec-test\` after implementation and before review.
|
|
123
|
+
`),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function schemaFile() {
|
|
127
|
+
return {
|
|
128
|
+
path: ".speckit/skills/schema.json",
|
|
129
|
+
content: json({
|
|
130
|
+
version: 1,
|
|
131
|
+
required: ["name", "purpose", "phase", "inputs", "outputs", "stop_conditions"],
|
|
132
|
+
statuses: ["DONE", "DONE_WITH_CONCERNS", "BLOCKED", "NEEDS_CONTEXT"],
|
|
133
|
+
selected_from: selectedSources,
|
|
134
|
+
}),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function skillFile(skill) {
|
|
138
|
+
return {
|
|
139
|
+
path: `.speckit/skills/${skill.name}.md`,
|
|
140
|
+
content: markdown(`# ${skill.name}
|
|
141
|
+
|
|
142
|
+
## Purpose
|
|
143
|
+
|
|
144
|
+
${skill.purpose}
|
|
145
|
+
|
|
146
|
+
## Phase
|
|
147
|
+
|
|
148
|
+
${skill.phase}
|
|
149
|
+
|
|
150
|
+
## Required Context
|
|
151
|
+
|
|
152
|
+
- \`.speckit/memory/project-context.md\`
|
|
153
|
+
- \`.speckit/sessions/active.md\`
|
|
154
|
+
- \`.speckit/context/current.md\` when story-scoped
|
|
155
|
+
- \`.speckit/context/subagent-handoff.md\` when delegating
|
|
156
|
+
|
|
157
|
+
## Practices
|
|
158
|
+
|
|
159
|
+
${skill.practices.map((practice) => `- ${practice}`).join("\n")}
|
|
160
|
+
|
|
161
|
+
## Stop Conditions
|
|
162
|
+
|
|
163
|
+
- Missing acceptance criteria.
|
|
164
|
+
- Missing or stale active session.
|
|
165
|
+
- Missing evidence path for code work.
|
|
166
|
+
- Blocked story or unresolved \`NEEDS_CONTEXT\` handoff.
|
|
167
|
+
|
|
168
|
+
## Output Contract
|
|
169
|
+
|
|
170
|
+
- State what was read.
|
|
171
|
+
- State what changed.
|
|
172
|
+
- State the next Speckit command.
|
|
173
|
+
- Write durable progress to the appropriate Speckit artifact.
|
|
174
|
+
- End delegated work with \`DONE\`, \`DONE_WITH_CONCERNS\`, \`BLOCKED\`, or \`NEEDS_CONTEXT\`.
|
|
175
|
+
`),
|
|
176
|
+
};
|
|
177
|
+
}
|
package/dist/core/story.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ export type StoryResolution = {
|
|
|
3
3
|
content: string;
|
|
4
4
|
id: string;
|
|
5
5
|
title: string;
|
|
6
|
+
status?: string;
|
|
7
|
+
evidencePath?: string;
|
|
6
8
|
};
|
|
7
9
|
export declare function resolveStory(root: string, target: string): Promise<StoryResolution | undefined>;
|
|
10
|
+
export declare function frontmatterValue(content: string, key: string): string | undefined;
|
|
11
|
+
export declare function extractEvidenceReference(content: string): string | undefined;
|
|
12
|
+
export declare function extractSection(content: string, heading: string): string | undefined;
|
|
8
13
|
export declare function firstHeading(content: string): string | undefined;
|
package/dist/core/story.js
CHANGED
|
@@ -16,6 +16,8 @@ export async function resolveStory(root, target) {
|
|
|
16
16
|
content,
|
|
17
17
|
id: basename(candidate).replace(/\.md$/, ""),
|
|
18
18
|
title: firstHeading(content) ?? basename(candidate).replace(/\.md$/, ""),
|
|
19
|
+
status: frontmatterValue(content, "status"),
|
|
20
|
+
evidencePath: frontmatterValue(content, "evidence") ?? extractEvidenceReference(content),
|
|
19
21
|
};
|
|
20
22
|
}
|
|
21
23
|
catch {
|
|
@@ -24,6 +26,38 @@ export async function resolveStory(root, target) {
|
|
|
24
26
|
}
|
|
25
27
|
return undefined;
|
|
26
28
|
}
|
|
29
|
+
export function frontmatterValue(content, key) {
|
|
30
|
+
const lines = content.split("\n");
|
|
31
|
+
const start = lines.findIndex((line) => line.trim() === "---");
|
|
32
|
+
if (start === -1)
|
|
33
|
+
return undefined;
|
|
34
|
+
const end = lines.findIndex((line, index) => index > start && line.trim() === "---");
|
|
35
|
+
if (end === -1)
|
|
36
|
+
return undefined;
|
|
37
|
+
const prefix = `${key}:`;
|
|
38
|
+
const found = lines
|
|
39
|
+
.slice(start + 1, end)
|
|
40
|
+
.find((line) => line.trim().toLowerCase().startsWith(prefix.toLowerCase()));
|
|
41
|
+
return found?.slice(found.indexOf(":") + 1).trim().replace(/^["']|["']$/g, "");
|
|
42
|
+
}
|
|
43
|
+
export function extractEvidenceReference(content) {
|
|
44
|
+
const match = content.match(/`([^`]*tdd-evidence\.md)`/i);
|
|
45
|
+
return match?.[1];
|
|
46
|
+
}
|
|
47
|
+
export function extractSection(content, heading) {
|
|
48
|
+
const lines = content.split("\n");
|
|
49
|
+
const start = lines.findIndex((line) => line.trim().toLowerCase() === `## ${heading}`.toLowerCase());
|
|
50
|
+
if (start === -1)
|
|
51
|
+
return undefined;
|
|
52
|
+
const collected = [];
|
|
53
|
+
for (const line of lines.slice(start + 1)) {
|
|
54
|
+
if (line.startsWith("## "))
|
|
55
|
+
break;
|
|
56
|
+
if (line.trim())
|
|
57
|
+
collected.push(line);
|
|
58
|
+
}
|
|
59
|
+
return collected.length > 0 ? collected.join("\n") : undefined;
|
|
60
|
+
}
|
|
27
61
|
export function firstHeading(content) {
|
|
28
62
|
return content
|
|
29
63
|
.split("\n")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
export async function readSyncedStories(root) {
|
|
4
|
+
try {
|
|
5
|
+
const content = await readFile(join(root, ".speckit", "sync", "beads-sync.jsonl"), "utf8");
|
|
6
|
+
return content
|
|
7
|
+
.split("\n")
|
|
8
|
+
.filter(Boolean)
|
|
9
|
+
.map((line) => JSON.parse(line));
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function selectableStories(stories) {
|
|
16
|
+
return stories.filter((story) => ["open", "ready-for-dev", "in-progress"].includes(story.status));
|
|
17
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const storyTemplate = "---\nstatus: draft\nevidence: .speckit/evidence/{{slug}}-tdd-evidence.md\ncontext: pending\n---\n\n# Story: {{title}}\n\n## Intent\n{{intent}}\n\n## Acceptance Criteria\n- Given ...\n- When ...\n- Then ...\n\n## TDD Checklist\n- [ ] Test targets identified\n- [ ] Red evidence recorded\n- [ ] Green evidence recorded\n- [ ] Refactor validation recorded\n\n## Notes\n- Risks:\n- Dependencies:\n\n## Spec Anti-Mistake Checklist\n- Reuse existing project patterns before adding new files.\n- Verify file locations before editing.\n- Do not introduce new libraries without explicit need.\n- Preserve existing behavior unless an acceptance criterion requires change.\n- Capture previous-story learnings if this continues prior work.\n";
|
|
2
|
+
export declare const tddEvidenceTemplate = "---\nstatus: missing\nstory: {{story}}\n---\n\n# TDD Evidence: {{story}}\n\n## Test Intent\n\n## Red\n- Command:\n- Result:\n\n## Green\n- Command:\n- Result:\n\n## Refactor\n- Command:\n- Result:\n";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const storyTemplate = `---
|
|
2
|
+
status: draft
|
|
3
|
+
evidence: .speckit/evidence/{{slug}}-tdd-evidence.md
|
|
4
|
+
context: pending
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Story: {{title}}
|
|
8
|
+
|
|
9
|
+
## Intent
|
|
10
|
+
{{intent}}
|
|
11
|
+
|
|
12
|
+
## Acceptance Criteria
|
|
13
|
+
- Given ...
|
|
14
|
+
- When ...
|
|
15
|
+
- Then ...
|
|
16
|
+
|
|
17
|
+
## TDD Checklist
|
|
18
|
+
- [ ] Test targets identified
|
|
19
|
+
- [ ] Red evidence recorded
|
|
20
|
+
- [ ] Green evidence recorded
|
|
21
|
+
- [ ] Refactor validation recorded
|
|
22
|
+
|
|
23
|
+
## Notes
|
|
24
|
+
- Risks:
|
|
25
|
+
- Dependencies:
|
|
26
|
+
|
|
27
|
+
## Spec Anti-Mistake Checklist
|
|
28
|
+
- Reuse existing project patterns before adding new files.
|
|
29
|
+
- Verify file locations before editing.
|
|
30
|
+
- Do not introduce new libraries without explicit need.
|
|
31
|
+
- Preserve existing behavior unless an acceptance criterion requires change.
|
|
32
|
+
- Capture previous-story learnings if this continues prior work.
|
|
33
|
+
`;
|
|
34
|
+
export const tddEvidenceTemplate = `---
|
|
35
|
+
status: missing
|
|
36
|
+
story: {{story}}
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
# TDD Evidence: {{story}}
|
|
40
|
+
|
|
41
|
+
## Test Intent
|
|
42
|
+
|
|
43
|
+
## Red
|
|
44
|
+
- Command:
|
|
45
|
+
- Result:
|
|
46
|
+
|
|
47
|
+
## Green
|
|
48
|
+
- Command:
|
|
49
|
+
- Result:
|
|
50
|
+
|
|
51
|
+
## Refactor
|
|
52
|
+
- Command:
|
|
53
|
+
- Result:
|
|
54
|
+
`;
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
Speckit MVP is implemented and pushed to `git@github.com:trieungoctam/speckit.git` on `main`.
|
|
6
6
|
|
|
7
|
-
Current package target: `@trieungoctam/speckit@0.
|
|
7
|
+
Current package target: `@trieungoctam/speckit@0.3.0`.
|
|
8
8
|
|
|
9
|
-
The CLI is npx-ready, generates Agile + TDD rules, creates workflow artifacts, supports five IDE adapters, wraps Beads Viewer safely, includes an enterprise harness, and has automated tests plus CI.
|
|
9
|
+
The CLI is npx-ready, generates Agile + TDD rules, creates workflow artifacts, supports five IDE adapters, wraps Beads Viewer safely, includes an enterprise harness, and has automated prompt/readiness/session tests plus CI.
|
|
10
10
|
|
|
11
11
|
## Milestones
|
|
12
12
|
|
|
@@ -14,18 +14,20 @@ The CLI is npx-ready, generates Agile + TDD rules, creates workflow artifacts, s
|
|
|
14
14
|
| --- | --- | --- |
|
|
15
15
|
| Product contract | Complete | Contract, workflow model, and command surface documented. |
|
|
16
16
|
| CLI scaffold | Complete | `bin/speckit`, TypeScript build, command router, managed file writer. |
|
|
17
|
-
| Workflow engine | Complete | `start`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `run`, `review`, and `close` generate linked artifacts. |
|
|
17
|
+
| Workflow engine | Complete | `start`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `ready`, `run`, `review`, and `close` generate linked artifacts. |
|
|
18
|
+
| Long session manager | Complete | `memory refresh` plus `session start/checkpoint/compact/resume/status` preserve agent continuity outside chat history. |
|
|
18
19
|
| IDE adapters | Complete | Claude Code, Codex, Antigravity, OpenCode, Cursor. |
|
|
19
|
-
| Beads integration | MVP Complete | `next`
|
|
20
|
+
| Beads integration | MVP Complete | `next` and `graph triage/plan/insights` wrap BV robot mode; `sync` exports story metadata JSONL. |
|
|
21
|
+
| Sprint automation | MVP Complete | `sprint plan` and `sprint next` select work from synced stories. |
|
|
20
22
|
| Enterprise harness | MVP Complete | `init --enterprise` creates flow, tool-policy, and prompt harness files; `doctor --deep` verifies them. |
|
|
23
|
+
| Curated skill catalog | Complete | Speckit now generates focused phase skills, a schema, delegation statuses, and task hydration/sync-back guidance. |
|
|
21
24
|
| Validation | Complete | Build and `node:test` suite pass locally with flow contract gates. |
|
|
22
25
|
| GitHub publish | Complete | Initial code pushed to `trieungoctam/speckit` at commit `7e5c582`; status docs follow-up in progress. |
|
|
23
26
|
| npm package readiness | Ready | Package scoped as `@trieungoctam/speckit`; `npm pack --dry-run` passes. |
|
|
24
27
|
|
|
25
28
|
## Next Roadmap
|
|
26
29
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- Add graph commands: `graph-plan`, `insights`, and `drift`.
|
|
30
|
+
- Add `review --deep` with blind, edge-case, and acceptance audit prompts.
|
|
31
|
+
- Add graph drift and history correlation commands.
|
|
30
32
|
- Add GitHub trusted publishing for npm releases.
|
|
31
33
|
- Add snapshot tests for full adapter file contents.
|
package/docs/product-contract.md
CHANGED
|
@@ -5,7 +5,10 @@ Speckit owns the workflow contract for enterprise Agile + TDD development with a
|
|
|
5
5
|
## Speckit Owns
|
|
6
6
|
|
|
7
7
|
- The `.speckit/` source of truth: config, rules, workflows, templates, generated artifacts.
|
|
8
|
-
- The command surface: `init`, `doctor`, `start`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `next`, `run`, `review`, `close`.
|
|
8
|
+
- The command surface: `init`, `doctor`, `start`, `memory`, `session`, `shape`, `plan`, `context`, `quick`, `sync`, `triage`, `sprint`, `graph`, `next`, `ready`, `run`, `review`, `close`.
|
|
9
|
+
- The skill catalog and super-agent routing contract for phase-specific agent behavior.
|
|
10
|
+
- IDE-specific initialization that installs the shared Speckit runtime plus only the selected IDE adapter when `--ide <name>` is provided.
|
|
11
|
+
- The long-session contract: project memory, active session state, checkpoints, compaction summaries, and resume handoffs.
|
|
9
12
|
- The TDD gate: code stories require red, green, and refactor evidence.
|
|
10
13
|
- The adapter compiler for Claude Code, Codex, Antigravity, OpenCode, and Cursor.
|
|
11
14
|
- The safety policy for destructive commands, secrets, production access, and review readiness.
|
|
@@ -15,13 +18,13 @@ Speckit owns the workflow contract for enterprise Agile + TDD development with a
|
|
|
15
18
|
- Implementation to the selected IDE and agent runtime.
|
|
16
19
|
- Product lifecycle, story readiness, and quality gates to Speckit-native phases.
|
|
17
20
|
- Execution orchestration to Speckit-native plan/run/test/review flows.
|
|
18
|
-
- Task graph prioritization to beads and Beads Viewer robot commands.
|
|
21
|
+
- Task graph prioritization to beads and Beads Viewer robot commands, with local JSON fallback when `bv` is unavailable.
|
|
19
22
|
- Git, tests, CI, and deployment to project-local tooling.
|
|
20
23
|
|
|
21
24
|
## State Model
|
|
22
25
|
|
|
23
26
|
```text
|
|
24
|
-
intake -> session -> shaped -> planned -> context-ready -> synced -> triaged -> tests-red -> running -> tests-green -> refactor -> review-ready -> closed
|
|
27
|
+
intake -> session -> memory-ready -> shaped -> planned -> sprint-ready -> context-ready -> synced -> graph-triaged -> ready-for-dev -> tests-red -> checkpointed -> running -> tests-green -> refactor -> compacted -> review-ready -> closed
|
|
25
28
|
```
|
|
26
29
|
|
|
27
|
-
Implementation starts only after
|
|
30
|
+
Implementation starts only after `speckit ready <story>` passes. Review starts only after test evidence exists and the active session has a current checkpoint.
|
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# Project Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0 - 2026-05-10
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Added `speckit memory refresh` for durable project context, decisions, and lessons.
|
|
8
|
+
- Added `speckit session start`, `checkpoint`, `compact`, `resume`, and `status`.
|
|
9
|
+
- Added `speckit sprint plan` and `speckit sprint next` from synced stories.
|
|
10
|
+
- Added `speckit graph triage`, `graph plan`, and `graph insights` with Beads Viewer robot mode and local JSON fallback.
|
|
11
|
+
- Added `.speckit/agents/super-agent.md` as the portable orchestration router.
|
|
12
|
+
- Added `.speckit/skills/catalog.md` plus a curated Speckit skill set for shape, research, plan, context, graph, session, TDD, test, debug, review, docs, and ship phases.
|
|
13
|
+
- Added `.speckit/skills/schema.json` to define the portable skill contract and delegation statuses.
|
|
14
|
+
- Added long-session prompt requirements for project memory, active session state, checkpoints, and compaction summaries.
|
|
15
|
+
- Added automatic `.beads/beads.jsonl` mirror generation so Beads Viewer robot commands can run without missing-project errors.
|
|
16
|
+
- Standard `speckit init --ide <name>` now installs the shared Speckit runtime, super-agent, and skill catalog for the selected IDE.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Enterprise flow now includes memory, sprint planning, graph triage, readiness, checkpoint, and compaction phases.
|
|
21
|
+
- Enterprise adapters now route through the Speckit super agent and smallest matching skill before execution.
|
|
22
|
+
- Super-agent routing now includes delegation status, task hydration, and sync-back contracts adapted from long-session orchestration patterns.
|
|
23
|
+
- IDE adapters now instruct agents to checkpoint red-green-refactor boundaries and compact before handoff.
|
|
24
|
+
- `speckit graph triage|plan|insights` now prepares the Beads Viewer mirror before invoking `bv --robot-*` from the project root.
|
|
25
|
+
- Selected-IDE init now avoids unrelated IDE adapters while still installing shared runtime files.
|
|
26
|
+
|
|
27
|
+
### Quality
|
|
28
|
+
|
|
29
|
+
- Added workflow tests for memory/session state, sprint planning, and graph fallback.
|
|
30
|
+
- Expanded prompt quality tests for project memory, active session, checkpoint, and compaction.
|
|
31
|
+
- Added init and flow contract coverage for the curated skill catalog.
|
|
32
|
+
|
|
33
|
+
## 0.2.2 - 2026-05-10
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Added `speckit ready <story>` readiness gate.
|
|
38
|
+
- Added status frontmatter to generated stories, evidence files, and current context.
|
|
39
|
+
- Added `.speckit/context/subagent-handoff.md` generation from story context.
|
|
40
|
+
- Added anti-mistake checklist sections to story and context artifacts.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- `speckit run <story>` now refuses blocked stories until readiness checks pass.
|
|
45
|
+
- Prompt contracts now require readiness status, fresh context, and subagent handoff.
|
|
46
|
+
|
|
47
|
+
### Quality
|
|
48
|
+
|
|
49
|
+
- Added readiness and blocked-run tests.
|
|
50
|
+
- Expanded prompt quality tests for readiness and subagent handoff.
|
|
51
|
+
- `npm test` passes with 26 tests.
|
|
52
|
+
|
|
53
|
+
## 0.2.1 - 2026-05-10
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- Strengthened generated prompts across Claude Code, Codex, Antigravity, OpenCode, Cursor, and the enterprise run prompt.
|
|
58
|
+
- Made prompt contracts explicitly require current context, acceptance criteria, session handoff, red-green-refactor evidence, and robot-safe graph commands.
|
|
59
|
+
|
|
60
|
+
### Quality
|
|
61
|
+
|
|
62
|
+
- Added prompt quality tests covering enterprise prompts, IDE adapter prompts, and tracked generated prompt files.
|
|
63
|
+
- `npm test` passes with 24 tests.
|
|
64
|
+
|
|
3
65
|
## 0.2.0 - 2026-05-10
|
|
4
66
|
|
|
5
67
|
### Added
|
|
@@ -16,6 +78,10 @@
|
|
|
16
78
|
- `npm pack --dry-run` passes.
|
|
17
79
|
- Full enterprise temp flow passes: `init --enterprise -> start -> quick -> context -> sync -> triage -> close -> doctor --deep`.
|
|
18
80
|
|
|
81
|
+
### Published
|
|
82
|
+
|
|
83
|
+
- Published `@trieungoctam/speckit@0.2.0` to npm with `latest` dist-tag.
|
|
84
|
+
|
|
19
85
|
## 2026-05-10
|
|
20
86
|
|
|
21
87
|
### Changed
|
|
@@ -16,5 +16,5 @@ Before publishing Speckit:
|
|
|
16
16
|
- [x] README quickstart is accurate.
|
|
17
17
|
- [x] No secrets, local credentials, or generated private data are included.
|
|
18
18
|
- [x] Initial code pushed to `git@github.com:trieungoctam/speckit.git`.
|
|
19
|
-
- [
|
|
19
|
+
- [x] npm package published.
|
|
20
20
|
- [ ] GitHub trusted publishing configured for npm releases.
|