@heyhuynhgiabuu/pi-task 0.1.1 → 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/CHANGELOG.md CHANGED
@@ -4,6 +4,57 @@ All notable changes to `@heyhuynhgiabuu/pi-task` are documented here.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [0.1.3] — 2026-06-21
8
+
9
+ ### Fixed
10
+
11
+ - Replaced tmux task startup via `send-keys` with direct
12
+ `split-window <command>` execution so long, quoted `pi ...` launch
13
+ commands are not truncated or interrupted by terminal input buffering.
14
+ - Hardened tmux steering/follow-up text injection by using tmux buffers
15
+ (`load-buffer` + `paste-buffer`) instead of typing long text via
16
+ `send-keys`.
17
+
18
+ ### Verified
19
+
20
+ - `npm test` passes
21
+ - `npm run typecheck` passes
22
+ - `npm run build` passes
23
+ - `npm run smoke` passes
24
+ - Long task-tool tmux launch stress test passed with quotes, backticks,
25
+ shell expansions, redirects, newlines, unicode, and long prompt text.
26
+
27
+ [0.1.3]: https://github.com/heyhuynhgiabuu/pi-task/releases/tag/v0.1.3
28
+
29
+ ## [0.1.2] — 2025
30
+
31
+ ### Fixed
32
+
33
+ - **Missing `pi.extensions` field in `package.json`.** Without it,
34
+ the package was installed by `pi install` but pi's package loader
35
+ didn't recognize it as an extension, so the `task` tool was never
36
+ registered.
37
+
38
+ Added:
39
+
40
+ ```json
41
+ "pi": {
42
+ "extensions": [
43
+ "./dist/index.js"
44
+ ]
45
+ }
46
+ ```
47
+
48
+ ### Verified
49
+
50
+ - `npm run build` succeeds
51
+ - `npm test` 1/1 pass
52
+ - `tsc --noEmit` clean
53
+ - `npm view @heyhuynhgiabuu/pi-task@0.1.2 pi` returns
54
+ `{ extensions: [ './dist/index.js' ] }`
55
+
56
+ [0.1.2]: https://github.com/buddingnewinsights/pi-task/releases/tag/v0.1.2
57
+
7
58
  ## [0.1.1] — 2025
8
59
 
9
60
  ### Fixed
package/dist/helpers.d.ts CHANGED
@@ -50,7 +50,7 @@ export declare function parseResultXml(raw: string): ParsedResult;
50
50
  export declare function formatMs(ms: number): string;
51
51
  export declare function parseIdTimestamp(id: string): number;
52
52
  export declare function shellQuote(value: string): string;
53
- export declare function buildTmuxSendKeysArgs(paneId: string, command: string): string[];
53
+ export declare function buildTmuxSplitWindowArgs(cwd: string, command: string): string[];
54
54
  export interface BackgroundReceiptInput {
55
55
  taskId: string;
56
56
  agentType: string;
package/dist/helpers.js CHANGED
@@ -128,8 +128,8 @@ export function parseIdTimestamp(id) {
128
128
  export function shellQuote(value) {
129
129
  return `'${value.replace(/'/g, `'"'"'`)}'`;
130
130
  }
131
- export function buildTmuxSendKeysArgs(paneId, command) {
132
- return ["send-keys", "-t", paneId, command, "Enter"];
131
+ export function buildTmuxSplitWindowArgs(cwd, command) {
132
+ return ["split-window", "-h", "-P", "-F", "#{pane_id}", "-c", cwd, command];
133
133
  }
134
134
  export function formatBackgroundReceipt(input) {
135
135
  return [
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import { dirname, join } from "node:path";
22
22
  import { fileURLToPath } from "node:url";
23
23
  import { Type } from "@sinclair/typebox";
24
24
  import { Text, truncateToWidth } from "@earendil-works/pi-tui";
25
- import { TASK_BACKGROUND_DEFAULT, TASK_RESULT_XML_INSTRUCTIONS, TASK_TOOL_DESCRIPTION, buildTmuxSendKeysArgs, formatBackgroundReceipt, buildPiArgs, parseResultXml, formatMs, shellQuote, discoverAgents, formatAgentList, countToolUses, readRecentToolCalls, } from "./helpers.js";
25
+ import { TASK_BACKGROUND_DEFAULT, TASK_RESULT_XML_INSTRUCTIONS, TASK_TOOL_DESCRIPTION, buildTmuxSplitWindowArgs, formatBackgroundReceipt, buildPiArgs, parseResultXml, formatMs, shellQuote, discoverAgents, formatAgentList, countToolUses, readRecentToolCalls, } from "./helpers.js";
26
26
  import { runSdkSubagent } from "./subagent/runSdk.js";
27
27
  import { checkTaskCompletion, waitForTaskCompletion as waitForSessionTaskCompletion, } from "./subagent/waitCompletion.js";
28
28
  import { buildAgentToolSelection } from "./agent-tools.js";
@@ -81,18 +81,7 @@ function getCurrentPaneId() {
81
81
  }
82
82
  function splitWindowPane(cwd, command) {
83
83
  const originalPane = getCurrentPaneId();
84
- const paneId = tmuxCmd([
85
- "split-window",
86
- "-h",
87
- "-P",
88
- "-F",
89
- "#{pane_id}",
90
- "-c",
91
- cwd,
92
- ]);
93
- execFileSync("tmux", buildTmuxSendKeysArgs(paneId, command), {
94
- stdio: "ignore",
95
- });
84
+ const paneId = tmuxCmd(buildTmuxSplitWindowArgs(cwd, command));
96
85
  return { paneId, originalPane };
97
86
  }
98
87
  function killAgentPane(paneId, originalPane) {
@@ -10,5 +10,5 @@ export declare function splitWindowPane(cwd: string, command: string): {
10
10
  originalPane: string | null;
11
11
  };
12
12
  export declare function killAgentPane(paneId: string, originalPane: string | null): void;
13
- /** Inject keys into a running subagent pane (steer / follow-up). */
13
+ /** Inject text into a running subagent pane (steer / follow-up). */
14
14
  export declare function tmuxSteerPane(paneId: string, message: string): void;
@@ -64,9 +64,23 @@ export function killAgentPane(paneId, originalPane) {
64
64
  }
65
65
  }
66
66
  }
67
- /** Inject keys into a running subagent pane (steer / follow-up). */
67
+ /** Inject text into a running subagent pane (steer / follow-up). */
68
68
  export function tmuxSteerPane(paneId, message) {
69
- const escaped = message.replace(/'/g, `'\"'\"'`);
70
- tmuxCmd(["send-keys", "-t", paneId, "-l", escaped]);
69
+ const bufferName = `pi-task-steer-${process.pid}-${Date.now()}`;
70
+ try {
71
+ execFileSync("tmux", ["load-buffer", "-b", bufferName, "-"], {
72
+ input: message,
73
+ stdio: ["pipe", "pipe", "pipe"],
74
+ });
75
+ tmuxCmd(["paste-buffer", "-b", bufferName, "-t", paneId]);
76
+ }
77
+ finally {
78
+ try {
79
+ tmuxCmd(["delete-buffer", "-b", bufferName]);
80
+ }
81
+ catch {
82
+ /* ignore */
83
+ }
84
+ }
71
85
  tmuxCmd(["send-keys", "-t", paneId, "Enter"]);
72
86
  }
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@heyhuynhgiabuu/pi-task",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Delegating task/subagent extension for Pi: foreground/background subagents, widgets, tmux observability, SDK fallback.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
+ "pi": {
9
+ "extensions": [
10
+ "./dist/index.js"
11
+ ]
12
+ },
8
13
  "exports": {
9
14
  ".": {
10
15
  "types": "./dist/index.d.ts",