empirical-sdd 0.20.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.
@@ -0,0 +1,3 @@
1
+ import type { IntegrationReport } from "./types.js";
2
+ export declare function installProjectIntegrations(root: string): Promise<IntegrationReport>;
3
+ export declare function installGlobalAgentSkills(homeRoot?: string): Promise<IntegrationReport>;
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function createMcpServer(defaultRoot?: string): McpServer;
3
+ export declare function runMcpServer(defaultRoot?: string): Promise<void>;
@@ -0,0 +1,12 @@
1
+ import { type ProjectStore } from "./storage.js";
2
+ import type { ArchiveReport, CapabilityDelta, CapabilitySummary, DeltaValidationReport } from "./types.js";
3
+ export interface CapabilityArchivePlan {
4
+ report: Omit<ArchiveReport, "feature" | "converged">;
5
+ commit: () => Promise<() => Promise<void>>;
6
+ }
7
+ export declare function loadCapabilityDeltas(store: ProjectStore, feature: string): Promise<CapabilityDelta[]>;
8
+ export declare function parseCapabilityDelta(capability: string, markdown: string, source?: string): CapabilityDelta;
9
+ export declare function validateFeatureDeltas(store: ProjectStore, feature: string): Promise<DeltaValidationReport>;
10
+ export declare function capabilityDeltaDigest(store: ProjectStore, feature: string): Promise<string | null>;
11
+ export declare function planCapabilityArchive(store: ProjectStore, feature: string): Promise<CapabilityArchivePlan>;
12
+ export declare function listCapabilities(store: ProjectStore): Promise<CapabilitySummary[]>;
@@ -0,0 +1,74 @@
1
+ import { type ProjectPolicy, type ProjectConfig, type WorkflowState } from "./types.js";
2
+ export declare class ProjectStore {
3
+ readonly root: string;
4
+ readonly feature: string | null;
5
+ constructor(root: string, feature?: string | null);
6
+ get directory(): string;
7
+ get configPath(): string;
8
+ get policyPath(): string;
9
+ get stateDirectory(): string;
10
+ get statePath(): string;
11
+ get eventsDirectory(): string;
12
+ get capabilitiesDirectory(): string;
13
+ forFeature(feature: string): ProjectStore;
14
+ capabilityDirectory(capability: string): string;
15
+ capabilitySpecPath(capability: string): string;
16
+ specDirectory(feature: string): string;
17
+ specPath(feature: string): string;
18
+ evidencePath(feature: string): string;
19
+ deltaDirectory(feature: string): string;
20
+ exists(): Promise<boolean>;
21
+ ensureLayout(): Promise<void>;
22
+ loadPolicy(): Promise<ProjectPolicy>;
23
+ writePolicy(policy: ProjectPolicy): Promise<void>;
24
+ loadConfig(): Promise<ProjectConfig>;
25
+ loadState(recover?: boolean): Promise<WorkflowState>;
26
+ writeConfig(config: ProjectConfig): Promise<void>;
27
+ writeInitial(config: ProjectConfig): Promise<void>;
28
+ writeInitialFeature(state: WorkflowState, actor?: string, summary?: string): Promise<void>;
29
+ configure(update: Partial<ProjectConfig>): Promise<ProjectConfig>;
30
+ activeFeature(recover?: boolean): Promise<string | null>;
31
+ listFeatureIds(): Promise<string[]>;
32
+ transition(expectedRevision: number, actor: string, summary: string, mutate: (state: WorkflowState) => WorkflowState): Promise<WorkflowState>;
33
+ transaction<T>(prepare: (current: WorkflowState) => Promise<{
34
+ actor: string;
35
+ summary: string;
36
+ state: WorkflowState;
37
+ value: T;
38
+ validate?: () => Promise<void>;
39
+ effect?: () => Promise<() => Promise<void>>;
40
+ }>): Promise<{
41
+ state: WorkflowState;
42
+ value: T;
43
+ }>;
44
+ migrateSchema(): Promise<Record<string, unknown>>;
45
+ writeSpec(feature: string, contents: string): Promise<void>;
46
+ readSpec(feature: string): Promise<string>;
47
+ writeEvidence(feature: string, evidence: unknown): Promise<void>;
48
+ readEvidence<T>(feature: string): Promise<T[]>;
49
+ listCapabilityNames(): Promise<string[]>;
50
+ readCapability(capability: string): Promise<string | null>;
51
+ writeCapability(capability: string, contents: string): Promise<void>;
52
+ removeCapability(capability: string): Promise<void>;
53
+ withResourceLock<T>(resource: "specs" | "capabilities" | "policy", operation: () => Promise<T>): Promise<T>;
54
+ assertCurrentSchemaReadOnly(): Promise<void>;
55
+ private eventPath;
56
+ private latestEvent;
57
+ private commitInitialState;
58
+ private withLock;
59
+ private requireFeature;
60
+ private assertCapabilityPathSafe;
61
+ assertFeaturePathSafe(feature: string, additional?: string[]): Promise<void>;
62
+ private assertProjectPathSafe;
63
+ private ensureProjectMetadata;
64
+ private ensureCurrentConfigSchema;
65
+ }
66
+ export declare function isRetryableLockOpenError(error: unknown, platform?: NodeJS.Platform): boolean;
67
+ export declare function discoverProject(start: string): Promise<ProjectStore>;
68
+ export declare function writeJsonAtomic(path: string, value: unknown): Promise<void>;
69
+ export declare function writeTextAtomic(path: string, contents: string): Promise<void>;
70
+ export declare function isFile(path: string): Promise<boolean>;
71
+ export declare function isSymbolicLink(path: string): Promise<boolean>;
72
+ export declare function readJson<T>(path: string, code?: string): Promise<T>;
73
+ export declare function assertFeatureId(feature: string): void;
74
+ export declare function assertCapabilityId(capability: string): void;
@@ -0,0 +1,283 @@
1
+ export declare const SCHEMA_VERSION: 4;
2
+ export declare const PRODUCT_VERSION = "0.20.0";
3
+ export declare const POLICY_SCHEMA_VERSION: 1;
4
+ export type Workflow = "fast" | "complex";
5
+ export type Profile = Workflow | "quick";
6
+ export type Phase = "idle" | "shape" | "specify" | "design" | "plan" | "implement" | "verify" | "review" | "archive" | "done";
7
+ export type WorkflowStatus = "idle" | "waiting" | "awaiting_human" | "blocked" | "done";
8
+ export type Outcome = "passed" | "failed" | "awaiting_human" | "blocked";
9
+ export type EvidenceKind = "test" | "browser" | "screenshot" | "review" | "human";
10
+ export type ChangeType = "feature" | "fix" | "chore";
11
+ export type IsolationMode = "ask" | "off";
12
+ export type ComplexDecisionMode = "required" | "off";
13
+ export interface IsolationConfig {
14
+ mode: IsolationMode;
15
+ baseBranch: string;
16
+ worktreePath: string;
17
+ branchPattern: string;
18
+ }
19
+ export interface DecisionConfig {
20
+ complexRecords: ComplexDecisionMode;
21
+ }
22
+ export interface ProjectConfig {
23
+ schemaVersion: typeof SCHEMA_VERSION;
24
+ profile: Profile;
25
+ maxRepairAttempts: number;
26
+ evidence: {
27
+ required: boolean;
28
+ browserForUi: boolean;
29
+ screenshotForUi: boolean;
30
+ codeReview: boolean;
31
+ };
32
+ isolation: IsolationConfig;
33
+ decisions: DecisionConfig;
34
+ setupComplete: boolean;
35
+ legacySource: "ai" | null;
36
+ }
37
+ export interface ProjectConfigurationInput {
38
+ isolation?: Partial<IsolationConfig>;
39
+ decisions?: Partial<DecisionConfig>;
40
+ setupComplete?: boolean;
41
+ }
42
+ export interface WorkflowState {
43
+ schemaVersion: typeof SCHEMA_VERSION;
44
+ revision: number;
45
+ activeFeature: string | null;
46
+ request: string | null;
47
+ profile: Profile;
48
+ phase: Phase;
49
+ status: WorkflowStatus;
50
+ repairAttempts: number;
51
+ message: string | null;
52
+ implementationActor: string | null;
53
+ specDigest: string | null;
54
+ capabilityArchiveRequired: boolean;
55
+ capabilityDeltaDigest: string | null;
56
+ evidence: Evidence[];
57
+ updatedAt: string;
58
+ }
59
+ export interface ProjectPolicy {
60
+ schemaVersion: typeof POLICY_SCHEMA_VERSION;
61
+ context: string[];
62
+ phases: Partial<Record<Phase, string[]>>;
63
+ }
64
+ export interface Criterion {
65
+ id: string;
66
+ text: string;
67
+ ui: boolean;
68
+ checked: boolean;
69
+ }
70
+ export interface Evidence {
71
+ criterionId: string;
72
+ kind: EvidenceKind;
73
+ passed: boolean;
74
+ summary: string;
75
+ artifact?: string;
76
+ }
77
+ export interface CompletionInput {
78
+ revision: number;
79
+ outcome: Outcome;
80
+ summary: string;
81
+ actor?: string;
82
+ evidence?: Evidence[];
83
+ }
84
+ export interface ActionRationale {
85
+ currentState: string;
86
+ nextAction: string;
87
+ reason: string;
88
+ requiredContext: string[];
89
+ missingContext: string[];
90
+ gate: "proceed" | "stop";
91
+ }
92
+ export interface ActionPacket {
93
+ kind: "action";
94
+ protocol: "empirical-sdd";
95
+ schemaVersion: typeof SCHEMA_VERSION;
96
+ root: string;
97
+ feature: string | null;
98
+ request: string | null;
99
+ profile: Profile;
100
+ phase: Phase;
101
+ status: WorkflowStatus;
102
+ revision: number;
103
+ instructions: string;
104
+ rationale: ActionRationale;
105
+ acceptanceCriteria: Criterion[];
106
+ requiredEvidence: EvidenceKind[];
107
+ artifacts: string[];
108
+ projectContext: string[];
109
+ capabilityContext: string[];
110
+ completion: {
111
+ available: boolean;
112
+ mcpTool: "empirical_complete" | "empirical_archive";
113
+ cli: string;
114
+ requiredFields: string[];
115
+ };
116
+ }
117
+ export interface WorktreeProposal {
118
+ kind: "worktree_proposal";
119
+ protocol: "empirical-sdd";
120
+ schemaVersion: typeof SCHEMA_VERSION;
121
+ root: string;
122
+ request: string;
123
+ workflow: Workflow;
124
+ changeType: ChangeType;
125
+ feature: string;
126
+ branch: string;
127
+ path: string;
128
+ base: string;
129
+ baseCommit: string;
130
+ activeFeature: string;
131
+ approvalToken: string;
132
+ command: string[];
133
+ requiresApproval: true;
134
+ }
135
+ export interface WorktreeCreateInput {
136
+ request: string;
137
+ workflow: Workflow;
138
+ changeType?: ChangeType;
139
+ feature?: string;
140
+ branch?: string;
141
+ path?: string;
142
+ base?: string;
143
+ baseCommit: string;
144
+ activeFeature: string;
145
+ approvalToken: string;
146
+ approved: true;
147
+ }
148
+ export interface WorktreeHandoff {
149
+ kind: "worktree_handoff";
150
+ protocol: "empirical-sdd";
151
+ schemaVersion: typeof SCHEMA_VERSION;
152
+ root: string;
153
+ path: string;
154
+ branch: string;
155
+ base: string;
156
+ baseCommit: string;
157
+ feature: string;
158
+ revision: number;
159
+ workflow: Workflow;
160
+ resume: string;
161
+ action: ActionPacket;
162
+ }
163
+ export type FeatureStartResult = ActionPacket | WorktreeProposal;
164
+ export interface DecisionSummary {
165
+ id: string;
166
+ title: string;
167
+ status: "Accepted" | "Superseded";
168
+ chosenApproach: string;
169
+ supersedes: string[];
170
+ supersededBy: string | null;
171
+ }
172
+ export interface DecisionValidationReport {
173
+ valid: boolean;
174
+ decisions: DecisionSummary[];
175
+ issues: string[];
176
+ }
177
+ export interface ExplainReport {
178
+ protocol: "empirical-sdd";
179
+ schemaVersion: typeof SCHEMA_VERSION;
180
+ root: string;
181
+ feature: string | null;
182
+ phase: Phase;
183
+ status: WorkflowStatus;
184
+ revision: number;
185
+ rationale: ActionRationale;
186
+ decisions: DecisionSummary[];
187
+ }
188
+ export interface ExplorationPacket {
189
+ protocol: "empirical-sdd";
190
+ schemaVersion: typeof SCHEMA_VERSION;
191
+ root: string;
192
+ problem: string;
193
+ instructions: string[];
194
+ questions: string[];
195
+ projectContext: string[];
196
+ capabilityContext: string[];
197
+ next: {
198
+ fast: string;
199
+ complex: string;
200
+ };
201
+ }
202
+ export type DeltaOperation = "added" | "modified" | "removed";
203
+ export interface RequirementDelta {
204
+ operation: DeltaOperation;
205
+ name: string;
206
+ contents: string;
207
+ }
208
+ export interface CapabilityDelta {
209
+ capability: string;
210
+ purpose: string | null;
211
+ requirements: RequirementDelta[];
212
+ source: string;
213
+ }
214
+ export interface CapabilitySummary {
215
+ name: string;
216
+ path: string;
217
+ requirements: number;
218
+ }
219
+ export interface DeltaValidationReport {
220
+ valid: boolean;
221
+ capabilities: string[];
222
+ operations: number;
223
+ issues: string[];
224
+ digest: string | null;
225
+ }
226
+ export interface ArchiveReport {
227
+ feature: string;
228
+ capabilities: string[];
229
+ added: number;
230
+ modified: number;
231
+ removed: number;
232
+ converged: boolean;
233
+ }
234
+ export interface ArchiveResult {
235
+ action: ActionPacket;
236
+ report: ArchiveReport;
237
+ }
238
+ export interface TransitionEvent {
239
+ schemaVersion: typeof SCHEMA_VERSION;
240
+ revision: number;
241
+ previousRevision: number;
242
+ actor: string;
243
+ summary: string;
244
+ createdAt: string;
245
+ state: WorkflowState;
246
+ }
247
+ export interface IntegrationReport {
248
+ scope: "project" | "global";
249
+ created: string[];
250
+ updated: string[];
251
+ preserved: string[];
252
+ entrypoints: AgentEntrypointReport[];
253
+ }
254
+ export type AgentIntegrationId = "codex" | "claude" | "cursor" | "gemini" | "windsurf";
255
+ export interface AgentEntrypointReport {
256
+ id: AgentIntegrationId;
257
+ agent: string;
258
+ kind: "skill" | "slash-command";
259
+ artifactRoot: string;
260
+ invocations: string[];
261
+ reload: string;
262
+ }
263
+ export interface InitOptions extends ProjectConfigurationInput {
264
+ profile?: Workflow;
265
+ integrations?: boolean;
266
+ }
267
+ export interface StartOptions {
268
+ profile?: Workflow;
269
+ id?: string;
270
+ }
271
+ export interface FeatureStartOptions {
272
+ id?: string;
273
+ }
274
+ export interface AdoptionOptions extends ProjectConfigurationInput {
275
+ profile?: Workflow;
276
+ integrations?: boolean;
277
+ }
278
+ export interface ValidationReport {
279
+ valid: boolean;
280
+ phase: Phase;
281
+ criteria: number;
282
+ missing: string[];
283
+ }
@@ -0,0 +1,13 @@
1
+ import { type ChangeType, type IsolationConfig, type Workflow, type WorktreeProposal } from "./types.js";
2
+ export interface WorktreeOverrides {
3
+ changeType?: ChangeType;
4
+ feature?: string;
5
+ branch?: string;
6
+ path?: string;
7
+ base?: string;
8
+ }
9
+ export declare function inferChangeType(request: string): ChangeType;
10
+ export declare function featureSlug(request: string): string;
11
+ export declare function proposeWorktree(root: string, request: string, workflow: Workflow, activeFeature: string, config: IsolationConfig, overrides?: WorktreeOverrides): WorktreeProposal;
12
+ export declare function createGitWorktree(proposal: WorktreeProposal): Promise<void>;
13
+ export declare function detectBase(root: string): string;
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "empirical-sdd",
3
+ "version": "0.20.0",
4
+ "description": "Agent-neutral, resumable spec-driven development for every terminal-capable coding agent",
5
+ "type": "module",
6
+ "bin": {
7
+ "empirical": "dist/cli.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "engines": {
21
+ "node": ">=20"
22
+ },
23
+ "scripts": {
24
+ "build": "bun run scripts/build.ts",
25
+ "check": "tsc -p tsconfig.json --noEmit",
26
+ "test": "bun test",
27
+ "test:dist": "bun run build && bun run scripts/smoke-mcp.ts",
28
+ "prepack": "bun run build",
29
+ "test:package": "bun run scripts/test-package.ts",
30
+ "ci": "bun run check && bun test && bun run test:dist && bun run test:package"
31
+ },
32
+ "keywords": [
33
+ "agents",
34
+ "mcp",
35
+ "sdd",
36
+ "spec-driven-development",
37
+ "codex",
38
+ "claude"
39
+ ],
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/MateoCerquetella/empirical-sdd.git"
44
+ },
45
+ "bugs": {
46
+ "url": "https://github.com/MateoCerquetella/empirical-sdd/issues"
47
+ },
48
+ "homepage": "https://github.com/MateoCerquetella/empirical-sdd#readme",
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "devDependencies": {
53
+ "@modelcontextprotocol/sdk": "^1.30.0",
54
+ "@types/node": "^26.1.2",
55
+ "typescript": "^7.0.2",
56
+ "zod": "^4.4.3"
57
+ }
58
+ }