@sleep2agi/agent-network 2.3.0-preview.14 → 2.3.0-preview.140

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 (151) 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/bin/goal-wake-log-render.d.ts +31 -0
  6. package/dist/src/active-network-task.d.ts +28 -0
  7. package/dist/src/batch-workdir.d.ts +9 -0
  8. package/dist/src/bootstrap-password-db.d.ts +13 -0
  9. package/dist/src/channel-attachments.d.ts +29 -0
  10. package/dist/src/channel-inbox-wake.d.ts +21 -0
  11. package/dist/src/channel-meta.d.ts +10 -0
  12. package/dist/src/channel-peer-reply.d.ts +41 -0
  13. package/dist/src/channel-task-trace.d.ts +14 -0
  14. package/dist/src/claude-vendor-env.d.ts +28 -0
  15. package/dist/src/cli-args.d.ts +8 -0
  16. package/dist/src/cli-auth-session.d.ts +47 -0
  17. package/dist/src/cli-errors.d.ts +39 -0
  18. package/dist/src/cli-exit.d.ts +11 -0
  19. package/dist/src/cli-help.d.ts +10 -0
  20. package/dist/src/cli-version-display.d.ts +16 -0
  21. package/dist/src/client-task-trace.d.ts +9 -0
  22. package/dist/src/client.js +1 -1
  23. package/dist/src/codex-adopt.d.ts +46 -0
  24. package/dist/src/codex-auth-fingerprint.d.ts +211 -0
  25. package/dist/src/codex-copresence-bridge-log.d.ts +44 -0
  26. package/dist/src/codex-copresence-login-gate.d.ts +16 -0
  27. package/dist/src/codex-copresence-model.d.ts +23 -0
  28. package/dist/src/codex-copresence-preflight.d.ts +65 -0
  29. package/dist/src/codex-copresence-profile.d.ts +125 -0
  30. package/dist/src/codex-copresence-recovery.d.ts +58 -0
  31. package/dist/src/codex-copresence-thread.d.ts +13 -0
  32. package/dist/src/codex-home-enforce.d.ts +71 -0
  33. package/dist/src/codex-lifecycle-account.d.ts +104 -0
  34. package/dist/src/codex-lifecycle-canary.d.ts +20 -0
  35. package/dist/src/codex-lifecycle-facts.d.ts +53 -0
  36. package/dist/src/codex-lifecycle-fork.d.ts +91 -0
  37. package/dist/src/codex-lifecycle-preflight.d.ts +77 -0
  38. package/dist/src/codex-lifecycle-receipt.d.ts +53 -0
  39. package/dist/src/codex-lifecycle-restart.d.ts +88 -0
  40. package/dist/src/codex-login-share-guard.d.ts +146 -0
  41. package/dist/src/codex-menu.d.ts +78 -0
  42. package/dist/src/codex-model-default.d.ts +6 -0
  43. package/dist/src/codex-node-login.d.ts +98 -0
  44. package/dist/src/codex-resume.d.ts +89 -0
  45. package/dist/src/codex-tui-client-health.d.ts +30 -0
  46. package/dist/src/commhub-response.d.ts +1 -0
  47. package/dist/src/controlled-upload.d.ts +83 -0
  48. package/dist/src/copresence-deps.d.ts +22 -0
  49. package/dist/src/copresence-identity.d.ts +353 -0
  50. package/dist/src/copresence-startup-diagnosis.d.ts +17 -0
  51. package/dist/src/daemon-anet-bin.d.ts +32 -0
  52. package/dist/src/daemon-capability-display.d.ts +110 -0
  53. package/dist/src/daemon-capability-display.js +21 -0
  54. package/dist/src/daemon-runtime-path-preflight.d.ts +22 -0
  55. package/dist/src/daemon-runtime-staleness.d.ts +13 -0
  56. package/dist/src/dashboard-managed-process.d.ts +35 -0
  57. package/dist/src/display-width.d.ts +27 -0
  58. package/dist/src/doctor-node-count.d.ts +28 -0
  59. package/dist/src/environ-alias.d.ts +14 -0
  60. package/dist/src/grok-attach-client.d.ts +129 -0
  61. package/dist/src/grok-build-drift.d.ts +15 -0
  62. package/dist/src/grok-copresence-disclosure.d.ts +11 -0
  63. package/dist/src/grok-copresence-orchestration.d.ts +75 -0
  64. package/dist/src/grok-copresence-profile.d.ts +65 -0
  65. package/dist/src/grok-create-mode.d.ts +19 -0
  66. package/dist/src/host-telemetry.d.ts +14 -0
  67. package/dist/src/hub-health-timeout.d.ts +4 -0
  68. package/dist/src/hub-server-version.d.ts +64 -0
  69. package/dist/src/hub-stop.d.ts +74 -0
  70. package/dist/src/hub-time-display.d.ts +20 -0
  71. package/dist/src/hub-version-skew.d.ts +19 -0
  72. package/dist/src/im/correlation-store.d.ts +34 -0
  73. package/dist/src/im/feishu/adapter.d.ts +80 -0
  74. package/dist/src/im/feishu/bridge.d.ts +78 -14
  75. package/dist/src/im/feishu/config.d.ts +31 -0
  76. package/dist/src/im/feishu/hub-upload.d.ts +88 -0
  77. package/dist/src/im/feishu/outbound-route.d.ts +62 -0
  78. package/dist/src/im/feishu/worker-lifecycle.d.ts +13 -0
  79. package/dist/src/im/feishu/worker.js +187 -144
  80. package/dist/src/im/types.d.ts +30 -1
  81. package/dist/src/inbox-drain.d.ts +20 -0
  82. package/dist/src/local-process-state.d.ts +12 -0
  83. package/dist/src/locale-diagnostic.d.ts +12 -0
  84. package/dist/src/login-client-label.d.ts +6 -0
  85. package/dist/src/ls-columns.d.ts +15 -0
  86. package/dist/src/mock-llm.d.ts +12 -0
  87. package/dist/src/node-activity-log.d.ts +4 -0
  88. package/dist/src/node-clone.d.ts +134 -0
  89. package/dist/src/node-delete-hub.d.ts +42 -0
  90. package/dist/src/node-files.d.ts +62 -0
  91. package/dist/src/node-locate.d.ts +60 -0
  92. package/dist/src/node-not-found.d.ts +1 -0
  93. package/dist/src/node-running-guard.d.ts +9 -0
  94. package/dist/src/node-server-identity.d.ts +35 -0
  95. package/dist/src/node-server-payload.d.ts +66 -0
  96. package/dist/src/node-server-rules-file.d.ts +14 -0
  97. package/dist/src/node-server-version.d.ts +39 -0
  98. package/dist/src/node-server.js +8 -1
  99. package/dist/src/node-skills.d.ts +32 -0
  100. package/dist/src/normalize-runtime.d.ts +29 -2
  101. package/dist/src/offline-age.d.ts +29 -0
  102. package/dist/src/one-line-cell.d.ts +20 -0
  103. package/dist/src/opencode-agent-node-pair.d.ts +25 -0
  104. package/dist/src/opencode-auth-login.d.ts +43 -0
  105. package/dist/src/opencode-free-tier.d.ts +27 -0
  106. package/dist/src/opencode-generation-create.d.ts +27 -0
  107. package/dist/src/opencode-generation-record.d.ts +24 -0
  108. package/dist/src/opencode-launch-env.d.ts +13 -0
  109. package/dist/src/opencode-owner-mode.d.ts +6 -0
  110. package/dist/src/opencode-package-binary.d.ts +44 -0
  111. package/dist/src/opencode-pin.d.ts +61 -0
  112. package/dist/src/opencode-preset.d.ts +73 -0
  113. package/dist/src/opencode-runtime-binding.d.ts +30 -0
  114. package/dist/src/opencode-safe-root.d.ts +36 -0
  115. package/dist/src/opencode-smoke-env.d.ts +1 -0
  116. package/dist/src/opencode-versions.d.ts +44 -0
  117. package/dist/src/outbound-attachments.d.ts +60 -0
  118. package/dist/src/outbound-tool-names.d.ts +1 -0
  119. package/dist/src/owned-roots.d.ts +58 -0
  120. package/dist/src/owner-env-file.d.ts +2 -0
  121. package/dist/src/package-mode-preflight.d.ts +41 -0
  122. package/dist/src/posix-codex-copresence.d.ts +35 -0
  123. package/dist/src/posix-modes.d.ts +36 -0
  124. package/dist/src/primary-network.d.ts +23 -0
  125. package/dist/src/private-state.d.ts +10 -0
  126. package/dist/src/process-telemetry.d.ts +12 -0
  127. package/dist/src/profile-serialize.d.ts +1 -0
  128. package/dist/src/project-key.d.ts +1 -0
  129. package/dist/src/reply-local-links.d.ts +47 -0
  130. package/dist/src/reply-originator.d.ts +20 -0
  131. package/dist/src/resume-runtime-infer.d.ts +18 -0
  132. package/dist/src/rules-file.d.ts +53 -0
  133. package/dist/src/secret-shell-guidance.d.ts +4 -0
  134. package/dist/src/session-status-class.d.ts +48 -0
  135. package/dist/src/sibling-agent-node.d.ts +23 -0
  136. package/dist/src/stale-socket.d.ts +118 -0
  137. package/dist/src/subcommand-redirect.d.ts +26 -0
  138. package/dist/src/task-trace.d.ts +33 -0
  139. package/dist/src/tmux-attach.d.ts +11 -0
  140. package/dist/src/tmux-capability.d.ts +58 -0
  141. package/dist/src/tmux-exact-target.d.ts +36 -0
  142. package/dist/src/tmux-format.d.ts +20 -0
  143. package/dist/src/tmux-pane-prompt.d.ts +22 -0
  144. package/dist/src/tmux.d.ts +44 -0
  145. package/dist/src/token-cli.d.ts +13 -0
  146. package/dist/src/tool-allowlist.d.ts +28 -0
  147. package/dist/src/unsafe-package-path-reason.d.ts +31 -0
  148. package/dist/src/upgrade-channel.d.ts +31 -0
  149. package/dist/src/win-launcher.d.ts +20 -0
  150. package/dist/src/windows-codex-copresence.d.ts +60 -0
  151. package/package.json +11 -6
@@ -0,0 +1,78 @@
1
+ export type CodexKind = "co-presence" | "codex-sdk";
2
+ export interface CodexMenuNode {
3
+ id: string;
4
+ alias: string;
5
+ profile: Record<string, any> | null;
6
+ }
7
+ export interface CodexNodeRow {
8
+ id: string;
9
+ alias: string;
10
+ kind: CodexKind;
11
+ /** "running" | "stopped" | "partial 1/3" … */
12
+ state: string;
13
+ running: boolean;
14
+ loggedIn: boolean;
15
+ /** Where the login lives: the node's own CODEX_HOME, or the host's ~/.codex. */
16
+ loginWhere: "node" | "host";
17
+ /** Absolute CODEX_HOME for `codex login`; null = codex's own default (~/.codex). */
18
+ codexHome: string | null;
19
+ threadId: string | null;
20
+ model: string;
21
+ modelIsDefault: boolean;
22
+ }
23
+ export interface CollectEnv {
24
+ nodesDir: string;
25
+ /** $HOME — only used to locate the host's ~/.codex/auth.json. */
26
+ home: string;
27
+ /** The environment a start would inherit (CODEX_HOME); defaults to process.env. */
28
+ env?: Record<string, string | undefined>;
29
+ /** Exact tmux session names on the server anet uses (empty when none). */
30
+ tmuxSessions?: () => Set<string>;
31
+ pidAlive?: (pid: number) => boolean;
32
+ }
33
+ /** Only codex nodes: co-presence (codex-app-server) and codex-sdk. */
34
+ export declare function collectCodexRows(nodes: CodexMenuNode[], env: CollectEnv): CodexNodeRow[];
35
+ export declare function renderCodexTable(rows: CodexNodeRow[], cwd: string): string;
36
+ export declare const CODEX_CHEAT_SHEET: string;
37
+ export type MenuAction = "start" | "stop" | "restart" | "verify" | "login" | "continue" | "pick" | "model" | "copy" | "delete";
38
+ export declare const MENU_ACTIONS: {
39
+ key: MenuAction;
40
+ label: string;
41
+ }[];
42
+ export interface PlannedCommand {
43
+ /** argv[0] is "anet" (re-invoke this CLI) or "codex". */
44
+ argv: string[];
45
+ /** Extra env for the child (only CODEX_HOME for login). */
46
+ env?: Record<string, string>;
47
+ /** Shown before the confirm prompt, after the command. */
48
+ note?: string;
49
+ /** Shown after the command succeeded. */
50
+ after?: string;
51
+ }
52
+ export declare function displayQuote(v: string): string;
53
+ export declare function commandLine(cmd: PlannedCommand): string;
54
+ export interface ActionInput {
55
+ model?: string;
56
+ newName?: string;
57
+ workdir?: string;
58
+ }
59
+ /** #528 — not about an existing node: turn a codex conversation started outside anet into a new one. */
60
+ export declare const ADOPT_KEY = "a";
61
+ export declare function planAdopt(newName: string): PlannedCommand;
62
+ export declare function planAction(row: CodexNodeRow, action: MenuAction, input?: ActionInput): PlannedCommand;
63
+ export interface MenuIO {
64
+ write(s: string): void;
65
+ /** Resolves to the next line, or null at end of input. */
66
+ readLine(prompt: string): Promise<string | null>;
67
+ }
68
+ export type Runner = (cmd: PlannedCommand) => Promise<number>;
69
+ /** Returns the process exit code. Runs at most one command. */
70
+ export declare function codexMenu(rows: CodexNodeRow[], io: MenuIO, run: Runner, ctx: {
71
+ cwd: string;
72
+ }): Promise<number>;
73
+ /** Entry from cli.ts (`anet node codex` with no arguments). Returns the exit code. */
74
+ export declare function runCodexMenu(nodes: CodexMenuNode[], opts: {
75
+ nodesDir: string;
76
+ home: string;
77
+ cwd?: string;
78
+ }): Promise<number>;
@@ -0,0 +1,6 @@
1
+ export declare const DEFAULT_CODEX_MODEL = "gpt-5.6-sol";
2
+ export declare const CODEX_MODEL_CHOICES: ReadonlyArray<{
3
+ readonly id: string;
4
+ readonly default?: boolean;
5
+ }>;
6
+ export declare function defaultCodexModelForRuntime(runtime: string): string | undefined;
@@ -0,0 +1,98 @@
1
+ export type CodexLoginKind = "chatgpt" | "api-key" | "none" | "unreadable";
2
+ export interface CodexLoginFacts {
3
+ readonly loggedIn: boolean;
4
+ readonly kind: CodexLoginKind;
5
+ /** #1918 refresh-chain fingerprint (8 hex) — what actually collides. */
6
+ readonly loginFingerprint: string | null;
7
+ /** #1856 account fingerprint (sha256(account_id), 16 hex). */
8
+ readonly accountFingerprint: string | null;
9
+ /** `email` claim of the id_token, when present. Not a credential. */
10
+ readonly email: string | null;
11
+ }
12
+ /** What an auth.json says about a login — without ever returning a token. */
13
+ export declare function codexLoginFactsFromText(text: string | null): CodexLoginFacts;
14
+ export declare function codexLoginFactsOfHome(codexHome: string): CodexLoginFacts;
15
+ export interface NodeConfigLike {
16
+ runtime?: unknown;
17
+ codexCopresence?: unknown;
18
+ codexHome?: unknown;
19
+ env?: unknown;
20
+ alias?: unknown;
21
+ node_name?: unknown;
22
+ name?: unknown;
23
+ }
24
+ /** A node whose runtime runs codex. */
25
+ export declare function isCodexNodeConfig(cfg: NodeConfigLike | null | undefined): boolean;
26
+ export type EffectiveCodexHomeSource = "config.codexHome" | "node-codex-home" | "config.env" | "environment" | "default";
27
+ /**
28
+ * The CODEX_HOME this node's codex process will get — the same decision
29
+ * `applyNodeCodexHome` makes on start: the node's own value; otherwise an
30
+ * inherited CODEX_HOME unless it is another node's codex-home; otherwise
31
+ * codex's default `~/.codex`.
32
+ */
33
+ export declare function effectiveCodexHome(nodeDir: string, cfg: NodeConfigLike | null, env: Record<string, string | undefined>, home: string): {
34
+ codexHome: string;
35
+ source: EffectiveCodexHomeSource;
36
+ };
37
+ export interface LoginNextStepInput {
38
+ readonly alias: string;
39
+ readonly codexHome: string;
40
+ /** Does the codex-home directory exist yet? codex 0.133 refuses a CODEX_HOME that does not. */
41
+ readonly homeExists: boolean;
42
+ /** e.g. `anet node start <alias>`; printed as what comes after the login. */
43
+ readonly then?: string;
44
+ }
45
+ /**
46
+ * The one next step for a codex node without a login. Plain text, no token,
47
+ * nothing executed. `--device-auth` is in `codex login --help` of the pinned
48
+ * codex (agent-node depends on @openai/codex ^0.133; checked on 0.133.0).
49
+ */
50
+ export declare function codexLoginNextStepLines(i: LoginNextStepInput): string[];
51
+ export interface CreateLoginGapInput {
52
+ readonly nodeDir: string;
53
+ readonly config: NodeConfigLike | null;
54
+ readonly env: Record<string, string | undefined>;
55
+ readonly home: string;
56
+ /**
57
+ * For a co-presence node whose own codex-home has no login: would its first
58
+ * start be allowed to stage the host login (#514 gate says "ok")? Injected so
59
+ * this stays a pure decision; the CLI passes evaluateCodexLoginStaging.
60
+ */
61
+ readonly hostLoginWouldBeStaged: (hostAuthPath: string) => boolean;
62
+ }
63
+ /** null = the node will have a usable login; otherwise the CODEX_HOME to log in. */
64
+ export declare function codexCreateLoginGap(i: CreateLoginGapInput): {
65
+ codexHome: string;
66
+ homeExists: boolean;
67
+ } | null;
68
+ export interface CodexLoginStatusRow {
69
+ alias: string;
70
+ node_id: string | null;
71
+ runtime: string;
72
+ copresence: boolean;
73
+ codex_home: string;
74
+ codex_home_source: EffectiveCodexHomeSource;
75
+ logged_in: boolean;
76
+ login_kind: CodexLoginKind;
77
+ /** #1918 refresh-chain fingerprint (8 hex). */
78
+ login_fingerprint: string | null;
79
+ /** #1856 account fingerprint (16 hex). */
80
+ account_fingerprint: string | null;
81
+ email: string | null;
82
+ /** Other nodes holding the SAME refresh chain — they log each other out. */
83
+ shared_with: string[];
84
+ /** Other nodes logged in to the same account with their OWN login — fine. */
85
+ same_account_as: string[];
86
+ }
87
+ export interface LoginStatusOptions {
88
+ /** `<workspace>/.anet/nodes` */
89
+ readonly nodesRoot: string;
90
+ readonly env: Record<string, string | undefined>;
91
+ readonly home: string;
92
+ /** Host index of published fingerprints (#1918); default under `home`. */
93
+ readonly indexDir?: string;
94
+ }
95
+ /** One row per codex node under `nodesRoot`. Read-only. */
96
+ export declare function codexNodeLoginStatus(o: LoginStatusOptions): CodexLoginStatusRow[];
97
+ /** Human table. Never contains a token: rows carry none. */
98
+ export declare function formatCodexLoginStatus(rows: readonly CodexLoginStatusRow[], workspace: string): string[];
@@ -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,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;