@mgiles/perk 1.1.0 → 2.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 (93) hide show
  1. package/README.md +68 -44
  2. package/extension/adapters/planAdapterPlannotator.ts +27 -41
  3. package/extension/adapters/planAdapterTombell.ts +15 -28
  4. package/extension/adapters/todoAdapterJuicesharp.ts +10 -13
  5. package/extension/checkpoints/checkpoints.ts +19 -12
  6. package/extension/doors/address.ts +4 -4
  7. package/extension/doors/askUser.ts +12 -8
  8. package/extension/doors/ciExecutor.ts +21 -14
  9. package/extension/doors/hunkHandoff.ts +202 -0
  10. package/extension/doors/land.ts +31 -9
  11. package/extension/doors/learn.ts +2 -2
  12. package/extension/doors/learnFactory.ts +144 -0
  13. package/extension/doors/plannotatorHandoff.ts +509 -0
  14. package/extension/doors/prReview.ts +4 -4
  15. package/extension/doors/prReviewBrowser.ts +341 -0
  16. package/extension/doors/prReviewTerminal.ts +267 -0
  17. package/extension/doors/selfcheck.ts +238 -5
  18. package/extension/doors/submit.ts +20 -0
  19. package/extension/doors/submitPrReview.ts +408 -0
  20. package/extension/factories/objective.ts +15 -5
  21. package/extension/factories/objectiveAuthor.ts +15 -32
  22. package/extension/factories/objectiveDraft.ts +1 -1
  23. package/extension/factories/objectivePlan.ts +12 -10
  24. package/extension/factories/objectiveSave.ts +2 -2
  25. package/extension/factories/planMode.ts +22 -40
  26. package/extension/factories/planReview.ts +213 -191
  27. package/extension/factories/planSave.ts +7 -7
  28. package/extension/index.ts +83 -25
  29. package/extension/substrate/bindingDelivery.ts +32 -10
  30. package/extension/substrate/bindings.ts +4 -2
  31. package/extension/substrate/cache.ts +34 -7
  32. package/extension/substrate/clipboard.ts +81 -0
  33. package/extension/substrate/config.ts +88 -65
  34. package/extension/substrate/git.ts +43 -0
  35. package/extension/substrate/paths.ts +1 -1
  36. package/extension/substrate/prompts.ts +2 -2
  37. package/extension/substrate/providers.ts +62 -8
  38. package/extension/substrate/sessionPointers.ts +35 -6
  39. package/extension/substrate/structuredOutput.ts +3 -1
  40. package/extension/substrate/terminalLaunch.ts +178 -0
  41. package/extension/substrate/toolGating.ts +330 -79
  42. package/extension/substrate/toolParams.ts +7 -0
  43. package/extension/substrate/workflowState.ts +54 -2
  44. package/extension/surfaces/footerProvider.ts +8 -4
  45. package/extension/surfaces/surfaces.ts +330 -12
  46. package/extension/vendor/btw/btw.ts +10 -0
  47. package/extension/worker/readOnlySession.ts +19 -6
  48. package/extension/worker/worker.ts +77 -7
  49. package/extension/workerMain.ts +12 -13
  50. package/package.json +3 -3
  51. package/prompts/_fixtures/live.yaml +117 -2
  52. package/prompts/contexts/adapters/juicesharp-todo.md +7 -0
  53. package/prompts/contexts/adapters/plannotator-objective.md +7 -0
  54. package/prompts/contexts/adapters/plannotator-plan.md +6 -0
  55. package/prompts/contexts/adapters/tombell-plan.md +17 -0
  56. package/prompts/contexts/objective-authoring.md +20 -0
  57. package/prompts/contexts/plan-authoring.md +24 -0
  58. package/prompts/contexts/read-only.md +10 -0
  59. package/prompts/stages/conflict-resolution.md +1 -1
  60. package/prompts/stages/learn-code.md +1 -1
  61. package/prompts/stages/learn-docs.md +2 -2
  62. package/prompts/stages/learn-orchestrate.md +1 -1
  63. package/prompts/stages/objective-author/adopt.md +1 -1
  64. package/prompts/stages/objective-author/file.md +1 -1
  65. package/prompts/stages/objective-plan/guidance.md +1 -1
  66. package/prompts/stages/objective-plan/seed.md +1 -1
  67. package/prompts/stages/objective-reconcile.md +1 -1
  68. package/prompts/stages/objective-replan.md +1 -1
  69. package/prompts/stages/plan-from/adopt.md +2 -2
  70. package/prompts/stages/plan-from/file.md +2 -2
  71. package/prompts/stages/pr-review-browser/active.md +11 -0
  72. package/prompts/stages/pr-review-browser/foreign.md +11 -0
  73. package/prompts/stages/pr-review-terminal/active.md +12 -0
  74. package/prompts/stages/pr-review-terminal/foreign.md +13 -0
  75. package/prompts/stages/pr-review-terminal/local.md +4 -0
  76. package/prompts/stages/pr-review.md +1 -1
  77. package/prompts/stages/replan.md +2 -2
  78. package/prompts/stages/skills/create-from.md +1 -1
  79. package/prompts/stages/skills/create.md +1 -1
  80. package/prompts/stages/skills/refine.md +1 -1
  81. package/shared/README.md +22 -18
  82. package/shared/bindings.yaml +10 -2
  83. package/shared/contracts-history.md +24 -0
  84. package/shared/contracts.md +1442 -1787
  85. package/shared/providers.yaml +8 -1
  86. package/shared/registry.yaml +7 -8
  87. package/shared/schemas/inputs/review-submit-batch.schema.json +66 -0
  88. package/shared/schemas/outputs/pr-review-checkout.schema.json +69 -0
  89. package/shared/schemas/outputs/pr-review-cleanup.schema.json +54 -0
  90. package/shared/schemas/outputs/pr-review-submit.schema.json +64 -0
  91. package/extension/doors/learnCode.ts +0 -100
  92. package/extension/doors/learnDocs.ts +0 -100
  93. package/extension/doors/prReviewLocal.ts +0 -229
@@ -4,7 +4,8 @@
4
4
  // perk owns NO parallel enforcement here — the gate is the single read-only authority.
5
5
  //
6
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),
7
+ // under its own `perk:plan-context` customType (display:false, once-only: branch-scan dedup'd on
8
+ // the marker),
8
9
  // keyed directly off the read-only gate (read-only ⟹ plan in the main session). The
9
10
  // content is stripped from `context` when the gate is off — the same hygiene the gate applies to its
10
11
  // `perk:mode-context`. An optional `[workflow] plan_authoring` config addendum (extension/substrate/config.ts)
@@ -30,9 +31,9 @@
30
31
  // handler-time deferral alone is insufficient once the foreign package is loaded).
31
32
 
32
33
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
33
- import { Key } from "@earendil-works/pi-tui";
34
34
  import { registerPerkCommand } from "../substrate/command.ts";
35
35
  import { loadPerkConfig } from "../substrate/config.ts";
36
+ import { render } from "../substrate/prompts.ts";
36
37
  import {
37
38
  loadProviders,
38
39
  PERK_PLAN_PROVIDER_ID,
@@ -40,8 +41,11 @@ import {
40
41
  resolveProviders,
41
42
  } from "../substrate/providers.ts";
42
43
  import type { ToolGating } from "../substrate/toolGating.ts";
43
- import { branchOf, rebuildWorkflowState } from "../substrate/workflowState.ts";
44
+ import { branchCarries, branchOf, rebuildWorkflowState } from "../substrate/workflowState.ts";
44
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";
45
49
  import { OBJECTIVE_AUTHOR_STAGE } from "./objectiveAuthor.ts";
46
50
 
47
51
  /** The plan-authoring context customType (distinct from the gate's `perk:mode-context`). */
@@ -54,40 +58,9 @@ const PLAN_MARKER = "[PLAN AUTHORING]";
54
58
  * decision-complete plan an executor with zero prior context can follow (mirrors
55
59
  * skills/perk-plan/SKILL.md). Durable anchors only, no line numbers.
56
60
  */
57
- export const PLAN_AUTHORING_CONTEXT = `${PLAN_MARKER}
58
- You are authoring a perk plan in read-only mode — explore first, then write.
59
-
60
- Gather before you plan. Materialize four finding categories from real evidence:
61
- - Status: what exists today (the current behavior, where it lives).
62
- - Discoveries: concrete findings with real file paths and function/class names.
63
- - Corrections: assumptions that turned out wrong, and what is actually true.
64
- - Codebase evidence: the specific code you verified each decision against.
65
-
66
- Check \`docs/learned/\` for relevant prior art and gotchas before you plan. The ambient routing
67
- index in your system prompt points into the full catalog at \`docs/learned/index.md\`; when a
68
- routing cue matches your change, \`read\` that doc. This is a check, not a requirement — there may
69
- be nothing relevant to your change, and your plan does not need to be grounded in prior learnings.
70
-
71
- Write the plan so an executor (a future session, or another engineer) with zero prior context can
72
- implement it without guessing. Anchor every change durably — function/class names, behavioral
73
- descriptions, structural locations — never line numbers. Resolve every open choice before saving;
74
- a saved plan must leave no decisions to the implementer.
75
-
76
- When the plan is decision-complete, request a human review:
77
- - Keep the working draft current with plan_draft — the validated plan-draft artifact is what gets
78
- reviewed AND auto-saved.
79
- - Call the plan_review tool — the human reviews the plan in the configured review surface (perk's
80
- in-TUI editor review by default).
81
- - If the review is DENIED: revise per the feedback, rewrite the draft with plan_draft, then call
82
- plan_review again.
83
- - If the review is APPROVED: the plan is auto-saved and the session leaves read-only. Relay the
84
- save outcome — do NOT re-dump the plan as a final message and do NOT tell the user to run
85
- /plan-save.
86
- - If the review returns IMPLEMENT HERE: the human chose to implement without saving an issue —
87
- the session is read-write; implement the plan now in this checkout (edits only; leave git
88
- gestures to the user).
89
- - If plan_review reports it was skipped or unavailable (headless, dismissed, no surface): present
90
- the complete plan as your final message; the human runs /plan-save (the manual failsafe).`;
61
+ export const PLAN_AUTHORING_CONTEXT = render("contexts/plan-authoring.md", {
62
+ marker: PLAN_MARKER,
63
+ });
91
64
 
92
65
  /** Build the full plan-authoring injection, appending the project config addendum when present. */
93
66
  export function planContextContent(cwd: string): string {
@@ -98,13 +71,19 @@ export function planContextContent(cwd: string): string {
98
71
  /**
99
72
  * The resolved `[providers] plan` selection id for `cwd`, read fresh per-event (no static state —
100
73
  * the same per-event-read shape `planContextContent(ctx.cwd)` uses). Fail-safe to the perk-plan
101
- * reference: any load/resolution failure (corrupt bundled set, etc.) returns the reference id so
102
- * perk's own plan mode keeps working — the default path is the hard guarantee.
74
+ * reference: any load/resolution failure returns the reference id so perk's own plan mode keeps
75
+ * working — the default path is the hard guarantee. With the resolver's per-seam fail-open
76
+ * fallbacks this catch narrows to genuine file-read/parse failures — logged loudly (consoleCapture
77
+ * routes it into the session log), never swallowed: a silent catch here once masked a
78
+ * version-skew throw and silently swapped the review surface to first-party.
103
79
  */
104
80
  export function resolvedPlanProviderId(cwd: string): string {
105
81
  try {
106
82
  return resolveProviders(loadPerkConfig(cwd).providers, loadProviders()).plan.id;
107
- } catch {
83
+ } catch (error) {
84
+ console.error(
85
+ `perk: plan provider resolution failed — falling back to ${PERK_PLAN_PROVIDER_ID}: ${error}`,
86
+ );
108
87
  return PERK_PLAN_PROVIDER_ID;
109
88
  }
110
89
  }
@@ -185,6 +164,9 @@ export function registerPlanMode(pi: ExtensionAPI, gating: ToolGating): void {
185
164
  if (!gating.isActive()) return;
186
165
  const branch = branchOf(ctx);
187
166
  if (rebuildWorkflowState(branch).stage === OBJECTIVE_AUTHOR_STAGE) return;
167
+ // Once-only: injected customs persist to the branch, so a live copy suppresses re-injection;
168
+ // compaction dropping it makes the scan come up clean and the next turn re-injects.
169
+ if (branchCarries(branch, PLAN_MARKER)) return;
188
170
  return {
189
171
  message: {
190
172
  customType: PLAN_CONTEXT_TYPE,