@mgiles/perk 3.1.0 → 3.3.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/README.md +5 -0
- package/extension/authoring/gist/draft.ts +198 -0
- package/extension/authoring/gist/prose.ts +46 -0
- package/extension/authoring/gist/review.ts +133 -0
- package/extension/authoring/gist/save.ts +118 -0
- package/extension/authoring/objective/draft.ts +345 -0
- package/extension/{factories/objectiveDreamReport.ts → authoring/objective/dreamReportGate.ts} +74 -131
- package/extension/authoring/objective/planning.ts +124 -0
- package/extension/authoring/objective/prose.ts +103 -0
- package/extension/authoring/objective/review.ts +128 -0
- package/extension/authoring/objective/save.ts +224 -0
- package/extension/authoring/plan/draft.ts +84 -0
- package/extension/authoring/plan/prose.ts +41 -0
- package/extension/authoring/plan/review.ts +269 -0
- package/extension/authoring/plan/save.ts +256 -0
- package/extension/authoring/plan/source.ts +82 -0
- package/extension/authoring/refinement/context.ts +468 -0
- package/extension/authoring/refinement/draft.ts +261 -0
- package/extension/authoring/refinement/prose.ts +79 -0
- package/extension/authoring/refinement/review.ts +111 -0
- package/extension/authoring/refinement/save.ts +119 -0
- package/extension/authoring/review/approvalGate.ts +34 -0
- package/extension/authoring/review/draftContext.ts +68 -0
- package/extension/codeReview/automated.ts +352 -0
- package/extension/codeReview/submission.ts +229 -0
- package/extension/delivery/address.ts +295 -0
- package/extension/delivery/ci.ts +355 -0
- package/extension/delivery/commitCompact.ts +93 -0
- package/extension/delivery/conflictResolution.ts +247 -0
- package/extension/delivery/ready.ts +193 -0
- package/extension/delivery/stackConflict.ts +361 -0
- package/extension/delivery/stackObjective.ts +16 -0
- package/extension/delivery/stackReconcile.ts +165 -0
- package/extension/delivery/submit.ts +171 -0
- package/extension/index.ts +369 -359
- package/extension/learning/analystWave.ts +324 -0
- package/extension/learning/audit.ts +667 -0
- package/extension/learning/capture.ts +92 -0
- package/extension/learning/containment.ts +104 -0
- package/extension/{waves/dreamWave.ts → learning/dream.ts} +112 -94
- package/extension/learning/dreamAnalysis.ts +435 -0
- package/extension/{waves/dreamReducerWave.ts → learning/dreamReducer.ts} +46 -41
- package/extension/{waves → learning}/dreamReport.ts +35 -31
- package/extension/learning/harvest.ts +491 -0
- package/extension/learning/prose.ts +66 -0
- package/extension/learning/routing.ts +79 -0
- package/extension/pi/v1/bashScanTimeout.ts +64 -0
- package/extension/{doors/prReview.ts → pi/v1/codeReview/automated.ts} +215 -310
- package/extension/{doors/prReviewBrowser.ts → pi/v1/codeReview/browser.ts} +125 -57
- package/extension/{doors/hunkHandoff.ts → pi/v1/codeReview/checkout.ts} +12 -8
- package/extension/{doors/reviewWaveTools.ts → pi/v1/codeReview/reviewWave.ts} +169 -116
- package/extension/pi/v1/codeReview/stack.ts +606 -0
- package/extension/pi/v1/codeReview/submit.ts +354 -0
- package/extension/{doors/prReviewTerminal.ts → pi/v1/codeReview/terminal.ts} +32 -27
- package/extension/pi/v1/contextEvidence.ts +80 -0
- package/extension/pi/v1/contextInjection.ts +207 -0
- package/extension/{doors → pi/v1/delivery}/address.ts +163 -265
- package/extension/pi/v1/delivery/ci.ts +570 -0
- package/extension/pi/v1/delivery/commitCompact.ts +201 -0
- package/extension/pi/v1/delivery/conflictResolverEngine.ts +425 -0
- package/extension/{doors → pi/v1/delivery}/land.ts +128 -60
- package/extension/pi/v1/delivery/ready.ts +322 -0
- package/extension/pi/v1/delivery/stackConflictResolver.ts +172 -0
- package/extension/pi/v1/delivery/stackDrive.ts +120 -0
- package/extension/pi/v1/delivery/stackLand.ts +223 -0
- package/extension/pi/v1/delivery/stackRecover.ts +265 -0
- package/extension/pi/v1/delivery/stackStatus.ts +237 -0
- package/extension/pi/v1/delivery/stackSync.ts +658 -0
- package/extension/pi/v1/delivery/submit.ts +389 -0
- package/extension/pi/v1/delivery/submitConflict.ts +186 -0
- package/extension/pi/v1/draftReview.ts +431 -0
- package/extension/{doors → pi/v1}/draftReviewWaveTools.ts +141 -151
- package/extension/pi/v1/gist.ts +794 -0
- package/extension/pi/v1/learning/audit.ts +186 -0
- package/extension/pi/v1/learning/dream.ts +207 -0
- package/extension/{doors/learnFactory.ts → pi/v1/learning/factory.ts} +18 -65
- package/extension/{doors/harvestWaveTools.ts → pi/v1/learning/harvest.ts} +46 -100
- package/extension/pi/v1/learning/learn.ts +585 -0
- package/extension/{doors → pi/v1}/lifecycleGates.ts +14 -59
- package/extension/{factories → pi/v1}/objective.ts +53 -33
- package/extension/pi/v1/objectiveAuthoring.ts +672 -0
- package/extension/pi/v1/objectiveDreamGate.ts +160 -0
- package/extension/pi/v1/objectivePlanning.ts +776 -0
- package/extension/pi/v1/objectiveRefinement.ts +1320 -0
- package/extension/pi/v1/objectiveReview.ts +451 -0
- package/extension/{doors → pi/v1}/objectiveReviewBrowser.ts +259 -172
- package/extension/pi/v1/plan.ts +812 -0
- package/extension/pi/v1/planReview.ts +820 -0
- package/extension/{doors → pi/v1}/planReviewBrowser.ts +228 -152
- package/extension/{doors/annotationPush.ts → pi/v1/providers/annotations.ts} +158 -89
- package/extension/pi/v1/providers/plannotator.ts +487 -0
- package/extension/{doors → pi/v1/providers}/plannotatorHandoff.ts +152 -34
- package/extension/pi/v1/providers/selection.ts +43 -0
- package/extension/{adapters/planAdapterTombell.ts → pi/v1/providers/tombell.ts} +43 -72
- package/extension/pi/v1/review.ts +538 -0
- package/extension/pi/v1/reviewOutcome.ts +9 -0
- package/extension/pi/v1/scoutWave.ts +318 -0
- package/extension/{doors → pi/v1}/selfcheck.ts +4 -4
- package/extension/session/branchWorkflowSession.ts +60 -0
- package/extension/session/lifecycle.ts +644 -0
- package/extension/session/lifecycleGates.ts +64 -0
- package/extension/session/saveDestination.ts +87 -0
- package/extension/session/workflowSession.ts +971 -0
- package/extension/substrate/agentScratch.ts +27 -54
- package/extension/substrate/bashScanTimeout.ts +181 -0
- package/extension/substrate/bindingDelivery.ts +38 -30
- package/extension/substrate/bindings.ts +4 -5
- package/extension/substrate/cache.ts +64 -12
- package/extension/substrate/childRestrictions.ts +39 -0
- package/extension/substrate/coldDoor.ts +17 -1
- package/extension/substrate/config.ts +157 -19
- package/extension/substrate/git.ts +88 -6
- package/extension/substrate/modelVisible.ts +53 -0
- package/extension/substrate/paths.ts +2 -7
- package/extension/substrate/prompts.ts +22 -0
- package/extension/substrate/registry.ts +2 -0
- package/extension/substrate/resolverLease.ts +364 -0
- package/extension/substrate/sessionData.ts +85 -152
- package/extension/substrate/toolGating.ts +279 -84
- package/extension/substrate/unifiedDiff.ts +1 -1
- package/extension/substrate/workflowState.ts +191 -166
- package/extension/substrate/worktreeResolverLock.ts +261 -0
- package/extension/surfaces/surfaces.ts +79 -27
- package/extension/waves/adversarialReviewWave.ts +103 -48
- package/extension/waves/blockedReports.ts +59 -0
- package/extension/waves/draftReviewWave.ts +42 -42
- package/extension/waves/laneIdentity.ts +77 -0
- package/extension/waves/objectiveExplorerWave.ts +24 -24
- package/extension/waves/prReviewWave.ts +89 -77
- package/extension/waves/reportWave.ts +438 -578
- package/extension/waves/reviewClassifierWave.ts +22 -22
- package/extension/waves/rpcAdapter.ts +100 -15
- package/extension/waves/scoutWave.ts +192 -0
- package/extension/waves/transport.ts +480 -0
- package/extension/worker/sdkAdapter.ts +494 -0
- package/extension/worker/stageExecution.ts +679 -0
- package/extension/workerMain.ts +18 -19
- package/package.json +6 -4
- package/prompts/_fixtures/live.yaml +98 -10
- package/prompts/contexts/adapters/plannotator-gist.md +6 -0
- package/prompts/contexts/adapters/plannotator-objective.md +6 -0
- package/prompts/contexts/adapters/plannotator-plan.md +8 -1
- package/prompts/contexts/adapters/plannotator-refinement.md +22 -0
- package/prompts/contexts/adapters/tombell-plan.md +4 -0
- package/prompts/contexts/objective-refinement.md +17 -0
- package/prompts/contexts/plan-authoring.md +6 -5
- package/prompts/contexts/read-only.md +1 -1
- package/prompts/stages/conflict-resolution-continuation.md +9 -0
- package/prompts/stages/conflict-resolution.md +4 -4
- package/prompts/stages/objective-author/adopt.md +1 -1
- package/prompts/stages/objective-author/file.md +1 -1
- package/prompts/stages/objective-author/seed.md +1 -1
- package/prompts/stages/objective-plan/guidance.md +2 -2
- package/prompts/stages/objective-plan/seed.md +9 -1
- package/prompts/stages/objective-reconcile-ready.md +7 -0
- package/prompts/stages/objective-reconcile.md +1 -1
- package/prompts/stages/objective-refine/seed.md +18 -0
- package/prompts/stages/objective-review-browser.md +4 -4
- package/prompts/stages/objective-sync.md +1 -1
- package/prompts/stages/plan-review-browser.md +4 -4
- package/prompts/stages/pr-review-browser/active.md +3 -4
- package/prompts/stages/pr-review-browser/foreign.md +3 -4
- package/prompts/stages/pr-review-terminal/active.md +3 -3
- package/prompts/stages/pr-review-terminal/foreign.md +3 -3
- package/prompts/stages/pr-review.md +3 -3
- package/prompts/stages/stack-review/cold.md +1 -0
- package/prompts/stages/stack-review-browser/stack.md +22 -0
- package/shared/README.md +8 -3
- package/shared/bindings.yaml +6 -3
- package/shared/contracts.md +4499 -2147
- package/shared/fixtures/issues-table.json +130 -0
- package/shared/registry.yaml +29 -1
- package/shared/schemas/outputs/objective-node-engagement.schema.json +318 -0
- package/shared/schemas/outputs/objective-stack-status.schema.json +178 -2
- package/shared/schemas/outputs/pr-ready.schema.json +110 -2
- package/shared/schemas/outputs/pr-review-context.schema.json +54 -9
- package/shared/schemas/outputs/pr-review-stack-context.schema.json +196 -0
- package/extension/adapters/planAdapterPlannotator.ts +0 -362
- package/extension/doors/auditWaveTools.ts +0 -352
- package/extension/doors/ciExecutor.ts +0 -756
- package/extension/doors/commitCompact.ts +0 -251
- package/extension/doors/dreamWaveTools.ts +0 -475
- package/extension/doors/learn.ts +0 -655
- package/extension/doors/objectiveStack.ts +0 -1143
- package/extension/doors/prReviewDynamic.ts +0 -276
- package/extension/doors/ready.ts +0 -87
- package/extension/doors/submit.ts +0 -347
- package/extension/doors/submitPrReview.ts +0 -408
- package/extension/factories/gistAuthor.ts +0 -94
- package/extension/factories/gistDraft.ts +0 -265
- package/extension/factories/gistSave.ts +0 -251
- package/extension/factories/implementHere.ts +0 -116
- package/extension/factories/objectiveAuthor.ts +0 -98
- package/extension/factories/objectiveDraft.ts +0 -466
- package/extension/factories/objectivePlan.ts +0 -975
- package/extension/factories/objectiveSave.ts +0 -363
- package/extension/factories/planDraft.ts +0 -140
- package/extension/factories/planMode.ts +0 -205
- package/extension/factories/planReview.ts +0 -1237
- package/extension/factories/planSave.ts +0 -604
- package/extension/factories/planTitle.ts +0 -141
- package/extension/substrate/structuredOutput.ts +0 -202
- package/extension/waves/auditWave.ts +0 -312
- package/extension/waves/harvestWave.ts +0 -399
- package/extension/waves/learnWave.ts +0 -155
- package/extension/waves/memoryAdapter.ts +0 -139
- package/extension/waves/prReviewDynamicWave.ts +0 -777
- package/extension/worker/readOnlySession.ts +0 -294
- package/extension/worker/worker.ts +0 -899
- package/prompts/stages/pr-review-dynamic.md +0 -7
- package/shared/contracts-history.md +0 -605
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// review — plannotator always, no provider dispatch (the surface-named command IS the selection).
|
|
3
3
|
//
|
|
4
4
|
// Three modes, keyed off the arg parse + the active-PR resolution ladder (the parse is IMPORTED
|
|
5
|
-
// from
|
|
5
|
+
// from terminal.ts — one function ⇒ identical arg semantics by construction):
|
|
6
6
|
// foreign — `/pr-review-browser <pr|url> [focus]`: the detached `perk pr review checkout`, the
|
|
7
7
|
// browser opened in the background on the PR URL, the async adversarial-reviewer
|
|
8
8
|
// fan-out with per-angle annotation waves streamed to the local plannotator server.
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
// (plannotator reads `PLANNOTATOR_PORT` at bind time — see plannotatorHandoff.ts), so in the PR
|
|
18
18
|
// modes the handler starts `startPlannotatorBrowser`, injects the mode guidance IMMEDIATELY, and
|
|
19
19
|
// ends its turn — no blocking readiness poll in the handler. The readiness promise is observed
|
|
20
|
-
// in a background task: ready → an info note
|
|
20
|
+
// in a background task: ready → an info note + a continuation for pending annotation work;
|
|
21
|
+
// timeout / an error-or-unavailable bridge settle →
|
|
21
22
|
// a loud error plus a degrade notice injected to the model (findings render in-session; posting
|
|
22
23
|
// unchanged) AND the annotation surface cleared. `push_annotations` owns the
|
|
23
24
|
// hold-and-accumulate discipline: a held batch before any door failure notice means "not up
|
|
@@ -30,23 +31,31 @@
|
|
|
30
31
|
//
|
|
31
32
|
// THE COMPANION TOOLS: the reviewer fan-out is the globally registered `start_review_wave` /
|
|
32
33
|
// `collect_review_wave` pair, and the annotation delivery is the globally registered
|
|
33
|
-
// `push_annotations` tool PRIMED BY THIS DOOR (`primeAnnotationSurface`
|
|
34
|
-
//
|
|
34
|
+
// `push_annotations` tool PRIMED BY THIS DOOR (`primeAnnotationSurface` over the threaded
|
|
35
|
+
// per-activation annotation state on a PR-mode open, cleared on bridge settle and on the
|
|
36
|
+
// readiness-degrade arm — the model never sees the URL).
|
|
35
37
|
// The door still registers NO tools of its own; perk-side posting reuses `submit_pr_review`
|
|
36
|
-
// (
|
|
38
|
+
// (installed by `installCuratedSubmissionBindings`). The local (pre-PR) mode never primes.
|
|
37
39
|
|
|
38
40
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
39
|
-
import { bindingSuffix } from "
|
|
40
|
-
import { runColdDoor } from "
|
|
41
|
-
import { registerPerkCommand } from "
|
|
42
|
-
import { interceptConsoleError } from "
|
|
43
|
-
import { render } from "
|
|
44
|
-
import { type ReportTarget, report } from "
|
|
45
|
-
import {
|
|
46
|
-
import { type CheckoutOk, decodeCheckout } from "./hunkHandoff.ts";
|
|
41
|
+
import { bindingSuffix } from "../../../substrate/bindingDelivery.ts";
|
|
42
|
+
import { runColdDoor } from "../../../substrate/coldDoor.ts";
|
|
43
|
+
import { registerPerkCommand } from "../../../substrate/command.ts";
|
|
44
|
+
import { interceptConsoleError } from "../../../substrate/consoleCapture.ts";
|
|
45
|
+
import { render } from "../../../substrate/prompts.ts";
|
|
46
|
+
import { type ReportTarget, report } from "../../../surfaces/report.ts";
|
|
47
|
+
import type { ActivityHandle } from "../../../surfaces/surfaces.ts";
|
|
47
48
|
import {
|
|
49
|
+
type AnnotationState,
|
|
50
|
+
clearAnnotationSurface,
|
|
51
|
+
primeAnnotationSurface,
|
|
52
|
+
resumeAnnotationDelivery,
|
|
53
|
+
} from "../providers/annotations.ts";
|
|
54
|
+
import {
|
|
55
|
+
type CodeReviewOutcome,
|
|
48
56
|
decodePrUrl,
|
|
49
57
|
LOCAL_REVIEW_DIFF_TYPE,
|
|
58
|
+
type PrUrl,
|
|
50
59
|
plannotatorPresent,
|
|
51
60
|
planRefBaseOf,
|
|
52
61
|
type RespondSink,
|
|
@@ -56,8 +65,9 @@ import {
|
|
|
56
65
|
routePrReviewOutcome,
|
|
57
66
|
type StartedBrowser,
|
|
58
67
|
startPlannotatorBrowser,
|
|
59
|
-
} from "
|
|
60
|
-
import {
|
|
68
|
+
} from "../providers/plannotatorHandoff.ts";
|
|
69
|
+
import { type CheckoutOk, decodeCheckout } from "./checkout.ts";
|
|
70
|
+
import { parseReviewDoorArgs } from "./terminal.ts";
|
|
61
71
|
|
|
62
72
|
/** The door's report scope — also the `command:<id>` binding trigger id. */
|
|
63
73
|
const SCOPE = "pr-review-browser";
|
|
@@ -95,8 +105,9 @@ export function prReviewBrowserGuidance(opts: PrReviewBrowserGuidanceOpts): stri
|
|
|
95
105
|
/**
|
|
96
106
|
* The degrade notice injected when the browser never comes up — the model renders the findings
|
|
97
107
|
* in-session and runs the same triage conversationally; the posting contract is unchanged.
|
|
108
|
+
* Exported as the `openReviewBrowserCore` default (the stack door supplies its own).
|
|
98
109
|
*/
|
|
99
|
-
const DEGRADE_NOTICE =
|
|
110
|
+
export const DEGRADE_NOTICE =
|
|
100
111
|
"The plannotator browser review is unavailable (the review server never became ready) — " +
|
|
101
112
|
"degrade in-session: render the reviewers' reconciled findings as a table in your reply and " +
|
|
102
113
|
"run the same triage loop conversationally. The annotation surface is cleared — " +
|
|
@@ -106,8 +117,9 @@ const DEGRADE_NOTICE =
|
|
|
106
117
|
|
|
107
118
|
/**
|
|
108
119
|
* Observe the readiness poll in the background (the handler has already injected the guidance
|
|
109
|
-
* and ended): ready → an info note
|
|
110
|
-
*
|
|
120
|
+
* and ended): ready → an info note + an immediate/followUp annotation-delivery continuation
|
|
121
|
+
* when the still-current surface has held or in-flight work; timeout / an error-or-unavailable
|
|
122
|
+
* bridge settle → a loud error report PLUS the degrade notice injected to the model (idle → immediate,
|
|
111
123
|
* streaming → followUp). A bridge that settled `handled` (the human finished before the poll saw
|
|
112
124
|
* the server) or `aborted` routes via the respond routing alone — no degrade. Structural param
|
|
113
125
|
* slices keep it offline-testable; exported for the door tests.
|
|
@@ -116,10 +128,16 @@ export async function observeBrowserReadiness(
|
|
|
116
128
|
pi: RespondSink,
|
|
117
129
|
ctx: ReportTarget & Pick<ExtensionContext, "isIdle">,
|
|
118
130
|
started: StartedBrowser,
|
|
131
|
+
annotations: AnnotationState,
|
|
132
|
+
opts?: { scope?: string; degradeNotice?: string },
|
|
119
133
|
): Promise<void> {
|
|
134
|
+
const scope = opts?.scope ?? SCOPE;
|
|
135
|
+
const degradeNotice = opts?.degradeNotice ?? DEGRADE_NOTICE;
|
|
136
|
+
const surface = annotations.surface;
|
|
120
137
|
const state = await started.readiness;
|
|
121
138
|
if (state === "ready") {
|
|
122
|
-
report(ctx,
|
|
139
|
+
report(ctx, scope, "info", `plannotator is up at ${started.url} — browser opening`);
|
|
140
|
+
resumeAnnotationDelivery(annotations, surface, pi, ctx);
|
|
123
141
|
return;
|
|
124
142
|
}
|
|
125
143
|
if (state === "aborted") return; // the turn was interrupted — no-op
|
|
@@ -129,85 +147,137 @@ export async function observeBrowserReadiness(
|
|
|
129
147
|
}
|
|
130
148
|
report(
|
|
131
149
|
ctx,
|
|
132
|
-
|
|
150
|
+
scope,
|
|
133
151
|
"error",
|
|
134
152
|
`the plannotator review server did not become ready at ${started.url} — the browser ` +
|
|
135
153
|
"review is unavailable",
|
|
136
154
|
{ alsoLog: true },
|
|
137
155
|
);
|
|
138
156
|
if (ctx.isIdle()) {
|
|
139
|
-
pi.sendUserMessage(
|
|
157
|
+
pi.sendUserMessage(degradeNotice);
|
|
140
158
|
} else {
|
|
141
|
-
pi.sendUserMessage(
|
|
159
|
+
pi.sendUserMessage(degradeNotice, { deliverAs: "followUp" });
|
|
142
160
|
}
|
|
143
161
|
// Consistent with "render findings in-session": a post-degrade push_annotations refuses
|
|
144
162
|
// loudly (`no_surface`). Idempotent beside the bridge-settle clear.
|
|
145
|
-
clearAnnotationSurface();
|
|
163
|
+
clearAnnotationSurface(annotations);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** The parameterized browser-lifecycle core's options (see `openReviewBrowserCore`). */
|
|
167
|
+
export interface ReviewBrowserCoreOpts {
|
|
168
|
+
/** The invoking door's report scope. */
|
|
169
|
+
scope: string;
|
|
170
|
+
/** The `startPlannotatorBrowser` opts minus `signal`/`activity` (both threaded by the core). */
|
|
171
|
+
browserOpts: { cwd: string; prUrl?: string; diffType?: string; defaultBranch?: string };
|
|
172
|
+
/** The fully composed guidance to inject (binding suffix included by the caller). */
|
|
173
|
+
guidance: string;
|
|
174
|
+
/** The degrade notice for the browser-never-ready arm (default: the PR-mode notice). */
|
|
175
|
+
degradeNotice?: string;
|
|
176
|
+
/** The respond → injection mapper (default: `respondMessage` — the single-PR contract). */
|
|
177
|
+
respondMessageFor?: (outcome: CodeReviewOutcome) => string | null;
|
|
178
|
+
/**
|
|
179
|
+
* Whether the core injects `guidance` as a user message at the end (default true — the warm
|
|
180
|
+
* doors). The `open_stack_review` tool passes false and returns the guidance as its ok text
|
|
181
|
+
* instead (the tool result is the seeded session's delivery channel).
|
|
182
|
+
*/
|
|
183
|
+
injectGuidance?: boolean;
|
|
146
184
|
}
|
|
147
185
|
|
|
148
186
|
/**
|
|
149
|
-
* The
|
|
150
|
-
*
|
|
151
|
-
* the
|
|
152
|
-
*
|
|
153
|
-
*
|
|
187
|
+
* The full browser-lifecycle core, extracted from the PR-mode arm and parameterized for the
|
|
188
|
+
* stack door: start the browser open in the background, prime the annotation surface the
|
|
189
|
+
* moment the port is picked (push_annotations now serves this browser session), observe
|
|
190
|
+
* readiness in the background (degrade notice on never-ready), route the bridge respond
|
|
191
|
+
* through the injectable mapper, clear the surface on settle, and inject the guidance
|
|
192
|
+
* immediately (the URL is deterministic once the port is picked). While plannotator sets up,
|
|
193
|
+
* its in-process `console.error` chatter re-routes through the TUI-safe report() seam (the
|
|
194
|
+
* debounce restores once setup goes quiet, with the `finally` as a backstop).
|
|
195
|
+
*
|
|
196
|
+
* Accepted stale-clear edge (unchanged from the pre-extraction arm): a second browser door
|
|
197
|
+
* while this browser is still open re-primes (a new browser session supersedes everything),
|
|
198
|
+
* and THIS bridge's later settle would clear the second session's surface — rare and loud
|
|
199
|
+
* (the fixed-port EADDRINUSE caveat, contracts §8.4), noted, not engineered around.
|
|
154
200
|
*/
|
|
155
|
-
async function
|
|
201
|
+
export async function openReviewBrowserCore(
|
|
156
202
|
pi: ExtensionAPI,
|
|
157
203
|
ctx: ExtensionContext,
|
|
158
|
-
|
|
159
|
-
|
|
204
|
+
annotations: AnnotationState,
|
|
205
|
+
status: ActivityHandle,
|
|
206
|
+
opts: ReviewBrowserCoreOpts,
|
|
207
|
+
): Promise<boolean> {
|
|
160
208
|
let started: StartedBrowser;
|
|
161
209
|
try {
|
|
162
210
|
started = await startPlannotatorBrowser(pi.events, {
|
|
163
|
-
|
|
164
|
-
cwd: ctx.cwd,
|
|
211
|
+
...opts.browserOpts,
|
|
165
212
|
signal: ctx.signal,
|
|
213
|
+
activity: (text) => status.beginActivity(ctx, text),
|
|
166
214
|
});
|
|
167
215
|
} catch (error) {
|
|
168
216
|
const detail = error instanceof Error ? error.message : String(error);
|
|
169
217
|
report(
|
|
170
218
|
ctx,
|
|
171
|
-
|
|
219
|
+
opts.scope,
|
|
172
220
|
"error",
|
|
173
221
|
`could not pick a free local port for the plannotator review server: ${detail}`,
|
|
174
222
|
{ alsoLog: true },
|
|
175
223
|
);
|
|
176
|
-
return;
|
|
224
|
+
return false;
|
|
177
225
|
}
|
|
178
226
|
|
|
179
|
-
|
|
180
|
-
// the background-open header note): push_annotations now serves this browser session. Accepted
|
|
181
|
-
// stale-clear edge: a second /pr-review-browser while this browser is still open re-primes (a
|
|
182
|
-
// new browser session supersedes everything), and THIS bridge's later settle would clear the
|
|
183
|
-
// second session's surface — the overlap is already rare and loud (the fixed-port EADDRINUSE
|
|
184
|
-
// caveat, contracts §8.4), so it is noted, not engineered around.
|
|
185
|
-
primeAnnotationSurface({ mode: "review", url: started.url });
|
|
227
|
+
primeAnnotationSurface(annotations, { mode: "review", url: started.url });
|
|
186
228
|
|
|
187
|
-
void observeBrowserReadiness(pi, ctx, started
|
|
229
|
+
void observeBrowserReadiness(pi, ctx, started, annotations, {
|
|
230
|
+
scope: opts.scope,
|
|
231
|
+
...(opts.degradeNotice !== undefined ? { degradeNotice: opts.degradeNotice } : {}),
|
|
232
|
+
});
|
|
188
233
|
|
|
189
234
|
void (async () => {
|
|
190
|
-
const interceptor = interceptConsoleError((line) => report(ctx,
|
|
235
|
+
const interceptor = interceptConsoleError((line) => report(ctx, opts.scope, "info", line), {
|
|
191
236
|
// plannotator can pause up to ~4s between setup lines — keep the quiet window above that.
|
|
192
237
|
quietMs: 6000,
|
|
193
238
|
});
|
|
194
239
|
try {
|
|
195
240
|
const out = await started.bridgePromise;
|
|
196
|
-
routeBrowserRespond(pi, ctx, out,
|
|
241
|
+
routeBrowserRespond(pi, ctx, out, opts.scope, opts.respondMessageFor);
|
|
197
242
|
} finally {
|
|
198
243
|
// The browser session is over — drop the surface so a later push refuses (`no_surface`).
|
|
199
|
-
clearAnnotationSurface();
|
|
244
|
+
clearAnnotationSurface(annotations);
|
|
200
245
|
interceptor.restore();
|
|
201
246
|
}
|
|
202
247
|
})();
|
|
203
248
|
|
|
204
|
-
pi.sendUserMessage(
|
|
249
|
+
if (opts.injectGuidance !== false) pi.sendUserMessage(opts.guidance);
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* The shared PR-mode arm (foreign + active): the extracted core with this door's values —
|
|
255
|
+
* PR-mode browser opts, the mode guidance + binding suffix, and the default degrade notice /
|
|
256
|
+
* respond mapper (the byte-stability of the pre-extraction behavior is proven by this door's
|
|
257
|
+
* untouched tests).
|
|
258
|
+
*/
|
|
259
|
+
async function openBrowserAndGuide(
|
|
260
|
+
pi: ExtensionAPI,
|
|
261
|
+
ctx: ExtensionContext,
|
|
262
|
+
annotations: AnnotationState,
|
|
263
|
+
status: ActivityHandle,
|
|
264
|
+
opts: PrReviewBrowserGuidanceOpts,
|
|
265
|
+
): Promise<void> {
|
|
266
|
+
await openReviewBrowserCore(pi, ctx, annotations, status, {
|
|
267
|
+
scope: SCOPE,
|
|
268
|
+
browserOpts: { prUrl: opts.prUrl, cwd: ctx.cwd },
|
|
269
|
+
guidance: prReviewBrowserGuidance(opts) + bindingSuffix(ctx.cwd, `command:${SCOPE}`),
|
|
270
|
+
});
|
|
205
271
|
}
|
|
206
272
|
|
|
207
273
|
// ------------------------------------------------------------------------ registration
|
|
208
274
|
|
|
209
|
-
/**
|
|
210
|
-
export function
|
|
275
|
+
/** Install the warm `/pr-review-browser` command (no tools — posting rides submit_pr_review). */
|
|
276
|
+
export function installPrReviewBrowserBindings(
|
|
277
|
+
pi: ExtensionAPI,
|
|
278
|
+
annotations: AnnotationState,
|
|
279
|
+
status: ActivityHandle,
|
|
280
|
+
): void {
|
|
211
281
|
registerPerkCommand(pi, SCOPE, {
|
|
212
282
|
description:
|
|
213
283
|
"Review a PR human-in-the-loop in the plannotator browser UI: no arg reviews the active " +
|
|
@@ -269,7 +339,7 @@ export function registerPrReviewBrowser(pi: ExtensionAPI): void {
|
|
|
269
339
|
? `PR #${parsed.pr} → adversarial reviewers (focus: ${parsed.directive}) → plannotator browser triage → you post from the browser`
|
|
270
340
|
: `PR #${parsed.pr} → adversarial reviewers → plannotator browser triage → you post from the browser`,
|
|
271
341
|
);
|
|
272
|
-
await openBrowserAndGuide(pi, ctx, {
|
|
342
|
+
await openBrowserAndGuide(pi, ctx, annotations, status, {
|
|
273
343
|
mode: "foreign",
|
|
274
344
|
pr: parsed.pr,
|
|
275
345
|
prUrl: checkout.data.url,
|
|
@@ -280,12 +350,10 @@ export function registerPrReviewBrowser(pi: ExtensionAPI): void {
|
|
|
280
350
|
}
|
|
281
351
|
|
|
282
352
|
// The active arm: resolve the worktree's own PR via the shared ladder.
|
|
283
|
-
const r = await runColdDoor<
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
{ label: "perk pr url", decode: decodePrUrl },
|
|
288
|
-
);
|
|
353
|
+
const r = await runColdDoor<PrUrl>(pi, ctx, ["pr", "url", "--json"], {
|
|
354
|
+
label: "perk pr url",
|
|
355
|
+
decode: decodePrUrl,
|
|
356
|
+
});
|
|
289
357
|
const target = resolveReviewTarget(r, planRefBaseOf(ctx.cwd));
|
|
290
358
|
if (target.mode === "fail") {
|
|
291
359
|
report(
|
|
@@ -307,7 +375,7 @@ export function registerPrReviewBrowser(pi: ExtensionAPI): void {
|
|
|
307
375
|
? `PR #${target.number} (active worktree) → adversarial reviewers (focus: ${parsed.directive}) → plannotator browser triage → you post from the browser`
|
|
308
376
|
: `PR #${target.number} (active worktree) → adversarial reviewers → plannotator browser triage → you post from the browser`,
|
|
309
377
|
);
|
|
310
|
-
await openBrowserAndGuide(pi, ctx, {
|
|
378
|
+
await openBrowserAndGuide(pi, ctx, annotations, status, {
|
|
311
379
|
mode: "active",
|
|
312
380
|
pr: target.number,
|
|
313
381
|
prUrl: target.prUrl,
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
// The
|
|
1
|
+
// The neutral shared checkout/PR-token substrate serving the code-review doors: the strict
|
|
2
2
|
// `perk pr review checkout` decode, the `hunk --version` presence probe, and the R7 launch
|
|
3
3
|
// handoff (clipboard copy + terminal auto-launch raced against a soft deadline) — plus the
|
|
4
4
|
// door-common PR-token arg grammar (`parseReviewArgs`) that `/pr-review-browser` also consumes
|
|
5
|
-
// via `parseReviewDoorArgs`.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
// via `parseReviewDoorArgs`. Its only consumers are the `pi/v1/codeReview/` siblings.
|
|
6
|
+
|
|
7
|
+
import { copyToClipboard } from "../../../substrate/clipboard.ts";
|
|
8
|
+
import {
|
|
9
|
+
type ColdJson,
|
|
10
|
+
type ExecHost,
|
|
11
|
+
numberField,
|
|
12
|
+
stringField,
|
|
13
|
+
} from "../../../substrate/coldDoor.ts";
|
|
14
|
+
import { LAUNCH_SURFACE, launchInTerminal } from "../../../substrate/terminalLaunch.ts";
|
|
15
|
+
import { type ReportTarget, report } from "../../../surfaces/report.ts";
|
|
12
16
|
|
|
13
17
|
/** The install hint for the absent hunk binary — the exact `HUNK_INSTALL_HINT` wording
|
|
14
18
|
* (src/perk/convergence/init/review_cli.py). */
|