@a13xu/lucid 1.13.0 → 1.16.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/build/compression/semantic.d.ts +31 -0
- package/build/compression/semantic.js +196 -0
- package/build/config.d.ts +15 -0
- package/build/http/routes.d.ts +3 -0
- package/build/http/routes.js +56 -0
- package/build/http/server.d.ts +7 -0
- package/build/http/server.js +11 -0
- package/build/index.js +176 -0
- package/build/lucid-sync.d.ts +15 -0
- package/build/lucid-sync.js +72 -0
- package/build/retrieval/context.js +6 -0
- package/build/retrieval/qdrant.d.ts +1 -1
- package/build/retrieval/qdrant.js +11 -2
- package/build/tools/compress.d.ts +15 -0
- package/build/tools/compress.js +18 -0
- package/build/tools/init.js +16 -1
- package/build/tools/model-advisor.d.ts +9 -0
- package/build/tools/model-advisor.js +30 -0
- package/build/tools/smart-context.d.ts +16 -0
- package/build/tools/smart-context.js +54 -0
- package/build/tools/sync.js +8 -0
- package/package.json +64 -59
- package/skills/lucid-audit/SKILL.md +73 -53
- package/skills/lucid-context/SKILL.md +69 -35
- package/skills/lucid-plan/SKILL.md +52 -60
- package/skills/lucid-security/SKILL.md +41 -59
- package/skills/lucid-start/SKILL.md +70 -0
- package/skills/lucid-webdev/SKILL.md +45 -123
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Only active when QDRANT_URL is set (via env var or lucid.config.json)
|
|
3
3
|
// Falls back silently to TF-IDF when unavailable
|
|
4
4
|
import { safeFetch } from "../security/ssrf.js";
|
|
5
|
+
import { tryCompressTextSemantic } from "../compression/semantic.js";
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
// Embedding generation (OpenAI-compatible endpoint)
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
@@ -85,16 +86,24 @@ function stableId(s) {
|
|
|
85
86
|
// Public API
|
|
86
87
|
// ---------------------------------------------------------------------------
|
|
87
88
|
/** Index one file into Qdrant (called by sync_file when Qdrant is configured). */
|
|
88
|
-
export async function indexFileInQdrant(filepath, text, cfg) {
|
|
89
|
+
export async function indexFileInQdrant(filepath, text, cfg, compressionCfg) {
|
|
89
90
|
await ensureCollection(cfg);
|
|
90
91
|
const chunks = chunkFile(filepath, text);
|
|
91
92
|
if (chunks.length === 0)
|
|
92
93
|
return;
|
|
94
|
+
const compressForEmbedding = compressionCfg?.enabled && compressionCfg.applyToEmbeddings !== false;
|
|
93
95
|
// Batch embed (max 96 texts per request for most providers)
|
|
94
96
|
const BATCH = 32;
|
|
95
97
|
for (let b = 0; b < chunks.length; b += BATCH) {
|
|
96
98
|
const batch = chunks.slice(b, b + BATCH);
|
|
97
|
-
|
|
99
|
+
let textsToEmbed;
|
|
100
|
+
if (compressForEmbedding) {
|
|
101
|
+
textsToEmbed = await Promise.all(batch.map((c) => tryCompressTextSemantic(c.text, compressionCfg.ratio ?? 0.5, compressionCfg.minLength ?? 300)));
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
textsToEmbed = batch.map((c) => c.text);
|
|
105
|
+
}
|
|
106
|
+
const vectors = await embed(textsToEmbed, cfg);
|
|
98
107
|
const points = batch.map((c, idx) => ({
|
|
99
108
|
id: c.id,
|
|
100
109
|
vector: vectors[idx],
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const CompressTextSchema: z.ZodObject<{
|
|
3
|
+
text: z.ZodString;
|
|
4
|
+
ratio: z.ZodOptional<z.ZodNumber>;
|
|
5
|
+
min_length: z.ZodOptional<z.ZodNumber>;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
text: string;
|
|
8
|
+
ratio?: number | undefined;
|
|
9
|
+
min_length?: number | undefined;
|
|
10
|
+
}, {
|
|
11
|
+
text: string;
|
|
12
|
+
ratio?: number | undefined;
|
|
13
|
+
min_length?: number | undefined;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function handleCompressText(args: z.infer<typeof CompressTextSchema>): Promise<string>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { compressTextSemantic } from "../compression/semantic.js";
|
|
3
|
+
export const CompressTextSchema = z.object({
|
|
4
|
+
text: z.string().min(1).describe("Text to compress"),
|
|
5
|
+
ratio: z.number().min(0.1).max(0.9).optional().describe("Target compression ratio: 0.3 = keep 30%, 0.5 = keep 50% (default: 0.5)"),
|
|
6
|
+
min_length: z.number().int().optional().describe("Skip compression for texts shorter than this in chars (default: 300)"),
|
|
7
|
+
});
|
|
8
|
+
export async function handleCompressText(args) {
|
|
9
|
+
const result = await compressTextSemantic(args.text, args.ratio ?? 0.5, args.min_length ?? 300);
|
|
10
|
+
return JSON.stringify({
|
|
11
|
+
compressed: result.compressed,
|
|
12
|
+
original_length: result.originalLength,
|
|
13
|
+
compressed_length: result.compressedLength,
|
|
14
|
+
ratio_kept: result.ratio,
|
|
15
|
+
method: result.method,
|
|
16
|
+
tokens_saved: Math.ceil((result.originalLength - result.compressedLength) / 4),
|
|
17
|
+
}, null, 2);
|
|
18
|
+
}
|
package/build/tools/init.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { resolve, join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
3
4
|
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "fs";
|
|
4
5
|
import { fileURLToPath } from "url";
|
|
5
6
|
import { indexProject } from "../indexer/project.js";
|
|
@@ -35,7 +36,7 @@ const LUCID_HOOK = {
|
|
|
35
36
|
hooks: [
|
|
36
37
|
{
|
|
37
38
|
type: "command",
|
|
38
|
-
command: `echo '🔄 ${LUCID_MARKER}(path)
|
|
39
|
+
command: `lucid-sync 2>/dev/null || echo '🔄 ${LUCID_MARKER}(path) — install lucid globally: npm i -g @a13xu/lucid'`,
|
|
39
40
|
},
|
|
40
41
|
],
|
|
41
42
|
};
|
|
@@ -167,6 +168,17 @@ export async function handleInitProject(stmts, input) {
|
|
|
167
168
|
else if (skillsResult.skipped.length > 0) {
|
|
168
169
|
lines.push(`📚 Skills: already installed (${skillsResult.skipped.length} skill(s))`);
|
|
169
170
|
}
|
|
171
|
+
// ── Global skills (~/.claude/skills/) ────────────────────────────────────
|
|
172
|
+
const globalSkillsResult = installGlobalSkills();
|
|
173
|
+
if (globalSkillsResult.installed.length > 0) {
|
|
174
|
+
lines.push(`🌐 Global skills installed in ~/.claude/skills/:`);
|
|
175
|
+
for (const s of globalSkillsResult.installed) {
|
|
176
|
+
lines.push(` • /${s} (available in all projects)`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else if (globalSkillsResult.skipped.length > 0) {
|
|
180
|
+
lines.push(`🌐 Global skills: already installed (${globalSkillsResult.skipped.length} skill(s))`);
|
|
181
|
+
}
|
|
170
182
|
// ── CLAUDE.md injection ───────────────────────────────────────────────────
|
|
171
183
|
const injected = injectClaudeMdInstruction(dir);
|
|
172
184
|
if (injected) {
|
|
@@ -277,6 +289,9 @@ function installSkills(projectDir) {
|
|
|
277
289
|
}
|
|
278
290
|
return result;
|
|
279
291
|
}
|
|
292
|
+
function installGlobalSkills() {
|
|
293
|
+
return installSkills(homedir());
|
|
294
|
+
}
|
|
280
295
|
function buildChannelSummary(cfg) {
|
|
281
296
|
const channels = [];
|
|
282
297
|
if (cfg.adminEmail && cfg.smtpHost)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const SuggestModelSchema: z.ZodObject<{
|
|
3
|
+
task_description: z.ZodString;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
task_description: string;
|
|
6
|
+
}, {
|
|
7
|
+
task_description: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function handleSuggestModel(args: z.infer<typeof SuggestModelSchema>): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const SuggestModelSchema = z.object({
|
|
3
|
+
task_description: z.string().min(1).describe("Natural language description of the task you are about to perform"),
|
|
4
|
+
});
|
|
5
|
+
const HAIKU_TRIGGERS = [
|
|
6
|
+
"list", "show", "find", "search", "where", "what is",
|
|
7
|
+
"recall", "get recent", "status",
|
|
8
|
+
];
|
|
9
|
+
const MODEL_IDS = {
|
|
10
|
+
haiku: "claude-haiku-4-5-20251001",
|
|
11
|
+
sonnet: "claude-sonnet-4-6",
|
|
12
|
+
};
|
|
13
|
+
const CONTEXT_BUDGETS = {
|
|
14
|
+
haiku: 2000,
|
|
15
|
+
sonnet: 8000,
|
|
16
|
+
};
|
|
17
|
+
export function handleSuggestModel(args) {
|
|
18
|
+
const lower = args.task_description.toLowerCase();
|
|
19
|
+
const haikuTrigger = HAIKU_TRIGGERS.find((t) => lower.includes(t));
|
|
20
|
+
const model = haikuTrigger ? "haiku" : "sonnet";
|
|
21
|
+
const reasoning = haikuTrigger
|
|
22
|
+
? `Task matches retrieval/lookup pattern ("${haikuTrigger}") — Haiku is faster for read-only queries.`
|
|
23
|
+
: "No simple retrieval trigger detected — defaulting to Sonnet for reasoning, code generation, and analysis.";
|
|
24
|
+
return JSON.stringify({
|
|
25
|
+
model,
|
|
26
|
+
model_id: MODEL_IDS[model],
|
|
27
|
+
reasoning,
|
|
28
|
+
context_budget: CONTEXT_BUDGETS[model],
|
|
29
|
+
}, null, 2);
|
|
30
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Statements } from "../database.js";
|
|
3
|
+
export declare const SmartContextSchema: z.ZodObject<{
|
|
4
|
+
query: z.ZodString;
|
|
5
|
+
task_type: z.ZodOptional<z.ZodEnum<["simple", "moderate", "complex"]>>;
|
|
6
|
+
dirs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
}, "strip", z.ZodTypeAny, {
|
|
8
|
+
query: string;
|
|
9
|
+
dirs?: string[] | undefined;
|
|
10
|
+
task_type?: "simple" | "moderate" | "complex" | undefined;
|
|
11
|
+
}, {
|
|
12
|
+
query: string;
|
|
13
|
+
dirs?: string[] | undefined;
|
|
14
|
+
task_type?: "simple" | "moderate" | "complex" | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function handleSmartContext(stmts: Statements, args: z.infer<typeof SmartContextSchema>): Promise<string>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { assembleContext } from "../retrieval/context.js";
|
|
3
|
+
import { recall } from "./recall.js";
|
|
4
|
+
import { loadConfig } from "../config.js";
|
|
5
|
+
import { createExperience } from "../memory/experience.js";
|
|
6
|
+
export const SmartContextSchema = z.object({
|
|
7
|
+
query: z.string().min(1).describe("What you are working on — used for both code retrieval and knowledge graph search"),
|
|
8
|
+
task_type: z.enum(["simple", "moderate", "complex"]).optional().describe("Token budget: simple=2000, moderate=6000 (default), complex=12000"),
|
|
9
|
+
dirs: z.array(z.string()).optional().describe("Whitelist: only return files from these directories"),
|
|
10
|
+
});
|
|
11
|
+
const TASK_BUDGETS = {
|
|
12
|
+
simple: 2000,
|
|
13
|
+
moderate: 6000,
|
|
14
|
+
complex: 12000,
|
|
15
|
+
};
|
|
16
|
+
export async function handleSmartContext(stmts, args) {
|
|
17
|
+
const cfg = loadConfig();
|
|
18
|
+
const maxTokens = TASK_BUDGETS[args.task_type ?? "moderate"] ?? 6000;
|
|
19
|
+
// 1. Knowledge graph entities (synchronous)
|
|
20
|
+
const recallResult = recall(stmts, { query: args.query });
|
|
21
|
+
// 2. Code context with adaptive budget (async)
|
|
22
|
+
const contextResult = await assembleContext(args.query, stmts, cfg, {
|
|
23
|
+
maxTokens,
|
|
24
|
+
dirs: args.dirs,
|
|
25
|
+
});
|
|
26
|
+
// 3. Log experience so reward()/penalize() work after this call
|
|
27
|
+
const expId = createExperience(args.query, contextResult.files.map((f) => f.filepath), contextResult.strategy, stmts);
|
|
28
|
+
const budgetUsedPct = Math.round((contextResult.totalTokens / maxTokens) * 100);
|
|
29
|
+
const sections = [
|
|
30
|
+
"## Knowledge Context (entities)",
|
|
31
|
+
recallResult,
|
|
32
|
+
"",
|
|
33
|
+
"## Code Context (files)",
|
|
34
|
+
];
|
|
35
|
+
if (contextResult.files.length === 0) {
|
|
36
|
+
sections.push("No relevant files found. Run init_project() or sync_project() first.");
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
for (const f of contextResult.files) {
|
|
40
|
+
sections.push(`// ─── ${f.filepath} [${f.language}] ~${f.tokens}t (${f.reason}) ───`);
|
|
41
|
+
sections.push(f.content);
|
|
42
|
+
sections.push("");
|
|
43
|
+
}
|
|
44
|
+
if (contextResult.truncated) {
|
|
45
|
+
sections.push(`// ⚠️ Truncated — ${contextResult.skippedFiles} files skipped. Use task_type="complex" for more.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
sections.push("", "---");
|
|
49
|
+
sections.push(`Strategy: ${contextResult.strategy}`);
|
|
50
|
+
sections.push(`Files: ${contextResult.files.length} files, ${contextResult.totalTokens} tokens`);
|
|
51
|
+
sections.push(`Budget used: ${budgetUsedPct}%`);
|
|
52
|
+
sections.push(`Experience #${expId} logged. Call reward() if helpful, penalize() if not.`);
|
|
53
|
+
return sections.join("\n");
|
|
54
|
+
}
|
package/build/tools/sync.js
CHANGED
|
@@ -6,6 +6,8 @@ import { indexProject } from "../indexer/project.js";
|
|
|
6
6
|
import { computeDiff } from "../retrieval/context.js";
|
|
7
7
|
import { decompress } from "../store/content.js";
|
|
8
8
|
import { implicitRewardFromSync } from "../memory/experience.js";
|
|
9
|
+
import { indexFileInQdrant } from "../retrieval/qdrant.js";
|
|
10
|
+
import { loadConfig, getQdrantConfig } from "../config.js";
|
|
9
11
|
const SUPPORTED_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".vue", ".py", ".go", ".rs"]);
|
|
10
12
|
// ---------------------------------------------------------------------------
|
|
11
13
|
// sync_file
|
|
@@ -51,6 +53,12 @@ export function handleSyncFile(stmts, args) {
|
|
|
51
53
|
const implicitRewarded = implicitRewardFromSync(filepath, stmts);
|
|
52
54
|
if (implicitRewarded)
|
|
53
55
|
lines.push(` 🎯 Implicit reward +0.3 (file was in recent context)`);
|
|
56
|
+
// Qdrant vector indexing — fire-and-forget (Qdrant is optional, silent on failure)
|
|
57
|
+
const cfg = loadConfig();
|
|
58
|
+
const qdrantCfg = getQdrantConfig(cfg);
|
|
59
|
+
if (qdrantCfg) {
|
|
60
|
+
void indexFileInQdrant(filepath, source, qdrantCfg, cfg.semanticCompression).catch(() => { });
|
|
61
|
+
}
|
|
54
62
|
return lines.join("\n");
|
|
55
63
|
}
|
|
56
64
|
// ---------------------------------------------------------------------------
|
package/package.json
CHANGED
|
@@ -1,59 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@a13xu/lucid",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Token-efficient memory, code indexing, and validation for Claude Code agents — SQLite + FTS5, TF-IDF + Qdrant retrieval, AST skeleton pruning, diff-aware context, Logic Guardian drift detection",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"lucid": "./build/index.js"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"build/**/*.
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
"claude
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@a13xu/lucid",
|
|
3
|
+
"version": "1.16.0",
|
|
4
|
+
"description": "Token-efficient memory, code indexing, and validation for Claude Code agents — SQLite + FTS5, TF-IDF + Qdrant retrieval, AST skeleton pruning, diff-aware context, Logic Guardian drift detection",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"lucid": "./build/index.js",
|
|
8
|
+
"lucid-sync": "./build/lucid-sync.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"build/**/*.js",
|
|
12
|
+
"build/**/*.d.ts",
|
|
13
|
+
"skills/**/*.md",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mcp",
|
|
22
|
+
"claude",
|
|
23
|
+
"claude-code",
|
|
24
|
+
"memory",
|
|
25
|
+
"sqlite",
|
|
26
|
+
"knowledge-graph",
|
|
27
|
+
"code-indexing",
|
|
28
|
+
"logic-guardian",
|
|
29
|
+
"drift-detection",
|
|
30
|
+
"tfidf",
|
|
31
|
+
"qdrant",
|
|
32
|
+
"token-optimization",
|
|
33
|
+
"context-pruning",
|
|
34
|
+
"ai",
|
|
35
|
+
"anthropic"
|
|
36
|
+
],
|
|
37
|
+
"author": "a13xu",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/a13xu/lucid.git"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/a13xu/lucid#readme",
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@huggingface/transformers": "^4.0.0",
|
|
52
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
53
|
+
"better-sqlite3": "^12.0.0",
|
|
54
|
+
"chokidar": "^4.0.3",
|
|
55
|
+
"express": "^5.2.1",
|
|
56
|
+
"zod": "^3.23.8"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/better-sqlite3": "^7.6.11",
|
|
60
|
+
"@types/express": "^5.0.6",
|
|
61
|
+
"@types/node": "^22.0.0",
|
|
62
|
+
"typescript": "^5.4.0"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1,53 +1,73 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: lucid-audit
|
|
3
|
-
description:
|
|
4
|
-
argument-hint: "[file path or 'all']"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
1
|
+
---
|
|
2
|
+
name: lucid-audit
|
|
3
|
+
description: MANDATORY before marking any task done — runs Logic Guardian + Code Quality checks. HARD-GATE blocks completion without validation.
|
|
4
|
+
argument-hint: "[file path or 'all changed files']"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<HARD-GATE>
|
|
8
|
+
You are about to say "done", "fixed", "complete", or "implemented".
|
|
9
|
+
STOP. You have NOT verified the code yet.
|
|
10
|
+
|
|
11
|
+
Do NOT mark any task as done, do NOT commit, do NOT say the work is complete
|
|
12
|
+
until you have run BOTH validators below and fixed all 🔴 CRITICAL issues.
|
|
13
|
+
|
|
14
|
+
"It looks correct" is not verification. Run the tools.
|
|
15
|
+
</HARD-GATE>
|
|
16
|
+
|
|
17
|
+
## When to invoke
|
|
18
|
+
|
|
19
|
+
**INVOKE when:** about to say done/fixed/complete/implemented, before committing, before creating a PR
|
|
20
|
+
**DO NOT INVOKE for:** read-only tasks, pure research, config changes with no logic
|
|
21
|
+
|
|
22
|
+
## Steps
|
|
23
|
+
|
|
24
|
+
```dot
|
|
25
|
+
digraph lucid_audit {
|
|
26
|
+
"About to say done?" -> "validate_file(path)";
|
|
27
|
+
"validate_file(path)" -> "Critical issues?";
|
|
28
|
+
"Critical issues?" -> "Fix issues" [label="yes 🔴"];
|
|
29
|
+
"Fix issues" -> "validate_file(path)";
|
|
30
|
+
"Critical issues?" -> "check_code_quality(path)" [label="no ✓"];
|
|
31
|
+
"check_code_quality(path)" -> "HIGH issues?";
|
|
32
|
+
"HIGH issues?" -> "Fix if safe" [label="yes 🟠"];
|
|
33
|
+
"Fix if safe" -> "Mark done ✓";
|
|
34
|
+
"HIGH issues?" -> "Mark done ✓" [label="no ✓"];
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 0. Get model recommendation
|
|
39
|
+
```
|
|
40
|
+
suggest_model(task_description="<paste the file path or description of what was written>")
|
|
41
|
+
```
|
|
42
|
+
Say: **"Using [model] — [reasoning]"** then proceed.
|
|
43
|
+
|
|
44
|
+
### 1. Validate logic correctness
|
|
45
|
+
```
|
|
46
|
+
validate_file(path="<file you wrote or modified>")
|
|
47
|
+
```
|
|
48
|
+
Fix every 🔴 CRITICAL issue. Re-run until clean.
|
|
49
|
+
|
|
50
|
+
### 2. Validate code quality
|
|
51
|
+
```
|
|
52
|
+
check_code_quality(path="<same file>")
|
|
53
|
+
```
|
|
54
|
+
Fix 🔴 HIGH severity issues. Address 🟠 MEDIUM where practical.
|
|
55
|
+
|
|
56
|
+
### 3. For complex logic — get the full checklist
|
|
57
|
+
```
|
|
58
|
+
get_checklist()
|
|
59
|
+
```
|
|
60
|
+
Run all 5 mental passes before marking done.
|
|
61
|
+
|
|
62
|
+
### 4. Pre-write validation (before writing to disk)
|
|
63
|
+
```
|
|
64
|
+
check_drift(code="<your code snippet>", language="typescript")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Severity guide
|
|
68
|
+
|
|
69
|
+
| Icon | Level | Action |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| 🔴 | Critical/High | Fix immediately — do not proceed |
|
|
72
|
+
| 🟠 | Medium | Fix if the refactor is safe |
|
|
73
|
+
| 🔵 | Low/Info | Note for future cleanup |
|
|
@@ -1,35 +1,69 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: lucid-context
|
|
3
|
-
description: Use
|
|
4
|
-
argument-hint: "[what you are working on]"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
1
|
+
---
|
|
2
|
+
name: lucid-context
|
|
3
|
+
description: Use BEFORE starting any coding task — retrieves relevant context via smart_context (code + knowledge graph). HARD-GATE: do not read files manually before calling smart_context.
|
|
4
|
+
argument-hint: "[what you are working on]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<HARD-GATE>
|
|
8
|
+
Do NOT open any source file, read any code, or start implementation
|
|
9
|
+
until you have called smart_context and reviewed the result.
|
|
10
|
+
Reading files manually when Lucid is available wastes tokens and misses context.
|
|
11
|
+
</HARD-GATE>
|
|
12
|
+
|
|
13
|
+
## When to invoke this skill
|
|
14
|
+
|
|
15
|
+
**INVOKE when:** about to work on a feature, fix a bug, understand a module, or any coding task
|
|
16
|
+
**DO NOT INVOKE for:** pure conversation, reading docs, non-code questions
|
|
17
|
+
|
|
18
|
+
## Steps
|
|
19
|
+
|
|
20
|
+
```dot
|
|
21
|
+
digraph lucid_context {
|
|
22
|
+
"Describe task" -> "suggest_model";
|
|
23
|
+
"suggest_model" -> "call smart_context";
|
|
24
|
+
"call smart_context" -> "Result relevant?";
|
|
25
|
+
"Result relevant?" -> "call reward()" [label="yes"];
|
|
26
|
+
"Result relevant?" -> "call penalize()" [label="no — note what was missing"];
|
|
27
|
+
"reward()" -> "Start coding";
|
|
28
|
+
"penalize()" -> "Start coding";
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 0. Get model recommendation
|
|
33
|
+
```
|
|
34
|
+
suggest_model(task_description="<concise description of what you are working on>")
|
|
35
|
+
```
|
|
36
|
+
Say: **"Using [model] — [reasoning]"**
|
|
37
|
+
|
|
38
|
+
### 1. Call smart_context
|
|
39
|
+
```
|
|
40
|
+
smart_context(query="<concise description of what you are working on>", task_type="moderate")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Use `dirs` to narrow scope and `task_type` to adjust budget:
|
|
44
|
+
```
|
|
45
|
+
smart_context(query="...", dirs=["src/api"], task_type="simple")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2. Review results and give feedback
|
|
49
|
+
|
|
50
|
+
| Result quality | Action |
|
|
51
|
+
|---|---|
|
|
52
|
+
| Included the files you needed | `reward()` |
|
|
53
|
+
| Missed important files you had to find manually | `penalize(note="missed: src/path/file.ts")` |
|
|
54
|
+
| Partially useful | no action |
|
|
55
|
+
|
|
56
|
+
### 3. Supplement if needed
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
grep_code(pattern="functionName") # locate specific usages
|
|
60
|
+
get_recent(hours=2) # after git pull — see what changed
|
|
61
|
+
recall(query="<topic>") # search accumulated knowledge
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 4. After finishing — sync
|
|
65
|
+
|
|
66
|
+
After every Write/Edit:
|
|
67
|
+
```
|
|
68
|
+
sync_file(path="<modified file>")
|
|
69
|
+
```
|