astrocode-workflow 0.1.31 → 0.1.35
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/dist/agents/prompts.d.ts +1 -1
- package/dist/agents/prompts.js +31 -19
- package/dist/tools/workflow.js +19 -0
- package/dist/workflow/baton.js +18 -3
- package/package.json +1 -1
- package/src/agents/prompts.ts +31 -19
- package/src/tools/workflow.ts +22 -0
- package/src/workflow/baton.ts +18 -2
package/dist/agents/prompts.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const BASE_ORCH_PROMPT = "You are Astro (Orchestrator) for Astrocode.\n\nMission:\n- Advance a deterministic pipeline: frame \u2192 plan \u2192 spec \u2192 implement \u2192 review \u2192 verify \u2192 close.\n- The SQLite DB is the source of truth. Prefer tools over prose.\n- Never narrate what prompts you received.\n- Keep outputs short; store large outputs as artifacts and reference paths.\n\nOperating rules:\n- Only start new runs when the user explicitly requests implementation, workflow management, or story processing.\n- Answer questions directly when possible without starting workflows.\n- Prefer calling astro_workflow_proceed (step/loop) and astro_status only when actively managing a workflow.\n- Delegate stage work only to the stage subagent matching the current stage.\n- If a stage subagent returns status=blocked, inject the BLOCKED directive and stop.\n- Never delegate from subagents (enforced by permissions).\n- Be discretionary: assess if the user's request requires workflow initiation or just information.\n";
|
|
2
|
-
export declare const BASE_STAGE_PROMPT = "You are an Astro stage subagent.\n\n***CRITICAL: Follow the latest [SYSTEM DIRECTIVE: ASTROCODE \u2014 STAGE_*] you receive EXACTLY.***\n\nYour output MUST be in this EXACT format (
|
|
2
|
+
export declare const BASE_STAGE_PROMPT = "You are an Astro stage subagent.\n\n***CRITICAL: Follow the latest [SYSTEM DIRECTIVE: ASTROCODE \u2014 STAGE_*] you receive EXACTLY.***\n\nYour output MUST be in this EXACT format (copy/paste this template):\n\n1) First, a short summary paragraph (1-3 sentences).\n\n2) Then, immediately after, the ASTRO JSON between markers:\n\n<!-- ASTRO_JSON_BEGIN -->\n{\n \"stage_key\": \"CURRENT_STAGE\",\n \"status\": \"ok\",\n \"summary\": \"Brief summary of work done\",\n \"tasks\": [],\n \"files\": [],\n \"questions\": []\n}\n<!-- ASTRO_JSON_END -->\n\nMANDATORY:\n- stage_key must be \"CURRENT_STAGE\"\n- status must be \"ok\", \"blocked\", or \"failed\"\n- summary must be a non-empty string\n- JSON must be valid syntax\n- Use exact markers shown above\n\nEXAMPLE OUTPUT:\nI analyzed the requirements and identified key components for implementation.\n\n<!-- ASTRO_JSON_BEGIN -->\n{\n \"stage_key\": \"plan\",\n \"status\": \"ok\",\n \"summary\": \"Created implementation plan with 5 main tasks\",\n \"tasks\": [\n {\"title\": \"Setup database\", \"complexity\": 3},\n {\"title\": \"Build API endpoints\", \"complexity\": 5}\n ],\n \"files\": [\n {\"path\": \"schema.prisma\", \"kind\": \"file\"}\n ],\n \"questions\": []\n}\n<!-- ASTRO_JSON_END -->\n\nIf blocked, set status=\"blocked\" and add ONE question to questions array. Do not deviate from this format.\n";
|
package/dist/agents/prompts.js
CHANGED
|
@@ -19,36 +19,48 @@ export const BASE_STAGE_PROMPT = `You are an Astro stage subagent.
|
|
|
19
19
|
|
|
20
20
|
***CRITICAL: Follow the latest [SYSTEM DIRECTIVE: ASTROCODE — STAGE_*] you receive EXACTLY.***
|
|
21
21
|
|
|
22
|
-
Your output MUST be in this EXACT format (
|
|
22
|
+
Your output MUST be in this EXACT format (copy/paste this template):
|
|
23
23
|
|
|
24
|
-
1) First, a short
|
|
24
|
+
1) First, a short summary paragraph (1-3 sentences).
|
|
25
25
|
|
|
26
|
-
2) Then, immediately after, the ASTRO JSON markers
|
|
26
|
+
2) Then, immediately after, the ASTRO JSON between markers:
|
|
27
27
|
|
|
28
28
|
<!-- ASTRO_JSON_BEGIN -->
|
|
29
29
|
{
|
|
30
|
-
"schema_version": 1,
|
|
31
30
|
"stage_key": "CURRENT_STAGE",
|
|
32
31
|
"status": "ok",
|
|
33
|
-
"summary": "Brief summary",
|
|
34
|
-
"decisions": [],
|
|
35
|
-
"next_actions": [],
|
|
32
|
+
"summary": "Brief summary of work done",
|
|
36
33
|
"tasks": [],
|
|
37
34
|
"files": [],
|
|
38
|
-
"
|
|
39
|
-
"new_stories": [],
|
|
40
|
-
"questions": [],
|
|
41
|
-
"metrics": {}
|
|
35
|
+
"questions": []
|
|
42
36
|
}
|
|
43
37
|
<!-- ASTRO_JSON_END -->
|
|
44
38
|
|
|
45
|
-
MANDATORY
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
- Markers MUST be exact as shown
|
|
39
|
+
MANDATORY:
|
|
40
|
+
- stage_key must be "CURRENT_STAGE"
|
|
41
|
+
- status must be "ok", "blocked", or "failed"
|
|
42
|
+
- summary must be a non-empty string
|
|
43
|
+
- JSON must be valid syntax
|
|
44
|
+
- Use exact markers shown above
|
|
52
45
|
|
|
53
|
-
|
|
46
|
+
EXAMPLE OUTPUT:
|
|
47
|
+
I analyzed the requirements and identified key components for implementation.
|
|
48
|
+
|
|
49
|
+
<!-- ASTRO_JSON_BEGIN -->
|
|
50
|
+
{
|
|
51
|
+
"stage_key": "plan",
|
|
52
|
+
"status": "ok",
|
|
53
|
+
"summary": "Created implementation plan with 5 main tasks",
|
|
54
|
+
"tasks": [
|
|
55
|
+
{"title": "Setup database", "complexity": 3},
|
|
56
|
+
{"title": "Build API endpoints", "complexity": 5}
|
|
57
|
+
],
|
|
58
|
+
"files": [
|
|
59
|
+
{"path": "schema.prisma", "kind": "file"}
|
|
60
|
+
],
|
|
61
|
+
"questions": []
|
|
62
|
+
}
|
|
63
|
+
<!-- ASTRO_JSON_END -->
|
|
64
|
+
|
|
65
|
+
If blocked, set status="blocked" and add ONE question to questions array. Do not deviate from this format.
|
|
54
66
|
`;
|
package/dist/tools/workflow.js
CHANGED
|
@@ -122,6 +122,25 @@ export function createAstroWorkflowProceedTool(opts) {
|
|
|
122
122
|
if (config.ui.toasts.enabled && config.ui.toasts.show_run_completed) {
|
|
123
123
|
await toasts.show({ title: "Astrocode", message: `Run completed (${next.run_id})`, variant: "success" });
|
|
124
124
|
}
|
|
125
|
+
// Inject continuation directive for workflow resumption
|
|
126
|
+
if (sessionId) {
|
|
127
|
+
const continueDirective = [
|
|
128
|
+
`[SYSTEM DIRECTIVE: ASTROCODE — CONTINUE]`,
|
|
129
|
+
``,
|
|
130
|
+
`Run ${next.run_id} completed successfully.`,
|
|
131
|
+
``,
|
|
132
|
+
`The Clara Forms implementation run has finished all stages. The spec has been analyzed and decomposed into prioritized implementation stories.`,
|
|
133
|
+
``,
|
|
134
|
+
`Next actions: Review the generated stories and approve the next one to continue development.`,
|
|
135
|
+
].join("\n");
|
|
136
|
+
await injectChatPrompt({
|
|
137
|
+
ctx,
|
|
138
|
+
sessionId,
|
|
139
|
+
text: continueDirective,
|
|
140
|
+
agent: "Astro"
|
|
141
|
+
});
|
|
142
|
+
actions.push(`injected continuation directive for completed run ${next.run_id}`);
|
|
143
|
+
}
|
|
125
144
|
// Check for next approved story to start
|
|
126
145
|
const nextStory = db.prepare("SELECT story_key, title FROM stories WHERE state = 'approved' ORDER BY priority DESC, created_at ASC LIMIT 1").get();
|
|
127
146
|
if (nextStory && sessionId) {
|
package/dist/workflow/baton.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { clampLines, normalizeNewlines, stripCodeFences } from "../shared/text";
|
|
2
2
|
import { z, ZodError } from "zod";
|
|
3
|
-
import { debug } from "../shared/log";
|
|
4
3
|
export const ASTRO_JSON_BEGIN = "<!-- ASTRO_JSON_BEGIN -->";
|
|
5
4
|
export const ASTRO_JSON_END = "<!-- ASTRO_JSON_END -->";
|
|
6
5
|
export const StageKeySchema = z.enum(["frame", "plan", "spec", "implement", "review", "verify", "close"]);
|
|
@@ -45,11 +44,27 @@ export function parseStageOutputText(text) {
|
|
|
45
44
|
let jsonRaw = "";
|
|
46
45
|
let fallbackUsed = false;
|
|
47
46
|
if (beginIdx === -1 || endIdx === -1 || endIdx <= beginIdx) {
|
|
47
|
+
// Enhanced fallback: scan for any JSON object in the text
|
|
48
|
+
const jsonMatch = norm.match(/\{[\s\S]*\}/);
|
|
49
|
+
if (jsonMatch) {
|
|
50
|
+
try {
|
|
51
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
52
|
+
const astroJson = AstroJsonSchema.parse(parsed);
|
|
53
|
+
return {
|
|
54
|
+
baton_md: norm.replace(jsonMatch[0], "").trim(),
|
|
55
|
+
astro_json: astroJson,
|
|
56
|
+
astro_json_raw: jsonMatch[0],
|
|
57
|
+
error: null
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
// JSON found but invalid, continue to marker error
|
|
62
|
+
}
|
|
63
|
+
}
|
|
48
64
|
// Fallback: if no markers, check if the entire text is JSON
|
|
49
65
|
try {
|
|
50
66
|
const parsed = JSON.parse(norm);
|
|
51
67
|
const astroJson = AstroJsonSchema.parse(parsed);
|
|
52
|
-
debug("Used JSON fallback parsing (no markers found)", { stage_key: astroJson.stage_key });
|
|
53
68
|
return {
|
|
54
69
|
baton_md: "",
|
|
55
70
|
astro_json: astroJson,
|
|
@@ -64,7 +79,7 @@ export function parseStageOutputText(text) {
|
|
|
64
79
|
baton_md: norm,
|
|
65
80
|
astro_json: null,
|
|
66
81
|
astro_json_raw: null,
|
|
67
|
-
error: `Missing ASTRO JSON markers. Expected markers ${ASTRO_JSON_BEGIN} ... ${ASTRO_JSON_END}. If output
|
|
82
|
+
error: `Missing ASTRO JSON markers. Expected markers ${ASTRO_JSON_BEGIN} ... ${ASTRO_JSON_END}. If output contains JSON, ensure it's valid.`,
|
|
68
83
|
};
|
|
69
84
|
}
|
|
70
85
|
const before = norm.slice(0, beginIdx).trim();
|
package/package.json
CHANGED
package/src/agents/prompts.ts
CHANGED
|
@@ -20,36 +20,48 @@ export const BASE_STAGE_PROMPT = `You are an Astro stage subagent.
|
|
|
20
20
|
|
|
21
21
|
***CRITICAL: Follow the latest [SYSTEM DIRECTIVE: ASTROCODE — STAGE_*] you receive EXACTLY.***
|
|
22
22
|
|
|
23
|
-
Your output MUST be in this EXACT format (
|
|
23
|
+
Your output MUST be in this EXACT format (copy/paste this template):
|
|
24
24
|
|
|
25
|
-
1) First, a short
|
|
25
|
+
1) First, a short summary paragraph (1-3 sentences).
|
|
26
26
|
|
|
27
|
-
2) Then, immediately after, the ASTRO JSON markers
|
|
27
|
+
2) Then, immediately after, the ASTRO JSON between markers:
|
|
28
28
|
|
|
29
29
|
<!-- ASTRO_JSON_BEGIN -->
|
|
30
30
|
{
|
|
31
|
-
"schema_version": 1,
|
|
32
31
|
"stage_key": "CURRENT_STAGE",
|
|
33
32
|
"status": "ok",
|
|
34
|
-
"summary": "Brief summary",
|
|
35
|
-
"decisions": [],
|
|
36
|
-
"next_actions": [],
|
|
33
|
+
"summary": "Brief summary of work done",
|
|
37
34
|
"tasks": [],
|
|
38
35
|
"files": [],
|
|
39
|
-
"
|
|
40
|
-
"new_stories": [],
|
|
41
|
-
"questions": [],
|
|
42
|
-
"metrics": {}
|
|
36
|
+
"questions": []
|
|
43
37
|
}
|
|
44
38
|
<!-- ASTRO_JSON_END -->
|
|
45
39
|
|
|
46
|
-
MANDATORY
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
- Markers MUST be exact as shown
|
|
40
|
+
MANDATORY:
|
|
41
|
+
- stage_key must be "CURRENT_STAGE"
|
|
42
|
+
- status must be "ok", "blocked", or "failed"
|
|
43
|
+
- summary must be a non-empty string
|
|
44
|
+
- JSON must be valid syntax
|
|
45
|
+
- Use exact markers shown above
|
|
53
46
|
|
|
54
|
-
|
|
47
|
+
EXAMPLE OUTPUT:
|
|
48
|
+
I analyzed the requirements and identified key components for implementation.
|
|
49
|
+
|
|
50
|
+
<!-- ASTRO_JSON_BEGIN -->
|
|
51
|
+
{
|
|
52
|
+
"stage_key": "plan",
|
|
53
|
+
"status": "ok",
|
|
54
|
+
"summary": "Created implementation plan with 5 main tasks",
|
|
55
|
+
"tasks": [
|
|
56
|
+
{"title": "Setup database", "complexity": 3},
|
|
57
|
+
{"title": "Build API endpoints", "complexity": 5}
|
|
58
|
+
],
|
|
59
|
+
"files": [
|
|
60
|
+
{"path": "schema.prisma", "kind": "file"}
|
|
61
|
+
],
|
|
62
|
+
"questions": []
|
|
63
|
+
}
|
|
64
|
+
<!-- ASTRO_JSON_END -->
|
|
65
|
+
|
|
66
|
+
If blocked, set status="blocked" and add ONE question to questions array. Do not deviate from this format.
|
|
55
67
|
`;
|
package/src/tools/workflow.ts
CHANGED
|
@@ -153,6 +153,28 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
|
|
|
153
153
|
await toasts.show({ title: "Astrocode", message: `Run completed (${next.run_id})`, variant: "success" });
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
// Inject continuation directive for workflow resumption
|
|
157
|
+
if (sessionId) {
|
|
158
|
+
const continueDirective = [
|
|
159
|
+
`[SYSTEM DIRECTIVE: ASTROCODE — CONTINUE]`,
|
|
160
|
+
``,
|
|
161
|
+
`Run ${next.run_id} completed successfully.`,
|
|
162
|
+
``,
|
|
163
|
+
`The Clara Forms implementation run has finished all stages. The spec has been analyzed and decomposed into prioritized implementation stories.`,
|
|
164
|
+
``,
|
|
165
|
+
`Next actions: Review the generated stories and approve the next one to continue development.`,
|
|
166
|
+
].join("\n");
|
|
167
|
+
|
|
168
|
+
await injectChatPrompt({
|
|
169
|
+
ctx,
|
|
170
|
+
sessionId,
|
|
171
|
+
text: continueDirective,
|
|
172
|
+
agent: "Astro"
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
actions.push(`injected continuation directive for completed run ${next.run_id}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
156
178
|
// Check for next approved story to start
|
|
157
179
|
const nextStory = db.prepare(
|
|
158
180
|
"SELECT story_key, title FROM stories WHERE state = 'approved' ORDER BY priority DESC, created_at ASC LIMIT 1"
|
package/src/workflow/baton.ts
CHANGED
|
@@ -80,11 +80,27 @@ export function parseStageOutputText(text: string): ParsedStageOutput {
|
|
|
80
80
|
let fallbackUsed = false;
|
|
81
81
|
|
|
82
82
|
if (beginIdx === -1 || endIdx === -1 || endIdx <= beginIdx) {
|
|
83
|
+
// Enhanced fallback: scan for any JSON object in the text
|
|
84
|
+
const jsonMatch = norm.match(/\{[\s\S]*\}/);
|
|
85
|
+
if (jsonMatch) {
|
|
86
|
+
try {
|
|
87
|
+
const parsed = JSON.parse(jsonMatch[0]) as unknown;
|
|
88
|
+
const astroJson = AstroJsonSchema.parse(parsed);
|
|
89
|
+
return {
|
|
90
|
+
baton_md: norm.replace(jsonMatch[0], "").trim(),
|
|
91
|
+
astro_json: astroJson,
|
|
92
|
+
astro_json_raw: jsonMatch[0],
|
|
93
|
+
error: null
|
|
94
|
+
};
|
|
95
|
+
} catch (e) {
|
|
96
|
+
// JSON found but invalid, continue to marker error
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
83
100
|
// Fallback: if no markers, check if the entire text is JSON
|
|
84
101
|
try {
|
|
85
102
|
const parsed = JSON.parse(norm) as unknown;
|
|
86
103
|
const astroJson = AstroJsonSchema.parse(parsed);
|
|
87
|
-
debug("Used JSON fallback parsing (no markers found)", { stage_key: astroJson.stage_key });
|
|
88
104
|
return {
|
|
89
105
|
baton_md: "",
|
|
90
106
|
astro_json: astroJson,
|
|
@@ -99,7 +115,7 @@ export function parseStageOutputText(text: string): ParsedStageOutput {
|
|
|
99
115
|
baton_md: norm,
|
|
100
116
|
astro_json: null,
|
|
101
117
|
astro_json_raw: null,
|
|
102
|
-
error: `Missing ASTRO JSON markers. Expected markers ${ASTRO_JSON_BEGIN} ... ${ASTRO_JSON_END}. If output
|
|
118
|
+
error: `Missing ASTRO JSON markers. Expected markers ${ASTRO_JSON_BEGIN} ... ${ASTRO_JSON_END}. If output contains JSON, ensure it's valid.`,
|
|
103
119
|
};
|
|
104
120
|
}
|
|
105
121
|
|