total-recall-brain 3.43.3 → 3.44.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/docs/reference/cli-reference.md +3 -1
- package/package.json +3 -3
- package/scaffold/.agent/skills/plugin/SKILL.md +7 -2
- package/scaffold/.agent/skills/plugin/evals/README.md +5 -0
- package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +1 -0
- package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +1 -0
- package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +1 -0
- package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +1 -0
- package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +1 -0
- package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +1 -0
- package/scaffold/.agent/skills/plugin/evals/cases/07-missing-reuse.mjs +11 -0
- package/scaffold/.agent/skills/plugin/evals/cases/08-unresolved-owner-command.mjs +12 -0
- package/scaffold/.agent/skills/plugin/evals/cases/09-missing-brick.mjs +12 -0
- package/scaffold/.agent/skills/plugin/prompts/01-function.md +4 -3
- package/scaffold/.agent/skills/plugin/prompts/08-verify.md +1 -0
- package/scaffold/.agent/skills/plugin/references/surfaces.md +12 -2
- package/scaffold/.agent/skills/plugin/scripts/record.mjs +59 -2
- package/scaffold/.agent/skills/total-recall/plugins/auth/README.md +8 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-gh-login.mjs +102 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +18 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/login-projections.mjs +157 -13
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-sync.mjs +161 -17
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +38 -5
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +38 -7
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +85 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +104 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +12 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +15 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +38 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +42 -11
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +40 -13
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +249 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +3 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/pool.mjs +16 -8
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +1 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +5 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +27 -11
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +28 -6
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +110 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +322 -40
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +14 -13
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/ssss/assets/scaffold.json +5 -5
- package/scaffold/.agent/skills/total-recall/plugins/ssss/package-lock.json +6 -6
- package/scaffold/.agent/skills/total-recall/plugins/ssss/package.json +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/ssss/plugin.json +1 -1
- package/src/cli/connect.mjs +2 -29
- package/src/cli/context.mjs +1 -0
- package/src/cli/ingest-okf.mjs +4 -4
- package/src/cli/release.mjs +4 -1
- package/src/cli/update.mjs +4 -1
- package/src/core/automatic-brain-updates.mjs +11 -6
- package/src/core/brain-updates.mjs +11 -1
- package/src/core/context-compactor.mjs +7 -2
- package/src/core/context-compiler.mjs +6 -1
- package/src/core/context-policy.mjs +7 -3
- package/src/core/daemon-control.mjs +22 -0
- package/src/core/global-brain-updates.mjs +1 -1
- package/src/core/mesh-brain-updates.mjs +2 -1
- package/src/core/server-restart.mjs +128 -7
- package/src/core/ssss-kernel-bridge.mjs +1 -2
- package/src/core/surface.mjs +3 -3
- package/src/core/task-context.mjs +9 -8
- package/src/core/validated-write.mjs +4 -0
- package/src/core/vault-files.mjs +8 -2
- package/src/core/vault.mjs +1 -1
- package/src/server/index.mjs +3 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
3
|
"id": "openwiki",
|
|
4
4
|
"name": "OpenWiki",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.10",
|
|
6
6
|
"description": "Multi-repo knowledge graph and documentation wiki engine for Total Recall.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"runtime": {
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-security",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "tr-plugin-security",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.6",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@gregiteen/ssss-cli": "0.14.
|
|
12
|
+
"@gregiteen/ssss-cli": "0.14.5"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"jsdom": "^26.1.0",
|
|
16
|
-
"total-recall-brain": "3.
|
|
16
|
+
"total-recall-brain": "3.43.3"
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"node_modules/@alcalzone/ansi-tokenize": {
|
|
@@ -845,9 +845,9 @@
|
|
|
845
845
|
}
|
|
846
846
|
},
|
|
847
847
|
"node_modules/@gregiteen/ssss-cli": {
|
|
848
|
-
"version": "0.14.
|
|
849
|
-
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.
|
|
850
|
-
"integrity": "sha512-
|
|
848
|
+
"version": "0.14.5",
|
|
849
|
+
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.5.tgz",
|
|
850
|
+
"integrity": "sha512-qVEYOocnwn97uJ0eDzmuwN06CYsYWr2t3+iKylpisBHX4wlLWk7P8EmFFdBlx7NyKVIZDDeYT164Gd7/T8UGgw==",
|
|
851
851
|
"license": "ISC",
|
|
852
852
|
"bin": {
|
|
853
853
|
"ssss": "scripts/ssss.mjs"
|
|
@@ -1686,9 +1686,9 @@
|
|
|
1686
1686
|
},
|
|
1687
1687
|
"node_modules/@ssss/cli": {
|
|
1688
1688
|
"name": "@gregiteen/ssss-cli",
|
|
1689
|
-
"version": "0.14.
|
|
1690
|
-
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.
|
|
1691
|
-
"integrity": "sha512-
|
|
1689
|
+
"version": "0.14.5",
|
|
1690
|
+
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.5.tgz",
|
|
1691
|
+
"integrity": "sha512-qVEYOocnwn97uJ0eDzmuwN06CYsYWr2t3+iKylpisBHX4wlLWk7P8EmFFdBlx7NyKVIZDDeYT164Gd7/T8UGgw==",
|
|
1692
1692
|
"dev": true,
|
|
1693
1693
|
"license": "ISC",
|
|
1694
1694
|
"bin": {
|
|
@@ -5698,9 +5698,9 @@
|
|
|
5698
5698
|
}
|
|
5699
5699
|
},
|
|
5700
5700
|
"node_modules/total-recall-brain": {
|
|
5701
|
-
"version": "3.
|
|
5702
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.
|
|
5703
|
-
"integrity": "sha512-
|
|
5701
|
+
"version": "3.43.3",
|
|
5702
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.43.3.tgz",
|
|
5703
|
+
"integrity": "sha512-yjfPN/BQxEEa+iodyFXQov/6fRt1pZg/7RcmgsbpALwBt6Ki3JJjT3tzArBC7NxHQmXgGYyKnCYId6xe/W2rPg==",
|
|
5704
5704
|
"dev": true,
|
|
5705
5705
|
"license": "MIT",
|
|
5706
5706
|
"workspaces": [
|
|
@@ -5731,6 +5731,7 @@
|
|
|
5731
5731
|
"antigravity": "bin/antigravity.mjs",
|
|
5732
5732
|
"total-recall": "bin/total-recall.mjs",
|
|
5733
5733
|
"total-recall-memory": "bin/total-recall-memory.mjs",
|
|
5734
|
+
"total-recall-server-release": "bin/total-recall-server-release.mjs",
|
|
5734
5735
|
"vibebrain": "bin/total-recall.mjs"
|
|
5735
5736
|
},
|
|
5736
5737
|
"optionalDependencies": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-security",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Standalone security suite for Total Recall: static analysis, file and permission hardening schemes, AES-256-GCM encryption tools, and egress audit controls",
|
|
6
6
|
"scripts": {
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@gregiteen/ssss-cli": "0.14.
|
|
27
|
+
"@gregiteen/ssss-cli": "0.14.5"
|
|
28
28
|
},
|
|
29
29
|
"overrides": {
|
|
30
|
-
"@ssss/cli": "npm:@gregiteen/ssss-cli@0.14.
|
|
30
|
+
"@ssss/cli": "npm:@gregiteen/ssss-cli@0.14.5"
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
3
|
"id": "security",
|
|
4
4
|
"name": "Security Assessments",
|
|
5
|
-
"version": "0.3.
|
|
5
|
+
"version": "0.3.6",
|
|
6
6
|
"description": "Machine and device security assessments for macOS, Linux, Windows, Android, Chromebook, iPhone and iPad, with explicit measured and manual coverage.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"requires": [{ "id": "auth", "range": ">=1.2.1" }],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.14.
|
|
2
|
+
"version": "0.14.5",
|
|
3
3
|
"files": {
|
|
4
4
|
".gitignore": {
|
|
5
5
|
"sha256": "0d6c69a5cbd2270c9163d8e1563976b6d15131d0ef599e6fbc413ee287a86da0",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"content": "# ssss-project — System Architecture & Design\n\n> Technical design and architecture specification for ssss-project.\n\n## Overview\n\n<High-level summary of the system and its primary goals.>\n\n## Component Architecture\n\n- **Vault Structure**: Typed Markdown documents under `vault/` serving as the source of truth.\n- **Workflows & Execution**: Automated procedures defined in `vault/workflows/` triggered by operational events.\n- **Capabilities & Resources**: Tools and external service integrations required for execution.\n\n## Data & Schema Contracts\n\n<Core entities, external dependencies, and integration interfaces.>\n\n## Open Decisions & Invariants\n\n- SSSS VFS is the single source of truth for application state.\n- Structural business logic is strictly decoupled from private tenant operational data.\n- App-specific primitives reside in `registry/extensions/` within this repository and extend `core`.\n- Core SSSS library (`@gregiteen/ssss-cli`) remains vendor-neutral and dependency-free.\n"
|
|
19
19
|
},
|
|
20
20
|
"package.json": {
|
|
21
|
-
"sha256": "
|
|
22
|
-
"content": "{\n \"name\": \"ssss-project\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"description\": \"An SSSS-native project — Markdown vault as source of truth.\",\n \"scripts\": {\n \"ssss\": \"ssss\",\n \"test\": \"node --test\",\n \"export\": \"ssss export vault --profile sale --out dist/bundle.ucw.json\",\n \"validate\": \"ssss conformance --engine\"\n },\n \"dependencies\": {\n \"@gregiteen/ssss-cli\": \"github:gregiteen/ssss#v0.14.
|
|
21
|
+
"sha256": "ea77c2944b853999741a8e603de257604048c63b5db8754a0e8b92f383ff973b",
|
|
22
|
+
"content": "{\n \"name\": \"ssss-project\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"description\": \"An SSSS-native project — Markdown vault as source of truth.\",\n \"scripts\": {\n \"ssss\": \"ssss\",\n \"test\": \"node --test\",\n \"export\": \"ssss export vault --profile sale --out dist/bundle.ucw.json\",\n \"validate\": \"ssss conformance --engine\"\n },\n \"dependencies\": {\n \"@gregiteen/ssss-cli\": \"github:gregiteen/ssss#v0.14.5\"\n }\n}\n"
|
|
23
23
|
},
|
|
24
24
|
"test/ssss-conformance.test.mjs": {
|
|
25
25
|
"sha256": "f626d2f56799fcfda74375d3ddf546cc181a10caf2df08b72b7f2e36782c9bc1",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"skill": {
|
|
46
|
-
"SKILL.md": "
|
|
47
|
-
"core/SKILL.md": "
|
|
46
|
+
"SKILL.md": "e5c2c0aa2c0fb5480c1f7bdb37928f935e1160bff18fd6b63366a04f3e281938",
|
|
47
|
+
"core/SKILL.md": "12543720135f13650efcd7afd751e3253996692c6ab805fd7da99788b6fc4af9",
|
|
48
48
|
"core/references/core-registry.json": "16831aa3b6be3f561a9ca7abdc36065a4843ff595aa3acf5c3fb8af2d733b7e3",
|
|
49
49
|
"core/references/ssss-spec.md": "cc319e78b1b568651d5717695348363349d502c0e20663da9858369022ddfc3b",
|
|
50
50
|
"core/scripts/maintain.mjs": "eebcae898f2ce0cf3f0059c6f6737bee8877409de2d370d54a4015a9a82414e9",
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-ssss",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "tr-plugin-ssss",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.3",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@gregiteen/ssss-cli": "0.14.
|
|
12
|
+
"@gregiteen/ssss-cli": "0.14.5"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"node_modules/@gregiteen/ssss-cli": {
|
|
16
|
-
"version": "0.14.
|
|
17
|
-
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.
|
|
18
|
-
"integrity": "sha512-
|
|
16
|
+
"version": "0.14.5",
|
|
17
|
+
"resolved": "https://registry.npmjs.org/@gregiteen/ssss-cli/-/ssss-cli-0.14.5.tgz",
|
|
18
|
+
"integrity": "sha512-qVEYOocnwn97uJ0eDzmuwN06CYsYWr2t3+iKylpisBHX4wlLWk7P8EmFFdBlx7NyKVIZDDeYT164Gd7/T8UGgw==",
|
|
19
19
|
"license": "ISC",
|
|
20
20
|
"bin": {
|
|
21
21
|
"ssss": "scripts/ssss.mjs"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-ssss",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Canonical SSSS distribution, scaffolding and validation for Total Recall installations.",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"check:ssss-conformance": "node cli.mjs conformance"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@gregiteen/ssss-cli": "0.14.
|
|
22
|
+
"@gregiteen/ssss-cli": "0.14.5"
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT"
|
|
25
25
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
3
|
"id": "ssss",
|
|
4
4
|
"name": "SSSS",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.3",
|
|
6
6
|
"description": "Canonical SSSS distribution, scaffolding and validation for Total Recall installations.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"use_cases": ["software-development", "state-conformance"],
|
package/src/cli/connect.mjs
CHANGED
|
@@ -80,11 +80,10 @@ export const CLIENTS = {
|
|
|
80
80
|
},
|
|
81
81
|
openclaw: {
|
|
82
82
|
label: 'OpenClaw',
|
|
83
|
-
mode: '
|
|
83
|
+
mode: 'symlink',
|
|
84
84
|
enforcement: 'enforced',
|
|
85
85
|
enforcementReason: 'before_tool_call hook denies unreceipted tool calls with exit 2',
|
|
86
|
-
|
|
87
|
-
agentsTarget: 'AGENTS.md',
|
|
86
|
+
target: 'AGENTS.md',
|
|
88
87
|
},
|
|
89
88
|
cursor: {
|
|
90
89
|
label: 'Cursor',
|
|
@@ -880,32 +879,6 @@ export default async function connect(args) {
|
|
|
880
879
|
result.notes.push(` DeepSeek Harness MEMORY.md → ${globalMemPath}`);
|
|
881
880
|
}
|
|
882
881
|
result.notes.push(` DeepSeek Harness AGENTS.md → INSTRUCTIONS.md`);
|
|
883
|
-
} else if (preset.mode === 'openclaw') {
|
|
884
|
-
// OpenClaw: write MEMORY.md + symlink AGENTS.md in cwd
|
|
885
|
-
const instructions = readInstructions(cwd, agentDir);
|
|
886
|
-
if (!instructions) throw new Error('No INSTRUCTIONS.md found. Run npx total-recall init or compile first.');
|
|
887
|
-
// MEMORY.md — curated facts extracted from instructions
|
|
888
|
-
const memPath = path.join(cwd, preset.memoryTarget);
|
|
889
|
-
if (!fs.existsSync(memPath) || opts.force) {
|
|
890
|
-
fs.writeFileSync(memPath, instructions, 'utf8');
|
|
891
|
-
}
|
|
892
|
-
// AGENTS.md — symlink to INSTRUCTIONS.md
|
|
893
|
-
const agentsPath = path.join(cwd, preset.agentsTarget);
|
|
894
|
-
if (pathExists(agentsPath)) {
|
|
895
|
-
if (opts.force) {
|
|
896
|
-
try {
|
|
897
|
-
fs.unlinkSync(agentsPath);
|
|
898
|
-
} catch {
|
|
899
|
-
fs.rmSync(agentsPath, { force: true, recursive: true });
|
|
900
|
-
}
|
|
901
|
-
fs.symlinkSync('INSTRUCTIONS.md', agentsPath);
|
|
902
|
-
}
|
|
903
|
-
} else {
|
|
904
|
-
fs.symlinkSync('INSTRUCTIONS.md', agentsPath);
|
|
905
|
-
}
|
|
906
|
-
result.projection = { targetPath: memPath, action: 'written' };
|
|
907
|
-
result.notes.push(` OpenClaw MEMORY.md written to ${memPath}`);
|
|
908
|
-
result.notes.push(` OpenClaw AGENTS.md → INSTRUCTIONS.md`);
|
|
909
882
|
} else if (preset.mode === 'vault') {
|
|
910
883
|
result.projection = writeVaultProjection(agentDir, preset, opts);
|
|
911
884
|
const folderName = result.projection.folderName || preset.folderName;
|
package/src/cli/context.mjs
CHANGED
|
@@ -61,6 +61,7 @@ async function printCompacted({ query, actions, budget, format, version, rulesHa
|
|
|
61
61
|
if (format !== 'json') return result.context;
|
|
62
62
|
const payload = { ready: true, compacted: true, ranking: result.ranking, context: result.context, counts: result.counts,
|
|
63
63
|
stats: { version, rules_hash: rulesHash, budget, retrieval: summarizeRetrieval(knowledge?.summary), token_measurement: 'estimated_chars_divided_by_four' } };
|
|
64
|
+
if (result.evidenceStart !== undefined) payload.evidence_start = result.evidenceStart;
|
|
64
65
|
for (let index = 0; index < 10; index++) {
|
|
65
66
|
const tokens = estimateTokens(`${JSON.stringify(payload)}\n`);
|
|
66
67
|
if (tokens === payload.stats.total_tokens) break;
|
package/src/cli/ingest-okf.mjs
CHANGED
|
@@ -11,7 +11,7 @@ export async function runOkfIngest(args) {
|
|
|
11
11
|
dryRun: false,
|
|
12
12
|
category: null,
|
|
13
13
|
importance: null,
|
|
14
|
-
onConflict: '
|
|
14
|
+
onConflict: 'skip',
|
|
15
15
|
typeMap: null,
|
|
16
16
|
help: false
|
|
17
17
|
};
|
|
@@ -118,10 +118,10 @@ function printIngestOkfHelp() {
|
|
|
118
118
|
|
|
119
119
|
Options:
|
|
120
120
|
--dry-run Validate concepts and preview import without writing
|
|
121
|
-
--category <name>
|
|
121
|
+
--category <name> Choose a descriptive category for imported concepts
|
|
122
122
|
--importance <1-5> Override default importance (default: 3)
|
|
123
|
-
--on-conflict <strategy>
|
|
124
|
-
--type-map <mapping>
|
|
123
|
+
--on-conflict <strategy> 'skip' (default), 'warn' (report and skip), or 'overwrite' (same imported concept)
|
|
124
|
+
--type-map <mapping> Map types to descriptive categories, e.g. "Type A=facts,Type B=concepts"
|
|
125
125
|
--global Target the global brain
|
|
126
126
|
--project Target the project brain (default)
|
|
127
127
|
--help, -h Show this help
|
package/src/cli/release.mjs
CHANGED
|
@@ -141,7 +141,10 @@ export async function tarballServed(pkg, version, { exec = spawnSync, fetchImpl
|
|
|
141
141
|
* Wait until a just-published version can be installed: listed as latest, and its tarball served.
|
|
142
142
|
* 3.42.0 took about six minutes and 3.42.1 about eight, its listing four minutes ahead of its tarball.
|
|
143
143
|
*/
|
|
144
|
-
|
|
144
|
+
/** npm has taken 8 and then 23 minutes to serve an accepted publish, so a shorter wait reports failure on a good release. */
|
|
145
|
+
export const REGISTRY_WAIT = Object.freeze({ attempts: 120, delayMs: 20000 });
|
|
146
|
+
|
|
147
|
+
export async function awaitPublished(pkg, version, { attempts = REGISTRY_WAIT.attempts, delayMs = REGISTRY_WAIT.delayMs, exec = spawnSync, sleep, tarball = tarballServed } = {}) {
|
|
145
148
|
const pause = sleep || ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
146
149
|
let last = null;
|
|
147
150
|
for (let i = 0; i < attempts; i++) {
|
package/src/cli/update.mjs
CHANGED
|
@@ -79,7 +79,9 @@ function printHelp() {
|
|
|
79
79
|
writing package.json or the lockfile. Register it to develop it here.
|
|
80
80
|
total-recall update --automatic [--json]
|
|
81
81
|
Daemon maintenance: update both packages, ensure defaults, update every
|
|
82
|
-
installed plugin from its recorded source and refresh surfaces.
|
|
82
|
+
installed plugin from its recorded source and refresh surfaces. Where a
|
|
83
|
+
per-user service (LaunchAgent, systemd user unit) runs the server from
|
|
84
|
+
the global install, also restart a stale server and verify /health.
|
|
83
85
|
total-recall update --status [--json]
|
|
84
86
|
Read the actual last automatic maintenance report without starting work.
|
|
85
87
|
Also reports what the server on this host runs against the release.
|
|
@@ -96,6 +98,7 @@ function printHelp() {
|
|
|
96
98
|
|
|
97
99
|
Env:
|
|
98
100
|
TR_AUTO_UPDATE_PACKAGE=0 Disable daemon cron auto-update (default: on)
|
|
101
|
+
TR_SERVER_AUTO_RESTART=0 Report a stale server instead of restarting it (default: on)
|
|
99
102
|
TR_SYNC_REPOS=/a:/b Extra project roots
|
|
100
103
|
|
|
101
104
|
Source monorepos named ${PACKAGE_NAME} are skipped (use git, not npm into self).
|
|
@@ -13,6 +13,7 @@ import { updateMeshBrainPackages } from './mesh-brain-updates.mjs';
|
|
|
13
13
|
import { updateSourceBrainPackages } from './source-brain-updates.mjs';
|
|
14
14
|
import { updateInstalledPlugins } from './plugin-updates.mjs';
|
|
15
15
|
import { runningServerStatus } from './running-server.mjs';
|
|
16
|
+
import { replaceStaleServer } from './server-restart.mjs';
|
|
16
17
|
|
|
17
18
|
export function automaticUpdateStatus(brainDir) {
|
|
18
19
|
let last;
|
|
@@ -37,7 +38,7 @@ export function startAutomaticBrainUpdates({brainDir,intervalMs=60*60*1000,run=r
|
|
|
37
38
|
return {tick,stop(){stopped=true;clearInterval(timer);}};
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
export async function runAutomaticBrainUpdates({brainDir,fleet=false,force=false,skipThrottle=false,intervalMs=60*60*1000,update=updateAllBrains,compile=maintainCliSurfaces,globalUpdate=updateGlobalBrainPackages,meshUpdate=updateMeshBrainPackages,sourceUpdate=updateSourceBrainPackages,pluginUpdate=updateInstalledPlugins,skillMaintenance=maintainPortableSkills,serverCheck=runningServerStatus,now=Date.now}={}) {
|
|
41
|
+
export async function runAutomaticBrainUpdates({brainDir,fleet=false,force=false,skipThrottle=false,intervalMs=60*60*1000,update=updateAllBrains,compile=maintainCliSurfaces,globalUpdate=updateGlobalBrainPackages,meshUpdate=updateMeshBrainPackages,sourceUpdate=updateSourceBrainPackages,pluginUpdate=updateInstalledPlugins,skillMaintenance=maintainPortableSkills,serverCheck=runningServerStatus,replaceServer=replaceStaleServer,now=Date.now}={}) {
|
|
41
42
|
if(!force && !isPackageAutoUpdateEnabled())return {skipped:true,reason:'disabled',results:[]};
|
|
42
43
|
const file=path.join(brainDir,'memory-derived/automatic-brain-updates.json');
|
|
43
44
|
let saved;try{saved=JSON.parse(fs.readFileSync(file,'utf8'));}catch{}
|
|
@@ -65,16 +66,20 @@ export async function runAutomaticBrainUpdates({brainDir,fleet=false,force=false
|
|
|
65
66
|
const plugins=await pluginUpdate({roots:[path.resolve(brainDir,'../../..')]});
|
|
66
67
|
const mesh=fleet && summary.versions?await meshUpdate({versions:summary.versions,version:summary.versions['total-recall-brain']}):{failed:0,results:[],scope:'local-only'};
|
|
67
68
|
const changed=summary.updated>0 || plugins.updated>0 || global.results.some(row=>row.status==='updated') || sources.results.some(row=>row.status==='updated') || JSON.stringify(saved?.versions)!==JSON.stringify(summary.versions);
|
|
68
|
-
// A lagging server is reported and not counted as a failure: maintenance cannot fix it, and
|
|
69
|
-
// a failure would retry every five minutes. Replacing one in production is a deploy decision.
|
|
70
|
-
const server=await serverCheck({brainDir,latest:summary.versions?.['total-recall-brain']});
|
|
71
|
-
if(server.status==='stale' || server.status==='down')logger.error('automatic-brain-updates',`Running server: ${server.reason}`);
|
|
72
69
|
const skills=await skillMaintenance({brainDir});
|
|
73
70
|
const surfaces=await compile({brainDir,force:changed || skills.updated > 0});
|
|
71
|
+
// Last, so a replaced server starts on everything this run moved. Where maintenance cannot
|
|
72
|
+
// replace it, a lagging server is reported and not counted as a failure, which would retry
|
|
73
|
+
// every five minutes for nothing: in production that is a deploy decision. Where it can, a
|
|
74
|
+
// hold or a failed attempt is this machine's own failure, which is what makes a peer dispatch it again.
|
|
75
|
+
let server=await serverCheck({brainDir,latest:summary.versions?.['total-recall-brain']});
|
|
76
|
+
if(server.status==='stale')server=await replaceServer({brainDir,server,globalRoot:global.root,previous:saved?.server});
|
|
77
|
+
if(server.status==='stale' || server.status==='down')logger.error('automatic-brain-updates',`Running server: ${server.replacement?.reason || server.reason}`);
|
|
78
|
+
const serverFailed=['held','failed'].includes(server.replacement?.state)?1:0;
|
|
74
79
|
// local_failed is this node's own maintenance. Peers judge a node by it, not by
|
|
75
80
|
// `failed`, which also counts the node's view of its peers: judging by that made
|
|
76
81
|
// every fleet pass mark every peer failed forever, each because the others had.
|
|
77
|
-
const local_failed=(summary.failed || 0)+global.failed+sources.failed+plugins.failed+(skills.failed || 0)+(surfaces.ok?0:surfaces.results.filter(row=>row.status==='failed').length);
|
|
82
|
+
const local_failed=(summary.failed || 0)+global.failed+sources.failed+plugins.failed+(skills.failed || 0)+(surfaces.ok?0:surfaces.results.filter(row=>row.status==='failed').length)+serverFailed;
|
|
78
83
|
report={...summary,global,sources,plugins,mesh,server,skills,surfaces,local_failed,failed:local_failed+mesh.failed,checkedAt:now()};
|
|
79
84
|
}catch(error){report={failed:1,error:error.message,checkedAt:now(),results:[]};}
|
|
80
85
|
const temporary=`${file}.${process.pid}.tmp`;fs.writeFileSync(temporary,JSON.stringify(report,null,2));fs.renameSync(temporary,file);
|
|
@@ -19,6 +19,13 @@ const sections = ['dependencies', 'devDependencies', 'optionalDependencies', 'pe
|
|
|
19
19
|
const ignored = new Set(['node_modules', 'vendor', 'dist', 'build', 'coverage', 'venv',
|
|
20
20
|
'test', 'tests', '__tests__', 'fixtures', 'tmp', 'scratch', 'scaffold', 'memory-derived']);
|
|
21
21
|
const canonical = key => key === '@ssss/cli' ? '@gregiteen/ssss-cli' : key;
|
|
22
|
+
// Plugins also force the engine alias through `overrides`. Those pins move with the dependency,
|
|
23
|
+
// or a consumer ends up asking for two versions of the same package.
|
|
24
|
+
const overrideKeys = pkg => Object.entries(pkg.overrides || {})
|
|
25
|
+
.filter(([key, spec]) => typeof spec === 'string' && BRAIN_PACKAGES.includes(canonical(key)) && canonical(key) !== pkg.name)
|
|
26
|
+
.map(([key]) => key);
|
|
27
|
+
const overridesLag = (pkg, versions) => overrideKeys(pkg)
|
|
28
|
+
.some(key => versions[canonical(key)] && pkg.overrides[key] !== targetSpec(key, versions[canonical(key)]));
|
|
22
29
|
const read = file => JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
23
30
|
const isLink = file => { try { return fs.lstatSync(file).isSymbolicLink(); } catch { return false; } };
|
|
24
31
|
export const brainUpdateLockPath = owner => path.join(os.tmpdir(),
|
|
@@ -261,7 +268,7 @@ export async function updateAllBrains(opts = {}) {
|
|
|
261
268
|
row.status = 'failed'; row.error = 'Newer local/preview package; refusing an implicit downgrade'; continue;
|
|
262
269
|
}
|
|
263
270
|
const shared = isLink(path.join(owner.owner, 'node_modules')) || isLink(path.join(consumer.root, 'node_modules'));
|
|
264
|
-
const needsChange = shared || consumer.deps.some(dep => {
|
|
271
|
+
const needsChange = shared || (!consumer.runtimeOnly && overridesLag(consumer.pkg, versions)) || consumer.deps.some(dep => {
|
|
265
272
|
const pinLags = !consumer.runtimeOnly && dep.declared !== targetSpec(dep.key, versions[dep.package]);
|
|
266
273
|
if (absentDevDep(dep)) return pinLags;
|
|
267
274
|
return pinLags || dep.version !== versions[dep.package]
|
|
@@ -296,6 +303,9 @@ export async function updateAllBrains(opts = {}) {
|
|
|
296
303
|
saved.set(consumer.file, text);
|
|
297
304
|
const pkg = read(consumer.file);
|
|
298
305
|
for (const dep of consumer.deps) pkg[dep.section][dep.key] = targetSpec(dep.key, versions[dep.package]);
|
|
306
|
+
for (const key of overrideKeys(pkg)) {
|
|
307
|
+
if (versions[canonical(key)]) pkg.overrides[key] = targetSpec(key, versions[canonical(key)]);
|
|
308
|
+
}
|
|
299
309
|
const indent = /\n([ \t]+)"/.exec(text)?.[1] || 2;
|
|
300
310
|
fs.writeFileSync(consumer.file, JSON.stringify(pkg, null, indent) + '\n');
|
|
301
311
|
}
|
|
@@ -62,6 +62,9 @@ export function compactRules(items, { budget, expand = [], header, complete = fa
|
|
|
62
62
|
if (unknown.length) throw new Error(`Cannot expand rules not in this capsule: ${unknown.join(', ')}`);
|
|
63
63
|
const duplicateOf = findDuplicates(ranked.filter(item => !expand.includes(item.slug)));
|
|
64
64
|
const tiers = new Map(ranked.map(item => [item.slug, 'omitted']));
|
|
65
|
+
const isEvidence = item => item.taskEvidence && !item.required;
|
|
66
|
+
const supplement = supplemental.filter(item => item.text && !isEvidence(item)).map(item => item.text.trim());
|
|
67
|
+
const evidence = supplemental.filter(item => item.text && isEvidence(item)).map(item => item.text.trim()).join('\n\n---\n\n');
|
|
65
68
|
|
|
66
69
|
const render = () => {
|
|
67
70
|
const of = tier => ranked.filter(item => tiers.get(item.slug) === tier);
|
|
@@ -71,10 +74,11 @@ export function compactRules(items, { budget, expand = [], header, complete = fa
|
|
|
71
74
|
const blocks = [
|
|
72
75
|
...full.map(item => item.text.trim()),
|
|
73
76
|
...summary.map(item => `[${item.slug}] ${summarizeRule(item.body)}`),
|
|
74
|
-
...
|
|
77
|
+
...supplement,
|
|
75
78
|
];
|
|
76
79
|
if (reference.length) blocks.push(`Referenced: ${reference.map(item => item.slug).join(', ')}`);
|
|
77
80
|
if (duplicate.length) blocks.push(`Duplicates: ${duplicate.map(item => `${item.slug} (of ${duplicateOf.get(item.slug)})`).join(', ')}`);
|
|
81
|
+
if (evidence) blocks.push(evidence);
|
|
78
82
|
const body = blocks.join('\n\n---\n\n');
|
|
79
83
|
// The token count sits inside the text it counts, so iterate to a stable value.
|
|
80
84
|
let tokens = estimateTokens(body);
|
|
@@ -142,5 +146,6 @@ export function compactRules(items, { budget, expand = [], header, complete = fa
|
|
|
142
146
|
for (const slug of duplicateOf.keys()) tryTier(ranked.find(item => item.slug === slug), 'duplicate');
|
|
143
147
|
|
|
144
148
|
const { context, counts, tokens } = render();
|
|
145
|
-
return { context, counts, tokens, tiers: Object.fromEntries(tiers)
|
|
149
|
+
return { context, counts, tokens, tiers: Object.fromEntries(tiers),
|
|
150
|
+
...(evidence && { evidenceStart: context.length - evidence.length }) };
|
|
146
151
|
}
|
|
@@ -109,7 +109,10 @@ export async function compileContext({
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
const cliContributions = cliVerbContribution ? [cliVerbContribution] : [];
|
|
112
|
-
const
|
|
112
|
+
const evidence = knowledge.summary.selected
|
|
113
|
+
? knowledge.contributions.map(item => ({ ...item, taskEvidence: true }))
|
|
114
|
+
: knowledge.contributions;
|
|
115
|
+
const supporting = [...evidence, ...cliContributions];
|
|
113
116
|
const result = assembleContext([...required, ...supporting, ...contributions], { total: b.total });
|
|
114
117
|
const evidenceMissing = supporting.some(item => !result.stats.contributions.some(placed => placed.id === item.id));
|
|
115
118
|
// Compaction may reclaim rule explanation space; never claim readiness after losing selected task evidence.
|
|
@@ -163,6 +166,8 @@ export function capsuleResponse(result, { total = 4000, debug = false, format =
|
|
|
163
166
|
retrieval: summarizeRetrieval(result.stats.retrieval),
|
|
164
167
|
};
|
|
165
168
|
const response = { ready: result.ready, context: result.context, stats };
|
|
169
|
+
// This offset refers to the decoded context string, not the escaped JSON bytes.
|
|
170
|
+
if (result.evidenceStart !== undefined) response.evidence_start = result.evidenceStart;
|
|
166
171
|
stats.budget = total;
|
|
167
172
|
// Counts affect serialization themselves. Iterate to a stable representation.
|
|
168
173
|
for (let i = 0; i < 20; i++) {
|
|
@@ -100,14 +100,18 @@ export function assembleContext(contributions, { total = 4000 } = {}) {
|
|
|
100
100
|
if (estimateTokens(render([...selected, item])) <= total) selected.push(item);
|
|
101
101
|
else excluded.push(item.id);
|
|
102
102
|
}
|
|
103
|
-
const
|
|
103
|
+
const isEvidence = item => item.taskEvidence && !item.required;
|
|
104
|
+
const evidence = selected.filter(isEvidence);
|
|
105
|
+
const ordered = [...selected.filter(item => !isEvidence(item)), ...evidence];
|
|
106
|
+
const context = render(ordered);
|
|
107
|
+
const evidenceText = render(evidence);
|
|
104
108
|
const totalTokens = estimateTokens(context);
|
|
105
|
-
return { context, ready: requiredTokens <= total, stats: {
|
|
109
|
+
return { context, ...(evidenceText && { evidenceStart: context.length - evidenceText.length }), ready: requiredTokens <= total, stats: {
|
|
106
110
|
token_measurement: 'estimated_chars_divided_by_four', total_tokens: totalTokens,
|
|
107
111
|
budget_used: totalTokens, budget_remaining: Math.max(0, total - totalTokens),
|
|
108
112
|
required_tokens: requiredTokens, overflow_tokens: Math.max(0, requiredTokens - total),
|
|
109
113
|
required_ids: required.map(c => c.id), excluded_ids: excluded,
|
|
110
|
-
contributions:
|
|
114
|
+
contributions: ordered.map(c => ({ id: c.id, required: Boolean(c.required), chars: c.text.length, estimated_tokens: estimateTokens(c.text) })),
|
|
111
115
|
version: crypto.createHash('sha256').update(JSON.stringify({ total, contributions })).digest('hex'),
|
|
112
116
|
} };
|
|
113
117
|
}
|
|
@@ -37,6 +37,28 @@ export function getDaemonStatus() {
|
|
|
37
37
|
return status === 'not-started' ? 'not_started' : status === 'stopped' ? 'dead' : status;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Remove the lock of a daemon that is gone, for a server told to run none.
|
|
42
|
+
*
|
|
43
|
+
* startDaemon is the only other thing that recovers this lock, and such a server never
|
|
44
|
+
* calls it. A daemon that went down with the machine left a lock nothing would ever
|
|
45
|
+
* clear, so the server reported `dead` and `degraded` for good. Only a lock whose process
|
|
46
|
+
* is verified gone is removed: a live process or one that cannot be identified keeps it.
|
|
47
|
+
* @returns {boolean} True if a lock was removed.
|
|
48
|
+
*/
|
|
49
|
+
export function clearStaleDaemonLock({ observe = getDaemonObservation } = {}) {
|
|
50
|
+
try {
|
|
51
|
+
const before = fs.readFileSync(PID_FILE, 'utf8');
|
|
52
|
+
if (observe().status !== 'stopped') return false;
|
|
53
|
+
if (fs.readFileSync(PID_FILE, 'utf8') !== before) return false;
|
|
54
|
+
fs.unlinkSync(PID_FILE);
|
|
55
|
+
logger.info('daemon-control', `Removed the lock of daemon PID ${before.trim()}, which is gone. This server runs no daemon.`);
|
|
56
|
+
return true;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
40
62
|
/**
|
|
41
63
|
* Detaches the daemon script in the background and writes its PID to file.
|
|
42
64
|
* @returns {number} The PID of the newly spawned daemon.
|
|
@@ -55,5 +55,5 @@ export function updateGlobalBrainPackages({versions,exec=spawnSync,sourceUpdate=
|
|
|
55
55
|
if(row.status==='failed')row.error=result.error?.message || result.stderr?.slice(-1000) || 'Global version verification failed';
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
return {failed:results.filter(row=>row.status==='failed').length,results};
|
|
58
|
+
return {failed:results.filter(row=>row.status==='failed').length,results,root};
|
|
59
59
|
}
|
|
@@ -30,7 +30,8 @@ export async function updateMeshBrainPackages({version,versions,listNodes,exec,n
|
|
|
30
30
|
let report,serving;try{const status=JSON.parse(observed.stdout);report=status.last;serving=status.server;}catch{}
|
|
31
31
|
const localFailed=report?(report.local_failed ?? Math.max(0,(report.failed || 0)-(report.mesh?.failed || 0))):null;
|
|
32
32
|
const current=observed.success && report && localFailed===0 && now()>=report.checkedAt && now()-report.checkedAt<2*60*60*1000 && report.versions?.['total-recall-brain']===version && (!versions?.['@gregiteen/ssss-cli'] || report.versions?.['@gregiteen/ssss-cli']===versions['@gregiteen/ssss-cli']);
|
|
33
|
-
// Maintenance
|
|
33
|
+
// Maintenance could not fix this server, or it would have reported a local failure above and
|
|
34
|
+
// been dispatched again, so this is reported. One that lags since the last run waits for that run's report to age.
|
|
34
35
|
if(current && serving?.status==='stale'){row.status='failed';row.report=report;row.server=serving;row.error=serving.reason;continue;}
|
|
35
36
|
if(current){row.status='verified';row.report=report;continue;}
|
|
36
37
|
// npm exec pins the verified release so an old installed CLI can bootstrap
|