@mytechtoday/augment-sdd 1.0.0 → 1.1.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 (58) hide show
  1. package/out/beads/BeadsAdapter.js +30 -0
  2. package/out/beads/BeadsAdapter.js.map +1 -0
  3. package/out/beads/ClassicBeadsAdapter.js +84 -0
  4. package/out/beads/ClassicBeadsAdapter.js.map +1 -0
  5. package/out/beads/PowerShellBeadsAdapter.js +118 -0
  6. package/out/beads/PowerShellBeadsAdapter.js.map +1 -0
  7. package/out/beads/getBeadsAdapter.js +94 -0
  8. package/out/beads/getBeadsAdapter.js.map +1 -0
  9. package/out/commands/executeBeadsBatch.js +29 -15
  10. package/out/commands/executeBeadsBatch.js.map +1 -1
  11. package/out/commands/generateBeads.js +25 -22
  12. package/out/commands/generateBeads.js.map +1 -1
  13. package/out/commands/initWizard.js +184 -0
  14. package/out/commands/initWizard.js.map +1 -0
  15. package/out/extension.js +10 -0
  16. package/out/extension.js.map +1 -1
  17. package/out/test/integration/executeBeadsBatch.test.js +83 -57
  18. package/out/test/integration/executeBeadsBatch.test.js.map +1 -1
  19. package/out/test/integration/generateBeads.test.js +156 -0
  20. package/out/test/integration/generateBeads.test.js.map +1 -0
  21. package/out/test/integration/generateOpenSpec.test.js +16 -39
  22. package/out/test/integration/generateOpenSpec.test.js.map +1 -1
  23. package/out/test/unit/ClassicBeadsAdapter.test.js +121 -0
  24. package/out/test/unit/ClassicBeadsAdapter.test.js.map +1 -0
  25. package/out/test/unit/PowerShellBeadsAdapter.test.js +120 -0
  26. package/out/test/unit/PowerShellBeadsAdapter.test.js.map +1 -0
  27. package/out/test/unit/getBeadsAdapter.test.js +97 -0
  28. package/out/test/unit/getBeadsAdapter.test.js.map +1 -0
  29. package/out/test/unit/initWizard.test.js +170 -0
  30. package/out/test/unit/initWizard.test.js.map +1 -0
  31. package/out/test/unit/runCli.test.js +11 -24
  32. package/out/test/unit/runCli.test.js.map +1 -1
  33. package/out/utils/detectCli.js +47 -1
  34. package/out/utils/detectCli.js.map +1 -1
  35. package/out/utils/runCli.js +9 -3
  36. package/out/utils/runCli.js.map +1 -1
  37. package/package.json +22 -1
  38. package/.eslintrc.json +0 -20
  39. package/src/commands/executeBeadsBatch.ts +0 -153
  40. package/src/commands/fullPipeline.ts +0 -120
  41. package/src/commands/generateBeads.ts +0 -127
  42. package/src/commands/generateOpenSpec.ts +0 -227
  43. package/src/dashboard/DashboardPanel.ts +0 -168
  44. package/src/extension.ts +0 -77
  45. package/src/parsers/parseBeadUpdates.ts +0 -26
  46. package/src/parsers/parseTasksMarkdown.ts +0 -61
  47. package/src/test/integration/executeBeadsBatch.test.ts +0 -129
  48. package/src/test/integration/generateOpenSpec.test.ts +0 -129
  49. package/src/test/runTest.ts +0 -15
  50. package/src/test/suite/index.ts +0 -37
  51. package/src/test/unit/parseBeadUpdates.test.ts +0 -48
  52. package/src/test/unit/parseTasksMarkdown.test.ts +0 -41
  53. package/src/test/unit/runCli.test.ts +0 -109
  54. package/src/utils/detectCli.ts +0 -28
  55. package/src/utils/getConfig.ts +0 -25
  56. package/src/utils/logger.ts +0 -42
  57. package/src/utils/runCli.ts +0 -102
  58. package/tsconfig.json +0 -18
@@ -0,0 +1,170 @@
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 initWizard (UT-5 — ps-fix test-spec.md)
38
+ *
39
+ * UT-5a: QuickPick cancelled → no config written
40
+ * UT-5b: "beads-ps1" selected → scripts copied, .beads/issues.jsonl created,
41
+ * beadsBackend written to workspace config
42
+ * UT-5c: "bd" selected + dolt absent → error message shown, no config written
43
+ * UT-5d: "bd" selected + dolt present → bd init called, config written
44
+ * UT-5e: current config ≠ "auto" + user keeps → returns early (no QuickPick)
45
+ * UT-5f: "coming soon" item selected → info message, no config written
46
+ *
47
+ * Strategy:
48
+ * - Stub vscode.window.showQuickPick, showInformationMessage, showErrorMessage.
49
+ * - Stub vscode.workspace.getConfiguration.
50
+ * - Stub detectBackends from detectCli module.
51
+ * - Stub fs.promises.copyFile, mkdir, writeFile for file operations.
52
+ * - Stub runCli for the "bd init" call.
53
+ */
54
+ const assert = __importStar(require("assert"));
55
+ const fs = __importStar(require("fs"));
56
+ const os = __importStar(require("os"));
57
+ const path = __importStar(require("path"));
58
+ const sinon = __importStar(require("sinon"));
59
+ const vscode = __importStar(require("vscode"));
60
+ const initWizard_1 = require("../../commands/initWizard");
61
+ const detectCliModule = __importStar(require("../../utils/detectCli"));
62
+ const runCliModule = __importStar(require("../../utils/runCli"));
63
+ // ---------------------------------------------------------------------------
64
+ // Helpers
65
+ // ---------------------------------------------------------------------------
66
+ function makeContext(extensionPath) {
67
+ return { extensionPath };
68
+ }
69
+ const BACKENDS_ALL_PRESENT = {
70
+ bd: { name: 'bd', version: '1.2.3' },
71
+ pwsh: { name: 'pwsh', version: '7.4.0' },
72
+ powershell: { name: 'powershell', version: null },
73
+ dolt: { name: 'dolt', version: '1.0.0' },
74
+ };
75
+ const BACKENDS_NONE = {
76
+ bd: { name: 'bd', version: null },
77
+ pwsh: { name: 'pwsh', version: null },
78
+ powershell: { name: 'powershell', version: null },
79
+ dolt: { name: 'dolt', version: null },
80
+ };
81
+ // Build a minimal config stub that tracks update() calls.
82
+ function makeConfigStub(current = 'auto') {
83
+ const updateStub = sinon.stub().resolves();
84
+ const stub = sinon.stub(vscode.workspace, 'getConfiguration').returns({
85
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
+ get: (key, def) => key === 'beadsBackend' ? current : def,
87
+ update: updateStub,
88
+ });
89
+ return { stub, updateStub };
90
+ }
91
+ // ---------------------------------------------------------------------------
92
+ // Tests
93
+ // ---------------------------------------------------------------------------
94
+ suite('initWizard — unit tests', () => {
95
+ let tmpDir;
96
+ setup(() => {
97
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'augsdd-wiz-'));
98
+ sinon.stub(detectCliModule, 'detectBackends').resolves(BACKENDS_ALL_PRESENT);
99
+ sinon.stub(detectCliModule, 'formatDetectionSummary').returns('summary');
100
+ });
101
+ teardown(() => {
102
+ sinon.restore();
103
+ fs.rmSync(tmpDir, { recursive: true, force: true });
104
+ });
105
+ // UT-5a -------------------------------------------------------------------
106
+ test('UT-5a: QuickPick cancelled → no config.update called', async () => {
107
+ const { updateStub } = makeConfigStub();
108
+ sinon.stub(vscode.window, 'showQuickPick').resolves(undefined);
109
+ await (0, initWizard_1.initWizard)(makeContext(tmpDir), tmpDir);
110
+ assert.ok(!updateStub.called, 'config.update should NOT be called when QuickPick is cancelled');
111
+ });
112
+ // UT-5b -------------------------------------------------------------------
113
+ test('UT-5b: "beads-ps1" selected → scripts copied, config written', async () => {
114
+ const { updateStub } = makeConfigStub();
115
+ // Create fake bundled scripts in the extension path
116
+ const extScriptsDir = path.join(tmpDir, 'scripts');
117
+ fs.mkdirSync(extScriptsDir, { recursive: true });
118
+ fs.writeFileSync(path.join(extScriptsDir, 'beads-helpers.ps1'), '# stub');
119
+ fs.writeFileSync(path.join(extScriptsDir, 'beads-query.ps1'), '# stub');
120
+ // Workspace dir (separate subdir so no collision)
121
+ const wsDir = path.join(tmpDir, 'ws');
122
+ fs.mkdirSync(wsDir);
123
+ sinon.stub(vscode.window, 'showQuickPick').resolves({
124
+ label: 'PowerShell Beads', backendId: 'beads-ps1',
125
+ });
126
+ sinon.stub(vscode.window, 'showInformationMessage').resolves(undefined);
127
+ await (0, initWizard_1.initWizard)(makeContext(tmpDir), wsDir);
128
+ // Scripts should have been copied to wsDir/scripts/
129
+ assert.ok(fs.existsSync(path.join(wsDir, 'scripts', 'beads-helpers.ps1')), 'beads-helpers.ps1 should be copied to workspace');
130
+ assert.ok(fs.existsSync(path.join(wsDir, 'scripts', 'beads-query.ps1')), 'beads-query.ps1 should be copied to workspace');
131
+ // .beads/issues.jsonl should be created
132
+ assert.ok(fs.existsSync(path.join(wsDir, '.beads', 'issues.jsonl')), '.beads/issues.jsonl should be created');
133
+ assert.ok(updateStub.calledWith('beadsBackend', 'beads-ps1', vscode.ConfigurationTarget.Workspace), 'config.update should set beadsBackend to beads-ps1');
134
+ });
135
+ // UT-5c -------------------------------------------------------------------
136
+ test('UT-5c: "bd" selected + dolt absent → error shown, no config.update', async () => {
137
+ detectCliModule.detectBackends.resolves(BACKENDS_NONE);
138
+ const { updateStub } = makeConfigStub();
139
+ sinon.stub(vscode.window, 'showQuickPick').resolves({
140
+ label: 'Classic Beads', backendId: 'bd',
141
+ });
142
+ const errStub = sinon.stub(vscode.window, 'showErrorMessage').resolves(undefined);
143
+ await (0, initWizard_1.initWizard)(makeContext(tmpDir), tmpDir);
144
+ assert.ok(errStub.called, 'error message should be shown when dolt is absent');
145
+ assert.ok(!updateStub.called, 'config.update should NOT be called when dolt is absent');
146
+ });
147
+ // UT-5d -------------------------------------------------------------------
148
+ test('UT-5d: "bd" selected + dolt present → bd init called, config written', async () => {
149
+ const { updateStub } = makeConfigStub();
150
+ sinon.stub(vscode.window, 'showQuickPick').resolves({
151
+ label: 'Classic Beads', backendId: 'bd',
152
+ });
153
+ sinon.stub(vscode.window, 'showInformationMessage').resolves(undefined);
154
+ const runCliStub = sinon.stub(runCliModule, 'runCli').resolves('Initialized.');
155
+ await (0, initWizard_1.initWizard)(makeContext(tmpDir), tmpDir);
156
+ assert.ok(runCliStub.calledWith('bd', ['init'], tmpDir), 'runCli should call bd init with the workspace root');
157
+ assert.ok(updateStub.calledWith('beadsBackend', 'bd', vscode.ConfigurationTarget.Workspace), 'config.update should set beadsBackend to bd');
158
+ });
159
+ // UT-5e -------------------------------------------------------------------
160
+ test('UT-5e: existing non-auto config + user keeps → early return, no QuickPick', async () => {
161
+ makeConfigStub('beads-ps1'); // already configured
162
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
+ const infoStub = sinon.stub(vscode.window, 'showInformationMessage').resolves('Keep');
164
+ const qpStub = sinon.stub(vscode.window, 'showQuickPick');
165
+ await (0, initWizard_1.initWizard)(makeContext(tmpDir), tmpDir);
166
+ assert.ok(infoStub.called, 'info message should ask about existing config');
167
+ assert.ok(!qpStub.called, 'QuickPick should NOT be shown if user keeps current backend');
168
+ });
169
+ });
170
+ //# sourceMappingURL=initWizard.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initWizard.test.js","sourceRoot":"","sources":["../../../src/test/unit/initWizard.test.ts"],"names":[],"mappings":"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"}
@@ -38,10 +38,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
38
38
  * UT-1: resolves with trimmed stdout on exit code 0
39
39
  * UT-2: rejects on non-zero exit code
40
40
  * UT-3: rejects on timeout
41
+ *
42
+ * Strategy: use the injectable _spawn parameter so cp.spawn is never stubbed
43
+ * directly (which fails in the VS Code Electron environment because the
44
+ * property descriptor is non-configurable and non-writable).
41
45
  */
42
46
  const assert = __importStar(require("assert"));
43
- const cp = __importStar(require("child_process"));
44
- const sinon = __importStar(require("sinon"));
45
47
  const events_1 = require("events");
46
48
  const runCli_1 = require("../../utils/runCli");
47
49
  function fakeProc(opts) {
@@ -80,34 +82,19 @@ function fakeProc(opts) {
80
82
  // ---------------------------------------------------------------------------
81
83
  suite('runCli — unit tests', () => {
82
84
  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
- }
85
+ const fakeSpawn = () => fakeProc({ stdout: 'hello\n', code: 0 });
86
+ const result = await (0, runCli_1.runCli)('echo', ['hello'], '/tmp', 30000, undefined, true, fakeSpawn);
87
+ assert.strictEqual(result, 'hello');
91
88
  });
92
89
  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
- }
90
+ const fakeSpawn = () => fakeProc({ stdout: '', stderr: 'err', code: 1 });
91
+ await assert.rejects((0, runCli_1.runCli)('false', [], '/tmp', 30000, undefined, true, fakeSpawn), /failed with exit code 1/);
100
92
  });
101
93
  test('UT-3: rejects on timeout', async () => {
102
94
  // hangMs (5 000) >> timeoutMs (100) → timer fires first, process is killed,
103
95
  // 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
- }
96
+ const fakeSpawn = () => fakeProc({ hangMs: 5000, code: null });
97
+ await assert.rejects((0, runCli_1.runCli)('sleep', ['5'], '/tmp', 100, undefined, true, fakeSpawn), /timed out/i);
111
98
  });
112
99
  });
113
100
  //# sourceMappingURL=runCli.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runCli.test.js","sourceRoot":"","sources":["../../../src/test/unit/runCli.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runCli.test.js","sourceRoot":"","sources":["../../../src/test/unit/runCli.test.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.detectCli = detectCli;
4
+ exports.detectBackends = detectBackends;
5
+ exports.formatDetectionSummary = formatDetectionSummary;
4
6
  /**
5
- * detectCli — checks whether a CLI binary is accessible on the system PATH.
7
+ * detectCli — PATH presence check + concurrent multi-backend probing.
6
8
  *
7
9
  * Uses the platform-appropriate tool (where on Windows, which on Unix) via
8
10
  * runCli so that detection is non-interactive and consistent with all other
@@ -27,4 +29,48 @@ async function detectCli(name) {
27
29
  return false;
28
30
  }
29
31
  }
32
+ /**
33
+ * Probes bd, pwsh, powershell, and dolt in parallel (5 s timeout each).
34
+ * Each probe runs `<tool> --version`; any failure is recorded as version = null.
35
+ * Must never throw — safe to fire-and-forget on extension activation.
36
+ */
37
+ async function detectBackends() {
38
+ const TIMEOUT_MS = 5000;
39
+ async function probeVersion(name) {
40
+ try {
41
+ const out = await (0, runCli_1.runCli)(name, ['--version'], process.cwd(), TIMEOUT_MS);
42
+ const firstLine = out.split('\n')[0].trim();
43
+ return { name, version: firstLine || null };
44
+ }
45
+ catch {
46
+ return { name, version: null };
47
+ }
48
+ }
49
+ const [bd, pwsh, powershell, dolt] = await Promise.all([
50
+ probeVersion('bd'),
51
+ probeVersion('pwsh'),
52
+ probeVersion('powershell'),
53
+ probeVersion('dolt'),
54
+ ]);
55
+ return { bd, pwsh, powershell, dolt };
56
+ }
57
+ /**
58
+ * Formats a DetectionResult as a multi-line summary suitable for the Output Channel.
59
+ *
60
+ * Example output:
61
+ * Augment SDD: Detecting Beads backends...
62
+ * ✓ bd — [v1.4.2]
63
+ * ✓ pwsh — [7.4.1]
64
+ * ✗ powershell — not found
65
+ * ✗ dolt — not found
66
+ */
67
+ function formatDetectionSummary(result) {
68
+ const lines = ['Augment SDD: Detecting Beads backends...'];
69
+ for (const probe of [result.bd, result.pwsh, result.powershell, result.dolt]) {
70
+ const icon = probe.version ? ' ✓' : ' ✗';
71
+ const versionStr = probe.version ? `[${probe.version}]` : 'not found';
72
+ lines.push(`${icon} ${probe.name.padEnd(12)} — ${versionStr}`);
73
+ }
74
+ return lines.join('\n');
75
+ }
30
76
  //# sourceMappingURL=detectCli.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"detectCli.js","sourceRoot":"","sources":["../../src/utils/detectCli.ts"],"names":[],"mappings":";;AAeA,8BAWC;AA2BD,wCAqBC;AAYD,wDAQC;AA9FD;;;;;;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;AAsBD;;;;GAIG;AACI,KAAK,UAAU,cAAc;IAClC,MAAM,UAAU,GAAG,IAAK,CAAC;IAEzB,KAAK,UAAU,YAAY,CAAC,IAAY;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAA,eAAM,EAAC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;YACzE,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI,EAAE,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACrD,YAAY,CAAC,IAAI,CAAC;QAClB,YAAY,CAAC,MAAM,CAAC;QACpB,YAAY,CAAC,YAAY,CAAC;QAC1B,YAAY,CAAC,MAAM,CAAC;KACrB,CAAC,CAAC;IAEH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,sBAAsB,CAAC,MAAuB;IAC5D,MAAM,KAAK,GAAa,CAAC,0CAA0C,CAAC,CAAC;IACrE,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,GAAQ,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAChD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC;QACtE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,UAAU,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -56,15 +56,21 @@ const MAX_LOGGED_ARGS_CHARS = 500;
56
56
  * - Kill the process and reject with a timeout Error when `timeoutMs` elapses.
57
57
  * - Reject immediately if the spawn itself emits an error (e.g., ENOENT).
58
58
  *
59
- * @param command Executable name or path (passed to spawn with shell: true).
59
+ * @param command Executable name or path.
60
60
  * @param args Argument list. Prompt-like args are truncated in log output.
61
61
  * @param cwd Working directory for the spawned process.
62
62
  * @param timeoutMs Maximum allowed runtime in ms. Defaults to 120 000 ms.
63
63
  * @param logger Optional callback that receives structured log messages
64
64
  * (pre-run, result, timeout, spawn-error). Timestamps should
65
65
  * be added by the caller (e.g., the `log` helper in logger.ts).
66
+ * @param shell Whether to spawn via the OS shell (`shell: true`). Defaults
67
+ * to `true` for backward compatibility. Pass `false` when
68
+ * invoking `pwsh`/`powershell` directly so that Windows
69
+ * `cmd.exe` does not mangle script arguments.
66
70
  */
67
- function runCli(command, args, cwd, timeoutMs = 120000, logger) {
71
+ function runCli(command, args, cwd, timeoutMs = 120000, logger, shell = true,
72
+ /** Injectable spawn implementation — override in tests to avoid real processes. */
73
+ _spawn = cp.spawn) {
68
74
  // Log the invocation with args truncated to avoid flooding the Output Channel
69
75
  // with large Auggie prompts (spec: truncate prompt ≤ 500 chars in log entries).
70
76
  const rawArgs = args.join(' ');
@@ -73,7 +79,7 @@ function runCli(command, args, cwd, timeoutMs = 120000, logger) {
73
79
  : rawArgs;
74
80
  logger?.(`Run: ${command} ${displayArgs}`);
75
81
  return new Promise((resolve, reject) => {
76
- const proc = cp.spawn(command, args, { cwd, shell: true });
82
+ const proc = _spawn(command, args, { cwd, shell });
77
83
  let stdout = '';
78
84
  let stderr = '';
79
85
  let settled = false;
@@ -1 +1 @@
1
- {"version":3,"file":"runCli.js","sourceRoot":"","sources":["../../src/utils/runCli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runCli.js","sourceRoot":"","sources":["../../src/utils/runCli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "@mytechtoday/augment-sdd",
4
4
  "displayName": "Augment SDD",
5
5
  "description": "Automates the OpenSpec + Beads + Auggie pipeline (steps 5–7) for spec-driven development in VS Code.",
6
- "version": "1.0.0",
6
+ "version": "1.1.0",
7
7
  "publisher": "mytech-today-now",
8
8
  "engines": {
9
9
  "vscode": "^1.85.0"
@@ -15,6 +15,11 @@
15
15
  "onStartupFinished"
16
16
  ],
17
17
  "main": "./out/extension.js",
18
+ "files": [
19
+ "out/**",
20
+ "scripts/beads-helpers.ps1",
21
+ "scripts/beads-query.ps1"
22
+ ],
18
23
  "contributes": {
19
24
  "commands": [
20
25
  {
@@ -36,6 +41,11 @@
36
41
  "command": "augmentSdd.fullPipeline",
37
42
  "title": "Augment SDD: Run Full Pipeline",
38
43
  "category": "Augment SDD"
44
+ },
45
+ {
46
+ "command": "augmentSdd.init",
47
+ "title": "Augment SDD: Initialize / Configure Backend",
48
+ "category": "Augment SDD"
39
49
  }
40
50
  ],
41
51
  "configuration": {
@@ -62,6 +72,17 @@
62
72
  "type": "boolean",
63
73
  "default": true,
64
74
  "description": "Show the Augment SDD Webview dashboard after pipeline steps."
75
+ },
76
+ "augmentSdd.beadsBackend": {
77
+ "type": "string",
78
+ "enum": ["auto", "bd", "beads-ps1"],
79
+ "enumDescriptions": [
80
+ "Auto-detect: use bd if available on PATH, fall back to scripts/beads-query.ps1 in the workspace.",
81
+ "Always use the classic bd CLI (requires bd.exe + dolt on PATH).",
82
+ "Always use the PowerShell scripts in scripts/ (no external dependencies)."
83
+ ],
84
+ "default": "auto",
85
+ "description": "Which Beads backend to use for issue tracking. Run 'Augment SDD: Init' to configure."
65
86
  }
66
87
  }
67
88
  }
package/.eslintrc.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "root": true,
3
- "parser": "@typescript-eslint/parser",
4
- "parserOptions": {
5
- "ecmaVersion": 2020,
6
- "sourceType": "module"
7
- },
8
- "plugins": ["@typescript-eslint"],
9
- "extends": [
10
- "eslint:recommended",
11
- "plugin:@typescript-eslint/recommended"
12
- ],
13
- "rules": {
14
- "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
15
- "@typescript-eslint/explicit-function-return-type": "off",
16
- "@typescript-eslint/no-explicit-any": "warn"
17
- },
18
- "ignorePatterns": ["out", "node_modules"]
19
- }
20
-
@@ -1,153 +0,0 @@
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
-