@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
|
@@ -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)",
|
|
@@ -36,7 +53,7 @@ export const COMMANDS = [
|
|
|
36
53
|
},
|
|
37
54
|
{
|
|
38
55
|
name: "whoami",
|
|
39
|
-
summary: "show agent id + base URL + token presence (never the token)",
|
|
56
|
+
summary: "show agent id + how it resolved + base URL + token presence (never the token)",
|
|
40
57
|
issue: 106,
|
|
41
58
|
subcommands: [],
|
|
42
59
|
help: [
|
|
@@ -44,7 +61,30 @@ export const COMMANDS = [
|
|
|
44
61
|
"",
|
|
45
62
|
"Usage: oh-hai whoami [--check]",
|
|
46
63
|
"",
|
|
47
|
-
"Prints agent id,
|
|
64
|
+
"Prints agent id, how it resolved (flag / env / directory binding / user config /",
|
|
65
|
+
"discovered), base URL, and token presence. --check probes the Hub for validity and,",
|
|
66
|
+
"when you're signed in as a human, prints your resolver id (`human:<id>`) — the actor",
|
|
67
|
+
"an agent addresses to route an ask/task to you.",
|
|
68
|
+
].join("\n"),
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "use",
|
|
72
|
+
summary: "bind this directory to an agent (per-project identity, no --account juggling)",
|
|
73
|
+
issue: 307,
|
|
74
|
+
subcommands: [],
|
|
75
|
+
help: [
|
|
76
|
+
"oh-hai use — bind the current directory to an agent (cli spec §4 / §6).",
|
|
77
|
+
"",
|
|
78
|
+
"Usage: oh-hai use <agent> bind this directory (and its subtree) to <agent>",
|
|
79
|
+
" oh-hai use --list list all directory bindings",
|
|
80
|
+
" oh-hai use --unset remove this directory's binding",
|
|
81
|
+
"",
|
|
82
|
+
"Sessions run from a bound directory tree resolve to its agent automatically — no",
|
|
83
|
+
"--account needed. Bindings are USER-side (~/.config/oh-hai/bindings.json), scoped per",
|
|
84
|
+
"Hub, and NEVER settable from a repo (credential-safety §6). Resolution walks up from",
|
|
85
|
+
"the current directory (git-style) to the nearest bound ancestor. Precedence:",
|
|
86
|
+
"--account / MA2H_AGENT_ID > directory binding > user default_account. Offline — no",
|
|
87
|
+
"Hub call, and the agent need not be logged in yet.",
|
|
48
88
|
].join("\n"),
|
|
49
89
|
},
|
|
50
90
|
{
|
|
@@ -70,10 +110,11 @@ export const COMMANDS = [
|
|
|
70
110
|
"oh-hai ask — request a human decision.",
|
|
71
111
|
"",
|
|
72
112
|
"Usage: oh-hai ask submit --mode <select|input|confirm> --title <t>",
|
|
73
|
-
" --resolver human:<id> [--option k:Label]... [--schema <json>]",
|
|
113
|
+
" [--resolver human:<id>]... [--option k:Label]... [--schema <json>]",
|
|
74
114
|
" oh-hai ask await --id <id> [--interval <ms>] [--await-timeout <ms>]",
|
|
75
115
|
"",
|
|
76
|
-
"Carries a REQUIRED idempotency key.
|
|
116
|
+
"Carries a REQUIRED idempotency key. --resolver is optional: with none, the account",
|
|
117
|
+
"owner can answer (it needn't be hand-typed). See cli spec §4.4.",
|
|
77
118
|
].join("\n"),
|
|
78
119
|
},
|
|
79
120
|
{
|
|
@@ -84,11 +125,12 @@ export const COMMANDS = [
|
|
|
84
125
|
help: [
|
|
85
126
|
"oh-hai task — hand a human a manual action.",
|
|
86
127
|
"",
|
|
87
|
-
"Usage: oh-hai task submit --instructions <text> --title <t> --resolver human:<id>",
|
|
128
|
+
"Usage: oh-hai task submit --instructions <text> --title <t> [--resolver human:<id>]...",
|
|
88
129
|
" [--checklist <text>]... [--callback pull|push]",
|
|
89
130
|
" oh-hai task await --id <id> [--interval <ms>] [--await-timeout <ms>]",
|
|
90
131
|
"",
|
|
91
|
-
"Terminal by default.
|
|
132
|
+
"Terminal by default. --resolver is optional: with none, the account owner can mark",
|
|
133
|
+
"it done. See cli spec §4.4.",
|
|
92
134
|
].join("\n"),
|
|
93
135
|
},
|
|
94
136
|
{
|
|
@@ -114,14 +156,17 @@ export const COMMANDS = [
|
|
|
114
156
|
help: [
|
|
115
157
|
"oh-hai inbox — the human→agent inbound leg (MA2H v0.4).",
|
|
116
158
|
"",
|
|
117
|
-
"Usage: oh-hai inbox watch [--interval <ms>] [--once] [--max <n>]",
|
|
159
|
+
"Usage: oh-hai inbox watch [--interval <ms>] [--once] [--max <n>] [--force]",
|
|
118
160
|
"",
|
|
119
161
|
"watch drains your agent's mailbox, streams each directive to stdout for the",
|
|
120
162
|
"agent runtime, posts a single batched ack, and — because each authenticated",
|
|
121
163
|
"poll is the presence heartbeat — keeps you 'online' by polling on --interval",
|
|
122
164
|
"(default 5000ms). Under --json each directive is one NDJSON envelope. --once",
|
|
123
165
|
"drains a single batch and exits (cron / scripting). --max caps the drain size.",
|
|
124
|
-
"
|
|
166
|
+
"Only one watcher per identity may drain ON THIS MACHINE: a second is refused",
|
|
167
|
+
"(exit 10) so two local sessions can't race to consume the same directive; --force",
|
|
168
|
+
"takes over. Watchers on different machines aren't detected and will split the",
|
|
169
|
+
"mailbox. See cli spec §4.7.",
|
|
125
170
|
].join("\n"),
|
|
126
171
|
},
|
|
127
172
|
{
|
|
@@ -137,6 +182,41 @@ export const COMMANDS = [
|
|
|
137
182
|
"Local checks run offline; connectivity + --test-notify are network checks. See cli spec §4.6.",
|
|
138
183
|
].join("\n"),
|
|
139
184
|
},
|
|
185
|
+
{
|
|
186
|
+
name: "teach",
|
|
187
|
+
summary: "teach this machine's agents about OH HAI (AGENTS.md snippet)",
|
|
188
|
+
issue: 295,
|
|
189
|
+
subcommands: [],
|
|
190
|
+
help: [
|
|
191
|
+
"oh-hai teach — teach this machine's agents that OH HAI exists (cli spec §4.9).",
|
|
192
|
+
"",
|
|
193
|
+
"Usage: oh-hai teach [--global] [--dry-run] [--yes]",
|
|
194
|
+
"",
|
|
195
|
+
"Writes a vendor-neutral OH HAI snippet into the agent-instruction files this machine's",
|
|
196
|
+
"agents already read: the cross-vendor AGENTS.md (project-level by default; --global for",
|
|
197
|
+
"the user-level convention path) plus any detected vendor files (CLAUDE.md, GEMINI.md, …).",
|
|
198
|
+
"Idempotent — a stable marked block it updates in place, never a duplicate; never a secret.",
|
|
199
|
+
"--dry-run previews what it would touch; --yes skips the confirm (required under --json).",
|
|
200
|
+
].join("\n"),
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "upgrade",
|
|
204
|
+
summary: "check for a newer oh-hai and self-update (or print how)",
|
|
205
|
+
issue: 343,
|
|
206
|
+
subcommands: [],
|
|
207
|
+
help: [
|
|
208
|
+
"oh-hai upgrade — update the CLI to the latest published version (cli spec §4 / #277).",
|
|
209
|
+
"",
|
|
210
|
+
"Usage: oh-hai upgrade [--check]",
|
|
211
|
+
"",
|
|
212
|
+
"Checks the npm registry for a newer @oh-hai/cli and acts by how you installed it: a global npm",
|
|
213
|
+
"install self-updates with `npm i -g @oh-hai/cli@latest`, and a standalone binary downloads the",
|
|
214
|
+
"matching release, checksum-verifies it, and swaps itself in place — both only in interactive",
|
|
215
|
+
"sessions (a pipe / CI / --json prints guidance instead, never mutating silently). A source",
|
|
216
|
+
"checkout gets guidance rather than a fabricated upgrade. --check reports availability without",
|
|
217
|
+
"changing anything. Already-latest and offline are both reported honestly.",
|
|
218
|
+
].join("\n"),
|
|
219
|
+
},
|
|
140
220
|
];
|
|
141
221
|
export function findCommand(name) {
|
|
142
222
|
return COMMANDS.find((command) => command.name === name);
|
|
@@ -1 +1 @@
|
|
|
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,+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
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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>;
|
|
10
|
+
/**
|
|
11
|
+
* Bare-`oh-hai` project-onboarding offer for an ALREADY-SET-UP machine (#322, part of #307). When this
|
|
12
|
+
* machine has MULTIPLE connected agents and the current directory is UNBOUND, the no-flag messaging
|
|
13
|
+
* workflow is ambiguous — resolution refuses to guess among several stored identities, so
|
|
14
|
+
* `notify`/`ask`/`task` fail without `--account`. Offer the one-prompt fix: create a PROJECT-SCOPED
|
|
15
|
+
* agent via the shared device flow (the human creates + labels it in the browser; the CLI can only
|
|
16
|
+
* SUGGEST the project name — the browser owns agent creation, and the CLI holds no human session to mint
|
|
17
|
+
* `/v1/agents` directly), then BIND this directory to the returned agent so sessions in the tree resolve
|
|
18
|
+
* to it with no `--account`. Purely additive: the single-agent and zero-config/env paths never reach the
|
|
19
|
+
* prompt (they carry `storedCount <= 1`), so the #271 happy path is untouched.
|
|
20
|
+
*
|
|
21
|
+
* Returns true when it HANDLED the bare invocation (it offered — whether the human accepted or declined),
|
|
22
|
+
* so the caller skips its default help; false when the conditions don't apply and the caller should print
|
|
23
|
+
* help as before. Never prompts (or hangs) under `--json` or a non-interactive stdin — the same gate
|
|
24
|
+
* `handleAlreadySetUp`'s reconnect prompt uses. Every gate lives here so the behavior is one testable unit.
|
|
25
|
+
*/
|
|
26
|
+
export declare function offerProjectAgent(ctx: CommandContext, status: MachineStatus): Promise<boolean>;
|
|
@@ -0,0 +1,221 @@
|
|
|
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 { basename, isAbsolute } from "node:path";
|
|
14
|
+
import { originOf } from "../auth/resolve-token.js";
|
|
15
|
+
import { bindingStoreStatus, setBinding } from "../bindings.js";
|
|
16
|
+
import { buildOk, serializeEnvelope } from "../envelope.js";
|
|
17
|
+
import { sanitizeForTerminal } from "../terminal.js";
|
|
18
|
+
import { machineStatus } from "../onboarding/status.js";
|
|
19
|
+
import { parseCommandArgs } from "./flags.js";
|
|
20
|
+
import { runDeviceCodeFlow } from "./login.js";
|
|
21
|
+
export async function setupCommand(ctx, pre = {}) {
|
|
22
|
+
// Reject stray flags/positionals like every other command (e.g. `oh-hai setup --chek` → exit 2).
|
|
23
|
+
parseCommandArgs(ctx.argv, {});
|
|
24
|
+
// `machineStatus` opens the store lazily via the thunk, so an env-token `oh-hai setup` never probes
|
|
25
|
+
// the keychain before reporting `already_configured`.
|
|
26
|
+
const status = pre.status ?? (await machineStatus(ctx.config, () => ctx.runtime.openStore()));
|
|
27
|
+
if (!status.setUp) {
|
|
28
|
+
await runOnboarding(ctx);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
await handleAlreadySetUp(ctx, status);
|
|
32
|
+
}
|
|
33
|
+
/** First-run onboarding: welcome → device-code flow (browser auto-open) → next steps. The device flow
|
|
34
|
+
* owns the success output (a human line on stdout, or the `--json` envelope); the framing lines go to
|
|
35
|
+
* stderr so they never pollute the `--json` stdout envelope (§8). A denied/expired code throws out of
|
|
36
|
+
* runDeviceCodeFlow and the next-steps line is (correctly) skipped. */
|
|
37
|
+
async function runOnboarding(ctx) {
|
|
38
|
+
if (!ctx.json) {
|
|
39
|
+
ctx.io.err(`oh-hai: let's connect this machine to ${originOf(ctx.config.baseUrl)}.`);
|
|
40
|
+
ctx.io.err("oh-hai: approve in your browser and pick (or create) an agent — no key to copy.");
|
|
41
|
+
}
|
|
42
|
+
// Pass the `setup` command label so the `--json` success envelope reports `command:"setup"` (not
|
|
43
|
+
// `login`), keeping the per-command JSON contract consistent for automation.
|
|
44
|
+
const agentId = await runDeviceCodeFlow(ctx, "setup");
|
|
45
|
+
await reportNextSteps(ctx, agentId);
|
|
46
|
+
}
|
|
47
|
+
/** Already-set-up re-run: report identity, then (interactively) offer to reconnect. Never dead-ends. */
|
|
48
|
+
async function handleAlreadySetUp(ctx, status) {
|
|
49
|
+
const hub = originOf(ctx.config.baseUrl);
|
|
50
|
+
if (ctx.json) {
|
|
51
|
+
// Machine-readable status only — never prompt/hang under --json.
|
|
52
|
+
ctx.io.log(serializeEnvelope(buildOk("setup", {
|
|
53
|
+
status: "already_configured",
|
|
54
|
+
base_url: ctx.config.baseUrl,
|
|
55
|
+
agent_id: status.agentId ?? null,
|
|
56
|
+
source: status.source,
|
|
57
|
+
})));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
ctx.io.err(`oh-hai: this machine is connected to ${hub} ${describeIdentity(status)}.`);
|
|
61
|
+
// Never a dead end — but only PROMPT when a human is actually at the terminal. Gate on real TTY-ness,
|
|
62
|
+
// NOT on `readLine` presence: production always wires `readLine`, so a `readLine`-presence check would
|
|
63
|
+
// still prompt (and could block on `read`) under a pipe / CI. Non-interactive → report a path forward
|
|
64
|
+
// and exit. `readLine` may still be absent in a hermetic caller, so require it to actually read.
|
|
65
|
+
const interactive = (ctx.runtime.isInteractive?.() ?? false) && ctx.runtime.readLine !== undefined;
|
|
66
|
+
if (!interactive) {
|
|
67
|
+
ctx.io.log("Already set up. Re-run `oh-hai setup` in an interactive terminal to connect another agent.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
ctx.io.err("Connect another agent or re-authorize? [y/N]: ");
|
|
71
|
+
const answer = (await ctx.runtime.readLine()).trim().toLowerCase();
|
|
72
|
+
if (answer === "y" || answer === "yes") {
|
|
73
|
+
const agentId = await runDeviceCodeFlow(ctx, "setup");
|
|
74
|
+
await reportNextSteps(ctx, agentId);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
ctx.io.log("Nothing to do — you're already set up.");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* After a successful connect, tell the human what actually happens next — honestly. Onboarding binds an
|
|
82
|
+
* agent in the BROWSER, but the no-flag `notify`/`ask`/`task` workflow resolves a credential by a fixed
|
|
83
|
+
* precedence (env token > configured account > sole stored identity, resolve-token.ts). When the bearer
|
|
84
|
+
* we just stored ISN'T what that resolver will pick, an unconditional "you're all set" would be a lie —
|
|
85
|
+
* the next command fails auth. So reconcile the stored agent against `machineStatus` (same precedence)
|
|
86
|
+
* and print the corrective next step instead. Human output only — the `--json` envelope already spoke.
|
|
87
|
+
*/
|
|
88
|
+
async function reportNextSteps(ctx, storedAgentId) {
|
|
89
|
+
if (ctx.json)
|
|
90
|
+
return;
|
|
91
|
+
const allSet = 'oh-hai: you\'re all set. Try `oh-hai notify --title "hello"`, or run `oh-hai doctor` to verify.';
|
|
92
|
+
const after = await machineStatus(ctx.config, () => ctx.runtime.openStore());
|
|
93
|
+
const stored = sanitizeForTerminal(storedAgentId);
|
|
94
|
+
// An env token outranks any stored bearer (§5.3): the new agent won't be used until it's unset.
|
|
95
|
+
if (after.source === "env") {
|
|
96
|
+
ctx.io.err(`oh-hai: connected as ${stored}, but MA2H_AGENT_TOKEN is set and takes precedence — unset it to use this agent.`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// A configured account that isn't the agent just bound won't resolve this bearer (notify/ask look up
|
|
100
|
+
// only the configured account). Note this rather than claim success — and give the remedy that matches
|
|
101
|
+
// HOW the account resolved: a directory binding still wins on the next command, so "run without
|
|
102
|
+
// --account" is wrong there; point at re-binding / unsetting the directory instead (§6, #321).
|
|
103
|
+
if (ctx.config.account !== undefined && ctx.config.account !== storedAgentId) {
|
|
104
|
+
const active = sanitizeForTerminal(ctx.config.account);
|
|
105
|
+
if (ctx.config.accountSource === "binding") {
|
|
106
|
+
ctx.io.err(`oh-hai: connected as ${stored}, but this directory is bound to ${active}. ` +
|
|
107
|
+
`Run \`oh-hai use ${stored}\` to rebind it here (or \`oh-hai use --unset\`) to use this agent.`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
ctx.io.err(`oh-hai: connected as ${stored}, but --account/MA2H_AGENT_ID is ${active}. ` +
|
|
111
|
+
`Run without --account, or set MA2H_AGENT_ID=${stored}, to use this agent.`);
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Zero-config resolution refuses to guess among multiple stored agents — adding a second one makes the
|
|
116
|
+
// no-flag workflow ambiguous, so point at the required --account rather than a bare "done".
|
|
117
|
+
if (ctx.config.account === undefined && after.storedCount > 1) {
|
|
118
|
+
ctx.io.err(`oh-hai: this machine now has ${after.storedCount} connected agents — run with --account ${stored} ` +
|
|
119
|
+
`(or set a default) to choose one.`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
ctx.io.err(allSet);
|
|
123
|
+
// The final onboarding step: teach this machine's agents that OH HAI exists so they actually reach for
|
|
124
|
+
// it. A pointer only — `teach` writes files, so it stays an explicit opt-in, never auto-run here.
|
|
125
|
+
ctx.io.err("oh-hai: to teach this machine's agents to use OH HAI, run `oh-hai teach` (writes an AGENTS.md snippet).");
|
|
126
|
+
}
|
|
127
|
+
/** Human phrasing for who the machine is connected as, across the env / sole / multiple cases. */
|
|
128
|
+
function describeIdentity(status) {
|
|
129
|
+
if (status.agentId !== undefined)
|
|
130
|
+
return `as ${sanitizeForTerminal(status.agentId)}`;
|
|
131
|
+
if (status.source === "env")
|
|
132
|
+
return "via the MA2H_AGENT_TOKEN environment credential";
|
|
133
|
+
return `with ${status.storedCount} connected agents`;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Bare-`oh-hai` project-onboarding offer for an ALREADY-SET-UP machine (#322, part of #307). When this
|
|
137
|
+
* machine has MULTIPLE connected agents and the current directory is UNBOUND, the no-flag messaging
|
|
138
|
+
* workflow is ambiguous — resolution refuses to guess among several stored identities, so
|
|
139
|
+
* `notify`/`ask`/`task` fail without `--account`. Offer the one-prompt fix: create a PROJECT-SCOPED
|
|
140
|
+
* agent via the shared device flow (the human creates + labels it in the browser; the CLI can only
|
|
141
|
+
* SUGGEST the project name — the browser owns agent creation, and the CLI holds no human session to mint
|
|
142
|
+
* `/v1/agents` directly), then BIND this directory to the returned agent so sessions in the tree resolve
|
|
143
|
+
* to it with no `--account`. Purely additive: the single-agent and zero-config/env paths never reach the
|
|
144
|
+
* prompt (they carry `storedCount <= 1`), so the #271 happy path is untouched.
|
|
145
|
+
*
|
|
146
|
+
* Returns true when it HANDLED the bare invocation (it offered — whether the human accepted or declined),
|
|
147
|
+
* so the caller skips its default help; false when the conditions don't apply and the caller should print
|
|
148
|
+
* help as before. Never prompts (or hangs) under `--json` or a non-interactive stdin — the same gate
|
|
149
|
+
* `handleAlreadySetUp`'s reconnect prompt uses. Every gate lives here so the behavior is one testable unit.
|
|
150
|
+
*/
|
|
151
|
+
export async function offerProjectAgent(ctx, status) {
|
|
152
|
+
// Only the ambiguous multi-identity case warrants a prompt: >1 resolvable stored identity means the
|
|
153
|
+
// no-flag workflow can't pick one. `storedCount` is 0 on the env-token / configured-account paths, so
|
|
154
|
+
// those (and the single-agent default) fall straight through to help — the happy path stays prompt-free.
|
|
155
|
+
if (status.storedCount <= 1)
|
|
156
|
+
return false;
|
|
157
|
+
// A directory already bound to an agent resolves unambiguously — nothing to offer. `accountSource` is
|
|
158
|
+
// "binding" whenever resolution walked up to a binding on this dir OR an ancestor, so a subtree of a
|
|
159
|
+
// bound project is covered too. (Via the cli.ts bare dispatch this is redundant — a resolved binding
|
|
160
|
+
// sets `config.account`, which makes `machineStatus` report `storedCount <= 1`, so the gate above
|
|
161
|
+
// already returned — but it's the load-bearing bound-tree guard for a DIRECT caller / the unit tests,
|
|
162
|
+
// so keep it rather than rely on the storedCount coupling.)
|
|
163
|
+
if (ctx.config.accountSource === "binding")
|
|
164
|
+
return false;
|
|
165
|
+
// Never prompt under --json (stdout is reserved for the envelope) or a non-interactive stdin (a pipe /
|
|
166
|
+
// CI would block on a `readLine` that never gets a line) — mirrors `handleAlreadySetUp`'s gate. Gate on
|
|
167
|
+
// real TTY-ness, not merely `readLine` presence (production always wires `readLine`).
|
|
168
|
+
if (ctx.json)
|
|
169
|
+
return false;
|
|
170
|
+
const interactive = (ctx.runtime.isInteractive?.() ?? false) && ctx.runtime.readLine !== undefined;
|
|
171
|
+
if (!interactive)
|
|
172
|
+
return false;
|
|
173
|
+
// Need a writable bindings store with an absolute cwd to persist the bind; without it, don't send the
|
|
174
|
+
// human through a browser flow whose binding can't be written afterward (mirrors `use`'s write preflight
|
|
175
|
+
// — "unavailable"/"unsupported-version" both mean a bind would be lost or would clobber a newer file).
|
|
176
|
+
const io = ctx.runtime.bindingsIo;
|
|
177
|
+
if (io === undefined || !isAbsolute(io.cwd) || bindingStoreStatus(io) !== "ok")
|
|
178
|
+
return false;
|
|
179
|
+
const project = sanitizeForTerminal(basename(io.cwd));
|
|
180
|
+
ctx.io.err(`oh-hai: this machine has ${status.storedCount} connected agents and this directory isn't bound to one.`);
|
|
181
|
+
ctx.io.err(`oh-hai: create a new agent for "${project}" and bind this directory to it? [y/N]: `);
|
|
182
|
+
const answer = (await ctx.runtime.readLine()).trim().toLowerCase();
|
|
183
|
+
if (answer !== "y" && answer !== "yes") {
|
|
184
|
+
// Declined — point at the manual paths and stop. We HANDLED the bare invocation, so don't also print
|
|
185
|
+
// help (returning true suppresses the caller's fallback).
|
|
186
|
+
ctx.io.err("oh-hai: ok — run `oh-hai use <agent>` to bind this directory to an existing agent, or pass `--account <id>` per command.");
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
// Suggest the label the human types on /activate (the browser owns agent creation + labeling). The
|
|
190
|
+
// device flow stores the returned bearer under the new agent id — never printed (§5.4).
|
|
191
|
+
ctx.io.err(`oh-hai: approve in your browser and create an agent — suggested label: ${project}.`);
|
|
192
|
+
const agentId = await runDeviceCodeFlow(ctx, "setup");
|
|
193
|
+
const boundAgent = sanitizeForTerminal(agentId);
|
|
194
|
+
// Bind cwd → the new agent so this tree resolves to it with no --account (resolveConfig precedence:
|
|
195
|
+
// flag > env > binding > user-default). setBinding writes ONLY the user-side store (credential-safe §6).
|
|
196
|
+
//
|
|
197
|
+
// The write preflight above ran BEFORE the (multi-minute) browser approval, so re-check the store here:
|
|
198
|
+
// if it went unwritable during the wait, or a NEWER CLI wrote a v2 bindings.json meanwhile, blindly
|
|
199
|
+
// calling setBinding would throw a raw OS error (unwritable) or SILENTLY clobber the newer file
|
|
200
|
+
// (loadBindings read-degrades a v2 doc to [], then writeBindings stamps a fresh v1). The agent is
|
|
201
|
+
// already minted + its bearer stored, so don't fail opaquely — tell the human exactly how to finish the
|
|
202
|
+
// bind by hand (mirrors the post-mint recovery guidance in `agents create`, commands/agents.ts).
|
|
203
|
+
if (bindingStoreStatus(io) !== "ok") {
|
|
204
|
+
ctx.io.err(`oh-hai: connected as ${boundAgent}, but this directory's binding could not be written ` +
|
|
205
|
+
`(the bindings file changed during approval). Run \`oh-hai use ${boundAgent}\` here to bind it.`);
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
let path;
|
|
209
|
+
try {
|
|
210
|
+
path = setBinding(io, io.cwd, originOf(ctx.config.baseUrl), agentId);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
ctx.io.err(`oh-hai: connected as ${boundAgent}, but the directory binding could not be saved. ` +
|
|
214
|
+
`Run \`oh-hai use ${boundAgent}\` here to bind this directory to it.`);
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
ctx.io.err(`oh-hai: bound ${sanitizeForTerminal(path)} → ${boundAgent} — this directory now acts as ${boundAgent}.`);
|
|
218
|
+
ctx.io.err('oh-hai: try `oh-hai notify --title "hello"`, or run `oh-hai doctor` to verify.');
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
//# 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,UAAU,EAAE,MAAM,WAAW,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,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,uGAAuG;IACvG,gGAAgG;IAChG,+FAA+F;IAC/F,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC;QAC7E,MAAM,MAAM,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YAC3C,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,wBAAwB,MAAM,oCAAoC,MAAM,IAAI;gBAC1E,oBAAoB,MAAM,qEAAqE,CAClG,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,wBAAwB,MAAM,oCAAoC,MAAM,IAAI;gBAC1E,+CAA+C,MAAM,sBAAsB,CAC9E,CAAC;QACJ,CAAC;QACD,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;IACnB,uGAAuG;IACvG,kGAAkG;IAClG,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,yGAAyG,CAC1G,CAAC;AACJ,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;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,GAAmB,EAAE,MAAqB;IAChF,oGAAoG;IACpG,sGAAsG;IACtG,yGAAyG;IACzG,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,sGAAsG;IACtG,qGAAqG;IACrG,qGAAqG;IACrG,kGAAkG;IAClG,sGAAsG;IACtG,4DAA4D;IAC5D,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACzD,uGAAuG;IACvG,wGAAwG;IACxG,sFAAsF;IACtF,IAAI,GAAG,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAC3B,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;QAAE,OAAO,KAAK,CAAC;IAC/B,sGAAsG;IACtG,yGAAyG;IACzG,uGAAuG;IACvG,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC;IAClC,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,EAAE,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAE7F,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,4BAA4B,MAAM,CAAC,WAAW,0DAA0D,CACzG,CAAC;IACF,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,mCAAmC,OAAO,0CAA0C,CAAC,CAAC;IACjG,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,qGAAqG;QACrG,0DAA0D;QAC1D,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,0HAA0H,CAC3H,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mGAAmG;IACnG,wFAAwF;IACxF,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,0EAA0E,OAAO,GAAG,CAAC,CAAC;IACjG,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAEhD,oGAAoG;IACpG,yGAAyG;IACzG,EAAE;IACF,wGAAwG;IACxG,oGAAoG;IACpG,gGAAgG;IAChG,kGAAkG;IAClG,wGAAwG;IACxG,iGAAiG;IACjG,IAAI,kBAAkB,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;QACpC,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,wBAAwB,UAAU,sDAAsD;YACtF,iEAAiE,UAAU,qBAAqB,CACnG,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,wBAAwB,UAAU,kDAAkD;YAClF,oBAAoB,UAAU,uCAAuC,CACxE,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,GAAG,CAAC,EAAE,CAAC,GAAG,CACR,iBAAiB,mBAAmB,CAAC,IAAI,CAAC,MAAM,UAAU,iCAAiC,UAAU,GAAG,CACzG,CAAC;IACF,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,gFAAgF,CAAC,CAAC;IAC7F,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/commands/task.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// `oh-hai task` (docs/specs/cli.md §4.4) — hand a human a manual action. Subcommands `submit` +
|
|
2
2
|
// `await`. Productized from `scripts/task.ts`: account-aware bearer, `--json` envelope, §7 exit
|
|
3
|
-
// codes, injectable fetch. TERMINAL by default — `--callback` is pure opt-in
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// codes, injectable fetch. TERMINAL by default — `--callback` is pure opt-in. `--resolver` is
|
|
4
|
+
// OPTIONAL (issue #366): with none, the Hub lets the account owner mark the task done, so the agent
|
|
5
|
+
// needn't hand-type an id it can't know; `allowed_resolvers` is an optional narrowing. A task
|
|
6
|
+
// Response carries no `value` (resolutions are completed / dismissed / expired).
|
|
6
7
|
import { CliError, buildOk, serializeEnvelope } from "../envelope.js";
|
|
7
8
|
import { parseSubcommandArgs } from "./flags.js";
|
|
8
9
|
import { awaitResolution, printResolution, resolveAwaitTiming } from "./messaging/await.js";
|
|
@@ -67,7 +68,7 @@ async function taskSubmit(ctx, flags) {
|
|
|
67
68
|
const callback = resolveCallback(flags); // undefined → terminal task (opt-in)
|
|
68
69
|
const checklistRaw = Array.isArray(flags.checklist) ? flags.checklist.filter((c) => typeof c === "string") : [];
|
|
69
70
|
const checklist = checklistRaw.map((text) => ({ text }));
|
|
70
|
-
const resolvers = resolveResolvers(flags,
|
|
71
|
+
const resolvers = resolveResolvers(flags, ctx);
|
|
71
72
|
const action = { instructions };
|
|
72
73
|
if (checklist.length > 0)
|
|
73
74
|
action.checklist = checklist;
|
|
@@ -122,13 +123,13 @@ async function taskReplay(ctx, envelopeRaw, flags, dryRun) {
|
|
|
122
123
|
throw new CliError("usage", `--envelope is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
123
124
|
}
|
|
124
125
|
const envelope = assertTaskEnvelope(parsed);
|
|
126
|
+
// A captured envelope with no concrete human:<id> in allowed_resolvers is still resolvable by the
|
|
127
|
+
// account owner (issue #366) — the Hub always authorizes the account owner (a non-owner human is
|
|
128
|
+
// fail-closed: it may resolve only if explicitly listed, so an omitted list is owner-only), so this
|
|
129
|
+
// is no longer a submit-blocking dead-end. Note it (an all-wildcard/agent narrowing is unusual) but proceed.
|
|
125
130
|
if (!hasConcreteHumanResolver(replayResolvers(envelope))) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"never match): the resolve route is human-only, so it could never be marked done (inbox Done/Dismiss → " +
|
|
129
|
-
"403) and would sit open forever. Capture the envelope with a concrete human resolver. (Use --dry-run to preview anyway.)");
|
|
130
|
-
}
|
|
131
|
-
ctx.io.err("⚠ --envelope task has no concrete human:<id> resolver: this previewed replay would be UNRESOLVABLE.");
|
|
131
|
+
ctx.io.err("note: --envelope task lists no concrete human:<id> in action.allowed_resolvers; it will be resolvable " +
|
|
132
|
+
"by the account owner (the resolve route is human-only).");
|
|
132
133
|
}
|
|
133
134
|
if (dryRun) {
|
|
134
135
|
printDryRunEnvelope(ctx, "task.submit", envelope);
|
|
@@ -175,7 +176,7 @@ function resolveCallback(flags) {
|
|
|
175
176
|
}
|
|
176
177
|
return { mode: "pull" };
|
|
177
178
|
}
|
|
178
|
-
function resolveResolvers(flags,
|
|
179
|
+
function resolveResolvers(flags, ctx) {
|
|
179
180
|
const raw = Array.isArray(flags.resolver) ? flags.resolver.filter((r) => typeof r === "string") : [];
|
|
180
181
|
const resolvers = [];
|
|
181
182
|
for (const r of raw) {
|
|
@@ -186,19 +187,15 @@ function resolveResolvers(flags, dryRun, ctx) {
|
|
|
186
187
|
}
|
|
187
188
|
resolvers.push(r);
|
|
188
189
|
}
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
throw new CliError("usage", `a task needs at least one --resolver human:<id>: ${detail}, and the resolve route is human-only, so ` +
|
|
199
|
-
"the task could never be marked done. (Use --dry-run to preview the envelope without one.)");
|
|
200
|
-
}
|
|
201
|
-
ctx.io.err("⚠ no --resolver human:<id> given: this previewed task would be UNRESOLVABLE (resolve is human-only).");
|
|
190
|
+
// No --resolver is fine (issue #366): with no allowed_resolvers the Hub lets the account OWNER mark
|
|
191
|
+
// the task done — the agent needn't (and can't reliably) hand-type the account's canonical human id.
|
|
192
|
+
// When you DO pass --resolver, it is a fully fail-closed narrowing: a non-owner human may resolve only
|
|
193
|
+
// if explicitly listed, an omitted/empty list is owner-only (not "any account human"), and the account
|
|
194
|
+
// owner always may regardless of the list. Only a task whose ONLY resolvers are non-human is a real
|
|
195
|
+
// dead-end (the resolve route is human-only), so keep just that nudge.
|
|
196
|
+
if (resolvers.length > 0 && !hasHumanResolver(resolvers)) {
|
|
197
|
+
ctx.io.err(`⚠ every --resolver given (${resolvers.join(", ")}) is non-human (agent:/system:); the resolve route is ` +
|
|
198
|
+
"human-only, so this task can only be marked done by the account owner. Omit --resolver or add a human:<id>.");
|
|
202
199
|
}
|
|
203
200
|
return resolvers;
|
|
204
201
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,gGAAgG;AAChG,
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CommandContext, TeachFs } from "./context.js";
|
|
2
|
+
/**
|
|
3
|
+
* `oh-hai teach` handler (§4.9). Computes the target files + per-file action, then — unless `--dry-run` —
|
|
4
|
+
* confirms and writes. Flags: `--global` (user-level convention paths instead of the project), `--dry-run`
|
|
5
|
+
* (preview, no writes), `--yes` (skip the confirm). Under `--json`, `--yes` is required (no interactive
|
|
6
|
+
* confirm in machine mode). Reports exactly what it wrote where.
|
|
7
|
+
*/
|
|
8
|
+
export declare function teachCommand(ctx: CommandContext): Promise<void | number>;
|
|
9
|
+
/** Production `TeachFs` backed by the real filesystem + home dir. `read` classifies a target with `lstat`
|
|
10
|
+
* (which does NOT follow symlinks) before touching it — see `TeachRead`. `writeFile` creates parent
|
|
11
|
+
* directories so a global target (e.g. ~/.codex/AGENTS.md) works when the dir is absent. `cwd` degrades to
|
|
12
|
+
* "" if `process.cwd()` throws (a removed working dir), matching config-file.ts. */
|
|
13
|
+
export declare function nodeTeachFs(): TeachFs;
|