@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.
- package/.eslintrc.json +20 -0
- package/out/commands/executeBeadsBatch.js +165 -0
- package/out/commands/executeBeadsBatch.js.map +1 -0
- package/out/commands/fullPipeline.js +129 -0
- package/out/commands/fullPipeline.js.map +1 -0
- package/out/commands/generateBeads.js +148 -0
- package/out/commands/generateBeads.js.map +1 -0
- package/out/commands/generateOpenSpec.js +241 -0
- package/out/commands/generateOpenSpec.js.map +1 -0
- package/out/dashboard/DashboardPanel.js +171 -0
- package/out/dashboard/DashboardPanel.js.map +1 -0
- package/out/extension.js +96 -0
- package/out/extension.js.map +1 -0
- package/out/parsers/parseBeadUpdates.js +28 -0
- package/out/parsers/parseBeadUpdates.js.map +1 -0
- package/out/parsers/parseTasksMarkdown.js +49 -0
- package/out/parsers/parseTasksMarkdown.js.map +1 -0
- package/out/test/integration/executeBeadsBatch.test.js +155 -0
- package/out/test/integration/executeBeadsBatch.test.js.map +1 -0
- package/out/test/integration/generateOpenSpec.test.js +154 -0
- package/out/test/integration/generateOpenSpec.test.js.map +1 -0
- package/out/test/runTest.js +47 -0
- package/out/test/runTest.js.map +1 -0
- package/out/test/suite/index.js +74 -0
- package/out/test/suite/index.js.map +1 -0
- package/out/test/unit/parseBeadUpdates.test.js +73 -0
- package/out/test/unit/parseBeadUpdates.test.js.map +1 -0
- package/out/test/unit/parseTasksMarkdown.test.js +69 -0
- package/out/test/unit/parseTasksMarkdown.test.js.map +1 -0
- package/out/test/unit/runCli.test.js +113 -0
- package/out/test/unit/runCli.test.js.map +1 -0
- package/out/utils/detectCli.js +30 -0
- package/out/utils/detectCli.js.map +1 -0
- package/out/utils/getConfig.js +60 -0
- package/out/utils/getConfig.js.map +1 -0
- package/out/utils/logger.js +30 -0
- package/out/utils/logger.js.map +1 -0
- package/out/utils/runCli.js +122 -0
- package/out/utils/runCli.js.map +1 -0
- package/package.json +111 -0
- package/src/commands/executeBeadsBatch.ts +153 -0
- package/src/commands/fullPipeline.ts +120 -0
- package/src/commands/generateBeads.ts +127 -0
- package/src/commands/generateOpenSpec.ts +227 -0
- package/src/dashboard/DashboardPanel.ts +168 -0
- package/src/extension.ts +77 -0
- package/src/parsers/parseBeadUpdates.ts +26 -0
- package/src/parsers/parseTasksMarkdown.ts +61 -0
- package/src/test/integration/executeBeadsBatch.test.ts +129 -0
- package/src/test/integration/generateOpenSpec.test.ts +129 -0
- package/src/test/runTest.ts +15 -0
- package/src/test/suite/index.ts +37 -0
- package/src/test/unit/parseBeadUpdates.test.ts +48 -0
- package/src/test/unit/parseTasksMarkdown.test.ts +41 -0
- package/src/test/unit/runCli.test.ts +109 -0
- package/src/utils/detectCli.ts +28 -0
- package/src/utils/getConfig.ts +25 -0
- package/src/utils/logger.ts +42 -0
- package/src/utils/runCli.ts +102 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* detectCli — checks whether a CLI binary is accessible on the system PATH.
|
|
3
|
+
*
|
|
4
|
+
* Uses the platform-appropriate tool (where on Windows, which on Unix) via
|
|
5
|
+
* runCli so that detection is non-interactive and consistent with all other
|
|
6
|
+
* CLI invocations in the extension.
|
|
7
|
+
*/
|
|
8
|
+
import { runCli } from './runCli';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Returns `true` if `name` resolves to an executable on the system PATH,
|
|
12
|
+
* `false` otherwise.
|
|
13
|
+
*
|
|
14
|
+
* @param name The CLI binary name to look up (e.g., "auggie", "openspec", "bd").
|
|
15
|
+
*/
|
|
16
|
+
export async function detectCli(name: string): Promise<boolean> {
|
|
17
|
+
// `where` (Windows) / `which` (Unix/macOS) exits 0 only when the binary is found.
|
|
18
|
+
const lookupCommand = process.platform === 'win32' ? 'where' : 'which';
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// Use the workspace root as cwd; any valid directory works for which/where.
|
|
22
|
+
await runCli(lookupCommand, [name], process.cwd(), 10_000);
|
|
23
|
+
return true;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* getConfig — type-safe VS Code settings reader for the Augment SDD extension.
|
|
3
|
+
*
|
|
4
|
+
* All extension settings live under the "augmentSdd" namespace as declared in
|
|
5
|
+
* package.json `contributes.configuration`. Callers provide a default value
|
|
6
|
+
* so they never receive `undefined` even when the setting is absent.
|
|
7
|
+
*
|
|
8
|
+
* Bead 9 wires this helper into every command; it is created here early so
|
|
9
|
+
* generateOpenSpec (Bead 5) and generateBeads (Bead 6) can use it immediately.
|
|
10
|
+
*/
|
|
11
|
+
import * as vscode from 'vscode';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Read a value from the `augmentSdd` configuration scope.
|
|
15
|
+
*
|
|
16
|
+
* @param key Setting key without the `augmentSdd.` prefix
|
|
17
|
+
* (e.g., `"jiraFolder"`, `"batchSize"`).
|
|
18
|
+
* @param defaultValue Returned when the setting is absent or undefined.
|
|
19
|
+
* @returns The configured value, or `defaultValue`.
|
|
20
|
+
*/
|
|
21
|
+
export function getConfig<T>(key: string, defaultValue: T): T {
|
|
22
|
+
const value = vscode.workspace.getConfiguration('augmentSdd').get<T>(key);
|
|
23
|
+
return value !== undefined ? value : defaultValue;
|
|
24
|
+
}
|
|
25
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* logger.ts — Centralised logging for the Augment SDD extension.
|
|
3
|
+
*
|
|
4
|
+
* Separating the logger from extension.ts avoids circular-import issues when
|
|
5
|
+
* command modules import `log` / `revealOutputChannel` while extension.ts
|
|
6
|
+
* imports from those same command modules.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* 1. In extension.ts activate(): call initLogger(channel) immediately after
|
|
10
|
+
* creating the OutputChannel.
|
|
11
|
+
* 2. Everywhere else: import { log, revealOutputChannel } from './logger'.
|
|
12
|
+
*/
|
|
13
|
+
import * as vscode from 'vscode';
|
|
14
|
+
|
|
15
|
+
/** The shared OutputChannel instance, set by initLogger(). */
|
|
16
|
+
let _channel: vscode.OutputChannel | undefined;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Initialise the logger with the extension's shared OutputChannel.
|
|
20
|
+
* Must be called once in activate() before any other logging.
|
|
21
|
+
*/
|
|
22
|
+
export function initLogger(channel: vscode.OutputChannel): void {
|
|
23
|
+
_channel = channel;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Append a timestamped message to the Augment SDD Output Channel.
|
|
28
|
+
* Safe to call before initLogger() — the message is silently dropped.
|
|
29
|
+
*/
|
|
30
|
+
export function log(message: string): void {
|
|
31
|
+
const ts = new Date().toISOString();
|
|
32
|
+
_channel?.appendLine(`[${ts}] ${message}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Reveal the Augment SDD Output Channel in the VS Code UI and bring it
|
|
37
|
+
* into focus without stealing the editor focus.
|
|
38
|
+
*/
|
|
39
|
+
export function revealOutputChannel(): void {
|
|
40
|
+
_channel?.show(true);
|
|
41
|
+
}
|
|
42
|
+
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* runCli — reusable child_process.spawn wrapper for all augment-sdd commands.
|
|
3
|
+
*
|
|
4
|
+
* Design (D1): Uses spawn (not exec) to avoid memory caps and to enable
|
|
5
|
+
* deterministic timeout handling. execa is intentionally excluded to keep the
|
|
6
|
+
* runtime dependency footprint at zero.
|
|
7
|
+
*
|
|
8
|
+
* Design (D2): Centralises timeout, error formatting, and logging. The optional
|
|
9
|
+
* `logger` callback receives structured messages before and after each call so
|
|
10
|
+
* callers can route them to the Augment SDD Output Channel without this module
|
|
11
|
+
* depending on VS Code APIs.
|
|
12
|
+
*/
|
|
13
|
+
import * as cp from 'child_process';
|
|
14
|
+
|
|
15
|
+
/** Maximum characters of the serialised args string written to the log. */
|
|
16
|
+
const MAX_LOGGED_ARGS_CHARS = 500;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Spawn `command` with `args` in `cwd`, collect stdout/stderr, and:
|
|
20
|
+
* - Resolve with trimmed stdout on exit code 0.
|
|
21
|
+
* - Reject with a descriptive Error on non-zero exit code.
|
|
22
|
+
* - Kill the process and reject with a timeout Error when `timeoutMs` elapses.
|
|
23
|
+
* - Reject immediately if the spawn itself emits an error (e.g., ENOENT).
|
|
24
|
+
*
|
|
25
|
+
* @param command Executable name or path (passed to spawn with shell: true).
|
|
26
|
+
* @param args Argument list. Prompt-like args are truncated in log output.
|
|
27
|
+
* @param cwd Working directory for the spawned process.
|
|
28
|
+
* @param timeoutMs Maximum allowed runtime in ms. Defaults to 120 000 ms.
|
|
29
|
+
* @param logger Optional callback that receives structured log messages
|
|
30
|
+
* (pre-run, result, timeout, spawn-error). Timestamps should
|
|
31
|
+
* be added by the caller (e.g., the `log` helper in logger.ts).
|
|
32
|
+
*/
|
|
33
|
+
export function runCli(
|
|
34
|
+
command: string,
|
|
35
|
+
args: string[],
|
|
36
|
+
cwd: string,
|
|
37
|
+
timeoutMs: number = 120_000,
|
|
38
|
+
logger?: (message: string) => void
|
|
39
|
+
): Promise<string> {
|
|
40
|
+
// Log the invocation with args truncated to avoid flooding the Output Channel
|
|
41
|
+
// with large Auggie prompts (spec: truncate prompt ≤ 500 chars in log entries).
|
|
42
|
+
const rawArgs = args.join(' ');
|
|
43
|
+
const displayArgs = rawArgs.length > MAX_LOGGED_ARGS_CHARS
|
|
44
|
+
? rawArgs.slice(0, MAX_LOGGED_ARGS_CHARS) + '…'
|
|
45
|
+
: rawArgs;
|
|
46
|
+
logger?.(`Run: ${command} ${displayArgs}`);
|
|
47
|
+
|
|
48
|
+
return new Promise<string>((resolve, reject) => {
|
|
49
|
+
const proc = cp.spawn(command, args, { cwd, shell: true });
|
|
50
|
+
|
|
51
|
+
let stdout = '';
|
|
52
|
+
let stderr = '';
|
|
53
|
+
let settled = false;
|
|
54
|
+
|
|
55
|
+
/** Settle the promise at most once. */
|
|
56
|
+
function settle(action: () => void): void {
|
|
57
|
+
if (settled) { return; }
|
|
58
|
+
settled = true;
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
action();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Enforce a hard timeout: kill the process and reject with a clear message.
|
|
64
|
+
const timer = setTimeout(() => {
|
|
65
|
+
settle(() => {
|
|
66
|
+
proc.kill();
|
|
67
|
+
const msg = `CLI "${command} ${args.join(' ')}" timed out after ${timeoutMs} ms`;
|
|
68
|
+
logger?.(`Timeout after ${timeoutMs} ms | ${command}`);
|
|
69
|
+
reject(new Error(msg));
|
|
70
|
+
});
|
|
71
|
+
}, timeoutMs);
|
|
72
|
+
|
|
73
|
+
proc.stdout.on('data', (data: Buffer) => { stdout += data; });
|
|
74
|
+
proc.stderr.on('data', (data: Buffer) => { stderr += data; });
|
|
75
|
+
|
|
76
|
+
proc.on('close', (code: number | null) => {
|
|
77
|
+
settle(() => {
|
|
78
|
+
if (code === 0) {
|
|
79
|
+
logger?.(`Exit 0 | stdout: ${stdout.trim()}`);
|
|
80
|
+
resolve(stdout.trim());
|
|
81
|
+
} else {
|
|
82
|
+
const stderrTrimmed = stderr.trim();
|
|
83
|
+
logger?.(`Exit ${code} | stderr: ${stderrTrimmed}`);
|
|
84
|
+
reject(
|
|
85
|
+
new Error(
|
|
86
|
+
`CLI "${command} ${args.join(' ')}" failed with exit code ${code}\nStderr: ${stderrTrimmed}`
|
|
87
|
+
)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Propagate spawn errors (e.g., ENOENT — binary not found) immediately.
|
|
94
|
+
proc.on('error', (err: Error) => {
|
|
95
|
+
settle(() => {
|
|
96
|
+
logger?.(`Spawn error: ${err.message}`);
|
|
97
|
+
reject(err);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"target": "ES2020",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"outDir": "./out",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"noImplicitReturns": true,
|
|
11
|
+
"noFallthroughCasesInSwitch": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"skipLibCheck": true
|
|
14
|
+
},
|
|
15
|
+
"include": ["src"],
|
|
16
|
+
"exclude": ["node_modules", ".vscode-test"]
|
|
17
|
+
}
|
|
18
|
+
|