astrocode-workflow 0.4.0 → 0.4.1

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 (147) hide show
  1. package/dist/index.js +6 -0
  2. package/dist/shared/metrics.d.ts +66 -0
  3. package/dist/shared/metrics.js +112 -0
  4. package/dist/src/agents/commands.d.ts +9 -0
  5. package/dist/src/agents/commands.js +121 -0
  6. package/dist/src/agents/prompts.d.ts +3 -0
  7. package/dist/src/agents/prompts.js +232 -0
  8. package/dist/src/agents/registry.d.ts +6 -0
  9. package/dist/src/agents/registry.js +242 -0
  10. package/dist/src/agents/types.d.ts +14 -0
  11. package/dist/src/agents/types.js +8 -0
  12. package/dist/src/astro/workflow-runner.d.ts +15 -0
  13. package/dist/src/astro/workflow-runner.js +25 -0
  14. package/dist/src/config/config-handler.d.ts +4 -0
  15. package/dist/src/config/config-handler.js +46 -0
  16. package/dist/src/config/defaults.d.ts +3 -0
  17. package/dist/src/config/defaults.js +3 -0
  18. package/dist/src/config/loader.d.ts +11 -0
  19. package/dist/src/config/loader.js +82 -0
  20. package/dist/src/config/schema.d.ts +195 -0
  21. package/dist/src/config/schema.js +224 -0
  22. package/dist/src/hooks/continuation-enforcer.d.ts +34 -0
  23. package/dist/src/hooks/continuation-enforcer.js +190 -0
  24. package/dist/src/hooks/inject-provider.d.ts +27 -0
  25. package/dist/src/hooks/inject-provider.js +189 -0
  26. package/dist/src/hooks/tool-output-truncator.d.ts +25 -0
  27. package/dist/src/hooks/tool-output-truncator.js +57 -0
  28. package/dist/src/index.d.ts +3 -0
  29. package/dist/src/index.js +313 -0
  30. package/dist/src/shared/deep-merge.d.ts +8 -0
  31. package/dist/src/shared/deep-merge.js +25 -0
  32. package/dist/src/shared/hash.d.ts +1 -0
  33. package/dist/src/shared/hash.js +4 -0
  34. package/dist/src/shared/log.d.ts +7 -0
  35. package/dist/src/shared/log.js +24 -0
  36. package/dist/src/shared/metrics.d.ts +66 -0
  37. package/dist/src/shared/metrics.js +112 -0
  38. package/dist/src/shared/model-tuning.d.ts +9 -0
  39. package/dist/src/shared/model-tuning.js +28 -0
  40. package/dist/src/shared/paths.d.ts +19 -0
  41. package/dist/src/shared/paths.js +64 -0
  42. package/dist/src/shared/text.d.ts +4 -0
  43. package/dist/src/shared/text.js +19 -0
  44. package/dist/src/shared/time.d.ts +1 -0
  45. package/dist/src/shared/time.js +3 -0
  46. package/dist/src/state/adapters/index.d.ts +41 -0
  47. package/dist/src/state/adapters/index.js +115 -0
  48. package/dist/src/state/db.d.ts +16 -0
  49. package/dist/src/state/db.js +225 -0
  50. package/dist/src/state/ids.d.ts +8 -0
  51. package/dist/src/state/ids.js +25 -0
  52. package/dist/src/state/repo-lock.d.ts +67 -0
  53. package/dist/src/state/repo-lock.js +580 -0
  54. package/dist/src/state/schema.d.ts +2 -0
  55. package/dist/src/state/schema.js +258 -0
  56. package/dist/src/state/types.d.ts +71 -0
  57. package/dist/src/state/types.js +1 -0
  58. package/dist/src/state/workflow-repo-lock.d.ts +23 -0
  59. package/dist/src/state/workflow-repo-lock.js +83 -0
  60. package/dist/src/tools/artifacts.d.ts +18 -0
  61. package/dist/src/tools/artifacts.js +71 -0
  62. package/dist/src/tools/health.d.ts +8 -0
  63. package/dist/src/tools/health.js +119 -0
  64. package/dist/src/tools/index.d.ts +20 -0
  65. package/dist/src/tools/index.js +97 -0
  66. package/dist/src/tools/init.d.ts +17 -0
  67. package/dist/src/tools/init.js +96 -0
  68. package/dist/src/tools/injects.d.ts +53 -0
  69. package/dist/src/tools/injects.js +325 -0
  70. package/dist/src/tools/lock.d.ts +4 -0
  71. package/dist/src/tools/lock.js +78 -0
  72. package/dist/src/tools/metrics.d.ts +7 -0
  73. package/dist/src/tools/metrics.js +61 -0
  74. package/dist/src/tools/repair.d.ts +8 -0
  75. package/dist/src/tools/repair.js +59 -0
  76. package/dist/src/tools/reset.d.ts +8 -0
  77. package/dist/src/tools/reset.js +92 -0
  78. package/dist/src/tools/run.d.ts +13 -0
  79. package/dist/src/tools/run.js +54 -0
  80. package/dist/src/tools/spec.d.ts +12 -0
  81. package/dist/src/tools/spec.js +44 -0
  82. package/dist/src/tools/stage.d.ts +23 -0
  83. package/dist/src/tools/stage.js +371 -0
  84. package/dist/src/tools/status.d.ts +8 -0
  85. package/dist/src/tools/status.js +125 -0
  86. package/dist/src/tools/story.d.ts +23 -0
  87. package/dist/src/tools/story.js +85 -0
  88. package/dist/src/tools/workflow.d.ts +13 -0
  89. package/dist/src/tools/workflow.js +359 -0
  90. package/dist/src/ui/inject.d.ts +12 -0
  91. package/dist/src/ui/inject.js +107 -0
  92. package/dist/src/ui/toasts.d.ts +13 -0
  93. package/dist/src/ui/toasts.js +39 -0
  94. package/dist/src/workflow/artifacts.d.ts +24 -0
  95. package/dist/src/workflow/artifacts.js +45 -0
  96. package/dist/src/workflow/baton.d.ts +72 -0
  97. package/dist/src/workflow/baton.js +166 -0
  98. package/dist/src/workflow/context.d.ts +20 -0
  99. package/dist/src/workflow/context.js +113 -0
  100. package/dist/src/workflow/directives.d.ts +39 -0
  101. package/dist/src/workflow/directives.js +137 -0
  102. package/dist/src/workflow/repair.d.ts +8 -0
  103. package/dist/src/workflow/repair.js +99 -0
  104. package/dist/src/workflow/state-machine.d.ts +86 -0
  105. package/dist/src/workflow/state-machine.js +216 -0
  106. package/dist/src/workflow/story-helpers.d.ts +9 -0
  107. package/dist/src/workflow/story-helpers.js +13 -0
  108. package/dist/state/db.d.ts +1 -0
  109. package/dist/state/db.js +9 -0
  110. package/dist/state/repo-lock.d.ts +3 -0
  111. package/dist/state/repo-lock.js +29 -0
  112. package/dist/test/integration/db-transactions.test.d.ts +1 -0
  113. package/dist/test/integration/db-transactions.test.js +126 -0
  114. package/dist/test/integration/injection-metrics.test.d.ts +1 -0
  115. package/dist/test/integration/injection-metrics.test.js +129 -0
  116. package/dist/tools/health.d.ts +8 -0
  117. package/dist/tools/health.js +119 -0
  118. package/dist/tools/index.js +9 -0
  119. package/dist/tools/metrics.d.ts +7 -0
  120. package/dist/tools/metrics.js +61 -0
  121. package/dist/tools/reset.d.ts +8 -0
  122. package/dist/tools/reset.js +92 -0
  123. package/dist/tools/workflow.js +178 -168
  124. package/dist/ui/inject.js +21 -9
  125. package/package.json +6 -4
  126. package/src/astro/workflow-runner.ts +36 -0
  127. package/src/config/schema.ts +1 -0
  128. package/src/hooks/inject-provider.ts +94 -14
  129. package/src/index.ts +14 -0
  130. package/src/shared/metrics.ts +148 -0
  131. package/src/state/db.ts +10 -1
  132. package/src/state/repo-lock.ts +706 -0
  133. package/src/state/schema.ts +8 -1
  134. package/src/state/workflow-repo-lock.ts +111 -0
  135. package/src/tools/health.ts +128 -0
  136. package/src/tools/index.ts +15 -3
  137. package/src/tools/init.ts +7 -6
  138. package/src/tools/lock.ts +75 -0
  139. package/src/tools/metrics.ts +71 -0
  140. package/src/tools/repair.ts +44 -6
  141. package/src/tools/reset.ts +100 -0
  142. package/src/tools/stage.ts +1 -0
  143. package/src/tools/status.ts +2 -1
  144. package/src/tools/story.ts +1 -0
  145. package/src/tools/workflow.ts +19 -1
  146. package/src/ui/inject.ts +21 -9
  147. package/src/workflow/repair.ts +2 -2
@@ -8,6 +8,7 @@ import type { StoryState } from "../state/types";
8
8
  import { insertStory } from "../workflow/story-helpers";
9
9
 
10
10
 
11
+
11
12
  export function createAstroStoryQueueTool(opts: { ctx: any; config: AstrocodeConfig; db: SqliteDb }): ToolDefinition {
12
13
  const { db } = opts;
13
14
 
@@ -1,5 +1,6 @@
1
1
  // src/tools/workflow.ts
2
2
  import { tool, type ToolDefinition } from "@opencode-ai/plugin/tool";
3
+ import path from "node:path";
3
4
  import type { AstrocodeConfig } from "../config/schema";
4
5
  import type { SqliteDb } from "../state/db";
5
6
  import { withTx } from "../state/db";
@@ -19,9 +20,12 @@ import { buildStageDirective, directiveHash } from "../workflow/directives";
19
20
  import { injectChatPrompt } from "../ui/inject";
20
21
  import { nowISO } from "../shared/time";
21
22
  import { newEventId } from "../state/ids";
23
+
22
24
  import { debug } from "../shared/log";
23
25
  import { createToastManager } from "../ui/toasts";
24
26
  import type { AgentConfig } from "@opencode-ai/sdk";
27
+ import { acquireRepoLock } from "../state/repo-lock";
28
+ import { workflowRepoLock } from "../state/workflow-repo-lock";
25
29
 
26
30
  // Agent name mapping for case-sensitive resolution
27
31
  export const STAGE_TO_AGENT_MAP: Record<string, string> = {
@@ -184,8 +188,20 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
184
188
  max_steps: tool.schema.number().int().positive().default(config.workflow.default_max_steps),
185
189
  },
186
190
  execute: async ({ mode, max_steps }) => {
191
+ const repoRoot = (ctx as any).directory as string;
192
+ const lockPath = path.join(repoRoot, ".astro", "astro.lock");
187
193
  const sessionId = (ctx as any).sessionID as string | undefined;
188
- const steps = Math.min(max_steps, config.workflow.loop_max_steps_hard_cap);
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);
189
205
 
190
206
  const actions: string[] = [];
191
207
  const warnings: string[] = [];
@@ -408,6 +424,8 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
408
424
  }
409
425
 
410
426
  return lines.join("\n").trim();
427
+ },
428
+ });
411
429
  },
412
430
  });
413
431
  }
package/src/ui/inject.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/ui/inject.ts
2
+ import { recordInjection, recordError } from "../shared/metrics";
2
3
  type InjectionItem = {
3
4
  ctx: any;
4
5
  sessionId: string;
@@ -33,16 +34,26 @@ async function tryInjectOnce(item: InjectionItem): Promise<void> {
33
34
  const { ctx, sessionId, text, agent = "Astro" } = item;
34
35
  const prefixedText = `[${agent}]\n\n${text}`;
35
36
 
36
- const { session, prompt } = getPromptInvoker(ctx);
37
+ const injectionRecorder = recordInjection({ sessionId, attempts: item.attempts + 1, agent });
38
+ const injectionStart = injectionRecorder.start();
37
39
 
38
- // IMPORTANT: force correct `this` binding
39
- await prompt.call(session, {
40
- path: { id: sessionId },
41
- body: {
42
- parts: [{ type: "text", text: prefixedText }],
43
- agent,
44
- },
45
- });
40
+ try {
41
+ const { session, prompt } = getPromptInvoker(ctx);
42
+
43
+ // IMPORTANT: force correct `this` binding
44
+ await prompt.call(session, {
45
+ path: { id: sessionId },
46
+ body: {
47
+ parts: [{ type: "text", text: prefixedText }],
48
+ agent,
49
+ },
50
+ });
51
+
52
+ injectionRecorder.end(injectionStart, true);
53
+ } catch (error) {
54
+ injectionRecorder.end(injectionStart, false);
55
+ throw error;
56
+ }
46
57
  }
47
58
 
48
59
  async function runSessionQueue(sessionId: string) {
@@ -69,6 +80,7 @@ async function runSessionQueue(sessionId: string) {
69
80
  console.warn(
70
81
  `[Astrocode] Injection failed permanently after ${item.attempts} attempts: ${msg}`
71
82
  );
83
+ recordError("injection_failure", `Injection failed after ${item.attempts} attempts: ${msg}`);
72
84
  item.reject(err);
73
85
  continue;
74
86
  }
@@ -72,11 +72,11 @@ export function repairState(db: SqliteDb, config: AstrocodeConfig): RepairReport
72
72
  if (stageRuns.length < pipeline.length) {
73
73
  const existingKeys = new Set(stageRuns.map((s) => s.stage_key));
74
74
  const insert = db.prepare(
75
- "INSERT INTO stage_runs (stage_run_id, run_id, stage_key, stage_index, status, updated_at) VALUES (?, ?, ?, ?, 'pending', ?)"
75
+ "INSERT INTO stage_runs (stage_run_id, run_id, stage_key, stage_index, status, created_at, updated_at) VALUES (?, ?, ?, ?, 'pending', ?, ?)"
76
76
  );
77
77
  pipeline.forEach((key, idx) => {
78
78
  if (!existingKeys.has(key as any)) {
79
- insert.run(newStageRunId(), active.run_id, key, idx, now);
79
+ insert.run(newStageRunId(), active.run_id, key, idx, now, now);
80
80
  push(report, `Inserted missing stage_run ${key} for run ${active.run_id}`);
81
81
  }
82
82
  });