@threadbase-sh/streamer 1.62.0 → 1.64.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/dist/agent/agent-client.d.ts +14 -0
- package/dist/agent/agent-client.d.ts.map +1 -0
- package/dist/agent/agent-config.d.ts +24 -0
- package/dist/agent/agent-config.d.ts.map +1 -0
- package/dist/agent/conversation-writer.d.ts +13 -0
- package/dist/agent/conversation-writer.d.ts.map +1 -0
- package/dist/agent/dedupe.d.ts +6 -0
- package/dist/agent/dedupe.d.ts.map +1 -0
- package/dist/agent/errors.d.ts +23 -0
- package/dist/agent/errors.d.ts.map +1 -0
- package/dist/agent/handle-send-agent-input.d.ts +21 -0
- package/dist/agent/handle-send-agent-input.d.ts.map +1 -0
- package/dist/agent/handle-start-agent-session.d.ts +21 -0
- package/dist/agent/handle-start-agent-session.d.ts.map +1 -0
- package/dist/agent/history-mapper.d.ts +4 -0
- package/dist/agent/history-mapper.d.ts.map +1 -0
- package/dist/agent/payload-guard.d.ts +29 -0
- package/dist/agent/payload-guard.d.ts.map +1 -0
- package/dist/api/app.d.ts +28 -0
- package/dist/api/app.d.ts.map +1 -0
- package/dist/api/handlers/conversations.handlers.d.ts +69 -0
- package/dist/api/handlers/conversations.handlers.d.ts.map +1 -0
- package/dist/api/handlers/http-helpers.d.ts +50 -0
- package/dist/api/handlers/http-helpers.d.ts.map +1 -0
- package/dist/api/handlers/sessions.handlers.d.ts +230 -0
- package/dist/api/handlers/sessions.handlers.d.ts.map +1 -0
- package/dist/api/middleware/auth.middleware.d.ts +5 -0
- package/dist/api/middleware/auth.middleware.d.ts.map +1 -0
- package/dist/api/middleware/cors.middleware.d.ts +5 -0
- package/dist/api/middleware/cors.middleware.d.ts.map +1 -0
- package/dist/api/middleware/error.middleware.d.ts +4 -0
- package/dist/api/middleware/error.middleware.d.ts.map +1 -0
- package/dist/api/routes/backup.routes.d.ts +5 -0
- package/dist/api/routes/backup.routes.d.ts.map +1 -0
- package/dist/api/routes/browse.routes.d.ts +5 -0
- package/dist/api/routes/browse.routes.d.ts.map +1 -0
- package/dist/api/routes/cacheAlert.routes.d.ts +5 -0
- package/dist/api/routes/cacheAlert.routes.d.ts.map +1 -0
- package/dist/api/routes/config.routes.d.ts +5 -0
- package/dist/api/routes/config.routes.d.ts.map +1 -0
- package/dist/api/routes/conversations.routes.d.ts +5 -0
- package/dist/api/routes/conversations.routes.d.ts.map +1 -0
- package/dist/api/routes/devices.routes.d.ts +17 -0
- package/dist/api/routes/devices.routes.d.ts.map +1 -0
- package/dist/api/routes/diagnostics.routes.d.ts +5 -0
- package/dist/api/routes/diagnostics.routes.d.ts.map +1 -0
- package/dist/api/routes/health.routes.d.ts +5 -0
- package/dist/api/routes/health.routes.d.ts.map +1 -0
- package/dist/api/routes/logs.routes.d.ts +3 -0
- package/dist/api/routes/logs.routes.d.ts.map +1 -0
- package/dist/api/routes/misc.routes.d.ts +77 -0
- package/dist/api/routes/misc.routes.d.ts.map +1 -0
- package/dist/api/routes/pair.routes.d.ts +5 -0
- package/dist/api/routes/pair.routes.d.ts.map +1 -0
- package/dist/api/routes/progress.routes.d.ts +39 -0
- package/dist/api/routes/progress.routes.d.ts.map +1 -0
- package/dist/api/routes/projects.routes.d.ts +5 -0
- package/dist/api/routes/projects.routes.d.ts.map +1 -0
- package/dist/api/routes/providers.routes.d.ts +19 -0
- package/dist/api/routes/providers.routes.d.ts.map +1 -0
- package/dist/api/routes/scanner.routes.d.ts +5 -0
- package/dist/api/routes/scanner.routes.d.ts.map +1 -0
- package/dist/api/routes/sessions.routes.d.ts +6 -0
- package/dist/api/routes/sessions.routes.d.ts.map +1 -0
- package/dist/api/routes/ws.routes.d.ts +7 -0
- package/dist/api/routes/ws.routes.d.ts.map +1 -0
- package/dist/api/types/api-deps.d.ts +114 -0
- package/dist/api/types/api-deps.d.ts.map +1 -0
- package/dist/auth.d.ts +81 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/browse.d.ts +17 -0
- package/dist/browse.d.ts.map +1 -0
- package/dist/claude-flags.d.ts +76 -0
- package/dist/claude-flags.d.ts.map +1 -0
- package/dist/cli.cjs +1917 -1795
- package/dist/cli.cjs.map +1 -1
- package/dist/codex-pty-runner.d.ts +90 -0
- package/dist/codex-pty-runner.d.ts.map +1 -0
- package/dist/config/update-config.d.ts +13 -0
- package/dist/config/update-config.d.ts.map +1 -0
- package/dist/conversation-cache.d.ts +336 -0
- package/dist/conversation-cache.d.ts.map +1 -0
- package/dist/db/config.d.ts +11 -0
- package/dist/db/config.d.ts.map +1 -0
- package/dist/db/index.d.ts +5 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/migrations.d.ts +3 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.d.ts.map +1 -0
- package/dist/db/query-timing.d.ts +52 -0
- package/dist/db/query-timing.d.ts.map +1 -0
- package/dist/db/repositories/cacheMetadata.repository.d.ts +12 -0
- package/dist/db/repositories/cacheMetadata.repository.d.ts.map +1 -0
- package/dist/db/repositories/conversations.repository.d.ts +27 -0
- package/dist/db/repositories/conversations.repository.d.ts.map +1 -0
- package/dist/db/repositories/devices.repository.d.ts +137 -0
- package/dist/db/repositories/devices.repository.d.ts.map +1 -0
- package/dist/db/repositories/managed-sessions.repository.d.ts +127 -0
- package/dist/db/repositories/managed-sessions.repository.d.ts.map +1 -0
- package/dist/db/repositories/projects.repository.d.ts +28 -0
- package/dist/db/repositories/projects.repository.d.ts.map +1 -0
- package/dist/db/repositories/push.repository.d.ts +186 -0
- package/dist/db/repositories/push.repository.d.ts.map +1 -0
- package/dist/db/repositories/sessions.repository.d.ts +16 -0
- package/dist/db/repositories/sessions.repository.d.ts.map +1 -0
- package/dist/db/runtime-store.d.ts +80 -0
- package/dist/db/runtime-store.d.ts.map +1 -0
- package/dist/db/sqlite-migrate.d.ts +13 -0
- package/dist/db/sqlite-migrate.d.ts.map +1 -0
- package/dist/db/upload-records.d.ts +11 -0
- package/dist/db/upload-records.d.ts.map +1 -0
- package/dist/e2ee/noise.d.ts +261 -0
- package/dist/e2ee/noise.d.ts.map +1 -0
- package/dist/e2ee/pair-payload.d.ts +60 -0
- package/dist/e2ee/pair-payload.d.ts.map +1 -0
- package/dist/e2ee/pair-request.d.ts +24 -0
- package/dist/e2ee/pair-request.d.ts.map +1 -0
- package/dist/external-tails.d.ts +91 -0
- package/dist/external-tails.d.ts.map +1 -0
- package/dist/feature-flags.d.ts +212 -0
- package/dist/feature-flags.d.ts.map +1 -0
- package/dist/handlers/handleListProjects.d.ts +3 -0
- package/dist/handlers/handleListProjects.d.ts.map +1 -0
- package/dist/index.cjs +84 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -2571
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -15
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/constants.d.ts +21 -0
- package/dist/lifecycle/constants.d.ts.map +1 -0
- package/dist/lifecycle/process-liveness.d.ts +7 -0
- package/dist/lifecycle/process-liveness.d.ts.map +1 -0
- package/dist/live-session-manager.d.ts +59 -0
- package/dist/live-session-manager.d.ts.map +1 -0
- package/dist/logger.d.ts +14 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/pair-store.d.ts +60 -0
- package/dist/pair-store.d.ts.map +1 -0
- package/dist/platform.d.ts +25 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/process-discovery.d.ts +35 -0
- package/dist/process-discovery.d.ts.map +1 -0
- package/dist/providers.d.ts +7 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/pty-host/protocol.d.ts +270 -0
- package/dist/pty-host/protocol.d.ts.map +1 -0
- package/dist/pty-host/remote-session-runner.d.ts +133 -0
- package/dist/pty-host/remote-session-runner.d.ts.map +1 -0
- package/dist/pty-host/socket.d.ts +54 -0
- package/dist/pty-host/socket.d.ts.map +1 -0
- package/dist/pty-host/spawn-host.d.ts +30 -0
- package/dist/pty-host/spawn-host.d.ts.map +1 -0
- package/dist/pty-manager.d.ts +65 -0
- package/dist/pty-manager.d.ts.map +1 -0
- package/dist/pty-shared.d.ts +27 -0
- package/dist/pty-shared.d.ts.map +1 -0
- package/dist/scanner-manager.d.ts +126 -0
- package/dist/scanner-manager.d.ts.map +1 -0
- package/dist/schemas/cacheAlert.schema.d.ts +14 -0
- package/dist/schemas/cacheAlert.schema.d.ts.map +1 -0
- package/dist/schemas/claudeFlags.schema.d.ts +7 -0
- package/dist/schemas/claudeFlags.schema.d.ts.map +1 -0
- package/dist/schemas/project.schema.d.ts +18 -0
- package/dist/schemas/project.schema.d.ts.map +1 -0
- package/dist/schemas/updateConfig.schema.d.ts +19 -0
- package/dist/schemas/updateConfig.schema.d.ts.map +1 -0
- package/dist/seal.d.ts +14 -0
- package/dist/seal.d.ts.map +1 -0
- package/dist/server-identity.d.ts +43 -0
- package/dist/server-identity.d.ts.map +1 -0
- package/dist/server-wiring.d.ts +184 -0
- package/dist/server-wiring.d.ts.map +1 -0
- package/dist/server.d.ts +390 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/services/backup/backup.d.ts +103 -0
- package/dist/services/backup/backup.d.ts.map +1 -0
- package/dist/services/cache/cacheMetadata.d.ts +8 -0
- package/dist/services/cache/cacheMetadata.d.ts.map +1 -0
- package/dist/services/cache-integrity/alertStore.d.ts +24 -0
- package/dist/services/cache-integrity/alertStore.d.ts.map +1 -0
- package/dist/services/cache-integrity/backup.d.ts +8 -0
- package/dist/services/cache-integrity/backup.d.ts.map +1 -0
- package/dist/services/cache-integrity/cacheIntegrityMonitor.d.ts +71 -0
- package/dist/services/cache-integrity/cacheIntegrityMonitor.d.ts.map +1 -0
- package/dist/services/conversations/conversationWatcher.d.ts +99 -0
- package/dist/services/conversations/conversationWatcher.d.ts.map +1 -0
- package/dist/services/conversations/findSearchTarget.d.ts +30 -0
- package/dist/services/conversations/findSearchTarget.d.ts.map +1 -0
- package/dist/services/conversations/isAgentConversation.d.ts +8 -0
- package/dist/services/conversations/isAgentConversation.d.ts.map +1 -0
- package/dist/services/conversations/pruneAgentConversations.d.ts +8 -0
- package/dist/services/conversations/pruneAgentConversations.d.ts.map +1 -0
- package/dist/services/conversations/refreshConversationCache.d.ts +27 -0
- package/dist/services/conversations/refreshConversationCache.d.ts.map +1 -0
- package/dist/services/conversations/shouldRefreshProjectsFromHdd.d.ts +33 -0
- package/dist/services/conversations/shouldRefreshProjectsFromHdd.d.ts.map +1 -0
- package/dist/services/diagnostics/diagnostics.d.ts +66 -0
- package/dist/services/diagnostics/diagnostics.d.ts.map +1 -0
- package/dist/services/projectChats/deriveProjectChatTitle.d.ts +15 -0
- package/dist/services/projectChats/deriveProjectChatTitle.d.ts.map +1 -0
- package/dist/services/projects/ensureProjectsForConversations.d.ts +15 -0
- package/dist/services/projects/ensureProjectsForConversations.d.ts.map +1 -0
- package/dist/services/providers/capabilities.d.ts +105 -0
- package/dist/services/providers/capabilities.d.ts.map +1 -0
- package/dist/services/providers/providerHealth.d.ts +72 -0
- package/dist/services/providers/providerHealth.d.ts.map +1 -0
- package/dist/services/push/apnsClient.d.ts +105 -0
- package/dist/services/push/apnsClient.d.ts.map +1 -0
- package/dist/services/push/expoPushSender.d.ts +37 -0
- package/dist/services/push/expoPushSender.d.ts.map +1 -0
- package/dist/services/push/liveActivityContentState.d.ts +60 -0
- package/dist/services/push/liveActivityContentState.d.ts.map +1 -0
- package/dist/services/push/liveActivityNotifier.d.ts +49 -0
- package/dist/services/push/liveActivityNotifier.d.ts.map +1 -0
- package/dist/services/push/liveActivityRenewal.d.ts +63 -0
- package/dist/services/push/liveActivityRenewal.d.ts.map +1 -0
- package/dist/services/push/liveActivitySender.d.ts +88 -0
- package/dist/services/push/liveActivitySender.d.ts.map +1 -0
- package/dist/services/push/waitingInputNotifier.d.ts +41 -0
- package/dist/services/push/waitingInputNotifier.d.ts.map +1 -0
- package/dist/services/questions/answersToKeystrokes.d.ts +8 -0
- package/dist/services/questions/answersToKeystrokes.d.ts.map +1 -0
- package/dist/services/questions/codexGateAnswers.d.ts +14 -0
- package/dist/services/questions/codexGateAnswers.d.ts.map +1 -0
- package/dist/services/questions/codexScreen.d.ts +74 -0
- package/dist/services/questions/codexScreen.d.ts.map +1 -0
- package/dist/services/questions/detectAskUserQuestion.d.ts +6 -0
- package/dist/services/questions/detectAskUserQuestion.d.ts.map +1 -0
- package/dist/services/questions/detectPermissionGate.d.ts +62 -0
- package/dist/services/questions/detectPermissionGate.d.ts.map +1 -0
- package/dist/services/questions/detectQuestionFromScreen.d.ts +30 -0
- package/dist/services/questions/detectQuestionFromScreen.d.ts.map +1 -0
- package/dist/services/questions/detectShellPrompt.d.ts +18 -0
- package/dist/services/questions/detectShellPrompt.d.ts.map +1 -0
- package/dist/services/questions/parseAgentPhase.d.ts +12 -0
- package/dist/services/questions/parseAgentPhase.d.ts.map +1 -0
- package/dist/services/questions/parseStatusLine.d.ts +19 -0
- package/dist/services/questions/parseStatusLine.d.ts.map +1 -0
- package/dist/services/questions/questionBroadcast.d.ts +18 -0
- package/dist/services/questions/questionBroadcast.d.ts.map +1 -0
- package/dist/services/questions/resolveAnswer.d.ts +16 -0
- package/dist/services/questions/resolveAnswer.d.ts.map +1 -0
- package/dist/services/search/searchQuery.d.ts +78 -0
- package/dist/services/search/searchQuery.d.ts.map +1 -0
- package/dist/services/security/capabilities.d.ts +50 -0
- package/dist/services/security/capabilities.d.ts.map +1 -0
- package/dist/services/sessions/autoResumeOnBoot.d.ts +28 -0
- package/dist/services/sessions/autoResumeOnBoot.d.ts.map +1 -0
- package/dist/services/sessions/codexRolloutOwner.d.ts +55 -0
- package/dist/services/sessions/codexRolloutOwner.d.ts.map +1 -0
- package/dist/services/sessions/conversationBusy.d.ts +32 -0
- package/dist/services/sessions/conversationBusy.d.ts.map +1 -0
- package/dist/services/sessions/idempotency.d.ts +67 -0
- package/dist/services/sessions/idempotency.d.ts.map +1 -0
- package/dist/services/sessions/reconcileSessions.d.ts +63 -0
- package/dist/services/sessions/reconcileSessions.d.ts.map +1 -0
- package/dist/services/sessions/rehydrateSessions.d.ts +68 -0
- package/dist/services/sessions/rehydrateSessions.d.ts.map +1 -0
- package/dist/services/sessions/resumeIdentity.d.ts +16 -0
- package/dist/services/sessions/resumeIdentity.d.ts.map +1 -0
- package/dist/session-registry-boot.d.ts +142 -0
- package/dist/session-registry-boot.d.ts.map +1 -0
- package/dist/session-store.d.ts +32 -0
- package/dist/session-store.d.ts.map +1 -0
- package/dist/session-watchers.d.ts +60 -0
- package/dist/session-watchers.d.ts.map +1 -0
- package/dist/types.d.ts +616 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/uploads.d.ts +16 -0
- package/dist/uploads.d.ts.map +1 -0
- package/dist/utils/bootToken.d.ts +3 -0
- package/dist/utils/bootToken.d.ts.map +1 -0
- package/dist/utils/canonicalizeFilePath.d.ts +75 -0
- package/dist/utils/canonicalizeFilePath.d.ts.map +1 -0
- package/dist/utils/canonicalizeProjectPath.d.ts +13 -0
- package/dist/utils/canonicalizeProjectPath.d.ts.map +1 -0
- package/dist/utils/codexConversationLine.d.ts +38 -0
- package/dist/utils/codexConversationLine.d.ts.map +1 -0
- package/dist/utils/conversationEtag.d.ts +19 -0
- package/dist/utils/conversationEtag.d.ts.map +1 -0
- package/dist/utils/dates.d.ts +12 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/debounce.d.ts +15 -0
- package/dist/utils/debounce.d.ts.map +1 -0
- package/dist/utils/deriveSessionName.d.ts +10 -0
- package/dist/utils/deriveSessionName.d.ts.map +1 -0
- package/dist/utils/fileIdentity.d.ts +36 -0
- package/dist/utils/fileIdentity.d.ts.map +1 -0
- package/dist/utils/isScannedSnapshotStale.d.ts +16 -0
- package/dist/utils/isScannedSnapshotStale.d.ts.map +1 -0
- package/dist/utils/scanProgressThrottle.d.ts +12 -0
- package/dist/utils/scanProgressThrottle.d.ts.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/ws-hub.d.ts +15 -0
- package/dist/ws-hub.d.ts.map +1 -0
- package/package.json +3 -4
- package/dist/index.d.cts +0 -2571
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare const LAUNCHD_LABEL = "com.ronen.threadbase";
|
|
2
|
+
export declare const TASK_NAME: string;
|
|
3
|
+
export declare const DEFAULT_PROD_PORT = 8766;
|
|
4
|
+
export declare function installDir(): string;
|
|
5
|
+
export declare function markerPath(): string;
|
|
6
|
+
export declare function prefsPath(): string;
|
|
7
|
+
export declare function activeLink(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Absolute paths to the supervised streamer's stdout/stderr logs — the single
|
|
10
|
+
* source of truth every supervisor backend and deploy script must agree on.
|
|
11
|
+
*
|
|
12
|
+
* macOS points the plist's StandardOutPath/StandardErrorPath here; Windows has
|
|
13
|
+
* no native redirection, so `scripts/deploy.ps1` writes the same two paths into
|
|
14
|
+
* launch.cmd as cmd `>>` targets. That agreement is what `tb-streamer prod logs`
|
|
15
|
+
* depends on, and it is locked by `__tests__/deploy-windows-script.test.ts`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function logPaths(): {
|
|
18
|
+
stdout: string;
|
|
19
|
+
stderr: string;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lifecycle/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,aAAa,yBAAyB,CAAC;AACpD,eAAO,MAAM,SAAS,QAAmD,CAAC;AAC1E,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAG7D"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POSIX trick: kill(pid, 0) sends no signal but throws ESRCH if no such PID,
|
|
3
|
+
* EPERM if the PID exists but is owned by another user. Either way the
|
|
4
|
+
* process exists; ESRCH alone means dead.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isPidAlive(pid: number): boolean;
|
|
7
|
+
//# sourceMappingURL=process-liveness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-liveness.d.ts","sourceRoot":"","sources":["../../src/lifecycle/process-liveness.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAS/C"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type ProviderName } from "./providers";
|
|
2
|
+
import type { HostHeartbeatState, HostTransport } from "./pty-host/protocol";
|
|
3
|
+
import type { ManagedSession, PTYManagerOptions, StartForkSessionOptions, StartFreshSessionOptions, StartSessionOptions, UserMessage } from "./types";
|
|
4
|
+
export declare class LiveSessionManager {
|
|
5
|
+
private runners;
|
|
6
|
+
private remoteRunner;
|
|
7
|
+
private options;
|
|
8
|
+
constructor(options?: PTYManagerOptions);
|
|
9
|
+
useRemoteRunner(transport: HostTransport): Promise<ManagedSession[]>;
|
|
10
|
+
isRemote(): boolean;
|
|
11
|
+
startRemoteHeartbeat(getState: () => HostHeartbeatState): void;
|
|
12
|
+
start(sessionId: string, options: StartSessionOptions & {
|
|
13
|
+
provider?: ProviderName;
|
|
14
|
+
}): Promise<ManagedSession>;
|
|
15
|
+
startFresh(options: StartFreshSessionOptions & {
|
|
16
|
+
provider?: ProviderName;
|
|
17
|
+
}): Promise<ManagedSession>;
|
|
18
|
+
/**
|
|
19
|
+
* Fork an existing conversation into a new session. Codex-only: `codex fork`
|
|
20
|
+
* has no Claude Code equivalent, and there is no safe generic fallback — a
|
|
21
|
+
* silent downgrade to resume would attach to the very writer the caller is
|
|
22
|
+
* trying to leave alone.
|
|
23
|
+
*/
|
|
24
|
+
startFork(options: StartForkSessionOptions & {
|
|
25
|
+
provider?: ProviderName;
|
|
26
|
+
}): Promise<ManagedSession>;
|
|
27
|
+
sendInput(sessionId: string, input: string): number;
|
|
28
|
+
sendKeys(sessionId: string, keys: string): void;
|
|
29
|
+
cancel(sessionId: string): void;
|
|
30
|
+
killPid(pid: number): void;
|
|
31
|
+
putOnHold(sessionId: string): void;
|
|
32
|
+
getOutput(sessionId: string): string;
|
|
33
|
+
getOutputLines(sessionId: string, maxLines: number): Promise<string[]>;
|
|
34
|
+
getInputHistory(sessionId: string): UserMessage[];
|
|
35
|
+
getSession(sessionId: string): ManagedSession | null;
|
|
36
|
+
getPid(sessionId: string): number | null;
|
|
37
|
+
hasSession(sessionId: string): boolean;
|
|
38
|
+
listSessions(): ManagedSession[];
|
|
39
|
+
dispose(): void;
|
|
40
|
+
private runnerFor;
|
|
41
|
+
/**
|
|
42
|
+
* Refuse before spawning when the provider's CLI is not on this machine.
|
|
43
|
+
*
|
|
44
|
+
* Without this the spawn "succeeds": on POSIX execvp fails inside the forked
|
|
45
|
+
* child, so a session appears, exits ~12ms later with code 1 and no output,
|
|
46
|
+
* and the caller is told only that it "exited before becoming ready" — or,
|
|
47
|
+
* on the Claude resume path, is told nothing at all, since that path answers
|
|
48
|
+
* 200 before the process has had a chance to die. Every start route funnels
|
|
49
|
+
* through here, so one check covers start, resume, adopt and fork.
|
|
50
|
+
*
|
|
51
|
+
* 503, not 500: the request was well-formed and the fault is this machine's
|
|
52
|
+
* environment. `code` is what mobile branches on (it reads `errBody.code`),
|
|
53
|
+
* and `PROVIDER_NOT_INSTALLED` is a remediation string it already knows.
|
|
54
|
+
*/
|
|
55
|
+
private assertProviderInstalled;
|
|
56
|
+
private assertSupportedProvider;
|
|
57
|
+
private activeRunners;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=live-session-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live-session-manager.d.ts","sourceRoot":"","sources":["../src/live-session-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4C,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAG7E,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EAEjB,uBAAuB,EACvB,wBAAwB,EACxB,mBAAmB,EACnB,WAAW,EACZ,MAAM,SAAS,CAAC;AAEjB,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,OAAO,CAAoB;IAEnC,YAAY,OAAO,GAAE,iBAAsB,EAM1C;IAEK,eAAe,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAQzE;IAED,QAAQ,IAAI,OAAO,CAElB;IAED,oBAAoB,CAAC,QAAQ,EAAE,MAAM,kBAAkB,GAAG,IAAI,CAE7D;IAEK,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mBAAmB,GAAG;QAAE,QAAQ,CAAC,EAAE,YAAY,CAAA;KAAE,GACzD,OAAO,CAAC,cAAc,CAAC,CAKzB;IAEK,UAAU,CACd,OAAO,EAAE,wBAAwB,GAAG;QAAE,QAAQ,CAAC,EAAE,YAAY,CAAA;KAAE,GAC9D,OAAO,CAAC,cAAc,CAAC,CAKzB;IAED;;;;;OAKG;IACG,SAAS,CACb,OAAO,EAAE,uBAAuB,GAAG;QAAE,QAAQ,CAAC,EAAE,YAAY,CAAA;KAAE,GAC7D,OAAO,CAAC,cAAc,CAAC,CAczB;IAED,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;IAED,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAE9C;IAED,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE9B;IAED,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAIzB;IAOD,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAUjC;IAED,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnC;IAED,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAErE;IAED,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAEhD;IAED,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAMnD;IAKD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvC;IAED,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAKrC;IAED,YAAY,IAAI,cAAc,EAAE,CAE/B;IAED,OAAO,IAAI,IAAI,CAId;IAKD,OAAO,CAAC,SAAS;IAOjB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,uBAAuB;IAgB/B,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,aAAa;CAGtB"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Logger as PinoLogger } from "pino";
|
|
2
|
+
export type LogDest = "console" | "pino" | "both";
|
|
3
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
4
|
+
export interface Logger {
|
|
5
|
+
debug(msg: string, fields?: Record<string, unknown>, dest?: LogDest): void;
|
|
6
|
+
info(msg: string, fields?: Record<string, unknown>, dest?: LogDest): void;
|
|
7
|
+
warn(msg: string, fields?: Record<string, unknown>, dest?: LogDest): void;
|
|
8
|
+
error(msg: string, fields?: Record<string, unknown>, dest?: LogDest): void;
|
|
9
|
+
log(level: LogLevel, msg: string, fields?: Record<string, unknown>, dest?: LogDest): void;
|
|
10
|
+
pino: PinoLogger;
|
|
11
|
+
}
|
|
12
|
+
export declare function getLogger(component?: string): Logger;
|
|
13
|
+
export declare const logger: Logger;
|
|
14
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAa,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAY3D,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3E,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1E,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1E,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3E,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1F,IAAI,EAAE,UAAU,CAAC;CAClB;AAiDD,wBAAgB,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,eAAO,MAAM,MAAM,EAAE,MAA0B,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface PairTokenRecord {
|
|
2
|
+
token: string;
|
|
3
|
+
expiresAt: number;
|
|
4
|
+
used: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface MintResult {
|
|
7
|
+
token: string;
|
|
8
|
+
expiresAt: number;
|
|
9
|
+
expiresInSeconds: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ConsumeOk {
|
|
12
|
+
ok: true;
|
|
13
|
+
}
|
|
14
|
+
export interface ConsumeErr {
|
|
15
|
+
ok: false;
|
|
16
|
+
reason: "unknown" | "expired" | "used";
|
|
17
|
+
}
|
|
18
|
+
export type ConsumeResult = ConsumeOk | ConsumeErr;
|
|
19
|
+
export declare class PairTokenStore {
|
|
20
|
+
private current;
|
|
21
|
+
private readonly ttlMs;
|
|
22
|
+
private sweepTimer;
|
|
23
|
+
constructor(opts?: {
|
|
24
|
+
ttlSeconds?: number;
|
|
25
|
+
autoSweep?: boolean;
|
|
26
|
+
});
|
|
27
|
+
mint(): MintResult;
|
|
28
|
+
/**
|
|
29
|
+
* What `consume` would answer right now, WITHOUT spending the token.
|
|
30
|
+
*
|
|
31
|
+
* Exists so a caller can reject a bad token before doing any work, and still
|
|
32
|
+
* spend the token only once the work has succeeded. A pair token is
|
|
33
|
+
* single-use and lives 180 seconds, so spending it on a request that then
|
|
34
|
+
* fails costs the user a whole new QR — and, worse, makes their retry
|
|
35
|
+
* indistinguishable from an attacker replaying a photographed code, which is
|
|
36
|
+
* the one signal `design.md` §2.6 designates as replay detection.
|
|
37
|
+
*
|
|
38
|
+
* **Named for its relationship to `consume`, deliberately.** It reserves
|
|
39
|
+
* nothing and takes no lock, so two callers can both be told `{ ok: true }`
|
|
40
|
+
* for the same token. A name like `verify` would read as a gate that had
|
|
41
|
+
* decided something, and inviting a caller to act on this alone is precisely
|
|
42
|
+
* the misuse the ordering it enables exists to prevent. A reader who sees
|
|
43
|
+
* `wouldConsume` asks where the `consume` is, which is the right question.
|
|
44
|
+
*/
|
|
45
|
+
wouldConsume(token: string): ConsumeResult;
|
|
46
|
+
consume(token: string): ConsumeResult;
|
|
47
|
+
/**
|
|
48
|
+
* The shared predicate behind `verify` and `consume`.
|
|
49
|
+
*
|
|
50
|
+
* One implementation on purpose: two copies of "is this token usable" is two
|
|
51
|
+
* places for the expiry or single-use rule to drift, and a drift in this
|
|
52
|
+
* direction fails open.
|
|
53
|
+
*/
|
|
54
|
+
private check;
|
|
55
|
+
peek(): PairTokenRecord | null;
|
|
56
|
+
clear(): void;
|
|
57
|
+
sweep(): void;
|
|
58
|
+
dispose(): void;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=pair-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pair-store.d.ts","sourceRoot":"","sources":["../src/pair-store.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,IAAI,CAAC;CACV;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;AAKnD,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,UAAU,CAA+C;IAEjE,YAAY,IAAI,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAO,EAMlE;IAED,IAAI,IAAI,UAAU,CASjB;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAGzC;IAED,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAKpC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,KAAK;IAWb,IAAI,IAAI,eAAe,GAAG,IAAI,CAE7B;IAED,KAAK,IAAI,IAAI,CAEZ;IAED,KAAK,IAAI,IAAI,CAIZ;IAED,OAAO,IAAI,IAAI,CAId;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { execFileSync } from "child_process";
|
|
2
|
+
import { type ProviderName } from "./providers";
|
|
3
|
+
export declare const isWindows: boolean;
|
|
4
|
+
export declare function clearClaudeExeCache(): void;
|
|
5
|
+
export declare function resolveClaudeExe(): string;
|
|
6
|
+
export declare function clearCodexExeCache(): void;
|
|
7
|
+
export declare function resolveCodexExe(): string;
|
|
8
|
+
/**
|
|
9
|
+
* Where `exe` — a resolver's output — actually lives, or null if nowhere.
|
|
10
|
+
*
|
|
11
|
+
* A value carrying a path separator is checked directly; a bare command name is
|
|
12
|
+
* searched along PATH exactly the way execvp will search it. node-pty inherits
|
|
13
|
+
* the streamer's own environment (`buildSpawnEnv`), so the PATH walked here is
|
|
14
|
+
* the PATH the spawned child gets — which is what makes this predictive of the
|
|
15
|
+
* spawn rather than merely correlated with it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function locateExecutable(exe: string): string | null;
|
|
18
|
+
/** Where this provider's CLI lives on this machine, or null if it is absent. */
|
|
19
|
+
export declare function locateProviderExe(provider: ProviderName): string | null;
|
|
20
|
+
type SyncOptions = Parameters<typeof execFileSync>[2];
|
|
21
|
+
export declare function execHidden(file: string, args: string[], opts?: SyncOptions & {
|
|
22
|
+
encoding: "utf-8";
|
|
23
|
+
}): string;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAI7C,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEpE,eAAO,MAAM,SAAS,SAAyB,CAAC;AAkChD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAiEzC;AAWD,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAiExC;AA2BD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuB3D;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAWvE;AAOD,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtD,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,CAAC,EAAE,WAAW,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,GACzC,MAAM,CAKR"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DiscoveredProcess } from "./types";
|
|
2
|
+
export declare function discoverClaudeProcesses(): Promise<DiscoveredProcess[]>;
|
|
3
|
+
export declare function tokenizeCommandLine(commandLine: string): string[];
|
|
4
|
+
/**
|
|
5
|
+
* Whether a command line is a Claude Code CLI process.
|
|
6
|
+
*
|
|
7
|
+
* Accepts a native binary invoked by any path, and a JS runtime hosting the
|
|
8
|
+
* published CLI entry point. Deliberately conservative: it inspects only the
|
|
9
|
+
* executable and the script it runs, never the whole string, so an unrelated
|
|
10
|
+
* process that merely mentions "claude" in a flag (an editor session, this
|
|
11
|
+
* streamer itself) is not mistaken for an agent.
|
|
12
|
+
*/
|
|
13
|
+
export declare function looksLikeClaudeProcess(commandLine: string): boolean;
|
|
14
|
+
export declare function parsePsOutput(stdout: string): number[];
|
|
15
|
+
/**
|
|
16
|
+
* Full command line of a single live process, or "" if it cannot be read.
|
|
17
|
+
*
|
|
18
|
+
* Used by the boot reconciler's pid-reuse guard: a recorded pid being alive is
|
|
19
|
+
* never sufficient evidence that the process is still ours, because pids get
|
|
20
|
+
* recycled. The caller matches its stored token against this before claiming a
|
|
21
|
+
* surviving session — and treats an unreadable command line as "cannot confirm"
|
|
22
|
+
* rather than "confirmed", so a failure here can never promote an unrelated
|
|
23
|
+
* process into a managed session.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getProcessArgs(pid: number): Promise<string>;
|
|
26
|
+
interface CimProcess {
|
|
27
|
+
ProcessId: number;
|
|
28
|
+
CommandLine: string | null;
|
|
29
|
+
CreationDate: string | null;
|
|
30
|
+
}
|
|
31
|
+
export declare function parseCimProcesses(stdout: string): CimProcess[];
|
|
32
|
+
export declare function parseCimDate(value: string | null): Date;
|
|
33
|
+
export declare function extractResumeId(args: string): string | null;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=process-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-discovery.d.ts","sourceRoot":"","sources":["../src/process-discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAG5E;AAaD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBjE;AAWD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAenE;AAwFD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAYtD;AAiCD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAajE;AAUD,UAAU,UAAU;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAKD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAK9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAQvD;AAgHD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO3D"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const CLAUDE_CODE_PROVIDER: "claude-code";
|
|
2
|
+
export declare const CODEX_CLI_PROVIDER: "codex-cli";
|
|
3
|
+
export type ProviderName = typeof CLAUDE_CODE_PROVIDER | typeof CODEX_CLI_PROVIDER;
|
|
4
|
+
export declare function isProviderName(value: unknown): value is ProviderName;
|
|
5
|
+
export declare function coerceProviderForRunner(value: unknown): ProviderName;
|
|
6
|
+
export declare function isProviderResumable(_provider: string | null | undefined, availabilityResumable: boolean): boolean;
|
|
7
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,EAAG,aAAsB,CAAC;AAC3D,eAAO,MAAM,kBAAkB,EAAG,WAAoB,CAAC;AACvD,MAAM,MAAM,YAAY,GAAG,OAAO,oBAAoB,GAAG,OAAO,kBAAkB,CAAC;AAEnF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAMD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAEpE;AAQD,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,qBAAqB,EAAE,OAAO,GAC7B,OAAO,CAET"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import type { ProviderName } from "../providers";
|
|
2
|
+
import type { AgentPhase, AskQuestion, ManagedSession, PermissionOption, StartFreshSessionOptions, StartSessionOptions, UserMessage } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Wire protocol between the streamer and `tb-streamer pty-host`
|
|
5
|
+
* (persistence plan Phase 6a).
|
|
6
|
+
* See docs/plans/live-sessions-persistence-plan.md §4 and
|
|
7
|
+
* docs/architecture/2026-07-24-durable-session-runtime.md (alternative D).
|
|
8
|
+
*
|
|
9
|
+
* The point of the host is that the PTY master fd is held by a process that is
|
|
10
|
+
* NOT being restarted. Everything the audit lists as lost with the streamer —
|
|
11
|
+
* node-pty, the ring buffer, the xterm screen, inputHistory, pendingReady,
|
|
12
|
+
* queuedInputs, and the prompt/gate detectors — lives on the host side of this
|
|
13
|
+
* boundary; the streamer keeps only a mirror it can rebuild from `status`.
|
|
14
|
+
*
|
|
15
|
+
* Newline-delimited JSON rather than a binary framing: PTY output is already
|
|
16
|
+
* being JSON-escaped for the WebSocket hub a layer above, the volumes are a
|
|
17
|
+
* terminal's worth of bytes rather than a video stream, and a protocol you can
|
|
18
|
+
* read with `nc` is worth more during an incident than the bytes it saves.
|
|
19
|
+
*
|
|
20
|
+
* Two message directions, never mixed:
|
|
21
|
+
*
|
|
22
|
+
* - **Requests** (streamer → host) each carry an `id` and are answered by
|
|
23
|
+
* exactly one `Response` with the same `id`.
|
|
24
|
+
* - **Events** (host → streamer) are unsolicited and carry no `id`. They are
|
|
25
|
+
* the transport for what are callbacks in `PTYManagerOptions` today; the
|
|
26
|
+
* detectors that fire them run in the host, so every one of those callbacks
|
|
27
|
+
* needs an event here or the feature silently stops working when the flag
|
|
28
|
+
* is on. That is why this list is longer than the sketch in the plan.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately absent: `resize`. The plan lists it, but PTY dimensions are the
|
|
31
|
+
* fixed `PTY_COLS`/`PTY_ROWS` constants and `SessionRunner` has no resize
|
|
32
|
+
* method, so the verb would be one nothing could ever send. Add it with the
|
|
33
|
+
* caller that needs it.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Bumped on any incompatible change to the shapes below. Version 2 adds the
|
|
37
|
+
* heartbeat and shutdown controls required for host supervision. Version 3
|
|
38
|
+
* adds the `phase-change` event — the detector runs in the host, so without a
|
|
39
|
+
* verb here the agent-phase indicator silently stops working when the flag is
|
|
40
|
+
* on, which is exactly the failure this file's header warns about.
|
|
41
|
+
*/
|
|
42
|
+
export declare const PTY_HOST_PROTOCOL_VERSION = 3;
|
|
43
|
+
export interface HostHeartbeatState {
|
|
44
|
+
registryState: "known" | "unknown";
|
|
45
|
+
referencedSessionIds: string[];
|
|
46
|
+
}
|
|
47
|
+
/** `spawn` with a null sessionId means startFresh — the host assigns the id. */
|
|
48
|
+
export type SpawnRequest = {
|
|
49
|
+
id: number;
|
|
50
|
+
type: "spawn";
|
|
51
|
+
provider: ProviderName;
|
|
52
|
+
} & ({
|
|
53
|
+
sessionId: string;
|
|
54
|
+
options: StartSessionOptions;
|
|
55
|
+
} | {
|
|
56
|
+
sessionId: null;
|
|
57
|
+
options: StartFreshSessionOptions;
|
|
58
|
+
});
|
|
59
|
+
export type HostRequest = SpawnRequest
|
|
60
|
+
/** A submitted user message. Answered with the session's new promptCount. */
|
|
61
|
+
| {
|
|
62
|
+
id: number;
|
|
63
|
+
type: "write";
|
|
64
|
+
sessionId: string;
|
|
65
|
+
input: string;
|
|
66
|
+
}
|
|
67
|
+
/** Raw keystrokes — never recorded as a user message. */
|
|
68
|
+
| {
|
|
69
|
+
id: number;
|
|
70
|
+
type: "keys";
|
|
71
|
+
sessionId: string;
|
|
72
|
+
keys: string;
|
|
73
|
+
}
|
|
74
|
+
/** Begin receiving events. Sent once per connection after status passes the version check. */
|
|
75
|
+
| {
|
|
76
|
+
id: number;
|
|
77
|
+
type: "subscribe";
|
|
78
|
+
}
|
|
79
|
+
/** The rendered screen, newest `maxLines` rows, in true on-screen order. */
|
|
80
|
+
| {
|
|
81
|
+
id: number;
|
|
82
|
+
type: "replay";
|
|
83
|
+
sessionId: string;
|
|
84
|
+
maxLines: number;
|
|
85
|
+
} | {
|
|
86
|
+
id: number;
|
|
87
|
+
type: "input-history";
|
|
88
|
+
sessionId: string;
|
|
89
|
+
} | {
|
|
90
|
+
id: number;
|
|
91
|
+
type: "cancel";
|
|
92
|
+
sessionId: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Stop a session. `hold` is `putOnHold` (SIGINT, history intact, resumable);
|
|
96
|
+
* without it, and addressed by `pid`, it is `killPid`. One verb because the
|
|
97
|
+
* host's answer is the same either way: that process is no longer running.
|
|
98
|
+
*/
|
|
99
|
+
| {
|
|
100
|
+
id: number;
|
|
101
|
+
type: "kill";
|
|
102
|
+
sessionId: string;
|
|
103
|
+
hold: true;
|
|
104
|
+
} | {
|
|
105
|
+
id: number;
|
|
106
|
+
type: "kill";
|
|
107
|
+
pid: number;
|
|
108
|
+
hold?: false;
|
|
109
|
+
} | ({
|
|
110
|
+
id: number;
|
|
111
|
+
type: "heartbeat";
|
|
112
|
+
} & HostHeartbeatState)
|
|
113
|
+
/** Stop this host after acknowledging the request. Used only on version skew. */
|
|
114
|
+
| {
|
|
115
|
+
id: number;
|
|
116
|
+
type: "shutdown-host";
|
|
117
|
+
}
|
|
118
|
+
/** Every session the host owns. Seeds the streamer's mirror on connect. */
|
|
119
|
+
| {
|
|
120
|
+
id: number;
|
|
121
|
+
type: "status";
|
|
122
|
+
};
|
|
123
|
+
export type HostRequestType = HostRequest["type"];
|
|
124
|
+
/**
|
|
125
|
+
* One response per request, correlated by `id`.
|
|
126
|
+
*
|
|
127
|
+
* A failure is a value, not a dropped message: a request that never gets a
|
|
128
|
+
* response leaves the caller's promise pending forever, which is how a
|
|
129
|
+
* transport bug turns into a hung session start rather than an error.
|
|
130
|
+
*/
|
|
131
|
+
export type HostResponse = {
|
|
132
|
+
id: number;
|
|
133
|
+
ok: true;
|
|
134
|
+
result: unknown;
|
|
135
|
+
} | {
|
|
136
|
+
id: number;
|
|
137
|
+
ok: false;
|
|
138
|
+
error: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Unsolicited host → streamer messages. One per `PTYManagerOptions` callback,
|
|
142
|
+
* plus `exit`, which is `onStatusChange` with the process actually gone.
|
|
143
|
+
*/
|
|
144
|
+
export type HostEvent = {
|
|
145
|
+
type: "event";
|
|
146
|
+
event: "output";
|
|
147
|
+
sessionId: string;
|
|
148
|
+
data: string;
|
|
149
|
+
} | {
|
|
150
|
+
type: "event";
|
|
151
|
+
event: "status-change";
|
|
152
|
+
session: ManagedSession;
|
|
153
|
+
} | {
|
|
154
|
+
type: "event";
|
|
155
|
+
event: "ready";
|
|
156
|
+
session: ManagedSession;
|
|
157
|
+
} | {
|
|
158
|
+
type: "event";
|
|
159
|
+
event: "permission-change";
|
|
160
|
+
sessionId: string;
|
|
161
|
+
gate: {
|
|
162
|
+
prompt?: string;
|
|
163
|
+
detail?: string;
|
|
164
|
+
options: PermissionOption[];
|
|
165
|
+
cursor?: number;
|
|
166
|
+
} | null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Agent phase changed within a running turn, including to `null` at turn
|
|
170
|
+
* end. Carries the same always-present/nullable contract as the wire field:
|
|
171
|
+
* absence must never mean "cleared", because the consumer merges state.
|
|
172
|
+
*/
|
|
173
|
+
| {
|
|
174
|
+
type: "event";
|
|
175
|
+
event: "phase-change";
|
|
176
|
+
sessionId: string;
|
|
177
|
+
phase: AgentPhase | null;
|
|
178
|
+
} | {
|
|
179
|
+
type: "event";
|
|
180
|
+
event: "live-question";
|
|
181
|
+
sessionId: string;
|
|
182
|
+
questions: AskQuestion[];
|
|
183
|
+
} | {
|
|
184
|
+
type: "event";
|
|
185
|
+
event: "live-question-gone";
|
|
186
|
+
sessionId: string;
|
|
187
|
+
} | {
|
|
188
|
+
type: "event";
|
|
189
|
+
event: "user-message";
|
|
190
|
+
sessionId: string;
|
|
191
|
+
text: string;
|
|
192
|
+
ts: number;
|
|
193
|
+
} | {
|
|
194
|
+
type: "event";
|
|
195
|
+
event: "exit";
|
|
196
|
+
sessionId: string;
|
|
197
|
+
exitCode: number;
|
|
198
|
+
};
|
|
199
|
+
export type HostMessage = HostResponse | HostEvent;
|
|
200
|
+
export declare function isHostEvent(message: HostMessage): message is HostEvent;
|
|
201
|
+
/**
|
|
202
|
+
* A request minus the `id` the sender assigns.
|
|
203
|
+
*
|
|
204
|
+
* Distributive on purpose: a plain `Omit<HostRequest, "id">` collapses the
|
|
205
|
+
* union into its common keys, which loses `sessionId`, `provider` and the rest
|
|
206
|
+
* — so every call site fails to type-check against a request shape that is
|
|
207
|
+
* actually correct.
|
|
208
|
+
*/
|
|
209
|
+
export type HostRequestBody = HostRequest extends infer T ? T extends {
|
|
210
|
+
id: number;
|
|
211
|
+
} ? Omit<T, "id"> : never : never;
|
|
212
|
+
/**
|
|
213
|
+
* A session plus the one thing `ManagedSession` does not carry: the OS pid.
|
|
214
|
+
*
|
|
215
|
+
* The in-process runners read it off the node-pty handle, which lives on the
|
|
216
|
+
* host now — and the durable registry needs it at spawn to record something a
|
|
217
|
+
* later boot can probe. It is fixed for the life of a session, so `spawn` and
|
|
218
|
+
* `status` are the only messages that carry it.
|
|
219
|
+
*/
|
|
220
|
+
export interface HostSession {
|
|
221
|
+
session: ManagedSession;
|
|
222
|
+
pid: number | null;
|
|
223
|
+
}
|
|
224
|
+
/** Result shapes, named so both ends agree on what a given request answers. */
|
|
225
|
+
export interface StatusResult {
|
|
226
|
+
protocolVersion: number;
|
|
227
|
+
sessions: HostSession[];
|
|
228
|
+
}
|
|
229
|
+
export interface InputHistoryResult {
|
|
230
|
+
history: UserMessage[];
|
|
231
|
+
}
|
|
232
|
+
export interface ReplayResult {
|
|
233
|
+
lines: string[];
|
|
234
|
+
/** The raw ring buffer, so a reconnecting streamer can restore `getOutput`. */
|
|
235
|
+
output: string;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* A duplex line channel. Deliberately not a socket: the runner is tested
|
|
239
|
+
* against an in-memory pair, and PR 7 supplies the real one over a unix socket
|
|
240
|
+
* (POSIX) or named pipe (Windows).
|
|
241
|
+
*/
|
|
242
|
+
export interface HostTransport {
|
|
243
|
+
send(line: string): void;
|
|
244
|
+
onLine(handler: (line: string) => void): void;
|
|
245
|
+
onClose(handler: () => void): void;
|
|
246
|
+
close(): void;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Restore a `ManagedSession` that crossed the wire.
|
|
250
|
+
*
|
|
251
|
+
* JSON turns every `Date` into a string, and `ManagedSession.startedAt` is read
|
|
252
|
+
* as a Date all over the server (`elapsedMs` arithmetic, `toISOString()`).
|
|
253
|
+
* Without this the failure is a string where a Date is expected — which does
|
|
254
|
+
* not throw, it produces `NaN` elapsed times and a crash only at the
|
|
255
|
+
* `.toISOString()` call sites.
|
|
256
|
+
*/
|
|
257
|
+
export declare function reviveSession(raw: unknown): ManagedSession;
|
|
258
|
+
export declare function encodeMessage(message: HostRequest | HostMessage): string;
|
|
259
|
+
/**
|
|
260
|
+
* Reassemble newline-delimited JSON from arbitrarily-chunked reads.
|
|
261
|
+
*
|
|
262
|
+
* A socket splits wherever it likes, so "one chunk is one message" holds right
|
|
263
|
+
* up until a PTY burst makes it false. Stateful for exactly that reason: the
|
|
264
|
+
* tail of a chunk is held until its newline arrives.
|
|
265
|
+
*/
|
|
266
|
+
export declare class LineDecoder {
|
|
267
|
+
private buffer;
|
|
268
|
+
push(chunk: string): string[];
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/pty-host/protocol.ts"],"names":[],"mappings":"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"}
|