@hippodid/openclaw-plugin 1.0.9 → 1.0.10
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 +41 -5
- package/dist/hippodid-client.d.ts.map +1 -1
- package/dist/hippodid-client.js +13 -4
- package/dist/hippodid-client.js.map +1 -1
- package/dist/hooks/auto-capture.d.ts.map +1 -1
- package/dist/hooks/auto-capture.js +18 -11
- package/dist/hooks/auto-capture.js.map +1 -1
- package/dist/hooks/auto-recall.d.ts.map +1 -1
- package/dist/hooks/auto-recall.js +8 -9
- package/dist/hooks/auto-recall.js.map +1 -1
- package/dist/hooks/memory-flush.d.ts.map +1 -1
- package/dist/hooks/memory-flush.js +11 -6
- package/dist/hooks/memory-flush.js.map +1 -1
- package/dist/hooks/session-lifecycle.d.ts.map +1 -1
- package/dist/hooks/session-lifecycle.js +25 -5
- package/dist/hooks/session-lifecycle.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +125 -70
- package/dist/index.js.map +1 -1
- package/dist/tier-manager.d.ts.map +1 -1
- package/dist/tier-manager.js +2 -5
- package/dist/tier-manager.js.map +1 -1
- package/dist/types.d.ts +6 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +14 -7
- package/skills/hippodid/SKILL.md +4 -4
- package/src/hippodid-client.ts +16 -4
- package/src/hooks/auto-capture.ts +39 -27
- package/src/hooks/auto-recall.ts +29 -26
- package/src/hooks/memory-flush.ts +15 -6
- package/src/hooks/session-lifecycle.ts +34 -5
- package/src/index.ts +159 -107
- package/src/tier-manager.ts +2 -4
- package/src/types.ts +7 -4
package/README.md
CHANGED
|
@@ -34,6 +34,19 @@ Restart the gateway:
|
|
|
34
34
|
openclaw gateway restart
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
## Local Dev Install
|
|
38
|
+
|
|
39
|
+
You can test the plugin locally without publishing to npm:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm run build
|
|
43
|
+
openclaw plugins install --link .
|
|
44
|
+
openclaw gateway restart
|
|
45
|
+
openclaw plugins info hippodid
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
That links OpenClaw directly to this working tree, so rebuilding `dist/` updates what the gateway loads.
|
|
49
|
+
|
|
37
50
|
## How It Works
|
|
38
51
|
|
|
39
52
|
```
|
|
@@ -50,15 +63,30 @@ The plugin runs as a **non-slot plugin** — it doesn't replace your existing me
|
|
|
50
63
|
Already have memory files from previous sessions?
|
|
51
64
|
|
|
52
65
|
```bash
|
|
53
|
-
|
|
66
|
+
/hippodid import ~/.openclaw/workspace
|
|
54
67
|
```
|
|
55
68
|
|
|
56
69
|
This uploads all `MEMORY.md` + `memory/*.md` files to your HippoDid character in one pass.
|
|
57
70
|
|
|
58
|
-
##
|
|
71
|
+
## Commands
|
|
59
72
|
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
HippoDid exposes two command surfaces:
|
|
74
|
+
|
|
75
|
+
1. Chat commands handled by OpenClaw's command router:
|
|
76
|
+
- `/hippodid status`
|
|
77
|
+
- `/hippodid sync`
|
|
78
|
+
- `/hippodid import [workspace-path]`
|
|
79
|
+
2. Agent/tool calls available inside the runtime:
|
|
80
|
+
- `hippodid:status`
|
|
81
|
+
- `hippodid:sync`
|
|
82
|
+
- `hippodid:import`
|
|
83
|
+
|
|
84
|
+
Important: `openclaw agent --message "/hippodid status"` does **not** go through OpenClaw's slash-command router. That path sends the text straight to the agent, so `/hippodid ...` may be interpreted as ordinary user text instead of a plugin command. Use a real OpenClaw chat/channel surface for slash commands, or use the tool forms above for direct agent runs.
|
|
85
|
+
|
|
86
|
+
## Tool Names
|
|
87
|
+
|
|
88
|
+
| Tool | Description |
|
|
89
|
+
|------|-------------|
|
|
62
90
|
| `hippodid:status` | Show tier, sync status, watched paths |
|
|
63
91
|
| `hippodid:sync` | Trigger immediate sync of all watched files |
|
|
64
92
|
| `hippodid:import` | Import existing workspace memory |
|
|
@@ -102,7 +130,7 @@ This uploads all `MEMORY.md` + `memory/*.md` files to your HippoDid character in
|
|
|
102
130
|
| `apiKey` | string | *required* | HippoDid API key (`hd_sk_...`) |
|
|
103
131
|
| `characterId` | string | *required* | Target character ID |
|
|
104
132
|
| `baseUrl` | string | `https://api.hippodid.com` | API endpoint |
|
|
105
|
-
| `syncIntervalSeconds` | number | `300` | Debounce interval for file sync
|
|
133
|
+
| `syncIntervalSeconds` | number | `300` | Debounce interval for file sync. The server enforces a tier-based minimum. |
|
|
106
134
|
| `autoRecall` | boolean | `false` | Inject relevant memories before each turn (paid tier) |
|
|
107
135
|
| `autoCapture` | boolean | `false` | Extract and store facts after each turn (paid tier) |
|
|
108
136
|
| `additionalPaths` | array | `[]` | Extra files/directories to watch |
|
|
@@ -120,6 +148,8 @@ This uploads all `MEMORY.md` + `memory/*.md` files to your HippoDid character in
|
|
|
120
148
|
- **Auto-Capture**: Facts automatically extracted from conversations via AUDN pipeline
|
|
121
149
|
- Lower sync interval minimums
|
|
122
150
|
|
|
151
|
+
If the server reports `autoRecallAvailable` or `autoCaptureAvailable`, the plugin enables those hooks automatically when the matching config flag is `true`.
|
|
152
|
+
|
|
123
153
|
## Workspace Auto-Detection
|
|
124
154
|
|
|
125
155
|
The plugin automatically finds your memory files by searching:
|
|
@@ -136,6 +166,12 @@ Add `additionalPaths` in config to watch extra files or directories.
|
|
|
136
166
|
- Node.js 22+
|
|
137
167
|
- HippoDid account (free at hippodid.dev)
|
|
138
168
|
|
|
169
|
+
## Notes
|
|
170
|
+
|
|
171
|
+
- The plugin ships compiled output from `dist/` and reads its displayed version from `package.json` at runtime.
|
|
172
|
+
- Current HippoDid servers accept `Authorization: Bearer <apiKey>`. The plugin also sends the legacy `X-Api-Key` header for compatibility.
|
|
173
|
+
- File sync has been verified locally against a linked OpenClaw install, including watcher-driven sync and cloud status updates.
|
|
174
|
+
|
|
139
175
|
## License
|
|
140
176
|
|
|
141
177
|
Apache 2.0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hippodid-client.d.ts","sourceRoot":"","sources":["../src/hippodid-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,MAAM,EACN,QAAQ,EAER,YAAY,EAEZ,kBAAkB,EAGlB,kBAAkB,EAClB,YAAY,EAEb,MAAM,YAAY,CAAC;AAYpB,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxD,QAAQ,CACN,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IACjC,aAAa,CACX,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACxE,cAAc,CACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IACnC,SAAS,CACP,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"hippodid-client.d.ts","sourceRoot":"","sources":["../src/hippodid-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,MAAM,EACN,QAAQ,EAER,YAAY,EAEZ,kBAAkB,EAGlB,kBAAkB,EAClB,YAAY,EAEb,MAAM,YAAY,CAAC;AAYpB,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxD,QAAQ,CACN,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IACjC,aAAa,CACX,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9C,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACxE,cAAc,CACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IACnC,SAAS,CACP,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,CAmP5E"}
|
package/dist/hippodid-client.js
CHANGED
|
@@ -6,7 +6,8 @@ export function createClient(apiKey, baseUrl) {
|
|
|
6
6
|
let tierCache = null;
|
|
7
7
|
function headers() {
|
|
8
8
|
return {
|
|
9
|
-
|
|
9
|
+
Authorization: `Bearer ${apiKey}`,
|
|
10
|
+
'X-Api-Key': apiKey,
|
|
10
11
|
'Content-Type': 'application/json',
|
|
11
12
|
};
|
|
12
13
|
}
|
|
@@ -68,9 +69,15 @@ export function createClient(apiKey, baseUrl) {
|
|
|
68
69
|
return {
|
|
69
70
|
tier: raw.tier,
|
|
70
71
|
features: {
|
|
71
|
-
autoRecallAvailable: raw.features.
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
autoRecallAvailable: raw.features.autoRecallAvailable ??
|
|
73
|
+
raw.features.auto_recall_available ??
|
|
74
|
+
false,
|
|
75
|
+
autoCaptureAvailable: raw.features.autoCaptureAvailable ??
|
|
76
|
+
raw.features.auto_capture_available ??
|
|
77
|
+
false,
|
|
78
|
+
minSyncIntervalSeconds: raw.features.minSyncIntervalSeconds ??
|
|
79
|
+
raw.features.min_sync_interval_seconds ??
|
|
80
|
+
60,
|
|
74
81
|
},
|
|
75
82
|
};
|
|
76
83
|
}
|
|
@@ -104,8 +111,10 @@ export function createClient(apiKey, baseUrl) {
|
|
|
104
111
|
},
|
|
105
112
|
async syncFile(characterId, sourcePath, label, fileContent, checksum) {
|
|
106
113
|
const result = await request('POST', `/v1/characters/${encodeURIComponent(characterId)}/sync`, {
|
|
114
|
+
filePath: sourcePath,
|
|
107
115
|
source_path: sourcePath,
|
|
108
116
|
label,
|
|
117
|
+
fileContent: fileContent,
|
|
109
118
|
file_content: fileContent,
|
|
110
119
|
checksum,
|
|
111
120
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hippodid-client.js","sourceRoot":"","sources":["../src/hippodid-client.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAErC,MAAM,WAAW,GAAG,CAAC,CAAC;AACtB,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAiCxC,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,OAAe;IAC1D,IAAI,SAAS,GAAsB,IAAI,CAAC;IAExC,SAAS,OAAO;QACd,OAAO;YACL,
|
|
1
|
+
{"version":3,"file":"hippodid-client.js","sourceRoot":"","sources":["../src/hippodid-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-capture.d.ts","sourceRoot":"","sources":["../../src/hooks/auto-capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"auto-capture.d.ts","sourceRoot":"","sources":["../../src/hooks/auto-capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAmEpB"}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
export function createAutoCaptureHook(client, config, logger) {
|
|
2
2
|
return (api) => {
|
|
3
|
-
|
|
4
|
-
api.registerHook('agent_end', async (ctx) => {
|
|
3
|
+
api.on('agent_end', async (ctx) => {
|
|
5
4
|
try {
|
|
6
|
-
const user = ctx?.userMessage ??
|
|
7
|
-
|
|
5
|
+
const user = ctx?.userMessage ??
|
|
6
|
+
ctx?.message ??
|
|
7
|
+
ctx?.prompt ??
|
|
8
|
+
ctx?.input ??
|
|
9
|
+
ctx?.finalUserMessage ??
|
|
10
|
+
'';
|
|
11
|
+
const assistant = ctx?.assistantMessage ??
|
|
12
|
+
ctx?.response ??
|
|
13
|
+
ctx?.output ??
|
|
14
|
+
ctx?.finalResponse ??
|
|
15
|
+
'';
|
|
8
16
|
if (!user && !assistant)
|
|
9
17
|
return;
|
|
10
18
|
const content = [
|
|
11
19
|
user ? `User: ${user}` : '',
|
|
12
20
|
assistant ? `Assistant: ${assistant}` : '',
|
|
13
|
-
]
|
|
21
|
+
]
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
.join('\n');
|
|
14
24
|
const result = await client.addMemory(config.characterId, content);
|
|
15
25
|
if (result.ok) {
|
|
16
26
|
logger.info('hippodid: captured conversation turn');
|
|
@@ -19,8 +29,7 @@ export function createAutoCaptureHook(client, config, logger) {
|
|
|
19
29
|
catch (e) {
|
|
20
30
|
logger.warn(`hippodid: capture error: ${e instanceof Error ? e.message : String(e)}`);
|
|
21
31
|
}
|
|
22
|
-
}
|
|
23
|
-
// Explicit tool: agents can call hippodid:remember directly
|
|
32
|
+
});
|
|
24
33
|
api.registerTool({
|
|
25
34
|
name: 'hippodid:remember',
|
|
26
35
|
description: 'Save important information to HippoDid character memory. Call this to store facts, decisions, preferences, or context that should persist across sessions.',
|
|
@@ -40,10 +49,8 @@ export function createAutoCaptureHook(client, config, logger) {
|
|
|
40
49
|
logger.info(`hippodid: captured memory: ${content.slice(0, 80)}...`);
|
|
41
50
|
return 'Remembered.';
|
|
42
51
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return `Failed to remember: ${result.error.message}`;
|
|
46
|
-
}
|
|
52
|
+
logger.warn(`hippodid: capture failed: ${result.error.message}`);
|
|
53
|
+
return `Failed to remember: ${result.error.message}`;
|
|
47
54
|
},
|
|
48
55
|
});
|
|
49
56
|
logger.info('hippodid: auto-capture hook + hippodid:remember tool registered');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-capture.js","sourceRoot":"","sources":["../../src/hooks/auto-capture.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CACnC,MAAsB,EACtB,MAAoB,EACpB,MAA4D;IAE5D,OAAO,CAAC,GAAQ,EAAE,EAAE;QAClB,
|
|
1
|
+
{"version":3,"file":"auto-capture.js","sourceRoot":"","sources":["../../src/hooks/auto-capture.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CACnC,MAAsB,EACtB,MAAoB,EACpB,MAA4D;IAE5D,OAAO,CAAC,GAAQ,EAAE,EAAE;QAClB,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;YACrC,IAAI,CAAC;gBACH,MAAM,IAAI,GACR,GAAG,EAAE,WAAW;oBAChB,GAAG,EAAE,OAAO;oBACZ,GAAG,EAAE,MAAM;oBACX,GAAG,EAAE,KAAK;oBACV,GAAG,EAAE,gBAAgB;oBACrB,EAAE,CAAC;gBACL,MAAM,SAAS,GACb,GAAG,EAAE,gBAAgB;oBACrB,GAAG,EAAE,QAAQ;oBACb,GAAG,EAAE,MAAM;oBACX,GAAG,EAAE,aAAa;oBAClB,EAAE,CAAC;gBACL,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS;oBAAE,OAAO;gBAEhC,MAAM,OAAO,GAAG;oBACd,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;oBAC3B,SAAS,CAAC,CAAC,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;iBAC3C;qBACE,MAAM,CAAC,OAAO,CAAC;qBACf,IAAI,CAAC,IAAI,CAAC,CAAC;gBAEd,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBACnE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;oBACd,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,4BAA4B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACzE,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,YAAY,CAAC;YACf,IAAI,EAAE,mBAAmB;YACzB,WAAW,EACT,4JAA4J;YAC9J,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,6BAA6B;oBAC1C,QAAQ,EAAE,IAAI;iBACf;aACF;YACD,OAAO,EAAE,KAAK,EAAE,IAA4B,EAAE,EAAE;gBAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBACtC,IAAI,CAAC,OAAO;oBAAE,OAAO,sBAAsB,CAAC;gBAE5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBACnE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;oBACd,MAAM,CAAC,IAAI,CAAC,8BAA8B,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;oBACrE,OAAO,aAAa,CAAC;gBACvB,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACjE,OAAO,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACvD,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CACT,iEAAiE,CAClE,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-recall.d.ts","sourceRoot":"","sources":["../../src/hooks/auto-recall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"auto-recall.d.ts","sourceRoot":"","sources":["../../src/hooks/auto-recall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAsDpB"}
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
export function createAutoRecallHook(client, config, logger) {
|
|
2
2
|
return (api) => {
|
|
3
|
-
|
|
4
|
-
api.registerHook('before_agent_start', async (ctx) => {
|
|
3
|
+
api.on('before_agent_start', async (ctx) => {
|
|
5
4
|
try {
|
|
6
5
|
const query = ctx?.prompt ?? ctx?.message ?? ctx?.input ?? '';
|
|
7
|
-
if (!query)
|
|
6
|
+
if (!query || query.length < 5) {
|
|
8
7
|
return;
|
|
8
|
+
}
|
|
9
9
|
const result = await client.searchMemories(config.characterId, query);
|
|
10
10
|
if (result.ok && result.value?.length > 0) {
|
|
11
11
|
const memories = result.value
|
|
12
12
|
.map((m) => m.content ?? m.text ?? m.body ?? '')
|
|
13
13
|
.filter(Boolean)
|
|
14
14
|
.join('\n---\n');
|
|
15
|
-
ctx.prependContext?.(`## HippoDid Memories\n${memories}\n`);
|
|
16
15
|
logger.info(`hippodid: recalled ${result.value.length} memories`);
|
|
16
|
+
return {
|
|
17
|
+
prependContext: `## HippoDid Memories\n${memories}\n`,
|
|
18
|
+
};
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
catch (e) {
|
|
20
22
|
logger.warn(`hippodid: recall error: ${e instanceof Error ? e.message : String(e)}`);
|
|
21
23
|
}
|
|
22
|
-
}
|
|
23
|
-
// Explicit tool: agents can call hippodid:recall directly
|
|
24
|
+
});
|
|
24
25
|
api.registerTool({
|
|
25
26
|
name: 'hippodid:recall',
|
|
26
27
|
description: 'Search HippoDid character memory and return relevant context. Call this at the start of a task to recall relevant memories.',
|
|
@@ -38,9 +39,7 @@ export function createAutoRecallHook(client, config, logger) {
|
|
|
38
39
|
logger.info(`hippodid: recalled ${result.value.length} memories for query: ${query}`);
|
|
39
40
|
return result.value.map((m) => m.content).join('\n\n');
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
-
return 'No memories found.';
|
|
43
|
-
}
|
|
42
|
+
return 'No memories found.';
|
|
44
43
|
},
|
|
45
44
|
});
|
|
46
45
|
logger.info('hippodid: auto-recall hook + hippodid:recall tool registered');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-recall.js","sourceRoot":"","sources":["../../src/hooks/auto-recall.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,MAAoB,EACpB,MAA4D;IAE5D,OAAO,CAAC,GAAQ,EAAE,EAAE;QAClB,
|
|
1
|
+
{"version":3,"file":"auto-recall.js","sourceRoot":"","sources":["../../src/hooks/auto-recall.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,MAAoB,EACpB,MAA4D;IAE5D,OAAO,CAAC,GAAQ,EAAE,EAAE;QAClB,GAAG,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;YAC9C,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,GAAG,EAAE,MAAM,IAAI,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC;gBAC9D,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,OAAO;gBACT,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBACtE,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK;yBAC1B,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;yBACpD,MAAM,CAAC,OAAO,CAAC;yBACf,IAAI,CAAC,SAAS,CAAC,CAAC;oBAEnB,MAAM,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC;oBAClE,OAAO;wBACL,cAAc,EAAE,yBAAyB,QAAQ,IAAI;qBACtD,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,2BAA2B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACxE,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,YAAY,CAAC;YACf,IAAI,EAAE,iBAAiB;YACvB,WAAW,EACT,6HAA6H;YAC/H,IAAI,EAAE;gBACJ;oBACE,IAAI,EAAE,OAAO;oBACb,WAAW,EAAE,8BAA8B;oBAC3C,QAAQ,EAAE,IAAI;iBACf;aACF;YACD,OAAO,EAAE,KAAK,EAAE,IAA4B,EAAE,EAAE;gBAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAClC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBACtE,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzC,MAAM,CAAC,IAAI,CACT,sBAAsB,MAAM,CAAC,KAAK,CAAC,MAAM,wBAAwB,KAAK,EAAE,CACzE,CAAC;oBACF,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACzD,CAAC;gBACD,OAAO,oBAAoB,CAAC;YAC9B,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-flush.d.ts","sourceRoot":"","sources":["../../src/hooks/memory-flush.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"memory-flush.d.ts","sourceRoot":"","sources":["../../src/hooks/memory-flush.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAiBpB"}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
export function createMemoryFlushHook(fileSync, logger) {
|
|
2
|
-
return (
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
return (api) => {
|
|
3
|
+
api.on('before_compaction', async () => {
|
|
4
|
+
try {
|
|
5
|
+
const { synced, changed } = await fileSync.flushNow();
|
|
6
|
+
logger.info(`hippodid: flushed ${synced} files before compaction (${changed} changed)`);
|
|
7
|
+
}
|
|
8
|
+
catch (e) {
|
|
9
|
+
logger.warn(`hippodid: compaction flush failed: ${e instanceof Error ? e.message : 'unknown'}`);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
logger.info('hippodid: memory flush handler registered');
|
|
8
13
|
};
|
|
9
14
|
}
|
|
10
15
|
//# sourceMappingURL=memory-flush.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-flush.js","sourceRoot":"","sources":["../../src/hooks/memory-flush.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CACnC,QAAkB,EAClB,MAA4D;IAE5D,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"memory-flush.js","sourceRoot":"","sources":["../../src/hooks/memory-flush.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CACnC,QAAkB,EAClB,MAA4D;IAE5D,OAAO,CAAC,GAAQ,EAAE,EAAE;QAClB,GAAG,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;YACrC,IAAI,CAAC;gBACH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACtD,MAAM,CAAC,IAAI,CACT,qBAAqB,MAAM,6BAA6B,OAAO,WAAW,CAC3E,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,sCAAsC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CACnF,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-lifecycle.d.ts","sourceRoot":"","sources":["../../src/hooks/session-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"session-lifecycle.d.ts","sourceRoot":"","sources":["../../src/hooks/session-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAoCpB"}
|
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
export function createSessionHooks(fileSync, tierManager, autoRecall, logger) {
|
|
2
|
-
return (
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
return (api) => {
|
|
3
|
+
api.on('session_start', async () => {
|
|
4
|
+
try {
|
|
5
|
+
await tierManager.initialize();
|
|
6
|
+
if (!tierManager.shouldHydrateOnStart(autoRecall)) {
|
|
7
|
+
logger.info('hippodid: session start hydration skipped because auto-recall is active');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const hydrated = await fileSync.hydrateFromCloud();
|
|
11
|
+
logger.info(`hippodid: session started, hydrated ${hydrated} files`);
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
logger.warn(`hippodid: session start error: ${e instanceof Error ? e.message : 'unknown'}`);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
api.on('session_end', async () => {
|
|
18
|
+
try {
|
|
19
|
+
const { synced, changed } = await fileSync.flushNow();
|
|
20
|
+
logger.info(`hippodid: session ended, flushed ${synced} files (${changed} changed)`);
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
logger.warn(`hippodid: session end error: ${e instanceof Error ? e.message : 'unknown'}`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
logger.info('hippodid: session lifecycle hooks registered');
|
|
7
27
|
};
|
|
8
28
|
}
|
|
9
29
|
//# sourceMappingURL=session-lifecycle.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-lifecycle.js","sourceRoot":"","sources":["../../src/hooks/session-lifecycle.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,kBAAkB,CAChC,QAAkB,EAClB,WAAwB,EACxB,UAAmB,EACnB,MAA4D;IAE5D,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"session-lifecycle.js","sourceRoot":"","sources":["../../src/hooks/session-lifecycle.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,kBAAkB,CAChC,QAAkB,EAClB,WAAwB,EACxB,UAAmB,EACnB,MAA4D;IAE5D,OAAO,CAAC,GAAQ,EAAE,EAAE;QAClB,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;YACjC,IAAI,CAAC;gBACH,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC;gBAC/B,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;oBAClD,MAAM,CAAC,IAAI,CACT,yEAAyE,CAC1E,CAAC;oBACF,OAAO;gBACT,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,CAAC;gBACnD,MAAM,CAAC,IAAI,CAAC,uCAAuC,QAAQ,QAAQ,CAAC,CAAC;YACvE,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,kCAAkC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,aAAa,EAAE,KAAK,IAAI,EAAE;YAC/B,IAAI,CAAC;gBACH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACtD,MAAM,CAAC,IAAI,CACT,oCAAoC,MAAM,WAAW,OAAO,WAAW,CACxE,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,gCAAgC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAC7E,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IAC9D,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;kBAqBgB,GAAG,GAAG,IAAI;;AAH1B,wBA2GE"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
2
3
|
import { resolve } from 'node:path';
|
|
3
4
|
import { createClient } from './hippodid-client.js';
|
|
4
5
|
import { createFileSync } from './file-sync.js';
|
|
@@ -8,23 +9,29 @@ import { createMemoryFlushHook } from './hooks/memory-flush.js';
|
|
|
8
9
|
import { createSessionHooks } from './hooks/session-lifecycle.js';
|
|
9
10
|
import { createAutoRecallHook } from './hooks/auto-recall.js';
|
|
10
11
|
import { createAutoCaptureHook } from './hooks/auto-capture.js';
|
|
11
|
-
const
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
const VERSION = (require('../package.json').version) ?? '0.0.0-dev';
|
|
14
|
+
let hasInitialized = false;
|
|
12
15
|
export default {
|
|
13
16
|
id: 'hippodid',
|
|
14
17
|
register(api) {
|
|
15
18
|
try {
|
|
16
|
-
|
|
19
|
+
if (hasInitialized) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const config = resolveConfig(api.pluginConfig ?? api.config ?? {});
|
|
17
23
|
const logger = api.logger ?? {
|
|
18
24
|
info: (msg) => console.log(msg),
|
|
19
25
|
warn: (msg) => console.warn(msg),
|
|
20
26
|
error: (msg) => console.error(msg),
|
|
21
27
|
};
|
|
22
|
-
const apiKey = config
|
|
23
|
-
const characterId = config
|
|
28
|
+
const apiKey = config.apiKey.trim();
|
|
29
|
+
const characterId = config.characterId.trim();
|
|
24
30
|
if (!apiKey || !characterId) {
|
|
25
31
|
logger.warn('HippoDid: apiKey and characterId required — configure in openclaw.json');
|
|
26
32
|
return;
|
|
27
33
|
}
|
|
34
|
+
hasInitialized = true;
|
|
28
35
|
const client = createClient(apiKey, config.baseUrl);
|
|
29
36
|
const tierManager = createTierManager(client, characterId, logger);
|
|
30
37
|
const watchPaths = resolveWatchPaths(config);
|
|
@@ -92,26 +99,119 @@ function resolveConfig(raw) {
|
|
|
92
99
|
};
|
|
93
100
|
}
|
|
94
101
|
function registerCommands(api, config, client, fileSync, tierManager, logger) {
|
|
102
|
+
const getStatusText = async () => {
|
|
103
|
+
const tier = tierManager.getCurrentTier();
|
|
104
|
+
const statusResult = await client.getSyncStatus(config.characterId);
|
|
105
|
+
const lines = [
|
|
106
|
+
'HippoDid status:',
|
|
107
|
+
`- Character: ${config.characterId}`,
|
|
108
|
+
`- Tier: ${tier.tier}`,
|
|
109
|
+
`- Auto-Recall: ${tier.features.autoRecallAvailable ? 'available' : 'unavailable'} (config: ${config.autoRecall ? 'ON' : 'OFF'})`,
|
|
110
|
+
`- Auto-Capture: ${tier.features.autoCaptureAvailable ? 'available' : 'unavailable'} (config: ${config.autoCapture ? 'ON' : 'OFF'})`,
|
|
111
|
+
];
|
|
112
|
+
if (statusResult.ok) {
|
|
113
|
+
lines.push(`- Synced sources: ${statusResult.value.entries.length}`);
|
|
114
|
+
for (const entry of statusResult.value.entries) {
|
|
115
|
+
lines.push(` - ${entry.sourcePath} (${entry.label}) — last sync: ${entry.lastSyncedAt}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
lines.push(`- Sync status: unavailable (${statusResult.error.message})`);
|
|
120
|
+
}
|
|
121
|
+
return lines.join('\n');
|
|
122
|
+
};
|
|
123
|
+
const runImport = async (workspaceOverride) => {
|
|
124
|
+
const { readdir } = await import('node:fs/promises');
|
|
125
|
+
const { join, extname } = await import('node:path');
|
|
126
|
+
const { createHash } = await import('node:crypto');
|
|
127
|
+
const workspacePath = workspaceOverride
|
|
128
|
+
? resolve(workspaceOverride)
|
|
129
|
+
: resolve(process.cwd());
|
|
130
|
+
const memoryDir = join(workspacePath, 'memory');
|
|
131
|
+
const memoryMd = join(workspacePath, 'MEMORY.md');
|
|
132
|
+
const filesToImport = [];
|
|
133
|
+
try {
|
|
134
|
+
const entries = await readdir(memoryDir);
|
|
135
|
+
for (const entry of entries) {
|
|
136
|
+
if (extname(entry) === '.md') {
|
|
137
|
+
filesToImport.push({
|
|
138
|
+
path: join(memoryDir, entry),
|
|
139
|
+
label: 'workspace-memory',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// memory dir may not exist
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
await readFile(memoryMd);
|
|
149
|
+
filesToImport.push({ path: memoryMd, label: 'MEMORY.md' });
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// MEMORY.md may not exist
|
|
153
|
+
}
|
|
154
|
+
if (filesToImport.length === 0) {
|
|
155
|
+
return 'hippodid: no memory files found to import';
|
|
156
|
+
}
|
|
157
|
+
logger.info(`hippodid: importing ${filesToImport.length} files from ${workspacePath}...`);
|
|
158
|
+
let imported = 0;
|
|
159
|
+
for (const file of filesToImport) {
|
|
160
|
+
try {
|
|
161
|
+
const content = await readFile(file.path);
|
|
162
|
+
const hash = createHash('sha256').update(content).digest('hex');
|
|
163
|
+
const base64 = content.toString('base64');
|
|
164
|
+
const result = await client.syncFile(config.characterId, file.path, file.label, base64, hash);
|
|
165
|
+
if (result.ok)
|
|
166
|
+
imported++;
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
logger.warn(`hippodid: import failed for ${file.path}: ${e instanceof Error ? e.message : 'unknown'}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return `hippodid: import complete — ${imported}/${filesToImport.length} files imported`;
|
|
173
|
+
};
|
|
174
|
+
api.registerCommand({
|
|
175
|
+
name: 'hippodid',
|
|
176
|
+
description: 'Show HippoDid status and run sync/import actions.',
|
|
177
|
+
acceptsArgs: true,
|
|
178
|
+
handler: async (ctx) => {
|
|
179
|
+
const args = ctx?.args?.trim() ?? '';
|
|
180
|
+
const [action = 'status', ...rest] = args.split(/\s+/).filter(Boolean);
|
|
181
|
+
if (action === 'status') {
|
|
182
|
+
return { text: await getStatusText() };
|
|
183
|
+
}
|
|
184
|
+
if (action === 'sync') {
|
|
185
|
+
logger.info('hippodid: manual sync triggered...');
|
|
186
|
+
const { synced, changed } = await fileSync.flushNow();
|
|
187
|
+
return {
|
|
188
|
+
text: `hippodid: manual sync complete — ${synced} files (${changed} changed)`,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
if (action === 'import') {
|
|
192
|
+
const workspace = rest.join(' ').trim() || undefined;
|
|
193
|
+
return { text: await runImport(workspace) };
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
text: [
|
|
197
|
+
'HippoDid commands:',
|
|
198
|
+
'',
|
|
199
|
+
'/hippodid status',
|
|
200
|
+
'/hippodid sync',
|
|
201
|
+
'/hippodid import [workspace-path]',
|
|
202
|
+
].join('\n'),
|
|
203
|
+
};
|
|
204
|
+
},
|
|
205
|
+
});
|
|
95
206
|
api.registerTool({
|
|
96
207
|
name: 'hippodid:status',
|
|
97
208
|
description: 'Show HippoDid tier, sync status, and watched paths',
|
|
98
209
|
execute: async () => {
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
logger.info(`Character: ${config.characterId}`);
|
|
103
|
-
logger.info(`Tier: ${tier.tier}`);
|
|
104
|
-
logger.info(`Auto-Recall: ${tier.features.autoRecallAvailable ? 'available' : 'unavailable'} (config: ${config.autoRecall ? 'ON' : 'OFF'})`);
|
|
105
|
-
logger.info(`Auto-Capture: ${tier.features.autoCaptureAvailable ? 'available' : 'unavailable'} (config: ${config.autoCapture ? 'ON' : 'OFF'})`);
|
|
106
|
-
if (statusResult.ok) {
|
|
107
|
-
logger.info(`Synced sources: ${statusResult.value.entries.length}`);
|
|
108
|
-
for (const entry of statusResult.value.entries) {
|
|
109
|
-
logger.info(` ${entry.sourcePath} (${entry.label}) — last sync: ${entry.lastSyncedAt}`);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
logger.warn(`Could not fetch sync status: ${statusResult.error.message}`);
|
|
210
|
+
const text = await getStatusText();
|
|
211
|
+
for (const line of text.split('\n')) {
|
|
212
|
+
logger.info(line);
|
|
114
213
|
}
|
|
214
|
+
return text;
|
|
115
215
|
},
|
|
116
216
|
});
|
|
117
217
|
api.registerTool({
|
|
@@ -120,7 +220,9 @@ function registerCommands(api, config, client, fileSync, tierManager, logger) {
|
|
|
120
220
|
execute: async () => {
|
|
121
221
|
logger.info('hippodid: manual sync triggered...');
|
|
122
222
|
const { synced, changed } = await fileSync.flushNow();
|
|
123
|
-
|
|
223
|
+
const text = `hippodid: manual sync complete — ${synced} files (${changed} changed)`;
|
|
224
|
+
logger.info(text);
|
|
225
|
+
return text;
|
|
124
226
|
},
|
|
125
227
|
});
|
|
126
228
|
api.registerTool({
|
|
@@ -134,56 +236,9 @@ function registerCommands(api, config, client, fileSync, tierManager, logger) {
|
|
|
134
236
|
},
|
|
135
237
|
],
|
|
136
238
|
execute: async (args) => {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const workspacePath = args['workspace']
|
|
141
|
-
? resolve(args['workspace'])
|
|
142
|
-
: resolve(process.cwd());
|
|
143
|
-
const memoryDir = join(workspacePath, 'memory');
|
|
144
|
-
const memoryMd = join(workspacePath, 'MEMORY.md');
|
|
145
|
-
const filesToImport = [];
|
|
146
|
-
try {
|
|
147
|
-
const entries = await readdir(memoryDir);
|
|
148
|
-
for (const entry of entries) {
|
|
149
|
-
if (extname(entry) === '.md') {
|
|
150
|
-
filesToImport.push({
|
|
151
|
-
path: join(memoryDir, entry),
|
|
152
|
-
label: 'workspace-memory',
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
// memory dir may not exist
|
|
159
|
-
}
|
|
160
|
-
try {
|
|
161
|
-
await readFile(memoryMd);
|
|
162
|
-
filesToImport.push({ path: memoryMd, label: 'MEMORY.md' });
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
// MEMORY.md may not exist
|
|
166
|
-
}
|
|
167
|
-
if (filesToImport.length === 0) {
|
|
168
|
-
logger.info('hippodid: no memory files found to import');
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
logger.info(`hippodid: importing ${filesToImport.length} files from ${workspacePath}...`);
|
|
172
|
-
let imported = 0;
|
|
173
|
-
for (const file of filesToImport) {
|
|
174
|
-
try {
|
|
175
|
-
const content = await readFile(file.path);
|
|
176
|
-
const hash = createHash('sha256').update(content).digest('hex');
|
|
177
|
-
const base64 = content.toString('base64');
|
|
178
|
-
const result = await client.syncFile(config.characterId, file.path, file.label, base64, hash);
|
|
179
|
-
if (result.ok)
|
|
180
|
-
imported++;
|
|
181
|
-
}
|
|
182
|
-
catch (e) {
|
|
183
|
-
logger.warn(`hippodid: import failed for ${file.path}: ${e instanceof Error ? e.message : 'unknown'}`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
logger.info(`hippodid: import complete — ${imported}/${filesToImport.length} files imported`);
|
|
239
|
+
const text = await runImport(args['workspace']);
|
|
240
|
+
logger.info(text);
|
|
241
|
+
return text;
|
|
187
242
|
},
|
|
188
243
|
});
|
|
189
244
|
}
|