@cortexkit/common-auth 0.2.3 → 0.2.5

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 (44) hide show
  1. package/dist/auth-menu/accounts.d.ts +88 -0
  2. package/dist/auth-menu/accounts.js +401 -0
  3. package/dist/auth-menu/ansi.d.ts +24 -0
  4. package/dist/auth-menu/ansi.js +67 -0
  5. package/dist/auth-menu/confirm.d.ts +7 -0
  6. package/dist/auth-menu/confirm.js +21 -0
  7. package/dist/auth-menu/doctor.d.ts +52 -0
  8. package/dist/auth-menu/doctor.js +81 -0
  9. package/dist/auth-menu/index.d.ts +17 -0
  10. package/dist/auth-menu/index.js +12 -0
  11. package/dist/auth-menu/login.d.ts +47 -0
  12. package/dist/auth-menu/login.js +63 -0
  13. package/dist/auth-menu/menu.d.ts +59 -0
  14. package/dist/auth-menu/menu.js +73 -0
  15. package/dist/auth-menu/opencode-v1.d.ts +49 -0
  16. package/dist/auth-menu/opencode-v1.js +47 -0
  17. package/dist/auth-menu/select.d.ts +21 -0
  18. package/dist/auth-menu/select.js +153 -0
  19. package/dist/auth-menu/terminal.d.ts +43 -0
  20. package/dist/auth-menu/terminal.js +19 -0
  21. package/dist/cachekeep/index.d.ts +4 -0
  22. package/dist/cachekeep/index.js +2 -0
  23. package/dist/cachekeep/manager.d.ts +214 -0
  24. package/dist/cachekeep/manager.js +424 -0
  25. package/dist/cachekeep/window.d.ts +13 -0
  26. package/dist/cachekeep/window.js +33 -0
  27. package/dist/claustrum/index.d.ts +1 -0
  28. package/dist/claustrum/index.js +2 -0
  29. package/dist/commands/index.d.ts +1 -0
  30. package/dist/commands/index.js +2 -0
  31. package/dist/dump/index.d.ts +90 -0
  32. package/dist/dump/index.js +292 -0
  33. package/dist/opencode2/index.d.ts +1 -0
  34. package/dist/opencode2/index.js +2 -0
  35. package/dist/store/errors.d.ts +2 -2
  36. package/dist/store/hooks.d.ts +1 -1
  37. package/dist/store/index.d.ts +1 -1
  38. package/dist/store/mutate.d.ts +3 -2
  39. package/dist/store/mutate.js +2 -1
  40. package/dist/store/pool.d.ts +8 -1
  41. package/dist/store/pool.js +2 -1
  42. package/dist/store/rows.d.ts +28 -1
  43. package/dist/store/rows.js +93 -0
  44. package/package.json +37 -3
@@ -1,3 +1,4 @@
1
+ import { PoolOperationError } from './errors.js';
1
2
  import { assertNotInsideHook, runInsideHook } from './hooks.js';
2
3
  import { DUPLICATE_IDENTITY_REASON, disableIdentityDuplicates, disableIn, recordIdentityIn, } from './identity.js';
3
4
  import { notReadyError, readPool, runOperation, withTransaction, } from './mutate.js';
@@ -355,6 +356,98 @@ function hasStateAccount(state, id) {
355
356
  const accounts = state.accounts;
356
357
  return isRecord(accounts) && Object.hasOwn(accounts, id);
357
358
  }
359
+ /** The id a roster row carries, or undefined for a row that names none. */
360
+ function rosterIdOf(raw) {
361
+ return isRecord(raw) && typeof raw.id === 'string' ? raw.id : undefined;
362
+ }
363
+ /**
364
+ * Why `ids` is not an order of this roster: it must name every distinct
365
+ * roster id exactly once and nothing else.
366
+ */
367
+ function orderProblem(roster, ids) {
368
+ if (!Array.isArray(ids))
369
+ return 'ids must be an array of roster ids';
370
+ const rosterIds = new Set();
371
+ for (const raw of roster) {
372
+ const id = rosterIdOf(raw);
373
+ if (id !== undefined)
374
+ rosterIds.add(id);
375
+ }
376
+ const given = new Set();
377
+ for (const id of ids) {
378
+ if (typeof id !== 'string')
379
+ return 'ids must be an array of roster ids';
380
+ if (given.has(id))
381
+ return `id ${id} appears more than once`;
382
+ if (!rosterIds.has(id))
383
+ return `id ${id} is not in the roster`;
384
+ given.add(id);
385
+ }
386
+ const missing = [...rosterIds].filter((id) => !given.has(id));
387
+ if (missing.length > 0)
388
+ return `the order leaves out roster id(s) ${missing.join(', ')}`;
389
+ return undefined;
390
+ }
391
+ /**
392
+ * The roster in the new order. Every roster row is kept as the same object,
393
+ * so its serialized bytes are unchanged. Rows that carry an id fill the
394
+ * positions such rows held before, in the order of `ids`; a second row with
395
+ * an already-seen id (invalid, but preserved) travels right after the first.
396
+ * A row that names no id cannot be ordered by id, so it keeps its position.
397
+ */
398
+ function reorderedRoster(roster, ids) {
399
+ const byId = new Map();
400
+ for (const raw of roster) {
401
+ const id = rosterIdOf(raw);
402
+ if (id === undefined)
403
+ continue;
404
+ const group = byId.get(id);
405
+ if (group)
406
+ group.push(raw);
407
+ else
408
+ byId.set(id, [raw]);
409
+ }
410
+ const sequence = ids.flatMap((id) => byId.get(id) ?? []);
411
+ let next = 0;
412
+ return roster.map((raw) => rosterIdOf(raw) === undefined ? raw : sequence[next++]);
413
+ }
414
+ /**
415
+ * Sets the roster order in one config write. `ids` must name every roster id
416
+ * exactly once; anything else refuses (`invalid-order`) before writing. The
417
+ * roster rows, the per-row entries and the state file are left as they are:
418
+ * only the order of the legacy `accounts` array changes, which older readers
419
+ * load as is. It takes the extra locks, then the store locks, and no row or
420
+ * provider-wide lock, since no row's credential, identity or quota changes.
421
+ * An order equal to the current one writes nothing.
422
+ */
423
+ export async function reorderRows(rt, ids, options = {}) {
424
+ assertNotInsideHook('reorder');
425
+ const { ctx } = rt;
426
+ const onFailure = options.onFailure;
427
+ return runOperation(ctx, 'reorder', undefined, onFailure && ((_rowId, error) => onFailure(error)), async (locks, progress) => {
428
+ for (const extra of options.extraLocks ?? [])
429
+ await locks.acquire(extra);
430
+ return withTransaction(ctx, locks, progress, { operation: 'reorder', rowId: undefined }, async (tx) => {
431
+ const roster = tx.roster();
432
+ const problem = orderProblem(roster, ids);
433
+ if (problem)
434
+ throw new PoolOperationError({
435
+ operation: 'reorder',
436
+ phase: 'before-first-write',
437
+ retryable: false,
438
+ kind: 'invalid-order',
439
+ message: problem,
440
+ });
441
+ const order = [...ids];
442
+ const next = reorderedRoster(roster, order);
443
+ if (next.every((raw, index) => raw === roster[index]))
444
+ return { ids: order, outcome: 'unchanged' };
445
+ tx.config.accounts = next;
446
+ await tx.commitConfig();
447
+ return { ids: order, outcome: 'reordered' };
448
+ });
449
+ });
450
+ }
358
451
  export async function recordRowIdentity(rt, id, identity, options = {}) {
359
452
  assertNotInsideHook('recordIdentity');
360
453
  return runOperation(rt.ctx, 'recordIdentity', id, options.onFailure, async (locks, progress) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cortexkit/common-auth",
3
- "version": "0.2.3",
4
- "description": "Shared plumbing for the CortexKit auth plugins: loopback RPC, file locks and atomic writes, logger, sidebar state file, TUI preferences and TUI build.",
3
+ "version": "0.2.5",
4
+ "description": "Shared code for the CortexKit auth plugins: account pool, quota and routing, commands and auth menu, OpenCode 2 hooks, Claustrum custody, and plumbing (loopback RPC, file locks, logger, sidebar state, TUI preferences and build).",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -51,6 +51,30 @@
51
51
  "./routing": {
52
52
  "types": "./dist/routing/index.d.ts",
53
53
  "import": "./dist/routing/index.js"
54
+ },
55
+ "./commands": {
56
+ "types": "./dist/commands/index.d.ts",
57
+ "import": "./dist/commands/index.js"
58
+ },
59
+ "./auth-menu": {
60
+ "types": "./dist/auth-menu/index.d.ts",
61
+ "import": "./dist/auth-menu/index.js"
62
+ },
63
+ "./opencode2": {
64
+ "types": "./dist/opencode2/index.d.ts",
65
+ "import": "./dist/opencode2/index.js"
66
+ },
67
+ "./claustrum": {
68
+ "types": "./dist/claustrum/index.d.ts",
69
+ "import": "./dist/claustrum/index.js"
70
+ },
71
+ "./cachekeep": {
72
+ "types": "./dist/cachekeep/index.d.ts",
73
+ "import": "./dist/cachekeep/index.js"
74
+ },
75
+ "./dump": {
76
+ "types": "./dist/dump/index.d.ts",
77
+ "import": "./dist/dump/index.js"
54
78
  }
55
79
  },
56
80
  "files": [
@@ -73,7 +97,9 @@
73
97
  "peerDependencies": {
74
98
  "@opentui/core": ">=0.5.12",
75
99
  "@opentui/solid": ">=0.5.12",
76
- "solid-js": "1.9.12"
100
+ "solid-js": "1.9.12",
101
+ "@cortexkit/claustrum-client": ">=0.5.0",
102
+ "@opencode/plugin": ">=2.0.21"
77
103
  },
78
104
  "peerDependenciesMeta": {
79
105
  "@opentui/core": {
@@ -84,10 +110,18 @@
84
110
  },
85
111
  "solid-js": {
86
112
  "optional": true
113
+ },
114
+ "@cortexkit/claustrum-client": {
115
+ "optional": true
116
+ },
117
+ "@opencode/plugin": {
118
+ "optional": true
87
119
  }
88
120
  },
89
121
  "devDependencies": {
90
122
  "@biomejs/biome": "2.5.14",
123
+ "@cortexkit/claustrum-client": "0.5.0",
124
+ "@opencode/plugin": "2.0.21",
91
125
  "@opentui/core": ">=0.5.12",
92
126
  "@opentui/solid": ">=0.5.12",
93
127
  "@tsconfig/bun": "1.0.11",