openclaw-plugin-edicts 0.1.4 → 0.1.6
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/dist/index.cjs +5 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -331,10 +331,13 @@ var plugin = {
|
|
|
331
331
|
description: "Inject agent edicts into context and expose CRUD tools.",
|
|
332
332
|
register(api) {
|
|
333
333
|
const config = resolveConfig(api.pluginConfig ?? {});
|
|
334
|
-
|
|
334
|
+
const workspaceDir = api.resolvePath?.(".") ?? api.workspaceDir ?? null;
|
|
335
|
+
if (!workspaceDir) {
|
|
336
|
+
console.log("[edicts] register: no workspace dir available \u2014 skipping init (install-time probe)");
|
|
335
337
|
return;
|
|
336
338
|
}
|
|
337
|
-
|
|
339
|
+
console.log(`[edicts] register: workspaceDir=${workspaceDir}, configPath=${config.path}`);
|
|
340
|
+
const storePath = import_node_path.default.resolve(workspaceDir, config.path);
|
|
338
341
|
ensureEdictsFile(storePath);
|
|
339
342
|
const store = new import_edicts3.EdictStore({
|
|
340
343
|
path: storePath,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts","../src/config.ts","../src/context.ts","../src/tools.ts"],"sourcesContent":["import { existsSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { EdictStore } from 'edicts';\nimport { resolveConfig } from './src/config.js';\nimport { createContextHook } from './src/context.js';\nimport { registerEdictTools } from './src/tools.js';\n\n/**\n * OpenClaw plugin API surface — types inferred from OpenClaw runtime.\n * No compile-time dependency on OpenClaw; the runtime provides the API object.\n */\nexport interface OpenClawPluginApi {\n pluginConfig?: Record<string, unknown>;\n workspaceDir: string;\n registerTool(\n factory: () => Array<{\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params: any) => Promise<{ content: Array<{ type: 'text'; text: string }> }>;\n }>,\n opts?: { names?: string[]; optional?: boolean },\n ): void;\n on(\n hookName: 'before_prompt_build',\n handler: () => Promise<{ appendSystemContext?: string } | Record<string, never>>,\n ): void;\n}\n\n/**\n * Create a starter edicts.yaml if the file doesn't exist yet.\n * For OpenClaw users this means zero bootstrapping — install the plugin and go.\n */\nfunction ensureEdictsFile(filePath: string): void {\n if (existsSync(filePath)) return;\n const now = new Date().toISOString();\n const template = [\n 'version: 1',\n 'config:',\n ' maxEdicts: 200',\n ' tokenBudget: 4000',\n ' categories: []',\n 'edicts: []',\n 'history: []',\n '',\n ].join('\\n');\n writeFileSync(filePath, template, 'utf-8');\n}\n\nconst plugin = {\n id: 'openclaw-plugin-edicts',\n name: 'Edicts',\n description: 'Inject agent edicts into context and expose CRUD tools.',\n\n register(api: OpenClawPluginApi) {\n const config = resolveConfig(api.pluginConfig ?? {});\n\n if (!api.workspaceDir) {\n // Install-time probe — workspace not available yet. Skip initialization.\n return;\n }\n\n const storePath = path.resolve(api.workspaceDir, config.path);\n\n // Auto-create edicts file on first run — no manual init needed\n ensureEdictsFile(storePath);\n\n const store = new EdictStore({\n path: storePath,\n format: config.format,\n tokenBudget: config.tokenBudget,\n autoSave: true,\n });\n\n registerEdictTools(api, store);\n\n if (config.autoInject) {\n api.on('before_prompt_build', createContextHook(store, config));\n }\n },\n};\n\nexport default plugin;\n","export interface ResolvedConfig {\n path: string;\n format: 'yaml' | 'json';\n autoInject: boolean;\n autoInjectFilter: 'all';\n tokenBudget: number;\n}\n\n/**\n * Merge user-provided plugin config over defaults.\n * Infers format from path extension when not explicitly set.\n */\nexport function resolveConfig(raw: Record<string, unknown>): ResolvedConfig {\n const userPath = typeof raw.path === 'string' ? raw.path : 'edicts.yaml';\n\n let format: 'yaml' | 'json';\n if (raw.format === 'json' || raw.format === 'yaml') {\n format = raw.format;\n } else {\n format = userPath.endsWith('.json') ? 'json' : 'yaml';\n }\n\n return {\n path: userPath,\n format,\n autoInject: typeof raw.autoInject === 'boolean' ? raw.autoInject : true,\n autoInjectFilter: 'all',\n tokenBudget: typeof raw.tokenBudget === 'number' ? raw.tokenBudget : 2000,\n };\n}\n","import { renderPlain } from 'edicts';\nimport type { EdictStore } from 'edicts';\nimport type { ResolvedConfig } from './config.js';\n\n/**\n * Creates the before_prompt_build hook that injects edicts into system context.\n * v1: injects all edicts (autoInjectFilter = \"all\").\n */\nexport function createContextHook(\n store: EdictStore,\n config: ResolvedConfig,\n): () => Promise<{ appendSystemContext?: string } | Record<string, never>> {\n return async () => {\n try {\n await store.load();\n } catch {\n // File doesn't exist yet — empty store, nothing to inject\n return {};\n }\n\n const edicts = await store.all();\n\n if (edicts.length === 0) {\n return {};\n }\n\n const rendered = renderPlain(edicts);\n const appendSystemContext = wrapEdicts(rendered);\n\n return { appendSystemContext };\n };\n}\n\nfunction wrapEdicts(rendered: string): string {\n return [\n '## Edicts (Standing Instructions)',\n 'The following are your standing instructions. Follow them unless explicitly overridden.',\n '',\n rendered,\n ].join('\\n');\n}\n","import type { EdictStore } from 'edicts';\nimport type { EdictInput, FindQuery } from 'edicts';\nimport {\n EdictNotFoundError,\n EdictValidationError,\n EdictBudgetExceededError,\n EdictCountLimitError,\n EdictCategoryError,\n} from 'edicts';\n\ntype ToolResult = { content: Array<{ type: 'text'; text: string }> };\ntype Tool = {\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params?: any) => Promise<ToolResult>;\n};\n\nfunction text(msg: string): ToolResult {\n return { content: [{ type: 'text', text: msg }] };\n}\n\nfunction serialize(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\nfunction friendlyError(err: unknown): string {\n if (err instanceof EdictNotFoundError) return `No edict found with id '${(err as any).id ?? 'unknown'}'`;\n if (err instanceof EdictValidationError) return `Validation error: ${err.message}`;\n if (err instanceof EdictBudgetExceededError) return `Token budget exceeded: ${err.message}`;\n if (err instanceof EdictCountLimitError) return `Edict count limit reached: ${err.message}`;\n if (err instanceof EdictCategoryError) return `Category error: ${err.message}`;\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nconst TOOL_NAMES = [\n 'edicts_list',\n 'edicts_add',\n 'edicts_update',\n 'edicts_remove',\n 'edicts_search',\n 'edicts_stats',\n 'edicts_review',\n] as const;\n\nasync function ensureLoaded(store: EdictStore): Promise<EdictStore> {\n await store.load();\n return store;\n}\n\nfunction buildTools(store: EdictStore): Tool[] {\n return [\n {\n name: 'edicts_list',\n description: 'List edicts with optional filtering by category, tags, or ttl.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n limit: { type: 'number' },\n },\n },\n async execute(_id: string, params: FindQuery & { limit?: number } = {}) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.find(params);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts found matching the criteria.');\n return text(`${results.length} edict(s) found:\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error listing edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_add',\n description: 'Create a new edict (standing instruction).',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n source: { type: 'string' },\n key: { type: 'string' },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['text', 'category'],\n },\n async execute(_id: string, params: EdictInput) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.add(params);\n return text(`Edict created:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error adding edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_update',\n description: 'Update an existing edict by id.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string } & Partial<EdictInput>) {\n try {\n const { id, ...patch } = params;\n const s = await ensureLoaded(store);\n const result = await s.update(id, patch);\n return text(`Edict updated:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error updating edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_remove',\n description: 'Remove an edict.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string }) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.remove(params.id);\n return text(`Edict removed:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error removing edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_search',\n description: 'Free-text search across edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n query: { type: 'string' },\n limit: { type: 'number' },\n },\n required: ['query'],\n },\n async execute(_id: string, params: { query: string; limit?: number }) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.search(params.query);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts matched the search query.');\n return text(`${results.length} match(es):\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error searching edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_stats',\n description: 'Show edict store statistics.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {},\n },\n async execute() {\n try {\n const s = await ensureLoaded(store);\n const stats = await s.stats();\n return text(`Edict store statistics:\\n\\n${serialize(stats)}`);\n } catch (err: unknown) {\n return text(`Error fetching stats: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_review',\n description: 'Review and optionally clean up stale/expired edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n action: { type: 'string', enum: ['preview', 'compact'] },\n },\n },\n async execute(_id: string, params: { action?: 'preview' | 'compact' } = {}) {\n try {\n const s = await ensureLoaded(store);\n const action = params.action ?? 'preview';\n if (action === 'compact') {\n // compact() requires a callback-driven merge (group + merged edict).\n // For now, run review() and flag compaction candidates.\n const result = await s.review();\n return text(`Compaction candidates (auto-compact requires LLM callback — v2):\\n\\n${serialize(result)}`);\n }\n const result = await s.review();\n return text(`Review (preview):\\n\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error reviewing edicts: ${friendlyError(err)}`);\n }\n },\n },\n ];\n}\n\n/**\n * Register all edicts tools with the OpenClaw plugin API.\n * Tools are required (always available when plugin is enabled).\n */\nexport function registerEdictTools(\n api: { registerTool: (factory: () => Tool[], opts?: { names?: string[]; optional?: boolean }) => void },\n store: EdictStore,\n): void {\n api.registerTool(() => buildTools(store), {\n names: [...TOOL_NAMES],\n optional: false,\n });\n}\n"],"mappings":"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","names":["import_edicts","import_edicts","result","path"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts","../src/config.ts","../src/context.ts","../src/tools.ts"],"sourcesContent":["import { existsSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { EdictStore } from 'edicts';\nimport { resolveConfig } from './src/config.js';\nimport { createContextHook } from './src/context.js';\nimport { registerEdictTools } from './src/tools.js';\n\n/**\n * OpenClaw plugin API surface — types inferred from OpenClaw runtime.\n * No compile-time dependency on OpenClaw; the runtime provides the API object.\n */\nexport interface OpenClawPluginApi {\n pluginConfig?: Record<string, unknown>;\n workspaceDir?: string;\n resolvePath?(relativePath: string): string;\n registerTool(\n factory: () => Array<{\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params: any) => Promise<{ content: Array<{ type: 'text'; text: string }> }>;\n }>,\n opts?: { names?: string[]; optional?: boolean },\n ): void;\n on(\n hookName: 'before_prompt_build',\n handler: () => Promise<{ appendSystemContext?: string } | Record<string, never>>,\n ): void;\n}\n\n/**\n * Create a starter edicts.yaml if the file doesn't exist yet.\n * For OpenClaw users this means zero bootstrapping — install the plugin and go.\n */\nfunction ensureEdictsFile(filePath: string): void {\n if (existsSync(filePath)) return;\n const now = new Date().toISOString();\n const template = [\n 'version: 1',\n 'config:',\n ' maxEdicts: 200',\n ' tokenBudget: 4000',\n ' categories: []',\n 'edicts: []',\n 'history: []',\n '',\n ].join('\\n');\n writeFileSync(filePath, template, 'utf-8');\n}\n\nconst plugin = {\n id: 'openclaw-plugin-edicts',\n name: 'Edicts',\n description: 'Inject agent edicts into context and expose CRUD tools.',\n\n register(api: OpenClawPluginApi) {\n const config = resolveConfig(api.pluginConfig ?? {});\n\n // Resolve workspace dir: prefer resolvePath API, fall back to workspaceDir, then cwd\n const workspaceDir = api.resolvePath?.('.') ?? api.workspaceDir ?? null;\n if (!workspaceDir) {\n console.log('[edicts] register: no workspace dir available — skipping init (install-time probe)');\n return;\n }\n\n console.log(`[edicts] register: workspaceDir=${workspaceDir}, configPath=${config.path}`);\n\n const storePath = path.resolve(workspaceDir, config.path);\n\n // Auto-create edicts file on first run — no manual init needed\n ensureEdictsFile(storePath);\n\n const store = new EdictStore({\n path: storePath,\n format: config.format,\n tokenBudget: config.tokenBudget,\n autoSave: true,\n });\n\n registerEdictTools(api, store);\n\n if (config.autoInject) {\n api.on('before_prompt_build', createContextHook(store, config));\n }\n },\n};\n\nexport default plugin;\n","export interface ResolvedConfig {\n path: string;\n format: 'yaml' | 'json';\n autoInject: boolean;\n autoInjectFilter: 'all';\n tokenBudget: number;\n}\n\n/**\n * Merge user-provided plugin config over defaults.\n * Infers format from path extension when not explicitly set.\n */\nexport function resolveConfig(raw: Record<string, unknown>): ResolvedConfig {\n const userPath = typeof raw.path === 'string' ? raw.path : 'edicts.yaml';\n\n let format: 'yaml' | 'json';\n if (raw.format === 'json' || raw.format === 'yaml') {\n format = raw.format;\n } else {\n format = userPath.endsWith('.json') ? 'json' : 'yaml';\n }\n\n return {\n path: userPath,\n format,\n autoInject: typeof raw.autoInject === 'boolean' ? raw.autoInject : true,\n autoInjectFilter: 'all',\n tokenBudget: typeof raw.tokenBudget === 'number' ? raw.tokenBudget : 2000,\n };\n}\n","import { renderPlain } from 'edicts';\nimport type { EdictStore } from 'edicts';\nimport type { ResolvedConfig } from './config.js';\n\n/**\n * Creates the before_prompt_build hook that injects edicts into system context.\n * v1: injects all edicts (autoInjectFilter = \"all\").\n */\nexport function createContextHook(\n store: EdictStore,\n config: ResolvedConfig,\n): () => Promise<{ appendSystemContext?: string } | Record<string, never>> {\n return async () => {\n try {\n await store.load();\n } catch {\n // File doesn't exist yet — empty store, nothing to inject\n return {};\n }\n\n const edicts = await store.all();\n\n if (edicts.length === 0) {\n return {};\n }\n\n const rendered = renderPlain(edicts);\n const appendSystemContext = wrapEdicts(rendered);\n\n return { appendSystemContext };\n };\n}\n\nfunction wrapEdicts(rendered: string): string {\n return [\n '## Edicts (Standing Instructions)',\n 'The following are your standing instructions. Follow them unless explicitly overridden.',\n '',\n rendered,\n ].join('\\n');\n}\n","import type { EdictStore } from 'edicts';\nimport type { EdictInput, FindQuery } from 'edicts';\nimport {\n EdictNotFoundError,\n EdictValidationError,\n EdictBudgetExceededError,\n EdictCountLimitError,\n EdictCategoryError,\n} from 'edicts';\n\ntype ToolResult = { content: Array<{ type: 'text'; text: string }> };\ntype Tool = {\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params?: any) => Promise<ToolResult>;\n};\n\nfunction text(msg: string): ToolResult {\n return { content: [{ type: 'text', text: msg }] };\n}\n\nfunction serialize(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\nfunction friendlyError(err: unknown): string {\n if (err instanceof EdictNotFoundError) return `No edict found with id '${(err as any).id ?? 'unknown'}'`;\n if (err instanceof EdictValidationError) return `Validation error: ${err.message}`;\n if (err instanceof EdictBudgetExceededError) return `Token budget exceeded: ${err.message}`;\n if (err instanceof EdictCountLimitError) return `Edict count limit reached: ${err.message}`;\n if (err instanceof EdictCategoryError) return `Category error: ${err.message}`;\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nconst TOOL_NAMES = [\n 'edicts_list',\n 'edicts_add',\n 'edicts_update',\n 'edicts_remove',\n 'edicts_search',\n 'edicts_stats',\n 'edicts_review',\n] as const;\n\nasync function ensureLoaded(store: EdictStore): Promise<EdictStore> {\n await store.load();\n return store;\n}\n\nfunction buildTools(store: EdictStore): Tool[] {\n return [\n {\n name: 'edicts_list',\n description: 'List edicts with optional filtering by category, tags, or ttl.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n limit: { type: 'number' },\n },\n },\n async execute(_id: string, params: FindQuery & { limit?: number } = {}) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.find(params);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts found matching the criteria.');\n return text(`${results.length} edict(s) found:\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error listing edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_add',\n description: 'Create a new edict (standing instruction).',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n source: { type: 'string' },\n key: { type: 'string' },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['text', 'category'],\n },\n async execute(_id: string, params: EdictInput) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.add(params);\n return text(`Edict created:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error adding edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_update',\n description: 'Update an existing edict by id.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string } & Partial<EdictInput>) {\n try {\n const { id, ...patch } = params;\n const s = await ensureLoaded(store);\n const result = await s.update(id, patch);\n return text(`Edict updated:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error updating edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_remove',\n description: 'Remove an edict.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string }) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.remove(params.id);\n return text(`Edict removed:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error removing edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_search',\n description: 'Free-text search across edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n query: { type: 'string' },\n limit: { type: 'number' },\n },\n required: ['query'],\n },\n async execute(_id: string, params: { query: string; limit?: number }) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.search(params.query);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts matched the search query.');\n return text(`${results.length} match(es):\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error searching edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_stats',\n description: 'Show edict store statistics.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {},\n },\n async execute() {\n try {\n const s = await ensureLoaded(store);\n const stats = await s.stats();\n return text(`Edict store statistics:\\n\\n${serialize(stats)}`);\n } catch (err: unknown) {\n return text(`Error fetching stats: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_review',\n description: 'Review and optionally clean up stale/expired edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n action: { type: 'string', enum: ['preview', 'compact'] },\n },\n },\n async execute(_id: string, params: { action?: 'preview' | 'compact' } = {}) {\n try {\n const s = await ensureLoaded(store);\n const action = params.action ?? 'preview';\n if (action === 'compact') {\n // compact() requires a callback-driven merge (group + merged edict).\n // For now, run review() and flag compaction candidates.\n const result = await s.review();\n return text(`Compaction candidates (auto-compact requires LLM callback — v2):\\n\\n${serialize(result)}`);\n }\n const result = await s.review();\n return text(`Review (preview):\\n\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error reviewing edicts: ${friendlyError(err)}`);\n }\n },\n },\n ];\n}\n\n/**\n * Register all edicts tools with the OpenClaw plugin API.\n * Tools are required (always available when plugin is enabled).\n */\nexport function registerEdictTools(\n api: { registerTool: (factory: () => Tool[], opts?: { names?: string[]; optional?: boolean }) => void },\n store: EdictStore,\n): void {\n api.registerTool(() => buildTools(store), {\n names: [...TOOL_NAMES],\n optional: false,\n });\n}\n"],"mappings":"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","names":["import_edicts","import_edicts","result","path"]}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -303,10 +303,13 @@ var plugin = {
|
|
|
303
303
|
description: "Inject agent edicts into context and expose CRUD tools.",
|
|
304
304
|
register(api) {
|
|
305
305
|
const config = resolveConfig(api.pluginConfig ?? {});
|
|
306
|
-
|
|
306
|
+
const workspaceDir = api.resolvePath?.(".") ?? api.workspaceDir ?? null;
|
|
307
|
+
if (!workspaceDir) {
|
|
308
|
+
console.log("[edicts] register: no workspace dir available \u2014 skipping init (install-time probe)");
|
|
307
309
|
return;
|
|
308
310
|
}
|
|
309
|
-
|
|
311
|
+
console.log(`[edicts] register: workspaceDir=${workspaceDir}, configPath=${config.path}`);
|
|
312
|
+
const storePath = path.resolve(workspaceDir, config.path);
|
|
310
313
|
ensureEdictsFile(storePath);
|
|
311
314
|
const store = new EdictStore({
|
|
312
315
|
path: storePath,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts","../src/config.ts","../src/context.ts","../src/tools.ts"],"sourcesContent":["import { existsSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { EdictStore } from 'edicts';\nimport { resolveConfig } from './src/config.js';\nimport { createContextHook } from './src/context.js';\nimport { registerEdictTools } from './src/tools.js';\n\n/**\n * OpenClaw plugin API surface — types inferred from OpenClaw runtime.\n * No compile-time dependency on OpenClaw; the runtime provides the API object.\n */\nexport interface OpenClawPluginApi {\n pluginConfig?: Record<string, unknown>;\n workspaceDir: string;\n registerTool(\n factory: () => Array<{\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params: any) => Promise<{ content: Array<{ type: 'text'; text: string }> }>;\n }>,\n opts?: { names?: string[]; optional?: boolean },\n ): void;\n on(\n hookName: 'before_prompt_build',\n handler: () => Promise<{ appendSystemContext?: string } | Record<string, never>>,\n ): void;\n}\n\n/**\n * Create a starter edicts.yaml if the file doesn't exist yet.\n * For OpenClaw users this means zero bootstrapping — install the plugin and go.\n */\nfunction ensureEdictsFile(filePath: string): void {\n if (existsSync(filePath)) return;\n const now = new Date().toISOString();\n const template = [\n 'version: 1',\n 'config:',\n ' maxEdicts: 200',\n ' tokenBudget: 4000',\n ' categories: []',\n 'edicts: []',\n 'history: []',\n '',\n ].join('\\n');\n writeFileSync(filePath, template, 'utf-8');\n}\n\nconst plugin = {\n id: 'openclaw-plugin-edicts',\n name: 'Edicts',\n description: 'Inject agent edicts into context and expose CRUD tools.',\n\n register(api: OpenClawPluginApi) {\n const config = resolveConfig(api.pluginConfig ?? {});\n\n if (!api.workspaceDir) {\n // Install-time probe — workspace not available yet. Skip initialization.\n return;\n }\n\n const storePath = path.resolve(api.workspaceDir, config.path);\n\n // Auto-create edicts file on first run — no manual init needed\n ensureEdictsFile(storePath);\n\n const store = new EdictStore({\n path: storePath,\n format: config.format,\n tokenBudget: config.tokenBudget,\n autoSave: true,\n });\n\n registerEdictTools(api, store);\n\n if (config.autoInject) {\n api.on('before_prompt_build', createContextHook(store, config));\n }\n },\n};\n\nexport default plugin;\n","export interface ResolvedConfig {\n path: string;\n format: 'yaml' | 'json';\n autoInject: boolean;\n autoInjectFilter: 'all';\n tokenBudget: number;\n}\n\n/**\n * Merge user-provided plugin config over defaults.\n * Infers format from path extension when not explicitly set.\n */\nexport function resolveConfig(raw: Record<string, unknown>): ResolvedConfig {\n const userPath = typeof raw.path === 'string' ? raw.path : 'edicts.yaml';\n\n let format: 'yaml' | 'json';\n if (raw.format === 'json' || raw.format === 'yaml') {\n format = raw.format;\n } else {\n format = userPath.endsWith('.json') ? 'json' : 'yaml';\n }\n\n return {\n path: userPath,\n format,\n autoInject: typeof raw.autoInject === 'boolean' ? raw.autoInject : true,\n autoInjectFilter: 'all',\n tokenBudget: typeof raw.tokenBudget === 'number' ? raw.tokenBudget : 2000,\n };\n}\n","import { renderPlain } from 'edicts';\nimport type { EdictStore } from 'edicts';\nimport type { ResolvedConfig } from './config.js';\n\n/**\n * Creates the before_prompt_build hook that injects edicts into system context.\n * v1: injects all edicts (autoInjectFilter = \"all\").\n */\nexport function createContextHook(\n store: EdictStore,\n config: ResolvedConfig,\n): () => Promise<{ appendSystemContext?: string } | Record<string, never>> {\n return async () => {\n try {\n await store.load();\n } catch {\n // File doesn't exist yet — empty store, nothing to inject\n return {};\n }\n\n const edicts = await store.all();\n\n if (edicts.length === 0) {\n return {};\n }\n\n const rendered = renderPlain(edicts);\n const appendSystemContext = wrapEdicts(rendered);\n\n return { appendSystemContext };\n };\n}\n\nfunction wrapEdicts(rendered: string): string {\n return [\n '## Edicts (Standing Instructions)',\n 'The following are your standing instructions. Follow them unless explicitly overridden.',\n '',\n rendered,\n ].join('\\n');\n}\n","import type { EdictStore } from 'edicts';\nimport type { EdictInput, FindQuery } from 'edicts';\nimport {\n EdictNotFoundError,\n EdictValidationError,\n EdictBudgetExceededError,\n EdictCountLimitError,\n EdictCategoryError,\n} from 'edicts';\n\ntype ToolResult = { content: Array<{ type: 'text'; text: string }> };\ntype Tool = {\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params?: any) => Promise<ToolResult>;\n};\n\nfunction text(msg: string): ToolResult {\n return { content: [{ type: 'text', text: msg }] };\n}\n\nfunction serialize(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\nfunction friendlyError(err: unknown): string {\n if (err instanceof EdictNotFoundError) return `No edict found with id '${(err as any).id ?? 'unknown'}'`;\n if (err instanceof EdictValidationError) return `Validation error: ${err.message}`;\n if (err instanceof EdictBudgetExceededError) return `Token budget exceeded: ${err.message}`;\n if (err instanceof EdictCountLimitError) return `Edict count limit reached: ${err.message}`;\n if (err instanceof EdictCategoryError) return `Category error: ${err.message}`;\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nconst TOOL_NAMES = [\n 'edicts_list',\n 'edicts_add',\n 'edicts_update',\n 'edicts_remove',\n 'edicts_search',\n 'edicts_stats',\n 'edicts_review',\n] as const;\n\nasync function ensureLoaded(store: EdictStore): Promise<EdictStore> {\n await store.load();\n return store;\n}\n\nfunction buildTools(store: EdictStore): Tool[] {\n return [\n {\n name: 'edicts_list',\n description: 'List edicts with optional filtering by category, tags, or ttl.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n limit: { type: 'number' },\n },\n },\n async execute(_id: string, params: FindQuery & { limit?: number } = {}) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.find(params);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts found matching the criteria.');\n return text(`${results.length} edict(s) found:\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error listing edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_add',\n description: 'Create a new edict (standing instruction).',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n source: { type: 'string' },\n key: { type: 'string' },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['text', 'category'],\n },\n async execute(_id: string, params: EdictInput) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.add(params);\n return text(`Edict created:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error adding edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_update',\n description: 'Update an existing edict by id.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string } & Partial<EdictInput>) {\n try {\n const { id, ...patch } = params;\n const s = await ensureLoaded(store);\n const result = await s.update(id, patch);\n return text(`Edict updated:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error updating edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_remove',\n description: 'Remove an edict.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string }) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.remove(params.id);\n return text(`Edict removed:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error removing edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_search',\n description: 'Free-text search across edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n query: { type: 'string' },\n limit: { type: 'number' },\n },\n required: ['query'],\n },\n async execute(_id: string, params: { query: string; limit?: number }) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.search(params.query);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts matched the search query.');\n return text(`${results.length} match(es):\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error searching edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_stats',\n description: 'Show edict store statistics.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {},\n },\n async execute() {\n try {\n const s = await ensureLoaded(store);\n const stats = await s.stats();\n return text(`Edict store statistics:\\n\\n${serialize(stats)}`);\n } catch (err: unknown) {\n return text(`Error fetching stats: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_review',\n description: 'Review and optionally clean up stale/expired edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n action: { type: 'string', enum: ['preview', 'compact'] },\n },\n },\n async execute(_id: string, params: { action?: 'preview' | 'compact' } = {}) {\n try {\n const s = await ensureLoaded(store);\n const action = params.action ?? 'preview';\n if (action === 'compact') {\n // compact() requires a callback-driven merge (group + merged edict).\n // For now, run review() and flag compaction candidates.\n const result = await s.review();\n return text(`Compaction candidates (auto-compact requires LLM callback — v2):\\n\\n${serialize(result)}`);\n }\n const result = await s.review();\n return text(`Review (preview):\\n\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error reviewing edicts: ${friendlyError(err)}`);\n }\n },\n },\n ];\n}\n\n/**\n * Register all edicts tools with the OpenClaw plugin API.\n * Tools are required (always available when plugin is enabled).\n */\nexport function registerEdictTools(\n api: { registerTool: (factory: () => Tool[], opts?: { names?: string[]; optional?: boolean }) => void },\n store: EdictStore,\n): void {\n api.registerTool(() => buildTools(store), {\n names: [...TOOL_NAMES],\n optional: false,\n });\n}\n"],"mappings":"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","names":["result"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts","../src/config.ts","../src/context.ts","../src/tools.ts"],"sourcesContent":["import { existsSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { EdictStore } from 'edicts';\nimport { resolveConfig } from './src/config.js';\nimport { createContextHook } from './src/context.js';\nimport { registerEdictTools } from './src/tools.js';\n\n/**\n * OpenClaw plugin API surface — types inferred from OpenClaw runtime.\n * No compile-time dependency on OpenClaw; the runtime provides the API object.\n */\nexport interface OpenClawPluginApi {\n pluginConfig?: Record<string, unknown>;\n workspaceDir?: string;\n resolvePath?(relativePath: string): string;\n registerTool(\n factory: () => Array<{\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params: any) => Promise<{ content: Array<{ type: 'text'; text: string }> }>;\n }>,\n opts?: { names?: string[]; optional?: boolean },\n ): void;\n on(\n hookName: 'before_prompt_build',\n handler: () => Promise<{ appendSystemContext?: string } | Record<string, never>>,\n ): void;\n}\n\n/**\n * Create a starter edicts.yaml if the file doesn't exist yet.\n * For OpenClaw users this means zero bootstrapping — install the plugin and go.\n */\nfunction ensureEdictsFile(filePath: string): void {\n if (existsSync(filePath)) return;\n const now = new Date().toISOString();\n const template = [\n 'version: 1',\n 'config:',\n ' maxEdicts: 200',\n ' tokenBudget: 4000',\n ' categories: []',\n 'edicts: []',\n 'history: []',\n '',\n ].join('\\n');\n writeFileSync(filePath, template, 'utf-8');\n}\n\nconst plugin = {\n id: 'openclaw-plugin-edicts',\n name: 'Edicts',\n description: 'Inject agent edicts into context and expose CRUD tools.',\n\n register(api: OpenClawPluginApi) {\n const config = resolveConfig(api.pluginConfig ?? {});\n\n // Resolve workspace dir: prefer resolvePath API, fall back to workspaceDir, then cwd\n const workspaceDir = api.resolvePath?.('.') ?? api.workspaceDir ?? null;\n if (!workspaceDir) {\n console.log('[edicts] register: no workspace dir available — skipping init (install-time probe)');\n return;\n }\n\n console.log(`[edicts] register: workspaceDir=${workspaceDir}, configPath=${config.path}`);\n\n const storePath = path.resolve(workspaceDir, config.path);\n\n // Auto-create edicts file on first run — no manual init needed\n ensureEdictsFile(storePath);\n\n const store = new EdictStore({\n path: storePath,\n format: config.format,\n tokenBudget: config.tokenBudget,\n autoSave: true,\n });\n\n registerEdictTools(api, store);\n\n if (config.autoInject) {\n api.on('before_prompt_build', createContextHook(store, config));\n }\n },\n};\n\nexport default plugin;\n","export interface ResolvedConfig {\n path: string;\n format: 'yaml' | 'json';\n autoInject: boolean;\n autoInjectFilter: 'all';\n tokenBudget: number;\n}\n\n/**\n * Merge user-provided plugin config over defaults.\n * Infers format from path extension when not explicitly set.\n */\nexport function resolveConfig(raw: Record<string, unknown>): ResolvedConfig {\n const userPath = typeof raw.path === 'string' ? raw.path : 'edicts.yaml';\n\n let format: 'yaml' | 'json';\n if (raw.format === 'json' || raw.format === 'yaml') {\n format = raw.format;\n } else {\n format = userPath.endsWith('.json') ? 'json' : 'yaml';\n }\n\n return {\n path: userPath,\n format,\n autoInject: typeof raw.autoInject === 'boolean' ? raw.autoInject : true,\n autoInjectFilter: 'all',\n tokenBudget: typeof raw.tokenBudget === 'number' ? raw.tokenBudget : 2000,\n };\n}\n","import { renderPlain } from 'edicts';\nimport type { EdictStore } from 'edicts';\nimport type { ResolvedConfig } from './config.js';\n\n/**\n * Creates the before_prompt_build hook that injects edicts into system context.\n * v1: injects all edicts (autoInjectFilter = \"all\").\n */\nexport function createContextHook(\n store: EdictStore,\n config: ResolvedConfig,\n): () => Promise<{ appendSystemContext?: string } | Record<string, never>> {\n return async () => {\n try {\n await store.load();\n } catch {\n // File doesn't exist yet — empty store, nothing to inject\n return {};\n }\n\n const edicts = await store.all();\n\n if (edicts.length === 0) {\n return {};\n }\n\n const rendered = renderPlain(edicts);\n const appendSystemContext = wrapEdicts(rendered);\n\n return { appendSystemContext };\n };\n}\n\nfunction wrapEdicts(rendered: string): string {\n return [\n '## Edicts (Standing Instructions)',\n 'The following are your standing instructions. Follow them unless explicitly overridden.',\n '',\n rendered,\n ].join('\\n');\n}\n","import type { EdictStore } from 'edicts';\nimport type { EdictInput, FindQuery } from 'edicts';\nimport {\n EdictNotFoundError,\n EdictValidationError,\n EdictBudgetExceededError,\n EdictCountLimitError,\n EdictCategoryError,\n} from 'edicts';\n\ntype ToolResult = { content: Array<{ type: 'text'; text: string }> };\ntype Tool = {\n name: string;\n description: string;\n parameters: unknown;\n execute: (id: string, params?: any) => Promise<ToolResult>;\n};\n\nfunction text(msg: string): ToolResult {\n return { content: [{ type: 'text', text: msg }] };\n}\n\nfunction serialize(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\nfunction friendlyError(err: unknown): string {\n if (err instanceof EdictNotFoundError) return `No edict found with id '${(err as any).id ?? 'unknown'}'`;\n if (err instanceof EdictValidationError) return `Validation error: ${err.message}`;\n if (err instanceof EdictBudgetExceededError) return `Token budget exceeded: ${err.message}`;\n if (err instanceof EdictCountLimitError) return `Edict count limit reached: ${err.message}`;\n if (err instanceof EdictCategoryError) return `Category error: ${err.message}`;\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nconst TOOL_NAMES = [\n 'edicts_list',\n 'edicts_add',\n 'edicts_update',\n 'edicts_remove',\n 'edicts_search',\n 'edicts_stats',\n 'edicts_review',\n] as const;\n\nasync function ensureLoaded(store: EdictStore): Promise<EdictStore> {\n await store.load();\n return store;\n}\n\nfunction buildTools(store: EdictStore): Tool[] {\n return [\n {\n name: 'edicts_list',\n description: 'List edicts with optional filtering by category, tags, or ttl.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n limit: { type: 'number' },\n },\n },\n async execute(_id: string, params: FindQuery & { limit?: number } = {}) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.find(params);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts found matching the criteria.');\n return text(`${results.length} edict(s) found:\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error listing edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_add',\n description: 'Create a new edict (standing instruction).',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n source: { type: 'string' },\n key: { type: 'string' },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['text', 'category'],\n },\n async execute(_id: string, params: EdictInput) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.add(params);\n return text(`Edict created:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error adding edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_update',\n description: 'Update an existing edict by id.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n text: { type: 'string' },\n category: { type: 'string' },\n tags: { type: 'array', items: { type: 'string' } },\n confidence: { type: 'string', enum: ['verified', 'inferred', 'user'] },\n ttl: { type: 'string', enum: ['ephemeral', 'event', 'durable', 'permanent'] },\n expiresAt: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string } & Partial<EdictInput>) {\n try {\n const { id, ...patch } = params;\n const s = await ensureLoaded(store);\n const result = await s.update(id, patch);\n return text(`Edict updated:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error updating edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_remove',\n description: 'Remove an edict.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n id: { type: 'string' },\n },\n required: ['id'],\n },\n async execute(_id: string, params: { id: string }) {\n try {\n const s = await ensureLoaded(store);\n const result = await s.remove(params.id);\n return text(`Edict removed:\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error removing edict: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_search',\n description: 'Free-text search across edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n query: { type: 'string' },\n limit: { type: 'number' },\n },\n required: ['query'],\n },\n async execute(_id: string, params: { query: string; limit?: number }) {\n try {\n const s = await ensureLoaded(store);\n let results = await s.search(params.query);\n if (typeof params.limit === 'number' && params.limit > 0) {\n results = results.slice(0, params.limit);\n }\n if (results.length === 0) return text('No edicts matched the search query.');\n return text(`${results.length} match(es):\\n\\n${serialize(results)}`);\n } catch (err: unknown) {\n return text(`Error searching edicts: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_stats',\n description: 'Show edict store statistics.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {},\n },\n async execute() {\n try {\n const s = await ensureLoaded(store);\n const stats = await s.stats();\n return text(`Edict store statistics:\\n\\n${serialize(stats)}`);\n } catch (err: unknown) {\n return text(`Error fetching stats: ${friendlyError(err)}`);\n }\n },\n },\n {\n name: 'edicts_review',\n description: 'Review and optionally clean up stale/expired edicts.',\n parameters: {\n type: 'object',\n additionalProperties: false,\n properties: {\n action: { type: 'string', enum: ['preview', 'compact'] },\n },\n },\n async execute(_id: string, params: { action?: 'preview' | 'compact' } = {}) {\n try {\n const s = await ensureLoaded(store);\n const action = params.action ?? 'preview';\n if (action === 'compact') {\n // compact() requires a callback-driven merge (group + merged edict).\n // For now, run review() and flag compaction candidates.\n const result = await s.review();\n return text(`Compaction candidates (auto-compact requires LLM callback — v2):\\n\\n${serialize(result)}`);\n }\n const result = await s.review();\n return text(`Review (preview):\\n\\n${serialize(result)}`);\n } catch (err: unknown) {\n return text(`Error reviewing edicts: ${friendlyError(err)}`);\n }\n },\n },\n ];\n}\n\n/**\n * Register all edicts tools with the OpenClaw plugin API.\n * Tools are required (always available when plugin is enabled).\n */\nexport function registerEdictTools(\n api: { registerTool: (factory: () => Tool[], opts?: { names?: string[]; optional?: boolean }) => void },\n store: EdictStore,\n): void {\n api.registerTool(() => buildTools(store), {\n names: [...TOOL_NAMES],\n optional: false,\n });\n}\n"],"mappings":"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","names":["result"]}
|