total-recall-brain 3.44.0 → 3.45.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.mjs +6 -4
- package/docs/ARCHITECTURE.md +10 -7
- package/docs/reference/cli-reference.md +13 -8
- package/frontend/dist/assets/index-DACh1dhx.js +5613 -0
- package/frontend/dist/index.html +1 -1
- package/frontend/src/App.tsx +2 -2
- package/frontend/src/pages/PluginsPage.tsx +1 -1
- package/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/auth/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/cli-secret.mjs +20 -1
- package/scaffold/.agent/skills/total-recall/plugins/auth/src/secrets-store.mjs +12 -1
- package/scaffold/.agent/skills/total-recall/plugins/automations/BRICK.md +7 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/LICENSE +21 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/README.md +66 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/adapters.mjs +231 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/capability/index.mjs +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/cli.mjs +121 -0
- package/{src/core/plugin-cron.mjs → scaffold/.agent/skills/total-recall/plugins/automations/cron.mjs} +1 -3
- package/scaffold/.agent/skills/total-recall/plugins/automations/inventory.mjs +88 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/package-lock.json +7661 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/package.json +35 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/plugin.json +167 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/scheduler.mjs +246 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/DESIGN.md +42 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/automations.js +2 -0
- package/scaffold/.agent/skills/total-recall/plugins/automations/ui/card.js +273 -0
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/commands/run-core.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/check.mjs +57 -5
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report-data.mjs +40 -14
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/core/report.mjs +15 -40
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +1 -1
- 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 +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/composable-cli/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/embeddings/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/README.md +112 -0
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/cli.mjs +135 -23
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/package.json +2 -1
- package/scaffold/.agent/skills/total-recall/plugins/git/plugin.json +161 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/context.mjs +94 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/phase3-spec-support.mjs +50 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/runtime.mjs +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/lib/spec-support.mjs +51 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/_support.mjs +195 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/auth.mjs +201 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/bisect.mjs +40 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/cli-meta.mjs +159 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit-memory.mjs +30 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/commit.mjs +46 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/fleet.mjs +156 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/force-push.mjs +58 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/group.mjs +119 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/handoff.mjs +59 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/message.mjs +22 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/resolve.mjs +60 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/rules.mjs +81 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/secret-firewall.mjs +66 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/undo.mjs +132 -0
- package/scaffold/.agent/skills/total-recall/plugins/git/src/ops/why.mjs +16 -0
- package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/card.js +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/mesh/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/README.md +25 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/BRICK.md +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +18 -6
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +124 -24
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +147 -14
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +17 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/adoption.mjs +2 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +92 -18
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/control.mjs +145 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +42 -21
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch-request.mjs +4 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +33 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +55 -11
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +26 -4
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +29 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/included-usage.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/jobs.mjs +84 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +3 -12
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/maintenance.mjs +17 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/mcp-server.mjs +228 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/process-manager.mjs +25 -2
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reasoning.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/remote-operation.mjs +5 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +34 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/reviews.mjs +25 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/claude.mjs +319 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/codex.mjs +387 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/result.mjs +67 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/resume.mjs +373 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session/run.mjs +223 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/session-jobs.mjs +72 -0
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/setup.mjs +6 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/termination.mjs +16 -12
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +32 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/usage-queue.mjs +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/verify-ssss.mjs +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +285 -40
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +76 -9
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/DESIGN.md +5 -5
- package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +3 -3
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +47 -18
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh-diagnostics.mjs +44 -0
- package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +120 -113
- package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +7 -7
- package/scaffold/.agent/skills/total-recall/plugins/security/package.json +1 -1
- package/scaffold/.agent/skills/total-recall/plugins/security/plugin.json +1 -1
- package/scaffold/.agent/skills/total-recall/references/operations.md +1 -1
- package/src/cli/agent.mjs +1 -1
- package/src/cli/command.mjs +41 -2
- package/src/cli/dream.mjs +93 -69
- package/src/cli/harness.mjs +4 -4
- package/src/cli/help.mjs +1 -1
- package/src/cli/init.mjs +0 -25
- package/src/cli/lessons.mjs +51 -0
- package/src/cli/memory-plugin.mjs +1 -1
- package/src/cli/plugin/copies.mjs +64 -14
- package/src/cli/plugin/create.mjs +6 -7
- package/src/cli/plugin/index.mjs +11 -7
- package/src/cli/plugin/install.mjs +10 -15
- package/src/cli/plugin/remove.mjs +1 -1
- package/src/cli/plugin/search.mjs +2 -2
- package/src/cli/preflight.mjs +19 -6
- package/src/cli/proposals.mjs +1 -1
- package/src/cli/recall.mjs +66 -23
- package/src/cli/remember.mjs +3 -14
- package/src/cli/server.mjs +18 -0
- package/src/cli/startup.mjs +1 -0
- package/src/cli/task.mjs +9 -2
- package/src/cli/update.mjs +6 -2
- package/src/core/access-ledger.mjs +78 -0
- package/src/core/agent-manager.mjs +2 -2
- package/src/core/brain-locate.mjs +15 -0
- package/src/core/brain-updates.mjs +31 -11
- package/src/core/claude-hooks.mjs +3 -1
- package/src/core/cleanup-task.mjs +15 -0
- package/src/core/cli-commands.mjs +2 -0
- package/src/core/cli-maintenance.mjs +4 -1
- package/src/core/cli-semantic-index.mjs +23 -3
- package/src/core/context-compiler.mjs +20 -0
- package/src/core/daemon-loop.mjs +39 -62
- package/src/core/default-plugins.mjs +1 -1
- package/src/core/dream.mjs +33 -105
- package/src/core/ensure-dependencies.mjs +148 -0
- package/src/core/fast-recall.mjs +2 -2
- package/src/core/field-evaluation.mjs +23 -0
- package/src/core/gate-mode.mjs +1 -1
- package/src/core/harness-hooks.mjs +14 -2
- package/src/core/lesson-hooks.mjs +74 -0
- package/src/core/lesson-memory.mjs +24 -0
- package/src/core/lesson-sessions.mjs +52 -0
- package/src/core/lessons.mjs +96 -0
- package/src/core/meta-harness.mjs +2 -2
- package/src/core/optimizer.mjs +66 -165
- package/src/core/plugin-contracts/card.mjs +3 -0
- package/src/core/plugin-loader.mjs +12 -3
- package/src/core/plugin-runtime.mjs +40 -1
- package/src/core/plugin-store.mjs +35 -23
- package/src/core/post-mortem.mjs +52 -36
- package/src/core/preflight-gate.mjs +23 -2
- package/src/core/proposal-applier.mjs +31 -2
- package/src/core/repo-sync.mjs +4 -6
- package/src/core/required-plugins.mjs +26 -4
- package/src/core/rule-length.mjs +23 -0
- package/src/core/runtime.mjs +1 -1
- package/src/core/scheduler.mjs +35 -43
- package/src/core/schema.mjs +1 -2
- package/src/core/search.mjs +4 -3
- package/src/core/server-service.mjs +148 -0
- package/src/core/session-watcher.mjs +19 -1
- package/src/core/skill-gap.mjs +16 -0
- package/src/core/ssss-kernel-bridge.mjs +32 -4
- package/src/core/startup-health.mjs +6 -1
- package/src/core/surface.mjs +65 -54
- package/src/core/task-executors.mjs +54 -106
- package/src/core/validated-write.mjs +1 -0
- package/src/core/vector-field.mjs +134 -192
- package/src/server/invoke-core-child.mjs +24 -0
- package/src/server/invoke-core-operations.mjs +102 -0
- package/src/server/route-manifest.json +0 -56
- package/src/server/routes/brains.mjs +0 -18
- package/src/server/routes/context.mjs +0 -41
- package/src/server/routes/invoke.mjs +26 -1
- package/src/server/routes/ssss.mjs +0 -169
- package/src/server/routes/system.mjs +0 -15
- package/src/server/routes/tasks.mjs +0 -26
- package/src/server/routes/vault.mjs +2 -23
- package/frontend/dist/assets/index-DD4qONvH.js +0 -5607
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/README.md +0 -53
- package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/plugin.json +0 -129
- package/src/core/append-log.mjs +0 -131
- package/src/core/plugin-tasks.mjs +0 -173
- package/templates/onboarding-interview.md +0 -82
- /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/LICENSE +0 -0
- /package/scaffold/.agent/skills/total-recall/plugins/{git-sentinel → git}/ui/DESIGN.md +0 -0
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# Git Hygiene
|
|
2
|
-
|
|
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
|
-
|
|
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.
|
|
9
|
-
|
|
10
|
-
**Use cases:** software-development
|
|
11
|
-
|
|
12
|
-
## Install
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npx total-recall plugin install git-sentinel
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Use
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npx total-recall git-sentinel audit # human summary
|
|
22
|
-
npx total-recall git-sentinel audit --json # machine output for agents
|
|
23
|
-
npx total-recall git-sentinel diff # diffstat of unstaged changes
|
|
24
|
-
npx total-recall git-sentinel identity --json # current commit identity and local history audit
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Share with your other nodes
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npx total-recall plugin share git-sentinel
|
|
31
|
-
# on another node on the mesh:
|
|
32
|
-
npx total-recall plugin install peer:<this-node>/git-sentinel
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Capability scope
|
|
36
|
-
|
|
37
|
-
The plugin runs against the Git worktree selected by the installed Total Recall CLI. Use `diff --patch`, `--cached` and `--base <ref>` for actual Git comparisons. Worktree listing is read-only, creation makes a detached worktree, and removal requires a registered linked worktree. Dirty removal requires `--force`. See the [Git Sentinel project tracker](docs/projects/in-progress/GIT_SENTINEL_CARD/GIT_SENTINEL_CARD_PROJECT_TRACKER.md).
|
|
38
|
-
|
|
39
|
-
## Using this from an agent
|
|
40
|
-
|
|
41
|
-
Use the read operations for worktree state, changes, upstream comparison, stashes and commit identity. Worktree creation and removal have separate operation effects.
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
total-recall git-sentinel audit --json
|
|
45
|
-
total-recall git-sentinel diff --json
|
|
46
|
-
total-recall git-sentinel diff --patch --cached --json
|
|
47
|
-
total-recall git-sentinel identity --json
|
|
48
|
-
total-recall git-sentinel worktree-list --json
|
|
49
|
-
total-recall git-sentinel worktree-create <path> --base <ref> --json
|
|
50
|
-
total-recall git-sentinel worktree-remove <path> --json
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Raw commands this plugin owns: `git status`, `git stash list`, `git diff --stat`, `git config user.*` and author lookups through `git log`.
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://github.com/gregiteen/total-recall/blob/main/metadata.plugin.schema.json",
|
|
3
|
-
"id": "git-sentinel",
|
|
4
|
-
"name": "Git Sentinel",
|
|
5
|
-
"version": "1.1.5",
|
|
6
|
-
"description": "Worktree hygiene, branch inspection, unpushed commits, and stash tracker.",
|
|
7
|
-
"author": "Total Recall",
|
|
8
|
-
"license": "MIT",
|
|
9
|
-
"use_cases": [
|
|
10
|
-
"software-development"
|
|
11
|
-
],
|
|
12
|
-
"gate": {
|
|
13
|
-
"tasks": ["Check a repository's state before committing or pushing", "Review what changed in a working tree", "Read the commit identity"],
|
|
14
|
-
"owned_commands": [
|
|
15
|
-
{ "pattern": "git(\\s+-C\\s+\\S+)?\\s+status\\b", "use": "total-recall git-sentinel audit" },
|
|
16
|
-
{ "pattern": "git(\\s+-C\\s+\\S+)?\\s+stash\\s+list\\b", "use": "total-recall git-sentinel audit" },
|
|
17
|
-
{ "pattern": "git(\\s+-C\\s+\\S+)?\\s+diff\\s+--stat\\b", "use": "total-recall git-sentinel diff" },
|
|
18
|
-
{ "pattern": "git(\\s+-C\\s+\\S+)?\\s+config\\s+(--get\\s+)?user\\.(name|email)\\s*($|[;&|])", "use": "total-recall git-sentinel identity" },
|
|
19
|
-
{ "pattern": "git(\\s+-C\\s+\\S+)?\\s+log\\b[^;&|]*%a[en]", "use": "total-recall git-sentinel identity" }
|
|
20
|
-
]
|
|
21
|
-
},
|
|
22
|
-
"cli": {
|
|
23
|
-
"answers_help": true,
|
|
24
|
-
"command": "git-sentinel",
|
|
25
|
-
"handler": "./cli.mjs",
|
|
26
|
-
"subcommands": [
|
|
27
|
-
{
|
|
28
|
-
"name": "audit",
|
|
29
|
-
"description": "Summarise branch, worktree, upstream and stash state (--json for machine output)",
|
|
30
|
-
"effect": "read"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"name": "diff",
|
|
34
|
-
"description": "Read a stat or patch for unstaged, staged or base-relative changes",
|
|
35
|
-
"effect": "read",
|
|
36
|
-
"args": [
|
|
37
|
-
{ "name": "patch", "flag": "--patch", "type": "boolean", "label": "Show patch" },
|
|
38
|
-
{ "name": "cached", "flag": "--cached", "type": "boolean", "label": "Use staged changes" },
|
|
39
|
-
{ "name": "base", "flag": "--base", "type": "string", "label": "Base ref" }
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
{ "name": "worktree-list", "description": "Read registered worktrees for the current repository", "effect": "read" },
|
|
43
|
-
{ "name": "worktree-create", "description": "Create a detached worktree at a specified path and base ref", "effect": "write", "args": [
|
|
44
|
-
{ "name": "path", "type": "string", "label": "Worktree path", "required": true, "positional": true },
|
|
45
|
-
{ "name": "base", "flag": "--base", "type": "string", "label": "Base ref" }
|
|
46
|
-
] },
|
|
47
|
-
{ "name": "worktree-remove", "description": "Remove an owned linked worktree, with explicit force for dirty content", "effect": "destructive", "args": [
|
|
48
|
-
{ "name": "path", "type": "string", "label": "Worktree path", "required": true, "positional": true },
|
|
49
|
-
{ "name": "force", "flag": "--force", "type": "boolean", "label": "Allow removal of dirty content" }
|
|
50
|
-
] },
|
|
51
|
-
{ "name": "worktree", "description": "Compatibility form: worktree list, create or remove", "effect": "destructive" },
|
|
52
|
-
{
|
|
53
|
-
"name": "identity",
|
|
54
|
-
"description": "Show who commits here and which identities the history publishes; exits 1 on a missing or machine-derived identity (--json for machine output)",
|
|
55
|
-
"effect": "read"
|
|
56
|
-
}
|
|
57
|
-
]
|
|
58
|
-
},
|
|
59
|
-
"card_face": {
|
|
60
|
-
"skin": "copper-obsidian",
|
|
61
|
-
"theme": "copper",
|
|
62
|
-
"headline": "Worktree Hygiene & Repository Watch",
|
|
63
|
-
"primary_color": "#b45309",
|
|
64
|
-
"secondary_color": "#0c0a09",
|
|
65
|
-
"accent_color": "#f59e0b",
|
|
66
|
-
"touch_layout": "comfortable",
|
|
67
|
-
"interactive": true,
|
|
68
|
-
"quick_actions": [
|
|
69
|
-
{
|
|
70
|
-
"subcommand": "audit",
|
|
71
|
-
"label": "AUDIT"
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
"subcommand": "diff",
|
|
75
|
-
"label": "DIFFSTAT"
|
|
76
|
-
}
|
|
77
|
-
]
|
|
78
|
-
},
|
|
79
|
-
"ui": {
|
|
80
|
-
"design_tokens": "ui/DESIGN.md",
|
|
81
|
-
"elements": [
|
|
82
|
-
{
|
|
83
|
-
"id": "card",
|
|
84
|
-
"kind": "card",
|
|
85
|
-
"tag": "tr-git-sentinel-card",
|
|
86
|
-
"module": "ui/card.js",
|
|
87
|
-
"description": "Git Hygiene Repository Hygiene Card Face"
|
|
88
|
-
}
|
|
89
|
-
]
|
|
90
|
-
},
|
|
91
|
-
"auth": {
|
|
92
|
-
"plugin": "auth",
|
|
93
|
-
"methods": [
|
|
94
|
-
"passkey",
|
|
95
|
-
"google-oauth2"
|
|
96
|
-
],
|
|
97
|
-
"session_verification": true
|
|
98
|
-
},
|
|
99
|
-
"deploy": {
|
|
100
|
-
"targets": [
|
|
101
|
-
"ssss-app",
|
|
102
|
-
"nextjs",
|
|
103
|
-
"react",
|
|
104
|
-
"flask"
|
|
105
|
-
],
|
|
106
|
-
"required_ssss_version": ">=0.9.3",
|
|
107
|
-
"access_grants": [
|
|
108
|
-
"auth:session:verify",
|
|
109
|
-
"ssss:vault:read",
|
|
110
|
-
"ssss:vault:write",
|
|
111
|
-
"ssss:events:append"
|
|
112
|
-
]
|
|
113
|
-
},
|
|
114
|
-
"branding": {
|
|
115
|
-
"name": "Git Hygiene",
|
|
116
|
-
"color": "#b45309",
|
|
117
|
-
"accent": "#f59e0b",
|
|
118
|
-
"badge": "Repository Hygiene",
|
|
119
|
-
"font": "space-grotesk"
|
|
120
|
-
},
|
|
121
|
-
"status": {
|
|
122
|
-
"command": "audit",
|
|
123
|
-
"refresh_seconds": 60
|
|
124
|
-
},
|
|
125
|
-
"distribution": {
|
|
126
|
-
"tier": "official",
|
|
127
|
-
"license": "open"
|
|
128
|
-
}
|
|
129
|
-
}
|
package/src/core/append-log.mjs
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Append-only JSONL log with last-write-wins semantics and compaction.
|
|
3
|
-
*
|
|
4
|
-
* Write: O(1) — fs.appendFileSync one line
|
|
5
|
-
* Read: O(n) on cold load, cached after first read
|
|
6
|
-
* Compact: Rewrites only latest version of each key
|
|
7
|
-
*
|
|
8
|
-
* File format: One JSON object per line, each with a mandatory `_key` field.
|
|
9
|
-
* Later entries for the same `_key` shadow earlier ones.
|
|
10
|
-
* Tombstones: { "_key": "slug", "_deleted": true }
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import fs from 'node:fs';
|
|
14
|
-
import path from 'node:path';
|
|
15
|
-
import { atomicWrite } from './vault.mjs';
|
|
16
|
-
import { logger } from './logger.mjs';
|
|
17
|
-
|
|
18
|
-
/** @type {Map<string, AppendLog>} Registry of all active AppendLog instances */
|
|
19
|
-
const activeAppendLogs = new Map();
|
|
20
|
-
|
|
21
|
-
export class AppendLog {
|
|
22
|
-
#filePath;
|
|
23
|
-
#cache; // Map<string, object> — latest value per key
|
|
24
|
-
#dirty; // number of appended lines since last compact
|
|
25
|
-
#compactThreshold;
|
|
26
|
-
|
|
27
|
-
constructor(filePath, { compactThreshold = 500 } = {}) {
|
|
28
|
-
this.#filePath = filePath;
|
|
29
|
-
this.#cache = null;
|
|
30
|
-
this.#dirty = 0;
|
|
31
|
-
this.#compactThreshold = compactThreshold;
|
|
32
|
-
activeAppendLogs.set(filePath, this);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** Read the full index. Returns Map<key, value>. Cached after first call. */
|
|
36
|
-
entries() {
|
|
37
|
-
if (this.#cache) return this.#cache;
|
|
38
|
-
this.#cache = new Map();
|
|
39
|
-
if (!fs.existsSync(this.#filePath)) return this.#cache;
|
|
40
|
-
const raw = fs.readFileSync(this.#filePath, 'utf8');
|
|
41
|
-
for (const line of raw.split('\n')) {
|
|
42
|
-
if (!line.trim()) continue;
|
|
43
|
-
try {
|
|
44
|
-
const entry = JSON.parse(line);
|
|
45
|
-
if (entry._deleted) this.#cache.delete(entry._key);
|
|
46
|
-
else this.#cache.set(entry._key, entry);
|
|
47
|
-
} catch { /* skip corrupt lines */ }
|
|
48
|
-
}
|
|
49
|
-
return this.#cache;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** Get a single entry by key. */
|
|
53
|
-
get(key) {
|
|
54
|
-
return this.entries().get(key) ?? null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Append a single entry. O(1) I/O. */
|
|
58
|
-
append(key, value) {
|
|
59
|
-
const dir = path.dirname(this.#filePath);
|
|
60
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
61
|
-
const entry = { _key: key, ...value };
|
|
62
|
-
fs.appendFileSync(this.#filePath, JSON.stringify(entry) + '\n');
|
|
63
|
-
// Update in-memory cache
|
|
64
|
-
this.entries().set(key, entry);
|
|
65
|
-
this.#dirty++;
|
|
66
|
-
if (this.#dirty >= this.#compactThreshold) {
|
|
67
|
-
this.compact();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** Write a tombstone for a key. O(1) I/O. */
|
|
72
|
-
remove(key) {
|
|
73
|
-
const dir = path.dirname(this.#filePath);
|
|
74
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
75
|
-
fs.appendFileSync(this.#filePath, JSON.stringify({ _key: key, _deleted: true }) + '\n');
|
|
76
|
-
this.entries().delete(key);
|
|
77
|
-
this.#dirty++;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** Number of live entries. */
|
|
81
|
-
get size() {
|
|
82
|
-
return this.entries().size;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** Convert to plain object (for JSON.stringify compatibility). */
|
|
86
|
-
toObject() {
|
|
87
|
-
const obj = {};
|
|
88
|
-
for (const [key, value] of this.entries()) {
|
|
89
|
-
const { _key, ...rest } = value;
|
|
90
|
-
obj[key] = rest;
|
|
91
|
-
}
|
|
92
|
-
return obj;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** Compact: rewrite file with only latest versions. */
|
|
96
|
-
compact() {
|
|
97
|
-
const entries = this.entries();
|
|
98
|
-
const lines = [];
|
|
99
|
-
for (const [, value] of entries) {
|
|
100
|
-
lines.push(JSON.stringify(value));
|
|
101
|
-
}
|
|
102
|
-
atomicWrite(this.#filePath, lines.join('\n') + '\n');
|
|
103
|
-
this.#dirty = 0;
|
|
104
|
-
logger.info('append-log', `Compacted ${this.#filePath}: ${lines.length} entries`);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Invalidate the in-memory cache (force reload on next read). */
|
|
108
|
-
invalidate() {
|
|
109
|
-
this.#cache = null;
|
|
110
|
-
this.#dirty = 0;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Compact all active AppendLog instances.
|
|
116
|
-
* Returns summary with number of logs compacted and total entries.
|
|
117
|
-
*/
|
|
118
|
-
export function compactAppendLogs() {
|
|
119
|
-
let logsCompacted = 0;
|
|
120
|
-
let totalEntries = 0;
|
|
121
|
-
for (const [filePath, log] of activeAppendLogs) {
|
|
122
|
-
try {
|
|
123
|
-
log.compact();
|
|
124
|
-
logsCompacted++;
|
|
125
|
-
totalEntries += log.size;
|
|
126
|
-
} catch (err) {
|
|
127
|
-
logger.warn('append-log', `Failed to compact ${filePath}: ${err.message}`);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return { logs_compacted: logsCompacted, total_entries: totalEntries };
|
|
131
|
-
}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Scheduled plugin tasks.
|
|
3
|
-
*
|
|
4
|
-
* A manifest task `{ intent, schedule: "<5-field cron>", command }` runs the
|
|
5
|
-
* plugin's own CLI subcommand on that schedule, out of process. Tasks are per
|
|
6
|
-
* node by default, regardless of leadership. Tasks with selected-node placement
|
|
7
|
-
* require an explicit matching node in plugin_record.task_nodes[command].
|
|
8
|
-
*
|
|
9
|
-
* The last minute-slot each command ran in is kept in the plugin_record, so a
|
|
10
|
-
* restart neither repeats a slot nor loses one: when the daemon was busy or
|
|
11
|
-
* down, the most recent matching slot since the last run (within a day) runs
|
|
12
|
-
* once. A task never runs just because it was installed — the first run is the
|
|
13
|
-
* first matching slot after the scheduler first sees it.
|
|
14
|
-
*/
|
|
15
|
-
import { discoverPlugins } from './plugin-loader.mjs';
|
|
16
|
-
import { readPluginRecord, patchPluginRecord, ensurePluginRecord } from './plugin-store.mjs';
|
|
17
|
-
import { pluginExecutionEnabled } from './plugin-state.mjs';
|
|
18
|
-
import { runPluginCommand } from './plugin-runner.mjs';
|
|
19
|
-
import { appendVfsEvent } from './ssss-operation-service.mjs';
|
|
20
|
-
import { vaultForPluginsDir } from './plugin-loader.mjs';
|
|
21
|
-
import { logger } from './logger.mjs';
|
|
22
|
-
import { getMeshSelf, meshNodeKey } from './mesh.mjs';
|
|
23
|
-
|
|
24
|
-
const TASK_TIMEOUT_MS = 60_000;
|
|
25
|
-
const MAX_CATCHUP_MINUTES = 24 * 60;
|
|
26
|
-
import { parseCron, cronMatches } from './plugin-cron.mjs';
|
|
27
|
-
export { parseCron, cronMatches } from './plugin-cron.mjs';
|
|
28
|
-
const pad = (n) => String(n).padStart(2, '0');
|
|
29
|
-
|
|
30
|
-
/** A selected-node task stays idle until this node's plugin record selects it. */
|
|
31
|
-
export function taskRunsOnNode(task, record, self) {
|
|
32
|
-
if (task.placement !== 'selected-node') return true;
|
|
33
|
-
const selected = String(record?.task_nodes?.[task.command] || '').trim();
|
|
34
|
-
if (!selected || !self?.hostname) return false;
|
|
35
|
-
return selected === self.ip || meshNodeKey(selected) === meshNodeKey(self.hostname);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Local minute-slot key, e.g. 2026-09-22T14:05. */
|
|
39
|
-
export function minuteSlot(date) {
|
|
40
|
-
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function slotToDate(slot) {
|
|
44
|
-
const m = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/.exec(String(slot || ''));
|
|
45
|
-
return m ? new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]), Number(m[4]), Number(m[5])) : null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* The most recent slot matching `cron` in (lastSlot, now], or null.
|
|
50
|
-
* @returns {string|null}
|
|
51
|
-
*/
|
|
52
|
-
export function latestDueSlot(cron, lastSlot, now = new Date()) {
|
|
53
|
-
const floorNow = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes());
|
|
54
|
-
const last = slotToDate(lastSlot);
|
|
55
|
-
for (let i = 0; i < MAX_CATCHUP_MINUTES; i++) {
|
|
56
|
-
const candidate = new Date(floorNow.getTime() - i * 60_000);
|
|
57
|
-
if (last && candidate <= last) return null;
|
|
58
|
-
if (cronMatches(cron, candidate)) return minuteSlot(candidate);
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Run every task that is due. Tasks run sequentially so a slow plugin cannot
|
|
65
|
-
* multiply into concurrent processes on a constrained host.
|
|
66
|
-
* @param {{ projectRoot?: string, now?: Date, runner?: Function, selfNode?: object }} [options]
|
|
67
|
-
* @returns {Promise<Array<{ plugin: string, command: string, slot: string, ok: boolean, exitCode: number|null }>>}
|
|
68
|
-
*/
|
|
69
|
-
export async function runDuePluginTasks(options = {}) {
|
|
70
|
-
const { projectRoot = process.cwd(), now = new Date(), runner = runPluginCommand } = options;
|
|
71
|
-
const selfNode = options.selfNode === undefined ? getMeshSelf() : options.selfNode;
|
|
72
|
-
const results = [];
|
|
73
|
-
|
|
74
|
-
for (const plugin of discoverPlugins(projectRoot)) {
|
|
75
|
-
if (!plugin.valid || !Array.isArray(plugin.manifest.tasks) || plugin.manifest.tasks.length === 0) continue;
|
|
76
|
-
|
|
77
|
-
let record = readPluginRecord(plugin);
|
|
78
|
-
if (!record) record = await ensurePluginRecord(plugin);
|
|
79
|
-
// Scheduled work follows the repository's own setting for a shared plugin.
|
|
80
|
-
if (!pluginExecutionEnabled(plugin, { projectRoot })) continue;
|
|
81
|
-
const runs = { ...(record?.task_runs || {}) };
|
|
82
|
-
let changed = false;
|
|
83
|
-
|
|
84
|
-
for (const task of plugin.manifest.tasks) {
|
|
85
|
-
if (!taskRunsOnNode(task, record, selfNode)) continue;
|
|
86
|
-
let cron;
|
|
87
|
-
try {
|
|
88
|
-
cron = parseCron(task.schedule);
|
|
89
|
-
} catch (err) {
|
|
90
|
-
logger.warn('plugin-tasks', `Skipping ${plugin.id}:${task.command} — ${err.message}`);
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (!runs[task.command]) {
|
|
95
|
-
// First sighting: mark the present so the first run is the next real slot.
|
|
96
|
-
runs[task.command] = minuteSlot(now);
|
|
97
|
-
changed = true;
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const slot = latestDueSlot(cron, runs[task.command], now);
|
|
102
|
-
if (!slot) continue;
|
|
103
|
-
|
|
104
|
-
const result = await runner(plugin, { subcommand: task.command, cwd: projectRoot, timeoutMs: task.timeout_ms || TASK_TIMEOUT_MS })
|
|
105
|
-
.catch((err) => ({ ok: false, exitCode: null, output: err.message, durationMs: 0, timedOut: false }));
|
|
106
|
-
runs[task.command] = slot;
|
|
107
|
-
changed = true;
|
|
108
|
-
results.push({ plugin: plugin.id, command: task.command, slot, ok: result.ok, exitCode: result.exitCode });
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
await appendVfsEvent(
|
|
112
|
-
`plugins/${plugin.id}/task-${Date.now()}`,
|
|
113
|
-
{
|
|
114
|
-
kind: 'plugin.task_run',
|
|
115
|
-
plugin_id: plugin.id,
|
|
116
|
-
command: task.command,
|
|
117
|
-
intent: task.intent,
|
|
118
|
-
slot,
|
|
119
|
-
ok: result.ok,
|
|
120
|
-
exit_code: result.exitCode,
|
|
121
|
-
timed_out: !!result.timedOut,
|
|
122
|
-
duration_ms: result.durationMs,
|
|
123
|
-
output_tail: String(result.output || '').slice(-2000)
|
|
124
|
-
},
|
|
125
|
-
{ actorRole: 'system', intent: 'Record plugin task run', vaultRoot: vaultForPluginsDir(plugin.pluginsDir) }
|
|
126
|
-
);
|
|
127
|
-
} catch (err) {
|
|
128
|
-
logger.warn('plugin-tasks', `Could not record task run for ${plugin.id}: ${err.message}`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (changed) {
|
|
133
|
-
try {
|
|
134
|
-
await patchPluginRecord(plugin, { task_runs: runs });
|
|
135
|
-
} catch (err) {
|
|
136
|
-
logger.warn('plugin-tasks', `Could not update task runs for ${plugin.id}: ${err.message}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return results;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
let timer = null;
|
|
145
|
-
let running = false;
|
|
146
|
-
|
|
147
|
-
/** Check for due plugin tasks once a minute. Returns a stop function. */
|
|
148
|
-
export function startPluginTaskScheduler(options = {}) {
|
|
149
|
-
if (timer) return () => stopPluginTaskScheduler();
|
|
150
|
-
const tick = async () => {
|
|
151
|
-
if (running) return;
|
|
152
|
-
running = true;
|
|
153
|
-
try {
|
|
154
|
-
const results = await runDuePluginTasks(options);
|
|
155
|
-
for (const r of results) {
|
|
156
|
-
logger.info('plugin-tasks', `${r.plugin}:${r.command} slot ${r.slot} ${r.ok ? 'ok' : `failed (exit ${r.exitCode})`}`);
|
|
157
|
-
}
|
|
158
|
-
} catch (err) {
|
|
159
|
-
logger.warn('plugin-tasks', `Scheduler tick failed: ${err.message}`);
|
|
160
|
-
} finally {
|
|
161
|
-
running = false;
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
timer = setInterval(tick, 60_000);
|
|
165
|
-
timer.unref?.();
|
|
166
|
-
tick();
|
|
167
|
-
return () => stopPluginTaskScheduler();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
export function stopPluginTaskScheduler() {
|
|
171
|
-
if (timer) clearInterval(timer);
|
|
172
|
-
timer = null;
|
|
173
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: task
|
|
3
|
-
slug: onboarding-interview
|
|
4
|
-
category: onboarding
|
|
5
|
-
title: "Conduct portable-memory onboarding interview"
|
|
6
|
-
status: pending
|
|
7
|
-
priority: 1
|
|
8
|
-
created: {{CREATED_AT}}
|
|
9
|
-
updated: {{CREATED_AT}}
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## Objective
|
|
13
|
-
|
|
14
|
-
Conduct a warm, practical onboarding interview so Total Recall can store durable preferences and facts as Markdown memory nodes. This is personal portable memory — not an operating system takeover. Keep the tone helpful and concrete.
|
|
15
|
-
|
|
16
|
-
## Instructions for the Agent
|
|
17
|
-
|
|
18
|
-
When the user starts their next chat session (and they have no `user-profile` yet), conduct this interview BEFORE unrelated work. Do NOT dump all questions at once. Ask one at a time. Acknowledge each answer before the next.
|
|
19
|
-
|
|
20
|
-
Once the user has answered (or skipped any), write their answers into the vault using tools / CLI (`remember` or direct vault writes). Prefer CLI when available:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npx total-recall remember preference "..." --tags "user,profile,onboarding" --importance 5
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Interview Questions (ask one at a time)
|
|
27
|
-
|
|
28
|
-
1. **Who are you?** — "Quick intro: what do you do, and what are you most focused on right now?"
|
|
29
|
-
|
|
30
|
-
2. **What should I remember?** — "What kinds of things matter most for me to keep: decisions, preferences, project facts, people, or something else?"
|
|
31
|
-
|
|
32
|
-
3. **Which tools do you use?** — "Which IDEs or agents should share this memory? (Claude Code, Cursor, Codex, Gemini, Aider, Obsidian, HTTP, etc.) I can guide you with `npx total-recall connect …`."
|
|
33
|
-
|
|
34
|
-
4. **How should I talk?** — "Prefer short answers or detailed ones? Should I push back or mostly support?"
|
|
35
|
-
|
|
36
|
-
5. **Hard rules** — "Any absolute do's or don'ts I must always follow (style, tools, safety)?"
|
|
37
|
-
|
|
38
|
-
6. **Background work** — "Want dream consolidation and optional daemon tasks running in the background, or on-demand only?"
|
|
39
|
-
|
|
40
|
-
7. **Secrets** — "API keys never go in the vault. Use `npx total-recall auth secret set`. Any keys you want to set up next?"
|
|
41
|
-
|
|
42
|
-
8. **Notifications (optional)** — "Want Telegram pings when background tasks finish? If yes, BotFather token + chat ID."
|
|
43
|
-
|
|
44
|
-
## Product context to reinforce (lightly, not as a lecture)
|
|
45
|
-
|
|
46
|
-
- **Write** → `remember` / session ingest
|
|
47
|
-
- **Sleep** → `dream` (consolidate, conflict-check, recompile)
|
|
48
|
-
- **Read** → `recall` + compiled surfaces in any connected IDE
|
|
49
|
-
- **Async** → open task queue / daemon under policy
|
|
50
|
-
- Hosts are equal — track any repo; no product-specific hardcoding
|
|
51
|
-
|
|
52
|
-
## After the Interview
|
|
53
|
-
|
|
54
|
-
Write (or update) these files:
|
|
55
|
-
|
|
56
|
-
**`.agent/config/notifications.yml`** — only if they provided Telegram details:
|
|
57
|
-
```yaml
|
|
58
|
-
telegram_bot_token: "their-token-here"
|
|
59
|
-
telegram_chat_id: "their-chat-id-here"
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**`.agent/memory-vault/preferences/user-profile.md`** — identity + communication style
|
|
63
|
-
**`.agent/memory-vault/preferences/user-priorities.md`** — goals and what they want from memory
|
|
64
|
-
**`.agent/memory-vault/preferences/user-interests.md`** — topics worth tracking
|
|
65
|
-
|
|
66
|
-
Frontmatter template:
|
|
67
|
-
```yaml
|
|
68
|
-
---
|
|
69
|
-
type: memory
|
|
70
|
-
slug: user-profile
|
|
71
|
-
category: preferences
|
|
72
|
-
title: "User Profile"
|
|
73
|
-
status: active
|
|
74
|
-
confidence: 1.0
|
|
75
|
-
importance: 5
|
|
76
|
-
created: <ISO timestamp>
|
|
77
|
-
updated: <ISO timestamp>
|
|
78
|
-
tags: [user, profile, onboarding]
|
|
79
|
-
---
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Then mark this task `status: done` and confirm the profile was saved. Point them at the dashboard **Onboarding** page or `init → connect → remember → dream` if they prefer CLI-only.
|
|
File without changes
|
|
File without changes
|