@ddtcorex/dsh-maestro-memory 1.0.1
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/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +448 -0
- package/cordis.patch.yml +13 -0
- package/lib/client.js +756 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +627 -0
- package/lib/index.js.map +1 -0
- package/lib/memory/batch.d.ts +44 -0
- package/lib/memory/batch.d.ts.map +1 -0
- package/lib/memory/batch.js +75 -0
- package/lib/memory/batch.js.map +1 -0
- package/lib/memory/feedback.d.ts +18 -0
- package/lib/memory/feedback.d.ts.map +1 -0
- package/lib/memory/feedback.js +29 -0
- package/lib/memory/feedback.js.map +1 -0
- package/lib/memory/store.d.ts +154 -0
- package/lib/memory/store.d.ts.map +1 -0
- package/lib/memory/store.js +606 -0
- package/lib/memory/store.js.map +1 -0
- package/lib/migration/cli.d.ts +18 -0
- package/lib/migration/cli.d.ts.map +1 -0
- package/lib/migration/cli.js +143 -0
- package/lib/migration/cli.js.map +1 -0
- package/lib/migration/fixture.d.ts +45 -0
- package/lib/migration/fixture.d.ts.map +1 -0
- package/lib/migration/fixture.js +177 -0
- package/lib/migration/fixture.js.map +1 -0
- package/lib/migration/service.d.ts +75 -0
- package/lib/migration/service.d.ts.map +1 -0
- package/lib/migration/service.js +713 -0
- package/lib/migration/service.js.map +1 -0
- package/lib/prompt/snapshot.d.ts +26 -0
- package/lib/prompt/snapshot.d.ts.map +1 -0
- package/lib/prompt/snapshot.js +74 -0
- package/lib/prompt/snapshot.js.map +1 -0
- package/lib/review/queue.d.ts +72 -0
- package/lib/review/queue.d.ts.map +1 -0
- package/lib/review/queue.js +306 -0
- package/lib/review/queue.js.map +1 -0
- package/lib/skills-browser.d.ts +67 -0
- package/lib/skills-browser.d.ts.map +1 -0
- package/lib/skills-browser.js +185 -0
- package/lib/skills-browser.js.map +1 -0
- package/lib/storage/atomic-store.d.ts +211 -0
- package/lib/storage/atomic-store.d.ts.map +1 -0
- package/lib/storage/atomic-store.js +582 -0
- package/lib/storage/atomic-store.js.map +1 -0
- package/lib/storage/layout.d.ts +81 -0
- package/lib/storage/layout.d.ts.map +1 -0
- package/lib/storage/layout.js +162 -0
- package/lib/storage/layout.js.map +1 -0
- package/lib/storage/legacy-format.d.ts +104 -0
- package/lib/storage/legacy-format.d.ts.map +1 -0
- package/lib/storage/legacy-format.js +262 -0
- package/lib/storage/legacy-format.js.map +1 -0
- package/lib/sync/config.d.ts +22 -0
- package/lib/sync/config.d.ts.map +1 -0
- package/lib/sync/config.js +57 -0
- package/lib/sync/config.js.map +1 -0
- package/lib/sync/git.d.ts +97 -0
- package/lib/sync/git.d.ts.map +1 -0
- package/lib/sync/git.js +282 -0
- package/lib/sync/git.js.map +1 -0
- package/lib/sync/index.d.ts +6 -0
- package/lib/sync/index.d.ts.map +1 -0
- package/lib/sync/index.js +6 -0
- package/lib/sync/index.js.map +1 -0
- package/lib/sync/layout.d.ts +15 -0
- package/lib/sync/layout.d.ts.map +1 -0
- package/lib/sync/layout.js +33 -0
- package/lib/sync/layout.js.map +1 -0
- package/lib/sync/merge.d.ts +42 -0
- package/lib/sync/merge.d.ts.map +1 -0
- package/lib/sync/merge.js +159 -0
- package/lib/sync/merge.js.map +1 -0
- package/lib/sync/service.d.ts +70 -0
- package/lib/sync/service.d.ts.map +1 -0
- package/lib/sync/service.js +508 -0
- package/lib/sync/service.js.map +1 -0
- package/lib/todo/store.d.ts +142 -0
- package/lib/todo/store.d.ts.map +1 -0
- package/lib/todo/store.js +452 -0
- package/lib/todo/store.js.map +1 -0
- package/lib/types/client/index.d.ts +7 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/package.json +63 -0
- package/src/client/index.tsx +994 -0
- package/src/host/index.ts +591 -0
- package/src/host/memory/batch.ts +107 -0
- package/src/host/memory/feedback.ts +36 -0
- package/src/host/memory/store.ts +650 -0
- package/src/host/migration/cli.ts +139 -0
- package/src/host/migration/fixture.ts +218 -0
- package/src/host/migration/service.ts +786 -0
- package/src/host/prompt/snapshot.ts +95 -0
- package/src/host/review/queue.ts +325 -0
- package/src/host/skills-browser.ts +191 -0
- package/src/host/storage/atomic-store.ts +605 -0
- package/src/host/storage/layout.ts +191 -0
- package/src/host/storage/legacy-format.ts +308 -0
- package/src/host/sync/config.ts +67 -0
- package/src/host/sync/git.ts +280 -0
- package/src/host/sync/index.ts +5 -0
- package/src/host/sync/layout.ts +39 -0
- package/src/host/sync/merge.ts +188 -0
- package/src/host/sync/service.ts +494 -0
- package/src/host/todo/store.ts +480 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file. Format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [1.0.1] - 2026-08-25
|
|
8
|
+
|
|
9
|
+
Fix a live gap in the `memory` tool: the `daily` track only honored an explicit
|
|
10
|
+
`date` for `add`/`list`, so an entry on an older day could never be removed or
|
|
11
|
+
edited through the tool (it always targeted today's file). Verified on a real
|
|
12
|
+
session after restart.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **`date` now applies to `remove`/`replace` on the `daily` track.** The store
|
|
17
|
+
methods accept an optional `{ date }` and thread it through
|
|
18
|
+
`fileFor(target, cwd, date)`, and the host tool `execute` + `memory.mutate`
|
|
19
|
+
RPC pass it through. A non-`YYYY-MM-DD` value returns an error via the
|
|
20
|
+
existing `dailyPath` → `assertDate` guard.
|
|
21
|
+
- Updated the `date` schema description to cover add/list/replace/remove.
|
|
22
|
+
|
|
23
|
+
### Notes
|
|
24
|
+
|
|
25
|
+
- TDD regression tests added in `tests/memory-m2.spec.ts`; full suite 202 pass,
|
|
26
|
+
`pnpm run build` / `pnpm run verify` green.
|
|
27
|
+
|
|
28
|
+
## [1.0.0] - 2026-08-24
|
|
29
|
+
|
|
30
|
+
Initial release of `@ddtcorex/dsh-maestro-memory`, a from-scratch TypeScript
|
|
31
|
+
rebrand of `dsh-memory-evolve` that runs as a DeepSeek Harness plugin and
|
|
32
|
+
preserves the existing `~/.dsh/memories` files in place.
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- **Memory tool (`memory`)** across five durable tracks: global `memory`,
|
|
37
|
+
`user`, per-project `key` / `project`, and date-stamped `daily`. Entries are
|
|
38
|
+
stored verbatim in the same `§`-delimited layout as the legacy files; archived
|
|
39
|
+
entries split to `*-archive.md`.
|
|
40
|
+
- **Todos tool (`dtodo`)** across `life` / `work` / `project` / `daily` with a
|
|
41
|
+
bounded 8-item smart view, category and quadrant fields, and a per-day
|
|
42
|
+
`YYYY-MM-DD.todo.md` file.
|
|
43
|
+
- **`memory_suggest` tool** (confirmation-gated): proposals are queued in
|
|
44
|
+
`SUGGESTIONS.jsonl` and only written to memory after explicit user approval.
|
|
45
|
+
- **`memory:snapshot` system-prompt context** at configurable `snapshotOrder`
|
|
46
|
+
(default 500): injects session-id header, global + current-project `KEY`,
|
|
47
|
+
the end-of-turn daily/project write discipline, and the todos reminder.
|
|
48
|
+
- **In-place adoption migration** (`scripts/migrate.mjs`, RPC
|
|
49
|
+
`migration.*`): read-only `inspect` → `--apply` backs up a SHA-256 manifest
|
|
50
|
+
and adopts `schema.json`; `--verify` compares digests and blocks writes on
|
|
51
|
+
drift via `write-block.json`; `rollback(root, runId)` restores byte-identical
|
|
52
|
+
files.
|
|
53
|
+
- **Confirmation-gated review queue** (`queue.*`): review decisions are queued
|
|
54
|
+
and applied via an explicit, user-facing decision flow; the review tool is
|
|
55
|
+
registered dynamically and only when the runtime switch is on.
|
|
56
|
+
- **Read-first skills browser** (`skills.list`, host `skills-browser`):
|
|
57
|
+
metadata/origin-only listing of the default maestro-skills checkout, no
|
|
58
|
+
mutation and no body content.
|
|
59
|
+
- **Web UI** in a single `conversation.view` slot (`id: maestro-memory`,
|
|
60
|
+
order 40) with Memory / Review / Todos / Skills tabs, DSH-themed controls, and
|
|
61
|
+
package-private RPC over `/dsh-maestro-memory`.
|
|
62
|
+
- **M5 Git sync** (opt-in): project-scoped `sync.enable/disable/status/fetch/
|
|
63
|
+
push/pull/resolve/listConflicts`. Disabled means zero network activity; pushes
|
|
64
|
+
are explicit and a conflict never silently drops either version.
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- Hard-coded light-then-dark theme styles replaced with `--dsw-alias-*` tokens
|
|
69
|
+
(the active-tab highlight uses `--dsw-alias-interactive-bg-active`, which
|
|
70
|
+
flips correctly on both themes).
|
|
71
|
+
- Track/navigation controls made visually distinct and height-consistent so
|
|
72
|
+
switching between memory tracks never reflows the toolbar.
|
|
73
|
+
- The memory tool's `date` parameter is now honored for the `daily` track
|
|
74
|
+
(previously declared but unused) with an invalid-date guard.
|
|
75
|
+
- Key-track entries always carry an id even without a summary, so
|
|
76
|
+
`expand(id)` targets any key entry.
|
|
77
|
+
- Daily memory stamps the local calendar date (matching the todos store) instead
|
|
78
|
+
of UTC, so daily logs land on the same day.
|
|
79
|
+
- `skills.list` no longer reads an arbitrary client-supplied directory; it is
|
|
80
|
+
constrained to the resolved default maestro-skills checkout.
|
|
81
|
+
|
|
82
|
+
### Removed
|
|
83
|
+
|
|
84
|
+
- All legacy `dsh-memory-evolve` features not carried into the rebrand: COI /
|
|
85
|
+
broadcast, advisor, notify/`de_channel_send`, search, prompt library, model
|
|
86
|
+
registry, bookmarks/mermaid/canvas, and the old `/memory-evolve` HTTP server.
|
|
87
|
+
|
|
88
|
+
### Notes
|
|
89
|
+
|
|
90
|
+
- The package is consumed as a DSH plugin via `cordis.patch.yml`
|
|
91
|
+
(`id: maestro-memory`) and is installed with a `link:` dependency or the
|
|
92
|
+
`github:ddtcorex/dsh-maestro-memory#<sha>` form. Live `lib/` is committed so a
|
|
93
|
+
rebuild is only needed after editing `src/`.
|
|
94
|
+
|
|
95
|
+
[1.0.0]: https://github.com/ddtcorex/dsh-maestro-memory/releases/tag/v1.0.0
|
|
96
|
+
[1.0.1]: https://github.com/ddtcorex/dsh-maestro-memory/releases/tag/v1.0.1
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-external
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
# dsh-maestro-memory
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Durable, user-governed memory and todos for DeepSeek Harness (DSH) that preserves your existing `~/.dsh/memories` files in place.
|
|
6
|
+
|
|
7
|
+
> **One sentence:** Give the AI in DSH cross-session durable memory and todos — the more you use it, the more it understands you, and switching sessions never loses context.
|
|
8
|
+
|
|
9
|
+
- **Package:** `@ddtcorex/dsh-maestro-memory` (`cordis.patch.yml` id `maestro-memory`)
|
|
10
|
+
- **Changelog:** `CHANGELOG.md`
|
|
11
|
+
- **Version:** `1.0.1`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- Node.js 22+, pnpm 11+
|
|
18
|
+
- DSH `deepseek-harness` master (for `cordis`, `dsh-client-*` peers)
|
|
19
|
+
- Existing `~/.dsh/memories` directory (created lazily if absent)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
From the checked-out repo:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pnpm install # install deps (frozen lockfile in CI)
|
|
29
|
+
pnpm run build # tsc host + tsc client + build-client.mjs -> lib/
|
|
30
|
+
pnpm run verify # tsc --noEmit host + client (typecheck)
|
|
31
|
+
pnpm test # full Vitest suite (13 files, 199 tests)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Manual verification of the client bundle:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
test -f lib/client.js && head -n 2 lib/client.js | grep -q "ModuleLoader" && echo "bundle ok"
|
|
38
|
+
ls -lh lib/client.js lib/index.js
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### From a DSH profile (operator)
|
|
42
|
+
|
|
43
|
+
The package is consumed as a DSH plugin via `cordis.patch.yml`. Two install paths:
|
|
44
|
+
|
|
45
|
+
**Local link (development / recommended for cutover rehearsal):**
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
# inside the profile that will own the plugin:
|
|
49
|
+
dsh plugin --profile web add link:<workspace-root>/packages/dsh-maestro-memory
|
|
50
|
+
# or manually in ~/.dsh/profiles/web/package.json:
|
|
51
|
+
# "@ddtcorex/dsh-maestro-memory": "link:<workspace-root>/packages/dsh-maestro-memory"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Git / registry (production after release):**
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
dsh plugin --profile web add github:ddtcorex/dsh-maestro-memory#<tag-or-sha>
|
|
58
|
+
# pin to an exact commit SHA; branch names reuse stale tarballs (pnpm cache pitfall)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
After install, rebuild is not needed inside the profile — the host loads `lib/index.js` and the client loads `lib/client.js` via the `dsh.client` manifest. If you edited `src/client/`, rebuild at the checkout first (`pnpm run build`).
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Profile Patch
|
|
66
|
+
|
|
67
|
+
`cordis.patch.yml` is **owned by the package** and applied automatically by `dsh plugin add`. Do not duplicate it in the profile.
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
# dsh-maestro-memory/cordis.patch.yml (shipped with the package)
|
|
71
|
+
- insert:
|
|
72
|
+
- id: maestro-memory
|
|
73
|
+
name: '@ddtcorex/dsh-maestro-memory'
|
|
74
|
+
config:
|
|
75
|
+
memoryDir: null # null -> ~/.dsh/memories
|
|
76
|
+
snapshotOrder: 500 # systemPrompt.context order
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Profile `~/.dsh/profiles/web/package.json` after a correct install:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"dsh": { "profile": { "bundles": ["@ddtcorex/dsh-maestro-memory"] } },
|
|
84
|
+
"dependencies": {
|
|
85
|
+
"@ddtcorex/dsh-maestro-memory": "link:<workspace-root>/packages/dsh-maestro-memory"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Rules:**
|
|
91
|
+
|
|
92
|
+
- `dependencies` value **must be `link:`**, not a semver. CI and `assertSingleOwner` reject non-link owners.
|
|
93
|
+
- `bundles` must list exactly one owner for each compat tool (see below). Do not keep `dsh-memory-evolve` and `dsh-maestro-memory` in the same profile — they compete for `memory`/`dtodo` and for file ownership. The loader crashes on duplicate `id: maestro-memory` if you copy the patch row into the profile manually.
|
|
94
|
+
- `memoryDir: null` resolves to `~/.dsh/memories` (`resolveMemoryRoot(null)`). Override only for tests / rehearsal (`--root /tmp/...`).
|
|
95
|
+
|
|
96
|
+
Verify the profile in a rehearsal (see `src/host/migration/fixture.ts`):
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { createFixtureProfile, assertSingleOwner } from '@ddtcorex/dsh-maestro-memory/migration/fixture'
|
|
100
|
+
await createFixtureProfile({ profileDir: '/tmp/profile', packageDir: '/path/to/dsh-maestro-memory' })
|
|
101
|
+
const res = await assertSingleOwner('/tmp/profile')
|
|
102
|
+
console.assert(res.ok && res.owners['memory'] === '@ddtcorex/dsh-maestro-memory')
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Supported Tools
|
|
108
|
+
|
|
109
|
+
All tools are registered via `ctx.tools.register` inside `ctx.effect(..., 'label')` so they dispose cleanly on unload. No HTTP.
|
|
110
|
+
|
|
111
|
+
| Tool | Purpose | When visible |
|
|
112
|
+
|------|---------|--------------|
|
|
113
|
+
| `memory` | CRUD + query for five tracks (`memory`/`user`/`project`/`key`/`daily`) + archive/expand. See `src/host/memory/store.ts`. | Always |
|
|
114
|
+
| `dtodo` | Four-track todos (`life`/`work`/`project`/`daily`) with stable 8-hex ids, status/due/quadrant, smart view (max 8), historical daily lookup. | Always |
|
|
115
|
+
| `memory_suggest` | **Gated** — model proposes `memory`/`user`/`key`/`todo-*` into `SUGGESTIONS.jsonl`; never writes directly. Requires human approve/edit/reject via Review UI or `queue.decide` RPC. | Always |
|
|
116
|
+
| `memory_review_status` | Read-only queue depth / write-block status (used by prompt hint / UI badge). | Always |
|
|
117
|
+
| `skill_manage` | Browse / mutate `~/.agents/skills` (optional module). Disabled by default; enable only if the optional skills module is explicitly configured. | Opt-in |
|
|
118
|
+
|
|
119
|
+
### `memory` — actions and targets
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
memory({
|
|
123
|
+
action: 'add'|'list'|'replace'|'remove'|'archive'|'expand',
|
|
124
|
+
target: 'memory'|'user'|'project'|'key'|'daily', // memory=global, key=per-cwd long-term
|
|
125
|
+
content?: string, // add: entry body; replace: new body
|
|
126
|
+
match?: string, // replace/remove/archive: unique substring of existing entry
|
|
127
|
+
filter?: string, // list: content substring filter
|
|
128
|
+
since?: string, until?: string, // list: YYYY-MM-DD
|
|
129
|
+
limit?: number, recent?: boolean, branch?: string, archived?: boolean,
|
|
130
|
+
branches?: string, // add key: csv "main,dev" (empty=all), branch scope
|
|
131
|
+
summary?: string, // add key: one-line summary for progressive disclosure
|
|
132
|
+
id?: string, // expand: [mem-xxxx] id
|
|
133
|
+
cwd?: string, // project/key track working directory (defaults to session cwd)
|
|
134
|
+
date?: string, // daily track YYYY-MM-DD
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- **Progressive disclosure:** `key` entries are stored with an optional `[summary]` line; `list` without `expand` returns summaries; `expand` with `id` returns full text.
|
|
139
|
+
- **Branch scope:** `key` entries may carry `[branch:main]` tags; `list` with `branch` filters to that branch + entries with no branch tag.
|
|
140
|
+
|
|
141
|
+
### `dtodo` — actions
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
dtodo({
|
|
145
|
+
action: 'add'|'list'|'done'|'update'|'remove',
|
|
146
|
+
target?: 'life'|'work'|'project'|'daily', // add/list filter; add defaults to cwd?project:work
|
|
147
|
+
content?: string,
|
|
148
|
+
id?: string, // done/update/remove
|
|
149
|
+
due?: string, // YYYY-MM-DD
|
|
150
|
+
quadrant?: 'q1'|'q2'|'q3'|'q4', // or important/urgent booleans -> quadrant
|
|
151
|
+
cat?: string, status?: 'pending'|'doing'|'done'|'blocked'|'cancelled',
|
|
152
|
+
all?: boolean, past?: boolean, expired?: boolean, // list: smart-view controls
|
|
153
|
+
cwd?: string, date?: string,
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- **Smart view (default):** when `all !== true` and no filter, `list` returns at most 8 items ordered `overdue -> due today -> current project -> q1/q2 -> rest`. Uses local date, not UTC.
|
|
158
|
+
- **History:** `past=true` alone shows only completed history; `past=true AND expired=true` includes expired unfinished daily todos (daily todos expire same day).
|
|
159
|
+
|
|
160
|
+
### `memory_suggest` (gated)
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
memory_suggest({ target: 'memory'|'user'|'key'|'todo-life'|'todo-work'|'todo-project'|'todo-daily', content: string, reason: string })
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Dedupes by `(target, content)` within the queue (bumps `hits`), appends to `SUGGESTIONS.jsonl`. The model must never write `key`/`user` directly — queue + human click is the only activation path.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## System Prompt Snapshot
|
|
171
|
+
|
|
172
|
+
Registered as `ctx.systemPrompt.context({ name: 'memory:snapshot', order: 500, text: (ctx) => renderSnapshot(cwd, branch) })`.
|
|
173
|
+
|
|
174
|
+
Injected text is **bounded** and deterministic: `USER + global MEMORY + current-project KEY` (branch-filtered if `session.header.branch` is present), plus a header with `sessionId`/`sessionName` and an end-of-turn discipline note (rendered verbatim as `---` + newline + sentence):
|
|
175
|
+
|
|
176
|
+
> End of every turn you must: 1. Write daily+project via memory entries (daily+project in one call) 2. Check dtodo list (bounded, max 8)
|
|
177
|
+
|
|
178
|
+
`daily` and `project log` (`projects/<hash>/MEMORY.md`) are queryable via `memory` but **not injected**, to keep prompt cost predictable. New `prompt/snapshot.ts` must reproduce this contract or agents silently stop writing logs.
|
|
179
|
+
|
|
180
|
+
Each injected section also enforces a **per-track byte cap** — defaults `SNAPSHOT_SECTION_CAPS = { memory: 2048, user: 4096, key: 6144 }`, overridable per call via `renderSnapshot(store, ctx, { caps })`. Entries are kept newest-first; the oldest overflow is dropped. The newest entry is always kept: if it alone exceeds the cap **and** carries an `[summary:…]` header tag (parsed by `ENTRY_HEAD_RE`), it renders compacted to `head + [summary:…]`; untagged oversize entries stay whole rather than vanishing.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## UI & RPC
|
|
185
|
+
|
|
186
|
+
- **UI:** exactly one `conversation.view` slot `{ name:'conversation.view', id:'maestro-memory', order:40, label:()=>'Memory' }` with internal tabs **Memory / Review queue / Todos**. Uses package-private RPC, no HTTP, no DOM hacks. Client injects `['slots','locale','conversation','sessions','connection']`.
|
|
187
|
+
- **RPC channel:** `/dsh-maestro-memory` (`ctx.connection.rpc.handle` host, `ctx.connection.rpc.call` client). Endpoints: `queue.list`, `queue.decide` (`approve`/`reject`/`archive` with optional `edits`/`targets` + `cwd`), `memory.list`, `todo.list`, `todo.mutate`, `migration.inspect`/`dryRun`/`run`/`verify`, `status` (`{ queue, blocked }`). `migration.run` via RPC requires `payload.apply === true`.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Cutover
|
|
192
|
+
|
|
193
|
+
**Principle:** staged single-owner replacement — never run `dsh-memory-evolve` and `dsh-maestro-memory` in the same profile. The new internals, services, RPC methods, and slot ids use a Maestro namespace; compatibility is limited to agent-facing tool names and legacy file grammar.
|
|
194
|
+
|
|
195
|
+
**Operator steps (production):**
|
|
196
|
+
|
|
197
|
+
1. **Preflight** on a copy, not live home (see Migration). Keep the live profile untouched until verification passes.
|
|
198
|
+
2. **Backup** the live `~/.dsh/memories` via `node scripts/migrate.mjs --root ~/.dsh/memories --apply` — this is the only write; it creates `manifest.json` + byte-identical `files/` under `.maestro-memory/backups/<utc-run-id>/` + `schema.json` + `journal`.
|
|
199
|
+
3. **Verify** (`--verify`) — must be `ok=true`, `mismatches=[]`. If not, writes are blocked (`write-block.json`) — resolve before continuing.
|
|
200
|
+
4. **Profile swap:** remove `dsh-memory-evolve` from `bundles`/`dependencies`, add `@ddtcorex/dsh-maestro-memory` as `link:` (or pinned git SHA). Ensure exactly one owner per compat tool (`memory`, `dtodo`).
|
|
201
|
+
5. **Reload profile:** restart `dsh web` at a user-approved window (ask first — do not kill the live `dsh web` process mid-session; it holds both :3000 and :3080). After restart, live-read every track (`memory` list for each target, `dtodo` list) before first mutation.
|
|
202
|
+
6. **One write** against live data, then `verify` again.
|
|
203
|
+
|
|
204
|
+
**Before any writes, rollback is just a profile change** (remove Maestro, restore old bundle). After writes, restore files from the manifest.
|
|
205
|
+
|
|
206
|
+
For a disposable rehearsal, use `src/host/migration/fixture.ts` (`createFixtureProfile`, `createCopiedMemoryRoot`, `assertSingleOwner`) — see `tests/m4-rehearsal.spec.ts` and the `Migration rehearsal` CI job. Never touch `~/.dsh/memories` in tests.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Migration
|
|
211
|
+
|
|
212
|
+
CLI: `node scripts/migrate.mjs --root <path> [--inspect|--dry-run|--verify|--apply] [--run-id <id>]`
|
|
213
|
+
|
|
214
|
+
Default is **read-only**. The only write is `--apply`.
|
|
215
|
+
|
|
216
|
+
| Command | Effect | Side effects |
|
|
217
|
+
|---------|--------|--------------|
|
|
218
|
+
| `--inspect` (default) | Inventory, parse, byte count, SHA-256, warnings for malformed JSONL / locks / non-canonical files | None |
|
|
219
|
+
| `--dry-run` | Same as inspect, explicitly read-only | None |
|
|
220
|
+
| `--apply` | **Backup + adopt:** byte-preserving copy of every file (excluding `.maestro-memory`) into `backups/<utc-run-id>/files/` + `manifest.json` (`path, bytes, sha256, inventory`) + `schema.json` + `migration-journal.jsonl` entry. Only after all required data parses; source content is never reformatted. | Writes `manifest`, `files/`, `schema.json`, `journal` |
|
|
221
|
+
| `--verify` | Reopen with new stores, compare digest (`bytes`, `sha256`) + inventory (`memoryEntries`, `todoIds`, `queueValid`) against manifest. On mismatch, writes `.maestro-memory/write-block.json` and blocks mutations; on success clears the block. | Writes `write-block.json` on failure; clears on success |
|
|
222
|
+
|
|
223
|
+
**Disk layout:**
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
~/.dsh/memories/
|
|
227
|
+
MEMORY.md USER.md # may be absent until first global write
|
|
228
|
+
MEMORY-archive.md USER-archive.md
|
|
229
|
+
SUGGESTIONS.jsonl
|
|
230
|
+
TODOS-life.md TODOS-work.md
|
|
231
|
+
daily/YYYY-MM-DD.md daily/YYYY-MM-DD.todo.md
|
|
232
|
+
projects/<sha1(cwd)[:12]>/
|
|
233
|
+
MEMORY.md KEY.md
|
|
234
|
+
KEY-archive.md TODOS.md
|
|
235
|
+
.maestro-memory/
|
|
236
|
+
schema.json
|
|
237
|
+
migration-journal.jsonl
|
|
238
|
+
write-block.json # present only when verify failed
|
|
239
|
+
backups/<utc-run-id>/
|
|
240
|
+
manifest.json # { files:[{path,relative,bytes,sha256,kind,...}], inventory, runId, at }
|
|
241
|
+
files/... # byte-identical copies
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Warnings (non-fatal, reported in `inspect`/`dryRun`/`verify`):**
|
|
245
|
+
|
|
246
|
+
- `non-canonical` — file does not round-trip through `§` parse/serialize (drift); mutation is refused until canonicalized.
|
|
247
|
+
- `malformed todo` — entry missing timestamp/id in a todo file.
|
|
248
|
+
- `malformed queue` — JSONL line in `SUGGESTIONS.jsonl` that does not parse as `{target, content}`.
|
|
249
|
+
|
|
250
|
+
**Write-block:** `migration/service.ts:isWriteBlocked(root)` checks `.maestro-memory/write-block.json`. When blocked, `memory`/`dtodo` mutations return an error until `verify` passes or `rollback` clears it.
|
|
251
|
+
|
|
252
|
+
**Examples:**
|
|
253
|
+
|
|
254
|
+
```sh
|
|
255
|
+
node scripts/migrate.mjs --root ~/.dsh/memories # inspect (read-only)
|
|
256
|
+
node scripts/migrate.mjs --root /tmp/mem --dry-run # dry-run
|
|
257
|
+
node scripts/migrate.mjs --root /tmp/mem --apply # backup + adopt
|
|
258
|
+
node scripts/migrate.mjs --root /tmp/mem --verify # verify (latest manifest)
|
|
259
|
+
node scripts/migrate.mjs --root /tmp/mem --verify --run-id 20260824T151230.425Z
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Verification
|
|
265
|
+
|
|
266
|
+
1. After `inspect`/`dryRun`, confirm `ok=true`, expected `memoryEntries`/`todoIdsCount`/`queueValid`, and review `warnings`.
|
|
267
|
+
2. After `--apply`, confirm `manifest.json` exists, each `files/<relative>` copy is byte-identical (`sha256` matches), and `~/.dsh/memories` files are unchanged (no reformatting).
|
|
268
|
+
3. After `--verify`, confirm `ok=true`, `mismatches=[]`. If `ok=false`, check `mismatches` (`digest mismatch`, `byte count mismatch`, `todo ID set mismatch`, `inventory mismatch`) and `.maestro-memory/write-block.json`. No mutation should proceed while blocked.
|
|
269
|
+
4. After profile reload, live-read via tools/RPC (`memory` list for `memory`/`user`/`key`/`daily`/`project`, `dtodo` list for `life`/`work`/`project`/`daily`) and compare to pre-cutover inventory.
|
|
270
|
+
|
|
271
|
+
The rehearsal suite (`tests/m4-rehearsal.spec.ts`) exercises the full sequence against a copied schema: fixture profile (`link:`) → one-owner proof → dry-run (no `.maestro-memory`) → backup (byte-preserving) → verify → profile reload (`apply`/`ctx.effect`) → live reads → one write → second verify (fails) → rollback (byte-identical) → verify (passes) → live home untouched.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Rollback
|
|
276
|
+
|
|
277
|
+
Rollback restores files **byte-identical** from a backup manifest. It is exercised and tested in `tests/m4-rehearsal.spec.ts`.
|
|
278
|
+
|
|
279
|
+
**When to rollback:**
|
|
280
|
+
|
|
281
|
+
- Before any writes: no rollback needed — just revert the profile change (remove Maestro bundle, restore old plugin).
|
|
282
|
+
- After a failed `verify` or a bad write: restore from the backup that `verify` reports.
|
|
283
|
+
|
|
284
|
+
**How (CLI / service API):**
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
import { rollback } from './src/host/migration/service.ts'
|
|
288
|
+
// restore latest (schema.json runId or newest backup)
|
|
289
|
+
await rollback('/tmp/memories')
|
|
290
|
+
// or specific run
|
|
291
|
+
await rollback('/tmp/memories', '20260824T151230.425Z')
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Or via the `migration` RPC (host) if exposed. The service:
|
|
295
|
+
|
|
296
|
+
- Copies each `manifest.files[].relative` from `backups/<runId>/files/` to its original `path`, verifying `sha256` after copy.
|
|
297
|
+
- If a file was absent at backup time (`exists:false` in manifest) but appeared later, it is removed.
|
|
298
|
+
- Clears `write-block.json` on completion and appends a `rollback` entry to `migration-journal.jsonl`.
|
|
299
|
+
- Returns `{ ok, runId, manifestPath, restored, errors }` (`restored` = count of files restored/removed).
|
|
300
|
+
|
|
301
|
+
**After rollback:**
|
|
302
|
+
|
|
303
|
+
- `verify` must pass (`ok=true`, no mismatches).
|
|
304
|
+
- A new write must succeed (the write-block is cleared).
|
|
305
|
+
|
|
306
|
+
**Retention:** keep `~/.dsh/memories/.maestro-memory/backups/` for at least 90 days after cutover (per plan). Do not delete the manifest for the adopted run.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Removed Features (intentionally not in v1)
|
|
311
|
+
|
|
312
|
+
Source-grounded inventory. Propose any as a separate plugin later.
|
|
313
|
+
|
|
314
|
+
| Source subsystem | Verdict | Rationale |
|
|
315
|
+
|------------------|---------|-----------|
|
|
316
|
+
| **Cross-device Git memory sync** (`lib/sync/*`) | **KEEP as optional module (M5)** | Large conflict-resolution product; must not delay local-data reliability. Disabled = zero network/Git activity. |
|
|
317
|
+
| **Skills management/browser** (`lib/skills.js`, `lib/skills-manager.js`) | **KEEP as optional module (M6)** | Mutates `~/.agents/skills`; Maestro already owns skills in `maestro-skills`. Core stays read-only. |
|
|
318
|
+
| **COI / external CLI dispatch, scheduler, broadcast, ws coordinator, stats, attachments, session orchestration** (`lib/coi/*`, `lib/session-orch.js`) | **DROP** | Independent orchestration platform; profile already has DSH Codex/Claude subagent bundles. |
|
|
319
|
+
| **Advisor** (`lib/advisor/*`) | **REDESIGN** (separate opt-in plugin) | Full reviewer runtime with model calls and panel — not memory. |
|
|
320
|
+
| **Notify / channel send / session images** (`lib/notify.js`) | **DROP** | IM/web delivery via global integration registry (`de_channel_send`, `de_notify`); unrelated to durable memory. |
|
|
321
|
+
| **Local / docs / Codex search** (`lib/search-docs.js`, `lib/search/*`) | **DROP** | Host file scans / shell-out expands authority without being needed for memory. |
|
|
322
|
+
| **Prompt injection library** (`lib/prompts.js`) | **DROP** | Reusable guidance belongs in `maestro-skills`. |
|
|
323
|
+
| **Model registry / settings** (`lib/models.js`) | **DROP** | Overlays DSH model config; `lib/index.js` already injects DSH settings/llm. |
|
|
324
|
+
| **Bookmarks, Mermaid, canvas, UI settings, aliases, update checker, i18n** (`lib/{bookmarks,mermaid,canvas,ui-settings,aliases,update,i18n}.js`) | **REDESIGN** | Independent features; propose individually if needed. |
|
|
325
|
+
| **Client/WebUI broad tabs** (`src/client/index.ts` family) | **REDESIGN** | Legacy mounts many tabs/actions + HTTP API; v1 has one slot + package-private RPC. |
|
|
326
|
+
| **HTTP API** (`lib/api.js` `/memory-evolve` prefix, `ctx.webServer`) | **DROP** | No `webServer` registration; only `ctx.connection.rpc.handle('/dsh-maestro-memory', …)`. |
|
|
327
|
+
|
|
328
|
+
**Preserved in backup but not imported:** `advisor/`, `pending-skills/`, `plugin-state.json`, `search-docs-index.json`, `coi/` (copied byte-identical into `files/` and listed in `manifest.json`, never parsed as memory state).
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Workflow: Superpowers skills are mandatory
|
|
333
|
+
|
|
334
|
+
Every change to this repository MUST follow the Superpowers skill workflow, in order:
|
|
335
|
+
|
|
336
|
+
1. **brainstorming** — explore intent, requirements, and design before any code; record the outcome in `docs/superpowers/specs/` (`YYYY-MM-DD-<topic>-design.md`).
|
|
337
|
+
2. **writing-plans** — turn an approved spec into a task-by-task plan with exact test and implementation sketches in `docs/superpowers/plans/` (`YYYY-MM-DD-<topic>.md`).
|
|
338
|
+
3. **executing-plans** — implement task by task with strict TDD: write the failing test first, verify RED, implement, verify GREEN, then commit that task as its own commit before starting the next.
|
|
339
|
+
|
|
340
|
+
Do not skip ahead to implementation, batch multiple tasks into one commit, or commit while a task's tests are red. Trivial mechanical fixes may go straight to a commit but still need tests when behavior changes.
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Git Workflow
|
|
345
|
+
|
|
346
|
+
- Never commit to `master` directly; batch related work on a feature branch (`feat/...`, `fix/...`). One TDD task = one commit while executing a plan.
|
|
347
|
+
- Conventional commit subjects, imperative mood.
|
|
348
|
+
- Push the branch and open an MR when the batch is green; rebase instead of merging master into the branch when the base moves.
|
|
349
|
+
- `origin` is `git@github.com:ddtcorex/dsh-maestro-memory.git` (private, default branch `master`).
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
## Layout
|
|
354
|
+
|
|
355
|
+
- `src/host/` — Cordis host plugin (`storage/legacy-format.ts`, `storage/layout.ts`, `storage/atomic-store.ts`, `memory/store.ts`, `todo/store.ts`, `review/queue.ts`, `migration/service.ts`, `prompt/snapshot.ts`, `index.ts`).
|
|
356
|
+
- `src/client/` — DSH client bundle (`src/client/index.tsx` → `lib/client.js` via `scripts/build-client.mjs`, `conversation.view` id `maestro-memory` order 40, internal Memory/Review/Todos tabs, RPC `/dsh-maestro-memory`).
|
|
357
|
+
- `tests/` — Vitest specs (`legacy-format.spec.ts`, `storage.spec.ts`, `atomic-store.spec.ts`, `memory-m2.spec.ts`, `todo-m3.spec.ts`, `migration.spec.ts`, `m4-rehearsal.spec.ts`, etc.).
|
|
358
|
+
- `scripts/migrate.mjs` — migration CLI (`--root`, `--apply`/`--dry-run`/`--verify`).
|
|
359
|
+
|
|
360
|
+
Build outputs in `lib/` (`lib/client.js` via `scripts/build-client.mjs`) are generated — never edit by hand.
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Development
|
|
365
|
+
|
|
366
|
+
```sh
|
|
367
|
+
pnpm install
|
|
368
|
+
pnpm test # full suite (13 files, 199 tests)
|
|
369
|
+
pnpm run verify # tsc --noEmit host + client (typecheck)
|
|
370
|
+
pnpm run build # tsc host + tsc client + bundle client.js
|
|
371
|
+
pnpm exec vitest run tests/legacy-format.spec.ts tests/storage.spec.ts tests/atomic-store.spec.ts # unit
|
|
372
|
+
pnpm exec vitest run tests/memory-m2.spec.ts tests/todo-m3.spec.ts tests/suggestion-queue.spec.ts tests/rpc-queue.spec.ts # integration
|
|
373
|
+
pnpm exec vitest run tests/migration.spec.ts # migration
|
|
374
|
+
pnpm exec vitest run tests/m4-rehearsal.spec.ts # rehearsal (fixture profile + rollback)
|
|
375
|
+
node scripts/migrate.mjs --root ~/.dsh/memories # inspect (read-only)
|
|
376
|
+
node scripts/migrate.mjs --root /tmp/mem --apply # backup + adopt
|
|
377
|
+
node scripts/migrate.mjs --root /tmp/mem --verify # verify
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Run `pnpm test` after host changes, `pnpm run verify` after TypeScript changes, `pnpm run build` after editing `src/client/`. Do not kill/restart the live `dsh web` process serving a session — ask for a convenient restart window.
|
|
381
|
+
|
|
382
|
+
### CI
|
|
383
|
+
|
|
384
|
+
`.github/workflows/ci.yml` runs on `push` to `master`/`main` and on every PR:
|
|
385
|
+
|
|
386
|
+
| Job step | Command | What it proves |
|
|
387
|
+
|----------|---------|----------------|
|
|
388
|
+
| Install | `pnpm install --frozen-lockfile` | Reproducible deps |
|
|
389
|
+
| Build | `pnpm run build` | Host + client compile |
|
|
390
|
+
| Typecheck | `pnpm run verify` | `tsc --noEmit` host + client |
|
|
391
|
+
| Unit | `vitest run tests/legacy-format.spec.ts tests/storage.spec.ts tests/atomic-store.spec.ts` | Pure delimiter / path / atomic-store |
|
|
392
|
+
| Integration | `vitest run tests/memory-m2.spec.ts tests/todo-m3.spec.ts tests/suggestion-queue.spec.ts tests/rpc-queue.spec.ts tests/smoke.spec.ts` | Stores + queue + RPC |
|
|
393
|
+
| Migration | `vitest run tests/migration.spec.ts` | inspect/dryRun/run/verify, backup manifest, write-block |
|
|
394
|
+
| Rehearsal | `vitest run tests/m4-rehearsal.spec.ts` | Fixture `link:` profile, one-owner proof, copied-schema cutover + rollback, live home untouched |
|
|
395
|
+
| Client | `test -f lib/client.js && grep ModuleLoader lib/client.js` | Bundle exists + header |
|
|
396
|
+
| Full | `pnpm test` | Entire suite (13 files, 199 tests) |
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## Security
|
|
401
|
+
|
|
402
|
+
- Never print, commit, or add fixture values for secrets. Use obviously synthetic values in tests and docs.
|
|
403
|
+
- No cloud service, database rewrite, telemetry, or sync in v1; M5 sync (Git-backed) is opt-in and disabled means zero network activity.
|
|
404
|
+
- Secrets must never be echoed to the client; new secret-bearing fields need masking + constant-time comparison.
|
|
405
|
+
- File permissions: memory files inherit host umask; `SUGGESTIONS.jsonl` is append-only; `write-block.json` is local-only.
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Troubleshooting
|
|
410
|
+
|
|
411
|
+
| Symptom | Cause | Fix |
|
|
412
|
+
|---------|-------|-----|
|
|
413
|
+
| `tool "memory" has multiple owners` in `assertSingleOwner` | Both `dsh-memory-evolve` and `dsh-maestro-memory` in `bundles` | Remove the old plugin from the profile; keep exactly one owner per compat tool |
|
|
414
|
+
| `profile cordis.patch.yml must not duplicate id maestro-memory` | Profile patch duplicates the package's `cordis.patch.yml` row | Delete the row from the profile patch; the package provides it |
|
|
415
|
+
| `verify failed: digest mismatch` / `write-block.json` exists | File changed after backup (hand-edit, concurrent writer) | Inspect `write-block.json` mismatches, then `rollback(root, runId)` or resolve drift and `verify` again |
|
|
416
|
+
| `non-canonical` warning | File contains non-`§`-canonical content (hand-edit) | Back up manually, then normalize via a single `replace` edit through the tool (creates canonical serialization) |
|
|
417
|
+
| `mismatched todo IDs` after verify | Todo file edited outside the store | Roll back or re-run `inspect` and compare inventories |
|
|
418
|
+
| DSH Web UI shows no Memory tab | `lib/client.js` not built or bundle header missing | `pnpm run build` at the checkout, then restart `dsh web` (user-approved window) and hard-refresh the browser |
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Ghi chú vận hành (Tiếng Việt — ngắn gọn)
|
|
423
|
+
|
|
424
|
+
> English là ngôn ngữ chính của tài liệu và mã nguồn. Phần này chỉ tóm tắt thao tác cho người vận hành tiếng Việt.
|
|
425
|
+
|
|
426
|
+
- **Cài đặt:** `pnpm install` → `pnpm run build` → `pnpm run verify` → `pnpm test`. Thêm plugin vào profile bằng `dsh plugin --profile web add link:/path/to/dsh-maestro-memory` (không copy `cordis.patch.yml` vào profile).
|
|
427
|
+
- **Công cụ hỗ trợ:** `memory` (5 track), `dtodo` (4 track, smart view 8), `memory_suggest` (đề xuất phải được duyệt), `memory_review_status`. `skill_manage` chỉ khi bật module tùy chọn.
|
|
428
|
+
- **Cutover (chuyển đổi):** chỉ chạy một plugin sở hữu `memory`/`dtodo`. Không chạy đồng thời `dsh-memory-evolve` và `dsh-maestro-memory`. Thực hiện trên bản copy trước, sau đó mới áp dụng lên `~/.dsh/memories`.
|
|
429
|
+
- **Migration:** `node scripts/migrate.mjs --root <path>` (mặc định chỉ đọc). `--apply` mới ghi backup + `schema.json`. `--verify` kiểm tra `sha256` + tồn kho; nếu lệch sẽ ghi `write-block.json` và chặn ghi.
|
|
430
|
+
- **Rollback:** `await rollback(root, runId)` khôi phục byte-identical từ `backups/<runId>/files/`; xóa `write-block.json` khi xong. Trước khi có ghi mới, rollback chỉ là đổi profile.
|
|
431
|
+
- **Tính năng đã loại bỏ:** COI/broadcast, advisor, notify/`de_channel_send`, search, prompt library, model registry, bookmarks/mermaid/canvas. Chi tiết xem bảng "Removed Features".
|
|
432
|
+
- **CI:** `build` + `typecheck` + `unit` + `integration` + `migration` + `rehearsal` + `client` + `full` — tất cả phải xanh trước khi merge.
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## Documentation
|
|
437
|
+
|
|
438
|
+
Keep current behavior in `README.md`. Do not add plans, transient investigation logs, or duplicate specifications under `docs/`; capture only durable operator and architecture knowledge. The one exception is Superpowers artifacts: specs under `docs/superpowers/specs/` and plans under `docs/superpowers/plans/` are kept as the design record for each change batch.
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## References
|
|
443
|
+
|
|
444
|
+
- `src/host/migration/service.ts` — inspect/dryRun/run/verify/rollback implementation
|
|
445
|
+
- `src/host/migration/fixture.ts` — fixture profile + copied-schema helpers for rehearsal
|
|
446
|
+
- `tests/m4-rehearsal.spec.ts` — end-to-end rehearsal (profile → backup → verify → reload → write → rollback)
|
|
447
|
+
- `scripts/migrate.mjs` — operations CLI (read-only by default, `--apply` to write)
|
|
448
|
+
- `.github/workflows/ci.yml` — build / typecheck / unit / integration / migration / client / full
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# dsh-maestro-memory bundle patch: inserts the host row into the profile's
|
|
2
|
+
# plugin roster. The browser half rides the package's `dsh.client` manifest
|
|
3
|
+
# (the client registry serves lib/client.js), and this row materializes the
|
|
4
|
+
# Maestro memory / todos host plugin on boot.
|
|
5
|
+
# Install with `dsh plugin --profile <name> add <path-or-git-url>`; the bundle
|
|
6
|
+
# patch is applied automatically, so do NOT insert this row again in the
|
|
7
|
+
# profile patch (duplicate ids crash the loader).
|
|
8
|
+
- insert:
|
|
9
|
+
- id: maestro-memory
|
|
10
|
+
name: '@ddtcorex/dsh-maestro-memory'
|
|
11
|
+
config:
|
|
12
|
+
memoryDir: null
|
|
13
|
+
snapshotOrder: 500
|