@raidiant/notifai 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +17 -7
- package/dist/commands.d.ts +2 -0
- package/dist/commands.js +31 -39
- package/dist/commands.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +5 -9
- package/dist/config.js.map +1 -1
- package/dist/credentials.d.ts +54 -3
- package/dist/credentials.js +237 -18
- package/dist/credentials.js.map +1 -1
- package/dist/file-lock.js +15 -6
- package/dist/file-lock.js.map +1 -1
- package/dist/hook-adapter.d.ts +6 -2
- package/dist/hook-adapter.js +110 -29
- package/dist/hook-adapter.js.map +1 -1
- package/dist/hooks.js +2 -1
- package/dist/hooks.js.map +1 -1
- package/dist/install-hooks.d.ts +50 -21
- package/dist/install-hooks.js +141 -57
- package/dist/install-hooks.js.map +1 -1
- package/dist/native-skills.js +5 -10
- package/dist/native-skills.js.map +1 -1
- package/dist/opencode-plugin.d.ts +7 -2
- package/dist/opencode-plugin.js +142 -4
- package/dist/opencode-plugin.js.map +1 -1
- package/dist/platform.d.ts +73 -0
- package/dist/platform.js +143 -0
- package/dist/platform.js.map +1 -0
- package/dist/ui/config-view.js +5 -1
- package/dist/ui/config-view.js.map +1 -1
- package/package.json +3 -3
- package/src/commands.test.ts +100 -26
- package/src/commands.ts +49 -36
- package/src/config.ts +11 -9
- package/src/credentials.test.ts +291 -0
- package/src/credentials.ts +274 -17
- package/src/file-lock.ts +34 -9
- package/src/hook-adapter.test.ts +136 -0
- package/src/hook-adapter.ts +120 -28
- package/src/hooks.test.ts +27 -1
- package/src/hooks.ts +2 -1
- package/src/install-hooks.test.ts +174 -33
- package/src/install-hooks.ts +186 -54
- package/src/native-skills.ts +5 -10
- package/src/opencode-plugin.ts +148 -3
- package/src/platform.test.ts +152 -0
- package/src/platform.ts +173 -0
- package/src/ui/config-view.ts +5 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/config-view.js
CHANGED
|
@@ -47,7 +47,11 @@ export function renderConfigList(config, options = {}) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
lines.push('');
|
|
50
|
-
|
|
50
|
+
const command = 'notifai config explain <key>';
|
|
51
|
+
const help = `${glyph.arrow} ${command} for what one of these means and how to change it.`;
|
|
52
|
+
for (const line of wrap(help, columns)) {
|
|
53
|
+
lines.push(style.dim(line.replace(command, style.code(command))));
|
|
54
|
+
}
|
|
51
55
|
return lines;
|
|
52
56
|
}
|
|
53
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-view.js","sourceRoot":"","sources":["../../src/ui/config-view.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config-view.js","sourceRoot":"","sources":["../../src/ui/config-view.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raidiant/notifai",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Send native phone notifications from agents and local programs",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@clack/prompts": "^1.7.0",
|
|
17
|
-
"@raidiant/notifai-protocol": "0.
|
|
17
|
+
"@raidiant/notifai-protocol": "0.4.0",
|
|
18
18
|
"commander": "^14.0.0",
|
|
19
19
|
"picocolors": "^1.1.1",
|
|
20
20
|
"smol-toml": "^1.4.0"
|
|
@@ -54,6 +54,6 @@
|
|
|
54
54
|
"build": "node ../../scripts/clean-dist.mjs && tsc -p tsconfig.json",
|
|
55
55
|
"pretest": "pnpm run build",
|
|
56
56
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
57
|
-
"test": "
|
|
57
|
+
"test": "node ../../scripts/run-cli-tests.mjs"
|
|
58
58
|
}
|
|
59
59
|
}
|
package/src/commands.test.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
mkdtempSync,
|
|
5
|
+
readFileSync,
|
|
6
|
+
readdirSync,
|
|
7
|
+
rmSync,
|
|
8
|
+
symlinkSync,
|
|
9
|
+
writeFileSync,
|
|
10
|
+
} from 'node:fs'
|
|
2
11
|
import os from 'node:os'
|
|
3
12
|
import path from 'node:path'
|
|
4
13
|
import { fileURLToPath } from 'node:url'
|
|
@@ -10,7 +19,7 @@ import type {
|
|
|
10
19
|
SubmissionReceipt,
|
|
11
20
|
SubmitNotificationRequestT,
|
|
12
21
|
} from '@raidiant/notifai-protocol'
|
|
13
|
-
import { describe, expect, it } from 'vitest'
|
|
22
|
+
import { afterEach, describe, expect, it } from 'vitest'
|
|
14
23
|
import { ApiCallError, NetworkError, type ApiClient } from './client.js'
|
|
15
24
|
import type { ClaudeWakeAdapters } from './claude-wake.js'
|
|
16
25
|
import {
|
|
@@ -51,7 +60,7 @@ import {
|
|
|
51
60
|
} from './install-hooks.js'
|
|
52
61
|
import { readSessionState, writeProjectSession, writeSessionState } from './hooks.js'
|
|
53
62
|
import { nativeSkills as realNativeSkills, type NativeSkill, type NativeSkills, type SkillScope } from './native-skills.js'
|
|
54
|
-
import { CONFIG_KEYS, loadConfig, personalProjectConfigPath } from './config.js'
|
|
63
|
+
import { CONFIG_KEYS, loadConfig, personalProjectConfigPath, stateDir } from './config.js'
|
|
55
64
|
import { createLogger, logsDiskUsage, readLogRecords } from './logging.js'
|
|
56
65
|
import { hookAdapterPath, inspectHookAdapter } from './hook-adapter.js'
|
|
57
66
|
import type { Tone } from './ui/theme.js'
|
|
@@ -161,6 +170,29 @@ class InteractiveIo extends CapturedIo {
|
|
|
161
170
|
}
|
|
162
171
|
|
|
163
172
|
function trustInstalledCodexHooks(cwd: string, env: NodeJS.ProcessEnv): void {
|
|
173
|
+
const home = env['HOME']
|
|
174
|
+
if (home === undefined || home === '') {
|
|
175
|
+
throw new Error(
|
|
176
|
+
'trustInstalledCodexHooks requires env.HOME; refusing to use the real home directory',
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
const resolvedHome = path.resolve(home)
|
|
180
|
+
const tmpRoot = path.resolve(os.tmpdir())
|
|
181
|
+
const underTmp = resolvedHome === tmpRoot || resolvedHome.startsWith(`${tmpRoot}${path.sep}`)
|
|
182
|
+
if (!underTmp) {
|
|
183
|
+
throw new Error(
|
|
184
|
+
`trustInstalledCodexHooks will only write under ${tmpRoot}, not ${resolvedHome}`,
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
const codexHome = env['CODEX_HOME'] !== undefined && env['CODEX_HOME'] !== ''
|
|
188
|
+
? path.resolve(env['CODEX_HOME'])
|
|
189
|
+
: path.join(resolvedHome, '.codex')
|
|
190
|
+
if (codexHome !== tmpRoot && !codexHome.startsWith(`${tmpRoot}${path.sep}`)) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
`trustInstalledCodexHooks will only write under ${tmpRoot}, not ${codexHome}`,
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
const file = path.join(codexHome, 'config.toml')
|
|
164
196
|
const installations = findInstallations(cwd, env).filter(
|
|
165
197
|
(installation) => installation.harness === 'codex',
|
|
166
198
|
)
|
|
@@ -170,9 +202,7 @@ function trustInstalledCodexHooks(cwd: string, env: NodeJS.ProcessEnv): void {
|
|
|
170
202
|
return `[hooks.state.${JSON.stringify(key)}]\ntrusted_hash = ${JSON.stringify(codexHookIdentityHash(handler))}\n`
|
|
171
203
|
}),
|
|
172
204
|
)
|
|
173
|
-
|
|
174
|
-
mkdirSync(codexHome, { recursive: true })
|
|
175
|
-
const file = path.join(codexHome, 'config.toml')
|
|
205
|
+
mkdirSync(path.dirname(file), { recursive: true })
|
|
176
206
|
// Trust lives in the same config.toml as inline [hooks]. Overwriting the
|
|
177
207
|
// file would delete the global handlers this helper is trying to trust.
|
|
178
208
|
const existing = existsSync(file) ? readFileSync(file, 'utf8').trimEnd() : ''
|
|
@@ -219,6 +249,7 @@ function isolatedEnv(cwd: string): NodeJS.ProcessEnv {
|
|
|
219
249
|
HOME: home,
|
|
220
250
|
CLAUDE_CONFIG_DIR: path.join(home, '.claude'),
|
|
221
251
|
CODEX_HOME: path.join(home, '.codex'),
|
|
252
|
+
OPENCODE_CONFIG_DIR: path.join(home, '.config', 'opencode'),
|
|
222
253
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
223
254
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
224
255
|
}
|
|
@@ -1225,6 +1256,7 @@ describe('Cursor hook commands', () => {
|
|
|
1225
1256
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
1226
1257
|
CODEX_HOME: path.join(cwd, 'codex'),
|
|
1227
1258
|
CLAUDE_CONFIG_DIR: path.join(cwd, 'claude'),
|
|
1259
|
+
OPENCODE_CONFIG_DIR: path.join(cwd, 'opencode'),
|
|
1228
1260
|
},
|
|
1229
1261
|
store: { load: () => null, save: () => {}, clear: () => {}, describe: () => 'empty store' },
|
|
1230
1262
|
}
|
|
@@ -1303,7 +1335,7 @@ describe('Codex hook representation', () => {
|
|
|
1303
1335
|
expect(io.outLines.join('\n')).toMatch(/Stop and the existing one will both fire/i)
|
|
1304
1336
|
})
|
|
1305
1337
|
|
|
1306
|
-
it('
|
|
1338
|
+
it('preserves a foreign inline Stop while collapsing our duplicate definition', async () => {
|
|
1307
1339
|
const cwd = mkdtempSync(path.join(os.tmpdir(), 'notifai-codex-collapse-'))
|
|
1308
1340
|
const toml = writeInlineStop(cwd, 'gdh-stop')
|
|
1309
1341
|
const json = path.join(cwd, '.codex', 'hooks.json')
|
|
@@ -1485,7 +1517,11 @@ describe('harness activation guidance', () => {
|
|
|
1485
1517
|
const deps = {
|
|
1486
1518
|
...makeDeps(io, {} as ApiClient),
|
|
1487
1519
|
cwd,
|
|
1488
|
-
env: {
|
|
1520
|
+
env: {
|
|
1521
|
+
HOME: path.join(cwd, 'home'),
|
|
1522
|
+
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
1523
|
+
OPENCODE_CONFIG_DIR: path.join(cwd, 'opencode-home'),
|
|
1524
|
+
},
|
|
1489
1525
|
}
|
|
1490
1526
|
|
|
1491
1527
|
expect(hooksInstallCommand(deps, { harness: 'opencode', execPath, scriptPath })).toBe(
|
|
@@ -2120,6 +2156,7 @@ describe('init', () => {
|
|
|
2120
2156
|
platform: 'ios' as const,
|
|
2121
2157
|
permission_status: 'authorized',
|
|
2122
2158
|
registration_healthy: true,
|
|
2159
|
+
reply_protocol_version: 1,
|
|
2123
2160
|
last_seen_at: '2026-08-05T18:00:00.000Z',
|
|
2124
2161
|
}
|
|
2125
2162
|
|
|
@@ -2492,8 +2529,8 @@ describe('init', () => {
|
|
|
2492
2529
|
)
|
|
2493
2530
|
expect(wired).toEqual(['claude-code', 'codex'])
|
|
2494
2531
|
expect(existsSync(path.join(cwd, '.claude', 'settings.local.json'))).toBe(true)
|
|
2495
|
-
expect(existsSync(path.join(cwd, '.codex', '
|
|
2496
|
-
expect(existsSync(path.join(cwd, '.codex', '
|
|
2532
|
+
expect(existsSync(path.join(cwd, '.codex', 'hooks.json'))).toBe(true)
|
|
2533
|
+
expect(existsSync(path.join(cwd, '.codex', 'config.toml'))).toBe(false)
|
|
2497
2534
|
expect(io.outLines.join('\n')).toContain('Installed claude-code hooks')
|
|
2498
2535
|
expect(io.outLines.join('\n')).toContain('Installed codex hooks')
|
|
2499
2536
|
})
|
|
@@ -2664,6 +2701,7 @@ describe('init', () => {
|
|
|
2664
2701
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
2665
2702
|
CODEX_HOME: path.join(cwd, 'codex'),
|
|
2666
2703
|
CLAUDE_CONFIG_DIR: path.join(cwd, 'claude'),
|
|
2704
|
+
OPENCODE_CONFIG_DIR: path.join(cwd, 'opencode'),
|
|
2667
2705
|
},
|
|
2668
2706
|
}
|
|
2669
2707
|
|
|
@@ -2753,6 +2791,9 @@ describe('init', () => {
|
|
|
2753
2791
|
expect(io.notes.some((n) => n.message.includes('I will wait up to 10 minutes'))).toBe(true)
|
|
2754
2792
|
expect(io.spinnerEvents).toContain('stop:iPhone is ready to receive')
|
|
2755
2793
|
expect(io.spinnerEvents).toContain('stop:Receipt observed from iPhone')
|
|
2794
|
+
expect(io.outLines.join('\n')).toContain(
|
|
2795
|
+
"Companion Receipt (the app's delivery confirmation) observed from iPhone.",
|
|
2796
|
+
)
|
|
2756
2797
|
expect(io.outLines.join('\n')).toContain('All set.')
|
|
2757
2798
|
expect(submitCalls).toBe(1)
|
|
2758
2799
|
expect(submittedDraft?.draft.event).toBe('setup_verified')
|
|
@@ -2895,6 +2936,8 @@ describe('init', () => {
|
|
|
2895
2936
|
expect(io.outLines.join('\n')).toContain('Next: Delivery proof')
|
|
2896
2937
|
expect(io.outLines.join('\n')).toContain('Provider accepted the notification')
|
|
2897
2938
|
expect(io.outLines.join('\n')).toContain('Proof may still arrive')
|
|
2939
|
+
const proofDir = path.join(stateDir(deps.env), 'setup-proofs')
|
|
2940
|
+
expect(readdirSync(proofDir).some((name) => name.endsWith('.json'))).toBe(true)
|
|
2898
2941
|
|
|
2899
2942
|
io.outLines = []
|
|
2900
2943
|
io.errLines = []
|
|
@@ -3304,6 +3347,27 @@ describe('an outage is not an answer', () => {
|
|
|
3304
3347
|
describe('asking before the hooks have ever run', () => {
|
|
3305
3348
|
const execPath = process.execPath
|
|
3306
3349
|
const scriptPath = fileURLToPath(import.meta.url)
|
|
3350
|
+
const scratch: string[] = []
|
|
3351
|
+
|
|
3352
|
+
function scratchDir(prefix: string): string {
|
|
3353
|
+
const dir = mkdtempSync(path.join(os.tmpdir(), prefix))
|
|
3354
|
+
scratch.push(dir)
|
|
3355
|
+
return dir
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
afterEach(() => {
|
|
3359
|
+
while (scratch.length > 0) {
|
|
3360
|
+
rmSync(scratch.pop()!, { recursive: true, force: true })
|
|
3361
|
+
}
|
|
3362
|
+
})
|
|
3363
|
+
|
|
3364
|
+
it('refuses to write Codex trust outside the isolated test account', () => {
|
|
3365
|
+
expect(() => trustInstalledCodexHooks(os.tmpdir(), {})).toThrow(/requires env.HOME/)
|
|
3366
|
+
expect(() => trustInstalledCodexHooks(os.tmpdir(), { HOME: path.dirname(os.tmpdir()) })).toThrow(
|
|
3367
|
+
/will only write under/,
|
|
3368
|
+
)
|
|
3369
|
+
expect(os.homedir()).toBe(process.env['NOTIFAI_TEST_HOME'])
|
|
3370
|
+
})
|
|
3307
3371
|
|
|
3308
3372
|
it('names the active Codex harness instead of unrelated installed adapters', () => {
|
|
3309
3373
|
const cwd = mkdtempSync(path.join(os.tmpdir(), 'notifai-active-codex-missing-'))
|
|
@@ -3311,6 +3375,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3311
3375
|
const env = {
|
|
3312
3376
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3313
3377
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3378
|
+
HOME: path.join(cwd, 'home'),
|
|
3314
3379
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3315
3380
|
CODEX_THREAD_ID: 'codex-current-thread',
|
|
3316
3381
|
CLAUDE_CONFIG_DIR: path.join(cwd, 'claude-home'),
|
|
@@ -3335,6 +3400,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3335
3400
|
const env = {
|
|
3336
3401
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3337
3402
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3403
|
+
HOME: path.join(cwd, 'home'),
|
|
3338
3404
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3339
3405
|
CODEX_THREAD_ID: 'codex-current-thread',
|
|
3340
3406
|
}
|
|
@@ -3353,11 +3419,12 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3353
3419
|
})
|
|
3354
3420
|
|
|
3355
3421
|
it('registers only when the active Codex thread owns the project pointer', () => {
|
|
3356
|
-
const cwd =
|
|
3422
|
+
const cwd = scratchDir('notifai-active-codex-matching-')
|
|
3357
3423
|
const io = new CapturedIo()
|
|
3358
3424
|
const env = {
|
|
3359
3425
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3360
3426
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3427
|
+
HOME: path.join(cwd, 'home'),
|
|
3361
3428
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3362
3429
|
CODEX_THREAD_ID: 'codex-current-thread',
|
|
3363
3430
|
}
|
|
@@ -3497,11 +3564,12 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3497
3564
|
})
|
|
3498
3565
|
|
|
3499
3566
|
it('makes one work-resumption commitment per offered answer part of the asking turn', () => {
|
|
3500
|
-
const cwd =
|
|
3567
|
+
const cwd = scratchDir('notifai-ask-commitment-')
|
|
3501
3568
|
const io = new CapturedIo()
|
|
3502
3569
|
const env = {
|
|
3503
3570
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3504
3571
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3572
|
+
HOME: path.join(cwd, 'home'),
|
|
3505
3573
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3506
3574
|
CODEX_THREAD_ID: 'codex-commitment-thread',
|
|
3507
3575
|
}
|
|
@@ -3532,11 +3600,12 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3532
3600
|
})
|
|
3533
3601
|
|
|
3534
3602
|
it('requires a concrete fallback for free-text answers before the turn ends', () => {
|
|
3535
|
-
const cwd =
|
|
3603
|
+
const cwd = scratchDir('notifai-ask-free-text-')
|
|
3536
3604
|
const io = new CapturedIo()
|
|
3537
3605
|
const env = {
|
|
3538
3606
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3539
3607
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3608
|
+
HOME: path.join(cwd, 'home'),
|
|
3540
3609
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3541
3610
|
CODEX_THREAD_ID: 'codex-free-text-thread',
|
|
3542
3611
|
}
|
|
@@ -3555,11 +3624,12 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3555
3624
|
})
|
|
3556
3625
|
|
|
3557
3626
|
it('refuses a Codex question when the installed Stop definition is no longer trusted', async () => {
|
|
3558
|
-
const cwd =
|
|
3627
|
+
const cwd = scratchDir('notifai-codex-stale-trust-')
|
|
3559
3628
|
const io = new CapturedIo()
|
|
3560
3629
|
const env = {
|
|
3561
3630
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3562
3631
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3632
|
+
HOME: path.join(cwd, 'home'),
|
|
3563
3633
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3564
3634
|
CODEX_THREAD_ID: 'codex-current-thread',
|
|
3565
3635
|
}
|
|
@@ -3570,7 +3640,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3570
3640
|
.find((installation) => installation.harness === 'codex')
|
|
3571
3641
|
?.handlers.find((handler) => handler.event === 'Stop')
|
|
3572
3642
|
expect(stop).toBeDefined()
|
|
3573
|
-
const configFile = path.join(env.CODEX_HOME
|
|
3643
|
+
const configFile = path.join(env.CODEX_HOME!, 'config.toml')
|
|
3574
3644
|
writeFileSync(
|
|
3575
3645
|
configFile,
|
|
3576
3646
|
readFileSync(configFile, 'utf8').replace(codexHookIdentityHash(stop!), 'sha256:obsolete'),
|
|
@@ -3594,6 +3664,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3594
3664
|
const env = {
|
|
3595
3665
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3596
3666
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3667
|
+
HOME: path.join(cwd, 'home'),
|
|
3597
3668
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3598
3669
|
CODEX_THREAD_ID: 'codex-current-thread',
|
|
3599
3670
|
CLAUDE_CONFIG_DIR: path.join(cwd, 'claude-home'),
|
|
@@ -3702,7 +3773,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3702
3773
|
})
|
|
3703
3774
|
|
|
3704
3775
|
it('rejects duplicate active Codex definitions before registration', () => {
|
|
3705
|
-
const cwd =
|
|
3776
|
+
const cwd = scratchDir('notifai-active-codex-duplicate-')
|
|
3706
3777
|
const io = new CapturedIo()
|
|
3707
3778
|
const env = {
|
|
3708
3779
|
HOME: path.join(cwd, 'home'),
|
|
@@ -3713,7 +3784,8 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3713
3784
|
}
|
|
3714
3785
|
const deps = { ...makeDeps(io, {} as ApiClient), cwd, env, now: () => 42 }
|
|
3715
3786
|
expect(hooksInstallCommand(deps, { harness: 'codex', execPath, scriptPath })).toBe(EXIT.ok)
|
|
3716
|
-
|
|
3787
|
+
mkdirSync(env.CODEX_HOME!, { recursive: true })
|
|
3788
|
+
applyPlan(path.join(env.CODEX_HOME!, 'config.toml'), {
|
|
3717
3789
|
hooks: buildHookConfig({
|
|
3718
3790
|
adapterPath: hookAdapterPath(deps.hookAdapterHome),
|
|
3719
3791
|
harness: 'codex',
|
|
@@ -3822,6 +3894,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3822
3894
|
const env = {
|
|
3823
3895
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3824
3896
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3897
|
+
HOME: path.join(cwd, 'home'),
|
|
3825
3898
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3826
3899
|
CLAUDE_CONFIG_DIR: path.join(cwd, 'claude-home'),
|
|
3827
3900
|
CLAUDECODE: '1',
|
|
@@ -3844,6 +3917,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
3844
3917
|
XDG_CONFIG_HOME: path.join(cwd, 'config'),
|
|
3845
3918
|
XDG_STATE_HOME: path.join(cwd, 'state'),
|
|
3846
3919
|
CLAUDE_CONFIG_DIR: path.join(cwd, 'claude-home'),
|
|
3920
|
+
HOME: path.join(cwd, 'home'),
|
|
3847
3921
|
CODEX_HOME: path.join(cwd, 'codex-home'),
|
|
3848
3922
|
CLAUDECODE: '1',
|
|
3849
3923
|
CLAUDE_CODE_SESSION_ID: 'claude-current',
|
|
@@ -4026,7 +4100,12 @@ describe('asking before the hooks have ever run', () => {
|
|
|
4026
4100
|
...isolatedEnv(cwd),
|
|
4027
4101
|
CODEX_THREAD_ID: '9f1c2b3a-4d5e-6f70-8192-a3b4c5d6e7f8',
|
|
4028
4102
|
}
|
|
4029
|
-
const deps = {
|
|
4103
|
+
const deps = {
|
|
4104
|
+
...makeDeps(io, {} as ApiClient),
|
|
4105
|
+
cwd,
|
|
4106
|
+
env,
|
|
4107
|
+
hookPlatform: 'darwin' as NodeJS.Platform,
|
|
4108
|
+
}
|
|
4030
4109
|
expect(hooksInstallCommand(deps, { harness: 'codex', execPath, scriptPath })).toBe(EXIT.ok)
|
|
4031
4110
|
|
|
4032
4111
|
io.outLines = []
|
|
@@ -4037,14 +4116,8 @@ describe('asking before the hooks have ever run', () => {
|
|
|
4037
4116
|
io.outLines = []
|
|
4038
4117
|
await doctorCommand(deps, {})
|
|
4039
4118
|
const out = io.outLines.join('\n')
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
expect(out).toContain('can prove a stopped thread unowned before resuming it')
|
|
4043
|
-
} else {
|
|
4044
|
-
// Linux has no non-blocking `flock` through Node's `open(2)` flags, so
|
|
4045
|
-
// the gate stays shut and doctor says so rather than implying a wake.
|
|
4046
|
-
expect(out).toContain('nothing can be resumed')
|
|
4047
|
-
}
|
|
4119
|
+
expect(out).toMatch(/ok\s+hooks \(wake route\)/)
|
|
4120
|
+
expect(out).toContain('can prove a stopped thread unowned before resuming it')
|
|
4048
4121
|
})
|
|
4049
4122
|
|
|
4050
4123
|
it('documents the failing exit contract in doctor JSON', async () => {
|
|
@@ -4123,6 +4196,7 @@ describe('asking before the hooks have ever run', () => {
|
|
|
4123
4196
|
XDG_STATE_HOME: cwd,
|
|
4124
4197
|
CODEX_HOME: path.join(cwd, 'none'),
|
|
4125
4198
|
CLAUDE_CONFIG_DIR: path.join(cwd, 'none'),
|
|
4199
|
+
OPENCODE_CONFIG_DIR: path.join(cwd, 'none'),
|
|
4126
4200
|
},
|
|
4127
4201
|
}
|
|
4128
4202
|
|