@raidiant/notifai 3.0.1 → 5.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.
Files changed (71) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +12 -4
  3. package/dist/commands.d.ts +27 -10
  4. package/dist/commands.js +429 -152
  5. package/dist/commands.js.map +1 -1
  6. package/dist/config-schema.js +20 -11
  7. package/dist/config-schema.js.map +1 -1
  8. package/dist/config.d.ts +3 -1
  9. package/dist/config.js +12 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/file-lock.d.ts +6 -1
  12. package/dist/file-lock.js +55 -9
  13. package/dist/file-lock.js.map +1 -1
  14. package/dist/harnesses.d.ts +1 -1
  15. package/dist/harnesses.js.map +1 -1
  16. package/dist/hooks.d.ts +84 -12
  17. package/dist/hooks.js +433 -125
  18. package/dist/hooks.js.map +1 -1
  19. package/dist/install-hooks.d.ts +91 -14
  20. package/dist/install-hooks.js +226 -34
  21. package/dist/install-hooks.js.map +1 -1
  22. package/dist/interactive.d.ts +1 -1
  23. package/dist/interactive.js +1 -1
  24. package/dist/invocation-context.d.ts +42 -0
  25. package/dist/invocation-context.js +130 -0
  26. package/dist/invocation-context.js.map +1 -0
  27. package/dist/logging.d.ts +8 -0
  28. package/dist/logging.js +8 -0
  29. package/dist/logging.js.map +1 -1
  30. package/dist/main.js +84 -49
  31. package/dist/main.js.map +1 -1
  32. package/dist/opencode-plugin.d.ts +8 -0
  33. package/dist/opencode-plugin.js +24 -162
  34. package/dist/opencode-plugin.js.map +1 -1
  35. package/dist/send.d.ts +38 -7
  36. package/dist/send.js +97 -41
  37. package/dist/send.js.map +1 -1
  38. package/dist/ui/help.d.ts +0 -1
  39. package/dist/ui/help.js +6 -3
  40. package/dist/ui/help.js.map +1 -1
  41. package/dist/ui/theme.d.ts +0 -15
  42. package/dist/ui/theme.js +2 -18
  43. package/dist/ui/theme.js.map +1 -1
  44. package/package.json +2 -2
  45. package/src/commands.test.ts +501 -63
  46. package/src/commands.ts +547 -187
  47. package/src/config-schema.test.ts +1 -1
  48. package/src/config-schema.ts +22 -11
  49. package/src/config.test.ts +178 -18
  50. package/src/config.ts +14 -1
  51. package/src/file-lock.test.ts +41 -0
  52. package/src/file-lock.ts +59 -9
  53. package/src/harnesses.test.ts +37 -29
  54. package/src/harnesses.ts +1 -4
  55. package/src/hooks.test.ts +500 -58
  56. package/src/hooks.ts +523 -169
  57. package/src/install-hooks.test.ts +232 -12
  58. package/src/install-hooks.ts +241 -37
  59. package/src/interactive.ts +1 -1
  60. package/src/invocation-context.test.ts +253 -0
  61. package/src/invocation-context.ts +176 -0
  62. package/src/logging-process-worker.test.ts +8 -2
  63. package/src/logging.test.ts +33 -18
  64. package/src/logging.ts +11 -0
  65. package/src/main.ts +119 -54
  66. package/src/opencode-plugin.ts +24 -164
  67. package/src/question-caps.test.ts +49 -0
  68. package/src/send.ts +144 -50
  69. package/src/skill.test.ts +197 -120
  70. package/src/ui/help.ts +8 -3
  71. package/src/ui/theme.ts +2 -16
package/CHANGELOG.md CHANGED
@@ -8,6 +8,79 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
9
9
  and [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
10
10
 
11
+ ## [5.0.0](https://github.com/Raidiant-io/notifai/compare/v4.0.0...v5.0.0) (2026-08-16)
12
+
13
+
14
+ ### ⚠ BREAKING CHANGES
15
+
16
+ * `notifai send` now requires --kind. The account preference `agent_acknowledgements_enabled` is renamed to `agent_acknowledgement_text_enabled` and governs only the written reply.
17
+
18
+ ### Features
19
+
20
+ * **cli:** report an ask registration as data, and stop init promising routing it lacks ([156159b](https://github.com/Raidiant-io/notifai/commit/156159b4d39b249a1be65ac86a9f7452ee9720d2))
21
+ * keep a question answerable for a day, and let the user choose ([ace207e](https://github.com/Raidiant-io/notifai/commit/ace207e04cfdc3a0ccda14dffc79a882a663034c))
22
+ * make kind required and carry attention, and always acknowledge an answer ([07e7c21](https://github.com/Raidiant-io/notifai/commit/07e7c216d52f3041e50ce5c7ec1ce4a3f8491e64))
23
+
24
+
25
+ ### Bug Fixes
26
+
27
+ * clean up what the help, the README and a test comment were saying ([221ca6b](https://github.com/Raidiant-io/notifai/commit/221ca6b1d04a80cbd8473d54cd50a6024dcf6c50))
28
+ * **cli:** retire drafts the server rejects as invalid ([4023e42](https://github.com/Raidiant-io/notifai/commit/4023e42e3aeb9f8674239ab0516ccf2527b1428c))
29
+ * **cli:** retire drafts the server rejects as invalid ([d676726](https://github.com/Raidiant-io/notifai/commit/d6767265e4718102f7c97c6ee939073e79b038a2))
30
+ * **cli:** stop --reply-window advertising the default it no longer has ([b9eeabc](https://github.com/Raidiant-io/notifai/commit/b9eeabcbafd9a8e84d2aa86f44b04ca4ece237f2))
31
+ * give the detached waiter the wall clock its host already allows ([3d4b111](https://github.com/Raidiant-io/notifai/commit/3d4b111afb4d35bd8c04121deee82b849dd0ade1))
32
+ * **hooks:** never write a Codex hooks.json Notifai does not own ([8fdd00c](https://github.com/Raidiant-io/notifai/commit/8fdd00c6018915fe2164800c5797a9c3cb92da68))
33
+ * **hooks:** never write a Codex hooks.json Notifai does not own ([8948519](https://github.com/Raidiant-io/notifai/commit/894851942db6283ff856025e7f7d2dd86695013d))
34
+ * **hooks:** read the duplicate-representation warning as a sentence ([e0d041f](https://github.com/Raidiant-io/notifai/commit/e0d041f729e75a4c909f41c5dfafe6602f88edeb))
35
+ * **hooks:** read the duplicate-representation warning as a sentence ([936f068](https://github.com/Raidiant-io/notifai/commit/936f068d2587d56fc10a89a7d87c81c37ef50e2d))
36
+ * **hooks:** report a Codex dual representation only when Notifai is in both ([f4426dc](https://github.com/Raidiant-io/notifai/commit/f4426dc6e3876ac0a75f31ce5fb81c4ec2f4719d))
37
+ * **hooks:** report a Codex dual representation only when Notifai is in both ([2bab419](https://github.com/Raidiant-io/notifai/commit/2bab41987bf9fa251f71785b9881e3c8418be1bb))
38
+ * **hooks:** stop rewriting the whole of a user's Codex config.toml ([e037e22](https://github.com/Raidiant-io/notifai/commit/e037e227646178a0cbc08e7a00ab47129b3b435f))
39
+ * **hooks:** stop rewriting the whole of a user's Codex config.toml ([92ff189](https://github.com/Raidiant-io/notifai/commit/92ff1891c3f42092758af257ec3be8b68e51c0f1))
40
+ * let a question outlive the waiter that pushed it ([de242e7](https://github.com/Raidiant-io/notifai/commit/de242e753434dda87f665de6474491320fbc7365))
41
+ * **lock:** survive losing the rendezvous while registering ([2b5d46d](https://github.com/Raidiant-io/notifai/commit/2b5d46d5221b843fc2db5a803da561e3dbb3b7b0))
42
+ * **lock:** survive losing the rendezvous while registering ([efb8bd6](https://github.com/Raidiant-io/notifai/commit/efb8bd6f718f9f5e7e9bda1471cb88db0a77ef4c))
43
+ * reject an unknown --platform locally, the way send already does ([7ba7678](https://github.com/Raidiant-io/notifai/commit/7ba7678214cc3c98919ece2f533ed40f080951f3))
44
+ * report a failed image upload like every other API failure ([be76c48](https://github.com/Raidiant-io/notifai/commit/be76c4808e6c37bb97d64b14b018b148c4887d94))
45
+ * stop a busy session discarding the answer it was too busy to take ([13ce700](https://github.com/Raidiant-io/notifai/commit/13ce7003c393741b82886910cb51b18d0a9f1065))
46
+ * stop a turn-ending question expiring with the waiter that pushed it ([dd2cda6](https://github.com/Raidiant-io/notifai/commit/dd2cda6a339d711bc4c6723b93ccf940207565a7))
47
+ * stop a typed prompt erasing an outstanding acknowledgement ([ed15e18](https://github.com/Raidiant-io/notifai/commit/ed15e18fffd893ef0c5ad27bc17d4f78b0a88b6c))
48
+ * stop several surfaces stating things that are not true ([56402b9](https://github.com/Raidiant-io/notifai/commit/56402b98b763bdce2fb75c79f8502a92968a0abb))
49
+
50
+
51
+ ### Dependencies
52
+
53
+ * The following workspace dependencies were updated
54
+ * dependencies
55
+ * @raidiant/notifai-protocol bumped from 1.0.0 to 2.0.0
56
+
57
+ ## [4.0.0](https://github.com/Raidiant-io/notifai/compare/v3.0.1...v4.0.0) (2026-08-15)
58
+
59
+
60
+ ### ⚠ BREAKING CHANGES
61
+
62
+ * **cli:** `--detail` and `--detail-file` are removed; the one canonical Markdown body is `--body` / `--body-file`. `--session` is removed, replaced by `--session-id` and `--session-label`. `--image` is now a repeatable ordered collection (max 8) with `--image-alt` for alt text.
63
+
64
+ ### Features
65
+
66
+ * add unified notification content and source context ([3e6479a](https://github.com/Raidiant-io/notifai/commit/3e6479ae22c64c6886c1e919ba3183486e408596))
67
+ * add unified notification content and source context ([2473ed5](https://github.com/Raidiant-io/notifai/commit/2473ed51df42b56652435c611a57f3751fa484f5))
68
+
69
+
70
+ ### Bug Fixes
71
+
72
+ * attribute the unified-content break and propagate workspace dependency bumps ([cb438ce](https://github.com/Raidiant-io/notifai/commit/cb438cec76de9b393d7673554dc440a764887f76))
73
+ * **cli:** document replacements for the removed send flags ([44af905](https://github.com/Raidiant-io/notifai/commit/44af90536a1e6fa5af2ec6b58a19ea68f2d76b96))
74
+ * print server rejection details on command failures ([884fc78](https://github.com/Raidiant-io/notifai/commit/884fc78b62382ad23a49e1c5b92772dd1b8d574b))
75
+ * print server rejection details on command failures ([c9ec4e4](https://github.com/Raidiant-io/notifai/commit/c9ec4e45130784fff7b8ab4da560899eaddffcc5))
76
+
77
+
78
+ ### Dependencies
79
+
80
+ * The following workspace dependencies were updated
81
+ * dependencies
82
+ * @raidiant/notifai-protocol bumped from 0.6.0 to 1.0.0
83
+
11
84
  ## [3.0.1](https://github.com/Raidiant-io/notifai/compare/v3.0.0...v3.0.1) (2026-08-14)
12
85
 
13
86
 
package/README.md CHANGED
@@ -32,10 +32,13 @@ project or the machine. An unattended caller must select one explicitly:
32
32
  notifai send --title "Deploy finished" --body "staging, 2m14s" --kind done
33
33
  ```
34
34
 
35
- Write for a lock screen. The title gets a couple of seconds of attention
36
- and usually has to carry the whole message; assume the body may never be
37
- read. Long-form content belongs in `--detail`, which never appears on the
38
- banner and is shown in the companion app for when you sit down.
35
+ Write a brief title whose substance is immediately understandable; type lives
36
+ in `--kind`, and Project identity is inferred from the invocation directory.
37
+ The one body is always Markdown. Native banners show a bounded readable
38
+ plain-text excerpt from it, while Companion Apps render the complete body. Use
39
+ `--body-file <path|->` for long content. Repeat `--image` for an ordered image
40
+ collection (up to eight), pair each with `--image-alt` for alt text, and use
41
+ `media:1`, `media:2`, and so on for inline references.
39
42
 
40
43
  ## Asking you a question
41
44
 
@@ -51,6 +54,11 @@ By default a question reaches your devices when the agent turn ends, whether or
51
54
  not you are at the keyboard (`ask_grace_seconds = 0`). Set a positive grace
52
55
  period for a terminal-only answer window first.
53
56
 
57
+ When you answer, the agent acknowledges it before it does anything else, so you
58
+ find out your reply landed and what it set in motion — not just that you sent
59
+ it. Answering from your phone and wondering whether anything happened is the
60
+ whole problem this solves.
61
+
54
62
  For a harness that cannot resume an idle agent turn, `notifai send
55
63
  --reply` blocks and waits for the answer instead.
56
64
 
@@ -202,24 +202,34 @@ export declare function hookRunCommand(deps: CommandDeps, event: string, readStd
202
202
  */
203
203
  export declare function describeHookFailure(err: unknown): string[];
204
204
  export interface AskFlags {
205
+ /** Emit the registration and its turn obligation as one JSON object. */
206
+ json?: boolean;
205
207
  choice?: string[];
206
208
  /** The single question is multi-select: several answers may be chosen. */
207
209
  multi?: boolean;
208
- /** Long-form markdown context; shown in the app, never on the banner. */
209
- detail?: string;
210
+ /** Optional Markdown context appended after the question block. */
211
+ body?: string;
210
212
  /** Raw JSON for a multi-question form; replaces the positional question. */
211
213
  form?: string;
212
- session?: string;
214
+ image?: string[];
215
+ imageAlt?: string[];
216
+ project?: string;
217
+ sessionId?: string;
218
+ sessionLabel?: string;
219
+ }
220
+ export interface BuiltQuestions {
221
+ questions: QuestionT[];
222
+ /** Canonical Markdown body: question block first, optional context second. */
223
+ body: string;
213
224
  }
214
225
  /**
215
- * Turn ask input into the question set that will ride the push. Everything is
216
- * validated here, at registration, because the push happens inside a hook
217
- * where a rejection becomes a stderr note the agent never reads.
226
+ * Turn ask input into questions plus their canonical body. Everything is
227
+ * validated at registration because a later hook failure is easy to miss.
218
228
  */
219
229
  export declare function buildQuestions(flags: AskFlags, question: string | undefined): {
220
230
  ok: true;
221
231
  questions: QuestionT[];
222
- detail?: string;
232
+ body: string;
223
233
  } | {
224
234
  ok: false;
225
235
  error: string;
@@ -229,8 +239,15 @@ export declare function buildQuestions(flags: AskFlags, question: string | undef
229
239
  * can ask in prose and end its turn; the terminal keeps the question to itself
230
240
  * for `ask_grace_seconds` before it reaches any device.
231
241
  */
232
- export declare function askCommand(deps: CommandDeps, question: string | undefined, flags: AskFlags): number;
233
- /** Record the one Agent Acknowledgement associated with a replied-to request. */
242
+ export declare function askCommand(deps: CommandDeps, question: string | undefined, flags: AskFlags): number | Promise<number>;
243
+ /**
244
+ * Record the one Agent Acknowledgement associated with a replied-to request.
245
+ *
246
+ * `--text` is optional here because the acknowledgement is not: an account may
247
+ * turn the agent's written reply off, and the receipt must still be recorded so
248
+ * the user sees that an agent read the answer. The service holds the account's
249
+ * snapshot, so it — not this process — decides whether text was owed.
250
+ */
234
251
  export declare function acknowledgeCommand(deps: CommandDeps, requestId: string, flags: {
235
252
  text?: string;
236
253
  json?: boolean;
@@ -314,7 +331,7 @@ export declare function logsCommand(deps: CommandDeps, flags: LogsFlags): number
314
331
  * Null when the build cannot establish its version; see `./release.js`.
315
332
  */
316
333
  export declare const SKILLS_SOURCE: string | null;
317
- /** Derive a contract-valid project slug from a directory name. */
334
+ /** Derive a contract-valid project slug; init alone needs a non-empty fallback. */
318
335
  export declare function projectSlugFrom(name: string): string;
319
336
  export interface InitFlags {
320
337
  projectId?: string;