@brianluby/agent-brain 1.1.0
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/.claude-plugin/marketplace.json +16 -0
- package/.claude-plugin/plugin.json +12 -0
- package/LICENSE +21 -0
- package/README.md +249 -0
- package/commands/ask.md +27 -0
- package/commands/recent.md +27 -0
- package/commands/search.md +27 -0
- package/commands/stats.md +21 -0
- package/dist/hooks/hooks.json +44 -0
- package/dist/hooks/post-tool-use.js +1643 -0
- package/dist/hooks/post-tool-use.js.map +1 -0
- package/dist/hooks/session-start.js +554 -0
- package/dist/hooks/session-start.js.map +1 -0
- package/dist/hooks/smart-install.js +109 -0
- package/dist/hooks/smart-install.js.map +1 -0
- package/dist/hooks/stop.js +1386 -0
- package/dist/hooks/stop.js.map +1 -0
- package/dist/index.d.ts +397 -0
- package/dist/index.js +1236 -0
- package/dist/index.js.map +1 -0
- package/dist/opencode/plugin.d.ts +5 -0
- package/dist/opencode/plugin.js +1820 -0
- package/dist/opencode/plugin.js.map +1 -0
- package/dist/scripts/ask.js +213 -0
- package/dist/scripts/ask.js.map +1 -0
- package/dist/scripts/find.js +213 -0
- package/dist/scripts/find.js.map +1 -0
- package/dist/scripts/stats.js +225 -0
- package/dist/scripts/stats.js.map +1 -0
- package/dist/scripts/timeline.js +210 -0
- package/dist/scripts/timeline.js.map +1 -0
- package/package.json +91 -0
- package/skills/memory/SKILL.md +71 -0
- package/skills/mind/SKILL.md +71 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
3
|
+
import { dirname, resolve } from 'path';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import 'crypto';
|
|
6
|
+
|
|
7
|
+
function writeOutput(output) {
|
|
8
|
+
console.log(JSON.stringify(output));
|
|
9
|
+
process.exit(0);
|
|
10
|
+
}
|
|
11
|
+
function debug(message) {
|
|
12
|
+
if (process.env.MEMVID_MIND_DEBUG === "1") {
|
|
13
|
+
console.error(`[memvid-mind] ${message}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/hooks/smart-install.ts
|
|
18
|
+
var pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || dirname(dirname(__dirname));
|
|
19
|
+
var nodeModulesPath = resolve(pluginRoot, "node_modules");
|
|
20
|
+
var sdkPath = resolve(nodeModulesPath, "@memvid/sdk");
|
|
21
|
+
var packageJsonPath = resolve(pluginRoot, "package.json");
|
|
22
|
+
var installMarkerPath = resolve(pluginRoot, ".install-version");
|
|
23
|
+
function getPackageVersion() {
|
|
24
|
+
try {
|
|
25
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
26
|
+
return pkg.version || "unknown";
|
|
27
|
+
} catch {
|
|
28
|
+
return "unknown";
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function getInstallMarker() {
|
|
32
|
+
try {
|
|
33
|
+
if (existsSync(installMarkerPath)) {
|
|
34
|
+
return JSON.parse(readFileSync(installMarkerPath, "utf-8"));
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function saveInstallMarker(version) {
|
|
41
|
+
const marker = {
|
|
42
|
+
version,
|
|
43
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
44
|
+
};
|
|
45
|
+
writeFileSync(installMarkerPath, JSON.stringify(marker, null, 2));
|
|
46
|
+
}
|
|
47
|
+
function needsInstall() {
|
|
48
|
+
if (!existsSync(sdkPath)) {
|
|
49
|
+
debug("SDK not found, needs install");
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
const marker = getInstallMarker();
|
|
53
|
+
const currentVersion = getPackageVersion();
|
|
54
|
+
if (!marker || marker.version !== currentVersion) {
|
|
55
|
+
debug(`Version mismatch: ${marker?.version} -> ${currentVersion}`);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
function installDeps() {
|
|
61
|
+
debug("Installing dependencies...");
|
|
62
|
+
try {
|
|
63
|
+
execSync("npm install --production --no-fund --no-audit", {
|
|
64
|
+
cwd: pluginRoot,
|
|
65
|
+
stdio: "pipe",
|
|
66
|
+
timeout: 12e4
|
|
67
|
+
// 2 minute timeout
|
|
68
|
+
});
|
|
69
|
+
debug("Dependencies installed successfully");
|
|
70
|
+
return true;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
debug(`npm install failed: ${error}`);
|
|
73
|
+
try {
|
|
74
|
+
execSync("npm install --production --no-fund --no-audit --force", {
|
|
75
|
+
cwd: pluginRoot,
|
|
76
|
+
stdio: "pipe",
|
|
77
|
+
timeout: 12e4
|
|
78
|
+
});
|
|
79
|
+
debug("Dependencies installed with --force");
|
|
80
|
+
return true;
|
|
81
|
+
} catch (forceError) {
|
|
82
|
+
debug(`npm install --force failed: ${forceError}`);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function main() {
|
|
88
|
+
try {
|
|
89
|
+
if (needsInstall()) {
|
|
90
|
+
const success = installDeps();
|
|
91
|
+
if (success) {
|
|
92
|
+
const version = getPackageVersion();
|
|
93
|
+
saveInstallMarker(version);
|
|
94
|
+
debug(`Installed memvid-mind v${version}`);
|
|
95
|
+
} else {
|
|
96
|
+
debug("Failed to install dependencies");
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
debug("Dependencies already installed");
|
|
100
|
+
}
|
|
101
|
+
writeOutput({ continue: true });
|
|
102
|
+
} catch (error) {
|
|
103
|
+
debug(`Smart install error: ${error}`);
|
|
104
|
+
writeOutput({ continue: true });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
main();
|
|
108
|
+
//# sourceMappingURL=smart-install.js.map
|
|
109
|
+
//# sourceMappingURL=smart-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/helpers.ts","../../src/hooks/smart-install.ts"],"names":[],"mappings":"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","file":"smart-install.js","sourcesContent":["/**\n * Memvid Mind - Utility Helpers\n */\n\nimport { randomBytes } from \"node:crypto\";\n\n/**\n * Generate a unique ID\n */\nexport function generateId(): string {\n return randomBytes(8).toString(\"hex\");\n}\n\n/**\n * Estimate token count for text (rough approximation)\n * ~4 characters per token for English text\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Truncate text to fit within token limit\n */\nexport function truncateToTokens(text: string, maxTokens: number): string {\n const maxChars = maxTokens * 4;\n if (text.length <= maxChars) return text;\n return text.slice(0, maxChars - 3) + \"...\";\n}\n\n/**\n * Format timestamp to human-readable string\n */\nexport function formatTimestamp(ts: number): string {\n const date = new Date(ts);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return \"just now\";\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString();\n}\n\n/**\n * Parse JSON safely\n */\nexport function safeJsonParse<T>(text: string, fallback: T): T {\n try {\n return JSON.parse(text) as T;\n } catch {\n return fallback;\n }\n}\n\n/**\n * Read all stdin as string\n */\nexport async function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n\n return new Promise((resolve, reject) => {\n process.stdin.on(\"data\", (chunk) => chunks.push(chunk));\n process.stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n process.stdin.on(\"error\", reject);\n });\n}\n\n/**\n * Write JSON to stdout and exit immediately\n * (Prevents SDK background tasks from blocking process exit)\n */\nexport function writeOutput(output: unknown): never {\n console.log(JSON.stringify(output));\n process.exit(0);\n}\n\n/**\n * Log debug message to stderr\n */\nexport function debug(message: string): void {\n if (process.env.MEMVID_MIND_DEBUG === \"1\") {\n console.error(`[memvid-mind] ${message}`);\n }\n}\n\n/**\n * Extract key information from tool output\n */\nexport function extractKeyInfo(toolName: string, output: string): string {\n // Truncate very long outputs\n const maxLength = 2000;\n const truncated = output.length > maxLength\n ? output.slice(0, maxLength) + \"\\n... (truncated)\"\n : output;\n\n // Tool-specific extraction\n switch (toolName) {\n case \"Read\":\n // Extract file summary from read output\n return extractFileReadSummary(truncated);\n case \"Bash\":\n // Extract command summary\n return extractBashSummary(truncated);\n case \"Edit\":\n // Extract edit summary\n return extractEditSummary(truncated);\n case \"Grep\":\n case \"Glob\":\n // Extract search summary\n return extractSearchSummary(truncated);\n default:\n return truncated;\n }\n}\n\nfunction extractFileReadSummary(output: string): string {\n const lines = output.split(\"\\n\");\n if (lines.length <= 20) return output;\n return `${lines.slice(0, 10).join(\"\\n\")}\\n... (${lines.length} lines total)`;\n}\n\nfunction extractBashSummary(output: string): string {\n const lines = output.split(\"\\n\");\n if (lines.length <= 30) return output;\n return [\n ...lines.slice(0, 10),\n `... (${lines.length - 20} lines omitted)`,\n ...lines.slice(-10),\n ].join(\"\\n\");\n}\n\nfunction extractEditSummary(output: string): string {\n // Edits are usually compact, return as-is\n return output;\n}\n\nfunction extractSearchSummary(output: string): string {\n const lines = output.split(\"\\n\").filter(Boolean);\n if (lines.length <= 20) return output;\n return [\n ...lines.slice(0, 15),\n `... and ${lines.length - 15} more results`,\n ].join(\"\\n\");\n}\n\n/**\n * Classify observation type from tool and output\n */\nexport function classifyObservationType(\n toolName: string,\n output: string\n): \"discovery\" | \"decision\" | \"problem\" | \"solution\" | \"pattern\" | \"warning\" | \"success\" | \"refactor\" | \"bugfix\" | \"feature\" {\n const lowerOutput = output.toLowerCase();\n\n // Error detection\n if (\n lowerOutput.includes(\"error\") ||\n lowerOutput.includes(\"failed\") ||\n lowerOutput.includes(\"exception\")\n ) {\n return \"problem\";\n }\n\n // Success detection\n if (\n lowerOutput.includes(\"success\") ||\n lowerOutput.includes(\"passed\") ||\n lowerOutput.includes(\"completed\")\n ) {\n return \"success\";\n }\n\n // Warning detection\n if (lowerOutput.includes(\"warning\") || lowerOutput.includes(\"deprecated\")) {\n return \"warning\";\n }\n\n // Tool-based classification\n switch (toolName) {\n case \"Read\":\n case \"Glob\":\n case \"Grep\":\n return \"discovery\";\n case \"Edit\":\n if (lowerOutput.includes(\"fix\") || lowerOutput.includes(\"bug\")) {\n return \"bugfix\";\n }\n return \"refactor\";\n case \"Write\":\n return \"feature\";\n default:\n return \"discovery\";\n }\n}\n","#!/usr/bin/env node\n/**\n * Memvid Mind - Smart Install Hook\n *\n * Automatically installs dependencies on first run.\n * Runs on SessionStart before other hooks.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport { writeOutput, debug } from \"../utils/helpers.js\";\n\n// Get the plugin root directory\nconst pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || dirname(dirname(__dirname));\nconst nodeModulesPath = resolve(pluginRoot, \"node_modules\");\nconst sdkPath = resolve(nodeModulesPath, \"@memvid/sdk\");\nconst packageJsonPath = resolve(pluginRoot, \"package.json\");\nconst installMarkerPath = resolve(pluginRoot, \".install-version\");\n\ninterface InstallMarker {\n version: string;\n installedAt: string;\n}\n\nfunction getPackageVersion(): string {\n try {\n const pkg = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n return pkg.version || \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction getInstallMarker(): InstallMarker | null {\n try {\n if (existsSync(installMarkerPath)) {\n return JSON.parse(readFileSync(installMarkerPath, \"utf-8\"));\n }\n } catch {\n // Ignore errors\n }\n return null;\n}\n\nfunction saveInstallMarker(version: string): void {\n const marker: InstallMarker = {\n version,\n installedAt: new Date().toISOString(),\n };\n writeFileSync(installMarkerPath, JSON.stringify(marker, null, 2));\n}\n\nfunction needsInstall(): boolean {\n // Check if SDK exists\n if (!existsSync(sdkPath)) {\n debug(\"SDK not found, needs install\");\n return true;\n }\n\n // Check if version changed\n const marker = getInstallMarker();\n const currentVersion = getPackageVersion();\n\n if (!marker || marker.version !== currentVersion) {\n debug(`Version mismatch: ${marker?.version} -> ${currentVersion}`);\n return true;\n }\n\n return false;\n}\n\nfunction installDeps(): boolean {\n debug(\"Installing dependencies...\");\n\n try {\n // Try npm install first\n execSync(\"npm install --production --no-fund --no-audit\", {\n cwd: pluginRoot,\n stdio: \"pipe\",\n timeout: 120000, // 2 minute timeout\n });\n\n debug(\"Dependencies installed successfully\");\n return true;\n } catch (error) {\n debug(`npm install failed: ${error}`);\n\n // Try with force flag\n try {\n execSync(\"npm install --production --no-fund --no-audit --force\", {\n cwd: pluginRoot,\n stdio: \"pipe\",\n timeout: 120000,\n });\n debug(\"Dependencies installed with --force\");\n return true;\n } catch (forceError) {\n debug(`npm install --force failed: ${forceError}`);\n return false;\n }\n }\n}\n\nasync function main() {\n try {\n if (needsInstall()) {\n const success = installDeps();\n\n if (success) {\n const version = getPackageVersion();\n saveInstallMarker(version);\n debug(`Installed memvid-mind v${version}`);\n } else {\n debug(\"Failed to install dependencies\");\n }\n } else {\n debug(\"Dependencies already installed\");\n }\n\n // Always continue - don't block on install errors\n writeOutput({ continue: true });\n } catch (error) {\n debug(`Smart install error: ${error}`);\n writeOutput({ continue: true });\n }\n}\n\nmain();\n"]}
|