@launch11/srgical 0.0.2 → 0.0.4
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/README.md +23 -5
- package/dist/core/agent.js +20 -1
- package/dist/core/augment.js +278 -0
- package/dist/ui/studio.js +14 -1
- package/docs/distribution.md +6 -6
- package/docs/product-foundation.md +1 -1
- package/docs/testing-strategy.md +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
3. repeatedly execute the next eligible step,
|
|
8
8
|
4. force validation and handoff updates every time.
|
|
9
9
|
|
|
10
|
-
The current launch slice supports
|
|
11
|
-
workflow. `srgical` detects which supported tools are actually installed, keeps the planning pack
|
|
12
|
-
lets you choose the active agent for the current workspace session.
|
|
10
|
+
The current launch slice supports local `codex`, local `claude`, and local `auggie` installs through the same
|
|
11
|
+
`.srgical/` workflow. `srgical` detects which supported tools are actually installed, keeps the planning pack
|
|
12
|
+
agent-neutral, and lets you choose the active agent for the current workspace session.
|
|
13
13
|
|
|
14
14
|
## Why This Exists
|
|
15
15
|
|
|
@@ -46,8 +46,11 @@ This repo currently ships the foundation for:
|
|
|
46
46
|
- `claude`
|
|
47
47
|
Supported through the same adapter seam for planning, pack writing, and execution when the local Claude Code CLI is
|
|
48
48
|
installed and available on `PATH`.
|
|
49
|
+
- `augment`
|
|
50
|
+
Supported through the same adapter seam by targeting the local `auggie` binary for planning, pack writing, and
|
|
51
|
+
execution when Augment CLI automation is available on the current machine.
|
|
49
52
|
|
|
50
|
-
If only one supported agent is installed, `srgical` can auto-select it for the workspace session. If
|
|
53
|
+
If only one supported agent is installed, `srgical` can auto-select it for the workspace session. If more than one is
|
|
51
54
|
installed, you can keep the stored choice in the studio and still override a single execution with
|
|
52
55
|
`srgical run-next --agent <id>`.
|
|
53
56
|
|
|
@@ -145,6 +148,7 @@ To override the active workspace agent for one execution only:
|
|
|
145
148
|
```bash
|
|
146
149
|
node dist/index.js run-next --agent codex
|
|
147
150
|
node dist/index.js run-next --agent claude
|
|
151
|
+
node dist/index.js run-next --agent augment
|
|
148
152
|
```
|
|
149
153
|
|
|
150
154
|
## Current Claude Caveat
|
|
@@ -155,8 +159,22 @@ uses `plan` mode for planner replies and `acceptEdits` with allowlisted local to
|
|
|
155
159
|
If the Claude CLI is not installed locally, `doctor`, the studio, and `run-next --agent claude` all report that
|
|
156
160
|
honestly instead of falling back to a fake Claude path.
|
|
157
161
|
|
|
162
|
+
## Current Augment Caveat
|
|
163
|
+
|
|
164
|
+
Augment support is wired to the documented `auggie` automation flags: `--print`, `--quiet`, `--instruction-file`,
|
|
165
|
+
`--workspace-root`, `--rules`, `--allow-indexing`, `--wait-for-indexing`, `--max-turns`, and `--ask` for planner-only
|
|
166
|
+
runs.
|
|
167
|
+
|
|
168
|
+
The defaults deliberately force workspace indexing and append srgical-specific Augment rules so the agent stays biased
|
|
169
|
+
toward incremental planning, validated execution, and clear next-step handoffs. Session history is also left on so
|
|
170
|
+
workspace iterations can accumulate inside Auggie instead of being treated as throwaway runs.
|
|
171
|
+
|
|
172
|
+
That means successful Augment execution still depends on a real Augment CLI install, an authenticated session such as
|
|
173
|
+
`auggie login` or `AUGMENT_SESSION_AUTH`, and whatever automation entitlements or local permission policies your
|
|
174
|
+
account requires.
|
|
175
|
+
|
|
158
176
|
## Planned Next Steps
|
|
159
177
|
|
|
160
178
|
- deepen the studio experience without weakening the terminal-first workflow
|
|
161
|
-
- keep
|
|
179
|
+
- keep multi-agent docs and validation honest as Claude and Augment runtime behavior get more live coverage
|
|
162
180
|
- expand release outputs from npm tarballs into standalone binaries and wrapper package-manager installers
|
package/dist/core/agent.js
CHANGED
|
@@ -12,6 +12,7 @@ exports.runNextPrompt = runNextPrompt;
|
|
|
12
12
|
exports.selectPrimaryAgent = selectPrimaryAgent;
|
|
13
13
|
exports.resetAgentAdaptersForTesting = resetAgentAdaptersForTesting;
|
|
14
14
|
exports.setAgentAdaptersForTesting = setAgentAdaptersForTesting;
|
|
15
|
+
const augment_1 = require("./augment");
|
|
15
16
|
const claude_1 = require("./claude");
|
|
16
17
|
const codex_1 = require("./codex");
|
|
17
18
|
const studio_session_1 = require("./studio-session");
|
|
@@ -51,7 +52,25 @@ const claudeAdapter = {
|
|
|
51
52
|
writePlanningPack: claude_1.writePlanningPack,
|
|
52
53
|
runNextPrompt: claude_1.runNextPrompt
|
|
53
54
|
};
|
|
54
|
-
const
|
|
55
|
+
const augmentAdapter = {
|
|
56
|
+
id: "augment",
|
|
57
|
+
label: "Augment CLI",
|
|
58
|
+
async detectStatus() {
|
|
59
|
+
const status = await (0, augment_1.detectAugment)();
|
|
60
|
+
return {
|
|
61
|
+
id: "augment",
|
|
62
|
+
label: "Augment CLI",
|
|
63
|
+
available: status.available,
|
|
64
|
+
command: status.command,
|
|
65
|
+
version: status.version,
|
|
66
|
+
error: status.error
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
requestPlannerReply: augment_1.requestPlannerReply,
|
|
70
|
+
writePlanningPack: augment_1.writePlanningPack,
|
|
71
|
+
runNextPrompt: augment_1.runNextPrompt
|
|
72
|
+
};
|
|
73
|
+
const defaultAgentAdapters = [codexAdapter, claudeAdapter, augmentAdapter];
|
|
55
74
|
let registeredAgentAdapters = [...defaultAgentAdapters];
|
|
56
75
|
let primaryAgentId = registeredAgentAdapters[0].id;
|
|
57
76
|
function getSupportedAgentAdapters() {
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.detectAugment = detectAugment;
|
|
7
|
+
exports.requestPlannerReply = requestPlannerReply;
|
|
8
|
+
exports.writePlanningPack = writePlanningPack;
|
|
9
|
+
exports.runNextPrompt = runNextPrompt;
|
|
10
|
+
exports.setAugmentRuntimeForTesting = setAugmentRuntimeForTesting;
|
|
11
|
+
exports.resetAugmentRuntimeForTesting = resetAugmentRuntimeForTesting;
|
|
12
|
+
const node_child_process_1 = require("node:child_process");
|
|
13
|
+
const promises_1 = require("node:fs/promises");
|
|
14
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
15
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const local_pack_1 = require("./local-pack");
|
|
17
|
+
const planning_epochs_1 = require("./planning-epochs");
|
|
18
|
+
const prompts_1 = require("./prompts");
|
|
19
|
+
const AUGMENT_INSTALL_HINT = "install Augment CLI to enable";
|
|
20
|
+
const AUGMENT_DEFAULT_RULES = `You are operating inside srgical, a local-first planning and iteration machine.
|
|
21
|
+
|
|
22
|
+
Default behavior:
|
|
23
|
+
- Ground decisions in the current repository state and the current .srgical files when they exist.
|
|
24
|
+
- Prefer small validated steps over broad speculative rewrites.
|
|
25
|
+
- Preserve a clear next-step handoff after each meaningful change.
|
|
26
|
+
- Treat planning as preparation for execution, not open-ended brainstorming.
|
|
27
|
+
- Keep outputs practical, explicit, and ready for the next iteration.`;
|
|
28
|
+
let augmentCommandPromise;
|
|
29
|
+
let forcedAugmentCommand = null;
|
|
30
|
+
let spawnAndCaptureImpl = spawnAndCaptureBase;
|
|
31
|
+
async function detectAugment() {
|
|
32
|
+
try {
|
|
33
|
+
const command = await resolveAugmentCommand();
|
|
34
|
+
const version = await spawnAndCaptureImpl(command, ["--version"], process.cwd());
|
|
35
|
+
return {
|
|
36
|
+
available: true,
|
|
37
|
+
command,
|
|
38
|
+
version: version.stdout.trim()
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return {
|
|
43
|
+
available: false,
|
|
44
|
+
command: process.platform === "win32" ? "auggie.exe" : "auggie",
|
|
45
|
+
error: normalizeAugmentDetectionError(error)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function requestPlannerReply(workspaceRoot, messages) {
|
|
50
|
+
const result = await runAugmentExec({
|
|
51
|
+
cwd: workspaceRoot,
|
|
52
|
+
prompt: (0, prompts_1.buildPlannerPrompt)(messages, workspaceRoot),
|
|
53
|
+
askMode: true,
|
|
54
|
+
maxTurns: 4
|
|
55
|
+
});
|
|
56
|
+
return result.lastMessage.trim();
|
|
57
|
+
}
|
|
58
|
+
async function writePlanningPack(workspaceRoot, messages) {
|
|
59
|
+
const planningEpoch = await (0, planning_epochs_1.preparePlanningPackForWrite)(workspaceRoot);
|
|
60
|
+
const augmentStatus = await detectAugment();
|
|
61
|
+
if (!augmentStatus.available) {
|
|
62
|
+
return appendPlanningEpochSummary(planningEpoch, await (0, local_pack_1.writePlanningPackFallback)(workspaceRoot, messages, augmentStatus.error ?? "Augment CLI is unavailable", "Augment CLI"));
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const result = await runAugmentExec({
|
|
66
|
+
cwd: workspaceRoot,
|
|
67
|
+
prompt: await (0, prompts_1.buildPackWriterPrompt)(messages, workspaceRoot),
|
|
68
|
+
maxTurns: 24
|
|
69
|
+
});
|
|
70
|
+
return appendPlanningEpochSummary(planningEpoch, result.lastMessage.trim());
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (isAugmentUnavailableError(error)) {
|
|
74
|
+
const message = error instanceof Error ? error.message : "Augment CLI is unavailable";
|
|
75
|
+
return appendPlanningEpochSummary(planningEpoch, await (0, local_pack_1.writePlanningPackFallback)(workspaceRoot, messages, message, "Augment CLI"));
|
|
76
|
+
}
|
|
77
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
78
|
+
const epochSummary = (0, planning_epochs_1.formatPlanningEpochSummary)(planningEpoch);
|
|
79
|
+
if (epochSummary) {
|
|
80
|
+
throw new Error(`${epochSummary}\n${message}`);
|
|
81
|
+
}
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function runNextPrompt(workspaceRoot, prompt) {
|
|
86
|
+
const result = await runAugmentExec({
|
|
87
|
+
cwd: workspaceRoot,
|
|
88
|
+
prompt,
|
|
89
|
+
maxTurns: 24
|
|
90
|
+
});
|
|
91
|
+
return result.lastMessage.trim();
|
|
92
|
+
}
|
|
93
|
+
function setAugmentRuntimeForTesting(options) {
|
|
94
|
+
if (Object.prototype.hasOwnProperty.call(options, "command")) {
|
|
95
|
+
forcedAugmentCommand = options.command ?? null;
|
|
96
|
+
augmentCommandPromise = undefined;
|
|
97
|
+
}
|
|
98
|
+
if (options.spawnAndCapture) {
|
|
99
|
+
spawnAndCaptureImpl = options.spawnAndCapture;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function resetAugmentRuntimeForTesting() {
|
|
103
|
+
forcedAugmentCommand = null;
|
|
104
|
+
augmentCommandPromise = undefined;
|
|
105
|
+
spawnAndCaptureImpl = spawnAndCaptureBase;
|
|
106
|
+
}
|
|
107
|
+
async function runAugmentExec(options) {
|
|
108
|
+
const tempDir = await (0, promises_1.mkdtemp)(node_path_1.default.join(node_os_1.default.tmpdir(), "srgical-augment-"));
|
|
109
|
+
const promptFile = node_path_1.default.join(tempDir, "prompt.txt");
|
|
110
|
+
const rulesFile = node_path_1.default.join(tempDir, "rules.md");
|
|
111
|
+
const command = await resolveAugmentCommand();
|
|
112
|
+
const args = [
|
|
113
|
+
"--print",
|
|
114
|
+
"--quiet",
|
|
115
|
+
"--workspace-root",
|
|
116
|
+
options.cwd,
|
|
117
|
+
"--instruction-file",
|
|
118
|
+
promptFile,
|
|
119
|
+
"--rules",
|
|
120
|
+
rulesFile,
|
|
121
|
+
"--allow-indexing",
|
|
122
|
+
"--wait-for-indexing"
|
|
123
|
+
];
|
|
124
|
+
if (options.askMode) {
|
|
125
|
+
args.push("--ask");
|
|
126
|
+
}
|
|
127
|
+
if (options.maxTurns) {
|
|
128
|
+
args.push("--max-turns", String(options.maxTurns));
|
|
129
|
+
}
|
|
130
|
+
await (0, promises_1.writeFile)(promptFile, options.prompt, "utf8");
|
|
131
|
+
await (0, promises_1.writeFile)(rulesFile, AUGMENT_DEFAULT_RULES, "utf8");
|
|
132
|
+
try {
|
|
133
|
+
const result = await spawnAndCaptureImpl(command, args, options.cwd);
|
|
134
|
+
return {
|
|
135
|
+
stdout: result.stdout,
|
|
136
|
+
stderr: result.stderr,
|
|
137
|
+
lastMessage: result.stdout.trim()
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
await (0, promises_1.rm)(tempDir, { recursive: true, force: true });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function resolveAugmentCommand() {
|
|
145
|
+
if (forcedAugmentCommand) {
|
|
146
|
+
return forcedAugmentCommand;
|
|
147
|
+
}
|
|
148
|
+
if (!augmentCommandPromise) {
|
|
149
|
+
augmentCommandPromise = loadAugmentCommand();
|
|
150
|
+
}
|
|
151
|
+
return augmentCommandPromise;
|
|
152
|
+
}
|
|
153
|
+
async function loadAugmentCommand() {
|
|
154
|
+
if (process.platform !== "win32") {
|
|
155
|
+
return "auggie";
|
|
156
|
+
}
|
|
157
|
+
const result = await spawnAndCaptureImpl("where.exe", ["auggie"], process.cwd());
|
|
158
|
+
const matches = result.stdout
|
|
159
|
+
.split(/\r?\n/)
|
|
160
|
+
.map((line) => line.trim())
|
|
161
|
+
.filter(Boolean);
|
|
162
|
+
const shim = matches.find((line) => {
|
|
163
|
+
const lower = line.toLowerCase();
|
|
164
|
+
return lower.endsWith(".cmd") || lower.endsWith(".bat");
|
|
165
|
+
});
|
|
166
|
+
if (shim) {
|
|
167
|
+
return shim;
|
|
168
|
+
}
|
|
169
|
+
const executable = matches.find((line) => line.toLowerCase().endsWith(".exe"));
|
|
170
|
+
if (executable) {
|
|
171
|
+
return executable;
|
|
172
|
+
}
|
|
173
|
+
for (const candidate of matches) {
|
|
174
|
+
const siblingShim = await resolveSiblingShim(candidate);
|
|
175
|
+
if (siblingShim) {
|
|
176
|
+
return siblingShim;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (matches.length > 0) {
|
|
180
|
+
return matches[0];
|
|
181
|
+
}
|
|
182
|
+
throw new Error("Unable to resolve an Augment executable path.");
|
|
183
|
+
}
|
|
184
|
+
function spawnAndCaptureBase(command, args, cwd, stdinText) {
|
|
185
|
+
return new Promise((resolve, reject) => {
|
|
186
|
+
const spec = buildSpawnSpec(command, args, cwd);
|
|
187
|
+
const child = (0, node_child_process_1.spawn)(spec.command, spec.args, spec.options);
|
|
188
|
+
let stdout = "";
|
|
189
|
+
let stderr = "";
|
|
190
|
+
child.stdout.on("data", (chunk) => {
|
|
191
|
+
stdout += chunk.toString();
|
|
192
|
+
});
|
|
193
|
+
child.stderr.on("data", (chunk) => {
|
|
194
|
+
stderr += chunk.toString();
|
|
195
|
+
});
|
|
196
|
+
child.on("error", reject);
|
|
197
|
+
child.on("close", (code) => {
|
|
198
|
+
if (code === 0) {
|
|
199
|
+
resolve({ stdout, stderr });
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
reject(new Error(stderr.trim() || stdout.trim() || `${command} exited with code ${code}`));
|
|
203
|
+
});
|
|
204
|
+
if (stdinText) {
|
|
205
|
+
child.stdin.write(stdinText);
|
|
206
|
+
}
|
|
207
|
+
child.stdin.end();
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function buildSpawnSpec(command, args, cwd) {
|
|
211
|
+
const lower = command.toLowerCase();
|
|
212
|
+
if (lower.endsWith(".cmd") || lower.endsWith(".bat")) {
|
|
213
|
+
const commandLine = [quoteForShell(command), ...args.map(quoteForShell)].join(" ");
|
|
214
|
+
return {
|
|
215
|
+
command: commandLine,
|
|
216
|
+
args: [],
|
|
217
|
+
options: {
|
|
218
|
+
cwd,
|
|
219
|
+
env: process.env,
|
|
220
|
+
shell: true
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
command,
|
|
226
|
+
args,
|
|
227
|
+
options: {
|
|
228
|
+
cwd,
|
|
229
|
+
env: process.env
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async function resolveSiblingShim(candidate) {
|
|
234
|
+
const extension = node_path_1.default.extname(candidate);
|
|
235
|
+
if (extension) {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
for (const suffix of [".cmd", ".bat", ".exe"]) {
|
|
239
|
+
const sibling = `${candidate}${suffix}`;
|
|
240
|
+
try {
|
|
241
|
+
await (0, promises_1.access)(sibling);
|
|
242
|
+
return sibling;
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
function quoteForShell(value) {
|
|
251
|
+
if (/^[A-Za-z0-9_:\\/.=-]+$/.test(value)) {
|
|
252
|
+
return value;
|
|
253
|
+
}
|
|
254
|
+
const escaped = value.replace(/"/g, '""');
|
|
255
|
+
return `"${escaped}"`;
|
|
256
|
+
}
|
|
257
|
+
function normalizeAugmentDetectionError(error) {
|
|
258
|
+
const message = error instanceof Error ? error.message : "Failed to run auggie";
|
|
259
|
+
const normalized = message.toLowerCase();
|
|
260
|
+
if (normalized.includes("could not find files for the given pattern") ||
|
|
261
|
+
normalized.includes("unable to resolve an augment executable path") ||
|
|
262
|
+
normalized.includes("'auggie' is not recognized") ||
|
|
263
|
+
normalized.includes("enoent")) {
|
|
264
|
+
return AUGMENT_INSTALL_HINT;
|
|
265
|
+
}
|
|
266
|
+
return message;
|
|
267
|
+
}
|
|
268
|
+
function isAugmentUnavailableError(error) {
|
|
269
|
+
const message = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
|
270
|
+
return (message.includes("unable to resolve an augment executable path") ||
|
|
271
|
+
message.includes("'auggie' is not recognized") ||
|
|
272
|
+
message.includes("enoent") ||
|
|
273
|
+
message.includes("failed to run auggie"));
|
|
274
|
+
}
|
|
275
|
+
function appendPlanningEpochSummary(preparation, summary) {
|
|
276
|
+
const epochSummary = (0, planning_epochs_1.formatPlanningEpochSummary)(preparation);
|
|
277
|
+
return [epochSummary, summary].filter(Boolean).join("\n");
|
|
278
|
+
}
|
package/dist/ui/studio.js
CHANGED
|
@@ -335,7 +335,7 @@ async function launchStudio(options = {}) {
|
|
|
335
335
|
await appendMessage({
|
|
336
336
|
role: "system",
|
|
337
337
|
content: [
|
|
338
|
-
|
|
338
|
+
buildAgentUsageMessage(),
|
|
339
339
|
"",
|
|
340
340
|
renderAgentSelectionMessage(agentState.status, agentState.statuses)
|
|
341
341
|
].join("\n")
|
|
@@ -650,6 +650,19 @@ function renderAgentSelectionMessage(activeAgent, statuses) {
|
|
|
650
650
|
...statuses.map((status) => formatAgentStatusLine(status, status.id === activeAgent.id))
|
|
651
651
|
].join("\n");
|
|
652
652
|
}
|
|
653
|
+
function buildAgentUsageMessage() {
|
|
654
|
+
const usages = (0, agent_1.getSupportedAgentAdapters)().map((adapter) => `\`/agent ${adapter.id}\``);
|
|
655
|
+
if (usages.length === 0) {
|
|
656
|
+
return "Usage: `/agent <id>`";
|
|
657
|
+
}
|
|
658
|
+
if (usages.length === 1) {
|
|
659
|
+
return `Usage: ${usages[0]}`;
|
|
660
|
+
}
|
|
661
|
+
if (usages.length === 2) {
|
|
662
|
+
return `Usage: ${usages[0]} or ${usages[1]}`;
|
|
663
|
+
}
|
|
664
|
+
return `Usage: ${usages.slice(0, -1).join(", ")}, or ${usages[usages.length - 1]}`;
|
|
665
|
+
}
|
|
653
666
|
function formatAgentStatusLine(status, selected) {
|
|
654
667
|
const prefix = selected ? "*" : "-";
|
|
655
668
|
const detail = status.available ? `ready (${status.version ?? "version unknown"})` : formatUnavailableAgentDetail(status);
|
package/docs/distribution.md
CHANGED
|
@@ -6,9 +6,9 @@ The current production release channels are GitHub Packages for npm, the public
|
|
|
6
6
|
Versioning is tag-driven from git history, which means the repo carries a base major/minor line and CI computes the
|
|
7
7
|
next patch version during release instead of committing a version bump back to `main`.
|
|
8
8
|
|
|
9
|
-
The npm package does not bundle `codex` or `
|
|
10
|
-
separately and available on `PATH`, and `srgical doctor` remains the truthful way to confirm which agents are
|
|
11
|
-
the current machine.
|
|
9
|
+
The npm package does not bundle `codex`, `claude`, or `auggie`. Users still need at least one supported local agent CLI
|
|
10
|
+
installed separately and available on `PATH`, and `srgical doctor` remains the truthful way to confirm which agents are
|
|
11
|
+
usable on the current machine.
|
|
12
12
|
|
|
13
13
|
## Release Flow
|
|
14
14
|
|
|
@@ -76,8 +76,8 @@ After installing the package, run:
|
|
|
76
76
|
srgical doctor
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
That verifies the workspace state, shows the active agent, and reports whether `codex` and `
|
|
80
|
-
available or missing.
|
|
79
|
+
That verifies the workspace state, shows the active agent, and reports whether `codex`, `claude`, and `auggie` are
|
|
80
|
+
locally available or missing.
|
|
81
81
|
|
|
82
82
|
## Artifact Strategy
|
|
83
83
|
|
|
@@ -96,7 +96,7 @@ npm install -g @launch11/srgical
|
|
|
96
96
|
|
|
97
97
|
- Required local prerequisites after install:
|
|
98
98
|
- authenticated access to GitHub Packages
|
|
99
|
-
- `codex` and/or `
|
|
99
|
+
- `codex`, `claude`, and/or `auggie` installed separately
|
|
100
100
|
- available on `PATH` for the current shell session
|
|
101
101
|
|
|
102
102
|
- Local install smoke test from a generated tarball:
|
|
@@ -27,7 +27,7 @@ time.
|
|
|
27
27
|
|
|
28
28
|
## V1 Scope
|
|
29
29
|
|
|
30
|
-
-
|
|
30
|
+
- Three launch-scope agent adapters: `codex`, `claude`, and `augment`
|
|
31
31
|
- One planning-pack format under `.srgical/`
|
|
32
32
|
- One full-screen TUI for planning conversation
|
|
33
33
|
- One execution command that runs the current next-step prompt through the active workspace agent
|
package/docs/testing-strategy.md
CHANGED
|
@@ -24,8 +24,9 @@ real bugs.
|
|
|
24
24
|
|
|
25
25
|
### Tier 3: Adapter and Agent behavior
|
|
26
26
|
|
|
27
|
-
- primary-agent status detection must degrade cleanly when
|
|
28
|
-
- planner, pack-writing, and execution adapters must preserve today's
|
|
27
|
+
- primary-agent status detection must degrade cleanly when any supported adapter is unavailable.
|
|
28
|
+
- planner, pack-writing, and execution adapters must preserve today's multi-agent behavior across Codex, Claude Code,
|
|
29
|
+
and Augment CLI.
|
|
29
30
|
- Windows command resolution and shell-shim launching must stay covered because that path has already broken once.
|
|
30
31
|
|
|
31
32
|
### Tier 4: Release confidence
|