oira666_pi-subagent 0.2.2 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/runner.ts +37 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oira666_pi-subagent",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Subagent extension for Pi coding agent. Delegate tasks to specialized agents.",
5
5
  "type": "module",
6
6
  "main": "index.ts",
package/runner.ts CHANGED
@@ -81,6 +81,25 @@ function cleanupTempDir(dir: string | null): void {
81
81
  }
82
82
  }
83
83
 
84
+ function resolveWorkingDirectory(input: string, fallbackBase: string): string {
85
+ if (input.startsWith("~/")) return path.join(os.homedir(), input.slice(2));
86
+ if (path.isAbsolute(input)) return input;
87
+ return path.resolve(fallbackBase, input);
88
+ }
89
+
90
+ function getInvalidWorkingDirectoryMessage(input: string, resolved: string): string | null {
91
+ try {
92
+ const stat = fs.statSync(resolved);
93
+ if (!stat.isDirectory()) {
94
+ return `Invalid cwd "${input}" resolved to "${resolved}", but it is not a directory.`;
95
+ }
96
+ return null;
97
+ } catch (err) {
98
+ const detail = err instanceof Error ? err.message : String(err);
99
+ return `Invalid cwd "${input}" resolved to "${resolved}": ${detail}`;
100
+ }
101
+ }
102
+
84
103
  function getCurrentPiCliScript(): string | null {
85
104
  const script = process.argv[1];
86
105
  if (!script) return null;
@@ -504,6 +523,18 @@ export async function runAgentSubprocess(opts: RunAgentOptions): Promise<SingleR
504
523
 
505
524
  emitUpdate();
506
525
 
526
+ const requestedCwd = taskCwd ?? cwd;
527
+ const resolvedCwd = resolveWorkingDirectory(requestedCwd, cwd);
528
+ const invalidCwdMessage = getInvalidWorkingDirectoryMessage(requestedCwd, resolvedCwd);
529
+ if (invalidCwdMessage) {
530
+ result.exitCode = 1;
531
+ result.stopReason = "error";
532
+ result.errorMessage = invalidCwdMessage;
533
+ result.stderr = invalidCwdMessage;
534
+ emitUpdate();
535
+ return result;
536
+ }
537
+
507
538
  // Write system prompt to temp file if needed
508
539
  let promptTmpDir: string | null = null;
509
540
  let promptTmpPath: string | null = null;
@@ -533,7 +564,7 @@ export async function runAgentSubprocess(opts: RunAgentOptions): Promise<SingleR
533
564
  const spawnCmd = currentPiCli ? process.execPath : "pi";
534
565
  const spawnArgs = currentPiCli ? [currentPiCli, ...piArgs] : piArgs;
535
566
  const proc = spawn(spawnCmd, spawnArgs, {
536
- cwd: taskCwd ?? cwd,
567
+ cwd: resolvedCwd,
537
568
  shell: false,
538
569
  stdio: ["ignore", "pipe", "pipe"],
539
570
  env: {
@@ -667,9 +698,10 @@ export async function runAgentSubprocess(opts: RunAgentOptions): Promise<SingleR
667
698
  });
668
699
 
669
700
  proc.on("error", (err) => {
670
- result.stderr += `Spawn error: ${err.message}`;
701
+ const message = `Failed to spawn pi process in cwd "${resolvedCwd}": ${err.message}`;
702
+ result.stderr += result.stderr ? `\n${message}` : message;
671
703
  result.stopReason = "error";
672
- result.errorMessage = `Failed to spawn pi process: ${err.message}`;
704
+ result.errorMessage = message;
673
705
  doResolve(1);
674
706
  });
675
707
 
@@ -840,7 +872,8 @@ export async function executeParallelSubprocess(
840
872
  const successCount = results.filter((r) => r.exitCode === 0).length;
841
873
  const summaries = results.map((r) => {
842
874
  const output = getFinalOutput(r.messages);
843
- return `[${r.agent}] ${r.exitCode === 0 ? "completed" : "failed"}: ${output || "(no output)"}`;
875
+ const error = r.errorMessage || r.stderr;
876
+ return `[${r.agent}] ${r.exitCode === 0 ? "completed" : "failed"}: ${output || error || "(no output)"}`;
844
877
  });
845
878
 
846
879
  return {