@howaboua/pi-ask 0.0.18 → 0.0.19

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # @howaboua/pi-ask
2
2
 
3
+ ## 0.0.19
4
+
5
+ - Requires Node.js 22.19 or newer.
6
+ - Replaced the TypeBox dependency with Pi's native schema builders and validation.
7
+
3
8
  ## 0.0.18
4
9
 
5
10
  - Requires Pi 1.5 or newer.
package/README.md CHANGED
@@ -49,6 +49,7 @@ Set either value to `false`, then run `/reload`, to hide that template. The same
49
49
  ## TUI controls
50
50
 
51
51
  The panel uses Pi's active keybindings. The defaults are:
52
+
52
53
  - `Up` / `Down` — move through choices, free text, and comments
53
54
  - `Enter` — choose or edit the focused item, or save an edit
54
55
  - `Left` / `Right` — move between prompts and the review tab
package/ask/contracts.ts CHANGED
@@ -1,26 +1,43 @@
1
- import { StringEnum } from "@earendil-works/pi-ai";
2
- import { type Static, Type } from "typebox";
1
+ import {
2
+ arr,
3
+ bool,
4
+ lit,
5
+ obj,
6
+ oneOf,
7
+ opt,
8
+ type Static,
9
+ str,
10
+ } from "@earendil-works/pi-schema";
3
11
 
4
12
  const ASK_DELIVERIES = ["wait", "steer"] as const;
5
13
 
6
- const ChoiceSchema = Type.Object({
7
- label: Type.String(),
8
- description: Type.Optional(Type.String()),
9
- });
10
-
11
- const PromptSchema = Type.Object({
12
- title: Type.String(),
13
- body: Type.Optional(Type.String()),
14
- multiple: Type.Optional(Type.Boolean()),
15
- choices: Type.Optional(Type.Array(ChoiceSchema)),
16
- });
17
-
18
- export const AskParameters = Type.Object({
19
- help: Type.Optional(Type.Literal(true)),
20
- handoff: Type.Optional(Type.Boolean()),
21
- prompts: Type.Optional(Type.Array(PromptSchema)),
22
- delivery: Type.Optional(StringEnum(ASK_DELIVERIES)),
23
- });
14
+ const ChoiceSchema = obj(
15
+ {
16
+ label: str(),
17
+ description: opt(str()),
18
+ },
19
+ { open: true },
20
+ );
21
+
22
+ const PromptSchema = obj(
23
+ {
24
+ title: str(),
25
+ body: opt(str()),
26
+ multiple: opt(bool()),
27
+ choices: opt(arr(ChoiceSchema)),
28
+ },
29
+ { open: true },
30
+ );
31
+
32
+ export const AskParameters = obj(
33
+ {
34
+ help: opt({ ...lit(true), type: "boolean" }),
35
+ handoff: opt(bool()),
36
+ prompts: opt(arr(PromptSchema)),
37
+ delivery: opt({ ...oneOf(ASK_DELIVERIES), type: "string" }),
38
+ },
39
+ { open: true },
40
+ );
24
41
 
25
42
  export type PromptChoice = Static<typeof ChoiceSchema>;
26
43
 
package/ask/tool.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defineTool } from "@earendil-works/pi-coding-agent";
2
+ import { compile, type Static } from "@earendil-works/pi-schema";
2
3
  import { Text } from "@earendil-works/pi-tui";
3
- import { Check } from "typebox/value";
4
4
  import { AskParameters, type AskPrompt } from "./contracts.js";
5
5
  import {
6
6
  type AskCoordinatorOptions,
@@ -16,6 +16,8 @@ import {
16
16
  textContent,
17
17
  } from "./normalize.js";
18
18
 
19
+ const askValidator = compile(AskParameters);
20
+
19
21
  interface BlockedState {
20
22
  id: string;
21
23
  active: boolean;
@@ -57,13 +59,19 @@ export function createAskRuntime({
57
59
  const params = input === undefined ? {} : input;
58
60
  const problem = askInputProblem(params);
59
61
  if (problem) throw new Error(problem);
60
- if (!Check(AskParameters, params))
62
+ if (!askValidator.check(params))
61
63
  throw new Error(
62
64
  "Ask couldn't read these arguments. Call ask({}) for the supported format.",
63
65
  );
64
66
  return params;
65
67
  },
66
- async execute(toolCallId, params, signal, _onUpdate, ctx) {
68
+ async execute(
69
+ toolCallId,
70
+ params: Static<typeof AskParameters>,
71
+ signal,
72
+ _onUpdate,
73
+ ctx,
74
+ ) {
67
75
  if (isAskHelpInput(params)) {
68
76
  return {
69
77
  content: [
@@ -158,8 +166,15 @@ export function createAskRuntime({
158
166
  renderCall(args, theme, context) {
159
167
  if (isAskHelpInput(args))
160
168
  return new Text(theme.fg("toolTitle", theme.bold("ask help")), 0, 0);
161
- const count = Array.isArray(args.prompts) ? args.prompts.length : 0;
169
+ const prompts =
170
+ args && typeof args === "object" && "prompts" in args
171
+ ? args.prompts
172
+ : undefined;
173
+ const count = Array.isArray(prompts) ? prompts.length : 0;
162
174
  const label =
175
+ args &&
176
+ typeof args === "object" &&
177
+ "handoff" in args &&
163
178
  args.handoff === true
164
179
  ? "ask handoff "
165
180
  : isSteeringAskInput(args)
package/biome.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://biomejs.dev/schemas/2.6.3/schema.json",
2
+ "$schema": "https://biomejs.dev/schemas/2.6.6/schema.json",
3
3
  "vcs": {
4
4
  "enabled": true,
5
5
  "clientKind": "git",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@howaboua/pi-ask",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "Interactive decisions, review triage, and human handoffs for Pi.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,7 +23,7 @@
23
23
  "handoff"
24
24
  ],
25
25
  "engines": {
26
- "node": ">=20.6.0"
26
+ "node": ">=22.19.0"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"
@@ -44,11 +44,10 @@
44
44
  ]
45
45
  },
46
46
  "peerDependencies": {
47
- "@howaboua/pi-codex-conversion": ">=4.0.8",
47
+ "@howaboua/pi-codex-conversion": ">=4.0.10",
48
48
  "@earendil-works/pi-ai": ">=1.0.0",
49
49
  "@earendil-works/pi-coding-agent": ">=1.5.0",
50
- "@earendil-works/pi-tui": ">=1.0.0",
51
- "typebox": "*"
50
+ "@earendil-works/pi-tui": ">=1.0.0"
52
51
  },
53
52
  "peerDependenciesMeta": {
54
53
  "@howaboua/pi-codex-conversion": {
@@ -56,12 +55,11 @@
56
55
  }
57
56
  },
58
57
  "devDependencies": {
59
- "@howaboua/pi-codex-conversion": "4.0.8",
60
- "@biomejs/biome": "^2.6.3",
61
- "@earendil-works/pi-ai": "1.5.0",
62
- "@earendil-works/pi-coding-agent": "1.5.0",
63
- "@earendil-works/pi-tui": "1.5.0",
64
- "typebox": "1.4.3",
58
+ "@howaboua/pi-codex-conversion": "4.0.10",
59
+ "@biomejs/biome": "^2.6.6",
60
+ "@earendil-works/pi-ai": "1.5.2",
61
+ "@earendil-works/pi-coding-agent": "1.5.2",
62
+ "@earendil-works/pi-tui": "1.5.2",
65
63
  "typescript": "^7.0.2"
66
64
  },
67
65
  "scripts": {
@@ -73,5 +71,8 @@
73
71
  "pack:dry": "npm pack --dry-run"
74
72
  },
75
73
  "main": "index.ts",
76
- "exports": "./index.ts"
74
+ "exports": "./index.ts",
75
+ "dependencies": {
76
+ "@earendil-works/pi-schema": "1.5.2"
77
+ }
77
78
  }
package/prompts/fold.md CHANGED
@@ -11,6 +11,7 @@ $ARGUMENTS
11
11
  If no material follows the command, use the most recent lengthy report or structured list in the conversation.
12
12
 
13
13
  Call `ask` once with one prompt per independently decidable item:
14
+
14
15
  - Keep the title short.
15
16
  - Preserve concrete evidence, consequences, and recommendations in the body.
16
17
  - Use the source's natural choices. For review findings, default to Fix, Defer, and Reject.
package/prompts/grill.md CHANGED
@@ -11,6 +11,7 @@ $ARGUMENTS
11
11
  Use the working directory, web search, available skills, and any relevant tools to understand the thing before asking. Prefer finding answers yourself over asking me.
12
12
 
13
13
  Loop until ask is dismissed. There is no round limit:
14
+
14
15
  1. Investigate the relevant context.
15
16
  2. Use ask for the next set of decisions.
16
17
  3. After the first answer round, create docs/<short-name>.md.
@@ -18,6 +19,7 @@ Loop until ask is dismissed. There is no round limit:
18
19
  5. Keep updating the markdown file after each round.
19
20
 
20
21
  The markdown file is the current plan, not a transcript. Keep it ready to use if I stop at any point. Include:
22
+
21
23
  - goal
22
24
  - agreed decisions
23
25
  - important tradeoffs
@@ -28,6 +30,7 @@ The markdown file is the current plan, not a transcript. Keep it ready to use if
28
30
  Do not log every question and answer.
29
31
 
30
32
  When ask is dismissed, the grilling session is done. Then:
33
+
31
34
  - give a short summary of what was agreed
32
35
  - open the markdown file with $EDITOR if available
33
36
  - print the file path