@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
@@ -1,21 +1,21 @@
1
1
  import { submit, emitRunEvent } from './chunk-K2VMFZQ5.js';
2
2
  import { enqueueSessionWrite, hydrateSession, persistTurnToTranscript, flushSessionWrites, appendSessionMessage, getSessionMessages, discardSession, clearSession } from './chunk-2QKV4CGK.js';
3
- import { IndexManager } from './chunk-7SZAV6QG.js';
4
- import { loadHookConfig, warnOnce, currentPersonalityContext, warnPersonalitySwitchInsideFork } from './chunk-XD3FS5OI.js';
3
+ import { IndexManager } from './chunk-7MMTZBTT.js';
4
+ import { warnFailureOnce, loadHookConfig, warnOnce, currentPersonalityContext, warnPersonalitySwitchInsideFork } from './chunk-N2KAIZ5D.js';
5
5
  import { extractCodePlugins } from './chunk-2SFBB54R.js';
6
6
  import { createOpenAiCompatibleRuntime } from './chunk-55GB6JYQ.js';
7
7
  import { persistActiveMemoryTranscript } from './chunk-OR6XIWLB.js';
8
- import { writeSessionSummary, resolveMemoryRoot, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-SADXXGWU.js';
8
+ import { writeSessionSummary, resolveMemoryRoot, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-BZ3YMAMP.js';
9
9
  import { FsSessionStore } from './chunk-AAEZSPTC.js';
10
10
  import { discoverProviderPlugins, validateApiKeyShape, getConfiguredBaseUrl, httpRequest, isFixtureApiKey, presentProviderCredentialEnvVars, buildDefaultSummarizer, shouldUseRealLocalRuntime, parseSseStream, CircuitBreaker, resolveRunProvider, mergeExplicitApiKey, resolveProviderChain, abortError, tryFirstEvent, relayStream, renderToolResultContentText } from './chunk-KZSKIUXZ.js';
11
11
  import { resolveChildEnv } from './chunk-HKCKOAIO.js';
12
- import { DEFAULT_MAX_BYTES_PER_FILE, runDiscovery, truncateWithMarker } from './chunk-N6OOOYFZ.js';
12
+ import { DEFAULT_MAX_BYTES_PER_FILE, runDiscovery, truncateWithMarker } from './chunk-HUDNLFY4.js';
13
13
  import { readVersionedJson, writeVersionedJson } from './chunk-SVQIW5RJ.js';
14
14
  import { toJsonSchema } from './chunk-7I5Z3UBJ.js';
15
15
  import { sanitizeToolInput } from './chunk-FJWQP6EE.js';
16
16
  import { withInheritedSubAgentCredentials, subAgentToolsFromDefinitions } from './chunk-CFE6QF2Q.js';
17
17
  import { setAgentFacade } from './chunk-6X6ID4MO.js';
18
- import { escapeBlockBody, buildSkillsBlock, discoverSkills, stripSkillFrontmatter } from './chunk-LX7SEXOQ.js';
18
+ import { escapeBlockBody, buildSkillsBlock, discoverSkills, stripSkillFrontmatter } from './chunk-CA5VUAP3.js';
19
19
  import { withToolWhitelist, checkToolWhitelist } from './chunk-SAGRF4IB.js';
20
20
  import { validateArtifactPath, PathTraversalError, safePathJoin } from './chunk-EH6XD3FY.js';
21
21
  import { insideRoot, atOrInsideRoot } from './chunk-UKMBRMGT.js';
@@ -24,9 +24,9 @@ import { expandTilde, defaultBaseDir } from './chunk-JOFVLOFY.js';
24
24
  import { withFileLock } from './chunk-TA3K7SBK.js';
25
25
  import { withCwdMutex } from './chunk-Q5EWJPRY.js';
26
26
  import { sweepStaleAtomicTemps, atomicWriteJson } from './chunk-3JHIFQ4I.js';
27
- import { loadSubagents, pluginBundleDirs } from './chunk-O7L7M42F.js';
28
- import { reportUndeclaredSources, theokitConfigRoot, undefinedVariablesIn, getTheokitHome, adapterForConfigPath, projectConfigRoots, pluginBundleRoots } from './chunk-NSLHPAC7.js';
29
- import { readWorkspaceDir, parseSimpleYaml } from './chunk-JNAA4G4H.js';
27
+ import { loadSubagents, pluginBundleDirs } from './chunk-T3ZDEYTJ.js';
28
+ import { reportUndeclaredSources, theokitConfigRoot, undefinedVariablesIn, getTheokitHome, adapterForConfigPath, adaptersForSurface, projectConfigRoots, pluginBundleRoots } from './chunk-X7EUUHXU.js';
29
+ import { readWorkspaceDir, parseSimpleYaml } from './chunk-UOLBAPDM.js';
30
30
  import { resolveEffectiveContextWindow, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN } from './chunk-6M2OIS4Y.js';
31
31
  import { parseModelId } from './chunk-R7WIIPUR.js';
32
32
  import { getProviderProfile } from './chunk-XYFGKVZ7.js';
@@ -38,6 +38,7 @@ import { stat, mkdir, readFile, readdir, access, unlink } from 'fs/promises';
38
38
  import { randomUUID, createHash } from 'crypto';
39
39
  import { join, dirname, resolve, relative, isAbsolute } from 'path';
40
40
  import { existsSync, readFileSync } from 'fs';
41
+ import { platform } from 'process';
41
42
  import { spawn } from 'child_process';
42
43
  import { z } from 'zod';
43
44
  import { createRequire } from 'module';
@@ -2550,6 +2551,116 @@ function readCompatConfigFile(cwd) {
2550
2551
  function resolveCompatSources(options, cwd) {
2551
2552
  return options.local?.compatSources ?? readCompatConfigFile(cwd);
2552
2553
  }
2554
+ var KNOWN_KEYS = /* @__PURE__ */ new Set([
2555
+ "disableAllHooks",
2556
+ "disableSkillShellExecution",
2557
+ "permissions",
2558
+ "permissionMode"
2559
+ ]);
2560
+ function managedSettingsPathFor(root) {
2561
+ if (root !== void 0) return join(root, "claude-code", "managed-settings.json");
2562
+ if (platform === "darwin") {
2563
+ return "/Library/Application Support/ClaudeCode/managed-settings.json";
2564
+ }
2565
+ if (platform === "win32") {
2566
+ const programData = process.env.PROGRAMDATA ?? "C:\\ProgramData";
2567
+ return join(programData, "ClaudeCode", "managed-settings.json");
2568
+ }
2569
+ return "/etc/claude-code/managed-settings.json";
2570
+ }
2571
+ function readManagedSettings(root) {
2572
+ const path = managedSettingsPathFor(root);
2573
+ const parsed = readPolicyDocument(path);
2574
+ if (parsed === void 0) return {};
2575
+ const out = {};
2576
+ for (const [key, value] of Object.entries(parsed)) {
2577
+ applyPolicyKey(out, key, value, path);
2578
+ }
2579
+ return out;
2580
+ }
2581
+ function readPolicyDocument(path) {
2582
+ if (!existsSync(path)) return void 0;
2583
+ let raw;
2584
+ try {
2585
+ raw = readFileSync(path, "utf8");
2586
+ } catch (cause) {
2587
+ diagFailure(
2588
+ `[theokit-sdk] ${path} exists and could not be read (${cause.message}) \u2014 NO operator policy is being applied. Fix the permissions or remove the file.
2589
+ `
2590
+ );
2591
+ return void 0;
2592
+ }
2593
+ let parsed;
2594
+ try {
2595
+ parsed = JSON.parse(raw);
2596
+ } catch (cause) {
2597
+ diagFailure(
2598
+ `[theokit-sdk] ${path} is not valid JSON (${cause.message}) \u2014 NO operator policy is being applied.
2599
+ `
2600
+ );
2601
+ return void 0;
2602
+ }
2603
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
2604
+ diagFailure(
2605
+ `[theokit-sdk] ${path} is not a JSON object \u2014 NO operator policy is being applied.
2606
+ `
2607
+ );
2608
+ return void 0;
2609
+ }
2610
+ return parsed;
2611
+ }
2612
+ var PERMISSION_MODES = ["default", "plan", "acceptEdits", "bypass"];
2613
+ function applyPolicyKey(out, key, value, path) {
2614
+ if (!KNOWN_KEYS.has(key)) {
2615
+ decline(path, key, "this runtime does not enforce it");
2616
+ return;
2617
+ }
2618
+ if (key === "permissionMode") {
2619
+ const mode = readMode(value, path);
2620
+ if (mode !== void 0) out.permissionMode = mode;
2621
+ return;
2622
+ }
2623
+ if (key === "permissions") {
2624
+ const rules = readRuleLists(value, path);
2625
+ if (rules !== void 0) out.permissions = rules;
2626
+ return;
2627
+ }
2628
+ const flag = readBoolean(value, key, path);
2629
+ if (flag === void 0) return;
2630
+ if (key === "disableAllHooks") out.disableAllHooks = flag;
2631
+ if (key === "disableSkillShellExecution") out.disableSkillShellExecution = flag;
2632
+ }
2633
+ function decline(path, key, reason) {
2634
+ diagFailure(`[theokit-sdk] ${path} declares "${key}" \u2014 ${reason}. It is NOT being applied.
2635
+ `);
2636
+ }
2637
+ function readMode(value, path) {
2638
+ if (typeof value === "string" && PERMISSION_MODES.includes(value)) {
2639
+ return value;
2640
+ }
2641
+ decline(
2642
+ path,
2643
+ "permissionMode",
2644
+ `${JSON.stringify(value)} is not one of ${PERMISSION_MODES.join(", ")}`
2645
+ );
2646
+ return void 0;
2647
+ }
2648
+ function readRuleLists(value, path) {
2649
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2650
+ return value;
2651
+ }
2652
+ decline(
2653
+ path,
2654
+ "permissions",
2655
+ `it is ${Array.isArray(value) ? "an array" : typeof value}, not an object of rule lists`
2656
+ );
2657
+ return void 0;
2658
+ }
2659
+ function readBoolean(value, key, path) {
2660
+ if (typeof value === "boolean") return value;
2661
+ decline(path, key, `it is ${typeof value}, not a boolean`);
2662
+ return void 0;
2663
+ }
2553
2664
  function spawnAndCollect(options) {
2554
2665
  return new Promise((resolve) => {
2555
2666
  const timeoutMs = options.timeoutMs ?? 3e4;
@@ -2600,16 +2711,26 @@ function spawnAndCollect(options) {
2600
2711
 
2601
2712
  // src/internal/runtime/hooks/hooks-executor.ts
2602
2713
  var HooksExecutor = class {
2603
- constructor(cwd, compatSources = [], gate = void 0) {
2714
+ constructor(cwd, compatSources = [], gate = void 0, policy = {}) {
2604
2715
  this.cwd = cwd;
2605
2716
  this.compatSources = compatSources;
2606
2717
  this.gate = gate;
2718
+ this.policy = policy;
2607
2719
  }
2608
2720
  cwd;
2609
2721
  compatSources;
2610
2722
  gate;
2723
+ policy;
2611
2724
  config = {};
2612
2725
  async initialize(settingSourcesIncludeProject) {
2726
+ if (readManagedSettings(this.policy.managedSettingsRoot).disableAllHooks === true) {
2727
+ warnFailureOnce(
2728
+ "hooks-disabled-by-policy",
2729
+ "[theokit-sdk] hooks: an operator policy (managed-settings.json) declares disableAllHooks \u2014 NO hook will run, including any this project declared."
2730
+ );
2731
+ this.config = {};
2732
+ return;
2733
+ }
2613
2734
  if (!settingSourcesIncludeProject) {
2614
2735
  this.config = {};
2615
2736
  return;
@@ -2656,19 +2777,24 @@ var HooksExecutor = class {
2656
2777
  *
2657
2778
  * No gate means no refusal, which is what every consumer gets today.
2658
2779
  */
2659
- async refusedByConsumer(command, payload) {
2780
+ async refusedByConsumer(command, payload, timeoutMs) {
2660
2781
  if (this.gate?.approve === void 0) return false;
2661
2782
  const request = {
2662
2783
  command: command.command,
2663
2784
  event: payload.event,
2785
+ // #637 — the EFFECTIVE timeout, passed in rather than recomputed here, so the number the
2786
+ // consumer is shown and the number `spawnAndCollect` enforces are the same expression.
2787
+ // Recomputing would be one line and would be the place they later diverge.
2788
+ timeoutMs,
2789
+ sourceEvent: command.sourceEvent,
2664
2790
  ...command.sourcePath === void 0 ? {} : { sourcePath: command.sourcePath },
2665
2791
  ...command.matcher === void 0 ? {} : { matcher: command.matcher }
2666
2792
  };
2667
2793
  return !await this.gate.approve(request);
2668
2794
  }
2669
2795
  async executeOne(command, payload) {
2670
- if (await this.refusedByConsumer(command, payload)) return { decision: "allow" };
2671
2796
  const timeoutMs = command.timeoutMs ?? 3e4;
2797
+ if (await this.refusedByConsumer(command, payload, timeoutMs)) return { decision: "allow" };
2672
2798
  const env = runtimeEnvFor(command.sourcePath, this.cwd);
2673
2799
  const result = await spawnAndCollect({
2674
2800
  command: "sh",
@@ -2676,7 +2802,7 @@ var HooksExecutor = class {
2676
2802
  cwd: this.cwd,
2677
2803
  ...Object.keys(env).length > 0 ? { env } : {},
2678
2804
  timeoutMs,
2679
- stdin: JSON.stringify(payload)
2805
+ stdin: JSON.stringify(stdinPayloadFor(payload, command, this.cwd))
2680
2806
  });
2681
2807
  const failure = this.decisionFromFailure(result, command, env, timeoutMs);
2682
2808
  return failure ?? parseDecisionFromStdout(result.stdout);
@@ -2690,9 +2816,16 @@ var HooksExecutor = class {
2690
2816
  * spawned.
2691
2817
  */
2692
2818
  decisionFromFailure(result, command, env, timeoutMs) {
2693
- if (result.timedOut) return { decision: "deny", reason: `Hook timed out after ${timeoutMs}ms` };
2819
+ if (result.timedOut)
2820
+ return {
2821
+ decision: "deny",
2822
+ reason: `Hook timed out after ${timeoutMs}ms`
2823
+ };
2694
2824
  if (result.spawnError !== void 0) {
2695
- return { decision: "deny", reason: `Hook spawn failed: ${result.spawnError.message}` };
2825
+ return {
2826
+ decision: "deny",
2827
+ reason: `Hook spawn failed: ${result.spawnError.message}`
2828
+ };
2696
2829
  }
2697
2830
  if (result.exitCode === 0) return void 0;
2698
2831
  const stderr = result.stderr.trim();
@@ -2705,6 +2838,16 @@ var HooksExecutor = class {
2705
2838
  };
2706
2839
  }
2707
2840
  };
2841
+ function stdinPayloadFor(payload, command, cwd) {
2842
+ return {
2843
+ ...payload,
2844
+ cwd,
2845
+ ...command.sourceEvent === void 0 ? {} : { hook_event_name: command.sourceEvent },
2846
+ ...payload.tool === void 0 ? {} : { tool_name: payload.tool },
2847
+ ...payload.input === void 0 ? {} : { tool_input: payload.input },
2848
+ ...payload.output === void 0 ? {} : { tool_response: payload.output }
2849
+ };
2850
+ }
2708
2851
  function runtimeEnvFor(sourcePath, cwd) {
2709
2852
  if (sourcePath === void 0) return {};
2710
2853
  return adapterForConfigPath(sourcePath)?.runtimeEnv(cwd) ?? {};
@@ -2712,19 +2855,35 @@ function runtimeEnvFor(sourcePath, cwd) {
2712
2855
  function parseDecisionFromStdout(stdout) {
2713
2856
  const trimmed = stdout.trim();
2714
2857
  if (trimmed.length === 0) return { decision: "allow" };
2858
+ let parsed;
2715
2859
  try {
2716
- const parsed = JSON.parse(trimmed);
2717
- if (parsed.decision === "deny" || parsed.decision === "feedback") {
2718
- const result = { decision: parsed.decision };
2719
- if (parsed.reason !== void 0) result.reason = parsed.reason;
2720
- if (parsed.feedback !== void 0) result.feedback = parsed.feedback;
2721
- return result;
2722
- }
2723
- if (parsed.decision === "allow") return { decision: "allow" };
2860
+ parsed = JSON.parse(trimmed);
2724
2861
  } catch {
2725
2862
  return { decision: "feedback", feedback: trimmed };
2726
2863
  }
2727
- return { decision: "allow" };
2864
+ return nestedDecision(parsed) ?? flatDecision(parsed) ?? { decision: "allow" };
2865
+ }
2866
+ function nestedDecision(parsed) {
2867
+ const nested = parsed.hookSpecificOutput;
2868
+ if (nested?.permissionDecision === "allow") return { decision: "allow" };
2869
+ if (nested?.permissionDecision !== "deny" && nested?.permissionDecision !== "ask") {
2870
+ return void 0;
2871
+ }
2872
+ const result = { decision: "deny" };
2873
+ if (nested.permissionDecisionReason !== void 0) {
2874
+ result.reason = nested.permissionDecisionReason;
2875
+ }
2876
+ return result;
2877
+ }
2878
+ function flatDecision(parsed) {
2879
+ if (parsed.decision === "allow") return { decision: "allow" };
2880
+ if (parsed.decision !== "deny" && parsed.decision !== "block" && parsed.decision !== "feedback") {
2881
+ return void 0;
2882
+ }
2883
+ const result = parsed.decision === "feedback" ? { decision: "feedback" } : { decision: "deny" };
2884
+ if (parsed.reason !== void 0) result.reason = parsed.reason;
2885
+ if (parsed.feedback !== void 0) result.feedback = parsed.feedback;
2886
+ return result;
2728
2887
  }
2729
2888
 
2730
2889
  // src/internal/runtime/lifecycle/context-budget-event.ts
@@ -3038,7 +3197,15 @@ async function buildSystemPromptContext(inputs, userText, memoryFacts, manager =
3038
3197
  agentId: inputs.agentId,
3039
3198
  cwd: inputs.workspaceCwd,
3040
3199
  model: inputs.model,
3041
- skills: skills.map((skill) => ({ name: skill.name, description: skill.description })),
3200
+ // This is the ONLY place the model learns which skills exist, which is what makes
3201
+ // `disable-model-invocation` enforceable rather than decorative. The scaffold had been writing
3202
+ // authorization frontmatter that the parser discarded, so the default was disclose-all.
3203
+ //
3204
+ // A disclosure rule, not an execution rule: `skills.get(name)` still resolves a hidden skill,
3205
+ // because a caller naming one has already made the decision this field keeps away from the
3206
+ // model. Widening it to execution would break the case the field is FOR — a side-effecting
3207
+ // skill a human may run and the model may not propose.
3208
+ skills: skills.filter((skill) => skill.disableModelInvocation !== true).map((skill) => ({ name: skill.name, description: skill.description })),
3042
3209
  userMessage: userText,
3043
3210
  memory: memoryFacts.map((fact) => ({ text: fact.text }))
3044
3211
  };
@@ -4062,14 +4229,24 @@ var ContextSourceFrontmatterSchema = z.object({
4062
4229
 
4063
4230
  // src/internal/runtime/context/context-manager.ts
4064
4231
  var FileContextManager = class {
4065
- constructor(cwd, settings, settingSourcesIncludeProject) {
4232
+ /**
4233
+ * @param compatSources - What the consumer declared in `local.compatSources` (or
4234
+ * `.theokit/config.json`), as `resolveCompatSources` resolved it. `undefined` means the caller
4235
+ * did not thread the declaration through at all and every dialect runs — the pre-#652 behaviour,
4236
+ * kept so an internal caller constructing this directly does not silently lose content. An empty
4237
+ * ARRAY is different and is the fix: it means the consumer declared no foreign dialect, so
4238
+ * `.claude/rules/*.md` does not reach the prompt.
4239
+ */
4240
+ constructor(cwd, settings, settingSourcesIncludeProject, compatSources) {
4066
4241
  this.cwd = cwd;
4067
4242
  this.settings = settings;
4068
4243
  this.settingSourcesIncludeProject = settingSourcesIncludeProject;
4244
+ this.compatSources = compatSources;
4069
4245
  }
4070
4246
  cwd;
4071
4247
  settings;
4072
4248
  settingSourcesIncludeProject;
4249
+ compatSources;
4073
4250
  state;
4074
4251
  /**
4075
4252
  * The in-scope file set used by the most recent `refresh`. Tracked so
@@ -4078,6 +4255,19 @@ var FileContextManager = class {
4078
4255
  * snapshot untouched, at zero per-send cost.
4079
4256
  */
4080
4257
  lastScope = [];
4258
+ /**
4259
+ * The dialect kinds granted the `context` surface, or `undefined` when nothing was declared to
4260
+ * this instance.
4261
+ *
4262
+ * Routed through `adaptersForSurface` rather than reading `.kind` off the declarations, so the
4263
+ * three fail-closed rules #524 established govern this surface identically to the other four: a
4264
+ * bare string admits everything, an object with no `import` admits nothing, and an unrecognised
4265
+ * surface name narrows rather than widens.
4266
+ */
4267
+ grantedContextDialects() {
4268
+ if (this.compatSources === void 0) return void 0;
4269
+ return adaptersForSurface(this.compatSources, "context").map((a) => a.kind);
4270
+ }
4081
4271
  async initialize() {
4082
4272
  if (!this.settingSourcesIncludeProject && this.settings.manager !== "file") {
4083
4273
  this.state = { config: { sources: [] }, loadedSources: [] };
@@ -4105,11 +4295,16 @@ var FileContextManager = class {
4105
4295
  const legacy = await loadSources(config, this.cwd);
4106
4296
  const maxBytesPerFile = this.settings.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE;
4107
4297
  const maxBytesTotal = this.settings.maxBytesTotal ?? DEFAULT_MAX_BYTES_TOTAL;
4298
+ const granted = this.grantedContextDialects();
4108
4299
  const discovered = await runDiscovery({
4109
4300
  cwd: this.cwd,
4110
4301
  maxBytesPerFile,
4111
4302
  skipLegacyTheokitContext: true,
4112
- touchedFiles
4303
+ touchedFiles,
4304
+ // #652 — the grant this path never consulted. Without it, a consumer who enabled project
4305
+ // scope for its OWN `.theokit/` also received a cloned repository's `.claude/rules/*.md`,
4306
+ // through a door the hooks/skills/subagents/plugins gate does not cover.
4307
+ ...granted === void 0 ? {} : { declaredCompatKinds: granted }
4113
4308
  });
4114
4309
  const legacyAsAggregator = legacy.filter((src) => src.status !== "excluded").map((src) => ({
4115
4310
  id: src.name,
@@ -4504,7 +4699,12 @@ function buildContext(args, out) {
4504
4699
  out.context = new FileContextManager(
4505
4700
  args.workspaceCwd,
4506
4701
  args.options.context,
4507
- args.settingSourcesIncludeProject
4702
+ args.settingSourcesIncludeProject,
4703
+ // #652 — the same declaration `buildSkills` and `buildPlugins` already pass. Omitting it here
4704
+ // is what let a foreign root's instructions into the system prompt while its skills, subagents,
4705
+ // hooks and plugins were correctly withheld: four surfaces failing closed and a fifth nobody
4706
+ // had wired to the gate.
4707
+ resolveCompatSources(args.options, args.workspaceCwd)
4508
4708
  );
4509
4709
  }
4510
4710
  function buildProviders(args, out) {
@@ -9152,7 +9352,7 @@ async function* localAgentStreamToCompletion(agent, message, options) {
9152
9352
  async function localAgentFork(parent, options) {
9153
9353
  const { forkAgentImpl } = await import('./fork-agent-S2EPIML7.js');
9154
9354
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
9155
- const { withPersonalityContext } = await import('./context-EGM6CHXD.js');
9355
+ const { withPersonalityContext } = await import('./context-J5BJ3LBS.js');
9156
9356
  const create = getAgentFacade().create;
9157
9357
  return withPersonalityContext(
9158
9358
  { slug: parent.personalitySlugSnapshot, isFork: true },
@@ -10929,7 +11129,7 @@ var Agent = class _Agent {
10929
11129
  */
10930
11130
  static async describe(agentId) {
10931
11131
  const agent = await getRegisteredAgentOrThrow(agentId);
10932
- const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-AIVDQ2D5.js');
11132
+ const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-CJFYQQU2.js');
10933
11133
  const settingSources = agent.options.local?.settingSources;
10934
11134
  const subagents = await loadSubagents2(
10935
11135
  agent.cwd ?? process.cwd(),
@@ -11035,6 +11235,6 @@ async function openLocalStore(reg) {
11035
11235
  return { cwd, model, store: new FsSessionStore2({ baseDir, cwd }) };
11036
11236
  }
11037
11237
 
11038
- export { Agent, AgentBuilder, DEFAULT_AGENTIC_MODEL_ID, MEMORY_EMBEDDING_ADAPTERS, Tool, ToolError, UsageAccumulator, computeCost, generateCronId, getPricingEntry, openRouterMemoryEmbeddingProviderAdapter, resolveSessionDir };
11039
- //# sourceMappingURL=chunk-IKBLU7ZS.js.map
11040
- //# sourceMappingURL=chunk-IKBLU7ZS.js.map
11238
+ export { Agent, AgentBuilder, DEFAULT_AGENTIC_MODEL_ID, MEMORY_EMBEDDING_ADAPTERS, Tool, ToolError, UsageAccumulator, computeCost, generateCronId, getPricingEntry, managedSettingsPathFor, openRouterMemoryEmbeddingProviderAdapter, readManagedSettings, resolveSessionDir };
11239
+ //# sourceMappingURL=chunk-2UXQASTX.js.map
11240
+ //# sourceMappingURL=chunk-2UXQASTX.js.map