@krtclcdy/tersio 2.18.0 → 2.20.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 (44) hide show
  1. package/README.md +2 -2
  2. package/cli/common.js +21 -3
  3. package/cli/currency.js +102 -0
  4. package/cli/dashboard.js +54 -2
  5. package/cli/doctor.js +9 -7
  6. package/cli/install.js +35 -101
  7. package/cli/profile.js +92 -0
  8. package/cli/reset.js +4 -2
  9. package/cli/settings.js +122 -0
  10. package/cli/usage.js +38 -24
  11. package/dashboard/app.js +297 -70
  12. package/dashboard/styles.css +58 -1
  13. package/dashboard/template.html +75 -3
  14. package/extensions/ai-addons-updater/index.ts +377 -0
  15. package/extensions/caveman-session/index.ts +161 -0
  16. package/extensions/combo-toggle/index.ts +217 -0
  17. package/extensions/lib/utils.ts +162 -0
  18. package/extensions/rtk-session/index.ts +164 -0
  19. package/extensions/shared/carbon.ts +123 -0
  20. package/extensions/shared/mode-reinforcement.ts +29 -0
  21. package/extensions/shared/plugin-settings.ts +57 -0
  22. package/extensions/shared/pricing.ts +168 -0
  23. package/extensions/shared/rtk-gain.ts +105 -0
  24. package/extensions/shared/session-state.ts +201 -0
  25. package/extensions/shared/types.ts +85 -0
  26. package/extensions/shared/usage-ledger.ts +406 -0
  27. package/extensions/shared/usage-store.ts +325 -0
  28. package/extensions/tersio-commands/index.ts +110 -0
  29. package/package.json +36 -24
  30. package/tersio.js +8 -1
  31. package/extensions/ai-addons-updater/index.js +0 -331
  32. package/extensions/caveman-session/index.js +0 -152
  33. package/extensions/combo-toggle/index.js +0 -165
  34. package/extensions/lib/utils.js +0 -154
  35. package/extensions/rtk-session/index.js +0 -148
  36. package/extensions/shared/carbon.js +0 -88
  37. package/extensions/shared/mode-reinforcement.js +0 -26
  38. package/extensions/shared/plugin-settings.js +0 -51
  39. package/extensions/shared/pricing.js +0 -163
  40. package/extensions/shared/rtk-gain.js +0 -82
  41. package/extensions/shared/session-state.js +0 -177
  42. package/extensions/shared/types.js +0 -3
  43. package/extensions/shared/usage-ledger.js +0 -333
  44. package/extensions/tersio-commands/index.js +0 -102
@@ -1,102 +0,0 @@
1
- // /tersio root command — status, check, update, gain, usage, help.
2
- // Mode switches live on their own commands (/caveman, /rtk, /combo, and the
3
- // upstream /ponytail): the router keeps no redundant copies. Shared-state
4
- // publishes sync sibling mirrors live, so switches notify and take effect
5
- // next turn — no reload.
6
- import { getSharedComboState, reconcileSharedComboEntries, sessionEntries, } from '../shared/session-state.js';
7
- import os from 'node:os';
8
- import path from 'node:path';
9
- import { appendUsage, readUsage } from '../shared/usage-ledger.js';
10
- import { checkAddonsSummary, runAddonUpdate } from '../ai-addons-updater/index.js';
11
- const HELP = [
12
- '/tersio status — active modes + combo level',
13
- '/tersio check — add-on version check',
14
- '/tersio update <ponytail|rtk|caveman|all> [--dry-run]',
15
- '/tersio gain — savings summary + dashboard hint',
16
- '/tersio usage — ledger report for this machine',
17
- '/tersio help — this table',
18
- 'mode switches: /caveman /rtk /combo (tersio) + /ponytail (upstream)',
19
- ].join('\n');
20
- function statusLine() {
21
- const s = getSharedComboState();
22
- const level = s.level === 'custom' ? 'INACTIVE' : s.level.toUpperCase();
23
- return `tersio — caveman=${s.caveman.toUpperCase()} · rtk=${s.rtk.toUpperCase()} · ponytail=${s.ponytail.toUpperCase()} (combo ${level})`;
24
- }
25
- function usageSummary() {
26
- const rows = readUsage();
27
- if (rows.length === 0)
28
- return 'tersio usage: no ledger yet — run commands first.';
29
- const byKind = {};
30
- for (const r of rows)
31
- byKind[r.kind] = (byKind[r.kind] ?? 0) + 1;
32
- const parts = Object.entries(byKind).map(([k, n]) => `${k}×${n}`);
33
- const last = new Date(rows[rows.length - 1].ts).toISOString();
34
- return `tersio usage: ${rows.length} rows (${parts.join(', ')}), last write ${last}.`;
35
- }
36
- // Gain opens instantaneously in the default browser: export a file://-ready
37
- // snapshot (data inlined, no server to babysit) and open it. Falls back to
38
- // the shell command when export or open fails.
39
- async function openGainDashboard(pi, ctx) {
40
- const file = path.join(os.tmpdir(), `tersio-gain-${Date.now()}.html`);
41
- try {
42
- const exported = await pi.exec?.('tersio', ['gain', '--export', file], { cwd: ctx?.cwd });
43
- if (!exported || exported.code !== 0)
44
- throw new Error((exported?.stderr || 'export failed').trim());
45
- const openCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
46
- await pi.exec?.(openCmd, [file], { cwd: ctx?.cwd });
47
- ctx?.ui?.notify?.(`tersio gain: dashboard opened in your browser.`, 'info');
48
- }
49
- catch (e) {
50
- ctx?.ui?.notify?.(`tersio gain: could not open dashboard (${e.message}). Run 'tersio gain --open' in a shell.`, 'warning');
51
- }
52
- }
53
- export default function tersioCommandsExtension(pi) {
54
- pi.setLabel?.('Tersio unified root command');
55
- pi.registerCommand?.('tersio', {
56
- description: 'Tersio root: status|check|update|gain|usage|help (modes: /caveman /rtk /combo /ponytail)',
57
- handler: async (args, ctx) => {
58
- const parts = String(args || '').trim().toLowerCase().split(/\s+/).filter(Boolean);
59
- const [sub] = [parts[0]];
60
- appendUsage('command', `/tersio ${parts.join(' ')}`.trim());
61
- if (!sub || sub === 'status') {
62
- if (ctx?.hasUI)
63
- reconcileSharedComboEntries(sessionEntries(ctx));
64
- ctx?.ui?.notify?.(statusLine(), 'info');
65
- return;
66
- }
67
- if (sub === 'help') {
68
- ctx?.ui?.notify?.(HELP, 'info');
69
- return;
70
- }
71
- if (sub === 'check') {
72
- await checkAddonsSummary(ctx);
73
- return;
74
- }
75
- if (sub === 'update') {
76
- const dryRun = parts.includes('--dry-run');
77
- const target = parts.filter((p) => p !== '--dry-run' && p !== 'update' && p !== 'tersio').join(' ');
78
- if (!target) {
79
- ctx?.ui?.notify?.('Usage: /tersio update <ponytail|rtk|caveman|all> [--dry-run]', 'warning');
80
- return;
81
- }
82
- await runAddonUpdate(pi, ctx, target, dryRun);
83
- return;
84
- }
85
- if (sub === 'gain') {
86
- await openGainDashboard(pi, ctx);
87
- return;
88
- }
89
- if (sub === 'usage') {
90
- ctx?.ui?.notify?.(usageSummary(), 'info');
91
- return;
92
- }
93
- // Removed mode switches redirect to their own commands so only one
94
- // spelling exists to learn: /caveman, /rtk, /combo, /ponytail.
95
- if (sub === 'caveman' || sub === 'rtk' || sub === 'combo' || sub === 'ponytail') {
96
- ctx?.ui?.notify?.(`Use /${sub} instead — /tersio no longer duplicates mode switches.\n${HELP}`, 'warning');
97
- return;
98
- }
99
- ctx?.ui?.notify?.(`Unknown subcommand: ${sub}.\n${HELP}`, 'warning');
100
- },
101
- });
102
- }