@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,321 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
- import {
3
- CLAUDE_PEER_PROTOCOL,
4
- CLAUDE_POST_SEND_LIVENESS_MS,
5
- claudeWakeRoute,
6
- observeClaudeSession,
7
- type ClaudeSessionDescriptor,
8
- type ClaudeWakeAdapters,
9
- } from './claude-wake.js'
10
-
11
- const SESSION_ID = '11111111-1111-4111-8111-111111111111'
12
- const STARTED_AT = 1_800_000_000_000
13
-
14
- function descriptor(overrides: Partial<ClaudeSessionDescriptor> = {}): ClaudeSessionDescriptor {
15
- return {
16
- pid: 12345,
17
- sessionId: SESSION_ID,
18
- cwd: '/tmp/notifai-claude-wake',
19
- startedAt: STARTED_AT,
20
- procStart: 'Wed Aug 12 08:17:53 2026',
21
- version: '2.1.228',
22
- peerProtocol: CLAUDE_PEER_PROTOCOL,
23
- messagingSocketPath: '/tmp/cc-socks/12345.sock',
24
- status: 'idle',
25
- ...overrides,
26
- }
27
- }
28
-
29
- function adapters(options: {
30
- agents?: unknown[]
31
- descriptor?: unknown
32
- agentsSequence?: unknown[][]
33
- } = {}): ClaudeWakeAdapters & {
34
- sent: Array<{ socketPath: string; line: string }>
35
- resumed: Array<{ sessionId: string; cwd: string; context: string }>
36
- sleeps: number[]
37
- } {
38
- const current = descriptor()
39
- const sent: Array<{ socketPath: string; line: string }> = []
40
- const resumed: Array<{ sessionId: string; cwd: string; context: string }> = []
41
- const sleeps: number[] = []
42
- const sequence = [...(options.agentsSequence ?? [])]
43
- return {
44
- sent,
45
- resumed,
46
- sleeps,
47
- async listAgents() {
48
- return sequence.shift() ?? options.agents ?? [
49
- {
50
- pid: current.pid,
51
- sessionId: current.sessionId,
52
- startedAt: current.startedAt,
53
- status: current.status,
54
- },
55
- ]
56
- },
57
- readDescriptor() {
58
- return options.descriptor ?? current
59
- },
60
- async sendSocket(socketPath, line) {
61
- sent.push({ socketPath, line })
62
- },
63
- async resume(sessionId, cwd, context) {
64
- resumed.push({ sessionId, cwd, context })
65
- },
66
- async sleep(milliseconds) {
67
- sleeps.push(milliseconds)
68
- },
69
- }
70
- }
71
-
72
- const event = {
73
- context:
74
- 'Notifai — question_id rollout-option, question "Which rollout option?"; the user answered "BETA".',
75
- answers: 1,
76
- remaining: 0,
77
- request_ids: ['req_test'],
78
- journal_recorded_at: STARTED_AT,
79
- commitDelivery: () => true,
80
- }
81
-
82
- describe('Claude session observation', () => {
83
- it('treats a validated idle owner as socket-wakeable', async () => {
84
- const observation = await observeClaudeSession(SESSION_ID, adapters())
85
-
86
- expect(observation).toMatchObject({
87
- state: 'live-idle',
88
- descriptor: { sessionId: SESSION_ID, peerProtocol: CLAUDE_PEER_PROTOCOL },
89
- })
90
- })
91
-
92
- it('treats a validated busy owner as queueable on the inbox socket', async () => {
93
- const live = descriptor({ status: 'busy' })
94
- const observation = await observeClaudeSession(
95
- SESSION_ID,
96
- adapters({
97
- agents: [
98
- {
99
- pid: live.pid,
100
- sessionId: live.sessionId,
101
- startedAt: live.startedAt,
102
- status: live.status,
103
- },
104
- ],
105
- descriptor: live,
106
- }),
107
- )
108
-
109
- expect(observation.state).toBe('live-busy')
110
- })
111
-
112
- it('fails closed on an unknown peer protocol', async () => {
113
- const observation = await observeClaudeSession(
114
- SESSION_ID,
115
- adapters({ descriptor: descriptor({ peerProtocol: CLAUDE_PEER_PROTOCOL + 1 }) }),
116
- )
117
-
118
- expect(observation).toEqual({
119
- state: 'unknown',
120
- reason: `unsupported Claude peer protocol ${CLAUDE_PEER_PROTOCOL + 1}`,
121
- })
122
- })
123
-
124
- it('uses first-party status when the descriptor is in a transient shell state', async () => {
125
- const observation = await observeClaudeSession(
126
- SESSION_ID,
127
- adapters({ descriptor: descriptor({ status: 'shell' }) }),
128
- )
129
-
130
- expect(observation.state).toBe('live-idle')
131
- })
132
-
133
- it('fails closed when the first-party probe and descriptor identity disagree', async () => {
134
- const observation = await observeClaudeSession(
135
- SESSION_ID,
136
- adapters({ descriptor: descriptor({ startedAt: STARTED_AT + 1 }) }),
137
- )
138
-
139
- expect(observation).toEqual({
140
- state: 'unknown',
141
- reason: 'Claude liveness probe and descriptor disagree',
142
- })
143
- })
144
-
145
- it('calls a session stopped only when the liveness probe returns no owner', async () => {
146
- await expect(observeClaudeSession(SESSION_ID, adapters({ agents: [] }))).resolves.toEqual({
147
- state: 'stopped',
148
- })
149
- })
150
- })
151
-
152
- describe('Claude wake delivery', () => {
153
- it('posts one newline-terminated JSON message and stays alive for provenance', async () => {
154
- const wake = adapters()
155
- const outcome = await claudeWakeRoute({
156
- sessionId: SESSION_ID,
157
- cwd: '/tmp/notifai-claude-wake',
158
- sourcePid: 12345,
159
- adapters: wake,
160
- }).deliver(event)
161
-
162
- expect(wake.sent).toHaveLength(1)
163
- expect(wake.sent[0]?.socketPath).toBe('/tmp/cc-socks/12345.sock')
164
- expect(wake.sent[0]?.line.endsWith('\n')).toBe(true)
165
- expect(JSON.parse(wake.sent[0]!.line)).toEqual({
166
- type: 'user',
167
- message: { role: 'user', content: event.context },
168
- })
169
- expect(wake.sleeps).toEqual([CLAUDE_POST_SEND_LIVENESS_MS])
170
- expect(wake.resumed).toEqual([])
171
- expect(outcome.log).toEqual({
172
- route: 'inbox-socket',
173
- stage: 'delivered',
174
- session_state: 'live-idle',
175
- })
176
- })
177
-
178
- it('holds rather than sending when exact Stop-hook ownership cannot be proven', async () => {
179
- const wake = adapters()
180
-
181
- const outcome = await claudeWakeRoute({
182
- sessionId: SESSION_ID,
183
- cwd: '/tmp/notifai-claude-wake',
184
- sourcePid: 99999,
185
- adapters: wake,
186
- }).deliver(event)
187
-
188
- expect(wake.sent).toEqual([])
189
- expect(outcome.log).toMatchObject({
190
- route: 'hold-for-next-turn',
191
- stage: 'queued',
192
- reason: 'the Stop-hook process cannot prove exact Claude session ownership',
193
- })
194
- })
195
-
196
- it('uses the same socket path for a busy session and reports queued delivery', async () => {
197
- const live = descriptor({ status: 'busy' })
198
- const wake = adapters({
199
- agents: [
200
- {
201
- pid: live.pid,
202
- sessionId: live.sessionId,
203
- startedAt: live.startedAt,
204
- status: live.status,
205
- },
206
- ],
207
- descriptor: live,
208
- })
209
-
210
- const outcome = await claudeWakeRoute({
211
- sessionId: SESSION_ID,
212
- cwd: live.cwd,
213
- sourcePid: 12345,
214
- adapters: wake,
215
- }).deliver(event)
216
-
217
- expect(wake.sent).toHaveLength(1)
218
- expect(outcome.notes.join('\n')).toContain('busy Claude session')
219
- expect(outcome.log?.['session_state']).toBe('live-busy')
220
- })
221
-
222
- it('cold-resumes only after two first-party probes both prove no owner', async () => {
223
- const wake = adapters({ agentsSequence: [[], []] })
224
- const outcome = await claudeWakeRoute({
225
- sessionId: SESSION_ID,
226
- cwd: '/tmp/notifai-claude-wake',
227
- sourcePid: 12345,
228
- adapters: wake,
229
- }).deliver(event)
230
-
231
- expect(wake.sent).toEqual([])
232
- expect(wake.resumed).toEqual([
233
- {
234
- sessionId: SESSION_ID,
235
- cwd: '/tmp/notifai-claude-wake',
236
- context: event.context,
237
- },
238
- ])
239
- expect(outcome.log).toEqual({ route: 'cold-resume', stage: 'delivered' })
240
- })
241
-
242
- it('holds rather than cold-resuming without exact Stop-hook parent ownership', async () => {
243
- const wake = adapters({ agentsSequence: [[], []] })
244
-
245
- const outcome = await claudeWakeRoute({
246
- sessionId: SESSION_ID,
247
- cwd: '/tmp/notifai-claude-wake',
248
- sourcePid: 99999,
249
- adapters: wake,
250
- }).deliver(event)
251
-
252
- expect(wake.resumed).toEqual([])
253
- expect(outcome.log).toMatchObject({
254
- route: 'hold-for-next-turn',
255
- stage: 'queued',
256
- reason: 'the Stop-hook process cannot prove exact Claude session ownership',
257
- })
258
- })
259
-
260
- it('refuses a ghost resume when a session becomes live between probes', async () => {
261
- const liveAgent = {
262
- pid: 12345,
263
- sessionId: SESSION_ID,
264
- startedAt: STARTED_AT,
265
- status: 'idle',
266
- }
267
- const wake = adapters({ agentsSequence: [[], [liveAgent]] })
268
-
269
- const outcome = await claudeWakeRoute({
270
- sessionId: SESSION_ID,
271
- cwd: '/tmp/notifai-claude-wake',
272
- sourcePid: 12345,
273
- adapters: wake,
274
- }).deliver(event)
275
-
276
- expect(wake.resumed).toEqual([])
277
- expect(wake.sent).toEqual([])
278
- expect(outcome.log).toMatchObject({
279
- route: 'hold-for-next-turn',
280
- stage: 'queued',
281
- })
282
- expect(outcome.notes.join('\n')).toContain('became live before cold resume')
283
- })
284
-
285
- it('holds the accepted answer when state or protocol is unknown', async () => {
286
- const wake = adapters({
287
- descriptor: descriptor({ peerProtocol: CLAUDE_PEER_PROTOCOL + 1 }),
288
- })
289
- const outcome = await claudeWakeRoute({
290
- sessionId: SESSION_ID,
291
- cwd: '/tmp/notifai-claude-wake',
292
- sourcePid: 12345,
293
- adapters: wake,
294
- }).deliver(event)
295
-
296
- expect(wake.sent).toEqual([])
297
- expect(wake.resumed).toEqual([])
298
- expect(outcome.log).toEqual({
299
- route: 'hold-for-next-turn',
300
- stage: 'queued',
301
- reason: `unsupported Claude peer protocol ${CLAUDE_PEER_PROTOCOL + 1}`,
302
- })
303
- })
304
-
305
- it('does not report delivery when the socket write fails', async () => {
306
- const wake = adapters()
307
- wake.sendSocket = vi.fn(async () => {
308
- throw new Error('socket unavailable')
309
- })
310
-
311
- await expect(
312
- claudeWakeRoute({
313
- sessionId: SESSION_ID,
314
- cwd: '/tmp/notifai-claude-wake',
315
- sourcePid: 12345,
316
- adapters: wake,
317
- }).deliver(event),
318
- ).rejects.toThrow('socket unavailable')
319
- expect(wake.sleeps).toEqual([])
320
- })
321
- })