astrocode-workflow 0.4.1 → 0.4.3

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.
@@ -6,56 +6,22 @@ import { withTx } from "../state/db";
6
6
  import { repairState, formatRepairReport } from "../workflow/repair";
7
7
  import { putArtifact } from "../workflow/artifacts";
8
8
  import { nowISO } from "../shared/time";
9
- import { getLockStatus, tryRemoveStaleLock } from "../state/repo-lock";
10
9
 
11
10
 
12
11
  export function createAstroRepairTool(opts: { ctx: any; config: AstrocodeConfig; db: SqliteDb }): ToolDefinition {
13
12
  const { ctx, config, db } = opts;
14
13
 
15
14
  return tool({
16
- description: "Repair Astrocode invariants and recover from inconsistent DB state. Also checks and repairs lock files. Writes a repair report artifact.",
15
+ description: "Repair Astrocode invariants and recover from inconsistent DB state. Writes a repair report artifact.",
17
16
  args: {
18
17
  write_report_artifact: tool.schema.boolean().default(true),
19
- repair_lock: tool.schema.boolean().default(true).describe("Attempt to remove stale/dead lock files"),
20
18
  },
21
- execute: async ({ write_report_artifact, repair_lock }) => {
19
+ execute: async ({ write_report_artifact }) => {
22
20
  const repoRoot = ctx.directory as string;
23
- const lockPath = path.join(repoRoot, ".astro", "astro.lock");
24
21
 
25
- // First, check and repair lock if requested
26
- const lockLines: string[] = [];
27
- const lockStatus = getLockStatus(lockPath);
28
-
29
- if (lockStatus.exists) {
30
- lockLines.push("## Lock Status");
31
- lockLines.push(`- Lock found: ${lockPath}`);
32
- lockLines.push(`- PID: ${lockStatus.pid} (${lockStatus.pidAlive ? 'alive' : 'dead'})`);
33
- lockLines.push(`- Age: ${lockStatus.ageMs ? Math.floor(lockStatus.ageMs / 1000) : '?'}s`);
34
- lockLines.push(`- Status: ${lockStatus.isStale ? 'stale' : 'fresh'}`);
35
-
36
- if (repair_lock) {
37
- const result = tryRemoveStaleLock(lockPath);
38
- if (result.removed) {
39
- lockLines.push(`- **Removed**: ${result.reason}`);
40
- } else {
41
- lockLines.push(`- **Not removed**: ${result.reason}`);
42
- }
43
- } else {
44
- if (!lockStatus.pidAlive || lockStatus.isStale) {
45
- lockLines.push(`- **Recommendation**: Run with repair_lock=true to remove this ${!lockStatus.pidAlive ? 'dead' : 'stale'} lock`);
46
- }
47
- }
48
- lockLines.push("");
49
- }
50
-
51
- // Then repair database state
22
+ // Repair database state
52
23
  const report = withTx(db, () => repairState(db, config));
53
- const dbMd = formatRepairReport(report);
54
-
55
- // Combine lock and DB repair
56
- const fullMd = lockLines.length > 0
57
- ? `# Astrocode Repair Report\n\n${lockLines.join("\n")}\n${dbMd.replace(/^# Astrocode repair report\n*/i, "")}`
58
- : dbMd;
24
+ const fullMd = formatRepairReport(report);
59
25
 
60
26
  if (write_report_artifact) {
61
27
  const rel = `.astro/repair/repair_${nowISO().replace(/[:.]/g, "-")}.md`;
@@ -24,8 +24,6 @@ import { newEventId } from "../state/ids";
24
24
  import { debug } from "../shared/log";
25
25
  import { createToastManager } from "../ui/toasts";
26
26
  import type { AgentConfig } from "@opencode-ai/sdk";
27
- import { acquireRepoLock } from "../state/repo-lock";
28
- import { workflowRepoLock } from "../state/workflow-repo-lock";
29
27
 
30
28
  // Agent name mapping for case-sensitive resolution
31
29
  export const STAGE_TO_AGENT_MAP: Record<string, string> = {
@@ -140,36 +138,33 @@ function buildUiMessage(e: UiEmitEvent): { title: string; message: string; varia
140
138
  case "stage_started": {
141
139
  const agent = e.agent_name ? ` (${e.agent_name})` : "";
142
140
  const title = "Astrocode";
143
- const message = `Stage started: ${e.stage_key}${agent}`;
141
+ const message = `▶ Stage started: ${e.stage_key}${agent}`;
144
142
  const chatText = [
145
- `[SYSTEM DIRECTIVE: ASTROCODE STAGE_STARTED]`,
146
- ``,
147
- `Run: ${e.run_id}`,
148
- `Stage: ${e.stage_key}${agent}`,
143
+ `### ASTROCODE: STAGE_STARTED`,
144
+ `**Run:** \`${e.run_id}\` `,
145
+ `**Stage:** \`${e.stage_key}\`${agent}`,
149
146
  ].join("\n");
150
147
  return { title, message, variant: "info", chatText };
151
148
  }
152
149
  case "run_completed": {
153
150
  const title = "Astrocode";
154
- const message = `Run completed: ${e.run_id}`;
151
+ const message = `✓ Run completed: ${e.run_id}`;
155
152
  const chatText = [
156
- `[SYSTEM DIRECTIVE: ASTROCODE RUN_COMPLETED]`,
157
- ``,
158
- `Run: ${e.run_id}`,
159
- `Story: ${e.story_key}`,
153
+ `### ASTROCODE: RUN_COMPLETED`,
154
+ `**Run:** \`${e.run_id}\` `,
155
+ `**Story:** \`${e.story_key}\``,
160
156
  ].join("\n");
161
157
  return { title, message, variant: "success", chatText };
162
158
  }
163
159
  case "run_failed": {
164
160
  const title = "Astrocode";
165
- const message = `Run failed: ${e.run_id} (${e.stage_key})`;
161
+ const message = `✖ Run failed: ${e.run_id} (${e.stage_key})`;
166
162
  const chatText = [
167
- `[SYSTEM DIRECTIVE: ASTROCODE RUN_FAILED]`,
168
- ``,
169
- `Run: ${e.run_id}`,
170
- `Story: ${e.story_key}`,
171
- `Stage: ${e.stage_key}`,
172
- `Error: ${e.error_text}`,
163
+ `### ASTROCODE: RUN_FAILED`,
164
+ `**Run:** \`${e.run_id}\` `,
165
+ `**Story:** \`${e.story_key}\` `,
166
+ `**Stage:** \`${e.stage_key}\` `,
167
+ `**Error:** ${e.error_text}`,
173
168
  ].join("\n");
174
169
  return { title, message, variant: "error", chatText };
175
170
  }
@@ -188,20 +183,8 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
188
183
  max_steps: tool.schema.number().int().positive().default(config.workflow.default_max_steps),
189
184
  },
190
185
  execute: async ({ mode, max_steps }) => {
191
- const repoRoot = (ctx as any).directory as string;
192
- const lockPath = path.join(repoRoot, ".astro", "astro.lock");
193
186
  const sessionId = (ctx as any).sessionID as string | undefined;
194
-
195
- return workflowRepoLock(
196
- { acquireRepoLock },
197
- {
198
- lockPath,
199
- repoRoot,
200
- sessionId,
201
- owner: "astro_workflow_proceed",
202
- advisory: true, // Advisory mode: warn instead of blocking on lock contention
203
- fn: async () => {
204
- const steps = Math.min(max_steps, config.workflow.loop_max_steps_hard_cap);
187
+ const steps = Math.min(max_steps, config.workflow.loop_max_steps_hard_cap);
205
188
 
206
189
  const actions: string[] = [];
207
190
  const warnings: string[] = [];
@@ -322,14 +305,14 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
322
305
  await injectChatPrompt({ ctx, sessionId, text: delegatePrompt, agent: "Astro" });
323
306
 
324
307
  const continueMessage = [
325
- `[SYSTEM DIRECTIVE: ASTROCODE AWAIT_STAGE_COMPLETION]`,
326
- ``,
308
+ `### ASTROCODE: AWAITING COMPLETION`,
327
309
  `Stage \`${next.stage_key}\` delegated to \`${agentName}\`.`,
328
310
  ``,
329
- `When \`${agentName}\` completes, call:`,
330
- `astro_stage_complete(run_id="${active.run_id}", stage_key="${next.stage_key}", output_text="[paste subagent output here]")`,
331
- ``,
332
- `This advances the workflow.`,
311
+ `**Action Required:** When \`${agentName}\` completes, call:`,
312
+ `\`\`\`bash`,
313
+ `astro_stage_complete(run_id="${active.run_id}", stage_key="${next.stage_key}", output_text="...")`,
314
+ `\`\`\``,
315
+ `*Then run \`astro_workflow_proceed\` to continue.*`,
333
316
  ].join("\n");
334
317
 
335
318
  await injectChatPrompt({ ctx, sessionId, text: continueMessage, agent: "Astro" });
@@ -353,12 +336,12 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
353
336
  });
354
337
 
355
338
  const prompt = [
356
- `[SYSTEM DIRECTIVE: ASTROCODE AWAIT_STAGE_OUTPUT]`,
357
- ``,
339
+ `### 📥 ASTROCODE: AWAITING OUTPUT`,
358
340
  `Run \`${next.run_id}\` is waiting for stage \`${next.stage_key}\` output.`,
359
- `If you have the subagent output, call astro_stage_complete with output_text=the FULL output.`,
360
341
  ``,
361
- `Context snapshot:`,
342
+ `**Action Required:** If you have the subagent output, call \`astro_stage_complete\` with \`output_text=the FULL output\`.`,
343
+ ``,
344
+ `#### Context Snapshot`,
362
345
  context,
363
346
  ].join("\n").trim();
364
347
 
@@ -424,8 +407,6 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
424
407
  }
425
408
 
426
409
  return lines.join("\n").trim();
427
- },
428
- });
429
410
  },
430
411
  });
431
412
  }