Compare commits
5 Commits
ef21b03d9c
...
desktop-v0
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a74576955 | |||
| bd76e53570 | |||
| b0a75df204 | |||
| c7af406cbf | |||
| 8042376f9c |
@@ -50,7 +50,9 @@ jobs:
|
|||||||
packages/desktop/release/*.deb
|
packages/desktop/release/*.deb
|
||||||
packages/desktop/release/latest-linux.yml
|
packages/desktop/release/latest-linux.yml
|
||||||
# Best-effort : attache les installeurs (+ latest-linux.yml pour l'auto-update) à la release
|
# Best-effort : attache les installeurs (+ latest-linux.yml pour l'auto-update) à la release
|
||||||
# Gitea du tag (crée la release si absente). Réutilise NPM_TOKEN (même token Gitea).
|
# Gitea du tag (crée la release si absente). Réutilise NPM_TOKEN (même token Gitea) : ce token
|
||||||
|
# doit porter la portée write:repository en plus de write:package, sinon l'API release renvoie
|
||||||
|
# un 403 (l'attache est ignorée, les installeurs restent disponibles en artefact du run).
|
||||||
- name: Attach installers to Gitea release
|
- name: Attach installers to Gitea release
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
env:
|
env:
|
||||||
@@ -72,6 +74,13 @@ jobs:
|
|||||||
for f in packages/desktop/release/*.AppImage packages/desktop/release/*.deb packages/desktop/release/latest-linux.yml; do
|
for f in packages/desktop/release/*.AppImage packages/desktop/release/*.deb packages/desktop/release/latest-linux.yml; do
|
||||||
[ -f "$f" ] || continue
|
[ -f "$f" ] || continue
|
||||||
name=$(basename "$f")
|
name=$(basename "$f")
|
||||||
|
# Re-run idempotent : supprimer un asset existant du même nom avant de ré-uploader, pour
|
||||||
|
# que le dernier build gagne (l'API Gitea refuse sinon un asset déjà présent).
|
||||||
|
existing=$(curl -fsSL -H "$auth" "${api}/releases/${rid}/assets" | node -e "const a=JSON.parse(require('fs').readFileSync(0,'utf8'));const m=Array.isArray(a)?a.find(x=>x.name===process.argv[1]):null;process.stdout.write(m?String(m.id):'')" "$name" || true)
|
||||||
|
if [ -n "$existing" ]; then
|
||||||
|
echo "replacing existing $name (asset $existing)"
|
||||||
|
curl -fsSL -X DELETE -H "$auth" "${api}/releases/${rid}/assets/${existing}" || true
|
||||||
|
fi
|
||||||
echo "attaching $name"
|
echo "attaching $name"
|
||||||
curl -fsSL -X POST -H "$auth" -F "attachment=@${f}" "${api}/releases/${rid}/assets?name=${name}"
|
curl -fsSL -X POST -H "$auth" -F "attachment=@${f}" "${api}/releases/${rid}/assets?name=${name}"
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -46,9 +46,10 @@ jobs:
|
|||||||
name: vsix
|
name: vsix
|
||||||
path: packages/vscode/*.vsix
|
path: packages/vscode/*.vsix
|
||||||
# Best-effort : attache le VSIX à la release Gitea du tag (crée la release si absente).
|
# Best-effort : attache le VSIX à la release Gitea du tag (crée la release si absente).
|
||||||
# Réutilise le secret NPM_TOKEN (même token Gitea que la publication du daemon, droits
|
# Réutilise le secret NPM_TOKEN (même token Gitea que la publication du daemon) : ce token doit
|
||||||
# repository suffisants pour l'API release). Sans lui, l'étape est ignorée sans faire échouer
|
# porter write:repository en plus de write:package, sinon l'API release renvoie un 403. Sans
|
||||||
# le job (continue-on-error) ; le VSIX reste disponible en artefact.
|
# token, l'étape est ignorée sans faire échouer le job (continue-on-error) ; le VSIX reste
|
||||||
|
# disponible en artefact.
|
||||||
- name: Attach VSIX to Gitea release
|
- name: Attach VSIX to Gitea release
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
env:
|
env:
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -7924,7 +7924,7 @@
|
|||||||
},
|
},
|
||||||
"packages/server": {
|
"packages/server": {
|
||||||
"name": "@johanleroy/git-arboretum",
|
"name": "@johanleroy/git-arboretum",
|
||||||
"version": "2.0.0",
|
"version": "3.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cookie": "^11.0.0",
|
"@fastify/cookie": "^11.0.0",
|
||||||
@@ -8053,7 +8053,7 @@
|
|||||||
},
|
},
|
||||||
"packages/vscode": {
|
"packages/vscode": {
|
||||||
"name": "git-arboretum",
|
"name": "git-arboretum",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@arboretum/shared": "0.1.0",
|
"@arboretum/shared": "0.1.0",
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
"name": "arboretum-monorepo",
|
"name": "arboretum-monorepo",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"author": "Johan LEROY <contact@johanleroy.fr>",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/shared",
|
"packages/shared",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
appId: fr.lidge.arboretum
|
appId: fr.lidge.arboretum
|
||||||
productName: Arboretum
|
productName: Arboretum
|
||||||
copyright: Copyright Johan Leroy
|
copyright: Copyright © 2026 Johan Leroy
|
||||||
|
|
||||||
directories:
|
directories:
|
||||||
output: release
|
output: release
|
||||||
@@ -32,6 +32,8 @@ linux:
|
|||||||
deb:
|
deb:
|
||||||
# git est requis pour les operations de worktree ; claude n'est pas dans les depots (documente).
|
# git est requis pour les operations de worktree ; claude n'est pas dans les depots (documente).
|
||||||
depends: [git]
|
depends: [git]
|
||||||
|
# Mainteneur .deb explicite (electron-builder l'exige ; sinon derive de author.email du package.json).
|
||||||
|
maintainer: Johan LEROY <contact@johanleroy.fr>
|
||||||
|
|
||||||
win:
|
win:
|
||||||
target:
|
target:
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "Arboretum desktop app: Electron shell that runs the daemon and shows its web UI",
|
"description": "Arboretum desktop app: Electron shell that runs the daemon and shows its web UI",
|
||||||
|
"homepage": "https://git-arboretum.com",
|
||||||
|
"license": "MIT",
|
||||||
|
"author": {
|
||||||
|
"name": "Johan LEROY",
|
||||||
|
"email": "contact@johanleroy.fr"
|
||||||
|
},
|
||||||
"main": "dist/main.js",
|
"main": "dist/main.js",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { seedSessionCookie } from './auth';
|
|||||||
import { loadWindowState, saveWindowState } from './window-state';
|
import { loadWindowState, saveWindowState } from './window-state';
|
||||||
import { createTray } from './tray';
|
import { createTray } from './tray';
|
||||||
import { initUpdater } from './updater';
|
import { initUpdater } from './updater';
|
||||||
|
import { resolveIconPath } from './paths';
|
||||||
|
|
||||||
const PARTITION = 'persist:arboretum';
|
const PARTITION = 'persist:arboretum';
|
||||||
const PORT = 7317;
|
const PORT = 7317;
|
||||||
@@ -53,6 +54,8 @@ function createWindow(url: string): void {
|
|||||||
width: state.width,
|
width: state.width,
|
||||||
height: state.height,
|
height: state.height,
|
||||||
backgroundColor: '#09090b',
|
backgroundColor: '#09090b',
|
||||||
|
// Logo de la fenêtre / barre des tâches (sinon icône Electron générique sous Linux/Windows).
|
||||||
|
icon: resolveIconPath(),
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
partition: PARTITION,
|
partition: PARTITION,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
|
|||||||
@@ -14,6 +14,15 @@ export function resolveServerEntry(): string {
|
|||||||
return join(__dirname, '..', '..', 'server', 'dist', 'index.js');
|
return join(__dirname, '..', '..', 'server', 'dist', 'index.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Logo de l'app (fenêtre, tray, barre des tâches) : le mark Arboretum embarqué. */
|
||||||
|
export function resolveIconPath(): string {
|
||||||
|
// packagé : extraResources copie resources/icon.png à la racine de resources/.
|
||||||
|
// dev : depuis dist/main.js -> ../resources/icon.png.
|
||||||
|
return app.isPackaged
|
||||||
|
? join(process.resourcesPath, 'icon.png')
|
||||||
|
: join(__dirname, '..', 'resources', 'icon.png');
|
||||||
|
}
|
||||||
|
|
||||||
/** Binaire Node qui exécute le daemon (>= 22.16 : node:sqlite + ABI node-pty maîtrisé). */
|
/** Binaire Node qui exécute le daemon (>= 22.16 : node:sqlite + ABI node-pty maîtrisé). */
|
||||||
export function resolveNodeBin(): string {
|
export function resolveNodeBin(): string {
|
||||||
if (app.isPackaged) {
|
if (app.isPackaged) {
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
import { app, Menu, Tray, nativeImage } from 'electron';
|
import { Menu, Tray, nativeImage } from 'electron';
|
||||||
import { join } from 'node:path';
|
|
||||||
import { isAutoStartEnabled, setAutoStart } from './autostart';
|
import { isAutoStartEnabled, setAutoStart } from './autostart';
|
||||||
|
import { resolveIconPath } from './paths';
|
||||||
function iconPath(): string {
|
|
||||||
return app.isPackaged
|
|
||||||
? join(process.resourcesPath, 'icon.png')
|
|
||||||
: join(__dirname, '..', 'resources', 'icon.png');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Icône de barre système : ouvrir la fenêtre, basculer le lancement au login, quitter. */
|
/** Icône de barre système : ouvrir la fenêtre, basculer le lancement au login, quitter. */
|
||||||
export function createTray(opts: { show: () => void; quit: () => void }): Tray {
|
export function createTray(opts: { show: () => void; quit: () => void }): Tray {
|
||||||
const image = nativeImage.createFromPath(iconPath());
|
const image = nativeImage.createFromPath(resolveIconPath());
|
||||||
const tray = new Tray(image.isEmpty() ? nativeImage.createEmpty() : image.resize({ width: 18, height: 18 }));
|
const tray = new Tray(image.isEmpty() ? nativeImage.createEmpty() : image.resize({ width: 18, height: 18 }));
|
||||||
tray.setToolTip('Arboretum');
|
tray.setToolTip('Arboretum');
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@johanleroy/git-arboretum",
|
"name": "@johanleroy/git-arboretum",
|
||||||
"version": "2.0.0",
|
"version": "3.0.0",
|
||||||
"description": "Self-hosted web dashboard for git worktrees and the Claude Code sessions running on them",
|
"description": "Self-hosted web dashboard for git worktrees and the Claude Code sessions running on them",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
@@ -83,9 +83,13 @@ const dlgOptions = computed(() =>
|
|||||||
<span class="rounded border border-zinc-700 px-[5px] py-px font-mono text-[10px] text-zinc-500">⌘K</span>
|
<span class="rounded border border-zinc-700 px-[5px] py-px font-mono text-[10px] text-zinc-500">⌘K</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- nav primaire -->
|
<!-- nav primaire (fidèle à AppSidebar : IDE actif, puis Worktrees / Sessions / Groups) -->
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<div class="flex items-center gap-2.5 rounded-lg bg-zinc-800 px-2.5 py-1.5 text-zinc-100">
|
<div class="flex items-center gap-2.5 rounded-lg bg-zinc-800 px-2.5 py-1.5 text-zinc-100">
|
||||||
|
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="18" height="18" x="3" y="3" rx="2" /><path d="M3 9h18" /><path d="M9 21V9" /></svg>
|
||||||
|
<span class="flex-1 text-[12.5px] font-medium">{{ t('mIde') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2.5 rounded-lg px-2.5 py-1.5 text-zinc-400">
|
||||||
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15" /><circle cx="18" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><path d="M18 9a9 9 0 0 1-9 9" /></svg>
|
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15" /><circle cx="18" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><path d="M18 9a9 9 0 0 1-9 9" /></svg>
|
||||||
<span class="flex-1 text-[12.5px] font-medium">{{ t('mWorktrees') }}</span>
|
<span class="flex-1 text-[12.5px] font-medium">{{ t('mWorktrees') }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,7 +135,7 @@ const dlgOptions = computed(() =>
|
|||||||
<span class="rounded border border-zinc-700 px-1.5 py-px font-mono text-[10px] text-zinc-400">{{ locale.toUpperCase() }}</span>
|
<span class="rounded border border-zinc-700 px-1.5 py-px font-mono text-[10px] text-zinc-400">{{ locale.toUpperCase() }}</span>
|
||||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#34d399" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.268 21a2 2 0 0 0 3.464 0" /><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" /></svg>
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#34d399" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.268 21a2 2 0 0 0 3.464 0" /><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" /></svg>
|
||||||
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#71717a" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" /><polyline points="16 17 21 12 16 7" /><line x1="21" x2="9" y1="12" y2="12" /></svg>
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="#71717a" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" /><polyline points="16 17 21 12 16 7" /><line x1="21" x2="9" y1="12" y2="12" /></svg>
|
||||||
<span class="ml-auto font-mono text-[10px] text-zinc-600">v1.6.0</span>
|
<span class="ml-auto font-mono text-[10px] text-zinc-600">v2.0.0</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -230,6 +230,10 @@ const dlgOpts = computed(() => DLG_OPTS[locale.value as AppLocale]);
|
|||||||
|
|
||||||
<!-- barre d'onglets mobile (fidèle à MobileTabBar) -->
|
<!-- barre d'onglets mobile (fidèle à MobileTabBar) -->
|
||||||
<div class="absolute inset-x-0 bottom-0 flex border-t border-zinc-800 bg-zinc-950/95 backdrop-blur">
|
<div class="absolute inset-x-0 bottom-0 flex border-t border-zinc-800 bg-zinc-950/95 backdrop-blur">
|
||||||
|
<div class="flex flex-1 flex-col items-center gap-0.5 py-2 text-zinc-500">
|
||||||
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect width="18" height="18" x="3" y="3" rx="2" /><path d="M3 9h18" /><path d="M9 21V9" /></svg>
|
||||||
|
<span class="text-[10px]">{{ t('mIde') }}</span>
|
||||||
|
</div>
|
||||||
<div class="flex flex-1 flex-col items-center gap-0.5 py-2 text-zinc-500">
|
<div class="flex flex-1 flex-col items-center gap-0.5 py-2 text-zinc-500">
|
||||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15" /><circle cx="18" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><path d="M18 9a9 9 0 0 1-9 9" /></svg>
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="6" x2="6" y1="3" y2="15" /><circle cx="18" cy="6" r="3" /><circle cx="6" cy="18" r="3" /><path d="M18 9a9 9 0 0 1-9 9" /></svg>
|
||||||
<span class="text-[10px]">{{ t('mWorktrees') }}</span>
|
<span class="text-[10px]">{{ t('mWorktrees') }}</span>
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export default {
|
|||||||
footTag: 'a garden of branches, one pane of glass.',
|
footTag: 'a garden of branches, one pane of glass.',
|
||||||
license: 'MIT License',
|
license: 'MIT License',
|
||||||
coffee: 'Buy me a coffee',
|
coffee: 'Buy me a coffee',
|
||||||
|
mIde: 'IDE',
|
||||||
mWorktrees: 'Worktrees',
|
mWorktrees: 'Worktrees',
|
||||||
mSessions: 'Sessions',
|
mSessions: 'Sessions',
|
||||||
mGroups: 'Groups',
|
mGroups: 'Groups',
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export default {
|
|||||||
footTag: 'un jardin de branches, une seule vitre.',
|
footTag: 'un jardin de branches, une seule vitre.',
|
||||||
license: 'Licence MIT',
|
license: 'Licence MIT',
|
||||||
coffee: 'Paye-moi un café',
|
coffee: 'Paye-moi un café',
|
||||||
|
mIde: 'IDE',
|
||||||
mWorktrees: 'Worktrees',
|
mWorktrees: 'Worktrees',
|
||||||
mSessions: 'Sessions',
|
mSessions: 'Sessions',
|
||||||
mGroups: 'Groupes',
|
mGroups: 'Groupes',
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.3.0
|
||||||
|
|
||||||
|
Aligns with the daemon's **multi-project IDE** milestone: the web UI is now a single IDE that holds all
|
||||||
|
your open projects at once (a unified project / worktree / session tree, a tabbed Monaco editor, and
|
||||||
|
Claude terminals docked at the bottom), and ships as a native desktop app too. The extension stays a
|
||||||
|
lightweight visual worktree manager (no editor duplicated here), and its deep-link now opens that IDE:
|
||||||
|
|
||||||
|
- **Open Worktree IDE** now deep-links into the multi-project IDE (route `/workspace/:repoId/:wt`) and
|
||||||
|
focuses the chosen worktree in its unified tree.
|
||||||
|
- Worktree deep-link encoding unified with the web front through the shared `encodeWtKey`
|
||||||
|
(`@arboretum/shared`), so links resolve consistently on both sides.
|
||||||
|
|
||||||
## 0.2.0
|
## 0.2.0
|
||||||
|
|
||||||
Follows the daemon's "worktree IDE" milestone (P7→P12), while keeping the extension a lightweight
|
Follows the daemon's "worktree IDE" milestone (P7→P12), while keeping the extension a lightweight
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ integration on top of the [Arboretum](https://git.lidge.fr/johanleroy/arboretum)
|
|||||||
input: answer **Yes/No** without even opening the terminal (uses the daemon's `answer` command).
|
input: answer **Yes/No** without even opening the terminal (uses the daemon's `answer` command).
|
||||||
- **Git mutations** from the tree: create worktree, commit, push, fetch, pull, promote to main, with a
|
- **Git mutations** from the tree: create worktree, commit, push, fetch, pull, promote to main, with a
|
||||||
**detailed git status** on each worktree (staged / unstaged / conflicts and the last commit subject).
|
**detailed git status** on each worktree (staged / unstaged / conflicts and the last commit subject).
|
||||||
- **Open Worktree IDE**: jump from any worktree to its full `/workspace` view (file tree, Monaco editor,
|
- **Open Worktree IDE**: jump from any worktree into the multi-project IDE (unified project / worktree /
|
||||||
inline diffs, integrated terminal) in the browser. The extension stays a lightweight visual worktree
|
session tree, tabbed Monaco editor with inline diffs, docked terminals), in the browser or the native
|
||||||
manager: the heavy editing lives in the web IDE.
|
desktop app. The extension stays a lightweight visual worktree manager: the heavy editing lives in the IDE.
|
||||||
- **Workspace-aware**: the worktree matching your open folder is highlighted; start a session or create a
|
- **Workspace-aware**: the worktree matching your open folder is highlighted; start a session or create a
|
||||||
worktree for the current folder in one command.
|
worktree for the current folder in one command.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "git-arboretum",
|
"name": "git-arboretum",
|
||||||
"displayName": "Arboretum",
|
"displayName": "Arboretum",
|
||||||
"description": "Pilot your git worktrees and Claude Code sessions from VS Code: native terminals, live tree, waiting alerts.",
|
"description": "Pilot your git worktrees and Claude Code sessions from VS Code: native terminals, live tree, waiting alerts.",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"publisher": "johanleroy",
|
"publisher": "johanleroy",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -85,77 +85,332 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"commands": [
|
"commands": [
|
||||||
{ "command": "arboretum.signIn", "title": "Sign In", "category": "Arboretum" },
|
{
|
||||||
{ "command": "arboretum.signOut", "title": "Sign Out", "category": "Arboretum" },
|
"command": "arboretum.signIn",
|
||||||
{ "command": "arboretum.refresh", "title": "Refresh", "category": "Arboretum", "icon": "$(refresh)" },
|
"title": "Sign In",
|
||||||
{ "command": "arboretum.openDashboard", "title": "Open Dashboard in Browser", "category": "Arboretum", "icon": "$(globe)" },
|
"category": "Arboretum"
|
||||||
{ "command": "arboretum.attachSession", "title": "Attach Terminal", "category": "Arboretum", "icon": "$(terminal)" },
|
},
|
||||||
{ "command": "arboretum.observeSession", "title": "Observe Terminal (read-only)", "category": "Arboretum", "icon": "$(eye)" },
|
{
|
||||||
{ "command": "arboretum.answerSession", "title": "Answer Prompt…", "category": "Arboretum", "icon": "$(comment-discussion)" },
|
"command": "arboretum.signOut",
|
||||||
{ "command": "arboretum.killSession", "title": "Kill Session", "category": "Arboretum", "icon": "$(trash)" },
|
"title": "Sign Out",
|
||||||
{ "command": "arboretum.hideSession", "title": "Hide Session", "category": "Arboretum", "icon": "$(eye-closed)" },
|
"category": "Arboretum"
|
||||||
{ "command": "arboretum.resumeSession", "title": "Resume Session", "category": "Arboretum", "icon": "$(debug-restart)" },
|
},
|
||||||
{ "command": "arboretum.forkSession", "title": "Fork Session", "category": "Arboretum", "icon": "$(git-branch)" },
|
{
|
||||||
{ "command": "arboretum.createWorktree", "title": "Create Worktree…", "category": "Arboretum", "icon": "$(add)" },
|
"command": "arboretum.refresh",
|
||||||
{ "command": "arboretum.commitWorktree", "title": "Commit…", "category": "Arboretum", "icon": "$(git-commit)" },
|
"title": "Refresh",
|
||||||
{ "command": "arboretum.pushWorktree", "title": "Push", "category": "Arboretum", "icon": "$(repo-push)" },
|
"category": "Arboretum",
|
||||||
{ "command": "arboretum.fetchWorktree", "title": "Fetch", "category": "Arboretum", "icon": "$(cloud-download)" },
|
"icon": "$(refresh)"
|
||||||
{ "command": "arboretum.pullWorktree", "title": "Pull…", "category": "Arboretum", "icon": "$(arrow-down)" },
|
},
|
||||||
{ "command": "arboretum.promoteWorktree", "title": "Promote to Main", "category": "Arboretum", "icon": "$(arrow-up)" },
|
{
|
||||||
{ "command": "arboretum.openWorktreeIde", "title": "Open Worktree IDE", "category": "Arboretum", "icon": "$(link-external)" },
|
"command": "arboretum.openDashboard",
|
||||||
{ "command": "arboretum.startSession", "title": "Start Claude Session", "category": "Arboretum", "icon": "$(play)" },
|
"title": "Open Dashboard in Browser",
|
||||||
{ "command": "arboretum.startGroupSession", "title": "Start Group Session…", "category": "Arboretum", "icon": "$(play)" },
|
"category": "Arboretum",
|
||||||
{ "command": "arboretum.startSessionHere", "title": "Start Session in Current Folder", "category": "Arboretum" },
|
"icon": "$(globe)"
|
||||||
{ "command": "arboretum.createWorktreeHere", "title": "Create Worktree for Current Folder…", "category": "Arboretum" },
|
},
|
||||||
{ "command": "arboretum.revealWorktree", "title": "Reveal Worktree for Current Folder", "category": "Arboretum" }
|
{
|
||||||
|
"command": "arboretum.attachSession",
|
||||||
|
"title": "Attach Terminal",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(terminal)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.observeSession",
|
||||||
|
"title": "Observe Terminal (read-only)",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(eye)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.answerSession",
|
||||||
|
"title": "Answer Prompt…",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(comment-discussion)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.killSession",
|
||||||
|
"title": "Kill Session",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(trash)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.hideSession",
|
||||||
|
"title": "Hide Session",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(eye-closed)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.resumeSession",
|
||||||
|
"title": "Resume Session",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(debug-restart)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.forkSession",
|
||||||
|
"title": "Fork Session",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(git-branch)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.createWorktree",
|
||||||
|
"title": "Create Worktree…",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(add)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.commitWorktree",
|
||||||
|
"title": "Commit…",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(git-commit)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.pushWorktree",
|
||||||
|
"title": "Push",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(repo-push)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.fetchWorktree",
|
||||||
|
"title": "Fetch",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(cloud-download)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.pullWorktree",
|
||||||
|
"title": "Pull…",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(arrow-down)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.promoteWorktree",
|
||||||
|
"title": "Promote to Main",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(arrow-up)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.openWorktreeIde",
|
||||||
|
"title": "Open Worktree IDE",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(link-external)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.startSession",
|
||||||
|
"title": "Start Claude Session",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(play)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.startGroupSession",
|
||||||
|
"title": "Start Group Session…",
|
||||||
|
"category": "Arboretum",
|
||||||
|
"icon": "$(play)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.startSessionHere",
|
||||||
|
"title": "Start Session in Current Folder",
|
||||||
|
"category": "Arboretum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.createWorktreeHere",
|
||||||
|
"title": "Create Worktree for Current Folder…",
|
||||||
|
"category": "Arboretum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.revealWorktree",
|
||||||
|
"title": "Reveal Worktree for Current Folder",
|
||||||
|
"category": "Arboretum"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"menus": {
|
"menus": {
|
||||||
"view/title": [
|
"view/title": [
|
||||||
{ "command": "arboretum.refresh", "when": "view == arboretum.repos || view == arboretum.groups", "group": "navigation" },
|
{
|
||||||
{ "command": "arboretum.openDashboard", "when": "view == arboretum.repos", "group": "navigation" },
|
"command": "arboretum.refresh",
|
||||||
{ "command": "arboretum.signOut", "when": "view == arboretum.repos && arboretum.connected", "group": "1_auth" },
|
"when": "view == arboretum.repos || view == arboretum.groups",
|
||||||
{ "command": "arboretum.signIn", "when": "view == arboretum.repos && !arboretum.connected", "group": "1_auth" }
|
"group": "navigation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.openDashboard",
|
||||||
|
"when": "view == arboretum.repos",
|
||||||
|
"group": "navigation"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.signOut",
|
||||||
|
"when": "view == arboretum.repos && arboretum.connected",
|
||||||
|
"group": "1_auth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.signIn",
|
||||||
|
"when": "view == arboretum.repos && !arboretum.connected",
|
||||||
|
"group": "1_auth"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"view/item/context": [
|
"view/item/context": [
|
||||||
{ "command": "arboretum.createWorktree", "when": "viewItem == arboretum:repo", "group": "inline" },
|
{
|
||||||
{ "command": "arboretum.startSession", "when": "viewItem == arboretum:repo", "group": "1_session" },
|
"command": "arboretum.createWorktree",
|
||||||
{ "command": "arboretum.openWorktreeIde", "when": "viewItem == arboretum:worktree", "group": "inline" },
|
"when": "viewItem == arboretum:repo",
|
||||||
{ "command": "arboretum.commitWorktree", "when": "viewItem == arboretum:worktree", "group": "1_git" },
|
"group": "inline"
|
||||||
{ "command": "arboretum.pushWorktree", "when": "viewItem == arboretum:worktree", "group": "1_git" },
|
},
|
||||||
{ "command": "arboretum.fetchWorktree", "when": "viewItem == arboretum:worktree", "group": "1_git" },
|
{
|
||||||
{ "command": "arboretum.pullWorktree", "when": "viewItem == arboretum:worktree", "group": "1_git" },
|
"command": "arboretum.startSession",
|
||||||
{ "command": "arboretum.promoteWorktree", "when": "viewItem == arboretum:worktree", "group": "2_git" },
|
"when": "viewItem == arboretum:repo",
|
||||||
{ "command": "arboretum.openWorktreeIde", "when": "viewItem == arboretum:worktree", "group": "2_git" },
|
"group": "1_session"
|
||||||
{ "command": "arboretum.startSession", "when": "viewItem == arboretum:worktree", "group": "3_session" },
|
},
|
||||||
{ "command": "arboretum.attachSession", "when": "viewItem =~ /arboretum:session:live/", "group": "inline" },
|
{
|
||||||
{ "command": "arboretum.observeSession", "when": "viewItem =~ /arboretum:session:live/", "group": "1_term" },
|
"command": "arboretum.openWorktreeIde",
|
||||||
{ "command": "arboretum.answerSession", "when": "viewItem =~ /arboretum:session:live:.*waiting/", "group": "1_term" },
|
"when": "viewItem == arboretum:worktree",
|
||||||
{ "command": "arboretum.killSession", "when": "viewItem =~ /arboretum:session:live/", "group": "9_danger" },
|
"group": "inline"
|
||||||
{ "command": "arboretum.resumeSession", "when": "viewItem =~ /arboretum:session:dead/", "group": "inline" },
|
},
|
||||||
{ "command": "arboretum.forkSession", "when": "viewItem =~ /arboretum:session/", "group": "2_term" },
|
{
|
||||||
{ "command": "arboretum.hideSession", "when": "viewItem =~ /arboretum:session:.*discovered/", "group": "9_danger" },
|
"command": "arboretum.commitWorktree",
|
||||||
{ "command": "arboretum.startGroupSession", "when": "viewItem == arboretum:group", "group": "inline" }
|
"when": "viewItem == arboretum:worktree",
|
||||||
|
"group": "1_git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.pushWorktree",
|
||||||
|
"when": "viewItem == arboretum:worktree",
|
||||||
|
"group": "1_git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.fetchWorktree",
|
||||||
|
"when": "viewItem == arboretum:worktree",
|
||||||
|
"group": "1_git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.pullWorktree",
|
||||||
|
"when": "viewItem == arboretum:worktree",
|
||||||
|
"group": "1_git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.promoteWorktree",
|
||||||
|
"when": "viewItem == arboretum:worktree",
|
||||||
|
"group": "2_git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.openWorktreeIde",
|
||||||
|
"when": "viewItem == arboretum:worktree",
|
||||||
|
"group": "2_git"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.startSession",
|
||||||
|
"when": "viewItem == arboretum:worktree",
|
||||||
|
"group": "3_session"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.attachSession",
|
||||||
|
"when": "viewItem =~ /arboretum:session:live/",
|
||||||
|
"group": "inline"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.observeSession",
|
||||||
|
"when": "viewItem =~ /arboretum:session:live/",
|
||||||
|
"group": "1_term"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.answerSession",
|
||||||
|
"when": "viewItem =~ /arboretum:session:live:.*waiting/",
|
||||||
|
"group": "1_term"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.killSession",
|
||||||
|
"when": "viewItem =~ /arboretum:session:live/",
|
||||||
|
"group": "9_danger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.resumeSession",
|
||||||
|
"when": "viewItem =~ /arboretum:session:dead/",
|
||||||
|
"group": "inline"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.forkSession",
|
||||||
|
"when": "viewItem =~ /arboretum:session/",
|
||||||
|
"group": "2_term"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.hideSession",
|
||||||
|
"when": "viewItem =~ /arboretum:session:.*discovered/",
|
||||||
|
"group": "9_danger"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.startGroupSession",
|
||||||
|
"when": "viewItem == arboretum:group",
|
||||||
|
"group": "inline"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"commandPalette": [
|
"commandPalette": [
|
||||||
{ "command": "arboretum.refresh", "when": "arboretum.connected" },
|
{
|
||||||
{ "command": "arboretum.signOut", "when": "arboretum.connected" },
|
"command": "arboretum.refresh",
|
||||||
{ "command": "arboretum.attachSession", "when": "false" },
|
"when": "arboretum.connected"
|
||||||
{ "command": "arboretum.observeSession", "when": "false" },
|
},
|
||||||
{ "command": "arboretum.answerSession", "when": "false" },
|
{
|
||||||
{ "command": "arboretum.killSession", "when": "false" },
|
"command": "arboretum.signOut",
|
||||||
{ "command": "arboretum.hideSession", "when": "false" },
|
"when": "arboretum.connected"
|
||||||
{ "command": "arboretum.resumeSession", "when": "false" },
|
},
|
||||||
{ "command": "arboretum.forkSession", "when": "false" },
|
{
|
||||||
{ "command": "arboretum.createWorktree", "when": "false" },
|
"command": "arboretum.attachSession",
|
||||||
{ "command": "arboretum.commitWorktree", "when": "false" },
|
"when": "false"
|
||||||
{ "command": "arboretum.pushWorktree", "when": "false" },
|
},
|
||||||
{ "command": "arboretum.fetchWorktree", "when": "false" },
|
{
|
||||||
{ "command": "arboretum.pullWorktree", "when": "false" },
|
"command": "arboretum.observeSession",
|
||||||
{ "command": "arboretum.promoteWorktree", "when": "false" },
|
"when": "false"
|
||||||
{ "command": "arboretum.openWorktreeIde", "when": "false" },
|
},
|
||||||
{ "command": "arboretum.startSession", "when": "false" },
|
{
|
||||||
{ "command": "arboretum.startGroupSession", "when": "false" },
|
"command": "arboretum.answerSession",
|
||||||
{ "command": "arboretum.revealWorktree", "when": "false" }
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.killSession",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.hideSession",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.resumeSession",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.forkSession",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.createWorktree",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.commitWorktree",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.pushWorktree",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.fetchWorktree",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.pullWorktree",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.promoteWorktree",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.openWorktreeIde",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.startSession",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.startGroupSession",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "arboretum.revealWorktree",
|
||||||
|
"when": "false"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user