@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
package/CHANGELOG.md CHANGED
@@ -8,6 +8,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
9
9
  and [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
10
10
 
11
+ ## [6.0.0](https://github.com/Raidiant-io/notifai/compare/v5.0.0...v6.0.0) (2026-08-18)
12
+
13
+
14
+ ### ⚠ BREAKING CHANGES
15
+
16
+ * **compatibility:** the protocol lifecycle vocabulary no longer includes superseded.
17
+ * **protocol:** Device registration no longer accepts the reply protocol integer.
18
+
19
+ ### Features
20
+
21
+ * **cli:** focus companion setup on iPhone ([77b9197](https://github.com/Raidiant-io/notifai/commit/77b91976182ded7e7722469c400ef2c238e738a2))
22
+ * **compatibility:** preserve baseline delivery across client skew ([f5fe1d1](https://github.com/Raidiant-io/notifai/commit/f5fe1d1c7c5c7b1f80906d01e3b23a1061ba7f1c))
23
+ * **protocol:** negotiate named client capabilities ([873973b](https://github.com/Raidiant-io/notifai/commit/873973b98c4d91ed585ac85b6ac8abd267573f01))
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **cli:** preserve future session state on prompts ([2e18601](https://github.com/Raidiant-io/notifai/commit/2e186015e106a9559188e67230913fb25c56dfb5))
29
+ * **cli:** preserve future session state on prompts ([f70c885](https://github.com/Raidiant-io/notifai/commit/f70c88556539b13689c2669e43103056ef69b1c2))
30
+
31
+
32
+ ### Dependencies
33
+
34
+ * The following workspace dependencies were updated
35
+ * dependencies
36
+ * @raidiant/notifai-protocol bumped from 2.0.0 to 3.0.0
37
+
11
38
  ## [5.0.0](https://github.com/Raidiant-io/notifai/compare/v4.0.0...v5.0.0) (2026-08-16)
12
39
 
13
40
 
package/README.md CHANGED
@@ -65,8 +65,8 @@ For a harness that cannot resume an idle agent turn, `notifai send
65
65
  ## Agent harnesses
66
66
 
67
67
  The CLI and managed hook adapters support macOS, Linux, and Windows. Receiving
68
- still requires the current iPhone or macOS Companion App; native Windows and
69
- Linux Companion Apps are not shipped yet.
68
+ in the current release requires the iPhone Companion App; native desktop
69
+ Companion Apps are not shipped yet.
70
70
 
71
71
  ```sh
72
72
  notifai hooks install
package/dist/client.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import type { AccountAccessResponse, BeginPairingResponse, CapabilityDocument, CreateMediaUploadRequestT, CreateMediaUploadResponse, FinalizeMediaUploadResponse, EvidenceSnapshot, GetAgentAcknowledgementResponse, ListDevicesResponse, ListRepliesResponse, Platform, PollPairingResponse, PutAgentAcknowledgementRequestT, PutAgentAcknowledgementResponse, SubmissionReceipt, SubmitNotificationRequestT } from '@raidiant/notifai-protocol';
1
+ import type { AccountAccessResponse, BeginPairingResponse, CapabilityDocument, CreateMediaUploadRequestT, CreateMediaUploadResponse, FinalizeMediaUploadResponse, EvidenceSnapshot, GetAgentAcknowledgementResponse, ListDevicesResponse, ClientCapability, CompatibilityResponse, RecoveryAction, ListRepliesResponse, Platform, PollPairingResponse, PutAgentAcknowledgementRequestT, PutAgentAcknowledgementResponse, SubmissionReceipt, SubmitNotificationRequestT } from '@raidiant/notifai-protocol';
2
2
  import type { Logger } from './logging.js';
3
3
  export declare class ApiCallError extends Error {
4
4
  status: number;
5
5
  code: string;
6
6
  nextAction: string | null;
7
7
  details: unknown;
8
- constructor(status: number, code: string, message: string, nextAction?: string | null, details?: unknown);
8
+ recoveryAction: RecoveryAction | null;
9
+ constructor(status: number, code: string, message: string, nextAction?: string | null, details?: unknown, recoveryAction?: RecoveryAction | null);
9
10
  }
10
11
  export declare class NetworkError extends Error {
11
12
  }
@@ -25,7 +26,8 @@ export interface ApiClient {
25
26
  pollPairing(pairingId: string, pollVerifier: string): Promise<PollPairingResponse>;
26
27
  accessStatus(): Promise<AccountAccessResponse>;
27
28
  listDevices(): Promise<ListDevicesResponse>;
28
- capabilities(platform?: Platform): Promise<CapabilityDocument>;
29
+ capabilities(platform?: Platform, appVersion?: string, appBuild?: string): Promise<CapabilityDocument>;
30
+ compatibility(): Promise<CompatibilityResponse>;
29
31
  submit(body: SubmitNotificationRequestT, waitSeconds: number): Promise<SubmissionReceipt>;
30
32
  evidence(requestId: string): Promise<EvidenceSnapshot>;
31
33
  replies(requestId: string, options: {
@@ -65,5 +67,8 @@ export interface ClientOptions {
65
67
  * instantly by a status code and a duration.
66
68
  */
67
69
  logger?: Pick<Logger, 'debug' | 'error'>;
70
+ /** Artifact identity and named jobs advertised only on authenticated traffic. */
71
+ cliVersion?: string | null;
72
+ capabilities?: readonly ClientCapability[];
68
73
  }
69
74
  export declare function createClient(baseUrl: string, bearer: string | null, options?: ClientOptions): ApiClient;
package/dist/client.js CHANGED
@@ -1,14 +1,17 @@
1
+ import { CAPABILITIES_HEADER, CLI_VERSION_HEADER, } from '@raidiant/notifai-protocol';
1
2
  export class ApiCallError extends Error {
2
3
  status;
3
4
  code;
4
5
  nextAction;
5
6
  details;
6
- constructor(status, code, message, nextAction = null, details = null) {
7
+ recoveryAction;
8
+ constructor(status, code, message, nextAction = null, details = null, recoveryAction = null) {
7
9
  super(message);
8
10
  this.status = status;
9
11
  this.code = code;
10
12
  this.nextAction = nextAction;
11
13
  this.details = details;
14
+ this.recoveryAction = recoveryAction;
12
15
  }
13
16
  }
14
17
  export class NetworkError extends Error {
@@ -45,6 +48,14 @@ export function createClient(baseUrl, bearer, options = {}) {
45
48
  const budgetMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
46
49
  const now = options.now ?? Date.now;
47
50
  const logger = options.logger;
51
+ const clientHeaders = bearer
52
+ ? {
53
+ ...(options.cliVersion ? { [CLI_VERSION_HEADER]: options.cliVersion } : {}),
54
+ ...(options.capabilities
55
+ ? { [CAPABILITIES_HEADER]: options.capabilities.join(',') }
56
+ : {}),
57
+ }
58
+ : {};
48
59
  async function call(method, apiPath, body,
49
60
  /** Seconds the server was asked to hold the connection open. */
50
61
  serverWaitSeconds = 0) {
@@ -90,6 +101,7 @@ export function createClient(baseUrl, bearer, options = {}) {
90
101
  headers: {
91
102
  ...(body !== undefined ? { 'content-type': 'application/json' } : {}),
92
103
  ...(bearer ? { authorization: bearer } : {}),
104
+ ...clientHeaders,
93
105
  },
94
106
  signal,
95
107
  ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
@@ -106,7 +118,7 @@ export function createClient(baseUrl, bearer, options = {}) {
106
118
  catch {
107
119
  // non-JSON body
108
120
  }
109
- throw new ApiCallError(response.status, parsed?.error.code ?? 'internal_error', parsed?.error.message ?? `Request failed with status ${response.status}`, parsed?.error.next_action ?? null, parsed?.error.details ?? null);
121
+ throw new ApiCallError(response.status, parsed?.error.code ?? 'internal_error', parsed?.error.message ?? `Request failed with status ${response.status}`, parsed?.error.next_action ?? null, parsed?.error.details ?? null, parsed?.error.recovery_action ?? null);
110
122
  }
111
123
  if (response.status === 204)
112
124
  return undefined;
@@ -124,7 +136,16 @@ export function createClient(baseUrl, bearer, options = {}) {
124
136
  pollPairing: (pairingId, pollVerifier) => call('POST', `/api/v1/pairings/${pairingId}/poll`, { poll_verifier: pollVerifier }),
125
137
  accessStatus: () => call('GET', '/api/v1/account/access'),
126
138
  listDevices: () => call('GET', '/api/v1/devices'),
127
- capabilities: (platform = 'ios') => call('GET', `/api/v1/capabilities/${platform}`),
139
+ capabilities: (platform = 'ios', appVersion, appBuild) => {
140
+ const query = new URLSearchParams();
141
+ if (appVersion !== undefined)
142
+ query.set('app_version', appVersion);
143
+ if (appBuild !== undefined)
144
+ query.set('app_build', appBuild);
145
+ const suffix = query.size > 0 ? `?${query.toString()}` : '';
146
+ return call('GET', `/api/v1/capabilities/${platform}${suffix}`);
147
+ },
148
+ compatibility: () => call('GET', '/api/v1/compatibility'),
128
149
  submit: (body, waitSeconds) => call('POST', `/api/v1/notifications?wait_seconds=${waitSeconds}`, body, waitSeconds),
129
150
  evidence: (requestId) => call('GET', `/api/v1/notifications/${requestId}`),
130
151
  replies: (requestId, { waitSeconds, afterSeq }) => call('GET', `/api/v1/notifications/${encodeURIComponent(requestId)}/replies?wait_seconds=${waitSeconds}&after_seq=${afterSeq}`, undefined, waitSeconds),
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type CommandDeps } from './commands-core.js';
2
+ export declare function loginCommand(deps: CommandDeps, flags: {
3
+ name?: string;
4
+ baseUrl?: string;
5
+ open?: boolean;
6
+ }): Promise<number>;
7
+ export declare function logoutCommand(deps: CommandDeps): number;
8
+ export declare function authStatusCommand(deps: CommandDeps, flags: {
9
+ json?: boolean;
10
+ }): number;
11
+ /** Show the server's account access decision without attempting a product mutation. */
12
+ export declare function accessStatusCommand(deps: CommandDeps, flags: {
13
+ json?: boolean;
14
+ }): Promise<number>;
@@ -0,0 +1,154 @@
1
+ import {} from '@raidiant/notifai-protocol';
2
+ import { sha256Hex } from '@raidiant/notifai-protocol/node';
3
+ import { randomBytes } from 'node:crypto';
4
+ import os from 'node:os';
5
+ import { NetworkError } from './client.js';
6
+ import {} from './config.js';
7
+ import { EXIT, authedClient, loadLoggedConfig, makeClient, reportError, } from './commands-core.js';
8
+ // ---------------------------------------------------------------------------
9
+ // login / logout / auth status
10
+ // ---------------------------------------------------------------------------
11
+ export async function loginCommand(deps, flags) {
12
+ const config = loadLoggedConfig(deps, { cwd: deps.cwd, env: deps.env, flags: { base_url: flags.baseUrl } });
13
+ const baseUrl = config.base_url.value;
14
+ const machineName = flags.name ?? os.hostname();
15
+ const secret = randomBytes(32).toString('base64url');
16
+ const pollVerifier = randomBytes(24).toString('base64url');
17
+ const client = makeClient(deps, baseUrl, null);
18
+ let begin;
19
+ try {
20
+ begin = await client.beginPairing({
21
+ machine_name: machineName,
22
+ credential_hash: sha256Hex(secret),
23
+ poll_verifier_hash: sha256Hex(pollVerifier),
24
+ });
25
+ }
26
+ catch (err) {
27
+ return reportError(deps, err);
28
+ }
29
+ const interactive = deps.io.interactive === true;
30
+ if (interactive) {
31
+ await deps.io.intro?.('Notifai sign in');
32
+ await deps.io.note?.(`Code: ${begin.code}\n${begin.approve_url}`, 'Approve this machine');
33
+ }
34
+ else {
35
+ deps.io.out(`Pairing code: ${begin.code}`);
36
+ deps.io.out(`Approve this machine at: ${begin.approve_url}`);
37
+ deps.io.out('Waiting for approval…');
38
+ }
39
+ if (flags.open !== false)
40
+ deps.io.openUrl(begin.approve_url);
41
+ const expiresAt = new Date(begin.expires_at).getTime();
42
+ const intervalMs = Math.max(begin.poll_interval_seconds, 1) * 1000;
43
+ const now = deps.now ?? Date.now;
44
+ const sleep = deps.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
45
+ const approvalWaitMessage = () => {
46
+ const remainingSec = Math.max(0, Math.ceil((expiresAt - now()) / 1000));
47
+ const minutes = Math.floor(remainingSec / 60);
48
+ const seconds = remainingSec % 60;
49
+ const remaining = minutes > 0 ? `${minutes}m ${seconds.toString().padStart(2, '0')}s` : `${seconds}s`;
50
+ return `Waiting for approval… code ${begin.code} · ${remaining} left`;
51
+ };
52
+ const spinner = interactive ? await deps.io.spinner?.(approvalWaitMessage()) : null;
53
+ while (now() < expiresAt) {
54
+ await sleep(intervalMs);
55
+ let poll;
56
+ try {
57
+ poll = await client.pollPairing(begin.pairing_id, pollVerifier);
58
+ }
59
+ catch (err) {
60
+ if (err instanceof NetworkError) {
61
+ spinner?.message(`Connection lost — retrying… code ${begin.code}`);
62
+ continue;
63
+ }
64
+ spinner?.error('Pairing failed');
65
+ return reportError(deps, err);
66
+ }
67
+ if (poll.status === 'approved' && poll.machine_id) {
68
+ deps.store.save({ machineId: poll.machine_id, secret, baseUrl, machineName });
69
+ if (interactive) {
70
+ spinner?.stop(`Machine "${machineName}" approved`);
71
+ await deps.io.outro?.(`Credential stored in ${deps.store.describe()}`);
72
+ }
73
+ else {
74
+ deps.io.out(`Machine "${machineName}" approved. Credential stored in ${deps.store.describe()}.`);
75
+ }
76
+ return EXIT.ok;
77
+ }
78
+ if (poll.status === 'denied') {
79
+ spinner?.error('Pairing denied');
80
+ deps.io.err('Pairing was denied from the dashboard.');
81
+ return EXIT.auth;
82
+ }
83
+ if (poll.status === 'no_active_plan') {
84
+ const next = poll.next_action ??
85
+ `Open ${baseUrl.replace(/\/$/, '')}/support to request Alpha access, then retry.`;
86
+ spinner?.error('Account has no Alpha access');
87
+ deps.io.err('This account has no active plan or temporary Alpha access.');
88
+ deps.io.err(`next: ${next}`);
89
+ deps.io.err('After access is granted, run `notifai login` again.');
90
+ return EXIT.auth;
91
+ }
92
+ if (poll.status === 'expired')
93
+ break;
94
+ spinner?.message(approvalWaitMessage());
95
+ }
96
+ spinner?.error('Pairing expired');
97
+ deps.io.err('Pairing expired before it was approved. Run `notifai login` again.');
98
+ return EXIT.auth;
99
+ }
100
+ export function logoutCommand(deps) {
101
+ deps.store.clear();
102
+ deps.io.out('Machine credential removed. Revoke it in the dashboard too if the machine is untrusted.');
103
+ return EXIT.ok;
104
+ }
105
+ export function authStatusCommand(deps, flags) {
106
+ const credential = deps.store.load();
107
+ if (flags.json) {
108
+ deps.io.out(JSON.stringify(credential
109
+ ? {
110
+ signed_in: true,
111
+ machine_id: credential.machineId,
112
+ machine_name: credential.machineName,
113
+ base_url: credential.baseUrl,
114
+ store: deps.store.describe(),
115
+ }
116
+ : { signed_in: false }, null, 2));
117
+ return credential ? EXIT.ok : EXIT.auth;
118
+ }
119
+ if (!credential) {
120
+ deps.io.err('Not signed in. Run `notifai login`.');
121
+ return EXIT.auth;
122
+ }
123
+ deps.io.out(`Signed in as machine "${credential.machineName}" (${credential.machineId})`);
124
+ deps.io.out(`Server: ${credential.baseUrl}`);
125
+ deps.io.out(`Credential store: ${deps.store.describe()}`);
126
+ return EXIT.ok;
127
+ }
128
+ /** Show the server's account access decision without attempting a product mutation. */
129
+ export async function accessStatusCommand(deps, flags) {
130
+ const config = loadLoggedConfig(deps, { cwd: deps.cwd, env: deps.env });
131
+ const authed = authedClient(deps, config);
132
+ if (!authed)
133
+ return EXIT.auth;
134
+ try {
135
+ const access = await authed.client.accessStatus();
136
+ if (flags.json) {
137
+ deps.io.out(JSON.stringify(access, null, 2));
138
+ return access.status === 'active' ? EXIT.ok : EXIT.failed;
139
+ }
140
+ if (access.status === 'no_active_plan') {
141
+ const supportUrl = `${authed.baseUrl.replace(/\/$/, '')}/support`;
142
+ deps.io.out('No active plan or temporary Alpha access for this account.');
143
+ deps.io.out(`next: Open ${supportUrl} to request Alpha access, then retry.`);
144
+ return EXIT.failed;
145
+ }
146
+ const expiry = access.expires_at ? ` until ${access.expires_at}` : '';
147
+ deps.io.out(`Access active (${access.reason})${expiry}`);
148
+ return EXIT.ok;
149
+ }
150
+ catch (err) {
151
+ return reportError(deps, err);
152
+ }
153
+ }
154
+ //# sourceMappingURL=commands-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands-auth.js","sourceRoot":"","sources":["../src/commands-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type CommandDeps } from './commands-core.js';
2
+ export declare function configShowCommand(deps: CommandDeps, flags: {
3
+ json?: boolean;
4
+ explain?: boolean;
5
+ plain?: boolean;
6
+ }): number;
7
+ /**
8
+ * One setting, explained in full.
9
+ *
10
+ * The gap this closes: `config show` prints a value and provenance but that is
11
+ * not enough to explain the setting's consequences. Every key already had a
12
+ * careful explanation — in a TypeScript comment, read by everyone except the
13
+ * person who needed it.
14
+ */
15
+ export declare function configExplainCommand(deps: CommandDeps, key: string, flags?: {
16
+ json?: boolean;
17
+ }): number;
18
+ export declare function configSetCommand(deps: CommandDeps, key: string, rawValue: string, flags: {
19
+ project?: boolean;
20
+ local?: boolean;
21
+ session?: string;
22
+ yes?: boolean;
23
+ }): Promise<number>;
24
+ type ConfigMutationFlags = {
25
+ project?: boolean;
26
+ local?: boolean;
27
+ session?: string;
28
+ yes?: boolean;
29
+ };
30
+ export declare function configUnsetCommand(deps: CommandDeps, key: string, flags: ConfigMutationFlags): Promise<number>;
31
+ export {};
@@ -0,0 +1,246 @@
1
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync, } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parse as parseToml, stringify as stringifyToml } from 'smol-toml';
4
+ import { acceptedValues, configInfo } from './config-schema.js';
5
+ import { BOOLEAN_CONFIG_KEYS, CONFIG_KEYS, NUMERIC_CONFIG_KEYS, configBounds, configDefaultValue, findProjectConfigPath, globalConfigPath, personalProjectConfigPath, sessionConfigPath, } from './config.js';
6
+ import { renderConfigExplain, renderConfigList, renderConfigPlain } from './ui/config-view.js';
7
+ import { EXIT, loadLoggedConfig } from './commands-core.js';
8
+ // ---------------------------------------------------------------------------
9
+ // config show / set / unset
10
+ // ---------------------------------------------------------------------------
11
+ export function configShowCommand(deps, flags) {
12
+ const config = loadLoggedConfig(deps, { cwd: deps.cwd, env: deps.env });
13
+ if (flags.json) {
14
+ const output = Object.fromEntries(CONFIG_KEYS.map((key) => [
15
+ key,
16
+ {
17
+ value: config[key].value,
18
+ source: config[key].source,
19
+ summary: configInfo(key).summary,
20
+ },
21
+ ]));
22
+ deps.io.out(JSON.stringify(output, null, 2));
23
+ return EXIT.ok;
24
+ }
25
+ // Anything that is not a person at a terminal keeps the flat `key = value`
26
+ // form it has always had. Scripts parse this, and a prettier layout for an
27
+ // audience that cannot see it would only be a breaking change.
28
+ if (deps.io.interactive !== true || flags.plain === true) {
29
+ for (const line of renderConfigPlain(config, flags.explain === true))
30
+ deps.io.out(line);
31
+ return EXIT.ok;
32
+ }
33
+ for (const line of renderConfigList(config, { showAdvanced: flags.explain === true })) {
34
+ deps.io.out(line);
35
+ }
36
+ return EXIT.ok;
37
+ }
38
+ /**
39
+ * One setting, explained in full.
40
+ *
41
+ * The gap this closes: `config show` prints a value and provenance but that is
42
+ * not enough to explain the setting's consequences. Every key already had a
43
+ * careful explanation — in a TypeScript comment, read by everyone except the
44
+ * person who needed it.
45
+ */
46
+ export function configExplainCommand(deps, key, flags = {}) {
47
+ if (!CONFIG_KEYS.includes(key)) {
48
+ deps.io.err(`Unknown setting "${key}".`);
49
+ deps.io.err(`Valid settings: ${CONFIG_KEYS.join(', ')}`);
50
+ return EXIT.usage;
51
+ }
52
+ const configKey = key;
53
+ const config = loadLoggedConfig(deps, { cwd: deps.cwd, env: deps.env });
54
+ const info = configInfo(configKey);
55
+ const entry = config[configKey];
56
+ if (flags.json) {
57
+ deps.io.out(JSON.stringify({
58
+ key: configKey,
59
+ label: info.label,
60
+ group: info.group,
61
+ kind: info.kind,
62
+ summary: info.summary,
63
+ detail: info.detail,
64
+ accepts: acceptedValues(configKey),
65
+ ...(info.choices !== undefined ? { choices: info.choices } : {}),
66
+ value: entry.value,
67
+ source: entry.source,
68
+ }, null, 2));
69
+ return EXIT.ok;
70
+ }
71
+ if (deps.io.interactive !== true) {
72
+ deps.io.out(`${configKey} = ${JSON.stringify(entry.value)} [${entry.source}]`);
73
+ deps.io.out(info.detail.replace(/\n\n/g, '\n'));
74
+ deps.io.out(`accepts: ${acceptedValues(configKey)}`);
75
+ return EXIT.ok;
76
+ }
77
+ for (const line of renderConfigExplain(configKey, config))
78
+ deps.io.out(line);
79
+ return EXIT.ok;
80
+ }
81
+ /**
82
+ * Closest config key by edit distance, or null when nothing is close.
83
+ *
84
+ * The threshold matters more than the algorithm: suggesting a key that shares
85
+ * three letters with the typo sends the reader to the wrong setting with
86
+ * confidence, which is worse than listing all fourteen and letting them look.
87
+ */
88
+ function nearestKey(input) {
89
+ let best = null;
90
+ let bestDistance = Number.POSITIVE_INFINITY;
91
+ for (const candidate of CONFIG_KEYS) {
92
+ const distance = editDistance(input.toLowerCase(), candidate);
93
+ if (distance < bestDistance) {
94
+ bestDistance = distance;
95
+ best = candidate;
96
+ }
97
+ }
98
+ return best !== null && bestDistance <= Math.max(2, Math.floor(best.length / 3)) ? best : null;
99
+ }
100
+ function editDistance(a, b) {
101
+ const previous = Array.from({ length: b.length + 1 }, (_, i) => i);
102
+ for (let i = 1; i <= a.length; i += 1) {
103
+ let diagonal = previous[0];
104
+ previous[0] = i;
105
+ for (let j = 1; j <= b.length; j += 1) {
106
+ const above = previous[j];
107
+ previous[j] = Math.min(previous[j] + 1, previous[j - 1] + 1, diagonal + (a[i - 1] === b[j - 1] ? 0 : 1));
108
+ diagonal = above;
109
+ }
110
+ }
111
+ return previous[b.length];
112
+ }
113
+ export async function configSetCommand(deps, key, rawValue, flags) {
114
+ const configKey = configMutationKey(deps, key);
115
+ if (configKey === null)
116
+ return EXIT.usage;
117
+ const info = configInfo(configKey);
118
+ let value = rawValue;
119
+ if (NUMERIC_CONFIG_KEYS.includes(configKey)) {
120
+ const numeric = Number(rawValue);
121
+ if (!Number.isInteger(numeric)) {
122
+ deps.io.err(`${key} takes ${acceptedValues(configKey)}, not "${rawValue}".`);
123
+ return EXIT.usage;
124
+ }
125
+ const bounds = configBounds(configKey);
126
+ if (bounds !== undefined && (numeric < bounds.min || numeric > bounds.max)) {
127
+ deps.io.err(`${key} must be between ${bounds.min} and ${bounds.max}.`);
128
+ return EXIT.usage;
129
+ }
130
+ value = numeric;
131
+ }
132
+ if (BOOLEAN_CONFIG_KEYS.includes(configKey)) {
133
+ if (rawValue !== 'true' && rawValue !== 'false') {
134
+ deps.io.err(`${key} is a toggle — pass "true" or "false", not "${rawValue}".`);
135
+ return EXIT.usage;
136
+ }
137
+ value = rawValue === 'true';
138
+ }
139
+ // Enum keys were accepted unchecked, so `config set sound whatever` wrote a
140
+ // value the sender would later reject — a typo that only surfaces at the
141
+ // moment a notification fails to carry the sound you asked for.
142
+ if (info.kind === 'enum' && info.choices !== undefined && !info.choices.includes(rawValue)) {
143
+ deps.io.err(`${key} takes one of: ${info.choices.join(', ')} — not "${rawValue}".`);
144
+ return EXIT.usage;
145
+ }
146
+ if (key === 'devices')
147
+ value = rawValue.split(',').map((s) => s.trim()).filter(Boolean);
148
+ const target = await configMutationTarget(deps, flags);
149
+ if (target === null)
150
+ return EXIT.usage;
151
+ if (target.layer === 'global' && Object.is(value, configDefaultValue(configKey))) {
152
+ deps.io.err(`${key} is already the shipped default (${JSON.stringify(value)}).`);
153
+ deps.io.err(`Run \`notifai config unset ${key} --yes\` to remove a redundant override instead of creating one.`);
154
+ return EXIT.usage;
155
+ }
156
+ if (!flags.yes) {
157
+ const confirmed = await deps.io.confirm(`Set ${key} = ${JSON.stringify(value)} in ${target.path}?`);
158
+ if (!confirmed) {
159
+ deps.io.err('Not confirmed. Pass --yes to skip the confirmation gate.');
160
+ return EXIT.usage;
161
+ }
162
+ }
163
+ const existing = existsSync(target.path)
164
+ ? parseToml(readFileSync(target.path, 'utf8'))
165
+ : {};
166
+ existing[key] = value;
167
+ mkdirSync(path.dirname(target.path), { recursive: true });
168
+ writeFileSync(target.path, `${stringifyToml(existing)}\n`);
169
+ deps.io.out(`Wrote ${key} to ${target.path}`);
170
+ return EXIT.ok;
171
+ }
172
+ function configMutationKey(deps, key) {
173
+ if (!CONFIG_KEYS.includes(key)) {
174
+ deps.io.err(`Unknown setting "${key}".`);
175
+ const near = nearestKey(key);
176
+ if (near !== null)
177
+ deps.io.err(`Did you mean "${near}"?`);
178
+ deps.io.err(`Valid settings: ${CONFIG_KEYS.join(', ')}`);
179
+ deps.io.err('Run `notifai config explain <key>` to see what one of them does.');
180
+ return null;
181
+ }
182
+ return key;
183
+ }
184
+ async function configMutationTarget(deps, flags) {
185
+ let layer = flags.local ? 'local' : flags.project ? 'project' : 'global';
186
+ if (flags.session === undefined &&
187
+ flags.local !== true &&
188
+ flags.project !== true &&
189
+ flags.yes !== true &&
190
+ deps.io.interactive === true &&
191
+ deps.io.select) {
192
+ const selected = await deps.io.select('Where should this setting live?', [
193
+ { value: 'global', label: 'This machine', hint: 'applies across projects' },
194
+ { value: 'project', label: 'This project (shared)', hint: '.notifai/config.toml' },
195
+ { value: 'local', label: 'This project (personal)', hint: 'stored on this machine, not in the repo' },
196
+ ]);
197
+ if (selected === null) {
198
+ deps.io.err('No configuration layer selected.');
199
+ return null;
200
+ }
201
+ layer = selected;
202
+ }
203
+ const targetPath = flags.session
204
+ ? sessionConfigPath(flags.session, deps.env)
205
+ : layer === 'local'
206
+ ? personalProjectConfigPath(deps.cwd, deps.env)
207
+ : layer === 'project'
208
+ ? (findProjectConfigPath(deps.cwd) ?? path.join(deps.cwd, '.notifai', 'config.toml'))
209
+ : globalConfigPath(deps.env);
210
+ return {
211
+ path: targetPath,
212
+ layer: flags.session ? 'session' : layer,
213
+ };
214
+ }
215
+ export async function configUnsetCommand(deps, key, flags) {
216
+ const configKey = configMutationKey(deps, key);
217
+ if (configKey === null)
218
+ return EXIT.usage;
219
+ const target = await configMutationTarget(deps, flags);
220
+ if (target === null)
221
+ return EXIT.usage;
222
+ const existing = existsSync(target.path)
223
+ ? parseToml(readFileSync(target.path, 'utf8'))
224
+ : {};
225
+ if (!Object.prototype.hasOwnProperty.call(existing, configKey)) {
226
+ deps.io.out(`${configKey} is not set in ${target.path}`);
227
+ return EXIT.ok;
228
+ }
229
+ if (!flags.yes) {
230
+ const confirmed = await deps.io.confirm(`Remove ${configKey} from ${target.path}?`);
231
+ if (!confirmed) {
232
+ deps.io.err('Not confirmed. Pass --yes to skip the confirmation gate.');
233
+ return EXIT.usage;
234
+ }
235
+ }
236
+ delete existing[configKey];
237
+ if (Object.keys(existing).length === 0) {
238
+ rmSync(target.path, { force: true });
239
+ }
240
+ else {
241
+ writeFileSync(target.path, `${stringifyToml(existing)}\n`);
242
+ }
243
+ deps.io.out(`Removed ${configKey} from ${target.path}; the inherited value now applies.`);
244
+ return EXIT.ok;
245
+ }
246
+ //# sourceMappingURL=commands-config.js.map