@launch11/srgical 0.0.5 → 0.0.7
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 +19 -7
- package/dist/commands/doctor.js +60 -13
- package/dist/commands/init.js +10 -6
- package/dist/commands/run-next.js +41 -8
- package/dist/commands/studio.js +2 -2
- package/dist/core/agent.js +19 -19
- package/dist/core/augment.js +7 -7
- package/dist/core/auto-run-state.js +89 -0
- package/dist/core/auto-run.js +270 -0
- package/dist/core/claude.js +7 -7
- package/dist/core/codex.js +7 -7
- package/dist/core/execution-state.js +5 -5
- package/dist/core/local-pack.js +9 -6
- package/dist/core/planning-epochs.js +10 -3
- package/dist/core/planning-pack-state.js +132 -9
- package/dist/core/planning-state.js +61 -0
- package/dist/core/prompts.js +4 -4
- package/dist/core/studio-session.js +14 -14
- package/dist/core/templates.js +13 -10
- package/dist/core/workspace.js +127 -8
- package/dist/index.js +18 -6
- package/dist/ui/studio.js +329 -193
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,20 +30,20 @@ This repo currently ships the foundation for:
|
|
|
30
30
|
- `srgical --version`
|
|
31
31
|
Prints the installed version with release-note links instead of only echoing the semver.
|
|
32
32
|
- `srgical doctor`
|
|
33
|
-
Reports
|
|
34
|
-
|
|
33
|
+
Reports the active plan, plan readiness, execution state, auto-run state, and which supported agents are available
|
|
34
|
+
locally.
|
|
35
35
|
- `srgical about`
|
|
36
36
|
Shows package details, release links, and the currently supported agent adapters.
|
|
37
37
|
- `srgical changelog`
|
|
38
38
|
Points straight at the installed version's release notes and the local packaged changelog.
|
|
39
39
|
- `srgical init`
|
|
40
|
-
Creates a local `.srgical/` planning pack from built-in templates.
|
|
40
|
+
Creates a local `.srgical/` planning pack from built-in templates, with `--plan <id>` for named plans.
|
|
41
41
|
- `srgical studio`
|
|
42
|
-
Opens a full-screen planning studio where you can
|
|
43
|
-
|
|
42
|
+
Opens a full-screen planning studio where you can switch between named plans, inspect readiness with `/readiness`,
|
|
43
|
+
inspect supported tools with `/agents`, and explicitly trigger pack writes, single-step execution, or `/auto`.
|
|
44
44
|
- `srgical run-next`
|
|
45
|
-
Replays the generated next-agent prompt through the active agent, with `--
|
|
46
|
-
`--agent <id>` for a one-run override
|
|
45
|
+
Replays the generated next-agent prompt through the active agent, with `--plan <id>` for plan targeting,
|
|
46
|
+
`--dry-run` for safe preview, `--agent <id>` for a one-run override, and `--auto` for bounded multi-step execution.
|
|
47
47
|
|
|
48
48
|
## Supported Agents
|
|
49
49
|
|
|
@@ -148,8 +148,11 @@ node dist/index.js --version
|
|
|
148
148
|
node dist/index.js about
|
|
149
149
|
node dist/index.js doctor
|
|
150
150
|
node dist/index.js changelog
|
|
151
|
+
node dist/index.js init --plan release-readiness
|
|
152
|
+
node dist/index.js studio --plan release-readiness
|
|
151
153
|
node dist/index.js run-next --dry-run
|
|
152
154
|
node dist/index.js run-next
|
|
155
|
+
node dist/index.js run-next --auto --max-steps 10
|
|
153
156
|
```
|
|
154
157
|
|
|
155
158
|
To override the active workspace agent for one execution only:
|
|
@@ -160,6 +163,15 @@ node dist/index.js run-next --agent claude
|
|
|
160
163
|
node dist/index.js run-next --agent augment
|
|
161
164
|
```
|
|
162
165
|
|
|
166
|
+
Inside the studio, the footer is intentionally minimal:
|
|
167
|
+
|
|
168
|
+
- `PgUp/PgDn` scrolls the transcript
|
|
169
|
+
- `/agents` chooses the current tool
|
|
170
|
+
- `/help` shows the full command set
|
|
171
|
+
|
|
172
|
+
The composer is now multiline with a minimum two-line visible input area. `Enter` sends, while `Shift+Enter`,
|
|
173
|
+
`Alt+Enter`, or `Ctrl+J` inserts a newline when the terminal exposes those keys distinctly.
|
|
174
|
+
|
|
163
175
|
## Current Claude Caveat
|
|
164
176
|
|
|
165
177
|
Claude support is real, but it is not treated as interchangeable with Codex. The current non-interactive Claude path
|
package/dist/commands/doctor.js
CHANGED
|
@@ -8,30 +8,43 @@ const node_process_1 = __importDefault(require("node:process"));
|
|
|
8
8
|
const agent_1 = require("../core/agent");
|
|
9
9
|
const planning_pack_state_1 = require("../core/planning-pack-state");
|
|
10
10
|
const workspace_1 = require("../core/workspace");
|
|
11
|
-
async function runDoctorCommand(workspaceArg) {
|
|
11
|
+
async function runDoctorCommand(workspaceArg, options = {}) {
|
|
12
12
|
const workspace = (0, workspace_1.resolveWorkspace)(workspaceArg);
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
(0,
|
|
16
|
-
(0, workspace_1.isGitRepo)(workspace)
|
|
13
|
+
const selectedPlanId = await (0, workspace_1.resolvePlanId)(workspace, options.planId);
|
|
14
|
+
const [resolvedAgent, gitRepo, planRefs, selectedPlanState] = await Promise.all([
|
|
15
|
+
(0, agent_1.resolvePrimaryAgent)(workspace, { planId: selectedPlanId }),
|
|
16
|
+
(0, workspace_1.isGitRepo)(workspace),
|
|
17
|
+
(0, workspace_1.listPlanningDirectories)(workspace),
|
|
18
|
+
(0, planning_pack_state_1.readPlanningPackState)(workspace, { planId: selectedPlanId })
|
|
17
19
|
]);
|
|
18
20
|
const { status: activeAgent, statuses } = resolvedAgent;
|
|
19
21
|
const lines = [
|
|
20
22
|
`Workspace: ${workspace}`,
|
|
21
23
|
`Git repo: ${gitRepo ? "yes" : "no"}`,
|
|
22
|
-
`
|
|
24
|
+
`Active plan: ${selectedPlanId}`,
|
|
23
25
|
`Active agent: ${activeAgent.label} (${activeAgent.id}) - ${formatAgentAvailability(activeAgent)}`,
|
|
24
26
|
"",
|
|
25
27
|
...renderSupportedAgentLines(statuses, activeAgent.id),
|
|
28
|
+
"",
|
|
29
|
+
"Plans:"
|
|
26
30
|
];
|
|
27
|
-
if (
|
|
28
|
-
lines.push(
|
|
31
|
+
if (planRefs.length === 0) {
|
|
32
|
+
lines.push(`- ${workspace_1.DEFAULT_PLAN_ID}: no planning packs detected yet`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const planStates = await Promise.all(planRefs.map((ref) => (0, planning_pack_state_1.readPlanningPackState)(workspace, { planId: ref.planId })));
|
|
36
|
+
for (const state of planStates) {
|
|
37
|
+
lines.push(renderPlanSummaryLine(state, state.planId === selectedPlanId));
|
|
38
|
+
}
|
|
29
39
|
}
|
|
30
|
-
lines.push("",
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
lines.push("", `Selected plan details (${selectedPlanId}):`, ...renderPlanDetailLines(selectedPlanState));
|
|
41
|
+
lines.push("", selectedPlanState.packPresent
|
|
42
|
+
? selectedPlanState.mode === "Ready to Write" || selectedPlanState.mode === "Gathering Context"
|
|
43
|
+
? "Next move: run `srgical studio` to refine the plan, check `/readiness`, and use `/write` when it is ready."
|
|
44
|
+
: selectedPlanState.mode === "Ready to Execute" || selectedPlanState.mode === "Execution Active" || selectedPlanState.mode === "Auto Running"
|
|
45
|
+
? "Next move: run `srgical run-next --plan <id>` for one step or `srgical run-next --plan <id> --auto` to continue automatically."
|
|
46
|
+
: "Next move: run `srgical studio` to queue or refine the next execution-ready step."
|
|
47
|
+
: "Next move: run `srgical init --plan <id>` for a scaffold or `srgical studio --plan <id>` to start planning.");
|
|
35
48
|
node_process_1.default.stdout.write(`${lines.join("\n")}\n`);
|
|
36
49
|
}
|
|
37
50
|
function renderSupportedAgentLines(statuses, activeAgentId) {
|
|
@@ -41,11 +54,45 @@ function renderSupportedAgentLines(statuses, activeAgentId) {
|
|
|
41
54
|
}
|
|
42
55
|
return lines;
|
|
43
56
|
}
|
|
57
|
+
function renderPlanSummaryLine(state, selected) {
|
|
58
|
+
return [
|
|
59
|
+
`- ${state.planId}${selected ? " [active]" : ""}:`,
|
|
60
|
+
`path ${state.packDir}`,
|
|
61
|
+
`mode ${state.mode}`,
|
|
62
|
+
`docs ${state.docsPresent}/4`,
|
|
63
|
+
`readiness ${state.readiness.score}/${state.readiness.total}`,
|
|
64
|
+
`execution ${state.executionActivated ? "started" : "not-started"}`,
|
|
65
|
+
`auto ${state.autoRun?.status ?? "idle"}`
|
|
66
|
+
].join(" | ");
|
|
67
|
+
}
|
|
44
68
|
function formatAgentAvailability(status) {
|
|
45
69
|
return status.available
|
|
46
70
|
? `available (${status.version ?? "version unknown"})`
|
|
47
71
|
: `missing (${status.error ?? "unknown error"})`;
|
|
48
72
|
}
|
|
73
|
+
function renderPlanDetailLines(state) {
|
|
74
|
+
const lines = [
|
|
75
|
+
`Plan dir: ${state.packDir}`,
|
|
76
|
+
`Pack present: ${state.packPresent ? "yes" : "no"}`,
|
|
77
|
+
`Pack mode: ${state.packMode}`,
|
|
78
|
+
`Mode: ${state.mode}${state.hasFailureOverlay ? " [last run failed]" : ""}`,
|
|
79
|
+
`Docs present: ${state.docsPresent}/4`,
|
|
80
|
+
`Readiness: ${state.readiness.score}/${state.readiness.total}${state.readiness.readyToWrite ? " (ready to write)" : ""}`,
|
|
81
|
+
`Execution activated: ${state.executionActivated ? "yes" : "no"}`,
|
|
82
|
+
`Auto mode: ${state.autoRun?.status ?? "idle"}`
|
|
83
|
+
];
|
|
84
|
+
if (state.readiness.missingLabels.length > 0) {
|
|
85
|
+
lines.push(`Missing readiness signals: ${state.readiness.missingLabels.join(", ")}`);
|
|
86
|
+
}
|
|
87
|
+
lines.push(...renderNextStepLines(state.nextStepSummary, state.currentPosition.nextRecommended));
|
|
88
|
+
if (state.lastExecution) {
|
|
89
|
+
lines.push(`Last run: ${state.lastExecution.status} via ${state.lastExecution.source} at ${state.lastExecution.updatedAt}`);
|
|
90
|
+
}
|
|
91
|
+
if (state.autoRun) {
|
|
92
|
+
lines.push(`Auto run detail: attempted ${state.autoRun.stepsAttempted}${state.autoRun.maxSteps ? `/${state.autoRun.maxSteps}` : ""}, stop reason ${state.autoRun.stopReason ?? "none"}`);
|
|
93
|
+
}
|
|
94
|
+
return lines;
|
|
95
|
+
}
|
|
49
96
|
function renderNextStepLines(nextStepSummary, nextRecommended) {
|
|
50
97
|
if (!nextStepSummary) {
|
|
51
98
|
return [
|
package/dist/commands/init.js
CHANGED
|
@@ -5,22 +5,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.runInitCommand = runInitCommand;
|
|
7
7
|
const node_process_1 = __importDefault(require("node:process"));
|
|
8
|
+
const planning_state_1 = require("../core/planning-state");
|
|
8
9
|
const templates_1 = require("../core/templates");
|
|
9
10
|
const workspace_1 = require("../core/workspace");
|
|
10
|
-
async function runInitCommand(workspaceArg, force = false) {
|
|
11
|
+
async function runInitCommand(workspaceArg, force = false, planId) {
|
|
11
12
|
const workspace = (0, workspace_1.resolveWorkspace)(workspaceArg);
|
|
12
|
-
const exists = await (0, workspace_1.planningPackExists)(workspace);
|
|
13
|
+
const exists = await (0, workspace_1.planningPackExists)(workspace, { planId });
|
|
13
14
|
if (exists && !force) {
|
|
14
|
-
throw new Error("A
|
|
15
|
+
throw new Error("A planning pack already exists for the selected plan. Re-run with --force to overwrite it.");
|
|
15
16
|
}
|
|
16
|
-
const paths = await (0, workspace_1.ensurePlanningDir)(workspace);
|
|
17
|
+
const paths = await (0, workspace_1.ensurePlanningDir)(workspace, { planId });
|
|
17
18
|
const templates = (0, templates_1.getInitialTemplates)(paths);
|
|
18
19
|
await Promise.all(Object.entries(templates).map(([filePath, content]) => (0, workspace_1.writeText)(filePath, content)));
|
|
20
|
+
await (0, planning_state_1.savePlanningState)(workspace, "scaffolded", { planId: paths.planId });
|
|
21
|
+
await (0, workspace_1.saveActivePlanId)(workspace, paths.planId);
|
|
19
22
|
node_process_1.default.stdout.write([
|
|
20
|
-
`Created planning pack in ${paths.dir}`,
|
|
23
|
+
`Created planning pack for plan \`${paths.planId}\` in ${paths.dir}`,
|
|
21
24
|
`- ${paths.plan}`,
|
|
22
25
|
`- ${paths.context}`,
|
|
23
26
|
`- ${paths.tracker}`,
|
|
24
|
-
`- ${paths.nextPrompt}
|
|
27
|
+
`- ${paths.nextPrompt}`,
|
|
28
|
+
`Next: run \`srgical doctor --plan ${paths.planId}\` or open \`srgical studio --plan ${paths.planId}\`.`
|
|
25
29
|
].join("\n") + "\n");
|
|
26
30
|
}
|
|
@@ -5,23 +5,53 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.runRunNextCommand = runRunNextCommand;
|
|
7
7
|
const node_process_1 = __importDefault(require("node:process"));
|
|
8
|
+
const auto_run_1 = require("../core/auto-run");
|
|
8
9
|
const agent_1 = require("../core/agent");
|
|
9
10
|
const execution_state_1 = require("../core/execution-state");
|
|
10
11
|
const execution_controls_1 = require("../core/execution-controls");
|
|
11
12
|
const planning_pack_state_1 = require("../core/planning-pack-state");
|
|
12
13
|
const workspace_1 = require("../core/workspace");
|
|
14
|
+
const workspace_2 = require("../core/workspace");
|
|
13
15
|
async function runRunNextCommand(workspaceArg, options = {}) {
|
|
14
|
-
const workspace = (0,
|
|
15
|
-
const
|
|
16
|
+
const workspace = (0, workspace_2.resolveWorkspace)(workspaceArg);
|
|
17
|
+
const planId = await (0, workspace_1.resolvePlanId)(workspace, options.planId);
|
|
18
|
+
const packState = await (0, planning_pack_state_1.readPlanningPackState)(workspace, { planId });
|
|
16
19
|
if (!packState.packPresent) {
|
|
17
20
|
throw new Error("No .srgical planning pack found. Run `srgical init` or `srgical studio` first.");
|
|
18
21
|
}
|
|
22
|
+
if (options.auto && options.dryRun) {
|
|
23
|
+
throw new Error("`--auto` cannot be combined with `--dry-run`.");
|
|
24
|
+
}
|
|
19
25
|
if (!options.dryRun && !(0, execution_controls_1.hasQueuedNextStep)(packState.currentPosition.nextRecommended)) {
|
|
20
26
|
throw new Error((0, execution_controls_1.formatNoQueuedNextStepMessage)("run-next"));
|
|
21
27
|
}
|
|
22
|
-
await (0, agent_1.resolveExecutionAgent)(workspace, options.agent);
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
await (0, agent_1.resolveExecutionAgent)(workspace, options.agent, { planId });
|
|
29
|
+
await (0, workspace_1.saveActivePlanId)(workspace, planId);
|
|
30
|
+
if (options.auto) {
|
|
31
|
+
const stopHandler = () => {
|
|
32
|
+
void (0, auto_run_1.requestAutoRunStop)(workspace, { planId });
|
|
33
|
+
node_process_1.default.stdout.write("Stop requested. Auto mode will finish the current iteration before stopping.\n");
|
|
34
|
+
};
|
|
35
|
+
node_process_1.default.once("SIGINT", stopHandler);
|
|
36
|
+
try {
|
|
37
|
+
const result = await (0, auto_run_1.executeAutoRun)(workspace, {
|
|
38
|
+
source: "run-next",
|
|
39
|
+
planId,
|
|
40
|
+
agentId: options.agent,
|
|
41
|
+
maxSteps: options.maxSteps,
|
|
42
|
+
onMessage: (line) => {
|
|
43
|
+
node_process_1.default.stdout.write(`${line}\n`);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
node_process_1.default.stdout.write(`${result.summary}\n`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
node_process_1.default.removeListener("SIGINT", stopHandler);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const paths = (0, workspace_2.getPlanningPackPaths)(workspace, { planId });
|
|
54
|
+
const prompt = await (0, workspace_2.readText)(paths.nextPrompt);
|
|
25
55
|
const previewLines = options.dryRun
|
|
26
56
|
? (0, execution_controls_1.renderDryRunPreview)(prompt, packState.nextStepSummary, packState.currentPosition.nextRecommended)
|
|
27
57
|
: (0, execution_controls_1.renderExecutionStepLines)(packState.nextStepSummary, packState.currentPosition.nextRecommended);
|
|
@@ -35,18 +65,21 @@ async function runRunNextCommand(workspaceArg, options = {}) {
|
|
|
35
65
|
node_process_1.default.stdout.write(`Running the current next-agent prompt through ${(0, agent_1.getPrimaryAgentAdapter)().label}...\n`);
|
|
36
66
|
try {
|
|
37
67
|
const result = await (0, agent_1.runNextPrompt)(workspace, prompt, {
|
|
38
|
-
agentId: options.agent
|
|
68
|
+
agentId: options.agent,
|
|
69
|
+
planId
|
|
39
70
|
});
|
|
40
|
-
await (0, execution_state_1.saveExecutionState)(workspace, "success", "run-next", result);
|
|
71
|
+
await (0, execution_state_1.saveExecutionState)(workspace, "success", "run-next", result, { planId });
|
|
41
72
|
await (0, execution_state_1.appendExecutionLog)(workspace, "success", "run-next", result, {
|
|
73
|
+
planId,
|
|
42
74
|
stepLabel: (0, execution_controls_1.formatStepLabel)(packState.nextStepSummary, packState.currentPosition.nextRecommended)
|
|
43
75
|
});
|
|
44
76
|
node_process_1.default.stdout.write(`${result}\n`);
|
|
45
77
|
}
|
|
46
78
|
catch (error) {
|
|
47
79
|
const message = error instanceof Error ? error.message : String(error);
|
|
48
|
-
await (0, execution_state_1.saveExecutionState)(workspace, "failure", "run-next", message);
|
|
80
|
+
await (0, execution_state_1.saveExecutionState)(workspace, "failure", "run-next", message, { planId });
|
|
49
81
|
await (0, execution_state_1.appendExecutionLog)(workspace, "failure", "run-next", message, {
|
|
82
|
+
planId,
|
|
50
83
|
stepLabel: (0, execution_controls_1.formatStepLabel)(packState.nextStepSummary, packState.currentPosition.nextRecommended)
|
|
51
84
|
});
|
|
52
85
|
throw new Error((0, execution_controls_1.formatExecutionFailureMessage)(message, packState.nextStepSummary, packState.currentPosition.nextRecommended, "run-next"));
|
package/dist/commands/studio.js
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.runStudioCommand = runStudioCommand;
|
|
4
4
|
const studio_1 = require("../ui/studio");
|
|
5
|
-
async function runStudioCommand(workspaceArg) {
|
|
6
|
-
await (0, studio_1.launchStudio)({ workspace: workspaceArg });
|
|
5
|
+
async function runStudioCommand(workspaceArg, options = {}) {
|
|
6
|
+
await (0, studio_1.launchStudio)({ workspace: workspaceArg, planId: options.planId });
|
|
7
7
|
}
|
package/dist/core/agent.js
CHANGED
|
@@ -84,9 +84,9 @@ async function detectSupportedAgents(workspaceRoot) {
|
|
|
84
84
|
syncPrimaryAgent((await resolvePrimaryAgentStatus(statuses, workspaceRoot)).id);
|
|
85
85
|
return statuses;
|
|
86
86
|
}
|
|
87
|
-
async function resolvePrimaryAgent(workspaceRoot) {
|
|
87
|
+
async function resolvePrimaryAgent(workspaceRoot, options = {}) {
|
|
88
88
|
const statuses = await collectAgentStatuses();
|
|
89
|
-
const status = await resolvePrimaryAgentStatus(statuses, workspaceRoot);
|
|
89
|
+
const status = await resolvePrimaryAgentStatus(statuses, workspaceRoot, options);
|
|
90
90
|
const adapter = getAgentAdapterById(status.id) ?? getSupportedAgentAdapters()[0];
|
|
91
91
|
syncPrimaryAgent(adapter.id);
|
|
92
92
|
return {
|
|
@@ -95,13 +95,13 @@ async function resolvePrimaryAgent(workspaceRoot) {
|
|
|
95
95
|
statuses
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
-
async function detectPrimaryAgent(workspaceRoot) {
|
|
99
|
-
return (await resolvePrimaryAgent(workspaceRoot)).status;
|
|
98
|
+
async function detectPrimaryAgent(workspaceRoot, options = {}) {
|
|
99
|
+
return (await resolvePrimaryAgent(workspaceRoot, options)).status;
|
|
100
100
|
}
|
|
101
|
-
async function resolveExecutionAgent(workspaceRoot, overrideId) {
|
|
101
|
+
async function resolveExecutionAgent(workspaceRoot, overrideId, options = {}) {
|
|
102
102
|
const normalizedOverrideId = overrideId?.trim().toLowerCase();
|
|
103
103
|
if (!normalizedOverrideId) {
|
|
104
|
-
return resolvePrimaryAgent(workspaceRoot);
|
|
104
|
+
return resolvePrimaryAgent(workspaceRoot, options);
|
|
105
105
|
}
|
|
106
106
|
const statuses = await collectAgentStatuses();
|
|
107
107
|
const status = statuses.find((candidate) => candidate.id === normalizedOverrideId);
|
|
@@ -119,19 +119,19 @@ async function resolveExecutionAgent(workspaceRoot, overrideId) {
|
|
|
119
119
|
statuses
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
|
-
async function requestPlannerReply(workspaceRoot, messages) {
|
|
123
|
-
const { adapter } = await resolvePrimaryAgent(workspaceRoot);
|
|
124
|
-
return adapter.requestPlannerReply(workspaceRoot, messages);
|
|
122
|
+
async function requestPlannerReply(workspaceRoot, messages, options = {}) {
|
|
123
|
+
const { adapter } = await resolvePrimaryAgent(workspaceRoot, options);
|
|
124
|
+
return adapter.requestPlannerReply(workspaceRoot, messages, options);
|
|
125
125
|
}
|
|
126
|
-
async function writePlanningPack(workspaceRoot, messages) {
|
|
127
|
-
const { adapter } = await resolvePrimaryAgent(workspaceRoot);
|
|
128
|
-
return adapter.writePlanningPack(workspaceRoot, messages);
|
|
126
|
+
async function writePlanningPack(workspaceRoot, messages, options = {}) {
|
|
127
|
+
const { adapter } = await resolvePrimaryAgent(workspaceRoot, options);
|
|
128
|
+
return adapter.writePlanningPack(workspaceRoot, messages, options);
|
|
129
129
|
}
|
|
130
130
|
async function runNextPrompt(workspaceRoot, prompt, options = {}) {
|
|
131
|
-
const { adapter } = await resolveExecutionAgent(workspaceRoot, options.agentId);
|
|
132
|
-
return adapter.runNextPrompt(workspaceRoot, prompt);
|
|
131
|
+
const { adapter } = await resolveExecutionAgent(workspaceRoot, options.agentId, { planId: options.planId });
|
|
132
|
+
return adapter.runNextPrompt(workspaceRoot, prompt, { planId: options.planId });
|
|
133
133
|
}
|
|
134
|
-
async function selectPrimaryAgent(workspaceRoot, id) {
|
|
134
|
+
async function selectPrimaryAgent(workspaceRoot, id, options = {}) {
|
|
135
135
|
const normalizedId = id.trim().toLowerCase();
|
|
136
136
|
const statuses = await collectAgentStatuses();
|
|
137
137
|
const status = statuses.find((candidate) => candidate.id === normalizedId);
|
|
@@ -141,7 +141,7 @@ async function selectPrimaryAgent(workspaceRoot, id) {
|
|
|
141
141
|
if (!status.available) {
|
|
142
142
|
throw new Error(`Cannot activate ${status.label}: ${status.error ?? `${status.command} is not available`}.`);
|
|
143
143
|
}
|
|
144
|
-
await (0, studio_session_1.saveStoredActiveAgentId)(workspaceRoot, status.id);
|
|
144
|
+
await (0, studio_session_1.saveStoredActiveAgentId)(workspaceRoot, status.id, options);
|
|
145
145
|
const adapter = getAgentAdapterById(status.id) ?? getSupportedAgentAdapters()[0];
|
|
146
146
|
syncPrimaryAgent(adapter.id);
|
|
147
147
|
return {
|
|
@@ -161,15 +161,15 @@ function setAgentAdaptersForTesting(adapters) {
|
|
|
161
161
|
async function collectAgentStatuses() {
|
|
162
162
|
return Promise.all(getSupportedAgentAdapters().map((adapter) => adapter.detectStatus()));
|
|
163
163
|
}
|
|
164
|
-
async function resolvePrimaryAgentStatus(statuses, workspaceRoot) {
|
|
165
|
-
const storedId = workspaceRoot ? await (0, studio_session_1.loadStoredActiveAgentId)(workspaceRoot) : null;
|
|
164
|
+
async function resolvePrimaryAgentStatus(statuses, workspaceRoot, options = {}) {
|
|
165
|
+
const storedId = workspaceRoot ? await (0, studio_session_1.loadStoredActiveAgentId)(workspaceRoot, options) : null;
|
|
166
166
|
if (storedId) {
|
|
167
167
|
const storedStatus = statuses.find((status) => status.id === storedId);
|
|
168
168
|
if (storedStatus) {
|
|
169
169
|
return storedStatus;
|
|
170
170
|
}
|
|
171
171
|
if (workspaceRoot) {
|
|
172
|
-
await (0, studio_session_1.saveStoredActiveAgentId)(workspaceRoot, null);
|
|
172
|
+
await (0, studio_session_1.saveStoredActiveAgentId)(workspaceRoot, null, options);
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
return statuses.find((status) => status.available) ?? statuses[0];
|
package/dist/core/augment.js
CHANGED
|
@@ -46,7 +46,7 @@ async function detectAugment() {
|
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
async function requestPlannerReply(workspaceRoot, messages) {
|
|
49
|
+
async function requestPlannerReply(workspaceRoot, messages, _options = {}) {
|
|
50
50
|
const result = await runAugmentExec({
|
|
51
51
|
cwd: workspaceRoot,
|
|
52
52
|
prompt: (0, prompts_1.buildPlannerPrompt)(messages, workspaceRoot),
|
|
@@ -55,16 +55,16 @@ async function requestPlannerReply(workspaceRoot, messages) {
|
|
|
55
55
|
});
|
|
56
56
|
return result.lastMessage.trim();
|
|
57
57
|
}
|
|
58
|
-
async function writePlanningPack(workspaceRoot, messages) {
|
|
59
|
-
const planningEpoch = await (0, planning_epochs_1.preparePlanningPackForWrite)(workspaceRoot);
|
|
58
|
+
async function writePlanningPack(workspaceRoot, messages, options = {}) {
|
|
59
|
+
const planningEpoch = await (0, planning_epochs_1.preparePlanningPackForWrite)(workspaceRoot, options);
|
|
60
60
|
const augmentStatus = await detectAugment();
|
|
61
61
|
if (!augmentStatus.available) {
|
|
62
|
-
return appendPlanningEpochSummary(planningEpoch, await (0, local_pack_1.writePlanningPackFallback)(workspaceRoot, messages, augmentStatus.error ?? "Augment CLI is unavailable", "Augment CLI"));
|
|
62
|
+
return appendPlanningEpochSummary(planningEpoch, await (0, local_pack_1.writePlanningPackFallback)(workspaceRoot, messages, augmentStatus.error ?? "Augment CLI is unavailable", "Augment CLI", options));
|
|
63
63
|
}
|
|
64
64
|
try {
|
|
65
65
|
const result = await runAugmentExec({
|
|
66
66
|
cwd: workspaceRoot,
|
|
67
|
-
prompt: await (0, prompts_1.buildPackWriterPrompt)(messages, workspaceRoot),
|
|
67
|
+
prompt: await (0, prompts_1.buildPackWriterPrompt)(messages, workspaceRoot, options),
|
|
68
68
|
maxTurns: 24
|
|
69
69
|
});
|
|
70
70
|
return appendPlanningEpochSummary(planningEpoch, result.lastMessage.trim());
|
|
@@ -72,7 +72,7 @@ async function writePlanningPack(workspaceRoot, messages) {
|
|
|
72
72
|
catch (error) {
|
|
73
73
|
if (isAugmentUnavailableError(error)) {
|
|
74
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"));
|
|
75
|
+
return appendPlanningEpochSummary(planningEpoch, await (0, local_pack_1.writePlanningPackFallback)(workspaceRoot, messages, message, "Augment CLI", options));
|
|
76
76
|
}
|
|
77
77
|
const message = error instanceof Error ? error.message : String(error);
|
|
78
78
|
const epochSummary = (0, planning_epochs_1.formatPlanningEpochSummary)(planningEpoch);
|
|
@@ -82,7 +82,7 @@ async function writePlanningPack(workspaceRoot, messages) {
|
|
|
82
82
|
throw error;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
async function runNextPrompt(workspaceRoot, prompt) {
|
|
85
|
+
async function runNextPrompt(workspaceRoot, prompt, _options = {}) {
|
|
86
86
|
const result = await runAugmentExec({
|
|
87
87
|
cwd: workspaceRoot,
|
|
88
88
|
prompt,
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadAutoRunState = loadAutoRunState;
|
|
4
|
+
exports.saveAutoRunState = saveAutoRunState;
|
|
5
|
+
exports.updateAutoRunState = updateAutoRunState;
|
|
6
|
+
exports.createIdleAutoRunState = createIdleAutoRunState;
|
|
7
|
+
const workspace_1 = require("./workspace");
|
|
8
|
+
async function loadAutoRunState(workspaceRoot, options = {}) {
|
|
9
|
+
const paths = (0, workspace_1.getPlanningPackPaths)(workspaceRoot, options);
|
|
10
|
+
if (!(await (0, workspace_1.fileExists)(paths.autoRunState))) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const parsed = JSON.parse(await (0, workspace_1.readText)(paths.autoRunState));
|
|
15
|
+
if (parsed.version !== 1 ||
|
|
16
|
+
typeof parsed.planId !== "string" ||
|
|
17
|
+
!isAutoRunStatus(parsed.status) ||
|
|
18
|
+
(parsed.startedAt !== null && typeof parsed.startedAt !== "string") ||
|
|
19
|
+
typeof parsed.updatedAt !== "string" ||
|
|
20
|
+
(parsed.endedAt !== null && typeof parsed.endedAt !== "string") ||
|
|
21
|
+
(parsed.source !== null && parsed.source !== "studio" && parsed.source !== "run-next") ||
|
|
22
|
+
(parsed.maxSteps !== null && typeof parsed.maxSteps !== "number") ||
|
|
23
|
+
typeof parsed.stepsAttempted !== "number" ||
|
|
24
|
+
(parsed.lastStartedStepId !== null && typeof parsed.lastStartedStepId !== "string") ||
|
|
25
|
+
(parsed.lastObservedNextStepId !== null && typeof parsed.lastObservedNextStepId !== "string") ||
|
|
26
|
+
(parsed.stopReason !== null && typeof parsed.stopReason !== "string")) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
version: 1,
|
|
31
|
+
planId: parsed.planId,
|
|
32
|
+
status: parsed.status,
|
|
33
|
+
startedAt: parsed.startedAt,
|
|
34
|
+
updatedAt: parsed.updatedAt,
|
|
35
|
+
endedAt: parsed.endedAt,
|
|
36
|
+
source: parsed.source,
|
|
37
|
+
maxSteps: parsed.maxSteps,
|
|
38
|
+
stepsAttempted: parsed.stepsAttempted,
|
|
39
|
+
lastStartedStepId: parsed.lastStartedStepId,
|
|
40
|
+
lastObservedNextStepId: parsed.lastObservedNextStepId,
|
|
41
|
+
stopReason: parsed.stopReason
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function saveAutoRunState(workspaceRoot, state, options = {}) {
|
|
49
|
+
const paths = await (0, workspace_1.ensurePlanningDir)(workspaceRoot, options);
|
|
50
|
+
await (0, workspace_1.writeText)(paths.autoRunState, JSON.stringify(state, null, 2));
|
|
51
|
+
return state;
|
|
52
|
+
}
|
|
53
|
+
async function updateAutoRunState(workspaceRoot, updates, options = {}) {
|
|
54
|
+
const paths = (0, workspace_1.getPlanningPackPaths)(workspaceRoot, options);
|
|
55
|
+
const existing = (await loadAutoRunState(workspaceRoot, options)) ?? createIdleAutoRunState(paths.planId);
|
|
56
|
+
const nextState = {
|
|
57
|
+
...existing,
|
|
58
|
+
...updates,
|
|
59
|
+
version: 1,
|
|
60
|
+
planId: paths.planId,
|
|
61
|
+
updatedAt: new Date().toISOString()
|
|
62
|
+
};
|
|
63
|
+
await saveAutoRunState(workspaceRoot, nextState, options);
|
|
64
|
+
return nextState;
|
|
65
|
+
}
|
|
66
|
+
function createIdleAutoRunState(planId) {
|
|
67
|
+
return {
|
|
68
|
+
version: 1,
|
|
69
|
+
planId,
|
|
70
|
+
status: "idle",
|
|
71
|
+
startedAt: null,
|
|
72
|
+
updatedAt: new Date().toISOString(),
|
|
73
|
+
endedAt: null,
|
|
74
|
+
source: null,
|
|
75
|
+
maxSteps: null,
|
|
76
|
+
stepsAttempted: 0,
|
|
77
|
+
lastStartedStepId: null,
|
|
78
|
+
lastObservedNextStepId: null,
|
|
79
|
+
stopReason: null
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function isAutoRunStatus(value) {
|
|
83
|
+
return (value === "idle" ||
|
|
84
|
+
value === "running" ||
|
|
85
|
+
value === "stop_requested" ||
|
|
86
|
+
value === "stopped" ||
|
|
87
|
+
value === "completed" ||
|
|
88
|
+
value === "failed");
|
|
89
|
+
}
|