@intentic/machine 1.317.0 → 1.319.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +186 -11
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +2 -2
- package/dist/commands.js.map +1 -1
- package/dist/device/commands.d.ts +3 -1
- package/dist/device/commands.d.ts.map +1 -1
- package/dist/device/commands.js +2 -2
- package/dist/device/commands.js.map +1 -1
- package/dist/device/connection.d.ts +1 -0
- package/dist/device/connection.d.ts.map +1 -1
- package/dist/device/connection.js +5 -0
- package/dist/device/connection.js.map +1 -1
- package/dist/device/grant.d.ts +38 -0
- package/dist/device/grant.d.ts.map +1 -1
- package/dist/device/loopback-catch.d.ts +3 -0
- package/dist/device/loopback-catch.d.ts.map +1 -0
- package/dist/device/loopback-catch.js +103 -0
- package/dist/device/loopback-catch.js.map +1 -0
- package/dist/device/mcp.d.ts.map +1 -1
- package/dist/device/mcp.js +8 -1
- package/dist/device/mcp.js.map +1 -1
- package/dist/device/router.d.ts +38 -0
- package/dist/device/router.d.ts.map +1 -1
- package/dist/device/router.js +3 -1
- package/dist/device/router.js.map +1 -1
- package/dist/device/sandbox-cli.d.ts +3 -0
- package/dist/device/sandbox-cli.d.ts.map +1 -1
- package/dist/device/sandbox-cli.js +42 -0
- package/dist/device/sandbox-cli.js.map +1 -1
- package/dist/device/sandbox-rounds/ic-rounds.d.ts +3 -4
- package/dist/device/sandbox-rounds/ic-rounds.d.ts.map +1 -1
- package/dist/device/sandbox-rounds/ic-rounds.js +9 -3
- package/dist/device/sandbox-rounds/ic-rounds.js.map +1 -1
- package/dist/device/sandbox-rounds/keeper.d.ts +95 -0
- package/dist/device/sandbox-rounds/keeper.d.ts.map +1 -0
- package/dist/device/sandbox-rounds/keeper.js +277 -0
- package/dist/device/sandbox-rounds/keeper.js.map +1 -0
- package/dist/device/sandbox-rounds/swap-records.d.ts +1 -0
- package/dist/device/sandbox-rounds/swap-records.d.ts.map +1 -1
- package/dist/device/sandbox-rounds/swap-records.js +7 -0
- package/dist/device/sandbox-rounds/swap-records.js.map +1 -1
- package/dist/device/tools/agent.d.ts +2 -2
- package/dist/device/tools/agent.d.ts.map +1 -1
- package/dist/device/tools/agent.js +1 -3
- package/dist/device/tools/agent.js.map +1 -1
- package/dist/device/tools/describe.d.ts +1 -1
- package/dist/device/tools/describe.d.ts.map +1 -1
- package/dist/device/tools/describe.js +2 -1
- package/dist/device/tools/describe.js.map +1 -1
- package/dist/device/tools/in-flight.d.ts +6 -0
- package/dist/device/tools/in-flight.d.ts.map +1 -0
- package/dist/device/tools/in-flight.js +26 -0
- package/dist/device/tools/in-flight.js.map +1 -0
- package/dist/device/tools/sandboxes.d.ts +19 -7
- package/dist/device/tools/sandboxes.d.ts.map +1 -1
- package/dist/device/tools/sandboxes.js +90 -20
- package/dist/device/tools/sandboxes.js.map +1 -1
- package/dist/environments/machine.d.ts +1 -0
- package/dist/environments/machine.d.ts.map +1 -1
- package/dist/environments/machine.js.map +1 -1
- package/dist/resident.d.ts +12 -1
- package/dist/resident.d.ts.map +1 -1
- package/dist/resident.js +45 -14
- package/dist/resident.js.map +1 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +9 -4
- package/dist/status.js.map +1 -1
- package/dist/sync/commands.d.ts +21 -1
- package/dist/sync/commands.d.ts.map +1 -1
- package/dist/sync/commands.js +91 -20
- package/dist/sync/commands.js.map +1 -1
- package/dist/sync/config.d.ts +10 -1
- package/dist/sync/config.d.ts.map +1 -1
- package/dist/sync/config.js +42 -1
- package/dist/sync/config.js.map +1 -1
- package/dist/sync/folders.d.ts +8 -0
- package/dist/sync/folders.d.ts.map +1 -0
- package/dist/sync/folders.js +34 -0
- package/dist/sync/folders.js.map +1 -0
- package/dist/sync/git-bridge.d.ts +1 -1
- package/dist/sync/git-bridge.d.ts.map +1 -1
- package/dist/sync/git-bridge.js +2 -1
- package/dist/sync/git-bridge.js.map +1 -1
- package/dist/sync/mirror.d.ts.map +1 -1
- package/dist/sync/mirror.js +3 -3
- package/dist/sync/mirror.js.map +1 -1
- package/dist/sync/mutagen.d.ts +16 -3
- package/dist/sync/mutagen.d.ts.map +1 -1
- package/dist/sync/mutagen.js +40 -22
- package/dist/sync/mutagen.js.map +1 -1
- package/dist/sync/project-commands.d.ts +23 -0
- package/dist/sync/project-commands.d.ts.map +1 -0
- package/dist/sync/project-commands.js +212 -0
- package/dist/sync/project-commands.js.map +1 -0
- package/dist/sync/project-files.d.ts +42 -0
- package/dist/sync/project-files.d.ts.map +1 -0
- package/dist/sync/project-files.js +110 -0
- package/dist/sync/project-files.js.map +1 -0
- package/dist/sync/project-local.d.ts +46 -0
- package/dist/sync/project-local.d.ts.map +1 -0
- package/dist/sync/project-local.js +217 -0
- package/dist/sync/project-local.js.map +1 -0
- package/dist/sync/project-remote.d.ts +55 -0
- package/dist/sync/project-remote.d.ts.map +1 -0
- package/dist/sync/project-remote.js +261 -0
- package/dist/sync/project-remote.js.map +1 -0
- package/dist/sync/project-transfer.d.ts +52 -0
- package/dist/sync/project-transfer.d.ts.map +1 -0
- package/dist/sync/project-transfer.js +278 -0
- package/dist/sync/project-transfer.js.map +1 -0
- package/dist/sync/report.d.ts.map +1 -1
- package/dist/sync/report.js +6 -4
- package/dist/sync/report.js.map +1 -1
- package/dist/sync/residue.d.ts.map +1 -1
- package/dist/sync/residue.js +2 -1
- package/dist/sync/residue.js.map +1 -1
- package/dist/sync/restore-points.d.ts +72 -0
- package/dist/sync/restore-points.d.ts.map +1 -0
- package/dist/sync/restore-points.js +154 -0
- package/dist/sync/restore-points.js.map +1 -0
- package/dist/sync/ssh.d.ts +3 -0
- package/dist/sync/ssh.d.ts.map +1 -1
- package/dist/sync/ssh.js +13 -4
- package/dist/sync/ssh.js.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -21,7 +21,10 @@ flowchart LR
|
|
|
21
21
|
the intentic sandboxes on this machine through the `ic` CLI.
|
|
22
22
|
- The sandbox tools are thin callers of `ic` ([`tools/sandboxes.ts`](src/device/tools/sandboxes.ts)): the listing is
|
|
23
23
|
`ic sandbox list --json` passed through, and start, stop, restart, the swaps, `set-shape`, `forget-shape` and the
|
|
24
|
-
logs are ic's own verbs, argv spelled by the contract (`icShapeArgs`, `icPowerArgs`).
|
|
24
|
+
logs are ic's own verbs, argv spelled by the contract (`icShapeArgs`, `icPowerArgs`). `diagnose_sandbox` is
|
|
25
|
+
`ic sandbox doctor <slug> --json`, read-only and gated like the logs (`shell` or `sandboxes`), so an agent in another
|
|
26
|
+
sandbox can find out why one on this device is unreachable; it skips the listing, which cannot answer while Docker is
|
|
27
|
+
down, and refuses a slug ic would read as a flag. The shape reaches ic as the
|
|
25
28
|
contract's own object (`--set memoryGib=12`), so no flag of ic's is spelled here; the old `reshape` op is carried
|
|
26
29
|
out through the same verb. A rollback's `to` becomes `ic sandbox rollback <slug> --to <version>`. A sandbox an
|
|
27
30
|
interrupted swap left parked is listed under its own slug and found like any other, so start, rollback and update
|
|
@@ -33,14 +36,25 @@ flowchart LR
|
|
|
33
36
|
A fetch that fails is logged with its reason and reported in the device's facts (`icOutOfDate`, beside `features`),
|
|
34
37
|
so a stale `ic` explains why logs and saving a shape are missing; the next sandbox action tries again.
|
|
35
38
|
- **sync** (`src/sync/`): `sync setup` enrolls an SSH key and runs Mutagen against the sandbox's sshd, reached
|
|
36
|
-
through a loopback port tunnelled over a WebSocket. It keeps a folder two-way synced
|
|
37
|
-
port to the same localhost port, and fast-forwards local git clones from the sandbox.
|
|
39
|
+
through a loopback port tunnelled over a WebSocket. It keeps a folder two-way synced (a project copy-first, below),
|
|
40
|
+
forwards every workspace port to the same localhost port, and fast-forwards local git clones from the sandbox.
|
|
41
|
+
- A **project pairing** (`sync setup --remote-dir /work/<name> --project`, what the desktop app asks for when it
|
|
42
|
+
makes a sandbox for a folder the owner picked) syncs that folder with `/work/<name>` rather than `/work`, and nothing
|
|
43
|
+
of the sandbox's is written into it: no state backup session, no git bridge, and an ignore list that keeps a
|
|
44
|
+
project's own `.intentic/` and `refs/` ([`sync/config.ts`](src/sync/config.ts) holds a remote dir to those two
|
|
45
|
+
shapes, and refuses `sync.json` whole otherwise). `setup` refuses a folder that is, holds or sits inside another
|
|
46
|
+
sandbox's, and a set-up-again that would change where a paired sandbox's folder syncs. It is **copy-first** unless
|
|
47
|
+
its owner opted into two-way: see [Copy-first projects](#copy-first-projects).
|
|
38
48
|
- Only the resident agent creates Mutagen sessions: `setup` records the pairing and waits for the session to
|
|
39
49
|
appear, since two creators racing left one name holding two identical sessions. The agent keeps one session per
|
|
40
|
-
name, terminating any extras, and recreates a session whose rules drifted
|
|
50
|
+
name, terminating any extras, and recreates a session whose rules drifted (its ignores, its folders, its sync mode,
|
|
51
|
+
its symlink mode). A two-way session replaced by another waits until no conflicts are left and has its derived
|
|
52
|
+
residue swept first; every other replacement happens as soon as the sandbox answers (`settlesFirst` in
|
|
53
|
+
[`sync/mutagen.ts`](src/sync/mutagen.ts) says why for each).
|
|
41
54
|
- `setup` replaces what this agent's `known_hosts` holds for the pairing's alias (hashed entries included): with the
|
|
42
|
-
host key the enrollment carries when it carries one
|
|
43
|
-
|
|
55
|
+
host key the enrollment carries when it carries one (a sandbox reads its sshd's public key off its history volume and
|
|
56
|
+
answers with it, `SyncEnrollmentAnswerSchema` in the contract), else with nothing, so `accept-new` records the key
|
|
57
|
+
the sandbox presents now, as it does for an older sandbox. Outside an enrollment a changed key is still refused. A sandbox whose ports poll has failed for ten
|
|
44
58
|
minutes has its forwards taken off localhost, and they come back with its first answer. `sync uninstall` stops and
|
|
45
59
|
unregisters Mutagen's daemon only when it is this agent's own copy, never a Mutagen the user installed.
|
|
46
60
|
- Symbolic links travel only where the device can create them ([`sync/symlinks.ts`](src/sync/symlinks.ts)). A
|
|
@@ -63,18 +77,135 @@ flowchart LR
|
|
|
63
77
|
- Scopes are enforced here and nowhere else: the sandbox only asks, and a refusal names the switch that is off.
|
|
64
78
|
Files stay inside the configured roots, writes need their own switch, and every call is appended to
|
|
65
79
|
`~/.intentic/machine/audit.jsonl`. While an agent drives input on Windows, a notice shows on screen and
|
|
66
|
-
`PAUSE_HOTKEY` pauses every link.
|
|
67
|
-
|
|
80
|
+
`PAUSE_HOTKEY` pauses every link. The one door behind no switch is this agent's own Update and Restart
|
|
81
|
+
(`runAgentFlow`, [`device/tools/agent.ts`](src/device/tools/agent.ts)): no agent tool reaches it, and the sandbox
|
|
82
|
+
admits only a maintainer to it, so the owner's maintenance does not wait on the agents' "Run commands" (2026-09-29;
|
|
83
|
+
it rode that switch before, and an owner had to widen what agents may do to update the agent).
|
|
84
|
+
- Every connection dials out; the only listeners are on loopback. One of them is short-lived: while a sandbox's
|
|
85
|
+
sign-in is open, [`device/loopback-catch.ts`](src/device/loopback-catch.ts) listens on the
|
|
86
|
+
`http://localhost:<port>/…` address the provider redirects to, the one a CLI running here would have held, and
|
|
87
|
+
streams each landing back (`catchLoopback`, advertised as the `loopback-catch` feature). It checks nothing: the state
|
|
88
|
+
and the PKCE verifier stay in the sandbox, which alone can tell the sign-in from anything else that hits the port. A
|
|
89
|
+
taken port answers `busy`, and the sandbox leaves the paste to the person.
|
|
68
90
|
- On Windows the Windows side is the root of the PC (`src/environments/`): it holds one `wsl.exe` session per
|
|
69
91
|
distro with an agent, and `upgrade` brings every environment to the same release. The root also updates itself
|
|
70
92
|
on a timer and pre-downloads sandbox updates with `ic sandbox prepare --auto`.
|
|
71
93
|
- The install shims only put a first binary down and run `setup`; `install.ts` decides the rest. `status --json`
|
|
72
94
|
is what the desktop app's tray reads.
|
|
73
95
|
|
|
96
|
+
### Copy-first projects
|
|
97
|
+
|
|
98
|
+
A project's folder flows **one way**, this device to the sandbox, so nothing an agent does in `/work/<name>` (an
|
|
99
|
+
`rm -rf` included) reaches the owner's files. What an agent changed comes back only when the owner asks, through
|
|
100
|
+
`sync bring-back`, which keeps a restore point first. Two-way stays one switch away.
|
|
101
|
+
|
|
102
|
+
- **Direction** is the pairing's `direction` in `sync.json`: `"to-sandbox"` (Mutagen's `one-way-safe`, this device as
|
|
103
|
+
alpha) or `"both"` (`two-way-safe`, as every workspace pairing). Absent, as on every project paired before it existed,
|
|
104
|
+
means `"to-sandbox"`, and so does a value this build has no word for; it means nothing on a workspace pairing
|
|
105
|
+
([`sync/config.ts`](src/sync/config.ts) `projectDirection`). An older agent keeps the field through every write but a
|
|
106
|
+
`setup` (which resets it, with the pairing's other switches), and keeps the copy-first session it finds, since it never
|
|
107
|
+
compared sync modes. `sync direction` rewrites the field; the watcher sees the new mode on its next tick and recreates
|
|
108
|
+
the session (`sessionMatchesSpec` compares the live session's `mode`).
|
|
109
|
+
- **Replacements** into copy-first happen at once, conflicts or not, with no flush and no residue sweep: a last flush
|
|
110
|
+
of a two-way session would carry the sandbox's latest changes into the folder, and the new session never writes here.
|
|
111
|
+
Out of copy-first too: a one-way session's conflicts are the agent's kept edits, which differ whoever holds them. This
|
|
112
|
+
is how every existing project becomes copy-first on its first start of this build.
|
|
113
|
+
|
|
114
|
+
**What one-way-safe does**, measured with Mutagen 0.18.1 over ssh against an sshd whose `/work` was a scratch folder,
|
|
115
|
+
driving this agent's own session code and CLI (alpha is this device, beta the sandbox):
|
|
116
|
+
|
|
117
|
+
| The sandbox (an agent)… | Mutagen one-way-safe |
|
|
118
|
+
|---|---|
|
|
119
|
+
| edits a file this folder has | keeps the sandbox's version and reports it as a conflict; this folder is untouched |
|
|
120
|
+
| creates a file | keeps it in the sandbox, no conflict; nothing reaches this folder |
|
|
121
|
+
| deletes a file or a folder | puts it back from this folder on the next cycle |
|
|
122
|
+
| runs `rm -rf /work/<name>/*`, or removes `/work/<name>` | refills the sandbox's copy from this folder; this folder is untouched |
|
|
123
|
+
|
|
124
|
+
| This device… | Mutagen one-way-safe |
|
|
125
|
+
|---|---|
|
|
126
|
+
| edits, creates or deletes a file | carries it to the sandbox, except over a file the sandbox changed, which is kept |
|
|
127
|
+
| deletes a file the sandbox changed | the sandbox keeps its version, and the conflict clears |
|
|
128
|
+
|
|
129
|
+
A fresh session over two copies that already differ (what any replacement starts from) deletes nothing on either side.
|
|
130
|
+
One-way-safe copies what only this folder has into the sandbox and keeps every sandbox file that differs, as a conflict.
|
|
131
|
+
Two-way-safe also copies what only the sandbox has into this folder, and reports what differs on both as a conflict.
|
|
132
|
+
`mutagen sync list --template '{{json .}}'` prints the mode as a top-level `mode`, absent on a session created without
|
|
133
|
+
`--sync-mode`, which Mutagen runs two-way-safe.
|
|
134
|
+
|
|
135
|
+
**The commands**, all under `intentic-machine sync`, name the project by `--dir <its folder>` (links resolved, case
|
|
136
|
+
folded where the platform folds it). With `--json` each prints exactly one JSON object on stdout, and on failure
|
|
137
|
+
`{ "ok": false, "error": "<sentence>" }` with exit code 1. The desktop app parses these, so fields are only ever added.
|
|
138
|
+
|
|
139
|
+
| Command | Success output |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `sync changes` | `{ "ok": true, "pairing": "<id>", "direction": "to-sandbox"\|"both", "changes": [{ "path", "kind": "added"\|"modified"\|"deleted", "size"?, "conflict"?: true }], "truncated"?: true }` |
|
|
142
|
+
| `sync bring-back [--path <p>]... [--paths-file <file>]` | `{ "ok": true, "point": "<id>", "applied": [{ "path", "kind" }], "skipped": [{ "path", "reason" }] }` |
|
|
143
|
+
| `sync restore-points` | `{ "ok": true, "points": [{ "id", "createdAt", "entries": n }] }` |
|
|
144
|
+
| `sync restore --point <id>` | `{ "ok": true, "restored": n, "skipped": [{ "path", "reason" }] }` |
|
|
145
|
+
| `sync direction <to-sandbox\|both>` | `{ "ok": true, "direction": "…" }` |
|
|
146
|
+
|
|
147
|
+
- **`sync changes`** lists what the sandbox did, relative paths with `/`, sorted, the first 5,000 (`truncated` when
|
|
148
|
+
there were more): `added` exists only in the sandbox's copy, `modified` on both with different content (`size` is the
|
|
149
|
+
sandbox copy's), `deleted` was removed there. The sandbox is listed by ONE command over the pairing's ssh alias, a
|
|
150
|
+
node program that walks `/work/<name>` and prints path, size and sha256 NUL-separated, so any name survives. This
|
|
151
|
+
device is walked the same way, reading a file only where its size matches the sandbox's, through a hash cache keyed
|
|
152
|
+
by path, size and times in `~/.intentic/machine/hashes/<pairing>.json`. Both walks prune by the pairing's ignore list
|
|
153
|
+
read as Mutagen reads it: a name, `*` within it, at any depth (or at the root with a leading `/`), taking a matched
|
|
154
|
+
folder's contents along; any other spelling is refused rather than approximated. Mutagen's `.mutagen-temporary-*`
|
|
155
|
+
scratch files are left out too, and so are links and anything else that is not a regular file, on either side.
|
|
156
|
+
- **Whose change it is, and never over a newer edit.** The same cache file records each path's content when both
|
|
157
|
+
copies were last seen equal. A difference the sandbox did not move away from (an edit made here, still on its way) is
|
|
158
|
+
not listed at all. A file only this device holds is offered as `deleted` only when that record shows the sandbox had
|
|
159
|
+
exactly this copy. A `modified` file is written over here only when this device's copy is still what the two last
|
|
160
|
+
agreed on, which only a session that was running and whose flush just finished a whole cycle can show. Mutagen's own
|
|
161
|
+
record says so for the files it reports in conflict (ten at most, each with SHA-1 digests of what the two last agreed
|
|
162
|
+
on and of this device's copy, the latter checked against the file here now); the listing record says so for the rest.
|
|
163
|
+
Anything else is listed with `conflict: true` and skipped by bring-back with its reason, even when named by `--path`:
|
|
164
|
+
both copies moved (a record gone stale while the sync was paused, say, with the owner's own older version in the
|
|
165
|
+
sandbox), no record of the two ever agreeing on it, or a session that was paused, absent, or whose flush did not
|
|
166
|
+
finish. Since one-way-safe puts an agent's deletions back, `deleted` shows up mainly while the session is paused, and
|
|
167
|
+
a rename in the sandbox comes back as an addition (the old name is put back there). The record is written only by
|
|
168
|
+
whoever holds the folder's lock, so a listing beside a running bring-back never undoes what that one recorded.
|
|
169
|
+
- **`sync bring-back`** runs with the session paused (after a flush) if it was running, and leaves one somebody paused
|
|
170
|
+
as it is. It lists both sides and fetches the `added` and `modified` files in ONE ssh stream into a private staging
|
|
171
|
+
folder, each checked against the listing's sha256 (a file that changed since is skipped with the reason). Then it
|
|
172
|
+
writes the restore point, and only then touches the folder: each file renamed into place from a copy beside it, only
|
|
173
|
+
where the folder still holds what the point kept of it. `deleted` files are removed with the folders they leave
|
|
174
|
+
empty. `--path` takes a file or a folder, repeatable; `--paths-file` names a UTF-8 file holding a JSON array of such
|
|
175
|
+
paths (a Windows command line holds 32,767 characters, fewer than a long selection), taken together with any
|
|
176
|
+
`--path`. An unreadable file, one that is not such an array, or an empty one (which would otherwise mean every change)
|
|
177
|
+
is refused before anything is listed. A new file gets the sandbox copy's executable bit. Nothing is written through a
|
|
178
|
+
link: every folder on the way is checked.
|
|
179
|
+
- **Why the session pushes nothing stale back.** Paused, it runs no cycle between the listing, the fetch and the writes,
|
|
180
|
+
and on resume it rescans both sides. What was written here is byte for byte the sandbox's, so both sides moved from
|
|
181
|
+
their last agreement to the same content: Mutagen records that and transfers nothing. A sandbox file that changed
|
|
182
|
+
again meanwhile is a sandbox modification one-way-safe keeps, as a conflict. The e2e run checked all of it: no
|
|
183
|
+
conflicts after resume, the sandbox still holding the agent's content, and a later edit here carried over as usual.
|
|
184
|
+
- **Restore points** live in `~/.intentic/machine/restore/<pairing>/<id>/`, the id being the creation time in ISO 8601
|
|
185
|
+
basic format (`20260928T213000.123Z`, a folder name on every system). Each holds `manifest.json`, which is
|
|
186
|
+
`{ id, createdAt, dir, entries: [{ path, kind, backedUp, applied, backup?, mode? }] }` (`applied` is the sha256
|
|
187
|
+
bring-back left, null for a deletion), and `files/<path>`, a copy of every file bring-back overwrote or deleted. Only
|
|
188
|
+
what was actually written stays in the manifest. All of it is on the disk before the first write here: each copy is
|
|
189
|
+
flushed as it is made, the manifest by a durable write, then every folder of the point up to `restore/<pairing>`, so a
|
|
190
|
+
crash right after a bring-back never finds the folder rewritten and the copies empty. Files put in the folder are
|
|
191
|
+
flushed before the rename that places them.
|
|
192
|
+
- **Retention**, after each bring-back and under its lock: a pairing keeps its newest 20 points that hold files, plus
|
|
193
|
+
every such point younger than 30 days. A point that holds nothing (a bring-back that wrote nothing, or one cut off
|
|
194
|
+
before its manifest) never counts toward the 20, is never listed, and goes at the next bring-back. Until then it is
|
|
195
|
+
the `point` that bring-back answered with, so that answer always names a real point, as the desktop app expects.
|
|
196
|
+
- **`sync restore --point <id>`** puts each backed-up file back and removes each file bring-back added, where the
|
|
197
|
+
folder still holds exactly what bring-back left (by sha256). Anything else is skipped and reported, one already put
|
|
198
|
+
back included. Copy-first then carries the restored files to the sandbox, as it does any edit here, so the agent's
|
|
199
|
+
versions they replace are gone from there too.
|
|
200
|
+
- One bring-back or restore runs per folder at a time (`restore/<pairing>/.operation.pid`, a pid of this boot, checked
|
|
201
|
+
alive). A pause an operation made and never lifted (the process killed in between) is recorded in
|
|
202
|
+
`restore/<pairing>/.paused`, and the next command about that folder resumes the session.
|
|
203
|
+
|
|
74
204
|
### Upgrades that can be undone
|
|
75
205
|
|
|
76
206
|
- **A swap is never cut short by this agent.** `ic` runs in a process group of its own on POSIX, keeps its pipes, and
|
|
77
|
-
is never killed when the link or request that asked for it goes away.
|
|
207
|
+
is never killed when the link or request that asked for it goes away. The one run it ever stops is the keeper's
|
|
208
|
+
`sandbox fix` past its deadline (below), which is not a swap. Every restart of the agent (the auto-upgrade
|
|
78
209
|
tick, `upgrade`, `run`, the browser's Update and Restart) waits while any channel record in this environment's ic
|
|
79
210
|
home (`INTENTIC_HOME`, else `~/.intentic`) says `swap_phase=cutover` with `swap_at` in the last 30 minutes, or while
|
|
80
211
|
this process runs a flow that moves a container ([`device/sandbox-rounds/swap-records.ts`](src/device/sandbox-rounds/swap-records.ts)); the tick
|
|
@@ -111,8 +242,52 @@ flowchart LR
|
|
|
111
242
|
([`tools/command-ledger.ts`](src/device/tools/command-ledger.ts)). The login entries of the two agents this one
|
|
112
243
|
replaced on 2026-08-29 (`intentic-host`, the sync mirror) are removed once, at start.
|
|
113
244
|
- `intentic-machine sandbox <verb> [slug]` passes `list`, `start`, `stop`, `restart`, `update`, `rollback [--to]`,
|
|
114
|
-
`versions`, `logs`, `doctor`, `watch`, `backup
|
|
115
|
-
a sandbox can be looked at and repaired from here
|
|
245
|
+
`versions`, `logs`, `doctor`, `watch`, `backup`, `backups` and `fix [--code] [--auto] [--yes] [--accept] [--json]
|
|
246
|
+
[--source]` straight to ic, in this terminal, with ic's exit code: a sandbox can be looked at and repaired from here
|
|
247
|
+
when no browser reaches it, and `fix` asks here for the yes the keeper never gives.
|
|
248
|
+
|
|
249
|
+
### The keeper
|
|
250
|
+
|
|
251
|
+
When a sandbox on this machine stops answering (Docker Desktop not started after a reboot, a stopped container, a
|
|
252
|
+
daemon whose registration gave up, a full disk), the agent heals what is safe to heal by itself and reports the rest
|
|
253
|
+
([`device/sandbox-rounds/keeper.ts`](src/device/sandbox-rounds/keeper.ts)). ic does every fix; the keeper keeps the
|
|
254
|
+
clock.
|
|
255
|
+
|
|
256
|
+
- **When.** `ic sandbox fix --auto --json --source agent` over every sandbox half a minute after the agent starts (the
|
|
257
|
+
logon case: Docker Desktop is off by default after a reboot) and every five minutes, and `ic sandbox fix <slug> …` as
|
|
258
|
+
soon as the agent's link to a sandbox that runs on this machine has failed for a minute. A link's sandbox runs here
|
|
259
|
+
when this environment's ic has a record of it or listed it (by its hostname's first label or the id in it, as sync's
|
|
260
|
+
swap pause maps them), or when the agent has reached it over loopback.
|
|
261
|
+
- **What ic does by itself** under `--auto`: starts Docker Desktop and waits for it, starts a sandbox its owner did not
|
|
262
|
+
stop on purpose, restarts one whose registration gave up, tidies when the disk is low. It posts its report to the
|
|
263
|
+
platform itself; nothing comes back down to the device (there is no platform-to-device relay).
|
|
264
|
+
- **What the keeper never does**: apply a fix that needs a yes (each is logged with `intentic-machine sandbox fix
|
|
265
|
+
<slug>`, which asks in a terminal, as the desktop app's buttons and the recovery panel's command do), run two fixes at
|
|
266
|
+
once, run while the probation watch is running ic, fix a sandbox a swap is moving or one a flow of this agent holds,
|
|
267
|
+
or start the sweep while any flow runs. Each run holds the sandboxes it may touch as a flow that moves a container,
|
|
268
|
+
so the other rounds leave them alone and the agent does not restart under it.
|
|
269
|
+
- **Bounded.** A run is stopped after eight minutes (starting Docker Desktop alone can take five), with its process
|
|
270
|
+
group on POSIX and its process tree on Windows.
|
|
271
|
+
- **Waiting.** A sandbox whose run left something (needs-you, failed, no verdict) waits 3 minutes, then 6, 12, 24 and
|
|
272
|
+
30 at most, and the wait ends when its link comes back. One ic found healthy or fixed while its link stays down is
|
|
273
|
+
asked about again after five minutes, not every ten seconds. The sweep's own cadence stretches on the same ladder
|
|
274
|
+
(never under five minutes) while a sweep leaves something. An ic that cannot fix (one from before `sandbox fix`,
|
|
275
|
+
which clap refuses with no JSON, or no ic at all) is said once and asked again on the same ladder.
|
|
276
|
+
- **The log** (`~/.intentic/machine/machine.log`, like every round): what ic is doing as it does it, and each
|
|
277
|
+
sandbox's verdict when it changes (a standing `healthy` or `needs-you` is said once per stretch; `fixed` always).
|
|
278
|
+
- **Where.** Every environment runs its own keeper, since `ic sandbox fix` knows only the sandboxes its own ic keeps
|
|
279
|
+
records of; a WSL distro's shares the Windows side's Docker Desktop.
|
|
280
|
+
- **The switch** is this environment's `sandboxKeeper` in `machine.json` (absent means on), set by
|
|
281
|
+
`intentic-machine sandbox keeper on|off` and read by `keeper status`. It is re-read every round.
|
|
282
|
+
- **It keeps the agent resident.** An agent with no link, no pairing and no distro to serve used to take its login
|
|
283
|
+
entry away and exit, and then nothing started Docker Desktop after the next reboot. It now stays while the keeper is
|
|
284
|
+
on and this machine hosts a sandbox other than a runner: the ones `ic sandbox list --json` names when Docker answers,
|
|
285
|
+
else the ones ic keeps a record of (a removed sandbox's record lasts until `ic sandbox tidy` archives it, so the
|
|
286
|
+
listing wins whenever it answers). The resident asks at start and then every five minutes, and only while it has
|
|
287
|
+
nothing else to serve. `keeper off` lets it go; `intentic-machine uninstall` retires it whatever this machine hosts,
|
|
288
|
+
while `device uninstall` and `sync uninstall` leave it running for the sandboxes here and say so (2026-09-30:
|
|
289
|
+
retiring as before was rejected, since a machine whose last link was revoked kept its sandbox down after every
|
|
290
|
+
reboot).
|
|
116
291
|
|
|
117
292
|
## Key files
|
|
118
293
|
|
package/dist/commands.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAqGjF,eAAO,MAAM,QAAQ,kDAoBnB,CAAC"}
|
package/dist/commands.js
CHANGED
|
@@ -64,8 +64,8 @@ const uninstall = buildCommand({
|
|
|
64
64
|
parameters: {},
|
|
65
65
|
async func() {
|
|
66
66
|
const out = (message) => void this.process.stdout.write(`${message}\n`);
|
|
67
|
-
await syncUninstall(out);
|
|
68
|
-
await deviceUninstall(out);
|
|
67
|
+
await syncUninstall(out, undefined, { forGood: true });
|
|
68
|
+
await deviceUninstall(out, undefined, { forGood: true });
|
|
69
69
|
const still = await readResident();
|
|
70
70
|
out(still === undefined
|
|
71
71
|
? "Nothing intentic stays resident here."
|
package/dist/commands.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type Log } from "@intentic/local-agent";
|
|
2
2
|
import { type CommandContext } from "@stricli/core";
|
|
3
|
-
export declare const deviceUninstall: (out: Log, sandbox?: string
|
|
3
|
+
export declare const deviceUninstall: (out: Log, sandbox?: string, { forGood }?: {
|
|
4
|
+
readonly forGood?: boolean;
|
|
5
|
+
}) => Promise<void>;
|
|
4
6
|
export declare const dropUnreachableLinks: (out: Log) => Promise<void>;
|
|
5
7
|
export declare const deviceCommands: {
|
|
6
8
|
setup: import("@stricli/core").Command<CommandContext>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/device/commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,GAAG,EAA0B,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAsHlE,eAAO,MAAM,eAAe,QAAe,GAAG,YAAY,MAAM,
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/device/commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,GAAG,EAA0B,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAsHlE,eAAO,MAAM,eAAe,QAAe,GAAG,YAAY,MAAM,gBAAuB;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,KAAQ,OAAO,CAAC,IAAI,CAyBxI,CAAC;AAgBF,eAAO,MAAM,oBAAoB,QAAe,GAAG,KAAG,OAAO,CAAC,IAAI,CA0BjE,CAAC;AAEF,eAAO,MAAM,cAAc;;;;CAAgE,CAAC"}
|
package/dist/device/commands.js
CHANGED
|
@@ -79,7 +79,7 @@ const uninstall = buildCommand({
|
|
|
79
79
|
await deviceUninstall(out, flags.sandbox);
|
|
80
80
|
},
|
|
81
81
|
});
|
|
82
|
-
export const deviceUninstall = async (out, sandbox) => {
|
|
82
|
+
export const deviceUninstall = async (out, sandbox, { forGood = false } = {}) => {
|
|
83
83
|
const only = sandbox === undefined || sandbox === "" ? undefined : sandbox;
|
|
84
84
|
const dropped = await removeLinks(only);
|
|
85
85
|
const left = await readLinks();
|
|
@@ -90,7 +90,7 @@ export const deviceUninstall = async (out, sandbox) => {
|
|
|
90
90
|
if (left.length === 0) {
|
|
91
91
|
await rm(configPath, { force: true });
|
|
92
92
|
}
|
|
93
|
-
await ensureResident(out);
|
|
93
|
+
await ensureResident(out, { forGood });
|
|
94
94
|
if (left.length > 0) {
|
|
95
95
|
out(`Disconnected from ${dropped.map((link) => link.sandboxUrl).join(", ")}. Still connected to ${left.length} sandbox${left.length === 1 ? "" : "es"}.`);
|
|
96
96
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/device/commands.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/device/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ export interface Dial {
|
|
|
7
7
|
readonly resolveBase: (sandboxUrl: string) => Promise<DaemonBase>;
|
|
8
8
|
readonly socket: (url: string) => WebSocket;
|
|
9
9
|
}
|
|
10
|
+
export declare const reachedOverLoopback: ReadonlySet<string>;
|
|
10
11
|
declare const forgetLink: (sandboxUrl: string) => Promise<void>;
|
|
11
12
|
export declare const connect: (config: HostLink, version: string, log: Log, dial?: Dial, forget?: typeof forgetLink, indicator?: Indicator) => PeerLink;
|
|
12
13
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/device/connection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAkD,KAAK,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAErH,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,KAAK,QAAQ,EAA+B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,gBAAgB,CAAC;AASlE,MAAM,WAAW,IAAI;IACjB,QAAQ,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;CAC/C;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/device/connection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAkD,KAAK,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAErH,OAAO,EAAE,KAAK,UAAU,EAAqB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,KAAK,QAAQ,EAA+B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,gBAAgB,CAAC;AASlE,MAAM,WAAW,IAAI;IACjB,QAAQ,CAAC,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;CAC/C;AAQD,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAgB,CAAC;AAGrE,QAAA,MAAM,UAAU,eAAsB,MAAM,KAAG,OAAO,CAAC,IAAI,CAAyC,CAAC;AAErG,eAAO,MAAM,OAAO,WACR,QAAQ,WACP,MAAM,OACV,GAAG,SACF,IAAI,0CAEC,SAAS,KACrB,QA+DF,CAAC"}
|
|
@@ -8,6 +8,8 @@ import { rememberScopes, removeLinks } from "./config.js";
|
|
|
8
8
|
import { machineIndicator } from "./indicator.js";
|
|
9
9
|
import { createHostRouter } from "./router.js";
|
|
10
10
|
const realDial = { resolveBase: resolveDaemonBase, socket: (url) => new WebSocket(url) };
|
|
11
|
+
const loopbackUrls = new Set();
|
|
12
|
+
export const reachedOverLoopback = loopbackUrls;
|
|
11
13
|
const forgetLink = async (sandboxUrl) => void (await removeLinks(sandboxUrl));
|
|
12
14
|
export const connect = (config, version, log, dial = realDial, forget = forgetLink, indicator = machineIndicator()) => {
|
|
13
15
|
const linkLog = (message) => log(`${config.sandboxUrl}: ${message}`);
|
|
@@ -28,6 +30,9 @@ export const connect = (config, version, log, dial = realDial, forget = forgetLi
|
|
|
28
30
|
if (signal.aborted) {
|
|
29
31
|
return undefined;
|
|
30
32
|
}
|
|
33
|
+
if (local) {
|
|
34
|
+
loopbackUrls.add(config.sandboxUrl);
|
|
35
|
+
}
|
|
31
36
|
return {
|
|
32
37
|
socket: dial.socket(hostConnectUrl(base)),
|
|
33
38
|
said: `connected${local ? ` over loopback (${base})` : ""} as "${config.id}"`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/device/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAqB,MAAM,4BAA4B,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,EAAiB,MAAM,sCAAsC,CAAC;AACrH,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAmB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAiB,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAkB,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAa/C,MAAM,QAAQ,GAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/device/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/device/grant.d.ts
CHANGED
|
@@ -73,6 +73,7 @@ export declare const tolerantDeviceContract: {
|
|
|
73
73
|
sync: "sync";
|
|
74
74
|
}>;
|
|
75
75
|
localDir: z.ZodOptional<z.ZodString>;
|
|
76
|
+
remoteDir: z.ZodOptional<z.ZodString>;
|
|
76
77
|
mirroring: z.ZodOptional<z.ZodEnum<{
|
|
77
78
|
off: "off";
|
|
78
79
|
on: "on";
|
|
@@ -242,6 +243,43 @@ export declare const tolerantDeviceContract: {
|
|
|
242
243
|
message: z.ZodString;
|
|
243
244
|
}, z.core.$strip>], "kind">;
|
|
244
245
|
}, Record<never, never>, Record<never, never>>;
|
|
246
|
+
catchLoopback: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
|
|
247
|
+
id: z.ZodString;
|
|
248
|
+
host: z.ZodEnum<{
|
|
249
|
+
"127.0.0.1": "127.0.0.1";
|
|
250
|
+
localhost: "localhost";
|
|
251
|
+
}>;
|
|
252
|
+
port: z.ZodNumber;
|
|
253
|
+
path: z.ZodString;
|
|
254
|
+
expiresAt: z.ZodNumber;
|
|
255
|
+
title: z.ZodString;
|
|
256
|
+
}, z.core.$strict>, import("@orpc/contract").Schema<AsyncIteratorObject<{
|
|
257
|
+
type: "listening";
|
|
258
|
+
} | {
|
|
259
|
+
type: "busy";
|
|
260
|
+
reason: string;
|
|
261
|
+
} | {
|
|
262
|
+
type: "landed";
|
|
263
|
+
url: string;
|
|
264
|
+
}, unknown, void>, import("@orpc/contract").AsyncIteratorClass<{
|
|
265
|
+
type: "listening";
|
|
266
|
+
} | {
|
|
267
|
+
type: "busy";
|
|
268
|
+
reason: string;
|
|
269
|
+
} | {
|
|
270
|
+
type: "landed";
|
|
271
|
+
url: string;
|
|
272
|
+
}, unknown, void>> & {
|
|
273
|
+
[x: symbol]: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
274
|
+
type: z.ZodLiteral<"listening">;
|
|
275
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
276
|
+
type: z.ZodLiteral<"busy">;
|
|
277
|
+
reason: z.ZodString;
|
|
278
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
279
|
+
type: z.ZodLiteral<"landed">;
|
|
280
|
+
url: z.ZodString;
|
|
281
|
+
}, z.core.$strip>], "type">;
|
|
282
|
+
}, Record<never, never>, Record<never, never>>;
|
|
245
283
|
setScopes: {
|
|
246
284
|
"~orpc": {
|
|
247
285
|
meta: Record<never, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../src/device/grant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAkB,MAAM,4BAA4B,CAAC;AACnG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAyE,CAAC;AACvG,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAM1D,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,eAAO,MAAM,SAAS,UAAW,UAAU,KAAG,KAK5C,CAAC;AAIH,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"grant.d.ts","sourceRoot":"","sources":["../../src/device/grant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAkB,MAAM,4BAA4B,CAAC;AACnG,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAyE,CAAC;AACvG,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAM1D,MAAM,WAAW,KAAK;IAClB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,eAAO,MAAM,SAAS,UAAW,UAAU,KAAG,KAK5C,CAAC;AAIH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGlC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { LoopbackCatch, LoopbackCatchEvent } from "@intentic/sandbox-contract";
|
|
2
|
+
export declare function catchLoopback(spec: LoopbackCatch, signal: AbortSignal | undefined, log: (message: string) => void): AsyncGenerator<LoopbackCatchEvent>;
|
|
3
|
+
//# sourceMappingURL=loopback-catch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopback-catch.d.ts","sourceRoot":"","sources":["../../src/device/loopback-catch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AA6EpF,wBAAuB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,cAAc,CAAC,kBAAkB,CAAC,CAqD7J"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
const LONGEST_WATCH_MS = 30 * 60_000;
|
|
3
|
+
const escapeHtml = (text) => text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
4
|
+
const landedPage = (title) => `<!doctype html>
|
|
5
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<title>Signed in to ${escapeHtml(title)}</title>
|
|
7
|
+
<style>body{font:16px/1.5 system-ui,sans-serif;margin:0;min-height:100vh;display:grid;place-items:center;background:#0f1115;color:#e6e6e6}main{max-width:28rem;padding:2rem;text-align:center}h1{font-size:1.25rem;margin:0 0 .5rem}p{margin:0;color:#a0a4ab}</style>
|
|
8
|
+
</head><body><main><h1>Signed in to ${escapeHtml(title)}</h1><p>Intentic is finishing the connection. You can close this tab and go back to it.</p></main></body></html>`;
|
|
9
|
+
const listen = (server, port, address) => new Promise((resolve) => {
|
|
10
|
+
const onError = (error) => resolve({ ok: false, code: error.code, message: error.message });
|
|
11
|
+
server.once("error", onError);
|
|
12
|
+
server.listen({ port, host: address, exclusive: true }, () => {
|
|
13
|
+
server.off("error", onError);
|
|
14
|
+
resolve({ ok: true });
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
const bind = async (spec, onRequest) => {
|
|
18
|
+
const addresses = spec.host === "localhost" ? ["127.0.0.1", "::1"] : ["127.0.0.1"];
|
|
19
|
+
const servers = [];
|
|
20
|
+
const sockets = new Set();
|
|
21
|
+
const close = async () => {
|
|
22
|
+
for (const socket of sockets) {
|
|
23
|
+
socket.destroy();
|
|
24
|
+
}
|
|
25
|
+
await Promise.all(servers.map((server) => new Promise((resolve) => server.close(() => resolve()))));
|
|
26
|
+
};
|
|
27
|
+
for (const [index, address] of addresses.entries()) {
|
|
28
|
+
const server = createServer(onRequest);
|
|
29
|
+
server.on("connection", (socket) => {
|
|
30
|
+
sockets.add(socket);
|
|
31
|
+
socket.on("close", () => sockets.delete(socket));
|
|
32
|
+
});
|
|
33
|
+
const bound = await listen(server, spec.port, address);
|
|
34
|
+
if (bound.ok) {
|
|
35
|
+
servers.push(server);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (index === 0) {
|
|
39
|
+
await close();
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
reason: bound.code === "EADDRINUSE" ? `port ${spec.port} is already taken on this machine` : `could not listen on ${address}:${spec.port}: ${bound.message}`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { ok: true, close };
|
|
47
|
+
};
|
|
48
|
+
const landingUrl = (spec, request) => new URL(request.url ?? "/", `http://${spec.host}:${spec.port}`);
|
|
49
|
+
export async function* catchLoopback(spec, signal, log) {
|
|
50
|
+
const queue = [];
|
|
51
|
+
let wake;
|
|
52
|
+
let over = false;
|
|
53
|
+
const nudge = () => {
|
|
54
|
+
const resume = wake;
|
|
55
|
+
wake = undefined;
|
|
56
|
+
resume?.();
|
|
57
|
+
};
|
|
58
|
+
const end = () => {
|
|
59
|
+
over = true;
|
|
60
|
+
nudge();
|
|
61
|
+
};
|
|
62
|
+
const bound = await bind(spec, (request, response) => {
|
|
63
|
+
const url = landingUrl(spec, request);
|
|
64
|
+
if (request.method !== "GET" || url.pathname !== spec.path) {
|
|
65
|
+
response.writeHead(404, { "content-type": "text/plain; charset=utf-8" }).end("Not found");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
queue.push({ type: "landed", url: url.toString() });
|
|
69
|
+
nudge();
|
|
70
|
+
response
|
|
71
|
+
.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", "referrer-policy": "no-referrer" })
|
|
72
|
+
.end(landedPage(spec.title));
|
|
73
|
+
});
|
|
74
|
+
if (!bound.ok) {
|
|
75
|
+
log(`could not watch for the ${spec.title} sign-in: ${bound.reason}`);
|
|
76
|
+
yield { type: "busy", reason: bound.reason };
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
log(`watching ${spec.host}:${spec.port}${spec.path} for the ${spec.title} sign-in`);
|
|
80
|
+
const deadline = setTimeout(end, Math.max(0, Math.min(spec.expiresAt - Date.now(), LONGEST_WATCH_MS)));
|
|
81
|
+
signal?.addEventListener("abort", end, { once: true });
|
|
82
|
+
try {
|
|
83
|
+
yield { type: "listening" };
|
|
84
|
+
for (;;) {
|
|
85
|
+
const next = queue.shift();
|
|
86
|
+
if (next !== undefined) {
|
|
87
|
+
yield next;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (over || signal?.aborted === true) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
await new Promise((resolve) => (wake = resolve));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
clearTimeout(deadline);
|
|
98
|
+
signal?.removeEventListener("abort", end);
|
|
99
|
+
await bound.close();
|
|
100
|
+
log(`stopped watching ${spec.host}:${spec.port} for the ${spec.title} sign-in`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=loopback-catch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopback-catch.js","sourceRoot":"","sources":["../../src/device/loopback-catch.ts"],"names":[],"mappings":"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"}
|
package/dist/device/mcp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/device/mcp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/device/mcp.ts"],"names":[],"mappings":"AAsbA,eAAO,MAAM,gBAAgB;;;;;;;;kDAQ3B,CAAC"}
|
package/dist/device/mcp.js
CHANGED
|
@@ -11,7 +11,7 @@ import { editTextFile, listDirectory, readTextFile, trashFile, writeTextFile } f
|
|
|
11
11
|
import { focusWindow, listWindows, openTarget, readClipboard, writeClipboard } from "./tools/apps.js";
|
|
12
12
|
import { clickElement, fillElement, listTabs, openPage, pressKey, readPage, selectTab, snapshotPage } from "./tools/browser.js";
|
|
13
13
|
import { act, describeAction, settle } from "./tools/device.js";
|
|
14
|
-
import { DEFAULT_LOG_LINES, forgetShape, listSandboxes, manageSandbox, MAX_LOG_LINES, removeSandbox, SandboxOpSchema, SandboxSwapSchema, sandboxLogs, shapeSandbox, swapSandbox, } from "./tools/sandboxes.js";
|
|
14
|
+
import { DEFAULT_LOG_LINES, diagnoseSandbox, forgetShape, listSandboxes, manageSandbox, MAX_LOG_LINES, removeSandbox, SandboxOpSchema, SandboxSwapSchema, sandboxLogs, shapeSandbox, swapSandbox, } from "./tools/sandboxes.js";
|
|
15
15
|
import { DEFAULT_TIMEOUT_MS, describeResult, MAX_TIMEOUT_MS, runCommand } from "./tools/shell.js";
|
|
16
16
|
import { MACHINE_VERSION } from "../version.js";
|
|
17
17
|
const NO_ARGS = z.object({});
|
|
@@ -326,6 +326,13 @@ const TOOLS = [
|
|
|
326
326
|
}),
|
|
327
327
|
run: async ({ slug, lines }, scopes) => textResult(await sandboxLogs(slug, lines, scopes)),
|
|
328
328
|
}),
|
|
329
|
+
tool({
|
|
330
|
+
name: "diagnose_sandbox",
|
|
331
|
+
description: "Check every link of one Intentic sandbox's reachability chain on this device (Docker, its container, its daemon, its registration with the platform, the network, the tunnel) and say what is broken and what fixes it, as JSON from the device's `ic sandbox doctor`. Changes nothing, and answers while Docker is down, when list_sandboxes cannot: how you find out why a sandbox on this device cannot be reached. Requires 'Run commands' or 'Manage sandboxes on this device'.",
|
|
332
|
+
effect: "read",
|
|
333
|
+
input: z.object({ slug: required.describe("The sandbox's slug, from list_sandboxes, or the first label of its address.") }),
|
|
334
|
+
run: async ({ slug }, scopes) => textResult(await diagnoseSandbox(slug, scopes)),
|
|
335
|
+
}),
|
|
329
336
|
];
|
|
330
337
|
const auditDetail = (name, args) => {
|
|
331
338
|
const redact = (name === "device" && args["action"] === "type") || (name === "clipboard" && args["action"] === "write") || name === "browser_fill";
|