@applica-software-guru/sdd-core 1.0.0 → 1.0.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.
@@ -0,0 +1,3 @@
1
+ export declare const DEFAULT_AGENTS: Record<string, string>;
2
+ export declare function resolveAgentCommand(name: string, configAgents?: Record<string, string>): string | undefined;
3
+ //# sourceMappingURL=agent-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-defaults.d.ts","sourceRoot":"","sources":["../../src/agent/agent-defaults.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIjD,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,MAAM,GAAG,SAAS,CAEpB"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_AGENTS = void 0;
4
+ exports.resolveAgentCommand = resolveAgentCommand;
5
+ exports.DEFAULT_AGENTS = {
6
+ claude: 'claude -p "$(cat $PROMPT_FILE)" --dangerously-skip-permissions --verbose',
7
+ codex: 'codex -q "$(cat $PROMPT_FILE)"',
8
+ opencode: 'opencode -p "$(cat $PROMPT_FILE)"',
9
+ };
10
+ function resolveAgentCommand(name, configAgents) {
11
+ return configAgents?.[name] ?? exports.DEFAULT_AGENTS[name];
12
+ }
13
+ //# sourceMappingURL=agent-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-defaults.js","sourceRoot":"","sources":["../../src/agent/agent-defaults.ts"],"names":[],"mappings":";;;AAMA,kDAKC;AAXY,QAAA,cAAc,GAA2B;IACpD,MAAM,EAAE,0EAA0E;IAClF,KAAK,EAAE,gCAAgC;IACvC,QAAQ,EAAE,mCAAmC;CAC9C,CAAC;AAEF,SAAgB,mBAAmB,CACjC,IAAY,EACZ,YAAqC;IAErC,OAAO,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,sBAAc,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface AgentRunnerOptions {
2
+ root: string;
3
+ prompt: string;
4
+ agent: string;
5
+ agents?: Record<string, string>;
6
+ onOutput?: (data: string) => void;
7
+ }
8
+ export declare function runAgent(options: AgentRunnerOptions): Promise<number>;
9
+ //# sourceMappingURL=agent-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../../src/agent/agent-runner.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsC3E"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runAgent = runAgent;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const promises_1 = require("node:fs/promises");
6
+ const node_os_1 = require("node:os");
7
+ const node_path_1 = require("node:path");
8
+ const node_crypto_1 = require("node:crypto");
9
+ const agent_defaults_js_1 = require("./agent-defaults.js");
10
+ async function runAgent(options) {
11
+ const { root, prompt, agent, agents, onOutput } = options;
12
+ const template = (0, agent_defaults_js_1.resolveAgentCommand)(agent, agents);
13
+ if (!template) {
14
+ throw new Error(`Unknown agent "${agent}". Available: ${Object.keys(agents ?? {}).join(', ') || 'claude, codex, opencode'}`);
15
+ }
16
+ // Write prompt to temp file (too large for CLI arg)
17
+ const tmpFile = (0, node_path_1.join)((0, node_os_1.tmpdir)(), `sdd-prompt-${(0, node_crypto_1.randomBytes)(6).toString('hex')}.md`);
18
+ await (0, promises_1.writeFile)(tmpFile, prompt, 'utf-8');
19
+ // Replace $PROMPT_FILE with the temp file path in the command template
20
+ const command = template.replace(/\$PROMPT_FILE/g, tmpFile);
21
+ try {
22
+ const exitCode = await new Promise((resolve, reject) => {
23
+ const child = (0, node_child_process_1.spawn)(command, {
24
+ cwd: root,
25
+ shell: true,
26
+ stdio: onOutput ? ['inherit', 'pipe', 'pipe'] : 'inherit',
27
+ });
28
+ if (onOutput && child.stdout) {
29
+ child.stdout.on('data', (data) => onOutput(data.toString()));
30
+ }
31
+ if (onOutput && child.stderr) {
32
+ child.stderr.on('data', (data) => onOutput(data.toString()));
33
+ }
34
+ child.on('error', reject);
35
+ child.on('close', (code) => resolve(code ?? 1));
36
+ });
37
+ return exitCode;
38
+ }
39
+ finally {
40
+ await (0, promises_1.unlink)(tmpFile).catch(() => { });
41
+ }
42
+ }
43
+ //# sourceMappingURL=agent-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../../src/agent/agent-runner.ts"],"names":[],"mappings":";;AAeA,4BAsCC;AArDD,2DAA2C;AAC3C,+CAAqD;AACrD,qCAAiC;AACjC,yCAAiC;AACjC,6CAA0C;AAC1C,2DAA0D;AAUnD,KAAK,UAAU,QAAQ,CAAC,OAA2B;IACxD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE1D,MAAM,QAAQ,GAAG,IAAA,uCAAmB,EAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,iBAAiB,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,yBAAyB,EAAE,CAAC,CAAC;IAC/H,CAAC;IAED,oDAAoD;IACpD,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,IAAA,gBAAM,GAAE,EAAE,cAAc,IAAA,yBAAW,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClF,MAAM,IAAA,oBAAS,EAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAE1C,uEAAuE;IACvE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7D,MAAM,KAAK,GAAG,IAAA,0BAAK,EAAC,OAAO,EAAE;gBAC3B,GAAG,EAAE,IAAI;gBACT,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;aAC1D,CAAC,CAAC;YAEH,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACvE,CAAC;YACD,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACvE,CAAC;YAED,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,MAAM,IAAA,iBAAM,EAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,5 +2,8 @@ export { SDD } from './sdd.js';
2
2
  export type { StoryFrontmatter, StoryFile, PendingItem, Delta, DeltaFile, ValidationResult, ValidationIssue, StoryStatus, StoryFileStatus, SDDConfig, ChangeRequest, ChangeRequestFrontmatter, ChangeRequestStatus, Bug, BugFrontmatter, BugStatus, } from './types.js';
3
3
  export { SDDError, LockFileNotFoundError, ParseError, ProjectNotInitializedError } from './errors.js';
4
4
  export type { ProjectInfo } from './scaffold/templates.js';
5
- export { isSDDProject, readConfig } from './config/config-manager.js';
5
+ export { isSDDProject, readConfig, writeConfig } from './config/config-manager.js';
6
+ export { runAgent } from './agent/agent-runner.js';
7
+ export type { AgentRunnerOptions } from './agent/agent-runner.js';
8
+ export { DEFAULT_AGENTS, resolveAgentCommand } from './agent/agent-defaults.js';
6
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,eAAe,EACf,SAAS,EACT,aAAa,EACb,wBAAwB,EACxB,mBAAmB,EACnB,GAAG,EACH,cAAc,EACd,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACtG,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,YAAY,EACV,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,eAAe,EACf,SAAS,EACT,aAAa,EACb,wBAAwB,EACxB,mBAAmB,EACnB,GAAG,EACH,cAAc,EACd,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,UAAU,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACtG,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readConfig = exports.isSDDProject = exports.ProjectNotInitializedError = exports.ParseError = exports.LockFileNotFoundError = exports.SDDError = exports.SDD = void 0;
3
+ exports.resolveAgentCommand = exports.DEFAULT_AGENTS = exports.runAgent = exports.writeConfig = exports.readConfig = exports.isSDDProject = exports.ProjectNotInitializedError = exports.ParseError = exports.LockFileNotFoundError = exports.SDDError = exports.SDD = void 0;
4
4
  var sdd_js_1 = require("./sdd.js");
5
5
  Object.defineProperty(exports, "SDD", { enumerable: true, get: function () { return sdd_js_1.SDD; } });
6
6
  var errors_js_1 = require("./errors.js");
@@ -11,4 +11,10 @@ Object.defineProperty(exports, "ProjectNotInitializedError", { enumerable: true,
11
11
  var config_manager_js_1 = require("./config/config-manager.js");
12
12
  Object.defineProperty(exports, "isSDDProject", { enumerable: true, get: function () { return config_manager_js_1.isSDDProject; } });
13
13
  Object.defineProperty(exports, "readConfig", { enumerable: true, get: function () { return config_manager_js_1.readConfig; } });
14
+ Object.defineProperty(exports, "writeConfig", { enumerable: true, get: function () { return config_manager_js_1.writeConfig; } });
15
+ var agent_runner_js_1 = require("./agent/agent-runner.js");
16
+ Object.defineProperty(exports, "runAgent", { enumerable: true, get: function () { return agent_runner_js_1.runAgent; } });
17
+ var agent_defaults_js_1 = require("./agent/agent-defaults.js");
18
+ Object.defineProperty(exports, "DEFAULT_AGENTS", { enumerable: true, get: function () { return agent_defaults_js_1.DEFAULT_AGENTS; } });
19
+ Object.defineProperty(exports, "resolveAgentCommand", { enumerable: true, get: function () { return agent_defaults_js_1.resolveAgentCommand; } });
14
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA+B;AAAtB,6FAAA,GAAG,OAAA;AAmBZ,yCAAsG;AAA7F,qGAAA,QAAQ,OAAA;AAAE,kHAAA,qBAAqB,OAAA;AAAE,uGAAA,UAAU,OAAA;AAAE,uHAAA,0BAA0B,OAAA;AAEhF,gEAAsE;AAA7D,iHAAA,YAAY,OAAA;AAAE,+GAAA,UAAU,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA+B;AAAtB,6FAAA,GAAG,OAAA;AAmBZ,yCAAsG;AAA7F,qGAAA,QAAQ,OAAA;AAAE,kHAAA,qBAAqB,OAAA;AAAE,uGAAA,UAAU,OAAA;AAAE,uHAAA,0BAA0B,OAAA;AAEhF,gEAAmF;AAA1E,iHAAA,YAAY,OAAA;AAAE,+GAAA,UAAU,OAAA;AAAE,gHAAA,WAAW,OAAA;AAC9C,2DAAmD;AAA1C,2GAAA,QAAQ,OAAA;AAEjB,+DAAgF;AAAvE,mHAAA,cAAc,OAAA;AAAE,wHAAA,mBAAmB,OAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Bug, ChangeRequest, StoryFile } from '../types.js';
2
+ export declare function generateApplyPrompt(bugs: Bug[], changeRequests: ChangeRequest[], pendingFiles: StoryFile[], root: string): string | null;
3
+ //# sourceMappingURL=apply-prompt-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-prompt-generator.d.ts","sourceRoot":"","sources":["../../src/prompt/apply-prompt-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjE,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,GAAG,EAAE,EACX,cAAc,EAAE,aAAa,EAAE,EAC/B,YAAY,EAAE,SAAS,EAAE,EACzB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAyEf"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateApplyPrompt = generateApplyPrompt;
4
+ const git_js_1 = require("../git/git.js");
5
+ function generateApplyPrompt(bugs, changeRequests, pendingFiles, root) {
6
+ if (bugs.length === 0 && changeRequests.length === 0 && pendingFiles.length === 0) {
7
+ return null;
8
+ }
9
+ const sections = [];
10
+ sections.push('# SDD Apply\n\nThis project uses Story Driven Development. Complete the tasks below in order.');
11
+ // Bugs section
12
+ if (bugs.length > 0) {
13
+ const lines = [`## Open Bugs (${bugs.length})\n`];
14
+ for (const bug of bugs) {
15
+ lines.push(`### \`${bug.relativePath}\` — ${bug.frontmatter.title}\n`);
16
+ lines.push(bug.body.trim());
17
+ lines.push('');
18
+ }
19
+ sections.push(lines.join('\n'));
20
+ }
21
+ // Change Requests section
22
+ if (changeRequests.length > 0) {
23
+ const lines = [`## Pending Change Requests (${changeRequests.length})\n`];
24
+ for (const cr of changeRequests) {
25
+ lines.push(`### \`${cr.relativePath}\` — ${cr.frontmatter.title}\n`);
26
+ lines.push(cr.body.trim());
27
+ lines.push('');
28
+ }
29
+ sections.push(lines.join('\n'));
30
+ }
31
+ // Pending Files section
32
+ if (pendingFiles.length > 0) {
33
+ const lines = [`## Pending Files (${pendingFiles.length})\n`];
34
+ for (const f of pendingFiles) {
35
+ lines.push(`- \`${f.relativePath}\` — **${f.frontmatter.status}**`);
36
+ }
37
+ lines.push('');
38
+ lines.push('Read each file listed above before implementing.');
39
+ // Show git diff for changed files
40
+ const changed = pendingFiles.filter((f) => f.frontmatter.status === 'changed');
41
+ for (const f of changed) {
42
+ const diff = (0, git_js_1.getFileDiff)(root, f.relativePath);
43
+ if (diff) {
44
+ lines.push('');
45
+ lines.push(`### Changes in \`${f.relativePath}\`\n\n\`\`\`diff\n${diff}\n\`\`\``);
46
+ }
47
+ }
48
+ sections.push(lines.join('\n'));
49
+ }
50
+ // Instructions
51
+ const instructions = ['## Instructions\n'];
52
+ if (bugs.length > 0) {
53
+ instructions.push('1. Fix each open bug, then run `sdd mark-bug-resolved <file>` and commit');
54
+ }
55
+ if (changeRequests.length > 0) {
56
+ instructions.push(`${bugs.length > 0 ? '2' : '1'}. Apply each CR to the documentation, then run \`sdd mark-cr-applied <file>\` and commit`);
57
+ }
58
+ if (pendingFiles.length > 0) {
59
+ const step = (bugs.length > 0 ? 1 : 0) + (changeRequests.length > 0 ? 1 : 0) + 1;
60
+ instructions.push(`${step}. Implement each pending file, then run \`sdd mark-synced <file>\` and commit`);
61
+ }
62
+ const lastStep = (bugs.length > 0 ? 1 : 0) + (changeRequests.length > 0 ? 1 : 0) + (pendingFiles.length > 0 ? 1 : 0) + 1;
63
+ instructions.push(`${lastStep}. After each mark-* command, immediately commit: \`git add -A && git commit -m "sdd: <description>"\``);
64
+ sections.push(instructions.join('\n'));
65
+ return sections.join('\n\n');
66
+ }
67
+ //# sourceMappingURL=apply-prompt-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-prompt-generator.js","sourceRoot":"","sources":["../../src/prompt/apply-prompt-generator.ts"],"names":[],"mappings":"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"}
package/dist/sdd.d.ts CHANGED
@@ -10,6 +10,7 @@ export declare class SDD {
10
10
  status(): Promise<StoryStatus>;
11
11
  pending(): Promise<import('./types.js').StoryFile[]>;
12
12
  sync(): Promise<string>;
13
+ applyPrompt(): Promise<string | null>;
13
14
  validate(): Promise<ValidationResult>;
14
15
  markSynced(paths?: string[]): Promise<string[]>;
15
16
  changeRequests(): Promise<ChangeRequest[]>;
package/dist/sdd.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdd.d.ts","sourceRoot":"","sources":["../src/sdd.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAS/F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,qBAAa,GAAG;IACd,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IAI/B,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI3C,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC;IAK5B,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC;IAc9B,OAAO,IAAI,OAAO,CAAC,OAAO,YAAY,EAAE,SAAS,EAAE,CAAC;IAMpD,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAKvB,QAAQ,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAMrC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA6B/C,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAK1C,qBAAqB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAKjD,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBlD,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAKtB,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAK1B,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmB1D,OAAO,CAAC,iBAAiB;CAK1B"}
1
+ {"version":3,"file":"sdd.d.ts","sourceRoot":"","sources":["../src/sdd.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAU/F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,qBAAa,GAAG;IACd,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IAI/B,IAAI,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI3C,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC;IAK5B,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC;IAc9B,OAAO,IAAI,OAAO,CAAC,OAAO,YAAY,EAAE,SAAS,EAAE,CAAC;IAMpD,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAKvB,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAUrC,QAAQ,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAMrC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA6B/C,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAK1C,qBAAqB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAKjD,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBlD,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAKtB,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAK1B,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmB1D,OAAO,CAAC,iBAAiB;CAK1B"}
package/dist/sdd.js CHANGED
@@ -6,6 +6,7 @@ const node_path_1 = require("node:path");
6
6
  const errors_js_1 = require("./errors.js");
7
7
  const story_parser_js_1 = require("./parser/story-parser.js");
8
8
  const prompt_generator_js_1 = require("./prompt/prompt-generator.js");
9
+ const apply_prompt_generator_js_1 = require("./prompt/apply-prompt-generator.js");
9
10
  const validator_js_1 = require("./validate/validator.js");
10
11
  const init_js_1 = require("./scaffold/init.js");
11
12
  const config_manager_js_1 = require("./config/config-manager.js");
@@ -44,6 +45,15 @@ class SDD {
44
45
  const pending = await this.pending();
45
46
  return (0, prompt_generator_js_1.generatePrompt)(pending, this.root);
46
47
  }
48
+ async applyPrompt() {
49
+ this.ensureInitialized();
50
+ const [bugs, changeRequests, pendingFiles] = await Promise.all([
51
+ this.openBugs(),
52
+ this.pendingChangeRequests(),
53
+ this.pending(),
54
+ ]);
55
+ return (0, apply_prompt_generator_js_1.generateApplyPrompt)(bugs, changeRequests, pendingFiles, this.root);
56
+ }
47
57
  async validate() {
48
58
  this.ensureInitialized();
49
59
  const files = await (0, story_parser_js_1.parseAllStoryFiles)(this.root);
package/dist/sdd.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdd.js","sourceRoot":"","sources":["../src/sdd.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdd.js","sourceRoot":"","sources":["../src/sdd.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -49,6 +49,8 @@ export interface StoryStatus {
49
49
  export interface SDDConfig {
50
50
  description: string;
51
51
  'last-sync-commit'?: string;
52
+ agent?: string;
53
+ agents?: Record<string, string>;
52
54
  }
53
55
  export type ChangeRequestStatus = 'draft' | 'applied';
54
56
  export interface ChangeRequestFrontmatter {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;QACjD,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEtD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,wBAAwB,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,GAAG;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,cAAc,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,KAAK;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;QACjD,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEtD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,mBAAmB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,wBAAwB,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,GAAG;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,cAAc,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applica-software-guru/sdd-core",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Core library for Story Driven Development",
5
5
  "author": "Bruno Fortunato <bruno.fortunato@applica.guru>",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,12 @@
1
+ export const DEFAULT_AGENTS: Record<string, string> = {
2
+ claude: 'claude -p "$(cat $PROMPT_FILE)" --dangerously-skip-permissions --verbose',
3
+ codex: 'codex -q "$(cat $PROMPT_FILE)"',
4
+ opencode: 'opencode -p "$(cat $PROMPT_FILE)"',
5
+ };
6
+
7
+ export function resolveAgentCommand(
8
+ name: string,
9
+ configAgents?: Record<string, string>
10
+ ): string | undefined {
11
+ return configAgents?.[name] ?? DEFAULT_AGENTS[name];
12
+ }
@@ -0,0 +1,54 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { writeFile, unlink } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { randomBytes } from 'node:crypto';
6
+ import { resolveAgentCommand } from './agent-defaults.js';
7
+
8
+ export interface AgentRunnerOptions {
9
+ root: string;
10
+ prompt: string;
11
+ agent: string;
12
+ agents?: Record<string, string>;
13
+ onOutput?: (data: string) => void;
14
+ }
15
+
16
+ export async function runAgent(options: AgentRunnerOptions): Promise<number> {
17
+ const { root, prompt, agent, agents, onOutput } = options;
18
+
19
+ const template = resolveAgentCommand(agent, agents);
20
+ if (!template) {
21
+ throw new Error(`Unknown agent "${agent}". Available: ${Object.keys(agents ?? {}).join(', ') || 'claude, codex, opencode'}`);
22
+ }
23
+
24
+ // Write prompt to temp file (too large for CLI arg)
25
+ const tmpFile = join(tmpdir(), `sdd-prompt-${randomBytes(6).toString('hex')}.md`);
26
+ await writeFile(tmpFile, prompt, 'utf-8');
27
+
28
+ // Replace $PROMPT_FILE with the temp file path in the command template
29
+ const command = template.replace(/\$PROMPT_FILE/g, tmpFile);
30
+
31
+ try {
32
+ const exitCode = await new Promise<number>((resolve, reject) => {
33
+ const child = spawn(command, {
34
+ cwd: root,
35
+ shell: true,
36
+ stdio: onOutput ? ['inherit', 'pipe', 'pipe'] : 'inherit',
37
+ });
38
+
39
+ if (onOutput && child.stdout) {
40
+ child.stdout.on('data', (data: Buffer) => onOutput(data.toString()));
41
+ }
42
+ if (onOutput && child.stderr) {
43
+ child.stderr.on('data', (data: Buffer) => onOutput(data.toString()));
44
+ }
45
+
46
+ child.on('error', reject);
47
+ child.on('close', (code) => resolve(code ?? 1));
48
+ });
49
+
50
+ return exitCode;
51
+ } finally {
52
+ await unlink(tmpFile).catch(() => {});
53
+ }
54
+ }
package/src/index.ts CHANGED
@@ -19,4 +19,7 @@ export type {
19
19
  } from './types.js';
20
20
  export { SDDError, LockFileNotFoundError, ParseError, ProjectNotInitializedError } from './errors.js';
21
21
  export type { ProjectInfo } from './scaffold/templates.js';
22
- export { isSDDProject, readConfig } from './config/config-manager.js';
22
+ export { isSDDProject, readConfig, writeConfig } from './config/config-manager.js';
23
+ export { runAgent } from './agent/agent-runner.js';
24
+ export type { AgentRunnerOptions } from './agent/agent-runner.js';
25
+ export { DEFAULT_AGENTS, resolveAgentCommand } from './agent/agent-defaults.js';
@@ -0,0 +1,82 @@
1
+ import type { Bug, ChangeRequest, StoryFile } from '../types.js';
2
+ import { getFileDiff } from '../git/git.js';
3
+
4
+ export function generateApplyPrompt(
5
+ bugs: Bug[],
6
+ changeRequests: ChangeRequest[],
7
+ pendingFiles: StoryFile[],
8
+ root: string
9
+ ): string | null {
10
+ if (bugs.length === 0 && changeRequests.length === 0 && pendingFiles.length === 0) {
11
+ return null;
12
+ }
13
+
14
+ const sections: string[] = [];
15
+
16
+ sections.push('# SDD Apply\n\nThis project uses Story Driven Development. Complete the tasks below in order.');
17
+
18
+ // Bugs section
19
+ if (bugs.length > 0) {
20
+ const lines = [`## Open Bugs (${bugs.length})\n`];
21
+ for (const bug of bugs) {
22
+ lines.push(`### \`${bug.relativePath}\` — ${bug.frontmatter.title}\n`);
23
+ lines.push(bug.body.trim());
24
+ lines.push('');
25
+ }
26
+ sections.push(lines.join('\n'));
27
+ }
28
+
29
+ // Change Requests section
30
+ if (changeRequests.length > 0) {
31
+ const lines = [`## Pending Change Requests (${changeRequests.length})\n`];
32
+ for (const cr of changeRequests) {
33
+ lines.push(`### \`${cr.relativePath}\` — ${cr.frontmatter.title}\n`);
34
+ lines.push(cr.body.trim());
35
+ lines.push('');
36
+ }
37
+ sections.push(lines.join('\n'));
38
+ }
39
+
40
+ // Pending Files section
41
+ if (pendingFiles.length > 0) {
42
+ const lines = [`## Pending Files (${pendingFiles.length})\n`];
43
+ for (const f of pendingFiles) {
44
+ lines.push(`- \`${f.relativePath}\` — **${f.frontmatter.status}**`);
45
+ }
46
+ lines.push('');
47
+ lines.push('Read each file listed above before implementing.');
48
+
49
+ // Show git diff for changed files
50
+ const changed = pendingFiles.filter((f) => f.frontmatter.status === 'changed');
51
+ for (const f of changed) {
52
+ const diff = getFileDiff(root, f.relativePath);
53
+ if (diff) {
54
+ lines.push('');
55
+ lines.push(`### Changes in \`${f.relativePath}\`\n\n\`\`\`diff\n${diff}\n\`\`\``);
56
+ }
57
+ }
58
+
59
+ sections.push(lines.join('\n'));
60
+ }
61
+
62
+ // Instructions
63
+ const instructions = ['## Instructions\n'];
64
+
65
+ if (bugs.length > 0) {
66
+ instructions.push('1. Fix each open bug, then run `sdd mark-bug-resolved <file>` and commit');
67
+ }
68
+ if (changeRequests.length > 0) {
69
+ instructions.push(`${bugs.length > 0 ? '2' : '1'}. Apply each CR to the documentation, then run \`sdd mark-cr-applied <file>\` and commit`);
70
+ }
71
+ if (pendingFiles.length > 0) {
72
+ const step = (bugs.length > 0 ? 1 : 0) + (changeRequests.length > 0 ? 1 : 0) + 1;
73
+ instructions.push(`${step}. Implement each pending file, then run \`sdd mark-synced <file>\` and commit`);
74
+ }
75
+
76
+ const lastStep = (bugs.length > 0 ? 1 : 0) + (changeRequests.length > 0 ? 1 : 0) + (pendingFiles.length > 0 ? 1 : 0) + 1;
77
+ instructions.push(`${lastStep}. After each mark-* command, immediately commit: \`git add -A && git commit -m "sdd: <description>"\``);
78
+
79
+ sections.push(instructions.join('\n'));
80
+
81
+ return sections.join('\n\n');
82
+ }
package/src/sdd.ts CHANGED
@@ -4,6 +4,7 @@ import type { StoryStatus, ValidationResult, SDDConfig, ChangeRequest, Bug } fro
4
4
  import { ProjectNotInitializedError } from './errors.js';
5
5
  import { parseAllStoryFiles } from './parser/story-parser.js';
6
6
  import { generatePrompt } from './prompt/prompt-generator.js';
7
+ import { generateApplyPrompt } from './prompt/apply-prompt-generator.js';
7
8
  import { validate } from './validate/validator.js';
8
9
  import { initProject } from './scaffold/init.js';
9
10
  import { isSDDProject, readConfig, writeConfig } from './config/config-manager.js';
@@ -52,6 +53,16 @@ export class SDD {
52
53
  return generatePrompt(pending, this.root);
53
54
  }
54
55
 
56
+ async applyPrompt(): Promise<string | null> {
57
+ this.ensureInitialized();
58
+ const [bugs, changeRequests, pendingFiles] = await Promise.all([
59
+ this.openBugs(),
60
+ this.pendingChangeRequests(),
61
+ this.pending(),
62
+ ]);
63
+ return generateApplyPrompt(bugs, changeRequests, pendingFiles, this.root);
64
+ }
65
+
55
66
  async validate(): Promise<ValidationResult> {
56
67
  this.ensureInitialized();
57
68
  const files = await parseAllStoryFiles(this.root);
package/src/types.ts CHANGED
@@ -58,6 +58,8 @@ export interface StoryStatus {
58
58
  export interface SDDConfig {
59
59
  description: string;
60
60
  'last-sync-commit'?: string;
61
+ agent?: string;
62
+ agents?: Record<string, string>;
61
63
  }
62
64
 
63
65
  export type ChangeRequestStatus = 'draft' | 'applied';
@@ -0,0 +1,119 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateApplyPrompt } from '../src/prompt/apply-prompt-generator.js';
3
+ import { resolveAgentCommand, DEFAULT_AGENTS } from '../src/agent/agent-defaults.js';
4
+ import type { Bug, ChangeRequest, StoryFile } from '../src/types.js';
5
+
6
+ function makeBug(overrides: Partial<Bug> = {}): Bug {
7
+ return {
8
+ relativePath: 'bugs/BUG-001.md',
9
+ frontmatter: {
10
+ title: 'Login button broken',
11
+ status: 'open',
12
+ author: 'test',
13
+ 'created-at': '2024-01-01T00:00:00.000Z',
14
+ },
15
+ body: '## Description\n\nThe login button does not work.',
16
+ ...overrides,
17
+ };
18
+ }
19
+
20
+ function makeCR(overrides: Partial<ChangeRequest> = {}): ChangeRequest {
21
+ return {
22
+ relativePath: 'change-requests/CR-001.md',
23
+ frontmatter: {
24
+ title: 'Add dark mode',
25
+ status: 'draft',
26
+ author: 'test',
27
+ 'created-at': '2024-01-01T00:00:00.000Z',
28
+ },
29
+ body: '## Changes\n\nAdd dark mode support.',
30
+ ...overrides,
31
+ };
32
+ }
33
+
34
+ function makeFile(overrides: Partial<StoryFile> = {}): StoryFile {
35
+ return {
36
+ relativePath: 'product/features/auth.md',
37
+ frontmatter: {
38
+ title: 'Auth',
39
+ status: 'new',
40
+ author: 'test',
41
+ 'last-modified': '2024-01-01T00:00:00.000Z',
42
+ version: '1.0',
43
+ },
44
+ body: '# Auth Feature',
45
+ pendingItems: [],
46
+ agentNotes: null,
47
+ crossRefs: [],
48
+ hash: 'abc',
49
+ ...overrides,
50
+ };
51
+ }
52
+
53
+ describe('generateApplyPrompt', () => {
54
+ it('returns null when nothing to do', () => {
55
+ const result = generateApplyPrompt([], [], [], '/tmp');
56
+ expect(result).toBeNull();
57
+ });
58
+
59
+ it('generates prompt with only bugs', () => {
60
+ const prompt = generateApplyPrompt([makeBug()], [], [], '/tmp');
61
+ expect(prompt).not.toBeNull();
62
+ expect(prompt).toContain('# SDD Apply');
63
+ expect(prompt).toContain('Open Bugs (1)');
64
+ expect(prompt).toContain('Login button broken');
65
+ expect(prompt).toContain('bugs/BUG-001.md');
66
+ expect(prompt).not.toContain('Pending Change Requests');
67
+ expect(prompt).not.toContain('Pending Files');
68
+ });
69
+
70
+ it('generates prompt with only CRs', () => {
71
+ const prompt = generateApplyPrompt([], [makeCR()], [], '/tmp');
72
+ expect(prompt).not.toBeNull();
73
+ expect(prompt).toContain('Pending Change Requests (1)');
74
+ expect(prompt).toContain('Add dark mode');
75
+ expect(prompt).not.toContain('Open Bugs');
76
+ expect(prompt).not.toContain('Pending Files');
77
+ });
78
+
79
+ it('generates prompt with only pending files', () => {
80
+ const prompt = generateApplyPrompt([], [], [makeFile()], '/tmp');
81
+ expect(prompt).not.toBeNull();
82
+ expect(prompt).toContain('Pending Files (1)');
83
+ expect(prompt).toContain('product/features/auth.md');
84
+ expect(prompt).toContain('**new**');
85
+ expect(prompt).not.toContain('Open Bugs');
86
+ expect(prompt).not.toContain('Pending Change Requests');
87
+ });
88
+
89
+ it('generates prompt with all three', () => {
90
+ const prompt = generateApplyPrompt([makeBug()], [makeCR()], [makeFile()], '/tmp');
91
+ expect(prompt).not.toBeNull();
92
+ expect(prompt).toContain('Open Bugs (1)');
93
+ expect(prompt).toContain('Pending Change Requests (1)');
94
+ expect(prompt).toContain('Pending Files (1)');
95
+ expect(prompt).toContain('## Instructions');
96
+ });
97
+ });
98
+
99
+ describe('resolveAgentCommand', () => {
100
+ it('resolves built-in agent', () => {
101
+ const cmd = resolveAgentCommand('claude');
102
+ expect(cmd).toBe(DEFAULT_AGENTS.claude);
103
+ });
104
+
105
+ it('resolves config agent over built-in', () => {
106
+ const cmd = resolveAgentCommand('claude', { claude: 'my-claude $PROMPT' });
107
+ expect(cmd).toBe('my-claude $PROMPT');
108
+ });
109
+
110
+ it('resolves custom agent from config', () => {
111
+ const cmd = resolveAgentCommand('my-agent', { 'my-agent': 'my-agent-cmd $PROMPT' });
112
+ expect(cmd).toBe('my-agent-cmd $PROMPT');
113
+ });
114
+
115
+ it('returns undefined for unknown agent', () => {
116
+ const cmd = resolveAgentCommand('unknown');
117
+ expect(cmd).toBeUndefined();
118
+ });
119
+ });