opencode-codegraph 0.1.23 → 0.1.25

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.25 - 2026-03-21
4
+
5
+ - append full workflow guidance alongside post-commit review summaries so commit-time output matches the normalized status contract more closely
6
+
7
+ ## 0.1.24 - 2026-03-20
8
+
9
+ - surface workflow-state transitions after later bash interactions so async state changes become visible without waiting for explicit status checks
10
+
3
11
  ## 0.1.23 - 2026-03-20
4
12
 
5
13
  - surface workflow-state transitions on later interactions so async status changes become visible without waiting for a fresh session
package/README.md CHANGED
@@ -54,7 +54,7 @@ Every conversation includes:
54
54
 
55
55
  ### Post-Commit Updates
56
56
 
57
- After `git commit`, the plugin triggers incremental CPG re-parsing via GoCPG and syncs the ChromaDB vector store. If durable review-trace artifacts exist for the new `HEAD`, the plugin also appends a structured post-commit block with:
57
+ After `git commit`, the plugin triggers incremental CPG re-parsing via GoCPG and syncs the ChromaDB vector store. If durable review-trace artifacts exist for the new `HEAD`, the plugin also appends a structured post-commit block plus the current workflow guidance with:
58
58
 
59
59
  - what changed in the review trace
60
60
  - why it matters
@@ -117,11 +117,21 @@ Place in `.opencode/commands/`:
117
117
  | `tool.execute.after` on test commands | Add after-test workflow guidance and detect failed test runs before suggesting the next command |
118
118
  | `tool.execute.after` on `git status` / `git diff` | Add current workflow guidance directly to common git inspection commands |
119
119
  | `tool.execute.after` | Trigger CPG update after git commit and append structured post-commit review summary |
120
+ | generic `tool.execute.after` | Surface workflow-state transitions after other bash commands when the underlying state changes |
120
121
  | `codegraph_review` tool | Returns review results together with current workflow guidance and suggested follow-up command |
121
122
  | `experimental.session.compacting` | Preserve current dogfooding status when OpenCode compacts long sessions |
122
- | `command.execute.before` | Inject current dogfooding status into `/review`, `/audit`, `/update`, `/status`, and `/next` |
123
+ | `command.execute.before` | Inject current dogfooding status into `/review`, `/audit`, `/update`, `/status`, `/next`, `/continue`, `/maintain-db`, and `/unlock-db` |
123
124
  | `db_locked` recovery path | Surface lock-holder-aware recovery guidance when DuckDB is blocked by another process |
124
125
  | `permission.ask` | Auto-allow `codegraph_*` tools |
126
+
127
+ Across status-oriented surfaces, the plugin is converging on one shared summary contract:
128
+
129
+ - workflow state
130
+ - blockers
131
+ - warnings
132
+ - what improved
133
+ - still blocked
134
+ - recommended command
125
135
 
126
136
  ## License
127
137
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-codegraph",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "OpenCode plugin for CodeGraph CPG-powered code analysis",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/index.ts CHANGED
@@ -135,7 +135,7 @@ const codegraphPlugin: Plugin = async (input) => {
135
135
  // 1c. Command execution: inject current dogfooding status into guided commands
136
136
  // -----------------------------------------------------------------
137
137
  "command.execute.before": async (inp, output) => {
138
- if (!["review", "audit", "update", "status", "next"].includes(inp.command)) {
138
+ if (!["review", "audit", "update", "status", "next", "continue", "maintain-db", "unlock-db"].includes(inp.command)) {
139
139
  return
140
140
  }
141
141
 
@@ -177,7 +177,7 @@ const codegraphPlugin: Plugin = async (input) => {
177
177
  const editIntent = messageSuggestsEditing(output.parts)
178
178
  const workflowIntent = messageSuggestsWorkflowGuidance(output.parts)
179
179
 
180
- if (!files.length && !workflowIntent) return
180
+ if (!files.length && !workflowIntent && !pendingReviewCommit) return
181
181
 
182
182
  try {
183
183
  const pendingUpdate = await consumePendingReviewTraceUpdate()
@@ -248,6 +248,7 @@ const codegraphPlugin: Plugin = async (input) => {
248
248
  "tool.execute.after": async (inp, output) => {
249
249
  if (inp.tool !== "bash") return
250
250
  const command = typeof inp.args?.command === "string" ? inp.args.command : ""
251
+ let appendedWorkflowGuidance = false
251
252
 
252
253
  if (isTestCommand(command)) {
253
254
  try {
@@ -260,6 +261,7 @@ const codegraphPlugin: Plugin = async (input) => {
260
261
  output.title = "CodeGraph: after-test guidance ready"
261
262
  const existingOutput = output.output?.trimEnd() || ""
262
263
  output.output = [existingOutput, transition || "", guidance].filter(Boolean).join("\n\n")
264
+ appendedWorkflowGuidance = true
263
265
  output.metadata = {
264
266
  ...output.metadata,
265
267
  codegraph_after_test_result: testFailed ? "failed" : "passed_or_unknown",
@@ -283,6 +285,7 @@ const codegraphPlugin: Plugin = async (input) => {
283
285
  output.title = "CodeGraph: git workflow guidance ready"
284
286
  const existingOutput = output.output?.trimEnd() || ""
285
287
  output.output = [existingOutput, transition || "", guidance].filter(Boolean).join("\n\n")
288
+ appendedWorkflowGuidance = true
286
289
  output.metadata = {
287
290
  ...output.metadata,
288
291
  codegraph_git_workflow_state: status.workflow_state || null,
@@ -295,6 +298,21 @@ const codegraphPlugin: Plugin = async (input) => {
295
298
  }
296
299
  }
297
300
 
301
+ if (!appendedWorkflowGuidance) {
302
+ try {
303
+ const rawStatus = await $`python -m src.cli.import_commands dogfood status --json`.quiet().text()
304
+ const status = JSON.parse(rawStatus)
305
+ const transition = workflowTransition(status)
306
+ if (transition) {
307
+ output.title = "CodeGraph: workflow update detected"
308
+ const existingOutput = output.output?.trimEnd() || ""
309
+ output.output = [existingOutput, transition].filter(Boolean).join("\n\n")
310
+ }
311
+ } catch {
312
+ // Best-effort guidance only
313
+ }
314
+ }
315
+
298
316
  if (!isGitCommit(output.output)) return
299
317
 
300
318
  try {
@@ -302,6 +320,7 @@ const codegraphPlugin: Plugin = async (input) => {
302
320
  await api.triggerIncrementalUpdate(projectId, directory)
303
321
 
304
322
  let traceSummary: string | null = null
323
+ let workflowGuidance: string | null = null
305
324
  if (commit) {
306
325
  const traceSnapshot = await readReviewTraceSnapshot(directory, commit)
307
326
  if (traceSnapshot) {
@@ -344,17 +363,27 @@ const codegraphPlugin: Plugin = async (input) => {
344
363
  }
345
364
  }
346
365
 
366
+ try {
367
+ const rawStatus = await $`python -m src.cli.import_commands dogfood status --json`.quiet().text()
368
+ const status = JSON.parse(rawStatus)
369
+ workflowGuidance = formatWorkflowGuidanceBlock(status)
370
+ } catch {
371
+ // keep commit flow resilient if unified status is unavailable
372
+ }
373
+
347
374
  // Notify user via output metadata (visible in OpenCode UI)
348
- output.title = traceSummary
375
+ output.title = traceSummary || workflowGuidance
349
376
  ? "CodeGraph: post-commit review summary ready"
350
377
  : "CodeGraph: CPG update triggered"
351
378
  output.metadata = {
352
379
  ...output.metadata,
353
380
  codegraph_cpg_update: "triggered",
354
381
  }
355
- if (traceSummary) {
382
+ if (traceSummary || workflowGuidance) {
356
383
  const existingOutput = output.output?.trimEnd() || ""
357
- output.output = existingOutput ? `${existingOutput}\n\n${traceSummary}` : traceSummary
384
+ output.output = [existingOutput, traceSummary || "", workflowGuidance || ""]
385
+ .filter(Boolean)
386
+ .join("\n\n")
358
387
  }
359
388
  } catch {
360
389
  // Best-effort — don't break the workflow
package/src/util.ts CHANGED
@@ -43,6 +43,13 @@ export type DogfoodStatusSnapshot = {
43
43
  workflow_state?: string
44
44
  recommended_next_action?: string
45
45
  recommended_command?: string
46
+ blockers?: string[]
47
+ warnings?: string[]
48
+ closure?: {
49
+ what_improved?: string
50
+ still_blocked?: string
51
+ before_push?: string
52
+ }
46
53
  }
47
54
 
48
55
  /**
@@ -397,6 +404,9 @@ export function formatDogfoodStatusSummary(snapshot: DogfoodStatusSnapshot): str
397
404
  const workflowState = snapshot.workflow_state
398
405
  const nextAction = snapshot.recommended_next_action
399
406
  const nextCommand = (snapshot as { recommended_command?: string }).recommended_command
407
+ const blockers = Array.isArray(snapshot.blockers) ? snapshot.blockers.filter(Boolean) : []
408
+ const warnings = Array.isArray(snapshot.warnings) ? snapshot.warnings.filter(Boolean) : []
409
+ const closure = snapshot.closure || {}
400
410
 
401
411
  if (typeof isFresh === "undefined" && !headCommit && !nextAction) {
402
412
  return null
@@ -432,6 +442,21 @@ export function formatDogfoodStatusSummary(snapshot: DogfoodStatusSnapshot): str
432
442
  if (nextCommand) {
433
443
  lines.push(`- Suggested command: ${nextCommand}`)
434
444
  }
445
+ if (blockers.length) {
446
+ lines.push(`- Blockers: ${blockers.join("; ")}`)
447
+ }
448
+ if (warnings.length) {
449
+ lines.push(`- Warnings: ${warnings.join("; ")}`)
450
+ }
451
+ if (closure.what_improved) {
452
+ lines.push(`- What improved: ${closure.what_improved}`)
453
+ }
454
+ if (closure.still_blocked) {
455
+ lines.push(`- Still blocked: ${closure.still_blocked}`)
456
+ }
457
+ if (closure.before_push) {
458
+ lines.push(`- Before push: ${closure.before_push}`)
459
+ }
435
460
  return lines.join("\n")
436
461
  }
437
462
 
@@ -439,8 +464,11 @@ export function formatWorkflowGuidanceBlock(snapshot: DogfoodStatusSnapshot): st
439
464
  const workflowState = snapshot.workflow_state
440
465
  const nextAction = snapshot.recommended_next_action
441
466
  const nextCommand = snapshot.recommended_command
467
+ const blockers = Array.isArray(snapshot.blockers) ? snapshot.blockers.filter(Boolean) : []
468
+ const warnings = Array.isArray(snapshot.warnings) ? snapshot.warnings.filter(Boolean) : []
469
+ const closure = snapshot.closure || {}
442
470
 
443
- if (!workflowState && !nextAction && !nextCommand) {
471
+ if (!workflowState && !nextAction && !nextCommand && !blockers.length && !warnings.length) {
444
472
  return null
445
473
  }
446
474
 
@@ -454,6 +482,21 @@ export function formatWorkflowGuidanceBlock(snapshot: DogfoodStatusSnapshot): st
454
482
  if (nextCommand) {
455
483
  lines.push(`- Suggested command: ${nextCommand}`)
456
484
  }
485
+ if (blockers.length) {
486
+ lines.push(`- Blockers: ${blockers.join("; ")}`)
487
+ }
488
+ if (warnings.length) {
489
+ lines.push(`- Warnings: ${warnings.join("; ")}`)
490
+ }
491
+ if (closure.what_improved) {
492
+ lines.push(`- What improved: ${closure.what_improved}`)
493
+ }
494
+ if (closure.still_blocked) {
495
+ lines.push(`- Still blocked: ${closure.still_blocked}`)
496
+ }
497
+ if (closure.before_push) {
498
+ lines.push(`- Before push: ${closure.before_push}`)
499
+ }
457
500
  return lines.join("\n")
458
501
  }
459
502
 
@@ -510,6 +553,24 @@ export function formatAfterTestGuidance(
510
553
  if (nextCommand) {
511
554
  lines.push(`- Suggested command: ${nextCommand}`)
512
555
  }
556
+ const blockers = Array.isArray(snapshot.blockers) ? snapshot.blockers.filter(Boolean) : []
557
+ const warnings = Array.isArray(snapshot.warnings) ? snapshot.warnings.filter(Boolean) : []
558
+ const closure = snapshot.closure || {}
559
+ if (blockers.length) {
560
+ lines.push(`- Blockers: ${blockers.join("; ")}`)
561
+ }
562
+ if (warnings.length) {
563
+ lines.push(`- Warnings: ${warnings.join("; ")}`)
564
+ }
565
+ if (closure.what_improved) {
566
+ lines.push(`- What improved: ${closure.what_improved}`)
567
+ }
568
+ if (closure.still_blocked) {
569
+ lines.push(`- Still blocked: ${closure.still_blocked}`)
570
+ }
571
+ if (closure.before_push) {
572
+ lines.push(`- Before push: ${closure.before_push}`)
573
+ }
513
574
  return lines.join("\n")
514
575
  }
515
576