aicodeman 1.47.0 → 1.49.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 +15 -3
- package/dist/cli-notify.d.ts +34 -0
- package/dist/cli-notify.d.ts.map +1 -0
- package/dist/cli-notify.js +100 -0
- package/dist/cli-notify.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +16 -0
- package/dist/cli.js.map +1 -1
- package/dist/config/cli-registry/patterns.d.ts +1 -1
- package/dist/config/cli-registry/patterns.d.ts.map +1 -1
- package/dist/config/cli-registry/patterns.js +4 -0
- package/dist/config/cli-registry/patterns.js.map +1 -1
- package/dist/config/cli-registry/schema.d.ts +7 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +67 -3
- 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 +114 -31
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +51 -21
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/config/foreign-tmux.d.ts +48 -0
- package/dist/config/foreign-tmux.d.ts.map +1 -0
- package/dist/config/foreign-tmux.js +48 -0
- package/dist/config/foreign-tmux.js.map +1 -0
- package/dist/config/path-probe.d.ts +6 -0
- package/dist/config/path-probe.d.ts.map +1 -1
- package/dist/config/path-probe.js +6 -0
- package/dist/config/path-probe.js.map +1 -1
- package/dist/config-backup.d.ts +1 -1
- package/dist/config-backup.d.ts.map +1 -1
- package/dist/config-backup.js +2 -0
- package/dist/config-backup.js.map +1 -1
- package/dist/custom-model-hosts.d.ts +32 -8
- package/dist/custom-model-hosts.d.ts.map +1 -1
- package/dist/custom-model-hosts.js +10 -0
- package/dist/custom-model-hosts.js.map +1 -1
- package/dist/custom-model-injection-apply.d.ts +21 -5
- package/dist/custom-model-injection-apply.d.ts.map +1 -1
- package/dist/custom-model-injection-apply.js +121 -27
- package/dist/custom-model-injection-apply.js.map +1 -1
- package/dist/custom-model-injection.d.ts +6 -0
- package/dist/custom-model-injection.d.ts.map +1 -1
- package/dist/custom-model-injection.js +92 -10
- package/dist/custom-model-injection.js.map +1 -1
- package/dist/discord-bridge.d.ts +338 -0
- package/dist/discord-bridge.d.ts.map +1 -0
- package/dist/discord-bridge.js +1256 -0
- package/dist/discord-bridge.js.map +1 -0
- package/dist/docker-hosts.d.ts +8 -1
- package/dist/docker-hosts.d.ts.map +1 -1
- package/dist/docker-hosts.js +5 -5
- package/dist/docker-hosts.js.map +1 -1
- package/dist/edit-history-local-source.d.ts +83 -0
- package/dist/edit-history-local-source.d.ts.map +1 -0
- package/dist/edit-history-local-source.js +198 -0
- package/dist/edit-history-local-source.js.map +1 -0
- package/dist/edit-history-parse.d.ts +114 -0
- package/dist/edit-history-parse.d.ts.map +1 -0
- package/dist/edit-history-parse.js +312 -0
- package/dist/edit-history-parse.js.map +1 -0
- package/dist/edit-history-store.d.ts +209 -0
- package/dist/edit-history-store.d.ts.map +1 -0
- package/dist/edit-history-store.js +599 -0
- package/dist/edit-history-store.js.map +1 -0
- package/dist/foreign-tmux-discovery.d.ts +140 -0
- package/dist/foreign-tmux-discovery.d.ts.map +1 -0
- package/dist/foreign-tmux-discovery.js +366 -0
- package/dist/foreign-tmux-discovery.js.map +1 -0
- package/dist/foreign-tmux.d.ts +381 -0
- package/dist/foreign-tmux.d.ts.map +1 -0
- package/dist/foreign-tmux.js +775 -0
- package/dist/foreign-tmux.js.map +1 -0
- package/dist/git-clone.d.ts +6 -1
- package/dist/git-clone.d.ts.map +1 -1
- package/dist/git-clone.js +79 -14
- package/dist/git-clone.js.map +1 -1
- package/dist/git-fetch-scheduler.d.ts +2 -0
- package/dist/git-fetch-scheduler.d.ts.map +1 -1
- package/dist/git-fetch-scheduler.js +1 -1
- package/dist/git-fetch-scheduler.js.map +1 -1
- package/dist/git-fetch.d.ts +1 -1
- package/dist/git-fetch.d.ts.map +1 -1
- package/dist/git-workspace-status.d.ts +2 -2
- package/dist/git-workspace-status.d.ts.map +1 -1
- package/dist/hooks-config.d.ts +2 -1
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +2 -1
- package/dist/hooks-config.js.map +1 -1
- package/dist/image-watcher.js +4 -4
- package/dist/image-watcher.js.map +1 -1
- package/dist/live-worktree.d.ts +53 -0
- package/dist/live-worktree.d.ts.map +1 -0
- package/dist/live-worktree.js +97 -0
- package/dist/live-worktree.js.map +1 -0
- package/dist/mux-interface.d.ts +22 -2
- package/dist/mux-interface.d.ts.map +1 -1
- package/dist/reboot-restore.d.ts +1 -1
- package/dist/reboot-restore.d.ts.map +1 -1
- package/dist/reboot-restore.js +9 -0
- package/dist/reboot-restore.js.map +1 -1
- package/dist/remote-files.d.ts +150 -5
- package/dist/remote-files.d.ts.map +1 -1
- package/dist/remote-files.js +505 -7
- package/dist/remote-files.js.map +1 -1
- package/dist/remote-hosts.d.ts +15 -9
- package/dist/remote-hosts.d.ts.map +1 -1
- package/dist/remote-hosts.js +42 -20
- package/dist/remote-hosts.js.map +1 -1
- package/dist/session-cli-registry-bridge.d.ts.map +1 -1
- package/dist/session-cli-registry-bridge.js +23 -8
- package/dist/session-cli-registry-bridge.js.map +1 -1
- package/dist/session-env-clamp.d.ts +1 -1
- package/dist/session-env-clamp.d.ts.map +1 -1
- package/dist/session-env-clamp.js +4 -3
- package/dist/session-env-clamp.js.map +1 -1
- package/dist/session.d.ts +161 -24
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +337 -37
- package/dist/session.js.map +1 -1
- package/dist/tmux-manager.d.ts +114 -12
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +318 -41
- package/dist/tmux-manager.js.map +1 -1
- package/dist/types/discord.d.ts +55 -0
- package/dist/types/discord.d.ts.map +1 -0
- package/dist/types/discord.js +18 -0
- package/dist/types/discord.js.map +1 -0
- package/dist/types/foreign-tmux.d.ts +101 -0
- package/dist/types/foreign-tmux.d.ts.map +1 -0
- package/dist/types/foreign-tmux.js +27 -0
- package/dist/types/foreign-tmux.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/session.d.ts +119 -2
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/types/update.d.ts +4 -1
- package/dist/types/update.d.ts.map +1 -1
- package/dist/web/case-path.d.ts +2 -0
- package/dist/web/case-path.d.ts.map +1 -1
- package/dist/web/case-path.js +3 -3
- package/dist/web/case-path.js.map +1 -1
- package/dist/web/edit-history-sync.d.ts +178 -0
- package/dist/web/edit-history-sync.d.ts.map +1 -0
- package/dist/web/edit-history-sync.js +461 -0
- package/dist/web/edit-history-sync.js.map +1 -0
- package/dist/web/launch-defaults.d.ts +1 -1
- package/dist/web/launch-defaults.js +2 -2
- package/dist/web/launch-defaults.js.map +1 -1
- package/dist/web/linked-cases-writer.d.ts +43 -0
- package/dist/web/linked-cases-writer.d.ts.map +1 -0
- package/dist/web/linked-cases-writer.js +107 -0
- package/dist/web/linked-cases-writer.js.map +1 -0
- package/dist/web/paste-image-gc.d.ts +10 -1
- package/dist/web/paste-image-gc.d.ts.map +1 -1
- package/dist/web/paste-image-gc.js +10 -2
- package/dist/web/paste-image-gc.js.map +1 -1
- package/dist/web/ports/session-port.d.ts +13 -0
- package/dist/web/ports/session-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.fe8a6b4c.js → app.9ea37070.js} +6 -6
- package/dist/web/public/app.9ea37070.js.br +0 -0
- package/dist/web/public/app.9ea37070.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/{constants.affcdde6.js → constants.782170e1.js} +114 -25
- package/dist/web/public/constants.782170e1.js.br +0 -0
- package/dist/web/public/constants.782170e1.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/edit-history-ui.js +643 -0
- package/dist/web/public/edit-history-ui.js.br +0 -0
- package/dist/web/public/edit-history-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/foreign-sessions.js +476 -0
- package/dist/web/public/foreign-sessions.js.br +0 -0
- package/dist/web/public/foreign-sessions.js.gz +0 -0
- package/dist/web/public/git-status-ui.js +5 -3
- 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.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.a5e82c95.js +2 -0
- package/dist/web/public/i18n.a5e82c95.js.br +0 -0
- package/dist/web/public/i18n.a5e82c95.js.gz +0 -0
- package/dist/web/public/image-input.a5d0f8f3.js.gz +0 -0
- package/dist/web/public/index.html +183 -18
- 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.ff64fafc.js → keyboard-accessory.b941676c.js} +75 -2
- package/dist/web/public/keyboard-accessory.b941676c.js.br +0 -0
- package/dist/web/public/keyboard-accessory.b941676c.js.gz +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 +10 -0
- package/dist/web/public/mobile-overview.js.br +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/mobile.67c8eb5b.css +1 -0
- package/dist/web/public/mobile.67c8eb5b.css.br +0 -0
- package/dist/web/public/mobile.67c8eb5b.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.4a56ee63.js → panels-ui.8bcd4473.js} +5 -5
- package/dist/web/public/panels-ui.8bcd4473.js.br +0 -0
- package/dist/web/public/panels-ui.8bcd4473.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 → respawn-ui.304ba0d4.js} +1 -1
- package/dist/web/public/respawn-ui.304ba0d4.js.br +0 -0
- package/dist/web/public/respawn-ui.304ba0d4.js.gz +0 -0
- package/dist/web/public/sanitize-html.e7147e76.js.gz +0 -0
- package/dist/web/public/security-notices.json +1 -21
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/{session-ui.426fb671.js → session-ui.a7c8c095.js} +30 -30
- package/dist/web/public/session-ui.a7c8c095.js.br +0 -0
- package/dist/web/public/session-ui.a7c8c095.js.gz +0 -0
- package/dist/web/public/settings-ui.18f92052.js +106 -0
- package/dist/web/public/settings-ui.18f92052.js.br +0 -0
- package/dist/web/public/settings-ui.18f92052.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.6a718331.css +1 -0
- package/dist/web/public/styles.6a718331.css.br +0 -0
- package/dist/web/public/styles.6a718331.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.b5cdceaf.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.98843069.js.gz +0 -0
- package/dist/web/public/terminal-split.js.gz +0 -0
- package/dist/web/public/terminal-tile.js +2 -2
- 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.a7883640.js +4 -0
- package/dist/web/public/terminal-ui.a7883640.js.br +0 -0
- package/dist/web/public/terminal-ui.a7883640.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.276b11d9.js.gz +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 -8
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +165 -50
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/config-backup-routes.d.ts +5 -1
- package/dist/web/routes/config-backup-routes.d.ts.map +1 -1
- package/dist/web/routes/config-backup-routes.js +4 -1
- package/dist/web/routes/config-backup-routes.js.map +1 -1
- package/dist/web/routes/custom-model-routes.d.ts +7 -2
- package/dist/web/routes/custom-model-routes.d.ts.map +1 -1
- package/dist/web/routes/custom-model-routes.js +51 -6
- package/dist/web/routes/custom-model-routes.js.map +1 -1
- package/dist/web/routes/discord-routes.d.ts +25 -0
- package/dist/web/routes/discord-routes.d.ts.map +1 -0
- package/dist/web/routes/discord-routes.js +206 -0
- package/dist/web/routes/discord-routes.js.map +1 -0
- package/dist/web/routes/edit-history-routes.d.ts +43 -0
- package/dist/web/routes/edit-history-routes.d.ts.map +1 -0
- package/dist/web/routes/edit-history-routes.js +107 -0
- package/dist/web/routes/edit-history-routes.js.map +1 -0
- package/dist/web/routes/file-routes.d.ts.map +1 -1
- package/dist/web/routes/file-routes.js +273 -102
- package/dist/web/routes/file-routes.js.map +1 -1
- package/dist/web/routes/git-status-routes.d.ts.map +1 -1
- package/dist/web/routes/git-status-routes.js +7 -2
- package/dist/web/routes/git-status-routes.js.map +1 -1
- 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/mux-routes.d.ts +10 -3
- package/dist/web/routes/mux-routes.d.ts.map +1 -1
- package/dist/web/routes/mux-routes.js +59 -1
- package/dist/web/routes/mux-routes.js.map +1 -1
- package/dist/web/routes/ralph-routes.d.ts.map +1 -1
- package/dist/web/routes/ralph-routes.js +22 -0
- package/dist/web/routes/ralph-routes.js.map +1 -1
- package/dist/web/routes/readmymind-routes.d.ts.map +1 -1
- package/dist/web/routes/readmymind-routes.js +3 -2
- package/dist/web/routes/readmymind-routes.js.map +1 -1
- package/dist/web/routes/respawn-routes.d.ts.map +1 -1
- package/dist/web/routes/respawn-routes.js +24 -0
- package/dist/web/routes/respawn-routes.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts +21 -1
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +338 -55
- 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 +4 -2
- package/dist/web/routes/system-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +92 -2
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +111 -10
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/self-update.d.ts +9 -0
- package/dist/web/self-update.d.ts.map +1 -1
- package/dist/web/self-update.js +19 -3
- package/dist/web/self-update.js.map +1 -1
- package/dist/web/sensitive-path.d.ts.map +1 -1
- package/dist/web/sensitive-path.js +15 -0
- package/dist/web/sensitive-path.js.map +1 -1
- package/dist/web/server.d.ts +56 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +285 -17
- package/dist/web/server.js.map +1 -1
- package/dist/web/session-wait-registry.d.ts +13 -0
- package/dist/web/session-wait-registry.d.ts.map +1 -1
- package/dist/web/session-wait-registry.js +16 -8
- package/dist/web/session-wait-registry.js.map +1 -1
- package/package.json +2 -2
- package/skills/codeman/SKILL.md +20 -4
- package/dist/web/public/app.fe8a6b4c.js.br +0 -0
- package/dist/web/public/app.fe8a6b4c.js.gz +0 -0
- package/dist/web/public/constants.affcdde6.js.br +0 -0
- package/dist/web/public/constants.affcdde6.js.gz +0 -0
- package/dist/web/public/i18n.a618ef4e.js +0 -2
- package/dist/web/public/i18n.a618ef4e.js.br +0 -0
- package/dist/web/public/i18n.a618ef4e.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.ff64fafc.js.br +0 -0
- package/dist/web/public/keyboard-accessory.ff64fafc.js.gz +0 -0
- package/dist/web/public/mobile.1bbd2d67.css +0 -1
- package/dist/web/public/mobile.1bbd2d67.css.br +0 -0
- package/dist/web/public/mobile.1bbd2d67.css.gz +0 -0
- 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/respawn-ui.d7adcf6a.js.br +0 -0
- package/dist/web/public/respawn-ui.d7adcf6a.js.gz +0 -0
- package/dist/web/public/session-ui.426fb671.js.br +0 -0
- package/dist/web/public/session-ui.426fb671.js.gz +0 -0
- package/dist/web/public/settings-ui.a191154e.js +0 -106
- 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/styles.4f0c67a0.css +0 -1
- package/dist/web/public/styles.4f0c67a0.css.br +0 -0
- package/dist/web/public/styles.4f0c67a0.css.gz +0 -0
- package/dist/web/public/terminal-ui.7e787829.js +0 -4
- package/dist/web/public/terminal-ui.7e787829.js.br +0 -0
- package/dist/web/public/terminal-ui.7e787829.js.gz +0 -0
|
@@ -69,12 +69,20 @@ contextLength) {
|
|
|
69
69
|
return result;
|
|
70
70
|
}
|
|
71
71
|
case 'configContentEnv': {
|
|
72
|
-
const content = renderConfigContent(cap.template, endpoint, modelId, apiKey);
|
|
72
|
+
const content = renderConfigContent(cap.template, endpoint, modelId, apiKey, contextLength);
|
|
73
73
|
return withLaunchModel({ kind: 'env', envOverrides: { [cap.envVar]: content } }, cap.launchModel, modelId);
|
|
74
74
|
}
|
|
75
75
|
case 'configDir': {
|
|
76
|
-
const { content, extraEnv } = renderConfigFile(cap.template, endpoint, modelId, apiKey);
|
|
77
|
-
return withLaunchModel({
|
|
76
|
+
const { content, extraEnv } = renderConfigFile(cap.template, endpoint, modelId, apiKey, contextLength);
|
|
77
|
+
return withLaunchModel({
|
|
78
|
+
kind: 'configDir',
|
|
79
|
+
dirEnvVar: cap.dirEnvVar,
|
|
80
|
+
files: [{ relPath: cap.fileName, content }],
|
|
81
|
+
extraEnv,
|
|
82
|
+
...(cap.linkFromRealHome ? { linkFromRealHome: cap.linkFromRealHome } : {}),
|
|
83
|
+
...(cap.linkFromRealHomeDirs ? { linkFromRealHomeDirs: cap.linkFromRealHomeDirs } : {}),
|
|
84
|
+
...(cap.realHomeFallback ? { realHomeFallback: cap.realHomeFallback } : {}),
|
|
85
|
+
}, cap.launchModel, modelId);
|
|
78
86
|
}
|
|
79
87
|
case 'unsupported':
|
|
80
88
|
return { kind: 'unsupported' };
|
|
@@ -86,28 +94,96 @@ function withLaunchModel(result, template, modelId) {
|
|
|
86
94
|
return result;
|
|
87
95
|
return { ...result, launchModel: template.split('{modelId}').join(modelId) };
|
|
88
96
|
}
|
|
89
|
-
|
|
97
|
+
/**
|
|
98
|
+
* One quarter of the window is held back for the reply, capped at 8192 tokens (a small local
|
|
99
|
+
* model's window must not lose a disproportionate slice to the reservation). Returns undefined
|
|
100
|
+
* for an unknown or non-finite size: opencode then keeps its own default guess, which is the
|
|
101
|
+
* pre-fix behaviour; never invent a limit here.
|
|
102
|
+
*/
|
|
103
|
+
function opencodeModelLimit(contextLength) {
|
|
104
|
+
if (contextLength === undefined || !Number.isFinite(contextLength))
|
|
105
|
+
return undefined;
|
|
106
|
+
const total = Math.trunc(contextLength);
|
|
107
|
+
if (total <= 0)
|
|
108
|
+
return undefined;
|
|
109
|
+
const output = Math.max(1, Math.min(8192, Math.floor(total / 4)));
|
|
110
|
+
// `limit.context` is the FULL window as far as opencode is concerned: it reserves for
|
|
111
|
+
// the reply itself, so the discovered total is passed through, never a shrunk figure.
|
|
112
|
+
return { context: total, output };
|
|
113
|
+
}
|
|
114
|
+
function renderConfigContent(template, endpoint, modelId, apiKey, contextLength) {
|
|
90
115
|
switch (template) {
|
|
91
|
-
case 'opencode-json':
|
|
116
|
+
case 'opencode-json': {
|
|
117
|
+
// `limit` carries the discovered context window (issue #749): without it opencode assumes
|
|
118
|
+
// a large default window for an unrecognized model id and eventually overflows a much
|
|
119
|
+
// smaller local server. `context` is the FULL window and opencode reserves for the reply
|
|
120
|
+
// inside it itself, so `opencodeModelLimit` passes the real total through and only
|
|
121
|
+
// `output` gets the capped reservation.
|
|
122
|
+
const limit = opencodeModelLimit(contextLength);
|
|
92
123
|
return JSON.stringify({
|
|
93
124
|
$schema: 'https://opencode.ai/config.json',
|
|
94
125
|
provider: {
|
|
95
126
|
custom: {
|
|
96
127
|
options: { baseURL: withV1Suffix(endpoint.baseUrl), apiKey },
|
|
97
|
-
models: { [modelId]: {} },
|
|
128
|
+
models: { [modelId]: limit ? { limit } : {} },
|
|
98
129
|
},
|
|
99
130
|
},
|
|
100
131
|
model: `custom/${modelId}`,
|
|
101
132
|
});
|
|
133
|
+
}
|
|
102
134
|
}
|
|
103
135
|
}
|
|
104
|
-
|
|
136
|
+
/** The DEDICATED env var carrying a custom endpoint's API key for config-file recipes that
|
|
137
|
+
* reference keys by name (codex's `env_key`, deepseek's `apiKeyEnv`). Never a CLI-native
|
|
138
|
+
* name: dsh's own `llm-deepseek`/`web-search-deepseek` rows read `DEEPSEEK_API_KEY` too,
|
|
139
|
+
* so an in-session `/model` switch back to `deepseek-official` (or a profile with web
|
|
140
|
+
* search on) would otherwise send the custom endpoint's key to api.deepseek.com. Both
|
|
141
|
+
* entries list it in `privilegedEnvKeys` (stock.ts) like each other's redirect vars.
|
|
142
|
+
*/
|
|
143
|
+
const CUSTOM_MODEL_API_KEY_ENV_VAR = 'CODEMAN_CUSTOM_MODEL_API_KEY';
|
|
105
144
|
/** The `[model.<name>]` block name grok's config.toml uses for the injected model — also
|
|
106
145
|
* what `-m <name>` in the standalone script's ONE_SHOT argv must reference to select it. */
|
|
107
146
|
export const GROK_CUSTOM_MODEL_NAME = 'codeman-custom';
|
|
108
|
-
function renderConfigFile(template, endpoint, modelId, apiKey) {
|
|
147
|
+
function renderConfigFile(template, endpoint, modelId, apiKey, contextLength) {
|
|
109
148
|
const baseUrl = withV1Suffix(endpoint.baseUrl);
|
|
110
149
|
switch (template) {
|
|
150
|
+
case 'deepseek-patch-json': {
|
|
151
|
+
const route = { provider: 'codeman-custom', model: modelId };
|
|
152
|
+
return {
|
|
153
|
+
content: JSON.stringify([
|
|
154
|
+
{
|
|
155
|
+
id: 'llm-pi-ai',
|
|
156
|
+
name: '@deepseek-ai/dsh-llm-pi-ai',
|
|
157
|
+
config: {
|
|
158
|
+
providers: {
|
|
159
|
+
'codeman-custom': {
|
|
160
|
+
// By NAME only (never the literal key, see CUSTOM_MODEL_API_KEY_ENV_VAR).
|
|
161
|
+
apiKeyEnv: CUSTOM_MODEL_API_KEY_ENV_VAR,
|
|
162
|
+
api: 'openai-completions',
|
|
163
|
+
baseURL: baseUrl,
|
|
164
|
+
models: [
|
|
165
|
+
{
|
|
166
|
+
id: modelId,
|
|
167
|
+
name: modelId,
|
|
168
|
+
...(contextLength !== undefined && Number.isFinite(contextLength) && contextLength > 0
|
|
169
|
+
? {
|
|
170
|
+
contextWindow: Math.trunc(contextLength),
|
|
171
|
+
// A quarter of the window keeps the reply inside the prompt's share; 8192 caps it on a large window.
|
|
172
|
+
maxTokens: Math.max(1, Math.min(8192, Math.floor(contextLength / 4))),
|
|
173
|
+
}
|
|
174
|
+
: {}),
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
{ id: 'dsh-tui', name: '@deepseek-harness-tui/dsh-tui', config: route },
|
|
182
|
+
{ id: 'agent-default-model', name: '@deepseek-ai/dsh-agent-default-model', config: route },
|
|
183
|
+
], null, 2),
|
|
184
|
+
extraEnv: { [CUSTOM_MODEL_API_KEY_ENV_VAR]: apiKey },
|
|
185
|
+
};
|
|
186
|
+
}
|
|
111
187
|
case 'codex-toml': {
|
|
112
188
|
// Verified against real codex (>= Feb 2026): `model` is a top-level STRING, never
|
|
113
189
|
// a `[model].default` table — codex rejects that with "invalid type: map, expected
|
|
@@ -126,15 +202,21 @@ function renderConfigFile(template, endpoint, modelId, apiKey) {
|
|
|
126
202
|
const content = [
|
|
127
203
|
`model = ${quoted(modelId)}`,
|
|
128
204
|
`model_provider = "custom"`,
|
|
205
|
+
...(contextLength !== undefined && Number.isFinite(contextLength) && contextLength > 0
|
|
206
|
+
? [
|
|
207
|
+
`model_context_window = ${Math.trunc(contextLength)}`,
|
|
208
|
+
`model_auto_compact_token_limit = ${Math.max(1, Math.floor(contextLength * 0.75))}`,
|
|
209
|
+
]
|
|
210
|
+
: []),
|
|
129
211
|
'',
|
|
130
212
|
'[model_providers.custom]',
|
|
131
213
|
`name = "Custom Endpoint"`,
|
|
132
214
|
`base_url = ${quoted(baseUrl)}`,
|
|
133
|
-
`env_key = ${quoted(
|
|
215
|
+
`env_key = ${quoted(CUSTOM_MODEL_API_KEY_ENV_VAR)}`,
|
|
134
216
|
`wire_api = "responses"`,
|
|
135
217
|
'',
|
|
136
218
|
].join('\n');
|
|
137
|
-
return { content, extraEnv: { [
|
|
219
|
+
return { content, extraEnv: { [CUSTOM_MODEL_API_KEY_ENV_VAR]: apiKey } };
|
|
138
220
|
}
|
|
139
221
|
case 'pi-models-json':
|
|
140
222
|
// Verified against pi's OWN bundled docs (models.md): `models` is an ARRAY of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-model-injection.js","sourceRoot":"","sources":["../src/custom-model-injection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;
|
|
1
|
+
{"version":3,"file":"custom-model-injection.js","sourceRoot":"","sources":["../src/custom-model-injection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Two-way Discord bridge: one thread per tab, alerts out, replies typed back in.
|
|
3
|
+
*
|
|
4
|
+
* Split like webhook-notify.ts, so the parts that matter are testable without a network:
|
|
5
|
+
* - pure: `sanitiseReply`, `threadNameFor`, `buildPost`, `discordConfigProblem`, `maskToken`
|
|
6
|
+
* - store: `~/.codeman/discord.json` (bot token, 0600 via tmp+rename) and
|
|
7
|
+
* `~/.codeman/discord-bridge.json` (sessionId -> threadId, not secret)
|
|
8
|
+
* - IO: `DiscordApi` (REST, injected fetch), `DiscordGateway` (inbound WebSocket, injected
|
|
9
|
+
* socket factory) and `DiscordBridge` (the rules that tie them to sessions)
|
|
10
|
+
*
|
|
11
|
+
* Rules the code keeps and the tests pin:
|
|
12
|
+
* - The bot token lives only in `discord.json`; it is never returned, logged, or put in an error.
|
|
13
|
+
* - Only messages from `allowedUserIds`, in `guildId`, inside a thread this bridge created, are
|
|
14
|
+
* acted on. Everything else is dropped without being read further.
|
|
15
|
+
* - A reply becomes one printable line plus Enter. Embedded newlines would submit early. A lone digit
|
|
16
|
+
* while a permission or question is pending goes as the key alone (see onGatewayMessage).
|
|
17
|
+
* - Posts never ping unless `pingMode` says so, and then only the allowlisted user ids.
|
|
18
|
+
* - A Discord outage or a bad token never reaches a session: every IO path catches and backs off.
|
|
19
|
+
*
|
|
20
|
+
* @module discord-bridge
|
|
21
|
+
*/
|
|
22
|
+
import { type WebhookUrgency } from './types/push.js';
|
|
23
|
+
import { type DiscordConfig, type DiscordGatewayState, type DiscordPingMode, type DiscordResult } from './types/discord.js';
|
|
24
|
+
/** Longest reply typed into a session; Discord allows 2000, a CLI prompt rarely needs more than this. */
|
|
25
|
+
export declare const MAX_REPLY_CHARS = 1000;
|
|
26
|
+
export declare const DEFAULT_DISCORD_CONFIG: DiscordConfig;
|
|
27
|
+
export interface DiscordMessage {
|
|
28
|
+
event: string;
|
|
29
|
+
title: string;
|
|
30
|
+
body: string;
|
|
31
|
+
urgency: WebhookUrgency;
|
|
32
|
+
sessionId?: string;
|
|
33
|
+
sessionName?: string;
|
|
34
|
+
/** The tail of what the CLI last printed, so the reader can see what it is asking. */
|
|
35
|
+
tail?: string | (() => string);
|
|
36
|
+
/**
|
|
37
|
+
* The CLI's whole last message, read from its transcript. When it yields text the post carries that
|
|
38
|
+
* (split over as many posts as it needs, markdown kept) instead of the screen tail.
|
|
39
|
+
*/
|
|
40
|
+
fullText?: () => Promise<{
|
|
41
|
+
text: string;
|
|
42
|
+
version?: string;
|
|
43
|
+
} | undefined>;
|
|
44
|
+
host?: string;
|
|
45
|
+
/** A file to upload with the post (already read and size-checked by the caller). */
|
|
46
|
+
file?: DiscordFile;
|
|
47
|
+
}
|
|
48
|
+
export interface DiscordFile {
|
|
49
|
+
name: string;
|
|
50
|
+
data: Uint8Array;
|
|
51
|
+
}
|
|
52
|
+
/** Why `cfg` cannot be saved as an enabled config, or null. */
|
|
53
|
+
export declare function discordConfigProblem(cfg: DiscordConfig): string | null;
|
|
54
|
+
/** First four and last two characters, so the user can tell which token is saved. */
|
|
55
|
+
export declare function maskToken(token: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* A Discord reply as one printable line plus Enter, or null when nothing printable is left. The caller
|
|
58
|
+
* drops the Enter for a lone digit answering a pending dialog.
|
|
59
|
+
*/
|
|
60
|
+
export declare function sanitiseReply(raw: string, files?: string[]): string | null;
|
|
61
|
+
export declare function threadNameFor(sessionName: string | undefined, sessionId: string): string;
|
|
62
|
+
/** Whether `urgency` earns a ping under `mode`. */
|
|
63
|
+
export declare function shouldPing(mode: DiscordPingMode, urgency: WebhookUrgency, explicitUrgent?: boolean): boolean;
|
|
64
|
+
export declare function shouldSendDiscord(cfg: DiscordConfig, urgency: WebhookUrgency): boolean;
|
|
65
|
+
/** Largest single file taken from Discord, or sent to it. Discord's own free limit is higher. */
|
|
66
|
+
export declare const MAX_FILE_BYTES: number;
|
|
67
|
+
/** Where a session's received files go, relative to its working folder. */
|
|
68
|
+
export declare const RECEIVED_DIR = ".codeman-discord";
|
|
69
|
+
/**
|
|
70
|
+
* What a session is told about the bridge. Claude gets it as `--append-system-prompt`; no other CLI
|
|
71
|
+
* is told. No apostrophes: it is rendered into a shell command.
|
|
72
|
+
*/
|
|
73
|
+
export declare const DISCORD_STARTUP_HINT: string;
|
|
74
|
+
/** The hint to launch Claude with, or undefined while the bridge or the setting is off. */
|
|
75
|
+
export declare function getDiscordStartupHint(): string | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* The last lines of a rendered screen for a post: colour and charset codes removed, blank lines and
|
|
78
|
+
* pure rule lines (box drawing, dashes) dropped, the last 14 lines, at most 900 characters, cut on a line.
|
|
79
|
+
* With `composerGlyph` (the CLI's own prompt mark), the composer row and everything under it (the status
|
|
80
|
+
* and mode hints) is cut first, but only within the last 8 rows and never a dialog's selected option
|
|
81
|
+
* (`❯ 1. Yes`), so a question's choices stay.
|
|
82
|
+
*/
|
|
83
|
+
export declare function screenTail(screen: string, maxLines?: number, maxChars?: number, composerGlyph?: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Discord does not render Markdown tables: a `| a | b |` block shows as raw pipes. Each table outside a
|
|
86
|
+
* code fence becomes a code block with the columns padded to their widest cell (right-aligned where the
|
|
87
|
+
* separator row says `---:`), which a monospace font lines up. Bold and code marks inside a cell are
|
|
88
|
+
* dropped, since a code block would show them literally.
|
|
89
|
+
*/
|
|
90
|
+
export declare function tablesToCodeBlocks(text: string): string;
|
|
91
|
+
/**
|
|
92
|
+
* Split a long message into posts of at most `max` characters, on blank lines first, then lines, then
|
|
93
|
+
* (for one huge line) by length. A code fence the cut lands inside is closed and reopened, so each post
|
|
94
|
+
* renders on its own. At most `maxPosts`; the last carries a note when text is left over.
|
|
95
|
+
*/
|
|
96
|
+
export declare function splitForDiscord(text: string, max?: number, maxPosts?: number): string[];
|
|
97
|
+
/** Final path segment only, `[A-Za-z0-9._-]`, no leading dot, at most 80 characters. */
|
|
98
|
+
export declare function safeAttachmentName(name: string): string;
|
|
99
|
+
/** Discord's own CDN over https: the only place an attachment URL may point. */
|
|
100
|
+
export declare function isDiscordCdnUrl(raw: string): boolean;
|
|
101
|
+
export interface DiscordPost {
|
|
102
|
+
content: string;
|
|
103
|
+
allowed_mentions: {
|
|
104
|
+
parse: string[];
|
|
105
|
+
users: string[];
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export declare function buildPost(msg: DiscordMessage, cfg: DiscordConfig, explicitUrgent?: boolean): DiscordPost;
|
|
109
|
+
export declare function discordConfigPath(configDir: string): string;
|
|
110
|
+
export declare function readDiscordConfig(configDir: string): Promise<DiscordConfig>;
|
|
111
|
+
/** 0600 via tmp+rename: `mode` on writeFile only applies to a file being created. */
|
|
112
|
+
export declare function writeDiscordConfig(configDir: string, cfg: DiscordConfig): Promise<void>;
|
|
113
|
+
export declare function readThreadMap(configDir: string): Promise<Record<string, string>>;
|
|
114
|
+
export interface DiscordThreadInfo {
|
|
115
|
+
id: string;
|
|
116
|
+
parent_id?: string;
|
|
117
|
+
owner_id?: string;
|
|
118
|
+
thread_metadata?: {
|
|
119
|
+
archived?: boolean;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export type DiscordFetch = (target: URL, init: RequestInit) => Promise<Response>;
|
|
123
|
+
export declare class DiscordHttpError extends Error {
|
|
124
|
+
readonly status: number;
|
|
125
|
+
/** Discord's own error code (10003 unknown channel, 50001 missing access ...). */
|
|
126
|
+
readonly code?: number | undefined;
|
|
127
|
+
constructor(status: number,
|
|
128
|
+
/** Discord's own error code (10003 unknown channel, 50001 missing access ...). */
|
|
129
|
+
code?: number | undefined);
|
|
130
|
+
}
|
|
131
|
+
/** Thin REST client. The token goes only in the Authorization header and never into a message. */
|
|
132
|
+
export declare class DiscordApi {
|
|
133
|
+
private readonly token;
|
|
134
|
+
private readonly fetchImpl;
|
|
135
|
+
private readonly sleep;
|
|
136
|
+
constructor(token: () => string, fetchImpl: DiscordFetch, sleep?: (ms: number) => Promise<void>);
|
|
137
|
+
request<T = unknown>(method: string, path: string, body?: unknown, retried?: boolean): Promise<T | null>;
|
|
138
|
+
createThread(parentId: string, name: string): Promise<{
|
|
139
|
+
id: string;
|
|
140
|
+
} | null>;
|
|
141
|
+
post(channelId: string, p: DiscordPost): Promise<{
|
|
142
|
+
id: string;
|
|
143
|
+
} | null>;
|
|
144
|
+
postWithFile(channelId: string, p: DiscordPost, file: DiscordFile): Promise<{
|
|
145
|
+
id: string;
|
|
146
|
+
} | null>;
|
|
147
|
+
rename(threadId: string, name: string): Promise<unknown>;
|
|
148
|
+
archive(threadId: string): Promise<unknown>;
|
|
149
|
+
remove(threadId: string): Promise<unknown>;
|
|
150
|
+
botUserId(): Promise<{
|
|
151
|
+
id: string;
|
|
152
|
+
} | null>;
|
|
153
|
+
/** Active threads of the guild (all channels: the caller filters by parent). */
|
|
154
|
+
activeThreads(guildId: string): Promise<{
|
|
155
|
+
threads: DiscordThreadInfo[];
|
|
156
|
+
} | null>;
|
|
157
|
+
/** The most recent archived public threads of a channel (one page). */
|
|
158
|
+
archivedThreads(parentId: string): Promise<{
|
|
159
|
+
threads: DiscordThreadInfo[];
|
|
160
|
+
} | null>;
|
|
161
|
+
react(channelId: string, messageId: string, emoji: string): Promise<unknown>;
|
|
162
|
+
}
|
|
163
|
+
export interface GatewayMessage {
|
|
164
|
+
id: string;
|
|
165
|
+
channel_id: string;
|
|
166
|
+
guild_id?: string;
|
|
167
|
+
content: string;
|
|
168
|
+
author: {
|
|
169
|
+
id: string;
|
|
170
|
+
bot?: boolean;
|
|
171
|
+
};
|
|
172
|
+
attachments?: Array<{
|
|
173
|
+
id: string;
|
|
174
|
+
filename: string;
|
|
175
|
+
size: number;
|
|
176
|
+
url: string;
|
|
177
|
+
}>;
|
|
178
|
+
}
|
|
179
|
+
/** The subset of `ws` the gateway uses, so tests can drive it without a socket. */
|
|
180
|
+
export interface GatewaySocket {
|
|
181
|
+
send(data: string): void;
|
|
182
|
+
close(code?: number): void;
|
|
183
|
+
on(event: 'message', cb: (data: {
|
|
184
|
+
toString(): string;
|
|
185
|
+
}) => void): void;
|
|
186
|
+
on(event: 'close', cb: (code: number) => void): void;
|
|
187
|
+
on(event: 'error', cb: (err: Error) => void): void;
|
|
188
|
+
}
|
|
189
|
+
export type SocketFactory = (url: string) => GatewaySocket;
|
|
190
|
+
/**
|
|
191
|
+
* Inbound half: identify, heartbeat, resume and reconnect with backoff. Only MESSAGE_CREATE is
|
|
192
|
+
* surfaced. A close code that retrying cannot fix (bad token, intent not enabled) stops it and
|
|
193
|
+
* records `lastError` for the Settings status line.
|
|
194
|
+
*/
|
|
195
|
+
export declare class DiscordGateway {
|
|
196
|
+
private readonly token;
|
|
197
|
+
private readonly onMessage;
|
|
198
|
+
private readonly socketFactory;
|
|
199
|
+
private readonly backoffMs;
|
|
200
|
+
state: DiscordGatewayState;
|
|
201
|
+
lastError: string | null;
|
|
202
|
+
private sock;
|
|
203
|
+
private seq;
|
|
204
|
+
private sessionId;
|
|
205
|
+
private resumeUrl;
|
|
206
|
+
private hb;
|
|
207
|
+
private retry;
|
|
208
|
+
private acked;
|
|
209
|
+
private attempts;
|
|
210
|
+
private stopped;
|
|
211
|
+
constructor(token: () => string, onMessage: (m: GatewayMessage) => void, socketFactory?: SocketFactory, backoffMs?: (attempt: number) => number);
|
|
212
|
+
start(): void;
|
|
213
|
+
stop(): void;
|
|
214
|
+
private clearTimers;
|
|
215
|
+
private connect;
|
|
216
|
+
private scheduleReconnect;
|
|
217
|
+
private handle;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Create or re-verify `<workingDir>/.codeman-discord`, or null when it is not safe to write there.
|
|
221
|
+
* Same safeguards as the prompt uploads folder: the workspace is probed with the bounded probe before
|
|
222
|
+
* the first disk touch (a dead mount must not hang the event loop), a symlink or a non-directory at
|
|
223
|
+
* the folder is refused (an agent could plant `.codeman-discord -> ~/.ssh`), and the folder ignores
|
|
224
|
+
* itself with a `.gitignore` of `*`, written once with O_EXCL so an `git add -A` never commits what was
|
|
225
|
+
* sent and a file already there stays the user's.
|
|
226
|
+
*/
|
|
227
|
+
export declare function ensureReceivedDir(workingDir: string): Promise<string | null>;
|
|
228
|
+
export interface DiscordBridgeDeps {
|
|
229
|
+
configDir: string;
|
|
230
|
+
fetchImpl: DiscordFetch;
|
|
231
|
+
/**
|
|
232
|
+
* Types a person's Discord reply into the session (a line ending in Enter, or a lone digit for a
|
|
233
|
+
* dialog). False when the session is gone.
|
|
234
|
+
*/
|
|
235
|
+
sendInput: (sessionId: string, text: string) => Promise<boolean>;
|
|
236
|
+
/** True once the tab's agent has exited: tmux still accepts keys for a dead pane, so a tick would lie. */
|
|
237
|
+
agentExited?: (sessionId: string) => boolean;
|
|
238
|
+
/** True while the session shows a permission or question dialog, which acts on a bare keypress. */
|
|
239
|
+
awaitingChoice?: (sessionId: string) => boolean;
|
|
240
|
+
/** A session's working folder, where received files are saved. Undefined when it is gone or remote. */
|
|
241
|
+
sessionDir?: (sessionId: string) => string | undefined;
|
|
242
|
+
socketFactory?: SocketFactory;
|
|
243
|
+
now?: () => number;
|
|
244
|
+
sleep?: (ms: number) => Promise<void>;
|
|
245
|
+
backoffMs?: (attempt: number) => number;
|
|
246
|
+
}
|
|
247
|
+
export declare class DiscordBridge {
|
|
248
|
+
private readonly deps;
|
|
249
|
+
private cfg;
|
|
250
|
+
private threads;
|
|
251
|
+
private loaded;
|
|
252
|
+
private gateway;
|
|
253
|
+
/** The token the running gateway was started with ('' when none). */
|
|
254
|
+
private gatewayToken;
|
|
255
|
+
private lastSent;
|
|
256
|
+
private lastReply;
|
|
257
|
+
/** The last name seen per session, so only a real rename touches the thread. */
|
|
258
|
+
private names;
|
|
259
|
+
private pending;
|
|
260
|
+
/** Tabs closed while their thread was still being created: the creation applies `onSessionDelete` to it. */
|
|
261
|
+
private closedWhilePending;
|
|
262
|
+
/** The last whole message posted per tab, so the same text is not posted twice (idle, then stop). */
|
|
263
|
+
private lastFull;
|
|
264
|
+
/** The parent channel the thread map was built under. */
|
|
265
|
+
private threadsParent;
|
|
266
|
+
/** True from boot until the restored tabs exist (see hold). */
|
|
267
|
+
private held;
|
|
268
|
+
/** Thread-map writes run one after another: concurrent creations must not interleave on the tmp file. */
|
|
269
|
+
private persistChain;
|
|
270
|
+
/** Per-thread chain of inbound messages (see onGatewayMessage). */
|
|
271
|
+
private inbound;
|
|
272
|
+
private mapLoad?;
|
|
273
|
+
private sweepTimer?;
|
|
274
|
+
/** The first full load (config, thread map, gateway), shared by every caller that arrives before it ends. */
|
|
275
|
+
private firstLoad?;
|
|
276
|
+
private last;
|
|
277
|
+
private readonly api;
|
|
278
|
+
private readonly now;
|
|
279
|
+
constructor(deps: DiscordBridgeDeps);
|
|
280
|
+
get lastResult(): DiscordResult | null;
|
|
281
|
+
get gatewayState(): DiscordGatewayState;
|
|
282
|
+
get gatewayError(): string | null;
|
|
283
|
+
ensureLoaded(): Promise<void>;
|
|
284
|
+
/** Forget thread entries for tabs that no longer exist (dropped without a delete, for example). Once, at boot. */
|
|
285
|
+
prune(liveIds: Iterable<string>): Promise<void>;
|
|
286
|
+
/**
|
|
287
|
+
* Close threads in the parent channel that this bot made and no tab maps to (`staleThreads`). Runs after
|
|
288
|
+
* the boot prune, then daily. Never touches a thread someone else made (owner is the bot), a young one
|
|
289
|
+
* (its map entry may not be written yet), or anything while the map is empty (a lost map would make
|
|
290
|
+
* every thread look stale). Returns how many it archived or deleted. Never throws.
|
|
291
|
+
*/
|
|
292
|
+
sweepStaleThreads(): Promise<number>;
|
|
293
|
+
/** Sweep now, then daily. The timer does not keep the process alive and `stop()` clears it. */
|
|
294
|
+
startStaleSweep(): void;
|
|
295
|
+
/** Hold the gateway back (boot): a reply must not arrive before the restored tabs exist. */
|
|
296
|
+
hold(): void;
|
|
297
|
+
/** Boot is done: start the gateway if the bridge is on. */
|
|
298
|
+
release(): Promise<void>;
|
|
299
|
+
/** (Re)read the config and start or stop the gateway to match. Call at boot and after a save. */
|
|
300
|
+
reload(): Promise<void>;
|
|
301
|
+
stop(): void;
|
|
302
|
+
private fail;
|
|
303
|
+
private persistThreads;
|
|
304
|
+
/** The thread for a session, creating it when absent. Concurrent callers share one creation. */
|
|
305
|
+
private threadFor;
|
|
306
|
+
/** Post an alert. Session-less messages go to the parent channel. Never throws. */
|
|
307
|
+
notify(msg: DiscordMessage, opts?: {
|
|
308
|
+
urgent?: boolean;
|
|
309
|
+
deliberate?: boolean;
|
|
310
|
+
}): Promise<DiscordResult | null>;
|
|
311
|
+
/** A deliberate test send to the parent channel: bypasses `enabled`, scope and dedupe. */
|
|
312
|
+
sendTest(cfg: DiscordConfig, host?: string): Promise<DiscordResult>;
|
|
313
|
+
/** Session tab created: make its thread now when `threadCreation` is `onSessionStart`. */
|
|
314
|
+
sessionCreated(sessionId: string, name: string | undefined): Promise<void>;
|
|
315
|
+
sessionRenamed(sessionId: string, name: string | undefined): Promise<void>;
|
|
316
|
+
/**
|
|
317
|
+
* Drop the per-tab state only, keeping the thread and its map entry. For a session that is discarded
|
|
318
|
+
* but can come back under the same id (a failed reboot-restore rebuild stays on offer for a retry).
|
|
319
|
+
* Per-tab state goes whether or not the tab ever had a thread, so these maps cannot grow for the life of the server.
|
|
320
|
+
*/
|
|
321
|
+
forgetTab(sessionId: string): void;
|
|
322
|
+
/** Session tab deleted: apply `onSessionDelete` and forget the mapping. */
|
|
323
|
+
sessionDeleted(sessionId: string): Promise<void>;
|
|
324
|
+
/** Apply `onSessionDelete` to a thread. */
|
|
325
|
+
private closeThread;
|
|
326
|
+
private say;
|
|
327
|
+
/**
|
|
328
|
+
* Save a reply's attachments under the session's working folder and return the paths. Only Discord
|
|
329
|
+
* CDN URLs, at most 5 files of 8 MB each, names reduced to safe characters. Anything skipped is
|
|
330
|
+
* named in `refused`, so the person is not left guessing why a file did not arrive.
|
|
331
|
+
*/
|
|
332
|
+
private saveAttachments;
|
|
333
|
+
/** Inbound reply. One chain per thread, so a reply that waits on a file download cannot be overtaken by a later one. */
|
|
334
|
+
onGatewayMessage(m: GatewayMessage): Promise<void>;
|
|
335
|
+
/** Every gate here drops silently: a stranger learns nothing. */
|
|
336
|
+
private handleMessage;
|
|
337
|
+
}
|
|
338
|
+
//# sourceMappingURL=discord-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord-bridge.d.ts","sourceRoot":"","sources":["../src/discord-bridge.ts"],"names":[],"mappings":"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"}
|