opencode-codegraph 0.1.6 → 0.1.8
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 +12 -0
- package/README.md +10 -3
- package/package.json +1 -1
- package/src/index.ts +29 -10
- package/src/util.ts +102 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.8 - 2026-03-20
|
|
4
|
+
|
|
5
|
+
- add normalized workflow states (`refresh_needed`, `trace_pending`, `review_required`, `ready_to_continue`) across dogfooding status and review trace flows
|
|
6
|
+
- surface a recommended command alongside next-action guidance in session-start, status, and post-commit summaries
|
|
7
|
+
- align `/review`, `/audit`, and `/update` around the same status-derived command guidance
|
|
8
|
+
|
|
9
|
+
## 0.1.7 - 2026-03-20
|
|
10
|
+
|
|
11
|
+
- add command-oriented next-step guidance (`/status`, `/update`, `/review`) to review-trace and dogfooding status flows
|
|
12
|
+
- unify `/review`, `/audit`, and `/update` around the shared `dogfood status --json` backend
|
|
13
|
+
- keep session-start and post-commit guidance aligned on the same recommended command semantics
|
|
14
|
+
|
|
3
15
|
## 0.1.6 - 2026-03-20
|
|
4
16
|
|
|
5
17
|
- add explicit pending post-commit summary when durable review trace is not yet available
|
package/README.md
CHANGED
|
@@ -39,9 +39,14 @@ Plugin injects:
|
|
|
39
39
|
|
|
40
40
|
If the message also suggests an edit intent (`refactor`, `fix`, `modify`, `update`, etc.), the plugin appends a pre-edit warning block with complexity, fan-out, dead-code, and security hints for the referenced file.
|
|
41
41
|
|
|
42
|
-
### System Prompt
|
|
43
|
-
|
|
44
|
-
Every conversation includes
|
|
42
|
+
### System Prompt
|
|
43
|
+
|
|
44
|
+
Every conversation includes:
|
|
45
|
+
|
|
46
|
+
- a project summary with file count, top complexity hotspots, and open security findings;
|
|
47
|
+
- a lightweight dogfooding status block when available, including freshness, current `HEAD`, review-trace state, and recommended next action.
|
|
48
|
+
- a recommended command (`/status`, `/update`, or `/review`) when the workflow can point to a deterministic next step.
|
|
49
|
+
- a normalized workflow state so the session can distinguish `refresh_needed`, `trace_pending`, `review_required`, and `ready_to_continue`.
|
|
45
50
|
|
|
46
51
|
### Post-Commit Updates
|
|
47
52
|
|
|
@@ -51,6 +56,8 @@ After `git commit`, the plugin triggers incremental CPG re-parsing via GoCPG and
|
|
|
51
56
|
- why it matters
|
|
52
57
|
- top recommendations
|
|
53
58
|
- one clear next action
|
|
59
|
+
- one suggested command to run next
|
|
60
|
+
- one normalized workflow state
|
|
54
61
|
|
|
55
62
|
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
63
|
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -17,13 +17,16 @@ import { CodeGraphAPI } from "./api"
|
|
|
17
17
|
import {
|
|
18
18
|
extractFileRefs,
|
|
19
19
|
fileNeedsRegistrationCheck,
|
|
20
|
+
formatDogfoodStatusSummary,
|
|
20
21
|
formatPendingReviewTraceSummary,
|
|
21
22
|
formatReviewTraceSummary,
|
|
22
23
|
getHeadCommit,
|
|
23
24
|
isGitCommit,
|
|
24
25
|
messageSuggestsEditing,
|
|
26
|
+
recommendedCommandFromReviewTrace,
|
|
25
27
|
recommendedNextActionFromReviewTrace,
|
|
26
28
|
readReviewTraceSnapshot,
|
|
29
|
+
workflowStateFromReviewTrace,
|
|
27
30
|
whatChangedFromReviewTrace,
|
|
28
31
|
whyItMattersFromReviewTrace,
|
|
29
32
|
} from "./util"
|
|
@@ -42,16 +45,26 @@ const codegraphPlugin: Plugin = async (input) => {
|
|
|
42
45
|
// -----------------------------------------------------------------
|
|
43
46
|
// 1. System prompt: inject CPG project summary
|
|
44
47
|
// -----------------------------------------------------------------
|
|
45
|
-
"experimental.chat.system.transform": async (_inp, output) => {
|
|
46
|
-
try {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
"experimental.chat.system.transform": async (_inp, output) => {
|
|
49
|
+
try {
|
|
50
|
+
const rawStatus = await $`python -m src.cli.import_commands dogfood status --json`.quiet().text()
|
|
51
|
+
const statusSummary = formatDogfoodStatusSummary(JSON.parse(rawStatus))
|
|
52
|
+
if (statusSummary) {
|
|
53
|
+
output.system.push(statusSummary)
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
// Dogfooding status unavailable — keep session startup lightweight
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const summary = await api.getProjectSummary(projectId)
|
|
61
|
+
if (summary) {
|
|
62
|
+
output.system.push(summary)
|
|
63
|
+
}
|
|
64
|
+
} catch {
|
|
65
|
+
// CodeGraph API not available — skip silently
|
|
66
|
+
}
|
|
67
|
+
},
|
|
55
68
|
|
|
56
69
|
// -----------------------------------------------------------------
|
|
57
70
|
// 2. Chat message: auto-enrich with CPG context for mentioned files
|
|
@@ -112,11 +125,15 @@ const codegraphPlugin: Plugin = async (input) => {
|
|
|
112
125
|
output.metadata = {
|
|
113
126
|
...output.metadata,
|
|
114
127
|
codegraph_review_trace_status: traceSnapshot.status || "unknown",
|
|
128
|
+
codegraph_review_trace_workflow_state:
|
|
129
|
+
traceSnapshot.workflow_state || workflowStateFromReviewTrace(traceSnapshot),
|
|
115
130
|
codegraph_review_trace_phase: traceSnapshot.phase || "unknown",
|
|
116
131
|
codegraph_review_trace_findings: traceSnapshot.review_findings_count ?? null,
|
|
117
132
|
codegraph_review_trace_recommendations:
|
|
118
133
|
traceSnapshot.review_recommendations?.slice(0, 3) || [],
|
|
119
134
|
codegraph_review_trace_next_action: recommendedNextActionFromReviewTrace(traceSnapshot),
|
|
135
|
+
codegraph_review_trace_recommended_command:
|
|
136
|
+
traceSnapshot.recommended_command || recommendedCommandFromReviewTrace(traceSnapshot),
|
|
120
137
|
codegraph_review_trace_what_changed: whatChangedFromReviewTrace(traceSnapshot),
|
|
121
138
|
codegraph_review_trace_why_it_matters: whyItMattersFromReviewTrace(traceSnapshot),
|
|
122
139
|
}
|
|
@@ -125,11 +142,13 @@ const codegraphPlugin: Plugin = async (input) => {
|
|
|
125
142
|
output.metadata = {
|
|
126
143
|
...output.metadata,
|
|
127
144
|
codegraph_review_trace_status: "pending_or_missing",
|
|
145
|
+
codegraph_review_trace_workflow_state: "trace_pending",
|
|
128
146
|
codegraph_review_trace_phase: "awaiting_trace",
|
|
129
147
|
codegraph_review_trace_findings: null,
|
|
130
148
|
codegraph_review_trace_recommendations: [],
|
|
131
149
|
codegraph_review_trace_next_action:
|
|
132
150
|
"Wait briefly for review trace completion, then run /status to check the latest result.",
|
|
151
|
+
codegraph_review_trace_recommended_command: "/status",
|
|
133
152
|
codegraph_review_trace_what_changed: [
|
|
134
153
|
`Incremental CPG update was triggered for ${commit.slice(0, 12)}.`,
|
|
135
154
|
"Durable review trace is not available yet or has not been written.",
|
package/src/util.ts
CHANGED
|
@@ -14,6 +14,22 @@ export type ReviewTraceSnapshot = {
|
|
|
14
14
|
review_severity_counts?: Record<string, number>
|
|
15
15
|
review_recommendations?: string[]
|
|
16
16
|
error?: string | null
|
|
17
|
+
workflow_state?: string
|
|
18
|
+
recommended_command?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type DogfoodStatusSnapshot = {
|
|
22
|
+
cpg_status?: {
|
|
23
|
+
is_fresh?: boolean
|
|
24
|
+
freshness_reason?: string
|
|
25
|
+
commits_behind?: number
|
|
26
|
+
db_exists?: boolean
|
|
27
|
+
}
|
|
28
|
+
head_commit?: string
|
|
29
|
+
review_trace?: ReviewTraceSnapshot | null
|
|
30
|
+
workflow_state?: string
|
|
31
|
+
recommended_next_action?: string
|
|
32
|
+
recommended_command?: string
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
/**
|
|
@@ -146,6 +162,8 @@ export function formatPendingReviewTraceSummary(commit: string | null): string {
|
|
|
146
162
|
"### What to do now",
|
|
147
163
|
"",
|
|
148
164
|
"- Wait briefly for review trace completion, then run `/status` to check the latest result.",
|
|
165
|
+
"- Suggested command: `/status`",
|
|
166
|
+
"- Workflow state: `trace_pending`",
|
|
149
167
|
].join("\n")
|
|
150
168
|
}
|
|
151
169
|
|
|
@@ -156,6 +174,8 @@ export function formatReviewTraceSummary(snapshot: ReviewTraceSnapshot): string
|
|
|
156
174
|
const whatChanged = whatChangedFromReviewTrace(snapshot)
|
|
157
175
|
const whyItMatters = whyItMattersFromReviewTrace(snapshot)
|
|
158
176
|
const nextAction = recommendedNextActionFromReviewTrace(snapshot)
|
|
177
|
+
const nextCommand = recommendedCommandFromReviewTrace(snapshot)
|
|
178
|
+
const workflowState = workflowStateFromReviewTrace(snapshot)
|
|
159
179
|
|
|
160
180
|
const lines = ["## CodeGraph Post-Commit Summary", ""]
|
|
161
181
|
|
|
@@ -176,6 +196,8 @@ export function formatReviewTraceSummary(snapshot: ReviewTraceSnapshot): string
|
|
|
176
196
|
}
|
|
177
197
|
|
|
178
198
|
lines.push("### What to do now", "", `- ${nextAction}`)
|
|
199
|
+
lines.push(`- Suggested command: \`${nextCommand}\``)
|
|
200
|
+
lines.push(`- Workflow state: \`${workflowState}\``)
|
|
179
201
|
|
|
180
202
|
return lines.join("\n")
|
|
181
203
|
}
|
|
@@ -236,12 +258,12 @@ export function recommendedNextActionFromReviewTrace(snapshot: ReviewTraceSnapsh
|
|
|
236
258
|
? snapshot.review_recommendations.filter(Boolean)
|
|
237
259
|
: []
|
|
238
260
|
|
|
261
|
+
if (workflowStateFromReviewTrace(snapshot) === "trace_pending") {
|
|
262
|
+
return "Wait for review trace completion, then inspect findings and recommendations."
|
|
263
|
+
}
|
|
239
264
|
if (snapshot.error) {
|
|
240
265
|
return "Investigate the review-trace error, then run /review once the pipeline is healthy."
|
|
241
266
|
}
|
|
242
|
-
if (status === "running") {
|
|
243
|
-
return "Wait for review trace completion, then inspect findings and recommendations."
|
|
244
|
-
}
|
|
245
267
|
if (status && status !== "completed") {
|
|
246
268
|
return "Check the latest review trace status again and rerun /review if the result is incomplete."
|
|
247
269
|
}
|
|
@@ -254,6 +276,83 @@ export function recommendedNextActionFromReviewTrace(snapshot: ReviewTraceSnapsh
|
|
|
254
276
|
return "No review findings recorded; continue with /review or push once the rest of your checks are green."
|
|
255
277
|
}
|
|
256
278
|
|
|
279
|
+
export function recommendedCommandFromReviewTrace(snapshot: ReviewTraceSnapshot): string {
|
|
280
|
+
const status = (snapshot.status || "").toLowerCase()
|
|
281
|
+
const findingsCount = snapshot.review_findings_count
|
|
282
|
+
const workflowState = workflowStateFromReviewTrace(snapshot)
|
|
283
|
+
|
|
284
|
+
if (workflowState === "trace_pending") {
|
|
285
|
+
return "/status"
|
|
286
|
+
}
|
|
287
|
+
if (snapshot.error) {
|
|
288
|
+
return "/review"
|
|
289
|
+
}
|
|
290
|
+
if (status && status !== "completed") {
|
|
291
|
+
return "/review"
|
|
292
|
+
}
|
|
293
|
+
if (typeof findingsCount === "number" && findingsCount > 0) {
|
|
294
|
+
return "/review"
|
|
295
|
+
}
|
|
296
|
+
return "/review"
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export function workflowStateFromReviewTrace(snapshot: ReviewTraceSnapshot): string {
|
|
300
|
+
const status = (snapshot.status || "").toLowerCase()
|
|
301
|
+
const findingsCount = snapshot.review_findings_count
|
|
302
|
+
|
|
303
|
+
if (snapshot.error) {
|
|
304
|
+
return "review_required"
|
|
305
|
+
}
|
|
306
|
+
if (status === "running" || status === "pending_or_missing") {
|
|
307
|
+
return "trace_pending"
|
|
308
|
+
}
|
|
309
|
+
if (status && status !== "completed") {
|
|
310
|
+
return "review_required"
|
|
311
|
+
}
|
|
312
|
+
if (typeof findingsCount === "number" && findingsCount > 0) {
|
|
313
|
+
return "review_required"
|
|
314
|
+
}
|
|
315
|
+
return "ready_to_continue"
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export function formatDogfoodStatusSummary(snapshot: DogfoodStatusSnapshot): string | null {
|
|
319
|
+
const cpg = snapshot.cpg_status || {}
|
|
320
|
+
const isFresh = cpg.is_fresh
|
|
321
|
+
const freshnessReason = cpg.freshness_reason || "unknown"
|
|
322
|
+
const commitsBehind = cpg.commits_behind
|
|
323
|
+
const headCommit = snapshot.head_commit ? snapshot.head_commit.slice(0, 12) : null
|
|
324
|
+
const reviewTrace = snapshot.review_trace || null
|
|
325
|
+
const traceStatus = reviewTrace?.status || "missing"
|
|
326
|
+
const workflowState = snapshot.workflow_state
|
|
327
|
+
const nextAction = snapshot.recommended_next_action
|
|
328
|
+
const nextCommand = (snapshot as { recommended_command?: string }).recommended_command
|
|
329
|
+
|
|
330
|
+
if (typeof isFresh === "undefined" && !headCommit && !nextAction) {
|
|
331
|
+
return null
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const lines = ["## CodeGraph Dogfooding Status", ""]
|
|
335
|
+
if (typeof isFresh !== "undefined") {
|
|
336
|
+
const freshness = isFresh ? "fresh" : "stale"
|
|
337
|
+
const behind = typeof commitsBehind === "number" ? `, commits behind: ${commitsBehind}` : ""
|
|
338
|
+
lines.push(`- CPG freshness: ${freshness} (reason: ${freshnessReason}${behind})`)
|
|
339
|
+
}
|
|
340
|
+
if (headCommit) {
|
|
341
|
+
lines.push(`- HEAD: ${headCommit}`)
|
|
342
|
+
}
|
|
343
|
+
lines.push(`- Review trace: ${traceStatus}`)
|
|
344
|
+
if (workflowState) {
|
|
345
|
+
lines.push(`- Workflow state: ${workflowState}`)
|
|
346
|
+
}
|
|
347
|
+
if (nextAction) {
|
|
348
|
+
lines.push(`- Next action: ${nextAction}`)
|
|
349
|
+
}
|
|
350
|
+
if (nextCommand) {
|
|
351
|
+
lines.push(`- Suggested command: ${nextCommand}`)
|
|
352
|
+
}
|
|
353
|
+
return lines.join("\n")
|
|
354
|
+
}
|
|
355
|
+
|
|
257
356
|
// File extensions recognized as source code
|
|
258
357
|
const SOURCE_EXTENSIONS = new Set([
|
|
259
358
|
"py",
|