@krtclcdy/tersio 2.0.0 → 2.0.1
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
|
@@ -61,16 +61,18 @@ User-level installs also register the package in `~/.omp/plugins` (visible in OM
|
|
|
61
61
|
|
|
62
62
|
## Benchmarks
|
|
63
63
|
|
|
64
|
-
Measured
|
|
64
|
+
Measured savings against the same workload without the modes. Token counts are real `o200k_base` BPE tokens (js-tiktoken), not chars÷4 estimates. Sample protocol, per-sample data, and caveats in [BENCHMARK.md](./BENCHMARK.md).
|
|
65
65
|
|
|
66
|
-
|
|
|
67
|
-
|
|
68
|
-
|
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
66
|
+
| Measured surface (n) | Baseline → Tersio | Δ |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| Terse reply, caveman lite — BPE tok (3 samples, p50) | 146 → 73 tok | **−52.6%** |
|
|
69
|
+
| Terse reply, caveman full — BPE tok (3 samples, p50) | 154 → 58 tok | **−62.3%** |
|
|
70
|
+
| Terse reply, caveman ultra — BPE tok (3 samples, p50) | 146 → 33 tok | **−78.6%** |
|
|
71
|
+
| Code diff, ponytail minimal-ladder — BPE tok (2 tasks) | 261–481 → 108–143 tok | **−58.6…−70.3%** |
|
|
72
|
+
| Shell output, rtk — `git status` — BPE tok | 32 → 21 tok | **−34.4%** |
|
|
73
|
+
| Shell output, rtk — repo `grep` — BPE tok | 537 → 469 tok | **−12.7%** |
|
|
74
|
+
|
|
75
|
+
Break-even math, balanced preset (caveman full + rtk + ponytail): `⌈overhead ÷ saving-per-turn⌉ = ⌈480 ÷ 306⌉ = 2 turns`, where a mixed turn (reply + `git status`-class command + code task) costs 944 tok baseline vs 638 tok with Tersio — a 0.68× ratio. Every turn after turn 2 nets ≈ −32%. RTK keeps diffs and failing-test output exact by design (−0.4% and −1.5% there), concentrating savings where noise lives.
|
|
74
76
|
|
|
75
77
|
## CLI
|
|
76
78
|
|
|
@@ -80,7 +82,7 @@ Measured before/after — real `o200k_base` token counts, samples and run protoc
|
|
|
80
82
|
| `tersio update` | Refresh from the latest release |
|
|
81
83
|
| `tersio reinstall` | Fresh install, preserving the Ponytail package |
|
|
82
84
|
| `tersio doctor` | Check OMP, extension, Ponytail, and RTK health |
|
|
83
|
-
| `tersio uninstall` | Remove extensions and
|
|
85
|
+
| `tersio uninstall` | Remove extensions, registration, and the Ponytail plugin (`--keep-ponytail` keeps Ponytail; `--remove-rtk` also removes the RTK binary) |
|
|
84
86
|
| `tersio version` | Print version |
|
|
85
87
|
|
|
86
88
|
Flags: `--dry-run`, `--yes`/`-y`, `--verbose`, `--scope`, `--combo-default`/`--caveman-default`/`--rtk-default`/`--ponytail-default`. Legacy `--doctor` / `--uninstall` forms still work.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
-
import { asPromptArray, getSharedComboState, isComboPresetActive, isOmpSubagentPrompt, lastCustomValue, normalizeInputCommand, normalizeMode, paintStatusBar, sessionEntries, setSharedComboMode } from '../shared/session-state.js';
|
|
4
|
+
import { asPromptArray, getSharedComboState, isComboPresetActive, isOmpSubagentPrompt, lastCustomValue, normalizeInputCommand, normalizeMode, paintStatusBar, reconcileSharedComboEntries, sessionEntries, setSharedComboMode } from '../shared/session-state.js';
|
|
5
5
|
import { readCavemanDefault } from '../shared/plugin-settings.js';
|
|
6
6
|
const CAVERN_DIR = dirname(fileURLToPath(import.meta.url));
|
|
7
7
|
const RULE_PATH = join(CAVERN_DIR, 'rule.md');
|
|
@@ -96,6 +96,11 @@ export default function cavemanSessionExtension(pi) {
|
|
|
96
96
|
});
|
|
97
97
|
function restoreMode(ctx) {
|
|
98
98
|
const entries = sessionEntries(ctx);
|
|
99
|
+
// Publish the persisted combo state (incl. combo-level) before painting:
|
|
100
|
+
// bar suppression reads the in-process bridge, which is empty in a fresh
|
|
101
|
+
// host until the combo extension reconciles — and its reconcile is
|
|
102
|
+
// UI-gated. Deriving it here makes suppression independent of load order.
|
|
103
|
+
reconcileSharedComboEntries(entries);
|
|
99
104
|
// Persisted session state wins; a fresh session falls back to the
|
|
100
105
|
// installer/user-configured default (off unless configured).
|
|
101
106
|
const persisted = resolveMode(entries, '');
|
|
@@ -29,7 +29,6 @@ function loadPonytailInstructions(mode) {
|
|
|
29
29
|
}
|
|
30
30
|
export default function comboToggleExtension(pi) {
|
|
31
31
|
pi.setLabel?.('Combo session toggle (all 3 add-ons)');
|
|
32
|
-
let currentState = getSharedComboState();
|
|
33
32
|
let lastCtx = undefined;
|
|
34
33
|
function syncStatus(ctx) {
|
|
35
34
|
if (ctx)
|
|
@@ -43,11 +42,14 @@ export default function comboToggleExtension(pi) {
|
|
|
43
42
|
c.ui.setStatus('combo', undefined);
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
45
|
+
// Read the live bridge, not cached extension state: sibling extensions
|
|
46
|
+
// reconcile it from persisted entries before this one runs.
|
|
47
|
+
const state = getSharedComboState();
|
|
46
48
|
const theme = c.ui.theme;
|
|
47
|
-
const c0 =
|
|
48
|
-
const r =
|
|
49
|
-
const p =
|
|
50
|
-
const lvl =
|
|
49
|
+
const c0 = state.caveman.toUpperCase();
|
|
50
|
+
const r = state.rtk.toUpperCase();
|
|
51
|
+
const p = state.ponytail.toUpperCase();
|
|
52
|
+
const lvl = state.level.toUpperCase();
|
|
51
53
|
const label = `combo ${lvl}: 🪨caveman=${c0} ⚡rtk=${r} 🦥ponytail=${p}`;
|
|
52
54
|
c.ui.setStatus('combo', theme?.fg ? `${theme.fg('accent', '🧩')} ${theme.fg('muted', label)}` : `🧩 ${label}`);
|
|
53
55
|
// Clobber any sibling bars another extension may have painted in a race
|
|
@@ -67,13 +69,12 @@ export default function comboToggleExtension(pi) {
|
|
|
67
69
|
pi.appendEntry?.('combo-level', { level });
|
|
68
70
|
}
|
|
69
71
|
function useState(state, ctx) {
|
|
70
|
-
currentState = state;
|
|
71
72
|
syncStatus(ctx);
|
|
72
73
|
return state;
|
|
73
74
|
}
|
|
74
75
|
function reconcile(ctx) {
|
|
75
76
|
if (!ctx?.hasUI)
|
|
76
|
-
return
|
|
77
|
+
return getSharedComboState();
|
|
77
78
|
return useState(reconcileSharedComboEntries(sessionEntries(ctx)), ctx);
|
|
78
79
|
}
|
|
79
80
|
function listen(ctx) {
|
|
@@ -109,7 +110,7 @@ export default function comboToggleExtension(pi) {
|
|
|
109
110
|
}
|
|
110
111
|
persistPreset(level);
|
|
111
112
|
useState(setSharedComboLevel(level), ctx);
|
|
112
|
-
ctx?.ui?.notify?.(`Combo ${level} applied: ${levelSummary(
|
|
113
|
+
ctx?.ui?.notify?.(`Combo ${level} applied: ${levelSummary(getSharedComboState())}`, 'info');
|
|
113
114
|
if (ctx?.reload)
|
|
114
115
|
await ctx.reload();
|
|
115
116
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import os from 'node:os';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { asPromptArray, getSharedComboState, isComboPresetActive, isOmpSubagentPrompt, lastCustomValue, normalizeInputCommand, paintStatusBar, sessionEntries, setSharedComboMode } from '../shared/session-state.js';
|
|
3
|
+
import { asPromptArray, getSharedComboState, isComboPresetActive, isOmpSubagentPrompt, lastCustomValue, normalizeInputCommand, paintStatusBar, reconcileSharedComboEntries, sessionEntries, setSharedComboMode } from '../shared/session-state.js';
|
|
4
4
|
import { readRtkDefault } from '../shared/plugin-settings.js';
|
|
5
5
|
const DEFAULT_ENABLED = false;
|
|
6
6
|
function asBoolean(value) {
|
|
@@ -102,6 +102,11 @@ export default function rtkSessionExtension(pi) {
|
|
|
102
102
|
});
|
|
103
103
|
function restoreEnabled(ctx) {
|
|
104
104
|
const entries = sessionEntries(ctx);
|
|
105
|
+
// Publish the persisted combo state (incl. combo-level) before painting:
|
|
106
|
+
// bar suppression reads the in-process bridge, which is empty in a fresh
|
|
107
|
+
// host until the combo extension reconciles — and its reconcile is
|
|
108
|
+
// UI-gated. Deriving it here makes suppression independent of load order.
|
|
109
|
+
reconcileSharedComboEntries(entries);
|
|
105
110
|
// Persisted session state wins; a fresh session falls back to the
|
|
106
111
|
// installer/user-configured default (off unless configured).
|
|
107
112
|
const persisted = resolveEnabled(entries);
|
package/package.json
CHANGED
package/tersio.js
CHANGED
|
@@ -69,6 +69,7 @@ const verbose = args.includes('--verbose');
|
|
|
69
69
|
const doctor = command === 'doctor' || args.includes('--doctor');
|
|
70
70
|
const uninstall = command === 'uninstall' || args.includes('--uninstall');
|
|
71
71
|
const removePonytail = args.includes('--remove-ponytail');
|
|
72
|
+
const keepPonytail = args.includes('--keep-ponytail');
|
|
72
73
|
const removeRtk = args.includes('--remove-rtk');
|
|
73
74
|
const scopeFlag = flagValue('--scope')?.toLowerCase() ?? null;
|
|
74
75
|
// --- Profile selection (session-start mode defaults) ---
|
|
@@ -92,7 +93,7 @@ Commands:
|
|
|
92
93
|
|
|
93
94
|
Options:
|
|
94
95
|
--scope user|project|both
|
|
95
|
-
--
|
|
96
|
+
--keep-ponytail (uninstall: keep the Ponytail plugin — removed by default)
|
|
96
97
|
--remove-rtk (uninstall: also remove the RTK binary)
|
|
97
98
|
--combo-default off|medium|balanced|max (implies caveman, rtk, ponytail)
|
|
98
99
|
--caveman-default off|lite|full|ultra|wenyan (override; default follows combo)
|
|
@@ -800,7 +801,9 @@ async function removeUninstallTarget(target, shouldDryRun, recursive = true) {
|
|
|
800
801
|
async function runUninstall(options = {}) {
|
|
801
802
|
const shouldDryRun = options.dryRun ?? dryRun;
|
|
802
803
|
const confirmed = (options.yes ?? yes) || shouldDryRun;
|
|
803
|
-
|
|
804
|
+
// Ponytail ships with Tersio's presets, so a full uninstall removes it too;
|
|
805
|
+
// --keep-ponytail opts out and reinstall always preserves it.
|
|
806
|
+
const shouldRemovePonytail = options.removePonytail ?? (removePonytail || !keepPonytail);
|
|
804
807
|
const shouldRemoveRtk = options.removeRtk ?? removeRtk;
|
|
805
808
|
console.log('\n=== Tersio Uninstall ===\n');
|
|
806
809
|
const extDir = path.join(OMP_AGENT_DIR, 'extensions');
|