@loicngr/kobo 1.6.6 → 1.6.8
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/dist/server/db/migrations.js +13 -0
- package/dist/server/db/schema.js +8 -0
- package/dist/server/index.js +3 -1
- package/dist/server/routes/workspaces.js +45 -0
- package/dist/server/services/agent/orchestrator.js +18 -0
- package/dist/server/services/pr-watcher-service.js +14 -0
- package/dist/server/services/wakeup-service.js +154 -0
- package/dist/server/services/workspace-service.js +7 -0
- package/package.json +1 -1
- package/src/client/dist/spa/assets/{ActivityFeed-BmGNYNux.js → ActivityFeed-Bn9tpyLw.js} +1 -1
- package/src/client/dist/spa/assets/{CreatePage-BC4P1Xq2.js → CreatePage-DDPmb3I-.js} +1 -1
- package/src/client/dist/spa/assets/{DiffViewer-C6d1h3-o.js → DiffViewer-CM3g7W7U.js} +2 -2
- package/src/client/dist/spa/assets/{HealthPage-usVzGjv-.js → HealthPage-BNv_dnMz.js} +1 -1
- package/src/client/dist/spa/assets/{MainLayout-BAimmdFy.css → MainLayout-BeKCjOA2.css} +1 -1
- package/src/client/dist/spa/assets/{MainLayout-DcltT6j8.js → MainLayout-NzuypipH.js} +16 -16
- package/src/client/dist/spa/assets/{SearchPage-DqVwM-Nw.js → SearchPage-B3m_OWli.js} +1 -1
- package/src/client/dist/spa/assets/{SettingsPage-BKKAIJXH.js → SettingsPage-CpQm15XA.js} +1 -1
- package/src/client/dist/spa/assets/WorkspacePage-BQzk5qfr.js +4 -0
- package/src/client/dist/spa/assets/{WorkspacePage-BIquds-p.css → WorkspacePage-CM676R3B.css} +1 -1
- package/src/client/dist/spa/assets/{build-path-tree-BaiH1Val.js → build-path-tree-DOPXkGhj.js} +1 -1
- package/src/client/dist/spa/assets/{cssMode-DV77SXAp.js → cssMode-BPObkLMQ.js} +1 -1
- package/src/client/dist/spa/assets/{documents-DLpLMq-0.js → documents-DMvdjtPf.js} +1 -1
- package/src/client/dist/spa/assets/{editor.api-BGhylbsn.js → editor.api-BpCtstKS.js} +1 -1
- package/src/client/dist/spa/assets/{editor.main-qZAJW6DY.js → editor.main-C2h6FfOt.js} +3 -3
- package/src/client/dist/spa/assets/{freemarker2-BKAXCv8N.js → freemarker2-DUmHGv4C.js} +1 -1
- package/src/client/dist/spa/assets/{handlebars-v0nKPEWi.js → handlebars-BU6pjzPg.js} +1 -1
- package/src/client/dist/spa/assets/{html-BRupIzA4.js → html-A5-15bWl.js} +1 -1
- package/src/client/dist/spa/assets/{htmlMode-BihW-P2O.js → htmlMode-C3KkomG3.js} +1 -1
- package/src/client/dist/spa/assets/i18n-CIduhxS0.js +1 -0
- package/src/client/dist/spa/assets/index-QcUb2Iwh.js +2 -0
- package/src/client/dist/spa/assets/{javascript-BJDZ_NcB.js → javascript-ggaOKiy5.js} +1 -1
- package/src/client/dist/spa/assets/{jsonMode-C9JdqFNv.js → jsonMode-Bk-QMPGJ.js} +1 -1
- package/src/client/dist/spa/assets/{liquid-Lk-oZkkL.js → liquid-CJdzn-JB.js} +1 -1
- package/src/client/dist/spa/assets/{mdx-DXTW2dI0.js → mdx-D5wRO-st.js} +1 -1
- package/src/client/dist/spa/assets/{models-D_Rq_B4d.js → models-CwWSex3X.js} +1 -1
- package/src/client/dist/spa/assets/{monaco.contribution-sDg_eF3E.js → monaco.contribution-CPqJifAu.js} +2 -2
- package/src/client/dist/spa/assets/{python-DWz3NVjv.js → python-DHI9rQDm.js} +1 -1
- package/src/client/dist/spa/assets/{razor-BwkYCkDS.js → razor-CzQWNzhW.js} +1 -1
- package/src/client/dist/spa/assets/{tsMode-C0izvBnL.js → tsMode-DPkpdkNr.js} +1 -1
- package/src/client/dist/spa/assets/{typescript-CKsF3o2F.js → typescript-Dgm0x_-O.js} +1 -1
- package/src/client/dist/spa/assets/{xml-D2KHAqfG.js → xml-BeXyffrj.js} +1 -1
- package/src/client/dist/spa/assets/{yaml-Bh60Z-Sr.js → yaml-D4UE_1wU.js} +1 -1
- package/src/client/dist/spa/index.html +1 -1
- package/src/client/dist/spa/assets/WorkspacePage-B-iEkrN1.js +0 -4
- package/src/client/dist/spa/assets/i18n-B4u2URrK.js +0 -1
- package/src/client/dist/spa/assets/index-CDTpNA2L.js +0 -2
|
@@ -88,6 +88,19 @@ export const migrations = [
|
|
|
88
88
|
})();
|
|
89
89
|
},
|
|
90
90
|
},
|
|
91
|
+
{
|
|
92
|
+
version: 11,
|
|
93
|
+
name: 'add-pending-wakeups-table',
|
|
94
|
+
migrate: (db) => {
|
|
95
|
+
db.prepare(`CREATE TABLE IF NOT EXISTS pending_wakeups (
|
|
96
|
+
workspace_id TEXT PRIMARY KEY REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
97
|
+
target_at TEXT NOT NULL,
|
|
98
|
+
prompt TEXT NOT NULL,
|
|
99
|
+
reason TEXT,
|
|
100
|
+
created_at TEXT NOT NULL
|
|
101
|
+
)`).run();
|
|
102
|
+
},
|
|
103
|
+
},
|
|
91
104
|
];
|
|
92
105
|
/** Current schema version — always equals the highest migration version. */
|
|
93
106
|
export const SCHEMA_VERSION = migrations.length > 0 ? migrations[migrations.length - 1].version : 1;
|
package/dist/server/db/schema.js
CHANGED
|
@@ -54,6 +54,14 @@ export function initSchema(db) {
|
|
|
54
54
|
created_at TEXT NOT NULL
|
|
55
55
|
);
|
|
56
56
|
|
|
57
|
+
CREATE TABLE IF NOT EXISTS pending_wakeups (
|
|
58
|
+
workspace_id TEXT PRIMARY KEY REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
59
|
+
target_at TEXT NOT NULL,
|
|
60
|
+
prompt TEXT NOT NULL,
|
|
61
|
+
reason TEXT,
|
|
62
|
+
created_at TEXT NOT NULL
|
|
63
|
+
);
|
|
64
|
+
|
|
57
65
|
CREATE INDEX IF NOT EXISTS idx_tasks_workspace_id ON tasks(workspace_id);
|
|
58
66
|
CREATE INDEX IF NOT EXISTS idx_agent_sessions_workspace_id ON agent_sessions(workspace_id);
|
|
59
67
|
CREATE INDEX IF NOT EXISTS idx_ws_events_workspace_id ON ws_events(workspace_id);
|
package/dist/server/index.js
CHANGED
|
@@ -26,6 +26,7 @@ import { createDailyDbBackupIfNeeded } from './services/db-backup-service.js';
|
|
|
26
26
|
import { startDevServer, stopDevServer } from './services/dev-server-service.js';
|
|
27
27
|
import { startPrWatcher, stopPrWatcher } from './services/pr-watcher-service.js';
|
|
28
28
|
import { createTerminal, destroyAllTerminals, getTerminal } from './services/terminal-service.js';
|
|
29
|
+
import * as wakeupService from './services/wakeup-service.js';
|
|
29
30
|
import { emit, handleConnection, setMessageHandler } from './services/websocket-service.js';
|
|
30
31
|
import { getActiveSession, getWorkspace, updateWorkspaceStatus } from './services/workspace-service.js';
|
|
31
32
|
import { getClientSpaPath, getDbPath, getKoboHome, getPackageVersion } from './utils/paths.js';
|
|
@@ -53,10 +54,11 @@ void createDailyDbBackupIfNeeded(db, getDbPath()).then((r) => {
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
});
|
|
56
|
-
// Initialize process cleanup, agent watchdog, and
|
|
57
|
+
// Initialize process cleanup, agent watchdog, PR watcher, and wakeup rehydration
|
|
57
58
|
initProcessCleanup();
|
|
58
59
|
reconcileOrphanSessions();
|
|
59
60
|
startWatchdog();
|
|
61
|
+
wakeupService.rehydrate();
|
|
60
62
|
startPrWatcher();
|
|
61
63
|
// Create Hono app
|
|
62
64
|
const app = new Hono();
|
|
@@ -11,10 +11,12 @@ import * as agentManager from '../services/agent/orchestrator.js';
|
|
|
11
11
|
import * as devServerService from '../services/dev-server-service.js';
|
|
12
12
|
import * as notionService from '../services/notion-service.js';
|
|
13
13
|
import { renderPrTemplate } from '../services/pr-template-service.js';
|
|
14
|
+
import { getAllPrStates } from '../services/pr-watcher-service.js';
|
|
14
15
|
import * as sentryService from '../services/sentry-service.js';
|
|
15
16
|
import * as settingsService from '../services/settings-service.js';
|
|
16
17
|
import { runSetupScript } from '../services/setup-script-service.js';
|
|
17
18
|
import * as terminalService from '../services/terminal-service.js';
|
|
19
|
+
import * as wakeupService from '../services/wakeup-service.js';
|
|
18
20
|
import * as wsService from '../services/websocket-service.js';
|
|
19
21
|
import * as workspaceService from '../services/workspace-service.js';
|
|
20
22
|
import * as worktreeService from '../services/worktree-service.js';
|
|
@@ -515,6 +517,44 @@ app.get('/:id/sessions', (c) => {
|
|
|
515
517
|
return c.json({ error: message }, 500);
|
|
516
518
|
}
|
|
517
519
|
});
|
|
520
|
+
// GET /api/workspaces/pr-states — batch snapshot of PR states known to the
|
|
521
|
+
// pr-watcher service, keyed by workspace id. Used by the drawer to show a
|
|
522
|
+
// small PR indicator without N separate `gh pr view` calls. Workspaces
|
|
523
|
+
// without a PR are absent from the response (do NOT assume keys are
|
|
524
|
+
// exhaustive over the workspace list).
|
|
525
|
+
app.get('/pr-states', (c) => {
|
|
526
|
+
try {
|
|
527
|
+
return c.json(getAllPrStates());
|
|
528
|
+
}
|
|
529
|
+
catch (err) {
|
|
530
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
531
|
+
return c.json({ error: message }, 500);
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
// GET /api/workspaces/:id/pending-wakeup — returns the pending wakeup or null.
|
|
535
|
+
app.get('/:id/pending-wakeup', (c) => {
|
|
536
|
+
try {
|
|
537
|
+
const id = c.req.param('id');
|
|
538
|
+
const pending = wakeupService.getPending(id);
|
|
539
|
+
return c.json(pending);
|
|
540
|
+
}
|
|
541
|
+
catch (err) {
|
|
542
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
543
|
+
return c.json({ error: message }, 500);
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
// DELETE /api/workspaces/:id/pending-wakeup — user-initiated cancel ("×" button).
|
|
547
|
+
app.delete('/:id/pending-wakeup', (c) => {
|
|
548
|
+
try {
|
|
549
|
+
const id = c.req.param('id');
|
|
550
|
+
wakeupService.cancel(id, 'manual');
|
|
551
|
+
return c.json({ ok: true });
|
|
552
|
+
}
|
|
553
|
+
catch (err) {
|
|
554
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
555
|
+
return c.json({ error: message }, 500);
|
|
556
|
+
}
|
|
557
|
+
});
|
|
518
558
|
// PATCH /api/workspaces/:id/sessions/:sessionId — rename a session
|
|
519
559
|
app.patch('/:id/sessions/:sessionId', async (c) => {
|
|
520
560
|
try {
|
|
@@ -1481,6 +1521,9 @@ Start now.`;
|
|
|
1481
1521
|
// Persist the prompt in the chat feed so the user sees what was dispatched.
|
|
1482
1522
|
const session = workspaceService.getActiveSession(workspace.id);
|
|
1483
1523
|
wsService.emit(workspace.id, 'user:message', { content: prompt, sender: 'user' }, session?.id ?? undefined);
|
|
1524
|
+
// Cancel any pending wakeup: the user is driving this turn, the
|
|
1525
|
+
// scheduler should not also wake the agent a few minutes later.
|
|
1526
|
+
wakeupService.cancel(workspace.id, 'user-message');
|
|
1484
1527
|
let messageSent = false;
|
|
1485
1528
|
try {
|
|
1486
1529
|
agentManager.sendMessage(workspace.id, prompt);
|
|
@@ -1615,6 +1658,8 @@ app.post('/:id/open-pr', async (c) => {
|
|
|
1615
1658
|
// Emit user:message into the chat feed
|
|
1616
1659
|
const session = workspaceService.getActiveSession(workspace.id);
|
|
1617
1660
|
wsService.emit(workspace.id, 'user:message', { content: rendered, sender: 'user' }, session?.id ?? undefined);
|
|
1661
|
+
// Cancel any pending wakeup: the user is driving this turn.
|
|
1662
|
+
wakeupService.cancel(workspace.id, 'user-message');
|
|
1618
1663
|
// Send to the running agent, or resume the agent with the PR prompt
|
|
1619
1664
|
let messageSent = false;
|
|
1620
1665
|
try {
|
|
@@ -4,6 +4,7 @@ import { getDb } from '../../db/index.js';
|
|
|
4
4
|
import { ensureKoboHome, getCompiledMcpServerPath, getDbPath, getKoboHome, getMcpServerSourcePath, getSettingsPath, getSkillsPath, } from '../../utils/paths.js';
|
|
5
5
|
import { unregisterProcess } from '../../utils/process-tracker.js';
|
|
6
6
|
import { getEffectiveSettings } from '../settings-service.js';
|
|
7
|
+
import * as wakeupService from '../wakeup-service.js';
|
|
7
8
|
import { emitEphemeral } from '../websocket-service.js';
|
|
8
9
|
import { getWorkspace as getWs, markWorkspaceUnread, updateWorkspaceStatus } from '../workspace-service.js';
|
|
9
10
|
import { resolveEngine } from './engines/registry.js';
|
|
@@ -252,6 +253,15 @@ function reuseOrCreateFreshSession(workspaceId, existingSessionId) {
|
|
|
252
253
|
// ── Event handler ─────────────────────────────────────────────────────────────
|
|
253
254
|
function handleEvent(workspaceId, agentSessionId, ev) {
|
|
254
255
|
routeEvent(workspaceId, agentSessionId, ev);
|
|
256
|
+
if (ev.kind === 'tool:call' && ev.name === 'ScheduleWakeup') {
|
|
257
|
+
const input = ev.input;
|
|
258
|
+
const delay = typeof input?.delaySeconds === 'number' ? input.delaySeconds : 0;
|
|
259
|
+
const prompt = typeof input?.prompt === 'string' ? input.prompt : '';
|
|
260
|
+
const reason = typeof input?.reason === 'string' ? input.reason : undefined;
|
|
261
|
+
if (delay > 0 && prompt) {
|
|
262
|
+
wakeupService.schedule(workspaceId, delay, prompt, reason);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
255
265
|
if (ev.kind === 'skills:discovered') {
|
|
256
266
|
availableSkills = ev.skills;
|
|
257
267
|
try {
|
|
@@ -470,6 +480,7 @@ export function stopAgent(workspaceId) {
|
|
|
470
480
|
if (!ctrl) {
|
|
471
481
|
throw new Error(`No agent running for workspace '${workspaceId}'`);
|
|
472
482
|
}
|
|
483
|
+
wakeupService.cancel(workspaceId, 'stopped');
|
|
473
484
|
// Remove from the map immediately so startAgent can proceed right away.
|
|
474
485
|
// The session:ended handler checks identity before removing, so a new
|
|
475
486
|
// controller started in the meantime is preserved.
|
|
@@ -490,12 +501,17 @@ export function sendMessage(workspaceId, content) {
|
|
|
490
501
|
if (!ctrl) {
|
|
491
502
|
throw new Error(`No agent running for workspace '${workspaceId}'`);
|
|
492
503
|
}
|
|
504
|
+
wakeupService.cancel(workspaceId, 'user-message');
|
|
493
505
|
ctrl.sendMessage(content);
|
|
494
506
|
}
|
|
495
507
|
/** In-memory status of the agent for a workspace, or null if not running. */
|
|
496
508
|
export function getAgentStatus(workspaceId) {
|
|
497
509
|
return controllers.get(workspaceId)?.status ?? null;
|
|
498
510
|
}
|
|
511
|
+
/** True when an agent controller is currently running for the workspace. */
|
|
512
|
+
export function hasController(workspaceId) {
|
|
513
|
+
return controllers.has(workspaceId);
|
|
514
|
+
}
|
|
499
515
|
/** Number of currently running controllers. */
|
|
500
516
|
export function getRunningCount() {
|
|
501
517
|
return controllers.size;
|
|
@@ -580,3 +596,5 @@ export function _getSessionIds() {
|
|
|
580
596
|
export function _runWatchdogForTest() {
|
|
581
597
|
runWatchdog();
|
|
582
598
|
}
|
|
599
|
+
/** Test-only export. Not part of the public module API. */
|
|
600
|
+
export const __test__ = { handleEvent };
|
|
@@ -16,6 +16,20 @@ let timer = null;
|
|
|
16
16
|
let checking = false;
|
|
17
17
|
/** Tracks the last known PR state per workspace to detect transitions. */
|
|
18
18
|
const lastKnownState = new Map();
|
|
19
|
+
/**
|
|
20
|
+
* Read-only snapshot of PR states known to the watcher, keyed by workspace id.
|
|
21
|
+
* Used by the drawer to show a small PR-open indicator without N separate
|
|
22
|
+
* `gh pr view` calls per workspace. Only contains entries where a PR has been
|
|
23
|
+
* detected at least once by the watcher since boot; workspaces without a PR
|
|
24
|
+
* are absent from the map.
|
|
25
|
+
*/
|
|
26
|
+
export function getAllPrStates() {
|
|
27
|
+
const out = {};
|
|
28
|
+
for (const [id, state] of lastKnownState) {
|
|
29
|
+
out[id] = state;
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
19
33
|
async function checkPrStatuses() {
|
|
20
34
|
const workspaces = listWorkspaces(false); // non-archived only
|
|
21
35
|
// Clean up entries for workspaces that no longer exist
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getDb } from '../db/index.js';
|
|
3
|
+
import * as orchestrator from './agent/orchestrator.js';
|
|
4
|
+
import { emitEphemeral } from './websocket-service.js';
|
|
5
|
+
const MIN_DELAY_SECONDS = 60;
|
|
6
|
+
const MAX_DELAY_SECONDS = 3600;
|
|
7
|
+
const STALE_WAKEUP_GRACE_MS = 5 * 60 * 1000;
|
|
8
|
+
const AUTONOMOUS_LOOP_SENTINEL = '<<autonomous-loop-dynamic>>';
|
|
9
|
+
const AUTONOMOUS_LOOP_FALLBACK_PROMPT = 'Continue where you left off.';
|
|
10
|
+
/** In-memory timers — cleared on cancel/fire; rebuilt on boot via rehydrate. */
|
|
11
|
+
const timers = new Map();
|
|
12
|
+
function clamp(n, lo, hi) {
|
|
13
|
+
return Math.max(lo, Math.min(hi, n));
|
|
14
|
+
}
|
|
15
|
+
function rowToPending(row) {
|
|
16
|
+
if (!row)
|
|
17
|
+
return null;
|
|
18
|
+
return { targetAt: row.target_at, reason: row.reason ?? undefined };
|
|
19
|
+
}
|
|
20
|
+
/** Schedule a wakeup for the given workspace. Replaces any existing pending wakeup. */
|
|
21
|
+
export function schedule(workspaceId, delaySeconds, prompt, reason) {
|
|
22
|
+
try {
|
|
23
|
+
const clampedSeconds = clamp(Math.floor(delaySeconds), MIN_DELAY_SECONDS, MAX_DELAY_SECONDS);
|
|
24
|
+
const effectivePrompt = prompt === AUTONOMOUS_LOOP_SENTINEL ? AUTONOMOUS_LOOP_FALLBACK_PROMPT : prompt;
|
|
25
|
+
const targetAtIso = new Date(Date.now() + clampedSeconds * 1000).toISOString();
|
|
26
|
+
const existing = timers.get(workspaceId);
|
|
27
|
+
if (existing)
|
|
28
|
+
clearTimeout(existing);
|
|
29
|
+
const db = getDb();
|
|
30
|
+
db.prepare(`INSERT OR REPLACE INTO pending_wakeups
|
|
31
|
+
(workspace_id, target_at, prompt, reason, created_at)
|
|
32
|
+
VALUES (?, ?, ?, ?, ?)`).run(workspaceId, targetAtIso, effectivePrompt, reason ?? null, new Date().toISOString());
|
|
33
|
+
const timeout = setTimeout(() => fire(workspaceId), clampedSeconds * 1000);
|
|
34
|
+
timeout.unref?.();
|
|
35
|
+
timers.set(workspaceId, timeout);
|
|
36
|
+
emitEphemeral(workspaceId, 'wakeup:scheduled', { targetAt: targetAtIso, reason });
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
console.error('[wakeup-service] schedule failed:', err);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Cancel any pending wakeup for the workspace. Idempotent. */
|
|
43
|
+
export function cancel(workspaceId, reason) {
|
|
44
|
+
try {
|
|
45
|
+
const existing = timers.get(workspaceId);
|
|
46
|
+
if (existing) {
|
|
47
|
+
clearTimeout(existing);
|
|
48
|
+
timers.delete(workspaceId);
|
|
49
|
+
}
|
|
50
|
+
const db = getDb();
|
|
51
|
+
const result = db.prepare('DELETE FROM pending_wakeups WHERE workspace_id = ?').run(workspaceId);
|
|
52
|
+
if (result.changes > 0) {
|
|
53
|
+
emitEphemeral(workspaceId, 'wakeup:cancelled', { reason });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
console.error('[wakeup-service] cancel failed:', err);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** Return the current pending wakeup for a workspace, or null if none. */
|
|
61
|
+
export function getPending(workspaceId) {
|
|
62
|
+
try {
|
|
63
|
+
const db = getDb();
|
|
64
|
+
const row = db.prepare('SELECT * FROM pending_wakeups WHERE workspace_id = ?').get(workspaceId);
|
|
65
|
+
return rowToPending(row);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.error('[wakeup-service] getPending failed:', err);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Re-register timers for rows persisted across restart. Skips stale entries. */
|
|
73
|
+
export function rehydrate() {
|
|
74
|
+
try {
|
|
75
|
+
const db = getDb();
|
|
76
|
+
const rows = db.prepare('SELECT * FROM pending_wakeups').all();
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
for (const row of rows) {
|
|
79
|
+
try {
|
|
80
|
+
const target = new Date(row.target_at).getTime();
|
|
81
|
+
const delay = target - now;
|
|
82
|
+
if (delay > 0) {
|
|
83
|
+
const timeout = setTimeout(() => fire(row.workspace_id), delay);
|
|
84
|
+
timeout.unref?.();
|
|
85
|
+
timers.set(row.workspace_id, timeout);
|
|
86
|
+
}
|
|
87
|
+
else if (-delay <= STALE_WAKEUP_GRACE_MS) {
|
|
88
|
+
const timeout = setTimeout(() => fire(row.workspace_id), 0);
|
|
89
|
+
timeout.unref?.();
|
|
90
|
+
timers.set(row.workspace_id, timeout);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
db.prepare('DELETE FROM pending_wakeups WHERE workspace_id = ?').run(row.workspace_id);
|
|
94
|
+
console.log(`[wakeup-service] Skipping stale wakeup for workspace ${row.workspace_id} (late by ${Math.round(-delay / 1000)}s)`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
console.error('[wakeup-service] rehydrate row failed:', row.workspace_id, err);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
console.error('[wakeup-service] rehydrate failed:', err);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Internal — invoked by setTimeout. */
|
|
107
|
+
function fire(workspaceId) {
|
|
108
|
+
try {
|
|
109
|
+
const db = getDb();
|
|
110
|
+
// Atomic claim: SELECT + DELETE in a single transaction so a concurrent
|
|
111
|
+
// cancel() can't race us between the read and the act. If we come out
|
|
112
|
+
// with a row, it's ours exclusively; no other caller will ever see it.
|
|
113
|
+
const row = db.transaction(() => {
|
|
114
|
+
const r = db.prepare('SELECT * FROM pending_wakeups WHERE workspace_id = ?').get(workspaceId);
|
|
115
|
+
if (r) {
|
|
116
|
+
db.prepare('DELETE FROM pending_wakeups WHERE workspace_id = ?').run(workspaceId);
|
|
117
|
+
}
|
|
118
|
+
return r;
|
|
119
|
+
})();
|
|
120
|
+
timers.delete(workspaceId);
|
|
121
|
+
if (!row)
|
|
122
|
+
return;
|
|
123
|
+
if (orchestrator.hasController(workspaceId)) {
|
|
124
|
+
emitEphemeral(workspaceId, 'wakeup:skipped', { reason: 'session-active' });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const wsRow = db
|
|
128
|
+
.prepare(`SELECT project_path, working_branch, model, permission_mode, reasoning_effort
|
|
129
|
+
FROM workspaces WHERE id = ?`)
|
|
130
|
+
.get(workspaceId);
|
|
131
|
+
if (!wsRow) {
|
|
132
|
+
emitEphemeral(workspaceId, 'wakeup:skipped', { reason: 'fire-failed' });
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const worktreePath = path.join(wsRow.project_path, '.worktrees', wsRow.working_branch);
|
|
136
|
+
// Defensive: narrow `permission_mode` against the two known values rather
|
|
137
|
+
// than trusting the DB column shape. Any unexpected value falls back to
|
|
138
|
+
// the safer 'auto-accept'.
|
|
139
|
+
const permissionMode = wsRow.permission_mode === 'plan' ? 'plan' : 'auto-accept';
|
|
140
|
+
try {
|
|
141
|
+
orchestrator.startAgent(workspaceId, worktreePath, row.prompt, wsRow.model, true, permissionMode, undefined, wsRow.reasoning_effort);
|
|
142
|
+
emitEphemeral(workspaceId, 'wakeup:fired', {});
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
146
|
+
console.error(`[wakeup-service] startAgent at fire time failed for '${workspaceId}':`, message);
|
|
147
|
+
emitEphemeral(workspaceId, 'wakeup:skipped', { reason: 'fire-failed' });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
console.error('[wakeup-service] fire failed:', err);
|
|
152
|
+
timers.delete(workspaceId);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { nanoid } from 'nanoid';
|
|
2
2
|
import { getDb } from '../db/index.js';
|
|
3
|
+
import * as wakeupService from './wakeup-service.js';
|
|
3
4
|
/** Allowed status transitions per current status. Enforced by updateWorkspaceStatus. */
|
|
4
5
|
const VALID_TRANSITIONS = {
|
|
5
6
|
created: ['extracting', 'brainstorming', 'idle', 'error'],
|
|
@@ -208,6 +209,10 @@ export function markWorkspaceUnread(id) {
|
|
|
208
209
|
}
|
|
209
210
|
/** Delete a workspace and cascade-delete its tasks. */
|
|
210
211
|
export function deleteWorkspace(id) {
|
|
212
|
+
// Cancel any pending wakeup first so the in-memory timer is cleared.
|
|
213
|
+
// The DB row is removed via ON DELETE CASCADE, but the timer would
|
|
214
|
+
// otherwise fire and hit an empty workspace.
|
|
215
|
+
wakeupService.cancel(id, 'deleted');
|
|
211
216
|
const db = getDb();
|
|
212
217
|
db.prepare('DELETE FROM workspaces WHERE id = ?').run(id);
|
|
213
218
|
}
|
|
@@ -289,6 +294,8 @@ export function archiveWorkspace(id) {
|
|
|
289
294
|
if (workspace.archivedAt) {
|
|
290
295
|
throw new Error(`Workspace '${id}' is already archived`);
|
|
291
296
|
}
|
|
297
|
+
// Cancel any pending wakeup — archived workspaces should not wake up.
|
|
298
|
+
wakeupService.cancel(id, 'archived');
|
|
292
299
|
const now = new Date().toISOString();
|
|
293
300
|
db.prepare('UPDATE workspaces SET archived_at = ?, updated_at = ? WHERE id = ?').run(now, now, id);
|
|
294
301
|
return getWorkspace(id);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loicngr/kobo",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
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{E as e,F as t,H as n,L as r,M as i,Q as a,U as o,_t as s,bt as c,d as l,f as u,g as d,h as f,l as p,p as m,r as h,rt as g,u as _,v,yt as y}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{L as b,l as x,t as S}from"./QIcon-B0-pH3Qs.js";import{t as C}from"./QBtn-CyzfM9-_.js";import{n as w}from"./vue-i18n-eUDnMrPl.js";import{C as T,S as E,b as D,v as O}from"./index-
|
|
1
|
+
import{E as e,F as t,H as n,L as r,M as i,Q as a,U as o,_t as s,bt as c,d as l,f as u,g as d,h as f,l as p,p as m,r as h,rt as g,u as _,v,yt as y}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{L as b,l as x,t as S}from"./QIcon-B0-pH3Qs.js";import{t as C}from"./QBtn-CyzfM9-_.js";import{n as w}from"./vue-i18n-eUDnMrPl.js";import{C as T,S as E,b as D,v as O}from"./index-QcUb2Iwh.js";import{t as k}from"./QSpinnerDots-By20ptst.js";import{t as A}from"./QExpansionItem-HLBjHx-0.js";import{t as j}from"./QScrollArea-CBW6shMb.js";import{t as M}from"./QTooltip-DbEBexRN.js";import{n as N,r as P,t as F}from"./documents-DMvdjtPf.js";import{t as I}from"./_plugin-vue_export-helper-Cj6tcsj6.js";function ee(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:brainstorm-complete`: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 te(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}function L(e){switch(e.type){case`user`:return e.sender===`system-prompt`?`system-prompt`:`user`;case`session`:return`session`;default:return`agent`}}function ne(e){let t=[],n=null;for(let r of e){let e=L(r),i=e===`session`||e===`system-prompt`;!n||n.speaker!==e||i?(n={speaker:e,ts:r.ts,items:[r]},t.push(n),i&&(n=null)):n.items.push(r)}return t}var R={class:`text-caption text-grey-6`},z=v({__name:`SessionEventItem`,props:{item:{}},setup(e){let n=e,r=p(()=>{switch(n.item.kind){case`started`:return`session.started`;case`ended`:return`session.ended`;case`compacted`:return`session.compacted`;default:return`session.started`}});return(e,n)=>(t(),m(`span`,R,c(e.$t(r.value)),1))}});function B(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){V(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 V(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=H(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 H(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 U=[`innerHTML`],W=I(v({__name:`TextMessageItem`,props:{item:{}},setup(e){let n=e,r=F(),i=O(),a=p(()=>{let e=i.selectedWorkspaceId;return e?r.documentsFor(e).map(e=>e.path):[]}),o=p(()=>{let e=B(N.parse(n.item.text,{async:!1,breaks:!0,gfm:!0}),a.value);return P.sanitize(e,{ADD_ATTR:[`data-document-path`]})});function s(e){let t=e.target?.closest(`.document-link`);if(!t)return;e.preventDefault();let n=t.getAttribute(`data-document-path`),a=i.selectedWorkspaceId;!n||!a||r.openDocumentByPath(a,n)}return(n,r)=>(t(),m(`div`,{class:`markdown-message`,onClick:s},[_(`div`,{innerHTML:o.value},null,8,U),e.item.streaming?(t(),l(x,{key:0,size:`xs`,class:`q-ml-xs`})):u(``,!0)]))}}),[[`__scopeId`,`data-v-0ac5a3e4`]]),G={key:0,class:`text-caption text-grey-5`,style:{"font-style":`italic`}},K=[`innerHTML`],q={key:1,style:{"white-space":`pre-wrap`}},J=I(v({__name:`ThinkingItem`,props:{item:{}},setup(e){let n=e,r=p(()=>n.item.text.trim().slice(0,100)),i=p(()=>n.item.text.trim().length>0),a=p(()=>n.item.text.trim().length>100),s=p(()=>{let e=N.parse(n.item.text,{async:!1,breaks:!0,gfm:!0});return P.sanitize(e)});return(n,d)=>i.value?(t(),m(`div`,G,[a.value?(t(),l(A,{key:0,dense:``,"dense-toggle":``,label:r.value,"header-class":`text-grey-5 text-caption`,style:{"font-style":`italic`}},{default:o(()=>[_(`div`,{class:`q-py-xs markdown-thinking`,innerHTML:s.value},null,8,K)]),_:1},8,[`label`])):(t(),m(`span`,q,c(e.item.text),1))])):u(``,!0)}}),[[`__scopeId`,`data-v-e9fb9f90`]]);function Y(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 X(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??``;return{toolName:`Edit`,filePath:e,oldString:t,newString:r,replaceAll:n.replace_all??!1,additions:r?r.split(`
|
|
4
4
|
`).length:0,deletions:t?t.split(`
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{F as e,H as t,L as n,M as r,N as i,Q as a,T as ee,U as o,bt as s,d as c,f as l,g as u,h as d,l as f,p,r as m,rt as te,u as h,v as ne,vt as re,x as ie}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{I as g,L as _,M as ae,t as v}from"./QIcon-B0-pH3Qs.js";import{t as y}from"./QSeparator-DNSiXYrN.js";import{t as b}from"./QBtn-CyzfM9-_.js";import{n as oe}from"./vue-i18n-eUDnMrPl.js";import{S as se,g as ce,i as x,m as le,v as ue}from"./index-
|
|
1
|
+
import{F as e,H as t,L as n,M as r,N as i,Q as a,T as ee,U as o,bt as s,d as c,f as l,g as u,h as d,l as f,p,r as m,rt as te,u as h,v as ne,vt as re,x as ie}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{I as g,L as _,M as ae,t as v}from"./QIcon-B0-pH3Qs.js";import{t as y}from"./QSeparator-DNSiXYrN.js";import{t as b}from"./QBtn-CyzfM9-_.js";import{n as oe}from"./vue-i18n-eUDnMrPl.js";import{S as se,g as ce,i as x,m as le,v as ue}from"./index-QcUb2Iwh.js";import{n as S,t as C}from"./QItemSection-BzWLL-V-.js";import{t as w}from"./QItemLabel-Czw5g0px.js";import{t as de}from"./QExpansionItem-HLBjHx-0.js";import{t as T}from"./QTooltip-DbEBexRN.js";import{t as fe}from"./_plugin-vue_export-helper-Cj6tcsj6.js";import{t as pe}from"./QSpace-0zdF1m5x.js";import{t as me}from"./use-quasar-BBrzedjR.js";import{n as E,t as he}from"./models-CwWSex3X.js";import{t as ge}from"./QPage-BTzNQlb1.js";var _e={class:`create-inner`},ve={class:`create-title text-center text-weight-bold q-mb-lg text-grey-3`},ye={class:`create-card rounded-borders`},be={class:`card-top-bar row items-center q-px-md q-py-xs`},xe={class:`model-badge cursor-default row items-center q-gutter-xs`},Se={class:`text-indigo-3 text-weight-medium text-caption`},Ce={key:0,class:`notion-url-wrap`},we={key:0,class:`notion-error text-caption q-px-md q-pb-xs text-red-5`},Te={key:1,class:`notion-valid text-caption q-px-md q-pb-xs text-green-4`},Ee={key:0,class:`sentry-url-wrap`},De={key:0,class:`sentry-error text-caption q-px-md q-pb-xs text-red-5`},Oe={key:1,class:`sentry-valid text-caption q-px-md q-pb-xs text-red-4`},ke={class:`card-name-wrap`},Ae={class:`card-textarea-wrap`},je={class:`manual-hint q-px-md q-py-sm text-caption text-grey-6`},Me={class:`q-pa-sm manual-section-body`},Ne={class:`row items-center q-gutter-sm q-mb-sm`},Pe={class:`col text-caption text-grey-4`},Fe={class:`q-pa-sm manual-section-body`},Ie={class:`row items-center q-gutter-sm q-mb-sm`},Le={class:`col text-caption text-grey-4`},Re={class:`card-bottom-bar`},ze={class:`bottom-row bottom-row-agent row items-center q-gutter-xs q-px-sm q-py-xs`},Be={class:`bottom-select-label row items-center no-wrap`},Ve={class:`bottom-select-label row items-center no-wrap`},He={class:`bottom-select-label row items-center no-wrap`},Ue={class:`bottom-select-label row items-center no-wrap`},We={class:`bottom-row bottom-row-git row items-center q-gutter-xs q-px-sm q-py-xs`},Ge={class:`bottom-select-label row items-center no-wrap`},Ke={class:`bottom-select-label row items-center no-wrap`},qe={class:`row justify-center q-px-sm q-py-sm`},Je={class:`create-hint text-center text-body2 q-mt-md text-grey-8`},Ye=fe(ne({__name:`CreatePage`,setup(ne){let fe=le(),Ye=me(),Xe=ue(),D=se(),{t:O}=oe(),Ze=a([]),k=a(``),A=a(``),j=a(``),M=a(!1),N=a(`claude-opus-4-7`),P=a(`auto`),F=a(``),I=a(null),L=a(`feature`),R=a(!1),Qe=a([]),z=a(`claude-code`),$e=f(()=>Qe.value.find(e=>e.id===z.value)),et=f(()=>Qe.value.map(e=>({value:e.id,label:e.displayName}))),tt=f(()=>($e.value?.capabilities.permissionModes??[`auto-accept`,`plan`]).map(e=>({value:e,label:O(`engine.permission.${e}`)}))),nt=[{label:`feature/`,value:`feature`},{label:`fix/`,value:`fix`},{label:`hotfix/`,value:`hotfix`},{label:`chore/`,value:`chore`},{label:`refactor/`,value:`refactor`},{label:`docs/`,value:`docs`},{label:`test/`,value:`test`}],B=a(D.global.defaultPermissionMode||`plan`),V=a([]),H=a(!1),U=a(!1),rt=f(()=>he.map(e=>({label:O(e.i18nLabelKey),value:e.value,description:O(e.i18nDescriptionKey)})));function W(e){let t=e.indexOf(`:`);return t>=0?e.slice(t+1).trim():e}let it=f(()=>[{label:W(O(`reasoning.auto`)),value:`auto`,description:O(`reasoning.autoDescription`)},{label:W(O(`reasoning.low`)),value:`low`,description:O(`reasoning.lowDescription`)},{label:W(O(`reasoning.medium`)),value:`medium`,description:O(`reasoning.mediumDescription`)},{label:W(O(`reasoning.high`)),value:`high`,description:O(`reasoning.highDescription`)},{label:W(O(`reasoning.xhigh`)),value:`xhigh`,description:O(`reasoning.xhighDescription`)},{label:W(O(`reasoning.max`)),value:`max`,description:O(`reasoning.maxDescription`)}]),G=f(()=>j.value.trim().startsWith(`https://www.notion.so/`)),K=a([]),q=a([]),J=a(``),Y=a(``),at=f(()=>!M.value||!G.value);function ot(){let e=J.value.trim();e&&(K.value.push(e),J.value=``)}function st(e){K.value.splice(e,1)}function ct(){let e=Y.value.trim();e&&(q.value.push(e),Y.value=``)}function lt(e){q.value.splice(e,1)}function ut(){M.value=!M.value,M.value||(j.value=``)}let X=a(!1),Z=a(``),Q=f(()=>/\/issues\/\d+/.test(Z.value.trim()));function dt(){X.value=!X.value,X.value||(Z.value=``)}async function ft(e){if(!e.trim()){V.value=[],I.value=null;return}H.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();V.value=n.local??n.branches??[],V.value.length>0&&!I.value&&(I.value=V.value[0]??null)}catch{V.value=[],I.value=null}finally{H.value=!1}}function pt(e){let t=D.getProjectByPath(e);t&&(t.defaultSourceBranch&&(I.value=t.defaultSourceBranch),t.defaultModel?N.value=t.defaultModel:D.global.defaultModel&&(N.value=D.global.defaultModel))}let $=null;t(F,e=>{$&&clearTimeout($),$=setTimeout(()=>{I.value=null,ft(e),pt(e)},500)});function mt(e,t){t(()=>{Ze.value=D.projectPaths.filter(t=>t.toLowerCase().includes(e.toLowerCase()))})}r(async()=>{D.fetchSettings();try{let e=await fetch(`/api/engines`);e.ok&&(Qe.value=await e.json())}catch{}}),i(()=>{$&&clearTimeout($)});function ht(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 gt(){return k.value.trim()?k.value.trim().substring(0,80):!M.value&&!X.value&&A.value.trim()&&(A.value.trim().split(`
|
|
2
2
|
`)[0]??``).substring(0,80)||`workspace`}function _t(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 vt(){return M.value&&!G.value?O(`createPage.validationNotionUrl`):X.value&&!Q.value?O(`createPage.sentryValidation`):!M.value&&!X.value&&!A.value.trim()?O(`createPage.validationDescription`):!M.value&&!X.value&&(!gt()||gt()===`workspace`)&&!k.value.trim()&&!A.value.trim()?O(`createPage.validationName`):F.value.trim()?I.value?null:O(`createPage.validationBranch`):O(`createPage.validationPath`)}async function yt(){let e=vt();if(e){Ye.notify({type:`negative`,message:e,position:`top`});return}U.value=!0;try{let e=gt(),t;t=M.value&&G.value?_t(j.value.trim()):e===`workspace`?`task-${Date.now()}`:ht(e);let n=`${L.value}/${t}`,r={name:e,projectPath:F.value.trim(),sourceBranch:I.value,workingBranch:n,engine:z.value,model:N.value,reasoningEffort:P.value,...M.value&&G.value?{notionUrl:j.value.trim()}:{},...X.value&&Q.value?{sentryUrl:Z.value.trim()}:{},...at.value&&K.value.length>0?{tasks:K.value}:{},...at.value&&q.value.length>0?{acceptanceCriteria:q.value}:{},...R.value?{skipSetupScript:!0}:{},...A.value.trim()?{description:A.value.trim()}:{},permissionMode:B.value},i=await Xe.createWorkspace(r);ce().subscribe(i.id),Xe.selectWorkspace(i.id),fe.push({name:`workspace`,params:{id:i.id}})}catch{Ye.notify({type:`negative`,message:O(`createPage.errorCreating`),position:`top`})}finally{U.value=!1}}return(t,r)=>(e(),c(ge,{class:`create-page flex flex-center column`},{default:o(()=>[h(`div`,_e,[h(`div`,ve,s(t.$t(`createPage.title`)),1),h(`div`,ye,[h(`div`,be,[h(`span`,xe,[u(v,{name:`auto_awesome`,size:`14px`,color:`indigo-4`}),h(`span`,Se,s($e.value?.displayName??t.$t(`createPage.claudeCode`)),1)]),u(pe),u(b,{flat:``,dense:``,"no-caps":``,size:`sm`,color:M.value?`green-4`:`grey-5`,class:`notion-toggle-btn text-caption rounded-borders`,onClick:ut},{default:o(()=>[u(v,{name:`description`,size:`14px`,class:`q-mr-xs`}),d(` `+s(M.value?t.$t(`createPage.notionEnabled`):t.$t(`createPage.importNotion`)),1)]),_:1},8,[`color`]),u(b,{flat:``,dense:``,"no-caps":``,size:`sm`,color:X.value?`red-4`:`grey-5`,class:`sentry-toggle-btn text-caption rounded-borders q-ml-sm`,onClick:dt},{default:o(()=>[u(v,{name:`bug_report`,size:`14px`,class:`q-mr-xs`}),d(` `+s(X.value?t.$t(`createPage.sentryEnabled`):t.$t(`createPage.importSentry`)),1)]),_:1},8,[`color`])]),u(y,{color:`grey-9`}),u(ae,{name:`slide`},{default:o(()=>[M.value?(e(),p(`div`,Ce,[u(x,{modelValue:j.value,"onUpdate:modelValue":r[0]||=e=>j.value=e,borderless:``,dense:``,placeholder:t.$t(`createPage.notionPlaceholder`),class:`notion-url-input`,"input-class":`notion-url-input-inner`},{prepend:o(()=>[u(v,{name:`link`,size:`16px`,color:G.value?`green-4`:`grey-6`},null,8,[`color`])]),_:1},8,[`modelValue`,`placeholder`]),j.value.trim()&&!G.value?(e(),p(`div`,we,s(t.$t(`createPage.notionValidation`)),1)):l(``,!0),G.value?(e(),p(`div`,Te,s(t.$t(`createPage.notionAutoExtract`)),1)):l(``,!0)])):l(``,!0)]),_:1}),M.value?(e(),c(y,{key:0,color:`grey-9`})):l(``,!0),u(ae,{name:`slide`},{default:o(()=>[X.value?(e(),p(`div`,Ee,[u(x,{modelValue:Z.value,"onUpdate:modelValue":r[1]||=e=>Z.value=e,borderless:``,dense:``,placeholder:t.$t(`createPage.sentryPlaceholder`),class:`sentry-url-input`,"input-class":`sentry-url-input-inner`},{prepend:o(()=>[u(v,{name:`link`,size:`16px`,color:Q.value?`red-4`:`grey-6`},null,8,[`color`])]),_:1},8,[`modelValue`,`placeholder`]),Z.value.trim()&&!Q.value?(e(),p(`div`,De,s(t.$t(`createPage.sentryValidation`)),1)):l(``,!0),Q.value?(e(),p(`div`,Oe,s(t.$t(`createPage.sentryAutoExtract`)),1)):l(``,!0)])):l(``,!0)]),_:1}),X.value?(e(),c(y,{key:1,color:`grey-9`})):l(``,!0),h(`div`,ke,[u(x,{modelValue:k.value,"onUpdate:modelValue":r[2]||=e=>k.value=e,borderless:``,dense:``,placeholder:M.value&&G.value?t.$t(`createPage.workspaceName`):t.$t(`createPage.workspaceNamePlaceholder`),class:`name-input`,"input-class":`name-input-inner`},null,8,[`modelValue`,`placeholder`])]),u(y,{color:`grey-9`}),h(`div`,Ae,[u(x,{modelValue:A.value,"onUpdate:modelValue":r[3]||=e=>A.value=e,type:`textarea`,borderless:``,autogrow:``,rows:3,placeholder:M.value?t.$t(`createPage.instructions`):t.$t(`createPage.instructionsPlaceholder`),class:`create-textarea`,"input-class":`create-textarea-input`,onKeydown:[g(_(yt,[`ctrl`]),[`enter`]),g(_(yt,[`meta`]),[`enter`])]},null,8,[`modelValue`,`placeholder`,`onKeydown`])]),u(y,{color:`grey-9`}),at.value?(e(),p(m,{key:2},[h(`div`,je,s(t.$t(`createPage.manualHint`)),1),u(de,{dark:``,dense:``,label:t.$t(`createPage.tasks`,{count:K.value.length}),"header-class":`text-grey-4 manual-expansion-header`,class:`manual-expansion q-mx-sm`},{default:o(()=>[h(`div`,Me,[h(`div`,Ne,[u(x,{modelValue:J.value,"onUpdate:modelValue":r[4]||=e=>J.value=e,dark:``,dense:``,borderless:``,placeholder:t.$t(`createPage.addTask`),class:`col manual-input`,"input-class":`manual-input-inner`,onKeydown:g(_(ot,[`prevent`]),[`enter`])},null,8,[`modelValue`,`placeholder`,`onKeydown`]),u(b,{flat:``,dense:``,round:``,icon:`add`,color:`indigo-4`,disable:!J.value.trim(),onClick:ot},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.addTask`)),1)]),_:1})]),_:1},8,[`disable`])]),(e(!0),p(m,null,n(K.value,(n,r)=>(e(),p(`div`,{key:`task-${r}`,class:`row items-center q-py-xs manual-item`},[h(`span`,Pe,s(n),1),u(b,{flat:``,dense:``,round:``,icon:`close`,size:`xs`,color:`grey-6`,onClick:e=>st(r)},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.removeTask`)),1)]),_:1})]),_:1},8,[`onClick`])]))),128))])]),_:1},8,[`label`]),u(de,{dark:``,dense:``,label:t.$t(`createPage.acceptanceCriteria`,{count:q.value.length}),"header-class":`text-grey-4 manual-expansion-header`,class:`manual-expansion q-mx-sm q-mb-sm`},{default:o(()=>[h(`div`,Fe,[h(`div`,Ie,[u(x,{modelValue:Y.value,"onUpdate:modelValue":r[5]||=e=>Y.value=e,dark:``,dense:``,borderless:``,placeholder:t.$t(`createPage.addCriterion`),class:`col manual-input`,"input-class":`manual-input-inner`,onKeydown:g(_(ct,[`prevent`]),[`enter`])},null,8,[`modelValue`,`placeholder`,`onKeydown`]),u(b,{flat:``,dense:``,round:``,icon:`add`,color:`indigo-4`,disable:!Y.value.trim(),onClick:ct},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.addCriterion`)),1)]),_:1})]),_:1},8,[`disable`])]),(e(!0),p(m,null,n(q.value,(n,r)=>(e(),p(`div`,{key:`crit-${r}`,class:`row items-center q-py-xs manual-item`},[h(`span`,Le,s(n),1),u(b,{flat:``,dense:``,round:``,icon:`close`,size:`xs`,color:`grey-6`,onClick:e=>lt(r)},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.removeCriterion`)),1)]),_:1})]),_:1},8,[`onClick`])]))),128))])]),_:1},8,[`label`]),u(y,{color:`grey-9`})],64)):l(``,!0),h(`div`,Re,[h(`div`,ze,[et.value.length>0?(e(),c(E,{key:0,modelValue:z.value,"onUpdate:modelValue":r[6]||=e=>z.value=e,options:et.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[h(`span`,Be,[u(v,{name:`hub`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(et.value.find(e=>e.value===z.value)?.label??z.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`engine.select`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`])):l(``,!0),u(E,{modelValue:N.value,"onUpdate:modelValue":r[7]||=e=>N.value=e,options:rt.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(()=>[h(`span`,Ve,[d(s(rt.value.find(e=>e.value===N.value)?.label??N.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(({opt:e,itemProps:t})=>[u(S,ee(t,{class:`model-option`}),{default:o(()=>[u(C,null,{default:o(()=>[u(w,{class:`text-white`},{default:o(()=>[d(s(e.label),1)]),_:2},1024),u(w,{caption:``,class:`text-grey-5`},{default:o(()=>[d(s(e.description),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),_:1},8,[`modelValue`,`options`]),u(E,{modelValue:P.value,"onUpdate:modelValue":r[8]||=e=>P.value=e,options:it.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[h(`span`,He,[u(v,{name:`psychology`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(it.value.find(e=>e.value===P.value)?.label??P.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),option:o(({opt:e,itemProps:t})=>[u(S,re(ie(t)),{default:o(()=>[u(C,null,{default:o(()=>[u(w,{class:`text-white`},{default:o(()=>[d(s(e.label),1)]),_:2},1024),u(w,{caption:``,class:`text-grey-5`},{default:o(()=>[d(s(e.description),1)]),_:2},1024)]),_:2},1024)]),_:2},1040)]),_:1},8,[`modelValue`,`options`]),u(E,{modelValue:B.value,"onUpdate:modelValue":r[9]||=e=>B.value=e,options:tt.value,dense:``,borderless:``,class:`bottom-select rounded-borders`,"hide-dropdown-icon":``,"emit-value":``,"map-options":``,"option-value":`value`,"option-label":`label`},{selected:o(()=>[h(`span`,Ue,[u(v,{name:B.value===`plan`?`visibility`:`flash_on`,size:`12px`,color:`amber-6`,class:`q-mr-xs`},null,8,[`name`]),d(` `+s(tt.value.find(e=>e.value===B.value)?.label??B.value)+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`engine.permission`)),1)]),_:1})]),_:1},8,[`modelValue`,`options`]),u(pe),u(b,{flat:``,dense:``,size:`sm`,"no-caps":``,icon:R.value?`play_disabled`:`play_circle`,color:R.value?`orange-4`:`grey-5`,label:t.$t(`createPage.skipSetupScript`),class:`skip-setup-btn`,onClick:r[10]||=e=>R.value=!R.value},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`createPage.skipSetupScript`)),1)]),_:1})]),_:1},8,[`icon`,`color`,`label`])]),h(`div`,We,[u(E,{modelValue:F.value,"onUpdate:modelValue":r[11]||=e=>F.value=e,options:Ze.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":F.value?``:`repo-input-empty`,placeholder:t.$t(`createPage.projectPath`),behavior:te(D).projectPaths.length>0?`menu`:`dialog`,onFilter:mt,onInputValue:r[12]||=e=>{F.value=e}},{prepend:o(()=>[u(v,{name:`folder`,size:`14px`,color:`grey-5`})]),"no-option":o(()=>[u(S,null,{default:o(()=>[u(C,{class:`text-grey-6 text-caption`},{default:o(()=>[d(s(t.$t(`createPage.enterPath`)),1)]),_:1})]),_:1})]),_:1},8,[`modelValue`,`options`,`input-class`,`placeholder`,`behavior`]),u(E,{modelValue:L.value,"onUpdate:modelValue":r[13]||=e=>L.value=e,options:nt,"emit-value":``,"map-options":``,dense:``,borderless:``,class:`bottom-select rounded-borders branch-type-select`,"hide-dropdown-icon":``},{selected:o(()=>[h(`span`,Ge,[u(v,{name:`account_tree`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(L.value)+`/ `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`createPage.branchType`)),1)]),_:1})]),_:1},8,[`modelValue`]),u(E,{modelValue:I.value,"onUpdate:modelValue":r[14]||=e=>I.value=e,options:V.value,dense:``,borderless:``,class:`bottom-select rounded-borders branch-select`,"hide-dropdown-icon":``,loading:H.value,disable:!F.value.trim()||H.value},{selected:o(()=>[h(`span`,Ke,[u(v,{name:`call_split`,size:`12px`,color:`grey-5`,class:`q-mr-xs`}),d(` `+s(I.value??t.$t(`createPage.branch`))+` `,1),u(v,{name:`expand_more`,size:`12px`,color:`grey-5`})])]),"no-option":o(()=>[u(S,null,{default:o(()=>[u(C,{class:`text-grey-6 text-caption`},{default:o(()=>[d(s(F.value.trim()?t.$t(`createPage.noBranches`):t.$t(`createPage.enterPath`)),1)]),_:1})]),_:1})]),_:1},8,[`modelValue`,`options`,`loading`,`disable`])])]),h(`div`,qe,[u(b,{label:t.$t(`createPage.create`),"no-caps":``,unelevated:``,class:`create-btn text-weight-bold rounded-borders`,loading:U.value,onClick:yt},null,8,[`label`,`loading`])])]),h(`div`,Je,s(M.value?t.$t(`createPage.notionExtractHint`):t.$t(`createPage.notionImportHint`)),1)])]),_:1}))}}),[[`__scopeId`,`data-v-2d121476`]]);export{Ye as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/editor.main-
|
|
2
|
-
import{F as e,H as t,M as n,N as r,Q as i,S as a,U as o,bt as s,d as c,f as l,g as u,h as d,l as f,p,r as m,rt as ee,u as h,v as g,yt as _}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{O as v,a as y,t as b}from"./QIcon-B0-pH3Qs.js";import{t as te}from"./QSeparator-DNSiXYrN.js";import{n as ne,t as x}from"./QBtn-CyzfM9-_.js";import{n as re}from"./vue-i18n-eUDnMrPl.js";import{r as S,t as C}from"./private.use-form-C5G_3nU5.js";import{f as ie}from"./index-CDTpNA2L.js";import{t as w}from"./QSpinnerDots-By20ptst.js";import{t as ae}from"./QScrollArea-CBW6shMb.js";import{t as T}from"./QTooltip-DbEBexRN.js";import{t as E}from"./_plugin-vue_export-helper-Cj6tcsj6.js";import{t as D}from"./QBadge-Di02fu2H.js";import{t as oe}from"./QSpace-0zdF1m5x.js";import{i as O,n as se,r as ce,t as le}from"./build-path-tree-BaiH1Val.js";var k=v({name:`QBtnToggle`,props:{...S,modelValue:{required:!0},options:{type:Array,required:!0,validator:e=>e.every(e=>(`label`in e||`icon`in e||`slot`in e)&&`value`in e)},color:String,textColor:String,toggleColor:{type:String,default:`primary`},toggleTextColor:String,outline:Boolean,flat:Boolean,unelevated:Boolean,rounded:Boolean,push:Boolean,glossy:Boolean,size:String,padding:String,noCaps:Boolean,noWrap:Boolean,dense:Boolean,readonly:Boolean,disable:Boolean,stack:Boolean,stretch:Boolean,spread:Boolean,clearable:Boolean,ripple:{type:[Boolean,Object],default:!0}},emits:[`update:modelValue`,`clear`,`click`],setup(e,{slots:t,emit:n}){let r=f(()=>e.options.find(t=>t.value===e.modelValue)!==void 0),i=C(f(()=>({type:`hidden`,name:e.name,value:e.modelValue}))),o=f(()=>ne(e)),s=f(()=>({rounded:e.rounded,dense:e.dense,...o.value})),c=f(()=>e.options.map((t,n)=>{let{attrs:r,value:i,slot:a,...o}=t;return{slot:a,props:{key:n,"aria-pressed":i===e.modelValue?`true`:`false`,...r,...o,...s.value,disable:e.disable===!0||o.disable===!0,color:i===e.modelValue?u(o,`toggleColor`):u(o,`color`),textColor:i===e.modelValue?u(o,`toggleTextColor`):u(o,`textColor`),noCaps:u(o,`noCaps`)===!0,noWrap:u(o,`noWrap`)===!0,size:u(o,`size`),padding:u(o,`padding`),ripple:u(o,`ripple`),stack:u(o,`stack`)===!0,stretch:u(o,`stretch`)===!0,onClick(e){l(i,t,e)}}}}));function l(t,r,i){e.readonly!==!0&&(e.modelValue===t?e.clearable===!0&&(n(`update:modelValue`,null,null),n(`clear`)):n(`update:modelValue`,t,r),n(`click`,i))}function u(t,n){return t[n]===void 0?e[n]:t[n]}function d(){let n=c.value.map(e=>a(x,e.props,e.slot===void 0?void 0:t[e.slot]));return e.name!==void 0&&e.disable!==!0&&r.value===!0&&i(n,`push`),y(t.default,n)}return()=>a(O,{class:`q-btn-toggle`,...o.value,rounded:e.rounded,stretch:e.stretch,glossy:e.glossy,spread:e.spread},d)}}),ue={class:`diff-viewer column full-height`},de={class:`diff-header row items-center q-px-md q-py-sm no-wrap`},fe={class:`text-body1 text-weight-medium text-grey-3`},pe={key:0,class:`text-caption text-grey-6 q-ml-md`,style:{"font-size":`11px`}},me={class:`text-grey-7`},he={class:`text-green-4`},A={class:`text-grey-7`},j={key:1,class:`text-caption text-grey-5 q-ml-md ellipsis`,style:{"font-size":`11px`,"font-family":`'Roboto Mono', monospace`,"max-width":`400px`}},M={class:`row col no-wrap`,style:{"min-height":`0`}},N={key:1,class:`text-caption text-grey-8 q-pa-sm`},P={class:`text-grey-4`,style:{"font-family":`'Roboto Mono', monospace`,"font-size":`11px`}},F={class:`text-grey-3 ellipsis`,style:{"font-family":`'Roboto Mono', monospace`,"font-size":`11px`}},I={class:`col column`,style:{"min-width":`0`,position:`relative`}},L={key:0,class:`col column items-center justify-center`},ge={key:1,class:`col column items-center justify-center text-grey-8 text-caption`},R=`kobo:diffViewerFileListWidth`,z=180,B=600,V=E(g({__name:`DiffViewer`,props:{workspaceId:{}},emits:[`close`,`sendToChat`],setup(a,{emit:g}){let v=a,y=g,{t:ne}=re(),S=i([]),C=i(``),E=i(``),O=i(null),V=i(!1),H=i(!1),U=i(null),W=i(`side`),G=i(`branch`),_e=parseInt(localStorage.getItem(R)??`280`,10),K=i(Math.min(B,Math.max(z,_e)));function ve(e){e.preventDefault();let t=e.target.closest(`.diff-viewer`);if(!t)return;let n=t.getBoundingClientRect().left,r=e=>{K.value=Math.min(B,Math.max(z,e.clientX-n))},i=()=>{localStorage.setItem(R,String(K.value)),document.removeEventListener(`mousemove`,r),document.removeEventListener(`mouseup`,i),document.body.style.cursor=``,document.body.style.userSelect=``};document.body.style.cursor=`col-resize`,document.body.style.userSelect=`none`,document.addEventListener(`mousemove`,r),document.addEventListener(`mouseup`,i)}let q=null,J=null,Y=[],ye=f(()=>le(S.value)),X=f(()=>O.value?`file:${O.value}`:``);async function Z(){V.value=!0;try{let e=await fetch(`/api/workspaces/${v.workspaceId}/diff?mode=${G.value}`,{cache:`no-store`});if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();S.value=t.files,C.value=t.sourceBranch??``,E.value=t.workingBranch??``}catch(e){console.error(`Failed to load diff files:`,e)}finally{V.value=!1}}async function Q(e){if(U.value){H.value=!0;try{q||(self.MonacoEnvironment={getWorker(e,t){return t===`json`?new Worker(new URL(`/assets/json.worker-C9p7xCYk.js`,``+import.meta.url),{type:`module`}):t===`css`||t===`scss`||t===`less`?new Worker(new URL(`/assets/css.worker-D1piIYC4.js`,``+import.meta.url),{type:`module`}):t===`html`||t===`handlebars`||t===`razor`?new Worker(new URL(`/assets/html.worker-C4q4XMPn.js`,``+import.meta.url),{type:`module`}):t===`typescript`||t===`javascript`?new Worker(new URL(`/assets/ts.worker-Cj3zTgVE.js`,``+import.meta.url),{type:`module`}):new Worker(new URL(`/assets/editor.worker-CJ9iTmkr.js`,``+import.meta.url),{type:`module`})}},q=await ie(()=>import(`./editor.main-qZAJW6DY.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17])),q.editor.defineTheme(`kobo-dark`,{base:`vs-dark`,inherit:!0,rules:[],colors:{"editor.background":`#1a1a2e`,"diffEditor.insertedTextBackground":`#22c55e20`,"diffEditor.removedTextBackground":`#ef444420`}}));let t=await fetch(`/api/workspaces/${v.workspaceId}/diff-file?path=${encodeURIComponent(e)}&mode=${G.value}`,{cache:`no-store`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json(),r={ts:`typescript`,tsx:`typescript`,js:`javascript`,jsx:`javascript`,vue:`html`,html:`html`,css:`css`,scss:`scss`,json:`json`,md:`markdown`,yaml:`yaml`,yml:`yaml`,sh:`shell`,sql:`sql`,py:`python`,rs:`rust`,go:`go`}[e.split(`.`).pop()??``]??`plaintext`;if(J){for(let e of Y)e.dispose();Y=[];let e=J.getModel();J.dispose(),J=null,e?.original?.dispose(),e?.modified?.dispose()}let i=q.editor.createModel(n.original??``,r),a=q.editor.createModel(n.modified??``,r);J=q.editor.createDiffEditor(U.value,{theme:`kobo-dark`,readOnly:!0,renderSideBySide:W.value===`side`,automaticLayout:!0,minimap:{enabled:!1},scrollBeyondLastLine:!1,fontSize:12,lineHeight:18}),J.setModel({original:i,modified:a}),be()}catch(e){console.error(`Failed to load file diff:`,e)}finally{H.value=!1}}}let $=i(!1);function be(){if(!J)return;for(let e of Y)e.dispose();Y=[];let e=J.getModifiedEditor(),t=J.getOriginalEditor();for(let n of[e,t]){let e=n.onDidChangeCursorSelection(()=>{let e=n.getSelection();$.value=!!(e&&!e.isEmpty())});Y.push(e)}}function xe(){if(!(!J||!O.value))for(let e of[J.getModifiedEditor(),J.getOriginalEditor()]){let t=e.getSelection();if(t&&!t.isEmpty()){let n=e.getModel();if(!n)continue;let r=n.getValueInRange(t),i=e===J.getModifiedEditor()?`modified`:`original`;y(`sendToChat`,`\`\`\`\n// ${O.value} (${i}) L${t.startLineNumber}-L${t.endLineNumber}\n${r}\n\`\`\``);return}}}t(O,e=>{e&&Q(e)}),t(W,()=>{J&&J.updateOptions({renderSideBySide:W.value===`side`})}),t(G,async()=>{let e=O.value;await Z(),e&&S.value.some(t=>t.path===e)?Q(e):O.value=null});function Se(e){switch(e){case`added`:return`#4ade80`;case`deleted`:return`#f87171`;case`renamed`:return`#60a5fa`;default:return`#f59e0b`}}return n(Z),r(()=>{for(let e of Y)e.dispose();if(Y=[],J){let e=J.getModel();J.dispose(),J=null,e?.original?.dispose(),e?.modified?.dispose()}}),(t,n)=>(e(),p(`div`,ue,[h(`div`,de,[u(b,{name:`difference`,size:`18px`,color:`indigo-4`,class:`q-mr-xs`}),h(`span`,fe,s(t.$t(`diff.title`)),1),u(D,{label:`${S.value.length}`,color:`grey-8`,"text-color":`grey-4`,class:`q-ml-sm`,style:{"font-size":`10px`}},null,8,[`label`]),C.value?(e(),p(`span`,pe,[G.value===`branch`?(e(),p(m,{key:0},[h(`span`,me,s(C.value),1),u(b,{name:`arrow_forward`,size:`11px`,color:`grey-8`,class:`q-mx-xs`}),h(`span`,he,s(E.value),1)],64)):(e(),p(m,{key:1},[h(`span`,A,`origin/`+s(E.value),1),u(b,{name:`arrow_forward`,size:`11px`,color:`grey-8`,class:`q-mx-xs`}),n[4]||=h(`span`,{class:`text-green-4`},`HEAD`,-1)],64))])):l(``,!0),O.value?(e(),p(`span`,j,s(O.value),1)):l(``,!0),u(oe),u(k,{modelValue:G.value,"onUpdate:modelValue":n[0]||=e=>G.value=e,dense:``,"no-caps":``,size:`sm`,"toggle-color":`indigo-8`,color:`grey-9`,"text-color":`grey-5`,options:[{label:t.$t(`diff.scopeBranch`),value:`branch`},{label:t.$t(`diff.scopeUnpushed`),value:`unpushed`}],class:`q-mr-sm`},null,8,[`modelValue`,`options`]),u(k,{modelValue:W.value,"onUpdate:modelValue":n[1]||=e=>W.value=e,dense:``,"no-caps":``,size:`sm`,"toggle-color":`indigo-8`,color:`grey-9`,"text-color":`grey-5`,options:[{label:t.$t(`diff.side`),value:`side`},{label:t.$t(`diff.inline`),value:`inline`}],class:`q-mr-sm`},null,8,[`modelValue`,`options`]),u(x,{flat:``,round:``,dense:``,icon:`close`,color:`grey-5`,size:`sm`,onClick:n[2]||=e=>y(`close`)},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.closeDiffViewer`)),1)]),_:1})]),_:1})]),u(te,{dark:``}),h(`div`,M,[h(`div`,{class:`diff-file-list-wrapper`,style:_({width:`${K.value}px`,minWidth:`${z}px`})},[u(ae,{class:`diff-file-list q-pa-xs`,style:{width:`100%`,height:`100%`,"border-right":`1px solid #2a2a4a`}},{default:o(()=>[V.value?(e(),c(w,{key:0,size:`24px`,color:`grey-6`,class:`q-ma-md`})):S.value.length===0?(e(),p(`div`,N,s(t.$t(`diff.noChanges`)),1)):(e(),c(ce,{key:2,nodes:ye.value,"node-key":`nodeKey`,"label-key":`label`,"children-key":`children`,dark:``,dense:``,"default-expand-all":``,"no-selection-unset":``,selected:X.value,class:`diff-tree`,"onUpdate:selected":n[3]||=e=>{typeof e!=`string`||!e.startsWith(`file:`)||(O.value=e.slice(5))}},{"default-header":o(({node:t})=>[t.isFolder?(e(),p(m,{key:0},[u(b,{name:`folder`,size:`14px`,color:`indigo-4`,class:`q-mr-xs`}),h(`span`,P,s(t.label),1),u(D,{label:t.children?ee(se)(t.children):0,color:`grey-9`,"text-color":`grey-5`,class:`q-ml-xs`,style:{"font-size":`9px`}},null,8,[`label`])],64)):(e(),p(m,{key:1},[u(b,{name:`description`,size:`14px`,style:_({color:Se(t.file.status)}),class:`q-mr-xs`},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.file.status),1)]),_:2},1024)]),_:2},1032,[`style`]),h(`span`,F,s(t.label),1)],64))]),_:1},8,[`nodes`,`selected`]))]),_:1}),h(`div`,{class:`diff-file-list-resize-handle`,onMousedown:ve},null,32)],4),h(`div`,I,[H.value?(e(),p(`div`,L,[u(w,{size:`32px`,color:`indigo-4`})])):O.value?l(``,!0):(e(),p(`div`,ge,s(t.$t(`diff.selectFile`)),1)),h(`div`,{ref_key:`editorContainer`,ref:U,class:`col`,style:{"min-height":`0`}},null,512),$.value?(e(),c(x,{key:2,"no-caps":``,dense:``,size:`sm`,color:`primary`,icon:`chat`,label:t.$t(`diff.addToChat`),class:`send-to-chat-btn`,onClick:xe},null,8,[`label`])):l(``,!0)])])]))}}),[[`__scopeId`,`data-v-23217be2`]]);export{V as default};
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/editor.main-C2h6FfOt.js","assets/index-QcUb2Iwh.js","assets/vue-i18n-eUDnMrPl.js","assets/runtime-core.esm-bundler-C3IgBgY5.js","assets/QIcon-B0-pH3Qs.js","assets/use-id-BmXMngYX.js","assets/QSeparator-DNSiXYrN.js","assets/QBtn-CyzfM9-_.js","assets/use-checkbox-BduGd8xg.js","assets/private.use-form-C5G_3nU5.js","assets/QDialog-G448EJG4.js","assets/scroll-C-Vz5BD9.js","assets/symbols-DCYodwb2.js","assets/index-eX_lKHSg.css","assets/editor.api-BpCtstKS.js","assets/editor-COGk2gAX.css","assets/monaco.contribution-CPqJifAu.js","assets/editor-CS3NEPi9.css"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{F as e,H as t,M as n,N as r,Q as i,S as a,U as o,bt as s,d as c,f as l,g as u,h as d,l as f,p,r as m,rt as ee,u as h,v as g,yt as _}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{O as v,a as y,t as b}from"./QIcon-B0-pH3Qs.js";import{t as te}from"./QSeparator-DNSiXYrN.js";import{n as ne,t as x}from"./QBtn-CyzfM9-_.js";import{n as re}from"./vue-i18n-eUDnMrPl.js";import{r as S,t as C}from"./private.use-form-C5G_3nU5.js";import{f as ie}from"./index-QcUb2Iwh.js";import{t as w}from"./QSpinnerDots-By20ptst.js";import{t as ae}from"./QScrollArea-CBW6shMb.js";import{t as T}from"./QTooltip-DbEBexRN.js";import{t as E}from"./_plugin-vue_export-helper-Cj6tcsj6.js";import{t as D}from"./QBadge-Di02fu2H.js";import{t as oe}from"./QSpace-0zdF1m5x.js";import{i as O,n as se,r as ce,t as le}from"./build-path-tree-DOPXkGhj.js";var k=v({name:`QBtnToggle`,props:{...S,modelValue:{required:!0},options:{type:Array,required:!0,validator:e=>e.every(e=>(`label`in e||`icon`in e||`slot`in e)&&`value`in e)},color:String,textColor:String,toggleColor:{type:String,default:`primary`},toggleTextColor:String,outline:Boolean,flat:Boolean,unelevated:Boolean,rounded:Boolean,push:Boolean,glossy:Boolean,size:String,padding:String,noCaps:Boolean,noWrap:Boolean,dense:Boolean,readonly:Boolean,disable:Boolean,stack:Boolean,stretch:Boolean,spread:Boolean,clearable:Boolean,ripple:{type:[Boolean,Object],default:!0}},emits:[`update:modelValue`,`clear`,`click`],setup(e,{slots:t,emit:n}){let r=f(()=>e.options.find(t=>t.value===e.modelValue)!==void 0),i=C(f(()=>({type:`hidden`,name:e.name,value:e.modelValue}))),o=f(()=>ne(e)),s=f(()=>({rounded:e.rounded,dense:e.dense,...o.value})),c=f(()=>e.options.map((t,n)=>{let{attrs:r,value:i,slot:a,...o}=t;return{slot:a,props:{key:n,"aria-pressed":i===e.modelValue?`true`:`false`,...r,...o,...s.value,disable:e.disable===!0||o.disable===!0,color:i===e.modelValue?u(o,`toggleColor`):u(o,`color`),textColor:i===e.modelValue?u(o,`toggleTextColor`):u(o,`textColor`),noCaps:u(o,`noCaps`)===!0,noWrap:u(o,`noWrap`)===!0,size:u(o,`size`),padding:u(o,`padding`),ripple:u(o,`ripple`),stack:u(o,`stack`)===!0,stretch:u(o,`stretch`)===!0,onClick(e){l(i,t,e)}}}}));function l(t,r,i){e.readonly!==!0&&(e.modelValue===t?e.clearable===!0&&(n(`update:modelValue`,null,null),n(`clear`)):n(`update:modelValue`,t,r),n(`click`,i))}function u(t,n){return t[n]===void 0?e[n]:t[n]}function d(){let n=c.value.map(e=>a(x,e.props,e.slot===void 0?void 0:t[e.slot]));return e.name!==void 0&&e.disable!==!0&&r.value===!0&&i(n,`push`),y(t.default,n)}return()=>a(O,{class:`q-btn-toggle`,...o.value,rounded:e.rounded,stretch:e.stretch,glossy:e.glossy,spread:e.spread},d)}}),ue={class:`diff-viewer column full-height`},de={class:`diff-header row items-center q-px-md q-py-sm no-wrap`},fe={class:`text-body1 text-weight-medium text-grey-3`},pe={key:0,class:`text-caption text-grey-6 q-ml-md`,style:{"font-size":`11px`}},me={class:`text-grey-7`},he={class:`text-green-4`},A={class:`text-grey-7`},j={key:1,class:`text-caption text-grey-5 q-ml-md ellipsis`,style:{"font-size":`11px`,"font-family":`'Roboto Mono', monospace`,"max-width":`400px`}},M={class:`row col no-wrap`,style:{"min-height":`0`}},N={key:1,class:`text-caption text-grey-8 q-pa-sm`},P={class:`text-grey-4`,style:{"font-family":`'Roboto Mono', monospace`,"font-size":`11px`}},F={class:`text-grey-3 ellipsis`,style:{"font-family":`'Roboto Mono', monospace`,"font-size":`11px`}},I={class:`col column`,style:{"min-width":`0`,position:`relative`}},L={key:0,class:`col column items-center justify-center`},ge={key:1,class:`col column items-center justify-center text-grey-8 text-caption`},R=`kobo:diffViewerFileListWidth`,z=180,B=600,V=E(g({__name:`DiffViewer`,props:{workspaceId:{}},emits:[`close`,`sendToChat`],setup(a,{emit:g}){let v=a,y=g,{t:ne}=re(),S=i([]),C=i(``),E=i(``),O=i(null),V=i(!1),H=i(!1),U=i(null),W=i(`side`),G=i(`branch`),_e=parseInt(localStorage.getItem(R)??`280`,10),K=i(Math.min(B,Math.max(z,_e)));function ve(e){e.preventDefault();let t=e.target.closest(`.diff-viewer`);if(!t)return;let n=t.getBoundingClientRect().left,r=e=>{K.value=Math.min(B,Math.max(z,e.clientX-n))},i=()=>{localStorage.setItem(R,String(K.value)),document.removeEventListener(`mousemove`,r),document.removeEventListener(`mouseup`,i),document.body.style.cursor=``,document.body.style.userSelect=``};document.body.style.cursor=`col-resize`,document.body.style.userSelect=`none`,document.addEventListener(`mousemove`,r),document.addEventListener(`mouseup`,i)}let q=null,J=null,Y=[],ye=f(()=>le(S.value)),X=f(()=>O.value?`file:${O.value}`:``);async function Z(){V.value=!0;try{let e=await fetch(`/api/workspaces/${v.workspaceId}/diff?mode=${G.value}`,{cache:`no-store`});if(!e.ok)throw Error(`HTTP ${e.status}`);let t=await e.json();S.value=t.files,C.value=t.sourceBranch??``,E.value=t.workingBranch??``}catch(e){console.error(`Failed to load diff files:`,e)}finally{V.value=!1}}async function Q(e){if(U.value){H.value=!0;try{q||(self.MonacoEnvironment={getWorker(e,t){return t===`json`?new Worker(new URL(`/assets/json.worker-C9p7xCYk.js`,``+import.meta.url),{type:`module`}):t===`css`||t===`scss`||t===`less`?new Worker(new URL(`/assets/css.worker-D1piIYC4.js`,``+import.meta.url),{type:`module`}):t===`html`||t===`handlebars`||t===`razor`?new Worker(new URL(`/assets/html.worker-C4q4XMPn.js`,``+import.meta.url),{type:`module`}):t===`typescript`||t===`javascript`?new Worker(new URL(`/assets/ts.worker-Cj3zTgVE.js`,``+import.meta.url),{type:`module`}):new Worker(new URL(`/assets/editor.worker-CJ9iTmkr.js`,``+import.meta.url),{type:`module`})}},q=await ie(()=>import(`./editor.main-C2h6FfOt.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17])),q.editor.defineTheme(`kobo-dark`,{base:`vs-dark`,inherit:!0,rules:[],colors:{"editor.background":`#1a1a2e`,"diffEditor.insertedTextBackground":`#22c55e20`,"diffEditor.removedTextBackground":`#ef444420`}}));let t=await fetch(`/api/workspaces/${v.workspaceId}/diff-file?path=${encodeURIComponent(e)}&mode=${G.value}`,{cache:`no-store`});if(!t.ok)throw Error(`HTTP ${t.status}`);let n=await t.json(),r={ts:`typescript`,tsx:`typescript`,js:`javascript`,jsx:`javascript`,vue:`html`,html:`html`,css:`css`,scss:`scss`,json:`json`,md:`markdown`,yaml:`yaml`,yml:`yaml`,sh:`shell`,sql:`sql`,py:`python`,rs:`rust`,go:`go`}[e.split(`.`).pop()??``]??`plaintext`;if(J){for(let e of Y)e.dispose();Y=[];let e=J.getModel();J.dispose(),J=null,e?.original?.dispose(),e?.modified?.dispose()}let i=q.editor.createModel(n.original??``,r),a=q.editor.createModel(n.modified??``,r);J=q.editor.createDiffEditor(U.value,{theme:`kobo-dark`,readOnly:!0,renderSideBySide:W.value===`side`,automaticLayout:!0,minimap:{enabled:!1},scrollBeyondLastLine:!1,fontSize:12,lineHeight:18}),J.setModel({original:i,modified:a}),be()}catch(e){console.error(`Failed to load file diff:`,e)}finally{H.value=!1}}}let $=i(!1);function be(){if(!J)return;for(let e of Y)e.dispose();Y=[];let e=J.getModifiedEditor(),t=J.getOriginalEditor();for(let n of[e,t]){let e=n.onDidChangeCursorSelection(()=>{let e=n.getSelection();$.value=!!(e&&!e.isEmpty())});Y.push(e)}}function xe(){if(!(!J||!O.value))for(let e of[J.getModifiedEditor(),J.getOriginalEditor()]){let t=e.getSelection();if(t&&!t.isEmpty()){let n=e.getModel();if(!n)continue;let r=n.getValueInRange(t),i=e===J.getModifiedEditor()?`modified`:`original`;y(`sendToChat`,`\`\`\`\n// ${O.value} (${i}) L${t.startLineNumber}-L${t.endLineNumber}\n${r}\n\`\`\``);return}}}t(O,e=>{e&&Q(e)}),t(W,()=>{J&&J.updateOptions({renderSideBySide:W.value===`side`})}),t(G,async()=>{let e=O.value;await Z(),e&&S.value.some(t=>t.path===e)?Q(e):O.value=null});function Se(e){switch(e){case`added`:return`#4ade80`;case`deleted`:return`#f87171`;case`renamed`:return`#60a5fa`;default:return`#f59e0b`}}return n(Z),r(()=>{for(let e of Y)e.dispose();if(Y=[],J){let e=J.getModel();J.dispose(),J=null,e?.original?.dispose(),e?.modified?.dispose()}}),(t,n)=>(e(),p(`div`,ue,[h(`div`,de,[u(b,{name:`difference`,size:`18px`,color:`indigo-4`,class:`q-mr-xs`}),h(`span`,fe,s(t.$t(`diff.title`)),1),u(D,{label:`${S.value.length}`,color:`grey-8`,"text-color":`grey-4`,class:`q-ml-sm`,style:{"font-size":`10px`}},null,8,[`label`]),C.value?(e(),p(`span`,pe,[G.value===`branch`?(e(),p(m,{key:0},[h(`span`,me,s(C.value),1),u(b,{name:`arrow_forward`,size:`11px`,color:`grey-8`,class:`q-mx-xs`}),h(`span`,he,s(E.value),1)],64)):(e(),p(m,{key:1},[h(`span`,A,`origin/`+s(E.value),1),u(b,{name:`arrow_forward`,size:`11px`,color:`grey-8`,class:`q-mx-xs`}),n[4]||=h(`span`,{class:`text-green-4`},`HEAD`,-1)],64))])):l(``,!0),O.value?(e(),p(`span`,j,s(O.value),1)):l(``,!0),u(oe),u(k,{modelValue:G.value,"onUpdate:modelValue":n[0]||=e=>G.value=e,dense:``,"no-caps":``,size:`sm`,"toggle-color":`indigo-8`,color:`grey-9`,"text-color":`grey-5`,options:[{label:t.$t(`diff.scopeBranch`),value:`branch`},{label:t.$t(`diff.scopeUnpushed`),value:`unpushed`}],class:`q-mr-sm`},null,8,[`modelValue`,`options`]),u(k,{modelValue:W.value,"onUpdate:modelValue":n[1]||=e=>W.value=e,dense:``,"no-caps":``,size:`sm`,"toggle-color":`indigo-8`,color:`grey-9`,"text-color":`grey-5`,options:[{label:t.$t(`diff.side`),value:`side`},{label:t.$t(`diff.inline`),value:`inline`}],class:`q-mr-sm`},null,8,[`modelValue`,`options`]),u(x,{flat:``,round:``,dense:``,icon:`close`,color:`grey-5`,size:`sm`,onClick:n[2]||=e=>y(`close`)},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.$t(`tooltip.closeDiffViewer`)),1)]),_:1})]),_:1})]),u(te,{dark:``}),h(`div`,M,[h(`div`,{class:`diff-file-list-wrapper`,style:_({width:`${K.value}px`,minWidth:`${z}px`})},[u(ae,{class:`diff-file-list q-pa-xs`,style:{width:`100%`,height:`100%`,"border-right":`1px solid #2a2a4a`}},{default:o(()=>[V.value?(e(),c(w,{key:0,size:`24px`,color:`grey-6`,class:`q-ma-md`})):S.value.length===0?(e(),p(`div`,N,s(t.$t(`diff.noChanges`)),1)):(e(),c(ce,{key:2,nodes:ye.value,"node-key":`nodeKey`,"label-key":`label`,"children-key":`children`,dark:``,dense:``,"default-expand-all":``,"no-selection-unset":``,selected:X.value,class:`diff-tree`,"onUpdate:selected":n[3]||=e=>{typeof e!=`string`||!e.startsWith(`file:`)||(O.value=e.slice(5))}},{"default-header":o(({node:t})=>[t.isFolder?(e(),p(m,{key:0},[u(b,{name:`folder`,size:`14px`,color:`indigo-4`,class:`q-mr-xs`}),h(`span`,P,s(t.label),1),u(D,{label:t.children?ee(se)(t.children):0,color:`grey-9`,"text-color":`grey-5`,class:`q-ml-xs`,style:{"font-size":`9px`}},null,8,[`label`])],64)):(e(),p(m,{key:1},[u(b,{name:`description`,size:`14px`,style:_({color:Se(t.file.status)}),class:`q-mr-xs`},{default:o(()=>[u(T,null,{default:o(()=>[d(s(t.file.status),1)]),_:2},1024)]),_:2},1032,[`style`]),h(`span`,F,s(t.label),1)],64))]),_:1},8,[`nodes`,`selected`]))]),_:1}),h(`div`,{class:`diff-file-list-resize-handle`,onMousedown:ve},null,32)],4),h(`div`,I,[H.value?(e(),p(`div`,L,[u(w,{size:`32px`,color:`indigo-4`})])):O.value?l(``,!0):(e(),p(`div`,ge,s(t.$t(`diff.selectFile`)),1)),h(`div`,{ref_key:`editorContainer`,ref:U,class:`col`,style:{"min-height":`0`}},null,512),$.value?(e(),c(x,{key:2,"no-caps":``,dense:``,size:`sm`,color:`primary`,icon:`chat`,label:t.$t(`diff.addToChat`),class:`send-to-chat-btn`,onClick:xe},null,8,[`label`])):l(``,!0)])])]))}}),[[`__scopeId`,`data-v-23217be2`]]);export{V as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,L as t,M as n,Q as r,U as i,_t as ee,bt as a,d as o,f as s,g as c,l,p as u,r as te,rt as d,u as f,v as ne}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{t as p}from"./QIcon-B0-pH3Qs.js";import{t as m}from"./QBtn-CyzfM9-_.js";import{E as h,O as g,m as re}from"./index-
|
|
1
|
+
import{F as e,L as t,M as n,Q as r,U as i,_t as ee,bt as a,d as o,f as s,g as c,l,p as u,r as te,rt as d,u as f,v as ne}from"./runtime-core.esm-bundler-C3IgBgY5.js";import{t as p}from"./QIcon-B0-pH3Qs.js";import{t as m}from"./QBtn-CyzfM9-_.js";import{E as h,O as g,m as re}from"./index-QcUb2Iwh.js";import{n as ie,t as ae}from"./QItemSection-BzWLL-V-.js";import{t as _}from"./QSpace-0zdF1m5x.js";import{t as oe}from"./use-quasar-BBrzedjR.js";import{t as v}from"./QList-D2GuTeLl.js";import{t as y}from"./QPage-BTzNQlb1.js";var b={class:`row items-center q-mb-md`},x={class:`text-h6 q-ml-sm`},S={key:0,class:`text-grey-6 text-center q-pa-lg`},C={key:1,class:`column q-gutter-md`},w={class:`text-subtitle2 q-mb-sm`},T={class:`text-caption text-grey-6`},E={class:`text-body2`},D={class:`row items-center`},O={class:`text-subtitle2`},k={class:`row q-col-gutter-md q-mt-xs`},A={class:`col`},j={class:`text-caption text-grey-6`},M={class:`text-body2`},N={class:`col-auto`},P={class:`text-caption text-grey-6`},F={class:`text-body2`},I={class:`col-auto`},L={class:`text-caption text-grey-6`},R={class:`text-body2`},z={class:`row items-center`},B={class:`text-subtitle2`},V={key:0,class:`text-caption text-grey-5 q-mt-xs`},se={key:1,class:`text-caption text-negative q-mt-xs`},H={class:`row items-center`},U={class:`text-subtitle2`},W={class:`text-caption text-grey-6 q-mt-xs`},G={key:0,class:`q-mt-sm`},K={class:`text-caption text-negative q-mb-xs`},ce={class:`text-body2`},le={class:`text-caption text-grey-6`},ue={class:`row items-center`},de={class:`text-subtitle2`},fe={class:`text-subtitle2 q-mb-sm`},pe={class:`column q-gutter-xs`},me={class:`row items-center`},he={class:`q-ml-sm text-caption text-grey-6`},ge={class:`row items-center`},_e={class:`q-ml-sm text-caption text-grey-6`},ve={class:`row items-center`},ye={class:`q-ml-sm text-caption text-grey-6`},q=ne({__name:`HealthPage`,setup(ne){let q=oe(),be=re(),J=r(null),Y=r(!1);async function X(){Y.value=!0;try{let e=await fetch(`/api/health/report`);if(!e.ok)throw Error(`HTTP ${e.status}`);J.value=await e.json()}catch(e){q.notify({type:`negative`,message:String(e),position:`top`,timeout:4e3})}finally{Y.value=!1}}n(X);let xe=l(()=>{let e=J.value?.db.sizeBytes;return e==null?`—`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}),Z=l(()=>{let e=J.value;return e?e.db.schemaVersion===e.db.currentSchemaVersion:!1});function Q(e){return e?`check_circle`:`error`}function $(e){return e?`positive`:`negative`}return(n,r)=>(e(),o(y,{class:`q-pa-md`,style:{"max-width":`900px`,margin:`0 auto`}},{default:i(()=>[f(`div`,b,[c(m,{flat:``,dense:``,round:``,icon:`arrow_back`,onClick:r[0]||=e=>d(be).back()}),f(`div`,x,a(n.$t(`health.title`)),1),c(_),c(m,{flat:``,dense:``,icon:`refresh`,loading:Y.value,label:n.$t(`common.refresh`),onClick:X},null,8,[`loading`,`label`])]),!J.value&&Y.value?(e(),u(`div`,S,a(n.$t(`common.loading`)),1)):J.value?(e(),u(`div`,C,[c(h,{dark:``,flat:``,bordered:``},{default:i(()=>[c(g,null,{default:i(()=>[f(`div`,w,a(n.$t(`health.envTitle`)),1),f(`div`,T,a(n.$t(`health.koboHome`)),1),f(`div`,E,a(J.value.koboHome),1)]),_:1})]),_:1}),c(h,{dark:``,flat:``,bordered:``},{default:i(()=>[c(g,null,{default:i(()=>[f(`div`,D,[f(`div`,O,a(n.$t(`health.dbTitle`)),1),c(_),c(p,{name:Q(Z.value),color:$(Z.value)},null,8,[`name`,`color`])]),f(`div`,k,[f(`div`,A,[f(`div`,j,a(n.$t(`health.dbPath`)),1),f(`div`,M,a(J.value.db.path),1)]),f(`div`,N,[f(`div`,P,a(n.$t(`health.dbSize`)),1),f(`div`,F,a(xe.value),1)]),f(`div`,I,[f(`div`,L,a(n.$t(`health.schemaVersion`)),1),f(`div`,R,a(J.value.db.schemaVersion)+` / `+a(J.value.db.currentSchemaVersion),1)])])]),_:1})]),_:1}),c(h,{dark:``,flat:``,bordered:``},{default:i(()=>[c(g,null,{default:i(()=>[f(`div`,z,[f(`div`,B,a(n.$t(`health.cliTitle`)),1),c(_),c(p,{name:Q(J.value.claudeCli.available),color:$(J.value.claudeCli.available)},null,8,[`name`,`color`])]),J.value.claudeCli.available?(e(),u(`div`,V,a(J.value.claudeCli.version),1)):(e(),u(`div`,se,a(n.$t(`health.cliMissing`)),1))]),_:1})]),_:1}),c(h,{dark:``,flat:``,bordered:``},{default:i(()=>[c(g,null,{default:i(()=>[f(`div`,H,[f(`div`,U,a(n.$t(`health.workspacesTitle`)),1),c(_),c(p,{name:Q(J.value.workspaces.worktreesMissing.length===0),color:$(J.value.workspaces.worktreesMissing.length===0)},null,8,[`name`,`color`])]),f(`div`,W,a(n.$t(`health.workspacesCount`,{total:J.value.workspaces.total,archived:J.value.workspaces.archived})),1),J.value.workspaces.worktreesMissing.length>0?(e(),u(`div`,G,[f(`div`,K,a(n.$t(`health.worktreesMissing`,{count:J.value.workspaces.worktreesMissing.length})),1),c(v,{dense:``,dark:``},{default:i(()=>[(e(!0),u(te,null,t(J.value.workspaces.worktreesMissing,t=>(e(),o(ie,{key:t.workspaceId},{default:i(()=>[c(ae,null,{default:i(()=>[f(`div`,ce,a(t.name),1),f(`div`,le,a(t.path),1)]),_:2},1024)]),_:2},1024))),128))]),_:1})])):s(``,!0)]),_:1})]),_:1}),c(h,{dark:``,flat:``,bordered:``},{default:i(()=>[c(g,null,{default:i(()=>[f(`div`,ue,[f(`div`,de,a(n.$t(`health.sessionsTitle`)),1),c(_),c(p,{name:Q(J.value.agentSessions.orphaned===0),color:$(J.value.agentSessions.orphaned===0)},null,8,[`name`,`color`])]),f(`div`,{class:ee([`text-caption q-mt-xs`,J.value.agentSessions.orphaned>0?`text-negative`:`text-grey-6`])},a(n.$t(`health.sessionsOrphaned`,{n:J.value.agentSessions.orphaned})),3)]),_:1})]),_:1}),c(h,{dark:``,flat:``,bordered:``},{default:i(()=>[c(g,null,{default:i(()=>[f(`div`,fe,a(n.$t(`health.integrationsTitle`)),1),f(`div`,pe,[f(`div`,me,[c(p,{name:Q(J.value.integrations.notion.configured),color:$(J.value.integrations.notion.configured),size:`sm`},null,8,[`name`,`color`]),r[1]||=f(`span`,{class:`q-ml-sm text-body2`},`Notion`,-1),f(`span`,he,a(J.value.integrations.notion.configured?n.$t(`health.integrationConfigured`):n.$t(`health.integrationMissing`)),1)]),f(`div`,ge,[c(p,{name:Q(J.value.integrations.sentry.configured),color:$(J.value.integrations.sentry.configured),size:`sm`},null,8,[`name`,`color`]),r[2]||=f(`span`,{class:`q-ml-sm text-body2`},`Sentry`,-1),f(`span`,_e,a(J.value.integrations.sentry.configured?n.$t(`health.integrationConfigured`):n.$t(`health.integrationMissing`)),1)]),f(`div`,ve,[c(p,{name:Q(J.value.integrations.editor.configured),color:$(J.value.integrations.editor.configured),size:`sm`},null,8,[`name`,`color`]),r[3]||=f(`span`,{class:`q-ml-sm text-body2`},`Editor`,-1),f(`span`,ye,a(J.value.integrations.editor.configured?n.$t(`health.integrationConfigured`):n.$t(`health.integrationMissing`)),1)])])]),_:1})]),_:1})])):s(``,!0)]),_:1}))}});export{q as default};
|