@vibe-commit/capture 0.6.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/README.md +80 -5
- package/dist/agent_hooks.d.ts +8 -0
- package/dist/agent_hooks.js +31 -1
- package/dist/agent_hooks.js.map +1 -1
- package/dist/agents/claude_code.d.ts +34 -0
- package/dist/agents/claude_code.js +141 -8
- package/dist/agents/claude_code.js.map +1 -1
- package/dist/agents/codex_cli.d.ts +13 -0
- package/dist/agents/codex_cli.js +241 -2
- package/dist/agents/codex_cli.js.map +1 -1
- package/dist/agents/cursor.d.ts +34 -0
- package/dist/agents/cursor.js +115 -1
- package/dist/agents/cursor.js.map +1 -1
- package/dist/agents/session_listing.d.ts +29 -0
- package/dist/agents/session_listing.js +49 -0
- package/dist/agents/session_listing.js.map +1 -0
- package/dist/agents/types.d.ts +118 -8
- package/dist/agents/types.js +17 -3
- package/dist/agents/types.js.map +1 -1
- package/dist/commands/approval_pending.d.ts +9 -0
- package/dist/commands/approval_pending.js +23 -0
- package/dist/commands/approval_pending.js.map +1 -0
- package/dist/commands/auth.js +31 -11
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/backfill.d.ts +160 -0
- package/dist/commands/backfill.js +748 -0
- package/dist/commands/backfill.js.map +1 -0
- package/dist/commands/browser_credential.d.ts +2 -0
- package/dist/commands/browser_credential.js +31 -14
- package/dist/commands/browser_credential.js.map +1 -1
- package/dist/commands/connect.d.ts +137 -0
- package/dist/commands/connect.js +203 -109
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connect_picker.d.ts +27 -0
- package/dist/commands/connect_picker.js +415 -0
- package/dist/commands/connect_picker.js.map +1 -0
- package/dist/commands/context.d.ts +16 -0
- package/dist/commands/context.js +27 -0
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/credential_problem.d.ts +15 -4
- package/dist/commands/credential_problem.js +29 -22
- package/dist/commands/credential_problem.js.map +1 -1
- package/dist/commands/device_credential.d.ts +2 -0
- package/dist/commands/device_credential.js +16 -14
- package/dist/commands/device_credential.js.map +1 -1
- package/dist/commands/finalize.d.ts +95 -0
- package/dist/commands/finalize.js +249 -74
- package/dist/commands/finalize.js.map +1 -1
- package/dist/commands/finish_mint.d.ts +2 -6
- package/dist/commands/finish_mint.js +10 -2
- package/dist/commands/finish_mint.js.map +1 -1
- package/dist/commands/report.js +38 -30
- package/dist/commands/report.js.map +1 -1
- package/dist/commands/scan.d.ts +162 -0
- package/dist/commands/scan.js +507 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/status.js +119 -22
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/status_hooks.d.ts +14 -0
- package/dist/commands/status_hooks.js +81 -0
- package/dist/commands/status_hooks.js.map +1 -0
- package/dist/commands/status_machine.d.ts +18 -0
- package/dist/commands/status_machine.js +149 -0
- package/dist/commands/status_machine.js.map +1 -0
- package/dist/commands/why.js +44 -31
- package/dist/commands/why.js.map +1 -1
- package/dist/consent.d.ts +111 -0
- package/dist/consent.js +203 -1
- package/dist/consent.js.map +1 -1
- package/dist/copy/error_codes.d.ts +222 -0
- package/dist/copy/error_codes.js +105 -0
- package/dist/copy/error_codes.js.map +1 -0
- package/dist/copy/index.d.ts +2 -2
- package/dist/copy/index.js +2 -2
- package/dist/copy/index.js.map +1 -1
- package/dist/copy/strings.d.ts +497 -29
- package/dist/copy/strings.js +601 -35
- package/dist/copy/strings.js.map +1 -1
- package/dist/copy/time.d.ts +11 -0
- package/dist/copy/time.js +18 -0
- package/dist/copy/time.js.map +1 -1
- package/dist/credential.d.ts +5 -1
- package/dist/credential.js +2 -2
- package/dist/credential.js.map +1 -1
- package/dist/git.d.ts +43 -0
- package/dist/git.js +95 -0
- package/dist/git.js.map +1 -1
- package/dist/hooks/entry.d.ts +18 -1
- package/dist/hooks/entry.js +110 -13
- package/dist/hooks/entry.js.map +1 -1
- package/dist/hooks/post_commit.js +3 -3
- package/dist/hooks/post_commit.js.map +1 -1
- package/dist/hooks/post_rewrite.js +6 -4
- package/dist/hooks/post_rewrite.js.map +1 -1
- package/dist/hooks/session_start.d.ts +93 -0
- package/dist/hooks/session_start.js +199 -0
- package/dist/hooks/session_start.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +56 -8
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +57 -0
- package/dist/install.js +54 -20
- package/dist/install.js.map +1 -1
- package/dist/json.d.ts +32 -9
- package/dist/json.js +35 -8
- package/dist/json.js.map +1 -1
- package/dist/machine_state.d.ts +52 -0
- package/dist/machine_state.js +63 -0
- package/dist/machine_state.js.map +1 -0
- package/dist/oauth/session.d.ts +1 -0
- package/dist/org_pending.d.ts +52 -0
- package/dist/org_pending.js +109 -0
- package/dist/org_pending.js.map +1 -0
- package/dist/paths.d.ts +50 -0
- package/dist/paths.js +64 -0
- package/dist/paths.js.map +1 -1
- package/dist/picker.d.ts +180 -0
- package/dist/picker.js +477 -0
- package/dist/picker.js.map +1 -0
- package/dist/picker_checklist.d.ts +125 -0
- package/dist/picker_checklist.js +375 -0
- package/dist/picker_checklist.js.map +1 -0
- package/dist/policy.d.ts +54 -0
- package/dist/policy.js +47 -0
- package/dist/policy.js.map +1 -1
- package/dist/post.d.ts +50 -16
- package/dist/post.js +220 -16
- package/dist/post.js.map +1 -1
- package/dist/state.d.ts +6 -0
- package/dist/state.js +38 -1
- package/dist/state.js.map +1 -1
- package/dist/system_message.d.ts +8 -1
- package/dist/system_message.js +19 -1
- package/dist/system_message.js.map +1 -1
- package/dist/term.d.ts +28 -2
- package/dist/term.js +23 -2
- package/dist/term.js.map +1 -1
- package/dist/verb_help.d.ts +13 -0
- package/dist/verb_help.js +40 -0
- package/dist/verb_help.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -9
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `connect` picker flow — style guide §10.12 (0.7.0, PR 3): scan → picker → disclosure → grant y/N → sign in → hooks →
|
|
3
|
+
* (in a repo) the test capture → "Capture is on" or the held beat → backfill offer → URL.
|
|
4
|
+
*
|
|
5
|
+
* ⛔ LOADED LAZILY, AND THAT IS THE POINT OF THIS FILE BEING SEPARATE. `connect.ts` imports it with `await import(...)` at
|
|
6
|
+
* the two call sites that reach the picker. `src/index.ts` statically imports every verb, so everything `connect.ts`
|
|
7
|
+
* imports is loaded by EVERY process, a hook's included; the picker, its checklist and the scan engine are a person-at-a-
|
|
8
|
+
* terminal feature and must not ride along on the hook's load path. (Measured: no timing difference at all in 120
|
|
9
|
+
* interleaved starts, so this is for the principle and for the SIGTERM cell's sake, not for a number.)
|
|
10
|
+
* The helpers it shares with the 0.6.0 flow are exported from `connect.ts`; the import is circular only at call time.
|
|
11
|
+
*/
|
|
12
|
+
import { dialectFor } from "../agents/registry.js";
|
|
13
|
+
import { AGENT_HOOKS, COMMANDS, COMMIT_HOOK, CONNECT, PICKER, SCAN, URLS } from "../copy/index.js";
|
|
14
|
+
import { EMPTY_GRANTS, GrantsUnreadableError, grantsUnreadable, isAffirmative, normalizeOwner, normalizeSlug, ownerOfSlug, readGrants, revokeProject, updateGrants, } from "../consent.js";
|
|
15
|
+
import { EXIT } from "../exit.js";
|
|
16
|
+
import { channelCommand, connectCommandFor, installCaptureHooks } from "../install.js";
|
|
17
|
+
import { machineCapture, machineSummary, readPerClone } from "../machine_state.js";
|
|
18
|
+
import { buildModel, grantQuestion, hasAdditions, isNoChange, notUnderstoodLines, parseTyped, preChange, renderGrantBlock, renderTyped, } from "../picker.js";
|
|
19
|
+
import { runChecklist } from "../picker_checklist.js";
|
|
20
|
+
import { credentialFingerprint } from "../post.js";
|
|
21
|
+
import { metaFor } from "../credential_meta.js";
|
|
22
|
+
import { paint, renderErrorBlock, tildePath, truncatePath, wrap } from "../term.js";
|
|
23
|
+
import { signInBeat } from "./browser_credential.js";
|
|
24
|
+
import { agentHookBeat, approvalPending, approvalPendingBeat, askOrCancel, cancelled, disclosure, grantsUnreadableBlock, obtainCredential, sendTestCapture, tail, } from "./connect.js";
|
|
25
|
+
import { writeLines } from "./context.js";
|
|
26
|
+
import { pickerNotListedLines, sawNoSession, scanMachine } from "./scan.js";
|
|
27
|
+
/**
|
|
28
|
+
* `connect` from any folder: scan → picker → disclosure → grant y/N → sign in → hooks → "Capture is on" → backfill offer
|
|
29
|
+
* → URL (§10.12). At most three questions in a run (D7 · 3A): the grant, the workspace (inside the mint, only where
|
|
30
|
+
* 0.6.0 already asks it) and the backfill (PR 5's seam).
|
|
31
|
+
*
|
|
32
|
+
* ⛔ **CONSENT STAYS AHEAD OF THE CREDENTIAL, and nothing before the grant opens a transcript.** The scan, the picker and
|
|
33
|
+
* the offer read directory entries and four Codex index columns only. The grant is written BEFORE the sign-in, as the
|
|
34
|
+
* per-clone consent always was.
|
|
35
|
+
*/
|
|
36
|
+
export async function connectPicker(ctx, options, deps, here,
|
|
37
|
+
/** The working folder's keys, when it is a work tree: the in-repo path probes its session (VQ item 7). */
|
|
38
|
+
keys = null) {
|
|
39
|
+
if (grantsUnreadable(ctx.home)) {
|
|
40
|
+
writeLines(ctx.stderr, grantsUnreadableBlock(ctx));
|
|
41
|
+
return EXIT.failure;
|
|
42
|
+
}
|
|
43
|
+
// ⛔ THE NON-TTY REFUSAL COMES BEFORE THE SCAN (VQ + VT, PR 6 item 6): "Nothing was read and nothing was uploaded" stays
|
|
44
|
+
// literally true, and a CI job that pipes `connect` never walks the filesystem. The disclosure still prints first
|
|
45
|
+
// (CR-117), under the picker heading. It names the folder to run it in when `connect` runs INSIDE a repo (`here.kind === "repo"`,
|
|
46
|
+
// the folder `connectPicker` was already given, never one the scan found), cut from the left as the `local:` refusal does; from a
|
|
47
|
+
// folder that is not a repo, and from `$HOME` (a dotfiles repo there is `kind: "folder"` and the run is machine-level), it names none.
|
|
48
|
+
if (!ctx.stdinIsTty) {
|
|
49
|
+
writeLines(ctx.stdout, disclosure(ctx, true));
|
|
50
|
+
writeLines(ctx.stderr, renderErrorBlock({
|
|
51
|
+
kind: "bad",
|
|
52
|
+
code: "CONSENT_NEEDS_TTY",
|
|
53
|
+
what: CONNECT.pickerNonInteractiveWhat,
|
|
54
|
+
why: [CONNECT.pickerNonInteractiveWhy],
|
|
55
|
+
fixLabel: here !== null && here.kind === "repo"
|
|
56
|
+
? CONNECT.nonInteractiveFix(truncatePath(tildePath(here.toplevel, ctx.home), 46))
|
|
57
|
+
: CONNECT.pickerNonInteractiveFix,
|
|
58
|
+
fixes: [connectCommandFor(ctx.env, ctx.selfPath)],
|
|
59
|
+
}, ctx.colour));
|
|
60
|
+
return EXIT.usage;
|
|
61
|
+
}
|
|
62
|
+
// D17: one static beat line, overwritten once with `done` on a terminal. `ctx.colour` is false with no terminal and under
|
|
63
|
+
// NO_COLOR, where it prints plainly with no overwrite. No spinner (§13.8): the bytes are the same at any speed.
|
|
64
|
+
const beat = ` ${SCAN.beat}`;
|
|
65
|
+
if (ctx.colour)
|
|
66
|
+
ctx.stdout.write(`\n${beat}`);
|
|
67
|
+
const scanned = (deps.scan ?? scanMachine)(ctx.home, ctx.env);
|
|
68
|
+
ctx.stdout.write(ctx.colour ? `\r${beat} ${SCAN.beatDone}\n` : `\n${beat} ${SCAN.beatDone}\n`);
|
|
69
|
+
const read = readGrants(ctx.home);
|
|
70
|
+
const grants = read.kind === "ok" ? read.grants : EMPTY_GRANTS;
|
|
71
|
+
const model = buildModel({
|
|
72
|
+
repos: scanned.repos,
|
|
73
|
+
grants,
|
|
74
|
+
perClone: readPerClone(ctx.home),
|
|
75
|
+
notListed: pickerNotListedLines(scanned.notListed, connectCommandFor(ctx.env, ctx.selfPath)),
|
|
76
|
+
sawNothing: sawNoSession(scanned.notListed, ctx.home),
|
|
77
|
+
here,
|
|
78
|
+
});
|
|
79
|
+
const pick = await choose(ctx, options, deps, model);
|
|
80
|
+
if (pick.kind === "cancel")
|
|
81
|
+
return cancelled(ctx);
|
|
82
|
+
if (pick.kind === "none" || isNoChange(pick.change)) {
|
|
83
|
+
// Enter is "change nothing" (D5): no grant, no credential, and a completed consent flow (§13.7).
|
|
84
|
+
const on = machineCapture(ctx.home);
|
|
85
|
+
const line = on.kind === "on" ? PICKER.noChanges(machineSummary(on)) : PICKER.nothingGranted(connectCommandFor(ctx.env, ctx.selfPath));
|
|
86
|
+
writeLines(ctx.stdout, ["", ...wrap(line, 2)]);
|
|
87
|
+
return EXIT.ok;
|
|
88
|
+
}
|
|
89
|
+
const { change } = pick;
|
|
90
|
+
// One disclosure and one y/N cover additions and removals together, and a No changes nothing. Removals alone skip the
|
|
91
|
+
// disclosure and ask the stop question (§10.12 "The grant y/N").
|
|
92
|
+
const facts = { reposHere: reposByOwner(model), noClone: pick.noClone };
|
|
93
|
+
writeLines(ctx.stdout, hasAdditions(change) ? ["", ...disclosure(ctx, true)] : [""]);
|
|
94
|
+
writeLines(ctx.stdout, renderGrantBlock(change, facts, ctx.colour));
|
|
95
|
+
const answer = await askOrCancel(ctx, grantQuestion(change, ctx.colour, CONNECT.consentAnswers));
|
|
96
|
+
if (answer === null)
|
|
97
|
+
return cancelled(ctx);
|
|
98
|
+
if (!isAffirmative(answer)) {
|
|
99
|
+
writeLines(ctx.stdout, ["", ...wrap(CONNECT.declined, 2)]);
|
|
100
|
+
return EXIT.ok;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
applyChange(ctx, model, change);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (!(error instanceof GrantsUnreadableError))
|
|
107
|
+
throw error;
|
|
108
|
+
// Raced with an edit of `grants.json` since the check above. Nothing was written.
|
|
109
|
+
writeLines(ctx.stderr, grantsUnreadableBlock(ctx));
|
|
110
|
+
return EXIT.failure;
|
|
111
|
+
}
|
|
112
|
+
if (!hasAdditions(change)) {
|
|
113
|
+
writeLines(ctx.stdout, ["", ...wrap(PICKER.stopped, 2)]);
|
|
114
|
+
return EXIT.ok;
|
|
115
|
+
}
|
|
116
|
+
if (options.signIn === true) {
|
|
117
|
+
const code = await signInBeat(ctx, { retry: "sign-in", verify: true, ...(deps.fetch === undefined ? {} : { fetch: deps.fetch }) });
|
|
118
|
+
if (code !== EXIT.ok)
|
|
119
|
+
return code;
|
|
120
|
+
}
|
|
121
|
+
const got = await obtainCredential(ctx, deps, options, "repos");
|
|
122
|
+
if (got.kind === "exit")
|
|
123
|
+
return got.code;
|
|
124
|
+
// L11: the hooks print first. Commit hooks for every clone found of what is now on, then the agent hooks.
|
|
125
|
+
const on = onSlugs(ctx, model, change);
|
|
126
|
+
const onRepos = scanned.repos.filter((repo) => on(normalizeSlug(repo.slug)));
|
|
127
|
+
const clones = [
|
|
128
|
+
...new Set([
|
|
129
|
+
...onRepos.flatMap((repo) => repo.clones.map((clone) => clone.path)),
|
|
130
|
+
...(here !== null && here.kind === "repo" && on(normalizeSlug(here.slug)) ? [here.toplevel] : []),
|
|
131
|
+
]),
|
|
132
|
+
];
|
|
133
|
+
commitHooksStep(ctx, clones);
|
|
134
|
+
agentHookBeat(ctx);
|
|
135
|
+
// ⛔ IN A REPO, THE TEST CAPTURE RUNS BEFORE "Capture is on", AND ITS OUTCOME PICKS THE ENDING (VQ item 7, adopting VT).
|
|
136
|
+
// 0.6.0's payoff was evidence — this session, recorded, with a link — and "Capture is on" printed ahead of a result that
|
|
137
|
+
// can contradict it (an org that has not approved capture) would say the opposite of what happens next. So: hooks
|
|
138
|
+
// (L11), then the probe inside ONE hook budget (the same call the `local:` path makes), then either the held beat or
|
|
139
|
+
// "Capture is on" with the session link as the one URL line. From `~` there is no session to probe and nothing changes.
|
|
140
|
+
let probe = null;
|
|
141
|
+
if (keys !== null && here !== null && here.kind === "repo" && on(normalizeSlug(here.slug))) {
|
|
142
|
+
const { hasLocator, found } = locateTranscript(ctx, keys.worktree);
|
|
143
|
+
const { delivery } = hasLocator && found === null
|
|
144
|
+
? { delivery: null }
|
|
145
|
+
: await sendTestCapture(ctx, keys, got.credential, found);
|
|
146
|
+
probe = { hasLocator, found, delivery };
|
|
147
|
+
const pending = approvalPending(delivery);
|
|
148
|
+
if (pending !== null) {
|
|
149
|
+
// `capture_not_approved` for THIS repo (CR-110, D81): armed, waiting on an owner. Never "Capture is on" over it, and no
|
|
150
|
+
// offer to upload more into a refusal. `deliver` has recorded it, so `status` says the same.
|
|
151
|
+
approvalPendingBeat(ctx, keys.worktree, pending.ownersNotified);
|
|
152
|
+
return tail(ctx, got.unconfirmed);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// D18 · D19: "Capture is on" before the optional upload, so it is on screen within seconds of the sign-in.
|
|
156
|
+
// The block cannot know whether an organization has approved capture for a repo it did not probe: it says one may need to,
|
|
157
|
+
// when a granted owner is not the person's own account. In a repo the owner the test capture CHECKED is left out.
|
|
158
|
+
const checkedOwner = probe !== null && here !== null && answeredWith2xx(probe.delivery) ? ownerOfSlug(normalizeSlug(here.slug)) : null;
|
|
159
|
+
captureOnBlock(ctx, model, change, clones.length === 0, otherOwnersCaveat(ctx, got.credential, checkedOwner));
|
|
160
|
+
// The backfill offer. Left out (`deps.backfill`), no offer is made and the ending is the one after a no. The URL follows
|
|
161
|
+
// what LANDED (D19): the conversations list once at least one session was uploaded, whether the run finished or stopped.
|
|
162
|
+
let url = probeUrl(probe);
|
|
163
|
+
if (deps.backfill !== undefined && onRepos.length > 0) {
|
|
164
|
+
const outcome = await deps.backfill(ctx, onRepos);
|
|
165
|
+
if (outcome.kind !== "declined" && outcome.uploaded > 0)
|
|
166
|
+
url = URLS.conversations;
|
|
167
|
+
}
|
|
168
|
+
writeLines(ctx.stdout, ["", ` ${paint(ctx.colour, "accent", url)}`]);
|
|
169
|
+
return tail(ctx, got.unconfirmed);
|
|
170
|
+
}
|
|
171
|
+
/** Where the current session's transcript is, per the dialect's locator: `hasLocator` is false for an agent that has none. */
|
|
172
|
+
function locateTranscript(ctx, projectKey) {
|
|
173
|
+
const locate = dialectFor(ctx.agentId).locateCurrentTranscript;
|
|
174
|
+
return { hasLocator: locate !== undefined, found: locate === undefined ? null : locate(ctx.home, ctx.env, projectKey) };
|
|
175
|
+
}
|
|
176
|
+
/** Did the server answer any delta of the test capture with a 2xx? (`ok`, or a `later` that carries delta 1's session id.) */
|
|
177
|
+
function answeredWith2xx(delivery) {
|
|
178
|
+
return delivery?.kind === "attempted" && (delivery.disposition === "ok" || delivery.conversationId !== undefined);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Does any granted owner differ from the signed-in person's own GitHub handle? (Alexander, 2026-10-24: "Caveat for other
|
|
182
|
+
* owners".) Compared case-insensitively over the owners granted whole AND the owners of repos granted one by one; an `account`
|
|
183
|
+
* the server did not give (`null`) cannot be shown to match, so it counts as differing. Nothing granted, nothing to caveat.
|
|
184
|
+
* `account` is whatever the whoami probe or the mint recorded for this credential, so it is known by the time the block prints.
|
|
185
|
+
*
|
|
186
|
+
* ⛔ **IN A REPO, THE CHECKED OWNER DOES NOT COUNT** (Alexander, 17:20). "Checked" means the server answered ANY delta of the
|
|
187
|
+
* test capture with a 2xx — the delivery is `ok`, or it carries a `conversationId` (after PR 4a a big session can get a 2xx on
|
|
188
|
+
* delta 1 and a timeout on delta 2, which combines to `later` with delta 1's id; a 2xx proves the org approved). Every other
|
|
189
|
+
* outcome — no transcript, a `later`, a network loss — leaves this repo's owner unchecked, and it counts like any other.
|
|
190
|
+
*/
|
|
191
|
+
function otherOwnersCaveat(ctx, credential, checkedOwner) {
|
|
192
|
+
const on = machineCapture(ctx.home);
|
|
193
|
+
if (on.kind !== "on")
|
|
194
|
+
return false;
|
|
195
|
+
// The owner of the repo the test capture just checked is not "another owner": the server answered for it (see `checkedOwner`).
|
|
196
|
+
const skip = checkedOwner === null ? null : checkedOwner.toLowerCase();
|
|
197
|
+
const owners = [...on.grants.owners, ...on.grants.repos.map(ownerOfSlug)].filter((o) => o !== "" && o.toLowerCase() !== skip);
|
|
198
|
+
if (owners.length === 0)
|
|
199
|
+
return false;
|
|
200
|
+
const account = metaFor(ctx.home, credentialFingerprint(credential))?.account ?? null;
|
|
201
|
+
if (account === null)
|
|
202
|
+
return true;
|
|
203
|
+
const own = account.toLowerCase();
|
|
204
|
+
return owners.some((owner) => owner.toLowerCase() !== own);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* The one URL line after "Capture is on". From `~` (no probe) it is the dashboard, as after a no. In a repo it is the
|
|
208
|
+
* recorded session's own page when the 2xx carried its id (`DX D8`); the captures list where 0.6.0 falls back to it (a
|
|
209
|
+
* delivery with no id, an agent with no locator); and the dashboard when there was no transcript to link.
|
|
210
|
+
*/
|
|
211
|
+
function probeUrl(probe) {
|
|
212
|
+
if (probe === null)
|
|
213
|
+
return URLS.dashboard;
|
|
214
|
+
if (probe.hasLocator && probe.found === null)
|
|
215
|
+
return URLS.dashboard;
|
|
216
|
+
const id = probe.delivery?.kind === "attempted" ? probe.delivery.conversationId : undefined;
|
|
217
|
+
return id === undefined ? URLS.commits : URLS.conversation(id);
|
|
218
|
+
}
|
|
219
|
+
/** The checklist when a person is driving a real terminal (D28); the typed prompt otherwise. */
|
|
220
|
+
function useChecklist(ctx, options, model) {
|
|
221
|
+
if (options.typed === true || !ctx.stdinIsTty)
|
|
222
|
+
return false;
|
|
223
|
+
const out = ctx.stdout;
|
|
224
|
+
if (out.isTTY !== true || ctx.env.TERM === "dumb")
|
|
225
|
+
return false;
|
|
226
|
+
// The frame is erased by line count, so a terminal narrower than the frame (which soft-wraps) would leave debris. A width
|
|
227
|
+
// of 0 or none is a terminal that does not say, which is not a narrow one.
|
|
228
|
+
if (out.columns !== undefined && out.columns > 0 && out.columns < 80)
|
|
229
|
+
return false;
|
|
230
|
+
return model.onNow.length + model.owners.length + model.turnedOff.length > 0;
|
|
231
|
+
}
|
|
232
|
+
async function choose(ctx, options, deps, model) {
|
|
233
|
+
const nowMs = ctx.now().getTime();
|
|
234
|
+
if (useChecklist(ctx, options, model)) {
|
|
235
|
+
const result = await runChecklist(model, { colour: ctx.colour, nowMs, typedCommand: channelCommand(ctx.env, ctx.selfPath, COMMANDS.connectTyped) }, { input: deps.checklist?.input ?? process.stdin, output: ctx.stdout, ...deps.checklist });
|
|
236
|
+
if (result.kind === "cancel")
|
|
237
|
+
return { kind: "cancel" };
|
|
238
|
+
if (result.kind === "done")
|
|
239
|
+
return { kind: "change", change: result.change, noClone: new Set() };
|
|
240
|
+
// `t`: the typed prompt, from the same model.
|
|
241
|
+
}
|
|
242
|
+
return await typedPick(ctx, model, nowMs);
|
|
243
|
+
}
|
|
244
|
+
/** How many answers in a row the typed prompt will refuse before it gives up. */
|
|
245
|
+
const MAX_MISSES = 10;
|
|
246
|
+
/** The typed prompt (§10.12 "The picker, typed"): re-asks on any token it does not understand, never applying part. */
|
|
247
|
+
async function typedPick(ctx, model, nowMs) {
|
|
248
|
+
const pre = preChange(model);
|
|
249
|
+
let showAll = false;
|
|
250
|
+
for (;;) {
|
|
251
|
+
writeLines(ctx.stdout, renderTyped(model, { colour: ctx.colour, nowMs, showAll }));
|
|
252
|
+
let misses = 0;
|
|
253
|
+
for (;;) {
|
|
254
|
+
const answer = await askOrCancel(ctx, ` ${PICKER.promptMark}`);
|
|
255
|
+
if (answer === null)
|
|
256
|
+
return { kind: "cancel" };
|
|
257
|
+
const parsed = parseTyped(answer, model, showAll);
|
|
258
|
+
if (parsed.kind === "more") {
|
|
259
|
+
// `more` reprints with every repo shown and numbered afresh, then asks again. Nothing is chosen yet.
|
|
260
|
+
showAll = true;
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
if (parsed.kind === "error") {
|
|
264
|
+
writeLines(ctx.stdout, notUnderstoodLines(parsed.tokens));
|
|
265
|
+
// A prompt that re-asks without end is a hang for anything driving it (a closed input, a script). Ten misses in a
|
|
266
|
+
// row is somebody who is not going to get there: treat it as the Ctrl+C it is, which changes nothing.
|
|
267
|
+
misses += 1;
|
|
268
|
+
if (misses >= MAX_MISSES)
|
|
269
|
+
return { kind: "cancel" };
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (parsed.kind === "empty") {
|
|
273
|
+
// Enter. A pre-selected repo (D34) is the one thing Enter leads to the y/N with; otherwise it changes nothing.
|
|
274
|
+
return pre === null ? { kind: "none" } : { kind: "change", change: pre, noClone: new Set() };
|
|
275
|
+
}
|
|
276
|
+
return { kind: "change", change: parsed.change, noClone: new Set(parsed.noClone) };
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/** How many repos an owner row covers HERE: the same count the owner row printed (`a1 all 2 repos here`), so they agree. */
|
|
281
|
+
function reposByOwner(model) {
|
|
282
|
+
return new Map(model.owners.map((group) => [normalizeOwner(group.owner), group.repos.length]));
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Write the change. `grants.json` first (atomic, and it THROWS rather than overwrite a file it cannot read), then the
|
|
286
|
+
* per-clone consents a removal withdraws. A turned-off repo that is chosen again is re-included here: removing it from
|
|
287
|
+
* `excluded` is the exclusion lifting, and only this yes does it (`off`'s contract). It joins `repos` unless an owner
|
|
288
|
+
* grant already covers it.
|
|
289
|
+
*/
|
|
290
|
+
function applyChange(ctx, model, change) {
|
|
291
|
+
updateGrants(ctx.home, (g) => {
|
|
292
|
+
const owners = [...g.owners.filter((o) => !change.stopOwners.includes(o)), ...change.addOwners];
|
|
293
|
+
const covered = (slug) => owners.includes(ownerOfSlug(slug));
|
|
294
|
+
return {
|
|
295
|
+
disclosed_at: hasAdditions(change) ? ctx.now().toISOString() : g.disclosed_at,
|
|
296
|
+
owners,
|
|
297
|
+
repos: [
|
|
298
|
+
...g.repos.filter((r) => !change.stopRepos.includes(r)),
|
|
299
|
+
...change.addRepos,
|
|
300
|
+
...change.turnOn.filter((slug) => !covered(slug)),
|
|
301
|
+
],
|
|
302
|
+
excluded: g.excluded.filter((x) => !change.turnOn.includes(x)),
|
|
303
|
+
refused: g.refused,
|
|
304
|
+
};
|
|
305
|
+
});
|
|
306
|
+
for (const slug of change.stopClones) {
|
|
307
|
+
for (const row of model.onNow) {
|
|
308
|
+
if (row.kind !== "clone" || row.key !== slug)
|
|
309
|
+
continue;
|
|
310
|
+
for (const commonDir of row.commonDirs)
|
|
311
|
+
revokeProject(ctx.home, commonDir);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/** Is this slug on once `change` is applied? Reads the grants just written, and keeps the per-clone consents not withdrawn. */
|
|
316
|
+
function onSlugs(ctx, model, change) {
|
|
317
|
+
const read = readGrants(ctx.home);
|
|
318
|
+
const grants = read.kind === "ok" ? read.grants : EMPTY_GRANTS;
|
|
319
|
+
const kept = new Set(model.onNow.filter((r) => r.kind === "clone" && !change.stopClones.includes(r.key)).map((r) => r.key));
|
|
320
|
+
return (slug) => !grants.excluded.includes(slug) &&
|
|
321
|
+
(grants.owners.includes(ownerOfSlug(slug)) || grants.repos.includes(slug) || kept.has(slug));
|
|
322
|
+
}
|
|
323
|
+
/** `~/code/x core.hooksPath is set` — one exception row, the path cut from the left to leave the reason room (§13.4). */
|
|
324
|
+
function exceptionRow(ctx, path, reason) {
|
|
325
|
+
const room = 80 - 4 - 3 - reason.length;
|
|
326
|
+
return ` ${paint(ctx.colour, "muted", `${truncatePath(tildePath(path, ctx.home), room)} ${reason}`)}`;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* The hooks step (D13 · 7A): one beat line with a count, then an exceptions block naming ONLY the clones where hooks were
|
|
330
|
+
* not added, each with its path and reason, the fix last. `connect` runs with the user watching, so it chains a clone's
|
|
331
|
+
* existing hook (kept, runs first) and counts it as added. The only skip is `core.hooksPath`; a failed write is listed too.
|
|
332
|
+
* ⚠ Never changes the exit code, for `commitHookBeat`'s reason.
|
|
333
|
+
*/
|
|
334
|
+
function commitHooksStep(ctx, clones) {
|
|
335
|
+
if (clones.length === 0)
|
|
336
|
+
return;
|
|
337
|
+
const beat = ` ${PICKER.hooksBeat(clones.length)}`;
|
|
338
|
+
if (ctx.colour)
|
|
339
|
+
ctx.stdout.write(`\n${beat}`);
|
|
340
|
+
let added = 0;
|
|
341
|
+
let chained = 0;
|
|
342
|
+
const skipped = [];
|
|
343
|
+
for (const path of clones) {
|
|
344
|
+
const verdict = installCaptureHooks(path, ctx.selfPath).commit;
|
|
345
|
+
if (verdict.kind === "hooks-path")
|
|
346
|
+
skipped.push({ path, reason: PICKER.hooksPathReason, hooksPath: true });
|
|
347
|
+
else if (verdict.kind === "failed")
|
|
348
|
+
skipped.push({ path, reason: PICKER.hooksFailedReason, hooksPath: false });
|
|
349
|
+
else {
|
|
350
|
+
added += 1;
|
|
351
|
+
if (verdict.kind === "chained")
|
|
352
|
+
chained += 1;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const done = `${beat.padEnd(45)} ${PICKER.hooksDone}`;
|
|
356
|
+
ctx.stdout.write(ctx.colour ? `\r${done}\n` : `\n${done}\n`);
|
|
357
|
+
writeLines(ctx.stdout, [` ${paint(ctx.colour, "muted", PICKER.hooksCount(added, chained, skipped.length))}`]);
|
|
358
|
+
if (skipped.length === 0)
|
|
359
|
+
return;
|
|
360
|
+
// ⛔ EACH EXCEPTION GETS ITS OWN FIX, and only its own: `core.hooksPath` gets the shipped unset/chain pair, a write that
|
|
361
|
+
// failed gets `vibecommit connect` (run in that clone, it adds the hook with the person watching), and neither is
|
|
362
|
+
// shown the other's. Session capture is unaffected by either, so that is said once.
|
|
363
|
+
const hooksPathHit = skipped.some((s) => s.hooksPath);
|
|
364
|
+
const failedHit = skipped.some((s) => !s.hooksPath);
|
|
365
|
+
writeLines(ctx.stdout, [
|
|
366
|
+
"",
|
|
367
|
+
paint(ctx.colour, "warn", ` ${PICKER.hooksNotAdded(skipped.length)}`),
|
|
368
|
+
...skipped.map((s) => exceptionRow(ctx, s.path, s.reason)),
|
|
369
|
+
...wrap(hooksPathHit ? PICKER.hooksStillCaptured : PICKER.hooksStillCapturedOther, 2),
|
|
370
|
+
...(hooksPathHit
|
|
371
|
+
? [COMMIT_HOOK.hooksPathFixUnset, COMMIT_HOOK.hooksPathFixManual(channelCommand(ctx.env, ctx.selfPath, COMMANDS.postCommit))].map((fix) => ` ${paint(ctx.colour, "accent", fix)}`)
|
|
372
|
+
: []),
|
|
373
|
+
...(failedHit
|
|
374
|
+
? [...wrap(PICKER.hooksFailedFixLabel, 2), ` ${paint(ctx.colour, "accent", connectCommandFor(ctx.env, ctx.selfPath))}`]
|
|
375
|
+
: []),
|
|
376
|
+
]);
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* "Capture is on" (D18 · 12A, D19 · 13A): what is on, then the first proof to expect (§10.1 state 4). A new laptop whose
|
|
380
|
+
* granted owner has no clone here gets its own block. ⛔ **No variant says "Nothing else to do"**: that line stays on the
|
|
381
|
+
* 0.6.0 in-repo screen only.
|
|
382
|
+
*/
|
|
383
|
+
function captureOnBlock(ctx, model, change, noClones,
|
|
384
|
+
/** The "other owners" caveat, for owners the test capture did not check: see `otherOwnersCaveat`. */
|
|
385
|
+
caveat) {
|
|
386
|
+
// What is on NOW, read back from disk after the write: the same counts `status` and `auth` give.
|
|
387
|
+
const summary = machineSummary(machineCapture(ctx.home));
|
|
388
|
+
if (noClones) {
|
|
389
|
+
const names = [
|
|
390
|
+
...model.onNow.filter((r) => !change.stopOwners.includes(r.key) && !change.stopRepos.includes(r.key) && !change.stopClones.includes(r.key)).map((r) => (r.kind === "owner" ? `${r.key}/` : r.key)),
|
|
391
|
+
...change.addOwners.map((o) => `${o}/`),
|
|
392
|
+
...change.addRepos,
|
|
393
|
+
...change.turnOn,
|
|
394
|
+
];
|
|
395
|
+
writeLines(ctx.stdout, [
|
|
396
|
+
"",
|
|
397
|
+
...renderErrorBlock({
|
|
398
|
+
kind: "ok",
|
|
399
|
+
what: PICKER.onNewLaptop(names.length <= 3 ? names.join(", ") : summary),
|
|
400
|
+
why: [PICKER.onNewLaptopProof, AGENT_HOOKS.codexTrust, ...(caveat ? [PICKER.ownerApproval(channelCommand(ctx.env, ctx.selfPath, COMMANDS.status))] : [])],
|
|
401
|
+
}, ctx.colour),
|
|
402
|
+
]);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
writeLines(ctx.stdout, [
|
|
406
|
+
"",
|
|
407
|
+
...renderErrorBlock({
|
|
408
|
+
kind: "ok",
|
|
409
|
+
what: PICKER.onFor(summary),
|
|
410
|
+
why: [PICKER.onProof, AGENT_HOOKS.codexTrust, ...(caveat ? [PICKER.ownerApproval(channelCommand(ctx.env, ctx.selfPath, COMMANDS.status))] : [])],
|
|
411
|
+
}, ctx.colour),
|
|
412
|
+
...wrap(`${PICKER.stopOne} ${channelCommand(ctx.env, ctx.selfPath, COMMANDS.off)}`, 2),
|
|
413
|
+
]);
|
|
414
|
+
}
|
|
415
|
+
//# sourceMappingURL=connect_picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect_picker.js","sourceRoot":"","sources":["../../src/commands/connect_picker.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* the risk of a test run touching the developer's own credentials.
|
|
8
8
|
*/
|
|
9
9
|
import type { Writable } from "node:stream";
|
|
10
|
+
import { type JsonVerb } from "../json.js";
|
|
11
|
+
import { type ErrorBlock } from "../term.js";
|
|
10
12
|
export interface CommandContext {
|
|
11
13
|
readonly env: NodeJS.ProcessEnv;
|
|
12
14
|
readonly home: string;
|
|
@@ -43,3 +45,17 @@ export interface CommandContext {
|
|
|
43
45
|
readonly agentId?: string;
|
|
44
46
|
}
|
|
45
47
|
export declare function writeLines(stream: Writable, lines: readonly string[]): void;
|
|
48
|
+
/**
|
|
49
|
+
* A `bad` block, written the way the verb's mode wants it: under `--json` ONE failure document on stdout and nothing on
|
|
50
|
+
* stderr; otherwise §13.6's block on stderr. `lead` is the blank line some callers print before the block.
|
|
51
|
+
*/
|
|
52
|
+
export declare function writeFailure(ctx: CommandContext, block: Extract<ErrorBlock, {
|
|
53
|
+
kind: "bad";
|
|
54
|
+
}>, json?: JsonVerb | null, lead?: readonly string[]): void;
|
|
55
|
+
/**
|
|
56
|
+
* `NOT_A_REPO` — the one block `why`, `report` and `finalize` share. Names the folder (tilde, cut from the LEFT so the
|
|
57
|
+
* end that identifies it stays, §13.4) and says where to run it; there is no command to type, so the fix is a label.
|
|
58
|
+
*/
|
|
59
|
+
export declare function notAGitRepoBlock(ctx: CommandContext): Extract<ErrorBlock, {
|
|
60
|
+
kind: "bad";
|
|
61
|
+
}>;
|
package/dist/commands/context.js
CHANGED
|
@@ -6,9 +6,36 @@
|
|
|
6
6
|
* which is what lets the tests drive a real binary against a temp HOME without
|
|
7
7
|
* the risk of a test run touching the developer's own credentials.
|
|
8
8
|
*/
|
|
9
|
+
import { emitJsonError } from "../json.js";
|
|
10
|
+
import { ERRORS } from "../copy/index.js";
|
|
11
|
+
import { renderErrorBlock, tildePath, truncatePath } from "../term.js";
|
|
9
12
|
export function writeLines(stream, lines) {
|
|
10
13
|
if (lines.length === 0)
|
|
11
14
|
return;
|
|
12
15
|
stream.write(`${lines.join("\n")}\n`);
|
|
13
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* A `bad` block, written the way the verb's mode wants it: under `--json` ONE failure document on stdout and nothing on
|
|
19
|
+
* stderr; otherwise §13.6's block on stderr. `lead` is the blank line some callers print before the block.
|
|
20
|
+
*/
|
|
21
|
+
export function writeFailure(ctx, block, json = null, lead = []) {
|
|
22
|
+
if (json !== null) {
|
|
23
|
+
emitJsonError(ctx.stdout, json, block);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
writeLines(ctx.stderr, [...lead, ...renderErrorBlock(block, ctx.colour)]);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* `NOT_A_REPO` — the one block `why`, `report` and `finalize` share. Names the folder (tilde, cut from the LEFT so the
|
|
30
|
+
* end that identifies it stays, §13.4) and says where to run it; there is no command to type, so the fix is a label.
|
|
31
|
+
*/
|
|
32
|
+
export function notAGitRepoBlock(ctx) {
|
|
33
|
+
return {
|
|
34
|
+
kind: "bad",
|
|
35
|
+
code: "NOT_A_REPO",
|
|
36
|
+
what: ERRORS.notAGitRepo,
|
|
37
|
+
why: [ERRORS.notAGitRepoWhy(truncatePath(tildePath(ctx.cwd, ctx.home), 40))],
|
|
38
|
+
fixLabel: ERRORS.notAGitRepoFix,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
14
41
|
//# sourceMappingURL=context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAmB,MAAM,YAAY,CAAC;AAsCxF,MAAM,UAAU,UAAU,CAAC,MAAgB,EAAE,KAAwB;IACnE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAmB,EACnB,KAA2C,EAC3C,OAAwB,IAAI,EAC5B,OAA0B,EAAE;IAE5B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAmB;IAClD,OAAO;QACL,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,MAAM,CAAC,WAAW;QACxB,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5E,QAAQ,EAAE,MAAM,CAAC,cAAc;KAChC,CAAC;AACJ,CAAC"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* unreadable or insecure file: false, and the real fix (`chmod 600`, or `auth`) was one line away.
|
|
6
6
|
* It still never MINTS over a fault (D206 §5) — it only names the fault correctly.
|
|
7
7
|
*/
|
|
8
|
+
import { type ErrorBlock } from "../term.js";
|
|
8
9
|
/**
|
|
9
10
|
* The three credential problems that are worth four different fixes on an
|
|
10
11
|
* interactive surface. The hook collapses them to one `systemMessage`; here the
|
|
@@ -13,19 +14,29 @@
|
|
|
13
14
|
* None of these lines can carry credential bytes: the plaintext leaves
|
|
14
15
|
* `IngestCredential` only through `expose()`, and no copy path calls it.
|
|
15
16
|
*/
|
|
16
|
-
export declare function credentialProblem(load:
|
|
17
|
+
export declare function credentialProblem(load: CredentialLoadProblem, colour: boolean,
|
|
18
|
+
/** The channel's `auth` (`installChannel`) — `vibecommit auth` on npm, `node <path> auth` for the plugin. */
|
|
19
|
+
authCommand?: string): string[];
|
|
20
|
+
/** The three non-ok `loadCredential` kinds a stored credential can be in (`absent` is `NO_CREDENTIAL`, not a fault). */
|
|
21
|
+
export type CredentialLoadProblem = {
|
|
17
22
|
kind: "wrong-class";
|
|
18
23
|
source: "env" | "file";
|
|
19
24
|
} | {
|
|
20
25
|
kind: "insecure-file";
|
|
21
26
|
path: string;
|
|
22
27
|
mode: string;
|
|
28
|
+
target: "directory" | "file";
|
|
23
29
|
} | {
|
|
24
30
|
kind: "unreadable";
|
|
25
31
|
path: string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* The block itself, un-rendered: `--json` failures carry the same code, sentences and fix commands as the text.
|
|
35
|
+
* 0.7.0 PR 7: the fix command is the one the caller gives (the channel's `auth`), never a literal.
|
|
36
|
+
*/
|
|
37
|
+
export declare function credentialProblemBlock(load: CredentialLoadProblem, authCommand?: string): Extract<ErrorBlock, {
|
|
38
|
+
kind: "bad";
|
|
39
|
+
}>;
|
|
29
40
|
/**
|
|
30
41
|
* The credential-rejected block (`11A`) — §13.6 what / why / fix, fix LAST, for `connect` (after a
|
|
31
42
|
* 401 from the probe) and `status` (a standing stop). The `why` says "expired" outright only when
|