claude-code-session-manager 0.57.1 → 0.59.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/README.md +2 -2
- package/dist/assets/{TiptapBody-CJDxVF7X.js → TiptapBody-PUx4oZTh.js} +1 -1
- package/dist/assets/index-BPnfPdLW.js +3222 -0
- package/dist/assets/{index-WUc_GHMf.css → index-CPMP2XZ_.css} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -2
- package/plugins/session-manager-dev/skills/develop/SKILL.md +7 -6
- package/plugins/session-manager-dev/skills/develop/standards.md +1 -1
- package/plugins/session-manager-dev/skills/explain-to-me/SKILL.md +1 -1
- package/plugins/session-manager-dev/skills/find-opportunity/SKILL.md +1 -1
- package/plugins/session-manager-dev/skills/ops-sweep/SKILL.md +16 -25
- package/plugins/session-manager-dev/skills/project-status/SKILL.md +5 -5
- package/scripts/lib/watchdogHelpers.cjs +0 -434
- package/scripts/mint-epic.cjs +6 -6
- package/src/main/__tests__/activeIndexMerge.test.cjs +2 -2
- package/src/main/__tests__/agentModelResolve.test.cjs +119 -0
- package/src/main/__tests__/classifyTranscriptLine.test.cjs +128 -17
- package/src/main/__tests__/epicContextDigest.test.cjs +100 -0
- package/src/main/__tests__/epicMint.test.cjs +165 -207
- package/src/main/__tests__/epicValidationHook.test.cjs +291 -0
- package/src/main/__tests__/prdMigration.test.cjs +160 -0
- package/src/main/__tests__/projectPages.test.cjs +151 -0
- package/src/main/__tests__/promptSessionEvents.test.cjs +74 -0
- package/src/main/__tests__/promptSessionSchema.test.cjs +101 -0
- package/src/main/__tests__/promptSessionsCreateEpicHandler.test.cjs +139 -0
- package/src/main/__tests__/rcaReport.test.cjs +188 -0
- package/src/main/__tests__/runVerify.test.cjs +109 -6
- package/src/main/__tests__/scheduler-effective-concurrency.test.cjs +32 -12
- package/src/main/__tests__/scheduler-epic-digest.test.cjs +214 -0
- package/src/main/__tests__/scheduler-heal-refusal.test.cjs +61 -0
- package/src/main/__tests__/scheduler-notify-originating-tab.test.cjs +74 -0
- package/src/main/__tests__/scheduler-writeprd-epic-rollback.test.cjs +5 -5
- package/src/main/__tests__/transcripts-doFlush-array.test.cjs +118 -0
- package/src/main/__tests__/transcripts-paged-reads.test.cjs +233 -0
- package/src/main/__tests__/uniquePrdNumbers.test.cjs +7 -2
- package/src/main/chatRunner.cjs +10 -1
- package/src/main/health.cjs +5 -1
- package/src/main/index.cjs +3 -5
- package/src/main/ipcSchemas.cjs +72 -4
- package/src/main/lib/__tests__/schedulerBatchDepends.test.cjs +130 -0
- package/src/main/lib/agentModelResolve.cjs +97 -0
- package/src/main/lib/auditLog.cjs +2 -2
- package/src/main/lib/classifyTranscriptLine.cjs +131 -48
- package/src/main/lib/epicContextDigest.cjs +78 -0
- package/src/main/lib/epicMint.cjs +86 -164
- package/src/main/lib/epicValidationHook.cjs +192 -0
- package/src/main/lib/prdMigration.cjs +76 -5
- package/src/main/lib/promptSessionSchema.cjs +95 -0
- package/src/main/lib/promptSessionsCreateEpic.cjs +70 -0
- package/src/main/lib/{rcaFeedbackHook.cjs → rcaReport.cjs} +47 -114
- package/src/main/lib/schedulerBatch.cjs +70 -111
- package/src/main/lib/schedulerConfig.cjs +0 -1
- package/src/main/otel.cjs +3 -1
- package/src/main/projectPages.cjs +60 -14
- package/src/main/promptSessionEvents.cjs +16 -1
- package/src/main/runVerify.cjs +17 -2
- package/src/main/scheduler.cjs +302 -68
- package/src/main/templates/project-pages-default-home.html +123 -0
- package/src/main/transcripts.cjs +191 -32
- package/src/main/webRemote.cjs +8 -7
- package/src/preload/api.d.ts +100 -57
- package/src/preload/index.cjs +9 -7
- package/dist/assets/index-DCa3QvAi.js +0 -3227
- package/plugins/session-manager-dev/skills/propose-epic/SKILL.md +0 -68
- package/scripts/propose-epic.cjs +0 -56
- package/src/main/__tests__/rcaFeedbackHook.test.cjs +0 -280
- package/src/main/repoAnalyzer.cjs +0 -346
- package/src/main/search.cjs +0 -332
package/src/preload/api.d.ts
CHANGED
|
@@ -171,10 +171,20 @@ export type TranscriptEventKind =
|
|
|
171
171
|
| 'message'
|
|
172
172
|
| string;
|
|
173
173
|
|
|
174
|
+
export interface TranscriptEventRef {
|
|
175
|
+
filePath: string;
|
|
176
|
+
byteOffset: number;
|
|
177
|
+
byteLength: number;
|
|
178
|
+
}
|
|
179
|
+
|
|
174
180
|
export interface TranscriptEvent {
|
|
175
181
|
kind: TranscriptEventKind;
|
|
176
182
|
data: unknown;
|
|
177
183
|
raw: unknown;
|
|
184
|
+
/** Short, bounded human-scannable preview of `data` — never the source of truth. */
|
|
185
|
+
previewText: string;
|
|
186
|
+
/** Byte range of this event's source line on disk; null when classified with no file context. */
|
|
187
|
+
ref: TranscriptEventRef | null;
|
|
178
188
|
}
|
|
179
189
|
|
|
180
190
|
export interface SubscribeResult {
|
|
@@ -396,7 +406,6 @@ export interface ScheduleConfig {
|
|
|
396
406
|
/** Minutes to wait after the 5h reset before firing pending jobs.
|
|
397
407
|
* Used by 'on-reset'. Ignored by 'when-available' and 'manual'. */
|
|
398
408
|
offsetMinutes: number;
|
|
399
|
-
concurrencyCap: number;
|
|
400
409
|
defaultCwd: string;
|
|
401
410
|
/** Auto-fire policy. Default 'when-available'. */
|
|
402
411
|
firePolicy: ScheduleFirePolicy;
|
|
@@ -547,14 +556,45 @@ export interface SchedulePollHealth {
|
|
|
547
556
|
lastFailureKind: string | null;
|
|
548
557
|
}
|
|
549
558
|
|
|
559
|
+
/** One `pending` job held by an unsatisfied dependency, and which dep. */
|
|
560
|
+
export interface ScheduleJobHold {
|
|
561
|
+
slug: string;
|
|
562
|
+
dep: string;
|
|
563
|
+
depStatus: string;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/** Outcome of the scheduler's last tick — why the batch was (or wasn't) fired.
|
|
567
|
+
* Every field is computed by tickQueue; nothing here is derived in the UI. */
|
|
568
|
+
export interface ScheduleLastTick {
|
|
569
|
+
fired: boolean;
|
|
570
|
+
reason: 'held' | 'slots-exhausted' | 'memory-deferred' | 'already-running' | 'drained' | 'paused' | string;
|
|
571
|
+
/** Human-readable one-liner for the binding constraint, when there is one. */
|
|
572
|
+
detail?: string;
|
|
573
|
+
deferredCount?: number;
|
|
574
|
+
runningCount?: number;
|
|
575
|
+
count?: number;
|
|
576
|
+
availableMb?: number;
|
|
577
|
+
threshold?: number;
|
|
578
|
+
holders?: { owner: string; at: string }[];
|
|
579
|
+
holds?: ScheduleJobHold[];
|
|
580
|
+
at: string;
|
|
581
|
+
}
|
|
582
|
+
|
|
550
583
|
export interface ScheduleEffectiveConcurrency {
|
|
584
|
+
/** Total slots in the machine-wide sessionSlots pool — the ONLY concurrency
|
|
585
|
+
* limit. The scheduler no longer carries a private concurrencyCap. */
|
|
551
586
|
cap: number;
|
|
552
|
-
/**
|
|
553
|
-
|
|
587
|
+
/** Slots free right now (pool total minus held, incl. chat runs). */
|
|
588
|
+
free: number;
|
|
589
|
+
/** 'env' when SM_SESSION_SLOTS pins the pool; 'pool' when the persisted
|
|
590
|
+
* Home-tab value governs. */
|
|
591
|
+
source: 'env' | 'pool';
|
|
554
592
|
}
|
|
555
593
|
|
|
556
594
|
export interface ScheduleStateSnapshot {
|
|
557
595
|
config: ScheduleConfig & { supervisor?: SupervisorConfig };
|
|
596
|
+
/** Why the last tick fired (or didn't). Null before the first tick. */
|
|
597
|
+
lastTick?: ScheduleLastTick | null;
|
|
558
598
|
jobs: ScheduleJob[];
|
|
559
599
|
scheduledFor: string | null;
|
|
560
600
|
lastRunAt: string | null;
|
|
@@ -699,47 +739,6 @@ export interface FilesDuplicateResult { ok: boolean; path?: string; error?: stri
|
|
|
699
739
|
export interface DocEditResult { ok: boolean; after?: string; error?: string }
|
|
700
740
|
export interface DocEditSessionResult { tabId: string; requestId: string; ok: boolean; after?: string; error?: string }
|
|
701
741
|
|
|
702
|
-
export interface SearchFileEntry {
|
|
703
|
-
name: string;
|
|
704
|
-
path: string;
|
|
705
|
-
isDirectory: false;
|
|
706
|
-
isFile: true;
|
|
707
|
-
}
|
|
708
|
-
export interface SearchFilesResult {
|
|
709
|
-
ok: boolean;
|
|
710
|
-
files: SearchFileEntry[];
|
|
711
|
-
error: string | null;
|
|
712
|
-
usedRipgrep: boolean;
|
|
713
|
-
}
|
|
714
|
-
export interface SearchTextMatch {
|
|
715
|
-
path: string;
|
|
716
|
-
line: number;
|
|
717
|
-
column: number;
|
|
718
|
-
text: string;
|
|
719
|
-
}
|
|
720
|
-
export interface SearchTextResult {
|
|
721
|
-
ok: boolean;
|
|
722
|
-
matches: SearchTextMatch[];
|
|
723
|
-
error: string | null;
|
|
724
|
-
usedRipgrep: boolean;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
export interface RepoLanguageStats { files: number; lines: number }
|
|
728
|
-
export interface RepoTopDirectory { path: string; fileCount: number; totalLines: number }
|
|
729
|
-
export interface RepoGitStatusSummary { uncommitted: number; branch: string | null }
|
|
730
|
-
export interface RepoAnalyzeResult {
|
|
731
|
-
ok: true;
|
|
732
|
-
cwd: string;
|
|
733
|
-
totalFiles: number;
|
|
734
|
-
totalLines: number;
|
|
735
|
-
languageBreakdown: Record<string, RepoLanguageStats>;
|
|
736
|
-
topDirectories: RepoTopDirectory[];
|
|
737
|
-
gitStatus: RepoGitStatusSummary;
|
|
738
|
-
truncated: boolean;
|
|
739
|
-
durationMs: number;
|
|
740
|
-
}
|
|
741
|
-
export interface RepoAnalyzeError { ok: false; error: string }
|
|
742
|
-
|
|
743
742
|
export interface WatcherInfo {
|
|
744
743
|
watcherId: string;
|
|
745
744
|
tabId: string;
|
|
@@ -989,17 +988,28 @@ export type ProjectBriefUpdateResult =
|
|
|
989
988
|
| { ok: true; brief: ProjectBrief }
|
|
990
989
|
| { ok: false; error: string };
|
|
991
990
|
|
|
992
|
-
// ────────────────────────────────────────────── Project Pages (PRD 929-932)
|
|
991
|
+
// ────────────────────────────────────────────── Project Pages (PRD 929-932, 969, project-home-hosted-html-spec)
|
|
993
992
|
export interface ProjectPagesOutput {
|
|
994
993
|
home: string;
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
994
|
+
/** Absent when `isDefault` is true — the shipped default only covers the home lens. */
|
|
995
|
+
marketing?: string;
|
|
996
|
+
/** Absent when `isDefault` is true — the shipped default only covers the home lens. */
|
|
997
|
+
feature?: string;
|
|
998
|
+
/** Absent when `isDefault` is true — the shipped default only covers the home lens. */
|
|
999
|
+
architecture?: string;
|
|
1000
|
+
/** Absent for output generated before the 'brief' lens existed (PRD 969), or
|
|
1001
|
+
* when `isDefault` is true — a project must regenerate to pick it up. */
|
|
1002
|
+
brief?: string;
|
|
1003
|
+
/** null for the shipped default (never generated). */
|
|
1004
|
+
generatedAt: string | null;
|
|
1005
|
+
/** True when `home` is the build-time shipped default, not this project's own
|
|
1006
|
+
* generated output — the renderer must label provenance rather than infer it. */
|
|
1007
|
+
isDefault: boolean;
|
|
999
1008
|
}
|
|
1000
1009
|
|
|
1001
1010
|
export interface ProjectPagesGetResult {
|
|
1002
|
-
/** null
|
|
1011
|
+
/** Never null in practice — a project with no generated output still gets the
|
|
1012
|
+
* shipped default (isDefault: true). The type stays nullable defensively. */
|
|
1003
1013
|
output: ProjectPagesOutput | null;
|
|
1004
1014
|
}
|
|
1005
1015
|
|
|
@@ -1398,6 +1408,11 @@ export interface SessionManagerAPI {
|
|
|
1398
1408
|
/** Permanently destroy the sub (genuine tab close). */
|
|
1399
1409
|
closeTab: (tabId: string) => Promise<{ ok: boolean }>;
|
|
1400
1410
|
buffer: (tabId: string) => Promise<TranscriptEvent[]>;
|
|
1411
|
+
/** Paged read over the subscribed transcript's line-offset index — [startLine, endLine] inclusive, 0-based.
|
|
1412
|
+
* Reads only the requested byte range from disk; never materializes the whole file. */
|
|
1413
|
+
page: (tabId: string, startLine: number, endLine: number) => Promise<{ events: (TranscriptEvent & { lineNumber: number })[]; totalLines: number }>;
|
|
1414
|
+
/** Full untruncated single-line read via a classifier byte reference (expand-to-full path). */
|
|
1415
|
+
readRef: (ref: TranscriptEventRef) => Promise<{ ok: boolean; text?: string; error?: string }>;
|
|
1401
1416
|
pathFor: (cwd: string, sessionUuid: string) => Promise<string>;
|
|
1402
1417
|
/** Batched token-usage totals, one map entry per requested sessionId. A
|
|
1403
1418
|
* session with no transcript file yet (or one over the main-process size
|
|
@@ -1521,13 +1536,6 @@ export interface SessionManagerAPI {
|
|
|
1521
1536
|
| { as: 'revealPath'; path: string }
|
|
1522
1537
|
) => Promise<{ ok: boolean; opener?: string; error?: string }>;
|
|
1523
1538
|
};
|
|
1524
|
-
search: {
|
|
1525
|
-
files: (cwd: string, query?: string, opts?: { limit?: number }) => Promise<SearchFilesResult>;
|
|
1526
|
-
text: (cwd: string, query: string, opts?: { limit?: number; caseSensitive?: boolean }) => Promise<SearchTextResult>;
|
|
1527
|
-
};
|
|
1528
|
-
repo: {
|
|
1529
|
-
analyze: (cwd: string) => Promise<RepoAnalyzeResult | RepoAnalyzeError>;
|
|
1530
|
-
};
|
|
1531
1539
|
history: {
|
|
1532
1540
|
aggregate: (req?: HistoryAggregateRequest) => Promise<HistoryAggregateResult>;
|
|
1533
1541
|
scanProjects: () => Promise<SessionScanResult>;
|
|
@@ -1765,6 +1773,12 @@ export interface SessionManagerAPI {
|
|
|
1765
1773
|
* in-memory contribution for the cwd; disk stays main's truth, merged
|
|
1766
1774
|
* inside the same lock epicMint.cjs's ensureEpic serializes through. */
|
|
1767
1775
|
mergeActiveIndex: (payload: PromptSessionsMergeActiveIndexPayload) => Promise<PromptSessionsMergeActiveIndexResult>;
|
|
1776
|
+
/** Mints a brand-new 'proposed' Epic through main's own ensureEpic()
|
|
1777
|
+
* (lib/promptSessionsCreateEpic.cjs) instead of the renderer
|
|
1778
|
+
* hand-constructing the PromptSession record itself. Unused today —
|
|
1779
|
+
* additive step 1 of a two-PRD chain; a later PRD routes
|
|
1780
|
+
* createPromptSession through this. */
|
|
1781
|
+
create: (payload: PromptSessionsCreateEpicPayload) => Promise<PromptSessionsCreateEpicResult>;
|
|
1768
1782
|
};
|
|
1769
1783
|
}
|
|
1770
1784
|
|
|
@@ -1782,6 +1796,35 @@ export interface PromptSessionsMergeActiveIndexResult {
|
|
|
1782
1796
|
events: Record<string, unknown[]>;
|
|
1783
1797
|
}
|
|
1784
1798
|
|
|
1799
|
+
// ─────────────────────────────────── PromptSessions create-epic (main-side ensureEpic)
|
|
1800
|
+
export interface PromptSessionsCreateEpicPayload {
|
|
1801
|
+
cwd: string;
|
|
1802
|
+
goalText: string;
|
|
1803
|
+
tag?: 'feature' | 'bug' | 'discussion' | 'build' | 'project-home-builder' | 'bilko-host-publisher';
|
|
1804
|
+
agentType?: string;
|
|
1805
|
+
source?: {
|
|
1806
|
+
producer: 'new-epic-ui' | 'scheduler-dispatch';
|
|
1807
|
+
prdSlug?: string;
|
|
1808
|
+
runId?: string;
|
|
1809
|
+
sourceTabId?: string;
|
|
1810
|
+
};
|
|
1811
|
+
/** Full first-prompt body + its labeled sections (epicIntake.ts's
|
|
1812
|
+
* composeEpicIntake) — carried alongside goalText so the Epic's first
|
|
1813
|
+
* turn can render a structured AIM briefing card. */
|
|
1814
|
+
openingPrompt?: string;
|
|
1815
|
+
sections?: Array<{
|
|
1816
|
+
kind: 'actor' | 'injection' | 'input' | 'mission' | 'goal' | 'reference';
|
|
1817
|
+
label: string;
|
|
1818
|
+
text: string;
|
|
1819
|
+
source?: string;
|
|
1820
|
+
}>;
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1823
|
+
export interface PromptSessionsCreateEpicResult {
|
|
1824
|
+
epicId: string;
|
|
1825
|
+
session: Record<string, unknown>;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1785
1828
|
// ─────────────────────────────────── PromptSession event-appended broadcast
|
|
1786
1829
|
|
|
1787
1830
|
export interface PromptSessionEventAppendedPayload {
|
package/src/preload/index.cjs
CHANGED
|
@@ -121,6 +121,9 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
121
121
|
unsubscribe: (tabId) => ipcRenderer.invoke('transcript:unsubscribe', { tabId }),
|
|
122
122
|
closeTab: (tabId) => ipcRenderer.invoke('transcript:close', { tabId }),
|
|
123
123
|
buffer: (tabId) => ipcRenderer.invoke('transcript:buffer', { tabId }),
|
|
124
|
+
page: (tabId, startLine, endLine) =>
|
|
125
|
+
ipcRenderer.invoke('transcript:page', { tabId, startLine, endLine }),
|
|
126
|
+
readRef: (ref) => ipcRenderer.invoke('transcript:readRef', ref),
|
|
124
127
|
pathFor: (cwd, sessionUuid) =>
|
|
125
128
|
ipcRenderer.invoke('transcript:path', { cwd, sessionUuid }),
|
|
126
129
|
usageFor: (cwd, sessionIds) =>
|
|
@@ -258,13 +261,6 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
258
261
|
shell: {
|
|
259
262
|
open: (opts) => ipcRenderer.invoke('shell:open', opts),
|
|
260
263
|
},
|
|
261
|
-
search: {
|
|
262
|
-
files: (cwd, query, opts) => ipcRenderer.invoke('search:files', { cwd, query, opts }),
|
|
263
|
-
text: (cwd, query, opts) => ipcRenderer.invoke('search:text', { cwd, query, opts }),
|
|
264
|
-
},
|
|
265
|
-
repo: {
|
|
266
|
-
analyze: (cwd) => ipcRenderer.invoke('repo:analyze', { cwd }),
|
|
267
|
-
},
|
|
268
264
|
schedule: {
|
|
269
265
|
state: () => ipcRenderer.invoke('schedule:state'),
|
|
270
266
|
sessionSlots: () => ipcRenderer.invoke('schedule:session-slots'),
|
|
@@ -493,5 +489,11 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
493
489
|
* renderer-side read-merge-write. Payload carries only this renderer's
|
|
494
490
|
* own in-memory contribution for the cwd; disk stays main's truth. */
|
|
495
491
|
mergeActiveIndex: (payload) => ipcRenderer.invoke('promptSessions:merge-active-index', payload),
|
|
492
|
+
/** Mints a brand-new 'proposed' Epic through main's own ensureEpic()
|
|
493
|
+
* (lib/promptSessionsCreateEpic.cjs) instead of the renderer
|
|
494
|
+
* hand-constructing the PromptSession record itself. Unused today —
|
|
495
|
+
* additive step 1 of a two-PRD chain; a later PRD routes
|
|
496
|
+
* createPromptSession through this. */
|
|
497
|
+
create: (payload) => ipcRenderer.invoke('promptSessions:create-epic', payload),
|
|
496
498
|
},
|
|
497
499
|
});
|