@oh-hai/cli 0.1.0-beta.0 → 0.2.1
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 +51 -8
- package/dist/auth/resolve-token.d.ts +2 -4
- package/dist/auth/resolve-token.js +4 -11
- package/dist/auth/resolve-token.js.map +1 -1
- package/dist/bindings.d.ts +65 -0
- package/dist/bindings.js +242 -0
- package/dist/bindings.js.map +1 -0
- package/dist/cli.js +211 -12
- package/dist/cli.js.map +1 -1
- package/dist/commands/ask.js +21 -17
- package/dist/commands/ask.js.map +1 -1
- package/dist/commands/binary-update.d.ts +61 -0
- package/dist/commands/binary-update.js +160 -0
- package/dist/commands/binary-update.js.map +1 -0
- package/dist/commands/context.d.ts +135 -0
- package/dist/commands/doctor.js +30 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/flags.d.ts +14 -2
- package/dist/commands/flags.js +34 -6
- package/dist/commands/flags.js.map +1 -1
- package/dist/commands/handlers.js +8 -0
- package/dist/commands/handlers.js.map +1 -1
- package/dist/commands/inbox.js +129 -33
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/login.d.ts +13 -0
- package/dist/commands/login.js +35 -27
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/messaging/identity.d.ts +9 -0
- package/dist/commands/messaging/identity.js +21 -0
- package/dist/commands/messaging/identity.js.map +1 -1
- package/dist/commands/messaging/validate.d.ts +6 -5
- package/dist/commands/messaging/validate.js +7 -16
- package/dist/commands/messaging/validate.js.map +1 -1
- package/dist/commands/registry.js +88 -8
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/setup.d.ts +26 -0
- package/dist/commands/setup.js +221 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/task.js +21 -24
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/teach.d.ts +13 -0
- package/dist/commands/teach.js +317 -0
- package/dist/commands/teach.js.map +1 -0
- package/dist/commands/update-check.d.ts +49 -0
- package/dist/commands/update-check.js +203 -0
- package/dist/commands/update-check.js.map +1 -0
- package/dist/commands/upgrade.d.ts +2 -0
- package/dist/commands/upgrade.js +178 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/use.d.ts +2 -0
- package/dist/commands/use.js +99 -0
- package/dist/commands/use.js.map +1 -0
- package/dist/commands/whoami.js +113 -27
- package/dist/commands/whoami.js.map +1 -1
- package/dist/config-file.js +4 -20
- package/dist/config-file.js.map +1 -1
- package/dist/config.d.ts +15 -1
- package/dist/config.js +43 -4
- package/dist/config.js.map +1 -1
- package/dist/exit-codes.d.ts +6 -0
- package/dist/exit-codes.js +6 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/help.js +5 -1
- package/dist/help.js.map +1 -1
- package/dist/onboarding/open-url.d.ts +26 -0
- package/dist/onboarding/open-url.js +69 -0
- package/dist/onboarding/open-url.js.map +1 -0
- package/dist/onboarding/status.d.ts +24 -0
- package/dist/onboarding/status.js +53 -0
- package/dist/onboarding/status.js.map +1 -0
- package/dist/os.d.ts +16 -0
- package/dist/os.js +32 -0
- package/dist/os.js.map +1 -0
- package/dist/url.d.ts +8 -0
- package/dist/url.js +29 -0
- package/dist/url.js.map +1 -0
- package/dist/version.d.ts +11 -3
- package/dist/version.js +20 -3
- package/dist/version.js.map +1 -1
- package/dist/watch-lock.d.ts +85 -0
- package/dist/watch-lock.js +358 -0
- package/dist/watch-lock.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// In-place binary self-update for `oh-hai upgrade` (docs/specs/cli.md §4, #358 — the binary case of
|
|
2
|
+
// #343, completing #277's distribution story). A `bun --compile` standalone can't `npm i -g` itself;
|
|
3
|
+
// instead it downloads the matching release asset, verifies its SHA-256 against the release's
|
|
4
|
+
// `SHA256SUMS`, and atomically swaps itself. This mirrors `packaging/install.sh`'s
|
|
5
|
+
// stage→verify-run→rename sequence — the SAME asset contract the installer implements
|
|
6
|
+
// (docs/runbooks/cli-release.md "Asset contract for consumers").
|
|
7
|
+
//
|
|
8
|
+
// Security: nothing untrusted is ever executed or installed. The bytes are checksum-verified BEFORE
|
|
9
|
+
// they are made executable, run, or swapped in; a MISMATCH is a loud hard-stop (corruption/tamper),
|
|
10
|
+
// never a silent fallback. `performBinaryUpdate` NEVER throws — it returns a structured result and
|
|
11
|
+
// `upgradeCommand` (upgrade.ts) applies the CLI policy (emit an outcome vs. throw a CliError), the
|
|
12
|
+
// same split `checkForUpdate` (update-check.ts) uses.
|
|
13
|
+
import { createHash } from "node:crypto";
|
|
14
|
+
import { MAX_TIMER_MS } from "./messaging/shared.js";
|
|
15
|
+
/** The public distribution mirror that serves the release binaries (matches
|
|
16
|
+
* `packaging/install.sh`'s default and docs/runbooks/cli-release.md). The repo is private, so
|
|
17
|
+
* its GitHub Release URLs 404 for the public; CI mirrors each `cli-v*` release into an R2
|
|
18
|
+
* bucket served at this base by dist-worker/ (#357). */
|
|
19
|
+
const DIST_BASE_URL = "https://ohhai.app";
|
|
20
|
+
/** Default per-request bound for the asset/checksum downloads; mirrors update-check.ts so a stalled
|
|
21
|
+
* download is an explicit failure, never a silent hang. */
|
|
22
|
+
const DEFAULT_DOWNLOAD_TIMEOUT_MS = 30_000;
|
|
23
|
+
/** The download URL for a release asset on the mirror. The release tag is `cli-vX.Y.Z` (the bare
|
|
24
|
+
* `X.Y.Z` is what `oh-hai --version` prints), so the `cli-v` prefix is prepended here. */
|
|
25
|
+
function releaseAssetUrl(version, asset) {
|
|
26
|
+
return `${DIST_BASE_URL}/dist/cli-v${version}/${asset}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Map the running host to its published release asset name, or `undefined` when the host has no
|
|
30
|
+
* prebuilt binary. The published set (docs/runbooks/cli-release.md): `oh-hai-{linux,darwin}-{x64,arm64}`
|
|
31
|
+
* and `oh-hai-windows-x64.exe`. Notably **windows-arm64 is absent** (no `bun-windows-arm64` compile
|
|
32
|
+
* target) and MUST fall back to guidance rather than 404 on a guessed filename. Pure + exported so
|
|
33
|
+
* every host maps deterministically in a unit test.
|
|
34
|
+
*/
|
|
35
|
+
export function assetNameFor(platform, arch) {
|
|
36
|
+
const os = platform === "win32" ? "windows" : platform === "darwin" ? "darwin" : platform === "linux" ? "linux" : undefined;
|
|
37
|
+
const cpu = arch === "x64" ? "x64" : arch === "arm64" ? "arm64" : undefined;
|
|
38
|
+
if (os === undefined || cpu === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
if (os === "windows" && cpu === "arm64")
|
|
41
|
+
return undefined; // no bun-windows-arm64 target
|
|
42
|
+
const ext = os === "windows" ? ".exe" : "";
|
|
43
|
+
return `oh-hai-${os}-${cpu}${ext}`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Extract the expected lowercase SHA-256 hex for `asset` from a `SHA256SUMS` file. The contract uses
|
|
47
|
+
* BARE filenames (no path components), one `<hex> <filename>` pair per line (the `sha256sum`/`shasum`
|
|
48
|
+
* format, one or more spaces, an optional `*` binary marker). Returns `undefined` when there is no
|
|
49
|
+
* line for `asset`. Pure + exported.
|
|
50
|
+
*/
|
|
51
|
+
export function expectedSha(sumsText, asset) {
|
|
52
|
+
for (const line of sumsText.split(/\r?\n/)) {
|
|
53
|
+
const m = /^([0-9a-fA-F]{64})\s+\*?(.+)$/.exec(line.trim());
|
|
54
|
+
if (m !== null && m[2] === asset)
|
|
55
|
+
return m[1]?.toLowerCase();
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
function errorMessage(error) {
|
|
60
|
+
return error instanceof Error ? error.message : String(error);
|
|
61
|
+
}
|
|
62
|
+
/** GET a URL, returning the `HttpResponse` or a structured failure (never throws — mirrors
|
|
63
|
+
* update-check). On a non-200 `status` is the HTTP code (so the caller can distinguish a 404); on a
|
|
64
|
+
* transport error `status` is undefined and `network` is true. */
|
|
65
|
+
async function get(fetchImpl, url, bound) {
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetchImpl(url, { method: "GET", headers: {}, signal: AbortSignal.timeout(bound) });
|
|
68
|
+
if (response.status !== 200) {
|
|
69
|
+
return { ok: false, error: `HTTP ${response.status}`, network: false, status: response.status };
|
|
70
|
+
}
|
|
71
|
+
return { ok: true, response };
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
return { ok: false, error: errorMessage(error), network: true };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Download the release binary matching this host, verify its SHA-256 against the release's
|
|
79
|
+
* `SHA256SUMS`, and atomically swap it into place via the injected `io`. Order is the security
|
|
80
|
+
* invariant: fetch → checksum-verify → stage → verify-runs → finalize. Nothing untrusted is made
|
|
81
|
+
* executable, run, or installed before the checksum matches. Never throws.
|
|
82
|
+
*/
|
|
83
|
+
export async function performBinaryUpdate(io, fetchImpl, version, timeoutMs) {
|
|
84
|
+
const asset = assetNameFor(io.platform, io.arch);
|
|
85
|
+
if (asset === undefined) {
|
|
86
|
+
return { status: "unsupported", platform: io.platform, arch: io.arch };
|
|
87
|
+
}
|
|
88
|
+
const bound = Math.min(timeoutMs !== undefined && timeoutMs > 0 ? timeoutMs : DEFAULT_DOWNLOAD_TIMEOUT_MS, MAX_TIMER_MS);
|
|
89
|
+
// 1. The binary itself (bytes).
|
|
90
|
+
const binaryGet = await get(fetchImpl, releaseAssetUrl(version, asset), bound);
|
|
91
|
+
if (!binaryGet.ok) {
|
|
92
|
+
// A 404 on the asset means the `cli-v<version>` binaries aren't on the mirror yet — npm's
|
|
93
|
+
// dist-tag can lead them by minutes (all fire on the same tag; the matrix + mirror upload are
|
|
94
|
+
// slower). Surface that as a distinct "try again shortly" state, not a generic download error.
|
|
95
|
+
if (binaryGet.status === 404) {
|
|
96
|
+
return { status: "release-pending" };
|
|
97
|
+
}
|
|
98
|
+
return { status: "download-failed", detail: `${asset}: ${binaryGet.error}`, network: binaryGet.network };
|
|
99
|
+
}
|
|
100
|
+
if (binaryGet.response.arrayBuffer === undefined) {
|
|
101
|
+
return { status: "download-failed", detail: `${asset}: response has no body`, network: true };
|
|
102
|
+
}
|
|
103
|
+
let bytes;
|
|
104
|
+
try {
|
|
105
|
+
bytes = new Uint8Array(await binaryGet.response.arrayBuffer());
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
return { status: "download-failed", detail: `${asset}: ${errorMessage(error)}`, network: true };
|
|
109
|
+
}
|
|
110
|
+
// 2. The release checksums (text). Note: SHA256SUMS is a plain sha256 manifest on the same channel
|
|
111
|
+
// as the binary — it proves non-corruption, not authenticity (see the supply-chain residual).
|
|
112
|
+
const sumsGet = await get(fetchImpl, releaseAssetUrl(version, "SHA256SUMS"), bound);
|
|
113
|
+
if (!sumsGet.ok) {
|
|
114
|
+
// The mirror uploads binaries BEFORE SHA256SUMS within a version, so a 404 here is the
|
|
115
|
+
// same mid-publish window as a missing binary — "try again shortly", not a hard error.
|
|
116
|
+
if (sumsGet.status === 404) {
|
|
117
|
+
return { status: "release-pending" };
|
|
118
|
+
}
|
|
119
|
+
return { status: "download-failed", detail: `SHA256SUMS: ${sumsGet.error}`, network: sumsGet.network };
|
|
120
|
+
}
|
|
121
|
+
if (sumsGet.response.text === undefined) {
|
|
122
|
+
return { status: "download-failed", detail: `SHA256SUMS: response has no body`, network: true };
|
|
123
|
+
}
|
|
124
|
+
let sumsText;
|
|
125
|
+
try {
|
|
126
|
+
sumsText = await sumsGet.response.text();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
return { status: "download-failed", detail: `SHA256SUMS: ${errorMessage(error)}`, network: true };
|
|
130
|
+
}
|
|
131
|
+
const expected = expectedSha(sumsText, asset);
|
|
132
|
+
if (expected === undefined) {
|
|
133
|
+
return { status: "download-failed", detail: `no checksum for ${asset} in SHA256SUMS`, network: false };
|
|
134
|
+
}
|
|
135
|
+
// 3. Verify BEFORE anything is staged, made executable, or run.
|
|
136
|
+
const actual = createHash("sha256").update(bytes).digest("hex");
|
|
137
|
+
if (actual !== expected) {
|
|
138
|
+
return { status: "checksum-mismatch" };
|
|
139
|
+
}
|
|
140
|
+
// 4. Stage → verify-runs → atomic swap. Any fs/exec failure aborts WITHOUT clobbering the current
|
|
141
|
+
// install (the old binary is only replaced by the final atomic rename). The whole block is
|
|
142
|
+
// wrapped so a throwing `io` (stage/verifyRuns/finalize) can't break this function's never-throws
|
|
143
|
+
// contract — a throw becomes `install-failed`, distinct from `verifyRuns` merely returning false.
|
|
144
|
+
let staged;
|
|
145
|
+
try {
|
|
146
|
+
staged = io.stage(bytes);
|
|
147
|
+
if (!io.verifyRuns(staged)) {
|
|
148
|
+
io.cleanup(staged);
|
|
149
|
+
return { status: "unverified-binary" };
|
|
150
|
+
}
|
|
151
|
+
io.finalize(staged);
|
|
152
|
+
return { status: "updated" };
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (staged !== undefined)
|
|
156
|
+
io.cleanup(staged);
|
|
157
|
+
return { status: "install-failed", detail: errorMessage(error) };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=binary-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binary-update.js","sourceRoot":"","sources":["../../src/commands/binary-update.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ResolvedConfig } from "../config.js";
|
|
2
2
|
import type { LoadedConfigFiles } from "../config-file.js";
|
|
3
|
+
import type { Binding, BindingsIo } from "../bindings.js";
|
|
3
4
|
import type { CredentialStore, OpenStoreOptions } from "../auth/token-store.js";
|
|
5
|
+
import type { WatchLockIo } from "../watch-lock.js";
|
|
4
6
|
/** Output sink — the same shape `cli.ts` uses, so tests capture stdout/stderr in-process. */
|
|
5
7
|
export interface Io {
|
|
6
8
|
log(line: string): void;
|
|
@@ -19,6 +21,13 @@ export interface HttpResponse {
|
|
|
19
21
|
headers?: {
|
|
20
22
|
get(name: string): string | null;
|
|
21
23
|
};
|
|
24
|
+
/** The raw response body as bytes — read only by the binary self-update (#358), to download the
|
|
25
|
+
* release binary. Optional so a status-only / JSON fake still satisfies the type; the DOM
|
|
26
|
+
* `Response.arrayBuffer` is structurally assignable, so production `fetch` provides it. */
|
|
27
|
+
arrayBuffer?(): Promise<ArrayBuffer>;
|
|
28
|
+
/** The response body as text — read only by the binary self-update (#358), to download the
|
|
29
|
+
* `SHA256SUMS` checksum file. Optional for the same reason as `arrayBuffer`. */
|
|
30
|
+
text?(): Promise<string>;
|
|
22
31
|
}
|
|
23
32
|
/** The subset of `fetch` the CLI uses. `body` carries a JSON request payload (the device-code
|
|
24
33
|
* POSTs); it's optional so a bodyless GET (`whoami --check`) is unaffected. Real `fetch`'s return
|
|
@@ -29,6 +38,84 @@ export type FetchLike = (url: string, init: {
|
|
|
29
38
|
body?: string;
|
|
30
39
|
signal?: AbortSignal;
|
|
31
40
|
}) => Promise<HttpResponse>;
|
|
41
|
+
/** How the running CLI was installed (drives `oh-hai upgrade`, §4 / #343). `dev` is a source or
|
|
42
|
+
* local-dist checkout; `binary` is a compiled standalone; `npm-global` is a global npm install;
|
|
43
|
+
* `unknown` is the safe fallback (generic guidance, no self-mutation). */
|
|
44
|
+
export type InstallMethod = "npm-global" | "binary" | "dev" | "unknown";
|
|
45
|
+
/** The facts `classifyInstall` (update-check.ts) reduces to an `InstallMethod`. Injected via
|
|
46
|
+
* `RuntimeDeps.installFacts` so the classification stays a pure, unit-tested function and the CLI
|
|
47
|
+
* never touches the real process/module layout in a test. */
|
|
48
|
+
export interface InstallFacts {
|
|
49
|
+
/** `process.execPath` — the executable running the CLI: `node`/`bun` when an interpreter runs a
|
|
50
|
+
* built script, or the compiled standalone binary itself (which is what `binary` self-update
|
|
51
|
+
* replaces). Its basename is the signal that distinguishes the two (see `classifyInstall`). */
|
|
52
|
+
execPath: string;
|
|
53
|
+
/** The real (symlink-resolved) on-disk path of the CLI module — npm installs the bin as a symlink. */
|
|
54
|
+
modulePath: string;
|
|
55
|
+
}
|
|
56
|
+
/** Host + filesystem seam for `oh-hai upgrade`'s in-place binary self-update (§4 / #358). The
|
|
57
|
+
* command downloads the release asset via the existing `fetchImpl`; THIS seam owns the host
|
|
58
|
+
* identity (`platform`/`arch` → asset name) and the stage→verify-run→atomic-swap that
|
|
59
|
+
* `packaging/install.sh` performs in shell. Injected so the binary case is unit-testable with zero
|
|
60
|
+
* disk, network, or subprocess — a test passes a fake that records `stage`/`finalize` and returns a
|
|
61
|
+
* canned `verifyRuns`. Production (cli.ts) wires it over `node:fs`/`node:child_process` against
|
|
62
|
+
* `realpath(process.execPath)` (the running standalone). The current binary path is INTERNAL to the
|
|
63
|
+
* production impl — the orchestrator never learns where the binary lives, only that it can stage,
|
|
64
|
+
* verify, finalize, and clean up. */
|
|
65
|
+
export interface BinaryUpdateIo {
|
|
66
|
+
/** `process.platform` — mapped to the asset OS token (`win32`→`windows`, else as-is). */
|
|
67
|
+
platform: NodeJS.Platform;
|
|
68
|
+
/** `process.arch` — mapped to the asset arch token (`x64`/`arm64`; anything else is unsupported). */
|
|
69
|
+
arch: string;
|
|
70
|
+
/** Write `bytes` as an executable file (mode 0o755) BESIDE the running binary — same filesystem, so
|
|
71
|
+
* the later `finalize` rename is atomic — and return the staged path. Throws on a write failure. */
|
|
72
|
+
stage(bytes: Uint8Array): string;
|
|
73
|
+
/** Run `<stagedPath> --version`; true iff it exits 0. Guards against an authentic-but-unrunnable
|
|
74
|
+
* binary replacing a working install (e.g. a glibc build on musl) — the checksum proves the bytes
|
|
75
|
+
* are genuine, not that they execute here. Only ever called AFTER checksum verification. */
|
|
76
|
+
verifyRuns(stagedPath: string): boolean;
|
|
77
|
+
/** Atomically replace the running binary with the staged file (a same-dir rename on POSIX; on
|
|
78
|
+
* Windows the live `.exe` is locked, so rename the current binary aside then move the staged one
|
|
79
|
+
* into place). Throws on failure, leaving the current install untouched. */
|
|
80
|
+
finalize(stagedPath: string): void;
|
|
81
|
+
/** Best-effort delete of the staged file on an aborted update (checksum mismatch, unrunnable
|
|
82
|
+
* binary, or a finalize failure). Never throws. */
|
|
83
|
+
cleanup(stagedPath: string): void;
|
|
84
|
+
}
|
|
85
|
+
/** The captured result of a subprocess run (mirrors auth/keychain.ts's ProcResult). `spawnError` is
|
|
86
|
+
* set (e.g. `"ENOENT"`) when the binary is missing; `code` is null on a spawn failure. */
|
|
87
|
+
export interface CommandResult {
|
|
88
|
+
code: number | null;
|
|
89
|
+
stdout: string;
|
|
90
|
+
stderr: string;
|
|
91
|
+
spawnError?: string;
|
|
92
|
+
}
|
|
93
|
+
/** The result of inspecting a teach target. `absent` = no such file (safe to create); `file` = a regular
|
|
94
|
+
* file we read (safe to update); `unsafe` = it exists but must NOT be read or written through — a symlink
|
|
95
|
+
* (writing would follow it OUTSIDE the repo), a non-regular file (FIFO/device/dir — reading could hang),
|
|
96
|
+
* or an existing file that failed to read for a non-ENOENT reason (treating it as absent would let a later
|
|
97
|
+
* write TRUNCATE it). The three states are distinguished so teach never conflates "unreadable" with
|
|
98
|
+
* "missing" — the difference is the line between a safe create and silent data loss. */
|
|
99
|
+
export type TeachRead = {
|
|
100
|
+
kind: "absent";
|
|
101
|
+
} | {
|
|
102
|
+
kind: "file";
|
|
103
|
+
content: string;
|
|
104
|
+
} | {
|
|
105
|
+
kind: "unsafe";
|
|
106
|
+
reason: string;
|
|
107
|
+
};
|
|
108
|
+
/** Filesystem seam for `oh-hai teach` (§4.9) — the only command that writes arbitrary files (the
|
|
109
|
+
* agent-instruction files it manages). Injected so the teach tests run against an in-memory tree with
|
|
110
|
+
* zero disk access, mirroring `ConfigFileIo` (config-file.ts). `read` classifies a target (see
|
|
111
|
+
* `TeachRead`); `writeFile` creates any missing parent directories. `cwd`/`homedir` are the fixed anchors
|
|
112
|
+
* targets are joined onto — the project root (cwd) and the user's home (`--global`). */
|
|
113
|
+
export interface TeachFs {
|
|
114
|
+
read(path: string): TeachRead;
|
|
115
|
+
writeFile(path: string, content: string): void;
|
|
116
|
+
cwd: string;
|
|
117
|
+
homedir: string;
|
|
118
|
+
}
|
|
32
119
|
/** Side-effecting dependencies, injected so command tests stay hermetic. */
|
|
33
120
|
export interface RuntimeDeps {
|
|
34
121
|
/** Open the credential store (selects keychain vs `0600` file fallback). */
|
|
@@ -43,6 +130,15 @@ export interface RuntimeDeps {
|
|
|
43
130
|
fetchImpl: FetchLike;
|
|
44
131
|
/** Load the user-global + per-project config files (§6). Injected so tests never read real disk. */
|
|
45
132
|
loadConfigFiles: () => LoadedConfigFiles;
|
|
133
|
+
/** Load the user-side directory→agent bindings (bindings.ts, §6). The entrypoint feeds the result
|
|
134
|
+
* into `resolveConfig` for account resolution. Optional so an existing hermetic caller that never
|
|
135
|
+
* touches bindings (and doesn't set it) resolves as if there were none — the entrypoint treats an
|
|
136
|
+
* absent loader as an empty binding set. */
|
|
137
|
+
loadBindings?: () => Binding[];
|
|
138
|
+
/** Filesystem seam for `oh-hai use` — the command that READS/WRITES bindings and needs the process
|
|
139
|
+
* cwd (the directory it binds). Optional so no existing hermetic caller needs the field; production
|
|
140
|
+
* wires `nodeBindingsIo()`, and the `use` handler errors clearly if it's absent when `use` runs. */
|
|
141
|
+
bindingsIo?: BindingsIo;
|
|
46
142
|
/** Sleep `ms` milliseconds between device-code polls (§4.3). Injected so tests don't actually
|
|
47
143
|
* wait — a no-op keeps the happy path instant, and a recording sleep lets a test assert the
|
|
48
144
|
* `slow_down` backoff grew the interval. */
|
|
@@ -52,6 +148,45 @@ export interface RuntimeDeps {
|
|
|
52
148
|
* — a caller that omits it (and every hermetic test) skips the wait, since in-memory IO never
|
|
53
149
|
* backpressures. Production awaits `process.stdout` drain. */
|
|
54
150
|
flushOutput?: () => Promise<void>;
|
|
151
|
+
/** Open a URL in the user's browser for the onboarding device-approval step (§4.3, #271). Resolves
|
|
152
|
+
* `true` when the opener launched, `false` when it couldn't (no browser / non-http(s) URL) so the
|
|
153
|
+
* caller prints the URL instead. Optional — an omitting caller (and hermetic tests that don't pass
|
|
154
|
+
* one) is treated as "couldn't open", so the flow always degrades to the printed fallback. */
|
|
155
|
+
openBrowser?: (url: string) => Promise<boolean>;
|
|
156
|
+
/** True when stdin is an interactive terminal (§4.3, #271). `oh-hai setup` on an already-set-up
|
|
157
|
+
* machine only PROMPTS to reconnect when interactive — under a pipe / CI it reports status and exits
|
|
158
|
+
* instead of blocking on a read that may never get a line. Production wires `process.stdin.isTTY`;
|
|
159
|
+
* an omitting caller (and hermetic tests that don't set it) is treated as NON-interactive, so no test
|
|
160
|
+
* ever blocks on a prompt by accident. Distinct from `readLine`, which merely READS a line — its
|
|
161
|
+
* presence says nothing about whether a human is there to answer. */
|
|
162
|
+
isInteractive?: () => boolean;
|
|
163
|
+
/** Filesystem seam for `oh-hai teach` (§4.9). Optional so no existing hermetic caller needs the field;
|
|
164
|
+
* production wires `nodeTeachFs()` (teach.ts) and the handler throws a clear internal error if it's
|
|
165
|
+
* absent when teach actually runs. */
|
|
166
|
+
teachFs?: TeachFs;
|
|
167
|
+
/** Lock seam for the `inbox watch` concurrent-drain guard (#323). Optional so existing hermetic
|
|
168
|
+
* callers compile unchanged — when absent, the guard is skipped entirely (today's behavior).
|
|
169
|
+
* Production wires `nodeWatchLockIo()` (watch-lock.ts) so the guard is active in the shipped CLI. */
|
|
170
|
+
watchLockIo?: WatchLockIo;
|
|
171
|
+
/** How the CLI was installed, for `oh-hai upgrade` (#343). Optional so hermetic callers compile
|
|
172
|
+
* unchanged — when absent, `upgrade` classifies the install as `unknown` and gives generic
|
|
173
|
+
* guidance. Production wires the real process/module facts (cli.ts). */
|
|
174
|
+
installFacts?: InstallFacts;
|
|
175
|
+
/** Run a subprocess and capture its result, for `oh-hai upgrade` → `npm i -g @oh-hai/cli@latest`
|
|
176
|
+
* (#343). Optional so hermetic callers compile unchanged — when absent (or under a pipe / --json)
|
|
177
|
+
* `upgrade` PRINTS the command instead of spawning. Production wires a `spawn`-based runner (cli.ts). */
|
|
178
|
+
runCommand?: (file: string, args: string[]) => Promise<CommandResult>;
|
|
179
|
+
/** Whether stdout is a TTY, for `oh-hai upgrade`'s auto-run gate (#343/#349). `isInteractive` (stdin
|
|
180
|
+
* TTY) alone isn't enough: `oh-hai upgrade | tee log` has a TTY stdin but a piped stdout, and the
|
|
181
|
+
* spec promises a pipe PRINTS the command rather than mutating a global install. Optional — an
|
|
182
|
+
* omitting caller is treated as a TTY stdout (hermetic tests that only set isInteractive assume a
|
|
183
|
+
* terminal); production wires `process.stdout.isTTY`. */
|
|
184
|
+
isStdoutTty?: () => boolean;
|
|
185
|
+
/** Host + fs seam for `oh-hai upgrade`'s in-place binary self-update (#358). Optional so hermetic
|
|
186
|
+
* callers compile unchanged — when absent (or under `--json`), the `binary` case emits installer
|
|
187
|
+
* guidance instead of mutating (machine mode / an unwired caller must not swap the binary).
|
|
188
|
+
* Production wires the real download-and-replace over node fs/child_process (cli.ts). */
|
|
189
|
+
binaryUpdateIo?: BinaryUpdateIo;
|
|
55
190
|
}
|
|
56
191
|
export interface CommandContext {
|
|
57
192
|
io: Io;
|
package/dist/commands/doctor.js
CHANGED
|
@@ -17,11 +17,13 @@ import { resolveIdentity } from "../auth/resolve-token.js";
|
|
|
17
17
|
import { buildOk, serializeEnvelope } from "../envelope.js";
|
|
18
18
|
import { ExitCode } from "../exit-codes.js";
|
|
19
19
|
import { sanitizeForTerminal } from "../terminal.js";
|
|
20
|
+
import { cliVersion } from "../version.js";
|
|
20
21
|
import { flagOn, parseCommandArgs } from "./flags.js";
|
|
21
22
|
import { buildNotify } from "./messaging/build.js";
|
|
22
23
|
import { submitEnvelope } from "./messaging/http.js";
|
|
23
24
|
import { resolveSubmitIdentity } from "./messaging/identity.js";
|
|
24
25
|
import { resolveRunId } from "./messaging/shared.js";
|
|
26
|
+
import { checkForUpdate } from "./update-check.js";
|
|
25
27
|
/** Default per-request bound for the network probes when no --timeout/MA2H_TIMEOUT_MS is set —
|
|
26
28
|
* §9 promises offline is an explicit state, never a silent hang. Mirrors whoami's checkToken. */
|
|
27
29
|
const DEFAULT_PROBE_TIMEOUT_MS = 10_000;
|
|
@@ -96,6 +98,24 @@ async function testNotifyCheck(ctx) {
|
|
|
96
98
|
return { name: "test-notify", status: "warn", detail: `could not send test notify — ${message}` };
|
|
97
99
|
}
|
|
98
100
|
}
|
|
101
|
+
/** Advisory "update available" check (§4.6, #343). Best-effort and network-based: a `warn` when a
|
|
102
|
+
* newer @oh-hai/cli is published, a `pass` when current. Returns `undefined` on ANY registry
|
|
103
|
+
* failure so doctor omits the line entirely — connectivity already reports offline, so a second
|
|
104
|
+
* network warn would be noise — and the exit code is never touched (advisory carries no exitCode). */
|
|
105
|
+
async function updateCheck(ctx) {
|
|
106
|
+
const current = cliVersion();
|
|
107
|
+
const result = await checkForUpdate(current, ctx.runtime.fetchImpl, probeTimeoutMs(ctx));
|
|
108
|
+
if (result.error !== undefined)
|
|
109
|
+
return undefined;
|
|
110
|
+
if (result.updateAvailable) {
|
|
111
|
+
return {
|
|
112
|
+
name: "update",
|
|
113
|
+
status: "warn",
|
|
114
|
+
detail: `update available: v${current} → v${result.latest ?? "?"} — run \`oh-hai upgrade\``,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return { name: "update", status: "pass", detail: `up to date (v${current})` };
|
|
118
|
+
}
|
|
99
119
|
/** Emit the collected checks: the uniform --json envelope (data.checks, exactly name/status/detail),
|
|
100
120
|
* or a human table with a per-status marker. Details are sanitized on BOTH paths (§5.4): some carry
|
|
101
121
|
* Hub-supplied strings (a device-code-login discovered agent id, a --test-notify ack id), and
|
|
@@ -222,9 +242,16 @@ export async function doctorCommand(ctx) {
|
|
|
222
242
|
: "OS keychain unavailable — the 0600 file fallback would be used (§5.2)";
|
|
223
243
|
checks.push({ name: "keychain", status: "warn", detail });
|
|
224
244
|
}
|
|
225
|
-
// 4. Hub connectivity (ADVISORY
|
|
226
|
-
|
|
227
|
-
//
|
|
245
|
+
// 4-5. Hub connectivity + the update check (both ADVISORY, and hitting independent hosts — the Hub
|
|
246
|
+
// vs registry.npmjs.org) run concurrently, so a slow registry never serializes behind a slow
|
|
247
|
+
// Hub on every doctor run. Order is preserved by pushing connectivity first; the update line is
|
|
248
|
+
// omitted entirely on any registry failure (#343).
|
|
249
|
+
const [connectivity, update] = await Promise.all([probeConnectivity(ctx, token), updateCheck(ctx)]);
|
|
250
|
+
checks.push(connectivity);
|
|
251
|
+
if (update !== undefined) {
|
|
252
|
+
checks.push(update);
|
|
253
|
+
}
|
|
254
|
+
// 6. test-notify (ADVISORY, opt-in).
|
|
228
255
|
if (testNotify) {
|
|
229
256
|
checks.push(await testNotifyCheck(ctx));
|
|
230
257
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,2FAA2F;AAC3F,6FAA6F;AAC7F,kGAAkG;AAClG,+FAA+F;AAC/F,yFAAyF;AACzF,+FAA+F;AAC/F,gGAAgG;AAChG,2DAA2D;AAC3D,EAAE;AACF,mGAAmG;AACnG,8FAA8F;AAC9F,oGAAoG;AACpG,mGAAmG;AACnG,6CAA6C;AAE7C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/flags.d.ts
CHANGED
|
@@ -10,8 +10,20 @@ export declare const GLOBAL_OPTIONS: OptionsConfig;
|
|
|
10
10
|
* are on; `--json=false` / `0` / `no` are off. A repeated flag becomes an array — last wins.
|
|
11
11
|
*/
|
|
12
12
|
export declare function flagOn(value: unknown): boolean;
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Like `flagOn`, but REJECTS an unrecognized value (usage error) instead of silently treating it as
|
|
15
|
+
* off. For a SAFETY flag where a typo'd value must not fall through to the unsafe path — e.g.
|
|
16
|
+
* `oh-hai upgrade --check=treu` must fail loudly, not run the live `npm i -g` (#349 review). Bare
|
|
17
|
+
* presence and clean truthy values are on; explicit `false`/`0`/`no`/`off` are off; anything else
|
|
18
|
+
* throws. The raw value is not echoed (it's user argv, and the message stays control-char-free).
|
|
19
|
+
*/
|
|
20
|
+
export declare function flagOnStrict(value: unknown, flag: string): boolean;
|
|
21
|
+
/** Parse argv for a command with no subcommand operand (the auth commands). `maxOperands` (default 0)
|
|
22
|
+
* allows a command to accept that many positional operands BEYOND the command token — `oh-hai use
|
|
23
|
+
* <agent>` passes 1 so a single free-form operand is accepted while a second stray one still errors. */
|
|
24
|
+
export declare function parseCommandArgs(argv: string[], extra?: OptionsConfig, opts?: {
|
|
25
|
+
maxOperands?: number;
|
|
26
|
+
}): ReturnType<typeof parseArgs>;
|
|
15
27
|
/** Parse argv for a command that takes a SUBCOMMAND operand (`ask`/`task` → submit | await).
|
|
16
28
|
* Like `parseCommandArgs` (global + `extra` options, `strict:false` so the `--flag=value`
|
|
17
29
|
* boolean form isn't rejected, then reject any unknown flag), but `positionals[0]` is the
|
package/dist/commands/flags.js
CHANGED
|
@@ -36,6 +36,30 @@ export function flagOn(value) {
|
|
|
36
36
|
}
|
|
37
37
|
return false;
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Like `flagOn`, but REJECTS an unrecognized value (usage error) instead of silently treating it as
|
|
41
|
+
* off. For a SAFETY flag where a typo'd value must not fall through to the unsafe path — e.g.
|
|
42
|
+
* `oh-hai upgrade --check=treu` must fail loudly, not run the live `npm i -g` (#349 review). Bare
|
|
43
|
+
* presence and clean truthy values are on; explicit `false`/`0`/`no`/`off` are off; anything else
|
|
44
|
+
* throws. The raw value is not echoed (it's user argv, and the message stays control-char-free).
|
|
45
|
+
*/
|
|
46
|
+
export function flagOnStrict(value, flag) {
|
|
47
|
+
if (value === true) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if (typeof value === "string") {
|
|
51
|
+
const v = value.trim().toLowerCase();
|
|
52
|
+
if (v === "" || v === "true" || v === "1" || v === "yes" || v === "on")
|
|
53
|
+
return true;
|
|
54
|
+
if (v === "false" || v === "0" || v === "no" || v === "off")
|
|
55
|
+
return false;
|
|
56
|
+
throw new CliError("usage", `--${flag} is a boolean flag: pass it bare or as --${flag}=false (unrecognized value).`);
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
return value.length > 0 && flagOnStrict(value[value.length - 1], flag);
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
39
63
|
/** Parse argv against the global flags plus the command's own `extra` options with `strict: false`
|
|
40
64
|
* (so the `--flag=value` boolean form the CLI supports isn't rejected), then reject any flag NOT
|
|
41
65
|
* in the known set — so a typo like `oh-hai whoami --chek` is a usage error (exit 2), not silently
|
|
@@ -67,13 +91,17 @@ function parseKnownFlags(argv, extra) {
|
|
|
67
91
|
}
|
|
68
92
|
return parsed;
|
|
69
93
|
}
|
|
70
|
-
/** Parse argv for a command with no subcommand operand (the auth commands).
|
|
71
|
-
|
|
94
|
+
/** Parse argv for a command with no subcommand operand (the auth commands). `maxOperands` (default 0)
|
|
95
|
+
* allows a command to accept that many positional operands BEYOND the command token — `oh-hai use
|
|
96
|
+
* <agent>` passes 1 so a single free-form operand is accepted while a second stray one still errors. */
|
|
97
|
+
export function parseCommandArgs(argv, extra = {}, opts = {}) {
|
|
72
98
|
const parsed = parseKnownFlags(argv, extra);
|
|
73
|
-
// positionals[0] is the command token;
|
|
74
|
-
// stray one (`oh-hai logout all`, `oh-hai whoami check`) is a typo, not a silently-ignored arg.
|
|
75
|
-
|
|
76
|
-
|
|
99
|
+
// positionals[0] is the command token; most auth commands take no operands (maxOperands 0), so a
|
|
100
|
+
// stray one (`oh-hai logout all`, `oh-hai whoami check`) is a typo, not a silently-ignored arg. A
|
|
101
|
+
// command that DOES take an operand (`use <agent>`) raises the ceiling.
|
|
102
|
+
const ceiling = 1 + (opts.maxOperands ?? 0);
|
|
103
|
+
if (parsed.positionals.length > ceiling) {
|
|
104
|
+
throw new CliError("usage", `unexpected argument: ${parsed.positionals[ceiling]}. Run 'oh-hai <command> --help'.`);
|
|
77
105
|
}
|
|
78
106
|
return parsed;
|
|
79
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../../src/commands/flags.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../../src/commands/flags.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,17 +10,25 @@ import { inboxCommand } from "./inbox.js";
|
|
|
10
10
|
import { loginCommand } from "./login.js";
|
|
11
11
|
import { logoutCommand } from "./logout.js";
|
|
12
12
|
import { notifyCommand } from "./notify.js";
|
|
13
|
+
import { setupCommand } from "./setup.js";
|
|
13
14
|
import { taskCommand } from "./task.js";
|
|
15
|
+
import { teachCommand } from "./teach.js";
|
|
16
|
+
import { upgradeCommand } from "./upgrade.js";
|
|
17
|
+
import { useCommand } from "./use.js";
|
|
14
18
|
import { whoamiCommand } from "./whoami.js";
|
|
15
19
|
export const COMMAND_HANDLERS = {
|
|
20
|
+
setup: setupCommand,
|
|
16
21
|
login: loginCommand,
|
|
17
22
|
logout: logoutCommand,
|
|
18
23
|
whoami: whoamiCommand,
|
|
24
|
+
use: useCommand,
|
|
19
25
|
notify: notifyCommand,
|
|
20
26
|
ask: askCommand,
|
|
21
27
|
task: taskCommand,
|
|
22
28
|
agents: agentsCommand,
|
|
23
29
|
inbox: inboxCommand,
|
|
24
30
|
doctor: doctorCommand,
|
|
31
|
+
teach: teachCommand,
|
|
32
|
+
upgrade: upgradeCommand,
|
|
25
33
|
};
|
|
26
34
|
//# sourceMappingURL=handlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/commands/handlers.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,4FAA4F;AAC5F,2FAA2F;AAC3F,uFAAuF;AACvF,2FAA2F;AAE3F,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,gBAAgB,GAAmC;IAC9D,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/commands/handlers.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,4FAA4F;AAC5F,2FAA2F;AAC3F,uFAAuF;AACvF,2FAA2F;AAE3F,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,gBAAgB,GAAmC;IAC9D,KAAK,EAAE,YAAY;IACnB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,GAAG,EAAE,UAAU;IACf,MAAM,EAAE,aAAa;IACrB,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,OAAO,EAAE,cAAc;CACxB,CAAC"}
|