@theokit/sdk 4.44.1 → 4.46.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.46.0
4
+
5
+ ### Minor Changes
6
+
7
+ - dbead57: `foldLayers` / `verifyLayerOrdering` — combine configuration layers in a declared order.
8
+
9
+ Later layers win, `undefined` never overwrites, and named keys ACCUMULATE instead of being
10
+ replaced. That last rule is not a nicety: with plain last-wins a project file DISPLACES the user's
11
+ entries for a list-valued key rather than adding to them, and for a key like `hooks` — arbitrary
12
+ command execution on every tool call — that is the difference between a repository adding a hook and
13
+ a repository removing yours.
14
+
15
+ `verifyLayerOrdering` refuses a chain that is not strictly ascending, naming both layers and both
16
+ precedences. Tolerating it would make resolution depend on array order rather than on declared
17
+ precedence: two sources of truth for one decision.
18
+
19
+ The layer NAMES are the caller's, supplied as data — one product's chain is
20
+ defaults/user/project/profile/env/cli and `profile` is that product's idea. Entries may omit
21
+ `precedence` to mean "this array is already the order".
22
+
23
+ Additive. Nothing calls it yet.
24
+
25
+ ## 4.45.0
26
+
27
+ ### Minor Changes
28
+
29
+ - f9a29f5: `applySecurityFloor` — a lower-trust configuration layer may tighten a security setting, never loosen it.
30
+
31
+ Layered configuration usually resolves last-wins, and for the keys that decide confinement that is a
32
+ hole: a project layer outranks the user's own file, so a cloned repository can hand itself the most
33
+ permissive sandbox and the operator's global choice loses silently, at the moment the directory is
34
+ opened. Nothing fails; the confinement is simply gone.
35
+
36
+ The rule is generic and the vocabulary is not, so the vocabulary is parameters: which values count
37
+ as more permissive, which layers are restricted, and which layer is the operator's explicit
38
+ override. A second product supplies its own without inheriting the first's words.
39
+
40
+ The override is returned verbatim even when outside the vocabulary — validating the operator's flag
41
+ is the consumer's job, and silently dropping an unrecognised one is worse than passing it through. A
42
+ value outside the vocabulary in a RESTRICTED layer is ignored instead: a typo in a repository's
43
+ config must neither become the effective setting nor read as maximally permissive.
44
+
45
+ Additive. Nothing calls it yet.
46
+
3
47
  ## 4.44.1
4
48
 
5
49
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -919,6 +919,42 @@ var JobQueue = class {
919
919
  if (next !== void 0) next();
920
920
  }
921
921
  };
922
+
923
+ // src/layer-fold.ts
924
+ var LayerOrderError = class extends chunkYULF6FPB_cjs.TheokitAgentError {
925
+ name = "LayerOrderError";
926
+ };
927
+ function verifyLayerOrdering(layers) {
928
+ let previous;
929
+ for (const current of layers) {
930
+ if (current.precedence === void 0) continue;
931
+ const declared = { layer: current.layer, precedence: current.precedence };
932
+ if (previous !== void 0 && declared.precedence <= previous.precedence) {
933
+ throw new LayerOrderError(
934
+ `layers out of order: \`${declared.layer}\` (precedence ${String(declared.precedence)}) comes after \`${previous.layer}\` (precedence ${String(previous.precedence)}) but does not outrank it`
935
+ );
936
+ }
937
+ previous = declared;
938
+ }
939
+ }
940
+ function foldLayers(entries, accumulatingKeys = []) {
941
+ verifyLayerOrdering(entries);
942
+ const accumulated = new Map(accumulatingKeys.map((k) => [k, []]));
943
+ const combined = {};
944
+ for (const { values } of entries) {
945
+ for (const [key, value] of Object.entries(values)) {
946
+ if (value === void 0) continue;
947
+ const stack = accumulated.get(key);
948
+ if (stack !== void 0 && Array.isArray(value)) {
949
+ stack.push(...value);
950
+ combined[key] = [...stack];
951
+ continue;
952
+ }
953
+ combined[key] = value;
954
+ }
955
+ }
956
+ return combined;
957
+ }
922
958
  function diaryPath(cwd) {
923
959
  return path.join(chunkGH52NOCL_cjs.memoryDir(cwd), "dream-diary.md");
924
960
  }
@@ -1621,6 +1657,39 @@ var Security = class {
1621
1657
  }
1622
1658
  };
1623
1659
 
1660
+ // src/security-floor.ts
1661
+ function permissivenessOf(order, value) {
1662
+ if (value === void 0) return -1;
1663
+ return order.indexOf(value);
1664
+ }
1665
+ function baseline(input) {
1666
+ const { restricted, override, layers } = input;
1667
+ let value;
1668
+ for (const [name, candidate] of Object.entries(layers)) {
1669
+ if (name === override || restricted.includes(name)) continue;
1670
+ if (candidate !== void 0) value = candidate;
1671
+ }
1672
+ return value;
1673
+ }
1674
+ function tightenOnly(input, start) {
1675
+ const { permissiveness, restricted, layers } = input;
1676
+ let resolved = start;
1677
+ let ceiling = permissivenessOf(permissiveness, start);
1678
+ for (const layer of restricted) {
1679
+ const candidate = layers[layer];
1680
+ if (candidate === void 0) continue;
1681
+ const level = permissivenessOf(permissiveness, candidate);
1682
+ if (level < 0) continue;
1683
+ if (ceiling >= 0 && level > ceiling) continue;
1684
+ resolved = candidate;
1685
+ ceiling = level;
1686
+ }
1687
+ return resolved;
1688
+ }
1689
+ function applySecurityFloor(input) {
1690
+ return input.layers[input.override] ?? tightenOnly(input, baseline(input));
1691
+ }
1692
+
1624
1693
  // src/session-scope.ts
1625
1694
  function scopedConversationId(scope, id) {
1626
1695
  return `${scope}__${id}`;
@@ -2251,6 +2320,7 @@ exports.AgentFactory = AgentFactory;
2251
2320
  exports.Budget = Budget;
2252
2321
  exports.EventBus = EventBus;
2253
2322
  exports.JobQueue = JobQueue;
2323
+ exports.LayerOrderError = LayerOrderError;
2254
2324
  exports.Memory = Memory;
2255
2325
  exports.NoopMemoryProvider = NoopMemoryProvider;
2256
2326
  exports.PermissionEngine = PermissionEngine;
@@ -2267,10 +2337,12 @@ exports.Theokit = Theokit;
2267
2337
  exports.TokenLimiter = TokenLimiter;
2268
2338
  exports.UnicodeNormalizer = UnicodeNormalizer;
2269
2339
  exports.applyMode = applyMode;
2340
+ exports.applySecurityFloor = applySecurityFloor;
2270
2341
  exports.chargeAndCheckThresholds = chargeAndCheckThresholds;
2271
2342
  exports.createCounterBudgetTracker = createCounterBudgetTracker;
2272
2343
  exports.estimateTokens = estimateTokens;
2273
2344
  exports.extractRawId = extractRawId;
2345
+ exports.foldLayers = foldLayers;
2274
2346
  exports.inferApiMode = inferApiMode;
2275
2347
  exports.loadProjectEnv = loadProjectEnv;
2276
2348
  exports.migrateSqliteToLance = migrateSqliteToLance2;
@@ -2282,5 +2354,6 @@ exports.runGoalLoop = runGoalLoop;
2282
2354
  exports.scopedConversationId = scopedConversationId;
2283
2355
  exports.sessionScopePrefix = sessionScopePrefix;
2284
2356
  exports.toShareGptTrajectory = toShareGptTrajectory;
2357
+ exports.verifyLayerOrdering = verifyLayerOrdering;
2285
2358
  //# sourceMappingURL=index.cjs.map
2286
2359
  //# sourceMappingURL=index.cjs.map