@raidiant/notifai 5.0.0 → 6.0.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.
Files changed (104) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +2 -2
  3. package/dist/client.d.ts +8 -3
  4. package/dist/client.js +24 -3
  5. package/dist/client.js.map +1 -1
  6. package/dist/commands-auth.d.ts +14 -0
  7. package/dist/commands-auth.js +154 -0
  8. package/dist/commands-auth.js.map +1 -0
  9. package/dist/commands-config.d.ts +31 -0
  10. package/dist/commands-config.js +246 -0
  11. package/dist/commands-config.js.map +1 -0
  12. package/dist/commands-core.d.ts +102 -0
  13. package/dist/commands-core.js +135 -0
  14. package/dist/commands-core.js.map +1 -0
  15. package/dist/commands-devices.d.ts +31 -0
  16. package/dist/commands-devices.js +124 -0
  17. package/dist/commands-devices.js.map +1 -0
  18. package/dist/commands-doctor.d.ts +24 -0
  19. package/dist/commands-doctor.js +1011 -0
  20. package/dist/commands-doctor.js.map +1 -0
  21. package/dist/commands-harness-context.d.ts +61 -0
  22. package/dist/commands-harness-context.js +93 -0
  23. package/dist/commands-harness-context.js.map +1 -0
  24. package/dist/commands-hook-shape.d.ts +17 -0
  25. package/dist/commands-hook-shape.js +37 -0
  26. package/dist/commands-hook-shape.js.map +1 -0
  27. package/dist/commands-hooks.d.ts +115 -0
  28. package/dist/commands-hooks.js +1225 -0
  29. package/dist/commands-hooks.js.map +1 -0
  30. package/dist/commands-init.d.ts +35 -0
  31. package/dist/commands-init.js +580 -0
  32. package/dist/commands-init.js.map +1 -0
  33. package/dist/commands-io.d.ts +2 -0
  34. package/dist/commands-io.js +110 -0
  35. package/dist/commands-io.js.map +1 -0
  36. package/dist/commands-logs.d.ts +30 -0
  37. package/dist/commands-logs.js +201 -0
  38. package/dist/commands-logs.js.map +1 -0
  39. package/dist/commands-send-support.d.ts +44 -0
  40. package/dist/commands-send-support.js +180 -0
  41. package/dist/commands-send-support.js.map +1 -0
  42. package/dist/commands-send.d.ts +33 -0
  43. package/dist/commands-send.js +519 -0
  44. package/dist/commands-send.js.map +1 -0
  45. package/dist/commands-setup-proof.d.ts +15 -0
  46. package/dist/commands-setup-proof.js +53 -0
  47. package/dist/commands-setup-proof.js.map +1 -0
  48. package/dist/commands-skill.d.ts +10 -0
  49. package/dist/commands-skill.js +71 -0
  50. package/dist/commands-skill.js.map +1 -0
  51. package/dist/commands.d.ts +12 -387
  52. package/dist/commands.js +12 -4536
  53. package/dist/commands.js.map +1 -1
  54. package/dist/config-schema.js +1 -1
  55. package/dist/config-schema.js.map +1 -1
  56. package/dist/config.d.ts +1 -1
  57. package/dist/config.js +3 -1
  58. package/dist/config.js.map +1 -1
  59. package/dist/credentials.js +13 -3
  60. package/dist/credentials.js.map +1 -1
  61. package/dist/hooks.d.ts +2 -2
  62. package/dist/hooks.js +127 -99
  63. package/dist/hooks.js.map +1 -1
  64. package/dist/interactive.js +4 -4
  65. package/dist/interactive.js.map +1 -1
  66. package/dist/logging.js +1 -0
  67. package/dist/logging.js.map +1 -1
  68. package/dist/main.js +1 -1
  69. package/dist/main.js.map +1 -1
  70. package/dist/readiness.d.ts +3 -1
  71. package/dist/readiness.js.map +1 -1
  72. package/package.json +2 -2
  73. package/src/client.test.ts +90 -1
  74. package/src/client.ts +35 -2
  75. package/src/commands-auth.ts +174 -0
  76. package/src/commands-config.ts +307 -0
  77. package/src/commands-core.ts +240 -0
  78. package/src/commands-devices.ts +150 -0
  79. package/src/commands-doctor.ts +1209 -0
  80. package/src/commands-harness-context.ts +126 -0
  81. package/src/commands-hook-shape.ts +53 -0
  82. package/src/commands-hooks.ts +1586 -0
  83. package/src/commands-init.ts +721 -0
  84. package/src/commands-io.ts +108 -0
  85. package/src/commands-logs.ts +243 -0
  86. package/src/commands-send-support.ts +224 -0
  87. package/src/commands-send.ts +623 -0
  88. package/src/commands-setup-proof.ts +71 -0
  89. package/src/commands-skill.ts +84 -0
  90. package/src/commands.test.ts +493 -39
  91. package/src/commands.ts +58 -5614
  92. package/src/config-schema.ts +1 -1
  93. package/src/config.test.ts +9 -0
  94. package/src/config.ts +7 -2
  95. package/src/credentials.test.ts +25 -1
  96. package/src/credentials.ts +13 -3
  97. package/src/hooks.test.ts +351 -11
  98. package/src/hooks.ts +145 -97
  99. package/src/interactive.test.ts +19 -1
  100. package/src/interactive.ts +4 -4
  101. package/src/logging.test.ts +15 -2
  102. package/src/logging.ts +1 -0
  103. package/src/main.ts +1 -1
  104. package/src/readiness.ts +3 -1
@@ -0,0 +1,71 @@
1
+ import {} from './readiness.js';
2
+ import { skillsSource } from './release.js';
3
+ /**
4
+ * Where `npx skills add` fetches the optional agent skill from, derived from
5
+ * this build's own version so the pin cannot drift from the release it names.
6
+ * Null when the build cannot establish its version; see `./release.js`.
7
+ */
8
+ export const SKILLS_SOURCE = skillsSource();
9
+ /**
10
+ * How to refer to the pin in user-facing text.
11
+ *
12
+ * Only reached in a corrupted install, where naming the tag is impossible but
13
+ * saying nothing would be worse — the sentence still has to read as English.
14
+ */
15
+ const SKILLS_SOURCE_LABEL = SKILLS_SOURCE ?? 'the public release tag matching this CLI';
16
+ function skillSourceParts() {
17
+ if (SKILLS_SOURCE === null)
18
+ return null;
19
+ const match = /^([^#]+)#(.+)$/.exec(SKILLS_SOURCE);
20
+ return match === null ? null : { source: match[1], ref: match[2] };
21
+ }
22
+ function expectedSkill(skill) {
23
+ const expected = skillSourceParts();
24
+ return (expected !== null &&
25
+ skill.name === 'notifai' &&
26
+ skill.source === expected.source &&
27
+ skill.sourceType === 'github' &&
28
+ skill.ref === expected.ref);
29
+ }
30
+ export async function skillReadiness(deps, selectedScope) {
31
+ const scopes = selectedScope === undefined ? ['project', 'global'] : [selectedScope];
32
+ const results = await Promise.all(scopes.map(async (scope) => {
33
+ if (deps.nativeSkills === undefined)
34
+ return { scope, skills: [] };
35
+ try {
36
+ return { scope, ...(await deps.nativeSkills.list(scope, deps.cwd, deps.env)) };
37
+ }
38
+ catch (err) {
39
+ return { scope, skills: [], error: String(err) };
40
+ }
41
+ }));
42
+ const installed = results.flatMap(({ skills }) => skills).find(expectedSkill);
43
+ if (installed !== undefined) {
44
+ return {
45
+ id: 'skill',
46
+ title: 'Agent guidance skill',
47
+ status: 'ready',
48
+ detail: `installed from ${SKILLS_SOURCE_LABEL} in the ${installed.scope} scope`,
49
+ };
50
+ }
51
+ const errors = results
52
+ .filter((result) => result.error !== undefined)
53
+ .map((result) => `${result.scope}: ${result.error}`);
54
+ const scopeText = selectedScope === undefined ? 'project or machine-global scope' : `${selectedScope} scope`;
55
+ return {
56
+ id: 'skill',
57
+ title: 'Agent guidance skill',
58
+ status: 'optional-gap',
59
+ detail: errors.length > 0
60
+ ? `could not verify installer-managed state in ${scopeText} (${errors.join('; ')})`
61
+ : `not installed from ${SKILLS_SOURCE_LABEL} in ${scopeText}`,
62
+ remedy: {
63
+ by: 'cli',
64
+ summary: 'install the skill agents follow when deciding to notify',
65
+ command: selectedScope === undefined
66
+ ? 'notifai init --skills'
67
+ : `notifai init --skills --skills-scope ${selectedScope}`,
68
+ },
69
+ };
70
+ }
71
+ //# sourceMappingURL=commands-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands-skill.js","sourceRoot":"","sources":["../src/commands-skill.ts"],"names":[],"mappings":"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"}
@@ -1,387 +1,12 @@
1
- import { type ListRepliesResponse, type Platform, type QuestionT, type ReplyView, type RoutableDevice } from '@raidiant/notifai-protocol';
2
- import { type ApiClient, type ClientOptions } from './client.js';
3
- import type { CredentialStore } from './credentials.js';
4
- import { type Readiness, type ReadinessRefresh } from './readiness.js';
5
- import type { Tone } from './ui/theme.js';
6
- import { type HookHarness } from './hooks.js';
7
- import { type Logger } from './logging.js';
8
- import { type ClaudeWakeAdapters } from './claude-wake.js';
9
- import { type CodexWakeAdapters } from './codex-wake.js';
10
- import { type HookAdapterTarget } from './hook-adapter.js';
11
- import { type SendFlags } from './send.js';
12
- import type { NativeSkills, SkillScope } from './native-skills.js';
13
- export interface CommandIo {
14
- out(line: string): void;
15
- err(line: string): void;
16
- /** Interactive confirmation; resolves `fallback` (default false) when not interactive. */
17
- confirm(question: string, fallback?: boolean): Promise<boolean>;
18
- openUrl(url: string): void;
19
- /**
20
- * True only when a human is demonstrably driving a terminal. Everything below
21
- * is optional sugar that MUST only be called behind this flag: an agent that
22
- * reaches an interactive prompt does not error, it hangs — the prompt
23
- * libraries wait on stdin for ever — so the gate is bypass, not handling.
24
- * Test fakes leave all of this undefined and exercise the plain paths.
25
- */
26
- interactive?: boolean;
27
- select?(message: string, options: {
28
- value: string;
29
- label: string;
30
- hint?: string;
31
- }[]): Promise<string | null>;
32
- /** Interactive multi-select. `initial` are pre-selected values. */
33
- multiselect?(message: string, options: {
34
- value: string;
35
- label: string;
36
- hint?: string;
37
- }[], initial?: string[]): Promise<string[] | null>;
38
- intro?(title: string): Promise<void>;
39
- outro?(message: string): Promise<void>;
40
- note?(message: string, title?: string): Promise<void>;
41
- spinner?(message: string): Promise<CommandSpinner | null>;
42
- /**
43
- * A report line. `tone` distinguishes the two states that are neither pass
44
- * nor fail — something optional the user declined, and something that was
45
- * never evaluated — which a boolean has to round to one or the other.
46
- * Optional so existing implementations keep type-checking.
47
- */
48
- check?(ok: boolean, message: string, tone?: Tone): Promise<void>;
49
- }
50
- export interface CommandSpinner {
51
- message(message: string): void;
52
- stop(message: string): void;
53
- error(message: string): void;
54
- }
55
- export interface CommandDeps {
56
- io: CommandIo;
57
- store: CredentialStore;
58
- env: NodeJS.ProcessEnv;
59
- cwd: string;
60
- /** Test seam; production fixes the hook adapter under os.homedir(). */
61
- hookAdapterHome?: string;
62
- /** Test seam; production uses this process's Node and CLI paths. */
63
- hookInstallTarget?: HookAdapterTarget;
64
- /** Test seam; production uses process.platform for adapter format and quoting. */
65
- hookPlatform?: NodeJS.Platform;
66
- /** Test seam; production uses fetch against base_url. */
67
- clientFactory?: (baseUrl: string, bearer: string | null, options?: ClientOptions) => ApiClient;
68
- /** Test seam for bounded polling without wall-clock sleeps. */
69
- now?: () => number;
70
- /** Test seam for retry/backoff timing. */
71
- sleep?: (milliseconds: number) => Promise<void>;
72
- /** Test seams for Claude liveness, socket delivery, and cold resume. */
73
- claudeWake?: ClaudeWakeAdapters;
74
- claudeSourcePid?: number;
75
- /** Test seams for the Codex thread-writer probe and cold resume. */
76
- codexWake?: CodexWakeAdapters;
77
- codexSourcePid?: number;
78
- /** Test seam and production adapter for the external native skills installer. */
79
- nativeSkills?: NativeSkills;
80
- /**
81
- * The local record of what this invocation did. Optional so a test fake need
82
- * not carry one; `log(deps)` supplies a logger that records nothing.
83
- */
84
- logger?: Logger;
85
- }
86
- /** The invocation's logger, or one that discards everything. */
87
- export declare function log(deps: CommandDeps): Logger;
88
- export declare const EXIT: {
89
- readonly ok: 0;
90
- readonly failed: 1;
91
- readonly usage: 2;
92
- readonly noReply: 3;
93
- readonly auth: 4;
94
- readonly network: 5;
95
- };
96
- export declare function loginCommand(deps: CommandDeps, flags: {
97
- name?: string;
98
- baseUrl?: string;
99
- open?: boolean;
100
- }): Promise<number>;
101
- export declare function logoutCommand(deps: CommandDeps): number;
102
- export declare function authStatusCommand(deps: CommandDeps, flags: {
103
- json?: boolean;
104
- }): number;
105
- /** Show the server's account access decision without attempting a product mutation. */
106
- export declare function accessStatusCommand(deps: CommandDeps, flags: {
107
- json?: boolean;
108
- }): Promise<number>;
109
- export declare function devicesCommand(deps: CommandDeps, flags: {
110
- json?: boolean;
111
- }): Promise<number>;
112
- /**
113
- * Devices as data, for surfaces that render them themselves.
114
- *
115
- * `devicesCommand` prints and returns an exit code, which is the right shape
116
- * for a command and the wrong one for a menu that wants to show names beside
117
- * checkboxes. Silent on every failure by design: the interactive app already
118
- * shows the credential and connectivity state on its status card, so a second
119
- * error line here would be reporting the same fault twice.
120
- */
121
- export declare function deviceInventory(deps: CommandDeps): Promise<RoutableDevice[] | null>;
122
- /** Whether a device is in a state where a notification would actually arrive. */
123
- export declare function canDeviceReceive(device: RoutableDevice): boolean;
124
- export declare function capabilitiesCommand(deps: CommandDeps, flags: {
125
- json?: boolean;
126
- platform?: Platform;
127
- }): Promise<number>;
128
- export declare function sendCommand(deps: CommandDeps, flags: SendFlags & {
129
- json?: boolean;
130
- wait?: number;
131
- noWait?: boolean;
132
- replyTimeout?: number;
133
- noBlock?: boolean;
134
- idempotencyKey?: string;
135
- baseUrl?: string;
136
- }): Promise<number>;
137
- export declare function repliesCommand(deps: CommandDeps, requestedId: string | undefined, flags: {
138
- wait?: number;
139
- after?: number;
140
- json?: boolean;
141
- pending?: boolean;
142
- }): Promise<number>;
143
- interface ReplyWaitOptions {
144
- timeoutSeconds: number;
145
- afterSeq: number;
146
- now?: (() => number) | undefined;
147
- sleep?: ((milliseconds: number) => Promise<void>) | undefined;
148
- }
149
- interface ReplyWaitResult {
150
- response: ListRepliesResponse;
151
- timedOut: boolean;
152
- /**
153
- * The wait ended while polls were failing, so silence is unproven: the user
154
- * may well have answered and we could not see it.
155
- */
156
- degraded: boolean;
157
- }
158
- /** Loop over server-capped long polls until a reply arrives or the caller's deadline passes. */
159
- export declare function waitForReply(client: ApiClient, requestId: string, options: ReplyWaitOptions): Promise<ReplyWaitResult>;
160
- /**
161
- * The correction note for a wait that saw more than one answer.
162
- *
163
- * A later reply that conflicts with an earlier one is a correction, so the
164
- * latest answer is the one that counts. The server retires the question on
165
- * the other devices the moment one answers, which makes this rare; it is
166
- * still reachable, because a device can answer between the first reply
167
- * landing and its retirement arriving.
168
- *
169
- * Ordered by seq, so `replies.at(-1)` is the answer to act on.
170
- */
171
- export declare function contradictingAnswer(replies: ReplyView[]): string | null;
172
- export declare function statusCommand(deps: CommandDeps, requestId: string, flags: {
173
- json?: boolean;
174
- }): Promise<number>;
175
- export declare const HOOK_EVENTS: readonly ["user-prompt-submit", "stop", "session-end"];
176
- export type HookEvent = (typeof HOOK_EVENTS)[number];
177
- /** SessionEnd cleanup must precede every diagnostic that can wait on a file lock. */
178
- export declare function hookDefersDiagnosticsUntilAfterCleanup(event: unknown): event is 'session-end';
179
- /**
180
- * Runs one harness hook. Contract with every harness: hook JSON arrives on
181
- * stdin, the decision (if any) goes to stdout, diagnostics go to stderr, and
182
- * exit 0 with no stdout means "no decision — carry on as normal".
183
- *
184
- * Every failure path in here must reach that no-decision state. A hook that
185
- * throws, or that blocks past the harness's timeout, degrades the agent for a
186
- * feature the user only asked to make it more convenient.
187
- */
188
- export declare function hookRunCommand(deps: CommandDeps, event: string, readStdin: () => Promise<string>, harness?: HookHarness): Promise<number>;
189
- /**
190
- * What went wrong, in terms of what to do about it.
191
- *
192
- * On 2026-08-03 a contract change shipped without the server deploy that goes
193
- * with it. The CLI stamped `lifecycle` on every question draft, the deployed
194
- * server rejected the unknown field, and escalation stopped working entirely —
195
- * announced as "hook failed, deferring to the terminal", which reads like a
196
- * flaky network. The information needed to diagnose it in one second was
197
- * already in hand: a 422 whose details name the offending path. It was being
198
- * thrown away by `String(err)`.
199
- *
200
- * A hook still exits 0 whatever this says. Handing the terminal back is always
201
- * right; the only question is whether the user is told anything they can use.
202
- */
203
- export declare function describeHookFailure(err: unknown): string[];
204
- export interface AskFlags {
205
- /** Emit the registration and its turn obligation as one JSON object. */
206
- json?: boolean;
207
- choice?: string[];
208
- /** The single question is multi-select: several answers may be chosen. */
209
- multi?: boolean;
210
- /** Optional Markdown context appended after the question block. */
211
- body?: string;
212
- /** Raw JSON for a multi-question form; replaces the positional question. */
213
- form?: string;
214
- image?: string[];
215
- imageAlt?: string[];
216
- project?: string;
217
- sessionId?: string;
218
- sessionLabel?: string;
219
- }
220
- export interface BuiltQuestions {
221
- questions: QuestionT[];
222
- /** Canonical Markdown body: question block first, optional context second. */
223
- body: string;
224
- }
225
- /**
226
- * Turn ask input into questions plus their canonical body. Everything is
227
- * validated at registration because a later hook failure is easy to miss.
228
- */
229
- export declare function buildQuestions(flags: AskFlags, question: string | undefined): {
230
- ok: true;
231
- questions: QuestionT[];
232
- body: string;
233
- } | {
234
- ok: false;
235
- error: string;
236
- };
237
- /**
238
- * Registers a question for turn-end routing. Returns immediately so the agent
239
- * can ask in prose and end its turn; the terminal keeps the question to itself
240
- * for `ask_grace_seconds` before it reaches any device.
241
- */
242
- export declare function askCommand(deps: CommandDeps, question: string | undefined, flags: AskFlags): number | Promise<number>;
243
- /**
244
- * Record the one Agent Acknowledgement associated with a replied-to request.
245
- *
246
- * `--text` is optional here because the acknowledgement is not: an account may
247
- * turn the agent's written reply off, and the receipt must still be recorded so
248
- * the user sees that an agent read the answer. The service holds the account's
249
- * snapshot, so it — not this process — decides whether text was owed.
250
- */
251
- export declare function acknowledgeCommand(deps: CommandDeps, requestId: string, flags: {
252
- text?: string;
253
- json?: boolean;
254
- }): Promise<number>;
255
- /** Retire a question so a late answer is rejected rather than silently lost. */
256
- export declare function closeCommand(deps: CommandDeps, requestId: string, flags?: {
257
- json?: boolean;
258
- }): Promise<number>;
259
- export interface HooksInstallFlags {
260
- harness?: string;
261
- global?: boolean;
262
- /** Test seam; production resolves the running CLI. */
263
- execPath?: string;
264
- scriptPath?: string;
265
- }
266
- /** True when this process is `npx` / `npm exec`, not a global or linked install. */
267
- export declare function runningViaNpx(env: NodeJS.ProcessEnv, scriptPath: string): boolean;
268
- export declare function hooksInstallCommand(deps: CommandDeps, flags: HooksInstallFlags): number;
269
- export declare function hooksUninstallCommand(deps: CommandDeps, flags: HooksInstallFlags): number;
270
- export declare function configShowCommand(deps: CommandDeps, flags: {
271
- json?: boolean;
272
- explain?: boolean;
273
- plain?: boolean;
274
- }): number;
275
- /**
276
- * One setting, explained in full.
277
- *
278
- * The gap this closes: `config show` prints a value and provenance but that is
279
- * not enough to explain the setting's consequences. Every key already had a
280
- * careful explanation — in a TypeScript comment, read by everyone except the
281
- * person who needed it.
282
- */
283
- export declare function configExplainCommand(deps: CommandDeps, key: string, flags?: {
284
- json?: boolean;
285
- }): number;
286
- export declare function configSetCommand(deps: CommandDeps, key: string, rawValue: string, flags: {
287
- project?: boolean;
288
- local?: boolean;
289
- session?: string;
290
- yes?: boolean;
291
- }): Promise<number>;
292
- type ConfigMutationFlags = {
293
- project?: boolean;
294
- local?: boolean;
295
- session?: string;
296
- yes?: boolean;
297
- };
298
- export declare function configUnsetCommand(deps: CommandDeps, key: string, flags: ConfigMutationFlags): Promise<number>;
299
- export interface LogsFlags {
300
- json?: boolean;
301
- limit?: number;
302
- all?: boolean;
303
- since?: string;
304
- level?: string;
305
- event?: string[];
306
- run?: string;
307
- request?: string;
308
- session?: string;
309
- project?: string;
310
- allProjects?: boolean;
311
- grep?: string;
312
- path?: boolean;
313
- clear?: boolean;
314
- }
315
- /** `10m`, `2h`, `1d`, or an ISO 8601 instant. */
316
- export declare function parseSince(raw: string, now: number): number | null;
317
- /**
318
- * What this machine recorded about itself.
319
- *
320
- * The retrieval half of the local log, and the half that decides whether the
321
- * log is worth having. Three things make it usable by an agent rather than
322
- * merely available to one: the default is bounded and scoped to this project,
323
- * the filters match the questions actually asked ("that run", "that
324
- * notification", "just the failures"), and `--json` gives the machine the
325
- * records untouched on stdout while every word of explanation goes to stderr.
326
- */
327
- export declare function logsCommand(deps: CommandDeps, flags: LogsFlags): number;
328
- /**
329
- * Where `npx skills add` fetches the optional agent skill from, derived from
330
- * this build's own version so the pin cannot drift from the release it names.
331
- * Null when the build cannot establish its version; see `./release.js`.
332
- */
333
- export declare const SKILLS_SOURCE: string | null;
334
- /** Derive a contract-valid project slug; init alone needs a non-empty fallback. */
335
- export declare function projectSlugFrom(name: string): string;
336
- export interface InitFlags {
337
- projectId?: string;
338
- /**
339
- * Install the agent guidance skill. Tri-state on purpose:
340
- * true installs, false skips silently, and undefined means "offer it when a
341
- * human is present, do nothing when one is not" — an unattended run must
342
- * never spawn npx against the network by default.
343
- */
344
- skills?: boolean;
345
- /** Scope selected by an unattended caller; humans choose inside npx skills. */
346
- skillsScope?: SkillScope;
347
- /** Same tri-state, for the harness hooks. */
348
- hooks?: boolean;
349
- }
350
- /**
351
- * Setup as one step at a time.
352
- *
353
- * The old version ran five steps in a fixed order and ended with a list of
354
- * everything still outstanding. That is a report, and a report is the wrong
355
- * output here: someone handed five things to do does none of them, and the
356
- * order was the script's rather than the dependency graph's — it offered to
357
- * install hooks after a sign-in that had just failed.
358
- *
359
- * So this closes what it can, then surfaces exactly one thing, the first that
360
- * stands in the way. Re-running advances by one. Idempotence stops being a
361
- * property to preserve and becomes the mechanism: every decision is derived
362
- * from observed state, so a partial run, a second project, a fresh worktree
363
- * and a revoked credential are the same code path arriving at different
364
- * states rather than four branches to enumerate.
365
- */
366
- export declare function initCommand(deps: CommandDeps, flags: InitFlags): Promise<number>;
367
- /**
368
- * Read the whole setup once, in dependency order.
369
- *
370
- * Descent stops where a prerequisite is missing: without a credential there is
371
- * nothing to ask the server with, and without a reachable server a contract
372
- * mismatch is unknowable rather than absent. Those downstream states report
373
- * `unknown`, which is the honest answer and keeps a network outage from
374
- * looking like a broken install.
375
- */
376
- export declare function assessReadiness(deps: CommandDeps, options?: {
377
- skillScope?: SkillScope;
378
- previous?: Readiness;
379
- refresh?: readonly ReadinessRefresh[];
380
- }): Promise<Readiness>;
381
- export declare function doctorCommand(deps: CommandDeps, flags: {
382
- json?: boolean;
383
- }, options?: {
384
- readiness?: Readiness;
385
- }): Promise<number>;
386
- export declare function realIo(env?: NodeJS.ProcessEnv): CommandIo;
387
- export {};
1
+ export { EXIT, log, type CommandDeps, type CommandIo, type CommandSpinner, } from './commands-core.js';
2
+ export { accessStatusCommand, authStatusCommand, loginCommand, logoutCommand, } from './commands-auth.js';
3
+ export { canDeviceReceive, capabilitiesCommand, deviceInventory, devicesCommand, } from './commands-devices.js';
4
+ export { contradictingAnswer, repliesCommand, sendCommand, statusCommand, } from './commands-send.js';
5
+ export { waitForReply } from './commands-send-support.js';
6
+ export { HOOK_EVENTS, acknowledgeCommand, askCommand, buildQuestions, closeCommand, describeHookFailure, hookDefersDiagnosticsUntilAfterCleanup, hookRunCommand, hooksInstallCommand, hooksUninstallCommand, runningViaNpx, type AskFlags, type BuiltQuestions, type HookEvent, type HooksInstallFlags, } from './commands-hooks.js';
7
+ export { configExplainCommand, configSetCommand, configShowCommand, configUnsetCommand, } from './commands-config.js';
8
+ export { logsCommand, parseSince, type LogsFlags } from './commands-logs.js';
9
+ export { SKILLS_SOURCE } from './commands-skill.js';
10
+ export { initCommand, projectSlugFrom, type InitFlags, } from './commands-init.js';
11
+ export { assessReadiness, doctorCommand } from './commands-doctor.js';
12
+ export { realIo } from './commands-io.js';