@raidiant/notifai 10.1.0 → 10.1.2

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 (204) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +3 -0
  3. package/dist/cli-bin.d.ts +21 -1
  4. package/dist/cli-bin.js +141 -10
  5. package/dist/cli-bin.js.map +1 -1
  6. package/dist/cli-update-contract.d.ts +7 -0
  7. package/dist/cli-update-contract.js +10 -0
  8. package/dist/cli-update-contract.js.map +1 -0
  9. package/dist/client.d.ts +6 -1
  10. package/dist/client.js +1 -0
  11. package/dist/client.js.map +1 -1
  12. package/dist/codex-wake.d.ts +2 -0
  13. package/dist/codex-wake.js +2 -1
  14. package/dist/codex-wake.js.map +1 -1
  15. package/dist/commands-auth.d.ts +15 -1
  16. package/dist/commands-auth.js +29 -11
  17. package/dist/commands-auth.js.map +1 -1
  18. package/dist/commands-core.d.ts +9 -2
  19. package/dist/commands-core.js +11 -4
  20. package/dist/commands-core.js.map +1 -1
  21. package/dist/commands-devices.d.ts +10 -1
  22. package/dist/commands-devices.js +17 -13
  23. package/dist/commands-devices.js.map +1 -1
  24. package/dist/commands-doctor.js +93 -49
  25. package/dist/commands-doctor.js.map +1 -1
  26. package/dist/commands-hooks.js +47 -10
  27. package/dist/commands-hooks.js.map +1 -1
  28. package/dist/commands-init.d.ts +16 -0
  29. package/dist/commands-init.js +254 -93
  30. package/dist/commands-init.js.map +1 -1
  31. package/dist/commands-send-support.js +3 -0
  32. package/dist/commands-send-support.js.map +1 -1
  33. package/dist/commands-send.d.ts +1 -1
  34. package/dist/commands-send.js +121 -35
  35. package/dist/commands-send.js.map +1 -1
  36. package/dist/commands-skill.js +72 -54
  37. package/dist/commands-skill.js.map +1 -1
  38. package/dist/commands-update.d.ts +10 -0
  39. package/dist/commands-update.js +141 -0
  40. package/dist/commands-update.js.map +1 -0
  41. package/dist/commands.d.ts +2 -1
  42. package/dist/commands.js +2 -1
  43. package/dist/commands.js.map +1 -1
  44. package/dist/hook-adapter.d.ts +2 -0
  45. package/dist/hook-adapter.js +12 -1
  46. package/dist/hook-adapter.js.map +1 -1
  47. package/dist/hooks.d.ts +43 -2
  48. package/dist/hooks.js +163 -21
  49. package/dist/hooks.js.map +1 -1
  50. package/dist/invocation-context.d.ts +1 -0
  51. package/dist/invocation-context.js +9 -1
  52. package/dist/invocation-context.js.map +1 -1
  53. package/dist/main-run.d.ts +1 -0
  54. package/dist/main-run.js +42 -0
  55. package/dist/main-run.js.map +1 -0
  56. package/dist/main.js +10 -31
  57. package/dist/main.js.map +1 -1
  58. package/dist/native-skills.d.ts +13 -3
  59. package/dist/native-skills.js +51 -12
  60. package/dist/native-skills.js.map +1 -1
  61. package/dist/node-floor.d.ts +19 -0
  62. package/dist/node-floor.js +39 -0
  63. package/dist/node-floor.js.map +1 -0
  64. package/dist/orca-session-title.d.ts +5 -4
  65. package/dist/orca-session-title.js +32 -19
  66. package/dist/orca-session-title.js.map +1 -1
  67. package/dist/platform.d.ts +11 -17
  68. package/dist/platform.js +20 -23
  69. package/dist/platform.js.map +1 -1
  70. package/dist/program.d.ts +2 -1
  71. package/dist/program.js +22 -5
  72. package/dist/program.js.map +1 -1
  73. package/dist/question-settlement-process.d.ts +15 -0
  74. package/dist/question-settlement-process.js +35 -0
  75. package/dist/question-settlement-process.js.map +1 -0
  76. package/dist/readiness.d.ts +25 -1
  77. package/dist/readiness.js +32 -2
  78. package/dist/readiness.js.map +1 -1
  79. package/dist/release.d.ts +5 -5
  80. package/dist/release.js +5 -5
  81. package/dist/setup-destinations.d.ts +23 -0
  82. package/dist/setup-destinations.js +44 -0
  83. package/dist/setup-destinations.js.map +1 -0
  84. package/dist/skill-integrity.d.ts +49 -0
  85. package/dist/skill-integrity.js +154 -0
  86. package/dist/skill-integrity.js.map +1 -0
  87. package/dist/skill-source/manifest.json +16 -0
  88. package/dist/skill-source/notifai/SKILL.md +390 -0
  89. package/dist/skill-source/notifai/references/harness-setup.md +220 -0
  90. package/package.json +11 -14
  91. package/src/atomic-file.ts +0 -198
  92. package/src/claude-wake.test.ts +0 -321
  93. package/src/claude-wake.ts +0 -499
  94. package/src/cli-bin.test.ts +0 -38
  95. package/src/cli-bin.ts +0 -67
  96. package/src/cli-release.test.ts +0 -46
  97. package/src/cli-release.ts +0 -78
  98. package/src/client.test.ts +0 -390
  99. package/src/client.ts +0 -345
  100. package/src/codex-wake.test.ts +0 -254
  101. package/src/codex-wake.ts +0 -297
  102. package/src/command-session.ts +0 -38
  103. package/src/commands-agent-sessions.ts +0 -72
  104. package/src/commands-auth.ts +0 -205
  105. package/src/commands-config.ts +0 -336
  106. package/src/commands-core.ts +0 -298
  107. package/src/commands-devices.test.ts +0 -15
  108. package/src/commands-devices.ts +0 -173
  109. package/src/commands-doctor.ts +0 -1440
  110. package/src/commands-guidance.ts +0 -181
  111. package/src/commands-harness-context.ts +0 -207
  112. package/src/commands-hook-shape.ts +0 -69
  113. package/src/commands-hooks.ts +0 -2268
  114. package/src/commands-init.ts +0 -878
  115. package/src/commands-io.ts +0 -108
  116. package/src/commands-logs.ts +0 -243
  117. package/src/commands-project.ts +0 -47
  118. package/src/commands-send-support.test.ts +0 -156
  119. package/src/commands-send-support.ts +0 -311
  120. package/src/commands-send.ts +0 -769
  121. package/src/commands-setup-proof.test.ts +0 -72
  122. package/src/commands-setup-proof.ts +0 -124
  123. package/src/commands-skill.test.ts +0 -44
  124. package/src/commands-skill.ts +0 -204
  125. package/src/commands-sounds.test.ts +0 -106
  126. package/src/commands-sounds.ts +0 -49
  127. package/src/commands.test.ts +0 -7828
  128. package/src/commands.ts +0 -75
  129. package/src/config-schema.test.ts +0 -153
  130. package/src/config-schema.ts +0 -349
  131. package/src/config.test.ts +0 -581
  132. package/src/config.ts +0 -475
  133. package/src/credentials.test.ts +0 -403
  134. package/src/credentials.ts +0 -403
  135. package/src/file-lock-process-worker.test.ts +0 -64
  136. package/src/file-lock.test.ts +0 -320
  137. package/src/file-lock.ts +0 -393
  138. package/src/fixtures/hermes-0.20.6-classic-cli-local.json +0 -50
  139. package/src/fixtures/openclaw-2026.7.1-2-agent-local.json +0 -57
  140. package/src/generated-session-label.ts +0 -155
  141. package/src/guidance-content.ts +0 -278
  142. package/src/guidance-render.ts +0 -56
  143. package/src/guidance.test.ts +0 -327
  144. package/src/guidance.ts +0 -233
  145. package/src/harness-integration.test.ts +0 -294
  146. package/src/harnesses.test.ts +0 -149
  147. package/src/harnesses.ts +0 -164
  148. package/src/hook-adapter.test.ts +0 -496
  149. package/src/hook-adapter.ts +0 -410
  150. package/src/hook-input.test.ts +0 -39
  151. package/src/hook-input.ts +0 -72
  152. package/src/hooks.test.ts +0 -5549
  153. package/src/hooks.ts +0 -3759
  154. package/src/install-hooks.test.ts +0 -1614
  155. package/src/install-hooks.ts +0 -1501
  156. package/src/interactive.test.ts +0 -387
  157. package/src/interactive.ts +0 -858
  158. package/src/invocation-context.test.ts +0 -352
  159. package/src/invocation-context.ts +0 -197
  160. package/src/logging-process-worker.test.ts +0 -45
  161. package/src/logging.test.ts +0 -544
  162. package/src/logging.ts +0 -698
  163. package/src/main.ts +0 -36
  164. package/src/native-skills.test.ts +0 -115
  165. package/src/native-skills.ts +0 -162
  166. package/src/onboarding-docs.test.ts +0 -25
  167. package/src/openclaw-plugin.ts +0 -409
  168. package/src/opencode-plugin.ts +0 -298
  169. package/src/orca-session-title.test.ts +0 -54
  170. package/src/orca-session-title.ts +0 -103
  171. package/src/pack-feedback-slice.test.ts +0 -212
  172. package/src/pack-feedback-slice.ts +0 -187
  173. package/src/platform.test.ts +0 -152
  174. package/src/platform.ts +0 -173
  175. package/src/program.test.ts +0 -282
  176. package/src/program.ts +0 -818
  177. package/src/project-enablement.test.ts +0 -55
  178. package/src/project-enablement.ts +0 -99
  179. package/src/question-caps.test.ts +0 -49
  180. package/src/question-timing.ts +0 -56
  181. package/src/readiness.test.ts +0 -25
  182. package/src/readiness.ts +0 -179
  183. package/src/release.ts +0 -51
  184. package/src/send-attempts.test.ts +0 -143
  185. package/src/send-attempts.ts +0 -188
  186. package/src/send.test.ts +0 -28
  187. package/src/send.ts +0 -436
  188. package/src/session-activation.ts +0 -61
  189. package/src/session-end-log-lock-worker.test.ts +0 -35
  190. package/src/session-labels.test.ts +0 -490
  191. package/src/session-labels.ts +0 -474
  192. package/src/skill.test.ts +0 -415
  193. package/src/sound-ref.test.ts +0 -31
  194. package/src/sound-ref.ts +0 -34
  195. package/src/trust-policy.test.ts +0 -701
  196. package/src/ui/banner.ts +0 -95
  197. package/src/ui/config-view.test.ts +0 -90
  198. package/src/ui/config-view.ts +0 -138
  199. package/src/ui/help.test.ts +0 -16
  200. package/src/ui/help.ts +0 -128
  201. package/src/ui/theme.test.ts +0 -92
  202. package/src/ui/theme.ts +0 -265
  203. package/src/url-policy.ts +0 -399
  204. package/tsconfig.json +0 -10
@@ -1,282 +0,0 @@
1
- import { mkdtempSync, writeFileSync } from 'node:fs'
2
- import os from 'node:os'
3
- import path from 'node:path'
4
- import { describe, expect, it } from 'vitest'
5
- import { buildProgram, type ProgramRunners } from './program.js'
6
- import type { CommandDeps } from './commands.js'
7
-
8
- /**
9
- * The layer these tests own is the argv boundary: what a real command line
10
- * turns into by the time a command implementation receives it. Collector
11
- * defaults, `--no-wait` disentangling, `--body-file` reading — none of that is
12
- * visible to the unit tests on the commands themselves, and it used to be
13
- * covered by nothing but reading `program.ts` with human eyes.
14
- */
15
-
16
- class ExitSentinel extends Error {
17
- constructor(readonly code: number) {
18
- super(`exit ${code}`)
19
- }
20
- }
21
-
22
- function makeDeps(): CommandDeps & { outLines: string[]; errLines: string[] } {
23
- const outLines: string[] = []
24
- const errLines: string[] = []
25
- return {
26
- io: {
27
- out: (line: string) => outLines.push(line),
28
- err: (line: string) => errLines.push(line),
29
- confirm: async () => false,
30
- openUrl: () => {},
31
- },
32
- store: {
33
- load: () => null,
34
- save: () => {},
35
- clear: () => {},
36
- describe: () => 'test credential store',
37
- },
38
- env: {},
39
- cwd: os.tmpdir(),
40
- outLines,
41
- errLines,
42
- }
43
- }
44
-
45
- /**
46
- * Parse a real command line and capture what would have been dispatched.
47
- * `exit` throws so post-exit code cannot run — the same property
48
- * `process.exit` gives production.
49
- */
50
- async function parse(
51
- argv: string[],
52
- runners: Partial<ProgramRunners>,
53
- deps = makeDeps(),
54
- ): Promise<{ exitCode: number | undefined; deps: ReturnType<typeof makeDeps> }> {
55
- let exitCode: number | undefined
56
- const program = buildProgram(deps, {
57
- runners,
58
- exit: (code: number) => {
59
- exitCode = code
60
- throw new ExitSentinel(code)
61
- },
62
- })
63
- try {
64
- await program.parseAsync(['node', 'notifai', ...argv])
65
- } catch (err) {
66
- if (!(err instanceof ExitSentinel)) throw err
67
- }
68
- return { exitCode, deps }
69
- }
70
-
71
- describe('program argv parsing', () => {
72
- it('maps a full send command line onto sendCommand flags', async () => {
73
- let seen: Record<string, unknown> | undefined
74
- const { exitCode } = await parse(
75
- [
76
- 'send',
77
- '--kind', 'done',
78
- '--title', 'Build finished',
79
- '--body', 'All green.',
80
- '--choice', 'Ship it',
81
- '--choice', 'Hold',
82
- '--multi',
83
- '--reply',
84
- '--reply-timeout', '30',
85
- ],
86
- { send: (async (_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['send'] },
87
- )
88
- expect(exitCode).toBe(0)
89
- expect(seen).toMatchObject({
90
- kind: 'done',
91
- title: 'Build finished',
92
- body: 'All green.',
93
- choice: ['Ship it', 'Hold'],
94
- multi: true,
95
- reply: true,
96
- replyTimeout: 30,
97
- noWait: false,
98
- })
99
- })
100
-
101
- it('preserves deliberate Projectless send intent at the argv boundary', async () => {
102
- let seen: Record<string, unknown> | undefined
103
- await parse(
104
- ['send', '--kind', 'done', '--title', 'T', '--body', 'B', '--projectless'],
105
- { send: (async (_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['send'] },
106
- )
107
- expect(seen).toMatchObject({ projectless: true })
108
- })
109
-
110
- it('dispatches User-owned Project enablement commands', async () => {
111
- let enabled = 0
112
- const result = await parse(['project', 'enable'], {
113
- projectEnable: ((_deps) => (enabled += 1, 0)) as ProgramRunners['projectEnable'],
114
- })
115
- expect(result.exitCode).toBe(0)
116
- expect(enabled).toBe(1)
117
- })
118
-
119
- it('dispatches the current Agent Session rename without exposing an id override', async () => {
120
- let label: string | undefined
121
- const result = await parse(['session', 'rename', 'Hermes Support'], {
122
- agentSessionRename: (async (_deps, value) => ((label = value), 0)) as ProgramRunners['agentSessionRename'],
123
- })
124
- expect(result.exitCode).toBe(0)
125
- expect(label).toBe('Hermes Support')
126
- })
127
-
128
- it('dispatches sounds --json onto soundsCommand', async () => {
129
- let seen: Record<string, unknown> | undefined
130
- const result = await parse(['sounds', '--json'], {
131
- sounds: (async (_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['sounds'],
132
- })
133
- expect(result.exitCode).toBe(0)
134
- expect(seen).toMatchObject({ json: true })
135
- })
136
-
137
- it('passes a custom sound name through --sound', async () => {
138
- let seen: Record<string, unknown> | undefined
139
- await parse(
140
- ['send', '--kind', 'done', '--title', 'T', '--body', 'B', '--sound', 'Kitchen timer'],
141
- { send: (async (_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['send'] },
142
- )
143
- expect(seen).toMatchObject({ sound: 'Kitchen timer' })
144
- })
145
-
146
- it('drops empty collector defaults so "not passed" stays absent', async () => {
147
- let seen: Record<string, unknown> | undefined
148
- await parse(
149
- ['send', '--kind', 'update', '--title', 'T', '--body', 'B'],
150
- { send: (async (_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['send'] },
151
- )
152
- expect(seen).toBeDefined()
153
- expect(seen).not.toHaveProperty('choice')
154
- expect(seen).not.toHaveProperty('image')
155
- expect(seen).not.toHaveProperty('imageAlt')
156
- expect(seen).not.toHaveProperty('wait')
157
- })
158
-
159
- it('maps init --setup-scope onto the command flags', async () => {
160
- let seen: Record<string, unknown> | undefined
161
- const { exitCode } = await parse(
162
- ['init', '--skills', '--setup-scope', 'global', '--no-hooks'],
163
- { init: (async (_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['init'] },
164
- )
165
- expect(exitCode).toBe(0)
166
- expect(seen).toMatchObject({ skills: true, setupScope: 'global', hooks: false })
167
- })
168
-
169
- it('disentangles --no-wait and --wait from their shared commander flag', async () => {
170
- const capture = (sink: Record<string, unknown>[]): ProgramRunners['send'] =>
171
- (async (_deps, flags) => (sink.push(flags as Record<string, unknown>), 0)) as ProgramRunners['send']
172
- const seen: Record<string, unknown>[] = []
173
- await parse(['send', '--kind', 'update', '--title', 'T', '--body', 'B', '--no-wait'], { send: capture(seen) })
174
- await parse(['send', '--kind', 'update', '--title', 'T', '--body', 'B', '--wait', '5'], { send: capture(seen) })
175
- expect(seen[0]).toMatchObject({ noWait: true })
176
- expect(seen[0]).not.toHaveProperty('wait')
177
- expect(seen[1]).toMatchObject({ noWait: false, wait: 5 })
178
- })
179
-
180
- it('reads --body-file and refuses it alongside --body', async () => {
181
- const dir = mkdtempSync(path.join(os.tmpdir(), 'notifai-program-test-'))
182
- const file = path.join(dir, 'body.md')
183
- writeFileSync(file, 'From a file.\n')
184
- let seen: Record<string, unknown> | undefined
185
- const send = (async (_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['send']
186
-
187
- const ok = await parse(['send', '--kind', 'update', '--title', 'T', '--body-file', file], { send })
188
- expect(ok.exitCode).toBe(0)
189
- expect(seen).toMatchObject({ body: 'From a file.\n' })
190
- expect(seen).not.toHaveProperty('bodyFile')
191
-
192
- const both = await parse(
193
- ['send', '--kind', 'update', '--title', 'T', '--body', 'B', '--body-file', file],
194
- { send },
195
- )
196
- expect(both.exitCode).toBe(2)
197
- expect(both.deps.errLines.join('\n')).toContain('either --body or --body-file')
198
-
199
- const missing = await parse(
200
- ['send', '--kind', 'update', '--title', 'T', '--body-file', path.join(dir, 'absent.md')],
201
- { send },
202
- )
203
- expect(missing.exitCode).toBe(2)
204
- expect(missing.deps.errLines.join('\n')).toContain('Could not read')
205
- })
206
-
207
- it('builds ask flags without empty collectors and passes the question through', async () => {
208
- let seenQuestion: string | undefined
209
- let seenFlags: Record<string, unknown> | undefined
210
- const ask = (async (_deps, question, flags) => {
211
- seenQuestion = question
212
- seenFlags = flags as Record<string, unknown>
213
- return 0
214
- }) as ProgramRunners['ask']
215
-
216
- await parse(
217
- ['ask', 'Deploy where?', '--choice', 'Staging', '--choice', 'Production', '--session-label', 'release run', '--json'],
218
- { ask },
219
- )
220
- expect(seenQuestion).toBe('Deploy where?')
221
- expect(seenFlags).toEqual({
222
- choice: ['Staging', 'Production'],
223
- sessionLabel: 'release run',
224
- json: true,
225
- })
226
-
227
- await parse(['ask', 'Free text?'], { ask })
228
- expect(seenFlags).toEqual({})
229
- })
230
-
231
- it('rejects --no-block as unknown: the flag is gone, not tombstoned', async () => {
232
- const { exitCode, deps } = await parse(
233
- ['send', '--kind', 'update', '--title', 'T', '--body', 'B', '--no-block'],
234
- { send: (async () => 0) as ProgramRunners['send'] },
235
- )
236
- expect(exitCode).toBe(2)
237
- expect(deps.errLines).toHaveLength(0)
238
- })
239
-
240
- it('names an unknown command and exits 2', async () => {
241
- const { exitCode, deps } = await parse(['sendd'], {})
242
- expect(exitCode).toBe(2)
243
- expect(deps.errLines.join('\n')).toContain('Unknown command "sendd"')
244
- expect(deps.errLines.join('\n')).toContain('send')
245
- })
246
-
247
- it('rejects send --event now that the public event field is gone', async () => {
248
- const { exitCode, deps } = await parse(
249
- ['send', '--kind', 'done', '--title', 'T', '--body', 'B', '--event', 'tests_passed'],
250
- { send: (async () => 0) as ProgramRunners['send'] },
251
- )
252
- expect(exitCode).toBe(2)
253
- expect(deps.errLines).toHaveLength(0)
254
- })
255
-
256
- it('drops the empty --event collector for logs', async () => {
257
- let seen: Record<string, unknown> | undefined
258
- const logs = ((_deps, flags) => ((seen = flags as Record<string, unknown>), 0)) as ProgramRunners['logs']
259
- await parse(['logs'], { logs })
260
- expect(seen).not.toHaveProperty('event')
261
- await parse(['logs', '--event', 'send.submitted'], { logs })
262
- expect(seen).toMatchObject({ event: ['send.submitted'] })
263
- })
264
-
265
- it('passes close --pending without inventing a request id', async () => {
266
- let seenId: string | undefined
267
- let seenFlags: Record<string, unknown> | undefined
268
- const close = (async (_deps, requestId, flags) => {
269
- seenId = requestId
270
- seenFlags = flags as Record<string, unknown>
271
- return 0
272
- }) as ProgramRunners['close']
273
-
274
- await parse(['close', '--pending', '--json'], { close })
275
- expect(seenId).toBeUndefined()
276
- expect(seenFlags).toEqual({ pending: true, json: true })
277
-
278
- await parse(['close', 'req_abc'], { close })
279
- expect(seenId).toBe('req_abc')
280
- expect(seenFlags).toEqual({})
281
- })
282
- })