total-recall-brain 3.40.7 → 3.41.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/bin/total-recall-memory.mjs +0 -0
- package/bin/total-recall.mjs +9 -40
- package/docs/reference/cli-reference.md +65 -1
- package/frontend/dist/assets/{index-AGUes-VG.css → index-BG9NkVUy.css} +1 -1
- package/frontend/dist/assets/{index-Bt5iVPZj.js → index-BtuiZqwP.js} +20 -7
- package/frontend/dist/index.html +2 -2
- package/frontend/src/components/plugins/PluginPanel.tsx +31 -5
- package/frontend/src/components/plugins/card/CardEngine.tsx +15 -23
- package/frontend/src/components/plugins/card/CardScenes.tsx +52 -23
- package/frontend/src/components/plugins/card/card.css +2 -5
- package/frontend/src/components/plugins/card/contract.ts +13 -19
- package/frontend/src/components/plugins/card/format.ts +8 -1
- package/frontend/src/components/plugins/card/widgets.tsx +4 -35
- package/frontend/src/components/plugins/plugin-frame.ts +30 -3
- package/frontend/src/pages/PluginsPage.tsx +3 -2
- package/package.json +1 -1
- package/scaffold/.agent/skills/plugin/SKILL.md +110 -0
- package/scaffold/.agent/skills/plugin/evals/README.md +53 -0
- package/scaffold/.agent/skills/plugin/evals/cases/01-fabricated-seed.mjs +42 -0
- package/scaffold/.agent/skills/plugin/evals/cases/02-reassuring-default.mjs +39 -0
- package/scaffold/.agent/skills/plugin/evals/cases/03-declared-template.mjs +32 -0
- package/scaffold/.agent/skills/plugin/evals/cases/04-card-collects-credential.mjs +46 -0
- package/scaffold/.agent/skills/plugin/evals/cases/05-host-leak-in-scaffold.mjs +55 -0
- package/scaffold/.agent/skills/plugin/evals/cases/06-correct-plugin.mjs +92 -0
- package/scaffold/.agent/skills/plugin/evals/run.mjs +118 -0
- package/scaffold/.agent/skills/plugin/prompts/01-function.md +29 -0
- package/scaffold/.agent/skills/plugin/prompts/02-surfaces.md +43 -0
- package/scaffold/.agent/skills/plugin/prompts/03-scaffold.md +31 -0
- package/scaffold/.agent/skills/plugin/prompts/04-cli.md +49 -0
- package/scaffold/.agent/skills/plugin/prompts/05-credentials.md +41 -0
- package/scaffold/.agent/skills/plugin/prompts/06-card.md +46 -0
- package/scaffold/.agent/skills/plugin/prompts/07-scaffold.md +52 -0
- package/scaffold/.agent/skills/plugin/prompts/08-verify.md +43 -0
- package/scaffold/.agent/skills/plugin/references/anti-patterns.md +123 -0
- package/scaffold/.agent/skills/plugin/references/card.md +90 -0
- package/scaffold/.agent/skills/plugin/references/scaffold.md +120 -0
- package/scaffold/.agent/skills/plugin/references/surfaces.md +206 -0
- package/scaffold/.agent/skills/plugin/scripts/record.mjs +360 -0
- package/scaffold/.agent/skills/plugin/subagents/card-designer.md +60 -0
- package/scaffold/.agent/skills/plugin/subagents/plugin-reviewer.md +55 -0
- package/scaffold/.agent/skills/plugin/subagents/scaffold-extractor.md +71 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +71 -1441
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +7 -5
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +3 -44
- package/scaffold/.agent/skills/total-recall/plugins/auth/scripts/agent-login-pty.py +185 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +20 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/host-secrets-store.mjs +15 -0
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-env-export.mjs +6 -4
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-remote-deploy.mjs +1 -0
- package/scaffold/.agent/skills/total-recall/plugins/cli-agents/plugin.json +0 -24
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/plugin.json +0 -21
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +0 -32
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +11 -0
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/README.md +5 -2
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +1 -28
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/DESIGN.md +95 -13
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/ui/card.js +553 -340
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +0 -36
- package/scaffold/.agent/skills/total-recall/plugins/mesh/ui/card.js +383 -400
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +0 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +0 -28
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +4 -4
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +0 -32
- package/scaffold/.agent/skills/total-recall/references/auth.md +3 -1
- package/scaffold/.agent/skills/total-recall/references/memory.md +4 -0
- package/scaffold/.agent/skills/total-recall/references/openwiki.md +2 -0
- package/scaffold/.agent/skills/total-recall/references/operations.md +12 -0
- package/src/cli/brain.mjs +4 -2
- package/src/cli/context-stats.mjs +104 -0
- package/src/cli/context.mjs +8 -0
- package/src/cli/daemon.mjs +10 -1
- package/src/cli/export.mjs +3 -2
- package/src/cli/ingest-okf.mjs +12 -15
- package/src/cli/init.mjs +0 -85
- package/src/cli/lint.mjs +3 -2
- package/src/cli/plugin/copies.mjs +68 -0
- package/src/cli/plugin/create.mjs +22 -24
- package/src/cli/plugin/index.mjs +49 -3
- package/src/cli/plugin/search.mjs +19 -2
- package/src/cli/rebuild.mjs +2 -0
- package/src/cli/remember.mjs +23 -0
- package/src/cli/status.mjs +10 -3
- package/src/cli/update.mjs +3 -2
- package/src/core/action-predictor.mjs +161 -0
- package/src/core/app-deploy/runtime-cli/node.mjs.tmpl +20 -3
- package/src/core/app-deploy/source.mjs +16 -9
- package/src/core/automatic-brain-updates.mjs +6 -3
- package/src/core/brain-registry.mjs +19 -2
- package/src/core/brain-state.mjs +23 -0
- package/src/core/cli-commands.mjs +1 -0
- package/src/core/cli-maintenance.mjs +1 -1
- package/src/core/cli-semantic-index.mjs +1 -1
- package/src/core/command-surface.mjs +3 -3
- package/src/core/composed-command-resolution.mjs +21 -0
- package/src/core/config.mjs +84 -0
- package/src/core/confined-memory.mjs +93 -0
- package/src/core/context-telemetry.mjs +214 -0
- package/src/core/daemon-control.mjs +14 -43
- package/src/core/fast-recall.mjs +1 -1
- package/src/core/memory-brain.mjs +2 -0
- package/src/core/plugin-activation.mjs +38 -6
- package/src/core/plugin-bundle.mjs +54 -0
- package/src/core/plugin-catalog.mjs +1 -1
- package/src/core/plugin-context.mjs +1 -1
- package/src/core/plugin-contracts/card.mjs +69 -37
- package/src/core/plugin-loader.mjs +5 -6
- package/src/core/plugin-runner.mjs +13 -6
- package/src/core/plugin-runtime.mjs +5 -4
- package/src/core/plugin-setup.mjs +5 -3
- package/src/core/plugin-state-store.mjs +12 -1
- package/src/core/plugin-state.mjs +46 -5
- package/src/core/plugin-store.mjs +78 -3
- package/src/core/plugin-tasks.mjs +3 -1
- package/src/core/plugin-updates.mjs +117 -0
- package/src/core/plugin-vendor.mjs +10 -4
- package/src/core/project-brain.mjs +14 -41
- package/src/core/project-id.mjs +4 -1
- package/src/core/required-plugins.mjs +151 -13
- package/src/core/skills-registry.mjs +27 -3
- package/src/core/ssss-kernel-bridge.mjs +3 -1
- package/src/core/startup-health.mjs +66 -16
- package/src/core/surface.mjs +51 -44
- package/src/core/testing/plugin-fixture.mjs +69 -0
- package/src/core/vault-files.mjs +13 -0
- package/src/core/vault.mjs +4 -30
- package/src/server/index.mjs +13 -1
- package/src/server/invoke-decision-child.mjs +49 -0
- package/src/server/invoke-execution.mjs +87 -0
- package/src/server/invoke-policy.mjs +64 -0
- package/src/server/invoke-read-child.mjs +26 -0
- package/src/server/invoke-targets.mjs +49 -0
- package/src/server/invoke-write-child.mjs +19 -0
- package/src/server/routes/invoke.mjs +314 -0
- package/src/server/routes/plugins.mjs +1 -1
- package/scaffold/.agent/skills/plugins/SKILL.md +0 -57
- package/scaffold/.agent/skills/plugins/references/card-design.md +0 -55
- package/scaffold/.agent/skills/plugins/references/distribution.md +0 -23
- package/scaffold/.agent/skills/plugins/references/manifest-contract.md +0 -90
- package/scaffold/.agent/skills/plugins/references/optimized/index.md +0 -9
- package/scaffold/.agent/skills/plugins/references/optimized/manifest.json +0 -35
- package/scaffold/.agent/skills/plugins/references/optimized/original.md +0 -58
- package/scaffold/.agent/skills/plugins/references/optimized/section-01.md +0 -5
- package/scaffold/.agent/skills/plugins/references/optimized/section-02.md +0 -25
- package/scaffold/.agent/skills/plugins/references/optimized/section-03.md +0 -12
- package/scaffold/.agent/skills/plugins/references/optimized/section-04.md +0 -7
- package/scaffold/.agent/skills/plugins/references/optimized/section-05.md +0 -5
- package/scaffold/.agent/skills/total-recall/openwiki/README.md +0 -10
- package/scaffold/.agent/skills/total-recall/openwiki/architecture.md +0 -5
- package/scaffold/.agent/skills/total-recall/openwiki/ide.md +0 -10
- package/scaffold/.agent/skills/total-recall/openwiki/memory.md +0 -11
- package/scaffold/.agent/skills/total-recall/openwiki/secrets.md +0 -7
- package/scaffold/.agent/skills/total-recall/openwiki/skills.md +0 -7
- package/scaffold/openwiki/README.md +0 -10
- package/scaffold/openwiki/architecture.md +0 -5
- package/scaffold/openwiki/ide.md +0 -10
- package/scaffold/openwiki/memory.md +0 -11
- package/scaffold/openwiki/secrets.md +0 -7
- package/scaffold/openwiki/skills.md +0 -7
- package/src/core/okf-adapter.mjs +0 -559
- package/templates/openwiki/README.md +0 -10
- package/templates/openwiki/architecture.md +0 -5
- package/templates/openwiki/ide.md +0 -10
- package/templates/openwiki/memory.md +0 -11
- package/templates/openwiki/secrets.md +0 -7
- package/templates/openwiki/skills.md +0 -7
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"version": "0.1.1",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"total-recall-brain": "3.40.
|
|
12
|
+
"total-recall-brain": "^3.40.7"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"node_modules/@hexagon/base64": {
|
|
@@ -2556,9 +2556,9 @@
|
|
|
2556
2556
|
}
|
|
2557
2557
|
},
|
|
2558
2558
|
"node_modules/total-recall-brain": {
|
|
2559
|
-
"version": "3.40.
|
|
2560
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.
|
|
2561
|
-
"integrity": "sha512
|
|
2559
|
+
"version": "3.40.7",
|
|
2560
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.7.tgz",
|
|
2561
|
+
"integrity": "sha512-G+sEWXVucI5Zs8uV1ie8P+mV/6cncWX76ES72T5dnPB3sFAwlcG9ous2SYTUaYUOETGB2vHTSo3cV4XWkHQ0Ww==",
|
|
2562
2562
|
"dev": true,
|
|
2563
2563
|
"license": "MIT",
|
|
2564
2564
|
"workspaces": [
|
|
@@ -131,33 +131,5 @@
|
|
|
131
131
|
"status": {
|
|
132
132
|
"command": "status",
|
|
133
133
|
"refresh_seconds": 300
|
|
134
|
-
},
|
|
135
|
-
"card_layout": {
|
|
136
|
-
"template": "dashboard",
|
|
137
|
-
"regions": [
|
|
138
|
-
{
|
|
139
|
-
"widget": "status",
|
|
140
|
-
"title": "Status"
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
"widget": "live",
|
|
144
|
-
"title": "Live view"
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
"widget": "list",
|
|
148
|
-
"title": "Details",
|
|
149
|
-
"source": {
|
|
150
|
-
"command": "hubs"
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"widget": "actions",
|
|
155
|
-
"title": "Commands"
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
"widget": "activity",
|
|
159
|
-
"title": "Recent activity"
|
|
160
|
-
}
|
|
161
|
-
]
|
|
162
134
|
}
|
|
163
135
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"jsdom": "^26.1.0",
|
|
13
|
-
"total-recall-brain": "3.40.
|
|
13
|
+
"total-recall-brain": "^3.40.7"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"node_modules/@asamuzakjp/css-color": {
|
|
@@ -2916,9 +2916,9 @@
|
|
|
2916
2916
|
}
|
|
2917
2917
|
},
|
|
2918
2918
|
"node_modules/total-recall-brain": {
|
|
2919
|
-
"version": "3.40.
|
|
2920
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.
|
|
2921
|
-
"integrity": "sha512
|
|
2919
|
+
"version": "3.40.7",
|
|
2920
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.7.tgz",
|
|
2921
|
+
"integrity": "sha512-G+sEWXVucI5Zs8uV1ie8P+mV/6cncWX76ES72T5dnPB3sFAwlcG9ous2SYTUaYUOETGB2vHTSo3cV4XWkHQ0Ww==",
|
|
2922
2922
|
"dev": true,
|
|
2923
2923
|
"license": "MIT",
|
|
2924
2924
|
"workspaces": [
|
|
@@ -259,37 +259,5 @@
|
|
|
259
259
|
"distribution": {
|
|
260
260
|
"tier": "official",
|
|
261
261
|
"license": "open"
|
|
262
|
-
},
|
|
263
|
-
"card_layout": {
|
|
264
|
-
"template": "vault",
|
|
265
|
-
"regions": [
|
|
266
|
-
{
|
|
267
|
-
"widget": "status",
|
|
268
|
-
"title": "Status"
|
|
269
|
-
},
|
|
270
|
-
{
|
|
271
|
-
"widget": "live",
|
|
272
|
-
"title": "Live view"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
"widget": "list",
|
|
276
|
-
"title": "Details",
|
|
277
|
-
"source": {
|
|
278
|
-
"command": "platforms"
|
|
279
|
-
}
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
"widget": "actions",
|
|
283
|
-
"title": "Commands"
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
"widget": "credentials",
|
|
287
|
-
"title": "Credentials"
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
"widget": "activity",
|
|
291
|
-
"title": "Recent activity"
|
|
292
|
-
}
|
|
293
|
-
]
|
|
294
262
|
}
|
|
295
263
|
}
|
|
@@ -4,7 +4,7 @@ Auth is the credential owner and is shipped in Total Recall scaffold. Its source
|
|
|
4
4
|
|
|
5
5
|
Discover `total-recall auth --help` and `total-recall auth secret --help`. The auth namespace is the only credential command path. Use `auth secret set KEY --stdin` for values, never argv, chat, logs or vault content. `auth secret list` and `catalog` expose metadata. Avoid `get` in a tool transcript; consumers resolve through the auth runtime in-process. Auth API lives under `/api/plugins/auth/secrets`; any retained legacy HTTP route is implemented by auth, never core.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
There is one secrets store per host: the global auth store. The CLI never selects a store from the cwd (`--project` and `--layer` are refused); `TR_SECRETS_BRAIN` is the only override, for deploy, ops and tests. A per-repo `secrets.enc` is breakage: fold it in with `auth secret merge-store <dir>` (a dry run unless `--apply`; conflicts are settled only with `--take` or `--rename`) and archive it encrypted. Existing carrier paths and encrypted data are preserved; no migration may overwrite credentials. No environment credential fallback. Auth alone manages its unlock carriers. Failed unlock/decryption must propagate; never report the store empty after failure. Rekey changes the master carrier, not provider keys: read the current rekey CLI and runbook, update every selected carrier, verify fresh-shell reads and retired-password rejection without exposing either password.
|
|
8
8
|
|
|
9
9
|
For provider key setup, verify against an authenticated provider operation before saving; format-only checks and timeouts are not verification. Require HTTPS except explicit loopback development, reject redirects containing credentials, and return safe errors. Rotation follows verify → store/project → deploy/verify → revoke, respecting the provider's supported recipe and user authorization. Manual provider steps remain manual. Exported environment files are deployment projections, not an alternate credential authority.
|
|
10
10
|
|
|
@@ -22,6 +22,8 @@ Before uninstall, auth decrypts/verifies the source and retains byte-identical e
|
|
|
22
22
|
|
|
23
23
|
Auth card/panel results represent completed operations only. Passkey registration requires browser credential creation and successful server verification. HTTP reachability is not provider authentication or a security audit. Configuration is not an active rotation schedule. The scaffold installs auth and resolves declared dependencies to compatible installed host packages; missing/incompatible dependencies fail initialization.
|
|
24
24
|
|
|
25
|
+
Production services own distinct, app-named keys bound to their repo with `provides` naming the app-facing variable; `auth secret get KEY` or `set KEY` run inside that repo resolves to the app's key, and elsewhere to the plain (developer) key. Read bindings, tags and provides with `auth secret list --json` (metadata only). Metadata writes never move a value's `updated_at`.
|
|
26
|
+
|
|
25
27
|
Internal CLI consumers may use `auth secret get KEY --json`: a missing key returns `{found:false}`; found values remain private to the consuming process. Unlock, parsing and decryption failures are errors. `TR_SECRETS_BRAIN` selects one store for the complete operation; no project-to-global retry is permitted. Consumer transports must parse structured results, propagate failures, use stdin for writes and verify readback. Never run a value-returning command into an agent transcript.
|
|
26
28
|
|
|
27
29
|
## Mesh-identity secret sync
|
|
@@ -5,3 +5,7 @@
|
|
|
5
5
|
Context returns the complete required rule set, not just a relevance-ranked search result. Treat unknown applicability conservatively. Explicit budgets govern readiness. `context:universal` is a curated permanent bootstrap, not an automatic property of every global rule. Do not infer local applicability from global descriptive facts.
|
|
6
6
|
|
|
7
7
|
Use `compile` to rebuild instruction surfaces and indexes after externally maintained skill/rule sources change. Do not delete embeddings databases to force work. Inspect proposals through proposal operations; memory node enumeration excludes proposal documents. Embedding coverage counts eligible memory documents. SSSS registry/envelope validation and event receipts define persistence; projections are derived.
|
|
8
|
+
|
|
9
|
+
Compilation verifies instruction output bytes and canonical file bindings before recording disposable `surface-artifacts.json`; incremental skips require intact outputs as well as unchanged inputs. Missing or edited managed instruction outputs trigger repair. Actual client consumption remains a separate verification step.
|
|
10
|
+
|
|
11
|
+
OKF conversion, import/export, metadata checks and explicit `okf project` index/log generation belong to the OKF plugin. Core `export --okf`, `ingest okf` and `lint --okf` delegate to its declared active adapter and fail if the owner is unavailable. Core compilation never generates OKF index.md or log.md.
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
OpenWiki is a plugin-owned documentation hub and ingestion capability. Discover `total-recall openwiki --help`, then `openwiki hubs --json`. Current hubs discovery reads Markdown files directly under the current project's `openwiki/` directory; ingestion recursively reads a supplied directory. The hub count is a filesystem inventory, not proof of prior graph indexing.
|
|
4
4
|
|
|
5
|
+
Core initialization does not create wiki pages. Use `total-recall openwiki bootstrap --brain <absolute-brain-dir> [--project-root <absolute-repo-dir>] --json` explicitly when seed documentation is wanted. `--dry-run` previews missing pages; existing authored pages and page symlinks are preserved. The OpenWiki plugin owns these templates and their bootstrap implementation.
|
|
6
|
+
|
|
5
7
|
Read existing relevant hubs before changing architecture or capability boundaries. Maintain source-linked hubs for core architecture, plugin ownership, auth/secrets, CRM and current implementation/verification state. Use normal source edits for documentation Markdown; never edit canonical memory files directly. Keep secrets, personal vault contents and generated state out of hubs.
|
|
6
8
|
|
|
7
9
|
Review `openwiki ingest <absolute-directory> --dry-run --project`, then ingest through the plugin without `--dry-run`. `--global` explicitly selects the global brain. The plugin routes each document through validated `remember`; read import/error totals and actual exit status. Verify resulting `openwiki-<path-slug>` documents with local recall. A dry run does not index anything. A backend health probe does not prove graph coverage. Partial imports must be reported and repaired.
|
|
@@ -12,6 +12,18 @@ For research queues, discover `research --help`, select project/global scope exp
|
|
|
12
12
|
|
|
13
13
|
Publication/deployment use the owning push/deploy procedures when authorized. Shared production services require staged health-checked zero-downtime switching and rollback. Do not use a generated restart command as permission to interrupt a serving process.
|
|
14
14
|
|
|
15
|
+
## Optional developer API
|
|
16
|
+
|
|
17
|
+
The full server's `/v1/invoke` requires a named auth-owned PAT with a literal `invoke:full` or `invoke:restricted` mode; legacy wildcards and dashboard sessions do not opt in. Full mode requires full grants throughout the issuer chain and intentionally grants trusted host administration, including auth-owned credentials and nested owner execution. Do not describe it as a sandbox or give it to a restricted consumer to bypass a denial.
|
|
18
|
+
|
|
19
|
+
Restricted `ssss.read` additionally requires `ssss:read` and `brain:server`, uses local server-brain retrieval and spends no provider credits. Restricted `ssss.write` requires `ssss:write` and `brain:server` and creates descriptive facts only through the shared memory owner with generated create-only paths, exact schemas and generator-free local indexing. The same owner supports local `remember fact "content" --confined-fact`. Arbitrary mutation metadata, rule categories, CLI/plugin/composed execution and paid decisions remain unavailable. Capabilities omit denied operations. Fresh role/issuer/expiry/revocation checks, controlled child environment, filesystem permissions, concurrency/time/output bounds and validated SSSS execution audit apply. Mutation errors preserve known commit/index state or report unknown commit state after interruption; effects already committed cannot be rolled back. Provider quotas, broader owner adapters and the complete API/launch journey remain separate acceptance work. Read the shipped `docs/reference/cli-reference.md` developer API contract before migration or execution.
|
|
20
|
+
|
|
15
21
|
## Uniform dependency updates
|
|
16
22
|
|
|
23
|
+
Project registration automatically creates and records its stable UUID through the existing identity owner. Malformed/non-object identities are preserved and fail explicitly; provisioning failure must not register an incomplete fallback. `project-id --all` is for legacy reconciliation, not a required step after ordinary registration.
|
|
24
|
+
|
|
25
|
+
Restricted memory also accepts `project:<uuid>` with the effective auth scope `brain:project-<uuid>` plus its read/write scope. Use existing brain registration/on/off, project-id and auth-key commands. Only registered, enabled, canonical identity-matched brains execute; discovery lists granted usable IDs, never paths. Running work pins and revalidates that binding; removal, disablement or identity/path changes stop continuation. Project-only keys have no implicit server access. Writes retain the closed descriptive fact schema and validated SSSS owner.
|
|
26
|
+
|
|
27
|
+
Full-mode `decision.run` and `decision.predict` execute the installed owner in bounded children, with auth-owner credential resolution inside the child. Timeout, output overflow, client disconnect and revoked authority terminate local continuation. Decision failure envelopes suppress child diagnostics; credential/provider failures are explicit. Cancellation cannot reverse accepted remote billing. Spending quotas and broader restricted adapters remain separate acceptance work.
|
|
28
|
+
|
|
17
29
|
Use `total-recall update --all-brains` to plan both SSSS and Total Recall updates across registered brains, installed plugin owners and nested consumers. Add `--apply` to pin the resolved published releases, refresh npm/pnpm locks and verify actual package resolution; `--json` returns per-consumer results and failures. Extra roots use repeatable `--repo` or `TR_SYNC_REPOS`. Every consumer owns a local installation: a shared node_modules link is detached without mutating its former target and restored on failure. Missing versions, unsupported managers, newer previews and verification mismatches fail explicitly. This updates local dependencies; it does not deploy services or merge brains.
|
package/src/cli/brain.mjs
CHANGED
|
@@ -108,7 +108,7 @@ async function handleEnsure(targetArgs, globalBrainDir) {
|
|
|
108
108
|
console.log(` Repo: ${result.repoRoot}`);
|
|
109
109
|
console.log(` Brain: ${result.brainDir}`);
|
|
110
110
|
console.log(` complete=${health.complete} full_brain=${health.full_brain}`);
|
|
111
|
-
console.log(`
|
|
111
|
+
console.log(` directories created +${result.dirs_created}`);
|
|
112
112
|
console.log('');
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -213,7 +213,7 @@ async function handleRegister(registryPath, targetArgs) {
|
|
|
213
213
|
process.exit(1);
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
// Full project brain for any user repo (vault,
|
|
216
|
+
// Full project brain for any user repo (vault, sessions, registry, …)
|
|
217
217
|
try {
|
|
218
218
|
const { ensureFullProjectBrain } = await import('../core/project-brain.mjs');
|
|
219
219
|
const globalBrainDir = path.join(getGlobalAgentDir(), 'skills', 'total-recall');
|
|
@@ -226,6 +226,8 @@ async function handleRegister(registryPath, targetArgs) {
|
|
|
226
226
|
console.log(` ✅ Full project brain ready at ${path.join(absoluteRoot, '.agent', 'skills', 'total-recall')}`);
|
|
227
227
|
} catch (err) {
|
|
228
228
|
console.error(` ⚠️ Could not fully provision brain layout: ${err.message}`);
|
|
229
|
+
process.exitCode = 1;
|
|
230
|
+
return;
|
|
229
231
|
}
|
|
230
232
|
|
|
231
233
|
const brainDir = path.join(absoluteRoot, '.agent', 'skills', 'total-recall');
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* total-recall context-stats — read the capsule measurement ledger.
|
|
3
|
+
*
|
|
4
|
+
* Answers the questions a context-policy decision actually needs:
|
|
5
|
+
* - Which actions overflow, and how often (a rate, not an anecdote)?
|
|
6
|
+
* - How close is the required set to the budget, per action?
|
|
7
|
+
* - Which rules are force-included on every call?
|
|
8
|
+
*
|
|
9
|
+
* Read-only. Measurement is recorded by `total-recall context`.
|
|
10
|
+
*/
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { getBothBrains, parseLayerFlag } from './agent-dir.mjs';
|
|
13
|
+
import { readLedger, summariseLedger, ledgerPath, telemetryEnabled } from '../core/context-telemetry.mjs';
|
|
14
|
+
import { readConfigValue } from './config.mjs';
|
|
15
|
+
|
|
16
|
+
const pct = (n) => `${Math.round(n * 100)}%`;
|
|
17
|
+
|
|
18
|
+
function renderSummary(summary, { budget, ledger }) {
|
|
19
|
+
const lines = [];
|
|
20
|
+
if (summary.samples === 0) {
|
|
21
|
+
lines.push('No capsule measurements recorded yet.');
|
|
22
|
+
lines.push('');
|
|
23
|
+
lines.push('Every `total-recall context` call records one line. Run a few, then re-check.');
|
|
24
|
+
return lines.join('\n');
|
|
25
|
+
}
|
|
26
|
+
lines.push(`Capsule measurements: ${summary.samples} sample(s)`);
|
|
27
|
+
lines.push(`Range: ${summary.first_at} → ${summary.last_at}`);
|
|
28
|
+
if (budget) lines.push(`Configured budget: ${budget}`);
|
|
29
|
+
lines.push('');
|
|
30
|
+
lines.push('By action:');
|
|
31
|
+
lines.push(' action samples overflow required(avg/max) excluded');
|
|
32
|
+
for (const a of summary.actions) {
|
|
33
|
+
lines.push(` ${String(a.action).padEnd(12)} ${String(a.samples).padStart(7)} ${pct(a.overflow_rate).padStart(8)} ${String(a.required_avg).padStart(8)}/${String(a.required_max).padEnd(8)} ${a.excluded_total}`);
|
|
34
|
+
}
|
|
35
|
+
if (budget) {
|
|
36
|
+
const worst = summary.actions[0];
|
|
37
|
+
if (worst) {
|
|
38
|
+
lines.push('');
|
|
39
|
+
const head = worst.required_max - budget;
|
|
40
|
+
lines.push(head > 0
|
|
41
|
+
? `Headroom: NEGATIVE on '${worst.action}' by ${head} tokens at its largest sample.`
|
|
42
|
+
: `Headroom: ${budget - worst.required_max} tokens at the largest required set ('${worst.action}').`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (summary.most_required.length) {
|
|
46
|
+
lines.push('');
|
|
47
|
+
lines.push('Rules included most often (candidates for action-scoping):');
|
|
48
|
+
for (const r of summary.most_required.slice(0, 15)) {
|
|
49
|
+
lines.push(` ${String(r.appearances).padStart(6)}x ${r.id}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
lines.push('');
|
|
53
|
+
lines.push(`Ledger: ${ledger}`);
|
|
54
|
+
lines.push('Identifiers and counts only; never rule text or capsule content.');
|
|
55
|
+
return lines.join('\n');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default async function contextStats(args = []) {
|
|
59
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
60
|
+
console.log('Usage: total-recall context-stats [--json] [--limit N] [--project|--global]\n\nRead-only summary of capsule measurements recorded by `total-recall context`.\nReports overflow rate per action, required-token headroom, and which rules are\nincluded most often (the input to action-scoping a rule).\n\nEnvironment: TR_CONTEXT_TELEMETRY=off stops recording (this command then reports\nno samples). TR_CONTEXT_LEDGER_MAX_BYTES caps the ledger (default 8 MiB).');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// parseLayerFlag consumes --global/--project and returns what is left, so the
|
|
64
|
+
// loop must read `remainingArgs`; reading `args` re-rejected the layer flag.
|
|
65
|
+
const { layer, remainingArgs } = parseLayerFlag(args);
|
|
66
|
+
let isJson = false, limit = 0;
|
|
67
|
+
for (let i = 0; i < remainingArgs.length; i++) {
|
|
68
|
+
if (remainingArgs[i] === '--json') { isJson = true; continue; }
|
|
69
|
+
if (remainingArgs[i] === '--limit') { limit = Number(remainingArgs[++i]) || 0; continue; }
|
|
70
|
+
// Reject an unknown flag rather than ignoring it: a silently dropped
|
|
71
|
+
// --globel would report project scope while the operator believed
|
|
72
|
+
// otherwise, and this command exists to be trusted about scope.
|
|
73
|
+
throw new Error(`Unknown context-stats option: ${remainingArgs[i]}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const brains = getBothBrains();
|
|
77
|
+
const own = layer !== 'global' && brains.project ? brains.project.brainDir : null;
|
|
78
|
+
const global = layer !== 'project' && brains.global ? brains.global.brainDir : null;
|
|
79
|
+
const brainDir = own || global;
|
|
80
|
+
if (!brainDir) throw new Error('No enabled brain in selected scope');
|
|
81
|
+
const derivedDir = path.join(brainDir, 'memory-derived');
|
|
82
|
+
|
|
83
|
+
const records = readLedger(derivedDir, { limit });
|
|
84
|
+
const summary = summariseLedger(records);
|
|
85
|
+
const budget = (() => {
|
|
86
|
+
for (const candidate of [layer === 'global' ? 'global' : 'project', 'global']) {
|
|
87
|
+
try { const v = readConfigValue('context_budget', candidate); if (Number.isFinite(v) && v > 0) return v; } catch { /* next layer */ }
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
})();
|
|
91
|
+
|
|
92
|
+
if (isJson) {
|
|
93
|
+
console.log(JSON.stringify({
|
|
94
|
+
enabled: telemetryEnabled(), budget, ledger: ledgerPath(derivedDir),
|
|
95
|
+
...summary,
|
|
96
|
+
}, null, 2));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (!telemetryEnabled()) {
|
|
100
|
+
console.log('Capsule telemetry is off (TR_CONTEXT_TELEMETRY=off). No measurements are recorded.');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.log(renderSummary(summary, { budget, ledger: ledgerPath(derivedDir) }));
|
|
104
|
+
}
|
package/src/cli/context.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { compileContext, capsuleResponse, renderCapsule } from '../core/context-
|
|
|
6
6
|
import { isBrainEnabled } from '../core/brain-registry.mjs';
|
|
7
7
|
import { surfaceInputsHash } from '../core/command-surface.mjs';
|
|
8
8
|
import { readConfigValue } from './config.mjs';
|
|
9
|
+
import { recordCapsule } from '../core/context-telemetry.mjs';
|
|
9
10
|
|
|
10
11
|
export default async function context(args = []) {
|
|
11
12
|
if (!args.length || args.includes('--help')) {
|
|
@@ -46,6 +47,13 @@ export default async function context(args = []) {
|
|
|
46
47
|
derivedDir, contributions: legacyRuleContributions(skillsDir), versionInputs: surfaceInputsHash({ skillsDir }) });
|
|
47
48
|
if (debug && format === 'text') throw new Error('--debug requires --format json');
|
|
48
49
|
const response = capsuleResponse(result, { total: budget, debug, format });
|
|
50
|
+
// Measured before the admission branch, so a capsule that failed to fit is
|
|
51
|
+
// recorded too. Those refusals are the samples the budget decision needs, and
|
|
52
|
+
// a measurement that only counts successes would hide the exact case it
|
|
53
|
+
// exists to explain.
|
|
54
|
+
recordCapsule({ ...result.stats, total_tokens: result.stats.total_tokens }, {
|
|
55
|
+
derivedDir, action: actions, query, consumer: 'cli',
|
|
56
|
+
});
|
|
49
57
|
if (!response.ready && !debug) {
|
|
50
58
|
// Admission failed: emitting bodies here makes each budget retry load the
|
|
51
59
|
// same rules again. Keep the full set in the compiler/API, and admit it only
|
package/src/cli/daemon.mjs
CHANGED
|
@@ -18,7 +18,7 @@ import os from 'node:os';
|
|
|
18
18
|
import path from 'node:path';
|
|
19
19
|
import { fileURLToPath } from 'node:url';
|
|
20
20
|
import { resolveBrainDir } from './agent-dir.mjs';
|
|
21
|
-
import { startDaemon, stopDaemon, readPid } from '../core/daemon-control.mjs';
|
|
21
|
+
import { startDaemon, stopDaemon, readPid, getDaemonObservation } from '../core/daemon-control.mjs';
|
|
22
22
|
|
|
23
23
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
24
24
|
const ROOT = path.join(__dirname, '..', '..');
|
|
@@ -208,6 +208,14 @@ export default async function daemon(args) {
|
|
|
208
208
|
const useSystemd = hasSystemd();
|
|
209
209
|
const useLaunchd = !useSystemd && hasLaunchd();
|
|
210
210
|
|
|
211
|
+
// Managers must honor the same brain lock as direct lifecycle operations.
|
|
212
|
+
if (['start', 'ensure', 'stop'].includes(subcommand)) {
|
|
213
|
+
const observation = getDaemonObservation();
|
|
214
|
+
if (['conflict', 'unknown'].includes(observation.status)) {
|
|
215
|
+
throw new Error(`Daemon ${subcommand} refused: ${observation.reason || observation.status}; expected ${observation.expected_entry}${observation.entry ? `, observed ${observation.entry}` : ''}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
211
219
|
switch (subcommand) {
|
|
212
220
|
case 'ensure': {
|
|
213
221
|
if(!useSystemd)throw new Error('Managed daemon ensure currently requires systemd on the daemon host');
|
|
@@ -253,6 +261,7 @@ export default async function daemon(args) {
|
|
|
253
261
|
else await directStop();
|
|
254
262
|
break;
|
|
255
263
|
case 'status':
|
|
264
|
+
console.log(JSON.stringify({ daemon: getDaemonObservation() }));
|
|
256
265
|
if (useSystemd) systemdStatus();
|
|
257
266
|
else if (useLaunchd) launchctlStatus();
|
|
258
267
|
else directStatus();
|
package/src/cli/export.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { parseLayerFlag, resolveBrainDir } from './agent-dir.mjs';
|
|
4
|
-
import {
|
|
4
|
+
import { loadPluginModule } from '../core/plugin-runtime.mjs';
|
|
5
5
|
|
|
6
6
|
export default async function exportCommand(args) {
|
|
7
7
|
const { layer, remainingArgs } = parseLayerFlag(args);
|
|
@@ -51,6 +51,7 @@ export default async function exportCommand(args) {
|
|
|
51
51
|
console.log(` 📂 Destination: ${opts.outputPath} (Format: ${opts.format})`);
|
|
52
52
|
|
|
53
53
|
try {
|
|
54
|
+
const { exportBundle } = await loadPluginModule('okf', 'adapter', { activeRequired: true });
|
|
54
55
|
const report = await exportBundle(vaultDir, opts.outputPath, {
|
|
55
56
|
format: opts.format,
|
|
56
57
|
stripSsss: opts.stripSsss
|
|
@@ -63,7 +64,7 @@ export default async function exportCommand(args) {
|
|
|
63
64
|
console.log(` ✅ Export completed successfully.\n`);
|
|
64
65
|
} catch (err) {
|
|
65
66
|
console.error(`\n ❌ Export failed: ${err.message}\n`);
|
|
66
|
-
process.
|
|
67
|
+
process.exitCode = 1;
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
package/src/cli/ingest-okf.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { parseLayerFlag, resolveBrainDir } from './agent-dir.mjs';
|
|
4
|
-
import {
|
|
4
|
+
import { loadPluginModule } from '../core/plugin-runtime.mjs';
|
|
5
5
|
|
|
6
6
|
export async function runOkfIngest(args) {
|
|
7
7
|
const { layer, remainingArgs } = parseLayerFlag(args);
|
|
@@ -69,6 +69,7 @@ export async function runOkfIngest(args) {
|
|
|
69
69
|
console.log(` 🧠 Target Brain: ${layer} (${vaultDir})`);
|
|
70
70
|
if (opts.dryRun) console.log(' ⚠️ DRY RUN: No actual writes will be committed.');
|
|
71
71
|
|
|
72
|
+
const { importBundle } = await loadPluginModule('okf', 'adapter', { activeRequired: true });
|
|
72
73
|
const report = await importBundle(opts.bundlePath, vaultDir, {
|
|
73
74
|
dryRun: opts.dryRun,
|
|
74
75
|
category: opts.category,
|
|
@@ -94,23 +95,19 @@ export async function runOkfIngest(args) {
|
|
|
94
95
|
for (const item of report.errors) {
|
|
95
96
|
console.log(` • ${item.file}: ${item.error}`);
|
|
96
97
|
}
|
|
97
|
-
process.
|
|
98
|
+
process.exitCode = 1;
|
|
99
|
+
return;
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
if (report.imported.length > 0 && !opts.dryRun) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
child.unref();
|
|
110
|
-
console.log(' ✅ Background compilation started.');
|
|
111
|
-
} catch (err) {
|
|
112
|
-
console.warn(` ⚠️ Background recompilation spawn failed: ${err.message}`);
|
|
113
|
-
}
|
|
103
|
+
console.log('\n ⏳ Recompiling memory surfaces and indexes...');
|
|
104
|
+
const { spawn } = await import('node:child_process');
|
|
105
|
+
await new Promise((resolve, reject) => {
|
|
106
|
+
const child = spawn(process.argv[0], [process.argv[1], 'compile', ...(layer === 'project' ? ['--project'] : layer === 'global' ? ['--global'] : [])], { stdio: 'inherit' });
|
|
107
|
+
child.once('error', reject);
|
|
108
|
+
child.once('exit', (code, signal) => code === 0 ? resolve() : reject(new Error(`Compilation failed (${signal || code})`)));
|
|
109
|
+
});
|
|
110
|
+
console.log(' ✅ Compilation completed.');
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
|
package/src/cli/init.mjs
CHANGED
|
@@ -77,63 +77,6 @@ function copyDirMerge(src, dest, dryRun) {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
/**
|
|
81
|
-
* Ship openwiki with the brain (global or project). Prefer packaged templates;
|
|
82
|
-
* fall back to a minimal set of pages so every brain has docs.
|
|
83
|
-
*/
|
|
84
|
-
async function ensureOpenWiki(brainDir, isProject, dryRun) {
|
|
85
|
-
const wikiDirs = [path.join(brainDir, 'openwiki')];
|
|
86
|
-
if (isProject) {
|
|
87
|
-
wikiDirs.push(path.join(process.cwd(), 'openwiki'));
|
|
88
|
-
}
|
|
89
|
-
const templateRoot = fs.existsSync(path.join(ROOT, 'scaffold', 'openwiki'))
|
|
90
|
-
? path.join(ROOT, 'scaffold', 'openwiki')
|
|
91
|
-
: path.join(ROOT, 'templates', 'openwiki');
|
|
92
|
-
|
|
93
|
-
for (const wikiDir of wikiDirs) {
|
|
94
|
-
if (ensureDir(wikiDir, dryRun)) {
|
|
95
|
-
logOk(`Created openwiki at ${path.relative(process.cwd(), wikiDir) || wikiDir}`);
|
|
96
|
-
}
|
|
97
|
-
if (fs.existsSync(templateRoot)) {
|
|
98
|
-
copyDirMerge(templateRoot, wikiDir, dryRun);
|
|
99
|
-
} else {
|
|
100
|
-
// Minimal fallback pages when templates/ not packaged yet
|
|
101
|
-
const pages = {
|
|
102
|
-
'README.md': `# OpenWiki\n\nPortable knowledge docs for this Total Recall brain (${isProject ? 'project' : 'global'}).\n\n- Not the SSSS memory vault — use vault nodes for rules/facts.\n- Use these pages for architecture, stack, and how-to knowledge.\n`,
|
|
103
|
-
'architecture.md': `# Architecture\n\nComponent overview, domain boundaries, and runtime execution flow.\n`,
|
|
104
|
-
'stack.md': `# Stack\n\nRuntime dependencies, frameworks, and system tools.\n`,
|
|
105
|
-
'memory.md': `# Memory\n\nHow this brain stores invariants, preferences, and facts.\n\nUse \`npx total-recall remember\` / \`recall\` / \`compile\`.\n`,
|
|
106
|
-
'ide.md': `# IDE personalization\n\nConnect surfaces with \`npx total-recall connect <ide>\`.\nInjected blocks live inside BEGIN/END INJECTED MEMORY markers only.\n`,
|
|
107
|
-
'skills.md': `# Skills\n\nUser skills live in \`.agent/skills/<name>/\` (siblings of total-recall).\nTotal Recall tracks and deploys skills; it does not nest product skills inside itself.\n`,
|
|
108
|
-
'secrets.md': `# Secrets\n\nAPI keys and credentials belong in the encrypted secrets store — never in openwiki or instruction shims.\n`,
|
|
109
|
-
};
|
|
110
|
-
for (const [name, body] of Object.entries(pages)) {
|
|
111
|
-
const dest = path.join(wikiDir, name);
|
|
112
|
-
if (fs.existsSync(dest)) continue;
|
|
113
|
-
if (!dryRun) fs.writeFileSync(dest, body);
|
|
114
|
-
logOk(`Seeded openwiki/${name}`);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Auto-ingest into memory graph when project is initialized
|
|
120
|
-
if (isProject && !dryRun) {
|
|
121
|
-
try {
|
|
122
|
-
const { discoverPlugins } = await import('../core/plugin-loader.mjs');
|
|
123
|
-
const { runPluginCommand } = await import('../core/plugin-runner.mjs');
|
|
124
|
-
const plugins = discoverPlugins(process.cwd());
|
|
125
|
-
const openwikiPlugin = plugins.find((p) => p.id === 'openwiki');
|
|
126
|
-
const targetWiki = path.join(process.cwd(), 'openwiki');
|
|
127
|
-
if (openwikiPlugin && fs.existsSync(targetWiki)) {
|
|
128
|
-
await runPluginCommand(openwikiPlugin, { subcommand: 'ingest', args: [targetWiki] });
|
|
129
|
-
logOk('Ingested openwiki into semantic knowledge graph');
|
|
130
|
-
}
|
|
131
|
-
} catch {
|
|
132
|
-
// Best-effort ingestion
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
80
|
function parseArgs(args) {
|
|
138
81
|
const opts = {
|
|
139
82
|
dryRun: false,
|
|
@@ -565,33 +508,11 @@ export default async function init(args) {
|
|
|
565
508
|
}
|
|
566
509
|
}
|
|
567
510
|
|
|
568
|
-
// Optional LLM OpenWiki agent (interactive only). openwiki CLI has no --yes flag.
|
|
569
|
-
// Non-interactive init always uses TR template openwiki via ensureOpenWiki() below.
|
|
570
|
-
const runOpenwiki = (await ask('\n [3.8] Run OpenWiki agent to auto-document this codebase? (y/N): ')).trim().toLowerCase();
|
|
571
|
-
if (runOpenwiki === 'y' || runOpenwiki === 'yes') {
|
|
572
|
-
console.error('\n Starting OpenWiki agent (--init). This is interactive / network-using.');
|
|
573
|
-
console.error(' Tip: skip this and use TR template openwiki (step 3.6) for offline setup.');
|
|
574
|
-
spawnSync('npx', ['-y', 'openwiki', '--init'], { stdio: 'inherit', cwd: process.cwd() });
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
const runOkf = (await ask('\n [3.9] Would you like to import an existing OKF knowledge bundle? (y/N): ')).trim().toLowerCase();
|
|
578
|
-
if (runOkf === 'y' || runOkf === 'yes') {
|
|
579
|
-
const bundlePath = (await ask(' Enter path to OKF bundle: ')).trim();
|
|
580
|
-
if (bundlePath) {
|
|
581
|
-
spawnSync('npx', ['-y', 'total-recall', 'ingest', 'okf', bundlePath], { stdio: 'inherit', cwd: process.cwd() });
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
|
|
585
511
|
rl.close();
|
|
586
512
|
} else {
|
|
587
|
-
// Non-interactive (--yes / non-TTY): never call openwiki CLI (no --yes support; can hang).
|
|
588
|
-
// Step 3.6 ensureOpenWiki() ships portable template pages offline.
|
|
589
513
|
if (!deployMode) {
|
|
590
514
|
deployMode = 'local';
|
|
591
515
|
}
|
|
592
|
-
if (!opts.dryRun) {
|
|
593
|
-
log('Skipping external openwiki agent in non-interactive mode (templates via ensureOpenWiki).');
|
|
594
|
-
}
|
|
595
516
|
}
|
|
596
517
|
|
|
597
518
|
// Verify cloudflared binary dependency if a tunnel mode is selected
|
|
@@ -683,12 +604,6 @@ export default async function init(args) {
|
|
|
683
604
|
// (TR_CORE_FOCUS). Implementation lives in total-recall/modules/. User skills are
|
|
684
605
|
// only those with SKILL.md directly under .agent/skills/<name>/.
|
|
685
606
|
|
|
686
|
-
// ── Step 3.6: Ensure openwiki ships with the brain (offline templates; always) ──
|
|
687
|
-
// This is the non-interactive openwiki path. External `openwiki --init` is optional
|
|
688
|
-
// and only offered interactively (that CLI has no --yes flag).
|
|
689
|
-
logStep('3.6/4', 'Ensuring openwiki is present');
|
|
690
|
-
await ensureOpenWiki(brainDir, isProject, opts.dryRun);
|
|
691
|
-
|
|
692
607
|
if (isProject) {
|
|
693
608
|
logStep('3.6/4', 'Ensuring repository-specific expert');
|
|
694
609
|
try {
|
package/src/cli/lint.mjs
CHANGED
|
@@ -51,7 +51,7 @@ function printHelp() {
|
|
|
51
51
|
--global Lint the global vault (default)
|
|
52
52
|
--project Lint the project vault for the current repo
|
|
53
53
|
--strict Treat warnings as errors (exit 1 on any issue)
|
|
54
|
-
--okf
|
|
54
|
+
--okf Inspect metadata through the installed OKF plugin
|
|
55
55
|
--plugins Validate all installed plugin manifests (plugin.json)
|
|
56
56
|
--json Output results as JSONL
|
|
57
57
|
--help, -h Show this help
|
|
@@ -72,7 +72,8 @@ export default async function lint(args) {
|
|
|
72
72
|
const vaultDir = opts.vault || path.join(resolveBrainDir(effectiveLayer), 'memory-vault');
|
|
73
73
|
|
|
74
74
|
if (opts.okf) {
|
|
75
|
-
const {
|
|
75
|
+
const { loadPluginModule } = await import('../core/plugin-runtime.mjs');
|
|
76
|
+
const { lintOkfCompliance } = await loadPluginModule('okf', 'adapter', { activeRequired: true });
|
|
76
77
|
const report = lintOkfCompliance(vaultDir, { strict: opts.strict });
|
|
77
78
|
|
|
78
79
|
if (opts.json) {
|