@oh-hai/cli 0.1.0-beta.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +41 -11
- package/dist/cli.js.map +1 -1
- package/dist/commands/context.d.ts +12 -0
- package/dist/commands/handlers.js +2 -0
- package/dist/commands/handlers.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/validate.js +1 -11
- package/dist/commands/messaging/validate.js.map +1 -1
- package/dist/commands/registry.js +17 -0
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/setup.d.ts +9 -0
- package/dist/commands/setup.js +121 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/help.js +1 -0
- 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/url.d.ts +1 -0
- package/dist/url.js +15 -0
- package/dist/url.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -13,9 +13,12 @@ import { openStore } from "./auth/token-store.js";
|
|
|
13
13
|
import { GLOBAL_OPTIONS, flagOn } from "./commands/flags.js";
|
|
14
14
|
import { COMMAND_HANDLERS } from "./commands/handlers.js";
|
|
15
15
|
import { findCommand } from "./commands/registry.js";
|
|
16
|
+
import { setupCommand } from "./commands/setup.js";
|
|
16
17
|
import { notImplemented } from "./commands/stub.js";
|
|
18
|
+
import { machineStatus } from "./onboarding/status.js";
|
|
17
19
|
import { resolveConfig } from "./config.js";
|
|
18
20
|
import { loadConfigFiles, nodeConfigFileIo } from "./config-file.js";
|
|
21
|
+
import { openInBrowser } from "./onboarding/open-url.js";
|
|
19
22
|
import { CliError, buildErr, buildOk, serializeEnvelope } from "./envelope.js";
|
|
20
23
|
import { ExitCode } from "./exit-codes.js";
|
|
21
24
|
import { TOP_LEVEL_HELP } from "./help.js";
|
|
@@ -62,6 +65,12 @@ const productionRuntime = {
|
|
|
62
65
|
// for a queued-but-below-high-water-mark write. On a write error (e.g. EPIPE — the consumer closed
|
|
63
66
|
// the pipe) the barrier rejects, so the loop exits WITHOUT acking an undelivered directive.
|
|
64
67
|
flushOutput: () => new Promise((resolve, reject) => process.stdout.write("", (err) => (err ? reject(err) : resolve()))),
|
|
68
|
+
// Onboarding device-approval: open the verification URL in the user's browser (#271). Best-effort —
|
|
69
|
+
// resolves false when it can't, so the device-code flow prints the URL + code as the fallback.
|
|
70
|
+
openBrowser: (url) => openInBrowser(url),
|
|
71
|
+
// Whether a human is at the terminal — gates the `setup` reconnect prompt so a piped/CI run reports
|
|
72
|
+
// status instead of blocking on a read (`readLine` being wired says nothing about interactivity).
|
|
73
|
+
isInteractive: () => Boolean(process.stdin.isTTY),
|
|
65
74
|
};
|
|
66
75
|
/**
|
|
67
76
|
* True when `moduleUrl`'s file is the process entrypoint. Compares REAL paths (resolving
|
|
@@ -151,19 +160,20 @@ export async function run(argv, io = consoleIo, runtime = productionRuntime) {
|
|
|
151
160
|
return ExitCode.SUCCESS;
|
|
152
161
|
}
|
|
153
162
|
const command = positionals[0];
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
|
|
163
|
+
// Explicit top-level `--help` (no command) stays config-free — help text only, no config I/O or
|
|
164
|
+
// credential warnings. Truly-bare `oh-hai` (no command, no --help) is the onboarding entrypoint,
|
|
165
|
+
// handled after config resolution below (it needs the resolved Hub + the store).
|
|
166
|
+
if (command === undefined && flagOn(values.help)) {
|
|
157
167
|
emitHelp(TOP_LEVEL_HELP);
|
|
158
168
|
return ExitCode.SUCCESS;
|
|
159
169
|
}
|
|
160
|
-
commandLabel = command;
|
|
161
|
-
// Resolve config (§6)
|
|
162
|
-
// format applies uniformly
|
|
163
|
-
// the not-implemented decline,
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
170
|
+
commandLabel = command ?? "oh-hai";
|
|
171
|
+
// Resolve config (§6) for every non-meta path — a NAMED command AND bare onboarding — so a
|
|
172
|
+
// config-selected output format applies uniformly: the unknown-command error, per-command --help,
|
|
173
|
+
// the not-implemented decline, real handlers, and the first-run onboarding. Pure meta flags
|
|
174
|
+
// (--version, top-level --help) returned above, so they stay config-free — no config I/O or
|
|
175
|
+
// credential warnings on `oh-hai --version` / `oh-hai --help`. `warnings` carries the
|
|
176
|
+
// credential-safety rejections (a per-project config that tried to set base_url / account) —
|
|
167
177
|
// surfaced on stderr so they never pollute the --json envelope on stdout.
|
|
168
178
|
const { userConfig, projectConfig } = runtime.loadConfigFiles();
|
|
169
179
|
const { config, warnings } = resolveConfig({
|
|
@@ -179,6 +189,26 @@ export async function run(argv, io = consoleIo, runtime = productionRuntime) {
|
|
|
179
189
|
// throw so the catch-block error envelope (an unknown command, a bad --timeout, a stub decline)
|
|
180
190
|
// respects the configured format too. `config.output` already folds in the --json flag.
|
|
181
191
|
json = config.output === "json";
|
|
192
|
+
// Validate `--timeout` for EVERY dispatched path — including bare onboarding below and the stub —
|
|
193
|
+
// not just implemented handlers. Otherwise `oh-hai --timeout=-1` on a fresh machine would treat the
|
|
194
|
+
// malformed value as absent and start browser authorization instead of returning the §7 usage error.
|
|
195
|
+
validateTimeoutFlag(values);
|
|
196
|
+
// Bare `oh-hai` (no command) is the platinum first-run onboarding entrypoint (#271): with no
|
|
197
|
+
// stored auth for this Hub it drops straight into `setup`; once set up it behaves as it always
|
|
198
|
+
// has and prints the top-level help. `--help` was handled config-free above; every named command
|
|
199
|
+
// falls through to dispatch below. `machineStatus` opens the store lazily via the thunk, so an
|
|
200
|
+
// env-token bare run takes the env short-circuit with no keychain probe at all.
|
|
201
|
+
if (command === undefined) {
|
|
202
|
+
const status = await machineStatus(config, runtime.openStore);
|
|
203
|
+
if (!status.setUp) {
|
|
204
|
+
commandLabel = "setup"; // so a device-flow error reports under the `setup` command label (§8)
|
|
205
|
+
// Reuse the status we just resolved so `setup` doesn't recompute it.
|
|
206
|
+
await setupCommand({ io, json, config, runtime, argv }, { status });
|
|
207
|
+
return ExitCode.SUCCESS;
|
|
208
|
+
}
|
|
209
|
+
emitHelp(TOP_LEVEL_HELP);
|
|
210
|
+
return ExitCode.SUCCESS;
|
|
211
|
+
}
|
|
182
212
|
const spec = findCommand(command);
|
|
183
213
|
if (spec === undefined) {
|
|
184
214
|
throw new CliError("usage", `unknown command: ${command}. Run 'oh-hai --help'.`);
|
|
@@ -204,7 +234,7 @@ export async function run(argv, io = consoleIo, runtime = productionRuntime) {
|
|
|
204
234
|
// check (a throw would replace the `--json` checks envelope with a `buildErr` one).
|
|
205
235
|
const handler = COMMAND_HANDLERS[spec.name];
|
|
206
236
|
if (handler !== undefined) {
|
|
207
|
-
|
|
237
|
+
// `--timeout` was already validated above (before the bare branch), covering every dispatched path.
|
|
208
238
|
const result = await handler({ io, json, config, runtime, argv });
|
|
209
239
|
return typeof result === "number" ? result : ExitCode.SUCCESS;
|
|
210
240
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,sFAAsF;AACtF,4FAA4F;AAC5F,6FAA6F;AAC7F,+FAA+F;AAC/F,8FAA8F;AAC9F,yEAAyE;AAEzE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI7D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,0FAA0F;AAC1F,MAAM,SAAS,GAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;AAE/D,yFAAyF;AACzF,KAAK,UAAU,YAAY;IACzB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED;;qDAEqD;AACrD,KAAK,UAAU,gBAAgB;IAC7B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,EAAE,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;4FAC4F;AAC5F,MAAM,iBAAiB,GAAgB;IACrC,SAAS;IACT,SAAS,EAAE,YAAY;IACvB,QAAQ,EAAE,gBAAgB;IAC1B,SAAS,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC;IAC1C,eAAe,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,gBAAgB,EAAE,CAAC;IAC1D,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChE,sFAAsF;IACtF,mGAAmG;IACnG,oGAAoG;IACpG,oGAAoG;IACpG,mGAAmG;IACnG,4FAA4F;IAC5F,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACvH,oGAAoG;IACpG,+FAA+F;IAC/F,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC;IACxC,oGAAoG;IACpG,kGAAkG;IAClG,aAAa,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;CAClD,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,WAA+B,EAAE,SAAiB;IAC7E,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,WAAW,CAAC,KAAK,YAAY,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,SAAS,UAAU,CAAC,MAA+B;IACjD,MAAM,GAAG,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxF,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzF,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAChC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QACjD,+FAA+F;QAC/F,4FAA4F;QAC5F,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QACjE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACnC,SAAS,EAAE,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;KAC3G,CAAC;AACJ,CAAC;AAED;iGACiG;AACjG,SAAS,mBAAmB,CAAC,MAA+B;IAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;IAC3B,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,mDAAmD,CAAC,CAAC;IAC5G,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,SAAS,SAAS,CAAC,GAAsB;IACvC,OAAO;QACL,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACvB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,IAAc,EACd,KAAS,SAAS,EAClB,UAAuB,iBAAiB;IAExC,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,YAAY,GAAG,QAAQ,CAAC;IAE5B,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;YACxC,IAAI,EAAE,IAAI;YACV,gBAAgB,EAAE,IAAI;YACtB,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,cAAc;SACxB,CAAC,CAAC;QAEH,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,uFAAuF;QACvF,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAQ,EAAE;YACtC,IAAI,IAAI,EAAE,CAAC;gBACT,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QACH,CAAC,CAAC;QAEF,2CAA2C;QAC3C,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,IAAI,IAAI,EAAE,CAAC;gBACT,EAAE,CAAC,GAAG,CACJ,iBAAiB,CACf,OAAO,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC,CAC/E,CACF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;YACvB,CAAC;YACD,OAAO,QAAQ,CAAC,OAAO,CAAC;QAC1B,CAAC;QAED,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAE/B,gGAAgG;QAChG,iGAAiG;QACjG,iFAAiF;QACjF,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACjD,QAAQ,CAAC,cAAc,CAAC,CAAC;YACzB,OAAO,QAAQ,CAAC,OAAO,CAAC;QAC1B,CAAC;QAED,YAAY,GAAG,OAAO,IAAI,QAAQ,CAAC;QAEnC,2FAA2F;QAC3F,kGAAkG;QAClG,4FAA4F;QAC5F,4FAA4F;QAC5F,sFAAsF;QACtF,6FAA6F;QAC7F,0EAA0E;QAC1E,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;QAChE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;YACzC,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC;YACzB,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;YAC3B,UAAU;YACV,aAAa;SACd,CAAC,CAAC;QACH,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,EAAE,CAAC,GAAG,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;QAC/B,CAAC;QACD,kGAAkG;QAClG,gGAAgG;QAChG,wFAAwF;QACxF,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC;QAEhC,kGAAkG;QAClG,oGAAoG;QACpG,qGAAqG;QACrG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAE5B,6FAA6F;QAC7F,+FAA+F;QAC/F,iGAAiG;QACjG,+FAA+F;QAC/F,gFAAgF;QAChF,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YAC9D,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAClB,YAAY,GAAG,OAAO,CAAC,CAAC,sEAAsE;gBAC9F,qEAAqE;gBACrE,MAAM,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBACpE,OAAO,QAAQ,CAAC,OAAO,CAAC;YAC1B,CAAC;YACD,QAAQ,CAAC,cAAc,CAAC,CAAC;YACzB,OAAO,QAAQ,CAAC,OAAO,CAAC;QAC1B,CAAC;QAED,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,oBAAoB,OAAO,wBAAwB,CAAC,CAAC;QACnF,CAAC;QAED,8FAA8F;QAC9F,mGAAmG;QACnG,gGAAgG;QAChG,0FAA0F;QAC1F,MAAM,GAAG,GACP,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YACzB,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACxE,CAAC,CAAC,SAAS,CAAC;QAChB,YAAY,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAErE,oBAAoB;QACpB,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO,QAAQ,CAAC,OAAO,CAAC;QAC1B,CAAC;QAED,gGAAgG;QAChG,mGAAmG;QACnG,iGAAiG;QACjG,6FAA6F;QAC7F,kGAAkG;QAClG,oFAAoF;QACpF,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,oGAAoG;YACpG,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAChE,CAAC;QAED,kDAAkD;QAClD,MAAM,OAAO,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACtE,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,GACZ,KAAK,YAAY,QAAQ;YACvB,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACpF,IAAI,IAAI,EAAE,CAAC;YACT,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrF,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,GAAG,CAAC,WAAW,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAC3B,CAAC;IAED,wFAAwF;IACxF,wEAAwE;IACxE,OAAO,QAAQ,CAAC,OAAO,CAAC;AAC1B,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,qEAAqE;AACrE,IAAI,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACnD,KAAK,IAAI,EAAE,CAAC;AACd,CAAC"}
|
|
@@ -52,6 +52,18 @@ export interface RuntimeDeps {
|
|
|
52
52
|
* — a caller that omits it (and every hermetic test) skips the wait, since in-memory IO never
|
|
53
53
|
* backpressures. Production awaits `process.stdout` drain. */
|
|
54
54
|
flushOutput?: () => Promise<void>;
|
|
55
|
+
/** Open a URL in the user's browser for the onboarding device-approval step (§4.3, #271). Resolves
|
|
56
|
+
* `true` when the opener launched, `false` when it couldn't (no browser / non-http(s) URL) so the
|
|
57
|
+
* caller prints the URL instead. Optional — an omitting caller (and hermetic tests that don't pass
|
|
58
|
+
* one) is treated as "couldn't open", so the flow always degrades to the printed fallback. */
|
|
59
|
+
openBrowser?: (url: string) => Promise<boolean>;
|
|
60
|
+
/** True when stdin is an interactive terminal (§4.3, #271). `oh-hai setup` on an already-set-up
|
|
61
|
+
* machine only PROMPTS to reconnect when interactive — under a pipe / CI it reports status and exits
|
|
62
|
+
* instead of blocking on a read that may never get a line. Production wires `process.stdin.isTTY`;
|
|
63
|
+
* an omitting caller (and hermetic tests that don't set it) is treated as NON-interactive, so no test
|
|
64
|
+
* ever blocks on a prompt by accident. Distinct from `readLine`, which merely READS a line — its
|
|
65
|
+
* presence says nothing about whether a human is there to answer. */
|
|
66
|
+
isInteractive?: () => boolean;
|
|
55
67
|
}
|
|
56
68
|
export interface CommandContext {
|
|
57
69
|
io: Io;
|
|
@@ -10,9 +10,11 @@ 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";
|
|
14
15
|
import { whoamiCommand } from "./whoami.js";
|
|
15
16
|
export const COMMAND_HANDLERS = {
|
|
17
|
+
setup: setupCommand,
|
|
16
18
|
login: loginCommand,
|
|
17
19
|
logout: logoutCommand,
|
|
18
20
|
whoami: whoamiCommand,
|
|
@@ -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;CACtB,CAAC"}
|
|
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,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,MAAM,EAAE,aAAa;IACrB,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,aAAa;IACrB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,aAAa;CACtB,CAAC"}
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
import type { CommandContext } from "./context.js";
|
|
2
2
|
export declare function loginCommand(ctx: CommandContext): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* The device-code acquisition (§4.3/§1, RFC 8628), shared by `oh-hai login`, `oh-hai setup`, and the
|
|
5
|
+
* bare-`oh-hai` first-run onboarding (#271). Requests a device code, opens the human's browser to the
|
|
6
|
+
* approval URL (falling back to PRINTING it), prompts on STDERR (stdout stays reserved for the single
|
|
7
|
+
* `--json` envelope, §8), then polls until the human approves — storing the returned bearer under
|
|
8
|
+
* `<origin>|<agent id>`. The agent id comes FROM the token response (the human chose which agent to
|
|
9
|
+
* bind at approval time, in the browser), so this path needs no `--account`, unlike `--token-stdin`.
|
|
10
|
+
* `command` is the §8 envelope label the success reports under — "login" for `oh-hai login`, "setup"
|
|
11
|
+
* for the onboarding entrypoints — so `--json` automation dispatching on `command` stays consistent.
|
|
12
|
+
* Returns the AGENT ID the approved bearer was stored under (the one the human bound in the browser),
|
|
13
|
+
* so the onboarding caller can reconcile it against the resolver's precedence and give honest next steps.
|
|
14
|
+
*/
|
|
15
|
+
export declare function runDeviceCodeFlow(ctx: CommandContext, command?: string): Promise<string>;
|
package/dist/commands/login.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { CliError, buildOk, serializeEnvelope } from "../envelope.js";
|
|
10
10
|
import { originOf } from "../auth/resolve-token.js";
|
|
11
11
|
import { sanitizeForTerminal } from "../terminal.js";
|
|
12
|
+
import { isHttpUrl } from "../url.js";
|
|
12
13
|
import { flagOn, parseCommandArgs } from "./flags.js";
|
|
13
14
|
import { throwTransportError } from "./http.js";
|
|
14
15
|
/** Per-request bound for each device-grant POST when no `--timeout`/`MA2H_TIMEOUT_MS` is set. It
|
|
@@ -36,7 +37,7 @@ export async function loginCommand(ctx) {
|
|
|
36
37
|
await tokenStdinLogin(ctx);
|
|
37
38
|
}
|
|
38
39
|
else {
|
|
39
|
-
await
|
|
40
|
+
await runDeviceCodeFlow(ctx);
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
/** `--token-stdin` (§4.3): read a bearer from stdin (local bootstrap / paste) and store it the same
|
|
@@ -54,19 +55,35 @@ async function tokenStdinLogin(ctx) {
|
|
|
54
55
|
await storeAndReport(ctx, account, token);
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
|
-
* The
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
58
|
+
* The device-code acquisition (§4.3/§1, RFC 8628), shared by `oh-hai login`, `oh-hai setup`, and the
|
|
59
|
+
* bare-`oh-hai` first-run onboarding (#271). Requests a device code, opens the human's browser to the
|
|
60
|
+
* approval URL (falling back to PRINTING it), prompts on STDERR (stdout stays reserved for the single
|
|
61
|
+
* `--json` envelope, §8), then polls until the human approves — storing the returned bearer under
|
|
62
|
+
* `<origin>|<agent id>`. The agent id comes FROM the token response (the human chose which agent to
|
|
63
|
+
* bind at approval time, in the browser), so this path needs no `--account`, unlike `--token-stdin`.
|
|
64
|
+
* `command` is the §8 envelope label the success reports under — "login" for `oh-hai login`, "setup"
|
|
65
|
+
* for the onboarding entrypoints — so `--json` automation dispatching on `command` stays consistent.
|
|
66
|
+
* Returns the AGENT ID the approved bearer was stored under (the one the human bound in the browser),
|
|
67
|
+
* so the onboarding caller can reconcile it against the resolver's precedence and give honest next steps.
|
|
62
68
|
*/
|
|
63
|
-
async function
|
|
69
|
+
export async function runDeviceCodeFlow(ctx, command = "login") {
|
|
64
70
|
const code = await requestDeviceCode(ctx);
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
// Try to open the browser for the human first (#271 "platinum" onboarding — no copy-paste). The
|
|
72
|
+
// capability is optional and best-effort: `openBrowser` resolves false when it can't launch one
|
|
73
|
+
// (headless box, no opener), and every hermetic test omits it → the printed fallback below. `openUrl`
|
|
74
|
+
// prefers the one-click `verification_uri_complete` (embeds the code). All server-supplied strings are
|
|
75
|
+
// sanitized of control characters first — they're echoed straight to the terminal.
|
|
76
|
+
const opened = ctx.runtime.openBrowser !== undefined ? await ctx.runtime.openBrowser(code.openUrl) : false;
|
|
77
|
+
if (opened) {
|
|
78
|
+
ctx.io.err(`oh-hai: opened your browser to ${sanitizeForTerminal(code.openUrl)} — approve there.`);
|
|
79
|
+
// Still show the short code so the human can approve from ANOTHER device if the opened tab isn't
|
|
80
|
+
// where they're signed in.
|
|
81
|
+
ctx.io.err(`oh-hai: if it didn't open, enter this code there: ${sanitizeForTerminal(code.userCode)}`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
ctx.io.err(`oh-hai: to authorize this device, open ${sanitizeForTerminal(code.openUrl)}`);
|
|
85
|
+
ctx.io.err(`oh-hai: and enter the code: ${sanitizeForTerminal(code.userCode)}`);
|
|
86
|
+
}
|
|
70
87
|
ctx.io.err("oh-hai: waiting for approval…");
|
|
71
88
|
// Poll budget: the server expires the code and returns `expired_token` at the real deadline; this
|
|
72
89
|
// cap is a pure anti-infinite-loop guard against a server that never returns a terminal state.
|
|
@@ -83,8 +100,8 @@ async function deviceCodeLogin(ctx) {
|
|
|
83
100
|
const res = await hubPost(ctx, "/auth/device/token", { device_code: code.deviceCode });
|
|
84
101
|
if (res.status === 200) {
|
|
85
102
|
const token = await readAccessToken(res);
|
|
86
|
-
await storeAndReport(ctx, token.agentId, token.accessToken);
|
|
87
|
-
return;
|
|
103
|
+
await storeAndReport(ctx, token.agentId, token.accessToken, command);
|
|
104
|
+
return token.agentId;
|
|
88
105
|
}
|
|
89
106
|
// The Hub's per-IP limiter throttles the shared device surface with HTTP 429 `rate_limited`
|
|
90
107
|
// (+ Retry-After); a legit poller (e.g. behind a corporate NAT) can trip it mid-approval, so
|
|
@@ -122,14 +139,15 @@ async function deviceCodeLogin(ctx) {
|
|
|
122
139
|
throw new CliError("timeout", "device authorization did not complete before the code expired; run `oh-hai login` again.");
|
|
123
140
|
}
|
|
124
141
|
/** Store the bearer Hub-scoped (§5.1) and report success. The token is NEVER in the output (§5.4);
|
|
125
|
-
* an existing token for this identity is overwritten silently (§4.3). Shared by both login paths
|
|
126
|
-
|
|
142
|
+
* an existing token for this identity is overwritten silently (§4.3). Shared by both login paths and
|
|
143
|
+
* the onboarding entrypoints — `command` labels the §8 success envelope ("login" / "setup"). */
|
|
144
|
+
async function storeAndReport(ctx, agentId, token, command = "login") {
|
|
127
145
|
const store = await ctx.runtime.openStore();
|
|
128
146
|
await store.set(originOf(ctx.config.baseUrl), agentId, token);
|
|
129
147
|
if (ctx.json) {
|
|
130
148
|
// No token field, ever (§5.4). `storage` reports which backend actually holds it. The agent id
|
|
131
149
|
// is emitted raw — JSON.stringify escapes any control character, so it can't reach the terminal.
|
|
132
|
-
ctx.io.log(serializeEnvelope(buildOk(
|
|
150
|
+
ctx.io.log(serializeEnvelope(buildOk(command, { agent_id: agentId, base_url: ctx.config.baseUrl, storage: store.backendName })));
|
|
133
151
|
}
|
|
134
152
|
else {
|
|
135
153
|
// Sanitize the DISPLAYED agent id — on the device-code path it's server-supplied, so a hostile
|
|
@@ -251,16 +269,6 @@ function str(value) {
|
|
|
251
269
|
const trimmed = value.trim();
|
|
252
270
|
return trimmed === "" ? undefined : trimmed;
|
|
253
271
|
}
|
|
254
|
-
/** True when `value` parses as an http(s) URL — the only schemes we invite the user to open (§4.3). */
|
|
255
|
-
function isHttpUrl(value) {
|
|
256
|
-
try {
|
|
257
|
-
const { protocol } = new URL(value);
|
|
258
|
-
return protocol === "http:" || protocol === "https:";
|
|
259
|
-
}
|
|
260
|
-
catch {
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
272
|
/** An integer from an unknown response field, clamped to `[min, max]`; `fallback` (already in range)
|
|
265
273
|
* is used when the value is missing or non-finite. Clamping means a missing, zero, fractional
|
|
266
274
|
* (floors to 0), negative, or absurdly large server-supplied `interval` / `expires_in` can never
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,4FAA4F;AAC5F,4FAA4F;AAC5F,0FAA0F;AAC1F,8FAA8F;AAC9F,gGAAgG;AAChG,kGAAkG;AAClG,8EAA8E;AAE9E,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// so tests stay hermetic.
|
|
7
7
|
import { readFileSync } from "node:fs";
|
|
8
8
|
import { CliError } from "../../envelope.js";
|
|
9
|
+
import { isHttpUrl } from "../../url.js";
|
|
9
10
|
export const PRIORITIES = ["low", "normal", "high", "urgent"];
|
|
10
11
|
export const REQUEST_MODES = ["select", "input", "confirm"];
|
|
11
12
|
export const CALLBACK_MODES = ["pull", "push"];
|
|
@@ -23,17 +24,6 @@ export function isCallbackMode(value) {
|
|
|
23
24
|
export function isActor(value) {
|
|
24
25
|
return /^(human|agent|system):[^\s]+$/.test(value);
|
|
25
26
|
}
|
|
26
|
-
/** True when `raw` parses as an http(s) URL — the only schemes the Hub's SSRF delivery guard
|
|
27
|
-
* accepts for a push callback, so a mailto:/file: url would silently lose the push. */
|
|
28
|
-
function isHttpUrl(raw) {
|
|
29
|
-
try {
|
|
30
|
-
const u = new URL(raw);
|
|
31
|
-
return u.protocol === "http:" || u.protocol === "https:";
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
27
|
/** Normalize a push `--callback-url` to the canonical WHATWG href the Hub signs and `fetch` POSTs
|
|
38
28
|
* to (so the signed callback_url can't desync from the delivery URL), and enforce http(s) — the
|
|
39
29
|
* Hub's SSRF delivery guard rejects every other scheme, so a mailto:/file: url would pass
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/messaging/validate.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,wFAAwF;AACxF,4FAA4F;AAC5F,yFAAyF;AACzF,gGAAgG;AAChG,0BAA0B;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/messaging/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
// messaging #107, agents #209, health/doctor #108). Subcommands are listed so the
|
|
4
4
|
// dispatcher can form the envelope `command` name (e.g. "ask.submit") and print per-command help.
|
|
5
5
|
export const COMMANDS = [
|
|
6
|
+
{
|
|
7
|
+
name: "setup",
|
|
8
|
+
summary: "first-run onboarding — connect this machine (no key to copy)",
|
|
9
|
+
issue: 271,
|
|
10
|
+
subcommands: [],
|
|
11
|
+
help: [
|
|
12
|
+
"oh-hai setup — connect this machine to OH HAI (cli spec §4.3).",
|
|
13
|
+
"",
|
|
14
|
+
"Usage: oh-hai setup",
|
|
15
|
+
"",
|
|
16
|
+
"The platinum first-run flow: opens your browser to approve this device, where you",
|
|
17
|
+
"pick (or create) an agent — no token is ever shown, typed, or pasted. The approved",
|
|
18
|
+
"bearer is stored in the OS keychain (or a 0600 file fallback). Bare `oh-hai` with no",
|
|
19
|
+
"stored auth runs this automatically. Re-running on a set-up machine offers to connect",
|
|
20
|
+
"another agent or re-authorize — never a dead end.",
|
|
21
|
+
].join("\n"),
|
|
22
|
+
},
|
|
6
23
|
{
|
|
7
24
|
name: "login",
|
|
8
25
|
summary: "acquire a token → OS keychain (never printed)",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,mFAAmF;AACnF,kFAAkF;AAClF,kGAAkG;AAelG,MAAM,CAAC,MAAM,QAAQ,GAA2B;IAC9C;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,8DAA8D;QACvE,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,EAAE;QACf,IAAI,EAAE;YACJ,gEAAgE;YAChE,EAAE;YACF,qBAAqB;YACrB,EAAE;YACF,mFAAmF;YACnF,oFAAoF;YACpF,sFAAsF;YACtF,uFAAuF;YACvF,mDAAmD;SACpD,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,+CAA+C;QACxD,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,EAAE;QACf,IAAI,EAAE;YACJ,iEAAiE;YACjE,EAAE;YACF,wCAAwC;YACxC,uEAAuE;YACvE,EAAE;YACF,mFAAmF;YACnF,mFAAmF;YACnF,yEAAyE;YACzE,mFAAmF;YACnF,qCAAqC;SACtC,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,yBAAyB;QAClC,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,EAAE;QACf,IAAI,EAAE;YACJ,kFAAkF;YAClF,EAAE;YACF,+CAA+C;YAC/C,EAAE;YACF,6DAA6D;SAC9D,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,6DAA6D;QACtE,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,EAAE;QACf,IAAI,EAAE;YACJ,0EAA0E;YAC1E,EAAE;YACF,gCAAgC;YAChC,EAAE;YACF,qFAAqF;SACtF,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,uCAAuC;QAChD,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,EAAE;QACf,IAAI,EAAE;YACJ,uEAAuE;YACvE,EAAE;YACF,qFAAqF;YACrF,iDAAiD;YACjD,EAAE;YACF,2EAA2E;SAC5E,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,gCAAgC;QACzC,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;QAChC,IAAI,EAAE;YACJ,wCAAwC;YACxC,EAAE;YACF,oEAAoE;YACpE,wFAAwF;YACxF,6EAA6E;YAC7E,EAAE;YACF,wDAAwD;SACzD,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,qCAAqC;QAC9C,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;QAChC,IAAI,EAAE;YACJ,6CAA6C;YAC7C,EAAE;YACF,mFAAmF;YACnF,0EAA0E;YAC1E,8EAA8E;YAC9E,EAAE;YACF,yCAAyC;SAC1C,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,yCAAyC;QAClD,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC;QACzC,IAAI,EAAE;YACJ,gDAAgD;YAChD,EAAE;YACF,2BAA2B;YAC3B,6CAA6C;YAC7C,yDAAyD;YACzD,EAAE;YACF,oBAAoB;SACrB,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,8DAA8D;QACvE,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,CAAC,OAAO,CAAC;QACtB,IAAI,EAAE;YACJ,yDAAyD;YACzD,EAAE;YACF,kEAAkE;YAClE,EAAE;YACF,6EAA6E;YAC7E,6EAA6E;YAC7E,8EAA8E;YAC9E,8EAA8E;YAC9E,gFAAgF;YAChF,oBAAoB;SACrB,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,uDAAuD;QAChE,KAAK,EAAE,GAAG;QACV,WAAW,EAAE,EAAE;QACf,IAAI,EAAE;YACJ,kEAAkE;YAClE,EAAE;YACF,sCAAsC;YACtC,EAAE;YACF,+FAA+F;SAChG,CAAC,IAAI,CAAC,IAAI,CAAC;KACb;CACF,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type MachineStatus } from "../onboarding/status.js";
|
|
2
|
+
import type { CommandContext } from "./context.js";
|
|
3
|
+
/** Optional pre-resolved status, passed by the bare-`oh-hai` dispatch (cli.ts) which has ALREADY
|
|
4
|
+
* computed the status to decide help-vs-onboarding — so setup doesn't recompute (and, on the env-token
|
|
5
|
+
* path, doesn't touch the keychain a second time). */
|
|
6
|
+
export interface SetupPrecomputed {
|
|
7
|
+
status?: MachineStatus;
|
|
8
|
+
}
|
|
9
|
+
export declare function setupCommand(ctx: CommandContext, pre?: SetupPrecomputed): Promise<void>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// `oh-hai setup` (docs/specs/cli.md §4.3; issue #271) — the platinum first-run onboarding entrypoint.
|
|
2
|
+
// Bare `oh-hai` with no stored auth drops straight into this flow (cli.ts); it's also runnable
|
|
3
|
+
// explicitly. It composes already-shipped pieces so the human NEVER copies or pastes a key:
|
|
4
|
+
//
|
|
5
|
+
// - NOT set up → onboarding: friendly framing, then the shared device-code flow (login.ts) which
|
|
6
|
+
// opens the browser (falls back to printing the URL + code) and stores the bearer the human's
|
|
7
|
+
// browser approval minted — bound to the agent they picked/created on /activate. Then a
|
|
8
|
+
// next-steps hint. Agent selection lives in the BROWSER (server #193 + web /activate #194/#198),
|
|
9
|
+
// which is why this path needs no --account and mints nothing itself.
|
|
10
|
+
// - ALREADY set up → never a dead end: report the current identity, and (interactively) offer to
|
|
11
|
+
// connect another agent / re-authorize. Under --json or a non-interactive stdin, just report and
|
|
12
|
+
// exit 0 — no prompt, no hang.
|
|
13
|
+
import { originOf } from "../auth/resolve-token.js";
|
|
14
|
+
import { buildOk, serializeEnvelope } from "../envelope.js";
|
|
15
|
+
import { sanitizeForTerminal } from "../terminal.js";
|
|
16
|
+
import { machineStatus } from "../onboarding/status.js";
|
|
17
|
+
import { parseCommandArgs } from "./flags.js";
|
|
18
|
+
import { runDeviceCodeFlow } from "./login.js";
|
|
19
|
+
export async function setupCommand(ctx, pre = {}) {
|
|
20
|
+
// Reject stray flags/positionals like every other command (e.g. `oh-hai setup --chek` → exit 2).
|
|
21
|
+
parseCommandArgs(ctx.argv, {});
|
|
22
|
+
// `machineStatus` opens the store lazily via the thunk, so an env-token `oh-hai setup` never probes
|
|
23
|
+
// the keychain before reporting `already_configured`.
|
|
24
|
+
const status = pre.status ?? (await machineStatus(ctx.config, () => ctx.runtime.openStore()));
|
|
25
|
+
if (!status.setUp) {
|
|
26
|
+
await runOnboarding(ctx);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
await handleAlreadySetUp(ctx, status);
|
|
30
|
+
}
|
|
31
|
+
/** First-run onboarding: welcome → device-code flow (browser auto-open) → next steps. The device flow
|
|
32
|
+
* owns the success output (a human line on stdout, or the `--json` envelope); the framing lines go to
|
|
33
|
+
* stderr so they never pollute the `--json` stdout envelope (§8). A denied/expired code throws out of
|
|
34
|
+
* runDeviceCodeFlow and the next-steps line is (correctly) skipped. */
|
|
35
|
+
async function runOnboarding(ctx) {
|
|
36
|
+
if (!ctx.json) {
|
|
37
|
+
ctx.io.err(`oh-hai: let's connect this machine to ${originOf(ctx.config.baseUrl)}.`);
|
|
38
|
+
ctx.io.err("oh-hai: approve in your browser and pick (or create) an agent — no key to copy.");
|
|
39
|
+
}
|
|
40
|
+
// Pass the `setup` command label so the `--json` success envelope reports `command:"setup"` (not
|
|
41
|
+
// `login`), keeping the per-command JSON contract consistent for automation.
|
|
42
|
+
const agentId = await runDeviceCodeFlow(ctx, "setup");
|
|
43
|
+
await reportNextSteps(ctx, agentId);
|
|
44
|
+
}
|
|
45
|
+
/** Already-set-up re-run: report identity, then (interactively) offer to reconnect. Never dead-ends. */
|
|
46
|
+
async function handleAlreadySetUp(ctx, status) {
|
|
47
|
+
const hub = originOf(ctx.config.baseUrl);
|
|
48
|
+
if (ctx.json) {
|
|
49
|
+
// Machine-readable status only — never prompt/hang under --json.
|
|
50
|
+
ctx.io.log(serializeEnvelope(buildOk("setup", {
|
|
51
|
+
status: "already_configured",
|
|
52
|
+
base_url: ctx.config.baseUrl,
|
|
53
|
+
agent_id: status.agentId ?? null,
|
|
54
|
+
source: status.source,
|
|
55
|
+
})));
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
ctx.io.err(`oh-hai: this machine is connected to ${hub} ${describeIdentity(status)}.`);
|
|
59
|
+
// Never a dead end — but only PROMPT when a human is actually at the terminal. Gate on real TTY-ness,
|
|
60
|
+
// NOT on `readLine` presence: production always wires `readLine`, so a `readLine`-presence check would
|
|
61
|
+
// still prompt (and could block on `read`) under a pipe / CI. Non-interactive → report a path forward
|
|
62
|
+
// and exit. `readLine` may still be absent in a hermetic caller, so require it to actually read.
|
|
63
|
+
const interactive = (ctx.runtime.isInteractive?.() ?? false) && ctx.runtime.readLine !== undefined;
|
|
64
|
+
if (!interactive) {
|
|
65
|
+
ctx.io.log("Already set up. Re-run `oh-hai setup` in an interactive terminal to connect another agent.");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
ctx.io.err("Connect another agent or re-authorize? [y/N]: ");
|
|
69
|
+
const answer = (await ctx.runtime.readLine()).trim().toLowerCase();
|
|
70
|
+
if (answer === "y" || answer === "yes") {
|
|
71
|
+
const agentId = await runDeviceCodeFlow(ctx, "setup");
|
|
72
|
+
await reportNextSteps(ctx, agentId);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
ctx.io.log("Nothing to do — you're already set up.");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* After a successful connect, tell the human what actually happens next — honestly. Onboarding binds an
|
|
80
|
+
* agent in the BROWSER, but the no-flag `notify`/`ask`/`task` workflow resolves a credential by a fixed
|
|
81
|
+
* precedence (env token > configured account > sole stored identity, resolve-token.ts). When the bearer
|
|
82
|
+
* we just stored ISN'T what that resolver will pick, an unconditional "you're all set" would be a lie —
|
|
83
|
+
* the next command fails auth. So reconcile the stored agent against `machineStatus` (same precedence)
|
|
84
|
+
* and print the corrective next step instead. Human output only — the `--json` envelope already spoke.
|
|
85
|
+
*/
|
|
86
|
+
async function reportNextSteps(ctx, storedAgentId) {
|
|
87
|
+
if (ctx.json)
|
|
88
|
+
return;
|
|
89
|
+
const allSet = 'oh-hai: you\'re all set. Try `oh-hai notify --title "hello"`, or run `oh-hai doctor` to verify.';
|
|
90
|
+
const after = await machineStatus(ctx.config, () => ctx.runtime.openStore());
|
|
91
|
+
const stored = sanitizeForTerminal(storedAgentId);
|
|
92
|
+
// An env token outranks any stored bearer (§5.3): the new agent won't be used until it's unset.
|
|
93
|
+
if (after.source === "env") {
|
|
94
|
+
ctx.io.err(`oh-hai: connected as ${stored}, but MA2H_AGENT_TOKEN is set and takes precedence — unset it to use this agent.`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
// A configured account that isn't the agent just bound won't resolve this bearer (notify/ask look up
|
|
98
|
+
// only the configured account). Note this rather than claim success.
|
|
99
|
+
if (ctx.config.account !== undefined && ctx.config.account !== storedAgentId) {
|
|
100
|
+
ctx.io.err(`oh-hai: connected as ${stored}, but --account/MA2H_AGENT_ID is ${sanitizeForTerminal(ctx.config.account)}. ` +
|
|
101
|
+
`Run without --account, or set MA2H_AGENT_ID=${stored}, to use this agent.`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Zero-config resolution refuses to guess among multiple stored agents — adding a second one makes the
|
|
105
|
+
// no-flag workflow ambiguous, so point at the required --account rather than a bare "done".
|
|
106
|
+
if (ctx.config.account === undefined && after.storedCount > 1) {
|
|
107
|
+
ctx.io.err(`oh-hai: this machine now has ${after.storedCount} connected agents — run with --account ${stored} ` +
|
|
108
|
+
`(or set a default) to choose one.`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
ctx.io.err(allSet);
|
|
112
|
+
}
|
|
113
|
+
/** Human phrasing for who the machine is connected as, across the env / sole / multiple cases. */
|
|
114
|
+
function describeIdentity(status) {
|
|
115
|
+
if (status.agentId !== undefined)
|
|
116
|
+
return `as ${sanitizeForTerminal(status.agentId)}`;
|
|
117
|
+
if (status.source === "env")
|
|
118
|
+
return "via the MA2H_AGENT_TOKEN environment credential";
|
|
119
|
+
return `with ${status.storedCount} connected agents`;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,+FAA+F;AAC/F,4FAA4F;AAC5F,EAAE;AACF,mGAAmG;AACnG,kGAAkG;AAClG,4FAA4F;AAC5F,qGAAqG;AACrG,0EAA0E;AAC1E,mGAAmG;AACnG,qGAAqG;AACrG,mCAAmC;AAEnC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAsB,MAAM,yBAAyB,CAAC;AAE5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAS/C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAmB,EAAE,MAAwB,EAAE;IAChF,iGAAiG;IACjG,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAE/B,oGAAoG;IACpG,sDAAsD;IACtD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAE9F,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC;QACzB,OAAO;IACT,CAAC;IACD,MAAM,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED;;;wEAGwE;AACxE,KAAK,UAAU,aAAa,CAAC,GAAmB;IAC9C,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,yCAAyC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrF,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;IAChG,CAAC;IACD,iGAAiG;IACjG,6EAA6E;IAC7E,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,wGAAwG;AACxG,KAAK,UAAU,kBAAkB,CAAC,GAAmB,EAAE,MAAqB;IAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,iEAAiE;QACjE,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,iBAAiB,CACf,OAAO,CAAC,OAAO,EAAE;YACf,MAAM,EAAE,oBAAoB;YAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO;YAC5B,QAAQ,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;YAChC,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CACH,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,wCAAwC,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAEvF,sGAAsG;IACtG,uGAAuG;IACvG,sGAAsG;IACtG,iGAAiG;IACjG,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC;IACnG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAC;QACzG,OAAO;IACT,CAAC;IAED,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,QAAS,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpE,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,eAAe,CAAC,GAAmB,EAAE,aAAqB;IACvE,IAAI,GAAG,CAAC,IAAI;QAAE,OAAO;IACrB,MAAM,MAAM,GAAG,iGAAiG,CAAC;IACjH,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAElD,gGAAgG;IAChG,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC3B,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,wBAAwB,MAAM,kFAAkF,CACjH,CAAC;QACF,OAAO;IACT,CAAC;IACD,qGAAqG;IACrG,qEAAqE;IACrE,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;QAC7E,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,wBAAwB,MAAM,oCAAoC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI;YAC3G,+CAA+C,MAAM,sBAAsB,CAC9E,CAAC;QACF,OAAO;IACT,CAAC;IACD,uGAAuG;IACvG,4FAA4F;IAC5F,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,gCAAgC,KAAK,CAAC,WAAW,0CAA0C,MAAM,GAAG;YAClG,mCAAmC,CACtC,CAAC;QACF,OAAO;IACT,CAAC;IACD,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,kGAAkG;AAClG,SAAS,gBAAgB,CAAC,MAAqB;IAC7C,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,MAAM,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IACrF,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK;QAAE,OAAO,iDAAiD,CAAC;IACtF,OAAO,QAAQ,MAAM,CAAC,WAAW,mBAAmB,CAAC;AACvD,CAAC"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const DEFAULT_BASE_URL = "
|
|
1
|
+
export declare const DEFAULT_BASE_URL = "https://inbox.ohhai.app";
|
|
2
2
|
export type OutputFormat = "human" | "json";
|
|
3
3
|
export type TokenSource = "env" | "keychain" | "file" | "none";
|
|
4
4
|
/** Global flags after parsing (the subset that feeds config resolution). */
|
package/dist/config.js
CHANGED
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
//
|
|
12
12
|
// #105 implements the resolution CONTRACT over an already-parsed, in-memory config object.
|
|
13
13
|
// The TOML file loader + per-project discovery + keychain read land in #106/#107.
|
|
14
|
-
|
|
14
|
+
// The production Hub — a shipped CLI must reach the real service with zero configuration (#271, R8).
|
|
15
|
+
// Local development points at a local hub by setting MA2H_BASE_URL (or `--base-url`), which outranks
|
|
16
|
+
// this default (§6 precedence).
|
|
17
|
+
export const DEFAULT_BASE_URL = "https://inbox.ohhai.app";
|
|
15
18
|
/** A string is "present" only when non-empty after trimming; the trimmed value is returned
|
|
16
19
|
* so stray whitespace never rides along into a base URL / account / token. */
|
|
17
20
|
function presentString(value) {
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,sFAAsF;AACtF,EAAE;AACF,sFAAsF;AACtF,2FAA2F;AAC3F,6FAA6F;AAC7F,2FAA2F;AAC3F,2FAA2F;AAC3F,0FAA0F;AAC1F,EAAE;AACF,2FAA2F;AAC3F,kFAAkF;AAElF,MAAM,CAAC,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/help.js
CHANGED
|
@@ -5,6 +5,7 @@ export const TOP_LEVEL_HELP = [
|
|
|
5
5
|
"",
|
|
6
6
|
"Usage: oh-hai [global flags] <command> [subcommand] [flags]",
|
|
7
7
|
"",
|
|
8
|
+
"Setup: setup (bare `oh-hai` on a new machine onboards; re-run to add/re-auth)",
|
|
8
9
|
"Auth: login | logout | whoami",
|
|
9
10
|
"Messaging: notify | ask | task",
|
|
10
11
|
"Inbox: inbox watch",
|
package/dist/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,qEAAqE;AAErE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,8DAA8D;IAC9D,EAAE;IACF,6DAA6D;IAC7D,EAAE;IACF,qCAAqC;IACrC,iCAAiC;IACjC,yBAAyB;IACzB,2CAA2C;IAC3C,oBAAoB;IACpB,EAAE;IACF,kFAAkF;IAClF,4CAA4C;CAC7C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,qEAAqE;AAErE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,8DAA8D;IAC9D,EAAE;IACF,6DAA6D;IAC7D,EAAE;IACF,sFAAsF;IACtF,qCAAqC;IACrC,iCAAiC;IACjC,yBAAyB;IACzB,2CAA2C;IAC3C,oBAAoB;IACpB,EAAE;IACF,kFAAkF;IAClF,4CAA4C;CAC7C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** The minimal child-process surface this util touches — `once('spawn'|'error')` to learn whether
|
|
2
|
+
* the opener launched, and `unref()` so it doesn't keep the event loop (or the CLI) alive. Node's
|
|
3
|
+
* real `ChildProcess` is structurally assignable, so the production `spawn` fits without a cast. */
|
|
4
|
+
export interface SpawnedOpener {
|
|
5
|
+
once(event: "spawn", listener: () => void): unknown;
|
|
6
|
+
once(event: "error", listener: (err: Error) => void): unknown;
|
|
7
|
+
unref(): void;
|
|
8
|
+
}
|
|
9
|
+
/** The `spawn` shape the util needs (file + argv + detached/ignore options). Injected so tests assert
|
|
10
|
+
* the exact opener + argv without launching anything. Node's `child_process.spawn` is assignable. */
|
|
11
|
+
export type SpawnLike = (file: string, args: string[], options: {
|
|
12
|
+
detached: boolean;
|
|
13
|
+
stdio: "ignore";
|
|
14
|
+
}) => SpawnedOpener;
|
|
15
|
+
export interface OpenUrlDeps {
|
|
16
|
+
/** Override the detected platform (tests exercise darwin / win32 / linux without three machines). */
|
|
17
|
+
platform?: NodeJS.Platform;
|
|
18
|
+
/** Inject the spawn implementation (tests). Defaults to the real `node:child_process` spawn. */
|
|
19
|
+
spawn?: SpawnLike;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Try to open `url` in the user's default browser. Resolves `true` when the opener process
|
|
23
|
+
* launched, `false` when it couldn't (non-http(s) URL, missing opener binary, spawn failure).
|
|
24
|
+
* Never throws — a `false` result is the caller's cue to print the URL + code instead.
|
|
25
|
+
*/
|
|
26
|
+
export declare function openInBrowser(url: string, deps?: OpenUrlDeps): Promise<boolean>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Best-effort browser opener for the onboarding flow (docs/specs/cli.md §4; issue #271). The
|
|
2
|
+
// device-code login prompts a human to APPROVE in their browser; "platinum" onboarding opens that
|
|
3
|
+
// URL for them instead of making them copy it. This is deliberately fire-and-forget and NON-fatal:
|
|
4
|
+
//
|
|
5
|
+
// - It launches the platform's own opener via `node:child_process` (no runtime dependency, mirroring
|
|
6
|
+
// the keychain backend's shell-out): macOS `open`, Windows `cmd /c start`, else `xdg-open`.
|
|
7
|
+
// - It returns whether the opener process LAUNCHED — never whether the human finished anything.
|
|
8
|
+
// A missing opener (headless box, no `xdg-open`), an unknown platform, or a non-http(s) URL all
|
|
9
|
+
// resolve `false` so the caller falls back to PRINTING the URL + short code. It never throws.
|
|
10
|
+
// - The child is spawned DETACHED with `stdio: "ignore"` and `unref()`'d so the CLI can exit
|
|
11
|
+
// immediately after; we never wait on the browser or read its output.
|
|
12
|
+
//
|
|
13
|
+
// SECURITY: only http(s) URLs are ever handed to the opener. The verification URL is server-supplied
|
|
14
|
+
// (login.ts already validates the scheme), so this is defense-in-depth — a `file:`/`javascript:` URL
|
|
15
|
+
// must never reach a shell-less `open`/`xdg-open` as a thing to "open".
|
|
16
|
+
import { spawn } from "node:child_process";
|
|
17
|
+
import { isHttpUrl } from "../url.js";
|
|
18
|
+
/** The opener command + argv for a platform. On Windows we deliberately do NOT use `cmd /c start`:
|
|
19
|
+
* even a shell-less spawn there launches `cmd.exe`, whose OWN parser re-interprets `& | < > ^ ( )`
|
|
20
|
+
* before argv splitting — and the URL is Hub-supplied (`verification_uri[_complete]`), guarded only
|
|
21
|
+
* by a scheme check, so `https://h/?x=1&calc.exe` would let a hostile Hub run a local command during
|
|
22
|
+
* onboarding. `rundll32 url.dll,FileProtocolHandler <url>` hands the URL to the OS default-handler as
|
|
23
|
+
* a SINGLE argv element with no command interpreter in the path. `open`/`xdg-open` already take the
|
|
24
|
+
* URL as one argv element (no shell), so they're unaffected. */
|
|
25
|
+
function openerFor(platform, url) {
|
|
26
|
+
if (platform === "darwin")
|
|
27
|
+
return { file: "open", args: [url] };
|
|
28
|
+
if (platform === "win32")
|
|
29
|
+
return { file: "rundll32", args: ["url.dll,FileProtocolHandler", url] };
|
|
30
|
+
return { file: "xdg-open", args: [url] };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Try to open `url` in the user's default browser. Resolves `true` when the opener process
|
|
34
|
+
* launched, `false` when it couldn't (non-http(s) URL, missing opener binary, spawn failure).
|
|
35
|
+
* Never throws — a `false` result is the caller's cue to print the URL + code instead.
|
|
36
|
+
*/
|
|
37
|
+
export function openInBrowser(url, deps = {}) {
|
|
38
|
+
if (!isHttpUrl(url))
|
|
39
|
+
return Promise.resolve(false);
|
|
40
|
+
const platform = deps.platform ?? process.platform;
|
|
41
|
+
const spawnImpl = deps.spawn ?? spawn;
|
|
42
|
+
const { file, args } = openerFor(platform, url);
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
let settled = false;
|
|
45
|
+
const done = (value) => {
|
|
46
|
+
if (!settled) {
|
|
47
|
+
settled = true;
|
|
48
|
+
resolve(value);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
// Detached + ignored stdio so the opener outlives the CLI and never blocks on I/O.
|
|
53
|
+
const child = spawnImpl(file, args, { detached: true, stdio: "ignore" });
|
|
54
|
+
// `spawn` fires once the child process actually started; `error` fires on ENOENT (opener
|
|
55
|
+
// missing) or a spawn failure. Either resolves the promise exactly once.
|
|
56
|
+
child.once("spawn", () => {
|
|
57
|
+
child.unref();
|
|
58
|
+
done(true);
|
|
59
|
+
});
|
|
60
|
+
child.once("error", () => done(false));
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// A synchronous throw from spawn (e.g. an invalid options combination) is still just "couldn't
|
|
64
|
+
// open" — degrade to the print fallback rather than failing onboarding.
|
|
65
|
+
done(false);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=open-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-url.js","sourceRoot":"","sources":["../../src/onboarding/open-url.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,kGAAkG;AAClG,mGAAmG;AACnG,EAAE;AACF,uGAAuG;AACvG,gGAAgG;AAChG,kGAAkG;AAClG,oGAAoG;AACpG,kGAAkG;AAClG,+FAA+F;AAC/F,0EAA0E;AAC1E,EAAE;AACF,qGAAqG;AACrG,qGAAqG;AACrG,wEAAwE;AAExE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AA0BtC;;;;;;iEAMiE;AACjE,SAAS,SAAS,CAAC,QAAyB,EAAE,GAAW;IACvD,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAChE,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,6BAA6B,EAAE,GAAG,CAAC,EAAE,CAAC;IAClG,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,OAAoB,EAAE;IAC/D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,IAAK,KAA8B,CAAC;IAChE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAEhD,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QACtC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,IAAI,GAAG,CAAC,KAAc,EAAQ,EAAE;YACpC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC;YACH,mFAAmF;YACnF,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YACzE,yFAAyF;YACzF,yEAAyE;YACzE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,+FAA+F;YAC/F,wEAAwE;YACxE,IAAI,CAAC,KAAK,CAAC,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ResolvedConfig } from "../config.js";
|
|
2
|
+
import type { CredentialStore } from "../auth/token-store.js";
|
|
3
|
+
export interface MachineStatus {
|
|
4
|
+
/** True when this machine already has a usable credential for the resolved Hub origin. */
|
|
5
|
+
setUp: boolean;
|
|
6
|
+
/** Where the credential came from: the env token, a stored identity, or nothing. */
|
|
7
|
+
source: "env" | "stored" | "none";
|
|
8
|
+
/** The agent id to display, when unambiguous — the env / configured account, or a sole stored
|
|
9
|
+
* identity. Undefined when there is no single one to name (no account on the env token, or multiple
|
|
10
|
+
* stored identities discovered). */
|
|
11
|
+
agentId: string | undefined;
|
|
12
|
+
/** How many resolvable stored identities exist for this origin (0 on the env / configured-account
|
|
13
|
+
* paths, which resolve a single specific credential rather than discovering). */
|
|
14
|
+
storedCount: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve whether this machine is set up for the config's Hub, and how, WITHOUT revealing a token.
|
|
18
|
+
* `openStore` is a thunk so the store is opened only when a local lookup is actually needed — the env
|
|
19
|
+
* credential proves set-up with no keychain probe at all (important in CI / locked-keychain envs). The
|
|
20
|
+
* resolution precedence mirrors `resolveIdentity` (resolve-token.ts) exactly, so a machine that reads
|
|
21
|
+
* as "set up" here is one whose credential `notify`/`ask` will actually resolve:
|
|
22
|
+
* env token > the explicitly-configured account's token > the sole discoverable stored identity.
|
|
23
|
+
*/
|
|
24
|
+
export declare function machineStatus(config: ResolvedConfig, openStore: () => Promise<CredentialStore>): Promise<MachineStatus>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// "Is this machine set up?" — shared by `oh-hai setup` (#271) and the bare-`oh-hai` first-run
|
|
2
|
+
// dispatch (cli.ts). A machine is set up for a Hub when it already has a usable credential for that
|
|
3
|
+
// Hub's ORIGIN (§5.1 Hub-scoping): either the `MA2H_AGENT_TOKEN` env credential (the CI path) or at
|
|
4
|
+
// least one stored identity in the keychain/file backend whose bearer still resolves.
|
|
5
|
+
//
|
|
6
|
+
// This mirrors resolveIdentity()'s "resolvable stored identity" logic (resolve-token.ts): `list()`
|
|
7
|
+
// reads a keys-only index (redaction-safe — it can drift from the backend), so an identity counts
|
|
8
|
+
// only when its token actually resolves. We count resolvable identities to decide set-up + whether
|
|
9
|
+
// there's a single unambiguous one to name in the "connected as …" message.
|
|
10
|
+
import { originOf } from "../auth/resolve-token.js";
|
|
11
|
+
/**
|
|
12
|
+
* Resolve whether this machine is set up for the config's Hub, and how, WITHOUT revealing a token.
|
|
13
|
+
* `openStore` is a thunk so the store is opened only when a local lookup is actually needed — the env
|
|
14
|
+
* credential proves set-up with no keychain probe at all (important in CI / locked-keychain envs). The
|
|
15
|
+
* resolution precedence mirrors `resolveIdentity` (resolve-token.ts) exactly, so a machine that reads
|
|
16
|
+
* as "set up" here is one whose credential `notify`/`ask` will actually resolve:
|
|
17
|
+
* env token > the explicitly-configured account's token > the sole discoverable stored identity.
|
|
18
|
+
*/
|
|
19
|
+
export async function machineStatus(config, openStore) {
|
|
20
|
+
// The env credential (CI path, §5.3) is authoritative and needs no store lookup. Its agent id may be
|
|
21
|
+
// absent (a token with no MA2H_AGENT_ID) — still "set up", just unnamed.
|
|
22
|
+
if (config.tokenSource === "env") {
|
|
23
|
+
return { setUp: true, source: "env", agentId: config.account, storedCount: 0 };
|
|
24
|
+
}
|
|
25
|
+
const origin = originOf(config.baseUrl);
|
|
26
|
+
const store = await openStore();
|
|
27
|
+
// An explicitly-configured account (--account / MA2H_AGENT_ID / default_account) wins: set-up means
|
|
28
|
+
// THAT account resolves, not merely that some other identity does — otherwise bare `oh-hai` would
|
|
29
|
+
// print help while `notify` (which looks up only the configured account) fails auth. Mirrors
|
|
30
|
+
// resolveIdentity's "configured account wins, no discovery" branch.
|
|
31
|
+
if (config.account !== undefined) {
|
|
32
|
+
const found = await store.getWithSource(origin, config.account);
|
|
33
|
+
return found !== undefined
|
|
34
|
+
? { setUp: true, source: "stored", agentId: config.account, storedCount: 1 }
|
|
35
|
+
: { setUp: false, source: "none", agentId: undefined, storedCount: 0 };
|
|
36
|
+
}
|
|
37
|
+
// No configured account: discover the resolvable stored identities for this origin (a sole one is
|
|
38
|
+
// unambiguous; several stay ambiguous → no single agent to name, but still "set up").
|
|
39
|
+
const listed = (await store.list()).filter((identity) => identity.origin === origin);
|
|
40
|
+
let count = 0;
|
|
41
|
+
let soleAgent;
|
|
42
|
+
for (const identity of listed) {
|
|
43
|
+
const found = await store.getWithSource(origin, identity.agentId);
|
|
44
|
+
if (found !== undefined) {
|
|
45
|
+
count++;
|
|
46
|
+
soleAgent = identity.agentId; // meaningful only when count ends at 1
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (count === 0)
|
|
50
|
+
return { setUp: false, source: "none", agentId: undefined, storedCount: 0 };
|
|
51
|
+
return { setUp: true, source: "stored", agentId: count === 1 ? soleAgent : undefined, storedCount: count };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/onboarding/status.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,oGAAoG;AACpG,oGAAoG;AACpG,sFAAsF;AACtF,EAAE;AACF,mGAAmG;AACnG,kGAAkG;AAClG,mGAAmG;AACnG,4EAA4E;AAI5E,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAgBpD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAsB,EACtB,SAAyC;IAEzC,qGAAqG;IACrG,yEAAyE;IACzE,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;QACjC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IACjF,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAEhC,oGAAoG;IACpG,kGAAkG;IAClG,6FAA6F;IAC7F,oEAAoE;IACpE,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAChE,OAAO,KAAK,KAAK,SAAS;YACxB,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE;YAC5E,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IAC3E,CAAC;IAED,kGAAkG;IAClG,sFAAsF;IACtF,MAAM,MAAM,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACrF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,SAA6B,CAAC;IAClC,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAClE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,KAAK,EAAE,CAAC;YACR,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,uCAAuC;QACvE,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IAC7F,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;AAC7G,CAAC"}
|
package/dist/url.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isHttpUrl(value: string): boolean;
|
package/dist/url.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Shared http(s) URL scheme guard. A server-supplied URL is safe to hand to a browser opener, or to
|
|
2
|
+
// accept as a callback / verification URL, only when its scheme is http(s) — never file: / javascript:
|
|
3
|
+
// / data: etc. Consolidated here after the guard reached three copies (login.ts device-code flow,
|
|
4
|
+
// onboarding/open-url.ts, messaging/validate.ts); a scheme check is security-relevant, so it should
|
|
5
|
+
// have one definition and one rationale, not three that can drift apart.
|
|
6
|
+
export function isHttpUrl(value) {
|
|
7
|
+
try {
|
|
8
|
+
const { protocol } = new URL(value);
|
|
9
|
+
return protocol === "http:" || protocol === "https:";
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=url.js.map
|
package/dist/url.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,uGAAuG;AACvG,kGAAkG;AAClG,oGAAoG;AACpG,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QACpC,OAAO,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-hai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "OH HAI — the `oh-hai` CLI: reach a human from your agent through an MA2H Hub (notify / ask / task). Placement + machine contract; command bodies land in #106–#108.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|