@balpal4495/quorum 3.0.1 → 3.0.3

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.
@@ -269,19 +269,20 @@ function summarizeBehaviorMap(map) {
269
269
  // ── Score computation ─────────────────────────────────────────────────────────
270
270
 
271
271
  function computeScore(dims) {
272
+ const d = dims ?? {}
272
273
  const raw =
273
- dims.strategic_fit * 20 +
274
- dims.user_problem_clarity * 15 +
275
- dims.evidence_strength * 20 +
276
- dims.leverage * 10 +
277
- dims.feasibility * 15 +
278
- dims.time_to_signal * 10 +
279
- dims.reversibility * 10 -
280
- dims.complexity_penalty * 10 -
281
- dims.dependency_penalty * 8 -
282
- dims.contradiction_penalty * 15 -
283
- dims.evidence_gap_penalty * 12
284
- return { ...dims, total: Math.max(0, Math.min(100, Math.round(raw))) }
274
+ (d.strategic_fit ?? 0) * 20 +
275
+ (d.user_problem_clarity ?? 0) * 15 +
276
+ (d.evidence_strength ?? 0) * 20 +
277
+ (d.leverage ?? 0) * 10 +
278
+ (d.feasibility ?? 0) * 15 +
279
+ (d.time_to_signal ?? 0) * 10 +
280
+ (d.reversibility ?? 0) * 10 -
281
+ (d.complexity_penalty ?? 0) * 10 -
282
+ (d.dependency_penalty ?? 0) * 8 -
283
+ (d.contradiction_penalty ?? 0) * 15 -
284
+ (d.evidence_gap_penalty ?? 0) * 12
285
+ return { ...d, total: Math.max(0, Math.min(100, Math.round(raw))) }
285
286
  }
286
287
 
287
288
  // ── Prompts ───────────────────────────────────────────────────────────────────
@@ -672,9 +673,21 @@ function renderProductBrief(brief) {
672
673
  }
673
674
  }
674
675
 
675
- // ── Last-run artifact cache (used by --from-last) ─────────────────────────────
676
+ // ── Last-run artifact cache (persisted to disk so propose --from-last works across invocations)
676
677
 
677
- let _lastArtifact = null
678
+ async function saveLastArtifact(chronicleDir, artifact) {
679
+ try {
680
+ await fs.mkdir(chronicleDir, { recursive: true })
681
+ await fs.writeFile(path.join(chronicleDir, "compass-last.json"), JSON.stringify(artifact, null, 2), "utf8")
682
+ } catch { /* best-effort */ }
683
+ }
684
+
685
+ async function loadLastArtifact(chronicleDir) {
686
+ try {
687
+ const raw = await fs.readFile(path.join(chronicleDir, "compass-last.json"), "utf8")
688
+ return JSON.parse(raw)
689
+ } catch { return null }
690
+ }
678
691
 
679
692
  // ── Main ─────────────────────────────────────────────────────────────────────
680
693
 
@@ -711,15 +724,16 @@ export async function run(argv) {
711
724
  // ── Setup ─────────────────────────────────────────────────────────────────
712
725
 
713
726
  const rootDir = process.cwd()
714
- const chronicleDir = findChronicleDir(rootDir)
727
+ const chronicleDir = await findChronicleDir(rootDir)
715
728
 
716
729
  if (!chronicleDir) {
717
730
  console.error(c.red("Error: Chronicle not found. Run 'quorum init' first."))
718
731
  process.exit(1)
719
732
  }
720
733
 
721
- const NO_LLM_CMDS = new Set(["map", "opportunities"])
722
- const llm = NO_LLM_CMDS.has(subcommand) ? undefined : detectProvider()
734
+ const NO_LLM_CMDS = new Set(["map", "opportunities", "behavior", "propose", "outcome"])
735
+ const provider = NO_LLM_CMDS.has(subcommand) ? null : await detectProvider()
736
+ const llm = provider?.llm
723
737
 
724
738
  // ── Shared context helper ─────────────────────────────────────────────────
725
739
 
@@ -830,7 +844,7 @@ export async function run(argv) {
830
844
  let parsed
831
845
  try { parsed = parseLLMJson(raw) } catch { throw new Error(`Compass pathways: LLM returned non-JSON. Raw: ${raw.slice(0, 300)}`) }
832
846
  const data = (parsed.pathways ?? []).map(p => ({ ...p, scores: computeScore(p.scores ?? {}) }))
833
- _lastArtifact = { kind: "product_pathway", items: data }
847
+ await saveLastArtifact(chronicleDir, { kind: "product_pathway", items: data })
834
848
  if (jsonMode) { console.log(JSON.stringify(data, null, 2)); break }
835
849
  renderPathways(data)
836
850
  console.log(c.dim("\nTip: run 'quorum compass propose --from-last' to stage a Chronicle entry."))
@@ -843,7 +857,7 @@ export async function run(argv) {
843
857
  let parsed
844
858
  try { parsed = parseLLMJson(raw) } catch { throw new Error(`Compass bets: LLM returned non-JSON. Raw: ${raw.slice(0, 300)}`) }
845
859
  const data = (parsed.bets ?? []).map(b => ({ ...b, scores: computeScore(b.scores ?? {}) }))
846
- _lastArtifact = { kind: "product_bet", items: data }
860
+ await saveLastArtifact(chronicleDir, { kind: "product_bet", items: data })
847
861
  if (jsonMode) { console.log(JSON.stringify(data, null, 2)); break }
848
862
  renderBets(data)
849
863
  console.log(c.dim("\nTip: run 'quorum compass propose --from-last' to stage a Chronicle entry."))
@@ -861,7 +875,7 @@ export async function run(argv) {
861
875
  let data
862
876
  try { data = parseLLMJson(raw) } catch { throw new Error(`Compass score: LLM returned non-JSON. Raw: ${raw.slice(0, 300)}`) }
863
877
  if (data.scores) data.scores = computeScore(data.scores)
864
- _lastArtifact = { kind: "product_idea_score", items: [data] }
878
+ await saveLastArtifact(chronicleDir, { kind: "product_idea_score", items: [data] })
865
879
  if (jsonMode) { console.log(JSON.stringify(data, null, 2)); break }
866
880
  renderScore(data)
867
881
  break
@@ -893,12 +907,13 @@ Return ONLY valid JSON: { "title":"${title}","problem":"<problem>","target_user"
893
907
 
894
908
  case "propose": {
895
909
  if (flags["from-last"]) {
896
- if (!_lastArtifact?.items?.length) {
897
- console.error(c.red("Error: no Compass artifact in memory. Run pathways/bets/score first in the same session."))
910
+ const last = await loadLastArtifact(chronicleDir)
911
+ if (!last?.items?.length) {
912
+ console.error(c.red("Error: no prior Compass artifact found. Run 'quorum compass pathways', 'bets', or 'score' first."))
898
913
  process.exit(1)
899
914
  }
900
- const item = _lastArtifact.items[0]
901
- const res = await stageProposal(chronicleDir, _lastArtifact.kind, item)
915
+ const item = last.items[0]
916
+ const res = await stageProposal(chronicleDir, last.kind, item)
902
917
  console.log(c.green(`\n✓ ${res.message}`))
903
918
  break
904
919
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@balpal4495/quorum",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Git-backed memory and design review for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",