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 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@v1
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 test # 19 tests, includes a real npm pack + install + load check
101
- npm run test:unit # skips the slow sandbox install check
102
- npm run typecheck # tsc --noEmit
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
@@ -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
- formatTitle(index, questions.length, question, "empty, Escape to skip"),
97
- undefined,
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 neverShown = requested - details.answers.length;
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 before ${neverShown} question(s) were shown. ` +
145
- "Do not assume answers to questions that were never asked.",
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
- "name": "pi-ask-user-questions",
3
- "version": "0.1.0",
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
- "test": "vitest run",
24
- "test:unit": "vitest run __tests__/ask-user.test.ts __tests__/mock-ui.test.ts __tests__/smoke.test.ts",
25
- "typecheck": "tsc --noEmit"
26
- },
27
- "peerDependencies": {
28
- "@earendil-works/pi-agent-core": "*",
29
- "@earendil-works/pi-ai": "*",
30
- "@earendil-works/pi-coding-agent": "*",
31
- "typebox": "*"
32
- },
33
- "devDependencies": {
34
- "@earendil-works/pi-agent-core": "0.87.1",
35
- "@earendil-works/pi-ai": "0.87.1",
36
- "@earendil-works/pi-coding-agent": "0.87.1",
37
- "@marcfargas/pi-test-harness": "0.6.1",
38
- "@types/node": "^26.6.3",
39
- "typebox": "^1.1.38",
40
- "typescript": "^5.8.3",
41
- "vitest": "^3.1.4"
42
- },
43
- "repository": {
44
- "type": "git",
45
- "url": "git+github.com/qunm00/pi-ask-user-questions.git"
46
- },
47
- "homepage": "https://github.com/qunm00/pi-ask-user-questions#readme",
48
- "bugs": {
49
- "url": "https://github.com/qunm00/pi-ask-user-questions/issues"
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
  }