@mytechtoday/augment-sdd 1.0.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.
Files changed (60) hide show
  1. package/.eslintrc.json +20 -0
  2. package/out/commands/executeBeadsBatch.js +165 -0
  3. package/out/commands/executeBeadsBatch.js.map +1 -0
  4. package/out/commands/fullPipeline.js +129 -0
  5. package/out/commands/fullPipeline.js.map +1 -0
  6. package/out/commands/generateBeads.js +148 -0
  7. package/out/commands/generateBeads.js.map +1 -0
  8. package/out/commands/generateOpenSpec.js +241 -0
  9. package/out/commands/generateOpenSpec.js.map +1 -0
  10. package/out/dashboard/DashboardPanel.js +171 -0
  11. package/out/dashboard/DashboardPanel.js.map +1 -0
  12. package/out/extension.js +96 -0
  13. package/out/extension.js.map +1 -0
  14. package/out/parsers/parseBeadUpdates.js +28 -0
  15. package/out/parsers/parseBeadUpdates.js.map +1 -0
  16. package/out/parsers/parseTasksMarkdown.js +49 -0
  17. package/out/parsers/parseTasksMarkdown.js.map +1 -0
  18. package/out/test/integration/executeBeadsBatch.test.js +155 -0
  19. package/out/test/integration/executeBeadsBatch.test.js.map +1 -0
  20. package/out/test/integration/generateOpenSpec.test.js +154 -0
  21. package/out/test/integration/generateOpenSpec.test.js.map +1 -0
  22. package/out/test/runTest.js +47 -0
  23. package/out/test/runTest.js.map +1 -0
  24. package/out/test/suite/index.js +74 -0
  25. package/out/test/suite/index.js.map +1 -0
  26. package/out/test/unit/parseBeadUpdates.test.js +73 -0
  27. package/out/test/unit/parseBeadUpdates.test.js.map +1 -0
  28. package/out/test/unit/parseTasksMarkdown.test.js +69 -0
  29. package/out/test/unit/parseTasksMarkdown.test.js.map +1 -0
  30. package/out/test/unit/runCli.test.js +113 -0
  31. package/out/test/unit/runCli.test.js.map +1 -0
  32. package/out/utils/detectCli.js +30 -0
  33. package/out/utils/detectCli.js.map +1 -0
  34. package/out/utils/getConfig.js +60 -0
  35. package/out/utils/getConfig.js.map +1 -0
  36. package/out/utils/logger.js +30 -0
  37. package/out/utils/logger.js.map +1 -0
  38. package/out/utils/runCli.js +122 -0
  39. package/out/utils/runCli.js.map +1 -0
  40. package/package.json +111 -0
  41. package/src/commands/executeBeadsBatch.ts +153 -0
  42. package/src/commands/fullPipeline.ts +120 -0
  43. package/src/commands/generateBeads.ts +127 -0
  44. package/src/commands/generateOpenSpec.ts +227 -0
  45. package/src/dashboard/DashboardPanel.ts +168 -0
  46. package/src/extension.ts +77 -0
  47. package/src/parsers/parseBeadUpdates.ts +26 -0
  48. package/src/parsers/parseTasksMarkdown.ts +61 -0
  49. package/src/test/integration/executeBeadsBatch.test.ts +129 -0
  50. package/src/test/integration/generateOpenSpec.test.ts +129 -0
  51. package/src/test/runTest.ts +15 -0
  52. package/src/test/suite/index.ts +37 -0
  53. package/src/test/unit/parseBeadUpdates.test.ts +48 -0
  54. package/src/test/unit/parseTasksMarkdown.test.ts +41 -0
  55. package/src/test/unit/runCli.test.ts +109 -0
  56. package/src/utils/detectCli.ts +28 -0
  57. package/src/utils/getConfig.ts +25 -0
  58. package/src/utils/logger.ts +42 -0
  59. package/src/utils/runCli.ts +102 -0
  60. package/tsconfig.json +18 -0
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ /**
37
+ * Unit tests for runCli.ts
38
+ * UT-1: resolves with trimmed stdout on exit code 0
39
+ * UT-2: rejects on non-zero exit code
40
+ * UT-3: rejects on timeout
41
+ */
42
+ const assert = __importStar(require("assert"));
43
+ const cp = __importStar(require("child_process"));
44
+ const sinon = __importStar(require("sinon"));
45
+ const events_1 = require("events");
46
+ const runCli_1 = require("../../utils/runCli");
47
+ function fakeProc(opts) {
48
+ const stdoutEE = new events_1.EventEmitter();
49
+ const stderrEE = new events_1.EventEmitter();
50
+ const procEE = new events_1.EventEmitter();
51
+ // Minimal object that satisfies what runCli actually accesses.
52
+ const proc = {
53
+ stdout: stdoutEE,
54
+ stderr: stderrEE,
55
+ kill: () => { },
56
+ on: procEE.on.bind(procEE),
57
+ once: procEE.once.bind(procEE),
58
+ removeListener: procEE.removeListener.bind(procEE),
59
+ emit: procEE.emit.bind(procEE),
60
+ };
61
+ setImmediate(() => {
62
+ if (opts.stdout) {
63
+ stdoutEE.emit('data', Buffer.from(opts.stdout));
64
+ }
65
+ if (opts.stderr) {
66
+ stderrEE.emit('data', Buffer.from(opts.stderr));
67
+ }
68
+ if (opts.hangMs === undefined) {
69
+ procEE.emit('close', opts.code ?? 0);
70
+ }
71
+ else {
72
+ // Deliberately hang so the runCli timer can fire first.
73
+ setTimeout(() => procEE.emit('close', null), opts.hangMs);
74
+ }
75
+ });
76
+ return proc;
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // Tests
80
+ // ---------------------------------------------------------------------------
81
+ suite('runCli — unit tests', () => {
82
+ test('UT-1: resolves with trimmed stdout on exit code 0', async () => {
83
+ const stub = sinon.stub(cp, 'spawn').returns(fakeProc({ stdout: 'hello\n', code: 0 }));
84
+ try {
85
+ const result = await (0, runCli_1.runCli)('echo', ['hello'], '/tmp');
86
+ assert.strictEqual(result, 'hello');
87
+ }
88
+ finally {
89
+ stub.restore();
90
+ }
91
+ });
92
+ test('UT-2: rejects on non-zero exit code', async () => {
93
+ const stub = sinon.stub(cp, 'spawn').returns(fakeProc({ stdout: '', stderr: 'err', code: 1 }));
94
+ try {
95
+ await assert.rejects((0, runCli_1.runCli)('false', [], '/tmp'), /failed with exit code 1/);
96
+ }
97
+ finally {
98
+ stub.restore();
99
+ }
100
+ });
101
+ test('UT-3: rejects on timeout', async () => {
102
+ // hangMs (5 000) >> timeoutMs (100) → timer fires first, process is killed,
103
+ // promise rejects with a message containing "timed out".
104
+ const stub = sinon.stub(cp, 'spawn').returns(fakeProc({ hangMs: 5000, code: null }));
105
+ try {
106
+ await assert.rejects((0, runCli_1.runCli)('sleep', ['5'], '/tmp', 100), /timed out/i);
107
+ }
108
+ finally {
109
+ stub.restore();
110
+ }
111
+ });
112
+ });
113
+ //# sourceMappingURL=runCli.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runCli.test.js","sourceRoot":"","sources":["../../../src/test/unit/runCli.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectCli = detectCli;
4
+ /**
5
+ * detectCli — checks whether a CLI binary is accessible on the system PATH.
6
+ *
7
+ * Uses the platform-appropriate tool (where on Windows, which on Unix) via
8
+ * runCli so that detection is non-interactive and consistent with all other
9
+ * CLI invocations in the extension.
10
+ */
11
+ const runCli_1 = require("./runCli");
12
+ /**
13
+ * Returns `true` if `name` resolves to an executable on the system PATH,
14
+ * `false` otherwise.
15
+ *
16
+ * @param name The CLI binary name to look up (e.g., "auggie", "openspec", "bd").
17
+ */
18
+ async function detectCli(name) {
19
+ // `where` (Windows) / `which` (Unix/macOS) exits 0 only when the binary is found.
20
+ const lookupCommand = process.platform === 'win32' ? 'where' : 'which';
21
+ try {
22
+ // Use the workspace root as cwd; any valid directory works for which/where.
23
+ await (0, runCli_1.runCli)(lookupCommand, [name], process.cwd(), 10000);
24
+ return true;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ //# sourceMappingURL=detectCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectCli.js","sourceRoot":"","sources":["../../src/utils/detectCli.ts"],"names":[],"mappings":";;AAeA,8BAWC;AA1BD;;;;;;GAMG;AACH,qCAAkC;AAElC;;;;;GAKG;AACI,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,kFAAkF;IAClF,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAEvE,IAAI,CAAC;QACH,4EAA4E;QAC5E,MAAM,IAAA,eAAM,EAAC,aAAa,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,KAAM,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getConfig = getConfig;
37
+ /**
38
+ * getConfig — type-safe VS Code settings reader for the Augment SDD extension.
39
+ *
40
+ * All extension settings live under the "augmentSdd" namespace as declared in
41
+ * package.json `contributes.configuration`. Callers provide a default value
42
+ * so they never receive `undefined` even when the setting is absent.
43
+ *
44
+ * Bead 9 wires this helper into every command; it is created here early so
45
+ * generateOpenSpec (Bead 5) and generateBeads (Bead 6) can use it immediately.
46
+ */
47
+ const vscode = __importStar(require("vscode"));
48
+ /**
49
+ * Read a value from the `augmentSdd` configuration scope.
50
+ *
51
+ * @param key Setting key without the `augmentSdd.` prefix
52
+ * (e.g., `"jiraFolder"`, `"batchSize"`).
53
+ * @param defaultValue Returned when the setting is absent or undefined.
54
+ * @returns The configured value, or `defaultValue`.
55
+ */
56
+ function getConfig(key, defaultValue) {
57
+ const value = vscode.workspace.getConfiguration('augmentSdd').get(key);
58
+ return value !== undefined ? value : defaultValue;
59
+ }
60
+ //# sourceMappingURL=getConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getConfig.js","sourceRoot":"","sources":["../../src/utils/getConfig.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBA,8BAGC;AAvBD;;;;;;;;;GASG;AACH,+CAAiC;AAEjC;;;;;;;GAOG;AACH,SAAgB,SAAS,CAAI,GAAW,EAAE,YAAe;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC,GAAG,CAAI,GAAG,CAAC,CAAC;IAC1E,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC;AACpD,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initLogger = initLogger;
4
+ exports.log = log;
5
+ exports.revealOutputChannel = revealOutputChannel;
6
+ /** The shared OutputChannel instance, set by initLogger(). */
7
+ let _channel;
8
+ /**
9
+ * Initialise the logger with the extension's shared OutputChannel.
10
+ * Must be called once in activate() before any other logging.
11
+ */
12
+ function initLogger(channel) {
13
+ _channel = channel;
14
+ }
15
+ /**
16
+ * Append a timestamped message to the Augment SDD Output Channel.
17
+ * Safe to call before initLogger() — the message is silently dropped.
18
+ */
19
+ function log(message) {
20
+ const ts = new Date().toISOString();
21
+ _channel?.appendLine(`[${ts}] ${message}`);
22
+ }
23
+ /**
24
+ * Reveal the Augment SDD Output Channel in the VS Code UI and bring it
25
+ * into focus without stealing the editor focus.
26
+ */
27
+ function revealOutputChannel() {
28
+ _channel?.show(true);
29
+ }
30
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";;AAqBA,gCAEC;AAMD,kBAGC;AAMD,kDAEC;AA1BD,8DAA8D;AAC9D,IAAI,QAA0C,CAAC;AAE/C;;;GAGG;AACH,SAAgB,UAAU,CAAC,OAA6B;IACtD,QAAQ,GAAG,OAAO,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAgB,GAAG,CAAC,OAAe;IACjC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,QAAQ,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB;IACjC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runCli = runCli;
37
+ /**
38
+ * runCli — reusable child_process.spawn wrapper for all augment-sdd commands.
39
+ *
40
+ * Design (D1): Uses spawn (not exec) to avoid memory caps and to enable
41
+ * deterministic timeout handling. execa is intentionally excluded to keep the
42
+ * runtime dependency footprint at zero.
43
+ *
44
+ * Design (D2): Centralises timeout, error formatting, and logging. The optional
45
+ * `logger` callback receives structured messages before and after each call so
46
+ * callers can route them to the Augment SDD Output Channel without this module
47
+ * depending on VS Code APIs.
48
+ */
49
+ const cp = __importStar(require("child_process"));
50
+ /** Maximum characters of the serialised args string written to the log. */
51
+ const MAX_LOGGED_ARGS_CHARS = 500;
52
+ /**
53
+ * Spawn `command` with `args` in `cwd`, collect stdout/stderr, and:
54
+ * - Resolve with trimmed stdout on exit code 0.
55
+ * - Reject with a descriptive Error on non-zero exit code.
56
+ * - Kill the process and reject with a timeout Error when `timeoutMs` elapses.
57
+ * - Reject immediately if the spawn itself emits an error (e.g., ENOENT).
58
+ *
59
+ * @param command Executable name or path (passed to spawn with shell: true).
60
+ * @param args Argument list. Prompt-like args are truncated in log output.
61
+ * @param cwd Working directory for the spawned process.
62
+ * @param timeoutMs Maximum allowed runtime in ms. Defaults to 120 000 ms.
63
+ * @param logger Optional callback that receives structured log messages
64
+ * (pre-run, result, timeout, spawn-error). Timestamps should
65
+ * be added by the caller (e.g., the `log` helper in logger.ts).
66
+ */
67
+ function runCli(command, args, cwd, timeoutMs = 120000, logger) {
68
+ // Log the invocation with args truncated to avoid flooding the Output Channel
69
+ // with large Auggie prompts (spec: truncate prompt ≤ 500 chars in log entries).
70
+ const rawArgs = args.join(' ');
71
+ const displayArgs = rawArgs.length > MAX_LOGGED_ARGS_CHARS
72
+ ? rawArgs.slice(0, MAX_LOGGED_ARGS_CHARS) + '…'
73
+ : rawArgs;
74
+ logger?.(`Run: ${command} ${displayArgs}`);
75
+ return new Promise((resolve, reject) => {
76
+ const proc = cp.spawn(command, args, { cwd, shell: true });
77
+ let stdout = '';
78
+ let stderr = '';
79
+ let settled = false;
80
+ /** Settle the promise at most once. */
81
+ function settle(action) {
82
+ if (settled) {
83
+ return;
84
+ }
85
+ settled = true;
86
+ clearTimeout(timer);
87
+ action();
88
+ }
89
+ // Enforce a hard timeout: kill the process and reject with a clear message.
90
+ const timer = setTimeout(() => {
91
+ settle(() => {
92
+ proc.kill();
93
+ const msg = `CLI "${command} ${args.join(' ')}" timed out after ${timeoutMs} ms`;
94
+ logger?.(`Timeout after ${timeoutMs} ms | ${command}`);
95
+ reject(new Error(msg));
96
+ });
97
+ }, timeoutMs);
98
+ proc.stdout.on('data', (data) => { stdout += data; });
99
+ proc.stderr.on('data', (data) => { stderr += data; });
100
+ proc.on('close', (code) => {
101
+ settle(() => {
102
+ if (code === 0) {
103
+ logger?.(`Exit 0 | stdout: ${stdout.trim()}`);
104
+ resolve(stdout.trim());
105
+ }
106
+ else {
107
+ const stderrTrimmed = stderr.trim();
108
+ logger?.(`Exit ${code} | stderr: ${stderrTrimmed}`);
109
+ reject(new Error(`CLI "${command} ${args.join(' ')}" failed with exit code ${code}\nStderr: ${stderrTrimmed}`));
110
+ }
111
+ });
112
+ });
113
+ // Propagate spawn errors (e.g., ENOENT — binary not found) immediately.
114
+ proc.on('error', (err) => {
115
+ settle(() => {
116
+ logger?.(`Spawn error: ${err.message}`);
117
+ reject(err);
118
+ });
119
+ });
120
+ });
121
+ }
122
+ //# sourceMappingURL=runCli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runCli.js","sourceRoot":"","sources":["../../src/utils/runCli.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,111 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/vscode-extension-manifest.json",
3
+ "name": "@mytechtoday/augment-sdd",
4
+ "displayName": "Augment SDD",
5
+ "description": "Automates the OpenSpec + Beads + Auggie pipeline (steps 5–7) for spec-driven development in VS Code.",
6
+ "version": "1.0.0",
7
+ "publisher": "mytech-today-now",
8
+ "engines": {
9
+ "vscode": "^1.85.0"
10
+ },
11
+ "categories": [
12
+ "Other"
13
+ ],
14
+ "activationEvents": [
15
+ "onStartupFinished"
16
+ ],
17
+ "main": "./out/extension.js",
18
+ "contributes": {
19
+ "commands": [
20
+ {
21
+ "command": "augmentSdd.generateOpenSpec",
22
+ "title": "Augment SDD: Generate OpenSpec",
23
+ "category": "Augment SDD"
24
+ },
25
+ {
26
+ "command": "augmentSdd.generateBeads",
27
+ "title": "Augment SDD: Generate Beads",
28
+ "category": "Augment SDD"
29
+ },
30
+ {
31
+ "command": "augmentSdd.executeBeadsBatch",
32
+ "title": "Augment SDD: Execute Beads Batch",
33
+ "category": "Augment SDD"
34
+ },
35
+ {
36
+ "command": "augmentSdd.fullPipeline",
37
+ "title": "Augment SDD: Run Full Pipeline",
38
+ "category": "Augment SDD"
39
+ }
40
+ ],
41
+ "configuration": {
42
+ "title": "Augment SDD",
43
+ "properties": {
44
+ "augmentSdd.batchSize": {
45
+ "type": "integer",
46
+ "default": 3,
47
+ "minimum": 1,
48
+ "maximum": 10,
49
+ "description": "Number of Beads to include in each Auggie batch execution."
50
+ },
51
+ "augmentSdd.auggieExtraFlags": {
52
+ "type": "string",
53
+ "default": "",
54
+ "description": "Extra flags appended to every `auggie --print --quiet` invocation."
55
+ },
56
+ "augmentSdd.jiraFolder": {
57
+ "type": "string",
58
+ "default": ".jira",
59
+ "description": "Folder to auto-detect JIRA Markdown ticket files."
60
+ },
61
+ "augmentSdd.enableWebviewDashboard": {
62
+ "type": "boolean",
63
+ "default": true,
64
+ "description": "Show the Augment SDD Webview dashboard after pipeline steps."
65
+ }
66
+ }
67
+ }
68
+ },
69
+ "scripts": {
70
+ "vscode:prepublish": "npm run compile",
71
+ "compile": "tsc -p ./",
72
+ "watch": "tsc -watch -p ./",
73
+ "test": "node ./out/test/runTest.js",
74
+ "lint": "eslint src --ext ts"
75
+ },
76
+ "devDependencies": {
77
+ "@types/glob": "^8.1.0",
78
+ "@types/mocha": "^10.0.0",
79
+ "@types/node": "^20.x",
80
+ "@types/sinon": "^17.0.0",
81
+ "@types/vscode": "^1.85.0",
82
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
83
+ "@typescript-eslint/parser": "^7.0.0",
84
+ "@vscode/test-electron": "^2.3.0",
85
+ "eslint": "^8.0.0",
86
+ "mocha": "^10.0.0",
87
+ "sinon": "^17.0.0",
88
+ "typescript": "^5.3.0"
89
+ },
90
+ "publishConfig": {
91
+ "access": "restricted",
92
+ "registry": "https://registry.npmjs.org/"
93
+ },
94
+ "metadata": {
95
+ "openspecChange": "init",
96
+ "jiraTicket": "AUGSDD-1",
97
+ "schema": "spec-driven",
98
+ "createdAt": "2026-04-02",
99
+ "capabilities": [
100
+ "cli-detection",
101
+ "generate-openspec",
102
+ "generate-beads",
103
+ "execute-beads-batch",
104
+ "full-pipeline",
105
+ "run-cli-wrapper",
106
+ "logging-output-channel",
107
+ "extension-settings",
108
+ "webview-dashboard"
109
+ ]
110
+ }
111
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * executeBeadsBatch — Bead 7 command implementation.
3
+ *
4
+ * Steps (tasks 7.1-7.7):
5
+ * 7.1 Fetch and JSON-parse bd ready --json; exit gracefully if empty.
6
+ * 7.2 Slice first N beads per augmentSdd.batchSize setting (default 3).
7
+ * 7.3 Build batch Auggie prompt with --- BEAD START --- sentinels.
8
+ * 7.4 Execute auggie --print --quiet via runCli.
9
+ * 7.5 Parse bd update sentinel lines from response.
10
+ * 7.6 Execute each parsed bd update command; continue on partial failure.
11
+ * 7.7 Show warning if no sentinel lines were parsed from Auggie response.
12
+ */
13
+ import * as vscode from 'vscode';
14
+ import { runCli } from '../utils/runCli';
15
+ import { getConfig } from '../utils/getConfig';
16
+ import { log, revealOutputChannel } from '../utils/logger';
17
+ import { parseBeadUpdates } from '../parsers/parseBeadUpdates';
18
+
19
+ /** Shape returned by `bd ready --json`. */
20
+ interface ReadyBead {
21
+ id: string;
22
+ title: string;
23
+ description: string;
24
+ }
25
+
26
+ /** Entry point registered as `augmentSdd.executeBeadsBatch`. */
27
+ export async function executeBeadsBatch(): Promise<void> {
28
+ const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
29
+ if (!workspaceRoot) {
30
+ vscode.window.showErrorMessage('Augment SDD: No workspace folder open.');
31
+ return;
32
+ }
33
+
34
+ // 7.1 Fetch ready beads
35
+ let beads: ReadyBead[];
36
+ try {
37
+ const raw = await runCli('bd', ['ready', '--json'], workspaceRoot, 30_000, log);
38
+ beads = JSON.parse(raw) as ReadyBead[];
39
+ } catch (err) {
40
+ const msg = err instanceof Error ? err.message : String(err);
41
+ log(`executeBeadsBatch: failed to fetch ready beads — ${msg}`);
42
+ const action = await vscode.window.showErrorMessage(
43
+ `Augment SDD: Failed to fetch ready beads. ${msg}`,
44
+ 'View Logs'
45
+ );
46
+ if (action === 'View Logs') { revealOutputChannel(); }
47
+ return;
48
+ }
49
+
50
+ if (beads.length === 0) {
51
+ vscode.window.showInformationMessage('Augment SDD: No beads ready.');
52
+ return;
53
+ }
54
+
55
+ // 7.2 Slice to batchSize
56
+ const batchSize = getConfig<number>('batchSize', 3);
57
+ const batch = beads.slice(0, batchSize);
58
+ log(`executeBeadsBatch: ${batch.length} bead(s) selected (batchSize=${batchSize})`);
59
+
60
+ // 7.3 Build prompt
61
+ const prompt = buildBatchPrompt(batch);
62
+ log(`executeBeadsBatch: prompt length=${prompt.length}`);
63
+
64
+ // 7.4 Run Auggie
65
+ let auggieOutput: string;
66
+ try {
67
+ const extraFlags = getConfig<string>('auggieExtraFlags', '');
68
+ const args = ['--print', '--quiet', prompt];
69
+ if (extraFlags) {
70
+ args.push(...extraFlags.split(/\s+/).filter(Boolean));
71
+ }
72
+ auggieOutput = await runCli('auggie', args, workspaceRoot, 600_000, log);
73
+ } catch (err) {
74
+ const msg = err instanceof Error ? err.message : String(err);
75
+ log(`executeBeadsBatch: Auggie failed — ${msg}`);
76
+ const action = await vscode.window.showErrorMessage(
77
+ `Augment SDD: Auggie execution failed. ${msg}`,
78
+ 'View Logs'
79
+ );
80
+ if (action === 'View Logs') { revealOutputChannel(); }
81
+ return;
82
+ }
83
+
84
+ // 7.5 Parse sentinel lines
85
+ const updates = parseBeadUpdates(auggieOutput);
86
+ log(`executeBeadsBatch: parsed ${updates.length} sentinel line(s)`);
87
+
88
+ // 7.7 Warn if no sentinels found
89
+ if (updates.length === 0) {
90
+ log('executeBeadsBatch: WARNING — no bd update sentinel lines found in Auggie response');
91
+ const action = await vscode.window.showWarningMessage(
92
+ 'Augment SDD: Auggie did not return any bead completion sentinels. Check logs for details.',
93
+ 'View Logs'
94
+ );
95
+ if (action === 'View Logs') { revealOutputChannel(); }
96
+ return;
97
+ }
98
+
99
+ // 7.6 Execute each sentinel command; continue on partial failure
100
+ let successCount = 0;
101
+ let failureCount = 0;
102
+ for (const updateCmd of updates) {
103
+ const parts = updateCmd.split(/\s+/);
104
+ // parts: ['bd', 'update', '<id>', '--status', 'done']
105
+ const args = parts.slice(1); // drop 'bd'
106
+ try {
107
+ await runCli('bd', args, workspaceRoot, 30_000, log);
108
+ log(`executeBeadsBatch: ✓ ${updateCmd}`);
109
+ successCount++;
110
+ } catch (err) {
111
+ const msg = err instanceof Error ? err.message : String(err);
112
+ log(`executeBeadsBatch: ✗ ${updateCmd} — ${msg}`);
113
+ failureCount++;
114
+ }
115
+ }
116
+
117
+ // Surface final result
118
+ if (failureCount === 0) {
119
+ vscode.window.showInformationMessage(
120
+ `Augment SDD: Batch complete — ${successCount} bead(s) marked done.`
121
+ );
122
+ } else {
123
+ const action = await vscode.window.showWarningMessage(
124
+ `Augment SDD: Batch finished with ${failureCount} failure(s). ${successCount} bead(s) succeeded.`,
125
+ 'View Logs'
126
+ );
127
+ if (action === 'View Logs') { revealOutputChannel(); }
128
+ }
129
+ }
130
+
131
+ /**
132
+ * 7.3: Construct the multi-bead Auggie prompt with --- BEAD START --- sentinels.
133
+ */
134
+ function buildBatchPrompt(beads: ReadyBead[]): string {
135
+ const header = [
136
+ 'You are Auggie, a senior engineer working inside this codebase.',
137
+ 'Implement the following beads one at a time. For each bead:',
138
+ '',
139
+ '1. Understand the requirements from the provided OpenSpec context.',
140
+ '2. Make all necessary code changes.',
141
+ '3. At the VERY END of your response for that specific bead, output EXACTLY this line and nothing else on that line:',
142
+ ' bd update <BEAD-ID> --status done',
143
+ '',
144
+ 'Do not output any other bd commands unless completing a bead.',
145
+ ].join('\n');
146
+
147
+ const sections = beads.map(b =>
148
+ `--- BEAD START ---\nID: ${b.id}\nTitle: ${b.title}\nDescription: ${b.description}`
149
+ ).join('\n\n');
150
+
151
+ return `${header}\n\n${sections}`;
152
+ }
153
+