@hippodid/openclaw-plugin 1.0.0 → 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.
Files changed (41) hide show
  1. package/dist/file-sync.d.ts +18 -0
  2. package/dist/file-sync.d.ts.map +1 -0
  3. package/dist/file-sync.js +172 -0
  4. package/dist/file-sync.js.map +1 -0
  5. package/dist/hippodid-client.d.ts +11 -0
  6. package/dist/hippodid-client.d.ts.map +1 -0
  7. package/dist/hippodid-client.js +155 -0
  8. package/dist/hippodid-client.js.map +1 -0
  9. package/dist/hooks/auto-capture.d.ts +7 -0
  10. package/dist/hooks/auto-capture.d.ts.map +1 -0
  11. package/dist/hooks/auto-capture.js +45 -0
  12. package/dist/hooks/auto-capture.js.map +1 -0
  13. package/dist/hooks/auto-recall.d.ts +7 -0
  14. package/dist/hooks/auto-recall.d.ts.map +1 -0
  15. package/dist/hooks/auto-recall.js +46 -0
  16. package/dist/hooks/auto-recall.js.map +1 -0
  17. package/dist/hooks/memory-flush.d.ts +7 -0
  18. package/dist/hooks/memory-flush.d.ts.map +1 -0
  19. package/dist/hooks/memory-flush.js +14 -0
  20. package/dist/hooks/memory-flush.js.map +1 -0
  21. package/dist/hooks/session-lifecycle.d.ts +8 -0
  22. package/dist/hooks/session-lifecycle.d.ts.map +1 -0
  23. package/dist/hooks/session-lifecycle.js +29 -0
  24. package/dist/hooks/session-lifecycle.js.map +1 -0
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +164 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/tier-manager.d.ts +16 -0
  30. package/dist/tier-manager.d.ts.map +1 -0
  31. package/dist/tier-manager.js +57 -0
  32. package/dist/tier-manager.js.map +1 -0
  33. package/dist/types.d.ts +123 -0
  34. package/dist/types.d.ts.map +1 -0
  35. package/dist/types.js +8 -0
  36. package/dist/types.js.map +1 -0
  37. package/dist/workspace-detector.d.ts +5 -0
  38. package/dist/workspace-detector.d.ts.map +1 -0
  39. package/dist/workspace-detector.js +88 -0
  40. package/dist/workspace-detector.js.map +1 -0
  41. package/package.json +8 -2
@@ -0,0 +1,18 @@
1
+ import type { HippoDidClient } from './hippodid-client.js';
2
+ import type { PluginConfig, WatchPath } from './types.js';
3
+ export interface FileSync {
4
+ start(): void;
5
+ stop(): void;
6
+ flushNow(): Promise<{
7
+ synced: number;
8
+ changed: number;
9
+ }>;
10
+ hydrateFromCloud(): Promise<number>;
11
+ }
12
+ interface Logger {
13
+ info(message: string): void;
14
+ warn(message: string): void;
15
+ }
16
+ export declare function createFileSync(client: HippoDidClient, config: PluginConfig, watchPaths: WatchPath[], logger: Logger, effectiveSyncIntervalSeconds?: number): FileSync;
17
+ export {};
18
+ //# sourceMappingURL=file-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-sync.d.ts","sourceRoot":"","sources":["../src/file-sync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAqB,SAAS,EAAE,MAAM,YAAY,CAAC;AAE7E,MAAM,WAAW,QAAQ;IACvB,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC;AAED,UAAU,MAAM;IACd,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,SAAS,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,4BAA4B,CAAC,EAAE,MAAM,GACpC,QAAQ,CAgOV"}
@@ -0,0 +1,172 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFile, writeFile, readdir, stat } from 'node:fs/promises';
3
+ import { watch } from 'node:fs';
4
+ import { resolve, join, extname } from 'node:path';
5
+ export function createFileSync(client, config, watchPaths, logger, effectiveSyncIntervalSeconds) {
6
+ const syncIntervalMs = (effectiveSyncIntervalSeconds ?? config.syncIntervalSeconds) * 1000;
7
+ const tracking = new Map();
8
+ const watchers = [];
9
+ let debounceTimer = null;
10
+ let pendingChanges = new Set();
11
+ async function computeHash(filePath) {
12
+ const content = await readFile(filePath);
13
+ return createHash('sha256').update(content).digest('hex');
14
+ }
15
+ function toBase64(buffer) {
16
+ return buffer.toString('base64');
17
+ }
18
+ function fromBase64(content) {
19
+ return Buffer.from(content, 'base64').toString('utf-8');
20
+ }
21
+ async function resolveFilesForPath(wp) {
22
+ try {
23
+ const s = await stat(wp.path);
24
+ if (s.isDirectory()) {
25
+ const entries = await readdir(wp.path);
26
+ return entries
27
+ .filter((e) => extname(e) === '.md')
28
+ .map((e) => resolve(join(wp.path, e)));
29
+ }
30
+ return [resolve(wp.path)];
31
+ }
32
+ catch {
33
+ return [];
34
+ }
35
+ }
36
+ async function resolveAllFiles() {
37
+ const files = [];
38
+ const seen = new Set();
39
+ for (const wp of watchPaths) {
40
+ const resolved = await resolveFilesForPath(wp);
41
+ for (const filePath of resolved) {
42
+ if (!seen.has(filePath)) {
43
+ seen.add(filePath);
44
+ files.push({ filePath, label: wp.label });
45
+ }
46
+ }
47
+ }
48
+ return files;
49
+ }
50
+ async function syncFile(filePath, label) {
51
+ try {
52
+ const content = await readFile(filePath);
53
+ const hash = createHash('sha256').update(content).digest('hex');
54
+ const existing = tracking.get(filePath);
55
+ if (existing && existing.hash === hash) {
56
+ return false;
57
+ }
58
+ const base64Content = toBase64(content);
59
+ const result = await client.syncFile(config.characterId, filePath, label, base64Content, hash);
60
+ if (result.ok) {
61
+ tracking.set(filePath, { hash, lastSyncedAt: new Date() });
62
+ return result.value.changed;
63
+ }
64
+ logger.warn(`hippodid: sync failed for ${filePath}: ${result.error.message}`);
65
+ return false;
66
+ }
67
+ catch (e) {
68
+ logger.warn(`hippodid: error syncing ${filePath}: ${e instanceof Error ? e.message : 'unknown'}`);
69
+ return false;
70
+ }
71
+ }
72
+ async function runSync() {
73
+ const files = await resolveAllFiles();
74
+ let synced = 0;
75
+ let changed = 0;
76
+ for (const { filePath, label } of files) {
77
+ const wasChanged = await syncFile(filePath, label);
78
+ synced++;
79
+ if (wasChanged)
80
+ changed++;
81
+ }
82
+ logger.info(`hippodid: synced ${synced} files (${changed} changed, ${synced - changed} unchanged)`);
83
+ return { synced, changed };
84
+ }
85
+ function scheduleDebouncedSync() {
86
+ if (debounceTimer) {
87
+ clearTimeout(debounceTimer);
88
+ }
89
+ debounceTimer = setTimeout(() => {
90
+ debounceTimer = null;
91
+ runSync().catch((e) => {
92
+ logger.warn(`hippodid: debounced sync error: ${e instanceof Error ? e.message : 'unknown'}`);
93
+ });
94
+ }, syncIntervalMs);
95
+ }
96
+ function onFileChange(filePath) {
97
+ pendingChanges.add(filePath);
98
+ scheduleDebouncedSync();
99
+ }
100
+ return {
101
+ start() {
102
+ for (const wp of watchPaths) {
103
+ try {
104
+ const watcher = watch(wp.path, { persistent: false }, (_event, filename) => {
105
+ if (filename && extname(filename) === '.md') {
106
+ const fullPath = resolve(join(wp.path.endsWith('.md') ? resolve(wp.path, '..') : wp.path, filename));
107
+ onFileChange(fullPath);
108
+ }
109
+ else if (wp.path.endsWith('.md')) {
110
+ onFileChange(resolve(wp.path));
111
+ }
112
+ });
113
+ watcher.on('error', (err) => {
114
+ logger.warn(`hippodid: watcher error for ${wp.path}: ${err instanceof Error ? err.message : 'unknown'}`);
115
+ });
116
+ watchers.push(watcher);
117
+ }
118
+ catch (e) {
119
+ logger.warn(`hippodid: failed to watch ${wp.path}: ${e instanceof Error ? e.message : 'unknown'}`);
120
+ }
121
+ }
122
+ scheduleDebouncedSync();
123
+ },
124
+ stop() {
125
+ for (const w of watchers) {
126
+ w.close();
127
+ }
128
+ watchers.length = 0;
129
+ if (debounceTimer) {
130
+ clearTimeout(debounceTimer);
131
+ debounceTimer = null;
132
+ }
133
+ pendingChanges.clear();
134
+ },
135
+ async flushNow() {
136
+ if (debounceTimer) {
137
+ clearTimeout(debounceTimer);
138
+ debounceTimer = null;
139
+ }
140
+ return runSync();
141
+ },
142
+ async hydrateFromCloud() {
143
+ const files = await resolveAllFiles();
144
+ let hydrated = 0;
145
+ for (const { filePath } of files) {
146
+ try {
147
+ const result = await client.getLatestSync(config.characterId, filePath);
148
+ if (!result.ok) {
149
+ logger.warn(`hippodid: hydration lookup failed for ${filePath}: ${result.error.message}`);
150
+ continue;
151
+ }
152
+ if (result.value === null) {
153
+ continue;
154
+ }
155
+ const cloudContent = fromBase64(result.value.fileContent);
156
+ await writeFile(filePath, cloudContent, 'utf-8');
157
+ const hash = createHash('sha256')
158
+ .update(Buffer.from(cloudContent))
159
+ .digest('hex');
160
+ tracking.set(filePath, { hash, lastSyncedAt: new Date() });
161
+ hydrated++;
162
+ }
163
+ catch (e) {
164
+ logger.warn(`hippodid: hydration error for ${filePath}: ${e instanceof Error ? e.message : 'unknown'}`);
165
+ }
166
+ }
167
+ logger.info(`hippodid: hydrated ${hydrated} files from cloud`);
168
+ return hydrated;
169
+ },
170
+ };
171
+ }
172
+ //# sourceMappingURL=file-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-sync.js","sourceRoot":"","sources":["../src/file-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Result, TierInfo, SyncResponse, SyncLatestResponse, SyncStatusResponse, SearchResult } from './types.js';
2
+ export interface HippoDidClient {
3
+ getTier(characterId: string): Promise<Result<TierInfo>>;
4
+ syncFile(characterId: string, sourcePath: string, label: string, fileContent: string, checksum: string): Promise<Result<SyncResponse>>;
5
+ getLatestSync(characterId: string, sourcePath: string): Promise<Result<SyncLatestResponse | null>>;
6
+ getSyncStatus(characterId: string): Promise<Result<SyncStatusResponse>>;
7
+ searchMemories(characterId: string, query: string, topK?: number): Promise<Result<SearchResult[]>>;
8
+ addMemory(characterId: string, content: string, source?: string): Promise<Result<void>>;
9
+ }
10
+ export declare function createClient(apiKey: string, baseUrl: string): HippoDidClient;
11
+ //# sourceMappingURL=hippodid-client.d.ts.map
@@ -0,0 +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,CAuO5E"}
@@ -0,0 +1,155 @@
1
+ import { ok, err } from './types.js';
2
+ const MAX_RETRIES = 3;
3
+ const REQUEST_TIMEOUT_MS = 10_000;
4
+ const TIER_CACHE_TTL_MS = 5 * 60 * 1000;
5
+ export function createClient(apiKey, baseUrl) {
6
+ let tierCache = null;
7
+ function headers() {
8
+ return {
9
+ 'X-Api-Key': apiKey,
10
+ 'Content-Type': 'application/json',
11
+ };
12
+ }
13
+ function isRetryable(status) {
14
+ return status === 429 || status >= 500;
15
+ }
16
+ function toApiError(status, message) {
17
+ return { status, message, retryable: isRetryable(status) };
18
+ }
19
+ async function fetchWithTimeout(url, init) {
20
+ const controller = new AbortController();
21
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
22
+ try {
23
+ return await fetch(url, { ...init, signal: controller.signal });
24
+ }
25
+ finally {
26
+ clearTimeout(timeout);
27
+ }
28
+ }
29
+ async function request(method, path, body) {
30
+ const url = `${baseUrl}${path}`;
31
+ let lastError = null;
32
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
33
+ if (attempt > 0) {
34
+ const delay = Math.min(1000 * Math.pow(2, attempt - 1), 8000);
35
+ await new Promise((r) => setTimeout(r, delay));
36
+ }
37
+ try {
38
+ const resp = await fetchWithTimeout(url, {
39
+ method,
40
+ headers: headers(),
41
+ body: body !== undefined ? JSON.stringify(body) : undefined,
42
+ });
43
+ if (!resp.ok) {
44
+ const errorText = await resp.text().catch(() => 'Unknown error');
45
+ lastError = toApiError(resp.status, errorText);
46
+ if (!isRetryable(resp.status)) {
47
+ return err(lastError);
48
+ }
49
+ continue;
50
+ }
51
+ if (resp.status === 204) {
52
+ return ok(undefined);
53
+ }
54
+ const data = (await resp.json());
55
+ return ok(data);
56
+ }
57
+ catch (e) {
58
+ const message = e instanceof Error ? e.message : 'Unknown network error';
59
+ lastError = toApiError(0, message);
60
+ if (attempt < MAX_RETRIES) {
61
+ continue;
62
+ }
63
+ }
64
+ }
65
+ return err(lastError ?? toApiError(0, 'Request failed after retries'));
66
+ }
67
+ function mapTierResponse(raw) {
68
+ return {
69
+ tier: raw.tier,
70
+ features: {
71
+ autoRecallAvailable: raw.features.auto_recall_available,
72
+ autoCaptureAvailable: raw.features.auto_capture_available,
73
+ minSyncIntervalSeconds: raw.features.min_sync_interval_seconds,
74
+ },
75
+ };
76
+ }
77
+ function mapSyncResponse(raw) {
78
+ return {
79
+ status: raw.status,
80
+ snapshotId: raw.snapshot_id,
81
+ changed: raw.changed,
82
+ };
83
+ }
84
+ function mapSyncLatestResponse(raw) {
85
+ return {
86
+ sourcePath: raw.source_path,
87
+ fileContent: raw.file_content,
88
+ snapshotId: raw.snapshot_id,
89
+ syncedAt: raw.synced_at,
90
+ };
91
+ }
92
+ return {
93
+ async getTier(characterId) {
94
+ const now = Date.now();
95
+ if (tierCache && now - tierCache.fetchedAt < TIER_CACHE_TTL_MS) {
96
+ return ok(tierCache.info);
97
+ }
98
+ const result = await request('GET', `/v1/tier?characterId=${encodeURIComponent(characterId)}`);
99
+ if (!result.ok)
100
+ return result;
101
+ const info = mapTierResponse(result.value);
102
+ tierCache = { info, fetchedAt: now };
103
+ return ok(info);
104
+ },
105
+ async syncFile(characterId, sourcePath, label, fileContent, checksum) {
106
+ const result = await request('POST', `/v1/characters/${encodeURIComponent(characterId)}/sync`, {
107
+ source_path: sourcePath,
108
+ label,
109
+ file_content: fileContent,
110
+ checksum,
111
+ });
112
+ if (!result.ok)
113
+ return result;
114
+ return ok(mapSyncResponse(result.value));
115
+ },
116
+ async getLatestSync(characterId, sourcePath) {
117
+ const result = await request('GET', `/v1/characters/${encodeURIComponent(characterId)}/sync/latest?source_path=${encodeURIComponent(sourcePath)}`);
118
+ if (!result.ok) {
119
+ if (result.error.status === 404) {
120
+ return ok(null);
121
+ }
122
+ return result;
123
+ }
124
+ return ok(mapSyncLatestResponse(result.value));
125
+ },
126
+ async getSyncStatus(characterId) {
127
+ const result = await request('GET', `/v1/characters/${encodeURIComponent(characterId)}/sync/status`);
128
+ if (!result.ok)
129
+ return result;
130
+ return ok({
131
+ entries: result.value.entries.map((e) => ({
132
+ sourcePath: e.source_path,
133
+ label: e.label,
134
+ lastSyncedAt: e.last_synced_at,
135
+ snapshotId: e.snapshot_id,
136
+ })),
137
+ });
138
+ },
139
+ async searchMemories(characterId, query, topK) {
140
+ const result = await request('POST', `/v1/characters/${encodeURIComponent(characterId)}/search`, { query, top_k: topK ?? 5 });
141
+ if (!result.ok)
142
+ return result;
143
+ return ok(result.value.map((r) => ({
144
+ content: r.content,
145
+ category: r.category,
146
+ score: r.score,
147
+ createdAt: r.created_at,
148
+ })));
149
+ },
150
+ async addMemory(characterId, content, source) {
151
+ return request('POST', `/v1/characters/${encodeURIComponent(characterId)}/memories`, { content, source: source ?? 'openclaw-plugin' });
152
+ },
153
+ };
154
+ }
155
+ //# sourceMappingURL=hippodid-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hippodid-client.js","sourceRoot":"","sources":["../src/hippodid-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { HippoDidClient } from '../hippodid-client.js';
2
+ import type { PluginConfig, OpenClawPluginAPI } from '../types.js';
3
+ export declare function createAutoCaptureHook(client: HippoDidClient, config: PluginConfig, logger: {
4
+ info(msg: string): void;
5
+ warn(msg: string): void;
6
+ }): (api: OpenClawPluginAPI) => void;
7
+ //# sourceMappingURL=auto-capture.d.ts.map
@@ -0,0 +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,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEnE,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,iBAAiB,KAAK,IAAI,CA8BlC"}
@@ -0,0 +1,45 @@
1
+ export function createAutoCaptureHook(client, config, logger) {
2
+ return (api) => {
3
+ api.hooks.on('agent_end', (...args) => {
4
+ try {
5
+ const exchange = extractExchange(args);
6
+ if (!exchange)
7
+ return;
8
+ client
9
+ .addMemory(config.characterId, exchange, 'openclaw-auto-capture')
10
+ .then((result) => {
11
+ if (result.ok) {
12
+ logger.info('hippodid: captured exchange for memory extraction');
13
+ }
14
+ else {
15
+ logger.warn(`hippodid: capture failed: ${result.error.message}`);
16
+ }
17
+ })
18
+ .catch((e) => {
19
+ logger.warn(`hippodid: capture error: ${e instanceof Error ? e.message : 'unknown'}`);
20
+ });
21
+ }
22
+ catch (e) {
23
+ logger.warn(`hippodid: capture hook error: ${e instanceof Error ? e.message : 'unknown'}`);
24
+ }
25
+ });
26
+ };
27
+ }
28
+ function extractExchange(args) {
29
+ if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {
30
+ const event = args[0];
31
+ const userMsg = typeof event['userMessage'] === 'string' ? event['userMessage'] : '';
32
+ const agentResp = typeof event['agentResponse'] === 'string' ? event['agentResponse'] : '';
33
+ if (userMsg || agentResp) {
34
+ return `User: ${userMsg}\n\nAgent: ${agentResp}`;
35
+ }
36
+ if (typeof event['content'] === 'string')
37
+ return event['content'];
38
+ if (typeof event['text'] === 'string')
39
+ return event['text'];
40
+ }
41
+ if (typeof args[0] === 'string')
42
+ return args[0];
43
+ return null;
44
+ }
45
+ //# sourceMappingURL=auto-capture.js.map
@@ -0,0 +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,GAAsB,EAAE,EAAE;QAChC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;YAC/C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;gBACvC,IAAI,CAAC,QAAQ;oBAAE,OAAO;gBAEtB,MAAM;qBACH,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,EAAE,uBAAuB,CAAC;qBAChE,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;oBACf,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;wBACd,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;oBACnE,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,IAAI,CACT,6BAA6B,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CACpD,CAAC;oBACJ,CAAC;gBACH,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBACX,MAAM,CAAC,IAAI,CACT,4BAA4B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CACzE,CAAC;gBACJ,CAAC,CAAC,CAAC;YACP,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,iCAAiC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAC9E,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,IAAe;IACtC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAA4B,CAAC;QAEjD,MAAM,OAAO,GACX,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,SAAS,GACb,OAAO,KAAK,CAAC,eAAe,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE3E,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;YACzB,OAAO,SAAS,OAAO,cAAc,SAAS,EAAE,CAAC;QACnD,CAAC;QAED,IAAI,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC;QAClE,IAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { HippoDidClient } from '../hippodid-client.js';
2
+ import type { PluginConfig, OpenClawPluginAPI } from '../types.js';
3
+ export declare function createAutoRecallHook(client: HippoDidClient, config: PluginConfig, logger: {
4
+ info(msg: string): void;
5
+ warn(msg: string): void;
6
+ }): (api: OpenClawPluginAPI) => void;
7
+ //# sourceMappingURL=auto-recall.d.ts.map
@@ -0,0 +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,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEnE,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,iBAAiB,KAAK,IAAI,CAoClC"}
@@ -0,0 +1,46 @@
1
+ export function createAutoRecallHook(client, config, logger) {
2
+ return (api) => {
3
+ api.hooks.on('before_agent_start', async (...args) => {
4
+ try {
5
+ const userMessage = extractUserMessage(args);
6
+ if (!userMessage)
7
+ return;
8
+ const result = await client.searchMemories(config.characterId, userMessage, 5);
9
+ if (!result.ok) {
10
+ logger.warn(`hippodid: recall search failed: ${result.error.message}`);
11
+ return;
12
+ }
13
+ const memories = result.value;
14
+ if (memories.length === 0) {
15
+ logger.info('hippodid: no relevant memories found');
16
+ return;
17
+ }
18
+ const contextBlock = formatMemoriesBlock(memories);
19
+ api.context.prepend(contextBlock);
20
+ logger.info(`hippodid: recalled ${memories.length} memories for context`);
21
+ }
22
+ catch (e) {
23
+ logger.warn(`hippodid: recall hook error: ${e instanceof Error ? e.message : 'unknown'}`);
24
+ }
25
+ });
26
+ };
27
+ }
28
+ function extractUserMessage(args) {
29
+ if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {
30
+ const event = args[0];
31
+ if (typeof event['message'] === 'string')
32
+ return event['message'];
33
+ if (typeof event['content'] === 'string')
34
+ return event['content'];
35
+ if (typeof event['text'] === 'string')
36
+ return event['text'];
37
+ }
38
+ if (typeof args[0] === 'string')
39
+ return args[0];
40
+ return null;
41
+ }
42
+ function formatMemoriesBlock(memories) {
43
+ const lines = memories.map((m) => `- [Category: ${m.category}] ${m.content}`);
44
+ return `<hippodid-memories>\n${lines.join('\n')}\n</hippodid-memories>`;
45
+ }
46
+ //# sourceMappingURL=auto-recall.js.map
@@ -0,0 +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,GAAsB,EAAE,EAAE;QAChC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;YAC9D,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAC7C,IAAI,CAAC,WAAW;oBAAE,OAAO;gBAEzB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CACxC,MAAM,CAAC,WAAW,EAClB,WAAW,EACX,CAAC,CACF,CAAC;gBAEF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CACT,mCAAmC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAC1D,CAAC;oBACF,OAAO;gBACT,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;gBAC9B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;oBACpD,OAAO;gBACT,CAAC;gBAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;gBACnD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC,sBAAsB,QAAQ,CAAC,MAAM,uBAAuB,CAAC,CAAC;YAC5E,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;IACL,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAe;IACzC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAA4B,CAAC;QACjD,IAAI,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC;QAClE,IAAI,OAAO,KAAK,CAAC,SAAS,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC;QAClE,IAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC;AAOD,SAAS,mBAAmB,CAAC,QAAuB;IAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,OAAO,EAAE,CAClD,CAAC;IACF,OAAO,wBAAwB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { FileSync } from '../file-sync.js';
2
+ import type { OpenClawPluginAPI } from '../types.js';
3
+ export declare function createMemoryFlushHook(fileSync: FileSync, logger: {
4
+ info(msg: string): void;
5
+ warn(msg: string): void;
6
+ }): (api: OpenClawPluginAPI) => void;
7
+ //# sourceMappingURL=memory-flush.d.ts.map
@@ -0,0 +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;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,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,iBAAiB,KAAK,IAAI,CAelC"}
@@ -0,0 +1,14 @@
1
+ export function createMemoryFlushHook(fileSync, logger) {
2
+ return (api) => {
3
+ api.hooks.on('memoryFlush', async () => {
4
+ try {
5
+ const { synced, changed } = await fileSync.flushNow();
6
+ logger.info(`hippodid: pre-compaction flush — synced ${synced} files (${changed} changed)`);
7
+ }
8
+ catch (e) {
9
+ logger.warn(`hippodid: pre-compaction flush failed: ${e instanceof Error ? e.message : 'unknown'}`);
10
+ }
11
+ });
12
+ };
13
+ }
14
+ //# sourceMappingURL=memory-flush.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-flush.js","sourceRoot":"","sources":["../../src/hooks/memory-flush.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CACnC,QAAkB,EAClB,MAA4D;IAE5D,OAAO,CAAC,GAAsB,EAAE,EAAE;QAChC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,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,2CAA2C,MAAM,WAAW,OAAO,WAAW,CAC/E,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,0CAA0C,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CACvF,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { FileSync } from '../file-sync.js';
2
+ import type { TierManager } from '../tier-manager.js';
3
+ import type { OpenClawPluginAPI } from '../types.js';
4
+ export declare function createSessionHooks(fileSync: FileSync, tierManager: TierManager, autoRecallEnabled: boolean, logger: {
5
+ info(msg: string): void;
6
+ warn(msg: string): void;
7
+ }): (api: OpenClawPluginAPI) => void;
8
+ //# sourceMappingURL=session-lifecycle.d.ts.map
@@ -0,0 +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;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,OAAO,EAC1B,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,iBAAiB,KAAK,IAAI,CAgClC"}
@@ -0,0 +1,29 @@
1
+ export function createSessionHooks(fileSync, tierManager, autoRecallEnabled, logger) {
2
+ return (api) => {
3
+ api.hooks.on('session:start', async () => {
4
+ try {
5
+ await tierManager.initialize();
6
+ if (tierManager.shouldHydrateOnStart(autoRecallEnabled)) {
7
+ const count = await fileSync.hydrateFromCloud();
8
+ logger.info(`hippodid: session started, hydrated ${count} files from cloud`);
9
+ }
10
+ else {
11
+ logger.info('hippodid: session started, hydration skipped (autoRecall active)');
12
+ }
13
+ }
14
+ catch (e) {
15
+ logger.warn(`hippodid: session start error: ${e instanceof Error ? e.message : 'unknown'}`);
16
+ }
17
+ });
18
+ api.hooks.on('session:end', async () => {
19
+ try {
20
+ const { synced, changed } = await fileSync.flushNow();
21
+ logger.info(`hippodid: session ended, final sync — ${synced} files (${changed} changed)`);
22
+ }
23
+ catch (e) {
24
+ logger.warn(`hippodid: session end flush failed: ${e instanceof Error ? e.message : 'unknown'}`);
25
+ }
26
+ });
27
+ };
28
+ }
29
+ //# sourceMappingURL=session-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-lifecycle.js","sourceRoot":"","sources":["../../src/hooks/session-lifecycle.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,kBAAkB,CAChC,QAAkB,EAClB,WAAwB,EACxB,iBAA0B,EAC1B,MAA4D;IAE5D,OAAO,CAAC,GAAsB,EAAE,EAAE;QAChC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;YACvC,IAAI,CAAC;gBACH,MAAM,WAAW,CAAC,UAAU,EAAE,CAAC;gBAE/B,IAAI,WAAW,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACxD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,CAAC;oBAChD,MAAM,CAAC,IAAI,CAAC,uCAAuC,KAAK,mBAAmB,CAAC,CAAC;gBAC/E,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;gBAClF,CAAC;YACH,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,KAAK,CAAC,EAAE,CAAC,aAAa,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,yCAAyC,MAAM,WAAW,OAAO,WAAW,CAC7E,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CACT,uCAAuC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CACpF,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { OpenClawPluginAPI } from './types.js';
2
+ export declare const id = "hippodid";
3
+ export default function register(api: OpenClawPluginAPI): void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,YAAY,CAAC;AAUlE,eAAO,MAAM,EAAE,aAAa,CAAC;AAI7B,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA+D7D"}
package/dist/index.js ADDED
@@ -0,0 +1,164 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+ import { createClient } from './hippodid-client.js';
4
+ import { createFileSync } from './file-sync.js';
5
+ import { resolveWatchPaths } from './workspace-detector.js';
6
+ import { createTierManager } from './tier-manager.js';
7
+ import { createMemoryFlushHook } from './hooks/memory-flush.js';
8
+ import { createSessionHooks } from './hooks/session-lifecycle.js';
9
+ import { createAutoRecallHook } from './hooks/auto-recall.js';
10
+ import { createAutoCaptureHook } from './hooks/auto-capture.js';
11
+ export const id = 'hippodid';
12
+ const VERSION = '1.0.0';
13
+ export default function register(api) {
14
+ try {
15
+ const config = resolveConfig(api.config);
16
+ const logger = api.logger ?? {
17
+ info: (msg) => console.log(msg),
18
+ warn: (msg) => console.warn(msg),
19
+ error: (msg) => console.error(msg),
20
+ };
21
+ const client = createClient(config.apiKey, config.baseUrl);
22
+ const tierManager = createTierManager(client, config.characterId, logger);
23
+ const watchPaths = resolveWatchPaths(config);
24
+ const effectiveSyncInterval = Math.max(config.syncIntervalSeconds, 60);
25
+ const fileSync = createFileSync(client, config, watchPaths, logger, effectiveSyncInterval);
26
+ const registerMemoryFlush = createMemoryFlushHook(fileSync, logger);
27
+ registerMemoryFlush(api);
28
+ const registerSessionHooks = createSessionHooks(fileSync, tierManager, config.autoRecall, logger);
29
+ registerSessionHooks(api);
30
+ tierManager.initialize().then((tier) => {
31
+ if (tierManager.shouldMountAutoRecall(config.autoRecall)) {
32
+ const registerAutoRecall = createAutoRecallHook(client, config, logger);
33
+ registerAutoRecall(api);
34
+ }
35
+ if (tierManager.shouldMountAutoCapture(config.autoCapture)) {
36
+ const registerAutoCapture = createAutoCaptureHook(client, config, logger);
37
+ registerAutoCapture(api);
38
+ }
39
+ if (tierManager.shouldMountFileSync(config.autoCapture)) {
40
+ fileSync.start();
41
+ }
42
+ const autoRecallStatus = tierManager.shouldMountAutoRecall(config.autoRecall)
43
+ ? 'ON'
44
+ : 'OFF';
45
+ const autoCaptureStatus = tierManager.shouldMountAutoCapture(config.autoCapture)
46
+ ? 'ON'
47
+ : 'OFF';
48
+ logger.info(`hippodid: v${VERSION} | character: ${config.characterId} | tier: ${tier.tier} | watching ${watchPaths.length} paths | autoRecall: ${autoRecallStatus} | autoCapture: ${autoCaptureStatus}`);
49
+ }).catch((e) => {
50
+ logger.warn(`hippodid: tier initialization failed, running in free mode: ${e instanceof Error ? e.message : 'unknown'}`);
51
+ fileSync.start();
52
+ });
53
+ registerCommands(api, config, client, fileSync, tierManager, logger);
54
+ }
55
+ catch (e) {
56
+ const msg = e instanceof Error ? e.message : 'unknown';
57
+ (api.logger ?? console).error(`hippodid: plugin initialization failed: ${msg}`);
58
+ }
59
+ }
60
+ function resolveConfig(raw) {
61
+ return {
62
+ apiKey: raw.apiKey,
63
+ characterId: raw.characterId,
64
+ baseUrl: raw.baseUrl ?? 'https://api.hippodid.com',
65
+ syncIntervalSeconds: raw.syncIntervalSeconds ?? 300,
66
+ autoRecall: raw.autoRecall ?? false,
67
+ autoCapture: raw.autoCapture ?? false,
68
+ additionalPaths: raw.additionalPaths ?? [],
69
+ };
70
+ }
71
+ function registerCommands(api, config, client, fileSync, tierManager, logger) {
72
+ api.commands.register('hippodid:status', {
73
+ description: 'Show HippoDid tier, sync status, and watched paths',
74
+ handler: async () => {
75
+ const tier = tierManager.getCurrentTier();
76
+ const statusResult = await client.getSyncStatus(config.characterId);
77
+ logger.info(`--- HippoDid Status ---`);
78
+ logger.info(`Character: ${config.characterId}`);
79
+ logger.info(`Tier: ${tier.tier}`);
80
+ logger.info(`Auto-Recall: ${tier.features.autoRecallAvailable ? 'available' : 'unavailable'} (config: ${config.autoRecall ? 'ON' : 'OFF'})`);
81
+ logger.info(`Auto-Capture: ${tier.features.autoCaptureAvailable ? 'available' : 'unavailable'} (config: ${config.autoCapture ? 'ON' : 'OFF'})`);
82
+ if (statusResult.ok) {
83
+ logger.info(`Synced sources: ${statusResult.value.entries.length}`);
84
+ for (const entry of statusResult.value.entries) {
85
+ logger.info(` ${entry.sourcePath} (${entry.label}) — last sync: ${entry.lastSyncedAt}`);
86
+ }
87
+ }
88
+ else {
89
+ logger.warn(`Could not fetch sync status: ${statusResult.error.message}`);
90
+ }
91
+ },
92
+ });
93
+ api.commands.register('hippodid:sync', {
94
+ description: 'Trigger immediate sync of all watched files',
95
+ handler: async () => {
96
+ logger.info('hippodid: manual sync triggered...');
97
+ const { synced, changed } = await fileSync.flushNow();
98
+ logger.info(`hippodid: manual sync complete — ${synced} files (${changed} changed)`);
99
+ },
100
+ });
101
+ api.commands.register('hippodid:import', {
102
+ description: 'Import existing workspace memory into HippoDid character',
103
+ args: [
104
+ {
105
+ name: 'workspace',
106
+ description: 'Path to OpenClaw workspace (default: auto-detect)',
107
+ required: false,
108
+ },
109
+ ],
110
+ handler: async (args) => {
111
+ const { readdir } = await import('node:fs/promises');
112
+ const { join, extname } = await import('node:path');
113
+ const { createHash } = await import('node:crypto');
114
+ const workspacePath = args['workspace']
115
+ ? resolve(args['workspace'])
116
+ : resolve(process.cwd());
117
+ const memoryDir = join(workspacePath, 'memory');
118
+ const memoryMd = join(workspacePath, 'MEMORY.md');
119
+ const filesToImport = [];
120
+ try {
121
+ const entries = await readdir(memoryDir);
122
+ for (const entry of entries) {
123
+ if (extname(entry) === '.md') {
124
+ filesToImport.push({
125
+ path: join(memoryDir, entry),
126
+ label: 'workspace-memory',
127
+ });
128
+ }
129
+ }
130
+ }
131
+ catch {
132
+ // memory dir may not exist
133
+ }
134
+ try {
135
+ await readFile(memoryMd);
136
+ filesToImport.push({ path: memoryMd, label: 'MEMORY.md' });
137
+ }
138
+ catch {
139
+ // MEMORY.md may not exist
140
+ }
141
+ if (filesToImport.length === 0) {
142
+ logger.info('hippodid: no memory files found to import');
143
+ return;
144
+ }
145
+ logger.info(`hippodid: importing ${filesToImport.length} files from ${workspacePath}...`);
146
+ let imported = 0;
147
+ for (const file of filesToImport) {
148
+ try {
149
+ const content = await readFile(file.path);
150
+ const hash = createHash('sha256').update(content).digest('hex');
151
+ const base64 = content.toString('base64');
152
+ const result = await client.syncFile(config.characterId, file.path, file.label, base64, hash);
153
+ if (result.ok)
154
+ imported++;
155
+ }
156
+ catch (e) {
157
+ logger.warn(`hippodid: import failed for ${file.path}: ${e instanceof Error ? e.message : 'unknown'}`);
158
+ }
159
+ }
160
+ logger.info(`hippodid: import complete — ${imported}/${filesToImport.length} files imported`);
161
+ },
162
+ });
163
+ }
164
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { HippoDidClient } from './hippodid-client.js';
2
+ import type { TierInfo } from './types.js';
3
+ export interface TierManager {
4
+ initialize(): Promise<TierInfo>;
5
+ getCurrentTier(): TierInfo;
6
+ shouldMountFileSync(autoCaptureEnabled: boolean): boolean;
7
+ shouldMountAutoRecall(autoRecallEnabled: boolean): boolean;
8
+ shouldMountAutoCapture(autoCaptureEnabled: boolean): boolean;
9
+ shouldHydrateOnStart(autoRecallEnabled: boolean): boolean;
10
+ getEffectiveSyncInterval(configInterval: number): number;
11
+ }
12
+ export declare function createTierManager(client: HippoDidClient, characterId: string, logger: {
13
+ info(msg: string): void;
14
+ warn(msg: string): void;
15
+ }): TierManager;
16
+ //# sourceMappingURL=tier-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-manager.d.ts","sourceRoot":"","sources":["../src/tier-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,UAAU,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,cAAc,IAAI,QAAQ,CAAC;IAC3B,mBAAmB,CAAC,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1D,qBAAqB,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,CAAC;IAC3D,sBAAsB,CAAC,kBAAkB,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7D,oBAAoB,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1D,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1D;AAWD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE;IAAE,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D,WAAW,CA2Db"}
@@ -0,0 +1,57 @@
1
+ const FREE_TIER_FALLBACK = {
2
+ tier: 'free',
3
+ features: {
4
+ autoRecallAvailable: false,
5
+ autoCaptureAvailable: false,
6
+ minSyncIntervalSeconds: 60,
7
+ },
8
+ };
9
+ export function createTierManager(client, characterId, logger) {
10
+ let currentTier = FREE_TIER_FALLBACK;
11
+ return {
12
+ async initialize() {
13
+ const result = await client.getTier(characterId);
14
+ if (result.ok) {
15
+ currentTier = result.value;
16
+ }
17
+ else {
18
+ logger.warn(`hippodid: failed to fetch tier, defaulting to free: ${result.error.message}`);
19
+ currentTier = FREE_TIER_FALLBACK;
20
+ }
21
+ logger.info(`hippodid: tier=${currentTier.tier}, autoRecall=${currentTier.features.autoRecallAvailable ? 'available' : 'unavailable'}, autoCapture=${currentTier.features.autoCaptureAvailable ? 'available' : 'unavailable'}`);
22
+ return currentTier;
23
+ },
24
+ getCurrentTier() {
25
+ return currentTier;
26
+ },
27
+ shouldMountFileSync(autoCaptureEnabled) {
28
+ const isFree = !isPaidTier(currentTier);
29
+ if (isFree)
30
+ return true;
31
+ return !autoCaptureEnabled;
32
+ },
33
+ shouldMountAutoRecall(autoRecallEnabled) {
34
+ return (isPaidTier(currentTier) &&
35
+ autoRecallEnabled &&
36
+ currentTier.features.autoRecallAvailable);
37
+ },
38
+ shouldMountAutoCapture(autoCaptureEnabled) {
39
+ return (isPaidTier(currentTier) &&
40
+ autoCaptureEnabled &&
41
+ currentTier.features.autoCaptureAvailable);
42
+ },
43
+ shouldHydrateOnStart(autoRecallEnabled) {
44
+ const isFree = !isPaidTier(currentTier);
45
+ if (isFree)
46
+ return true;
47
+ return !autoRecallEnabled;
48
+ },
49
+ getEffectiveSyncInterval(configInterval) {
50
+ return Math.max(configInterval, currentTier.features.minSyncIntervalSeconds);
51
+ },
52
+ };
53
+ }
54
+ function isPaidTier(tier) {
55
+ return tier.tier !== 'free';
56
+ }
57
+ //# sourceMappingURL=tier-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-manager.js","sourceRoot":"","sources":["../src/tier-manager.ts"],"names":[],"mappings":"AAaA,MAAM,kBAAkB,GAAa;IACnC,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE;QACR,mBAAmB,EAAE,KAAK;QAC1B,oBAAoB,EAAE,KAAK;QAC3B,sBAAsB,EAAE,EAAE;KAC3B;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAC/B,MAAsB,EACtB,WAAmB,EACnB,MAA4D;IAE5D,IAAI,WAAW,GAAa,kBAAkB,CAAC;IAE/C,OAAO;QACL,KAAK,CAAC,UAAU;YACd,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAEjD,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;gBACd,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CACT,uDAAuD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAC9E,CAAC;gBACF,WAAW,GAAG,kBAAkB,CAAC;YACnC,CAAC;YAED,MAAM,CAAC,IAAI,CACT,kBAAkB,WAAW,CAAC,IAAI,gBAAgB,WAAW,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,iBAAiB,WAAW,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,EAAE,CACnN,CAAC;YAEF,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,cAAc;YACZ,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,mBAAmB,CAAC,kBAA2B;YAC7C,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YACxC,IAAI,MAAM;gBAAE,OAAO,IAAI,CAAC;YACxB,OAAO,CAAC,kBAAkB,CAAC;QAC7B,CAAC;QAED,qBAAqB,CAAC,iBAA0B;YAC9C,OAAO,CACL,UAAU,CAAC,WAAW,CAAC;gBACvB,iBAAiB;gBACjB,WAAW,CAAC,QAAQ,CAAC,mBAAmB,CACzC,CAAC;QACJ,CAAC;QAED,sBAAsB,CAAC,kBAA2B;YAChD,OAAO,CACL,UAAU,CAAC,WAAW,CAAC;gBACvB,kBAAkB;gBAClB,WAAW,CAAC,QAAQ,CAAC,oBAAoB,CAC1C,CAAC;QACJ,CAAC;QAED,oBAAoB,CAAC,iBAA0B;YAC7C,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YACxC,IAAI,MAAM;gBAAE,OAAO,IAAI,CAAC;YACxB,OAAO,CAAC,iBAAiB,CAAC;QAC5B,CAAC;QAED,wBAAwB,CAAC,cAAsB;YAC7C,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;QAC/E,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAc;IAChC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,123 @@
1
+ export type Result<T, E = ApiError> = {
2
+ ok: true;
3
+ value: T;
4
+ } | {
5
+ ok: false;
6
+ error: E;
7
+ };
8
+ export declare function ok<T>(value: T): Result<T, never>;
9
+ export declare function err<E>(error: E): Result<never, E>;
10
+ export interface ApiError {
11
+ status: number;
12
+ message: string;
13
+ retryable: boolean;
14
+ }
15
+ export interface PluginConfig {
16
+ apiKey: string;
17
+ characterId: string;
18
+ baseUrl: string;
19
+ syncIntervalSeconds: number;
20
+ autoRecall: boolean;
21
+ autoCapture: boolean;
22
+ additionalPaths: WatchPathConfig[];
23
+ }
24
+ export interface WatchPathConfig {
25
+ path: string;
26
+ label?: string;
27
+ }
28
+ export interface WatchPath {
29
+ path: string;
30
+ label: string;
31
+ source: 'auto-detected' | 'user-specified';
32
+ }
33
+ export interface TierInfo {
34
+ tier: string;
35
+ features: {
36
+ autoRecallAvailable: boolean;
37
+ autoCaptureAvailable: boolean;
38
+ minSyncIntervalSeconds: number;
39
+ };
40
+ }
41
+ export interface TierApiResponse {
42
+ tier: string;
43
+ features: {
44
+ auto_recall_available: boolean;
45
+ auto_capture_available: boolean;
46
+ min_sync_interval_seconds: number;
47
+ };
48
+ }
49
+ export interface SyncResponse {
50
+ status: string;
51
+ snapshotId: string;
52
+ changed: boolean;
53
+ }
54
+ export interface SyncApiResponse {
55
+ status: string;
56
+ snapshot_id: string;
57
+ changed: boolean;
58
+ }
59
+ export interface SyncLatestResponse {
60
+ sourcePath: string;
61
+ fileContent: string;
62
+ snapshotId: string;
63
+ syncedAt: string;
64
+ }
65
+ export interface SyncLatestApiResponse {
66
+ source_path: string;
67
+ file_content: string;
68
+ snapshot_id: string;
69
+ synced_at: string;
70
+ }
71
+ export interface SyncStatusEntry {
72
+ sourcePath: string;
73
+ label: string;
74
+ lastSyncedAt: string;
75
+ snapshotId: string;
76
+ }
77
+ export interface SyncStatusResponse {
78
+ entries: SyncStatusEntry[];
79
+ }
80
+ export interface SearchResult {
81
+ content: string;
82
+ category: string;
83
+ score: number;
84
+ createdAt: string;
85
+ }
86
+ export interface SearchResultApiResponse {
87
+ content: string;
88
+ category: string;
89
+ score: number;
90
+ created_at: string;
91
+ }
92
+ export interface FileTrackingEntry {
93
+ hash: string;
94
+ lastSyncedAt: Date;
95
+ }
96
+ export interface OpenClawPluginAPI {
97
+ config: PluginConfig;
98
+ logger: {
99
+ info(message: string): void;
100
+ warn(message: string): void;
101
+ error(message: string): void;
102
+ };
103
+ hooks: {
104
+ on(event: string, handler: (...args: any[]) => void | Promise<void>): void;
105
+ };
106
+ context: {
107
+ prepend(content: string): void;
108
+ };
109
+ commands: {
110
+ register(name: string, options: CommandOptions): void;
111
+ };
112
+ }
113
+ export interface CommandOptions {
114
+ description: string;
115
+ args?: CommandArg[];
116
+ handler: (args: Record<string, string>) => void | Promise<void>;
117
+ }
118
+ export interface CommandArg {
119
+ name: string;
120
+ description: string;
121
+ required?: boolean;
122
+ }
123
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ // --- Result type (discriminated union, zero deps) ---
2
+ export function ok(value) {
3
+ return { ok: true, value };
4
+ }
5
+ export function err(error) {
6
+ return { ok: false, error };
7
+ }
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAMvD,MAAM,UAAU,EAAE,CAAI,KAAQ;IAC5B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,GAAG,CAAI,KAAQ;IAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { PluginConfig, WatchPath } from './types.js';
2
+ export declare function detectWorkspaceMemoryDir(): string | null;
3
+ export declare function detectMemoryMdPath(): string | null;
4
+ export declare function resolveWatchPaths(config: PluginConfig): WatchPath[];
5
+ //# sourceMappingURL=workspace-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-detector.d.ts","sourceRoot":"","sources":["../src/workspace-detector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAkBxD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAoBlD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,EAAE,CA2CnE"}
@@ -0,0 +1,88 @@
1
+ import { existsSync, readdirSync, statSync } from 'node:fs';
2
+ import { resolve, join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ export function detectWorkspaceMemoryDir() {
5
+ const candidates = [];
6
+ const envWorkspace = process.env['OPENCLAW_WORKSPACE'];
7
+ if (envWorkspace) {
8
+ candidates.push(resolve(join(envWorkspace, 'memory')));
9
+ }
10
+ candidates.push(resolve(join(homedir(), '.openclaw', 'workspace', 'memory')));
11
+ candidates.push(resolve(join(process.cwd(), 'memory')));
12
+ for (const candidate of candidates) {
13
+ if (isValidMemoryDir(candidate)) {
14
+ return candidate;
15
+ }
16
+ }
17
+ return null;
18
+ }
19
+ export function detectMemoryMdPath() {
20
+ const candidates = [];
21
+ const envWorkspace = process.env['OPENCLAW_WORKSPACE'];
22
+ if (envWorkspace) {
23
+ candidates.push(resolve(join(envWorkspace, 'MEMORY.md')));
24
+ }
25
+ candidates.push(resolve(join(homedir(), '.openclaw', 'workspace', 'MEMORY.md')));
26
+ candidates.push(resolve(join(process.cwd(), 'MEMORY.md')));
27
+ for (const candidate of candidates) {
28
+ if (existsSync(candidate)) {
29
+ return candidate;
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ export function resolveWatchPaths(config) {
35
+ const paths = [];
36
+ const seen = new Set();
37
+ const memoryDir = detectWorkspaceMemoryDir();
38
+ if (memoryDir) {
39
+ const resolved = resolve(memoryDir);
40
+ if (!seen.has(resolved)) {
41
+ seen.add(resolved);
42
+ paths.push({
43
+ path: resolved,
44
+ label: 'workspace-memory',
45
+ source: 'auto-detected',
46
+ });
47
+ }
48
+ }
49
+ const memoryMd = detectMemoryMdPath();
50
+ if (memoryMd) {
51
+ const resolved = resolve(memoryMd);
52
+ if (!seen.has(resolved)) {
53
+ seen.add(resolved);
54
+ paths.push({
55
+ path: resolved,
56
+ label: 'MEMORY.md',
57
+ source: 'auto-detected',
58
+ });
59
+ }
60
+ }
61
+ for (const additional of config.additionalPaths) {
62
+ const resolved = resolve(additional.path);
63
+ if (!seen.has(resolved)) {
64
+ seen.add(resolved);
65
+ paths.push({
66
+ path: resolved,
67
+ label: additional.label ?? resolved,
68
+ source: 'user-specified',
69
+ });
70
+ }
71
+ }
72
+ return paths;
73
+ }
74
+ function isValidMemoryDir(dirPath) {
75
+ try {
76
+ if (!existsSync(dirPath))
77
+ return false;
78
+ const s = statSync(dirPath);
79
+ if (!s.isDirectory())
80
+ return false;
81
+ const entries = readdirSync(dirPath);
82
+ return entries.some((e) => e.endsWith('.md'));
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ //# sourceMappingURL=workspace-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-detector.js","sourceRoot":"","sources":["../src/workspace-detector.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hippodid/openclaw-plugin",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Cloud sync for MEMORY.md with structured character memory. Survives context compaction.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -18,7 +18,8 @@
18
18
  ],
19
19
  "main": "src/index.ts",
20
20
  "files": [
21
- "src/",
21
+ "dist",
22
+ "src",
22
23
  "openclaw.plugin.json",
23
24
  "LICENSE",
24
25
  "README.md"
@@ -34,5 +35,10 @@
34
35
  "@vitest/coverage-v8": "^3.2.4",
35
36
  "typescript": "^5.7.0",
36
37
  "vitest": "^3.0.0"
38
+ },
39
+ "openclaw": {
40
+ "extensions": [
41
+ "./dist/index.js"
42
+ ]
37
43
  }
38
44
  }