@balpal4495/quorum 3.0.3 → 3.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/bin/commands/compass.js +4 -4
- package/bin/shared/llm.js +2 -2
- 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
package/bin/commands/compass.js
CHANGED
|
@@ -350,7 +350,7 @@ ${chronicleCtx}
|
|
|
350
350
|
## Current product behaviour
|
|
351
351
|
${behaviorCtx}
|
|
352
352
|
|
|
353
|
-
Return ONLY valid JSON: { "pathways": [ { "id":"<slug>","kind":"product_pathway","title":"<title>","goal":"<goal>","target_user":"<who>","problem":"<problem>","current_behaviors":["<behaviour>"],"opportunity":"<gap>","why_now":"<why>","smallest_useful_version":"<mvp>","phases":[{"name":"<phase>","outcome":"<outcome>","user_value":"<value>","build_notes":["<note>"],"dependencies":["<dep>"],"risks":["<risk>"]}],"dependencies":["<dep>"],"risks":["<risk>"],"assumptions":["<assumption>"],"open_questions":["<question>"],"evidence":[{"id":"<id>","kind":"<kind>","source":"<source>","summary":"<summary>","confidence":<0-1>}],"scores":{"strategic_fit":<0-1>,"user_problem_clarity":<0-1>,"evidence_strength":<0-1>,"leverage":<0-1>,"feasibility":<0-1>,"time_to_signal":<0-1>,"reversibility":<0-1>,"complexity_penalty":<0-1>,"dependency_penalty":<0-1>,"contradiction_penalty":<0-1>,"evidence_gap_penalty":<0-1>,"total":<0-100>},"confidence":<0-1>,"time_to_signal":"<timeframe>","reversibility":"high|medium|low","suggested_next_step":"<step>" } ] }
|
|
353
|
+
Return ONLY valid JSON (no markdown fences, no explanation): { "pathways": [ { "id":"<slug>","kind":"product_pathway","title":"<title>","goal":"<goal>","target_user":"<who>","problem":"<problem>","current_behaviors":["<behaviour>"],"opportunity":"<gap>","why_now":"<why>","smallest_useful_version":"<mvp>","phases":[{"name":"<phase>","outcome":"<outcome>","user_value":"<value>","build_notes":["<note>"],"dependencies":["<dep>"],"risks":["<risk>"]}],"dependencies":["<dep>"],"risks":["<risk>"],"assumptions":["<assumption>"],"open_questions":["<question>"],"evidence":[{"id":"<id>","kind":"<kind>","source":"<source>","summary":"<summary>","confidence":<0-1>}],"scores":{"strategic_fit":<0-1>,"user_problem_clarity":<0-1>,"evidence_strength":<0-1>,"leverage":<0-1>,"feasibility":<0-1>,"time_to_signal":<0-1>,"reversibility":<0-1>,"complexity_penalty":<0-1>,"dependency_penalty":<0-1>,"contradiction_penalty":<0-1>,"evidence_gap_penalty":<0-1>,"total":<0-100>},"confidence":<0-1>,"time_to_signal":"<timeframe>","reversibility":"high|medium|low","suggested_next_step":"<step>" } ] }
|
|
354
354
|
|
|
355
355
|
Sort by scores.total descending. Assumptions must always be present.`
|
|
356
356
|
}
|
|
@@ -368,7 +368,7 @@ ${chronicleCtx}
|
|
|
368
368
|
## Current product behaviour
|
|
369
369
|
${behaviorCtx}
|
|
370
370
|
|
|
371
|
-
Return ONLY valid JSON: { "bets": [ { "id":"<slug>","kind":"product_bet","title":"<title>","thesis":"<falsifiable hypothesis>","why_now":"<why>","target_user":"<who>","upside":"<best case>","downside":"<downside>","assumptions":["<assumption>"],"validation_signals":["<signal>"],"invalidation_signals":["<signal>"],"kill_criteria":["<criteria>"],"first_experiment":"<smallest test>","build_path":["<phase>"],"evidence":[{"id":"<id>","kind":"<kind>","source":"<source>","summary":"<summary>","confidence":<0-1>}],"scores":{"strategic_fit":<0-1>,"user_problem_clarity":<0-1>,"evidence_strength":<0-1>,"leverage":<0-1>,"feasibility":<0-1>,"time_to_signal":<0-1>,"reversibility":<0-1>,"complexity_penalty":<0-1>,"dependency_penalty":<0-1>,"contradiction_penalty":<0-1>,"evidence_gap_penalty":<0-1>,"total":<0-100>},"confidence":<0-1>,"time_to_signal":"<timeframe>","reversibility":"high|medium|low","appetite":"small|medium|large" } ] }
|
|
371
|
+
Return ONLY valid JSON (no markdown fences, no explanation): { "bets": [ { "id":"<slug>","kind":"product_bet","title":"<title>","thesis":"<falsifiable hypothesis>","why_now":"<why>","target_user":"<who>","upside":"<best case>","downside":"<downside>","assumptions":["<assumption>"],"validation_signals":["<signal>"],"invalidation_signals":["<signal>"],"kill_criteria":["<criteria>"],"first_experiment":"<smallest test>","build_path":["<phase>"],"evidence":[{"id":"<id>","kind":"<kind>","source":"<source>","summary":"<summary>","confidence":<0-1>}],"scores":{"strategic_fit":<0-1>,"user_problem_clarity":<0-1>,"evidence_strength":<0-1>,"leverage":<0-1>,"feasibility":<0-1>,"time_to_signal":<0-1>,"reversibility":<0-1>,"complexity_penalty":<0-1>,"dependency_penalty":<0-1>,"contradiction_penalty":<0-1>,"evidence_gap_penalty":<0-1>,"total":<0-100>},"confidence":<0-1>,"time_to_signal":"<timeframe>","reversibility":"high|medium|low","appetite":"small|medium|large" } ] }
|
|
372
372
|
|
|
373
373
|
Kill criteria and invalidation_signals must be present. If no user evidence, evidence_strength ≤ 0.4.`
|
|
374
374
|
}
|
|
@@ -384,7 +384,7 @@ ${chronicleCtx}
|
|
|
384
384
|
## Current product behaviour
|
|
385
385
|
${behaviorCtx}
|
|
386
386
|
|
|
387
|
-
Return ONLY valid JSON: { "idea":"${idea}","summary":"<one sentence>","recommendation":"pursue|pursue-small-test|investigate-more|defer|avoid","scores":{"strategic_fit":<0-1>,"user_problem_clarity":<0-1>,"evidence_strength":<0-1>,"leverage":<0-1>,"feasibility":<0-1>,"time_to_signal":<0-1>,"reversibility":<0-1>,"complexity_penalty":<0-1>,"dependency_penalty":<0-1>,"contradiction_penalty":<0-1>,"evidence_gap_penalty":<0-1>,"total":<0-100>},"evidence":[{"id":"<id>","kind":"<kind>","source":"<source>","summary":"<summary>","confidence":<0-1>}],"supporting_reasons":["<reason>"],"risks":["<risk>"],"assumptions":["<assumption>"],"open_questions":["<question>"],"suggested_next_step":"<action>" }
|
|
387
|
+
Return ONLY valid JSON (no markdown fences, no explanation): { "idea":"${idea}","summary":"<one sentence>","recommendation":"pursue|pursue-small-test|investigate-more|defer|avoid","scores":{"strategic_fit":<0-1>,"user_problem_clarity":<0-1>,"evidence_strength":<0-1>,"leverage":<0-1>,"feasibility":<0-1>,"time_to_signal":<0-1>,"reversibility":<0-1>,"complexity_penalty":<0-1>,"dependency_penalty":<0-1>,"contradiction_penalty":<0-1>,"evidence_gap_penalty":<0-1>,"total":<0-100>},"evidence":[{"id":"<id>","kind":"<kind>","source":"<source>","summary":"<summary>","confidence":<0-1>}],"supporting_reasons":["<reason>"],"risks":["<risk>"],"assumptions":["<assumption>"],"open_questions":["<question>"],"suggested_next_step":"<action>" }
|
|
388
388
|
|
|
389
389
|
Score total = strategic_fit*20 + user_problem_clarity*15 + evidence_strength*20 + leverage*10 + feasibility*15 + time_to_signal*10 + reversibility*10 - complexity_penalty*10 - dependency_penalty*8 - contradiction_penalty*15 - evidence_gap_penalty*12. Clamp 0–100.`
|
|
390
390
|
}
|
|
@@ -896,7 +896,7 @@ ${chronicleCtx}
|
|
|
896
896
|
## Current product behaviour
|
|
897
897
|
${behaviorCtx}
|
|
898
898
|
|
|
899
|
-
Return ONLY valid JSON: { "title":"${title}","problem":"<problem>","target_user":"<user>","recommended_solution":"<solution>","smallest_useful_version":"<mvp>","non_goals":["<non-goal>"],"risks":["<risk>"],"open_questions":["<question>"],"suggested_quorum_checks":["<quorum command>"] }`
|
|
899
|
+
Return ONLY valid JSON (no markdown fences, no explanation): { "title":"${title}","problem":"<problem>","target_user":"<user>","recommended_solution":"<solution>","smallest_useful_version":"<mvp>","non_goals":["<non-goal>"],"risks":["<risk>"],"open_questions":["<question>"],"suggested_quorum_checks":["<quorum command>"] }`
|
|
900
900
|
const raw = await callLLM(llm, specPrompt)
|
|
901
901
|
let data
|
|
902
902
|
try { data = parseLLMJson(raw) } catch { throw new Error(`Compass spec: LLM returned non-JSON. Raw: ${raw.slice(0, 300)}`) }
|
package/bin/shared/llm.js
CHANGED
|
@@ -112,7 +112,7 @@ function createAnthropicProvider(apiKey) {
|
|
|
112
112
|
},
|
|
113
113
|
body: JSON.stringify({
|
|
114
114
|
model,
|
|
115
|
-
max_tokens:
|
|
115
|
+
max_tokens: 8192,
|
|
116
116
|
...(systemMsg ? { system: systemMsg } : {}),
|
|
117
117
|
messages: userMessages,
|
|
118
118
|
}),
|
|
@@ -140,7 +140,7 @@ function createOpenAICompatProvider(apiKey, baseUrl, fixedModel) {
|
|
|
140
140
|
body: JSON.stringify({
|
|
141
141
|
model: fixedModel ?? model,
|
|
142
142
|
messages,
|
|
143
|
-
max_tokens:
|
|
143
|
+
max_tokens: 8192,
|
|
144
144
|
}),
|
|
145
145
|
})
|
|
146
146
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AdvisorInput, AdvisorOutput, AdvisorDeps } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ask the Advisor a plain-language question.
|
|
4
|
+
*
|
|
5
|
+
* Internally calls the LLM and validates the answer against a satisfaction
|
|
6
|
+
* threshold (confidence ≥ 0.7, no blockers). Retries up to MAX_RETRIES times
|
|
7
|
+
* with the previous answer included as context. Returns the best answer found
|
|
8
|
+
* within the retry budget regardless of whether the threshold was met.
|
|
9
|
+
*
|
|
10
|
+
* Throws if the LLM returns non-JSON or output that fails schema validation.
|
|
11
|
+
*/
|
|
12
|
+
export declare function ask(input: AdvisorInput, deps: AdvisorDeps): Promise<AdvisorOutput>;
|
|
13
|
+
//# sourceMappingURL=ask.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../modules/advisor/ask.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAiB,WAAW,EAAE,MAAM,YAAY,CAAA;AA6DzF;;;;;;;;;GASG;AACH,wBAAsB,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAcxF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { SYSTEM_PROMPT, buildUserPrompt } from "./prompt.js";
|
|
3
|
+
const SATISFACTION_THRESHOLD = 0.7;
|
|
4
|
+
const MAX_RETRIES = 2;
|
|
5
|
+
const AdvisorAnswerSchema = z.object({
|
|
6
|
+
confidence: z.number().min(0).max(1),
|
|
7
|
+
what_we_know: z.string().min(1),
|
|
8
|
+
risks: z.array(z.string()),
|
|
9
|
+
blockers: z.array(z.string()),
|
|
10
|
+
recommendation: z.string().min(1),
|
|
11
|
+
next_step: z.string().min(1),
|
|
12
|
+
});
|
|
13
|
+
async function callLLM(input, deps, attempt, previous) {
|
|
14
|
+
const { llm, model } = deps;
|
|
15
|
+
let userPrompt = buildUserPrompt(input.question, input.evidence);
|
|
16
|
+
if (attempt > 0 && previous) {
|
|
17
|
+
userPrompt += [
|
|
18
|
+
"",
|
|
19
|
+
`## Previous Answer (attempt ${attempt} — did not meet quality threshold)`,
|
|
20
|
+
`Confidence: ${previous.confidence.toFixed(2)} (need ≥ ${SATISFACTION_THRESHOLD})`,
|
|
21
|
+
previous.blockers.length > 0
|
|
22
|
+
? `Unresolved blockers: ${previous.blockers.join("; ")}`
|
|
23
|
+
: "",
|
|
24
|
+
"Please produce a more specific and concrete answer.",
|
|
25
|
+
].filter(Boolean).join("\n");
|
|
26
|
+
}
|
|
27
|
+
const raw = await llm([
|
|
28
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
29
|
+
{ role: "user", content: userPrompt },
|
|
30
|
+
], model);
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
const cleaned = raw.replace(/^```(?:json)?\s*/m, "").replace(/\s*```$/m, "").trim();
|
|
34
|
+
parsed = JSON.parse(cleaned);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
throw new Error(`Advisor: LLM returned non-JSON. Raw (first 300 chars): ${raw.slice(0, 300)}`);
|
|
38
|
+
}
|
|
39
|
+
const result = AdvisorAnswerSchema.safeParse(parsed);
|
|
40
|
+
if (!result.success) {
|
|
41
|
+
throw new Error(`Advisor: LLM output failed validation. Issues: ${JSON.stringify(result.error.issues)}`);
|
|
42
|
+
}
|
|
43
|
+
return result.data;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Ask the Advisor a plain-language question.
|
|
47
|
+
*
|
|
48
|
+
* Internally calls the LLM and validates the answer against a satisfaction
|
|
49
|
+
* threshold (confidence ≥ 0.7, no blockers). Retries up to MAX_RETRIES times
|
|
50
|
+
* with the previous answer included as context. Returns the best answer found
|
|
51
|
+
* within the retry budget regardless of whether the threshold was met.
|
|
52
|
+
*
|
|
53
|
+
* Throws if the LLM returns non-JSON or output that fails schema validation.
|
|
54
|
+
*/
|
|
55
|
+
export async function ask(input, deps) {
|
|
56
|
+
let last = null;
|
|
57
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
58
|
+
const answer = await callLLM(input, deps, attempt, last);
|
|
59
|
+
last = answer;
|
|
60
|
+
const satisfied = answer.confidence >= SATISFACTION_THRESHOLD && answer.blockers.length === 0;
|
|
61
|
+
if (satisfied || attempt === MAX_RETRIES) {
|
|
62
|
+
return { ...answer, question: input.question, retries: attempt };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { ...last, question: input.question, retries: MAX_RETRIES };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=ask.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../modules/advisor/ask.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../modules/advisor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAC9B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../modules/advisor/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { OracleResult } from "../shared/types.js";
|
|
2
|
+
export declare const SYSTEM_PROMPT = "You are the Quorum Advisor \u2014 the plain-language interface to a team's collective knowledge.\n\nYou receive a question from a developer or engineering manager, along with relevant Chronicle evidence.\nSynthesise that evidence into a clear, concise answer a human can act on.\n\nRules:\n- Write for a human who does not know what \"Chronicle entries\" or \"vector search\" mean.\n- Be direct. One clear recommendation, not a list of options unless genuinely necessary.\n- If Chronicle has relevant evidence, reference it plainly: \"the team already decided X\".\n- If Chronicle has no evidence, say so honestly \u2014 do not invent history.\n- Blockers are hard blockers only \u2014 things that MUST be resolved before moving forward.\n- risks are real concerns worth knowing, not theoretical edge cases.\n\nReturn ONLY valid JSON matching this schema (no markdown fences, no explanation):\n{\n \"confidence\": <number 0\u20131 \u2014 how confident are you given the available evidence>,\n \"what_we_know\": <string \u2014 what Chronicle knows about this topic. Plain English, 1\u20133 sentences.>,\n \"risks\": [<string \u2014 each real risk, plain English, one per item. Empty array if none.>],\n \"blockers\": [<string \u2014 hard blockers only. Empty array if none.>],\n \"recommendation\": <string \u2014 one clear recommended action>,\n \"next_step\": <string \u2014 the specific next thing to do, e.g. a quorum command or a decision>\n}";
|
|
3
|
+
export declare function formatEvidence(evidence: OracleResult[]): string;
|
|
4
|
+
export declare function buildUserPrompt(question: string, evidence: OracleResult[]): string;
|
|
5
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../modules/advisor/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGtD,eAAO,MAAM,aAAa,i7CAqBxB,CAAA;AAEF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAa/D;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAQlF"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { entryText } from "../shared/types"
|
|
3
|
-
|
|
1
|
+
import { entryText } from "../shared/types.js";
|
|
4
2
|
export const SYSTEM_PROMPT = `You are the Quorum Advisor — the plain-language interface to a team's collective knowledge.
|
|
5
3
|
|
|
6
4
|
You receive a question from a developer or engineering manager, along with relevant Chronicle evidence.
|
|
@@ -22,29 +20,27 @@ Return ONLY valid JSON matching this schema (no markdown fences, no explanation)
|
|
|
22
20
|
"blockers": [<string — hard blockers only. Empty array if none.>],
|
|
23
21
|
"recommendation": <string — one clear recommended action>,
|
|
24
22
|
"next_step": <string — the specific next thing to do, e.g. a quorum command or a decision>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
e.
|
|
36
|
-
e.status === "validated" ? " [VALIDATED]" : ""
|
|
37
|
-
return `[${e.id.slice(0, 8)}]${statusTag} ${text}\n Areas: ${e.affected_areas.join(", ")}`
|
|
23
|
+
}`;
|
|
24
|
+
export function formatEvidence(evidence) {
|
|
25
|
+
if (evidence.length === 0) {
|
|
26
|
+
return "Chronicle has no prior entries on this topic.";
|
|
27
|
+
}
|
|
28
|
+
return evidence
|
|
29
|
+
.map(e => {
|
|
30
|
+
const text = entryText(e);
|
|
31
|
+
const statusTag = e.status === "refuted" ? " [REJECTED]" :
|
|
32
|
+
e.status === "validated" ? " [VALIDATED]" : "";
|
|
33
|
+
return `[${e.id.slice(0, 8)}]${statusTag} ${text}\n Areas: ${e.affected_areas.join(", ")}`;
|
|
38
34
|
})
|
|
39
|
-
|
|
35
|
+
.join("\n\n");
|
|
40
36
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
].join("\n")
|
|
37
|
+
export function buildUserPrompt(question, evidence) {
|
|
38
|
+
return [
|
|
39
|
+
"## Question",
|
|
40
|
+
question,
|
|
41
|
+
"",
|
|
42
|
+
"## Chronicle Evidence",
|
|
43
|
+
formatEvidence(evidence),
|
|
44
|
+
].join("\n");
|
|
50
45
|
}
|
|
46
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../modules/advisor/prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE9C,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;EAqB3B,CAAA;AAEF,MAAM,UAAU,cAAc,CAAC,QAAwB;IACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,+CAA+C,CAAA;IACxD,CAAC;IACD,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE;QACP,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QACzB,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,KAAK,SAAS,CAAG,CAAC,CAAC,aAAa,CAAE,CAAC;YAC3C,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAA;QAChD,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,SAAS,IAAI,IAAI,cAAc,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;IAC7F,CAAC,CAAC;SACD,IAAI,CAAC,MAAM,CAAC,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,QAAwB;IACxE,OAAO;QACL,aAAa;QACb,QAAQ;QACR,EAAE;QACF,uBAAuB;QACvB,cAAc,CAAC,QAAQ,CAAC;KACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { OracleResult, LLMProvider } from "../shared/types.js";
|
|
2
|
+
export interface AdvisorInput {
|
|
3
|
+
question: string;
|
|
4
|
+
evidence: OracleResult[];
|
|
5
|
+
}
|
|
6
|
+
export interface AdvisorAnswer {
|
|
7
|
+
confidence: number;
|
|
8
|
+
what_we_know: string;
|
|
9
|
+
risks: string[];
|
|
10
|
+
blockers: string[];
|
|
11
|
+
recommendation: string;
|
|
12
|
+
next_step: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AdvisorOutput extends AdvisorAnswer {
|
|
15
|
+
question: string;
|
|
16
|
+
/** Number of retries taken before the answer met the satisfaction threshold. */
|
|
17
|
+
retries: number;
|
|
18
|
+
}
|
|
19
|
+
export interface AdvisorDeps {
|
|
20
|
+
llm: LLMProvider;
|
|
21
|
+
model?: string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../modules/advisor/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEnE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,QAAQ,EAAE,MAAM,CAAA;IAChB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,WAAW,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../modules/advisor/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BehaviorMap, BehaviorMapInput, ProductSourceFinding } from "./types.js";
|
|
2
|
+
export declare function mapBehaviorsFromFindings(findings: ProductSourceFinding[], input?: BehaviorMapInput): BehaviorMap;
|
|
3
|
+
export declare function summarizeBehaviorMap(map: BehaviorMap): string;
|
|
4
|
+
//# sourceMappingURL=behavior.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior.d.ts","sourceRoot":"","sources":["../../modules/compass/behavior.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACyD,WAAW,EAC9E,gBAAgB,EAAE,oBAAoB,EACvC,MAAM,YAAY,CAAA;AAInB,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,oBAAoB,EAAE,EAChC,KAAK,GAAE,gBAAqB,GAC3B,WAAW,CAkGb;AAID,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAkB7D"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// ── Deterministic behaviour mapping from source findings ─────────────────────
|
|
2
|
+
export function mapBehaviorsFromFindings(findings, input = {}) {
|
|
3
|
+
const behaviors = [];
|
|
4
|
+
const gaps = [];
|
|
5
|
+
const contradictions = [];
|
|
6
|
+
// Group CLI commands into behaviours
|
|
7
|
+
const cliFindings = findings.filter(f => f.kind === "cli");
|
|
8
|
+
for (const f of cliFindings) {
|
|
9
|
+
behaviors.push({
|
|
10
|
+
id: `behavior-cli-${f.id}`,
|
|
11
|
+
area: inferArea(f),
|
|
12
|
+
name: f.title,
|
|
13
|
+
description: f.summary,
|
|
14
|
+
current_behavior: f.summary,
|
|
15
|
+
evidence: [findingToRef(f)],
|
|
16
|
+
basis: ["implemented"],
|
|
17
|
+
confidence: f.confidence,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// Extract documented user flows from docs findings
|
|
21
|
+
const docsFindings = findings.filter(f => f.kind === "docs" && f.tags.includes("cli"));
|
|
22
|
+
for (const f of docsFindings) {
|
|
23
|
+
// Only add if not already covered by a CLI finding
|
|
24
|
+
const alreadyPresent = behaviors.some(b => b.current_behavior.toLowerCase().includes(extractCommand(f.summary).toLowerCase()) &&
|
|
25
|
+
extractCommand(f.summary).length > 3);
|
|
26
|
+
if (!alreadyPresent && extractCommand(f.summary)) {
|
|
27
|
+
behaviors.push({
|
|
28
|
+
id: `behavior-docs-${f.id}`,
|
|
29
|
+
area: inferArea(f),
|
|
30
|
+
name: `Documented: ${f.title}`,
|
|
31
|
+
description: f.summary,
|
|
32
|
+
current_behavior: f.summary,
|
|
33
|
+
evidence: [findingToRef(f)],
|
|
34
|
+
basis: ["documented"],
|
|
35
|
+
confidence: f.confidence * 0.9,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Cross-reference: documented claims without implementation
|
|
40
|
+
const docsHeadings = findings.filter(f => f.kind === "docs" && !f.tags.includes("cli"));
|
|
41
|
+
const implementedAreas = new Set(behaviors.map(b => b.area));
|
|
42
|
+
// Detect gaps: central product promises with no CLI surface
|
|
43
|
+
const EXPECTED_AREAS = ["onboarding", "chronicle", "advisor", "review"];
|
|
44
|
+
for (const expected of EXPECTED_AREAS) {
|
|
45
|
+
const hasBehavior = behaviors.some(b => b.area === expected || b.name.toLowerCase().includes(expected));
|
|
46
|
+
if (!hasBehavior) {
|
|
47
|
+
const docRef = docsHeadings.find(f => f.summary.toLowerCase().includes(expected));
|
|
48
|
+
gaps.push({
|
|
49
|
+
id: `gap-${expected}`,
|
|
50
|
+
area: expected,
|
|
51
|
+
gap: `No first-class CLI command found for '${expected}'.`,
|
|
52
|
+
why_it_matters: `'${expected}' appears in product docs but has no dedicated CLI surface.`,
|
|
53
|
+
evidence: docRef ? [findingToRef(docRef)] : [],
|
|
54
|
+
confidence: 0.7,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Gap: no product-direction module (Compass itself)
|
|
59
|
+
const hasCompass = behaviors.some(b => b.name.toLowerCase().includes("compass"));
|
|
60
|
+
if (!hasCompass) {
|
|
61
|
+
gaps.push({
|
|
62
|
+
id: "gap-product-direction",
|
|
63
|
+
area: "product direction",
|
|
64
|
+
gap: "No product behaviour mapping or direction module currently exists.",
|
|
65
|
+
why_it_matters: "Quorum helps agents avoid repeating engineering mistakes, but has no module to help avoid repeating product-direction mistakes.",
|
|
66
|
+
evidence: [],
|
|
67
|
+
confidence: 0.93,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Filter by area if provided
|
|
71
|
+
const filteredBehaviors = input.area
|
|
72
|
+
? behaviors.filter(b => b.area.toLowerCase().includes(input.area.toLowerCase()) ||
|
|
73
|
+
b.name.toLowerCase().includes(input.area.toLowerCase()))
|
|
74
|
+
: behaviors;
|
|
75
|
+
const overallConfidence = filteredBehaviors.length === 0
|
|
76
|
+
? 0.5
|
|
77
|
+
: filteredBehaviors.reduce((s, b) => s + b.confidence, 0) / filteredBehaviors.length;
|
|
78
|
+
return {
|
|
79
|
+
generated_at: new Date().toISOString(),
|
|
80
|
+
area: input.area,
|
|
81
|
+
behaviors: filteredBehaviors,
|
|
82
|
+
gaps: input.area
|
|
83
|
+
? gaps.filter(g => g.area.toLowerCase().includes(input.area.toLowerCase()))
|
|
84
|
+
: gaps,
|
|
85
|
+
contradictions,
|
|
86
|
+
confidence: Math.round(overallConfidence * 100) / 100,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// ── Extract documented behaviors for LLM context ─────────────────────────────
|
|
90
|
+
export function summarizeBehaviorMap(map) {
|
|
91
|
+
const lines = [];
|
|
92
|
+
if (map.behaviors.length > 0) {
|
|
93
|
+
lines.push("## Current behaviours");
|
|
94
|
+
for (const b of map.behaviors.slice(0, 20)) {
|
|
95
|
+
lines.push(` ✓ ${b.current_behavior.slice(0, 100)}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (map.gaps.length > 0) {
|
|
99
|
+
lines.push("\n## Gaps");
|
|
100
|
+
for (const g of map.gaps) {
|
|
101
|
+
lines.push(` ? ${g.gap}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return lines.join("\n");
|
|
105
|
+
}
|
|
106
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
107
|
+
function findingToRef(f) {
|
|
108
|
+
return {
|
|
109
|
+
id: f.id,
|
|
110
|
+
kind: f.kind,
|
|
111
|
+
source: f.source,
|
|
112
|
+
path: f.path,
|
|
113
|
+
summary: f.summary,
|
|
114
|
+
confidence: f.confidence,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function inferArea(f) {
|
|
118
|
+
if (f.tags.includes("onboarding") || f.tags.includes("init"))
|
|
119
|
+
return "onboarding";
|
|
120
|
+
if (f.tags.includes("chronicle") || f.tags.includes("commit") || f.tags.includes("proposal"))
|
|
121
|
+
return "chronicle review";
|
|
122
|
+
if (f.tags.includes("advisor"))
|
|
123
|
+
return "memory retrieval";
|
|
124
|
+
if (f.tags.includes("sentinel"))
|
|
125
|
+
return "coverage";
|
|
126
|
+
if (f.tags.includes("compass"))
|
|
127
|
+
return "product direction";
|
|
128
|
+
if (f.tags.includes("auth"))
|
|
129
|
+
return "auth";
|
|
130
|
+
if (f.tags.includes("cli"))
|
|
131
|
+
return "cli";
|
|
132
|
+
return "general";
|
|
133
|
+
}
|
|
134
|
+
function extractCommand(text) {
|
|
135
|
+
const match = text.match(/`(quorum [^`]+)`/);
|
|
136
|
+
return match?.[1] ?? "";
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=behavior.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior.js","sourceRoot":"","sources":["../../modules/compass/behavior.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../modules/compass/create.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,OAAO,EAAE,oBAAoB,EAW9B,MAAM,YAAY,CAAA;AAoCnB,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CA0TpE"}
|