harnery 0.45.0 → 0.45.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/dist/commander.js +0 -1
  2. package/dist/commands/files.d.ts +2 -2
  3. package/dist/commands/files.d.ts.map +1 -1
  4. package/dist/commands/files.js +4 -7
  5. package/dist/commands/servers.d.ts.map +1 -1
  6. package/dist/commands/servers.js +17 -11
  7. package/dist/commands/tunnel.d.ts +0 -15
  8. package/dist/commands/tunnel.d.ts.map +1 -1
  9. package/dist/commands/tunnel.js +153 -453
  10. package/dist/commands/workflow.d.ts.map +1 -1
  11. package/dist/commands/workflow.js +6 -45
  12. package/dist/core/agents/coord-client.d.ts.map +1 -1
  13. package/dist/core/agents/coord-client.js +0 -18
  14. package/dist/core/agents/live-authority-v3.d.ts +0 -1
  15. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  16. package/dist/core/agents/live-authority-v3.js +0 -11
  17. package/dist/core/agents/live-lifecycle-v3.d.ts +2 -4
  18. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
  19. package/dist/core/agents/live-lifecycle-v3.js +7 -28
  20. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  21. package/dist/core/agents/state/heartbeat-writer.js +14 -25
  22. package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -1
  23. package/dist/core/agents/state/live-coordination-writer.js +0 -5
  24. package/dist/core/agents/state/pidmap.d.ts.map +1 -1
  25. package/dist/core/agents/state/pidmap.js +2 -7
  26. package/dist/core/agents/state/proc-start.d.ts +20 -31
  27. package/dist/core/agents/state/proc-start.d.ts.map +1 -1
  28. package/dist/core/agents/state/proc-start.js +37 -70
  29. package/dist/core/agents/state/service-process.d.ts +61 -0
  30. package/dist/core/agents/state/service-process.d.ts.map +1 -0
  31. package/dist/core/agents/state/service-process.js +143 -0
  32. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  33. package/dist/core/agents/state/stale-sweep.js +70 -180
  34. package/dist/core/artifacts/activity.d.ts +4 -1
  35. package/dist/core/artifacts/activity.d.ts.map +1 -1
  36. package/dist/core/artifacts/activity.js +8 -2
  37. package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
  38. package/dist/core/artifacts/delivery-card.js +1 -2
  39. package/dist/core/artifacts/index.d.ts.map +1 -1
  40. package/dist/core/artifacts/index.js +38 -12
  41. package/dist/core/context/index.d.ts +6 -4
  42. package/dist/core/context/index.d.ts.map +1 -1
  43. package/dist/core/context/index.js +194 -256
  44. package/dist/core/context/observation.d.ts +9 -9
  45. package/dist/core/context/observation.d.ts.map +1 -1
  46. package/dist/core/context/observation.js +37 -6
  47. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  48. package/dist/core/events/v3/authority-outbox.js +0 -29
  49. package/dist/core/events/v3/producers/coordination-recorder.d.ts +0 -1
  50. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  51. package/dist/core/events/v3/producers/coordination-recorder.js +0 -7
  52. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  53. package/dist/core/events/v3/producers/recorder.js +64 -77
  54. package/dist/core/events/v3/runtime-build.d.ts +14 -0
  55. package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
  56. package/dist/core/events/v3/runtime-build.js +44 -0
  57. package/dist/core/governor/index.d.ts +2 -1
  58. package/dist/core/governor/index.d.ts.map +1 -1
  59. package/dist/core/governor/index.js +2 -1
  60. package/dist/core/governor/service-read.d.ts +3 -10
  61. package/dist/core/governor/service-read.d.ts.map +1 -1
  62. package/dist/core/governor/service-read.js +10 -94
  63. package/dist/core/governor/service.d.ts +3 -7
  64. package/dist/core/governor/service.d.ts.map +1 -1
  65. package/dist/core/governor/service.js +17 -182
  66. package/dist/core/hooks/cli.js +78 -48
  67. package/dist/core/hooks/resolve/owner.js +2 -2
  68. package/dist/core/resources/sampler.js +2 -2
  69. package/dist/core/resources/service-status.d.ts +2 -14
  70. package/dist/core/resources/service-status.d.ts.map +1 -1
  71. package/dist/core/resources/service-status.js +3 -23
  72. package/dist/core/resources/service.d.ts +3 -7
  73. package/dist/core/resources/service.d.ts.map +1 -1
  74. package/dist/core/resources/service.js +12 -101
  75. package/dist/core/resources/status.d.ts.map +1 -1
  76. package/dist/core/resources/status.js +3 -2
  77. package/dist/core/semantic/service.d.ts.map +1 -1
  78. package/dist/core/semantic/service.js +9 -2
  79. package/dist/core/servers/index.d.ts +11 -10
  80. package/dist/core/servers/index.d.ts.map +1 -1
  81. package/dist/core/servers/index.js +82 -192
  82. package/dist/core/servers/tunnels.d.ts +3 -5
  83. package/dist/core/servers/tunnels.d.ts.map +1 -1
  84. package/dist/core/servers/tunnels.js +2 -45
  85. package/dist/core/storage/durable-history.js +56 -22
  86. package/dist/core/storage/segments.d.ts.map +1 -1
  87. package/dist/core/storage/segments.js +73 -17
  88. package/dist/core/supervisor/service.d.ts +4 -7
  89. package/dist/core/supervisor/service.d.ts.map +1 -1
  90. package/dist/core/supervisor/service.js +23 -122
  91. package/dist/core/supervisor/services.js +2 -2
  92. package/dist/core/supervisor/status.d.ts +3 -17
  93. package/dist/core/supervisor/status.d.ts.map +1 -1
  94. package/dist/core/supervisor/status.js +7 -70
  95. package/dist/core/work/state.js +7 -7
  96. package/dist/core/workflow/engine.d.ts.map +1 -1
  97. package/dist/core/workflow/engine.js +23 -66
  98. package/dist/core/workflow/index.d.ts +3 -4
  99. package/dist/core/workflow/index.d.ts.map +1 -1
  100. package/dist/core/workflow/index.js +2 -2
  101. package/dist/core/workflow/live-session-v3.d.ts +0 -6
  102. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  103. package/dist/core/workflow/live-session-v3.js +5 -126
  104. package/dist/core/workflow/proof.d.ts +4 -4
  105. package/dist/core/workflow/proof.d.ts.map +1 -1
  106. package/dist/core/workflow/proof.js +34 -86
  107. package/dist/core/workflow/resume-lock.d.ts +17 -0
  108. package/dist/core/workflow/resume-lock.d.ts.map +1 -0
  109. package/dist/core/workflow/resume-lock.js +158 -0
  110. package/dist/core/workflow/run-state.d.ts +0 -21
  111. package/dist/core/workflow/run-state.d.ts.map +1 -1
  112. package/dist/core/workflow/run-state.js +3 -174
  113. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  114. package/dist/core/workflow/spawn-claude.js +0 -19
  115. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  116. package/dist/core/workflow/spawn-codex.js +0 -13
  117. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  118. package/dist/core/workflow/spawn-cursor.js +0 -19
  119. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
  120. package/dist/core/workflow/spawn-opencode.js +0 -14
  121. package/dist/core/workflow/types.d.ts +11 -54
  122. package/dist/core/workflow/types.d.ts.map +1 -1
  123. package/dist/core/workflow/workspaces/leases.d.ts +4 -0
  124. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  125. package/dist/core/workflow/workspaces/leases.js +1 -1
  126. package/dist/core/workflow/workspaces/local-git.js +91 -210
  127. package/dist/core/workflow/workspaces/ownership.d.ts +0 -7
  128. package/dist/core/workflow/workspaces/ownership.d.ts.map +1 -1
  129. package/dist/core/workflow/workspaces/ownership.js +3 -130
  130. package/dist/core/workflow/workspaces/reclaim.d.ts +4 -7
  131. package/dist/core/workflow/workspaces/reclaim.d.ts.map +1 -1
  132. package/dist/core/workflow/workspaces/reclaim.js +0 -4
  133. package/dist/core/workflow/workspaces/recovery.d.ts +1 -1
  134. package/dist/core/workflow/workspaces/recovery.d.ts.map +1 -1
  135. package/dist/core/workflow/workspaces/recovery.js +1 -1
  136. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  137. package/dist/core/workflow/workspaces/state.js +1 -4
  138. package/dist/lib/identities/assume.d.ts.map +1 -1
  139. package/dist/lib/identities/assume.js +0 -4
  140. package/dist/lib/tunnel/state.d.ts +6 -13
  141. package/dist/lib/tunnel/state.d.ts.map +1 -1
  142. package/dist/lib/tunnel/state.js +12 -58
  143. package/package.json +1 -6
  144. package/src/commander.ts +0 -10
  145. package/src/commands/files.ts +5 -13
  146. package/src/commands/servers.ts +23 -12
  147. package/src/commands/tunnel.ts +166 -533
  148. package/src/commands/workflow.ts +8 -58
  149. package/src/core/agents/coord-client.ts +0 -20
  150. package/src/core/agents/live-authority-v3.ts +0 -17
  151. package/src/core/agents/live-lifecycle-v3.ts +14 -52
  152. package/src/core/agents/state/heartbeat-writer.ts +12 -29
  153. package/src/core/agents/state/live-coordination-writer.ts +0 -29
  154. package/src/core/agents/state/pidmap.ts +2 -15
  155. package/src/core/agents/state/proc-start.ts +41 -69
  156. package/src/core/agents/state/service-process.ts +217 -0
  157. package/src/core/agents/state/stale-sweep.ts +82 -247
  158. package/src/core/artifacts/activity.ts +9 -2
  159. package/src/core/artifacts/delivery-card.ts +1 -7
  160. package/src/core/artifacts/index.ts +45 -12
  161. package/src/core/context/index.ts +207 -272
  162. package/src/core/context/observation.ts +40 -9
  163. package/src/core/events/v3/authority-outbox.ts +0 -56
  164. package/src/core/events/v3/producers/coordination-recorder.ts +0 -15
  165. package/src/core/events/v3/producers/recorder.ts +68 -94
  166. package/src/core/events/v3/runtime-build.ts +62 -0
  167. package/src/core/governor/index.ts +1 -2
  168. package/src/core/governor/service-read.ts +15 -114
  169. package/src/core/governor/service.ts +36 -220
  170. package/src/core/hooks/cli.ts +85 -47
  171. package/src/core/hooks/resolve/owner.ts +2 -2
  172. package/src/core/resources/sampler.ts +3 -2
  173. package/src/core/resources/service-status.ts +6 -35
  174. package/src/core/resources/service.ts +23 -133
  175. package/src/core/resources/status.ts +3 -2
  176. package/src/core/semantic/service.ts +8 -2
  177. package/src/core/servers/index.ts +86 -228
  178. package/src/core/servers/tunnels.ts +3 -55
  179. package/src/core/storage/durable-history.ts +52 -20
  180. package/src/core/storage/segments.ts +79 -17
  181. package/src/core/supervisor/service.ts +33 -155
  182. package/src/core/supervisor/services.ts +2 -2
  183. package/src/core/supervisor/status.ts +10 -85
  184. package/src/core/work/state.ts +7 -7
  185. package/src/core/workflow/engine.ts +22 -74
  186. package/src/core/workflow/index.ts +2 -13
  187. package/src/core/workflow/live-session-v3.ts +5 -146
  188. package/src/core/workflow/proof.ts +40 -104
  189. package/src/core/workflow/resume-lock.ts +179 -0
  190. package/src/core/workflow/run-state.ts +3 -207
  191. package/src/core/workflow/spawn-claude.ts +0 -18
  192. package/src/core/workflow/spawn-codex.ts +0 -13
  193. package/src/core/workflow/spawn-cursor.ts +0 -18
  194. package/src/core/workflow/spawn-opencode.ts +0 -14
  195. package/src/core/workflow/types.ts +11 -41
  196. package/src/core/workflow/workspaces/leases.ts +1 -1
  197. package/src/core/workflow/workspaces/local-git.ts +120 -239
  198. package/src/core/workflow/workspaces/ownership.ts +3 -158
  199. package/src/core/workflow/workspaces/reclaim.ts +3 -9
  200. package/src/core/workflow/workspaces/recovery.ts +1 -1
  201. package/src/core/workflow/workspaces/state.ts +1 -5
  202. package/src/lib/identities/assume.ts +0 -4
  203. package/src/lib/tunnel/state.ts +15 -70
  204. package/dist/commands/turn-rollback.d.ts +0 -5
  205. package/dist/commands/turn-rollback.d.ts.map +0 -1
  206. package/dist/commands/turn-rollback.js +0 -76
  207. package/dist/core/agents/state/process-handle.d.ts +0 -26
  208. package/dist/core/agents/state/process-handle.d.ts.map +0 -1
  209. package/dist/core/agents/state/process-handle.js +0 -121
  210. package/dist/core/agents/state/unchanged-file.d.ts +0 -44
  211. package/dist/core/agents/state/unchanged-file.d.ts.map +0 -1
  212. package/dist/core/agents/state/unchanged-file.js +0 -390
  213. package/dist/core/events/v3/generation-custody.d.ts +0 -5
  214. package/dist/core/events/v3/generation-custody.d.ts.map +0 -1
  215. package/dist/core/events/v3/generation-custody.js +0 -50
  216. package/dist/core/turn-rollback/content.d.ts +0 -53
  217. package/dist/core/turn-rollback/content.d.ts.map +0 -1
  218. package/dist/core/turn-rollback/content.js +0 -396
  219. package/dist/core/turn-rollback/index.d.ts +0 -72
  220. package/dist/core/turn-rollback/index.d.ts.map +0 -1
  221. package/dist/core/turn-rollback/index.js +0 -443
  222. package/dist/core/workflow/failure-evidence.d.ts +0 -16
  223. package/dist/core/workflow/failure-evidence.d.ts.map +0 -1
  224. package/dist/core/workflow/failure-evidence.js +0 -114
  225. package/dist/core/workflow/recovery-audit.d.ts +0 -30
  226. package/dist/core/workflow/recovery-audit.d.ts.map +0 -1
  227. package/dist/core/workflow/recovery-audit.js +0 -116
  228. package/src/commands/turn-rollback.ts +0 -111
  229. package/src/core/agents/state/process-handle.ts +0 -165
  230. package/src/core/agents/state/unchanged-file.ts +0 -456
  231. package/src/core/events/v3/generation-custody.ts +0 -59
  232. package/src/core/turn-rollback/content.ts +0 -499
  233. package/src/core/turn-rollback/index.ts +0 -580
  234. package/src/core/workflow/failure-evidence.ts +0 -141
  235. package/src/core/workflow/recovery-audit.ts +0 -181
@@ -16,7 +16,6 @@
16
16
  */
17
17
 
18
18
  import { existsSync } from "node:fs";
19
- import type { WorkflowRecoveryAuthorization } from "../recovery-audit.ts";
20
19
  import { git, gitMaybe } from "./git.ts";
21
20
  import type { WorkflowLiveness } from "./recovery.ts";
22
21
  import type { WorkspaceCleanupAttempt, WorkspaceCleanupReceipt } from "./types.ts";
@@ -26,7 +25,6 @@ export type ReclaimMode = "salvage" | "discard";
26
25
  export type WorkflowReclaimRefusalCode =
27
26
  | "workflow_reclaim_run_live"
28
27
  | "workflow_reclaim_liveness_unknown"
29
- | "workflow_reclaim_recovery_mismatch"
30
28
  | "workflow_reclaim_ownership_unproven"
31
29
  | "workflow_reclaim_lease_held";
32
30
 
@@ -43,7 +41,8 @@ export class WorkflowReclaimError extends Error {
43
41
  export interface WorkspaceReclaimOptions {
44
42
  mode: ReclaimMode;
45
43
  yes?: boolean;
46
- unknownLiveness?: WorkflowRecoveryAuthorization & { evidenceSha256: string };
44
+ /** Admit missing or corrupt liveness evidence; active evidence still refuses. */
45
+ force?: boolean;
47
46
  }
48
47
 
49
48
  export interface ReclaimLeaseHolder {
@@ -59,7 +58,6 @@ export interface WorkspaceReclaimPreview {
59
58
  run_id: string;
60
59
  mode: ReclaimMode;
61
60
  liveness: WorkflowLiveness;
62
- evidence_sha256: string;
63
61
  ownership: "ok" | "unproven";
64
62
  ownership_detail?: string;
65
63
  dirty_paths: string[] | null;
@@ -84,7 +82,7 @@ export interface PrepareReclaimInput {
84
82
  worktreePath: string;
85
83
  mode: ReclaimMode;
86
84
  runId: string;
87
- /** Revalidate the held reservation and peer authority immediately before effects. */
85
+ /** Recheck peer authority once, immediately before the first destructive step. */
88
86
  beforeEffect?: () => void;
89
87
  }
90
88
 
@@ -117,7 +115,6 @@ export function prepareReclaim(input: PrepareReclaimInput): ReclaimPreparation {
117
115
  // cannot see. Running clean first would leave staged deletions behind.
118
116
  input.beforeEffect?.();
119
117
  git(input.worktreePath, ["reset", "--hard"]);
120
- input.beforeEffect?.();
121
118
  git(input.worktreePath, ["clean", "-fd"]);
122
119
  return { action: "discarded", detail: "uncommitted changes were discarded on request" };
123
120
  }
@@ -138,13 +135,10 @@ export function prepareReclaim(input: PrepareReclaimInput): ReclaimPreparation {
138
135
  const before = git(input.worktreePath, ["rev-parse", "HEAD"]).trim();
139
136
  input.beforeEffect?.();
140
137
  git(input.worktreePath, ["add", "-A"]);
141
- input.beforeEffect?.();
142
138
  git(input.worktreePath, ["commit", "--no-verify", "-m", salvageMessage(input.runId)]);
143
139
  const commit = git(input.worktreePath, ["rev-parse", "HEAD"]).trim();
144
140
  const branch = salvageBranch(input.runId);
145
- input.beforeEffect?.();
146
141
  git(input.worktreePath, ["branch", "--force", branch, commit]);
147
- input.beforeEffect?.();
148
142
  git(input.worktreePath, ["reset", "--hard", before]);
149
143
  return {
150
144
  action: "salvaged",
@@ -4,7 +4,7 @@ import { readWorkflowProof } from "../proof.ts";
4
4
 
5
5
  export type WorkflowLiveness = "active" | "inactive" | "unknown";
6
6
 
7
- /** Corruption must not hide a readable active marker from an audited override. */
7
+ /** Corruption must not hide a readable active marker from a forced reclaim. */
8
8
  export function hasActiveWorkflowEvidence(coordRoot: string, runId: string): boolean {
9
9
  const path = join(resolve(coordRoot), ".harnery", "workflows", runId, "transcript.jsonl");
10
10
  if (!existsSync(path)) return false;
@@ -19,7 +19,7 @@ import {
19
19
  stableDigest,
20
20
  writeImmutableJson,
21
21
  } from "../durable-record.ts";
22
- import { assertClaimAuthority, publishWorkspaceClaim } from "./ownership.ts";
22
+ import { assertClaimAuthority } from "./ownership.ts";
23
23
 
24
24
  export { appendWorkflowTranscriptEvent } from "../transcript.ts";
25
25
 
@@ -143,10 +143,6 @@ export function readWorkspaceRequest(
143
143
  }
144
144
 
145
145
  export function writeWorkspaceClaim(coordRoot: string, claim: WorkspaceClaim): boolean {
146
- return publishWorkspaceClaim(coordRoot, claim, () => writeClaim(coordRoot, claim));
147
- }
148
-
149
- function writeClaim(coordRoot: string, claim: WorkspaceClaim): boolean {
150
146
  const path = workspaceClaimPath(coordRoot, claim.provider_id, claim.binding_id);
151
147
  try {
152
148
  return writeImmutableJson(path, claim);
@@ -140,7 +140,6 @@ export function reclaimAbandonedLocalConflict(
140
140
  let sessionId = conflict.instance_id;
141
141
  let ageSecs: number | undefined;
142
142
  const liveRow = readLiveCoordinationRow(coordRoot, conflict.instance_id);
143
- let expectedGenerationId = liveRow?.v3_generation_id ?? null;
144
143
  if (liveRow) {
145
144
  adapter = adapterOf(liveRow.platform);
146
145
  sessionId = liveRow.session_id || conflict.instance_id;
@@ -154,9 +153,7 @@ export function reclaimAbandonedLocalConflict(
154
153
  // It is required to join the exact producer state when recording the sweep.
155
154
  adapter = adapterOf(hb.platform);
156
155
  sessionId = hb.session_id || conflict.instance_id;
157
- expectedGenerationId = hb.v3_generation_id ?? null;
158
156
  } catch {
159
- expectedGenerationId = null;
160
157
  /* content unreadable — still reclaim the file */
161
158
  }
162
159
  try {
@@ -171,7 +168,6 @@ export function reclaimAbandonedLocalConflict(
171
168
  owner: conflict.instance_id,
172
169
  nativeSessionId: sessionId,
173
170
  adapter,
174
- expectedGenerationId,
175
171
  observation: "stale_heartbeat",
176
172
  ageMs: Math.max(0, (ageSecs ?? 0) * 1_000),
177
173
  });
@@ -2,7 +2,6 @@
2
2
  // <cwd>/.cache/tunnel/; gitignored, so the allowlist is per-machine.
3
3
 
4
4
  import { spawnSync } from "node:child_process";
5
- import { randomUUID } from "node:crypto";
6
5
  import {
7
6
  accessSync,
8
7
  chmodSync,
@@ -11,7 +10,6 @@ import {
11
10
  mkdirSync,
12
11
  readdirSync,
13
12
  readFileSync,
14
- renameSync,
15
13
  statSync,
16
14
  unlinkSync,
17
15
  writeFileSync,
@@ -106,12 +104,10 @@ export interface TunnelState {
106
104
  provider: TunnelProvider;
107
105
  url: string;
108
106
  gate_pid: number;
109
- gate_start_token?: string;
110
- cloudflared_start_token?: string;
111
- registration_id?: string;
112
- provider_state?: "pending" | "ready";
113
107
  /** Present for Cloudflare quick tunnels; absent for Tailscale Serve/Funnel. */
114
108
  cloudflared_pid?: number;
109
+ /** Optional provider-side process when a provider owns one. */
110
+ provider_pid?: number;
115
111
  started_at: string;
116
112
  target: string;
117
113
  vhost: string;
@@ -172,15 +168,7 @@ export function readState(
172
168
  }
173
169
 
174
170
  export function writeState(state: TunnelState, root: string = process.cwd()): void {
175
- const path = cachePath(stateFile(state.name), root);
176
- const temporary = `${path}.${randomUUID()}.tmp`;
177
- try {
178
- writeFileSync(temporary, JSON.stringify(state, null, 2), { flag: "wx", mode: 0o600 });
179
- renameSync(temporary, path);
180
- } catch (error) {
181
- if (existsSync(temporary)) unlinkSync(temporary);
182
- throw error;
183
- }
171
+ writeFileSync(cachePath(stateFile(state.name), root), JSON.stringify(state, null, 2));
184
172
  }
185
173
 
186
174
  export function clearState(name: string = DEFAULT_INSTANCE, root: string = process.cwd()): void {
@@ -214,60 +202,17 @@ export function isProcessAlive(pid: number): boolean {
214
202
  }
215
203
  }
216
204
 
217
- export type TunnelReadiness = "ready" | "dead" | "unknown";
218
- export type TunnelProcessObservation = "same" | "absent" | "different" | "unknown";
219
-
220
- export interface TunnelReadinessVerifier {
221
- observeProcess(pid: number, originalToken: string): TunnelProcessObservation;
222
- withRegistration(state: TunnelState, inspect: () => TunnelReadiness): TunnelReadiness;
223
- }
205
+ export type ProcessAliveCheck = (pid: number) => boolean;
224
206
 
225
- /** Classify saved original witnesses under the verifier's registration custody. */
226
- export function tunnelReadiness(
207
+ /** True when both the local gate and its provider-side process are live. */
208
+ export function isTunnelStateLive(
227
209
  state: TunnelState,
228
- verifier: TunnelReadinessVerifier,
229
- ): TunnelReadiness {
230
- if (
231
- !state ||
232
- typeof state !== "object" ||
233
- Object.hasOwn(state, "provider_pid") ||
234
- Object.hasOwn(state, "provider_start_token") ||
235
- typeof state.registration_id !== "string" ||
236
- !state.registration_id ||
237
- !Number.isSafeInteger(state.gate_pid) ||
238
- state.gate_pid < 1 ||
239
- typeof state.gate_start_token !== "string" ||
240
- !state.gate_start_token
241
- )
242
- return "unknown";
243
- const targets = [{ pid: state.gate_pid, token: state.gate_start_token }];
244
- if (state.provider === "tailscale") {
245
- if (
246
- state.provider_state !== "ready" ||
247
- state.cloudflared_pid !== undefined ||
248
- state.cloudflared_start_token !== undefined
249
- )
250
- return "unknown";
251
- } else if (state.provider === "cloudflare") {
252
- if (
253
- !Number.isSafeInteger(state.cloudflared_pid) ||
254
- state.cloudflared_pid! < 1 ||
255
- typeof state.cloudflared_start_token !== "string" ||
256
- !state.cloudflared_start_token
257
- )
258
- return "unknown";
259
- targets.push({ pid: state.cloudflared_pid!, token: state.cloudflared_start_token });
260
- } else return "unknown";
261
- try {
262
- return verifier.withRegistration(state, () => {
263
- const observed = targets.map(({ pid, token }) => verifier.observeProcess(pid, token));
264
- if (observed.every((value) => value === "absent")) return "dead";
265
- if (observed.every((value) => value === "same")) return "ready";
266
- return "unknown";
267
- });
268
- } catch {
269
- return "unknown";
270
- }
210
+ processAlive: ProcessAliveCheck = isProcessAlive,
211
+ ): boolean {
212
+ if (!processAlive(state.gate_pid)) return false;
213
+ if (state.provider === "tailscale") return true;
214
+ const providerPid = state.cloudflared_pid ?? state.provider_pid;
215
+ return typeof providerPid === "number" && processAlive(providerPid);
271
216
  }
272
217
 
273
218
  export function tunnelTargetPort(state: TunnelState): number | null {
@@ -297,15 +242,15 @@ export function tunnelTargetPort(state: TunnelState): number | null {
297
242
  export function findLiveTunnelForOrigin(
298
243
  port: number,
299
244
  vhost: string,
300
- root: string,
301
- verifier: TunnelReadinessVerifier,
245
+ root: string = process.cwd(),
246
+ processAlive: ProcessAliveCheck = isProcessAlive,
302
247
  ): TunnelState | null {
303
248
  return (
304
249
  listStates(root).find(
305
250
  (state) =>
306
251
  tunnelTargetPort(state) === port &&
307
252
  state.vhost === vhost &&
308
- tunnelReadiness(state, verifier) === "ready",
253
+ isTunnelStateLive(state, processAlive),
309
254
  ) ?? null
310
255
  );
311
256
  }
@@ -1,5 +0,0 @@
1
- import type { Command } from "commander";
2
- import type { EmitContext, HarneryProgramContext } from "../commander.js";
3
- /** Explicit turn boundaries; hooks cannot infer provider ownership or path scope. */
4
- export declare function registerTurnRollbackCommand(program: Command, emit: EmitContext, context?: HarneryProgramContext): void;
5
- //# sourceMappingURL=turn-rollback.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"turn-rollback.d.ts","sourceRoot":"","sources":["../../src/commands/turn-rollback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAa1E,qFAAqF;AACrF,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,IAAI,CA2FN"}
@@ -1,76 +0,0 @@
1
- import { monorepoRoot } from "../core/agents/index.js";
2
- import { applyTurnRollback, beginTurnRollback, inspectTurnRollback, prepareTurnRollback, sealTurnRollback, } from "../core/turn-rollback/index.js";
3
- import { readJsonRecord } from "../core/workflow/durable-record.js";
4
- import { readWorkspaceBinding } from "../core/workflow/workspaces/state.js";
5
- /** Explicit turn boundaries; hooks cannot infer provider ownership or path scope. */
6
- export function registerTurnRollbackCommand(program, emit, context) {
7
- const command = program
8
- .command("turn-rollback")
9
- .description("Capture and review exact-path content rollback in an owned workspace");
10
- const run = (operation) => async (options) => {
11
- try {
12
- const coordRoot = context?.resolveCoordRoot?.() ?? context?.repoRoot ?? monorepoRoot();
13
- if (!coordRoot)
14
- throw new Error("project coordination root is unavailable");
15
- emit.config({ format: "json" });
16
- const result = await operation(coordRoot, options);
17
- emit.data(result);
18
- if (result &&
19
- typeof result === "object" &&
20
- "status" in result &&
21
- result.status === "unknown")
22
- emit.setExitCode(1);
23
- }
24
- catch (error) {
25
- emit.error({ code: "turn_rollback_refused", message: String(error) });
26
- emit.setExitCode(1);
27
- }
28
- };
29
- const binding = (root, options) => {
30
- const value = readWorkspaceBinding(root, "local-git-worktree", options.binding);
31
- if (!value)
32
- throw new Error("immutable workspace binding was not found");
33
- return value;
34
- };
35
- command
36
- .command("begin")
37
- .description("Capture exact literal paths before a turn")
38
- .requiredOption("--binding <id>", "Owned workspace binding ID")
39
- .requiredOption("--turn <id>", "Caller turn identity")
40
- .requiredOption("--generation <number>", "Increasing turn generation")
41
- .requiredOption("--path <file...>", "Exact relative file paths, including planned new files")
42
- .action(run((root, options) => beginTurnRollback(root, {
43
- binding: binding(root, options),
44
- turn: { turn_id: options.turn, generation: Number(options.generation) },
45
- paths: options.path,
46
- })));
47
- for (const operation of ["seal", "prepare", "show"]) {
48
- command
49
- .command(`${operation} <capture-id>`)
50
- .description(`${operation} an exact turn capture`)
51
- .requiredOption("--binding <id>", "Owned workspace binding ID")
52
- .action((id, options) => run((root, opts) => {
53
- const input = { binding: binding(root, opts), capture_id: id };
54
- return operation === "seal"
55
- ? sealTurnRollback(root, input)
56
- : operation === "prepare"
57
- ? prepareTurnRollback(root, input)
58
- : inspectTurnRollback(root, input);
59
- })(options));
60
- }
61
- command
62
- .command("apply")
63
- .description("Preview a saved proposal, or apply it after exact confirmation")
64
- .requiredOption("--binding <id>", "Owned workspace binding ID")
65
- .requiredOption("--plan <file>", "Saved JSON proposal returned by prepare")
66
- .option("--yes", "Apply this exact proposal; preview is the default")
67
- .option("--actor <name>", "Who authorized the restore")
68
- .option("--reason <text>", "Why this turn is being restored")
69
- .action(run((root, options) => applyTurnRollback(root, {
70
- binding: binding(root, options),
71
- plan: readJsonRecord(options.plan, "rollback proposal"),
72
- yes: options.yes,
73
- actor: options.actor,
74
- reason: options.reason,
75
- })));
76
- }
@@ -1,26 +0,0 @@
1
- import type { ProcessGenerationVerdict } from "./proc-start.js";
2
- export interface ProcessHandleSignalResult {
3
- sent: boolean;
4
- verdict: ProcessGenerationVerdict;
5
- }
6
- export type NativeProcessHelperRunner = (command: string, args: string[], options: {
7
- input: string;
8
- encoding: "utf8";
9
- timeout: number;
10
- maxBuffer: number;
11
- windowsHide: boolean;
12
- }) => {
13
- status: number | null;
14
- stdout: string | Buffer | null;
15
- error?: Error;
16
- };
17
- export declare const LINUX_PROCESS_HANDLE_SCRIPT = "\nimport json, os, pathlib, signal, sys\nresult = {\"sent\": False, \"verdict\": \"unknown\"}\nfd = None\ntry:\n request = json.loads(sys.stdin.readline())\n if not hasattr(os, \"pidfd_open\") or not hasattr(signal, \"pidfd_send_signal\"):\n raise RuntimeError(\"pidfd support unavailable\")\n fd = os.pidfd_open(request[\"pid\"])\n stat = pathlib.Path(\"/proc/%d/stat\" % request[\"pid\"]).read_text()\n ticks = stat[stat.rfind(\") \") + 2:].split()[19]\n boot = pathlib.Path(\"/proc/sys/kernel/random/boot_id\").read_text().strip().replace(\"-\", \"\")[:8]\n token = \"l%s.%s\" % (boot, ticks)\n result[\"token\"] = token\n recorded = request.get(\"token\")\n result[\"verdict\"] = \"same\" if token == recorded else \"different\"\n if request[\"mode\"] == \"signal\" and result[\"verdict\"] == \"same\":\n print(json.dumps({\"phase\": \"verified\"}), flush=True)\n if sys.stdin.readline().strip() == \"signal\":\n signal.pidfd_send_signal(fd, request[\"signal\"])\n result[\"sent\"] = True\nexcept Exception:\n pass\nfinally:\n if fd is not None:\n os.close(fd)\nprint(json.dumps(result), flush=True)\n";
18
- export declare const WINDOWS_PROCESS_HANDLE_SCRIPT = "\n$ErrorActionPreference = 'Stop'\n$result = @{ sent = $false; verdict = 'unknown' }\n$handle = [IntPtr]::Zero\ntry {\n Add-Type -TypeDefinition @'\nusing System;\nusing System.Runtime.InteropServices;\npublic static class HarneryProcessHandle {\n [DllImport(\"kernel32.dll\", SetLastError=true)] public static extern IntPtr OpenProcess(uint access, bool inherit, uint processId);\n [DllImport(\"kernel32.dll\", SetLastError=true)] public static extern bool GetProcessTimes(IntPtr handle, out long creation, out long exit, out long kernel, out long user);\n [DllImport(\"kernel32.dll\", SetLastError=true)] public static extern bool TerminateProcess(IntPtr handle, uint exitCode);\n [DllImport(\"kernel32.dll\")] public static extern uint WaitForSingleObject(IntPtr handle, uint milliseconds);\n [DllImport(\"kernel32.dll\")] public static extern bool CloseHandle(IntPtr handle);\n}\n'@\n $request = [Console]::In.ReadLine() | ConvertFrom-Json\n $access = [uint32]0x101000\n if ($request.mode -eq 'signal') { $access = $access -bor 1 }\n $handle = [HarneryProcessHandle]::OpenProcess($access, $false, [uint32]$request.pid)\n if ($handle -eq [IntPtr]::Zero) { throw 'process handle unavailable' }\n [long]$creation = 0; [long]$exitTime = 0; [long]$kernel = 0; [long]$userTime = 0\n if (-not [HarneryProcessHandle]::GetProcessTimes($handle, [ref]$creation, [ref]$exitTime, [ref]$kernel, [ref]$userTime)) { throw 'process time unavailable' }\n $token = 'w' + $creation.ToString([Globalization.CultureInfo]::InvariantCulture)\n $result.token = $token\n $result.verdict = if ($token -ceq $request.token) { 'same' } else { 'different' }\n if ($request.mode -eq 'signal' -and $result.verdict -eq 'same') {\n [Console]::Out.WriteLine('{\"phase\":\"verified\"}')\n [Console]::Out.Flush()\n if ([Console]::In.ReadLine() -eq 'signal' -and [HarneryProcessHandle]::WaitForSingleObject($handle, 0) -eq 258) {\n $result.sent = [HarneryProcessHandle]::TerminateProcess($handle, 1)\n }\n }\n} catch {} finally {\n if ($handle -ne [IntPtr]::Zero) { [void][HarneryProcessHandle]::CloseHandle($handle) }\n}\n$result | ConvertTo-Json -Compress\n";
19
- /** Windows creation FILETIME, read from an OpenProcess handle. */
20
- export declare function windowsProcessStartToken(pid: number, run?: NativeProcessHelperRunner): string | null;
21
- /** No numeric-PID signaling fallback is permitted when an exact handle fails. */
22
- export declare function signalProcessWithHandle(pid: number, recordedToken: string, signal: NodeJS.Signals | number, options?: {
23
- platform?: NodeJS.Platform;
24
- run?: NativeProcessHelperRunner;
25
- }): ProcessHandleSignalResult;
26
- //# sourceMappingURL=process-handle.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"process-handle.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/process-handle.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,wBAAwB,CAAC;CACnC;AAMD,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE;IACP,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACtB,KACE;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAI9E,eAAO,MAAM,2BAA2B,+qCA2BvC,CAAC;AAEF,eAAO,MAAM,6BAA6B,qnEAqCzC,CAAC;AAwCF,kEAAkE;AAClE,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,GAAG,GAAE,yBAAqC,GACzC,MAAM,GAAG,IAAI,CAGf;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,EAC/B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAAC,GAAG,CAAC,EAAE,yBAAyB,CAAA;CAAO,GAC5E,yBAAyB,CAgB3B"}
@@ -1,121 +0,0 @@
1
- import { spawnSync } from "node:child_process";
2
- import { constants } from "node:os";
3
- // The helper owns the descriptor throughout observation and effect. The second
4
- // input line authorizes the effect; EOF releases the handle without signaling.
5
- export const LINUX_PROCESS_HANDLE_SCRIPT = `
6
- import json, os, pathlib, signal, sys
7
- result = {"sent": False, "verdict": "unknown"}
8
- fd = None
9
- try:
10
- request = json.loads(sys.stdin.readline())
11
- if not hasattr(os, "pidfd_open") or not hasattr(signal, "pidfd_send_signal"):
12
- raise RuntimeError("pidfd support unavailable")
13
- fd = os.pidfd_open(request["pid"])
14
- stat = pathlib.Path("/proc/%d/stat" % request["pid"]).read_text()
15
- ticks = stat[stat.rfind(") ") + 2:].split()[19]
16
- boot = pathlib.Path("/proc/sys/kernel/random/boot_id").read_text().strip().replace("-", "")[:8]
17
- token = "l%s.%s" % (boot, ticks)
18
- result["token"] = token
19
- recorded = request.get("token")
20
- result["verdict"] = "same" if token == recorded else "different"
21
- if request["mode"] == "signal" and result["verdict"] == "same":
22
- print(json.dumps({"phase": "verified"}), flush=True)
23
- if sys.stdin.readline().strip() == "signal":
24
- signal.pidfd_send_signal(fd, request["signal"])
25
- result["sent"] = True
26
- except Exception:
27
- pass
28
- finally:
29
- if fd is not None:
30
- os.close(fd)
31
- print(json.dumps(result), flush=True)
32
- `;
33
- export const WINDOWS_PROCESS_HANDLE_SCRIPT = `
34
- $ErrorActionPreference = 'Stop'
35
- $result = @{ sent = $false; verdict = 'unknown' }
36
- $handle = [IntPtr]::Zero
37
- try {
38
- Add-Type -TypeDefinition @'
39
- using System;
40
- using System.Runtime.InteropServices;
41
- public static class HarneryProcessHandle {
42
- [DllImport("kernel32.dll", SetLastError=true)] public static extern IntPtr OpenProcess(uint access, bool inherit, uint processId);
43
- [DllImport("kernel32.dll", SetLastError=true)] public static extern bool GetProcessTimes(IntPtr handle, out long creation, out long exit, out long kernel, out long user);
44
- [DllImport("kernel32.dll", SetLastError=true)] public static extern bool TerminateProcess(IntPtr handle, uint exitCode);
45
- [DllImport("kernel32.dll")] public static extern uint WaitForSingleObject(IntPtr handle, uint milliseconds);
46
- [DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr handle);
47
- }
48
- '@
49
- $request = [Console]::In.ReadLine() | ConvertFrom-Json
50
- $access = [uint32]0x101000
51
- if ($request.mode -eq 'signal') { $access = $access -bor 1 }
52
- $handle = [HarneryProcessHandle]::OpenProcess($access, $false, [uint32]$request.pid)
53
- if ($handle -eq [IntPtr]::Zero) { throw 'process handle unavailable' }
54
- [long]$creation = 0; [long]$exitTime = 0; [long]$kernel = 0; [long]$userTime = 0
55
- if (-not [HarneryProcessHandle]::GetProcessTimes($handle, [ref]$creation, [ref]$exitTime, [ref]$kernel, [ref]$userTime)) { throw 'process time unavailable' }
56
- $token = 'w' + $creation.ToString([Globalization.CultureInfo]::InvariantCulture)
57
- $result.token = $token
58
- $result.verdict = if ($token -ceq $request.token) { 'same' } else { 'different' }
59
- if ($request.mode -eq 'signal' -and $result.verdict -eq 'same') {
60
- [Console]::Out.WriteLine('{"phase":"verified"}')
61
- [Console]::Out.Flush()
62
- if ([Console]::In.ReadLine() -eq 'signal' -and [HarneryProcessHandle]::WaitForSingleObject($handle, 0) -eq 258) {
63
- $result.sent = [HarneryProcessHandle]::TerminateProcess($handle, 1)
64
- }
65
- }
66
- } catch {} finally {
67
- if ($handle -ne [IntPtr]::Zero) { [void][HarneryProcessHandle]::CloseHandle($handle) }
68
- }
69
- $result | ConvertTo-Json -Compress
70
- `;
71
- function runHelper(request, platform, run) {
72
- const unknown = { sent: false, verdict: "unknown" };
73
- if (!Number.isInteger(request.pid) || request.pid <= 0)
74
- return unknown;
75
- if (platform !== "linux" && platform !== "win32")
76
- return unknown;
77
- try {
78
- const command = platform === "linux" ? "python3" : "powershell.exe";
79
- const args = platform === "linux"
80
- ? ["-I", "-c", LINUX_PROCESS_HANDLE_SCRIPT]
81
- : ["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", WINDOWS_PROCESS_HANDLE_SCRIPT];
82
- const output = run(command, args, {
83
- input: `${JSON.stringify(request)}\nsignal\n`,
84
- encoding: "utf8",
85
- timeout: 10_000,
86
- maxBuffer: 64 * 1024,
87
- windowsHide: true,
88
- });
89
- if (output.error || output.status !== 0)
90
- return unknown;
91
- const lines = String(output.stdout ?? "")
92
- .trim()
93
- .split(/\r?\n/);
94
- const parsed = JSON.parse(lines.at(-1) ?? "");
95
- if (typeof parsed.sent !== "boolean" ||
96
- !["same", "different", "unknown"].includes(parsed.verdict) ||
97
- (parsed.sent && parsed.verdict !== "same"))
98
- return unknown;
99
- return parsed;
100
- }
101
- catch {
102
- return unknown;
103
- }
104
- }
105
- /** Windows creation FILETIME, read from an OpenProcess handle. */
106
- export function windowsProcessStartToken(pid, run = spawnSync) {
107
- const result = runHelper({ mode: "probe", pid }, "win32", run);
108
- return typeof result.token === "string" && /^w\d+$/.test(result.token) ? result.token : null;
109
- }
110
- /** No numeric-PID signaling fallback is permitted when an exact handle fails. */
111
- export function signalProcessWithHandle(pid, recordedToken, signal, options = {}) {
112
- const platform = options.platform ?? process.platform;
113
- const number = typeof signal === "number" ? signal : constants.signals[signal];
114
- if (!Number.isInteger(number) ||
115
- number <= 0 ||
116
- (platform === "linux" && !/^l[0-9a-f]{8}\.\d+$/.test(recordedToken)) ||
117
- (platform === "win32" && (!/^w\d+$/.test(recordedToken) || ![9, 15].includes(number))))
118
- return { sent: false, verdict: "unknown" };
119
- const result = runHelper({ mode: "signal", pid, token: recordedToken, signal: number }, platform, options.run ?? spawnSync);
120
- return { sent: result.sent, verdict: result.verdict };
121
- }
@@ -1,44 +0,0 @@
1
- export interface FileRevision {
2
- readonly bytes: Buffer;
3
- readonly dev: bigint;
4
- readonly ino: bigint;
5
- readonly size: bigint;
6
- readonly mtimeNs: bigint;
7
- readonly ctimeNs: bigint;
8
- }
9
- export type DeleteFileResult = {
10
- state: "deleted" | "changed" | "missing" | "rejected";
11
- } | {
12
- state: "recovery-required";
13
- recoveryPath: string;
14
- error?: string;
15
- } | {
16
- state: "error";
17
- recoveryPath?: string;
18
- error: string;
19
- };
20
- export interface FileRecoveryResult {
21
- state: "restored" | "retained" | "error";
22
- recoveryPath: string;
23
- sourcePath?: string;
24
- error?: string;
25
- }
26
- /** A stable read of one regular file, including its exact bytes and revision. */
27
- export declare function captureFileRevision(filePath: string): FileRevision | null;
28
- export declare function fileRevisionMatches(filePath: string, expected: FileRevision): boolean;
29
- /**
30
- * Writers must publish by atomic rename, never by an open descriptor to the old
31
- * inode. The private directory is outside their publication namespace. Moving
32
- * the row gives deletion custody over that inode without owning its live name.
33
- * The caller owns the state parent and keeps its topology stable. Its platform
34
- * permissions define which principals can modify it; this protocol does not
35
- * exclude principals already authorized to change that parent.
36
- */
37
- export declare function deleteFileIfUnchanged(filePath: string, expected: FileRevision, validate: (pinned: FileRevision) => boolean): DeleteFileResult;
38
- /**
39
- * Recover same-host/platform/PID-namespace pins after process termination. File fsync
40
- * protects manifest contents; directory entries are not fsynced, so this does
41
- * not promise recovery after an OS crash or power loss.
42
- */
43
- export declare function recoverInterruptedFileDeletions(directoryPath: string, validate: (sourcePath: string) => boolean): FileRecoveryResult[];
44
- //# sourceMappingURL=unchanged-file.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"unchanged-file.d.ts","sourceRoot":"","sources":["../../../../src/core/agents/state/unchanged-file.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;CAAE,GACzD;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAoCzE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,OAAO,CAGrF;AAsGD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,GAC1C,gBAAgB,CAmFlB;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,GACxC,kBAAkB,EAAE,CA+FtB"}