@alisio/core 0.1.0-alpha.8 → 0.1.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 (189) hide show
  1. package/README.md +52 -7
  2. package/dist/agents/active.d.ts +99 -0
  3. package/dist/agents/active.js +218 -0
  4. package/dist/agents/capabilities.d.ts +26 -0
  5. package/dist/agents/capabilities.js +120 -0
  6. package/dist/agents/create-agent-skill.d.ts +11 -0
  7. package/dist/agents/create-agent-skill.js +60 -0
  8. package/dist/agents/definitions.d.ts +88 -0
  9. package/dist/agents/definitions.js +404 -0
  10. package/dist/agents/draft.d.ts +41 -0
  11. package/dist/agents/draft.js +133 -0
  12. package/dist/agents/service.d.ts +57 -0
  13. package/dist/agents/service.js +86 -0
  14. package/dist/agents/templates.d.ts +8 -0
  15. package/dist/agents/templates.js +102 -0
  16. package/dist/analysis/capabilities.d.ts +48 -0
  17. package/dist/analysis/capabilities.js +90 -0
  18. package/dist/analysis/data/csv.d.ts +46 -0
  19. package/dist/analysis/data/csv.js +240 -0
  20. package/dist/analysis/data/datasets.d.ts +132 -0
  21. package/dist/analysis/data/datasets.js +441 -0
  22. package/dist/analysis/data/describe.d.ts +27 -0
  23. package/dist/analysis/data/describe.js +103 -0
  24. package/dist/analysis/data/engine-client.d.ts +58 -0
  25. package/dist/analysis/data/engine-client.js +304 -0
  26. package/dist/analysis/data/engine-entry.d.ts +1 -0
  27. package/dist/analysis/data/engine-entry.js +59 -0
  28. package/dist/analysis/data/engine-source.d.ts +4 -0
  29. package/dist/analysis/data/engine-source.js +6 -0
  30. package/dist/analysis/data/engine-types.d.ts +86 -0
  31. package/dist/analysis/data/engine-types.js +7 -0
  32. package/dist/analysis/data/infer.d.ts +42 -0
  33. package/dist/analysis/data/infer.js +118 -0
  34. package/dist/analysis/data/ingest-worker.d.ts +17 -0
  35. package/dist/analysis/data/ingest-worker.js +365 -0
  36. package/dist/analysis/data/json.d.ts +19 -0
  37. package/dist/analysis/data/json.js +44 -0
  38. package/dist/analysis/data/query-worker.d.ts +12 -0
  39. package/dist/analysis/data/query-worker.js +75 -0
  40. package/dist/analysis/data/rows.d.ts +39 -0
  41. package/dist/analysis/data/rows.js +120 -0
  42. package/dist/analysis/data/sql-guard.d.ts +20 -0
  43. package/dist/analysis/data/sql-guard.js +129 -0
  44. package/dist/analysis/data/stats.d.ts +18 -0
  45. package/dist/analysis/data/stats.js +77 -0
  46. package/dist/analysis/install-hints.d.ts +33 -0
  47. package/dist/analysis/install-hints.js +144 -0
  48. package/dist/analysis/janitor.d.ts +60 -0
  49. package/dist/analysis/janitor.js +264 -0
  50. package/dist/analysis/jobs.d.ts +94 -0
  51. package/dist/analysis/jobs.js +165 -0
  52. package/dist/analysis/oci.d.ts +129 -0
  53. package/dist/analysis/oci.js +330 -0
  54. package/dist/analysis/python/sources.d.ts +2 -0
  55. package/dist/analysis/python/sources.js +10 -0
  56. package/dist/analysis/requirements.d.ts +32 -0
  57. package/dist/analysis/requirements.js +73 -0
  58. package/dist/analysis/rerun.d.ts +40 -0
  59. package/dist/analysis/rerun.js +136 -0
  60. package/dist/analysis/runtime-manager.d.ts +146 -0
  61. package/dist/analysis/runtime-manager.js +472 -0
  62. package/dist/analysis/status.d.ts +21 -0
  63. package/dist/analysis/status.js +52 -0
  64. package/dist/application.d.ts +118 -3
  65. package/dist/application.js +510 -19
  66. package/dist/artifacts/kinds.d.ts +35 -0
  67. package/dist/artifacts/kinds.js +177 -0
  68. package/dist/artifacts/publisher.d.ts +7 -0
  69. package/dist/artifacts/publisher.js +29 -0
  70. package/dist/artifacts/store.d.ts +119 -0
  71. package/dist/artifacts/store.js +581 -0
  72. package/dist/background/janitor.d.ts +22 -0
  73. package/dist/background/janitor.js +62 -0
  74. package/dist/background/mirror.d.ts +14 -0
  75. package/dist/background/mirror.js +41 -0
  76. package/dist/background/notify.d.ts +58 -0
  77. package/dist/background/notify.js +172 -0
  78. package/dist/background/output.d.ts +46 -0
  79. package/dist/background/output.js +179 -0
  80. package/dist/background/service.d.ts +137 -0
  81. package/dist/background/service.js +410 -0
  82. package/dist/background/store.d.ts +103 -0
  83. package/dist/background/store.js +195 -0
  84. package/dist/changelog/data.d.ts +6 -0
  85. package/dist/changelog/data.js +293 -0
  86. package/dist/changelog/index.d.ts +5 -0
  87. package/dist/changelog/index.js +7 -0
  88. package/dist/changelog/parse.d.ts +53 -0
  89. package/dist/changelog/parse.js +160 -0
  90. package/dist/commands/builtins.d.ts +10 -0
  91. package/dist/commands/builtins.js +161 -0
  92. package/dist/commands/catalog.d.ts +86 -0
  93. package/dist/commands/catalog.js +304 -0
  94. package/dist/config.d.ts +252 -5
  95. package/dist/config.js +514 -13
  96. package/dist/core/compaction.js +13 -2
  97. package/dist/core/contracts.d.ts +180 -3
  98. package/dist/core/opt-in.d.ts +12 -0
  99. package/dist/core/opt-in.js +12 -0
  100. package/dist/core/output-limit.d.ts +34 -0
  101. package/dist/core/output-limit.js +39 -0
  102. package/dist/core/run-stats.d.ts +16 -0
  103. package/dist/core/run-stats.js +8 -0
  104. package/dist/core/runner.d.ts +152 -4
  105. package/dist/core/runner.js +792 -138
  106. package/dist/core/timeout.d.ts +15 -0
  107. package/dist/core/timeout.js +61 -0
  108. package/dist/core/truncation.d.ts +30 -0
  109. package/dist/core/truncation.js +83 -0
  110. package/dist/goal/blockers.d.ts +45 -0
  111. package/dist/goal/blockers.js +51 -0
  112. package/dist/goal/budget.d.ts +24 -0
  113. package/dist/goal/budget.js +53 -0
  114. package/dist/goal/command.d.ts +36 -0
  115. package/dist/goal/command.js +98 -0
  116. package/dist/goal/format.d.ts +19 -0
  117. package/dist/goal/format.js +102 -0
  118. package/dist/goal/host.d.ts +29 -0
  119. package/dist/goal/host.js +42 -0
  120. package/dist/goal/index.d.ts +9 -0
  121. package/dist/goal/index.js +9 -0
  122. package/dist/goal/machine.d.ts +186 -0
  123. package/dist/goal/machine.js +344 -0
  124. package/dist/goal/prompts.d.ts +10 -0
  125. package/dist/goal/prompts.js +75 -0
  126. package/dist/goal/service.d.ts +113 -0
  127. package/dist/goal/service.js +273 -0
  128. package/dist/goal/store.d.ts +59 -0
  129. package/dist/goal/store.js +184 -0
  130. package/dist/index.d.ts +51 -6
  131. package/dist/index.js +49 -4
  132. package/dist/mcp/connector.js +38 -6
  133. package/dist/mcp/rich.d.ts +41 -0
  134. package/dist/mcp/rich.js +362 -0
  135. package/dist/permissions/modes.d.ts +72 -0
  136. package/dist/permissions/modes.js +98 -0
  137. package/dist/plan/exit-plan.d.ts +25 -0
  138. package/dist/plan/exit-plan.js +130 -0
  139. package/dist/plan/state.d.ts +102 -0
  140. package/dist/plan/state.js +165 -0
  141. package/dist/plugins/host.d.ts +39 -1
  142. package/dist/plugins/host.js +150 -9
  143. package/dist/providers/settings.d.ts +15 -0
  144. package/dist/providers/settings.js +38 -0
  145. package/dist/reload.d.ts +75 -0
  146. package/dist/reload.js +204 -0
  147. package/dist/resources/context.d.ts +5 -0
  148. package/dist/resources/context.js +13 -1
  149. package/dist/runtime/access.d.ts +62 -0
  150. package/dist/runtime/access.js +115 -0
  151. package/dist/runtime/blobs.d.ts +51 -0
  152. package/dist/runtime/blobs.js +177 -0
  153. package/dist/runtime/diff.d.ts +23 -0
  154. package/dist/runtime/diff.js +154 -0
  155. package/dist/runtime/ids.d.ts +8 -0
  156. package/dist/runtime/ids.js +32 -0
  157. package/dist/runtime/paths.d.ts +11 -0
  158. package/dist/runtime/paths.js +17 -1
  159. package/dist/runtime/process.d.ts +22 -0
  160. package/dist/runtime/process.js +100 -15
  161. package/dist/runtime/sqlite.d.ts +2 -0
  162. package/dist/runtime/sqlite.js +18 -0
  163. package/dist/runtime/store.d.ts +91 -3
  164. package/dist/runtime/store.js +465 -11
  165. package/dist/runtime/zip.d.ts +24 -0
  166. package/dist/runtime/zip.js +126 -0
  167. package/dist/sessions/children.js +17 -1
  168. package/dist/sessions/side-questions.d.ts +57 -0
  169. package/dist/sessions/side-questions.js +161 -0
  170. package/dist/startup/screen.js +6 -5
  171. package/dist/tools/analysis.d.ts +37 -0
  172. package/dist/tools/analysis.js +573 -0
  173. package/dist/tools/artifacts.d.ts +14 -0
  174. package/dist/tools/artifacts.js +143 -0
  175. package/dist/tools/background.d.ts +7 -0
  176. package/dist/tools/background.js +165 -0
  177. package/dist/tools/data.d.ts +7 -0
  178. package/dist/tools/data.js +160 -0
  179. package/dist/tools/execute.d.ts +5 -0
  180. package/dist/tools/execute.js +15 -3
  181. package/dist/tools/goal.d.ts +19 -0
  182. package/dist/tools/goal.js +126 -0
  183. package/dist/tools/search.d.ts +17 -3
  184. package/dist/tools/search.js +153 -0
  185. package/dist/tools/standard.d.ts +4 -1
  186. package/dist/tools/standard.js +99 -18
  187. package/dist/version.d.ts +5 -3
  188. package/dist/version.js +35 -6
  189. package/package.json +2 -2
@@ -0,0 +1,304 @@
1
+ import { agentCatalogFromState, agentCommandDescriptors, resolveActiveAgent, } from "../agents/active.js";
2
+ import { formatSideQuestion, SIDE_QUESTION_DESCRIPTION, SIDE_QUESTION_USAGE, } from "../sessions/side-questions.js";
3
+ import { BUILTIN_COMMANDS } from "./builtins.js";
4
+ export { BUILTIN_COMMANDS };
5
+ const builtinDescriptor = (c) => ({
6
+ name: c.name,
7
+ description: c.description,
8
+ ...(c.aliases ? { aliases: [...c.aliases] } : {}),
9
+ ...(c.argumentHint ? { argumentHint: c.argumentHint } : {}),
10
+ source: "builtin",
11
+ surfaces: [...c.surfaces],
12
+ execution: c.execution,
13
+ });
14
+ const ALL = ["tui", "web", "api"];
15
+ /** Root sessions of this workspace bound to the current provider, newest first (as the TUI). */
16
+ const workspaceSessions = (host) => host.store
17
+ .list()
18
+ .filter((s) => s.workspace === host.workspace && s.provider === host.provider.id);
19
+ const firstPrompt = (host, id) => {
20
+ const first = host.store.messages(id).find((m) => m.role === "user" && !m.summary);
21
+ return first?.role === "user" ? first.text.replace(/\s+/g, " ").slice(0, 60) : "";
22
+ };
23
+ const HANDLERS = {
24
+ async tools(_args, _ctx, host) {
25
+ const policy = host.runner.policy;
26
+ const rows = host.registry
27
+ .list()
28
+ .map((t) => {
29
+ const effect = t.effect ?? "external";
30
+ const state = effect === "read" || effect === "internal" || policy[effect]
31
+ ? "enabled"
32
+ : host.runner.approvals && (effect === "write" || effect === "process")
33
+ ? "ask"
34
+ : "disabled";
35
+ return `| \`${t.name}\` | ${effect} | ${state} |`;
36
+ })
37
+ .join("\n");
38
+ return {
39
+ text: `**Tools**\n\n| Tool | Effect | State |\n| --- | --- | --- |\n${rows}\n\n\`ask\` prompts before running (allow once / session / deny). Use --allow-write / --allow-process to pre-allow; --read-only disables them. Paths outside the workspace ask per directory; pre-allow with --add-dir or the \`additionalDirectories\` config key. \`internal\` tools (built-in plugins) only write Alisio's own state.`,
40
+ };
41
+ },
42
+ async sessions(_args, ctx, host) {
43
+ const list = workspaceSessions(host).slice(0, 20);
44
+ if (!list.length)
45
+ return { text: "No sessions in this workspace", tone: "notice" };
46
+ return {
47
+ text: [
48
+ "**Recent sessions** (use `/resume <id-prefix>`)",
49
+ "",
50
+ ...list.map((s) => `- \`${s.id}\` ${s.id === ctx.sessionId ? "**(current)** " : ""}${s.model} · ${host.store.messages(s.id).length} msgs · ${firstPrompt(host, s.id) || "_empty_"}`),
51
+ ].join("\n"),
52
+ data: list,
53
+ };
54
+ },
55
+ async resume(args, _ctx, host) {
56
+ const target = args.trim();
57
+ if (!target)
58
+ throw new Error("Usage: /resume <id>");
59
+ const matches = workspaceSessions(host).filter((s) => s.id.startsWith(target));
60
+ if (matches.length !== 1)
61
+ throw new Error(matches.length
62
+ ? `Ambiguous session prefix: ${target}`
63
+ : `No session in this workspace matches ${target}`);
64
+ const found = matches[0];
65
+ return { text: `Resumed session ${found.id}`, tone: "notice", sessionId: found.id };
66
+ },
67
+ async clear(_args, ctx, host) {
68
+ const model = host.store.get(ctx.sessionId).model;
69
+ const created = host.store.create(host.workspace, host.provider.id, model);
70
+ return { text: `New session ${created.id}`, tone: "notice", sessionId: created.id };
71
+ },
72
+ async compact(args, ctx, host) {
73
+ const result = await host.runner.compact(ctx.sessionId, {
74
+ ...(args.trim() ? { focus: args.trim() } : {}),
75
+ ...(ctx.signal ? { signal: ctx.signal } : {}),
76
+ });
77
+ return result
78
+ ? {
79
+ text: `Compacted ${result.replaced} messages: ~${result.before} → ~${result.after} tokens`,
80
+ tone: "notice",
81
+ data: result,
82
+ }
83
+ : { text: "Not enough history to compact", tone: "notice" };
84
+ },
85
+ async model(args, ctx, host) {
86
+ const model = args.trim();
87
+ if (!model)
88
+ throw new Error("Usage: /model <model id>");
89
+ host.runner.setModel(ctx.sessionId, model);
90
+ return { text: `Model set to \`${model}\``, tone: "notice", data: { model } };
91
+ },
92
+ async effort(args, _ctx, host) {
93
+ const level = args.trim();
94
+ if (!level)
95
+ return {
96
+ text: `Reasoning effort: ${host.config?.agents.effort ?? "model default"}`,
97
+ tone: "notice",
98
+ };
99
+ if (!host.updateSetting)
100
+ throw new Error("Effort changes are unavailable here");
101
+ const value = level === "!clear" ? undefined : level;
102
+ await host.updateSetting("agents.effort", value);
103
+ return {
104
+ text: value ? `Reasoning effort set to ${value}` : "Reasoning effort cleared",
105
+ tone: "notice",
106
+ data: { effort: value },
107
+ };
108
+ },
109
+ async stats(_args, ctx, host) {
110
+ const session = host.store.get(ctx.sessionId);
111
+ const runs = host.store.runs?.(ctx.sessionId) ?? [];
112
+ const tokens = runs.reduce((sum, r) => ({
113
+ input: sum.input + (r.usage?.input ?? 0),
114
+ output: sum.output + (r.usage?.output ?? 0),
115
+ }), { input: 0, output: 0 });
116
+ return {
117
+ text: [
118
+ "**Session statistics**",
119
+ "",
120
+ `- Session: \`${session.id}\``,
121
+ `- Model: \`${session.model}\``,
122
+ `- Messages: ${host.store.messages(session.id).length}`,
123
+ `- Runs: ${runs.length}`,
124
+ `- Tokens: in ${tokens.input} · out ${tokens.output}`,
125
+ ].join("\n"),
126
+ data: { session, runs: runs.length, tokens },
127
+ };
128
+ },
129
+ async skills(_args, _ctx, host) {
130
+ const skills = host.skillCatalog?.() ?? [];
131
+ if (!skills.length)
132
+ return { text: "No skills found", tone: "notice" };
133
+ const state = (s) => s.effective ? "enabled" : s.shadowedBy ? `shadowed by ${s.shadowedBy}` : "disabled";
134
+ return {
135
+ text: `**Skills**\n\n| Skill | Scope | State |\n| --- | --- | --- |\n${skills
136
+ .map((s) => `| \`${s.displayId}\` | ${s.scope} | ${state(s)} |`)
137
+ .join("\n")}`,
138
+ data: skills,
139
+ };
140
+ },
141
+ async plugins(_args, _ctx, host) {
142
+ const plugins = host.pluginCatalog?.() ?? [];
143
+ if (!plugins.length)
144
+ return { text: "No plugins loaded", tone: "notice" };
145
+ return {
146
+ text: `**Plugins**\n\n| Plugin | Status | Enabled |\n| --- | --- | --- |\n${plugins
147
+ .map((p) => `| \`${p.id}\` | ${p.status} | ${p.enabled ? "yes" : "no"} |`)
148
+ .join("\n")}`,
149
+ data: plugins,
150
+ };
151
+ },
152
+ async mcps(_args, _ctx, host) {
153
+ const servers = host.mcp?.list() ?? [];
154
+ if (!servers.length)
155
+ return { text: "No MCP servers configured", tone: "notice" };
156
+ return {
157
+ text: `**MCP servers**\n\n| Server | Status | Tools |\n| --- | --- | --- |\n${servers
158
+ .map((s) => `| \`${s.name}\` | ${s.status} | ${s.counts.tools} |`)
159
+ .join("\n")}`,
160
+ data: servers,
161
+ };
162
+ },
163
+ async btw(args, ctx, host) {
164
+ const question = args.trim();
165
+ const side = host.sideQuestions;
166
+ if (!question) {
167
+ const history = side?.history(ctx.sessionId) ?? [];
168
+ const latest = history.at(-1);
169
+ if (!latest)
170
+ return {
171
+ text: `${SIDE_QUESTION_USAGE}\n${SIDE_QUESTION_DESCRIPTION}`,
172
+ tone: "notice",
173
+ data: { history },
174
+ };
175
+ return {
176
+ text: formatSideQuestion(latest, history.length, history.length),
177
+ data: { history, entry: latest },
178
+ };
179
+ }
180
+ if (!side)
181
+ throw new Error("Side questions are unavailable here");
182
+ const entry = await side.ask(ctx.sessionId, question, ctx.signal ? { signal: ctx.signal } : {});
183
+ const total = side.history(ctx.sessionId).length;
184
+ return { text: formatSideQuestion(entry, total, total), data: { entry } };
185
+ },
186
+ async agents(args, ctx, host) {
187
+ // With arguments, `/agents <verb>` belongs to the subagents plugin's own command (as in the
188
+ // TUI); without them it lists the active-agent catalog.
189
+ const plugin = args.trim() ? host.plugins?.commands.get("agents") : undefined;
190
+ if (plugin)
191
+ return { text: await plugin(args.trim(), { sessionId: ctx.sessionId }) };
192
+ let state;
193
+ try {
194
+ state = host.plugins?.pluginState?.("subagents", "mainAgents");
195
+ }
196
+ catch {
197
+ /* agent contributions are best-effort */
198
+ }
199
+ const agents = agentCatalogFromState(state);
200
+ const active = resolveActiveAgent(agents, host.config?.agents.active);
201
+ return {
202
+ text: [
203
+ "**Agents**",
204
+ "",
205
+ ...agents.map((a) => `- **${a.name}**${a.id === active.id ? " (current)" : ""}${a.readOnly ? " · read-only" : ""} — ${a.description}`),
206
+ ].join("\n"),
207
+ data: { agents, active: active.id },
208
+ };
209
+ },
210
+ };
211
+ export class CommandCatalog {
212
+ host;
213
+ constructor(host) {
214
+ this.host = host;
215
+ }
216
+ builtins() {
217
+ return BUILTIN_COMMANDS.map(builtinDescriptor);
218
+ }
219
+ /** Every descriptor (optionally for one surface). Precedence: builtin > plugin > prompt > skill. */
220
+ list(surface) {
221
+ const out = this.builtins();
222
+ const taken = new Set(out.flatMap((c) => [c.name, ...(c.aliases ?? [])]));
223
+ const push = (descriptor) => {
224
+ if (taken.has(descriptor.name))
225
+ return;
226
+ taken.add(descriptor.name);
227
+ out.push(descriptor);
228
+ };
229
+ const host = this.host;
230
+ if (host?.plugins)
231
+ for (const [name, info] of host.plugins.commandInfo)
232
+ push({
233
+ name,
234
+ description: info.description ?? `plugin ${info.plugin}`,
235
+ ...(info.argumentHint ? { argumentHint: info.argumentHint } : {}),
236
+ source: "plugin",
237
+ owner: info.plugin,
238
+ surfaces: [...ALL],
239
+ execution: "core",
240
+ });
241
+ if (host?.prompts)
242
+ for (const template of host.prompts.templates.values())
243
+ push({
244
+ name: template.name,
245
+ description: template.description,
246
+ ...(template.argumentHint ? { argumentHint: template.argumentHint } : {}),
247
+ source: "prompt",
248
+ owner: template.source,
249
+ surfaces: [...ALL],
250
+ execution: "surface",
251
+ });
252
+ for (const skill of host?.skillCatalog?.() ?? [])
253
+ if (skill.effective && skill.enabled)
254
+ push({
255
+ name: `skill:${skill.id}`,
256
+ description: skill.description,
257
+ source: "skill",
258
+ ...(skill.owner ? { owner: skill.owner.id } : {}),
259
+ surfaces: [...ALL],
260
+ execution: "surface",
261
+ });
262
+ // `/agent:<id>` activates a loaded agent (built-ins, project and global agent files).
263
+ if (host?.plugins) {
264
+ let state;
265
+ try {
266
+ state = host.plugins.pluginState?.("subagents", "mainAgents");
267
+ }
268
+ catch {
269
+ /* agent contributions are best-effort */
270
+ }
271
+ for (const descriptor of agentCommandDescriptors(agentCatalogFromState(state), taken))
272
+ push(descriptor);
273
+ }
274
+ return surface ? out.filter((c) => c.surfaces.includes(surface)) : out;
275
+ }
276
+ /** A command by name or alias (built-in names and aliases are case-insensitive). */
277
+ resolve(name) {
278
+ const lower = name.toLowerCase();
279
+ const all = this.list();
280
+ return (all.find((c) => c.source === "builtin" && (c.name === lower || c.aliases?.includes(lower))) ??
281
+ all.find((c) => c.source !== "builtin" && c.name === name));
282
+ }
283
+ /** Runs an `execution: "core"` command. Surface commands and unknown names throw. */
284
+ async execute(name, args, ctx) {
285
+ const descriptor = this.resolve(name);
286
+ if (!descriptor)
287
+ throw new Error(`Unknown command /${name}. Type /help.`);
288
+ if (descriptor.execution !== "core")
289
+ throw new Error(`/${descriptor.name} is handled by each surface, not by the core catalog`);
290
+ const host = this.host;
291
+ if (!host)
292
+ throw new Error(`/${descriptor.name} needs an application host`);
293
+ if (descriptor.source === "plugin") {
294
+ const handler = host.plugins?.commands.get(descriptor.name);
295
+ if (!handler)
296
+ throw new Error(`Unknown plugin command: ${descriptor.name}`);
297
+ return { text: await handler(args, { sessionId: ctx.sessionId }) };
298
+ }
299
+ const handler = HANDLERS[descriptor.name];
300
+ if (!handler)
301
+ throw new Error(`/${descriptor.name} has no core handler`);
302
+ return handler(args, ctx, host);
303
+ }
304
+ }
package/dist/config.d.ts CHANGED
@@ -12,6 +12,11 @@ declare const serverSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
12
12
  url: z.ZodString;
13
13
  bearerTokenEnv: z.ZodOptional<z.ZodString>;
14
14
  }, z.core.$strict>], "transport">;
15
+ /**
16
+ * A container image reference pinned by digest. Anchored at the start with a letter or digit so a
17
+ * value can never be read as an option by the container CLI.
18
+ */
19
+ export declare const OCI_IMAGE_PATTERN: RegExp;
15
20
  export declare const configSchema: z.ZodPipe<z.ZodObject<{
16
21
  schemaVersion: z.ZodDefault<z.ZodLiteral<1>>;
17
22
  provider: z.ZodDefault<z.ZodObject<{
@@ -36,6 +41,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
36
41
  }, z.core.$strict>>;
37
42
  plugins: z.ZodDefault<z.ZodArray<z.ZodString>>;
38
43
  skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
44
+ additionalDirectories: z.ZodDefault<z.ZodArray<z.ZodString>>;
39
45
  skillOverrides: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
40
46
  enabled: z.ZodBoolean;
41
47
  }, z.core.$strict>>>;
@@ -155,6 +161,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
155
161
  websearch: z.ZodDefault<z.ZodObject<{
156
162
  provider: z.ZodOptional<z.ZodEnum<{
157
163
  brave: "brave";
164
+ "duckduckgo-html": "duckduckgo-html";
158
165
  "duckduckgo-instant": "duckduckgo-instant";
159
166
  native: "native";
160
167
  searxng: "searxng";
@@ -168,10 +175,71 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
168
175
  limits: z.ZodDefault<z.ZodObject<{
169
176
  maxTurns: z.ZodDefault<z.ZodNumber>;
170
177
  timeoutMs: z.ZodDefault<z.ZodNumber>;
178
+ firstTokenTimeoutMs: z.ZodDefault<z.ZodNumber>;
179
+ firstTokenRetries: z.ZodDefault<z.ZodNumber>;
180
+ truncationRecoveries: z.ZodDefault<z.ZodNumber>;
171
181
  maxContextChars: z.ZodDefault<z.ZodNumber>;
172
- maxOutputTokens: z.ZodDefault<z.ZodNumber>;
182
+ maxOutputTokens: z.ZodOptional<z.ZodNumber>;
173
183
  maxTokens: z.ZodOptional<z.ZodNumber>;
174
184
  }, z.core.$strip>>;
185
+ analysis: z.ZodDefault<z.ZodObject<{
186
+ enabled: z.ZodDefault<z.ZodBoolean>;
187
+ runtime: z.ZodDefault<z.ZodEnum<{
188
+ managed: "managed";
189
+ oci: "oci";
190
+ }>>;
191
+ oci: z.ZodDefault<z.ZodObject<{
192
+ engine: z.ZodDefault<z.ZodEnum<{
193
+ docker: "docker";
194
+ podman: "podman";
195
+ }>>;
196
+ image: z.ZodOptional<z.ZodString>;
197
+ memoryMb: z.ZodDefault<z.ZodNumber>;
198
+ cpus: z.ZodDefault<z.ZodNumber>;
199
+ }, z.core.$strict>>;
200
+ limits: z.ZodDefault<z.ZodObject<{
201
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
202
+ maxFiles: z.ZodDefault<z.ZodNumber>;
203
+ maxFileBytes: z.ZodDefault<z.ZodNumber>;
204
+ maxOutputBytes: z.ZodDefault<z.ZodNumber>;
205
+ maxLogBytes: z.ZodDefault<z.ZodNumber>;
206
+ }, z.core.$strict>>;
207
+ data: z.ZodDefault<z.ZodObject<{
208
+ maxUploadBytes: z.ZodDefault<z.ZodNumber>;
209
+ maxRows: z.ZodDefault<z.ZodNumber>;
210
+ queryTimeoutMs: z.ZodDefault<z.ZodNumber>;
211
+ maxInteractiveRows: z.ZodDefault<z.ZodNumber>;
212
+ }, z.core.$strict>>;
213
+ retention: z.ZodDefault<z.ZodObject<{
214
+ jobsDays: z.ZodDefault<z.ZodNumber>;
215
+ intermediateDays: z.ZodDefault<z.ZodNumber>;
216
+ artifactsDays: z.ZodDefault<z.ZodNumber>;
217
+ }, z.core.$strict>>;
218
+ }, z.core.$strict>>;
219
+ tasks: z.ZodDefault<z.ZodObject<{
220
+ enabled: z.ZodDefault<z.ZodBoolean>;
221
+ maxPerSession: z.ZodDefault<z.ZodNumber>;
222
+ maxRunMs: z.ZodDefault<z.ZodNumber>;
223
+ maxOutputBytes: z.ZodDefault<z.ZodNumber>;
224
+ retentionDays: z.ZodDefault<z.ZodNumber>;
225
+ }, z.core.$strict>>;
226
+ goal: z.ZodDefault<z.ZodObject<{
227
+ enabled: z.ZodDefault<z.ZodBoolean>;
228
+ maxTurns: z.ZodDefault<z.ZodNumber>;
229
+ maxMinutes: z.ZodDefault<z.ZodNumber>;
230
+ repeatedReplyLimit: z.ZodDefault<z.ZodNumber>;
231
+ noToolTurnsLimit: z.ZodDefault<z.ZodNumber>;
232
+ blockedRepeats: z.ZodDefault<z.ZodNumber>;
233
+ }, z.core.$strict>>;
234
+ tui: z.ZodDefault<z.ZodObject<{
235
+ paddingX: z.ZodDefault<z.ZodNumber>;
236
+ contentPaddingX: z.ZodDefault<z.ZodNumber>;
237
+ skillSlashCommands: z.ZodDefault<z.ZodBoolean>;
238
+ }, z.core.$strict>>;
239
+ agents: z.ZodDefault<z.ZodObject<{
240
+ active: z.ZodDefault<z.ZodString>;
241
+ effort: z.ZodOptional<z.ZodString>;
242
+ }, z.core.$strict>>;
175
243
  }, z.core.$strict>, z.ZodTransform<{
176
244
  schemaVersion: 1;
177
245
  provider: {
@@ -186,6 +254,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
186
254
  };
187
255
  plugins: string[];
188
256
  skills: string[];
257
+ additionalDirectories: string[];
189
258
  skillOverrides: Record<string, {
190
259
  enabled: boolean;
191
260
  }>;
@@ -211,7 +280,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
211
280
  maxOutputTokens: number;
212
281
  };
213
282
  websearch: {
214
- provider?: "brave" | "duckduckgo-instant" | "native" | "searxng" | "serpapi" | "tavily" | undefined;
283
+ provider?: "brave" | "duckduckgo-html" | "duckduckgo-instant" | "native" | "searxng" | "serpapi" | "tavily" | undefined;
215
284
  searxngUrl?: string | undefined;
216
285
  apiKeyEnv?: string | undefined;
217
286
  nativeToolType: string;
@@ -219,10 +288,65 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
219
288
  limits: {
220
289
  maxTurns: number;
221
290
  timeoutMs: number;
291
+ firstTokenTimeoutMs: number;
292
+ firstTokenRetries: number;
293
+ truncationRecoveries: number;
222
294
  maxContextChars: number;
223
- maxOutputTokens: number;
295
+ maxOutputTokens?: number | undefined;
224
296
  maxTokens?: number | undefined;
225
297
  };
298
+ analysis: {
299
+ enabled: boolean;
300
+ runtime: "managed" | "oci";
301
+ oci: {
302
+ engine: "docker" | "podman";
303
+ image?: string | undefined;
304
+ memoryMb: number;
305
+ cpus: number;
306
+ };
307
+ limits: {
308
+ timeoutMs: number;
309
+ maxFiles: number;
310
+ maxFileBytes: number;
311
+ maxOutputBytes: number;
312
+ maxLogBytes: number;
313
+ };
314
+ data: {
315
+ maxUploadBytes: number;
316
+ maxRows: number;
317
+ queryTimeoutMs: number;
318
+ maxInteractiveRows: number;
319
+ };
320
+ retention: {
321
+ jobsDays: number;
322
+ intermediateDays: number;
323
+ artifactsDays: number;
324
+ };
325
+ };
326
+ tasks: {
327
+ enabled: boolean;
328
+ maxPerSession: number;
329
+ maxRunMs: number;
330
+ maxOutputBytes: number;
331
+ retentionDays: number;
332
+ };
333
+ goal: {
334
+ enabled: boolean;
335
+ maxTurns: number;
336
+ maxMinutes: number;
337
+ repeatedReplyLimit: number;
338
+ noToolTurnsLimit: number;
339
+ blockedRepeats: number;
340
+ };
341
+ tui: {
342
+ paddingX: number;
343
+ contentPaddingX: number;
344
+ skillSlashCommands: boolean;
345
+ };
346
+ agents: {
347
+ active: string;
348
+ effort?: string | undefined;
349
+ };
226
350
  mcp: {
227
351
  allow?: boolean | undefined;
228
352
  servers: {
@@ -267,6 +391,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
267
391
  };
268
392
  plugins: string[];
269
393
  skills: string[];
394
+ additionalDirectories: string[];
270
395
  skillOverrides: Record<string, {
271
396
  enabled: boolean;
272
397
  }>;
@@ -345,7 +470,7 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
345
470
  maxOutputTokens: number;
346
471
  };
347
472
  websearch: {
348
- provider?: "brave" | "duckduckgo-instant" | "native" | "searxng" | "serpapi" | "tavily" | undefined;
473
+ provider?: "brave" | "duckduckgo-html" | "duckduckgo-instant" | "native" | "searxng" | "serpapi" | "tavily" | undefined;
349
474
  searxngUrl?: string | undefined;
350
475
  apiKeyEnv?: string | undefined;
351
476
  nativeToolType: string;
@@ -353,10 +478,65 @@ export declare const configSchema: z.ZodPipe<z.ZodObject<{
353
478
  limits: {
354
479
  maxTurns: number;
355
480
  timeoutMs: number;
481
+ firstTokenTimeoutMs: number;
482
+ firstTokenRetries: number;
483
+ truncationRecoveries: number;
356
484
  maxContextChars: number;
357
- maxOutputTokens: number;
485
+ maxOutputTokens?: number | undefined;
358
486
  maxTokens?: number | undefined;
359
487
  };
488
+ analysis: {
489
+ enabled: boolean;
490
+ runtime: "managed" | "oci";
491
+ oci: {
492
+ engine: "docker" | "podman";
493
+ image?: string | undefined;
494
+ memoryMb: number;
495
+ cpus: number;
496
+ };
497
+ limits: {
498
+ timeoutMs: number;
499
+ maxFiles: number;
500
+ maxFileBytes: number;
501
+ maxOutputBytes: number;
502
+ maxLogBytes: number;
503
+ };
504
+ data: {
505
+ maxUploadBytes: number;
506
+ maxRows: number;
507
+ queryTimeoutMs: number;
508
+ maxInteractiveRows: number;
509
+ };
510
+ retention: {
511
+ jobsDays: number;
512
+ intermediateDays: number;
513
+ artifactsDays: number;
514
+ };
515
+ };
516
+ tasks: {
517
+ enabled: boolean;
518
+ maxPerSession: number;
519
+ maxRunMs: number;
520
+ maxOutputBytes: number;
521
+ retentionDays: number;
522
+ };
523
+ goal: {
524
+ enabled: boolean;
525
+ maxTurns: number;
526
+ maxMinutes: number;
527
+ repeatedReplyLimit: number;
528
+ noToolTurnsLimit: number;
529
+ blockedRepeats: number;
530
+ };
531
+ tui: {
532
+ paddingX: number;
533
+ contentPaddingX: number;
534
+ skillSlashCommands: boolean;
535
+ };
536
+ agents: {
537
+ active: string;
538
+ effort?: string | undefined;
539
+ };
360
540
  }>>;
361
541
  export type Config = z.infer<typeof configSchema>;
362
542
  export type ServerConfig = z.infer<typeof serverSchema>;
@@ -374,6 +554,8 @@ export interface ConfigProvenance {
374
554
  kind: "project" | "explicit";
375
555
  hasLegacyProvider: boolean;
376
556
  };
557
+ /** Keys a project or explicit layer set that only the global layer may decide (ignored). */
558
+ ignored?: string[];
377
559
  }
378
560
  export interface ConfigLoadResult {
379
561
  config: LoadedConfig;
@@ -416,6 +598,71 @@ export declare function setMcpServerEnabled(input: {
416
598
  export declare function setGlobalMcpAllow(input: {
417
599
  allow: boolean;
418
600
  }): Promise<string>;
601
+ declare const SETTABLE_KEYS: {
602
+ readonly "compaction.auto": z.ZodDefault<z.ZodBoolean>;
603
+ readonly "compaction.threshold": z.ZodDefault<z.ZodNumber>;
604
+ readonly "compaction.keepTurns": z.ZodDefault<z.ZodNumber>;
605
+ readonly "compaction.maxOutputTokens": z.ZodDefault<z.ZodNumber>;
606
+ readonly "context.claudeMdFallback": z.ZodDefault<z.ZodBoolean>;
607
+ readonly "context.maxBytes": z.ZodDefault<z.ZodNumber>;
608
+ readonly "limits.maxTurns": z.ZodDefault<z.ZodNumber>;
609
+ readonly "limits.maxOutputTokens": z.ZodOptional<z.ZodNumber>;
610
+ readonly "limits.maxContextChars": z.ZodDefault<z.ZodNumber>;
611
+ readonly "limits.timeoutMs": z.ZodDefault<z.ZodNumber>;
612
+ readonly "limits.firstTokenTimeoutMs": z.ZodDefault<z.ZodNumber>;
613
+ readonly "limits.firstTokenRetries": z.ZodDefault<z.ZodNumber>;
614
+ readonly "limits.truncationRecoveries": z.ZodDefault<z.ZodNumber>;
615
+ readonly "pluginHooks.timeoutMs": z.ZodDefault<z.ZodNumber>;
616
+ readonly "tui.paddingX": z.ZodDefault<z.ZodNumber>;
617
+ readonly "tui.contentPaddingX": z.ZodDefault<z.ZodNumber>;
618
+ readonly "tui.skillSlashCommands": z.ZodDefault<z.ZodBoolean>;
619
+ readonly "websearch.provider": z.ZodOptional<z.ZodEnum<{
620
+ brave: "brave";
621
+ "duckduckgo-html": "duckduckgo-html";
622
+ "duckduckgo-instant": "duckduckgo-instant";
623
+ native: "native";
624
+ searxng: "searxng";
625
+ serpapi: "serpapi";
626
+ tavily: "tavily";
627
+ }>>;
628
+ readonly "agents.active": z.ZodDefault<z.ZodString>;
629
+ readonly "agents.effort": z.ZodOptional<z.ZodString>;
630
+ readonly "analysis.enabled": z.ZodDefault<z.ZodBoolean>;
631
+ readonly "analysis.limits.timeoutMs": z.ZodDefault<z.ZodNumber>;
632
+ readonly "analysis.retention.jobsDays": z.ZodDefault<z.ZodNumber>;
633
+ readonly "analysis.retention.intermediateDays": z.ZodDefault<z.ZodNumber>;
634
+ readonly "analysis.retention.artifactsDays": z.ZodDefault<z.ZodNumber>;
635
+ readonly "tasks.enabled": z.ZodDefault<z.ZodBoolean>;
636
+ readonly "tasks.maxPerSession": z.ZodDefault<z.ZodNumber>;
637
+ readonly "tasks.maxRunMs": z.ZodDefault<z.ZodNumber>;
638
+ readonly "tasks.maxOutputBytes": z.ZodDefault<z.ZodNumber>;
639
+ readonly "tasks.retentionDays": z.ZodDefault<z.ZodNumber>;
640
+ readonly "goal.enabled": z.ZodDefault<z.ZodBoolean>;
641
+ readonly "goal.maxTurns": z.ZodDefault<z.ZodNumber>;
642
+ readonly "goal.maxMinutes": z.ZodDefault<z.ZodNumber>;
643
+ readonly "goal.repeatedReplyLimit": z.ZodDefault<z.ZodNumber>;
644
+ readonly "goal.noToolTurnsLimit": z.ZodDefault<z.ZodNumber>;
645
+ readonly "goal.blockedRepeats": z.ZodDefault<z.ZodNumber>;
646
+ };
647
+ export type SettableSettingKey = keyof typeof SETTABLE_KEYS;
648
+ export declare function isSettableSettingKey(key: string): key is SettableSettingKey;
649
+ export interface SettableSettingInfo {
650
+ key: SettableSettingKey;
651
+ kind: "boolean" | "number" | "string" | "enum";
652
+ options?: string[];
653
+ }
654
+ /** Every settable key with its value kind (and enum options), for settings editors. */
655
+ export declare function settableSettings(): SettableSettingInfo[];
656
+ /**
657
+ * Atomically sets one user-facing setting in the global config file (`<config home>/config.json`)
658
+ * while preserving every unrelated JSON field. The value is validated against the same zod leaf
659
+ * used by `configSchema`, so a write can never produce a config the loader would reject. The
660
+ * caller is responsible for applying the change to the running process (see `application.ts`).
661
+ */
662
+ export declare function setConfigValue(input: {
663
+ key: SettableSettingKey;
664
+ value: unknown;
665
+ }): Promise<string>;
419
666
  /** Atomically updates one project plugin override while preserving every unrelated JSON field. */
420
667
  export declare function setProjectPluginEnabled(input: {
421
668
  workspace: string;