@krtclcdy/tersio 2.0.1 → 2.1.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 +1 -1
- package/package.json +1 -1
- package/tersio.js +105 -52
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ Break-even math, balanced preset (caveman full + rtk + ponytail): `⌈overhead
|
|
|
79
79
|
| Command | Purpose |
|
|
80
80
|
|---|---|
|
|
81
81
|
| `tersio install` | Install (user scope by default; `--scope project\|both` for more) |
|
|
82
|
-
| `tersio update` | Refresh
|
|
82
|
+
| `tersio update` | Refresh the CLI, extensions, and add-ons (RTK binary, Caveman rule, Ponytail) |
|
|
83
83
|
| `tersio reinstall` | Fresh install, preserving the Ponytail package |
|
|
84
84
|
| `tersio doctor` | Check OMP, extension, Ponytail, and RTK health |
|
|
85
85
|
| `tersio uninstall` | Remove extensions, registration, and the Ponytail plugin (`--keep-ponytail` keeps Ponytail; `--remove-rtk` also removes the RTK binary) |
|
package/package.json
CHANGED
package/tersio.js
CHANGED
|
@@ -84,7 +84,7 @@ function printHelp() {
|
|
|
84
84
|
|
|
85
85
|
Commands:
|
|
86
86
|
install Install the add-ons (user scope by default)
|
|
87
|
-
update
|
|
87
|
+
update Refresh the CLI and add-ons (RTK binary, Caveman rule, Ponytail)
|
|
88
88
|
reinstall Clean and reinstall the user-scope add-ons
|
|
89
89
|
doctor Check the current installation
|
|
90
90
|
uninstall Remove the managed extensions
|
|
@@ -661,17 +661,8 @@ async function stepCombo(extDir, options) {
|
|
|
661
661
|
await ensureExtensionInConfig(configPath, dest, 'combo', options);
|
|
662
662
|
}
|
|
663
663
|
// --- Doctor ---
|
|
664
|
-
function presence(label, text) {
|
|
665
|
-
console.log(` ${label}: ${text !== null ? 'installed' : 'MISSING'}`);
|
|
666
|
-
}
|
|
667
|
-
function locationLine(label, ok, loc) {
|
|
668
|
-
console.log(` ${label}: ${ok ? 'ok' : 'MISSING'} ${loc}`);
|
|
669
|
-
}
|
|
670
664
|
async function runDoctor() {
|
|
671
|
-
console.log('\n=== Tersio Doctor
|
|
672
|
-
// Node
|
|
673
|
-
console.log(` Node: ok ${process.version}`);
|
|
674
|
-
// OMP CLI version joins FS probes below; logs keep fixed order.
|
|
665
|
+
console.log('\n=== Tersio Doctor ===');
|
|
675
666
|
// Directories
|
|
676
667
|
const agentDir = OMP_AGENT_DIR;
|
|
677
668
|
const extDir = path.join(agentDir, 'extensions');
|
|
@@ -707,48 +698,66 @@ async function runDoctor() {
|
|
|
707
698
|
readTextIfExists(comboIndex),
|
|
708
699
|
readTextIfExists(modeReinforcement),
|
|
709
700
|
]);
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
presence('Ponytail package', ponytailPkgText);
|
|
717
|
-
presence('Ponytail extension', ponytailExtText);
|
|
718
|
-
if (configText) {
|
|
719
|
-
const hasPonytailPath = configText.includes('ponytail') && configText.includes('pi-extension');
|
|
720
|
-
console.log(` Ponytail in config.yml: ${hasPonytailPath ? 'registered' : 'MISSING'}`);
|
|
721
|
-
}
|
|
722
|
-
// Self plugin registration (Settings → Plugins listing)
|
|
723
|
-
const selfDep = PACKAGE_NAME in (parseJsonObject(pluginsPkgRaw)?.dependencies || {});
|
|
724
|
-
console.log(` Self plugin in plugins/package.json: ${selfDep ? 'registered' : 'MISSING'}`);
|
|
725
|
-
console.log(` Self plugin package: ${selfPkgText !== null ? 'installed' : 'MISSING'}`);
|
|
726
|
-
// RTK
|
|
727
|
-
const rtkExists = rtkBinText !== null;
|
|
728
|
-
console.log(` RTK binary: ${rtkExists ? 'installed' : 'MISSING'} ${rtkBin}`);
|
|
729
|
-
if (rtkExists) {
|
|
730
|
-
try {
|
|
731
|
-
const v = (await execP(rtkBin, ['--version'], { timeout: 5000 })).stdout.trim();
|
|
732
|
-
console.log(` RTK version: ${v}`);
|
|
701
|
+
// Categorized output with a tally; section headers group related probes.
|
|
702
|
+
const tally = { ok: 0, missing: 0, warn: 0 };
|
|
703
|
+
function check(label, ok, detail = '') {
|
|
704
|
+
if (ok) {
|
|
705
|
+
tally.ok++;
|
|
706
|
+
console.log(` ${label}: ok${detail ? ` ${detail}` : ''}`);
|
|
733
707
|
}
|
|
734
|
-
|
|
735
|
-
|
|
708
|
+
else {
|
|
709
|
+
tally.missing++;
|
|
710
|
+
console.log(` ${label}: MISSING${detail ? ` ${detail}` : ''}`);
|
|
736
711
|
}
|
|
737
712
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
713
|
+
function warnLine(label, detail) {
|
|
714
|
+
tally.warn++;
|
|
715
|
+
console.log(` ${label}: warn ${detail}`);
|
|
716
|
+
}
|
|
717
|
+
section('Environment');
|
|
718
|
+
check('Node', true, process.version);
|
|
719
|
+
check('OMP CLI', ompVersion !== null, ompVersion ?? '');
|
|
720
|
+
console.log(` Home: ${HOME}`);
|
|
721
|
+
section('Installation');
|
|
722
|
+
check('OMP agent dir', agentEntries !== null, agentDir);
|
|
723
|
+
check('OMP extensions dir', extEntries !== null, extDir);
|
|
724
|
+
check('OMP config.yml', configText !== null, configPath);
|
|
725
|
+
check('Shared session bridge', sharedStateText !== null);
|
|
726
|
+
section('Extensions');
|
|
727
|
+
check('Caveman extension', cavemanIndexText !== null);
|
|
728
|
+
check('Caveman rule.md', cavemanRuleText !== null);
|
|
729
|
+
check('RTK extension', rtkIndexText !== null);
|
|
730
|
+
check('Updater extension', updaterIndexText !== null);
|
|
731
|
+
check('Combo extension', comboIndexText !== null);
|
|
732
|
+
check('Mode reinforcement extension', modeReinforcementText !== null);
|
|
733
|
+
section('Plugins');
|
|
734
|
+
check('Ponytail package', ponytailPkgText !== null);
|
|
735
|
+
check('Ponytail extension', ponytailExtText !== null);
|
|
748
736
|
if (configText) {
|
|
749
|
-
|
|
750
|
-
|
|
737
|
+
check('Ponytail in config.yml', configText.includes('ponytail') && configText.includes('pi-extension'));
|
|
738
|
+
check('Combo in config.yml', configText.includes('combo-toggle'));
|
|
751
739
|
}
|
|
740
|
+
check('Self plugin package', selfPkgText !== null);
|
|
741
|
+
const selfDep = PACKAGE_NAME in (parseJsonObject(pluginsPkgRaw)?.dependencies || {});
|
|
742
|
+
check('Self plugin in plugins/package.json', selfDep);
|
|
743
|
+
section('RTK');
|
|
744
|
+
check('RTK binary', rtkBinText !== null, rtkBin);
|
|
745
|
+
if (rtkBinText !== null) {
|
|
746
|
+
// rtk may exit non-zero while still printing its version — accept either stream.
|
|
747
|
+
const version = await execP(rtkBin, ['--version'], { timeout: 5000 }).then((r) => r.stdout.trim() || r.stderr.trim() || null, (e) => {
|
|
748
|
+
const err = e;
|
|
749
|
+
return err.stdout?.trim() || err.stderr?.trim() || null;
|
|
750
|
+
});
|
|
751
|
+
if (version)
|
|
752
|
+
check('RTK version', true, version);
|
|
753
|
+
else
|
|
754
|
+
warnLine('RTK version', 'unavailable — binary may not be executable');
|
|
755
|
+
}
|
|
756
|
+
const total = tally.ok + tally.missing + tally.warn;
|
|
757
|
+
console.log(`\n Summary: ${total} checks — ${tally.ok} ok, ${tally.warn} warn, ${tally.missing} missing`);
|
|
758
|
+
}
|
|
759
|
+
function section(name) {
|
|
760
|
+
console.log(`\n${name}`);
|
|
752
761
|
}
|
|
753
762
|
// Read-modify-write a JSON file. mutate returns true when it changed
|
|
754
763
|
// something; no change (or unreadable file) means no output at all.
|
|
@@ -897,6 +906,7 @@ async function runUninstall(options = {}) {
|
|
|
897
906
|
return true;
|
|
898
907
|
}
|
|
899
908
|
const SCOPE_MAP = { user: '1', project: '2', both: '3' };
|
|
909
|
+
const COMBO_MENU = { '1': 'off', '2': 'medium', '3': 'balanced', '4': 'max' };
|
|
900
910
|
async function runLatestUpdate() {
|
|
901
911
|
const updateScope = scopeFlag || 'user';
|
|
902
912
|
if (!Object.hasOwn(SCOPE_MAP, updateScope)) {
|
|
@@ -923,6 +933,31 @@ async function runLatestUpdate() {
|
|
|
923
933
|
const npmCommandArgs = IS_WINDOWS ? ['/d', '/s', '/c', 'npm', ...npmArgs] : npmArgs;
|
|
924
934
|
console.log('=== Updating Tersio ===');
|
|
925
935
|
console.log(` Running the latest ${PACKAGE_NAME} installer...\n`);
|
|
936
|
+
// The npx delegation below only refreshes the OMP-side files; the globally
|
|
937
|
+
// installed CLI keeps its old version until npm -g runs. Refresh both.
|
|
938
|
+
if (dryRun) {
|
|
939
|
+
console.log(` [dry-run] would run: npm install -g ${PACKAGE_NAME}@latest --no-audit --no-fund`);
|
|
940
|
+
}
|
|
941
|
+
else {
|
|
942
|
+
try {
|
|
943
|
+
const globalArgs = IS_WINDOWS ? ['/d', '/s', '/c', 'npm', 'install', '-g', `${PACKAGE_NAME}@latest`, '--no-audit', '--no-fund'] : ['install', '-g', `${PACKAGE_NAME}@latest`, '--no-audit', '--no-fund'];
|
|
944
|
+
const globalResult = await execP(npmCommand, globalArgs, {
|
|
945
|
+
timeout: 300000,
|
|
946
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
947
|
+
windowsHide: true,
|
|
948
|
+
shell: false,
|
|
949
|
+
});
|
|
950
|
+
if (globalResult.stdout)
|
|
951
|
+
process.stdout.write(globalResult.stdout);
|
|
952
|
+
if (globalResult.stderr)
|
|
953
|
+
process.stderr.write(globalResult.stderr);
|
|
954
|
+
console.log(` [ok] CLI updated to ${PACKAGE_NAME}@latest`);
|
|
955
|
+
}
|
|
956
|
+
catch (e) {
|
|
957
|
+
console.log(` [warn] Global CLI update skipped: ${e.message}`);
|
|
958
|
+
console.log(` [hint] Manual: npm install -g ${PACKAGE_NAME}@latest`);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
926
961
|
try {
|
|
927
962
|
const result = await execP(npmCommand, npmCommandArgs, {
|
|
928
963
|
timeout: 300000,
|
|
@@ -992,12 +1027,27 @@ async function resolveScope() {
|
|
|
992
1027
|
async function resolveProfile() {
|
|
993
1028
|
const profile = defaultProfile();
|
|
994
1029
|
// Single interactive prompt: the Combo preset implies all three modes.
|
|
1030
|
+
// Numbered menu, same pattern as the scope prompt — no typing preset names.
|
|
995
1031
|
// Only for a real user at a terminal, only when no default flags were
|
|
996
1032
|
// given, and never for --apply-update runs.
|
|
997
1033
|
if (tty() && !profileFlagsGiven && !applyUpdate && (install || reinstall)) {
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1034
|
+
console.log(' Session-start defaults — Combo preset:');
|
|
1035
|
+
console.log(' 1) off');
|
|
1036
|
+
console.log(' 2) medium (caveman=lite, rtk=on, ponytail=lite)');
|
|
1037
|
+
console.log(' 3) balanced (caveman=full, rtk=on, ponytail=full)');
|
|
1038
|
+
console.log(' 4) max (caveman=ultra, rtk=on, ponytail=ultra)');
|
|
1039
|
+
for (;;) {
|
|
1040
|
+
const answer = (await ask(' Choose [1-4] (default 1): ')).trim();
|
|
1041
|
+
if (!answer) {
|
|
1042
|
+
profile.comboDefault = 'off';
|
|
1043
|
+
break;
|
|
1044
|
+
}
|
|
1045
|
+
if (COMBO_MENU[answer]) {
|
|
1046
|
+
profile.comboDefault = COMBO_MENU[answer];
|
|
1047
|
+
break;
|
|
1048
|
+
}
|
|
1049
|
+
console.log(` [fail] Invalid choice: ${answer}. Choose 1, 2, 3, or 4.`);
|
|
1050
|
+
}
|
|
1001
1051
|
}
|
|
1002
1052
|
// Explicit flags always win over the Combo preset.
|
|
1003
1053
|
if (comboDefaultFlag !== undefined)
|
|
@@ -1119,7 +1169,10 @@ async function main() {
|
|
|
1119
1169
|
const userDir = OMP_AGENT_DIR;
|
|
1120
1170
|
const userExtDir = path.join(userDir, 'extensions');
|
|
1121
1171
|
const projectExtDir = path.join(process.cwd(), '.omp', 'extensions');
|
|
1122
|
-
|
|
1172
|
+
// apply-update is `tersio update`'s payload run: treat it like reinstall so
|
|
1173
|
+
// the add-ons refresh too — Ponytail package via npm, self plugin, RTK
|
|
1174
|
+
// binary (always re-downloaded), and the Caveman rule (always re-fetched).
|
|
1175
|
+
const options = { dryRun, verbose, yes, scope, reinstall: reinstall || applyUpdate };
|
|
1123
1176
|
// Check prerequisites
|
|
1124
1177
|
console.log('\nPrerequisites:');
|
|
1125
1178
|
try {
|