@raidiant/notifai 10.0.0 → 10.1.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/CHANGELOG.md +31 -0
- package/README.md +4 -1
- package/dist/cli-bin.d.ts +21 -1
- package/dist/cli-bin.js +141 -10
- package/dist/cli-bin.js.map +1 -1
- package/dist/cli-update-contract.d.ts +7 -0
- package/dist/cli-update-contract.js +10 -0
- package/dist/cli-update-contract.js.map +1 -0
- package/dist/client.d.ts +6 -1
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/codex-wake.d.ts +2 -0
- package/dist/codex-wake.js +2 -1
- package/dist/codex-wake.js.map +1 -1
- package/dist/commands-auth.d.ts +15 -1
- package/dist/commands-auth.js +32 -14
- package/dist/commands-auth.js.map +1 -1
- package/dist/commands-core.d.ts +10 -1
- package/dist/commands-core.js +13 -4
- package/dist/commands-core.js.map +1 -1
- package/dist/commands-devices.d.ts +10 -1
- package/dist/commands-devices.js +17 -13
- package/dist/commands-devices.js.map +1 -1
- package/dist/commands-doctor.js +158 -71
- package/dist/commands-doctor.js.map +1 -1
- package/dist/commands-harness-context.js +8 -0
- package/dist/commands-harness-context.js.map +1 -1
- package/dist/commands-hooks.js +169 -15
- package/dist/commands-hooks.js.map +1 -1
- package/dist/commands-init.d.ts +16 -0
- package/dist/commands-init.js +254 -91
- package/dist/commands-init.js.map +1 -1
- package/dist/commands-send.d.ts +1 -1
- package/dist/commands-send.js +121 -35
- package/dist/commands-send.js.map +1 -1
- package/dist/commands-update.d.ts +10 -0
- package/dist/commands-update.js +141 -0
- package/dist/commands-update.js.map +1 -0
- package/dist/commands.d.ts +2 -1
- package/dist/commands.js +2 -1
- package/dist/commands.js.map +1 -1
- package/dist/harnesses.d.ts +2 -2
- package/dist/harnesses.js +22 -2
- package/dist/harnesses.js.map +1 -1
- package/dist/hook-adapter.d.ts +2 -0
- package/dist/hook-adapter.js +12 -1
- package/dist/hook-adapter.js.map +1 -1
- package/dist/hooks.d.ts +43 -2
- package/dist/hooks.js +163 -21
- package/dist/hooks.js.map +1 -1
- package/dist/install-hooks.js +15 -9
- package/dist/install-hooks.js.map +1 -1
- package/dist/interactive.js +20 -23
- package/dist/interactive.js.map +1 -1
- package/dist/main-run.d.ts +1 -0
- package/dist/main-run.js +42 -0
- package/dist/main-run.js.map +1 -0
- package/dist/main.js +10 -31
- package/dist/main.js.map +1 -1
- package/dist/node-floor.d.ts +18 -0
- package/dist/node-floor.js +35 -0
- package/dist/node-floor.js.map +1 -0
- package/dist/openclaw-plugin.d.ts +49 -0
- package/dist/openclaw-plugin.js +350 -0
- package/dist/openclaw-plugin.js.map +1 -0
- package/dist/program.d.ts +2 -1
- package/dist/program.js +31 -13
- package/dist/program.js.map +1 -1
- package/dist/question-settlement-process.d.ts +15 -0
- package/dist/question-settlement-process.js +35 -0
- package/dist/question-settlement-process.js.map +1 -0
- package/dist/readiness.d.ts +25 -1
- package/dist/readiness.js +32 -2
- package/dist/readiness.js.map +1 -1
- package/dist/session-activation.js +1 -1
- package/dist/session-activation.js.map +1 -1
- package/dist/setup-destinations.d.ts +23 -0
- package/dist/setup-destinations.js +44 -0
- package/dist/setup-destinations.js.map +1 -0
- package/dist/ui/help.d.ts +4 -5
- package/dist/ui/help.js +5 -6
- package/dist/ui/help.js.map +1 -1
- package/package.json +2 -2
- package/src/cli-bin.test.ts +145 -7
- package/src/cli-bin.ts +176 -10
- package/src/cli-update-contract.ts +9 -0
- package/src/cli-update.test.ts +125 -0
- package/src/client.ts +7 -0
- package/src/codex-wake.ts +5 -1
- package/src/commands-auth.ts +47 -13
- package/src/commands-core.ts +21 -4
- package/src/commands-devices.ts +23 -16
- package/src/commands-doctor.ts +197 -75
- package/src/commands-harness-context.ts +8 -0
- package/src/commands-hooks.ts +210 -18
- package/src/commands-init.ts +275 -92
- package/src/commands-send.ts +145 -39
- package/src/commands-update.ts +180 -0
- package/src/commands.test.ts +701 -53
- package/src/commands.ts +2 -0
- package/src/fixtures/openclaw-2026.7.1-2-agent-local.json +57 -0
- package/src/harness-integration.test.ts +82 -0
- package/src/harnesses.test.ts +9 -1
- package/src/harnesses.ts +24 -2
- package/src/hook-adapter.ts +14 -0
- package/src/hooks.test.ts +275 -0
- package/src/hooks.ts +270 -18
- package/src/install-hooks.test.ts +208 -0
- package/src/install-hooks.ts +19 -9
- package/src/interactive.test.ts +31 -0
- package/src/interactive.ts +20 -26
- package/src/main-run.ts +45 -0
- package/src/main.ts +9 -33
- package/src/node-floor.test.ts +27 -0
- package/src/node-floor.ts +37 -0
- package/src/openclaw-plugin.ts +409 -0
- package/src/program.test.ts +35 -0
- package/src/program.ts +37 -12
- package/src/question-settlement-process.ts +47 -0
- package/src/readiness.ts +35 -2
- package/src/session-activation.ts +1 -1
- package/src/setup-destinations.test.ts +41 -0
- package/src/setup-destinations.ts +50 -0
- package/src/skill.test.ts +13 -2
- package/src/ui/help.test.ts +16 -0
- package/src/ui/help.ts +6 -7
- package/src/commands-devices.test.ts +0 -15
package/dist/commands-core.js
CHANGED
|
@@ -6,6 +6,7 @@ import { loadConfig } from './config.js';
|
|
|
6
6
|
import {} from './hook-adapter.js';
|
|
7
7
|
import { logConfigResolved, logSettingsFrom, nullLogger } from './logging.js';
|
|
8
8
|
import { packageVersion } from './release.js';
|
|
9
|
+
import { cliUpdateRecoveryCommand } from './cli-update-contract.js';
|
|
9
10
|
/** The invocation's logger, or one that discards everything. */
|
|
10
11
|
export function log(deps) {
|
|
11
12
|
return deps.logger ?? nullLogger();
|
|
@@ -75,7 +76,15 @@ export function authedClient(deps, config) {
|
|
|
75
76
|
baseUrl,
|
|
76
77
|
};
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Resolve a current CLI independently of PATH. A bare `notifai update` would
|
|
81
|
+
* be captured by the stale winner this action is meant to repair.
|
|
82
|
+
*/
|
|
83
|
+
export function updateCliCommand(_deps) {
|
|
84
|
+
return cliUpdateRecoveryCommand();
|
|
85
|
+
}
|
|
86
|
+
/** The one first-run command an unsigned machine is told to run. */
|
|
87
|
+
export const SETUP_COMMAND = 'notifai init';
|
|
79
88
|
function affectedDeviceNames(details) {
|
|
80
89
|
if (typeof details !== 'object' || details === null || !('device_names' in details))
|
|
81
90
|
return [];
|
|
@@ -91,10 +100,10 @@ function naturalList(values) {
|
|
|
91
100
|
return `${values[0]} and ${values[1]}`;
|
|
92
101
|
return `${values.slice(0, -1).join(', ')}, and ${values.at(-1)}`;
|
|
93
102
|
}
|
|
94
|
-
function localRecovery(action, details) {
|
|
103
|
+
function localRecovery(deps, action, details) {
|
|
95
104
|
switch (action) {
|
|
96
105
|
case 'update_cli':
|
|
97
|
-
return `next: ${
|
|
106
|
+
return `next: ${updateCliCommand(deps)}`;
|
|
98
107
|
case 'update_companion': {
|
|
99
108
|
const names = affectedDeviceNames(details);
|
|
100
109
|
return names.length > 0
|
|
@@ -149,7 +158,7 @@ export function reportError(deps, err, context = {}) {
|
|
|
149
158
|
}
|
|
150
159
|
const recovery = err.code === 'no_active_devices'
|
|
151
160
|
? 'next: Run `notifai init` to connect an active Companion App; it will complete machine setup and identify any human-only device step.'
|
|
152
|
-
: localRecovery(err.recoveryAction, err.details);
|
|
161
|
+
: localRecovery(deps, err.recoveryAction, err.details);
|
|
153
162
|
if (recovery !== null)
|
|
154
163
|
deps.io.err(recovery);
|
|
155
164
|
else if (err.recoveryAction === null && err.nextAction)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-core.js","sourceRoot":"","sources":["../src/commands-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAuB,MAAM,4BAA4B,CAAA;AAC1F,OAAO,EAA2B,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,GAGb,MAAM,aAAa,CAAA;AACpB,OAAO,EAA0B,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,UAAU,EAAkB,MAAM,aAAa,CAAA;AAExD,OAAO,EAA0B,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,UAAU,EAAe,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"commands-core.js","sourceRoot":"","sources":["../src/commands-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Platform, type RoutableDevice } from '@raidiant/notifai-protocol';
|
|
2
2
|
import { type CommandDeps } from './commands-core.js';
|
|
3
|
+
import { type CompanionPlatform } from './setup-destinations.js';
|
|
3
4
|
export declare function devicesCommand(deps: CommandDeps, flags: {
|
|
4
5
|
json?: boolean;
|
|
5
6
|
platform?: string;
|
|
@@ -20,13 +21,21 @@ export declare function capabilitiesCommand(deps: CommandDeps, flags: {
|
|
|
20
21
|
json?: boolean;
|
|
21
22
|
platform?: Platform;
|
|
22
23
|
}): Promise<number>;
|
|
23
|
-
export declare function supportPageUrl(baseUrl: string): string;
|
|
24
24
|
/** Same-account line for the device hop; prefers the real email when known. */
|
|
25
25
|
export declare function sameAccountSignInLine(email: string | null | undefined): string;
|
|
26
|
+
/**
|
|
27
|
+
* What is actually left to do on the phone.
|
|
28
|
+
*
|
|
29
|
+
* Three sub-states, three remedies. "Install the app" is useless advice to
|
|
30
|
+
* someone who installed it and then declined the permission prompt, and
|
|
31
|
+
* offering install steps to a registered device says this terminal did not
|
|
32
|
+
* read the state it just fetched.
|
|
33
|
+
*/
|
|
26
34
|
export declare function deviceInstallRemedy(options: {
|
|
27
35
|
baseUrl: string;
|
|
28
36
|
email: string | null;
|
|
29
37
|
devices: readonly RoutableDevice[];
|
|
38
|
+
platform?: CompanionPlatform;
|
|
30
39
|
}): string;
|
|
31
40
|
export declare function deviceCanReceive(device: RoutableDevice): boolean;
|
|
32
41
|
export declare function readyCompanionDevices(devices: readonly RoutableDevice[]): RoutableDevice[];
|
package/dist/commands-devices.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PLATFORMS } from '@raidiant/notifai-protocol';
|
|
2
2
|
import { EXIT, authedClient, loadLoggedConfig, makeClient, reportError, resolvedBaseUrl, } from './commands-core.js';
|
|
3
|
+
import { companionPlatformLabel, setupCompanionUrl, } from './setup-destinations.js';
|
|
3
4
|
// ---------------------------------------------------------------------------
|
|
4
5
|
// devices / capabilities
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
@@ -27,15 +28,15 @@ export async function devicesCommand(deps, flags) {
|
|
|
27
28
|
deps.io.out(`No ${platform} devices registered.`);
|
|
28
29
|
return EXIT.ok;
|
|
29
30
|
}
|
|
30
|
-
const
|
|
31
|
+
const setupUrl = setupCompanionUrl(authed.baseUrl);
|
|
31
32
|
let email = null;
|
|
32
33
|
try {
|
|
33
34
|
email = (await authed.client.accessStatus()).email;
|
|
34
35
|
}
|
|
35
36
|
catch {
|
|
36
|
-
// Best-effort: the empty-state copy still
|
|
37
|
+
// Best-effort: the empty-state copy still names the destination.
|
|
37
38
|
}
|
|
38
|
-
deps.io.out(`No devices yet.
|
|
39
|
+
deps.io.out(`No devices yet. Set up a Companion App at ${setupUrl}, ${sameAccountSignInLine(email)}, and allow notifications.`);
|
|
39
40
|
return EXIT.ok;
|
|
40
41
|
}
|
|
41
42
|
for (const d of devices) {
|
|
@@ -102,25 +103,28 @@ export async function capabilitiesCommand(deps, flags) {
|
|
|
102
103
|
return reportError(deps, err);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
export function supportPageUrl(baseUrl) {
|
|
106
|
-
const normalized = baseUrl.replace(/\/+$/, '');
|
|
107
|
-
if (normalized === 'https://api.notifai.sh' || normalized === 'https://notifai.fly.dev') {
|
|
108
|
-
return 'https://app.notifai.sh/support';
|
|
109
|
-
}
|
|
110
|
-
return `${normalized}/support`;
|
|
111
|
-
}
|
|
112
106
|
/** Same-account line for the device hop; prefers the real email when known. */
|
|
113
107
|
export function sameAccountSignInLine(email) {
|
|
114
108
|
return email
|
|
115
109
|
? `sign in with the same email as this account (${email})`
|
|
116
110
|
: 'sign in with the same email as this account';
|
|
117
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* What is actually left to do on the phone.
|
|
114
|
+
*
|
|
115
|
+
* Three sub-states, three remedies. "Install the app" is useless advice to
|
|
116
|
+
* someone who installed it and then declined the permission prompt, and
|
|
117
|
+
* offering install steps to a registered device says this terminal did not
|
|
118
|
+
* read the state it just fetched.
|
|
119
|
+
*/
|
|
118
120
|
export function deviceInstallRemedy(options) {
|
|
119
|
-
const support = supportPageUrl(options.baseUrl);
|
|
120
121
|
const sameEmail = sameAccountSignInLine(options.email);
|
|
121
122
|
if (options.devices.length === 0) {
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
const destination = setupCompanionUrl(options.baseUrl, options.platform);
|
|
124
|
+
const named = options.platform === undefined
|
|
125
|
+
? 'the Companion App'
|
|
126
|
+
: `Notifai on ${companionPlatformLabel(options.platform)}`;
|
|
127
|
+
return `open the steps for ${named} at ${destination}, install it, ${sameEmail}, and allow notifications`;
|
|
124
128
|
}
|
|
125
129
|
if (options.devices.some((d) => d.permission_status === 'denied')) {
|
|
126
130
|
return "allow notifications for Notifai in the device's Settings";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands-devices.js","sourceRoot":"","sources":["../src/commands-devices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAsC,MAAM,4BAA4B,CAAA;AAC1F,OAAO,EACL,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,eAAe,GAEhB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"commands-devices.js","sourceRoot":"","sources":["../src/commands-devices.ts"],"names":[],"mappings":"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"}
|
package/dist/commands-doctor.js
CHANGED
|
@@ -6,18 +6,19 @@ import { ApiCallError } from './client.js';
|
|
|
6
6
|
import { inspectCodexResume } from './codex-wake.js';
|
|
7
7
|
import {} from './config.js';
|
|
8
8
|
import { HARNESS_CAPABILITIES, HARNESS_LABELS, HERMES_QUESTION_ROUTING_UNAVAILABLE, isHookInstallableHarness, } from './harnesses.js';
|
|
9
|
-
import { inspectHookAdapter } from './hook-adapter.js';
|
|
9
|
+
import { hookAdapterTargetsArtifact, inspectHookAdapter, isNpxAdapterTarget, } from './hook-adapter.js';
|
|
10
10
|
import { readLiveProjectSessionPointers, readProjectSessionPointer, readSessionState, } from './hooks.js';
|
|
11
11
|
import { NON_ROUTING_BLOCKING_STOP_TIMEOUT_SECONDS, QUESTION_STOP_TIMEOUT_SECONDS, codexCoexistenceNotes, codexHomeNote, codexLayerDir, codexLayerPaths, codexProjectRoot, codexRepresentationProblems, codexTrustProblems, detectedHarnesses, findInstallations, handlerEvent, inspectCodexLayer, } from './install-hooks.js';
|
|
12
12
|
import { inferInvocationContext } from './invocation-context.js';
|
|
13
13
|
import { firstBlocker, readinessJson, } from './readiness.js';
|
|
14
14
|
import { packageVersion } from './release.js';
|
|
15
|
-
import { EXIT,
|
|
16
|
-
import { deviceInstallRemedy, readyCompanionDevices
|
|
15
|
+
import { EXIT, SETUP_COMMAND, diagnoseIgnoredOriginOverride, loadLoggedConfig, makeClient, resolvedBaseUrl, updateCliCommand, } from './commands-core.js';
|
|
16
|
+
import { deviceInstallRemedy, readyCompanionDevices } from './commands-devices.js';
|
|
17
|
+
import { setupAccessUrl } from './setup-destinations.js';
|
|
17
18
|
import { claudeSessionPid, resolveActiveHarness, } from './commands-harness-context.js';
|
|
18
19
|
import { stopShapeProblems } from './commands-hook-shape.js';
|
|
19
20
|
import { HOOK_EVENTS, activeQuestionRouteProblems, hookActivationAdvice, requiredHookEvents, } from './commands-hooks.js';
|
|
20
|
-
import { cliBinReadiness } from './cli-bin.js';
|
|
21
|
+
import { cliBinReadiness, inspectCliInstallations } from './cli-bin.js';
|
|
21
22
|
import { latestPublishedCliVersion, newerPublishedCli, shouldConsultCliRegistry, thisCliVersion, } from './cli-release.js';
|
|
22
23
|
import { SETUP_PROOF_STALE_MS, observedCompanionReceipt, readSetupProof, setupProofProject, setupProofIsStale, setupProofApplies, } from './commands-setup-proof.js';
|
|
23
24
|
import { skillReadiness } from './commands-skill.js';
|
|
@@ -30,7 +31,7 @@ import { projectBinding, projectEnabled } from './project-enablement.js';
|
|
|
30
31
|
* versions and document integers are structured inventory, never routing or a
|
|
31
32
|
* definition of "up to date".
|
|
32
33
|
*/
|
|
33
|
-
async function compatibilityCheck(client) {
|
|
34
|
+
async function compatibilityCheck(client, deps) {
|
|
34
35
|
try {
|
|
35
36
|
const [compatibility, documents] = await Promise.all([
|
|
36
37
|
client.compatibility(),
|
|
@@ -63,7 +64,7 @@ async function compatibilityCheck(client) {
|
|
|
63
64
|
remedy: {
|
|
64
65
|
by: 'user-here',
|
|
65
66
|
summary: 'update Notifai',
|
|
66
|
-
command:
|
|
67
|
+
command: updateCliCommand(deps),
|
|
67
68
|
},
|
|
68
69
|
};
|
|
69
70
|
}
|
|
@@ -80,7 +81,7 @@ async function compatibilityCheck(client) {
|
|
|
80
81
|
remedy: {
|
|
81
82
|
by: 'user-here',
|
|
82
83
|
summary: 'update Notifai',
|
|
83
|
-
command:
|
|
84
|
+
command: updateCliCommand(deps),
|
|
84
85
|
},
|
|
85
86
|
};
|
|
86
87
|
}
|
|
@@ -219,6 +220,91 @@ function remoteInvalidatedByConfig(previous, config, credential) {
|
|
|
219
220
|
const server = previous.states.find((state) => state.id === 'server');
|
|
220
221
|
return server === undefined || !server.detail.includes(origin);
|
|
221
222
|
}
|
|
223
|
+
function isNoActivePlanError(err) {
|
|
224
|
+
return err instanceof ApiCallError && err.code === 'no_active_plan';
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Device listing is grant-gated; access status is not. A paired Account whose
|
|
228
|
+
* plan lapsed must not be diagnosed as a revoked machine.
|
|
229
|
+
*/
|
|
230
|
+
async function probeAccount(client, credential, baseUrl) {
|
|
231
|
+
const [devicesOutcome, accessOutcome, requestOutcome] = await Promise.allSettled([
|
|
232
|
+
Promise.resolve().then(() => client.listDevices()),
|
|
233
|
+
Promise.resolve().then(() => client.accessStatus()),
|
|
234
|
+
Promise.resolve().then(() => client.accessRequest()),
|
|
235
|
+
]);
|
|
236
|
+
const access = accessOutcome.status === 'fulfilled' ? accessOutcome.value : null;
|
|
237
|
+
const pendingRequest = requestOutcome.status === 'fulfilled' ? requestOutcome.value.request : null;
|
|
238
|
+
const devices = devicesOutcome.status === 'fulfilled' ? devicesOutcome.value.devices : null;
|
|
239
|
+
const email = access?.email ?? null;
|
|
240
|
+
const devicesErr = devicesOutcome.status === 'rejected' ? devicesOutcome.reason : null;
|
|
241
|
+
const noActivePlan = access?.status === 'no_active_plan' || isNoActivePlanError(devicesErr);
|
|
242
|
+
if (noActivePlan) {
|
|
243
|
+
const next = (isNoActivePlanError(devicesErr) ? devicesErr.nextAction : null) ??
|
|
244
|
+
`Open ${setupAccessUrl(baseUrl)} to set up access, then retry.`;
|
|
245
|
+
const who = email ? ` (${email})` : '';
|
|
246
|
+
// Three values, not two. Someone who asked yesterday is waiting on a person,
|
|
247
|
+
// not on an action of theirs, and telling them to ask again — every run,
|
|
248
|
+
// forever — is the only thing this terminal could get wrong about a wait it
|
|
249
|
+
// cannot shorten.
|
|
250
|
+
return {
|
|
251
|
+
email,
|
|
252
|
+
devices: null,
|
|
253
|
+
lookupFailed: true,
|
|
254
|
+
auth: pendingRequest === null
|
|
255
|
+
? {
|
|
256
|
+
id: 'auth',
|
|
257
|
+
title: 'Account',
|
|
258
|
+
status: 'gap',
|
|
259
|
+
detail: `this account does not have access to Notifai yet${who}`,
|
|
260
|
+
remedy: { by: 'user-elsewhere', summary: next },
|
|
261
|
+
}
|
|
262
|
+
: {
|
|
263
|
+
id: 'auth',
|
|
264
|
+
title: 'Account',
|
|
265
|
+
status: 'gap',
|
|
266
|
+
detail: `access requested on ${pendingRequest.requested_at.slice(0, 10)}${who} — waiting to be granted`,
|
|
267
|
+
remedy: {
|
|
268
|
+
by: 'user-elsewhere',
|
|
269
|
+
summary: 'nothing is needed from you; this resumes on the next run once access is granted',
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
if (devices !== null) {
|
|
275
|
+
return {
|
|
276
|
+
email,
|
|
277
|
+
devices,
|
|
278
|
+
lookupFailed: false,
|
|
279
|
+
auth: {
|
|
280
|
+
id: 'auth',
|
|
281
|
+
title: 'Account',
|
|
282
|
+
status: 'ready',
|
|
283
|
+
detail: email
|
|
284
|
+
? `machine ${credential.machineId} accepted (${email})`
|
|
285
|
+
: `machine ${credential.machineId} accepted`,
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
const err = devicesErr ?? (accessOutcome.status === 'rejected' ? accessOutcome.reason : null);
|
|
290
|
+
return {
|
|
291
|
+
email: null,
|
|
292
|
+
devices: null,
|
|
293
|
+
lookupFailed: true,
|
|
294
|
+
auth: {
|
|
295
|
+
id: 'auth',
|
|
296
|
+
title: 'Account',
|
|
297
|
+
status: 'gap',
|
|
298
|
+
detail: err instanceof ApiCallError ? `${err.code}: ${err.message}` : String(err),
|
|
299
|
+
remedy: {
|
|
300
|
+
by: 'user-here',
|
|
301
|
+
summary: 'this machine is no longer recognised; pair it again',
|
|
302
|
+
command: SETUP_COMMAND,
|
|
303
|
+
interactive: true,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
}
|
|
222
308
|
/**
|
|
223
309
|
* Read the whole setup once, in dependency order.
|
|
224
310
|
*
|
|
@@ -282,7 +368,7 @@ export async function assessReadiness(deps, options = {}) {
|
|
|
282
368
|
remedy: {
|
|
283
369
|
by: 'user-here',
|
|
284
370
|
summary: 'sign in — this opens your browser to approve the machine',
|
|
285
|
-
command:
|
|
371
|
+
command: SETUP_COMMAND,
|
|
286
372
|
interactive: true,
|
|
287
373
|
},
|
|
288
374
|
});
|
|
@@ -323,7 +409,7 @@ export async function assessReadiness(deps, options = {}) {
|
|
|
323
409
|
}
|
|
324
410
|
else {
|
|
325
411
|
const compatibilityClient = makeClient(deps, baseUrl, `Bearer nfm_${credential.machineId}.${credential.secret}`);
|
|
326
|
-
states.push(await compatibilityCheck(compatibilityClient));
|
|
412
|
+
states.push(await compatibilityCheck(compatibilityClient, deps));
|
|
327
413
|
}
|
|
328
414
|
let accountEmail = null;
|
|
329
415
|
let accountLookupFailed = false;
|
|
@@ -334,40 +420,11 @@ export async function assessReadiness(deps, options = {}) {
|
|
|
334
420
|
else {
|
|
335
421
|
const client = makeClient(deps, baseUrl, `Bearer nfm_${credential.machineId}.${credential.secret}`);
|
|
336
422
|
accountClient = client;
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
.catch(() => null),
|
|
343
|
-
]);
|
|
344
|
-
accountDevices = devices;
|
|
345
|
-
accountEmail = email;
|
|
346
|
-
states.push({
|
|
347
|
-
id: 'auth',
|
|
348
|
-
title: 'Account',
|
|
349
|
-
status: 'ready',
|
|
350
|
-
detail: accountEmail
|
|
351
|
-
? `machine ${credential.machineId} accepted (${accountEmail})`
|
|
352
|
-
: `machine ${credential.machineId} accepted`,
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
catch (err) {
|
|
356
|
-
// A credential the server rejects is revocation, not absence, and the
|
|
357
|
-
// remedy is the same sign-in either way.
|
|
358
|
-
accountLookupFailed = true;
|
|
359
|
-
states.push({
|
|
360
|
-
id: 'auth',
|
|
361
|
-
title: 'Account',
|
|
362
|
-
status: 'gap',
|
|
363
|
-
detail: err instanceof ApiCallError ? `${err.code}: ${err.message}` : String(err),
|
|
364
|
-
remedy: {
|
|
365
|
-
by: 'user-here',
|
|
366
|
-
summary: 'this machine is no longer recognised; pair it again',
|
|
367
|
-
command: 'notifai login',
|
|
368
|
-
},
|
|
369
|
-
});
|
|
370
|
-
}
|
|
423
|
+
const probed = await probeAccount(client, credential, baseUrl);
|
|
424
|
+
accountDevices = probed.devices;
|
|
425
|
+
accountEmail = probed.email;
|
|
426
|
+
accountLookupFailed = probed.lookupFailed;
|
|
427
|
+
states.push(probed.auth);
|
|
371
428
|
}
|
|
372
429
|
// Optional setup that works without a companion device must appear before the
|
|
373
430
|
// device gap: init stops at the first user-elsewhere blocker, and hooks/skill
|
|
@@ -403,7 +460,7 @@ export async function assessReadiness(deps, options = {}) {
|
|
|
403
460
|
// permission prompt. The live bridge is /support on the
|
|
404
461
|
// dashboard origin — not a placeholder, and not typed by hand.
|
|
405
462
|
detail: companionDevices.length === 0
|
|
406
|
-
?
|
|
463
|
+
? 'no active Companion App registered yet'
|
|
407
464
|
: `${companionDevices.map((d) => `${d.display_name} (${d.platform}, ${d.permission_status})`).join(', ')} — registered but not able to receive`,
|
|
408
465
|
remedy: {
|
|
409
466
|
by: 'user-elsewhere',
|
|
@@ -439,7 +496,7 @@ async function applyRegistryRecommendation(deps, json, states) {
|
|
|
439
496
|
contract.remedy = {
|
|
440
497
|
by: 'user-here',
|
|
441
498
|
summary: 'update Notifai',
|
|
442
|
-
command:
|
|
499
|
+
command: updateCliCommand(deps),
|
|
443
500
|
};
|
|
444
501
|
}
|
|
445
502
|
async function setupProofState(deps, config, client, devices) {
|
|
@@ -547,8 +604,10 @@ export async function doctorCommand(deps, flags, options = {}) {
|
|
|
547
604
|
if (s.status === 'ready' || s.status === 'unknown')
|
|
548
605
|
continue;
|
|
549
606
|
deps.io.out(s.detail);
|
|
550
|
-
if (s.remedy?.by !== 'user-elsewhere' &&
|
|
551
|
-
|
|
607
|
+
if (s.remedy?.by !== 'user-elsewhere' &&
|
|
608
|
+
s.remedy?.summary === 'update Notifai' &&
|
|
609
|
+
s.remedy.command !== undefined) {
|
|
610
|
+
deps.io.out(s.remedy.command);
|
|
552
611
|
}
|
|
553
612
|
continue;
|
|
554
613
|
}
|
|
@@ -615,14 +674,15 @@ export function remedyLine(state) {
|
|
|
615
674
|
* way and is not worth re-deriving. The judgment added here is which failures
|
|
616
675
|
* actually stand in the way.
|
|
617
676
|
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
*
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
677
|
+
* `doctor` is a report and keeps its strict verdict here: a Codex Stop handler
|
|
678
|
+
* that would swallow an answer is a real failure and reads as one. `init` is
|
|
679
|
+
* the other consumer, and it treats every state in this group as a report line
|
|
680
|
+
* rather than a blocker — Question Routing is optional automation, and nothing
|
|
681
|
+
* optional may stand between a send-capable setup and its delivery proof.
|
|
682
|
+
*
|
|
683
|
+
* `reportOnly` marks the checks that no command can close, only the passage of
|
|
684
|
+
* a turn. Those are report lines even in `doctor`, because "look again" is not
|
|
685
|
+
* a remedy.
|
|
626
686
|
*/
|
|
627
687
|
function hookStates(deps) {
|
|
628
688
|
const installations = findInstallations(deps.cwd, deps.env, deps.hookAdapterHome, deps.hookPlatform);
|
|
@@ -715,23 +775,21 @@ function hookStates(deps) {
|
|
|
715
775
|
function checkTitle(name) {
|
|
716
776
|
return CHECK_TITLES[name] ?? name;
|
|
717
777
|
}
|
|
718
|
-
/** Real but not in the way; see the note above. */
|
|
719
|
-
const informational = new Set();
|
|
720
778
|
return [
|
|
721
779
|
...hookChecks(deps).map((check) => ({
|
|
722
780
|
id: check.name.replace(/[ ()]+/g, '-').replace(/-$/, ''),
|
|
723
781
|
title: checkTitle(check.name),
|
|
724
782
|
status: check.ok
|
|
725
783
|
? 'ready'
|
|
726
|
-
: check.
|
|
784
|
+
: check.reportOnly === true
|
|
727
785
|
? 'optional-gap'
|
|
728
786
|
: 'gap',
|
|
729
787
|
detail: check.detail,
|
|
788
|
+
...(check.technical === undefined ? {} : { technical: check.technical }),
|
|
730
789
|
...(check.ok
|
|
731
790
|
? {}
|
|
732
791
|
: {
|
|
733
792
|
remedy: {
|
|
734
|
-
by: 'user-here',
|
|
735
793
|
// The check's own remedy when it has one; the generic reinstall
|
|
736
794
|
// line was wrong exactly where it mattered (an unfired pointer
|
|
737
795
|
// needs a prompt, not `hooks install`).
|
|
@@ -739,6 +797,7 @@ function hookStates(deps) {
|
|
|
739
797
|
summary: 'the detail above names what to change',
|
|
740
798
|
command: 'notifai hooks install',
|
|
741
799
|
}),
|
|
800
|
+
by: check.remedy?.by ?? 'user-here',
|
|
742
801
|
},
|
|
743
802
|
}),
|
|
744
803
|
})),
|
|
@@ -771,7 +830,7 @@ function hookChecks(deps) {
|
|
|
771
830
|
checks.push({
|
|
772
831
|
name: 'hooks (detected)',
|
|
773
832
|
ok: false,
|
|
774
|
-
|
|
833
|
+
reportOnly: true,
|
|
775
834
|
detail: `${unwired.map((harness) => HARNESS_LABELS[harness]).join(', ')} detected on this machine but not wired`,
|
|
776
835
|
remedy: {
|
|
777
836
|
summary: 'install hooks for every detected harness',
|
|
@@ -787,7 +846,7 @@ function hookChecks(deps) {
|
|
|
787
846
|
checks.push({
|
|
788
847
|
name: 'hooks (active harness)',
|
|
789
848
|
ok: false,
|
|
790
|
-
|
|
849
|
+
reportOnly: true,
|
|
791
850
|
detail: `Several harness sessions could own this shell (${contested.map((candidate) => candidate.label).join(', ')}); routing readiness is intentionally not attributed to either one`,
|
|
792
851
|
});
|
|
793
852
|
}
|
|
@@ -795,7 +854,7 @@ function hookChecks(deps) {
|
|
|
795
854
|
checks.push({
|
|
796
855
|
name: 'hooks (active harness)',
|
|
797
856
|
ok: true,
|
|
798
|
-
|
|
857
|
+
reportOnly: true,
|
|
799
858
|
detail: `${active.label}: ${HERMES_QUESTION_ROUTING_UNAVAILABLE.deliveryContract}`,
|
|
800
859
|
});
|
|
801
860
|
}
|
|
@@ -828,7 +887,7 @@ function hookChecks(deps) {
|
|
|
828
887
|
checks.push({
|
|
829
888
|
name: 'hooks (active session)',
|
|
830
889
|
ok: false,
|
|
831
|
-
|
|
890
|
+
reportOnly: true,
|
|
832
891
|
detail: `active ${active.label} session has not published exact lifecycle state — send one ${active.label} prompt, then check again`,
|
|
833
892
|
remedy: {
|
|
834
893
|
summary: `send one ${active.label} prompt — its hook publishes the routing pointer`,
|
|
@@ -873,14 +932,41 @@ function hookChecks(deps) {
|
|
|
873
932
|
const adapterProblems = installations.flatMap((installation) => (installation.problems ?? []).map((problem) => `${installation.file}: ${problem}`));
|
|
874
933
|
const sharedAdapter = inspectHookAdapter(deps.hookAdapterHome, deps.hookPlatform);
|
|
875
934
|
adapterProblems.push(...sharedAdapter.problems);
|
|
935
|
+
const runningTarget = deps.hookInstallTarget;
|
|
936
|
+
const runningArtifact = runningTarget !== undefined && !isNpxAdapterTarget(runningTarget)
|
|
937
|
+
? runningTarget.scriptPath
|
|
938
|
+
: process.argv[1];
|
|
939
|
+
const cliInstallations = inspectCliInstallations(deps.env, deps.hookPlatform ?? process.platform, {
|
|
940
|
+
...(runningArtifact === undefined ? {} : { runningArtifactPath: runningArtifact }),
|
|
941
|
+
currentVersion: packageVersion(),
|
|
942
|
+
});
|
|
943
|
+
const effectiveArtifact = cliInstallations.effective?.artifact_path ?? null;
|
|
944
|
+
const adapterMismatch = sharedAdapter.problems.length === 0 &&
|
|
945
|
+
effectiveArtifact !== null &&
|
|
946
|
+
!hookAdapterTargetsArtifact(sharedAdapter.target, effectiveArtifact);
|
|
947
|
+
if (adapterMismatch) {
|
|
948
|
+
adapterProblems.push('the registered CLI does not match the effective notifai command');
|
|
949
|
+
}
|
|
876
950
|
if (adapterProblems.length > 0) {
|
|
877
951
|
checks.push({
|
|
878
952
|
name: 'hooks (adapter)',
|
|
879
953
|
ok: false,
|
|
880
954
|
// A machine-global install for a harness that is not active in this
|
|
881
|
-
// project is useful diagnosis, but it
|
|
882
|
-
|
|
955
|
+
// project is useful diagnosis, but it is not this project's failure.
|
|
956
|
+
reportOnly: active === null && installations.every((installation) => installation.global),
|
|
883
957
|
detail: adapterProblems.join('; '),
|
|
958
|
+
...(adapterMismatch
|
|
959
|
+
? { technical: { effective_cli_artifact: effectiveArtifact, registered_target: sharedAdapter.target } }
|
|
960
|
+
: {}),
|
|
961
|
+
...(adapterMismatch && adapterProblems.length === 1
|
|
962
|
+
? {
|
|
963
|
+
remedy: {
|
|
964
|
+
by: 'cli',
|
|
965
|
+
summary: 'retarget Question Routing to the effective notifai command',
|
|
966
|
+
command: 'notifai init',
|
|
967
|
+
},
|
|
968
|
+
}
|
|
969
|
+
: {}),
|
|
884
970
|
});
|
|
885
971
|
}
|
|
886
972
|
const trustProblems = codexTrustProblems(installations, deps.env);
|
|
@@ -1004,9 +1090,10 @@ function hookChecks(deps) {
|
|
|
1004
1090
|
checks.push({
|
|
1005
1091
|
name: 'hooks (fired)',
|
|
1006
1092
|
ok: fired,
|
|
1007
|
-
//
|
|
1008
|
-
//
|
|
1009
|
-
|
|
1093
|
+
// Nothing here is a command. Whether the pointer is absent or the turn is
|
|
1094
|
+
// half-finished, the only thing that closes this is a turn ending — which
|
|
1095
|
+
// an agent running `init` inside that very turn cannot supply.
|
|
1096
|
+
reportOnly: true,
|
|
1010
1097
|
detail: fired
|
|
1011
1098
|
? active === null
|
|
1012
1099
|
? 'a session in this directory has run UserPromptSubmit and Stop'
|
|
@@ -1039,7 +1126,7 @@ function hookChecks(deps) {
|
|
|
1039
1126
|
name: 'hooks (answer continuation)',
|
|
1040
1127
|
ok: continuationHarnesses.length > 0 &&
|
|
1041
1128
|
continuationHarnesses.every((harness) => HARNESS_CAPABILITIES[harness].stopContinuation !== 'unsupported'),
|
|
1042
|
-
|
|
1129
|
+
reportOnly: active === null,
|
|
1043
1130
|
detail: continuationHarnesses.length === 0
|
|
1044
1131
|
? active === null
|
|
1045
1132
|
? 'no installed harness route to assess'
|
|
@@ -1089,7 +1176,7 @@ function wakeRouteCheck(deps, active, activeInstallations) {
|
|
|
1089
1176
|
return {
|
|
1090
1177
|
name: 'hooks (wake route)',
|
|
1091
1178
|
ok: readiness.state === 'ready',
|
|
1092
|
-
|
|
1179
|
+
reportOnly: true,
|
|
1093
1180
|
detail: readiness.state === 'ready'
|
|
1094
1181
|
? `this Claude Code ${readiness.version} session is listening on ${readiness.socketPath}, so an answer can start a turn here without you`
|
|
1095
1182
|
: `${readiness.reason}. Answers are still delivered, at this session's next turn rather than on their own`,
|
|
@@ -1103,7 +1190,7 @@ function wakeRouteCheck(deps, active, activeInstallations) {
|
|
|
1103
1190
|
return {
|
|
1104
1191
|
name: 'hooks (wake route)',
|
|
1105
1192
|
ok: readiness.state === 'ready',
|
|
1106
|
-
|
|
1193
|
+
reportOnly: true,
|
|
1107
1194
|
detail: readiness.state === 'ready'
|
|
1108
1195
|
? `the held Codex turn continues from its own hook, and after it returns ${readiness.lockDirectory} can prove a stopped thread unowned before resuming it`
|
|
1109
1196
|
: `the held Codex turn still continues from its own hook, but after it returns nothing can be resumed: ${readiness.reason}. Answers wait for the next turn`,
|