@krtclcdy/tersio 2.23.0 → 2.24.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.
- package/README.md +58 -45
- package/cli/agent-hosts.js +42 -0
- package/cli/agents.js +266 -0
- package/cli/common.js +16 -20
- package/cli/currency.js +8 -12
- package/cli/dashboard.js +49 -37
- package/cli/doctor-fix.js +28 -17
- package/cli/doctor.js +52 -41
- package/cli/hosts.js +118 -0
- package/cli/install.js +180 -117
- package/cli/interactive.js +27 -1
- package/cli/layer.js +24 -0
- package/cli/manifest.js +36 -0
- package/cli/omp-layer.js +51 -0
- package/cli/pi-layer.js +37 -0
- package/cli/pi-wiring.js +92 -0
- package/cli/profile.js +44 -46
- package/cli/reset.js +3 -26
- package/cli/rtk-wiring.js +10 -15
- package/cli/uninstall.js +135 -44
- package/cli/update.js +12 -19
- package/dashboard/dist/index.html +16 -16
- package/extensions/ai-addons-updater/index.js +31 -24
- package/extensions/ai-addons-updater/index.ts +32 -32
- package/extensions/caveman-session/index.js +6 -6
- package/extensions/caveman-session/index.ts +6 -6
- package/extensions/combo-toggle/index.js +42 -40
- package/extensions/combo-toggle/index.ts +36 -47
- package/extensions/lib/utils.js +36 -9
- package/extensions/lib/utils.ts +37 -9
- package/extensions/rtk-session/index.js +9 -9
- package/extensions/rtk-session/index.ts +9 -14
- package/extensions/shared/carbon.js +5 -8
- package/extensions/shared/carbon.ts +5 -8
- package/extensions/shared/host.js +68 -0
- package/extensions/shared/host.ts +104 -0
- package/extensions/shared/omp-prompt.js +12 -0
- package/extensions/shared/plugin-settings.js +43 -30
- package/extensions/shared/plugin-settings.ts +45 -26
- package/extensions/shared/pricing.js +26 -15
- package/extensions/shared/pricing.ts +28 -16
- package/extensions/shared/rtk-gain.js +11 -22
- package/extensions/shared/rtk-gain.ts +11 -22
- package/extensions/shared/session-state.js +21 -25
- package/extensions/shared/session-state.ts +22 -26
- package/extensions/shared/types.ts +10 -3
- package/extensions/shared/usage-ledger.js +24 -36
- package/extensions/shared/usage-ledger.ts +29 -50
- package/extensions/shared/usage-store.js +14 -12
- package/extensions/shared/usage-store.ts +16 -14
- package/extensions/tersio-commands/index.js +2 -1
- package/extensions/tersio-commands/index.ts +2 -1
- package/package.json +4 -2
- package/tersio.js +4 -4
- package/extensions/shared/mode-reinforcement.js +0 -26
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
// extensions/shared/usage-store.ts — tersio-owned usage.db.
|
|
2
|
-
// Persists the
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// never a fork. Missing sqlite3 CLI → sync false / read null, callers fall
|
|
8
|
-
// back to the live path. Never touches RTK's history.db or host transcripts.
|
|
2
|
+
// Persists the rows importSessionTokens derives live, so reports survive
|
|
3
|
+
// session-file rotation. Sync is incremental (a files ledger skips unchanged
|
|
4
|
+
// transcripts) and every read applies the reset watermark, so the store is a
|
|
5
|
+
// cache, never a fork. Missing sqlite3 → sync false / read null. Never touches
|
|
6
|
+
// RTK's history.db or host transcripts.
|
|
9
7
|
import { execFileSync } from 'node:child_process';
|
|
10
8
|
import fs from 'node:fs';
|
|
11
9
|
import os from 'node:os';
|
|
@@ -23,6 +21,7 @@ import {
|
|
|
23
21
|
walkJsonl,
|
|
24
22
|
} from './usage-ledger.ts';
|
|
25
23
|
import { tersioDataPath } from '../lib/utils.ts';
|
|
24
|
+
import { MODEL_ALIASES } from './pricing.ts';
|
|
26
25
|
import type { RunStatus, SessionTokens } from './usage-ledger.ts';
|
|
27
26
|
|
|
28
27
|
export function usageDbPath(): string {
|
|
@@ -70,6 +69,10 @@ function query(db: string, sql: string): string[][] {
|
|
|
70
69
|
|
|
71
70
|
function ensureSchema(db: string): void {
|
|
72
71
|
fs.mkdirSync(path.dirname(db), { recursive: true });
|
|
72
|
+
// Rows imported before an alias existed keep the spelling they were stored
|
|
73
|
+
// with, and the mtime ledger will not re-read those transcripts. Fold them in
|
|
74
|
+
// once, so the merge shows up without a reset.
|
|
75
|
+
const rekeys = MODEL_ALIASES.map((a) => `UPDATE messages SET model='${a.id}' WHERE model='${a.feed}';`).join('');
|
|
73
76
|
run(
|
|
74
77
|
db,
|
|
75
78
|
`CREATE TABLE IF NOT EXISTS meta (k TEXT PRIMARY KEY, v TEXT NOT NULL);` +
|
|
@@ -77,7 +80,7 @@ function ensureSchema(db: string): void {
|
|
|
77
80
|
`CREATE TABLE IF NOT EXISTS messages (file TEXT NOT NULL, t REAL, model TEXT NOT NULL,` +
|
|
78
81
|
` i INTEGER NOT NULL, o INTEGER NOT NULL, d REAL, cr INTEGER NOT NULL, cw INTEGER NOT NULL,` +
|
|
79
82
|
` usd REAL, st TEXT NOT NULL, code REAL, note TEXT, tools TEXT NOT NULL DEFAULT '[]');` +
|
|
80
|
-
`CREATE INDEX IF NOT EXISTS idx_messages_file ON messages(file)
|
|
83
|
+
`CREATE INDEX IF NOT EXISTS idx_messages_file ON messages(file);` + rekeys,
|
|
81
84
|
);
|
|
82
85
|
}
|
|
83
86
|
|
|
@@ -91,8 +94,8 @@ function readFiles(db: string): Record<string, { mtime: number; size: number }>
|
|
|
91
94
|
return known;
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
// One parsed assistant message, as stored. `t` is
|
|
95
|
-
//
|
|
97
|
+
// One parsed assistant message, as stored. `t` is null when the source row has
|
|
98
|
+
// no usable timestamp: counted, but skipped in the recent list.
|
|
96
99
|
interface StoredRow {
|
|
97
100
|
t: number | null;
|
|
98
101
|
model: string;
|
|
@@ -173,10 +176,9 @@ function insertSql(file: string, r: StoredRow): string {
|
|
|
173
176
|
`${nullNum(r.code)},${nullStr(r.note)},${esc(JSON.stringify(r.tools))});`;
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
// Incremental sync: unchanged transcripts are skipped via mtime+size,
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
// (including nothing-to-do), false when sqlite3 or disk is unavailable.
|
|
179
|
+
// Incremental sync: unchanged transcripts are skipped via mtime+size, changed
|
|
180
|
+
// ones re-inserted. Rows for deleted transcripts are kept, so rotation never
|
|
181
|
+
// erases history. False when sqlite3 or disk is unavailable.
|
|
180
182
|
export function syncUsageDb(): boolean {
|
|
181
183
|
let db: string;
|
|
182
184
|
try {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// publishes sync sibling mirrors live, so switches notify and take effect
|
|
5
5
|
// next turn — no reload.
|
|
6
6
|
import { getSharedComboState, reconcileSharedComboEntries, sessionEntries, } from '../shared/session-state.js';
|
|
7
|
+
import { setExtensionLabel } from '../shared/host.js';
|
|
7
8
|
import os from 'node:os';
|
|
8
9
|
import path from 'node:path';
|
|
9
10
|
import { appendUsage, readUsage } from '../shared/usage-ledger.js';
|
|
@@ -48,7 +49,7 @@ async function openDashboard(pi, ctx) {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
export default function tersioCommandsExtension(pi) {
|
|
51
|
-
pi
|
|
52
|
+
setExtensionLabel(pi, 'Tersio unified root command');
|
|
52
53
|
pi.registerCommand?.('tersio', {
|
|
53
54
|
description: 'Tersio root: status|check|update|dashboard|usage|help',
|
|
54
55
|
handler: async (args, ctx) => {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
reconcileSharedComboEntries,
|
|
9
9
|
sessionEntries,
|
|
10
10
|
} from '../shared/session-state.ts';
|
|
11
|
+
import { setExtensionLabel } from '../shared/host.ts';
|
|
11
12
|
import os from 'node:os';
|
|
12
13
|
import path from 'node:path';
|
|
13
14
|
import { appendUsage, readUsage } from '../shared/usage-ledger.ts';
|
|
@@ -54,7 +55,7 @@ async function openDashboard(pi: ExtensionApi, ctx?: ExtensionCtx): Promise<void
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export default function tersioCommandsExtension(pi: ExtensionApi): void {
|
|
57
|
-
pi
|
|
58
|
+
setExtensionLabel(pi, 'Tersio unified root command');
|
|
58
59
|
|
|
59
60
|
|
|
60
61
|
pi.registerCommand?.('tersio', {
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@krtclcdy/tersio",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.24.0",
|
|
4
|
+
"description": "\u2702\ufe0f Token-saving OMP add-ons: terse Caveman replies, compact RTK shell output, lean Ponytail code calls \u2014 one-command combo presets.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"omp",
|
|
7
|
+
"pi",
|
|
8
|
+
"pi-package",
|
|
7
9
|
"token-saving",
|
|
8
10
|
"ai-tools",
|
|
9
11
|
"developer-tools",
|
package/tersio.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// tersio.ts — Install Tersio (caveman/rtk/ponytail) add-ons on any OMP device.
|
|
3
|
-
// Usage: node tersio.js [install|update|
|
|
3
|
+
// Usage: node tersio.js [install|update|doctor|dashboard|uninstall|version|help] [options]
|
|
4
4
|
// Requires: node/npm and omp CLI
|
|
5
5
|
import { PACKAGE_BIN, PACKAGE_VERSION, applyUpdate, commandArg, dashboard, dashboardExport, dashboardOpen, dashboardPort, doctor, reset, settings, showHelp, showVersion, uninstall, unknownCommand, update, usage, } from './cli/common.js';
|
|
6
6
|
import { closeRL } from './cli/interactive.js';
|
|
@@ -16,9 +16,8 @@ function printHelp() {
|
|
|
16
16
|
console.log(`Usage: ${PACKAGE_BIN} [command] [options]
|
|
17
17
|
|
|
18
18
|
Commands:
|
|
19
|
-
install Install the add-ons (
|
|
19
|
+
install Install the add-ons for one agent (--host omp|pi, or ask at a terminal)
|
|
20
20
|
update Refresh the CLI and add-ons (RTK binary, Caveman rule, Ponytail)
|
|
21
|
-
reinstall Clean and reinstall the user-scope add-ons
|
|
22
21
|
doctor Check the current installation (--fix repairs, --dry-run previews)
|
|
23
22
|
usage Ledger-backed usage + savings report
|
|
24
23
|
dashboard Open the Dashboard (localhost only)
|
|
@@ -31,8 +30,9 @@ Commands:
|
|
|
31
30
|
Options:
|
|
32
31
|
--fix (doctor: repairs all; --fix=<scope> repairs one of extensions, registrations, rtk, ponytail, cli)
|
|
33
32
|
--scope user (legacy; accepted and ignored — user scope is the only scope)
|
|
33
|
+
--host omp|pi (install|uninstall: target agent; a terminal asks instead)
|
|
34
34
|
--keep-ponytail (uninstall: keep the bundled Ponytail copy — removed by default)
|
|
35
|
-
--remove-rtk (uninstall: also remove the RTK binary)
|
|
35
|
+
--remove-rtk (uninstall: also remove the RTK binary; its OMP wiring always goes)
|
|
36
36
|
--combo-default off|medium|balanced|max (implies caveman, rtk, ponytail)
|
|
37
37
|
--caveman-default off|lite|full|ultra|wenyan-lite|wenyan-full|wenyan-ultra (override; default follows combo)
|
|
38
38
|
--ponytail-default off|lite|full|ultra (override; default follows combo)
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { asPromptArray, reconcileSharedComboEntries, sessionEntries, systemPromptIncludes } from './session-state.js';
|
|
2
|
-
const MARKER = 'SUPREME TOKEN SAVER MODES ACTIVE';
|
|
3
|
-
function instruction(state) {
|
|
4
|
-
const modes = [
|
|
5
|
-
state.caveman !== 'off' && `caveman=${state.caveman}`,
|
|
6
|
-
state.rtk === 'on' && 'rtk=on',
|
|
7
|
-
state.ponytail !== 'off' && `ponytail=${state.ponytail}`,
|
|
8
|
-
].filter(Boolean);
|
|
9
|
-
if (!modes.length)
|
|
10
|
-
return null;
|
|
11
|
-
return `${MARKER}: ${modes.join(' · ')}. Keep these active for the entire response: concise Caveman prose, RTK for eligible noisy shell output, and the smallest correct Ponytail solution. Do not weaken or disable a mode unless the user explicitly asks.`;
|
|
12
|
-
}
|
|
13
|
-
export default function modeReinforcementExtension(pi) {
|
|
14
|
-
pi.setLabel?.('Tersio mode reinforcement');
|
|
15
|
-
pi.on('before_agent_start', async (event, ctx) => {
|
|
16
|
-
if (!ctx?.hasUI)
|
|
17
|
-
return;
|
|
18
|
-
const text = instruction(reconcileSharedComboEntries(sessionEntries(ctx)));
|
|
19
|
-
if (!text)
|
|
20
|
-
return;
|
|
21
|
-
const base = asPromptArray(event.systemPrompt);
|
|
22
|
-
if (systemPromptIncludes(base, MARKER))
|
|
23
|
-
return;
|
|
24
|
-
return { systemPrompt: [...base, text] };
|
|
25
|
-
});
|
|
26
|
-
}
|