@devo-bmad-custom/agent-orchestration 1.0.17 → 1.0.19
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/lib/installer.js
CHANGED
|
@@ -724,19 +724,22 @@ async function setupTmux(projectRoot, chalk) {
|
|
|
724
724
|
console.log(' ' + chalk.cyan('sudo apt-get install -y wl-clipboard imagemagick wslu'));
|
|
725
725
|
console.log(' ' + chalk.white('⑤ Docker Desktop WSL integration') + chalk.dim(' — GUI only:'));
|
|
726
726
|
console.log(' ' + chalk.dim('Docker Desktop → Settings → Resources → WSL Integration → toggle Ubuntu → Apply & Restart'));
|
|
727
|
+
console.log(' ' + chalk.white('⑥ gsudo') + chalk.dim(' (Windows sudo — allows WSL to run elevated PowerShell):'));
|
|
728
|
+
console.log(' ' + chalk.cyan('winget install gerardog.gsudo'));
|
|
729
|
+
console.log(' ' + chalk.dim(' Or via scoop: scoop install gsudo'));
|
|
727
730
|
|
|
728
731
|
console.log('');
|
|
729
732
|
console.log(chalk.bold.yellow(' ✦ Can be done manually OR by an AI with relaxed permissions:'));
|
|
730
733
|
console.log(chalk.dim(' These are safe to automate — no sudo or system-level access needed.\n'));
|
|
731
|
-
console.log(' ' + chalk.white('
|
|
734
|
+
console.log(' ' + chalk.white('⑧ NVM + Node') + chalk.dim(' (required for Node-based MCP servers):'));
|
|
732
735
|
console.log(' ' + chalk.cyan('curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash'));
|
|
733
736
|
console.log(' ' + chalk.cyan('source ~/.bashrc && nvm install --lts'));
|
|
734
|
-
console.log(' ' + chalk.white('
|
|
737
|
+
console.log(' ' + chalk.white('⑨ TPM (tmux Plugin Manager):'));
|
|
735
738
|
console.log(' ' + chalk.cyan('git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm'));
|
|
736
739
|
console.log(' ' + chalk.dim(' Then inside tmux: press Ctrl+B I to install plugins'));
|
|
737
|
-
console.log(' ' + chalk.white('
|
|
740
|
+
console.log(' ' + chalk.white('⑩ fzf') + chalk.dim(' (required for Actions popup menu):'));
|
|
738
741
|
console.log(' ' + chalk.cyan('mkdir -p ~/.local/bin && curl -Lo /tmp/fzf.tar.gz https://github.com/junegunn/fzf/releases/download/v0.54.3/fzf-0.54.3-linux_amd64.tar.gz && tar -xzf /tmp/fzf.tar.gz -C ~/.local/bin'));
|
|
739
|
-
console.log(' ' + chalk.white('
|
|
742
|
+
console.log(' ' + chalk.white('⑪ Nerd Fonts') + chalk.dim(' (required for Powerline status bar separators):'));
|
|
740
743
|
console.log(' ' + chalk.dim(' Download JetBrainsMono NFM from https://www.nerdfonts.com/'));
|
|
741
744
|
console.log(' ' + chalk.dim(' Install JetBrainsMonoNerdFontMono-Regular.ttf to Windows (double-click → Install for all users)'));
|
|
742
745
|
console.log(' ' + chalk.white(' Cursor/VS Code:') + ' ' + chalk.cyan('"terminal.integrated.fontFamily": "JetBrainsMono NFM"'));
|
|
@@ -798,6 +801,33 @@ async function setupTmux(projectRoot, chalk) {
|
|
|
798
801
|
console.log(chalk.dim(` ○ ${xdgOpenPath} already exists`));
|
|
799
802
|
}
|
|
800
803
|
|
|
804
|
+
// gsudo shim — lets WSL call Windows-side gsudo.exe without full path
|
|
805
|
+
const gsudoShimPath = path.join(homeDir, '.local', 'bin', 'gsudo');
|
|
806
|
+
if (!await fs.pathExists(gsudoShimPath)) {
|
|
807
|
+
// Find gsudo.exe on Windows side
|
|
808
|
+
const { execSync } = require('child_process');
|
|
809
|
+
let gsudoExe = null;
|
|
810
|
+
try {
|
|
811
|
+
// cmd.exe /c where gsudo returns Windows paths — convert first result to WSL path
|
|
812
|
+
const winPath = execSync('cmd.exe /c where gsudo 2>NUL', { stdio: 'pipe' })
|
|
813
|
+
.toString().split('\n')[0].trim();
|
|
814
|
+
if (winPath && winPath.endsWith('.exe')) {
|
|
815
|
+
// Convert C:\... → /mnt/c/...
|
|
816
|
+
gsudoExe = '/mnt/' + winPath.replace(/\\/g, '/').replace(/^([A-Za-z]):/, (_, d) => d.toLowerCase());
|
|
817
|
+
}
|
|
818
|
+
} catch { /* gsudo not installed on Windows yet */ }
|
|
819
|
+
|
|
820
|
+
if (gsudoExe) {
|
|
821
|
+
const shimContent = `#!/bin/bash\nexec '${gsudoExe}' "$@"\n`;
|
|
822
|
+
await fs.writeFile(gsudoShimPath, shimContent, { mode: 0o755 });
|
|
823
|
+
console.log(chalk.green(` ✓ gsudo shim → ${gsudoShimPath} (delegates to ${gsudoExe})`));
|
|
824
|
+
} else {
|
|
825
|
+
console.log(chalk.yellow(' ⚠ gsudo not found on Windows — install it first (winget install gerardog.gsudo), then re-run setup'));
|
|
826
|
+
}
|
|
827
|
+
} else {
|
|
828
|
+
console.log(chalk.dim(` ○ gsudo shim already exists at ${gsudoShimPath}`));
|
|
829
|
+
}
|
|
830
|
+
|
|
801
831
|
// ── Step 3: TPM check ────────────────────────────────────────────────────
|
|
802
832
|
console.log('\n' + chalk.bold('Step 3 — TPM check'));
|
|
803
833
|
if (await fs.pathExists(tpmPath)) {
|
|
@@ -834,15 +864,7 @@ async function setupTmux(projectRoot, chalk) {
|
|
|
834
864
|
const src = path.join(tmuxSrc, srcName);
|
|
835
865
|
if (!await fs.pathExists(src)) continue;
|
|
836
866
|
|
|
837
|
-
|
|
838
|
-
if (exists) {
|
|
839
|
-
const overwrite = await ask(chalk.dim(` ${dest} already exists. Overwrite? (y/N): `));
|
|
840
|
-
if (!overwrite.toLowerCase().startsWith('y')) {
|
|
841
|
-
console.log(chalk.dim(` ○ Skipped ${path.basename(dest)}`));
|
|
842
|
-
continue;
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
|
|
867
|
+
// Always overwrite tmux scripts — ensures fixes (e.g. PNG normalization) propagate on update
|
|
846
868
|
await fs.copy(src, dest, { overwrite: true });
|
|
847
869
|
if (dest.endsWith('.sh') || dest.endsWith('.py') || dest === xclipPath) {
|
|
848
870
|
try { await fs.chmod(dest, 0o755); } catch {}
|
package/package.json
CHANGED
|
@@ -54,15 +54,28 @@ if [ -n "$IMAGE_TYPE" ]; then
|
|
|
54
54
|
# Fall back to PowerShell (Windows clipboard API) when wl-paste produces empty output.
|
|
55
55
|
if [ ! -s "$PNGFILE" ]; then
|
|
56
56
|
WINPATH=$(wslpath -w "$PNGFILE" 2>/dev/null)
|
|
57
|
+
# Normalize to 32bppArgb before saving — System.Drawing.Image.Save() can produce
|
|
58
|
+
# indexed/palette PNGs that the Anthropic API rejects with "image format not supported".
|
|
57
59
|
powershell.exe -NoProfile -Command "
|
|
58
60
|
Add-Type -AssemblyName System.Windows.Forms
|
|
61
|
+
Add-Type -AssemblyName System.Drawing
|
|
59
62
|
\$img = [System.Windows.Forms.Clipboard]::GetImage()
|
|
60
|
-
if (\$img -ne \$null) {
|
|
63
|
+
if (\$img -ne \$null) {
|
|
64
|
+
\$bmp = New-Object System.Drawing.Bitmap(\$img.Width, \$img.Height, [System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
|
|
65
|
+
\$g = [System.Drawing.Graphics]::FromImage(\$bmp)
|
|
66
|
+
\$g.DrawImage(\$img, 0, 0)
|
|
67
|
+
\$g.Dispose()
|
|
68
|
+
\$bmp.Save('$WINPATH', [System.Drawing.Imaging.ImageFormat]::Png)
|
|
69
|
+
\$bmp.Dispose()
|
|
70
|
+
\$img.Dispose()
|
|
71
|
+
}
|
|
61
72
|
" 2>/dev/null
|
|
62
73
|
fi
|
|
63
74
|
|
|
64
75
|
[ -s "$PNGFILE" ] || exit 1
|
|
65
76
|
send_path "@$PNGFILE"
|
|
77
|
+
# Writeback normalized PNG to Wayland clipboard so subsequent pastes are also clean
|
|
78
|
+
/usr/bin/wl-copy --type image/png < "$PNGFILE" 2>/dev/null || true
|
|
66
79
|
exit 0
|
|
67
80
|
fi
|
|
68
81
|
|
|
@@ -681,7 +681,11 @@ tmux kill-pane -t <pane_id>
|
|
|
681
681
|
| `text/html` | Saved to `/tmp/tmux_clipboard_content.html`, path typed |
|
|
682
682
|
| `text/plain` | If it's a valid path: `@path`; otherwise saved to `/tmp/tmux_clipboard_text.txt` |
|
|
683
683
|
|
|
684
|
-
**Implementation:** `paste_image_wrapper.sh` uses `/usr/bin/wl-paste` (Linux-native Wayland clipboard — no PowerShell/vsock). Files are saved as `/tmp/tmux_clip_YYYYMMDD_HHMMSS.<ext>`. On each run, files from previous days are automatically deleted. The PNG is also
|
|
684
|
+
**Implementation:** `paste_image_wrapper.sh` uses `/usr/bin/wl-paste` (Linux-native Wayland clipboard — no PowerShell/vsock). Files are saved as `/tmp/tmux_clip_YYYYMMDD_HHMMSS.<ext>`. On each run, files from previous days are automatically deleted. The normalized PNG is also written back to the Wayland clipboard via `wl-copy` so subsequent pastes are also clean.
|
|
685
|
+
|
|
686
|
+
**PNG normalization (WSLg PowerShell fallback):** When `wl-paste` produces empty output (common on WSLg), the script falls back to PowerShell's `System.Windows.Forms.Clipboard::GetImage()`. The raw `Image.Save()` call can produce indexed/palette-mode PNGs that the Anthropic API rejects with `"image format image/png not supported"`. The fix redraws the clipboard image onto a fresh `Format32bppArgb` bitmap before saving, ensuring the output is always standard RGBA PNG.
|
|
687
|
+
|
|
688
|
+
> **Troubleshooting:** If Claude reports `"Image format image/png not supported"` after pasting a screenshot, your `paste_image_wrapper.sh` is outdated. Re-run the installer (it now always overwrites tmux scripts) or copy the latest version from `docs/dev/paste_image_wrapper.sh`.
|
|
685
689
|
|
|
686
690
|
**`Ctrl+V` binding** uses `tmux paste-buffer -p` (no trailing newline). Without `-p`, `paste-buffer` appended a newline that auto-submitted the pasted content — fixed.
|
|
687
691
|
|