@raidiant/notifai 9.2.2 → 10.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.
- package/CHANGELOG.md +45 -0
- package/README.md +8 -5
- package/dist/claude-wake.js +11 -0
- package/dist/claude-wake.js.map +1 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -1
- package/dist/codex-wake.js +9 -0
- package/dist/codex-wake.js.map +1 -1
- package/dist/commands-agent-sessions.d.ts +6 -0
- package/dist/commands-agent-sessions.js +51 -0
- package/dist/commands-agent-sessions.js.map +1 -0
- package/dist/commands-config.js +11 -4
- package/dist/commands-config.js.map +1 -1
- package/dist/commands-core.d.ts +1 -1
- package/dist/commands-doctor.js +83 -6
- package/dist/commands-doctor.js.map +1 -1
- package/dist/commands-harness-context.d.ts +15 -2
- package/dist/commands-harness-context.js +32 -1
- package/dist/commands-harness-context.js.map +1 -1
- package/dist/commands-hook-shape.d.ts +4 -3
- package/dist/commands-hook-shape.js +19 -10
- package/dist/commands-hook-shape.js.map +1 -1
- package/dist/commands-hooks.d.ts +4 -3
- package/dist/commands-hooks.js +80 -23
- package/dist/commands-hooks.js.map +1 -1
- package/dist/commands-init.js +12 -1
- package/dist/commands-init.js.map +1 -1
- package/dist/commands-project.d.ts +4 -0
- package/dist/commands-project.js +41 -0
- package/dist/commands-project.js.map +1 -0
- package/dist/commands-send-support.js +0 -4
- package/dist/commands-send-support.js.map +1 -1
- package/dist/commands-send.js +12 -6
- package/dist/commands-send.js.map +1 -1
- package/dist/commands-skill.js +58 -0
- package/dist/commands-skill.js.map +1 -1
- package/dist/commands-sounds.d.ts +12 -0
- package/dist/commands-sounds.js +35 -0
- package/dist/commands-sounds.js.map +1 -0
- package/dist/commands.d.ts +3 -0
- package/dist/commands.js +3 -0
- package/dist/commands.js.map +1 -1
- package/dist/config-schema.js +7 -4
- package/dist/config-schema.js.map +1 -1
- package/dist/config.d.ts +6 -7
- package/dist/config.js +9 -9
- package/dist/config.js.map +1 -1
- package/dist/credentials.js +4 -1
- package/dist/credentials.js.map +1 -1
- package/dist/guidance-content.d.ts +3 -0
- package/dist/guidance-content.js +20 -0
- package/dist/guidance-content.js.map +1 -1
- package/dist/guidance-render.js +3 -3
- package/dist/guidance-render.js.map +1 -1
- package/dist/harnesses.d.ts +49 -7
- package/dist/harnesses.js +90 -24
- package/dist/harnesses.js.map +1 -1
- package/dist/hooks.d.ts +28 -52
- package/dist/hooks.js +393 -152
- package/dist/hooks.js.map +1 -1
- package/dist/install-hooks.d.ts +17 -39
- package/dist/install-hooks.js +21 -41
- package/dist/install-hooks.js.map +1 -1
- package/dist/invocation-context.d.ts +2 -2
- package/dist/orca-session-title.d.ts +2 -2
- package/dist/orca-session-title.js +3 -4
- package/dist/orca-session-title.js.map +1 -1
- package/dist/program.d.ts +6 -1
- package/dist/program.js +46 -5
- package/dist/program.js.map +1 -1
- package/dist/project-enablement.d.ts +15 -0
- package/dist/project-enablement.js +87 -0
- package/dist/project-enablement.js.map +1 -0
- package/dist/question-timing.d.ts +46 -0
- package/dist/question-timing.js +48 -0
- package/dist/question-timing.js.map +1 -0
- package/dist/readiness.d.ts +7 -0
- package/dist/readiness.js.map +1 -1
- package/dist/send.d.ts +2 -0
- package/dist/send.js +17 -15
- package/dist/send.js.map +1 -1
- package/dist/session-activation.d.ts +1 -1
- package/dist/session-activation.js +3 -4
- package/dist/session-activation.js.map +1 -1
- package/dist/session-labels.d.ts +18 -2
- package/dist/session-labels.js +79 -8
- package/dist/session-labels.js.map +1 -1
- package/dist/sound-ref.d.ts +23 -0
- package/dist/sound-ref.js +28 -0
- package/dist/sound-ref.js.map +1 -0
- package/package.json +3 -3
- package/src/claude-wake.test.ts +1 -0
- package/src/claude-wake.ts +10 -0
- package/src/client.test.ts +12 -0
- package/src/client.ts +8 -0
- package/src/codex-wake.test.ts +1 -0
- package/src/codex-wake.ts +9 -0
- package/src/commands-agent-sessions.ts +72 -0
- package/src/commands-config.ts +10 -4
- package/src/commands-core.ts +1 -1
- package/src/commands-doctor.ts +96 -8
- package/src/commands-harness-context.ts +48 -2
- package/src/commands-hook-shape.ts +26 -10
- package/src/commands-hooks.ts +95 -31
- package/src/commands-init.ts +11 -1
- package/src/commands-project.ts +47 -0
- package/src/commands-send-support.ts +0 -4
- package/src/commands-send.ts +10 -5
- package/src/commands-skill.test.ts +44 -0
- package/src/commands-skill.ts +57 -0
- package/src/commands-sounds.test.ts +106 -0
- package/src/commands-sounds.ts +49 -0
- package/src/commands.test.ts +386 -23
- package/src/commands.ts +10 -0
- package/src/config-schema.test.ts +1 -0
- package/src/config-schema.ts +7 -4
- package/src/config.test.ts +44 -23
- package/src/config.ts +13 -15
- package/src/credentials.test.ts +20 -0
- package/src/credentials.ts +4 -1
- package/src/fixtures/hermes-0.20.6-classic-cli-local.json +50 -0
- package/src/guidance-content.ts +22 -0
- package/src/guidance-render.ts +3 -3
- package/src/harness-integration.test.ts +212 -0
- package/src/harnesses.test.ts +107 -8
- package/src/harnesses.ts +111 -30
- package/src/hook-adapter.test.ts +27 -8
- package/src/hooks.test.ts +812 -83
- package/src/hooks.ts +529 -185
- package/src/install-hooks.test.ts +13 -16
- package/src/install-hooks.ts +40 -58
- package/src/invocation-context.ts +2 -2
- package/src/orca-session-title.test.ts +8 -49
- package/src/orca-session-title.ts +3 -5
- package/src/program.test.ts +45 -0
- package/src/program.ts +60 -4
- package/src/project-enablement.test.ts +55 -0
- package/src/project-enablement.ts +99 -0
- package/src/question-timing.ts +56 -0
- package/src/readiness.ts +8 -1
- package/src/send.ts +18 -20
- package/src/session-activation.ts +3 -4
- package/src/session-labels.test.ts +58 -9
- package/src/session-labels.ts +95 -12
- package/src/skill.test.ts +14 -3
- package/src/sound-ref.test.ts +31 -0
- package/src/sound-ref.ts +34 -0
- package/src/ui/config-view.test.ts +1 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import os from 'node:os'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import type { ApiClient } from './client.js'
|
|
5
|
+
import { EXIT, type CommandDeps, type CommandIo } from './commands-core.js'
|
|
6
|
+
import { soundsCommand } from './commands-sounds.js'
|
|
7
|
+
|
|
8
|
+
class CapturedIo implements CommandIo {
|
|
9
|
+
readonly outLines: string[] = []
|
|
10
|
+
readonly errLines: string[] = []
|
|
11
|
+
out(line: string): void {
|
|
12
|
+
this.outLines.push(line)
|
|
13
|
+
}
|
|
14
|
+
err(line: string): void {
|
|
15
|
+
this.errLines.push(line)
|
|
16
|
+
}
|
|
17
|
+
async confirm(): Promise<boolean> {
|
|
18
|
+
return true
|
|
19
|
+
}
|
|
20
|
+
openUrl(): void {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function makeDeps(io: CapturedIo, client: ApiClient): CommandDeps {
|
|
24
|
+
const testRoot = path.join(os.tmpdir(), 'notifai-cli-sounds-tests')
|
|
25
|
+
return {
|
|
26
|
+
io,
|
|
27
|
+
store: {
|
|
28
|
+
load: () => ({
|
|
29
|
+
machineId: 'mac_test',
|
|
30
|
+
secret: 'test-secret',
|
|
31
|
+
baseUrl: 'https://test.notifai.invalid',
|
|
32
|
+
machineName: 'test-machine',
|
|
33
|
+
}),
|
|
34
|
+
save: () => {},
|
|
35
|
+
clear: () => {},
|
|
36
|
+
describe: () => 'test credential store',
|
|
37
|
+
},
|
|
38
|
+
env: {
|
|
39
|
+
XDG_CONFIG_HOME: testRoot,
|
|
40
|
+
XDG_STATE_HOME: path.join(os.tmpdir(), 'notifai-cli-sounds-tests-state'),
|
|
41
|
+
},
|
|
42
|
+
cwd: os.tmpdir(),
|
|
43
|
+
clientFactory: () => client,
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const kitchenTimer = {
|
|
48
|
+
sound_id: 'snd_kitchen',
|
|
49
|
+
name: 'Kitchen timer',
|
|
50
|
+
duration_ms: 2400,
|
|
51
|
+
content_hash: 'a'.repeat(64),
|
|
52
|
+
url: 'https://wav.example/kitchen.wav',
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
describe('soundsCommand', () => {
|
|
56
|
+
it('lists shipped names and Account custom sounds', async () => {
|
|
57
|
+
const io = new CapturedIo()
|
|
58
|
+
const client = {
|
|
59
|
+
listSounds: async () => ({ sounds: [kitchenTimer] }),
|
|
60
|
+
} as unknown as ApiClient
|
|
61
|
+
|
|
62
|
+
expect(await soundsCommand(makeDeps(io, client), {})).toBe(EXIT.ok)
|
|
63
|
+
expect(io.outLines[0]).toBe('default Device default')
|
|
64
|
+
expect(io.outLines).toContain('done completion chime')
|
|
65
|
+
expect(io.outLines).toContain('none silent')
|
|
66
|
+
expect(io.outLines.at(-1)).toBe('snd_kitchen Kitchen timer 2.4s')
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('prints the catalog as JSON when asked', async () => {
|
|
70
|
+
const io = new CapturedIo()
|
|
71
|
+
const client = {
|
|
72
|
+
listSounds: async () => ({ sounds: [kitchenTimer] }),
|
|
73
|
+
} as unknown as ApiClient
|
|
74
|
+
|
|
75
|
+
expect(await soundsCommand(makeDeps(io, client), { json: true })).toBe(EXIT.ok)
|
|
76
|
+
const parsed = JSON.parse(io.outLines.join('\n')) as {
|
|
77
|
+
shipped: { ref: string; name: string }[]
|
|
78
|
+
custom: typeof kitchenTimer[]
|
|
79
|
+
}
|
|
80
|
+
expect(parsed.shipped[0]).toEqual({ ref: 'default', name: 'Device default' })
|
|
81
|
+
expect(parsed.custom).toEqual([kitchenTimer])
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('refuses to list custom sounds when this machine is not signed in', async () => {
|
|
85
|
+
const io = new CapturedIo()
|
|
86
|
+
let calls = 0
|
|
87
|
+
const deps: CommandDeps = {
|
|
88
|
+
...makeDeps(io, {
|
|
89
|
+
listSounds: async () => {
|
|
90
|
+
calls += 1
|
|
91
|
+
return { sounds: [] }
|
|
92
|
+
},
|
|
93
|
+
} as unknown as ApiClient),
|
|
94
|
+
store: {
|
|
95
|
+
load: () => null,
|
|
96
|
+
save: () => {},
|
|
97
|
+
clear: () => {},
|
|
98
|
+
describe: () => 'empty store',
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
expect(await soundsCommand(deps, {})).toBe(EXIT.auth)
|
|
103
|
+
expect(calls).toBe(0)
|
|
104
|
+
expect(io.errLines.join('\n')).toMatch(/not signed in/i)
|
|
105
|
+
})
|
|
106
|
+
})
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ListSoundsResponse, SoundView } from '@raidiant/notifai-protocol'
|
|
2
|
+
import {
|
|
3
|
+
EXIT,
|
|
4
|
+
authedClient,
|
|
5
|
+
loadLoggedConfig,
|
|
6
|
+
reportError,
|
|
7
|
+
type CommandDeps,
|
|
8
|
+
} from './commands-core.js'
|
|
9
|
+
import { SHIPPED_SOUND_LISTING } from './sound-ref.js'
|
|
10
|
+
|
|
11
|
+
export interface SoundsListing {
|
|
12
|
+
shipped: readonly { ref: string; name: string }[]
|
|
13
|
+
custom: SoundView[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function formatSoundDuration(ms: number): string {
|
|
17
|
+
const seconds = ms / 1000
|
|
18
|
+
const text = Number.isInteger(seconds) ? String(seconds) : seconds.toFixed(1)
|
|
19
|
+
return `${text}s`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function soundsCommand(
|
|
23
|
+
deps: CommandDeps,
|
|
24
|
+
flags: { json?: boolean },
|
|
25
|
+
): Promise<number> {
|
|
26
|
+
const config = loadLoggedConfig(deps, { cwd: deps.cwd, env: deps.env })
|
|
27
|
+
const authed = authedClient(deps, config)
|
|
28
|
+
if (!authed) return EXIT.auth
|
|
29
|
+
try {
|
|
30
|
+
const result: ListSoundsResponse = await authed.client.listSounds()
|
|
31
|
+
const listing: SoundsListing = {
|
|
32
|
+
shipped: SHIPPED_SOUND_LISTING,
|
|
33
|
+
custom: result.sounds,
|
|
34
|
+
}
|
|
35
|
+
if (flags.json) {
|
|
36
|
+
deps.io.out(JSON.stringify(listing, null, 2))
|
|
37
|
+
return EXIT.ok
|
|
38
|
+
}
|
|
39
|
+
for (const sound of listing.shipped) {
|
|
40
|
+
deps.io.out(`${sound.ref} ${sound.name}`)
|
|
41
|
+
}
|
|
42
|
+
for (const sound of listing.custom) {
|
|
43
|
+
deps.io.out(`${sound.sound_id} ${sound.name} ${formatSoundDuration(sound.duration_ms)}`)
|
|
44
|
+
}
|
|
45
|
+
return EXIT.ok
|
|
46
|
+
} catch (err) {
|
|
47
|
+
return reportError(deps, err)
|
|
48
|
+
}
|
|
49
|
+
}
|