@thinkrun/cli 0.1.27
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 +349 -0
- package/dist/bin/thinkrun.d.ts +6 -0
- package/dist/bin/thinkrun.d.ts.map +1 -0
- package/dist/bin/thinkrun.js +124 -0
- package/dist/bin/thinkrun.js.map +1 -0
- package/dist/scripts/browse.sh +1107 -0
- package/dist/src/adapters/cloud.d.ts +79 -0
- package/dist/src/adapters/cloud.d.ts.map +1 -0
- package/dist/src/adapters/cloud.js +637 -0
- package/dist/src/adapters/cloud.js.map +1 -0
- package/dist/src/adapters/index.d.ts +47 -0
- package/dist/src/adapters/index.d.ts.map +1 -0
- package/dist/src/adapters/index.js +211 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/adapters/local-command-retry.d.ts +12 -0
- package/dist/src/adapters/local-command-retry.d.ts.map +1 -0
- package/dist/src/adapters/local-command-retry.js +224 -0
- package/dist/src/adapters/local-command-retry.js.map +1 -0
- package/dist/src/adapters/local.d.ts +136 -0
- package/dist/src/adapters/local.d.ts.map +1 -0
- package/dist/src/adapters/local.js +1273 -0
- package/dist/src/adapters/local.js.map +1 -0
- package/dist/src/adapters/types.d.ts +45 -0
- package/dist/src/adapters/types.d.ts.map +1 -0
- package/dist/src/adapters/types.js +6 -0
- package/dist/src/adapters/types.js.map +1 -0
- package/dist/src/commands/actions.d.ts +135 -0
- package/dist/src/commands/actions.d.ts.map +1 -0
- package/dist/src/commands/actions.js +2207 -0
- package/dist/src/commands/actions.js.map +1 -0
- package/dist/src/commands/agent-init.d.ts +16 -0
- package/dist/src/commands/agent-init.d.ts.map +1 -0
- package/dist/src/commands/agent-init.js +222 -0
- package/dist/src/commands/agent-init.js.map +1 -0
- package/dist/src/commands/analyze.d.ts +11 -0
- package/dist/src/commands/analyze.d.ts.map +1 -0
- package/dist/src/commands/analyze.js +238 -0
- package/dist/src/commands/analyze.js.map +1 -0
- package/dist/src/commands/cache.d.ts +6 -0
- package/dist/src/commands/cache.d.ts.map +1 -0
- package/dist/src/commands/cache.js +147 -0
- package/dist/src/commands/cache.js.map +1 -0
- package/dist/src/commands/cloud.d.ts +6 -0
- package/dist/src/commands/cloud.d.ts.map +1 -0
- package/dist/src/commands/cloud.js +332 -0
- package/dist/src/commands/cloud.js.map +1 -0
- package/dist/src/commands/config.d.ts +7 -0
- package/dist/src/commands/config.d.ts.map +1 -0
- package/dist/src/commands/config.js +208 -0
- package/dist/src/commands/config.js.map +1 -0
- package/dist/src/commands/doctor.d.ts +127 -0
- package/dist/src/commands/doctor.d.ts.map +1 -0
- package/dist/src/commands/doctor.js +684 -0
- package/dist/src/commands/doctor.js.map +1 -0
- package/dist/src/commands/evaluate-helpers.d.ts +6 -0
- package/dist/src/commands/evaluate-helpers.d.ts.map +1 -0
- package/dist/src/commands/evaluate-helpers.js +13 -0
- package/dist/src/commands/evaluate-helpers.js.map +1 -0
- package/dist/src/commands/install.d.ts +118 -0
- package/dist/src/commands/install.d.ts.map +1 -0
- package/dist/src/commands/install.js +975 -0
- package/dist/src/commands/install.js.map +1 -0
- package/dist/src/commands/release.d.ts +7 -0
- package/dist/src/commands/release.d.ts.map +1 -0
- package/dist/src/commands/release.js +123 -0
- package/dist/src/commands/release.js.map +1 -0
- package/dist/src/commands/reset-connection.d.ts +17 -0
- package/dist/src/commands/reset-connection.d.ts.map +1 -0
- package/dist/src/commands/reset-connection.js +141 -0
- package/dist/src/commands/reset-connection.js.map +1 -0
- package/dist/src/commands/session-debug.d.ts +23 -0
- package/dist/src/commands/session-debug.d.ts.map +1 -0
- package/dist/src/commands/session-debug.js +267 -0
- package/dist/src/commands/session-debug.js.map +1 -0
- package/dist/src/commands/setup.d.ts +53 -0
- package/dist/src/commands/setup.d.ts.map +1 -0
- package/dist/src/commands/setup.js +249 -0
- package/dist/src/commands/setup.js.map +1 -0
- package/dist/src/config/store.d.ts +39 -0
- package/dist/src/config/store.d.ts.map +1 -0
- package/dist/src/config/store.js +290 -0
- package/dist/src/config/store.js.map +1 -0
- package/dist/src/daemon/access.d.ts +53 -0
- package/dist/src/daemon/access.d.ts.map +1 -0
- package/dist/src/daemon/access.js +87 -0
- package/dist/src/daemon/access.js.map +1 -0
- package/dist/src/daemon/bridge-envelope.d.ts +96 -0
- package/dist/src/daemon/bridge-envelope.d.ts.map +1 -0
- package/dist/src/daemon/bridge-envelope.js +235 -0
- package/dist/src/daemon/bridge-envelope.js.map +1 -0
- package/dist/src/daemon/utils.d.ts +43 -0
- package/dist/src/daemon/utils.d.ts.map +1 -0
- package/dist/src/daemon/utils.js +134 -0
- package/dist/src/daemon/utils.js.map +1 -0
- package/dist/src/errors.d.ts +60 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +87 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/local-bridge-timing.d.ts +31 -0
- package/dist/src/local-bridge-timing.d.ts.map +1 -0
- package/dist/src/local-bridge-timing.js +41 -0
- package/dist/src/local-bridge-timing.js.map +1 -0
- package/dist/src/obstacle-recovery/classify-script.d.ts +16 -0
- package/dist/src/obstacle-recovery/classify-script.d.ts.map +1 -0
- package/dist/src/obstacle-recovery/classify-script.js +53 -0
- package/dist/src/obstacle-recovery/classify-script.js.map +1 -0
- package/dist/src/obstacle-recovery/obstacle-classifier.d.ts +21 -0
- package/dist/src/obstacle-recovery/obstacle-classifier.d.ts.map +1 -0
- package/dist/src/obstacle-recovery/obstacle-classifier.js +37 -0
- package/dist/src/obstacle-recovery/obstacle-classifier.js.map +1 -0
- package/dist/src/obstacle-recovery/state-fingerprint.d.ts +26 -0
- package/dist/src/obstacle-recovery/state-fingerprint.d.ts.map +1 -0
- package/dist/src/obstacle-recovery/state-fingerprint.js +85 -0
- package/dist/src/obstacle-recovery/state-fingerprint.js.map +1 -0
- package/dist/src/obstacle-recovery/types.d.ts +44 -0
- package/dist/src/obstacle-recovery/types.d.ts.map +1 -0
- package/dist/src/obstacle-recovery/types.js +16 -0
- package/dist/src/obstacle-recovery/types.js.map +1 -0
- package/dist/src/output/formatter.d.ts +55 -0
- package/dist/src/output/formatter.d.ts.map +1 -0
- package/dist/src/output/formatter.js +55 -0
- package/dist/src/output/formatter.js.map +1 -0
- package/dist/src/output/mode.d.ts +11 -0
- package/dist/src/output/mode.d.ts.map +1 -0
- package/dist/src/output/mode.js +16 -0
- package/dist/src/output/mode.js.map +1 -0
- package/dist/src/protected-flow/detector.d.ts +26 -0
- package/dist/src/protected-flow/detector.d.ts.map +1 -0
- package/dist/src/protected-flow/detector.js +75 -0
- package/dist/src/protected-flow/detector.js.map +1 -0
- package/dist/src/protected-flow/types.d.ts +24 -0
- package/dist/src/protected-flow/types.d.ts.map +1 -0
- package/dist/src/protected-flow/types.js +28 -0
- package/dist/src/protected-flow/types.js.map +1 -0
- package/dist/src/session/agent-identity.d.ts +65 -0
- package/dist/src/session/agent-identity.d.ts.map +1 -0
- package/dist/src/session/agent-identity.js +133 -0
- package/dist/src/session/agent-identity.js.map +1 -0
- package/dist/src/session/cli-session-sync.d.ts +72 -0
- package/dist/src/session/cli-session-sync.d.ts.map +1 -0
- package/dist/src/session/cli-session-sync.js +244 -0
- package/dist/src/session/cli-session-sync.js.map +1 -0
- package/dist/src/session/context.d.ts +24 -0
- package/dist/src/session/context.d.ts.map +1 -0
- package/dist/src/session/context.js +165 -0
- package/dist/src/session/context.js.map +1 -0
- package/dist/src/session/continuity.d.ts +33 -0
- package/dist/src/session/continuity.d.ts.map +1 -0
- package/dist/src/session/continuity.js +179 -0
- package/dist/src/session/continuity.js.map +1 -0
- package/dist/src/session/errors.d.ts +9 -0
- package/dist/src/session/errors.d.ts.map +1 -0
- package/dist/src/session/errors.js +31 -0
- package/dist/src/session/errors.js.map +1 -0
- package/dist/src/session/local-continuity.d.ts +16 -0
- package/dist/src/session/local-continuity.d.ts.map +1 -0
- package/dist/src/session/local-continuity.js +146 -0
- package/dist/src/session/local-continuity.js.map +1 -0
- package/dist/src/session/signal-handler.d.ts +24 -0
- package/dist/src/session/signal-handler.d.ts.map +1 -0
- package/dist/src/session/signal-handler.js +35 -0
- package/dist/src/session/signal-handler.js.map +1 -0
- package/dist/src/shared/local-recovery-policy.d.ts +40 -0
- package/dist/src/shared/local-recovery-policy.d.ts.map +1 -0
- package/dist/src/shared/local-recovery-policy.js +59 -0
- package/dist/src/shared/local-recovery-policy.js.map +1 -0
- package/dist/src/shared/recovery-state.d.ts +3 -0
- package/dist/src/shared/recovery-state.d.ts.map +1 -0
- package/dist/src/shared/recovery-state.js +9 -0
- package/dist/src/shared/recovery-state.js.map +1 -0
- package/dist/src/types.d.ts +131 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +5 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils.d.ts +50 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +147 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/src/working-location.d.ts +107 -0
- package/dist/src/working-location.d.ts.map +1 -0
- package/dist/src/working-location.js +651 -0
- package/dist/src/working-location.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// Four hours is conservative enough to survive ordinary CLI pauses while still
|
|
2
|
+
// allowing reclaim of obviously orphaned state within the same work day.
|
|
3
|
+
export const DEFAULT_CONTINUITY_STALE_LEASE_WINDOW_MS = 4 * 60 * 60 * 1000;
|
|
4
|
+
function toMs(value) {
|
|
5
|
+
if (value == null)
|
|
6
|
+
return null;
|
|
7
|
+
if (typeof value === 'number')
|
|
8
|
+
return Number.isFinite(value) ? value : null;
|
|
9
|
+
if (value instanceof Date)
|
|
10
|
+
return Number.isFinite(value.getTime()) ? value.getTime() : null;
|
|
11
|
+
const parsed = Date.parse(value);
|
|
12
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
13
|
+
}
|
|
14
|
+
function normalizeStaleLeaseWindow(staleLeaseWindowMs) {
|
|
15
|
+
return Number.isFinite(staleLeaseWindowMs) && staleLeaseWindowMs != null && staleLeaseWindowMs > 0
|
|
16
|
+
? staleLeaseWindowMs
|
|
17
|
+
: DEFAULT_CONTINUITY_STALE_LEASE_WINDOW_MS;
|
|
18
|
+
}
|
|
19
|
+
export function isContinuityLeaseStale(setAt, now = Date.now(), staleLeaseWindowMs = DEFAULT_CONTINUITY_STALE_LEASE_WINDOW_MS) {
|
|
20
|
+
const leaseMs = toMs(setAt);
|
|
21
|
+
const nowMs = toMs(now);
|
|
22
|
+
if (leaseMs == null || nowMs == null)
|
|
23
|
+
return false;
|
|
24
|
+
return nowMs - leaseMs >= normalizeStaleLeaseWindow(staleLeaseWindowMs);
|
|
25
|
+
}
|
|
26
|
+
function getEffectiveTabId(evidence) {
|
|
27
|
+
// Prefer the freshest local attachment context first, then the tab currently
|
|
28
|
+
// locked on disk, then any older persisted binding. Later guards treat tab
|
|
29
|
+
// identity mismatches as blocking, so this ordering favors live continuity
|
|
30
|
+
// evidence without silently trusting a stale tab reference.
|
|
31
|
+
const workingTabId = evidence.workingLocation?.tabId;
|
|
32
|
+
if (workingTabId != null)
|
|
33
|
+
return String(workingTabId);
|
|
34
|
+
const lockTabId = evidence.lockOwner?.tabId;
|
|
35
|
+
if (lockTabId != null)
|
|
36
|
+
return String(lockTabId);
|
|
37
|
+
const persistedTabId = evidence.persistedBinding?.tabId;
|
|
38
|
+
if (persistedTabId != null && persistedTabId.length > 0)
|
|
39
|
+
return persistedTabId;
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
function hasSameControllerEvidence(evidence) {
|
|
43
|
+
const { currentAgentId, workingLocation, lockOwner } = evidence;
|
|
44
|
+
return workingLocation?.agentId === currentAgentId || lockOwner?.agentId === currentAgentId;
|
|
45
|
+
}
|
|
46
|
+
function hasConflictingControllerEvidence(evidence) {
|
|
47
|
+
const { currentAgentId, workingLocation, lockOwner } = evidence;
|
|
48
|
+
const foreignWorkingAgent = workingLocation?.agentId && workingLocation.agentId !== currentAgentId;
|
|
49
|
+
const foreignLockAgent = lockOwner?.agentId && lockOwner.agentId !== currentAgentId;
|
|
50
|
+
// Any foreign-authority signal is enough to mark the evidence set as conflicting.
|
|
51
|
+
return !!foreignWorkingAgent || !!foreignLockAgent;
|
|
52
|
+
}
|
|
53
|
+
function isStaleReclaimable(evidence) {
|
|
54
|
+
const leaseWindowMs = normalizeStaleLeaseWindow(evidence.staleLeaseWindowMs);
|
|
55
|
+
const leaseSetAt = evidence.lockOwner?.setAt;
|
|
56
|
+
return (
|
|
57
|
+
// Reclaim requires authoritative lock-file evidence; working-location state
|
|
58
|
+
// alone is intentionally insufficient to justify ownership transfer.
|
|
59
|
+
evidence.lockOwner != null
|
|
60
|
+
&& evidence.ownerShellAlive === false
|
|
61
|
+
&& evidence.runtimeSessionState === 'missing'
|
|
62
|
+
&& isContinuityLeaseStale(leaseSetAt, evidence.now, leaseWindowMs));
|
|
63
|
+
}
|
|
64
|
+
export function assessLocalContinuity(evidence) {
|
|
65
|
+
const effectiveTabId = getEffectiveTabId(evidence);
|
|
66
|
+
if (!effectiveTabId) {
|
|
67
|
+
return {
|
|
68
|
+
state: 'unbound',
|
|
69
|
+
effectiveTabId: null,
|
|
70
|
+
sameController: false,
|
|
71
|
+
canRepairRuntime: false,
|
|
72
|
+
canReclaim: false,
|
|
73
|
+
reason: 'no_binding',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (evidence.tabIdentityState === 'mismatch') {
|
|
77
|
+
return {
|
|
78
|
+
state: 'ambiguous_blocked',
|
|
79
|
+
effectiveTabId,
|
|
80
|
+
sameController: false,
|
|
81
|
+
canRepairRuntime: false,
|
|
82
|
+
canReclaim: false,
|
|
83
|
+
reason: 'tab_identity_mismatch',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (evidence.legacyStateStatus === 'legacy_conflict') {
|
|
87
|
+
return {
|
|
88
|
+
state: 'ambiguous_blocked',
|
|
89
|
+
effectiveTabId,
|
|
90
|
+
sameController: false,
|
|
91
|
+
canRepairRuntime: false,
|
|
92
|
+
canReclaim: false,
|
|
93
|
+
reason: 'legacy_state_conflict',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const sameController = hasSameControllerEvidence(evidence);
|
|
97
|
+
const conflictingController = hasConflictingControllerEvidence(evidence);
|
|
98
|
+
if (sameController && conflictingController) {
|
|
99
|
+
return {
|
|
100
|
+
state: 'ambiguous_blocked',
|
|
101
|
+
effectiveTabId,
|
|
102
|
+
sameController: false,
|
|
103
|
+
canRepairRuntime: false,
|
|
104
|
+
canReclaim: false,
|
|
105
|
+
reason: 'conflicting_controller_evidence',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (sameController) {
|
|
109
|
+
if (evidence.runtimeSessionState === 'recognized') {
|
|
110
|
+
return {
|
|
111
|
+
state: 'same_controller_resumable',
|
|
112
|
+
effectiveTabId,
|
|
113
|
+
sameController: true,
|
|
114
|
+
canRepairRuntime: false,
|
|
115
|
+
canReclaim: false,
|
|
116
|
+
reason: 'same_controller_live_runtime',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (evidence.runtimeSessionState === 'unknown') {
|
|
120
|
+
return {
|
|
121
|
+
state: 'ambiguous_blocked',
|
|
122
|
+
effectiveTabId,
|
|
123
|
+
sameController: true,
|
|
124
|
+
canRepairRuntime: false,
|
|
125
|
+
canReclaim: false,
|
|
126
|
+
reason: 'runtime_status_unknown',
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
state: 'same_controller_missing_runtime',
|
|
131
|
+
effectiveTabId,
|
|
132
|
+
sameController: true,
|
|
133
|
+
canRepairRuntime: true,
|
|
134
|
+
canReclaim: false,
|
|
135
|
+
reason: 'same_controller_runtime_missing',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (conflictingController && evidence.ownerShellAlive === true) {
|
|
139
|
+
return {
|
|
140
|
+
state: 'foreign_controller_live',
|
|
141
|
+
effectiveTabId,
|
|
142
|
+
sameController: false,
|
|
143
|
+
canRepairRuntime: false,
|
|
144
|
+
canReclaim: false,
|
|
145
|
+
reason: 'foreign_controller_live',
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if (conflictingController && isStaleReclaimable(evidence)) {
|
|
149
|
+
return {
|
|
150
|
+
state: 'stale_reclaimable',
|
|
151
|
+
effectiveTabId,
|
|
152
|
+
sameController: false,
|
|
153
|
+
canRepairRuntime: false,
|
|
154
|
+
canReclaim: true,
|
|
155
|
+
reason: 'stale_lease_reclaimable',
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (!sameController && evidence.persistedBinding) {
|
|
159
|
+
return {
|
|
160
|
+
state: 'ambiguous_blocked',
|
|
161
|
+
effectiveTabId,
|
|
162
|
+
sameController: false,
|
|
163
|
+
canRepairRuntime: false,
|
|
164
|
+
canReclaim: false,
|
|
165
|
+
reason: conflictingController ? 'insufficient_stale_evidence' : 'missing_continuity_proof',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
// Safety-net fallback for future callers that provide a tab target without any
|
|
169
|
+
// usable continuity proof. Current tests exercise the explicit ambiguous path.
|
|
170
|
+
return {
|
|
171
|
+
state: 'ambiguous_blocked',
|
|
172
|
+
effectiveTabId,
|
|
173
|
+
sameController: false,
|
|
174
|
+
canRepairRuntime: false,
|
|
175
|
+
canReclaim: false,
|
|
176
|
+
reason: 'missing_continuity_proof',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=continuity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuity.js","sourceRoot":"","sources":["../../../src/session/continuity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ApiKeyError, ApiError, SessionError } from '../errors.js';
|
|
2
|
+
export declare function mixedSessionStateError(): ApiError;
|
|
3
|
+
export declare function localSessionStateConflictError(): ApiError;
|
|
4
|
+
export declare function localSessionBridgeUnavailableError(): ApiError;
|
|
5
|
+
export declare function cloudSessionMissingApiKeyError(): ApiKeyError;
|
|
6
|
+
export declare function noConnectionError(): ApiError;
|
|
7
|
+
export declare function localCommandRequiresTabError(): SessionError;
|
|
8
|
+
export declare function cloudCommandRequiresSessionError(): SessionError;
|
|
9
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/session/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGnE,wBAAgB,sBAAsB,IAAI,QAAQ,CAMjD;AAED,wBAAgB,8BAA8B,IAAI,QAAQ,CAMzD;AAED,wBAAgB,kCAAkC,IAAI,QAAQ,CAQ7D;AAED,wBAAgB,8BAA8B,IAAI,WAAW,CAkB5D;AAED,wBAAgB,iBAAiB,IAAI,QAAQ,CAO5C;AAED,wBAAgB,4BAA4B,IAAI,YAAY,CAK3D;AAED,wBAAgB,gCAAgC,IAAI,YAAY,CAK/D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ApiKeyError, ApiError, SessionError } from '../errors.js';
|
|
2
|
+
import { config } from '../config/store.js';
|
|
3
|
+
export function mixedSessionStateError() {
|
|
4
|
+
return new ApiError('Config contains both local and cloud session state', undefined, 'Re-attach to a local tab with: thinkrun attach <tabId>, or reset the active cloud session with: thinkrun cloud start');
|
|
5
|
+
}
|
|
6
|
+
export function localSessionStateConflictError() {
|
|
7
|
+
return new ApiError('Config local tab binding conflicts with private local control state', undefined, 'Run: thinkrun session debug\nThen re-attach to the intended local tab with: thinkrun attach <tabId>');
|
|
8
|
+
}
|
|
9
|
+
export function localSessionBridgeUnavailableError() {
|
|
10
|
+
return new ApiError('Active session is a local tab, but the native host is not reachable', undefined, 'Open a Chromium-based browser (e.g. Chrome or Helium) with the ThinkRun extension active, or switch to cloud mode with: thinkrun cloud start', 'NATIVE_HOST_UNREACHABLE', false);
|
|
11
|
+
}
|
|
12
|
+
export function cloudSessionMissingApiKeyError() {
|
|
13
|
+
// PRD 0086 B2: classify by actual key state so the cloud-session routing
|
|
14
|
+
// path matches the CloudAdapter constructor taxonomy.
|
|
15
|
+
const health = config.getKeyHealth();
|
|
16
|
+
if (health.state === 'malformed') {
|
|
17
|
+
return new ApiKeyError(`Active session is a cloud session, but the stored API key is malformed and was quarantined (${health.quarantinedMasked}).`, 'API_KEY_MALFORMED', 'Set a valid key: thinkrun config set-key <your-api-key>. Diagnose with: thinkrun doctor', 401);
|
|
18
|
+
}
|
|
19
|
+
return new ApiKeyError('Active session is a cloud session, but no API key is configured', 'API_KEY_MISSING', 'Run: thinkrun config set-key <your-api-key>, or attach to a local tab with: thinkrun attach <tabId>', 401);
|
|
20
|
+
}
|
|
21
|
+
export function noConnectionError() {
|
|
22
|
+
return new ApiError('ThinkRun extension not reachable', undefined, 'Start a Chromium-based browser (e.g. Chrome or Helium) with the ThinkRun extension active, then run: thinkrun attach <tabId>\n' +
|
|
23
|
+
'To use a cloud browser instead: thinkrun cloud start (requires an API key)');
|
|
24
|
+
}
|
|
25
|
+
export function localCommandRequiresTabError() {
|
|
26
|
+
return new SessionError('No active local tab', 'List tabs with: thinkrun tabs\nThen attach: thinkrun attach <tabId>');
|
|
27
|
+
}
|
|
28
|
+
export function cloudCommandRequiresSessionError() {
|
|
29
|
+
return new SessionError('No active session', 'Start a session with: thinkrun cloud start');
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/session/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,QAAQ,CACjB,oDAAoD,EACpD,SAAS,EACT,sHAAsH,CACvH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,8BAA8B;IAC5C,OAAO,IAAI,QAAQ,CACjB,qEAAqE,EACrE,SAAS,EACT,qGAAqG,CACtG,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kCAAkC;IAChD,OAAO,IAAI,QAAQ,CACjB,qEAAqE,EACrE,SAAS,EACT,8IAA8I,EAC9I,yBAAyB,EACzB,KAAK,CACN,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,8BAA8B;IAC5C,yEAAyE;IACzE,sDAAsD;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IACrC,IAAI,MAAM,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;QACjC,OAAO,IAAI,WAAW,CACpB,+FAA+F,MAAM,CAAC,iBAAiB,IAAI,EAC3H,mBAAmB,EACnB,yFAAyF,EACzF,GAAG,CACJ,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,WAAW,CACpB,iEAAiE,EACjE,iBAAiB,EACjB,qGAAqG,EACrG,GAAG,CACJ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,QAAQ,CACjB,kCAAkC,EAClC,SAAS,EACT,gIAAgI;QAChI,6EAA6E,CAC9E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,OAAO,IAAI,YAAY,CACrB,qBAAqB,EACrB,qEAAqE,CACtE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gCAAgC;IAC9C,OAAO,IAAI,YAAY,CACrB,mBAAmB,EACnB,4CAA4C,CAC7C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type WorkingLocation } from '../working-location.js';
|
|
2
|
+
import type { LocalSessionContext } from './context.js';
|
|
3
|
+
export type LocalContinuityState = 'unbound' | 'same_controller_read_resumable' | 'same_controller_read_write_resumable' | 'same_controller_missing_runtime_registration' | 'same_controller_missing_mutating_authority_state' | 'foreign_controller_live' | 'stale_reclaimable' | 'ambiguous_blocked';
|
|
4
|
+
export type LocalContinuityLockOwner = Pick<WorkingLocation, 'tabId' | 'agentId' | 'pid' | 'ownerShellPid' | 'controlSessionId' | 'setAt'>;
|
|
5
|
+
export type LocalContinuityAssessment = {
|
|
6
|
+
state: LocalContinuityState;
|
|
7
|
+
effectiveTabId: string | null;
|
|
8
|
+
hint: string | null;
|
|
9
|
+
runtimeSessionPresent: boolean;
|
|
10
|
+
controlSessionPresent: boolean;
|
|
11
|
+
controlLeaseHeld: boolean;
|
|
12
|
+
staleLock: boolean;
|
|
13
|
+
lockOwner: LocalContinuityLockOwner | null;
|
|
14
|
+
};
|
|
15
|
+
export declare function assessLocalContinuity(localContext?: LocalSessionContext, workingLocation?: WorkingLocation | null): LocalContinuityAssessment;
|
|
16
|
+
//# sourceMappingURL=local-continuity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-continuity.d.ts","sourceRoot":"","sources":["../../../src/session/local-continuity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC5G,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAGxD,MAAM,MAAM,oBAAoB,GAC5B,SAAS,GACT,gCAAgC,GAChC,sCAAsC,GACtC,8CAA8C,GAC9C,kDAAkD,GAClD,yBAAyB,GACzB,mBAAmB,GACnB,mBAAmB,CAAC;AAExB,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,eAAe,EACf,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,eAAe,GAAG,kBAAkB,GAAG,OAAO,CAC7E,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAC5C,CAAC;AAcF,wBAAgB,qBAAqB,CACnC,YAAY,CAAC,EAAE,mBAAmB,EAClC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,GACvC,yBAAyB,CA2I3B"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { getLockedBy, getWorkingLocation, isLockStale } from '../working-location.js';
|
|
2
|
+
import { resolveAgentId } from './agent-identity.js';
|
|
3
|
+
function toLockOwner(lock) {
|
|
4
|
+
if (!lock)
|
|
5
|
+
return null;
|
|
6
|
+
return {
|
|
7
|
+
tabId: lock.tabId,
|
|
8
|
+
...(lock.agentId ? { agentId: lock.agentId } : {}),
|
|
9
|
+
pid: lock.pid,
|
|
10
|
+
...(lock.ownerShellPid !== undefined ? { ownerShellPid: lock.ownerShellPid } : {}),
|
|
11
|
+
...(lock.controlSessionId ? { controlSessionId: lock.controlSessionId } : {}),
|
|
12
|
+
setAt: lock.setAt,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function assessLocalContinuity(localContext, workingLocation) {
|
|
16
|
+
const currentAgentId = resolveAgentId();
|
|
17
|
+
const context = localContext;
|
|
18
|
+
const working = workingLocation ?? getWorkingLocation();
|
|
19
|
+
const effectiveTabId = working ? String(working.tabId) : context?.tabId ?? null;
|
|
20
|
+
const lock = effectiveTabId ? getLockedBy(Number(effectiveTabId)) : null;
|
|
21
|
+
const staleLock = effectiveTabId ? isLockStale(Number(effectiveTabId)) : false;
|
|
22
|
+
const lockOwner = toLockOwner(lock);
|
|
23
|
+
const runtimeSessionPresent = typeof context?.agentSessionId === 'string' && context.agentSessionId.length > 0;
|
|
24
|
+
const controlSessionPresent = typeof context?.controlSessionId === 'string' && context.controlSessionId.length > 0;
|
|
25
|
+
const sameTab = !!context?.tabId && !!working && context.tabId === String(working.tabId);
|
|
26
|
+
const sameControllerWorking = !!working?.agentId && working.agentId === currentAgentId;
|
|
27
|
+
const sameControllerLock = !!lock?.agentId && lock.agentId === currentAgentId;
|
|
28
|
+
const workingControlMismatch = !!context?.controlSessionId
|
|
29
|
+
&& !!working?.controlSessionId
|
|
30
|
+
&& working.controlSessionId !== context.controlSessionId;
|
|
31
|
+
const lockControlMismatch = !!context?.controlSessionId
|
|
32
|
+
&& !!lock?.controlSessionId
|
|
33
|
+
&& lock.controlSessionId !== context.controlSessionId;
|
|
34
|
+
const controlLeaseHeld = controlSessionPresent
|
|
35
|
+
&& !workingControlMismatch
|
|
36
|
+
&& !lockControlMismatch;
|
|
37
|
+
if (!context?.tabId && !working && !lock) {
|
|
38
|
+
return {
|
|
39
|
+
state: 'unbound',
|
|
40
|
+
effectiveTabId: null,
|
|
41
|
+
hint: 'No persisted local binding or working location exists yet. Attach or open a new local tab first.',
|
|
42
|
+
runtimeSessionPresent: false,
|
|
43
|
+
controlSessionPresent: false,
|
|
44
|
+
controlLeaseHeld: false,
|
|
45
|
+
staleLock: false,
|
|
46
|
+
lockOwner: null,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (lock?.agentId && lock.agentId !== currentAgentId) {
|
|
50
|
+
if (staleLock) {
|
|
51
|
+
return {
|
|
52
|
+
state: 'stale_reclaimable',
|
|
53
|
+
effectiveTabId,
|
|
54
|
+
hint: `Tab ${effectiveTabId} still has a stale foreign lock. Inspect session debug, then re-attach to reclaim it safely if the other controller is really gone.`,
|
|
55
|
+
runtimeSessionPresent,
|
|
56
|
+
controlSessionPresent,
|
|
57
|
+
controlLeaseHeld: false,
|
|
58
|
+
staleLock: true,
|
|
59
|
+
lockOwner,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
state: 'foreign_controller_live',
|
|
64
|
+
effectiveTabId,
|
|
65
|
+
hint: `Tab ${effectiveTabId} is actively controlled by another local agent. Use a new tab/window or wait for that controller to release it.`,
|
|
66
|
+
runtimeSessionPresent,
|
|
67
|
+
controlSessionPresent,
|
|
68
|
+
controlLeaseHeld: false,
|
|
69
|
+
staleLock: false,
|
|
70
|
+
lockOwner,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (context?.tabId && working && !sameTab) {
|
|
74
|
+
return {
|
|
75
|
+
state: 'ambiguous_blocked',
|
|
76
|
+
effectiveTabId,
|
|
77
|
+
hint: `Persisted local binding points to tab ${context.tabId}, but working location points to tab ${working.tabId}. Resolve the drift before trusting mutating continuity.`,
|
|
78
|
+
runtimeSessionPresent,
|
|
79
|
+
controlSessionPresent,
|
|
80
|
+
controlLeaseHeld: false,
|
|
81
|
+
staleLock,
|
|
82
|
+
lockOwner,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (sameControllerWorking || sameControllerLock || controlSessionPresent) {
|
|
86
|
+
if (runtimeSessionPresent && controlLeaseHeld) {
|
|
87
|
+
return {
|
|
88
|
+
state: 'same_controller_read_write_resumable',
|
|
89
|
+
effectiveTabId,
|
|
90
|
+
hint: `Same-controller continuity is intact for tab ${effectiveTabId}. Read and mutating commands should resume cleanly.`,
|
|
91
|
+
runtimeSessionPresent,
|
|
92
|
+
controlSessionPresent,
|
|
93
|
+
controlLeaseHeld: true,
|
|
94
|
+
staleLock,
|
|
95
|
+
lockOwner,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (!runtimeSessionPresent && controlLeaseHeld) {
|
|
99
|
+
return {
|
|
100
|
+
state: 'same_controller_missing_runtime_registration',
|
|
101
|
+
effectiveTabId,
|
|
102
|
+
hint: `Same-controller continuity is proven for tab ${effectiveTabId}, but the runtime session registration is missing. A narrow re-register path is expected to repair mutating commands.`,
|
|
103
|
+
runtimeSessionPresent,
|
|
104
|
+
controlSessionPresent,
|
|
105
|
+
controlLeaseHeld: true,
|
|
106
|
+
staleLock,
|
|
107
|
+
lockOwner,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (runtimeSessionPresent && !controlLeaseHeld) {
|
|
111
|
+
return {
|
|
112
|
+
state: 'same_controller_missing_mutating_authority_state',
|
|
113
|
+
effectiveTabId,
|
|
114
|
+
hint: `Targeting continuity still exists for tab ${effectiveTabId}, but the active mutating-authority lease is missing or inconsistent. Read-only commands may still work while mutations fail.`,
|
|
115
|
+
runtimeSessionPresent,
|
|
116
|
+
controlSessionPresent,
|
|
117
|
+
controlLeaseHeld: false,
|
|
118
|
+
staleLock,
|
|
119
|
+
lockOwner,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
state: 'same_controller_read_resumable',
|
|
124
|
+
effectiveTabId,
|
|
125
|
+
hint: `Some same-controller continuity evidence exists for tab ${effectiveTabId}, but not enough to trust mutating authority yet.`,
|
|
126
|
+
runtimeSessionPresent,
|
|
127
|
+
controlSessionPresent,
|
|
128
|
+
controlLeaseHeld: false,
|
|
129
|
+
staleLock,
|
|
130
|
+
lockOwner,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
state: 'ambiguous_blocked',
|
|
135
|
+
effectiveTabId,
|
|
136
|
+
hint: effectiveTabId
|
|
137
|
+
? `Local context still points at tab ${effectiveTabId}, but same-controller authority could not be proven from the current working-location and lock state.`
|
|
138
|
+
: 'Local continuity could not be proven from the current persisted state.',
|
|
139
|
+
runtimeSessionPresent,
|
|
140
|
+
controlSessionPresent,
|
|
141
|
+
controlLeaseHeld: false,
|
|
142
|
+
staleLock,
|
|
143
|
+
lockOwner,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=local-continuity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-continuity.js","sourceRoot":"","sources":["../../../src/session/local-continuity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIGINT / SIGTERM handler factory for the CLI entry point.
|
|
3
|
+
*
|
|
4
|
+
* Extracted into a separate module so that unit tests can import and call
|
|
5
|
+
* `handleTermSignal` directly, instead of simulating the handler logic
|
|
6
|
+
* inline and risking test/handler drift.
|
|
7
|
+
*/
|
|
8
|
+
import { closeCliSessionSync } from './cli-session-sync.js';
|
|
9
|
+
import { getWorkingLocation } from '../working-location.js';
|
|
10
|
+
/**
|
|
11
|
+
* Returns a function that, when called, performs a best-effort synchronous
|
|
12
|
+
* close of the current CLI session and then exits the process with `exitCode`.
|
|
13
|
+
*
|
|
14
|
+
* Uses `getWorkingLocation()` as the authoritative source of the active tabId
|
|
15
|
+
* so the correct session is closed even when the handler fires mid-command.
|
|
16
|
+
*
|
|
17
|
+
* @param exitCode - Process exit code (130 for SIGINT, 143 for SIGTERM).
|
|
18
|
+
* @param status - Session close status: 'failed' for SIGINT (user interrupt),
|
|
19
|
+
* 'completed' for SIGTERM (graceful shutdown by process manager).
|
|
20
|
+
* @param getLocFn - Injectable for testing; defaults to `getWorkingLocation`.
|
|
21
|
+
* @param closeFn - Injectable for testing; defaults to `closeCliSessionSync`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function handleTermSignal(exitCode: number, status?: 'completed' | 'failed', getLocFn?: () => ReturnType<typeof getWorkingLocation>, closeFn?: typeof closeCliSessionSync): () => void;
|
|
24
|
+
//# sourceMappingURL=signal-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal-handler.d.ts","sourceRoot":"","sources":["../../../src/session/signal-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,WAAW,GAAG,QAAmB,EACzC,QAAQ,GAAE,MAAM,UAAU,CAAC,OAAO,kBAAkB,CAAsB,EAC1E,OAAO,GAAE,OAAO,mBAAyC,GACxD,MAAM,IAAI,CAUZ"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SIGINT / SIGTERM handler factory for the CLI entry point.
|
|
3
|
+
*
|
|
4
|
+
* Extracted into a separate module so that unit tests can import and call
|
|
5
|
+
* `handleTermSignal` directly, instead of simulating the handler logic
|
|
6
|
+
* inline and risking test/handler drift.
|
|
7
|
+
*/
|
|
8
|
+
import { closeCliSessionSync } from './cli-session-sync.js';
|
|
9
|
+
import { getWorkingLocation } from '../working-location.js';
|
|
10
|
+
/**
|
|
11
|
+
* Returns a function that, when called, performs a best-effort synchronous
|
|
12
|
+
* close of the current CLI session and then exits the process with `exitCode`.
|
|
13
|
+
*
|
|
14
|
+
* Uses `getWorkingLocation()` as the authoritative source of the active tabId
|
|
15
|
+
* so the correct session is closed even when the handler fires mid-command.
|
|
16
|
+
*
|
|
17
|
+
* @param exitCode - Process exit code (130 for SIGINT, 143 for SIGTERM).
|
|
18
|
+
* @param status - Session close status: 'failed' for SIGINT (user interrupt),
|
|
19
|
+
* 'completed' for SIGTERM (graceful shutdown by process manager).
|
|
20
|
+
* @param getLocFn - Injectable for testing; defaults to `getWorkingLocation`.
|
|
21
|
+
* @param closeFn - Injectable for testing; defaults to `closeCliSessionSync`.
|
|
22
|
+
*/
|
|
23
|
+
export function handleTermSignal(exitCode, status = 'failed', getLocFn = getWorkingLocation, closeFn = closeCliSessionSync) {
|
|
24
|
+
return () => {
|
|
25
|
+
try {
|
|
26
|
+
const loc = getLocFn();
|
|
27
|
+
if (loc?.tabId) {
|
|
28
|
+
closeFn(String(loc.tabId), status);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch { /* best-effort — never block clean exit */ }
|
|
32
|
+
process.exit(exitCode);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=signal-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal-handler.js","sourceRoot":"","sources":["../../../src/session/signal-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,SAAiC,QAAQ,EACzC,WAAwD,kBAAkB,EAC1E,UAAsC,mBAAmB;IAEzD,OAAO,GAAG,EAAE;QACV,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC;YACvB,IAAI,GAAG,EAAE,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,0CAA0C,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const LOCAL_BRIDGE_RECOVERY_RETRY_DELAYS_MS: readonly [250, 500, 1000, 2000, 4000];
|
|
2
|
+
export declare const LOCAL_SAFE_MAX_ATTEMPTS: number;
|
|
3
|
+
export declare const LOCAL_MUTATION_MAX_ATTEMPTS = 1;
|
|
4
|
+
export declare const LOCAL_SAFE_NO_RETRY_MAX_ATTEMPTS = 1;
|
|
5
|
+
export type LocalReplayPolicy = 'safe' | 'safe-no-retry' | 'mutation';
|
|
6
|
+
/**
|
|
7
|
+
* Canonical replay policy for local CLI commands while the extension/native host
|
|
8
|
+
* transport is reconnecting.
|
|
9
|
+
*/
|
|
10
|
+
export declare const LOCAL_COMMAND_REPLAY_POLICY: {
|
|
11
|
+
getSession: "safe";
|
|
12
|
+
listSessions: "safe";
|
|
13
|
+
wait: "safe-no-retry";
|
|
14
|
+
waitForText: "safe-no-retry";
|
|
15
|
+
snapshot: "safe";
|
|
16
|
+
screenshot: "safe";
|
|
17
|
+
extract: "safe";
|
|
18
|
+
getUrl: "safe";
|
|
19
|
+
getTitle: "safe";
|
|
20
|
+
getHtml: "safe";
|
|
21
|
+
getDialog: "safe-no-retry";
|
|
22
|
+
getConsoleMessages: "safe";
|
|
23
|
+
getNetworkRequests: "safe";
|
|
24
|
+
navigate: "mutation";
|
|
25
|
+
goBack: "mutation";
|
|
26
|
+
goForward: "mutation";
|
|
27
|
+
click: "mutation";
|
|
28
|
+
type: "mutation";
|
|
29
|
+
fill: "mutation";
|
|
30
|
+
press: "mutation";
|
|
31
|
+
scroll: "mutation";
|
|
32
|
+
hover: "mutation";
|
|
33
|
+
select: "mutation";
|
|
34
|
+
evaluate: "mutation";
|
|
35
|
+
handleDialog: "mutation";
|
|
36
|
+
clearLogs: "mutation";
|
|
37
|
+
};
|
|
38
|
+
export declare const LOCAL_RECONNECTABLE_BRIDGE_CODES: Set<string>;
|
|
39
|
+
export declare const LOCAL_RECONNECTABLE_TIMEOUT_CODES: Set<string>;
|
|
40
|
+
//# sourceMappingURL=local-recovery-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-recovery-policy.d.ts","sourceRoot":"","sources":["../../../src/shared/local-recovery-policy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qCAAqC,uCAMxC,CAAC;AAEX,eAAO,MAAM,uBAAuB,QAAmD,CAAC;AACxF,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAG7C,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,eAAe,GAAG,UAAU,CAAC;AAEtE;;;GAGG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BK,CAAC;AAE9C,eAAO,MAAM,gCAAgC,aAI3C,CAAC;AAEH,eAAO,MAAM,iCAAiC,aAK5C,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export const LOCAL_BRIDGE_RECOVERY_RETRY_DELAYS_MS = [
|
|
2
|
+
250,
|
|
3
|
+
500,
|
|
4
|
+
1_000,
|
|
5
|
+
2_000,
|
|
6
|
+
4_000,
|
|
7
|
+
];
|
|
8
|
+
export const LOCAL_SAFE_MAX_ATTEMPTS = LOCAL_BRIDGE_RECOVERY_RETRY_DELAYS_MS.length + 1;
|
|
9
|
+
export const LOCAL_MUTATION_MAX_ATTEMPTS = 1;
|
|
10
|
+
// Keep a distinct constant for explicit mutation semantics even though it currently
|
|
11
|
+
// matches the observation no-retry budget.
|
|
12
|
+
export const LOCAL_SAFE_NO_RETRY_MAX_ATTEMPTS = 1;
|
|
13
|
+
/**
|
|
14
|
+
* Canonical replay policy for local CLI commands while the extension/native host
|
|
15
|
+
* transport is reconnecting.
|
|
16
|
+
*/
|
|
17
|
+
export const LOCAL_COMMAND_REPLAY_POLICY = {
|
|
18
|
+
getSession: 'safe',
|
|
19
|
+
listSessions: 'safe',
|
|
20
|
+
wait: 'safe-no-retry',
|
|
21
|
+
waitForText: 'safe-no-retry',
|
|
22
|
+
snapshot: 'safe',
|
|
23
|
+
screenshot: 'safe',
|
|
24
|
+
extract: 'safe',
|
|
25
|
+
getUrl: 'safe',
|
|
26
|
+
getTitle: 'safe',
|
|
27
|
+
getHtml: 'safe',
|
|
28
|
+
// Keep a single attempt for dialog inspection, but use observation wording until
|
|
29
|
+
// the bridge exposes a distinct read-only command path for dialog state.
|
|
30
|
+
getDialog: 'safe-no-retry',
|
|
31
|
+
getConsoleMessages: 'safe',
|
|
32
|
+
getNetworkRequests: 'safe',
|
|
33
|
+
navigate: 'mutation',
|
|
34
|
+
goBack: 'mutation',
|
|
35
|
+
goForward: 'mutation',
|
|
36
|
+
click: 'mutation',
|
|
37
|
+
type: 'mutation',
|
|
38
|
+
fill: 'mutation',
|
|
39
|
+
press: 'mutation',
|
|
40
|
+
scroll: 'mutation',
|
|
41
|
+
hover: 'mutation',
|
|
42
|
+
select: 'mutation',
|
|
43
|
+
// Scripts are opaque here; we cannot distinguish read-only evaluation from mutation safely.
|
|
44
|
+
evaluate: 'mutation',
|
|
45
|
+
handleDialog: 'mutation',
|
|
46
|
+
clearLogs: 'mutation',
|
|
47
|
+
};
|
|
48
|
+
export const LOCAL_RECONNECTABLE_BRIDGE_CODES = new Set([
|
|
49
|
+
'EXTENSION_NOT_CONNECTED',
|
|
50
|
+
'EXTENSION_DISCONNECTED',
|
|
51
|
+
'NATIVE_HOST_UNREACHABLE',
|
|
52
|
+
]);
|
|
53
|
+
export const LOCAL_RECONNECTABLE_TIMEOUT_CODES = new Set([
|
|
54
|
+
// These are only replayed when the native host marks them retryable, which
|
|
55
|
+
// signals bridge-state churn rather than a definitive command timeout.
|
|
56
|
+
'REQUEST_TIMEOUT',
|
|
57
|
+
'COMMAND_TIMEOUT',
|
|
58
|
+
]);
|
|
59
|
+
//# sourceMappingURL=local-recovery-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-recovery-policy.js","sourceRoot":"","sources":["../../../src/shared/local-recovery-policy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qCAAqC,GAAG;IACnD,GAAG;IACH,GAAG;IACH,KAAK;IACL,KAAK;IACL,KAAK;CACG,CAAC;AAEX,MAAM,CAAC,MAAM,uBAAuB,GAAG,qCAAqC,CAAC,MAAM,GAAG,CAAC,CAAC;AACxF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAC7C,oFAAoF;AACpF,2CAA2C;AAC3C,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAC,CAAC;AAIlD;;;GAGG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,UAAU,EAAE,MAAM;IAClB,YAAY,EAAE,MAAM;IACpB,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,eAAe;IAC5B,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,MAAM;IAClB,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,MAAM;IAChB,OAAO,EAAE,MAAM;IACf,iFAAiF;IACjF,yEAAyE;IACzE,SAAS,EAAE,eAAe;IAC1B,kBAAkB,EAAE,MAAM;IAC1B,kBAAkB,EAAE,MAAM;IAC1B,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,UAAU;IAClB,SAAS,EAAE,UAAU;IACrB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,4FAA4F;IAC5F,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,UAAU;IACxB,SAAS,EAAE,UAAU;CACsB,CAAC;AAE9C,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,GAAG,CAAC;IACtD,yBAAyB;IACzB,wBAAwB;IACxB,yBAAyB;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iCAAiC,GAAG,IAAI,GAAG,CAAC;IACvD,2EAA2E;IAC3E,uEAAuE;IACvE,iBAAiB;IACjB,iBAAiB;CAClB,CAAC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const RECOVERY_STATE_VALUES: readonly ["healthy", "recovering", "recently_recovered", "circuit_breaker_tripped", "service_worker_flapping", "hard_disconnected"];
|
|
2
|
+
export type RecoveryState = (typeof RECOVERY_STATE_VALUES)[number];
|
|
3
|
+
//# sourceMappingURL=recovery-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-state.d.ts","sourceRoot":"","sources":["../../../src/shared/recovery-state.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,qIAOxB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-state.js","sourceRoot":"","sources":["../../../src/shared/recovery-state.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,SAAS;IACT,YAAY;IACZ,oBAAoB;IACpB,yBAAyB;IACzB,yBAAyB;IACzB,mBAAmB;CACX,CAAC"}
|