@haven_ai/connect 0.1.27-alpha.0 → 0.1.29-alpha.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 +68 -0
- package/dist/cli.cjs +997 -188
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +999 -190
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1009 -188
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +195 -5
- package/dist/index.d.ts +195 -5
- package/dist/index.js +1007 -191
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -125,6 +125,12 @@ interface StoredCredentialPaths {
|
|
|
125
125
|
interface WriteCredentialInput {
|
|
126
126
|
baseDir?: string;
|
|
127
127
|
agentId: string;
|
|
128
|
+
/**
|
|
129
|
+
* #1696: wiring slug. Named agents live at ~/.haven/agents/<slug>/ (stable
|
|
130
|
+
* across a re-key by construction — the slug never rotates); unnamed keep
|
|
131
|
+
* the historical ~/.haven/agents/<agent-uuid>/. Both schemes coexist.
|
|
132
|
+
*/
|
|
133
|
+
serverName?: string;
|
|
128
134
|
apiKey: string;
|
|
129
135
|
delegateKey: string;
|
|
130
136
|
delegateAddress: string;
|
|
@@ -161,6 +167,69 @@ interface RuntimeProfile {
|
|
|
161
167
|
}
|
|
162
168
|
declare function runtimeProfile(runtime: string | undefined, env?: NodeJS.ProcessEnv): RuntimeProfile;
|
|
163
169
|
declare function normalizeRuntime(runtime: string | undefined, env?: NodeJS.ProcessEnv): RuntimeId;
|
|
170
|
+
/** The flag values a refusal message should offer. Mirrors RuntimeId. */
|
|
171
|
+
declare const RUNTIME_FLAG_VALUES: "claude-code, codex-cli, codex-desktop, cursor, vscode, vscode-insiders, claude-desktop, hermes, other";
|
|
172
|
+
interface RuntimeSelection {
|
|
173
|
+
runtime: RuntimeId | null;
|
|
174
|
+
source: 'force' | 'detected' | 'explicit' | 'prompted' | 'none';
|
|
175
|
+
/** Set when a confident environment detection overrode a contradicting explicit hint (#1672). */
|
|
176
|
+
overrodeHint?: RuntimeId;
|
|
177
|
+
/** Set when a supplied hint was not a runtime name at all and detection carried the run (#1719). */
|
|
178
|
+
discardedHint?: string;
|
|
179
|
+
}
|
|
180
|
+
interface RuntimeResolutionOptions {
|
|
181
|
+
env?: NodeJS.ProcessEnv;
|
|
182
|
+
/**
|
|
183
|
+
* Rung 3b (#1719): the harness an AGENT executing this command reported for
|
|
184
|
+
* ITSELF, when detection found nothing to go on.
|
|
185
|
+
*
|
|
186
|
+
* It deliberately enters at the same precedence as `--runtime`, which is
|
|
187
|
+
* what makes it safe: a hint can only ever fill a vacuum, and loses to a
|
|
188
|
+
* confident detection exactly as #1672 made it. In practice the agent
|
|
189
|
+
* supplies it BY re-running with `--runtime <name>`; this field exists so a
|
|
190
|
+
* programmatic caller can pass a self-report without pretending to be a
|
|
191
|
+
* command-line flag, and so the ladder names the rung it has.
|
|
192
|
+
*/
|
|
193
|
+
selfReported?: string;
|
|
194
|
+
/**
|
|
195
|
+
* Rung 4 (#1719): ask a human at an interactive terminal which of the
|
|
196
|
+
* clients installed on this machine to configure. Injected as a thunk so
|
|
197
|
+
* the ladder stays a policy function — the scan, the readline prompt, and
|
|
198
|
+
* the "nothing writable is installed" refusal all live in
|
|
199
|
+
* `installed-clients.ts`. Omitted (`--json`, no TTY, library callers) means
|
|
200
|
+
* the rung is skipped entirely, not answered with a guess.
|
|
201
|
+
*/
|
|
202
|
+
promptForRuntime?: () => Promise<RuntimeId>;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Runtime resolution, detection-first (#1672) and self-resolving (#1719).
|
|
206
|
+
*
|
|
207
|
+
* The setup command carries no `--runtime`; the connector works out the
|
|
208
|
+
* runtime it is executing inside. Precedence:
|
|
209
|
+
*
|
|
210
|
+
* 1. `--runtime-force <name>` — always wins (unknown name refuses).
|
|
211
|
+
* 2. Environment detection over a CONTRADICTING hint. Detection only fires
|
|
212
|
+
* inside a real agent shell, where writing a different client's config is
|
|
213
|
+
* almost surely wrong — the claude-desktop-hint-in-Claude-Code dead end
|
|
214
|
+
* this exists to close.
|
|
215
|
+
* 3. An explicit `--runtime`, or an agent's self-report, with no contradicting
|
|
216
|
+
* detection (the legit plain-terminal "configure Claude Desktop by hand"
|
|
217
|
+
* case — unchanged).
|
|
218
|
+
* 4. Detection alone.
|
|
219
|
+
* 5. An interactive pick among the clients actually installed here, when a
|
|
220
|
+
* human is at a TTY. The scan populates the choices; it never selects.
|
|
221
|
+
* 6. Nothing known → `runtime: null`; the caller refuses BEFORE side effects
|
|
222
|
+
* rather than guessing a config location.
|
|
223
|
+
*
|
|
224
|
+
* A hint that is not a runtime name at all is not a hint — it is a mistake, and
|
|
225
|
+
* the one thing it must never do is fall through to a config location nobody
|
|
226
|
+
* asked for. With no detection to fall back on it refuses (`runtime_unrecognized`).
|
|
227
|
+
* With a detection it loses to it, loudly, exactly like a contradicting hint:
|
|
228
|
+
* the detected client is the right write either way, and refusing there would
|
|
229
|
+
* turn every rollout window in which the dashboard learns an id before the
|
|
230
|
+
* published connector does into a hard failure.
|
|
231
|
+
*/
|
|
232
|
+
declare function resolveRuntimeSelection(explicit: string | undefined, force: string | undefined, options?: RuntimeResolutionOptions): Promise<RuntimeSelection>;
|
|
164
233
|
|
|
165
234
|
type RuntimeMcpMode = 'local_stdio' | 'hosted_plus_signer' | 'manual';
|
|
166
235
|
|
|
@@ -184,6 +253,8 @@ interface PrepareLocalMcpRuntimeInput {
|
|
|
184
253
|
signerPath: string;
|
|
185
254
|
homeDir?: string;
|
|
186
255
|
nodeVersion?: string;
|
|
256
|
+
/** #1696: wiring slug, recorded in the sidecar for per-agent inventory (#1697). */
|
|
257
|
+
serverName?: string;
|
|
187
258
|
}
|
|
188
259
|
interface PreparedLocalMcpRuntime {
|
|
189
260
|
command: string;
|
|
@@ -199,6 +270,8 @@ interface PrepareSignerRuntimeInput {
|
|
|
199
270
|
credentialDirectory: string;
|
|
200
271
|
signerPath: string;
|
|
201
272
|
homeDir?: string;
|
|
273
|
+
/** #1696: wiring slug, recorded in the sidecar for per-agent inventory (#1697). */
|
|
274
|
+
serverName?: string;
|
|
202
275
|
}
|
|
203
276
|
interface PreparedSignerRuntime {
|
|
204
277
|
/** Absolute command to register as the signer MCP `command`. */
|
|
@@ -249,6 +322,11 @@ interface RuntimeInstallInput {
|
|
|
249
322
|
* used when this is true and the runtime supports it.
|
|
250
323
|
*/
|
|
251
324
|
localMcp?: boolean;
|
|
325
|
+
/**
|
|
326
|
+
* #1695: wiring slug for a NAMED MCP pair (haven-<slug> /
|
|
327
|
+
* haven-signer-<slug>). Absent = the bare pair, unchanged from today.
|
|
328
|
+
*/
|
|
329
|
+
serverName?: string;
|
|
252
330
|
}
|
|
253
331
|
interface RuntimeInstallResult {
|
|
254
332
|
runtime: RuntimeId;
|
|
@@ -333,13 +411,30 @@ declare function runtimeInstallCapabilities(runtime: string | undefined, env?: N
|
|
|
333
411
|
restartRequired: boolean;
|
|
334
412
|
};
|
|
335
413
|
|
|
336
|
-
declare const CONNECTOR_VERSION = "0.1.
|
|
414
|
+
declare const CONNECTOR_VERSION = "0.1.29-alpha.0";
|
|
337
415
|
interface ConnectOptions {
|
|
338
416
|
setupToken: string;
|
|
339
417
|
apiBaseUrl: string;
|
|
340
418
|
runtime?: string;
|
|
419
|
+
/** #1672 escape hatch: use exactly this runtime, ignoring environment detection. */
|
|
420
|
+
runtimeForce?: string;
|
|
421
|
+
/**
|
|
422
|
+
* #1719: the harness an AGENT running this command reported for itself. Enters
|
|
423
|
+
* at the same precedence as `runtime`, so it can only fill a vacuum — never
|
|
424
|
+
* override a detected environment.
|
|
425
|
+
*/
|
|
426
|
+
runtimeSelfReport?: string;
|
|
427
|
+
/**
|
|
428
|
+
* #1719: this run may ask a human which installed client to configure. The
|
|
429
|
+
* CLI sets it for a non-`--json` run; a library caller must opt in. Combined
|
|
430
|
+
* with `deps.isTty`, it is what makes the prompt rung SKIPPED rather than
|
|
431
|
+
* answered in CI, in `--json` automation, and in library embeddings.
|
|
432
|
+
*/
|
|
433
|
+
interactive?: boolean;
|
|
341
434
|
credentialsDir?: string;
|
|
342
435
|
environmentLabel?: string;
|
|
436
|
+
/** #1696: wiring slug for a named MCP pair + slug-keyed credential dir. */
|
|
437
|
+
serverName?: string;
|
|
343
438
|
connectorVersion?: string;
|
|
344
439
|
ackSigner?: boolean;
|
|
345
440
|
ackLocalTools?: boolean;
|
|
@@ -401,6 +496,12 @@ interface ConnectDeps {
|
|
|
401
496
|
redactPaths?: boolean;
|
|
402
497
|
/** Overridable so the Node-floor refusal is testable without spawning a Node. */
|
|
403
498
|
nodeVersion?: string;
|
|
499
|
+
/** Overridable so runtime detection (#1672) is testable without faking process.env. */
|
|
500
|
+
env?: NodeJS.ProcessEnv;
|
|
501
|
+
/** Overridable so the #1719 TTY gate is testable without faking process.stdin. */
|
|
502
|
+
isTty?: boolean;
|
|
503
|
+
/** Overridable so the #1719 installed-client prompt is testable without readline. */
|
|
504
|
+
promptRuntime?: () => Promise<RuntimeId>;
|
|
404
505
|
}
|
|
405
506
|
interface ConnectResult {
|
|
406
507
|
setupId: string;
|
|
@@ -420,6 +521,11 @@ declare function completionOutcome(input: {
|
|
|
420
521
|
/**
|
|
421
522
|
* A deliberately terse failure record: error messages can contain server or
|
|
422
523
|
* filesystem detail, while this public contract must remain safe to serialize.
|
|
524
|
+
*
|
|
525
|
+
* #1719: a `ConnectError` carries its own code and next action, so it is read
|
|
526
|
+
* rather than guessed. The regex ladder below survives only for the refusals
|
|
527
|
+
* that are still plain `Error`s — every new failure mode joins the vocabulary
|
|
528
|
+
* instead of joining that ladder.
|
|
423
529
|
*/
|
|
424
530
|
declare function failedConnectOutcome(runtimeHint: string | undefined, error: unknown): ConnectOutcome;
|
|
425
531
|
/**
|
|
@@ -452,6 +558,12 @@ interface ParsedCli {
|
|
|
452
558
|
/** #1589: diagnosis mode — no setup token required. */
|
|
453
559
|
doctor: boolean;
|
|
454
560
|
repair: boolean;
|
|
561
|
+
/** #1681: retire an agent credential directory in place — no token required. */
|
|
562
|
+
tombstone?: {
|
|
563
|
+
directory: string;
|
|
564
|
+
reason?: string;
|
|
565
|
+
replacedBy?: string;
|
|
566
|
+
};
|
|
455
567
|
}
|
|
456
568
|
declare function parseArgs(argv: string[], env?: NodeJS.ProcessEnv): ParsedCli;
|
|
457
569
|
declare function helpText(): string;
|
|
@@ -459,13 +571,91 @@ declare function helpText(): string;
|
|
|
459
571
|
declare function redactSecrets(value: string): string;
|
|
460
572
|
declare function shortAddress(address: string): string;
|
|
461
573
|
|
|
574
|
+
/**
|
|
575
|
+
* The connector's machine-readable failure vocabulary (#1719).
|
|
576
|
+
*
|
|
577
|
+
* Before this, a refusal was a bare `throw new Error(...)` and the automation
|
|
578
|
+
* contract recovered a code by regex-matching the message in
|
|
579
|
+
* `failedConnectOutcome`. That works only for as long as nobody rewords a
|
|
580
|
+
* sentence, and it gives the caller nothing to branch on that the wording did
|
|
581
|
+
* not accidentally provide. Every refusal this module fronts carries:
|
|
582
|
+
*
|
|
583
|
+
* - `code` — stable, snake_case, safe to switch on;
|
|
584
|
+
* - `nextAction` — the one thing to do next, in the same snake_case shape the
|
|
585
|
+
* install-status contract already uses for `next_action`;
|
|
586
|
+
* - `message` — human/agent prose, still the thing printed to a terminal.
|
|
587
|
+
*
|
|
588
|
+
* Codes are additive and never renamed: a consumer pinned to an older
|
|
589
|
+
* connector must keep recognising the ones it already knows.
|
|
590
|
+
*/
|
|
591
|
+
declare class ConnectError extends Error {
|
|
592
|
+
readonly code: string;
|
|
593
|
+
readonly nextAction: string;
|
|
594
|
+
constructor(code: string, message: string, nextAction: string);
|
|
595
|
+
}
|
|
596
|
+
declare function isConnectError(err: unknown): err is ConnectError;
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Installed-client scan + interactive pick (#1719).
|
|
600
|
+
*
|
|
601
|
+
* The rung that answers "which runtime am I configuring?" for a HUMAN in a
|
|
602
|
+
* plain terminal, where there is no agent shell to detect. Two properties hold
|
|
603
|
+
* it up, and both are load-bearing:
|
|
604
|
+
*
|
|
605
|
+
* 1. **Only clients the connector can actually write.** A row that cannot be
|
|
606
|
+
* configured is not a choice, it is a dead end wearing a choice's clothes.
|
|
607
|
+
* 2. **The scan populates the choices; it never selects.** Finding exactly one
|
|
608
|
+
* installed app tells you what EXISTS, not where the user wants their agent
|
|
609
|
+
* to run — and the cost of being wrong is an API key and a delegate key
|
|
610
|
+
* written into an app the user does not use. `scanInstalledClients` returns
|
|
611
|
+
* candidates and nothing else; only an answer typed at the prompt resolves
|
|
612
|
+
* a runtime.
|
|
613
|
+
*/
|
|
614
|
+
interface InstalledClientCandidate {
|
|
615
|
+
runtime: RuntimeId;
|
|
616
|
+
label: string;
|
|
617
|
+
/** What made this a candidate — shown at the prompt so the pick is informed. */
|
|
618
|
+
detail: string;
|
|
619
|
+
/**
|
|
620
|
+
* The config file Haven would write for this client, when it owns one.
|
|
621
|
+
* `null` for Claude Code, which is configured through its own CLI. Set
|
|
622
|
+
* regardless of which evidence found the client — `evidence` is what says
|
|
623
|
+
* whether that file exists today.
|
|
624
|
+
*/
|
|
625
|
+
configPath: string | null;
|
|
626
|
+
evidence: 'config-file' | 'client-directory';
|
|
627
|
+
}
|
|
628
|
+
interface ScanInstalledClientsOptions {
|
|
629
|
+
homeDir?: string;
|
|
630
|
+
/** Workspace root, for the project-local `.vscode/` marker. */
|
|
631
|
+
cwd?: string;
|
|
632
|
+
env?: NodeJS.ProcessEnv;
|
|
633
|
+
/** Injectable so the scan is testable without a populated home directory. */
|
|
634
|
+
exists?: (path: string) => Promise<boolean>;
|
|
635
|
+
}
|
|
636
|
+
declare function scanInstalledClients(options?: ScanInstalledClientsOptions): Promise<InstalledClientCandidate[]>;
|
|
637
|
+
interface PromptIo {
|
|
638
|
+
write: (text: string) => void;
|
|
639
|
+
/** Resolves the typed line, or `null` on EOF / Ctrl-C. */
|
|
640
|
+
question: (query: string) => Promise<string | null>;
|
|
641
|
+
}
|
|
642
|
+
declare function promptForInstalledClient(candidates: readonly InstalledClientCandidate[], io?: PromptIo): Promise<RuntimeId>;
|
|
643
|
+
/**
|
|
644
|
+
* The whole rung as one thunk: scan, refuse if nothing writable is installed,
|
|
645
|
+
* otherwise prompt. This is what `resolveRuntimeSelection` calls, which is why
|
|
646
|
+
* the registry needs no knowledge of the filesystem or of readline.
|
|
647
|
+
*/
|
|
648
|
+
declare function resolveRuntimeByInstalledClientPrompt(options?: ScanInstalledClientsOptions & {
|
|
649
|
+
io?: PromptIo;
|
|
650
|
+
}): Promise<RuntimeId>;
|
|
651
|
+
|
|
462
652
|
declare const MCP_RUNTIME_MANIFEST: {
|
|
463
653
|
readonly mcpPackage: "@haven_ai/mcp";
|
|
464
|
-
readonly mcpVersion: "0.1.
|
|
654
|
+
readonly mcpVersion: "0.1.29-alpha.0";
|
|
465
655
|
readonly sdkPackage: "@haven_ai/sdk";
|
|
466
|
-
readonly sdkVersion: "0.1.
|
|
656
|
+
readonly sdkVersion: "0.1.29-alpha.0";
|
|
467
657
|
readonly signerPackage: "@haven_ai/signer";
|
|
468
|
-
readonly signerVersion: "0.1.
|
|
658
|
+
readonly signerVersion: "0.1.29-alpha.0";
|
|
469
659
|
readonly minimumNodeVersion: "22.0.0";
|
|
470
660
|
readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
|
|
471
661
|
readonly requiredTools: readonly string[];
|
|
@@ -481,4 +671,4 @@ declare function mcpPackageSpec(): string;
|
|
|
481
671
|
declare function sdkPackageSpec(): string;
|
|
482
672
|
declare function signerPackageSpec(): string;
|
|
483
673
|
|
|
484
|
-
export { CONNECTOR_VERSION, CONNECT_OUTCOME_SCHEMA_VERSION, type ConnectApiClient, type ConnectDeps, type ConnectOptions, type ConnectOutcome, type ConnectOutcomeStatus, type ConnectResult, type LocalDelegateKey, MCP_RUNTIME_MANIFEST, type ParsedCli, type PrepareSignerRuntimeInput, type PreparedSignerRuntime, type RegisterSetupInput, type RegisterSetupResponse, type ResolveSetupInput, type ResolvedSetup, type RuntimeId, type RuntimeInstallInput, type RuntimeInstallResult, type RuntimeProfile, type StoredCredentialPaths, type UpdateInstallStatusInput, type WriteCredentialInput, completionOutcome, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, failedConnectOutcome, generateDelegateKey, helpText, installRuntime, mcpPackageSpec, normalizeRuntime, parseArgs, prepareSignerRuntime, redactSecrets, runConnect, runtimeInstallCapabilities, runtimeProfile, sdkPackageSpec, shortAddress, signerPackageSpec, writeCredentialFiles };
|
|
674
|
+
export { CONNECTOR_VERSION, CONNECT_OUTCOME_SCHEMA_VERSION, type ConnectApiClient, type ConnectDeps, ConnectError, type ConnectOptions, type ConnectOutcome, type ConnectOutcomeStatus, type ConnectResult, type InstalledClientCandidate, type LocalDelegateKey, MCP_RUNTIME_MANIFEST, type ParsedCli, type PrepareSignerRuntimeInput, type PreparedSignerRuntime, type PromptIo, RUNTIME_FLAG_VALUES, type RegisterSetupInput, type RegisterSetupResponse, type ResolveSetupInput, type ResolvedSetup, type RuntimeId, type RuntimeInstallInput, type RuntimeInstallResult, type RuntimeProfile, type RuntimeResolutionOptions, type RuntimeSelection, type ScanInstalledClientsOptions, type StoredCredentialPaths, type UpdateInstallStatusInput, type WriteCredentialInput, completionOutcome, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, failedConnectOutcome, generateDelegateKey, helpText, installRuntime, isConnectError, mcpPackageSpec, normalizeRuntime, parseArgs, prepareSignerRuntime, promptForInstalledClient, redactSecrets, resolveRuntimeByInstalledClientPrompt, resolveRuntimeSelection, runConnect, runtimeInstallCapabilities, runtimeProfile, scanInstalledClients, sdkPackageSpec, shortAddress, signerPackageSpec, writeCredentialFiles };
|
package/dist/index.d.ts
CHANGED
|
@@ -125,6 +125,12 @@ interface StoredCredentialPaths {
|
|
|
125
125
|
interface WriteCredentialInput {
|
|
126
126
|
baseDir?: string;
|
|
127
127
|
agentId: string;
|
|
128
|
+
/**
|
|
129
|
+
* #1696: wiring slug. Named agents live at ~/.haven/agents/<slug>/ (stable
|
|
130
|
+
* across a re-key by construction — the slug never rotates); unnamed keep
|
|
131
|
+
* the historical ~/.haven/agents/<agent-uuid>/. Both schemes coexist.
|
|
132
|
+
*/
|
|
133
|
+
serverName?: string;
|
|
128
134
|
apiKey: string;
|
|
129
135
|
delegateKey: string;
|
|
130
136
|
delegateAddress: string;
|
|
@@ -161,6 +167,69 @@ interface RuntimeProfile {
|
|
|
161
167
|
}
|
|
162
168
|
declare function runtimeProfile(runtime: string | undefined, env?: NodeJS.ProcessEnv): RuntimeProfile;
|
|
163
169
|
declare function normalizeRuntime(runtime: string | undefined, env?: NodeJS.ProcessEnv): RuntimeId;
|
|
170
|
+
/** The flag values a refusal message should offer. Mirrors RuntimeId. */
|
|
171
|
+
declare const RUNTIME_FLAG_VALUES: "claude-code, codex-cli, codex-desktop, cursor, vscode, vscode-insiders, claude-desktop, hermes, other";
|
|
172
|
+
interface RuntimeSelection {
|
|
173
|
+
runtime: RuntimeId | null;
|
|
174
|
+
source: 'force' | 'detected' | 'explicit' | 'prompted' | 'none';
|
|
175
|
+
/** Set when a confident environment detection overrode a contradicting explicit hint (#1672). */
|
|
176
|
+
overrodeHint?: RuntimeId;
|
|
177
|
+
/** Set when a supplied hint was not a runtime name at all and detection carried the run (#1719). */
|
|
178
|
+
discardedHint?: string;
|
|
179
|
+
}
|
|
180
|
+
interface RuntimeResolutionOptions {
|
|
181
|
+
env?: NodeJS.ProcessEnv;
|
|
182
|
+
/**
|
|
183
|
+
* Rung 3b (#1719): the harness an AGENT executing this command reported for
|
|
184
|
+
* ITSELF, when detection found nothing to go on.
|
|
185
|
+
*
|
|
186
|
+
* It deliberately enters at the same precedence as `--runtime`, which is
|
|
187
|
+
* what makes it safe: a hint can only ever fill a vacuum, and loses to a
|
|
188
|
+
* confident detection exactly as #1672 made it. In practice the agent
|
|
189
|
+
* supplies it BY re-running with `--runtime <name>`; this field exists so a
|
|
190
|
+
* programmatic caller can pass a self-report without pretending to be a
|
|
191
|
+
* command-line flag, and so the ladder names the rung it has.
|
|
192
|
+
*/
|
|
193
|
+
selfReported?: string;
|
|
194
|
+
/**
|
|
195
|
+
* Rung 4 (#1719): ask a human at an interactive terminal which of the
|
|
196
|
+
* clients installed on this machine to configure. Injected as a thunk so
|
|
197
|
+
* the ladder stays a policy function — the scan, the readline prompt, and
|
|
198
|
+
* the "nothing writable is installed" refusal all live in
|
|
199
|
+
* `installed-clients.ts`. Omitted (`--json`, no TTY, library callers) means
|
|
200
|
+
* the rung is skipped entirely, not answered with a guess.
|
|
201
|
+
*/
|
|
202
|
+
promptForRuntime?: () => Promise<RuntimeId>;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Runtime resolution, detection-first (#1672) and self-resolving (#1719).
|
|
206
|
+
*
|
|
207
|
+
* The setup command carries no `--runtime`; the connector works out the
|
|
208
|
+
* runtime it is executing inside. Precedence:
|
|
209
|
+
*
|
|
210
|
+
* 1. `--runtime-force <name>` — always wins (unknown name refuses).
|
|
211
|
+
* 2. Environment detection over a CONTRADICTING hint. Detection only fires
|
|
212
|
+
* inside a real agent shell, where writing a different client's config is
|
|
213
|
+
* almost surely wrong — the claude-desktop-hint-in-Claude-Code dead end
|
|
214
|
+
* this exists to close.
|
|
215
|
+
* 3. An explicit `--runtime`, or an agent's self-report, with no contradicting
|
|
216
|
+
* detection (the legit plain-terminal "configure Claude Desktop by hand"
|
|
217
|
+
* case — unchanged).
|
|
218
|
+
* 4. Detection alone.
|
|
219
|
+
* 5. An interactive pick among the clients actually installed here, when a
|
|
220
|
+
* human is at a TTY. The scan populates the choices; it never selects.
|
|
221
|
+
* 6. Nothing known → `runtime: null`; the caller refuses BEFORE side effects
|
|
222
|
+
* rather than guessing a config location.
|
|
223
|
+
*
|
|
224
|
+
* A hint that is not a runtime name at all is not a hint — it is a mistake, and
|
|
225
|
+
* the one thing it must never do is fall through to a config location nobody
|
|
226
|
+
* asked for. With no detection to fall back on it refuses (`runtime_unrecognized`).
|
|
227
|
+
* With a detection it loses to it, loudly, exactly like a contradicting hint:
|
|
228
|
+
* the detected client is the right write either way, and refusing there would
|
|
229
|
+
* turn every rollout window in which the dashboard learns an id before the
|
|
230
|
+
* published connector does into a hard failure.
|
|
231
|
+
*/
|
|
232
|
+
declare function resolveRuntimeSelection(explicit: string | undefined, force: string | undefined, options?: RuntimeResolutionOptions): Promise<RuntimeSelection>;
|
|
164
233
|
|
|
165
234
|
type RuntimeMcpMode = 'local_stdio' | 'hosted_plus_signer' | 'manual';
|
|
166
235
|
|
|
@@ -184,6 +253,8 @@ interface PrepareLocalMcpRuntimeInput {
|
|
|
184
253
|
signerPath: string;
|
|
185
254
|
homeDir?: string;
|
|
186
255
|
nodeVersion?: string;
|
|
256
|
+
/** #1696: wiring slug, recorded in the sidecar for per-agent inventory (#1697). */
|
|
257
|
+
serverName?: string;
|
|
187
258
|
}
|
|
188
259
|
interface PreparedLocalMcpRuntime {
|
|
189
260
|
command: string;
|
|
@@ -199,6 +270,8 @@ interface PrepareSignerRuntimeInput {
|
|
|
199
270
|
credentialDirectory: string;
|
|
200
271
|
signerPath: string;
|
|
201
272
|
homeDir?: string;
|
|
273
|
+
/** #1696: wiring slug, recorded in the sidecar for per-agent inventory (#1697). */
|
|
274
|
+
serverName?: string;
|
|
202
275
|
}
|
|
203
276
|
interface PreparedSignerRuntime {
|
|
204
277
|
/** Absolute command to register as the signer MCP `command`. */
|
|
@@ -249,6 +322,11 @@ interface RuntimeInstallInput {
|
|
|
249
322
|
* used when this is true and the runtime supports it.
|
|
250
323
|
*/
|
|
251
324
|
localMcp?: boolean;
|
|
325
|
+
/**
|
|
326
|
+
* #1695: wiring slug for a NAMED MCP pair (haven-<slug> /
|
|
327
|
+
* haven-signer-<slug>). Absent = the bare pair, unchanged from today.
|
|
328
|
+
*/
|
|
329
|
+
serverName?: string;
|
|
252
330
|
}
|
|
253
331
|
interface RuntimeInstallResult {
|
|
254
332
|
runtime: RuntimeId;
|
|
@@ -333,13 +411,30 @@ declare function runtimeInstallCapabilities(runtime: string | undefined, env?: N
|
|
|
333
411
|
restartRequired: boolean;
|
|
334
412
|
};
|
|
335
413
|
|
|
336
|
-
declare const CONNECTOR_VERSION = "0.1.
|
|
414
|
+
declare const CONNECTOR_VERSION = "0.1.29-alpha.0";
|
|
337
415
|
interface ConnectOptions {
|
|
338
416
|
setupToken: string;
|
|
339
417
|
apiBaseUrl: string;
|
|
340
418
|
runtime?: string;
|
|
419
|
+
/** #1672 escape hatch: use exactly this runtime, ignoring environment detection. */
|
|
420
|
+
runtimeForce?: string;
|
|
421
|
+
/**
|
|
422
|
+
* #1719: the harness an AGENT running this command reported for itself. Enters
|
|
423
|
+
* at the same precedence as `runtime`, so it can only fill a vacuum — never
|
|
424
|
+
* override a detected environment.
|
|
425
|
+
*/
|
|
426
|
+
runtimeSelfReport?: string;
|
|
427
|
+
/**
|
|
428
|
+
* #1719: this run may ask a human which installed client to configure. The
|
|
429
|
+
* CLI sets it for a non-`--json` run; a library caller must opt in. Combined
|
|
430
|
+
* with `deps.isTty`, it is what makes the prompt rung SKIPPED rather than
|
|
431
|
+
* answered in CI, in `--json` automation, and in library embeddings.
|
|
432
|
+
*/
|
|
433
|
+
interactive?: boolean;
|
|
341
434
|
credentialsDir?: string;
|
|
342
435
|
environmentLabel?: string;
|
|
436
|
+
/** #1696: wiring slug for a named MCP pair + slug-keyed credential dir. */
|
|
437
|
+
serverName?: string;
|
|
343
438
|
connectorVersion?: string;
|
|
344
439
|
ackSigner?: boolean;
|
|
345
440
|
ackLocalTools?: boolean;
|
|
@@ -401,6 +496,12 @@ interface ConnectDeps {
|
|
|
401
496
|
redactPaths?: boolean;
|
|
402
497
|
/** Overridable so the Node-floor refusal is testable without spawning a Node. */
|
|
403
498
|
nodeVersion?: string;
|
|
499
|
+
/** Overridable so runtime detection (#1672) is testable without faking process.env. */
|
|
500
|
+
env?: NodeJS.ProcessEnv;
|
|
501
|
+
/** Overridable so the #1719 TTY gate is testable without faking process.stdin. */
|
|
502
|
+
isTty?: boolean;
|
|
503
|
+
/** Overridable so the #1719 installed-client prompt is testable without readline. */
|
|
504
|
+
promptRuntime?: () => Promise<RuntimeId>;
|
|
404
505
|
}
|
|
405
506
|
interface ConnectResult {
|
|
406
507
|
setupId: string;
|
|
@@ -420,6 +521,11 @@ declare function completionOutcome(input: {
|
|
|
420
521
|
/**
|
|
421
522
|
* A deliberately terse failure record: error messages can contain server or
|
|
422
523
|
* filesystem detail, while this public contract must remain safe to serialize.
|
|
524
|
+
*
|
|
525
|
+
* #1719: a `ConnectError` carries its own code and next action, so it is read
|
|
526
|
+
* rather than guessed. The regex ladder below survives only for the refusals
|
|
527
|
+
* that are still plain `Error`s — every new failure mode joins the vocabulary
|
|
528
|
+
* instead of joining that ladder.
|
|
423
529
|
*/
|
|
424
530
|
declare function failedConnectOutcome(runtimeHint: string | undefined, error: unknown): ConnectOutcome;
|
|
425
531
|
/**
|
|
@@ -452,6 +558,12 @@ interface ParsedCli {
|
|
|
452
558
|
/** #1589: diagnosis mode — no setup token required. */
|
|
453
559
|
doctor: boolean;
|
|
454
560
|
repair: boolean;
|
|
561
|
+
/** #1681: retire an agent credential directory in place — no token required. */
|
|
562
|
+
tombstone?: {
|
|
563
|
+
directory: string;
|
|
564
|
+
reason?: string;
|
|
565
|
+
replacedBy?: string;
|
|
566
|
+
};
|
|
455
567
|
}
|
|
456
568
|
declare function parseArgs(argv: string[], env?: NodeJS.ProcessEnv): ParsedCli;
|
|
457
569
|
declare function helpText(): string;
|
|
@@ -459,13 +571,91 @@ declare function helpText(): string;
|
|
|
459
571
|
declare function redactSecrets(value: string): string;
|
|
460
572
|
declare function shortAddress(address: string): string;
|
|
461
573
|
|
|
574
|
+
/**
|
|
575
|
+
* The connector's machine-readable failure vocabulary (#1719).
|
|
576
|
+
*
|
|
577
|
+
* Before this, a refusal was a bare `throw new Error(...)` and the automation
|
|
578
|
+
* contract recovered a code by regex-matching the message in
|
|
579
|
+
* `failedConnectOutcome`. That works only for as long as nobody rewords a
|
|
580
|
+
* sentence, and it gives the caller nothing to branch on that the wording did
|
|
581
|
+
* not accidentally provide. Every refusal this module fronts carries:
|
|
582
|
+
*
|
|
583
|
+
* - `code` — stable, snake_case, safe to switch on;
|
|
584
|
+
* - `nextAction` — the one thing to do next, in the same snake_case shape the
|
|
585
|
+
* install-status contract already uses for `next_action`;
|
|
586
|
+
* - `message` — human/agent prose, still the thing printed to a terminal.
|
|
587
|
+
*
|
|
588
|
+
* Codes are additive and never renamed: a consumer pinned to an older
|
|
589
|
+
* connector must keep recognising the ones it already knows.
|
|
590
|
+
*/
|
|
591
|
+
declare class ConnectError extends Error {
|
|
592
|
+
readonly code: string;
|
|
593
|
+
readonly nextAction: string;
|
|
594
|
+
constructor(code: string, message: string, nextAction: string);
|
|
595
|
+
}
|
|
596
|
+
declare function isConnectError(err: unknown): err is ConnectError;
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Installed-client scan + interactive pick (#1719).
|
|
600
|
+
*
|
|
601
|
+
* The rung that answers "which runtime am I configuring?" for a HUMAN in a
|
|
602
|
+
* plain terminal, where there is no agent shell to detect. Two properties hold
|
|
603
|
+
* it up, and both are load-bearing:
|
|
604
|
+
*
|
|
605
|
+
* 1. **Only clients the connector can actually write.** A row that cannot be
|
|
606
|
+
* configured is not a choice, it is a dead end wearing a choice's clothes.
|
|
607
|
+
* 2. **The scan populates the choices; it never selects.** Finding exactly one
|
|
608
|
+
* installed app tells you what EXISTS, not where the user wants their agent
|
|
609
|
+
* to run — and the cost of being wrong is an API key and a delegate key
|
|
610
|
+
* written into an app the user does not use. `scanInstalledClients` returns
|
|
611
|
+
* candidates and nothing else; only an answer typed at the prompt resolves
|
|
612
|
+
* a runtime.
|
|
613
|
+
*/
|
|
614
|
+
interface InstalledClientCandidate {
|
|
615
|
+
runtime: RuntimeId;
|
|
616
|
+
label: string;
|
|
617
|
+
/** What made this a candidate — shown at the prompt so the pick is informed. */
|
|
618
|
+
detail: string;
|
|
619
|
+
/**
|
|
620
|
+
* The config file Haven would write for this client, when it owns one.
|
|
621
|
+
* `null` for Claude Code, which is configured through its own CLI. Set
|
|
622
|
+
* regardless of which evidence found the client — `evidence` is what says
|
|
623
|
+
* whether that file exists today.
|
|
624
|
+
*/
|
|
625
|
+
configPath: string | null;
|
|
626
|
+
evidence: 'config-file' | 'client-directory';
|
|
627
|
+
}
|
|
628
|
+
interface ScanInstalledClientsOptions {
|
|
629
|
+
homeDir?: string;
|
|
630
|
+
/** Workspace root, for the project-local `.vscode/` marker. */
|
|
631
|
+
cwd?: string;
|
|
632
|
+
env?: NodeJS.ProcessEnv;
|
|
633
|
+
/** Injectable so the scan is testable without a populated home directory. */
|
|
634
|
+
exists?: (path: string) => Promise<boolean>;
|
|
635
|
+
}
|
|
636
|
+
declare function scanInstalledClients(options?: ScanInstalledClientsOptions): Promise<InstalledClientCandidate[]>;
|
|
637
|
+
interface PromptIo {
|
|
638
|
+
write: (text: string) => void;
|
|
639
|
+
/** Resolves the typed line, or `null` on EOF / Ctrl-C. */
|
|
640
|
+
question: (query: string) => Promise<string | null>;
|
|
641
|
+
}
|
|
642
|
+
declare function promptForInstalledClient(candidates: readonly InstalledClientCandidate[], io?: PromptIo): Promise<RuntimeId>;
|
|
643
|
+
/**
|
|
644
|
+
* The whole rung as one thunk: scan, refuse if nothing writable is installed,
|
|
645
|
+
* otherwise prompt. This is what `resolveRuntimeSelection` calls, which is why
|
|
646
|
+
* the registry needs no knowledge of the filesystem or of readline.
|
|
647
|
+
*/
|
|
648
|
+
declare function resolveRuntimeByInstalledClientPrompt(options?: ScanInstalledClientsOptions & {
|
|
649
|
+
io?: PromptIo;
|
|
650
|
+
}): Promise<RuntimeId>;
|
|
651
|
+
|
|
462
652
|
declare const MCP_RUNTIME_MANIFEST: {
|
|
463
653
|
readonly mcpPackage: "@haven_ai/mcp";
|
|
464
|
-
readonly mcpVersion: "0.1.
|
|
654
|
+
readonly mcpVersion: "0.1.29-alpha.0";
|
|
465
655
|
readonly sdkPackage: "@haven_ai/sdk";
|
|
466
|
-
readonly sdkVersion: "0.1.
|
|
656
|
+
readonly sdkVersion: "0.1.29-alpha.0";
|
|
467
657
|
readonly signerPackage: "@haven_ai/signer";
|
|
468
|
-
readonly signerVersion: "0.1.
|
|
658
|
+
readonly signerVersion: "0.1.29-alpha.0";
|
|
469
659
|
readonly minimumNodeVersion: "22.0.0";
|
|
470
660
|
readonly supportedClients: readonly ["codex-cli", "codex-desktop", "claude-code"];
|
|
471
661
|
readonly requiredTools: readonly string[];
|
|
@@ -481,4 +671,4 @@ declare function mcpPackageSpec(): string;
|
|
|
481
671
|
declare function sdkPackageSpec(): string;
|
|
482
672
|
declare function signerPackageSpec(): string;
|
|
483
673
|
|
|
484
|
-
export { CONNECTOR_VERSION, CONNECT_OUTCOME_SCHEMA_VERSION, type ConnectApiClient, type ConnectDeps, type ConnectOptions, type ConnectOutcome, type ConnectOutcomeStatus, type ConnectResult, type LocalDelegateKey, MCP_RUNTIME_MANIFEST, type ParsedCli, type PrepareSignerRuntimeInput, type PreparedSignerRuntime, type RegisterSetupInput, type RegisterSetupResponse, type ResolveSetupInput, type ResolvedSetup, type RuntimeId, type RuntimeInstallInput, type RuntimeInstallResult, type RuntimeProfile, type StoredCredentialPaths, type UpdateInstallStatusInput, type WriteCredentialInput, completionOutcome, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, failedConnectOutcome, generateDelegateKey, helpText, installRuntime, mcpPackageSpec, normalizeRuntime, parseArgs, prepareSignerRuntime, redactSecrets, runConnect, runtimeInstallCapabilities, runtimeProfile, sdkPackageSpec, shortAddress, signerPackageSpec, writeCredentialFiles };
|
|
674
|
+
export { CONNECTOR_VERSION, CONNECT_OUTCOME_SCHEMA_VERSION, type ConnectApiClient, type ConnectDeps, ConnectError, type ConnectOptions, type ConnectOutcome, type ConnectOutcomeStatus, type ConnectResult, type InstalledClientCandidate, type LocalDelegateKey, MCP_RUNTIME_MANIFEST, type ParsedCli, type PrepareSignerRuntimeInput, type PreparedSignerRuntime, type PromptIo, RUNTIME_FLAG_VALUES, type RegisterSetupInput, type RegisterSetupResponse, type ResolveSetupInput, type ResolvedSetup, type RuntimeId, type RuntimeInstallInput, type RuntimeInstallResult, type RuntimeProfile, type RuntimeResolutionOptions, type RuntimeSelection, type ScanInstalledClientsOptions, type StoredCredentialPaths, type UpdateInstallStatusInput, type WriteCredentialInput, completionOutcome, createConnectApiClient, defaultAgentDirectory, delegateKeyFromPrivateKey, failedConnectOutcome, generateDelegateKey, helpText, installRuntime, isConnectError, mcpPackageSpec, normalizeRuntime, parseArgs, prepareSignerRuntime, promptForInstalledClient, redactSecrets, resolveRuntimeByInstalledClientPrompt, resolveRuntimeSelection, runConnect, runtimeInstallCapabilities, runtimeProfile, scanInstalledClients, sdkPackageSpec, shortAddress, signerPackageSpec, writeCredentialFiles };
|