@mrclrchtr/supi-prompt-improver 0.0.0-stage → 9.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 (118) hide show
  1. package/README.md +68 -2
  2. package/node_modules/@mrclrchtr/supi-ask-user/README.md +204 -0
  3. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/README.md +137 -0
  4. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/package.json +73 -0
  5. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/api.ts +42 -0
  6. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/config/config.ts +342 -0
  7. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +363 -0
  8. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/config.ts +17 -0
  9. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/context/context-provider-registry.ts +36 -0
  10. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/context/context-tag.ts +31 -0
  11. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/context.ts +8 -0
  12. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/debug-identity.ts +11 -0
  13. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +313 -0
  14. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +120 -0
  15. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/debug.ts +14 -0
  16. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +41 -0
  17. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +64 -0
  18. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/index.ts +38 -0
  19. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/llm.ts +356 -0
  20. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  21. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +44 -0
  22. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/path.ts +2 -0
  23. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/project-roots.ts +170 -0
  24. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/project.ts +15 -0
  25. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  26. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/registry-utils.ts +93 -0
  27. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/report.ts +121 -0
  28. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/session-capabilities.ts +242 -0
  29. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/session-capability-profiles.ts +240 -0
  30. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/session-utils.ts +71 -0
  31. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/session.ts +47 -0
  32. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +105 -0
  33. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +454 -0
  34. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/settings.ts +36 -0
  35. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  36. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  37. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/terminal.ts +60 -0
  38. package/node_modules/@mrclrchtr/supi-ask-user/node_modules/@mrclrchtr/supi-core/src/tui.ts +141 -0
  39. package/node_modules/@mrclrchtr/supi-ask-user/package.json +68 -0
  40. package/node_modules/@mrclrchtr/supi-ask-user/src/api.ts +22 -0
  41. package/node_modules/@mrclrchtr/supi-ask-user/src/ask-user.ts +64 -0
  42. package/node_modules/@mrclrchtr/supi-ask-user/src/extension.ts +1 -0
  43. package/node_modules/@mrclrchtr/supi-ask-user/src/form-api.ts +106 -0
  44. package/node_modules/@mrclrchtr/supi-ask-user/src/normalize.ts +266 -0
  45. package/node_modules/@mrclrchtr/supi-ask-user/src/schema.ts +80 -0
  46. package/node_modules/@mrclrchtr/supi-ask-user/src/session/controller.ts +314 -0
  47. package/node_modules/@mrclrchtr/supi-ask-user/src/session/lock.ts +15 -0
  48. package/node_modules/@mrclrchtr/supi-ask-user/src/tool/ask_user/execute.ts +100 -0
  49. package/node_modules/@mrclrchtr/supi-ask-user/src/tool/ask_user/guidance.ts +19 -0
  50. package/node_modules/@mrclrchtr/supi-ask-user/src/tool/ask_user/register.ts +31 -0
  51. package/node_modules/@mrclrchtr/supi-ask-user/src/tool/ask_user/render.ts +238 -0
  52. package/node_modules/@mrclrchtr/supi-ask-user/src/tool/ask_user/result.ts +151 -0
  53. package/node_modules/@mrclrchtr/supi-ask-user/src/tool/ask_user/spec.ts +14 -0
  54. package/node_modules/@mrclrchtr/supi-ask-user/src/types.ts +131 -0
  55. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/choose-renderer.ts +27 -0
  56. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form-component.ts +752 -0
  57. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form-question-render.ts +173 -0
  58. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form-render-primitives.ts +73 -0
  59. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form-render.ts +329 -0
  60. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form-review-render.ts +152 -0
  61. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form-view.ts +29 -0
  62. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form-viewport.ts +92 -0
  63. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/form.ts +35 -0
  64. package/node_modules/@mrclrchtr/supi-ask-user/src/ui/types.ts +54 -0
  65. package/node_modules/@mrclrchtr/supi-core/README.md +137 -0
  66. package/node_modules/@mrclrchtr/supi-core/package.json +73 -0
  67. package/node_modules/@mrclrchtr/supi-core/src/api.ts +42 -0
  68. package/node_modules/@mrclrchtr/supi-core/src/config/config.ts +342 -0
  69. package/node_modules/@mrclrchtr/supi-core/src/config/prompt-surface.ts +363 -0
  70. package/node_modules/@mrclrchtr/supi-core/src/config.ts +17 -0
  71. package/node_modules/@mrclrchtr/supi-core/src/context/context-provider-registry.ts +36 -0
  72. package/node_modules/@mrclrchtr/supi-core/src/context/context-tag.ts +31 -0
  73. package/node_modules/@mrclrchtr/supi-core/src/context.ts +8 -0
  74. package/node_modules/@mrclrchtr/supi-core/src/debug-identity.ts +11 -0
  75. package/node_modules/@mrclrchtr/supi-core/src/debug-registry.ts +313 -0
  76. package/node_modules/@mrclrchtr/supi-core/src/debug-timing.ts +120 -0
  77. package/node_modules/@mrclrchtr/supi-core/src/debug.ts +14 -0
  78. package/node_modules/@mrclrchtr/supi-core/src/evidence-badge.ts +41 -0
  79. package/node_modules/@mrclrchtr/supi-core/src/footer-registry.ts +64 -0
  80. package/node_modules/@mrclrchtr/supi-core/src/index.ts +38 -0
  81. package/node_modules/@mrclrchtr/supi-core/src/llm.ts +356 -0
  82. package/node_modules/@mrclrchtr/supi-core/src/model-selection.ts +134 -0
  83. package/node_modules/@mrclrchtr/supi-core/src/path-utils.ts +44 -0
  84. package/node_modules/@mrclrchtr/supi-core/src/path.ts +2 -0
  85. package/node_modules/@mrclrchtr/supi-core/src/project-roots.ts +170 -0
  86. package/node_modules/@mrclrchtr/supi-core/src/project.ts +15 -0
  87. package/node_modules/@mrclrchtr/supi-core/src/prompt-surface.ts +4 -0
  88. package/node_modules/@mrclrchtr/supi-core/src/registry-utils.ts +93 -0
  89. package/node_modules/@mrclrchtr/supi-core/src/report.ts +121 -0
  90. package/node_modules/@mrclrchtr/supi-core/src/session-capabilities.ts +242 -0
  91. package/node_modules/@mrclrchtr/supi-core/src/session-capability-profiles.ts +240 -0
  92. package/node_modules/@mrclrchtr/supi-core/src/session-utils.ts +71 -0
  93. package/node_modules/@mrclrchtr/supi-core/src/session.ts +47 -0
  94. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-registry.ts +105 -0
  95. package/node_modules/@mrclrchtr/supi-core/src/settings/settings-schema.ts +454 -0
  96. package/node_modules/@mrclrchtr/supi-core/src/settings.ts +36 -0
  97. package/node_modules/@mrclrchtr/supi-core/src/spinner-frames.ts +11 -0
  98. package/node_modules/@mrclrchtr/supi-core/src/status-spinner.ts +68 -0
  99. package/node_modules/@mrclrchtr/supi-core/src/terminal.ts +60 -0
  100. package/node_modules/@mrclrchtr/supi-core/src/tui.ts +141 -0
  101. package/package.json +70 -4
  102. package/src/config.ts +46 -0
  103. package/src/context.ts +184 -0
  104. package/src/diagnostic-data.ts +398 -0
  105. package/src/diagnostic-snapshot.ts +209 -0
  106. package/src/diagnostics.ts +181 -0
  107. package/src/draft.ts +188 -0
  108. package/src/extension.ts +191 -0
  109. package/src/model-request.ts +314 -0
  110. package/src/model.ts +15 -0
  111. package/src/proposal-review.ts +111 -0
  112. package/src/protocol.ts +134 -0
  113. package/src/response.ts +103 -0
  114. package/src/ui-primitives.ts +82 -0
  115. package/src/ui-review.ts +193 -0
  116. package/src/ui.ts +371 -0
  117. package/src/workflow-types.ts +25 -0
  118. package/src/workflow.ts +276 -0
package/README.md CHANGED
@@ -1,3 +1,69 @@
1
- # Temporary Holding Version
1
+ # @mrclrchtr/supi-prompt-improver
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Command-based prompt improvement for the [pi coding agent](https://github.com/earendil-works/pi).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pi install npm:@mrclrchtr/supi-prompt-improver
9
+ pi install npm:@mrclrchtr/supi-settings
10
+ ```
11
+
12
+ The model picker is provided by `@mrclrchtr/supi-settings`. Install it separately. Prompt improver does not bundle that extension because another installed copy may already register `/supi-settings`. After both installs, run `/reload` in Pi to use the model picker. The package also loads the shared Ask User form that it needs for clarification.
13
+
14
+ ## Configuration
15
+
16
+ Open `/supi-settings` → **Prompt improver** → **Improver model**. The default is `disabled`. Select a model to enable improvement. The command does not use the main model as a fallback.
17
+
18
+ ## Use
19
+
20
+ 1. Run `/supi-improve [draft]` while Pi is idle in TUI mode.
21
+ 2. Enter or edit the draft in the local form. Command arguments prefill this form.
22
+ 3. Confirm the draft. The command copies it to the main editor before improvement starts.
23
+ 4. Answer clarification questions if needed. The command can ask questions in one Ask User form, within the shared form limits.
24
+ 5. Review the proposal. Accept it to replace the editor text, or dismiss it to keep the confirmed draft.
25
+ 6. Make any further changes in the main editor, then submit the request yourself.
26
+
27
+ Pi clears the main editor before the command runs. The command cannot restore text that Pi cleared when you entered the command.
28
+
29
+ Acceptance does not submit the request. Dismissal, cancellation, an error, or an unchanged result keeps the confirmed draft unless another action has changed the editor or session. The feature does not add an undo action or store an undo record.
30
+
31
+ Each invocation uses one temporary conversation kept in memory. A clear draft needs one model request. If clarification is needed, the submitted form continues that conversation with one final request. The feature does not open a Pi child session or carry this conversation into the next invocation.
32
+
33
+ ## Privacy
34
+
35
+ The selected provider receives the confirmed draft and the context categories shown in the proposal screen. Context can include already-loaded project guidance, recent projected user and assistant text, and one available session summary. It does not include tool results, tool arguments, skills, or the full system prompt. The command does not scan files, call tools, use the web, or make a summary request.
36
+
37
+ The draft controls the request's intent. Context is background only. Assistant messages are treated as claims, not verified facts.
38
+
39
+ By default, the feature does not retain drafts, answers, proposals, or response content in diagnostics. Pi can keep the submitted command text in its normal history. Provider retention rules still apply.
40
+
41
+ ## Optional diagnostics
42
+
43
+ Prompt-improver diagnostics are off by default. To enable them, install `@mrclrchtr/supi-debug` and turn on **Debug > Enabled** in `/supi-settings`. The shared debug registry keeps events in memory. The `supi-debug` extension also persists sanitized events as custom entries in the current Pi session. Prompt improver does not depend on or call that extension directly.
44
+
45
+ When enabled, diagnostics can contain the confirmed draft, selected context, prepared request, provider response snapshot, clarification questions and answers, proposal, and error details. These can include private content. Events use sanitized `data`, never `rawData`, and obey the shared `agentAccess` setting. Secret redaction is best-effort; it may not remove every secret. Review the content before you enable capture or share a session file. Setting **Agent Access** to `off` blocks access through the debug tool but does not stop capture. Turn **Enabled** off to stop new capture. This does not remove events already written to a session file.
46
+
47
+ Capture has size limits, but these limits do not make captured content private. See the [diagnostics contract](SPEC.md#opt-in-diagnostics) for exact limits and provider-field rules.
48
+
49
+ Use `/supi-debug source=prompt-improver` to inspect current events. The report displays matched content in the session. For an earlier session, add `sessionFile=<path>` with the Pi session JSONL path. Historical events are sanitized. Keep the session file and any report private.
50
+
51
+ ## Text support
52
+
53
+ Input is text-only. Expanded text pastes are supported. Literal paths stay as text; the feature does not read those files. The feature rejects known unresolved Pi paste markers. It cannot detect every attachment from every custom editor and does not support attachment refinement.
54
+
55
+ ## Limits
56
+
57
+ - Draft: 32,000 Unicode code points.
58
+ - Loaded project guidance: 12,000 code points.
59
+ - Recent projected conversation: 12,000 code points and up to 12 messages.
60
+ - One session summary: 4,000 code points.
61
+ - Clarification: one form within the shared Ask User question limits.
62
+
63
+ The feature checks the complete conversation before each request, including clarification answers and comments. It drops optional context when needed. If required content still does not fit, it stops and keeps the confirmed draft. It does not trim the draft or answers, ask a second clarification round, or retry a rejected request.
64
+
65
+ ## Developer references
66
+
67
+ - [Behavior contract](SPEC.md): ownership, context, model requests, diagnostics, and acceptance criteria.
68
+ - [Domain terms](CONTEXT.md): draft, proposal, clarification, and improvement session.
69
+ - [Package guidance](CLAUDE.md): implementation safeguards and package checks.
@@ -0,0 +1,204 @@
1
+ <div align="center">
2
+ <a href="https://github.com/mrclrchtr/supi/tree/main/packages/supi-ask-user">
3
+ <img src="https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-ask-user/assets/social-preview.png" alt="SuPi Ask User" width="100%">
4
+ </a>
5
+ </div>
6
+
7
+ # @mrclrchtr/supi-ask-user — Ask-User Tool for Pi
8
+
9
+ [![GitHub stars](https://img.shields.io/github/stars/mrclrchtr/supi)](https://github.com/mrclrchtr/supi/stargazers) [![npm downloads](https://img.shields.io/npm/dm/@mrclrchtr/supi-ask-user)](https://www.npmjs.com/package/@mrclrchtr/supi-ask-user)
10
+
11
+ Adds `ask_user`, a structured decision-form tool for the [Pi coding agent](https://github.com/earendil-works/pi). The agent can stop at one decision, show a keyboard form, and continue with structured answers.
12
+
13
+ ## What it adds
14
+
15
+ - **One focused decision** — one blocking form contains 1-10 related questions.
16
+ - **Choice and text questions** — choose one option, choose multiple options, or enter free-form text.
17
+ - **Recommendations** — the agent can select or prefill a suggested answer. You can change it.
18
+ - **Option context** — focused options can show descriptions, trade-offs, consequences, or code samples.
19
+ - **Comments at each level** — add a form comment, a question comment, or a comment on a selected or unselected option.
20
+ - **Review before submission** — inspect each answer, edit a question, and see unanswered items.
21
+ - **Structured results** — complete forms return `submitted`. Forms with unanswered questions return `needs_discussion`.
22
+
23
+ ## Example requests
24
+
25
+ You can tell Pi when you want a structured handoff:
26
+
27
+ - “Before scaffolding the project, ask me about the package manager, test runner, and linting.”
28
+ - “If you find product decisions during implementation, collect the related questions into one form.”
29
+ - “Show the trade-offs beside each migration option before I choose.”
30
+ - “Ask me which findings to fix, and let me comment on individual choices.”
31
+
32
+ The agent is also guided to use `ask_user` only after inspecting what it can inspect itself—not for status updates, broad surveys, or facts it can determine from the repository.
33
+
34
+ ## How it works
35
+
36
+ 1. The agent calls `ask_user` with one focused decision and related questions.
37
+ 2. Pi opens a keyboard-driven form and pauses the agent.
38
+ 3. You answer, comment, or deliberately mark a question unanswered.
39
+ 4. The review screen lets you edit the form before submitting.
40
+ 5. The agent receives ordered, structured responses and continues from your decision.
41
+
42
+ Completed forms have the `decision` label in Pi's session tree. The result remains in chat history. Use the `app.tools.expand` keybinding (`Ctrl+O` by default) to expand it for read-only review.
43
+
44
+ ## See it in action
45
+
46
+ <table>
47
+ <tr>
48
+ <td align="center">
49
+ <img src="https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-ask-user/assets/ask-user-choice-details.png" width="100%" alt="Single-choice decision with a recommendation and side-by-side details" />
50
+ <br/>Single choice with recommendation and details
51
+ </td>
52
+ <td align="center">
53
+ <img src="https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-ask-user/assets/ask-user-multi-choice-details.png" width="100%" alt="Multi-select decision with recommendations and side-by-side details" />
54
+ <br/>Multi-select with recommendation and details
55
+ </td>
56
+ </tr>
57
+ <tr>
58
+ <td align="center">
59
+ <img src="https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-ask-user/assets/ask-user-text-input.png" width="100%" alt="Free-form text answer prefilled with a recommendation" />
60
+ <br/>Text answer with a recommendation
61
+ </td>
62
+ <td align="center">
63
+ <img src="https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-ask-user/assets/ask-user-question-comment.png" width="100%" alt="Question comment editor" />
64
+ <br/>Question comment
65
+ </td>
66
+ </tr>
67
+ <tr>
68
+ <td colspan="2" align="center">
69
+ <img src="https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-ask-user/assets/ask-user-review-form-comment.png" width="70%" alt="Review screen showing answers, an unanswered question, and a form comment" />
70
+ <br/>Review answers, comments, and unanswered questions
71
+ </td>
72
+ </tr>
73
+ </table>
74
+
75
+ ## Install
76
+
77
+ This package is in the recommended SuPi release stack. SuPi is pre-release.
78
+
79
+ Install it globally:
80
+
81
+ ```bash
82
+ pi install npm:@mrclrchtr/supi-ask-user
83
+ ```
84
+
85
+ Install it for one project:
86
+
87
+ ```bash
88
+ pi install npm:@mrclrchtr/supi-ask-user -l
89
+ ```
90
+
91
+ Try it for one run without a persistent install:
92
+
93
+ ```bash
94
+ pi -e npm:@mrclrchtr/supi-ask-user
95
+ ```
96
+
97
+ ## Keyboard controls
98
+
99
+ The form shows context-specific key hints at the bottom.
100
+
101
+ | Key | Action |
102
+ |---|---|
103
+ | `↑` `↓` | Move through choices or review rows; at the first or last row, scroll surrounding content |
104
+ | `Alt+Page Up` / `Alt+Page Down` | Scroll the outer form while editing text or comments |
105
+ | `Space` | Select a single choice or toggle a multi-select option |
106
+ | `Enter` | Accept an answer, save text or comments, edit a review row, or submit the form |
107
+ | `←` `→` | Move between choice questions; `←` returns from review |
108
+ | `Tab` / `Shift+Tab` | Move forward or backward between questions |
109
+ | `c` / `Alt+C` | Comment on the current question (`Alt+C` for text questions) |
110
+ | `n` | Comment on the focused choice option |
111
+ | `u` / `Alt+U` | Mark the question unanswered (`Alt+U` for text questions) |
112
+ | `Esc` | Cancel the form; in a comment editor, discard unsaved comment text |
113
+
114
+ On wide terminals, option details appear beside the choices. On narrow terminals, they appear below the choices. Ask User uses up to 85% of the terminal height, capped at 36 rows. If a form is taller than its inline height limit, Ask User keeps the focused row visible and shows a scroll position indicator.
115
+
116
+ ## Requirements, defaults, and limits
117
+
118
+ - `ask_user` requires Pi's interactive TUI and custom component support. The tool is only registered in TUI sessions and is not offered to the model in RPC, JSON, or print mode.
119
+ - The package needs no additional binary, service, or API key.
120
+ - Only one form can be active. The tool uses sequential execution, so sibling tool calls do not run beside a live form.
121
+ - Cancelling a form cancels the current agent turn. It does not record a user response.
122
+ - All questions are expected for a complete submission. Mark a question unanswered to request discussion.
123
+ - A form contains 1-10 questions. A choice question contains 2-12 options with unique values.
124
+ - If a single-choice question has no recommendation, the first option is selected. A multi-select question has no selection by default.
125
+ - Titles can contain 120 characters. Headers can contain 60 characters. Intros and prompts can contain 4,000 characters. Text placeholders can contain 200 characters.
126
+ - Ask User reuses a compatible Pi custom editor for text and comments. It uses the default editor if the custom editor is not compatible.
127
+ - The model-visible result is limited to Pi's default 2,000 lines or 50 KB. The structured result remains available in the session transcript.
128
+
129
+ ## Model guidance configuration
130
+
131
+ You can change the model-facing tool description, prompt snippet, and guidelines. This configuration changes the instructions that Pi sends to the model. It does not change form behavior.
132
+
133
+ Use `~/.pi/agent/supi/config.json` for global configuration or `.pi/supi/config.json` for project configuration:
134
+
135
+ ```json
136
+ {
137
+ "ask-user": {
138
+ "tools": {
139
+ "ask_user": {
140
+ "promptSurface": {
141
+ "appendPromptGuidelines": [
142
+ "Use ask_user for release decisions that need maintainer approval."
143
+ ]
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ ```
150
+
151
+ The extension applies package defaults, then global values, then trusted project values. It ignores project prompt overrides unless Pi trusts the project and finds a trust-requiring project resource, such as `.pi/settings.json`.
152
+
153
+ `promptSurface` accepts `description`, `promptSnippet`, `promptGuidelines`, `prependPromptGuidelines`, and `appendPromptGuidelines`. Use `$reset` with an array of `description`, `promptSnippet`, or `promptGuidelines` to restore those fields to package defaults. Run `/reload` after you edit the file.
154
+
155
+ ## Public API
156
+
157
+ The package also provides a headless TypeScript API. Install the package and its schema dependency with your package manager:
158
+
159
+ ```bash
160
+ pnpm add @mrclrchtr/supi-ask-user typebox
161
+ ```
162
+
163
+ Import the explicit API subpath:
164
+
165
+ ```ts
166
+ import {
167
+ AskUserController,
168
+ normalizeQuestionnaire,
169
+ openAskUserForm,
170
+ type AskUserOutcome,
171
+ } from "@mrclrchtr/supi-ask-user/api";
172
+
173
+ const questionnaire = normalizeQuestionnaire({
174
+ questions: [
175
+ {
176
+ type: "text",
177
+ id: "notes",
178
+ header: "Notes",
179
+ prompt: "What must the agent know?",
180
+ },
181
+ ],
182
+ });
183
+
184
+ const controller = new AskUserController(questionnaire);
185
+ const outcome: AskUserOutcome = controller.outcome();
186
+
187
+ // Open the full form from an extension context.
188
+ const result = await openAskUserForm(questionnaire, {
189
+ ui: ctx.ui,
190
+ signal: ctx.signal,
191
+ });
192
+ ```
193
+
194
+ `openAskUserForm()` uses the shared form UI in Pi's editor area and one lock for all callers. Pass `overlay: true` to use a focused overlay instead. It returns structured answers or a cancel/abort result. It does not write to the session transcript or call `ctx.abort()`; the caller owns those actions. A caller can pass its own `AbortSignal`.
195
+
196
+ The API exports `AskUserParamsSchema`, `normalizeQuestionnaire`, `AskUserValidationError`, `AskUserController`, and `openAskUserForm()`. It also exports types for the form UI, normalized questions, responses, outcomes, tool details, and cancel or abort interaction results. The package root is not an import surface. Use `/api` for the library or `/extension` for the Pi extension entrypoint.
197
+
198
+ The package ships TypeScript source. A standalone consumer must use a runtime or build tool that can load TypeScript.
199
+
200
+ ## Privacy and security
201
+
202
+ Pi stores the tool result in the session. The active model receives a text summary of answers and comments. This package does not send a separate network request or start an external process.
203
+
204
+ Like all Pi extensions, this package runs with your user permissions. Review the package source before installation.
@@ -0,0 +1,137 @@
1
+ <div align="center">
2
+ <a href="https://github.com/mrclrchtr/supi/tree/main/packages/supi-core">
3
+ <img src="https://raw.githubusercontent.com/mrclrchtr/supi/main/packages/supi-core/assets/social-preview.png" alt="SuPi Core" width="100%">
4
+ </a>
5
+ </div>
6
+
7
+ # @mrclrchtr/supi-core
8
+
9
+ [![GitHub stars](https://img.shields.io/github/stars/mrclrchtr/supi)](https://github.com/mrclrchtr/supi/stargazers)
10
+
11
+ Shared infrastructure for SuPi extensions.
12
+
13
+ This is a **pure library** — it does not register any pi commands or tools. The `/supi-settings` command is now available through `@mrclrchtr/supi-settings`.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ pnpm add @mrclrchtr/supi-core
19
+ ```
20
+
21
+ ## Package surfaces
22
+
23
+ - `@mrclrchtr/supi-core/api` — reusable helpers for other packages and extensions
24
+ - `@mrclrchtr/supi-core/llm` — PI-owned direct model requests and JSON helpers
25
+ - `@mrclrchtr/supi-core/report` — shared text/report rendering helpers for TUI and plain-text summaries
26
+ - `@mrclrchtr/supi-core/tui` — shared terminal UI helpers for list titles, rows, menus, and descriptions
27
+
28
+ ## What you get from the API
29
+
30
+ ### Config helpers
31
+
32
+ - `loadSupiConfig()` — merged config with resolution order `defaults <- global <- project`
33
+ - `loadSupiConfigForScope()` — load one scope at a time for settings UIs
34
+ - `writeSupiConfig()` — persist values
35
+ - `replaceSupiConfigSection()` — replace one nested section while preserving other sections
36
+ - `removeSupiConfigKey()` — remove a key or override
37
+
38
+ Config file locations:
39
+
40
+ - global: `~/.pi/agent/supi/config.json`
41
+ - project: `.pi/supi/config.json`
42
+
43
+ ### Settings helpers
44
+
45
+ - `registerSettings(pi, module)` — register one canonical asynchronous settings module
46
+ - `defineConfigSettings(options)` — adapt a fixed SuPi config section to that module interface
47
+ - settings registry helpers and types for the `@mrclrchtr/supi-settings` configuration surface
48
+
49
+ ### Context helpers
50
+
51
+ - `wrapExtensionContext()` — wrap injected text in SuPi's `<extension-context>` tag
52
+
53
+ ### Model requests
54
+
55
+ - `completeModelRequest(ctx, model, context, options)` — send API-specific options through PI's model registry.
56
+ - `completeSimpleModelRequest(ctx, model, context, options)` — send provider-neutral options through `streamSimple().result()` on PI 0.86.0 or later. PI supplies model-derived output limits and context guards.
57
+ - `callWithJsonResponse()` — retry a registry request, extract JSON, and validate it with TypeBox.
58
+
59
+ Both completion helpers require a stable `affinityScope`. PI owns auth and endpoint resolution. The helpers keep cache retention defaults, exclude prompt content from the affinity ID, and add OpenCode headers only when the provider or exact model endpoint matches OpenCode. Use the simple helper when PI should manage output limits; the API-specific helper forwards the caller's limit unchanged.
60
+
61
+ ### Shared registries
62
+
63
+ - context-provider registry for `/supi-context`
64
+ - debug-event registry and monotonic phase timers for producers that want shared debug capture
65
+ - optional Debug Operation IDs for exact, directly owned public Tool-call correlation; ambient events stay uncorrelated
66
+ - settings registry used by `/supi-settings`
67
+
68
+ ### Project and session helpers
69
+
70
+ - project-root detection and directory walking helpers such as `findProjectRoot()` and `walkProject()`
71
+ - active-branch session helper: `getActiveBranchEntries()`
72
+ - terminal helpers such as `formatTitle()`, `signalWaiting()`, and `signalDone()`
73
+
74
+ ### TUI helpers
75
+
76
+ - `formatTuiTitleLine()` — use the shared title style in terminal lists
77
+ - `renderSelectableRow()` — render a selected row with an aligned value
78
+ - `renderDescriptionViewport()` — show a fixed-height description preview
79
+ - `renderTuiHintLine()` — render short key hints in one line
80
+ - `createSelectListMenu()` — build an action menu with shared key hints
81
+
82
+ ### Report helpers
83
+
84
+ - `clampReportWidth()` — enforce a minimum readable report width
85
+ - `formatReportTitle()` / `formatSectionHeader()` — shared themed headers
86
+ - `formatDimLine()` / `formatKeyValueLine()` — common summary rows
87
+ - `formatOverflowHint()` — consistent preview-overflow hints
88
+ - `wrapReportText()` — ANSI-aware wrapped report blocks with optional indentation
89
+
90
+ ## Example
91
+
92
+ ```ts
93
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
94
+ import {
95
+ defineConfigSettings,
96
+ loadSupiConfig,
97
+ registerSettings,
98
+ wrapExtensionContext,
99
+ } from "@mrclrchtr/supi-core/api";
100
+
101
+ export default function myExtension(pi: ExtensionAPI) {
102
+ const defaults = { enabled: true };
103
+ const config = loadSupiConfig("my-extension", process.cwd(), defaults);
104
+
105
+ registerSettings(
106
+ pi,
107
+ defineConfigSettings({
108
+ id: "my-extension",
109
+ label: "My Extension",
110
+ section: "my-extension",
111
+ defaults,
112
+ fields: [
113
+ {
114
+ kind: "boolean" as const,
115
+ key: "enabled",
116
+ label: "Enabled",
117
+ },
118
+ ],
119
+ }),
120
+ );
121
+
122
+ const message = wrapExtensionContext("my-extension", "hello", {
123
+ enabled: config.enabled,
124
+ });
125
+ void message;
126
+ }
127
+ ```
128
+
129
+ ## Source
130
+
131
+ - `src/api.ts` — exported library surface
132
+ - `src/config.ts` — shared config loading and writing
133
+ - `src/debug-registry.ts` — Debug domain surface, event state, retention, redaction, listeners, and queries
134
+ - `src/debug-timing.ts` — monotonic total and phase timers for Debug Event Producers
135
+ - `src/settings/` — settings registry, schema, scope resolution, and persistence
136
+ - `src/report.ts` — shared text/report rendering helpers
137
+ - `src/tui.ts` — shared terminal UI list and action-menu helpers
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@mrclrchtr/supi-core",
3
+ "version": "9.0.0",
4
+ "description": "Shared settings, configuration, reporting, and session infrastructure",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/mrclrchtr/supi.git",
9
+ "directory": "packages/supi-core"
10
+ },
11
+ "homepage": "https://github.com/mrclrchtr/supi/tree/main/packages/supi-core#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/mrclrchtr/supi/issues"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "keywords": [
19
+ "pi",
20
+ "pi-coding-agent",
21
+ "supi",
22
+ "extension-utils",
23
+ "settings",
24
+ "configuration"
25
+ ],
26
+ "type": "module",
27
+ "files": [
28
+ "src/**/*.ts",
29
+ "!__tests__"
30
+ ],
31
+ "peerDependencies": {
32
+ "@earendil-works/pi-ai": "*",
33
+ "@earendil-works/pi-coding-agent": "*",
34
+ "@earendil-works/pi-tui": "*",
35
+ "typebox": "*"
36
+ },
37
+ "peerDependenciesMeta": {
38
+ "@earendil-works/pi-ai": {
39
+ "optional": true
40
+ },
41
+ "@earendil-works/pi-coding-agent": {
42
+ "optional": true
43
+ },
44
+ "@earendil-works/pi-tui": {
45
+ "optional": true
46
+ },
47
+ "typebox": {
48
+ "optional": true
49
+ }
50
+ },
51
+ "main": "src/api.ts",
52
+ "exports": {
53
+ "./api": "./src/api.ts",
54
+ "./config": "./src/config.ts",
55
+ "./context": "./src/context.ts",
56
+ "./debug": "./src/debug.ts",
57
+ "./evidence-badge": "./src/evidence-badge.ts",
58
+ "./footer-registry": "./src/footer-registry.ts",
59
+ "./llm": "./src/llm.ts",
60
+ "./model-selection": "./src/model-selection.ts",
61
+ "./package.json": "./package.json",
62
+ "./path": "./src/path.ts",
63
+ "./project": "./src/project.ts",
64
+ "./prompt-surface": "./src/prompt-surface.ts",
65
+ "./report": "./src/report.ts",
66
+ "./session": "./src/session.ts",
67
+ "./settings": "./src/settings.ts",
68
+ "./spinner-frames": "./src/spinner-frames.ts",
69
+ "./status-spinner": "./src/status-spinner.ts",
70
+ "./terminal": "./src/terminal.ts",
71
+ "./tui": "./src/tui.ts"
72
+ }
73
+ }
@@ -0,0 +1,42 @@
1
+ // supi-core — shared infrastructure for SuPi extensions.
2
+ // Provides XML context tag wrapping, unified config, prompt-surface resolution,
3
+ // and shared settings, reporting, and session utilities.
4
+ //
5
+ // Convenience barrel — re-exports all domain entry points.
6
+ // For lighter imports, use one of the domain subpaths directly
7
+ // (e.g. @mrclrchtr/supi-core/config, @mrclrchtr/supi-core/context).
8
+
9
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
10
+ export * from "./config.ts";
11
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
12
+ export * from "./context.ts";
13
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
14
+ export * from "./debug.ts";
15
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
16
+ export * from "./evidence-badge.ts";
17
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
18
+ export * from "./footer-registry.ts";
19
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
20
+ export * from "./llm.ts";
21
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
22
+ export * from "./model-selection.ts";
23
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
24
+ export * from "./path.ts";
25
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
26
+ export * from "./project.ts";
27
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
28
+ export * from "./prompt-surface.ts";
29
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
30
+ export * from "./report.ts";
31
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
32
+ export * from "./session.ts";
33
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
34
+ export * from "./settings.ts";
35
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
36
+ export * from "./spinner-frames.ts";
37
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
38
+ export * from "./status-spinner.ts";
39
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
40
+ export * from "./terminal.ts";
41
+ // biome-ignore lint/performance/noReExportAll: intentional convenience barrel
42
+ export * from "./tui.ts";