@loicngr/kobo 1.8.8 → 1.9.0
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/AGENTS.md +3 -1
- package/CHANGELOG.md +12 -1
- package/README.md +12 -2
- package/dist/server/db/migrations.js +18 -0
- package/dist/server/db/schema.js +1 -0
- package/dist/server/index.js +14 -2
- package/dist/server/middleware/network-auth-middleware.js +4 -1
- package/dist/server/routes/settings.js +5 -0
- package/dist/server/routes/workspaces.js +29 -1
- package/dist/server/services/network-access-service.js +23 -1
- package/dist/server/services/pr-watcher-service.js +15 -1
- package/dist/server/services/settings-service.js +16 -0
- package/dist/server/services/workspace-service.js +26 -0
- package/package.json +1 -1
- package/src/client/dist/spa/assets/{ActivityFeed-CFtA0ESZ.js → ActivityFeed-9SMCiAn6.js} +1 -1
- package/src/client/dist/spa/assets/{ChangelogPage-BRRQ3rbp.js → ChangelogPage-V-wG4ROg.js} +1 -1
- package/src/client/dist/spa/assets/{ClosePopup-C6lH1yCG.js → ClosePopup-BOISqscq.js} +1 -1
- package/src/client/dist/spa/assets/{CreatePage-BTCe-DOl.js → CreatePage-Dg_sW17N.js} +1 -1
- package/src/client/dist/spa/assets/{DiffViewer-4tJkKsps.js → DiffViewer-BiVY7uho.js} +3 -3
- package/src/client/dist/spa/assets/{HealthPage-BkEv-aMq.js → HealthPage-Bu18TAZd.js} +1 -1
- package/src/client/dist/spa/assets/{MainLayout-DXz5Vnxf.css → MainLayout-7nwhu8UE.css} +1 -1
- package/src/client/dist/spa/assets/{MainLayout-Bf9oF2M-.js → MainLayout-DCLtuMGJ.js} +3 -3
- package/src/client/dist/spa/assets/{QBtnToggle-xCWfa0zI.js → QBtnToggle-BEgY0AkW.js} +1 -1
- package/src/client/dist/spa/assets/{QChip-BdkOPqy5.js → QChip-Ccf5FEQu.js} +1 -1
- package/src/client/dist/spa/assets/{QExpansionItem-BDyoC1Ly.js → QExpansionItem-CYcOrwbm.js} +1 -1
- package/src/client/dist/spa/assets/{QScrollArea-DeI8xL_d.js → QScrollArea-BYYLivp9.js} +1 -1
- package/src/client/dist/spa/assets/{QSelect-DxY4RU7V.js → QSelect-DJgkh8M3.js} +1 -1
- package/src/client/dist/spa/assets/{QTooltip-Cpm_IfVm.js → QTooltip-epbJipNF.js} +1 -1
- package/src/client/dist/spa/assets/{SearchPage-eh-XyEGg.js → SearchPage-pREfSfc6.js} +1 -1
- package/src/client/dist/spa/assets/SettingsPage-DLBFaoj3.js +16 -0
- package/src/client/dist/spa/assets/SettingsPage-DR5mOiX3.css +1 -0
- package/src/client/dist/spa/assets/{TouchPan-DHAMpPA1.js → TouchPan-DkFNDIAU.js} +1 -1
- package/src/client/dist/spa/assets/WorkspacePage-DlN_zJvE.js +4 -0
- package/src/client/dist/spa/assets/{WorkspacePage-DauW-aqm.css → WorkspacePage-axYxoa9m.css} +1 -1
- package/src/client/dist/spa/assets/{build-path-tree-JfzwoWFk.js → build-path-tree-Ol62y1Kn.js} +1 -1
- package/src/client/dist/spa/assets/{cssMode-CqkmkxoC.js → cssMode-B6O6JP-b.js} +1 -1
- package/src/client/dist/spa/assets/{documents-DM1f62Ca.js → documents-XYso3qnK.js} +1 -1
- package/src/client/dist/spa/assets/{editor.api2-IJMSUmRN.js → editor.api2-DXnjOqbp.js} +1 -1
- package/src/client/dist/spa/assets/{editor.main-CR76sugj.js → editor.main-0W7zX41H.js} +2 -2
- package/src/client/dist/spa/assets/{expand-template-lTTAWhou.js → expand-template-BsmF6e32.js} +1 -1
- package/src/client/dist/spa/assets/{formatters-_8dkjSkO.js → formatters-DB4LxyaP.js} +1 -1
- package/src/client/dist/spa/assets/{freemarker2-DXRiOLBf.js → freemarker2-DMoM0_gk.js} +1 -1
- package/src/client/dist/spa/assets/{handlebars-D0LypT-N.js → handlebars-Da81JqAH.js} +1 -1
- package/src/client/dist/spa/assets/{html-DmKSVUQI.js → html-CaX0PPST.js} +1 -1
- package/src/client/dist/spa/assets/{htmlMode-D63dd2k1.js → htmlMode-vYUYLNhw.js} +1 -1
- package/src/client/dist/spa/assets/i18n-CIIGUi3c.js +1 -0
- package/src/client/dist/spa/assets/{index-DODmyTEl.js → index-02IPrCWM.js} +7 -7
- package/src/client/dist/spa/assets/{javascript-BAUCdi7S.js → javascript-KVXsoiIo.js} +1 -1
- package/src/client/dist/spa/assets/{jsonMode-COygYAf4.js → jsonMode-DxQZuUA4.js} +1 -1
- package/src/client/dist/spa/assets/{kobo-commands-DRr54Gj1.js → kobo-commands-DpqDgjYQ.js} +1 -1
- package/src/client/dist/spa/assets/{layout-CvuA9F6q.js → layout-0RUyV_n-.js} +1 -1
- package/src/client/dist/spa/assets/{liquid-oq8bpzTN.js → liquid-ezLYma6x.js} +1 -1
- package/src/client/dist/spa/assets/{lspLanguageFeatures-CVL-3CRs.js → lspLanguageFeatures-B_BCv0M4.js} +1 -1
- package/src/client/dist/spa/assets/{mdx-Byp34ebl.js → mdx-BatnpHIx.js} +1 -1
- package/src/client/dist/spa/assets/{monaco.contribution-D2h-fJiD.js → monaco.contribution-Dkhpc3_y.js} +2 -2
- package/src/client/dist/spa/assets/{network-auth-DfISpE97.js → network-auth-CRzlXaPk.js} +1 -1
- package/src/client/dist/spa/assets/{project-color-Cvt0AAeh.js → project-color-CubSkld3.js} +1 -1
- package/src/client/dist/spa/assets/{python-D-1c5J5l.js → python-Bj1W8loP.js} +1 -1
- package/src/client/dist/spa/assets/{razor-CPeWkxpV.js → razor-CuJR7SS8.js} +1 -1
- package/src/client/dist/spa/assets/{render-chat-markdown-DbKsA_Ux.js → render-chat-markdown-OO8yJF8P.js} +1 -1
- package/src/client/dist/spa/assets/{tsMode-BFEzVMJt.js → tsMode-CkPJHNND.js} +1 -1
- package/src/client/dist/spa/assets/{typescript-C-84YsEc.js → typescript-snHlQcwB.js} +1 -1
- package/src/client/dist/spa/assets/{use-onboarding-Bxi9kF5f.js → use-onboarding-DXKr7HBO.js} +1 -1
- package/src/client/dist/spa/assets/{use-quasar-B20UL17o.js → use-quasar-CwG_Rs2g.js} +1 -1
- package/src/client/dist/spa/assets/{workers-B5wOtN6Y.js → workers-BK0CNSbu.js} +1 -1
- package/src/client/dist/spa/assets/{xml-BjPqYcxj.js → xml-B40Ya2Q2.js} +1 -1
- package/src/client/dist/spa/assets/{yaml-lZDMbDzQ.js → yaml-DAP0EIwM.js} +1 -1
- package/src/client/dist/spa/index.html +1 -1
- package/src/client/dist/spa/assets/SettingsPage-DTd5pM5A.js +0 -16
- package/src/client/dist/spa/assets/SettingsPage-DfYhuzv0.css +0 -1
- package/src/client/dist/spa/assets/WorkspacePage-Cdq798Xz.js +0 -4
- package/src/client/dist/spa/assets/i18n-DIxccx-f.js +0 -1
package/AGENTS.md
CHANGED
|
@@ -100,7 +100,7 @@ src/
|
|
|
100
100
|
|
|
101
101
|
| Table | Purpose |
|
|
102
102
|
|---|---|
|
|
103
|
-
| `workspaces` | the unit of work: id, name, project_path, source_branch, working_branch, status, notion_url, model, dev_server_status, `archived_at`, `worktree_purged_at`, `worktree_purge_restore_data` (JSON), `auto_loop`, `auto_loop_ready`, `no_progress_streak`, timestamps |
|
|
103
|
+
| `workspaces` | the unit of work: id, name, project_path, source_branch, working_branch, status, notion_url, model, `brainstorm_model`, dev_server_status, `archived_at`, `worktree_purged_at`, `worktree_purge_restore_data` (JSON), `auto_loop`, `auto_loop_ready`, `auto_loop_session_mode`, `no_progress_streak`, timestamps |
|
|
104
104
|
| `tasks` | workspace sub-items: title, status, `is_acceptance_criterion`, sort_order; CASCADE DELETE on workspace |
|
|
105
105
|
| `agent_sessions` | Claude Code CLI invocations: pid, `claude_session_id`, status, started_at, ended_at, `name` |
|
|
106
106
|
| `ws_events` | persisted WebSocket events for replay on reconnect: type, payload, session_id, created_at |
|
|
@@ -115,6 +115,8 @@ src/
|
|
|
115
115
|
|
|
116
116
|
`auto_loop` (bool, default 0), `auto_loop_ready` (bool, default 0) and `no_progress_streak` (int, default 0) drive the auto-loop feature: when `auto_loop=1`, `session:ended` triggers `auto-loop-service.onSessionEnded` which either spawns the next iteration via a fresh `startAgent(resume=false)`, disables with `reason='completed'` (no pending tasks), or disables with `reason='stall'` (3 consecutive sessions without a task completed). Archive + delete both auto-disable.
|
|
117
117
|
|
|
118
|
+
`brainstorm_model` (nullable, set only at creation) lets a workspace created with `auto_loop=1` run its initial brainstorming session on a different model than the auto-loop iterations that follow, while staying on the same engine. `POST /api/workspaces` uses it for the very first `startAgent` call only; every subsequent auto-loop iteration (`auto-loop-service.ts`'s `spawnNextIteration`) always reads `model`, unchanged. The switch to `model` takes effect once that first live session ends naturally — not at the `[BRAINSTORM_COMPLETE]` marker, since the same session keeps running under `brainstorm_model` until it stops on its own.
|
|
119
|
+
|
|
118
120
|
## Database migrations
|
|
119
121
|
|
|
120
122
|
**The project is in production**. Every schema change MUST ship as an incremental migration that preserves existing data. Never drop-and-recreate, never rely on `initSchema` alone to patch running databases.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,10 +4,21 @@ All notable changes to Kōbō are documented here. The format is based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/). Each release is an `## <version>`
|
|
5
5
|
section — the in-app "What's new" dialog reads this file.
|
|
6
6
|
|
|
7
|
+
## 1.9.0
|
|
8
|
+
|
|
9
|
+
- feat: opt out a workspace from PR-watch (skip forge polling, keep local git stats)
|
|
10
|
+
- feat: official Docker image, with an example Traefik reverse-proxy stack
|
|
11
|
+
- feat: reverse-proxy-safe auth mode + env-var network-access bootstrap
|
|
12
|
+
- feat: workspace toolbar polish (aligned model badges, copy engine session ID)
|
|
13
|
+
- docs: document reverse-proxy mode, Docker deployment, and Codex maturity
|
|
14
|
+
|
|
15
|
+
## 1.8.9
|
|
16
|
+
|
|
17
|
+
- docs: sync README/AGENTS.md with recent changes, dedupe CHANGELOG
|
|
18
|
+
|
|
7
19
|
## 1.8.8
|
|
8
20
|
|
|
9
21
|
- fix: resolve npm audit findings and scope client audit to prod deps
|
|
10
|
-
- feat: add auto-loop brainstorming model override and Claude Opus 5
|
|
11
22
|
|
|
12
23
|
## 1.8.7
|
|
13
24
|
|
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ Kōbō runs multiple coding agents in parallel, each isolated in its own git wor
|
|
|
29
29
|
- **Interactive Q&A**: an agent can pause mid-session to ask a clarifying question through the UI; the workspace surfaces under "Needs Attention" until you answer.
|
|
30
30
|
|
|
31
31
|

|
|
32
|
-
- **Auto-loop**: an opt-in mode that walks the task list, spawning a fresh session per task and stopping once there's nothing left to do, progress stalls, an error occurs, or the agent needs input from you.
|
|
32
|
+
- **Auto-loop**: an opt-in mode that walks the task list, spawning a fresh session per task and stopping once there's nothing left to do, progress stalls, an error occurs, or the agent needs input from you. Optionally run the initial brainstorming session on a stronger model and every task after that on a cheaper one, without leaving the engine you picked.
|
|
33
33
|
- **Quota-aware**: 5-hour / 7-day Claude usage and Codex rate-limit buckets sit in the footer, and sessions auto-resume after a rate-limit reset.
|
|
34
34
|
- **Scheduled wakeups**: the agent schedules a one-shot wake-up via the `schedule_wakeup` MCP tool. Kōbō persists it across restarts, shows a live countdown, and re-invokes the agent with the stored prompt at the chosen time.
|
|
35
35
|
- **Cron schedules**: recurring per-workspace triggers the agent registers through MCP tools (`cron_create` / `cron_delete` / `cron_list`). Each tick resumes the workspace session (skipped if already active), and schedules are re-armed at boot with skip-missed semantics.
|
|
@@ -55,6 +55,16 @@ Open <http://localhost:3000> (or whichever port you picked). Data is persisted u
|
|
|
55
55
|
|
|
56
56
|
Want to run from source or contribute? See [`CONTRIBUTING.md`](./CONTRIBUTING.md).
|
|
57
57
|
|
|
58
|
+
### Docker
|
|
59
|
+
|
|
60
|
+
An official `Dockerfile` and an example Traefik + Kōbō stack
|
|
61
|
+
([`docker-compose.example.yml`](./docker-compose.example.yml)) ship in this repository — useful for
|
|
62
|
+
running Kōbō on a VPS behind a reverse proxy, with git SSH auth, Claude Code / Codex credentials,
|
|
63
|
+
optional Docker-socket passthrough for the dev-server panel, and SSH access into the container for
|
|
64
|
+
interactive work. See [`CONFIGURATION.md`](./CONFIGURATION.md#behind-a-reverse-proxy) for the full
|
|
65
|
+
setup, including the `KOBO_NETWORK_ACCESS_ENABLED` / `KOBO_NETWORK_ACCESS_BEHIND_PROXY` env vars
|
|
66
|
+
that bootstrap network access at container boot with no manual step.
|
|
67
|
+
|
|
58
68
|
## Configuration
|
|
59
69
|
|
|
60
70
|
The most common knobs:
|
|
@@ -75,7 +85,7 @@ The full reference (every env var, every setting key, MCP server registration, N
|
|
|
75
85
|
## Agent runtimes
|
|
76
86
|
|
|
77
87
|
- **Claude Code.** Authenticate once with `claude /login`. Kōbō calls the embedded SDK directly, so no `claude` binary is required at runtime.
|
|
78
|
-
- **OpenAI Codex
|
|
88
|
+
- **OpenAI Codex.** Run `codex login` or export `OPENAI_API_KEY`. Kōbō spawns a long-lived `codex app-server` subprocess per workspace and bridges its JSON-RPC stream to the same UI.
|
|
79
89
|
|
|
80
90
|
You pick the engine at workspace creation. Both share the same task tracking, permission modes, sub-agent panel, and quota footer. The mapping of Kōbō's four permission modes (`plan` / `bypass` / `strict` / `interactive`) to each engine's native sandbox + approval semantics is in [`CONFIGURATION.md`](./CONFIGURATION.md#permission-modes).
|
|
81
91
|
|
|
@@ -389,6 +389,24 @@ export const migrations = [
|
|
|
389
389
|
}
|
|
390
390
|
},
|
|
391
391
|
},
|
|
392
|
+
{
|
|
393
|
+
version: 30,
|
|
394
|
+
name: 'add-pr-watch-disabled',
|
|
395
|
+
migrate: (db) => {
|
|
396
|
+
// When set, the PR watcher skips the forge (gh/glab) call for this
|
|
397
|
+
// workspace every tick — no PR-status fetch, no auto-archive-on-merge,
|
|
398
|
+
// no auto-purge, no PR-derived attention badges. Local git stats
|
|
399
|
+
// (ahead/behind, changed files, rebase status) keep updating every
|
|
400
|
+
// tick regardless — see pr-watcher-service.ts's checkPrStatuses().
|
|
401
|
+
const table = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='workspaces'").get();
|
|
402
|
+
if (!table)
|
|
403
|
+
return;
|
|
404
|
+
const cols = db.prepare('PRAGMA table_info(workspaces)').all();
|
|
405
|
+
if (!cols.some((c) => c.name === 'pr_watch_disabled_at')) {
|
|
406
|
+
db.prepare('ALTER TABLE workspaces ADD COLUMN pr_watch_disabled_at TEXT').run();
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
},
|
|
392
410
|
];
|
|
393
411
|
/** Current schema version — always equals the highest migration version. */
|
|
394
412
|
export const SCHEMA_VERSION = migrations.length > 0 ? migrations[migrations.length - 1].version : 1;
|
package/dist/server/db/schema.js
CHANGED
|
@@ -21,6 +21,7 @@ export function initSchema(db) {
|
|
|
21
21
|
has_unread INTEGER NOT NULL DEFAULT 0,
|
|
22
22
|
archived_at TEXT,
|
|
23
23
|
favorited_at TEXT,
|
|
24
|
+
pr_watch_disabled_at TEXT,
|
|
24
25
|
tags TEXT NOT NULL DEFAULT '[]',
|
|
25
26
|
engine TEXT NOT NULL DEFAULT 'claude-code',
|
|
26
27
|
auto_loop INTEGER NOT NULL DEFAULT 0,
|
package/dist/server/index.js
CHANGED
|
@@ -31,10 +31,10 @@ import { runContentMigrationIfNeeded } from './services/content-migration-servic
|
|
|
31
31
|
import * as cronService from './services/cron-service.js';
|
|
32
32
|
import { createDailyDbBackupIfNeeded, createPreMigrationBackup } from './services/db-backup-service.js';
|
|
33
33
|
import { startDevServer, stopDevServer } from './services/dev-server-service.js';
|
|
34
|
-
import { authorizeWsUpgrade, getLanUrls, resolveBindHost } from './services/network-access-service.js';
|
|
34
|
+
import { authorizeWsUpgrade, generateToken, getLanUrls, resolveBindHost, resolveNetworkAccessEnvOverrides, } from './services/network-access-service.js';
|
|
35
35
|
import { startPrWatcher, stopPrWatcher } from './services/pr-watcher-service.js';
|
|
36
36
|
import * as quotaBackoffService from './services/quota-backoff-service.js';
|
|
37
|
-
import { getGlobalSettings } from './services/settings-service.js';
|
|
37
|
+
import { getGlobalSettings, updateNetworkAccessSettings } from './services/settings-service.js';
|
|
38
38
|
import { reloadDefaultTemplates } from './services/templates-service.js';
|
|
39
39
|
import { createTerminal, destroyAllTerminals, getTerminal } from './services/terminal-service.js';
|
|
40
40
|
import { startUsagePoller, stopUsagePoller } from './services/usage/index.js';
|
|
@@ -165,6 +165,16 @@ if (clientDistPath) {
|
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
// Create HTTP server via @hono/node-server
|
|
168
|
+
const networkAccessEnvOverrides = resolveNetworkAccessEnvOverrides(process.env);
|
|
169
|
+
if (Object.keys(networkAccessEnvOverrides).length > 0) {
|
|
170
|
+
const patch = {
|
|
171
|
+
...networkAccessEnvOverrides,
|
|
172
|
+
};
|
|
173
|
+
if (networkAccessEnvOverrides.networkAccessEnabled && !getGlobalSettings().networkAccessToken) {
|
|
174
|
+
patch.networkAccessToken = generateToken();
|
|
175
|
+
}
|
|
176
|
+
updateNetworkAccessSettings(patch);
|
|
177
|
+
}
|
|
168
178
|
const bindHost = resolveBindHost(getGlobalSettings().networkAccessEnabled);
|
|
169
179
|
const server = serve({
|
|
170
180
|
fetch: app.fetch,
|
|
@@ -176,6 +186,7 @@ const server = serve({
|
|
|
176
186
|
console.log(`Server running — network access ON (port ${info.port})`);
|
|
177
187
|
for (const url of getLanUrls(info.port))
|
|
178
188
|
console.log(` LAN: ${url}`);
|
|
189
|
+
console.log(` Token: ${getGlobalSettings().networkAccessToken}`);
|
|
179
190
|
}
|
|
180
191
|
else {
|
|
181
192
|
console.log(`Server running at http://localhost:${info.port} (localhost only)`);
|
|
@@ -392,6 +403,7 @@ server.on('upgrade', (request, socket, head) => {
|
|
|
392
403
|
rawUrl: request.url,
|
|
393
404
|
enabled: wsGlobal.networkAccessEnabled,
|
|
394
405
|
expectedToken: wsGlobal.networkAccessToken,
|
|
406
|
+
trustLoopback: !wsGlobal.networkAccessBehindProxy,
|
|
395
407
|
})) {
|
|
396
408
|
console.warn(`[network-auth] WS 401 (missing/invalid token) from ${request.socket.remoteAddress ?? 'unknown'} ${pathname}`);
|
|
397
409
|
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
|
|
@@ -4,7 +4,9 @@ import { getGlobalSettings } from '../services/settings-service.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Gates non-loopback requests behind the network-access token.
|
|
6
6
|
*
|
|
7
|
-
* Loopback requests
|
|
7
|
+
* Loopback requests pass without a token (the host machine's own usage is
|
|
8
|
+
* frictionless) — unless `networkAccessBehindProxy` is enabled, in which case
|
|
9
|
+
* loopback is treated like any other address (see network-access-service.ts).
|
|
8
10
|
* The client IP comes only from the OS socket via getConnInfo, never from
|
|
9
11
|
* X-Forwarded-For, so a remote client cannot spoof a loopback address.
|
|
10
12
|
*/
|
|
@@ -16,6 +18,7 @@ export const networkAuthMiddleware = async (c, next) => {
|
|
|
16
18
|
enabled: global.networkAccessEnabled,
|
|
17
19
|
expectedToken: global.networkAccessToken,
|
|
18
20
|
providedToken: c.req.header('X-Kobo-Token'),
|
|
21
|
+
trustLoopback: !global.networkAccessBehindProxy,
|
|
19
22
|
});
|
|
20
23
|
if (decision.allow)
|
|
21
24
|
return next();
|
|
@@ -54,6 +54,7 @@ app.get('/network', (c) => {
|
|
|
54
54
|
return c.json({
|
|
55
55
|
enabled: global.networkAccessEnabled,
|
|
56
56
|
token: global.networkAccessToken,
|
|
57
|
+
behindProxy: global.networkAccessBehindProxy,
|
|
57
58
|
urls: getLanUrls(getBackendPort()),
|
|
58
59
|
});
|
|
59
60
|
}
|
|
@@ -81,10 +82,14 @@ app.post('/network', async (c) => {
|
|
|
81
82
|
if (body.regenerate) {
|
|
82
83
|
patch.networkAccessToken = generateToken();
|
|
83
84
|
}
|
|
85
|
+
if (typeof body.behindProxy === 'boolean' && body.behindProxy !== current.networkAccessBehindProxy) {
|
|
86
|
+
patch.networkAccessBehindProxy = body.behindProxy;
|
|
87
|
+
}
|
|
84
88
|
const updated = settingsService.updateNetworkAccessSettings(patch);
|
|
85
89
|
return c.json({
|
|
86
90
|
enabled: updated.networkAccessEnabled,
|
|
87
91
|
token: updated.networkAccessToken,
|
|
92
|
+
behindProxy: updated.networkAccessBehindProxy,
|
|
88
93
|
urls: getLanUrls(getBackendPort()),
|
|
89
94
|
restartRequired,
|
|
90
95
|
});
|
|
@@ -24,7 +24,7 @@ import { computeGitStats } from '../services/git-stats-service.js';
|
|
|
24
24
|
import { DEFAULT_NOTION_INITIAL_PROMPT, DEFAULT_SENTRY_INITIAL_PROMPT, renderNotionInitialPrompt, renderSentryInitialPrompt, } from '../services/initial-prompt-template-service.js';
|
|
25
25
|
import * as notionService from '../services/notion-service.js';
|
|
26
26
|
import { renderPrTemplate } from '../services/pr-template-service.js';
|
|
27
|
-
import { getAllGitStats, getAllPrSnapshots, refreshPrSnapshot } from '../services/pr-watcher-service.js';
|
|
27
|
+
import { clearPrSnapshotCache, getAllGitStats, getAllPrSnapshots, refreshPrSnapshot, } from '../services/pr-watcher-service.js';
|
|
28
28
|
import * as quotaBackoffService from '../services/quota-backoff-service.js';
|
|
29
29
|
import { getActiveReviewTemplate, renderReviewTemplate } from '../services/review-template-service.js';
|
|
30
30
|
import * as sentryService from '../services/sentry-service.js';
|
|
@@ -1686,6 +1686,34 @@ app.delete('/:id/favorite', (c) => {
|
|
|
1686
1686
|
return c.json({ error: msg }, status);
|
|
1687
1687
|
}
|
|
1688
1688
|
});
|
|
1689
|
+
// POST /api/workspaces/:id/pr-watch-disabled — skip PR-watcher forge polling for this workspace
|
|
1690
|
+
app.post('/:id/pr-watch-disabled', (c) => {
|
|
1691
|
+
const { id } = c.req.param();
|
|
1692
|
+
try {
|
|
1693
|
+
const ws = workspaceService.setPrWatchDisabled(id);
|
|
1694
|
+
clearPrSnapshotCache(id);
|
|
1695
|
+
return c.json(ws);
|
|
1696
|
+
}
|
|
1697
|
+
catch (err) {
|
|
1698
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
1699
|
+
const status = msg.includes('not found') ? 404 : 500;
|
|
1700
|
+
return c.json({ error: msg }, status);
|
|
1701
|
+
}
|
|
1702
|
+
});
|
|
1703
|
+
// DELETE /api/workspaces/:id/pr-watch-disabled — resume PR-watcher forge polling, refresh immediately
|
|
1704
|
+
app.delete('/:id/pr-watch-disabled', async (c) => {
|
|
1705
|
+
const { id } = c.req.param();
|
|
1706
|
+
try {
|
|
1707
|
+
const ws = workspaceService.setPrWatchEnabled(id);
|
|
1708
|
+
const prSnapshot = await refreshPrSnapshot(id).catch(() => null);
|
|
1709
|
+
return c.json({ workspace: ws, prSnapshot });
|
|
1710
|
+
}
|
|
1711
|
+
catch (err) {
|
|
1712
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
1713
|
+
const status = msg.includes('not found') ? 404 : 500;
|
|
1714
|
+
return c.json({ error: msg }, status);
|
|
1715
|
+
}
|
|
1716
|
+
});
|
|
1689
1717
|
// PUT /api/workspaces/:id/tags — replace the workspace's tag list
|
|
1690
1718
|
app.put('/:id/tags', async (c) => {
|
|
1691
1719
|
const { id } = c.req.param();
|
|
@@ -41,7 +41,8 @@ export function tokenMatches(provided, expected) {
|
|
|
41
41
|
}
|
|
42
42
|
/** Core gate decision shared by the HTTP middleware and the WS upgrade guard. */
|
|
43
43
|
export function evaluateNetworkAccess(params) {
|
|
44
|
-
|
|
44
|
+
const trustLoopback = params.trustLoopback ?? true;
|
|
45
|
+
if (trustLoopback && isLoopbackAddress(params.address))
|
|
45
46
|
return { allow: true, status: 200 };
|
|
46
47
|
if (!params.enabled)
|
|
47
48
|
return { allow: false, status: 403 };
|
|
@@ -63,5 +64,26 @@ export function authorizeWsUpgrade(params) {
|
|
|
63
64
|
enabled: params.enabled,
|
|
64
65
|
expectedToken: params.expectedToken,
|
|
65
66
|
providedToken,
|
|
67
|
+
trustLoopback: params.trustLoopback,
|
|
66
68
|
}).allow;
|
|
67
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Reads KOBO_NETWORK_ACCESS_ENABLED / KOBO_NETWORK_ACCESS_BEHIND_PROXY and
|
|
72
|
+
* returns only the fields an env var actually specifies — an unset env var
|
|
73
|
+
* means "leave current settings alone" (key omitted from the result); a SET
|
|
74
|
+
* env var always produces a decisive true/false, even for a value that isn't
|
|
75
|
+
* literally "true"/"1" (an explicit non-true value is a deliberate "off",
|
|
76
|
+
* not "don't touch"). Re-applied on every server boot — see index.ts.
|
|
77
|
+
*/
|
|
78
|
+
export function resolveNetworkAccessEnvOverrides(env) {
|
|
79
|
+
const overrides = {};
|
|
80
|
+
if (env.KOBO_NETWORK_ACCESS_ENABLED !== undefined) {
|
|
81
|
+
overrides.networkAccessEnabled =
|
|
82
|
+
env.KOBO_NETWORK_ACCESS_ENABLED === 'true' || env.KOBO_NETWORK_ACCESS_ENABLED === '1';
|
|
83
|
+
}
|
|
84
|
+
if (env.KOBO_NETWORK_ACCESS_BEHIND_PROXY !== undefined) {
|
|
85
|
+
overrides.networkAccessBehindProxy =
|
|
86
|
+
env.KOBO_NETWORK_ACCESS_BEHIND_PROXY === 'true' || env.KOBO_NETWORK_ACCESS_BEHIND_PROXY === '1';
|
|
87
|
+
}
|
|
88
|
+
return overrides;
|
|
89
|
+
}
|
|
@@ -45,6 +45,13 @@ export function getAllGitStats() {
|
|
|
45
45
|
}
|
|
46
46
|
return out;
|
|
47
47
|
}
|
|
48
|
+
/** Drops a single workspace's cached PR snapshot — called when PR-watch is
|
|
49
|
+
* disabled for it, so a stale "Ready to merge"-style badge doesn't linger
|
|
50
|
+
* after the toggle (the watcher loop skips, rather than clears, a disabled
|
|
51
|
+
* workspace's entry, so this must be done explicitly by the caller). */
|
|
52
|
+
export function clearPrSnapshotCache(workspaceId) {
|
|
53
|
+
lastKnownPr.delete(workspaceId);
|
|
54
|
+
}
|
|
48
55
|
/**
|
|
49
56
|
* Test-only escape hatch — drops the in-memory cache so each test starts
|
|
50
57
|
* from a clean slate. Not part of the public API.
|
|
@@ -109,7 +116,14 @@ export async function checkPrStatuses() {
|
|
|
109
116
|
if (!fs.existsSync(ws.worktreePath))
|
|
110
117
|
continue;
|
|
111
118
|
try {
|
|
112
|
-
|
|
119
|
+
// Opt-out: skip the forge call entirely for a workspace with PR-watch
|
|
120
|
+
// disabled — no PR-status fetch, no auto-archive/purge, no PR-derived
|
|
121
|
+
// badges. Git stats (below) still run every tick regardless; the
|
|
122
|
+
// existing `if (!pr) continue` further down already handles a null
|
|
123
|
+
// `pr` correctly (same path taken by a workspace with no PR yet).
|
|
124
|
+
const pr = ws.prWatchDisabledAt
|
|
125
|
+
? null
|
|
126
|
+
: await getForgeProvider(resolveForge(ws.projectPath)).getPrStatus(ws.worktreePath, ws.workingBranch);
|
|
113
127
|
// Detect a PR base change BEFORE computing git stats so the new base
|
|
114
128
|
// is used in commitCount / behindCount / diffStats. Otherwise the
|
|
115
129
|
// user keeps seeing stale ahead/behind counts vs the OLD base until
|
|
@@ -654,6 +654,18 @@ const settingsMigrations = [
|
|
|
654
654
|
}
|
|
655
655
|
},
|
|
656
656
|
},
|
|
657
|
+
{
|
|
658
|
+
version: 41,
|
|
659
|
+
name: 'add-network-access-behind-proxy',
|
|
660
|
+
migrate: ({ global }) => {
|
|
661
|
+
// Disables the loopback-trust bypass when true — every request needs
|
|
662
|
+
// the token, even ones that look like they came from 127.0.0.1. Only
|
|
663
|
+
// meaningful when networkAccessEnabled is also true.
|
|
664
|
+
if (typeof global.networkAccessBehindProxy !== 'boolean') {
|
|
665
|
+
global.networkAccessBehindProxy = false;
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
},
|
|
657
669
|
];
|
|
658
670
|
/** Current settings schema version — always equals the highest migration version. */
|
|
659
671
|
export const SETTINGS_SCHEMA_VERSION = settingsMigrations.length > 0 ? settingsMigrations[settingsMigrations.length - 1].version : 0;
|
|
@@ -702,6 +714,7 @@ function defaultSettings() {
|
|
|
702
714
|
autoPurgeOnPrMerged: false,
|
|
703
715
|
networkAccessEnabled: false,
|
|
704
716
|
networkAccessToken: '',
|
|
717
|
+
networkAccessBehindProxy: false,
|
|
705
718
|
browserNotifications: true,
|
|
706
719
|
audioNotifications: true,
|
|
707
720
|
audioNotificationSound: 'hey.mp3',
|
|
@@ -1139,6 +1152,9 @@ export function updateNetworkAccessSettings(patch) {
|
|
|
1139
1152
|
if (typeof patch.networkAccessToken === 'string') {
|
|
1140
1153
|
settings.global.networkAccessToken = patch.networkAccessToken;
|
|
1141
1154
|
}
|
|
1155
|
+
if (typeof patch.networkAccessBehindProxy === 'boolean') {
|
|
1156
|
+
settings.global.networkAccessBehindProxy = patch.networkAccessBehindProxy;
|
|
1157
|
+
}
|
|
1142
1158
|
writeSettings(settings, { backup: true });
|
|
1143
1159
|
return settings.global;
|
|
1144
1160
|
}
|
|
@@ -54,6 +54,7 @@ function mapWorkspace(row) {
|
|
|
54
54
|
hasUnread: row.has_unread === 1,
|
|
55
55
|
archivedAt: row.archived_at,
|
|
56
56
|
favoritedAt: row.favorited_at,
|
|
57
|
+
prWatchDisabledAt: row.pr_watch_disabled_at,
|
|
57
58
|
tags: parseTags(row.tags),
|
|
58
59
|
description: row.description,
|
|
59
60
|
agentDescription: row.agent_description,
|
|
@@ -599,6 +600,31 @@ export function unsetFavorite(id) {
|
|
|
599
600
|
}
|
|
600
601
|
return getWorkspace(id);
|
|
601
602
|
}
|
|
603
|
+
/** Skip the PR watcher's forge (gh/glab) call for this workspace every tick — no PR-status fetch,
|
|
604
|
+
* no auto-archive-on-merge, no auto-purge. Local git stats keep updating regardless. */
|
|
605
|
+
export function setPrWatchDisabled(id) {
|
|
606
|
+
const db = getDb();
|
|
607
|
+
const now = new Date().toISOString();
|
|
608
|
+
const result = db
|
|
609
|
+
.prepare('UPDATE workspaces SET pr_watch_disabled_at = ?, updated_at = ? WHERE id = ?')
|
|
610
|
+
.run(now, now, id);
|
|
611
|
+
if (result.changes === 0) {
|
|
612
|
+
throw new Error(`Workspace '${id}' not found`);
|
|
613
|
+
}
|
|
614
|
+
return getWorkspace(id);
|
|
615
|
+
}
|
|
616
|
+
/** Resume PR-watcher forge polling for this workspace. */
|
|
617
|
+
export function setPrWatchEnabled(id) {
|
|
618
|
+
const db = getDb();
|
|
619
|
+
const now = new Date().toISOString();
|
|
620
|
+
const result = db
|
|
621
|
+
.prepare('UPDATE workspaces SET pr_watch_disabled_at = NULL, updated_at = ? WHERE id = ?')
|
|
622
|
+
.run(now, id);
|
|
623
|
+
if (result.changes === 0) {
|
|
624
|
+
throw new Error(`Workspace '${id}' not found`);
|
|
625
|
+
}
|
|
626
|
+
return getWorkspace(id);
|
|
627
|
+
}
|
|
602
628
|
/** Maximum tag length (characters) and max number of tags per workspace. */
|
|
603
629
|
export const MAX_TAG_LENGTH = 50;
|
|
604
630
|
export const MAX_WORKSPACE_TAGS = 50;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loicngr/kobo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Kōbō — multi-workspace agent manager for Claude Code. Orchestrates isolated git worktrees with dev servers, Notion integration, and MCP tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{$ as e,B as t,F as n,I as r,R as i,S as a,U as o,W as s,_ as c,at as l,b as u,c as d,ct as f,g as p,h as m,it as h,k as g,m as _,n as v,p as y,s as b,st as x,y as S}from"./vue.runtime.esm-bundler-JZnIeD9D.js";import{l as C,t as w}from"./QIcon-C6E-oEjI.js";import{B as T,C as E,N as D,S as O,d as k,p as A,x as j,z as ee}from"./index-
|
|
1
|
+
import{$ as e,B as t,F as n,I as r,R as i,S as a,U as o,W as s,_ as c,at as l,b as u,c as d,ct as f,g as p,h as m,it as h,k as g,m as _,n as v,p as y,s as b,st as x,y as S}from"./vue.runtime.esm-bundler-JZnIeD9D.js";import{l as C,t as w}from"./QIcon-C6E-oEjI.js";import{B as T,C as E,N as D,S as O,d as k,p as A,x as j,z as ee}from"./index-02IPrCWM.js";import{t as te}from"./QSpinnerDots-DIV68-cV.js";import{t as M}from"./QTooltip-epbJipNF.js";import{t as N}from"./QExpansionItem-CYcOrwbm.js";import{t as ne}from"./QScrollArea-BYYLivp9.js";import{t as re}from"./documents-XYso3qnK.js";import{i as ie,n as ae,t as P}from"./render-chat-markdown-OO8yJF8P.js";import{t as F}from"./_plugin-vue_export-helper-BDNMzG2s.js";function oe(e,t,n=!0){let r=[],i=new Map,a=new Map;for(let n=0;n<e.length;n++){let o=e[n],s=t?.[n];switch(o.kind){case`message:text`:{let e=i.get(o.messageId);if(e)e.text+=o.text,e.streaming=o.streaming;else{let e={type:`text`,messageId:o.messageId,text:o.text,streaming:o.streaming,ts:s};i.set(o.messageId,e),r.push(e)}break}case`message:end`:{let e=i.get(o.messageId);e&&(e.streaming=!1);break}case`message:thinking`:r.push({type:`thinking`,messageId:o.messageId,text:o.text,ts:s});break;case`tool:call`:{let e={type:`tool`,toolCallId:o.toolCallId,name:o.name,input:o.input,ts:s};a.set(o.toolCallId,e),r.push(e);break}case`tool:result`:{let e=a.get(o.toolCallId);e&&(e.result={output:o.output,isError:o.isError});break}case`session:started`:r.push({type:`session`,kind:`started`,detail:{engineSessionId:o.engineSessionId,model:o.model},ts:s});break;case`session:ended`:r.push({type:`session`,kind:`ended`,detail:{reason:o.reason,exitCode:o.exitCode},ts:s});break;case`session:compacted`:r.push({type:`session`,kind:`compacted`,ts:s});break;case`session:compacting`:case`session:brainstorm-complete`:case`session:user-input-requested`:case`message:raw`:case`skills:discovered`:case`usage`:case`rate_limit`:case`subagent:progress`:case`error`:break;default:}}let o=null;for(let e of r)e.type===`text`&&e.streaming&&(o&&(o.streaming=!1),o=e);return o&&!n&&(o.streaming=!1),r}function se(e,t){if(t.length===0)return e;let n=t.map(e=>({type:`user`,content:e.content,sender:e.sender,ts:e.ts})),r=[...e,...n];r.sort((e,t)=>{let n=e.ts??``,r=t.ts??``;return n===r?0:n?r?n<r?-1:1:-1:1});let i;for(let e of r)e.type===`user`&&e.sender!==`system-prompt`&&e.ts&&(!i||e.ts>i)&&(i=e.ts);if(i)for(let e of r)e.type===`text`&&e.streaming&&(!e.ts||e.ts<i)&&(e.streaming=!1);return r}var I=new Set([`setup`,`cleanup`,`archive`]);function L(e){switch(e.type){case`user`:return e.sender===`system-prompt`?`system-prompt`:I.has(e.sender)?`script`:`user`;case`session`:return`session`;default:return`agent`}}function ce(e){let t=[],n=null,r=null;for(let i of e){let e=L(i),a=e===`session`||e===`system-prompt`,o=e===`script`&&i.type===`user`?`script:${i.sender}`:e;!n||r!==o||a?(n={speaker:e,ts:i.ts,items:[i]},r=o,t.push(n),a&&(n=null)):n.items.push(i)}return t}var R={class:`text-caption text-grey-6`},z=a({__name:`SessionEventItem`,props:{item:{}},setup(e){let t=e,n=y(()=>{switch(t.item.kind){case`started`:return`session.started`;case`ended`:return`session.ended`;case`compacted`:return`session.compacted`;default:return`session.started`}});return(e,t)=>(i(),c(`span`,R,f(e.$t(n.value)),1))}});function le(e,t){if(t.length===0||e.length===0)return e;let n=[...t].sort((e,t)=>t.length-e.length),r=new DOMParser().parseFromString(`<div>${e}</div>`,`text/html`),i=r.body.firstChild;if(!i)return e;function a(e){if(e.nodeType===Node.TEXT_NODE){ue(e,n,r);return}if(e.nodeName===`A`)return;let t=Array.from(e.childNodes);for(let e of t)a(e)}return a(i),i.innerHTML}function ue(e,t,n){let r=e.textContent??``;if(!t.some(e=>r.includes(e)))return;let i=n.createDocumentFragment(),a=0;for(;a<r.length;){let e=B(r,a,t);if(!e){i.appendChild(n.createTextNode(r.slice(a)));break}e.index>a&&i.appendChild(n.createTextNode(r.slice(a,e.index)));let o=n.createElement(`a`);o.className=`document-link`,o.setAttribute(`data-document-path`,e.path),o.setAttribute(`href`,`#`),o.textContent=e.path,i.appendChild(o),a=e.index+e.path.length}e.parentNode?.replaceChild(i,e)}function B(e,t,n){let r=null;for(let i of n){let n=e.indexOf(i,t);n<0||(!r||n<r.index||n===r.index&&i.length>r.path.length)&&(r={index:n,path:i})}return r}var V=[`innerHTML`],H=F(a({__name:`TextMessageItem`,props:{item:{}},setup(e){let t=e,n=re(),r=k(),a=y(()=>{let e=r.selectedWorkspaceId;return e?n.documentsFor(e).map(e=>e.path):[]}),o=y(()=>ae(le(ie.parse(t.item.text,{async:!1,breaks:!0,gfm:!0}),a.value),{addAttr:[`data-document-path`]}));function s(e){let t=e.target?.closest(`.document-link`);if(!t)return;e.preventDefault();let i=t.getAttribute(`data-document-path`),a=r.selectedWorkspaceId;!i||!a||n.openDocumentByPath(a,i)}return(t,n)=>(i(),c(`div`,{class:`markdown-message`,onClick:s},[_(`div`,{innerHTML:o.value},null,8,V),e.item.streaming?(i(),m(C,{key:0,size:`xs`,class:`q-ml-xs`})):p(``,!0)]))}}),[[`__scopeId`,`data-v-1b7bd8ca`]]),de={key:0,class:`text-caption text-grey-5`,style:{"font-style":`italic`}},U=[`innerHTML`],W={key:1,style:{"white-space":`pre-wrap`}},G=F(a({__name:`ThinkingItem`,props:{item:{}},setup(e){let t=e,n=y(()=>t.item.text.trim().slice(0,100)),r=y(()=>t.item.text.trim().length>0),a=y(()=>t.item.text.trim().length>100),o=y(()=>P(t.item.text));return(t,l)=>r.value?(i(),c(`div`,de,[a.value?(i(),m(N,{key:0,dense:``,"dense-toggle":``,label:n.value,"header-class":`text-grey-5 text-caption`,style:{"font-style":`italic`}},{default:s(()=>[_(`div`,{class:`q-py-xs markdown-thinking`,innerHTML:o.value},null,8,U)]),_:1},8,[`label`])):(i(),c(`span`,W,f(e.item.text),1))])):p(``,!0)}}),[[`__scopeId`,`data-v-7f45ed94`]]);function K(e,t){let n=e.split(`
|
|
2
2
|
`),r=t.split(`
|
|
3
3
|
`),i=n.length,a=r.length,o=Array.from({length:i+1},()=>Array(a+1).fill(0));for(let e=i-1;e>=0;e--)for(let t=a-1;t>=0;t--)n[e]===r[t]?o[e][t]=o[e+1][t+1]+1:o[e][t]=Math.max(o[e+1][t],o[e][t+1]);let s=[],c=0,l=0;for(;c<i&&l<a;)n[c]===r[l]?(s.push({type:`context`,content:n[c]}),c++,l++):o[c+1][l]>=o[c][l+1]?(s.push({type:`del`,content:n[c]}),c++):(s.push({type:`add`,content:r[l]}),l++);for(;c<i;)s.push({type:`del`,content:n[c++]});for(;l<a;)s.push({type:`add`,content:r[l++]});return s}function fe(e){let t=e.split(`
|
|
4
4
|
`),n=[];for(let e of t)e.startsWith(`@@`)||e.startsWith(`+++`)||e.startsWith(`---`)||(e.startsWith(`+`)?n.push({type:`add`,content:e.slice(1)}):e.startsWith(`-`)?n.push({type:`del`,content:e.slice(1)}):e.startsWith(` `)?n.push({type:`context`,content:e.slice(1)}):e.length>0&&n.push({type:`context`,content:e}));return n}function pe(e,t){if(!t||typeof t!=`object`)return null;let n=t;if(e===`Edit`){let e=n.file_path;if(!e)return null;let t=n.old_string??``,r=n.new_string??``,i=typeof n.diff==`string`?n.diff:``;if(!t&&!r&&i.length>0){let t=fe(i);return{toolName:`Edit`,filePath:e,additions:t.filter(e=>e.type===`add`).length,deletions:t.filter(e=>e.type===`del`).length,diffLines:t}}return{toolName:`Edit`,filePath:e,oldString:t,newString:r,replaceAll:n.replace_all??!1,additions:r?r.split(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as e,B as t,F as n,R as r,S as i,W as a,_ as o,b as s,c,ct as l,g as u,h as d,it as f,m as p}from"./vue.runtime.esm-bundler-JZnIeD9D.js";import{N as m,gt as h,mt as g,s as _}from"./index-
|
|
1
|
+
import{$ as e,B as t,F as n,R as r,S as i,W as a,_ as o,b as s,c,ct as l,g as u,h as d,it as f,m as p}from"./vue.runtime.esm-bundler-JZnIeD9D.js";import{N as m,gt as h,mt as g,s as _}from"./index-02IPrCWM.js";import{t as v}from"./render-chat-markdown-OO8yJF8P.js";import{t as y}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{t as b}from"./QSpace-ezNrZkuj.js";import{t as x}from"./QChip-Ccf5FEQu.js";import{t as S}from"./QPage-D3rjwA1l.js";var C={class:`row items-center q-mb-md`},w={class:`text-h6 q-ml-sm`},T={key:0,class:`text-grey-6 text-center q-pa-lg`},E={key:1,class:`text-negative text-center q-pa-lg`},D={key:2,class:`text-grey-6 text-center q-pa-lg`},O={key:3,class:`column q-gutter-md`},k={key:0,class:`text-caption text-grey-6`},A={class:`row items-center q-mb-sm`},j={class:`text-subtitle1 text-indigo-3`,style:{"font-family":`var(--kobo-font-mono, monospace)`}},M=[`innerHTML`],N=y(i({__name:`ChangelogPage`,setup(i){let y=_(),N=e([]),P=e(``),F=e(!1),I=e(null);function L(e){return v(e)}async function R(){F.value=!0,I.value=null;try{let e=await fetch(`/api/changelog`);if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();P.value=t.currentVersion??``,N.value=t.versions??[]}catch(e){I.value=e instanceof Error?e.message:String(e)}finally{F.value=!1}}return n(R),(e,n)=>(r(),d(S,{class:`q-pa-md`,style:{"max-width":`900px`,margin:`0 auto`}},{default:a(()=>[p(`div`,C,[s(m,{flat:``,dense:``,round:``,icon:`arrow_back`,onClick:n[0]||=e=>f(y).back()}),p(`div`,w,l(e.$t(`changelog.title`)),1),s(b),s(m,{flat:``,dense:``,icon:`refresh`,loading:F.value,label:e.$t(`common.refresh`),onClick:R},null,8,[`loading`,`label`])]),F.value&&N.value.length===0?(r(),o(`div`,T,l(e.$t(`common.loading`)),1)):I.value?(r(),o(`div`,E,l(I.value),1)):N.value.length===0?(r(),o(`div`,D,l(e.$t(`changelog.empty`)),1)):(r(),o(`div`,O,[P.value?(r(),o(`div`,k,l(e.$t(`changelog.currentVersion`,{version:P.value})),1)):u(``,!0),(r(!0),o(c,null,t(N.value,t=>(r(),d(g,{key:t.version,dark:``,flat:``,bordered:``},{default:a(()=>[s(h,null,{default:a(()=>[p(`div`,A,[p(`div`,j,` v`+l(t.version),1),t.version===P.value?(r(),d(x,{key:0,dense:``,size:`sm`,color:`indigo-7`,"text-color":`grey-2`,label:e.$t(`changelog.current`),class:`q-ml-sm`},null,8,[`label`])):u(``,!0)]),p(`div`,{class:`changelog-notes`,innerHTML:L(t.notes)},null,8,M)]),_:2},1024)]),_:2},1024))),128))]))]),_:1}))}}),[[`__scopeId`,`data-v-ed73d661`]]);export{N as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{P as e,b as t}from"./QIcon-C6E-oEjI.js";import{nt as n,rt as r}from"./index-
|
|
1
|
+
import{P as e,b as t}from"./QIcon-C6E-oEjI.js";import{nt as n,rt as r}from"./index-02IPrCWM.js";var i={left:!0,right:!0,up:!0,down:!0,horizontal:!0,vertical:!0},a=Object.keys(i);i.all=!0;function o(e){let t={};for(let n of a)e[n]&&(t[n]=!0);return Object.keys(t).length===0?i:(t.horizontal?t.left=t.right=!0:t.left&&t.right&&(t.horizontal=!0),t.vertical?t.up=t.down=!0:t.up&&t.down&&(t.vertical=!0),t.horizontal&&t.vertical&&(t.all=!0),t)}var s=[`INPUT`,`TEXTAREA`];function c(e,t){return t.event===void 0&&e.target!==void 0&&!e.target.draggable&&typeof t.handler==`function`&&!s.includes(e.target.nodeName.toUpperCase())&&(e.qClonedBy===void 0||!e.qClonedBy.includes(t.uid))}function l(e){return e===!1?0:e===!0||e===void 0?1:Number.parseInt(e,10)||0}var u=e({name:`close-popup`,beforeMount(e,{value:i}){let a={depth:l(i),handler(t){a.depth!==0&&setTimeout(()=>{let i=r(e);i!==void 0&&n(i,t,a.depth)},0)},handlerKey(e){t(e,13)&&a.handler(e)}};e.__qclosepopup=a,e.addEventListener(`click`,a.handler),e.addEventListener(`keyup`,a.handlerKey)},updated(e,{value:t,oldValue:n}){t!==n&&(e.__qclosepopup.depth=l(t))},beforeUnmount(e){let t=e.__qclosepopup;e.removeEventListener(`click`,t.handler),e.removeEventListener(`keyup`,t.handlerKey),delete e.__qclosepopup}});export{o as n,c as r,u as t};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{$ as e,B as t,F as n,I as r,O as i,R as a,S as ee,U as te,W as o,_ as s,at as ne,b as c,c as re,ct as l,g as u,h as d,it as f,k as ie,m as p,n as ae,o as oe,ot as se,p as m,s as h,w as ce,y as g}from"./vue.runtime.esm-bundler-JZnIeD9D.js";import{t as _}from"./QIcon-C6E-oEjI.js";import{t as le}from"./QSeparator-DWTCQxsa.js";import{t as v}from"./QInput-BF8x4RTv.js";import{E as ue,N as y,d as de,l as fe,s as pe,x as me,z as he}from"./index-DODmyTEl.js";import{t as ge}from"./QSpinnerDots-DIV68-cV.js";import{n as b,r as x,t as _e}from"./use-quasar-B20UL17o.js";import{l as S,t as C}from"./QSelect-DxY4RU7V.js";import{t as w}from"./QTooltip-Cpm_IfVm.js";import{t as ve}from"./QExpansionItem-BDyoC1Ly.js";import{t as ye}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{t as be}from"./QSpace-ezNrZkuj.js";import{t as xe}from"./QBtnToggle-xCWfa0zI.js";import{i as Se}from"./project-color-Cvt0AAeh.js";import{t as Ce}from"./QPage-D3rjwA1l.js";import{a as we,i as Te,n as Ee,r as De,t as Oe}from"./expand-template-lTTAWhou.js";import{i as ke,r as Ae,t as je}from"./permissionModes-6jhegAm-.js";var Me=`kobo:create-page-prefs`;function T(){try{let e=localStorage.getItem(Me);return e===null?void 0:JSON.parse(e)}catch{return}}function Ne(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Pe(){let e=T();if(!Ne(e))return{};let t={};return typeof e.projectPath==`string`&&e.projectPath.length>0&&(t.projectPath=e.projectPath),typeof e.autoLoop==`boolean`&&(t.autoLoop=e.autoLoop),(e.autoLoopSessionMode===`per_task`||e.autoLoopSessionMode===`continuous`)&&(t.autoLoopSessionMode=e.autoLoopSessionMode),typeof e.brainstormModel==`string`&&e.brainstormModel.length>0&&(t.brainstormModel=e.brainstormModel),t}function Fe(e){try{localStorage.setItem(Me,JSON.stringify(e))}catch{}}var Ie={class:`create-inner`},Le={class:`create-title text-center text-weight-bold q-mb-lg text-grey-3`},Re={class:`create-card rounded-borders`},ze={class:`card-top-bar row items-center q-px-md q-py-xs`},Be={class:`model-badge cursor-default row items-center q-gutter-xs`},Ve={class:`text-indigo-3 text-weight-medium text-caption`},He={key:0,class:`notion-url-wrap`},Ue={key:0,class:`notion-error text-caption q-px-md q-pb-xs text-red-5`},We={key:1,class:`notion-valid text-caption q-px-md q-pb-xs text-green-4`},Ge={key:2,class:`notion-peek-choice q-px-md q-pb-sm`},Ke={class:`text-caption text-grey-4 q-mb-sm`},qe={class:`row q-gutter-sm`},Je={class:`peek-card-text`},Ye={class:`peek-card-title`},Xe={class:`peek-card-desc`},Ze={class:`peek-card-text`},Qe={class:`peek-card-title`},$e={class:`peek-card-desc`},et={key:0,class:`sentry-url-wrap`},tt={key:0,class:`sentry-error text-caption q-px-md q-pb-xs text-red-5`},nt={key:1,class:`sentry-valid text-caption q-px-md q-pb-xs text-red-4`},rt={class:`card-name-wrap`},it={class:`card-textarea-wrap`},at={class:`row items-center justify-end q-px-sm q-pb-xs q-gutter-sm`},ot={key:0,class:`row items-center text-caption text-amber-6`},st={class:`manual-hint q-px-md q-py-sm text-caption text-grey-6`},ct={class:`q-pa-sm manual-section-body`},lt={class:`row items-center q-gutter-sm q-mb-sm`},ut={class:`col text-caption text-grey-4`},dt={class:`q-pa-sm manual-section-body`},ft={class:`row items-center q-gutter-sm q-mb-sm`},pt={class:`col text-caption text-grey-4`},mt={class:`card-bottom-bar`},ht={class:`row q-col-gutter-xs q-px-xs`},gt={key:0,class:`col-12 col-sm-6 col-md-3`},_t={class:`bottom-select-label row items-center no-wrap`},vt={class:`col-12 col-sm-6 col-md-3`},yt={class:`bottom-select-label row items-center no-wrap`},bt={key:0,class:`text-grey-5 q-mr-xs`},xt={class:`col-12 col-sm-6 col-md-3`},St={class:`bottom-select-label row items-center no-wrap`},Ct={class:`col-12 col-md-3`},wt={class:`bottom-select-label row items-center no-wrap`},Tt={class:`row q-col-gutter-xs q-pa-xs col-12 items-center justify-center`},Et={class:`col-12 col-md-auto`},Dt={key:0,class:`col-12 col-md-auto`},Ot={key:1,class:`col-12 col-md-auto`},kt={class:`bottom-select-label row items-center no-wrap`},At={class:`text-grey-5 q-mr-xs`},jt={class:`row q-col-gutter-xs q-pa-xs col-12 items-center justify-center`},Mt={class:`col-12 col-md-auto`},Nt={class:`col-12 col-md-auto`},Pt={class:`row q-col-gutter-xs q-px-xs bottom-row-git`},Ft={class:`col-12 col-md-4`},It={key:0,class:`col-12 col-md-4`},Lt={class:`bottom-select-label row items-center no-wrap`},Rt={key:1,class:`col-12 col-md-4`},zt={class:`bottom-select-label row items-center no-wrap`},Bt={class:`col-12 col-md-4`},Vt={class:`bottom-select-label row items-center no-wrap`},Ht={class:`row justify-center q-px-sm q-py-sm`},Ut={class:`create-hint text-center text-body2 q-mt-md text-grey-8`},Wt=6e4,E=ye(ee({__name:`CreatePage`,setup(ee){function ye(e){return e.disabled===!0}let Me=pe(),T=_e(),Ne=de(),E=me(),{t:D}=he(),Gt=e([]),Kt=e(``),O=e(``),qt=e(null),Jt=e(``),k=e(!1),A=e(!1),Yt=e(null),Xt=e(null),Zt=e([]),Qt=e(null),j=e(``),M=e(!1),N=e(`claude-opus-4-8`),P=e(`claude-opus-4-8`),F=e(`auto`),I=e(``),L=e(null),R=e(`feature`),z=e(!1),$t=m(()=>E.global.voiceEnabled),en=e([]),B=e(`claude-code`),tn=m(()=>en.value.find(e=>e.id===B.value)),nn=m(()=>en.value.map(e=>({value:e.id,label:e.displayName}))),rn=m(()=>E.global.branchPrefixes.map(e=>({label:`${e}/`,value:e}))),an=[`plan`,`bypass`,`strict`,`interactive`];function on(e,t){let n=e?E.getProjectByPath(e):void 0,r=n?.agentPermissionMode;if(typeof r==`string`&&an.includes(r))return r;let i=E.global.defaultPermissionModeByEngine?.[t];return typeof i==`string`&&an.includes(i)?i:n?.dangerouslySkipPermissions??E.global.dangerouslySkipPermissions??!0?`bypass`:t===`codex`?`plan`:`interactive`}let V=e(on(``,B.value)),sn=m(()=>{switch(V.value){case`plan`:return`visibility`;case`bypass`:return`flash_on`;case`strict`:return`lock`;case`interactive`:return`security`}}),cn=m(()=>(je[B.value]??an).map(e=>({value:e,label:D(`agentPermissionMode.${e}`),disabled:e===`plan`&&X.value}))),H=e([]),ln=e([]),un=e(!1),dn=e(!1);function fn(e,t){t(()=>{ln.value=e?H.value.filter(t=>t.toLowerCase().includes(e.toLowerCase())):H.value})}let pn=ue();function mn(){return qt.value?.nativeEl??null}let{showSkills:hn,selectedSkillIndex:U,groupedDropdown:gn,flatDropdown:W,fetchSkills:_n,detectSlashFragment:vn,replaceFragmentWith:yn,closeDropdown:bn}=Te(O,mn,{excludeKoboCommands:!0});_n(),te(O,async()=>{await ie(),await vn()});function xn(e){if(e.type===`template`){let t=pn.templates.find(t=>t.slug===e.name);if(!t)return;yn(Ee(t.content,Oe({workspace:null,gitStats:null,sessionName:null}))),bn();return}yn(`/${e.name} `),bn()}function Sn(e){!hn.value||W.value.length===0||(e.key===`ArrowDown`?(e.preventDefault(),U.value=(U.value+1)%W.value.length):e.key===`ArrowUp`?(e.preventDefault(),U.value=(U.value-1+W.value.length)%W.value.length):e.key===`Enter`&&!e.shiftKey&&!e.ctrlKey&&!e.metaKey?(e.preventDefault(),xn(W.value[U.value])):e.key===`Escape`&&(e.preventDefault(),bn()))}async function Cn(){if(!(!$t.value||k.value||A.value)){if(!navigator.mediaDevices?.getUserMedia||typeof MediaRecorder>`u`){T.notify({type:`warning`,message:D(`voice.notSupported`),position:`top`,timeout:4e3});return}try{let e=await navigator.mediaDevices.getUserMedia({audio:!0});Xt.value=e,Zt.value=[];let t=MediaRecorder.isTypeSupported(`audio/webm`)?`audio/webm`:``,n=t?new MediaRecorder(e,{mimeType:t}):new MediaRecorder(e);n.ondataavailable=e=>{e.data&&e.data.size>0&&Zt.value.push(e.data)},n.start(),Yt.value=n,k.value=!0,Qt.value=setTimeout(()=>{G(),T.notify({type:`info`,message:D(`voice.maxDurationReached`),position:`top`,timeout:3500})},Wt)}catch{T.notify({type:`negative`,message:D(`voice.errorMicPermission`),position:`top`,timeout:5e3})}}}async function G(){if(!k.value)return;let e=Yt.value;if(!e)return;k.value=!1,A.value=!0,Qt.value&&=(clearTimeout(Qt.value),null);let t=await new Promise(t=>{e.onstop=()=>t(new Blob(Zt.value,{type:`audio/webm`})),e.stop()});try{if(t.size===0)throw Error(`MIC_AUDIO_INVALID`);let e=new FormData;e.append(`audio`,t,`voice.webm`),e.append(`language`,E.global.voiceLanguage||`auto`);let n=await fetch(`/api/voice/transcribe`,{method:`POST`,body:e});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(String(e.code??e.error??`HTTP_${n.status}`))}let r=await n.json();r.text?.trim()&&(O.value=O.value?`${O.value.trimEnd()} ${r.text.trim()}`:r.text.trim())}catch(e){let t=e instanceof Error?e.message:`TRANSCRIPTION_FAILED`;T.notify({type:`negative`,message:D({VOICE_DISABLED:`voice.errorDisabled`,MODEL_NOT_CONFIGURED:`voice.errorModelMissing`,MODEL_NOT_INSTALLED:`voice.errorModelNotInstalled`,VOICE_RUNTIME_MISSING:`voice.errorRuntimeMissing`,MIC_AUDIO_INVALID:`voice.errorAudioInvalid`,LANGUAGE_INVALID:`voice.errorLanguageInvalid`,TRANSCRIPTION_TIMEOUT:`voice.errorTranscription`}[t]??`voice.errorTranscription`),position:`top`,timeout:5e3})}finally{Yt.value=null,Zt.value=[],Xt.value?.getTracks().forEach(e=>{e.stop()}),Xt.value=null,A.value=!1}}function wn(e){return $t.value?E.global.voicePttKey===`ctrl+space`?e.ctrlKey&&e.code===`Space`:e.key===`Alt`:!1}function Tn(e){!wn(e)||e.repeat||(e.preventDefault(),Cn())}function En(e){wn(e)&&(e.preventDefault(),G())}function Dn(){k.value&&G()}function On(){document.visibilityState!==`visible`&&k.value&&G()}let K=m(()=>(ke[B.value]??Ae).map(e=>({label:D(e.i18nLabelKey),value:e.value,description:D(e.i18nDescriptionKey)})));te(B,()=>{let e=K.value.map(e=>e.value);if(e.length>0){let t=E.global.defaultModelByEngine?.[B.value];typeof t==`string`&&e.includes(t)?N.value=t:e.includes(N.value)||(N.value=e.includes(`auto`)?`auto`:e[0]??`auto`)}e.length>0&&!e.includes(P.value)&&(P.value=e.includes(`auto`)?`auto`:e[0]??`auto`);let t=je[B.value]??[];t.length>0&&!t.includes(V.value)&&(V.value=on(I.value,B.value));let n=(De[B.value]??[]).map(e=>e.value);n.length>0&&!n.includes(F.value)&&(F.value=n.includes(`auto`)?`auto`:n[0]??`auto`)});function kn(e){let t=e.indexOf(`:`);return t>=0?e.slice(t+1).trim():e}let An=m(()=>(De[B.value]??De[`claude-code`]).map(e=>({value:e.value,label:kn(D(e.i18nLabelKey)),description:D(e.i18nDescriptionKey)}))),q=m(()=>{let e=j.value.trim();return e.startsWith(`https://www.notion.so/`)||e.startsWith(`https://app.notion.com/`)}),jn=m(()=>/[?&]p=[0-9a-f]{32}(?:[&#]|$)/i.test(j.value)),J=e(`panel`);function Mn(){let e=j.value.trim();return J.value===`parent`&&jn.value?e.replace(/([?&])p=[0-9a-f]{32}(?=[&#]|$)/i,`$1`).replace(/([?&])pm=[a-z]+(?=[&#]|$)/i,`$1`).replace(/[?&]+$/,``).replace(/\?&/,`?`):e}let Nn=e([]),Pn=e([]),Fn=e(``),In=e(``),Ln=m(()=>!M.value||!q.value);function Rn(){let e=Fn.value.trim();e&&(Nn.value.push(e),Fn.value=``)}function zn(e){Nn.value.splice(e,1)}function Bn(){let e=In.value.trim();e&&(Pn.value.push(e),In.value=``)}function Vn(e){Pn.value.splice(e,1)}function Hn(){M.value=!M.value,M.value||(j.value=``)}let Y=e(!1),X=e(!1),Un=e(`per_task`);te(()=>X.value,e=>{e&&V.value!==`bypass`&&(V.value=`bypass`)});function Wn(){X.value=!X.value,X.value&&(P.value=N.value)}let Z=e(``),Gn=m(()=>/\/issues\/\d+/.test(Z.value.trim()));function Kn(){Y.value=!Y.value,Y.value||(Z.value=``)}let Q=e(!1),$=e(null),qn=e([]),Jn=e(!1);async function Yn(){if(!I.value.trim()){qn.value=[];return}Jn.value=!0;try{qn.value=await Ne.fetchOrphanWorktrees(I.value.trim())}catch{qn.value=[]}finally{Jn.value=!1}}function Xn(){Q.value=!Q.value,Q.value?(M.value=!1,j.value=``,Y.value=!1,Z.value=``,z.value=!0,Yn()):$.value=null}te(I,()=>{$.value=null,Q.value&&Yn()}),te($,e=>{if(!e)return;let t=qn.value.find(t=>t.path===e);t&&(L.value=t.suggestedSourceBranch),z.value=!0});async function Zn(e){if(!e.trim()){H.value=[],L.value=null;return}un.value=!0;try{let t=await fetch(`/api/git/branches?path=${encodeURIComponent(e.trim())}`);if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();H.value=n.local??n.branches??[],H.value.length>0&&!L.value&&(L.value=H.value[0]??null)}catch{H.value=[],L.value=null}finally{un.value=!1}}function Qn(e){let t=E.getProjectByPath(e);if(t){t.defaultSourceBranch&&(L.value=t.defaultSourceBranch);let e=t.taskPromptTemplate??``;(O.value===``||O.value===Jt.value)&&(O.value=e,Jt.value=e);let n=K.value.map(e=>e.value);if(t.defaultModel&&n.includes(t.defaultModel))N.value=t.defaultModel;else{let e=E.global.defaultModelByEngine?.[B.value];typeof e==`string`&&n.includes(e)&&(N.value=e)}}V.value=on(e,B.value)}let $n=null;te(I,e=>{$n&&clearTimeout($n),$n=setTimeout(()=>{L.value=null,Zn(e),Qn(e)},500)});function er(e,t){let n=e.toLowerCase();t(()=>{Gt.value=E.projectPaths.filter(e=>e.toLowerCase().includes(n)||Se(e).toLowerCase().includes(n))})}function tr(e){I.value=E.projectPaths.find(t=>Se(t)===e)??e}n(async()=>{await E.fetchSettings();let e=E.global.branchPrefixes;e.length>0&&!e.includes(R.value)&&(R.value=e[0]);let t=Pe();t.autoLoop===!0&&(X.value=!0),t.autoLoopSessionMode===`continuous`&&(Un.value=`continuous`),t.autoLoop===!0&&t.brainstormModel&&(P.value=t.brainstormModel),t.projectPath&&E.projectPaths.includes(t.projectPath)&&(I.value=t.projectPath),V.value=on(I.value,B.value);try{let e=await fetch(`/api/engines`);e.ok&&(en.value=await e.json())}catch{}{let e=K.value.map(e=>e.value),t=E.global.defaultModelByEngine?.[B.value];typeof t==`string`&&e.includes(t)?N.value=t:e.length>0&&!e.includes(N.value)&&(N.value=e.includes(`auto`)?`auto`:e[0]??`auto`)}{let e=K.value.map(e=>e.value);e.length>0&&!e.includes(P.value)&&(P.value=e.includes(`auto`)?`auto`:e[0]??`auto`)}window.addEventListener(`keydown`,Tn),window.addEventListener(`keyup`,En),window.addEventListener(`blur`,Dn),document.addEventListener(`visibilitychange`,On)}),r(()=>{$n&&clearTimeout($n),window.removeEventListener(`keydown`,Tn),window.removeEventListener(`keyup`,En),window.removeEventListener(`blur`,Dn),document.removeEventListener(`visibilitychange`,On),Qt.value&&=(clearTimeout(Qt.value),null),k.value&&G()});function nr(e){return e.normalize(`NFD`).replace(/[\u0300-\u036f]/g,``).toLowerCase().replace(/[^a-z0-9\s-]/g,``).trim().replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50)}function rr(){return Kt.value.trim()?Kt.value.trim().substring(0,80):!M.value&&!Y.value&&O.value.trim()&&(O.value.trim().split(`
|
|
1
|
+
import{$ as e,B as t,F as n,I as r,O as i,R as a,S as ee,U as te,W as o,_ as s,at as ne,b as c,c as re,ct as l,g as u,h as d,it as f,k as ie,m as p,n as ae,o as oe,ot as se,p as m,s as h,w as ce,y as g}from"./vue.runtime.esm-bundler-JZnIeD9D.js";import{t as _}from"./QIcon-C6E-oEjI.js";import{t as le}from"./QSeparator-DWTCQxsa.js";import{t as v}from"./QInput-BF8x4RTv.js";import{E as ue,N as y,d as de,l as fe,s as pe,x as me,z as he}from"./index-02IPrCWM.js";import{t as ge}from"./QSpinnerDots-DIV68-cV.js";import{n as b,r as x,t as _e}from"./use-quasar-CwG_Rs2g.js";import{l as S,t as C}from"./QSelect-DJgkh8M3.js";import{t as w}from"./QTooltip-epbJipNF.js";import{t as ve}from"./QExpansionItem-CYcOrwbm.js";import{t as ye}from"./_plugin-vue_export-helper-BDNMzG2s.js";import{t as be}from"./QSpace-ezNrZkuj.js";import{t as xe}from"./QBtnToggle-BEgY0AkW.js";import{i as Se}from"./project-color-CubSkld3.js";import{t as Ce}from"./QPage-D3rjwA1l.js";import{a as we,i as Te,n as Ee,r as De,t as Oe}from"./expand-template-BsmF6e32.js";import{i as ke,r as Ae,t as je}from"./permissionModes-6jhegAm-.js";var Me=`kobo:create-page-prefs`;function T(){try{let e=localStorage.getItem(Me);return e===null?void 0:JSON.parse(e)}catch{return}}function Ne(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Pe(){let e=T();if(!Ne(e))return{};let t={};return typeof e.projectPath==`string`&&e.projectPath.length>0&&(t.projectPath=e.projectPath),typeof e.autoLoop==`boolean`&&(t.autoLoop=e.autoLoop),(e.autoLoopSessionMode===`per_task`||e.autoLoopSessionMode===`continuous`)&&(t.autoLoopSessionMode=e.autoLoopSessionMode),typeof e.brainstormModel==`string`&&e.brainstormModel.length>0&&(t.brainstormModel=e.brainstormModel),t}function Fe(e){try{localStorage.setItem(Me,JSON.stringify(e))}catch{}}var Ie={class:`create-inner`},Le={class:`create-title text-center text-weight-bold q-mb-lg text-grey-3`},Re={class:`create-card rounded-borders`},ze={class:`card-top-bar row items-center q-px-md q-py-xs`},Be={class:`model-badge cursor-default row items-center q-gutter-xs`},Ve={class:`text-indigo-3 text-weight-medium text-caption`},He={key:0,class:`notion-url-wrap`},Ue={key:0,class:`notion-error text-caption q-px-md q-pb-xs text-red-5`},We={key:1,class:`notion-valid text-caption q-px-md q-pb-xs text-green-4`},Ge={key:2,class:`notion-peek-choice q-px-md q-pb-sm`},Ke={class:`text-caption text-grey-4 q-mb-sm`},qe={class:`row q-gutter-sm`},Je={class:`peek-card-text`},Ye={class:`peek-card-title`},Xe={class:`peek-card-desc`},Ze={class:`peek-card-text`},Qe={class:`peek-card-title`},$e={class:`peek-card-desc`},et={key:0,class:`sentry-url-wrap`},tt={key:0,class:`sentry-error text-caption q-px-md q-pb-xs text-red-5`},nt={key:1,class:`sentry-valid text-caption q-px-md q-pb-xs text-red-4`},rt={class:`card-name-wrap`},it={class:`card-textarea-wrap`},at={class:`row items-center justify-end q-px-sm q-pb-xs q-gutter-sm`},ot={key:0,class:`row items-center text-caption text-amber-6`},st={class:`manual-hint q-px-md q-py-sm text-caption text-grey-6`},ct={class:`q-pa-sm manual-section-body`},lt={class:`row items-center q-gutter-sm q-mb-sm`},ut={class:`col text-caption text-grey-4`},dt={class:`q-pa-sm manual-section-body`},ft={class:`row items-center q-gutter-sm q-mb-sm`},pt={class:`col text-caption text-grey-4`},mt={class:`card-bottom-bar`},ht={class:`row q-col-gutter-xs q-px-xs`},gt={key:0,class:`col-12 col-sm-6 col-md-3`},_t={class:`bottom-select-label row items-center no-wrap`},vt={class:`col-12 col-sm-6 col-md-3`},yt={class:`bottom-select-label row items-center no-wrap`},bt={key:0,class:`text-grey-5 q-mr-xs`},xt={class:`col-12 col-sm-6 col-md-3`},St={class:`bottom-select-label row items-center no-wrap`},Ct={class:`col-12 col-md-3`},wt={class:`bottom-select-label row items-center no-wrap`},Tt={class:`row q-col-gutter-xs q-pa-xs col-12 items-center justify-center`},Et={class:`col-12 col-md-auto`},Dt={key:0,class:`col-12 col-md-auto`},Ot={key:1,class:`col-12 col-md-auto`},kt={class:`bottom-select-label row items-center no-wrap`},At={class:`text-grey-5 q-mr-xs`},jt={class:`row q-col-gutter-xs q-pa-xs col-12 items-center justify-center`},Mt={class:`col-12 col-md-auto`},Nt={class:`col-12 col-md-auto`},Pt={class:`row q-col-gutter-xs q-px-xs bottom-row-git`},Ft={class:`col-12 col-md-4`},It={key:0,class:`col-12 col-md-4`},Lt={class:`bottom-select-label row items-center no-wrap`},Rt={key:1,class:`col-12 col-md-4`},zt={class:`bottom-select-label row items-center no-wrap`},Bt={class:`col-12 col-md-4`},Vt={class:`bottom-select-label row items-center no-wrap`},Ht={class:`row justify-center q-px-sm q-py-sm`},Ut={class:`create-hint text-center text-body2 q-mt-md text-grey-8`},Wt=6e4,E=ye(ee({__name:`CreatePage`,setup(ee){function ye(e){return e.disabled===!0}let Me=pe(),T=_e(),Ne=de(),E=me(),{t:D}=he(),Gt=e([]),Kt=e(``),O=e(``),qt=e(null),Jt=e(``),k=e(!1),A=e(!1),Yt=e(null),Xt=e(null),Zt=e([]),Qt=e(null),j=e(``),M=e(!1),N=e(`claude-opus-4-8`),P=e(`claude-opus-4-8`),F=e(`auto`),I=e(``),L=e(null),R=e(`feature`),z=e(!1),$t=m(()=>E.global.voiceEnabled),en=e([]),B=e(`claude-code`),tn=m(()=>en.value.find(e=>e.id===B.value)),nn=m(()=>en.value.map(e=>({value:e.id,label:e.displayName}))),rn=m(()=>E.global.branchPrefixes.map(e=>({label:`${e}/`,value:e}))),an=[`plan`,`bypass`,`strict`,`interactive`];function on(e,t){let n=e?E.getProjectByPath(e):void 0,r=n?.agentPermissionMode;if(typeof r==`string`&&an.includes(r))return r;let i=E.global.defaultPermissionModeByEngine?.[t];return typeof i==`string`&&an.includes(i)?i:n?.dangerouslySkipPermissions??E.global.dangerouslySkipPermissions??!0?`bypass`:t===`codex`?`plan`:`interactive`}let V=e(on(``,B.value)),sn=m(()=>{switch(V.value){case`plan`:return`visibility`;case`bypass`:return`flash_on`;case`strict`:return`lock`;case`interactive`:return`security`}}),cn=m(()=>(je[B.value]??an).map(e=>({value:e,label:D(`agentPermissionMode.${e}`),disabled:e===`plan`&&X.value}))),H=e([]),ln=e([]),un=e(!1),dn=e(!1);function fn(e,t){t(()=>{ln.value=e?H.value.filter(t=>t.toLowerCase().includes(e.toLowerCase())):H.value})}let pn=ue();function mn(){return qt.value?.nativeEl??null}let{showSkills:hn,selectedSkillIndex:U,groupedDropdown:gn,flatDropdown:W,fetchSkills:_n,detectSlashFragment:vn,replaceFragmentWith:yn,closeDropdown:bn}=Te(O,mn,{excludeKoboCommands:!0});_n(),te(O,async()=>{await ie(),await vn()});function xn(e){if(e.type===`template`){let t=pn.templates.find(t=>t.slug===e.name);if(!t)return;yn(Ee(t.content,Oe({workspace:null,gitStats:null,sessionName:null}))),bn();return}yn(`/${e.name} `),bn()}function Sn(e){!hn.value||W.value.length===0||(e.key===`ArrowDown`?(e.preventDefault(),U.value=(U.value+1)%W.value.length):e.key===`ArrowUp`?(e.preventDefault(),U.value=(U.value-1+W.value.length)%W.value.length):e.key===`Enter`&&!e.shiftKey&&!e.ctrlKey&&!e.metaKey?(e.preventDefault(),xn(W.value[U.value])):e.key===`Escape`&&(e.preventDefault(),bn()))}async function Cn(){if(!(!$t.value||k.value||A.value)){if(!navigator.mediaDevices?.getUserMedia||typeof MediaRecorder>`u`){T.notify({type:`warning`,message:D(`voice.notSupported`),position:`top`,timeout:4e3});return}try{let e=await navigator.mediaDevices.getUserMedia({audio:!0});Xt.value=e,Zt.value=[];let t=MediaRecorder.isTypeSupported(`audio/webm`)?`audio/webm`:``,n=t?new MediaRecorder(e,{mimeType:t}):new MediaRecorder(e);n.ondataavailable=e=>{e.data&&e.data.size>0&&Zt.value.push(e.data)},n.start(),Yt.value=n,k.value=!0,Qt.value=setTimeout(()=>{G(),T.notify({type:`info`,message:D(`voice.maxDurationReached`),position:`top`,timeout:3500})},Wt)}catch{T.notify({type:`negative`,message:D(`voice.errorMicPermission`),position:`top`,timeout:5e3})}}}async function G(){if(!k.value)return;let e=Yt.value;if(!e)return;k.value=!1,A.value=!0,Qt.value&&=(clearTimeout(Qt.value),null);let t=await new Promise(t=>{e.onstop=()=>t(new Blob(Zt.value,{type:`audio/webm`})),e.stop()});try{if(t.size===0)throw Error(`MIC_AUDIO_INVALID`);let e=new FormData;e.append(`audio`,t,`voice.webm`),e.append(`language`,E.global.voiceLanguage||`auto`);let n=await fetch(`/api/voice/transcribe`,{method:`POST`,body:e});if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(String(e.code??e.error??`HTTP_${n.status}`))}let r=await n.json();r.text?.trim()&&(O.value=O.value?`${O.value.trimEnd()} ${r.text.trim()}`:r.text.trim())}catch(e){let t=e instanceof Error?e.message:`TRANSCRIPTION_FAILED`;T.notify({type:`negative`,message:D({VOICE_DISABLED:`voice.errorDisabled`,MODEL_NOT_CONFIGURED:`voice.errorModelMissing`,MODEL_NOT_INSTALLED:`voice.errorModelNotInstalled`,VOICE_RUNTIME_MISSING:`voice.errorRuntimeMissing`,MIC_AUDIO_INVALID:`voice.errorAudioInvalid`,LANGUAGE_INVALID:`voice.errorLanguageInvalid`,TRANSCRIPTION_TIMEOUT:`voice.errorTranscription`}[t]??`voice.errorTranscription`),position:`top`,timeout:5e3})}finally{Yt.value=null,Zt.value=[],Xt.value?.getTracks().forEach(e=>{e.stop()}),Xt.value=null,A.value=!1}}function wn(e){return $t.value?E.global.voicePttKey===`ctrl+space`?e.ctrlKey&&e.code===`Space`:e.key===`Alt`:!1}function Tn(e){!wn(e)||e.repeat||(e.preventDefault(),Cn())}function En(e){wn(e)&&(e.preventDefault(),G())}function Dn(){k.value&&G()}function On(){document.visibilityState!==`visible`&&k.value&&G()}let K=m(()=>(ke[B.value]??Ae).map(e=>({label:D(e.i18nLabelKey),value:e.value,description:D(e.i18nDescriptionKey)})));te(B,()=>{let e=K.value.map(e=>e.value);if(e.length>0){let t=E.global.defaultModelByEngine?.[B.value];typeof t==`string`&&e.includes(t)?N.value=t:e.includes(N.value)||(N.value=e.includes(`auto`)?`auto`:e[0]??`auto`)}e.length>0&&!e.includes(P.value)&&(P.value=e.includes(`auto`)?`auto`:e[0]??`auto`);let t=je[B.value]??[];t.length>0&&!t.includes(V.value)&&(V.value=on(I.value,B.value));let n=(De[B.value]??[]).map(e=>e.value);n.length>0&&!n.includes(F.value)&&(F.value=n.includes(`auto`)?`auto`:n[0]??`auto`)});function kn(e){let t=e.indexOf(`:`);return t>=0?e.slice(t+1).trim():e}let An=m(()=>(De[B.value]??De[`claude-code`]).map(e=>({value:e.value,label:kn(D(e.i18nLabelKey)),description:D(e.i18nDescriptionKey)}))),q=m(()=>{let e=j.value.trim();return e.startsWith(`https://www.notion.so/`)||e.startsWith(`https://app.notion.com/`)}),jn=m(()=>/[?&]p=[0-9a-f]{32}(?:[&#]|$)/i.test(j.value)),J=e(`panel`);function Mn(){let e=j.value.trim();return J.value===`parent`&&jn.value?e.replace(/([?&])p=[0-9a-f]{32}(?=[&#]|$)/i,`$1`).replace(/([?&])pm=[a-z]+(?=[&#]|$)/i,`$1`).replace(/[?&]+$/,``).replace(/\?&/,`?`):e}let Nn=e([]),Pn=e([]),Fn=e(``),In=e(``),Ln=m(()=>!M.value||!q.value);function Rn(){let e=Fn.value.trim();e&&(Nn.value.push(e),Fn.value=``)}function zn(e){Nn.value.splice(e,1)}function Bn(){let e=In.value.trim();e&&(Pn.value.push(e),In.value=``)}function Vn(e){Pn.value.splice(e,1)}function Hn(){M.value=!M.value,M.value||(j.value=``)}let Y=e(!1),X=e(!1),Un=e(`per_task`);te(()=>X.value,e=>{e&&V.value!==`bypass`&&(V.value=`bypass`)});function Wn(){X.value=!X.value,X.value&&(P.value=N.value)}let Z=e(``),Gn=m(()=>/\/issues\/\d+/.test(Z.value.trim()));function Kn(){Y.value=!Y.value,Y.value||(Z.value=``)}let Q=e(!1),$=e(null),qn=e([]),Jn=e(!1);async function Yn(){if(!I.value.trim()){qn.value=[];return}Jn.value=!0;try{qn.value=await Ne.fetchOrphanWorktrees(I.value.trim())}catch{qn.value=[]}finally{Jn.value=!1}}function Xn(){Q.value=!Q.value,Q.value?(M.value=!1,j.value=``,Y.value=!1,Z.value=``,z.value=!0,Yn()):$.value=null}te(I,()=>{$.value=null,Q.value&&Yn()}),te($,e=>{if(!e)return;let t=qn.value.find(t=>t.path===e);t&&(L.value=t.suggestedSourceBranch),z.value=!0});async function Zn(e){if(!e.trim()){H.value=[],L.value=null;return}un.value=!0;try{let t=await fetch(`/api/git/branches?path=${encodeURIComponent(e.trim())}`);if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json();H.value=n.local??n.branches??[],H.value.length>0&&!L.value&&(L.value=H.value[0]??null)}catch{H.value=[],L.value=null}finally{un.value=!1}}function Qn(e){let t=E.getProjectByPath(e);if(t){t.defaultSourceBranch&&(L.value=t.defaultSourceBranch);let e=t.taskPromptTemplate??``;(O.value===``||O.value===Jt.value)&&(O.value=e,Jt.value=e);let n=K.value.map(e=>e.value);if(t.defaultModel&&n.includes(t.defaultModel))N.value=t.defaultModel;else{let e=E.global.defaultModelByEngine?.[B.value];typeof e==`string`&&n.includes(e)&&(N.value=e)}}V.value=on(e,B.value)}let $n=null;te(I,e=>{$n&&clearTimeout($n),$n=setTimeout(()=>{L.value=null,Zn(e),Qn(e)},500)});function er(e,t){let n=e.toLowerCase();t(()=>{Gt.value=E.projectPaths.filter(e=>e.toLowerCase().includes(n)||Se(e).toLowerCase().includes(n))})}function tr(e){I.value=E.projectPaths.find(t=>Se(t)===e)??e}n(async()=>{await E.fetchSettings();let e=E.global.branchPrefixes;e.length>0&&!e.includes(R.value)&&(R.value=e[0]);let t=Pe();t.autoLoop===!0&&(X.value=!0),t.autoLoopSessionMode===`continuous`&&(Un.value=`continuous`),t.autoLoop===!0&&t.brainstormModel&&(P.value=t.brainstormModel),t.projectPath&&E.projectPaths.includes(t.projectPath)&&(I.value=t.projectPath),V.value=on(I.value,B.value);try{let e=await fetch(`/api/engines`);e.ok&&(en.value=await e.json())}catch{}{let e=K.value.map(e=>e.value),t=E.global.defaultModelByEngine?.[B.value];typeof t==`string`&&e.includes(t)?N.value=t:e.length>0&&!e.includes(N.value)&&(N.value=e.includes(`auto`)?`auto`:e[0]??`auto`)}{let e=K.value.map(e=>e.value);e.length>0&&!e.includes(P.value)&&(P.value=e.includes(`auto`)?`auto`:e[0]??`auto`)}window.addEventListener(`keydown`,Tn),window.addEventListener(`keyup`,En),window.addEventListener(`blur`,Dn),document.addEventListener(`visibilitychange`,On)}),r(()=>{$n&&clearTimeout($n),window.removeEventListener(`keydown`,Tn),window.removeEventListener(`keyup`,En),window.removeEventListener(`blur`,Dn),document.removeEventListener(`visibilitychange`,On),Qt.value&&=(clearTimeout(Qt.value),null),k.value&&G()});function nr(e){return e.normalize(`NFD`).replace(/[\u0300-\u036f]/g,``).toLowerCase().replace(/[^a-z0-9\s-]/g,``).trim().replace(/\s+/g,`-`).replace(/-+/g,`-`).substring(0,50)}function rr(){return Kt.value.trim()?Kt.value.trim().substring(0,80):!M.value&&!Y.value&&O.value.trim()&&(O.value.trim().split(`
|
|
2
2
|
`)[0]??``).substring(0,80)||`workspace`}function ir(e){let t=(e.split(`/`).pop()??``).split(`-`);t.length>1&&/^[0-9a-f]{12,}$/i.test(t[t.length-1])&&t.pop();let n=t.join(`-`).toLowerCase(),r=n.match(/tk-(\d+)/);if(r){let e=`TK-${r[1]}`,t=n.replace(/tk-\d+/i,``).replace(/-+/g,`-`).replace(/^-|-$/g,``).substring(0,40);return t?`${e}--${t}`:e}return n.substring(0,50)||`task-${Date.now()}`}function ar(){return M.value&&!q.value?D(`createPage.validationNotionUrl`):Y.value&&!Gn.value?D(`createPage.sentryValidation`):!M.value&&!Y.value&&!O.value.trim()?D(`createPage.validationDescription`):!M.value&&!Y.value&&(!rr()||rr()===`workspace`)&&!Kt.value.trim()&&!O.value.trim()?D(`createPage.validationName`):I.value.trim()?L.value?null:D(`createPage.validationBranch`):D(`createPage.validationPath`)}async function or(){let e=ar();if(e){T.notify({type:`negative`,message:e,position:`top`});return}if(Q.value&&!$.value){T.notify({type:`negative`,message:D(`createPage.pickWorktreeRequired`),position:`top`});return}dn.value=!0;try{let e=rr(),t;t=M.value&&q.value?ir(Mn()):e===`workspace`?`task-${Date.now()}`:nr(e);let n=`${R.value}/${t}`,r={name:e,projectPath:I.value.trim(),sourceBranch:L.value,...Q.value&&$.value?{worktreePath:$.value,skipSetupScript:!0}:{workingBranch:n},engine:B.value,model:N.value,reasoningEffort:F.value,...M.value&&q.value?{notionUrl:Mn()}:{},...Y.value&&Gn.value?{sentryUrl:Z.value.trim()}:{},...Ln.value&&Nn.value.length>0?{tasks:Nn.value}:{},...Ln.value&&Pn.value.length>0?{acceptanceCriteria:Pn.value}:{},...z.value&&!Q.value?{skipSetupScript:!0}:{},...O.value.trim()?{description:O.value.trim()}:{},...X.value?{autoLoop:!0,autoLoopSessionMode:Un.value,brainstormModel:P.value}:{},agentPermissionMode:X.value&&V.value===`plan`?`bypass`:V.value},i=await Ne.createWorkspace(r);i._branchAdjusted&&T.notify({type:`info`,message:D(`createPage.branchAdjusted`,{branch:i.workingBranch}),position:`top`,timeout:6e3}),Fe({projectPath:I.value.trim(),autoLoop:X.value,autoLoopSessionMode:Un.value,...X.value?{brainstormModel:P.value}:{}}),fe().subscribe(i.id),Ne.selectWorkspace(i.id),Me.push({name:`workspace`,params:{id:i.id}})}catch{T.notify({type:`negative`,message:D(`createPage.errorCreating`),position:`top`})}finally{dn.value=!1}}return(e,n)=>(a(),d(Ce,{class:`create-page flex flex-center column`},{default:o(()=>[p(`div`,Ie,[p(`div`,Le,l(e.$t(`createPage.title`)),1),p(`div`,Re,[p(`div`,ze,[p(`span`,Be,[c(_,{name:`auto_awesome`,size:`14px`,color:`indigo-4`}),p(`span`,Ve,l(tn.value?.displayName??e.$t(`createPage.claudeCode`)),1)]),c(be),c(y,{flat:``,dense:``,"no-caps":``,size:`sm`,color:M.value?`green-4`:`grey-5`,class:`notion-toggle-btn text-caption rounded-borders`,disable:Q.value,onClick:Hn},{default:o(()=>[c(_,{name:`description`,size:`14px`,class:`q-mr-xs`}),g(` `+l(M.value?e.$t(`createPage.notionEnabled`):e.$t(`createPage.importNotion`)),1)]),_:1},8,[`color`,`disable`]),c(y,{flat:``,dense:``,"no-caps":``,size:`sm`,color:Y.value?`red-4`:`grey-5`,class:`sentry-toggle-btn text-caption rounded-borders q-ml-sm`,disable:Q.value,onClick:Kn},{default:o(()=>[c(_,{name:`bug_report`,size:`14px`,class:`q-mr-xs`}),g(` `+l(Y.value?e.$t(`createPage.sentryEnabled`):e.$t(`createPage.importSentry`)),1)]),_:1},8,[`color`,`disable`])]),c(le,{color:`grey-9`}),c(ae,{name:`slide`},{default:o(()=>[M.value?(a(),s(`div`,He,[c(v,{modelValue:j.value,"onUpdate:modelValue":n[0]||=e=>j.value=e,borderless:``,dense:``,placeholder:e.$t(`createPage.notionPlaceholder`),class:`notion-url-input`,"input-class":`notion-url-input-inner`},{prepend:o(()=>[c(_,{name:`link`,size:`16px`,color:q.value?`green-4`:`grey-6`},null,8,[`color`])]),_:1},8,[`modelValue`,`placeholder`]),j.value.trim()&&!q.value?(a(),s(`div`,Ue,l(e.$t(`createPage.notionValidation`)),1)):u(``,!0),q.value?(a(),s(`div`,We,l(e.$t(`createPage.notionAutoExtract`)),1)):u(``,!0),q.value&&jn.value?(a(),s(`div`,Ge,[p(`div`,Ke,[c(_,{name:`info`,size:`14px`,color:`indigo-4`,class:`q-mr-xs`}),g(` `+l(e.$t(`createPage.notionPanelChoiceLabel`)),1)]),p(`div`,qe,[p(`button`,{type:`button`,class:ne([`peek-card col`,{"peek-card--active":J.value===`panel`}]),onClick:n[1]||=e=>J.value=`panel`},[c(_,{name:`article`,size:`22px`,class:`peek-card-icon`}),p(`div`,Je,[p(`div`,Ye,l(e.$t(`createPage.notionPanelOption`)),1),p(`div`,Xe,l(e.$t(`createPage.notionPanelOptionDesc`)),1)]),J.value===`panel`?(a(),d(_,{key:0,name:`check_circle`,size:`18px`,color:`indigo-4`,class:`peek-card-check`})):u(``,!0)],2),p(`button`,{type:`button`,class:ne([`peek-card col`,{"peek-card--active":J.value===`parent`}]),onClick:n[2]||=e=>J.value=`parent`},[c(_,{name:`folder_open`,size:`22px`,class:`peek-card-icon`}),p(`div`,Ze,[p(`div`,Qe,l(e.$t(`createPage.notionParentOption`)),1),p(`div`,$e,l(e.$t(`createPage.notionParentOptionDesc`)),1)]),J.value===`parent`?(a(),d(_,{key:0,name:`check_circle`,size:`18px`,color:`indigo-4`,class:`peek-card-check`})):u(``,!0)],2)])])):u(``,!0)])):u(``,!0)]),_:1}),M.value?(a(),d(le,{key:0,color:`grey-9`})):u(``,!0),c(ae,{name:`slide`},{default:o(()=>[Y.value?(a(),s(`div`,et,[c(v,{modelValue:Z.value,"onUpdate:modelValue":n[3]||=e=>Z.value=e,borderless:``,dense:``,placeholder:e.$t(`createPage.sentryPlaceholder`),class:`sentry-url-input`,"input-class":`sentry-url-input-inner`},{prepend:o(()=>[c(_,{name:`link`,size:`16px`,color:Gn.value?`red-4`:`grey-6`},null,8,[`color`])]),_:1},8,[`modelValue`,`placeholder`]),Z.value.trim()&&!Gn.value?(a(),s(`div`,tt,l(e.$t(`createPage.sentryValidation`)),1)):u(``,!0),Gn.value?(a(),s(`div`,nt,l(e.$t(`createPage.sentryAutoExtract`)),1)):u(``,!0)])):u(``,!0)]),_:1}),Y.value?(a(),d(le,{key:1,color:`grey-9`})):u(``,!0),p(`div`,rt,[c(v,{modelValue:Kt.value,"onUpdate:modelValue":n[4]||=e=>Kt.value=e,borderless:``,dense:``,placeholder:M.value&&q.value?e.$t(`createPage.workspaceName`):e.$t(`createPage.workspaceNamePlaceholder`),class:`name-input`,"input-class":`name-input-inner`},null,8,[`modelValue`,`placeholder`])]),c(le,{color:`grey-9`}),p(`div`,it,[c(v,{ref_key:`descriptionRef`,ref:qt,modelValue:O.value,"onUpdate:modelValue":n[5]||=e=>O.value=e,type:`textarea`,borderless:``,autogrow:``,rows:3,placeholder:M.value?e.$t(`createPage.instructions`):e.$t(`createPage.instructionsPlaceholder`),class:`create-textarea`,"input-class":`create-textarea-input`,onKeydown:[Sn,oe(h(or,[`ctrl`]),[`enter`]),oe(h(or,[`meta`]),[`enter`])]},null,8,[`modelValue`,`placeholder`,`onKeydown`]),p(`div`,at,[A.value?(a(),s(`div`,ot,[c(ge,{size:`14px`,color:`amber-6`,class:`q-mr-xs`}),p(`span`,null,l(e.$t(`voice.transcribing`)),1)])):u(``,!0),c(y,{flat:``,dense:``,size:`sm`,icon:A.value?`hourglass_top`:k.value?`mic`:`mic_none`,color:k.value?`red-5`:A.value?`amber-6`:`grey-6`,disable:!$t.value||A.value,class:ne({"voice-btn--recording":k.value}),onMousedown:h(Cn,[`prevent`]),onMouseup:h(G,[`prevent`]),onMouseleave:h(G,[`prevent`]),onTouchstart:h(Cn,[`prevent`]),onTouchend:h(G,[`prevent`])},{default:o(()=>[c(w,null,{default:o(()=>[g(l(A.value?e.$t(`voice.transcribing`):k.value?e.$t(`voice.recording`):e.$t(`voice.holdToTalk`)),1)]),_:1})]),_:1},8,[`icon`,`color`,`disable`,`class`])]),f(hn)&&f(W).length>0?(a(),d(we,{key:0,class:`create-slash-popup`,"grouped-dropdown":f(gn),"flat-dropdown":f(W),"selected-index":f(U),onSelect:xn},null,8,[`grouped-dropdown`,`flat-dropdown`,`selected-index`])):u(``,!0)]),c(le,{color:`grey-9`}),Ln.value?(a(),s(re,{key:2},[p(`div`,st,l(e.$t(`createPage.manualHint`)),1),c(ve,{dark:``,dense:``,label:e.$t(`createPage.tasks`,{count:Nn.value.length}),"header-class":`text-grey-4 manual-expansion-header`,class:`manual-expansion q-mx-sm`},{default:o(()=>[p(`div`,ct,[p(`div`,lt,[c(v,{modelValue:Fn.value,"onUpdate:modelValue":n[6]||=e=>Fn.value=e,dark:``,dense:``,borderless:``,placeholder:e.$t(`createPage.addTask`),class:`col manual-input`,"input-class":`manual-input-inner`,onKeydown:oe(h(Rn,[`prevent`]),[`enter`])},null,8,[`modelValue`,`placeholder`,`onKeydown`]),c(y,{flat:``,dense:``,round:``,icon:`add`,color:`indigo-4`,disable:!Fn.value.trim(),onClick:Rn},{default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`tooltip.addTask`)),1)]),_:1})]),_:1},8,[`disable`])]),(a(!0),s(re,null,t(Nn.value,(t,n)=>(a(),s(`div`,{key:`task-${n}`,class:`row items-center q-py-xs manual-item`},[p(`span`,ut,l(t),1),c(y,{flat:``,dense:``,round:``,icon:`close`,size:`xs`,color:`grey-6`,onClick:e=>zn(n)},{default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`tooltip.removeTask`)),1)]),_:1})]),_:1},8,[`onClick`])]))),128))])]),_:1},8,[`label`]),c(ve,{dark:``,dense:``,label:e.$t(`createPage.acceptanceCriteria`,{count:Pn.value.length}),"header-class":`text-grey-4 manual-expansion-header`,class:`manual-expansion q-mx-sm q-mb-sm`},{default:o(()=>[p(`div`,dt,[p(`div`,ft,[c(v,{modelValue:In.value,"onUpdate:modelValue":n[7]||=e=>In.value=e,dark:``,dense:``,borderless:``,placeholder:e.$t(`createPage.addCriterion`),class:`col manual-input`,"input-class":`manual-input-inner`,onKeydown:oe(h(Bn,[`prevent`]),[`enter`])},null,8,[`modelValue`,`placeholder`,`onKeydown`]),c(y,{flat:``,dense:``,round:``,icon:`add`,color:`indigo-4`,disable:!In.value.trim(),onClick:Bn},{default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`tooltip.addCriterion`)),1)]),_:1})]),_:1},8,[`disable`])]),(a(!0),s(re,null,t(Pn.value,(t,n)=>(a(),s(`div`,{key:`crit-${n}`,class:`row items-center q-py-xs manual-item`},[p(`span`,pt,l(t),1),c(y,{flat:``,dense:``,round:``,icon:`close`,size:`xs`,color:`grey-6`,onClick:e=>Vn(n)},{default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`tooltip.removeCriterion`)),1)]),_:1})]),_:1},8,[`onClick`])]))),128))])]),_:1},8,[`label`]),c(le,{color:`grey-9`})],64)):u(``,!0),p(`div`,mt,[p(`div`,ht,[nn.value.length>0?(a(),s(`div`,gt,[c(C,{modelValue:B.value,"onUpdate:modelValue":n[8]||=e=>B.value=e,options:nn.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[p(`span`,_t,[c(_,{name:`hub`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),g(` `+l(nn.value.find(e=>e.value===B.value)?.label??B.value)+` `,1),c(_,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`engine.select`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`])])):u(``,!0),p(`div`,vt,[c(C,{modelValue:N.value,"onUpdate:modelValue":n[9]||=e=>N.value=e,options:K.value,dense:``,borderless:``,class:`bottom-select rounded-borders model-select`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[p(`span`,yt,[X.value?(a(),s(`span`,bt,l(e.$t(`autoLoop.executionModelPrefix`)),1)):u(``,!0),g(` `+l(K.value.find(e=>e.value===N.value)?.label??N.value)+` `,1),c(_,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(({opt:e,itemProps:t})=>[c(x,i(t,{class:`model-option`}),{default:o(()=>[c(b,null,{default:o(()=>[c(S,{class:`text-white`},{default:o(()=>[g(l(e.label),1)]),_:2},1024),c(S,{caption:``,class:`text-grey-5`},{default:o(()=>[g(l(e.description),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),default:o(()=>[X.value?(a(),d(w,{key:0},{default:o(()=>[g(l(e.$t(`autoLoop.executionModelTooltip`)),1)]),_:1})):u(``,!0)]),_:1},8,[`modelValue`,`options`])]),p(`div`,xt,[c(C,{modelValue:F.value,"onUpdate:modelValue":n[10]||=e=>F.value=e,options:An.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[p(`span`,St,[c(_,{name:`psychology`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),g(` `+l(An.value.find(e=>e.value===F.value)?.label??F.value)+` `,1),c(_,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(({opt:e,itemProps:t})=>[c(x,se(ce(t)),{default:o(()=>[c(b,null,{default:o(()=>[c(S,{class:`text-white`},{default:o(()=>[g(l(e.label),1)]),_:2},1024),c(S,{caption:``,class:`text-grey-5`},{default:o(()=>[g(l(e.description),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),_:1},8,[`modelValue`,`options`])]),p(`div`,Ct,[c(C,{modelValue:V.value,"onUpdate:modelValue":n[11]||=e=>V.value=e,options:cn.value,disable:X.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`,"option-disable":ye},{selected:o(()=>[p(`span`,wt,[c(_,{name:sn.value,size:`12px`,color:`amber-6`,class:`q-mr-xs`},null,8,[`name`]),g(` `+l(cn.value.find(e=>e.value===V.value)?.label??V.value)+` `,1),X.value?u(``,!0):(a(),d(_,{key:0,name:`expand_more`,size:`12px`,color:`grey-5`}))])]),default:o(()=>[c(w,null,{default:o(()=>[g(l(X.value?e.$t(`agentPermissionMode.autoLoopLocked`):e.$t(`agentPermissionMode.tooltip`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`,`disable`])])]),p(`div`,Tt,[p(`div`,Et,[c(y,{flat:``,dense:``,size:`sm`,"no-caps":``,icon:X.value?`autorenew`:`sync_disabled`,color:X.value?`amber-4`:`grey-5`,label:e.$t(`autoLoop.startInMode`),class:`skip-setup-btn`,onClick:Wn},{default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`autoLoop.startInMode`)),1)]),_:1})]),_:1},8,[`icon`,`color`,`label`])]),X.value?(a(),s(`div`,Dt,[c(xe,{modelValue:Un.value,"onUpdate:modelValue":n[12]||=e=>Un.value=e,dense:``,"no-caps":``,size:`sm`,"toggle-color":`indigo-8`,color:`grey-9`,"text-color":`grey-5`,options:[{label:e.$t(`autoLoop.sessionMode.perTask`),value:`per_task`,icon:`restart_alt`},{label:e.$t(`autoLoop.sessionMode.continuous`),value:`continuous`,icon:`link`}]},{default:o(()=>[c(w,null,{default:o(()=>[g(l(Un.value===`continuous`?e.$t(`autoLoop.sessionMode.continuousTooltip`):e.$t(`autoLoop.sessionMode.perTaskTooltip`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`])])):u(``,!0),X.value?(a(),s(`div`,Ot,[c(C,{modelValue:P.value,"onUpdate:modelValue":n[13]||=e=>P.value=e,options:K.value,dense:``,borderless:``,class:`bottom-select rounded-borders model-select`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[p(`span`,kt,[c(_,{name:`tips_and_updates`,size:`12px`,color:`amber-6`,class:`q-mr-xs`}),p(`span`,At,l(e.$t(`autoLoop.brainstormModelPrefix`)),1),g(` `+l(K.value.find(e=>e.value===P.value)?.label??P.value)+` `,1),c(_,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(({opt:e,itemProps:t})=>[c(x,i(t,{class:`model-option`}),{default:o(()=>[c(b,null,{default:o(()=>[c(S,{class:`text-white`},{default:o(()=>[g(l(e.label),1)]),_:2},1024),c(S,{caption:``,class:`text-grey-5`},{default:o(()=>[g(l(e.description),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`autoLoop.brainstormModelTooltip`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`])])):u(``,!0)]),p(`div`,jt,[p(`div`,Mt,[c(y,{flat:``,dense:``,size:`sm`,"no-caps":``,icon:z.value?`play_disabled`:`play_circle`,color:z.value?`orange-4`:`grey-5`,label:e.$t(`createPage.skipSetupScript`),class:`skip-setup-btn`,onClick:n[14]||=e=>z.value=!z.value},{default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`createPage.skipSetupScript`)),1)]),_:1})]),_:1},8,[`icon`,`color`,`label`])]),p(`div`,Nt,[c(y,{flat:``,dense:``,size:`sm`,"no-caps":``,icon:`folder_open`,color:Q.value?`cyan-4`:`grey-5`,label:Q.value?e.$t(`createPage.attachWorktreeEnabled`):e.$t(`createPage.attachWorktreeToggle`),class:`skip-setup-btn`,onClick:Xn},null,8,[`color`,`label`])])]),p(`div`,Pt,[p(`div`,Ft,[c(C,{modelValue:I.value,"onUpdate:modelValue":n[15]||=e=>I.value=e,options:Gt.value,dense:``,borderless:``,"use-input":``,"fill-input":``,"hide-selected":``,"input-debounce":`0`,"new-value-mode":`add`,class:`bottom-select rounded-borders repo-select`,"hide-dropdown-icon":``,"input-class":I.value?``:`repo-input-empty`,placeholder:e.$t(`createPage.projectPath`),behavior:f(E).projectPaths.length>0?`menu`:`dialog`,"option-label":e=>e?f(Se)(e):``,onFilter:er,onInputValue:tr},{prepend:o(()=>[c(_,{name:`folder`,size:`14px`,color:`grey-5`})]),option:o(({opt:e,itemProps:t})=>[c(x,se(ce(t)),{default:o(()=>[c(b,null,{default:o(()=>[c(S,null,{default:o(()=>[g(l(f(Se)(e)),1)]),_:2},1024),c(S,{caption:``},{default:o(()=>[g(l(e),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),"no-option":o(()=>[c(x,null,{default:o(()=>[c(b,{class:`text-grey-6 text-caption`},{default:o(()=>[g(l(e.$t(`createPage.enterPath`)),1)]),_:1})]),_:1})]),_:1},8,[`modelValue`,`options`,`input-class`,`placeholder`,`behavior`,`option-label`])]),Q.value?u(``,!0):(a(),s(`div`,It,[c(C,{modelValue:R.value,"onUpdate:modelValue":n[16]||=e=>R.value=e,options:rn.value,"emit-value":``,"map-options":``,dense:``,borderless:``,class:`bottom-select rounded-borders branch-type-select`,"hide-dropdown-icon":``},{selected:o(()=>[p(`span`,Lt,[c(_,{name:`account_tree`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),g(` `+l(R.value)+`/ `,1),c(_,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[c(w,null,{default:o(()=>[g(l(e.$t(`createPage.branchType`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`])])),Q.value?(a(),s(`div`,Rt,[c(C,{modelValue:$.value,"onUpdate:modelValue":n[17]||=e=>$.value=e,options:qn.value,"option-label":`branch`,"option-value":`path`,"emit-value":``,"map-options":``,"use-input":``,dense:``,borderless:``,class:`bottom-select rounded-borders worktree-select`,"hide-dropdown-icon":``,loading:Jn.value,disable:!I.value.trim()||Jn.value},{selected:o(()=>[p(`span`,zt,[c(_,{name:`folder_open`,size:`12px`,color:`cyan-5`,class:`q-mr-xs`}),g(` `+l($.value?qn.value.find(e=>e.path===$.value)?.branch??$.value:e.$t(`createPage.worktreePickerLabel`))+` `,1),c(_,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(e=>[c(x,se(ce(e.itemProps)),{default:o(()=>[c(b,null,{default:o(()=>[c(S,null,{default:o(()=>[g(l(e.opt.branch),1)]),_:2},1024),c(S,{caption:``},{default:o(()=>[g(l(e.opt.path),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),"no-option":o(()=>[c(x,null,{default:o(()=>[c(b,{class:`text-grey-6 text-caption`},{default:o(()=>[g(l(I.value.trim()?e.$t(`createPage.noOrphanWorktrees`):e.$t(`createPage.enterPath`)),1)]),_:1})]),_:1})]),_:1},8,[`modelValue`,`options`,`loading`,`disable`])])):u(``,!0),p(`div`,Bt,[c(C,{modelValue:L.value,"onUpdate:modelValue":n[18]||=e=>L.value=e,options:ln.value,dense:``,borderless:``,class:`bottom-select rounded-borders branch-select`,"hide-dropdown-icon":``,"use-input":``,"input-debounce":`0`,loading:un.value,disable:!I.value.trim()||un.value,onFilter:fn},{selected:o(()=>[p(`span`,Vt,[c(_,{name:`call_split`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),g(` `+l(L.value??e.$t(`createPage.branch`))+` `,1),c(_,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),"no-option":o(()=>[c(x,null,{default:o(()=>[c(b,{class:`text-grey-6 text-caption`},{default:o(()=>[g(l(I.value.trim()?e.$t(`createPage.noBranches`):e.$t(`createPage.enterPath`)),1)]),_:1})]),_:1})]),_:1},8,[`modelValue`,`options`,`loading`,`disable`])])])]),p(`div`,Ht,[c(y,{label:e.$t(`createPage.create`),"no-caps":``,unelevated:``,class:`create-btn text-weight-bold rounded-borders`,loading:dn.value,disable:dn.value||Q.value&&!$.value,onClick:or},null,8,[`label`,`loading`,`disable`])])]),p(`div`,Ut,l(M.value?e.$t(`createPage.notionExtractHint`):e.$t(`createPage.notionImportHint`)),1)])]),_:1}))}}),[[`__scopeId`,`data-v-0767cd07`]]);export{E as default};
|