total-recall-brain 3.46.0 → 3.46.2
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/bin/total-recall.mjs
CHANGED
|
@@ -275,6 +275,9 @@ async function main() {
|
|
|
275
275
|
console.error(`Expected handler at: ${handlerPath}`);
|
|
276
276
|
process.exit(1);
|
|
277
277
|
}
|
|
278
|
+
// A new plugin contract refuses the previous release's defaults, `update` included; refresh them and rerun once.
|
|
279
|
+
const rerun = await import('../src/core/default-plugin-refresh.mjs').then(m => m.rerunAfterDefaultRefresh(err), () => null);
|
|
280
|
+
if (rerun !== null) process.exit(rerun);
|
|
278
281
|
console.error(`Error executing '${command}':`, err.message);
|
|
279
282
|
process.exit(1);
|
|
280
283
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "total-recall-brain",
|
|
3
|
-
"version": "3.46.
|
|
3
|
+
"version": "3.46.2",
|
|
4
4
|
"description": "The Vibe Coding Brain & Autonomous Software Factory: memory, rules, secrets, and 33 visual plugins automatically managed across all your devices.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
* background with the frontend's own build script, and keeps serving the
|
|
15
15
|
* current bundle until the new one is complete. It never installs
|
|
16
16
|
* dependencies: missing build tools are reported, not repaired behind the
|
|
17
|
-
* operator's back. An
|
|
18
|
-
*
|
|
17
|
+
* operator's back. An installed package (a root inside node_modules) serves
|
|
18
|
+
* the bundle its release built, which the publish gate checked, and is never
|
|
19
|
+
* stale and never builds: npm does not keep the tarball's file times on every
|
|
20
|
+
* install, so comparing times there reports a stale bundle that is not.
|
|
19
21
|
*/
|
|
20
22
|
import { spawn } from 'node:child_process';
|
|
21
23
|
import fs from 'node:fs';
|
|
@@ -60,9 +62,10 @@ export async function newestUnder(target) {
|
|
|
60
62
|
* Returns { ok, reason, bundle, source }; never throws, never prints, so the
|
|
61
63
|
* decision can be tested apart from how it is reported.
|
|
62
64
|
*/
|
|
63
|
-
export async function checkDistFreshness({ distDir, sourcePaths }) {
|
|
65
|
+
export async function checkDistFreshness({ distDir, sourcePaths, packaged = false }) {
|
|
64
66
|
const bundle = await newestUnder(distDir);
|
|
65
67
|
if (!bundle) return { ok: false, reason: 'missing-bundle', bundle: null, source: null };
|
|
68
|
+
if (packaged) return { ok: true, reason: 'packaged', bundle, source: null };
|
|
66
69
|
|
|
67
70
|
let source = null;
|
|
68
71
|
for (const candidate of sourcePaths) {
|
|
@@ -76,6 +79,11 @@ export async function checkDistFreshness({ distDir, sourcePaths }) {
|
|
|
76
79
|
return { ok: true, reason: 'current', bundle, source };
|
|
77
80
|
}
|
|
78
81
|
|
|
82
|
+
/** An npm-installed package: its root sits inside a node_modules directory. */
|
|
83
|
+
export function isInstalledPackage(root) {
|
|
84
|
+
return path.resolve(root).split(path.sep).includes('node_modules');
|
|
85
|
+
}
|
|
86
|
+
|
|
79
87
|
/** Every input whose change changes the built dashboard. */
|
|
80
88
|
export function dashboardTargets(root) {
|
|
81
89
|
const frontend = path.join(root, 'frontend');
|
|
@@ -85,6 +93,7 @@ export function dashboardTargets(root) {
|
|
|
85
93
|
} catch { /* no frontend directory: nothing to compare */ }
|
|
86
94
|
return {
|
|
87
95
|
distDir: path.join(frontend, 'dist'),
|
|
96
|
+
packaged: isInstalledPackage(root),
|
|
88
97
|
sourcePaths: [
|
|
89
98
|
path.join(frontend, 'src'),
|
|
90
99
|
path.join(frontend, 'public'),
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A release that changes the plugin contract refuses the shared default plugins the previous release
|
|
3
|
+
* installed, and with them every command that loads one, `update` included: the very command that would
|
|
4
|
+
* replace them. So a machine moving to such a release could not update itself. When a command fails that
|
|
5
|
+
* way, refresh the defaults from this package's bundled copies (a link is its owner's checkout and is left
|
|
6
|
+
* alone) and run the command again, once.
|
|
7
|
+
*/
|
|
8
|
+
import { spawnSync } from 'node:child_process';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import { ensureRequiredPlugins } from './required-plugins.mjs';
|
|
11
|
+
import { globalPluginsDir } from './plugin-loader.mjs';
|
|
12
|
+
|
|
13
|
+
const REFUSAL = /\bRequired (?:plugin [\w-]+|[\w-]+ plugin) is missing or invalid\b/;
|
|
14
|
+
export const REFRESHED_ENV = 'TR_DEFAULT_PLUGINS_REFRESHED';
|
|
15
|
+
|
|
16
|
+
export function isDefaultPluginRefusal(error) {
|
|
17
|
+
return REFUSAL.test(String(error?.message || ''));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Returns the rerun's exit status, or null when this error is not one a refresh can fix. */
|
|
21
|
+
export function rerunAfterDefaultRefresh(error, {
|
|
22
|
+
env = process.env, argv = process.argv, execPath = process.execPath, ensure = ensureRequiredPlugins,
|
|
23
|
+
sharedBrainDir = path.dirname(globalPluginsDir()), run = spawnSync, log = (line) => console.error(line),
|
|
24
|
+
} = {}) {
|
|
25
|
+
if (!isDefaultPluginRefusal(error) || env[REFRESHED_ENV] === '1') return null;
|
|
26
|
+
try {
|
|
27
|
+
ensure(sharedBrainDir, { sharedBrainDir });
|
|
28
|
+
} catch (refreshError) {
|
|
29
|
+
log(`The default plugins could not be refreshed from this release: ${refreshError.message}`);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
log('Refreshed the default plugins from this release; running the command again.');
|
|
33
|
+
const result = run(execPath, argv.slice(1), { stdio: 'inherit', env: { ...env, [REFRESHED_ENV]: '1' } });
|
|
34
|
+
if (result.error) {
|
|
35
|
+
log(`The command could not be run again: ${result.error.message}`);
|
|
36
|
+
return 1;
|
|
37
|
+
}
|
|
38
|
+
return result.status ?? 1;
|
|
39
|
+
}
|