pi-long-task 0.1.2 → 0.1.3

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
@@ -46,6 +46,18 @@ After installing, start `pi` in your target project and ask it to use the `pi_lo
46
46
 
47
47
  ## Usage
48
48
 
49
+ Use natural language:
50
+
51
+ ```text
52
+ Run a long task without commits to add tests for the parser and fix any failures.
53
+ ```
54
+
55
+ ```text
56
+ Run a long task with commits to implement the TODOs in @TODO.md.
57
+ ```
58
+
59
+ You can also call the tool explicitly.
60
+
49
61
  Run without commits:
50
62
 
51
63
  ```text
@@ -78,6 +90,8 @@ The tool has two inputs:
78
90
  - `inputText` is the request or TODO markdown to work on.
79
91
  - `commit` controls whether Pi Long Task may create git commits.
80
92
 
93
+ For natural-language requests, Pi Long Task routes phrases like "run a long task with commits" to the tool with commits enabled. If you ask for a long task without mentioning commits, commits stay disabled.
94
+
81
95
  No other public options are required.
82
96
 
83
97
  ## Commits and files
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-long-task",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "Pi extension for breaking down and running long coding tasks safely.",
6
6
  "keywords": [
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
2
 
3
3
  import { runCoordinator, type CoordinatorProgressUpdate, type CoordinatorResult } from "./coordinator.ts";
4
+ import { longTaskInputTransform } from "./input_router.ts";
4
5
  import { renderLongTaskToolCall, renderLongTaskToolResult } from "./render.ts";
5
6
  import { PiLongTaskParams } from "./types.ts";
6
7
 
@@ -22,10 +23,24 @@ function toolDetails(result: CoordinatorResult) {
22
23
  }
23
24
 
24
25
  export default function registerPiLongTaskExtension(pi: ExtensionAPI) {
26
+ pi.on("input", (event) => {
27
+ if (event.source === "extension") {
28
+ return { action: "continue" as const };
29
+ }
30
+
31
+ const transformed = longTaskInputTransform(event.text);
32
+ if (!transformed) {
33
+ return { action: "continue" as const };
34
+ }
35
+
36
+ return { action: "transform" as const, text: transformed };
37
+ });
38
+
25
39
  pi.registerTool({
26
40
  name: "pi_long_task",
27
41
  label: "Pi Long Task",
28
- description: "Break down and run long coding tasks from a request or TODO plan.",
42
+ description:
43
+ "Run long or multi-step coding tasks from a request or TODO plan. Use this when the user asks to run/start/handle a long task; set commit true only when they ask for commits or committing as work progresses.",
29
44
  parameters: PiLongTaskParams,
30
45
  renderCall: renderLongTaskToolCall,
31
46
  renderResult: renderLongTaskToolResult,
@@ -0,0 +1,57 @@
1
+ const LONG_TASK_RE = /\b(?:long[-\s]?task|longtask|large[-\s]?task|big[-\s]?task|multi[-\s]?step(?:\s+task)?)\b/i;
2
+ const DIRECT_LONG_TASK_REQUEST_RE =
3
+ /\b(?:run|start|do|handle|execute|launch|kick\s+off|use)\s+(?:a\s+|the\s+)?(?:long[-\s]?task|longtask|large[-\s]?task|big[-\s]?task|multi[-\s]?step(?:\s+task)?)\b/i;
4
+ const WANT_LONG_TASK_RE =
5
+ /\b(?:please|can\s+you|could\s+you|i\s+want|i\s+need|i'd\s+like|i\s+would\s+like|let's|lets)\b[\s\S]*\b(?:long[-\s]?task|longtask|large[-\s]?task|big[-\s]?task|multi[-\s]?step(?:\s+task)?)\b/i;
6
+ const NEGATED_LONG_TASK_RE =
7
+ /\b(?:do\s+not|don't|dont|never)\s+(?:run|start|do|handle|execute|launch|kick\s+off|use)\s+(?:a\s+|the\s+)?(?:long[-\s]?task|longtask|large[-\s]?task|big[-\s]?task|multi[-\s]?step(?:\s+task)?)\b/i;
8
+ const INFORMATION_QUESTION_RE = /^\s*(?:how|what|why|when|where|who)\b/i;
9
+ const EXPLICIT_TOOL_RE = /\bpi_long_task\b/i;
10
+
11
+ const COMMIT_FALSE_RE =
12
+ /\b(?:without|no|disable|disabled|off)\s+commits?\b|\bcommits?\s*(?:false|off|disabled)\b|\bcommit\s*:\s*(?:false|off|no)\b|\b(?:do\s+not|don't|dont)\s+commit\b/i;
13
+ const COMMIT_TRUE_RE =
14
+ /\bwith\s+commits?\b|\bcommits?\s*(?:true|on|enabled)\b|\bcommit\s*:\s*(?:true|on|yes)\b|\bcommit(?:ting)?\s+as\s+(?:you|we)\s+go\b|\b(?:make|create|include|allow|enable)\s+commits?\b/i;
15
+
16
+ export function longTaskInputTransform(text: string): string | undefined {
17
+ if (!isNaturalLanguageLongTaskRequest(text)) {
18
+ return undefined;
19
+ }
20
+
21
+ const commit = inferCommitSetting(text) ?? false;
22
+ return buildLongTaskToolPrompt(text, commit);
23
+ }
24
+
25
+ export function isNaturalLanguageLongTaskRequest(text: string): boolean {
26
+ const trimmed = text.trim();
27
+ if (!trimmed || trimmed.startsWith("/") || EXPLICIT_TOOL_RE.test(trimmed)) {
28
+ return false;
29
+ }
30
+ if (!LONG_TASK_RE.test(trimmed) || INFORMATION_QUESTION_RE.test(trimmed) || NEGATED_LONG_TASK_RE.test(trimmed)) {
31
+ return false;
32
+ }
33
+ return DIRECT_LONG_TASK_REQUEST_RE.test(trimmed) || WANT_LONG_TASK_RE.test(trimmed);
34
+ }
35
+
36
+ export function inferCommitSetting(text: string): boolean | undefined {
37
+ if (COMMIT_FALSE_RE.test(text)) {
38
+ return false;
39
+ }
40
+ if (COMMIT_TRUE_RE.test(text)) {
41
+ return true;
42
+ }
43
+ return undefined;
44
+ }
45
+
46
+ function buildLongTaskToolPrompt(originalText: string, commit: boolean): string {
47
+ return [
48
+ "Use the pi_long_task tool for this request.",
49
+ `Set commit to ${commit ? "true" : "false"}.`,
50
+ "Set inputText to the user's original request below. Do not perform the work directly outside pi_long_task.",
51
+ "",
52
+ "Original request:",
53
+ "```text",
54
+ originalText.trim(),
55
+ "```",
56
+ ].join("\n");
57
+ }
package/src/types.ts CHANGED
@@ -5,8 +5,13 @@ import type { SessionOutcome } from "./worker_session.ts";
5
5
 
6
6
  export const PiLongTaskParams = Type.Object(
7
7
  {
8
- inputText: Type.String({ description: "TODO file content or long-task instructions to process." }),
9
- commit: Type.Boolean({ description: "Whether Pi Long Task may commit completed worker changes." }),
8
+ inputText: Type.String({
9
+ description: "TODO file content or the user's long-task instructions to process.",
10
+ }),
11
+ commit: Type.Boolean({
12
+ description:
13
+ "Whether Pi Long Task may commit completed worker changes. Use true when the user asks for commits or committing as work progresses; otherwise use false.",
14
+ }),
10
15
  },
11
16
  { additionalProperties: false },
12
17
  );