@theokit/sdk 2.23.0 → 2.25.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 (43) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/a2a/index.cjs +259 -192
  3. package/dist/a2a/index.cjs.map +1 -1
  4. package/dist/a2a/index.js +259 -192
  5. package/dist/a2a/index.js.map +1 -1
  6. package/dist/create-skill.d.ts +8 -0
  7. package/dist/{cron-7CruUd_0.d.ts → cron-B44D-678.d.ts} +67 -4
  8. package/dist/{cron-Bpt_1khA.d.cts → cron-qI-dbG7c.d.cts} +67 -4
  9. package/dist/cron.cjs +246 -181
  10. package/dist/cron.cjs.map +1 -1
  11. package/dist/cron.d.cts +2 -2
  12. package/dist/cron.d.ts +2 -2
  13. package/dist/cron.js +246 -181
  14. package/dist/cron.js.map +1 -1
  15. package/dist/define-tool.d.ts +33 -20
  16. package/dist/{errors-CkCaIqVP.d.cts → errors-DIKBXffg.d.cts} +1 -1
  17. package/dist/{errors-BuwwkrAk.d.ts → errors-DRS-kqOK.d.ts} +1 -1
  18. package/dist/errors.d.cts +2 -2
  19. package/dist/eval.cjs +246 -181
  20. package/dist/eval.cjs.map +1 -1
  21. package/dist/eval.js +246 -181
  22. package/dist/eval.js.map +1 -1
  23. package/dist/index.cjs +299 -186
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +75 -27
  26. package/dist/index.d.ts +75 -27
  27. package/dist/index.js +299 -187
  28. package/dist/index.js.map +1 -1
  29. package/dist/internal/runtime/local-agent/local-agent-bootstrap.d.ts +2 -4
  30. package/dist/internal/runtime/skills/skill-frontmatter.d.ts +6 -0
  31. package/dist/{run-CrIulPF7.d.cts → run-Cr0C6cOM.d.cts} +17 -0
  32. package/dist/{run-CrIulPF7.d.ts → run-Cr0C6cOM.d.ts} +17 -0
  33. package/dist/skills.cjs.map +1 -1
  34. package/dist/skills.js.map +1 -1
  35. package/dist/types/agent.d.ts +57 -2
  36. package/dist/types/run.d.ts +17 -0
  37. package/dist/workflow.cjs +37 -0
  38. package/dist/workflow.cjs.map +1 -1
  39. package/dist/workflow.d.cts +47 -1
  40. package/dist/workflow.d.ts +47 -1
  41. package/dist/workflow.js +37 -2
  42. package/dist/workflow.js.map +1 -1
  43. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -575,10 +575,10 @@ function buildToolPrompt(prompt) {
575
575
  Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
576
576
  }
577
577
  function setupStructuredOutput(schema, maxRetries) {
578
- const z8 = requireZod();
578
+ const z9 = requireZod();
579
579
  const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
580
580
  return {
581
- z: z8,
581
+ z: z9,
582
582
  jsonSchema,
583
583
  maxRetries: maxRetries ?? 1,
584
584
  initialUsage: { inputTokens: 0, outputTokens: 0 }
@@ -6046,7 +6046,8 @@ function stripSecretsFromOptions(options) {
6046
6046
  local: serializeLocal(options.local),
6047
6047
  cloud: serializeCloud(options.cloud),
6048
6048
  memory: serializeMemory(options.memory),
6049
- skills: serializeEnabledList(options.skills),
6049
+ // SE22 — a SkillsResolver function isn't serializable; persist only the static form.
6050
+ skills: serializeEnabledList(typeof options.skills === "function" ? void 0 : options.skills),
6050
6051
  // Code-`Plugin` objects are closures and cannot be persisted (like custom
6051
6052
  // tools); only the named-enable settings form is serialized.
6052
6053
  plugins: serializeEnabledList(asPluginsSettings(options.plugins)),
@@ -6354,6 +6355,7 @@ function serializeCloud2(cloud) {
6354
6355
  return result;
6355
6356
  }
6356
6357
  function serializeSkills(skills) {
6358
+ if (typeof skills === "function") return void 0;
6357
6359
  if (skills?.enabled === void 0 || skills.enabled.length === 0) return void 0;
6358
6360
  return { enabled: [...skills.enabled] };
6359
6361
  }
@@ -7734,6 +7736,7 @@ init_errors();
7734
7736
  function validateCloudToolParity(options) {
7735
7737
  if (options.cloud === void 0) return;
7736
7738
  rejectFunctionSystemPrompt(options);
7739
+ rejectFunctionSkills(options);
7737
7740
  rejectStdioMcpLocalPaths(options);
7738
7741
  }
7739
7742
  function rejectFunctionSystemPrompt(options) {
@@ -7744,6 +7747,14 @@ function rejectFunctionSystemPrompt(options) {
7744
7747
  );
7745
7748
  }
7746
7749
  }
7750
+ function rejectFunctionSkills(options) {
7751
+ if (typeof options.skills === "function") {
7752
+ throw new exports.ConfigurationError(
7753
+ "Cloud agents require skills as a static settings object. SkillsResolver functions can't run on PaaS \u2014 resolve to a SkillsSettings object before Agent.create() or move the dynamic logic into a hook rule.",
7754
+ { code: "cloud_incompatible_function_resolver" }
7755
+ );
7756
+ }
7757
+ }
7747
7758
  function rejectStdioMcpLocalPaths(options) {
7748
7759
  if (options.mcpServers === void 0) return;
7749
7760
  for (const [name, config] of Object.entries(options.mcpServers)) {
@@ -9570,9 +9581,224 @@ function parseFrontmatterFields(frontmatter) {
9570
9581
  return out;
9571
9582
  }
9572
9583
 
9584
+ // src/internal/runtime/skills/discover-skills.ts
9585
+ init_errors();
9586
+ init_path_guard();
9587
+
9588
+ // src/internal/runtime/skills/skill-frontmatter.ts
9589
+ init_errors();
9590
+ init_yaml_frontmatter();
9591
+ function asString(v) {
9592
+ return typeof v === "string" ? v : void 0;
9593
+ }
9594
+ function toStringFields(raw) {
9595
+ const out = {};
9596
+ for (const [k, v] of Object.entries(raw)) out[k] = asString(v);
9597
+ return out;
9598
+ }
9599
+ function parseSkillFrontmatter(raw, fallbackName) {
9600
+ const fields = extractAndParseFrontmatter(raw, fallbackName);
9601
+ const name = resolveName(fields, fallbackName);
9602
+ ensureRequiredFields(fields, name);
9603
+ return buildFrontmatter(fields, name);
9604
+ }
9605
+ function stripSkillFrontmatter(raw) {
9606
+ const match = /^---\s*\n[\s\S]*?\n---\s*\n/.exec(raw);
9607
+ return (match === null ? raw : raw.slice(match[0].length)).trim();
9608
+ }
9609
+ function extractAndParseFrontmatter(raw, fallbackName) {
9610
+ const match = /^---\s*\n([\s\S]*?)\n---\s*\n/.exec(raw);
9611
+ if (match === null) {
9612
+ throw new exports.ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {
9613
+ code: "missing_frontmatter"
9614
+ });
9615
+ }
9616
+ const frontmatter = match[1] ?? "";
9617
+ try {
9618
+ return toStringFields(parseSimpleYaml(frontmatter));
9619
+ } catch (cause) {
9620
+ const detail = cause instanceof Error ? cause.message : String(cause);
9621
+ throw new exports.ConfigurationError(
9622
+ `Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,
9623
+ { code: "schema_invalid", cause }
9624
+ );
9625
+ }
9626
+ }
9627
+ function resolveName(fields, fallbackName) {
9628
+ if (hasContent(fields.name)) return fields.name;
9629
+ if (hasContent(fallbackName)) return fallbackName;
9630
+ throw new exports.ConfigurationError("Skill at unknown path is missing required field: name", {
9631
+ code: "schema_invalid"
9632
+ });
9633
+ }
9634
+ function ensureRequiredFields(fields, name) {
9635
+ if (!hasContent(fields.description)) {
9636
+ throw new exports.ConfigurationError(`Skill ${name} is missing required field: description`, {
9637
+ code: "schema_invalid"
9638
+ });
9639
+ }
9640
+ }
9641
+ function buildFrontmatter(fields, name) {
9642
+ const description = fields.description;
9643
+ if (description === void 0) {
9644
+ throw new exports.ConfigurationError(`Skill ${name} missing description`, { code: "schema_invalid" });
9645
+ }
9646
+ const result = { name, description };
9647
+ if (hasContent(fields.category)) result.category = fields.category;
9648
+ const deps = parseDependencies(fields.dependencies);
9649
+ if (deps !== void 0) result.dependencies = deps;
9650
+ return result;
9651
+ }
9652
+ function parseDependencies(raw) {
9653
+ if (!hasContent(raw)) return void 0;
9654
+ const deps = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
9655
+ return deps.length > 0 ? deps : void 0;
9656
+ }
9657
+ function hasContent(value) {
9658
+ return value !== void 0 && value.trim().length > 0;
9659
+ }
9660
+
9661
+ // src/internal/runtime/skills/discover-skills.ts
9662
+ async function discoverSkills(dir, options) {
9663
+ let entries;
9664
+ try {
9665
+ entries = await readWorkspaceDir(dir, "skills_read_error", "skills directory");
9666
+ } catch {
9667
+ return [];
9668
+ }
9669
+ const skills = [];
9670
+ for (const entry of entries) {
9671
+ if (!entry.isDirectory()) continue;
9672
+ let skillDir;
9673
+ try {
9674
+ skillDir = safePathJoin(dir, entry.name);
9675
+ assertNoSymlinkEscape(skillDir, dir);
9676
+ } catch {
9677
+ continue;
9678
+ }
9679
+ const skillPath = path.join(skillDir, "SKILL.md");
9680
+ let raw;
9681
+ try {
9682
+ raw = await promises.readFile(skillPath, "utf8");
9683
+ } catch {
9684
+ continue;
9685
+ }
9686
+ const skill = tryParseSkill(raw, entry.name, skillPath, options);
9687
+ if (skill !== void 0) skills.push(skill);
9688
+ }
9689
+ return skills;
9690
+ }
9691
+ function tryParseSkill(raw, fallbackName, source, options) {
9692
+ try {
9693
+ const frontmatter = parseSkillFrontmatter(raw, fallbackName);
9694
+ const skill = {
9695
+ name: frontmatter.name,
9696
+ description: frontmatter.description,
9697
+ source
9698
+ };
9699
+ if (frontmatter.category !== void 0) skill.category = frontmatter.category;
9700
+ if (frontmatter.dependencies !== void 0) skill.dependencies = frontmatter.dependencies;
9701
+ return skill;
9702
+ } catch (cause) {
9703
+ if (cause instanceof exports.ConfigurationError) {
9704
+ options?.onInvalidSkill?.({
9705
+ name: fallbackName,
9706
+ source,
9707
+ code: cause.code ?? "unknown",
9708
+ message: cause.message
9709
+ });
9710
+ return void 0;
9711
+ }
9712
+ throw cause;
9713
+ }
9714
+ }
9715
+
9716
+ // src/internal/runtime/skills/skills-manager.ts
9717
+ var SkillsManager = class {
9718
+ constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
9719
+ this.cwd = cwd;
9720
+ this.settingSourcesIncludeProject = settingSourcesIncludeProject;
9721
+ this.skillsDir = skillsDir;
9722
+ this.inline = inline;
9723
+ }
9724
+ cwd;
9725
+ settingSourcesIncludeProject;
9726
+ skillsDir;
9727
+ inline;
9728
+ skills = [];
9729
+ async initialize() {
9730
+ if (!this.settingSourcesIncludeProject) {
9731
+ this.skills = this.mergeInline([]);
9732
+ return;
9733
+ }
9734
+ await this.refresh();
9735
+ }
9736
+ async refresh() {
9737
+ const skillsRoot = this.skillsDir ?? path.join(this.cwd, ".theokit", "skills");
9738
+ const discovered = await discoverSkills(skillsRoot, {
9739
+ onInvalidSkill: (info) => {
9740
+ process.stderr.write(
9741
+ `[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
9742
+ `
9743
+ );
9744
+ }
9745
+ });
9746
+ this.skills = this.mergeInline(discovered);
9747
+ }
9748
+ /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
9749
+ mergeInline(discovered) {
9750
+ if (this.inline === void 0 || this.inline.length === 0) return discovered;
9751
+ const inlineNames = new Set(this.inline.map((s) => s.name));
9752
+ return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
9753
+ }
9754
+ list() {
9755
+ return Promise.resolve(this.skills);
9756
+ }
9757
+ /**
9758
+ * SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
9759
+ * skills carry `instructions` on the object; filesystem skills read the body
9760
+ * from their `source` SKILL.md (frontmatter stripped). `undefined` when no
9761
+ * enabled skill matches (malformed skills were already excluded at discovery).
9762
+ */
9763
+ async get(name) {
9764
+ const skill = this.skills.find((s) => s.name === name);
9765
+ if (skill === void 0) return void 0;
9766
+ const instructions = typeof skill.instructions === "string" ? skill.instructions : stripSkillFrontmatter(await promises.readFile(skill.source, "utf8"));
9767
+ const references = skill.references;
9768
+ return {
9769
+ name: skill.name,
9770
+ description: skill.description,
9771
+ instructions,
9772
+ ...references !== void 0 ? { references } : {}
9773
+ };
9774
+ }
9775
+ };
9776
+
9573
9777
  // src/internal/runtime/system-prompt/local-assembly.ts
9574
- async function buildSystemPromptContext(inputs, userText, memoryFacts) {
9575
- const skills = inputs.skillsManager !== void 0 ? await inputs.skillsManager.list() : [];
9778
+ async function resolveSendSkills(inputs, userText, memoryFacts) {
9779
+ const skills = inputs.options.skills;
9780
+ if (typeof skills !== "function") {
9781
+ return { manager: inputs.skillsManager, autoInject: skills?.autoInject ?? true };
9782
+ }
9783
+ const settings = await skills({
9784
+ agentId: inputs.agentId,
9785
+ cwd: inputs.workspaceCwd,
9786
+ model: inputs.model,
9787
+ userMessage: userText,
9788
+ memory: memoryFacts.map((fact) => ({ text: fact.text }))
9789
+ });
9790
+ const manager = new SkillsManager(
9791
+ inputs.workspaceCwd,
9792
+ settings.enabled,
9793
+ inputs.settingSourcesIncludeProject,
9794
+ settings.skillsDir,
9795
+ settings.inline
9796
+ );
9797
+ await manager.initialize();
9798
+ return { manager, autoInject: settings.autoInject ?? true };
9799
+ }
9800
+ async function buildSystemPromptContext(inputs, userText, memoryFacts, manager = inputs.skillsManager) {
9801
+ const skills = manager !== void 0 ? await manager.list() : [];
9576
9802
  return {
9577
9803
  agentId: inputs.agentId,
9578
9804
  cwd: inputs.workspaceCwd,
@@ -9583,10 +9809,11 @@ async function buildSystemPromptContext(inputs, userText, memoryFacts) {
9583
9809
  };
9584
9810
  }
9585
9811
  async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary) {
9586
- const baseCtx = await buildSystemPromptContext(inputs, userText, memoryFacts);
9812
+ const resolved = await resolveSendSkills(inputs, userText, memoryFacts);
9813
+ const baseCtx = await buildSystemPromptContext(inputs, userText, memoryFacts, resolved.manager);
9587
9814
  const assemblyCtx = {
9588
9815
  ...baseCtx,
9589
- skillsAutoInject: inputs.options.skills?.autoInject ?? true,
9816
+ skillsAutoInject: resolved.autoInject,
9590
9817
  memoryAutoInject: inputs.options.memory?.autoInject ?? true
9591
9818
  };
9592
9819
  if (baseSystemPrompt !== void 0) assemblyCtx.baseSystemPrompt = baseSystemPrompt;
@@ -10839,177 +11066,6 @@ async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
10839
11066
  return metadata;
10840
11067
  }
10841
11068
 
10842
- // src/internal/runtime/skills/discover-skills.ts
10843
- init_errors();
10844
- init_path_guard();
10845
-
10846
- // src/internal/runtime/skills/skill-frontmatter.ts
10847
- init_errors();
10848
- init_yaml_frontmatter();
10849
- function asString(v) {
10850
- return typeof v === "string" ? v : void 0;
10851
- }
10852
- function toStringFields(raw) {
10853
- const out = {};
10854
- for (const [k, v] of Object.entries(raw)) out[k] = asString(v);
10855
- return out;
10856
- }
10857
- function parseSkillFrontmatter(raw, fallbackName) {
10858
- const fields = extractAndParseFrontmatter(raw, fallbackName);
10859
- const name = resolveName(fields, fallbackName);
10860
- ensureRequiredFields(fields, name);
10861
- return buildFrontmatter(fields, name);
10862
- }
10863
- function extractAndParseFrontmatter(raw, fallbackName) {
10864
- const match = /^---\s*\n([\s\S]*?)\n---\s*\n/.exec(raw);
10865
- if (match === null) {
10866
- throw new exports.ConfigurationError(`Skill ${fallbackName} is missing frontmatter`, {
10867
- code: "missing_frontmatter"
10868
- });
10869
- }
10870
- const frontmatter = match[1] ?? "";
10871
- try {
10872
- return toStringFields(parseSimpleYaml(frontmatter));
10873
- } catch (cause) {
10874
- const detail = cause instanceof Error ? cause.message : String(cause);
10875
- throw new exports.ConfigurationError(
10876
- `Skill ${fallbackName} has malformed YAML frontmatter: ${detail}`,
10877
- { code: "schema_invalid", cause }
10878
- );
10879
- }
10880
- }
10881
- function resolveName(fields, fallbackName) {
10882
- if (hasContent(fields.name)) return fields.name;
10883
- if (hasContent(fallbackName)) return fallbackName;
10884
- throw new exports.ConfigurationError("Skill at unknown path is missing required field: name", {
10885
- code: "schema_invalid"
10886
- });
10887
- }
10888
- function ensureRequiredFields(fields, name) {
10889
- if (!hasContent(fields.description)) {
10890
- throw new exports.ConfigurationError(`Skill ${name} is missing required field: description`, {
10891
- code: "schema_invalid"
10892
- });
10893
- }
10894
- }
10895
- function buildFrontmatter(fields, name) {
10896
- const description = fields.description;
10897
- if (description === void 0) {
10898
- throw new exports.ConfigurationError(`Skill ${name} missing description`, { code: "schema_invalid" });
10899
- }
10900
- const result = { name, description };
10901
- if (hasContent(fields.category)) result.category = fields.category;
10902
- const deps = parseDependencies(fields.dependencies);
10903
- if (deps !== void 0) result.dependencies = deps;
10904
- return result;
10905
- }
10906
- function parseDependencies(raw) {
10907
- if (!hasContent(raw)) return void 0;
10908
- const deps = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
10909
- return deps.length > 0 ? deps : void 0;
10910
- }
10911
- function hasContent(value) {
10912
- return value !== void 0 && value.trim().length > 0;
10913
- }
10914
-
10915
- // src/internal/runtime/skills/discover-skills.ts
10916
- async function discoverSkills(dir, options) {
10917
- let entries;
10918
- try {
10919
- entries = await readWorkspaceDir(dir, "skills_read_error", "skills directory");
10920
- } catch {
10921
- return [];
10922
- }
10923
- const skills = [];
10924
- for (const entry of entries) {
10925
- if (!entry.isDirectory()) continue;
10926
- let skillDir;
10927
- try {
10928
- skillDir = safePathJoin(dir, entry.name);
10929
- assertNoSymlinkEscape(skillDir, dir);
10930
- } catch {
10931
- continue;
10932
- }
10933
- const skillPath = path.join(skillDir, "SKILL.md");
10934
- let raw;
10935
- try {
10936
- raw = await promises.readFile(skillPath, "utf8");
10937
- } catch {
10938
- continue;
10939
- }
10940
- const skill = tryParseSkill(raw, entry.name, skillPath, options);
10941
- if (skill !== void 0) skills.push(skill);
10942
- }
10943
- return skills;
10944
- }
10945
- function tryParseSkill(raw, fallbackName, source, options) {
10946
- try {
10947
- const frontmatter = parseSkillFrontmatter(raw, fallbackName);
10948
- const skill = {
10949
- name: frontmatter.name,
10950
- description: frontmatter.description,
10951
- source
10952
- };
10953
- if (frontmatter.category !== void 0) skill.category = frontmatter.category;
10954
- if (frontmatter.dependencies !== void 0) skill.dependencies = frontmatter.dependencies;
10955
- return skill;
10956
- } catch (cause) {
10957
- if (cause instanceof exports.ConfigurationError) {
10958
- options?.onInvalidSkill?.({
10959
- name: fallbackName,
10960
- source,
10961
- code: cause.code ?? "unknown",
10962
- message: cause.message
10963
- });
10964
- return void 0;
10965
- }
10966
- throw cause;
10967
- }
10968
- }
10969
-
10970
- // src/internal/runtime/skills/skills-manager.ts
10971
- var SkillsManager = class {
10972
- constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
10973
- this.cwd = cwd;
10974
- this.settingSourcesIncludeProject = settingSourcesIncludeProject;
10975
- this.skillsDir = skillsDir;
10976
- this.inline = inline;
10977
- }
10978
- cwd;
10979
- settingSourcesIncludeProject;
10980
- skillsDir;
10981
- inline;
10982
- skills = [];
10983
- async initialize() {
10984
- if (!this.settingSourcesIncludeProject) {
10985
- this.skills = this.mergeInline([]);
10986
- return;
10987
- }
10988
- await this.refresh();
10989
- }
10990
- async refresh() {
10991
- const skillsRoot = this.skillsDir ?? path.join(this.cwd, ".theokit", "skills");
10992
- const discovered = await discoverSkills(skillsRoot, {
10993
- onInvalidSkill: (info) => {
10994
- process.stderr.write(
10995
- `[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
10996
- `
10997
- );
10998
- }
10999
- });
11000
- this.skills = this.mergeInline(discovered);
11001
- }
11002
- /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
11003
- mergeInline(discovered) {
11004
- if (this.inline === void 0 || this.inline.length === 0) return discovered;
11005
- const inlineNames = new Set(this.inline.map((s) => s.name));
11006
- return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
11007
- }
11008
- list() {
11009
- return Promise.resolve(this.skills);
11010
- }
11011
- };
11012
-
11013
11069
  // src/internal/runtime/local-agent/local-agent-bootstrap.ts
11014
11070
  function registerLocalAgent(args) {
11015
11071
  registerAgent({
@@ -11045,16 +11101,23 @@ function bootstrapSubmanagers(args) {
11045
11101
  );
11046
11102
  }
11047
11103
  if (args.options.skills !== void 0 || args.settingSourcesIncludeProject) {
11104
+ const staticSkills = typeof args.options.skills === "function" ? void 0 : args.options.skills;
11048
11105
  out.skillsManager = new SkillsManager(
11049
11106
  args.workspaceCwd,
11050
- args.options.skills?.enabled,
11107
+ staticSkills?.enabled,
11051
11108
  args.settingSourcesIncludeProject,
11052
11109
  // M22 — custom skills directory + inline (code-defined) skills.
11053
- args.options.skills?.skillsDir,
11054
- args.options.skills?.inline
11110
+ staticSkills?.skillsDir,
11111
+ staticSkills?.inline
11055
11112
  );
11056
11113
  const localSkills = out.skillsManager;
11057
- out.skills = { list: () => localSkills.list() };
11114
+ out.skills = {
11115
+ // Project to the public shape (name + description only). Inline skills carry
11116
+ // their body + references on the object; `list()` must never leak them —
11117
+ // the body is reachable exclusively through `get()`.
11118
+ list: async () => (await localSkills.list()).map((s) => ({ name: s.name, description: s.description })),
11119
+ get: (name) => localSkills.get(name)
11120
+ };
11058
11121
  }
11059
11122
  if (args.options.plugins !== void 0 || args.settingSourcesIncludePlugins) {
11060
11123
  out.pluginsManager = new PluginsManager(
@@ -15788,6 +15851,7 @@ function levenshtein(a, b) {
15788
15851
  }
15789
15852
 
15790
15853
  // src/internal/runtime/local-agent/real-local-run.ts
15854
+ init_async_local_storage();
15791
15855
  function createRealLocalRun(options) {
15792
15856
  const { userText, id, startTime } = prepareRunContext(options.message);
15793
15857
  const supported = /* @__PURE__ */ new Set(["stream", "wait", "cancel", "conversation"]);
@@ -15899,6 +15963,7 @@ function buildLoopInputs(options, runId, userText) {
15899
15963
  ...options.onStep !== void 0 ? { onStep: options.onStep } : {},
15900
15964
  ...options.onDelta !== void 0 ? { onDelta: options.onDelta } : {},
15901
15965
  ...options.sendOptions.toolChoice !== void 0 ? { toolChoice: options.sendOptions.toolChoice } : {},
15966
+ ...options.sendOptions.activeTools !== void 0 ? { activeTools: options.sendOptions.activeTools } : {},
15902
15967
  ...options.priorMessages !== void 0 ? { priorMessages: options.priorMessages } : {},
15903
15968
  ...options.memoryTools !== void 0 && options.memoryTools.length > 0 ? { memoryTools: options.memoryTools } : {},
15904
15969
  ...buildCustomToolsInput(
@@ -16029,7 +16094,7 @@ var RealLocalRun = class extends FixtureRunBase {
16029
16094
  }
16030
16095
  async executeAgentLoop(inputs) {
16031
16096
  try {
16032
- const output = await runAgentLoop(inputs);
16097
+ const output = inputs.activeTools !== void 0 ? await withToolWhitelist(new Set(inputs.activeTools), () => runAgentLoop(inputs)) : await runAgentLoop(inputs);
16033
16098
  this.applyAgentLoopOutput(output);
16034
16099
  this.transitionTo(output.finalStatus);
16035
16100
  } catch (cause) {
@@ -17966,7 +18031,7 @@ var LocalAgent = class {
17966
18031
  }
17967
18032
  // biome-ignore format: G8 budget — thin accessor for the assembly inputs.
17968
18033
  assemblyInputs() {
17969
- return { agentId: this.agentId, workspaceCwd: this.workspaceCwd, model: this.model, options: this.options, context: this.context, skillsManager: this.skillsManager, systemPromptPipeline: this.systemPromptPipeline };
18034
+ return { agentId: this.agentId, workspaceCwd: this.workspaceCwd, model: this.model, options: this.options, context: this.context, skillsManager: this.skillsManager, settingSourcesIncludeProject: this.settingSourcesIncludeProject, systemPromptPipeline: this.systemPromptPipeline };
17970
18035
  }
17971
18036
  async resolveSystemPrompt(userText, options, memoryFacts) {
17972
18037
  const base = await resolveSystemPromptForSend(
@@ -19086,7 +19151,8 @@ function createSkill(spec) {
19086
19151
  source: `inline://${spec.name}`,
19087
19152
  instructions: spec.instructions,
19088
19153
  ...spec.category !== void 0 ? { category: spec.category } : {},
19089
- ...spec.dependencies !== void 0 ? { dependencies: spec.dependencies } : {}
19154
+ ...spec.dependencies !== void 0 ? { dependencies: spec.dependencies } : {},
19155
+ ...spec.references !== void 0 ? { references: spec.references } : {}
19090
19156
  };
19091
19157
  }
19092
19158
 
@@ -19513,8 +19579,53 @@ function defineProvider(profile, opts) {
19513
19579
  };
19514
19580
  }
19515
19581
 
19582
+ // src/define-skill-read-tool.ts
19583
+ init_to_json_schema();
19584
+ var SkillReadInputSchema = zod.z.object({
19585
+ name: zod.z.string().min(1, "skill_read: `name` is required.")
19586
+ });
19587
+ function renderSkill(skill) {
19588
+ const parts = [`# Skill: ${skill.name}`, "", skill.instructions];
19589
+ const refs = skill.references;
19590
+ if (refs !== void 0 && Object.keys(refs).length > 0) {
19591
+ parts.push("", "## References");
19592
+ for (const [file, content] of Object.entries(refs)) {
19593
+ parts.push("", `### ${file}`, content);
19594
+ }
19595
+ }
19596
+ return parts.join("\n");
19597
+ }
19598
+ function defineSkillReadTool(skills) {
19599
+ const seen = /* @__PURE__ */ new Set();
19600
+ for (const skill of skills) {
19601
+ if (seen.has(skill.name)) {
19602
+ throw new Error(`defineSkillReadTool: duplicate skill name "${skill.name}".`);
19603
+ }
19604
+ seen.add(skill.name);
19605
+ }
19606
+ return {
19607
+ name: "skill_read",
19608
+ description: "Read a skill's full instructions (and any bundled reference documents) by its name. Use this to load the body of a skill listed in the <skills> block before acting on it.",
19609
+ inputSchema: toJsonSchema(SkillReadInputSchema),
19610
+ handler: (input) => {
19611
+ const { name } = SkillReadInputSchema.parse(input);
19612
+ const skill = skills.find((s) => s.name === name);
19613
+ if (skill === void 0) {
19614
+ const available = skills.map((s) => s.name).join(", ");
19615
+ return `Skill "${name}" not found. Available skills: ${available.length > 0 ? available : "(none)"}.`;
19616
+ }
19617
+ return renderSkill(skill);
19618
+ }
19619
+ };
19620
+ }
19621
+
19516
19622
  // src/define-tool.ts
19517
19623
  init_to_json_schema();
19624
+ function shapeToolResult(spec, out) {
19625
+ const validated = spec.outputSchema === void 0 ? out : spec.outputSchema.parse(out);
19626
+ if (spec.toModelOutput !== void 0) return spec.toModelOutput(validated);
19627
+ return typeof validated === "string" ? validated : JSON.stringify(validated);
19628
+ }
19518
19629
  function defineTool(spec) {
19519
19630
  const inputSchema = toJsonSchema(spec.inputSchema, {
19520
19631
  unrepresentable: "any"
@@ -19529,7 +19640,8 @@ function defineTool(spec) {
19529
19640
  schema: spec.inputSchema
19530
19641
  }).value : input;
19531
19642
  const parsed = spec.inputSchema.parse(raw);
19532
- return await spec.handler(parsed, ctx);
19643
+ const out = await spec.handler(parsed, ctx);
19644
+ return shapeToolResult(spec, out);
19533
19645
  }
19534
19646
  };
19535
19647
  }
@@ -21432,6 +21544,7 @@ exports.createSkill = createSkill;
21432
21544
  exports.createSquad = createSquad;
21433
21545
  exports.definePlugin = definePlugin;
21434
21546
  exports.defineProvider = defineProvider;
21547
+ exports.defineSkillReadTool = defineSkillReadTool;
21435
21548
  exports.defineTool = defineTool;
21436
21549
  exports.emitRunEvent = emitRunEvent;
21437
21550
  exports.extractRawId = extractRawId;