opencode-codeops 2.1.0 → 2.2.0

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
@@ -2,8 +2,109 @@
2
2
 
3
3
  All notable changes to CodeOps are recorded here.
4
4
 
5
+ ## 2.2.0 — 2026-10-10
6
+
7
+ ### Fixes
8
+
9
+ - scripts: make the changelog content test survive the release fold
10
+ - docs: address the Phase 4 review findings
11
+ - tui: arm the clear guard before the identity gate
12
+ - progress: return promises from the tool and progress handlers
13
+ - progress: align schema typings with the host JsonSchema contract
14
+ - tui: scope the status RPC call to the session location
15
+ - tui: contain status transport failures in the strip
16
+ - plan: keep migration admission checkbox-based
17
+ - plan: count only id-prefixed execution tasks
18
+
19
+ ### Chores
20
+
21
+ - repo: ignore the local project-scope install
22
+ - progress: complete the final full verification
23
+ - progress: pass the Phase 3 full verification
24
+ - progress: pass the Phase 2 full verification
25
+ - plan: final verification and go/no-go record
26
+ - plan: phase 2 full verification
27
+ - plan: phase 1 full verification
28
+ - codeops: refresh the specialist check state
29
+ - codeops: record the specialist check state
30
+
31
+ ### Documentation
32
+
33
+ - roadmap: mark REQ-LIVE-TASK-PROGRESS done
34
+ - document the live sidebar and update the changelog
35
+ - exec-plan: add the fail-soft progress reporting protocol
36
+ - plan: pass the live-task-progress preflight and resolve 29 findings
37
+ - plan: add the live-task-progress plan set (gate passed)
38
+ - plan: fix the phase 3 review nits and record the review
39
+ - changelog: add the Unreleased entry for the foundation slices
40
+ - plan: record phase 2 review evidence
41
+ - agents: refresh the specialist coverage line
42
+ - agents: add the specialist coverage line to managed project facts
43
+ - changelog: add the 2.1.1 upgrade notes
44
+
45
+ ### Tests
46
+
47
+ - progress: record the ST-23 remote-client acceptance
48
+ - progress: record the ST-22 live smoke evidence
49
+ - progress: add the exec-plan protocol and docs content tests
50
+ - tui: add the sidebar view implementation tests
51
+ - progress: add the sidebar live-view specification tests
52
+ - progress: add the server wiring implementation tests
53
+ - progress: add the server wiring specification tests
54
+ - progress: add the core implementation tests
55
+ - progress: add the live progress core specification tests
56
+ - smoke: record the live TUI smoke evidence (v2.0.24)
57
+ - tui: add foundation implementation tests
58
+ - tui: add foundation spec tests (red phase)
59
+ - plan: add parser counting implementation tests
60
+ - plan: add the parser counting spec tests (red phase)
61
+
62
+ ### Features
63
+
64
+ - tui: replace the status strip with the live progress view
65
+ - progress: wire the live run state into the server plugin
66
+ - progress: add the guarded progress tool registration
67
+ - rpc: add the progress method, live events, and emit binding
68
+ - progress: add the run-state runtime and honesty display
69
+ - progress: add the live progress core contracts
70
+ - tui: add the sidebar status strip and packaging
71
+ - tui: register the codeops status RPC from the server plugin
72
+ - tui: add the shared codeops status RPC helper
73
+ - agents: add the agent-pipeline-reviewer specialist
74
+
75
+ ### CI
76
+
77
+ - test on Node 24 instead of end-of-life Node 20
78
+
79
+ ## 2.1.1 — 2026-10-09
80
+
81
+ ### Upgrade Notes
82
+
83
+ - Update and restart the OpenCode service to pick up the fix: until the 2.1.1
84
+ plugin is loaded, plugin unloads keep deleting the shared `$CODEOPS_TMPDIR`
85
+ directory of running sessions.
86
+
87
+ ### Fixes
88
+
89
+ - plugin: stop deleting the shared scratch directory on unload
90
+
91
+ ### Tests
92
+
93
+ - plugin: pin the scratch-directory lifecycle contract (red phase)
94
+
95
+ ### Documentation
96
+
97
+ - changelog: add the 2.1.0 usage notes and complete the feature
98
+
5
99
  ## 2.1.0 — 2026-10-09
6
100
 
101
+ ### Usage
102
+
103
+ - Run the `analyze-agents` skill on demand for a project-level specialist check; it records
104
+ `codeops/specialist-check.json`, and `analyze-project` reports the coverage line.
105
+ - `exec-plan` records each ruling batch in `plans/<plan>/05-findings.md`, which feeds finding-area
106
+ recurrence in the check.
107
+
7
108
  ### Documentation
8
109
 
9
110
  - readme: list the analyze-agents skill and the on-demand detection flow
package/README.md CHANGED
@@ -145,11 +145,22 @@ The plugin also warns (non-blocking) if any tool attempts to edit `codeops/.code
145
145
 
146
146
  Every session also gets a workspace-hygiene guard: the plugin exports `CODEOPS_TMPDIR`, a scratch
147
147
  directory under the OS temp directory that belongs to the running OpenCode plugin instance. Skills
148
- and agents put temporary files there and delete them when the run completes; the plugin removes the
149
- directory when it unloads and sweeps directories abandoned by interrupted runs at startup, so
150
- CodeOps does not accumulate scratch data. Because OpenCode 2 does not expose a session id to shell
151
- hooks, concurrent sessions served by one instance share this directory. The full protocol is in
152
- `_shared/workspace-hygiene.md`.
148
+ and agents put temporary files there and delete them when the run completes; the plugin sweeps
149
+ directories abandoned by interrupted runs at startup (older than seven days), so CodeOps does not
150
+ accumulate scratch data. Because OpenCode 2 does not expose a session id to shell hooks, concurrent
151
+ sessions served by one instance share this directory, and no session's scratch is deleted while
152
+ others may still use it. The full protocol is in `_shared/workspace-hygiene.md`.
153
+
154
+ ## Live task progress in the sidebar
155
+
156
+ While an `exec-plan` run is active, the sidebar shows the current run — plan, phase, task,
157
+ activity (`starting`, `implementing`, `verifying`, `reviewing`, `delegating`, `blocked`,
158
+ `waiting`, `done`), and the verified-task count — reported by the agent through the
159
+ `codeops_progress` tool. The view is intentionally honest: it always shows an "as of" time; a
160
+ run with no update for 10 minutes is marked "stale" instead of looking live; and nothing renders
161
+ when no run is active, when the host lacks the plugin APIs, or when every call fails. The
162
+ Markdown execution plan remains the single progress source of truth; the live view never gates
163
+ execution.
153
164
 
154
165
  ## Agent model configuration
155
166
 
@@ -51,7 +51,9 @@ keep scratch file names specific to the run to avoid collisions.
51
51
 
52
52
  ## Automatic safety net
53
53
 
54
- The CodeOps plugin exports `$CODEOPS_TMPDIR` for each runtime and removes that runtime's
55
- directory when the plugin unloads. At startup it also removes CodeOps temp directories older
56
- than seven days, so an interrupted run cannot leak storage forever. The safety net is a
57
- fallback, not a substitute: the run itself still performs the cleanup pass above.
54
+ The CodeOps plugin exports `$CODEOPS_TMPDIR` for each runtime. At startup it removes CodeOps
55
+ temp directories older than seven days, so an interrupted run cannot leak storage forever.
56
+ The plugin never deletes a runtime's directory while sessions may still be running — several
57
+ sessions can share one directory, so reclamation happens only through the age-based sweep.
58
+ The safety net is a fallback, not a substitute: the run itself still performs the cleanup
59
+ pass above.
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Type declarations for the live progress core.
3
+ *
4
+ * The module is plain JavaScript so `node --test` can exercise it directly;
5
+ * these declarations give the TypeScript plugin entries typed access.
6
+ */
7
+
8
+ /** The eight activity states a run can report. */
9
+ export type CodeOpsActivity =
10
+ | "starting"
11
+ | "implementing"
12
+ | "verifying"
13
+ | "reviewing"
14
+ | "delegating"
15
+ | "waiting"
16
+ | "blocked"
17
+ | "done"
18
+
19
+ /** A progress report as sent by an agent through the tool. */
20
+ export interface CodeOpsProgressReport {
21
+ readonly plan: string
22
+ readonly activity: CodeOpsActivity
23
+ readonly phase?: string
24
+ readonly task?: string
25
+ readonly detail?: string
26
+ readonly verified?: number
27
+ readonly total?: number
28
+ }
29
+
30
+ /**
31
+ * A report after normalization.
32
+ *
33
+ * Only fields present in the input appear; optional text fields may be `null`
34
+ * when the input carried a whitespace-only string.
35
+ */
36
+ export interface NormalizedProgressReport {
37
+ readonly plan: string
38
+ readonly activity: CodeOpsActivity
39
+ readonly phase?: string | null
40
+ readonly task?: string | null
41
+ readonly detail?: string | null
42
+ readonly verified?: number
43
+ readonly total?: number
44
+ }
45
+
46
+ /** One complete run snapshot: the `progress` payload and `updated` event data. */
47
+ export interface CodeOpsRunState {
48
+ readonly plan: string
49
+ readonly phase: string | null
50
+ readonly task: string | null
51
+ readonly detail: string | null
52
+ readonly activity: CodeOpsActivity
53
+ readonly verified: number
54
+ readonly total: number | null
55
+ readonly startedAt: number
56
+ readonly updatedAt: number
57
+ readonly sessionID: string
58
+ }
59
+
60
+ /** The cleared-event payload: the cleared run's identity and clear time. */
61
+ export interface CodeOpsRunCleared {
62
+ readonly plan: string
63
+ readonly sessionID: string
64
+ readonly clearedAt: number
65
+ }
66
+
67
+ /** JSON-Schema shape of the progress tool's input. */
68
+ export type CodeOpsProgressReportSchema = {
69
+ readonly type: "object"
70
+ readonly additionalProperties: false
71
+ readonly required: readonly ["plan", "activity"]
72
+ readonly properties: {
73
+ readonly plan: { readonly type: "string" }
74
+ readonly phase: { readonly type: "string" }
75
+ readonly task: { readonly type: "string" }
76
+ readonly activity: { readonly type: "string"; readonly enum: readonly CodeOpsActivity[] }
77
+ readonly detail: { readonly type: "string" }
78
+ readonly verified: { readonly type: "integer"; readonly minimum: 0 }
79
+ readonly total: { readonly type: "integer"; readonly minimum: 0 }
80
+ }
81
+ }
82
+
83
+ /** JSON-Schema shape of the progress tool's acknowledgement. */
84
+ export type CodeOpsProgressOutputSchema = {
85
+ readonly type: "object"
86
+ readonly additionalProperties: false
87
+ readonly required: readonly ["ok"]
88
+ readonly properties: { readonly ok: { readonly type: "boolean" } }
89
+ }
90
+
91
+ /** JSON-Schema shape of a complete run snapshot. */
92
+ export type CodeOpsRunStateSchema = {
93
+ readonly type: "object"
94
+ readonly additionalProperties: false
95
+ readonly required: readonly [
96
+ "plan",
97
+ "phase",
98
+ "task",
99
+ "activity",
100
+ "detail",
101
+ "verified",
102
+ "total",
103
+ "startedAt",
104
+ "updatedAt",
105
+ "sessionID",
106
+ ]
107
+ readonly properties: {
108
+ readonly plan: { readonly type: "string" }
109
+ readonly phase: { readonly type: readonly ["string", "null"] }
110
+ readonly task: { readonly type: readonly ["string", "null"] }
111
+ readonly detail: { readonly type: readonly ["string", "null"] }
112
+ readonly activity: { readonly type: "string"; readonly enum: readonly CodeOpsActivity[] }
113
+ readonly verified: { readonly type: "integer"; readonly minimum: 0 }
114
+ readonly total: { readonly type: readonly ["integer", "null"]; readonly minimum: 0 }
115
+ readonly startedAt: { readonly type: "integer"; readonly minimum: 0 }
116
+ readonly updatedAt: { readonly type: "integer"; readonly minimum: 0 }
117
+ readonly sessionID: { readonly type: "string" }
118
+ }
119
+ }
120
+
121
+ /** JSON-Schema shape of the cleared-event payload. */
122
+ export type CodeOpsRunClearedSchema = {
123
+ readonly type: "object"
124
+ readonly additionalProperties: false
125
+ readonly required: readonly ["plan", "sessionID", "clearedAt"]
126
+ readonly properties: {
127
+ readonly plan: { readonly type: "string" }
128
+ readonly sessionID: { readonly type: "string" }
129
+ readonly clearedAt: { readonly type: "integer"; readonly minimum: 0 }
130
+ }
131
+ }
132
+
133
+ /** The name of the agent-callable tool that reports task progress. */
134
+ export declare const CODE_OPS_TOOL_NAME: "codeops_progress"
135
+
136
+ /** The description of the progress tool, shown in the host's tool list. */
137
+ export declare const CODE_OPS_TOOL_DESCRIPTION: string
138
+
139
+ /** Longest accepted free-text value; longer values are truncated. */
140
+ export declare const CODE_OPS_STRING_CAP: 200
141
+
142
+ /** Largest accepted `verified`/`total` count; larger values are clamped. */
143
+ export declare const CODE_OPS_COUNT_MAX: 1000000
144
+
145
+ /** Age in milliseconds at which a run is shown as stale (10 minutes). */
146
+ export declare const CODE_OPS_STALE_MS: 600000
147
+
148
+ /** The input schema of the progress tool. */
149
+ export declare const ProgressReportSchema: CodeOpsProgressReportSchema
150
+
151
+ /** The output schema of the progress tool. */
152
+ export declare const ProgressOutputSchema: CodeOpsProgressOutputSchema
153
+
154
+ /** The schema of one complete run snapshot. */
155
+ export declare const RunStateSchema: CodeOpsRunStateSchema
156
+
157
+ /** The schema of the cleared-event payload. */
158
+ export declare const RunClearedSchema: CodeOpsRunClearedSchema
159
+
160
+ /** Validate an unknown value as a progress report. */
161
+ export declare function isCodeOpsProgressReport(value: unknown): value is CodeOpsProgressReport
162
+
163
+ /** Validate an unknown value as a complete run snapshot. */
164
+ export declare function isCodeOpsRunState(value: unknown): value is CodeOpsRunState
165
+
166
+ /**
167
+ * Accept a validated snapshot from an `updated` event scoped to the viewer's
168
+ * directory; `null` when the event is foreign or its data is invalid.
169
+ */
170
+ export declare function acceptRunUpdate(event: unknown, directory: string): CodeOpsRunState | null
171
+
172
+ /**
173
+ * Accept a validated cleared payload from a `cleared` event scoped to the
174
+ * viewer's directory; `null` when the event is foreign or its data is invalid.
175
+ */
176
+ export declare function acceptRunCleared(
177
+ event: unknown,
178
+ directory: string
179
+ ): CodeOpsRunCleared | null
180
+
181
+ /** Normalize an unknown report; `null` means rejection. */
182
+ export declare function normalizeProgressReport(value: unknown): NormalizedProgressReport | null
183
+
184
+ /** Emit binding accepted by {@link CodeOpsProgressRuntime.bindEmit}. */
185
+ export type CodeOpsEmit = (name: string, payload: unknown) => void | Promise<void>
186
+
187
+ /** The in-memory run-state runtime shared by the tool handler and the RPC. */
188
+ export interface CodeOpsProgressRuntime {
189
+ /** Normalize and apply a report; `null` means the report was rejected. */
190
+ report(input: unknown, sessionID: string, nowMs?: number): CodeOpsRunState | null
191
+ /** The current snapshot, or `null` when no run is active. */
192
+ snapshot(): CodeOpsRunState | null
193
+ /**
194
+ * Clear the active run when `sessionID` is the last reporter; returns the
195
+ * cleared identity, or `null` when a different session owns the run.
196
+ */
197
+ clearSession(sessionID: string): CodeOpsRunCleared | null
198
+ /** Bind the event emitter; a throwing or rejecting emitter is swallowed. */
199
+ bindEmit(emit: CodeOpsEmit): void
200
+ }
201
+
202
+ /** Create one in-memory run-state runtime. */
203
+ export declare function createCodeOpsProgress(): CodeOpsProgressRuntime
204
+
205
+ /**
206
+ * Pick the newer of two snapshots; an equal `updatedAt` lets `incoming` win,
207
+ * so the view converges on the latest delivery.
208
+ */
209
+ export declare function mergeRunState(
210
+ current: CodeOpsRunState | null,
211
+ incoming: CodeOpsRunState
212
+ ): CodeOpsRunState
213
+
214
+ /** Test whether a run has not been updated for ten minutes. */
215
+ export declare function isRunStale(snapshot: Pick<CodeOpsRunState, "updatedAt">, nowMs: number): boolean
216
+
217
+ /** The rendered sidebar text for a run snapshot. */
218
+ export interface CodeOpsRunDisplay {
219
+ /** The three display lines (fewer segments when values are unknown). */
220
+ readonly lines: string[]
221
+ /** Whether the last update is ten minutes old or older. */
222
+ readonly stale: boolean
223
+ }
224
+
225
+ /** Render the visible sidebar lines for a run snapshot. */
226
+ export declare function describeRun(snapshot: CodeOpsRunState, nowMs: number): CodeOpsRunDisplay
227
+
228
+ /**
229
+ * Register the agent-callable progress tool on a plugin context,
230
+ * feature-detected and never-throwing; `false` when the host lacks the tool
231
+ * API or the registration failed.
232
+ */
233
+ export declare function registerCodeOpsProgressTool(
234
+ ctx: unknown,
235
+ runtime: CodeOpsProgressRuntime
236
+ ): Promise<boolean>