flavor-code 1.3.10 → 1.3.11

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.
@@ -16,7 +16,7 @@ import {
16
16
  redactErrorText,
17
17
  transcriptReducer,
18
18
  withTimeout
19
- } from "./chunk-Y3DPUAEJ.js";
19
+ } from "./chunk-IGFN2DM5.js";
20
20
  import "./chunk-IG4Z23CL.js";
21
21
  import {
22
22
  Box_default,
@@ -1257,7 +1257,7 @@ function slashCandidatePresentation(selected) {
1257
1257
  matchStyle: { color: "ansi:cyan", bold: true }
1258
1258
  };
1259
1259
  }
1260
- function buildSlashCandidates(commands, plugins, skills) {
1260
+ function buildSlashCandidates(commands, plugins, skills, tools = []) {
1261
1261
  const candidates = /* @__PURE__ */ new Map();
1262
1262
  for (const command of commands) {
1263
1263
  candidates.set(command.name, { name: command.name, kind: "command", description: command.description });
@@ -1267,6 +1267,11 @@ function buildSlashCandidates(commands, plugins, skills) {
1267
1267
  candidates.set(plugin.name, plugin.description === void 0 ? { name: plugin.name, kind: "plugin" } : { name: plugin.name, kind: "plugin", description: plugin.description });
1268
1268
  }
1269
1269
  }
1270
+ for (const tool of tools) {
1271
+ if (!candidates.has(tool.name)) {
1272
+ candidates.set(tool.name, tool.description === void 0 ? { name: tool.name, kind: "tool" } : { name: tool.name, kind: "tool", description: tool.description });
1273
+ }
1274
+ }
1270
1275
  for (const skill of skills) {
1271
1276
  if (!candidates.has(skill.name)) {
1272
1277
  candidates.set(skill.name, {
@@ -1850,7 +1855,8 @@ function appRuntimeOptions(props, output, onApprovalChange) {
1850
1855
  ...props.palAlias === void 0 ? {} : { alias: props.palAlias }
1851
1856
  },
1852
1857
  output,
1853
- onApprovalChange
1858
+ onApprovalChange,
1859
+ onToolsChange: onApprovalChange
1854
1860
  };
1855
1861
  }
1856
1862
  function App({ workspace, home, resumeSession, instanceId, palAlias }) {
@@ -1954,13 +1960,23 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
1954
1960
  }
1955
1961
  dispatch({ type: "restore", state: created.restoredTranscript });
1956
1962
  runtimeRef.current = created;
1957
- setSlashCandidates(buildSlashCandidates(BUILTIN_SLASH_CANDIDATES, created.services.pluginCommands(), []));
1963
+ setSlashCandidates(buildSlashCandidates(
1964
+ BUILTIN_SLASH_CANDIDATES,
1965
+ created.services.pluginCommands(),
1966
+ [],
1967
+ created.services.managedToolCommands()
1968
+ ));
1958
1969
  setRuntime(created);
1959
1970
  await created.session.start();
1960
1971
  try {
1961
1972
  const skills = await created.services.skills();
1962
1973
  if (!disposed) {
1963
- setSlashCandidates(buildSlashCandidates(BUILTIN_SLASH_CANDIDATES, created.services.pluginCommands(), skills));
1974
+ setSlashCandidates(buildSlashCandidates(
1975
+ BUILTIN_SLASH_CANDIDATES,
1976
+ created.services.pluginCommands(),
1977
+ skills,
1978
+ created.services.managedToolCommands()
1979
+ ));
1964
1980
  }
1965
1981
  } catch {
1966
1982
  }
@@ -1975,6 +1991,28 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
1975
1991
  `));
1976
1992
  };
1977
1993
  }, [workspace, home, resumeSession, instanceId, palAlias]);
1994
+ useEffect3(() => {
1995
+ if (runtime === void 0) return;
1996
+ let disposed = false;
1997
+ void runtime.services.skills().then((skills) => {
1998
+ if (!disposed) setSlashCandidates(buildSlashCandidates(
1999
+ BUILTIN_SLASH_CANDIDATES,
2000
+ runtime.services.pluginCommands(),
2001
+ skills,
2002
+ runtime.services.managedToolCommands()
2003
+ ));
2004
+ }).catch(() => {
2005
+ if (!disposed) setSlashCandidates(buildSlashCandidates(
2006
+ BUILTIN_SLASH_CANDIDATES,
2007
+ runtime.services.pluginCommands(),
2008
+ [],
2009
+ runtime.services.managedToolCommands()
2010
+ ));
2011
+ });
2012
+ return () => {
2013
+ disposed = true;
2014
+ };
2015
+ }, [runtime, revision]);
1978
2016
  useEffect3(() => installSigintHandler(process, interrupt), [interrupt]);
1979
2017
  useEffect3(() => {
1980
2018
  if (runtime?.services.ideContext === void 0) {
@@ -2347,7 +2385,6 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2347
2385
  setDismissedMentionInput(void 0);
2348
2386
  }
2349
2387
  });
2350
- void revision;
2351
2388
  if (runtime === void 0) return /* @__PURE__ */ jsx5(
2352
2389
  StartingLayout,
2353
2390
  {
@@ -2996,7 +2996,8 @@ var MVP_COMMANDS = [
2996
2996
  "fork",
2997
2997
  "pals",
2998
2998
  "chat",
2999
- "co-work"
2999
+ "co-work",
3000
+ "tool"
3000
3001
  ];
3001
3002
  var COMMAND_DESCRIPTIONS = {
3002
3003
  model: "Switch the active model",
@@ -3034,16 +3035,24 @@ var COMMAND_DESCRIPTIONS = {
3034
3035
  fork: "Continue context from a prior session node",
3035
3036
  pals: "List, rename, or inspect active Flavor pals",
3036
3037
  chat: "Send a task to another Flavor pal",
3037
- "co-work": "Coordinate a shared goal with another Flavor pal"
3038
+ "co-work": "Coordinate a shared goal with another Flavor pal",
3039
+ tool: "Run a registered managed tool with a JSON object"
3038
3040
  };
3039
- function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
3041
+ function parseSlashCommand(input, dynamicCommands = [], skillCommands = [], managedTools = []) {
3040
3042
  const trimmed = input.trim();
3041
3043
  if (!trimmed.startsWith("/")) return null;
3042
- const [rawName = "", ...args] = trimmed.slice(1).split(/\s+/);
3044
+ const match = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(trimmed.slice(1));
3045
+ const rawName = match?.[1] ?? "";
3046
+ const rawArguments = match?.[2] ?? "";
3047
+ const args = rawArguments.length === 0 ? [] : rawArguments.split(/\s+/u);
3043
3048
  const name = rawName.toLowerCase();
3044
3049
  if (!MVP_COMMANDS.includes(name) && dynamicCommands.includes(name)) {
3045
3050
  return { name: "plugin", command: name, args };
3046
3051
  }
3052
+ if (!MVP_COMMANDS.includes(name)) {
3053
+ const managedTool = managedTools.find((tool) => tool.toLowerCase() === name);
3054
+ if (managedTool !== void 0) return { name: "managed-tool", tool: managedTool, input: rawArguments };
3055
+ }
3047
3056
  if (!MVP_COMMANDS.includes(name) && skillCommands.includes(name)) {
3048
3057
  return { name: "skill", skill: name, prompt: args.join(" ") };
3049
3058
  }
@@ -3065,6 +3074,15 @@ function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
3065
3074
  }
3066
3075
  return { name, mode: normalized };
3067
3076
  }
3077
+ if (name === "tool") {
3078
+ const [requested] = args;
3079
+ const managedTool = requested === void 0 ? void 0 : managedTools.find((candidate) => candidate.toLowerCase() === requested.toLowerCase());
3080
+ if (managedTool === void 0) {
3081
+ return { name: "invalid", command: name, message: "Use /tool <registered-tool> [JSON object]." };
3082
+ }
3083
+ const inputStart = rawArguments.search(/\s/u);
3084
+ return { name: "managed-tool", tool: managedTool, input: inputStart < 0 ? "" : rawArguments.slice(inputStart).trimStart() };
3085
+ }
3068
3086
  if (name === "audit") {
3069
3087
  const toolFilter = args.length > 0 ? args.join(" ") : void 0;
3070
3088
  return { name, toolFilter };
@@ -3292,6 +3310,7 @@ var HELP = [
3292
3310
  "/review [focus] review uncommitted changes before committing",
3293
3311
  "/evolve <signals|suggest|improve <id>|verify <name>|reload <name>|test|revert <name>|done <id>> self-improvement loop",
3294
3312
  "/mcp [status|tools|reconnect|enable|disable] manage MCP servers",
3313
+ "/tool <registered-tool> [JSON object] run a registered tool (or use /<tool-name>)",
3295
3314
  "/ide show VS Code connection and cursor/selection",
3296
3315
  "/pals [--verbose|rename <alias>|info <alias-or-uuid>]",
3297
3316
  "/chat <alias-or-uuid> <goal> send a task that starts on the receiving pal",
@@ -3563,7 +3582,12 @@ var FlavorSession = class {
3563
3582
  } catch {
3564
3583
  }
3565
3584
  }
3566
- const command = parseSlashCommand(prompt, this.#services.pluginCommands().map(({ name }) => name), skillNames);
3585
+ const command = parseSlashCommand(
3586
+ prompt,
3587
+ this.#services.pluginCommands().map(({ name }) => name),
3588
+ skillNames,
3589
+ this.#services.managedToolCommands().map(({ name }) => name)
3590
+ );
3567
3591
  if (command !== null) await this.#dispatch(command, controller.signal);
3568
3592
  else for await (const event of this.#services.run(prompt, controller.signal, {
3569
3593
  getSteeringMessages: () => this.#drainMessages("steer", true).map((item) => item.text),
@@ -3665,6 +3689,8 @@ var FlavorSession = class {
3665
3689
  this.#notice(`Main permissions set to ${command.mode}. Child approvals use bubble mode unless plan mode is active.`);
3666
3690
  } else if (command.name === "plugin") {
3667
3691
  this.#notice(format(await this.#services.runPluginCommand(command.command, command.args, signal)));
3692
+ } else if (command.name === "managed-tool") {
3693
+ this.#notice(format(await this.#services.runManagedTool(command.tool, command.input, signal)));
3668
3694
  } else if (command.name === "skill") {
3669
3695
  for await (const event of this.#services.runSkill(command.skill, command.prompt, signal)) this.#services.output(event);
3670
3696
  } else if (command.name === "loop") {
@@ -6536,9 +6562,10 @@ function withStructuredOutput(options) {
6536
6562
  throw new Error("Structured output retry delays must be non-negative integers");
6537
6563
  }
6538
6564
  }
6539
- const tool = modelToolFromZod(options.name, options.description, options.schema);
6565
+ const generatedTool = options.modelInputSchema === void 0 ? modelToolFromZod(options.name, options.description, options.schema) : { name: options.name, description: options.description, inputSchema: options.modelInputSchema };
6566
+ const tool = options.modelStrict === void 0 ? generatedTool : { ...generatedTool, strict: options.modelStrict };
6540
6567
  const maxAttempts = retry.maxRetries + 1;
6541
- const jsonSchema = tool.inputSchema;
6568
+ const validationSchema = jsonSchemaFromZod(options.schema);
6542
6569
  const model = {
6543
6570
  async *stream(request) {
6544
6571
  let candidate;
@@ -6611,7 +6638,7 @@ function withStructuredOutput(options) {
6611
6638
  }
6612
6639
  }
6613
6640
  if (candidateCount === 1 && candidate !== null && typeof candidate === "object") {
6614
- candidate = coerceByJsonSchema(candidate, jsonSchema);
6641
+ candidate = coerceByJsonSchema(candidate, validationSchema);
6615
6642
  }
6616
6643
  if (candidateCount !== 1) {
6617
6644
  attemptError = {
@@ -6683,7 +6710,13 @@ function withStructuredOutput(options) {
6683
6710
  return model;
6684
6711
  }
6685
6712
  function strictJsonSchema(schema) {
6686
- return ensureStrictSchema(z7.toJSONSchema(schema));
6713
+ return strictJsonSchemaObject(jsonSchemaFromZod(schema));
6714
+ }
6715
+ function jsonSchemaFromZod(schema) {
6716
+ return z7.toJSONSchema(schema);
6717
+ }
6718
+ function strictJsonSchemaObject(schema) {
6719
+ return ensureStrictSchema(schema);
6687
6720
  }
6688
6721
  function extractJsonObject(text) {
6689
6722
  const trimmed = text.trim();
@@ -6731,6 +6764,7 @@ function coerceByJsonSchema(value, schema) {
6731
6764
  const node = schema;
6732
6765
  const branches = [
6733
6766
  ...Array.isArray(node.anyOf) ? node.anyOf : [],
6767
+ ...Array.isArray(node.oneOf) ? node.oneOf : [],
6734
6768
  ...Array.isArray(node.allOf) ? node.allOf : []
6735
6769
  ].filter((branch) => branch !== null && typeof branch === "object");
6736
6770
  const types = [];
@@ -6750,40 +6784,108 @@ function coerceByJsonSchema(value, schema) {
6750
6784
  if (lowered === "true") return true;
6751
6785
  if (lowered === "false") return false;
6752
6786
  }
6787
+ if (types.includes("object") && !types.includes("string") && typeof value === "string") {
6788
+ const trimmed = value.trim();
6789
+ if (trimmed.startsWith("{")) {
6790
+ try {
6791
+ const parsed = JSON.parse(trimmed);
6792
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
6793
+ return coerceByJsonSchema(parsed, node);
6794
+ }
6795
+ } catch {
6796
+ }
6797
+ }
6798
+ }
6799
+ if (types.includes("array") && !Array.isArray(value) && value !== null && value !== void 0 && !types.some((type) => matchesJsonSchemaType(value, type))) {
6800
+ const arraySchema = [node, ...branches].find((candidate) => {
6801
+ const type = candidate.type;
6802
+ return type === "array" || Array.isArray(type) && type.includes("array");
6803
+ });
6804
+ if (typeof value === "string" && value.trim().startsWith("[")) {
6805
+ try {
6806
+ const parsed = JSON.parse(value.trim());
6807
+ if (Array.isArray(parsed)) return coerceByJsonSchema(parsed, arraySchema ?? node);
6808
+ } catch {
6809
+ }
6810
+ }
6811
+ return [arraySchema?.items === void 0 ? value : coerceByJsonSchema(value, arraySchema.items)];
6812
+ }
6753
6813
  if (value !== null && typeof value === "object" && !Array.isArray(value)) {
6754
- const properties = node.properties ?? branches.find((branch) => branch.properties)?.properties;
6814
+ const objectSchema = [node, ...branches].find((candidate) => candidate.type === "object" || candidate.properties !== void 0);
6815
+ const properties = objectSchema?.properties;
6755
6816
  if (properties !== void 0) {
6756
6817
  const output = {};
6818
+ const required2 = new Set(Array.isArray(objectSchema?.required) ? objectSchema.required : []);
6757
6819
  for (const [key, child] of Object.entries(value)) {
6758
- output[key] = properties[key] !== void 0 ? coerceByJsonSchema(child, properties[key]) : child;
6820
+ const childSchema = properties[key];
6821
+ if (child === null && childSchema !== void 0 && !required2.has(key) && !jsonSchemaAllowsNull(childSchema)) {
6822
+ continue;
6823
+ }
6824
+ output[key] = childSchema !== void 0 ? coerceByJsonSchema(child, childSchema) : child;
6759
6825
  }
6760
6826
  return output;
6761
6827
  }
6762
6828
  }
6763
- if (types.includes("array") && Array.isArray(value) && node.items !== void 0) {
6764
- return value.map((item) => coerceByJsonSchema(item, node.items));
6829
+ if (types.includes("array") && Array.isArray(value)) {
6830
+ const arraySchema = [node, ...branches].find((candidate) => {
6831
+ const type = candidate.type;
6832
+ return type === "array" || Array.isArray(type) && type.includes("array");
6833
+ });
6834
+ if (arraySchema?.items !== void 0) {
6835
+ return value.map((item) => coerceByJsonSchema(item, arraySchema.items));
6836
+ }
6765
6837
  }
6766
6838
  return value;
6767
6839
  }
6840
+ function matchesJsonSchemaType(value, type) {
6841
+ if (type === "null") return value === null;
6842
+ if (type === "array") return Array.isArray(value);
6843
+ if (type === "object") return value !== null && typeof value === "object" && !Array.isArray(value);
6844
+ if (type === "integer") return typeof value === "number" && Number.isInteger(value);
6845
+ if (type === "number") return typeof value === "number";
6846
+ return typeof value === type;
6847
+ }
6848
+ function jsonSchemaAllowsNull(schema) {
6849
+ if (schema === null || typeof schema !== "object") return false;
6850
+ const node = schema;
6851
+ if (node.type === "null" || Array.isArray(node.type) && node.type.includes("null")) return true;
6852
+ return [node.anyOf, node.oneOf].some((branches) => Array.isArray(branches) && branches.some((branch) => jsonSchemaAllowsNull(branch)));
6853
+ }
6768
6854
  function modelToolFromZod(name, description, schema) {
6769
6855
  return { name, description, inputSchema: strictJsonSchema(schema) };
6770
6856
  }
6771
6857
  function ensureStrictSchema(schema) {
6858
+ const output = { ...schema };
6859
+ for (const keyword of ["anyOf", "oneOf", "allOf", "prefixItems"]) {
6860
+ const branches = schema[keyword];
6861
+ if (Array.isArray(branches)) {
6862
+ output[keyword] = branches.map((branch) => typeof branch === "object" && branch !== null ? ensureStrictSchema(branch) : branch);
6863
+ }
6864
+ }
6865
+ if (typeof schema.items === "object" && schema.items !== null) {
6866
+ output.items = ensureStrictSchema(schema.items);
6867
+ }
6868
+ for (const keyword of ["$defs", "definitions"]) {
6869
+ const definitions = schema[keyword];
6870
+ if (typeof definitions === "object" && definitions !== null && !Array.isArray(definitions)) {
6871
+ output[keyword] = Object.fromEntries(Object.entries(definitions).map(([key, definition]) => [
6872
+ key,
6873
+ typeof definition === "object" && definition !== null ? ensureStrictSchema(definition) : definition
6874
+ ]));
6875
+ }
6876
+ }
6772
6877
  if (schema.type !== "object" || typeof schema.properties !== "object" || schema.properties === null) {
6773
- return schema;
6878
+ return output;
6774
6879
  }
6775
- const required2 = Array.isArray(schema.required) ? [...schema.required] : [];
6776
- const requiredSet = new Set(required2);
6880
+ const requiredSet = new Set(Array.isArray(schema.required) ? schema.required : []);
6777
6881
  const properties = {};
6778
6882
  for (const [key, value] of Object.entries(schema.properties)) {
6779
6883
  const child = typeof value === "object" && value !== null ? ensureStrictSchema(value) : value;
6780
- if (requiredSet.has(key)) properties[key] = child;
6781
- else {
6782
- properties[key] = { anyOf: [child, { type: "null" }] };
6783
- requiredSet.add(key);
6784
- }
6884
+ if (requiredSet.has(key) || jsonSchemaAllowsNull(child)) properties[key] = child;
6885
+ else properties[key] = { anyOf: [child, { type: "null" }] };
6886
+ requiredSet.add(key);
6785
6887
  }
6786
- return { ...schema, additionalProperties: false, required: [...requiredSet], properties };
6888
+ return { ...output, additionalProperties: false, required: [...requiredSet], properties };
6787
6889
  }
6788
6890
  function repairMessages(messages, tool, original, candidate, error) {
6789
6891
  const details = [
@@ -7153,19 +7255,11 @@ var AgentLoop = class {
7153
7255
  });
7154
7256
  continue;
7155
7257
  }
7156
- const validation = collected.kind === "valid" ? this.#options.runtime.validate(collected) : { ok: false, error: collected.error };
7258
+ const validation = collected.kind === "valid" ? this.#options.runtime.normalize(collected) : { ok: false, error: collected.error };
7157
7259
  if (validation.ok) {
7158
7260
  toolCalls.push({ id: collected.id, name: collected.name, input: validation.input });
7159
7261
  continue;
7160
7262
  }
7161
- if (collected.kind === "valid") {
7162
- const coerced = coerceByJsonSchema(collected.input, strictJsonSchema(definition.inputSchema));
7163
- const revalidation = this.#options.runtime.validate({ ...collected, input: coerced });
7164
- if (revalidation.ok) {
7165
- toolCalls.push({ id: collected.id, name: collected.name, input: revalidation.input });
7166
- continue;
7167
- }
7168
- }
7169
7263
  const repairModelId = this.#options.fallbackModelId ?? this.#options.modelId;
7170
7264
  const invalidOutput = collected.kind === "invalid" ? collected.rawInput : serializeToolInput(collected.input);
7171
7265
  const structured = withStructuredOutput({
@@ -7174,6 +7268,8 @@ var AgentLoop = class {
7174
7268
  name: definition.name,
7175
7269
  description: definition.description,
7176
7270
  schema: definition.inputSchema,
7271
+ ...definition.modelInputSchema === void 0 ? {} : { modelInputSchema: definition.modelInputSchema },
7272
+ ...definition.modelStrict === void 0 ? {} : { modelStrict: definition.modelStrict },
7177
7273
  beforeAttempt: async ({ attempt: repairAttempt, maxAttempts: repairMaxAttempts, messageCount }) => {
7178
7274
  const before = await this.#options.hooks.emit({
7179
7275
  version: 1,
@@ -7654,12 +7750,24 @@ var ToolRuntime = class {
7654
7750
  throw error;
7655
7751
  }
7656
7752
  }
7753
+ /**
7754
+ * Validates a call and applies the same conservative provider-argument
7755
+ * normalization used by the agent loop before falling back to repair.
7756
+ */
7757
+ normalize(call) {
7758
+ const validation = this.validate(call);
7759
+ if (validation.ok || validation.error.code === "unknown_tool") return validation;
7760
+ const tool = this.#tools.get(call.name);
7761
+ if (tool === void 0) return validation;
7762
+ const input = coerceByJsonSchema(call.input, jsonSchemaFromZod(tool.inputSchema));
7763
+ return this.validate({ ...call, input });
7764
+ }
7657
7765
  async #execute(call, context) {
7658
7766
  const tool = this.#tools.get(call.name);
7659
7767
  if (tool === void 0) return { ok: false, error: { code: "unknown_tool", message: `Unknown tool: ${call.name}` } };
7660
7768
  const signal = context.signal ?? new AbortController().signal;
7661
7769
  const toolCallId = call.id ?? randomUUID7();
7662
- const validation = this.validate(call);
7770
+ const validation = this.normalize(call);
7663
7771
  if (!validation.ok) {
7664
7772
  return this.#fail(toolCallId, call.name, call.input, context.agent, validation.error.code, validation.error.message);
7665
7773
  }
@@ -9388,6 +9496,7 @@ var PluginHost = class {
9388
9496
  description: contribution.description,
9389
9497
  inputSchema: z13.unknown(),
9390
9498
  ...contribution.modelInputSchema === void 0 ? {} : { modelInputSchema: contribution.modelInputSchema },
9499
+ ...contribution.modelInputSchema === void 0 ? {} : { modelStrict: false },
9391
9500
  ...contribution.readOnly === void 0 ? {} : { readOnly: contribution.readOnly },
9392
9501
  paths: () => [],
9393
9502
  execute: (input, _signal, toolContext) => session.invoke("tool", contribution.name, [
@@ -17795,7 +17904,7 @@ function compileDefinition(record, scope2, workspace) {
17795
17904
  name: record.name,
17796
17905
  description: record.description,
17797
17906
  inputSchema,
17798
- modelInputSchema: record.inputSchema,
17907
+ modelInputSchema: strictJsonSchemaObject(record.inputSchema),
17799
17908
  modelStrict: true,
17800
17909
  ...record.agents === void 0 ? {} : { agents: record.agents },
17801
17910
  paths: () => [],
@@ -20859,6 +20968,7 @@ async function createProductionRuntime(options) {
20859
20968
  managedTools.push(tool);
20860
20969
  }
20861
20970
  if (harnessCreated) harness.replaceMainTools(tools);
20971
+ options.onToolsChange?.();
20862
20972
  };
20863
20973
  tools.push(...createManagedToolManagementTools({
20864
20974
  store: managedToolStore,
@@ -22188,6 +22298,25 @@ ${renderMemoryDocument(entries)}`;
22188
22298
  signal.throwIfAborted();
22189
22299
  return awaitWithSignal(Promise.resolve(handler(args, { workspace, signal })), signal);
22190
22300
  },
22301
+ managedToolCommands: () => managedTools.map(({ name, description }) => ({ name, description })).sort((left, right) => left.name.localeCompare(right.name)),
22302
+ runManagedTool: async (name, rawInput, signal) => {
22303
+ const tool = managedTools.find((candidate) => sameToolName(candidate.name, name));
22304
+ if (tool === void 0) throw new Error(`Registered tool "${name}" is no longer available.`);
22305
+ signal.throwIfAborted();
22306
+ const input = normalizeToolCallInput(rawInput);
22307
+ const call = { name: tool.name, input };
22308
+ const validation = harness.main.runtime.normalize(call);
22309
+ if (!validation.ok) throw new Error(`Invalid input for registered tool "${tool.name}": ${validation.error.message}`);
22310
+ harness.main.runtime.beginTurn();
22311
+ const result = await harness.main.runtime.execute(
22312
+ { name: tool.name, input: validation.input },
22313
+ { agent: "main", ownerId: "main", signal }
22314
+ );
22315
+ if (!result.ok) {
22316
+ throw new Error(`Registered tool "${tool.name}" failed (${result.error?.code ?? "unknown"}): ${result.error?.message ?? "Unknown error"}`);
22317
+ }
22318
+ return result.output !== void 0 ? result.output : result.content;
22319
+ },
22191
22320
  output: emitOutput,
22192
22321
  questions,
22193
22322
  async login() {
@@ -4,7 +4,7 @@ import {
4
4
  message,
5
5
  redactErrorText,
6
6
  redactSecrets
7
- } from "./chunk-Y3DPUAEJ.js";
7
+ } from "./chunk-IGFN2DM5.js";
8
8
 
9
9
  // src/rpc/server.ts
10
10
  import { createInterface } from "readline";
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire } from "node:module"; const require = createRequire(impor
3
3
  import {
4
4
  FlavorRpcServer,
5
5
  TraceRecorder
6
- } from "./chunk-T2ARW6CZ.js";
6
+ } from "./chunk-JZ5FVBET.js";
7
7
  import {
8
8
  staticTaskLines
9
9
  } from "./chunk-KKIBYDJI.js";
@@ -23,7 +23,7 @@ import {
23
23
  packageVersion,
24
24
  redactErrorText,
25
25
  runPalBroker
26
- } from "./chunk-Y3DPUAEJ.js";
26
+ } from "./chunk-IGFN2DM5.js";
27
27
  import {
28
28
  McpServerConfigSchema,
29
29
  McpServerNameSchema,
@@ -877,7 +877,7 @@ async function runInteractiveCli(props) {
877
877
  const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
878
878
  import("./claude-ink-ORUA7GWG.js"),
879
879
  import("react"),
880
- import("./app-YSBW7GXH.js")
880
+ import("./app-L52CTVNR.js")
881
881
  ]);
882
882
  const instance = await render(createElement(
883
883
  AlternateScreen,