@elie-laloum/outpost 5.0.0 → 6.0.1

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 (270) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +11 -11
  3. package/SECURITY.md +2 -0
  4. package/dist/adapters/agents/antigravity-adapter.d.ts +3 -0
  5. package/dist/adapters/agents/antigravity-adapter.js +39 -0
  6. package/dist/adapters/agents/antigravity-adapter.js.map +1 -0
  7. package/dist/adapters/agents/antigravity-authentication.d.ts +2 -0
  8. package/dist/adapters/agents/antigravity-authentication.js +27 -0
  9. package/dist/adapters/agents/antigravity-authentication.js.map +1 -0
  10. package/dist/adapters/agents/antigravity-diagnostics.d.ts +1 -0
  11. package/dist/adapters/agents/antigravity-diagnostics.js +6 -0
  12. package/dist/adapters/agents/antigravity-diagnostics.js.map +1 -0
  13. package/dist/adapters/agents/antigravity-events.d.ts +2 -0
  14. package/dist/adapters/agents/antigravity-events.js +66 -0
  15. package/dist/adapters/agents/antigravity-events.js.map +1 -0
  16. package/dist/adapters/agents/antigravity-request.d.ts +5 -0
  17. package/dist/adapters/agents/antigravity-request.js +29 -0
  18. package/dist/adapters/agents/antigravity-request.js.map +1 -0
  19. package/dist/adapters/agents/{gemini.types.d.ts → antigravity.types.d.ts} +2 -2
  20. package/dist/adapters/agents/antigravity.types.js +2 -0
  21. package/dist/adapters/agents/antigravity.types.js.map +1 -0
  22. package/dist/adapters/agents/authentication.constants.d.ts +19 -9
  23. package/dist/adapters/agents/authentication.constants.js +12 -9
  24. package/dist/adapters/agents/authentication.constants.js.map +1 -1
  25. package/dist/adapters/agents/authentication.d.ts +11 -2
  26. package/dist/adapters/agents/authentication.js +70 -47
  27. package/dist/adapters/agents/authentication.js.map +1 -1
  28. package/dist/adapters/agents/authentication.types.d.ts +20 -0
  29. package/dist/adapters/agents/authentication.types.js +2 -0
  30. package/dist/adapters/agents/authentication.types.js.map +1 -0
  31. package/dist/adapters/agents/claude-adapter.js +4 -2
  32. package/dist/adapters/agents/claude-adapter.js.map +1 -1
  33. package/dist/adapters/agents/claude-authentication.d.ts +2 -0
  34. package/dist/adapters/agents/claude-authentication.js +34 -0
  35. package/dist/adapters/agents/claude-authentication.js.map +1 -0
  36. package/dist/adapters/agents/cli-diagnostics.constants.d.ts +6 -6
  37. package/dist/adapters/agents/cli-diagnostics.constants.js +6 -6
  38. package/dist/adapters/agents/cli-diagnostics.constants.js.map +1 -1
  39. package/dist/adapters/agents/cli-diagnostics.d.ts +1 -0
  40. package/dist/adapters/agents/cli-diagnostics.js +11 -0
  41. package/dist/adapters/agents/cli-diagnostics.js.map +1 -1
  42. package/dist/adapters/agents/codex-adapter.js +4 -2
  43. package/dist/adapters/agents/codex-adapter.js.map +1 -1
  44. package/dist/adapters/agents/codex-authentication.d.ts +3 -0
  45. package/dist/adapters/agents/codex-authentication.js +47 -0
  46. package/dist/adapters/agents/codex-authentication.js.map +1 -0
  47. package/dist/adapters/agents/copilot-adapter.d.ts +3 -0
  48. package/dist/adapters/agents/copilot-adapter.js +39 -0
  49. package/dist/adapters/agents/copilot-adapter.js.map +1 -0
  50. package/dist/adapters/agents/copilot-authentication.d.ts +2 -0
  51. package/dist/adapters/agents/copilot-authentication.js +45 -0
  52. package/dist/adapters/agents/copilot-authentication.js.map +1 -0
  53. package/dist/adapters/agents/copilot-diagnostics.d.ts +1 -0
  54. package/dist/adapters/agents/copilot-diagnostics.js +6 -0
  55. package/dist/adapters/agents/copilot-diagnostics.js.map +1 -0
  56. package/dist/adapters/agents/copilot-events.d.ts +2 -0
  57. package/dist/adapters/agents/copilot-events.js +50 -0
  58. package/dist/adapters/agents/copilot-events.js.map +1 -0
  59. package/dist/adapters/agents/copilot-request.d.ts +5 -0
  60. package/dist/adapters/agents/copilot-request.js +19 -0
  61. package/dist/adapters/agents/copilot-request.js.map +1 -0
  62. package/dist/adapters/agents/copilot.types.d.ts +6 -0
  63. package/dist/adapters/agents/copilot.types.js +2 -0
  64. package/dist/adapters/agents/copilot.types.js.map +1 -0
  65. package/dist/adapters/agents/event-decoder.d.ts +2 -2
  66. package/dist/adapters/agents/event-decoder.js +6 -5
  67. package/dist/adapters/agents/event-decoder.js.map +1 -1
  68. package/dist/adapters/agents/kimi-adapter.d.ts +3 -0
  69. package/dist/adapters/agents/kimi-adapter.js +35 -0
  70. package/dist/adapters/agents/kimi-adapter.js.map +1 -0
  71. package/dist/adapters/agents/kimi-authentication.d.ts +2 -0
  72. package/dist/adapters/agents/kimi-authentication.js +48 -0
  73. package/dist/adapters/agents/kimi-authentication.js.map +1 -0
  74. package/dist/adapters/agents/kimi-diagnostics.d.ts +1 -0
  75. package/dist/adapters/agents/kimi-diagnostics.js +6 -0
  76. package/dist/adapters/agents/kimi-diagnostics.js.map +1 -0
  77. package/dist/adapters/agents/kimi-events.d.ts +2 -0
  78. package/dist/adapters/agents/kimi-events.js +51 -0
  79. package/dist/adapters/agents/kimi-events.js.map +1 -0
  80. package/dist/adapters/agents/{gemini-request.d.ts → kimi-request.d.ts} +2 -2
  81. package/dist/adapters/agents/kimi-request.js +28 -0
  82. package/dist/adapters/agents/kimi-request.js.map +1 -0
  83. package/dist/adapters/agents/kimi.types.d.ts +6 -0
  84. package/dist/adapters/agents/kimi.types.js +2 -0
  85. package/dist/adapters/agents/kimi.types.js.map +1 -0
  86. package/dist/adapters/agents/model-support.constants.d.ts +3 -1
  87. package/dist/adapters/agents/model-support.constants.js +12 -2
  88. package/dist/adapters/agents/model-support.constants.js.map +1 -1
  89. package/dist/adapters/agents/protocol-fixtures.constants.d.ts +2 -2
  90. package/dist/adapters/agents/protocol-fixtures.constants.js +135 -9
  91. package/dist/adapters/agents/protocol-fixtures.constants.js.map +1 -1
  92. package/dist/adapters/agents/protocol-fixtures.types.d.ts +1 -0
  93. package/dist/adapters/agents/protocol-fixtures.types.js.map +1 -1
  94. package/dist/adapters/agents/protocol.d.ts +1 -0
  95. package/dist/adapters/agents/protocol.js +9 -0
  96. package/dist/adapters/agents/protocol.js.map +1 -1
  97. package/dist/application/agent-authentication.d.ts +4 -0
  98. package/dist/application/agent-authentication.js +32 -0
  99. package/dist/application/agent-authentication.js.map +1 -0
  100. package/dist/application/agent-bootstrap.constants.d.ts +2 -5
  101. package/dist/application/agent-bootstrap.constants.js +29 -4
  102. package/dist/application/agent-bootstrap.constants.js.map +1 -1
  103. package/dist/application/agent-bootstrap.js +33 -12
  104. package/dist/application/agent-bootstrap.js.map +1 -1
  105. package/dist/application/agent-bootstrap.types.d.ts +20 -0
  106. package/dist/application/agent-bootstrap.types.js +2 -0
  107. package/dist/application/agent-bootstrap.types.js.map +1 -0
  108. package/dist/application/credential-installer.constants.d.ts +1 -0
  109. package/dist/application/credential-installer.constants.js +22 -0
  110. package/dist/application/credential-installer.constants.js.map +1 -0
  111. package/dist/application/doctor-agent.constants.d.ts +2 -8
  112. package/dist/application/doctor-agent.constants.js +40 -6
  113. package/dist/application/doctor-agent.constants.js.map +1 -1
  114. package/dist/application/doctor-agent.d.ts +2 -1
  115. package/dist/application/doctor-agent.js +11 -3
  116. package/dist/application/doctor-agent.js.map +1 -1
  117. package/dist/application/doctor-image.js +4 -6
  118. package/dist/application/doctor-image.js.map +1 -1
  119. package/dist/application/doctor-protocol.js +6 -11
  120. package/dist/application/doctor-protocol.js.map +1 -1
  121. package/dist/application/doctor-protocol.types.d.ts +1 -1
  122. package/dist/application/doctor-protocol.types.js.map +1 -1
  123. package/dist/application/doctor-sandbox.js +2 -5
  124. package/dist/application/doctor-sandbox.js.map +1 -1
  125. package/dist/application/doctor.js +2 -4
  126. package/dist/application/doctor.js.map +1 -1
  127. package/dist/application/doctor.types.d.ts +9 -1
  128. package/dist/application/doctor.types.js.map +1 -1
  129. package/dist/application/outpost.types.d.ts +0 -1
  130. package/dist/application/outpost.types.js.map +1 -1
  131. package/dist/application/recovery-retention.js +65 -24
  132. package/dist/application/recovery-retention.js.map +1 -1
  133. package/dist/application/sandbox-agents.js +9 -8
  134. package/dist/application/sandbox-agents.js.map +1 -1
  135. package/dist/application/sandbox-dispatch.js +0 -2
  136. package/dist/application/sandbox-dispatch.js.map +1 -1
  137. package/dist/application/sandbox-session.types.d.ts +5 -0
  138. package/dist/application/sandbox-session.types.js.map +1 -1
  139. package/dist/application/startup-recovery.js +1 -1
  140. package/dist/application/startup-recovery.js.map +1 -1
  141. package/dist/application/storage-reservation.js +9 -2
  142. package/dist/application/storage-reservation.js.map +1 -1
  143. package/dist/cli/doctor-command.js +5 -1
  144. package/dist/cli/doctor-command.js.map +1 -1
  145. package/dist/cli/init-authentication.d.ts +4 -1
  146. package/dist/cli/init-authentication.js +28 -33
  147. package/dist/cli/init-authentication.js.map +1 -1
  148. package/dist/cli/init-command.js +3 -3
  149. package/dist/cli/init-command.js.map +1 -1
  150. package/dist/cli/main.constants.d.ts +50 -13
  151. package/dist/cli/main.constants.js +70 -8
  152. package/dist/cli/main.constants.js.map +1 -1
  153. package/dist/cli/scaffold-files.js +1 -1
  154. package/dist/cli/scaffold-files.js.map +1 -1
  155. package/dist/cli/scaffold-validation.js +29 -22
  156. package/dist/cli/scaffold-validation.js.map +1 -1
  157. package/dist/cli/scaffold.constants.d.ts +0 -1
  158. package/dist/cli/scaffold.constants.js +5 -2
  159. package/dist/cli/scaffold.constants.js.map +1 -1
  160. package/dist/cli/scaffold.types.d.ts +8 -2
  161. package/dist/cli/scaffold.types.js.map +1 -1
  162. package/dist/cli/starters.js +1 -3
  163. package/dist/cli/starters.js.map +1 -1
  164. package/dist/domain/agent.types.d.ts +47 -11
  165. package/dist/domain/agent.types.js.map +1 -1
  166. package/dist/domain/authentication.constants.d.ts +3 -0
  167. package/dist/domain/authentication.constants.js +11 -0
  168. package/dist/domain/authentication.constants.js.map +1 -0
  169. package/dist/domain/authentication.d.ts +3 -0
  170. package/dist/domain/authentication.js +22 -0
  171. package/dist/domain/authentication.js.map +1 -0
  172. package/dist/domain/authentication.types.d.ts +5 -0
  173. package/dist/domain/authentication.types.js +2 -0
  174. package/dist/domain/authentication.types.js.map +1 -0
  175. package/dist/domain/harness.d.ts +2 -2
  176. package/dist/domain/harness.js.map +1 -1
  177. package/dist/domain/harness.types.d.ts +2 -2
  178. package/dist/domain/harness.types.js.map +1 -1
  179. package/dist/index.d.ts +4 -8
  180. package/dist/index.js +1 -3
  181. package/dist/index.js.map +1 -1
  182. package/dist/infrastructure/git/git.constants.d.ts +1 -1
  183. package/dist/infrastructure/git/git.constants.js +1 -0
  184. package/dist/infrastructure/git/git.constants.js.map +1 -1
  185. package/dist/infrastructure/host-credentials.constants.d.ts +1 -0
  186. package/dist/infrastructure/host-credentials.constants.js +2 -0
  187. package/dist/infrastructure/host-credentials.constants.js.map +1 -0
  188. package/dist/infrastructure/host-credentials.d.ts +4 -0
  189. package/dist/infrastructure/host-credentials.js +89 -0
  190. package/dist/infrastructure/host-credentials.js.map +1 -0
  191. package/dist/infrastructure/inspection-path.js +4 -3
  192. package/dist/infrastructure/inspection-path.js.map +1 -1
  193. package/dist/infrastructure/journal.js +7 -74
  194. package/dist/infrastructure/journal.js.map +1 -1
  195. package/dist/infrastructure/journal.types.d.ts +0 -2
  196. package/dist/infrastructure/journal.types.js.map +1 -1
  197. package/dist/infrastructure/local-transport.js +9 -4
  198. package/dist/infrastructure/local-transport.js.map +1 -1
  199. package/dist/infrastructure/repository-transport.constants.d.ts +1 -0
  200. package/dist/infrastructure/repository-transport.constants.js +2 -0
  201. package/dist/infrastructure/repository-transport.constants.js.map +1 -0
  202. package/dist/infrastructure/repository-transport.d.ts +2 -0
  203. package/dist/infrastructure/repository-transport.js +9 -0
  204. package/dist/infrastructure/repository-transport.js.map +1 -0
  205. package/dist/infrastructure/resource-activity-inspection.js +19 -24
  206. package/dist/infrastructure/resource-activity-inspection.js.map +1 -1
  207. package/dist/infrastructure/resource-activity.constants.d.ts +0 -1
  208. package/dist/infrastructure/resource-activity.constants.js +0 -1
  209. package/dist/infrastructure/resource-activity.constants.js.map +1 -1
  210. package/dist/infrastructure/resource-activity.js +20 -83
  211. package/dist/infrastructure/resource-activity.js.map +1 -1
  212. package/dist/infrastructure/storage-inventory.constants.js +1 -0
  213. package/dist/infrastructure/storage-inventory.constants.js.map +1 -1
  214. package/dist/infrastructure/storage-inventory.types.d.ts +1 -1
  215. package/dist/infrastructure/storage-inventory.types.js.map +1 -1
  216. package/dist/infrastructure/storage-reservations.types.d.ts +0 -8
  217. package/dist/infrastructure/storage-reservations.types.js.map +1 -1
  218. package/dist/infrastructure/transport-reservations.d.ts +1 -1
  219. package/dist/infrastructure/transport-reservations.js +14 -8
  220. package/dist/infrastructure/transport-reservations.js.map +1 -1
  221. package/dist/providers/agents.d.ts +7 -2
  222. package/dist/providers/agents.js +4 -1
  223. package/dist/providers/agents.js.map +1 -1
  224. package/dist/providers/versions.constants.d.ts +3 -1
  225. package/dist/providers/versions.constants.js +3 -1
  226. package/dist/providers/versions.constants.js.map +1 -1
  227. package/package.json +3 -3
  228. package/dist/adapters/agents/gemini-adapter.d.ts +0 -3
  229. package/dist/adapters/agents/gemini-adapter.js +0 -34
  230. package/dist/adapters/agents/gemini-adapter.js.map +0 -1
  231. package/dist/adapters/agents/gemini-diagnostics.d.ts +0 -2
  232. package/dist/adapters/agents/gemini-diagnostics.js +0 -15
  233. package/dist/adapters/agents/gemini-diagnostics.js.map +0 -1
  234. package/dist/adapters/agents/gemini-events.d.ts +0 -2
  235. package/dist/adapters/agents/gemini-events.js +0 -50
  236. package/dist/adapters/agents/gemini-events.js.map +0 -1
  237. package/dist/adapters/agents/gemini-request.js +0 -23
  238. package/dist/adapters/agents/gemini-request.js.map +0 -1
  239. package/dist/adapters/agents/gemini.types.js +0 -2
  240. package/dist/adapters/agents/gemini.types.js.map +0 -1
  241. package/dist/infrastructure/artifact-store.d.ts +0 -3
  242. package/dist/infrastructure/artifact-store.js +0 -110
  243. package/dist/infrastructure/artifact-store.js.map +0 -1
  244. package/dist/infrastructure/artifact-store.types.d.ts +0 -6
  245. package/dist/infrastructure/artifact-store.types.js +0 -2
  246. package/dist/infrastructure/artifact-store.types.js.map +0 -1
  247. package/dist/infrastructure/journal-retention.constants.d.ts +0 -4
  248. package/dist/infrastructure/journal-retention.constants.js +0 -5
  249. package/dist/infrastructure/journal-retention.constants.js.map +0 -1
  250. package/dist/infrastructure/journal-retention.d.ts +0 -2
  251. package/dist/infrastructure/journal-retention.js +0 -51
  252. package/dist/infrastructure/journal-retention.js.map +0 -1
  253. package/dist/infrastructure/storage-mutation-lock.constants.d.ts +0 -5
  254. package/dist/infrastructure/storage-mutation-lock.constants.js +0 -6
  255. package/dist/infrastructure/storage-mutation-lock.constants.js.map +0 -1
  256. package/dist/infrastructure/storage-mutation-lock.d.ts +0 -1
  257. package/dist/infrastructure/storage-mutation-lock.js +0 -21
  258. package/dist/infrastructure/storage-mutation-lock.js.map +0 -1
  259. package/dist/infrastructure/storage-reservations.constants.d.ts +0 -4
  260. package/dist/infrastructure/storage-reservations.constants.js +0 -5
  261. package/dist/infrastructure/storage-reservations.constants.js.map +0 -1
  262. package/dist/infrastructure/storage-reservations.d.ts +0 -2
  263. package/dist/infrastructure/storage-reservations.js +0 -150
  264. package/dist/infrastructure/storage-reservations.js.map +0 -1
  265. package/dist/infrastructure/workflow-checkpoint.d.ts +0 -3
  266. package/dist/infrastructure/workflow-checkpoint.js +0 -84
  267. package/dist/infrastructure/workflow-checkpoint.js.map +0 -1
  268. package/dist/infrastructure/workflow-checkpoint.types.d.ts +0 -6
  269. package/dist/infrastructure/workflow-checkpoint.types.js +0 -2
  270. package/dist/infrastructure/workflow-checkpoint.types.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.0.1
4
+
5
+ - Rebuild the English and French Guide from scratch with focused explanations and short, directly usable snippets. Introduce a new page structure, task-based navigation and a dedicated responsive Guide layout.
6
+ - Cover setup, agent configuration, sandboxes, workflows, persistence, monitoring, operations and the experimental model engine across 60 pages per language. Preserve the Reference content and navigation.
7
+ - Redirect retired Guide URLs to their new destinations, including localized links and continuation anchors. Validate rendered links, search, navigation and examples in both languages.
8
+ - Replace workshop preparation generation with compilation of Guide snippets, offline execution of selected examples and real Docker/Podman checks of the documented command example. Public library contracts are unchanged.
9
+
10
+ ## 6.0.0
11
+
12
+ Breaking changes, without compatibility aliases:
13
+
14
+ - Unify artifact, checkpoint, journal, resource activity and reservation persistence through Transport, with `localTransport()` for disk storage. Remove `fileArtifactStore`, `fileWorkflowCheckpointStore`, their option types, `logging.file` and `DispatchResult.log`; journals expose `logReference`. Default runtime objects live under `.outpost/storage`. Checkpoint and reservation crash recovery is explicit locally and remotely; old file layouts are not migrated. Git worktrees and execution staging remain filesystem operations. Local transports and inspection reads accept root-owned system links among ancestors, such as `/var` on macOS, and still reject links created by users.
15
+ - Rename `CustomHarness` to `Harness` and `CustomHarnessOptions` to `HarnessOptions`; the former `Harness` union becomes `AgentHarness` (`CliHarness | Harness`). Runtime behavior and discriminants are unchanged.
16
+ - Replace the `{ mode: "api-key" | "oauth-token" | "login", environment?, credentials? }` authentication shapes with `authentication: "account" | "usage" | { account: { file | key | variable } } | { usage: { key | variable } }` on every CLI harness, with the new `AccountCredential` and `UsageCredential` types. There is no automatic mode; unsupported forms fail when the agent is composed and list the accepted forms. `AgentAdapter.authenticate()` becomes `credentials(variables)`, returning a `CredentialPlan`.
17
+ - `outpost init --authentication` accepts `account`, `account-token` (Claude and Copilot) or `usage` and defaults to `account`; generated scripts no longer read credential files.
18
+ - Remove Gemini CLI, which no longer serves free, Google AI Pro and Ultra accounts: `geminiHarness()`, `GeminiSettings`, `agentVersions.gemini` and `doctor --agent gemini` are removed, and generated images no longer install `@google/gemini-cli`.
19
+
20
+ Unified CLI authentication:
21
+
22
+ - `account` copies the CLI's own host session into the private sandbox home: Claude `.credentials.json` (only `claudeAiOauth`), Codex `auth.json`, the Antigravity OAuth token file, the Copilot token stored in `config.json` (forwarded as `COPILOT_GITHUB_TOKEN`), and the Kimi Code credentials and device identifier followed by `kimi login` in the sandbox. `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `COPILOT_HOME` and `KIMI_CODE_HOME` relocate the host sources, and `account.file` selects a dedicated profile.
23
+ - `usage` forwards the CLI's standard API-key variable: `ANTHROPIC_API_KEY`, `OPENAI_API_KEY` followed by `codex login --with-api-key` in the sandbox, `GEMINI_API_KEY` with a generated Antigravity `settings.json`, or `KIMI_API_KEY` translated to Kimi's model variables with a required model. Codex with a custom `modelProvider` accepts only usage forms, applied to `apiKeyEnvironment`. Classic `ghp_` tokens are rejected for Copilot.
24
+ - Outpost reads only regular host files up to 1 MiB, never reads a system keychain, and installs credentials through one stdin-fed installer with 0700 directories and 0600 files. The local provider receives variables only: no file is written and no login command runs on the host.
25
+
26
+ New CLI harnesses:
27
+
28
+ - Add `antigravityHarness()`, `copilotHarness()` and `kimiHarness()` with `AntigravitySettings`, `CopilotSettings` and `KimiSettings`. They run fresh sessions without native capture, resume, fork or automatic response repairs, accept model names only and disable CLI auto-updates by default. Copilot and Kimi report no token usage. `doctor` accepts `antigravity`, `copilot` and `kimi`.
29
+ - Generated images, the published agent image lock and remote bootstrap pin GitHub Copilot CLI 1.0.88 and Kimi Code 2.1.1. Images install `agy` with the official Antigravity script into `/usr/local/bin`, and remote bootstrap runs the same script when `agy` is missing; `agy` is not version-pinned. Images set `XDG_CACHE_HOME=/tmp/.cache` so Copilot can load its native addon outside the noexec home.
30
+ - Protocols are covered by synthetic fixtures and help checks of the installed CLIs; live model runs of the three CLIs remain unvalidated.
31
+
3
32
  ## 5.0.0
4
33
 
5
34
  Breaking changes, without compatibility aliases:
package/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  [Documentation](https://elie-laloum.github.io/outpost/) · [Français](https://elie-laloum.github.io/outpost/fr/) · [API](https://elie-laloum.github.io/outpost/reference/) · [Changelog](CHANGELOG.md)
4
4
 
5
- Outpost is a TypeScript library for running coding agents in reusable sandboxes, managing their Git workspaces and composing typed workflows. Claude Code, Codex and Gemini CLI adapters work with Docker, Podman, Vercel, Daytona or explicit host execution. Gemini supports fresh sessions only; native conversation capture, resume and fork are available for Claude Code and Codex.
5
+ Outpost is a TypeScript library for running coding agents in reusable sandboxes, managing their Git workspaces and composing typed workflows. Claude Code, Codex, Antigravity, GitHub Copilot CLI and Kimi Code adapters work with Docker, Podman, Vercel, Daytona or explicit host execution. Each harness authenticates explicitly with your account login or an API key. Antigravity, Copilot and Kimi run fresh sessions only; native conversation capture, resume and fork are available for Claude Code and Codex.
6
6
 
7
- Version 5.0.0 composes every agent with `agent({ harness, model })`, moves reasoning and output limits onto the agent model, and adds an experimental built-in harness engine: Outpost drives a model provider with tools, hooks, permissions, persisted conversations, context strategies, skills and streaming. It contains breaking API changes. See the [changelog](CHANGELOG.md#500) for details and migration notes, and the [roadmap](https://elie-laloum.github.io/outpost/project/roadmap/) for remaining validation and upcoming priorities.
7
+ Version 6.0.0 unifies CLI authentication: every harness selects `account` (your host login, copied into the private sandbox home) or `usage` (an API key), and Outpost never reads a system keychain. It replaces Gemini CLI with Antigravity, GitHub Copilot CLI and Kimi Code harnesses, routes all runtime persistence through storage transports, and renames the harness types. It contains breaking API changes. See the [changelog](CHANGELOG.md#600) for details and migration notes, and the [roadmap](https://elie-laloum.github.io/outpost/project/roadmap/) for remaining validation and upcoming priorities.
8
8
 
9
9
  ## Get started
10
10
 
11
- New to Outpost? Follow the [complete first-run workshop](https://elie-laloum.github.io/outpost/guide/start/quickstart/): choose Codex or Claude and account or API-key access, create a disposable TypeScript repository, then fix and verify a real test. The [Guide](https://elie-laloum.github.io/outpost/guide/) teaches the concepts; the [Reference](https://elie-laloum.github.io/outpost/reference/) explains exact contracts. Every [cookbook recipe](https://elie-laloum.github.io/outpost/guide/cookbook/) includes its own preparation and runnable code.
11
+ Start with [Setup](https://elie-laloum.github.io/outpost/guide/setup/), then [send your first request](https://elie-laloum.github.io/outpost/guide/first-request/). The [Guide](https://elie-laloum.github.io/outpost/guide/introduction/) explains each capability with focused snippets; the [Reference](https://elie-laloum.github.io/outpost/reference/) documents exact API contracts.
12
12
 
13
13
  Requires Node.js **24+**, Git, a target repository with a commit, and the credentials of your chosen agent. The workflow can live in its own directory. This example uses Docker.
14
14
 
@@ -18,37 +18,37 @@ cd workflow1
18
18
  npx @elie-laloum/outpost init --yes --repository /path1/repository --install
19
19
  ```
20
20
 
21
- Copy `.env.example` to `.env` and declare `OPENAI_API_KEY`. An empty declaration inherits the matching process variable. Then run the generated script:
21
+ The generated script uses `authentication: "account"`: log in to Codex on the host with file credential storage (`codex -c cli_auth_credentials_store='"file"' login`), and Outpost copies that login into the private sandbox home. For API billing instead, add `--authentication usage`, copy `.env.example` to `.env` and declare `OPENAI_API_KEY`; an empty declaration inherits the matching process variable. Then run the generated script:
22
22
 
23
23
  ```sh
24
24
  node run.ts "Add validation, run tests and commit the change"
25
25
  ```
26
26
 
27
- `init` creates `package.json`, `run.ts`, `brief.md`, `.env.example`, `.gitignore` and a container recipe directly in the workflow directory. Existing package manifests are preserved; explicit CommonJS projects get `run.mts` for compatibility. The script resolves its brief, environment and relative repository paths from its own directory. See [multi-repository workflows](https://elie-laloum.github.io/outpost/guide/workflows/sandbox-tasks/) to orchestrate several repositories.
27
+ `init` creates `package.json`, `run.ts`, `brief.md`, `.env.example`, `.gitignore` and a container recipe directly in the workflow directory. Existing package manifests are preserved; explicit CommonJS projects get `run.mts` for compatibility. The script resolves its brief, environment and relative repository paths from its own directory. See [multi-repository workflows](https://elie-laloum.github.io/outpost/guide/parallel-repositories/) to orchestrate several repositories.
28
28
 
29
- Generated Codex API-key workflows prepare login inside the sandbox. For account login and credential storage, see [Connect Codex](https://elie-laloum.github.io/outpost/guide/agents/connect-codex/) before dispatching.
29
+ Outpost never reads a system keychain. See [authentication](https://elie-laloum.github.io/outpost/guide/access-credentials/) for every agent's account and API-key forms before dispatching.
30
30
 
31
31
  ## Use the library
32
32
 
33
- After preparing the selected agent credentials and provider, library calls follow this shape. For a fully runnable version with explicit authentication, use the [dispatch workshop](https://elie-laloum.github.io/outpost/guide/agents/dispatch/).
33
+ After preparing the selected agent credentials and provider, library calls follow this shape. For configuration and a first call, see [First request](https://elie-laloum.github.io/outpost/guide/first-request/).
34
34
 
35
35
  ```ts
36
36
  import { agent, dispatch, codexHarness } from "@elie-laloum/outpost";
37
37
 
38
38
  const result = await dispatch({
39
39
  repository: "/path1/repository",
40
- agent: agent({ harness: codexHarness({}) }),
40
+ agent: agent({ harness: codexHarness({ authentication: "account" }) }),
41
41
  branch: { mode: "integrate" },
42
42
  brief: { text: "Fix the failing tests, verify and commit." },
43
43
  });
44
44
  console.log(result.branch, result.commits);
45
45
  ```
46
46
 
47
- `repository` selects a local Git checkout; without it, library calls use the current working directory. See [repository paths](https://elie-laloum.github.io/outpost/guide/environment/repositories/) for external checkouts and paths relative to the workflow script.
47
+ `repository` selects a local Git checkout; without it, library calls use the current working directory. See [repository paths](https://elie-laloum.github.io/outpost/guide/repository-context/) for external checkouts and paths relative to the workflow script.
48
48
 
49
- Let Outpost drive a model itself with `harness({ modelProvider, tools, instructions, limits })` and tools from `defineHarnessTool()`, then compose it with `agent({ harness, model })`. See [build a custom harness](https://elie-laloum.github.io/outpost/guide/agents/harness/) for a complete example.
49
+ Let Outpost drive a model itself with `harness({ modelProvider, tools, instructions, limits })` and tools from `defineHarnessTool()`, then compose it with `agent({ harness, model })`. See [build a custom harness](https://elie-laloum.github.io/outpost/guide/model-loop/) for configuration.
50
50
 
51
- Learn about [sandboxes](https://elie-laloum.github.io/outpost/guide/environment/lifecycle/), [workflows](https://elie-laloum.github.io/outpost/guide/workflows/graph/), [providers](https://elie-laloum.github.io/outpost/guide/environment/providers/overview/) and [recovery](https://elie-laloum.github.io/outpost/guide/operations/recovery/) in the English/French documentation. The [roadmap](https://elie-laloum.github.io/outpost/project/roadmap/) describes future work.
51
+ Learn about [sandboxes](https://elie-laloum.github.io/outpost/guide/sandbox-sessions/), [workflows](https://elie-laloum.github.io/outpost/guide/task-dependencies/), [providers](https://elie-laloum.github.io/outpost/guide/execution-backends/) and [recovery](https://elie-laloum.github.io/outpost/guide/failure-recovery/) in the English/French documentation. The [roadmap](https://elie-laloum.github.io/outpost/project/roadmap/) describes future work.
52
52
 
53
53
  ## Development
54
54
 
package/SECURITY.md CHANGED
@@ -12,6 +12,8 @@ Remote providers upload repository history and inputs to the selected cloud acco
12
12
 
13
13
  Prompt command expansion only recognizes commands present in the original prompt file. Substitution cannot introduce new expansion fragments. Values substituted inside an original shell command still have shell semantics and must be trusted or quoted by the prompt author.
14
14
 
15
+ Agent authentication is explicit. `account` reads only the selected CLI's own session file (or the file or profile named by `account.file`) on the host, refuses links, directories and files above 1 MiB, and never reads a system keychain. Isolated providers receive a copy in the private sandbox home through stdin, with 0700 directories and 0600 files; `localSandboxProvider()` receives credential variables only and no host file is written. A sandbox copy can refresh and rotate a subscription refresh token, invalidating the host login; use a dedicated profile through `account.file` when that matters. Agents can read every credential they receive, so give them only the access their task requires. Generated images and remote bootstrap install npm CLIs at pinned versions, but install the Antigravity CLI with Google's official script, which fetches the current release: build and pin your own image when you need a reviewed agent binary.
16
+
15
17
  Conversation transcripts, logs, bundles and patches may contain secrets. Runtime files are ignored by Git and sensitive files are created with restrictive permissions where supported. Keep API keys in environment variables or ignored `.env` files. Never embed tokens in tracked configuration, remote URLs or examples.
16
18
 
17
19
  Report vulnerabilities privately using the repository's security reporting channel when enabled, or contact the maintainer through the hosting profile. Do not include live credentials in reports. V1 receives fixes for reproducible security defects.
@@ -0,0 +1,3 @@
1
+ import type { CliHarness } from "../../domain/agent.types.ts";
2
+ import type { AntigravitySettings } from "./antigravity.types.ts";
3
+ export declare function antigravityHarness(settings?: AntigravitySettings): CliHarness;
@@ -0,0 +1,39 @@
1
+ import { antigravityCredentials } from "./antigravity-authentication.js";
2
+ import { antigravityEvents } from "./antigravity-events.js";
3
+ import { antigravityRequest } from "./antigravity-request.js";
4
+ import { credentialPlanner } from "./authentication.js";
5
+ import { antigravityModelSupport } from "./model-support.constants.js";
6
+ import { harnessSettings, supportModel } from "./model-support.js";
7
+ function bindAntigravity(settings) {
8
+ supportModel(antigravityModelSupport, settings.model);
9
+ const credentials = credentialPlanner("Antigravity", antigravityCredentials, settings.authentication, settings.model);
10
+ return Object.freeze({
11
+ name: "antigravity",
12
+ ...(credentials ? { credentials } : {}),
13
+ bootstrap: "antigravity",
14
+ resumable: false,
15
+ capture: false,
16
+ requiresFinishedEvent: true,
17
+ variables: Object.freeze({
18
+ AGY_CLI_DISABLE_AUTO_UPDATE: "true",
19
+ ...settings.variables,
20
+ }),
21
+ request: (input) => antigravityRequest(settings, input),
22
+ events: antigravityEvents,
23
+ });
24
+ }
25
+ export function antigravityHarness(settings = {}) {
26
+ harnessSettings(settings);
27
+ const configured = Object.freeze({
28
+ ...settings,
29
+ variables: Object.freeze({ ...settings.variables }),
30
+ });
31
+ return Object.freeze({
32
+ kind: "cli",
33
+ bind: (model) => bindAntigravity({
34
+ ...configured,
35
+ ...(model === undefined ? {} : { model }),
36
+ }),
37
+ });
38
+ }
39
+ //# sourceMappingURL=antigravity-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity-adapter.js","sourceRoot":"","sources":["../../../src/adapters/agents/antigravity-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGnE,SAAS,eAAe,CAAC,QAAoC;IAC3D,YAAY,CAAC,uBAAuB,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,WAAW,GAAG,iBAAiB,CACnC,aAAa,EACb,sBAAsB,EACtB,QAAQ,CAAC,cAAc,EACvB,QAAQ,CAAC,KAAK,CACf,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,aAAa;QACnB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,SAAS,EAAE,aAAa;QACxB,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,KAAK;QACd,qBAAqB,EAAE,IAAI;QAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC;YACvB,2BAA2B,EAAE,MAAM;YACnC,GAAG,QAAQ,CAAC,SAAS;SACtB,CAAC;QACF,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC;QACvD,MAAM,EAAE,iBAAiB;KACH,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,WAAgC,EAAE;IAElC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1B,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;QAC/B,GAAG,QAAQ;QACX,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;KACpD,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,CAAC,KAAkB,EAAE,EAAE,CAC3B,eAAe,CAAC;YACd,GAAG,UAAU;YACb,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;SAC1C,CAAC;KACL,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { AgentAdapter, CliHarness } from \"../../domain/agent.types.ts\";\nimport type { AgentModel } from \"../../domain/model.types.ts\";\nimport { antigravityCredentials } from \"./antigravity-authentication.ts\";\nimport { antigravityEvents } from \"./antigravity-events.ts\";\nimport { antigravityRequest } from \"./antigravity-request.ts\";\nimport type { AntigravitySettings } from \"./antigravity.types.ts\";\nimport { credentialPlanner } from \"./authentication.ts\";\nimport { antigravityModelSupport } from \"./model-support.constants.ts\";\nimport { harnessSettings, supportModel } from \"./model-support.ts\";\nimport type { Bound } from \"./settings.types.ts\";\n\nfunction bindAntigravity(settings: Bound<AntigravitySettings>): AgentAdapter {\n supportModel(antigravityModelSupport, settings.model);\n const credentials = credentialPlanner(\n \"Antigravity\",\n antigravityCredentials,\n settings.authentication,\n settings.model,\n );\n return Object.freeze({\n name: \"antigravity\",\n ...(credentials ? { credentials } : {}),\n bootstrap: \"antigravity\",\n resumable: false,\n capture: false,\n requiresFinishedEvent: true,\n variables: Object.freeze({\n AGY_CLI_DISABLE_AUTO_UPDATE: \"true\",\n ...settings.variables,\n }),\n request: (input) => antigravityRequest(settings, input),\n events: antigravityEvents,\n } satisfies AgentAdapter);\n}\n\nexport function antigravityHarness(\n settings: AntigravitySettings = {},\n): CliHarness {\n harnessSettings(settings);\n const configured = Object.freeze({\n ...settings,\n variables: Object.freeze({ ...settings.variables }),\n });\n return Object.freeze({\n kind: \"cli\",\n bind: (model?: AgentModel) =>\n bindAntigravity({\n ...configured,\n ...(model === undefined ? {} : { model }),\n }),\n });\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { CredentialStrategy } from "./authentication.types.ts";
2
+ export declare const antigravityCredentials: CredentialStrategy;
@@ -0,0 +1,27 @@
1
+ import { credentialRecipes, credentialVariables, } from "./authentication.constants.js";
2
+ import { hostFile, variableCredential } from "./authentication.js";
3
+ const file = hostFile({
4
+ source: { path: "~/.gemini/antigravity-cli/antigravity-oauth-token" },
5
+ destination: { file: ".gemini/antigravity-cli/antigravity-oauth-token" },
6
+ login: "agy and sign in with your Google account",
7
+ alternative: `"usage" with ${credentialVariables.antigravity.usage}`,
8
+ });
9
+ const key = variableCredential({
10
+ variable: credentialVariables.antigravity.usage,
11
+ expose: () => ({
12
+ files: [
13
+ {
14
+ path: ".gemini/antigravity-cli/settings.json",
15
+ content: credentialRecipes.antigravitySettings,
16
+ },
17
+ ],
18
+ }),
19
+ });
20
+ export const antigravityCredentials = Object.freeze({
21
+ account: file.preset,
22
+ "account.file": file.file,
23
+ usage: key.preset,
24
+ "usage.key": key.key,
25
+ "usage.variable": key.variable,
26
+ });
27
+ //# sourceMappingURL=antigravity-authentication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity-authentication.js","sourceRoot":"","sources":["../../../src/adapters/agents/antigravity-authentication.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGnE,MAAM,IAAI,GAAG,QAAQ,CAAC;IACpB,MAAM,EAAE,EAAE,IAAI,EAAE,mDAAmD,EAAE;IACrE,WAAW,EAAE,EAAE,IAAI,EAAE,iDAAiD,EAAE;IACxE,KAAK,EAAE,0CAA0C;IACjD,WAAW,EAAE,gBAAgB,mBAAmB,CAAC,WAAW,CAAC,KAAK,EAAE;CACrE,CAAC,CAAC;AAEH,MAAM,GAAG,GAAG,kBAAkB,CAAC;IAC7B,QAAQ,EAAE,mBAAmB,CAAC,WAAW,CAAC,KAAK;IAC/C,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACb,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,uCAAuC;gBAC7C,OAAO,EAAE,iBAAiB,CAAC,mBAAmB;aAC/C;SACF;KACF,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAuB,MAAM,CAAC,MAAM,CAAC;IACtE,OAAO,EAAE,IAAI,CAAC,MAAM;IACpB,cAAc,EAAE,IAAI,CAAC,IAAI;IACzB,KAAK,EAAE,GAAG,CAAC,MAAM;IACjB,WAAW,EAAE,GAAG,CAAC,GAAG;IACpB,gBAAgB,EAAE,GAAG,CAAC,QAAQ;CAC/B,CAAC,CAAC","sourcesContent":["import {\n credentialRecipes,\n credentialVariables,\n} from \"./authentication.constants.ts\";\nimport { hostFile, variableCredential } from \"./authentication.ts\";\nimport type { CredentialStrategy } from \"./authentication.types.ts\";\n\nconst file = hostFile({\n source: { path: \"~/.gemini/antigravity-cli/antigravity-oauth-token\" },\n destination: { file: \".gemini/antigravity-cli/antigravity-oauth-token\" },\n login: \"agy and sign in with your Google account\",\n alternative: `\"usage\" with ${credentialVariables.antigravity.usage}`,\n});\n\nconst key = variableCredential({\n variable: credentialVariables.antigravity.usage,\n expose: () => ({\n files: [\n {\n path: \".gemini/antigravity-cli/settings.json\",\n content: credentialRecipes.antigravitySettings,\n },\n ],\n }),\n});\n\nexport const antigravityCredentials: CredentialStrategy = Object.freeze({\n account: file.preset,\n \"account.file\": file.file,\n usage: key.preset,\n \"usage.key\": key.key,\n \"usage.variable\": key.variable,\n});\n"]}
@@ -0,0 +1 @@
1
+ export declare function antigravityDiagnostics(): readonly import("./cli-diagnostics.types.ts").AgentCliDiagnostic[];
@@ -0,0 +1,6 @@
1
+ import { antigravityRequest } from "./antigravity-request.js";
2
+ import { helpDiagnostics } from "./cli-diagnostics.js";
3
+ export function antigravityDiagnostics() {
4
+ return helpDiagnostics((input) => antigravityRequest({}, input), "Usage of agy:");
5
+ }
6
+ //# sourceMappingURL=antigravity-diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity-diagnostics.js","sourceRoot":"","sources":["../../../src/adapters/agents/antigravity-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,UAAU,sBAAsB;IACpC,OAAO,eAAe,CACpB,CAAC,KAAK,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC,EACxC,eAAe,CAChB,CAAC;AACJ,CAAC","sourcesContent":["import { antigravityRequest } from \"./antigravity-request.ts\";\nimport { helpDiagnostics } from \"./cli-diagnostics.ts\";\n\nexport function antigravityDiagnostics() {\n return helpDiagnostics(\n (input) => antigravityRequest({}, input),\n \"Usage of agy:\",\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { AgentEvent } from "../../domain/agent.types.ts";
2
+ export declare function antigravityEvents(line: string): AgentEvent[];
@@ -0,0 +1,66 @@
1
+ import { decodeLine } from "./event-decoder.js";
2
+ import { asRecord, numberOrZero } from "./protocol.js";
3
+ const steps = {
4
+ agent_response: (step) => typeof step.text_delta === "string" && step.text_delta
5
+ ? [{ kind: "text", text: step.text_delta }]
6
+ : [],
7
+ tool: (step) => typeof step.tool_name === "string" &&
8
+ (step.state === "DONE" || step.state === "ERROR")
9
+ ? [
10
+ {
11
+ kind: "tool",
12
+ name: step.tool_name,
13
+ input: asRecord(step.tool_info).parameters,
14
+ },
15
+ ]
16
+ : [],
17
+ };
18
+ function failure(result, response) {
19
+ if (typeof result.error === "string" && result.error)
20
+ return result.error;
21
+ if (result.status === "SUCCESS" && !response.trim())
22
+ return "Antigravity returned an empty response";
23
+ return `Antigravity ended the turn with status ${String(result.status ?? "unknown")}`;
24
+ }
25
+ function result(event) {
26
+ const result = asRecord(event.result);
27
+ const usage = asRecord(result.usage);
28
+ const response = typeof result.response === "string" ? result.response : "";
29
+ const events = Object.keys(usage).length
30
+ ? [
31
+ {
32
+ kind: "usage",
33
+ tokens: {
34
+ input: numberOrZero(usage.input_tokens),
35
+ cached: numberOrZero(usage.cache_read_tokens),
36
+ output: numberOrZero(usage.output_tokens) +
37
+ numberOrZero(usage.thinking_tokens),
38
+ },
39
+ },
40
+ ]
41
+ : [];
42
+ if (result.status === "SUCCESS" && response.trim())
43
+ return [
44
+ ...events,
45
+ { kind: "result", text: response },
46
+ { kind: "finished" },
47
+ ];
48
+ return [...events, { kind: "failure", message: failure(result, response) }];
49
+ }
50
+ export function antigravityEvents(line) {
51
+ return decodeLine(line, {
52
+ init: (event) => typeof event.conversation_id === "string"
53
+ ? [{ kind: "conversation", id: event.conversation_id }]
54
+ : [],
55
+ step_update: (event) => {
56
+ const step = asRecord(event.step_update);
57
+ const decode = typeof step.step_type === "string" &&
58
+ Object.hasOwn(steps, step.step_type)
59
+ ? steps[step.step_type]
60
+ : undefined;
61
+ return decode?.(step) ?? [];
62
+ },
63
+ result,
64
+ }, "event");
65
+ }
66
+ //# sourceMappingURL=antigravity-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity-events.js","sourceRoot":"","sources":["../../../src/adapters/agents/antigravity-events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGvD,MAAM,KAAK,GAAkB;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CACvB,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU;QACpD,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;QAC3C,CAAC,CAAC,EAAE;IACR,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CACb,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;QAClC,CAAC,IAAI,CAAC,KAAK,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC;QAC/C,CAAC,CAAC;YACE;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS;gBACpB,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,UAAU;aAC3C;SACF;QACH,CAAC,CAAC,EAAE;CACT,CAAC;AAEF,SAAS,OAAO,CAAC,MAAsB,EAAE,QAAgB;IACvD,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IAC1E,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;QACjD,OAAO,wCAAwC,CAAC;IAClD,OAAO,0CAA0C,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,EAAE,CAAC;AACxF,CAAC;AAED,SAAS,MAAM,CAAC,KAAqB;IACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,MAAM,GAAiB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM;QACpD,CAAC,CAAC;YACE;gBACE,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE;oBACN,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC;oBACvC,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,iBAAiB,CAAC;oBAC7C,MAAM,EACJ,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC;wBACjC,YAAY,CAAC,KAAK,CAAC,eAAe,CAAC;iBACtC;aACF;SACF;QACH,CAAC,CAAC,EAAE,CAAC;IACP,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,EAAE;QAChD,OAAO;YACL,GAAG,MAAM;YACT,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;YAClC,EAAE,IAAI,EAAE,UAAU,EAAE;SACrB,CAAC;IACJ,OAAO,CAAC,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,UAAU,CACf,IAAI,EACJ;QACE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CACd,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ;YACvC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,KAAK,CAAC,eAAe,EAAE,CAAC;YACvD,CAAC,CAAC,EAAE;QACR,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;YACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACzC,MAAM,MAAM,GACV,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;gBAClC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC;gBAClC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;gBACvB,CAAC,CAAC,SAAS,CAAC;YAChB,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;QACD,MAAM;KACP,EACD,OAAO,CACR,CAAC;AACJ,CAAC","sourcesContent":["import type { AgentEvent } from \"../../domain/agent.types.ts\";\nimport { decodeLine } from \"./event-decoder.ts\";\nimport { asRecord, numberOrZero } from \"./protocol.ts\";\nimport type { EventDecoders, ProtocolRecord } from \"./protocol.types.ts\";\n\nconst steps: EventDecoders = {\n agent_response: (step) =>\n typeof step.text_delta === \"string\" && step.text_delta\n ? [{ kind: \"text\", text: step.text_delta }]\n : [],\n tool: (step) =>\n typeof step.tool_name === \"string\" &&\n (step.state === \"DONE\" || step.state === \"ERROR\")\n ? [\n {\n kind: \"tool\",\n name: step.tool_name,\n input: asRecord(step.tool_info).parameters,\n },\n ]\n : [],\n};\n\nfunction failure(result: ProtocolRecord, response: string): string {\n if (typeof result.error === \"string\" && result.error) return result.error;\n if (result.status === \"SUCCESS\" && !response.trim())\n return \"Antigravity returned an empty response\";\n return `Antigravity ended the turn with status ${String(result.status ?? \"unknown\")}`;\n}\n\nfunction result(event: ProtocolRecord): AgentEvent[] {\n const result = asRecord(event.result);\n const usage = asRecord(result.usage);\n const response = typeof result.response === \"string\" ? result.response : \"\";\n const events: AgentEvent[] = Object.keys(usage).length\n ? [\n {\n kind: \"usage\",\n tokens: {\n input: numberOrZero(usage.input_tokens),\n cached: numberOrZero(usage.cache_read_tokens),\n output:\n numberOrZero(usage.output_tokens) +\n numberOrZero(usage.thinking_tokens),\n },\n },\n ]\n : [];\n if (result.status === \"SUCCESS\" && response.trim())\n return [\n ...events,\n { kind: \"result\", text: response },\n { kind: \"finished\" },\n ];\n return [...events, { kind: \"failure\", message: failure(result, response) }];\n}\n\nexport function antigravityEvents(line: string): AgentEvent[] {\n return decodeLine(\n line,\n {\n init: (event) =>\n typeof event.conversation_id === \"string\"\n ? [{ kind: \"conversation\", id: event.conversation_id }]\n : [],\n step_update: (event) => {\n const step = asRecord(event.step_update);\n const decode =\n typeof step.step_type === \"string\" &&\n Object.hasOwn(steps, step.step_type)\n ? steps[step.step_type]\n : undefined;\n return decode?.(step) ?? [];\n },\n result,\n },\n \"event\",\n );\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import type { AgentInput } from "../../domain/agent.types.ts";
2
+ import type { Command } from "../../domain/command.types.ts";
3
+ import type { AntigravitySettings } from "./antigravity.types.ts";
4
+ import type { Bound } from "./settings.types.ts";
5
+ export declare function antigravityRequest(settings: Bound<AntigravitySettings>, input: AgentInput): Command;
@@ -0,0 +1,29 @@
1
+ import { invariant } from "../../domain/errors.js";
2
+ export function antigravityRequest(settings, input) {
3
+ invariant(!input.continuation, "Antigravity does not support continuation or fork in Outpost");
4
+ const args = [];
5
+ if (settings.model)
6
+ args.push("--model", settings.model.name);
7
+ if (settings.mode)
8
+ args.push("--mode", settings.mode);
9
+ if (input.interactive)
10
+ return {
11
+ executable: "agy",
12
+ arguments: [
13
+ ...args,
14
+ ...(input.text === undefined
15
+ ? []
16
+ : ["--prompt-interactive", input.text]),
17
+ ],
18
+ interactive: true,
19
+ };
20
+ if (!settings.mode)
21
+ args.push("--dangerously-skip-permissions");
22
+ args.push("--input-format", "stream-json", "--output-format", "stream-json");
23
+ return {
24
+ executable: "agy",
25
+ arguments: args,
26
+ stdin: `${JSON.stringify({ event: "user", message: { content: input.text ?? "" } })}\n`,
27
+ };
28
+ }
29
+ //# sourceMappingURL=antigravity-request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity-request.js","sourceRoot":"","sources":["../../../src/adapters/agents/antigravity-request.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAInD,MAAM,UAAU,kBAAkB,CAChC,QAAoC,EACpC,KAAiB;IAEjB,SAAS,CACP,CAAC,KAAK,CAAC,YAAY,EACnB,8DAA8D,CAC/D,CAAC;IACF,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,QAAQ,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9D,IAAI,QAAQ,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,WAAW;QACnB,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,SAAS,EAAE;gBACT,GAAG,IAAI;gBACP,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;oBAC1B,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,CAAC,sBAAsB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;aAC1C;YACD,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,IAAI,CAAC,QAAQ,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAChE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;IAC7E,OAAO;QACL,UAAU,EAAE,KAAK;QACjB,SAAS,EAAE,IAAI;QACf,KAAK,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI;KACxF,CAAC;AACJ,CAAC","sourcesContent":["import type { AgentInput } from \"../../domain/agent.types.ts\";\nimport type { Command } from \"../../domain/command.types.ts\";\nimport { invariant } from \"../../domain/errors.ts\";\nimport type { AntigravitySettings } from \"./antigravity.types.ts\";\nimport type { Bound } from \"./settings.types.ts\";\n\nexport function antigravityRequest(\n settings: Bound<AntigravitySettings>,\n input: AgentInput,\n): Command {\n invariant(\n !input.continuation,\n \"Antigravity does not support continuation or fork in Outpost\",\n );\n const args: string[] = [];\n if (settings.model) args.push(\"--model\", settings.model.name);\n if (settings.mode) args.push(\"--mode\", settings.mode);\n if (input.interactive)\n return {\n executable: \"agy\",\n arguments: [\n ...args,\n ...(input.text === undefined\n ? []\n : [\"--prompt-interactive\", input.text]),\n ],\n interactive: true,\n };\n if (!settings.mode) args.push(\"--dangerously-skip-permissions\");\n args.push(\"--input-format\", \"stream-json\", \"--output-format\", \"stream-json\");\n return {\n executable: \"agy\",\n arguments: args,\n stdin: `${JSON.stringify({ event: \"user\", message: { content: input.text ?? \"\" } })}\\n`,\n };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { AgentAuthentication } from "../../domain/agent.types.ts";
2
2
  import type { Variables } from "../../domain/command.types.ts";
3
- export interface GeminiSettings {
3
+ export interface AntigravitySettings {
4
4
  readonly authentication?: AgentAuthentication;
5
5
  readonly variables?: Variables;
6
- readonly approvalMode?: "default" | "auto_edit" | "yolo" | "plan";
6
+ readonly mode?: "accept-edits" | "plan";
7
7
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=antigravity.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"antigravity.types.js","sourceRoot":"","sources":["../../../src/adapters/agents/antigravity.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AgentAuthentication } from \"../../domain/agent.types.ts\";\nimport type { Variables } from \"../../domain/command.types.ts\";\n\nexport interface AntigravitySettings {\n readonly authentication?: AgentAuthentication;\n readonly variables?: Variables;\n readonly mode?: \"accept-edits\" | \"plan\";\n}\n"]}
@@ -1,13 +1,23 @@
1
- export declare const authenticationRecipes: {
1
+ export declare const credentialRecipes: Readonly<{
2
+ tool: "const {spawnSync}=require(\"node:child_process\"); const {existsSync}=require(\"node:fs\"); const {join}=require(\"node:path\"); const {homedir}=require(\"node:os\"); const [binary,...args]=process.argv.slice(1); const installed=join(homedir(),\".outpost-tools\",\"bin\",binary); const result=spawnSync(existsSync(installed)?installed:binary,args,{stdio:\"inherit\",shell:process.platform===\"win32\"}); process.exit(result.status ?? 1);";
3
+ antigravitySettings: "{\"modelProvider\":\"gemini\"}\n";
4
+ }>;
5
+ export declare const credentialVariables: Readonly<{
6
+ readonly claude: {
7
+ readonly account: "CLAUDE_CODE_OAUTH_TOKEN";
8
+ readonly usage: "ANTHROPIC_API_KEY";
9
+ };
2
10
  readonly codex: {
3
- readonly environment: "OPENAI_API_KEY=\n";
4
- readonly login: "const {spawnSync}=require(\"node:child_process\"); const {existsSync}=require(\"node:fs\"); const {join}=require(\"node:path\"); const {homedir}=require(\"node:os\"); const installed=join(homedir(),\".outpost-tools\",\"bin\",\"codex\"); const result=spawnSync(existsSync(installed)?installed:\"codex\",[\"login\",\"--with-api-key\"],{stdio:\"inherit\",shell:process.platform===\"win32\"}); process.exit(result.status ?? 1);";
5
- readonly seed: "const {mkdirSync,writeFileSync,readFileSync,chmodSync}=require(\"node:fs\"); const {join}=require(\"node:path\"); const {homedir}=require(\"node:os\"); const directory=join(homedir(),\".codex\"); mkdirSync(directory,{recursive:true,mode:0o700}); const target=join(directory,\"auth.json\"); writeFileSync(target,readFileSync(0),{mode:0o600}); chmodSync(target,0o600);";
11
+ readonly usage: "OPENAI_API_KEY";
6
12
  };
7
- readonly claude: {
8
- readonly environment: "ANTHROPIC_API_KEY=\n";
13
+ readonly antigravity: {
14
+ readonly usage: "GEMINI_API_KEY";
15
+ };
16
+ readonly copilot: {
17
+ readonly account: "COPILOT_GITHUB_TOKEN";
9
18
  };
10
- readonly gemini: {
11
- readonly environment: "GEMINI_API_KEY=\n";
19
+ readonly kimi: {
20
+ readonly usage: "KIMI_API_KEY";
12
21
  };
13
- };
22
+ }>;
23
+ export declare const KIMI_LOGIN_DEADLINE_MS = 120000;
@@ -1,10 +1,13 @@
1
- export const authenticationRecipes = {
2
- codex: {
3
- environment: "OPENAI_API_KEY=\n",
4
- login: 'const {spawnSync}=require("node:child_process"); const {existsSync}=require("node:fs"); const {join}=require("node:path"); const {homedir}=require("node:os"); const installed=join(homedir(),".outpost-tools","bin","codex"); const result=spawnSync(existsSync(installed)?installed:"codex",["login","--with-api-key"],{stdio:"inherit",shell:process.platform==="win32"}); process.exit(result.status ?? 1);',
5
- seed: 'const {mkdirSync,writeFileSync,readFileSync,chmodSync}=require("node:fs"); const {join}=require("node:path"); const {homedir}=require("node:os"); const directory=join(homedir(),".codex"); mkdirSync(directory,{recursive:true,mode:0o700}); const target=join(directory,"auth.json"); writeFileSync(target,readFileSync(0),{mode:0o600}); chmodSync(target,0o600);',
6
- },
7
- claude: { environment: "ANTHROPIC_API_KEY=\n" },
8
- gemini: { environment: "GEMINI_API_KEY=\n" },
9
- };
1
+ export const credentialRecipes = Object.freeze({
2
+ tool: 'const {spawnSync}=require("node:child_process"); const {existsSync}=require("node:fs"); const {join}=require("node:path"); const {homedir}=require("node:os"); const [binary,...args]=process.argv.slice(1); const installed=join(homedir(),".outpost-tools","bin",binary); const result=spawnSync(existsSync(installed)?installed:binary,args,{stdio:"inherit",shell:process.platform==="win32"}); process.exit(result.status ?? 1);',
3
+ antigravitySettings: '{"modelProvider":"gemini"}\n',
4
+ });
5
+ export const credentialVariables = Object.freeze({
6
+ claude: { account: "CLAUDE_CODE_OAUTH_TOKEN", usage: "ANTHROPIC_API_KEY" },
7
+ codex: { usage: "OPENAI_API_KEY" },
8
+ antigravity: { usage: "GEMINI_API_KEY" },
9
+ copilot: { account: "COPILOT_GITHUB_TOKEN" },
10
+ kimi: { usage: "KIMI_API_KEY" },
11
+ });
12
+ export const KIMI_LOGIN_DEADLINE_MS = 120_000;
10
13
  //# sourceMappingURL=authentication.constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"authentication.constants.js","sourceRoot":"","sources":["../../../src/adapters/agents/authentication.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,KAAK,EAAE;QACL,WAAW,EAAE,mBAAmB;QAChC,KAAK,EACH,iZAAiZ;QACnZ,IAAI,EAAE,sWAAsW;KAC7W;IACD,MAAM,EAAE,EAAE,WAAW,EAAE,sBAAsB,EAAE;IAC/C,MAAM,EAAE,EAAE,WAAW,EAAE,mBAAmB,EAAE;CACpC,CAAC","sourcesContent":["export const authenticationRecipes = {\n codex: {\n environment: \"OPENAI_API_KEY=\\n\",\n login:\n 'const {spawnSync}=require(\"node:child_process\"); const {existsSync}=require(\"node:fs\"); const {join}=require(\"node:path\"); const {homedir}=require(\"node:os\"); const installed=join(homedir(),\".outpost-tools\",\"bin\",\"codex\"); const result=spawnSync(existsSync(installed)?installed:\"codex\",[\"login\",\"--with-api-key\"],{stdio:\"inherit\",shell:process.platform===\"win32\"}); process.exit(result.status ?? 1);',\n seed: 'const {mkdirSync,writeFileSync,readFileSync,chmodSync}=require(\"node:fs\"); const {join}=require(\"node:path\"); const {homedir}=require(\"node:os\"); const directory=join(homedir(),\".codex\"); mkdirSync(directory,{recursive:true,mode:0o700}); const target=join(directory,\"auth.json\"); writeFileSync(target,readFileSync(0),{mode:0o600}); chmodSync(target,0o600);',\n },\n claude: { environment: \"ANTHROPIC_API_KEY=\\n\" },\n gemini: { environment: \"GEMINI_API_KEY=\\n\" },\n} as const;\n"]}
1
+ {"version":3,"file":"authentication.constants.js","sourceRoot":"","sources":["../../../src/adapters/agents/authentication.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7C,IAAI,EAAE,uaAAua;IAC7a,mBAAmB,EAAE,8BAA8B;CACpD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/C,MAAM,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,mBAAmB,EAAE;IAC1E,KAAK,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE;IAClC,WAAW,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE;IACxC,OAAO,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE;IAC5C,IAAI,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE;CACvB,CAAC,CAAC;AAEZ,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC","sourcesContent":["export const credentialRecipes = Object.freeze({\n tool: 'const {spawnSync}=require(\"node:child_process\"); const {existsSync}=require(\"node:fs\"); const {join}=require(\"node:path\"); const {homedir}=require(\"node:os\"); const [binary,...args]=process.argv.slice(1); const installed=join(homedir(),\".outpost-tools\",\"bin\",binary); const result=spawnSync(existsSync(installed)?installed:binary,args,{stdio:\"inherit\",shell:process.platform===\"win32\"}); process.exit(result.status ?? 1);',\n antigravitySettings: '{\"modelProvider\":\"gemini\"}\\n',\n});\n\nexport const credentialVariables = Object.freeze({\n claude: { account: \"CLAUDE_CODE_OAUTH_TOKEN\", usage: \"ANTHROPIC_API_KEY\" },\n codex: { usage: \"OPENAI_API_KEY\" },\n antigravity: { usage: \"GEMINI_API_KEY\" },\n copilot: { account: \"COPILOT_GITHUB_TOKEN\" },\n kimi: { usage: \"KIMI_API_KEY\" },\n} as const);\n\nexport const KIMI_LOGIN_DEADLINE_MS = 120_000;\n"]}
@@ -1,2 +1,11 @@
1
- import type { AgentAdapter, AgentAuthentication } from "../../domain/agent.types.ts";
2
- export declare function authenticationCommand(name: "codex" | "claude" | "gemini", authentication: AgentAuthentication | undefined, externalModel?: boolean): NonNullable<AgentAdapter["authenticate"]>;
1
+ import type { AgentAdapter, AgentAuthentication, CredentialPlan } from "../../domain/agent.types.ts";
2
+ import type { Command, Variables } from "../../domain/command.types.ts";
3
+ import type { AgentModel } from "../../domain/model.types.ts";
4
+ import type { CredentialRecipe, CredentialStrategy, HostFileOptions, VariableCredentialOptions } from "./authentication.types.ts";
5
+ export declare function credentialPlan(plan?: Partial<CredentialPlan>): CredentialPlan;
6
+ export declare function toolCommand(binary: string, args: readonly string[], options?: Pick<Command, "stdin" | "deadlineMs">): Command;
7
+ export declare function requiredVariable(variables: Variables, name: string): string;
8
+ export declare function variableCredential(options: VariableCredentialOptions): Readonly<Record<"preset" | "key" | "variable", CredentialRecipe>>;
9
+ export declare function hostFile(options: HostFileOptions): Readonly<Record<"preset" | "file", CredentialRecipe>>;
10
+ export declare function excluding(recipe: CredentialRecipe, variable: string, message: string): CredentialRecipe;
11
+ export declare function credentialPlanner(agent: string, strategy: CredentialStrategy, authentication: AgentAuthentication | undefined, model?: AgentModel): AgentAdapter["credentials"];
@@ -1,52 +1,75 @@
1
+ import { authenticationForm } from "../../domain/authentication.js";
1
2
  import { invariant } from "../../domain/errors.js";
2
- import { authenticationRecipes } from "./authentication.constants.js";
3
- export function authenticationCommand(name, authentication, externalModel = false) {
4
- if (!authentication)
5
- return () => undefined;
6
- const mode = authentication.mode;
7
- invariant(mode === "api-key" ||
8
- (mode === "oauth-token" && name === "claude") ||
9
- (mode === "login" && name === "codex" && !externalModel), "Unsupported harness authentication mode");
10
- if (mode === "login") {
11
- const credentials = authentication.credentials;
12
- if (credentials === undefined)
13
- return () => undefined;
14
- try {
15
- JSON.parse(credentials);
16
- }
17
- catch {
18
- throw new Error("Invalid Codex credential JSON");
19
- }
20
- return () => ({
21
- executable: "node",
22
- arguments: ["-e", authenticationRecipes.codex.seed],
23
- stdin: credentials,
24
- });
25
- }
26
- const environment = mode === "oauth-token"
27
- ? "CLAUDE_CODE_OAUTH_TOKEN"
28
- : (authentication.environment ??
29
- authenticationRecipes[name].environment.trim().replace("=", ""));
30
- invariant(/^[A-Za-z_][A-Za-z0-9_]*$/.test(environment), "Invalid authentication environment variable");
31
- invariant(name === "codex" ||
32
- mode === "oauth-token" ||
33
- environment ===
34
- authenticationRecipes[name].environment.trim().replace("=", ""), "This CLI requires its standard authentication environment variable");
35
- return (variables) => {
36
- invariant(variables[environment], `Missing ${environment}. Declare the selected credential explicitly.`);
37
- if (name === "claude") {
38
- const conflict = mode === "oauth-token"
39
- ? "ANTHROPIC_API_KEY"
40
- : "CLAUDE_CODE_OAUTH_TOKEN";
41
- invariant(!variables[conflict], "Conflicting Claude authentication methods");
42
- }
43
- if (name !== "codex" || externalModel)
44
- return undefined;
45
- return {
46
- executable: "node",
47
- arguments: ["-e", authenticationRecipes.codex.login],
48
- stdin: variables[environment],
3
+ import { credentialRecipes } from "./authentication.constants.js";
4
+ export function credentialPlan(plan = {}) {
5
+ return Object.freeze({
6
+ variables: Object.freeze({ ...plan.variables }),
7
+ host: Object.freeze([...(plan.host ?? [])]),
8
+ files: Object.freeze([...(plan.files ?? [])]),
9
+ commands: Object.freeze([...(plan.commands ?? [])]),
10
+ });
11
+ }
12
+ export function toolCommand(binary, args, options = {}) {
13
+ return {
14
+ executable: "node",
15
+ arguments: ["-e", credentialRecipes.tool, binary, ...args],
16
+ ...options,
17
+ };
18
+ }
19
+ export function requiredVariable(variables, name) {
20
+ const value = variables[name];
21
+ invariant(value, `Missing ${name}. Declare the selected credential explicitly.`);
22
+ return value;
23
+ }
24
+ export function variableCredential(options) {
25
+ const recipe = (read) => (input) => {
26
+ options.bind?.(input);
27
+ return (variables) => {
28
+ const secret = read(input.value, variables);
29
+ options.accept?.(secret);
30
+ const exposed = options.expose?.(secret, input) ?? {};
31
+ return credentialPlan({
32
+ ...exposed,
33
+ variables: { [options.variable]: secret, ...exposed.variables },
34
+ });
49
35
  };
50
36
  };
37
+ return {
38
+ preset: recipe((_, variables) => requiredVariable(variables, options.variable)),
39
+ key: (input) => {
40
+ options.accept?.(input.value);
41
+ return recipe((value) => value)(input);
42
+ },
43
+ variable: recipe((value, variables) => requiredVariable(variables, value)),
44
+ };
45
+ }
46
+ export function hostFile(options) {
47
+ const { files, source, ...credential } = options;
48
+ const recipe = (path) => () => credentialPlan({
49
+ host: [{ ...credential, source: path }],
50
+ ...(files ? { files } : {}),
51
+ });
52
+ return {
53
+ preset: () => recipe(source),
54
+ file: (input) => recipe({ path: input.value }),
55
+ };
56
+ }
57
+ export function excluding(recipe, variable, message) {
58
+ return (input) => {
59
+ const planFor = recipe(input);
60
+ return (variables) => {
61
+ invariant(!variables[variable], message);
62
+ return planFor(variables);
63
+ };
64
+ };
65
+ }
66
+ export function credentialPlanner(agent, strategy, authentication, model) {
67
+ if (authentication === undefined)
68
+ return undefined;
69
+ const { form, value = "" } = authenticationForm(authentication);
70
+ const recipe = Object.hasOwn(strategy, form) ? strategy[form] : undefined;
71
+ const accepted = Object.keys(strategy);
72
+ invariant(recipe, `${agent} does not support ${form} authentication. Accepted forms: ${accepted.length ? accepted.join(", ") : "none"}`);
73
+ return recipe(model === undefined ? { value } : { value, model });
51
74
  }
52
75
  //# sourceMappingURL=authentication.js.map