specweave 1.0.259 → 1.0.261

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.
Files changed (70) hide show
  1. package/CLAUDE.md +40 -25
  2. package/bin/specweave.js +11 -0
  3. package/dist/dashboard/assets/index-CDl14O5G.css +1 -0
  4. package/dist/dashboard/assets/index-CmqBqnWd.js +11 -0
  5. package/dist/dashboard/index.html +14 -0
  6. package/dist/src/cli/commands/dashboard.d.ts +18 -0
  7. package/dist/src/cli/commands/dashboard.d.ts.map +1 -0
  8. package/dist/src/cli/commands/dashboard.js +142 -0
  9. package/dist/src/cli/commands/dashboard.js.map +1 -0
  10. package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts +9 -4
  11. package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts.map +1 -1
  12. package/dist/src/core/lazy-loading/llm-plugin-detector.js +9 -4
  13. package/dist/src/core/lazy-loading/llm-plugin-detector.js.map +1 -1
  14. package/dist/src/dashboard/server/command-runner.d.ts +21 -0
  15. package/dist/src/dashboard/server/command-runner.d.ts.map +1 -0
  16. package/dist/src/dashboard/server/command-runner.js +92 -0
  17. package/dist/src/dashboard/server/command-runner.js.map +1 -0
  18. package/dist/src/dashboard/server/dashboard-server.d.ts +33 -0
  19. package/dist/src/dashboard/server/dashboard-server.d.ts.map +1 -0
  20. package/dist/src/dashboard/server/dashboard-server.js +867 -0
  21. package/dist/src/dashboard/server/dashboard-server.js.map +1 -0
  22. package/dist/src/dashboard/server/data/activity-stream.d.ts +27 -0
  23. package/dist/src/dashboard/server/data/activity-stream.d.ts.map +1 -0
  24. package/dist/src/dashboard/server/data/activity-stream.js +142 -0
  25. package/dist/src/dashboard/server/data/activity-stream.js.map +1 -0
  26. package/dist/src/dashboard/server/data/claude-log-parser.d.ts +34 -0
  27. package/dist/src/dashboard/server/data/claude-log-parser.d.ts.map +1 -0
  28. package/dist/src/dashboard/server/data/claude-log-parser.js +218 -0
  29. package/dist/src/dashboard/server/data/claude-log-parser.js.map +1 -0
  30. package/dist/src/dashboard/server/data/cost-aggregator.d.ts +36 -0
  31. package/dist/src/dashboard/server/data/cost-aggregator.d.ts.map +1 -0
  32. package/dist/src/dashboard/server/data/cost-aggregator.js +156 -0
  33. package/dist/src/dashboard/server/data/cost-aggregator.js.map +1 -0
  34. package/dist/src/dashboard/server/data/dashboard-data-aggregator.d.ts +62 -0
  35. package/dist/src/dashboard/server/data/dashboard-data-aggregator.d.ts.map +1 -0
  36. package/dist/src/dashboard/server/data/dashboard-data-aggregator.js +361 -0
  37. package/dist/src/dashboard/server/data/dashboard-data-aggregator.js.map +1 -0
  38. package/dist/src/dashboard/server/data/plugin-scanner.d.ts +35 -0
  39. package/dist/src/dashboard/server/data/plugin-scanner.d.ts.map +1 -0
  40. package/dist/src/dashboard/server/data/plugin-scanner.js +96 -0
  41. package/dist/src/dashboard/server/data/plugin-scanner.js.map +1 -0
  42. package/dist/src/dashboard/server/data/sync-audit-reader.d.ts +38 -0
  43. package/dist/src/dashboard/server/data/sync-audit-reader.d.ts.map +1 -0
  44. package/dist/src/dashboard/server/data/sync-audit-reader.js +94 -0
  45. package/dist/src/dashboard/server/data/sync-audit-reader.js.map +1 -0
  46. package/dist/src/dashboard/server/file-watcher.d.ts +19 -0
  47. package/dist/src/dashboard/server/file-watcher.d.ts.map +1 -0
  48. package/dist/src/dashboard/server/file-watcher.js +104 -0
  49. package/dist/src/dashboard/server/file-watcher.js.map +1 -0
  50. package/dist/src/dashboard/server/router.d.ts +16 -0
  51. package/dist/src/dashboard/server/router.d.ts.map +1 -0
  52. package/dist/src/dashboard/server/router.js +110 -0
  53. package/dist/src/dashboard/server/router.js.map +1 -0
  54. package/dist/src/dashboard/server/sse-manager.d.ts +25 -0
  55. package/dist/src/dashboard/server/sse-manager.d.ts.map +1 -0
  56. package/dist/src/dashboard/server/sse-manager.js +75 -0
  57. package/dist/src/dashboard/server/sse-manager.js.map +1 -0
  58. package/dist/src/dashboard/types.d.ts +194 -0
  59. package/dist/src/dashboard/types.d.ts.map +1 -0
  60. package/dist/src/dashboard/types.js +2 -0
  61. package/dist/src/dashboard/types.js.map +1 -0
  62. package/package.json +12 -2
  63. package/plugins/specweave/hooks/user-prompt-submit.sh +79 -154
  64. package/plugins/specweave/skills/auto/SKILL.md +35 -0
  65. package/plugins/specweave/skills/do/SKILL.md +32 -2
  66. package/plugins/specweave/skills/increment/SKILL.md +1 -1
  67. package/plugins/specweave/skills/increment-planner/SKILL.md +26 -0
  68. package/plugins/specweave/skills/increment-work-router/SKILL.md +37 -9
  69. package/plugins/specweave/skills/plan/SKILL.md +37 -0
  70. package/plugins/specweave/skills/team-lead/SKILL.md +1 -1
@@ -0,0 +1,156 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as readline from 'readline';
4
+ // Pricing per million tokens (as of Feb 2026)
5
+ const PRICING = {
6
+ 'claude-opus-4-6': { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.50 },
7
+ 'claude-sonnet-4-5-20250929': { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.30 },
8
+ 'claude-haiku-4-5-20251001': { input: 0.80, output: 4, cacheWrite: 1.00, cacheRead: 0.08 },
9
+ };
10
+ // Fallback patterns for model detection
11
+ function resolveModel(raw) {
12
+ if (!raw)
13
+ return 'unknown';
14
+ if (raw.includes('opus'))
15
+ return 'claude-opus-4-6';
16
+ if (raw.includes('sonnet'))
17
+ return 'claude-sonnet-4-5-20250929';
18
+ if (raw.includes('haiku'))
19
+ return 'claude-haiku-4-5-20251001';
20
+ return raw;
21
+ }
22
+ function getPricing(model) {
23
+ return PRICING[model] || PRICING[resolveModel(model)] || PRICING['claude-sonnet-4-5-20250929'];
24
+ }
25
+ export class CostAggregator {
26
+ constructor(projectRoot) {
27
+ this.cache = null;
28
+ this.cacheTime = 0;
29
+ this.cacheTTL = 60000; // 60 seconds
30
+ const slug = projectRoot.replace(/^\//, '').replace(/\//g, '-');
31
+ this.logDir = path.join(process.env.HOME || '', '.claude/projects', `-${slug}`);
32
+ }
33
+ async getTokenSummaries(limit = 200) {
34
+ if (this.cache && Date.now() - this.cacheTime < this.cacheTTL) {
35
+ return this.cache;
36
+ }
37
+ const files = this.getSessionFiles();
38
+ const recent = files.slice(-limit);
39
+ const sessions = [];
40
+ const modelBreakdown = {};
41
+ for (const file of recent) {
42
+ try {
43
+ const summary = await this.extractTokensFromSession(file);
44
+ if (summary && summary.inputTokens + summary.outputTokens > 0) {
45
+ sessions.push(summary);
46
+ const model = summary.model || 'unknown';
47
+ if (!modelBreakdown[model])
48
+ modelBreakdown[model] = { cost: 0, tokens: 0, sessions: 0 };
49
+ modelBreakdown[model].cost += summary.cost;
50
+ modelBreakdown[model].tokens += summary.inputTokens + summary.outputTokens;
51
+ modelBreakdown[model].sessions++;
52
+ }
53
+ }
54
+ catch { /* skip corrupted files */ }
55
+ }
56
+ sessions.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
57
+ const totalCost = sessions.reduce((s, x) => s + x.cost, 0);
58
+ const totalSavings = sessions.reduce((s, x) => s + x.savings, 0);
59
+ const totalTokens = sessions.reduce((s, x) => s + x.inputTokens + x.outputTokens, 0);
60
+ const result = {
61
+ totalCost,
62
+ totalSavings,
63
+ totalTokens,
64
+ sessionCount: sessions.length,
65
+ sessions,
66
+ modelBreakdown,
67
+ isMaxPlan: sessions.length > 0 && totalCost === 0,
68
+ };
69
+ this.cache = result;
70
+ this.cacheTime = Date.now();
71
+ return result;
72
+ }
73
+ async extractTokensFromSession(filePath) {
74
+ const sessionId = path.basename(filePath, '.jsonl');
75
+ const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });
76
+ const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
77
+ let inputTokens = 0;
78
+ let outputTokens = 0;
79
+ let cacheWriteTokens = 0;
80
+ let cacheReadTokens = 0;
81
+ let model = '';
82
+ let startTime = '';
83
+ let endTime = '';
84
+ for await (const line of rl) {
85
+ if (!line.trim())
86
+ continue;
87
+ try {
88
+ const entry = JSON.parse(line);
89
+ const ts = entry.timestamp || '';
90
+ if (!startTime && ts)
91
+ startTime = ts;
92
+ if (ts)
93
+ endTime = ts;
94
+ // Extract model from assistant messages
95
+ if (entry.type === 'assistant' && entry.message?.model && !model) {
96
+ model = entry.message.model;
97
+ }
98
+ // Extract token usage
99
+ const usage = entry.message?.usage || entry.usage;
100
+ if (usage) {
101
+ inputTokens += usage.input_tokens || 0;
102
+ outputTokens += usage.output_tokens || 0;
103
+ cacheWriteTokens += usage.cache_creation_input_tokens || 0;
104
+ cacheReadTokens += usage.cache_read_input_tokens || 0;
105
+ }
106
+ }
107
+ catch { /* skip malformed lines */ }
108
+ }
109
+ if (!startTime || (inputTokens + outputTokens === 0))
110
+ return null;
111
+ const resolvedModel = resolveModel(model);
112
+ const pricing = getPricing(resolvedModel);
113
+ const cost = ((inputTokens * pricing.input) +
114
+ (outputTokens * pricing.output) +
115
+ (cacheWriteTokens * pricing.cacheWrite) +
116
+ (cacheReadTokens * pricing.cacheRead)) / 1000000;
117
+ // Savings from cache hits (difference between full input price and cache read price)
118
+ const savings = (cacheReadTokens * (pricing.input - pricing.cacheRead)) / 1000000;
119
+ const duration = startTime && endTime
120
+ ? (new Date(endTime).getTime() - new Date(startTime).getTime()) / 1000
121
+ : undefined;
122
+ return {
123
+ sessionId,
124
+ model: resolvedModel,
125
+ inputTokens,
126
+ outputTokens,
127
+ cacheWriteTokens,
128
+ cacheReadTokens,
129
+ cost,
130
+ savings,
131
+ timestamp: startTime,
132
+ duration,
133
+ };
134
+ }
135
+ getSessionFiles() {
136
+ if (!fs.existsSync(this.logDir))
137
+ return [];
138
+ try {
139
+ return fs.readdirSync(this.logDir)
140
+ .filter(f => f.endsWith('.jsonl'))
141
+ .map(f => path.join(this.logDir, f))
142
+ .sort((a, b) => {
143
+ try {
144
+ return fs.statSync(a).mtimeMs - fs.statSync(b).mtimeMs;
145
+ }
146
+ catch {
147
+ return 0;
148
+ }
149
+ });
150
+ }
151
+ catch {
152
+ return [];
153
+ }
154
+ }
155
+ }
156
+ //# sourceMappingURL=cost-aggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-aggregator.js","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/cost-aggregator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { OverviewPayload, IncrementListPayload, SyncStatusPayload, SkillUsage, LspStatus, PluginInfo } from '../../types.js';
2
+ import type { CostsSummaryPayload } from './cost-aggregator.js';
3
+ interface AnalyticsAggregation {
4
+ totalEvents: number;
5
+ successRate: number;
6
+ topCommands: Array<{
7
+ name: string;
8
+ count: number;
9
+ }>;
10
+ topSkills: Array<{
11
+ name: string;
12
+ plugin: string;
13
+ count: number;
14
+ successCount: number;
15
+ failureCount: number;
16
+ lastUsed: string;
17
+ }>;
18
+ topAgents: Array<{
19
+ name: string;
20
+ count: number;
21
+ }>;
22
+ dailySummaries: Array<{
23
+ date: string;
24
+ totalEvents: number;
25
+ }>;
26
+ last24hEvents: number;
27
+ }
28
+ export declare class DashboardDataAggregator {
29
+ private projectRoot;
30
+ private analyticsCache;
31
+ private analyticsCacheTime;
32
+ private readonly analyticsCacheTTL;
33
+ constructor(projectRoot: string);
34
+ /** Get overview combining all sources */
35
+ getOverview(costData?: CostsSummaryPayload): Promise<OverviewPayload>;
36
+ /** Get increments list */
37
+ getIncrements(): Promise<IncrementListPayload>;
38
+ /** Get sync status with enriched connection diagnosis */
39
+ getSyncStatus(): Promise<SyncStatusPayload>;
40
+ /** Get analytics summary aggregated from events.jsonl */
41
+ getAnalyticsSummary(): Promise<AnalyticsAggregation>;
42
+ /** Get per-skill usage stats from events.jsonl */
43
+ getSkillUsage(): Promise<SkillUsage[]>;
44
+ /** Get notifications */
45
+ getNotifications(): Promise<unknown[]>;
46
+ /** Get config */
47
+ getConfig(): Promise<Record<string, unknown>>;
48
+ /** Get LSP status */
49
+ getLspStatus(): Promise<LspStatus | null>;
50
+ /** Get installed plugins */
51
+ getPlugins(): Promise<PluginInfo[]>;
52
+ private aggregateEventsFromJsonl;
53
+ private enrichSyncPlatforms;
54
+ private readDashboardJson;
55
+ private readSyncMetadata;
56
+ private readNotifications;
57
+ private readConfig;
58
+ private readJsonFile;
59
+ private extractStatusBreakdown;
60
+ }
61
+ export {};
62
+ //# sourceMappingURL=dashboard-data-aggregator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-data-aggregator.d.ts","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/dashboard-data-aggregator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EAEpB,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,UAAU,oBAAoB;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChI,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,cAAc,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,uBAAuB;IAKtB,OAAO,CAAC,WAAW;IAJ/B,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;gBAExB,WAAW,EAAE,MAAM;IAEvC,yCAAyC;IACnC,WAAW,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;IA2C3E,0BAA0B;IACpB,aAAa,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAoCpD,yDAAyD;IACnD,aAAa,IAAI,OAAO,CAAC,iBAAiB,CAAC;IASjD,yDAAyD;IACnD,mBAAmB,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAI1D,kDAAkD;IAC5C,aAAa,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAa5C,wBAAwB;IAClB,gBAAgB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAI5C,iBAAiB;IACX,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAInD,qBAAqB;IACf,YAAY,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAI/C,4BAA4B;IACtB,UAAU,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAwC3B,wBAAwB;IA6GtC,OAAO,CAAC,mBAAmB;IAqE3B,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,sBAAsB;CAQ/B"}
@@ -0,0 +1,361 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ export class DashboardDataAggregator {
4
+ constructor(projectRoot) {
5
+ this.projectRoot = projectRoot;
6
+ this.analyticsCache = null;
7
+ this.analyticsCacheTime = 0;
8
+ this.analyticsCacheTTL = 30000; // 30 seconds
9
+ }
10
+ /** Get overview combining all sources */
11
+ async getOverview(costData) {
12
+ const dashboard = this.readDashboardJson();
13
+ const syncMeta = this.readSyncMetadata();
14
+ const notifications = this.readNotifications();
15
+ const analytics = await this.aggregateEventsFromJsonl();
16
+ const config = this.readConfig();
17
+ return {
18
+ project: {
19
+ name: config?.project?.name,
20
+ totalIncrements: dashboard?.summary?.total ?? 0,
21
+ activeIncrements: dashboard?.summary?.active ?? 0,
22
+ completedIncrements: dashboard?.summary?.completed ?? 0,
23
+ statusBreakdown: this.extractStatusBreakdown(dashboard?.summary),
24
+ typeBreakdown: dashboard?.summary?.byType ?? {},
25
+ priorityBreakdown: dashboard?.summary?.byPriority ?? {},
26
+ },
27
+ analytics: {
28
+ totalEvents: analytics.totalEvents,
29
+ successRate: analytics.successRate,
30
+ last24hEvents: analytics.last24hEvents,
31
+ },
32
+ costs: {
33
+ totalCost: costData?.totalCost ?? 0,
34
+ totalSavings: costData?.totalSavings ?? 0,
35
+ totalTokens: costData?.totalTokens ?? 0,
36
+ sessionCount: costData?.sessionCount ?? 0,
37
+ },
38
+ notifications: {
39
+ pendingCount: Array.isArray(notifications)
40
+ ? notifications.filter((n) => !n.dismissedAt).length
41
+ : 0,
42
+ criticalCount: Array.isArray(notifications)
43
+ ? notifications.filter((n) => !n.dismissedAt && n.severity === 'critical').length
44
+ : 0,
45
+ },
46
+ sync: {
47
+ platforms: this.enrichSyncPlatforms(syncMeta, config),
48
+ },
49
+ generatedAt: new Date().toISOString(),
50
+ };
51
+ }
52
+ /** Get increments list */
53
+ async getIncrements() {
54
+ const dashboard = this.readDashboardJson();
55
+ const increments = [];
56
+ if (dashboard?.increments) {
57
+ for (const [id, data] of Object.entries(dashboard.increments)) {
58
+ increments.push({
59
+ id,
60
+ title: data.title || id,
61
+ status: data.status || 'unknown',
62
+ type: data.type || 'feature',
63
+ priority: data.priority || 'P2',
64
+ project: data.project,
65
+ tasks: data.tasks || { total: 0, completed: 0 },
66
+ acs: data.acs || { total: 0, completed: 0 },
67
+ createdAt: data.createdAt || '',
68
+ lastActivity: data.lastActivity || '',
69
+ });
70
+ }
71
+ }
72
+ // Sort: active first, then by last activity descending
73
+ increments.sort((a, b) => {
74
+ const statusOrder = { active: 0, planning: 1, paused: 2, ready_for_review: 3, completed: 4, abandoned: 5 };
75
+ const aOrder = statusOrder[a.status] ?? 3;
76
+ const bOrder = statusOrder[b.status] ?? 3;
77
+ if (aOrder !== bOrder)
78
+ return aOrder - bOrder;
79
+ return (b.lastActivity || '').localeCompare(a.lastActivity || '');
80
+ });
81
+ return {
82
+ increments,
83
+ summary: dashboard?.summary ?? {},
84
+ };
85
+ }
86
+ /** Get sync status with enriched connection diagnosis */
87
+ async getSyncStatus() {
88
+ const meta = this.readSyncMetadata();
89
+ const config = this.readConfig();
90
+ return {
91
+ platforms: this.enrichSyncPlatforms(meta, config),
92
+ lastUpdated: meta?.lastUpdated,
93
+ };
94
+ }
95
+ /** Get analytics summary aggregated from events.jsonl */
96
+ async getAnalyticsSummary() {
97
+ return this.aggregateEventsFromJsonl();
98
+ }
99
+ /** Get per-skill usage stats from events.jsonl */
100
+ async getSkillUsage() {
101
+ const analytics = await this.aggregateEventsFromJsonl();
102
+ return analytics.topSkills.map(s => ({
103
+ name: s.name,
104
+ plugin: s.plugin,
105
+ count: s.count,
106
+ successCount: s.successCount,
107
+ failureCount: s.failureCount,
108
+ avgDuration: undefined,
109
+ lastUsed: s.lastUsed,
110
+ }));
111
+ }
112
+ /** Get notifications */
113
+ async getNotifications() {
114
+ return this.readNotifications() || [];
115
+ }
116
+ /** Get config */
117
+ async getConfig() {
118
+ return this.readConfig() || {};
119
+ }
120
+ /** Get LSP status */
121
+ async getLspStatus() {
122
+ return this.readJsonFile('.specweave/state/lsp-check.json');
123
+ }
124
+ /** Get installed plugins */
125
+ async getPlugins() {
126
+ const cacheDir = path.join(process.env.HOME || '', '.claude/plugins/cache/specweave');
127
+ if (!fs.existsSync(cacheDir))
128
+ return [];
129
+ const plugins = [];
130
+ try {
131
+ const entries = fs.readdirSync(cacheDir, { withFileTypes: true });
132
+ for (const entry of entries) {
133
+ if (!entry.isDirectory())
134
+ continue;
135
+ const pluginDir = path.join(cacheDir, entry.name);
136
+ const versions = fs.readdirSync(pluginDir, { withFileTypes: true })
137
+ .filter(v => v.isDirectory())
138
+ .map(v => v.name);
139
+ const version = versions[0] || '0.0.0';
140
+ const versionDir = path.join(pluginDir, version);
141
+ let skillCount = 0;
142
+ let commandCount = 0;
143
+ const skillsDir = path.join(versionDir, 'skills');
144
+ const commandsDir = path.join(versionDir, 'commands');
145
+ if (fs.existsSync(skillsDir)) {
146
+ skillCount = fs.readdirSync(skillsDir, { withFileTypes: true })
147
+ .filter(d => d.isDirectory()).length;
148
+ }
149
+ if (fs.existsSync(commandsDir)) {
150
+ commandCount = fs.readdirSync(commandsDir)
151
+ .filter(f => f.endsWith('.md')).length;
152
+ }
153
+ plugins.push({ name: entry.name, version, skillCount, commandCount });
154
+ }
155
+ }
156
+ catch { /* ignore read errors */ }
157
+ return plugins;
158
+ }
159
+ // --- Analytics Aggregation from events.jsonl ---
160
+ async aggregateEventsFromJsonl() {
161
+ if (this.analyticsCache && Date.now() - this.analyticsCacheTime < this.analyticsCacheTTL) {
162
+ return this.analyticsCache;
163
+ }
164
+ const eventsPath = path.join(this.projectRoot, '.specweave/state/analytics/events.jsonl');
165
+ const commandCounts = new Map();
166
+ const skillMap = new Map();
167
+ const agentCounts = new Map();
168
+ const dailyCounts = new Map();
169
+ let totalEvents = 0;
170
+ let successCount = 0;
171
+ let last24hEvents = 0;
172
+ const now24h = new Date(Date.now() - 86400000).toISOString();
173
+ try {
174
+ if (!fs.existsSync(eventsPath)) {
175
+ const empty = { totalEvents: 0, successRate: 0, topCommands: [], topSkills: [], topAgents: [], dailySummaries: [], last24hEvents: 0 };
176
+ this.analyticsCache = empty;
177
+ this.analyticsCacheTime = Date.now();
178
+ return empty;
179
+ }
180
+ const content = fs.readFileSync(eventsPath, 'utf-8');
181
+ const lines = content.split('\n').filter(Boolean);
182
+ for (const line of lines) {
183
+ try {
184
+ const event = JSON.parse(line);
185
+ totalEvents++;
186
+ if (event.success)
187
+ successCount++;
188
+ if (event.timestamp && event.timestamp >= now24h)
189
+ last24hEvents++;
190
+ const name = event.name || '';
191
+ const type = event.type || '';
192
+ // Command counts
193
+ if (name) {
194
+ commandCounts.set(name, (commandCounts.get(name) || 0) + 1);
195
+ }
196
+ // Skill tracking (commands starting with /sw:)
197
+ if (name.startsWith('/sw:') || type === 'skill_activation') {
198
+ const existing = skillMap.get(name);
199
+ if (existing) {
200
+ existing.count++;
201
+ if (event.success)
202
+ existing.successCount++;
203
+ else
204
+ existing.failureCount++;
205
+ if (event.timestamp > existing.lastUsed)
206
+ existing.lastUsed = event.timestamp;
207
+ }
208
+ else {
209
+ skillMap.set(name, {
210
+ plugin: event.plugin || 'specweave',
211
+ count: 1,
212
+ successCount: event.success ? 1 : 0,
213
+ failureCount: event.success ? 0 : 1,
214
+ lastUsed: event.timestamp || '',
215
+ });
216
+ }
217
+ }
218
+ // Agent tracking
219
+ if (type === 'agent_spawn') {
220
+ agentCounts.set(name, (agentCounts.get(name) || 0) + 1);
221
+ }
222
+ // Daily bucketing
223
+ if (event.timestamp) {
224
+ const date = event.timestamp.slice(0, 10);
225
+ dailyCounts.set(date, (dailyCounts.get(date) || 0) + 1);
226
+ }
227
+ }
228
+ catch { /* skip bad lines */ }
229
+ }
230
+ }
231
+ catch { /* file read error */ }
232
+ const topCommands = Array.from(commandCounts.entries())
233
+ .map(([name, count]) => ({ name, count }))
234
+ .sort((a, b) => b.count - a.count)
235
+ .slice(0, 20);
236
+ const topSkills = Array.from(skillMap.entries())
237
+ .map(([name, data]) => ({ name, ...data }))
238
+ .sort((a, b) => b.count - a.count);
239
+ const topAgents = Array.from(agentCounts.entries())
240
+ .map(([name, count]) => ({ name, count }))
241
+ .sort((a, b) => b.count - a.count)
242
+ .slice(0, 10);
243
+ const dailySummaries = Array.from(dailyCounts.entries())
244
+ .map(([date, totalEvents]) => ({ date, totalEvents }))
245
+ .sort((a, b) => a.date.localeCompare(b.date));
246
+ const result = {
247
+ totalEvents,
248
+ successRate: totalEvents > 0 ? Math.round((successCount / totalEvents) * 100) : 0,
249
+ topCommands,
250
+ topSkills,
251
+ topAgents,
252
+ dailySummaries,
253
+ last24hEvents,
254
+ };
255
+ this.analyticsCache = result;
256
+ this.analyticsCacheTime = Date.now();
257
+ return result;
258
+ }
259
+ // --- Sync Enrichment ---
260
+ enrichSyncPlatforms(syncMeta, config) {
261
+ const platforms = {};
262
+ const platformConfigs = {
263
+ github: {
264
+ key: 'github',
265
+ label: 'GitHub',
266
+ configCheck: () => {
267
+ const gh = config?.sync?.github;
268
+ return gh?.owner && gh?.repo ? `${gh.owner}/${gh.repo}` : null;
269
+ },
270
+ },
271
+ jira: {
272
+ key: 'jira',
273
+ label: 'JIRA',
274
+ configCheck: () => {
275
+ const j = config?.sync?.jira;
276
+ return j?.domain ? `${j.domain} (${j.projectKey || 'N/A'})` : null;
277
+ },
278
+ },
279
+ ado: {
280
+ key: 'ado',
281
+ label: 'Azure DevOps',
282
+ configCheck: () => {
283
+ const a = config?.sync?.ado;
284
+ return a?.organization ? `${a.organization}/${a.project || ''}` : null;
285
+ },
286
+ },
287
+ };
288
+ for (const [key, pConfig] of Object.entries(platformConfigs)) {
289
+ const meta = syncMeta?.[key];
290
+ const configDetail = pConfig.configCheck();
291
+ const lastImport = meta?.lastImport || '';
292
+ const lastSyncResult = meta?.lastSyncResult || 'unknown';
293
+ const lastImportCount = meta?.lastImportCount ?? 0;
294
+ let connectionStatus;
295
+ let diagnosticMessage = '';
296
+ if (!configDetail) {
297
+ connectionStatus = 'not_configured';
298
+ diagnosticMessage = `${pConfig.label} sync is not configured. Add credentials in config.json.`;
299
+ }
300
+ else if (!lastImport) {
301
+ connectionStatus = 'configured_never_synced';
302
+ diagnosticMessage = `${pConfig.label} configured for ${configDetail}. No sync attempted yet.`;
303
+ }
304
+ else if (lastSyncResult === 'success') {
305
+ connectionStatus = 'connected';
306
+ diagnosticMessage = `${pConfig.label} connected to ${configDetail}. Last sync: ${lastImportCount} items.`;
307
+ }
308
+ else {
309
+ connectionStatus = 'sync_failed';
310
+ diagnosticMessage = `${pConfig.label} configured for ${configDetail}. Last sync attempt failed at ${new Date(lastImport).toLocaleString()}.`;
311
+ }
312
+ platforms[key] = {
313
+ lastImport,
314
+ lastSyncResult,
315
+ lastImportCount,
316
+ lastSkippedCount: meta?.lastSkippedCount ?? 0,
317
+ connectionStatus,
318
+ diagnosticMessage,
319
+ configDetail,
320
+ };
321
+ }
322
+ return platforms;
323
+ }
324
+ // --- Private helpers ---
325
+ readDashboardJson() {
326
+ return this.readJsonFile('.specweave/state/dashboard.json');
327
+ }
328
+ readSyncMetadata() {
329
+ return this.readJsonFile('.specweave/sync-metadata.json');
330
+ }
331
+ readNotifications() {
332
+ const data = this.readJsonFile('.specweave/state/notifications.json');
333
+ return data?.notifications || data || [];
334
+ }
335
+ readConfig() {
336
+ return this.readJsonFile('.specweave/config.json');
337
+ }
338
+ readJsonFile(relativePath) {
339
+ const fullPath = path.join(this.projectRoot, relativePath);
340
+ try {
341
+ if (!fs.existsSync(fullPath))
342
+ return null;
343
+ const content = fs.readFileSync(fullPath, 'utf-8');
344
+ return JSON.parse(content);
345
+ }
346
+ catch {
347
+ return null;
348
+ }
349
+ }
350
+ extractStatusBreakdown(summary) {
351
+ if (!summary)
352
+ return {};
353
+ const result = {};
354
+ for (const key of ['active', 'completed', 'paused', 'planning', 'backlog', 'ready_for_review', 'abandoned']) {
355
+ if (summary[key] != null)
356
+ result[key] = summary[key];
357
+ }
358
+ return result;
359
+ }
360
+ }
361
+ //# sourceMappingURL=dashboard-data-aggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-data-aggregator.js","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/dashboard-data-aggregator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { PluginInfo, SkillUsage, LspStatus } from '../../types.js';
2
+ /**
3
+ * Enhanced plugin scanner that reads plugin cache, LSP status,
4
+ * LSP warmup, and skill trigger data.
5
+ */
6
+ export declare class PluginScanner {
7
+ private projectRoot;
8
+ constructor(projectRoot: string);
9
+ /** Scan installed plugins from cache */
10
+ getInstalledPlugins(): PluginInfo[];
11
+ /** Get LSP check status */
12
+ getLspStatus(): LspStatus | null;
13
+ /** Get LSP warmup status */
14
+ getLspWarmup(): LspWarmupStatus | null;
15
+ /** Get skill trigger index */
16
+ getSkillTriggers(): Record<string, string[]>;
17
+ /** Get skill usage from analytics cache */
18
+ getSkillUsage(): SkillUsage[];
19
+ /** Combined plugins + LSP response */
20
+ getFullPluginData(): {
21
+ plugins: PluginInfo[];
22
+ skills: SkillUsage[];
23
+ lsp: LspStatus | null;
24
+ warmup: LspWarmupStatus | null;
25
+ triggerCount: number;
26
+ };
27
+ private readJson;
28
+ }
29
+ export interface LspWarmupStatus {
30
+ warmedUp: string[];
31
+ failed: string[];
32
+ elapsed: number;
33
+ timestamp: string;
34
+ }
35
+ //# sourceMappingURL=plugin-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-scanner.d.ts","sourceRoot":"","sources":["../../../../../src/dashboard/server/data/plugin-scanner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAExE;;;GAGG;AACH,qBAAa,aAAa;IACZ,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEvC,wCAAwC;IACxC,mBAAmB,IAAI,UAAU,EAAE;IAoCnC,2BAA2B;IAC3B,YAAY,IAAI,SAAS,GAAG,IAAI;IAIhC,4BAA4B;IAC5B,YAAY,IAAI,eAAe,GAAG,IAAI;IAItC,8BAA8B;IAC9B,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAK5C,2CAA2C;IAC3C,aAAa,IAAI,UAAU,EAAE;IAc7B,sCAAsC;IACtC,iBAAiB,IAAI;QACnB,OAAO,EAAE,UAAU,EAAE,CAAC;QACtB,MAAM,EAAE,UAAU,EAAE,CAAC;QACrB,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;QACtB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;QAC/B,YAAY,EAAE,MAAM,CAAC;KACtB;IAUD,OAAO,CAAC,QAAQ;CAOjB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB"}