@jacques-ai/core 0.0.7-alpha.1
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/archive/archive-store.d.ts +166 -0
- package/dist/archive/archive-store.d.ts.map +1 -0
- package/dist/archive/archive-store.js +612 -0
- package/dist/archive/archive-store.js.map +1 -0
- package/dist/archive/bulk-archive.d.ts +63 -0
- package/dist/archive/bulk-archive.d.ts.map +1 -0
- package/dist/archive/bulk-archive.js +315 -0
- package/dist/archive/bulk-archive.js.map +1 -0
- package/dist/archive/filename-utils.d.ts +39 -0
- package/dist/archive/filename-utils.d.ts.map +1 -0
- package/dist/archive/filename-utils.js +78 -0
- package/dist/archive/filename-utils.js.map +1 -0
- package/dist/archive/index.d.ts +21 -0
- package/dist/archive/index.d.ts.map +1 -0
- package/dist/archive/index.js +45 -0
- package/dist/archive/index.js.map +1 -0
- package/dist/archive/manifest-extractor.d.ts +40 -0
- package/dist/archive/manifest-extractor.d.ts.map +1 -0
- package/dist/archive/manifest-extractor.js +456 -0
- package/dist/archive/manifest-extractor.js.map +1 -0
- package/dist/archive/migration.d.ts +59 -0
- package/dist/archive/migration.d.ts.map +1 -0
- package/dist/archive/migration.js +172 -0
- package/dist/archive/migration.js.map +1 -0
- package/dist/archive/plan-cataloger.d.ts +24 -0
- package/dist/archive/plan-cataloger.d.ts.map +1 -0
- package/dist/archive/plan-cataloger.js +100 -0
- package/dist/archive/plan-cataloger.js.map +1 -0
- package/dist/archive/plan-extractor.d.ts +84 -0
- package/dist/archive/plan-extractor.d.ts.map +1 -0
- package/dist/archive/plan-extractor.js +371 -0
- package/dist/archive/plan-extractor.js.map +1 -0
- package/dist/archive/search-indexer.d.ts +50 -0
- package/dist/archive/search-indexer.d.ts.map +1 -0
- package/dist/archive/search-indexer.js +294 -0
- package/dist/archive/search-indexer.js.map +1 -0
- package/dist/archive/subagent-store.d.ts +113 -0
- package/dist/archive/subagent-store.d.ts.map +1 -0
- package/dist/archive/subagent-store.js +173 -0
- package/dist/archive/subagent-store.js.map +1 -0
- package/dist/archive/types.d.ts +236 -0
- package/dist/archive/types.d.ts.map +1 -0
- package/dist/archive/types.js +30 -0
- package/dist/archive/types.js.map +1 -0
- package/dist/branding.d.ts +9 -0
- package/dist/branding.d.ts.map +1 -0
- package/dist/branding.js +50 -0
- package/dist/branding.js.map +1 -0
- package/dist/cache/git-utils.d.ts +36 -0
- package/dist/cache/git-utils.d.ts.map +1 -0
- package/dist/cache/git-utils.js +160 -0
- package/dist/cache/git-utils.js.map +1 -0
- package/dist/cache/hidden-projects.d.ts +19 -0
- package/dist/cache/hidden-projects.d.ts.map +1 -0
- package/dist/cache/hidden-projects.js +48 -0
- package/dist/cache/hidden-projects.js.map +1 -0
- package/dist/cache/index.d.ts +15 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +20 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/metadata-extractor.d.ts +62 -0
- package/dist/cache/metadata-extractor.d.ts.map +1 -0
- package/dist/cache/metadata-extractor.js +574 -0
- package/dist/cache/metadata-extractor.js.map +1 -0
- package/dist/cache/mode-detector.d.ts +19 -0
- package/dist/cache/mode-detector.d.ts.map +1 -0
- package/dist/cache/mode-detector.js +161 -0
- package/dist/cache/mode-detector.js.map +1 -0
- package/dist/cache/persistence.d.ts +39 -0
- package/dist/cache/persistence.d.ts.map +1 -0
- package/dist/cache/persistence.js +98 -0
- package/dist/cache/persistence.js.map +1 -0
- package/dist/cache/project-discovery.d.ts +41 -0
- package/dist/cache/project-discovery.d.ts.map +1 -0
- package/dist/cache/project-discovery.js +212 -0
- package/dist/cache/project-discovery.js.map +1 -0
- package/dist/cache/session-index.d.ts +258 -0
- package/dist/cache/session-index.d.ts.map +1 -0
- package/dist/cache/session-index.js +1030 -0
- package/dist/cache/session-index.js.map +1 -0
- package/dist/cache/types.d.ts +159 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +29 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/catalog/bulk-extractor.d.ts +18 -0
- package/dist/catalog/bulk-extractor.d.ts.map +1 -0
- package/dist/catalog/bulk-extractor.js +150 -0
- package/dist/catalog/bulk-extractor.js.map +1 -0
- package/dist/catalog/extractor.d.ts +53 -0
- package/dist/catalog/extractor.d.ts.map +1 -0
- package/dist/catalog/extractor.js +522 -0
- package/dist/catalog/extractor.js.map +1 -0
- package/dist/catalog/index.d.ts +10 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +11 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/catalog/types.d.ts +134 -0
- package/dist/catalog/types.d.ts.map +1 -0
- package/dist/catalog/types.js +8 -0
- package/dist/catalog/types.js.map +1 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +5 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/websocket-client.d.ts +96 -0
- package/dist/client/websocket-client.d.ts.map +1 -0
- package/dist/client/websocket-client.js +222 -0
- package/dist/client/websocket-client.js.map +1 -0
- package/dist/context/index.d.ts +13 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +26 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/indexer.d.ts +73 -0
- package/dist/context/indexer.d.ts.map +1 -0
- package/dist/context/indexer.js +233 -0
- package/dist/context/indexer.js.map +1 -0
- package/dist/context/manager.d.ts +66 -0
- package/dist/context/manager.d.ts.map +1 -0
- package/dist/context/manager.js +310 -0
- package/dist/context/manager.js.map +1 -0
- package/dist/context/types.d.ts +149 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +36 -0
- package/dist/context/types.js.map +1 -0
- package/dist/handoff/catalog.d.ts +54 -0
- package/dist/handoff/catalog.d.ts.map +1 -0
- package/dist/handoff/catalog.js +121 -0
- package/dist/handoff/catalog.js.map +1 -0
- package/dist/handoff/generator.d.ts +107 -0
- package/dist/handoff/generator.d.ts.map +1 -0
- package/dist/handoff/generator.js +603 -0
- package/dist/handoff/generator.js.map +1 -0
- package/dist/handoff/index.d.ts +13 -0
- package/dist/handoff/index.d.ts.map +1 -0
- package/dist/handoff/index.js +12 -0
- package/dist/handoff/index.js.map +1 -0
- package/dist/handoff/llm-generator.d.ts +77 -0
- package/dist/handoff/llm-generator.d.ts.map +1 -0
- package/dist/handoff/llm-generator.js +513 -0
- package/dist/handoff/llm-generator.js.map +1 -0
- package/dist/handoff/prompts.d.ts +18 -0
- package/dist/handoff/prompts.d.ts.map +1 -0
- package/dist/handoff/prompts.js +22 -0
- package/dist/handoff/prompts.js.map +1 -0
- package/dist/handoff/types.d.ts +28 -0
- package/dist/handoff/types.d.ts.map +1 -0
- package/dist/handoff/types.js +7 -0
- package/dist/handoff/types.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +132 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/claude-operations.d.ts +111 -0
- package/dist/logging/claude-operations.d.ts.map +1 -0
- package/dist/logging/claude-operations.js +132 -0
- package/dist/logging/claude-operations.js.map +1 -0
- package/dist/logging/error-utils.d.ts +18 -0
- package/dist/logging/error-utils.d.ts.map +1 -0
- package/dist/logging/error-utils.js +37 -0
- package/dist/logging/error-utils.js.map +1 -0
- package/dist/logging/index.d.ts +11 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +10 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.d.ts +25 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +39 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/notifications/constants.d.ts +16 -0
- package/dist/notifications/constants.d.ts.map +1 -0
- package/dist/notifications/constants.js +49 -0
- package/dist/notifications/constants.js.map +1 -0
- package/dist/notifications/index.d.ts +9 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +8 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/types.d.ts +28 -0
- package/dist/notifications/types.d.ts.map +1 -0
- package/dist/notifications/types.js +7 -0
- package/dist/notifications/types.js.map +1 -0
- package/dist/notifications/utils.d.ts +20 -0
- package/dist/notifications/utils.d.ts.map +1 -0
- package/dist/notifications/utils.js +37 -0
- package/dist/notifications/utils.js.map +1 -0
- package/dist/plan/index.d.ts +12 -0
- package/dist/plan/index.d.ts.map +1 -0
- package/dist/plan/index.js +15 -0
- package/dist/plan/index.js.map +1 -0
- package/dist/plan/plan-parser.d.ts +33 -0
- package/dist/plan/plan-parser.d.ts.map +1 -0
- package/dist/plan/plan-parser.js +189 -0
- package/dist/plan/plan-parser.js.map +1 -0
- package/dist/plan/progress-computer.d.ts +34 -0
- package/dist/plan/progress-computer.d.ts.map +1 -0
- package/dist/plan/progress-computer.js +211 -0
- package/dist/plan/progress-computer.js.map +1 -0
- package/dist/plan/progress-matcher.d.ts +34 -0
- package/dist/plan/progress-matcher.d.ts.map +1 -0
- package/dist/plan/progress-matcher.js +297 -0
- package/dist/plan/progress-matcher.js.map +1 -0
- package/dist/plan/task-extractor.d.ts +30 -0
- package/dist/plan/task-extractor.d.ts.map +1 -0
- package/dist/plan/task-extractor.js +435 -0
- package/dist/plan/task-extractor.js.map +1 -0
- package/dist/plan/types.d.ts +131 -0
- package/dist/plan/types.d.ts.map +1 -0
- package/dist/plan/types.js +8 -0
- package/dist/plan/types.js.map +1 -0
- package/dist/project/aggregator.d.ts +43 -0
- package/dist/project/aggregator.d.ts.map +1 -0
- package/dist/project/aggregator.js +218 -0
- package/dist/project/aggregator.js.map +1 -0
- package/dist/project/index.d.ts +9 -0
- package/dist/project/index.d.ts.map +1 -0
- package/dist/project/index.js +9 -0
- package/dist/project/index.js.map +1 -0
- package/dist/project/types.d.ts +65 -0
- package/dist/project/types.d.ts.map +1 -0
- package/dist/project/types.js +27 -0
- package/dist/project/types.js.map +1 -0
- package/dist/session/detector.d.ts +113 -0
- package/dist/session/detector.d.ts.map +1 -0
- package/dist/session/detector.js +333 -0
- package/dist/session/detector.js.map +1 -0
- package/dist/session/filters.d.ts +32 -0
- package/dist/session/filters.d.ts.map +1 -0
- package/dist/session/filters.js +100 -0
- package/dist/session/filters.js.map +1 -0
- package/dist/session/format-title.d.ts +16 -0
- package/dist/session/format-title.d.ts.map +1 -0
- package/dist/session/format-title.js +54 -0
- package/dist/session/format-title.js.map +1 -0
- package/dist/session/index.d.ts +16 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +10 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/parser.d.ts +264 -0
- package/dist/session/parser.d.ts.map +1 -0
- package/dist/session/parser.js +588 -0
- package/dist/session/parser.js.map +1 -0
- package/dist/session/token-estimator.d.ts +32 -0
- package/dist/session/token-estimator.d.ts.map +1 -0
- package/dist/session/token-estimator.js +139 -0
- package/dist/session/token-estimator.js.map +1 -0
- package/dist/session/transformer.d.ts +126 -0
- package/dist/session/transformer.d.ts.map +1 -0
- package/dist/session/transformer.js +158 -0
- package/dist/session/transformer.js.map +1 -0
- package/dist/setup/hooks-config.d.ts +35 -0
- package/dist/setup/hooks-config.d.ts.map +1 -0
- package/dist/setup/hooks-config.js +107 -0
- package/dist/setup/hooks-config.js.map +1 -0
- package/dist/setup/hooks-symlink.d.ts +17 -0
- package/dist/setup/hooks-symlink.d.ts.map +1 -0
- package/dist/setup/hooks-symlink.js +89 -0
- package/dist/setup/hooks-symlink.js.map +1 -0
- package/dist/setup/index.d.ts +13 -0
- package/dist/setup/index.d.ts.map +1 -0
- package/dist/setup/index.js +12 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/prerequisites.d.ts +11 -0
- package/dist/setup/prerequisites.d.ts.map +1 -0
- package/dist/setup/prerequisites.js +72 -0
- package/dist/setup/prerequisites.js.map +1 -0
- package/dist/setup/settings-merge.d.ts +33 -0
- package/dist/setup/settings-merge.d.ts.map +1 -0
- package/dist/setup/settings-merge.js +131 -0
- package/dist/setup/settings-merge.js.map +1 -0
- package/dist/setup/skills-install.d.ts +17 -0
- package/dist/setup/skills-install.d.ts.map +1 -0
- package/dist/setup/skills-install.js +60 -0
- package/dist/setup/skills-install.js.map +1 -0
- package/dist/setup/types.d.ts +39 -0
- package/dist/setup/types.d.ts.map +1 -0
- package/dist/setup/types.js +7 -0
- package/dist/setup/types.js.map +1 -0
- package/dist/setup/verification.d.ts +9 -0
- package/dist/setup/verification.d.ts.map +1 -0
- package/dist/setup/verification.js +91 -0
- package/dist/setup/verification.js.map +1 -0
- package/dist/shortcuts/index.d.ts +8 -0
- package/dist/shortcuts/index.d.ts.map +1 -0
- package/dist/shortcuts/index.js +6 -0
- package/dist/shortcuts/index.js.map +1 -0
- package/dist/shortcuts/key-utils.d.ts +54 -0
- package/dist/shortcuts/key-utils.d.ts.map +1 -0
- package/dist/shortcuts/key-utils.js +129 -0
- package/dist/shortcuts/key-utils.js.map +1 -0
- package/dist/shortcuts/shortcut-registry.d.ts +37 -0
- package/dist/shortcuts/shortcut-registry.d.ts.map +1 -0
- package/dist/shortcuts/shortcut-registry.js +322 -0
- package/dist/shortcuts/shortcut-registry.js.map +1 -0
- package/dist/sources/config.d.ts +91 -0
- package/dist/sources/config.d.ts.map +1 -0
- package/dist/sources/config.js +229 -0
- package/dist/sources/config.js.map +1 -0
- package/dist/sources/googledocs.d.ts +43 -0
- package/dist/sources/googledocs.d.ts.map +1 -0
- package/dist/sources/googledocs.js +298 -0
- package/dist/sources/googledocs.js.map +1 -0
- package/dist/sources/index.d.ts +14 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +19 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/notion.d.ts +35 -0
- package/dist/sources/notion.d.ts.map +1 -0
- package/dist/sources/notion.js +352 -0
- package/dist/sources/notion.js.map +1 -0
- package/dist/sources/obsidian.d.ts +38 -0
- package/dist/sources/obsidian.d.ts.map +1 -0
- package/dist/sources/obsidian.js +228 -0
- package/dist/sources/obsidian.js.map +1 -0
- package/dist/sources/types.d.ts +133 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +19 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/writer.d.ts +86 -0
- package/dist/storage/writer.d.ts.map +1 -0
- package/dist/storage/writer.js +137 -0
- package/dist/storage/writer.js.map +1 -0
- package/dist/types.d.ts +203 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/claude-token.d.ts +49 -0
- package/dist/utils/claude-token.d.ts.map +1 -0
- package/dist/utils/claude-token.js +169 -0
- package/dist/utils/claude-token.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +13 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/settings.d.ts +100 -0
- package/dist/utils/settings.d.ts.map +1 -0
- package/dist/utils/settings.js +206 -0
- package/dist/utils/settings.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Aggregator
|
|
3
|
+
*
|
|
4
|
+
* Aggregates data from multiple sources to build project statistics
|
|
5
|
+
* and session lists for the dashboard.
|
|
6
|
+
*
|
|
7
|
+
* Sources:
|
|
8
|
+
* - Live sessions (from WebSocket/Session registry)
|
|
9
|
+
* - Saved sessions (.jacques/index.json)
|
|
10
|
+
* - Archived sessions (~/.jacques/archive/manifests/)
|
|
11
|
+
* - Handoffs (.jacques/handoffs/)
|
|
12
|
+
* - Plans (.jacques/index.json plans array)
|
|
13
|
+
*/
|
|
14
|
+
import { promises as fs } from "fs";
|
|
15
|
+
import { basename, join } from "path";
|
|
16
|
+
import { getDefaultStatistics } from "./types.js";
|
|
17
|
+
import { readProjectIndex } from "../context/indexer.js";
|
|
18
|
+
import { listManifestsByProject, } from "../archive/archive-store.js";
|
|
19
|
+
import { getHandoffsDir } from "../handoff/catalog.js";
|
|
20
|
+
/**
|
|
21
|
+
* Count handoff files in a project
|
|
22
|
+
*/
|
|
23
|
+
async function countHandoffs(projectPath) {
|
|
24
|
+
try {
|
|
25
|
+
const handoffsDir = getHandoffsDir(projectPath);
|
|
26
|
+
const files = await fs.readdir(handoffsDir);
|
|
27
|
+
return files.filter((f) => f.endsWith("-handoff.md")).length;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the project slug (basename) from a path
|
|
35
|
+
*/
|
|
36
|
+
function getProjectSlug(projectPath) {
|
|
37
|
+
return basename(projectPath);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Aggregate statistics for a project
|
|
41
|
+
*
|
|
42
|
+
* @param projectPath - Full path to the project directory
|
|
43
|
+
* @param liveSessions - Currently active sessions from the server
|
|
44
|
+
*/
|
|
45
|
+
export async function aggregateProjectStatistics(projectPath, liveSessions) {
|
|
46
|
+
const stats = getDefaultStatistics();
|
|
47
|
+
const projectSlug = getProjectSlug(projectPath);
|
|
48
|
+
// 1. Count live sessions for this project
|
|
49
|
+
const projectLiveSessions = liveSessions.filter((s) => s.project === projectSlug || s.cwd === projectPath);
|
|
50
|
+
stats.activeSessions = projectLiveSessions.length;
|
|
51
|
+
// Aggregate live session metrics
|
|
52
|
+
for (const session of projectLiveSessions) {
|
|
53
|
+
if (session.context_metrics) {
|
|
54
|
+
stats.totalInputTokens += session.context_metrics.total_input_tokens || 0;
|
|
55
|
+
stats.totalOutputTokens +=
|
|
56
|
+
session.context_metrics.total_output_tokens || 0;
|
|
57
|
+
}
|
|
58
|
+
if (session.model?.display_name) {
|
|
59
|
+
const modelName = session.model.display_name;
|
|
60
|
+
stats.modelUsage[modelName] = (stats.modelUsage[modelName] || 0) + 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// 2. Load saved sessions from .jacques/index.json
|
|
64
|
+
try {
|
|
65
|
+
const index = await readProjectIndex(projectPath);
|
|
66
|
+
stats.savedSessions = index.sessions.length;
|
|
67
|
+
stats.totalPlans = index.plans.length;
|
|
68
|
+
// Aggregate saved session metrics
|
|
69
|
+
for (const session of index.sessions) {
|
|
70
|
+
stats.totalDurationMinutes += session.durationMinutes || 0;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// No local index yet
|
|
75
|
+
}
|
|
76
|
+
// 3. Load archived manifests for this project
|
|
77
|
+
try {
|
|
78
|
+
const manifestsByProject = await listManifestsByProject();
|
|
79
|
+
const projectManifests = manifestsByProject.get(projectSlug) || [];
|
|
80
|
+
stats.archivedSessions = projectManifests.length;
|
|
81
|
+
// Aggregate archive metrics (avoid double-counting with saved)
|
|
82
|
+
const savedIds = new Set();
|
|
83
|
+
try {
|
|
84
|
+
const index = await readProjectIndex(projectPath);
|
|
85
|
+
for (const s of index.sessions) {
|
|
86
|
+
savedIds.add(s.id);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// No index
|
|
91
|
+
}
|
|
92
|
+
for (const manifest of projectManifests) {
|
|
93
|
+
// Only add duration if not already counted from saved
|
|
94
|
+
if (!savedIds.has(manifest.id)) {
|
|
95
|
+
stats.totalDurationMinutes += manifest.durationMinutes || 0;
|
|
96
|
+
}
|
|
97
|
+
// Count tool calls and messages (only from archive, saved doesn't have this)
|
|
98
|
+
stats.totalAgentCalls += manifest.subagents?.count || 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// No archive
|
|
103
|
+
}
|
|
104
|
+
// 4. Count handoffs
|
|
105
|
+
stats.totalHandoffs = await countHandoffs(projectPath);
|
|
106
|
+
// 5. Calculate total sessions (deduplicated)
|
|
107
|
+
// Live + saved + archived (with overlap consideration)
|
|
108
|
+
stats.totalSessions =
|
|
109
|
+
stats.activeSessions + stats.savedSessions + stats.archivedSessions;
|
|
110
|
+
return stats;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Build a unified list of sessions for display
|
|
114
|
+
*
|
|
115
|
+
* Combines live, saved, and archived sessions, sorted by date (newest first).
|
|
116
|
+
* Deduplicates sessions that appear in multiple sources.
|
|
117
|
+
*
|
|
118
|
+
* @param projectPath - Full path to the project directory
|
|
119
|
+
* @param liveSessions - Currently active sessions from the server
|
|
120
|
+
* @param focusedSessionId - ID of the currently focused session
|
|
121
|
+
*/
|
|
122
|
+
export async function buildProjectSessionList(projectPath, liveSessions, focusedSessionId) {
|
|
123
|
+
const items = [];
|
|
124
|
+
const seenIds = new Set();
|
|
125
|
+
const projectSlug = getProjectSlug(projectPath);
|
|
126
|
+
// 1. Add live sessions first (highest priority)
|
|
127
|
+
const projectLiveSessions = liveSessions.filter((s) => s.project === projectSlug || s.cwd === projectPath);
|
|
128
|
+
for (const session of projectLiveSessions) {
|
|
129
|
+
seenIds.add(session.session_id);
|
|
130
|
+
items.push({
|
|
131
|
+
id: session.session_id,
|
|
132
|
+
title: session.session_title || "Untitled Session",
|
|
133
|
+
source: "live",
|
|
134
|
+
date: new Date(session.registered_at).toISOString(),
|
|
135
|
+
durationMinutes: Math.round((Date.now() - session.registered_at) / 60000),
|
|
136
|
+
model: session.model?.display_name,
|
|
137
|
+
contextPercent: session.context_metrics?.used_percentage,
|
|
138
|
+
isActive: session.status === "active" || session.status === "working",
|
|
139
|
+
isFocused: session.session_id === focusedSessionId,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// 2. Add saved sessions from .jacques/index.json
|
|
143
|
+
try {
|
|
144
|
+
const index = await readProjectIndex(projectPath);
|
|
145
|
+
for (const session of index.sessions) {
|
|
146
|
+
if (seenIds.has(session.id))
|
|
147
|
+
continue;
|
|
148
|
+
seenIds.add(session.id);
|
|
149
|
+
items.push({
|
|
150
|
+
id: session.id,
|
|
151
|
+
title: session.title,
|
|
152
|
+
source: "saved",
|
|
153
|
+
date: session.endedAt || session.savedAt,
|
|
154
|
+
durationMinutes: session.durationMinutes,
|
|
155
|
+
model: undefined, // Not stored in saved sessions
|
|
156
|
+
contextPercent: undefined,
|
|
157
|
+
isActive: false,
|
|
158
|
+
isFocused: false,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// No local index
|
|
164
|
+
}
|
|
165
|
+
// 3. Add archived sessions (only if not already in saved)
|
|
166
|
+
try {
|
|
167
|
+
const manifestsByProject = await listManifestsByProject();
|
|
168
|
+
const projectManifests = manifestsByProject.get(projectSlug) || [];
|
|
169
|
+
for (const manifest of projectManifests) {
|
|
170
|
+
if (seenIds.has(manifest.id))
|
|
171
|
+
continue;
|
|
172
|
+
seenIds.add(manifest.id);
|
|
173
|
+
items.push({
|
|
174
|
+
id: manifest.id,
|
|
175
|
+
title: manifest.title,
|
|
176
|
+
source: "archived",
|
|
177
|
+
date: manifest.endedAt || manifest.archivedAt,
|
|
178
|
+
durationMinutes: manifest.durationMinutes,
|
|
179
|
+
model: undefined, // Could extract from technologies
|
|
180
|
+
contextPercent: undefined,
|
|
181
|
+
isActive: false,
|
|
182
|
+
isFocused: false,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// No archive
|
|
188
|
+
}
|
|
189
|
+
// Sort by date (newest first)
|
|
190
|
+
items.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
|
191
|
+
return items;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get plans for a project
|
|
195
|
+
*/
|
|
196
|
+
export async function getProjectPlans(projectPath) {
|
|
197
|
+
try {
|
|
198
|
+
const index = await readProjectIndex(projectPath);
|
|
199
|
+
// Sort by updatedAt (newest first)
|
|
200
|
+
return [...index.plans].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Read the content of a local plan file from .jacques/
|
|
208
|
+
*/
|
|
209
|
+
export async function readLocalPlanContent(projectPath, plan) {
|
|
210
|
+
try {
|
|
211
|
+
const planPath = join(projectPath, ".jacques", plan.path);
|
|
212
|
+
return await fs.readFile(planPath, "utf-8");
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=aggregator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregator.js","sourceRoot":"","sources":["../../src/project/aggregator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Module
|
|
3
|
+
*
|
|
4
|
+
* Data aggregation for the project dashboard view.
|
|
5
|
+
*/
|
|
6
|
+
export type { ProjectStatistics, ProjectSessionItem } from "./types.js";
|
|
7
|
+
export { getDefaultStatistics } from "./types.js";
|
|
8
|
+
export { aggregateProjectStatistics, buildProjectSessionList, getProjectPlans, readLocalPlanContent, } from "./aggregator.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/project/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,eAAe,EACf,oBAAoB,GACrB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Module
|
|
3
|
+
*
|
|
4
|
+
* Data aggregation for the project dashboard view.
|
|
5
|
+
*/
|
|
6
|
+
export { getDefaultStatistics } from "./types.js";
|
|
7
|
+
// Aggregator
|
|
8
|
+
export { aggregateProjectStatistics, buildProjectSessionList, getProjectPlans, readLocalPlanContent, } from "./aggregator.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/project/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,aAAa;AACb,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,eAAe,EACf,oBAAoB,GACrB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Dashboard Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the project dashboard view.
|
|
5
|
+
* Aggregates data from live sessions, saved sessions, and archive.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Aggregated statistics for a project
|
|
9
|
+
*/
|
|
10
|
+
export interface ProjectStatistics {
|
|
11
|
+
/** Total sessions (live + saved + archived) */
|
|
12
|
+
totalSessions: number;
|
|
13
|
+
/** Currently active/live sessions */
|
|
14
|
+
activeSessions: number;
|
|
15
|
+
/** Saved sessions in .jacques/ */
|
|
16
|
+
savedSessions: number;
|
|
17
|
+
/** Archived sessions in global archive */
|
|
18
|
+
archivedSessions: number;
|
|
19
|
+
/** Total input tokens used across all sessions */
|
|
20
|
+
totalInputTokens: number;
|
|
21
|
+
/** Total output tokens used across all sessions */
|
|
22
|
+
totalOutputTokens: number;
|
|
23
|
+
/** Total agent/subagent calls */
|
|
24
|
+
totalAgentCalls: number;
|
|
25
|
+
/** Total web searches performed */
|
|
26
|
+
totalWebSearches: number;
|
|
27
|
+
/** Total auto-compacts that occurred */
|
|
28
|
+
totalAutoCompacts: number;
|
|
29
|
+
/** Total handoff documents created */
|
|
30
|
+
totalHandoffs: number;
|
|
31
|
+
/** Total plans created */
|
|
32
|
+
totalPlans: number;
|
|
33
|
+
/** Total duration across all sessions (minutes) */
|
|
34
|
+
totalDurationMinutes: number;
|
|
35
|
+
/** Model usage: model name -> session count */
|
|
36
|
+
modelUsage: Record<string, number>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A session item for display in the dashboard
|
|
40
|
+
*/
|
|
41
|
+
export interface ProjectSessionItem {
|
|
42
|
+
/** Session ID */
|
|
43
|
+
id: string;
|
|
44
|
+
/** Session title */
|
|
45
|
+
title: string;
|
|
46
|
+
/** Source: live (active), saved (in .jacques), or archived (global) */
|
|
47
|
+
source: "live" | "saved" | "archived";
|
|
48
|
+
/** Display date (ISO string) */
|
|
49
|
+
date: string;
|
|
50
|
+
/** Duration in minutes */
|
|
51
|
+
durationMinutes: number;
|
|
52
|
+
/** Model used (if known) */
|
|
53
|
+
model?: string;
|
|
54
|
+
/** Context percentage (only for live sessions) */
|
|
55
|
+
contextPercent?: number;
|
|
56
|
+
/** Is this session currently active? */
|
|
57
|
+
isActive: boolean;
|
|
58
|
+
/** Is this the focused session? */
|
|
59
|
+
isFocused: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Default empty statistics
|
|
63
|
+
*/
|
|
64
|
+
export declare function getDefaultStatistics(): ProjectStatistics;
|
|
65
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/project/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,CAAC;IAEzB,kDAAkD;IAClD,gBAAgB,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAE1B,iCAAiC;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,iBAAiB,EAAE,MAAM,CAAC;IAE1B,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAC;IAEnB,mDAAmD;IACnD,oBAAoB,EAAE,MAAM,CAAC;IAE7B,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iBAAiB;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACtC,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,QAAQ,EAAE,OAAO,CAAC;IAClB,mCAAmC;IACnC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,CAgBxD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project Dashboard Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the project dashboard view.
|
|
5
|
+
* Aggregates data from live sessions, saved sessions, and archive.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Default empty statistics
|
|
9
|
+
*/
|
|
10
|
+
export function getDefaultStatistics() {
|
|
11
|
+
return {
|
|
12
|
+
totalSessions: 0,
|
|
13
|
+
activeSessions: 0,
|
|
14
|
+
savedSessions: 0,
|
|
15
|
+
archivedSessions: 0,
|
|
16
|
+
totalInputTokens: 0,
|
|
17
|
+
totalOutputTokens: 0,
|
|
18
|
+
totalAgentCalls: 0,
|
|
19
|
+
totalWebSearches: 0,
|
|
20
|
+
totalAutoCompacts: 0,
|
|
21
|
+
totalHandoffs: 0,
|
|
22
|
+
totalPlans: 0,
|
|
23
|
+
totalDurationMinutes: 0,
|
|
24
|
+
modelUsage: {},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/project/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+DH;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,CAAC;QACjB,aAAa,EAAE,CAAC;QAChB,gBAAgB,EAAE,CAAC;QACnB,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,eAAe,EAAE,CAAC;QAClB,gBAAgB,EAAE,CAAC;QACnB,iBAAiB,EAAE,CAAC;QACpB,aAAa,EAAE,CAAC;QAChB,UAAU,EAAE,CAAC;QACb,oBAAoB,EAAE,CAAC;QACvB,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects the current Claude Code session JSONL file.
|
|
5
|
+
* Claude Code stores session history at:
|
|
6
|
+
* ~/.claude/projects/[encoded-directory-path]/[session-uuid].jsonl
|
|
7
|
+
*
|
|
8
|
+
* Encoding rule: Replace '/' with '-' (e.g., /Users/gole/Desktop/project → -Users-gole-Desktop-project)
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT: Claude Code encodes BOTH '/' AND '_' as '-', making naive
|
|
11
|
+
* string-based reversal impossible. Use decodeProjectPath() which reads
|
|
12
|
+
* the authoritative originalPath from sessions-index.json.
|
|
13
|
+
*/
|
|
14
|
+
export interface SessionFile {
|
|
15
|
+
/** Full path to the JSONL file */
|
|
16
|
+
filePath: string;
|
|
17
|
+
/** Session UUID (extracted from filename) */
|
|
18
|
+
sessionId: string;
|
|
19
|
+
/** Last modification time */
|
|
20
|
+
modifiedAt: Date;
|
|
21
|
+
/** File size in bytes */
|
|
22
|
+
sizeBytes: number;
|
|
23
|
+
}
|
|
24
|
+
export interface DetectorOptions {
|
|
25
|
+
/** Working directory to detect session for (defaults to process.cwd()) */
|
|
26
|
+
cwd?: string;
|
|
27
|
+
/** Path to Claude projects directory (defaults to ~/.claude/projects) */
|
|
28
|
+
claudeProjectsDir?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the Claude projects directory path.
|
|
32
|
+
*
|
|
33
|
+
* Resolution order:
|
|
34
|
+
* 1. CLAUDE_CONFIG_DIR env var + /projects
|
|
35
|
+
* 2. rootPath from ~/.jacques/config.json + /projects
|
|
36
|
+
* 3. Default: ~/.claude/projects
|
|
37
|
+
*
|
|
38
|
+
* Works cross-platform: macOS, Linux, and Windows.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getClaudeProjectsDir(): string;
|
|
41
|
+
/**
|
|
42
|
+
* Get the Claude settings.json path.
|
|
43
|
+
* Uses the same resolution logic as getClaudeProjectsDir().
|
|
44
|
+
*/
|
|
45
|
+
export declare function getClaudeSettingsPath(): string;
|
|
46
|
+
/**
|
|
47
|
+
* Encode a directory path to Claude's format.
|
|
48
|
+
* Replaces path separators with '-' (keeps leading dash).
|
|
49
|
+
* Example: /Users/gole/Desktop/project -> -Users-gole-Desktop-project
|
|
50
|
+
*
|
|
51
|
+
* Cross-platform: handles both '/' (Unix) and '\' (Windows) separators.
|
|
52
|
+
* On Windows, also strips the drive letter colon (C:\foo → -C-foo).
|
|
53
|
+
* TODO: verify encoding on actual Windows Claude Code installation
|
|
54
|
+
*/
|
|
55
|
+
export declare function encodeProjectPath(dirPath: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* Naive decode: replace all dashes with slashes.
|
|
58
|
+
* This is WRONG for paths containing dashes or underscores, but serves
|
|
59
|
+
* as a fallback when sessions-index.json is unavailable.
|
|
60
|
+
*/
|
|
61
|
+
export declare function decodeProjectPathNaive(encodedDir: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Decode an encoded project directory name to the real filesystem path.
|
|
64
|
+
*
|
|
65
|
+
* Resolution order:
|
|
66
|
+
* 1. sessions-index.json originalPath (authoritative, written by Claude Code)
|
|
67
|
+
* 2. cwd field from first JSONL entry (reliable, written at session start)
|
|
68
|
+
* 3. Naive decode: replace all dashes with slashes (last resort, often wrong)
|
|
69
|
+
*/
|
|
70
|
+
export declare function decodeProjectPath(encodedDir: string, claudeProjectsDir?: string): Promise<string>;
|
|
71
|
+
/**
|
|
72
|
+
* Detect the current Claude session JSONL file.
|
|
73
|
+
* Returns the most recently modified .jsonl file in the project directory.
|
|
74
|
+
*/
|
|
75
|
+
export declare function detectCurrentSession(options?: DetectorOptions): Promise<SessionFile | null>;
|
|
76
|
+
/**
|
|
77
|
+
* List all session files for a project.
|
|
78
|
+
* Returns sessions sorted by modification time (most recent first).
|
|
79
|
+
*/
|
|
80
|
+
export declare function listProjectSessions(options?: DetectorOptions): Promise<SessionFile[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Get the expected project directory path for a given working directory.
|
|
83
|
+
* Useful for debugging and testing.
|
|
84
|
+
*/
|
|
85
|
+
export declare function getProjectDirPath(cwd: string, claudeProjectsDir?: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* Subagent file info
|
|
88
|
+
*/
|
|
89
|
+
export interface SubagentFile {
|
|
90
|
+
/** Full path to the subagent JSONL file */
|
|
91
|
+
filePath: string;
|
|
92
|
+
/** Agent ID extracted from filename (e.g., "a0323e0") */
|
|
93
|
+
agentId: string;
|
|
94
|
+
/** Last modification time */
|
|
95
|
+
modifiedAt: Date;
|
|
96
|
+
/** File size in bytes */
|
|
97
|
+
sizeBytes: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* List all subagent JSONL files for a given session.
|
|
101
|
+
* Claude Code stores subagent conversations in:
|
|
102
|
+
* {session-id}/subagents/agent-{agentId}.jsonl
|
|
103
|
+
*
|
|
104
|
+
* @param sessionFilePath Path to the main session JSONL file
|
|
105
|
+
* @returns Array of subagent files found
|
|
106
|
+
*/
|
|
107
|
+
export declare function listSubagentFiles(sessionFilePath: string): Promise<SubagentFile[]>;
|
|
108
|
+
/**
|
|
109
|
+
* Find a session file by session ID across all project directories.
|
|
110
|
+
* This is useful when the cwd is incorrect but we know the session ID.
|
|
111
|
+
*/
|
|
112
|
+
export declare function findSessionById(sessionId: string, claudeProjectsDir?: string): Promise<SessionFile | null>;
|
|
113
|
+
//# sourceMappingURL=detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/session/detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,IAAI,CAAC;IACjB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAM7C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMzD;AAiED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAwD7B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,WAAW,EAAE,CAAC,CAuCxB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,iBAAiB,CAAC,EAAE,MAAM,GACzB,MAAM,CAIR;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,UAAU,EAAE,IAAI,CAAC;IACjB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,YAAY,EAAE,CAAC,CA2CzB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAkC7B"}
|