borgmcp 1.1.14 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +15 -0
- package/LICENSE +201 -33
- package/NOTICE +2 -0
- package/README.md +86 -37
- package/SECURITY.md +7 -0
- package/dist/agent-runtime.d.ts.map +1 -0
- package/dist/agent-runtime.js +63 -1
- package/dist/agent-runtime.js.map +1 -0
- package/dist/assimilate-cmd.d.ts +96 -17
- package/dist/assimilate-cmd.d.ts.map +1 -0
- package/dist/assimilate-cmd.js +1396 -48
- package/dist/assimilate-cmd.js.map +1 -0
- package/dist/assimilate-deps.d.ts.map +1 -0
- package/dist/assimilate-deps.js +384 -3
- package/dist/assimilate-deps.js.map +1 -0
- package/dist/assimilate-guard.d.ts +5 -7
- package/dist/assimilate-guard.d.ts.map +1 -0
- package/dist/assimilate-guard.js +60 -2
- package/dist/assimilate-guard.js.map +1 -0
- package/dist/assimilate-welcome.d.ts +1 -1
- package/dist/assimilate-welcome.d.ts.map +1 -0
- package/dist/assimilate-welcome.js +32 -2
- package/dist/assimilate-welcome.js.map +1 -0
- package/dist/auth-env.d.ts +7 -50
- package/dist/auth-env.d.ts.map +1 -0
- package/dist/auth-env.js +22 -1
- package/dist/auth-env.js.map +1 -0
- package/dist/backends/launch-all-pastelist.d.ts.map +1 -0
- package/dist/backends/launch-all-pastelist.js +11 -4
- package/dist/backends/launch-all-pastelist.js.map +1 -0
- package/dist/backends/launch-all-tmux.d.ts.map +1 -0
- package/dist/backends/launch-all-tmux.js +49 -1
- package/dist/backends/launch-all-tmux.js.map +1 -0
- package/dist/backends/launch-all-windows.d.ts.map +1 -0
- package/dist/backends/launch-all-windows.js +86 -12
- package/dist/backends/launch-all-windows.js.map +1 -0
- package/dist/bare-launch-menu.d.ts.map +1 -0
- package/dist/bare-launch-menu.js +83 -6
- package/dist/bare-launch-menu.js.map +1 -0
- package/dist/claude-launch-args.d.ts.map +1 -0
- package/dist/claude-launch-args.js +34 -1
- package/dist/claude-launch-args.js.map +1 -0
- package/dist/claude.d.ts.map +1 -0
- package/dist/claude.js +486 -14
- package/dist/claude.js.map +1 -0
- package/dist/cleanup-cmd.d.ts +5 -5
- package/dist/cleanup-cmd.d.ts.map +1 -0
- package/dist/cleanup-cmd.js +453 -14
- package/dist/cleanup-cmd.js.map +1 -0
- package/dist/clear-rewake-core.d.ts.map +1 -0
- package/dist/clear-rewake-core.js +23 -2
- package/dist/clear-rewake-core.js.map +1 -0
- package/dist/clear-rewake.d.ts.map +1 -0
- package/dist/clear-rewake.js +19 -1
- package/dist/clear-rewake.js.map +1 -0
- package/dist/cli-help.d.ts +5 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +104 -56
- package/dist/cli-help.js.map +1 -0
- package/dist/cli-platform.d.ts.map +1 -0
- package/dist/cli-platform.js +106 -4
- package/dist/cli-platform.js.map +1 -0
- package/dist/cli-tool-approval.d.ts +84 -0
- package/dist/cli-tool-approval.d.ts.map +1 -0
- package/dist/cli-tool-approval.js +583 -0
- package/dist/cli-tool-approval.js.map +1 -0
- package/dist/codex-app-server.d.ts.map +1 -0
- package/dist/codex-app-server.js +228 -4
- package/dist/codex-app-server.js.map +1 -0
- package/dist/codex-app-wake.d.ts.map +1 -0
- package/dist/codex-app-wake.js +432 -2
- package/dist/codex-app-wake.js.map +1 -0
- package/dist/codex-launch.d.ts.map +1 -0
- package/dist/codex-launch.js +102 -2
- package/dist/codex-launch.js.map +1 -0
- package/dist/codex-remote.d.ts +6 -1
- package/dist/codex-remote.d.ts.map +1 -0
- package/dist/codex-remote.js +394 -1
- package/dist/codex-remote.js.map +1 -0
- package/dist/codex-wake-resolve.d.ts.map +1 -0
- package/dist/codex-wake-resolve.js +127 -1
- package/dist/codex-wake-resolve.js.map +1 -0
- package/dist/config-utils.d.ts +2 -2
- package/dist/config-utils.d.ts.map +1 -0
- package/dist/config-utils.js +766 -3
- package/dist/config-utils.js.map +1 -0
- package/dist/config.d.ts +98 -61
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +426 -1
- package/dist/config.js.map +1 -0
- package/dist/console-prefix.d.ts.map +1 -0
- package/dist/console-prefix.js +96 -1
- package/dist/console-prefix.js.map +1 -0
- package/dist/cube-name.d.ts.map +1 -0
- package/dist/cube-name.js +67 -1
- package/dist/cube-name.js.map +1 -0
- package/dist/cubes.d.ts +126 -18
- package/dist/cubes.d.ts.map +1 -0
- package/dist/cubes.js +412 -4
- package/dist/cubes.js.map +1 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +71 -1
- package/dist/debug.js.map +1 -0
- package/dist/direct-log.d.ts.map +1 -0
- package/dist/direct-log.js +11 -1
- package/dist/direct-log.js.map +1 -0
- package/dist/docs-sections.d.ts +11 -10
- package/dist/docs-sections.d.ts.map +1 -0
- package/dist/docs-sections.js +113 -3
- package/dist/docs-sections.js.map +1 -0
- package/dist/drone-lifecycle.d.ts +5 -21
- package/dist/drone-lifecycle.d.ts.map +1 -0
- package/dist/drone-lifecycle.js +57 -8
- package/dist/drone-lifecycle.js.map +1 -0
- package/dist/drone-management.d.ts +29 -0
- package/dist/drone-management.d.ts.map +1 -0
- package/dist/drone-management.js +109 -0
- package/dist/drone-management.js.map +1 -0
- package/dist/ensure-mcp-config.d.ts.map +1 -0
- package/dist/ensure-mcp-config.js +36 -1
- package/dist/ensure-mcp-config.js.map +1 -0
- package/dist/evict-drone.d.ts +10 -2
- package/dist/evict-drone.d.ts.map +1 -0
- package/dist/evict-drone.js +60 -1
- package/dist/evict-drone.js.map +1 -0
- package/dist/gc-orphan-inboxes.d.ts.map +1 -0
- package/dist/gc-orphan-inboxes.js +177 -1
- package/dist/gc-orphan-inboxes.js.map +1 -0
- package/dist/inbox-monitor.d.ts +1 -1
- package/dist/inbox-monitor.d.ts.map +1 -0
- package/dist/inbox-monitor.js +856 -3
- package/dist/inbox-monitor.js.map +1 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1034 -37
- package/dist/index.js.map +1 -0
- package/dist/launch-all-cmd.d.ts.map +1 -0
- package/dist/launch-all-cmd.js +377 -37
- package/dist/launch-all-cmd.js.map +1 -0
- package/dist/launch-all-command.d.ts.map +1 -0
- package/dist/launch-all-command.js +24 -1
- package/dist/launch-all-command.js.map +1 -0
- package/dist/launch-all-deps.d.ts +3 -8
- package/dist/launch-all-deps.d.ts.map +1 -0
- package/dist/launch-all-deps.js +99 -1
- package/dist/launch-all-deps.js.map +1 -0
- package/dist/launch-all-discovery.d.ts +1 -0
- package/dist/launch-all-discovery.d.ts.map +1 -0
- package/dist/launch-all-discovery.js +90 -4
- package/dist/launch-all-discovery.js.map +1 -0
- package/dist/launch-all-locks.d.ts.map +1 -0
- package/dist/launch-all-locks.js +54 -1
- package/dist/launch-all-locks.js.map +1 -0
- package/dist/launch-gate.d.ts +2 -2
- package/dist/launch-gate.d.ts.map +1 -0
- package/dist/launch-gate.js +73 -1
- package/dist/launch-gate.js.map +1 -0
- package/dist/lifecycle-log-guard.d.ts.map +1 -0
- package/dist/lifecycle-log-guard.js +93 -2
- package/dist/lifecycle-log-guard.js.map +1 -0
- package/dist/list-roles-render.d.ts.map +1 -0
- package/dist/list-roles-render.js +40 -6
- package/dist/list-roles-render.js.map +1 -0
- package/dist/local-log-routing.d.ts +19 -0
- package/dist/local-log-routing.d.ts.map +1 -0
- package/dist/local-log-routing.js +67 -0
- package/dist/local-log-routing.js.map +1 -0
- package/dist/local-manage-tool-result.d.ts +8 -0
- package/dist/local-manage-tool-result.d.ts.map +1 -0
- package/dist/local-manage-tool-result.js +10 -0
- package/dist/local-manage-tool-result.js.map +1 -0
- package/dist/local-server-cursor.d.ts +34 -0
- package/dist/local-server-cursor.d.ts.map +1 -0
- package/dist/local-server-cursor.js +151 -0
- package/dist/local-server-cursor.js.map +1 -0
- package/dist/log-audit.d.ts.map +1 -0
- package/dist/log-audit.js +194 -3
- package/dist/log-audit.js.map +1 -0
- package/dist/log-stream.d.ts +31 -18
- package/dist/log-stream.d.ts.map +1 -0
- package/dist/log-stream.js +1214 -12
- package/dist/log-stream.js.map +1 -0
- package/dist/model-presets.d.ts.map +1 -0
- package/dist/model-presets.js +19 -1
- package/dist/model-presets.js.map +1 -0
- package/dist/name-validator.d.ts.map +1 -0
- package/dist/name-validator.js +22 -1
- package/dist/name-validator.js.map +1 -0
- package/dist/opencode-drone.d.ts.map +1 -0
- package/dist/opencode-drone.js +438 -4
- package/dist/opencode-drone.js.map +1 -0
- package/dist/opencode-plugin.d.ts +1 -1
- package/dist/opencode-plugin.d.ts.map +1 -0
- package/dist/opencode-plugin.js +29 -4
- package/dist/opencode-plugin.js.map +1 -0
- package/dist/parse-assimilate-args.d.ts +1 -1
- package/dist/parse-assimilate-args.d.ts.map +1 -0
- package/dist/parse-assimilate-args.js +125 -1
- package/dist/parse-assimilate-args.js.map +1 -0
- package/dist/parse-launch-all-args.d.ts.map +1 -0
- package/dist/parse-launch-all-args.js +70 -1
- package/dist/parse-launch-all-args.js.map +1 -0
- package/dist/postinstall-banner.d.ts.map +1 -0
- package/dist/postinstall-banner.js +27 -2
- package/dist/postinstall-banner.js.map +1 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +32 -5
- package/dist/postinstall.js.map +1 -0
- package/dist/readiness-probe.d.ts.map +1 -0
- package/dist/readiness-probe.js +9 -1
- package/dist/readiness-probe.js.map +1 -0
- package/dist/regen-format.d.ts.map +1 -0
- package/dist/regen-format.js +545 -13
- package/dist/regen-format.js.map +1 -0
- package/dist/regen.d.ts.map +1 -0
- package/dist/regen.js +141 -5
- package/dist/regen.js.map +1 -0
- package/dist/remote-client.d.ts +65 -175
- package/dist/remote-client.d.ts.map +1 -0
- package/dist/remote-client.js +942 -1
- package/dist/remote-client.js.map +1 -0
- package/dist/reset-local-seat-cmd.d.ts +50 -0
- package/dist/reset-local-seat-cmd.d.ts.map +1 -0
- package/dist/reset-local-seat-cmd.js +169 -0
- package/dist/reset-local-seat-cmd.js.map +1 -0
- package/dist/role-match.d.ts.map +1 -0
- package/dist/role-match.js +23 -1
- package/dist/role-match.js.map +1 -0
- package/dist/role-resolver.d.ts.map +1 -0
- package/dist/role-resolver.js +60 -1
- package/dist/role-resolver.js.map +1 -0
- package/dist/roster-render.d.ts.map +1 -0
- package/dist/roster-render.js +121 -3
- package/dist/roster-render.js.map +1 -0
- package/dist/seat-probe.d.ts +32 -13
- package/dist/seat-probe.d.ts.map +1 -0
- package/dist/seat-probe.js +78 -1
- package/dist/seat-probe.js.map +1 -0
- package/dist/seat-store.d.ts +76 -0
- package/dist/seat-store.d.ts.map +1 -0
- package/dist/seat-store.js +309 -0
- package/dist/seat-store.js.map +1 -0
- package/dist/seats.d.ts +303 -0
- package/dist/seats.d.ts.map +1 -0
- package/dist/seats.js +551 -0
- package/dist/seats.js.map +1 -0
- package/dist/self-path.d.ts +27 -0
- package/dist/self-path.d.ts.map +1 -0
- package/dist/self-path.js +43 -0
- package/dist/self-path.js.map +1 -0
- package/dist/server-endpoint.d.ts +9 -0
- package/dist/server-endpoint.d.ts.map +1 -0
- package/dist/server-endpoint.js +38 -0
- package/dist/server-endpoint.js.map +1 -0
- package/dist/server-errors.d.ts +50 -0
- package/dist/server-errors.d.ts.map +1 -0
- package/dist/server-errors.js +79 -0
- package/dist/server-errors.js.map +1 -0
- package/dist/server-handshake.d.ts +197 -0
- package/dist/server-handshake.d.ts.map +1 -0
- package/dist/server-handshake.js +505 -0
- package/dist/server-handshake.js.map +1 -0
- package/dist/server-response.d.ts +3 -0
- package/dist/server-response.d.ts.map +1 -0
- package/dist/server-response.js +67 -0
- package/dist/server-response.js.map +1 -0
- package/dist/server-trust.d.ts +14 -0
- package/dist/server-trust.d.ts.map +1 -0
- package/dist/server-trust.js +225 -0
- package/dist/server-trust.js.map +1 -0
- package/dist/setup-confirm.d.ts +3 -3
- package/dist/setup-confirm.d.ts.map +1 -0
- package/dist/setup-confirm.js +126 -2
- package/dist/setup-confirm.js.map +1 -0
- package/dist/setup.d.ts +5 -3
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +169 -46
- package/dist/setup.js.map +1 -0
- package/dist/shell-escape.d.ts.map +1 -0
- package/dist/shell-escape.js +22 -1
- package/dist/shell-escape.js.map +1 -0
- package/dist/spawn.d.ts +2 -2
- package/dist/spawn.d.ts.map +1 -0
- package/dist/spawn.js +29 -10
- package/dist/spawn.js.map +1 -0
- package/dist/startup-services.d.ts +0 -1
- package/dist/startup-services.d.ts.map +1 -0
- package/dist/startup-services.js +26 -1
- package/dist/startup-services.js.map +1 -0
- package/dist/stream-owner.d.ts +6 -2
- package/dist/stream-owner.d.ts.map +1 -0
- package/dist/stream-owner.js +547 -2
- package/dist/stream-owner.js.map +1 -0
- package/dist/stream-status.d.ts +1 -1
- package/dist/stream-status.d.ts.map +1 -0
- package/dist/stream-status.js +268 -3
- package/dist/stream-status.js.map +1 -0
- package/dist/sync-roles-render.d.ts.map +1 -0
- package/dist/sync-roles-render.js +118 -3
- package/dist/sync-roles-render.js.map +1 -0
- package/dist/sync.d.ts +1 -1
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +286 -22
- package/dist/sync.js.map +1 -0
- package/dist/terminal-title.d.ts.map +1 -0
- package/dist/terminal-title.js +68 -1
- package/dist/terminal-title.js.map +1 -0
- package/dist/token-store.d.ts +17 -111
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +81 -1
- package/dist/token-store.js.map +1 -0
- package/dist/tool-manifest.d.ts +4 -8
- package/dist/tool-manifest.d.ts.map +1 -0
- package/dist/tool-manifest.js +554 -1
- package/dist/tool-manifest.js.map +1 -0
- package/dist/tool-scope.d.ts +8 -12
- package/dist/tool-scope.d.ts.map +1 -0
- package/dist/tool-scope.js +97 -1
- package/dist/tool-scope.js.map +1 -0
- package/dist/types.d.ts +1 -5
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/unknown-subcommand.d.ts +1 -1
- package/dist/unknown-subcommand.d.ts.map +1 -0
- package/dist/unknown-subcommand.js +37 -1
- package/dist/unknown-subcommand.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +78 -2
- package/dist/version.js.map +1 -0
- package/dist/working-repo.d.ts.map +1 -0
- package/dist/working-repo.js +81 -1
- package/dist/working-repo.js.map +1 -0
- package/dist/worktree-lifecycle.d.ts.map +1 -0
- package/dist/worktree-lifecycle.js +205 -2
- package/dist/worktree-lifecycle.js.map +1 -0
- package/docs/EXTRACTION_PROVENANCE.md +40 -0
- package/docs/LOCAL_SERVER.md +103 -0
- package/docs/RELEASING.md +120 -0
- package/package.json +52 -34
- package/src/agent-runtime.ts +69 -0
- package/src/assimilate-cmd.ts +1864 -0
- package/src/assimilate-deps.ts +444 -0
- package/src/assimilate-guard.ts +84 -0
- package/src/assimilate-welcome.ts +39 -0
- package/src/auth-env.ts +21 -0
- package/src/backends/launch-all-pastelist.ts +18 -0
- package/src/backends/launch-all-tmux.ts +75 -0
- package/src/backends/launch-all-windows.ts +110 -0
- package/src/bare-launch-menu.ts +148 -0
- package/src/claude-launch-args.ts +35 -0
- package/src/claude.ts +561 -0
- package/src/cleanup-cmd.ts +581 -0
- package/src/clear-rewake-core.ts +34 -0
- package/src/clear-rewake.ts +18 -0
- package/src/cli-help.ts +116 -0
- package/src/cli-platform.ts +127 -0
- package/src/cli-tool-approval.ts +716 -0
- package/src/codex-app-server.ts +238 -0
- package/src/codex-app-wake.ts +512 -0
- package/src/codex-launch.ts +140 -0
- package/src/codex-remote.ts +500 -0
- package/src/codex-wake-resolve.ts +155 -0
- package/src/config-utils.ts +811 -0
- package/src/config.ts +595 -0
- package/src/console-prefix.ts +99 -0
- package/src/cube-name.ts +69 -0
- package/src/cubes.ts +583 -0
- package/src/debug.ts +73 -0
- package/src/direct-log.ts +9 -0
- package/src/docs-sections.ts +129 -0
- package/src/drone-lifecycle.ts +62 -0
- package/src/drone-management.ts +162 -0
- package/src/ensure-mcp-config.ts +54 -0
- package/src/evict-drone.ts +82 -0
- package/src/gc-orphan-inboxes.ts +229 -0
- package/src/inbox-monitor.ts +1005 -0
- package/src/index.ts +1201 -0
- package/src/launch-all-cmd.ts +450 -0
- package/src/launch-all-command.ts +30 -0
- package/src/launch-all-deps.ts +188 -0
- package/src/launch-all-discovery.ts +118 -0
- package/src/launch-all-locks.ts +74 -0
- package/src/launch-gate.ts +80 -0
- package/src/lifecycle-log-guard.ts +144 -0
- package/src/list-roles-render.ts +52 -0
- package/src/local-log-routing.ts +106 -0
- package/src/local-manage-tool-result.ts +10 -0
- package/src/local-server-cursor.ts +188 -0
- package/src/log-audit.ts +207 -0
- package/src/log-stream.ts +1505 -0
- package/src/model-presets.ts +22 -0
- package/src/name-validator.ts +23 -0
- package/src/opencode-drone.ts +528 -0
- package/src/opencode-plugin.ts +38 -0
- package/src/parse-assimilate-args.ts +125 -0
- package/src/parse-launch-all-args.ts +100 -0
- package/src/postinstall-banner.ts +37 -0
- package/src/postinstall.ts +36 -0
- package/src/readiness-probe.ts +12 -0
- package/src/regen-format.ts +651 -0
- package/src/regen.ts +150 -0
- package/src/remote-client.ts +1379 -0
- package/src/reset-local-seat-cmd.ts +227 -0
- package/src/role-match.ts +29 -0
- package/src/role-resolver.ts +93 -0
- package/src/roster-render.ts +196 -0
- package/src/seat-probe.ts +115 -0
- package/src/seat-store.ts +333 -0
- package/src/seats.ts +741 -0
- package/src/self-path.ts +51 -0
- package/src/server-endpoint.ts +38 -0
- package/src/server-errors.ts +93 -0
- package/src/server-handshake.ts +783 -0
- package/src/server-response.ts +76 -0
- package/src/server-trust.ts +245 -0
- package/src/setup-confirm.ts +171 -0
- package/src/setup.ts +186 -0
- package/src/shell-escape.ts +22 -0
- package/src/spawn.ts +31 -0
- package/src/startup-services.ts +36 -0
- package/src/stream-owner.ts +686 -0
- package/src/stream-status.ts +337 -0
- package/src/sync-roles-render.ts +163 -0
- package/src/sync.ts +363 -0
- package/src/terminal-title.ts +76 -0
- package/src/token-store.ts +102 -0
- package/src/tool-manifest.ts +610 -0
- package/src/tool-scope.ts +110 -0
- package/src/types.ts +5 -0
- package/src/unknown-subcommand.ts +35 -0
- package/src/version.ts +82 -0
- package/src/working-repo.ts +99 -0
- package/src/worktree-lifecycle.ts +254 -0
- package/dist/auth-recovery.d.ts +0 -33
- package/dist/auth-recovery.js +0 -1
- package/dist/auth.d.ts +0 -103
- package/dist/auth.js +0 -39
- package/dist/device-auth.d.ts +0 -75
- package/dist/device-auth.js +0 -1
- package/dist/drone-address.d.ts +0 -26
- package/dist/drone-address.js +0 -1
- package/dist/get-started.d.ts +0 -20
- package/dist/get-started.js +0 -2
- package/dist/health-beat.d.ts +0 -134
- package/dist/health-beat.js +0 -1
- package/dist/role-section.d.ts +0 -110
- package/dist/role-section.js +0 -8
- package/dist/setup-action.d.ts +0 -20
- package/dist/setup-action.js +0 -1
- package/dist/stale-version-check.d.ts +0 -40
- package/dist/stale-version-check.js +0 -1
- package/dist/subscription-retry.d.ts +0 -40
- package/dist/subscription-retry.js +0 -1
- package/dist/templates.d.ts +0 -107
- package/dist/templates.js +0 -359
- package/dist/token-crypto.d.ts +0 -50
- package/dist/token-crypto.js +0 -1
package/dist/auth.d.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google OAuth 2.0 Authorization Code Flow with PKCE
|
|
3
|
-
* For Desktop/CLI applications
|
|
4
|
-
*
|
|
5
|
-
* Flow:
|
|
6
|
-
* 1. Generate PKCE code_verifier and code_challenge
|
|
7
|
-
* 2. Start local HTTP server for callback
|
|
8
|
-
* 3. Open browser to Google authorization URL
|
|
9
|
-
* 4. User authorizes in browser
|
|
10
|
-
* 5. Receive authorization code via localhost callback
|
|
11
|
-
* 6. Exchange code for tokens
|
|
12
|
-
* 7. Store tokens securely in OS keychain
|
|
13
|
-
*/
|
|
14
|
-
import { type DeviceAuthConfig, type DeviceAuthDeps } from './device-auth.js';
|
|
15
|
-
/**
|
|
16
|
-
* Refresh-token-revoked / expired — the user must re-run `borg setup`
|
|
17
|
-
* to recover. Anchored on Google's canonical signal: HTTP 400 + JSON
|
|
18
|
-
* body `{"error": "invalid_grant", ...}` from the OAuth token
|
|
19
|
-
* endpoint. Callers should `clearTokens()` on this class only —
|
|
20
|
-
* preserving keychain state on the transient class.
|
|
21
|
-
*
|
|
22
|
-
* Constructor stores parsed `error` + `error_description` fields
|
|
23
|
-
* only — never the request body (which contains the refresh_token)
|
|
24
|
-
* or the raw response body verbatim (per drone-8 SR axis b on
|
|
25
|
-
* token-material non-leakage in error messages).
|
|
26
|
-
*/
|
|
27
|
-
export declare class RefreshTokenInvalidError extends Error {
|
|
28
|
-
readonly errorCode: string;
|
|
29
|
-
readonly errorDescription?: string | undefined;
|
|
30
|
-
constructor(errorCode: string, errorDescription?: string | undefined);
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Transient failure of the refresh path — network failure, Google
|
|
34
|
-
* 5xx, malformed response, non-`invalid_grant` 4xx, etc. The
|
|
35
|
-
* refresh_token in keychain is presumed still valid; callers MUST
|
|
36
|
-
* NOT `clearTokens()` on this class.
|
|
37
|
-
*
|
|
38
|
-
* The pre-gh#34 implementation classified all refresh failures
|
|
39
|
-
* uniformly and called `clearTokens()` unconditionally; a single
|
|
40
|
-
* transient blip would destroy the durable session. This typed
|
|
41
|
-
* class is the discrimination axis.
|
|
42
|
-
*/
|
|
43
|
-
export declare class RefreshTransientError extends Error {
|
|
44
|
-
constructor(message: string);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Decide whether to use the no-browser device-grant flow. An explicit
|
|
48
|
-
* `--no-browser`/`--device` (surfaced as opts.noBrowser) wins; otherwise
|
|
49
|
-
* auto-detect via isNoBrowserEnv (SSH session, container, headless Linux).
|
|
50
|
-
*/
|
|
51
|
-
export declare function shouldUseDeviceFlow(opts?: {
|
|
52
|
-
noBrowser?: boolean;
|
|
53
|
-
}): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Assemble the device-grant OAuth config from the environment. Enforces the
|
|
56
|
-
* gh#557 ESCALATION-1 gate: a "TVs & Limited Input devices" client id must be
|
|
57
|
-
* available (baked-in once the operator creates it, or via GOOGLE_DEVICE_CLIENT_ID).
|
|
58
|
-
* Without one we fail with an actionable error instead of hitting Google with
|
|
59
|
-
* the Desktop client, which rejects /device/code as invalid_client.
|
|
60
|
-
*/
|
|
61
|
-
export declare function buildDeviceAuthConfig(env?: NodeJS.ProcessEnv): DeviceAuthConfig;
|
|
62
|
-
/**
|
|
63
|
-
* The RFC 8628 device-grant flow (no browser). Prints a verification URL +
|
|
64
|
-
* user_code for the human to open on ANY device, polls Google until they
|
|
65
|
-
* authorize, then stores tokens in the selected backend. Network deps are
|
|
66
|
-
* injectable for tests; the device-poll state machine itself lives in
|
|
67
|
-
* device-auth.ts (fully unit-tested).
|
|
68
|
-
*/
|
|
69
|
-
export declare function authenticateWithDeviceFlow(deps?: DeviceAuthDeps, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
70
|
-
/**
|
|
71
|
-
* Perform the complete OAuth flow, choosing the browser/loopback flow or the
|
|
72
|
-
* no-browser device-grant flow based on the environment (gh#557). Stores
|
|
73
|
-
* tokens in the selected backend on success.
|
|
74
|
-
*
|
|
75
|
-
* @param opts.noBrowser force the device flow (`--no-browser`/`--device`);
|
|
76
|
-
* when omitted, the environment is auto-detected.
|
|
77
|
-
*/
|
|
78
|
-
export declare function authenticateWithGoogle(opts?: {
|
|
79
|
-
noBrowser?: boolean;
|
|
80
|
-
}): Promise<void>;
|
|
81
|
-
/**
|
|
82
|
-
* Refresh the stored id_token, redeeming the refresh_token against the
|
|
83
|
-
* OAuth client that ISSUED it (gh#691).
|
|
84
|
-
*
|
|
85
|
-
* A refresh_token can only be redeemed by its issuing client. The browser
|
|
86
|
-
* flow issues tokens under the web client (GOOGLE_CLIENT_ID); the device
|
|
87
|
-
* flow (`borg setup --no-browser`, gh#557) issues them under the device
|
|
88
|
-
* client (buildDeviceAuthConfig). We don't persist which flow minted the
|
|
89
|
-
* stored token, so try the web client first, then the device client.
|
|
90
|
-
*
|
|
91
|
-
* Before this fix the refresh hard-coded the web client, so every
|
|
92
|
-
* device-flow user's silent refresh failed at id_token expiry — forcing a
|
|
93
|
-
* full re-auth (which revokes the working refresh_token to force fresh
|
|
94
|
-
* consent) on the next command. That was the friction in gh#691.
|
|
95
|
-
*
|
|
96
|
-
* Keychain safety: clear-on-revocation (RefreshTokenInvalidError, which
|
|
97
|
-
* callers gate `clearTokens()` on) is surfaced ONLY when BOTH clients
|
|
98
|
-
* reject the token with invalid_grant. Any inconclusive/transient outcome
|
|
99
|
-
* on either attempt preserves the keychain for retry — a wrong-client
|
|
100
|
-
* invalid_grant must not be mistaken for a genuine revocation.
|
|
101
|
-
*/
|
|
102
|
-
export declare function refreshIdToken(refreshToken: string): Promise<void>;
|
|
103
|
-
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import{createServer as k}from"http";import{URL as w}from"url";import g from"crypto";import P from"open";import{storeIdToken as d,storeRefreshToken as f,getRefreshToken as p,isUsingKeychainBackend as O,migrateToFileBackendWithTokens as I}from"./config.js";import{cerr as t}from"./console-prefix.js";import{isNoBrowserEnv as A}from"./auth-env.js";import{requestDeviceCode as x,pollForDeviceToken as G}from"./device-auth.js";class L extends Error{errorCode;errorDescription;constructor(r,n){super(n?`Refresh token invalid (${r}): ${n}`:`Refresh token invalid (${r})`),this.errorCode=r,this.errorDescription=n,this.name="RefreshTokenInvalidError"}}class l extends Error{constructor(r){super(r),this.name="RefreshTransientError"}}const m="675073910799-41pbe12rfhqemidh64h09s4q3e0udpgp.apps.googleusercontent.com",_="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",S="675073910799-6qmi73v5106dj1v0l22j2qnkh5r3e8fq.apps.googleusercontent.com",$="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",N="https://accounts.google.com/o/oauth2/v2/auth",T="https://oauth2.googleapis.com/token",D="https://oauth2.googleapis.com/revoke",y=["openid","email","profile"],re=8e3,ne=9e3,E=300*1e3,v=E/6e4;function U(){const e=g.randomBytes(32).toString("base64url"),r=g.createHash("sha256").update(e).digest("base64url");return{verifier:e,challenge:r}}async function B(){return new Promise((e,r)=>{const n=k();n.listen(0,()=>{const o=n.address();if(o&&typeof o=="object"){const i=o.port;n.close(()=>e(i))}else n.close(()=>r(new Error("Failed to get assigned port")))}),n.on("error",r)})}async function F(){const e=await B(),r=new Promise((n,o)=>{const i=k((s,c)=>{const a=new w(s.url,`http://localhost:${e}`);if(a.pathname==="/callback"){const h=a.searchParams.get("code"),u=a.searchParams.get("error");if(u){c.writeHead(400,{"Content-Type":"text/html"}),c.end(`
|
|
2
|
-
<html>
|
|
3
|
-
<body>
|
|
4
|
-
<h1>\u25FC Authentication Failed</h1>
|
|
5
|
-
<p>Error: ${u}</p>
|
|
6
|
-
<p>You can close this window.</p>
|
|
7
|
-
</body>
|
|
8
|
-
</html>
|
|
9
|
-
`),i.close(),o(new Error(`OAuth error: ${u}`));return}if(h){c.writeHead(200,{"Content-Type":"text/html"}),c.end(`
|
|
10
|
-
<html>
|
|
11
|
-
<body>
|
|
12
|
-
<h1>\u25FC Authentication Successful!</h1>
|
|
13
|
-
<p>You can close this window and return to your terminal.</p>
|
|
14
|
-
</body>
|
|
15
|
-
</html>
|
|
16
|
-
`),i.close(),n(h);return}c.writeHead(400,{"Content-Type":"text/html"}),c.end(`
|
|
17
|
-
<html>
|
|
18
|
-
<body>
|
|
19
|
-
<h1>\u25FC Invalid Request</h1>
|
|
20
|
-
<p>Missing authorization code.</p>
|
|
21
|
-
</body>
|
|
22
|
-
</html>
|
|
23
|
-
`),i.close(),o(new Error("Missing authorization code"))}});i.listen(e,()=>{t(`Callback server listening on http://localhost:${e}`)}),setTimeout(()=>{i.close(),o(new Error(`Authentication timed out after ${v} minutes \u2014 no authorization received from the browser. Re-run \`borg setup\` and complete the Google sign-in in the page that opens.`))},E).unref()});return{port:e,codePromise:r}}async function M(e,r,n){const o=`http://localhost:${n}/callback`,i=await fetch(T,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:m,client_secret:_,code:e,code_verifier:r,grant_type:"authorization_code",redirect_uri:o})});if(!i.ok){const s=await i.text();throw new Error(`Failed to exchange code for tokens: ${s}`)}return await i.json()}async function b(e){try{await fetch(D,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:`token=${encodeURIComponent(e)}`})}catch{}}async function K(){t(`
|
|
24
|
-
\u25FC Borg MCP Authentication`),t(`\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
25
|
-
`);const e=await p();e&&(t("Revoking previous refresh_token to force fresh consent..."),await b(e)),t("Generating PKCE challenge...");const r=U();t("Starting local callback server...");const{port:n,codePromise:o}=await F(),i=`http://localhost:${n}/callback`,s=new w(N);s.searchParams.set("client_id",m),s.searchParams.set("redirect_uri",i),s.searchParams.set("response_type","code"),s.searchParams.set("scope",y.join(" ")),s.searchParams.set("code_challenge",r.challenge),s.searchParams.set("code_challenge_method","S256"),s.searchParams.set("access_type","offline"),s.searchParams.set("prompt","consent select_account"),t(`
|
|
26
|
-
\u{1F4F1} Opening browser for authorization...`),t("If browser does not open, visit:"),t(`${s.toString()}
|
|
27
|
-
`);try{await P(s.toString())}catch(u){t(`Could not open a browser automatically: ${u?.message??"unknown"}`),t("Continue by opening the URL above manually.")}t(`Waiting for you to finish signing in (up to ${v} minutes)... this terminal continues automatically once you approve.`);const c=await o;t("Exchanging authorization code for tokens...");const a=await M(c,r.verifier,n),h=Date.now()+a.expires_in*1e3;await d(a.id_token,h),a.refresh_token?await f(a.refresh_token):(t(`
|
|
28
|
-
\u26A0 No refresh_token returned by Google.`),t(" Your session will expire after ~1 hour and require"),t(" re-running `borg setup`. To enable auto-refresh:"),t(" 1. Visit https://myaccount.google.com/permissions"),t(' 2. Find "Borg MCP" and click "Remove access"'),t(" 3. Re-run `borg setup`"),t(` (Google will then issue a fresh refresh_token.)
|
|
29
|
-
`)),t(`
|
|
30
|
-
\u25FC Authentication successful!
|
|
31
|
-
`)}function q(e){return e?.noBrowser??A()}function C(e=process.env){const r=e.GOOGLE_DEVICE_CLIENT_ID?.trim(),n=e.GOOGLE_DEVICE_CLIENT_SECRET?.trim()||void 0;let o,i;if(r?(o=r,i=n):(o=S,i=$||void 0),!o)throw new Error('No-browser (device-grant) auth needs a Google "TVs & Limited Input devices" OAuth client. Set GOOGLE_DEVICE_CLIENT_ID in the environment, or run `borg setup` on a machine with a browser. See docs/REMOTE_TERMINAL_AUTH.md.');return{clientId:o,clientSecret:i,scopes:y}}function H(e){return new Promise(r=>setTimeout(r,e))}async function V(e={fetch,sleep:H},r=process.env){t(`
|
|
32
|
-
\u25FC Borg MCP Authentication (no-browser mode)`),t(`\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
33
|
-
`);const n=C(r),o=await p();o&&(t("Revoking previous refresh_token to force fresh consent..."),await b(o));const i=await x(n,e);t("To authorize Borg MCP on this machine:"),t(` 1. On any device with a browser, open: ${i.verification_url}`),t(` 2. Enter this code: ${i.user_code}
|
|
34
|
-
`),t("Waiting for authorization (this page can be open on your phone or laptop)...");const s=await G(i,n,e),c=Date.now()+s.expires_in*1e3;await d(s.id_token,c),s.refresh_token?await f(s.refresh_token):(t(`
|
|
35
|
-
\u26A0 No refresh_token returned by Google.`),t(" Your session will expire after ~1 hour and require re-running"),t(" `borg setup`. Re-consent at https://myaccount.google.com/permissions"),t(` (remove "Borg MCP") then re-run setup to restore automatic token refresh.
|
|
36
|
-
`)),t(`
|
|
37
|
-
\u25FC Authentication successful!
|
|
38
|
-
`)}async function oe(e){return q(e)?V():K()}async function R(e,r,n){const o={client_id:r,refresh_token:e,grant_type:"refresh_token"};n&&(o.client_secret=n);let i;try{i=await fetch(T,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(o)})}catch(a){return{ok:!1,kind:"transient",error:new l(`Network failure during token refresh: ${a?.message??"unknown"}`)}}if(!i.ok){let a=null;try{a=await i.json()}catch{return{ok:!1,kind:"transient",error:new l(`Token refresh failed with HTTP ${i.status} (non-JSON body)`)}}return i.status===400&&a?.error==="invalid_grant"?{ok:!1,kind:"invalid",error:new L("invalid_grant",a.error_description)}:{ok:!1,kind:"transient",error:new l(`Token refresh failed with HTTP ${i.status}${a?.error?` (${a.error})`:""}`)}}let s;try{s=await i.json()}catch(a){return{ok:!1,kind:"transient",error:new l(`Token refresh response unparseable: ${a?.message??"unknown"}`)}}if(!s.id_token||typeof s.expires_in!="number")return{ok:!1,kind:"transient",error:new l("Token refresh response missing id_token or expires_in")};const c=Date.now()+s.expires_in*1e3;try{if(s.refresh_token){const a=await p();await f(s.refresh_token);try{await d(s.id_token,c)}catch(h){if(a)try{await f(a)}catch{}throw h}}else await d(s.id_token,c);return{ok:!0}}catch(a){return await z(s,c)?{ok:!0}:{ok:!1,kind:"transient",persistFailed:!0,error:new l(`Token refresh succeeded but saving it to the credential store failed (the keychain may be locked, or a background process can't write it): ${a?.message??"unknown"}`)}}}async function z(e,r){if(!e.id_token)return!1;let n=!1;try{if(!await O())return!1;const o=e.refresh_token??await p();if(!o)return!1;n=await I({idToken:e.id_token,expiresAt:r,refreshToken:o})}catch{return!1}return n?(W(),!0):!1}function W(){t(`
|
|
39
|
-
\u26A0 Keychain write failed \u2014 migrated this session to the encrypted-file token store (~/.borg/credentials).`),t(" This is an AVAILABILITY fallback, NOT equivalent to the OS keychain."),t(" The file backend is obfuscation-grade: its key is derived from"),t(" hostname+username+platform (non-secret), so it is WEAKER at-rest than"),t(" the keychain \u2014 same-machine/root access can re-derive it and decrypt."),t(" To restore keychain storage, fix keychain write access and re-run `borg setup`.\n")}async function ie(e){const r=await R(e,m,_);if(r.ok)return;if(r.kind==="transient"&&r.persistFailed)throw r.error;const n=C(),o=await R(e,n.clientId,n.clientSecret);if(!o.ok)throw r.kind==="invalid"&&o.kind==="invalid"?o.error:r.kind==="transient"?r.error:o.error}export{L as RefreshTokenInvalidError,l as RefreshTransientError,V as authenticateWithDeviceFlow,oe as authenticateWithGoogle,C as buildDeviceAuthConfig,ie as refreshIdToken,q as shouldUseDeviceFlow};
|
package/dist/device-auth.d.ts
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gh#557 — Google OAuth 2.0 Device Authorization Grant (RFC 8628).
|
|
3
|
-
*
|
|
4
|
-
* The no-browser counterpart to the loopback flow in auth.ts. Instead of
|
|
5
|
-
* opening a browser and listening on localhost, the device flow:
|
|
6
|
-
* 1. asks Google for a device_code + a short human-typable user_code,
|
|
7
|
-
* 2. prints a verification URL + the user_code for the human to open on
|
|
8
|
-
* ANY device (their phone, a laptop with a browser), and
|
|
9
|
-
* 3. polls Google's token endpoint until the human authorizes (or the
|
|
10
|
-
* code expires / is denied).
|
|
11
|
-
*
|
|
12
|
-
* This module is decoupled from the live Google client: `fetch`, `sleep`,
|
|
13
|
-
* and `now` are injected, and the client_id / client_secret / endpoints
|
|
14
|
-
* come from the caller. The live device flow needs a Google OAuth client
|
|
15
|
-
* of type "TVs & Limited Input devices" (a separate GOOGLE_DEVICE_CLIENT_ID
|
|
16
|
-
* — Desktop/loopback clients reject /device/code with invalid_client); the
|
|
17
|
-
* wiring layer supplies those credentials. Everything here is unit-tested
|
|
18
|
-
* against a mocked Google.
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* Failure of the device-grant flow. `code` is Google's OAuth error code
|
|
22
|
-
* where one exists (`access_denied`, `expired_token`, `invalid_client`,
|
|
23
|
-
* `slow_down`, `authorization_pending`) or a synthetic code for
|
|
24
|
-
* transport/shape failures (`device_code_request_failed`,
|
|
25
|
-
* `device_token_request_failed`, `malformed_token_response`).
|
|
26
|
-
*
|
|
27
|
-
* Token material is never placed in the message — only Google's error
|
|
28
|
-
* code + description, mirroring RefreshTokenInvalidError's discipline.
|
|
29
|
-
*/
|
|
30
|
-
export declare class DeviceAuthError extends Error {
|
|
31
|
-
readonly code: string;
|
|
32
|
-
constructor(code: string, message?: string);
|
|
33
|
-
}
|
|
34
|
-
export interface DeviceAuthConfig {
|
|
35
|
-
clientId: string;
|
|
36
|
-
/** Limited-Input clients are issued a secret; included in the token poll. */
|
|
37
|
-
clientSecret?: string;
|
|
38
|
-
scopes: string[];
|
|
39
|
-
/** Overridable for tests; defaults to Google's production endpoints. */
|
|
40
|
-
deviceCodeUrl?: string;
|
|
41
|
-
tokenUrl?: string;
|
|
42
|
-
}
|
|
43
|
-
export interface DeviceAuthDeps {
|
|
44
|
-
fetch: typeof fetch;
|
|
45
|
-
sleep: (ms: number) => Promise<void>;
|
|
46
|
-
/** Monotonic-ish clock for the local expiry deadline; defaults to Date.now. */
|
|
47
|
-
now?: () => number;
|
|
48
|
-
}
|
|
49
|
-
export interface DeviceCodeResponse {
|
|
50
|
-
device_code: string;
|
|
51
|
-
user_code: string;
|
|
52
|
-
/** Google returns `verification_url` (not the RFC's `verification_uri`). */
|
|
53
|
-
verification_url: string;
|
|
54
|
-
expires_in: number;
|
|
55
|
-
interval: number;
|
|
56
|
-
}
|
|
57
|
-
export interface DeviceTokenResult {
|
|
58
|
-
id_token: string;
|
|
59
|
-
refresh_token?: string;
|
|
60
|
-
expires_in: number;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Step 1 — request a device_code + user_code from Google.
|
|
64
|
-
*/
|
|
65
|
-
export declare function requestDeviceCode(config: DeviceAuthConfig, deps: DeviceAuthDeps): Promise<DeviceCodeResponse>;
|
|
66
|
-
/**
|
|
67
|
-
* Step 2 — poll Google's token endpoint until the user authorizes the
|
|
68
|
-
* device_code, honoring the RFC 8628 poll semantics.
|
|
69
|
-
*
|
|
70
|
-
* Sleeps `interval` BEFORE each poll (never hammers immediately). A local
|
|
71
|
-
* deadline derived from `expires_in` bounds the loop so a code the user
|
|
72
|
-
* abandons can't poll forever even if Google never returns expired_token.
|
|
73
|
-
*/
|
|
74
|
-
export declare function pollForDeviceToken(deviceCode: DeviceCodeResponse, config: DeviceAuthConfig, deps: DeviceAuthDeps): Promise<DeviceTokenResult>;
|
|
75
|
-
//# sourceMappingURL=device-auth.d.ts.map
|
package/dist/device-auth.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const u="https://oauth2.googleapis.com/device/code",p="https://oauth2.googleapis.com/token",w="urn:ietf:params:oauth:grant-type:device_code",h=5,f=5;class n extends Error{code;constructor(o,i){super(i??o),this.code=o,this.name="DeviceAuthError"}}async function v(t,o){const i=t.deviceCodeUrl??u;let c;try{c=await o.fetch(i,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:t.clientId,scope:t.scopes.join(" ")})})}catch(s){throw new n("device_code_request_failed",`Could not reach Google device endpoint: ${s?.message??"unknown"}`)}if(!c.ok){const s=await l(c);throw new n(s??"device_code_request_failed",`Device-code request failed (HTTP ${c.status}${s?`, ${s}`:""})`)}let e;try{e=await c.json()}catch{throw new n("malformed_token_response","Device-code response was not JSON")}if(!e.device_code||!e.user_code||!e.verification_url)throw new n("malformed_token_response","Device-code response missing device_code/user_code/verification_url");return{device_code:e.device_code,user_code:e.user_code,verification_url:e.verification_url,expires_in:typeof e.expires_in=="number"?e.expires_in:1800,interval:typeof e.interval=="number"?e.interval:5}}async function E(t,o,i){const c=o.tokenUrl??p,e=i.now??Date.now,s=e()+t.expires_in*1e3;let _=t.interval>0?t.interval:5;for(;;){if(e()>=s)throw new n("expired_token","Device code expired before the authorization was completed");await i.sleep(_*1e3);let a;try{a=await i.fetch(c,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({client_id:o.clientId,...o.clientSecret?{client_secret:o.clientSecret}:{},device_code:t.device_code,grant_type:w})})}catch(r){throw new n("device_token_request_failed",`Could not reach Google token endpoint: ${r?.message??"unknown"}`)}if(a.ok){let r;try{r=await a.json()}catch{throw new n("malformed_token_response","Token response was not JSON")}if(!r.id_token||typeof r.expires_in!="number")throw new n("malformed_token_response","Token response missing id_token or expires_in");return{id_token:r.id_token,refresh_token:r.refresh_token,expires_in:r.expires_in}}const d=await l(a);switch(d){case"authorization_pending":continue;case"slow_down":_+=5;continue;case"access_denied":throw new n("access_denied","Authorization was denied by the user");case"expired_token":throw new n("expired_token","Device code expired before authorization");default:throw new n(d??"device_token_request_failed",`Device token poll failed (HTTP ${a.status}${d?`, ${d}`:""})`)}}}async function l(t){try{const o=await t.json();return typeof o?.error=="string"?o.error:null}catch{return null}}export{n as DeviceAuthError,E as pollForDeviceToken,v as requestDeviceCode};
|
package/dist/drone-address.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gh#371 two-layer drone addressing — the shared short-uuid render helper.
|
|
3
|
-
*
|
|
4
|
-
* Lives in its own neutral module so BOTH the roster renderer
|
|
5
|
-
* (roster-render.ts) and the read-log renderer (regen-format.ts
|
|
6
|
-
* formatLogEntryMarkdown) import the SAME helper — one canonical token, no
|
|
7
|
-
* cross-surface divergence (gh#371 decision-3). A drone's live LABEL renumbers
|
|
8
|
-
* when cube membership changes (e.g. eighteen-of-28 → eighteen-of-30, which
|
|
9
|
-
* bounced this cluster's own dispatches); the short-uuid is the STABLE address.
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* The stable short-uuid: the first 8 hex of the drone_id (UUID). It is, by
|
|
13
|
-
* construction, a valid `startsWith` prefix of the full drone_id, so the
|
|
14
|
-
* worker resolver (resolveDirectRecipientIds, gh#371 S1) matches it
|
|
15
|
-
* cube-scoped. Lowercased to match the resolver's `/^[0-9a-f]{8,}$/i` guard.
|
|
16
|
-
*/
|
|
17
|
-
export declare function shortDroneId(droneId: string): string;
|
|
18
|
-
/**
|
|
19
|
-
* The clearly-LABELED address token shown beside a drone on the roster and on
|
|
20
|
-
* each read-log entry (gh#371 finding-2): `` `id:3336cde1` ``. Backticked so it
|
|
21
|
-
* renders monospace — visually distinct from the plain `[entry_id: …]` bracket
|
|
22
|
-
* that sits beside it in read-log, so a weak model never confuses which token
|
|
23
|
-
* to `borg_ack` with (entry_id) versus address a dispatch to (`id:` short-uuid).
|
|
24
|
-
*/
|
|
25
|
-
export declare function formatDroneAddressToken(droneId: string): string;
|
|
26
|
-
//# sourceMappingURL=drone-address.d.ts.map
|
package/dist/drone-address.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function e(r){return r.slice(0,8).toLowerCase()}function o(r){return`\`id:${e(r)}\``}export{o as formatDroneAddressToken,e as shortDroneId};
|
package/dist/get-started.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fresh-vs-configured rule. "Configured" = the user has completed `borg setup`,
|
|
3
|
-
* signalled by the PRESENCE of a stored credential. Inputs are existence
|
|
4
|
-
* booleans only — the caller null-checks the token accessors and never decodes,
|
|
5
|
-
* logs, or prints the token value (SR gh#817 constraint).
|
|
6
|
-
*
|
|
7
|
-
* Refresh-token presence is the durable signal: it survives id_token expiry, so
|
|
8
|
-
* a configured user whose id_token has lapsed is NOT mistaken for fresh (which
|
|
9
|
-
* would wrongly suppress their normal launch). The id_token presence is the
|
|
10
|
-
* fallback for the rare case where Google returned no refresh_token and the
|
|
11
|
-
* id_token is still valid.
|
|
12
|
-
*/
|
|
13
|
-
export declare function shouldShowGetStarted(hasRefreshToken: boolean, hasIdToken: boolean): boolean;
|
|
14
|
-
/**
|
|
15
|
-
* The user-visible get-started text. Carries ZERO auth material (no tokens, no
|
|
16
|
-
* PII) — it is pure onboarding guidance. When no agent CLI is detected, lead
|
|
17
|
-
* with the install-an-agent-CLI step (mirrors the B1 banner intent).
|
|
18
|
-
*/
|
|
19
|
-
export declare function composeGetStarted(hasAgentCli: boolean): string;
|
|
20
|
-
//# sourceMappingURL=get-started.d.ts.map
|
package/dist/get-started.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function n(o,e){return!o&&!e}function r(o){const e=["","Welcome to Borg MCP \u2014 multi-agent coordination for your AI coding agent.","","You're not set up yet. To get started:",""];let t=1;return o||(e.push(` ${t}. Install an agent CLI first:`," Claude Code: https://claude.ai/download"," Codex: https://developers.openai.com/codex"),t++),e.push(` ${t}. borg setup${" ".repeat(Math.max(1,8))}\u2014 sign in with Google`),t++,e.push(` ${t}. cd into your project, then: borg assimilate \u2014 join/create a cube`,"","Then `borg` launches your agent in that cube. Run `borg --help` for more.",""),e.join(`
|
|
2
|
-
`)}export{r as composeGetStarted,n as shouldShowGetStarted};
|
package/dist/health-beat.d.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gh#541 WU-2 — client health beat (the Part B "receipt watermark" producer).
|
|
3
|
-
*
|
|
4
|
-
* The MCP-client child process emits a periodic + event-driven health BEAT to
|
|
5
|
-
* the server's `POST /api/drone/health` (WU-1). The beat reports:
|
|
6
|
-
* - `last_event_at` — when this client last RECEIVED an inbound cube
|
|
7
|
-
* event (the wake-path RECEIPT evidence). This is
|
|
8
|
-
* produced BELOW the agent classifier (WU-0 proved
|
|
9
|
-
* child-process HTTP is independent of the agent
|
|
10
|
-
* tool-call path), so it stays fresh even during a
|
|
11
|
-
* classifier outage and even when the agent /loop
|
|
12
|
-
* never wakes — which is exactly what lets the
|
|
13
|
-
* watchdog (WU-3) tell DEAF (Monitor down) apart
|
|
14
|
-
* from POST-BLOCKED.
|
|
15
|
-
* - `sse_connected` — the SSE wire state.
|
|
16
|
-
* - `inbox_monitor_armed` — whether a tail-Monitor is watching the inbox.
|
|
17
|
-
*
|
|
18
|
-
* The beat carries NO token material in the body (auth is the X-Drone-Session
|
|
19
|
-
* header, same as every other drone endpoint). It is strictly BEST-EFFORT: a
|
|
20
|
-
* failed POST is swallowed and must never crash the SSE stream.
|
|
21
|
-
*
|
|
22
|
-
* Side-effecting deps (fetch, token, cube/status/monitor probes, clock) are
|
|
23
|
-
* injected so the producer is unit-tested without real network/keychain/pgrep.
|
|
24
|
-
*/
|
|
25
|
-
/** The cube context needed to address + auth a beat (subset of ActiveCube). */
|
|
26
|
-
export interface HealthBeatActive {
|
|
27
|
-
cubeId: string;
|
|
28
|
-
droneId: string;
|
|
29
|
-
sessionToken: string;
|
|
30
|
-
apiUrl: string;
|
|
31
|
-
}
|
|
32
|
-
export interface HealthPayload {
|
|
33
|
-
sse_connected: boolean;
|
|
34
|
-
inbox_monitor_armed: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* gh#633: transport-AGNOSTIC wake-path-armed signal. The client computes it
|
|
37
|
-
* from its OWN runtime wake mechanism — claude=tail-F inbox Monitor health,
|
|
38
|
-
* codex=app-server bridge liveness — so the HOP-2 wake-path-deaf classifier
|
|
39
|
-
* reads one boolean without branching on (mis-recordable) agent_kind. For a
|
|
40
|
-
* claude drone this equals inbox_monitor_armed; for codex it reflects the
|
|
41
|
-
* bridge (which has no tail-F Monitor by design).
|
|
42
|
-
*/
|
|
43
|
-
wake_armed: boolean;
|
|
44
|
-
/**
|
|
45
|
-
* gh#634: the drone's agent_kind from LIVE runtime detection
|
|
46
|
-
* (resolveSessionAgentKind). Assimilation captures agent_kind only at join,
|
|
47
|
-
* so a relaunch of an existing seat needs this always-running child to
|
|
48
|
-
* refresh the recorded value through recordDroneHealth's COALESCE update.
|
|
49
|
-
*/
|
|
50
|
-
agent_kind: 'claude' | 'codex' | 'opencode';
|
|
51
|
-
/**
|
|
52
|
-
* gh#408: live runtime hostname. Assimilate captures hostname only at first
|
|
53
|
-
* join; the beat carries the relaunched process's current machine name so
|
|
54
|
-
* the server can self-heal the recorded display value.
|
|
55
|
-
*/
|
|
56
|
-
hostname: string | null;
|
|
57
|
-
/**
|
|
58
|
-
* gh#646: installed borgmcp client version from getPackageVersion().
|
|
59
|
-
* Stored separately from liveness so a relaunched/upgraded drone can refresh
|
|
60
|
-
* its recorded version without re-assimilating.
|
|
61
|
-
*/
|
|
62
|
-
version: string;
|
|
63
|
-
last_event_at: string | null;
|
|
64
|
-
}
|
|
65
|
-
/** Record that an inbound cube event was just received (the receipt evidence). */
|
|
66
|
-
export declare function recordEventReceipt(now?: Date): void;
|
|
67
|
-
export declare function getLastEventReceivedAt(): Date | null;
|
|
68
|
-
export declare function getCachedMonitorHealthy(): boolean | null;
|
|
69
|
-
/** Cached transport-agnostic wake-armed (gh#633), for cheap per-event beats. */
|
|
70
|
-
export declare function getCachedWakeArmed(): boolean | null;
|
|
71
|
-
/**
|
|
72
|
-
* Reset module state. TEST-ONLY — the beat state is a process singleton in
|
|
73
|
-
* normal operation; nothing in production code should call this.
|
|
74
|
-
* @internal
|
|
75
|
-
*/
|
|
76
|
-
export declare function __resetHealthBeatStateForTest(): void;
|
|
77
|
-
/**
|
|
78
|
-
* Build the beat payload from the current receipt watermark + the supplied
|
|
79
|
-
* wire/monitor state.
|
|
80
|
-
*
|
|
81
|
-
* `inbox_monitor_armed` maps the tri-state monitor probe to the boolean the
|
|
82
|
-
* server schema requires: ONLY a POSITIVELY-broken probe (`false`) reports
|
|
83
|
-
* `false`; both healthy (`true`) and unknown (`null`) report `true`. This
|
|
84
|
-
* mirrors `shouldShowWakePathWarning` (which fires only on `=== false`) and is
|
|
85
|
-
* the design's false-deaf-avoidance posture — an undeterminable probe must not
|
|
86
|
-
* masquerade as a dead Monitor.
|
|
87
|
-
*/
|
|
88
|
-
export declare function buildHealthPayload(sseConnected: boolean, inboxMonitorHealthy: boolean | null, wakeArmed: boolean | null, agentKind: 'claude' | 'codex' | 'opencode', hostname: string | null, version: string): HealthPayload;
|
|
89
|
-
export interface BeatTransport {
|
|
90
|
-
fetchImpl: typeof fetch;
|
|
91
|
-
getToken: () => Promise<string>;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Best-effort POST of a beat. Swallows ALL errors (token fetch, network,
|
|
95
|
-
* non-2xx) — a beat that can't be delivered must never propagate into the
|
|
96
|
-
* stream loop. Body carries NO token material; auth is via headers.
|
|
97
|
-
*/
|
|
98
|
-
export declare function postHealthBeat(active: HealthBeatActive, payload: HealthPayload, deps: BeatTransport): Promise<void>;
|
|
99
|
-
/** Build the current payload and post it (best-effort). */
|
|
100
|
-
export declare function emitHealthBeat(active: HealthBeatActive, opts: {
|
|
101
|
-
sseConnected: boolean;
|
|
102
|
-
inboxMonitorHealthy: boolean | null;
|
|
103
|
-
wakeArmed: boolean | null;
|
|
104
|
-
agentKind: 'claude' | 'codex' | 'opencode';
|
|
105
|
-
hostname: string | null;
|
|
106
|
-
version: string;
|
|
107
|
-
} & BeatTransport): Promise<void>;
|
|
108
|
-
export interface HealthBeatTickDeps extends BeatTransport {
|
|
109
|
-
getActiveCube: () => Promise<HealthBeatActive | null>;
|
|
110
|
-
getStreamConnected: () => boolean;
|
|
111
|
-
getInboxPath: (active: HealthBeatActive) => string | null;
|
|
112
|
-
checkMonitor: (inboxPath: string | null) => boolean | null;
|
|
113
|
-
isCodexRemoteWake: () => boolean;
|
|
114
|
-
probeBridgeArmed: (active: HealthBeatActive) => Promise<boolean | null>;
|
|
115
|
-
probeOpenCodeDrone?: (active: HealthBeatActive) => Promise<boolean | null>;
|
|
116
|
-
resolveAgentKind: () => 'claude' | 'codex' | 'opencode';
|
|
117
|
-
resolveHostname: () => string | null;
|
|
118
|
-
resolveVersion: () => string;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* One tick of the periodic beat: resolve the active cube, probe the live
|
|
122
|
-
* wire + Monitor state, cache the monitor result (so cheap per-event beats can
|
|
123
|
-
* reuse it without re-spawning pgrep), and emit the beat. No active cube → no
|
|
124
|
-
* beat. Best-effort: never throws.
|
|
125
|
-
*/
|
|
126
|
-
export declare function runHealthBeatOnce(deps: HealthBeatTickDeps): Promise<void>;
|
|
127
|
-
/** Default periodic cadence for the health beat. */
|
|
128
|
-
export declare const HEALTH_BEAT_INTERVAL_MS = 60000;
|
|
129
|
-
/**
|
|
130
|
-
* Start the periodic beat. Fire-and-forget; the timer is `unref`'d so it never
|
|
131
|
-
* keeps the process alive on its own. Returns the timer handle (tests clear it).
|
|
132
|
-
*/
|
|
133
|
-
export declare function startHealthBeatTick(deps: HealthBeatTickDeps, intervalMs?: number): NodeJS.Timeout;
|
|
134
|
-
//# sourceMappingURL=health-beat.d.ts.map
|
package/dist/health-beat.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
let r=null,i=null,l=null;function g(e=new Date){r=e}function v(){return r}function y(){return i}function k(){return l}function A(){r=null,i=null,l=null}function d(e,t,n,o,a,c){return{sse_connected:e,inbox_monitor_armed:t!==!1,wake_armed:n!==!1,agent_kind:o,hostname:a,version:c,last_event_at:r?r.toISOString():null}}async function f(e,t,n){try{const o=await n.getToken();await n.fetchImpl(`${e.apiUrl}/api/drone/health`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"X-Drone-Session":e.sessionToken,"Content-Type":"application/json"},body:JSON.stringify(t)})}catch{}}async function m(e,t){const n=d(t.sseConnected,t.inboxMonitorHealthy,t.wakeArmed,t.agentKind,t.hostname,t.version);await f(e,n,t)}async function h(e){try{const t=await e.getActiveCube();if(!t)return;const n=e.getStreamConnected(),o=e.checkMonitor(e.getInboxPath(t));i=o;const a=e.resolveAgentKind(),c=a==="opencode"?await e.probeOpenCodeDrone?.(t)??null:a==="codex"?e.isCodexRemoteWake()?await e.probeBridgeArmed(t):!1:o;l=c;const s=e.resolveHostname(),u=e.resolveVersion();await m(t,{sseConnected:n,inboxMonitorHealthy:o,wakeArmed:c,agentKind:a,hostname:s,version:u,fetchImpl:e.fetchImpl,getToken:e.getToken})}catch{}}const x=6e4;function H(e,t=x){h(e);const n=setInterval(()=>{h(e)},t);return n.unref?.(),n}export{x as HEALTH_BEAT_INTERVAL_MS,A as __resetHealthBeatStateForTest,d as buildHealthPayload,m as emitHealthBeat,y as getCachedMonitorHealthy,k as getCachedWakeArmed,v as getLastEventReceivedAt,f as postHealthBeat,g as recordEventReceipt,h as runHealthBeatOnce,H as startHealthBeatTick};
|
package/dist/role-section.d.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Role-text section parsing + granular section patching (gh#473 PR1).
|
|
3
|
-
*
|
|
4
|
-
* Platform-dependency-free, same shape as `message-taxonomy.ts`: pure
|
|
5
|
-
* string logic so the worker DB layer AND unit tests can both import it
|
|
6
|
-
* without dragging in Cloudflare / Neon types.
|
|
7
|
-
*
|
|
8
|
-
* ## Why not markdown `##` headings
|
|
9
|
-
*
|
|
10
|
-
* Real role `detailed_description` text (see `client/src/templates.ts`)
|
|
11
|
-
* does NOT use `##` headings. It is structured as:
|
|
12
|
-
*
|
|
13
|
-
* - a PREAMBLE — free prose before the first label line
|
|
14
|
-
* (e.g. "You implement changes to the codebase…");
|
|
15
|
-
* - one or more SECTIONS, each headed by a PLAIN-LABEL LINE — a line
|
|
16
|
-
* that is a short label terminated by a single trailing colon and
|
|
17
|
-
* nothing else (e.g. `Workflow:`, `Project conventions:`,
|
|
18
|
-
* `Your job:`, `Log conventions you use:`);
|
|
19
|
-
* - TRAILING inlined `${ESCALATION_DISCIPLINE}` / `${...}` constant
|
|
20
|
-
* text woven onto the end of the field. That text uses `**bold:**`
|
|
21
|
-
* markdown emphasis, NOT bare label lines, so it is NOT a section
|
|
22
|
-
* boundary — it falls into the last label section as literal text.
|
|
23
|
-
*
|
|
24
|
-
* A parser that splits on `##` finds ZERO sections in real role text.
|
|
25
|
-
* The label-line delimiter below matches the ACTUAL structure.
|
|
26
|
-
*
|
|
27
|
-
* ## Byte-identical round-trip invariant
|
|
28
|
-
*
|
|
29
|
-
* `serializeSections(parseRoleSections(text)) === text` for ANY input.
|
|
30
|
-
* The parser does not trim, normalize newlines, or otherwise rewrite
|
|
31
|
-
* bytes — each section's `body` retains the exact slice (including its
|
|
32
|
-
* heading line and the newline that terminates it) so concatenation
|
|
33
|
-
* reproduces the original field verbatim. The single named-fragment
|
|
34
|
-
* mutation is therefore the ONLY byte-level change a patch makes.
|
|
35
|
-
*/
|
|
36
|
-
/** What kind of label heads a section. */
|
|
37
|
-
export type RoleSectionKind = 'preamble' | 'label';
|
|
38
|
-
export interface RoleSection {
|
|
39
|
-
/**
|
|
40
|
-
* The section's label WITHOUT the trailing colon, trimmed
|
|
41
|
-
* (e.g. "Workflow", "Project conventions"). `null` for the preamble
|
|
42
|
-
* (the pre-first-label span). Used as the addressing key for patches.
|
|
43
|
-
*/
|
|
44
|
-
heading: string | null;
|
|
45
|
-
kind: RoleSectionKind;
|
|
46
|
-
/**
|
|
47
|
-
* The EXACT source slice for this section, including its heading line
|
|
48
|
-
* (for label sections) and every byte through to (but not including)
|
|
49
|
-
* the next section's heading line. Concatenating every section's
|
|
50
|
-
* `body` in order reproduces the original text byte-for-byte.
|
|
51
|
-
*/
|
|
52
|
-
body: string;
|
|
53
|
-
}
|
|
54
|
-
export type RoleSectionPatchOp = {
|
|
55
|
-
action: 'replace';
|
|
56
|
-
heading: string;
|
|
57
|
-
body: string;
|
|
58
|
-
} | {
|
|
59
|
-
action: 'insert';
|
|
60
|
-
heading: string;
|
|
61
|
-
body: string;
|
|
62
|
-
after?: string | null;
|
|
63
|
-
} | {
|
|
64
|
-
action: 'delete';
|
|
65
|
-
heading: string;
|
|
66
|
-
};
|
|
67
|
-
/**
|
|
68
|
-
* Test whether a single line is a plain-label section heading.
|
|
69
|
-
*
|
|
70
|
-
* Rules (deliberately narrow to avoid false positives against prose
|
|
71
|
-
* that merely contains a colon):
|
|
72
|
-
* - no leading whitespace (label lines start at column 0);
|
|
73
|
-
* - the line ends with exactly one `:`;
|
|
74
|
-
* - the text before the colon is non-empty, contains no other `:`,
|
|
75
|
-
* and is "short" (≤ 60 chars) — long colon-terminated prose lines
|
|
76
|
-
* are not labels;
|
|
77
|
-
* - the label is not a markdown emphasis run (does not start with
|
|
78
|
-
* `*`, `-`, `#`, `>` or backtick) — those are list/markdown lines,
|
|
79
|
-
* not plain labels (the woven `**Dense communication discipline:**`
|
|
80
|
-
* constant headings must NOT be treated as section boundaries).
|
|
81
|
-
*/
|
|
82
|
-
export declare function isLabelLine(line: string): boolean;
|
|
83
|
-
/**
|
|
84
|
-
* Parse role `detailed_description` text into ordered sections.
|
|
85
|
-
*
|
|
86
|
-
* The result always round-trips byte-identical through
|
|
87
|
-
* `serializeSections`. An empty string yields a single empty preamble
|
|
88
|
-
* section so callers always have a stable shape to address.
|
|
89
|
-
*/
|
|
90
|
-
export declare function parseRoleSections(text: string): RoleSection[];
|
|
91
|
-
/** Concatenate sections back into the original field text. */
|
|
92
|
-
export declare function serializeSections(sections: RoleSection[]): string;
|
|
93
|
-
/**
|
|
94
|
-
* Apply a single section-level patch to role text, returning the new
|
|
95
|
-
* full field text. Every other byte is preserved.
|
|
96
|
-
*
|
|
97
|
-
* - replace: overwrite the matched section's body with a re-rendered
|
|
98
|
-
* `<heading>:\n<body>` block. The heading match is case-insensitive
|
|
99
|
-
* on the label; the re-rendered heading uses the supplied casing.
|
|
100
|
-
* - insert: add a new label section. Placed after the section named by
|
|
101
|
-
* `after` (case-insensitive), or appended at the end when `after` is
|
|
102
|
-
* omitted/null. Rejects if a section with the same heading already
|
|
103
|
-
* exists (use replace instead).
|
|
104
|
-
* - delete: drop the matched section entirely.
|
|
105
|
-
*
|
|
106
|
-
* Throws when the target section is missing (replace/delete) or already
|
|
107
|
-
* present (insert), or when `after` does not resolve.
|
|
108
|
-
*/
|
|
109
|
-
export declare function patchRoleSectionText(text: string, op: RoleSectionPatchOp): string;
|
|
110
|
-
//# sourceMappingURL=role-section.d.ts.map
|
package/dist/role-section.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
function b(t){if(/^\s/.test(t)||!t.endsWith(":"))return!1;const e=t.slice(0,-1);return!(e.length===0||e.length>60||e.includes(":")||/^[*\-#>`]/.test(e))}function w(t){const e=[],n=t.split(`
|
|
2
|
-
`),l=i=>i<n.length-1?n[i]+`
|
|
3
|
-
`:n[i];let f=null,s="preamble",d="",a=!1;const r=()=>{e.push({heading:f,kind:s,body:d})};for(let i=0;i<n.length;i++){const u=n[i];b(u)?(r(),f=u.slice(0,-1).trim(),s="label",d=l(i),a=!0):(d+=l(i),a=!0)}return(a||e.length===0)&&r(),e}function c(t){return t.map(e=>e.body).join("")}function o(t){return t.trim().toLowerCase()}function h(t,e){const n=`${t.trim()}:
|
|
4
|
-
`;if(e==="")return n;const l=e.endsWith(`
|
|
5
|
-
`)?e:e+`
|
|
6
|
-
`;return n+l}function g(t,e){if(e<0||e>=t.length)return;const n=t[e];n.body!==""&&!n.body.endsWith(`
|
|
7
|
-
`)&&(t[e]={...n,body:n.body+`
|
|
8
|
-
`})}function y(t,e){const n=w(t),l=o(e.heading);if(e.action==="replace"){const r=n.findIndex(i=>i.kind==="label"&&i.heading!=null&&o(i.heading)===l);if(r===-1)throw new Error(`Role section "${e.heading}" not found. Use action="insert" to add it.`);return n[r]={heading:e.heading.trim(),kind:"label",body:h(e.heading,e.body)},c(n)}if(e.action==="delete"){const r=n.findIndex(i=>i.kind==="label"&&i.heading!=null&&o(i.heading)===l);if(r===-1)throw new Error(`Role section "${e.heading}" not found.`);return n.splice(r,1),c(n)}if(n.some(r=>r.kind==="label"&&r.heading!=null&&o(r.heading)===l))throw new Error(`Role section "${e.heading}" already exists. Use action="replace" to overwrite it.`);const s={heading:e.heading.trim(),kind:"label",body:h(e.heading,e.body)};if(e.after==null)return g(n,n.length-1),n.push(s),c(n);const d=o(e.after),a=n.findIndex(r=>r.kind==="label"&&r.heading!=null&&o(r.heading)===d);if(a===-1)throw new Error(`Cannot insert after section "${e.after}" \u2014 it does not exist.`);return g(n,a),n.splice(a+1,0,s),c(n)}export{b as isLabelLine,w as parseRoleSections,y as patchRoleSectionText,c as serializeSections};
|
package/dist/setup-action.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gh#794 (CR 9f302b15): the `borg setup` auth-step decision, extracted as a
|
|
3
|
-
* PURE, side-effect-free mapping so the SR#3 contract is unit-pinned WITHOUT
|
|
4
|
-
* importing setup.ts (which runs `main()` at module load) or mocking the
|
|
5
|
-
* monolithic runSetup. `tsc` proves setup.ts's switch COMPILES; the unit test
|
|
6
|
-
* over this helper proves it MAPS correctly — a future mis-edit (e.g. a
|
|
7
|
-
* 'transient' wrongly skipping → an SR#3 break) fails the mapping test instead
|
|
8
|
-
* of silently passing every probeSession test.
|
|
9
|
-
*
|
|
10
|
-
* - 'valid' → 'skip' (short-circuit OAuth; session is usable)
|
|
11
|
-
* - 'dead' → 'reauth' (full re-auth — NEVER short-circuit past a dead
|
|
12
|
-
* token, the exact failure #794 fixes)
|
|
13
|
-
* - 'transient' → 'retry' (network blip — don't re-auth, don't destroy)
|
|
14
|
-
*
|
|
15
|
-
* Type-only import of SessionState → zero runtime coupling to remote-client.
|
|
16
|
-
*/
|
|
17
|
-
import type { SessionState } from './remote-client.js';
|
|
18
|
-
export type SetupAuthAction = 'skip' | 'reauth' | 'retry';
|
|
19
|
-
export declare function setupActionForSession(state: SessionState): SetupAuthAction;
|
|
20
|
-
//# sourceMappingURL=setup-action.d.ts.map
|
package/dist/setup-action.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function t(e){switch(e){case"valid":return"skip";case"transient":return"retry";default:return"reauth"}}export{t as setupActionForSession};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sprint 7 (b) — stale-binary defensive hardening (gh#148 close-out).
|
|
3
|
-
*
|
|
4
|
-
* drone-3's v0.8.0 case (cube log 2026-05-18T10:35Z) ran for months
|
|
5
|
-
* without warning that v0.8.10 had shipped the gh#71 carve-out for
|
|
6
|
-
* own-drone heartbeat-pings. The silent-stale-binary failure mode
|
|
7
|
-
* costs cube collective time to diagnose because the gap between
|
|
8
|
-
* "installed version" and "latest published" is invisible to the
|
|
9
|
-
* operator.
|
|
10
|
-
*
|
|
11
|
-
* This module surfaces that gap at borg launch time via a stderr
|
|
12
|
-
* warning. Network check against npmjs.org registry is async +
|
|
13
|
-
* timeout-gated so a slow registry doesn't block the operator. Fails
|
|
14
|
-
* silently on any error (network failure, registry change,
|
|
15
|
-
* prerelease version, etc.) — defense-in-depth, never a blocker.
|
|
16
|
-
*/
|
|
17
|
-
export interface VersionCheckResult {
|
|
18
|
-
stale: boolean;
|
|
19
|
-
message: string | null;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Pure compare: given an installed version string and a latest version
|
|
23
|
-
* string, decide whether to warn. Both strings are expected in semver
|
|
24
|
-
* `MAJOR.MINOR.PATCH` form (no prerelease, no build metadata).
|
|
25
|
-
*
|
|
26
|
-
* Returns `{stale: true, message}` when installed is at least
|
|
27
|
-
* MINOR_VERSIONS_BEHIND_THRESHOLD minor versions behind latest on the
|
|
28
|
-
* same major. Defaults conservatively — unparseable input, prerelease
|
|
29
|
-
* tags, or anything weird returns `stale: false` so we never
|
|
30
|
-
* false-positive on edge cases.
|
|
31
|
-
*/
|
|
32
|
-
export declare function compareVersionsForStaleness(installed: string, latest: string): VersionCheckResult;
|
|
33
|
-
/**
|
|
34
|
-
* Fetch the latest published borgmcp version from the npm registry.
|
|
35
|
-
* Returns the version string on success, `null` on any failure
|
|
36
|
-
* (timeout, network error, registry change, malformed response).
|
|
37
|
-
* Never throws — caller treats null as "skip the warning."
|
|
38
|
-
*/
|
|
39
|
-
export declare function fetchLatestBorgmcpVersion(): Promise<string | null>;
|
|
40
|
-
//# sourceMappingURL=stale-version-check.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const a="https://registry.npmjs.org/borgmcp/latest",i=2e3,c=1;function u(t,e){const r=o(t),n=o(e);if(!r||!n)return{stale:!1,message:null};if(r.major!==n.major)return{stale:!1,message:null};const s=n.minor-r.minor;return s<1?{stale:!1,message:null}:{stale:!0,message:`\u26A0 borgmcp ${t} is behind latest ${e} \u2014 npm install -g borgmcp@latest`}}function o(t){if(typeof t!="string"||t.length===0)return null;const e=/^(\d+)\.(\d+)\.(\d+)$/.exec(t);return e?{major:parseInt(e[1],10),minor:parseInt(e[2],10),patch:parseInt(e[3],10)}:null}async function m(){const t=new AbortController,e=setTimeout(()=>t.abort(),2e3);try{const r=await fetch(a,{signal:t.signal,headers:{Accept:"application/json"}});if(!r.ok)return null;const n=await r.json();return typeof n.version!="string"||n.version.length===0?null:n.version}catch{return null}finally{clearTimeout(e)}}export{u as compareVersionsForStaleness,m as fetchLatestBorgmcpVersion};
|