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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tr-plugin-auth",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "White-label Total Recall auth plugin: Passkey biometric FIDO2 and Google OAuth2 authentication.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "cli.mjs",
|
|
@@ -16,18 +16,20 @@
|
|
|
16
16
|
],
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"
|
|
19
|
+
"@simplewebauthn/server": "^13.3.2",
|
|
20
20
|
"bcrypt": "^6.0.0",
|
|
21
|
-
"
|
|
21
|
+
"express": "^5.2.1",
|
|
22
22
|
"express-rate-limit": "^8.5.1",
|
|
23
|
-
"
|
|
24
|
-
"
|
|
23
|
+
"jsonwebtoken": "^9.0.3",
|
|
24
|
+
"yaml": "^2.9.0"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"cli.mjs",
|
|
28
28
|
"plugin.json",
|
|
29
29
|
"README.md",
|
|
30
30
|
"src/",
|
|
31
|
+
"test/",
|
|
32
|
+
"scripts/",
|
|
31
33
|
"!src/**/*.spec.mjs",
|
|
32
34
|
"ui/"
|
|
33
35
|
],
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
3
|
"id": "auth",
|
|
4
4
|
"name": "Auth & Secrets",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.2.1",
|
|
6
6
|
"description": "Hardware WebAuthn biometric FIDO2 passkeys, OAuth session security, and access control.",
|
|
7
7
|
"author": "Total Recall contributors",
|
|
8
8
|
"license": "MIT",
|
|
@@ -146,6 +146,7 @@
|
|
|
146
146
|
]
|
|
147
147
|
},
|
|
148
148
|
"ui": {
|
|
149
|
+
"design_tokens": "ui/DESIGN.md",
|
|
149
150
|
"elements": [
|
|
150
151
|
{
|
|
151
152
|
"id": "card",
|
|
@@ -153,13 +154,6 @@
|
|
|
153
154
|
"tag": "tr-auth-card",
|
|
154
155
|
"module": "ui/card.js",
|
|
155
156
|
"description": "Gatepass Card Face"
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
"id": "panel",
|
|
159
|
-
"kind": "panel",
|
|
160
|
-
"tag": "tr-auth-panel",
|
|
161
|
-
"module": "ui/panel.js",
|
|
162
|
-
"description": "Auth Management Panel"
|
|
163
157
|
}
|
|
164
158
|
]
|
|
165
159
|
},
|
|
@@ -225,6 +219,7 @@
|
|
|
225
219
|
"runtime": {
|
|
226
220
|
"modules": {
|
|
227
221
|
"secrets-store": "src/secrets-store.mjs",
|
|
222
|
+
"host-secrets-store": "src/host-secrets-store.mjs",
|
|
228
223
|
"secrets-gateway": "src/secrets-gateway.mjs",
|
|
229
224
|
"secrets-keychain": "src/secrets-keychain.mjs",
|
|
230
225
|
"secrets-env-diff": "src/secrets-env-diff.mjs",
|
|
@@ -266,41 +261,5 @@
|
|
|
266
261
|
"distribution": {
|
|
267
262
|
"tier": "official",
|
|
268
263
|
"license": "open"
|
|
269
|
-
},
|
|
270
|
-
"card_layout": {
|
|
271
|
-
"template": "vault",
|
|
272
|
-
"regions": [
|
|
273
|
-
{
|
|
274
|
-
"widget": "status",
|
|
275
|
-
"title": "Status"
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
"widget": "live",
|
|
279
|
-
"title": "Live view"
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
"widget": "list",
|
|
283
|
-
"title": "Details",
|
|
284
|
-
"source": {
|
|
285
|
-
"command": "audit"
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
"widget": "actions",
|
|
290
|
-
"title": "Commands"
|
|
291
|
-
},
|
|
292
|
-
{
|
|
293
|
-
"widget": "settings",
|
|
294
|
-
"title": "Settings"
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
"widget": "credentials",
|
|
298
|
-
"title": "Credentials"
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
"widget": "activity",
|
|
302
|
-
"title": "Recent activity"
|
|
303
|
-
}
|
|
304
|
-
]
|
|
305
264
|
}
|
|
306
265
|
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Sign in an agent CLI that authenticates on its own terminal.
|
|
3
|
+
|
|
4
|
+
Some agent CLIs (Antigravity / `agy`) print an OAuth consent URL, then block reading the
|
|
5
|
+
authorization code from their terminal. Driving that needs a pty, and Node has none built in and no
|
|
6
|
+
pty library in this plugin, so the pty lives here — as part of the plugin, not as a script beside it.
|
|
7
|
+
|
|
8
|
+
The code arrives through a file this process watches. That is a constraint, not a preference:
|
|
9
|
+
`legacy_tiocsti` is 0 on current kernels, so no outside process can type into another process's pty,
|
|
10
|
+
and a backgrounded command has no attachable stdin. `--code` and `--code-file` both funnel into the
|
|
11
|
+
same pty write.
|
|
12
|
+
|
|
13
|
+
Prints newline-delimited JSON events on stdout so the caller can relay progress, and exits 0 only
|
|
14
|
+
when the CLI's own login probe says the session exists.
|
|
15
|
+
"""
|
|
16
|
+
import argparse
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
19
|
+
import pty
|
|
20
|
+
import re
|
|
21
|
+
import select
|
|
22
|
+
import subprocess
|
|
23
|
+
import sys
|
|
24
|
+
import time
|
|
25
|
+
|
|
26
|
+
ANSI = re.compile(r'\x1b\[[0-9;]*[a-zA-Z]')
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def emit(event, **fields):
|
|
30
|
+
payload = {'event': event}
|
|
31
|
+
payload.update(fields)
|
|
32
|
+
sys.stdout.write(json.dumps(payload) + '\n')
|
|
33
|
+
sys.stdout.flush()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def resolve_binary(name):
|
|
37
|
+
for candidate in (
|
|
38
|
+
os.path.join(os.path.expanduser('~'), '.local', 'bin', name),
|
|
39
|
+
os.path.join('/usr/local/bin', name),
|
|
40
|
+
os.path.join('/usr/bin', name),
|
|
41
|
+
):
|
|
42
|
+
if os.path.exists(candidate):
|
|
43
|
+
return candidate
|
|
44
|
+
return name
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def probe(binary, args, signed_out_pattern):
|
|
48
|
+
"""Ask the CLI itself whether a session exists. The transcript is not evidence."""
|
|
49
|
+
try:
|
|
50
|
+
result = subprocess.run([binary] + args, capture_output=True, text=True, timeout=60)
|
|
51
|
+
output = (result.stdout or '') + (result.stderr or '')
|
|
52
|
+
signed_out = bool(re.search(signed_out_pattern, output, re.I))
|
|
53
|
+
return {
|
|
54
|
+
'signed_in': (not signed_out) and result.returncode == 0,
|
|
55
|
+
'status': result.returncode,
|
|
56
|
+
'output': output.strip()[:400],
|
|
57
|
+
}
|
|
58
|
+
except Exception as error: # noqa: BLE001 - report, never raise
|
|
59
|
+
return {'signed_in': False, 'status': None, 'output': str(error)[:400]}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def main():
|
|
63
|
+
parser = argparse.ArgumentParser()
|
|
64
|
+
parser.add_argument('--agent', required=True)
|
|
65
|
+
parser.add_argument('--binary', required=True)
|
|
66
|
+
parser.add_argument('--code', default='')
|
|
67
|
+
parser.add_argument('--code-file', default='')
|
|
68
|
+
parser.add_argument('--url-file', default='')
|
|
69
|
+
parser.add_argument('--timeout', type=int, default=900)
|
|
70
|
+
parser.add_argument('--probe-args', default='models')
|
|
71
|
+
parser.add_argument('--signed-out-pattern', default=r'please sign in')
|
|
72
|
+
parser.add_argument('--consent-host', default='accounts.google.com')
|
|
73
|
+
args = parser.parse_args()
|
|
74
|
+
|
|
75
|
+
binary = resolve_binary(args.binary)
|
|
76
|
+
|
|
77
|
+
before = probe(binary, args.probe_args.split(), args.signed_out_pattern)
|
|
78
|
+
if before['signed_in']:
|
|
79
|
+
emit('already_signed_in', probe=before)
|
|
80
|
+
emit('done', ok=True)
|
|
81
|
+
return 0
|
|
82
|
+
|
|
83
|
+
pid, fd = pty.fork()
|
|
84
|
+
if pid == 0:
|
|
85
|
+
os.environ['PATH'] = os.path.dirname(binary) + os.pathsep + os.environ.get('PATH', '')
|
|
86
|
+
os.execv(binary, [args.binary])
|
|
87
|
+
|
|
88
|
+
time.sleep(2)
|
|
89
|
+
os.write(fd, b'\r')
|
|
90
|
+
|
|
91
|
+
published_url = ''
|
|
92
|
+
delivered_code = args.code.strip()
|
|
93
|
+
buffer = b''
|
|
94
|
+
deadline = time.time() + args.timeout
|
|
95
|
+
next_probe_at = time.time()
|
|
96
|
+
success = False
|
|
97
|
+
|
|
98
|
+
while time.time() < deadline:
|
|
99
|
+
try:
|
|
100
|
+
ready, _, _ = select.select([fd], [], [], 1.0)
|
|
101
|
+
if ready:
|
|
102
|
+
chunk = os.read(fd, 8192)
|
|
103
|
+
if not chunk:
|
|
104
|
+
break
|
|
105
|
+
buffer += chunk
|
|
106
|
+
text = ANSI.sub('', buffer.decode('utf-8', errors='ignore'))
|
|
107
|
+
|
|
108
|
+
if not published_url:
|
|
109
|
+
parts, collecting = [], False
|
|
110
|
+
for line in text.splitlines():
|
|
111
|
+
line = line.strip()
|
|
112
|
+
if args.consent_host in line:
|
|
113
|
+
collecting = True
|
|
114
|
+
if collecting:
|
|
115
|
+
parts.append(line)
|
|
116
|
+
if 'state=' in line:
|
|
117
|
+
break
|
|
118
|
+
candidate = ''.join(parts).replace(' ', '')
|
|
119
|
+
if candidate:
|
|
120
|
+
published_url = candidate
|
|
121
|
+
if args.url_file:
|
|
122
|
+
with open(args.url_file, 'w') as handle:
|
|
123
|
+
handle.write(candidate + '\n')
|
|
124
|
+
emit('url', url=candidate)
|
|
125
|
+
except Exception:
|
|
126
|
+
break
|
|
127
|
+
|
|
128
|
+
# Deliver the code once the URL is out, from the argument or from the watched file.
|
|
129
|
+
if published_url and not delivered_code:
|
|
130
|
+
if args.code_file and os.path.exists(args.code_file):
|
|
131
|
+
try:
|
|
132
|
+
candidate = open(args.code_file).read().strip()
|
|
133
|
+
except Exception:
|
|
134
|
+
candidate = ''
|
|
135
|
+
if candidate:
|
|
136
|
+
delivered_code = candidate
|
|
137
|
+
os.write(fd, candidate.encode() + b'\r')
|
|
138
|
+
emit('code_delivered', length=len(candidate))
|
|
139
|
+
elif args.code:
|
|
140
|
+
delivered_code = args.code.strip()
|
|
141
|
+
os.write(fd, delivered_code.encode() + b'\r')
|
|
142
|
+
emit('code_delivered', length=len(delivered_code))
|
|
143
|
+
|
|
144
|
+
# Two ways to know it is done. The CLI's success line is one, but not every CLI prints a
|
|
145
|
+
# string we can rely on — Antigravity completed the sign-in without ever emitting the
|
|
146
|
+
# literal line. The authoritative signal is the CLI's own probe, so poll it too; otherwise
|
|
147
|
+
# this waits out the full timeout on a sign-in that already succeeded.
|
|
148
|
+
if published_url:
|
|
149
|
+
if re.search(r'authentication successful', ANSI.sub('', buffer.decode('utf-8', errors='ignore')), re.I):
|
|
150
|
+
success = True
|
|
151
|
+
break
|
|
152
|
+
if delivered_code:
|
|
153
|
+
if time.time() >= next_probe_at:
|
|
154
|
+
if probe(binary, args.probe_args.split(), args.signed_out_pattern)['signed_in']:
|
|
155
|
+
success = True
|
|
156
|
+
break
|
|
157
|
+
next_probe_at = time.time() + 5
|
|
158
|
+
|
|
159
|
+
if success:
|
|
160
|
+
after = probe(binary, args.probe_args.split(), args.signed_out_pattern)
|
|
161
|
+
emit('probe', probe=after)
|
|
162
|
+
ok = bool(after['signed_in'])
|
|
163
|
+
emit('done', ok=ok)
|
|
164
|
+
try:
|
|
165
|
+
os.write(fd, b'\x03')
|
|
166
|
+
except Exception:
|
|
167
|
+
pass
|
|
168
|
+
return 0 if ok else 2
|
|
169
|
+
|
|
170
|
+
emit('done', ok=False, reason='timed out waiting for the sign-in to complete')
|
|
171
|
+
# Restore the tty before exiting. Leaving it to the runtime produced
|
|
172
|
+
# 'tcsetattr: Inappropriate ioctl for device' on the way out.
|
|
173
|
+
try:
|
|
174
|
+
os.write(fd, b'\x03')
|
|
175
|
+
except Exception:
|
|
176
|
+
pass
|
|
177
|
+
try:
|
|
178
|
+
os.close(fd)
|
|
179
|
+
except Exception:
|
|
180
|
+
pass
|
|
181
|
+
return 2
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
if __name__ == '__main__':
|
|
185
|
+
sys.exit(main())
|
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
} from './secrets-remote-deploy.mjs';
|
|
59
59
|
import { listProviders, getProvider } from './provider-catalog.mjs';
|
|
60
60
|
import { resolveBrainDir, parseLayerFlag, detectProjectBrain } from './agent-dir.mjs';
|
|
61
|
+
import { hostSecretsBrainDir } from './host-secrets-store.mjs';
|
|
61
62
|
import fs from 'node:fs';
|
|
62
63
|
import { ensureProjectId } from './project-id.mjs';
|
|
63
64
|
import path from 'node:path';
|
|
@@ -219,6 +220,8 @@ function printHelp() {
|
|
|
219
220
|
--no-example Skip .env.example
|
|
220
221
|
--no-global Only keys bound to this repo (skip unbound)
|
|
221
222
|
--replace-all Overwrite entire .env (default: merge TR block only)
|
|
223
|
+
--rename STORE=ENV Write a store key under the env name an app expects
|
|
224
|
+
(repeatable, comma separated)
|
|
222
225
|
--remote <name> Also push the SSOT projection to a configured remote
|
|
223
226
|
target over SSH (see 'auth secret remote') instead of
|
|
224
227
|
(or in addition to) a local file
|
|
@@ -344,6 +347,7 @@ function parseArgs(args) {
|
|
|
344
347
|
noExample: false,
|
|
345
348
|
noGlobal: false,
|
|
346
349
|
replaceAll: false,
|
|
350
|
+
rename: {},
|
|
347
351
|
exportEnv: false,
|
|
348
352
|
exportAll: false,
|
|
349
353
|
enqueue: false,
|
|
@@ -530,6 +534,18 @@ function parseArgs(args) {
|
|
|
530
534
|
case '--replace-all':
|
|
531
535
|
out.replaceAll = true;
|
|
532
536
|
break;
|
|
537
|
+
case '--rename': {
|
|
538
|
+
// Write a store key under the variable name an app expects. An app
|
|
539
|
+
// reads the provider's plain variable name, but each app must own a
|
|
540
|
+
// distinct credential in the store, so prefix the store key per app
|
|
541
|
+
// (for example APP_A_PROVIDER_KEY, APP_B_PROVIDER_KEY, ...).
|
|
542
|
+
const spec = String(args[++i] || '');
|
|
543
|
+
for (const pair of spec.split(',')) {
|
|
544
|
+
const [from, to] = pair.split('=').map((v) => (v || '').trim());
|
|
545
|
+
if (from && to) out.rename[from] = to;
|
|
546
|
+
}
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
533
549
|
case '--from-clipboard':
|
|
534
550
|
out.fromClipboard = true;
|
|
535
551
|
break;
|
|
@@ -641,7 +657,8 @@ export default async function secretCli(argv) {
|
|
|
641
657
|
|
|
642
658
|
let brainDir;
|
|
643
659
|
try {
|
|
644
|
-
|
|
660
|
+
if (layer === 'project') throw new Error('Secrets have one host store; --project does not apply.');
|
|
661
|
+
brainDir = hostSecretsBrainDir();
|
|
645
662
|
} catch (err) {
|
|
646
663
|
console.error(`❌ ${err.message}`);
|
|
647
664
|
process.exit(1);
|
|
@@ -1180,6 +1197,7 @@ export default async function secretCli(argv) {
|
|
|
1180
1197
|
const r = await deployEnvToRemote(brainDir, opts.key, {
|
|
1181
1198
|
dryRun: opts.dryRun,
|
|
1182
1199
|
keys: opts.keys.length ? opts.keys : undefined,
|
|
1200
|
+
rename: opts.rename,
|
|
1183
1201
|
});
|
|
1184
1202
|
if (r.dryRun) {
|
|
1185
1203
|
console.log(`\n 📤 dry-run remote deploy → ${r.target} (${r.host})`);
|
|
@@ -1442,6 +1460,7 @@ export default async function secretCli(argv) {
|
|
|
1442
1460
|
includeGlobal: !opts.noGlobal,
|
|
1443
1461
|
replaceAll: !!opts.replaceAll,
|
|
1444
1462
|
keys: opts.keys.length ? opts.keys : undefined,
|
|
1463
|
+
rename: opts.rename,
|
|
1445
1464
|
};
|
|
1446
1465
|
|
|
1447
1466
|
if (opts.remote) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The host credential authority is independent of a caller's project brain.
|
|
6
|
+
* TR_SECRETS_BRAIN is the explicit operational override. The _TR_TEST_* roots
|
|
7
|
+
* preserve disposable test isolation without making AGENT_DIR/TR_BRAIN stores.
|
|
8
|
+
* This selector only resolves a path; it never opens or initializes a store.
|
|
9
|
+
*/
|
|
10
|
+
export function hostSecretsBrainDir() {
|
|
11
|
+
if (process.env.TR_SECRETS_BRAIN) return process.env.TR_SECRETS_BRAIN;
|
|
12
|
+
if (process.env._TR_TEST_BRAIN_DIR) return process.env._TR_TEST_BRAIN_DIR;
|
|
13
|
+
const agentRoot = process.env._TR_TEST_AGENT_DIR || path.join(os.homedir(), '.agent');
|
|
14
|
+
return path.join(agentRoot, 'skills', 'total-recall');
|
|
15
|
+
}
|
|
@@ -146,19 +146,20 @@ export async function buildEnvProjection(brainDir, target = {}) {
|
|
|
146
146
|
if (value == null || value === '') continue;
|
|
147
147
|
const meta = byKey.get(key) || { key, repos: [], scope: 'global' };
|
|
148
148
|
if (!secretMatchesTarget(meta, target)) continue;
|
|
149
|
-
|
|
149
|
+
const outKey = (target.rename && target.rename[key]) || key;
|
|
150
|
+
selected.push({ key, outKey, value: String(value), meta });
|
|
150
151
|
}
|
|
151
152
|
|
|
152
153
|
selected.sort((a, b) => a.key.localeCompare(b.key));
|
|
153
154
|
|
|
154
|
-
const lines = selected.map(({
|
|
155
|
+
const lines = selected.map(({ outKey, value }) => {
|
|
155
156
|
// Quote if needed
|
|
156
157
|
const needsQuote = /[\s#"'$\\]/.test(value);
|
|
157
158
|
const v = needsQuote ? JSON.stringify(value) : value;
|
|
158
|
-
return `${
|
|
159
|
+
return `${outKey}=${v}`;
|
|
159
160
|
});
|
|
160
161
|
|
|
161
|
-
const exampleLines = selected.map(({
|
|
162
|
+
const exampleLines = selected.map(({ outKey }) => `${outKey}=`);
|
|
162
163
|
|
|
163
164
|
const body = `${envHeader()}${lines.join('\n')}${lines.length ? '\n' : ''}${END_MARK}\n`;
|
|
164
165
|
const exampleBody = `# Example env — names only. Values live in Total Recall secrets store.
|
|
@@ -200,6 +201,7 @@ export async function exportEnvToProject(brainDir, projectPath, opts = {}) {
|
|
|
200
201
|
projectSlug: projectSlugFromPath(abs),
|
|
201
202
|
includeGlobal: opts.includeGlobal !== false,
|
|
202
203
|
keys: opts.keys,
|
|
204
|
+
rename: opts.rename,
|
|
203
205
|
};
|
|
204
206
|
|
|
205
207
|
const projection = await buildEnvProjection(brainDir, target);
|
|
@@ -180,6 +180,7 @@ export async function deployEnvToRemote(brainDir, targetName, opts = {}) {
|
|
|
180
180
|
keys: opts.keys?.length ? opts.keys : target.keys,
|
|
181
181
|
projectPath,
|
|
182
182
|
projectSlug: opts.projectSlug || projectSlugFromPath(projectPath),
|
|
183
|
+
rename: opts.rename,
|
|
183
184
|
});
|
|
184
185
|
|
|
185
186
|
const remoteFile = path.posix.join(target.remotePath, target.filename || '.env');
|
|
@@ -254,30 +254,6 @@
|
|
|
254
254
|
"tier": "official",
|
|
255
255
|
"license": "open"
|
|
256
256
|
},
|
|
257
|
-
"card_layout": {
|
|
258
|
-
"template": "workbench",
|
|
259
|
-
"regions": [
|
|
260
|
-
{
|
|
261
|
-
"widget": "live",
|
|
262
|
-
"title": "Live view"
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
"widget": "list",
|
|
266
|
-
"title": "Details",
|
|
267
|
-
"source": {
|
|
268
|
-
"command": "status"
|
|
269
|
-
}
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
"widget": "actions",
|
|
273
|
-
"title": "Commands"
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
"widget": "activity",
|
|
277
|
-
"title": "Recent activity"
|
|
278
|
-
}
|
|
279
|
-
]
|
|
280
|
-
},
|
|
281
257
|
"tasks": [
|
|
282
258
|
{
|
|
283
259
|
"intent": "Keep official agent documentation and Total Recall integrations current",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@gregiteen/ssss-cli": "0.11.2"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"total-recall-brain": "3.40.
|
|
15
|
+
"total-recall-brain": "^3.40.7"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"node_modules/@gregiteen/ssss-cli": {
|
|
@@ -2595,9 +2595,9 @@
|
|
|
2595
2595
|
}
|
|
2596
2596
|
},
|
|
2597
2597
|
"node_modules/total-recall-brain": {
|
|
2598
|
-
"version": "3.40.
|
|
2599
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.
|
|
2600
|
-
"integrity": "sha512
|
|
2598
|
+
"version": "3.40.7",
|
|
2599
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.7.tgz",
|
|
2600
|
+
"integrity": "sha512-G+sEWXVucI5Zs8uV1ie8P+mV/6cncWX76ES72T5dnPB3sFAwlcG9ous2SYTUaYUOETGB2vHTSo3cV4XWkHQ0Ww==",
|
|
2601
2601
|
"dev": true,
|
|
2602
2602
|
"license": "MIT",
|
|
2603
2603
|
"workspaces": [
|
|
@@ -161,26 +161,5 @@
|
|
|
161
161
|
"distribution": {
|
|
162
162
|
"tier": "official",
|
|
163
163
|
"license": "open"
|
|
164
|
-
},
|
|
165
|
-
"card_layout": {
|
|
166
|
-
"template": "workbench",
|
|
167
|
-
"regions": [
|
|
168
|
-
{
|
|
169
|
-
"widget": "status",
|
|
170
|
-
"title": "Status"
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
"widget": "live",
|
|
174
|
-
"title": "Live view"
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
"widget": "actions",
|
|
178
|
-
"title": "Commands"
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
"widget": "activity",
|
|
182
|
-
"title": "Recent activity"
|
|
183
|
-
}
|
|
184
|
-
]
|
|
185
164
|
}
|
|
186
165
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@gregiteen/ssss-cli": "0.11.2"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"total-recall-brain": "3.40.
|
|
15
|
+
"total-recall-brain": "^3.40.7"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"node_modules/@gregiteen/ssss-cli": {
|
|
@@ -2595,9 +2595,9 @@
|
|
|
2595
2595
|
}
|
|
2596
2596
|
},
|
|
2597
2597
|
"node_modules/total-recall-brain": {
|
|
2598
|
-
"version": "3.40.
|
|
2599
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.
|
|
2600
|
-
"integrity": "sha512
|
|
2598
|
+
"version": "3.40.7",
|
|
2599
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.7.tgz",
|
|
2600
|
+
"integrity": "sha512-G+sEWXVucI5Zs8uV1ie8P+mV/6cncWX76ES72T5dnPB3sFAwlcG9ous2SYTUaYUOETGB2vHTSo3cV4XWkHQ0Ww==",
|
|
2601
2601
|
"dev": true,
|
|
2602
2602
|
"license": "MIT",
|
|
2603
2603
|
"workspaces": [
|
|
@@ -185,37 +185,5 @@
|
|
|
185
185
|
"distribution": {
|
|
186
186
|
"tier": "official",
|
|
187
187
|
"license": "open"
|
|
188
|
-
},
|
|
189
|
-
"card_layout": {
|
|
190
|
-
"template": "workbench",
|
|
191
|
-
"regions": [
|
|
192
|
-
{
|
|
193
|
-
"widget": "status",
|
|
194
|
-
"title": "Status"
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
"widget": "live",
|
|
198
|
-
"title": "Live view"
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
"widget": "list",
|
|
202
|
-
"title": "Details",
|
|
203
|
-
"source": {
|
|
204
|
-
"command": "list"
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
"widget": "actions",
|
|
209
|
-
"title": "Commands"
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
"widget": "credentials",
|
|
213
|
-
"title": "Credentials"
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
"widget": "activity",
|
|
217
|
-
"title": "Recent activity"
|
|
218
|
-
}
|
|
219
|
-
]
|
|
220
188
|
}
|
|
221
189
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"version": "0.1.0",
|
|
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": {
|
|
@@ -2566,9 +2566,9 @@
|
|
|
2566
2566
|
}
|
|
2567
2567
|
},
|
|
2568
2568
|
"node_modules/total-recall-brain": {
|
|
2569
|
-
"version": "3.40.
|
|
2570
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.
|
|
2571
|
-
"integrity": "sha512
|
|
2569
|
+
"version": "3.40.7",
|
|
2570
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.7.tgz",
|
|
2571
|
+
"integrity": "sha512-G+sEWXVucI5Zs8uV1ie8P+mV/6cncWX76ES72T5dnPB3sFAwlcG9ous2SYTUaYUOETGB2vHTSo3cV4XWkHQ0Ww==",
|
|
2572
2572
|
"dev": true,
|
|
2573
2573
|
"license": "MIT",
|
|
2574
2574
|
"workspaces": [
|
|
@@ -55,6 +55,17 @@
|
|
|
55
55
|
"handler": "./ui/card.js",
|
|
56
56
|
"element": "tr-embeddings-card"
|
|
57
57
|
},
|
|
58
|
+
"ui": {
|
|
59
|
+
"elements": [
|
|
60
|
+
{
|
|
61
|
+
"id": "card",
|
|
62
|
+
"kind": "card",
|
|
63
|
+
"tag": "tr-embeddings-card",
|
|
64
|
+
"module": "ui/card.js",
|
|
65
|
+
"description": "Embeddings card face"
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
},
|
|
58
69
|
"status": {
|
|
59
70
|
"command": "status",
|
|
60
71
|
"refresh_seconds": 60
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Git Hygiene
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reports the state of the git repository you run it in: current branch, staged / unstaged / untracked / conflicted files, commits not yet pushed to upstream, and stashes.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Reporting accuracy, verified 2026-10-23.** Two defects reported in the September 30 review are fixed and covered by testing:
|
|
6
|
+
|
|
7
|
+
- **Porcelain columns are preserved.** `git status --porcelain` output is never trimmed, so a file whose name begins with a space parses correctly. Verified against a file literally named `" leading-space.txt"`, which reports as `A leading-space.txt`.
|
|
8
|
+
- **An unknown upstream is never reported as zero unpushed commits.** `upstreamStatus` distinguishes `tracking`, `none`, `gone`, `detached`, `unborn`, `unknown` and `error`; where no comparison exists, `unpushedCommits` is `null` rather than `0`. Verified in a repository with no remote configured.
|
|
6
9
|
|
|
7
10
|
**Use cases:** software-development
|
|
8
11
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"version": "1.1.2",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"total-recall-brain": "3.40.
|
|
12
|
+
"total-recall-brain": "3.40.7",
|
|
13
13
|
"vitest": "^4.1.10"
|
|
14
14
|
}
|
|
15
15
|
},
|
|
@@ -3560,9 +3560,9 @@
|
|
|
3560
3560
|
}
|
|
3561
3561
|
},
|
|
3562
3562
|
"node_modules/total-recall-brain": {
|
|
3563
|
-
"version": "3.40.
|
|
3564
|
-
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.
|
|
3565
|
-
"integrity": "sha512
|
|
3563
|
+
"version": "3.40.7",
|
|
3564
|
+
"resolved": "https://registry.npmjs.org/total-recall-brain/-/total-recall-brain-3.40.7.tgz",
|
|
3565
|
+
"integrity": "sha512-G+sEWXVucI5Zs8uV1ie8P+mV/6cncWX76ES72T5dnPB3sFAwlcG9ous2SYTUaYUOETGB2vHTSo3cV4XWkHQ0Ww==",
|
|
3566
3566
|
"dev": true,
|
|
3567
3567
|
"license": "MIT",
|
|
3568
3568
|
"workspaces": [
|