@theokit/sdk 5.4.0 → 5.6.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 (132) hide show
  1. package/CHANGELOG.md +642 -0
  2. package/dist/{agent-AUVD4TI4.cjs → agent-47NS6ZVL.cjs} +13 -13
  3. package/dist/{agent-AUVD4TI4.cjs.map → agent-47NS6ZVL.cjs.map} +1 -1
  4. package/dist/{agent-C1Efo7PI.d.cts → agent-82d_DrCL.d.cts} +33 -2
  5. package/dist/{agent-Bmy2G_ml.d.ts → agent-G6g-uwcB.d.ts} +33 -2
  6. package/dist/{agent-MNINE73R.js → agent-JJZM2VIK.js} +12 -12
  7. package/dist/{agent-MNINE73R.js.map → agent-JJZM2VIK.js.map} +1 -1
  8. package/dist/{chunk-IKBLU7ZS.js → chunk-2UXQASTX.js} +232 -32
  9. package/dist/chunk-2UXQASTX.js.map +1 -0
  10. package/dist/{chunk-VPK6PHIE.cjs → chunk-52FDUJSV.cjs} +8 -8
  11. package/dist/{chunk-VPK6PHIE.cjs.map → chunk-52FDUJSV.cjs.map} +1 -1
  12. package/dist/{chunk-2XRAWOZZ.js → chunk-5NELQ6LB.js} +65 -3
  13. package/dist/chunk-5NELQ6LB.js.map +1 -0
  14. package/dist/{chunk-3FDU5JFE.cjs → chunk-7IZKTQ5G.cjs} +35 -7
  15. package/dist/chunk-7IZKTQ5G.cjs.map +1 -0
  16. package/dist/{chunk-7SZAV6QG.js → chunk-7MMTZBTT.js} +3 -3
  17. package/dist/{chunk-7SZAV6QG.js.map → chunk-7MMTZBTT.js.map} +1 -1
  18. package/dist/{chunk-SADXXGWU.js → chunk-BZ3YMAMP.js} +3 -3
  19. package/dist/{chunk-NQTNSHSB.cjs.map → chunk-BZ3YMAMP.js.map} +1 -1
  20. package/dist/{chunk-LX7SEXOQ.js → chunk-CA5VUAP3.js} +25 -7
  21. package/dist/chunk-CA5VUAP3.js.map +1 -0
  22. package/dist/{chunk-IU5N5224.cjs → chunk-EIOMN5VA.cjs} +8 -8
  23. package/dist/chunk-EIOMN5VA.cjs.map +1 -0
  24. package/dist/{chunk-KWGSBZ2Q.js → chunk-FPIY5CLV.js} +3 -3
  25. package/dist/{chunk-KWGSBZ2Q.js.map → chunk-FPIY5CLV.js.map} +1 -1
  26. package/dist/{chunk-UALC6Q3J.cjs → chunk-GCHZMH42.cjs} +290 -88
  27. package/dist/chunk-GCHZMH42.cjs.map +1 -0
  28. package/dist/{chunk-NQTNSHSB.cjs → chunk-GFFBXSQT.cjs} +5 -5
  29. package/dist/chunk-GFFBXSQT.cjs.map +1 -0
  30. package/dist/{chunk-J6KZE2ZQ.cjs → chunk-HG4UN4MN.cjs} +4 -4
  31. package/dist/{chunk-J6KZE2ZQ.cjs.map → chunk-HG4UN4MN.cjs.map} +1 -1
  32. package/dist/{chunk-N6OOOYFZ.js → chunk-HUDNLFY4.js} +4 -4
  33. package/dist/chunk-HUDNLFY4.js.map +1 -0
  34. package/dist/{chunk-LOHMT36V.cjs → chunk-LD6HASA5.cjs} +65 -2
  35. package/dist/chunk-LD6HASA5.cjs.map +1 -0
  36. package/dist/{chunk-QATRS7JD.cjs → chunk-MYJGWS2J.cjs} +26 -8
  37. package/dist/chunk-MYJGWS2J.cjs.map +1 -0
  38. package/dist/{chunk-XD3FS5OI.js → chunk-N2KAIZ5D.js} +34 -7
  39. package/dist/chunk-N2KAIZ5D.js.map +1 -0
  40. package/dist/{chunk-HW7SEELD.cjs → chunk-QRVS2PRE.cjs} +31 -8
  41. package/dist/chunk-QRVS2PRE.cjs.map +1 -0
  42. package/dist/{chunk-AYA65JA5.cjs → chunk-RWPLWMCZ.cjs} +25 -9
  43. package/dist/chunk-RWPLWMCZ.cjs.map +1 -0
  44. package/dist/{chunk-WS5ULCL4.js → chunk-STGSMJMJ.js} +3 -3
  45. package/dist/{chunk-WS5ULCL4.js.map → chunk-STGSMJMJ.js.map} +1 -1
  46. package/dist/{chunk-O7L7M42F.js → chunk-T3ZDEYTJ.js} +21 -5
  47. package/dist/chunk-T3ZDEYTJ.js.map +1 -0
  48. package/dist/{chunk-43YXGD3P.cjs → chunk-TY56BKSK.cjs} +8 -4
  49. package/dist/chunk-TY56BKSK.cjs.map +1 -0
  50. package/dist/chunk-UOLBAPDM.js +66 -0
  51. package/dist/chunk-UOLBAPDM.js.map +1 -0
  52. package/dist/{chunk-Z2JFX372.cjs → chunk-VUHXC74Q.cjs} +15 -15
  53. package/dist/{chunk-Z2JFX372.cjs.map → chunk-VUHXC74Q.cjs.map} +1 -1
  54. package/dist/{chunk-NSLHPAC7.js → chunk-X7EUUHXU.js} +6 -5
  55. package/dist/chunk-X7EUUHXU.js.map +1 -0
  56. package/dist/context/index.cjs +7 -7
  57. package/dist/context/index.js +3 -3
  58. package/dist/{context-4AIK26QB.cjs → context-HR4KMXMA.cjs} +7 -7
  59. package/dist/{context-4AIK26QB.cjs.map → context-HR4KMXMA.cjs.map} +1 -1
  60. package/dist/context-J5BJ3LBS.js +6 -0
  61. package/dist/{context-EGM6CHXD.js.map → context-J5BJ3LBS.js.map} +1 -1
  62. package/dist/{cron-DSMdlhyF.d.cts → cron-DWv69ZSD.d.cts} +1 -1
  63. package/dist/{cron-Dcdrdv_T.d.ts → cron-GynWtAax.d.ts} +1 -1
  64. package/dist/cron.cjs +12 -12
  65. package/dist/cron.d.cts +2 -2
  66. package/dist/cron.d.ts +2 -2
  67. package/dist/cron.js +11 -11
  68. package/dist/eval.cjs +11 -11
  69. package/dist/eval.js +10 -10
  70. package/dist/{index-manager-W7FDMGEG.js → index-manager-27WLNQEE.js} +5 -5
  71. package/dist/{index-manager-W7FDMGEG.js.map → index-manager-27WLNQEE.js.map} +1 -1
  72. package/dist/{index-manager-3UNPYH34.cjs → index-manager-BBHDKMQS.cjs} +6 -6
  73. package/dist/{index-manager-3UNPYH34.cjs.map → index-manager-BBHDKMQS.cjs.map} +1 -1
  74. package/dist/index.cjs +274 -40
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.d.cts +168 -5
  77. package/dist/index.d.ts +168 -5
  78. package/dist/index.js +246 -23
  79. package/dist/index.js.map +1 -1
  80. package/dist/internal/memory/storage/index.cjs +32 -32
  81. package/dist/internal/memory/storage/index.js +3 -3
  82. package/dist/internal/memory/storage/memory-root.d.cts +27 -0
  83. package/dist/internal/memory/storage/memory-root.d.ts +27 -0
  84. package/dist/internal/persistence/index.cjs +4 -4
  85. package/dist/internal/persistence/index.js +1 -1
  86. package/dist/internal/runtime/compat/foreign-config-sources.d.ts +17 -4
  87. package/dist/internal/runtime/compat/managed-settings.d.ts +80 -0
  88. package/dist/internal/runtime/context/context-discovery-runner.d.ts +14 -0
  89. package/dist/internal/runtime/context/context-discovery.d.ts +37 -0
  90. package/dist/internal/runtime/context/context-manager.d.ts +21 -1
  91. package/dist/internal/runtime/context/yaml-frontmatter.d.ts +6 -3
  92. package/dist/internal/runtime/hooks/hooks-executor.d.ts +23 -1
  93. package/dist/internal/runtime/hooks/hooks-source.d.ts +46 -1
  94. package/dist/internal/runtime/skills/discover-skills.d.ts +4 -0
  95. package/dist/project.cjs +3 -3
  96. package/dist/project.js +1 -1
  97. package/dist/skills.cjs +5 -5
  98. package/dist/skills.js +2 -2
  99. package/dist/subagents-loader-CJFYQQU2.js +7 -0
  100. package/dist/{subagents-loader-AIVDQ2D5.js.map → subagents-loader-CJFYQQU2.js.map} +1 -1
  101. package/dist/subagents-loader-MOO7DC4E.cjs +16 -0
  102. package/dist/{subagents-loader-DN4LETGL.cjs.map → subagents-loader-MOO7DC4E.cjs.map} +1 -1
  103. package/dist/subagents-loader.cjs +4 -4
  104. package/dist/subagents-loader.d.cts +1 -1
  105. package/dist/subagents-loader.d.ts +1 -1
  106. package/dist/subagents-loader.js +3 -3
  107. package/dist/types/agent.d.ts +6 -1
  108. package/dist/types/hooks.d.ts +22 -0
  109. package/docs/error-codes.md +20 -18
  110. package/docs/harness-capability-map.md +9 -1
  111. package/package.json +1 -1
  112. package/dist/chunk-2XRAWOZZ.js.map +0 -1
  113. package/dist/chunk-3FDU5JFE.cjs.map +0 -1
  114. package/dist/chunk-43YXGD3P.cjs.map +0 -1
  115. package/dist/chunk-AYA65JA5.cjs.map +0 -1
  116. package/dist/chunk-HW7SEELD.cjs.map +0 -1
  117. package/dist/chunk-IKBLU7ZS.js.map +0 -1
  118. package/dist/chunk-IU5N5224.cjs.map +0 -1
  119. package/dist/chunk-JNAA4G4H.js +0 -43
  120. package/dist/chunk-JNAA4G4H.js.map +0 -1
  121. package/dist/chunk-LOHMT36V.cjs.map +0 -1
  122. package/dist/chunk-LX7SEXOQ.js.map +0 -1
  123. package/dist/chunk-N6OOOYFZ.js.map +0 -1
  124. package/dist/chunk-NSLHPAC7.js.map +0 -1
  125. package/dist/chunk-O7L7M42F.js.map +0 -1
  126. package/dist/chunk-QATRS7JD.cjs.map +0 -1
  127. package/dist/chunk-SADXXGWU.js.map +0 -1
  128. package/dist/chunk-UALC6Q3J.cjs.map +0 -1
  129. package/dist/chunk-XD3FS5OI.js.map +0 -1
  130. package/dist/context-EGM6CHXD.js +0 -6
  131. package/dist/subagents-loader-AIVDQ2D5.js +0 -7
  132. package/dist/subagents-loader-DN4LETGL.cjs +0 -16
package/dist/index.js CHANGED
@@ -1,27 +1,27 @@
1
1
  export { StreamObjectError } from './chunk-5WKQDIGO.js';
2
2
  export { GOAL_CONTINUATION_MARKER } from './chunk-PY2RQOA7.js';
3
3
  export { JudgeCredentialError } from './chunk-IUMAQURF.js';
4
- import { migrateSqliteToLance, appendDiaryEntry } from './chunk-WS5ULCL4.js';
4
+ import { migrateSqliteToLance, appendDiaryEntry } from './chunk-STGSMJMJ.js';
5
5
  export { GenerateObjectError } from './chunk-44I6UYVH.js';
6
6
  import './chunk-47TF32NQ.js';
7
7
  import { Workflow, agentStep } from './chunk-HFEJE7AC.js';
8
8
  export { Workflow, agentStep, fn } from './chunk-HFEJE7AC.js';
9
9
  import './chunk-GBCVPKHE.js';
10
10
  import './chunk-HY66GLM6.js';
11
- export { Cron } from './chunk-KWGSBZ2Q.js';
12
- import { MEMORY_EMBEDDING_ADAPTERS, resolveSessionDir, DEFAULT_AGENTIC_MODEL_ID, Agent } from './chunk-IKBLU7ZS.js';
13
- export { Agent, AgentBuilder, Tool, ToolError, UsageAccumulator, computeCost, getPricingEntry } from './chunk-IKBLU7ZS.js';
11
+ export { Cron } from './chunk-FPIY5CLV.js';
12
+ import { MEMORY_EMBEDDING_ADAPTERS, resolveSessionDir, DEFAULT_AGENTIC_MODEL_ID, Agent } from './chunk-2UXQASTX.js';
13
+ export { Agent, AgentBuilder, Tool, ToolError, UsageAccumulator, computeCost, getPricingEntry, managedSettingsPathFor, readManagedSettings } from './chunk-2UXQASTX.js';
14
14
  import { configure, submit, list, get, cancel, subscribe } from './chunk-K2VMFZQ5.js';
15
15
  export { emitRunEvent } from './chunk-K2VMFZQ5.js';
16
16
  import './chunk-2QKV4CGK.js';
17
17
  import './chunk-K2BQQ445.js';
18
- import './chunk-7SZAV6QG.js';
19
- import './chunk-XD3FS5OI.js';
18
+ import './chunk-7MMTZBTT.js';
19
+ import './chunk-N2KAIZ5D.js';
20
20
  import './chunk-2SFBB54R.js';
21
21
  import './chunk-55GB6JYQ.js';
22
22
  import './chunk-H73MEMQB.js';
23
23
  import './chunk-OR6XIWLB.js';
24
- import { resolveMemoryRoot, readFactsFromMarkdown } from './chunk-SADXXGWU.js';
24
+ import { resolveMemoryRoot, readFactsFromMarkdown } from './chunk-BZ3YMAMP.js';
25
25
  import { FsSessionStore } from './chunk-AAEZSPTC.js';
26
26
  import { discoverProviderPlugins, shouldUseFixtureMode, isFixtureApiKey, httpRequest, mapOllamaTransportError, readErrorResponseBody, mapOllamaHttpError } from './chunk-KZSKIUXZ.js';
27
27
  import './chunk-UBR5PWD7.js';
@@ -30,7 +30,7 @@ import './chunk-XB4GI5RZ.js';
30
30
  import './chunk-24MGQDK3.js';
31
31
  import { readSessionMessages } from './chunk-2WXHA33T.js';
32
32
  import './chunk-HKCKOAIO.js';
33
- import './chunk-N6OOOYFZ.js';
33
+ import './chunk-HUDNLFY4.js';
34
34
  import './chunk-KVNWIAO4.js';
35
35
  import './chunk-SVQIW5RJ.js';
36
36
  import './chunk-FD2UT76F.js';
@@ -39,8 +39,8 @@ import './chunk-FJWQP6EE.js';
39
39
  import './chunk-NAF4L3T6.js';
40
40
  import './chunk-CFE6QF2Q.js';
41
41
  import './chunk-6X6ID4MO.js';
42
- import './chunk-LX7SEXOQ.js';
43
- import './chunk-2XRAWOZZ.js';
42
+ import { stripSkillFrontmatter } from './chunk-CA5VUAP3.js';
43
+ import './chunk-5NELQ6LB.js';
44
44
  import './chunk-SAGRF4IB.js';
45
45
  import './chunk-EH6XD3FY.js';
46
46
  import './chunk-UKMBRMGT.js';
@@ -55,9 +55,9 @@ import { withCwdMutex } from './chunk-Q5EWJPRY.js';
55
55
  export { withCwdMutex } from './chunk-Q5EWJPRY.js';
56
56
  export { TASK_RESERVED_PREFIXES, isValidTaskId } from './chunk-EIQFAOFD.js';
57
57
  import { replaceFileAtomic } from './chunk-3JHIFQ4I.js';
58
- import './chunk-O7L7M42F.js';
59
- import './chunk-NSLHPAC7.js';
60
- import './chunk-JNAA4G4H.js';
58
+ import './chunk-T3ZDEYTJ.js';
59
+ import { CLAUDE_DIR_NAME, THEOKIT_DIR_LITERAL } from './chunk-X7EUUHXU.js';
60
+ import './chunk-UOLBAPDM.js';
61
61
  import { estimateTokens, CHARS_PER_TOKEN } from './chunk-6M2OIS4Y.js';
62
62
  export { estimateTokens } from './chunk-6M2OIS4Y.js';
63
63
  import { parseModelId } from './chunk-R7WIIPUR.js';
@@ -72,9 +72,10 @@ export { AgentDisposedError, AgentRunError, AuthenticationError, BudgetExceededE
72
72
  import { diag, redactSecrets, addPattern, resolveApiKey } from './chunk-CZJ6Q7CW.js';
73
73
  export { setDiagnosticsSink } from './chunk-CZJ6Q7CW.js';
74
74
  import { createHash, randomUUID } from 'crypto';
75
+ import { readFile, mkdir, readdir } from 'fs/promises';
76
+ import { resolve, normalize, sep, isAbsolute, parse, relative, dirname, join } from 'path';
75
77
  import { z } from 'zod';
76
- import { mkdir } from 'fs/promises';
77
- import { join } from 'path';
78
+ import { homedir } from 'os';
78
79
 
79
80
  // src/agent-factory.ts
80
81
  function createAgentFactory(common) {
@@ -691,12 +692,43 @@ var Provider = class _Provider {
691
692
  return _Provider.builtins().find((p) => p.name === provider);
692
693
  }
693
694
  };
695
+ async function resolveBody(skill) {
696
+ if (typeof skill.instructions === "string") {
697
+ const inline = skill;
698
+ return inline.references === void 0 ? { instructions: inline.instructions } : { instructions: inline.instructions, references: inline.references };
699
+ }
700
+ const source = skill.source;
701
+ const skillDir = dirname(source);
702
+ const body = stripSkillFrontmatter(await readFile(source, "utf8"));
703
+ const instructions = body.replaceAll(SKILL_DIR_PLACEHOLDER, skillDir);
704
+ const references = await readReferences(skillDir);
705
+ return references === void 0 ? { instructions } : { instructions, references };
706
+ }
707
+ var SKILL_DIR_PLACEHOLDER = "${CLAUDE_SKILL_DIR}";
708
+ async function readReferences(skillDir) {
709
+ const dir = join(skillDir, "references");
710
+ let names;
711
+ try {
712
+ names = await readdir(dir);
713
+ } catch {
714
+ return void 0;
715
+ }
716
+ const refs = {};
717
+ for (const name of names) {
718
+ try {
719
+ refs[name] = await readFile(join(dir, name), "utf8");
720
+ } catch {
721
+ }
722
+ }
723
+ return Object.keys(refs).length > 0 ? refs : void 0;
724
+ }
694
725
  var SkillReadInputSchema = z.object({
695
726
  name: z.string().min(1, "skill_read: `name` is required.")
696
727
  });
697
- function renderSkill(skill) {
698
- const parts = [`# Skill: ${skill.name}`, "", skill.instructions];
699
- const refs = skill.references;
728
+ async function renderSkill(skill) {
729
+ const { instructions, references } = await resolveBody(skill);
730
+ const parts = [`# Skill: ${skill.name}`, "", instructions];
731
+ const refs = references;
700
732
  if (refs !== void 0 && Object.keys(refs).length > 0) {
701
733
  parts.push("", "## References");
702
734
  for (const [file, content] of Object.entries(refs)) {
@@ -719,6 +751,11 @@ function defineSkillReadTool(skills) {
719
751
  name: "skill_read",
720
752
  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.",
721
753
  inputSchema: toJsonSchema(SkillReadInputSchema),
754
+ // NOT `async`. Marking the whole handler async turns the schema's SYNCHRONOUS throw into a
755
+ // rejected promise, and this module's contract is that malformed input "fails at the trust
756
+ // boundary via the schema" — measured, two trust-boundary tests went from throwing to
757
+ // returning `undefined`. Only the body read needs to be asynchronous, so only it returns a
758
+ // promise: parse and the not-found answer stay exactly as synchronous as they were.
722
759
  handler: (input) => {
723
760
  const { name } = SkillReadInputSchema.parse(input);
724
761
  const skill = skills.find((s) => s.name === name);
@@ -1028,10 +1065,10 @@ var JobQueue = class {
1028
1065
  this.running += 1;
1029
1066
  return Promise.resolve();
1030
1067
  }
1031
- return new Promise((resolve) => {
1068
+ return new Promise((resolve2) => {
1032
1069
  this.waiting.push(() => {
1033
1070
  this.running += 1;
1034
- resolve();
1071
+ resolve2();
1035
1072
  });
1036
1073
  });
1037
1074
  }
@@ -1339,7 +1376,7 @@ var Memory = {
1339
1376
  openArgs.embedding = await resolveEmbedding(opts.embedding, peer.MEMORY_EMBEDDING_ADAPTERS);
1340
1377
  return await peer.IndexManager.open(openArgs);
1341
1378
  }
1342
- const { IndexManager } = await import('./index-manager-W7FDMGEG.js');
1379
+ const { IndexManager } = await import('./index-manager-27WLNQEE.js');
1343
1380
  openArgs.embedding = await resolveEmbedding(opts.embedding, MEMORY_EMBEDDING_ADAPTERS);
1344
1381
  return await IndexManager.open(openArgs);
1345
1382
  },
@@ -1484,6 +1521,111 @@ var PermissionEngine = class {
1484
1521
  return true;
1485
1522
  }
1486
1523
  };
1524
+ var PROTECTED_SEGMENTS = [
1525
+ ".git",
1526
+ // The two agent-configuration directories come from the dialect declarations rather than being
1527
+ // spelled again here. A second copy of `.theokit` would drift from the one `paths.ts` resolves
1528
+ // against, and this list would then protect a directory the runtime no longer uses — worse than
1529
+ // not protecting it, because the gap would be invisible.
1530
+ CLAUDE_DIR_NAME,
1531
+ THEOKIT_DIR_LITERAL,
1532
+ ".ssh",
1533
+ ".gnupg"
1534
+ ];
1535
+ var PROTECTED_FILES = [
1536
+ ".envrc",
1537
+ ".npmrc",
1538
+ ".mcp.json",
1539
+ ".pre-commit-config.yaml",
1540
+ ".netrc"
1541
+ ];
1542
+ var WRITING_TOOLS = /^(write|edit|apply_?patch|multi_?edit|notebook_?edit|create)/i;
1543
+ var PATH_ARGS = ["file_path", "path", "notebook_path"];
1544
+ var COMMAND_ARGS = ["command", "cmd"];
1545
+ function permissionFloorReason(toolName, args, context = {}) {
1546
+ const cwd = resolve(context.cwd ?? process.cwd());
1547
+ const home = resolve(context.home ?? homedir());
1548
+ const command = firstString(args, COMMAND_ARGS);
1549
+ if (command !== void 0) {
1550
+ const target = destructiveTargetIn(command, { cwd, home });
1551
+ if (target !== void 0) {
1552
+ return `refused by the critical-path floor: "${command}" is a destructive operation on ${target}. This tier is above every permission rule and every mode \u2014 it is not a rule you can reorder, and nothing in your settings is misconfigured.`;
1553
+ }
1554
+ }
1555
+ if (!WRITING_TOOLS.test(toolName)) return void 0;
1556
+ const path = firstString(args, PATH_ARGS);
1557
+ if (path === void 0) return void 0;
1558
+ const protectedBy = protectedReasonFor(path);
1559
+ if (protectedBy !== void 0) {
1560
+ return `refused by the protected-path floor: writing "${path}" would change ${protectedBy}, which no allow rule can pre-approve. This tier is above every permission rule; nothing in your settings is misconfigured.`;
1561
+ }
1562
+ return void 0;
1563
+ }
1564
+ function firstString(args, names) {
1565
+ if (args === void 0) return void 0;
1566
+ for (const name of names) {
1567
+ const v = args[name];
1568
+ if (typeof v === "string") return v;
1569
+ }
1570
+ return void 0;
1571
+ }
1572
+ function protectedReasonFor(path) {
1573
+ const segments = normalize(path).split(/[\\/]+/).filter((s) => s.length > 0);
1574
+ for (const segment of segments) {
1575
+ if (PROTECTED_SEGMENTS.includes(segment)) return `the ${segment} directory`;
1576
+ }
1577
+ const last = segments.at(-1);
1578
+ if (last !== void 0 && PROTECTED_FILES.includes(last)) return `the ${last} file`;
1579
+ return void 0;
1580
+ }
1581
+ var DESTRUCTIVE = /(?:^|[;&|])\s*(rm|rmdir|shred|mkfs(?:\.[\w.-]{1,32})?|dd)\s/;
1582
+ function destructiveTargetIn(command, roots) {
1583
+ if (!DESTRUCTIVE.test(command)) return void 0;
1584
+ if (SUBSTITUTES.test(command)) {
1585
+ return "a target this floor cannot resolve (the command substitutes or expands it)";
1586
+ }
1587
+ const critical = criticalRootsFor(roots);
1588
+ for (const token of command.split(/\s+/)) {
1589
+ const target = absoluteTargetOf(token, roots.home);
1590
+ const hit = target === void 0 ? void 0 : critical.get(target);
1591
+ if (hit !== void 0) return hit;
1592
+ }
1593
+ return void 0;
1594
+ }
1595
+ var SUBSTITUTES = /\$\(|`|\$\{?\w/;
1596
+ function criticalRootsFor(roots) {
1597
+ const map = /* @__PURE__ */ new Map([
1598
+ [resolve("/"), "the filesystem root"],
1599
+ [roots.home, "the home directory"]
1600
+ ]);
1601
+ for (const parent of ancestorsOf(roots.cwd)) {
1602
+ map.set(parent, "a parent of the working directory");
1603
+ }
1604
+ map.set(roots.cwd, "the working directory");
1605
+ return map;
1606
+ }
1607
+ function absoluteTargetOf(token, home) {
1608
+ const bare = token.replace(/["']/g, "").replace(/\/\*+$/, "");
1609
+ if (bare.length === 0 || bare.startsWith("-")) return void 0;
1610
+ const expanded = bare === "~" || bare.startsWith(`~${sep}`) ? home : bare;
1611
+ return isAbsolute(expanded) ? resolve(expanded) : void 0;
1612
+ }
1613
+ function ancestorsOf(dir) {
1614
+ const out = [];
1615
+ let current = dir;
1616
+ const { root } = parse(dir);
1617
+ while (current !== root) {
1618
+ const parent = resolve(current, "..");
1619
+ if (parent === current) break;
1620
+ out.push(parent);
1621
+ current = parent;
1622
+ }
1623
+ return out;
1624
+ }
1625
+ function isInside(parent, child) {
1626
+ const rel = relative(resolve(parent), resolve(child));
1627
+ return rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
1628
+ }
1487
1629
 
1488
1630
  // src/permission-plugin.ts
1489
1631
  async function resolveAsk(opts, name, args, mode) {
@@ -1507,6 +1649,8 @@ function createPermissionPlugin(engine, opts = {}) {
1507
1649
  ctx.on("pre_tool_call", async (rawCtx) => {
1508
1650
  const { name, args, permissionMode } = rawCtx;
1509
1651
  const mode = permissionMode ?? opts.mode ?? "default";
1652
+ const floor = permissionFloorReason(name, args, {});
1653
+ if (floor !== void 0) return { block: true, message: floor };
1510
1654
  const action = engine.evaluate(name, args, mode);
1511
1655
  if (action === "deny") {
1512
1656
  return { block: true, message: `denied by permission engine: ${name}` };
@@ -1525,6 +1669,85 @@ var PermissionPlugin = class {
1525
1669
  }
1526
1670
  };
1527
1671
 
1672
+ // src/permission-rules.ts
1673
+ var PRIMARY_ARG_NAMES = ["command", "file_path", "path", "url", "query"];
1674
+ function parsePermissionRules(set) {
1675
+ return [
1676
+ ...(set.deny ?? []).flatMap((r) => parseOne(r, "deny")),
1677
+ ...(set.ask ?? []).flatMap((r) => parseOne(r, "ask")),
1678
+ ...(set.allow ?? []).flatMap((r) => parseOne(r, "allow"))
1679
+ ];
1680
+ }
1681
+ function parseOne(rule, action) {
1682
+ const trimmed = rule.trim();
1683
+ const open = trimmed.indexOf("(");
1684
+ if (open === -1) {
1685
+ if (trimmed.length === 0) {
1686
+ throw new ConfigurationError("permission rule is empty", { code: "permission_rule_invalid" });
1687
+ }
1688
+ return [{ tool: normaliseToolName(trimmed), action }];
1689
+ }
1690
+ if (!trimmed.endsWith(")")) {
1691
+ throw new ConfigurationError(
1692
+ `permission rule "${rule}" opens a specifier and never closes it \u2014 expected Tool(specifier)`,
1693
+ { code: "permission_rule_invalid" }
1694
+ );
1695
+ }
1696
+ const tool = trimmed.slice(0, open).trim();
1697
+ const specifier = trimmed.slice(open + 1, -1);
1698
+ if (tool.length === 0) {
1699
+ throw new ConfigurationError(`permission rule "${rule}" names no tool`, {
1700
+ code: "permission_rule_invalid"
1701
+ });
1702
+ }
1703
+ if (specifier === "*") return [{ tool: normaliseToolName(tool), action }];
1704
+ const test = predicateFor(specifier);
1705
+ const name = normaliseToolName(tool);
1706
+ return PRIMARY_ARG_NAMES.map((arg) => ({ tool: name, action, args: { [arg]: test } }));
1707
+ }
1708
+ function normaliseToolName(tool) {
1709
+ if (!tool.startsWith("mcp__")) return tool;
1710
+ return `mcp_${tool.slice("mcp__".length).replaceAll("__", "_")}`;
1711
+ }
1712
+ function predicateFor(specifier) {
1713
+ if (specifier.startsWith("path:")) {
1714
+ const re = globToRegExp(specifier.slice("path:".length));
1715
+ return (v) => typeof v === "string" && re.test(v);
1716
+ }
1717
+ if (specifier.startsWith("domain:")) {
1718
+ const host = specifier.slice("domain:".length).toLowerCase();
1719
+ return (v) => typeof v === "string" && hostOf(v) === host;
1720
+ }
1721
+ if (specifier.endsWith("*")) {
1722
+ const prefix = specifier.slice(0, -1);
1723
+ return (v) => typeof v === "string" && v.startsWith(prefix);
1724
+ }
1725
+ return (v) => v === specifier;
1726
+ }
1727
+ function hostOf(value) {
1728
+ try {
1729
+ return new URL(value).hostname.toLowerCase();
1730
+ } catch {
1731
+ return void 0;
1732
+ }
1733
+ }
1734
+ function translateGlobChar(glob, i) {
1735
+ const c = glob[i] ?? "";
1736
+ if (c === "?") return { pattern: "[^/]", consumed: 0 };
1737
+ if (c !== "*") return { pattern: c.replace(/[.+^${}()|[\]\\]/g, "\\$&"), consumed: 0 };
1738
+ if (glob[i + 1] !== "*") return { pattern: "[^/]*", consumed: 0 };
1739
+ return { pattern: ".*", consumed: glob[i + 2] === "/" ? 2 : 1 };
1740
+ }
1741
+ function globToRegExp(glob) {
1742
+ let out = "";
1743
+ for (let i = 0; i < glob.length; i += 1) {
1744
+ const piece = translateGlobChar(glob, i);
1745
+ out += piece.pattern;
1746
+ i += piece.consumed;
1747
+ }
1748
+ return new RegExp(`^${out}$`);
1749
+ }
1750
+
1528
1751
  // src/project-env.ts
1529
1752
  var SOVEREIGN_ENV_KEYS = [
1530
1753
  /** Locates the SDK home — sessions, and the credential store beneath it. */
@@ -1792,7 +2015,7 @@ function isBuiltAgent(m) {
1792
2015
  return typeof m.send === "function";
1793
2016
  }
1794
2017
  async function materialize(def, index) {
1795
- const { Agent: Agent2 } = await import('./agent-MNINE73R.js');
2018
+ const { Agent: Agent2 } = await import('./agent-JJZM2VIK.js');
1796
2019
  return Agent2.create({
1797
2020
  // `AgentDefinition.model` admits the sentinel `'inherit'`, which is not a model id. Inheriting
1798
2021
  // here means "declare nothing and let the default apply" — forwarding the literal would create
@@ -2326,6 +2549,6 @@ function recordWiring(input) {
2326
2549
  return record;
2327
2550
  }
2328
2551
 
2329
- export { AgentFactory, Budget, EventBus, JobQueue, LayerOrderError, LiveSessionError, Memory, NoopMemoryProvider, PermissionEngine, PermissionPlugin, Plugin, Provider, RetentionPolicyError, SOVEREIGN_ENV_KEYS, Security, Skill, SkillReadTool, Squad, Task, Theokit, TokenLimiter, UngatedCapabilityError, UnicodeNormalizer, applyMode, applySecurityFloor, auditEnvReachability, chargeAndCheckThresholds, createCounterBudgetTracker, decideApproval, describeAction, describeCredential, effectiveToolNames, evaluateBlastRadius, extractRawId, foldLayers, guardSessionDestruction, inferApiMode, loadProjectEnv, migrateSqliteToLance2 as migrateSqliteToLance, mkMemoryId, normalizeSchema, normalizeUsage, planReaping, preflightCheck, readSessionMessages2 as readSessionMessages, recordWiring, resolveTrustPosture, runGoalLoop, scopedConversationId, sessionScopePrefix, toShareGptTrajectory, verifyLayerOrdering, withBlastRadius };
2552
+ export { AgentFactory, Budget, EventBus, JobQueue, LayerOrderError, LiveSessionError, Memory, NoopMemoryProvider, PermissionEngine, PermissionPlugin, Plugin, Provider, RetentionPolicyError, SOVEREIGN_ENV_KEYS, Security, Skill, SkillReadTool, Squad, Task, Theokit, TokenLimiter, UngatedCapabilityError, UnicodeNormalizer, applyMode, applySecurityFloor, auditEnvReachability, chargeAndCheckThresholds, createCounterBudgetTracker, decideApproval, describeAction, describeCredential, effectiveToolNames, evaluateBlastRadius, extractRawId, foldLayers, guardSessionDestruction, inferApiMode, isInside, loadProjectEnv, migrateSqliteToLance2 as migrateSqliteToLance, mkMemoryId, normalizeSchema, normalizeUsage, parsePermissionRules, permissionFloorReason, planReaping, preflightCheck, readSessionMessages2 as readSessionMessages, recordWiring, resolveTrustPosture, runGoalLoop, scopedConversationId, sessionScopePrefix, toShareGptTrajectory, verifyLayerOrdering, withBlastRadius };
2330
2553
  //# sourceMappingURL=index.js.map
2331
2554
  //# sourceMappingURL=index.js.map