harnery 0.42.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/commander.d.ts +16 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +18 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +95 -52
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +38 -11
- package/dist/commands/diagnostics.d.ts.map +1 -1
- package/dist/commands/diagnostics.js +10 -0
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +22 -7
- package/dist/commands/governor.js +22 -10
- package/dist/commands/inbox.d.ts +1 -1
- package/dist/commands/inbox.d.ts.map +1 -1
- package/dist/commands/inbox.js +55 -2
- package/dist/commands/rm.d.ts.map +1 -1
- package/dist/commands/rm.js +28 -4
- package/dist/commands/servers.d.ts.map +1 -1
- package/dist/commands/servers.js +16 -1
- package/dist/commands/supervisor.d.ts.map +1 -1
- package/dist/commands/supervisor.js +7 -2
- package/dist/commands/toc.d.ts +14 -0
- package/dist/commands/toc.d.ts.map +1 -1
- package/dist/commands/toc.js +7 -4
- package/dist/commands/tunnel.d.ts +65 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +290 -101
- package/dist/commands/web-fetch.d.ts +3 -2
- package/dist/commands/web-fetch.d.ts.map +1 -1
- package/dist/commands/web-fetch.js +25 -19
- package/dist/commands/web.d.ts +7 -1
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +9 -3
- package/dist/commands/workflow.js +24 -30
- package/dist/core/agents/live-authority-v3.d.ts +1 -0
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +11 -0
- package/dist/core/agents/live-lifecycle-v3.d.ts +4 -2
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
- package/dist/core/agents/live-lifecycle-v3.js +28 -7
- package/dist/core/agents/mailbox.d.ts +9 -8
- package/dist/core/agents/mailbox.d.ts.map +1 -1
- package/dist/core/agents/mailbox.js +24 -17
- package/dist/core/agents/render/prompt-context.d.ts +2 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +19 -17
- package/dist/core/agents/render/session-context.d.ts +2 -8
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +64 -43
- package/dist/core/agents/rules/stop-hook.js +3 -3
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +25 -14
- package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-writer.js +5 -0
- package/dist/core/agents/state/names.d.ts +43 -3
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +87 -3
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +5 -0
- package/dist/core/agents/state/proc-start.d.ts +19 -0
- package/dist/core/agents/state/proc-start.d.ts.map +1 -1
- package/dist/core/agents/state/proc-start.js +41 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +180 -70
- package/dist/core/agents/state/unchanged-file.d.ts +44 -0
- package/dist/core/agents/state/unchanged-file.d.ts.map +1 -0
- package/dist/core/agents/state/unchanged-file.js +390 -0
- package/dist/core/context/index.d.ts +22 -10
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +381 -119
- package/dist/core/context/observation.d.ts +26 -0
- package/dist/core/context/observation.d.ts.map +1 -0
- package/dist/core/context/observation.js +11 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +25 -14
- package/dist/core/diagnostics/path-identity.d.ts +3 -0
- package/dist/core/diagnostics/path-identity.d.ts.map +1 -0
- package/dist/core/diagnostics/path-identity.js +12 -0
- package/dist/core/diagnostics/sanitize.d.ts.map +1 -1
- package/dist/core/diagnostics/sanitize.js +4 -3
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +29 -0
- package/dist/core/events/v3/generation-custody.d.ts +5 -0
- package/dist/core/events/v3/generation-custody.d.ts.map +1 -0
- package/dist/core/events/v3/generation-custody.js +50 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +1 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +7 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +77 -64
- package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
- package/dist/core/events/v3/support-storage/pack-reader.js +42 -16
- package/dist/core/governor/planning.d.ts.map +1 -1
- package/dist/core/governor/planning.js +14 -1
- package/dist/core/governor/service-read.d.ts +10 -2
- package/dist/core/governor/service-read.d.ts.map +1 -1
- package/dist/core/governor/service-read.js +105 -22
- package/dist/core/governor/service.d.ts +20 -2
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +72 -47
- package/dist/core/hooks/cli.js +120 -23
- package/dist/core/hooks/fork-lineage.d.ts +40 -0
- package/dist/core/hooks/fork-lineage.d.ts.map +1 -0
- package/dist/core/hooks/fork-lineage.js +62 -0
- package/dist/core/hooks/resolve/transcript.d.ts +16 -0
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +84 -0
- package/dist/core/hooks/shell-rm.d.ts +2 -0
- package/dist/core/hooks/shell-rm.d.ts.map +1 -0
- package/dist/core/hooks/shell-rm.js +105 -0
- package/dist/core/hooks/shell-tokens.d.ts +12 -0
- package/dist/core/hooks/shell-tokens.d.ts.map +1 -0
- package/dist/core/hooks/shell-tokens.js +97 -0
- package/dist/core/hooks/shell-waiter.d.ts.map +1 -1
- package/dist/core/hooks/shell-waiter.js +3 -93
- package/dist/core/inbox/contract.d.ts +2 -1
- package/dist/core/inbox/contract.d.ts.map +1 -1
- package/dist/core/inbox/index.d.ts +2 -0
- package/dist/core/inbox/index.d.ts.map +1 -1
- package/dist/core/inbox/index.js +2 -0
- package/dist/core/inbox/peer-messages.d.ts +37 -0
- package/dist/core/inbox/peer-messages.d.ts.map +1 -0
- package/dist/core/inbox/peer-messages.js +72 -0
- package/dist/core/inbox/service.d.ts +8 -1
- package/dist/core/inbox/service.d.ts.map +1 -1
- package/dist/core/inbox/service.js +67 -21
- package/dist/core/inbox/targets.d.ts +22 -0
- package/dist/core/inbox/targets.d.ts.map +1 -0
- package/dist/core/inbox/targets.js +108 -0
- package/dist/core/inbox/watcher.js +7 -3
- package/dist/core/journal/index.d.ts.map +1 -1
- package/dist/core/journal/index.js +17 -2
- package/dist/core/resources/contract.d.ts +3 -0
- package/dist/core/resources/contract.d.ts.map +1 -1
- package/dist/core/resources/service-status.d.ts +14 -1
- package/dist/core/resources/service-status.d.ts.map +1 -1
- package/dist/core/resources/service-status.js +23 -13
- package/dist/core/resources/service.d.ts +9 -1
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +47 -27
- package/dist/core/resources/status.d.ts +2 -5
- package/dist/core/resources/status.d.ts.map +1 -1
- package/dist/core/resources/status.js +36 -7
- package/dist/core/semantic/contract.d.ts +5 -5
- package/dist/core/servers/index.d.ts +24 -13
- package/dist/core/servers/index.d.ts.map +1 -1
- package/dist/core/servers/index.js +132 -92
- package/dist/core/servers/tunnels.d.ts +3 -5
- package/dist/core/servers/tunnels.d.ts.map +1 -1
- package/dist/core/servers/tunnels.js +3 -9
- package/dist/core/storage/process-log.d.ts +12 -0
- package/dist/core/storage/process-log.d.ts.map +1 -1
- package/dist/core/storage/process-log.js +10 -2
- package/dist/core/supervisor/contract.d.ts +12 -0
- package/dist/core/supervisor/contract.d.ts.map +1 -1
- package/dist/core/supervisor/explanations.d.ts.map +1 -1
- package/dist/core/supervisor/explanations.js +2 -1
- package/dist/core/supervisor/findings.d.ts.map +1 -1
- package/dist/core/supervisor/findings.js +54 -9
- package/dist/core/supervisor/service.d.ts +9 -1
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +59 -29
- package/dist/core/supervisor/services.d.ts.map +1 -1
- package/dist/core/supervisor/services.js +22 -1
- package/dist/core/supervisor/status.d.ts +17 -2
- package/dist/core/supervisor/status.d.ts.map +1 -1
- package/dist/core/supervisor/status.js +70 -12
- package/dist/core/supervisor/timeline.d.ts.map +1 -1
- package/dist/core/supervisor/timeline.js +2 -1
- package/dist/core/work/state.js +7 -7
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +105 -32
- package/dist/core/workflow/failure-evidence.d.ts +16 -0
- package/dist/core/workflow/failure-evidence.d.ts.map +1 -0
- package/dist/core/workflow/failure-evidence.js +114 -0
- package/dist/core/workflow/index.d.ts +1 -1
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +1 -1
- package/dist/core/workflow/live-session-v3.d.ts +6 -0
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +126 -5
- package/dist/core/workflow/proof.d.ts +5 -5
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +115 -20
- package/dist/core/workflow/run-state.d.ts +3 -1
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +31 -27
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +19 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +13 -0
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +19 -0
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
- package/dist/core/workflow/spawn-opencode.js +14 -0
- package/dist/core/workflow/types.d.ts +64 -17
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/index.d.ts +0 -1
- package/dist/core/workflow/workspaces/index.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/index.js +0 -1
- package/dist/core/workflow/workspaces/leases.d.ts +3 -1
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +30 -16
- package/dist/core/workflow/workspaces/local-git.d.ts +6 -2
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +270 -6
- package/dist/core/workflow/workspaces/ownership.d.ts +11 -0
- package/dist/core/workflow/workspaces/ownership.d.ts.map +1 -0
- package/dist/core/workflow/workspaces/ownership.js +194 -0
- package/dist/core/workflow/workspaces/reclaim.d.ts +35 -0
- package/dist/core/workflow/workspaces/reclaim.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/reclaim.js +14 -0
- package/dist/core/workflow/workspaces/recovery.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/recovery.js +21 -13
- package/dist/core/workflow/workspaces/state.d.ts +1 -0
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +21 -1
- package/dist/lib/browser/windows-chrome.d.ts +100 -12
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -1
- package/dist/lib/browser/windows-chrome.js +262 -73
- package/dist/lib/docs-links.d.ts.map +1 -1
- package/dist/lib/docs-links.js +45 -2
- package/dist/lib/guarded-remove.d.ts +7 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -1
- package/dist/lib/guarded-remove.js +106 -12
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +4 -0
- package/dist/lib/tunnel/allowlist.d.ts +44 -0
- package/dist/lib/tunnel/allowlist.d.ts.map +1 -0
- package/dist/lib/tunnel/allowlist.js +204 -0
- package/dist/lib/tunnel/current-address.d.ts +41 -0
- package/dist/lib/tunnel/current-address.d.ts.map +1 -0
- package/dist/lib/tunnel/current-address.js +123 -0
- package/dist/lib/tunnel/gate.js +13 -6
- package/dist/lib/tunnel/processes.d.ts +39 -0
- package/dist/lib/tunnel/processes.d.ts.map +1 -0
- package/dist/lib/tunnel/processes.js +121 -0
- package/dist/lib/tunnel/state.d.ts +28 -3
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +98 -27
- package/dist/lib/zip/index.d.ts +41 -0
- package/dist/lib/zip/index.d.ts.map +1 -0
- package/dist/lib/zip/index.js +398 -0
- package/package.json +8 -1
- package/src/commander.ts +32 -0
- package/src/commands/agents.ts +151 -74
- package/src/commands/browse.ts +50 -14
- package/src/commands/diagnostics.ts +10 -0
- package/src/commands/doctor.ts +26 -7
- package/src/commands/governor.ts +23 -10
- package/src/commands/inbox.ts +52 -2
- package/src/commands/rm.ts +43 -4
- package/src/commands/servers.ts +16 -4
- package/src/commands/supervisor.ts +7 -2
- package/src/commands/toc.ts +14 -6
- package/src/commands/tunnel.ts +394 -116
- package/src/commands/web-fetch.ts +30 -19
- package/src/commands/web.ts +9 -3
- package/src/commands/workflow.ts +30 -30
- package/src/core/agents/live-authority-v3.ts +17 -0
- package/src/core/agents/live-lifecycle-v3.ts +52 -14
- package/src/core/agents/mailbox.ts +26 -17
- package/src/core/agents/render/prompt-context.ts +35 -20
- package/src/core/agents/render/session-context.ts +92 -48
- package/src/core/agents/rules/stop-hook.ts +3 -3
- package/src/core/agents/state/heartbeat-writer.ts +29 -12
- package/src/core/agents/state/live-coordination-writer.ts +29 -0
- package/src/core/agents/state/names.ts +117 -6
- package/src/core/agents/state/pidmap.ts +13 -0
- package/src/core/agents/state/proc-start.ts +57 -0
- package/src/core/agents/state/stale-sweep.ts +247 -82
- package/src/core/agents/state/unchanged-file.ts +456 -0
- package/src/core/context/index.ts +446 -136
- package/src/core/context/observation.ts +29 -0
- package/src/core/diagnostics/bundle.ts +23 -18
- package/src/core/diagnostics/path-identity.ts +15 -0
- package/src/core/diagnostics/sanitize.ts +4 -3
- package/src/core/events/v3/authority-outbox.ts +56 -0
- package/src/core/events/v3/generation-custody.ts +59 -0
- package/src/core/events/v3/producers/coordination-recorder.ts +15 -0
- package/src/core/events/v3/producers/recorder.ts +94 -68
- package/src/core/events/v3/support-storage/pack-reader.ts +45 -19
- package/src/core/governor/planning.ts +20 -8
- package/src/core/governor/service-read.ts +128 -20
- package/src/core/governor/service.ts +119 -42
- package/src/core/hooks/cli.ts +139 -22
- package/src/core/hooks/fork-lineage.ts +82 -0
- package/src/core/hooks/resolve/transcript.ts +88 -0
- package/src/core/hooks/shell-rm.ts +103 -0
- package/src/core/hooks/shell-tokens.ts +96 -0
- package/src/core/hooks/shell-waiter.ts +4 -91
- package/src/core/inbox/contract.ts +2 -1
- package/src/core/inbox/index.ts +2 -0
- package/src/core/inbox/peer-messages.ts +94 -0
- package/src/core/inbox/service.ts +88 -22
- package/src/core/inbox/targets.ts +148 -0
- package/src/core/inbox/watcher.ts +8 -9
- package/src/core/journal/index.ts +19 -2
- package/src/core/resources/contract.ts +4 -0
- package/src/core/resources/service-status.ts +35 -12
- package/src/core/resources/service.ts +71 -24
- package/src/core/resources/status.ts +57 -8
- package/src/core/servers/index.ts +177 -91
- package/src/core/servers/tunnels.ts +3 -11
- package/src/core/storage/process-log.ts +17 -2
- package/src/core/supervisor/contract.ts +13 -0
- package/src/core/supervisor/explanations.ts +4 -1
- package/src/core/supervisor/findings.ts +68 -10
- package/src/core/supervisor/service.ts +88 -26
- package/src/core/supervisor/services.ts +26 -8
- package/src/core/supervisor/status.ts +89 -12
- package/src/core/supervisor/timeline.ts +2 -1
- package/src/core/work/state.ts +7 -7
- package/src/core/workflow/engine.ts +131 -49
- package/src/core/workflow/failure-evidence.ts +141 -0
- package/src/core/workflow/index.ts +0 -1
- package/src/core/workflow/live-session-v3.ts +146 -5
- package/src/core/workflow/proof.ts +134 -26
- package/src/core/workflow/run-state.ts +31 -29
- package/src/core/workflow/spawn-claude.ts +18 -0
- package/src/core/workflow/spawn-codex.ts +13 -0
- package/src/core/workflow/spawn-cursor.ts +18 -0
- package/src/core/workflow/spawn-opencode.ts +14 -0
- package/src/core/workflow/types.ts +51 -17
- package/src/core/workflow/workspaces/index.ts +0 -1
- package/src/core/workflow/workspaces/leases.ts +48 -17
- package/src/core/workflow/workspaces/local-git.ts +315 -5
- package/src/core/workflow/workspaces/ownership.ts +232 -0
- package/src/core/workflow/workspaces/reclaim.ts +58 -0
- package/src/core/workflow/workspaces/recovery.ts +25 -13
- package/src/core/workflow/workspaces/state.ts +20 -0
- package/src/lib/browser/windows-chrome.ts +346 -86
- package/src/lib/docs-links.ts +49 -2
- package/src/lib/guarded-remove.ts +132 -14
- package/src/lib/identities/assume.ts +4 -0
- package/src/lib/tunnel/allowlist.ts +208 -0
- package/src/lib/tunnel/current-address.ts +158 -0
- package/src/lib/tunnel/gate.ts +16 -8
- package/src/lib/tunnel/processes.ts +149 -0
- package/src/lib/tunnel/state.ts +123 -27
- package/src/lib/zip/index.ts +483 -0
|
@@ -152,7 +152,7 @@ export declare const SemanticUsageReceiptV1Schema: import("@sinclair/typebox").T
|
|
|
152
152
|
scope: import("@sinclair/typebox").TLiteral<"unreported">;
|
|
153
153
|
}>]>;
|
|
154
154
|
export declare const SemanticEvidenceObservationV1Schema: import("@sinclair/typebox").TObject<{
|
|
155
|
-
kind: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"
|
|
155
|
+
kind: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"recovery" | "artifact" | "error" | "operation" | "action" | "terminal" | "task" | "progress" | "intent" | "wait" | "lifecycle" | "claim-conflict">[]>;
|
|
156
156
|
event_id: import("@sinclair/typebox").TString;
|
|
157
157
|
observed_at: import("@sinclair/typebox").TString;
|
|
158
158
|
label: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -193,7 +193,7 @@ export declare const SemanticEvidenceV1Schema: import("@sinclair/typebox").TObje
|
|
|
193
193
|
started_at: import("@sinclair/typebox").TString;
|
|
194
194
|
}>>;
|
|
195
195
|
recent: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
196
|
-
kind: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"
|
|
196
|
+
kind: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"recovery" | "artifact" | "error" | "operation" | "action" | "terminal" | "task" | "progress" | "intent" | "wait" | "lifecycle" | "claim-conflict">[]>;
|
|
197
197
|
event_id: import("@sinclair/typebox").TString;
|
|
198
198
|
observed_at: import("@sinclair/typebox").TString;
|
|
199
199
|
label: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -201,7 +201,7 @@ export declare const SemanticEvidenceV1Schema: import("@sinclair/typebox").TObje
|
|
|
201
201
|
error_class: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
202
202
|
}>>;
|
|
203
203
|
attention: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
204
|
-
kind: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"
|
|
204
|
+
kind: import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"recovery" | "artifact" | "error" | "operation" | "action" | "terminal" | "task" | "progress" | "intent" | "wait" | "lifecycle" | "claim-conflict">[]>;
|
|
205
205
|
event_id: import("@sinclair/typebox").TString;
|
|
206
206
|
observed_at: import("@sinclair/typebox").TString;
|
|
207
207
|
label: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -628,7 +628,7 @@ export declare const SemanticInvalidReadModelV2Schema: import("@sinclair/typebox
|
|
|
628
628
|
}>;
|
|
629
629
|
receipt: import("@sinclair/typebox").TObject<{
|
|
630
630
|
reason_code: import("@sinclair/typebox").TLiteral<"invalid_output">;
|
|
631
|
-
validation_issue_codes: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"unknown" | "
|
|
631
|
+
validation_issue_codes: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"unknown" | "confidence" | "schema" | "privacy" | "identity" | "basis" | "citation" | "unsupported_claim">[]>>;
|
|
632
632
|
usage: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
633
633
|
schema_version: import("@sinclair/typebox").TLiteral<1>;
|
|
634
634
|
source: import("@sinclair/typebox").TLiteral<"native">;
|
|
@@ -954,7 +954,7 @@ export declare const SemanticAgentReadModelV2Schema: import("@sinclair/typebox")
|
|
|
954
954
|
}>;
|
|
955
955
|
receipt: import("@sinclair/typebox").TObject<{
|
|
956
956
|
reason_code: import("@sinclair/typebox").TLiteral<"invalid_output">;
|
|
957
|
-
validation_issue_codes: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"unknown" | "
|
|
957
|
+
validation_issue_codes: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<import("@sinclair/typebox").TLiteral<"unknown" | "confidence" | "schema" | "privacy" | "identity" | "basis" | "citation" | "unsupported_claim">[]>>;
|
|
958
958
|
usage: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
959
959
|
schema_version: import("@sinclair/typebox").TLiteral<1>;
|
|
960
960
|
source: import("@sinclair/typebox").TLiteral<"native">;
|
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
* for `gc` once its starting agent has ended or been unobserved for a long
|
|
15
15
|
* time AND nobody has used the server for the idle window.
|
|
16
16
|
*
|
|
17
|
-
* Fail-closed rules: a record whose pid was recycled is
|
|
18
|
-
*
|
|
17
|
+
* Fail-closed rules: a record whose pid was recycled is never signalled;
|
|
18
|
+
* an unreadable start token or coordination view is `unknown`,
|
|
19
19
|
* which `gc` never stops; a record without an owner is never stopped
|
|
20
20
|
* automatically.
|
|
21
21
|
*/
|
|
22
|
+
import { type ProcessGenerationSignalDependencies, type ProcessGenerationVerdict } from "../agents/state/proc-start.js";
|
|
22
23
|
import { type ScanSupport } from "./net.js";
|
|
23
24
|
export { ancestry, establishedConnectionCounts, listListeningPorts, listListeningSockets, lsofConnectionCounts, lsofListeningSockets, parseElapsed, parseLsofListen, parseProcNetTcp, processStartedAt, psProcessInfo, readProcessInfo, scanSupport, } from "./net.js";
|
|
24
25
|
export { tunnelServerId, tunnelServerInput } from "./tunnels.js";
|
|
@@ -40,13 +41,13 @@ export interface ServerRecord {
|
|
|
40
41
|
start_token?: string;
|
|
41
42
|
/** Further processes that belong to this server (helpers, children). */
|
|
42
43
|
pids?: number[];
|
|
44
|
+
/** Generation witnesses captured when the further processes registered. */
|
|
45
|
+
pids_start_tokens?: Record<string, string>;
|
|
43
46
|
host: string;
|
|
44
47
|
/** What the server serves, usually a directory. */
|
|
45
48
|
scope?: string;
|
|
46
49
|
cwd?: string;
|
|
47
50
|
log?: string;
|
|
48
|
-
/** Graceful stop command; signals are the fallback. */
|
|
49
|
-
stop_argv?: string[];
|
|
50
51
|
owner?: {
|
|
51
52
|
instance_id: string;
|
|
52
53
|
name?: string;
|
|
@@ -63,11 +64,12 @@ export interface RegisterServerInput {
|
|
|
63
64
|
url?: string;
|
|
64
65
|
port?: number;
|
|
65
66
|
pid?: number;
|
|
67
|
+
/** Preserve an observed witness when adopting, rather than probing a new generation. */
|
|
68
|
+
start_token?: string;
|
|
66
69
|
pids?: number[];
|
|
67
70
|
scope?: string;
|
|
68
71
|
cwd?: string;
|
|
69
72
|
log?: string;
|
|
70
|
-
stop_argv?: string[];
|
|
71
73
|
started_at?: string;
|
|
72
74
|
/** `null` records no owner; omitted resolves the calling agent session. */
|
|
73
75
|
owner?: {
|
|
@@ -78,7 +80,7 @@ export interface RegisterServerInput {
|
|
|
78
80
|
export interface ServerOptions {
|
|
79
81
|
coordRoot?: string | null;
|
|
80
82
|
}
|
|
81
|
-
export type ServerState = "running" | "dead" | "other-host";
|
|
83
|
+
export type ServerState = "running" | "dead" | "other-host" | "unknown";
|
|
82
84
|
export type OwnerState = "live" | "abandoned" | "ended" | "unknown" | "none";
|
|
83
85
|
export interface ServerView {
|
|
84
86
|
record: ServerRecord;
|
|
@@ -90,6 +92,8 @@ export interface ServerView {
|
|
|
90
92
|
}
|
|
91
93
|
export interface UnregisteredListener {
|
|
92
94
|
pid: number;
|
|
95
|
+
/** Captured during the scan, before a stop can be authorized. */
|
|
96
|
+
start_token?: string;
|
|
93
97
|
port: number;
|
|
94
98
|
address: string;
|
|
95
99
|
command: string;
|
|
@@ -134,7 +138,7 @@ export declare function touchServer(id: string, options?: ServerOptions & {
|
|
|
134
138
|
export declare function createServerToucher(id: string, options?: ServerOptions): () => void;
|
|
135
139
|
export declare function readServerRecords(options?: ServerOptions): ServerRecord[];
|
|
136
140
|
export declare function pidAlive(pid: number): boolean;
|
|
137
|
-
export declare function serverState(record: ServerRecord): ServerState;
|
|
141
|
+
export declare function serverState(record: ServerRecord, readToken?: (pid: number) => string | null, probePid?: (pid: number) => boolean): ServerState;
|
|
138
142
|
export interface ListServersOptions extends ServerOptions {
|
|
139
143
|
/** Look for listening processes inside the project that never registered. */
|
|
140
144
|
scan?: boolean;
|
|
@@ -147,8 +151,6 @@ export interface ListServersOptions extends ServerOptions {
|
|
|
147
151
|
}
|
|
148
152
|
/** Read every record, observe it, and optionally find unregistered listeners. */
|
|
149
153
|
export declare function listServers(options?: ListServersOptions): ServersReport;
|
|
150
|
-
/** Register running tunnels that have no current record. Returns adopted ids. */
|
|
151
|
-
export declare function adoptRunningTunnels(coordRoot: string): string[];
|
|
152
154
|
/**
|
|
153
155
|
* Listening processes that run inside the project (working directory or
|
|
154
156
|
* command line within the coordination root) but are not covered by any
|
|
@@ -175,16 +177,21 @@ export declare function planServerGc(views: ServerView[], policy?: GcPolicy): Gc
|
|
|
175
177
|
export interface StopResult {
|
|
176
178
|
id: string;
|
|
177
179
|
stopped: boolean;
|
|
178
|
-
method: "not-running" | "
|
|
180
|
+
method: "not-running" | "signal" | "refused";
|
|
181
|
+
generation?: ProcessGenerationVerdict;
|
|
179
182
|
detail?: string;
|
|
180
183
|
}
|
|
184
|
+
export interface ServerProcessDependencies extends ProcessGenerationSignalDependencies {
|
|
185
|
+
probePid?: (pid: number) => boolean;
|
|
186
|
+
}
|
|
181
187
|
/**
|
|
182
|
-
* Stop
|
|
183
|
-
*
|
|
184
|
-
*
|
|
188
|
+
* Stop a verified server with SIGTERM, then SIGKILL after the grace period.
|
|
189
|
+
* Each signal, including the process group and auxiliary processes, requires
|
|
190
|
+
* a fresh generation check. Unknown or different generations retain the record.
|
|
185
191
|
*/
|
|
186
192
|
export declare function stopServer(record: ServerRecord, options?: ServerOptions & {
|
|
187
193
|
graceMs?: number;
|
|
194
|
+
signalDependencies?: ServerProcessDependencies;
|
|
188
195
|
}): Promise<StopResult>;
|
|
189
196
|
/**
|
|
190
197
|
* The first free port in the configured range for `type`
|
|
@@ -200,6 +207,10 @@ export interface AdoptOptions extends ServerOptions {
|
|
|
200
207
|
scope?: string;
|
|
201
208
|
/** `self` (default) records the adopting agent as owner; `none` records no owner. */
|
|
202
209
|
owner?: "self" | "none";
|
|
210
|
+
dependencies?: {
|
|
211
|
+
listServers?: typeof listServers;
|
|
212
|
+
readToken?: (pid: number) => string | null;
|
|
213
|
+
};
|
|
203
214
|
}
|
|
204
215
|
/**
|
|
205
216
|
* Register a running server that never registered itself. Only a pid the scan
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/servers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/servers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAQH,OAAO,EACL,KAAK,mCAAmC,EACxC,KAAK,wBAAwB,EAI9B,MAAM,+BAA+B,CAAC;AASvC,OAAO,EAOL,KAAK,WAAW,EAEjB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,QAAQ,EACR,2BAA2B,EAC3B,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,WAAW,GACZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjE,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAGnD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,OAAO,4BAA4B,CAAC;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;AACxE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,CAAC,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEpD;AAMD,2DAA2D;AAC3D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAM7D;AASD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEnD;AAOD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,EAC1B,OAAO,CAAC,EAAE,aAAa,GACtB,YAAY,GAAG,IAAI,CA4CrB;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,mBAAmB,EAC1B,OAAO,CAAC,EAAE,aAAa,GACtB,YAAY,GAAG,IAAI,CAMrB;AAaD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAWhG;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,GAAG,IAAI,CAInF;AAED,iCAAiC;AACjC,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAUtF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,IAAI,CAYnF;AAmBD,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,EAAE,CAazE;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE7C;AAsBD,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EAC1C,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,GAClC,WAAW,CAOb;AAsBD,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,6EAA6E;IAC7E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8DAA8D;IAC9D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,aAAa,CAsDvE;AASD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC,GACnD,oBAAoB,EAAE,CAmCxB;AAgBD,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,EAAE,CAiBjF;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC7C,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,yBAA0B,SAAQ,mCAAmC;IACpF,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,aAAa,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,yBAAyB,CAAC;CAChD,GACA,OAAO,CAAC,UAAU,CAAC,CAgErB;AA8CD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAWvF;AAED,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE;QACb,WAAW,CAAC,EAAE,OAAO,WAAW,CAAC;QACjC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;KAC5C,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,YAAY,CAsC7E;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1D"}
|
|
@@ -14,27 +14,24 @@
|
|
|
14
14
|
* for `gc` once its starting agent has ended or been unobserved for a long
|
|
15
15
|
* time AND nobody has used the server for the idle window.
|
|
16
16
|
*
|
|
17
|
-
* Fail-closed rules: a record whose pid was recycled is
|
|
18
|
-
*
|
|
17
|
+
* Fail-closed rules: a record whose pid was recycled is never signalled;
|
|
18
|
+
* an unreadable start token or coordination view is `unknown`,
|
|
19
19
|
* which `gc` never stops; a record without an owner is never stopped
|
|
20
20
|
* automatically.
|
|
21
21
|
*/
|
|
22
|
-
import { spawnSync } from "node:child_process";
|
|
23
22
|
import { createHash } from "node:crypto";
|
|
24
23
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync } from "node:fs";
|
|
25
24
|
import { hostname } from "node:os";
|
|
26
25
|
import { basename, isAbsolute, join, relative, resolve } from "node:path";
|
|
27
|
-
import { listStates } from "../../lib/tunnel/state.js";
|
|
28
26
|
import { resolveCoordRoot } from "../agents/coord-client.js";
|
|
29
27
|
import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.js";
|
|
30
|
-
import {
|
|
28
|
+
import { processStartToken, signalIfSameGeneration, verifyProcessGeneration, } from "../agents/state/proc-start.js";
|
|
31
29
|
import { serverPortRange } from "../config.js";
|
|
32
30
|
import { readCoordinationViewV3, requireAuthoritySafeCoordinationViewV3, } from "../events/v3/coordination-view.js";
|
|
33
31
|
import { liveInstanceIdV3 } from "../events/v3/live-route-observer.js";
|
|
34
32
|
import { resolveOwner } from "../hooks/resolve/owner.js";
|
|
35
33
|
import { writePrivateJsonAtomic } from "../storage/atomic-json.js";
|
|
36
34
|
import { ancestry, establishedConnectionCounts, listListeningPorts, listListeningSockets, processStartedAt, readProcessInfo, scanSupport, } from "./net.js";
|
|
37
|
-
import { tunnelServerId, tunnelServerInput } from "./tunnels.js";
|
|
38
35
|
export { ancestry, establishedConnectionCounts, listListeningPorts, listListeningSockets, lsofConnectionCounts, lsofListeningSockets, parseElapsed, parseLsofListen, parseProcNetTcp, processStartedAt, psProcessInfo, readProcessInfo, scanSupport, } from "./net.js";
|
|
39
36
|
export { tunnelServerId, tunnelServerInput } from "./tunnels.js";
|
|
40
37
|
export const SERVER_RECORD_SCHEMA_VERSION = 1;
|
|
@@ -87,7 +84,14 @@ export function registerServer(input, options) {
|
|
|
87
84
|
throw new Error(`invalid server port: ${input.port}`);
|
|
88
85
|
const id = input.id ?? serverId(input.type, input.scope);
|
|
89
86
|
const now = new Date().toISOString();
|
|
90
|
-
const startToken = processStartToken(pid);
|
|
87
|
+
const startToken = input.start_token ?? processStartToken(pid);
|
|
88
|
+
const pids = [...new Set(input.pids?.filter((p) => Number.isSafeInteger(p) && p > 0))];
|
|
89
|
+
const pidsStartTokens = {};
|
|
90
|
+
for (const auxiliaryPid of pids) {
|
|
91
|
+
const token = processStartToken(auxiliaryPid);
|
|
92
|
+
if (token)
|
|
93
|
+
pidsStartTokens[auxiliaryPid] = token;
|
|
94
|
+
}
|
|
91
95
|
const owner = input.owner === undefined ? callingOwner(coordRoot) : (input.owner ?? undefined);
|
|
92
96
|
const record = {
|
|
93
97
|
schema_version: SERVER_RECORD_SCHEMA_VERSION,
|
|
@@ -99,19 +103,18 @@ export function registerServer(input, options) {
|
|
|
99
103
|
...(input.port ? { port: input.port } : {}),
|
|
100
104
|
pid,
|
|
101
105
|
...(startToken ? { start_token: startToken } : {}),
|
|
102
|
-
...(
|
|
103
|
-
? { pids: input.pids.filter((p) => Number.isSafeInteger(p) && p > 0) }
|
|
104
|
-
: {}),
|
|
106
|
+
...(pids.length ? { pids, pids_start_tokens: pidsStartTokens } : {}),
|
|
105
107
|
host: hostname(),
|
|
106
108
|
...(input.scope ? { scope: resolve(input.scope) } : {}),
|
|
107
109
|
...(input.cwd ? { cwd: resolve(input.cwd) } : {}),
|
|
108
110
|
...(input.log ? { log: resolve(input.log) } : {}),
|
|
109
|
-
...(input.stop_argv?.length ? { stop_argv: input.stop_argv } : {}),
|
|
110
111
|
...(owner ? { owner } : {}),
|
|
111
112
|
started_at: input.started_at ?? now,
|
|
112
113
|
registered_at: now,
|
|
113
114
|
last_active_at: now,
|
|
114
115
|
};
|
|
116
|
+
if (input.start_token !== undefined && verifyProcessGeneration(pid, input.start_token) !== "same")
|
|
117
|
+
throw new Error(`pid ${pid} generation could not be verified before registration`);
|
|
115
118
|
writePrivateJsonAtomic(recordPath(coordRoot, id), record);
|
|
116
119
|
return record;
|
|
117
120
|
}
|
|
@@ -224,20 +227,33 @@ export function readServerRecords(options) {
|
|
|
224
227
|
.sort((a, b) => a.kind.localeCompare(b.kind) || a.type.localeCompare(b.type) || a.id.localeCompare(b.id));
|
|
225
228
|
}
|
|
226
229
|
export function pidAlive(pid) {
|
|
230
|
+
return processPresence(pid) !== "absent";
|
|
231
|
+
}
|
|
232
|
+
function processPresence(pid, probePid) {
|
|
227
233
|
try {
|
|
234
|
+
if (probePid)
|
|
235
|
+
return probePid(pid) ? "present" : "absent";
|
|
228
236
|
process.kill(pid, 0);
|
|
229
|
-
return
|
|
237
|
+
return "present";
|
|
230
238
|
}
|
|
231
239
|
catch (error) {
|
|
232
|
-
|
|
240
|
+
const code = error.code;
|
|
241
|
+
return code === "ESRCH" ? "absent" : code === "EPERM" ? "present" : "unknown";
|
|
233
242
|
}
|
|
234
243
|
}
|
|
235
|
-
|
|
244
|
+
function allProcessesAbsent(record, probePid) {
|
|
245
|
+
return [record.pid, ...(record.pids ?? [])].every((pid) => processPresence(pid, probePid) === "absent");
|
|
246
|
+
}
|
|
247
|
+
export function serverState(record, readToken, probePid) {
|
|
236
248
|
if (record.host !== hostname())
|
|
237
249
|
return "other-host";
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
250
|
+
const presence = processPresence(record.pid, probePid);
|
|
251
|
+
if (presence === "absent")
|
|
252
|
+
return allProcessesAbsent(record, probePid) ? "dead" : "unknown";
|
|
253
|
+
if (presence === "unknown")
|
|
254
|
+
return "unknown";
|
|
255
|
+
const verdict = verifyProcessGeneration(record.pid, record.start_token, readToken);
|
|
256
|
+
return verdict === "same" ? "running" : verdict === "different" ? "dead" : "unknown";
|
|
241
257
|
}
|
|
242
258
|
function ownerReader(coordRoot, ownerStaleMs, nowMs) {
|
|
243
259
|
let view = null;
|
|
@@ -268,7 +284,6 @@ export function listServers(options) {
|
|
|
268
284
|
const now = options?.now ?? new Date();
|
|
269
285
|
const nowMs = now.getTime();
|
|
270
286
|
const ownerStaleMs = hours(options?.ownerStaleHours ?? SERVER_DEFAULT_OWNER_STALE_HOURS);
|
|
271
|
-
adoptRunningTunnels(coordRoot);
|
|
272
287
|
const records = readServerRecords({ coordRoot });
|
|
273
288
|
const ownerOf = ownerReader(coordRoot, ownerStaleMs, nowMs);
|
|
274
289
|
const states = records.map((record) => serverState(record));
|
|
@@ -278,7 +293,7 @@ export function listServers(options) {
|
|
|
278
293
|
const servers = [];
|
|
279
294
|
records.forEach((record, i) => {
|
|
280
295
|
const state = states[i];
|
|
281
|
-
if (state === "dead" && options?.prune !== false) {
|
|
296
|
+
if (state === "dead" && allProcessesAbsent(record) && options?.prune !== false) {
|
|
282
297
|
unregisterServer(record.id, { coordRoot, pid: record.pid });
|
|
283
298
|
pruned.push(record.id);
|
|
284
299
|
return;
|
|
@@ -316,27 +331,6 @@ export function listServers(options) {
|
|
|
316
331
|
pruned,
|
|
317
332
|
};
|
|
318
333
|
}
|
|
319
|
-
/** Register running tunnels that have no current record. Returns adopted ids. */
|
|
320
|
-
export function adoptRunningTunnels(coordRoot) {
|
|
321
|
-
const adopted = [];
|
|
322
|
-
let states;
|
|
323
|
-
try {
|
|
324
|
-
states = listStates(coordRoot);
|
|
325
|
-
}
|
|
326
|
-
catch {
|
|
327
|
-
return adopted;
|
|
328
|
-
}
|
|
329
|
-
for (const state of states) {
|
|
330
|
-
if (!state.gate_pid || !pidAlive(state.gate_pid))
|
|
331
|
-
continue;
|
|
332
|
-
const id = tunnelServerId(state.name);
|
|
333
|
-
if (readServer(id, { coordRoot })?.pid === state.gate_pid)
|
|
334
|
-
continue;
|
|
335
|
-
if (tryRegisterServer(tunnelServerInput(state, coordRoot), { coordRoot }))
|
|
336
|
-
adopted.push(id);
|
|
337
|
-
}
|
|
338
|
-
return adopted;
|
|
339
|
-
}
|
|
340
334
|
/** Processes that browser automation and editors start; never project servers. */
|
|
341
335
|
const IGNORED_LISTENER_COMMANDS = [
|
|
342
336
|
/(^|\/)(chrome|chromium|chrome-headless-shell|headless_shell|msedge|firefox)( |$)/i,
|
|
@@ -350,10 +344,10 @@ const IGNORED_LISTENER_COMMANDS = [
|
|
|
350
344
|
* a recorded port.
|
|
351
345
|
*/
|
|
352
346
|
export function findUnregisteredListeners(coordRoot, servers) {
|
|
353
|
-
const
|
|
347
|
+
const registered = servers.filter((server) => server.record.host === hostname());
|
|
354
348
|
const covered = new Set();
|
|
355
349
|
const ports = new Set();
|
|
356
|
-
for (const { record } of
|
|
350
|
+
for (const { record } of registered) {
|
|
357
351
|
covered.add(record.pid);
|
|
358
352
|
for (const pid of record.pids ?? [])
|
|
359
353
|
covered.add(pid);
|
|
@@ -363,8 +357,9 @@ export function findUnregisteredListeners(coordRoot, servers) {
|
|
|
363
357
|
const results = [];
|
|
364
358
|
const seenPids = new Map();
|
|
365
359
|
for (const socket of listListeningSockets()) {
|
|
366
|
-
if (ports.has(socket.port) || socket.pid === process.pid)
|
|
360
|
+
if (ports.has(socket.port) || covered.has(socket.pid) || socket.pid === process.pid)
|
|
367
361
|
continue;
|
|
362
|
+
const startToken = processStartToken(socket.pid);
|
|
368
363
|
let inside = seenPids.get(socket.pid);
|
|
369
364
|
const info = readProcessInfo(socket.pid);
|
|
370
365
|
if (!info)
|
|
@@ -380,6 +375,7 @@ export function findUnregisteredListeners(coordRoot, servers) {
|
|
|
380
375
|
continue;
|
|
381
376
|
results.push({
|
|
382
377
|
pid: socket.pid,
|
|
378
|
+
...(startToken ? { start_token: startToken } : {}),
|
|
383
379
|
port: socket.port,
|
|
384
380
|
address: socket.address,
|
|
385
381
|
command: info.command.slice(0, 300),
|
|
@@ -430,72 +426,111 @@ export function planServerGc(views, policy) {
|
|
|
430
426
|
});
|
|
431
427
|
}
|
|
432
428
|
/**
|
|
433
|
-
* Stop
|
|
434
|
-
*
|
|
435
|
-
*
|
|
429
|
+
* Stop a verified server with SIGTERM, then SIGKILL after the grace period.
|
|
430
|
+
* Each signal, including the process group and auxiliary processes, requires
|
|
431
|
+
* a fresh generation check. Unknown or different generations retain the record.
|
|
436
432
|
*/
|
|
437
433
|
export async function stopServer(record, options) {
|
|
438
434
|
const coordRoot = rootOf(options);
|
|
439
435
|
const graceMs = options?.graceMs ?? 5_000;
|
|
436
|
+
const dependencies = options?.signalDependencies ?? {};
|
|
437
|
+
const targets = [
|
|
438
|
+
{ pid: record.pid, token: record.start_token },
|
|
439
|
+
...[...new Set(record.pids ?? [])]
|
|
440
|
+
.filter((pid) => pid !== record.pid)
|
|
441
|
+
.map((pid) => ({ pid, token: record.pids_start_tokens?.[pid] })),
|
|
442
|
+
];
|
|
443
|
+
const refuse = (pid, generation) => ({
|
|
444
|
+
id: record.id,
|
|
445
|
+
stopped: false,
|
|
446
|
+
method: "refused",
|
|
447
|
+
generation,
|
|
448
|
+
detail: `pid ${pid} generation is ${generation}; left the server record in place`,
|
|
449
|
+
});
|
|
440
450
|
const finish = (result) => {
|
|
441
451
|
if (result.stopped || result.method === "not-running")
|
|
442
452
|
unregisterServer(record.id, { coordRoot, pid: record.pid });
|
|
443
453
|
return result;
|
|
444
454
|
};
|
|
445
|
-
|
|
446
|
-
if (state === "other-host")
|
|
455
|
+
if (record.host !== hostname())
|
|
447
456
|
return { id: record.id, stopped: false, method: "refused", detail: `runs on ${record.host}` };
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
457
|
+
const leaderPresence = processPresence(record.pid, dependencies.probePid);
|
|
458
|
+
if (leaderPresence === "unknown" ||
|
|
459
|
+
(leaderPresence === "absent" && !allProcessesAbsent(record, dependencies.probePid)))
|
|
460
|
+
return refuse(record.pid, "unknown");
|
|
461
|
+
// Check every recorded live process before sending the first signal.
|
|
462
|
+
for (const target of targets) {
|
|
463
|
+
const presence = processPresence(target.pid, dependencies.probePid);
|
|
464
|
+
if (presence === "absent")
|
|
465
|
+
continue;
|
|
466
|
+
if (presence === "unknown")
|
|
467
|
+
return refuse(target.pid, "unknown");
|
|
468
|
+
const verdict = verifyProcessGeneration(target.pid, target.token, dependencies.readToken);
|
|
469
|
+
if (verdict !== "same")
|
|
470
|
+
return refuse(target.pid, verdict);
|
|
455
471
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
472
|
+
if (targets.every((target) => processPresence(target.pid, dependencies.probePid) === "absent"))
|
|
473
|
+
return finish({ id: record.id, stopped: false, method: "not-running" });
|
|
474
|
+
for (const name of ["SIGTERM", "SIGKILL"]) {
|
|
475
|
+
for (const target of targets) {
|
|
476
|
+
const presence = processPresence(target.pid, dependencies.probePid);
|
|
477
|
+
if (presence === "absent")
|
|
478
|
+
continue;
|
|
479
|
+
if (presence === "unknown")
|
|
480
|
+
return refuse(target.pid, "unknown");
|
|
481
|
+
const result = target.pid === record.pid
|
|
482
|
+
? signalServerLeader(target.pid, target.token, name, dependencies)
|
|
483
|
+
: signalIfSameGeneration(target.pid, target.token, name, dependencies);
|
|
484
|
+
if (result.verdict !== "same")
|
|
485
|
+
return refuse(target.pid, result.verdict);
|
|
486
|
+
}
|
|
487
|
+
const observed = await waitForExit(targets, name === "SIGTERM" ? graceMs : 2_000, dependencies);
|
|
488
|
+
if (observed.refused)
|
|
489
|
+
return refuse(observed.refused.pid, observed.refused.verdict);
|
|
490
|
+
if (observed.exited)
|
|
491
|
+
return finish({ id: record.id, stopped: true, method: "signal", generation: "same" });
|
|
465
492
|
}
|
|
466
|
-
|
|
467
|
-
return finish({
|
|
493
|
+
return {
|
|
468
494
|
id: record.id,
|
|
469
|
-
stopped,
|
|
495
|
+
stopped: false,
|
|
470
496
|
method: "signal",
|
|
471
|
-
|
|
472
|
-
|
|
497
|
+
generation: "same",
|
|
498
|
+
detail: "process survived SIGKILL",
|
|
499
|
+
};
|
|
473
500
|
}
|
|
474
|
-
function
|
|
475
|
-
//
|
|
476
|
-
//
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
process.kill(pid, name);
|
|
486
|
-
}
|
|
487
|
-
catch {
|
|
488
|
-
// Already gone.
|
|
489
|
-
}
|
|
501
|
+
function signalServerLeader(pid, token, name, dependencies) {
|
|
502
|
+
// The leader's generation authorizes its group. A failed group signal must
|
|
503
|
+
// not reuse that observation for the direct-PID fallback.
|
|
504
|
+
const kill = dependencies.kill ?? process.kill;
|
|
505
|
+
const group = signalIfSameGeneration(pid, token, name, {
|
|
506
|
+
readToken: dependencies.readToken,
|
|
507
|
+
kill: (leader, signal) => kill(-leader, signal),
|
|
508
|
+
});
|
|
509
|
+
return group.sent || group.verdict !== "same"
|
|
510
|
+
? group
|
|
511
|
+
: signalIfSameGeneration(pid, token, name, dependencies);
|
|
490
512
|
}
|
|
491
|
-
async function
|
|
513
|
+
async function waitForExit(targets, waitMs, dependencies) {
|
|
492
514
|
const deadline = Date.now() + waitMs;
|
|
493
|
-
while (
|
|
494
|
-
|
|
495
|
-
|
|
515
|
+
while (true) {
|
|
516
|
+
let live = false;
|
|
517
|
+
for (const target of targets) {
|
|
518
|
+
const presence = processPresence(target.pid, dependencies.probePid);
|
|
519
|
+
if (presence === "absent")
|
|
520
|
+
continue;
|
|
521
|
+
if (presence === "unknown")
|
|
522
|
+
return { exited: false, refused: { pid: target.pid, verdict: "unknown" } };
|
|
523
|
+
const verdict = verifyProcessGeneration(target.pid, target.token, dependencies.readToken);
|
|
524
|
+
if (verdict !== "same")
|
|
525
|
+
return { exited: false, refused: { pid: target.pid, verdict } };
|
|
526
|
+
live = true;
|
|
527
|
+
}
|
|
528
|
+
if (!live)
|
|
529
|
+
return { exited: true };
|
|
530
|
+
if (Date.now() >= deadline)
|
|
531
|
+
return { exited: false };
|
|
496
532
|
await new Promise((r) => setTimeout(r, 100));
|
|
497
533
|
}
|
|
498
|
-
return serverState(record) !== "running";
|
|
499
534
|
}
|
|
500
535
|
/**
|
|
501
536
|
* The first free port in the configured range for `type`
|
|
@@ -510,7 +545,8 @@ export function allocateServerPort(type, options) {
|
|
|
510
545
|
return null;
|
|
511
546
|
const taken = listListeningPorts();
|
|
512
547
|
for (const record of readServerRecords({ coordRoot })) {
|
|
513
|
-
|
|
548
|
+
const state = serverState(record);
|
|
549
|
+
if (record.port && (state === "running" || state === "unknown"))
|
|
514
550
|
taken.add(record.port);
|
|
515
551
|
}
|
|
516
552
|
for (let port = range[0]; port <= range[1]; port++)
|
|
@@ -526,12 +562,15 @@ export function adoptServer(pid, options) {
|
|
|
526
562
|
const coordRoot = rootOf(options);
|
|
527
563
|
if (!coordRoot)
|
|
528
564
|
throw new Error("no Harnery project found (coordination root did not resolve)");
|
|
529
|
-
const report = listServers({ coordRoot, sample: false });
|
|
565
|
+
const report = (options?.dependencies?.listServers ?? listServers)({ coordRoot, sample: false });
|
|
530
566
|
const listeners = report.unregistered.filter((item) => item.pid === pid);
|
|
531
567
|
if (!listeners.length)
|
|
532
568
|
throw new Error(`pid ${pid} is not an unregistered listener inside this project`);
|
|
533
569
|
const ports = listeners.map((item) => item.port).sort((a, b) => a - b);
|
|
534
570
|
const first = listeners[0];
|
|
571
|
+
const generation = verifyProcessGeneration(pid, first.start_token, options?.dependencies?.readToken);
|
|
572
|
+
if (generation !== "same")
|
|
573
|
+
throw new Error(`pid ${pid} generation is ${generation}; adoption refused`);
|
|
535
574
|
const type = options?.type ?? "adopted";
|
|
536
575
|
const scope = options?.scope ?? first.cwd ?? undefined;
|
|
537
576
|
const started = processStartedAt(pid);
|
|
@@ -543,6 +582,7 @@ export function adoptServer(pid, options) {
|
|
|
543
582
|
url: `http://127.0.0.1:${ports[0]}/`,
|
|
544
583
|
port: ports[0],
|
|
545
584
|
pid,
|
|
585
|
+
start_token: first.start_token,
|
|
546
586
|
...(scope ? { scope } : {}),
|
|
547
587
|
...(first.cwd ? { cwd: first.cwd } : {}),
|
|
548
588
|
...(options?.owner === "none" ? { owner: null } : {}),
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tunnels as registry services.
|
|
3
3
|
*
|
|
4
|
-
* `tunnel up` and `tunnel reload` register the
|
|
5
|
-
*
|
|
6
|
-
* time the registry is read, so a long-lived tunnel never shows as an
|
|
7
|
-
* unregistered listener.
|
|
4
|
+
* `tunnel up` and `tunnel reload` register the new gate; `tunnel down` removes
|
|
5
|
+
* its record. Older tunnels need an explicit adoption of an observed listener.
|
|
8
6
|
*/
|
|
9
7
|
import { type TunnelState } from "../../lib/tunnel/state.js";
|
|
10
8
|
import type { RegisterServerInput } from "./index.js";
|
|
11
9
|
export declare function tunnelServerId(name: string): string;
|
|
12
|
-
/**
|
|
10
|
+
/** Register the new gate; saved helper PIDs have no generation witnesses. */
|
|
13
11
|
export declare function tunnelServerInput(state: TunnelState, coordRoot: string): RegisterServerInput;
|
|
14
12
|
//# sourceMappingURL=tunnels.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnels.d.ts","sourceRoot":"","sources":["../../../src/core/servers/tunnels.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tunnels.d.ts","sourceRoot":"","sources":["../../../src/core/servers/tunnels.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,mBAAmB,CAc5F"}
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tunnels as registry services.
|
|
3
3
|
*
|
|
4
|
-
* `tunnel up` and `tunnel reload` register the
|
|
5
|
-
*
|
|
6
|
-
* time the registry is read, so a long-lived tunnel never shows as an
|
|
7
|
-
* unregistered listener.
|
|
4
|
+
* `tunnel up` and `tunnel reload` register the new gate; `tunnel down` removes
|
|
5
|
+
* its record. Older tunnels need an explicit adoption of an observed listener.
|
|
8
6
|
*/
|
|
9
7
|
import { resolve } from "node:path";
|
|
10
8
|
import { gateLogFile } from "../../lib/tunnel/state.js";
|
|
11
|
-
import { resolveBinName } from "../config.js";
|
|
12
9
|
export function tunnelServerId(name) {
|
|
13
10
|
return `tunnel-${name.toLowerCase().replace(/[^a-z0-9._-]+/g, "-")}`;
|
|
14
11
|
}
|
|
15
|
-
/**
|
|
12
|
+
/** Register the new gate; saved helper PIDs have no generation witnesses. */
|
|
16
13
|
export function tunnelServerInput(state, coordRoot) {
|
|
17
|
-
const helpers = [state.cloudflared_pid, state.provider_pid].filter((pid) => typeof pid === "number" && pid > 0);
|
|
18
14
|
return {
|
|
19
15
|
id: tunnelServerId(state.name),
|
|
20
16
|
kind: "service",
|
|
@@ -23,10 +19,8 @@ export function tunnelServerInput(state, coordRoot) {
|
|
|
23
19
|
url: state.url,
|
|
24
20
|
port: state.gate_port,
|
|
25
21
|
pid: state.gate_pid,
|
|
26
|
-
...(helpers.length ? { pids: helpers } : {}),
|
|
27
22
|
log: resolve(coordRoot, ".cache", "tunnel", gateLogFile(state.name)),
|
|
28
23
|
cwd: coordRoot,
|
|
29
|
-
stop_argv: [resolveBinName(coordRoot), "tunnel", "down", "--name", state.name],
|
|
30
24
|
started_at: state.started_at,
|
|
31
25
|
owner: null,
|
|
32
26
|
};
|