@byokit/herdr 0.4.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
+ export { installMuse, museReadiness, MUSE_INSTALL_URL } from './muse.ts';
2
+ export type { InstallMuseOptions, MuseReadiness, MuseInstallReceipt, MuseInstallResult } from './muse.ts';
1
3
  export { HERDR_VERSION, HERDR_PROTOCOL } from './constants.ts';
4
+ export { accountKinds, accountKind, type AccountKind } from './kinds.ts';
2
5
  export { HerdrKit } from './kit.ts';
3
6
  export { agentWords, stateWords, words, WORDS, type WordKey } from './words.ts';
4
7
  export { agentProbePath, extraPathDirs, runStatusCommand, agentInstallState, isAutoInstallShim, resolveAgentBinary, classifyStartFailure } from './agents.ts';
5
- export type { AgentCliSignIn, AgentInstallProbe, AgentInstallState, AgentLaunchFailureReason, AgentReadiness, AgentStartEvent, AgentStatusOptions, AgentStatusRunner, AgentRef, AgentStatus, BlockedAgent, HerdrEvent, HerdrEventName, HerdrEventOf, HerdrKitOptions, HerdrMethod, HerdrMethods, HerdrParams, HerdrProtocolRange, HerdrResult, HerdrSnapshot, HerdrState, HerdrSubscription, HerdrSubscribeStop, HerdrTransport, Move, MoveToAccount, MoveToAccountResult, MoveResult, OpenSignInTab, PromptReceipt, StartAgent, TerminalSession, AgentTurnEnd, AgentTurnOptions, AgentTurnFiles, AgentTurnResult, AgentTurnResultPolicy, } from './types.ts';
8
+ export type { AgentCliSignIn, AgentInstallProbe, AgentInstallState, AgentLaunchFailureReason, AgentReadiness, AgentStartEvent, AgentStatusOptions, AgentStatusRunner, AgentRef, AgentStatus, BlockedAgent, HerdrEvent, HerdrEventName, HerdrEventOf, HerdrKitOptions, HerdrMethod, HerdrMethods, HerdrParams, HerdrProtocolRange, HerdrResult, HerdrSnapshot, HerdrState, HerdrSubscription, HerdrSubscribeStop, HerdrTransport, BusyHandoff, Move, MoveToAccount, MoveToAccountResult, MoveResult, OpenSignInTab, PromptReceipt, StartAgent, TerminalSession, AgentTurnEnd, AgentTurnOptions, AgentTurnFiles, AgentTurnResult, AgentTurnResultPolicy, } from './types.ts';
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  // `@byokit/herdr` — the Herdr runtime kit (Node host side). The phone and browser side lives in `./device`, the
2
2
  // host-side link adapter in `./link`; the fake Herdr and contract suite arrive with H6 in `./testing`.
3
+ export { installMuse, museReadiness, MUSE_INSTALL_URL } from "./muse.js";
3
4
  export { HERDR_VERSION, HERDR_PROTOCOL } from "./constants.js";
5
+ export { accountKinds, accountKind } from "./kinds.js";
4
6
  export { HerdrKit } from "./kit.js";
5
7
  export { agentWords, stateWords, words, WORDS } from "./words.js";
6
8
  export { agentProbePath, extraPathDirs, runStatusCommand, agentInstallState, isAutoInstallShim, resolveAgentBinary, classifyStartFailure } from "./agents.js";
@@ -0,0 +1,20 @@
1
+ /** Pinned capability data, not login readiness or native move qualification. */
2
+ export type AccountKind = {
3
+ kind: string;
4
+ aliases: string[];
5
+ aliasPattern?: string;
6
+ folderVar?: string;
7
+ resume: boolean;
8
+ sessionKinds: ('id' | 'path')[];
9
+ resumeArgs?: string[];
10
+ loginLabel: string;
11
+ billing: 'unknown';
12
+ offer: 'explicit';
13
+ upstream: {
14
+ version: string;
15
+ revision: string;
16
+ source: string;
17
+ };
18
+ };
19
+ export declare function accountKinds(): AccountKind[];
20
+ export declare function accountKind(kind: string): AccountKind | undefined;
package/dist/kinds.js ADDED
@@ -0,0 +1,6 @@
1
+ import table from './kinds.json' with { type: 'json' };
2
+ export function accountKinds() { return structuredClone(table); }
3
+ export function accountKind(kind) {
4
+ return accountKinds().find((row) => row.kind === kind || row.aliases.includes(kind)
5
+ || (row.aliasPattern !== undefined && new RegExp(row.aliasPattern).test(kind)));
6
+ }
@@ -0,0 +1,503 @@
1
+ [
2
+ {
3
+ "kind": "agy",
4
+ "aliases": [
5
+ "antigravity",
6
+ "antigravity-cli"
7
+ ],
8
+ "folderVar": "ANTIGRAVITY_CLI_CONFIG_DIR",
9
+ "resume": true,
10
+ "sessionKinds": [
11
+ "id"
12
+ ],
13
+ "resumeArgs": [
14
+ "--conversation",
15
+ "{session}"
16
+ ],
17
+ "loginLabel": "Sign in to this account on this computer",
18
+ "billing": "unknown",
19
+ "offer": "explicit",
20
+ "upstream": {
21
+ "version": "0.9.1",
22
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
23
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
24
+ }
25
+ },
26
+ {
27
+ "kind": "amp",
28
+ "aliases": [
29
+ "amp-local"
30
+ ],
31
+ "resume": false,
32
+ "sessionKinds": [],
33
+ "loginLabel": "One sign-in per computer user",
34
+ "billing": "unknown",
35
+ "offer": "explicit",
36
+ "upstream": {
37
+ "version": "0.9.1",
38
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
39
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
40
+ }
41
+ },
42
+ {
43
+ "kind": "claude",
44
+ "aliases": [
45
+ "claude-code"
46
+ ],
47
+ "folderVar": "CLAUDE_CONFIG_DIR",
48
+ "resume": true,
49
+ "sessionKinds": [
50
+ "id"
51
+ ],
52
+ "resumeArgs": [
53
+ "--resume",
54
+ "{session}"
55
+ ],
56
+ "loginLabel": "Sign in to this account on this computer",
57
+ "billing": "unknown",
58
+ "offer": "explicit",
59
+ "upstream": {
60
+ "version": "0.9.1",
61
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
62
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
63
+ }
64
+ },
65
+ {
66
+ "kind": "cline",
67
+ "aliases": [
68
+ ".cline"
69
+ ],
70
+ "resume": false,
71
+ "sessionKinds": [],
72
+ "loginLabel": "One sign-in per computer user",
73
+ "billing": "unknown",
74
+ "offer": "explicit",
75
+ "upstream": {
76
+ "version": "0.9.1",
77
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
78
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
79
+ }
80
+ },
81
+ {
82
+ "kind": "codex",
83
+ "aliases": [],
84
+ "folderVar": "CODEX_HOME",
85
+ "resume": true,
86
+ "sessionKinds": [
87
+ "id"
88
+ ],
89
+ "resumeArgs": [
90
+ "resume",
91
+ "{session}"
92
+ ],
93
+ "loginLabel": "Sign in to this account on this computer",
94
+ "billing": "unknown",
95
+ "offer": "explicit",
96
+ "upstream": {
97
+ "version": "0.9.1",
98
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
99
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
100
+ }
101
+ },
102
+ {
103
+ "kind": "copilot",
104
+ "aliases": [
105
+ "github-copilot",
106
+ "ghcs"
107
+ ],
108
+ "folderVar": "COPILOT_HOME",
109
+ "resume": true,
110
+ "sessionKinds": [
111
+ "id"
112
+ ],
113
+ "resumeArgs": [
114
+ "--resume={session}"
115
+ ],
116
+ "loginLabel": "Sign in to this account on this computer",
117
+ "billing": "unknown",
118
+ "offer": "explicit",
119
+ "upstream": {
120
+ "version": "0.9.1",
121
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
122
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
123
+ }
124
+ },
125
+ {
126
+ "kind": "cursor",
127
+ "aliases": [
128
+ "cursor-agent"
129
+ ],
130
+ "folderVar": "CURSOR_CONFIG_DIR",
131
+ "resume": true,
132
+ "sessionKinds": [
133
+ "id"
134
+ ],
135
+ "resumeArgs": [
136
+ "--resume",
137
+ "{session}"
138
+ ],
139
+ "loginLabel": "Sign in to this account on this computer",
140
+ "billing": "unknown",
141
+ "offer": "explicit",
142
+ "upstream": {
143
+ "version": "0.9.1",
144
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
145
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
146
+ }
147
+ },
148
+ {
149
+ "kind": "devin",
150
+ "aliases": [
151
+ "devin-cli",
152
+ "devin cli"
153
+ ],
154
+ "resume": true,
155
+ "sessionKinds": [
156
+ "id"
157
+ ],
158
+ "resumeArgs": [
159
+ "--resume",
160
+ "{session}"
161
+ ],
162
+ "loginLabel": "One sign-in per computer user",
163
+ "billing": "unknown",
164
+ "offer": "explicit",
165
+ "upstream": {
166
+ "version": "0.9.1",
167
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
168
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
169
+ }
170
+ },
171
+ {
172
+ "kind": "droid",
173
+ "aliases": [],
174
+ "resume": true,
175
+ "sessionKinds": [
176
+ "id"
177
+ ],
178
+ "resumeArgs": [
179
+ "--resume",
180
+ "{session}"
181
+ ],
182
+ "loginLabel": "One sign-in per computer user",
183
+ "billing": "unknown",
184
+ "offer": "explicit",
185
+ "upstream": {
186
+ "version": "0.9.1",
187
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
188
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
189
+ }
190
+ },
191
+ {
192
+ "kind": "gemini",
193
+ "aliases": [],
194
+ "resume": false,
195
+ "sessionKinds": [],
196
+ "loginLabel": "One sign-in per computer user",
197
+ "billing": "unknown",
198
+ "offer": "explicit",
199
+ "upstream": {
200
+ "version": "0.9.1",
201
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
202
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
203
+ }
204
+ },
205
+ {
206
+ "kind": "grok",
207
+ "aliases": [
208
+ "grok-build"
209
+ ],
210
+ "folderVar": "GROK_HOME",
211
+ "resume": true,
212
+ "sessionKinds": [
213
+ "id"
214
+ ],
215
+ "resumeArgs": [
216
+ "--resume",
217
+ "{session}"
218
+ ],
219
+ "loginLabel": "Sign in to this account on this computer",
220
+ "billing": "unknown",
221
+ "offer": "explicit",
222
+ "upstream": {
223
+ "version": "0.9.1",
224
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
225
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
226
+ }
227
+ },
228
+ {
229
+ "kind": "hermes",
230
+ "aliases": [
231
+ "hermes-agent"
232
+ ],
233
+ "folderVar": "HERMES_HOME",
234
+ "resume": true,
235
+ "sessionKinds": [
236
+ "id"
237
+ ],
238
+ "resumeArgs": [
239
+ "--resume",
240
+ "{session}"
241
+ ],
242
+ "loginLabel": "Sign in to this account on this computer",
243
+ "billing": "unknown",
244
+ "offer": "explicit",
245
+ "upstream": {
246
+ "version": "0.9.1",
247
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
248
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
249
+ }
250
+ },
251
+ {
252
+ "kind": "kilo",
253
+ "aliases": [
254
+ "kilo-code",
255
+ "kilo code"
256
+ ],
257
+ "resume": true,
258
+ "sessionKinds": [
259
+ "id"
260
+ ],
261
+ "resumeArgs": [
262
+ "--session",
263
+ "{session}"
264
+ ],
265
+ "loginLabel": "One sign-in per computer user",
266
+ "billing": "unknown",
267
+ "offer": "explicit",
268
+ "upstream": {
269
+ "version": "0.9.1",
270
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
271
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
272
+ }
273
+ },
274
+ {
275
+ "kind": "kimi",
276
+ "aliases": [
277
+ "kimi-code",
278
+ "kimi code"
279
+ ],
280
+ "folderVar": "KIMI_CODE_HOME",
281
+ "resume": true,
282
+ "sessionKinds": [
283
+ "id"
284
+ ],
285
+ "resumeArgs": [
286
+ "--session",
287
+ "{session}"
288
+ ],
289
+ "loginLabel": "Sign in to this account on this computer",
290
+ "billing": "unknown",
291
+ "offer": "explicit",
292
+ "upstream": {
293
+ "version": "0.9.1",
294
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
295
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
296
+ }
297
+ },
298
+ {
299
+ "kind": "kiro",
300
+ "aliases": [
301
+ "kiro-cli"
302
+ ],
303
+ "resume": false,
304
+ "sessionKinds": [],
305
+ "loginLabel": "One sign-in per computer user",
306
+ "billing": "unknown",
307
+ "offer": "explicit",
308
+ "upstream": {
309
+ "version": "0.9.1",
310
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
311
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
312
+ }
313
+ },
314
+ {
315
+ "kind": "letta",
316
+ "aliases": [
317
+ "letta-code",
318
+ "letta code"
319
+ ],
320
+ "resume": true,
321
+ "sessionKinds": [
322
+ "id"
323
+ ],
324
+ "loginLabel": "One sign-in per computer user",
325
+ "billing": "unknown",
326
+ "offer": "explicit",
327
+ "upstream": {
328
+ "version": "0.9.1",
329
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
330
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
331
+ }
332
+ },
333
+ {
334
+ "kind": "maki",
335
+ "aliases": [],
336
+ "resume": false,
337
+ "sessionKinds": [],
338
+ "loginLabel": "One sign-in per computer user",
339
+ "billing": "unknown",
340
+ "offer": "explicit",
341
+ "upstream": {
342
+ "version": "0.9.1",
343
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
344
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
345
+ }
346
+ },
347
+ {
348
+ "kind": "mastracode",
349
+ "aliases": [
350
+ "mastra-code",
351
+ "mastra code"
352
+ ],
353
+ "resume": true,
354
+ "sessionKinds": [
355
+ "id"
356
+ ],
357
+ "resumeArgs": [
358
+ "--thread",
359
+ "{session}"
360
+ ],
361
+ "loginLabel": "One sign-in per computer user",
362
+ "billing": "unknown",
363
+ "offer": "explicit",
364
+ "upstream": {
365
+ "version": "0.9.1",
366
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
367
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
368
+ }
369
+ },
370
+ {
371
+ "kind": "muse",
372
+ "aliases": [
373
+ "muse-code",
374
+ "muse-cli"
375
+ ],
376
+ "aliasPattern": "^muse-bin-[0-9]",
377
+ "resume": false,
378
+ "sessionKinds": [],
379
+ "loginLabel": "One sign-in per computer user",
380
+ "billing": "unknown",
381
+ "offer": "explicit",
382
+ "upstream": {
383
+ "version": "0.9.1",
384
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
385
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
386
+ }
387
+ },
388
+ {
389
+ "kind": "omp",
390
+ "aliases": [],
391
+ "folderVar": "PI_CODING_AGENT_DIR",
392
+ "resume": true,
393
+ "sessionKinds": [
394
+ "id",
395
+ "path"
396
+ ],
397
+ "resumeArgs": [
398
+ "--resume={session}"
399
+ ],
400
+ "loginLabel": "Sign in to this account on this computer",
401
+ "billing": "unknown",
402
+ "offer": "explicit",
403
+ "upstream": {
404
+ "version": "0.9.1",
405
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
406
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
407
+ }
408
+ },
409
+ {
410
+ "kind": "opencode",
411
+ "aliases": [
412
+ "opencode2",
413
+ "open-code"
414
+ ],
415
+ "resume": true,
416
+ "sessionKinds": [
417
+ "id"
418
+ ],
419
+ "resumeArgs": [
420
+ "--session",
421
+ "{session}"
422
+ ],
423
+ "loginLabel": "One sign-in per computer user",
424
+ "billing": "unknown",
425
+ "offer": "explicit",
426
+ "upstream": {
427
+ "version": "0.9.1",
428
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
429
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
430
+ }
431
+ },
432
+ {
433
+ "kind": "pi",
434
+ "aliases": [],
435
+ "folderVar": "PI_CODING_AGENT_DIR",
436
+ "resume": true,
437
+ "sessionKinds": [
438
+ "id",
439
+ "path"
440
+ ],
441
+ "resumeArgs": [
442
+ "--session",
443
+ "{session}"
444
+ ],
445
+ "loginLabel": "Sign in to this account on this computer",
446
+ "billing": "unknown",
447
+ "offer": "explicit",
448
+ "upstream": {
449
+ "version": "0.9.1",
450
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
451
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
452
+ }
453
+ },
454
+ {
455
+ "kind": "qodercli",
456
+ "aliases": [
457
+ "qoderclicn",
458
+ "qoder",
459
+ "qodercn"
460
+ ],
461
+ "folderVar": "QODER_CONFIG_DIR",
462
+ "resume": true,
463
+ "sessionKinds": [
464
+ "id"
465
+ ],
466
+ "resumeArgs": [
467
+ "--resume",
468
+ "{session}"
469
+ ],
470
+ "loginLabel": "Sign in to this account on this computer",
471
+ "billing": "unknown",
472
+ "offer": "explicit",
473
+ "upstream": {
474
+ "version": "0.9.1",
475
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
476
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
477
+ }
478
+ },
479
+ {
480
+ "kind": "qwen",
481
+ "aliases": [
482
+ "qwen-code",
483
+ "qwen code"
484
+ ],
485
+ "folderVar": "QWEN_HOME",
486
+ "resume": true,
487
+ "sessionKinds": [
488
+ "id"
489
+ ],
490
+ "resumeArgs": [
491
+ "--resume",
492
+ "{session}"
493
+ ],
494
+ "loginLabel": "Sign in to this account on this computer",
495
+ "billing": "unknown",
496
+ "offer": "explicit",
497
+ "upstream": {
498
+ "version": "0.9.1",
499
+ "revision": "065ef9d6a531c49fb8bee7e818ef837065b21ee9",
500
+ "source": "src/detect/mod.rs; src/integration/env.rs; src/agent_resume.rs"
501
+ }
502
+ }
503
+ ]
package/dist/kit.js CHANGED
@@ -139,6 +139,7 @@ export class HerdrKit {
139
139
  this.accountPanes = createAccountPanes({ call: this.callAny, startAgent: (o) => this.startAgent(o) });
140
140
  this.agents = createAgents({ call: this.callAny, snapshot: () => this.snapshot(),
141
141
  reread: (paneId) => this.reread(paneId),
142
+ launchEnv: () => o.mode === 'own' ? this.supervisor.env() : undefined,
142
143
  emitStart: (e) => { for (const fn of [...this.startListeners])
143
144
  try {
144
145
  fn(e);
@@ -0,0 +1,6 @@
1
+ import type { Call } from './agents.ts';
2
+ export type LaunchEnvironment = {
3
+ env: Record<string, string>;
4
+ unset: string[];
5
+ };
6
+ export declare function prepareLaunchEnv(call: Call, paneId: string, launch: LaunchEnvironment, timeout: number): Promise<void>;
@@ -0,0 +1,71 @@
1
+ // The pinned agent.start launches through the pane shell. Values stay in a private host file,
2
+ // never terminal text or argv. Only an idle POSIX shell may source it; preparation fails closed.
3
+ import { randomBytes } from 'node:crypto';
4
+ import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
5
+ import { tmpdir } from 'node:os';
6
+ import { join } from 'node:path';
7
+ const quote = (v) => `'${v.replaceAll("'", "'\\''")}'`;
8
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
9
+ export async function prepareLaunchEnv(call, paneId, launch, timeout) {
10
+ let dir;
11
+ try {
12
+ if (!Number.isFinite(timeout) || timeout <= 0)
13
+ throw new Error();
14
+ const entries = Object.entries(launch.env);
15
+ const unset = [...launch.unset];
16
+ const names = [...entries.map(([key]) => key), ...unset];
17
+ if (names.some((key) => !/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
18
+ || entries.some(([, value]) => typeof value !== 'string' || /[\r\n\0]/.test(value))
19
+ || unset.some((key) => Object.hasOwn(launch.env, key)))
20
+ throw new Error();
21
+ const deadline = Date.now() + timeout;
22
+ // Do not send shell input to an agent or another foreground program.
23
+ for (;;) {
24
+ const result = await call('pane.process_info', { pane_id: paneId }, Math.max(1, deadline - Date.now()));
25
+ const info = result?.process_info;
26
+ if (info?.shell_pid && info.foreground_processes?.length === 1
27
+ && info.foreground_processes[0]?.pid === info.shell_pid
28
+ && /^(?:-)?(?:ba|z|da|k)?sh$/.test(info.foreground_processes[0].name))
29
+ break;
30
+ if (Date.now() >= deadline)
31
+ throw new Error();
32
+ await sleep(Math.min(100, Math.max(1, deadline - Date.now())));
33
+ }
34
+ const marker = `BYOKIT_ENV_${randomBytes(16).toString('hex')}`;
35
+ dir = mkdtempSync(join(tmpdir(), 'byokit-env-'));
36
+ const file = join(dir, 'prepare.sh');
37
+ const steps = [
38
+ 'set +x +v',
39
+ // Remove exports absent from the clean result too: a pane may inherit more than the host.
40
+ // The pipeline is private; neither values nor variable listings reach the terminal.
41
+ `for BYOKIT_ENV_KEY in $(/usr/bin/env | /usr/bin/cut -d= -f1); do
42
+ case "$BYOKIT_ENV_KEY" in ''|[!A-Za-z_]*|*[!A-Za-z0-9_]*) continue ;; esac
43
+ case "$BYOKIT_ENV_KEY" in ${entries.length ? entries.map(([key]) => key).join('|') : 'BYOKIT_ENV_KEY'}) ;; *) unset "$BYOKIT_ENV_KEY" 2>/dev/null || return 1 ;; esac
44
+ done`,
45
+ 'unset BYOKIT_ENV_KEY',
46
+ ...unset.map((key) => `unset ${key}`),
47
+ ...entries.map(([key, value]) => `export ${key}=${quote(value)}`),
48
+ ...unset.map((key) => `test "\${${key}+present}" = ''`),
49
+ ...entries.map(([key, value]) => `test "\${${key}+present}" = present && test "$${key}" = ${quote(value)}`),
50
+ `printf '%s\\n' ${quote(marker)}`,
51
+ ];
52
+ writeFileSync(file, steps.join(' &&\n') + '\n', { mode: 0o600, flag: 'wx' });
53
+ await call('pane.send_text', { pane_id: paneId, text: `set +x +v; . ${quote(file)}\n` }, Math.max(1, deadline - Date.now()));
54
+ for (;;) {
55
+ const result = await call('pane.read', { pane_id: paneId, source: 'recent_unwrapped', lines: 40,
56
+ format: 'text', strip_ansi: true }, Math.max(1, deadline - Date.now()));
57
+ if (result?.read?.text?.split(/\r?\n/).some((line) => line.trim() === marker))
58
+ return;
59
+ if (Date.now() >= deadline)
60
+ throw new Error();
61
+ await sleep(Math.min(100, Math.max(1, deadline - Date.now())));
62
+ }
63
+ }
64
+ catch {
65
+ throw Object.assign(new Error('This pane could not use that sign-in.'), { code: 'env_mismatch' });
66
+ }
67
+ finally {
68
+ if (dir !== undefined)
69
+ rmSync(dir, { recursive: true, force: true });
70
+ }
71
+ }