astrocode-workflow 0.1.20 → 0.1.23

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.
@@ -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
- const relPath = path.relative(repoRoot, filePath);
47
- throw new Error(`Refusing to write outside .astro: ${filePath} (relative: ${relPath}, astroRoot: ${astroRoot})`);
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/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(next));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astrocode-workflow",
3
- "version": "0.1.20",
3
+ "version": "0.1.23",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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
- const relPath = path.relative(repoRoot, filePath);
66
- throw new Error(`Refusing to write outside .astro: ${filePath} (relative: ${relPath}, astroRoot: ${astroRoot})`);
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/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(next));
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 -->"}`,