@corenel/sidecar 0.3.0 → 0.3.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.
- package/CHANGELOG.md +231 -137
- package/dist/cli.js +357 -73
- package/package.json +13 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,137 +1,231 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 0.3.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Everything
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
###
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
now
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
and
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
###
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
- `--
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.2
|
|
4
|
+
|
|
5
|
+
Sessions stop being something you can only list. This release gives the sandbox
|
|
6
|
+
a full lifecycle from the command line, and the verbs are the port's own --
|
|
7
|
+
create/destroy, not add/remove: you add an entry to a list, you create and
|
|
8
|
+
destroy a thing that boots and holds memory.
|
|
9
|
+
|
|
10
|
+
Everything goes through the SAME backend the daemon uses. Two ways to make a
|
|
11
|
+
sandbox would stamp labels two ways and drift on limits.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- Session lifecycle: `corenel sessions create [--root <dir>]`, `run <id>
|
|
15
|
+
"<prompt>"`, and `pause|resume|destroy <id>`. `corenel run --session <id>`
|
|
16
|
+
forwards to the same place. `stop` is deliberately absent -- the port has
|
|
17
|
+
pause (stop admitting work, bounded drain, and it reports whether it drained)
|
|
18
|
+
and destroy, and a third word over two real concepts is a translation nobody
|
|
19
|
+
asked for.
|
|
20
|
+
- `exec` takes an optional env, threaded to `msb exec -e`. Without it the CLI
|
|
21
|
+
inside the guest answers "not signed in" -- the image ships no token and
|
|
22
|
+
create injects none -- so the sandbox was a box nothing useful could happen
|
|
23
|
+
in. It carries the HOST's identity: a session isolates the filesystem and the
|
|
24
|
+
process, not the wallet.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
Running against a real hypervisor found five defects that reading the code did
|
|
28
|
+
not:
|
|
29
|
+
|
|
30
|
+
- `create` always allocated `sess_1`. The id counter lives in the backend and
|
|
31
|
+
starts at zero, so the second create on a machine collided with the first.
|
|
32
|
+
Adoption is what advances it past what already exists -- the daemon does this
|
|
33
|
+
at boot and a one-shot command needs it for the same reason. The same fix is
|
|
34
|
+
what made `run` work at all.
|
|
35
|
+
- `sessions create --root X` silently used the CWD. The dispatcher stripped
|
|
36
|
+
flags before the subcommand could read them, so the value was dropped without
|
|
37
|
+
a word. The whole argv is passed through now, and the verbs are the non-flag
|
|
38
|
+
words.
|
|
39
|
+
- A created session reported `created 1787430794235` -- the label stores epoch
|
|
40
|
+
millis and nothing rendered it.
|
|
41
|
+
- A STOPPED session vanished from the list: `msb inspect` returns no labels for
|
|
42
|
+
one, so there was nothing to read. It is recovered from the sandbox name,
|
|
43
|
+
which the backend reserves for exactly this.
|
|
44
|
+
- ...and was therefore unrecoverable, since resume and destroy both look it up
|
|
45
|
+
first. `adopt()` also refuses a session whose workdir label it cannot read, so
|
|
46
|
+
the backend declined too and destroy reported success having done nothing.
|
|
47
|
+
There is now a direct-to-sandbox path used only after the backend declines,
|
|
48
|
+
and destroy VERIFIES the session is gone instead of assuming.
|
|
49
|
+
|
|
50
|
+
Verified end to end against real microVMs: create -> list -> show -> pause ->
|
|
51
|
+
resume -> destroy, and a run reaching the guest's own CLI.
|
|
52
|
+
|
|
53
|
+
## 0.3.1
|
|
54
|
+
|
|
55
|
+
This package is Corenel's, and now says so in its defaults. 0.3.0 pointed its
|
|
56
|
+
gateway, and the app it opens, at the sibling product.
|
|
57
|
+
|
|
58
|
+
The direction is the fix: prompd.app is a CONSUMER of these APIs, so it names
|
|
59
|
+
its own origin (`--app-url https://prompd.app/studio`, `--endpoint <its own>`)
|
|
60
|
+
and corenel.ai is what you get without asking.
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
- `sessions` subcommand: `corenel-sidecar sessions [list | show <id>]`, also
|
|
64
|
+
reachable as `corenel sessions`. Read-only, and read from the SANDBOXES rather
|
|
65
|
+
than from a daemon -- a subcommand runs in a new process and cannot see a
|
|
66
|
+
running daemon's SessionManager, so anything derived from it would be a guess.
|
|
67
|
+
Asking msb gets the same answer the daemon gets when it adopts at boot, and it
|
|
68
|
+
works with nothing running.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
- `--app-url` defaults to `https://corenel.ai`, and the open URL no longer has
|
|
72
|
+
`/studio` appended to it. That is a prompd route; corenel serves its app at
|
|
73
|
+
`/`, so the old shape would have opened a page that does not exist and lost
|
|
74
|
+
the pairing fragment on the redirect. `--app-url` is now the app URL in full,
|
|
75
|
+
path included -- prompd pairs at `https://prompd.app/studio`.
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
- The daemon called `https://api.prompd.app` for every model run -- the sibling
|
|
79
|
+
product's gateway, with a token minted against this one. The default endpoint
|
|
80
|
+
is now `https://api.corenel.ai/api`.
|
|
81
|
+
- That default was also missing the `/api` prefix the gateway is mounted behind.
|
|
82
|
+
`setGatewayBase` appends `/v1`, so a bare origin composed
|
|
83
|
+
`https://host/v1/chat/completions` and 404'd -- surfacing as "the run failed",
|
|
84
|
+
nowhere near the flag responsible. A bare origin now has the prefix added, and
|
|
85
|
+
any endpoint carrying a path is left exactly as given.
|
|
86
|
+
- `--allow-lan` did not do what it says. It widened the CORS origin allowlist
|
|
87
|
+
while the socket stayed bound to `127.0.0.1`, so nothing on the network could
|
|
88
|
+
connect and the banner still printed a loopback URL. It now binds all
|
|
89
|
+
interfaces and serves `wss://` with the self-signed cert (which already
|
|
90
|
+
covered the LAN IPs for exactly this). Both halves defer to anything
|
|
91
|
+
explicit: `--host` keeps its address, a supplied `--tls-cert` is not replaced.
|
|
92
|
+
|
|
93
|
+
This is the only way LAN pairing can work from the product: the app is served
|
|
94
|
+
over https, and a browser on an https page refuses a `ws://` connection to a
|
|
95
|
+
LAN address.
|
|
96
|
+
|
|
97
|
+
## 0.3.0
|
|
98
|
+
|
|
99
|
+
The isolation release. 0.2.0 could expose a machine's files and shell to a
|
|
100
|
+
session and run crew agents unattended; it always did that work in its own
|
|
101
|
+
process, on the host, with whatever reach the host had. This release puts a
|
|
102
|
+
boundary around a run and lets an external coding agent be governed by it.
|
|
103
|
+
|
|
104
|
+
Everything is additive and off by default. A 0.2.0 setup behaves exactly as it
|
|
105
|
+
did unless you pass one of the new flags.
|
|
106
|
+
|
|
107
|
+
### Sessions in a sandbox
|
|
108
|
+
- `--isolation <none|microvm>` chooses how a session confines a run. `none` is
|
|
109
|
+
the old behaviour and stays the default; `microvm` boots a sandbox per session.
|
|
110
|
+
- `--msb <path>` locates the microsandbox binary, and `--guest-image <ref>` picks
|
|
111
|
+
what a session boots. Pin the image by digest for anything you snapshot -- a
|
|
112
|
+
floating tag means a restored snapshot is not the thing that was captured.
|
|
113
|
+
|
|
114
|
+
### Proxying an external agent
|
|
115
|
+
- `--acp <target>` runs an external coding agent (`claude-code`) under our
|
|
116
|
+
policy rather than beside it. Needs `--root`.
|
|
117
|
+
- `--acp-policy <standard|read-only|autonomous>` governs what the proxied agent
|
|
118
|
+
may do, and `--acp-auth <subscription|api-key|inherit>` selects the credential
|
|
119
|
+
it uses.
|
|
120
|
+
- `--agent <name>` names the crew agent an `acp-agent` session drives.
|
|
121
|
+
|
|
122
|
+
### Boundaries the operator sets
|
|
123
|
+
- `--clone-under <dir>` lets a session clone a repository, and nothing more. The
|
|
124
|
+
clone runs on the host with your own git credentials; they never enter the
|
|
125
|
+
session.
|
|
126
|
+
- `--keep-transcripts` PERMITS a run to keep its words rather than only its
|
|
127
|
+
metadata. It is a ceiling, not a switch: each run still has to ask, and no run
|
|
128
|
+
can ask past an operator who did not pass this.
|
|
129
|
+
- `--allow-add-under <dir>` lets a client add working directories beneath a
|
|
130
|
+
subtree during a session. This grants directory-name enumeration over that
|
|
131
|
+
subtree, and added roots last only until the sidecar exits.
|
|
132
|
+
|
|
133
|
+
### Fixed
|
|
134
|
+
- `hosts list` -- the spelling `--help` documents -- was rejected as an unknown
|
|
135
|
+
argument; only a bare `hosts` worked. Both now do.
|
|
136
|
+
|
|
137
|
+
### Naming
|
|
138
|
+
- The `corenel` binary this package briefly declared is gone; it collided with
|
|
139
|
+
`@corenel/cli`, which owns that name. This package installs `corenel-sidecar`,
|
|
140
|
+
and `corenel sidecar …` reaches the same program through the CLI. `--help`
|
|
141
|
+
now reports whichever name you invoked.
|
|
142
|
+
|
|
143
|
+
## 0.2.0
|
|
144
|
+
|
|
145
|
+
Ships `--help`, and moves onto the workspace's shared version line — every
|
|
146
|
+
`@corenel/*` package is now 0.2.0, so a compatible set is obvious at a glance.
|
|
147
|
+
|
|
148
|
+
- `--help` / `-h` print usage and exit 0. They were previously rejected as
|
|
149
|
+
unknown arguments, which printed a bare flag list and exited 1 — the first
|
|
150
|
+
thing anyone types against an unfamiliar binary. The text is generated from the
|
|
151
|
+
same table the parser validates against, so a flag cannot be added without
|
|
152
|
+
appearing in `--help`. This landed just after 0.1.6 was published, so it has
|
|
153
|
+
not been in a release until now.
|
|
154
|
+
|
|
155
|
+
No behaviour changes to the daemon, tunnels, or host sync. Upgrading from 0.1.6
|
|
156
|
+
is safe; everything in the 0.1.6 notes below still applies.
|
|
157
|
+
|
|
158
|
+
## 0.1.6
|
|
159
|
+
|
|
160
|
+
The daemon release. `@corenel/sidecar` could already expose a machine's files and
|
|
161
|
+
shell to a browser session; it can now also **run crew agents on its own** —
|
|
162
|
+
on a schedule, when files change, or when another run finishes — with budgets,
|
|
163
|
+
permissions and per-owner isolation enforced node-side.
|
|
164
|
+
|
|
165
|
+
Everything below is additive. An existing `pd sidecar` setup behaves as it did in
|
|
166
|
+
0.1.5 unless you pass `--daemon`.
|
|
167
|
+
|
|
168
|
+
### Daemon core
|
|
169
|
+
- `--daemon` starts an always-on core: an interruptible clock (sleep-until-next-wake,
|
|
170
|
+
wake signal, max-sleep cap) driving a trigger dispatcher over a shared runner.
|
|
171
|
+
- Node run executor built on `runAgent`, with session recording to disk.
|
|
172
|
+
- Per-agent run queue — one live run per agent, so a slow run cannot stack.
|
|
173
|
+
- Node gateway client (absolute endpoint, node auth); daemon-origin requests are
|
|
174
|
+
tagged so entitlement metering can tell them from browser traffic.
|
|
175
|
+
- `--default-model` fallback; a crew agent with no model fails fast rather than
|
|
176
|
+
starting an unrunnable run.
|
|
177
|
+
|
|
178
|
+
### Triggers
|
|
179
|
+
- Minimal 5-field UTC cron matcher with per-agent trigger state (`lastFired`,
|
|
180
|
+
`nextWake`), persisted and serialized so concurrent writes cannot clobber it.
|
|
181
|
+
- File-change triggers: a self-contained glob matcher, a bounded change buffer,
|
|
182
|
+
and an idempotent re-scan.
|
|
183
|
+
- Run-complete triggers: an evaluator carrying owner, stop reason and run
|
|
184
|
+
generation, with a chain-depth cap (`--max-chain-depth`, validated so a bad
|
|
185
|
+
value cannot disable the cap) to stop runs triggering each other forever.
|
|
186
|
+
- `schedule_self` tool for self-directed wakes.
|
|
187
|
+
|
|
188
|
+
### Budgets
|
|
189
|
+
- Run budgets enforced node-side (stop / degrade), failing **closed** on an
|
|
190
|
+
unpriceable run rather than proceeding unmetered.
|
|
191
|
+
- A continuous trigger cannot become due without a budget cap.
|
|
192
|
+
- Pure usage pricing extracted to the harness; the node side hydrates a price table.
|
|
193
|
+
|
|
194
|
+
### Permissions and attendance
|
|
195
|
+
- Unattended prompt resolver: deny, park (bounded by the real budget remainder),
|
|
196
|
+
or allow — an abort resolves to null rather than a silent deny.
|
|
197
|
+
- Attendance registry: asks are broadcast to attached clients, first answer wins,
|
|
198
|
+
and replay on attach means reconnecting does not lose a pending ask.
|
|
199
|
+
- Pending-ask records with boot reconciliation (audit-only) and permission audit lines.
|
|
200
|
+
- Stall watchdog aborts hung runs while leaving parked ones alone.
|
|
201
|
+
|
|
202
|
+
### Multi-owner isolation
|
|
203
|
+
- Per-owner run state and owner-qualified dispatch keys; a multi-root schedule
|
|
204
|
+
enumerates the daemon's own crew plus every `hosts/<dir>/crew`.
|
|
205
|
+
- `call_agent` is confined to the caller's owner, and an attended run resolves its
|
|
206
|
+
owner from the authenticated identity rather than a client-supplied value.
|
|
207
|
+
|
|
208
|
+
### Hosts and sync
|
|
209
|
+
- Durable `sidecarId` with friendly-name resolution; the CLI advertises id and name.
|
|
210
|
+
- `hosts.json` manifest: sanitized frozen `dirName`, null-prototype parsing,
|
|
211
|
+
per-record validation, atomic writes and serialized read-modify-write.
|
|
212
|
+
- `pd sidecar hosts list` / `forget`; boot logs manifest drift.
|
|
213
|
+
- Host-sync service with daemon-derived destinations. Writes to a synced tree go
|
|
214
|
+
through `syncWrite`/`syncRemove` only — the exposed surface has no `write`/`remove`
|
|
215
|
+
to bypass, and path confinement is reused from `NodeFileService` rather than
|
|
216
|
+
reimplemented.
|
|
217
|
+
- A materialized directory is never reclaimed by eviction.
|
|
218
|
+
|
|
219
|
+
### Also
|
|
220
|
+
- `--help` / `-h` now print usage and exit 0. They were previously rejected as
|
|
221
|
+
unknown arguments, which printed a bare flag list and exited 1. The help text is
|
|
222
|
+
generated from the same table the parser validates against, so a flag cannot be
|
|
223
|
+
added without appearing in `--help`.
|
|
224
|
+
- `fs_delete` tool, wired to `SidecarFileService.remove`.
|
|
225
|
+
- Quieter cloudflared output.
|
|
226
|
+
- A second `hello` is ignored once authenticated.
|
|
227
|
+
|
|
228
|
+
### Housekeeping
|
|
229
|
+
- The package's own `typecheck` now passes. It shares modules with the browser
|
|
230
|
+
harness (which guards its browser bits at runtime), so the tsconfig lacked the
|
|
231
|
+
DOM *types* and reported a dozen phantom errors against correct code.
|
package/dist/cli.js
CHANGED
|
@@ -11908,7 +11908,7 @@ var require_runtime = __commonJS({
|
|
|
11908
11908
|
}
|
|
11909
11909
|
return p2 && p2.lookup(name);
|
|
11910
11910
|
};
|
|
11911
|
-
_proto.resolve = function
|
|
11911
|
+
_proto.resolve = function resolve10(name, forWrite) {
|
|
11912
11912
|
var p2 = forWrite && this.isolateWrites ? void 0 : this.parent;
|
|
11913
11913
|
var val = this.variables[name];
|
|
11914
11914
|
if (val !== void 0) {
|
|
@@ -13638,7 +13638,7 @@ var require_loader = __commonJS({
|
|
|
13638
13638
|
return _EmitterObj.apply(this, arguments) || this;
|
|
13639
13639
|
}
|
|
13640
13640
|
var _proto = Loader2.prototype;
|
|
13641
|
-
_proto.resolve = function
|
|
13641
|
+
_proto.resolve = function resolve10(from, to) {
|
|
13642
13642
|
return path.resolve(path.dirname(from), to);
|
|
13643
13643
|
};
|
|
13644
13644
|
_proto.isRelative = function isRelative(filename) {
|
|
@@ -17098,7 +17098,7 @@ var require_lib3 = __commonJS({
|
|
|
17098
17098
|
let accum = [];
|
|
17099
17099
|
let accumBytes = 0;
|
|
17100
17100
|
let abort = false;
|
|
17101
|
-
return new Body.Promise(function(
|
|
17101
|
+
return new Body.Promise(function(resolve10, reject) {
|
|
17102
17102
|
let resTimeout;
|
|
17103
17103
|
if (_this4.timeout) {
|
|
17104
17104
|
resTimeout = setTimeout(function() {
|
|
@@ -17132,7 +17132,7 @@ var require_lib3 = __commonJS({
|
|
|
17132
17132
|
}
|
|
17133
17133
|
clearTimeout(resTimeout);
|
|
17134
17134
|
try {
|
|
17135
|
-
|
|
17135
|
+
resolve10(Buffer.concat(accum, accumBytes));
|
|
17136
17136
|
} catch (err) {
|
|
17137
17137
|
reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
|
|
17138
17138
|
}
|
|
@@ -17807,7 +17807,7 @@ var require_lib3 = __commonJS({
|
|
|
17807
17807
|
throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
|
|
17808
17808
|
}
|
|
17809
17809
|
Body.Promise = fetch3.Promise;
|
|
17810
|
-
return new fetch3.Promise(function(
|
|
17810
|
+
return new fetch3.Promise(function(resolve10, reject) {
|
|
17811
17811
|
const request = new Request3(url, opts);
|
|
17812
17812
|
const options = getNodeRequestOptions(request);
|
|
17813
17813
|
const send = (options.protocol === "https:" ? https : http).request;
|
|
@@ -17940,7 +17940,7 @@ var require_lib3 = __commonJS({
|
|
|
17940
17940
|
requestOpts.body = void 0;
|
|
17941
17941
|
requestOpts.headers.delete("content-length");
|
|
17942
17942
|
}
|
|
17943
|
-
|
|
17943
|
+
resolve10(fetch3(new Request3(locationURL, requestOpts)));
|
|
17944
17944
|
finalize();
|
|
17945
17945
|
return;
|
|
17946
17946
|
}
|
|
@@ -17961,7 +17961,7 @@ var require_lib3 = __commonJS({
|
|
|
17961
17961
|
const codings = headers.get("Content-Encoding");
|
|
17962
17962
|
if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
|
|
17963
17963
|
response = new Response3(body, response_options);
|
|
17964
|
-
|
|
17964
|
+
resolve10(response);
|
|
17965
17965
|
return;
|
|
17966
17966
|
}
|
|
17967
17967
|
const zlibOptions = {
|
|
@@ -17971,7 +17971,7 @@ var require_lib3 = __commonJS({
|
|
|
17971
17971
|
if (codings == "gzip" || codings == "x-gzip") {
|
|
17972
17972
|
body = body.pipe(zlib.createGunzip(zlibOptions));
|
|
17973
17973
|
response = new Response3(body, response_options);
|
|
17974
|
-
|
|
17974
|
+
resolve10(response);
|
|
17975
17975
|
return;
|
|
17976
17976
|
}
|
|
17977
17977
|
if (codings == "deflate" || codings == "x-deflate") {
|
|
@@ -17983,12 +17983,12 @@ var require_lib3 = __commonJS({
|
|
|
17983
17983
|
body = body.pipe(zlib.createInflateRaw());
|
|
17984
17984
|
}
|
|
17985
17985
|
response = new Response3(body, response_options);
|
|
17986
|
-
|
|
17986
|
+
resolve10(response);
|
|
17987
17987
|
});
|
|
17988
17988
|
raw.on("end", function() {
|
|
17989
17989
|
if (!response) {
|
|
17990
17990
|
response = new Response3(body, response_options);
|
|
17991
|
-
|
|
17991
|
+
resolve10(response);
|
|
17992
17992
|
}
|
|
17993
17993
|
});
|
|
17994
17994
|
return;
|
|
@@ -17996,11 +17996,11 @@ var require_lib3 = __commonJS({
|
|
|
17996
17996
|
if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
|
|
17997
17997
|
body = body.pipe(zlib.createBrotliDecompress());
|
|
17998
17998
|
response = new Response3(body, response_options);
|
|
17999
|
-
|
|
17999
|
+
resolve10(response);
|
|
18000
18000
|
return;
|
|
18001
18001
|
}
|
|
18002
18002
|
response = new Response3(body, response_options);
|
|
18003
|
-
|
|
18003
|
+
resolve10(response);
|
|
18004
18004
|
});
|
|
18005
18005
|
writeToStream(req, request);
|
|
18006
18006
|
});
|
|
@@ -22281,8 +22281,8 @@ var SidecarServer = class {
|
|
|
22281
22281
|
}
|
|
22282
22282
|
hostCall(provider, method, args) {
|
|
22283
22283
|
const id = ++this.hostSeq;
|
|
22284
|
-
return new Promise((
|
|
22285
|
-
this.hostPending.set(id, { resolve:
|
|
22284
|
+
return new Promise((resolve10, reject) => {
|
|
22285
|
+
this.hostPending.set(id, { resolve: resolve10, reject });
|
|
22286
22286
|
this.ch.send({ t: "host-call", id, provider, method, args });
|
|
22287
22287
|
});
|
|
22288
22288
|
}
|
|
@@ -22463,13 +22463,13 @@ function probeAddress(bindHost) {
|
|
|
22463
22463
|
return h2;
|
|
22464
22464
|
}
|
|
22465
22465
|
function portInUse(host, port, timeoutMs = 500) {
|
|
22466
|
-
return new Promise((
|
|
22466
|
+
return new Promise((resolve10) => {
|
|
22467
22467
|
let settled = false;
|
|
22468
22468
|
const done = (busy) => {
|
|
22469
22469
|
if (settled) return;
|
|
22470
22470
|
settled = true;
|
|
22471
22471
|
socket.destroy();
|
|
22472
|
-
|
|
22472
|
+
resolve10(busy);
|
|
22473
22473
|
};
|
|
22474
22474
|
const socket = connect({ host, port });
|
|
22475
22475
|
socket.setTimeout(timeoutMs);
|
|
@@ -24361,8 +24361,9 @@ function inspectArgs(name) {
|
|
|
24361
24361
|
function snapshotListArgs() {
|
|
24362
24362
|
return ["snapshot", "list", "--format", "json"];
|
|
24363
24363
|
}
|
|
24364
|
-
function execArgs(name, command) {
|
|
24365
|
-
|
|
24364
|
+
function execArgs(name, command, env) {
|
|
24365
|
+
const e2 = env ? Object.entries(env).flatMap(([k2, v2]) => ["-e", `${k2}=${v2}`]) : [];
|
|
24366
|
+
return ["exec", name, ...e2, "--", ...command];
|
|
24366
24367
|
}
|
|
24367
24368
|
function wslHostPath(p2) {
|
|
24368
24369
|
const m2 = /^([A-Za-z]):[\\/](.*)$/.exec(p2);
|
|
@@ -24730,7 +24731,7 @@ function makeMicrovmBackend(deps) {
|
|
|
24730
24731
|
throw new SessionUnavailable(id, "paused");
|
|
24731
24732
|
}
|
|
24732
24733
|
if (command.length === 0) throw new Error("exec needs a command");
|
|
24733
|
-
const r2 = await deps.run(execArgs(sandboxName(id), command), opts);
|
|
24734
|
+
const r2 = await deps.run(execArgs(sandboxName(id), command, opts?.env), opts);
|
|
24734
24735
|
return { code: r2.code, stdout: r2.stdout, stderr: r2.stderr };
|
|
24735
24736
|
},
|
|
24736
24737
|
/**
|
|
@@ -27289,10 +27290,10 @@ ${content}` : parentData.content;
|
|
|
27289
27290
|
});
|
|
27290
27291
|
this.registerFiltersOnEnv(env);
|
|
27291
27292
|
const renderTimeout = 5e3;
|
|
27292
|
-
const renderPromise = new Promise((
|
|
27293
|
+
const renderPromise = new Promise((resolve10, reject) => {
|
|
27293
27294
|
try {
|
|
27294
27295
|
const result = env.renderString(content, context.parameters);
|
|
27295
|
-
|
|
27296
|
+
resolve10(result);
|
|
27296
27297
|
} catch (error) {
|
|
27297
27298
|
reject(error);
|
|
27298
27299
|
}
|
|
@@ -29328,7 +29329,7 @@ ${err}`;
|
|
|
29328
29329
|
}
|
|
29329
29330
|
const outcome = ctx.signal.aborted ? null : await Promise.race([
|
|
29330
29331
|
ctx.reviewEdit(ctx.callId),
|
|
29331
|
-
new Promise((
|
|
29332
|
+
new Promise((resolve10) => ctx.signal.addEventListener("abort", () => resolve10(null), { once: true }))
|
|
29332
29333
|
]);
|
|
29333
29334
|
if (!outcome) return "The run ended before the user reviewed this proposal. Do NOT assume the edit was applied.";
|
|
29334
29335
|
if (outcome.decision === "applied") {
|
|
@@ -31455,8 +31456,8 @@ function _addRequestID(value, response) {
|
|
|
31455
31456
|
}
|
|
31456
31457
|
var APIPromise = class _APIPromise extends Promise {
|
|
31457
31458
|
constructor(responsePromise, parseResponse2 = defaultParseResponse) {
|
|
31458
|
-
super((
|
|
31459
|
-
|
|
31459
|
+
super((resolve10) => {
|
|
31460
|
+
resolve10(null);
|
|
31460
31461
|
});
|
|
31461
31462
|
this.responsePromise = responsePromise;
|
|
31462
31463
|
this.parseResponse = parseResponse2;
|
|
@@ -32031,7 +32032,7 @@ var startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
|
|
|
32031
32032
|
var isAbsoluteURL = (url) => {
|
|
32032
32033
|
return startsWithSchemeRegexp.test(url);
|
|
32033
32034
|
};
|
|
32034
|
-
var sleep = (ms) => new Promise((
|
|
32035
|
+
var sleep = (ms) => new Promise((resolve10) => setTimeout(resolve10, ms));
|
|
32035
32036
|
var validatePositiveInteger = (name, n2) => {
|
|
32036
32037
|
if (typeof n2 !== "number" || !Number.isInteger(n2)) {
|
|
32037
32038
|
throw new OpenAIError(`${name} must be an integer`);
|
|
@@ -32464,12 +32465,12 @@ var EventStream = class {
|
|
|
32464
32465
|
_EventStream_errored.set(this, false);
|
|
32465
32466
|
_EventStream_aborted.set(this, false);
|
|
32466
32467
|
_EventStream_catchingPromiseCreated.set(this, false);
|
|
32467
|
-
__classPrivateFieldSet7(this, _EventStream_connectedPromise, new Promise((
|
|
32468
|
-
__classPrivateFieldSet7(this, _EventStream_resolveConnectedPromise,
|
|
32468
|
+
__classPrivateFieldSet7(this, _EventStream_connectedPromise, new Promise((resolve10, reject) => {
|
|
32469
|
+
__classPrivateFieldSet7(this, _EventStream_resolveConnectedPromise, resolve10, "f");
|
|
32469
32470
|
__classPrivateFieldSet7(this, _EventStream_rejectConnectedPromise, reject, "f");
|
|
32470
32471
|
}), "f");
|
|
32471
|
-
__classPrivateFieldSet7(this, _EventStream_endPromise, new Promise((
|
|
32472
|
-
__classPrivateFieldSet7(this, _EventStream_resolveEndPromise,
|
|
32472
|
+
__classPrivateFieldSet7(this, _EventStream_endPromise, new Promise((resolve10, reject) => {
|
|
32473
|
+
__classPrivateFieldSet7(this, _EventStream_resolveEndPromise, resolve10, "f");
|
|
32473
32474
|
__classPrivateFieldSet7(this, _EventStream_rejectEndPromise, reject, "f");
|
|
32474
32475
|
}), "f");
|
|
32475
32476
|
__classPrivateFieldGet8(this, _EventStream_connectedPromise, "f").catch(() => {
|
|
@@ -32553,11 +32554,11 @@ var EventStream = class {
|
|
|
32553
32554
|
* const message = await stream.emitted('message') // rejects if the stream errors
|
|
32554
32555
|
*/
|
|
32555
32556
|
emitted(event) {
|
|
32556
|
-
return new Promise((
|
|
32557
|
+
return new Promise((resolve10, reject) => {
|
|
32557
32558
|
__classPrivateFieldSet7(this, _EventStream_catchingPromiseCreated, true, "f");
|
|
32558
32559
|
if (event !== "error")
|
|
32559
32560
|
this.once("error", reject);
|
|
32560
|
-
this.once(event,
|
|
32561
|
+
this.once(event, resolve10);
|
|
32561
32562
|
});
|
|
32562
32563
|
}
|
|
32563
32564
|
async done() {
|
|
@@ -32710,7 +32711,7 @@ var AssistantStream = class _AssistantStream extends EventStream {
|
|
|
32710
32711
|
if (done) {
|
|
32711
32712
|
return { value: void 0, done: true };
|
|
32712
32713
|
}
|
|
32713
|
-
return new Promise((
|
|
32714
|
+
return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
32714
32715
|
}
|
|
32715
32716
|
const chunk = pushQueue.shift();
|
|
32716
32717
|
return { value: chunk, done: false };
|
|
@@ -34328,7 +34329,7 @@ var ChatCompletionStream = class _ChatCompletionStream extends AbstractChatCompl
|
|
|
34328
34329
|
if (done) {
|
|
34329
34330
|
return { value: void 0, done: true };
|
|
34330
34331
|
}
|
|
34331
|
-
return new Promise((
|
|
34332
|
+
return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
|
|
34332
34333
|
}
|
|
34333
34334
|
const chunk = pushQueue.shift();
|
|
34334
34335
|
return { value: chunk, done: false };
|
|
@@ -35977,7 +35978,7 @@ var ResponseStream = class _ResponseStream extends EventStream {
|
|
|
35977
35978
|
if (done) {
|
|
35978
35979
|
return { value: void 0, done: true };
|
|
35979
35980
|
}
|
|
35980
|
-
return new Promise((
|
|
35981
|
+
return new Promise((resolve10, reject) => readQueue.push({ resolve: resolve10, reject })).then((event2) => event2 ? { value: event2, done: false } : { value: void 0, done: true });
|
|
35981
35982
|
}
|
|
35982
35983
|
const event = pushQueue.shift();
|
|
35983
35984
|
return { value: event, done: false };
|
|
@@ -36619,7 +36620,7 @@ var openai_default = OpenAI;
|
|
|
36619
36620
|
var enabled = true;
|
|
36620
36621
|
function setAgentLogging(on) {
|
|
36621
36622
|
enabled = on;
|
|
36622
|
-
console.log(
|
|
36623
|
+
if (on) console.log("[agent] logging enabled");
|
|
36623
36624
|
}
|
|
36624
36625
|
function alog(...args) {
|
|
36625
36626
|
if (enabled) console.debug("[agent]", ...args);
|
|
@@ -36738,8 +36739,18 @@ function createChatClient(auth, opts = {}) {
|
|
|
36738
36739
|
}
|
|
36739
36740
|
|
|
36740
36741
|
// src/runner/gatewayClient.ts
|
|
36742
|
+
var API_PREFIX = "/api";
|
|
36743
|
+
function normalizeEndpoint(endpoint) {
|
|
36744
|
+
const trimmed = endpoint.replace(/\/+$/, "");
|
|
36745
|
+
try {
|
|
36746
|
+
const u2 = new URL(trimmed);
|
|
36747
|
+
return u2.pathname === "" || u2.pathname === "/" ? `${u2.origin}${API_PREFIX}` : trimmed;
|
|
36748
|
+
} catch {
|
|
36749
|
+
return trimmed;
|
|
36750
|
+
}
|
|
36751
|
+
}
|
|
36741
36752
|
function nodeGatewayClient(endpoint) {
|
|
36742
|
-
setGatewayBase(endpoint);
|
|
36753
|
+
setGatewayBase(normalizeEndpoint(endpoint));
|
|
36743
36754
|
return createChatClient(nodeAuthToken(), { origin: "daemon" });
|
|
36744
36755
|
}
|
|
36745
36756
|
|
|
@@ -36772,14 +36783,14 @@ function classifyStreamError(message, status) {
|
|
|
36772
36783
|
}
|
|
36773
36784
|
function abortableSleep(ms, signal) {
|
|
36774
36785
|
if (signal?.aborted) return Promise.resolve(false);
|
|
36775
|
-
return new Promise((
|
|
36786
|
+
return new Promise((resolve10) => {
|
|
36776
36787
|
const onAbort = () => {
|
|
36777
36788
|
clearTimeout(t2);
|
|
36778
|
-
|
|
36789
|
+
resolve10(false);
|
|
36779
36790
|
};
|
|
36780
36791
|
const t2 = setTimeout(() => {
|
|
36781
36792
|
signal?.removeEventListener("abort", onAbort);
|
|
36782
|
-
|
|
36793
|
+
resolve10(true);
|
|
36783
36794
|
}, ms);
|
|
36784
36795
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
36785
36796
|
});
|
|
@@ -37724,12 +37735,12 @@ function makeScheduleSelfTool(opts) {
|
|
|
37724
37735
|
var PARK_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
37725
37736
|
var PARK_POLL_MS = 250;
|
|
37726
37737
|
function defaultSleep(ms, signal) {
|
|
37727
|
-
return new Promise((
|
|
37738
|
+
return new Promise((resolve10) => {
|
|
37728
37739
|
let timer;
|
|
37729
37740
|
const onAbort = () => {
|
|
37730
37741
|
if (timer !== void 0) clearTimeout(timer);
|
|
37731
37742
|
signal.removeEventListener("abort", onAbort);
|
|
37732
|
-
|
|
37743
|
+
resolve10();
|
|
37733
37744
|
};
|
|
37734
37745
|
if (signal.aborted) {
|
|
37735
37746
|
onAbort();
|
|
@@ -37737,7 +37748,7 @@ function defaultSleep(ms, signal) {
|
|
|
37737
37748
|
}
|
|
37738
37749
|
timer = setTimeout(() => {
|
|
37739
37750
|
signal.removeEventListener("abort", onAbort);
|
|
37740
|
-
|
|
37751
|
+
resolve10();
|
|
37741
37752
|
}, ms);
|
|
37742
37753
|
signal.addEventListener("abort", onAbort);
|
|
37743
37754
|
});
|
|
@@ -38482,12 +38493,12 @@ function makeDispatcher(opts) {
|
|
|
38482
38493
|
// src/runner/clock.ts
|
|
38483
38494
|
var MAX_SLEEP_MS = 15 * 60 * 1e3;
|
|
38484
38495
|
function defaultSleep2(ms, signal) {
|
|
38485
|
-
return new Promise((
|
|
38496
|
+
return new Promise((resolve10) => {
|
|
38486
38497
|
let timer;
|
|
38487
38498
|
const onAbort = () => {
|
|
38488
38499
|
if (timer !== void 0) clearTimeout(timer);
|
|
38489
38500
|
signal.removeEventListener("abort", onAbort);
|
|
38490
|
-
|
|
38501
|
+
resolve10();
|
|
38491
38502
|
};
|
|
38492
38503
|
if (signal.aborted) {
|
|
38493
38504
|
onAbort();
|
|
@@ -38495,7 +38506,7 @@ function defaultSleep2(ms, signal) {
|
|
|
38495
38506
|
}
|
|
38496
38507
|
timer = setTimeout(() => {
|
|
38497
38508
|
signal.removeEventListener("abort", onAbort);
|
|
38498
|
-
|
|
38509
|
+
resolve10();
|
|
38499
38510
|
}, ms);
|
|
38500
38511
|
signal.addEventListener("abort", onAbort);
|
|
38501
38512
|
});
|
|
@@ -38859,7 +38870,7 @@ function makeAttendanceRegistry(opts) {
|
|
|
38859
38870
|
if (clients.size === 0) {
|
|
38860
38871
|
return Promise.resolve(null);
|
|
38861
38872
|
}
|
|
38862
|
-
return new Promise((
|
|
38873
|
+
return new Promise((resolve10) => {
|
|
38863
38874
|
let cleanupAbort;
|
|
38864
38875
|
const settleNull = () => {
|
|
38865
38876
|
const entry = outstanding.get(ask.id);
|
|
@@ -38871,7 +38882,7 @@ function makeAttendanceRegistry(opts) {
|
|
|
38871
38882
|
ask,
|
|
38872
38883
|
resolve: (decision) => {
|
|
38873
38884
|
cleanupAbort?.();
|
|
38874
|
-
|
|
38885
|
+
resolve10(decision);
|
|
38875
38886
|
}
|
|
38876
38887
|
});
|
|
38877
38888
|
for (const c2 of clients) {
|
|
@@ -39364,9 +39375,264 @@ async function runHostsCli(argv) {
|
|
|
39364
39375
|
}
|
|
39365
39376
|
}
|
|
39366
39377
|
|
|
39378
|
+
// src/sessionsCli.ts
|
|
39379
|
+
import { resolve as resolve6 } from "node:path";
|
|
39380
|
+
async function sandboxLifecycle(run, verb, name) {
|
|
39381
|
+
const call = async (args) => {
|
|
39382
|
+
const r2 = await run(args).catch((e2) => ({ code: 1, stdout: "", stderr: String(e2) }));
|
|
39383
|
+
return { ok: r2.code === 0, detail: (r2.stderr || r2.stdout).trim().split("\n").slice(-2).join("; ") };
|
|
39384
|
+
};
|
|
39385
|
+
if (verb === "pause") return call(["stop", name]);
|
|
39386
|
+
if (verb === "resume") return call(["start", name]);
|
|
39387
|
+
await call(["stop", name]);
|
|
39388
|
+
return call(["remove", name]);
|
|
39389
|
+
}
|
|
39390
|
+
function humanTime(v2) {
|
|
39391
|
+
if (!v2) return "";
|
|
39392
|
+
const n2 = Number(v2);
|
|
39393
|
+
if (!Number.isFinite(n2) || n2 <= 0) return v2;
|
|
39394
|
+
return new Date(n2).toISOString().replace("T", " ").replace(/\.\d+Z$/, "Z");
|
|
39395
|
+
}
|
|
39396
|
+
async function listSessions(run) {
|
|
39397
|
+
const listed = await run(listArgs()).catch(() => null);
|
|
39398
|
+
if (!listed || listed.code !== 0) return [];
|
|
39399
|
+
const rows = [];
|
|
39400
|
+
for (const box of parseSandboxList(listed.stdout)) {
|
|
39401
|
+
const inspected = await run(inspectArgs(box.name)).catch(() => null);
|
|
39402
|
+
const labels = inspected && inspected.code === 0 ? parseSandboxLabels(inspected.stdout) : {};
|
|
39403
|
+
const id = labels[LABEL_SESSION] ?? idFromSandboxName(box.name);
|
|
39404
|
+
if (!id) continue;
|
|
39405
|
+
const url = labels[LABEL_REPO_URL];
|
|
39406
|
+
const ref = labels[LABEL_REPO_REF];
|
|
39407
|
+
rows.push({
|
|
39408
|
+
id,
|
|
39409
|
+
sandbox: box.name,
|
|
39410
|
+
status: box.status || "unknown",
|
|
39411
|
+
workdir: labels[LABEL_WORKDIR] ?? "",
|
|
39412
|
+
owner: labels[LABEL_OWNER] ?? "",
|
|
39413
|
+
// The label stores epoch millis; a bare 1787430794235 in a terminal is a
|
|
39414
|
+
// number nobody can read as a time.
|
|
39415
|
+
created: humanTime(labels[LABEL_CREATED]) || (box.createdAt ? new Date(box.createdAt).toISOString() : ""),
|
|
39416
|
+
...url ? { repo: ref ? `${url}#${ref}` : url } : {}
|
|
39417
|
+
});
|
|
39418
|
+
}
|
|
39419
|
+
return rows;
|
|
39420
|
+
}
|
|
39421
|
+
function formatSessions(rows) {
|
|
39422
|
+
if (!rows.length) {
|
|
39423
|
+
return [
|
|
39424
|
+
"no sessions on this machine.",
|
|
39425
|
+
"",
|
|
39426
|
+
"Sessions are created by a daemon running with --isolation microvm.",
|
|
39427
|
+
"Without it, runs execute in the daemon process and leave nothing to list."
|
|
39428
|
+
].join("\n");
|
|
39429
|
+
}
|
|
39430
|
+
const w2 = (pick2, head) => Math.max(head.length, ...rows.map((r2) => pick2(r2).length));
|
|
39431
|
+
const idW = w2((r2) => r2.id, "session");
|
|
39432
|
+
const stW = w2((r2) => r2.status, "status");
|
|
39433
|
+
const wdW = w2((r2) => r2.workdir, "workdir");
|
|
39434
|
+
const line = (id, st2, wd, cr2) => `${id.padEnd(idW)} ${st2.padEnd(stW)} ${wd.padEnd(wdW)} ${cr2}`;
|
|
39435
|
+
return [
|
|
39436
|
+
line("session", "status", "workdir", "created"),
|
|
39437
|
+
...rows.map((r2) => line(r2.id, r2.status, r2.workdir, r2.created))
|
|
39438
|
+
].join("\n");
|
|
39439
|
+
}
|
|
39440
|
+
function formatSession(r2) {
|
|
39441
|
+
return [
|
|
39442
|
+
`session ${r2.id}`,
|
|
39443
|
+
`sandbox ${r2.sandbox}`,
|
|
39444
|
+
`status ${r2.status}`,
|
|
39445
|
+
`workdir ${r2.workdir || "(none)"}`,
|
|
39446
|
+
`owner ${r2.owner || "(none)"}`,
|
|
39447
|
+
`created ${r2.created || "(unknown)"}`,
|
|
39448
|
+
...r2.repo ? [`repo ${r2.repo}`] : []
|
|
39449
|
+
].join("\n");
|
|
39450
|
+
}
|
|
39451
|
+
var DEFAULT_GUEST_IMAGE = "corenel-guest:dev";
|
|
39452
|
+
function backendFor(deps, roots, run) {
|
|
39453
|
+
return makeMicrovmBackend({
|
|
39454
|
+
roots: () => roots,
|
|
39455
|
+
run,
|
|
39456
|
+
image: deps.image ?? DEFAULT_GUEST_IMAGE,
|
|
39457
|
+
// On Windows msb lives inside WSL, where C:\git\proj means nothing. The
|
|
39458
|
+
// daemon maps host paths the same way.
|
|
39459
|
+
...deps.wsl ? { hostPath: wslHostPath } : {}
|
|
39460
|
+
});
|
|
39461
|
+
}
|
|
39462
|
+
var VALUE_FLAGS = /* @__PURE__ */ new Set(["--root", "--msb", "--image"]);
|
|
39463
|
+
function rootFrom(argv, cwd) {
|
|
39464
|
+
const at2 = argv.indexOf("--root");
|
|
39465
|
+
return resolve6(at2 >= 0 && argv[at2 + 1] ? argv[at2 + 1] : cwd);
|
|
39466
|
+
}
|
|
39467
|
+
async function runSessionsCli(argv, deps) {
|
|
39468
|
+
const out = deps.out ?? ((s2) => process.stdout.write(s2));
|
|
39469
|
+
const err = deps.err ?? ((s2) => process.stderr.write(s2));
|
|
39470
|
+
const run = deps.run ?? makeMsbRunner(deps.msbBin, deps.wsl ? wslMsb(deps.msbBin) : void 0);
|
|
39471
|
+
const verbs = argv.filter((a2, i2) => !a2.startsWith("--") && !(i2 > 0 && VALUE_FLAGS.has(argv[i2 - 1])));
|
|
39472
|
+
const [verb, ...rest] = verbs;
|
|
39473
|
+
if (verb === void 0 || verb === "list") {
|
|
39474
|
+
if (rest.length) {
|
|
39475
|
+
err(`corenel sessions list: unexpected argument "${rest[0]}"
|
|
39476
|
+
`);
|
|
39477
|
+
return 1;
|
|
39478
|
+
}
|
|
39479
|
+
out(`${formatSessions(await listSessions(run))}
|
|
39480
|
+
`);
|
|
39481
|
+
return 0;
|
|
39482
|
+
}
|
|
39483
|
+
if (verb === "show") {
|
|
39484
|
+
const id = rest[0];
|
|
39485
|
+
if (!id) {
|
|
39486
|
+
err("corenel sessions show: missing <id>\n");
|
|
39487
|
+
return 1;
|
|
39488
|
+
}
|
|
39489
|
+
const found = (await listSessions(run)).find((r2) => r2.id === id || r2.sandbox === id);
|
|
39490
|
+
if (!found) {
|
|
39491
|
+
err(`corenel sessions: no session "${id}" on this machine
|
|
39492
|
+
`);
|
|
39493
|
+
return 1;
|
|
39494
|
+
}
|
|
39495
|
+
out(`${formatSession(found)}
|
|
39496
|
+
`);
|
|
39497
|
+
return 0;
|
|
39498
|
+
}
|
|
39499
|
+
if (verb === "create") {
|
|
39500
|
+
const root = rootFrom(argv, process.cwd());
|
|
39501
|
+
const backend = deps.backend ?? backendFor(deps, [root], run);
|
|
39502
|
+
if (backend.adopt) await backend.adopt().catch(() => void 0);
|
|
39503
|
+
try {
|
|
39504
|
+
const handle = await backend.create({ workdir: root, owner: process.env.USERNAME || process.env.USER || "cli" });
|
|
39505
|
+
out(`${handle.id}
|
|
39506
|
+
`);
|
|
39507
|
+
err(`created ${handle.id} on ${handle.workdir}
|
|
39508
|
+
`);
|
|
39509
|
+
return 0;
|
|
39510
|
+
} catch (e2) {
|
|
39511
|
+
err(`corenel sessions create: ${e2 instanceof Error ? e2.message : String(e2)}
|
|
39512
|
+
`);
|
|
39513
|
+
return 1;
|
|
39514
|
+
}
|
|
39515
|
+
}
|
|
39516
|
+
if (verb === "run") {
|
|
39517
|
+
const id = rest[0];
|
|
39518
|
+
const prompt = rest.slice(1).filter((a2) => !a2.startsWith("--")).join(" ").trim();
|
|
39519
|
+
if (!id) {
|
|
39520
|
+
err("corenel sessions run: missing <id>\n");
|
|
39521
|
+
return 1;
|
|
39522
|
+
}
|
|
39523
|
+
if (!prompt) {
|
|
39524
|
+
err('corenel sessions run: missing prompt\n usage: corenel sessions run <id> "<prompt>"\n');
|
|
39525
|
+
return 1;
|
|
39526
|
+
}
|
|
39527
|
+
const found = (await listSessions(run)).find((r2) => r2.id === id || r2.sandbox === id);
|
|
39528
|
+
if (!found) {
|
|
39529
|
+
err(`corenel sessions: no session "${id}" on this machine
|
|
39530
|
+
`);
|
|
39531
|
+
return 1;
|
|
39532
|
+
}
|
|
39533
|
+
const backend = deps.backend ?? backendFor(deps, [found.workdir], run);
|
|
39534
|
+
if (!backend.exec) {
|
|
39535
|
+
err("corenel sessions run: this backend cannot execute inside a session\n");
|
|
39536
|
+
return 1;
|
|
39537
|
+
}
|
|
39538
|
+
if (backend.adopt) await backend.adopt().catch(() => void 0);
|
|
39539
|
+
try {
|
|
39540
|
+
const token = await readAuthToken() ?? process.env.CORENEL_TOKEN ?? null;
|
|
39541
|
+
if (!token) {
|
|
39542
|
+
err("corenel sessions run: not signed in on this host.\n Run `corenel login` first \u2014 the session uses the host's credential.\n");
|
|
39543
|
+
return 1;
|
|
39544
|
+
}
|
|
39545
|
+
const r2 = await backend.exec(found.id, ["corenel", "run", prompt], { env: { CORENEL_TOKEN: token } });
|
|
39546
|
+
if (r2.stdout) out(r2.stdout.endsWith("\n") ? r2.stdout : `${r2.stdout}
|
|
39547
|
+
`);
|
|
39548
|
+
if (r2.stderr.trim()) err(r2.stderr.endsWith("\n") ? r2.stderr : `${r2.stderr}
|
|
39549
|
+
`);
|
|
39550
|
+
return r2.code ?? 1;
|
|
39551
|
+
} catch (e2) {
|
|
39552
|
+
err(`corenel sessions run: ${e2 instanceof Error ? e2.message : String(e2)}
|
|
39553
|
+
`);
|
|
39554
|
+
return 1;
|
|
39555
|
+
}
|
|
39556
|
+
}
|
|
39557
|
+
if (verb === "pause" || verb === "resume" || verb === "destroy") {
|
|
39558
|
+
const id = rest[0];
|
|
39559
|
+
if (!id) {
|
|
39560
|
+
err(`corenel sessions ${verb}: missing <id>
|
|
39561
|
+
`);
|
|
39562
|
+
return 1;
|
|
39563
|
+
}
|
|
39564
|
+
const found = (await listSessions(run)).find((r2) => r2.id === id || r2.sandbox === id);
|
|
39565
|
+
if (!found) {
|
|
39566
|
+
err(`corenel sessions: no session "${id}" on this machine
|
|
39567
|
+
`);
|
|
39568
|
+
return 1;
|
|
39569
|
+
}
|
|
39570
|
+
const backend = deps.backend ?? backendFor(deps, [found.workdir], run);
|
|
39571
|
+
if (backend.adopt) await backend.adopt().catch(() => void 0);
|
|
39572
|
+
const known = !!backend.get?.(found.id);
|
|
39573
|
+
if (!known) {
|
|
39574
|
+
const r2 = await sandboxLifecycle(run, verb, found.sandbox);
|
|
39575
|
+
if (!r2.ok) {
|
|
39576
|
+
err(`corenel sessions ${verb}: ${r2.detail || "msb refused"}
|
|
39577
|
+
`);
|
|
39578
|
+
return 1;
|
|
39579
|
+
}
|
|
39580
|
+
if (verb === "destroy") {
|
|
39581
|
+
const still = (await listSessions(run)).find((x2) => x2.id === found.id);
|
|
39582
|
+
if (still) {
|
|
39583
|
+
err(`corenel sessions destroy: ${found.id} is still present (status ${still.status})
|
|
39584
|
+
`);
|
|
39585
|
+
return 1;
|
|
39586
|
+
}
|
|
39587
|
+
}
|
|
39588
|
+
out(`${verb === "destroy" ? "destroyed" : verb === "pause" ? "paused" : "resumed"} ${found.id}
|
|
39589
|
+
`);
|
|
39590
|
+
return 0;
|
|
39591
|
+
}
|
|
39592
|
+
try {
|
|
39593
|
+
if (verb === "pause") {
|
|
39594
|
+
const r2 = await backend.pause(found.id);
|
|
39595
|
+
if (r2 && !r2.drained) {
|
|
39596
|
+
err(`paused ${found.id}, but ${r2.remaining.length} call(s) were STILL RUNNING when the drain gave up
|
|
39597
|
+
`);
|
|
39598
|
+
return 1;
|
|
39599
|
+
}
|
|
39600
|
+
out(`paused ${found.id}
|
|
39601
|
+
`);
|
|
39602
|
+
return 0;
|
|
39603
|
+
}
|
|
39604
|
+
if (verb === "resume") {
|
|
39605
|
+
await backend.resume(found.id);
|
|
39606
|
+
out(`resumed ${found.id}
|
|
39607
|
+
`);
|
|
39608
|
+
return 0;
|
|
39609
|
+
}
|
|
39610
|
+
await backend.destroy(found.id);
|
|
39611
|
+
const still = (await listSessions(run)).find((r2) => r2.id === found.id);
|
|
39612
|
+
if (still) {
|
|
39613
|
+
err(`corenel sessions destroy: ${found.id} is still present (status ${still.status})
|
|
39614
|
+
`);
|
|
39615
|
+
return 1;
|
|
39616
|
+
}
|
|
39617
|
+
out(`destroyed ${found.id}
|
|
39618
|
+
`);
|
|
39619
|
+
return 0;
|
|
39620
|
+
} catch (e2) {
|
|
39621
|
+
err(`corenel sessions ${verb}: ${e2 instanceof Error ? e2.message : String(e2)}
|
|
39622
|
+
`);
|
|
39623
|
+
return 1;
|
|
39624
|
+
}
|
|
39625
|
+
}
|
|
39626
|
+
err(`corenel sessions: unknown subcommand "${verb}"
|
|
39627
|
+
usage: corenel sessions [list | show <id> | create [--root <dir>] | run <id> "<prompt>"
|
|
39628
|
+
| pause <id> | resume <id> | destroy <id>]
|
|
39629
|
+
`);
|
|
39630
|
+
return 1;
|
|
39631
|
+
}
|
|
39632
|
+
|
|
39367
39633
|
// src/args.ts
|
|
39368
39634
|
import { statSync as statSync2 } from "node:fs";
|
|
39369
|
-
import { resolve as
|
|
39635
|
+
import { resolve as resolve7 } from "node:path";
|
|
39370
39636
|
|
|
39371
39637
|
// src/flags.ts
|
|
39372
39638
|
var FLAGS = [
|
|
@@ -39376,7 +39642,7 @@ var FLAGS = [
|
|
|
39376
39642
|
{ flag: "--allow-add-under", arg: "<dir>", help: "Let the client add working directories beneath <dir> during a session. Repeatable. Grants directory-name enumeration over the subtree. Added roots last until the sidecar exits." },
|
|
39377
39643
|
{ flag: "--allow-origin", arg: "<url>", help: "Allow a browser origin to connect. Repeatable." },
|
|
39378
39644
|
{ flag: "--allow-shell", help: "Enable the shell tool. Off by default." },
|
|
39379
|
-
{ flag: "--allow-lan", help: "
|
|
39645
|
+
{ flag: "--allow-lan", help: "Serve the local network, not just this machine: binds all interfaces and serves wss with a self-signed cert. --host / --tls-cert override each half." },
|
|
39380
39646
|
{ flag: "--tls-cert", arg: "<file>", help: "TLS certificate for wss://." },
|
|
39381
39647
|
{ flag: "--tls-key", arg: "<file>", help: "TLS private key for wss://." },
|
|
39382
39648
|
{ flag: "--self-signed", help: "Generate a self-signed certificate instead of supplying one." },
|
|
@@ -39384,9 +39650,9 @@ var FLAGS = [
|
|
|
39384
39650
|
{ flag: "--tunnel-name", arg: "<name>", help: "Use a named cloudflared tunnel." },
|
|
39385
39651
|
{ flag: "--tunnel-hostname", arg: "<host>", help: "Hostname for the named tunnel." },
|
|
39386
39652
|
{ flag: "--open", help: "Open the app in a browser once the sidecar is listening." },
|
|
39387
|
-
{ flag: "--app-url", arg: "<url>", help: "App to open and pair with (default https://prompd.app)." },
|
|
39653
|
+
{ flag: "--app-url", arg: "<url>", help: "App to open and pair with, path included (default https://corenel.ai; prompd pairs at https://prompd.app/studio)." },
|
|
39388
39654
|
{ flag: "--daemon", help: "Run crew agents on this machine unattended: cron, file-change and run-complete triggers." },
|
|
39389
|
-
{ flag: "--endpoint", arg: "<url>", help: "Gateway the daemon calls for model runs (default https://api.
|
|
39655
|
+
{ flag: "--endpoint", arg: "<url>", help: "Gateway the daemon calls for model runs (default https://api.corenel.ai/api). A bare origin gets /api appended." },
|
|
39390
39656
|
{ flag: "--state-dir", arg: "<dir>", help: "Where crew agents, sessions and tokens live (defaults to the Corenel dot-dir)." },
|
|
39391
39657
|
{ flag: "--default-model", arg: "<id>", help: "Model for crew agents that do not name one." },
|
|
39392
39658
|
{ flag: "--name", arg: "<label>", help: "Friendly name advertised to clients (defaults to the hostname)." },
|
|
@@ -39442,6 +39708,7 @@ function helpText() {
|
|
|
39442
39708
|
"Subcommands:",
|
|
39443
39709
|
" hosts list Show clients that have paired with this sidecar.",
|
|
39444
39710
|
" hosts forget Remove a paired client and its synced files.",
|
|
39711
|
+
" sessions List sandbox sessions on this machine (also `corenel sessions`).",
|
|
39445
39712
|
" acp-agent Speak ACP over stdio, for an editor to spawn (Zed, JetBrains).",
|
|
39446
39713
|
" login Sign in to Corenel in your browser.",
|
|
39447
39714
|
" logout Forget the stored sign-in (paired devices are unaffected).",
|
|
@@ -39527,14 +39794,18 @@ function parseArgs(argv) {
|
|
|
39527
39794
|
guestImage: "corenel-guest:dev",
|
|
39528
39795
|
selfSigned: false,
|
|
39529
39796
|
open: false,
|
|
39530
|
-
appUrl: "https://
|
|
39797
|
+
appUrl: "https://corenel.ai",
|
|
39798
|
+
// The gateway this package's own product talks to, and it carries the /api
|
|
39799
|
+
// prefix the gateway actually lives behind -- setGatewayBase appends /v1,
|
|
39800
|
+
// so a bare origin composes .../v1/chat/completions, which is a 404.
|
|
39531
39801
|
daemon: false,
|
|
39532
|
-
endpoint: "https://api.
|
|
39802
|
+
endpoint: "https://api.corenel.ai/api",
|
|
39533
39803
|
stateDir: corenelDir2(),
|
|
39534
39804
|
maxChainDepth: 8,
|
|
39535
39805
|
addUnder: [],
|
|
39536
39806
|
cloneUnder: []
|
|
39537
39807
|
};
|
|
39808
|
+
let hostSet = false;
|
|
39538
39809
|
for (let i2 = 0; i2 < argv.length; i2++) {
|
|
39539
39810
|
const a2 = argv[i2];
|
|
39540
39811
|
if (isHelpFlag(a2)) {
|
|
@@ -39542,10 +39813,12 @@ function parseArgs(argv) {
|
|
|
39542
39813
|
process.exit(0);
|
|
39543
39814
|
}
|
|
39544
39815
|
if (a2 === "--port") out.port = Number(argv[++i2]);
|
|
39545
|
-
else if (a2 === "--host")
|
|
39546
|
-
|
|
39547
|
-
|
|
39548
|
-
else if (a2 === "--
|
|
39816
|
+
else if (a2 === "--host") {
|
|
39817
|
+
out.host = argv[++i2];
|
|
39818
|
+
hostSet = true;
|
|
39819
|
+
} else if (a2 === "--root") out.roots.push(resolve7(argv[++i2]));
|
|
39820
|
+
else if (a2 === "--allow-add-under") out.addUnder.push(resolve7(argv[++i2]));
|
|
39821
|
+
else if (a2 === "--clone-under") out.cloneUnder.push(resolve7(argv[++i2]));
|
|
39549
39822
|
else if (a2 === "--allow-origin") out.allowOrigins.push(argv[++i2]);
|
|
39550
39823
|
else if (a2 === "--keep-transcripts") out.keepTranscripts = true;
|
|
39551
39824
|
else if (a2 === "--allow-shell") out.allowShell = true;
|
|
@@ -39556,8 +39829,8 @@ function parseArgs(argv) {
|
|
|
39556
39829
|
} else if (a2 === "--msb") out.msbBin = argv[++i2];
|
|
39557
39830
|
else if (a2 === "--guest-image") out.guestImage = argv[++i2];
|
|
39558
39831
|
else if (a2 === "--allow-lan") out.allowLan = true;
|
|
39559
|
-
else if (a2 === "--tls-cert") out.tlsCert =
|
|
39560
|
-
else if (a2 === "--tls-key") out.tlsKey =
|
|
39832
|
+
else if (a2 === "--tls-cert") out.tlsCert = resolve7(argv[++i2]);
|
|
39833
|
+
else if (a2 === "--tls-key") out.tlsKey = resolve7(argv[++i2]);
|
|
39561
39834
|
else if (a2 === "--self-signed") out.selfSigned = true;
|
|
39562
39835
|
else if (a2 === "--tunnel") out.tunnel = argv[++i2];
|
|
39563
39836
|
else if (a2 === "--tunnel-name") out.tunnelName = argv[++i2];
|
|
@@ -39572,7 +39845,7 @@ function parseArgs(argv) {
|
|
|
39572
39845
|
else if (a2 === "--acp-auth") out.acpAuth = argv[++i2];
|
|
39573
39846
|
else if (a2 === "--agent") out.acpAgentName = argv[++i2];
|
|
39574
39847
|
else if (a2 === "--max-chain-depth") out.maxChainDepth = Number(argv[++i2]);
|
|
39575
|
-
else if (a2 === "--state-dir") out.stateDir =
|
|
39848
|
+
else if (a2 === "--state-dir") out.stateDir = resolve7(argv[++i2]);
|
|
39576
39849
|
else if (a2 === "--name") out.name = argv[++i2];
|
|
39577
39850
|
else if (a2 === "--sidecar" || a2 === "start" || a2 === "--") {
|
|
39578
39851
|
} else throw new Error(`unknown argument: ${a2}
|
|
@@ -39580,6 +39853,10 @@ valid flags: ${KNOWN_FLAGS.join(" ")}`);
|
|
|
39580
39853
|
}
|
|
39581
39854
|
out.addUnder = [...new Set(out.addUnder)];
|
|
39582
39855
|
out.cloneUnder = [...new Set(out.cloneUnder)];
|
|
39856
|
+
if (out.allowLan) {
|
|
39857
|
+
if (!hostSet) out.host = "0.0.0.0";
|
|
39858
|
+
if (!out.tlsCert && !out.tlsKey) out.selfSigned = true;
|
|
39859
|
+
}
|
|
39583
39860
|
return out;
|
|
39584
39861
|
}
|
|
39585
39862
|
function validateArgs(args) {
|
|
@@ -39616,12 +39893,12 @@ function assertDirectory(path, flag2) {
|
|
|
39616
39893
|
|
|
39617
39894
|
// src/roots.ts
|
|
39618
39895
|
import { promises as fs11 } from "node:fs";
|
|
39619
|
-
import { resolve as
|
|
39896
|
+
import { resolve as resolve8 } from "node:path";
|
|
39620
39897
|
var DISABLED = "adding working directories is not enabled (no --allow-add-under)";
|
|
39621
39898
|
function createRootsController(opts) {
|
|
39622
39899
|
const roots = opts.roots;
|
|
39623
|
-
const areas = [...new Set(opts.areas.map((a2) =>
|
|
39624
|
-
const cloneAreas = [...new Set((opts.cloneAreas ?? []).map((a2) =>
|
|
39900
|
+
const areas = [...new Set(opts.areas.map((a2) => resolve8(a2)))];
|
|
39901
|
+
const cloneAreas = [...new Set((opts.cloneAreas ?? []).map((a2) => resolve8(a2)))];
|
|
39625
39902
|
const subs = /* @__PURE__ */ new Set();
|
|
39626
39903
|
const snapshot = () => ({ root: roots[0], roots: [...roots] });
|
|
39627
39904
|
async function assertInArea(abs) {
|
|
@@ -39649,8 +39926,8 @@ function createRootsController(opts) {
|
|
|
39649
39926
|
cloneAreas,
|
|
39650
39927
|
snapshot,
|
|
39651
39928
|
async addFromClone(path) {
|
|
39652
|
-
const abs =
|
|
39653
|
-
if (roots.some((r2) =>
|
|
39929
|
+
const abs = resolve8(path);
|
|
39930
|
+
if (roots.some((r2) => resolve8(r2) === abs)) return;
|
|
39654
39931
|
if (!cloneAreas.length) throw new Error("cloning repositories is not enabled (no --clone-under)");
|
|
39655
39932
|
if (!cloneAreas.some((a2) => withinRoot(a2, abs))) {
|
|
39656
39933
|
throw new Error(`checkout is outside every --clone-under directory: ${abs}`);
|
|
@@ -39668,14 +39945,14 @@ function createRootsController(opts) {
|
|
|
39668
39945
|
async browse(path) {
|
|
39669
39946
|
if (!areas.length) throw new Error(DISABLED);
|
|
39670
39947
|
if (path === void 0) return [...areas];
|
|
39671
|
-
const abs =
|
|
39948
|
+
const abs = resolve8(path);
|
|
39672
39949
|
await assertInArea(abs);
|
|
39673
39950
|
const entries = await fs11.readdir(abs, { withFileTypes: true });
|
|
39674
39951
|
return entries.filter((e2) => e2.isDirectory()).map((e2) => e2.name);
|
|
39675
39952
|
},
|
|
39676
39953
|
async add(path) {
|
|
39677
|
-
const abs =
|
|
39678
|
-
if (roots.some((r2) =>
|
|
39954
|
+
const abs = resolve8(path);
|
|
39955
|
+
if (roots.some((r2) => resolve8(r2) === abs)) return;
|
|
39679
39956
|
await assertInArea(abs);
|
|
39680
39957
|
const st2 = await fs11.stat(abs);
|
|
39681
39958
|
if (!st2.isDirectory()) throw new Error(`not a directory: ${abs}`);
|
|
@@ -39694,7 +39971,7 @@ function createRootsController(opts) {
|
|
|
39694
39971
|
// src/session/gitSource.ts
|
|
39695
39972
|
import { spawn as spawn6 } from "node:child_process";
|
|
39696
39973
|
import { promises as fs12 } from "node:fs";
|
|
39697
|
-
import { join as join12, resolve as
|
|
39974
|
+
import { join as join12, resolve as resolve9 } from "node:path";
|
|
39698
39975
|
var DEFAULT_TIMEOUT_MS3 = 10 * 6e4;
|
|
39699
39976
|
var ALLOWED_SCHEMES = ["https://", "ssh://", "git+ssh://"];
|
|
39700
39977
|
var SCP_LIKE = /^[A-Za-z0-9_.-]+@[A-Za-z0-9_.-]+:[A-Za-z0-9_./~-]+$/;
|
|
@@ -39780,7 +40057,7 @@ function failed(what, r2) {
|
|
|
39780
40057
|
${said}` : ""}`);
|
|
39781
40058
|
}
|
|
39782
40059
|
function createGitSource(deps) {
|
|
39783
|
-
const areas = [...new Set(deps.areas.map((a2) =>
|
|
40060
|
+
const areas = [...new Set(deps.areas.map((a2) => resolve9(a2)))];
|
|
39784
40061
|
async function assertInArea(abs) {
|
|
39785
40062
|
if (!areas.length) throw new Error(DISABLED2);
|
|
39786
40063
|
if (!areas.some((a2) => withinRoot(a2, abs))) {
|
|
@@ -39981,8 +40258,8 @@ var JsonRpcPeer = class {
|
|
|
39981
40258
|
return Promise.reject(new RpcError({ code: RPC_TRANSPORT_CLOSED, message: "transport closed" }));
|
|
39982
40259
|
}
|
|
39983
40260
|
const id = this.nextId++;
|
|
39984
|
-
return new Promise((
|
|
39985
|
-
this.pending.set(id, { resolve:
|
|
40261
|
+
return new Promise((resolve10, reject) => {
|
|
40262
|
+
this.pending.set(id, { resolve: resolve10, reject });
|
|
39986
40263
|
this.write({ jsonrpc: "2.0", id, method, ...params !== void 0 ? { params } : {} });
|
|
39987
40264
|
});
|
|
39988
40265
|
}
|
|
@@ -41086,6 +41363,13 @@ async function main() {
|
|
|
41086
41363
|
await runHostsCli(rawArgv.slice(1));
|
|
41087
41364
|
return;
|
|
41088
41365
|
}
|
|
41366
|
+
if (rawArgv[0] === "sessions") {
|
|
41367
|
+
const rest = rawArgv.slice(1);
|
|
41368
|
+
const at2 = rest.indexOf("--msb");
|
|
41369
|
+
const msbBin = at2 >= 0 && rest[at2 + 1] ? rest[at2 + 1] : process.env.MSB_BIN ?? "msb";
|
|
41370
|
+
process.exitCode = await runSessionsCli(rest, { msbBin, wsl: process.platform === "win32" });
|
|
41371
|
+
return;
|
|
41372
|
+
}
|
|
41089
41373
|
if (rawArgv[0] === "login" || rawArgv[0] === "logout" || rawArgv[0] === "auth") {
|
|
41090
41374
|
const sub = rawArgv[0];
|
|
41091
41375
|
const parsed = parseArgs(rawArgv.slice(1));
|
|
@@ -41408,7 +41692,7 @@ async function main() {
|
|
|
41408
41692
|
);
|
|
41409
41693
|
if (args.open) {
|
|
41410
41694
|
const loopback = `${handle.secure ? "wss" : "ws"}://127.0.0.1:${handle.port}`;
|
|
41411
|
-
const target = `${args.appUrl.replace(/\/$/, "")}
|
|
41695
|
+
const target = `${args.appUrl.replace(/\/$/, "")}#sidecar=${encodeURIComponent(loopback)}&token=${encodeURIComponent(token)}`;
|
|
41412
41696
|
process.stdout.write(` opening ${args.appUrl} (auto-pairing)\u2026
|
|
41413
41697
|
`);
|
|
41414
41698
|
openBrowser2(target);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corenel/sidecar",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Elastic-2.0",
|
|
6
6
|
"description": "Prompd sidecar — a local capability server. Run it next to Prompd (prompd.app) so the browser app can reach your machine: local LLMs (Ollama/LM Studio/vLLM) without CORS, your filesystem, and (opt-in) shell.",
|
|
@@ -26,26 +26,25 @@
|
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
|
-
"scripts": {
|
|
30
|
-
"build": "node build.mjs",
|
|
31
|
-
"prepublishOnly": "node build.mjs",
|
|
32
|
-
"start": "tsx src/cli.ts",
|
|
33
|
-
"typecheck": "tsc --noEmit",
|
|
34
|
-
"verify": "tsx src/verify.ts"
|
|
35
|
-
},
|
|
36
29
|
"dependencies": {
|
|
37
30
|
"selfsigned": "^2.4.1",
|
|
38
31
|
"ws": "^8.18.0"
|
|
39
32
|
},
|
|
40
33
|
"devDependencies": {
|
|
41
|
-
"@corenel/protocol": "workspace:*",
|
|
42
|
-
"@corenel/harness": "workspace:*",
|
|
43
|
-
"@corenel/tools-node": "workspace:*",
|
|
44
|
-
"@corenel/crew": "workspace:*",
|
|
45
34
|
"@types/node": "^24.13.1",
|
|
46
35
|
"@types/ws": "^8.5.13",
|
|
47
36
|
"esbuild": "^0.21.5",
|
|
48
37
|
"tsx": "^4.19.2",
|
|
49
|
-
"typescript": "^5.9.3"
|
|
38
|
+
"typescript": "^5.9.3",
|
|
39
|
+
"@corenel/protocol": "0.3.2",
|
|
40
|
+
"@corenel/harness": "0.3.2",
|
|
41
|
+
"@corenel/tools-node": "0.2.0",
|
|
42
|
+
"@corenel/crew": "0.0.0"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "node build.mjs",
|
|
46
|
+
"start": "tsx src/cli.ts",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"verify": "tsx src/verify.ts"
|
|
50
49
|
}
|
|
51
|
-
}
|
|
50
|
+
}
|