aicodeman 1.44.0 → 1.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -8
- package/dist/agent-codex-identity.d.ts +26 -0
- package/dist/agent-codex-identity.d.ts.map +1 -0
- package/dist/agent-codex-identity.js +253 -0
- package/dist/agent-codex-identity.js.map +1 -0
- package/dist/agent-inspection.d.ts +32 -0
- package/dist/agent-inspection.d.ts.map +1 -0
- package/dist/agent-inspection.js +196 -0
- package/dist/agent-inspection.js.map +1 -0
- package/dist/agent-staging.d.ts +130 -0
- package/dist/agent-staging.d.ts.map +1 -0
- package/dist/agent-staging.js +312 -0
- package/dist/agent-staging.js.map +1 -0
- package/dist/case-rename.d.ts +65 -0
- package/dist/case-rename.d.ts.map +1 -0
- package/dist/case-rename.js +198 -0
- package/dist/case-rename.js.map +1 -0
- package/dist/cli-agent.d.ts +91 -3
- package/dist/cli-agent.d.ts.map +1 -1
- package/dist/cli-agent.js +501 -44
- package/dist/cli-agent.js.map +1 -1
- package/dist/cli-history.d.ts +20 -0
- package/dist/cli-history.d.ts.map +1 -0
- package/dist/cli-history.js +61 -0
- package/dist/cli-history.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -1
- package/dist/cli.js.map +1 -1
- package/dist/codex-rollout-format.d.ts +66 -0
- package/dist/codex-rollout-format.d.ts.map +1 -0
- package/dist/codex-rollout-format.js +111 -0
- package/dist/codex-rollout-format.js.map +1 -0
- package/dist/codex-transcript.d.ts +3 -0
- package/dist/codex-transcript.d.ts.map +1 -1
- package/dist/codex-transcript.js +13 -41
- package/dist/codex-transcript.js.map +1 -1
- package/dist/config/auth-config.d.ts +16 -1
- package/dist/config/auth-config.d.ts.map +1 -1
- package/dist/config/auth-config.js +16 -1
- package/dist/config/auth-config.js.map +1 -1
- package/dist/config/cli-registry/schema.d.ts +12 -7
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +26 -0
- package/dist/config/cli-registry/schema.js.map +1 -1
- package/dist/config/cli-registry/stock.d.ts.map +1 -1
- package/dist/config/cli-registry/stock.js +40 -1
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +57 -0
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/config/server-timing.d.ts +6 -0
- package/dist/config/server-timing.d.ts.map +1 -1
- package/dist/config/server-timing.js +9 -0
- package/dist/config/server-timing.js.map +1 -1
- package/dist/daemon-control.d.ts +1 -0
- package/dist/daemon-control.d.ts.map +1 -1
- package/dist/daemon-control.js +2 -0
- package/dist/daemon-control.js.map +1 -1
- package/dist/deepseek-transcript.d.ts +9 -7
- package/dist/deepseek-transcript.d.ts.map +1 -1
- package/dist/deepseek-transcript.js +9 -7
- package/dist/deepseek-transcript.js.map +1 -1
- package/dist/docker-hosts.d.ts +8 -0
- package/dist/docker-hosts.d.ts.map +1 -1
- package/dist/docker-hosts.js +29 -0
- package/dist/docker-hosts.js.map +1 -1
- package/dist/git-fetch-scheduler.d.ts +124 -0
- package/dist/git-fetch-scheduler.d.ts.map +1 -0
- package/dist/git-fetch-scheduler.js +249 -0
- package/dist/git-fetch-scheduler.js.map +1 -0
- package/dist/git-fetch.d.ts +241 -0
- package/dist/git-fetch.d.ts.map +1 -0
- package/dist/git-fetch.js +392 -0
- package/dist/git-fetch.js.map +1 -0
- package/dist/git-workspace-status.d.ts +36 -1
- package/dist/git-workspace-status.d.ts.map +1 -1
- package/dist/git-workspace-status.js +42 -5
- package/dist/git-workspace-status.js.map +1 -1
- package/dist/hooks-config.d.ts +14 -2
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +39 -3
- package/dist/hooks-config.js.map +1 -1
- package/dist/host-sensors.d.ts +115 -0
- package/dist/host-sensors.d.ts.map +1 -0
- package/dist/host-sensors.js +457 -0
- package/dist/host-sensors.js.map +1 -0
- package/dist/local-history.d.ts +71 -0
- package/dist/local-history.d.ts.map +1 -0
- package/dist/local-history.js +750 -0
- package/dist/local-history.js.map +1 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +2 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/mux-interface.d.ts +5 -2
- package/dist/mux-interface.d.ts.map +1 -1
- package/dist/prompt-cache-keepwarm.d.ts.map +1 -1
- package/dist/prompt-cache-keepwarm.js +5 -3
- package/dist/prompt-cache-keepwarm.js.map +1 -1
- package/dist/remote-hosts.d.ts +7 -0
- package/dist/remote-hosts.d.ts.map +1 -1
- package/dist/remote-hosts.js +17 -3
- package/dist/remote-hosts.js.map +1 -1
- package/dist/remote-pane-history.d.ts.map +1 -1
- package/dist/remote-pane-history.js +2 -2
- package/dist/remote-pane-history.js.map +1 -1
- package/dist/session.d.ts +113 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +354 -13
- package/dist/session.js.map +1 -1
- package/dist/terminal-input-classifier.d.ts +8 -0
- package/dist/terminal-input-classifier.d.ts.map +1 -0
- package/dist/terminal-input-classifier.js +60 -0
- package/dist/terminal-input-classifier.js.map +1 -0
- package/dist/tmux-manager.d.ts +30 -4
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +101 -21
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-prefix-table.d.ts +37 -5
- package/dist/tmux-prefix-table.d.ts.map +1 -1
- package/dist/tmux-prefix-table.js +40 -5
- package/dist/tmux-prefix-table.js.map +1 -1
- package/dist/tui/tui-app.d.ts +8 -1
- package/dist/tui/tui-app.d.ts.map +1 -1
- package/dist/tui/tui-app.js +49 -12
- package/dist/tui/tui-app.js.map +1 -1
- package/dist/tui/tui-client.d.ts +90 -3
- package/dist/tui/tui-client.d.ts.map +1 -1
- package/dist/tui/tui-client.js +195 -26
- package/dist/tui/tui-client.js.map +1 -1
- package/dist/types/session.d.ts +15 -0
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/web/agent-inbox-persistence.d.ts +52 -0
- package/dist/web/agent-inbox-persistence.d.ts.map +1 -0
- package/dist/web/agent-inbox-persistence.js +139 -0
- package/dist/web/agent-inbox-persistence.js.map +1 -0
- package/dist/web/agent-inbox.d.ts +140 -0
- package/dist/web/agent-inbox.d.ts.map +1 -0
- package/dist/web/agent-inbox.js +258 -0
- package/dist/web/agent-inbox.js.map +1 -0
- package/dist/web/middleware/auth.d.ts +2 -0
- package/dist/web/middleware/auth.d.ts.map +1 -1
- package/dist/web/middleware/auth.js +145 -52
- package/dist/web/middleware/auth.js.map +1 -1
- package/dist/web/network-auth-policy.d.ts +13 -3
- package/dist/web/network-auth-policy.d.ts.map +1 -1
- package/dist/web/network-auth-policy.js +15 -3
- package/dist/web/network-auth-policy.js.map +1 -1
- package/dist/web/ports/infra-port.d.ts +2 -0
- package/dist/web/ports/infra-port.d.ts.map +1 -1
- package/dist/web/public/admin-ui.js.gz +0 -0
- package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
- package/dist/web/public/app.3093527f.js +43 -0
- package/dist/web/public/app.3093527f.js.br +0 -0
- package/dist/web/public/app.3093527f.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.4866ecc3.js → constants.affcdde6.js} +622 -12
- package/dist/web/public/constants.affcdde6.js.br +0 -0
- package/dist/web/public/constants.affcdde6.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/git-status-ui.js +88 -5
- package/dist/web/public/git-status-ui.js.br +0 -0
- package/dist/web/public/git-status-ui.js.gz +0 -0
- package/dist/web/public/header-divider.eb2d2463.js +1 -0
- package/dist/web/public/header-divider.eb2d2463.js.br +0 -0
- package/dist/web/public/header-divider.eb2d2463.js.gz +0 -0
- package/dist/web/public/home-sessions.js.gz +0 -0
- package/dist/web/public/host-wake-ui.js.gz +0 -0
- package/dist/web/public/i18n.70265257.js +2 -0
- package/dist/web/public/i18n.70265257.js.br +0 -0
- package/dist/web/public/i18n.70265257.js.gz +0 -0
- package/dist/web/public/image-input.941386e7.js.gz +0 -0
- package/dist/web/public/index.html +170 -16
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.8bc46081.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.4e8b20ac.js.gz +0 -0
- package/dist/web/public/{mobile-handlers.44adaa07.js → mobile-handlers.f7c3f692.js} +26 -2
- package/dist/web/public/mobile-handlers.f7c3f692.js.br +0 -0
- package/dist/web/public/mobile-handlers.f7c3f692.js.gz +0 -0
- package/dist/web/public/mobile-ime-preview.2dbaf262.js.gz +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/mobile.1bbd2d67.css +1 -0
- package/dist/web/public/mobile.1bbd2d67.css.br +0 -0
- package/dist/web/public/mobile.1bbd2d67.css.gz +0 -0
- package/dist/web/public/notification-manager.feb82c04.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/{panels-ui.cbb24ba1.js → panels-ui.4a56ee63.js} +76 -70
- package/dist/web/public/panels-ui.4a56ee63.js.br +0 -0
- package/dist/web/public/panels-ui.4a56ee63.js.gz +0 -0
- package/dist/web/public/ralph-panel.b350e2ef.js.gz +0 -0
- package/dist/web/public/ralph-wizard.b6c0dd19.js.gz +0 -0
- package/dist/web/public/readmymind-ui.js.gz +0 -0
- package/dist/web/public/reboot-restore-ui.js.gz +0 -0
- package/dist/web/public/respawn-ui.d7adcf6a.js.gz +0 -0
- package/dist/web/public/sanitize-html.e7147e76.js.gz +0 -0
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/session-ui.186f9419.js +106 -0
- package/dist/web/public/session-ui.186f9419.js.br +0 -0
- package/dist/web/public/session-ui.186f9419.js.gz +0 -0
- package/dist/web/public/settings-ui.a191154e.js +106 -0
- package/dist/web/public/settings-ui.a191154e.js.br +0 -0
- package/dist/web/public/settings-ui.a191154e.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview-worker.js.gz +0 -0
- package/dist/web/public/spreadsheet-preview.75c751de.js.gz +0 -0
- package/dist/web/public/spreadsheet-xlsx-core.js.gz +0 -0
- package/dist/web/public/styles.7238eae8.css +1 -0
- package/dist/web/public/styles.7238eae8.css.br +0 -0
- package/dist/web/public/styles.7238eae8.css.gz +0 -0
- package/dist/web/public/subagent-windows.07277a58.js.gz +0 -0
- package/dist/web/public/sw.js +2 -2
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/tab-layout-browser.2d6189f7.js.gz +0 -0
- package/dist/web/public/{tab-rail-resize.7157e0bd.js → tab-rail-resize.b5cdceaf.js} +1 -1
- package/dist/web/public/tab-rail-resize.b5cdceaf.js.br +0 -0
- package/dist/web/public/tab-rail-resize.b5cdceaf.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.af09f99a.js.gz +0 -0
- package/dist/web/public/terminal-split.js.gz +0 -0
- package/dist/web/public/terminal-tile.js +10 -1
- package/dist/web/public/terminal-tile.js.br +0 -0
- package/dist/web/public/terminal-tile.js.gz +0 -0
- package/dist/web/public/terminal-ui.7e787829.js +4 -0
- package/dist/web/public/terminal-ui.7e787829.js.br +0 -0
- package/dist/web/public/terminal-ui.7e787829.js.gz +0 -0
- package/dist/web/public/tile-grid.js.gz +0 -0
- package/dist/web/public/ultracode-panel.js.gz +0 -0
- package/dist/web/public/ultracode-windows.js.gz +0 -0
- package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
- package/dist/web/public/vendor/exceljs.min.js.gz +0 -0
- package/dist/web/public/vendor/fflate.min.js.gz +0 -0
- package/dist/web/public/vendor/marked.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/{xterm-predictive-echo.ae5e3d5d.js → xterm-predictive-echo.276b11d9.js} +1 -1
- package/dist/web/public/vendor/xterm-predictive-echo.276b11d9.js.br +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.276b11d9.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.1be42307.js +5 -0
- package/dist/web/public/vendor/xterm-zerolag-input.1be42307.js.br +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.1be42307.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/voice-input.2342c37b.js.gz +0 -0
- package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
- package/dist/web/public/webview-tabs.js.gz +0 -0
- package/dist/web/public/whats-new.json +9 -9
- package/dist/web/route-helpers.d.ts +57 -6
- package/dist/web/route-helpers.d.ts.map +1 -1
- package/dist/web/route-helpers.js +72 -4
- package/dist/web/route-helpers.js.map +1 -1
- package/dist/web/routes/agent-session-routes.d.ts +20 -0
- package/dist/web/routes/agent-session-routes.d.ts.map +1 -0
- package/dist/web/routes/agent-session-routes.js +160 -0
- package/dist/web/routes/agent-session-routes.js.map +1 -0
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +203 -16
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/config-backup-routes.js +2 -2
- package/dist/web/routes/config-backup-routes.js.map +1 -1
- package/dist/web/routes/git-status-routes.d.ts +21 -7
- package/dist/web/routes/git-status-routes.d.ts.map +1 -1
- package/dist/web/routes/git-status-routes.js +78 -12
- package/dist/web/routes/git-status-routes.js.map +1 -1
- package/dist/web/routes/inbox-routes.d.ts +43 -0
- package/dist/web/routes/inbox-routes.d.ts.map +1 -0
- package/dist/web/routes/inbox-routes.js +148 -0
- package/dist/web/routes/inbox-routes.js.map +1 -0
- package/dist/web/routes/index.d.ts +2 -0
- package/dist/web/routes/index.d.ts.map +1 -1
- package/dist/web/routes/index.js +2 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/ralph-routes.d.ts.map +1 -1
- package/dist/web/routes/ralph-routes.js +7 -16
- package/dist/web/routes/ralph-routes.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +120 -74
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/routes/system-routes.d.ts.map +1 -1
- package/dist/web/routes/system-routes.js +107 -59
- package/dist/web/routes/system-routes.js.map +1 -1
- package/dist/web/routes/ws-routes.d.ts +5 -0
- package/dist/web/routes/ws-routes.d.ts.map +1 -1
- package/dist/web/routes/ws-routes.js +84 -47
- package/dist/web/routes/ws-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +56 -7
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +88 -1
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/sensitive-path.d.ts.map +1 -1
- package/dist/web/sensitive-path.js +2 -0
- package/dist/web/sensitive-path.js.map +1 -1
- package/dist/web/server.d.ts +7 -2
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +144 -16
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-wait-registry.d.ts +48 -4
- package/dist/web/session-wait-registry.d.ts.map +1 -1
- package/dist/web/session-wait-registry.js +144 -6
- package/dist/web/session-wait-registry.js.map +1 -1
- package/dist/web/settings-writer.d.ts +47 -0
- package/dist/web/settings-writer.d.ts.map +1 -0
- package/dist/web/settings-writer.js +110 -0
- package/dist/web/settings-writer.js.map +1 -0
- package/dist/web/sse-events.d.ts +4 -1
- package/dist/web/sse-events.d.ts.map +1 -1
- package/dist/web/sse-events.js +4 -1
- package/dist/web/sse-events.js.map +1 -1
- package/package.json +1 -1
- package/skills/codeman/SKILL.md +30 -8
- package/skills/codeman/preamble.sh +3 -3
- package/skills/codeman/reference/endpoints.md +24 -3
- package/skills/codeman/reference/history.md +84 -0
- package/skills/codeman/reference/inspection-and-staging.md +152 -0
- package/skills/codeman/reference/messaging.md +1 -1
- package/skills/codeman/reference/verbs.md +65 -3
- package/dist/web/public/app.9314ee60.js +0 -43
- package/dist/web/public/app.9314ee60.js.br +0 -0
- package/dist/web/public/app.9314ee60.js.gz +0 -0
- package/dist/web/public/constants.4866ecc3.js.br +0 -0
- package/dist/web/public/constants.4866ecc3.js.gz +0 -0
- package/dist/web/public/i18n.22ca902b.js +0 -2
- package/dist/web/public/i18n.22ca902b.js.br +0 -0
- package/dist/web/public/i18n.22ca902b.js.gz +0 -0
- package/dist/web/public/mobile-handlers.44adaa07.js.br +0 -0
- package/dist/web/public/mobile-handlers.44adaa07.js.gz +0 -0
- package/dist/web/public/mobile.12fb18de.css +0 -1
- package/dist/web/public/mobile.12fb18de.css.br +0 -0
- package/dist/web/public/mobile.12fb18de.css.gz +0 -0
- package/dist/web/public/panels-ui.cbb24ba1.js.br +0 -0
- package/dist/web/public/panels-ui.cbb24ba1.js.gz +0 -0
- package/dist/web/public/session-ui.9c1f009b.js +0 -104
- package/dist/web/public/session-ui.9c1f009b.js.br +0 -0
- package/dist/web/public/session-ui.9c1f009b.js.gz +0 -0
- package/dist/web/public/settings-ui.fea9ddae.js +0 -106
- package/dist/web/public/settings-ui.fea9ddae.js.br +0 -0
- package/dist/web/public/settings-ui.fea9ddae.js.gz +0 -0
- package/dist/web/public/styles.e096fcd6.css +0 -1
- package/dist/web/public/styles.e096fcd6.css.br +0 -0
- package/dist/web/public/styles.e096fcd6.css.gz +0 -0
- package/dist/web/public/tab-rail-resize.7157e0bd.js.br +0 -0
- package/dist/web/public/tab-rail-resize.7157e0bd.js.gz +0 -0
- package/dist/web/public/terminal-ui.68dbd352.js +0 -2
- package/dist/web/public/terminal-ui.68dbd352.js.br +0 -0
- package/dist/web/public/terminal-ui.68dbd352.js.gz +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.ae5e3d5d.js.br +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.ae5e3d5d.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.0b69623c.js +0 -4
- package/dist/web/public/vendor/xterm-zerolag-input.0b69623c.js.br +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.0b69623c.js.gz +0 -0
package/README.md
CHANGED
|
@@ -460,7 +460,7 @@ PTY Output → 16ms Server Batch → DEC 2026 Wrap → SSE → Client rAF → xt
|
|
|
460
460
|
- **Background daemon & service install** — `codeman web -d` runs the server detached with a pidfile, `~/.codeman/web.log`, and verified startup (it polls the server until it answers, so a port clash never reads as success); `codeman service install` writes a systemd user unit (Linux) or LaunchAgent (macOS) with your shell's PATH baked in, so an nvm or Homebrew `node`, `tmux` and `claude` are actually found. Secrets are never written into unit files
|
|
461
461
|
- **Diagnostics in Settings** — **App Settings → System → Diagnostics → Run checks** runs `codeman doctor` on the server and lists Node, tmux, every agent CLI and the optional office tools with versions, paths and install hints. Besides the `PATH`, it also looks in each CLI's usual install directories (`~/.local/bin`, `~/.npm-global/bin` and the like), so most installs are found under a service with a minimal `PATH`. Admin only in multi-user mode.
|
|
462
462
|
- **Self-update** — git-clone installs under systemd/launchd update in place from **App Settings → System → Updates**: it detects the latest release, auto-stashes a dirty tree, and streams build progress across the service restart (npm installs report as non-updatable)
|
|
463
|
-
- **Git status in the bottom bar** — off by default (**App Settings → Header & Panels → Bottom bar → Git status**, per device). A small indicator at the right of the bottom bar shows the active session's repository at a glance: `● 3` uncommitted files, `↑ 2` commits not pushed, `⚠` merge conflicts, `✓` all committed and pushed. Click it for a draggable window listing the staged, not-staged, untracked and conflicted files (grouped under collapsed folders, or as a flat list if you turn that setting off) and the unpushed commits; **click a file to see its diff** (new files as all additions, deleted files as all removals), with **Open file** to jump to the viewer. A folder that holds several projects gets one collapsible section per repository found up to two levels down, all collapsed until you open them.
|
|
463
|
+
- **Git status in the bottom bar** — off by default (**App Settings → Header & Panels → Bottom bar → Git status**, per device). A small indicator at the right of the bottom bar shows the active session's repository at a glance: `● 3` uncommitted files, `↑ 2` commits not pushed, `⚠` merge conflicts, `✓` all committed and pushed. Click it for a draggable window listing the staged, not-staged, untracked and conflicted files (grouped under collapsed folders, or as a flat list if you turn that setting off) and the unpushed commits; **click a file to see its diff** (new files as all additions, deleted files as all removals), with **Open file** to jump to the viewer. A folder that holds several projects gets one collapsible section per repository found up to two levels down, all collapsed until you open them. **Fetch** in that window's header runs `git fetch` for the repositories it lists, on your click or on an interval you turn on (**App Settings → Bottom bar**, off by default; **Session Options → Git** overrides both the switch and the interval per session). Sessions open on the same folder share one run and each sees its result. Apart from that fetch Codeman never fetches or changes the repo, so "behind" is as of the last fetch; not shown for Docker or remote sessions.
|
|
464
464
|
- **Clone a GitHub repo as a case** — paste a repository URL into **Add Case → Clone Repo** and Codeman clones it into `~/codeman-cases/<name>` and registers it as a normal case, ready to run an agent in. It preflights the URL while you type (tells you whether it can be cloned anonymously and offers the repo's real branches and tags for the optional branch/tag field), fills the case name in from the URL, and lets you pick which CLI the Run button should use. Public repositories over `https://`; Codeman never collects or stores credentials
|
|
465
465
|
- **Create a case in a custom folder** — tick **Create in a custom folder** in **Add Case → Create New**, pick a parent folder (Browse included) and a name, and Codeman scaffolds the new case there instead of `~/codeman-cases`. The target must be a new or empty folder; system directories, your home folder itself, credential trees such as `~/.ssh`, and Codeman's own data folder are refused. Admin only in multi-user mode.
|
|
466
466
|
- **Multi-CLI** — run **Claude Code**, **OpenCode**, **Codex**, **Antigravity**, **Gemini**, **Pi**, **Grok**, **DeepSeek Harness**, **OMP**, or **GitHub Copilot CLI** per session; env-var prefixes auto-gate (`CLAUDE_CODE_*` vs `OPENCODE_*` vs `CODEX_*` vs `ANTIGRAVITY_*` vs `GEMINI_*`/`GOOGLE_*` vs `PI_*` vs `GROK_*`/`XAI_*` vs `DSH_*`/`DEEPSEEK_*` vs `OMP_*` vs `COPILOT_*`). See [`docs/opencode-integration.md`](docs/opencode-integration.md), [`docs/pi-integration.md`](docs/pi-integration.md), [`docs/grok-integration.md`](docs/grok-integration.md), [`docs/deepseek-integration.md`](docs/deepseek-integration.md) [`docs/omp-integration.md`](docs/omp-integration.md) and [`docs/copilot-integration.md`](docs/copilot-integration.md)
|
|
@@ -580,10 +580,12 @@ loginctl enable-linger $USER
|
|
|
580
580
|
1. First request → browser shows Basic Auth prompt (username: `admin` or `CODEMAN_USERNAME`)
|
|
581
581
|
2. On success → server issues a `codeman_session` cookie (24h TTL, auto-extends on activity)
|
|
582
582
|
3. Subsequent requests authenticate silently via cookie
|
|
583
|
-
4. 10 failed attempts per IP → 429 rate limit (15-minute decay)
|
|
583
|
+
4. 10 failed attempts per IP → 429 rate limit (15-minute decay). In multi-user mode the per-IP cap is 50, and each account allows 10 failed guesses per IP; past either, even a correct password from that IP waits for the decay, while the account still logs in from another IP
|
|
584
584
|
|
|
585
585
|
**Always set `CODEMAN_PASSWORD`** before exposing via tunnel — without it, anyone with the URL has full access to your sessions.
|
|
586
586
|
|
|
587
|
+
The tunnel Codeman manages (App Settings → System → Remote access) refuses to start without a login (`CODEMAN_PASSWORD` or multi-user mode) unless `CODEMAN_ALLOW_UNAUTHENTICATED_TUNNEL=1` or `codeman web --allow-unauthenticated-tunnel` acknowledges the exposure, or you accept the browser's confirm, which it asks before every enable while no login is set. `CODEMAN_ALLOW_UNAUTHENTICATED_NETWORK` covers only the network bind: it does not let the tunnel start.
|
|
588
|
+
|
|
587
589
|
</details>
|
|
588
590
|
|
|
589
591
|
### QR Code Authentication
|
|
@@ -670,7 +672,7 @@ By default Codeman launches sessions with `--dangerously-skip-permissions`, so t
|
|
|
670
672
|
|
|
671
673
|
- **Loopback by default** — the server binary binds `127.0.0.1`, reachable only from the same machine, so the no-password default is safe out of the box (the guided installer asks about network access and configures the binding + password for you). Binding a non-loopback host without `CODEMAN_PASSWORD` _starts but prints a loud warning_ with three concrete fixes (set a password, loopback + an authenticated tunnel, or explicitly acknowledge with `--allow-unauthenticated-network`)
|
|
672
674
|
- **Optional auth, real sessions** — HTTP Basic via `CODEMAN_USERNAME` (default `admin`) / `CODEMAN_PASSWORD`. Success issues an opaque 256-bit `codeman_session` cookie (`randomBytes(32)`) — validated server-side, not client-signed, so it can't be forged offline (24h TTL, auto-extend, device-context audit log)
|
|
673
|
-
- **Per-IP rate limiting** — 10 failed attempts → `429` with `Retry-After` (15-min decay). A valid cookie or correct password recovers _immediately_ even while an attacker hammers the same IP — important because all tunnel traffic shares one loopback IP. QR auth has its own separate limiter
|
|
675
|
+
- **Per-IP rate limiting** — 10 failed attempts → `429` with `Retry-After` (15-min decay). A valid cookie or correct password recovers _immediately_ even while an attacker hammers the same IP — important because all tunnel traffic shares one loopback IP. Multi-user mode allows 50 failures per IP instead, plus 10 failed guesses per account from one IP; both are checked before the password, so past either a correct password from that IP also waits for the decay, while the account still logs in from another IP. QR auth has its own separate limiter
|
|
674
676
|
- **Configurable permission mode** - `--dangerously-skip-permissions` is only the default. **App Settings → Agents & CLIs → Claude → Startup Mode** can switch new sessions to Anthropic's classifier-guarded `auto` mode (low-prompt, needs Claude Code 2.1.207+), `normal` prompting, or an explicit allowed-tools list. In multi-user mode, non-granted users are forced to `auto`, and shell sessions / skip-permissions require an explicit per-user grant
|
|
675
677
|
|
|
676
678
|
### Always-on browser hardening (v0.9.5)
|
|
@@ -825,12 +827,14 @@ Those `DONE_<task>_<random>` strings are the skill's **split marker** trick, and
|
|
|
825
827
|
| [`reference/recipes.md`](skills/codeman/reference/recipes.md) | 8 worked flows: claude, DeepSeek Harness and shell workers, fan-out, blocked-worker watch, messaging fan-out. On demand. |
|
|
826
828
|
| [`reference/endpoints.md`](skills/codeman/reference/endpoints.md) | Full endpoint tables, error codes, per-mode signal table, capacity limits. On demand. |
|
|
827
829
|
| [`reference/messaging.md`](skills/codeman/reference/messaging.md) | Talking to claude workers directly via Claude Code cross-session messaging. On demand. |
|
|
830
|
+
| [`reference/history.md`](skills/codeman/reference/history.md) | Reading saved Codex conversations offline with `codeman history read`: selectors, filters, forks, budgets. On demand. |
|
|
831
|
+
| [`reference/inspection-and-staging.md`](skills/codeman/reference/inspection-and-staging.md) | Experimental and opt-in: bounded pane inspection and guarded submission with `codeman agent inspect`, `stage` and `submit`. On demand. |
|
|
828
832
|
|
|
829
833
|
Every recipe in there was verified against a live server, and the comments record the failure modes that were measured rather than guessed.
|
|
830
834
|
|
|
831
835
|
#### Two things worth knowing
|
|
832
836
|
|
|
833
|
-
- **It self-gates.**
|
|
837
|
+
- **It self-gates.** It acts inside a Codeman-managed session. Outside one (`CODEMAN_MUX` unset) it only reads saved Codex conversations offline (`codeman history read`) and refuses everything else, and it never guesses an API URL, so a global install costs an unrelated Claude Code session nothing.
|
|
834
838
|
- **It is deliberately conservative.** Unprompted, it may only spawn sessions, prompt them, and delete ones **it created in that same conversation, by exact id**, through a fail-closed guard that refuses to delete the agent's own session. Deleting a case (which erases a real directory of your code), bulk kills, respawn/ralph/cron/orchestrator changes and settings writes all require you to ask, naming the target.
|
|
835
839
|
|
|
836
840
|
⚠️ Turning `agentSkillEnabled` back off **does not remove already-injected copies** (a create-time sweep would yank the skill out from under other live sessions sharing that workspace). Remove them per case with `codeman skill uninstall --case <name>`.
|
|
@@ -977,25 +981,44 @@ codeman tui 3 # attach to session 3 of that list
|
|
|
977
981
|
|
|
978
982
|
### `codeman agent` — session-to-session verbs in every CLI mode
|
|
979
983
|
|
|
980
|
-
The skill above drives the API with `curl` and `jq` from a preamble Codeman seeds per session. Where it does not reach (a `pi` or `shell` session, a machine without `jq`), the same environment is still there (`CODEMAN_MUX=1`, `CODEMAN_SESSION_ID`, `CODEMAN_API_URL` are exported into every pane), so `codeman agent` packages the same verbs as commands. It is a thin client over the endpoints listed under [API](#api):
|
|
984
|
+
The skill above drives the API with `curl` and `jq` from a preamble Codeman seeds per session. Where it does not reach (a `pi` or `shell` session, a machine without `jq`), the same environment is still there (`CODEMAN_MUX=1`, `CODEMAN_SESSION_ID`, `CODEMAN_API_URL` are exported into every pane), so `codeman agent` packages the same verbs as commands. It is a thin client over the endpoints listed under [API](#api): auth and ownership apply to every endpoint, including bounded inspection and guarded input. The `inspect`, `stage` and `submit` commands and their HTTP routes are **experimental** and **opt-in**: turn on **Experimental agent coordination** in App Settings (`agentCoordinationEnabled`, synced, off by default; until then the routes answer `403 FORBIDDEN` naming it). Their commands, flags, paths, payloads and behavior may change or be removed in minor or patch releases, so pin a compatible version when automating them; see [Experimental agent coordination](docs/versioning-policy.md#experimental-agent-coordination). One line in a case's `AGENTS.md` is enough: *"other sessions: `codeman agent --help`"*.
|
|
981
985
|
|
|
982
986
|
```bash
|
|
983
987
|
codeman agent ls # sessions; * marks this one
|
|
984
988
|
SID=$(codeman agent spawn scratch-1 --mode claude) # quick-start + wait for the composer where the mode has a ready mark
|
|
989
|
+
SID=$(codeman agent spawn --working-dir ~/src/app --mode codex) # no case: an existing directory (cwd by default)
|
|
985
990
|
codeman agent send "$SID" 'review src/, then say DONE' --until stop,exit --timeout 300000 # --wait = default signal set
|
|
986
991
|
codeman agent read "$SID" # last answer (as the server reads it for that mode)
|
|
987
992
|
codeman agent read "$SID" --tail 3000 # terminal tail, ANSI stripped (every mode)
|
|
993
|
+
codeman agent inspect "$SID" --max-bytes 8192 --json # recent evidence + opaque cursor (pane snapshots are labeled)
|
|
994
|
+
codeman agent stage "$SID" --message-file /tmp/prompt.txt --json # no Enter; known local Codex composer only
|
|
995
|
+
codeman agent submit "$SID" --stage-id "$STAGE_ID" --confirm-sha "$SHA256" --json # one conditional Enter
|
|
988
996
|
codeman agent send "$SID" 'run the tests, then print WORKDONE followed by _4711' # hook-less modes (opencode, pi, …): ask for the marker in halves …
|
|
989
997
|
codeman agent wait "$SID" --match WORKDONE_4711 # … and wait on the joined form, which the prompt's echo never contains
|
|
990
998
|
codeman agent interrupt "$SID" # a bare ESC, conversation intact
|
|
999
|
+
codeman agent post "$SID" 'context for later, not a prompt' # stored in its inbox, not typed into the pane
|
|
1000
|
+
codeman agent inbox --wait --timeout 300000 # your own inbox: blocks while nothing is new
|
|
1001
|
+
codeman agent ack <msg-id> # remove what you handled (read never removes)
|
|
991
1002
|
codeman agent rm "$SID" # any session except this one
|
|
992
1003
|
```
|
|
993
1004
|
|
|
994
|
-
Rules the commands enforce rather than document: they refuse outside a Codeman session and never guess a URL; `send` transmits printable text plus Enter only (a control byte such as `Ctrl+C` is `app_exit` in opencode — ESC exists solely as `interrupt`, which never appends Enter); `rm` refuses an empty id, an unprovable self id and a prefix match in either direction. Ids may be the 8-character prefixes `ls` prints (resolved through the list; an ambiguous prefix refuses, anything shorter than 8 characters refuses on every verb). A prompt that starts with `-` goes after `--` (`send "$SID" -- "- fix the bug"`). The echo of the prompt you sent is output too: a `--match` marker that appears verbatim in the prompt matches at once, before the worker has done anything, so the prompt asks for it in halves. A remote session whose host is asleep answers a fire-and-forget `send` with `buffered` (Codeman wakes the host and types the prompt once the pane is back) or `dropped` (over the wake buffer's cap, nothing will be typed: exit `1`). Exit codes: `0` delivered/matched/signal, `1` error, `2` timeout, `3` the worker exited or the wait ended without an answer (`delivered:false`, `ended:true`), `4` refused. `spawn` prints the id alone on stdout (prose goes to stderr), so `SID=$(…)` captures exactly the id. `--json` prints the envelope's `data` for every verb. `--until stop` on a mode without hook signals is the server's 400, passed through — the marker path (`--match`) is the answer there, exactly as for the skill.
|
|
1005
|
+
Rules the commands enforce rather than document: they refuse outside a Codeman session and never guess a URL; `send` transmits printable text plus Enter only (a control byte such as `Ctrl+C` is `app_exit` in opencode — ESC exists solely as `interrupt`, which never appends Enter); `rm` refuses an empty id, an unprovable self id and a prefix match in either direction. Ids may be the 8-character prefixes `ls` prints (resolved through the list; an ambiguous prefix refuses, anything shorter than 8 characters refuses on every verb). A prompt that starts with `-` goes after `--` (`send "$SID" -- "- fix the bug"`). The echo of the prompt you sent is output too: a `--match` marker that appears verbatim in the prompt matches at once, before the worker has done anything, so the prompt asks for it in halves. A remote session whose host is asleep answers a fire-and-forget `send` with `buffered` (Codeman wakes the host and types the prompt once the pane is back) or `dropped` (over the wake buffer's cap, nothing will be typed: exit `1`). Exit codes: `0` delivered/matched/signal, `1` error, `2` timeout, `3` the worker exited or the wait ended without an answer (`delivered:false`, `ended:true`), `4` refused. `spawn` prints the id alone on stdout (prose goes to stderr), so `SID=$(…)` captures exactly the id. `spawn` with no case, or with `--working-dir`, starts the worker in that existing directory through `POST /api/v1/sessions` plus `POST /api/v1/sessions/:id/interactive` (or `/shell`) instead of quick-start, so no case is created and the directory is never labelled agent scratch; an empty `--working-dir` refuses (exit `4`) rather than falling back to cwd, and so does a cwd that is your home directory (Codeman's hooks would land in `~/.claude`), which needs an explicit `--working-dir ~`; if the start fails it still prints the created id and exits `1`. `--json` prints the envelope's `data` for every verb, except a directory `spawn`, which prints `{ sessionId, workingDir, created: true }`, plus `ready` when a readiness wait ran, `readinessError` when that call failed, and `startupError` when the start failed. `--until stop` on a mode without hook signals is the server's 400, passed through — the marker path (`--match`) is the answer there, exactly as for the skill.
|
|
1006
|
+
|
|
1007
|
+
### `codeman history read`: saved Codex conversations, offline
|
|
1008
|
+
|
|
1009
|
+
`codeman history read` reads Codex's own saved rollouts (`$CODEX_HOME/sessions`, else `~/.codex/sessions`) straight from disk: no server, no managed session, nothing written. Unlike `codeman agent` it works anywhere, including on a machine where Codeman is not running.
|
|
1010
|
+
|
|
1011
|
+
```bash
|
|
1012
|
+
codeman history read --session-id 019fc604 # one conversation, by native id or 8+ character prefix
|
|
1013
|
+
codeman history read --root-session-id <uuid> --topic auth # a conversation and every sub-agent or fork under it
|
|
1014
|
+
codeman history read --file /path/to/rollout.jsonl --format text
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
Filters keep whole user/assistant turns (`--topic` is a literal, case-insensitive match; `--after`/`--before` are inclusive UTC dates). A forked or spawned thread's copy of its parent's history is dropped, so every record belongs to the thread that wrote it. Output is JSON by default and carries `complete: false` whenever the evidence is partial (a file that could not be attributed, a compressed `.jsonl.zst` rollout, a record a running Codex is still writing, an unknown ancestor). Every bound fails closed and is raisable: `--metadata-bytes` (attributing the store, default 1 GiB), `--max-entries` (default 65536), `--scan-bytes` (the selected transcripts, default 16 MiB) and `--max-bytes` (output, default 8192). The full reference is [`skills/codeman/reference/history.md`](skills/codeman/reference/history.md).
|
|
995
1018
|
|
|
996
1019
|
### MCP server (`codeman mcp`): drive Codeman from any MCP client
|
|
997
1020
|
|
|
998
|
-
`codeman mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server on stdio, so any MCP client (Claude Code, Claude Desktop, Codex, Gemini CLI, Cursor, ...) can start Codeman sessions in any installed agent CLI, prompt them, wait for them, read their answers and clean up, from inside Codeman or from outside it. Like `codeman agent`, it is a client of the HTTP API
|
|
1021
|
+
`codeman mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server on stdio, so any MCP client (Claude Code, Claude Desktop, Codex, Gemini CLI, Cursor, ...) can start Codeman sessions in any installed agent CLI, prompt them, wait for them, read their answers and clean up, from inside Codeman or from outside it. Like `codeman agent`, it is a client of the HTTP API. The MCP server adds no routes of its own, and auth and ownership are unchanged.
|
|
999
1022
|
|
|
1000
1023
|
```bash
|
|
1001
1024
|
# Claude Code
|
|
@@ -1067,6 +1090,7 @@ REST over Fastify — **~230 handlers across 25 route modules**, plus an SSE str
|
|
|
1067
1090
|
| `GET` | `/api/sessions/:id/last-response` | The last answer as clean text, read from the transcript (claude, codex, deepseek) |
|
|
1068
1091
|
| `GET` | `/api/sessions/:id/wait` | Block until a signal fires (`?until=stop,idle,exit&timeout=&fresh=`); a timeout is a `200` |
|
|
1069
1092
|
| `GET` | `/api/sessions/:id/wait-output` | Block until a literal string appears (`?match=&nocase=&from=now\|buffer&timeout=`) |
|
|
1093
|
+
| `POST` / `GET` | `/api/sessions/:id/inbox` | Agent inbox: post `{text}` / read every pending message (`?wait=` blocks while nothing is new); `POST …/inbox/ack {ids}` removes them, receiver only |
|
|
1070
1094
|
| `GET` | `/api/sessions/unified` | Unified live + history list (Session Manager) — `?q=&limit=` |
|
|
1071
1095
|
| `POST` | `/api/sessions/:id/pin` | Pin/unpin in the Session Manager (`{pinned}`) |
|
|
1072
1096
|
| `PUT` | `/api/session-order` | Sync tab order across devices (`{order: [ids]}`) |
|
|
@@ -1223,7 +1247,7 @@ Full details: [`docs/archive/code-structure-findings.md`](docs/archive/code-stru
|
|
|
1223
1247
|
|
|
1224
1248
|
[](https://www.npmjs.com/package/xterm-zerolag-input)
|
|
1225
1249
|
|
|
1226
|
-
Instant keystroke feedback overlay for xterm.js. Eliminates perceived input latency over high-RTT connections by rendering typed characters immediately as a pixel-perfect DOM overlay. Zero dependencies,
|
|
1250
|
+
Instant keystroke feedback overlay for xterm.js. Eliminates perceived input latency over high-RTT connections by rendering typed characters immediately as a pixel-perfect DOM overlay. Zero dependencies, 5.7 kB minified and gzipped, configurable prompt detection, CJK/emoji wide-character support, full state machine with 276 tests. Typing cost does not grow with prompt length.
|
|
1227
1251
|
|
|
1228
1252
|
```bash
|
|
1229
1253
|
npm install xterm-zerolag-input
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface CodexAttributionOptions {
|
|
2
|
+
codexHome: string;
|
|
3
|
+
sessionId: string;
|
|
4
|
+
workingDir: string;
|
|
5
|
+
resumeSessionId?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CodexAttributionBudget {
|
|
8
|
+
maxEntries: number;
|
|
9
|
+
maxBytes: number;
|
|
10
|
+
/** Separate bound for cheap negative prefixes; full candidate metadata has its own budget. */
|
|
11
|
+
maxPrefixBytes?: number;
|
|
12
|
+
}
|
|
13
|
+
/** Match the CLI's relative CODEX_HOME interpretation without exposing env credentials. */
|
|
14
|
+
export declare function resolveEffectiveCodexHome(sessionHome: string | undefined, workingDir: string, env?: Readonly<Record<string, string | undefined>>): string;
|
|
15
|
+
/** Test-only: forget every remembered attribution. */
|
|
16
|
+
export declare function __clearCodexAttributionMemo(): void;
|
|
17
|
+
/**
|
|
18
|
+
* A configured resume and a newly owned rollout conflict rather than pinning an
|
|
19
|
+
* old launch forever after /new. TUI resumes of foreign-originator threads cannot
|
|
20
|
+
* be authoritatively tracked from this metadata; this returns attributed evidence.
|
|
21
|
+
*/
|
|
22
|
+
export declare function findExactCodexConversation(options: CodexAttributionOptions, budget?: CodexAttributionBudget): Promise<{
|
|
23
|
+
id: string;
|
|
24
|
+
path: string;
|
|
25
|
+
} | undefined>;
|
|
26
|
+
//# sourceMappingURL=agent-codex-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-codex-identity.d.ts","sourceRoot":"","sources":["../src/agent-codex-identity.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,8FAA8F;IAC9F,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAcD,2FAA2F;AAC3F,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GAC9D,MAAM,CAGR;AA4CD,sDAAsD;AACtD,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAeD;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,uBAAuB,EAChC,MAAM,GAAE,sBAAgE,GACvE,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC,CAsDnD"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Bounded Codex rollout attribution for agent evidence. Never uses
|
|
3
|
+
* newest-mtime, prompt timestamps or cwd alone as proof of session ownership.
|
|
4
|
+
* The first call walks the store under explicit budgets; the attributed file is
|
|
5
|
+
* then remembered per session and only re-verified (plus a scan of the date
|
|
6
|
+
* directories not older than it) on later calls, since codex never prunes
|
|
7
|
+
* `~/.codex/sessions`.
|
|
8
|
+
*/
|
|
9
|
+
import { open, opendir, realpath } from 'node:fs/promises';
|
|
10
|
+
import { probePathKind } from './utils/bounded-path-probe.js';
|
|
11
|
+
import { tmpdir } from 'node:os';
|
|
12
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
13
|
+
import { LRUMap } from './utils/lru-map.js';
|
|
14
|
+
const UUID_AT_END = /-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
|
|
15
|
+
const HEAD_BYTES = 131072;
|
|
16
|
+
const PREFIX_SCAN_BYTES = 8 * 1024 * 1024;
|
|
17
|
+
async function canonical(path) {
|
|
18
|
+
if ((await probePathKind(path, { pastCap: true })) !== 'directory')
|
|
19
|
+
return undefined;
|
|
20
|
+
try {
|
|
21
|
+
return await realpath(path);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Match the CLI's relative CODEX_HOME interpretation without exposing env credentials. */
|
|
28
|
+
export function resolveEffectiveCodexHome(sessionHome, workingDir, env = process.env) {
|
|
29
|
+
const path = resolve(workingDir, sessionHome || env.CODEX_HOME || join(env.HOME || tmpdir(), '.codex'));
|
|
30
|
+
return path;
|
|
31
|
+
}
|
|
32
|
+
/** Complete metadata only: a prefix or a partially flushed JSONL row proves nothing. */
|
|
33
|
+
function strictMetadata(bytes) {
|
|
34
|
+
const rows = bytes.toString('utf8').split('\n');
|
|
35
|
+
rows.pop();
|
|
36
|
+
let found;
|
|
37
|
+
for (const line of rows) {
|
|
38
|
+
try {
|
|
39
|
+
const row = JSON.parse(line);
|
|
40
|
+
if (row.type !== 'session_meta')
|
|
41
|
+
continue;
|
|
42
|
+
if (found ||
|
|
43
|
+
typeof row.payload?.id !== 'string' ||
|
|
44
|
+
typeof row.payload.cwd !== 'string' ||
|
|
45
|
+
(row.payload.originator !== undefined && typeof row.payload.originator !== 'string'))
|
|
46
|
+
return undefined;
|
|
47
|
+
found = row.payload;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* Incomplete or malformed rows are not identity evidence. */
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return found;
|
|
54
|
+
}
|
|
55
|
+
const attributionMemo = new LRUMap({ maxSize: 1024 });
|
|
56
|
+
/** Test-only: forget every remembered attribution. */
|
|
57
|
+
export function __clearCodexAttributionMemo() {
|
|
58
|
+
attributionMemo.clear();
|
|
59
|
+
}
|
|
60
|
+
/** Short first read: `originator` sits right after `id`, `timestamp` and `cwd`. */
|
|
61
|
+
const PREFIX_FIRST_BYTES = 1024;
|
|
62
|
+
/** Fallback read when the first window holds no complete `originator` field. */
|
|
63
|
+
const PREFIX_MAX_BYTES = 4096;
|
|
64
|
+
const ORIGINATOR_FIELD = /"originator"\s*:\s*"(?:[^"\\]|\\.)*"/;
|
|
65
|
+
/**
|
|
66
|
+
* Is a date-shaped directory name older than the remembered one at the same depth?
|
|
67
|
+
* Only all-digit names compare (codex writes `sessions/YYYY/MM/DD/`); anything else
|
|
68
|
+
* is never pruned, so an unexpected layout costs a wider scan, not a missed rollout.
|
|
69
|
+
*/
|
|
70
|
+
function olderDatePart(name, memo) {
|
|
71
|
+
if (memo === undefined || !/^\d+$/.test(name) || !/^\d+$/.test(memo))
|
|
72
|
+
return false;
|
|
73
|
+
return Number(name) < Number(memo);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A configured resume and a newly owned rollout conflict rather than pinning an
|
|
77
|
+
* old launch forever after /new. TUI resumes of foreign-originator threads cannot
|
|
78
|
+
* be authoritatively tracked from this metadata; this returns attributed evidence.
|
|
79
|
+
*/
|
|
80
|
+
export async function findExactCodexConversation(options, budget = { maxEntries: 8192, maxBytes: 1048576 }) {
|
|
81
|
+
const workspace = await canonical(options.workingDir);
|
|
82
|
+
const home = await canonical(options.codexHome);
|
|
83
|
+
if (!workspace || !home)
|
|
84
|
+
return undefined;
|
|
85
|
+
const sessions = join(home, 'sessions');
|
|
86
|
+
if ((await probePathKind(sessions, { pastCap: true })) !== 'directory')
|
|
87
|
+
return undefined;
|
|
88
|
+
const key = [home, options.sessionId, options.resumeSessionId ?? '', workspace].join('\0');
|
|
89
|
+
const remembered = attributionMemo.get(key);
|
|
90
|
+
if (remembered) {
|
|
91
|
+
const verified = await verifyRemembered(remembered, workspace, budget);
|
|
92
|
+
if (verified) {
|
|
93
|
+
const others = await scanCandidates(sessions, options, budget, remembered.dirParts);
|
|
94
|
+
if (others && others.length === 1 && others[0].path === remembered.path) {
|
|
95
|
+
return { id: remembered.id, path: remembered.path };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
attributionMemo.delete(key);
|
|
99
|
+
// A file that no longer verifies (replaced, rewritten, gone) gets one full walk
|
|
100
|
+
// now. A verified file whose incremental scan failed does not: that scan reads a
|
|
101
|
+
// subset of what a full walk reads under the same budget, so a second candidate,
|
|
102
|
+
// an exhausted budget or an unreadable entry it hit is one the full walk would hit
|
|
103
|
+
// too, and walking the whole never-pruned store could only end the same way.
|
|
104
|
+
if (verified)
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const candidates = await scanCandidates(sessions, options, budget);
|
|
108
|
+
if (!candidates || candidates.length !== 1)
|
|
109
|
+
return undefined;
|
|
110
|
+
const candidate = candidates[0];
|
|
111
|
+
if (!candidate.meta.cwd || (await canonical(candidate.meta.cwd)) !== workspace)
|
|
112
|
+
return undefined;
|
|
113
|
+
const handle = await open(candidate.path, 'r').catch(() => undefined);
|
|
114
|
+
if (!handle)
|
|
115
|
+
return undefined;
|
|
116
|
+
try {
|
|
117
|
+
const info = await handle.stat();
|
|
118
|
+
const bytes = Buffer.alloc(HEAD_BYTES);
|
|
119
|
+
const read = await handle.read(bytes, 0, bytes.length, 0);
|
|
120
|
+
const meta = strictMetadata(bytes.subarray(0, read.bytesRead));
|
|
121
|
+
if (!meta ||
|
|
122
|
+
meta.id !== candidate.id ||
|
|
123
|
+
meta.cwd !== candidate.meta.cwd ||
|
|
124
|
+
meta.originator !== candidate.meta.originator)
|
|
125
|
+
return undefined;
|
|
126
|
+
attributionMemo.set(key, {
|
|
127
|
+
id: candidate.id,
|
|
128
|
+
path: candidate.path,
|
|
129
|
+
dev: info.dev,
|
|
130
|
+
ino: info.ino,
|
|
131
|
+
meta,
|
|
132
|
+
dirParts: relative(sessions, dirname(candidate.path)).split(sep).filter(Boolean),
|
|
133
|
+
});
|
|
134
|
+
return { id: candidate.id, path: candidate.path };
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
await handle.close();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/** Same file (`dev:ino`), same strict metadata, same canonical workspace: nothing else. */
|
|
141
|
+
async function verifyRemembered(memo, workspace, budget) {
|
|
142
|
+
if (HEAD_BYTES > budget.maxBytes)
|
|
143
|
+
return false;
|
|
144
|
+
if (!memo.meta.cwd || (await canonical(memo.meta.cwd)) !== workspace)
|
|
145
|
+
return false;
|
|
146
|
+
const handle = await open(memo.path, 'r').catch(() => undefined);
|
|
147
|
+
if (!handle)
|
|
148
|
+
return false;
|
|
149
|
+
try {
|
|
150
|
+
const info = await handle.stat();
|
|
151
|
+
if (!info.isFile() || info.dev !== memo.dev || info.ino !== memo.ino)
|
|
152
|
+
return false;
|
|
153
|
+
const bytes = Buffer.alloc(HEAD_BYTES);
|
|
154
|
+
const read = await handle.read(bytes, 0, bytes.length, 0);
|
|
155
|
+
const meta = strictMetadata(bytes.subarray(0, read.bytesRead));
|
|
156
|
+
return !!meta && meta.id === memo.id && meta.cwd === memo.meta.cwd && meta.originator === memo.meta.originator;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
await handle.close();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Every rollout under `sessions` whose strict metadata names this session (or the
|
|
167
|
+
* configured resume id), or undefined when the walk hit a bound or an unreadable
|
|
168
|
+
* entry (an incomplete inventory proves nothing). With `notOlderThan`, date-shaped
|
|
169
|
+
* directories older than those components are skipped.
|
|
170
|
+
*/
|
|
171
|
+
async function scanCandidates(sessions, options, budget, notOlderThan) {
|
|
172
|
+
// `onBoundary`: every ancestor so far equals the remembered path, so pruning applies.
|
|
173
|
+
const directories = [{ path: sessions, depth: 0, onBoundary: notOlderThan !== undefined }];
|
|
174
|
+
const candidates = [];
|
|
175
|
+
const originator = `codeman_${options.sessionId}`;
|
|
176
|
+
const originatorJson = JSON.stringify(originator);
|
|
177
|
+
const explicit = options.resumeSessionId;
|
|
178
|
+
let entries = 0;
|
|
179
|
+
let prefixes = 0;
|
|
180
|
+
const prefixLimit = Math.min(budget.maxPrefixBytes ?? PREFIX_SCAN_BYTES, PREFIX_SCAN_BYTES);
|
|
181
|
+
let scanned = HEAD_BYTES; // Reserve an independent final verification.
|
|
182
|
+
while (directories.length) {
|
|
183
|
+
const dir = directories.pop();
|
|
184
|
+
const handle = await opendir(dir.path).catch(() => undefined);
|
|
185
|
+
if (!handle)
|
|
186
|
+
return undefined;
|
|
187
|
+
for await (const entry of handle) {
|
|
188
|
+
if (++entries > budget.maxEntries)
|
|
189
|
+
return undefined;
|
|
190
|
+
const path = join(dir.path, entry.name);
|
|
191
|
+
if (entry.isDirectory()) {
|
|
192
|
+
if (dir.depth >= 8)
|
|
193
|
+
return undefined;
|
|
194
|
+
const part = notOlderThan?.[dir.depth];
|
|
195
|
+
if (dir.onBoundary && olderDatePart(entry.name, part))
|
|
196
|
+
continue;
|
|
197
|
+
directories.push({ path, depth: dir.depth + 1, onBoundary: dir.onBoundary && entry.name === part });
|
|
198
|
+
}
|
|
199
|
+
else if (entry.isFile() && entry.name.endsWith('.jsonl')) {
|
|
200
|
+
const id = entry.name.match(UUID_AT_END)?.[1];
|
|
201
|
+
if (!id)
|
|
202
|
+
continue; // no rollout id in the name: never a candidate, read nothing
|
|
203
|
+
const file = await open(path, 'r').catch(() => undefined);
|
|
204
|
+
if (!file)
|
|
205
|
+
return undefined;
|
|
206
|
+
try {
|
|
207
|
+
const info = await file.stat();
|
|
208
|
+
if (!info.isFile())
|
|
209
|
+
return undefined;
|
|
210
|
+
if (id !== explicit) {
|
|
211
|
+
// Cheap negative filter only; a match still needs full parsed metadata.
|
|
212
|
+
// A short first window decides when it already holds the whole
|
|
213
|
+
// `originator` field; only otherwise is the wider window read.
|
|
214
|
+
let window = Math.min(info.size, PREFIX_FIRST_BYTES);
|
|
215
|
+
let prefix = '';
|
|
216
|
+
for (;;) {
|
|
217
|
+
if (prefixes + window > prefixLimit)
|
|
218
|
+
return undefined;
|
|
219
|
+
prefixes += window;
|
|
220
|
+
const buffer = Buffer.alloc(window);
|
|
221
|
+
const first = await file.read(buffer, 0, window, 0);
|
|
222
|
+
prefix = buffer.subarray(0, first.bytesRead).toString('utf8');
|
|
223
|
+
if (prefix.includes(originatorJson) || ORIGINATOR_FIELD.test(prefix))
|
|
224
|
+
break;
|
|
225
|
+
const wider = Math.min(info.size, PREFIX_MAX_BYTES);
|
|
226
|
+
if (wider <= window)
|
|
227
|
+
break;
|
|
228
|
+
window = wider;
|
|
229
|
+
}
|
|
230
|
+
if (!prefix.includes(originatorJson))
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const size = Math.min(info.size, HEAD_BYTES);
|
|
234
|
+
if (scanned + size > budget.maxBytes)
|
|
235
|
+
return undefined;
|
|
236
|
+
scanned += size;
|
|
237
|
+
const bytes = Buffer.alloc(size);
|
|
238
|
+
const read = await file.read(bytes, 0, size, 0);
|
|
239
|
+
const meta = strictMetadata(bytes.subarray(0, read.bytesRead));
|
|
240
|
+
if (!meta || meta.id !== id)
|
|
241
|
+
continue;
|
|
242
|
+
if (id === explicit || meta.originator === originator)
|
|
243
|
+
candidates.push({ id, path, meta });
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
await file.close();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return candidates;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=agent-codex-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-codex-identity.js","sourceRoot":"","sources":["../src/agent-codex-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const INSPECT_MAX_BYTES = 65536;
|
|
2
|
+
export declare const INSPECT_SCAN_BYTES = 262144;
|
|
3
|
+
export interface InspectionScope {
|
|
4
|
+
owner: string;
|
|
5
|
+
sessionId: string;
|
|
6
|
+
generation: string;
|
|
7
|
+
conversationId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class InspectionConflict extends Error {
|
|
10
|
+
}
|
|
11
|
+
/** UTF8-safe suffix, also used for explicitly non-incremental pane evidence. */
|
|
12
|
+
export declare function boundedUtf8Tail(text: string, maxBytes: number): string;
|
|
13
|
+
/** Cursors kept per owner and session; older ones are retired first. */
|
|
14
|
+
export declare const INSPECT_CURSORS_PER_SCOPE = 8;
|
|
15
|
+
export declare class InspectionReader {
|
|
16
|
+
private readonly now;
|
|
17
|
+
private readonly capacity;
|
|
18
|
+
private readonly ttlMs;
|
|
19
|
+
private readonly perScope;
|
|
20
|
+
private readonly cursors;
|
|
21
|
+
constructor(now?: () => number, capacity?: number, ttlMs?: number, perScope?: number);
|
|
22
|
+
read(path: string, scope: InspectionScope, maxBytes: number, since?: string): Promise<{
|
|
23
|
+
evidence: string;
|
|
24
|
+
cursor: `${string}-${string}-${string}-${string}-${string}`;
|
|
25
|
+
omittedBeforeBytes: number;
|
|
26
|
+
truncated: boolean;
|
|
27
|
+
blockedReason: string | undefined;
|
|
28
|
+
scannedBytes: number;
|
|
29
|
+
}>;
|
|
30
|
+
clear(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=agent-inspection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-inspection.d.ts","sourceRoot":"","sources":["../src/agent-inspection.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,iBAAiB,QAAQ,CAAC;AACvC,eAAO,MAAM,kBAAkB,SAAS,CAAC;AACzC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAcD,qBAAa,kBAAmB,SAAQ,KAAK;CAAG;AAEhD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOtE;AAUD,wEAAwE;AACxE,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,qBAAa,gBAAgB;IAGzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAL3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;gBAEvC,GAAG,eAAW,EACd,QAAQ,SAAO,EACf,KAAK,SAAS,EACd,QAAQ,SAA4B;IAGjD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;;;;;;;;IA6IjF,KAAK,IAAI,IAAI;CAGd"}
|