astrocode-workflow 0.0.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.
- package/LICENSE +1 -0
- package/README.md +85 -0
- package/dist/agents/commands.d.ts +9 -0
- package/dist/agents/commands.js +121 -0
- package/dist/agents/prompts.d.ts +2 -0
- package/dist/agents/prompts.js +27 -0
- package/dist/agents/registry.d.ts +6 -0
- package/dist/agents/registry.js +223 -0
- package/dist/agents/types.d.ts +14 -0
- package/dist/agents/types.js +8 -0
- package/dist/config/config-handler.d.ts +4 -0
- package/dist/config/config-handler.js +46 -0
- package/dist/config/defaults.d.ts +3 -0
- package/dist/config/defaults.js +3 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.js +48 -0
- package/dist/config/schema.d.ts +176 -0
- package/dist/config/schema.js +198 -0
- package/dist/hooks/continuation-enforcer.d.ts +26 -0
- package/dist/hooks/continuation-enforcer.js +166 -0
- package/dist/hooks/tool-output-truncator.d.ts +17 -0
- package/dist/hooks/tool-output-truncator.js +56 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +108 -0
- package/dist/shared/deep-merge.d.ts +8 -0
- package/dist/shared/deep-merge.js +25 -0
- package/dist/shared/hash.d.ts +1 -0
- package/dist/shared/hash.js +4 -0
- package/dist/shared/log.d.ts +7 -0
- package/dist/shared/log.js +24 -0
- package/dist/shared/model-tuning.d.ts +9 -0
- package/dist/shared/model-tuning.js +28 -0
- package/dist/shared/paths.d.ts +19 -0
- package/dist/shared/paths.js +51 -0
- package/dist/shared/text.d.ts +4 -0
- package/dist/shared/text.js +19 -0
- package/dist/shared/time.d.ts +1 -0
- package/dist/shared/time.js +3 -0
- package/dist/state/adapters/index.d.ts +39 -0
- package/dist/state/adapters/index.js +119 -0
- package/dist/state/db.d.ts +17 -0
- package/dist/state/db.js +83 -0
- package/dist/state/ids.d.ts +8 -0
- package/dist/state/ids.js +25 -0
- package/dist/state/schema.d.ts +2 -0
- package/dist/state/schema.js +247 -0
- package/dist/state/types.d.ts +70 -0
- package/dist/state/types.js +1 -0
- package/dist/tools/artifacts.d.ts +18 -0
- package/dist/tools/artifacts.js +71 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.js +100 -0
- package/dist/tools/init.d.ts +8 -0
- package/dist/tools/init.js +41 -0
- package/dist/tools/injects.d.ts +23 -0
- package/dist/tools/injects.js +99 -0
- package/dist/tools/repair.d.ts +8 -0
- package/dist/tools/repair.js +25 -0
- package/dist/tools/run.d.ts +13 -0
- package/dist/tools/run.js +54 -0
- package/dist/tools/spec.d.ts +13 -0
- package/dist/tools/spec.js +41 -0
- package/dist/tools/stage.d.ts +23 -0
- package/dist/tools/stage.js +284 -0
- package/dist/tools/status.d.ts +8 -0
- package/dist/tools/status.js +107 -0
- package/dist/tools/story.d.ts +23 -0
- package/dist/tools/story.js +85 -0
- package/dist/tools/workflow.d.ts +8 -0
- package/dist/tools/workflow.js +197 -0
- package/dist/ui/inject.d.ts +5 -0
- package/dist/ui/inject.js +9 -0
- package/dist/ui/toasts.d.ts +13 -0
- package/dist/ui/toasts.js +39 -0
- package/dist/workflow/artifacts.d.ts +24 -0
- package/dist/workflow/artifacts.js +45 -0
- package/dist/workflow/baton.d.ts +66 -0
- package/dist/workflow/baton.js +101 -0
- package/dist/workflow/context.d.ts +12 -0
- package/dist/workflow/context.js +67 -0
- package/dist/workflow/directives.d.ts +37 -0
- package/dist/workflow/directives.js +111 -0
- package/dist/workflow/repair.d.ts +8 -0
- package/dist/workflow/repair.js +99 -0
- package/dist/workflow/state-machine.d.ts +43 -0
- package/dist/workflow/state-machine.js +127 -0
- package/dist/workflow/story-helpers.d.ts +9 -0
- package/dist/workflow/story-helpers.js +13 -0
- package/package.json +32 -0
- package/src/agents/commands.ts +137 -0
- package/src/agents/prompts.ts +28 -0
- package/src/agents/registry.ts +310 -0
- package/src/agents/types.ts +31 -0
- package/src/config/config-handler.ts +48 -0
- package/src/config/defaults.ts +4 -0
- package/src/config/loader.ts +55 -0
- package/src/config/schema.ts +236 -0
- package/src/hooks/continuation-enforcer.ts +217 -0
- package/src/hooks/tool-output-truncator.ts +82 -0
- package/src/index.ts +131 -0
- package/src/shared/deep-merge.ts +28 -0
- package/src/shared/hash.ts +5 -0
- package/src/shared/log.ts +30 -0
- package/src/shared/model-tuning.ts +48 -0
- package/src/shared/paths.ts +70 -0
- package/src/shared/text.ts +20 -0
- package/src/shared/time.ts +3 -0
- package/src/shims.node.d.ts +20 -0
- package/src/state/adapters/index.ts +155 -0
- package/src/state/db.ts +105 -0
- package/src/state/ids.ts +33 -0
- package/src/state/schema.ts +249 -0
- package/src/state/types.ts +76 -0
- package/src/tools/artifacts.ts +83 -0
- package/src/tools/index.ts +111 -0
- package/src/tools/init.ts +50 -0
- package/src/tools/injects.ts +108 -0
- package/src/tools/repair.ts +31 -0
- package/src/tools/run.ts +62 -0
- package/src/tools/spec.ts +50 -0
- package/src/tools/stage.ts +361 -0
- package/src/tools/status.ts +119 -0
- package/src/tools/story.ts +106 -0
- package/src/tools/workflow.ts +241 -0
- package/src/ui/inject.ts +13 -0
- package/src/ui/toasts.ts +48 -0
- package/src/workflow/artifacts.ts +69 -0
- package/src/workflow/baton.ts +141 -0
- package/src/workflow/context.ts +86 -0
- package/src/workflow/directives.ts +170 -0
- package/src/workflow/repair.ts +138 -0
- package/src/workflow/state-machine.ts +194 -0
- package/src/workflow/story-helpers.ts +18 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const PermissionValueSchema: z.ZodEnum<{
|
|
3
|
+
ask: "ask";
|
|
4
|
+
allow: "allow";
|
|
5
|
+
deny: "deny";
|
|
6
|
+
}>;
|
|
7
|
+
export type PermissionValue = z.infer<typeof PermissionValueSchema>;
|
|
8
|
+
declare const StageKeySchema: z.ZodEnum<{
|
|
9
|
+
frame: "frame";
|
|
10
|
+
plan: "plan";
|
|
11
|
+
spec: "spec";
|
|
12
|
+
implement: "implement";
|
|
13
|
+
review: "review";
|
|
14
|
+
verify: "verify";
|
|
15
|
+
close: "close";
|
|
16
|
+
}>;
|
|
17
|
+
export type StageKey = z.infer<typeof StageKeySchema>;
|
|
18
|
+
export declare const AstrocodeConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
19
|
+
disabled_hooks: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
20
|
+
disabled_agents: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
21
|
+
disabled_commands: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
|
|
22
|
+
determinism: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
23
|
+
mode: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
24
|
+
on: "on";
|
|
25
|
+
off: "off";
|
|
26
|
+
}>>>;
|
|
27
|
+
strict_stage_order: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
28
|
+
}, z.core.$strip>>>;
|
|
29
|
+
db: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
30
|
+
path: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
31
|
+
busy_timeout_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
32
|
+
pragmas: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
33
|
+
journal_mode: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
34
|
+
WAL: "WAL";
|
|
35
|
+
DELETE: "DELETE";
|
|
36
|
+
}>>>;
|
|
37
|
+
synchronous: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
38
|
+
NORMAL: "NORMAL";
|
|
39
|
+
FULL: "FULL";
|
|
40
|
+
OFF: "OFF";
|
|
41
|
+
}>>>;
|
|
42
|
+
foreign_keys: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
43
|
+
temp_store: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
44
|
+
DEFAULT: "DEFAULT";
|
|
45
|
+
MEMORY: "MEMORY";
|
|
46
|
+
FILE: "FILE";
|
|
47
|
+
}>>>;
|
|
48
|
+
}, z.core.$strip>>>;
|
|
49
|
+
schema_version_required: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
50
|
+
allow_auto_migrate: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
51
|
+
fail_on_downgrade: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
52
|
+
}, z.core.$strip>>>;
|
|
53
|
+
workflow: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
54
|
+
pipeline: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
55
|
+
frame: "frame";
|
|
56
|
+
plan: "plan";
|
|
57
|
+
spec: "spec";
|
|
58
|
+
implement: "implement";
|
|
59
|
+
review: "review";
|
|
60
|
+
verify: "verify";
|
|
61
|
+
close: "close";
|
|
62
|
+
}>>>>;
|
|
63
|
+
default_mode: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
64
|
+
step: "step";
|
|
65
|
+
loop: "loop";
|
|
66
|
+
}>>>;
|
|
67
|
+
default_max_steps: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
68
|
+
loop_max_steps_hard_cap: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
69
|
+
plan_max_tasks: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
70
|
+
plan_max_lines: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
71
|
+
forbid_prompt_narration: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
72
|
+
single_active_run_per_repo: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
73
|
+
lock_timeout_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
74
|
+
role_first_subagents: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
75
|
+
evidence_required: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
76
|
+
verify: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
77
|
+
implement: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
78
|
+
}, z.core.$strip>>>;
|
|
79
|
+
}, z.core.$strip>>>;
|
|
80
|
+
continuation: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
81
|
+
enabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
82
|
+
injection_mode: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
83
|
+
visible: "visible";
|
|
84
|
+
silent: "silent";
|
|
85
|
+
}>>>;
|
|
86
|
+
inject_on_session_idle: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
87
|
+
session_idle_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
88
|
+
inject_on_tool_done_if_run_active: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
89
|
+
inject_on_message_done_if_run_active: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
90
|
+
dedupe_window_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
91
|
+
max_same_directive_repeats: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
92
|
+
auto_continue: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
93
|
+
auto_continue_delay_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
94
|
+
max_auto_steps_per_session: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
95
|
+
}, z.core.$strip>>>;
|
|
96
|
+
truncation: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
97
|
+
enabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
98
|
+
truncate_all_tool_outputs: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
99
|
+
max_chars_default: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
100
|
+
max_chars_webfetch: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
101
|
+
max_chars_diff: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
102
|
+
persist_truncated_outputs: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
103
|
+
}, z.core.$strip>>>;
|
|
104
|
+
context_compaction: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
105
|
+
enabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
106
|
+
snapshot_after_stage_count: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
107
|
+
snapshot_max_lines: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
108
|
+
baton_summary_max_lines: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
109
|
+
inject_max_chars: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
110
|
+
}, z.core.$strip>>>;
|
|
111
|
+
artifacts: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
112
|
+
root_dir: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
113
|
+
runs_dir: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
114
|
+
spec_path: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
115
|
+
write_full_baton_md: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
116
|
+
write_baton_summary_md: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
117
|
+
write_baton_output_json: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
118
|
+
baton_filename: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
119
|
+
baton_summary_filename: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
120
|
+
baton_json_filename: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
121
|
+
}, z.core.$strip>>>;
|
|
122
|
+
agents: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
123
|
+
orchestrator_name: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
124
|
+
stage_agent_names: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
125
|
+
frame: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
126
|
+
plan: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
127
|
+
spec: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
128
|
+
implement: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
129
|
+
review: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
130
|
+
verify: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
131
|
+
close: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
132
|
+
}, z.core.$strip>>>;
|
|
133
|
+
librarian_name: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
134
|
+
explore_name: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
135
|
+
agent_variant_overrides: z.ZodOptional<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
136
|
+
variant: z.ZodOptional<z.ZodString>;
|
|
137
|
+
model: z.ZodOptional<z.ZodString>;
|
|
138
|
+
}, z.core.$strip>>>>;
|
|
139
|
+
}, z.core.$strip>>>;
|
|
140
|
+
permissions: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
141
|
+
enforce_task_tool_restrictions: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
142
|
+
deny_delegate_task_in_subagents: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
143
|
+
}, z.core.$strip>>>;
|
|
144
|
+
git: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
145
|
+
enabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
146
|
+
allow_dirty_start: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
147
|
+
auto_branch: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
148
|
+
branch_prefix: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
149
|
+
auto_commit: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
150
|
+
commit_message_template: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
|
151
|
+
persist_diff_artifacts: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
152
|
+
}, z.core.$strip>>>;
|
|
153
|
+
ui: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
154
|
+
toasts: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
155
|
+
enabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
156
|
+
throttle_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
157
|
+
show_run_started: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
158
|
+
show_stage_started: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
159
|
+
show_stage_completed: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
160
|
+
show_stage_failed: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
161
|
+
show_run_completed: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
162
|
+
show_auto_continue: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
163
|
+
}, z.core.$strip>>>;
|
|
164
|
+
continue_prompt: z.ZodOptional<z.ZodDefault<z.ZodObject<{
|
|
165
|
+
enabled: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
166
|
+
mode: z.ZodOptional<z.ZodDefault<z.ZodEnum<{
|
|
167
|
+
toast_button: "toast_button";
|
|
168
|
+
popup: "popup";
|
|
169
|
+
chat_only: "chat_only";
|
|
170
|
+
}>>>;
|
|
171
|
+
idle_prompt_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
172
|
+
}, z.core.$strip>>>;
|
|
173
|
+
}, z.core.$strip>>>;
|
|
174
|
+
}, z.core.$strip>>;
|
|
175
|
+
export type AstrocodeConfig = z.infer<typeof AstrocodeConfigSchema>;
|
|
176
|
+
export {};
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const PermissionValueSchema = z.enum(["ask", "allow", "deny"]);
|
|
3
|
+
const StageKeySchema = z.enum([
|
|
4
|
+
"frame",
|
|
5
|
+
"plan",
|
|
6
|
+
"spec",
|
|
7
|
+
"implement",
|
|
8
|
+
"review",
|
|
9
|
+
"verify",
|
|
10
|
+
"close",
|
|
11
|
+
]);
|
|
12
|
+
const InjectionModeSchema = z.enum(["visible", "silent"]);
|
|
13
|
+
const TruncationPolicySchema = z
|
|
14
|
+
.object({
|
|
15
|
+
enabled: z.boolean().default(true),
|
|
16
|
+
truncate_all_tool_outputs: z.boolean().default(false),
|
|
17
|
+
max_chars_default: z.number().int().positive().default(200_000),
|
|
18
|
+
max_chars_webfetch: z.number().int().positive().default(40_000),
|
|
19
|
+
max_chars_diff: z.number().int().positive().default(120_000),
|
|
20
|
+
persist_truncated_outputs: z.boolean().default(true),
|
|
21
|
+
})
|
|
22
|
+
.partial()
|
|
23
|
+
.default({});
|
|
24
|
+
const ContextCompactionSchema = z
|
|
25
|
+
.object({
|
|
26
|
+
enabled: z.boolean().default(true),
|
|
27
|
+
snapshot_after_stage_count: z.number().int().positive().default(2),
|
|
28
|
+
snapshot_max_lines: z.number().int().positive().default(60),
|
|
29
|
+
baton_summary_max_lines: z.number().int().positive().default(25),
|
|
30
|
+
inject_max_chars: z.number().int().positive().default(18_000),
|
|
31
|
+
})
|
|
32
|
+
.partial()
|
|
33
|
+
.default({});
|
|
34
|
+
const ContinuationSchema = z
|
|
35
|
+
.object({
|
|
36
|
+
enabled: z.boolean().default(true),
|
|
37
|
+
injection_mode: InjectionModeSchema.default("visible"),
|
|
38
|
+
inject_on_session_idle: z.boolean().default(true),
|
|
39
|
+
session_idle_ms: z.number().int().positive().default(12_000),
|
|
40
|
+
inject_on_tool_done_if_run_active: z.boolean().default(true),
|
|
41
|
+
inject_on_message_done_if_run_active: z.boolean().default(true),
|
|
42
|
+
dedupe_window_ms: z.number().int().positive().default(20_000),
|
|
43
|
+
max_same_directive_repeats: z.number().int().positive().default(1),
|
|
44
|
+
auto_continue: z.boolean().default(false),
|
|
45
|
+
auto_continue_delay_ms: z.number().int().positive().default(1500),
|
|
46
|
+
max_auto_steps_per_session: z.number().int().positive().default(50),
|
|
47
|
+
})
|
|
48
|
+
.partial()
|
|
49
|
+
.default({});
|
|
50
|
+
const ToastsSchema = z
|
|
51
|
+
.object({
|
|
52
|
+
enabled: z.boolean().default(true),
|
|
53
|
+
throttle_ms: z.number().int().positive().default(1500),
|
|
54
|
+
show_run_started: z.boolean().default(true),
|
|
55
|
+
show_stage_started: z.boolean().default(true),
|
|
56
|
+
show_stage_completed: z.boolean().default(true),
|
|
57
|
+
show_stage_failed: z.boolean().default(true),
|
|
58
|
+
show_run_completed: z.boolean().default(true),
|
|
59
|
+
show_auto_continue: z.boolean().default(true),
|
|
60
|
+
})
|
|
61
|
+
.partial()
|
|
62
|
+
.default({});
|
|
63
|
+
const DbSchema = z
|
|
64
|
+
.object({
|
|
65
|
+
path: z.string().default(".astro/astro.db"),
|
|
66
|
+
busy_timeout_ms: z.number().int().positive().default(5000),
|
|
67
|
+
pragmas: z
|
|
68
|
+
.object({
|
|
69
|
+
journal_mode: z.enum(["WAL", "DELETE"]).default("WAL"),
|
|
70
|
+
synchronous: z.enum(["NORMAL", "FULL", "OFF"]).default("NORMAL"),
|
|
71
|
+
foreign_keys: z.boolean().default(true),
|
|
72
|
+
temp_store: z.enum(["DEFAULT", "MEMORY", "FILE"]).default("MEMORY"),
|
|
73
|
+
})
|
|
74
|
+
// Why: Zod's .default({}) requires the *type* to accept an empty object.
|
|
75
|
+
// We still want runtime defaults for each key, so we make keys optional.
|
|
76
|
+
.partial()
|
|
77
|
+
.default({}),
|
|
78
|
+
schema_version_required: z.number().int().positive().default(2),
|
|
79
|
+
allow_auto_migrate: z.boolean().default(true),
|
|
80
|
+
fail_on_downgrade: z.boolean().default(true),
|
|
81
|
+
})
|
|
82
|
+
// Why: allow "db: {}" (or missing db) while still applying defaults.
|
|
83
|
+
.partial()
|
|
84
|
+
.default({});
|
|
85
|
+
const WorkflowSchema = z.object({
|
|
86
|
+
pipeline: z.array(StageKeySchema).default([
|
|
87
|
+
"frame",
|
|
88
|
+
"plan",
|
|
89
|
+
"spec",
|
|
90
|
+
"implement",
|
|
91
|
+
"review",
|
|
92
|
+
"verify",
|
|
93
|
+
"close",
|
|
94
|
+
]),
|
|
95
|
+
default_mode: z.enum(["step", "loop"]).default("step"),
|
|
96
|
+
default_max_steps: z.number().int().positive().default(1),
|
|
97
|
+
loop_max_steps_hard_cap: z.number().int().positive().default(200),
|
|
98
|
+
plan_max_tasks: z.number().int().positive().default(7),
|
|
99
|
+
plan_max_lines: z.number().int().positive().default(80),
|
|
100
|
+
forbid_prompt_narration: z.boolean().default(true),
|
|
101
|
+
single_active_run_per_repo: z.boolean().default(true),
|
|
102
|
+
lock_timeout_ms: z.number().int().positive().default(4000),
|
|
103
|
+
role_first_subagents: z.boolean().default(true),
|
|
104
|
+
evidence_required: z
|
|
105
|
+
.object({
|
|
106
|
+
verify: z.boolean().default(true),
|
|
107
|
+
implement: z.boolean().default(false),
|
|
108
|
+
})
|
|
109
|
+
// NOTE: We want callers to be able to omit the whole object ("{}")
|
|
110
|
+
// while still receiving per-field defaults at parse time.
|
|
111
|
+
.partial()
|
|
112
|
+
.default({}),
|
|
113
|
+
}).partial().default({});
|
|
114
|
+
const ArtifactsSchema = z.object({
|
|
115
|
+
root_dir: z.string().default(".astro"),
|
|
116
|
+
runs_dir: z.string().default(".astro/runs"),
|
|
117
|
+
spec_path: z.string().default(".astro/spec.md"),
|
|
118
|
+
write_full_baton_md: z.boolean().default(true),
|
|
119
|
+
write_baton_summary_md: z.boolean().default(true),
|
|
120
|
+
write_baton_output_json: z.boolean().default(true),
|
|
121
|
+
baton_filename: z.string().default("baton.md"),
|
|
122
|
+
baton_summary_filename: z.string().default("baton.summary.md"),
|
|
123
|
+
baton_json_filename: z.string().default("baton.json"),
|
|
124
|
+
}).partial().default({});
|
|
125
|
+
const AgentsSchema = z.object({
|
|
126
|
+
// Display name for the *primary* agent tab.
|
|
127
|
+
orchestrator_name: z.string().default("Astro"),
|
|
128
|
+
// Display names for the stage sub-agents.
|
|
129
|
+
stage_agent_names: z
|
|
130
|
+
.object({
|
|
131
|
+
frame: z.string().default("Astro — Frame"),
|
|
132
|
+
plan: z.string().default("Astro — Plan"),
|
|
133
|
+
spec: z.string().default("Astro — Spec"),
|
|
134
|
+
implement: z.string().default("Astro — Implement"),
|
|
135
|
+
review: z.string().default("Astro — Review"),
|
|
136
|
+
verify: z.string().default("Astro — Verify"),
|
|
137
|
+
close: z.string().default("Astro — Close"),
|
|
138
|
+
})
|
|
139
|
+
.partial()
|
|
140
|
+
.default({}),
|
|
141
|
+
librarian_name: z.string().default("Astro — Librarian"),
|
|
142
|
+
explore_name: z.string().default("Astro — Explore"),
|
|
143
|
+
agent_variant_overrides: z
|
|
144
|
+
.record(z.string(), z.object({
|
|
145
|
+
variant: z.string().optional(),
|
|
146
|
+
model: z.string().optional(),
|
|
147
|
+
}))
|
|
148
|
+
.default({}),
|
|
149
|
+
}).partial().default({});
|
|
150
|
+
const PermissionsSchema = z.object({
|
|
151
|
+
enforce_task_tool_restrictions: z.boolean().default(true),
|
|
152
|
+
deny_delegate_task_in_subagents: z.boolean().default(true),
|
|
153
|
+
}).partial().default({});
|
|
154
|
+
const GitSchema = z.object({
|
|
155
|
+
enabled: z.boolean().default(true),
|
|
156
|
+
allow_dirty_start: z.boolean().default(true),
|
|
157
|
+
auto_branch: z.boolean().default(true),
|
|
158
|
+
branch_prefix: z.string().default("astro/"),
|
|
159
|
+
auto_commit: z.boolean().default(false),
|
|
160
|
+
commit_message_template: z.string().default("astro: {{story_key}} {{title}}"),
|
|
161
|
+
persist_diff_artifacts: z.boolean().default(true),
|
|
162
|
+
}).partial().default({});
|
|
163
|
+
const UiSchema = z
|
|
164
|
+
.object({
|
|
165
|
+
toasts: ToastsSchema,
|
|
166
|
+
continue_prompt: z
|
|
167
|
+
.object({
|
|
168
|
+
enabled: z.boolean().default(true),
|
|
169
|
+
mode: z.enum(["toast_button", "popup", "chat_only"]).default("toast_button"),
|
|
170
|
+
idle_prompt_ms: z.number().int().positive().default(20_000),
|
|
171
|
+
})
|
|
172
|
+
.partial()
|
|
173
|
+
.default({}),
|
|
174
|
+
})
|
|
175
|
+
.partial()
|
|
176
|
+
.default({});
|
|
177
|
+
export const AstrocodeConfigSchema = z.object({
|
|
178
|
+
disabled_hooks: z.array(z.string()).default([]),
|
|
179
|
+
disabled_agents: z.array(z.string()).default([]),
|
|
180
|
+
disabled_commands: z.array(z.string()).default([]),
|
|
181
|
+
determinism: z
|
|
182
|
+
.object({
|
|
183
|
+
mode: z.enum(["on", "off"]).default("on"),
|
|
184
|
+
strict_stage_order: z.boolean().default(true),
|
|
185
|
+
})
|
|
186
|
+
.partial()
|
|
187
|
+
.default({}),
|
|
188
|
+
db: DbSchema,
|
|
189
|
+
workflow: WorkflowSchema,
|
|
190
|
+
continuation: ContinuationSchema,
|
|
191
|
+
truncation: TruncationPolicySchema,
|
|
192
|
+
context_compaction: ContextCompactionSchema,
|
|
193
|
+
artifacts: ArtifactsSchema,
|
|
194
|
+
agents: AgentsSchema,
|
|
195
|
+
permissions: PermissionsSchema,
|
|
196
|
+
git: GitSchema,
|
|
197
|
+
ui: UiSchema,
|
|
198
|
+
}).partial().default({});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AstrocodeConfig } from "../config/schema";
|
|
2
|
+
import type { SqliteDb } from "../state/db";
|
|
3
|
+
type ToolExecuteAfterInput = {
|
|
4
|
+
tool: string;
|
|
5
|
+
sessionID?: string;
|
|
6
|
+
};
|
|
7
|
+
type ChatMessageInput = {
|
|
8
|
+
sessionID: string;
|
|
9
|
+
agent: string;
|
|
10
|
+
};
|
|
11
|
+
type EventInput = {
|
|
12
|
+
event: {
|
|
13
|
+
type: string;
|
|
14
|
+
properties: any;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare function createContinuationEnforcer(opts: {
|
|
18
|
+
ctx: any;
|
|
19
|
+
config: AstrocodeConfig;
|
|
20
|
+
db: SqliteDb;
|
|
21
|
+
}): {
|
|
22
|
+
onToolAfter(input: ToolExecuteAfterInput): Promise<void>;
|
|
23
|
+
onChatMessage(_input: ChatMessageInput): Promise<void>;
|
|
24
|
+
onEvent(input: EventInput): Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { buildContextSnapshot } from "../workflow/context";
|
|
2
|
+
import { decideNextAction, getActiveRun } from "../workflow/state-machine";
|
|
3
|
+
import { buildContinueDirective } from "../workflow/directives";
|
|
4
|
+
import { injectChatPrompt } from "../ui/inject";
|
|
5
|
+
import { nowISO } from "../shared/time";
|
|
6
|
+
import { createToastManager } from "../ui/toasts";
|
|
7
|
+
function msFromIso(iso) {
|
|
8
|
+
const t = Date.parse(iso);
|
|
9
|
+
return Number.isFinite(t) ? t : 0;
|
|
10
|
+
}
|
|
11
|
+
export function createContinuationEnforcer(opts) {
|
|
12
|
+
const { ctx, config, db } = opts;
|
|
13
|
+
const toasts = createToastManager({ ctx, throttleMs: config.ui.toasts.throttle_ms });
|
|
14
|
+
const sessions = new Map();
|
|
15
|
+
function getState(sessionId) {
|
|
16
|
+
const cur = sessions.get(sessionId);
|
|
17
|
+
if (cur)
|
|
18
|
+
return cur;
|
|
19
|
+
const state = { lastHash: null, lastAtMs: 0, repeats: 0, autoSteps: 0, idleTimer: null };
|
|
20
|
+
sessions.set(sessionId, state);
|
|
21
|
+
return state;
|
|
22
|
+
}
|
|
23
|
+
function clearIdleTimer(sessionId) {
|
|
24
|
+
const s = getState(sessionId);
|
|
25
|
+
if (s.idleTimer) {
|
|
26
|
+
clearTimeout(s.idleTimer);
|
|
27
|
+
s.idleTimer = null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function scheduleIdleInjection(sessionId) {
|
|
31
|
+
clearIdleTimer(sessionId);
|
|
32
|
+
if (!config.continuation.enabled)
|
|
33
|
+
return;
|
|
34
|
+
if (!config.continuation.inject_on_session_idle)
|
|
35
|
+
return;
|
|
36
|
+
const delay = config.continuation.session_idle_ms;
|
|
37
|
+
const s = getState(sessionId);
|
|
38
|
+
s.idleTimer = setTimeout(() => {
|
|
39
|
+
// Fire and forget
|
|
40
|
+
void maybeInjectContinue(sessionId, "idle_timer");
|
|
41
|
+
}, delay);
|
|
42
|
+
}
|
|
43
|
+
function shouldDedupe(sessionId, directive) {
|
|
44
|
+
const s = getState(sessionId);
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
// Memory window
|
|
47
|
+
if (s.lastHash === directive.hash && now - s.lastAtMs < config.continuation.dedupe_window_ms) {
|
|
48
|
+
if (s.repeats >= config.continuation.max_same_directive_repeats)
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
// DB window (durable)
|
|
52
|
+
const cutoff = new Date(now - config.continuation.dedupe_window_ms).toISOString();
|
|
53
|
+
const row = db
|
|
54
|
+
.prepare("SELECT COUNT(*) as c FROM continuations WHERE session_id=? AND directive_hash=? AND created_at > ?")
|
|
55
|
+
.get(sessionId, directive.hash, cutoff);
|
|
56
|
+
if ((row?.c ?? 0) >= config.continuation.max_same_directive_repeats)
|
|
57
|
+
return true;
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
async function recordContinuation(sessionId, runId, directive, reason) {
|
|
61
|
+
db.prepare("INSERT INTO continuations (session_id, run_id, directive_hash, kind, reason, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(sessionId, runId, directive.hash, directive.kind, reason, nowISO());
|
|
62
|
+
const s = getState(sessionId);
|
|
63
|
+
const now = Date.now();
|
|
64
|
+
if (s.lastHash === directive.hash && now - s.lastAtMs < config.continuation.dedupe_window_ms) {
|
|
65
|
+
s.repeats += 1;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
s.lastHash = directive.hash;
|
|
69
|
+
s.repeats = 1;
|
|
70
|
+
}
|
|
71
|
+
s.lastAtMs = now;
|
|
72
|
+
}
|
|
73
|
+
function formatNextAction(next) {
|
|
74
|
+
switch (next.kind) {
|
|
75
|
+
case "idle":
|
|
76
|
+
return "No approved stories. Queue/approve a story.";
|
|
77
|
+
case "start_run":
|
|
78
|
+
return `Start run for story ${next.story_key}.`;
|
|
79
|
+
case "delegate_stage":
|
|
80
|
+
return `Delegate stage ${next.stage_key}.`;
|
|
81
|
+
case "await_stage_completion":
|
|
82
|
+
return `Await stage ${next.stage_key} completion. If you have stage output, call astro_stage_complete.`;
|
|
83
|
+
case "complete_run":
|
|
84
|
+
return `Complete run ${next.run_id}.`;
|
|
85
|
+
case "failed":
|
|
86
|
+
return `Run failed at stage ${next.stage_key}: ${next.error_text}`;
|
|
87
|
+
default:
|
|
88
|
+
return "Continue.";
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function maybeInjectContinue(sessionId, reason) {
|
|
92
|
+
if (!config.continuation.enabled)
|
|
93
|
+
return;
|
|
94
|
+
// Require active run
|
|
95
|
+
const active = getActiveRun(db);
|
|
96
|
+
if (!active)
|
|
97
|
+
return;
|
|
98
|
+
const next = decideNextAction(db, config);
|
|
99
|
+
// If failed, don't auto-inject "continue" — surface via toast and stop.
|
|
100
|
+
if (next.kind === "failed") {
|
|
101
|
+
if (config.ui.toasts.enabled && config.ui.toasts.show_stage_failed) {
|
|
102
|
+
await toasts.show({ title: "Astrocode", message: `Run failed at ${next.stage_key}`, variant: "error" });
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const nextActionStr = formatNextAction(next);
|
|
107
|
+
const context = buildContextSnapshot({ db, config, run_id: active.run_id, next_action: nextActionStr });
|
|
108
|
+
const directive = buildContinueDirective({
|
|
109
|
+
config,
|
|
110
|
+
run_id: active.run_id,
|
|
111
|
+
stage_key: active.current_stage_key,
|
|
112
|
+
next_action: nextActionStr,
|
|
113
|
+
context_snapshot_md: context,
|
|
114
|
+
});
|
|
115
|
+
if (shouldDedupe(sessionId, directive))
|
|
116
|
+
return;
|
|
117
|
+
await recordContinuation(sessionId, active.run_id, directive, reason);
|
|
118
|
+
// Injection mode
|
|
119
|
+
if (config.continuation.injection_mode === "visible") {
|
|
120
|
+
await injectChatPrompt({ ctx, sessionId, text: directive.body });
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Silent mode is TODO: requires experimental.chat.messages.transform.
|
|
124
|
+
// For v2-alpha, we fall back to visible injection but mark it.
|
|
125
|
+
await injectChatPrompt({ ctx, sessionId, text: directive.body + "\n\n(Injected in silent mode fallback)" });
|
|
126
|
+
}
|
|
127
|
+
if (config.ui.toasts.enabled && config.ui.toasts.show_auto_continue) {
|
|
128
|
+
await toasts.show({ title: "Astrocode", message: "Continue directive injected", variant: "info" });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Public hook handlers
|
|
132
|
+
return {
|
|
133
|
+
async onToolAfter(input) {
|
|
134
|
+
const sessionId = input.sessionID ?? ctx.sessionID;
|
|
135
|
+
if (!sessionId)
|
|
136
|
+
return;
|
|
137
|
+
if (!config.continuation.inject_on_tool_done_if_run_active)
|
|
138
|
+
return;
|
|
139
|
+
scheduleIdleInjection(sessionId);
|
|
140
|
+
},
|
|
141
|
+
async onChatMessage(_input) {
|
|
142
|
+
if (!config.continuation.inject_on_message_done_if_run_active)
|
|
143
|
+
return;
|
|
144
|
+
scheduleIdleInjection(_input.sessionID);
|
|
145
|
+
},
|
|
146
|
+
async onEvent(input) {
|
|
147
|
+
const type = input.event.type;
|
|
148
|
+
const sessionId = input.event.properties?.sessionID;
|
|
149
|
+
if (!sessionId)
|
|
150
|
+
return;
|
|
151
|
+
if (type === "session.idle") {
|
|
152
|
+
if (!config.continuation.inject_on_session_idle)
|
|
153
|
+
return;
|
|
154
|
+
await maybeInjectContinue(sessionId, "session.idle");
|
|
155
|
+
}
|
|
156
|
+
if (type === "session.created") {
|
|
157
|
+
// When a session is created and there is an active run, nudge.
|
|
158
|
+
scheduleIdleInjection(sessionId);
|
|
159
|
+
}
|
|
160
|
+
if (type === "session.deleted") {
|
|
161
|
+
clearIdleTimer(sessionId);
|
|
162
|
+
sessions.delete(sessionId);
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AstrocodeConfig } from "../config/schema";
|
|
2
|
+
import type { SqliteDb } from "../state/db";
|
|
3
|
+
type ToolExecuteAfterInput = {
|
|
4
|
+
tool: string;
|
|
5
|
+
sessionID?: string;
|
|
6
|
+
};
|
|
7
|
+
type ToolExecuteAfterOutput = {
|
|
8
|
+
title?: string;
|
|
9
|
+
output?: string;
|
|
10
|
+
metadata?: Record<string, any>;
|
|
11
|
+
};
|
|
12
|
+
export declare function createToolOutputTruncatorHook(opts: {
|
|
13
|
+
ctx: any;
|
|
14
|
+
config: AstrocodeConfig;
|
|
15
|
+
db: SqliteDb;
|
|
16
|
+
}): (input: ToolExecuteAfterInput, output: ToolExecuteAfterOutput) => Promise<void>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { getAstroPaths, ensureDir, toPosix } from "../shared/paths";
|
|
3
|
+
import { nowISO } from "../shared/time";
|
|
4
|
+
import { putArtifact } from "../workflow/artifacts";
|
|
5
|
+
import { sha256Hex } from "../shared/hash";
|
|
6
|
+
import { clampChars } from "../shared/text";
|
|
7
|
+
import { getActiveRun } from "../workflow/state-machine";
|
|
8
|
+
function pickMaxChars(toolName, cfg) {
|
|
9
|
+
if (toolName.includes("webfetch") || toolName.includes("web.run"))
|
|
10
|
+
return cfg.truncation.max_chars_webfetch;
|
|
11
|
+
if (toolName.includes("diff"))
|
|
12
|
+
return cfg.truncation.max_chars_diff;
|
|
13
|
+
return cfg.truncation.max_chars_default;
|
|
14
|
+
}
|
|
15
|
+
export function createToolOutputTruncatorHook(opts) {
|
|
16
|
+
const { ctx, config, db } = opts;
|
|
17
|
+
return async function toolExecuteAfter(input, output) {
|
|
18
|
+
if (!config.truncation.enabled)
|
|
19
|
+
return;
|
|
20
|
+
const toolName = input.tool;
|
|
21
|
+
const text = output.output ?? "";
|
|
22
|
+
const maxChars = pickMaxChars(toolName, config);
|
|
23
|
+
if (!text || text.length <= maxChars)
|
|
24
|
+
return;
|
|
25
|
+
const repoRoot = ctx.directory;
|
|
26
|
+
const paths = getAstroPaths(repoRoot, config.db.path);
|
|
27
|
+
ensureDir(paths.toolOutputDir);
|
|
28
|
+
const active = getActiveRun(db);
|
|
29
|
+
const timestamp = nowISO().replace(/[:.]/g, "-");
|
|
30
|
+
const relBase = active && config.truncation.persist_truncated_outputs
|
|
31
|
+
? toPosix(path.join(".astro", "runs", active.run_id, "_tool_output"))
|
|
32
|
+
: toPosix(path.join(".astro", "tool_output"));
|
|
33
|
+
const relPath = toPosix(path.join(relBase, toolName.replace(/[^a-zA-Z0-9_-]/g, "_"), `${timestamp}.txt`));
|
|
34
|
+
const { artifact_id } = putArtifact({
|
|
35
|
+
repoRoot,
|
|
36
|
+
db,
|
|
37
|
+
run_id: active?.run_id ?? null,
|
|
38
|
+
stage_key: active?.current_stage_key ?? null,
|
|
39
|
+
type: "tool_output",
|
|
40
|
+
rel_path: relPath,
|
|
41
|
+
content: text,
|
|
42
|
+
meta: { tool: toolName, session_id: input.sessionID ?? null },
|
|
43
|
+
});
|
|
44
|
+
const digest = sha256Hex(text);
|
|
45
|
+
const head = clampChars(text, Math.min(maxChars, 4000));
|
|
46
|
+
output.output =
|
|
47
|
+
head +
|
|
48
|
+
`\n\n…(truncated; sha256=${digest})\n` +
|
|
49
|
+
`Full output saved: ${relPath}\n` +
|
|
50
|
+
`Artifact ID: ${artifact_id}`;
|
|
51
|
+
output.metadata = output.metadata ?? {};
|
|
52
|
+
output.metadata.truncated = true;
|
|
53
|
+
output.metadata.artifact_id = artifact_id;
|
|
54
|
+
output.metadata.full_output_path = relPath;
|
|
55
|
+
};
|
|
56
|
+
}
|
package/dist/index.d.ts
ADDED