@sleep2agi/agent-network 2.3.0-preview.18 → 2.3.0-preview.180

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/README.md +35 -324
  2. package/dist/bin/anet.cjs +101 -0
  3. package/dist/bin/cli.d.ts +1 -0
  4. package/dist/bin/cli.js +20 -1
  5. package/dist/src/active-network-task.d.ts +28 -0
  6. package/dist/src/batch-workdir.d.ts +9 -0
  7. package/dist/src/bootstrap-password-db.d.ts +13 -0
  8. package/dist/src/channel-attachments.d.ts +29 -0
  9. package/dist/src/channel-inbox-wake.d.ts +21 -0
  10. package/dist/src/channel-meta.d.ts +10 -0
  11. package/dist/src/channel-peer-reply.d.ts +41 -0
  12. package/dist/src/channel-task-trace.d.ts +14 -0
  13. package/dist/src/claude-vendor-env.d.ts +28 -0
  14. package/dist/src/cli-args.d.ts +8 -0
  15. package/dist/src/cli-auth-session.d.ts +47 -0
  16. package/dist/src/cli-errors.d.ts +41 -0
  17. package/dist/src/cli-exit.d.ts +11 -0
  18. package/dist/src/cli-help.d.ts +10 -0
  19. package/dist/src/cli-version-display.d.ts +16 -0
  20. package/dist/src/client-task-trace.d.ts +9 -0
  21. package/dist/src/client.js +1 -1
  22. package/dist/src/codex-adopt.d.ts +46 -0
  23. package/dist/src/codex-auth-fingerprint.d.ts +211 -0
  24. package/dist/src/codex-bin-pin.d.ts +23 -0
  25. package/dist/src/codex-commhub-mcp.d.ts +22 -0
  26. package/dist/src/codex-copresence-bridge-log.d.ts +44 -0
  27. package/dist/src/codex-copresence-env.d.ts +5 -0
  28. package/dist/src/codex-copresence-login-gate.d.ts +18 -0
  29. package/dist/src/codex-copresence-model.d.ts +23 -0
  30. package/dist/src/codex-copresence-preflight.d.ts +78 -0
  31. package/dist/src/codex-copresence-profile.d.ts +126 -0
  32. package/dist/src/codex-copresence-recovery.d.ts +70 -0
  33. package/dist/src/codex-copresence-resume-timeout.d.ts +28 -0
  34. package/dist/src/codex-copresence-rollout-guard.d.ts +36 -0
  35. package/dist/src/codex-copresence-rpc.d.ts +17 -0
  36. package/dist/src/codex-copresence-thread.d.ts +13 -0
  37. package/dist/src/codex-copresence-yolo.d.ts +16 -0
  38. package/dist/src/codex-external-appserver.d.ts +130 -0
  39. package/dist/src/codex-fork-recovery.d.ts +52 -0
  40. package/dist/src/codex-home-enforce.d.ts +88 -0
  41. package/dist/src/codex-lifecycle-account.d.ts +104 -0
  42. package/dist/src/codex-lifecycle-canary.d.ts +20 -0
  43. package/dist/src/codex-lifecycle-facts.d.ts +53 -0
  44. package/dist/src/codex-lifecycle-fork.d.ts +91 -0
  45. package/dist/src/codex-lifecycle-preflight.d.ts +79 -0
  46. package/dist/src/codex-lifecycle-receipt.d.ts +53 -0
  47. package/dist/src/codex-lifecycle-restart.d.ts +88 -0
  48. package/dist/src/codex-login-share-guard.d.ts +146 -0
  49. package/dist/src/codex-menu.d.ts +99 -0
  50. package/dist/src/codex-model-default.d.ts +6 -0
  51. package/dist/src/codex-node-login.d.ts +98 -0
  52. package/dist/src/codex-pending-thread-restart.d.ts +69 -0
  53. package/dist/src/codex-reasoning-effort.d.ts +17 -0
  54. package/dist/src/codex-recovery-lease.d.ts +39 -0
  55. package/dist/src/codex-recovery-resource-gate.d.ts +15 -0
  56. package/dist/src/codex-resume.d.ts +89 -0
  57. package/dist/src/codex-rollout-history-guard.d.ts +84 -0
  58. package/dist/src/codex-tui-client-health.d.ts +30 -0
  59. package/dist/src/commhub-response.d.ts +1 -0
  60. package/dist/src/controlled-upload.d.ts +83 -0
  61. package/dist/src/copresence-deps.d.ts +22 -0
  62. package/dist/src/copresence-identity.d.ts +363 -0
  63. package/dist/src/copresence-startup-diagnosis.d.ts +17 -0
  64. package/dist/src/daemon-adopt.d.ts +14 -0
  65. package/dist/src/daemon-anet-bin.d.ts +32 -0
  66. package/dist/src/daemon-capability-display.d.ts +110 -0
  67. package/dist/src/daemon-capability-display.js +21 -0
  68. package/dist/src/daemon-codex-inventory.d.ts +65 -0
  69. package/dist/src/daemon-inherited-env.d.ts +9 -0
  70. package/dist/src/daemon-provider-account-custody.d.ts +28 -0
  71. package/dist/src/daemon-provider-account-readback.d.ts +3 -0
  72. package/dist/src/daemon-provider-application.d.ts +36 -0
  73. package/dist/src/daemon-provider-apply-command.d.ts +9 -0
  74. package/dist/src/daemon-provider-collect.d.ts +29 -0
  75. package/dist/src/daemon-provider-command.d.ts +7 -0
  76. package/dist/src/daemon-provider-initialize.d.ts +27 -0
  77. package/dist/src/daemon-provider-lifecycle.d.ts +4 -0
  78. package/dist/src/daemon-provider-store.d.ts +104 -0
  79. package/dist/src/daemon-runtime-path-preflight.d.ts +22 -0
  80. package/dist/src/daemon-runtime-staleness.d.ts +13 -0
  81. package/dist/src/dashboard-managed-process.d.ts +35 -0
  82. package/dist/src/display-width.d.ts +27 -0
  83. package/dist/src/doctor-node-count.d.ts +28 -0
  84. package/dist/src/grok-attach-client.d.ts +129 -0
  85. package/dist/src/grok-build-drift.d.ts +15 -0
  86. package/dist/src/grok-copresence-disclosure.d.ts +11 -0
  87. package/dist/src/grok-copresence-orchestration.d.ts +75 -0
  88. package/dist/src/grok-copresence-profile.d.ts +65 -0
  89. package/dist/src/grok-create-mode.d.ts +19 -0
  90. package/dist/src/host-telemetry.d.ts +14 -0
  91. package/dist/src/hub-health-timeout.d.ts +4 -0
  92. package/dist/src/hub-server-version.d.ts +64 -0
  93. package/dist/src/hub-stop.d.ts +74 -0
  94. package/dist/src/hub-time-display.d.ts +20 -0
  95. package/dist/src/hub-version-skew.d.ts +19 -0
  96. package/dist/src/im/correlation-store.d.ts +34 -0
  97. package/dist/src/im/feishu/adapter.d.ts +43 -0
  98. package/dist/src/im/feishu/bridge.d.ts +78 -14
  99. package/dist/src/im/feishu/hub-upload.d.ts +1 -1
  100. package/dist/src/im/feishu/worker-lifecycle.d.ts +13 -0
  101. package/dist/src/im/feishu/worker.js +174 -161
  102. package/dist/src/inbox-drain.d.ts +20 -0
  103. package/dist/src/local-process-state.d.ts +12 -0
  104. package/dist/src/locale-diagnostic.d.ts +12 -0
  105. package/dist/src/login-client-label.d.ts +6 -0
  106. package/dist/src/ls-columns.d.ts +15 -0
  107. package/dist/src/mock-llm.d.ts +12 -0
  108. package/dist/src/node-activity-log.d.ts +4 -0
  109. package/dist/src/node-clone.d.ts +134 -0
  110. package/dist/src/node-delete-hub.d.ts +42 -0
  111. package/dist/src/node-files.d.ts +62 -0
  112. package/dist/src/node-locate.d.ts +60 -0
  113. package/dist/src/node-ls-all.d.ts +80 -0
  114. package/dist/src/node-menu.d.ts +40 -0
  115. package/dist/src/node-not-found.d.ts +1 -0
  116. package/dist/src/node-remote.d.ts +180 -0
  117. package/dist/src/node-running-guard.d.ts +9 -0
  118. package/dist/src/node-server-identity.d.ts +35 -0
  119. package/dist/src/node-server-payload.d.ts +66 -0
  120. package/dist/src/node-server-rules-file.d.ts +14 -0
  121. package/dist/src/node-server-version.d.ts +39 -0
  122. package/dist/src/node-server.js +8 -1
  123. package/dist/src/node-skills.d.ts +57 -0
  124. package/dist/src/normalize-runtime.d.ts +29 -2
  125. package/dist/src/offline-age.d.ts +29 -0
  126. package/dist/src/one-line-cell.d.ts +20 -0
  127. package/dist/src/opencode-agent-node-pair.d.ts +28 -0
  128. package/dist/src/opencode-auth-login.d.ts +43 -0
  129. package/dist/src/opencode-free-tier.d.ts +27 -0
  130. package/dist/src/opencode-generation-create.d.ts +27 -0
  131. package/dist/src/opencode-generation-record.d.ts +24 -0
  132. package/dist/src/opencode-launch-env.d.ts +13 -0
  133. package/dist/src/opencode-owner-mode.d.ts +6 -0
  134. package/dist/src/opencode-package-binary.d.ts +44 -0
  135. package/dist/src/opencode-pin.d.ts +61 -0
  136. package/dist/src/opencode-preset.d.ts +77 -0
  137. package/dist/src/opencode-runtime-binding.d.ts +30 -0
  138. package/dist/src/opencode-safe-root.d.ts +36 -0
  139. package/dist/src/opencode-shared-server-create.d.ts +5 -0
  140. package/dist/src/opencode-smoke-env.d.ts +1 -0
  141. package/dist/src/opencode-start-mode.d.ts +8 -0
  142. package/dist/src/opencode-v2-configured-model.d.ts +34 -0
  143. package/dist/src/opencode-v2-create-align.d.ts +18 -0
  144. package/dist/src/opencode-versions.d.ts +44 -0
  145. package/dist/src/outbound-attachments.d.ts +60 -0
  146. package/dist/src/outbound-tool-names.d.ts +1 -0
  147. package/dist/src/owned-roots.d.ts +58 -0
  148. package/dist/src/owner-env-file.d.ts +2 -0
  149. package/dist/src/package-mode-preflight.d.ts +41 -0
  150. package/dist/src/posix-codex-copresence.d.ts +33 -0
  151. package/dist/src/posix-modes.d.ts +36 -0
  152. package/dist/src/primary-network.d.ts +23 -0
  153. package/dist/src/private-state.d.ts +10 -0
  154. package/dist/src/process-telemetry.d.ts +12 -0
  155. package/dist/src/profile-serialize.d.ts +1 -0
  156. package/dist/src/project-key.d.ts +1 -0
  157. package/dist/src/provider-application-contract.d.ts +11 -0
  158. package/dist/src/provider-apply.d.ts +28 -0
  159. package/dist/src/provider-presets.d.ts +76 -0
  160. package/dist/src/reply-local-links.d.ts +47 -0
  161. package/dist/src/reply-originator.d.ts +20 -0
  162. package/dist/src/resume-runtime-infer.d.ts +18 -0
  163. package/dist/src/rules-file.d.ts +53 -0
  164. package/dist/src/scoped-secrets.d.ts +33 -0
  165. package/dist/src/secret-shell-guidance.d.ts +4 -0
  166. package/dist/src/session-status-class.d.ts +48 -0
  167. package/dist/src/shared/opencode-borrowed-launch-health.d.ts +29 -0
  168. package/dist/src/shared/provider-collection.d.ts +9 -0
  169. package/dist/src/shared/provider-initialization.d.ts +7 -0
  170. package/dist/src/shared/reserved-env.d.ts +3 -0
  171. package/dist/src/shared/scoped-secret-contract.d.ts +1 -0
  172. package/dist/src/shared/scoped-secret-env.d.ts +3 -0
  173. package/dist/src/sibling-agent-node.d.ts +23 -0
  174. package/dist/src/stale-socket.d.ts +118 -0
  175. package/dist/src/standalone-bin.d.ts +101 -0
  176. package/dist/src/standalone-build-stamp.d.ts +33 -0
  177. package/dist/src/start-resource-gate.d.ts +146 -0
  178. package/dist/src/stopped-receipt.d.ts +8 -0
  179. package/dist/src/subcommand-redirect.d.ts +26 -0
  180. package/dist/src/task-trace.d.ts +33 -0
  181. package/dist/src/tmux-attach.d.ts +11 -0
  182. package/dist/src/tmux-capability.d.ts +58 -0
  183. package/dist/src/tmux-exact-target.d.ts +36 -0
  184. package/dist/src/tmux-format.d.ts +20 -0
  185. package/dist/src/tmux-pane-prompt.d.ts +22 -0
  186. package/dist/src/tmux.d.ts +44 -0
  187. package/dist/src/token-cli.d.ts +13 -0
  188. package/dist/src/tool-allowlist.d.ts +28 -0
  189. package/dist/src/unsafe-package-path-reason.d.ts +31 -0
  190. package/dist/src/upgrade-channel.d.ts +31 -0
  191. package/dist/src/win-launcher.d.ts +20 -0
  192. package/dist/src/windows-codex-copresence.d.ts +60 -0
  193. package/package.json +15 -7
@@ -0,0 +1,39 @@
1
+ export interface RecoveryLease {
2
+ release: () => void;
3
+ }
4
+ export interface RecoveryLeaseHolderDeps {
5
+ /** Register `fn` to run when the process exits; returns an unregister function.
6
+ * Defaults to process.on("exit"), which also covers `process.exit(1)` failure paths. */
7
+ onProcessExit?: (fn: () => void) => () => void;
8
+ log?: (message: string) => void;
9
+ }
10
+ export interface RecoveryLeaseHolder {
11
+ /** Take ownership of a lease returned by waitForCodexRecoveryResources. */
12
+ hold(lease: RecoveryLease): void;
13
+ /** Release the held lease (stops its heartbeat and drops the slot). Idempotent. */
14
+ release(reason?: string): void;
15
+ readonly held: boolean;
16
+ }
17
+ export declare function createRecoveryLeaseHolder(deps?: RecoveryLeaseHolderDeps): RecoveryLeaseHolder;
18
+ export interface CopresencePieces {
19
+ /** `--tui-first`: restore the exact-session TUI before the bridge attaches. */
20
+ tuiFirst: boolean;
21
+ /** Piece ②: starts the bridge and resolves once it reported READY. */
22
+ launchBridge: () => Promise<void>;
23
+ /** Piece ③: starts the TUI session ("③ TUI … ready to attach"). */
24
+ launchTui: () => void;
25
+ /** Resolves once the TUI has painted a usable screen. */
26
+ requireTuiPainted: () => Promise<void>;
27
+ /** The TUI's own process tree must connect to the exact app-server; paint alone
28
+ * can precede WebSocket hydration and does not release the recovery lane. */
29
+ requireTuiConnected: () => Promise<void>;
30
+ /** Runs once both sessions were launched (marker refresh, liveness check). */
31
+ afterLaunch?: () => void;
32
+ /** Printed between the TUI paint and the bridge attach on the --tui-first path. */
33
+ announceTuiFirst?: () => void;
34
+ lease: RecoveryLeaseHolder;
35
+ }
36
+ /** Bring up the bridge and the TUI in the configured order, then release the
37
+ * recovery lease: the legacy resume (bridge) and the TUI hydration are the
38
+ * memory-heavy part the lane protects. The lease is released on failure too. */
39
+ export declare function launchCopresencePiecesReleasingRecovery(p: CopresencePieces): Promise<void>;
@@ -0,0 +1,15 @@
1
+ import { waitForStartResources, type StartGateDeps, type StartGateResult } from "./start-resource-gate";
2
+ /** A measured 500 MiB legacy recovery peaked at 8.4x its rollout size. Nine
3
+ * times the rollout leaves a small margin while remaining an explainable,
4
+ * testable admission estimate rather than pretending maxPayload bounds Codex. */
5
+ export declare const CODEX_RECOVERY_MEMORY_MULTIPLIER = 9;
6
+ export declare const CODEX_RECOVERY_MIN_MEMORY_MB = 4096;
7
+ export declare function estimatedCodexRecoveryMemoryMb(rolloutBytes: number | null): number;
8
+ export interface CodexRecoveryGateDeps extends StartGateDeps {
9
+ /** @internal seam: the shared start gate owns locking and stale-lease safety. */
10
+ gate?: typeof waitForStartResources;
11
+ }
12
+ /** Serialize the memory-heavy legacy resume phase and require enough effective
13
+ * MemAvailable for this rollout. The returned lease stays held through the
14
+ * launcher, bridge and TUI attachment and must then be released. */
15
+ export declare function waitForCodexRecoveryResources(nodeId: string, rolloutBytes: number | null, deps?: CodexRecoveryGateDeps): Promise<StartGateResult>;
@@ -0,0 +1,89 @@
1
+ import { type ExternalThread } from "./codex-adopt";
2
+ import { type CollectEnv, type CodexMenuNode } from "./codex-menu";
3
+ export type CodexResumeKind = "co-presence" | "codex-sdk";
4
+ export interface CodexResumeFacts {
5
+ readonly alias: string;
6
+ readonly kind: CodexResumeKind;
7
+ /** "running" | "stopped" | "partial 1/3" (codex-menu's row.state). */
8
+ readonly state: string;
9
+ readonly running: boolean;
10
+ /** The CODEX_HOME the node's codex runs with (its own, or the host ~/.codex for a codex-sdk node). */
11
+ readonly codexHome: string;
12
+ readonly homeExists: boolean;
13
+ /** true = codex's default ~/.codex (no CODEX_HOME needed to log it in). */
14
+ readonly homeIsHost: boolean;
15
+ readonly loggedIn: boolean;
16
+ /** codexThreadId (co-presence) / session (codex-sdk) from the node config. */
17
+ readonly recordedThread: string | null;
18
+ /** Every rollout under `<codexHome>/sessions`, newest first. */
19
+ readonly threads: readonly ExternalThread[];
20
+ }
21
+ export interface CodexResumeRequest {
22
+ /** --thread <id|unique prefix> (also --session <id>, the old spelling). */
23
+ readonly thread?: string | null;
24
+ readonly pick?: boolean;
25
+ /** stdin and stdout are both a terminal. */
26
+ readonly tty: boolean;
27
+ }
28
+ export type CodexResumeDecision =
29
+ /** Nothing was done. `lines[0]` is the reason with the fix; exit with `code`. */
30
+ {
31
+ readonly kind: "refuse";
32
+ readonly code: number;
33
+ readonly lines: readonly string[];
34
+ }
35
+ /** --pick without a terminal: the list plus a copy-paste command. Nothing was done. */
36
+ | {
37
+ readonly kind: "list";
38
+ readonly code: number;
39
+ readonly lines: readonly string[];
40
+ }
41
+ /** --pick in a terminal: show `lines`, ask for a number in 1..`choices.length`. */
42
+ | {
43
+ readonly kind: "ask";
44
+ readonly lines: readonly string[];
45
+ readonly choices: readonly string[];
46
+ }
47
+ /** Already running on exactly that thread — attach instead (exit 0). */
48
+ | {
49
+ readonly kind: "already";
50
+ readonly lines: readonly string[];
51
+ }
52
+ /** Go: record `threadId` (when `changed`) and start the node. */
53
+ | {
54
+ readonly kind: "resume";
55
+ readonly threadId: string;
56
+ readonly changed: boolean;
57
+ readonly rolloutPath: string;
58
+ };
59
+ /** How many threads the picker numbers; older ones are reachable with --thread. */
60
+ export declare const PICK_LIMIT = 20;
61
+ export declare function freshStartCommand(f: Pick<CodexResumeFacts, "alias" | "kind">): string;
62
+ export declare function codexLoginCommand(f: Pick<CodexResumeFacts, "codexHome" | "homeIsHost">): string;
63
+ /** Numbered rows: time (UTC, as codex wrote it), short id, first user line. The recorded thread is marked. */
64
+ export declare function formatNodeThreadList(threads: readonly ExternalThread[], recorded: string | null, limit?: number): string[];
65
+ export declare function resumeCommandFor(alias: string, threadId: string): string;
66
+ /** The whole decision. Order: request shape → home → which thread → login → process state. */
67
+ export declare function decideCodexResume(f: CodexResumeFacts, req: CodexResumeRequest): CodexResumeDecision;
68
+ /** A typed answer to the picker: a number from the list; empty / q = cancel. */
69
+ export declare function parsePickAnswer(answer: string | null, choices: readonly string[]): {
70
+ kind: "ok";
71
+ threadId: string;
72
+ } | {
73
+ kind: "cancel";
74
+ } | {
75
+ kind: "bad";
76
+ message: string;
77
+ };
78
+ /**
79
+ * `anet node codex resume` records the thread in config before its state
80
+ * machine runs. If the run stops before anything was touched, the old value
81
+ * goes back — the config must not name a thread the node is not running (#531 §5).
82
+ */
83
+ export declare function resumeConfigShouldRollBack(stoppedAt: string): boolean;
84
+ /**
85
+ * The facts for one node, from the same helpers the codex menu uses
86
+ * (collectCodexRows: kind / state / login; effectiveCodexHome: which home).
87
+ * Read-only. null = not a codex node.
88
+ */
89
+ export declare function gatherCodexResumeFacts(node: CodexMenuNode, env: CollectEnv): CodexResumeFacts | null;
@@ -0,0 +1,84 @@
1
+ /** First codex release that writes paginated rollouts with per-line ordinals. */
2
+ export declare const PAGINATED_ROLLOUT_MIN_CODEX = "0.145.0";
3
+ /** Read the first line in chunks of this size … */
4
+ export declare const FIRST_LINE_CHUNK_BYTES: number;
5
+ /** … and give up (do not block) when no newline shows up within this many bytes. */
6
+ export declare const FIRST_LINE_MAX_BYTES: number;
7
+ export declare const BOARD_REF = "board #734";
8
+ export interface FirstLineRead {
9
+ /** The first line without its newline; null when it could not be read. */
10
+ line: string | null;
11
+ /** How many bytes were actually read from the file. */
12
+ bytesRead: number;
13
+ /** Why `line` is null. */
14
+ reason?: string;
15
+ }
16
+ /** Bounded read of the first line. Never reads past `maxBytes`. */
17
+ export declare function readRolloutFirstLine(path: string, maxBytes?: number, chunkBytes?: number): FirstLineRead;
18
+ export type HistoryModeParse = {
19
+ ok: true;
20
+ historyMode: string | null;
21
+ } | {
22
+ ok: false;
23
+ reason: string;
24
+ };
25
+ /** `payload.history_mode` of the session-meta line; null when the field is absent (legacy rollout). */
26
+ export declare function parseRolloutHistoryMode(line: string): HistoryModeParse;
27
+ /** <0, 0, >0 — numeric `x.y.z` compare; null when either side is not a version. */
28
+ export declare function compareVersions(a: string, b: string): number | null;
29
+ /**
30
+ * Version from `codex --version` output. Only a codex-identifying token counts
31
+ * (`codex-cli 0.159.2`, `codex 0.145.0`): a wrapper that prints its own version
32
+ * first (`nvm 0.39.7`) must not be read as the codex version. No match = unknown.
33
+ */
34
+ export declare function parseCodexVersionOutput(text: string | undefined | null): string | null;
35
+ /** `<bin> --version` → `x.y.z`, cached per binary for the life of the process. */
36
+ export declare function probeCodexVersionCached(bin: string, timeoutMs?: number): string | null;
37
+ /**
38
+ * The rollout codex would resume for `threadId`, following codex's own filesystem
39
+ * order (codex-rs thread-store thread_rollout_resolver): `sessions/` first, newest
40
+ * matching file wins; `archived_sessions/` only when nothing is in `sessions/`.
41
+ * (codex consults its SQLite index before the filesystem; that index is not read here.)
42
+ * The ONE resolver every anet guard uses (co-presence launchers and agent-node).
43
+ */
44
+ export declare function resolveCodexResumeRollout(codexHome: string, threadId: string): string | null;
45
+ export interface RolloutCompatInput {
46
+ threadId: string;
47
+ /** Exact rollout path, or null when the caller could not find one. */
48
+ rolloutPath: string | null;
49
+ /** How the operator would name the binary (path or command). */
50
+ codexBin: string;
51
+ /** Parsed version of `codexBin`; null/undefined = unknown. */
52
+ codexVersion: string | null | undefined;
53
+ /** How to point THIS node at another codex (one line per option). */
54
+ pointAtNewerCodex: string[];
55
+ /** Injected for tests; defaults to the bounded reader. */
56
+ readFirstLine?: (path: string) => FirstLineRead;
57
+ }
58
+ export type RolloutCompatVerdict = {
59
+ verdict: "block";
60
+ lines: string[];
61
+ historyMode: string;
62
+ codexVersion: string;
63
+ } | {
64
+ verdict: "allow";
65
+ historyMode: string | null;
66
+ codexVersion: string | null;
67
+ } | {
68
+ verdict: "unknown";
69
+ lines: string[];
70
+ };
71
+ /**
72
+ * Decide whether starting `codexBin` on `threadId` is safe.
73
+ * block — paginated rollout + codex < 0.145: starting would make the thread unresumable.
74
+ * allow — legacy rollout, or codex new enough.
75
+ * unknown — could not tell; caller must NOT block (warn and continue as before).
76
+ */
77
+ export declare function checkRolloutCodexCompat(input: RolloutCompatInput): RolloutCompatVerdict;
78
+ export declare const MISSING_ORDINAL_RE: RegExp;
79
+ export declare function isMissingOrdinalError(text: string): boolean;
80
+ /** Explanation for the upstream "missing an ordinal" resume failure; [] when `text` is something else. */
81
+ export declare function describeMissingOrdinalFailure(text: string, ctx?: {
82
+ threadId?: string;
83
+ rolloutPath?: string | null;
84
+ }): string[];
@@ -0,0 +1,30 @@
1
+ export declare function bridgeClientHealthReceipt(remote: string, threadId: string): string;
2
+ export interface MigratedCodexPendingThread {
3
+ version: 1;
4
+ threadId: string;
5
+ serverUrl: string;
6
+ marker: string;
7
+ }
8
+ /**
9
+ * Move a crash-window deferred candidate onto the launcher's new owned
10
+ * app-server generation. The old URL is an authority supplied by the same
11
+ * private node config, not by the pending object itself; every mismatch is a
12
+ * hard stop so restart never guesses or adopts a second thread.
13
+ */
14
+ export declare function migrateCodexPendingThread(value: unknown, oldServerUrl: unknown, expectedOldMarker: unknown, newServerUrl: string, newMarker: string): MigratedCodexPendingThread;
15
+ export declare function requirePromotedCodexPendingThread(value: unknown, pendingThreadId: string): string;
16
+ /**
17
+ * argv for the human TUI attached to the co-presence app-server.
18
+ *
19
+ * #505 — the permission override is only passed on the FRESH path. On
20
+ * `resume --remote <ws> <thread>` codex 0.155.1 exits immediately with
21
+ * "Error: Permission overrides are not supported when resuming a remote task."
22
+ * (anet then reports "TUI tmux session exited during startup"). Measured in
23
+ * Docker against a real app-server + real thread: 0.155.1 rejects
24
+ * resume + --dangerously-bypass-approvals-and-sandbox and accepts it fresh
25
+ * (TUI up, "permissions: YOLO mode"); 0.133.0 (agent-node's pin) accepts both.
26
+ * Nothing is lost by dropping it on resume: the app-server itself is started
27
+ * with `-c approval_policy=… -c sandbox_mode=…` from the same posture.
28
+ */
29
+ export declare function codexTuiLaunchArgs(remote: string, model: string, threadId?: string, dangerFullAccess?: boolean): string[];
30
+ export declare function assertPendingServerQuiesced(serverUrl: unknown, isListening: (port: number) => boolean | Promise<boolean>): Promise<void>;
@@ -0,0 +1 @@
1
+ export declare function parseCommhubToolResult(json: any): any;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * #693 — token-bound node controlled local file → Hub /api/upload bridge.
3
+ *
4
+ * Security boundary (hard gates):
5
+ * 1. Cross-host: bytes travel over HTTP multipart; Hub never reads agent FS.
6
+ * 2. Identity: caller supplies the node's bearer token; ntok binds network.
7
+ * 3. Path safety: realpath + allowlisted roots; reject NUL, symlink, traversal.
8
+ * 4. Size ≤ 12 MiB enforced with same-fd fstat + bounded read (no full slurp).
9
+ * 5. Hub /api/upload is the sole write surface (atomic on hub side).
10
+ *
11
+ * Adversarial add-only (#694 DO-NOT-MERGE fixes):
12
+ * - TOCTOU: open O_NOFOLLOW → fstat(fd) → read(fd) only; no re-open by path.
13
+ * - Bounded read: never allocate/read past CONTROLLED_UPLOAD_MAX_BYTES.
14
+ * - NUL guard is live and reachable before any fs call.
15
+ */
16
+ /** Mirrors server/src/uploads.ts MAX_UPLOAD_BYTES. */
17
+ export declare const CONTROLLED_UPLOAD_MAX_BYTES: number;
18
+ /** Chunk size for bounded streaming read from a single fd. */
19
+ export declare const CONTROLLED_UPLOAD_READ_CHUNK: number;
20
+ export type ControlledUploadErrorCode = "path_required" | "path_nul" | "path_not_found" | "path_untrusted" | "path_symlink" | "path_not_regular" | "path_empty" | "payload_too_large" | "read_failed" | "auth_required" | "hub_url_required" | "upload_failed" | "bad_response" | "missing_file_id";
21
+ export type ControlledUploadFail = {
22
+ ok: false;
23
+ error: ControlledUploadErrorCode;
24
+ message: string;
25
+ };
26
+ export type ControlledUploadOk = {
27
+ ok: true;
28
+ file_id: string;
29
+ name: string;
30
+ mime: string;
31
+ size: number;
32
+ url?: string;
33
+ };
34
+ export type ControlledUploadResult = ControlledUploadOk | ControlledUploadFail;
35
+ export interface ControlledUploadDeps {
36
+ hubUrl: string;
37
+ authToken: string;
38
+ allowedRoots?: string[];
39
+ alias?: string;
40
+ nodeDir?: string;
41
+ fetch?: typeof fetch;
42
+ home?: string;
43
+ }
44
+ /** Normalize a client filename: basename only, strip controls, cap 255. */
45
+ export declare function normalizeUploadName(input: string | undefined | null, fallback?: string): string;
46
+ export declare function defaultControlledUploadRoots(opts?: {
47
+ home?: string;
48
+ alias?: string;
49
+ nodeDir?: string;
50
+ cwd?: string;
51
+ env?: NodeJS.ProcessEnv;
52
+ }): string[];
53
+ /** True iff canonicalPath is strictly inside one of the allowlisted roots. */
54
+ export declare function isPathInsideAllowedRoots(canonicalPath: string, allowedRoots: string[]): boolean;
55
+ /**
56
+ * Resolve a user-supplied path to a canonical path under an allowlisted root.
57
+ * Does not open the file for reading — open+fstat+read is a separate same-fd step.
58
+ */
59
+ export declare function resolveControlledUploadPath(rawPath: string, allowedRoots: string[]): {
60
+ ok: true;
61
+ canonicalPath: string;
62
+ } | ControlledUploadFail;
63
+ export type ControlledFileBytes = {
64
+ ok: true;
65
+ bytes: Buffer;
66
+ size: number;
67
+ canonicalPath: string;
68
+ } | ControlledUploadFail;
69
+ /**
70
+ * Open → fstat(fd) → bounded read(fd) on the **same fd** (TOCTOU hard gate).
71
+ * Uses O_NOFOLLOW when available so a symlink swap at open is rejected.
72
+ * Never uses path-based readFileSync after the initial open.
73
+ */
74
+ export declare function openFstatBoundedReadControlledFile(canonicalPath: string, allowedRoots: string[], maxBytes?: number): ControlledFileBytes;
75
+ /**
76
+ * Upload a controlled local file to Hub POST /api/upload.
77
+ * Returns file_id + metadata for send_reply attachments.
78
+ * Never falls back to sending a raw path to the Hub.
79
+ */
80
+ export declare function uploadControlledLocalFile(rawPath: string, deps: ControlledUploadDeps, opts?: {
81
+ name?: string;
82
+ mime?: string;
83
+ }): Promise<ControlledUploadResult>;
@@ -0,0 +1,22 @@
1
+ export interface CopresenceDep {
2
+ readonly name: string;
3
+ readonly present: boolean;
4
+ /** Exact command for this platform, or null when we cannot name one. */
5
+ readonly install: string | null;
6
+ readonly why: string;
7
+ }
8
+ export type CommandProbe = (cmd: string) => boolean;
9
+ /** Which agent binary this co-presence lane is built on. */
10
+ export type CopresenceAgent = "codex" | "grok";
11
+ export declare function copresenceDeps(probe: CommandProbe, platform?: NodeJS.Platform, agent?: CopresenceAgent): CopresenceDep[];
12
+ export declare function missingCopresenceDeps(probe: CommandProbe, platform?: NodeJS.Platform, agent?: CopresenceAgent): CopresenceDep[];
13
+ /** One block naming every gap and how to close it — never one gap at a time. */
14
+ export declare function describeMissingDeps(missing: readonly CopresenceDep[], displayName: string): string;
15
+ /**
16
+ * May we start this hub ourselves?
17
+ *
18
+ * Only a loopback hub. A remote URL that refuses the connection is somebody
19
+ * else's service — spawning a local one would silently point the node at a
20
+ * DIFFERENT hub than its profile names, which is worse than failing.
21
+ */
22
+ export declare function isLoopbackHub(hubUrl: string): boolean;