opencode-plugin-flow 6.9.0 → 7.0.1
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 +80 -0
- package/README.md +92 -205
- package/dist/index.js +108 -95
- package/dist/index.js.map +20 -18
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -56,7 +56,8 @@ never silently fall back.
|
|
|
56
56
|
refreshed projection. This cleanup precedes goal alignment and grants no work.
|
|
57
57
|
Before another manager mutation, align the compact-projected goal with the
|
|
58
58
|
request. Continue only for the same goal or a narrowing that preserves every
|
|
59
|
-
outcome
|
|
59
|
+
outcome; authority the request adds over those same outcomes is continuation,
|
|
60
|
+
not expansion. Close a completed session as completed before new work. If the user
|
|
60
61
|
explicitly chooses deferred or abandoned closure for a non-completed session,
|
|
61
62
|
call \`flow_session_close\` with compact session id/revision, fresh operation
|
|
62
63
|
id, that kind, and optional summary; handle **Recovery**, follow a projected
|
|
@@ -546,9 +547,9 @@ checks from the changed behavior and risk:
|
|
|
546
547
|
sufficient alone only for genuinely mechanical or documentation-only work.
|
|
547
548
|
- UI claims need visual inspection when a runnable target is available.
|
|
548
549
|
- Cleanup claims need behavior-preservation evidence, not formatting alone.
|
|
549
|
-
- \`scope: "broad"\` is a claim
|
|
550
|
-
|
|
551
|
-
|
|
550
|
+
- \`scope: "broad"\` is a coverage claim, not a stronger label. Use it only for the
|
|
551
|
+
repository's canonical applicable gate or a justified equivalent covering the
|
|
552
|
+
delivered repository state.
|
|
552
553
|
|
|
553
554
|
Immediately before each evidence Bash command, call \`flow_validation_start\`
|
|
554
555
|
with current revision, feature id, exact command, and \`scope\` (\`focused\` or
|
|
@@ -561,11 +562,13 @@ A failed, incomplete, or source-drifted exact plan-listed observation creates a
|
|
|
561
562
|
freshness boundary. Before new review admission, that gate needs a complete
|
|
562
563
|
exit-zero observation for current source recorded after its latest relevant
|
|
563
564
|
failure or drift; returning to an older digest does not revive an earlier pass,
|
|
564
|
-
and substitute broad validation cannot discharge it.
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
565
|
+
and substitute broad validation cannot discharge it. Plan-listed validation prose
|
|
566
|
+
that has never run as an exact command remains reviewer judgment, not a fabricated
|
|
567
|
+
pass or failure.
|
|
568
|
+
|
|
569
|
+
A gate that cannot pass withholds completed closure, and reporting the blocker is
|
|
570
|
+
half the move. Fix the gate, or ask the user to choose deferred or abandoned
|
|
571
|
+
closure. Ending the turn having done neither leaves the workflow with no next step.
|
|
569
572
|
|
|
570
573
|
Every host-observed validation advances the session revision, so the revision
|
|
571
574
|
that armed a completed command is stale. The \`[flow-validation]\` marker reports
|
|
@@ -577,7 +580,7 @@ Use focused validation for ordinary features. For the final feature, run the
|
|
|
577
580
|
repository's broad applicable gate after the last relevant edit. A source edit
|
|
578
581
|
invalidates earlier applicability. Failed or unavailable checks are blockers,
|
|
579
582
|
not passing evidence. If the canonical gate cannot run, explain why the chosen
|
|
580
|
-
equivalent is broad enough
|
|
583
|
+
equivalent is broad enough.
|
|
581
584
|
|
|
582
585
|
Immediately before review admission, reconcile the preflight inventory against
|
|
583
586
|
the recorded current-source observations. Do not call \`flow_review_start\` while
|
|
@@ -653,13 +656,12 @@ stops. Under \`/flow-auto\`, return to its lifecycle loop.
|
|
|
653
656
|
`;
|
|
654
657
|
|
|
655
658
|
// src/guidance/ids.ts
|
|
656
|
-
var
|
|
659
|
+
var FLOW_GUIDANCE_IDS = [
|
|
657
660
|
"flow",
|
|
658
661
|
"flow-plan",
|
|
659
662
|
"flow-run",
|
|
660
663
|
"flow-review"
|
|
661
664
|
];
|
|
662
|
-
var FLOW_GUIDANCE_IDS = FLOW_GUIDANCE_TOPICS;
|
|
663
665
|
|
|
664
666
|
// src/guidance/catalog.ts
|
|
665
667
|
var FLOW_MANAGER_KERNEL = [
|
|
@@ -696,12 +698,7 @@ ${FLOW_MANAGER_KERNEL}
|
|
|
696
698
|
`,
|
|
697
699
|
"flow-review": SKILL_default3
|
|
698
700
|
};
|
|
699
|
-
var FLOW_GUIDANCE_DOCUMENTS =
|
|
700
|
-
relativePath: "SKILL.md",
|
|
701
|
-
content: GUIDANCE_CONTENT[name],
|
|
702
|
-
id: name,
|
|
703
|
-
topic: name
|
|
704
|
-
}));
|
|
701
|
+
var FLOW_GUIDANCE_DOCUMENTS = FLOW_GUIDANCE_IDS.map((id) => ({ id, content: GUIDANCE_CONTENT[id] }));
|
|
705
702
|
var FLOW_GUIDANCE_BY_ID = new Map(FLOW_GUIDANCE_DOCUMENTS.map((document) => [document.id, document]));
|
|
706
703
|
function getFlowGuidance(id) {
|
|
707
704
|
const document = FLOW_GUIDANCE_BY_ID.get(id);
|
|
@@ -709,9 +706,6 @@ function getFlowGuidance(id) {
|
|
|
709
706
|
throw new Error(`Missing bundled Flow guidance '${id}'.`);
|
|
710
707
|
return document;
|
|
711
708
|
}
|
|
712
|
-
if (FLOW_GUIDANCE_BY_ID.size !== FLOW_GUIDANCE_IDS.length) {
|
|
713
|
-
throw new Error("Bundled Flow guidance ids and documents are out of sync.");
|
|
714
|
-
}
|
|
715
709
|
|
|
716
710
|
// src/prompt-surfaces.ts
|
|
717
711
|
var FLOW_WORKER_PROMPT = [
|
|
@@ -939,17 +933,11 @@ function createFlowCoreConfigEntries(options) {
|
|
|
939
933
|
...FLOW_CORE_AGENTS["flow-reviewer"],
|
|
940
934
|
...model ? { model } : {},
|
|
941
935
|
...steps ? { steps } : {},
|
|
942
|
-
permission:
|
|
943
|
-
...FLOW_CORE_AGENTS["flow-reviewer"].permission,
|
|
944
|
-
task: { "*": "deny" }
|
|
945
|
-
}
|
|
936
|
+
permission: structuredClone(FLOW_CORE_AGENTS["flow-reviewer"].permission)
|
|
946
937
|
},
|
|
947
938
|
"flow-worker": {
|
|
948
939
|
...FLOW_CORE_AGENTS["flow-worker"],
|
|
949
|
-
permission:
|
|
950
|
-
...FLOW_CORE_AGENTS["flow-worker"].permission,
|
|
951
|
-
task: { "*": "deny" }
|
|
952
|
-
}
|
|
940
|
+
permission: structuredClone(FLOW_CORE_AGENTS["flow-worker"].permission)
|
|
953
941
|
}
|
|
954
942
|
},
|
|
955
943
|
command: Object.fromEntries(Object.entries(FLOW_CORE_COMMANDS).map(([name, value]) => [
|
|
@@ -1240,6 +1228,24 @@ var LONGEST_VALIDATION_INELIGIBLE_REASON = VALIDATION_INELIGIBLE_REASONS.reduce(
|
|
|
1240
1228
|
function isValidationEligible(observation, sourceDigest) {
|
|
1241
1229
|
return observation.ineligibleReason === undefined && observation.exitCode === 0 && observation.outputComplete && (sourceDigest === undefined || observation.sourceDigest === sourceDigest);
|
|
1242
1230
|
}
|
|
1231
|
+
var NARROWING_FLAGS = new Set([
|
|
1232
|
+
"-t",
|
|
1233
|
+
"--test-name-pattern",
|
|
1234
|
+
"--testNamePattern",
|
|
1235
|
+
"-k",
|
|
1236
|
+
"-run",
|
|
1237
|
+
"--grep",
|
|
1238
|
+
"--filter"
|
|
1239
|
+
]);
|
|
1240
|
+
function narrowingArguments(command) {
|
|
1241
|
+
return command.split(/\s+/).slice(1).filter((token) => {
|
|
1242
|
+
if (token.startsWith("-")) {
|
|
1243
|
+
return NARROWING_FLAGS.has(token.split("=")[0] ?? token);
|
|
1244
|
+
}
|
|
1245
|
+
const file = token.split("/").pop() ?? "";
|
|
1246
|
+
return /\.(?:test|spec)\./.test(file) || /_test\.[a-z]+$/.test(file) || /^test_.+\.py$/.test(file);
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1243
1249
|
function recordValidation(session, input) {
|
|
1244
1250
|
if (input.captureId.length < 1 || input.captureId.length > MAX_VALIDATION_ID_LENGTH) {
|
|
1245
1251
|
throw new FlowTransitionError(`Validation capture id must contain 1-${MAX_VALIDATION_ID_LENGTH} characters.`);
|
|
@@ -1267,6 +1273,12 @@ function recordValidation(session, input) {
|
|
|
1267
1273
|
if (run.validations.length >= MAX_VALIDATIONS_PER_RUN) {
|
|
1268
1274
|
throw new FlowTransitionError(`A feature run may contain at most ${MAX_VALIDATIONS_PER_RUN} validation observations.`);
|
|
1269
1275
|
}
|
|
1276
|
+
if (input.scope === "broad") {
|
|
1277
|
+
const narrowing = narrowingArguments(input.command);
|
|
1278
|
+
if (narrowing.length > 0) {
|
|
1279
|
+
throw new FlowTransitionError(`A broad observation cannot select which tests it runs (${narrowing.join(", ")}). Arm the repository's canonical gate, or record this command as focused.`);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1270
1282
|
const revision = session.revision + 1;
|
|
1271
1283
|
const observation = {
|
|
1272
1284
|
id: input.captureId,
|
|
@@ -1298,15 +1310,13 @@ function recordValidation(session, input) {
|
|
|
1298
1310
|
function isValidationFresh(session, run, observation) {
|
|
1299
1311
|
return session.runs.filter((candidate) => candidate.featureId === run.featureId).flatMap((candidate) => candidate.validations).every((candidate) => candidate.command !== observation.command || isValidationEligible(candidate) || candidate.recordedRevision < observation.recordedRevision);
|
|
1300
1312
|
}
|
|
1301
|
-
function
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
const
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
const commands = [...new Set(feature.validation)];
|
|
1309
|
-
return commands.filter((command) => validations.some((observation) => observation.command === command && !isValidationEligible(observation)) && !run.validations.some((observation) => observation.command === command && isValidationEligible(observation, sourceDigest) && isValidationFresh(session, run, observation)));
|
|
1313
|
+
function unresolvedVetoedCommands(session, run, sourceDigest) {
|
|
1314
|
+
const planned = session.approval === "approved" ? session.plan?.features.find((candidate) => candidate.id === run.featureId)?.validation ?? [] : [];
|
|
1315
|
+
const failed = session.runs.filter((candidate) => candidate.featureId === run.featureId).flatMap((candidate) => candidate.validations).filter((observation) => !isValidationEligible(observation));
|
|
1316
|
+
const commands = [
|
|
1317
|
+
...new Set(failed.filter((observation) => observation.scope === "broad" || planned.includes(observation.command)).map((observation) => observation.command))
|
|
1318
|
+
];
|
|
1319
|
+
return commands.filter((command) => !run.validations.some((observation) => observation.command === command && isValidationEligible(observation, sourceDigest) && isValidationFresh(session, run, observation)));
|
|
1310
1320
|
}
|
|
1311
1321
|
|
|
1312
1322
|
// src/domain/transitions.ts
|
|
@@ -1561,9 +1571,9 @@ function startReview(session, input, environment) {
|
|
|
1561
1571
|
if (run.reviews.length > 0) {
|
|
1562
1572
|
fail("Reset the feature before starting another full review.");
|
|
1563
1573
|
}
|
|
1564
|
-
const unresolved =
|
|
1574
|
+
const unresolved = unresolvedVetoedCommands(session, run, input.sourceDigest);
|
|
1565
1575
|
if (unresolved.length > 0) {
|
|
1566
|
-
fail(`Review requires passing exact
|
|
1576
|
+
fail(`Review requires passing these exact commands for the current workspace content: ${unresolved.map((command) => JSON.stringify(command)).join(", ")}. A different command cannot discharge one that failed.`);
|
|
1567
1577
|
}
|
|
1568
1578
|
const kind = isFinalFeatureRun(session, run) ? "final" : "feature";
|
|
1569
1579
|
const applicable = run.validations.filter((validation) => isValidationEligible(validation, input.sourceDigest) && isValidationFresh(session, run, validation));
|
|
@@ -1760,6 +1770,40 @@ function closeSession(session, input) {
|
|
|
1760
1770
|
fail("Flow could not record the closure.");
|
|
1761
1771
|
return { session: next, value: closure, replayed: false };
|
|
1762
1772
|
}
|
|
1773
|
+
|
|
1774
|
+
// src/application/errors.ts
|
|
1775
|
+
class UnreadableFlowSessionError extends Error {
|
|
1776
|
+
code = "UNREADABLE_FLOW_SESSION";
|
|
1777
|
+
reason;
|
|
1778
|
+
constructor(message, reason) {
|
|
1779
|
+
super(message);
|
|
1780
|
+
this.name = "UnreadableFlowSessionError";
|
|
1781
|
+
this.reason = reason;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
class UnsupportedFlowSessionVersionError extends Error {
|
|
1786
|
+
code = "UNSUPPORTED_FLOW_SESSION_VERSION";
|
|
1787
|
+
actualVersion;
|
|
1788
|
+
constructor(actualVersion) {
|
|
1789
|
+
super("Flow v6 supports only Session v5 active state. Close active older sessions before upgrading; archived history remains inert.");
|
|
1790
|
+
this.name = "UnsupportedFlowSessionVersionError";
|
|
1791
|
+
this.actualVersion = actualVersion;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
class ArchiveCollisionError extends Error {
|
|
1796
|
+
code = "FLOW_ARCHIVE_COLLISION";
|
|
1797
|
+
constructor(message) {
|
|
1798
|
+
super(message);
|
|
1799
|
+
this.name = "ArchiveCollisionError";
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
// src/application/schema.ts
|
|
1804
|
+
import { z } from "zod";
|
|
1805
|
+
|
|
1806
|
+
// src/domain/session-invariants.ts
|
|
1763
1807
|
function featurePassedBefore(session, featureId, revision) {
|
|
1764
1808
|
return session.runs.some((run) => run.featureId === featureId && run.reviews.some((review) => review.result?.verdict === "passed" && review.result.recordedRevision < revision));
|
|
1765
1809
|
}
|
|
@@ -1795,11 +1839,9 @@ function sessionInvariantIssues(session) {
|
|
|
1795
1839
|
issues.push("Runs require a plan.");
|
|
1796
1840
|
return issues;
|
|
1797
1841
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
issues.push(error instanceof Error ? error.message : String(error));
|
|
1802
|
-
}
|
|
1842
|
+
const planProblem = planIssue(session.plan);
|
|
1843
|
+
if (planProblem)
|
|
1844
|
+
issues.push(planProblem);
|
|
1803
1845
|
const featureIds = new Set(session.plan.features.map((feature) => feature.id));
|
|
1804
1846
|
const runIds = new Set;
|
|
1805
1847
|
const validationIds = new Set;
|
|
@@ -1888,11 +1930,9 @@ function sessionInvariantIssues(session) {
|
|
|
1888
1930
|
if (review.result.recordedRevision <= review.createdRevision || review.result.recordedRevision > session.revision) {
|
|
1889
1931
|
issues.push(`Review '${review.id}' has an invalid result revision.`);
|
|
1890
1932
|
}
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
issues.push(error instanceof Error ? error.message : String(error));
|
|
1895
|
-
}
|
|
1933
|
+
const resultProblem = review.result.findings.length > MAX_REVIEW_FINDINGS ? `A review may contain at most ${MAX_REVIEW_FINDINGS} findings.` : reviewResultSemanticIssues(review.result)[0]?.message;
|
|
1934
|
+
if (resultProblem)
|
|
1935
|
+
issues.push(resultProblem);
|
|
1896
1936
|
}
|
|
1897
1937
|
}
|
|
1898
1938
|
const last = run.reviews.at(-1);
|
|
@@ -1921,37 +1961,7 @@ function sessionInvariantIssues(session) {
|
|
|
1921
1961
|
return issues;
|
|
1922
1962
|
}
|
|
1923
1963
|
|
|
1924
|
-
// src/application/errors.ts
|
|
1925
|
-
class UnreadableFlowSessionError extends Error {
|
|
1926
|
-
code = "UNREADABLE_FLOW_SESSION";
|
|
1927
|
-
reason;
|
|
1928
|
-
constructor(message, reason) {
|
|
1929
|
-
super(message);
|
|
1930
|
-
this.name = "UnreadableFlowSessionError";
|
|
1931
|
-
this.reason = reason;
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
|
|
1935
|
-
class UnsupportedFlowSessionVersionError extends Error {
|
|
1936
|
-
code = "UNSUPPORTED_FLOW_SESSION_VERSION";
|
|
1937
|
-
actualVersion;
|
|
1938
|
-
constructor(actualVersion) {
|
|
1939
|
-
super("Flow v6 supports only Session v5 active state. Close active older sessions before upgrading; archived history remains inert.");
|
|
1940
|
-
this.name = "UnsupportedFlowSessionVersionError";
|
|
1941
|
-
this.actualVersion = actualVersion;
|
|
1942
|
-
}
|
|
1943
|
-
}
|
|
1944
|
-
|
|
1945
|
-
class ArchiveCollisionError extends Error {
|
|
1946
|
-
code = "FLOW_ARCHIVE_COLLISION";
|
|
1947
|
-
constructor(message) {
|
|
1948
|
-
super(message);
|
|
1949
|
-
this.name = "ArchiveCollisionError";
|
|
1950
|
-
}
|
|
1951
|
-
}
|
|
1952
|
-
|
|
1953
1964
|
// src/application/schema.ts
|
|
1954
|
-
import { z } from "zod";
|
|
1955
1965
|
var encoder = new TextEncoder;
|
|
1956
1966
|
function boundedText(label, options) {
|
|
1957
1967
|
const maxBytes = options?.maxBytes ?? MAX_TEXT_BYTES;
|
|
@@ -1960,6 +1970,7 @@ function boundedText(label, options) {
|
|
|
1960
1970
|
var FeatureIdSchema = z.string().max(MAX_SESSION_ID_LENGTH).regex(FEATURE_ID_PATTERN, FEATURE_ID_MESSAGE);
|
|
1961
1971
|
var OperationIdSchema = z.string().min(1).max(128).regex(/^[a-zA-Z0-9][a-zA-Z0-9._:-]*$/);
|
|
1962
1972
|
var ReviewAssignmentIdSchema = z.string().min(1).max(256);
|
|
1973
|
+
var RunIdSchema = z.string().min(1).max(256);
|
|
1963
1974
|
var RevisionSchema = z.number().int().safe().nonnegative();
|
|
1964
1975
|
var SourceDigestSchema = z.custom((value) => typeof value === "string" && /^sha256:[a-f0-9]{64}$/.test(value), "Expected a sha256: content digest.");
|
|
1965
1976
|
var PlanFeatureSchema = z.object({
|
|
@@ -2000,10 +2011,14 @@ var PublicReviewResultSchema = z.object({
|
|
|
2000
2011
|
context.addIssue({ code: "custom", ...issue });
|
|
2001
2012
|
}
|
|
2002
2013
|
});
|
|
2014
|
+
var ReviewPacketSchema = z.object({
|
|
2015
|
+
summary: boundedText("Review packet summary"),
|
|
2016
|
+
riskLenses: z.array(boundedText("Review risk lens")).max(16).default([])
|
|
2017
|
+
}).strict();
|
|
2003
2018
|
var ValidationObservationSchema = z.object({
|
|
2004
2019
|
id: z.string().min(1).max(MAX_VALIDATION_ID_LENGTH),
|
|
2005
2020
|
featureId: FeatureIdSchema,
|
|
2006
|
-
runId:
|
|
2021
|
+
runId: RunIdSchema,
|
|
2007
2022
|
scope: z.enum(["focused", "broad"]),
|
|
2008
2023
|
command: boundedText("Validation command"),
|
|
2009
2024
|
sourceDigest: SourceDigestSchema,
|
|
@@ -2024,19 +2039,16 @@ var ReviewAssignmentSchema = z.object({
|
|
|
2024
2039
|
id: ReviewAssignmentIdSchema,
|
|
2025
2040
|
operationId: OperationIdSchema,
|
|
2026
2041
|
featureId: FeatureIdSchema,
|
|
2027
|
-
runId:
|
|
2042
|
+
runId: RunIdSchema,
|
|
2028
2043
|
kind: z.enum(["feature", "final"]),
|
|
2029
2044
|
sourceDigest: SourceDigestSchema,
|
|
2030
2045
|
validationIds: z.array(z.string().min(1).max(MAX_VALIDATION_ID_LENGTH)).min(1).max(MAX_VALIDATIONS_PER_RUN),
|
|
2031
|
-
packet:
|
|
2032
|
-
summary: boundedText("Review packet summary"),
|
|
2033
|
-
riskLenses: z.array(boundedText("Review risk lens")).max(16).default([])
|
|
2034
|
-
}).strict(),
|
|
2046
|
+
packet: ReviewPacketSchema,
|
|
2035
2047
|
createdRevision: RevisionSchema,
|
|
2036
2048
|
result: PersistedReviewResultSchema.nullable()
|
|
2037
2049
|
}).strict();
|
|
2038
2050
|
var FeatureRunSchema = z.object({
|
|
2039
|
-
id:
|
|
2051
|
+
id: RunIdSchema,
|
|
2040
2052
|
featureId: FeatureIdSchema,
|
|
2041
2053
|
attempt: z.number().int().safe().positive(),
|
|
2042
2054
|
state: z.enum(["active", "completed", "blocked", "superseded"]),
|
|
@@ -2109,10 +2121,7 @@ var ReviewStartInputSchema = z.object({
|
|
|
2109
2121
|
...guarded,
|
|
2110
2122
|
featureId: FeatureIdSchema,
|
|
2111
2123
|
artifactsChanged: z.array(ArtifactSchema).max(MAX_ARTIFACTS),
|
|
2112
|
-
packet:
|
|
2113
|
-
summary: boundedText("Review packet summary"),
|
|
2114
|
-
riskLenses: z.array(boundedText("Review risk lens")).max(16).default([])
|
|
2115
|
-
}).strict()
|
|
2124
|
+
packet: ReviewPacketSchema
|
|
2116
2125
|
}).strict()
|
|
2117
2126
|
}).strict();
|
|
2118
2127
|
var FeatureCompleteInputSchema = z.object({
|
|
@@ -2274,7 +2283,7 @@ function nextAction(session, pendingReviewSourceStale = false, blockedFeature =
|
|
|
2274
2283
|
const hasPassingValidation = run.validations.some((validation) => isValidationEligible(validation) && isValidationFresh(session, run, validation) && (!finalRun || validation.scope === "broad"));
|
|
2275
2284
|
if (!hasPassingValidation)
|
|
2276
2285
|
return "flow_validation_start";
|
|
2277
|
-
if (
|
|
2286
|
+
if (unresolvedVetoedCommands(session, run).length > 0) {
|
|
2278
2287
|
return "flow_validation_start";
|
|
2279
2288
|
}
|
|
2280
2289
|
return "flow_review_start";
|
|
@@ -4149,8 +4158,10 @@ function registerFlowPluginInstance(scopeId, input) {
|
|
|
4149
4158
|
});
|
|
4150
4159
|
}
|
|
4151
4160
|
|
|
4152
|
-
// src/platform/opencode/
|
|
4161
|
+
// src/platform/opencode/sdk.ts
|
|
4153
4162
|
import { tool } from "@opencode-ai/plugin";
|
|
4163
|
+
|
|
4164
|
+
// src/platform/opencode/tools.ts
|
|
4154
4165
|
var host = tool.schema;
|
|
4155
4166
|
var encoder2 = new TextEncoder;
|
|
4156
4167
|
function boundedHostText(label, options) {
|
|
@@ -4191,7 +4202,9 @@ var plan = host.object({
|
|
|
4191
4202
|
var reviewFinding = host.object({
|
|
4192
4203
|
severity: host.enum(["blocking", "advisory"]),
|
|
4193
4204
|
summary: text,
|
|
4194
|
-
evidence: text.optional()
|
|
4205
|
+
evidence: text.optional(),
|
|
4206
|
+
scopeBlocker: host.boolean().optional(),
|
|
4207
|
+
findingId: host.string().max(MAX_SESSION_ID_LENGTH).regex(FINDING_ID_PATTERN, FINDING_ID_MESSAGE).optional()
|
|
4195
4208
|
}).strict();
|
|
4196
4209
|
var reviewResult = host.object({
|
|
4197
4210
|
verdict: host.enum(["passed", "failed"]),
|
|
@@ -4761,4 +4774,4 @@ export {
|
|
|
4761
4774
|
plugin_default as default
|
|
4762
4775
|
};
|
|
4763
4776
|
|
|
4764
|
-
//# debugId=
|
|
4777
|
+
//# debugId=F9B2A9081022601764756E2164756E21
|