claude-code-session-manager 0.92.0 → 0.93.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-DDGx3qrn.js +1 -0
- package/dist/assets/{History-BB6wpf02.js → History-CHBjYZyD.js} +2 -2
- package/dist/assets/{Hooks-zQZH56Sv.js → Hooks-DG4c-Rzz.js} +3 -3
- package/dist/assets/{HostBilko-CW0pHoPS.js → HostBilko-DHXcpV2c.js} +1 -1
- package/dist/assets/{Library-DrGdaz9N.js → Library-CN1h5rAE.js} +1 -1
- package/dist/assets/{MarkdownEditor-H1ytN4Tk.js → MarkdownEditor-DmBxrhdn.js} +1 -1
- package/dist/assets/{McpServers-CYSRCI-j.js → McpServers-Beb_HD6I.js} +2 -2
- package/dist/assets/{Memory-zMNpJyRU.js → Memory-Dk4uDCjg.js} +4 -4
- package/dist/assets/{Permissions-Be6cIkPg.js → Permissions-BovobeZw.js} +3 -3
- package/dist/assets/Plugins-DvOf_B62.js +2 -0
- package/dist/assets/ProvenanceBadge-Dutz_4OY.js +1 -0
- package/dist/assets/{SaveBar-xQZ2EBOn.js → SaveBar-CT5u6ZCJ.js} +1 -1
- package/dist/assets/Scheduler-B7GSnZj5.js +16 -0
- package/dist/assets/{ScopeSwitcher-BAfquN6Y.js → ScopeSwitcher-BUYDpz2v.js} +1 -1
- package/dist/assets/Settings-DIRmr3tL.js +3 -0
- package/dist/assets/{SkillReferenceGraph-BI1YtCbB.js → SkillReferenceGraph-CdGr6d3_.js} +1 -1
- package/dist/assets/Skills-BQOheQv4.js +3 -0
- package/dist/assets/SystemPrompt-5LsimKbX.js +1 -0
- package/dist/assets/TagLibrary-DreLsT3n.js +1 -0
- package/dist/assets/{TiptapBody-BptXAVR9.js → TiptapBody-C9kmlBnI.js} +1 -1
- package/dist/assets/{Toggle-BwiClCSI.js → Toggle-BKLCBu9A.js} +1 -1
- package/dist/assets/{index-D3P_jldk.css → index-CKH5Uxik.css} +1 -1
- package/dist/assets/index-Db_SK9rW.js +3079 -0
- package/dist/assets/settingsSchema-B5jBhSUP.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- 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__/chatRunner-session-flag-retry.test.cjs +44 -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 +75 -10
- package/src/main/__tests__/scheduler-prd-persona-spawn.test.cjs +47 -2
- package/src/main/agentLibrary.cjs +86 -40
- package/src/main/build-info.json +4 -4
- package/src/main/chatRunner.cjs +5 -0
- package/src/main/index.cjs +10 -0
- package/src/main/ipcSchemas.cjs +12 -0
- package/src/main/lib/__tests__/effectiveModelInfo.test.cjs +10 -5
- 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 +3 -0
- package/src/main/lib/effectiveModelInfo.cjs +38 -20
- package/src/main/lib/epicMint.cjs +5 -2
- package/src/main/lib/epicWorktreeMerge.cjs +7 -6
- package/src/main/lib/modelCatalog.cjs +243 -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 +3 -0
- package/src/main/lib/promptSessionsCreateEpic.cjs +5 -3
- package/src/main/pty.cjs +16 -2
- package/src/main/scheduler/prdParser.cjs +2 -0
- package/src/main/scheduler.cjs +21 -5
- package/src/main/templates/PRD_AUTHORING.md +4 -0
- package/src/preload/api.d.ts +53 -2
- package/src/preload/index.cjs +4 -0
- package/dist/assets/AgentLibrary-Bu-1eT_n.js +0 -3
- package/dist/assets/DataModel-Bk9rkJ8x.js +0 -1
- package/dist/assets/ListDetail-D4bxU_-2.js +0 -1
- package/dist/assets/Panel-RMz3Acpu.js +0 -1
- package/dist/assets/Plugins-B8sTWf2K.js +0 -2
- package/dist/assets/ProvenanceBadge-CO-DZN38.js +0 -1
- package/dist/assets/Scheduler-CF3zsJBw.js +0 -16
- package/dist/assets/Settings-uPjmqutA.js +0 -3
- package/dist/assets/Skills-BEy9FDYd.js +0 -3
- package/dist/assets/SystemPrompt-BYkkw-LL.js +0 -1
- package/dist/assets/TagLibrary-Kg3yOC5b.js +0 -1
- package/dist/assets/index-a2MVk8qh.js +0 -3074
- package/dist/assets/settingsSchema-DgxlStF5.js +0 -3
package/src/main/pty.cjs
CHANGED
|
@@ -23,6 +23,7 @@ const { checkInsideHome } = require('./lib/insideHome.cjs');
|
|
|
23
23
|
const { sendIfAlive } = require('./lib/sendToRenderer.cjs');
|
|
24
24
|
const opsErrorLog = require('./lib/opsErrorLog.cjs');
|
|
25
25
|
const { planEpicSpawn } = require('./lib/epicSpawnPlan.cjs');
|
|
26
|
+
const { resolveEpicSpawnCwd } = require('./lib/epicSpawnCwd.cjs');
|
|
26
27
|
const telemetryCounters = require('./lib/telemetryCounters.cjs');
|
|
27
28
|
|
|
28
29
|
// Absolute path to the installed package root (src/main/ -> ../../), shown in
|
|
@@ -180,8 +181,22 @@ class PtyManager {
|
|
|
180
181
|
// so this asks the same decision function chatRunner.cjs does (epicSpawnPlan.cjs). `cwd`
|
|
181
182
|
// itself is NEVER repointed; only this actual PTY spawn option is (epicSpawnCwd.cjs's
|
|
182
183
|
// ops-root hazard). A refused plan is surfaced in-tab rather than spawning into a bad cwd.
|
|
184
|
+
// Split: Chat and Terminal share this one verdict function, but the Terminal additionally
|
|
185
|
+
// downgrades `epic_closed` to a plain shell — it opens `$SHELL -il` (no --resume, no
|
|
186
|
+
// transcript write), not a chat turn. That path uses the read-side resolver WITHOUT
|
|
187
|
+
// `deps.restore`, so opening a closed Epic's terminal never re-attaches a checkout.
|
|
183
188
|
const plan = planEpicSpawn({ cwd, claudeSessionId: tabId });
|
|
184
|
-
|
|
189
|
+
let spawnCwd;
|
|
190
|
+
if (plan.ok) {
|
|
191
|
+
spawnCwd = plan.execCwd;
|
|
192
|
+
} else if (plan.code === 'epic_closed') {
|
|
193
|
+
spawnCwd = resolveEpicSpawnCwd({ cwd, claudeSessionId: tabId });
|
|
194
|
+
sendIfAlive(
|
|
195
|
+
this.window,
|
|
196
|
+
`pty:data:${tabId}`,
|
|
197
|
+
`\r\nThis Epic is completed \u2014 opening a read-only shell in ${spawnCwd}. Start a new Epic for new work.\r\n`,
|
|
198
|
+
);
|
|
199
|
+
} else {
|
|
185
200
|
opsErrorLog.appendError({
|
|
186
201
|
cwd,
|
|
187
202
|
scope: 'pty',
|
|
@@ -193,7 +208,6 @@ class PtyManager {
|
|
|
193
208
|
setImmediate(() => sendIfAlive(this.window, `pty:exit:${tabId}`, { exitCode: 1, signal: undefined }));
|
|
194
209
|
return { pid: null, cwd, reattached: false, error: plan.message };
|
|
195
210
|
}
|
|
196
|
-
const spawnCwd = plan.execCwd;
|
|
197
211
|
if (spawnCwd !== cwd) {
|
|
198
212
|
console.log(`[pty] tabId=${tabId} isolated in worktree ${spawnCwd}`);
|
|
199
213
|
}
|
|
@@ -126,6 +126,8 @@ async function parsePrdRaw(filePath) {
|
|
|
126
126
|
// the decision (first-ever PRD in its Epic, or one with its own explicit
|
|
127
127
|
// dependsOn).
|
|
128
128
|
disposition: (fm.disposition === 'append' || fm.disposition === 'new-head') ? fm.disposition : null,
|
|
129
|
+
// Durable wave identity (createPrd-stamped); malformed values read as absent.
|
|
130
|
+
planId: (typeof fm.planId === 'string' && /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(fm.planId)) ? fm.planId : null,
|
|
129
131
|
// Opt-in exclusive-lease flag (PRD 1107, quietMachineLease.cjs +
|
|
130
132
|
// schedulerBatch.cjs's pickNextBatch). Only a literal `true` opts in —
|
|
131
133
|
// matches prdFrontmatter.cjs's applyKey semantics for this field.
|
package/src/main/scheduler.cjs
CHANGED
|
@@ -145,6 +145,7 @@ const queueOps = require('./queueOps.cjs');
|
|
|
145
145
|
const { resolvePrdsDirs, resolveArchivedPrdsDirs, resolvePrdWriteDir, listEpicPrdDirs, listArchivedPrdDirs, deriveProjectCwdFromPrdPath } = require('./lib/prdLocations.cjs');
|
|
146
146
|
const { ensureEpic, appendPrdCreatedEvent, readActiveIndex } = require('./lib/epicMint.cjs');
|
|
147
147
|
const agentModelResolve = require('./lib/agentModelResolve.cjs');
|
|
148
|
+
const { resolveEpicEffort, effortArgs } = require('./lib/agentEffortResolve.cjs');
|
|
148
149
|
const { transitionJob, STATUS_HISTORY_CAP, LEGAL_TRANSITIONS } = require('./lib/scheduleJobTransitions.cjs');
|
|
149
150
|
const { buildContextDigest, composeExecutorPrompt } = require('./lib/epicContextDigest.cjs');
|
|
150
151
|
const { JOB_STATUSES } = require('./lib/scheduleJobSchema.cjs');
|
|
@@ -181,7 +182,7 @@ const supervisorRecord = require('./lib/jobSupervisorRecord.cjs');
|
|
|
181
182
|
const adoptedRunSupervisor = require('./lib/adoptedRunSupervisor.cjs');
|
|
182
183
|
const { splitFrontmatter, parsePrdFile, serializePrdFile } = require('./lib/prdFrontmatter.cjs');
|
|
183
184
|
const { resolveDepSlug, findNearMatches } = require('./lib/depSlugResolve.cjs');
|
|
184
|
-
const { computeDispositionRewrite } = require('./lib/prdDisposition.cjs');
|
|
185
|
+
const { computeDispositionRewrite, mintPlanId, resolveInheritedPlanId } = require('./lib/prdDisposition.cjs');
|
|
185
186
|
const { migratePrds, consolidateFlatPrds, legacyAdoptExistingPrds } = require('./lib/prdMigration.cjs');
|
|
186
187
|
const { allProjectCwds } = require('./lib/activeSessions.cjs');
|
|
187
188
|
|
|
@@ -2811,6 +2812,7 @@ async function reconcile(state) {
|
|
|
2811
2812
|
epicId: p.epicId ?? job.epicId ?? null,
|
|
2812
2813
|
dependsOn: p.dependsOn,
|
|
2813
2814
|
disposition: p.disposition ?? null,
|
|
2815
|
+
planId: p.planId ?? null,
|
|
2814
2816
|
quietMachine: p.quietMachine === true,
|
|
2815
2817
|
budgetExempt: p.budgetExempt === true,
|
|
2816
2818
|
originSessionId: job.originSessionId
|
|
@@ -2933,6 +2935,7 @@ async function reconcile(state) {
|
|
|
2933
2935
|
epicId: p.epicId ?? inv.row?.epicId ?? null,
|
|
2934
2936
|
dependsOn: p.dependsOn,
|
|
2935
2937
|
disposition: p.disposition ?? null,
|
|
2938
|
+
planId: p.planId ?? null,
|
|
2936
2939
|
quietMachine: p.quietMachine === true,
|
|
2937
2940
|
budgetExempt: p.budgetExempt === true,
|
|
2938
2941
|
originSessionId: inv.row?.originSessionId ?? resolveOriginSessionId(repairedCwd, p.epicId ?? p.sourcePromptId),
|
|
@@ -3067,6 +3070,7 @@ async function reconcile(state) {
|
|
|
3067
3070
|
epicId: p.epicId ?? null,
|
|
3068
3071
|
dependsOn: p.dependsOn,
|
|
3069
3072
|
disposition: p.disposition ?? null,
|
|
3073
|
+
planId: p.planId ?? null,
|
|
3070
3074
|
quietMachine: p.quietMachine === true,
|
|
3071
3075
|
budgetExempt: p.budgetExempt === true,
|
|
3072
3076
|
originSessionId: resolveOriginSessionId(discoveredCwd, p.epicId ?? p.sourcePromptId),
|
|
@@ -5249,15 +5253,17 @@ async function performLeftoverQuarantine(job, paths, headBefore = null) {
|
|
|
5249
5253
|
* selects `--resume <sessionId>` (reconnect) INSTEAD of `--session-id
|
|
5250
5254
|
* <sessionId>` (mint) — the two flags are mutually exclusive, never both.
|
|
5251
5255
|
* `--model` is always explicit (never left to the CLI's drifting default —
|
|
5252
|
-
* see conventions.md). `
|
|
5256
|
+
* see conventions.md). `effort`, when a level (persona `effort:` via
|
|
5257
|
+
* agentEffortResolve.cjs), appends `--effort <level>`; null/inherit → no flag. `systemPrompt`, when given (the PRD's `agentType`
|
|
5253
5258
|
* persona body, resolved by agentModelResolve.cjs's resolvePrdPersonaForSpawn),
|
|
5254
5259
|
* is passed as `--append-system-prompt` so the executor IS that persona at
|
|
5255
5260
|
* launch rather than being asked in prose to adopt one.
|
|
5256
5261
|
*/
|
|
5257
|
-
function buildClaudeSpawnArgs({ prompt, model, sessionId, resume, systemPrompt }) {
|
|
5262
|
+
function buildClaudeSpawnArgs({ prompt, model, effort, sessionId, resume, systemPrompt }) {
|
|
5258
5263
|
return [
|
|
5259
5264
|
'-p', prompt,
|
|
5260
5265
|
'--model', model,
|
|
5266
|
+
...effortArgs(effort),
|
|
5261
5267
|
...(systemPrompt ? ['--append-system-prompt', systemPrompt] : []),
|
|
5262
5268
|
'--dangerously-skip-permissions',
|
|
5263
5269
|
'--output-format', 'stream-json',
|
|
@@ -5510,7 +5516,8 @@ async function executeJob(job, runDir, defaultCwd, onPid, execCwd, resumeTarget
|
|
|
5510
5516
|
// a dangling/absent agentType falls back to no persona + FALLBACK_MODEL
|
|
5511
5517
|
// and is logged once by resolvePrdPersonaForSpawn itself.
|
|
5512
5518
|
const personaResolution = await agentModelResolve.resolvePrdPersonaForSpawn({ cwd, agentType: job.agentType });
|
|
5513
|
-
|
|
5519
|
+
const personaEffort = resolveEpicEffort({ cwd, agentType: job.agentType }).effort;
|
|
5520
|
+
safeLog(`[scheduler] agentType=${job.agentType || '(none)'} persona=${personaResolution.personaPath || '(fallback — no persona applied)'} model=${personaResolution.model}${personaEffort ? ` effort=${personaEffort}` : ''}\n`);
|
|
5514
5521
|
|
|
5515
5522
|
return await new Promise((resolve) => {
|
|
5516
5523
|
const claudeBin = resolveClaudeBin();
|
|
@@ -5710,6 +5717,7 @@ async function executeJob(job, runDir, defaultCwd, onPid, execCwd, resumeTarget
|
|
|
5710
5717
|
args: buildClaudeSpawnArgs({
|
|
5711
5718
|
prompt,
|
|
5712
5719
|
model: personaResolution.model,
|
|
5720
|
+
effort: personaEffort,
|
|
5713
5721
|
sessionId,
|
|
5714
5722
|
resume: !!resumeTarget,
|
|
5715
5723
|
systemPrompt: personaResolution.systemPrompt,
|
|
@@ -11946,6 +11954,7 @@ async function listPrdsInternal() {
|
|
|
11946
11954
|
dependsOn: parsed.dependsOn ?? null,
|
|
11947
11955
|
agentType: parsed.agentType ?? null,
|
|
11948
11956
|
disposition: parsed.disposition ?? null,
|
|
11957
|
+
planId: parsed.planId ?? null,
|
|
11949
11958
|
mtimeMs: stat.mtimeMs,
|
|
11950
11959
|
archived,
|
|
11951
11960
|
};
|
|
@@ -12379,7 +12388,14 @@ const remote = {
|
|
|
12379
12388
|
const rows = listing.prds ?? [];
|
|
12380
12389
|
const rewrite = computeDispositionRewrite({ slug, disposition, dependsOn: dependsOn ?? [], rows });
|
|
12381
12390
|
if (!rewrite.ok) return rewrite;
|
|
12382
|
-
|
|
12391
|
+
// Keep the durable planId in step with the new relationship: a promoted head
|
|
12392
|
+
// starts its own plan; a re-attached row joins the target chain's plan (cleared
|
|
12393
|
+
// when the target predates the stamp, so the derivation fallback applies).
|
|
12394
|
+
let planId = mintPlanId();
|
|
12395
|
+
if (disposition === 'append') {
|
|
12396
|
+
planId = resolveInheritedPlanId(rewrite.dependsOn, rows).planId;
|
|
12397
|
+
}
|
|
12398
|
+
return this.updatePrd({ slug, cwd, frontmatter: { dependsOn: rewrite.dependsOn, disposition, planId } });
|
|
12383
12399
|
},
|
|
12384
12400
|
|
|
12385
12401
|
// Cancels a job that hasn't finished yet. A 'running' job's process group
|
|
@@ -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/preload/api.d.ts
CHANGED
|
@@ -235,6 +235,8 @@ export interface AgentPersona {
|
|
|
235
235
|
description: string | null;
|
|
236
236
|
tools: string[];
|
|
237
237
|
model: string | null;
|
|
238
|
+
/** Per-Epic reasoning effort (`effort:` frontmatter; a `models.catalog` effort level). Null = inherit. Passed to the claude spawn as `--effort` (never `auto`). */
|
|
239
|
+
effort: string | null;
|
|
238
240
|
color: string | null;
|
|
239
241
|
/** Epic intent tags (tagLibrary.ts's TAG_LIBRARY) this persona is associated with. */
|
|
240
242
|
tags: AgentPersonaTag[];
|
|
@@ -253,6 +255,8 @@ export interface AgentPersona {
|
|
|
253
255
|
body: string;
|
|
254
256
|
/** Project names (basename of cwd) whose currently-open tab overlays this agent. */
|
|
255
257
|
overridingProjects: string[];
|
|
258
|
+
/** Per open project with an overlay: which frontmatter keys / body the overlay overrides (merged view provenance). */
|
|
259
|
+
overrideDetails?: { project: string; fields: string[]; values?: Record<string, string>; bodyOverridden: boolean; issue: string | null }[];
|
|
256
260
|
}
|
|
257
261
|
|
|
258
262
|
/** Payload for `agents.savePersona` — creates or overwrites a global persona file. */
|
|
@@ -263,6 +267,8 @@ export interface AgentPersonaSaveInput {
|
|
|
263
267
|
description: string;
|
|
264
268
|
tools: string[];
|
|
265
269
|
model: string;
|
|
270
|
+
/** Effort level, or `'inherit'`/omitted to write no `effort:` line. */
|
|
271
|
+
effort?: string;
|
|
266
272
|
color: string;
|
|
267
273
|
tags: AgentPersonaTag[];
|
|
268
274
|
/** Project cwds (or the `'*'` sentinel) this persona's Action button appears in. */
|
|
@@ -272,6 +278,8 @@ export interface AgentPersonaSaveInput {
|
|
|
272
278
|
/** Caption override for this persona's Action button. */
|
|
273
279
|
actionLabel?: string;
|
|
274
280
|
title?: string;
|
|
281
|
+
/** Open project name: write that project's frontmatter-only override (only `model`/`effort` are used) instead of the global file. */
|
|
282
|
+
projectName?: string;
|
|
275
283
|
body: string;
|
|
276
284
|
}
|
|
277
285
|
|
|
@@ -556,6 +564,8 @@ export interface ScheduleJob {
|
|
|
556
564
|
* independent root). Refreshed from the PRD file on every reconcile, like
|
|
557
565
|
* dependsOn above; null when this row never needed the decision. */
|
|
558
566
|
disposition?: 'append' | 'new-head' | null;
|
|
567
|
+
/** Durable wave identity stamped into PRD frontmatter by createPrd(); buildPlans groups by it. Null on PRDs that predate the stamp. */
|
|
568
|
+
planId?: string | null;
|
|
559
569
|
/** The originating claude session — the Epic's claudeSessionId, resolved
|
|
560
570
|
* from active-index.json at ingest (PRD 832). An Epic IS a tagged session. */
|
|
561
571
|
originSessionId?: string | null;
|
|
@@ -575,6 +585,9 @@ export interface ScheduleJob {
|
|
|
575
585
|
* intent-carrying `sourcePromptId`/`sourceTabId`, which can disagree.
|
|
576
586
|
* Authoritative source for "which Epic is this from" in every UI. */
|
|
577
587
|
epicId?: string | null;
|
|
588
|
+
/** Renderer-only: true for a row synthesized from an archived PRD file (no queue row
|
|
589
|
+
* exists to act on) — see lib/archivedPlanRows. Never present in queue.json. */
|
|
590
|
+
synthetic?: boolean;
|
|
578
591
|
/** Bounded trail of accepted status transitions (scheduleJobTransitions.cjs's
|
|
579
592
|
* transitionJob), oldest-first, capped at ~20 entries. Lets a status
|
|
580
593
|
* change be reviewed after the fact instead of only inferred from a
|
|
@@ -703,6 +716,8 @@ export interface PrdListItem {
|
|
|
703
716
|
dependsOn?: string[] | null;
|
|
704
717
|
/** PRD frontmatter `disposition` — see ScheduleJob.disposition. */
|
|
705
718
|
disposition?: 'append' | 'new-head' | null;
|
|
719
|
+
/** PRD frontmatter `planId` — see ScheduleJob.planId. */
|
|
720
|
+
planId?: string | null;
|
|
706
721
|
/** True when this PRD's source .md was found in a `prds-archived/` dir
|
|
707
722
|
* (its scheduler job already ran to completion) rather than the live
|
|
708
723
|
* `prds/` dir. Archived PRDs have no matching queue.json job row (the
|
|
@@ -1637,7 +1652,7 @@ export interface SessionManagerAPI {
|
|
|
1637
1652
|
* resolved with project-overlay-then-global precedence for `cwd` — unlike
|
|
1638
1653
|
* `listPersonas` above, which only reads the global directory. Null when neither
|
|
1639
1654
|
* location has the file. */
|
|
1640
|
-
getPersonaBody: (payload: { cwd: string; name: string }) => Promise<{ path: string; text: string } | null>;
|
|
1655
|
+
getPersonaBody: (payload: { cwd: string; name: string }) => Promise<{ path: string; text: string; provenance?: Record<string, 'overlay' | 'global'>; bodySource?: 'overlay' | 'global' } | null>;
|
|
1641
1656
|
/** "What will this Epic actually run as?" — persona alias, overlay-aware
|
|
1642
1657
|
* provenance, and evidence-based concrete model id (scheduler run log or
|
|
1643
1658
|
* session transcript). Never throws on the main side; a dangling
|
|
@@ -1649,9 +1664,15 @@ export interface SessionManagerAPI {
|
|
|
1649
1664
|
agentType: string;
|
|
1650
1665
|
modelAlias: string | null;
|
|
1651
1666
|
modelSource: 'persona' | 'persona-overlay' | 'inherit' | 'fallback';
|
|
1667
|
+
/** Per-frontmatter-key origin of the merged persona (overlay vs global). */
|
|
1668
|
+
personaProvenance?: Record<string, 'overlay' | 'global'>;
|
|
1652
1669
|
resolvedModelId: string | null;
|
|
1653
1670
|
resolvedFrom: 'scheduler-run' | 'transcript' | null;
|
|
1654
|
-
|
|
1671
|
+
/** Env-var path only: would cleanChildEnv strip CLAUDE_EFFORT. Persona effort travels on argv regardless. */
|
|
1672
|
+
effortEnvReachable: boolean;
|
|
1673
|
+
/** Persona `effort:` level (null = pass no --effort) and where it came from. */
|
|
1674
|
+
personaEffort: string | null;
|
|
1675
|
+
personaEffortSource: 'persona' | 'persona-overlay' | 'inherit' | null;
|
|
1655
1676
|
}>;
|
|
1656
1677
|
/** The launch-time authority for an Epic-backed session's `--model`: the SAME
|
|
1657
1678
|
* resolver (`agentModelResolve.cjs`'s `resolveEpicModel`) chatRunner.cjs's Chat
|
|
@@ -1660,9 +1681,36 @@ export interface SessionManagerAPI {
|
|
|
1660
1681
|
* (project `.claude/agents/<name>.md` wins over global), never throws — a
|
|
1661
1682
|
* dangling agentType or absent/`inherit` model falls back to `'sonnet'`. */
|
|
1662
1683
|
resolveEpicModel: (payload: { cwd: string; claudeSessionId: string }) => Promise<string>;
|
|
1684
|
+
/** Effort twin of `resolveEpicModel` (`agentEffortResolve.cjs`): the persona `effort:` level
|
|
1685
|
+
* Terminal must launch with, or `effort: null` = append NO `--effort` flag (inherit / absent /
|
|
1686
|
+
* dangling persona). Chat resolves the same value in-process. Never throws. */
|
|
1687
|
+
resolveEpicEffort: (payload: { cwd: string; claudeSessionId: string }) => Promise<{
|
|
1688
|
+
effort: string | null;
|
|
1689
|
+
source: 'persona' | 'persona-overlay' | 'inherit' | null;
|
|
1690
|
+
}>;
|
|
1663
1691
|
/** Fires after any save/delete/removeOverride — subscribers should re-fetch listPersonas(). */
|
|
1664
1692
|
onChanged: (handler: () => void) => () => void;
|
|
1665
1693
|
};
|
|
1694
|
+
models: {
|
|
1695
|
+
/** Live model/effort catalog (`modelCatalog.cjs`'s `resolveModelCatalog`). Never rejects from
|
|
1696
|
+
* the resolver itself — a failed probe degrades down cache → floor and sets `degraded`.
|
|
1697
|
+
* `cwd` only affects `availableModels` (settings-scope allowlist); `force` bypasses the cache. */
|
|
1698
|
+
catalog: (payload: { cwd?: string; force?: boolean }) => Promise<{
|
|
1699
|
+
aliases: string[];
|
|
1700
|
+
models: string[];
|
|
1701
|
+
effortLevels: string[];
|
|
1702
|
+
settingsEffortLevels: string[];
|
|
1703
|
+
availableModels: string[] | null;
|
|
1704
|
+
claudeVersion: string | null;
|
|
1705
|
+
probedAt: string | null;
|
|
1706
|
+
sources: {
|
|
1707
|
+
aliases: 'probe' | 'cache' | 'floor';
|
|
1708
|
+
models: 'binary' | 'cache' | 'floor';
|
|
1709
|
+
effortLevels: 'probe' | 'cache' | 'floor';
|
|
1710
|
+
};
|
|
1711
|
+
degraded: boolean;
|
|
1712
|
+
}>;
|
|
1713
|
+
};
|
|
1666
1714
|
logs: {
|
|
1667
1715
|
write: (
|
|
1668
1716
|
scope: string,
|
|
@@ -2053,6 +2101,9 @@ export interface PromptSessionsCreateEpicPayload {
|
|
|
2053
2101
|
goalText: string;
|
|
2054
2102
|
tag?: 'feature' | 'bug' | 'discussion' | 'build' | 'project-home-builder' | 'bilko-host-publisher';
|
|
2055
2103
|
agentType?: string;
|
|
2104
|
+
/** Per-Epic model/effort overrides (New Session card); omitted = the persona's own. */
|
|
2105
|
+
model?: string;
|
|
2106
|
+
effort?: string;
|
|
2056
2107
|
source?: {
|
|
2057
2108
|
producer: 'new-epic-ui' | 'scheduler-dispatch';
|
|
2058
2109
|
prdSlug?: string;
|
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-a2MVk8qh.js";import{P as te}from"./Panel-RMz3Acpu.js";import{L as ne}from"./ListDetail-D4bxU_-2.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-a2MVk8qh.js";import{P as V}from"./Panel-RMz3Acpu.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{ah as e}from"./index-a2MVk8qh.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 +0,0 @@
|
|
|
1
|
-
import{ah as e}from"./index-a2MVk8qh.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-BI1YtCbB.js","./index-a2MVk8qh.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-a2MVk8qh.js";import{P as V}from"./Panel-RMz3Acpu.js";import{P as z}from"./ProvenanceBadge-CO-DZN38.js";import{e as Z}from"./Library-DrGdaz9N.js";import{p as G}from"./skillFrontmatter-Dif5JIg7.js";import{_ as ee}from"./monaco-editor-BW5C4Iv1.js";import{L as te}from"./ListDetail-D4bxU_-2.js";import{M as ne}from"./MarkdownEditor-H1ytN4Tk.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-BI1YtCbB.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-a2MVk8qh.js";import{a as E,C as B,c as L,d as S,b as I}from"./Library-DrGdaz9N.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};
|