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 +8 -0
- package/README.md +12 -2
- package/package.json +1 -1
- package/src/index.ts +34 -5
- package/src/util.ts +62 -1
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 `/
|
|
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
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
|
|
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
|
|