@balpal4495/quorum 3.0.4 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/commands/compass.js +31 -12
- package/dist/advisor/ask.d.ts +13 -0
- package/dist/advisor/ask.d.ts.map +1 -0
- package/dist/advisor/ask.js +67 -0
- package/dist/advisor/ask.js.map +1 -0
- package/dist/advisor/index.d.ts +3 -0
- package/dist/advisor/index.d.ts.map +1 -0
- package/dist/advisor/index.js +2 -0
- package/dist/advisor/index.js.map +1 -0
- package/dist/advisor/prompt.d.ts +5 -0
- package/dist/advisor/prompt.d.ts.map +1 -0
- package/{modules/advisor/prompt.ts → dist/advisor/prompt.js} +22 -26
- package/dist/advisor/prompt.js.map +1 -0
- package/dist/advisor/types.d.ts +23 -0
- package/dist/advisor/types.d.ts.map +1 -0
- package/dist/advisor/types.js +2 -0
- package/dist/advisor/types.js.map +1 -0
- package/dist/compass/behavior.d.ts +4 -0
- package/dist/compass/behavior.d.ts.map +1 -0
- package/dist/compass/behavior.js +138 -0
- package/dist/compass/behavior.js.map +1 -0
- package/dist/compass/create.d.ts +3 -0
- package/dist/compass/create.d.ts.map +1 -0
- package/dist/compass/create.js +289 -0
- package/dist/compass/create.js.map +1 -0
- package/dist/compass/evidence/collect.d.ts +11 -0
- package/dist/compass/evidence/collect.d.ts.map +1 -0
- package/dist/compass/evidence/collect.js +86 -0
- package/dist/compass/evidence/collect.js.map +1 -0
- package/dist/compass/index.d.ts +8 -0
- package/dist/compass/index.d.ts.map +1 -0
- package/dist/compass/index.js +8 -0
- package/dist/compass/index.js.map +1 -0
- package/dist/compass/prompts/index.d.ts +28 -0
- package/dist/compass/prompts/index.d.ts.map +1 -0
- package/{modules/compass/prompts/index.ts → dist/compass/prompts/index.js} +13 -38
- package/dist/compass/prompts/index.js.map +1 -0
- package/dist/compass/prompts/system.d.ts +2 -0
- package/dist/compass/prompts/system.d.ts.map +1 -0
- package/{modules/compass/prompts/system.ts → dist/compass/prompts/system.js} +2 -1
- package/dist/compass/prompts/system.js.map +1 -0
- package/dist/compass/propose.d.ts +15 -0
- package/dist/compass/propose.d.ts.map +1 -0
- package/dist/compass/propose.js +128 -0
- package/dist/compass/propose.js.map +1 -0
- package/dist/compass/schemas.d.ts +1271 -0
- package/dist/compass/schemas.d.ts.map +1 -0
- package/dist/compass/schemas.js +113 -0
- package/dist/compass/schemas.js.map +1 -0
- package/dist/compass/score.d.ts +25 -0
- package/dist/compass/score.d.ts.map +1 -0
- package/dist/compass/score.js +89 -0
- package/dist/compass/score.js.map +1 -0
- package/dist/compass/sources/index.d.ts +9 -0
- package/dist/compass/sources/index.d.ts.map +1 -0
- package/dist/compass/sources/index.js +408 -0
- package/dist/compass/sources/index.js.map +1 -0
- package/dist/compass/types.d.ts +334 -0
- package/dist/compass/types.d.ts.map +1 -0
- package/dist/compass/types.js +2 -0
- package/dist/compass/types.js.map +1 -0
- package/dist/council/advisors.d.ts +15 -0
- package/dist/council/advisors.d.ts.map +1 -0
- package/dist/council/advisors.js +46 -0
- package/dist/council/advisors.js.map +1 -0
- package/dist/council/chairman.d.ts +13 -0
- package/dist/council/chairman.d.ts.map +1 -0
- package/dist/council/chairman.js +145 -0
- package/dist/council/chairman.js.map +1 -0
- package/dist/council/deliberate.d.ts +22 -0
- package/dist/council/deliberate.d.ts.map +1 -0
- package/dist/council/deliberate.js +99 -0
- package/dist/council/deliberate.js.map +1 -0
- package/dist/council/frame.d.ts +8 -0
- package/dist/council/frame.d.ts.map +1 -0
- package/dist/council/frame.js +40 -0
- package/dist/council/frame.js.map +1 -0
- package/dist/council/index.d.ts +6 -0
- package/dist/council/index.d.ts.map +1 -0
- package/dist/council/index.js +4 -0
- package/dist/council/index.js.map +1 -0
- package/dist/council/personas.d.ts +18 -0
- package/dist/council/personas.d.ts.map +1 -0
- package/dist/council/personas.js +44 -0
- package/dist/council/personas.js.map +1 -0
- package/dist/council/reviewers.d.ts +13 -0
- package/dist/council/reviewers.d.ts.map +1 -0
- package/dist/council/reviewers.js +59 -0
- package/dist/council/reviewers.js.map +1 -0
- package/dist/council/risk.d.ts +16 -0
- package/dist/council/risk.d.ts.map +1 -0
- package/dist/council/risk.js +74 -0
- package/dist/council/risk.js.map +1 -0
- package/dist/council/types.d.ts +95 -0
- package/dist/council/types.d.ts.map +1 -0
- package/dist/council/types.js +2 -0
- package/dist/council/types.js.map +1 -0
- package/dist/jury/evaluate.d.ts +13 -0
- package/dist/jury/evaluate.d.ts.map +1 -0
- package/{modules/jury/evaluate.ts → dist/jury/evaluate.js} +60 -84
- package/dist/jury/evaluate.js.map +1 -0
- package/dist/jury/index.d.ts +6 -0
- package/dist/jury/index.d.ts.map +1 -0
- package/dist/jury/index.js +4 -0
- package/dist/jury/index.js.map +1 -0
- package/dist/jury/preflight.d.ts +26 -0
- package/dist/jury/preflight.d.ts.map +1 -0
- package/dist/jury/preflight.js +71 -0
- package/dist/jury/preflight.js.map +1 -0
- package/dist/jury/schema.d.ts +57 -0
- package/dist/jury/schema.d.ts.map +1 -0
- package/dist/jury/schema.js +21 -0
- package/dist/jury/schema.js.map +1 -0
- package/dist/jury/types.d.ts +47 -0
- package/dist/jury/types.d.ts.map +1 -0
- package/dist/jury/types.js +2 -0
- package/dist/jury/types.js.map +1 -0
- package/dist/oracle/adapters/lance-db.d.ts +15 -0
- package/dist/oracle/adapters/lance-db.d.ts.map +1 -0
- package/dist/oracle/adapters/lance-db.js +68 -0
- package/dist/oracle/adapters/lance-db.js.map +1 -0
- package/dist/oracle/adapters/xenova-embedder.d.ts +21 -0
- package/dist/oracle/adapters/xenova-embedder.d.ts.map +1 -0
- package/dist/oracle/adapters/xenova-embedder.js +36 -0
- package/dist/oracle/adapters/xenova-embedder.js.map +1 -0
- package/dist/oracle/bm25.d.ts +20 -0
- package/dist/oracle/bm25.d.ts.map +1 -0
- package/dist/oracle/bm25.js +82 -0
- package/dist/oracle/bm25.js.map +1 -0
- package/dist/oracle/index.d.ts +21 -0
- package/dist/oracle/index.d.ts.map +1 -0
- package/dist/oracle/index.js +25 -0
- package/dist/oracle/index.js.map +1 -0
- package/dist/oracle/log.d.ts +6 -0
- package/dist/oracle/log.d.ts.map +1 -0
- package/dist/oracle/log.js +12 -0
- package/dist/oracle/log.js.map +1 -0
- package/dist/oracle/propose.d.ts +25 -0
- package/dist/oracle/propose.d.ts.map +1 -0
- package/dist/oracle/propose.js +133 -0
- package/dist/oracle/propose.js.map +1 -0
- package/dist/oracle/query.d.ts +17 -0
- package/dist/oracle/query.d.ts.map +1 -0
- package/dist/oracle/query.js +106 -0
- package/dist/oracle/query.js.map +1 -0
- package/dist/oracle/summary.d.ts +11 -0
- package/dist/oracle/summary.d.ts.map +1 -0
- package/dist/oracle/summary.js +102 -0
- package/dist/oracle/summary.js.map +1 -0
- package/dist/oracle/types.d.ts +31 -0
- package/dist/oracle/types.d.ts.map +1 -0
- package/dist/oracle/types.js +2 -0
- package/dist/oracle/types.js.map +1 -0
- package/dist/sentinel/assert.d.ts +28 -0
- package/dist/sentinel/assert.d.ts.map +1 -0
- package/dist/sentinel/assert.js +63 -0
- package/dist/sentinel/assert.js.map +1 -0
- package/dist/sentinel/coverage.d.ts +14 -0
- package/dist/sentinel/coverage.d.ts.map +1 -0
- package/dist/sentinel/coverage.js +96 -0
- package/dist/sentinel/coverage.js.map +1 -0
- package/dist/sentinel/drift.d.ts +12 -0
- package/dist/sentinel/drift.d.ts.map +1 -0
- package/dist/sentinel/drift.js +149 -0
- package/dist/sentinel/drift.js.map +1 -0
- package/dist/sentinel/index.d.ts +7 -0
- package/dist/sentinel/index.d.ts.map +1 -0
- package/dist/sentinel/index.js +5 -0
- package/dist/sentinel/index.js.map +1 -0
- package/dist/sentinel/review.d.ts +15 -0
- package/dist/sentinel/review.d.ts.map +1 -0
- package/dist/sentinel/review.js +177 -0
- package/dist/sentinel/review.js.map +1 -0
- package/dist/setup.d.ts +103 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +87 -0
- package/dist/setup.js.map +1 -0
- package/dist/shared/types.d.ts +173 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +16 -0
- package/dist/shared/types.js.map +1 -0
- package/package.json +13 -8
- package/.github/copilot-instructions.md +0 -117
- package/CLAUDE.md +0 -146
- package/GEMINI.md +0 -73
- package/SETUP.md +0 -264
- package/evals/__tests__/eval.test.ts +0 -31
- package/evals/cases/auth_hs256_rejected.json +0 -46
- package/evals/cases/auth_rs256_valid.json +0 -30
- package/evals/cases/cache_missing_lock.json +0 -31
- package/evals/cases/db_naive_not_null.json +0 -32
- package/evals/cases/logging_pii_leak.json +0 -32
- package/evals/cases/migration_with_rollback.json +0 -43
- package/evals/cases/no_evidence_novel_design.json +0 -16
- package/evals/cases/payment_no_idempotency.json +0 -33
- package/evals/cases/redis_session_rejected.json +0 -32
- package/evals/cases/safe_refactor.json +0 -17
- package/evals/runner.ts +0 -226
- package/modules/AGENTS.md +0 -78
- package/modules/CLAUDE.md +0 -93
- package/modules/README.md +0 -504
- package/modules/advisor/ask.ts +0 -87
- package/modules/advisor/index.ts +0 -2
- package/modules/advisor/types.ts +0 -26
- package/modules/compass/behavior.ts +0 -161
- package/modules/compass/create.ts +0 -365
- package/modules/compass/evidence/collect.ts +0 -109
- package/modules/compass/index.ts +0 -7
- package/modules/compass/propose.ts +0 -152
- package/modules/compass/schemas.ts +0 -121
- package/modules/compass/score.ts +0 -77
- package/modules/compass/sources/index.ts +0 -413
- package/modules/compass/types.ts +0 -431
- package/modules/council/advisors.ts +0 -71
- package/modules/council/chairman.ts +0 -183
- package/modules/council/deliberate.ts +0 -141
- package/modules/council/frame.ts +0 -54
- package/modules/council/index.ts +0 -9
- package/modules/council/personas.ts +0 -57
- package/modules/council/reviewers.ts +0 -82
- package/modules/council/risk.ts +0 -89
- package/modules/council/types.ts +0 -107
- package/modules/jury/index.ts +0 -5
- package/modules/jury/preflight.ts +0 -101
- package/modules/jury/schema.ts +0 -24
- package/modules/jury/types.ts +0 -50
- package/modules/oracle/adapters/lance-db.ts +0 -81
- package/modules/oracle/adapters/xenova-embedder.ts +0 -43
- package/modules/oracle/bm25.ts +0 -92
- package/modules/oracle/index.ts +0 -36
- package/modules/oracle/log.ts +0 -15
- package/modules/oracle/propose.ts +0 -164
- package/modules/oracle/query.ts +0 -146
- package/modules/oracle/summary.ts +0 -116
- package/modules/oracle/types.ts +0 -32
- package/modules/sentinel/assert.ts +0 -95
- package/modules/sentinel/coverage.ts +0 -106
- package/modules/sentinel/drift.ts +0 -163
- package/modules/sentinel/index.ts +0 -6
- package/modules/sentinel/review.ts +0 -208
- package/modules/setup.ts +0 -202
- package/modules/shared/types.ts +0 -193
|
@@ -1,413 +0,0 @@
|
|
|
1
|
-
import type { ProductSource, ProductSourceFinding, ProductSourceScanInput } from "../types"
|
|
2
|
-
|
|
3
|
-
export function docsSource(): ProductSource {
|
|
4
|
-
return {
|
|
5
|
-
id: "docs",
|
|
6
|
-
kind: "docs",
|
|
7
|
-
async scan(input: ProductSourceScanInput): Promise<ProductSourceFinding[]> {
|
|
8
|
-
const { promises: fs } = await import("fs")
|
|
9
|
-
const path = await import("path")
|
|
10
|
-
|
|
11
|
-
const targets = [
|
|
12
|
-
"README.md",
|
|
13
|
-
"SETUP.md",
|
|
14
|
-
"CLAUDE.md",
|
|
15
|
-
"AGENTS.md",
|
|
16
|
-
"GEMINI.md",
|
|
17
|
-
"modules/README.md",
|
|
18
|
-
"quorum/CLAUDE.md",
|
|
19
|
-
"quorum/SETUP.md",
|
|
20
|
-
"docs",
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
const findings: ProductSourceFinding[] = []
|
|
24
|
-
let idx = 0
|
|
25
|
-
|
|
26
|
-
async function scanMarkdown(filePath: string): Promise<void> {
|
|
27
|
-
let content: string
|
|
28
|
-
try {
|
|
29
|
-
content = await fs.readFile(filePath, "utf8")
|
|
30
|
-
} catch {
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
const rel = path.relative(input.rootDir, filePath).replace(/\\/g, "/")
|
|
34
|
-
const lines = content.split("\n")
|
|
35
|
-
|
|
36
|
-
// Extract headings as structural claims
|
|
37
|
-
for (let i = 0; i < lines.length; i++) {
|
|
38
|
-
const line = lines[i]
|
|
39
|
-
const headingMatch = line.match(/^#{1,3}\s+(.+)/)
|
|
40
|
-
if (headingMatch) {
|
|
41
|
-
const heading = headingMatch[1].trim()
|
|
42
|
-
// Grab up to 3 lines of context below
|
|
43
|
-
const context = lines
|
|
44
|
-
.slice(i + 1, i + 4)
|
|
45
|
-
.join(" ")
|
|
46
|
-
.replace(/```[^`]*```/g, "")
|
|
47
|
-
.trim()
|
|
48
|
-
.slice(0, 200)
|
|
49
|
-
findings.push({
|
|
50
|
-
id: `docs-${idx++}`,
|
|
51
|
-
kind: "docs",
|
|
52
|
-
source: rel,
|
|
53
|
-
path: rel,
|
|
54
|
-
line: i + 1,
|
|
55
|
-
title: heading,
|
|
56
|
-
summary: context || heading,
|
|
57
|
-
confidence: 0.8,
|
|
58
|
-
tags: inferTags(heading + " " + context),
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Extract CLI code blocks (``` lines starting with quorum)
|
|
63
|
-
if (line.trim().startsWith("quorum ") || line.trim().startsWith("npx quorum")) {
|
|
64
|
-
const cmd = line.trim()
|
|
65
|
-
findings.push({
|
|
66
|
-
id: `docs-cmd-${idx++}`,
|
|
67
|
-
kind: "docs",
|
|
68
|
-
source: rel,
|
|
69
|
-
path: rel,
|
|
70
|
-
line: i + 1,
|
|
71
|
-
title: `CLI usage: ${cmd.slice(0, 60)}`,
|
|
72
|
-
summary: `Documented command: ${cmd}`,
|
|
73
|
-
confidence: 0.85,
|
|
74
|
-
tags: ["cli", "command", ...inferTags(cmd)],
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async function scanDir(dir: string): Promise<void> {
|
|
81
|
-
let entries
|
|
82
|
-
try {
|
|
83
|
-
entries = await fs.readdir(dir, { withFileTypes: true })
|
|
84
|
-
} catch {
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
for (const entry of entries) {
|
|
88
|
-
const full = path.join(dir, entry.name)
|
|
89
|
-
if (entry.isDirectory() && !["node_modules", ".git", "dist"].includes(entry.name)) {
|
|
90
|
-
await scanDir(full)
|
|
91
|
-
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
92
|
-
await scanMarkdown(full)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
for (const target of targets) {
|
|
98
|
-
const full = path.join(input.rootDir, target)
|
|
99
|
-
let stat
|
|
100
|
-
try { stat = await fs.stat(full) } catch { continue }
|
|
101
|
-
if (stat.isDirectory()) {
|
|
102
|
-
await scanDir(full)
|
|
103
|
-
} else {
|
|
104
|
-
await scanMarkdown(full)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return area(input.area, findings)
|
|
109
|
-
},
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function packageSource(): ProductSource {
|
|
114
|
-
return {
|
|
115
|
-
id: "package",
|
|
116
|
-
kind: "package",
|
|
117
|
-
async scan(input: ProductSourceScanInput): Promise<ProductSourceFinding[]> {
|
|
118
|
-
const { promises: fs } = await import("fs")
|
|
119
|
-
const path = await import("path")
|
|
120
|
-
const pkgPath = path.join(input.rootDir, "package.json")
|
|
121
|
-
let pkg: Record<string, unknown>
|
|
122
|
-
try {
|
|
123
|
-
pkg = JSON.parse(await fs.readFile(pkgPath, "utf8"))
|
|
124
|
-
} catch {
|
|
125
|
-
return []
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const findings: ProductSourceFinding[] = []
|
|
129
|
-
let idx = 0
|
|
130
|
-
|
|
131
|
-
if (pkg.name) findings.push({ id: `pkg-${idx++}`, kind: "package", source: "package.json", title: "Package name", summary: `Published as: ${pkg.name}`, confidence: 1, tags: ["package", "identity"] })
|
|
132
|
-
if (pkg.description) findings.push({ id: `pkg-${idx++}`, kind: "package", source: "package.json", title: "Package description", summary: String(pkg.description), confidence: 1, tags: ["package", "description"] })
|
|
133
|
-
if (pkg.bin) {
|
|
134
|
-
for (const [name, entry] of Object.entries(pkg.bin as Record<string, string>)) {
|
|
135
|
-
findings.push({ id: `pkg-${idx++}`, kind: "package", source: "package.json", title: `CLI binary: ${name}`, summary: `CLI binary '${name}' at ${entry}`, confidence: 1, tags: ["cli", "binary"] })
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
if (pkg.scripts) {
|
|
139
|
-
for (const [name, cmd] of Object.entries(pkg.scripts as Record<string, string>)) {
|
|
140
|
-
findings.push({ id: `pkg-${idx++}`, kind: "package", source: "package.json", title: `Script: ${name}`, summary: `npm run ${name}: ${cmd}`, confidence: 0.9, tags: ["script", name] })
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
if (pkg.exports) {
|
|
144
|
-
findings.push({ id: `pkg-${idx++}`, kind: "package", source: "package.json", title: "Package exports", summary: `Exports: ${JSON.stringify(pkg.exports)}`, confidence: 0.95, tags: ["exports", "api"] })
|
|
145
|
-
}
|
|
146
|
-
if (pkg.engines) {
|
|
147
|
-
findings.push({ id: `pkg-${idx++}`, kind: "package", source: "package.json", title: "Engine requirements", summary: `Node: ${(pkg.engines as Record<string, string>).node ?? "unspecified"}`, confidence: 1, tags: ["runtime", "engines"] })
|
|
148
|
-
}
|
|
149
|
-
const deps = { ...(pkg.dependencies as Record<string, string> ?? {}), ...(pkg.optionalDependencies as Record<string, string> ?? {}) }
|
|
150
|
-
if (Object.keys(deps).length > 0) {
|
|
151
|
-
findings.push({ id: `pkg-${idx++}`, kind: "package", source: "package.json", title: "Runtime dependencies", summary: Object.keys(deps).join(", "), confidence: 0.9, tags: ["dependencies"] })
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return findings
|
|
155
|
-
},
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function cliSource(): ProductSource {
|
|
160
|
-
return {
|
|
161
|
-
id: "cli",
|
|
162
|
-
kind: "cli",
|
|
163
|
-
async scan(input: ProductSourceScanInput): Promise<ProductSourceFinding[]> {
|
|
164
|
-
const { promises: fs } = await import("fs")
|
|
165
|
-
const path = await import("path")
|
|
166
|
-
|
|
167
|
-
const findings: ProductSourceFinding[] = []
|
|
168
|
-
let idx = 0
|
|
169
|
-
|
|
170
|
-
const binDir = path.join(input.rootDir, "bin", "commands")
|
|
171
|
-
let commandFiles: string[] = []
|
|
172
|
-
try {
|
|
173
|
-
commandFiles = (await fs.readdir(binDir)).filter(f => f.endsWith(".js"))
|
|
174
|
-
} catch {
|
|
175
|
-
return []
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
for (const file of commandFiles) {
|
|
179
|
-
const cmdName = file.replace(".js", "")
|
|
180
|
-
const filePath = path.join(binDir, file)
|
|
181
|
-
let content: string
|
|
182
|
-
try { content = await fs.readFile(filePath, "utf8") } catch { continue }
|
|
183
|
-
|
|
184
|
-
const relPath = `bin/commands/${file}`
|
|
185
|
-
|
|
186
|
-
// Detect subcommands from switch/if patterns
|
|
187
|
-
const subcmdMatches = [...content.matchAll(/case ["']([a-z-]+)["']/g)]
|
|
188
|
-
const subcommands = subcmdMatches.map(m => m[1])
|
|
189
|
-
|
|
190
|
-
// Detect flags
|
|
191
|
-
const flagMatches = [...content.matchAll(/["'](--[a-z-]+)["']/g)]
|
|
192
|
-
const flags = [...new Set(flagMatches.map(m => m[1]))]
|
|
193
|
-
|
|
194
|
-
// Detect LLM usage
|
|
195
|
-
const usesLLM = /llm|LLM|provider|model/.test(content)
|
|
196
|
-
|
|
197
|
-
// Detect Chronicle reads/writes
|
|
198
|
-
const readsChronicle = /readCommitted|findChronicleDir|committed/.test(content)
|
|
199
|
-
const writesChronicle = /writeFile.*proposals|proposals.*writeFile|oracle\.propose/.test(content)
|
|
200
|
-
|
|
201
|
-
findings.push({
|
|
202
|
-
id: `cli-${idx++}`,
|
|
203
|
-
kind: "cli",
|
|
204
|
-
source: relPath,
|
|
205
|
-
path: relPath,
|
|
206
|
-
title: `Command: quorum ${cmdName}`,
|
|
207
|
-
summary: [
|
|
208
|
-
`quorum ${cmdName}`,
|
|
209
|
-
subcommands.length > 0 ? `Subcommands: ${subcommands.join(", ")}` : "",
|
|
210
|
-
flags.length > 0 ? `Flags: ${flags.slice(0, 8).join(", ")}` : "",
|
|
211
|
-
usesLLM ? "Uses LLM" : "No LLM required",
|
|
212
|
-
readsChronicle ? "Reads Chronicle" : "",
|
|
213
|
-
writesChronicle ? "Writes Chronicle proposals" : "",
|
|
214
|
-
].filter(Boolean).join(" | "),
|
|
215
|
-
confidence: 0.9,
|
|
216
|
-
tags: [
|
|
217
|
-
"cli", "command", cmdName,
|
|
218
|
-
...subcommands.map(s => `subcommand:${s}`),
|
|
219
|
-
usesLLM ? "llm" : "deterministic",
|
|
220
|
-
readsChronicle ? "chronicle" : "",
|
|
221
|
-
].filter(Boolean),
|
|
222
|
-
})
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return area(input.area, findings)
|
|
226
|
-
},
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function repoSource(): ProductSource {
|
|
231
|
-
return {
|
|
232
|
-
id: "repo",
|
|
233
|
-
kind: "code",
|
|
234
|
-
async scan(input: ProductSourceScanInput): Promise<ProductSourceFinding[]> {
|
|
235
|
-
const { promises: fs } = await import("fs")
|
|
236
|
-
const path = await import("path")
|
|
237
|
-
|
|
238
|
-
const findings: ProductSourceFinding[] = []
|
|
239
|
-
let idx = 0
|
|
240
|
-
|
|
241
|
-
// Scan modules/
|
|
242
|
-
const modulesDir = path.join(input.rootDir, "modules")
|
|
243
|
-
try {
|
|
244
|
-
const entries = await fs.readdir(modulesDir, { withFileTypes: true })
|
|
245
|
-
for (const entry of entries) {
|
|
246
|
-
if (entry.isDirectory() && !entry.name.startsWith("_") && !["shared"].includes(entry.name)) {
|
|
247
|
-
findings.push({
|
|
248
|
-
id: `repo-module-${idx++}`,
|
|
249
|
-
kind: "code",
|
|
250
|
-
source: `modules/${entry.name}/`,
|
|
251
|
-
path: `modules/${entry.name}/`,
|
|
252
|
-
title: `Module: ${entry.name}`,
|
|
253
|
-
summary: `TypeScript module: modules/${entry.name}/`,
|
|
254
|
-
confidence: 0.85,
|
|
255
|
-
tags: ["module", entry.name, "code"],
|
|
256
|
-
})
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
} catch { /* no modules dir */ }
|
|
260
|
-
|
|
261
|
-
// Scan workflows
|
|
262
|
-
const workflowsDir = path.join(input.rootDir, ".github", "workflows")
|
|
263
|
-
try {
|
|
264
|
-
const entries = await fs.readdir(workflowsDir)
|
|
265
|
-
for (const file of entries.filter(f => f.endsWith(".yml"))) {
|
|
266
|
-
const content = await fs.readFile(path.join(workflowsDir, file), "utf8")
|
|
267
|
-
const nameMatch = content.match(/^name:\s*(.+)$/m)
|
|
268
|
-
findings.push({
|
|
269
|
-
id: `repo-workflow-${idx++}`,
|
|
270
|
-
kind: "config",
|
|
271
|
-
source: `.github/workflows/${file}`,
|
|
272
|
-
path: `.github/workflows/${file}`,
|
|
273
|
-
title: `Workflow: ${nameMatch?.[1]?.trim() ?? file}`,
|
|
274
|
-
summary: `CI/CD workflow: ${nameMatch?.[1]?.trim() ?? file}`,
|
|
275
|
-
confidence: 0.8,
|
|
276
|
-
tags: ["workflow", "ci", "github-actions"],
|
|
277
|
-
})
|
|
278
|
-
}
|
|
279
|
-
} catch { /* no workflows */ }
|
|
280
|
-
|
|
281
|
-
return area(input.area, findings)
|
|
282
|
-
},
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export function testsSource(): ProductSource {
|
|
287
|
-
return {
|
|
288
|
-
id: "tests",
|
|
289
|
-
kind: "tests",
|
|
290
|
-
async scan(input: ProductSourceScanInput): Promise<ProductSourceFinding[]> {
|
|
291
|
-
const { promises: fs } = await import("fs")
|
|
292
|
-
const path = await import("path")
|
|
293
|
-
|
|
294
|
-
const findings: ProductSourceFinding[] = []
|
|
295
|
-
let idx = 0
|
|
296
|
-
|
|
297
|
-
async function walkTests(dir: string): Promise<void> {
|
|
298
|
-
let entries
|
|
299
|
-
try { entries = await fs.readdir(dir, { withFileTypes: true }) } catch { return }
|
|
300
|
-
for (const entry of entries) {
|
|
301
|
-
const full = path.join(dir, entry.name)
|
|
302
|
-
if (entry.isDirectory() && !["node_modules", "dist"].includes(entry.name)) {
|
|
303
|
-
await walkTests(full)
|
|
304
|
-
} else if (entry.isFile() && (entry.name.endsWith(".test.ts") || entry.name.endsWith(".test.js"))) {
|
|
305
|
-
let content: string
|
|
306
|
-
try { content = await fs.readFile(full, "utf8") } catch { continue }
|
|
307
|
-
const rel = path.relative(input.rootDir, full).replace(/\\/g, "/")
|
|
308
|
-
// Extract describe/it/test names
|
|
309
|
-
const describeMatches = [...content.matchAll(/(?:describe|it|test)\s*\(\s*["'`]([^"'`]+)/g)]
|
|
310
|
-
const behaviors = describeMatches.map(m => m[1]).slice(0, 5)
|
|
311
|
-
if (behaviors.length > 0) {
|
|
312
|
-
findings.push({
|
|
313
|
-
id: `test-${idx++}`,
|
|
314
|
-
kind: "tests",
|
|
315
|
-
source: rel,
|
|
316
|
-
path: rel,
|
|
317
|
-
title: `Test: ${path.basename(entry.name, ".test.ts")}`,
|
|
318
|
-
summary: `Regression-protected: ${behaviors.join("; ")}`,
|
|
319
|
-
confidence: 0.85,
|
|
320
|
-
tags: ["test", "guaranteed-behavior", ...inferTags(behaviors.join(" "))],
|
|
321
|
-
})
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
await walkTests(path.join(input.rootDir, "modules"))
|
|
328
|
-
await walkTests(path.join(input.rootDir, "evals"))
|
|
329
|
-
|
|
330
|
-
return area(input.area, findings)
|
|
331
|
-
},
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
export function configSource(): ProductSource {
|
|
336
|
-
return {
|
|
337
|
-
id: "config",
|
|
338
|
-
kind: "config",
|
|
339
|
-
async scan(input: ProductSourceScanInput): Promise<ProductSourceFinding[]> {
|
|
340
|
-
const { promises: fs } = await import("fs")
|
|
341
|
-
const path = await import("path")
|
|
342
|
-
|
|
343
|
-
const findings: ProductSourceFinding[] = []
|
|
344
|
-
let idx = 0
|
|
345
|
-
|
|
346
|
-
const configFiles = ["tsconfig.json", ".npmignore", ".gitignore"]
|
|
347
|
-
for (const file of configFiles) {
|
|
348
|
-
let content: string
|
|
349
|
-
try { content = await fs.readFile(path.join(input.rootDir, file), "utf8") } catch { continue }
|
|
350
|
-
findings.push({
|
|
351
|
-
id: `cfg-${idx++}`,
|
|
352
|
-
kind: "config",
|
|
353
|
-
source: file,
|
|
354
|
-
path: file,
|
|
355
|
-
title: `Config: ${file}`,
|
|
356
|
-
summary: `${file} — ${content.slice(0, 100).replace(/\n/g, " ").trim()}`,
|
|
357
|
-
confidence: 0.75,
|
|
358
|
-
tags: ["config", file.replace(/[^a-z]/gi, "-")],
|
|
359
|
-
})
|
|
360
|
-
}
|
|
361
|
-
return findings
|
|
362
|
-
},
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
367
|
-
|
|
368
|
-
function inferTags(text: string): string[] {
|
|
369
|
-
const tags: string[] = []
|
|
370
|
-
const lower = text.toLowerCase()
|
|
371
|
-
const patterns: [RegExp, string][] = [
|
|
372
|
-
[/onboard|init|install|setup|get.?started/, "onboarding"],
|
|
373
|
-
[/auth|jwt|session|login|token/, "auth"],
|
|
374
|
-
[/database|migration|sql|postgres|mysql/, "database"],
|
|
375
|
-
[/payment|stripe|billing|checkout/, "payments"],
|
|
376
|
-
[/pii|privacy|gdpr|personal.?data/, "pii"],
|
|
377
|
-
[/commit|proposal|review|approve|memory/, "chronicle"],
|
|
378
|
-
[/advisor|brief|query/, "advisor"],
|
|
379
|
-
[/sentinel|coverage|drift/, "sentinel"],
|
|
380
|
-
[/jury|evaluate|score/, "jury"],
|
|
381
|
-
[/council|deliberate|validate/, "council"],
|
|
382
|
-
[/compass|pathway|bet|direction/, "compass"],
|
|
383
|
-
[/cli|command|terminal/, "cli"],
|
|
384
|
-
[/test|eval|spec/, "testing"],
|
|
385
|
-
[/llm|gpt|claude|openai|anthropic|gemini/, "llm"],
|
|
386
|
-
]
|
|
387
|
-
for (const [rx, tag] of patterns) {
|
|
388
|
-
if (rx.test(lower)) tags.push(tag)
|
|
389
|
-
}
|
|
390
|
-
return tags
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function area(filterArea: string | undefined, findings: ProductSourceFinding[]): ProductSourceFinding[] {
|
|
394
|
-
if (!filterArea) return findings
|
|
395
|
-
const lower = filterArea.toLowerCase()
|
|
396
|
-
return findings.filter(f =>
|
|
397
|
-
f.tags.some(t => t.toLowerCase().includes(lower)) ||
|
|
398
|
-
f.summary.toLowerCase().includes(lower) ||
|
|
399
|
-
f.title.toLowerCase().includes(lower),
|
|
400
|
-
)
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Re-export all sources as a convenience default set
|
|
404
|
-
export function defaultSources(): ProductSource[] {
|
|
405
|
-
return [
|
|
406
|
-
docsSource(),
|
|
407
|
-
packageSource(),
|
|
408
|
-
cliSource(),
|
|
409
|
-
repoSource(),
|
|
410
|
-
testsSource(),
|
|
411
|
-
configSource(),
|
|
412
|
-
]
|
|
413
|
-
}
|