@agentmemory/agentmemory 0.9.29 → 0.9.30
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/.env.example +83 -22
- package/AGENTS.md +17 -24
- package/README.md +447 -170
- package/dist/.env.example +83 -22
- package/dist/cli.d.mts.map +1 -1
- package/dist/cli.mjs +1221 -335
- package/dist/cli.mjs.map +1 -1
- package/dist/{connect-Qaeq15TQ.mjs → connect-B4_ca6BD.mjs} +30 -39
- package/dist/connect-B4_ca6BD.mjs.map +1 -0
- package/dist/docker-compose.yml +40 -14
- package/dist/hooks/_capture.d.mts +22 -0
- package/dist/hooks/_capture.d.mts.map +1 -0
- package/dist/hooks/_capture.mjs +908 -0
- package/dist/hooks/_capture.mjs.map +1 -0
- package/dist/hooks/antigravity-bridge.d.mts +1 -1
- package/dist/hooks/antigravity-bridge.d.mts.map +1 -1
- package/dist/hooks/antigravity-bridge.mjs +24 -15
- package/dist/hooks/antigravity-bridge.mjs.map +1 -1
- package/dist/hooks/notification.mjs +17 -25
- package/dist/hooks/notification.mjs.map +1 -1
- package/dist/hooks/post-commit.mjs +71 -1
- package/dist/hooks/post-commit.mjs.map +1 -1
- package/dist/hooks/post-tool-failure.mjs +59 -25
- package/dist/hooks/post-tool-failure.mjs.map +1 -1
- package/dist/hooks/post-tool-use.mjs +87 -35
- package/dist/hooks/post-tool-use.mjs.map +1 -1
- package/dist/hooks/pre-compact.mjs +83 -3
- package/dist/hooks/pre-compact.mjs.map +1 -1
- package/dist/hooks/pre-tool-use.mjs +71 -1
- package/dist/hooks/pre-tool-use.mjs.map +1 -1
- package/dist/hooks/prompt-submit.mjs +13 -21
- package/dist/hooks/prompt-submit.mjs.map +1 -1
- package/dist/hooks/session-end.mjs +25 -20
- package/dist/hooks/session-end.mjs.map +1 -1
- package/dist/hooks/session-start.mjs +80 -3
- package/dist/hooks/session-start.mjs.map +1 -1
- package/dist/hooks/stop.mjs +71 -1
- package/dist/hooks/stop.mjs.map +1 -1
- package/dist/hooks/subagent-start.mjs +16 -25
- package/dist/hooks/subagent-start.mjs.map +1 -1
- package/dist/hooks/subagent-stop.mjs +17 -25
- package/dist/hooks/subagent-stop.mjs.map +1 -1
- package/dist/hooks/task-completed.mjs +19 -27
- package/dist/hooks/task-completed.mjs.map +1 -1
- package/dist/iii-config.docker.yaml +10 -10
- package/dist/iii-config.yaml +3 -1
- package/dist/{image-refs-BKLmp_sD.mjs → image-refs-BaT-9oMU.mjs} +2 -2
- package/dist/image-refs-BaT-9oMU.mjs.map +1 -0
- package/dist/{image-refs-CJgZmb9X.mjs → image-refs-T_urbwHM.mjs} +3 -3
- package/dist/image-refs-T_urbwHM.mjs.map +1 -0
- package/dist/{keyed-mutex-DTHtcZrt.mjs → image-store-BsN4vyjr.mjs} +2 -14
- package/dist/image-store-BsN4vyjr.mjs.map +1 -0
- package/dist/index.mjs +12943 -6218
- package/dist/index.mjs.map +1 -1
- package/dist/{schema-BFZhNTF7.mjs → keyed-mutex-DchXsyfP.mjs} +28 -4
- package/dist/keyed-mutex-DchXsyfP.mjs.map +1 -0
- package/dist/secret-store-BnY3A50C.mjs +2348 -0
- package/dist/secret-store-BnY3A50C.mjs.map +1 -0
- package/dist/{src-G7yt8gGm.mjs → src-Jsq9LCeH.mjs} +5941 -2180
- package/dist/src-Jsq9LCeH.mjs.map +1 -0
- package/dist/{standalone-BqNJDJ04.mjs → standalone-DKCdrf1d.mjs} +39 -12
- package/dist/standalone-DKCdrf1d.mjs.map +1 -0
- package/dist/standalone.d.mts.map +1 -1
- package/dist/standalone.mjs +249 -14
- package/dist/standalone.mjs.map +1 -1
- package/dist/status-IRz7ta8-.mjs +2344 -0
- package/dist/status-IRz7ta8-.mjs.map +1 -0
- package/dist/viewer/index.html +7224 -2794
- package/docker-compose.yml +40 -14
- package/iii-config.docker.yaml +10 -10
- package/iii-config.yaml +3 -1
- package/integrations/pi/index.ts +2 -3
- package/integrations/pi/security.ts +52 -0
- package/package.json +13 -4
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/.codex-plugin/plugin.json +26 -4
- package/plugin/.devin-plugin/plugin.json +1 -1
- package/plugin/.mcp.codex.json +12 -0
- package/plugin/.mcp.copilot.json +2 -7
- package/plugin/.mcp.json +2 -7
- package/plugin/assets/icon.svg +35 -0
- package/plugin/hooks/hooks.copilot.json +11 -11
- package/plugin/opencode/README.md +266 -30
- package/plugin/opencode/agentmemory-capture.ts +572 -3
- package/plugin/opencode/plugin.json +1 -1
- package/plugin/plugin.json +1 -1
- package/plugin/scripts/_capture.d.mts +22 -0
- package/plugin/scripts/_capture.d.mts.map +1 -0
- package/plugin/scripts/_capture.mjs +908 -0
- package/plugin/scripts/_capture.mjs.map +1 -0
- package/plugin/scripts/antigravity-bridge.d.mts +1 -1
- package/plugin/scripts/antigravity-bridge.d.mts.map +1 -1
- package/plugin/scripts/antigravity-bridge.mjs +24 -15
- package/plugin/scripts/antigravity-bridge.mjs.map +1 -1
- package/plugin/scripts/notification.mjs +17 -25
- package/plugin/scripts/notification.mjs.map +1 -1
- package/plugin/scripts/plugin-bridge.mjs +378 -0
- package/plugin/scripts/post-commit.mjs +71 -1
- package/plugin/scripts/post-commit.mjs.map +1 -1
- package/plugin/scripts/post-tool-failure.mjs +59 -25
- package/plugin/scripts/post-tool-failure.mjs.map +1 -1
- package/plugin/scripts/post-tool-use.mjs +87 -35
- package/plugin/scripts/post-tool-use.mjs.map +1 -1
- package/plugin/scripts/pre-compact.mjs +83 -3
- package/plugin/scripts/pre-compact.mjs.map +1 -1
- package/plugin/scripts/pre-tool-use.mjs +71 -1
- package/plugin/scripts/pre-tool-use.mjs.map +1 -1
- package/plugin/scripts/prompt-submit.mjs +13 -21
- package/plugin/scripts/prompt-submit.mjs.map +1 -1
- package/plugin/scripts/session-end.mjs +25 -20
- package/plugin/scripts/session-end.mjs.map +1 -1
- package/plugin/scripts/session-start.mjs +80 -3
- package/plugin/scripts/session-start.mjs.map +1 -1
- package/plugin/scripts/stop.mjs +71 -1
- package/plugin/scripts/stop.mjs.map +1 -1
- package/plugin/scripts/subagent-start.mjs +16 -25
- package/plugin/scripts/subagent-start.mjs.map +1 -1
- package/plugin/scripts/subagent-stop.mjs +17 -25
- package/plugin/scripts/subagent-stop.mjs.map +1 -1
- package/plugin/scripts/task-completed.mjs +19 -27
- package/plugin/scripts/task-completed.mjs.map +1 -1
- package/plugin/skills/_shared/TROUBLESHOOTING.md +22 -6
- package/plugin/skills/agentmemory-agents/REFERENCE.md +3 -3
- package/plugin/skills/agentmemory-config/REFERENCE.md +49 -1
- package/plugin/skills/agentmemory-config/SKILL.md +44 -7
- package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +1 -1
- package/plugin/skills/agentmemory-rest-api/REFERENCE.md +10 -2
- package/plugin/skills/handoff/SKILL.md +4 -2
- package/plugin/skills/memory-discipline/SKILL.md +13 -5
- package/dist/connect-Qaeq15TQ.mjs.map +0 -1
- package/dist/image-refs-BKLmp_sD.mjs.map +0 -1
- package/dist/image-refs-CJgZmb9X.mjs.map +0 -1
- package/dist/keyed-mutex-DTHtcZrt.mjs.map +0 -1
- package/dist/logger-BEB7pCI9.mjs +0 -43
- package/dist/logger-BEB7pCI9.mjs.map +0 -1
- package/dist/schema-BFZhNTF7.mjs.map +0 -1
- package/dist/src-G7yt8gGm.mjs.map +0 -1
- package/dist/standalone-BqNJDJ04.mjs.map +0 -1
- package/dist/tools-registry-BV_2bu7z.mjs +0 -1405
- package/dist/tools-registry-BV_2bu7z.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent-stop.mjs","names":[],"sources":["../../src/hooks/_project.ts","../../src/hooks/subagent-stop.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { basename } from \"node:path\";\n\n// Resolution order: AGENTMEMORY_PROJECT_NAME env → git toplevel basename → cwd basename.\nexport function resolveProject(cwd?: string): string {\n const explicit = process.env[\"AGENTMEMORY_PROJECT_NAME\"];\n if (explicit && explicit.trim()) return explicit.trim();\n const dir = cwd && cwd.trim() ? cwd : process.cwd();\n try {\n const top = execSync(\"git rev-parse --show-toplevel\", {\n cwd: dir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 500,\n })\n .toString()\n .trim();\n if (top) return basename(top);\n } catch {}\n return basename(dir);\n}\n\nexport function hookCwd(data: Record<string, unknown> | null | undefined): string | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n if (typeof data.cwd === \"string\" && data.cwd.trim()) return data.cwd;\n const roots = data.workspace_roots;\n if (Array.isArray(roots)) {\n for (const root of roots) {\n if (typeof root === \"string\" && root.trim()) return root;\n }\n }\n const projectDir =\n process.env[\"DEVIN_PROJECT_DIR\"] || process.env[\"CLAUDE_PROJECT_DIR\"];\n if (projectDir && projectDir.trim()) return projectDir;\n return undefined;\n}\n","#!/usr/bin/env node\nimport { resolveProject, hookCwd } from \"./_project.js\";\n\nfunction isSdkChildContext(payload: unknown): boolean {\n if (process.env[\"AGENTMEMORY_SDK_CHILD\"] === \"1\") return true;\n if (!payload || typeof payload !== \"object\") return false;\n return (payload as { entrypoint?: unknown }).entrypoint === \"sdk-ts\";\n}\n\nconst
|
|
1
|
+
{"version":3,"file":"subagent-stop.mjs","names":[],"sources":["../../src/hooks/_project.ts","../../src/hooks/subagent-stop.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { basename } from \"node:path\";\n\n// Resolution order: AGENTMEMORY_PROJECT_NAME env → git toplevel basename → cwd basename.\nexport function resolveProject(cwd?: string): string {\n const explicit = process.env[\"AGENTMEMORY_PROJECT_NAME\"];\n if (explicit && explicit.trim()) return explicit.trim();\n const dir = cwd && cwd.trim() ? cwd : process.cwd();\n try {\n const top = execSync(\"git rev-parse --show-toplevel\", {\n cwd: dir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 500,\n })\n .toString()\n .trim();\n if (top) return basename(top);\n } catch {}\n return basename(dir);\n}\n\nexport function hookCwd(data: Record<string, unknown> | null | undefined): string | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n if (typeof data.cwd === \"string\" && data.cwd.trim()) return data.cwd;\n const roots = data.workspace_roots;\n if (Array.isArray(roots)) {\n for (const root of roots) {\n if (typeof root === \"string\" && root.trim()) return root;\n }\n }\n const projectDir =\n process.env[\"DEVIN_PROJECT_DIR\"] || process.env[\"CLAUDE_PROJECT_DIR\"];\n if (projectDir && projectDir.trim()) return projectDir;\n return undefined;\n}\n","#!/usr/bin/env node\nimport { resolveProject, hookCwd } from \"./_project.js\";\nimport { captureObservation, isDrainChild, runDrainChild, withEventId } from \"./_capture.js\";\n\nfunction isSdkChildContext(payload: unknown): boolean {\n if (process.env[\"AGENTMEMORY_SDK_CHILD\"] === \"1\") return true;\n if (!payload || typeof payload !== \"object\") return false;\n return (payload as { entrypoint?: unknown }).entrypoint === \"sdk-ts\";\n}\n\nconst OBSERVE_TIMEOUT_MS = 2000;\nconst EXIT_CAP_MS = 2500;\n\nasync function main() {\n if (isDrainChild()) return runDrainChild();\n let input = \"\";\n for await (const chunk of process.stdin) {\n input += chunk;\n }\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(input);\n } catch {\n return;\n }\n\n if (!data || typeof data !== \"object\") return;\n if (isSdkChildContext(data)) return;\n\n const sessionId = ((data.session_id || data.sessionId || data.conversation_id) as string) || \"unknown\";\n const agentId = data.agent_id || data.agentName;\n const agentType = data.agent_type || data.agentDisplayName || data.agentName;\n const lastMsg =\n typeof data.last_assistant_message === \"string\"\n ? data.last_assistant_message.slice(0, 4000)\n : \"\";\n\n const cwd = hookCwd(data) || process.cwd();\n\n void captureObservation(\n withEventId(\n {\n hookType: \"subagent_stop\",\n sessionId,\n project: resolveProject(cwd),\n cwd,\n timestamp: new Date().toISOString(),\n data: {\n agent_id: agentId,\n agent_type: agentType,\n last_message: lastMsg,\n },\n },\n data,\n ),\n OBSERVE_TIMEOUT_MS,\n );\n setTimeout(() => process.exit(0), EXIT_CAP_MS).unref();\n}\n\nmain().catch(() => process.exit(0));\n"],"mappings":";;;;;AAIA,SAAgB,eAAe,KAAsB;CACnD,MAAM,WAAW,QAAQ,IAAI;AAC7B,KAAI,YAAY,SAAS,MAAM,CAAE,QAAO,SAAS,MAAM;CACvD,MAAM,MAAM,OAAO,IAAI,MAAM,GAAG,MAAM,QAAQ,KAAK;AACnD,KAAI;EACF,MAAM,MAAM,SAAS,iCAAiC;GACpD,KAAK;GACL,OAAO;IAAC;IAAU;IAAQ;IAAS;GACnC,SAAS;GACV,CAAC,CACC,UAAU,CACV,MAAM;AACT,MAAI,IAAK,QAAO,SAAS,IAAI;SACvB;AACR,QAAO,SAAS,IAAI;;AAGtB,SAAgB,QAAQ,MAAsE;AAC5F,KAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO,KAAA;AAC9C,KAAI,OAAO,KAAK,QAAQ,YAAY,KAAK,IAAI,MAAM,CAAE,QAAO,KAAK;CACjE,MAAM,QAAQ,KAAK;AACnB,KAAI,MAAM,QAAQ,MAAM;OACjB,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,YAAY,KAAK,MAAM,CAAE,QAAO;;CAGxD,MAAM,aACJ,QAAQ,IAAI,wBAAwB,QAAQ,IAAI;AAClD,KAAI,cAAc,WAAW,MAAM,CAAE,QAAO;;;;AC5B9C,SAAS,kBAAkB,SAA2B;AACpD,KAAI,QAAQ,IAAI,6BAA6B,IAAK,QAAO;AACzD,KAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,QAAQ,QAAqC,eAAe;;AAG9D,MAAM,qBAAqB;AAC3B,MAAM,cAAc;AAEpB,eAAe,OAAO;AACpB,KAAI,cAAc,CAAE,QAAO,eAAe;CAC1C,IAAI,QAAQ;AACZ,YAAW,MAAM,SAAS,QAAQ,MAChC,UAAS;CAGX,IAAI;AACJ,KAAI;AACF,SAAO,KAAK,MAAM,MAAM;SAClB;AACN;;AAGF,KAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,KAAI,kBAAkB,KAAK,CAAE;CAE7B,MAAM,YAAc,KAAK,cAAc,KAAK,aAAa,KAAK,mBAA+B;CAC7F,MAAM,UAAU,KAAK,YAAY,KAAK;CACtC,MAAM,YAAY,KAAK,cAAc,KAAK,oBAAoB,KAAK;CACnE,MAAM,UACJ,OAAO,KAAK,2BAA2B,WACnC,KAAK,uBAAuB,MAAM,GAAG,IAAK,GAC1C;CAEN,MAAM,MAAM,QAAQ,KAAK,IAAI,QAAQ,KAAK;AAErC,oBACH,YACE;EACE,UAAU;EACV;EACA,SAAS,eAAe,IAAI;EAC5B;EACA,4BAAW,IAAI,MAAM,EAAC,aAAa;EACnC,MAAM;GACJ,UAAU;GACV,YAAY;GACZ,cAAc;GACf;EACF,EACD,KACD,EACD,mBACD;AACD,kBAAiB,QAAQ,KAAK,EAAE,EAAE,YAAY,CAAC,OAAO;;AAGxD,MAAM,CAAC,YAAY,QAAQ,KAAK,EAAE,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { execSync } from "node:child_process";
|
|
3
3
|
import { basename } from "node:path";
|
|
4
|
+
import { captureObservation, isDrainChild, runDrainChild, withEventId } from "./_capture.mjs";
|
|
4
5
|
//#region src/hooks/_project.ts
|
|
5
6
|
function resolveProject(cwd) {
|
|
6
7
|
const explicit = process.env["AGENTMEMORY_PROJECT_NAME"];
|
|
@@ -37,14 +38,10 @@ function isSdkChildContext(payload) {
|
|
|
37
38
|
if (!payload || typeof payload !== "object") return false;
|
|
38
39
|
return payload.entrypoint === "sdk-ts";
|
|
39
40
|
}
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
function authHeaders() {
|
|
43
|
-
const h = { "Content-Type": "application/json" };
|
|
44
|
-
if (SECRET) h["Authorization"] = `Bearer ${SECRET}`;
|
|
45
|
-
return h;
|
|
46
|
-
}
|
|
41
|
+
const OBSERVE_TIMEOUT_MS = 2e3;
|
|
42
|
+
const EXIT_CAP_MS = 2500;
|
|
47
43
|
async function main() {
|
|
44
|
+
if (isDrainChild()) return runDrainChild();
|
|
48
45
|
let input = "";
|
|
49
46
|
for await (const chunk of process.stdin) input += chunk;
|
|
50
47
|
let data;
|
|
@@ -57,26 +54,21 @@ async function main() {
|
|
|
57
54
|
if (isSdkChildContext(data)) return;
|
|
58
55
|
const sessionId = data.session_id || data.sessionId || data.conversation_id || "unknown";
|
|
59
56
|
const cwd = hookCwd(data) || process.cwd();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
data:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
}),
|
|
77
|
-
signal: AbortSignal.timeout(2e3)
|
|
78
|
-
}).catch(() => {});
|
|
79
|
-
setTimeout(() => process.exit(0), 500).unref();
|
|
57
|
+
captureObservation(withEventId({
|
|
58
|
+
hookType: "task_completed",
|
|
59
|
+
sessionId,
|
|
60
|
+
project: resolveProject(cwd),
|
|
61
|
+
cwd,
|
|
62
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
63
|
+
data: {
|
|
64
|
+
task_id: data.task_id,
|
|
65
|
+
task_subject: data.task_subject,
|
|
66
|
+
task_description: typeof data.task_description === "string" ? data.task_description.slice(0, 2e3) : "",
|
|
67
|
+
teammate_name: data.teammate_name,
|
|
68
|
+
team_name: data.team_name
|
|
69
|
+
}
|
|
70
|
+
}, data), OBSERVE_TIMEOUT_MS);
|
|
71
|
+
setTimeout(() => process.exit(0), EXIT_CAP_MS).unref();
|
|
80
72
|
}
|
|
81
73
|
main().catch(() => process.exit(0));
|
|
82
74
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-completed.mjs","names":[],"sources":["../../src/hooks/_project.ts","../../src/hooks/task-completed.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { basename } from \"node:path\";\n\n// Resolution order: AGENTMEMORY_PROJECT_NAME env → git toplevel basename → cwd basename.\nexport function resolveProject(cwd?: string): string {\n const explicit = process.env[\"AGENTMEMORY_PROJECT_NAME\"];\n if (explicit && explicit.trim()) return explicit.trim();\n const dir = cwd && cwd.trim() ? cwd : process.cwd();\n try {\n const top = execSync(\"git rev-parse --show-toplevel\", {\n cwd: dir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 500,\n })\n .toString()\n .trim();\n if (top) return basename(top);\n } catch {}\n return basename(dir);\n}\n\nexport function hookCwd(data: Record<string, unknown> | null | undefined): string | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n if (typeof data.cwd === \"string\" && data.cwd.trim()) return data.cwd;\n const roots = data.workspace_roots;\n if (Array.isArray(roots)) {\n for (const root of roots) {\n if (typeof root === \"string\" && root.trim()) return root;\n }\n }\n const projectDir =\n process.env[\"DEVIN_PROJECT_DIR\"] || process.env[\"CLAUDE_PROJECT_DIR\"];\n if (projectDir && projectDir.trim()) return projectDir;\n return undefined;\n}\n","#!/usr/bin/env node\nimport { resolveProject, hookCwd } from \"./_project.js\";\n\nfunction isSdkChildContext(payload: unknown): boolean {\n if (process.env[\"AGENTMEMORY_SDK_CHILD\"] === \"1\") return true;\n if (!payload || typeof payload !== \"object\") return false;\n return (payload as { entrypoint?: unknown }).entrypoint === \"sdk-ts\";\n}\n\nconst
|
|
1
|
+
{"version":3,"file":"task-completed.mjs","names":[],"sources":["../../src/hooks/_project.ts","../../src/hooks/task-completed.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport { basename } from \"node:path\";\n\n// Resolution order: AGENTMEMORY_PROJECT_NAME env → git toplevel basename → cwd basename.\nexport function resolveProject(cwd?: string): string {\n const explicit = process.env[\"AGENTMEMORY_PROJECT_NAME\"];\n if (explicit && explicit.trim()) return explicit.trim();\n const dir = cwd && cwd.trim() ? cwd : process.cwd();\n try {\n const top = execSync(\"git rev-parse --show-toplevel\", {\n cwd: dir,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n timeout: 500,\n })\n .toString()\n .trim();\n if (top) return basename(top);\n } catch {}\n return basename(dir);\n}\n\nexport function hookCwd(data: Record<string, unknown> | null | undefined): string | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n if (typeof data.cwd === \"string\" && data.cwd.trim()) return data.cwd;\n const roots = data.workspace_roots;\n if (Array.isArray(roots)) {\n for (const root of roots) {\n if (typeof root === \"string\" && root.trim()) return root;\n }\n }\n const projectDir =\n process.env[\"DEVIN_PROJECT_DIR\"] || process.env[\"CLAUDE_PROJECT_DIR\"];\n if (projectDir && projectDir.trim()) return projectDir;\n return undefined;\n}\n","#!/usr/bin/env node\nimport { resolveProject, hookCwd } from \"./_project.js\";\nimport { captureObservation, isDrainChild, runDrainChild, withEventId } from \"./_capture.js\";\n\nfunction isSdkChildContext(payload: unknown): boolean {\n if (process.env[\"AGENTMEMORY_SDK_CHILD\"] === \"1\") return true;\n if (!payload || typeof payload !== \"object\") return false;\n return (payload as { entrypoint?: unknown }).entrypoint === \"sdk-ts\";\n}\n\nconst OBSERVE_TIMEOUT_MS = 2000;\nconst EXIT_CAP_MS = 2500;\n\nasync function main() {\n if (isDrainChild()) return runDrainChild();\n let input = \"\";\n for await (const chunk of process.stdin) {\n input += chunk;\n }\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(input);\n } catch {\n return;\n }\n\n if (!data || typeof data !== \"object\") return;\n if (isSdkChildContext(data)) return;\n\n const sessionId = ((data.session_id || data.sessionId || data.conversation_id) as string) || \"unknown\";\n\n const cwd = hookCwd(data) || process.cwd();\n\n void captureObservation(\n withEventId(\n {\n hookType: \"task_completed\",\n sessionId,\n project: resolveProject(cwd),\n cwd,\n timestamp: new Date().toISOString(),\n data: {\n task_id: data.task_id,\n task_subject: data.task_subject,\n task_description: typeof data.task_description === \"string\"\n ? data.task_description.slice(0, 2000)\n : \"\",\n teammate_name: data.teammate_name,\n team_name: data.team_name,\n },\n },\n data,\n ),\n OBSERVE_TIMEOUT_MS,\n );\n setTimeout(() => process.exit(0), EXIT_CAP_MS).unref();\n}\n\nmain().catch(() => process.exit(0));\n"],"mappings":";;;;;AAIA,SAAgB,eAAe,KAAsB;CACnD,MAAM,WAAW,QAAQ,IAAI;AAC7B,KAAI,YAAY,SAAS,MAAM,CAAE,QAAO,SAAS,MAAM;CACvD,MAAM,MAAM,OAAO,IAAI,MAAM,GAAG,MAAM,QAAQ,KAAK;AACnD,KAAI;EACF,MAAM,MAAM,SAAS,iCAAiC;GACpD,KAAK;GACL,OAAO;IAAC;IAAU;IAAQ;IAAS;GACnC,SAAS;GACV,CAAC,CACC,UAAU,CACV,MAAM;AACT,MAAI,IAAK,QAAO,SAAS,IAAI;SACvB;AACR,QAAO,SAAS,IAAI;;AAGtB,SAAgB,QAAQ,MAAsE;AAC5F,KAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO,KAAA;AAC9C,KAAI,OAAO,KAAK,QAAQ,YAAY,KAAK,IAAI,MAAM,CAAE,QAAO,KAAK;CACjE,MAAM,QAAQ,KAAK;AACnB,KAAI,MAAM,QAAQ,MAAM;OACjB,MAAM,QAAQ,MACjB,KAAI,OAAO,SAAS,YAAY,KAAK,MAAM,CAAE,QAAO;;CAGxD,MAAM,aACJ,QAAQ,IAAI,wBAAwB,QAAQ,IAAI;AAClD,KAAI,cAAc,WAAW,MAAM,CAAE,QAAO;;;;AC5B9C,SAAS,kBAAkB,SAA2B;AACpD,KAAI,QAAQ,IAAI,6BAA6B,IAAK,QAAO;AACzD,KAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AACpD,QAAQ,QAAqC,eAAe;;AAG9D,MAAM,qBAAqB;AAC3B,MAAM,cAAc;AAEpB,eAAe,OAAO;AACpB,KAAI,cAAc,CAAE,QAAO,eAAe;CAC1C,IAAI,QAAQ;AACZ,YAAW,MAAM,SAAS,QAAQ,MAChC,UAAS;CAGX,IAAI;AACJ,KAAI;AACF,SAAO,KAAK,MAAM,MAAM;SAClB;AACN;;AAGF,KAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,KAAI,kBAAkB,KAAK,CAAE;CAE7B,MAAM,YAAc,KAAK,cAAc,KAAK,aAAa,KAAK,mBAA+B;CAE7F,MAAM,MAAM,QAAQ,KAAK,IAAI,QAAQ,KAAK;AAErC,oBACH,YACE;EACE,UAAU;EACV;EACA,SAAS,eAAe,IAAI;EAC5B;EACA,4BAAW,IAAI,MAAM,EAAC,aAAa;EACnC,MAAM;GACJ,SAAS,KAAK;GACd,cAAc,KAAK;GACnB,kBAAkB,OAAO,KAAK,qBAAqB,WAC/C,KAAK,iBAAiB,MAAM,GAAG,IAAK,GACpC;GACJ,eAAe,KAAK;GACpB,WAAW,KAAK;GACjB;EACF,EACD,KACD,EACD,mBACD;AACD,kBAAiB,QAAQ,KAAK,EAAE,EAAE,YAAY,CAAC,OAAO;;AAGxD,MAAM,CAAC,YAAY,QAAQ,KAAK,EAAE,CAAC"}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
workers:
|
|
2
2
|
- name: iii-http
|
|
3
3
|
config:
|
|
4
|
-
port: 3111
|
|
4
|
+
port: ${III_REST_PORT:3111}
|
|
5
5
|
host: 0.0.0.0
|
|
6
6
|
default_timeout: 180000
|
|
7
7
|
cors:
|
|
8
|
-
allowed_origins: ["http://localhost:3111", "http://localhost:3113", "http://127.0.0.1:3111", "http://127.0.0.1:3113"]
|
|
8
|
+
allowed_origins: ["http://localhost:${III_REST_PORT:3111}", "http://localhost:${III_VIEWER_PORT:3113}", "http://127.0.0.1:${III_REST_PORT:3111}", "http://127.0.0.1:${III_VIEWER_PORT:3113}"]
|
|
9
9
|
allowed_methods: [GET, POST, PUT, DELETE, OPTIONS]
|
|
10
|
+
- name: iii-worker-manager
|
|
11
|
+
config:
|
|
12
|
+
port: ${III_ENGINE_PORT:49134}
|
|
13
|
+
host: 0.0.0.0
|
|
10
14
|
- name: iii-state
|
|
11
15
|
config:
|
|
12
16
|
adapter:
|
|
13
17
|
name: kv
|
|
14
18
|
config:
|
|
15
19
|
store_method: file_based
|
|
20
|
+
save_interval_ms: ${AGENTMEMORY_STATE_SAVE_INTERVAL_MS:2000}
|
|
16
21
|
file_path: /data/state_store.db
|
|
17
22
|
- name: iii-queue
|
|
18
23
|
config:
|
|
@@ -28,26 +33,21 @@ workers:
|
|
|
28
33
|
name: kv
|
|
29
34
|
- name: iii-stream
|
|
30
35
|
config:
|
|
31
|
-
port: 3112
|
|
36
|
+
port: ${III_STREAM_PORT:3112}
|
|
32
37
|
host: 0.0.0.0
|
|
33
38
|
adapter:
|
|
34
39
|
name: kv
|
|
35
40
|
config:
|
|
36
41
|
store_method: file_based
|
|
42
|
+
save_interval_ms: ${AGENTMEMORY_STATE_SAVE_INTERVAL_MS:2000}
|
|
37
43
|
file_path: /data/stream_store
|
|
38
44
|
- name: iii-observability
|
|
39
45
|
config:
|
|
40
46
|
enabled: true
|
|
41
47
|
service_name: agentmemory
|
|
42
48
|
exporter: memory
|
|
43
|
-
# See iii-config.yaml for the rationale on 0.1 / console-off
|
|
49
|
+
# See iii-config.yaml for the rationale on 0.1 / console-off.
|
|
44
50
|
sampling_ratio: 0.1
|
|
45
51
|
metrics_enabled: true
|
|
46
52
|
logs_enabled: true
|
|
47
53
|
logs_console_output: false
|
|
48
|
-
- name: iii-exec
|
|
49
|
-
config:
|
|
50
|
-
watch:
|
|
51
|
-
- src/**/*.ts
|
|
52
|
-
exec:
|
|
53
|
-
- node dist/index.mjs
|
package/dist/iii-config.yaml
CHANGED
|
@@ -13,6 +13,7 @@ workers:
|
|
|
13
13
|
name: kv
|
|
14
14
|
config:
|
|
15
15
|
store_method: file_based
|
|
16
|
+
save_interval_ms: 2000
|
|
16
17
|
file_path: ./data/state_store.db
|
|
17
18
|
- name: iii-queue
|
|
18
19
|
config:
|
|
@@ -34,6 +35,7 @@ workers:
|
|
|
34
35
|
name: kv
|
|
35
36
|
config:
|
|
36
37
|
store_method: file_based
|
|
38
|
+
save_interval_ms: 2000
|
|
37
39
|
file_path: ./data/stream_store
|
|
38
40
|
- name: iii-observability
|
|
39
41
|
config:
|
|
@@ -45,7 +47,7 @@ workers:
|
|
|
45
47
|
# subscriber lagged" WARN, and that WARN re-enters the same
|
|
46
48
|
# stream the subscriber is failing to drain — a positive
|
|
47
49
|
# feedback loop that wrote 137 GB to daemon.log.new on one user
|
|
48
|
-
# in a few days
|
|
50
|
+
# in a few days.
|
|
49
51
|
sampling_ratio: 0.1
|
|
50
52
|
metrics_enabled: true
|
|
51
53
|
logs_enabled: true
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as
|
|
2
|
+
import { i as withKeyedLock, n as touchImage, r as KV, t as deleteImage } from "./index.mjs";
|
|
3
3
|
import { TriggerAction } from "iii-sdk";
|
|
4
4
|
//#region src/functions/image-refs.ts
|
|
5
5
|
async function getImageRefCount(kv, filePath) {
|
|
@@ -31,4 +31,4 @@ async function decrementImageRef(kv, sdk, filePath) {
|
|
|
31
31
|
//#endregion
|
|
32
32
|
export { decrementImageRef, getImageRefCount, incrementImageRef };
|
|
33
33
|
|
|
34
|
-
//# sourceMappingURL=image-refs-
|
|
34
|
+
//# sourceMappingURL=image-refs-BaT-9oMU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-refs-BaT-9oMU.mjs","names":[],"sources":["../src/functions/image-refs.ts"],"sourcesContent":["import { TriggerAction, type IIIClient } from \"iii-sdk\";\nimport { KV } from \"../state/schema.js\";\nimport { StateKV } from \"../state/kv.js\";\nimport { deleteImage, touchImage } from \"../utils/image-store.js\";\nimport { withKeyedLock } from \"../state/keyed-mutex.js\";\n\nexport async function getImageRefCount(kv: StateKV, filePath: string): Promise<number> {\n const count = await kv.get<number>(KV.imageRefs, filePath);\n return count ? Number(count) : 0;\n}\n\nexport async function incrementImageRef(kv: StateKV, filePath: string): Promise<void> {\n return withKeyedLock(`imgRef:${filePath}`, async () => {\n const current = await getImageRefCount(kv, filePath);\n await kv.set(KV.imageRefs, filePath, current + 1);\n await touchImage(filePath);\n });\n}\n\nexport async function decrementImageRef(kv: StateKV, sdk: IIIClient, filePath: string): Promise<void> {\n return withKeyedLock(`imgRef:${filePath}`, async () => {\n const current = await getImageRefCount(kv, filePath);\n if (current <= 1) {\n await kv.delete(KV.imageEmbeddings, filePath);\n await kv.delete(KV.imageRefs, filePath);\n const { deletedBytes } = await deleteImage(filePath);\n if (deletedBytes > 0) {\n sdk.trigger({\n function_id: \"mem::disk-size-delta\",\n payload: { deltaBytes: -deletedBytes },\n action: TriggerAction.Void(),\n });\n }\n } else {\n await kv.set(KV.imageRefs, filePath, current - 1);\n }\n });\n}\n"],"mappings":";;;;AAMA,eAAsB,iBAAiB,IAAa,UAAmC;CACrF,MAAM,QAAQ,MAAM,GAAG,IAAY,GAAG,WAAW,SAAS;AAC1D,QAAO,QAAQ,OAAO,MAAM,GAAG;;AAGjC,eAAsB,kBAAkB,IAAa,UAAiC;AACpF,QAAO,cAAc,UAAU,YAAY,YAAY;EACrD,MAAM,UAAU,MAAM,iBAAiB,IAAI,SAAS;AACpD,QAAM,GAAG,IAAI,GAAG,WAAW,UAAU,UAAU,EAAE;AACjD,QAAM,WAAW,SAAS;GAC1B;;AAGJ,eAAsB,kBAAkB,IAAa,KAAgB,UAAiC;AACpG,QAAO,cAAc,UAAU,YAAY,YAAY;EACrD,MAAM,UAAU,MAAM,iBAAiB,IAAI,SAAS;AACpD,MAAI,WAAW,GAAG;AAChB,SAAM,GAAG,OAAO,GAAG,iBAAiB,SAAS;AAC7C,SAAM,GAAG,OAAO,GAAG,WAAW,SAAS;GACvC,MAAM,EAAE,iBAAiB,MAAM,YAAY,SAAS;AACpD,OAAI,eAAe,EACjB,KAAI,QAAQ;IACV,aAAa;IACb,SAAS,EAAE,YAAY,CAAC,cAAc;IACtC,QAAQ,cAAc,MAAM;IAC7B,CAAC;QAGJ,OAAM,GAAG,IAAI,GAAG,WAAW,UAAU,UAAU,EAAE;GAEnD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as KV, t as withKeyedLock } from "./keyed-mutex-DchXsyfP.mjs";
|
|
2
|
+
import { n as deleteImage, o as touchImage } from "./image-store-BsN4vyjr.mjs";
|
|
3
3
|
import { TriggerAction } from "iii-sdk";
|
|
4
4
|
//#region src/functions/image-refs.ts
|
|
5
5
|
async function getImageRefCount(kv, filePath) {
|
|
@@ -31,4 +31,4 @@ async function decrementImageRef(kv, sdk, filePath) {
|
|
|
31
31
|
//#endregion
|
|
32
32
|
export { decrementImageRef, getImageRefCount, incrementImageRef };
|
|
33
33
|
|
|
34
|
-
//# sourceMappingURL=image-refs-
|
|
34
|
+
//# sourceMappingURL=image-refs-T_urbwHM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-refs-T_urbwHM.mjs","names":[],"sources":["../src/functions/image-refs.ts"],"sourcesContent":["import { TriggerAction, type IIIClient } from \"iii-sdk\";\nimport { KV } from \"../state/schema.js\";\nimport { StateKV } from \"../state/kv.js\";\nimport { deleteImage, touchImage } from \"../utils/image-store.js\";\nimport { withKeyedLock } from \"../state/keyed-mutex.js\";\n\nexport async function getImageRefCount(kv: StateKV, filePath: string): Promise<number> {\n const count = await kv.get<number>(KV.imageRefs, filePath);\n return count ? Number(count) : 0;\n}\n\nexport async function incrementImageRef(kv: StateKV, filePath: string): Promise<void> {\n return withKeyedLock(`imgRef:${filePath}`, async () => {\n const current = await getImageRefCount(kv, filePath);\n await kv.set(KV.imageRefs, filePath, current + 1);\n await touchImage(filePath);\n });\n}\n\nexport async function decrementImageRef(kv: StateKV, sdk: IIIClient, filePath: string): Promise<void> {\n return withKeyedLock(`imgRef:${filePath}`, async () => {\n const current = await getImageRefCount(kv, filePath);\n if (current <= 1) {\n await kv.delete(KV.imageEmbeddings, filePath);\n await kv.delete(KV.imageRefs, filePath);\n const { deletedBytes } = await deleteImage(filePath);\n if (deletedBytes > 0) {\n sdk.trigger({\n function_id: \"mem::disk-size-delta\",\n payload: { deltaBytes: -deletedBytes },\n action: TriggerAction.Void(),\n });\n }\n } else {\n await kv.set(KV.imageRefs, filePath, current - 1);\n }\n });\n}\n"],"mappings":";;;;AAMA,eAAsB,iBAAiB,IAAa,UAAmC;CACrF,MAAM,QAAQ,MAAM,GAAG,IAAY,GAAG,WAAW,SAAS;AAC1D,QAAO,QAAQ,OAAO,MAAM,GAAG;;AAGjC,eAAsB,kBAAkB,IAAa,UAAiC;AACpF,QAAO,cAAc,UAAU,YAAY,YAAY;EACrD,MAAM,UAAU,MAAM,iBAAiB,IAAI,SAAS;AACpD,QAAM,GAAG,IAAI,GAAG,WAAW,UAAU,UAAU,EAAE;AACjD,QAAM,WAAW,SAAS;GAC1B;;AAGJ,eAAsB,kBAAkB,IAAa,KAAgB,UAAiC;AACpG,QAAO,cAAc,UAAU,YAAY,YAAY;EACrD,MAAM,UAAU,MAAM,iBAAiB,IAAI,SAAS;AACpD,MAAI,WAAW,GAAG;AAChB,SAAM,GAAG,OAAO,GAAG,iBAAiB,SAAS;AAC7C,SAAM,GAAG,OAAO,GAAG,WAAW,SAAS;GACvC,MAAM,EAAE,iBAAiB,MAAM,YAAY,SAAS;AACpD,OAAI,eAAe,EACjB,KAAI,QAAQ;IACV,aAAa;IACb,SAAS,EAAE,YAAY,CAAC,cAAc;IACtC,QAAQ,cAAc,MAAM;IAC7B,CAAC;QAGJ,OAAM,GAAG,IAAI,GAAG,WAAW,UAAU,UAAU,EAAE;GAEnD"}
|
|
@@ -71,18 +71,6 @@ async function touchImage(filePath) {
|
|
|
71
71
|
} catch (err) {}
|
|
72
72
|
}
|
|
73
73
|
//#endregion
|
|
74
|
-
|
|
75
|
-
const locks = /* @__PURE__ */ new Map();
|
|
76
|
-
function withKeyedLock(key, fn) {
|
|
77
|
-
const next = (locks.get(key) ?? Promise.resolve()).then(fn, fn);
|
|
78
|
-
const cleanup = next.then(() => {}, () => {});
|
|
79
|
-
locks.set(key, cleanup);
|
|
80
|
-
cleanup.then(() => {
|
|
81
|
-
if (locks.get(key) === cleanup) locks.delete(key);
|
|
82
|
-
});
|
|
83
|
-
return next;
|
|
84
|
-
}
|
|
85
|
-
//#endregion
|
|
86
|
-
export { isManagedImagePath as a, getMaxBytes as i, IMAGES_DIR as n, saveImageToDisk as o, deleteImage as r, touchImage as s, withKeyedLock as t };
|
|
74
|
+
export { saveImageToDisk as a, isManagedImagePath as i, deleteImage as n, touchImage as o, getMaxBytes as r, IMAGES_DIR as t };
|
|
87
75
|
|
|
88
|
-
//# sourceMappingURL=
|
|
76
|
+
//# sourceMappingURL=image-store-BsN4vyjr.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-store-BsN4vyjr.mjs","names":[],"sources":["../src/utils/image-store.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join, resolve, sep } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, writeFile, unlink, utimes, stat } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\n\nexport const IMAGES_DIR = join(homedir(), \".agentmemory\", \"images\");\n\nconst DEFAULT_MAX_BYTES = 500 * 1024 * 1024;\n\nexport function getMaxBytes(): number {\n return Number(process.env.AGENTMEMORY_IMAGE_STORE_MAX_BYTES) || DEFAULT_MAX_BYTES;\n}\n\nexport function isManagedImagePath(filePath: string): boolean {\n const resolved = resolve(filePath);\n const normalizedImagesDir = resolve(IMAGES_DIR);\n return resolved.startsWith(normalizedImagesDir + sep) || resolved === normalizedImagesDir;\n}\n\nfunction contentHash(data: string): string {\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\nexport async function saveImageToDisk(base64Data: string): Promise<{ filePath: string; bytesWritten: number }> {\n if (!base64Data) return { filePath: \"\", bytesWritten: 0 };\n\n if (!existsSync(IMAGES_DIR)) {\n await mkdir(IMAGES_DIR, { recursive: true });\n }\n\n let cleanBase64 = base64Data;\n let ext = \"png\";\n\n if (base64Data.startsWith(\"data:image/\")) {\n const commaIdx = base64Data.indexOf(\",\");\n if (commaIdx !== -1) {\n const meta = base64Data.substring(0, commaIdx);\n if (meta.includes(\"jpeg\") || meta.includes(\"jpg\")) ext = \"jpg\";\n else if (meta.includes(\"webp\")) ext = \"webp\";\n else if (meta.includes(\"gif\")) ext = \"gif\";\n cleanBase64 = base64Data.substring(commaIdx + 1);\n }\n } else if (base64Data.startsWith(\"/9j/\")) {\n ext = \"jpg\";\n }\n\n const hash = contentHash(cleanBase64);\n const filePath = join(IMAGES_DIR, `${hash}.${ext}`);\n\n if (existsSync(filePath)) {\n return { filePath, bytesWritten: 0 };\n }\n\n const buffer = Buffer.from(cleanBase64, \"base64\");\n await writeFile(filePath, buffer);\n\n const s = await stat(filePath);\n\n return { filePath, bytesWritten: s.size };\n}\n\nexport async function deleteImage(filePath: string | undefined): Promise<{ deletedBytes: number }> {\n if (!filePath) return { deletedBytes: 0 };\n if (!isManagedImagePath(filePath)) return { deletedBytes: 0 };\n try {\n if (existsSync(filePath)) {\n const s = await stat(filePath);\n const size = s.size;\n await unlink(filePath);\n return { deletedBytes: size };\n }\n } catch (err) {\n console.error(\"[agentmemory] Failed to delete image context:\", err);\n }\n return { deletedBytes: 0 };\n}\n\n/** Touch an image file to update its mtime (marking it as recently used for LRU eviction) */\nexport async function touchImage(filePath: string): Promise<void> {\n if (!filePath || !isManagedImagePath(filePath)) return;\n try {\n if (existsSync(filePath)) {\n const now = new Date();\n await utimes(filePath, now, now);\n }\n } catch (err) {\n // Ignore touch errors silently\n }\n}\n"],"mappings":";;;;;;AAMA,MAAa,aAAa,KAAK,SAAS,EAAE,gBAAgB,SAAS;AAEnE,MAAM,oBAAoB,MAAM,OAAO;AAEvC,SAAgB,cAAsB;AACpC,QAAO,OAAO,QAAQ,IAAI,kCAAkC,IAAI;;AAGlE,SAAgB,mBAAmB,UAA2B;CAC5D,MAAM,WAAW,QAAQ,SAAS;CAClC,MAAM,sBAAsB,QAAQ,WAAW;AAC/C,QAAO,SAAS,WAAW,sBAAsB,IAAI,IAAI,aAAa;;AAGxE,SAAS,YAAY,MAAsB;AACzC,QAAO,WAAW,SAAS,CAAC,OAAO,KAAK,CAAC,OAAO,MAAM;;AAGxD,eAAsB,gBAAgB,YAAyE;AAC7G,KAAI,CAAC,WAAY,QAAO;EAAE,UAAU;EAAI,cAAc;EAAG;AAEzD,KAAI,CAAC,WAAW,WAAW,CACzB,OAAM,MAAM,YAAY,EAAE,WAAW,MAAM,CAAC;CAG9C,IAAI,cAAc;CAClB,IAAI,MAAM;AAEV,KAAI,WAAW,WAAW,cAAc,EAAE;EACvC,MAAM,WAAW,WAAW,QAAQ,IAAI;AACxC,MAAI,aAAa,IAAI;GACnB,MAAM,OAAO,WAAW,UAAU,GAAG,SAAS;AAC9C,OAAI,KAAK,SAAS,OAAO,IAAI,KAAK,SAAS,MAAM,CAAE,OAAM;YAChD,KAAK,SAAS,OAAO,CAAE,OAAM;YAC7B,KAAK,SAAS,MAAM,CAAE,OAAM;AACrC,iBAAc,WAAW,UAAU,WAAW,EAAE;;YAE1C,WAAW,WAAW,OAAO,CACrC,OAAM;CAIT,MAAM,WAAW,KAAK,YAAY,GADrB,YAAY,YACgB,CAAC,GAAG,MAAM;AAEnD,KAAI,WAAW,SAAS,CACtB,QAAO;EAAE;EAAU,cAAc;EAAG;AAItC,OAAM,UAAU,UADD,OAAO,KAAK,aAAa,SACR,CAAC;AAIjC,QAAO;EAAE;EAAU,eAAc,MAFjB,KAAK,SAAS,EAEK;EAAM;;AAG3C,eAAsB,YAAY,UAAiE;AACjG,KAAI,CAAC,SAAU,QAAO,EAAE,cAAc,GAAG;AACzC,KAAI,CAAC,mBAAmB,SAAS,CAAE,QAAO,EAAE,cAAc,GAAG;AAC7D,KAAI;AACF,MAAI,WAAW,SAAS,EAAE;GAExB,MAAM,QAAO,MADG,KAAK,SAAS,EACf;AACf,SAAM,OAAO,SAAS;AACtB,UAAO,EAAE,cAAc,MAAM;;UAExB,KAAK;AACZ,UAAQ,MAAM,iDAAiD,IAAI;;AAErE,QAAO,EAAE,cAAc,GAAG;;;AAI5B,eAAsB,WAAW,UAAiC;AAChE,KAAI,CAAC,YAAY,CAAC,mBAAmB,SAAS,CAAE;AAChD,KAAI;AACF,MAAI,WAAW,SAAS,EAAE;GACxB,MAAM,sBAAM,IAAI,MAAM;AACtB,SAAM,OAAO,UAAU,KAAK,IAAI;;UAE3B,KAAK"}
|