@time-machine-lab/tmlbrain 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -14
- package/bin/tmlbrain.js +460 -57
- package/docs/architecture.md +20 -1
- package/docs/backup.md +57 -5
- package/docs/indexing.md +23 -4
- package/docs/install.md +44 -15
- package/docs/runtime.md +26 -9
- package/docs/server-api.md +62 -13
- package/docs/sync.md +24 -4
- package/package.json +3 -1
- package/scripts/backup/scheduled-backup.sh +32 -0
- package/scripts/backup/tmlbrain-backup.service +9 -0
- package/scripts/backup/tmlbrain-backup.timer +10 -0
- package/scripts/docker/server-entrypoint.sh +5 -1
- package/scripts/release/parse-auto-release.js +1 -1
- package/skills/tmlbrain/SKILL.md +34 -10
package/docs/architecture.md
CHANGED
|
@@ -50,6 +50,19 @@ editing interface, and clients do not push to it.
|
|
|
50
50
|
The Docker image intentionally contains only the TMLBrain tool and knowledge
|
|
51
51
|
templates. It must not contain real team knowledge.
|
|
52
52
|
|
|
53
|
+
## Knowledge Placement
|
|
54
|
+
|
|
55
|
+
Archive, store, save, and record are equivalent user intents for adding content
|
|
56
|
+
to TMLBrain. New knowledge is classified into the approved taxonomy by default:
|
|
57
|
+
|
|
58
|
+
- `project`, `meeting`, and `decision` content goes under `knowledge/10-projects/`.
|
|
59
|
+
- `area` content goes under `knowledge/20-areas/`.
|
|
60
|
+
- `resource` content goes under `knowledge/30-resources/`.
|
|
61
|
+
- `reference` content goes under `knowledge/40-references/`.
|
|
62
|
+
|
|
63
|
+
`knowledge/00-inbox/` is reserved for genuinely unclassified or explicitly
|
|
64
|
+
temporary capture, not as the default destination for normal saves.
|
|
65
|
+
|
|
53
66
|
## Release Workflow
|
|
54
67
|
|
|
55
68
|
The npm client package, Docker server image, and server deployment are handled
|
|
@@ -72,7 +85,13 @@ After pushing the image, the workflow logs in to the configured server with
|
|
|
72
85
|
restarts the `tmlbrain-server` container. Runtime knowledge repository
|
|
73
86
|
credentials are passed to the server as mounted secrets or environment
|
|
74
87
|
configuration; they are never baked into the image. Knowledge repository URLs
|
|
75
|
-
must be HTTPS URLs and use `TMLBRAIN_KNOWLEDGE_TOKEN`.
|
|
88
|
+
must be HTTPS URLs and use `TMLBRAIN_KNOWLEDGE_TOKEN`. Deployment validates the
|
|
89
|
+
knowledge repository URL and token before replacing the running server.
|
|
90
|
+
|
|
91
|
+
If the server needs a proxy for GitHub, deployment can use
|
|
92
|
+
`TMLBRAIN_SERVER_GIT_PROXY_URL` or an existing `tmlbrain-proxy` container. The
|
|
93
|
+
proxy is configured as a Git-only proxy for `https://github.com`, so normal
|
|
94
|
+
server API traffic is unchanged.
|
|
76
95
|
|
|
77
96
|
## Search And Graph Layer
|
|
78
97
|
|
package/docs/backup.md
CHANGED
|
@@ -6,9 +6,9 @@ The dedicated knowledge repository is used for disaster recovery, reviewable
|
|
|
6
6
|
history, first-boot restore, and off-server backup. It is not the primary
|
|
7
7
|
editing surface.
|
|
8
8
|
|
|
9
|
-
The server needs a dedicated knowledge repository credential
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
The server needs a dedicated knowledge repository credential if it is expected
|
|
10
|
+
to push backup state to GitHub. Clients never need repository write
|
|
11
|
+
credentials.
|
|
12
12
|
|
|
13
13
|
If TMLBrain must upload modified server knowledge back to GitHub, the running
|
|
14
14
|
server needs write authorization for the dedicated knowledge repository. GitHub
|
|
@@ -27,7 +27,7 @@ Recommended credential option:
|
|
|
27
27
|
Do not bake knowledge repository credentials into the Docker image. Do not
|
|
28
28
|
commit them to the project configuration. GitHub Actions secrets can be used to
|
|
29
29
|
deploy the credential to the server or create a Docker secret, but the running
|
|
30
|
-
server still needs access to a credential when it performs
|
|
30
|
+
server still needs access to a credential when it performs backup.
|
|
31
31
|
|
|
32
32
|
The auto-release workflow supports this deployment pattern with:
|
|
33
33
|
|
|
@@ -40,6 +40,18 @@ TMLBRAIN_KNOWLEDGE_REF
|
|
|
40
40
|
`TMLBRAIN_KNOWLEDGE_REPO` must be an HTTPS repository URL. The workflow writes
|
|
41
41
|
`TMLBRAIN_KNOWLEDGE_TOKEN` to a mounted secret file and uses `GIT_ASKPASS`
|
|
42
42
|
inside the container, so Git can clone on first boot and push backups later.
|
|
43
|
+
During deployment, the workflow validates the repository URL and token before
|
|
44
|
+
restarting the server container.
|
|
45
|
+
|
|
46
|
+
If the server cannot reach GitHub directly, set:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
TMLBRAIN_SERVER_GIT_PROXY_URL
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This proxy is scoped to Git operations for `https://github.com` only. If the
|
|
53
|
+
secret is not set but a `tmlbrain-proxy` container exists on the server, the
|
|
54
|
+
deployment uses that container automatically.
|
|
43
55
|
|
|
44
56
|
## Dry Run
|
|
45
57
|
|
|
@@ -51,6 +63,46 @@ tmlbrain backup --dry-run --remote backup
|
|
|
51
63
|
|
|
52
64
|
The command reports the source commit, target remote, and whether the target remote exists. Backup attempts are logged under `.tmlbrain/logs/backup.log`.
|
|
53
65
|
|
|
66
|
+
## Write-Time Backup
|
|
67
|
+
|
|
68
|
+
When a server API write creates a new commit, the server first pushes that
|
|
69
|
+
commit to its local `origin` bare repository, then attempts to push `HEAD` to
|
|
70
|
+
the configured `backup` remote. The backup result is returned in the API
|
|
71
|
+
response and appended to `.tmlbrain/logs/backup.log`.
|
|
72
|
+
|
|
73
|
+
Backup failure does not roll back the accepted knowledge write. Maintainers can
|
|
74
|
+
inspect the backup log and rerun:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
tmlbrain backup --remote backup
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Scheduled Backup
|
|
81
|
+
|
|
82
|
+
Write-time backup is the primary path. Scheduled backup is a server-side
|
|
83
|
+
fallback for missed pushes or manual server maintenance.
|
|
84
|
+
|
|
85
|
+
Docker deployments can enable the fallback loop with:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
TMLBRAIN_BACKUP_INTERVAL_SECONDS=900
|
|
89
|
+
TMLBRAIN_BACKUP_REMOTE=backup
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
When the interval is greater than zero, the container starts
|
|
93
|
+
`scripts/backup/scheduled-backup.sh` in the background and runs
|
|
94
|
+
`tmlbrain backup --remote <remote>` from `/data/worktree` at that interval.
|
|
95
|
+
|
|
96
|
+
Non-Docker deployments can use the templates:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
scripts/backup/tmlbrain-backup.service
|
|
100
|
+
scripts/backup/tmlbrain-backup.timer
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Copy them to `/etc/systemd/system/`, adjust paths if needed, then enable the
|
|
104
|
+
timer.
|
|
105
|
+
|
|
54
106
|
For Docker deployments, keep Git inside the server image or sidecar because the
|
|
55
107
|
server write path still commits and pushes. The client runtime can remain
|
|
56
108
|
HTTP-only and does not need Git.
|
|
@@ -60,7 +112,7 @@ HTTP-only and does not need Git.
|
|
|
60
112
|
For Docker deployments, first-boot restore can be handled by:
|
|
61
113
|
|
|
62
114
|
```text
|
|
63
|
-
TMLBRAIN_KNOWLEDGE_REPO=https://github.com/Time-Machine-Lab/
|
|
115
|
+
TMLBRAIN_KNOWLEDGE_REPO=https://github.com/Time-Machine-Lab/Knowledge.git
|
|
64
116
|
```
|
|
65
117
|
|
|
66
118
|
If `/data/worktree` is missing, the container clones that repository. If the
|
package/docs/indexing.md
CHANGED
|
@@ -6,8 +6,8 @@ TMLBrain retrieval is local-first:
|
|
|
6
6
|
|
|
7
7
|
1. Exact search with ripgrep or the CLI fallback.
|
|
8
8
|
2. Deterministic Markdown index generated by `tmlbrain index`.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
9
|
+
3. CocoIndex-compatible incremental pipeline through `tmlbrain graph index`.
|
|
10
|
+
4. LightRAG-compatible graph and semantic retrieval through `tmlbrain graph query`.
|
|
11
11
|
|
|
12
12
|
## Deterministic Index
|
|
13
13
|
|
|
@@ -22,11 +22,30 @@ These files are local generated artifacts and must not be pushed to the server.
|
|
|
22
22
|
|
|
23
23
|
## Graph Runtime
|
|
24
24
|
|
|
25
|
-
CocoIndex and LightRAG are preferred for the fuller graph retrieval pipeline,
|
|
25
|
+
CocoIndex and LightRAG are preferred for the fuller graph retrieval pipeline,
|
|
26
|
+
but exact search and the deterministic index remain available when the graph
|
|
27
|
+
runtime is disabled or optional packages are unavailable.
|
|
26
28
|
|
|
27
29
|
Optional adapter entrypoints live in:
|
|
28
30
|
|
|
29
31
|
- `scripts/index/cocoindex_pipeline.py`
|
|
30
32
|
- `scripts/index/lightrag_retrieval.py`
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Use:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
tmlbrain graph index --json
|
|
38
|
+
tmlbrain graph query "question" --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`tmlbrain graph index` scans `knowledge/**/*.md`, parses front matter,
|
|
42
|
+
headings, chunks, hashes, Markdown links, wiki links, heading anchors, and
|
|
43
|
+
backlinks, then writes local artifacts under `.tmlbrain/index/cocoindex/`.
|
|
44
|
+
It reuses the previous manifest to skip unchanged document entries by content
|
|
45
|
+
hash.
|
|
46
|
+
|
|
47
|
+
`tmlbrain graph query` reads the CocoIndex-compatible chunks and graph context,
|
|
48
|
+
then returns ranked local chunks with source paths, line ranges, document
|
|
49
|
+
metadata, and related graph edges. When LightRAG is installed/configured, the
|
|
50
|
+
adapter reports the preferred engine as available; otherwise it uses the
|
|
51
|
+
deterministic local compatible retriever and reports degraded status.
|
package/docs/install.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## Client
|
|
4
4
|
|
|
5
|
-
Recommended
|
|
5
|
+
Recommended npm install:
|
|
6
6
|
|
|
7
7
|
```text
|
|
8
|
-
|
|
8
|
+
npm install -g @time-machine-lab/tmlbrain@latest
|
|
9
|
+
tmlbrain client install
|
|
9
10
|
```
|
|
10
11
|
|
|
11
12
|
The installer asks for:
|
|
@@ -19,21 +20,31 @@ search, index, and save Markdown under the local `knowledge/` folder. They can
|
|
|
19
20
|
connect to a team server later:
|
|
20
21
|
|
|
21
22
|
```text
|
|
22
|
-
tmlbrain config set-server http://server-host:
|
|
23
|
+
tmlbrain config set-server http://server-host:8477 --token <token>
|
|
23
24
|
tmlbrain sync --pull
|
|
24
25
|
```
|
|
25
26
|
|
|
26
|
-
Non-interactive
|
|
27
|
+
Non-interactive npm install:
|
|
27
28
|
|
|
28
29
|
```text
|
|
29
|
-
|
|
30
|
+
npm install -g @time-machine-lab/tmlbrain@latest
|
|
31
|
+
tmlbrain client install --server http://server-host:8477 --token <token> --yes
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Update an existing npm-installed client:
|
|
33
35
|
|
|
34
36
|
```text
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
tmlbrain update
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`tmlbrain update` runs `npm install -g @time-machine-lab/tmlbrain@latest`,
|
|
41
|
+
refreshes the local Skill/runtime, and preserves the existing server URL and
|
|
42
|
+
token. Use `tmlbrain update 0.1.1` to update to a specific version.
|
|
43
|
+
|
|
44
|
+
Optional one-time npx install without keeping a global command:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
npx -y @time-machine-lab/tmlbrain@latest client install
|
|
37
48
|
```
|
|
38
49
|
|
|
39
50
|
## Server
|
|
@@ -45,9 +56,9 @@ skeleton.
|
|
|
45
56
|
|
|
46
57
|
```text
|
|
47
58
|
docker run -d --name tmlbrain-server \
|
|
48
|
-
-p
|
|
59
|
+
-p 8477:8477 \
|
|
49
60
|
-e TMLBRAIN_SERVER_TOKEN=<required-token> \
|
|
50
|
-
-e TMLBRAIN_KNOWLEDGE_REPO=https://github.com/Time-Machine-Lab/
|
|
61
|
+
-e TMLBRAIN_KNOWLEDGE_REPO=https://github.com/Time-Machine-Lab/Knowledge.git \
|
|
51
62
|
-e TMLBRAIN_KNOWLEDGE_REF=main \
|
|
52
63
|
-v tmlbrain-data:/data \
|
|
53
64
|
<DOCKER_REPO>:latest
|
|
@@ -72,7 +83,7 @@ The Docker image does not contain real team knowledge. Real knowledge should be
|
|
|
72
83
|
stored in a separate private repository, for example:
|
|
73
84
|
|
|
74
85
|
```text
|
|
75
|
-
https://github.com/Time-Machine-Lab/
|
|
86
|
+
https://github.com/Time-Machine-Lab/Knowledge.git
|
|
76
87
|
```
|
|
77
88
|
|
|
78
89
|
That repository must contain the TMLBrain `knowledge/` directory at its root.
|
|
@@ -89,7 +100,11 @@ repository configured in GitHub Actions secret `DOCKER_REPO`. The npm client
|
|
|
89
100
|
package is published by the same workflow with the `NPM_TOKEN` repository
|
|
90
101
|
secret. The workflow then logs in to the target server with
|
|
91
102
|
`SERVER_HOST`, `SERVER_USER`, and `SERVER_PWD`, pulls the new image, and
|
|
92
|
-
restarts the `tmlbrain-server` container.
|
|
103
|
+
restarts the `tmlbrain-server` container. Server-side Docker login is skipped
|
|
104
|
+
by default because the runtime image is expected to be public; only the GitHub
|
|
105
|
+
Actions runner needs Docker credentials to push the image. For a private image,
|
|
106
|
+
set `TMLBRAIN_SERVER_DOCKER_LOGIN=true` and provide
|
|
107
|
+
`TMLBRAIN_SERVER_DOCKER_USERNAME` plus `TMLBRAIN_SERVER_DOCKER_PASSWORD`.
|
|
93
108
|
|
|
94
109
|
```text
|
|
95
110
|
<DOCKER_REPO>:latest
|
|
@@ -119,7 +134,7 @@ TMLBRAIN_KNOWLEDGE_REF
|
|
|
119
134
|
```
|
|
120
135
|
|
|
121
136
|
`TMLBRAIN_KNOWLEDGE_REPO` must be an HTTPS URL, for example
|
|
122
|
-
`https://github.com/Time-Machine-Lab/
|
|
137
|
+
`https://github.com/Time-Machine-Lab/Knowledge.git`.
|
|
123
138
|
`TMLBRAIN_KNOWLEDGE_TOKEN` must be a GitHub token with write access to that
|
|
124
139
|
dedicated knowledge repository. Fine-grained tokens are preferred; classic
|
|
125
140
|
tokens also work when they have the right repository scope: use `repo` for
|
|
@@ -127,6 +142,20 @@ private repositories, or `public_repo` only for public repositories. This
|
|
|
127
142
|
credential belongs to the server runtime, not to clients and not to the Docker
|
|
128
143
|
image.
|
|
129
144
|
|
|
145
|
+
Optional GitHub connectivity secret:
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
TMLBRAIN_SERVER_GIT_PROXY_URL
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Use this only when the deployment server cannot reach GitHub directly. The
|
|
152
|
+
workflow applies the proxy to Git operations for `https://github.com` only. If
|
|
153
|
+
the secret is absent but a `tmlbrain-proxy` container is running on the server,
|
|
154
|
+
deployment connects the TMLBrain server container to that proxy automatically.
|
|
155
|
+
Before replacing the running server, the workflow validates
|
|
156
|
+
`TMLBRAIN_KNOWLEDGE_REPO` plus `TMLBRAIN_KNOWLEDGE_TOKEN` with Git so a broken
|
|
157
|
+
token does not create a bad deployment.
|
|
158
|
+
|
|
130
159
|
## Release Command Format
|
|
131
160
|
|
|
132
161
|
Releases are driven by the HEAD commit message on `main`. The workflow skips
|
|
@@ -135,7 +164,7 @@ commits that do not contain `<Auto>`.
|
|
|
135
164
|
Example:
|
|
136
165
|
|
|
137
166
|
```text
|
|
138
|
-
[tml-brain]<Auto> release server and client -v:0.1.0 -rp:
|
|
167
|
+
[tml-brain]<Auto> release server and client -v:0.1.0 -rp:8477 -de:<-e KEY=value>
|
|
139
168
|
```
|
|
140
169
|
|
|
141
170
|
Fields:
|
|
@@ -143,7 +172,7 @@ Fields:
|
|
|
143
172
|
- `<Auto>` is required to trigger publishing.
|
|
144
173
|
- `-v:<semver>` is required and is used for both npm and Docker versions. Use a
|
|
145
174
|
Docker-compatible value such as `0.1.0` or `0.1.0-beta.1`.
|
|
146
|
-
- `-rp:<port>` is optional and defaults to `
|
|
175
|
+
- `-rp:<port>` is optional and defaults to `8477`; it becomes the Docker image
|
|
147
176
|
default `TMLBRAIN_PORT`.
|
|
148
177
|
- `-de:<...>` is optional single-line Docker runtime metadata, such as
|
|
149
178
|
additional `docker run -e` arguments. It stays in the commit message and is
|
package/docs/runtime.md
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
TMLBrain should feel like one product to the user:
|
|
6
6
|
|
|
7
7
|
```text
|
|
8
|
-
|
|
8
|
+
npm install -g @time-machine-lab/tmlbrain@latest
|
|
9
|
+
tmlbrain client install
|
|
9
10
|
@TMLBrain search or update knowledge
|
|
10
11
|
```
|
|
11
12
|
|
|
@@ -21,7 +22,7 @@ The core runtime must work without Python:
|
|
|
21
22
|
- Local workspace state under `.tmlbrain/`.
|
|
22
23
|
- Exact search.
|
|
23
24
|
- Markdown validation.
|
|
24
|
-
- Document creation.
|
|
25
|
+
- Document creation with taxonomy-based placement.
|
|
25
26
|
- Server API write requests.
|
|
26
27
|
- Read-only snapshot sync.
|
|
27
28
|
|
|
@@ -34,16 +35,22 @@ CocoIndex and LightRAG are optional graph retrieval features. They are enabled b
|
|
|
34
35
|
|
|
35
36
|
```text
|
|
36
37
|
tmlbrain graph setup
|
|
38
|
+
tmlbrain graph index
|
|
39
|
+
tmlbrain graph query "question"
|
|
37
40
|
```
|
|
38
41
|
|
|
39
|
-
If Python
|
|
42
|
+
If Python cannot be activated, core TMLBrain remains usable in degraded search
|
|
43
|
+
mode. If Python is available but CocoIndex or LightRAG packages are missing,
|
|
44
|
+
the graph commands use compatible local adapters and report degraded status
|
|
45
|
+
instead of blocking exact search or deterministic indexing.
|
|
40
46
|
|
|
41
47
|
## Installer Entry Points
|
|
42
48
|
|
|
43
49
|
Recommended npm client entry:
|
|
44
50
|
|
|
45
51
|
```text
|
|
46
|
-
|
|
52
|
+
npm install -g @time-machine-lab/tmlbrain@latest
|
|
53
|
+
tmlbrain client install
|
|
47
54
|
```
|
|
48
55
|
|
|
49
56
|
The client installer asks for a server URL. Leaving it empty starts local-only
|
|
@@ -66,7 +73,8 @@ Both scripts call the same CLI bootstrap flow and keep the user away from raw Gi
|
|
|
66
73
|
Non-interactive client install:
|
|
67
74
|
|
|
68
75
|
```text
|
|
69
|
-
|
|
76
|
+
npm install -g @time-machine-lab/tmlbrain@latest
|
|
77
|
+
tmlbrain client install --server http://server-host:8477 --token secret --yes
|
|
70
78
|
```
|
|
71
79
|
|
|
72
80
|
## Server Runtime
|
|
@@ -74,7 +82,7 @@ npx @time-machine-lab/tmlbrain client install --server http://server-host:7389 -
|
|
|
74
82
|
Run with Docker:
|
|
75
83
|
|
|
76
84
|
```text
|
|
77
|
-
docker run -d --name tmlbrain-server -p
|
|
85
|
+
docker run -d --name tmlbrain-server -p 8477:8477 -e TMLBRAIN_SERVER_TOKEN=secret -e TMLBRAIN_KNOWLEDGE_REPO=https://github.com/Time-Machine-Lab/Knowledge.git -v tmlbrain-data:/data <DOCKER_REPO>:latest
|
|
78
86
|
```
|
|
79
87
|
|
|
80
88
|
The image contains tooling and templates only. Real knowledge is restored from
|
|
@@ -86,10 +94,19 @@ port with `-e TMLBRAIN_PORT=<port>` and the corresponding Docker `-p` mapping.
|
|
|
86
94
|
Manual development mode from the server worktree:
|
|
87
95
|
|
|
88
96
|
```text
|
|
89
|
-
node bin/tmlbrain.js serve --host 0.0.0.0 --port
|
|
97
|
+
node bin/tmlbrain.js serve --host 0.0.0.0 --port 8477
|
|
90
98
|
```
|
|
91
99
|
|
|
92
100
|
Only the server runtime should mutate Markdown, commit repository changes, or
|
|
93
101
|
push to the dedicated knowledge repository. Clients should use `tmlbrain sync
|
|
94
|
-
--pull` for snapshots, `tmlbrain find` for local search, and `tmlbrain save
|
|
95
|
-
`tmlbrain remote update` for write
|
|
102
|
+
--pull` for snapshots, `tmlbrain find` for local search, and `tmlbrain save`,
|
|
103
|
+
`tmlbrain remote update`, or explicit `tmlbrain remote delete` for write
|
|
104
|
+
requests. Normal `tmlbrain save` requests classify content into the knowledge
|
|
105
|
+
taxonomy; `00-inbox` is reserved for genuinely unclear or explicitly temporary
|
|
106
|
+
capture. Deletion is reserved for explicit user intent; otherwise prefer
|
|
107
|
+
marking content stale.
|
|
108
|
+
|
|
109
|
+
Server writes attempt GitHub backup immediately after an accepted commit. A
|
|
110
|
+
scheduled fallback can be enabled in Docker with
|
|
111
|
+
`TMLBRAIN_BACKUP_INTERVAL_SECONDS`; systemd timer templates are available under
|
|
112
|
+
`scripts/backup/` for non-Docker deployments.
|
package/docs/server-api.md
CHANGED
|
@@ -5,7 +5,15 @@ TMLBrain uses a server-owned write boundary.
|
|
|
5
5
|
Clients keep a read-only local snapshot for search and indexing. Clients request
|
|
6
6
|
knowledge mutations through the TMLBrain server API. The server mutates
|
|
7
7
|
Markdown, validates the knowledge base, commits the repository change, and then
|
|
8
|
-
pushes from the server worktree to the server bare repository.
|
|
8
|
+
pushes from the server worktree to the server bare repository. After a
|
|
9
|
+
successful write commit, the server also attempts to push the same commit to
|
|
10
|
+
the configured `backup` remote so the dedicated GitHub knowledge repository
|
|
11
|
+
stays current.
|
|
12
|
+
|
|
13
|
+
For new knowledge, archive/store/save/record requests are treated as the same
|
|
14
|
+
save operation. The client and server classify the document into the approved
|
|
15
|
+
taxonomy by default; `00-inbox` is reserved for genuinely unclear or explicitly
|
|
16
|
+
temporary capture.
|
|
9
17
|
|
|
10
18
|
## Run The Server
|
|
11
19
|
|
|
@@ -13,9 +21,9 @@ Recommended Docker deployment:
|
|
|
13
21
|
|
|
14
22
|
```text
|
|
15
23
|
docker run -d --name tmlbrain-server \
|
|
16
|
-
-p
|
|
24
|
+
-p 8477:8477 \
|
|
17
25
|
-e TMLBRAIN_SERVER_TOKEN=secret \
|
|
18
|
-
-e TMLBRAIN_KNOWLEDGE_REPO=https://github.com/Time-Machine-Lab/
|
|
26
|
+
-e TMLBRAIN_KNOWLEDGE_REPO=https://github.com/Time-Machine-Lab/Knowledge.git \
|
|
19
27
|
-v tmlbrain-data:/data \
|
|
20
28
|
<DOCKER_REPO>:latest
|
|
21
29
|
```
|
|
@@ -24,22 +32,29 @@ docker run -d --name tmlbrain-server \
|
|
|
24
32
|
data volume already contains `/data/worktree`, the container reuses that
|
|
25
33
|
worktree instead of cloning again.
|
|
26
34
|
|
|
35
|
+
For private GitHub knowledge repositories, deploy the server with
|
|
36
|
+
`TMLBRAIN_KNOWLEDGE_TOKEN` as a runtime secret. If the server cannot reach
|
|
37
|
+
GitHub directly, deployment may set `TMLBRAIN_SERVER_GIT_PROXY_URL` or reuse an
|
|
38
|
+
existing `tmlbrain-proxy` container; that proxy is applied only to GitHub Git
|
|
39
|
+
traffic.
|
|
40
|
+
|
|
27
41
|
Run from the server worktree:
|
|
28
42
|
|
|
29
43
|
```text
|
|
30
|
-
node bin/tmlbrain.js serve --host 0.0.0.0 --port
|
|
44
|
+
node bin/tmlbrain.js serve --host 0.0.0.0 --port 8477
|
|
31
45
|
```
|
|
32
46
|
|
|
33
47
|
Optional token protection:
|
|
34
48
|
|
|
35
49
|
```text
|
|
36
|
-
TMLBRAIN_SERVER_TOKEN=secret node bin/tmlbrain.js serve --host 0.0.0.0 --port
|
|
50
|
+
TMLBRAIN_SERVER_TOKEN=secret node bin/tmlbrain.js serve --host 0.0.0.0 --port 8477
|
|
37
51
|
```
|
|
38
52
|
|
|
39
53
|
Clients then install with:
|
|
40
54
|
|
|
41
55
|
```text
|
|
42
|
-
|
|
56
|
+
npm install -g @time-machine-lab/tmlbrain@latest
|
|
57
|
+
tmlbrain client install --server http://server-host:8477 --token secret --yes
|
|
43
58
|
```
|
|
44
59
|
|
|
45
60
|
The client stores this in `.tmlbrain/state.json`. The token is not shown by
|
|
@@ -54,19 +69,19 @@ node bin/tmlbrain.js config show
|
|
|
54
69
|
Switch a client to a different server:
|
|
55
70
|
|
|
56
71
|
```text
|
|
57
|
-
node bin/tmlbrain.js config set-server http://new-server-host:
|
|
72
|
+
node bin/tmlbrain.js config set-server http://new-server-host:8477 --token secret
|
|
58
73
|
node bin/tmlbrain.js sync --pull
|
|
59
74
|
```
|
|
60
75
|
|
|
61
76
|
`--server` and `--token` can also be passed to one command for temporary
|
|
62
77
|
overrides.
|
|
63
78
|
|
|
64
|
-
If the cloud security group does not expose port `
|
|
79
|
+
If the cloud security group does not expose port `8477`, keep the API private
|
|
65
80
|
and use a tunnel from the client machine:
|
|
66
81
|
|
|
67
82
|
```text
|
|
68
|
-
ssh -N -L
|
|
69
|
-
|
|
83
|
+
ssh -N -L 8478:127.0.0.1:8477 tmlbrain-1007
|
|
84
|
+
tmlbrain client install --server http://127.0.0.1:8478 --token secret --yes
|
|
70
85
|
```
|
|
71
86
|
|
|
72
87
|
## Client Commands
|
|
@@ -101,19 +116,53 @@ Ask the server to update a precise text region:
|
|
|
101
116
|
node bin/tmlbrain.js remote update --file knowledge/00-inbox/note.md --replace "old text" --with "new text"
|
|
102
117
|
```
|
|
103
118
|
|
|
119
|
+
Ask the server to delete a knowledge document only after the user explicitly
|
|
120
|
+
requests deletion:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
node bin/tmlbrain.js remote delete --file knowledge/30-resources/old-note.md
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Normal client updates automatically include the last synced file hash as
|
|
127
|
+
`expectedSha256` when the local snapshot has one. If the server document has
|
|
128
|
+
changed, the server returns a structured `409` conflict containing the current
|
|
129
|
+
hash, relevant current text, rejected intent, reason, and suggested next
|
|
130
|
+
actions. Delete requests use the same stale-file protection when the local
|
|
131
|
+
snapshot has a file hash. The CLI turns that response into a local TMLBrain
|
|
132
|
+
conflict package and refreshes the snapshot when possible.
|
|
133
|
+
|
|
104
134
|
## API Endpoints
|
|
105
135
|
|
|
106
136
|
- `GET /health`: server health and current head.
|
|
107
137
|
- `GET /capabilities`: machine-readable command and boundary description.
|
|
108
138
|
- `GET /snapshot`: read-only Markdown snapshot for clients.
|
|
109
|
-
- `POST /knowledge/add`: server-side add, validate, commit, and
|
|
110
|
-
- `POST /knowledge/update`: server-side replace or content-file update, validate, commit, and
|
|
139
|
+
- `POST /knowledge/add`: server-side classified add, validate, commit, push to local server repository, and attempt GitHub backup.
|
|
140
|
+
- `POST /knowledge/update`: server-side replace or content-file update, validate, commit, push to local server repository, and attempt GitHub backup.
|
|
141
|
+
- `POST /knowledge/delete`: server-side Markdown document delete, validate, commit, push to local server repository, and attempt GitHub backup.
|
|
142
|
+
|
|
143
|
+
Structured update conflicts return:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"ok": false,
|
|
148
|
+
"error": "Expected sha256 ...",
|
|
149
|
+
"conflict": {
|
|
150
|
+
"path": "knowledge/...",
|
|
151
|
+
"reason": "expected-sha256-mismatch",
|
|
152
|
+
"currentSha256": "...",
|
|
153
|
+
"expectedSha256": "...",
|
|
154
|
+
"currentRelevantText": "...",
|
|
155
|
+
"rejectedIntent": {},
|
|
156
|
+
"suggestedNextActions": []
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
111
160
|
|
|
112
161
|
## Boundary
|
|
113
162
|
|
|
114
163
|
Clients MUST NOT push to the server Git repository or dedicated knowledge
|
|
115
164
|
repository. Backing up to that repository remains a server-side operation
|
|
116
|
-
through `tmlbrain backup`.
|
|
165
|
+
through write-time backup and `tmlbrain backup`.
|
|
117
166
|
|
|
118
167
|
HTTP-only clients do not need Git installed. The server runtime still needs Git
|
|
119
168
|
because it validates, commits, pushes to the server bare repository, and runs
|
package/docs/sync.md
CHANGED
|
@@ -14,8 +14,14 @@ Users ask TMLBrain to write knowledge through the server:
|
|
|
14
14
|
tmlbrain save --title "Title" --content "Content"
|
|
15
15
|
tmlbrain save ./note.md
|
|
16
16
|
tmlbrain remote update --file knowledge/00-inbox/note.md --replace "old" --with "new"
|
|
17
|
+
tmlbrain remote delete --file knowledge/30-resources/old-note.md
|
|
17
18
|
```
|
|
18
19
|
|
|
20
|
+
Archive, store, save, and record are equivalent user intents for adding content
|
|
21
|
+
to the knowledge base. Save requests classify content into the approved
|
|
22
|
+
taxonomy by default. `00-inbox` is only used when the correct long-term folder
|
|
23
|
+
is genuinely unclear or explicitly requested.
|
|
24
|
+
|
|
19
25
|
They should not need to run `git pull`, `git push`, `git merge`, or `git rebase`.
|
|
20
26
|
Clients also should not perform hidden Git writes to the server. In the
|
|
21
27
|
HTTP-only workflow, clients do not need Git installed.
|
|
@@ -35,9 +41,14 @@ client write request
|
|
|
35
41
|
-> server validation
|
|
36
42
|
-> server Git commit
|
|
37
43
|
-> server bare repository
|
|
38
|
-
-> dedicated knowledge repository backup
|
|
44
|
+
-> dedicated knowledge repository backup attempt
|
|
39
45
|
```
|
|
40
46
|
|
|
47
|
+
`tmlbrain remote delete` is a server-owned write request too. Clients only send
|
|
48
|
+
the explicit delete intent; the server performs the file removal, validates the
|
|
49
|
+
remaining knowledge base, commits the change, pushes the server repository, and
|
|
50
|
+
attempts the dedicated GitHub backup.
|
|
51
|
+
|
|
41
52
|
## Conflict Handling
|
|
42
53
|
|
|
43
54
|
When the server cannot apply a requested update safely, it rejects the request
|
|
@@ -45,10 +56,19 @@ instead of silently overwriting remote knowledge. For precise text replacement,
|
|
|
45
56
|
the server requires the replacement text to match exactly once unless a broader
|
|
46
57
|
operation is explicitly requested.
|
|
47
58
|
|
|
59
|
+
For normal `tmlbrain remote update` requests, the client reads the last synced
|
|
60
|
+
file hash from `.tmlbrain/state.json` and sends it as `expectedSha256`. If the
|
|
61
|
+
server file has changed, or if replacement text is missing or ambiguous, the
|
|
62
|
+
server returns a structured `409` response with the current hash, relevant
|
|
63
|
+
server text, rejected intent, reason, and suggested next action.
|
|
64
|
+
|
|
48
65
|
When future merge flows need human review, TMLBrain should create conflict
|
|
49
66
|
packages under `.tmlbrain/conflicts/` instead of dropping the user into raw Git
|
|
50
67
|
conflict markers.
|
|
51
68
|
|
|
69
|
+
The CLI now creates those packages for API `409` responses and refreshes the
|
|
70
|
+
local snapshot when possible.
|
|
71
|
+
|
|
52
72
|
Conflict packages contain:
|
|
53
73
|
|
|
54
74
|
- conflict id;
|
|
@@ -72,8 +92,8 @@ Recommended MVP server layout:
|
|
|
72
92
|
|
|
73
93
|
The server API should run from `/srv/tmlbrain-worktree`. After an accepted
|
|
74
94
|
write request, the server commits in the worktree and pushes to
|
|
75
|
-
`/srv/tmlbrain.git
|
|
76
|
-
|
|
95
|
+
`/srv/tmlbrain.git`, then attempts to push the accepted commit to the
|
|
96
|
+
dedicated knowledge repository backup remote.
|
|
77
97
|
|
|
78
98
|
Recommended Docker server layout:
|
|
79
99
|
|
|
@@ -102,7 +122,7 @@ Use:
|
|
|
102
122
|
|
|
103
123
|
```text
|
|
104
124
|
tmlbrain config show
|
|
105
|
-
tmlbrain config set-server http://server-host:
|
|
125
|
+
tmlbrain config set-server http://server-host:8477 --token <token>
|
|
106
126
|
tmlbrain sync --pull
|
|
107
127
|
```
|
|
108
128
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@time-machine-lab/tmlbrain",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "TMLBrain local-first team knowledge base tooling.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
"tmlbrain": "node bin/tmlbrain.js",
|
|
20
20
|
"validate": "node bin/tmlbrain.js validate",
|
|
21
21
|
"index": "node bin/tmlbrain.js index",
|
|
22
|
+
"graph:index": "node bin/tmlbrain.js graph index --json",
|
|
23
|
+
"graph:query": "node bin/tmlbrain.js graph query \"knowledge\" --json",
|
|
22
24
|
"test": "node bin/tmlbrain.js validate && node bin/tmlbrain.js index --json"
|
|
23
25
|
},
|
|
24
26
|
"engines": {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
INTERVAL="${TMLBRAIN_BACKUP_INTERVAL_SECONDS:-0}"
|
|
5
|
+
REMOTE="${TMLBRAIN_BACKUP_REMOTE:-backup}"
|
|
6
|
+
WORKTREE="${TMLBRAIN_WORKTREE:-${TMLBRAIN_DATA_DIR:-/data}/worktree}"
|
|
7
|
+
APP_DIR="${TMLBRAIN_APP_DIR:-/app}"
|
|
8
|
+
|
|
9
|
+
case "$INTERVAL" in
|
|
10
|
+
''|*[!0-9]*)
|
|
11
|
+
echo "TMLBRAIN_BACKUP_INTERVAL_SECONDS must be a positive integer." >&2
|
|
12
|
+
exit 2
|
|
13
|
+
;;
|
|
14
|
+
esac
|
|
15
|
+
|
|
16
|
+
if [ "$INTERVAL" -le 0 ]; then
|
|
17
|
+
echo "TMLBrain scheduled backup disabled."
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
while :; do
|
|
22
|
+
sleep "$INTERVAL"
|
|
23
|
+
if [ ! -d "$WORKTREE/.git" ]; then
|
|
24
|
+
echo "TMLBrain scheduled backup skipped: $WORKTREE is not a Git worktree." >&2
|
|
25
|
+
continue
|
|
26
|
+
fi
|
|
27
|
+
echo "Running scheduled TMLBrain backup to $REMOTE."
|
|
28
|
+
(
|
|
29
|
+
cd "$WORKTREE"
|
|
30
|
+
node "$APP_DIR/bin/tmlbrain.js" backup --remote "$REMOTE"
|
|
31
|
+
) || echo "Scheduled TMLBrain backup failed." >&2
|
|
32
|
+
done
|