@galda/cli 0.10.80 → 0.10.81

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/app/index.html CHANGED
@@ -10628,7 +10628,7 @@ function renderCtxBar(){
10628
10628
  + `<span class="pt">\u200e${esc(folderShort(r.dir))}</span></button>`)
10629
10629
  .join('');
10630
10630
  const openRow = `<button type="button" class="appopt ctxopen" id="ctxopenfolder" title="Open the OS folder chooser"><svg viewBox="0 0 24 24"><path d="M3 7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><path d="M12 11v6M9 14h6"/></svg><span class="nm">Open folder…</span></button>`;
10631
- menu.innerHTML = `${opts}${openRow}<div class="ctxpath"><input type="text" id="ctxdirin" placeholder="~/path/to/repo" aria-label="Folder path" spellcheck="false"><button type="button" class="appopt" id="ctxdiruse" style="width:auto">Use</button></div><div class="ctxmsg" id="ctxdirmsg"></div>`;
10631
+ menu.innerHTML = `${opts}${openRow}<div class="ctxmsg" id="ctxdirmsg"></div>`;
10632
10632
  }
10633
10633
  // Workspace mode is fixed to the isolated worktree (clean separate checkout). The
10634
10634
  // direct-workspace escape hatch was removed after two accidents where a stray click
@@ -10656,7 +10656,7 @@ async function setProjectFolder(dir){
10656
10656
  const want = String(dir ?? '').trim();
10657
10657
  const msg = $('ctxdirmsg');
10658
10658
  const say = (t, bad) => { if (msg) { msg.textContent = t; msg.classList.toggle('bad', Boolean(bad)); } };
10659
- if (!want) { say('Type a path, or pick one above.', true); return; }
10659
+ if (!want) { say('Choose a folder.', true); return; }
10660
10660
  say('');
10661
10661
  try {
10662
10662
  const r = await fetch(withKey(`/api/projects/${encodeURIComponent(state.active)}`), {
@@ -10678,14 +10678,14 @@ function isLocalSession(){ return ['localhost', '127.0.0.1'].includes(location.h
10678
10678
  async function openFolderNative(){
10679
10679
  const msg = $('ctxdirmsg');
10680
10680
  const say = (t, bad) => { if (msg) { msg.textContent = t; msg.classList.toggle('bad', Boolean(bad)); } };
10681
- if (!isLocalSession()) { $('ctxdirin')?.focus(); say('Remote session pick a repo above or type a path.'); return; }
10681
+ if (!isLocalSession()) { say('Open Manager locally to choose a folder on this computer.', true); return; }
10682
10682
  say('Opening the folder chooser…');
10683
10683
  try {
10684
10684
  const r = await fetch(withKey('/api/choose-folder'), { method: 'POST' });
10685
10685
  const body = await r.json().catch(() => ({}));
10686
10686
  if (body.path) { setProjectFolder(body.path); return; } // reuse: PUT the project's dir, close, render
10687
10687
  if (body.cancelled) { say(''); return; }
10688
- if (body.unsupported) { say('This engine can’t open a folder dialog pick a repo above or type a path.'); return; }
10688
+ if (body.unsupported) { say('This engine can’t open a folder dialog on this system.', true); return; }
10689
10689
  say(body.error || 'Could not open the folder chooser.', true);
10690
10690
  } catch { say('Could not reach the engine.', true); }
10691
10691
  }
@@ -10701,11 +10701,6 @@ $('ctxdirmenu').addEventListener('click', (e) => {
10701
10701
  if (e.target.closest('#ctxopenfolder')) { openFolderNative(); return; }
10702
10702
  const opt = e.target.closest('[data-ctxdir]');
10703
10703
  if (opt) { setProjectFolder(opt.dataset.ctxdir); return; }
10704
- if (e.target.closest('#ctxdiruse')) setProjectFolder($('ctxdirin')?.value ?? '');
10705
- });
10706
- $('ctxdirmenu').addEventListener('keydown', (e) => {
10707
- e.stopPropagation();
10708
- if (e.key === 'Enter' && !e.isComposing && e.target.id === 'ctxdirin') { e.preventDefault(); setProjectFolder(e.target.value); }
10709
10704
  });
10710
10705
  $('appbtn').onclick = (e) => { e.stopPropagation(); $('appmenu').classList.toggle('show'); };
10711
10706
  $('appmenu').addEventListener('click', (e) => {
package/engine/server.mjs CHANGED
@@ -4101,13 +4101,17 @@ const server = createServer(async (req, res) => {
4101
4101
  // (otherwise the dialog would open on the server, not the person's screen). It
4102
4102
  // returns only the chosen path — nothing is scanned, listed, or invented.
4103
4103
  // { path, label } | { cancelled: true } | { unsupported: true } | { error }
4104
- // MANAGER_NO_NATIVE_DIALOG (and any non-macOS host) short-circuits to
4105
- // {unsupported} so tests/CI/headless never block on a GUI.
4104
+ // MANAGER_NO_NATIVE_DIALOG short-circuits so tests/CI/headless never block
4105
+ // on a GUI. macOS, Windows and common Linux desktops use their native picker.
4106
4106
  if (url.pathname === '/api/choose-folder' && req.method === 'POST') {
4107
- if (process.platform !== 'darwin' || process.env.MANAGER_NO_NATIVE_DIALOG) {
4107
+ if (process.env.MANAGER_NO_NATIVE_DIALOG) {
4108
4108
  return json(res, 200, { unsupported: true });
4109
4109
  }
4110
- execFile('osascript', ['-e', chooseFolderScript()], { timeout: 120000 }, (err, stdout, stderr) => {
4110
+ const windowsScript = 'Add-Type -AssemblyName System.Windows.Forms; $d = New-Object System.Windows.Forms.FolderBrowserDialog; if ($d.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { [Console]::Write($d.SelectedPath) }';
4111
+ const command = process.platform === 'darwin' ? 'osascript' : process.platform === 'win32' ? 'powershell.exe' : 'zenity';
4112
+ const args = process.platform === 'darwin' ? ['-e', chooseFolderScript()] : process.platform === 'win32'
4113
+ ? ['-NoProfile', '-NonInteractive', '-Command', windowsScript] : ['--file-selection', '--directory', '--title=Choose a project folder'];
4114
+ execFile(command, args, { timeout: 120000 }, (err, stdout, stderr) => {
4111
4115
  const verdict = parseChosenFolder({ code: err ? (err.code ?? 1) : 0, stdout, stderr });
4112
4116
  if (verdict.path) verdict.label = folderLabel(verdict.path, HOME);
4113
4117
  json(res, 200, verdict);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@galda/cli",
3
- "version": "0.10.80",
3
+ "version": "0.10.81",
4
4
  "type": "module",
5
5
  "description": "Galda - hand off work to Claude Code or Codex, get proof back. Runs on your existing subscription, no extra API cost.",
6
6
  "scripts": {