@stilero/bankan 1.1.2 → 1.1.4

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": "@stilero/bankan",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "type": "module",
5
5
  "description": "Run AI coding agents like a Kanban board. Plan, implement, review and ship code using parallel AI agents across your local repositories.",
6
6
  "license": "MIT",
@@ -65,8 +65,12 @@ export function approveMaxReviewBlocker(taskId) {
65
65
  const task = store.getTask(taskId);
66
66
  const updates = buildMaxReviewBlockerApprovalUpdate(task);
67
67
  if (!updates) return false;
68
- if (task?.workspacePath && existsSync(task.workspacePath)) {
69
- rmSync(task.workspacePath, { recursive: true, force: true });
68
+ if (task?.workspacePath) {
69
+ try {
70
+ rmSync(task.workspacePath, { recursive: true, force: true, maxRetries: 3, retryDelay: 500 });
71
+ } catch (err) {
72
+ console.warn(`Could not remove workspace ${task.workspacePath}: ${err.message}`);
73
+ }
70
74
  }
71
75
  store.updateTask(taskId, updates);
72
76
  store.appendLog(taskId, 'Human override: approved task to done after max review cycles.');
@@ -42,8 +42,10 @@ function stripAnsi(text) {
42
42
  );
43
43
  }
44
44
 
45
+ const isWindows = process.platform === 'win32';
46
+
45
47
  function escapePrompt(text) {
46
- if (process.platform === 'win32') {
48
+ if (isWindows) {
47
49
  // PowerShell: escape single quotes by doubling them
48
50
  return text.replace(/'/g, "''");
49
51
  }
@@ -51,9 +53,6 @@ function escapePrompt(text) {
51
53
  return text.replace(/'/g, "'\\''");
52
54
  }
53
55
 
54
- // TODO: buildCodexExecCommand emits bash syntax (mktemp, $?, printf).
55
- // On Windows the agent shell is PowerShell, so codex with captureLastMessage
56
- // will not work until this function gets a win32 branch.
57
56
  function buildCodexExecCommand(prompt, { captureLastMessage = false, sandbox = 'read-only', model = '' } = {}) {
58
57
  const escapedPrompt = escapePrompt(prompt);
59
58
  const modelFlag = model ? `-m ${model} ` : '';
@@ -64,13 +63,17 @@ function buildCodexExecCommand(prompt, { captureLastMessage = false, sandbox = '
64
63
  return `tmpfile=$(mktemp); codex exec ${modelFlag}--sandbox ${sandbox} -o "$tmpfile" '${escapedPrompt}'; status=$?; printf '\\n=== CODEX_LAST_MESSAGE_FILE:%s ===\\n' "$tmpfile"; exit $status`;
65
64
  }
66
65
 
66
+ // On Windows the agent shell is PowerShell, so the bash-syntax
67
+ // captureLastMessage path cannot work — the structured-capture and
68
+ // terminal-buffer fallbacks in extractStructuredStageText still apply.
67
69
  export function buildAgentCommand(cliTool, prompt, mode = 'interactive', model = '') {
68
70
  if (cliTool === 'codex') {
71
+ const capture = !isWindows;
69
72
  if (mode === 'plan' || mode === 'review') {
70
- return buildCodexExecCommand(prompt, { captureLastMessage: true, sandbox: 'read-only', model });
73
+ return buildCodexExecCommand(prompt, { captureLastMessage: capture, sandbox: 'read-only', model });
71
74
  }
72
75
  if (mode === 'interactive') {
73
- return buildCodexExecCommand(prompt, { captureLastMessage: true, sandbox: 'danger-full-access', model });
76
+ return buildCodexExecCommand(prompt, { captureLastMessage: capture, sandbox: 'danger-full-access', model });
74
77
  }
75
78
  return buildCodexExecCommand(prompt, { captureLastMessage: false, sandbox: 'read-only', model });
76
79
  }
@@ -703,8 +706,12 @@ async function prepareWorkspaceBranch(task) {
703
706
  }
704
707
 
705
708
  async function cleanupWorkspace(task) {
706
- if (task.workspacePath && existsSync(task.workspacePath)) {
707
- await rm(task.workspacePath, { recursive: true, force: true });
709
+ if (task.workspacePath) {
710
+ try {
711
+ await rm(task.workspacePath, { recursive: true, force: true, maxRetries: 3, retryDelay: 500 });
712
+ } catch (err) {
713
+ console.warn(`Could not remove workspace ${task.workspacePath}: ${err.message}`);
714
+ }
708
715
  store.updateTask(task.id, { workspacePath: null });
709
716
  }
710
717
  }