@wrongstack/core 0.306.3 → 0.307.0

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 (114) hide show
  1. package/dist/chronicle/index.js +957 -953
  2. package/dist/chronicle/metrics-ingest.d.ts +55 -0
  3. package/dist/chronicle/metrics-schema.d.ts +86 -0
  4. package/dist/chronicle/metrics-store.d.ts +5 -120
  5. package/dist/chronicle/project-server.js +1083 -1084
  6. package/dist/chronicle/sqlite-journal-quota.d.ts +39 -0
  7. package/dist/chronicle/sqlite-journal-schema.d.ts +25 -0
  8. package/dist/chronicle/sqlite-journal.d.ts +12 -177
  9. package/dist/coordination/agents/index.js +1738 -1690
  10. package/dist/coordination/agents/project-agent-capture.d.ts +48 -0
  11. package/dist/coordination/agents/project-agent-identity.d.ts +3 -129
  12. package/dist/coordination/agents/project-agent-roster.d.ts +17 -0
  13. package/dist/coordination/index.js +6103 -5890
  14. package/dist/coordination/mailbox-http-actor-query.d.ts +16 -0
  15. package/dist/coordination/mailbox-http-router.d.ts +0 -48
  16. package/dist/coordination/mailbox-http-sse.d.ts +12 -0
  17. package/dist/coordination/mailbox-message-types.d.ts +71 -0
  18. package/dist/coordination/mailbox-predicates.d.ts +13 -0
  19. package/dist/coordination/mailbox-project-server.js +1 -1
  20. package/dist/coordination/mailbox-session-sync.d.ts +8 -0
  21. package/dist/coordination/mailbox-types.d.ts +6 -793
  22. package/dist/core/agent-loop-context.d.ts +28 -0
  23. package/dist/core/agent-loop-detector.d.ts +25 -0
  24. package/dist/core/conversation-state.d.ts +1 -2
  25. package/dist/core/fallback-doctor.d.ts +72 -0
  26. package/dist/core/fallback-model.d.ts +19 -1
  27. package/dist/core/fallback-profile-manager.d.ts +21 -3
  28. package/dist/core/index.d.ts +2 -1
  29. package/dist/core/index.js +1143 -766
  30. package/dist/defaults/index.js +3833 -3595
  31. package/dist/execution/auto-compaction-middleware.d.ts +64 -0
  32. package/dist/execution/autonomy-brain-llm.d.ts +55 -0
  33. package/dist/execution/autonomy-brain.d.ts +3 -156
  34. package/dist/execution/compaction-budget.d.ts +38 -0
  35. package/dist/execution/compaction-core.d.ts +3 -166
  36. package/dist/execution/compaction-elision.d.ts +58 -0
  37. package/dist/execution/council-orchestrator-helpers.d.ts +39 -0
  38. package/dist/execution/council-orchestrator.d.ts +3 -42
  39. package/dist/execution/council-response-parser.d.ts +56 -0
  40. package/dist/execution/index.d.ts +1 -1
  41. package/dist/execution/index.js +10016 -9903
  42. package/dist/execution/prompt-enhancer.js +11 -3
  43. package/dist/execution/retry-policy.d.ts +27 -0
  44. package/dist/execution/tool-executor-guard.d.ts +18 -0
  45. package/dist/execution/tool-executor-runner.d.ts +12 -0
  46. package/dist/execution/tool-executor.d.ts +0 -75
  47. package/dist/goal/index.js +19 -6
  48. package/dist/hq/index.js +58 -17
  49. package/dist/index.d.ts +2 -1
  50. package/dist/index.js +8731 -7756
  51. package/dist/infrastructure/index.js +24 -1
  52. package/dist/kernel/events/agent-events.d.ts +2 -0
  53. package/dist/kernel/events/provider-events.d.ts +13 -0
  54. package/dist/plugin/index.js +2123 -1918
  55. package/dist/plugins/auto-review-config.d.ts +53 -0
  56. package/dist/plugins/auto-review-git.d.ts +19 -0
  57. package/dist/plugins/auto-review-plugin.d.ts +2 -140
  58. package/dist/plugins/review-finding-verification.d.ts +7 -0
  59. package/dist/prompts/index.d.ts +1 -0
  60. package/dist/prompts/prompt-journal.d.ts +94 -0
  61. package/dist/security/index.js +677 -667
  62. package/dist/security/permission-explain.d.ts +19 -0
  63. package/dist/security/permission-policy.d.ts +0 -101
  64. package/dist/security/yolo-risk.d.ts +5 -4
  65. package/dist/session-catalog/index.js +270 -227
  66. package/dist/session-catalog/project-server.js +277 -234
  67. package/dist/session-catalog/store-rebuild.d.ts +9 -0
  68. package/dist/session-catalog/store-schema.d.ts +48 -0
  69. package/dist/session-catalog/store.d.ts +0 -17
  70. package/dist/storage/cloud-config-sync/sanitize.d.ts +18 -0
  71. package/dist/storage/cloud-config-sync.d.ts +1 -1
  72. package/dist/storage/director-state.d.ts +6 -0
  73. package/dist/storage/file-session-writer.d.ts +2 -58
  74. package/dist/storage/index.d.ts +2 -1
  75. package/dist/storage/index.js +2121 -1736
  76. package/dist/storage/orphan-lock-cleaner.d.ts +15 -0
  77. package/dist/storage/provider-config-watcher.d.ts +9 -0
  78. package/dist/storage/session-recovery.d.ts +9 -0
  79. package/dist/storage/session-store/rename-session.d.ts +16 -0
  80. package/dist/storage/session-store/resume-session.d.ts +26 -0
  81. package/dist/storage/session-store/session-store-clear.d.ts +11 -0
  82. package/dist/storage/session-store/session-store-index.d.ts +13 -0
  83. package/dist/storage/session-store/strict-empty-check.d.ts +7 -0
  84. package/dist/storage/session-store.d.ts +2 -129
  85. package/dist/storage/session-summary-tracker.d.ts +39 -0
  86. package/dist/storage/session-write-buffer.d.ts +43 -0
  87. package/dist/storage/session-writer/session-writer-flush.d.ts +4 -0
  88. package/dist/storage/session-writer/session-writer-summary-tracker.d.ts +28 -0
  89. package/dist/tools/fallback-agent-model-assign-tool.d.ts +18 -0
  90. package/dist/tools/fallback-leader-model-set-tool.d.ts +18 -0
  91. package/dist/tools/fallback-manage-tools.d.ts +8 -45
  92. package/dist/tools/fallback-profile-manage-tool.d.ts +16 -0
  93. package/dist/tools/fallback-provider-key-set-tool.d.ts +17 -0
  94. package/dist/tools/fallback-provider-manage-tool.d.ts +26 -0
  95. package/dist/tools/index.d.ts +1 -1
  96. package/dist/tools/index.js +5150 -5090
  97. package/dist/types/config/root.d.ts +21 -2
  98. package/dist/types/default-config.d.ts +1 -1
  99. package/dist/types/index.d.ts +54 -55
  100. package/dist/types/index.js +953 -932
  101. package/dist/types/runtime-capability-manifest.d.ts +5 -5
  102. package/dist/types/session-markers.d.ts +12 -0
  103. package/dist/types/session-markers.js +19 -0
  104. package/dist/types/session.d.ts +7 -0
  105. package/dist/worktree/worktree-manager.d.ts +1 -1
  106. package/instructions/coordination/subagent-baseline.md +2 -2
  107. package/instructions/llm/prompt-enhancer.md +2 -1
  108. package/instructions/sections/tool/common-patterns.md +21 -0
  109. package/instructions/sections/tool/delegation-compact.md +3 -1
  110. package/instructions/sections/tool/delegation-full.md +5 -1
  111. package/instructions/system-lite.md +28 -3
  112. package/instructions/system-pro.md +37 -8
  113. package/instructions/system.md +4 -2
  114. package/package.json +5 -5
@@ -12,146 +12,385 @@ function isImageBlock(b) {
12
12
  return b.type === "image";
13
13
  }
14
14
 
15
- // src/types/tool.ts
16
- var ToolErrorCategory = /* @__PURE__ */ ((ToolErrorCategory2) => {
17
- ToolErrorCategory2["TRANSIENT"] = "transient";
18
- ToolErrorCategory2["NOT_FOUND"] = "not_found";
19
- ToolErrorCategory2["PERMISSION"] = "permission";
20
- ToolErrorCategory2["VALIDATION"] = "validation";
21
- ToolErrorCategory2["FATAL"] = "fatal";
22
- return ToolErrorCategory2;
23
- })(ToolErrorCategory || {});
24
-
25
- // src/types/tool-executor.ts
26
- var GOVERNED_TOOL_EXECUTOR_META_KEY = "toolExecutor.executeGoverned";
27
-
28
- // src/types/tool-markers.ts
29
- var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
30
-
31
- // src/utils/string.ts
32
- function truncate(s, max) {
33
- return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
15
+ // src/types/config/fleet-chat.ts
16
+ var FLEET_CHAT_VERBOSITY_VALUES = ["off", "full"];
17
+ function resolveFleetChatVerbosity(autonomy) {
18
+ const explicit = autonomy?.fleetChatVerbosity;
19
+ if (explicit && FLEET_CHAT_VERBOSITY_VALUES.includes(explicit)) {
20
+ return explicit;
21
+ }
22
+ return "off";
34
23
  }
35
24
 
36
- // src/utils/error.ts
37
- function toErrorMessage(err) {
38
- return err instanceof Error ? err.message : String(err);
25
+ // src/types/config/runtime.ts
26
+ function normalizeTokenSavingTier(val) {
27
+ if (val === void 0) return "off";
28
+ if (typeof val === "boolean") return val ? "medium" : "off";
29
+ if (val === "auto") return "medium";
30
+ const validTiers = /* @__PURE__ */ new Set([
31
+ "off",
32
+ "minimal",
33
+ "light",
34
+ "medium",
35
+ "aggressive"
36
+ ]);
37
+ return validTiers.has(val) ? val : "off";
39
38
  }
40
-
41
- // src/types/errors.ts
42
- var ERROR_CODES = {
43
- // Provider
44
- PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
45
- PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
46
- PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
47
- PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
48
- PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
49
- PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
50
- PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
51
- // Tool
52
- TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
53
- TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
54
- TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
55
- TOOL_TIMEOUT: "TOOL_TIMEOUT",
56
- TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
57
- // Config
58
- CONFIG_INVALID: "CONFIG_INVALID",
59
- CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
60
- CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
61
- CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
62
- // Plugin
63
- PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
64
- PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
65
- PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
66
- // Agent
67
- AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
68
- AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
69
- AGENT_ABORTED: "AGENT_ABORTED",
70
- AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
71
- // Session
72
- SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
73
- SESSION_CORRUPTED: "SESSION_CORRUPTED",
74
- SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
75
- // Container / Registry
76
- CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
77
- CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
78
- CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
79
- REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
80
- REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
81
- REGISTRY_INVALID: "REGISTRY_INVALID",
82
- // File system
83
- FS_READ_FAILED: "FS_READ_FAILED",
84
- FS_WRITE_FAILED: "FS_WRITE_FAILED",
85
- FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
86
- FS_DELETE_FAILED: "FS_DELETE_FAILED",
87
- FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
88
- // SDD (Spec-Driven Development)
89
- SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
90
- SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
91
- SDD_INVALID_STATE: "SDD_INVALID_STATE",
92
- SDD_NOT_READY: "SDD_NOT_READY",
93
- // General
94
- VALIDATION_ERROR: "VALIDATION_ERROR",
95
- PARSE_FAILED: "PARSE_FAILED",
96
- UNKNOWN: "UNKNOWN"
97
- };
98
- var WrongStackError = class extends Error {
99
- code;
100
- subsystem;
101
- severity;
102
- recoverable;
103
- context;
104
- constructor(opts) {
105
- super(opts.message, { cause: opts.cause });
106
- this.name = "WrongStackError";
107
- this.code = opts.code;
108
- this.subsystem = opts.subsystem;
109
- this.severity = opts.severity ?? "error";
110
- this.recoverable = opts.recoverable ?? false;
111
- this.context = opts.context;
39
+ function resolveTokenSavingTier(val, maxContext) {
40
+ if (val === "auto") {
41
+ if (typeof maxContext !== "number" || !Number.isFinite(maxContext) || maxContext <= 0) {
42
+ return "off";
43
+ }
44
+ if (maxContext < 32e3) return "medium";
45
+ if (maxContext < 128e3) return "light";
46
+ return "minimal";
112
47
  }
113
- /**
114
- * Render a one-line user-facing description.
115
- * Subclasses should override for domain-specific formatting.
116
- */
117
- describe() {
118
- const ctx = this.context ? ` ${formatContext(this.context)}` : "";
119
- return `${this.code}: ${this.message}${ctx}`;
48
+ return normalizeTokenSavingTier(val);
49
+ }
50
+ var DEFAULT_TUI_THINKING_WORD = "thinking";
51
+ var MAX_TUI_THINKING_WORD_LENGTH = 16;
52
+ function normalizeTuiThinkingWord(value) {
53
+ if (typeof value !== "string") return DEFAULT_TUI_THINKING_WORD;
54
+ const word = value.trim();
55
+ if (word.length === 0 || word.length > MAX_TUI_THINKING_WORD_LENGTH) {
56
+ return DEFAULT_TUI_THINKING_WORD;
120
57
  }
121
- };
122
- function formatContext(ctx) {
123
- const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
124
- return parts.length > 0 ? `[${parts.join(" ")}]` : "";
58
+ if (!/^[\p{L}\p{N}_-]+$/u.test(word)) return DEFAULT_TUI_THINKING_WORD;
59
+ return word;
125
60
  }
126
- var ToolError = class extends WrongStackError {
127
- toolName;
128
- constructor(opts) {
129
- super({
130
- message: opts.message,
131
- code: opts.code,
132
- subsystem: "tool",
133
- recoverable: opts.recoverable,
134
- context: { tool: opts.toolName, ...opts.context },
135
- cause: opts.cause
136
- });
137
- this.name = "ToolError";
138
- this.toolName = opts.toolName;
61
+
62
+ // src/types/config/ui.ts
63
+ var THEME_PRESET_IDS = [
64
+ "catppuccin",
65
+ "tokyo-night",
66
+ "nord",
67
+ "cyberpunk",
68
+ "dracula",
69
+ "gruvbox-dark",
70
+ "solarized-dark",
71
+ "one-dark",
72
+ "monokai",
73
+ "rose-pine",
74
+ "kanagawa",
75
+ "ayu-dark",
76
+ "everforest",
77
+ "night-owl",
78
+ "synthwave",
79
+ "github-dark",
80
+ "material-ocean",
81
+ "nightfox",
82
+ "oxocarbon",
83
+ "catppuccin-macchiato",
84
+ "catppuccin-frappe",
85
+ "gruvbox-material",
86
+ "tokyo-night-storm",
87
+ "rose-pine-moon",
88
+ "zenburn",
89
+ "palenight",
90
+ "horizon",
91
+ "sonokai",
92
+ "edge-dark",
93
+ "moonfly",
94
+ "melange",
95
+ "poimandres",
96
+ "vitesse-dark",
97
+ "aura",
98
+ "dark-plus"
99
+ ];
100
+
101
+ // src/utils/expect-defined.ts
102
+ function expectDefined(value, label) {
103
+ if (value === null || value === void 0) {
104
+ const err = new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
105
+ err.name = "ExpectDefinedError";
106
+ throw err;
139
107
  }
140
- };
141
- var ConfigError = class extends WrongStackError {
142
- constructor(opts) {
143
- super({
144
- message: opts.message,
145
- code: opts.code,
146
- subsystem: "config",
147
- severity: "fatal",
148
- recoverable: false,
149
- context: opts.context,
150
- cause: opts.cause
151
- });
152
- this.name = "ConfigError";
108
+ return value;
109
+ }
110
+
111
+ // src/types/context-window.ts
112
+ var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
113
+ var DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES = Object.freeze({
114
+ archival: "balanced"
115
+ });
116
+ var CONTEXT_WINDOW_MODES = Object.freeze([
117
+ {
118
+ id: "balanced",
119
+ name: "Balanced",
120
+ description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed.",
121
+ thresholds: { warn: 0.55, soft: 0.7, hard: 0.85 },
122
+ aggressiveOn: "soft",
123
+ preserveK: 8,
124
+ eliseThreshold: 1200,
125
+ targetLoad: 0.65
126
+ },
127
+ {
128
+ id: "frugal",
129
+ name: "Frugal",
130
+ description: "Token-saver mode: compacts early and keeps a tight verbatim tail.",
131
+ thresholds: { warn: 0.4, soft: 0.55, hard: 0.7 },
132
+ aggressiveOn: "warn",
133
+ preserveK: 4,
134
+ eliseThreshold: 500,
135
+ targetLoad: 0.45
136
+ },
137
+ {
138
+ id: "deep",
139
+ name: "Deep",
140
+ description: "Long-reasoning mode: delays compaction and keeps more recent turns intact.",
141
+ thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },
142
+ aggressiveOn: "hard",
143
+ preserveK: 18,
144
+ eliseThreshold: 5e3,
145
+ targetLoad: 0.82
153
146
  }
154
- };
147
+ ]);
148
+ function listContextWindowModes() {
149
+ return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));
150
+ }
151
+ function normalizeContextWindowModeId(id) {
152
+ if (!id) return null;
153
+ if (isContextWindowModeId(id)) return id;
154
+ return DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES[id] ?? null;
155
+ }
156
+ function isDeprecatedContextWindowModeId(id) {
157
+ return Object.hasOwn(DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES, id);
158
+ }
159
+ function isContextWindowModeSelectionId(id) {
160
+ return isContextWindowModeId(id) || isDeprecatedContextWindowModeId(id);
161
+ }
162
+ function getContextWindowMode(id) {
163
+ const normalized = normalizeContextWindowModeId(id);
164
+ if (!normalized) return null;
165
+ const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === normalized);
166
+ return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;
167
+ }
168
+ function isContextWindowModeId(id) {
169
+ return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
170
+ }
171
+ function resolveContextWindowPolicy(config = {}, overrideMode) {
172
+ const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
173
+ const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));
174
+ return {
175
+ ...mode,
176
+ thresholds: {
177
+ warn: config.warnThreshold ?? mode.thresholds.warn,
178
+ soft: config.softThreshold ?? mode.thresholds.soft,
179
+ hard: config.hardThreshold ?? mode.thresholds.hard
180
+ },
181
+ preserveK: config.preserveK ?? mode.preserveK,
182
+ eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,
183
+ targetLoad: config.targetLoad ?? mode.targetLoad
184
+ };
185
+ }
186
+ function formatContextWindowModeList(activeId) {
187
+ const active = normalizeContextWindowModeId(activeId);
188
+ return CONTEXT_WINDOW_MODES.map((m) => {
189
+ const marker = m.id === active ? "*" : " ";
190
+ return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;
191
+ }).join("\n");
192
+ }
193
+
194
+ // src/types/default-config.ts
195
+ var DEFAULT_TOOLS_CONFIG = Object.freeze({
196
+ defaultExecutionStrategy: "smart",
197
+ maxIterations: 100,
198
+ iterationTimeoutMs: 3e5,
199
+ maxToolTimeoutMs: 3e5,
200
+ sessionTimeoutMs: 18e5,
201
+ perIterationOutputCapBytes: 1e5,
202
+ descriptionMode: Object.freeze({}),
203
+ disabledTools: Object.freeze([]),
204
+ // Extension requires an explicit host/user policy. Without that boundary a
205
+ // nominal maxIterations cap can grow forever in autonomous sessions.
206
+ autoExtendLimit: false,
207
+ restrictToProjectRoot: true,
208
+ // Off by default: the board is a record of the work, not a permit for it.
209
+ // See ToolsConfig.kanbanGovernance for what turning it on costs and gates.
210
+ kanbanGovernance: false,
211
+ loopDetection: Object.freeze({
212
+ mode: "steer-then-cut",
213
+ steerThreshold: 3,
214
+ cutThreshold: 5,
215
+ windowSize: 12,
216
+ callRepeatThreshold: 4
217
+ })
218
+ });
219
+ var DEFAULT_CONTEXT_CONFIG = Object.freeze({
220
+ warnThreshold: 0.55,
221
+ softThreshold: 0.7,
222
+ hardThreshold: 0.85,
223
+ targetLoad: 0.65,
224
+ preserveK: 8,
225
+ eliseThreshold: 1200
226
+ });
227
+ var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
228
+ autoProceedDelayMs: 45e3
229
+ });
230
+ var DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({
231
+ enabled: false,
232
+ autoKillResetMs: 6e4
233
+ });
234
+ var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
235
+ auditLevel: "standard",
236
+ sampling: {
237
+ toolProgress: {
238
+ sampleRate: 8
239
+ }
240
+ }
241
+ });
242
+ var DEFAULT_SESSION_PRUNE_DAYS = 30;
243
+
244
+ // src/types/design-kit.ts
245
+ var DESIGN_STACKS = ["web", "react-native", "flutter", "swiftui", "compose"];
246
+ function isDesignStack(v) {
247
+ return DESIGN_STACKS.includes(v);
248
+ }
249
+ var KNOWN_TOKEN_GROUPS = {
250
+ /** Corner radii. */
251
+ radius: ["radius-none", "radius-sm", "radius-md", "radius-lg", "radius-xl", "radius-full"],
252
+ /** Spacing scale (4/8px rhythm). */
253
+ space: ["space-1", "space-2", "space-3", "space-4", "space-6", "space-8", "space-12"],
254
+ /** Type sizes. */
255
+ text: ["text-xs", "text-sm", "text-base", "text-lg", "text-xl", "text-2xl", "text-3xl"],
256
+ /** Line-heights (unitless). */
257
+ leading: ["leading-tight", "leading-normal", "leading-relaxed"],
258
+ /** Font weights (unitless). */
259
+ weight: ["weight-normal", "weight-medium", "weight-semibold", "weight-bold"],
260
+ /** Letter-spacing. */
261
+ tracking: ["tracking-tight", "tracking-normal", "tracking-wide"],
262
+ /** Elevation / shadow ramp. */
263
+ shadow: ["shadow-1", "shadow-2", "shadow-3", "shadow-4"],
264
+ /** Border widths. */
265
+ border: ["border-hairline", "border-thin", "border-thick"],
266
+ /** Motion durations. */
267
+ duration: ["duration-fast", "duration-base", "duration-slow"],
268
+ /** Motion easings. */
269
+ ease: ["ease-standard", "ease-emphasized"],
270
+ /** Font families. */
271
+ font: ["font-sans", "font-mono", "font-display"]
272
+ };
273
+ var KNOWN_TOKEN_NAMES = Object.values(KNOWN_TOKEN_GROUPS).flat();
274
+
275
+ // src/utils/error.ts
276
+ function toErrorMessage(err) {
277
+ return err instanceof Error ? err.message : String(err);
278
+ }
279
+
280
+ // src/types/errors.ts
281
+ var ERROR_CODES = {
282
+ // Provider
283
+ PROVIDER_RATE_LIMITED: "PROVIDER_RATE_LIMITED",
284
+ PROVIDER_AUTH_FAILED: "PROVIDER_AUTH_FAILED",
285
+ PROVIDER_OVERLOADED: "PROVIDER_OVERLOADED",
286
+ PROVIDER_INVALID_REQUEST: "PROVIDER_INVALID_REQUEST",
287
+ PROVIDER_SERVER_ERROR: "PROVIDER_SERVER_ERROR",
288
+ PROVIDER_NETWORK_ERROR: "PROVIDER_NETWORK_ERROR",
289
+ PROVIDER_CONTEXT_OVERFLOW: "PROVIDER_CONTEXT_OVERFLOW",
290
+ // Tool
291
+ TOOL_NOT_FOUND: "TOOL_NOT_FOUND",
292
+ TOOL_PERMISSION_DENIED: "TOOL_PERMISSION_DENIED",
293
+ TOOL_EXECUTION_FAILED: "TOOL_EXECUTION_FAILED",
294
+ TOOL_TIMEOUT: "TOOL_TIMEOUT",
295
+ TOOL_INPUT_INVALID: "TOOL_INPUT_INVALID",
296
+ // Config
297
+ CONFIG_INVALID: "CONFIG_INVALID",
298
+ CONFIG_NOT_FOUND: "CONFIG_NOT_FOUND",
299
+ CONFIG_PARSE_FAILED: "CONFIG_PARSE_FAILED",
300
+ CONFIG_MIGRATION_NEEDED: "CONFIG_MIGRATION_NEEDED",
301
+ // Plugin
302
+ PLUGIN_LOAD_FAILED: "PLUGIN_LOAD_FAILED",
303
+ PLUGIN_API_MISMATCH: "PLUGIN_API_MISMATCH",
304
+ PLUGIN_MISSING_DEPENDENCY: "PLUGIN_MISSING_DEPENDENCY",
305
+ // Agent
306
+ AGENT_ITERATION_LIMIT: "AGENT_ITERATION_LIMIT",
307
+ AGENT_CONTEXT_OVERFLOW: "AGENT_CONTEXT_OVERFLOW",
308
+ AGENT_ABORTED: "AGENT_ABORTED",
309
+ AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
310
+ // Session
311
+ SESSION_NOT_FOUND: "SESSION_NOT_FOUND",
312
+ SESSION_CORRUPTED: "SESSION_CORRUPTED",
313
+ SESSION_WRITE_FAILED: "SESSION_WRITE_FAILED",
314
+ // Container / Registry
315
+ CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
316
+ CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
317
+ CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
318
+ REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
319
+ REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
320
+ REGISTRY_INVALID: "REGISTRY_INVALID",
321
+ // File system
322
+ FS_READ_FAILED: "FS_READ_FAILED",
323
+ FS_WRITE_FAILED: "FS_WRITE_FAILED",
324
+ FS_MKDIR_FAILED: "FS_MKDIR_FAILED",
325
+ FS_DELETE_FAILED: "FS_DELETE_FAILED",
326
+ FS_ATOMIC_WRITE_FAILED: "FS_ATOMIC_WRITE_FAILED",
327
+ // SDD (Spec-Driven Development)
328
+ SDD_VALIDATION_FAILED: "SDD_VALIDATION_FAILED",
329
+ SDD_PARSE_FAILED: "SDD_PARSE_FAILED",
330
+ SDD_INVALID_STATE: "SDD_INVALID_STATE",
331
+ SDD_NOT_READY: "SDD_NOT_READY",
332
+ // General
333
+ VALIDATION_ERROR: "VALIDATION_ERROR",
334
+ PARSE_FAILED: "PARSE_FAILED",
335
+ UNKNOWN: "UNKNOWN"
336
+ };
337
+ var WrongStackError = class extends Error {
338
+ code;
339
+ subsystem;
340
+ severity;
341
+ recoverable;
342
+ context;
343
+ constructor(opts) {
344
+ super(opts.message, { cause: opts.cause });
345
+ this.name = "WrongStackError";
346
+ this.code = opts.code;
347
+ this.subsystem = opts.subsystem;
348
+ this.severity = opts.severity ?? "error";
349
+ this.recoverable = opts.recoverable ?? false;
350
+ this.context = opts.context;
351
+ }
352
+ /**
353
+ * Render a one-line user-facing description.
354
+ * Subclasses should override for domain-specific formatting.
355
+ */
356
+ describe() {
357
+ const ctx = this.context ? ` ${formatContext(this.context)}` : "";
358
+ return `${this.code}: ${this.message}${ctx}`;
359
+ }
360
+ };
361
+ function formatContext(ctx) {
362
+ const parts = Object.entries(ctx).filter(([, v]) => v !== void 0).slice(0, 3).map(([k, v]) => `${k}=${String(v)}`);
363
+ return parts.length > 0 ? `[${parts.join(" ")}]` : "";
364
+ }
365
+ var ToolError = class extends WrongStackError {
366
+ toolName;
367
+ constructor(opts) {
368
+ super({
369
+ message: opts.message,
370
+ code: opts.code,
371
+ subsystem: "tool",
372
+ recoverable: opts.recoverable,
373
+ context: { tool: opts.toolName, ...opts.context },
374
+ cause: opts.cause
375
+ });
376
+ this.name = "ToolError";
377
+ this.toolName = opts.toolName;
378
+ }
379
+ };
380
+ var ConfigError = class extends WrongStackError {
381
+ constructor(opts) {
382
+ super({
383
+ message: opts.message,
384
+ code: opts.code,
385
+ subsystem: "config",
386
+ severity: "fatal",
387
+ recoverable: false,
388
+ context: opts.context,
389
+ cause: opts.cause
390
+ });
391
+ this.name = "ConfigError";
392
+ }
393
+ };
155
394
  var PluginError = class extends WrongStackError {
156
395
  pluginName;
157
396
  constructor(opts) {
@@ -317,499 +556,229 @@ function isSddError(err) {
317
556
  return err instanceof SddError;
318
557
  }
319
558
 
320
- // src/types/quota-regex.ts
321
- var QUOTA_EXHAUSTED_RE = /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\s]*(?:quota|credit|balance)|(?:quota|credit|balance)(?:\s+(?:has|have))?(?:\s+been)?[-_\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\s-]*(?:hard[_\s-]*)?limit|payment required|spending limit|plan limit|usage[-_\s]*limit[-_\s]*(?:reached|exceeded)/i;
322
-
323
- // src/types/provider.ts
324
- function effectiveInputTokens(usage) {
325
- return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
326
- }
327
- var CONTEXT_OVERFLOW_RE = /context.length|context.window|maximum context|max.*tokens?.*exceeded|(?:prompt|request|input|messages?).{0,12}too (?:large|long)|exceeds the context|\btokens\b.*exceed|too many tokens|reduce the length|resulted in \d+ tokens|context_length_exceeded/i;
328
- var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
329
- var RATE_LIMIT_EXCEEDED_RE = /rate[-_\s]*limit[-_\s]*exceeded/i;
330
- function classifyProviderError(status, body, message) {
331
- const type = body?.type;
332
- const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
333
- if (status === 0) return "network";
334
- if (status === 408) return "timeout";
335
- if (status === 599) return "stream_hang";
336
- if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return "quota_exhausted";
337
- if (status === 429 && body?.message && body.type !== "rate_limit_exceeded" && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {
338
- return "quota_exhausted";
339
- }
340
- if (type === "rate_limit_error" || status === 429) return "rate_limit";
341
- if (type === "overloaded_error" || status === 529) return "overloaded";
342
- if (status >= 500) return "server";
343
- if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
344
- return "auth";
345
- }
346
- if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
347
- if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
348
- return "context_overflow";
349
- }
350
- if (status >= 400) return "invalid_request";
351
- return "unknown";
352
- }
353
- var MAX_RESET_HINT_MS = 7 * 24 * 60 * 60 * 1e3;
354
- function isRetryableKind(kind) {
355
- return RETRYABLE_BY_KIND[kind];
356
- }
357
- var RETRYABLE_BY_KIND = {
358
- rate_limit: true,
359
- quota_exhausted: false,
360
- overloaded: true,
361
- server: true,
362
- timeout: true,
363
- network: true,
364
- stream_hang: true,
365
- auth: false,
366
- context_overflow: false,
367
- content_filter: false,
368
- invalid_request: false,
369
- unknown: false
559
+ // src/types/memory.ts
560
+ var MEMORY_TYPE_LABELS = {
561
+ fact: "Fact",
562
+ decision: "Decision",
563
+ convention: "Convention",
564
+ preference: "Preference",
565
+ reference: "Reference",
566
+ anti_pattern: "Anti-pattern"
370
567
  };
371
- function isFallbackWorthy(kind) {
372
- return FALLBACK_WORTHY_BY_KIND[kind];
568
+ function defineMemoryCapability(id) {
569
+ return Object.freeze({
570
+ id,
571
+ /** Identity function that makes the brand a real runtime value so
572
+ * `defineMemoryCapability<A>('x')` and `defineMemoryCapability<B>('x')`
573
+ * produce structurally distinct objects. Capability lookup is still
574
+ * keyed by `id` only — the brand prevents accidental cross-type casts
575
+ * at the type level. */
576
+ __memoryCapabilityType: (v) => v
577
+ });
373
578
  }
374
- var FALLBACK_WORTHY_BY_KIND = {
375
- rate_limit: true,
376
- quota_exhausted: true,
377
- overloaded: true,
378
- server: true,
379
- timeout: true,
380
- network: true,
381
- stream_hang: true,
382
- auth: false,
383
- context_overflow: false,
384
- content_filter: false,
385
- invalid_request: false,
386
- unknown: false
387
- };
388
- var ProviderError = class extends WrongStackError {
389
- status;
390
- retryable;
391
- providerId;
392
- /** Canonical failure classification — see {@link ProviderErrorKind}. */
393
- kind;
394
- body;
395
- /**
396
- * Duck-type guard: checks whether an unknown value *looks like* a
397
- * ProviderError by probing for its structural properties. Use this
398
- * anywhere the constructor identity might cross a package boundary
399
- * (e.g. `@wrongstack/providers` creates the error, but the runner in
400
- * `@wrongstack/core` checks it). A plain `instanceof ProviderError`
401
- * can fail when npm hoists duplicate copies of `@wrongstack/core`,
402
- * each with its own class identity.
403
- *
404
- * The check tests for the four invariant properties defined in the
405
- * constructor: `name === 'ProviderError'`, `status` (number),
406
- * `retryable` (boolean), and `kind` (string). This tolerates both
407
- * true `ProviderError` instances and cross-boundary copies.
408
- */
409
- static isProviderError(err) {
410
- if (!err || typeof err !== "object") return false;
411
- const e = err;
412
- const name = e.name;
413
- if (typeof name !== "string" || !name.endsWith("Error")) return false;
414
- return typeof e.status === "number" && typeof e.retryable === "boolean" && typeof e.kind === "string" && typeof e.describe === "function";
415
- }
416
- constructor(message, status, retryable, providerId, opts = {}) {
417
- const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
418
- super({
419
- message,
420
- code: kindToCode(kind),
421
- subsystem: "provider",
422
- severity: status >= 500 ? "error" : "warning",
423
- recoverable: retryable,
424
- context: { providerId, status },
425
- cause: opts.cause
426
- });
427
- this.name = "ProviderError";
428
- this.status = status;
429
- this.retryable = retryable;
430
- this.providerId = providerId;
431
- this.kind = kind;
432
- this.body = opts.body;
433
- }
434
- /**
435
- * Render a one-line, user-facing description. Designed for the CLI/TUI
436
- * status line and the agent's retry warning. Avoids dumping raw JSON
437
- * (which is what users see today when a 529 lands and the log message
438
- * includes the full `{"type":"error",...}` body).
439
- *
440
- * Examples:
441
- * "minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]"
442
- * "openai rate limited (429): Retry after 12s"
443
- * "anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'"
444
- * "groq HTTP 500 (server error)"
445
- */
446
- describe() {
447
- const kind = describeStatus(this.status, this.body?.type);
448
- const head = `${this.providerId} ${kind}`;
449
- const detail = this.body?.message?.trim();
450
- const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
451
- if (detail && detail.length > 0) {
452
- return `${head}: ${truncate(detail, 240)}${reqId}`;
579
+
580
+ // src/types/mode-prompts.ts
581
+ import { readFileSync, statSync } from "node:fs";
582
+ import * as path from "node:path";
583
+ import { fileURLToPath } from "node:url";
584
+ function modePrompt(id) {
585
+ for (const dir of modePromptDirCandidates()) {
586
+ try {
587
+ return readFileSync(path.join(dir, `${id}.md`), "utf8").trimEnd();
588
+ } catch {
453
589
  }
454
- return `${head}${reqId}`;
455
590
  }
456
- };
457
- function isContextOverflowShaped(err) {
458
- if (!(err instanceof ProviderError) && !ProviderError.isProviderError(err)) return false;
459
- const providerErr = err;
460
- if (providerErr.kind === "context_overflow" || providerErr.status === 413) return true;
461
- if (providerErr.status < 400) return false;
462
- const text = [providerErr.message, providerErr.body?.message, providerErr.body?.type, providerErr.body?.raw].filter(Boolean).join("\n");
463
- return CONTEXT_OVERFLOW_RE.test(text);
464
- }
465
- function describeStatus(status, type) {
466
- if (status === 0) return "network error";
467
- if (status === 599) return `stream hang (${status})`;
468
- if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
469
- if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
470
- if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
471
- if (type === "permission_error" || status === 403) return `forbidden (${status})`;
472
- if (type === "not_found_error" || status === 404) return `not found (${status})`;
473
- if (type === "content_filter") return `content filtered (${status})`;
474
- if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
475
- if (status === 408) return `timeout (${status})`;
476
- if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
477
- if (type) return `${type} (${status})`;
478
- return `HTTP ${status}`;
591
+ return "";
479
592
  }
480
- var StreamHangError = class extends ProviderError {
481
- /** Name of the provider that hung, e.g. "zai", "anthropic". */
482
- hungProviderId;
483
- /** Model that was being called when the hang occurred. */
484
- hungModel;
485
- /** How long (ms) we waited for the next chunk before declaring a hang. */
486
- hangTimeoutMs;
487
- /** How many bytes were received before the hang. */
488
- bytesReceived;
489
- /** Elapsed time (ms) from the start of the stream until the hang. */
490
- elapsedMs;
491
- constructor(opts) {
492
- super(
493
- `Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,
494
- 599,
495
- true,
496
- // always retryable
497
- opts.providerId,
498
- {
499
- body: {
500
- message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`
501
- },
502
- cause: opts.cause
503
- }
504
- );
505
- this.name = "StreamHangError";
506
- this.hungProviderId = opts.providerId;
507
- this.hungModel = opts.model;
508
- this.hangTimeoutMs = opts.hangTimeoutMs;
509
- this.bytesReceived = opts.bytesReceived;
510
- this.elapsedMs = opts.elapsedMs;
511
- }
512
- };
513
- var KIND_TO_CODE = {
514
- network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
515
- timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
516
- rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
517
- quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,
518
- auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
519
- overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
520
- context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
521
- server: ERROR_CODES.PROVIDER_SERVER_ERROR,
522
- stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
523
- content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
524
- invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
525
- unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
526
- };
527
- function kindToCode(kind) {
528
- return KIND_TO_CODE[kind];
593
+ function modePromptDirCandidates() {
594
+ const here = path.dirname(fileURLToPath(import.meta.url));
595
+ const candidates = [
596
+ path.resolve(here, "../../instructions/modes"),
597
+ path.resolve(here, "../instructions/modes"),
598
+ path.resolve(here, "instructions/modes")
599
+ ];
600
+ return candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));
529
601
  }
530
-
531
- // src/types/config/fleet-chat.ts
532
- var FLEET_CHAT_VERBOSITY_VALUES = ["off", "full"];
533
- function resolveFleetChatVerbosity(autonomy) {
534
- const explicit = autonomy?.fleetChatVerbosity;
535
- if (explicit && FLEET_CHAT_VERBOSITY_VALUES.includes(explicit)) {
536
- return explicit;
602
+ function isDirectory(candidate) {
603
+ try {
604
+ return statSync(candidate).isDirectory();
605
+ } catch {
606
+ return false;
537
607
  }
538
- return "off";
539
608
  }
540
609
 
541
- // src/types/config/runtime.ts
542
- function normalizeTokenSavingTier(val) {
543
- if (val === void 0) return "off";
544
- if (typeof val === "boolean") return val ? "medium" : "off";
545
- if (val === "auto") return "medium";
546
- const validTiers = /* @__PURE__ */ new Set([
547
- "off",
548
- "minimal",
549
- "light",
550
- "medium",
551
- "aggressive"
552
- ]);
553
- return validTiers.has(val) ? val : "off";
554
- }
555
- function resolveTokenSavingTier(val, maxContext) {
556
- if (val === "auto") {
557
- if (typeof maxContext !== "number" || !Number.isFinite(maxContext) || maxContext <= 0) {
558
- return "off";
559
- }
560
- if (maxContext < 32e3) return "medium";
561
- if (maxContext < 128e3) return "light";
562
- return "minimal";
563
- }
564
- return normalizeTokenSavingTier(val);
565
- }
566
- var DEFAULT_TUI_THINKING_WORD = "thinking";
567
- var MAX_TUI_THINKING_WORD_LENGTH = 16;
568
- function normalizeTuiThinkingWord(value) {
569
- if (typeof value !== "string") return DEFAULT_TUI_THINKING_WORD;
570
- const word = value.trim();
571
- if (word.length === 0 || word.length > MAX_TUI_THINKING_WORD_LENGTH) {
572
- return DEFAULT_TUI_THINKING_WORD;
573
- }
574
- if (!/^[\p{L}\p{N}_-]+$/u.test(word)) return DEFAULT_TUI_THINKING_WORD;
575
- return word;
576
- }
577
-
578
- // src/types/config/ui.ts
579
- var THEME_PRESET_IDS = [
580
- "catppuccin",
581
- "tokyo-night",
582
- "nord",
583
- "cyberpunk",
584
- "dracula",
585
- "gruvbox-dark",
586
- "solarized-dark",
587
- "one-dark",
588
- "monokai",
589
- "rose-pine",
590
- "kanagawa",
591
- "ayu-dark",
592
- "everforest",
593
- "night-owl",
594
- "synthwave",
595
- "github-dark",
596
- "material-ocean",
597
- "nightfox",
598
- "oxocarbon",
599
- "catppuccin-macchiato",
600
- "catppuccin-frappe",
601
- "gruvbox-material",
602
- "tokyo-night-storm",
603
- "rose-pine-moon",
604
- "zenburn",
605
- "palenight",
606
- "horizon",
607
- "sonokai",
608
- "edge-dark",
609
- "moonfly",
610
- "melange",
611
- "poimandres",
612
- "vitesse-dark",
613
- "aura",
614
- "dark-plus"
615
- ];
616
-
617
- // src/types/session-markers.ts
618
- var SESSION_MARKER_EVENT_TYPES = /* @__PURE__ */ new Set([
619
- "mode_changed",
620
- "compaction",
621
- "checkpoint",
622
- "skill_activated",
623
- "skill_deactivated",
624
- "agent_spawned",
625
- "agent_stopped",
626
- "agent_error",
627
- "error",
628
- "provider_retry",
629
- "provider_error",
630
- "message_truncated"
631
- ]);
632
- var CHAT_MARKER_SOURCES = new Set(
633
- [...SESSION_MARKER_EVENT_TYPES].filter((type) => type !== "checkpoint")
634
- );
635
- function sessionEventToMarker(ev) {
636
- switch (ev.type) {
637
- case "compaction": {
638
- const before = (ev.before / 1e3).toFixed(0);
639
- const after = (ev.after / 1e3).toFixed(0);
640
- const level = ev.level ? ` (${ev.level})` : "";
641
- const reductions = ev.reductions && ev.reductions.length > 0 ? ` [${ev.reductions.map((r) => `${r.phase}: \u2212${r.saved}`).join(", ")}]` : "";
642
- return {
643
- ts: ev.ts,
644
- source: ev.type,
645
- level: "info",
646
- text: `\u27F2 context compacted${level}: ${before}K \u2192 ${after}K tokens${reductions}`
647
- };
648
- }
649
- case "error":
650
- return {
651
- ts: ev.ts,
652
- source: ev.type,
653
- level: "error",
654
- text: ev.phase ? `[${ev.phase}] ${ev.message}` : ev.message
655
- };
656
- case "provider_retry": {
657
- const secs = (ev.delayMs / 1e3).toFixed(ev.delayMs >= 1e3 ? 1 : 2);
658
- return {
659
- ts: ev.ts,
660
- source: ev.type,
661
- level: "warn",
662
- text: ev.status ? `\u27F3 retry ${ev.attempt} (HTTP ${ev.status}) after ${secs}s \u2014 ${ev.description}` : `\u27F3 retry ${ev.attempt} after ${secs}s \u2014 ${ev.description}`
663
- };
664
- }
665
- case "provider_error":
666
- return {
667
- ts: ev.ts,
668
- source: ev.type,
669
- level: "error",
670
- text: ev.status ? `provider error (HTTP ${ev.status}, ${ev.retryable ? "retryable" : "fatal"}): ${ev.description}` : `provider error (${ev.retryable ? "retryable" : "fatal"}): ${ev.description}`
671
- };
672
- case "checkpoint":
673
- return {
674
- ts: ev.ts,
675
- source: ev.type,
676
- level: "info",
677
- text: `\u2713 checkpoint #${ev.promptIndex}: "${ev.promptPreview.slice(0, 60)}"`
678
- };
679
- case "agent_spawned":
680
- return {
681
- ts: ev.ts,
682
- source: ev.type,
683
- level: "info",
684
- text: `spawned as ${ev.role}`,
685
- agentId: ev.agentId
686
- };
687
- case "agent_stopped":
688
- return {
689
- ts: ev.ts,
690
- source: ev.type,
691
- level: "info",
692
- text: "stopped",
693
- agentId: ev.agentId
694
- };
695
- case "agent_error":
696
- return {
697
- ts: ev.ts,
698
- source: ev.type,
699
- level: "error",
700
- text: `error: ${ev.error.slice(0, 80)}`,
701
- agentId: ev.agentId
702
- };
703
- case "mode_changed":
704
- return {
705
- ts: ev.ts,
706
- source: ev.type,
707
- level: "info",
708
- text: `mode: ${ev.from} \u2192 ${ev.to}`
709
- };
710
- case "skill_activated":
711
- return {
712
- ts: ev.ts,
713
- source: ev.type,
714
- level: "info",
715
- text: `skill activated: ${ev.skillName}`
716
- };
717
- case "skill_deactivated":
718
- return {
719
- ts: ev.ts,
720
- source: ev.type,
721
- level: "info",
722
- text: `skill deactivated: ${ev.skillName}`
723
- };
724
- case "message_truncated":
725
- return {
726
- ts: ev.ts,
727
- source: ev.type,
728
- level: "warn",
729
- text: ev.after < ev.before ? `message truncated: ${ev.before} \u2192 ${ev.after} tokens` : `message truncated at ${ev.after} tokens`
730
- };
731
- default:
732
- return null;
733
- }
734
- }
735
- function projectSessionMarkers(events, sources = SESSION_MARKER_EVENT_TYPES) {
736
- const markers = [];
737
- for (const ev of events) {
738
- if (!sources.has(ev.type)) continue;
739
- const marker = sessionEventToMarker(ev);
740
- if (marker) markers.push(marker);
741
- }
742
- return markers;
743
- }
744
-
745
- // src/types/default-config.ts
746
- var DEFAULT_TOOLS_CONFIG = Object.freeze({
747
- defaultExecutionStrategy: "smart",
748
- maxIterations: 100,
749
- iterationTimeoutMs: 3e5,
750
- maxToolTimeoutMs: 3e5,
751
- sessionTimeoutMs: 18e5,
752
- perIterationOutputCapBytes: 1e5,
753
- descriptionMode: Object.freeze({}),
754
- disabledTools: Object.freeze([]),
755
- autoExtendLimit: true,
756
- restrictToProjectRoot: true,
757
- // Off by default: the board is a record of the work, not a permit for it.
758
- // See ToolsConfig.kanbanGovernance for what turning it on costs and gates.
759
- kanbanGovernance: false,
760
- loopDetection: Object.freeze({
761
- mode: "steer-then-cut",
762
- steerThreshold: 3,
763
- cutThreshold: 5,
764
- windowSize: 12,
765
- callRepeatThreshold: 4
766
- })
767
- });
768
- var DEFAULT_CONTEXT_CONFIG = Object.freeze({
769
- warnThreshold: 0.55,
770
- softThreshold: 0.7,
771
- hardThreshold: 0.85,
772
- targetLoad: 0.65,
773
- preserveK: 8,
774
- eliseThreshold: 1200
775
- });
776
- var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
777
- autoProceedDelayMs: 45e3
778
- });
779
- var DEFAULT_CIRCUIT_BREAKER_CONFIG = Object.freeze({
780
- enabled: false,
781
- autoKillResetMs: 6e4
782
- });
783
- var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
784
- auditLevel: "standard",
785
- sampling: {
786
- toolProgress: {
787
- sampleRate: 8
788
- }
610
+ // src/types/mode.ts
611
+ var DEFAULT_MODES = [
612
+ {
613
+ id: "default",
614
+ name: "Default",
615
+ description: "Balanced general-purpose mode; use when no special token/coverage trade-off is needed",
616
+ prompt: "",
617
+ tags: ["general", "balanced"]
618
+ },
619
+ {
620
+ id: "brief",
621
+ name: "Brief",
622
+ description: "Ultra-compact responses for low-context, high-speed work",
623
+ prompt: modePrompt("brief"),
624
+ tags: ["lite", "fast", "concise", "token-saving"],
625
+ toolPreferences: ["read", "edit", "bash"],
626
+ suggestedSkills: []
627
+ },
628
+ {
629
+ id: "review-lite",
630
+ name: "Review Lite",
631
+ description: "Token-saving code review: changed files only, top correctness/security risks",
632
+ prompt: modePrompt("review-lite"),
633
+ tags: ["lite", "review", "quality", "token-saving"],
634
+ toolPreferences: ["git", "diff", "read", "grep"],
635
+ suggestedSkills: ["bug-hunter", "typescript-strict"]
636
+ },
637
+ {
638
+ id: "audit-lite",
639
+ name: "Audit Lite",
640
+ description: "Token-saving security triage for a small diff or named file",
641
+ prompt: modePrompt("audit-lite"),
642
+ tags: ["lite", "security", "audit", "token-saving"],
643
+ toolPreferences: ["grep", "read", "git"],
644
+ suggestedSkills: ["security-scanner"]
645
+ },
646
+ {
647
+ id: "plan-lite",
648
+ name: "Plan Lite",
649
+ description: "Token-saving planning: 3-6 actionable steps, minimal design debate",
650
+ prompt: modePrompt("plan-lite"),
651
+ tags: ["lite", "planning", "architecture", "token-saving"],
652
+ toolPreferences: ["tree", "glob", "read", "grep"],
653
+ suggestedSkills: ["refactor-planner"]
654
+ },
655
+ {
656
+ id: "debug-lite",
657
+ name: "Debug Lite",
658
+ description: "Token-saving bug triage: one hypothesis, nearest evidence, narrow check",
659
+ prompt: modePrompt("debug-lite"),
660
+ tags: ["lite", "debug", "triage", "token-saving"],
661
+ toolPreferences: ["read", "grep", "test", "logs"],
662
+ suggestedSkills: ["bug-hunter"]
663
+ },
664
+ {
665
+ id: "test-lite",
666
+ name: "Test Lite",
667
+ description: "Token-saving tests: one focused regression or narrow verification target",
668
+ prompt: modePrompt("test-lite"),
669
+ tags: ["lite", "testing", "qa", "token-saving"],
670
+ toolPreferences: ["test", "read", "grep"],
671
+ suggestedSkills: ["testing"]
672
+ },
673
+ {
674
+ id: "refactor-lite",
675
+ name: "Refactor Lite",
676
+ description: "Token-saving cleanup: small scoped behavior-preserving changes",
677
+ prompt: modePrompt("refactor-lite"),
678
+ tags: ["lite", "refactor", "token-saving"],
679
+ toolPreferences: ["read", "edit", "test"],
680
+ suggestedSkills: ["typescript-strict"]
681
+ },
682
+ {
683
+ id: "research-lite",
684
+ name: "Research Lite",
685
+ description: "Token-saving web research: one search, one authoritative fetch, short answer",
686
+ prompt: modePrompt("research-lite"),
687
+ tags: ["lite", "research", "web", "token-saving"],
688
+ toolPreferences: ["search", "fetch"],
689
+ suggestedSkills: ["research-web"]
690
+ },
691
+ {
692
+ id: "code-reviewer",
693
+ name: "Review Deep",
694
+ description: "Comprehensive code review across contracts, edge cases, lifecycle, errors, concurrency",
695
+ prompt: modePrompt("code-reviewer"),
696
+ tags: ["deep", "review", "quality", "security"],
697
+ toolPreferences: ["read", "grep", "git", "diff", "test"],
698
+ suggestedSkills: ["bug-hunter", "security-scanner", "typescript-strict", "testing"]
699
+ },
700
+ {
701
+ id: "code-auditor",
702
+ name: "Audit Deep",
703
+ description: "Comprehensive security audit with category coverage and exploitability notes",
704
+ prompt: modePrompt("code-auditor"),
705
+ tags: ["deep", "security", "audit", "compliance"],
706
+ toolPreferences: ["grep", "read", "audit", "bash"],
707
+ suggestedSkills: ["security-scanner", "bug-hunter", "audit-log"]
708
+ },
709
+ {
710
+ id: "architect",
711
+ name: "Architecture Deep",
712
+ description: "Comprehensive architecture and cross-module contract analysis",
713
+ prompt: modePrompt("architect"),
714
+ tags: ["deep", "architecture", "design", "scalability"],
715
+ toolPreferences: ["read", "glob", "tree", "diff"],
716
+ suggestedSkills: ["api-design", "refactor-planner", "node-modern", "docker-deploy"]
717
+ },
718
+ {
719
+ id: "debugger",
720
+ name: "Debug Deep",
721
+ description: "Comprehensive root-cause analysis with traces, logs, assumptions, and verification",
722
+ prompt: modePrompt("debugger"),
723
+ tags: ["deep", "debug", "investigation", "error-resolution"],
724
+ toolPreferences: ["read", "grep", "bash", "logs", "test"],
725
+ suggestedSkills: ["bug-hunter", "audit-log", "observability"]
726
+ },
727
+ {
728
+ id: "tester",
729
+ name: "Test Deep",
730
+ description: "Comprehensive QA mode for coverage, boundaries, isolation, and integration gaps",
731
+ prompt: modePrompt("tester"),
732
+ tags: ["deep", "testing", "qa", "quality"],
733
+ toolPreferences: ["read", "grep", "test", "bash"],
734
+ suggestedSkills: ["testing", "bug-hunter", "typescript-strict"]
735
+ },
736
+ {
737
+ id: "devops",
738
+ name: "DevOps Deep",
739
+ description: "Comprehensive infrastructure, deployment, observability, and operations review",
740
+ prompt: modePrompt("devops"),
741
+ tags: ["deep", "devops", "infrastructure", "operations"],
742
+ toolPreferences: ["read", "bash", "grep", "logs", "git"],
743
+ suggestedSkills: ["docker-deploy", "observability", "security-scanner"]
744
+ },
745
+ {
746
+ id: "refactorer",
747
+ name: "Refactor Deep",
748
+ description: "Comprehensive modernization/refactor mode with contracts and verification discipline",
749
+ prompt: modePrompt("refactorer"),
750
+ tags: ["deep", "refactor", "modernization", "improvement"],
751
+ toolPreferences: ["read", "edit", "test", "git", "grep"],
752
+ suggestedSkills: ["refactor-planner", "typescript-strict", "node-modern", "testing"]
753
+ },
754
+ {
755
+ id: "ui-design",
756
+ name: "UI Design Deep",
757
+ description: "Comprehensive design-first frontend/mobile UI work with kit, tokens, and accessibility",
758
+ prompt: modePrompt("ui-design"),
759
+ tags: ["deep", "ui", "frontend", "mobile", "design"],
760
+ toolPreferences: ["design", "write", "edit", "read", "scaffold"],
761
+ suggestedSkills: ["react-modern"]
762
+ },
763
+ {
764
+ id: "teach",
765
+ name: "Teach Deep",
766
+ description: "Mentor mode with explanations, mental models, trade-offs, and takeaways",
767
+ prompt: modePrompt("teach"),
768
+ tags: ["deep", "teaching", "mentor", "learning"],
769
+ toolPreferences: ["read", "edit", "explain"],
770
+ suggestedSkills: ["prompt-engineering", "skill-creator", "node-modern", "typescript-strict"]
771
+ },
772
+ {
773
+ id: "research-web",
774
+ name: "Research Deep",
775
+ description: "Comprehensive current-data research with cross-checking and reusable findings",
776
+ prompt: modePrompt("research-web"),
777
+ tags: ["deep", "research", "web", "current-data", "up-to-date"],
778
+ toolPreferences: ["search", "fetch", "context_manager"],
779
+ suggestedSkills: ["research-web", "tech-stack", "node-modern", "security-scanner", "react-modern"]
789
780
  }
790
- });
791
- var DEFAULT_SESSION_PRUNE_DAYS = 30;
792
-
793
- // src/types/memory.ts
794
- var MEMORY_TYPE_LABELS = {
795
- fact: "Fact",
796
- decision: "Decision",
797
- convention: "Convention",
798
- preference: "Preference",
799
- reference: "Reference",
800
- anti_pattern: "Anti-pattern"
801
- };
802
- function defineMemoryCapability(id) {
803
- return Object.freeze({
804
- id,
805
- /** Identity function that makes the brand a real runtime value so
806
- * `defineMemoryCapability<A>('x')` and `defineMemoryCapability<B>('x')`
807
- * produce structurally distinct objects. Capability lookup is still
808
- * keyed by `id` only — the brand prevents accidental cross-type casts
809
- * at the type level. */
810
- __memoryCapabilityType: (v) => v
811
- });
812
- }
781
+ ];
813
782
 
814
783
  // src/types/prompt.ts
815
784
  var BUILTIN_PROMPT_CATEGORIES = [
@@ -931,336 +900,365 @@ function diffRegistry(local, manifest) {
931
900
  return diff;
932
901
  }
933
902
 
934
- // src/types/design-kit.ts
935
- var DESIGN_STACKS = ["web", "react-native", "flutter", "swiftui", "compose"];
936
- function isDesignStack(v) {
937
- return DESIGN_STACKS.includes(v);
903
+ // src/utils/string.ts
904
+ function truncate(s, max) {
905
+ return s.length <= max ? s : `${s.slice(0, max - 1)}\u2026`;
938
906
  }
939
- var KNOWN_TOKEN_GROUPS = {
940
- /** Corner radii. */
941
- radius: ["radius-none", "radius-sm", "radius-md", "radius-lg", "radius-xl", "radius-full"],
942
- /** Spacing scale (4/8px rhythm). */
943
- space: ["space-1", "space-2", "space-3", "space-4", "space-6", "space-8", "space-12"],
944
- /** Type sizes. */
945
- text: ["text-xs", "text-sm", "text-base", "text-lg", "text-xl", "text-2xl", "text-3xl"],
946
- /** Line-heights (unitless). */
947
- leading: ["leading-tight", "leading-normal", "leading-relaxed"],
948
- /** Font weights (unitless). */
949
- weight: ["weight-normal", "weight-medium", "weight-semibold", "weight-bold"],
950
- /** Letter-spacing. */
951
- tracking: ["tracking-tight", "tracking-normal", "tracking-wide"],
952
- /** Elevation / shadow ramp. */
953
- shadow: ["shadow-1", "shadow-2", "shadow-3", "shadow-4"],
954
- /** Border widths. */
955
- border: ["border-hairline", "border-thin", "border-thick"],
956
- /** Motion durations. */
957
- duration: ["duration-fast", "duration-base", "duration-slow"],
958
- /** Motion easings. */
959
- ease: ["ease-standard", "ease-emphasized"],
960
- /** Font families. */
961
- font: ["font-sans", "font-mono", "font-display"]
962
- };
963
- var KNOWN_TOKEN_NAMES = Object.values(KNOWN_TOKEN_GROUPS).flat();
964
907
 
965
- // src/types/system-prompt.ts
966
- function flattenSystemPromptRegions(regions) {
967
- return [...regions.core, ...regions.session, ...regions.volatile];
968
- }
908
+ // src/types/quota-regex.ts
909
+ var QUOTA_EXHAUSTED_RE = /(?:insufficient|exhausted|depleted|exceeded|no|not enough)[-_\s]*(?:quota|credit|balance)|(?:quota|credit|balance)(?:\s+(?:has|have))?(?:\s+been)?[-_\s]*(?:exhausted|depleted|exceeded|insufficient)|billing[_\s-]*(?:hard[_\s-]*)?limit|payment required|spending limit|plan limit|usage[-_\s]*limit[-_\s]*(?:reached|exceeded)/i;
969
910
 
970
- // src/types/mode-prompts.ts
971
- import { readFileSync, statSync } from "node:fs";
972
- import * as path from "node:path";
973
- import { fileURLToPath } from "node:url";
974
- function modePrompt(id) {
975
- for (const dir of modePromptDirCandidates()) {
976
- try {
977
- return readFileSync(path.join(dir, `${id}.md`), "utf8").trimEnd();
978
- } catch {
911
+ // src/types/provider.ts
912
+ function effectiveInputTokens(usage) {
913
+ return usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0);
914
+ }
915
+ var CONTEXT_OVERFLOW_RE = /context.length|context.window|maximum context|max.*tokens?.*exceeded|(?:prompt|request|input|messages?).{0,12}too (?:large|long)|exceeds the context|\btokens\b.*exceed|too many tokens|reduce the length|resulted in \d+ tokens|context_length_exceeded/i;
916
+ var CONTENT_FILTER_RE = /content.(filter|policy|moderation)|safety (system|filter)/i;
917
+ var RATE_LIMIT_EXCEEDED_RE = /rate[-_\s]*limit[-_\s]*exceeded/i;
918
+ function classifyProviderError(status, body, message) {
919
+ const type = body?.type;
920
+ const text = [message, body?.message, type, body?.raw].filter(Boolean).join("\n");
921
+ if (status === 0) return "network";
922
+ if (status === 408) return "timeout";
923
+ if (status === 599) return "stream_hang";
924
+ if (status === 402 || QUOTA_EXHAUSTED_RE.test(text)) return "quota_exhausted";
925
+ if (status === 429 && body?.message && body.type !== "rate_limit_exceeded" && RATE_LIMIT_EXCEEDED_RE.test(body.message)) {
926
+ return "quota_exhausted";
927
+ }
928
+ if (type === "rate_limit_error" || status === 429) return "rate_limit";
929
+ if (type === "overloaded_error" || status === 529) return "overloaded";
930
+ if (status >= 500) return "server";
931
+ if (type === "authentication_error" || type === "permission_error" || status === 401 || status === 403) {
932
+ return "auth";
933
+ }
934
+ if (type === "content_filter" || CONTENT_FILTER_RE.test(text)) return "content_filter";
935
+ if (status === 413 || status >= 400 && CONTEXT_OVERFLOW_RE.test(text)) {
936
+ return "context_overflow";
937
+ }
938
+ if (status >= 400) return "invalid_request";
939
+ return "unknown";
940
+ }
941
+ var MAX_RESET_HINT_MS = 7 * 24 * 60 * 60 * 1e3;
942
+ function isRetryableKind(kind) {
943
+ return RETRYABLE_BY_KIND[kind];
944
+ }
945
+ var RETRYABLE_BY_KIND = {
946
+ rate_limit: true,
947
+ quota_exhausted: false,
948
+ overloaded: true,
949
+ server: true,
950
+ timeout: true,
951
+ network: true,
952
+ stream_hang: true,
953
+ auth: false,
954
+ context_overflow: false,
955
+ content_filter: false,
956
+ invalid_request: false,
957
+ unknown: false
958
+ };
959
+ function isFallbackWorthy(kind) {
960
+ return FALLBACK_WORTHY_BY_KIND[kind];
961
+ }
962
+ var FALLBACK_WORTHY_BY_KIND = {
963
+ rate_limit: true,
964
+ quota_exhausted: true,
965
+ overloaded: true,
966
+ server: true,
967
+ timeout: true,
968
+ network: true,
969
+ stream_hang: true,
970
+ auth: false,
971
+ context_overflow: false,
972
+ content_filter: false,
973
+ invalid_request: false,
974
+ unknown: false
975
+ };
976
+ var ProviderError = class extends WrongStackError {
977
+ status;
978
+ retryable;
979
+ providerId;
980
+ /** Canonical failure classification — see {@link ProviderErrorKind}. */
981
+ kind;
982
+ body;
983
+ /**
984
+ * Duck-type guard: checks whether an unknown value *looks like* a
985
+ * ProviderError by probing for its structural properties. Use this
986
+ * anywhere the constructor identity might cross a package boundary
987
+ * (e.g. `@wrongstack/providers` creates the error, but the runner in
988
+ * `@wrongstack/core` checks it). A plain `instanceof ProviderError`
989
+ * can fail when npm hoists duplicate copies of `@wrongstack/core`,
990
+ * each with its own class identity.
991
+ *
992
+ * The check tests for the four invariant properties defined in the
993
+ * constructor: `name === 'ProviderError'`, `status` (number),
994
+ * `retryable` (boolean), and `kind` (string). This tolerates both
995
+ * true `ProviderError` instances and cross-boundary copies.
996
+ */
997
+ static isProviderError(err) {
998
+ if (!err || typeof err !== "object") return false;
999
+ const e = err;
1000
+ const name = e.name;
1001
+ if (typeof name !== "string" || !name.endsWith("Error")) return false;
1002
+ return typeof e.status === "number" && typeof e.retryable === "boolean" && typeof e.kind === "string" && typeof e.describe === "function";
1003
+ }
1004
+ constructor(message, status, retryable, providerId, opts = {}) {
1005
+ const kind = opts.kind ?? classifyProviderError(status, opts.body, message);
1006
+ super({
1007
+ message,
1008
+ code: kindToCode(kind),
1009
+ subsystem: "provider",
1010
+ severity: status >= 500 ? "error" : "warning",
1011
+ recoverable: retryable,
1012
+ context: { providerId, status },
1013
+ cause: opts.cause
1014
+ });
1015
+ this.name = "ProviderError";
1016
+ this.status = status;
1017
+ this.retryable = retryable;
1018
+ this.providerId = providerId;
1019
+ this.kind = kind;
1020
+ this.body = opts.body;
1021
+ }
1022
+ /**
1023
+ * Render a one-line, user-facing description. Designed for the CLI/TUI
1024
+ * status line and the agent's retry warning. Avoids dumping raw JSON
1025
+ * (which is what users see today when a 529 lands and the log message
1026
+ * includes the full `{"type":"error",...}` body).
1027
+ *
1028
+ * Examples:
1029
+ * "minimax-coding-plan overloaded (529): High traffic detected. Upgrade for highspeed model. [req 06534785201de9c0…]"
1030
+ * "openai rate limited (429): Retry after 12s"
1031
+ * "anthropic invalid request (400): messages.0.role must be one of 'user'|'assistant'"
1032
+ * "groq HTTP 500 (server error)"
1033
+ */
1034
+ describe() {
1035
+ const kind = describeStatus(this.status, this.body?.type);
1036
+ const head = `${this.providerId} ${kind}`;
1037
+ const detail = this.body?.message?.trim();
1038
+ const reqId = this.body?.requestId ? ` [req ${this.body.requestId.slice(0, 16)}${this.body.requestId.length > 16 ? "\u2026" : ""}]` : "";
1039
+ if (detail && detail.length > 0) {
1040
+ return `${head}: ${truncate(detail, 240)}${reqId}`;
979
1041
  }
1042
+ return `${head}${reqId}`;
980
1043
  }
981
- return "";
982
- }
983
- function modePromptDirCandidates() {
984
- const here = path.dirname(fileURLToPath(import.meta.url));
985
- const candidates = [
986
- path.resolve(here, "../../instructions/modes"),
987
- path.resolve(here, "../instructions/modes"),
988
- path.resolve(here, "instructions/modes")
989
- ];
990
- return candidates.sort((a, b) => Number(!isDirectory(a)) - Number(!isDirectory(b)));
1044
+ };
1045
+ function isContextOverflowShaped(err) {
1046
+ if (!(err instanceof ProviderError) && !ProviderError.isProviderError(err)) return false;
1047
+ const providerErr = err;
1048
+ if (providerErr.kind === "context_overflow" || providerErr.status === 413) return true;
1049
+ if (providerErr.status < 400) return false;
1050
+ const text = [providerErr.message, providerErr.body?.message, providerErr.body?.type, providerErr.body?.raw].filter(Boolean).join("\n");
1051
+ return CONTEXT_OVERFLOW_RE.test(text);
991
1052
  }
992
- function isDirectory(candidate) {
993
- try {
994
- return statSync(candidate).isDirectory();
995
- } catch {
996
- return false;
997
- }
1053
+ function describeStatus(status, type) {
1054
+ if (status === 0) return "network error";
1055
+ if (status === 599) return `stream hang (${status})`;
1056
+ if (type === "overloaded_error" || status === 529) return `overloaded (${status})`;
1057
+ if (type === "rate_limit_error" || status === 429) return `rate limited (${status})`;
1058
+ if (type === "authentication_error" || status === 401) return `auth failed (${status})`;
1059
+ if (type === "permission_error" || status === 403) return `forbidden (${status})`;
1060
+ if (type === "not_found_error" || status === 404) return `not found (${status})`;
1061
+ if (type === "content_filter") return `content filtered (${status})`;
1062
+ if (type === "invalid_request_error" || status === 400) return `invalid request (${status})`;
1063
+ if (status === 408) return `timeout (${status})`;
1064
+ if (status >= 500 && status < 600) return `HTTP ${status} (server error)`;
1065
+ if (type) return `${type} (${status})`;
1066
+ return `HTTP ${status}`;
998
1067
  }
999
-
1000
- // src/types/mode.ts
1001
- var DEFAULT_MODES = [
1002
- {
1003
- id: "default",
1004
- name: "Default",
1005
- description: "Balanced general-purpose mode; use when no special token/coverage trade-off is needed",
1006
- prompt: "",
1007
- tags: ["general", "balanced"]
1008
- },
1009
- {
1010
- id: "brief",
1011
- name: "Brief",
1012
- description: "Ultra-compact responses for low-context, high-speed work",
1013
- prompt: modePrompt("brief"),
1014
- tags: ["lite", "fast", "concise", "token-saving"],
1015
- toolPreferences: ["read", "edit", "bash"],
1016
- suggestedSkills: []
1017
- },
1018
- {
1019
- id: "review-lite",
1020
- name: "Review Lite",
1021
- description: "Token-saving code review: changed files only, top correctness/security risks",
1022
- prompt: modePrompt("review-lite"),
1023
- tags: ["lite", "review", "quality", "token-saving"],
1024
- toolPreferences: ["git", "diff", "read", "grep"],
1025
- suggestedSkills: ["bug-hunter", "typescript-strict"]
1026
- },
1027
- {
1028
- id: "audit-lite",
1029
- name: "Audit Lite",
1030
- description: "Token-saving security triage for a small diff or named file",
1031
- prompt: modePrompt("audit-lite"),
1032
- tags: ["lite", "security", "audit", "token-saving"],
1033
- toolPreferences: ["grep", "read", "git"],
1034
- suggestedSkills: ["security-scanner"]
1035
- },
1036
- {
1037
- id: "plan-lite",
1038
- name: "Plan Lite",
1039
- description: "Token-saving planning: 3-6 actionable steps, minimal design debate",
1040
- prompt: modePrompt("plan-lite"),
1041
- tags: ["lite", "planning", "architecture", "token-saving"],
1042
- toolPreferences: ["tree", "glob", "read", "grep"],
1043
- suggestedSkills: ["refactor-planner"]
1044
- },
1045
- {
1046
- id: "debug-lite",
1047
- name: "Debug Lite",
1048
- description: "Token-saving bug triage: one hypothesis, nearest evidence, narrow check",
1049
- prompt: modePrompt("debug-lite"),
1050
- tags: ["lite", "debug", "triage", "token-saving"],
1051
- toolPreferences: ["read", "grep", "test", "logs"],
1052
- suggestedSkills: ["bug-hunter"]
1053
- },
1054
- {
1055
- id: "test-lite",
1056
- name: "Test Lite",
1057
- description: "Token-saving tests: one focused regression or narrow verification target",
1058
- prompt: modePrompt("test-lite"),
1059
- tags: ["lite", "testing", "qa", "token-saving"],
1060
- toolPreferences: ["test", "read", "grep"],
1061
- suggestedSkills: ["testing"]
1062
- },
1063
- {
1064
- id: "refactor-lite",
1065
- name: "Refactor Lite",
1066
- description: "Token-saving cleanup: small scoped behavior-preserving changes",
1067
- prompt: modePrompt("refactor-lite"),
1068
- tags: ["lite", "refactor", "token-saving"],
1069
- toolPreferences: ["read", "edit", "test"],
1070
- suggestedSkills: ["typescript-strict"]
1071
- },
1072
- {
1073
- id: "research-lite",
1074
- name: "Research Lite",
1075
- description: "Token-saving web research: one search, one authoritative fetch, short answer",
1076
- prompt: modePrompt("research-lite"),
1077
- tags: ["lite", "research", "web", "token-saving"],
1078
- toolPreferences: ["search", "fetch"],
1079
- suggestedSkills: ["research-web"]
1080
- },
1081
- {
1082
- id: "code-reviewer",
1083
- name: "Review Deep",
1084
- description: "Comprehensive code review across contracts, edge cases, lifecycle, errors, concurrency",
1085
- prompt: modePrompt("code-reviewer"),
1086
- tags: ["deep", "review", "quality", "security"],
1087
- toolPreferences: ["read", "grep", "git", "diff", "test"],
1088
- suggestedSkills: ["bug-hunter", "security-scanner", "typescript-strict", "testing"]
1089
- },
1090
- {
1091
- id: "code-auditor",
1092
- name: "Audit Deep",
1093
- description: "Comprehensive security audit with category coverage and exploitability notes",
1094
- prompt: modePrompt("code-auditor"),
1095
- tags: ["deep", "security", "audit", "compliance"],
1096
- toolPreferences: ["grep", "read", "audit", "bash"],
1097
- suggestedSkills: ["security-scanner", "bug-hunter", "audit-log"]
1098
- },
1099
- {
1100
- id: "architect",
1101
- name: "Architecture Deep",
1102
- description: "Comprehensive architecture and cross-module contract analysis",
1103
- prompt: modePrompt("architect"),
1104
- tags: ["deep", "architecture", "design", "scalability"],
1105
- toolPreferences: ["read", "glob", "tree", "diff"],
1106
- suggestedSkills: ["api-design", "refactor-planner", "node-modern", "docker-deploy"]
1107
- },
1108
- {
1109
- id: "debugger",
1110
- name: "Debug Deep",
1111
- description: "Comprehensive root-cause analysis with traces, logs, assumptions, and verification",
1112
- prompt: modePrompt("debugger"),
1113
- tags: ["deep", "debug", "investigation", "error-resolution"],
1114
- toolPreferences: ["read", "grep", "bash", "logs", "test"],
1115
- suggestedSkills: ["bug-hunter", "audit-log", "observability"]
1116
- },
1117
- {
1118
- id: "tester",
1119
- name: "Test Deep",
1120
- description: "Comprehensive QA mode for coverage, boundaries, isolation, and integration gaps",
1121
- prompt: modePrompt("tester"),
1122
- tags: ["deep", "testing", "qa", "quality"],
1123
- toolPreferences: ["read", "grep", "test", "bash"],
1124
- suggestedSkills: ["testing", "bug-hunter", "typescript-strict"]
1125
- },
1126
- {
1127
- id: "devops",
1128
- name: "DevOps Deep",
1129
- description: "Comprehensive infrastructure, deployment, observability, and operations review",
1130
- prompt: modePrompt("devops"),
1131
- tags: ["deep", "devops", "infrastructure", "operations"],
1132
- toolPreferences: ["read", "bash", "grep", "logs", "git"],
1133
- suggestedSkills: ["docker-deploy", "observability", "security-scanner"]
1134
- },
1135
- {
1136
- id: "refactorer",
1137
- name: "Refactor Deep",
1138
- description: "Comprehensive modernization/refactor mode with contracts and verification discipline",
1139
- prompt: modePrompt("refactorer"),
1140
- tags: ["deep", "refactor", "modernization", "improvement"],
1141
- toolPreferences: ["read", "edit", "test", "git", "grep"],
1142
- suggestedSkills: ["refactor-planner", "typescript-strict", "node-modern", "testing"]
1143
- },
1144
- {
1145
- id: "ui-design",
1146
- name: "UI Design Deep",
1147
- description: "Comprehensive design-first frontend/mobile UI work with kit, tokens, and accessibility",
1148
- prompt: modePrompt("ui-design"),
1149
- tags: ["deep", "ui", "frontend", "mobile", "design"],
1150
- toolPreferences: ["design", "write", "edit", "read", "scaffold"],
1151
- suggestedSkills: ["react-modern"]
1152
- },
1153
- {
1154
- id: "teach",
1155
- name: "Teach Deep",
1156
- description: "Mentor mode with explanations, mental models, trade-offs, and takeaways",
1157
- prompt: modePrompt("teach"),
1158
- tags: ["deep", "teaching", "mentor", "learning"],
1159
- toolPreferences: ["read", "edit", "explain"],
1160
- suggestedSkills: ["prompt-engineering", "skill-creator", "node-modern", "typescript-strict"]
1161
- },
1162
- {
1163
- id: "research-web",
1164
- name: "Research Deep",
1165
- description: "Comprehensive current-data research with cross-checking and reusable findings",
1166
- prompt: modePrompt("research-web"),
1167
- tags: ["deep", "research", "web", "current-data", "up-to-date"],
1168
- toolPreferences: ["search", "fetch", "context_manager"],
1169
- suggestedSkills: ["research-web", "tech-stack", "node-modern", "security-scanner", "react-modern"]
1170
- }
1171
- ];
1172
-
1173
- // src/utils/expect-defined.ts
1174
- function expectDefined(value, label) {
1175
- if (value === null || value === void 0) {
1176
- const err = new Error(label ? `Expected ${label} to be defined` : "Expected value to be defined");
1177
- err.name = "ExpectDefinedError";
1178
- throw err;
1068
+ var StreamHangError = class extends ProviderError {
1069
+ /** Name of the provider that hung, e.g. "zai", "anthropic". */
1070
+ hungProviderId;
1071
+ /** Model that was being called when the hang occurred. */
1072
+ hungModel;
1073
+ /** How long (ms) we waited for the next chunk before declaring a hang. */
1074
+ hangTimeoutMs;
1075
+ /** How many bytes were received before the hang. */
1076
+ bytesReceived;
1077
+ /** Elapsed time (ms) from the start of the stream until the hang. */
1078
+ elapsedMs;
1079
+ constructor(opts) {
1080
+ super(
1081
+ `Stream hang: ${opts.providerId}/${opts.model} \u2014 no data for ${opts.hangTimeoutMs}ms after ${opts.bytesReceived} bytes (${opts.elapsedMs}ms elapsed)`,
1082
+ 599,
1083
+ true,
1084
+ // always retryable
1085
+ opts.providerId,
1086
+ {
1087
+ body: {
1088
+ message: `Stream stalled after ${opts.elapsedMs}ms, ${opts.bytesReceived} bytes received`
1089
+ },
1090
+ cause: opts.cause
1091
+ }
1092
+ );
1093
+ this.name = "StreamHangError";
1094
+ this.hungProviderId = opts.providerId;
1095
+ this.hungModel = opts.model;
1096
+ this.hangTimeoutMs = opts.hangTimeoutMs;
1097
+ this.bytesReceived = opts.bytesReceived;
1098
+ this.elapsedMs = opts.elapsedMs;
1179
1099
  }
1180
- return value;
1100
+ };
1101
+ var KIND_TO_CODE = {
1102
+ network: ERROR_CODES.PROVIDER_NETWORK_ERROR,
1103
+ timeout: ERROR_CODES.PROVIDER_NETWORK_ERROR,
1104
+ rate_limit: ERROR_CODES.PROVIDER_RATE_LIMITED,
1105
+ quota_exhausted: ERROR_CODES.PROVIDER_RATE_LIMITED,
1106
+ auth: ERROR_CODES.PROVIDER_AUTH_FAILED,
1107
+ overloaded: ERROR_CODES.PROVIDER_OVERLOADED,
1108
+ context_overflow: ERROR_CODES.PROVIDER_CONTEXT_OVERFLOW,
1109
+ server: ERROR_CODES.PROVIDER_SERVER_ERROR,
1110
+ stream_hang: ERROR_CODES.PROVIDER_SERVER_ERROR,
1111
+ content_filter: ERROR_CODES.PROVIDER_INVALID_REQUEST,
1112
+ invalid_request: ERROR_CODES.PROVIDER_INVALID_REQUEST,
1113
+ unknown: ERROR_CODES.PROVIDER_INVALID_REQUEST
1114
+ };
1115
+ function kindToCode(kind) {
1116
+ return KIND_TO_CODE[kind];
1181
1117
  }
1182
1118
 
1183
- // src/types/context-window.ts
1184
- var DEFAULT_CONTEXT_WINDOW_MODE_ID = "balanced";
1185
- var DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES = Object.freeze({
1186
- archival: "balanced"
1187
- });
1188
- var CONTEXT_WINDOW_MODES = Object.freeze([
1189
- {
1190
- id: "balanced",
1191
- name: "Balanced",
1192
- description: "Default rolling compaction: recent work stays verbatim, old tool output is trimmed.",
1193
- thresholds: { warn: 0.55, soft: 0.7, hard: 0.85 },
1194
- aggressiveOn: "soft",
1195
- preserveK: 8,
1196
- eliseThreshold: 1200,
1197
- targetLoad: 0.65
1198
- },
1199
- {
1200
- id: "frugal",
1201
- name: "Frugal",
1202
- description: "Token-saver mode: compacts early and keeps a tight verbatim tail.",
1203
- thresholds: { warn: 0.4, soft: 0.55, hard: 0.7 },
1204
- aggressiveOn: "warn",
1205
- preserveK: 4,
1206
- eliseThreshold: 500,
1207
- targetLoad: 0.45
1208
- },
1209
- {
1210
- id: "deep",
1211
- name: "Deep",
1212
- description: "Long-reasoning mode: delays compaction and keeps more recent turns intact.",
1213
- thresholds: { warn: 0.72, soft: 0.86, hard: 0.96 },
1214
- aggressiveOn: "hard",
1215
- preserveK: 18,
1216
- eliseThreshold: 5e3,
1217
- targetLoad: 0.82
1218
- }
1119
+ // src/types/session-markers.ts
1120
+ var SESSION_MARKER_EVENT_TYPES = /* @__PURE__ */ new Set([
1121
+ "mode_changed",
1122
+ "compaction",
1123
+ "checkpoint",
1124
+ "skill_activated",
1125
+ "skill_deactivated",
1126
+ "agent_spawned",
1127
+ "agent_stopped",
1128
+ "agent_error",
1129
+ "error",
1130
+ "provider_retry",
1131
+ "provider_error",
1132
+ "message_truncated"
1219
1133
  ]);
1220
- function listContextWindowModes() {
1221
- return CONTEXT_WINDOW_MODES.map((m) => ({ ...m, thresholds: { ...m.thresholds } }));
1222
- }
1223
- function normalizeContextWindowModeId(id) {
1224
- if (!id) return null;
1225
- if (isContextWindowModeId(id)) return id;
1226
- return DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES[id] ?? null;
1227
- }
1228
- function isDeprecatedContextWindowModeId(id) {
1229
- return Object.hasOwn(DEPRECATED_CONTEXT_WINDOW_MODE_ALIASES, id);
1230
- }
1231
- function isContextWindowModeSelectionId(id) {
1232
- return isContextWindowModeId(id) || isDeprecatedContextWindowModeId(id);
1233
- }
1234
- function getContextWindowMode(id) {
1235
- const normalized = normalizeContextWindowModeId(id);
1236
- if (!normalized) return null;
1237
- const mode = CONTEXT_WINDOW_MODES.find((m) => m.id === normalized);
1238
- return mode ? { ...mode, thresholds: { ...mode.thresholds } } : null;
1239
- }
1240
- function isContextWindowModeId(id) {
1241
- return CONTEXT_WINDOW_MODES.some((m) => m.id === id);
1134
+ var CHAT_MARKER_SOURCES = new Set(
1135
+ [...SESSION_MARKER_EVENT_TYPES].filter((type) => type !== "checkpoint")
1136
+ );
1137
+ function sessionEventToMarker(ev) {
1138
+ switch (ev.type) {
1139
+ case "compaction": {
1140
+ const before = (ev.before / 1e3).toFixed(0);
1141
+ const after = (ev.after / 1e3).toFixed(0);
1142
+ const level = ev.level ? ` (${ev.level})` : "";
1143
+ const reductions = ev.reductions && ev.reductions.length > 0 ? ` [${ev.reductions.map((r) => `${r.phase}: \u2212${r.saved}`).join(", ")}]` : "";
1144
+ return {
1145
+ ts: ev.ts,
1146
+ source: ev.type,
1147
+ level: "info",
1148
+ text: `\u27F2 context compacted${level}: ${before}K \u2192 ${after}K tokens${reductions}`
1149
+ };
1150
+ }
1151
+ case "error":
1152
+ return {
1153
+ ts: ev.ts,
1154
+ source: ev.type,
1155
+ level: "error",
1156
+ text: ev.phase ? `[${ev.phase}] ${ev.message}` : ev.message
1157
+ };
1158
+ case "provider_retry": {
1159
+ const secs = (ev.delayMs / 1e3).toFixed(ev.delayMs >= 1e3 ? 1 : 2);
1160
+ return {
1161
+ ts: ev.ts,
1162
+ source: ev.type,
1163
+ level: "warn",
1164
+ text: ev.status ? `\u27F3 retry ${ev.attempt} (HTTP ${ev.status}) after ${secs}s \u2014 ${ev.description}` : `\u27F3 retry ${ev.attempt} after ${secs}s \u2014 ${ev.description}`
1165
+ };
1166
+ }
1167
+ case "provider_error":
1168
+ return {
1169
+ ts: ev.ts,
1170
+ source: ev.type,
1171
+ level: "error",
1172
+ text: ev.status ? `provider error (HTTP ${ev.status}, ${ev.retryable ? "retryable" : "fatal"}): ${ev.description}` : `provider error (${ev.retryable ? "retryable" : "fatal"}): ${ev.description}`
1173
+ };
1174
+ case "checkpoint":
1175
+ return {
1176
+ ts: ev.ts,
1177
+ source: ev.type,
1178
+ level: "info",
1179
+ text: `\u2713 checkpoint #${ev.promptIndex}: "${ev.promptPreview.slice(0, 60)}"`
1180
+ };
1181
+ case "agent_spawned":
1182
+ return {
1183
+ ts: ev.ts,
1184
+ source: ev.type,
1185
+ level: "info",
1186
+ text: `spawned as ${ev.role}`,
1187
+ agentId: ev.agentId
1188
+ };
1189
+ case "agent_stopped":
1190
+ return {
1191
+ ts: ev.ts,
1192
+ source: ev.type,
1193
+ level: "info",
1194
+ text: "stopped",
1195
+ agentId: ev.agentId
1196
+ };
1197
+ case "agent_error":
1198
+ return {
1199
+ ts: ev.ts,
1200
+ source: ev.type,
1201
+ level: "error",
1202
+ text: `error: ${ev.error.slice(0, 80)}`,
1203
+ agentId: ev.agentId
1204
+ };
1205
+ case "mode_changed":
1206
+ return {
1207
+ ts: ev.ts,
1208
+ source: ev.type,
1209
+ level: "info",
1210
+ text: `mode: ${ev.from} \u2192 ${ev.to}`
1211
+ };
1212
+ case "skill_activated":
1213
+ return {
1214
+ ts: ev.ts,
1215
+ source: ev.type,
1216
+ level: "info",
1217
+ text: `skill activated: ${ev.skillName}`
1218
+ };
1219
+ case "skill_deactivated":
1220
+ return {
1221
+ ts: ev.ts,
1222
+ source: ev.type,
1223
+ level: "info",
1224
+ text: `skill deactivated: ${ev.skillName}`
1225
+ };
1226
+ case "message_truncated":
1227
+ return {
1228
+ ts: ev.ts,
1229
+ source: ev.type,
1230
+ level: "warn",
1231
+ text: ev.after < ev.before ? `message truncated: ${ev.before} \u2192 ${ev.after} tokens` : `message truncated at ${ev.after} tokens`
1232
+ };
1233
+ default:
1234
+ return null;
1235
+ }
1242
1236
  }
1243
- function resolveContextWindowPolicy(config = {}, overrideMode) {
1244
- const requested = overrideMode ?? config.mode ?? DEFAULT_CONTEXT_WINDOW_MODE_ID;
1245
- const mode = getContextWindowMode(requested) ?? expectDefined(getContextWindowMode(DEFAULT_CONTEXT_WINDOW_MODE_ID));
1246
- return {
1247
- ...mode,
1248
- thresholds: {
1249
- warn: config.warnThreshold ?? mode.thresholds.warn,
1250
- soft: config.softThreshold ?? mode.thresholds.soft,
1251
- hard: config.hardThreshold ?? mode.thresholds.hard
1252
- },
1253
- preserveK: config.preserveK ?? mode.preserveK,
1254
- eliseThreshold: config.eliseThreshold ?? mode.eliseThreshold,
1255
- targetLoad: config.targetLoad ?? mode.targetLoad
1256
- };
1237
+ function projectSessionMarkers(events, sources = SESSION_MARKER_EVENT_TYPES) {
1238
+ const markers = [];
1239
+ for (const ev of events) {
1240
+ if (!sources.has(ev.type)) continue;
1241
+ const marker = sessionEventToMarker(ev);
1242
+ if (marker) markers.push(marker);
1243
+ }
1244
+ return markers;
1257
1245
  }
1258
- function formatContextWindowModeList(activeId) {
1259
- const active = normalizeContextWindowModeId(activeId);
1260
- return CONTEXT_WINDOW_MODES.map((m) => {
1261
- const marker = m.id === active ? "*" : " ";
1262
- return `${marker} ${m.id.padEnd(9)} ${m.name} - ${m.description}`;
1263
- }).join("\n");
1246
+ var SYSTEM_INJECTION_PREFIXES = [
1247
+ "[MAILBOX]",
1248
+ "[MAILBOX BTW]",
1249
+ "[BY THE WAY \u2014",
1250
+ "[QUEUED MESSAGES \u2014",
1251
+ "[FLEET PULSE]",
1252
+ "[loop-detector]",
1253
+ "[SESSION RESUME FILE VALIDATION]",
1254
+ "[SESSION RESUME INTERRUPTED WORK]"
1255
+ ];
1256
+ function isSystemInjectedMessage(text) {
1257
+ const trimmed = text.trimStart();
1258
+ for (const prefix of SYSTEM_INJECTION_PREFIXES) {
1259
+ if (trimmed.startsWith(prefix)) return true;
1260
+ }
1261
+ return false;
1264
1262
  }
1265
1263
 
1266
1264
  // src/types/spec.ts
@@ -1288,6 +1286,27 @@ var DEFAULT_SPEC_TEMPLATE = {
1288
1286
  }
1289
1287
  ]
1290
1288
  };
1289
+
1290
+ // src/types/system-prompt.ts
1291
+ function flattenSystemPromptRegions(regions) {
1292
+ return [...regions.core, ...regions.session, ...regions.volatile];
1293
+ }
1294
+
1295
+ // src/types/tool.ts
1296
+ var ToolErrorCategory = /* @__PURE__ */ ((ToolErrorCategory2) => {
1297
+ ToolErrorCategory2["TRANSIENT"] = "transient";
1298
+ ToolErrorCategory2["NOT_FOUND"] = "not_found";
1299
+ ToolErrorCategory2["PERMISSION"] = "permission";
1300
+ ToolErrorCategory2["VALIDATION"] = "validation";
1301
+ ToolErrorCategory2["FATAL"] = "fatal";
1302
+ return ToolErrorCategory2;
1303
+ })(ToolErrorCategory || {});
1304
+
1305
+ // src/types/tool-executor.ts
1306
+ var GOVERNED_TOOL_EXECUTOR_META_KEY = "toolExecutor.executeGoverned";
1307
+
1308
+ // src/types/tool-markers.ts
1309
+ var MALFORMED_ARG_MARKERS = ["__raw", "__raw_arguments", "_raw"];
1291
1310
  export {
1292
1311
  AgentError,
1293
1312
  BUILTIN_PROMPT_CATEGORIES,
@@ -1321,6 +1340,7 @@ export {
1321
1340
  PluginError,
1322
1341
  ProviderError,
1323
1342
  SESSION_MARKER_EVENT_TYPES,
1343
+ SYSTEM_INJECTION_PREFIXES,
1324
1344
  SddError,
1325
1345
  SessionError,
1326
1346
  StreamHangError,
@@ -1353,6 +1373,7 @@ export {
1353
1373
  isRetryableKind,
1354
1374
  isSddError,
1355
1375
  isSessionError,
1376
+ isSystemInjectedMessage,
1356
1377
  isTextBlock,
1357
1378
  isToolError,
1358
1379
  isToolResultBlock,