opencode-plugin-flow 6.3.0 → 6.4.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 +52 -2
- package/README.md +25 -17
- package/dist/index.js +91 -43
- package/dist/index.js.map +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,56 @@ One short entry per release, written for users deciding whether to upgrade.
|
|
|
6
6
|
|
|
7
7
|
No changes yet.
|
|
8
8
|
|
|
9
|
+
## [6.4.0] - 2026-07-21
|
|
10
|
+
|
|
11
|
+
Continuous-flow lore keeps an authorized goal inside Flow while preserving the
|
|
12
|
+
small, single-run architecture:
|
|
13
|
+
|
|
14
|
+
- `/flow-auto` is the normal end-to-end driver. An active session remains
|
|
15
|
+
authoritative until explicit completed, deferred, or abandoned closure, and
|
|
16
|
+
existing implementation authority carries across plan approval, feature
|
|
17
|
+
outcomes, qualifying worker waves, and in-scope failed-review repair.
|
|
18
|
+
- Direct `/flow-run` remains a one-feature advanced or recovery control. Work
|
|
19
|
+
stays inside the active feature, serial execution remains the default, and
|
|
20
|
+
bounded parallel waves still add no scheduler, durable wave state, telemetry,
|
|
21
|
+
or concurrent active features.
|
|
22
|
+
- Reviewers now receive every applicable passing validation while final review
|
|
23
|
+
still requires a broad gate. Reviewer guidance explicitly permits
|
|
24
|
+
workspace-local non-shell inspection, removing an ambiguity that could block
|
|
25
|
+
valid reviews.
|
|
26
|
+
- Deterministic coverage now exercises concurrent completion replay,
|
|
27
|
+
configuration collisions and warnings, the documented 1-through-1000 review
|
|
28
|
+
step range, temporary-workspace cleanup, and release-version derivation.
|
|
29
|
+
- Real-provider evidence completed an overlapping two-worker wave, a serial
|
|
30
|
+
integration feature, failed-review reset and repair, and ten ordinary
|
|
31
|
+
`/flow-auto` sessions through explicit closure.
|
|
32
|
+
|
|
33
|
+
Install or update:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
opencode plugin opencode-plugin-flow@6.4.0 --global --force
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## [6.3.1] - 2026-07-21
|
|
40
|
+
|
|
41
|
+
Read-only retry lore closes the recovery and documentation gaps in 6.3.0:
|
|
42
|
+
|
|
43
|
+
- While Session v5 remains active, every caller with tool access now receives an
|
|
44
|
+
exact accepted completion through the read-only replay path before a new
|
|
45
|
+
reviewer submission is considered. Reviewer retries no longer cancel
|
|
46
|
+
validation capture or write session state.
|
|
47
|
+
- Replay documentation now states the active Session v5 boundary, and release
|
|
48
|
+
language accurately describes secret avoidance as manager guidance rather
|
|
49
|
+
than runtime filtering or redaction.
|
|
50
|
+
- The documentation contract keeps the rolling `Unreleased` changelog heading
|
|
51
|
+
without requiring its contents to remain `No changes yet.`
|
|
52
|
+
|
|
53
|
+
Install or update:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
opencode plugin opencode-plugin-flow@6.3.1 --global --force
|
|
57
|
+
```
|
|
58
|
+
|
|
9
59
|
## [6.3.0] - 2026-07-21
|
|
10
60
|
|
|
11
61
|
Reviewer-owned submission lore strengthens independent review without turning
|
|
@@ -20,8 +70,8 @@ Flow back into a heavy orchestration framework:
|
|
|
20
70
|
revalidation, and fingerprint failures fail closed with repair guidance.
|
|
21
71
|
- Final reviewers receive the approved plan targets and validation intent,
|
|
22
72
|
completed feature IDs, and only assignment-linked evidence. Broad validation
|
|
23
|
-
is treated as a coverage claim;
|
|
24
|
-
output is reduced to completeness plus a digest.
|
|
73
|
+
is treated as a coverage claim; manager guidance warns against putting secrets
|
|
74
|
+
in durable commands, and raw output is reduced to completeness plus a digest.
|
|
25
75
|
- Closed-world permission tests and the pinned OpenCode host smoke cover every
|
|
26
76
|
registered Flow tool. Documentation distinguishes lifecycle mutation from
|
|
27
77
|
fail-closed quarantine maintenance.
|
package/README.md
CHANGED
|
@@ -11,16 +11,20 @@ Flow keeps one durable active feature run at a time. When implementation divides
|
|
|
11
11
|
cleanly, the manager may ask a small host-native worker cohort to contribute in
|
|
12
12
|
parallel before it validates and reviews the combined result.
|
|
13
13
|
|
|
14
|
+
Once a Flow session starts, it remains the workflow for that goal until Flow
|
|
15
|
+
records completed, deferred, or abandoned closure. It never silently falls back
|
|
16
|
+
to ordinary non-Flow coding.
|
|
17
|
+
|
|
14
18
|
## Install
|
|
15
19
|
|
|
16
20
|
Install the exact npm release through OpenCode:
|
|
17
21
|
|
|
18
22
|
```bash
|
|
19
|
-
opencode plugin opencode-plugin-flow@6.
|
|
23
|
+
opencode plugin opencode-plugin-flow@6.4.0 --global --force
|
|
20
24
|
```
|
|
21
25
|
|
|
22
26
|
Omit `--global` for project scope. Exact version pins do not update
|
|
23
|
-
automatically. To update, replace `6.
|
|
27
|
+
automatically. To update, replace `6.4.0` with the new release and rerun the
|
|
24
28
|
command.
|
|
25
29
|
|
|
26
30
|
Before upgrading from Flow v5 or earlier, finish or explicitly close any active
|
|
@@ -32,7 +36,7 @@ The equivalent manual project configuration is:
|
|
|
32
36
|
```json
|
|
33
37
|
{
|
|
34
38
|
"$schema": "https://opencode.ai/config.json",
|
|
35
|
-
"plugin": ["opencode-plugin-flow@6.
|
|
39
|
+
"plugin": ["opencode-plugin-flow@6.4.0"]
|
|
36
40
|
}
|
|
37
41
|
```
|
|
38
42
|
|
|
@@ -53,9 +57,11 @@ Start a complete workflow:
|
|
|
53
57
|
Flow inspects the worktree, proposes a feature plan, and asks for approval
|
|
54
58
|
unless your request already authorized implementation. It then runs one
|
|
55
59
|
runnable feature at a time, validates the actual workspace, obtains an
|
|
56
|
-
independent review, and repeats until it can close the session.
|
|
60
|
+
independent review, and repeats until it can close the session. Existing
|
|
61
|
+
implementation authority carries across approval, feature outcomes, and
|
|
62
|
+
in-scope failed-review repairs; Flow does not ask for the same permission again.
|
|
57
63
|
|
|
58
|
-
For
|
|
64
|
+
For plan-only or advanced use, plan first:
|
|
59
65
|
|
|
60
66
|
```text
|
|
61
67
|
/flow-plan add rate limiting to the public API
|
|
@@ -63,9 +69,10 @@ For more control, plan first:
|
|
|
63
69
|
|
|
64
70
|
Review the proposed plan and approve it conversationally. `/flow-plan` does not
|
|
65
71
|
silently grant permission to implement, commit, push, or publish. After
|
|
66
|
-
approval,
|
|
72
|
+
approval of a plan-only request, `/flow-run` can run or recover one feature.
|
|
67
73
|
|
|
68
|
-
|
|
74
|
+
`/flow-run` and `/flow-status` are advanced/recovery controls. At any point,
|
|
75
|
+
`/flow-status` reports the durable state and next action.
|
|
69
76
|
|
|
70
77
|
## How Flow works
|
|
71
78
|
|
|
@@ -86,7 +93,8 @@ action after a restart or context change.
|
|
|
86
93
|
Parallel contribution is optional and local to one active feature. The manager
|
|
87
94
|
may launch two or three `flow-worker` instances only for exact,
|
|
88
95
|
non-overlapping slices, then inspect and integrate their work. At most one
|
|
89
|
-
targeted follow-up wave may address a concrete gap.
|
|
96
|
+
targeted follow-up wave may address a concrete gap. Once implementation is
|
|
97
|
+
authorized, a qualifying wave needs no separate approval.
|
|
90
98
|
|
|
91
99
|
Workers cannot delegate, call Flow lifecycle tools, or approve their own work.
|
|
92
100
|
Flow persists no wave state: the manager remains responsible for the combined
|
|
@@ -97,20 +105,20 @@ integration-heavy tasks stay serial.
|
|
|
97
105
|
|
|
98
106
|
| Command | Purpose |
|
|
99
107
|
| --- | --- |
|
|
100
|
-
| `/flow-auto <goal>` |
|
|
101
|
-
| `/flow-plan <goal>` |
|
|
102
|
-
| `/flow-run` |
|
|
108
|
+
| `/flow-auto <goal>` | Normal end-to-end driver for the authorized lifecycle; stop after planning if implementation was not authorized. |
|
|
109
|
+
| `/flow-plan <goal>` | Plan-only/advanced creation, revision, and approval. |
|
|
110
|
+
| `/flow-run` | Advanced/recovery execution of one approved feature. |
|
|
103
111
|
| `/flow-review` | Internal/recovery dispatch for a runtime-created reviewer assignment. |
|
|
104
|
-
| `/flow-status` |
|
|
112
|
+
| `/flow-status` | Advanced/recovery inspection of the active session and next action. |
|
|
105
113
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
but it is not an ordinary starting point.
|
|
114
|
+
Use `/flow-auto` for the ordinary end-to-end workflow. The other commands expose
|
|
115
|
+
plan-only, advanced, internal, or recovery controls.
|
|
109
116
|
|
|
110
117
|
## Recovery
|
|
111
118
|
|
|
112
|
-
Start with `/flow-status`; its next action is authoritative
|
|
113
|
-
|
|
119
|
+
Start with `/flow-status`; its next action is authoritative workflow state, not
|
|
120
|
+
permission to exceed the user's authority. Do not hand-edit `.flow/session.json`
|
|
121
|
+
to bypass a gate. If validation, review, locking,
|
|
114
122
|
fingerprinting, or archive publication fails, follow the focused steps in
|
|
115
123
|
[troubleshooting](docs/troubleshooting.md).
|
|
116
124
|
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// skills/flow/SKILL.md
|
|
2
2
|
var SKILL_default = `---
|
|
3
3
|
name: flow
|
|
4
|
-
description:
|
|
4
|
+
description: Drive a Flow goal from planning through implementation, validation, independent review, and explicit closure. Use flow-auto as the normal end-to-end interface; use flow-plan for plan-only work and flow-run or flow-status for advanced recovery.
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Flow
|
|
8
8
|
|
|
9
|
-
Flow is a small state ledger around
|
|
9
|
+
Flow is a small state ledger around coding work. An active Flow session is
|
|
10
|
+
authoritative for its goal until completed, deferred, or abandoned closure; do
|
|
11
|
+
not silently fall back to ordinary non-Flow coding. The root manager owns
|
|
10
12
|
the session, integration, validation, review dispatch, reset, closure, and every
|
|
11
13
|
lifecycle mutation except review submission. Bounded \`flow-worker\`
|
|
12
14
|
instances may contribute disjoint work inside the active feature. The reserved
|
|
@@ -17,7 +19,9 @@ lifecycle mutation.
|
|
|
17
19
|
## Route from status
|
|
18
20
|
|
|
19
21
|
1. Call \`flow_status { request: { view: "compact" } }\` first. Trust its
|
|
20
|
-
projection over conversation memory.
|
|
22
|
+
projection over conversation memory. Treat \`nextAction\` as authoritative
|
|
23
|
+
workflow state, not permission to exceed or a reason to discard existing
|
|
24
|
+
user authority.
|
|
21
25
|
2. If there is no session or the plan is still a draft, call
|
|
22
26
|
\`flow_guidance { id: "flow-plan" }\` and follow that contract. Stop after
|
|
23
27
|
planning when the user asked for a plan only.
|
|
@@ -25,8 +29,15 @@ lifecycle mutation.
|
|
|
25
29
|
\`flow_guidance { id: "flow-run" }\` and follow that contract for exactly that
|
|
26
30
|
feature.
|
|
27
31
|
4. After the feature outcome, read compact status again. Start the next ready
|
|
28
|
-
feature, report
|
|
29
|
-
\`flow_session_close\` request.
|
|
32
|
+
feature, repair an in-scope failed review, report a real blocker, or close a
|
|
33
|
+
completed session with one \`flow_session_close\` request.
|
|
34
|
+
|
|
35
|
+
Within existing implementation authority, continue after approval, every
|
|
36
|
+
feature outcome, and an in-scope failed-review reset and repair without asking
|
|
37
|
+
again. Pause only for a material product or scope choice, missing authority for
|
|
38
|
+
an external Git or release action, a hard operational failure, or the user's
|
|
39
|
+
explicit selection of deferred or abandoned closure. Only the user may choose
|
|
40
|
+
either non-completed closure kind.
|
|
30
41
|
|
|
31
42
|
Core contracts are bundled in the plugin; load them through \`flow_guidance\` and
|
|
32
43
|
do not depend on native skill discovery. If a required Flow tool is unavailable,
|
|
@@ -34,8 +45,10 @@ report that the plugin is not fully loaded instead of simulating state changes.
|
|
|
34
45
|
|
|
35
46
|
## Invariants
|
|
36
47
|
|
|
37
|
-
- Approved plans do not change.
|
|
38
|
-
|
|
48
|
+
- Approved plans do not change. If implementation requires material scope
|
|
49
|
+
outside the plan, stop editing. Finish the approved plan or have the user
|
|
50
|
+
explicitly choose deferred or abandoned closure before starting a new plan;
|
|
51
|
+
do not replan in place.
|
|
39
52
|
- Only one durable feature run is active at a time. Conversation-local worker
|
|
40
53
|
waves do not create additional runs or Flow state.
|
|
41
54
|
- Work stays inside the active feature and preserves unrelated user changes.
|
|
@@ -141,14 +154,15 @@ description: Independently review one runtime-owned Flow assignment. Reserved fo
|
|
|
141
154
|
# Flow Review
|
|
142
155
|
|
|
143
156
|
You are the independent \`flow-reviewer\`. Review the assigned work; do not fix
|
|
144
|
-
it.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
157
|
+
it. Use workspace-local, non-shell inspection tools to read relevant files and
|
|
158
|
+
supplied evidence, but do not edit files, read outside the workspace, run
|
|
159
|
+
commands, or launch workers. Among Flow lifecycle tools, call only \`flow_status\`
|
|
160
|
+
to read this assignment and \`flow_feature_complete\` to submit its exact result.
|
|
161
|
+
The latter is your sole lifecycle mutation.
|
|
148
162
|
|
|
149
163
|
## Recover the assignment
|
|
150
164
|
|
|
151
|
-
When given an assignment id, call
|
|
165
|
+
When given an assignment id, first call
|
|
152
166
|
\`flow_status { request: { view: "reviewer", assignmentId: "..." } }\`. Use its
|
|
153
167
|
bounded packet, assignment-linked validations, approved-plan context, and
|
|
154
168
|
completed feature IDs instead of reconstructing feature, source,
|
|
@@ -231,7 +245,7 @@ a reason to lower the bar.
|
|
|
231
245
|
// skills/flow-run/SKILL.md
|
|
232
246
|
var SKILL_default4 = `---
|
|
233
247
|
name: flow-run
|
|
234
|
-
description: Implement, validate, independently review, and record one approved Flow feature. Use
|
|
248
|
+
description: Implement, validate, independently review, and record one approved Flow feature. Use after plan approval as an advanced or recovery control; flow-auto is the normal end-to-end driver.
|
|
235
249
|
---
|
|
236
250
|
|
|
237
251
|
# Flow Run
|
|
@@ -244,17 +258,21 @@ independent review and submits its own result.
|
|
|
244
258
|
|
|
245
259
|
## Start and scope
|
|
246
260
|
|
|
247
|
-
1. Call \`flow_status { request: { view: "compact" } }\` first.
|
|
261
|
+
1. Call \`flow_status { request: { view: "compact" } }\` first. Treat
|
|
262
|
+
\`nextAction\` as authoritative workflow state, not as a permission grant.
|
|
248
263
|
2. Call \`flow_run_start\` when a ready feature is not already running.
|
|
249
264
|
3. Read \`flow_status { request: { view: "execution" } }\` and use that
|
|
250
265
|
projection as the active scope and source of revision guards.
|
|
251
266
|
4. Read the feature summary, targets, validation, dependencies, requirements,
|
|
252
267
|
and decisions before editing.
|
|
253
268
|
|
|
254
|
-
Preserve unrelated worktree changes
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
269
|
+
Preserve unrelated worktree changes and stay inside the active feature. Leave
|
|
270
|
+
changes owned by another planned feature for that feature. If implementation
|
|
271
|
+
needs material scope outside the approved plan, stop editing. Finish the
|
|
272
|
+
approved plan or have the user explicitly choose deferred or abandoned closure
|
|
273
|
+
before starting a new plan; never replan the active approved session in place.
|
|
274
|
+
Use \`flow_feature_reset\` when a wrong design or invalid assumption requires a
|
|
275
|
+
fresh run within the active feature; do not layer a retry onto a bad execution.
|
|
258
276
|
|
|
259
277
|
## Implement
|
|
260
278
|
|
|
@@ -268,8 +286,10 @@ that separate action.
|
|
|
268
286
|
|
|
269
287
|
## Bounded worker waves
|
|
270
288
|
|
|
271
|
-
Work serially by default.
|
|
272
|
-
|
|
289
|
+
Work serially by default. Existing implementation authority covers a qualifying
|
|
290
|
+
worker wave; do not ask for separate approval. After manager orientation, fan
|
|
291
|
+
out only when two or three genuinely independent, non-overlapping slices can be
|
|
292
|
+
named and parallel execution has clear benefit. Run one cohort of two or three
|
|
273
293
|
\`flow-worker\` instances at a time. Issue every cohort Task call in the same
|
|
274
294
|
assistant tool-use turn before consuming any result. If the host or model
|
|
275
295
|
serializes those calls, treat and report that execution as serial instead of
|
|
@@ -320,6 +340,12 @@ secrets. Raw output is deliberately neither persisted nor projected: the
|
|
|
320
340
|
durable evidence is the command, exit code, output completeness, and output
|
|
321
341
|
digest, while the manager must inspect the live output.
|
|
322
342
|
|
|
343
|
+
Every host-observed validation advances the session revision through the
|
|
344
|
+
after-hook. Immediately refresh
|
|
345
|
+
\`flow_status { request: { view: "compact" } }\` after the command and before the
|
|
346
|
+
next \`flow_validation_start\` or \`flow_review_start\` mutation; the revision used
|
|
347
|
+
to arm the command is stale.
|
|
348
|
+
|
|
323
349
|
Use focused validation for ordinary features. For the final feature, run the
|
|
324
350
|
repository's broad applicable gate after the last relevant edit. A source edit
|
|
325
351
|
invalidates earlier applicability. Failed or unavailable checks are blockers,
|
|
@@ -352,11 +378,14 @@ source-stale assignment; start a fresh run and repeat full validation and
|
|
|
352
378
|
review. Never fabricate a verdict. A submitted pass completes the feature; a
|
|
353
379
|
submitted blocking finding records a blocked outcome.
|
|
354
380
|
|
|
355
|
-
|
|
356
|
-
repeat full validation and full
|
|
381
|
+
When implementation is already authorized, an in-scope failed review needs no
|
|
382
|
+
new permission: reset the feature, fix it, and repeat full validation and full
|
|
383
|
+
review in a fresh run.
|
|
357
384
|
|
|
358
|
-
Read compact status after every recorded outcome.
|
|
359
|
-
|
|
385
|
+
Read compact status after every recorded outcome. When invoked directly through
|
|
386
|
+
\`/flow-run\`, report that one feature's outcome and \`nextAction\`, then stop. When
|
|
387
|
+
the active driver is \`/flow-auto\`, return to its loop so it can start the next
|
|
388
|
+
feature, report a blocker, or close the completed session.
|
|
360
389
|
`;
|
|
361
390
|
|
|
362
391
|
// src/guidance/ids.ts
|
|
@@ -525,17 +554,17 @@ var FLOW_CORE_AGENTS = {
|
|
|
525
554
|
};
|
|
526
555
|
var FLOW_CORE_COMMANDS = {
|
|
527
556
|
"flow-auto": {
|
|
528
|
-
description: "Drive
|
|
557
|
+
description: "Drive one authorized Flow goal end to end",
|
|
529
558
|
subtask: false,
|
|
530
559
|
template: compileFlowPromptSurface("flow-auto")
|
|
531
560
|
},
|
|
532
561
|
"flow-plan": {
|
|
533
|
-
description: "
|
|
562
|
+
description: "Plan-only or advanced Flow planning",
|
|
534
563
|
subtask: false,
|
|
535
564
|
template: compileFlowPromptSurface("flow-plan")
|
|
536
565
|
},
|
|
537
566
|
"flow-run": {
|
|
538
|
-
description: "
|
|
567
|
+
description: "Advanced or recovery execution of one Flow feature",
|
|
539
568
|
subtask: false,
|
|
540
569
|
template: compileFlowPromptSurface("flow-run")
|
|
541
570
|
},
|
|
@@ -546,7 +575,7 @@ var FLOW_CORE_COMMANDS = {
|
|
|
546
575
|
template: compileFlowPromptSurface("flow-review")
|
|
547
576
|
},
|
|
548
577
|
"flow-status": {
|
|
549
|
-
description: "
|
|
578
|
+
description: "Advanced or recovery inspection of Flow state",
|
|
550
579
|
subtask: false,
|
|
551
580
|
template: compileFlowPromptSurface("flow-status")
|
|
552
581
|
}
|
|
@@ -559,7 +588,7 @@ function reviewerSteps(env, onWarning) {
|
|
|
559
588
|
const raw = envValue(env, "OPENCODE_FLOW_REVIEWER_STEPS");
|
|
560
589
|
if (!raw)
|
|
561
590
|
return;
|
|
562
|
-
if (!/^[1-9][0-9]
|
|
591
|
+
if (!/^[1-9][0-9]*$/.test(raw) || Number(raw) > 1000) {
|
|
563
592
|
onWarning?.("OPENCODE_FLOW_REVIEWER_STEPS must be an integer from 1 through 1000; ignoring it.");
|
|
564
593
|
return;
|
|
565
594
|
}
|
|
@@ -1087,8 +1116,9 @@ function startReview(session, input, environment) {
|
|
|
1087
1116
|
fail("Reset the feature before starting another full review.");
|
|
1088
1117
|
}
|
|
1089
1118
|
const kind = isFinalFeatureRun(session, run) ? "final" : "feature";
|
|
1090
|
-
const applicable = run.validations.filter((validation) => validation.exitCode === 0 && validation.outputComplete && validation.sourceDigest === input.sourceDigest
|
|
1091
|
-
|
|
1119
|
+
const applicable = run.validations.filter((validation) => validation.exitCode === 0 && validation.outputComplete && validation.sourceDigest === input.sourceDigest);
|
|
1120
|
+
const hasRequiredValidation = kind === "feature" ? applicable.length > 0 : applicable.some((validation) => validation.scope === "broad");
|
|
1121
|
+
if (!hasRequiredValidation) {
|
|
1092
1122
|
fail(kind === "final" ? "Final review requires passing broad validation for the current workspace content." : "Review requires passing validation for the current workspace content.");
|
|
1093
1123
|
}
|
|
1094
1124
|
const assignmentId = environment.newId("review");
|
|
@@ -2672,6 +2702,17 @@ function featureCompleteResponse(session, request, run, replayed) {
|
|
|
2672
2702
|
projection: compactProjection(session)
|
|
2673
2703
|
});
|
|
2674
2704
|
}
|
|
2705
|
+
function exactFeatureCompleteReplay(session, request) {
|
|
2706
|
+
const priorOperation = session.operations.find((operation) => operation.id === request.operationId);
|
|
2707
|
+
if (priorOperation?.kind !== "feature-complete" || priorOperation.inputDigest !== operationInputDigest(request)) {
|
|
2708
|
+
return null;
|
|
2709
|
+
}
|
|
2710
|
+
const result = completeFeature(session, request);
|
|
2711
|
+
if (!result.replayed) {
|
|
2712
|
+
throw new Error("Expected an exact feature-completion replay.");
|
|
2713
|
+
}
|
|
2714
|
+
return { session: result.session, run: result.value };
|
|
2715
|
+
}
|
|
2675
2716
|
async function loadExactArchivedClose(transaction, request) {
|
|
2676
2717
|
const archived = await transaction.loadArchive(request.sessionId);
|
|
2677
2718
|
const operation = archived?.operations.find((item) => item.id === request.operationId);
|
|
@@ -2856,10 +2897,21 @@ function createFlowService(repository, environment) {
|
|
|
2856
2897
|
async featureComplete(input) {
|
|
2857
2898
|
try {
|
|
2858
2899
|
const request = FeatureCompleteInputSchema.parse(input).request;
|
|
2900
|
+
const current = await repository.read();
|
|
2901
|
+
if (current) {
|
|
2902
|
+
const replay = exactFeatureCompleteReplay(current, request);
|
|
2903
|
+
if (replay) {
|
|
2904
|
+
return featureCompleteResponse(replay.session, request, replay.run, true);
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2859
2907
|
return await repository.transact(async (transaction) => {
|
|
2860
2908
|
const session = await transaction.load();
|
|
2861
2909
|
if (!session)
|
|
2862
2910
|
throw new Error("No active Flow session exists.");
|
|
2911
|
+
const racedReplay = exactFeatureCompleteReplay(session, request);
|
|
2912
|
+
if (racedReplay) {
|
|
2913
|
+
return featureCompleteResponse(racedReplay.session, request, racedReplay.run, true);
|
|
2914
|
+
}
|
|
2863
2915
|
const priorOperation = session.operations.find((operation) => operation.id === request.operationId);
|
|
2864
2916
|
if (!priorOperation) {
|
|
2865
2917
|
const assignment = session.runs.flatMap((run) => run.reviews).find((review) => review.id === request.assignmentId);
|
|
@@ -2883,15 +2935,11 @@ function createFlowService(repository, environment) {
|
|
|
2883
2935
|
const session = await repository.read();
|
|
2884
2936
|
if (!session)
|
|
2885
2937
|
throw new Error("No active Flow session exists.");
|
|
2886
|
-
const
|
|
2887
|
-
if (
|
|
2938
|
+
const replay = exactFeatureCompleteReplay(session, request);
|
|
2939
|
+
if (!replay) {
|
|
2888
2940
|
throw new Error("Only the Flow reviewer may submit a new feature completion; other agents may replay only an exact previously accepted request.");
|
|
2889
2941
|
}
|
|
2890
|
-
|
|
2891
|
-
if (!result.replayed) {
|
|
2892
|
-
throw new Error("Expected an exact feature-completion replay.");
|
|
2893
|
-
}
|
|
2894
|
-
return featureCompleteResponse(result.session, request, result.value, true);
|
|
2942
|
+
return featureCompleteResponse(replay.session, request, replay.run, true);
|
|
2895
2943
|
} catch (error) {
|
|
2896
2944
|
return errorResponse(error);
|
|
2897
2945
|
}
|
|
@@ -3101,11 +3149,11 @@ function executeMutation(context, validation, handler) {
|
|
|
3101
3149
|
validation.cancel(context.sessionID);
|
|
3102
3150
|
return execute(context, handler);
|
|
3103
3151
|
}
|
|
3104
|
-
function executeReviewerMutation(context,
|
|
3152
|
+
function executeReviewerMutation(context, handler, replayHandler) {
|
|
3105
3153
|
if (context.agent !== "flow-reviewer") {
|
|
3106
3154
|
return execute(context, replayHandler);
|
|
3107
3155
|
}
|
|
3108
|
-
return
|
|
3156
|
+
return execute(context, handler);
|
|
3109
3157
|
}
|
|
3110
3158
|
function createTools(_ctx, options) {
|
|
3111
3159
|
return {
|
|
@@ -3162,9 +3210,9 @@ function createTools(_ctx, options) {
|
|
|
3162
3210
|
execute: (args, context) => executeMutation(context, options.validation, (workspace) => flowReviewStart(workspace, args))
|
|
3163
3211
|
}),
|
|
3164
3212
|
flow_feature_complete: tool({
|
|
3165
|
-
description: "Submit a pending review result; only the reviewer may create a new completion, while exact accepted requests remain replayable.",
|
|
3213
|
+
description: "Submit a pending review result; only the reviewer may create a new completion, while exact accepted requests remain replayable for an active Session v5 workflow.",
|
|
3166
3214
|
args: FeatureCompleteArgs,
|
|
3167
|
-
execute: (args, context) => executeReviewerMutation(context,
|
|
3215
|
+
execute: (args, context) => executeReviewerMutation(context, (workspace) => flowFeatureComplete(workspace, args), (workspace) => flowFeatureCompleteReplay(workspace, args))
|
|
3168
3216
|
}),
|
|
3169
3217
|
flow_feature_reset: tool({
|
|
3170
3218
|
description: "Reset a feature and dependents for a fresh full retry.",
|
|
@@ -3430,4 +3478,4 @@ export {
|
|
|
3430
3478
|
plugin_default as default
|
|
3431
3479
|
};
|
|
3432
3480
|
|
|
3433
|
-
//# debugId=
|
|
3481
|
+
//# debugId=57F2808662DBAC8E64756E2164756E21
|