dsh-engramory 0.2.0 → 0.2.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/README.md +27 -19
- package/index.js +35 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,14 +18,17 @@ because the index loads every session and everything past the cap silently stops
|
|
|
18
18
|
recalled. On most hosts that limit is rules plus a checker the agent has to remember to
|
|
19
19
|
run. dsh exposes `ctx.tools.guard()` — a synchronous, **monotonic** refusal: once a guard
|
|
20
20
|
returns a reason, no later listener can turn it back into an allow. So here the limit is
|
|
21
|
-
enforced, not requested
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
enforced, not requested. Use **0.2.1 or later**: 0.2.0 shipped before profile installs
|
|
22
|
+
worked upstream and carried an `inject` declaration this Cordis does not accept — it
|
|
23
|
+
installed but never activated (issue #8). Outside Claude Code, dsh is the first host with
|
|
24
|
+
the shim actually written (a few others expose equivalent pre-write seams — see
|
|
25
|
+
PORTING.md — but have no shim yet).
|
|
26
|
+
|
|
27
|
+
**The protocol arrives with the plugin.** The skill is registered at runtime through
|
|
28
|
+
dsh's skill registry — via a reactive `ctx.inject(['skills'], …)` child, so a profile
|
|
29
|
+
without a registry still gets the cap and one whose registry activates late still gets
|
|
30
|
+
the skill — which means it does not depend on landing files in one of the five skill
|
|
31
|
+
roots dsh scans, a path that is easy to get subtly wrong and fails silently when you do.
|
|
29
32
|
|
|
30
33
|
## Install
|
|
31
34
|
|
|
@@ -91,18 +94,23 @@ newline, so an index sitting exactly at the cap stays writable.
|
|
|
91
94
|
index cannot be grown further, and a shrinking write always passes.
|
|
92
95
|
- **The tool roster follows dsh's documented tool-fs contract** (`write`/`edit` with
|
|
93
96
|
`file_path`, `str_replace_editor` with `path`) and is deliberately conservative:
|
|
94
|
-
unknown tools pass.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
97
|
+
unknown tools pass.
|
|
98
|
+
- **0.2.0 never activated; 0.2.1 is the first version that runs.** While the rc.6
|
|
99
|
+
preview bug blocked all third-party profile installs upstream, the only coverage a
|
|
100
|
+
plugin could have was mocks — and 0.2.0's mock hid two activation bugs: an
|
|
101
|
+
older-Cordis `{ required, optional }` inject shape (read as waiting for services
|
|
102
|
+
literally named `required`/`optional`, pending forever) and a bare `ctx.skills` read
|
|
103
|
+
of an undeclared service (throws under Cordis' reflective context). The first field
|
|
104
|
+
install caught both the moment installs became possible (issue #8). 0.2.1 fixes them,
|
|
105
|
+
verified end to end on a live dsh 0.1.0-rc.7 web profile (0.2.0 reproduces the boot
|
|
106
|
+
failure byte for byte; 0.2.1 boots and serves) and against the vendored
|
|
107
|
+
`@deepseek-ai/cordis` resolver (activation with, without, and with a late-mounted
|
|
108
|
+
skill registry). The test mock now mirrors the reflective-context access rules, and
|
|
109
|
+
the guard's decision table stays covered by `node --test` (22 cases, run in
|
|
110
|
+
Engramory's CI).
|
|
104
111
|
- dsh is a developer preview and its plugin API can change. This plugin deliberately
|
|
105
|
-
touches only `ctx.tools.guard()` and `ctx.skills
|
|
112
|
+
touches only `ctx.tools.guard()` and a reactive `ctx.inject(['skills'], …)` child
|
|
113
|
+
that registers the skill, so it stays cheap to fix.
|
|
106
114
|
|
|
107
115
|
## License
|
|
108
116
|
|
package/index.js
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* monotonic refusal — once a guard returns a reason, no later waterfall
|
|
8
8
|
* listener can turn it back into an allow. That makes it a stronger seam than
|
|
9
9
|
* most hosts expose, and it is why the 200-line / 25 KB limit can be enforced
|
|
10
|
-
* here rather than merely asked for.
|
|
11
|
-
* cap degrades to "rules plus a checker the agent has to
|
|
10
|
+
* here rather than merely asked for. Without a shim like this one, everywhere
|
|
11
|
+
* except Claude Code the cap degrades to "rules plus a checker the agent has to
|
|
12
|
+
* remember to run".
|
|
12
13
|
* 2. Skill delivery that does not depend on install paths. Registering at runtime
|
|
13
14
|
* sidesteps the five-root scan entirely, so the protocol is present because the
|
|
14
15
|
* plugin is loaded, not because a directory happened to be right.
|
|
@@ -27,9 +28,14 @@ import { basename } from 'node:path'
|
|
|
27
28
|
|
|
28
29
|
export const name = 'engramory'
|
|
29
30
|
|
|
30
|
-
// `tools` carries the cap and is
|
|
31
|
-
//
|
|
32
|
-
|
|
31
|
+
// `tools` carries the cap and is the plugin's only declared dependency. Cordis reads
|
|
32
|
+
// `inject` as an array of service names (or an object KEYED by them) and treats every
|
|
33
|
+
// entry as a hard wait — the `{ required, optional }` shape is older-Cordis syntax that
|
|
34
|
+
// the build dsh vendors resolves as services literally named "required"/"optional",
|
|
35
|
+
// which never appear, so the plugin sat pending forever (issue #8). `skills` is
|
|
36
|
+
// deliberately NOT declared: the cap must mount even on a profile with no skill
|
|
37
|
+
// registry, so apply() probes it at runtime instead.
|
|
38
|
+
export const inject = ['tools']
|
|
33
39
|
|
|
34
40
|
/** Mirrors hooks/engramory_index_guard.py — the caps are the protocol's, not this port's. */
|
|
35
41
|
const DEFAULT_INDEX_NAME = 'MEMORY.md'
|
|
@@ -57,19 +63,30 @@ export function apply(ctx, config = {}) {
|
|
|
57
63
|
|
|
58
64
|
ctx.tools.guard((exec) => refuseOversizedIndex(exec, settings))
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
// The skill registry is optional AND may activate after this plugin — fiber order
|
|
67
|
+
// between unrelated providers is not guaranteed, so a one-shot probe here would
|
|
68
|
+
// silently skip registration on such boots. ctx.inject() is Cordis' reactive form:
|
|
69
|
+
// the callback runs once `skills` is available (however late), re-runs if the
|
|
70
|
+
// registry reloads, and never makes the cap wait. A bare `ctx.skills` read at THIS
|
|
71
|
+
// level would throw (undeclared service — issue #8's second crash); inside the
|
|
72
|
+
// callback the service is declared, so the read is legal.
|
|
73
|
+
if (config.registerSkill !== false) {
|
|
74
|
+
ctx.inject(['skills'], (inner) => {
|
|
75
|
+
const skill = config.skill ?? builtinSkillBody()
|
|
76
|
+
// effect() ties the registration to the child fiber: it is disposed when the
|
|
77
|
+
// registry unloads, so a reload cannot accumulate duplicate registrations.
|
|
78
|
+
inner.effect(() => inner.skills.register({
|
|
79
|
+
name: 'engramory',
|
|
80
|
+
description:
|
|
81
|
+
'Curated file-based long-term memory: recall through MEMORY.md at the start of ' +
|
|
82
|
+
'a task, save durable user/feedback/project/reference facts, and sync before ' +
|
|
83
|
+
'compacting or opening a fresh thread.',
|
|
84
|
+
whenToUse:
|
|
85
|
+
'Starting or resuming work, learning something durable worth a future session, ' +
|
|
86
|
+
'or approaching a compact/clear/new-thread boundary.',
|
|
87
|
+
source: 'runtime',
|
|
88
|
+
content: skill,
|
|
89
|
+
}))
|
|
73
90
|
})
|
|
74
91
|
}
|
|
75
92
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-engramory",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Curated file-based long-term memory for DeepSeek Harness — human-readable markdown notes, one plain-file store shared across hosts (git-ignored when it lives inside a project repo), and a deterministic index cap enforced by ctx.tools.guard()",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh-plugin",
|