pi-ask-user-questions 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -4
- package/extensions/ask-user.ts +10 -9
- package/package.json +56 -49
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ The exact guidelines, verbatim:
|
|
|
52
52
|
pi install npm:pi-ask-user-questions
|
|
53
53
|
|
|
54
54
|
# from git
|
|
55
|
-
pi install git:github.com/qunm00/pi-ask-user-questions@
|
|
55
|
+
pi install git:github.com/qunm00/pi-ask-user-questions@v0.1.1
|
|
56
56
|
|
|
57
57
|
# try it for one run without saving
|
|
58
58
|
pi -e npm:pi-ask-user-questions
|
|
@@ -97,9 +97,12 @@ These are deliberate, not oversights:
|
|
|
97
97
|
|
|
98
98
|
```bash
|
|
99
99
|
npm install
|
|
100
|
-
npm
|
|
101
|
-
npm
|
|
102
|
-
npm run
|
|
100
|
+
npm run verify # lint + typecheck + all 27 tests
|
|
101
|
+
npm test # 27 tests, includes a real npm pack + install + load check
|
|
102
|
+
npm run test:unit # skips the slow sandbox install check
|
|
103
|
+
npm run lint # biome
|
|
104
|
+
npm run lint:fix # biome --write
|
|
105
|
+
npm run typecheck # tsc --noEmit
|
|
103
106
|
|
|
104
107
|
# load it into a live pi without installing
|
|
105
108
|
pi -e ./extensions/ask-user.ts
|
|
@@ -122,6 +125,64 @@ one. Remove those shims once a harness release supports 0.87.
|
|
|
122
125
|
Because the harness substitutes `ctx.ui.*`, **no automated test can check terminal
|
|
123
126
|
rendering**. `/ask-demo` is the manual gate for that.
|
|
124
127
|
|
|
128
|
+
Linting is [Biome](https://biomejs.dev) for formatting and non-type-aware rules. It does
|
|
129
|
+
not replace `tsc`: Biome has no type information, so `npm run typecheck` is a separate and
|
|
130
|
+
non-redundant gate.
|
|
131
|
+
|
|
132
|
+
## Requirements
|
|
133
|
+
|
|
134
|
+
Node >= 22.19.0, which is pi's own floor. Staged publishing additionally needs npm 12+
|
|
135
|
+
(the release workflow pins it).
|
|
136
|
+
|
|
137
|
+
## Continuous integration
|
|
138
|
+
|
|
139
|
+
`.github/workflows/` has two workflows:
|
|
140
|
+
|
|
141
|
+
- **`ci.yml`** — lint, typecheck and test on Node 22.19 and 24, plus two package-specific
|
|
142
|
+
jobs: one asserts the published tarball is exactly `LICENSE`, `README.md`,
|
|
143
|
+
`extensions/ask-user.ts` and `package.json`, the other asserts the pi package metadata
|
|
144
|
+
(`pi-package` keyword, resolvable `pi.extensions` paths, no runtime dependencies).
|
|
145
|
+
A weekly job re-runs the suite against `pi@latest` to catch the compat shims breaking
|
|
146
|
+
before a user does.
|
|
147
|
+
- **`release.yml`** — on a `v*` tag, verifies the tag matches the `package.json` version, then
|
|
148
|
+
**stages** the package with `npm stage publish` rather than publishing it. Staging uploads
|
|
149
|
+
the tarball to the registry in a non-public state and does not prompt for 2FA, which is
|
|
150
|
+
what makes it usable from an automated workflow. Nothing becomes installable until a
|
|
151
|
+
maintainer approves it with 2FA:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npm stage list # see what is pending
|
|
155
|
+
npm stage download <stage-id> # optional: inspect the tarball first
|
|
156
|
+
npm stage approve <stage-id> # requires 2FA, makes it public
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
This uses npm trusted publishing (OIDC), so there is no long-lived `NPM_TOKEN` in
|
|
160
|
+
repository settings. Set up the trust relationship to grant **stage** publish:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
npm trust github \
|
|
164
|
+
--file release.yml \
|
|
165
|
+
--repo qunm00/pi-ask-user-questions \
|
|
166
|
+
--allow-stage-publish
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Two constraints worth knowing: the dist-tag is fixed at stage time and is immutable, and
|
|
170
|
+
short-lived tokens from a trust relationship can only run `npm stage publish` and
|
|
171
|
+
`npm publish` — which is why approval has to be a human step. The workflow pins npm 12+,
|
|
172
|
+
since staged publishing is not present in older npm.
|
|
173
|
+
|
|
174
|
+
Releasing:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npm version 0.1.0 # updates package.json
|
|
178
|
+
git tag -a v0.1.0 -m "Initial release"
|
|
179
|
+
git push origin main --follow-tags
|
|
180
|
+
# CI stages it; then approve:
|
|
181
|
+
npm stage list && npm stage approve <stage-id>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The tag must match the manifest version; the release workflow fails if it does not.
|
|
185
|
+
|
|
125
186
|
## License
|
|
126
187
|
|
|
127
188
|
MIT
|
package/extensions/ask-user.ts
CHANGED
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
* never invent an answer.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
import { Type } from "typebox";
|
|
34
33
|
import { defineTool, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
34
|
+
import { Type } from "typebox";
|
|
35
35
|
|
|
36
36
|
interface AskQuestion {
|
|
37
37
|
question: string;
|
|
@@ -92,11 +92,9 @@ async function askQuestions(
|
|
|
92
92
|
// An accidental Enter is likelier than a deliberate blank answer, so
|
|
93
93
|
// confirm once before recording it as a skip. Escape skips immediately.
|
|
94
94
|
if (answer !== undefined && answer.trim() === "") {
|
|
95
|
-
answer = await ctx.ui.input(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
{ signal },
|
|
99
|
-
);
|
|
95
|
+
answer = await ctx.ui.input(formatTitle(index, questions.length, question, "empty, Escape to skip"), undefined, {
|
|
96
|
+
signal,
|
|
97
|
+
});
|
|
100
98
|
if (signal?.aborted) {
|
|
101
99
|
aborted = true;
|
|
102
100
|
break;
|
|
@@ -138,11 +136,14 @@ function buildContent(details: AskDetails, requested: number): string {
|
|
|
138
136
|
);
|
|
139
137
|
}
|
|
140
138
|
|
|
141
|
-
const
|
|
139
|
+
const unanswered = requested - details.answers.length;
|
|
142
140
|
if (details.aborted) {
|
|
141
|
+
// Wording is deliberately about *answered*, not *shown*. An aborted
|
|
142
|
+
// dialog may have been on screen, so claiming it was never shown could
|
|
143
|
+
// be false; "did not get answered" is always true.
|
|
143
144
|
lines.push(
|
|
144
|
-
`The turn was interrupted
|
|
145
|
-
|
|
145
|
+
`The turn was interrupted after ${details.answers.length} of ${requested} question(s). ` +
|
|
146
|
+
`Do not assume answers to the ${unanswered} that were not answered.`,
|
|
146
147
|
);
|
|
147
148
|
}
|
|
148
149
|
|
package/package.json
CHANGED
|
@@ -1,51 +1,58 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
2
|
+
"name": "pi-ask-user-questions",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Let the agent ask you a question and type your answer. No multiple choice. Batch questions are answered consecutively.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"pi-package",
|
|
9
|
+
"pi",
|
|
10
|
+
"pi-extension"
|
|
11
|
+
],
|
|
12
|
+
"files": [
|
|
13
|
+
"extensions/**/*.ts",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"pi": {
|
|
18
|
+
"extensions": [
|
|
19
|
+
"./extensions/ask-user.ts"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"lint": "biome check .",
|
|
24
|
+
"lint:fix": "biome check --write .",
|
|
25
|
+
"typecheck": "tsc --noEmit",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:unit": "vitest run __tests__/ask-user.test.ts __tests__/mock-ui.test.ts __tests__/smoke.test.ts __tests__/edge-cases.test.ts",
|
|
28
|
+
"verify": "npm run lint && npm run typecheck && npm test"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"@earendil-works/pi-agent-core": "*",
|
|
32
|
+
"@earendil-works/pi-ai": "*",
|
|
33
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
34
|
+
"typebox": "*"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@biomejs/biome": "^2.5.14",
|
|
38
|
+
"@earendil-works/pi-agent-core": "0.87.1",
|
|
39
|
+
"@earendil-works/pi-ai": "0.87.1",
|
|
40
|
+
"@earendil-works/pi-coding-agent": "0.87.1",
|
|
41
|
+
"@marcfargas/pi-test-harness": "0.6.1",
|
|
42
|
+
"@types/node": "^26.6.3",
|
|
43
|
+
"typebox": "^1.1.38",
|
|
44
|
+
"typescript": "^5.8.3",
|
|
45
|
+
"vitest": "^3.1.4"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/qunm00/pi-ask-user-questions"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/qunm00/pi-ask-user-questions",
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/qunm00/pi-ask-user-questions/issues"
|
|
54
|
+
},
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=22.19.0"
|
|
57
|
+
}
|
|
51
58
|
}
|