@raidiant/notifai 11.3.1 → 11.4.0-beta.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.
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: notifai
3
- description: Use Notifai proactively in every agent session that owns User-visible Notification Requests, even when the user does not mention it. The parent owns by default; use it in a worker only when ownership is explicitly delegated. Read guidance.
3
+ description: Use when work needs a User decision, approval, sign-in, credential setup or physical action, or substantial work finishes or fails, even if the User was recently active or does not mention Notifai. For Notification Request owners; parent owns by default, workers only by explicit delegation. Read guidance.
4
4
  ---
5
5
 
6
6
  # Notifai
7
7
 
8
- Use `notifai`; never hand-roll HTTP, hooks, or polling. It owns routing,
9
- retries, and delivery evidence.
8
+ Use `notifai` for routing, retries, and delivery evidence; never hand-roll
9
+ HTTP, hooks, or polling.
10
10
 
11
11
  If missing: `npm install -g @raidiant/notifai`. Pinned
12
12
  `npx --yes @raidiant/notifai@<version>` is only for users refusing a global binary,
@@ -112,9 +112,8 @@ saved config from inventing a Project and never enables one.
112
112
 
113
113
  **Declare the kind that is true**: it decides how insistently the notification lands.
114
114
 
115
- Work needs a User response to continue? Ask an answerable question — even if
116
- blocked. Use one-way blocked only when no User reply would resume the work.
117
- Reporting ready is a response.
115
+ Work needs a User response? [Ask an answerable question](#ask-a-question).
116
+ Use one-way blocked only when no User reply would resume the work.
118
117
 
119
118
  `titles` and `content` guidance own each field. The wire shape:
120
119
 
@@ -160,54 +159,56 @@ the active harness proves the exact current Agent Session.
160
159
 
161
160
  ## Ask a question
162
161
 
163
- A question must be answerable from the notification itself. The positional
164
- question is its Summary (under 240 characters) and supplies the notification
165
- title. Put reasoning in the optional standalone Markdown Body. Offer 2-6 closed choices, one
166
- flag per choice — commas inside a label are literal. A typed answer is always
167
- possible; closed choices appear after pressing and holding the notification.
162
+ Make the question answerable from the notification itself. The positional
163
+ question is its Summary (under 240 characters) and title. Body adds standalone
164
+ Markdown reasoning. Offer 2-6 closed choices, one flag each; commas are literal.
165
+ Typed answers are always possible; closed choices appear after pressing and
166
+ holding the notification.
168
167
 
169
- For both `ask` and `send --reply`, the Summary is the exact answerable question.
170
- Notifai never infers or truncates it from Body.
168
+ For `ask` and `send --reply`, Summary is the exact question, never inferred or
169
+ truncated from Body.
171
170
 
172
171
  ### Default: resume when they answer
173
172
 
174
- When work needs a User response before it can continue, use `ask`. It preserves
175
- the exact return path for the complete answer window without making the
176
- foreground command its owner:
173
+ When work you own or coordinate needs a User response, use `notifai ask` in the
174
+ same turn as its conversation question, even while other work continues or after
175
+ recent User activity; conversation alone misses an away User.
176
+ Ask for safe setup or readiness, never credentials. Harness permission prompts
177
+ and interactive pickers stay in the harness.
178
+
179
+ `ask` keeps the exact return path for the complete answer window:
177
180
 
178
181
  ```bash
179
182
  notifai ask "Which environment should I roll out to?" \
180
183
  --choice Staging --choice Production --choice Cancel
181
184
  ```
182
185
 
183
- Add `--json` for choice ids and the `question_id`.
186
+ `--json` returns choice ids and `question_id`.
184
187
 
185
188
  `registered: true` is local only. It has not yet been submitted as a
186
189
  Notification Request and has no Provider Acceptance. Never call a question sent
187
- or delivered from registration alone. Settlement preserves its `question_id` and adds a
188
- `request_id`. Inspect without changing it:
190
+ or delivered from registration alone. Settlement adds `request_id`, keeping
191
+ `question_id`. Inspect:
189
192
 
190
193
  ```bash
191
194
  notifai status <question_id> --json
192
195
  ```
193
196
 
194
- State is `local`, `frozen`, `live`, `answered`, `withdrawn`, or `retired`;
195
- promoted questions also show downstream evidence.
197
+ States: `local`, `frozen`, `live`, `answered`, `withdrawn`, `retired`.
196
198
 
197
- **Registering is not the end of the turn.** In that same turn, ask the question
198
- in the conversation and say what each answer will make you do, then end your
199
- turn to start submission. Ordinary sends need no turn boundary. Continue
200
- independent work in later turns; preserve supervision.
199
+ **Registering is not the end of the turn.** Ask in plain conversational text,
200
+ say what each answer will make you do, then end the turn to start submission.
201
+ A second harness form can remain pending after a reply. Follow
202
+ higher-priority rules; never claim either path retires the other.
201
203
 
202
- **Never say where the answer must arrive:** not "tell me here" or "type it at
203
- this prompt". The route is the harness's concern.
204
+ **Never say where the answer must arrive** ("tell me here"). The harness owns routing.
204
205
 
205
- Other surfaces: `--multi` combines answers; `--body`/`--body-file` adds Body;
206
- `--image`/`--image-alt` adds evidence; `--form <path|->` groups up to 10
207
- questions and requires a set-level `summary`.
206
+ Use `--multi` for combined answers, `--body`/`--body-file` for Body,
207
+ `--image`/`--image-alt` for evidence, or `--form <path|->` for up to 10 questions
208
+ with a set-level `summary`.
208
209
 
209
- Keep independent questions as separate `ask` calls. Retire a registration
210
- that is obsolete or that they answer in the conversation with
210
+ Register independent questions separately. Retire an obsolete registration or
211
+ one they answer in the conversation with
211
212
  `notifai close <question_id>` or `notifai close --pending`.
212
213
 
213
214
  Keep every ID after a timeout or unavailable route. Inspect the original with
@@ -249,10 +250,9 @@ resume later. Never create a duplicate. On exit 0, act on the answer.
249
250
 
250
251
  ## When the answer arrives
251
252
 
252
- The latest reply is the user's current word: a later one corrects an earlier
253
- one, and a typed answer arriving in parts is read together, in order. A relayed
254
- answer reaches you as the chosen label's text; `notifai replies <request_id>
255
- --json` has the stable choice ids.
253
+ The latest reply is the user's current word: later choices correct earlier
254
+ ones; typed parts are read together in order. A relayed answer uses the chosen
255
+ label; `notifai replies <request_id> --json` has stable choice ids.
256
256
 
257
257
  Questions normally remain answerable for a day. When resuming without a relayed
258
258
  answer, inspect the original `question_id`. If it is lost, list outstanding
@@ -1,7 +1,7 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
- import { compareVersions, isSemVer } from './version.js';
4
+ import { compareReleasePrecedence, isSemVer } from './version.js';
5
5
  const PACKAGE_ROOT = fileURLToPath(new URL('../', import.meta.url));
6
6
  const CHANGELOG_LIMIT = 16_000;
7
7
  export function releaseNotesUrl(version) {
@@ -18,9 +18,9 @@ export function installedChangelog(version, from, root = PACKAGE_ROOT) {
18
18
  const heading = /^## \[([^\]]+)\]/m.exec(section);
19
19
  if (heading === null || version === null)
20
20
  return false;
21
- const relative = compareVersions(heading[1], version);
21
+ const relative = compareReleasePrecedence(heading[1], version);
22
22
  return (relative === 'before' || relative === 'equal') &&
23
- (from === undefined || compareVersions(heading[1], from) === 'after');
23
+ (from === undefined || compareReleasePrecedence(heading[1], from) === 'after');
24
24
  });
25
25
  const text = sections.join('').trim();
26
26
  return { version, from: from ?? null, path: file, text: text.slice(0, CHANGELOG_LIMIT),
@@ -1 +1 @@
1
- {"version":3,"file":"update-handoff.js","sourceRoot":"","sources":["../src/update-handoff.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update-handoff.js","sourceRoot":"","sources":["../src/update-handoff.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -19,4 +19,22 @@ export function parseVersion(value: string): readonly [number, number, number] |
19
19
  export function compareVersions(left: string, right: string): VersionComparison;
20
20
  /** @param {string} value */
21
21
  export function isSemVer(value: string): boolean;
22
+ /**
23
+ * Order two published releases by full SemVer 2.0.0 precedence: a prerelease
24
+ * sorts before its stable release (`1.0.0-beta.2` < `1.0.0`), and build
25
+ * metadata is ignored. Use this for release ordering only; capability floors
26
+ * keep `compareVersions`. Anything that is not strict SemVer is `unparseable`
27
+ * and the caller chooses its safe posture.
28
+ *
29
+ * @param {string} left
30
+ * @param {string} right
31
+ * @returns {VersionComparison}
32
+ */
33
+ export function compareReleasePrecedence(left: string, right: string): VersionComparison;
34
+ /**
35
+ * Whether a strict SemVer release carries a prerelease, such as a beta.
36
+ *
37
+ * @param {string} value
38
+ */
39
+ export function isPrerelease(value: string): boolean;
22
40
  export type VersionComparison = "before" | "equal" | "after" | "unparseable";
package/dist/version.js CHANGED
@@ -1,4 +1,5 @@
1
- const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
1
+ const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
2
+ const NUMERIC_IDENTIFIER = /^\d+$/;
2
3
  const ORDERED_VERSION = /^v?(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/;
3
4
  /** @typedef {'before' | 'equal' | 'after' | 'unparseable'} VersionComparison */
4
5
  /**
@@ -48,4 +49,84 @@ export function compareVersions(left, right) {
48
49
  export function isSemVer(value) {
49
50
  return SEMVER.test(value);
50
51
  }
52
+ /**
53
+ * Order digit strings without leading zeros (SemVer forbids them), so values
54
+ * beyond Number.MAX_SAFE_INTEGER still compare exactly.
55
+ *
56
+ * @param {string} left
57
+ * @param {string} right
58
+ * @returns {-1 | 0 | 1}
59
+ */
60
+ function compareDigits(left, right) {
61
+ if (left.length !== right.length)
62
+ return left.length < right.length ? -1 : 1;
63
+ return left === right ? 0 : left < right ? -1 : 1;
64
+ }
65
+ /**
66
+ * SemVer 2.0.0 section 11: numeric identifiers compare numerically and rank
67
+ * below alphanumeric ones; a longer list wins when every shared field is equal.
68
+ *
69
+ * @param {readonly string[]} left
70
+ * @param {readonly string[]} right
71
+ * @returns {-1 | 0 | 1}
72
+ */
73
+ function comparePrerelease(left, right) {
74
+ for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
75
+ const a = left[index];
76
+ const b = right[index];
77
+ if (a === undefined)
78
+ return -1;
79
+ if (b === undefined)
80
+ return 1;
81
+ const aNumeric = NUMERIC_IDENTIFIER.test(a);
82
+ const bNumeric = NUMERIC_IDENTIFIER.test(b);
83
+ const order = aNumeric && bNumeric
84
+ ? compareDigits(a, b)
85
+ : aNumeric !== bNumeric
86
+ ? (aNumeric ? -1 : 1)
87
+ : a === b ? 0 : a < b ? -1 : 1;
88
+ if (order !== 0)
89
+ return order;
90
+ }
91
+ return 0;
92
+ }
93
+ /**
94
+ * Order two published releases by full SemVer 2.0.0 precedence: a prerelease
95
+ * sorts before its stable release (`1.0.0-beta.2` < `1.0.0`), and build
96
+ * metadata is ignored. Use this for release ordering only; capability floors
97
+ * keep `compareVersions`. Anything that is not strict SemVer is `unparseable`
98
+ * and the caller chooses its safe posture.
99
+ *
100
+ * @param {string} left
101
+ * @param {string} right
102
+ * @returns {VersionComparison}
103
+ */
104
+ export function compareReleasePrecedence(left, right) {
105
+ const a = SEMVER.exec(left);
106
+ const b = SEMVER.exec(right);
107
+ if (a === null || b === null)
108
+ return 'unparseable';
109
+ for (let index = 1; index <= 3; index += 1) {
110
+ const order = compareDigits(/** @type {string} */ (a[index]), /** @type {string} */ (b[index]));
111
+ if (order !== 0)
112
+ return order < 0 ? 'before' : 'after';
113
+ }
114
+ const aPrerelease = a[4];
115
+ const bPrerelease = b[4];
116
+ if (aPrerelease === undefined || bPrerelease === undefined) {
117
+ if (aPrerelease === bPrerelease)
118
+ return 'equal';
119
+ return aPrerelease === undefined ? 'after' : 'before';
120
+ }
121
+ const order = comparePrerelease(aPrerelease.split('.'), bPrerelease.split('.'));
122
+ return order === 0 ? 'equal' : order < 0 ? 'before' : 'after';
123
+ }
124
+ /**
125
+ * Whether a strict SemVer release carries a prerelease, such as a beta.
126
+ *
127
+ * @param {string} value
128
+ */
129
+ export function isPrerelease(value) {
130
+ return SEMVER.exec(value)?.[4] !== undefined;
131
+ }
51
132
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.js"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,iLAAiL,CAAA;AAChM,MAAM,eAAe,GAAG,oCAAoC,CAAA;AAE5D,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAK;IAChC,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACzC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC/B,MAAM,MAAM,GAAG,gDAAgD,CAAC,CAAC;QAC/D,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAChB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACjB,CAAC,CAAA;IACF,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;AAC3D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,IAAI,EAAE,KAAK;IACzC,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAC7B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,aAAa,CAAA;IAClD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;QACzB,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;QAC1B,IAAI,QAAQ,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,aAAa,CAAA;QAC3E,IAAI,QAAQ,KAAK,SAAS;YAAE,SAAQ;QACpC,OAAO,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAA;IAClD,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,QAAQ,CAAC,KAAK;IAC5B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAC3B,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.js"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raidiant/notifai",
3
- "version": "11.3.1",
3
+ "version": "11.4.0-beta.2",
4
4
  "type": "module",
5
5
  "description": "Send native device notifications from agents and local programs",
6
6
  "bin": {
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "dependencies": {
14
14
  "@clack/prompts": "^1.7.0",
15
- "@raidiant/notifai-protocol": "8.0.2",
15
+ "@raidiant/notifai-protocol": "8.0.3",
16
16
  "commander": "^14.0.0",
17
17
  "picocolors": "^1.1.1",
18
18
  "smol-toml": "^1.4.0"