astrocode-workflow 0.1.20 → 0.1.24
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/shared/paths.js +14 -2
- package/dist/tools/workflow.js +4 -8
- package/dist/ui/inject.js +5 -3
- package/dist/workflow/directives.js +8 -1
- package/package.json +1 -1
- package/src/shared/paths.ts +17 -2
- package/src/tools/workflow.ts +9 -13
- package/src/ui/inject.ts +6 -3
- package/src/workflow/directives.ts +8 -1
package/dist/shared/paths.js
CHANGED
|
@@ -42,9 +42,21 @@ export function assertInsideAstro(repoRoot, filePath) {
|
|
|
42
42
|
const absRepo = path.resolve(repoRoot);
|
|
43
43
|
const abs = path.resolve(filePath);
|
|
44
44
|
const astroRoot = path.resolve(path.join(repoRoot, ".astro"));
|
|
45
|
+
// Allow writing certain files in the repo root
|
|
46
|
+
const relPath = path.relative(repoRoot, filePath);
|
|
47
|
+
const allowedOutside = [
|
|
48
|
+
"stories.md",
|
|
49
|
+
"README.md",
|
|
50
|
+
"CHANGELOG.md",
|
|
51
|
+
"CONTRIBUTING.md",
|
|
52
|
+
"LICENSE",
|
|
53
|
+
".gitignore"
|
|
54
|
+
];
|
|
45
55
|
if (!abs.startsWith(astroRoot + path.sep) && abs !== astroRoot) {
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
// Check if it's an allowed file in repo root
|
|
57
|
+
if (!allowedOutside.includes(relPath)) {
|
|
58
|
+
throw new Error(`Refusing to write outside .astro: ${filePath} (relative: ${relPath}, astroRoot: ${astroRoot})`);
|
|
59
|
+
}
|
|
48
60
|
}
|
|
49
61
|
if (!abs.startsWith(absRepo + path.sep) && abs !== absRepo) {
|
|
50
62
|
throw new Error(`Refusing to write outside repo root: ${filePath}`);
|
package/dist/tools/workflow.js
CHANGED
|
@@ -154,16 +154,12 @@ export function createAstroWorkflowProceedTool(opts) {
|
|
|
154
154
|
return false;
|
|
155
155
|
};
|
|
156
156
|
if (!agentExists(agentName)) {
|
|
157
|
-
console.warn(`[Astrocode] Agent ${agentName} not found in config. Falling back to General.`);
|
|
157
|
+
console.warn(`[Astrocode] Agent ${agentName} not found in config. Falling back to orchestrator instead of General.`);
|
|
158
158
|
console.warn(`[Astrocode] Agent check: config.agent exists: ${!!systemConfig.agent}, agentName in config: ${systemConfig.agent ? agentName in systemConfig.agent : 'N/A'}`);
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
// Skip General fallback for stage agents to avoid malformed output
|
|
160
|
+
agentName = config.agents?.orchestrator_name || "Astro";
|
|
161
161
|
if (!agentExists(agentName)) {
|
|
162
|
-
|
|
163
|
-
agentName = config.agents?.orchestrator_name || "Astro";
|
|
164
|
-
if (!agentExists(agentName)) {
|
|
165
|
-
throw new Error(`Critical: No agents available for delegation. Primary: ${resolveAgentName(next.stage_key, config)}, General, Orchestrator: ${agentName}`);
|
|
166
|
-
}
|
|
162
|
+
throw new Error(`Critical: No agents available for delegation. Primary: ${resolveAgentName(next.stage_key, config)}, Orchestrator: ${agentName}`);
|
|
167
163
|
}
|
|
168
164
|
}
|
|
169
165
|
console.log(`[Astrocode] Delegating stage ${next.stage_key} to agent: ${agentName}`);
|
package/dist/ui/inject.js
CHANGED
|
@@ -2,9 +2,11 @@ let isInjecting = false;
|
|
|
2
2
|
let queuedInjection = null;
|
|
3
3
|
export async function injectChatPrompt(opts) {
|
|
4
4
|
const { ctx, sessionId, text } = opts;
|
|
5
|
+
// Prefix to clearly indicate source as Astro agent
|
|
6
|
+
const prefixedText = `[Astro Agent]\n\n${text}`;
|
|
5
7
|
if (isInjecting) {
|
|
6
8
|
// Replace any existing queued injection (keep only latest)
|
|
7
|
-
queuedInjection = opts;
|
|
9
|
+
queuedInjection = { ...opts, text: prefixedText };
|
|
8
10
|
return;
|
|
9
11
|
}
|
|
10
12
|
isInjecting = true;
|
|
@@ -12,7 +14,7 @@ export async function injectChatPrompt(opts) {
|
|
|
12
14
|
await ctx.client.session.prompt({
|
|
13
15
|
path: { id: sessionId },
|
|
14
16
|
body: {
|
|
15
|
-
parts: [{ type: "text", text }],
|
|
17
|
+
parts: [{ type: "text", text: prefixedText }],
|
|
16
18
|
},
|
|
17
19
|
});
|
|
18
20
|
}
|
|
@@ -23,7 +25,7 @@ export async function injectChatPrompt(opts) {
|
|
|
23
25
|
const next = queuedInjection;
|
|
24
26
|
queuedInjection = null;
|
|
25
27
|
// Schedule next injection asynchronously to prevent recursion
|
|
26
|
-
setImmediate(() => injectChatPrompt(
|
|
28
|
+
setImmediate(() => injectChatPrompt({ ...queuedInjection, text: prefixedText }));
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -10,6 +10,8 @@ export function buildContinueDirective(opts) {
|
|
|
10
10
|
const body = clampChars(normalizeNewlines([
|
|
11
11
|
`[SYSTEM DIRECTIVE: ASTROCODE — CONTINUE]`,
|
|
12
12
|
``,
|
|
13
|
+
`This directive is injected by the Astro agent to continue the workflow.`,
|
|
14
|
+
``,
|
|
13
15
|
`Run: \`${run_id}\`${stage_key ? ` Stage: \`${stage_key}\`` : ""}`,
|
|
14
16
|
``,
|
|
15
17
|
`Next action: ${next_action}`,
|
|
@@ -34,6 +36,8 @@ export function buildBlockedDirective(opts) {
|
|
|
34
36
|
const body = normalizeNewlines([
|
|
35
37
|
`[SYSTEM DIRECTIVE: ASTROCODE — BLOCKED]`,
|
|
36
38
|
``,
|
|
39
|
+
`This directive is injected by the Astro agent indicating the workflow is blocked.`,
|
|
40
|
+
``,
|
|
37
41
|
`Run: \`${run_id}\` Stage: \`${stage_key}\``,
|
|
38
42
|
``,
|
|
39
43
|
`You are blocked. Ask the user exactly ONE question (below), then stop.`,
|
|
@@ -54,6 +58,8 @@ export function buildRepairDirective(opts) {
|
|
|
54
58
|
const body = normalizeNewlines([
|
|
55
59
|
`[SYSTEM DIRECTIVE: ASTROCODE — REPAIR]`,
|
|
56
60
|
``,
|
|
61
|
+
`This directive is injected by the Astro agent after performing a repair pass.`,
|
|
62
|
+
``,
|
|
57
63
|
`Astrocode performed a repair pass. Summarize in <= 10 lines and continue.`,
|
|
58
64
|
``,
|
|
59
65
|
`Repair report:`,
|
|
@@ -75,6 +81,8 @@ export function buildStageDirective(opts) {
|
|
|
75
81
|
const body = clampChars(normalizeNewlines([
|
|
76
82
|
`[SYSTEM DIRECTIVE: ASTROCODE — STAGE_${stageKeyUpper}]`,
|
|
77
83
|
``,
|
|
84
|
+
`This directive is injected by the Astro agent to delegate the stage task.`,
|
|
85
|
+
``,
|
|
78
86
|
`You are: \`${stage_agent_name}\``,
|
|
79
87
|
`Run: \`${run_id}\``,
|
|
80
88
|
`Story: \`${story_key}\` — ${story_title}`,
|
|
@@ -90,7 +98,6 @@ export function buildStageDirective(opts) {
|
|
|
90
98
|
` "schema_version": 1,`,
|
|
91
99
|
` "stage_key": "${stage_key}",`,
|
|
92
100
|
` "status": "ok",`,
|
|
93
|
-
` "summary": "Brief summary of work done",`,
|
|
94
101
|
` ...`,
|
|
95
102
|
` }`,
|
|
96
103
|
` ${"<!-- ASTRO_JSON_END -->"}`,
|
package/package.json
CHANGED
package/src/shared/paths.ts
CHANGED
|
@@ -61,10 +61,25 @@ export function assertInsideAstro(repoRoot: string, filePath: string) {
|
|
|
61
61
|
const absRepo = path.resolve(repoRoot);
|
|
62
62
|
const abs = path.resolve(filePath);
|
|
63
63
|
const astroRoot = path.resolve(path.join(repoRoot, ".astro"));
|
|
64
|
+
|
|
65
|
+
// Allow writing certain files in the repo root
|
|
66
|
+
const relPath = path.relative(repoRoot, filePath);
|
|
67
|
+
const allowedOutside = [
|
|
68
|
+
"stories.md",
|
|
69
|
+
"README.md",
|
|
70
|
+
"CHANGELOG.md",
|
|
71
|
+
"CONTRIBUTING.md",
|
|
72
|
+
"LICENSE",
|
|
73
|
+
".gitignore"
|
|
74
|
+
];
|
|
75
|
+
|
|
64
76
|
if (!abs.startsWith(astroRoot + path.sep) && abs !== astroRoot) {
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
// Check if it's an allowed file in repo root
|
|
78
|
+
if (!allowedOutside.includes(relPath)) {
|
|
79
|
+
throw new Error(`Refusing to write outside .astro: ${filePath} (relative: ${relPath}, astroRoot: ${astroRoot})`);
|
|
80
|
+
}
|
|
67
81
|
}
|
|
82
|
+
|
|
68
83
|
if (!abs.startsWith(absRepo + path.sep) && abs !== absRepo) {
|
|
69
84
|
throw new Error(`Refusing to write outside repo root: ${filePath}`);
|
|
70
85
|
}
|
package/src/tools/workflow.ts
CHANGED
|
@@ -187,19 +187,15 @@ export function createAstroWorkflowProceedTool(opts: { ctx: any; config: Astroco
|
|
|
187
187
|
return false;
|
|
188
188
|
};
|
|
189
189
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
throw new Error(`Critical: No agents available for delegation. Primary: ${resolveAgentName(next.stage_key, config)}, General, Orchestrator: ${agentName}`);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
190
|
+
if (!agentExists(agentName)) {
|
|
191
|
+
console.warn(`[Astrocode] Agent ${agentName} not found in config. Falling back to orchestrator instead of General.`);
|
|
192
|
+
console.warn(`[Astrocode] Agent check: config.agent exists: ${!!systemConfig.agent}, agentName in config: ${systemConfig.agent ? agentName in systemConfig.agent : 'N/A'}`);
|
|
193
|
+
// Skip General fallback for stage agents to avoid malformed output
|
|
194
|
+
agentName = config.agents?.orchestrator_name || "Astro";
|
|
195
|
+
if (!agentExists(agentName)) {
|
|
196
|
+
throw new Error(`Critical: No agents available for delegation. Primary: ${resolveAgentName(next.stage_key, config)}, Orchestrator: ${agentName}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
203
199
|
|
|
204
200
|
console.log(`[Astrocode] Delegating stage ${next.stage_key} to agent: ${agentName}`);
|
|
205
201
|
|
package/src/ui/inject.ts
CHANGED
|
@@ -8,9 +8,12 @@ export async function injectChatPrompt(opts: {
|
|
|
8
8
|
}) {
|
|
9
9
|
const { ctx, sessionId, text } = opts;
|
|
10
10
|
|
|
11
|
+
// Prefix to clearly indicate source as Astro agent
|
|
12
|
+
const prefixedText = `[Astro Agent]\n\n${text}`;
|
|
13
|
+
|
|
11
14
|
if (isInjecting) {
|
|
12
15
|
// Replace any existing queued injection (keep only latest)
|
|
13
|
-
queuedInjection = opts;
|
|
16
|
+
queuedInjection = { ...opts, text: prefixedText };
|
|
14
17
|
return;
|
|
15
18
|
}
|
|
16
19
|
|
|
@@ -20,7 +23,7 @@ export async function injectChatPrompt(opts: {
|
|
|
20
23
|
await ctx.client.session.prompt({
|
|
21
24
|
path: { id: sessionId },
|
|
22
25
|
body: {
|
|
23
|
-
parts: [{ type: "text", text }],
|
|
26
|
+
parts: [{ type: "text", text: prefixedText }],
|
|
24
27
|
},
|
|
25
28
|
});
|
|
26
29
|
} finally {
|
|
@@ -30,7 +33,7 @@ export async function injectChatPrompt(opts: {
|
|
|
30
33
|
const next = queuedInjection;
|
|
31
34
|
queuedInjection = null;
|
|
32
35
|
// Schedule next injection asynchronously to prevent recursion
|
|
33
|
-
setImmediate(() => injectChatPrompt(
|
|
36
|
+
setImmediate(() => injectChatPrompt({ ...queuedInjection, text: prefixedText }));
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
}
|
|
@@ -32,6 +32,8 @@ export function buildContinueDirective(opts: {
|
|
|
32
32
|
[
|
|
33
33
|
`[SYSTEM DIRECTIVE: ASTROCODE — CONTINUE]`,
|
|
34
34
|
``,
|
|
35
|
+
`This directive is injected by the Astro agent to continue the workflow.`,
|
|
36
|
+
``,
|
|
35
37
|
`Run: \`${run_id}\`${stage_key ? ` Stage: \`${stage_key}\`` : ""}`,
|
|
36
38
|
``,
|
|
37
39
|
`Next action: ${next_action}`,
|
|
@@ -67,6 +69,8 @@ export function buildBlockedDirective(opts: {
|
|
|
67
69
|
[
|
|
68
70
|
`[SYSTEM DIRECTIVE: ASTROCODE — BLOCKED]`,
|
|
69
71
|
``,
|
|
72
|
+
`This directive is injected by the Astro agent indicating the workflow is blocked.`,
|
|
73
|
+
``,
|
|
70
74
|
`Run: \`${run_id}\` Stage: \`${stage_key}\``,
|
|
71
75
|
``,
|
|
72
76
|
`You are blocked. Ask the user exactly ONE question (below), then stop.`,
|
|
@@ -91,6 +95,8 @@ export function buildRepairDirective(opts: { report_md: string }): BuiltDirectiv
|
|
|
91
95
|
[
|
|
92
96
|
`[SYSTEM DIRECTIVE: ASTROCODE — REPAIR]`,
|
|
93
97
|
``,
|
|
98
|
+
`This directive is injected by the Astro agent after performing a repair pass.`,
|
|
99
|
+
``,
|
|
94
100
|
`Astrocode performed a repair pass. Summarize in <= 10 lines and continue.`,
|
|
95
101
|
``,
|
|
96
102
|
`Repair report:`,
|
|
@@ -130,6 +136,8 @@ export function buildStageDirective(opts: {
|
|
|
130
136
|
[
|
|
131
137
|
`[SYSTEM DIRECTIVE: ASTROCODE — STAGE_${stageKeyUpper}]`,
|
|
132
138
|
``,
|
|
139
|
+
`This directive is injected by the Astro agent to delegate the stage task.`,
|
|
140
|
+
``,
|
|
133
141
|
`You are: \`${stage_agent_name}\``,
|
|
134
142
|
`Run: \`${run_id}\``,
|
|
135
143
|
`Story: \`${story_key}\` — ${story_title}`,
|
|
@@ -145,7 +153,6 @@ export function buildStageDirective(opts: {
|
|
|
145
153
|
` "schema_version": 1,`,
|
|
146
154
|
` "stage_key": "${stage_key}",`,
|
|
147
155
|
` "status": "ok",`,
|
|
148
|
-
` "summary": "Brief summary of work done",`,
|
|
149
156
|
` ...`,
|
|
150
157
|
` }`,
|
|
151
158
|
` ${"<!-- ASTRO_JSON_END -->"}`,
|