aegis-desktop 1.0.9 → 1.0.10

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/README.md CHANGED
@@ -13,7 +13,7 @@ Prebuilt binaries (AppImage / MSI+NSIS / dmg) ship with each release, and the
13
13
  package is on npm:
14
14
 
15
15
  ```bash
16
- npm install -g aegis-desktop # requires Node 18+
16
+ npm install -g aegis-desktop # requires Node 22+
17
17
  aegis # launch
18
18
  ```
19
19
 
@@ -209,8 +209,15 @@ const DEFAULT_MODEL = 'nexus-brain';
209
209
  * depends on what the user's own daemon happens to have. Both REQUIRE an
210
210
  * explicit model, refused by name instead of silently resolving to
211
211
  * something nobody chose.
212
+ * - 'pro' DOES have a default, but not one this app chooses: a blank model
213
+ * means "the `claude` CLI picks for the subscription", which is what
214
+ * `--model` omitted says (engine.js sends no flag for `default`). Once a
215
+ * model IS stated it must be one of claude-pro.js's PRO_MODELS aliases —
216
+ * the same list the model picker offers — because the child accepts only
217
+ * those four spellings, and a `provider:model` id copied from a byok task
218
+ * would otherwise be handed to `claude --model` and fail there.
212
219
  */
213
- const MODEL_CLASSES = Object.freeze(['aegis', 'byok', 'local']);
220
+ const MODEL_CLASSES = Object.freeze(['aegis', 'byok', 'local', 'pro']);
214
221
 
215
222
  const AEGIS_MODEL_RE = /^(?:nexus|aegis)-brain(?:-(?:smart|neo))?$/;
216
223
  const AEGIS_MODEL_IDS = Object.freeze(['nexus-brain', 'aegis-brain']);
@@ -270,6 +277,34 @@ function modelRefusal(id, cls) {
270
277
  }
271
278
  return '';
272
279
  }
280
+ if (normalized === 'pro') {
281
+ // The subscription route. A blank model is legal and meaningful: engine.js
282
+ // sends no `--model` at all for 'default', so the child resolves the pick
283
+ // itself. Anything STATED must be a PRO_MODELS alias, because those four
284
+ // spellings are exactly what `claude --model` accepts — a byok-style
285
+ // "provider:model" copied between tasks would be handed to the child and
286
+ // fail there, three stages into a drain, with the queue's own file naming
287
+ // something the queue never validated.
288
+ if (!stated) return '';
289
+ // Required lazily: claude-pro.js is a heavy sibling (child spawn, session
290
+ // files) and this module is loaded by queue.js at every CLI start. The
291
+ // require is a plain sibling path with no back-require, so there is no
292
+ // cycle to guard — this is about load cost, not correctness.
293
+ let aliases;
294
+ try {
295
+ aliases = require('./claude-pro.js').PRO_MODELS;
296
+ } catch {
297
+ // If the alias list cannot be read we cannot validate a stated model, and
298
+ // accepting it unvalidated is the exact failure this arm exists to stop.
299
+ return `a pro task's model cannot be checked right now — queue it with no --model to let the claude CLI pick`;
300
+ }
301
+ const ids = (Array.isArray(aliases) ? aliases : []).map((m) => String(m && m.id).trim());
302
+ if (ids.includes(stated.toLowerCase())) return '';
303
+ return (
304
+ `the autonomous queue's Pro class runs the subscription through the claude CLI, ` +
305
+ `which accepts only its own model aliases (${ids.join('/')}); "${stated}" is not one`
306
+ );
307
+ }
273
308
  // normalized === 'local'
274
309
  if (!stated) return 'a local task needs a model — the tag of whatever is pulled into the local daemon';
275
310
  return '';
@@ -594,13 +629,18 @@ function createQueueWorker({
594
629
  */
595
630
  async function runTask(item, { carry = '', commit } = {}) {
596
631
  const cwd = item.cwd || process.cwd();
597
- // Aegis Cloud or nothing — checked BEFORE the turn, not at the server. An
598
- // item whose model is not a pooled tier (a hand-edited queue file, a
599
- // `--model` the CLI accepted before this rule existed, another host's
600
- // older build) would otherwise go out as `class: 'aegis'` with an id the
601
- // pool does not serve: billed work if it happens to be a per-provider
602
- // spelling, an opaque server error otherwise. Failing here names the model
603
- // and the allowed ones, and costs nothing.
632
+ // The task's own (model, class) pair checked BEFORE the turn, not at the
633
+ // server. An item whose model does not belong to its class (a hand-edited
634
+ // queue file, a `--model` the CLI accepted before this rule existed,
635
+ // another host's older build) would otherwise go out under a transport
636
+ // that does not serve it: billed work if it happens to be a per-provider
637
+ // spelling, an opaque server error otherwise, and for 'pro' a `claude
638
+ // --model` that the child rejects. Failing here names the model and the
639
+ // spellings that class accepts, and costs nothing.
640
+ //
641
+ // "Aegis Cloud or nothing" was this comment's old claim, and it stopped
642
+ // being true when byok/local were added (9eeef09) — modelRefusal is what
643
+ // actually enforces the rule now, per class, and it runs for all four.
604
644
  const cls = normalizeClass(item.class);
605
645
  const refusal = modelRefusal(item.model, cls);
606
646
  if (refusal) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aegis-desktop",
3
3
  "productName": "AEGIS Desktop",
4
- "version": "1.0.9",
4
+ "version": "1.0.10",
5
5
  "description": "Thin Electron host for AEGIS — a local chat UI over the shared client/aegis.js transport. Ships transport + UI only; engine logic stays server-side.",
6
6
  "author": {
7
7
  "name": "AEGIS Code",
@@ -58,14 +58,17 @@
58
58
  "test:renderer-fonts": "node test/renderer-fonts.test.mjs",
59
59
  "test:account-key": "node test/account-key.test.mjs"
60
60
  },
61
+ "engines": {
62
+ "node": ">=22.0.0"
63
+ },
61
64
  "dependencies": {
62
65
  "electron-updater": "^6.8.9"
63
66
  },
64
67
  "devDependencies": {
65
- "electron-builder": "^25.1.8",
66
- "electron": "^33.0.0"
68
+ "electron-builder": "^26.15.3",
69
+ "electron": "^44.0.0"
67
70
  },
68
71
  "optionalDependencies": {
69
- "electron": "^33.0.0"
72
+ "electron": "^44.0.0"
70
73
  }
71
74
  }