@ironmussa/funny 0.1.4 → 0.1.5
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/README.md +14 -19
- package/bin/funny.js +37 -66
- package/package.json +1 -1
- package/packages/client/dist/assets/{AcceptInvitePage-D2QlnwXy.js → AcceptInvitePage-Bz8azFPS.js} +1 -1
- package/packages/client/dist/assets/{ActivityPane-kz91jVAM.js → ActivityPane-DY9GzNxE.js} +1 -1
- package/packages/client/dist/assets/{AddProjectView-DWAvSEfh.js → AddProjectView-CS9PMuwG.js} +1 -1
- package/packages/client/dist/assets/{AllThreadsView-CEwWCoDj.js → AllThreadsView-wK8q3SsH.js} +1 -1
- package/packages/client/dist/assets/{AnalyticsView-DAWyZa5z.js → AnalyticsView-CZlraPUL.js} +1 -1
- package/packages/client/dist/assets/{App-BzBTjMsb.js → App-9j57f85r.js} +3 -3
- package/packages/client/dist/assets/{AutomationInboxView-zNA4E_CB.js → AutomationInboxView-CDlKbclJ.js} +1 -1
- package/packages/client/dist/assets/{BrowserPanel-CLETmPIM.js → BrowserPanel-B7imTgqS.js} +1 -1
- package/packages/client/dist/assets/{BrowserPreview-D6-GY7Lk.js → BrowserPreview-DOUyF-0l.js} +1 -1
- package/packages/client/dist/assets/{CircuitBreakerDialog-DCiRlBvD.js → CircuitBreakerDialog-C20MeUCC.js} +1 -1
- package/packages/client/dist/assets/{CommandPalette-MY2bMCP4.js → CommandPalette-B55GwOW8.js} +1 -1
- package/packages/client/dist/assets/{CommentsPane-tyNsUWqs.js → CommentsPane-js2FWA8j.js} +1 -1
- package/packages/client/dist/assets/{CsvTable-DB3mtG8a.js → CsvTable-CBgoinyU.js} +1 -1
- package/packages/client/dist/assets/{FileSearchDialog-4lhZizzD.js → FileSearchDialog-HCT2Hz0_.js} +1 -1
- package/packages/client/dist/assets/{FileTree-DESC68xP.js → FileTree-DUODDbNL.js} +1 -1
- package/packages/client/dist/assets/{FolderPicker-B5JTJeAY.js → FolderPicker-DEwPUyou.js} +1 -1
- package/packages/client/dist/assets/{GeneralSettingsView-SHsx-3nX.js → GeneralSettingsView-DkKqhc1H.js} +2 -2
- package/packages/client/dist/assets/{GitProgressModal-C_W78wcH.js → GitProgressModal-wumxtrFG.js} +1 -1
- package/packages/client/dist/assets/{LiveColumnsView-XMHr9OEz.js → LiveColumnsView-C9sNbvg3.js} +1 -1
- package/packages/client/dist/assets/{LoginPage-CQ9fP0F4.js → LoginPage-5VQrfpbg.js} +1 -1
- package/packages/client/dist/assets/{MediaPreview-2jhQWqiK.js → MediaPreview-DzlqoZwu.js} +1 -1
- package/packages/client/dist/assets/{MediaPreviewDialog-ZMIFbNgy.js → MediaPreviewDialog-C9ZILO-C.js} +1 -1
- package/packages/client/dist/assets/{MermaidBlock-Ub8VkOL4.js → MermaidBlock-xuBty90Y.js} +1 -1
- package/packages/client/dist/assets/{MobilePage-C9PpVVfq.js → MobilePage-B3b4tpPe.js} +2 -2
- package/packages/client/dist/assets/{MonacoEditorDialog-Co2xdBGu.js → MonacoEditorDialog-DfJmfHiL.js} +1 -1
- package/packages/client/dist/assets/{OrchestratorView-CJ529EFF.js → OrchestratorView--Df-JFQd.js} +1 -1
- package/packages/client/dist/assets/{PreferencesPanel-Cz4IuCEn.js → PreferencesPanel-CAhnrHw0.js} +1 -1
- package/packages/client/dist/assets/{PreviewBrowser-Csflu6Sr.js → PreviewBrowser-DKz2hR71.js} +1 -1
- package/packages/client/dist/assets/{ProjectFilesPane-C0-WA5jW.js → ProjectFilesPane-BbOGQ3kp.js} +1 -1
- package/packages/client/dist/assets/{ProjectHeader-Bf1gaA1F.js → ProjectHeader-DZ9UUaqW.js} +1 -1
- package/packages/client/dist/assets/{ProjectHooksSettings-DdChzrcv.js → ProjectHooksSettings-BGHkJMxp.js} +1 -1
- package/packages/client/dist/assets/{ReviewPane-DSytotSX.js → ReviewPane-83OOq41s.js} +1 -1
- package/packages/client/dist/assets/{SearchablePicker-ePO3BIOx.js → SearchablePicker-Cz6G4abl.js} +1 -1
- package/packages/client/dist/assets/{SettingsDetailView-DH9yGrff.js → SettingsDetailView-DwWVM6qW.js} +1 -1
- package/packages/client/dist/assets/{SettingsPageContent-C8EUEhHQ.js → SettingsPageContent-Cre7rDf1.js} +3 -3
- package/packages/client/dist/assets/{SetupWizard-DXcV9Vsz.js → SetupWizard-im6s3weh.js} +1 -1
- package/packages/client/dist/assets/{Sidebar-CnSzyO_S.js → Sidebar-C7PRUuZe.js} +1 -1
- package/packages/client/dist/assets/{StashTab-BZn6-Wn3.js → StashTab-CzC8WNxJ.js} +1 -1
- package/packages/client/dist/assets/{TestRunnerPane-Cz8KHMSp.js → TestRunnerPane-DjzPYNLs.js} +1 -1
- package/packages/client/dist/assets/{TextSearchDialog-BWChISXp.js → TextSearchDialog-DcYyEuMd.js} +1 -1
- package/packages/client/dist/assets/{ThreadPowerline-CX-bm7_6.js → ThreadPowerline-CTbQgGLL.js} +1 -1
- package/packages/client/dist/assets/{ThreadStatusPin-CjNRn4Rx.js → ThreadStatusPin-CYsH0F8e.js} +1 -1
- package/packages/client/dist/assets/{ThreadView-DbwUcWMo.js → ThreadView-DUaDYGnz.js} +1 -1
- package/packages/client/dist/assets/{app-store-BwZB2xp_.js → app-store-CVcOgstJ.js} +1 -1
- package/packages/client/dist/assets/{automation-store-DBy-NuND.js → automation-store-DteeWFhQ.js} +1 -1
- package/packages/client/dist/assets/{browser-panel-store-Bih_qYi6.js → browser-panel-store-3T75tTA2.js} +2 -2
- package/packages/client/dist/assets/{button-DeEOU1Fb.js → button-Bi9_EZFh.js} +1 -1
- package/packages/client/dist/assets/{combine-ISTWP4AL.js → combine-JFcc9GB_.js} +1 -1
- package/packages/client/dist/assets/{comment-store-Be3Fd_A7.js → comment-store-DgECCb00.js} +1 -1
- package/packages/client/dist/assets/{diff-parse-738OLLMl.js → diff-parse-CRTMJKOI.js} +1 -1
- package/packages/client/dist/assets/{element-CuNJpCWR.js → element-DgNlo25W.js} +1 -1
- package/packages/client/dist/assets/{go-to-thread-XoxeW5m_.js → go-to-thread-DJT-R5-a.js} +1 -1
- package/packages/client/dist/assets/{index-BsxcqNXe.js → index-Bmp1UFM1.js} +2 -2
- package/packages/client/dist/assets/{input-DV30TVat.js → input-BGZP-HTx.js} +1 -1
- package/packages/client/dist/assets/{items-_g3-I08l.js → items-C-m69VjA.js} +1 -1
- package/packages/client/dist/assets/{job-store-C5Ten7SL.js → job-store-BBERDOJO.js} +1 -1
- package/packages/client/dist/assets/{kbd-C7L0hICt.js → kbd-BrgsdFIb.js} +1 -1
- package/packages/client/dist/assets/{loading-state-BQjalkhM.js → loading-state-DGzdeccZ.js} +1 -1
- package/packages/client/dist/assets/{markdown-components-D4Y3yxJk.js → markdown-components-DbIYr3N1.js} +1 -1
- package/packages/client/dist/assets/{native-git-store-B9ZRXl6g.js → native-git-store-CYZj3IWH.js} +1 -1
- package/packages/client/dist/assets/{orchestrator-store-Vf7hIdtx.js → orchestrator-store-B-nOHeLj.js} +1 -1
- package/packages/client/dist/assets/{pipeline-approval-store-BzDMPaHv.js → pipeline-approval-store-DOhazL3I.js} +1 -1
- package/packages/client/dist/assets/{pr-detail-store-ZCVq5jO-.js → pr-detail-store-BJ3P2gik.js} +1 -1
- package/packages/client/dist/assets/{providers-CBJW4tBi.js → providers-BD43Asis.js} +1 -1
- package/packages/client/dist/assets/{sidebar-BzOM_jNz.js → sidebar-CL7TSCIO.js} +1 -1
- package/packages/client/dist/assets/{tabs-C98UD1RJ.js → tabs-DWlrx7U8.js} +1 -1
- package/packages/client/dist/assets/{test-store-BbGZeyOw.js → test-store-C40x04Fz.js} +1 -1
- package/packages/client/dist/assets/{tooltip-icon-button-z_YicoMI.js → tooltip-icon-button-DUnFi3-p.js} +1 -1
- package/packages/client/dist/assets/use-active-thread-id-De6IjhUY.js +1 -0
- package/packages/client/dist/assets/{use-branch-switch-mtbqs9Jw.js → use-branch-switch-4nDECRMh.js} +1 -1
- package/packages/client/dist/assets/{use-image-lightbox-D_bv65q5.js → use-image-lightbox-13VQ9o9i.js} +1 -1
- package/packages/client/dist/assets/{use-stable-navigate-CTxO5fW7.js → use-stable-navigate-uXVRGpin.js} +1 -1
- package/packages/client/dist/assets/{use-terminal-scope-DdXii8xw.js → use-terminal-scope-DHhH7AvQ.js} +1 -1
- package/packages/client/dist/assets/{use-thread-creation-Dyd2HCG5.js → use-thread-creation-CgT3SuOi.js} +1 -1
- package/packages/client/dist/assets/{use-thread-search-BIXj6zRV.js → use-thread-search-CbgQmS3O.js} +1 -1
- package/packages/client/dist/assets/{use-todo-panel-D9pAUf5W.js → use-todo-panel-CsXYDjtr.js} +1 -1
- package/packages/client/dist/assets/{use-unified-prompt-model-groups-CjX0kT2J.js → use-unified-prompt-model-groups-CUMps-gq.js} +1 -1
- package/packages/client/dist/assets/{use-ws-CeBgbigk.js → use-ws-DVvliZBW.js} +3 -3
- package/packages/client/dist/assets/{visualizer-loader-BVlcAMHr.js → visualizer-loader-Dv9AyyLp.js} +1 -1
- package/packages/client/dist/assets/{watcher-store-C6B9wUDN.js → watcher-store-srZSE5jI.js} +1 -1
- package/packages/client/dist/index.html +1 -1
- package/packages/runtime/dist/index.js +2 -2
- package/packages/runtime/dist/index.js.map +1 -1
- package/packages/client/dist/assets/use-active-thread-id-DE1fU7g0.js +0 -1
package/README.md
CHANGED
|
@@ -105,19 +105,13 @@ The admin can create additional user accounts from the central server's API.
|
|
|
105
105
|
|
|
106
106
|
#### Step 2: Each team member connects
|
|
107
107
|
|
|
108
|
-
Each team member runs funny locally with the `--team`
|
|
108
|
+
Each team member runs funny locally with the `--team` flag:
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
-
funny --team http://<central-server-ip>:3002
|
|
111
|
+
funny --team http://<central-server-ip>:3002
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
The
|
|
115
|
-
|
|
116
|
-
On first run, the `--team` and `--token` values are **automatically saved** to `~/.funny/.env`, so subsequent runs only need:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
funny
|
|
120
|
-
```
|
|
114
|
+
The runner prints a short device-link code. In the central server UI, open **Settings > Runners**, click **Link a runner**, enter the code, and approve it. A plain `funny` or `bunx @ironmussa/funny@latest` always starts local by default; every team run should pass `--team <url>` explicitly.
|
|
121
115
|
|
|
122
116
|
This starts the full funny app locally (UI, git, agents) **and** connects to the central server to:
|
|
123
117
|
|
|
@@ -159,6 +153,7 @@ Team member A Team member B
|
|
|
159
153
|
| `--auth-mode <mode>` | Authentication mode: `local` or `multi` | `local` |
|
|
160
154
|
| `--team <url>` | Connect to a central team server | - |
|
|
161
155
|
| `--token <token>` | Runner invite token for team registration | - |
|
|
156
|
+
| `--local` | Start standalone; cannot combine with `--team` | `false` |
|
|
162
157
|
| `--help` | Show help message | - |
|
|
163
158
|
|
|
164
159
|
**funny-server** (team coordination server)
|
|
@@ -171,19 +166,19 @@ Team member A Team member B
|
|
|
171
166
|
|
|
172
167
|
### Persistent Configuration
|
|
173
168
|
|
|
174
|
-
|
|
169
|
+
Saved values in `~/.funny/.env` do not activate team mode. A plain `funny` or `bunx @ironmussa/funny@latest` always starts in local mode by default. To connect to a central server, pass `--team <url>` explicitly.
|
|
175
170
|
|
|
176
171
|
```bash
|
|
177
|
-
#
|
|
178
|
-
funny --team http://192.168.1.10:3002 --token utkn_xxx
|
|
179
|
-
|
|
180
|
-
# Every subsequent run — just this
|
|
172
|
+
# Local standalone
|
|
181
173
|
funny
|
|
174
|
+
|
|
175
|
+
# Team runner
|
|
176
|
+
funny --team http://192.168.1.10:3002
|
|
182
177
|
```
|
|
183
178
|
|
|
184
|
-
**Precedence order:** CLI flags > shell environment variables > saved `~/.funny/.env
|
|
179
|
+
**Precedence order:** CLI flags > shell environment variables > saved non-team values in `~/.funny/.env`. Team mode requires `--team <url>`.
|
|
185
180
|
|
|
186
|
-
To change the server,
|
|
181
|
+
To change the server, pass `--team` with the new URL.
|
|
187
182
|
|
|
188
183
|
### Environment Variables
|
|
189
184
|
|
|
@@ -192,8 +187,8 @@ To change the server, simply pass `--team` again with a new URL — the saved co
|
|
|
192
187
|
| `PORT` | Server port | `3001` / `3002` | both |
|
|
193
188
|
| `HOST` | Server hostname | `127.0.0.1` | both |
|
|
194
189
|
| `AUTH_MODE` | Authentication mode (`local`/`multi`) | `local` | funny |
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
190
|
+
| `RUNNER_INVITE_TOKEN` | Runner invite token for `--team` classic flow | - | funny |
|
|
191
|
+
| `RUNNER_AUTH_SECRET` | Shared secret for `--team` classic flow | - | funny |
|
|
197
192
|
| `CORS_ORIGIN` | Custom CORS origins (comma-separated) | Auto-configured | both |
|
|
198
193
|
| `FUNNY_CENTRAL_DATA_DIR` | Central server data directory | `~/.funny-central` | funny-server |
|
|
199
194
|
| `LOG_LEVEL` | Log level (debug/info/warn/error) | `info` | funny-server |
|
|
@@ -489,7 +484,7 @@ run `bun run dev` as usual, or prefix any command with `PORTLESS=0`.
|
|
|
489
484
|
|
|
490
485
|
```
|
|
491
486
|
~/.funny/
|
|
492
|
-
├── .env #
|
|
487
|
+
├── .env # Optional local env file; team connection keys are ignored by the CLI
|
|
493
488
|
├── data.db # SQLite database (projects, threads, messages)
|
|
494
489
|
├── auth-token # Bearer token for local auth
|
|
495
490
|
├── auth-secret # Session secret (multi-user mode)
|
package/bin/funny.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { existsSync, readFileSync
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { resolve, join } from 'path';
|
|
5
5
|
import { parseArgs } from 'util';
|
|
@@ -8,6 +8,7 @@ import { parseArgs } from 'util';
|
|
|
8
8
|
|
|
9
9
|
const FUNNY_DIR = join(homedir(), '.funny');
|
|
10
10
|
const ENV_FILE = join(FUNNY_DIR, '.env');
|
|
11
|
+
const TEAM_ENV_KEYS = new Set(['TEAM_SERVER_URL', 'RUNNER_INVITE_TOKEN', 'RUNNER_AUTH_SECRET']);
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Parse a simple .env file into key-value pairs.
|
|
@@ -37,6 +38,8 @@ function parseEnvFile(content) {
|
|
|
37
38
|
/**
|
|
38
39
|
* Load saved env vars from ~/.funny/.env.
|
|
39
40
|
* Only sets values that are NOT already in process.env (env vars take precedence).
|
|
41
|
+
* Team connection keys are intentionally ignored: connecting to a central server
|
|
42
|
+
* must be requested explicitly with --team.
|
|
40
43
|
*/
|
|
41
44
|
function loadSavedEnv() {
|
|
42
45
|
if (!existsSync(ENV_FILE)) return;
|
|
@@ -44,6 +47,7 @@ function loadSavedEnv() {
|
|
|
44
47
|
const content = readFileSync(ENV_FILE, 'utf-8');
|
|
45
48
|
const vars = parseEnvFile(content);
|
|
46
49
|
for (const [key, value] of Object.entries(vars)) {
|
|
50
|
+
if (TEAM_ENV_KEYS.has(key)) continue;
|
|
47
51
|
if (!process.env[key]) {
|
|
48
52
|
process.env[key] = value;
|
|
49
53
|
}
|
|
@@ -53,51 +57,17 @@ function loadSavedEnv() {
|
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
/**
|
|
57
|
-
* Save env vars to ~/.funny/.env, merging with existing values.
|
|
58
|
-
* Creates ~/.funny directory if it doesn't exist.
|
|
59
|
-
*/
|
|
60
|
-
function saveEnv(updates) {
|
|
61
|
-
// Read existing values
|
|
62
|
-
let existing = {};
|
|
63
|
-
if (existsSync(ENV_FILE)) {
|
|
64
|
-
try {
|
|
65
|
-
existing = parseEnvFile(readFileSync(ENV_FILE, 'utf-8'));
|
|
66
|
-
} catch {}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Merge updates
|
|
70
|
-
const merged = { ...existing, ...updates };
|
|
71
|
-
|
|
72
|
-
// Write header + key=value pairs
|
|
73
|
-
const lines = ['# Saved by funny CLI — do not edit while running'];
|
|
74
|
-
for (const [key, value] of Object.entries(merged)) {
|
|
75
|
-
lines.push(`${key}=${value}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Ensure directory exists
|
|
79
|
-
mkdirSync(FUNNY_DIR, { recursive: true });
|
|
80
|
-
|
|
81
|
-
// Write with restricted permissions (0o600) — contains tokens
|
|
82
|
-
writeFileSync(ENV_FILE, lines.join('\n') + '\n', { mode: 0o600 });
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// ── Load saved config before parsing CLI args ─────────────
|
|
86
|
-
loadSavedEnv();
|
|
87
|
-
|
|
88
60
|
// ── `funny ext` — manage visualizer extensions (runs without the server) ──
|
|
89
61
|
// Dispatched BEFORE the strict parseArgs below, because `ext` subcommands carry
|
|
90
62
|
// their own flags (--ref, --subdir) that the top-level parser doesn't know.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
process.exit(await runExtCommand(rawArgs.slice(1)));
|
|
95
|
-
}
|
|
63
|
+
const rawArgs = process.argv.slice(2);
|
|
64
|
+
if (rawArgs[0] === 'ext') {
|
|
65
|
+
process.exit(await runExtCommand(rawArgs.slice(1)));
|
|
96
66
|
}
|
|
97
67
|
|
|
98
68
|
// ── Parse CLI arguments ───────────────────────────────────
|
|
99
69
|
|
|
100
|
-
const { values
|
|
70
|
+
const { values } = parseArgs({
|
|
101
71
|
options: {
|
|
102
72
|
port: {
|
|
103
73
|
type: 'string',
|
|
@@ -121,6 +91,10 @@ const { values, positionals } = parseArgs({
|
|
|
121
91
|
type: 'string',
|
|
122
92
|
description: 'Shared RUNNER_AUTH_SECRET (must match the central server) for team mode',
|
|
123
93
|
},
|
|
94
|
+
local: {
|
|
95
|
+
type: 'boolean',
|
|
96
|
+
default: false,
|
|
97
|
+
},
|
|
124
98
|
help: {
|
|
125
99
|
type: 'boolean',
|
|
126
100
|
},
|
|
@@ -128,6 +102,22 @@ const { values, positionals } = parseArgs({
|
|
|
128
102
|
allowPositionals: true,
|
|
129
103
|
});
|
|
130
104
|
|
|
105
|
+
if (values.local && values.team) {
|
|
106
|
+
console.error('[funny] ERROR: --local cannot be combined with --team.');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Saved and inherited team credentials are intentionally ignored unless --team
|
|
111
|
+
// is present. A plain `funny` or `bunx @ironmussa/funny` should always start
|
|
112
|
+
// local, even if the shell or ~/.funny/.env contains stale team variables.
|
|
113
|
+
loadSavedEnv();
|
|
114
|
+
|
|
115
|
+
if (!values.team || values.local) {
|
|
116
|
+
delete process.env.TEAM_SERVER_URL;
|
|
117
|
+
delete process.env.RUNNER_INVITE_TOKEN;
|
|
118
|
+
delete process.env.RUNNER_AUTH_SECRET;
|
|
119
|
+
}
|
|
120
|
+
|
|
131
121
|
if (values.help) {
|
|
132
122
|
console.log(`
|
|
133
123
|
funny - Parallel Claude Code agent orchestration
|
|
@@ -141,6 +131,7 @@ Options:
|
|
|
141
131
|
--team <url> Connect to a central team server (e.g. http://192.168.1.10:3002)
|
|
142
132
|
--token <token> Runner invite token for team server registration
|
|
143
133
|
--secret <secret> Shared RUNNER_AUTH_SECRET — must match the central server (team mode)
|
|
134
|
+
--local Start standalone; cannot be combined with --team
|
|
144
135
|
--help Show this help message
|
|
145
136
|
|
|
146
137
|
Team Mode:
|
|
@@ -151,10 +142,7 @@ Team Mode:
|
|
|
151
142
|
|
|
152
143
|
funny prints a short code; open the server, go to Settings ▸ Runners ▸
|
|
153
144
|
"Link a runner", enter the code, and approve. The runner then receives its
|
|
154
|
-
credentials automatically — no secret or token to copy.
|
|
155
|
-
to ~/.funny so later runs only need:
|
|
156
|
-
|
|
157
|
-
funny
|
|
145
|
+
credentials automatically — no secret or token to copy.
|
|
158
146
|
|
|
159
147
|
Classic flow (advanced): you may instead supply the shared secret + an invite
|
|
160
148
|
token yourself. RUNNER_AUTH_SECRET must match the central server's value:
|
|
@@ -176,15 +164,15 @@ Authentication:
|
|
|
176
164
|
Environment Variables:
|
|
177
165
|
PORT Server port
|
|
178
166
|
HOST Server host
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
RUNNER_AUTH_SECRET Shared secret matching the central server (same as --secret)
|
|
167
|
+
RUNNER_INVITE_TOKEN Runner invite token for --team classic flow
|
|
168
|
+
RUNNER_AUTH_SECRET Shared secret for --team classic flow
|
|
182
169
|
CORS_ORIGIN Custom CORS origins (comma-separated)
|
|
183
170
|
DB_MODE Database mode: sqlite (default) or postgres
|
|
184
171
|
DATABASE_URL PostgreSQL connection URL (when DB_MODE=postgres)
|
|
185
172
|
|
|
186
173
|
Config:
|
|
187
174
|
Saved config: ~/.funny/.env
|
|
175
|
+
Note: saved and inherited team connection keys are ignored; pass --team to connect.
|
|
188
176
|
Database: ~/.funny/data.db
|
|
189
177
|
|
|
190
178
|
For more information, visit: https://github.com/anthropics/funny
|
|
@@ -197,7 +185,7 @@ For more information, visit: https://github.com/anthropics/funny
|
|
|
197
185
|
process.env.PORT = values.port;
|
|
198
186
|
process.env.HOST = values.host;
|
|
199
187
|
|
|
200
|
-
// CLI --team and --token override env vars
|
|
188
|
+
// CLI --team and --token override env vars for this process only.
|
|
201
189
|
if (values.team) {
|
|
202
190
|
process.env.TEAM_SERVER_URL = values.team;
|
|
203
191
|
}
|
|
@@ -208,28 +196,11 @@ if (values.secret) {
|
|
|
208
196
|
process.env.RUNNER_AUTH_SECRET = values.secret;
|
|
209
197
|
}
|
|
210
198
|
|
|
211
|
-
// ── Save team config when provided via CLI ────────────────
|
|
212
|
-
|
|
213
|
-
const toSave = {};
|
|
214
|
-
if (values.team) toSave.TEAM_SERVER_URL = values.team;
|
|
215
|
-
if (values.token) toSave.RUNNER_INVITE_TOKEN = values.token;
|
|
216
|
-
if (values.secret) toSave.RUNNER_AUTH_SECRET = values.secret;
|
|
217
|
-
|
|
218
|
-
if (Object.keys(toSave).length > 0) {
|
|
219
|
-
try {
|
|
220
|
-
saveEnv(toSave);
|
|
221
|
-
console.log(`[funny] Config saved to ${ENV_FILE}`);
|
|
222
|
-
} catch (err) {
|
|
223
|
-
console.warn(`[funny] Warning: could not save config to ${ENV_FILE}:`, err.message);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
199
|
// ── Team mode log ─────────────────────────────────────────
|
|
228
200
|
|
|
229
201
|
if (process.env.TEAM_SERVER_URL) {
|
|
230
|
-
const source = values.team ? 'CLI' : existsSync(ENV_FILE) ? 'saved config' : 'env';
|
|
231
202
|
console.log(
|
|
232
|
-
`[funny] Team mode enabled — connecting to ${process.env.TEAM_SERVER_URL} (from
|
|
203
|
+
`[funny] Team mode enabled — connecting to ${process.env.TEAM_SERVER_URL} (from CLI)`,
|
|
233
204
|
);
|
|
234
205
|
}
|
|
235
206
|
|
|
@@ -255,7 +226,7 @@ if (!process.env.RUNNER_AUTH_SECRET) {
|
|
|
255
226
|
'\n[funny] ERROR: RUNNER_AUTH_SECRET is required when using --token in team mode.\n\n' +
|
|
256
227
|
'This runner connects to a central server and must use the SAME\n' +
|
|
257
228
|
'RUNNER_AUTH_SECRET as that server. Ask your admin for it, then pass\n' +
|
|
258
|
-
'it via flag or env
|
|
229
|
+
'it via flag or env:\n\n' +
|
|
259
230
|
` funny --team ${process.env.TEAM_SERVER_URL} --secret <secret-from-admin> --token <invite-token>\n\n` +
|
|
260
231
|
'Or drop --token and use device-link enrollment (no secret needed):\n\n' +
|
|
261
232
|
` funny --team ${process.env.TEAM_SERVER_URL}\n`,
|
package/package.json
CHANGED
package/packages/client/dist/assets/{AcceptInvitePage-D2QlnwXy.js → AcceptInvitePage-Bz8azFPS.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-Cyuzqnbw.js";import{Lt as t,ar as n,lr as r,m as i,zr as a}from"./icons-sqwAEN28.js";import{o}from"./markdown-DBtwZWLP.js";import{M as s,P as c,k as l}from"./index-
|
|
1
|
+
import{a as e}from"./rolldown-runtime-Cyuzqnbw.js";import{Lt as t,ar as n,lr as r,m as i,zr as a}from"./icons-sqwAEN28.js";import{o}from"./markdown-DBtwZWLP.js";import{M as s,P as c,k as l}from"./index-Bmp1UFM1.js";import{t as u}from"./button-Bi9_EZFh.js";import{t as d}from"./input-BGZP-HTx.js";import{t as f}from"./loading-state-DGzdeccZ.js";var p=e(a(),1),m=e(o(),1);function h({token:e}){let a=l(e=>e.isAuthenticated),[o,h]=(0,p.useState)(`verifying`),[g,_]=(0,p.useState)(``),[v,y]=(0,p.useState)(``),[b,x]=(0,p.useState)(``),[S,C]=(0,p.useState)(``),[w,T]=(0,p.useState)(``),[E,D]=(0,p.useState)(``),[O,k]=(0,p.useState)(!1),[A,j]=(0,p.useState)(``),[M,N]=(0,p.useState)(!1);(0,p.useEffect)(()=>{c.verifyInviteLink(e).then(e=>{e.isOk()?(y(e.value.organizationName),x(e.value.role),a?P():h(`register`)):(h(`error`),_(e.error.message||`Invalid or expired invite link`))})},[e]);let P=(0,p.useCallback)(async()=>{h(`accepting`);let t=await c.acceptInviteLink(e);t.isOk()?h(t.value.alreadyMember?`already`:`success`):(h(`error`),_(t.error.message||`Failed to join organization`))},[e]),F=async t=>{t.preventDefault(),j(``),k(!0);try{let t=await c.registerViaInvite({token:e,username:S,password:w,displayName:E||void 0});if(t.isOk()){let{user:e}=t.value;l.setState({isAuthenticated:!0,user:{id:e.id,username:e.username,displayName:e.displayName,role:`user`}}),h(`success`)}else j(t.error.message||`Registration failed`),k(!1)}catch(e){j(e.message||`Registration failed`),k(!1)}},I=async e=>{e.preventDefault(),j(``),k(!0);try{let e=await s.signIn.username({username:S,password:w});if(e.error){j(e.error.message||`Login failed`),k(!1);return}let t=e.data?.user;t&&l.setState({isAuthenticated:!0,user:{id:t.id,username:t.username||t.name||`user`,displayName:t.name||t.username||`User`,role:t.role||`user`}}),await P()}catch(e){j(e.message||`Login failed`),k(!1)}},L=()=>{window.location.href=`/`};return(0,m.jsx)(`div`,{className:`bg-background flex min-h-screen items-center justify-center`,children:(0,m.jsxs)(`div`,{className:`border-border bg-card w-full max-w-sm space-y-6 rounded-lg border p-8 text-center shadow-lg`,children:[o===`verifying`&&(0,m.jsx)(f,{fill:!1,testId:`accept-invite-verifying`,label:`Verifying invite link…`}),o===`register`&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(i,{className:`text-primary mx-auto size-8`}),(0,m.jsxs)(`div`,{children:[(0,m.jsxs)(`h2`,{className:`text-foreground text-lg font-semibold`,children:[`Join `,v]}),(0,m.jsxs)(`p`,{className:`text-muted-foreground mt-1 text-sm`,children:[`You've been invited as `,(0,m.jsx)(`span`,{className:`font-medium`,children:b}),`.`,` `,M?`Sign in to accept.`:`Create an account to get started.`]})]}),(0,m.jsxs)(`form`,{onSubmit:M?I:F,className:`space-y-4 text-left`,children:[(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{htmlFor:`invite-username`,className:`text-foreground text-sm font-medium`,children:`Username`}),(0,m.jsx)(d,{id:`invite-username`,type:`text`,value:S,onChange:e=>C(e.target.value),placeholder:`Choose a username`,autoFocus:!0,required:!0,"data-testid":`invite-username`})]}),!M&&(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsxs)(`label`,{htmlFor:`invite-display-name`,className:`text-foreground text-sm font-medium`,children:[`Display Name`,(0,m.jsx)(`span`,{className:`text-muted-foreground ml-1 font-normal`,children:`(optional)`})]}),(0,m.jsx)(d,{id:`invite-display-name`,type:`text`,value:E,onChange:e=>D(e.target.value),placeholder:`Your display name`,"data-testid":`invite-display-name`})]}),(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`label`,{htmlFor:`invite-password`,className:`text-foreground text-sm font-medium`,children:`Password`}),(0,m.jsx)(d,{id:`invite-password`,type:`password`,value:w,onChange:e=>T(e.target.value),placeholder:M?`Your password`:`Choose a password`,required:!0,"data-testid":`invite-password`})]}),A&&(0,m.jsx)(`p`,{className:`text-destructive text-sm`,children:A}),(0,m.jsxs)(u,{type:`submit`,className:`w-full`,disabled:O||!S||!w,"data-testid":`invite-submit`,children:[O?(0,m.jsx)(t,{className:`icon-base mr-2 animate-spin`}):null,M?`Sign In & Join`:`Create Account & Join`]})]}),(0,m.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:M?(0,m.jsxs)(m.Fragment,{children:[`Don't have an account?`,` `,(0,m.jsx)(`button`,{type:`button`,className:`text-primary hover:underline`,onClick:()=>{N(!1),j(``)},"data-testid":`invite-switch-register`,children:`Register`})]}):(0,m.jsxs)(m.Fragment,{children:[`Already have an account?`,` `,(0,m.jsx)(`button`,{type:`button`,className:`text-primary hover:underline`,onClick:()=>{N(!0),j(``)},"data-testid":`invite-switch-login`,children:`Sign in`})]})})]}),o===`accepting`&&(0,m.jsx)(f,{fill:!1,testId:`accept-invite-accepting`,label:`Joining ${v}...`}),o===`success`&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(r,{className:`mx-auto size-8 text-green-500`}),(0,m.jsx)(`h2`,{className:`text-foreground text-lg font-semibold`,children:`You're in!`}),(0,m.jsxs)(`p`,{className:`text-muted-foreground text-sm`,children:[`You've successfully joined `,(0,m.jsx)(`span`,{className:`font-medium`,children:v}),`.`]}),(0,m.jsx)(u,{onClick:L,className:`w-full`,"data-testid":`invite-continue`,children:`Continue to App`})]}),o===`already`&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(r,{className:`mx-auto size-8 text-blue-500`}),(0,m.jsx)(`h2`,{className:`text-foreground text-lg font-semibold`,children:`Already a member`}),(0,m.jsxs)(`p`,{className:`text-muted-foreground text-sm`,children:[`You're already a member of `,(0,m.jsx)(`span`,{className:`font-medium`,children:v}),`.`]}),(0,m.jsx)(u,{onClick:L,className:`w-full`,"data-testid":`invite-continue`,children:`Continue to App`})]}),o===`error`&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(n,{className:`text-destructive mx-auto size-8`}),(0,m.jsx)(`h2`,{className:`text-foreground text-lg font-semibold`,children:`Invitation failed`}),(0,m.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:g}),(0,m.jsx)(u,{variant:`outline`,onClick:L,className:`w-full`,"data-testid":`invite-continue`,children:`Go to App`})]})]})})}export{h as AcceptInvitePage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-Cyuzqnbw.js";import{Dr as t,Gn as n,Lt as r,Mn as i,Rr as a,ir as o,kn as s,lr as c,sr as l,ut as u,wn as d,zr as f}from"./icons-sqwAEN28.js";import{o as p}from"./markdown-DBtwZWLP.js";import{t as m}from"./useTranslation-DAPPK3Hy.js";import{G as h,P as g,W as _,lt as v,q as y}from"./index-
|
|
1
|
+
import{a as e}from"./rolldown-runtime-Cyuzqnbw.js";import{Dr as t,Gn as n,Lt as r,Mn as i,Rr as a,ir as o,kn as s,lr as c,sr as l,ut as u,wn as d,zr as f}from"./icons-sqwAEN28.js";import{o as p}from"./markdown-DBtwZWLP.js";import{t as m}from"./useTranslation-DAPPK3Hy.js";import{G as h,P as g,W as _,lt as v,q as y}from"./index-Bmp1UFM1.js";import{t as b}from"./button-Bi9_EZFh.js";import{$r as x,Ct as S,Dr as C,Dt as w,Gr as T,Jr as ee,Ot as E,Tt as D,Ur as O,in as te,qr as k,wt as A,yr as ne}from"./items-C-m69VjA.js";import{t as j}from"./FileTree-DUODDbNL.js";import{a as M,i as N,n as P,t as F}from"./diff-parse-CRTMJKOI.js";import{n as I}from"./review-pane-store-B31R8Yhv.js";import{n as re}from"./use-todo-panel-CsXYDjtr.js";var L=e(f(),1),R=new Set;function z(e){let t=S(),n=w()===`running`,[r,i]=(0,L.useState)(R),a=(0,L.useRef)(R),o=(0,L.useRef)(void 0),s=(0,L.useRef)(null);return(0,L.useEffect)(()=>{if(t!==o.current&&(o.current=t,i(R),a.current=R,s.current?.abort(),s.current=null),!t||!e)return;let r=!1,c=async()=>{s.current?.abort();let e=new AbortController;s.current=e;let n;try{n=await g.getTouchedFiles(t,e.signal)}catch{return}if(!(r||e.signal.aborted)&&n.isOk()){let e=n.value.files;if(e.length===0){a.current.size!==0&&(a.current=R,i(R));return}let t=new Set(e),r=a.current;(t.size!==r.size||![...t].every(e=>r.has(e)))&&(a.current=t,i(t))}};if(c(),n){let e=setInterval(c,5e3);return()=>{r=!0,s.current?.abort(),clearInterval(e)}}return()=>{r=!0,s.current?.abort()}},[t,n,e]),r}function B(e=!0){let t=S(),n=I(e=>e.dirtySignal),r=z(e),[i,a]=(0,L.useState)([]),[o,s]=(0,L.useState)(!1),[c,l]=(0,L.useState)(0),u=(0,L.useRef)(t);return(0,L.useEffect)(()=>{t!==u.current&&(u.current=t,a([]),s(!!t))},[t]),(0,L.useEffect)(()=>{if(!t){a([]);return}if(r.size===0){a([]),s(!1);return}let e=!1,n=setTimeout(async()=>{s(!0);let n;try{n=await g.getDiffSummary(t)}catch{e||s(!1);return}!e&&n.isOk()&&a(n.value.files.filter(e=>{for(let t of r)if(t.endsWith(`/${e.path}`)||t===e.path)return!0;return!1})),e||s(!1)},300);return()=>{e=!0,clearTimeout(n)}},[t,n,c,r]),{files:i,loading:o,refresh:(0,L.useCallback)(()=>l(e=>e+1),[])}}var V=e(p(),1),H={added:s,modified:i,deleted:d,renamed:i};function U(){let e=(0,L.useRef)([]),t=A();return(0,L.useMemo)(()=>{if(!t)return e.current.length===0||(e.current=[]),e.current;let n=[];for(let e of t)for(let t of e.toolCalls??[])n.push(t);let r=[];for(let e of n)if((e.name===`Task`||e.name===`Agent`)&&!e.output){let t=M(e.input),i=t.description??t.prompt??`Sub-agent`,a=n.filter(t=>t.parentToolCallId===e.id).length;r.push({id:e.id,description:i,childToolCallCount:a})}let i=e.current;return i.length===r.length&&r.every((e,t)=>e.id===i[t].id&&e.childToolCallCount===i[t].childToolCallCount)?i:(e.current=r,r)},[t])}function W({title:e,testId:t,count:n,children:r}){return(0,V.jsxs)(`div`,{"data-testid":t,children:[(0,V.jsxs)(`div`,{className:`border-border/50 flex items-center gap-2 border-b px-2 py-1.5`,children:[(0,V.jsx)(`span`,{className:`text-muted-foreground flex-1 text-xs font-semibold tracking-wider uppercase`,children:e}),n!==void 0&&n>0&&(0,V.jsx)(`span`,{className:`bg-muted text-muted-foreground rounded-full px-1.5 py-0.5 font-mono text-[10px]`,children:n})]}),r]})}function G({todos:e,progress:t}){let n=t.total>0?Math.round(t.completed/t.total*100):0,r=t.completed===t.total;return(0,V.jsxs)(`div`,{className:`mt-1.5 space-y-1.5`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(`div`,{className:`bg-muted h-1 flex-1 overflow-hidden rounded-full`,children:(0,V.jsx)(`div`,{className:v(`h-full rounded-full transition-all duration-500`,r?`bg-status-success/80`:`bg-status-info/80`),style:{width:`${n}%`}})}),(0,V.jsxs)(`span`,{className:v(`font-mono text-[10px]`,r?`text-status-success/80`:`text-muted-foreground`),children:[t.completed,`/`,t.total]})]}),(0,V.jsx)(`div`,{className:`space-y-1`,children:e.map((e,t)=>(0,V.jsxs)(`div`,{"data-testid":`activity-todo-${t}`,className:`flex items-start gap-2`,children:[e.status===`completed`?(0,V.jsx)(c,{className:`icon-sm text-status-success/80 mt-0.5 shrink-0`}):e.status===`in_progress`?(0,V.jsx)(l,{className:`icon-sm text-status-info mt-0.5 shrink-0 animate-pulse`}):(0,V.jsx)(o,{className:`icon-sm text-muted-foreground/50 mt-0.5 shrink-0`}),(0,V.jsx)(`span`,{className:v(`text-xs leading-relaxed`,e.status===`completed`&&`text-muted-foreground line-through`,e.status===`in_progress`&&`font-medium text-foreground`,e.status===`pending`&&`text-muted-foreground`),children:e.status===`in_progress`&&e.activeForm||e.content})]},e.content))})]})}function K({testId:e,icon:t,label:n,isRunning:i,childToolCallCount:a,todoSnapshot:o}){let{t:s}=m();return(0,V.jsxs)(`div`,{"data-testid":e,className:`px-2.5 py-2`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[i&&(0,V.jsx)(r,{className:`icon-xs text-muted-foreground shrink-0 animate-spin`}),(0,V.jsx)(t,{className:`icon-sm text-muted-foreground shrink-0`}),(0,V.jsx)(`span`,{className:`text-muted-foreground min-w-0 flex-1 truncate text-xs font-medium`,children:n}),a!==void 0&&a>0&&(0,V.jsxs)(`span`,{className:`bg-muted text-muted-foreground shrink-0 rounded px-1.5 py-0.5 font-mono text-[10px]`,children:[a,` `,s(`activity.toolCalls`,`tool calls`)]})]}),o&&(0,V.jsx)(G,{todos:o.todos,progress:o.progress})]})}function q({message:e}){return(0,V.jsx)(`div`,{className:`text-muted-foreground/50 px-4 py-3 text-center text-xs italic`,children:e})}function J(){let{t:e}=m(),r=U(),o=re(),s=w()===`running`,c=s||o.mainAgent!==null,l=+!!c+r.length,{files:d,loading:f,refresh:p}=B(),[v,A]=(0,L.useState)(null),[M,I]=(0,L.useState)(null),[R,z]=(0,L.useState)(new Map),[G,J]=(0,L.useState)(null),Y=S(),X=(0,L.useRef)(Y);(0,L.useEffect)(()=>{Y!==X.current&&(X.current=Y,A(null),I(null),z(new Map),J(null))},[Y]);let Z=E(),Q=D(),$=C(e=>e.projects),ie=(0,L.useMemo)(()=>Z||(Q?$.find(e=>e.id===Q)?.path??``:``),[Z,Q,$]),ae=(0,L.useCallback)(async e=>{if(!Y||R.has(e))return;let t=d.find(t=>t.path===e);if(!t)return;J(e);let n=await g.getFileDiff(Y,e,t.staged);n.isOk()&&z(t=>new Map(t).set(e,n.value.diff)),J(t=>t===e?null:t)},[Y,R,d]);(0,L.useEffect)(()=>{M&&!R.has(M)&&ae(M)},[M]);let oe=(0,L.useCallback)(async e=>{if(!Y)return null;let t=d.find(t=>t.path===e);if(!t)return null;let n=await g.getFileDiff(Y,e,t.staged,void 0,`full`);return n.isOk()?{oldValue:P(n.value.diff),newValue:F(n.value.diff),rawDiff:n.value.diff}:null},[Y,d]),se=(0,L.useCallback)(async t=>{if(!Y)return;let n=await g.revertFiles(Y,[t]);n.isErr()?O.error(e(`review.revertFailed`,{message:n.error.message})):(O.success(e(`review.revertSuccess`,{path:t,defaultValue:`{{path}} reverted`})),z(e=>{let n=new Map(e);return n.delete(t),n}),p())},[Y,e,p]),ce=(0,L.useCallback)(e=>{A(e),I(e)},[]);return Y?(0,V.jsxs)(`div`,{"data-testid":`activity-pane`,className:`flex h-full flex-col`,children:[(0,V.jsxs)(`div`,{className:`border-sidebar-border flex shrink-0 items-center justify-between border-b px-4 py-3`,children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,V.jsx)(a,{className:`icon-base text-muted-foreground`}),(0,V.jsx)(`h3`,{className:`text-sidebar-foreground text-xs font-semibold tracking-wider uppercase`,children:e(`activity.title`,`Activity`)})]}),(0,V.jsxs)(_,{children:[(0,V.jsx)(y,{asChild:!0,children:(0,V.jsx)(b,{variant:`ghost`,size:`icon-xs`,onClick:()=>ne.getState().setReviewPaneOpen(!1),className:`text-muted-foreground`,"data-testid":`activity-close`,children:(0,V.jsx)(u,{className:`icon-sm`})})}),(0,V.jsx)(h,{side:`bottom`,children:e(`common.close`,`Close`)})]})]}),(0,V.jsx)(te,{className:`min-h-0 flex-1`,children:(0,V.jsxs)(`div`,{className:`space-y-3 p-3`,children:[(0,V.jsx)(W,{title:e(`activity.agents`,`Agents`),testId:`activity-agents`,count:l,children:l>0?(0,V.jsxs)(`div`,{className:`space-y-1.5 px-2 py-1.5`,children:[c&&(0,V.jsx)(K,{testId:`activity-agent-main`,icon:n,label:e(`activity.mainAgent`,`Main agent`),isRunning:!!s,todoSnapshot:o.mainAgent}),r.map(e=>(0,V.jsx)(K,{testId:`activity-agent-${e.id}`,icon:t,label:e.description,isRunning:!0,childToolCallCount:e.childToolCallCount,todoSnapshot:o.bySubAgent.get(e.id)??null},e.id))]}):(0,V.jsx)(q,{message:e(`activity.noAgents`,`No running agents`)})}),(0,V.jsx)(W,{title:e(`activity.files`,`Modified Files`),testId:`activity-files`,count:d.length,children:d.length>0?(0,V.jsx)(j,{files:d,selectedFile:v,onFileClick:ce,onRevertFile:se,basePath:ie,diffStatsSize:`xs`,fontSize:`text-xs`,testIdPrefix:`activity-file`}):(0,V.jsx)(q,{message:f?e(`activity.loadingFiles`,`Loading...`):e(`activity.noFiles`,`No modified files`)})})]})}),(0,V.jsx)(T,{open:!!M,onOpenChange:e=>{e||I(null)},children:(0,V.jsx)(k,{className:`flex h-[85vh] w-[90vw] max-w-[90vw] flex-col gap-0 overflow-hidden p-0`,"data-testid":`activity-expanded-diff-overlay`,children:(()=>{let t=M?d.find(e=>e.path===M):void 0,n=M?R.get(M):void 0,r=t&&H[t.status]||i;return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(x,{className:`sr-only`,children:t?.path??e(`review.diffViewer`,`Diff viewer`)}),(0,V.jsx)(ee,{className:`sr-only`,children:e(`review.diffViewerDescription`,`View and stage changes for the selected file`)}),M&&(0,V.jsx)(`div`,{className:`flex min-h-0 min-w-0 flex-1`,children:(0,V.jsx)(`div`,{className:`flex min-w-0 flex-1 flex-col`,children:(0,V.jsx)(N,{filePath:t?.path||M,oldValue:n?P(n):``,newValue:n?F(n):``,icon:r,loading:G===M,rawDiff:n,files:d,onFileSelect:e=>{A(e),I(e)},diffCache:R,onClose:()=>I(null),onRequestFullDiff:oe})})})]})})()})})]}):(0,V.jsx)(`div`,{"data-testid":`activity-pane`,className:`text-muted-foreground flex h-full items-center justify-center text-sm`,children:e(`activity.noThread`,`Select a thread to see activity`)})}export{J as ActivityPane};
|
package/packages/client/dist/assets/{AddProjectView-DWAvSEfh.js → AddProjectView-CS9PMuwG.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,t}from"./rolldown-runtime-Cyuzqnbw.js";import{Ft as n,It as r,Kn as i,L as a,Lt as o,Mr as s,Q as c,on as l,yn as u,yr as d,zn as f,zr as p}from"./icons-sqwAEN28.js";import{o as m}from"./markdown-DBtwZWLP.js";import{i as h}from"./_core-lD_pNs53.js";import{a as g,i as _,n as v,o as y,r as b,t as x}from"./useTranslation-DAPPK3Hy.js";import{i as S,n as C,r as ee}from"./initReactI18next-Dr0vnWXF.js";import{G as w,P as T,W as te,_t as E,j as D,lt as O,q as k}from"./index-BsxcqNXe.js";import{t as A}from"./button-DeEOU1Fb.js";import{$r as ne,Gr as re,Jr as j,K as ie,Nn as M,Rt as N,Ur as P,Wn as F,Xr as ae,Yr as I,gt as oe,in as se,mn as ce,qr as L,yr as le}from"./items-_g3-I08l.js";import{t as R}from"./input-DV30TVat.js";import{t as ue}from"./loading-state-BQjalkhM.js";import{t as de}from"./app-store-BwZB2xp_.js";import{t as fe}from"./FolderPicker-B5JTJeAY.js";var pe=e(t(((e,t)=>{t.exports={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}}))()),z=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function B(e){var t={type:`tag`,name:``,voidElement:!1,attrs:{},children:[]},n=e.match(/<\/?([^\s]+?)[/\s>]/);if(n&&(t.name=n[1],(pe.default[n[1]]||e.charAt(e.length-2)===`/`)&&(t.voidElement=!0),t.name.startsWith(`!--`))){var r=e.indexOf(`-->`);return{type:`comment`,comment:r===-1?``:e.slice(4,r)}}for(var i=new RegExp(z),a=null;(a=i.exec(e))!==null;)if(a[0].trim())if(a[1]){var o=a[1].trim(),s=[o,``];o.indexOf(`=`)>-1&&(s=o.split(`=`)),t.attrs[s[0]]=s[1],i.lastIndex--}else a[2]&&(t.attrs[a[2]]=a[3].trim().substring(1,a[3].length-1));return t}var V=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,me=/^\s*$/,he=Object.create(null);function ge(e,t){switch(t.type){case`text`:return e+t.content;case`tag`:return e+=`<`+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+`="`+e[n]+`"`);return t.length?` `+t.join(` `):``}(t.attrs):``)+(t.voidElement?`/>`:`>`),t.voidElement?e:e+t.children.reduce(ge,``)+`</`+t.name+`>`;case`comment`:return e+`<!--`+t.comment+`-->`}}var _e={parse:function(e,t){t||={},t.components||=he;var n,r=[],i=[],a=-1,o=!1;if(e.indexOf(`<`)!==0){var s=e.indexOf(`<`);r.push({type:`text`,content:s===-1?e:e.substring(0,s)})}return e.replace(V,function(s,c){if(o){if(s!==`</`+n.name+`>`)return;o=!1}var l,u=s.charAt(1)!==`/`,d=s.startsWith(`<!--`),f=c+s.length,p=e.charAt(f);if(d){var m=B(s);return a<0?(r.push(m),r):((l=i[a]).children.push(m),r)}if(u&&(a++,(n=B(s)).type===`tag`&&t.components[n.name]&&(n.type=`component`,o=!0),n.voidElement||o||!p||p===`<`||n.children.push({type:`text`,content:e.slice(f,e.indexOf(`<`,f))}),a===0&&r.push(n),(l=i[a-1])&&l.children.push(n),i[a]=n),(!u||n.voidElement)&&(a>-1&&(n.voidElement||n.name===s.slice(2,-1))&&(a--,n=a===-1?r:i[a]),!o&&p!==`<`&&p)){l=a===-1?r:i[a].children;var h=e.indexOf(`<`,f),g=e.slice(f,h===-1?void 0:h);me.test(g)&&(g=` `),(h>-1&&a+l.length>=0||g!==` `)&&l.push({type:`text`,content:g})}}),r},stringify:function(e){return e.reduce(function(e,t){return e+ge(``,t)},``)}},H=e(p()),U=(e,t)=>{if(!e)return!1;let n=e.props?.children??e.children;return t?n.length>0:!!n},W=e=>{if(!e)return[];let t=e.props?.children??e.children;return e.props?.i18nIsDynamicList?K(t):t},G=e=>Array.isArray(e)&&e.every(H.isValidElement),K=e=>Array.isArray(e)?e:[e],ve=(e,t)=>{let n={...t};return n.props={...t.props,...e.props},n},q=e=>{let t={};if(!e)return t;let n=e=>{K(e).forEach(e=>{_(e)||(U(e)?n(W(e)):b(e)&&!(0,H.isValidElement)(e)&&Object.assign(t,e))})};return n(e),t},J=(e,t,n,r)=>{if(!e)return``;let i=``,a=K(e),o=t?.transSupportBasicHtmlNodes?t.transKeepBasicHtmlNodesFor??[]:[];return a.forEach((e,a)=>{if(_(e)){i+=`${e}`;return}if((0,H.isValidElement)(e)){let{props:s,type:c}=e,l=Object.keys(s).length,u=o.indexOf(c)>-1,d=s.children;if(!d&&u&&!l){i+=`<${c}/>`;return}if(!d&&(!u||l)||s.i18nIsDynamicList){i+=`<${a}></${a}>`;return}if(u&&l<=1){let e=_(d)?d:J(d,t,n,r);i+=`<${c}>${e}</${c}>`;return}let f=J(d,t,n,r);i+=`<${a}>${f}</${a}>`;return}if(e===null){g(n,`TRANS_NULL_VALUE`,`Passed in a null value as child`,{i18nKey:r});return}if(b(e)){let{format:t,...a}=e,o=Object.keys(a);if(o.length===1){let e=t?`${o[0]}, ${t}`:o[0];i+=`{{${e}}}`;return}g(n,`TRANS_INVALID_OBJ`,`Invalid child - Object should only have keys {{ value, format }} (format is optional).`,{i18nKey:r,child:e});return}g(n,`TRANS_INVALID_VAR`,`Passed in a variable like {number} - pass variables for interpolation as full objects like {{number}}.`,{i18nKey:r,child:e})}),i},ye=(e,t=[],n={})=>{if(!e)return e;let r=Object.keys(n),i=[...t,...r],a=``,o=0;for(;o<e.length;)if(e[o]===`<`){let t=!1,n=e.slice(o).match(/^<\/(\d+|[a-zA-Z][a-zA-Z0-9_-]*)>/);if(n){let e=n[1];(/^\d+$/.test(e)||i.includes(e))&&(t=!0,a+=n[0],o+=n[0].length)}if(!t){let n=e.slice(o).match(/^<(\d+|[a-zA-Z][a-zA-Z0-9_-]*)(\s+[\w-]+(?:=(?:"[^"]*"|'[^']*'|[^\s>]+))?)*\s*(\/)?>/);if(n){let e=n[1];(/^\d+$/.test(e)||i.includes(e))&&(t=!0,a+=n[0],o+=n[0].length)}}t||(a+=`<`,o+=1)}else a+=e[o],o+=1;return a},be=(e,t,n,r,i,a,o)=>{if(n===``)return[];let s=i.transKeepBasicHtmlNodesFor||[],c=n&&new RegExp(s.map(e=>`<${e}`).join(`|`)).test(n);if(!e&&!t&&!c&&!o)return[n];let l=t??{},u=e=>{K(e).forEach(e=>{_(e)||(U(e)?u(W(e)):b(e)&&!(0,H.isValidElement)(e)&&Object.assign(l,e))})};u(e);let d=ye(n,s,l),f=_e.parse(`<0>${d}</0>`),p={...l,...a},m=(e,t,n)=>{let r=W(e),i=g(r,t.children,n);return G(r)&&i.length===0||e.props?.i18nIsDynamicList?r:i},h=(e,t,n,r,i)=>{e.dummy?(e.children=t,n.push((0,H.cloneElement)(e,{key:r},i?void 0:t))):n.push(...H.Children.map([e],e=>{if(e.type===H.Fragment||e.props?.i18nIsDynamicList!==void 0){let n={key:r};return e&&e.props&&Object.keys(e.props).forEach(t=>{t===`children`||t===`i18nIsDynamicList`||(n[t]=e.props[t])}),(0,H.createElement)(e.type,n,i?null:t)}let n={key:r};return e&&e.props&&Object.keys(e.props).forEach(t=>{t===`ref`||t===`children`||(n[t]=e.props[t])}),(0,H.cloneElement)(e,n,i?null:t)}))},g=(e,n,a)=>{let l=K(e),u=K(n),d={};return u.reduce((e,n,u)=>{let f=n.children?.[0]?.content&&r.services.interpolator.interpolate(n.children[0].content,p,r.language);if(n.type===`tag`){let v=l[parseInt(n.name,10)];!v&&t&&(v=t[n.name]),a.length===1&&!v&&(v=a[0][n.name]),v||={};let y={...n.attrs};o&&Object.keys(y).forEach(e=>{let t=y[e];_(t)&&(y[e]=S(t))});let x=Object.keys(y).length===0?v:ve({props:y},v),C=(0,H.isValidElement)(x),ee=C&&U(n,!0)&&!n.voidElement,w=c&&b(x)&&x.dummy&&!C,T=b(t)&&Object.hasOwnProperty.call(t,n.name);if(_(x)){let t=r.services.interpolator.interpolate(x,p,r.language);e.push(t)}else if(U(x)||ee)h(x,m(x,n,a),e,u);else if(w)h(x,g(l,n.children,a),e,u);else if(Number.isNaN(parseFloat(n.name)))if(T)h(x,m(x,n,a),e,u,n.voidElement);else if(i.transSupportBasicHtmlNodes&&s.indexOf(n.name)>-1)if(n.voidElement)e.push((0,H.createElement)(n.name,{key:`${n.name}-${u}`}));else{let t=d[n.name]||0;d[n.name]=t+1;let r,i=0;for(let e=0;e<l.length;e+=1){let a=l[e];if((0,H.isValidElement)(a)&&a.type===n.name){if(i===t){r=a;break}i+=1}}let o=g(r?K(W(r)):l,n.children,a);e.push((0,H.createElement)(n.name,{key:`${n.name}-${u}`},o))}else if(n.voidElement)e.push(`<${n.name} />`);else{let t=g(l,n.children,a);e.push(`<${n.name}>${t}</${n.name}>`)}else if(b(x)&&!C){let t=n.children[0]?f:null;t&&e.push(t)}else h(x,f,e,u,n.children.length!==1||!f)}else if(n.type===`text`){let t=i.transWrapTextNodes,a=typeof i.unescape==`function`?i.unescape:ee().unescape,s=o?a(r.services.interpolator.interpolate(n.content,p,r.language)):r.services.interpolator.interpolate(n.content,p,r.language);t?e.push((0,H.createElement)(t,{key:`${n.name}-${u}`},s)):e.push(s)}return e},[])};return W(g([{dummy:!0,children:e||[]}],f,K(e||[]))[0])},Y=(e,t,n)=>{let r=e.key||t,i=(0,H.cloneElement)(e,{key:r});if(!i.props||!i.props.children||n.indexOf(`${t}/>`)<0&&n.indexOf(`${t} />`)<0)return i;function a(){return(0,H.createElement)(H.Fragment,null,i)}return(0,H.createElement)(a,{key:r})},xe=(e,t)=>e.map((e,n)=>Y(e,n,t)),X=(e,t)=>{let n={};return Object.keys(e).forEach(r=>{Object.assign(n,{[r]:Y(e[r],r,t)})}),n},Se=(e,t,n,r)=>e?Array.isArray(e)?xe(e,t):b(e)?X(e,t):(y(n,`TRANS_INVALID_COMPONENTS`,`<Trans /> "components" prop expects an object or array`,{i18nKey:r}),null):null,Z=e=>!b(e)||Array.isArray(e)?!1:Object.keys(e).reduce((e,t)=>e&&Number.isNaN(Number.parseFloat(t)),!0);function Ce({children:e,count:t,parent:n,i18nKey:r,context:i,tOptions:a={},values:o,defaults:s,components:c,ns:l,i18n:u,t:d,shouldUnescape:f,...p}){let m=u||C();if(!m)return y(m,`NO_I18NEXT_INSTANCE`,`Trans: You need to pass in an i18next instance using i18nextReactModule`,{i18nKey:r}),e;let g=d||m.t.bind(m)||(e=>e),v={...ee(),...m.options?.react},b=l||g.ns||m.options?.defaultNS;b=_(b)?[b]:b||[`translation`];let{transDefaultProps:x}=v,S=x?.tOptions?{...x.tOptions,...a}:a,w=f??x?.shouldUnescape,T=x?.values?{...x.values,...o}:o,te=x?.components?{...x.components,...c}:c,E=J(e,v,m,r),D=s||S?.defaultValue||E||v.transEmptyNodeValue||(typeof r==`function`?h(r):r),{hashTransKey:O}=v,k=r||(O?O(E||D):E||D);o=m.options?.interpolation?.defaultVariables?T&&Object.keys(T).length>0?{...T,...m.options.interpolation.defaultVariables}:{...m.options.interpolation.defaultVariables}:T;let A=q(e);A&&typeof A.count==`number`&&t===void 0&&(t=A.count);let ne=o||t!==void 0&&!m.options?.interpolation?.alwaysFormat||!e?S.interpolation:{interpolation:{...S.interpolation,prefix:`#$?`,suffix:`?$#`}},re={...S,context:i||S.context,count:t,...o,...ne,defaultValue:D,ns:b},j=k?g(k,re):D;j===k&&D&&(j=D);let ie=Se(te,j,m,r),M=ie||e,N=null;Z(ie)&&(N=ie,M=e);let P=be(M,N,j,m,v,re,w),F=n??v.defaultTransParent;return F?(0,H.createElement)(F,p,P):P}function we({children:e,count:t,parent:n,i18nKey:r,context:i,tOptions:a={},values:o,defaults:s,components:c,ns:l,i18n:u,t:d,shouldUnescape:f,...p}){let{i18n:m,defaultNS:h}=(0,H.useContext)(v)||{},g=u||m||C(),_=d||g?.t.bind(g);return Ce({children:e,count:t,parent:n,i18nKey:r,context:i,tOptions:a,values:o,defaults:s,components:c,ns:l||_?.ns||h||g?.options?.defaultNS,i18n:g,t:d,shouldUnescape:f,...p})}var Q=e(m(),1),Te=D(`clone-repo-view`);function Ee({onCloningChange:e}={}){let{t}=x(),c=E(),p=de(e=>e.loadProjects),m=de(e=>e.setAddProjectOpen),h=le(e=>e.generalSettingsOpen),[g,_]=(0,H.useState)(`checking`);(0,H.useEffect)(()=>{e?.(g===`cloning`)},[g,e]);let[v,y]=(0,H.useState)(null),[b,S]=(0,H.useState)(null),[C,ee]=(0,H.useState)(``),[w,te]=(0,H.useState)(``),[D,k]=(0,H.useState)(``),[ne,re]=(0,H.useState)(5),[j,ae]=ie(),I=(0,H.useRef)(null),[L,pe]=(0,H.useState)([]),[z,B]=(0,H.useState)(``),[V,me]=(0,H.useState)(``),[he,ge]=(0,H.useState)(!1),[_e,U]=(0,H.useState)(!1),[W,G]=(0,H.useState)(-1),K=(0,H.useRef)(null),ve=(0,H.useRef)(null),q=(0,H.useRef)(void 0),J=(0,H.useRef)(!1),ye=(0,H.useRef)(0),be=(0,H.useRef)(1),[Y,xe]=(0,H.useState)(null),[X,Se]=(0,H.useState)(``),[Z,Ce]=(0,H.useState)(``),[Ee,De]=(0,H.useState)(!1),[Oe,ke]=(0,H.useState)(!1),[Ae,je]=(0,H.useState)(``),[Me,Ne]=(0,H.useState)(void 0),[Pe,Fe]=(0,H.useState)(!1),Ie=(0,H.useRef)(``);(0,H.useEffect)(()=>{let e=e=>{let t=e.detail;if(t.phase){let e=t.phase.replace(/:.*$/,``).trim();e!==Ie.current&&(Fe(!0),Ie.current=e,requestAnimationFrame(()=>Fe(!1))),je(t.phase)}t.percent!==void 0&&Ne(t.percent)};return window.addEventListener(`clone:progress`,e),()=>window.removeEventListener(`clone:progress`,e)},[]);let $=(0,H.useCallback)(async()=>{let e=await T.githubStatus();e.isOk()?e.value.connected?(S(e.value.source??`profile`),await Le(),_(`repos`)):(S(null),_(`connect`)):_(`error`)},[]);(0,H.useEffect)(()=>{$()},[$]),(0,H.useEffect)(()=>{!h&&(g===`connect`||g===`error`)&&$()},[h,g,$]);let Le=async()=>{let e=await T.githubUser();e.isOk()&&y(e.value)},Re=(0,H.useCallback)(async(e,t,n)=>{let r=++ye.current;J.current=!0,U(!0),Te.debug(`github repo search`,{page:e,query:t,append:n});let i=await T.githubRepos({page:e,per_page:30,sort:`updated`,search:t||void 0});r===ye.current&&(i.isOk()&&(pe(e=>n?[...e,...i.value.repos]:i.value.repos),ge(i.value.hasMore)),J.current=!1,U(!1))},[]);(0,H.useEffect)(()=>(q.current&&clearTimeout(q.current),q.current=setTimeout(()=>{me(z)},200),()=>{q.current&&clearTimeout(q.current)}),[z]);let ze=z!==V||_e;(0,H.useEffect)(()=>{G(-1)},[V]);let Be=e=>{if(e.key===`ArrowDown`)e.preventDefault(),G(e=>Math.min(e+1,L.length-1));else if(e.key===`ArrowUp`)e.preventDefault(),G(e=>Math.max(e-1,0));else if(e.key===`Enter`&&W>=0&&W<L.length){e.preventDefault();let t=L[W];xe(t),Ce(t.name),_(`clone-config`)}};(0,H.useEffect)(()=>{W<0||!K.current||K.current.querySelectorAll(`[data-repo-item]`)[W]?.scrollIntoView({block:`nearest`})},[W]),(0,H.useEffect)(()=>{g===`repos`&&(be.current=1,Re(1,V,!1))},[g,V,Re]),(0,H.useEffect)(()=>{if(g!==`repos`)return;let e=K.current,t=ve.current;if(!e||!t)return;let n=new IntersectionObserver(e=>{if(!e[0]?.isIntersecting||J.current||!he)return;let t=be.current+1;be.current=t,Re(t,V,!0)},{root:e,rootMargin:`0px 0px 200px 0px`,threshold:0});return n.observe(t),()=>n.disconnect()},[g,he,V,Re]),(0,H.useEffect)(()=>()=>{I.current&&clearInterval(I.current)},[]);let Ve=async()=>{let e=await T.githubStartDevice();if(e.isErr()){F(e.error,`cloneRepo`);return}let t=e.value;ee(t.device_code),te(t.user_code),k(t.verification_uri),re(t.interval),_(`device-flow`),He(t.device_code,t.interval)},He=(e,n)=>{I.current&&clearInterval(I.current),I.current=setInterval(async()=>{let n=await T.githubPoll(e);if(n.isErr())return;let r=n.value;r.status===`success`?(I.current&&clearInterval(I.current),await Le(),_(`repos`),P.success(t(`github.connected`,{login:``}))):r.status===`expired`||r.status===`denied`?(I.current&&clearInterval(I.current),P.error(r.status===`expired`?t(`github.deviceFlow.expired`):t(`github.deviceFlow.denied`)),_(`connect`)):r.interval&&(I.current&&clearInterval(I.current),He(e,r.interval))},(n+1)*1e3)},Ue=e=>{xe(e),Ce(e.name),_(`clone-config`)},We=async()=>{if(!Y||!X||!Z)return;ke(!0),je(``),Ne(void 0),_(`cloning`);let e=await T.cloneRepo(Y.clone_url,X,Z);if(e.isErr()){F(e.error,`cloneRepo`),ke(!1),_(`clone-config`);return}P.success(t(`github.clone.success`)),await p(),m(!1),c(N(`/projects/${e.value.id}`))},Ge=async()=>{await T.githubDisconnect(),y(null),pe([]),_(`connect`),P.success(t(`github.disconnected`))},Ke=e=>{let n=Date.now()-new Date(e).getTime(),r=Math.floor(n/6e4);if(r<60)return t(`time.minutes`,{count:r});let i=Math.floor(r/60);if(i<24)return t(`time.hours`,{count:i});let a=Math.floor(i/24);return a<30?t(`time.days`,{count:a}):t(`time.months`,{count:Math.floor(a/30)})};if(g===`checking`)return(0,Q.jsx)(ue,{fill:!1,className:`py-12`,testId:`clone-repo-checking`});if(g===`error`)return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-8`,children:[(0,Q.jsx)(`div`,{className:`bg-destructive/10 flex size-12 items-center justify-center rounded-full`,children:(0,Q.jsx)(oe,{className:`icon-xl text-destructive`})}),(0,Q.jsxs)(`div`,{className:`space-y-1 text-center`,children:[(0,Q.jsx)(`h3`,{className:`font-medium`,children:t(`github.connectionError`,{defaultValue:`Connection Error`})}),(0,Q.jsx)(`p`,{className:`text-muted-foreground max-w-xs text-sm`,children:t(`github.connectionErrorDesc`,{defaultValue:`Could not check GitHub connection status. The server may be unavailable.`})})]}),(0,Q.jsx)(A,{onClick:()=>{_(`checking`),$()},"data-testid":`clone-repo-retry`,children:t(`common.retry`,{defaultValue:`Retry`})})]});if(g===`connect`)return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-8`,children:[(0,Q.jsx)(`div`,{className:`bg-muted flex size-12 items-center justify-center rounded-full`,children:(0,Q.jsx)(oe,{className:`icon-xl`})}),(0,Q.jsxs)(`div`,{className:`space-y-1 text-center`,children:[(0,Q.jsx)(`h3`,{className:`font-medium`,children:t(`github.connectGithub`)}),(0,Q.jsx)(`p`,{className:`text-muted-foreground max-w-xs text-sm`,children:t(`github.connectDesc`)})]}),(0,Q.jsxs)(`div`,{className:`flex w-full max-w-xs flex-col gap-2`,children:[(0,Q.jsxs)(A,{className:`w-full`,onClick:Ve,children:[(0,Q.jsx)(oe,{className:`icon-base mr-2`}),t(`github.connectGithub`)]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsx)(`div`,{className:`bg-border h-px flex-1`}),(0,Q.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:t(`common.or`)}),(0,Q.jsx)(`div`,{className:`bg-border h-px flex-1`})]}),(0,Q.jsxs)(A,{variant:`outline`,className:`w-full`,onClick:()=>c(N(`/preferences/github`)),children:[(0,Q.jsx)(a,{className:`icon-base mr-2`}),t(`github.useToken`)]}),(0,Q.jsx)(`p`,{className:`text-muted-foreground text-center text-xs`,children:(0,Q.jsx)(we,{i18nKey:`github.useTokenHint`,components:{link:(0,Q.jsx)(`a`,{href:`https://github.com/settings/tokens/new`,target:`_blank`,rel:`noopener noreferrer`,className:`hover:text-foreground underline`})}})})]})]});if(g===`device-flow`)return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-5 py-8`,children:[(0,Q.jsxs)(`div`,{className:`space-y-1 text-center`,children:[(0,Q.jsx)(`h3`,{className:`font-medium`,children:t(`github.deviceFlow.title`)}),(0,Q.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:t(`github.deviceFlow.desc`)})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`code`,{className:`bg-muted rounded-md px-4 py-2 font-mono text-2xl font-bold tracking-widest`,children:w}),(0,Q.jsx)(A,{variant:`outline`,size:`sm`,onClick:()=>ae(w),children:j?(0,Q.jsx)(d,{className:`icon-base`}):(0,Q.jsx)(i,{className:`icon-base`})})]}),(0,Q.jsx)(`div`,{className:`flex gap-2`,children:(0,Q.jsxs)(A,{variant:`outline`,onClick:()=>window.open(D,`_blank`),children:[(0,Q.jsx)(f,{className:`icon-base mr-2`}),t(`github.deviceFlow.openGithub`)]})}),(0,Q.jsx)(ue,{fill:!1,layout:`inline`,className:`text-sm`,testId:`clone-repo-waiting-auth`,label:t(`github.deviceFlow.waitingAuth`)}),(0,Q.jsx)(A,{variant:`ghost`,size:`sm`,className:`text-muted-foreground`,onClick:()=>{I.current&&clearInterval(I.current),_(`connect`)},children:t(`common.cancel`)})]});if(g===`repos`)return(0,Q.jsxs)(`div`,{className:`flex h-full flex-col`,children:[v&&(0,Q.jsxs)(`div`,{className:`mb-3 flex items-center gap-2`,children:[(0,Q.jsx)(`img`,{src:v.avatar_url,alt:v.login,className:`size-6 rounded-full`}),(0,Q.jsx)(`span`,{className:`text-sm font-medium`,children:v.login}),b===`cli`?(0,Q.jsx)(`span`,{className:`text-muted-foreground ml-auto text-xs`,children:t(`github.viaGhCli`,{defaultValue:`via gh CLI`})}):(0,Q.jsxs)(A,{variant:`ghost`,size:`sm`,className:`text-muted-foreground ml-auto h-7 text-xs`,onClick:Ge,"data-testid":`clone-repo-disconnect`,children:[(0,Q.jsx)(n,{className:`icon-xs mr-1`}),t(`github.disconnect`)]})]}),(0,Q.jsx)(`div`,{className:`mb-3`,children:(0,Q.jsx)(ce,{query:z,onQueryChange:B,placeholder:t(`github.repos.searchPlaceholder`),totalMatches:L.length,resultLabel:z?`${L.length}`:``,loading:ze,onClose:z?()=>B(``):void 0,onInputKeyDown:Be,autoFocus:!1,testIdPrefix:`clone-repo-search`,className:`border-input bg-background rounded-md border px-2`})}),(0,Q.jsxs)(se,{viewportRef:K,className:`-mx-1 max-h-[40vh] min-h-0 flex-1`,children:[L.map((e,t)=>(0,Q.jsxs)(`button`,{"data-repo-item":!0,"data-testid":`clone-repo-item-${e.id}`,onClick:()=>Ue(e),onMouseEnter:()=>G(t),className:O(`flex w-full flex-col gap-0.5 rounded-md px-3 py-2 text-left transition-colors hover:bg-accent`,W===t&&`bg-accent`),children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(M,{text:e.full_name,query:V,className:`truncate text-sm font-medium`}),e.private?(0,Q.jsx)(r,{className:`icon-xs text-status-pending shrink-0`}):(0,Q.jsx)(l,{className:`icon-xs text-muted-foreground shrink-0`})]}),e.description&&(0,Q.jsx)(M,{text:e.description,query:V,className:`text-muted-foreground truncate text-xs`}),(0,Q.jsxs)(`div`,{className:`text-muted-foreground flex items-center gap-3 text-xs`,children:[e.language&&(0,Q.jsx)(M,{text:e.language,query:V}),(0,Q.jsx)(`span`,{children:Ke(e.updated_at)})]})]},e.id)),_e&&(0,Q.jsx)(ue,{fill:!1,className:`py-4`,testId:`clone-repo-loading-repos`}),!_e&&L.length===0&&(0,Q.jsx)(`p`,{className:`text-muted-foreground py-8 text-center text-sm`,children:t(`github.repos.noRepos`)}),(0,Q.jsx)(`div`,{ref:ve,"aria-hidden":!0,className:`h-1 w-full`})]})]});if(g===`clone-config`&&Y)return(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsxs)(A,{variant:`ghost`,size:`sm`,className:`text-muted-foreground -ml-2`,onClick:()=>_(`repos`),children:[(0,Q.jsx)(s,{className:`icon-sm mr-1`}),t(`github.repos.title`)]}),(0,Q.jsxs)(`div`,{className:`border-border space-y-1 rounded-md border p-3`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`span`,{className:`text-sm font-medium`,children:Y.full_name}),Y.private&&(0,Q.jsx)(r,{className:`icon-xs text-status-pending`})]}),Y.description&&(0,Q.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:Y.description})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:t(`github.clone.projectName`)}),(0,Q.jsx)(R,{value:Z,onChange:e=>Ce(e.target.value)})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:t(`github.clone.destination`)}),(0,Q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Q.jsx)(R,{className:`flex-1`,placeholder:t(`github.clone.destinationDesc`),value:X,onChange:e=>Se(e.target.value)}),(0,Q.jsx)(A,{variant:`outline`,size:`sm`,onClick:()=>De(!0),children:(0,Q.jsx)(u,{className:`icon-base`})})]})]}),(0,Q.jsxs)(`div`,{className:`flex gap-2 pt-2`,children:[(0,Q.jsx)(A,{variant:`outline`,className:`flex-1`,onClick:()=>_(`repos`),children:t(`common.cancel`)}),(0,Q.jsx)(A,{className:`flex-1`,onClick:We,disabled:!X||!Z,children:t(`github.clone.cloneAndCreate`)})]}),Ee&&(0,Q.jsx)(fe,{onSelect:e=>{Se(e),De(!1)},onClose:()=>De(!1)})]});if(g===`cloning`){let e=Ae?Ae.replace(/:.*$/,``).trim().replace(/\b\w/g,e=>e.toUpperCase()):``;return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-12`,children:[(0,Q.jsx)(o,{className:`text-primary size-8 animate-spin`}),(0,Q.jsx)(`p`,{className:`text-sm font-medium`,children:t(`github.clone.cloning`,{repo:Y?.full_name})}),(0,Q.jsxs)(`div`,{className:`w-full max-w-xs`,children:[e&&(0,Q.jsx)(`p`,{className:`text-muted-foreground mb-1 text-xs font-medium`,children:e}),Me!==void 0&&(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`div`,{className:`bg-muted h-1.5 w-full overflow-hidden rounded-full`,children:(0,Q.jsx)(`div`,{className:O(`h-full rounded-full bg-primary`,Pe?``:`transition-all duration-300`),style:{width:`${Me}%`}})}),(0,Q.jsxs)(`p`,{className:`text-muted-foreground mt-1 text-right text-xs`,children:[Me,`%`]})]})]})]})}return null}function De(){let{t:e}=x(),t=E(),n=de(e=>e.loadProjects),[r,i]=(0,H.useState)(`local`),[a,s]=(0,H.useState)(``),[l,d]=(0,H.useState)(``),[f,p]=(0,H.useState)(!1),[m,h]=(0,H.useState)(!1),[g,_]=(0,H.useState)(!1),[v,y]=(0,H.useState)(!1);return(0,Q.jsxs)(se,{className:`flex flex-1 justify-center pt-[10vh]`,children:[(0,Q.jsxs)(`div`,{className:`mx-auto w-full max-w-md space-y-6 px-4 pb-8`,children:[!v&&(0,Q.jsxs)(`div`,{className:`space-y-2 text-center`,children:[(0,Q.jsx)(`div`,{className:`bg-primary/10 mx-auto flex size-12 items-center justify-center rounded-full`,children:(0,Q.jsx)(c,{className:`icon-xl text-primary`})}),(0,Q.jsx)(`h2`,{className:`text-xl font-semibold`,children:e(`sidebar.addProject`)})]}),(0,Q.jsxs)(`div`,{className:O(`flex gap-1 rounded-lg bg-muted p-1`,v&&`hidden`),children:[(0,Q.jsxs)(`button`,{className:`flex flex-1 items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${r===`local`?`bg-background text-foreground shadow-xs`:`text-muted-foreground hover:text-foreground`}`,"data-testid":`add-project-tab-local`,onClick:()=>i(`local`),children:[(0,Q.jsx)(u,{className:`icon-sm`}),e(`github.localFolder`)]}),(0,Q.jsxs)(`button`,{className:`flex flex-1 items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${r===`github`?`bg-background text-foreground shadow-xs`:`text-muted-foreground hover:text-foreground`}`,"data-testid":`add-project-tab-clone`,onClick:()=>i(`github`),children:[(0,Q.jsx)(oe,{className:`icon-sm`}),e(`github.cloneFromGithub`)]})]}),r===`local`?(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(`p`,{className:`text-muted-foreground text-center text-sm`,children:e(`sidebar.addProjectDescription`,{defaultValue:`Enter the project name and select the folder path.`})}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:e(`sidebar.projectName`)}),(0,Q.jsx)(R,{"data-testid":`add-project-name`,placeholder:e(`sidebar.projectName`),value:a,onChange:e=>s(e.target.value),autoFocus:!0})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:e(`sidebar.absolutePath`)}),(0,Q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Q.jsx)(R,{"data-testid":`add-project-path`,className:`flex-1`,placeholder:e(`sidebar.absolutePath`),value:l,onChange:e=>d(e.target.value)}),(0,Q.jsxs)(te,{children:[(0,Q.jsx)(k,{asChild:!0,children:(0,Q.jsx)(A,{"data-testid":`add-project-browse`,variant:`outline`,size:`sm`,onClick:()=>p(!0),"aria-label":e(`sidebar.browseFolder`),children:(0,Q.jsx)(u,{className:`icon-base`})})}),(0,Q.jsx)(w,{children:e(`sidebar.browseFolder`)})]})]})]}),(0,Q.jsxs)(`div`,{className:`flex gap-2 pt-2`,children:[(0,Q.jsx)(A,{"data-testid":`add-project-cancel`,variant:`outline`,className:`flex-1`,onClick:()=>t(N(`/`)),children:e(`common.cancel`,{defaultValue:`Cancel`})}),(0,Q.jsx)(A,{"data-testid":`add-project-submit`,className:`flex-1`,onClick:async()=>{if(!a||!l||m)return;h(!0);let r=await T.createProject(a,l);if(r.isErr()){if(r.error.message?.includes(`Not a git repository`)||r.error.message?.includes(`nested inside another git repository`)){h(!1),_(!0);return}F(r.error,`createProject`),h(!1);return}await n(),P.success(e(`project.created`,{name:a,defaultValue:`Project "${a}" created`})),t(N(`/projects/${r.value.id}`)),h(!1)},disabled:m||!a||!l,children:m?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(o,{className:`icon-base mr-2 animate-spin`}),e(`common.loading`)]}):e(`sidebar.add`)})]})]}):(0,Q.jsx)(Ee,{onCloningChange:y})]}),f&&(0,Q.jsx)(fe,{onSelect:async e=>{if(d(e),p(!1),!a){let t=await T.repoName(e);t.isOk()&&t.value.name?s(t.value.name):s(e.split(/[\\/]/).filter(Boolean).pop()||``)}},onClose:()=>p(!1)}),(0,Q.jsx)(re,{open:g,onOpenChange:_,children:(0,Q.jsxs)(L,{children:[(0,Q.jsxs)(ae,{children:[(0,Q.jsx)(ne,{children:e(`confirm.gitInitTitle`,{defaultValue:`Initialize Git Repository`})}),(0,Q.jsx)(j,{children:e(`confirm.notGitRepo`,{path:l})})]}),(0,Q.jsxs)(I,{children:[(0,Q.jsx)(A,{"data-testid":`git-init-cancel`,variant:`outline`,onClick:()=>_(!1),children:e(`common.cancel`,{defaultValue:`Cancel`})}),(0,Q.jsx)(A,{"data-testid":`git-init-confirm`,onClick:async()=>{_(!1),h(!0);let r=await T.gitInit(l);if(r.isErr()){F(r.error,`createProject`),h(!1);return}let i=await T.createProject(a,l);if(i.isErr()){F(i.error,`createProject`),h(!1);return}await n(),P.success(e(`project.created`,{name:a,defaultValue:`Project "${a}" created`})),t(N(`/projects/${i.value.id}`)),h(!1)},children:e(`confirm.gitInitAction`,{defaultValue:`Initialize`})})]})]})})]})}export{De as AddProjectView};
|
|
1
|
+
import{a as e,t}from"./rolldown-runtime-Cyuzqnbw.js";import{Ft as n,It as r,Kn as i,L as a,Lt as o,Mr as s,Q as c,on as l,yn as u,yr as d,zn as f,zr as p}from"./icons-sqwAEN28.js";import{o as m}from"./markdown-DBtwZWLP.js";import{i as h}from"./_core-lD_pNs53.js";import{a as g,i as _,n as v,o as y,r as b,t as x}from"./useTranslation-DAPPK3Hy.js";import{i as S,n as C,r as ee}from"./initReactI18next-Dr0vnWXF.js";import{G as w,P as T,W as te,_t as E,j as D,lt as O,q as k}from"./index-Bmp1UFM1.js";import{t as A}from"./button-Bi9_EZFh.js";import{$r as ne,Gr as re,Jr as j,K as ie,Nn as M,Rt as N,Ur as P,Wn as F,Xr as ae,Yr as I,gt as oe,in as se,mn as ce,qr as L,yr as le}from"./items-C-m69VjA.js";import{t as R}from"./input-BGZP-HTx.js";import{t as ue}from"./loading-state-DGzdeccZ.js";import{t as de}from"./app-store-CVcOgstJ.js";import{t as fe}from"./FolderPicker-DEwPUyou.js";var pe=e(t(((e,t)=>{t.exports={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}}))()),z=/\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g;function B(e){var t={type:`tag`,name:``,voidElement:!1,attrs:{},children:[]},n=e.match(/<\/?([^\s]+?)[/\s>]/);if(n&&(t.name=n[1],(pe.default[n[1]]||e.charAt(e.length-2)===`/`)&&(t.voidElement=!0),t.name.startsWith(`!--`))){var r=e.indexOf(`-->`);return{type:`comment`,comment:r===-1?``:e.slice(4,r)}}for(var i=new RegExp(z),a=null;(a=i.exec(e))!==null;)if(a[0].trim())if(a[1]){var o=a[1].trim(),s=[o,``];o.indexOf(`=`)>-1&&(s=o.split(`=`)),t.attrs[s[0]]=s[1],i.lastIndex--}else a[2]&&(t.attrs[a[2]]=a[3].trim().substring(1,a[3].length-1));return t}var V=/<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g,me=/^\s*$/,he=Object.create(null);function ge(e,t){switch(t.type){case`text`:return e+t.content;case`tag`:return e+=`<`+t.name+(t.attrs?function(e){var t=[];for(var n in e)t.push(n+`="`+e[n]+`"`);return t.length?` `+t.join(` `):``}(t.attrs):``)+(t.voidElement?`/>`:`>`),t.voidElement?e:e+t.children.reduce(ge,``)+`</`+t.name+`>`;case`comment`:return e+`<!--`+t.comment+`-->`}}var _e={parse:function(e,t){t||={},t.components||=he;var n,r=[],i=[],a=-1,o=!1;if(e.indexOf(`<`)!==0){var s=e.indexOf(`<`);r.push({type:`text`,content:s===-1?e:e.substring(0,s)})}return e.replace(V,function(s,c){if(o){if(s!==`</`+n.name+`>`)return;o=!1}var l,u=s.charAt(1)!==`/`,d=s.startsWith(`<!--`),f=c+s.length,p=e.charAt(f);if(d){var m=B(s);return a<0?(r.push(m),r):((l=i[a]).children.push(m),r)}if(u&&(a++,(n=B(s)).type===`tag`&&t.components[n.name]&&(n.type=`component`,o=!0),n.voidElement||o||!p||p===`<`||n.children.push({type:`text`,content:e.slice(f,e.indexOf(`<`,f))}),a===0&&r.push(n),(l=i[a-1])&&l.children.push(n),i[a]=n),(!u||n.voidElement)&&(a>-1&&(n.voidElement||n.name===s.slice(2,-1))&&(a--,n=a===-1?r:i[a]),!o&&p!==`<`&&p)){l=a===-1?r:i[a].children;var h=e.indexOf(`<`,f),g=e.slice(f,h===-1?void 0:h);me.test(g)&&(g=` `),(h>-1&&a+l.length>=0||g!==` `)&&l.push({type:`text`,content:g})}}),r},stringify:function(e){return e.reduce(function(e,t){return e+ge(``,t)},``)}},H=e(p()),U=(e,t)=>{if(!e)return!1;let n=e.props?.children??e.children;return t?n.length>0:!!n},W=e=>{if(!e)return[];let t=e.props?.children??e.children;return e.props?.i18nIsDynamicList?K(t):t},G=e=>Array.isArray(e)&&e.every(H.isValidElement),K=e=>Array.isArray(e)?e:[e],ve=(e,t)=>{let n={...t};return n.props={...t.props,...e.props},n},q=e=>{let t={};if(!e)return t;let n=e=>{K(e).forEach(e=>{_(e)||(U(e)?n(W(e)):b(e)&&!(0,H.isValidElement)(e)&&Object.assign(t,e))})};return n(e),t},J=(e,t,n,r)=>{if(!e)return``;let i=``,a=K(e),o=t?.transSupportBasicHtmlNodes?t.transKeepBasicHtmlNodesFor??[]:[];return a.forEach((e,a)=>{if(_(e)){i+=`${e}`;return}if((0,H.isValidElement)(e)){let{props:s,type:c}=e,l=Object.keys(s).length,u=o.indexOf(c)>-1,d=s.children;if(!d&&u&&!l){i+=`<${c}/>`;return}if(!d&&(!u||l)||s.i18nIsDynamicList){i+=`<${a}></${a}>`;return}if(u&&l<=1){let e=_(d)?d:J(d,t,n,r);i+=`<${c}>${e}</${c}>`;return}let f=J(d,t,n,r);i+=`<${a}>${f}</${a}>`;return}if(e===null){g(n,`TRANS_NULL_VALUE`,`Passed in a null value as child`,{i18nKey:r});return}if(b(e)){let{format:t,...a}=e,o=Object.keys(a);if(o.length===1){let e=t?`${o[0]}, ${t}`:o[0];i+=`{{${e}}}`;return}g(n,`TRANS_INVALID_OBJ`,`Invalid child - Object should only have keys {{ value, format }} (format is optional).`,{i18nKey:r,child:e});return}g(n,`TRANS_INVALID_VAR`,`Passed in a variable like {number} - pass variables for interpolation as full objects like {{number}}.`,{i18nKey:r,child:e})}),i},ye=(e,t=[],n={})=>{if(!e)return e;let r=Object.keys(n),i=[...t,...r],a=``,o=0;for(;o<e.length;)if(e[o]===`<`){let t=!1,n=e.slice(o).match(/^<\/(\d+|[a-zA-Z][a-zA-Z0-9_-]*)>/);if(n){let e=n[1];(/^\d+$/.test(e)||i.includes(e))&&(t=!0,a+=n[0],o+=n[0].length)}if(!t){let n=e.slice(o).match(/^<(\d+|[a-zA-Z][a-zA-Z0-9_-]*)(\s+[\w-]+(?:=(?:"[^"]*"|'[^']*'|[^\s>]+))?)*\s*(\/)?>/);if(n){let e=n[1];(/^\d+$/.test(e)||i.includes(e))&&(t=!0,a+=n[0],o+=n[0].length)}}t||(a+=`<`,o+=1)}else a+=e[o],o+=1;return a},be=(e,t,n,r,i,a,o)=>{if(n===``)return[];let s=i.transKeepBasicHtmlNodesFor||[],c=n&&new RegExp(s.map(e=>`<${e}`).join(`|`)).test(n);if(!e&&!t&&!c&&!o)return[n];let l=t??{},u=e=>{K(e).forEach(e=>{_(e)||(U(e)?u(W(e)):b(e)&&!(0,H.isValidElement)(e)&&Object.assign(l,e))})};u(e);let d=ye(n,s,l),f=_e.parse(`<0>${d}</0>`),p={...l,...a},m=(e,t,n)=>{let r=W(e),i=g(r,t.children,n);return G(r)&&i.length===0||e.props?.i18nIsDynamicList?r:i},h=(e,t,n,r,i)=>{e.dummy?(e.children=t,n.push((0,H.cloneElement)(e,{key:r},i?void 0:t))):n.push(...H.Children.map([e],e=>{if(e.type===H.Fragment||e.props?.i18nIsDynamicList!==void 0){let n={key:r};return e&&e.props&&Object.keys(e.props).forEach(t=>{t===`children`||t===`i18nIsDynamicList`||(n[t]=e.props[t])}),(0,H.createElement)(e.type,n,i?null:t)}let n={key:r};return e&&e.props&&Object.keys(e.props).forEach(t=>{t===`ref`||t===`children`||(n[t]=e.props[t])}),(0,H.cloneElement)(e,n,i?null:t)}))},g=(e,n,a)=>{let l=K(e),u=K(n),d={};return u.reduce((e,n,u)=>{let f=n.children?.[0]?.content&&r.services.interpolator.interpolate(n.children[0].content,p,r.language);if(n.type===`tag`){let v=l[parseInt(n.name,10)];!v&&t&&(v=t[n.name]),a.length===1&&!v&&(v=a[0][n.name]),v||={};let y={...n.attrs};o&&Object.keys(y).forEach(e=>{let t=y[e];_(t)&&(y[e]=S(t))});let x=Object.keys(y).length===0?v:ve({props:y},v),C=(0,H.isValidElement)(x),ee=C&&U(n,!0)&&!n.voidElement,w=c&&b(x)&&x.dummy&&!C,T=b(t)&&Object.hasOwnProperty.call(t,n.name);if(_(x)){let t=r.services.interpolator.interpolate(x,p,r.language);e.push(t)}else if(U(x)||ee)h(x,m(x,n,a),e,u);else if(w)h(x,g(l,n.children,a),e,u);else if(Number.isNaN(parseFloat(n.name)))if(T)h(x,m(x,n,a),e,u,n.voidElement);else if(i.transSupportBasicHtmlNodes&&s.indexOf(n.name)>-1)if(n.voidElement)e.push((0,H.createElement)(n.name,{key:`${n.name}-${u}`}));else{let t=d[n.name]||0;d[n.name]=t+1;let r,i=0;for(let e=0;e<l.length;e+=1){let a=l[e];if((0,H.isValidElement)(a)&&a.type===n.name){if(i===t){r=a;break}i+=1}}let o=g(r?K(W(r)):l,n.children,a);e.push((0,H.createElement)(n.name,{key:`${n.name}-${u}`},o))}else if(n.voidElement)e.push(`<${n.name} />`);else{let t=g(l,n.children,a);e.push(`<${n.name}>${t}</${n.name}>`)}else if(b(x)&&!C){let t=n.children[0]?f:null;t&&e.push(t)}else h(x,f,e,u,n.children.length!==1||!f)}else if(n.type===`text`){let t=i.transWrapTextNodes,a=typeof i.unescape==`function`?i.unescape:ee().unescape,s=o?a(r.services.interpolator.interpolate(n.content,p,r.language)):r.services.interpolator.interpolate(n.content,p,r.language);t?e.push((0,H.createElement)(t,{key:`${n.name}-${u}`},s)):e.push(s)}return e},[])};return W(g([{dummy:!0,children:e||[]}],f,K(e||[]))[0])},Y=(e,t,n)=>{let r=e.key||t,i=(0,H.cloneElement)(e,{key:r});if(!i.props||!i.props.children||n.indexOf(`${t}/>`)<0&&n.indexOf(`${t} />`)<0)return i;function a(){return(0,H.createElement)(H.Fragment,null,i)}return(0,H.createElement)(a,{key:r})},xe=(e,t)=>e.map((e,n)=>Y(e,n,t)),X=(e,t)=>{let n={};return Object.keys(e).forEach(r=>{Object.assign(n,{[r]:Y(e[r],r,t)})}),n},Se=(e,t,n,r)=>e?Array.isArray(e)?xe(e,t):b(e)?X(e,t):(y(n,`TRANS_INVALID_COMPONENTS`,`<Trans /> "components" prop expects an object or array`,{i18nKey:r}),null):null,Z=e=>!b(e)||Array.isArray(e)?!1:Object.keys(e).reduce((e,t)=>e&&Number.isNaN(Number.parseFloat(t)),!0);function Ce({children:e,count:t,parent:n,i18nKey:r,context:i,tOptions:a={},values:o,defaults:s,components:c,ns:l,i18n:u,t:d,shouldUnescape:f,...p}){let m=u||C();if(!m)return y(m,`NO_I18NEXT_INSTANCE`,`Trans: You need to pass in an i18next instance using i18nextReactModule`,{i18nKey:r}),e;let g=d||m.t.bind(m)||(e=>e),v={...ee(),...m.options?.react},b=l||g.ns||m.options?.defaultNS;b=_(b)?[b]:b||[`translation`];let{transDefaultProps:x}=v,S=x?.tOptions?{...x.tOptions,...a}:a,w=f??x?.shouldUnescape,T=x?.values?{...x.values,...o}:o,te=x?.components?{...x.components,...c}:c,E=J(e,v,m,r),D=s||S?.defaultValue||E||v.transEmptyNodeValue||(typeof r==`function`?h(r):r),{hashTransKey:O}=v,k=r||(O?O(E||D):E||D);o=m.options?.interpolation?.defaultVariables?T&&Object.keys(T).length>0?{...T,...m.options.interpolation.defaultVariables}:{...m.options.interpolation.defaultVariables}:T;let A=q(e);A&&typeof A.count==`number`&&t===void 0&&(t=A.count);let ne=o||t!==void 0&&!m.options?.interpolation?.alwaysFormat||!e?S.interpolation:{interpolation:{...S.interpolation,prefix:`#$?`,suffix:`?$#`}},re={...S,context:i||S.context,count:t,...o,...ne,defaultValue:D,ns:b},j=k?g(k,re):D;j===k&&D&&(j=D);let ie=Se(te,j,m,r),M=ie||e,N=null;Z(ie)&&(N=ie,M=e);let P=be(M,N,j,m,v,re,w),F=n??v.defaultTransParent;return F?(0,H.createElement)(F,p,P):P}function we({children:e,count:t,parent:n,i18nKey:r,context:i,tOptions:a={},values:o,defaults:s,components:c,ns:l,i18n:u,t:d,shouldUnescape:f,...p}){let{i18n:m,defaultNS:h}=(0,H.useContext)(v)||{},g=u||m||C(),_=d||g?.t.bind(g);return Ce({children:e,count:t,parent:n,i18nKey:r,context:i,tOptions:a,values:o,defaults:s,components:c,ns:l||_?.ns||h||g?.options?.defaultNS,i18n:g,t:d,shouldUnescape:f,...p})}var Q=e(m(),1),Te=D(`clone-repo-view`);function Ee({onCloningChange:e}={}){let{t}=x(),c=E(),p=de(e=>e.loadProjects),m=de(e=>e.setAddProjectOpen),h=le(e=>e.generalSettingsOpen),[g,_]=(0,H.useState)(`checking`);(0,H.useEffect)(()=>{e?.(g===`cloning`)},[g,e]);let[v,y]=(0,H.useState)(null),[b,S]=(0,H.useState)(null),[C,ee]=(0,H.useState)(``),[w,te]=(0,H.useState)(``),[D,k]=(0,H.useState)(``),[ne,re]=(0,H.useState)(5),[j,ae]=ie(),I=(0,H.useRef)(null),[L,pe]=(0,H.useState)([]),[z,B]=(0,H.useState)(``),[V,me]=(0,H.useState)(``),[he,ge]=(0,H.useState)(!1),[_e,U]=(0,H.useState)(!1),[W,G]=(0,H.useState)(-1),K=(0,H.useRef)(null),ve=(0,H.useRef)(null),q=(0,H.useRef)(void 0),J=(0,H.useRef)(!1),ye=(0,H.useRef)(0),be=(0,H.useRef)(1),[Y,xe]=(0,H.useState)(null),[X,Se]=(0,H.useState)(``),[Z,Ce]=(0,H.useState)(``),[Ee,De]=(0,H.useState)(!1),[Oe,ke]=(0,H.useState)(!1),[Ae,je]=(0,H.useState)(``),[Me,Ne]=(0,H.useState)(void 0),[Pe,Fe]=(0,H.useState)(!1),Ie=(0,H.useRef)(``);(0,H.useEffect)(()=>{let e=e=>{let t=e.detail;if(t.phase){let e=t.phase.replace(/:.*$/,``).trim();e!==Ie.current&&(Fe(!0),Ie.current=e,requestAnimationFrame(()=>Fe(!1))),je(t.phase)}t.percent!==void 0&&Ne(t.percent)};return window.addEventListener(`clone:progress`,e),()=>window.removeEventListener(`clone:progress`,e)},[]);let $=(0,H.useCallback)(async()=>{let e=await T.githubStatus();e.isOk()?e.value.connected?(S(e.value.source??`profile`),await Le(),_(`repos`)):(S(null),_(`connect`)):_(`error`)},[]);(0,H.useEffect)(()=>{$()},[$]),(0,H.useEffect)(()=>{!h&&(g===`connect`||g===`error`)&&$()},[h,g,$]);let Le=async()=>{let e=await T.githubUser();e.isOk()&&y(e.value)},Re=(0,H.useCallback)(async(e,t,n)=>{let r=++ye.current;J.current=!0,U(!0),Te.debug(`github repo search`,{page:e,query:t,append:n});let i=await T.githubRepos({page:e,per_page:30,sort:`updated`,search:t||void 0});r===ye.current&&(i.isOk()&&(pe(e=>n?[...e,...i.value.repos]:i.value.repos),ge(i.value.hasMore)),J.current=!1,U(!1))},[]);(0,H.useEffect)(()=>(q.current&&clearTimeout(q.current),q.current=setTimeout(()=>{me(z)},200),()=>{q.current&&clearTimeout(q.current)}),[z]);let ze=z!==V||_e;(0,H.useEffect)(()=>{G(-1)},[V]);let Be=e=>{if(e.key===`ArrowDown`)e.preventDefault(),G(e=>Math.min(e+1,L.length-1));else if(e.key===`ArrowUp`)e.preventDefault(),G(e=>Math.max(e-1,0));else if(e.key===`Enter`&&W>=0&&W<L.length){e.preventDefault();let t=L[W];xe(t),Ce(t.name),_(`clone-config`)}};(0,H.useEffect)(()=>{W<0||!K.current||K.current.querySelectorAll(`[data-repo-item]`)[W]?.scrollIntoView({block:`nearest`})},[W]),(0,H.useEffect)(()=>{g===`repos`&&(be.current=1,Re(1,V,!1))},[g,V,Re]),(0,H.useEffect)(()=>{if(g!==`repos`)return;let e=K.current,t=ve.current;if(!e||!t)return;let n=new IntersectionObserver(e=>{if(!e[0]?.isIntersecting||J.current||!he)return;let t=be.current+1;be.current=t,Re(t,V,!0)},{root:e,rootMargin:`0px 0px 200px 0px`,threshold:0});return n.observe(t),()=>n.disconnect()},[g,he,V,Re]),(0,H.useEffect)(()=>()=>{I.current&&clearInterval(I.current)},[]);let Ve=async()=>{let e=await T.githubStartDevice();if(e.isErr()){F(e.error,`cloneRepo`);return}let t=e.value;ee(t.device_code),te(t.user_code),k(t.verification_uri),re(t.interval),_(`device-flow`),He(t.device_code,t.interval)},He=(e,n)=>{I.current&&clearInterval(I.current),I.current=setInterval(async()=>{let n=await T.githubPoll(e);if(n.isErr())return;let r=n.value;r.status===`success`?(I.current&&clearInterval(I.current),await Le(),_(`repos`),P.success(t(`github.connected`,{login:``}))):r.status===`expired`||r.status===`denied`?(I.current&&clearInterval(I.current),P.error(r.status===`expired`?t(`github.deviceFlow.expired`):t(`github.deviceFlow.denied`)),_(`connect`)):r.interval&&(I.current&&clearInterval(I.current),He(e,r.interval))},(n+1)*1e3)},Ue=e=>{xe(e),Ce(e.name),_(`clone-config`)},We=async()=>{if(!Y||!X||!Z)return;ke(!0),je(``),Ne(void 0),_(`cloning`);let e=await T.cloneRepo(Y.clone_url,X,Z);if(e.isErr()){F(e.error,`cloneRepo`),ke(!1),_(`clone-config`);return}P.success(t(`github.clone.success`)),await p(),m(!1),c(N(`/projects/${e.value.id}`))},Ge=async()=>{await T.githubDisconnect(),y(null),pe([]),_(`connect`),P.success(t(`github.disconnected`))},Ke=e=>{let n=Date.now()-new Date(e).getTime(),r=Math.floor(n/6e4);if(r<60)return t(`time.minutes`,{count:r});let i=Math.floor(r/60);if(i<24)return t(`time.hours`,{count:i});let a=Math.floor(i/24);return a<30?t(`time.days`,{count:a}):t(`time.months`,{count:Math.floor(a/30)})};if(g===`checking`)return(0,Q.jsx)(ue,{fill:!1,className:`py-12`,testId:`clone-repo-checking`});if(g===`error`)return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-8`,children:[(0,Q.jsx)(`div`,{className:`bg-destructive/10 flex size-12 items-center justify-center rounded-full`,children:(0,Q.jsx)(oe,{className:`icon-xl text-destructive`})}),(0,Q.jsxs)(`div`,{className:`space-y-1 text-center`,children:[(0,Q.jsx)(`h3`,{className:`font-medium`,children:t(`github.connectionError`,{defaultValue:`Connection Error`})}),(0,Q.jsx)(`p`,{className:`text-muted-foreground max-w-xs text-sm`,children:t(`github.connectionErrorDesc`,{defaultValue:`Could not check GitHub connection status. The server may be unavailable.`})})]}),(0,Q.jsx)(A,{onClick:()=>{_(`checking`),$()},"data-testid":`clone-repo-retry`,children:t(`common.retry`,{defaultValue:`Retry`})})]});if(g===`connect`)return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-8`,children:[(0,Q.jsx)(`div`,{className:`bg-muted flex size-12 items-center justify-center rounded-full`,children:(0,Q.jsx)(oe,{className:`icon-xl`})}),(0,Q.jsxs)(`div`,{className:`space-y-1 text-center`,children:[(0,Q.jsx)(`h3`,{className:`font-medium`,children:t(`github.connectGithub`)}),(0,Q.jsx)(`p`,{className:`text-muted-foreground max-w-xs text-sm`,children:t(`github.connectDesc`)})]}),(0,Q.jsxs)(`div`,{className:`flex w-full max-w-xs flex-col gap-2`,children:[(0,Q.jsxs)(A,{className:`w-full`,onClick:Ve,children:[(0,Q.jsx)(oe,{className:`icon-base mr-2`}),t(`github.connectGithub`)]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsx)(`div`,{className:`bg-border h-px flex-1`}),(0,Q.jsx)(`span`,{className:`text-muted-foreground text-xs`,children:t(`common.or`)}),(0,Q.jsx)(`div`,{className:`bg-border h-px flex-1`})]}),(0,Q.jsxs)(A,{variant:`outline`,className:`w-full`,onClick:()=>c(N(`/preferences/github`)),children:[(0,Q.jsx)(a,{className:`icon-base mr-2`}),t(`github.useToken`)]}),(0,Q.jsx)(`p`,{className:`text-muted-foreground text-center text-xs`,children:(0,Q.jsx)(we,{i18nKey:`github.useTokenHint`,components:{link:(0,Q.jsx)(`a`,{href:`https://github.com/settings/tokens/new`,target:`_blank`,rel:`noopener noreferrer`,className:`hover:text-foreground underline`})}})})]})]});if(g===`device-flow`)return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-5 py-8`,children:[(0,Q.jsxs)(`div`,{className:`space-y-1 text-center`,children:[(0,Q.jsx)(`h3`,{className:`font-medium`,children:t(`github.deviceFlow.title`)}),(0,Q.jsx)(`p`,{className:`text-muted-foreground text-sm`,children:t(`github.deviceFlow.desc`)})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`code`,{className:`bg-muted rounded-md px-4 py-2 font-mono text-2xl font-bold tracking-widest`,children:w}),(0,Q.jsx)(A,{variant:`outline`,size:`sm`,onClick:()=>ae(w),children:j?(0,Q.jsx)(d,{className:`icon-base`}):(0,Q.jsx)(i,{className:`icon-base`})})]}),(0,Q.jsx)(`div`,{className:`flex gap-2`,children:(0,Q.jsxs)(A,{variant:`outline`,onClick:()=>window.open(D,`_blank`),children:[(0,Q.jsx)(f,{className:`icon-base mr-2`}),t(`github.deviceFlow.openGithub`)]})}),(0,Q.jsx)(ue,{fill:!1,layout:`inline`,className:`text-sm`,testId:`clone-repo-waiting-auth`,label:t(`github.deviceFlow.waitingAuth`)}),(0,Q.jsx)(A,{variant:`ghost`,size:`sm`,className:`text-muted-foreground`,onClick:()=>{I.current&&clearInterval(I.current),_(`connect`)},children:t(`common.cancel`)})]});if(g===`repos`)return(0,Q.jsxs)(`div`,{className:`flex h-full flex-col`,children:[v&&(0,Q.jsxs)(`div`,{className:`mb-3 flex items-center gap-2`,children:[(0,Q.jsx)(`img`,{src:v.avatar_url,alt:v.login,className:`size-6 rounded-full`}),(0,Q.jsx)(`span`,{className:`text-sm font-medium`,children:v.login}),b===`cli`?(0,Q.jsx)(`span`,{className:`text-muted-foreground ml-auto text-xs`,children:t(`github.viaGhCli`,{defaultValue:`via gh CLI`})}):(0,Q.jsxs)(A,{variant:`ghost`,size:`sm`,className:`text-muted-foreground ml-auto h-7 text-xs`,onClick:Ge,"data-testid":`clone-repo-disconnect`,children:[(0,Q.jsx)(n,{className:`icon-xs mr-1`}),t(`github.disconnect`)]})]}),(0,Q.jsx)(`div`,{className:`mb-3`,children:(0,Q.jsx)(ce,{query:z,onQueryChange:B,placeholder:t(`github.repos.searchPlaceholder`),totalMatches:L.length,resultLabel:z?`${L.length}`:``,loading:ze,onClose:z?()=>B(``):void 0,onInputKeyDown:Be,autoFocus:!1,testIdPrefix:`clone-repo-search`,className:`border-input bg-background rounded-md border px-2`})}),(0,Q.jsxs)(se,{viewportRef:K,className:`-mx-1 max-h-[40vh] min-h-0 flex-1`,children:[L.map((e,t)=>(0,Q.jsxs)(`button`,{"data-repo-item":!0,"data-testid":`clone-repo-item-${e.id}`,onClick:()=>Ue(e),onMouseEnter:()=>G(t),className:O(`flex w-full flex-col gap-0.5 rounded-md px-3 py-2 text-left transition-colors hover:bg-accent`,W===t&&`bg-accent`),children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(M,{text:e.full_name,query:V,className:`truncate text-sm font-medium`}),e.private?(0,Q.jsx)(r,{className:`icon-xs text-status-pending shrink-0`}):(0,Q.jsx)(l,{className:`icon-xs text-muted-foreground shrink-0`})]}),e.description&&(0,Q.jsx)(M,{text:e.description,query:V,className:`text-muted-foreground truncate text-xs`}),(0,Q.jsxs)(`div`,{className:`text-muted-foreground flex items-center gap-3 text-xs`,children:[e.language&&(0,Q.jsx)(M,{text:e.language,query:V}),(0,Q.jsx)(`span`,{children:Ke(e.updated_at)})]})]},e.id)),_e&&(0,Q.jsx)(ue,{fill:!1,className:`py-4`,testId:`clone-repo-loading-repos`}),!_e&&L.length===0&&(0,Q.jsx)(`p`,{className:`text-muted-foreground py-8 text-center text-sm`,children:t(`github.repos.noRepos`)}),(0,Q.jsx)(`div`,{ref:ve,"aria-hidden":!0,className:`h-1 w-full`})]})]});if(g===`clone-config`&&Y)return(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsxs)(A,{variant:`ghost`,size:`sm`,className:`text-muted-foreground -ml-2`,onClick:()=>_(`repos`),children:[(0,Q.jsx)(s,{className:`icon-sm mr-1`}),t(`github.repos.title`)]}),(0,Q.jsxs)(`div`,{className:`border-border space-y-1 rounded-md border p-3`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`span`,{className:`text-sm font-medium`,children:Y.full_name}),Y.private&&(0,Q.jsx)(r,{className:`icon-xs text-status-pending`})]}),Y.description&&(0,Q.jsx)(`p`,{className:`text-muted-foreground text-xs`,children:Y.description})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:t(`github.clone.projectName`)}),(0,Q.jsx)(R,{value:Z,onChange:e=>Ce(e.target.value)})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:t(`github.clone.destination`)}),(0,Q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Q.jsx)(R,{className:`flex-1`,placeholder:t(`github.clone.destinationDesc`),value:X,onChange:e=>Se(e.target.value)}),(0,Q.jsx)(A,{variant:`outline`,size:`sm`,onClick:()=>De(!0),children:(0,Q.jsx)(u,{className:`icon-base`})})]})]}),(0,Q.jsxs)(`div`,{className:`flex gap-2 pt-2`,children:[(0,Q.jsx)(A,{variant:`outline`,className:`flex-1`,onClick:()=>_(`repos`),children:t(`common.cancel`)}),(0,Q.jsx)(A,{className:`flex-1`,onClick:We,disabled:!X||!Z,children:t(`github.clone.cloneAndCreate`)})]}),Ee&&(0,Q.jsx)(fe,{onSelect:e=>{Se(e),De(!1)},onClose:()=>De(!1)})]});if(g===`cloning`){let e=Ae?Ae.replace(/:.*$/,``).trim().replace(/\b\w/g,e=>e.toUpperCase()):``;return(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-12`,children:[(0,Q.jsx)(o,{className:`text-primary size-8 animate-spin`}),(0,Q.jsx)(`p`,{className:`text-sm font-medium`,children:t(`github.clone.cloning`,{repo:Y?.full_name})}),(0,Q.jsxs)(`div`,{className:`w-full max-w-xs`,children:[e&&(0,Q.jsx)(`p`,{className:`text-muted-foreground mb-1 text-xs font-medium`,children:e}),Me!==void 0&&(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`div`,{className:`bg-muted h-1.5 w-full overflow-hidden rounded-full`,children:(0,Q.jsx)(`div`,{className:O(`h-full rounded-full bg-primary`,Pe?``:`transition-all duration-300`),style:{width:`${Me}%`}})}),(0,Q.jsxs)(`p`,{className:`text-muted-foreground mt-1 text-right text-xs`,children:[Me,`%`]})]})]})]})}return null}function De(){let{t:e}=x(),t=E(),n=de(e=>e.loadProjects),[r,i]=(0,H.useState)(`local`),[a,s]=(0,H.useState)(``),[l,d]=(0,H.useState)(``),[f,p]=(0,H.useState)(!1),[m,h]=(0,H.useState)(!1),[g,_]=(0,H.useState)(!1),[v,y]=(0,H.useState)(!1);return(0,Q.jsxs)(se,{className:`flex flex-1 justify-center pt-[10vh]`,children:[(0,Q.jsxs)(`div`,{className:`mx-auto w-full max-w-md space-y-6 px-4 pb-8`,children:[!v&&(0,Q.jsxs)(`div`,{className:`space-y-2 text-center`,children:[(0,Q.jsx)(`div`,{className:`bg-primary/10 mx-auto flex size-12 items-center justify-center rounded-full`,children:(0,Q.jsx)(c,{className:`icon-xl text-primary`})}),(0,Q.jsx)(`h2`,{className:`text-xl font-semibold`,children:e(`sidebar.addProject`)})]}),(0,Q.jsxs)(`div`,{className:O(`flex gap-1 rounded-lg bg-muted p-1`,v&&`hidden`),children:[(0,Q.jsxs)(`button`,{className:`flex flex-1 items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${r===`local`?`bg-background text-foreground shadow-xs`:`text-muted-foreground hover:text-foreground`}`,"data-testid":`add-project-tab-local`,onClick:()=>i(`local`),children:[(0,Q.jsx)(u,{className:`icon-sm`}),e(`github.localFolder`)]}),(0,Q.jsxs)(`button`,{className:`flex flex-1 items-center justify-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium transition-colors ${r===`github`?`bg-background text-foreground shadow-xs`:`text-muted-foreground hover:text-foreground`}`,"data-testid":`add-project-tab-clone`,onClick:()=>i(`github`),children:[(0,Q.jsx)(oe,{className:`icon-sm`}),e(`github.cloneFromGithub`)]})]}),r===`local`?(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(`p`,{className:`text-muted-foreground text-center text-sm`,children:e(`sidebar.addProjectDescription`,{defaultValue:`Enter the project name and select the folder path.`})}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:e(`sidebar.projectName`)}),(0,Q.jsx)(R,{"data-testid":`add-project-name`,placeholder:e(`sidebar.projectName`),value:a,onChange:e=>s(e.target.value),autoFocus:!0})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`label`,{className:`mb-1.5 block text-sm font-medium`,children:e(`sidebar.absolutePath`)}),(0,Q.jsxs)(`div`,{className:`flex gap-2`,children:[(0,Q.jsx)(R,{"data-testid":`add-project-path`,className:`flex-1`,placeholder:e(`sidebar.absolutePath`),value:l,onChange:e=>d(e.target.value)}),(0,Q.jsxs)(te,{children:[(0,Q.jsx)(k,{asChild:!0,children:(0,Q.jsx)(A,{"data-testid":`add-project-browse`,variant:`outline`,size:`sm`,onClick:()=>p(!0),"aria-label":e(`sidebar.browseFolder`),children:(0,Q.jsx)(u,{className:`icon-base`})})}),(0,Q.jsx)(w,{children:e(`sidebar.browseFolder`)})]})]})]}),(0,Q.jsxs)(`div`,{className:`flex gap-2 pt-2`,children:[(0,Q.jsx)(A,{"data-testid":`add-project-cancel`,variant:`outline`,className:`flex-1`,onClick:()=>t(N(`/`)),children:e(`common.cancel`,{defaultValue:`Cancel`})}),(0,Q.jsx)(A,{"data-testid":`add-project-submit`,className:`flex-1`,onClick:async()=>{if(!a||!l||m)return;h(!0);let r=await T.createProject(a,l);if(r.isErr()){if(r.error.message?.includes(`Not a git repository`)||r.error.message?.includes(`nested inside another git repository`)){h(!1),_(!0);return}F(r.error,`createProject`),h(!1);return}await n(),P.success(e(`project.created`,{name:a,defaultValue:`Project "${a}" created`})),t(N(`/projects/${r.value.id}`)),h(!1)},disabled:m||!a||!l,children:m?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(o,{className:`icon-base mr-2 animate-spin`}),e(`common.loading`)]}):e(`sidebar.add`)})]})]}):(0,Q.jsx)(Ee,{onCloningChange:y})]}),f&&(0,Q.jsx)(fe,{onSelect:async e=>{if(d(e),p(!1),!a){let t=await T.repoName(e);t.isOk()&&t.value.name?s(t.value.name):s(e.split(/[\\/]/).filter(Boolean).pop()||``)}},onClose:()=>p(!1)}),(0,Q.jsx)(re,{open:g,onOpenChange:_,children:(0,Q.jsxs)(L,{children:[(0,Q.jsxs)(ae,{children:[(0,Q.jsx)(ne,{children:e(`confirm.gitInitTitle`,{defaultValue:`Initialize Git Repository`})}),(0,Q.jsx)(j,{children:e(`confirm.notGitRepo`,{path:l})})]}),(0,Q.jsxs)(I,{children:[(0,Q.jsx)(A,{"data-testid":`git-init-cancel`,variant:`outline`,onClick:()=>_(!1),children:e(`common.cancel`,{defaultValue:`Cancel`})}),(0,Q.jsx)(A,{"data-testid":`git-init-confirm`,onClick:async()=>{_(!1),h(!0);let r=await T.gitInit(l);if(r.isErr()){F(r.error,`createProject`),h(!1);return}let i=await T.createProject(a,l);if(i.isErr()){F(i.error,`createProject`),h(!1);return}await n(),P.success(e(`project.created`,{name:a,defaultValue:`Project "${a}" created`})),t(N(`/projects/${i.value.id}`)),h(!1)},children:e(`confirm.gitInitAction`,{defaultValue:`Initialize`})})]})]})})]})}export{De as AddProjectView};
|