@mgiles/perk 3.2.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.
Files changed (202) hide show
  1. package/README.md +5 -0
  2. package/extension/authoring/gist/draft.ts +198 -0
  3. package/extension/authoring/gist/prose.ts +46 -0
  4. package/extension/authoring/gist/review.ts +133 -0
  5. package/extension/authoring/gist/save.ts +118 -0
  6. package/extension/authoring/objective/draft.ts +345 -0
  7. package/extension/{factories/objectiveDreamReport.ts → authoring/objective/dreamReportGate.ts} +74 -131
  8. package/extension/authoring/objective/planning.ts +124 -0
  9. package/extension/authoring/objective/prose.ts +103 -0
  10. package/extension/authoring/objective/review.ts +128 -0
  11. package/extension/authoring/objective/save.ts +224 -0
  12. package/extension/authoring/plan/draft.ts +84 -0
  13. package/extension/authoring/plan/prose.ts +41 -0
  14. package/extension/authoring/plan/review.ts +269 -0
  15. package/extension/authoring/plan/save.ts +256 -0
  16. package/extension/authoring/plan/source.ts +82 -0
  17. package/extension/authoring/refinement/context.ts +468 -0
  18. package/extension/authoring/refinement/draft.ts +261 -0
  19. package/extension/authoring/refinement/prose.ts +79 -0
  20. package/extension/authoring/refinement/review.ts +111 -0
  21. package/extension/authoring/refinement/save.ts +119 -0
  22. package/extension/authoring/review/approvalGate.ts +34 -0
  23. package/extension/authoring/review/draftContext.ts +68 -0
  24. package/extension/codeReview/automated.ts +352 -0
  25. package/extension/codeReview/submission.ts +229 -0
  26. package/extension/delivery/address.ts +295 -0
  27. package/extension/delivery/ci.ts +355 -0
  28. package/extension/delivery/commitCompact.ts +93 -0
  29. package/extension/delivery/conflictResolution.ts +247 -0
  30. package/extension/delivery/ready.ts +193 -0
  31. package/extension/delivery/stackConflict.ts +361 -0
  32. package/extension/delivery/stackObjective.ts +16 -0
  33. package/extension/delivery/stackReconcile.ts +165 -0
  34. package/extension/delivery/submit.ts +171 -0
  35. package/extension/index.ts +365 -380
  36. package/extension/learning/analystWave.ts +324 -0
  37. package/extension/learning/audit.ts +667 -0
  38. package/extension/learning/capture.ts +92 -0
  39. package/extension/learning/containment.ts +104 -0
  40. package/extension/{waves/dreamWave.ts → learning/dream.ts} +112 -94
  41. package/extension/learning/dreamAnalysis.ts +435 -0
  42. package/extension/{waves/dreamReducerWave.ts → learning/dreamReducer.ts} +46 -41
  43. package/extension/{waves → learning}/dreamReport.ts +35 -31
  44. package/extension/learning/harvest.ts +491 -0
  45. package/extension/learning/prose.ts +66 -0
  46. package/extension/learning/routing.ts +79 -0
  47. package/extension/pi/v1/bashScanTimeout.ts +64 -0
  48. package/extension/{doors/prReview.ts → pi/v1/codeReview/automated.ts} +215 -311
  49. package/extension/{doors/prReviewBrowser.ts → pi/v1/codeReview/browser.ts} +53 -33
  50. package/extension/{doors/hunkHandoff.ts → pi/v1/codeReview/checkout.ts} +12 -8
  51. package/extension/{doors/reviewWaveTools.ts → pi/v1/codeReview/reviewWave.ts} +146 -114
  52. package/extension/{doors/stackReviewBrowser.ts → pi/v1/codeReview/stack.ts} +62 -29
  53. package/extension/pi/v1/codeReview/submit.ts +354 -0
  54. package/extension/{doors/prReviewTerminal.ts → pi/v1/codeReview/terminal.ts} +32 -27
  55. package/extension/pi/v1/contextEvidence.ts +80 -0
  56. package/extension/pi/v1/contextInjection.ts +207 -0
  57. package/extension/{doors → pi/v1/delivery}/address.ts +154 -267
  58. package/extension/pi/v1/delivery/ci.ts +570 -0
  59. package/extension/pi/v1/delivery/commitCompact.ts +201 -0
  60. package/extension/pi/v1/delivery/conflictResolverEngine.ts +425 -0
  61. package/extension/{doors → pi/v1/delivery}/land.ts +123 -61
  62. package/extension/pi/v1/delivery/ready.ts +322 -0
  63. package/extension/pi/v1/delivery/stackConflictResolver.ts +172 -0
  64. package/extension/pi/v1/delivery/stackDrive.ts +120 -0
  65. package/extension/pi/v1/delivery/stackLand.ts +223 -0
  66. package/extension/pi/v1/delivery/stackRecover.ts +265 -0
  67. package/extension/pi/v1/delivery/stackStatus.ts +237 -0
  68. package/extension/pi/v1/delivery/stackSync.ts +658 -0
  69. package/extension/pi/v1/delivery/submit.ts +389 -0
  70. package/extension/pi/v1/delivery/submitConflict.ts +186 -0
  71. package/extension/pi/v1/draftReview.ts +431 -0
  72. package/extension/{doors → pi/v1}/draftReviewWaveTools.ts +141 -151
  73. package/extension/pi/v1/gist.ts +794 -0
  74. package/extension/pi/v1/learning/audit.ts +186 -0
  75. package/extension/pi/v1/learning/dream.ts +207 -0
  76. package/extension/{doors/learnFactory.ts → pi/v1/learning/factory.ts} +18 -65
  77. package/extension/{doors/harvestWaveTools.ts → pi/v1/learning/harvest.ts} +46 -100
  78. package/extension/pi/v1/learning/learn.ts +585 -0
  79. package/extension/pi/v1/lifecycleGates.ts +127 -0
  80. package/extension/{factories → pi/v1}/objective.ts +53 -33
  81. package/extension/pi/v1/objectiveAuthoring.ts +672 -0
  82. package/extension/pi/v1/objectiveDreamGate.ts +160 -0
  83. package/extension/{factories/objectivePlan.ts → pi/v1/objectivePlanning.ts} +328 -533
  84. package/extension/pi/v1/objectiveRefinement.ts +1320 -0
  85. package/extension/pi/v1/objectiveReview.ts +451 -0
  86. package/extension/{doors → pi/v1}/objectiveReviewBrowser.ts +259 -172
  87. package/extension/pi/v1/plan.ts +812 -0
  88. package/extension/pi/v1/planReview.ts +820 -0
  89. package/extension/{doors → pi/v1}/planReviewBrowser.ts +228 -152
  90. package/extension/{doors/annotationPush.ts → pi/v1/providers/annotations.ts} +158 -89
  91. package/extension/pi/v1/providers/plannotator.ts +487 -0
  92. package/extension/{doors → pi/v1/providers}/plannotatorHandoff.ts +73 -27
  93. package/extension/pi/v1/providers/selection.ts +43 -0
  94. package/extension/{adapters/planAdapterTombell.ts → pi/v1/providers/tombell.ts} +43 -72
  95. package/extension/pi/v1/review.ts +538 -0
  96. package/extension/pi/v1/reviewOutcome.ts +9 -0
  97. package/extension/pi/v1/scoutWave.ts +318 -0
  98. package/extension/{doors → pi/v1}/selfcheck.ts +4 -4
  99. package/extension/session/branchWorkflowSession.ts +60 -0
  100. package/extension/session/lifecycle.ts +644 -0
  101. package/extension/session/lifecycleGates.ts +64 -0
  102. package/extension/session/saveDestination.ts +87 -0
  103. package/extension/session/workflowSession.ts +971 -0
  104. package/extension/substrate/agentScratch.ts +27 -54
  105. package/extension/substrate/bashScanTimeout.ts +181 -0
  106. package/extension/substrate/bindingDelivery.ts +38 -30
  107. package/extension/substrate/bindings.ts +4 -5
  108. package/extension/substrate/cache.ts +64 -12
  109. package/extension/substrate/childRestrictions.ts +39 -0
  110. package/extension/substrate/coldDoor.ts +17 -1
  111. package/extension/substrate/config.ts +157 -21
  112. package/extension/substrate/git.ts +88 -6
  113. package/extension/substrate/modelVisible.ts +53 -0
  114. package/extension/substrate/prompts.ts +22 -0
  115. package/extension/substrate/registry.ts +2 -0
  116. package/extension/substrate/resolverLease.ts +5 -4
  117. package/extension/substrate/sessionData.ts +85 -152
  118. package/extension/substrate/toolGating.ts +263 -84
  119. package/extension/substrate/unifiedDiff.ts +1 -1
  120. package/extension/substrate/workflowState.ts +178 -163
  121. package/extension/substrate/worktreeResolverLock.ts +261 -0
  122. package/extension/surfaces/surfaces.ts +79 -27
  123. package/extension/waves/adversarialReviewWave.ts +87 -46
  124. package/extension/waves/blockedReports.ts +59 -0
  125. package/extension/waves/draftReviewWave.ts +42 -42
  126. package/extension/waves/laneIdentity.ts +77 -0
  127. package/extension/waves/objectiveExplorerWave.ts +24 -24
  128. package/extension/waves/prReviewWave.ts +89 -77
  129. package/extension/waves/reportWave.ts +438 -578
  130. package/extension/waves/reviewClassifierWave.ts +22 -22
  131. package/extension/waves/rpcAdapter.ts +100 -15
  132. package/extension/waves/scoutWave.ts +192 -0
  133. package/extension/waves/transport.ts +480 -0
  134. package/extension/worker/sdkAdapter.ts +494 -0
  135. package/extension/worker/stageExecution.ts +679 -0
  136. package/extension/workerMain.ts +18 -19
  137. package/package.json +6 -4
  138. package/prompts/_fixtures/live.yaml +43 -18
  139. package/prompts/contexts/adapters/plannotator-gist.md +6 -0
  140. package/prompts/contexts/adapters/plannotator-objective.md +6 -0
  141. package/prompts/contexts/adapters/plannotator-plan.md +8 -1
  142. package/prompts/contexts/adapters/plannotator-refinement.md +22 -0
  143. package/prompts/contexts/objective-refinement.md +17 -0
  144. package/prompts/contexts/read-only.md +1 -1
  145. package/prompts/stages/conflict-resolution-continuation.md +9 -6
  146. package/prompts/stages/conflict-resolution.md +4 -4
  147. package/prompts/stages/objective-plan/guidance.md +2 -2
  148. package/prompts/stages/objective-plan/seed.md +9 -1
  149. package/prompts/stages/objective-reconcile-ready.md +1 -1
  150. package/prompts/stages/objective-reconcile.md +1 -1
  151. package/prompts/stages/objective-refine/seed.md +18 -0
  152. package/prompts/stages/objective-review-browser.md +4 -4
  153. package/prompts/stages/objective-sync.md +1 -1
  154. package/prompts/stages/plan-review-browser.md +4 -4
  155. package/prompts/stages/pr-review-browser/active.md +3 -4
  156. package/prompts/stages/pr-review-browser/foreign.md +3 -4
  157. package/prompts/stages/pr-review-terminal/active.md +3 -3
  158. package/prompts/stages/pr-review-terminal/foreign.md +3 -3
  159. package/prompts/stages/pr-review.md +3 -3
  160. package/prompts/stages/stack-review-browser/stack.md +5 -6
  161. package/shared/README.md +8 -0
  162. package/shared/bindings.yaml +3 -3
  163. package/shared/contracts.md +2601 -506
  164. package/shared/fixtures/issues-table.json +130 -0
  165. package/shared/registry.yaml +13 -0
  166. package/shared/schemas/outputs/objective-node-engagement.schema.json +318 -0
  167. package/shared/schemas/outputs/objective-stack-status.schema.json +6 -1
  168. package/shared/schemas/outputs/pr-review-context.schema.json +54 -9
  169. package/shared/schemas/outputs/pr-review-stack-context.schema.json +196 -0
  170. package/extension/adapters/planAdapterPlannotator.ts +0 -362
  171. package/extension/doors/auditWaveTools.ts +0 -352
  172. package/extension/doors/ciExecutor.ts +0 -756
  173. package/extension/doors/commitCompact.ts +0 -251
  174. package/extension/doors/dreamWaveTools.ts +0 -489
  175. package/extension/doors/learn.ts +0 -668
  176. package/extension/doors/lifecycleGates.ts +0 -207
  177. package/extension/doors/objectiveStack.ts +0 -1543
  178. package/extension/doors/prReviewDynamic.ts +0 -276
  179. package/extension/doors/ready.ts +0 -279
  180. package/extension/doors/submit.ts +0 -373
  181. package/extension/doors/submitPrReview.ts +0 -505
  182. package/extension/factories/gistAuthor.ts +0 -94
  183. package/extension/factories/gistDraft.ts +0 -265
  184. package/extension/factories/gistSave.ts +0 -251
  185. package/extension/factories/implementHere.ts +0 -116
  186. package/extension/factories/objectiveAuthor.ts +0 -98
  187. package/extension/factories/objectiveDraft.ts +0 -466
  188. package/extension/factories/objectiveSave.ts +0 -366
  189. package/extension/factories/planDraft.ts +0 -140
  190. package/extension/factories/planMode.ts +0 -205
  191. package/extension/factories/planReview.ts +0 -1237
  192. package/extension/factories/planSave.ts +0 -604
  193. package/extension/factories/planTitle.ts +0 -141
  194. package/extension/substrate/structuredOutput.ts +0 -202
  195. package/extension/waves/auditWave.ts +0 -312
  196. package/extension/waves/harvestWave.ts +0 -399
  197. package/extension/waves/learnWave.ts +0 -155
  198. package/extension/waves/memoryAdapter.ts +0 -139
  199. package/extension/waves/prReviewDynamicWave.ts +0 -777
  200. package/extension/worker/readOnlySession.ts +0 -294
  201. package/extension/worker/worker.ts +0 -899
  202. package/prompts/stages/pr-review-dynamic.md +0 -7
@@ -1,205 +0,0 @@
1
- // perk-owned plan mode. The first consumer of the tool-gating primitive
2
- // (extension/substrate/toolGating.ts). This is the *toggle surface* on top of that structural gate: a
3
- // `/plan` command, a `Ctrl+Alt+P` shortcut, and a `--plan` flag all flip `gating.enter`/`exit`.
4
- // perk owns NO parallel enforcement here — the gate is the single read-only authority.
5
- //
6
- // It also injects the cooperative *plan-authoring* prompt layer (the gather-then-plan contract)
7
- // under its own `perk:plan-context` customType (display:false, once-only: branch-scan dedup'd on
8
- // the marker),
9
- // keyed directly off the read-only gate (read-only ⟹ plan in the main session). The
10
- // content is stripped from `context` when the gate is off — the same hygiene the gate applies to its
11
- // `perk:mode-context`. An optional `[workflow] plan_authoring` config addendum (extension/substrate/config.ts)
12
- // is appended when present.
13
- //
14
- // Grounded in pi's official `examples/extensions/plan-mode/` recipe, but perk adopts ONLY the
15
- // read-only authoring half: there is no in-session "execution mode" flip — perk separates plan
16
- // (read-only session) from implement (cold-door fresh worktree session), and progress tracking
17
- // lives in the implement session.
18
- //
19
- // REGISTRATION-TIME DEFERRAL, now THREE-TIER. `registerPlanMode` resolves the plan
20
- // provider id once at factory time and branches:
21
- // - `perk-plan` (and the fail-safe error path) → register EVERYTHING (the default path is the
22
- // hard guarantee, zero behavior change).
23
- // - `plannotator-plan` (AUGMENT posture) → register everything EXCEPT the `--plan` flag, the
24
- // `Ctrl+Alt+P` shortcut, and the `--plan` session_start handler: `@plannotator/pi-extension`
25
- // also registers that flag + shortcut, and duplicate flag/shortcut registration is the known
26
- // potentially-fatal Pi behavior — plannotator owns `--plan`/`Ctrl+Alt+P` exclusively while
27
- // perk keeps `/plan`, the authoring injection, and the read-only gate (plannotator augments
28
- // perk's plan flow via the planAdapterPlannotator `plan_review` bridge; it does not replace it).
29
- // - any other foreign id (tombell, REPLACE posture) → register NOTHING; the foreign package owns
30
- // `/plan`/`Ctrl+Alt+P`/`--plan` unambiguously (Pi suffixes duplicate command names, so
31
- // handler-time deferral alone is insufficient once the foreign package is loaded).
32
-
33
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
34
- import { registerPerkCommand } from "../substrate/command.ts";
35
- import { loadPerkConfig } from "../substrate/config.ts";
36
- import { render } from "../substrate/prompts.ts";
37
- import {
38
- loadProviders,
39
- PERK_PLAN_PROVIDER_ID,
40
- PLANNOTATOR_PLAN_PROVIDER_ID,
41
- resolveProviders,
42
- } from "../substrate/providers.ts";
43
- import type { ToolGating } from "../substrate/toolGating.ts";
44
- import { branchCarries, branchOf, rebuildWorkflowState } from "../substrate/workflowState.ts";
45
- import { report } from "../surfaces/report.ts";
46
- // `Key` via the surfaces re-export (keybinding vocabulary, not rich UI) — keeps pi-tui imports
47
- // structurally confined to the surfaces module (the surfacesGuard pi-tui import rule).
48
- import { Key } from "../surfaces/surfaces.ts";
49
- import { GIST_AUTHOR_STAGE } from "./gistAuthor.ts";
50
- import { OBJECTIVE_AUTHOR_STAGE } from "./objectiveAuthor.ts";
51
-
52
- /** The plan-authoring context customType (distinct from the gate's `perk:mode-context`). */
53
- export const PLAN_CONTEXT_TYPE = "perk:plan-context";
54
- const PLAN_MARKER = "[PLAN AUTHORING]";
55
-
56
- /**
57
- * The cooperative gather-then-plan contract. This is prompting, NOT enforcement (the gate is the
58
- * enforcement). It never leaks internal policy text — it tells the model how to materialize a
59
- * decision-complete plan an executor with zero prior context can follow. Per contracts.md §8.57
60
- * this mode context is the plan stage's DESIGNATED FLOW CARRIER in every plan-stage session
61
- * shape (seeded doors carry launch-shape deltas only; the `perk-plan` skill is the detail tier).
62
- * Durable anchors only, no line numbers.
63
- */
64
- export const PLAN_AUTHORING_CONTEXT = render("contexts/plan-authoring.md", {
65
- marker: PLAN_MARKER,
66
- });
67
-
68
- /** Build the full plan-authoring injection, appending the project config addendum when present. */
69
- export function planContextContent(cwd: string): string {
70
- const addendum = loadPerkConfig(cwd).planAuthoring;
71
- return addendum ? `${PLAN_AUTHORING_CONTEXT}\n\n${addendum.trim()}` : PLAN_AUTHORING_CONTEXT;
72
- }
73
-
74
- /**
75
- * The resolved `[providers] plan` selection id for `cwd`, read fresh per-event (no static state —
76
- * the same per-event-read shape `planContextContent(ctx.cwd)` uses). Fail-safe to the perk-plan
77
- * reference: any load/resolution failure returns the reference id so perk's own plan mode keeps
78
- * working — the default path is the hard guarantee. With the resolver's per-seam fail-open
79
- * fallbacks this catch narrows to genuine file-read/parse failures — logged loudly (consoleCapture
80
- * routes it into the session log), never swallowed: a silent catch here once masked a
81
- * version-skew throw and silently swapped the review surface to first-party.
82
- */
83
- export function resolvedPlanProviderId(cwd: string): string {
84
- try {
85
- return resolveProviders(loadPerkConfig(cwd).providers, loadProviders()).plan.id;
86
- } catch (error) {
87
- console.error(
88
- `perk: plan provider resolution failed — falling back to ${PERK_PLAN_PROVIDER_ID}: ${error}`,
89
- );
90
- return PERK_PLAN_PROVIDER_ID;
91
- }
92
- }
93
-
94
- /**
95
- * Whether perk's own plan-mode reference is the selected plan provider for `cwd`. When a foreign
96
- * plan provider is selected via `[providers] plan`, perk's authoring surface steps aside (defers).
97
- */
98
- export function isPerkPlanReferenceSelected(cwd: string): boolean {
99
- return resolvedPlanProviderId(cwd) === PERK_PLAN_PROVIDER_ID;
100
- }
101
-
102
- /**
103
- * Register the perk-owned plan-mode toggle surface over the read-only gate. Idempotent enter/exit (the gate
104
- * tracks its own on/off transition), fail-safe-headless (notify when UI, else stderr).
105
- */
106
- export function registerPlanMode(pi: ExtensionAPI, gating: ToolGating): void {
107
- // Three-tier registration branch (see the header comment): full registration for the reference
108
- // (fail-safe default), a PARTIAL vacate (skip only `--plan` + `Ctrl+Alt+P`) under the augment-
109
- // posture plannotator selection, and a full vacate under any other foreign selection (tombell).
110
- const providerId = resolvedPlanProviderId(process.cwd());
111
- const plannotatorSelected = providerId === PLANNOTATOR_PLAN_PROVIDER_ID;
112
- if (providerId !== PERK_PLAN_PROVIDER_ID && !plannotatorSelected) return;
113
-
114
- if (!plannotatorSelected) {
115
- pi.registerFlag("plan", {
116
- description: "Start in perk plan mode (read-only exploration + plan authoring).",
117
- type: "boolean",
118
- default: false,
119
- });
120
- }
121
-
122
- function announce(ctx: ExtensionContext, on: boolean): void {
123
- const message = on
124
- ? "plan mode ON — read-only exploration; author the plan, then review with plan_review (approval auto-saves; /plan-save is the manual failsafe)."
125
- : "plan mode OFF — full tool access restored.";
126
- report(ctx, "plan-mode", "info", message);
127
- }
128
-
129
- function toggle(ctx: ExtensionContext): void {
130
- if (gating.isActive()) {
131
- gating.exit(ctx);
132
- announce(ctx, false);
133
- } else {
134
- gating.enter(ctx);
135
- announce(ctx, true);
136
- }
137
- }
138
-
139
- registerPerkCommand(pi, "plan", {
140
- description: "Toggle perk plan mode (read-only exploration + plan authoring).",
141
- handler: async (_args, ctx) => toggle(ctx),
142
- });
143
-
144
- if (!plannotatorSelected) {
145
- pi.registerShortcut(Key.ctrlAlt("p"), {
146
- description: "Toggle perk plan mode",
147
- handler: async (ctx) => toggle(ctx),
148
- });
149
-
150
- // `--plan` cold start: enter read-only on session_start when the flag is set and the gate is
151
- // off. (index.ts's session_start already syncs the gate from the rebuilt `mode`; this layers
152
- // the flag on top for ad-hoc `pi --plan` interactive starts — the cold plan door drives
153
- // read-only via the handoff `mode`, not this flag.) Skipped under the plannotator selection
154
- // along with the flag itself (the flag no longer exists on perk's side).
155
- pi.on("session_start", async (_event, ctx) => {
156
- if (pi.getFlag("plan") === true && !gating.isActive()) {
157
- gating.enter(ctx);
158
- }
159
- });
160
- }
161
-
162
- // Inject the plan-authoring context while the read-only gate is active (display:false). The
163
- // exceptions: objective-author and gist-author sessions are ALSO read-only, but
164
- // objectiveAuthor.ts / gistAuthor.ts inject their own authoring contexts there — so plan mode
165
- // defers when the launched stage is either (the coupling break: plan-authoring context is no
166
- // longer keyed off the bare read-only gate).
167
- pi.on("before_agent_start", async (_event, ctx) => {
168
- if (!gating.isActive()) return;
169
- const branch = branchOf(ctx);
170
- const launchedStage = rebuildWorkflowState(branch).stage;
171
- if (launchedStage === OBJECTIVE_AUTHOR_STAGE || launchedStage === GIST_AUTHOR_STAGE) return;
172
- // Once-only: injected customs persist to the branch, so a live copy suppresses re-injection;
173
- // compaction dropping it makes the scan come up clean and the next turn re-injects.
174
- if (branchCarries(branch, PLAN_MARKER)) return;
175
- return {
176
- message: {
177
- customType: PLAN_CONTEXT_TYPE,
178
- content: planContextContent(ctx.cwd),
179
- display: false,
180
- },
181
- };
182
- });
183
-
184
- // Strip the stale plan-authoring marker from context when the gate is off (so it never lingers).
185
- pi.on("context", async (event) => {
186
- if (gating.isActive()) return;
187
- return {
188
- messages: event.messages.filter((m) => {
189
- const msg = m as { customType?: string; role?: string; content?: unknown };
190
- if (msg.customType === PLAN_CONTEXT_TYPE) return false;
191
- if (msg.role !== "user") return true;
192
- const content = msg.content;
193
- if (typeof content === "string") return !content.includes(PLAN_MARKER);
194
- if (Array.isArray(content)) {
195
- return !content.some(
196
- (c) =>
197
- (c as { type?: string; text?: string }).type === "text" &&
198
- ((c as { text?: string }).text ?? "").includes(PLAN_MARKER),
199
- );
200
- }
201
- return true;
202
- }),
203
- };
204
- });
205
- }