@balpal4495/quorum 3.0.2 → 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
 
@@ -718,7 +731,7 @@ export async function run(argv) {
718
731
  process.exit(1)
719
732
  }
720
733
 
721
- const NO_LLM_CMDS = new Set(["map", "opportunities"])
734
+ const NO_LLM_CMDS = new Set(["map", "opportunities", "behavior", "propose", "outcome"])
722
735
  const provider = NO_LLM_CMDS.has(subcommand) ? null : await detectProvider()
723
736
  const llm = provider?.llm
724
737
 
@@ -831,7 +844,7 @@ export async function run(argv) {
831
844
  let parsed
832
845
  try { parsed = parseLLMJson(raw) } catch { throw new Error(`Compass pathways: LLM returned non-JSON. Raw: ${raw.slice(0, 300)}`) }
833
846
  const data = (parsed.pathways ?? []).map(p => ({ ...p, scores: computeScore(p.scores ?? {}) }))
834
- _lastArtifact = { kind: "product_pathway", items: data }
847
+ await saveLastArtifact(chronicleDir, { kind: "product_pathway", items: data })
835
848
  if (jsonMode) { console.log(JSON.stringify(data, null, 2)); break }
836
849
  renderPathways(data)
837
850
  console.log(c.dim("\nTip: run 'quorum compass propose --from-last' to stage a Chronicle entry."))
@@ -844,7 +857,7 @@ export async function run(argv) {
844
857
  let parsed
845
858
  try { parsed = parseLLMJson(raw) } catch { throw new Error(`Compass bets: LLM returned non-JSON. Raw: ${raw.slice(0, 300)}`) }
846
859
  const data = (parsed.bets ?? []).map(b => ({ ...b, scores: computeScore(b.scores ?? {}) }))
847
- _lastArtifact = { kind: "product_bet", items: data }
860
+ await saveLastArtifact(chronicleDir, { kind: "product_bet", items: data })
848
861
  if (jsonMode) { console.log(JSON.stringify(data, null, 2)); break }
849
862
  renderBets(data)
850
863
  console.log(c.dim("\nTip: run 'quorum compass propose --from-last' to stage a Chronicle entry."))
@@ -862,7 +875,7 @@ export async function run(argv) {
862
875
  let data
863
876
  try { data = parseLLMJson(raw) } catch { throw new Error(`Compass score: LLM returned non-JSON. Raw: ${raw.slice(0, 300)}`) }
864
877
  if (data.scores) data.scores = computeScore(data.scores)
865
- _lastArtifact = { kind: "product_idea_score", items: [data] }
878
+ await saveLastArtifact(chronicleDir, { kind: "product_idea_score", items: [data] })
866
879
  if (jsonMode) { console.log(JSON.stringify(data, null, 2)); break }
867
880
  renderScore(data)
868
881
  break
@@ -894,12 +907,13 @@ Return ONLY valid JSON: { "title":"${title}","problem":"<problem>","target_user"
894
907
 
895
908
  case "propose": {
896
909
  if (flags["from-last"]) {
897
- if (!_lastArtifact?.items?.length) {
898
- 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."))
899
913
  process.exit(1)
900
914
  }
901
- const item = _lastArtifact.items[0]
902
- const res = await stageProposal(chronicleDir, _lastArtifact.kind, item)
915
+ const item = last.items[0]
916
+ const res = await stageProposal(chronicleDir, last.kind, item)
903
917
  console.log(c.green(`\n✓ ${res.message}`))
904
918
  break
905
919
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@balpal4495/quorum",
3
- "version": "3.0.2",
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",