claude-code-session-manager 0.92.1 → 0.94.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/dist/assets/DataModel-B0LDnnSL.js +1 -0
- package/dist/assets/{History-BOR_fJNr.js → History-C685Kytt.js} +2 -2
- package/dist/assets/{Hooks-BtD436iL.js → Hooks-CwLnp0Z_.js} +3 -3
- package/dist/assets/HostBilko-CwEHEKYk.js +1 -0
- package/dist/assets/{Library-DeKdY-tD.js → Library-BU9np05E.js} +25 -25
- package/dist/assets/{MarkdownEditor-CbzC-Oqf.js → MarkdownEditor-B74ogK2f.js} +1 -1
- package/dist/assets/McpServers-BLM3ftzP.js +2 -0
- package/dist/assets/{Memory-B68AJjg2.js → Memory-DAP1t8bA.js} +6 -6
- package/dist/assets/{Permissions-Cr0RRvNy.js → Permissions-3pGLJmxQ.js} +3 -3
- package/dist/assets/Plugins-Q1KoLEzn.js +2 -0
- package/dist/assets/ProvenanceBadge-BnjBQiV9.js +1 -0
- package/dist/assets/{SaveBar-87ZJfscX.js → SaveBar-Zq2NfcPf.js} +1 -1
- package/dist/assets/Scheduler-D488ebKm.js +16 -0
- package/dist/assets/{ScopeSwitcher-CKzpqjJ_.js → ScopeSwitcher-Cnojv22D.js} +1 -1
- package/dist/assets/Settings-D5Lhj7ga.js +3 -0
- package/dist/assets/{SkillReferenceGraph-D_-wg4r9.js → SkillReferenceGraph-BRDiE6Hv.js} +2 -2
- package/dist/assets/Skills-BQDqp-EN.js +3 -0
- package/dist/assets/SystemPrompt-tFr19Od6.js +1 -0
- package/dist/assets/TagLibrary-BjyrnaRE.js +1 -0
- package/dist/assets/{TiptapBody-DYXIp8aG.js → TiptapBody-DGzSg3BO.js} +1 -1
- package/dist/assets/{Toggle-CDXR5l3m.js → Toggle-DzoROibf.js} +1 -1
- package/dist/assets/index-CCl4tz-u.js +3079 -0
- package/dist/assets/{index-D3P_jldk.css → index-CKH5Uxik.css} +1 -1
- package/dist/assets/settingsSchema-BYKVe1WM.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +6 -3
- package/scripts/README.md +3 -0
- package/src/main/__tests__/agentEffortResolve.test.cjs +117 -0
- package/src/main/__tests__/agentLibrary.test.cjs +21 -0
- package/src/main/__tests__/agentModelResolve.test.cjs +16 -0
- package/src/main/__tests__/agentOverlayWrite.test.cjs +95 -0
- package/src/main/__tests__/chat-cancel-terminal.test.cjs +5 -2
- package/src/main/__tests__/chat-exit-close-race.test.cjs +8 -2
- package/src/main/__tests__/chat-mcp-consent-notice.test.cjs +5 -2
- package/src/main/__tests__/chatRunner-session-flag-retry.test.cjs +44 -0
- package/src/main/__tests__/intradayRefresh.test.cjs +39 -0
- package/src/main/__tests__/openExternalApp-spawn-error.test.cjs +25 -0
- package/src/main/__tests__/opsErrorLog.test.cjs +22 -0
- package/src/main/__tests__/personaMerge.test.cjs +169 -0
- package/src/main/__tests__/prdCreatePlanId.test.cjs +132 -0
- package/src/main/__tests__/promptSessionsCreateEpicHandler.test.cjs +13 -0
- package/src/main/__tests__/pty-epic-worktree-spawn-cwd.test.cjs +21 -0
- package/src/main/__tests__/rateLimitPollerStreak.test.cjs +14 -0
- package/src/main/__tests__/runVerify-atomic-verdicts.test.cjs +26 -0
- package/src/main/__tests__/runVerify-landed-commit-outranks.test.cjs +11 -1
- package/src/main/__tests__/runVerify-transcript-commit-evidence.test.cjs +11 -1
- package/src/main/__tests__/runVerify.test.cjs +12 -1
- package/src/main/__tests__/scheduler-prd-persona-spawn.test.cjs +47 -2
- package/src/main/__tests__/transcriptsUsageFor.test.cjs +112 -1
- package/src/main/agentLibrary.cjs +86 -40
- package/src/main/build-info.json +4 -4
- package/src/main/chatRunner.cjs +50 -10
- package/src/main/git.cjs +9 -2
- package/src/main/historyAggregator.cjs +2 -19
- package/src/main/index.cjs +17 -8
- package/src/main/ipcSchemas.cjs +25 -3
- package/src/main/lib/__tests__/childWithLog.test.cjs +180 -0
- package/src/main/lib/__tests__/delegationReadiness.test.cjs +19 -0
- package/src/main/lib/__tests__/effectiveModelInfo.test.cjs +10 -5
- package/src/main/lib/__tests__/gitCacheBound.test.cjs +69 -0
- package/src/main/lib/__tests__/modelCatalog.test.cjs +202 -0
- package/src/main/lib/agentEffortResolve.cjs +74 -0
- package/src/main/lib/agentModelResolve.cjs +52 -59
- package/src/main/lib/agentPersonaSchema.cjs +5 -0
- package/src/main/lib/childWithLog.cjs +92 -51
- package/src/main/lib/delegationReadiness.cjs +3 -1
- package/src/main/lib/effectiveModelInfo.cjs +38 -20
- package/src/main/lib/epicMint.cjs +5 -2
- package/src/main/lib/epicSpawnPlan.cjs +27 -8
- package/src/main/lib/epicTranscriptPath.cjs +5 -1
- package/src/main/lib/epicWorktreeMerge.cjs +7 -6
- package/src/main/lib/headTailBuffer.cjs +43 -0
- package/src/main/lib/intradayRefresh.cjs +33 -0
- package/src/main/lib/lruCache.cjs +39 -0
- package/src/main/lib/modelCatalog.cjs +243 -0
- package/src/main/lib/openExternalApp.cjs +27 -9
- package/src/main/lib/opsErrorLog.cjs +22 -0
- package/src/main/lib/personaMerge.cjs +166 -0
- package/src/main/lib/prdCreate.cjs +23 -5
- package/src/main/lib/prdDisposition.cjs +46 -0
- package/src/main/lib/prdFrontmatter.cjs +6 -2
- package/src/main/lib/promptSessionSchema.cjs +5 -0
- package/src/main/lib/promptSessionsCreateEpic.cjs +5 -3
- package/src/main/lib/rendererRecovery.cjs +141 -0
- package/src/main/lib/scheduleJobSchema.cjs +3 -0
- package/src/main/runVerify.cjs +3 -1
- package/src/main/scheduler/prdParser.cjs +2 -0
- package/src/main/scheduler.cjs +381 -262
- package/src/main/templates/PRD_AUTHORING.md +4 -0
- package/src/main/transcripts.cjs +54 -11
- package/src/preload/api.d.ts +56 -3
- package/src/preload/index.cjs +4 -0
- package/dist/assets/AgentLibrary-Ci6u03bq.js +0 -3
- package/dist/assets/DataModel-BIqcjsv2.js +0 -1
- package/dist/assets/HostBilko-CMe5cH3H.js +0 -1
- package/dist/assets/ListDetail-CtVjrHKB.js +0 -1
- package/dist/assets/McpServers-DKN75Shn.js +0 -2
- package/dist/assets/Panel-C2YTW-qP.js +0 -1
- package/dist/assets/Plugins-DbZkJs5l.js +0 -2
- package/dist/assets/ProvenanceBadge-kJ__BOQv.js +0 -1
- package/dist/assets/Scheduler-DdEaxku8.js +0 -16
- package/dist/assets/Settings-CjywVsNB.js +0 -3
- package/dist/assets/Skills-Cd_yPO_l.js +0 -3
- package/dist/assets/SystemPrompt-2z6eGPSF.js +0 -1
- package/dist/assets/TagLibrary-DcaWQSp4.js +0 -1
- package/dist/assets/index-D5H_H5wC.js +0 -3074
- package/dist/assets/settingsSchema-JRDfjgHb.js +0 -3
|
@@ -141,6 +141,10 @@ estimateMinutes: 60
|
|
|
141
141
|
- `estimateMinutes` is used for ETA display; include a realistic estimate (note: empirical median is ~10 min, p90 ~20 min — avoid wildly inflated estimates that hide real outliers).
|
|
142
142
|
- `parallelGroup` in frontmatter, when present, IS honored by the scheduler (`pickNextBatch` reads `parallelGroup ?? 99` and overrides the filename NN). Use this only for cross-stream interleaving — e.g., the cellar series `122-`, `123-`, `124-` overrides to groups `113`, `114`, `115` so cellar steps fire alongside the parallel etch steps. Do NOT use it to reorder within a single stream; rename the file instead.
|
|
143
143
|
|
|
144
|
+
### `planId` (API-owned — never pass it)
|
|
145
|
+
|
|
146
|
+
`planId` is a frontmatter key that `createPrd` stamps on every PRD: the durable identity of the plan (wave) the PRD belongs to. An `append` PRD (or one with an explicit `dependsOn`) inherits the planId of the PRD(s) it attaches behind; a first-ever or `new-head` PRD mints a fresh one. The Scheduler tracker groups by it, so a second plan in one Epic is a recorded fact, not a re-derivation. Callers never pass or hand-write it — `scheduler_create_prd` ignores it. PRDs without one (pre-stamp) fall back to dependency-graph grouping.
|
|
147
|
+
|
|
144
148
|
### Artifact-only PRDs
|
|
145
149
|
|
|
146
150
|
Use `deliverable: artifact` + `artifactPaths: [a, b]` (both passed to `scheduler_create_prd`) ONLY when every deliverable is a file the target repo deliberately git-excludes (e.g. patches/notes under `session-manager-operations/review-records/`, matched by `.git/info/exclude`), so "no commit" is the correct outcome.
|
package/src/main/transcripts.cjs
CHANGED
|
@@ -37,6 +37,7 @@ function attachWindow(w) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const { encodeCwd } = require('./lib/encodeCwd.cjs');
|
|
40
|
+
const { LRUCache } = require('./lib/lruCache.cjs');
|
|
40
41
|
const { classifyLine } = require('./lib/classifyTranscriptLine.cjs');
|
|
41
42
|
const { resolveEpicTranscriptPath } = require('./lib/epicTranscriptPath.cjs');
|
|
42
43
|
|
|
@@ -449,21 +450,32 @@ async function getBuffer(tabId) {
|
|
|
449
450
|
// this size report null (omitted by the renderer) rather than a partial sum.
|
|
450
451
|
const MAX_USAGE_FILE_BYTES = 64 * 1024 * 1024;
|
|
451
452
|
|
|
452
|
-
/**
|
|
453
|
-
const
|
|
453
|
+
/** Max distinct transcripts whose running totals stay cached. */
|
|
454
|
+
const USAGE_CACHE_MAX = 200;
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* LRU<filePath, { ino, size, mtimeMs, readOffset, usage }>. `readOffset` is the
|
|
458
|
+
* byte just past the last complete (newline-terminated) line already summed, so
|
|
459
|
+
* the next call only parses [readOffset, size). The full parse keeps no
|
|
460
|
+
* de-dup state (every usage event is summed), so none is cached here.
|
|
461
|
+
*/
|
|
462
|
+
const usageCache = new LRUCache(USAGE_CACHE_MAX);
|
|
454
463
|
|
|
455
464
|
/**
|
|
456
465
|
* Sum `usage` events out of one session's JSONL transcript — same
|
|
457
466
|
* classifyLine()/field-name resolution live.ts's ingest uses for its running
|
|
458
467
|
* per-tab totals (input_tokens/output_tokens, snake_case on the wire).
|
|
459
|
-
*
|
|
460
|
-
*
|
|
468
|
+
* Append-only tail parse: when the inode matches and the file has not shrunk,
|
|
469
|
+
* only the new bytes are read (positional fd.read) and a trailing partial line
|
|
470
|
+
* waits until completed; truncation / inode change → full re-parse.
|
|
471
|
+
* Cost per call: O(appended bytes) time and space; O(file) only on cold/reset.
|
|
461
472
|
*/
|
|
462
473
|
async function usageForOne(filePath) {
|
|
463
474
|
const stat = await fsp.stat(filePath).catch(() => null);
|
|
464
475
|
if (!stat) return null;
|
|
465
476
|
const cached = usageCache.get(filePath);
|
|
466
|
-
|
|
477
|
+
const canTail = !!cached && cached.ino === stat.ino && stat.size >= cached.readOffset;
|
|
478
|
+
if (canTail && cached.size === stat.size && cached.mtimeMs === stat.mtimeMs) {
|
|
467
479
|
return cached.usage;
|
|
468
480
|
}
|
|
469
481
|
if (stat.size > MAX_USAGE_FILE_BYTES) {
|
|
@@ -475,11 +487,33 @@ async function usageForOne(filePath) {
|
|
|
475
487
|
});
|
|
476
488
|
return null;
|
|
477
489
|
}
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
let
|
|
481
|
-
|
|
482
|
-
|
|
490
|
+
const start = canTail ? cached.readOffset : 0;
|
|
491
|
+
let inputTokens = canTail ? cached.usage.inputTokens : 0;
|
|
492
|
+
let outputTokens = canTail ? cached.usage.outputTokens : 0;
|
|
493
|
+
const want = stat.size - start;
|
|
494
|
+
let buf = Buffer.alloc(0);
|
|
495
|
+
if (want > 0) {
|
|
496
|
+
let fd;
|
|
497
|
+
try {
|
|
498
|
+
fd = await fsp.open(filePath, 'r');
|
|
499
|
+
buf = Buffer.alloc(want);
|
|
500
|
+
let got = 0;
|
|
501
|
+
while (got < want) {
|
|
502
|
+
const { bytesRead } = await fd.read(buf, got, want - got, start + got);
|
|
503
|
+
if (bytesRead === 0) break;
|
|
504
|
+
got += bytesRead;
|
|
505
|
+
}
|
|
506
|
+
buf = buf.subarray(0, got);
|
|
507
|
+
} catch {
|
|
508
|
+
return null;
|
|
509
|
+
} finally {
|
|
510
|
+
await fd?.close().catch(() => {});
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
// Consume only complete lines; a trailing partial line is re-read next call.
|
|
514
|
+
const lastNl = buf.lastIndexOf(0x0a);
|
|
515
|
+
const complete = lastNl === -1 ? '' : buf.subarray(0, lastNl + 1).toString('utf8');
|
|
516
|
+
for (const line of complete.split('\n')) {
|
|
483
517
|
if (!line) continue;
|
|
484
518
|
let obj;
|
|
485
519
|
try {
|
|
@@ -496,7 +530,13 @@ async function usageForOne(filePath) {
|
|
|
496
530
|
}
|
|
497
531
|
}
|
|
498
532
|
const usage = { inputTokens, outputTokens };
|
|
499
|
-
usageCache.set(filePath, {
|
|
533
|
+
usageCache.set(filePath, {
|
|
534
|
+
ino: stat.ino,
|
|
535
|
+
size: stat.size,
|
|
536
|
+
mtimeMs: stat.mtimeMs,
|
|
537
|
+
readOffset: start + lastNl + 1,
|
|
538
|
+
usage,
|
|
539
|
+
});
|
|
500
540
|
return usage;
|
|
501
541
|
}
|
|
502
542
|
|
|
@@ -562,6 +602,9 @@ module.exports = {
|
|
|
562
602
|
// Test-only accessor onto the raw Subscription object (its lineIndex in
|
|
563
603
|
// particular) — asserting a memory ceiling requires inspecting what's
|
|
564
604
|
// actually held, not just what a read API returns.
|
|
605
|
+
__usageCacheForTest: usageCache,
|
|
606
|
+
__usageForOneForTest: usageForOne,
|
|
607
|
+
__usageCacheMaxForTest: USAGE_CACHE_MAX,
|
|
565
608
|
__getSubForTest: (tabId) => subs.get(tabId),
|
|
566
609
|
// Test-only: run a live (emit:true) flush directly against a subscription,
|
|
567
610
|
// without going through the chokidar watcher — lets batching/IPC-shape
|
package/src/preload/api.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { PromptSession } from '../renderer/state/promptSessions';
|
|
2
|
+
|
|
1
3
|
export interface BuildTarget {
|
|
2
4
|
registry: string;
|
|
3
5
|
packageName: string;
|
|
@@ -235,6 +237,8 @@ export interface AgentPersona {
|
|
|
235
237
|
description: string | null;
|
|
236
238
|
tools: string[];
|
|
237
239
|
model: string | null;
|
|
240
|
+
/** Per-Epic reasoning effort (`effort:` frontmatter; a `models.catalog` effort level). Null = inherit. Passed to the claude spawn as `--effort` (never `auto`). */
|
|
241
|
+
effort: string | null;
|
|
238
242
|
color: string | null;
|
|
239
243
|
/** Epic intent tags (tagLibrary.ts's TAG_LIBRARY) this persona is associated with. */
|
|
240
244
|
tags: AgentPersonaTag[];
|
|
@@ -253,6 +257,8 @@ export interface AgentPersona {
|
|
|
253
257
|
body: string;
|
|
254
258
|
/** Project names (basename of cwd) whose currently-open tab overlays this agent. */
|
|
255
259
|
overridingProjects: string[];
|
|
260
|
+
/** Per open project with an overlay: which frontmatter keys / body the overlay overrides (merged view provenance). */
|
|
261
|
+
overrideDetails?: { project: string; fields: string[]; values?: Record<string, string>; bodyOverridden: boolean; issue: string | null }[];
|
|
256
262
|
}
|
|
257
263
|
|
|
258
264
|
/** Payload for `agents.savePersona` — creates or overwrites a global persona file. */
|
|
@@ -263,6 +269,8 @@ export interface AgentPersonaSaveInput {
|
|
|
263
269
|
description: string;
|
|
264
270
|
tools: string[];
|
|
265
271
|
model: string;
|
|
272
|
+
/** Effort level, or `'inherit'`/omitted to write no `effort:` line. */
|
|
273
|
+
effort?: string;
|
|
266
274
|
color: string;
|
|
267
275
|
tags: AgentPersonaTag[];
|
|
268
276
|
/** Project cwds (or the `'*'` sentinel) this persona's Action button appears in. */
|
|
@@ -272,6 +280,8 @@ export interface AgentPersonaSaveInput {
|
|
|
272
280
|
/** Caption override for this persona's Action button. */
|
|
273
281
|
actionLabel?: string;
|
|
274
282
|
title?: string;
|
|
283
|
+
/** Open project name: write that project's frontmatter-only override (only `model`/`effort` are used) instead of the global file. */
|
|
284
|
+
projectName?: string;
|
|
275
285
|
body: string;
|
|
276
286
|
}
|
|
277
287
|
|
|
@@ -556,6 +566,8 @@ export interface ScheduleJob {
|
|
|
556
566
|
* independent root). Refreshed from the PRD file on every reconcile, like
|
|
557
567
|
* dependsOn above; null when this row never needed the decision. */
|
|
558
568
|
disposition?: 'append' | 'new-head' | null;
|
|
569
|
+
/** Durable wave identity stamped into PRD frontmatter by createPrd(); buildPlans groups by it. Null on PRDs that predate the stamp. */
|
|
570
|
+
planId?: string | null;
|
|
559
571
|
/** The originating claude session — the Epic's claudeSessionId, resolved
|
|
560
572
|
* from active-index.json at ingest (PRD 832). An Epic IS a tagged session. */
|
|
561
573
|
originSessionId?: string | null;
|
|
@@ -575,6 +587,9 @@ export interface ScheduleJob {
|
|
|
575
587
|
* intent-carrying `sourcePromptId`/`sourceTabId`, which can disagree.
|
|
576
588
|
* Authoritative source for "which Epic is this from" in every UI. */
|
|
577
589
|
epicId?: string | null;
|
|
590
|
+
/** Renderer-only: true for a row synthesized from an archived PRD file (no queue row
|
|
591
|
+
* exists to act on) — see lib/archivedPlanRows. Never present in queue.json. */
|
|
592
|
+
synthetic?: boolean;
|
|
578
593
|
/** Bounded trail of accepted status transitions (scheduleJobTransitions.cjs's
|
|
579
594
|
* transitionJob), oldest-first, capped at ~20 entries. Lets a status
|
|
580
595
|
* change be reviewed after the fact instead of only inferred from a
|
|
@@ -703,6 +718,8 @@ export interface PrdListItem {
|
|
|
703
718
|
dependsOn?: string[] | null;
|
|
704
719
|
/** PRD frontmatter `disposition` — see ScheduleJob.disposition. */
|
|
705
720
|
disposition?: 'append' | 'new-head' | null;
|
|
721
|
+
/** PRD frontmatter `planId` — see ScheduleJob.planId. */
|
|
722
|
+
planId?: string | null;
|
|
706
723
|
/** True when this PRD's source .md was found in a `prds-archived/` dir
|
|
707
724
|
* (its scheduler job already ran to completion) rather than the live
|
|
708
725
|
* `prds/` dir. Archived PRDs have no matching queue.json job row (the
|
|
@@ -1637,7 +1654,7 @@ export interface SessionManagerAPI {
|
|
|
1637
1654
|
* resolved with project-overlay-then-global precedence for `cwd` — unlike
|
|
1638
1655
|
* `listPersonas` above, which only reads the global directory. Null when neither
|
|
1639
1656
|
* location has the file. */
|
|
1640
|
-
getPersonaBody: (payload: { cwd: string; name: string }) => Promise<{ path: string; text: string } | null>;
|
|
1657
|
+
getPersonaBody: (payload: { cwd: string; name: string }) => Promise<{ path: string; text: string; provenance?: Record<string, 'overlay' | 'global'>; bodySource?: 'overlay' | 'global' } | null>;
|
|
1641
1658
|
/** "What will this Epic actually run as?" — persona alias, overlay-aware
|
|
1642
1659
|
* provenance, and evidence-based concrete model id (scheduler run log or
|
|
1643
1660
|
* session transcript). Never throws on the main side; a dangling
|
|
@@ -1649,9 +1666,15 @@ export interface SessionManagerAPI {
|
|
|
1649
1666
|
agentType: string;
|
|
1650
1667
|
modelAlias: string | null;
|
|
1651
1668
|
modelSource: 'persona' | 'persona-overlay' | 'inherit' | 'fallback';
|
|
1669
|
+
/** Per-frontmatter-key origin of the merged persona (overlay vs global). */
|
|
1670
|
+
personaProvenance?: Record<string, 'overlay' | 'global'>;
|
|
1652
1671
|
resolvedModelId: string | null;
|
|
1653
1672
|
resolvedFrom: 'scheduler-run' | 'transcript' | null;
|
|
1654
|
-
|
|
1673
|
+
/** Env-var path only: would cleanChildEnv strip CLAUDE_EFFORT. Persona effort travels on argv regardless. */
|
|
1674
|
+
effortEnvReachable: boolean;
|
|
1675
|
+
/** Persona `effort:` level (null = pass no --effort) and where it came from. */
|
|
1676
|
+
personaEffort: string | null;
|
|
1677
|
+
personaEffortSource: 'persona' | 'persona-overlay' | 'inherit' | null;
|
|
1655
1678
|
}>;
|
|
1656
1679
|
/** The launch-time authority for an Epic-backed session's `--model`: the SAME
|
|
1657
1680
|
* resolver (`agentModelResolve.cjs`'s `resolveEpicModel`) chatRunner.cjs's Chat
|
|
@@ -1660,9 +1683,36 @@ export interface SessionManagerAPI {
|
|
|
1660
1683
|
* (project `.claude/agents/<name>.md` wins over global), never throws — a
|
|
1661
1684
|
* dangling agentType or absent/`inherit` model falls back to `'sonnet'`. */
|
|
1662
1685
|
resolveEpicModel: (payload: { cwd: string; claudeSessionId: string }) => Promise<string>;
|
|
1686
|
+
/** Effort twin of `resolveEpicModel` (`agentEffortResolve.cjs`): the persona `effort:` level
|
|
1687
|
+
* Terminal must launch with, or `effort: null` = append NO `--effort` flag (inherit / absent /
|
|
1688
|
+
* dangling persona). Chat resolves the same value in-process. Never throws. */
|
|
1689
|
+
resolveEpicEffort: (payload: { cwd: string; claudeSessionId: string }) => Promise<{
|
|
1690
|
+
effort: string | null;
|
|
1691
|
+
source: 'persona' | 'persona-overlay' | 'inherit' | null;
|
|
1692
|
+
}>;
|
|
1663
1693
|
/** Fires after any save/delete/removeOverride — subscribers should re-fetch listPersonas(). */
|
|
1664
1694
|
onChanged: (handler: () => void) => () => void;
|
|
1665
1695
|
};
|
|
1696
|
+
models: {
|
|
1697
|
+
/** Live model/effort catalog (`modelCatalog.cjs`'s `resolveModelCatalog`). Never rejects from
|
|
1698
|
+
* the resolver itself — a failed probe degrades down cache → floor and sets `degraded`.
|
|
1699
|
+
* `cwd` only affects `availableModels` (settings-scope allowlist); `force` bypasses the cache. */
|
|
1700
|
+
catalog: (payload: { cwd?: string; force?: boolean }) => Promise<{
|
|
1701
|
+
aliases: string[];
|
|
1702
|
+
models: string[];
|
|
1703
|
+
effortLevels: string[];
|
|
1704
|
+
settingsEffortLevels: string[];
|
|
1705
|
+
availableModels: string[] | null;
|
|
1706
|
+
claudeVersion: string | null;
|
|
1707
|
+
probedAt: string | null;
|
|
1708
|
+
sources: {
|
|
1709
|
+
aliases: 'probe' | 'cache' | 'floor';
|
|
1710
|
+
models: 'binary' | 'cache' | 'floor';
|
|
1711
|
+
effortLevels: 'probe' | 'cache' | 'floor';
|
|
1712
|
+
};
|
|
1713
|
+
degraded: boolean;
|
|
1714
|
+
}>;
|
|
1715
|
+
};
|
|
1666
1716
|
logs: {
|
|
1667
1717
|
write: (
|
|
1668
1718
|
scope: string,
|
|
@@ -2053,6 +2103,9 @@ export interface PromptSessionsCreateEpicPayload {
|
|
|
2053
2103
|
goalText: string;
|
|
2054
2104
|
tag?: 'feature' | 'bug' | 'discussion' | 'build' | 'project-home-builder' | 'bilko-host-publisher';
|
|
2055
2105
|
agentType?: string;
|
|
2106
|
+
/** Per-Epic model/effort overrides (New Session card); omitted = the persona's own. */
|
|
2107
|
+
model?: string;
|
|
2108
|
+
effort?: string;
|
|
2056
2109
|
source?: {
|
|
2057
2110
|
producer: 'new-epic-ui' | 'scheduler-dispatch';
|
|
2058
2111
|
prdSlug?: string;
|
|
@@ -2073,7 +2126,7 @@ export interface PromptSessionsCreateEpicPayload {
|
|
|
2073
2126
|
|
|
2074
2127
|
export interface PromptSessionsCreateEpicResult {
|
|
2075
2128
|
epicId: string;
|
|
2076
|
-
session:
|
|
2129
|
+
session: PromptSession;
|
|
2077
2130
|
}
|
|
2078
2131
|
|
|
2079
2132
|
// ─────────────────────────────────── PromptSessions create-worktree (main-side createEpicWorktree)
|
package/src/preload/index.cjs
CHANGED
|
@@ -108,6 +108,7 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
108
108
|
getPersonaBody: (payload) => ipcRenderer.invoke('agents:get-persona-body', payload),
|
|
109
109
|
resolveModelInfo: (payload) => ipcRenderer.invoke('agents:resolve-model-info', payload),
|
|
110
110
|
resolveEpicModel: (payload) => ipcRenderer.invoke('agents:resolve-epic-model', payload),
|
|
111
|
+
resolveEpicEffort: (payload) => ipcRenderer.invoke('agents:resolve-epic-effort', payload),
|
|
111
112
|
// Fired after any save/delete/removeOverride so every mounted
|
|
112
113
|
// subscriber (Agent Library, Tag Library) re-fetches the same file.
|
|
113
114
|
onChanged: (handler) => {
|
|
@@ -116,6 +117,9 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
116
117
|
return () => ipcRenderer.removeListener('agents:changed', listener);
|
|
117
118
|
},
|
|
118
119
|
},
|
|
120
|
+
models: {
|
|
121
|
+
catalog: (payload) => ipcRenderer.invoke('models:catalog', payload),
|
|
122
|
+
},
|
|
119
123
|
logs: {
|
|
120
124
|
// ctx is optional: { cwd, tabId, epicId, tags } — when present and
|
|
121
125
|
// level is 'error', main also appends a tagged line to that project's
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{ah as e,U as V,au as h,l as B,b as P,aH as w,aE as X,T as _,aG as Z,aO as ee,A as T}from"./index-D5H_H5wC.js";import{P as te}from"./Panel-C2YTW-qP.js";import{L as ne}from"./ListDetail-CtVjrHKB.js";import"./monaco-editor-BW5C4Iv1.js";function y({children:t,onClick:r,disabled:g,variant:f="default",tooltip:l,type:m="button",className:c}){const u=`px-2 py-0.5 text-xs rounded border transition-colors disabled:opacity-40 disabled:cursor-not-allowed ${f==="primary"?"text-accent border-accent/50 hover:bg-bg-hi":f==="danger"?"text-red-400 hover:text-red-300 border-line hover:border-red-400/50":"text-fg-dim border-line hover:text-fg hover:bg-bg-hi"} ${c??""}`,a=e.jsx("button",{type:m,title:l,onClick:r,disabled:g,className:u,children:t});return l?e.jsx(V,{content:l,align:"bottom-center",children:a}):a}const ae=["inherit","haiku","sonnet","opus","fable"],G=["Read","Grep","Glob","Bash","Write","Edit","WebFetch","WebSearch","Task"],se=["","red","orange","yellow","green","cyan","blue","purple","pink"],K={red:"#c0392b",orange:"#b85c34",yellow:"#c9a227",green:"#6f7d52",cyan:"#3f8f8a",blue:"#4a6fa5",purple:"#7a6a8a",pink:"#b45a80"};function E(t){return{name:t.name,description:t.description??"",tools:t.tools,model:t.model??"inherit",color:t.color??"",tags:t.tags,projects:t.projects??[],action:t.action??"",actionLabel:t.actionLabel??"",body:t.body}}const I={name:"new-agent",description:"",tools:["Read","Grep"],model:"inherit",color:"",tags:[],projects:[],action:"",actionLabel:"",body:""},re=new Set(_.map(t=>t.tag));function oe(t){return t.filter(r=>re.has(r))}function ie(){const[t,r]=h.useState(null),[g,f]=h.useState(null),[l,m]=h.useState(""),[c,i]=h.useState(null),[u,a]=h.useState(!1),[v,N]=h.useState(!1),[D,C]=h.useState(null),[k,s]=h.useState(!1),j=h.useRef(!0);h.useEffect(()=>()=>{j.current=!1},[]);const p=async n=>{try{const x=await window.api.agents.listPersonas();if(!j.current)return;r(x),f(L=>{var O;return n??L??((O=x[0])==null?void 0:O.name)??null})}catch(x){if(!j.current)return;r([]),w.error(x.message||"failed to load agent personas")}};if(h.useEffect(()=>{p()},[]),h.useEffect(()=>window.api.agents.onChanged(()=>p()),[]),h.useEffect(()=>{const n=X();n&&f(n);const x=L=>f(L.detail);return window.addEventListener("sm:select-persona",x),()=>window.removeEventListener("sm:select-persona",x)},[]),t===null)return e.jsx(B,{title:"loading…"});const $=l.toLowerCase(),R=t.filter(n=>!$||n.name.toLowerCase().includes($)||(n.description??"").toLowerCase().includes($)),d=t.find(n=>n.name===g)??t[0]??null,o=c??(d?E(d):null),F=!!c&&!!d&&JSON.stringify(c)!==JSON.stringify(E(d)),S=u,W=n=>{i(null),a(!1),N(!1),C(null),f(n)},z=n=>i(x=>({...x??(d?E(d):I),...n})),M=()=>{i({...I}),a(!0),N(!1)},J=()=>{o&&(i({...o,name:o.name+"-copy"}),a(!0))},H=()=>{i(null),a(!1)},U=async()=>{if(o){if(!/^[a-z][a-z0-9-]*$/.test(o.name)){w.error('agent name must be lowercase, hyphenated (e.g. "my-agent")');return}s(!0);try{const n={name:o.name,originalName:S||d==null?void 0:d.name,description:o.description,tools:o.tools,model:o.model,color:o.color,tags:oe(o.tags),projects:o.projects,action:o.action,actionLabel:o.actionLabel,body:o.body};await window.api.agents.savePersona(n),w.info(S?`created ${o.name}`:`saved ${o.name}`),i(null),a(!1),await p(o.name)}catch(n){w.error(n.message||"failed to save agent persona")}finally{s(!1)}}},Y=async()=>{if(d){s(!0);try{await window.api.agents.deletePersona({name:d.name}),w.info(`deleted ${d.name}`),N(!1),i(null),a(!1),await p()}catch(n){w.error(n.message||"failed to delete agent persona")}finally{s(!1)}}},q=async n=>{s(!0);try{await window.api.agents.deletePersona({name:n}),w.info(`deleted ${n}`),C(null),g===n&&(i(null),a(!1)),await p()}catch(x){w.error(x.message||"failed to delete agent persona")}finally{s(!1)}},Q=async n=>{if(d)try{await window.api.agents.removeOverride({name:d.name,projectName:n}),w.info(`removed ${n}'s override of ${d.name}`),await p(d.name)}catch(x){w.error(x.message||"failed to remove override")}};return e.jsx(te,{toolbar:e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"text-fg-faint",children:[t.length," persona",t.length===1?"":"s"]}),e.jsx("input",{value:l,onChange:n=>m(n.target.value),placeholder:"filter…",className:"bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg w-40"}),e.jsx("div",{className:"flex-1"}),e.jsx(y,{variant:"primary",onClick:M,children:"+ New agent"})]}),children:e.jsx(ne,{sidebar:e.jsxs("div",{className:"py-1",children:[S&&e.jsx("div",{className:"w-full text-left px-3 py-1 text-xs flex flex-col gap-0.5 bg-bg-hi text-fg border-l-2 border-accent",children:e.jsxs("span",{className:"flex items-center gap-2 justify-between w-full",children:[e.jsx("span",{className:"truncate font-mono",children:o==null?void 0:o.name}),e.jsx("span",{className:"shrink-0 text-[10px] font-semibold text-accent",children:"new"})]})}),R.length===0&&!S?e.jsx("div",{className:"px-3 py-1 text-xs text-fg-faint italic",children:"no agent personas found"}):R.map(n=>{const x=!S&&n.name===g,L=x&&F,O=D===n.name;return e.jsxs("div",{"data-agent-row":n.name,className:`group w-full text-left px-3 py-1 text-xs flex flex-col gap-0.5 border-l-2 cursor-pointer ${x?"bg-bg-hi text-fg border-accent":"text-fg-dim hover:text-fg hover:bg-bg-hi border-transparent"}`,onClick:()=>W(n.name),children:[e.jsxs("span",{className:"flex items-center gap-2 justify-between w-full",children:[e.jsxs("span",{className:"flex items-center gap-1.5 min-w-0",children:[e.jsx("span",{className:"w-2 h-2 rounded-sm shrink-0",style:{background:n.color?K[n.color]??n.color:"var(--fg-faint, #999)",opacity:n.color?1:.35}}),e.jsx("span",{className:"truncate font-mono",children:n.name})]}),e.jsxs("span",{className:"shrink-0 flex items-center gap-1.5",children:[L&&e.jsx("span",{className:"text-[10px] font-semibold text-accent",children:"unsaved"}),!L&&n.overridingProjects.length>0&&e.jsxs(P,{tone:"dim",children:[n.overridingProjects.length," override",n.overridingProjects.length>1?"s":""]}),O?e.jsxs("span",{className:"flex items-center gap-1",onClick:A=>A.stopPropagation(),children:[e.jsx("button",{onClick:()=>q(n.name),disabled:k,title:`Delete ${n.name}`,className:"text-[10px] font-semibold text-red-400 hover:text-red-300",children:"confirm"}),e.jsx("button",{onClick:()=>C(null),title:"Cancel",className:"text-[10px] text-fg-faint hover:text-fg",children:"cancel"})]}):e.jsx("button",{onClick:A=>{A.stopPropagation(),C(n.name)},title:`Delete ${n.name}`,className:"opacity-0 group-hover:opacity-100 text-fg-faint hover:text-red-400 transition-opacity",children:"×"})]})]}),n.description&&e.jsx("span",{className:"truncate text-fg-faint",children:n.description})]},n.name)})]}),detail:o?e.jsx(le,{obj:o,set:z,saved:d,dirty:F,isNew:S,busy:k,confirmDelete:v,setConfirmDelete:N,onDuplicate:J,onRevert:H,onSave:U,onDelete:Y,onDropOverride:Q}):e.jsx(B,{title:"select an agent"})})})}const he=h.memo(ie);function le({obj:t,set:r,saved:g,dirty:f,isNew:l,busy:m,confirmDelete:c,setConfirmDelete:i,onDuplicate:u,onRevert:a,onSave:v,onDelete:N,onDropOverride:D}){const C=`~/.claude/agents/${t.name}.md`,k=f||l;return e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"px-4 py-3 border-b border-line flex items-center gap-2 flex-wrap",children:[e.jsx("span",{className:"text-sm font-semibold text-fg font-mono",children:t.name}),l?e.jsx(P,{tone:"accent",children:"unsaved draft"}):f?e.jsx(P,{tone:"warn",children:"edited"}):e.jsx(P,{tone:"good",children:"saved"}),e.jsx("span",{className:"ml-auto text-[11px] text-fg-faint font-mono",children:C})]}),e.jsxs("div",{className:"p-4 space-y-4",children:[e.jsx(b,{label:"name",hint:"Filename on disk — lowercase, hyphenated.",children:e.jsx("input",{value:t.name,onChange:s=>r({name:s.target.value.toLowerCase()}),className:"w-full bg-bg border border-line rounded px-2 py-1 text-xs text-fg font-mono"})}),e.jsx(b,{label:"description",hint:"Shown in the list and in agent pickers.",children:e.jsx("input",{value:t.description,onChange:s=>r({description:s.target.value}),className:"w-full bg-bg border border-line rounded px-2 py-1 text-xs text-fg"})}),e.jsx(b,{label:"default model",hint:"This persona's default model for its Epics — sets the --model an Epic launches with (Terminal + Chat both honor it). 'inherit' falls back to each view's own default, not this Settings page. Cheap models for read-only personas; opus for judgement calls.",children:e.jsx(de,{options:ae,value:t.model,onChange:s=>r({model:s}),mono:!0})}),e.jsx(b,{label:"tools",hint:`${t.tools.length} of ${G.length} granted. Anything not ticked is refused at call time.`,children:e.jsx("div",{className:"flex flex-wrap gap-1.5",children:G.map(s=>{const j=t.tools.includes(s);return e.jsx("button",{onClick:()=>r({tools:j?t.tools.filter(p=>p!==s):[...t.tools,s]}),className:`px-2 py-0.5 rounded-full text-[11px] font-mono border ${j?"bg-sage/15 text-sage-dark border-sage/30":"bg-bg-hi text-fg-faint border-line"}`,children:s},s)})})}),e.jsx(b,{label:"color",children:e.jsx("div",{className:"flex gap-1.5",children:se.map(s=>e.jsx("button",{title:s||"none",onClick:()=>r({color:s}),className:"w-5 h-5 rounded",style:{background:s?K[s]:"transparent",border:t.color===s?"2px solid var(--accent, #b85c34)":"1px solid var(--line, #555)"}},s||"none"))})}),e.jsx(b,{label:"tags",hint:"Session mission tags this persona is associated with — shown as the default agent on that tag's own page. The first one (in Tag Library order) is the MISSION an Action button's session opens with.",children:e.jsx("div",{className:"flex flex-wrap gap-1.5",children:_.map(s=>{const j=t.tags.includes(s.tag),p=Z(s.tag);return e.jsxs("button",{onClick:()=>r({tags:j?t.tags.filter($=>$!==s.tag):[...t.tags,s.tag]}),className:`px-2 py-0.5 rounded-full text-[11px] font-mono border ${j?`${p.bg} ${p.text} ${p.border?"border-current/30":"border-transparent"}`:"bg-bg-hi text-fg-faint border-line"}`,children:["#",s.tag]},s.tag)})})}),e.jsx(ce,{obj:t,set:r}),e.jsx(b,{label:"definition",hint:"The system prompt this persona runs under.",children:e.jsx("textarea",{rows:9,value:t.body,onChange:s=>r({body:s.target.value}),className:"w-full bg-bg border border-line rounded px-2 py-1.5 text-xs text-fg font-mono leading-relaxed resize-y"})}),e.jsx(b,{label:"project overrides",hint:"Open projects that shadow this definition with a local copy.",children:g&&g.overridingProjects.length>0?e.jsx("div",{className:"flex flex-wrap gap-1.5",children:g.overridingProjects.map(s=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 bg-bg-elev border border-line rounded px-2 py-0.5 text-[11px] font-mono text-fg-dim",children:[s,e.jsx("button",{onClick:()=>D(s),title:"Drop the local copy",className:"text-fg-faint hover:text-fg",children:"×"})]},s))}):e.jsx("div",{className:"text-xs text-fg-faint italic",children:l?"save first to see project overrides.":"no open project overlays this agent — the global definition applies everywhere."})})]}),e.jsx("div",{className:"px-4 py-2.5 border-t border-line flex items-center gap-2 flex-wrap",children:c?e.jsxs(e.Fragment,{children:[e.jsxs("span",{className:"text-xs text-fg-dim",children:["Delete ",e.jsx("strong",{className:"font-mono",children:t.name})," and its file?"]}),e.jsx(y,{variant:"danger",onClick:N,disabled:m,children:"Delete"}),e.jsx(y,{onClick:()=>i(!1),children:"Keep"})]}):e.jsxs(e.Fragment,{children:[e.jsx(y,{onClick:u,disabled:m,children:"Duplicate"}),!l&&e.jsx(y,{variant:"danger",onClick:()=>i(!0),disabled:m,children:"Delete"}),e.jsx("div",{className:"flex-1"}),k&&e.jsx("span",{className:"text-[11px] text-fg-faint",children:"unsaved changes"}),e.jsx(y,{onClick:a,disabled:!k||m,children:"Revert"}),e.jsx(y,{variant:"primary",onClick:v,disabled:!k||m,children:m?"Saving…":l?"Create":"Save"})]})})]})}function ce({obj:t,set:r}){const{projects:g}=ee(),f=g.map(a=>({cwd:a.cwd,name:a.name})),l=new Set(f.map(a=>a.cwd)),m=t.projects.filter(a=>a!==T&&!l.has(a)),c=t.projects.includes(T),i=a=>r({projects:t.projects.includes(a)?t.projects.filter(v=>v!==a):[...t.projects,a]}),u=t.projects.length>0;return e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"action — appears in",hint:"Projects whose Sessions toolbar gets a one-click button for this agent. Pressing it starts a normal session: this persona is the ACTOR, its first tag is the MISSION, and the action text below is the opening goal. Leave empty for an agent that is only picked by hand in the New Session card.",children:e.jsxs("div",{className:"flex flex-wrap gap-1.5",children:[e.jsx("button",{onClick:()=>i(T),className:`px-2 py-0.5 rounded-full text-[11px] font-mono border ${c?"bg-accent/15 text-accent border-accent/40 font-semibold":"bg-bg-hi text-fg-faint border-line"}`,children:"every project"}),f.map(a=>{const v=t.projects.includes(a.cwd);return e.jsx("button",{title:a.cwd,onClick:()=>i(a.cwd),className:`px-2 py-0.5 rounded-full text-[11px] font-mono border ${v?"bg-sage/15 text-sage-dark border-sage/30":"bg-bg-hi text-fg-faint border-line"} ${c&&!v?"opacity-40":""}`,children:a.name},a.cwd)}),m.map(a=>e.jsxs("button",{title:`${a} — not a known project on this machine`,onClick:()=>i(a),className:"px-2 py-0.5 rounded-full text-[11px] font-mono border bg-bg-hi text-fg-faint border-dashed border-line",children:[a," ×"]},a))]})}),u&&e.jsxs(e.Fragment,{children:[e.jsx(b,{label:"action — button label",hint:"Caption on the Sessions toolbar button. Defaults to the agent name.",children:e.jsx("input",{value:t.actionLabel,onChange:a=>r({actionLabel:a.target.value}),placeholder:t.name,className:"w-full bg-bg border border-line rounded px-2 py-1 text-xs text-fg"})}),e.jsx(b,{label:"action — opening instruction",hint:"Sent as the session's first message, under the AIM framing. Falls back to this persona's description when empty; with neither, no button is shown.",children:e.jsx("textarea",{rows:3,value:t.action,onChange:a=>r({action:a.target.value}),placeholder:t.description||`e.g. /builder
|
|
2
|
-
|
|
3
|
-
Check git vs the published package and publish anything new.`,className:"w-full bg-bg border border-line rounded px-2 py-1.5 text-xs text-fg font-mono leading-relaxed resize-y"})})]})]})}function b({label:t,hint:r,children:g}){return e.jsxs("div",{children:[e.jsx("div",{className:"text-[10.5px] font-semibold uppercase tracking-wide text-fg-faint mb-1.5 font-mono",children:t}),g,r&&e.jsx("div",{className:"text-[11px] text-fg-faint mt-1 leading-snug",children:r})]})}function de({options:t,value:r,onChange:g,mono:f}){const l=r&&!t.includes(r),m=l?[...t,r]:t;return e.jsx("div",{className:"flex flex-wrap gap-1",children:m.map(c=>{const i=c===r,u=l&&c===r;return e.jsxs("button",{onClick:()=>g(c),title:u?`${c} — current on-disk value, not in the standard list`:void 0,className:`px-2.5 py-1 rounded text-xs border ${f?"font-mono":""} ${i?"bg-accent/15 text-accent border-accent/40 font-semibold":"bg-bg-hi text-fg-dim border-line"} ${u?"border-dashed":""}`,children:[c,u?" (current)":""]},c)})})}export{he as AgentLibrary};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{au as d,h as j,ai as $,a1 as g,ah as e,l as N,V as E,ak as S,a2 as b,aw as T,b as p,Y as D,i as v,E as R}from"./index-D5H_H5wC.js";import{P as V}from"./Panel-C2YTW-qP.js";import"./monaco-editor-BW5C4Iv1.js";const C=[{key:"diagram",label:"Diagram"},{key:"tables",label:"Tables"}];function G(){const[s,t]=d.useState("diagram"),[a,i]=d.useState(null),[l,n]=d.useState(()=>new Set),c=d.useMemo(()=>j.filter(r=>!l.has(r.group)),[l]),m=d.useMemo(()=>$(c),[c]),o=r=>{n(x=>{const h=new Set(x);return h.has(r)?h.delete(r):h.add(r),h}),i(null)},u=a?g(a):null,y=r=>c.some(x=>x.id===r);return e.jsx(V,{toolbar:e.jsxs(e.Fragment,{children:[e.jsx(E,{options:C,active:s,onChange:t}),e.jsx(M,{hiddenGroups:l,onToggle:o}),e.jsxs("span",{className:"ml-auto text-fg-faint",children:[j.length," entities"]})]}),children:s==="diagram"?e.jsxs("div",{className:"h-full flex",children:[e.jsx("div",{className:"flex-1 min-w-0 overflow-auto",children:e.jsx(O,{layout:m,selectedId:a,onSelect:r=>i(x=>x===r?null:r)})}),e.jsx("div",{className:"w-96 shrink-0 border-l border-line overflow-y-auto",children:u?e.jsx(F,{entity:u,onSelectRelated:r=>y(r)?i(r):void 0}):e.jsx(N,{title:"select an entity",hint:"click a box in the diagram to see its storage, fields, and relations"})})]}):e.jsx(P,{})})}const L=d.memo(G);function M({hiddenGroups:s,onToggle:t}){return e.jsx("div",{className:"flex items-center gap-1.5 flex-wrap",children:v.map(a=>{const i=s.has(a.id);return e.jsxs("button",{onClick:()=>t(a.id),title:`${a.blurb} (${a.realm})`,className:`flex items-center gap-1 px-1.5 py-0.5 rounded border text-[10.5px] ${i?"border-line text-fg-faint opacity-50":"border-line text-fg-dim hover:text-fg"}`,children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full ${a.tone.dot}`}),a.label,e.jsx("span",{className:"text-fg-faint",children:a.realm})]},a.id)})})}function O({layout:s,selectedId:t,onSelect:a}){const i=d.useMemo(()=>t?new Set(S(t)):null,[t]),l=n=>!!t&&(n.relation.from===t||n.relation.to===t);return s.boxes.length===0?e.jsx(N,{title:"no entities in view",hint:"toggle a group in the legend to show its entities"}):e.jsxs("div",{className:"relative p-4",style:{width:s.width+32,height:s.height+32},children:[e.jsxs("svg",{width:s.width,height:s.height,className:"absolute left-4 top-4 overflow-visible",children:[s.edges.map(n=>{const c=l(n);return e.jsx("path",{"data-testid":`erd-edge-${n.relation.from}-${n.relation.to}`,d:n.d,fill:"none",className:c?"stroke-accent":"stroke-line",strokeWidth:c?2:1,opacity:t&&!c?.25:1},`${n.relation.from}-${n.relation.to}-${n.relation.label}`)}),s.edges.map(n=>l(n)?e.jsx("text",{x:n.mx,y:n.my,textAnchor:"middle",className:"fill-fg-dim text-[10px]",children:n.relation.label},`label-${n.relation.from}-${n.relation.to}-${n.relation.label}`):null)]}),s.boxes.map(n=>e.jsx(_,{box:n,selected:n.id===t,dimmed:!!t&&n.id!==t&&!(i!=null&&i.has(n.id)),onClick:()=>a(n.id)},n.id))]})}function _({box:s,selected:t,dimmed:a,onClick:i}){const l=g(s.id),n=b(s.group),c=l.fields.slice(0,R),m=l.fields.length-c.length;return e.jsxs("button",{type:"button","data-testid":`erd-box-${s.id}`,onClick:i,className:`absolute text-left rounded border overflow-hidden bg-bg-hi ${t?"border-accent ring-1 ring-accent":"border-line"} ${a?"opacity-30":""}`,style:{left:s.x,top:s.y,width:s.w,height:s.h},children:[e.jsxs("div",{className:"px-2 py-1 border-b border-line flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${n.tone.dot}`}),e.jsx("span",{className:"text-[11px] font-semibold text-fg truncate",children:l.name})]}),l.aka&&e.jsx("div",{className:"px-2 pt-0.5 text-[9.5px] text-fg-faint truncate",children:l.aka}),e.jsxs("div",{className:"px-2 py-0.5",children:[c.map(o=>e.jsxs("div",{className:"text-[9.5px] font-mono text-fg-dim truncate flex items-center gap-1",children:[o.key&&e.jsx("span",{className:"text-fg-faint",children:o.key}),e.jsx("span",{className:"truncate",children:o.name})]},o.name)),m>0&&e.jsxs("div",{className:"text-[9.5px] text-fg-faint italic",children:["+",m," more"]})]})]})}function w({fields:s}){return e.jsxs("table",{className:"w-full text-[11px] font-mono",children:[e.jsx("thead",{className:"text-fg-faint uppercase tracking-wide text-[9.5px]",children:e.jsxs("tr",{className:"border-b border-line",children:[e.jsx("th",{className:"text-left font-normal px-2 py-1",children:"name"}),e.jsx("th",{className:"text-left font-normal px-2 py-1",children:"type"}),e.jsx("th",{className:"text-left font-normal px-2 py-1",children:"key"}),e.jsx("th",{className:"text-left font-normal px-2 py-1",children:"note"})]})}),e.jsx("tbody",{children:s.map(t=>e.jsxs("tr",{className:"border-b border-line/50",children:[e.jsxs("td",{className:"px-2 py-1 text-fg",children:[t.name,t.optional&&e.jsx("span",{className:"text-fg-faint",children:"?"})]}),e.jsx("td",{className:"px-2 py-1 text-fg-dim",children:t.type}),e.jsx("td",{className:"px-2 py-1",children:t.key&&e.jsxs(p,{tone:t.key==="pk"?"accent":"dim",children:[t.key,t.ref?` → ${t.ref}`:""]})}),e.jsx("td",{className:"px-2 py-1 text-fg-faint",children:t.note})]},t.name))})]})}function k({entity:s}){return e.jsxs("div",{className:"space-y-1 text-[11px]",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-fg-faint w-20 shrink-0",children:"path"}),e.jsx("span",{className:"font-mono text-fg-dim break-all",children:s.store.path})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-fg-faint w-20 shrink-0",children:"format"}),e.jsx("span",{className:"font-mono text-fg-dim",children:s.store.format})]}),s.store.writer&&e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-fg-faint w-20 shrink-0",children:"writer"}),e.jsxs(p,{tone:"accent",children:["single-writer: ",s.store.writer]})]}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-fg-faint w-20 shrink-0",children:"definedIn"}),e.jsx("span",{className:"font-mono text-fg-dim break-all",children:s.store.definedIn})]})]})}function F({entity:s,onSelectRelated:t}){const a=b(s.group),i=T(s.id);return e.jsxs("div",{className:"p-3 space-y-3",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-2 h-2 rounded-full ${a.tone.dot}`}),e.jsx("span",{className:"text-sm font-semibold text-fg",children:s.name})]}),s.aka&&e.jsx("div",{className:"text-[10.5px] text-fg-faint",children:s.aka}),e.jsx(p,{tone:"dim",className:"mt-1",children:a.label})]}),e.jsx("div",{className:"text-xs text-fg-dim leading-relaxed",children:s.summary}),e.jsxs("div",{children:[e.jsx(f,{children:"storage"}),e.jsx(k,{entity:s})]}),e.jsxs("div",{children:[e.jsx(f,{children:"fields"}),e.jsx(w,{fields:s.fields})]}),s.notes&&s.notes.length>0&&e.jsxs("div",{children:[e.jsx(f,{children:"notes"}),e.jsx("ul",{className:"list-disc pl-4 space-y-0.5 text-xs text-fg-dim",children:s.notes.map(l=>e.jsx("li",{children:l},l))})]}),e.jsxs("div",{children:[e.jsx(f,{children:"relations"}),i.length===0?e.jsx("div",{className:"text-xs text-fg-faint italic",children:"no relations"}):e.jsx("ul",{className:"space-y-1",children:i.map(l=>{const n=l.from===s.id?l.to:l.from,c=g(n);return e.jsxs("li",{className:"flex items-center gap-1.5 text-xs",children:[e.jsx("span",{className:"font-mono text-fg-faint w-10 shrink-0",children:D(l.cardinality)}),e.jsx("span",{className:"text-fg-dim",children:l.label}),l.via&&e.jsxs("span",{className:"font-mono text-[10px] text-fg-faint",children:["via ",l.via]}),e.jsx("button",{type:"button",onClick:()=>t(n),className:"ml-auto text-accent hover:underline font-mono",children:c.name})]},`${l.from}-${l.to}-${l.label}`)})})]})]})}function f({children:s}){return e.jsx("div",{className:"text-[10.5px] uppercase tracking-wide text-fg-faint mb-1 font-mono",children:s})}function P(){return e.jsx("div",{className:"p-4 space-y-6",children:v.map(s=>{const t=j.filter(a=>a.group===s.id);return t.length===0?null:e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-1.5 mb-2",children:[e.jsx("span",{className:`w-2 h-2 rounded-full ${s.tone.dot}`}),e.jsx("span",{className:"text-xs font-semibold text-fg",children:s.label}),e.jsx("span",{className:"text-[10.5px] text-fg-faint",children:s.realm})]}),e.jsx("div",{className:"grid grid-cols-1 xl:grid-cols-2 gap-3",children:t.map(a=>e.jsxs("div",{className:"border border-line rounded bg-bg-hi p-3 space-y-2",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm font-semibold text-fg",children:a.name}),a.aka&&e.jsx("span",{className:"text-[10.5px] text-fg-faint",children:a.aka})]}),e.jsx(p,{tone:"dim",className:"mt-1",children:s.label})]}),e.jsx("div",{className:"text-xs text-fg-dim leading-relaxed",children:a.summary}),e.jsx(k,{entity:a}),e.jsx(w,{fields:a.fields}),a.notes&&a.notes.length>0&&e.jsx("ul",{className:"list-disc pl-4 space-y-0.5 text-xs text-fg-dim",children:a.notes.map(i=>e.jsx("li",{children:i},i))})]},a.id))})]},s.id)})})}export{L as DataModel};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{au as i,aI as V,aR as P,aH as m,_ as Y,aJ as Q,ah as t,l as T,aB as W}from"./index-D5H_H5wC.js";import"./monaco-editor-BW5C4Iv1.js";function X(r){return r.hasMarketingPage?r.packagePrivate&&!r.packageHomepage?{kind:"private-needs-confirm"}:{kind:"ready"}:{kind:"no-marketing-page"}}const Z=["home","marketing","feature","architecture"],ee={home:"Home page",marketing:"Marketing page",feature:"Feature page",architecture:"Architecture page"};function $(r){return ee[r]}function D(r){const n=r.find(l=>l.subpath==="");return Z.map(l=>{const p=r.find(h=>h.source.kind==="project-page-lens"&&h.source.lens===l);return p?{lens:l,status:p.subpath===""?"root":"hosted",subpath:p.subpath,documentId:p.id}:!n&&l==="marketing"?{lens:l,status:"root",subpath:"",documentId:null}:{lens:l,status:"available",subpath:l,documentId:null}})}function te(r){return r.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)||"project"}const j="bilko-host-publisher",se="bilko-host-publisher",ne=[{value:"home",label:"Home lens"},{value:"marketing",label:"Marketing lens"},{value:"feature",label:"Feature lens"},{value:"architecture",label:"Architecture lens"}];function ae(r,n){for(const l of Object.values(r))if(l.cwd===n&&l.tag===j&&l.status==="active")return l;return null}function _(r){W(r),window.dispatchEvent(new CustomEvent("sm:navigate",{detail:"terminal"}))}function oe(){const r=V(),n=(r==null?void 0:r.cwd)??null,l=P(e=>e.sessions),p=P(e=>e.createPromptSession),h=P(e=>e.approveProposed),[o,C]=i.useState(null),[R,v]=i.useState(!1),[b,k]=i.useState(""),[E,H]=i.useState(!1),[B,M]=i.useState(!1),[u,A]=i.useState(null),[N,L]=i.useState(""),[f,I]=i.useState(""),[w,O]=i.useState("feature");i.useEffect(()=>{let e=!1;return window.api.agents.listPersonas().then(a=>{if(e)return;const s=a.find(g=>g.name===se);A(s?{name:s.name,description:s.description}:null)}).catch(()=>{e||A(null)}),()=>{e=!0}},[]);const c=i.useCallback(()=>{n&&(v(!1),window.api.bilkoHost.get(n).then(e=>{C(e),k(a=>{var s;return a||((s=e.bundleManifest)==null?void 0:s.slug)||e.defaultSlug}),v(!0)}).catch(e=>{v(!0),m.error(`Could not load bilko-host status: ${e instanceof Error?e.message:String(e)}`)}))},[n]);i.useEffect(()=>{C(null),k(""),H(!1),c()},[c]);const x=n?ae(l,n):null,z=i.useCallback(()=>{!n||!b||(M(!0),window.api.bilkoHost.prepareBundle(n,b).then(()=>c()).catch(e=>m.error(`Could not prepare bundle: ${e instanceof Error?e.message:String(e)}`)).finally(()=>M(!1)))},[n,b,c]),F=i.useCallback(()=>{if(!n)return;const e=te(N).replace(/^-+|-+$/g,"");if(!e||!f.trim()){m.error("A sub-path and a title are required.");return}const a={kind:"project-page-lens",lens:w};window.api.bilkoHost.addDocument(n,e,f.trim(),a).then(()=>{L(""),I(""),c()}).catch(s=>m.error(`Could not add document: ${s instanceof Error?s.message:String(s)}`))},[n,N,f,w,c]),G=i.useCallback((e,a)=>{n&&window.api.bilkoHost.addDocument(n,a,$(e),{kind:"project-page-lens",lens:e}).then(()=>c()).catch(s=>m.error(`Could not add ${e} page: ${s instanceof Error?s.message:String(s)}`))},[n,c]),J=i.useCallback(async()=>{if(!n||!o)return;const e=D(o.documents).filter(a=>a.status==="available");for(const a of e)try{await window.api.bilkoHost.addDocument(n,a.subpath,$(a.lens),{kind:"project-page-lens",lens:a.lens})}catch(s){m.error(`Could not add ${a.lens} page: ${s instanceof Error?s.message:String(s)}`)}c()},[n,o,c]),U=i.useCallback(e=>{n&&window.api.bilkoHost.removeDocument(n,e).then(()=>c()).catch(a=>m.error(`Could not remove document: ${a instanceof Error?a.message:String(a)}`))},[n,c]),q=i.useCallback(async()=>{if(!n||!b)return;if(x){_(x.id);return}const e=`Publish this project to bilko.run as a static-path listing, slug "${b}". Bundle is at session-manager-operations/bilko-host/dist/ (prepare it first via Prepare Bundle if it's missing or stale) — it may contain multiple documents (a root page plus sub-paths); publish the whole dist/ tree as one static-path app.`,{goalText:a,openingPrompt:s}=Y({title:"",goal:e,tag:j,agentName:u==null?void 0:u.name,agentDescription:(u==null?void 0:u.description)??void 0}),g=u?await p(n,a,j,"HostBilko",u.name):await p(n,a,j,"HostBilko");h(g.id,"HostBilko"),Q.getState().send({tabId:g.id,sessionId:g.claudeSessionId,cwd:n,prompt:s}),_(g.id)},[n,b,x,p,h,u]);if(!n)return t.jsx(T,{title:"Open a project to host it on Bilko.run"});if(!R||!o)return null;const y=X(o);if(y.kind==="no-marketing-page")return t.jsx(T,{title:"No Marketing page yet",hint:"Generate this project's Project Pages from Project Home first — the root document publishes the Marketing lens."});const d=o.publishState,K=(d==null?void 0:d.status)??(o.bundleManifest?"bundle-ready":"not-published"),S=y.kind==="ready"||E;return t.jsxs("div",{className:"max-w-2xl space-y-4",children:[t.jsxs("div",{className:"rounded-card border border-line bg-bg-hi p-5 space-y-4",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsxs("div",{children:[t.jsx("div",{className:"font-serif text-lg text-fg",children:o.projectName}),t.jsxs("div",{className:"text-xs text-fg-faint mt-0.5",children:["Status: ",t.jsx("span",{className:"font-mono",children:K}),o.bundleStale&&o.bundleManifest&&t.jsx("span",{className:"ml-2 text-accent",children:"bundle out of date — Prepare Bundle again"})]})]}),(d==null?void 0:d.status)==="published"&&d.url&&t.jsx("a",{href:d.url,target:"_blank",rel:"noreferrer",className:"text-xs text-accent hover:underline",children:d.url})]}),y.kind==="private-needs-confirm"&&!E&&t.jsxs("div",{className:"rounded-md border border-line bg-bg p-3 text-xs text-fg-dim",children:["This project's package.json is marked private with no public homepage. Confirm you want to publish it to bilko.run anyway.",t.jsx("button",{type:"button",onClick:()=>H(!0),className:"mt-2 block rounded-md bg-accent px-3 py-1.5 text-xs font-semibold text-bg-hi hover:bg-accent-dark",children:"Yes, this can be public"})]}),S&&t.jsxs(t.Fragment,{children:[t.jsxs("label",{className:"block text-xs text-fg-faint",children:["Slug (bilko.run/projects/<slug>/)",t.jsx("input",{value:b,onChange:e=>k(e.target.value.toLowerCase()),className:"mt-1 block w-full rounded-md border border-line bg-bg px-2.5 py-1.5 text-sm font-mono text-fg"})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("button",{type:"button",onClick:z,disabled:B,className:"rounded-md border border-line bg-bg px-3.5 py-1.5 text-xs font-semibold text-fg hover:bg-bg-hi disabled:opacity-50",children:B?"Preparing…":"Prepare Bundle"}),t.jsx("button",{type:"button",onClick:()=>{q().catch(e=>{m.error(e instanceof Error?e.message:String(e))})},disabled:!o.bundleManifest,title:o.bundleManifest?void 0:"Prepare a bundle first",className:"rounded-md bg-accent px-3.5 py-1.5 text-xs font-semibold text-bg-hi hover:bg-accent-dark disabled:opacity-50",children:x?"View publish in progress":"Publish"})]}),o.bundleManifest&&t.jsxs("div",{className:"text-[11px] text-fg-faint font-mono",children:["bundle: ",(o.bundleManifest.bundle.sizeBytesGz/1024).toFixed(1)," KB gz ·"," ",o.bundleManifest.bundle.fileCount," document",o.bundleManifest.bundle.fileCount===1?"":"s"," · built"," ",new Date(o.bundleManifest.builtAt).toLocaleString()," · ",o.bundleManifest.gitSha]}),(d==null?void 0:d.status)==="publish-failed"&&d.lastError&&t.jsxs("div",{className:"text-xs text-accent",children:["Last publish failed: ",d.lastError]})]})]}),S&&(()=>{const e=D(o.documents),a=e.filter(s=>s.status==="available").length;return t.jsxs("div",{className:"rounded-card border border-line bg-bg-hi p-5 space-y-3",children:[t.jsxs("div",{className:"flex items-center justify-between",children:[t.jsx("div",{className:"font-serif text-base text-fg",children:"Project Pages"}),a>1&&t.jsxs("button",{type:"button",onClick:J,className:"text-xs text-accent hover:underline",children:["Host all ",a," remaining"]})]}),t.jsxs("p",{className:"text-xs text-fg-faint",children:["This project generates 4 pages (Home / Marketing / Feature / Architecture). Marketing is the project's root (bilko.run/projects/",b||"<slug>","/); host any of the others as their own sub-page if you want them public too."]}),t.jsx("ul",{className:"space-y-1.5",children:e.map(s=>t.jsxs("li",{className:"flex items-center justify-between gap-2 rounded-md border border-line bg-bg px-3 py-2 text-xs",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"text-fg capitalize",children:s.lens}),t.jsx("div",{className:"text-fg-faint font-mono truncate",children:s.status==="root"?"(project root)":`/${s.subpath}/`})]}),s.status==="available"?t.jsxs("button",{type:"button",onClick:()=>G(s.lens,s.subpath),className:"shrink-0 rounded-md border border-line px-2 py-1 text-fg hover:bg-bg-hi",children:["+ Host as /",s.subpath,"/"]}):t.jsx("span",{className:"shrink-0 text-fg-faint",children:s.status==="root"?"root":"hosted"})]},s.lens))})]})})(),S&&t.jsxs("div",{className:"rounded-card border border-line bg-bg-hi p-5 space-y-3",children:[t.jsx("div",{className:"font-serif text-base text-fg",children:"Hosted documents"}),t.jsx("p",{className:"text-xs text-fg-faint",children:"One project, one Bilko listing — add as many explanatory pages as you want under it, each at its own sub-path. Removing one here takes it down on the next Publish."}),t.jsx("ul",{className:"space-y-1.5",children:o.documents.map(e=>t.jsxs("li",{className:"flex items-center justify-between gap-2 rounded-md border border-line bg-bg px-3 py-2 text-xs",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("div",{className:"text-fg truncate",children:e.title}),t.jsxs("div",{className:"text-fg-faint font-mono truncate",children:[e.subpath===""?"(root)":`/${e.subpath}/`," · ",e.url]})]}),e.subpath!==""&&t.jsx("button",{type:"button",onClick:()=>U(e.id),title:"Remove — takes effect on the next Publish",className:"shrink-0 rounded-md border border-line px-2 py-1 text-fg-faint hover:text-accent hover:border-accent/40",children:"Remove"})]},e.id))}),t.jsxs("div",{className:"rounded-md border border-line bg-bg p-3 space-y-2",children:[t.jsx("div",{className:"text-[11px] font-semibold uppercase tracking-wide text-fg-faint",children:"Add a document"}),t.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[t.jsx("input",{value:N,onChange:e=>L(e.target.value),placeholder:"sub-path, e.g. special-doc/01",className:"rounded-md border border-line bg-bg-hi px-2.5 py-1.5 text-xs font-mono text-fg"}),t.jsx("input",{value:f,onChange:e=>I(e.target.value),placeholder:"Title",className:"rounded-md border border-line bg-bg-hi px-2.5 py-1.5 text-xs text-fg"})]}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("select",{value:w,onChange:e=>O(e.target.value),className:"rounded-md border border-line bg-bg-hi px-2.5 py-1.5 text-xs text-fg",children:ne.map(e=>t.jsx("option",{value:e.value,children:e.label},e.value))}),t.jsx("button",{type:"button",onClick:F,className:"rounded-md border border-line bg-bg-hi px-3.5 py-1.5 text-xs font-semibold text-fg hover:bg-bg",children:"Add document"})]})]})]})]})}const le=i.memo(oe);export{le as HostBilko};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ah as e}from"./index-D5H_H5wC.js";function o({sidebar:r,detail:s,sidebarWidth:i="18rem"}){return e.jsxs("div",{className:"h-full flex",children:[e.jsx("div",{className:"shrink-0 border-r border-line overflow-y-auto",style:{width:i},children:r}),e.jsx("div",{className:"flex-1 min-w-0 overflow-auto",children:s})]})}export{o as L};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{ah as e,au as c,aN as oe,aI as ie,aP as ce,aK as N,l as O,b as Q,aH as q}from"./index-D5H_H5wC.js";import{P as $}from"./Panel-C2YTW-qP.js";import{L as de}from"./ListDetail-CtVjrHKB.js";import{S as xe}from"./SaveBar-87ZJfscX.js";import{S as H}from"./ScopeSwitcher-CKzpqjJ_.js";import{P as Y}from"./ProvenanceBadge-kJ__BOQv.js";import{M as ue,V as D}from"./Library-DeKdY-tD.js";import"./monaco-editor-BW5C4Iv1.js";const pe={live:"bg-emerald-400",idle:"bg-amber-400",offline:"bg-fg-faint",attention:"bg-accent",paused:"bg-zinc-500"},fe={sm:"w-1.5 h-1.5",md:"w-2 h-2"},me={on:"live",off:"offline",warn:"attention",live:"live",idle:"idle"};function W({state:n,kind:t,pulse:a=!1,size:d="sm",className:p="",title:b,"aria-label":o}){const j=n??(t?me[t]:"idle"),r=pe[j],g=fe[d],x=a?"animate-pulse":"",u=o??b??j;return e.jsx("span",{role:"img","aria-label":u,className:`inline-block rounded-full ${g} ${r} ${x} ${p}`.trim(),title:b})}const he={failed:"Failed","needs-auth":"Needs auth",pending:"Pending approval"};function G(n,t){const a=t!=null&&t.ok?t.servers.find(d=>d.name===n):void 0;return!a||a.status==="unknown"?{state:"unprobed",label:"Not checked",probeStatus:(a==null?void 0:a.status)??null,badgeTone:"dim",dotState:"offline"}:a.status==="connected"?{state:"ready",label:"Ready",probeStatus:a.status,badgeTone:"good",dotState:"live"}:{state:"not-ready",label:he[a.status],probeStatus:a.status,badgeTone:"warn",dotState:"attention"}}const U=(n,t)=>({type:"mcp",name:n,command:t.command,args:t.args,url:t.url}),ge=["stdio","http","streamable-http","sse","ws"],be=new Set(["workspace"]),je=new Set(["ide","tasks"]);function ve(n,t,a){return n==="user"?`${t}/.claude.json`:a?`${a}/.mcp.json`:null}function ye(n){if(n.trim()==="")return{full:{},servers:{},err:null};try{const t=JSON.parse(n),a=t.mcpServers??{};return{full:t,servers:a,err:null}}catch(t){return{full:{},servers:{},err:t.message}}}function Ne(n,t){return JSON.stringify({...n,mcpServers:t},null,2)+`
|
|
2
|
-
`}function we(n){let t=Object.keys(n).length+1,a=`server-${t}`;for(;n[a];)t+=1,a=`server-${t}`;return a}function Se(){const n=oe(),t=ie(),a=(t==null?void 0:t.cwd)??null,d=ce(s=>s.navFace),p=c.useRef(!1),b=c.useRef(d),[o,j]=c.useState(()=>d==="project"&&a?"project":"user"),[r,g]=c.useState(null),[x,u]=c.useState("installed"),[w,_]=c.useState("");c.useEffect(()=>{if(b.current!==d){if(b.current=d,p.current){p.current=!1;return}j(d==="project"&&a?"project":"user")}},[d,a]);const f=c.useMemo(()=>n?ve(o,n,a):null,[n,o,a]),k=N(s=>s.files),l=N(s=>s.loadJson),v=N(s=>s.setDraft),m=N(s=>s.saveJson),I=N(s=>s.revert),T=N(s=>s.watchFile),X=N(s=>s.unwatchFile);c.useEffect(()=>{if(f)return k[f]||l(f),T(f),()=>X(f)},[f]);const[ee,R]=c.useState(null),[J,K]=c.useState(null),[B,z]=c.useState(!1),F=c.useRef(0),A=c.useRef(!0);c.useEffect(()=>()=>{A.current=!1},[]);const V=async()=>{const s=++F.current;z(!0);try{const i=await window.api.mcp.status();if(!A.current||s!==F.current)return;K(i),i.ok||q.error(i.error??"MCP status probe failed")}catch(i){if(!A.current||s!==F.current)return;K(null),q.error(i.message||"MCP status probe failed")}finally{A.current&&s===F.current&&z(!1)}};if(c.useEffect(()=>{V()},[]),!n)return e.jsx(O,{title:"loading…"});if(x==="library")return e.jsx($,{toolbar:e.jsx(D,{active:x,onChange:u}),children:e.jsx(ue,{})});if(o==="project"&&!a)return e.jsx($,{toolbar:e.jsxs(e.Fragment,{children:[e.jsx(D,{active:x,onChange:u}),e.jsx("span",{className:"mx-2 text-fg-faint",children:"·"}),e.jsx(H,{scopes:["user","project"],active:o,onChange:s=>{p.current=!0,j(s)}})]}),children:e.jsx(O,{title:"no active project"})});if(!f)return e.jsx(O,{title:"loading…"});const y=k[f],{full:te,servers:h,err:se}=y?ye(y.draftRaw):{full:{},servers:{},err:null},L=Object.keys(h).sort(),M=r?h[r]:null,P=s=>{R(null),v(f,Ne(te,s))},ae=()=>{const s=we(h);P({...h,[s]:{type:"stdio",command:"",args:[]}}),g(s)},le=s=>{const i={...h};delete i[s],P(i),r===s&&g(null)},ne=(s,i)=>{if(!i||i===s||h[i])return;const S={};for(const C of Object.keys(h))S[C===s?i:C]=h[C];P(S),g(i)},re=(s,i)=>{P({...h,[s]:i})};return e.jsx($,{toolbar:e.jsxs(e.Fragment,{children:[e.jsx(D,{active:x,onChange:u}),e.jsx("span",{className:"mx-2 text-fg-faint",children:"·"}),e.jsx(H,{scopes:["user","project"],active:o,onChange:s=>{p.current=!0,j(s)}}),e.jsxs("span",{className:"ml-3 px-1.5 py-0.5 text-[10px] rounded border border-line text-fg-faint",children:[L.length," server",L.length===1?"":"s"]}),e.jsx("span",{className:"ml-2 text-fg-faint truncate",children:f}),e.jsx("div",{className:"flex-1"}),r&&M&&e.jsx(Y,{scope:o,input:U(r,M),className:"mr-2"}),e.jsx("button",{onClick:V,disabled:B,className:"px-2 py-0.5 text-xs border border-line rounded text-fg-dim hover:text-fg hover:bg-bg-hi disabled:opacity-50 mr-2",children:B?"checking…":"⟳ test connections"}),e.jsx("button",{onClick:ae,className:"px-2 py-0.5 text-xs border border-line rounded text-fg-dim hover:text-fg hover:bg-bg-hi",children:"+ new server"})]}),footer:y?e.jsx(xe,{dirty:y.dirty,busy:y.busy,parseError:ee||se||y.parseError,lastSavedAt:y.lastSavedAt,onSave:async()=>{R(null);const s=await m(f);s.ok||R(s.error??"save failed")},onRevert:()=>{R(null),I(f)}}):null,children:e.jsx(de,{sidebar:e.jsxs("div",{className:"py-2",children:[e.jsx("div",{className:"px-2 pb-1",children:e.jsx("input",{value:w,onChange:s=>_(s.target.value),placeholder:"filter…",className:"w-full bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg"})}),L.length===0?e.jsx("div",{className:"px-3 py-1 text-xs text-fg-faint italic",children:"no servers"}):L.filter(s=>!w||s.toLowerCase().includes(w.toLowerCase())).map(s=>{var C;const i=G(s,J),S=(C=h[s].description)==null?void 0:C.trim();return e.jsxs("button",{onClick:()=>g(s),className:`w-full text-left px-3 py-1 text-xs flex flex-col gap-0.5 ${r===s?"bg-bg-hi text-fg":"text-fg-dim hover:text-fg hover:bg-bg-hi"}`,children:[e.jsxs("span",{className:"flex items-center gap-2 justify-between w-full",children:[e.jsxs("span",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(W,{state:i.dotState,title:i.label}),e.jsx("span",{className:"truncate",children:s})]}),e.jsxs("span",{className:"ml-2 flex items-center gap-2 shrink-0",children:[e.jsx(Q,{tone:i.badgeTone,children:i.label}),e.jsx(Y,{interactive:!1,scope:o,input:U(s,h[s])}),e.jsx("span",{className:"text-fg-faint",children:h[s].type??"stdio"})]})]}),S?e.jsx("span",{className:"pl-5 text-fg-faint truncate",title:S,children:S}):null]},s)})]}),detail:r&&M?e.jsx(Ce,{name:r,server:M,connection:G(r,J),onTestConnection:V,testing:B,onRename:s=>ne(r,s),onChange:s=>re(r,s),onRemove:()=>le(r)}):e.jsx(O,{title:"select a server or click + new"})})})}const Pe=c.memo(Se);function Ce({name:n,server:t,connection:a,onTestConnection:d,testing:p,onRename:b,onChange:o,onRemove:j}){var k;const r=t.type??"stdio",g=be.has(n),x=je.has(n),u=(k=t.permissions)==null?void 0:k.tools,w=u===void 0?"inherit":u==="allow"?"allow":u==="deny"?"deny":"list",_=Array.isArray(u)?u:[],f=(t.disabledTools??[]).join(", ");return e.jsxs("div",{className:"p-4 space-y-4 max-w-2xl",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(W,{state:a.dotState,size:"md",title:a.label}),e.jsx(Q,{tone:a.badgeTone,children:a.label}),e.jsx("button",{onClick:d,disabled:p,className:"ml-auto px-2 py-0.5 text-xs border border-line rounded text-fg-dim hover:text-fg hover:bg-bg-hi disabled:opacity-50",children:p?"checking…":"test connection"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs text-fg-faint w-20",children:"name"}),e.jsx("input",{defaultValue:n,onBlur:l=>b(l.target.value.trim()),className:"flex-1 bg-bg-elev border border-line rounded px-2 py-1 text-xs text-fg font-mono"}),e.jsx("button",{onClick:j,className:"text-xs text-fg-faint hover:text-red-400 px-2 py-1 border border-line rounded",children:"delete"})]}),e.jsx(E,{label:"description",value:t.description??"",onChange:l=>o({...t,description:l||void 0}),placeholder:"what this server does…"}),g?e.jsxs("div",{className:"text-xs px-2 py-1 border border-red-500/50 rounded text-red-300 bg-red-500/5",children:["⚠ ",e.jsx("span",{className:"font-mono",children:n})," is a reserved name — Claude Code will refuse to load this server (v2.1.128+)."]}):x?e.jsxs("div",{className:"text-xs px-2 py-1 border border-yellow-600/50 rounded text-yellow-200 bg-yellow-500/5",children:["⚠ ",e.jsx("span",{className:"font-mono",children:n})," collides with a commonly-bundled MCP name; expect surprises in other tools."]}):null,e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs text-fg-faint w-20",children:"type"}),e.jsx("select",{value:r,onChange:l=>o({...t,type:l.target.value}),className:"bg-bg-elev border border-line rounded px-2 py-1 text-xs text-fg",children:ge.map(l=>e.jsx("option",{value:l,children:l},l))}),r==="sse"?e.jsx("span",{className:"text-xs text-yellow-400/80",children:"sse is deprecated — prefer streamable-http"}):null]}),r==="stdio"?e.jsxs(e.Fragment,{children:[e.jsx(E,{label:"command",value:t.command??"",onChange:l=>o({...t,command:l}),placeholder:"npx / node / python …"}),e.jsx(E,{label:"args",value:(t.args??[]).join(" "),onChange:l=>o({...t,args:l.split(/\s+/).filter(Boolean)}),placeholder:"space-separated args"}),e.jsx(Z,{label:"env",value:t.env??{},onChange:l=>o({...t,env:l})})]}):e.jsxs(e.Fragment,{children:[e.jsx(E,{label:"url",value:t.url??"",onChange:l=>o({...t,url:l}),placeholder:"https://…"}),e.jsx(Z,{label:"headers",value:t.headers??{},onChange:l=>o({...t,headers:l})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs text-fg-faint w-20",children:"alwaysLoad"}),e.jsxs("label",{className:"flex items-center gap-2 text-xs text-fg",children:[e.jsx("input",{type:"checkbox",checked:t.alwaysLoad===!0,onChange:l=>o({...t,alwaysLoad:l.target.checked||void 0})}),e.jsx("span",{className:"text-fg-dim",children:"bypass tool-search deferral (v2.1.121+)"})]})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs text-fg-faint w-20",children:"enabled"}),e.jsxs("label",{className:"flex items-center gap-2 text-xs text-fg",children:[e.jsx("input",{type:"checkbox",checked:t.enabled!==!1,onChange:l=>o({...t,enabled:l.target.checked?void 0:!1})}),e.jsx("span",{className:"text-fg-dim",children:"load this server in new sessions"})]})]}),e.jsx(E,{label:"disabledTools",value:f,onChange:l=>{const v=l.split(",").map(m=>m.trim()).filter(Boolean);o({...t,disabledTools:v.length?v:void 0})},placeholder:"comma-separated tool names to hide"}),e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("label",{className:"text-xs text-fg-faint w-20 pt-1",children:"permissions"}),e.jsxs("div",{className:"flex-1 space-y-1",children:[e.jsxs("select",{value:w,onChange:l=>{const v=l.target.value,m={...t};if(v==="inherit"){if(m.permissions){const{tools:I,...T}=m.permissions;m.permissions=Object.keys(T).length?T:void 0}}else v==="list"?m.permissions={...m.permissions??{},tools:[]}:m.permissions={...m.permissions??{},tools:v};o(m)},className:"bg-bg-elev border border-line rounded px-2 py-1 text-xs text-fg",children:[e.jsx("option",{value:"inherit",children:"inherit (default)"}),e.jsx("option",{value:"allow",children:"allow all tools"}),e.jsx("option",{value:"deny",children:"deny all tools"}),e.jsx("option",{value:"list",children:"allowlist…"})]}),w==="list"?e.jsx("input",{value:_.join(", "),onChange:l=>{const v=l.target.value.split(",").map(m=>m.trim()).filter(Boolean);o({...t,permissions:{...t.permissions??{},tools:v}})},placeholder:"comma-separated tool names",className:"w-full bg-bg-elev border border-line rounded px-2 py-1 text-xs text-fg font-mono"}):null]})]})]})}function E({label:n,value:t,onChange:a,placeholder:d}){return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:"text-xs text-fg-faint w-20",children:n}),e.jsx("input",{value:t,onChange:p=>a(p.target.value),placeholder:d,className:"flex-1 bg-bg-elev border border-line rounded px-2 py-1 text-xs text-fg font-mono"})]})}function Z({label:n,value:t,onChange:a}){const[d,p]=c.useState(""),[b,o]=c.useState(""),j=Object.entries(t);return e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("label",{className:"text-xs text-fg-faint w-20 pt-1",children:n}),e.jsxs("div",{className:"flex-1 space-y-1",children:[j.map(([r,g])=>e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{value:r,onChange:x=>{const u={...t};delete u[r],u[x.target.value]=g,a(u)},className:"w-32 bg-bg-elev border border-line rounded px-2 py-0.5 text-xs text-fg font-mono"}),e.jsx("input",{value:g,onChange:x=>a({...t,[r]:x.target.value}),className:"flex-1 bg-bg-elev border border-line rounded px-2 py-0.5 text-xs text-fg font-mono"}),e.jsx("button",{onClick:()=>{const x={...t};delete x[r],a(x)},className:"text-fg-faint hover:text-red-400 text-xs px-1",children:"×"})]},r)),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{value:d,onChange:r=>p(r.target.value),placeholder:"key",className:"w-32 bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg-dim font-mono"}),e.jsx("input",{value:b,onChange:r=>o(r.target.value),placeholder:"value",className:"flex-1 bg-bg border border-line rounded px-2 py-0.5 text-xs text-fg-dim font-mono"}),e.jsx("button",{onClick:()=>{d.trim()&&(a({...t,[d.trim()]:b}),p(""),o(""))},className:"px-2 text-xs border border-line rounded text-fg-dim hover:text-fg hover:bg-bg-hi",children:"+"})]})]})]})}export{Pe as McpServers,we as nextServerName};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ah as e}from"./index-D5H_H5wC.js";function n({toolbar:s,footer:l,children:r}){return e.jsxs("div",{className:"h-full flex flex-col",children:[s&&e.jsx("div",{className:"shrink-0 border-b border-line bg-bg-elev px-3 py-1.5 flex items-center gap-2 text-xs",children:s}),e.jsx("div",{className:"flex-1 min-h-0 overflow-auto",children:r}),l&&e.jsx("div",{className:"shrink-0 border-t border-line bg-bg-elev",children:l})]})}export{n as P};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./SkillReferenceGraph-D_-wg4r9.js","./index-D5H_H5wC.js","./monaco-editor-BW5C4Iv1.js","./monaco-editor-BTnBOi8r.css","./index-D3P_jldk.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{ah as e,au as p,l as y,aN as X,aH as R,b as Y}from"./index-D5H_H5wC.js";import{P as V}from"./Panel-C2YTW-qP.js";import{P as z}from"./ProvenanceBadge-kJ__BOQv.js";import{e as Z}from"./Library-DeKdY-tD.js";import{p as G}from"./skillFrontmatter-Dif5JIg7.js";import{_ as ee}from"./monaco-editor-BW5C4Iv1.js";import{L as te}from"./ListDetail-CtVjrHKB.js";import{M as ne}from"./MarkdownEditor-CbzC-Oqf.js";function se({columns:t,rows:n,getKey:o,onRowClick:a,activeKey:i,empty:m}){return n.length===0?e.jsx("div",{className:"p-6 text-fg-faint text-xs text-center",children:m??"no entries"}):e.jsxs("table",{className:"w-full text-xs",children:[e.jsx("thead",{className:"sticky top-0 bg-bg-elev text-fg-faint uppercase tracking-wider",children:e.jsx("tr",{className:"border-b border-line",children:t.map(l=>e.jsx("th",{className:`text-left font-normal px-3 py-1.5 ${l.className??""}`,style:l.width?{width:l.width}:void 0,children:l.header},l.key))})}),e.jsx("tbody",{children:n.map(l=>{const r=o(l),d=i===r;return e.jsx("tr",{"data-row-key":r,onClick:()=>a==null?void 0:a(l),className:`border-b border-line/50 transition-colors ${a?"cursor-pointer":""} ${d?"bg-bg-hi text-fg":"text-fg-dim hover:bg-bg-hi/50"}`,children:t.map(f=>e.jsx("td",{className:`px-3 py-1 ${f.className??""}`,children:f.render(l)},f.key))},r)})})]})}async function ie(t,n,o){var f,b;const a=`${n}/skills`;try{const c=await window.api.config.listDir(a,{dirsOnly:!0});if(c.ok&&c.entries.length>0)return a}catch{}let i=null;try{const c=await window.api.config.readJson(`${o}/.claude/plugins/installed_plugins.json`);c.exists&&!c.parseError&&c.data&&typeof c.data=="object"&&(i=c.data)}catch{return null}if(!(i!=null&&i.plugins))return null;const m=Object.keys(i.plugins).find(c=>c===t||c.startsWith(`${t}@`));if(!m)return null;const l=(b=(f=i.plugins[m])==null?void 0:f[0])==null?void 0:b.installPath;if(!l)return null;const r=`${l}/skills`;return await window.api.config.exists(r)?r:null}async function ae(t){const n=await window.api.config.listDir(t,{dirsOnly:!0}),o=[];for(const a of n.entries){const i=`${a.path}/SKILL.md`,m=await window.api.config.readText(i);if(!m.exists)continue;const l=G(m.text);o.push({id:a.name,name:l.name,description:l.description,dir:a.path,path:i,body:l.body})}return o}function le(t){const n=[],o=new Set;for(const a of t)for(const i of t){if(a.id===i.id)continue;const m=i.id.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),l=[`/${m}\\b`,`\`${m}\``];if(i.id.length>=4&&l.push(`\\b${m}\\b`),!l.some(f=>new RegExp(f,"i").test(a.body)))continue;const d=`${a.id}->${i.id}`;o.has(d)||(o.add(d),n.push({from:a.id,to:i.id}))}return n}const re=p.lazy(()=>ee(()=>import("./SkillReferenceGraph-D_-wg4r9.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url).then(t=>({default:t.SkillReferenceGraph})));function oe({pluginName:t,skills:n,onBack:o,initialSelectedId:a}){var b;const[i,m]=p.useState(a??((b=n[0])==null?void 0:b.id)??null),l=i?n.find(c=>c.id===i)??null:null,r=p.useMemo(()=>le(n),[n]),[d,f]=p.useState("list");return e.jsxs("div",{className:"flex flex-col h-full min-h-0 overflow-hidden",children:[e.jsxs("div",{className:"shrink-0 h-11 flex items-baseline gap-3.5 px-3 border-b border-line bg-bg",children:[e.jsxs("button",{type:"button",onClick:o,className:"font-mono text-accent hover:underline shrink-0 text-xs",children:["← ",t]}),e.jsx("span",{className:"font-serif text-[22px] text-fg shrink-0 truncate max-w-[16rem]",children:(l==null?void 0:l.name)??(l==null?void 0:l.id)??"skill"}),e.jsx("span",{className:"flex-1"}),e.jsx("div",{className:"flex items-center gap-1.5 shrink-0",children:e.jsxs("div",{className:"flex rounded border border-line overflow-hidden",children:[e.jsx("button",{onClick:()=>f("list"),className:`px-2 py-0.5 text-xs ${d==="list"?"bg-bg-hi text-fg":"text-fg-dim hover:text-fg hover:bg-bg-hi"}`,children:"list"}),e.jsx("button",{onClick:()=>f("graph"),className:`px-2 py-0.5 text-xs ${d==="graph"?"bg-bg-hi text-fg":"text-fg-dim hover:text-fg hover:bg-bg-hi"}`,children:"graph"})]})})]}),e.jsxs("div",{className:"shrink-0 h-[26px] flex items-center gap-[18px] px-3 bg-bg-elev border-b border-line text-[9px] font-mono uppercase tracking-wide overflow-hidden",children:[l!=null&&l.description?e.jsx("span",{className:"text-fg-dim truncate normal-case",children:l.description}):null,e.jsxs("span",{className:"ml-auto text-fg-faint truncate normal-case",children:[n.length," ",n.length===1?"skill":"skills"," · ",r.length," ",r.length===1?"reference":"references"]})]}),e.jsx("div",{className:"flex-1 min-h-0 overflow-hidden",children:n.length===0?e.jsx(y,{title:"no skills in this plugin"}):d==="graph"?e.jsx(p.Suspense,{fallback:e.jsx("div",{className:"p-6 text-xs text-fg-faint",children:"Loading graph…"}),children:e.jsx(re,{skills:n,edges:r,selectedId:i,onSelect:m})}):e.jsx(te,{sidebar:e.jsx("div",{className:"py-1",children:n.map(c=>e.jsxs("button",{onClick:()=>m(c.id),className:`w-full px-3 py-1 text-xs text-left ${i===c.id?"bg-bg-hi text-fg":"text-fg-dim hover:text-fg hover:bg-bg-hi"}`,children:[e.jsx("div",{className:"truncate",children:c.name??c.id}),c.description?e.jsx("div",{className:"truncate text-fg-faint",children:c.description}):null]},c.id))}),detail:l?e.jsx("div",{className:"h-full min-h-0",children:e.jsx(ne,{path:l.path,value:l.body,onChange:()=>{},readOnly:!0})}):e.jsx(y,{title:"select a skill"})})})]})}const q=t=>{var n,o;return{type:"plugin",name:t.name,repository:(n=t.manifest)==null?void 0:n.repository,homepage:(o=t.manifest)==null?void 0:o.homepage}};function ce(){const t=X(),[n,o]=p.useState([]),[a,i]=p.useState(!0),[m,l]=p.useState(null),[r,d]=p.useState("installed"),[f,b]=p.useState(null),[c,L]=p.useState(new Set);p.useEffect(()=>{var x,k;let s=!1;return(k=(x=window.api.app).seedStatus)==null||k.call(x).then(j=>{s||b(j)}).catch(()=>{}),()=>{s=!0}},[]),p.useEffect(()=>{if(!t)return;let s=!1;return(async()=>{var k;i(!0);const x=[];try{const j=await window.api.config.readJson(`${t}/.claude/plugins/installed_plugins.json`);if(j.exists&&!j.parseError&&j.data&&typeof j.data=="object"){const w=j.data;for(const[C,A]of Object.entries(w.plugins??{})){if(!Array.isArray(A))continue;const _=C.split("@")[0],u=C.split("@")[1];for(const g of A){if(!(g!=null&&g.installPath))continue;const B={name:_,path:g.installPath,isDirectory:!0,isFile:!1,mtimeMs:0,size:0},v=await fe(B);(k=v.manifest)!=null&&k.version||(v.manifest={...v.manifest??{},version:g.version}),v.marketplace=u,x.push(v)}}}}catch{}s||(x.sort((j,w)=>j.name.localeCompare(w.name)),s||(o(x),i(!1)))})(),()=>{s=!0}},[t]);const S=[{key:"name",header:"name",render:s=>{var x;return e.jsxs("div",{style:{maxWidth:"16rem"},children:[e.jsx("div",{className:"truncate",children:s.name}),(x=s.manifest)!=null&&x.description?e.jsx("div",{className:"truncate text-fg-faint",title:s.manifest.description,children:s.manifest.description}):null]})},width:"16rem"},{key:"origin",header:"origin",render:s=>e.jsx(z,{interactive:!1,input:q(s)}),width:"7rem"},{key:"version",header:"version",render:s=>{var x;return((x=s.manifest)==null?void 0:x.version)??e.jsx("span",{className:"text-fg-faint",children:"—"})},width:"6rem"},{key:"manifest",header:"manifest",render:s=>s.hasManifest?"plugin.json":e.jsx("span",{className:"text-fg-faint",children:"—"}),width:"8rem"},{key:"contents",header:"contents",render:s=>e.jsx("span",{className:"font-mono text-fg-faint text-xs",children:[s.agents>0?`${s.agents} agents`:null,s.skills>0?`${s.skills} skills`:null,s.hooks>0?`${s.hooks} hooks`:null,s.monitors>0?`${s.monitors} monitors`:null,s.binCount>0?`${s.binCount} bin`:null,s.hasLsp?"lsp":null,s.hasMcp?"mcp":null].filter(Boolean).join(" · ")||"—"})},{key:"path",header:"path",render:s=>e.jsx("span",{className:"font-mono text-fg-faint truncate",children:s.path})}],$=p.useMemo(()=>f?Object.keys(f).filter(s=>f[s].status==="exhausted"&&!c.has(s)):[],[f,c]),E=$.length>0?e.jsx(de,{seeders:$,seedStatus:f,onDismiss:s=>L(x=>new Set(x).add(s)),onOpenLibrary:()=>d("library")}):null;if(r==="library")return e.jsxs(V,{toolbar:e.jsx(W,{active:r,onChange:d}),children:[E,e.jsx(Z,{})]});const h=m?n.find(s=>s.path===m)??null:null;return e.jsxs(V,{toolbar:e.jsxs(e.Fragment,{children:[e.jsx(W,{active:r,onChange:d}),e.jsx("span",{className:"mx-2 text-fg-faint",children:"·"}),e.jsxs("span",{className:"text-fg-faint",children:[n.length," plugins"]}),e.jsx("div",{className:"flex-1"}),e.jsx("span",{className:"text-fg-faint font-mono truncate",children:"~/.claude/plugins/installed_plugins.json"})]}),children:[E,a?e.jsx(y,{title:"scanning plugins…"}):h?e.jsx(me,{row:h,home:t,onBack:()=>l(null)},h.path):e.jsx("div",{className:"flex flex-col h-full",children:e.jsx("div",{className:"flex-1 min-h-0 overflow-auto",children:e.jsx(se,{columns:S,rows:n,getKey:s=>s.path,activeKey:m,onRowClick:s=>l(s.path),empty:e.jsxs(e.Fragment,{children:["no plugins installed",e.jsxs("div",{className:"mt-2 text-fg-faint",children:["drop a plugin into ",e.jsx("code",{children:"~/.claude/plugins/"})]})]})})})})]})}const ke=p.memo(ce),K={"dev-plugin":"session-manager-dev plugin","scheduler-mcp":"Scheduler MCP server","agent-personas":"Agent personas (Architect, Dev Lead)"};function de({seeders:t,seedStatus:n,onDismiss:o,onOpenLibrary:a}){return e.jsx("div",{className:"shrink-0 flex flex-col gap-1.5 px-3 py-2 border-b border-line bg-yellow-950/20",children:t.map(i=>e.jsxs("div",{className:"flex items-start gap-2 text-xs text-yellow-300",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"font-medium",children:[K[i]," setup failed after retrying — manual fix needed"]}),i==="dev-plugin"?e.jsxs("div",{className:"text-yellow-400/80 mt-0.5",children:["Click ",e.jsx("button",{onClick:a,className:"underline hover:no-underline",children:"here"}),' to open the Library tab, then click Install next to "session-manager-dev".']}):e.jsx("div",{className:"text-yellow-400/80 mt-0.5 font-mono",children:n[i].fix})]}),e.jsx("button",{onClick:()=>o(i),className:"shrink-0 text-yellow-400/70 hover:text-yellow-300","aria-label":`Dismiss ${K[i]} warning`,children:"✕"})]},i))})}function W({active:t,onChange:n}){const o=[["installed","Installed"],["library","Library"]];return e.jsx("div",{className:"flex rounded border border-line overflow-hidden",role:"tablist","aria-label":"Plugins view",children:o.map(([a,i])=>e.jsx("button",{onClick:()=>n(a),role:"tab","aria-selected":t===a,className:`px-2 py-0.5 text-xs ${t===a?"bg-bg-hi text-fg":"text-fg-dim hover:text-fg hover:bg-bg-hi"}`,children:i},a))})}function me({row:t,home:n,onBack:o}){var j,w,C,A,_;const[a,i]=p.useState([]),[m,l]=p.useState([]),[r,d]=p.useState([]),[f,b]=p.useState([]),[c,L]=p.useState("skills"),[S,$]=p.useState(null),[E,h]=p.useState(!0);p.useEffect(()=>{if(!n)return;let u=!1;return(async()=>{h(!0);try{const[g,B,v,Q]=await Promise.all([ie(t.name,t.path,n),O(`${t.path}/agents`,{filesOnly:!0}),t.hasMcp?window.api.config.readJson(`${t.path}/.mcp.json`):Promise.resolve(null),O(`${t.path}/bin`,{filesOnly:!0})]),J=g?await ae(g):[],T=B.filter(N=>N.endsWith(".md")),U=await Promise.all(T.map(N=>window.api.config.readText(`${t.path}/agents/${N}`))),I=[];T.forEach((N,F)=>{const M=U[F];if(!M.exists)return;const D=G(M.text);I.push({id:N,name:D.name??N.replace(/\.md$/,""),description:D.description})});const H=[];if(v&&v.exists&&!v.parseError&&v.data&&typeof v.data=="object"){const N=v.data.mcpServers;if(N&&typeof N=="object")for(const[F,M]of Object.entries(N)){const D=M&&typeof M=="object"?M.command:void 0;H.push({id:F,name:F,description:typeof D=="string"?D:null})}}if(u)return;i(J),l(I),d(H),b(Q),L(J.length>0?"skills":I.length>0?"agents":H.length>0?"mcp":t.hooks>0?"hooks":t.monitors>0?"monitors":t.hasLsp?"lsp":"files")}catch(g){if(u)return;R.error(`Failed to load plugin contents: ${g instanceof Error?g.message:String(g)}`),i([]),l([]),d([]),b([])}finally{u||h(!1)}})(),()=>{u=!0}},[t.path,t.name,t.hasMcp,t.hooks,t.monitors,t.hasLsp,n]);const s=[{key:"skills",label:"Skills",count:a.length},{key:"agents",label:"Agents",count:m.length},{key:"mcp",label:"MCP server",count:r.length},{key:"hooks",label:"Hooks",count:t.hooks},{key:"monitors",label:"Monitors",count:t.monitors},{key:"lsp",label:"LSP",count:t.hasLsp?1:0},{key:"files",label:"Bin",count:f.length}],x=(j=t.manifest)!=null&&j.author?typeof t.manifest.author=="string"?t.manifest.author:t.manifest.author.name??null:null,k=async u=>{const g=await window.api.shell.open({as:"external",url:u});g.ok||R.error(g.error??`Failed to open ${u}`)};return S?e.jsx(oe,{pluginName:((w=t.manifest)==null?void 0:w.name)??t.name,skills:a,initialSelectedId:S.id,onBack:()=>$(null)},S.id):e.jsxs("div",{className:"flex flex-col h-full min-h-0 overflow-hidden",children:[e.jsxs("div",{className:"shrink-0 h-11 flex items-baseline gap-3.5 px-3 border-b border-line bg-bg",children:[e.jsx("button",{type:"button",onClick:o,className:"font-mono text-accent hover:underline shrink-0 text-xs",children:"← Plugins"}),e.jsx("span",{className:"font-serif text-[22px] text-fg shrink-0 truncate max-w-[16rem]",children:((C=t.manifest)==null?void 0:C.name)??t.name}),(A=t.manifest)!=null&&A.version?e.jsxs("span",{className:"font-mono text-fg-faint text-xs shrink-0",children:["v",t.manifest.version]}):null,(_=t.manifest)!=null&&_.description?e.jsx("span",{className:"text-fg-dim text-xs min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap",children:t.manifest.description}):e.jsx("span",{className:"flex-1"}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx(z,{input:q(t)}),t.hasMcp?e.jsx(Y,{tone:"accent",children:"MCP"}):null]})]}),t.manifest?e.jsxs("div",{className:"shrink-0 h-[26px] flex items-center gap-[18px] px-3 bg-bg-elev border-b border-line text-[9px] font-mono uppercase tracking-wide overflow-hidden",children:[x?e.jsxs("span",{className:"text-fg-dim truncate",children:[e.jsx("span",{className:"text-fg-faint",children:"Author "}),x]}):null,t.manifest.license?e.jsxs("span",{className:"text-fg-dim truncate",children:[e.jsx("span",{className:"text-fg-faint",children:"License "}),t.manifest.license]}):null,t.manifest.homepage?e.jsxs("button",{onClick:()=>k(t.manifest.homepage),className:"text-accent hover:underline truncate normal-case",title:t.manifest.homepage,children:[e.jsx("span",{className:"text-fg-faint uppercase",children:"Homepage "}),t.manifest.homepage]}):null,e.jsx("span",{className:"ml-auto text-fg-faint truncate normal-case",children:t.path})]}):e.jsx("div",{className:"shrink-0 h-[26px] flex items-center px-3 bg-bg-elev border-b border-line text-[9px] font-mono uppercase tracking-wide overflow-hidden",children:e.jsx("span",{className:"ml-auto text-fg-faint truncate normal-case",children:t.path})}),e.jsxs("div",{className:"flex-1 min-h-0 grid overflow-hidden",style:{gridTemplateColumns:"170px 1fr"},children:[e.jsx("div",{className:"min-h-0 overflow-auto bg-bg-elev border-r border-line py-1",children:s.map(u=>e.jsxs("button",{type:"button",disabled:u.count===0,onClick:()=>L(u.key),className:`w-full text-left px-3 py-1.5 text-xs flex items-center justify-between ${u.count===0?"text-fg-faint opacity-50 cursor-default":c===u.key?"bg-bg-hi text-fg":"text-fg-dim hover:text-fg hover:bg-bg-hi"}`,children:[e.jsx("span",{children:u.label}),u.count>0?e.jsx("span",{className:"font-mono text-fg-faint",children:u.count}):null]},u.key))}),e.jsx("div",{className:"min-h-0 overflow-auto",children:E?e.jsx(y,{title:"scanning…"}):e.jsx(he,{active:c,row:t,skills:a,agents:m,mcpServers:r,files:f,onOpenSkill:$})})]})]})}function he({active:t,row:n,skills:o,agents:a,mcpServers:i,files:m,onOpenSkill:l}){return t==="skills"?o.length===0?e.jsx(y,{title:"no components"}):e.jsx("div",{children:o.map((r,d)=>e.jsx(P,{n:d+1,name:r.name??r.id,description:r.description,onClick:()=>l(r)},r.id))}):t==="agents"?a.length===0?e.jsx(y,{title:"no components"}):e.jsx("div",{children:a.map((r,d)=>e.jsx(P,{n:d+1,name:r.name??r.id,description:r.description},r.id))}):t==="mcp"?i.length===0?e.jsx(y,{title:"no components"}):e.jsx("div",{children:i.map((r,d)=>e.jsx(P,{n:d+1,name:r.name,description:r.description},r.id))}):t==="hooks"?n.hooks===0?e.jsx(y,{title:"no components"}):e.jsx("div",{children:e.jsx(P,{n:1,name:`${n.hooks} ${n.hooks===1?"hook":"hooks"} configured`,description:`${n.path}/hooks/hooks.json`})}):t==="monitors"?n.monitors===0?e.jsx(y,{title:"no components"}):e.jsx("div",{children:e.jsx(P,{n:1,name:`${n.monitors} ${n.monitors===1?"monitor":"monitors"} configured`,description:`${n.path}/monitors/monitors.json`})}):t==="lsp"?n.hasLsp?e.jsx("div",{children:e.jsx(P,{n:1,name:"LSP server enabled",description:`${n.path}/.lsp.json`})}):e.jsx(y,{title:"no components"}):m.length===0?e.jsx(y,{title:"no components"}):e.jsx("div",{children:m.map((r,d)=>e.jsx(P,{n:d+1,name:r,description:null},r))})}function P({n:t,name:n,description:o,onClick:a}){const i=a?"button":"div";return e.jsxs(i,{onClick:a,className:`w-full flex items-baseline gap-2.5 py-[9px] px-3 border-b border-line text-left min-w-0 ${a?"hover:bg-bg-hi cursor-pointer":""}`,children:[e.jsx("span",{className:"font-serif text-fg-faint text-xs shrink-0 w-6 text-right",children:String(t).padStart(2,"0")}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-mono font-semibold text-accent truncate",children:n}),o?e.jsx("div",{className:"text-fg-dim text-xs truncate",children:o}):null]})]})}async function fe(t){let n=`${t.path}/.claude-plugin/plugin.json`,o=await window.api.config.exists(n);o||(n=`${t.path}/plugin.json`,o=await window.api.config.exists(n));let a=null;if(o){const h=await window.api.config.readJson(n);h.exists&&!h.parseError&&h.data&&typeof h.data=="object"&&(a=h.data)}const[i,m,l,r]=await Promise.all([window.api.config.exists(`${t.path}/.lsp.json`),window.api.config.exists(`${t.path}/.mcp.json`),window.api.config.exists(`${t.path}/monitors/monitors.json`),window.api.config.exists(`${t.path}/hooks/hooks.json`)]);let d=0;if(l){const h=await window.api.config.readJson(`${t.path}/monitors/monitors.json`);Array.isArray(h.data)?d=h.data.length:h.data&&typeof h.data=="object"&&Array.isArray(h.data.monitors)&&(d=h.data.monitors.length)}let f=0;if(r){const h=await window.api.config.readJson(`${t.path}/hooks/hooks.json`);if(h.data&&typeof h.data=="object"){const s=h.data;f=Object.values(s).reduce((x,k)=>Array.isArray(k)?x+k.reduce((j,w)=>j+(Array.isArray(w.hooks)?w.hooks.length:0),0):x,0)}}const[b,c,L]=await Promise.all([O(`${t.path}/agents`,{filesOnly:!0}),O(`${t.path}/bin`,{filesOnly:!0}),O(`${t.path}/skills`,{dirsOnly:!0})]),S=b.filter(h=>h.endsWith(".md")).length,$=c.length,E=L.length;return{name:t.name,path:t.path,mtimeMs:t.mtimeMs,hasManifest:o,manifest:a,hasLsp:i,monitors:d,hooks:f,agents:S,skills:E,binCount:$,hasMcp:m}}async function O(t,n){try{return(await window.api.config.listDir(t,n)).entries.map(a=>a.name)}catch{return[]}}export{ke as Plugins};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{$ as P,aN as G,au as x,ah as i,Z as R,B as T,b as _}from"./index-D5H_H5wC.js";import{a as E,C as B,c as L,d as S,b as I}from"./Library-DeKdY-tD.js";const N=e=>`${e}/.claude/session-manager/provenance.json`;function D(e){if(!e||typeof e!="object")return{};const t={};for(const[n,o]of Object.entries(e))(o==="anthropic"||o==="community"||o==="local")&&(t[n]=o);return t}const K=P((e,t)=>({overrides:{},loaded:!1,loading:!1,home:null,load:async n=>{const o=t();if(!(o.home===n&&(o.loaded||o.loading))){e({home:n,loading:!0});try{const r=await window.api.config.readJson(N(n)),d=r.exists?D(r.data):{};e(h=>({overrides:{...d,...h.overrides},loaded:!0,loading:!1}))}catch{e({loaded:!0,loading:!1})}}},setOverride:async(n,o)=>{const r={...t().overrides};o===null?delete r[n]:r[n]=o,e({overrides:r});const d=t().home;if(d)try{await window.api.config.writeJson(N(d),r)}catch{}}})),a=e=>(e??"").toLowerCase().trim(),$=new Set,j=new Set;for(const e of I){const t=e.official?$:j;t.add(a(e.id)),t.add(a(e.name))}const H=new Set(S.filter(e=>e.official).flatMap(e=>[a(e.id),a(e.name)])),J=new Set(S.filter(e=>!e.official).flatMap(e=>[a(e.id),a(e.name)])),U=new Set(L.filter(e=>e.official).flatMap(e=>[a(e.id),a(e.name)])),V=new Set(L.filter(e=>!e.official).flatMap(e=>[a(e.id),a(e.name)])),z=new Set(B.flatMap(e=>[a(e.id),a(e.name)])),Z=new Set(E.flatMap(e=>[a(e.id),a(e.name)])),q=new Set(E.map(e=>e.command.trim())),F=new Set(["security-review","pr-comments","release-notes","add-dir","code-review","simplify"]),Q=/(@anthropic-ai\/|anthropic\.com|github\.com\/anthropics)/i,W=/(^|\s)(npx|uvx|pipx|bunx|mcp-remote|deno\s+run|docker\s+run)(\s|$)/i;function X(e){return[e.command,...e.args??[],e.url,e.repository,e.homepage].filter(Boolean).join(" ").toLowerCase()}const l=e=>({provenance:"anthropic",reason:e}),y=e=>({provenance:"community",reason:e});function Y(e,t,n){switch(e){case"mcp":return $.has(t)?l("official MCP server (catalog)"):j.has(t)?y("third-party server (catalog)"):null;case"skill":case"command":return H.has(t)?l("official Anthropic skill (catalog)"):J.has(t)?y("third-party skill (catalog)"):null;case"plugin":return U.has(t)?l("official Anthropic plugin (catalog)"):V.has(t)?y("third-party plugin (catalog)"):null;case"subagent":return z.has(t)?l("bundled Anthropic subagent (catalog)"):null;case"hook":return Z.has(t)||n&&q.has(n.trim())?l("bundled hook (catalog)"):null}}function ee(e,t){return e.repository?"has a source repository":e.homepage?"has a homepage":e.url?"remote endpoint":W.test(t)?"installed from a package registry":null}function te(e){const t=a(e.name),n=X(e),o=Y(e.type,t,e.command);if(o)return o;if((e.type==="command"||e.type==="skill")&&F.has(t))return l("built-in Claude Code command");if(Q.test(n))return l("Anthropic package or repo");const r=ee(e,n);return r?y(r):{provenance:"local",reason:"no external source — assumed self-created"}}function ne(e,t,n){return`${e}:${t??"-"}:${n}`}const c={anthropic:"Anthropic",community:"Community",local:"Local"},O={anthropic:"accent",community:"warn",local:"dim"},oe=["anthropic","community","local"];function se({input:e,scope:t,interactive:n=!0,className:o=""}){const r=G(),{overrides:d,load:h,setOverride:k}=K(),[b,m]=x.useState(!1),v=x.useRef(null);x.useEffect(()=>{r&&h(r)},[r,h]),x.useEffect(()=>{if(!b)return;const s=C=>{v.current&&!v.current.contains(C.target)&&m(!1)},g=C=>{C.key==="Escape"&&m(!1)};return window.addEventListener("mousedown",s),window.addEventListener("keydown",g),()=>{window.removeEventListener("mousedown",s),window.removeEventListener("keydown",g)}},[b]);const w=ne(e.type,t??null,e.name),f=te(e),p=d[w],u=p??f.provenance,M=p?`Origin manually set to ${c[u]} — auto-detected ${c[f.provenance]} (${f.reason})`:`Auto-detected ${c[u]}: ${f.reason}`,A=i.jsxs(_,{tone:O[u],title:M,className:`${n?"cursor-pointer hover:brightness-125":""} ${o}`,children:[c[u],p&&i.jsx("span",{className:"w-1 h-1 rounded-full bg-current opacity-70","aria-hidden":!0})]});return n?i.jsxs("span",{ref:v,className:"relative inline-flex",children:[i.jsx("button",{type:"button",onClick:s=>{s.stopPropagation(),m(g=>!g)},className:"inline-flex","aria-label":`Origin: ${c[u]}. Click to change.`,children:A}),b&&i.jsxs("span",{className:`absolute ${R.dialog} top-full right-0 mt-1 min-w-[7.5rem] rounded-md border border-line bg-bg-elev shadow-lg py-1 text-left`,onClick:s=>s.stopPropagation(),children:[i.jsx("span",{className:"block px-2 pb-1 text-[10px] uppercase tracking-wide text-fg-faint",children:"Mark origin as"}),oe.map(s=>i.jsxs("button",{type:"button",onClick:()=>{k(w,s),m(!1)},className:`flex w-full items-center gap-2 px-2 py-1 text-[12px] hover:bg-bg-hi/60 ${u===s?"text-fg":"text-fg-dim"}`,children:[i.jsx("span",{className:`w-2 h-2 rounded-full border ${T[O[s]]}`,"aria-hidden":!0}),c[s],p===s&&i.jsx("span",{className:"ml-auto text-[10px] text-fg-faint",children:"set"})]},s)),i.jsx("div",{className:"my-1 border-t border-line"}),i.jsxs("button",{type:"button",onClick:()=>{k(w,null),m(!1)},disabled:!p,className:"flex w-full items-center gap-2 px-2 py-1 text-[12px] text-fg-dim hover:bg-bg-hi/60 disabled:opacity-40 disabled:hover:bg-transparent",title:`Revert to auto-detection (${c[f.provenance]})`,children:["Auto-detect",i.jsx("span",{className:"ml-auto text-[10px] text-fg-faint",children:c[f.provenance]})]})]})]}):A}export{se as P};
|