opencode-codegraph 0.1.4 → 0.1.6

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.6 - 2026-03-20
4
+
5
+ - add explicit pending post-commit summary when durable review trace is not yet available
6
+ - guide developers to `/status` instead of leaving post-commit review state ambiguous
7
+ - document pending-trace behavior in plugin and OpenCode workflow docs
8
+
9
+ ## 0.1.5 - 2026-03-20
10
+
11
+ - add unified next-action summary to review-trace status output
12
+ - surface next-action guidance in post-commit OpenCode plugin metadata and review-trace summaries
13
+ - document the next-action workflow in plugin and integration docs
14
+
3
15
  ## 0.1.4 - 2026-03-20
4
16
 
5
17
  - add conversational pre-edit guidance when a chat message suggests code modification
package/README.md CHANGED
@@ -45,7 +45,19 @@ Every conversation includes a project summary with file count, top complexity ho
45
45
 
46
46
  ### Post-Commit Updates
47
47
 
48
- 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 short review-trace summary with findings and recommendations.
48
+ 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:
49
+
50
+ - what changed in the review trace
51
+ - why it matters
52
+ - top recommendations
53
+ - one clear next action
54
+
55
+ If the durable review trace is not available yet, the plugin still appends a pending summary telling the developer to check `/status` instead of leaving the post-commit state ambiguous.
56
+
57
+ This means the post-commit UX now has two explicit states:
58
+
59
+ - trace ready -> structured summary with findings, recommendations, and next action
60
+ - trace pending/missing -> structured pending summary with deterministic follow-up
49
61
 
50
62
  ### Custom Tools
51
63
 
@@ -89,7 +101,7 @@ Place in `.opencode/commands/`:
89
101
  | `experimental.chat.system.transform` | Inject project summary into system prompt |
90
102
  | `chat.message` | Add CPG context for mentioned files |
91
103
  | `chat.message` (edit intent) | Add pre-edit warnings for files likely to be modified |
92
- | `tool.execute.after` | Trigger CPG update after git commit |
104
+ | `tool.execute.after` | Trigger CPG update after git commit and append structured post-commit review summary |
93
105
  | `permission.ask` | Auto-allow `codegraph_*` tools |
94
106
 
95
107
  ## License
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "opencode-codegraph",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "OpenCode plugin for CodeGraph CPG-powered code analysis",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "exports": {
8
8
  ".": "./src/index.ts"
9
9
  },
10
- "files": [
11
- "src",
12
- "CHANGELOG.md"
13
- ],
10
+ "files": [
11
+ "src",
12
+ "CHANGELOG.md"
13
+ ],
14
14
  "scripts": {
15
15
  "typecheck": "tsc --noEmit",
16
16
  "build": "tsc"
package/src/index.ts CHANGED
@@ -17,11 +17,15 @@ import { CodeGraphAPI } from "./api"
17
17
  import {
18
18
  extractFileRefs,
19
19
  fileNeedsRegistrationCheck,
20
+ formatPendingReviewTraceSummary,
20
21
  formatReviewTraceSummary,
21
22
  getHeadCommit,
22
23
  isGitCommit,
23
24
  messageSuggestsEditing,
25
+ recommendedNextActionFromReviewTrace,
24
26
  readReviewTraceSnapshot,
27
+ whatChangedFromReviewTrace,
28
+ whyItMattersFromReviewTrace,
25
29
  } from "./util"
26
30
 
27
31
  const codegraphPlugin: Plugin = async (input) => {
@@ -112,13 +116,33 @@ const codegraphPlugin: Plugin = async (input) => {
112
116
  codegraph_review_trace_findings: traceSnapshot.review_findings_count ?? null,
113
117
  codegraph_review_trace_recommendations:
114
118
  traceSnapshot.review_recommendations?.slice(0, 3) || [],
119
+ codegraph_review_trace_next_action: recommendedNextActionFromReviewTrace(traceSnapshot),
120
+ codegraph_review_trace_what_changed: whatChangedFromReviewTrace(traceSnapshot),
121
+ codegraph_review_trace_why_it_matters: whyItMattersFromReviewTrace(traceSnapshot),
122
+ }
123
+ } else {
124
+ traceSummary = formatPendingReviewTraceSummary(commit)
125
+ output.metadata = {
126
+ ...output.metadata,
127
+ codegraph_review_trace_status: "pending_or_missing",
128
+ codegraph_review_trace_phase: "awaiting_trace",
129
+ codegraph_review_trace_findings: null,
130
+ codegraph_review_trace_recommendations: [],
131
+ codegraph_review_trace_next_action:
132
+ "Wait briefly for review trace completion, then run /status to check the latest result.",
133
+ codegraph_review_trace_what_changed: [
134
+ `Incremental CPG update was triggered for ${commit.slice(0, 12)}.`,
135
+ "Durable review trace is not available yet or has not been written.",
136
+ ],
137
+ codegraph_review_trace_why_it_matters:
138
+ "Post-commit findings and recommendations may still be pending, so the commit is not fully evaluated yet.",
115
139
  }
116
140
  }
117
141
  }
118
142
 
119
143
  // Notify user via output metadata (visible in OpenCode UI)
120
144
  output.title = traceSummary
121
- ? "CodeGraph: CPG update triggered + review trace found"
145
+ ? "CodeGraph: post-commit review summary ready"
122
146
  : "CodeGraph: CPG update triggered"
123
147
  output.metadata = {
124
148
  ...output.metadata,
package/src/util.ts CHANGED
@@ -129,18 +129,65 @@ export async function readReviewTraceSnapshot(
129
129
  return null
130
130
  }
131
131
 
132
+ export function formatPendingReviewTraceSummary(commit: string | null): string {
133
+ const commitLabel = commit ? ` for \`${commit.slice(0, 12)}\`` : ""
134
+ return [
135
+ "## CodeGraph Post-Commit Summary",
136
+ "",
137
+ "### What changed",
138
+ "",
139
+ `- Incremental CPG update was triggered${commitLabel}.`,
140
+ "- Durable review trace is not available yet or has not been written.",
141
+ "",
142
+ "### Why it matters",
143
+ "",
144
+ "- Post-commit findings and recommendations may still be pending, so the commit is not fully evaluated yet.",
145
+ "",
146
+ "### What to do now",
147
+ "",
148
+ "- Wait briefly for review trace completion, then run `/status` to check the latest result.",
149
+ ].join("\n")
150
+ }
151
+
132
152
  export function formatReviewTraceSummary(snapshot: ReviewTraceSnapshot): string | null {
133
- const status = snapshot.status || "unknown"
134
- const phase = snapshot.phase || "unknown"
135
- const findingsCount = snapshot.review_findings_count
136
153
  const recommendations = Array.isArray(snapshot.review_recommendations)
137
154
  ? snapshot.review_recommendations.filter(Boolean)
138
155
  : []
156
+ const whatChanged = whatChangedFromReviewTrace(snapshot)
157
+ const whyItMatters = whyItMattersFromReviewTrace(snapshot)
158
+ const nextAction = recommendedNextActionFromReviewTrace(snapshot)
159
+
160
+ const lines = ["## CodeGraph Post-Commit Summary", ""]
139
161
 
140
- const lines = ["## CodeGraph Review Trace", "", `- Status: ${status}`, `- Phase: ${phase}`]
162
+ if (whatChanged) {
163
+ lines.push("### What changed", "", ...whatChanged.map((item) => `- ${item}`), "")
164
+ }
141
165
 
142
- if (typeof findingsCount === "number") {
143
- lines.push(`- Findings: ${findingsCount}`)
166
+ if (whyItMatters) {
167
+ lines.push("### Why it matters", "", `- ${whyItMatters}`, "")
168
+ }
169
+
170
+ if (recommendations.length) {
171
+ lines.push("### Top recommendations", "")
172
+ for (const recommendation of recommendations.slice(0, 3)) {
173
+ lines.push(`- ${recommendation}`)
174
+ }
175
+ lines.push("")
176
+ }
177
+
178
+ lines.push("### What to do now", "", `- ${nextAction}`)
179
+
180
+ return lines.join("\n")
181
+ }
182
+
183
+ export function whatChangedFromReviewTrace(snapshot: ReviewTraceSnapshot): string[] {
184
+ const items: string[] = []
185
+ const status = snapshot.status || "unknown"
186
+ const phase = snapshot.phase || "unknown"
187
+ items.push(`Review trace status is ${status} (phase: ${phase}).`)
188
+
189
+ if (typeof snapshot.review_findings_count === "number") {
190
+ items.push(`CodeGraph reported ${snapshot.review_findings_count} review finding(s).`)
144
191
  }
145
192
 
146
193
  const severityCounts = snapshot.review_severity_counts || {}
@@ -149,21 +196,62 @@ export function formatReviewTraceSummary(snapshot: ReviewTraceSnapshot): string
149
196
  .map(([severity, count]) => `${severity}:${count}`)
150
197
  .join(", ")
151
198
  if (severitySummary) {
152
- lines.push(`- Severity: ${severitySummary}`)
199
+ items.push(`Severity mix: ${severitySummary}.`)
153
200
  }
154
201
 
155
202
  if (snapshot.error) {
156
- lines.push(`- Error: ${snapshot.error}`)
203
+ items.push(`Review trace recorded an error: ${snapshot.error}`)
157
204
  }
158
205
 
159
- if (recommendations.length) {
160
- lines.push("", "### Recommendations")
161
- for (const recommendation of recommendations.slice(0, 3)) {
162
- lines.push(`- ${recommendation}`)
163
- }
206
+ return items
207
+ }
208
+
209
+ export function whyItMattersFromReviewTrace(snapshot: ReviewTraceSnapshot): string {
210
+ const severityCounts = snapshot.review_severity_counts || {}
211
+ const high = severityCounts.high || 0
212
+ const medium = severityCounts.medium || 0
213
+
214
+ if (snapshot.error) {
215
+ return "The post-commit feedback loop is incomplete, so current review guidance may be missing or stale."
216
+ }
217
+ if ((snapshot.status || "").toLowerCase() === "running") {
218
+ return "The review trace is still running, so findings and recommendations can still change."
219
+ }
220
+ if (high > 0) {
221
+ return "High-severity findings were recorded, so the commit may need immediate follow-up before merge or push."
164
222
  }
223
+ if (medium > 0) {
224
+ return "Medium-severity findings were recorded, so follow-up review is recommended before treating the commit as clean."
225
+ }
226
+ if (typeof snapshot.review_findings_count === "number" && snapshot.review_findings_count > 0) {
227
+ return "The review trace found issues worth checking, even if none were marked high severity."
228
+ }
229
+ return "No review findings were recorded, so the commit looks clean from the current trace perspective."
230
+ }
165
231
 
166
- return lines.length > 2 ? lines.join("\n") : null
232
+ export function recommendedNextActionFromReviewTrace(snapshot: ReviewTraceSnapshot): string {
233
+ const status = (snapshot.status || "").toLowerCase()
234
+ const findingsCount = snapshot.review_findings_count
235
+ const recommendations = Array.isArray(snapshot.review_recommendations)
236
+ ? snapshot.review_recommendations.filter(Boolean)
237
+ : []
238
+
239
+ if (snapshot.error) {
240
+ return "Investigate the review-trace error, then run /review once the pipeline is healthy."
241
+ }
242
+ if (status === "running") {
243
+ return "Wait for review trace completion, then inspect findings and recommendations."
244
+ }
245
+ if (status && status !== "completed") {
246
+ return "Check the latest review trace status again and rerun /review if the result is incomplete."
247
+ }
248
+ if (typeof findingsCount === "number" && findingsCount > 0) {
249
+ if (recommendations.length) {
250
+ return "Apply the top CodeGraph recommendations, then run /review to confirm the fixes."
251
+ }
252
+ return "Inspect the reported findings, fix the highest-risk issues, then run /review again."
253
+ }
254
+ return "No review findings recorded; continue with /review or push once the rest of your checks are green."
167
255
  }
168
256
 
169
257
  // File extensions recognized as source code