@kilnai/cli 0.23.1 → 1.0.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 (300) hide show
  1. package/README.md +33 -0
  2. package/dist/application/__tests__/plan-exit-tool.test.d.ts +2 -0
  3. package/dist/application/__tests__/plan-exit-tool.test.d.ts.map +1 -0
  4. package/dist/application/__tests__/plan-exit-tool.test.js +12 -0
  5. package/dist/application/__tests__/plan-exit-tool.test.js.map +1 -0
  6. package/dist/application/agent-loader.d.ts +12 -0
  7. package/dist/application/agent-loader.d.ts.map +1 -0
  8. package/dist/application/agent-loader.js +114 -0
  9. package/dist/application/agent-loader.js.map +1 -0
  10. package/dist/application/agent-loader.test.d.ts +2 -0
  11. package/dist/application/agent-loader.test.d.ts.map +1 -0
  12. package/dist/application/agent-loader.test.js +151 -0
  13. package/dist/application/agent-loader.test.js.map +1 -0
  14. package/dist/application/context-artifact-keys.d.ts +5 -0
  15. package/dist/application/context-artifact-keys.d.ts.map +1 -0
  16. package/dist/application/context-artifact-keys.js +14 -0
  17. package/dist/application/context-artifact-keys.js.map +1 -0
  18. package/dist/application/context-governance.d.ts +6 -0
  19. package/dist/application/context-governance.d.ts.map +1 -0
  20. package/dist/application/context-governance.js +20 -0
  21. package/dist/application/context-governance.js.map +1 -0
  22. package/dist/application/context-governor.d.ts +26 -0
  23. package/dist/application/context-governor.d.ts.map +1 -0
  24. package/dist/application/context-governor.js +164 -0
  25. package/dist/application/context-governor.js.map +1 -0
  26. package/dist/application/context-types.d.ts +20 -0
  27. package/dist/application/context-types.d.ts.map +1 -0
  28. package/dist/application/context-types.js +21 -0
  29. package/dist/application/context-types.js.map +1 -0
  30. package/dist/application/plan-exit-tool.d.ts +19 -0
  31. package/dist/application/plan-exit-tool.d.ts.map +1 -0
  32. package/dist/application/plan-exit-tool.js +13 -0
  33. package/dist/application/plan-exit-tool.js.map +1 -0
  34. package/dist/application/repo-summary-cache.d.ts +5 -0
  35. package/dist/application/repo-summary-cache.d.ts.map +1 -0
  36. package/dist/application/repo-summary-cache.js +82 -0
  37. package/dist/application/repo-summary-cache.js.map +1 -0
  38. package/dist/application/resume-strategy-feedback.d.ts +5 -0
  39. package/dist/application/resume-strategy-feedback.d.ts.map +1 -0
  40. package/dist/application/resume-strategy-feedback.js +81 -0
  41. package/dist/application/resume-strategy-feedback.js.map +1 -0
  42. package/dist/application/resume-strategy-policy.d.ts +26 -0
  43. package/dist/application/resume-strategy-policy.d.ts.map +1 -0
  44. package/dist/application/resume-strategy-policy.js +35 -0
  45. package/dist/application/resume-strategy-policy.js.map +1 -0
  46. package/dist/application/run-session.d.ts +39 -0
  47. package/dist/application/run-session.d.ts.map +1 -0
  48. package/dist/application/run-session.js +349 -0
  49. package/dist/application/run-session.js.map +1 -0
  50. package/dist/application/session-hooks.d.ts +20 -0
  51. package/dist/application/session-hooks.d.ts.map +1 -0
  52. package/dist/application/session-hooks.js +55 -0
  53. package/dist/application/session-hooks.js.map +1 -0
  54. package/dist/application/session-ledger.d.ts +12 -0
  55. package/dist/application/session-ledger.d.ts.map +1 -0
  56. package/dist/application/session-ledger.js +29 -0
  57. package/dist/application/session-ledger.js.map +1 -0
  58. package/dist/application/session-report.d.ts +19 -0
  59. package/dist/application/session-report.d.ts.map +1 -0
  60. package/dist/application/session-report.js +207 -0
  61. package/dist/application/session-report.js.map +1 -0
  62. package/dist/application/session-resume.d.ts +3 -0
  63. package/dist/application/session-resume.d.ts.map +1 -0
  64. package/dist/application/session-resume.js +16 -0
  65. package/dist/application/session-resume.js.map +1 -0
  66. package/dist/commands/auth.d.ts +2 -0
  67. package/dist/commands/auth.d.ts.map +1 -0
  68. package/dist/commands/auth.js +138 -0
  69. package/dist/commands/auth.js.map +1 -0
  70. package/dist/commands/config.d.ts +1 -1
  71. package/dist/commands/config.d.ts.map +1 -1
  72. package/dist/commands/config.js +141 -27
  73. package/dist/commands/config.js.map +1 -1
  74. package/dist/commands/cron.d.ts +3 -0
  75. package/dist/commands/cron.d.ts.map +1 -0
  76. package/dist/commands/cron.js +201 -0
  77. package/dist/commands/cron.js.map +1 -0
  78. package/dist/commands/dev.js +2 -2
  79. package/dist/commands/dev.js.map +1 -1
  80. package/dist/commands/domain.js +17 -17
  81. package/dist/commands/domain.js.map +1 -1
  82. package/dist/commands/init.d.ts +2 -11
  83. package/dist/commands/init.d.ts.map +1 -1
  84. package/dist/commands/init.js +14 -25
  85. package/dist/commands/init.js.map +1 -1
  86. package/dist/commands/mcp-config.d.ts +7 -1
  87. package/dist/commands/mcp-config.d.ts.map +1 -1
  88. package/dist/commands/mcp-config.js +26 -10
  89. package/dist/commands/mcp-config.js.map +1 -1
  90. package/dist/commands/memory.d.ts +1 -1
  91. package/dist/commands/memory.d.ts.map +1 -1
  92. package/dist/commands/memory.js +10 -10
  93. package/dist/commands/memory.js.map +1 -1
  94. package/dist/commands/run.d.ts +15 -3
  95. package/dist/commands/run.d.ts.map +1 -1
  96. package/dist/commands/run.js +464 -85
  97. package/dist/commands/run.js.map +1 -1
  98. package/dist/commands/serve.d.ts +1 -1
  99. package/dist/commands/serve.d.ts.map +1 -1
  100. package/dist/commands/serve.js +3 -3
  101. package/dist/commands/serve.js.map +1 -1
  102. package/dist/commands/skill-capture.d.ts +13 -0
  103. package/dist/commands/skill-capture.d.ts.map +1 -0
  104. package/dist/commands/skill-capture.js +212 -0
  105. package/dist/commands/skill-capture.js.map +1 -0
  106. package/dist/commands/skill.d.ts.map +1 -1
  107. package/dist/commands/skill.js +7 -3
  108. package/dist/commands/skill.js.map +1 -1
  109. package/dist/commands/status.d.ts +1 -1
  110. package/dist/commands/status.d.ts.map +1 -1
  111. package/dist/commands/status.js +15 -16
  112. package/dist/commands/status.js.map +1 -1
  113. package/dist/commands/sync.d.ts +11 -0
  114. package/dist/commands/sync.d.ts.map +1 -0
  115. package/dist/commands/sync.js +114 -0
  116. package/dist/commands/sync.js.map +1 -0
  117. package/dist/commands/tools.d.ts +6 -0
  118. package/dist/commands/tools.d.ts.map +1 -0
  119. package/dist/commands/tools.js +28 -0
  120. package/dist/commands/tools.js.map +1 -0
  121. package/dist/commands/tui.d.ts +29 -0
  122. package/dist/commands/tui.d.ts.map +1 -0
  123. package/dist/commands/tui.js +444 -0
  124. package/dist/commands/tui.js.map +1 -0
  125. package/dist/config/config-merger.d.ts +5 -0
  126. package/dist/config/config-merger.d.ts.map +1 -0
  127. package/dist/config/config-merger.js +25 -0
  128. package/dist/config/config-merger.js.map +1 -0
  129. package/dist/config/config-merger.test.d.ts +2 -0
  130. package/dist/config/config-merger.test.d.ts.map +1 -0
  131. package/dist/config/config-merger.test.js +165 -0
  132. package/dist/config/config-merger.test.js.map +1 -0
  133. package/dist/config/env-config.d.ts +5 -0
  134. package/dist/config/env-config.d.ts.map +1 -0
  135. package/dist/config/env-config.js +24 -0
  136. package/dist/config/env-config.js.map +1 -0
  137. package/dist/config/env-config.test.d.ts +2 -0
  138. package/dist/config/env-config.test.d.ts.map +1 -0
  139. package/dist/config/env-config.test.js +79 -0
  140. package/dist/config/env-config.test.js.map +1 -0
  141. package/dist/config/global-config.d.ts +23 -0
  142. package/dist/config/global-config.d.ts.map +1 -0
  143. package/dist/config/global-config.js +48 -0
  144. package/dist/config/global-config.js.map +1 -0
  145. package/dist/config/global-config.test.d.ts +2 -0
  146. package/dist/config/global-config.test.d.ts.map +1 -0
  147. package/dist/config/global-config.test.js +96 -0
  148. package/dist/config/global-config.test.js.map +1 -0
  149. package/dist/config-resolver.d.ts +5 -0
  150. package/dist/config-resolver.d.ts.map +1 -0
  151. package/dist/config-resolver.js +19 -0
  152. package/dist/config-resolver.js.map +1 -0
  153. package/dist/config.d.ts +8 -7
  154. package/dist/config.d.ts.map +1 -1
  155. package/dist/config.js +14 -1
  156. package/dist/config.js.map +1 -1
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +193 -16
  159. package/dist/index.js.map +1 -1
  160. package/dist/kiln-yaml-types.d.ts +127 -0
  161. package/dist/kiln-yaml-types.d.ts.map +1 -0
  162. package/dist/kiln-yaml-types.js +42 -0
  163. package/dist/kiln-yaml-types.js.map +1 -0
  164. package/dist/kiln-yaml.d.ts +10 -0
  165. package/dist/kiln-yaml.d.ts.map +1 -0
  166. package/dist/kiln-yaml.js +109 -0
  167. package/dist/kiln-yaml.js.map +1 -0
  168. package/dist/mcp/config-generator.d.ts +9 -2
  169. package/dist/mcp/config-generator.d.ts.map +1 -1
  170. package/dist/mcp/config-generator.js +132 -2
  171. package/dist/mcp/config-generator.js.map +1 -1
  172. package/dist/mcp/index.d.ts.map +1 -1
  173. package/dist/mcp/index.js +2 -1
  174. package/dist/mcp/index.js.map +1 -1
  175. package/dist/mcp/server.d.ts.map +1 -1
  176. package/dist/mcp/server.js +2 -1
  177. package/dist/mcp/server.js.map +1 -1
  178. package/dist/mcp-entry.js +0 -5
  179. package/dist/mcp-entry.js.map +1 -1
  180. package/dist/sync/agent-sync.d.ts +13 -0
  181. package/dist/sync/agent-sync.d.ts.map +1 -0
  182. package/dist/sync/agent-sync.js +130 -0
  183. package/dist/sync/agent-sync.js.map +1 -0
  184. package/dist/sync/agent-sync.test.d.ts +2 -0
  185. package/dist/sync/agent-sync.test.d.ts.map +1 -0
  186. package/dist/sync/agent-sync.test.js +130 -0
  187. package/dist/sync/agent-sync.test.js.map +1 -0
  188. package/dist/sync/agents-md-sync.d.ts +7 -0
  189. package/dist/sync/agents-md-sync.d.ts.map +1 -0
  190. package/dist/sync/agents-md-sync.js +44 -0
  191. package/dist/sync/agents-md-sync.js.map +1 -0
  192. package/dist/sync/agents-md-sync.test.d.ts +2 -0
  193. package/dist/sync/agents-md-sync.test.d.ts.map +1 -0
  194. package/dist/sync/agents-md-sync.test.js +154 -0
  195. package/dist/sync/agents-md-sync.test.js.map +1 -0
  196. package/dist/sync/hook-sync.d.ts +8 -0
  197. package/dist/sync/hook-sync.d.ts.map +1 -0
  198. package/dist/sync/hook-sync.js +90 -0
  199. package/dist/sync/hook-sync.js.map +1 -0
  200. package/dist/sync/security-sync.d.ts +9 -0
  201. package/dist/sync/security-sync.d.ts.map +1 -0
  202. package/dist/sync/security-sync.js +161 -0
  203. package/dist/sync/security-sync.js.map +1 -0
  204. package/dist/sync/skill-sync.d.ts +10 -0
  205. package/dist/sync/skill-sync.d.ts.map +1 -0
  206. package/dist/sync/skill-sync.js +87 -0
  207. package/dist/sync/skill-sync.js.map +1 -0
  208. package/dist/sync/skill-sync.test.d.ts +2 -0
  209. package/dist/sync/skill-sync.test.d.ts.map +1 -0
  210. package/dist/sync/skill-sync.test.js +163 -0
  211. package/dist/sync/skill-sync.test.js.map +1 -0
  212. package/dist/wrapper/approval-memory-store.d.ts +40 -0
  213. package/dist/wrapper/approval-memory-store.d.ts.map +1 -0
  214. package/dist/wrapper/approval-memory-store.js +132 -0
  215. package/dist/wrapper/approval-memory-store.js.map +1 -0
  216. package/dist/wrapper/claude-code-process.d.ts +32 -34
  217. package/dist/wrapper/claude-code-process.d.ts.map +1 -1
  218. package/dist/wrapper/claude-code-process.js +181 -66
  219. package/dist/wrapper/claude-code-process.js.map +1 -1
  220. package/dist/wrapper/cleanup-registry.d.ts +7 -0
  221. package/dist/wrapper/cleanup-registry.d.ts.map +1 -0
  222. package/dist/wrapper/cleanup-registry.js +11 -0
  223. package/dist/wrapper/cleanup-registry.js.map +1 -0
  224. package/dist/wrapper/codex-session.d.ts +49 -0
  225. package/dist/wrapper/codex-session.d.ts.map +1 -0
  226. package/dist/wrapper/codex-session.js +470 -0
  227. package/dist/wrapper/codex-session.js.map +1 -0
  228. package/dist/wrapper/debug.d.ts +2 -0
  229. package/dist/wrapper/debug.d.ts.map +1 -0
  230. package/dist/wrapper/debug.js +7 -0
  231. package/dist/wrapper/debug.js.map +1 -0
  232. package/dist/wrapper/executable-provider-session.d.ts +26 -0
  233. package/dist/wrapper/executable-provider-session.d.ts.map +1 -0
  234. package/dist/wrapper/executable-provider-session.js +214 -0
  235. package/dist/wrapper/executable-provider-session.js.map +1 -0
  236. package/dist/wrapper/hook-executor.d.ts +21 -0
  237. package/dist/wrapper/hook-executor.d.ts.map +1 -0
  238. package/dist/wrapper/hook-executor.js +100 -0
  239. package/dist/wrapper/hook-executor.js.map +1 -0
  240. package/dist/wrapper/hook-registry.d.ts +10 -0
  241. package/dist/wrapper/hook-registry.d.ts.map +1 -0
  242. package/dist/wrapper/hook-registry.js +57 -0
  243. package/dist/wrapper/hook-registry.js.map +1 -0
  244. package/dist/wrapper/index.d.ts +83 -2
  245. package/dist/wrapper/index.d.ts.map +1 -1
  246. package/dist/wrapper/index.js +11 -0
  247. package/dist/wrapper/index.js.map +1 -1
  248. package/dist/wrapper/mcp-selector.d.ts +2 -0
  249. package/dist/wrapper/mcp-selector.d.ts.map +1 -0
  250. package/dist/wrapper/mcp-selector.js +8 -0
  251. package/dist/wrapper/mcp-selector.js.map +1 -0
  252. package/dist/wrapper/opencode-session.d.ts +69 -0
  253. package/dist/wrapper/opencode-session.d.ts.map +1 -0
  254. package/dist/wrapper/opencode-session.js +568 -0
  255. package/dist/wrapper/opencode-session.js.map +1 -0
  256. package/dist/wrapper/permission-evaluator.d.ts +57 -0
  257. package/dist/wrapper/permission-evaluator.d.ts.map +1 -0
  258. package/dist/wrapper/permission-evaluator.js +310 -0
  259. package/dist/wrapper/permission-evaluator.js.map +1 -0
  260. package/dist/wrapper/permission-normalizer.d.ts +13 -0
  261. package/dist/wrapper/permission-normalizer.d.ts.map +1 -0
  262. package/dist/wrapper/permission-normalizer.js +88 -0
  263. package/dist/wrapper/permission-normalizer.js.map +1 -0
  264. package/dist/wrapper/permission-policy-authorizer.d.ts +12 -0
  265. package/dist/wrapper/permission-policy-authorizer.d.ts.map +1 -0
  266. package/dist/wrapper/permission-policy-authorizer.js +64 -0
  267. package/dist/wrapper/permission-policy-authorizer.js.map +1 -0
  268. package/dist/wrapper/preamble-builder.d.ts +7 -0
  269. package/dist/wrapper/preamble-builder.d.ts.map +1 -0
  270. package/dist/wrapper/preamble-builder.js +103 -0
  271. package/dist/wrapper/preamble-builder.js.map +1 -0
  272. package/dist/wrapper/provider-context.d.ts +20 -0
  273. package/dist/wrapper/provider-context.d.ts.map +1 -0
  274. package/dist/wrapper/provider-context.js +58 -0
  275. package/dist/wrapper/provider-context.js.map +1 -0
  276. package/dist/wrapper/provider-session.d.ts +27 -0
  277. package/dist/wrapper/provider-session.d.ts.map +1 -0
  278. package/dist/wrapper/provider-session.js +208 -0
  279. package/dist/wrapper/provider-session.js.map +1 -0
  280. package/dist/wrapper/session-manager.d.ts +21 -4
  281. package/dist/wrapper/session-manager.d.ts.map +1 -1
  282. package/dist/wrapper/session-manager.js +173 -14
  283. package/dist/wrapper/session-manager.js.map +1 -1
  284. package/dist/wrapper/session-registry.d.ts +136 -0
  285. package/dist/wrapper/session-registry.d.ts.map +1 -0
  286. package/dist/wrapper/session-registry.js +977 -0
  287. package/dist/wrapper/session-registry.js.map +1 -0
  288. package/dist/wrapper/session-store.d.ts +63 -0
  289. package/dist/wrapper/session-store.d.ts.map +1 -0
  290. package/dist/wrapper/session-store.js +215 -0
  291. package/dist/wrapper/session-store.js.map +1 -0
  292. package/dist/wrapper/session.d.ts +127 -0
  293. package/dist/wrapper/session.d.ts.map +1 -0
  294. package/dist/wrapper/session.js +14 -0
  295. package/dist/wrapper/session.js.map +1 -0
  296. package/dist/wrapper/worktree-manager.d.ts +30 -0
  297. package/dist/wrapper/worktree-manager.d.ts.map +1 -0
  298. package/dist/wrapper/worktree-manager.js +139 -0
  299. package/dist/wrapper/worktree-manager.js.map +1 -0
  300. package/package.json +11 -7
@@ -0,0 +1,977 @@
1
+ import { debug } from "./debug.js";
2
+ import { CodexOAuthAuth, getFieldStrength, MODEL_CATALOG } from "@kilnai/core";
3
+ import { ClaudeSession } from "./claude-code-process.js";
4
+ import { CodexSession } from "./codex-session.js";
5
+ import { OpenCodeSession } from "./opencode-session.js";
6
+ import { ProviderSession } from "./provider-session.js";
7
+ import { ExecutableProviderSession } from "./executable-provider-session.js";
8
+ import { WorktreeManager } from "./worktree-manager.js";
9
+ import { normalizePermissionPolicy } from "./permission-normalizer.js";
10
+ const DIRECT_API_PROVIDERS = new Set([
11
+ "codex-oauth",
12
+ "anthropic",
13
+ "openai",
14
+ "deepseek",
15
+ "openrouter",
16
+ "ollama",
17
+ ]);
18
+ const HARNESS_PROVIDERS = new Set(["claude", "codex", "opencode"]);
19
+ const FREE_PROVIDERS = new Set(["codex-oauth", "openrouter", "ollama"]);
20
+ const CODEX_OAUTH_AVAILABLE = await new CodexOAuthAuth().hasValidCredentials().catch((error) => {
21
+ debug("[provider:codex-oauth] availability check failed", error instanceof Error ? error.message : String(error));
22
+ return false;
23
+ });
24
+ export function isDirectApiProvider(provider) {
25
+ if (!provider)
26
+ return false;
27
+ return DIRECT_API_PROVIDERS.has(provider);
28
+ }
29
+ export function getProviderDisplayInfo(registry) {
30
+ return registry.list().map((provider) => ({
31
+ id: provider.id,
32
+ group: getProviderDisplayGroup(provider.id),
33
+ models: getProviderModels(provider.id),
34
+ free: FREE_PROVIDERS.has(provider.id),
35
+ }));
36
+ }
37
+ function getProviderDisplayGroup(provider) {
38
+ if (provider === "codex-oauth") {
39
+ return "subscription";
40
+ }
41
+ if (HARNESS_PROVIDERS.has(provider)) {
42
+ return "harness";
43
+ }
44
+ return "direct-api";
45
+ }
46
+ function getProviderModels(provider) {
47
+ const catalogProviders = (() => {
48
+ switch (provider) {
49
+ case "claude":
50
+ return ["anthropic"];
51
+ case "codex":
52
+ return ["codex-oauth", "openai"];
53
+ case "opencode":
54
+ return [];
55
+ default:
56
+ return [provider];
57
+ }
58
+ })();
59
+ const models = [];
60
+ for (const entry of MODEL_CATALOG) {
61
+ if (!catalogProviders.includes(entry.provider)) {
62
+ continue;
63
+ }
64
+ if (provider === "codex" && entry.provider === "openai") {
65
+ const isCodexModel = entry.model.startsWith("gpt-5.") || entry.model.includes("codex");
66
+ if (!isCodexModel) {
67
+ continue;
68
+ }
69
+ }
70
+ if (!models.includes(entry.model)) {
71
+ models.push(entry.model);
72
+ }
73
+ }
74
+ return models;
75
+ }
76
+ const OPENCODE_SANDBOX_WARNING = "OpenCode does not natively enforce Kiln sandbox modes; Kiln maps sandbox intent to permission prompting semantics only.";
77
+ const DIRECT_PROVIDER_POLICY_WARNING = "Direct API providers do not natively enforce Kiln granular permission rules; constraints are appended to the system prompt.";
78
+ export function translatePermission(policy, backend) {
79
+ const normalized = normalizePermissionPolicy(policy);
80
+ const approval = normalized.approval ?? "on-request";
81
+ const sandbox = normalized.sandbox ?? "read-only";
82
+ const granularRules = collectTranslationRules(normalized);
83
+ const representableRules = granularRules.filter((rule) => isRepresentableByBackend(rule, backend));
84
+ const unsupportedRules = granularRules.filter((rule) => !isRepresentableByBackend(rule, backend));
85
+ const constraintInstructions = buildConstraintInstructions(backend, unsupportedRules);
86
+ const warnings = [];
87
+ if (unsupportedRules.length > 0) {
88
+ warnings.push(`${unsupportedRules.length} granular permission rule(s) are not natively supported by ${backend} and require Kiln-side constraints`);
89
+ }
90
+ if (backend === "opencode") {
91
+ warnings.push(OPENCODE_SANDBOX_WARNING);
92
+ }
93
+ if (approval === "never") {
94
+ if (sandbox === "read-only") {
95
+ if (backend === "claude") {
96
+ return {
97
+ backend: "claude",
98
+ config: { permissionMode: "acceptEdits", allowDangerouslySkipPermissions: false },
99
+ nativeRules: buildClaudeNativeRules(representableRules),
100
+ representableRules,
101
+ unsupportedRules,
102
+ constraintInstructions,
103
+ warnings,
104
+ };
105
+ }
106
+ if (backend === "codex") {
107
+ return {
108
+ backend: "codex",
109
+ config: { approvalMode: "never", sandboxMode: "read-only" },
110
+ nativeRules: { coarseOnly: true },
111
+ representableRules,
112
+ unsupportedRules,
113
+ constraintInstructions,
114
+ warnings,
115
+ };
116
+ }
117
+ return {
118
+ backend: "opencode",
119
+ config: { permissionDefault: "ask" },
120
+ nativeRules: buildOpenCodeNativeRules(normalized),
121
+ representableRules,
122
+ unsupportedRules,
123
+ constraintInstructions,
124
+ warnings,
125
+ };
126
+ }
127
+ if (sandbox === "workspace-write") {
128
+ if (backend === "claude") {
129
+ return {
130
+ backend: "claude",
131
+ config: { permissionMode: "bypassPermissions", allowDangerouslySkipPermissions: true },
132
+ nativeRules: buildClaudeNativeRules(representableRules),
133
+ representableRules,
134
+ unsupportedRules,
135
+ constraintInstructions,
136
+ warnings,
137
+ };
138
+ }
139
+ if (backend === "codex") {
140
+ return {
141
+ backend: "codex",
142
+ config: { approvalMode: "never", sandboxMode: "workspace-write" },
143
+ nativeRules: { coarseOnly: true },
144
+ representableRules,
145
+ unsupportedRules,
146
+ constraintInstructions,
147
+ warnings,
148
+ };
149
+ }
150
+ return {
151
+ backend: "opencode",
152
+ config: { permissionDefault: "allow" },
153
+ nativeRules: buildOpenCodeNativeRules(normalized),
154
+ representableRules,
155
+ unsupportedRules,
156
+ constraintInstructions,
157
+ warnings,
158
+ };
159
+ }
160
+ if (sandbox === "danger-full-access") {
161
+ if (backend === "claude") {
162
+ return {
163
+ backend: "claude",
164
+ config: { permissionMode: "bypassPermissions", allowDangerouslySkipPermissions: true },
165
+ nativeRules: buildClaudeNativeRules(representableRules),
166
+ representableRules,
167
+ unsupportedRules,
168
+ constraintInstructions,
169
+ warnings,
170
+ };
171
+ }
172
+ if (backend === "codex") {
173
+ return {
174
+ backend: "codex",
175
+ config: { approvalMode: "never", sandboxMode: "danger-full-access" },
176
+ nativeRules: { coarseOnly: true },
177
+ representableRules,
178
+ unsupportedRules,
179
+ constraintInstructions,
180
+ warnings,
181
+ };
182
+ }
183
+ return {
184
+ backend: "opencode",
185
+ config: { permissionDefault: "allow" },
186
+ nativeRules: buildOpenCodeNativeRules(normalized),
187
+ representableRules,
188
+ unsupportedRules,
189
+ constraintInstructions,
190
+ warnings,
191
+ };
192
+ }
193
+ }
194
+ if (approval === "on-request") {
195
+ if (backend === "claude") {
196
+ return {
197
+ backend: "claude",
198
+ config: { permissionMode: "default", allowDangerouslySkipPermissions: false },
199
+ nativeRules: buildClaudeNativeRules(representableRules),
200
+ representableRules,
201
+ unsupportedRules,
202
+ constraintInstructions,
203
+ warnings,
204
+ };
205
+ }
206
+ if (backend === "codex") {
207
+ return {
208
+ backend: "codex",
209
+ config: { approvalMode: "on-request", sandboxMode: sandbox },
210
+ nativeRules: { coarseOnly: true },
211
+ representableRules,
212
+ unsupportedRules,
213
+ constraintInstructions,
214
+ warnings,
215
+ };
216
+ }
217
+ return {
218
+ backend: "opencode",
219
+ config: { permissionDefault: "ask" },
220
+ nativeRules: buildOpenCodeNativeRules(normalized),
221
+ representableRules,
222
+ unsupportedRules,
223
+ constraintInstructions,
224
+ warnings,
225
+ };
226
+ }
227
+ if (approval === "on-failure") {
228
+ if (backend === "claude") {
229
+ return {
230
+ backend: "claude",
231
+ config: { permissionMode: "default", allowDangerouslySkipPermissions: false },
232
+ nativeRules: buildClaudeNativeRules(representableRules),
233
+ representableRules,
234
+ unsupportedRules,
235
+ constraintInstructions,
236
+ warnings,
237
+ };
238
+ }
239
+ if (backend === "codex") {
240
+ return {
241
+ backend: "codex",
242
+ config: { approvalMode: "on-failure", sandboxMode: sandbox },
243
+ nativeRules: { coarseOnly: true },
244
+ representableRules,
245
+ unsupportedRules,
246
+ constraintInstructions,
247
+ warnings,
248
+ };
249
+ }
250
+ return {
251
+ backend: "opencode",
252
+ config: { permissionDefault: "ask" },
253
+ nativeRules: buildOpenCodeNativeRules(normalized),
254
+ representableRules,
255
+ unsupportedRules,
256
+ constraintInstructions,
257
+ warnings,
258
+ };
259
+ }
260
+ if (approval === "untrusted") {
261
+ if (backend === "claude") {
262
+ return {
263
+ backend: "claude",
264
+ config: { permissionMode: "plan", allowDangerouslySkipPermissions: false },
265
+ nativeRules: buildClaudeNativeRules(representableRules),
266
+ representableRules,
267
+ unsupportedRules,
268
+ constraintInstructions,
269
+ warnings,
270
+ };
271
+ }
272
+ if (backend === "codex") {
273
+ return {
274
+ backend: "codex",
275
+ config: { approvalMode: "untrusted", sandboxMode: sandbox },
276
+ nativeRules: { coarseOnly: true },
277
+ representableRules,
278
+ unsupportedRules,
279
+ constraintInstructions,
280
+ warnings,
281
+ };
282
+ }
283
+ return {
284
+ backend: "opencode",
285
+ config: { permissionDefault: "deny" },
286
+ nativeRules: buildOpenCodeNativeRules(normalized),
287
+ representableRules,
288
+ unsupportedRules,
289
+ constraintInstructions,
290
+ warnings,
291
+ };
292
+ }
293
+ if (backend === "claude") {
294
+ return {
295
+ backend: "claude",
296
+ config: { permissionMode: "default", allowDangerouslySkipPermissions: false },
297
+ nativeRules: buildClaudeNativeRules(representableRules),
298
+ representableRules,
299
+ unsupportedRules,
300
+ constraintInstructions,
301
+ warnings,
302
+ };
303
+ }
304
+ if (backend === "codex") {
305
+ return {
306
+ backend: "codex",
307
+ config: { approvalMode: approval, sandboxMode: sandbox },
308
+ nativeRules: { coarseOnly: true },
309
+ representableRules,
310
+ unsupportedRules,
311
+ constraintInstructions,
312
+ warnings,
313
+ };
314
+ }
315
+ return {
316
+ backend: "opencode",
317
+ config: { permissionDefault: "ask" },
318
+ nativeRules: buildOpenCodeNativeRules(normalized),
319
+ representableRules,
320
+ unsupportedRules,
321
+ constraintInstructions,
322
+ warnings,
323
+ };
324
+ }
325
+ export function translatePermissionForProvider(policy, provider) {
326
+ const normalized = normalizePermissionPolicy(policy);
327
+ const granularRules = collectTranslationRules(normalized);
328
+ const unsupportedRules = granularRules;
329
+ const constraintInstructions = buildConstraintInstructions(provider, unsupportedRules);
330
+ const warnings = [DIRECT_PROVIDER_POLICY_WARNING];
331
+ if (unsupportedRules.length > 0) {
332
+ warnings.push(`${unsupportedRules.length} granular permission rule(s) are not natively supported by ${provider} and require Kiln-side constraints`);
333
+ }
334
+ return {
335
+ provider,
336
+ unsupportedRules,
337
+ constraintInstructions,
338
+ warnings,
339
+ };
340
+ }
341
+ function collectTranslationRules(policy) {
342
+ const rules = [];
343
+ for (const toolRule of policy.tools) {
344
+ rules.push({
345
+ category: "tool",
346
+ selector: toolRule.tool,
347
+ action: toolRule.action,
348
+ reason: toolRule.reason,
349
+ });
350
+ }
351
+ for (const commandRule of policy.commands) {
352
+ const shell = commandRule.shell ?? "any";
353
+ rules.push({
354
+ category: "command",
355
+ selector: `${shell}:${commandRule.pattern}`,
356
+ action: commandRule.action,
357
+ reason: commandRule.reason,
358
+ });
359
+ }
360
+ for (const glob of policy.fileGovernance.denyGlobs ?? []) {
361
+ rules.push({
362
+ category: "file-governance",
363
+ selector: `deny:${glob}`,
364
+ action: "deny",
365
+ });
366
+ }
367
+ for (const glob of policy.fileGovernance.askGlobs ?? []) {
368
+ rules.push({
369
+ category: "file-governance",
370
+ selector: `ask:${glob}`,
371
+ action: "ask",
372
+ });
373
+ }
374
+ for (const glob of policy.fileGovernance.allowGlobs ?? []) {
375
+ rules.push({
376
+ category: "file-governance",
377
+ selector: `allow:${glob}`,
378
+ action: "allow",
379
+ });
380
+ }
381
+ for (const dataFirewallRule of policy.dataFirewall) {
382
+ const classes = dataFirewallRule.classifications?.length
383
+ ? `[${dataFirewallRule.classifications.join(",")}]`
384
+ : "";
385
+ rules.push({
386
+ category: "data-firewall",
387
+ selector: `${dataFirewallRule.destination}${classes}`,
388
+ action: dataFirewallRule.action,
389
+ reason: dataFirewallRule.reason,
390
+ });
391
+ }
392
+ for (const agentScope of policy.agentScopes) {
393
+ const mode = agentScope.inherit === false ? "replace" : "inherit";
394
+ rules.push({
395
+ category: "agent-scope",
396
+ selector: `${agentScope.agent}:${mode}`,
397
+ action: mode,
398
+ });
399
+ }
400
+ return rules;
401
+ }
402
+ function isRepresentableByBackend(rule, backend) {
403
+ if (backend === "codex")
404
+ return false;
405
+ if (backend === "claude") {
406
+ return rule.category === "tool" || rule.category === "command";
407
+ }
408
+ return rule.category === "tool"
409
+ || rule.category === "command"
410
+ || rule.category === "file-governance";
411
+ }
412
+ function buildConstraintInstructions(backend, unsupportedRules) {
413
+ if (unsupportedRules.length === 0)
414
+ return [];
415
+ const lines = [`Kiln policy constraints for ${backend}:`];
416
+ for (const rule of unsupportedRules) {
417
+ lines.push(`[${rule.category}] ${rule.action.toUpperCase()} ${rule.selector}${rule.reason ? ` -- ${rule.reason}` : ""}`);
418
+ }
419
+ return lines;
420
+ }
421
+ function buildClaudeNativeRules(representableRules) {
422
+ const allow = [];
423
+ const deny = [];
424
+ const ask = [];
425
+ for (const rule of representableRules) {
426
+ const target = rule.category === "command"
427
+ ? `Bash(${rule.selector})`
428
+ : rule.selector;
429
+ if (rule.action === "allow") {
430
+ allow.push(target);
431
+ continue;
432
+ }
433
+ if (rule.action === "deny") {
434
+ deny.push(target);
435
+ continue;
436
+ }
437
+ ask.push(target);
438
+ }
439
+ return { allow, deny, ask };
440
+ }
441
+ function buildOpenCodeNativeRules(policy) {
442
+ const tools = policy.tools.map((rule) => ({
443
+ tool: rule.tool,
444
+ action: rule.action,
445
+ }));
446
+ const commands = policy.commands.map((rule) => ({
447
+ pattern: rule.pattern,
448
+ shell: rule.shell ?? "any",
449
+ action: rule.action,
450
+ }));
451
+ return {
452
+ tools,
453
+ commands,
454
+ fileGovernance: {
455
+ denyGlobs: [...(policy.fileGovernance.denyGlobs ?? [])],
456
+ askGlobs: [...(policy.fileGovernance.askGlobs ?? [])],
457
+ allowGlobs: [...(policy.fileGovernance.allowGlobs ?? [])],
458
+ },
459
+ };
460
+ }
461
+ const COST_TIER_RANK = {
462
+ low: 0,
463
+ medium: 1,
464
+ high: 2,
465
+ };
466
+ export class SessionUnavailableError extends Error {
467
+ requirements;
468
+ scores;
469
+ constructor(requirements, scores) {
470
+ super("No available session provider matches requirements");
471
+ this.requirements = requirements;
472
+ this.scores = scores;
473
+ this.name = "SessionUnavailableError";
474
+ }
475
+ }
476
+ export class SessionRegistry {
477
+ providers = new Map();
478
+ circuitBreakers = new Map();
479
+ suppressionWindowMs = 30_000;
480
+ failureThreshold = 3;
481
+ constructor(providers) {
482
+ for (const p of providers) {
483
+ this.providers.set(p.id, p);
484
+ this.circuitBreakers.set(p.id, {
485
+ state: "closed",
486
+ failureCount: 0,
487
+ lastFailureAt: null,
488
+ suppressUntil: null,
489
+ });
490
+ }
491
+ }
492
+ selectBest(requirements = {}) {
493
+ const allIds = [...this.providers.keys()];
494
+ const scores = [];
495
+ const candidates = [];
496
+ for (const id of allIds) {
497
+ const descriptor = this.providers.get(id);
498
+ if (!descriptor)
499
+ continue;
500
+ const score = this._score(descriptor, requirements);
501
+ scores.push(score);
502
+ if (!score.excluded && this._isAvailable(id)) {
503
+ candidates.push(id);
504
+ }
505
+ }
506
+ if (candidates.length === 0) {
507
+ throw new SessionUnavailableError(requirements, scores);
508
+ }
509
+ candidates.sort((a, b) => {
510
+ const sa = scores.find((s) => s.id === a);
511
+ const sb = scores.find((s) => s.id === b);
512
+ return sb.score - sa.score;
513
+ });
514
+ const primary = candidates[0];
515
+ const orderedFallbacks = candidates.slice(1);
516
+ return { primary, orderedFallbacks, scores };
517
+ }
518
+ createSession(id, config) {
519
+ const descriptor = this.providers.get(id);
520
+ if (!descriptor) {
521
+ throw new Error(`Unknown provider: ${id}`);
522
+ }
523
+ return descriptor.create(config);
524
+ }
525
+ reportSuccess(id) {
526
+ const cb = this.circuitBreakers.get(id);
527
+ if (!cb)
528
+ return;
529
+ if (cb.state === "half-open") {
530
+ cb.state = "closed";
531
+ cb.failureCount = 0;
532
+ cb.lastFailureAt = null;
533
+ cb.suppressUntil = null;
534
+ }
535
+ else if (cb.state === "closed") {
536
+ cb.failureCount = 0;
537
+ }
538
+ }
539
+ reportFailure(id, _isPreflightCrash) {
540
+ const cb = this.circuitBreakers.get(id);
541
+ if (!cb)
542
+ return;
543
+ cb.lastFailureAt = Date.now();
544
+ if (cb.state === "half-open") {
545
+ cb.state = "open";
546
+ cb.suppressUntil = Date.now() + this.suppressionWindowMs;
547
+ }
548
+ else {
549
+ cb.failureCount += 1;
550
+ if (cb.failureCount >= this.failureThreshold) {
551
+ cb.state = "open";
552
+ cb.suppressUntil = Date.now() + this.suppressionWindowMs;
553
+ }
554
+ }
555
+ }
556
+ getHealth(id) {
557
+ const cb = this.circuitBreakers.get(id);
558
+ if (!cb)
559
+ return "healthy";
560
+ if (cb.state === "half-open")
561
+ return "half-open";
562
+ if (cb.state === "open") {
563
+ if (cb.suppressUntil !== null && Date.now() >= cb.suppressUntil) {
564
+ cb.state = "half-open";
565
+ return "half-open";
566
+ }
567
+ return "suppressed";
568
+ }
569
+ return "healthy";
570
+ }
571
+ list() {
572
+ const ids = [...this.providers.keys()];
573
+ return ids
574
+ .map((id) => {
575
+ const descriptor = this.providers.get(id);
576
+ if (!descriptor)
577
+ return null;
578
+ return { ...descriptor, health: this.getHealth(id) };
579
+ })
580
+ .filter((x) => x !== null);
581
+ }
582
+ _isAvailable(id) {
583
+ const descriptor = this.providers.get(id);
584
+ if (!descriptor)
585
+ return false;
586
+ if (descriptor.isAvailable && !descriptor.isAvailable())
587
+ return false;
588
+ const cb = this.circuitBreakers.get(id);
589
+ if (!cb)
590
+ return true;
591
+ if (cb.state === "closed")
592
+ return true;
593
+ if (cb.state === "half-open")
594
+ return true;
595
+ if (cb.state === "open") {
596
+ if (cb.suppressUntil !== null && Date.now() >= cb.suppressUntil) {
597
+ cb.state = "half-open";
598
+ return true;
599
+ }
600
+ return false;
601
+ }
602
+ return true;
603
+ }
604
+ _score(descriptor, requirements) {
605
+ const reasons = [];
606
+ let score = 0;
607
+ let excluded = false;
608
+ let exclusionReason;
609
+ if (requirements.preferredProvider === descriptor.id) {
610
+ score += 100;
611
+ reasons.push(`preferred provider: ${descriptor.id}`);
612
+ }
613
+ if (requirements.requiresMcp && !descriptor.capabilities.mcp) {
614
+ excluded = true;
615
+ exclusionReason = `requires MCP but ${descriptor.id} does not support it`;
616
+ }
617
+ if (requirements.requiresStreaming && !descriptor.capabilities.streaming) {
618
+ excluded = true;
619
+ exclusionReason = `requires streaming but ${descriptor.id} does not support it`;
620
+ }
621
+ if (requirements.requiresResume && !descriptor.capabilities.resume) {
622
+ excluded = true;
623
+ exclusionReason = `requires resume but ${descriptor.id} does not support it`;
624
+ }
625
+ if (!excluded && requirements.maxCostTier !== undefined) {
626
+ const maxRank = COST_TIER_RANK[requirements.maxCostTier];
627
+ const descRank = COST_TIER_RANK[descriptor.costTier];
628
+ if (descRank <= maxRank) {
629
+ score += 50;
630
+ reasons.push(`cost tier ${descriptor.costTier} within limit`);
631
+ }
632
+ }
633
+ if (!excluded) {
634
+ score += (4 - descriptor.capabilities.priority) * 10;
635
+ reasons.push(`priority ${descriptor.capabilities.priority}`);
636
+ }
637
+ if (!excluded) {
638
+ const fieldPressure = getFieldStrength(`provider:${descriptor.id}`);
639
+ if (fieldPressure > 0) {
640
+ const bonus = Math.min(fieldPressure * 15, 15);
641
+ score += bonus;
642
+ reasons.push(`field pressure +${bonus.toFixed(2)}`);
643
+ }
644
+ }
645
+ if (!excluded) {
646
+ reasons.push(`${descriptor.id} is available`);
647
+ }
648
+ return {
649
+ id: descriptor.id,
650
+ score,
651
+ reasons: reasons,
652
+ excluded,
653
+ exclusionReason,
654
+ };
655
+ }
656
+ }
657
+ const DEFAULT_POLICY = { approval: "on-request", sandbox: "read-only" };
658
+ export function createDefaultRegistry() {
659
+ const worktreeManager = new WorktreeManager(process.cwd());
660
+ worktreeManager.pruneStale().catch((err) => {
661
+ debug("pruneStale error:", err instanceof Error ? err.message : String(err));
662
+ });
663
+ const providers = [
664
+ {
665
+ id: "codex-oauth",
666
+ costTier: "low",
667
+ capabilities: {
668
+ mcp: false,
669
+ streaming: true,
670
+ resumable: false,
671
+ resume: false,
672
+ costTrackingMode: "computed",
673
+ supportedTools: ["bash", "read", "write", "edit", "grep", "glob", "git"],
674
+ maxContextTokens: null,
675
+ priority: 1,
676
+ fallbackTo: null,
677
+ permissionPolicy: DEFAULT_POLICY,
678
+ },
679
+ isAvailable: () => CODEX_OAUTH_AVAILABLE,
680
+ create: (config) => {
681
+ const translated = translatePermissionForProvider(config.permissionPolicy, "codex-oauth");
682
+ for (const warning of translated.warnings) {
683
+ debug("[provider:codex-oauth]", warning);
684
+ }
685
+ return new ExecutableProviderSession({
686
+ provider: "codex-oauth",
687
+ model: config.model,
688
+ task: config.task,
689
+ systemPrompt: config.systemPrompt,
690
+ cwd: config.cwd,
691
+ env: config.env,
692
+ permissionPolicy: config.permissionPolicy,
693
+ constraintInstructions: translated.constraintInstructions,
694
+ });
695
+ },
696
+ },
697
+ {
698
+ id: "claude",
699
+ costTier: "high",
700
+ capabilities: {
701
+ mcp: true,
702
+ streaming: true,
703
+ resumable: false,
704
+ resume: false,
705
+ costTrackingMode: "native",
706
+ supportedTools: [],
707
+ maxContextTokens: null,
708
+ priority: 1,
709
+ fallbackTo: null,
710
+ permissionPolicy: DEFAULT_POLICY,
711
+ },
712
+ create: (config) => {
713
+ const translated = translatePermission(config.permissionPolicy, "claude");
714
+ const cfg = translated.config;
715
+ return new ClaudeSession({
716
+ task: config.task,
717
+ systemPrompt: config.systemPrompt ?? "",
718
+ mcpServers: config.mcpServers,
719
+ cwd: config.cwd ?? process.cwd(),
720
+ env: config.env,
721
+ permissionMode: cfg.permissionMode,
722
+ allowDangerouslySkipPermissions: cfg.allowDangerouslySkipPermissions,
723
+ nativeRules: translated.nativeRules,
724
+ representableRules: translated.representableRules,
725
+ unsupportedRules: translated.unsupportedRules,
726
+ constraintInstructions: translated.constraintInstructions,
727
+ translationWarnings: translated.warnings,
728
+ resumeSessionId: config.resumeSessionId,
729
+ model: config.model,
730
+ });
731
+ },
732
+ },
733
+ {
734
+ id: "codex",
735
+ costTier: "low",
736
+ capabilities: {
737
+ mcp: false,
738
+ streaming: true,
739
+ resumable: false,
740
+ resume: false,
741
+ costTrackingMode: "computed",
742
+ supportedTools: [],
743
+ maxContextTokens: null,
744
+ priority: 3,
745
+ fallbackTo: null,
746
+ permissionPolicy: DEFAULT_POLICY,
747
+ },
748
+ create: (config) => {
749
+ const translated = translatePermission(config.permissionPolicy, "codex");
750
+ const cfg = translated.config;
751
+ return new CodexSession({
752
+ task: config.task,
753
+ model: config.model,
754
+ cwd: config.cwd,
755
+ env: config.env,
756
+ approvalMode: cfg.approvalMode,
757
+ sandboxMode: cfg.sandboxMode,
758
+ ephemeral: config.ephemeral,
759
+ profile: config.profile,
760
+ skipGitRepoCheck: config.skipGitRepoCheck,
761
+ outputSchema: config.outputSchema,
762
+ addDir: config.addDir,
763
+ localProvider: config.localProvider,
764
+ nativeRules: translated.nativeRules,
765
+ representableRules: translated.representableRules,
766
+ unsupportedRules: translated.unsupportedRules,
767
+ constraintInstructions: translated.constraintInstructions,
768
+ translationWarnings: translated.warnings,
769
+ resumeSessionId: config.resumeSessionId,
770
+ });
771
+ },
772
+ },
773
+ {
774
+ id: "opencode",
775
+ costTier: "medium",
776
+ capabilities: {
777
+ mcp: true,
778
+ streaming: true,
779
+ resumable: false,
780
+ resume: false,
781
+ costTrackingMode: "native",
782
+ supportedTools: [],
783
+ maxContextTokens: null,
784
+ priority: 2,
785
+ fallbackTo: null,
786
+ permissionPolicy: DEFAULT_POLICY,
787
+ },
788
+ create: (config) => {
789
+ const translated = translatePermission(config.permissionPolicy, "opencode");
790
+ const cfg = translated.config;
791
+ return new OpenCodeSession({
792
+ task: config.task,
793
+ model: config.model,
794
+ cwd: config.cwd ?? process.cwd(),
795
+ env: config.env,
796
+ mcpServers: config.mcpServers
797
+ ? Object.entries(config.mcpServers).map(([name, v]) => ({
798
+ name,
799
+ url: v.command,
800
+ }))
801
+ : [],
802
+ permissionDefault: cfg.permissionDefault,
803
+ sandboxMode: config.permissionPolicy.sandbox,
804
+ nativeRules: translated.nativeRules,
805
+ representableRules: translated.representableRules,
806
+ unsupportedRules: translated.unsupportedRules,
807
+ constraintInstructions: translated.constraintInstructions,
808
+ translationWarnings: translated.warnings,
809
+ resumeSessionId: config.resumeSessionId,
810
+ });
811
+ },
812
+ },
813
+ {
814
+ id: "anthropic",
815
+ costTier: "high",
816
+ capabilities: {
817
+ mcp: false,
818
+ streaming: true,
819
+ resumable: false,
820
+ resume: false,
821
+ costTrackingMode: "computed",
822
+ supportedTools: [],
823
+ maxContextTokens: null,
824
+ priority: 4,
825
+ fallbackTo: null,
826
+ permissionPolicy: DEFAULT_POLICY,
827
+ },
828
+ create: (config) => {
829
+ const translated = translatePermissionForProvider(config.permissionPolicy, "anthropic");
830
+ for (const warning of translated.warnings) {
831
+ debug("[provider:anthropic]", warning);
832
+ }
833
+ return new ProviderSession({
834
+ provider: "anthropic",
835
+ model: config.model,
836
+ task: config.task,
837
+ systemPrompt: config.systemPrompt,
838
+ cwd: config.cwd,
839
+ env: config.env,
840
+ permissionPolicy: config.permissionPolicy,
841
+ constraintInstructions: translated.constraintInstructions,
842
+ });
843
+ },
844
+ },
845
+ {
846
+ id: "openai",
847
+ costTier: "high",
848
+ capabilities: {
849
+ mcp: false,
850
+ streaming: true,
851
+ resumable: false,
852
+ resume: false,
853
+ costTrackingMode: "computed",
854
+ supportedTools: [],
855
+ maxContextTokens: null,
856
+ priority: 5,
857
+ fallbackTo: null,
858
+ permissionPolicy: DEFAULT_POLICY,
859
+ },
860
+ create: (config) => {
861
+ const translated = translatePermissionForProvider(config.permissionPolicy, "openai");
862
+ for (const warning of translated.warnings) {
863
+ debug("[provider:openai]", warning);
864
+ }
865
+ return new ProviderSession({
866
+ provider: "openai",
867
+ model: config.model,
868
+ task: config.task,
869
+ systemPrompt: config.systemPrompt,
870
+ cwd: config.cwd,
871
+ env: config.env,
872
+ permissionPolicy: config.permissionPolicy,
873
+ constraintInstructions: translated.constraintInstructions,
874
+ });
875
+ },
876
+ },
877
+ {
878
+ id: "openrouter",
879
+ costTier: "low",
880
+ capabilities: {
881
+ mcp: false,
882
+ streaming: true,
883
+ resumable: false,
884
+ resume: false,
885
+ costTrackingMode: "computed",
886
+ supportedTools: [],
887
+ maxContextTokens: null,
888
+ priority: 6,
889
+ fallbackTo: null,
890
+ permissionPolicy: DEFAULT_POLICY,
891
+ },
892
+ create: (config) => {
893
+ const translated = translatePermissionForProvider(config.permissionPolicy, "openrouter");
894
+ for (const warning of translated.warnings) {
895
+ debug("[provider:openrouter]", warning);
896
+ }
897
+ return new ProviderSession({
898
+ provider: "openrouter",
899
+ model: config.model,
900
+ task: config.task,
901
+ systemPrompt: config.systemPrompt,
902
+ cwd: config.cwd,
903
+ env: config.env,
904
+ permissionPolicy: config.permissionPolicy,
905
+ constraintInstructions: translated.constraintInstructions,
906
+ });
907
+ },
908
+ },
909
+ {
910
+ id: "deepseek",
911
+ costTier: "medium",
912
+ capabilities: {
913
+ mcp: false,
914
+ streaming: true,
915
+ resumable: false,
916
+ resume: false,
917
+ costTrackingMode: "computed",
918
+ supportedTools: [],
919
+ maxContextTokens: null,
920
+ priority: 7,
921
+ fallbackTo: null,
922
+ permissionPolicy: DEFAULT_POLICY,
923
+ },
924
+ create: (config) => {
925
+ const translated = translatePermissionForProvider(config.permissionPolicy, "deepseek");
926
+ for (const warning of translated.warnings) {
927
+ debug("[provider:deepseek]", warning);
928
+ }
929
+ return new ProviderSession({
930
+ provider: "deepseek",
931
+ model: config.model,
932
+ task: config.task,
933
+ systemPrompt: config.systemPrompt,
934
+ cwd: config.cwd,
935
+ env: config.env,
936
+ permissionPolicy: config.permissionPolicy,
937
+ constraintInstructions: translated.constraintInstructions,
938
+ });
939
+ },
940
+ },
941
+ {
942
+ id: "ollama",
943
+ costTier: "low",
944
+ capabilities: {
945
+ mcp: false,
946
+ streaming: true,
947
+ resumable: false,
948
+ resume: false,
949
+ costTrackingMode: "computed",
950
+ supportedTools: [],
951
+ maxContextTokens: null,
952
+ priority: 8,
953
+ fallbackTo: null,
954
+ permissionPolicy: DEFAULT_POLICY,
955
+ },
956
+ create: (config) => {
957
+ const translated = translatePermissionForProvider(config.permissionPolicy, "ollama");
958
+ for (const warning of translated.warnings) {
959
+ debug("[provider:ollama]", warning);
960
+ }
961
+ return new ProviderSession({
962
+ provider: "ollama",
963
+ model: config.model,
964
+ task: config.task,
965
+ systemPrompt: config.systemPrompt,
966
+ cwd: config.cwd,
967
+ env: config.env,
968
+ permissionPolicy: config.permissionPolicy,
969
+ constraintInstructions: translated.constraintInstructions,
970
+ });
971
+ },
972
+ },
973
+ ];
974
+ const registry = new SessionRegistry(providers);
975
+ return { registry, worktreeManager };
976
+ }
977
+ //# sourceMappingURL=session-registry.js.map