@pushpalsdev/cli 1.1.28 → 1.1.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pushpalsdev/cli",
3
- "version": "1.1.28",
3
+ "version": "1.1.29",
4
4
  "description": "PushPals terminal CLI for LocalBuddy -> RemoteBuddy orchestration",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,6 +42,7 @@ export const MINISWE_BACKEND: DockerBackendSpec = {
42
42
  taskExecute: createGenericPythonExecutor({
43
43
  backendName: "miniswe",
44
44
  scriptPath: resolve(import.meta.dir, "miniswe", "miniswe_executor.py"),
45
+ scriptSegments: ["apps", "workerpals", "src", "backends", "miniswe", "miniswe_executor.py"],
45
46
  pythonConfigKey: "miniswePython",
46
47
  timeoutConfigKey: "minisweTimeoutMs",
47
48
  }),
@@ -61,6 +61,7 @@ export const OPENAI_CODEX_BACKEND: DockerBackendSpec = {
61
61
  taskExecute: createGenericPythonExecutor({
62
62
  backendName: "openai_codex",
63
63
  scriptPath: resolve(import.meta.dir, "openai_codex", "openai_codex_executor.py"),
64
+ scriptSegments: ["apps", "workerpals", "src", "backends", "openai_codex", "openai_codex_executor.py"],
64
65
  pythonConfigKey: "openaiCodexPython",
65
66
  timeoutConfigKey: "openaiCodexTimeoutMs",
66
67
  }),
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { existsSync } from "fs";
11
- import { resolve } from "path";
11
+ import { dirname, join, resolve } from "path";
12
12
  import type { JobResult, JobTokenUsage } from "./types.js";
13
13
  import type { WorkerpalsRuntimeConfig } from "./executor_backend.js";
14
14
  import type { BackendTaskExecutor } from "../backends/types.js";
@@ -23,6 +23,7 @@ import { buildWorkerSandboxWritableEnv } from "./sandbox_env.js";
23
23
  interface GenericPythonExecutorConfig {
24
24
  backendName: string;
25
25
  scriptPath: string;
26
+ scriptSegments?: readonly string[];
26
27
  pythonConfigKey: string;
27
28
  timeoutConfigKey: string;
28
29
  capTimeoutToExecutionBudget?: boolean;
@@ -231,6 +232,28 @@ function formatGenericPythonExecutorTimeoutDetail(
231
232
  return `${configPath}=${configuredTimeoutMs}ms within planning executionBudgetMs=${executionBudgetMs}ms`;
232
233
  }
233
234
 
235
+ function uniqueStrings(values: string[]): string[] {
236
+ return Array.from(new Set(values.filter(Boolean)));
237
+ }
238
+
239
+ export function resolveGenericPythonExecutorScriptPath(
240
+ config: GenericPythonExecutorConfig,
241
+ runtimeConfig: WorkerpalsRuntimeConfig,
242
+ ): { scriptPath: string | null; candidates: string[] } {
243
+ const candidates = [config.scriptPath];
244
+ if (config.scriptSegments && config.scriptSegments.length > 0) {
245
+ const runtimeRoot = dirname(runtimeConfig.configDir);
246
+ candidates.push(join(runtimeRoot, ...config.scriptSegments));
247
+ candidates.push(join(runtimeConfig.projectRoot, ...config.scriptSegments));
248
+ }
249
+
250
+ const uniqueCandidates = uniqueStrings(candidates.map((candidate) => resolve(candidate)));
251
+ return {
252
+ scriptPath: uniqueCandidates.find((candidate) => existsSync(candidate)) ?? null,
253
+ candidates: uniqueCandidates,
254
+ };
255
+ }
256
+
234
257
  export function normalizeGenericPythonExecutorParsedResultForTimeout(params: {
235
258
  backendName: string;
236
259
  kind: string;
@@ -278,7 +301,7 @@ export function normalizeGenericPythonExecutorParsedResultForTimeout(params: {
278
301
  export function createGenericPythonExecutor(
279
302
  config: GenericPythonExecutorConfig,
280
303
  ): BackendTaskExecutor {
281
- const { backendName, scriptPath } = config;
304
+ const { backendName } = config;
282
305
  const backendLabel = backendName[0].toUpperCase() + backendName.slice(1);
283
306
 
284
307
  return async (
@@ -289,10 +312,13 @@ export function createGenericPythonExecutor(
289
312
  onLog?: (stream: "stdout" | "stderr", line: string) => void,
290
313
  budgets?: { executionBudgetMs?: number; finalizationBudgetMs?: number },
291
314
  ): Promise<JobResult> => {
292
- if (!existsSync(scriptPath)) {
315
+ const resolvedScript = resolveGenericPythonExecutorScriptPath(config, runtimeConfig);
316
+ const scriptPath = resolvedScript.scriptPath;
317
+ if (scriptPath == null) {
293
318
  return {
294
319
  ok: false,
295
- summary: `${backendName} wrapper script not found: ${scriptPath}`,
320
+ summary: `${backendName} wrapper script not found`,
321
+ stderr: `Checked wrapper script path(s): ${resolvedScript.candidates.join("; ")}`,
296
322
  exitCode: 1,
297
323
  };
298
324
  }