sideby 0.14.0 → 0.16.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 (66) hide show
  1. package/README.md +1 -0
  2. package/dist/build.json +1 -1
  3. package/dist/src/cli/commands.d.ts +7 -0
  4. package/dist/src/cli/commands.js +259 -9
  5. package/dist/src/cli/json-schemas.js +109 -2
  6. package/dist/src/cli/main.js +30 -6
  7. package/dist/src/core/config.d.ts +1 -0
  8. package/dist/src/core/config.js +8 -2
  9. package/dist/src/core/local-build.d.ts +63 -0
  10. package/dist/src/core/local-build.js +189 -0
  11. package/dist/src/core/skill-check.d.ts +14 -0
  12. package/dist/src/core/skill-check.js +29 -3
  13. package/dist/src/core/update.d.ts +73 -1
  14. package/dist/src/core/update.js +155 -23
  15. package/dist/src/panel/handler.d.ts +12 -1
  16. package/dist/src/panel/handler.js +84 -5
  17. package/dist/src/panel/i18n.d.ts +125 -5
  18. package/dist/src/panel/i18n.js +280 -40
  19. package/dist/src/panel/page-logic.d.ts +41 -0
  20. package/dist/src/panel/page-logic.js +46 -0
  21. package/dist/src/panel/page-script.js +616 -162
  22. package/dist/src/panel/page-styles.js +74 -23
  23. package/dist/src/panel/page.js +3 -0
  24. package/dist/src/runtime.d.ts +2 -0
  25. package/package.json +3 -2
  26. package/schemas/alias.json +1 -1
  27. package/schemas/app-install.json +1 -1
  28. package/schemas/app-uninstall.json +1 -1
  29. package/schemas/browser-open.json +1 -1
  30. package/schemas/browser-switch.json +1 -1
  31. package/schemas/browser.json +1 -1
  32. package/schemas/config.json +15 -1
  33. package/schemas/desktop-remove.json +1 -1
  34. package/schemas/desktop.json +1 -1
  35. package/schemas/doctor.json +1 -1
  36. package/schemas/error.json +1 -1
  37. package/schemas/families.json +1 -1
  38. package/schemas/handoff-disable.json +1 -1
  39. package/schemas/handoff-enable.json +1 -1
  40. package/schemas/handoff-ready.json +1 -1
  41. package/schemas/handoff-setup.json +1 -1
  42. package/schemas/handoff-status.json +282 -1
  43. package/schemas/handoff-teardown.json +1 -1
  44. package/schemas/list.json +6 -1
  45. package/schemas/local.json +165 -0
  46. package/schemas/model.json +1 -1
  47. package/schemas/new.json +1 -1
  48. package/schemas/next.json +1 -1
  49. package/schemas/order.json +148 -0
  50. package/schemas/pin.json +126 -0
  51. package/schemas/plugins.json +1 -1
  52. package/schemas/quota-check.json +88 -0
  53. package/schemas/quota-setup.json +1 -1
  54. package/schemas/quota-teardown.json +1 -1
  55. package/schemas/quota.json +1 -1
  56. package/schemas/remote-control.json +1 -1
  57. package/schemas/tune-change.json +1 -1
  58. package/schemas/tune.json +1 -1
  59. package/schemas/unpin.json +126 -0
  60. package/schemas/update-auto.json +84 -0
  61. package/schemas/update.json +79 -1
  62. package/skills/sideby/SKILL.md +8 -3
  63. package/skills/sideby/references/handoff.md +8 -0
  64. package/skills/sideby/references/panel.md +28 -0
  65. package/skills/sideby/references/quota.md +6 -0
  66. package/skills/sideby/references/update.md +15 -2
@@ -181,6 +181,27 @@ export function sortAccounts(list, mode, now, order) {
181
181
  out.sort((x, y) => pressure(y) - pressure(x) || byName(x, y));
182
182
  return out;
183
183
  }
184
+ /**
185
+ * Whether an Account is pinned (spec §3.25): its name is in `pinned`, or, for a Same Login, the name of any of its
186
+ * directories, so the login is pinned as a whole.
187
+ */
188
+ export function pinnedIn(a, pinned) {
189
+ return (pinned.includes(a.name) || (a.sameLogin ?? []).some((r) => pinned.includes(r.slice(r.indexOf(':') + 1))));
190
+ }
191
+ /**
192
+ * Pinned Accounts first (spec §3.25): the names in `pinned`, in that order, then the rest in the order they came.
193
+ * A Same Login follows any of its pinned directories, so it stays together. Names no longer there are simply not met.
194
+ */
195
+ export function withPinned(list, pinned) {
196
+ if (!pinned?.length)
197
+ return list.slice();
198
+ const top = [];
199
+ for (const n of pinned)
200
+ for (const a of list)
201
+ if (!top.includes(a) && pinnedIn(a, [n]))
202
+ top.push(a);
203
+ return top.concat(list.filter((a) => !top.includes(a)));
204
+ }
184
205
  /**
185
206
  * The sorted list with each Same Login together (spec §3.21): an Account, or the shown members of one login, in
186
207
  * order, at the place of its first member. A login with one shown member stays a plain Account.
@@ -336,6 +357,31 @@ export function panelHint(hint, fixable, action) {
336
357
  return hint;
337
358
  return hint.replace(/run `sideby doctor --fix`/g, (_m, at) => at === 0 ? action.charAt(0).toUpperCase() + action.slice(1) : action);
338
359
  }
360
+ /**
361
+ * Whether the Panel fixes Finding `f` with a button of its own: a sideby skill behind this version while the
362
+ * Update plan says sideby may update it (`skillUpdatable`). Such Findings stay out of the prompt for an AI agent.
363
+ */
364
+ export function panelFixes(f, skillUpdatable) {
365
+ return skillUpdatable && f.code === 'skill.outdated';
366
+ }
367
+ /**
368
+ * The prompt "Copy for AI" puts on the clipboard: `words.lead`, then each Finding that has no automatic fix
369
+ * (numbered, with its account, item, level, message and hint), then `words.fixFirst` when some Findings do have
370
+ * one, then `words.check`. Empty when every Finding has an automatic fix. `words.hint` labels a hint line.
371
+ */
372
+ export function fixPrompt(findings, words) {
373
+ const manual = findings.filter((f) => !f.fixable);
374
+ if (!manual.length)
375
+ return '';
376
+ const items = manual.map((f, i) => {
377
+ const lines = [i + 1 + '. [' + f.level + '] ' + f.account + ' · ' + f.item, ' ' + f.message];
378
+ if (f.hint)
379
+ lines.push(' ' + words.hint + f.hint);
380
+ return lines.join('\n');
381
+ });
382
+ const tail = manual.length < findings.length ? [words.fixFirst, words.check] : [words.check];
383
+ return [words.lead, items.join('\n\n'), ...tail].join('\n\n');
384
+ }
339
385
  /**
340
386
  * A short command to offer for a new Account `name` of a Family, from the config aliases of its existing Accounts:
341
387
  * an alias that is a prefix plus its Account's name (`cc001` for `claude:001`) gives the prefix, the most common