@mgiles/perk 2.3.0 → 3.0.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 (128) hide show
  1. package/README.md +1 -1
  2. package/extension/adapters/planAdapterPlannotator.ts +132 -91
  3. package/extension/adapters/planAdapterTombell.ts +5 -3
  4. package/extension/doors/address.ts +235 -37
  5. package/extension/doors/annotationPush.ts +924 -0
  6. package/extension/doors/auditWaveTools.ts +352 -0
  7. package/extension/doors/ciExecutor.ts +220 -55
  8. package/extension/doors/draftReviewWaveTools.ts +384 -0
  9. package/extension/doors/harvestWaveTools.ts +279 -0
  10. package/extension/doors/land.ts +1 -0
  11. package/extension/doors/learn.ts +24 -6
  12. package/extension/doors/learnFactory.ts +33 -7
  13. package/extension/doors/lifecycleGates.ts +1 -1
  14. package/extension/doors/objectiveReviewBrowser.ts +514 -0
  15. package/extension/doors/objectiveStack.ts +1143 -0
  16. package/extension/doors/planReviewBrowser.ts +453 -0
  17. package/extension/doors/plannotatorHandoff.ts +120 -49
  18. package/extension/doors/prReview.ts +26 -16
  19. package/extension/doors/prReviewBrowser.ts +31 -23
  20. package/extension/doors/prReviewDynamic.ts +25 -18
  21. package/extension/doors/prReviewTerminal.ts +6 -11
  22. package/extension/doors/reviewWaveTools.ts +374 -0
  23. package/extension/doors/selfcheck.ts +1 -1
  24. package/extension/doors/submit.ts +82 -7
  25. package/extension/factories/gistAuthor.ts +4 -4
  26. package/extension/factories/gistDraft.ts +1 -1
  27. package/extension/factories/gistSave.ts +2 -2
  28. package/extension/factories/objective.ts +7 -7
  29. package/extension/factories/objectiveAuthor.ts +5 -4
  30. package/extension/factories/objectiveDraft.ts +61 -6
  31. package/extension/factories/objectivePlan.ts +163 -9
  32. package/extension/factories/objectiveSave.ts +16 -1
  33. package/extension/factories/planMode.ts +5 -3
  34. package/extension/factories/planReview.ts +131 -36
  35. package/extension/factories/planTitle.ts +27 -9
  36. package/extension/hunkFeedback/inbox.ts +389 -0
  37. package/extension/hunkFeedback/perkFeedback.ts +364 -0
  38. package/extension/hunkFeedback/receiver.ts +296 -0
  39. package/extension/hunkFeedback/store.ts +533 -0
  40. package/extension/index.ts +109 -44
  41. package/extension/substrate/cache.ts +75 -22
  42. package/extension/substrate/coldDoor.ts +2 -3
  43. package/extension/substrate/config.ts +36 -12
  44. package/extension/substrate/git.ts +10 -0
  45. package/extension/substrate/providers.ts +4 -33
  46. package/extension/substrate/resources.ts +11 -0
  47. package/extension/substrate/result.ts +13 -5
  48. package/extension/substrate/sessionData.ts +3 -3
  49. package/extension/substrate/sessionPointers.ts +3 -3
  50. package/extension/substrate/structuredOutput.ts +78 -19
  51. package/extension/substrate/toolGating.ts +170 -23
  52. package/extension/substrate/workflowState.ts +6 -0
  53. package/extension/surfaces/footerProvider.ts +6 -6
  54. package/extension/surfaces/surfaces.ts +98 -282
  55. package/extension/vendor/btw/btw.ts +57 -12
  56. package/extension/waves/adversarialReviewWave.ts +164 -0
  57. package/extension/waves/auditWave.ts +312 -0
  58. package/extension/waves/draftReviewWave.ts +189 -0
  59. package/extension/waves/harvestWave.ts +399 -0
  60. package/extension/waves/memoryAdapter.ts +14 -1
  61. package/extension/waves/objectiveExplorerWave.ts +120 -0
  62. package/extension/waves/prReviewDynamicWave.ts +291 -61
  63. package/extension/waves/prReviewWave.ts +58 -13
  64. package/extension/waves/reportWave.ts +406 -106
  65. package/extension/waves/reviewClassifierWave.ts +109 -0
  66. package/extension/waves/rpcAdapter.ts +65 -2
  67. package/extension/worker/readOnlySession.ts +3 -3
  68. package/extension/worker/worker.ts +71 -93
  69. package/extension/workerMain.ts +4 -6
  70. package/package.json +15 -5
  71. package/prompts/README.md +19 -0
  72. package/prompts/_fixtures/live.yaml +66 -65
  73. package/prompts/common/resume-advisory.md +1 -0
  74. package/prompts/contexts/adapters/plannotator-gist.md +13 -0
  75. package/prompts/contexts/adapters/plannotator-objective.md +1 -2
  76. package/prompts/contexts/adapters/plannotator-plan.md +1 -2
  77. package/prompts/contexts/gist-authoring.md +6 -20
  78. package/prompts/contexts/objective-authoring.md +6 -18
  79. package/prompts/stages/address/action.md +3 -14
  80. package/prompts/stages/address/preview.md +2 -13
  81. package/prompts/stages/audit.md +18 -0
  82. package/prompts/stages/gist-author/seed.md +4 -4
  83. package/prompts/stages/gist-save.md +1 -1
  84. package/prompts/stages/implement.md +3 -1
  85. package/prompts/stages/learn-code.md +1 -1
  86. package/prompts/stages/learn-docs.md +2 -2
  87. package/prompts/stages/learn-harvest.md +15 -0
  88. package/prompts/stages/learn-orchestrate.md +1 -1
  89. package/prompts/stages/objective-author/adopt.md +5 -3
  90. package/prompts/stages/objective-author/file.md +5 -4
  91. package/prompts/stages/objective-author/seed.md +5 -4
  92. package/prompts/stages/objective-land.md +7 -0
  93. package/prompts/stages/objective-plan/guidance.md +2 -13
  94. package/prompts/stages/objective-plan/seed.md +5 -12
  95. package/prompts/stages/objective-recover.md +8 -0
  96. package/prompts/stages/objective-replan.md +4 -2
  97. package/prompts/stages/objective-review-browser.md +9 -0
  98. package/prompts/stages/objective-sync.md +6 -0
  99. package/prompts/stages/plan-from/adopt.md +2 -2
  100. package/prompts/stages/plan-from/file.md +2 -2
  101. package/prompts/stages/plan-review-browser.md +9 -0
  102. package/prompts/stages/pr-review-browser/active.md +6 -14
  103. package/prompts/stages/pr-review-browser/foreign.md +6 -14
  104. package/prompts/stages/pr-review-dynamic.md +3 -3
  105. package/prompts/stages/pr-review-terminal/active.md +7 -15
  106. package/prompts/stages/pr-review-terminal/foreign.md +7 -15
  107. package/prompts/stages/pr-review.md +2 -2
  108. package/prompts/stages/replan.md +3 -3
  109. package/shared/README.md +2 -2
  110. package/shared/bindings.yaml +12 -0
  111. package/shared/contracts-history.md +11 -0
  112. package/shared/contracts.md +3652 -236
  113. package/shared/providers.yaml +27 -60
  114. package/shared/registry.yaml +32 -8
  115. package/shared/schemas/outputs/objective-doctor.schema.json +449 -0
  116. package/shared/schemas/outputs/objective-stack-land.schema.json +732 -0
  117. package/shared/schemas/outputs/objective-stack-recover.schema.json +397 -0
  118. package/shared/schemas/outputs/objective-stack-status.schema.json +577 -0
  119. package/shared/schemas/outputs/objective-stack-sync.schema.json +184 -0
  120. package/shared/schemas/outputs/plan-save.schema.json +12 -0
  121. package/shared/schemas/outputs/pr-submit.schema.json +177 -1
  122. package/extension/adapters/todoAdapterJuicesharp.ts +0 -102
  123. package/extension/checkpoints/checkpoints.ts +0 -550
  124. package/extension/checkpoints/planSteps.ts +0 -108
  125. package/extension/doors/askUser.ts +0 -198
  126. package/prompts/common/output-schemas/objective-explorer.md +0 -36
  127. package/prompts/common/output-schemas/review-classifier.md +0 -47
  128. package/prompts/contexts/adapters/juicesharp-todo.md +0 -7
@@ -0,0 +1,184 @@
1
+ {
2
+ "$defs": {
3
+ "ObjectiveOut": {
4
+ "additionalProperties": false,
5
+ "description": "The resolved (ACTIVE) objective identity; ``redirected_from`` names the originally\nrequested objective when a ``superseded_by`` chain redirected forward.",
6
+ "properties": {
7
+ "id": {
8
+ "title": "Id",
9
+ "type": "string"
10
+ },
11
+ "url": {
12
+ "title": "Url",
13
+ "type": "string"
14
+ },
15
+ "redirected_from": {
16
+ "anyOf": [
17
+ {
18
+ "type": "string"
19
+ },
20
+ {
21
+ "type": "null"
22
+ }
23
+ ],
24
+ "title": "Redirected From"
25
+ }
26
+ },
27
+ "required": [
28
+ "id",
29
+ "url",
30
+ "redirected_from"
31
+ ],
32
+ "title": "ObjectiveOut",
33
+ "type": "object"
34
+ },
35
+ "SyncedLayerOut": {
36
+ "additionalProperties": false,
37
+ "properties": {
38
+ "node_id": {
39
+ "title": "Node Id",
40
+ "type": "string"
41
+ },
42
+ "plan_id": {
43
+ "title": "Plan Id",
44
+ "type": "string"
45
+ },
46
+ "branch": {
47
+ "title": "Branch",
48
+ "type": "string"
49
+ },
50
+ "pr_number": {
51
+ "title": "Pr Number",
52
+ "type": "integer"
53
+ },
54
+ "before_sha": {
55
+ "title": "Before Sha",
56
+ "type": "string"
57
+ },
58
+ "after_sha": {
59
+ "title": "After Sha",
60
+ "type": "string"
61
+ }
62
+ },
63
+ "required": [
64
+ "node_id",
65
+ "plan_id",
66
+ "branch",
67
+ "pr_number",
68
+ "before_sha",
69
+ "after_sha"
70
+ ],
71
+ "title": "SyncedLayerOut",
72
+ "type": "object"
73
+ }
74
+ },
75
+ "additionalProperties": false,
76
+ "description": "The ``perk objective stack sync --json`` envelope (the \u00a78.49 result-arm table).\n``dry_run`` / ``adopted_node`` / ``continued`` / ``aborted`` are the additive\ncontrol-surface arms (declared last, order load-bearing).",
77
+ "properties": {
78
+ "success": {
79
+ "title": "Success",
80
+ "type": "boolean"
81
+ },
82
+ "objective": {
83
+ "$ref": "#/$defs/ObjectiveOut"
84
+ },
85
+ "operation_id": {
86
+ "anyOf": [
87
+ {
88
+ "type": "string"
89
+ },
90
+ {
91
+ "type": "null"
92
+ }
93
+ ],
94
+ "title": "Operation Id"
95
+ },
96
+ "abandoned_operation_id": {
97
+ "anyOf": [
98
+ {
99
+ "type": "string"
100
+ },
101
+ {
102
+ "type": "null"
103
+ }
104
+ ],
105
+ "title": "Abandoned Operation Id"
106
+ },
107
+ "no_op": {
108
+ "title": "No Op",
109
+ "type": "boolean"
110
+ },
111
+ "declined": {
112
+ "title": "Declined",
113
+ "type": "boolean"
114
+ },
115
+ "resumed": {
116
+ "title": "Resumed",
117
+ "type": "boolean"
118
+ },
119
+ "base_cascaded": {
120
+ "title": "Base Cascaded",
121
+ "type": "boolean"
122
+ },
123
+ "base_advanced": {
124
+ "title": "Base Advanced",
125
+ "type": "boolean"
126
+ },
127
+ "affected": {
128
+ "items": {
129
+ "$ref": "#/$defs/SyncedLayerOut"
130
+ },
131
+ "title": "Affected",
132
+ "type": "array"
133
+ },
134
+ "notes": {
135
+ "items": {
136
+ "type": "string"
137
+ },
138
+ "title": "Notes",
139
+ "type": "array"
140
+ },
141
+ "dry_run": {
142
+ "title": "Dry Run",
143
+ "type": "boolean"
144
+ },
145
+ "adopted_node": {
146
+ "anyOf": [
147
+ {
148
+ "type": "string"
149
+ },
150
+ {
151
+ "type": "null"
152
+ }
153
+ ],
154
+ "title": "Adopted Node"
155
+ },
156
+ "continued": {
157
+ "title": "Continued",
158
+ "type": "boolean"
159
+ },
160
+ "aborted": {
161
+ "title": "Aborted",
162
+ "type": "boolean"
163
+ }
164
+ },
165
+ "required": [
166
+ "success",
167
+ "objective",
168
+ "operation_id",
169
+ "abandoned_operation_id",
170
+ "no_op",
171
+ "declined",
172
+ "resumed",
173
+ "base_cascaded",
174
+ "base_advanced",
175
+ "affected",
176
+ "notes",
177
+ "dry_run",
178
+ "adopted_node",
179
+ "continued",
180
+ "aborted"
181
+ ],
182
+ "title": "ObjectiveStackSyncOut",
183
+ "type": "object"
184
+ }
@@ -123,6 +123,18 @@
123
123
  ],
124
124
  "default": null,
125
125
  "title": "Base"
126
+ },
127
+ "delivery_lineage": {
128
+ "anyOf": [
129
+ {
130
+ "type": "string"
131
+ },
132
+ {
133
+ "type": "null"
134
+ }
135
+ ],
136
+ "default": null,
137
+ "title": "Delivery Lineage"
126
138
  }
127
139
  },
128
140
  "required": [
@@ -1,5 +1,70 @@
1
1
  {
2
2
  "$defs": {
3
+ "DeliveryOperationOut": {
4
+ "additionalProperties": false,
5
+ "description": "The typed delivery operation nested in a stacked cascade result.",
6
+ "properties": {
7
+ "kind": {
8
+ "title": "Kind",
9
+ "type": "string"
10
+ },
11
+ "operation_id": {
12
+ "anyOf": [
13
+ {
14
+ "type": "string"
15
+ },
16
+ {
17
+ "type": "null"
18
+ }
19
+ ],
20
+ "title": "Operation Id"
21
+ },
22
+ "abandoned_operation_id": {
23
+ "anyOf": [
24
+ {
25
+ "type": "string"
26
+ },
27
+ {
28
+ "type": "null"
29
+ }
30
+ ],
31
+ "title": "Abandoned Operation Id"
32
+ },
33
+ "resumed": {
34
+ "title": "Resumed",
35
+ "type": "boolean"
36
+ },
37
+ "no_op": {
38
+ "title": "No Op",
39
+ "type": "boolean"
40
+ },
41
+ "affected": {
42
+ "items": {
43
+ "$ref": "#/$defs/SyncedLayerOut"
44
+ },
45
+ "title": "Affected",
46
+ "type": "array"
47
+ },
48
+ "notes": {
49
+ "items": {
50
+ "type": "string"
51
+ },
52
+ "title": "Notes",
53
+ "type": "array"
54
+ }
55
+ },
56
+ "required": [
57
+ "kind",
58
+ "operation_id",
59
+ "abandoned_operation_id",
60
+ "resumed",
61
+ "no_op",
62
+ "affected",
63
+ "notes"
64
+ ],
65
+ "title": "DeliveryOperationOut",
66
+ "type": "object"
67
+ },
3
68
  "PlanHeaderUpdateOut": {
4
69
  "additionalProperties": false,
5
70
  "description": "The serialization boundary of the picked :class:`issue_backend.PlanHeaderUpdate` subset\n(field order load-bearing).",
@@ -18,6 +83,31 @@
18
83
  "title": "PlanHeaderUpdateOut",
19
84
  "type": "object"
20
85
  },
86
+ "StackRefOut": {
87
+ "additionalProperties": false,
88
+ "description": "The native-stack facts of a stacked submit (field order load-bearing): the stack\nnumber, its total size, and this PR's 1-based bottom\u2192top position.",
89
+ "properties": {
90
+ "number": {
91
+ "title": "Number",
92
+ "type": "integer"
93
+ },
94
+ "size": {
95
+ "title": "Size",
96
+ "type": "integer"
97
+ },
98
+ "position": {
99
+ "title": "Position",
100
+ "type": "integer"
101
+ }
102
+ },
103
+ "required": [
104
+ "number",
105
+ "size",
106
+ "position"
107
+ ],
108
+ "title": "StackRefOut",
109
+ "type": "object"
110
+ },
21
111
  "SubmitPrOut": {
22
112
  "additionalProperties": false,
23
113
  "description": "The serialization boundary of the picked :class:`github.PullRequest` subset\n(field order load-bearing).",
@@ -47,6 +137,46 @@
47
137
  ],
48
138
  "title": "SubmitPrOut",
49
139
  "type": "object"
140
+ },
141
+ "SyncedLayerOut": {
142
+ "additionalProperties": false,
143
+ "description": "One affected suffix layer in the delivery-operation block.",
144
+ "properties": {
145
+ "node_id": {
146
+ "title": "Node Id",
147
+ "type": "string"
148
+ },
149
+ "plan_id": {
150
+ "title": "Plan Id",
151
+ "type": "string"
152
+ },
153
+ "branch": {
154
+ "title": "Branch",
155
+ "type": "string"
156
+ },
157
+ "pr_number": {
158
+ "title": "Pr Number",
159
+ "type": "integer"
160
+ },
161
+ "before_sha": {
162
+ "title": "Before Sha",
163
+ "type": "string"
164
+ },
165
+ "after_sha": {
166
+ "title": "After Sha",
167
+ "type": "string"
168
+ }
169
+ },
170
+ "required": [
171
+ "node_id",
172
+ "plan_id",
173
+ "branch",
174
+ "pr_number",
175
+ "before_sha",
176
+ "after_sha"
177
+ ],
178
+ "title": "SyncedLayerOut",
179
+ "type": "object"
50
180
  }
51
181
  },
52
182
  "additionalProperties": false,
@@ -125,6 +255,48 @@
125
255
  },
126
256
  "title": "Conflicts",
127
257
  "type": "array"
258
+ },
259
+ "delivery": {
260
+ "anyOf": [
261
+ {
262
+ "type": "string"
263
+ },
264
+ {
265
+ "type": "null"
266
+ }
267
+ ],
268
+ "title": "Delivery"
269
+ },
270
+ "stack": {
271
+ "anyOf": [
272
+ {
273
+ "$ref": "#/$defs/StackRefOut"
274
+ },
275
+ {
276
+ "type": "null"
277
+ }
278
+ ]
279
+ },
280
+ "operation_id": {
281
+ "anyOf": [
282
+ {
283
+ "type": "string"
284
+ },
285
+ {
286
+ "type": "null"
287
+ }
288
+ ],
289
+ "title": "Operation Id"
290
+ },
291
+ "operation": {
292
+ "anyOf": [
293
+ {
294
+ "$ref": "#/$defs/DeliveryOperationOut"
295
+ },
296
+ {
297
+ "type": "null"
298
+ }
299
+ ]
128
300
  }
129
301
  },
130
302
  "required": [
@@ -140,7 +312,11 @@
140
312
  "dry_run",
141
313
  "base",
142
314
  "mergeable",
143
- "conflicts"
315
+ "conflicts",
316
+ "delivery",
317
+ "stack",
318
+ "operation_id",
319
+ "operation"
144
320
  ],
145
321
  "title": "PrSubmitOut",
146
322
  "type": "object"
@@ -1,102 +0,0 @@
1
- // The FIRST 3rd-party todo adapter. A perk-owned, injection-only bridge that re-enables
2
- // `@juicesharp/rpiv-todo` as a REAL, selectable todo provider: it carries perk's implement-progress
3
- // discipline onto that package's checklist-overlay surface (the todo-seam mirror of
4
- // planAdapterTombell, which bridges the plan seam).
5
- //
6
- // INERT BY DEFAULT. This shim is ALWAYS registered in index.ts but does nothing unless the resolved
7
- // `[providers] todo` selection is `juicesharp-todo` (read fresh per-event via the same
8
- // `resolvedTodoProviderId` the reference checkpoints provider uses) AND the session is an active
9
- // workflow (`active_plan_ref != null`, the same gate the reference checkpoints provider seeds on).
10
- // On any non-juicesharp selection it injects nothing and only strips its own stale marker — zero
11
- // behavior change on the default path.
12
- //
13
- // WHAT IT DOES (and does NOT do):
14
- // - It injects a hidden (`display:false`, once-only: branch-scan dedup'd on the marker)
15
- // `perk:todo-adapter-juicesharp` context that tells the
16
- // model the foreign `@juicesharp/rpiv-todo` checklist overlay is the sole progress surface here
17
- // (perk's own checkpoints stepped aside) and directs it to carry perk's
18
- // implement-progress DISCIPLINE onto that overlay: seed it from the plan body's `## Steps` and
19
- // mark each item complete in order — the same gather-then-advance flow perk's checkpoints embody.
20
- // - It does NOT own, replace, or duplicate the read-only gate (Invariant 1) and NEVER calls
21
- // `setActiveTools` / registers a `tool_call` handler (the todo seam composes no shared primitive).
22
- // - It does NOT write perk's `perk:checkpoint` entry and does NOT revive perk's deferred marker
23
- // scanner (Correction 2): that entry is a transient TS-only progress overlay nothing downstream
24
- // consumes, and perk's render + scanner are already deferred. Re-populating it would
25
- // be dead duplication — the foreign overlay is the sole, uncontested progress surface.
26
- // - It adds NO registration-time vacating (Correction 1): unlike the plan seam (where perk and the
27
- // foreign package both register `/plan`, forcing Pi to suffix the duplicate), the todo seam has
28
- // no command-name collision — perk registers `/checkpoints`; the foreign overlay registers its
29
- // own differently-named command(s) — so the runtime deferral is already sufficient.
30
-
31
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
32
- import { resolvedTodoProviderId } from "../checkpoints/checkpoints.ts";
33
- import { render } from "../substrate/prompts.ts";
34
- import { JUICESHARP_TODO_PROVIDER_ID } from "../substrate/providers.ts";
35
- import { branchCarries, branchOf, rebuildWorkflowState } from "../substrate/workflowState.ts";
36
-
37
- /** The juicesharp todo-adapter bridge customType (distinct from checkpoints' `perk:checkpoint`). */
38
- export const TODO_ADAPTER_JUICESHARP_CONTEXT_TYPE = "perk:todo-adapter-juicesharp";
39
- const TODO_ADAPTER_JUICESHARP_MARKER = "[TODO ADAPTER: JUICESHARP]";
40
-
41
- /**
42
- * The bridge prompt: carries perk's implement-progress discipline onto the foreign checklist
43
- * overlay. Prompting, NOT enforcement (perk's checkpoint scanner is deferred under this selection).
44
- * Durable anchors only, no line numbers.
45
- */
46
- export const TODO_ADAPTER_JUICESHARP_CONTEXT = render("contexts/adapters/juicesharp-todo.md", {
47
- marker: TODO_ADAPTER_JUICESHARP_MARKER,
48
- });
49
-
50
- /** Whether the foreign `juicesharp-todo` provider is the selected todo provider for `cwd`. */
51
- export function isJuicesharpTodoSelected(cwd: string): boolean {
52
- return resolvedTodoProviderId(cwd) === JUICESHARP_TODO_PROVIDER_ID;
53
- }
54
-
55
- /**
56
- * Register the juicesharp todo adapter: an injection-only bridge, inert unless `[providers] todo =
57
- * "juicesharp-todo"` AND the session is an active workflow. It NEVER touches tool gating /
58
- * setActiveTools (Invariant 1) and never throws.
59
- */
60
- export function registerTodoAdapterJuicesharp(pi: ExtensionAPI): void {
61
- // Inject the bridge context while the foreign juicesharp-todo provider is selected AND a workflow
62
- // is active (active_plan_ref != null) — the same active-workflow scope the reference checkpoints
63
- // provider seeds on, so the bridge never reaches planning/objective sessions (display:false).
64
- pi.on("before_agent_start", async (_event, ctx) => {
65
- if (!isJuicesharpTodoSelected(ctx.cwd)) return;
66
- const branch = branchOf(ctx);
67
- if (rebuildWorkflowState(branch).active_plan_ref == null) return;
68
- // Once-only: injected customs persist to the branch, so a live copy suppresses re-injection;
69
- // compaction dropping it makes the scan come up clean and the next turn re-injects.
70
- if (branchCarries(branch, TODO_ADAPTER_JUICESHARP_MARKER)) return;
71
- return {
72
- message: {
73
- customType: TODO_ADAPTER_JUICESHARP_CONTEXT_TYPE,
74
- content: TODO_ADAPTER_JUICESHARP_CONTEXT,
75
- display: false,
76
- },
77
- };
78
- });
79
-
80
- // Strip the stale bridge marker from context when juicesharp-todo is no longer selected (same
81
- // hygiene the sibling adapters apply), so it never lingers across a deselect.
82
- pi.on("context", async (event, ctx) => {
83
- if (isJuicesharpTodoSelected(ctx.cwd)) return;
84
- return {
85
- messages: event.messages.filter((m) => {
86
- const msg = m as { customType?: string; role?: string; content?: unknown };
87
- if (msg.customType === TODO_ADAPTER_JUICESHARP_CONTEXT_TYPE) return false;
88
- if (msg.role !== "user") return true;
89
- const content = msg.content;
90
- if (typeof content === "string") return !content.includes(TODO_ADAPTER_JUICESHARP_MARKER);
91
- if (Array.isArray(content)) {
92
- return !content.some(
93
- (c) =>
94
- (c as { type?: string; text?: string }).type === "text" &&
95
- ((c as { text?: string }).text ?? "").includes(TODO_ADAPTER_JUICESHARP_MARKER),
96
- );
97
- }
98
- return true;
99
- }),
100
- };
101
- });
102
- }