proofscan 0.10.20 → 0.10.22

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 (98) hide show
  1. package/README.ja.md +30 -21
  2. package/README.md +31 -22
  3. package/dist/cli.d.ts +3 -3
  4. package/dist/cli.js +22 -59
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/analyze.d.ts +72 -0
  7. package/dist/commands/analyze.d.ts.map +1 -0
  8. package/dist/commands/analyze.js +382 -0
  9. package/dist/commands/analyze.js.map +1 -0
  10. package/dist/commands/archive.d.ts.map +1 -1
  11. package/dist/commands/archive.js +85 -103
  12. package/dist/commands/archive.js.map +1 -1
  13. package/dist/commands/connectors.d.ts.map +1 -1
  14. package/dist/commands/connectors.js +11 -5
  15. package/dist/commands/connectors.js.map +1 -1
  16. package/dist/commands/i18n.d.ts +10 -0
  17. package/dist/commands/i18n.d.ts.map +1 -0
  18. package/dist/commands/i18n.js +49 -0
  19. package/dist/commands/i18n.js.map +1 -0
  20. package/dist/commands/index.d.ts +1 -4
  21. package/dist/commands/index.d.ts.map +1 -1
  22. package/dist/commands/index.js +3 -5
  23. package/dist/commands/index.js.map +1 -1
  24. package/dist/commands/popl.js +3 -3
  25. package/dist/commands/popl.js.map +1 -1
  26. package/dist/commands/record.d.ts.map +1 -1
  27. package/dist/commands/record.js +21 -18
  28. package/dist/commands/record.js.map +1 -1
  29. package/dist/commands/rpc.d.ts.map +1 -1
  30. package/dist/commands/rpc.js +21 -11
  31. package/dist/commands/rpc.js.map +1 -1
  32. package/dist/commands/secrets.d.ts.map +1 -1
  33. package/dist/commands/secrets.js +15 -8
  34. package/dist/commands/secrets.js.map +1 -1
  35. package/dist/commands/summary.d.ts.map +1 -1
  36. package/dist/commands/summary.js +19 -29
  37. package/dist/commands/summary.js.map +1 -1
  38. package/dist/commands/tool.d.ts.map +1 -1
  39. package/dist/commands/tool.js +1 -0
  40. package/dist/commands/tool.js.map +1 -1
  41. package/dist/commands/view.d.ts +5 -0
  42. package/dist/commands/view.d.ts.map +1 -1
  43. package/dist/commands/view.js +242 -11
  44. package/dist/commands/view.js.map +1 -1
  45. package/dist/db/tool-analysis.d.ts +117 -0
  46. package/dist/db/tool-analysis.d.ts.map +1 -0
  47. package/dist/db/tool-analysis.js +474 -0
  48. package/dist/db/tool-analysis.js.map +1 -0
  49. package/dist/help/categories.d.ts +39 -0
  50. package/dist/help/categories.d.ts.map +1 -0
  51. package/dist/help/categories.js +219 -0
  52. package/dist/help/categories.js.map +1 -0
  53. package/dist/help/index.d.ts +39 -0
  54. package/dist/help/index.d.ts.map +1 -0
  55. package/dist/help/index.js +138 -0
  56. package/dist/help/index.js.map +1 -0
  57. package/dist/i18n/index.d.ts +52 -0
  58. package/dist/i18n/index.d.ts.map +1 -0
  59. package/dist/i18n/index.js +165 -0
  60. package/dist/i18n/index.js.map +1 -0
  61. package/dist/i18n/locales/en.d.ts +238 -0
  62. package/dist/i18n/locales/en.d.ts.map +1 -0
  63. package/dist/i18n/locales/en.js +245 -0
  64. package/dist/i18n/locales/en.js.map +1 -0
  65. package/dist/i18n/locales/ja.d.ts +8 -0
  66. package/dist/i18n/locales/ja.d.ts.map +1 -0
  67. package/dist/i18n/locales/ja.js +243 -0
  68. package/dist/i18n/locales/ja.js.map +1 -0
  69. package/dist/shell/completer.d.ts.map +1 -1
  70. package/dist/shell/completer.js +4 -15
  71. package/dist/shell/completer.js.map +1 -1
  72. package/dist/shell/repl.d.ts +5 -5
  73. package/dist/shell/repl.d.ts.map +1 -1
  74. package/dist/shell/repl.js +73 -152
  75. package/dist/shell/repl.js.map +1 -1
  76. package/dist/shell/router-commands.d.ts +1 -1
  77. package/dist/shell/router-commands.js +1 -1
  78. package/dist/shell/types.d.ts +0 -1
  79. package/dist/shell/types.d.ts.map +1 -1
  80. package/dist/shell/types.js +5 -9
  81. package/dist/shell/types.js.map +1 -1
  82. package/package.json +1 -1
  83. package/dist/commands/events.d.ts +0 -7
  84. package/dist/commands/events.d.ts.map +0 -1
  85. package/dist/commands/events.js +0 -185
  86. package/dist/commands/events.js.map +0 -1
  87. package/dist/commands/explore.d.ts +0 -9
  88. package/dist/commands/explore.d.ts.map +0 -1
  89. package/dist/commands/explore.js +0 -346
  90. package/dist/commands/explore.js.map +0 -1
  91. package/dist/commands/monitor.d.ts +0 -7
  92. package/dist/commands/monitor.d.ts.map +0 -1
  93. package/dist/commands/monitor.js +0 -109
  94. package/dist/commands/monitor.js.map +0 -1
  95. package/dist/commands/permissions.d.ts +0 -44
  96. package/dist/commands/permissions.d.ts.map +0 -1
  97. package/dist/commands/permissions.js +0 -256
  98. package/dist/commands/permissions.js.map +0 -1
@@ -0,0 +1,382 @@
1
+ /**
2
+ * Analyze command
3
+ *
4
+ * Cross-session and cross-connector analysis of tool usage.
5
+ *
6
+ * Usage:
7
+ * pfscan analyze # Overall analysis
8
+ * pfscan analyze <connector> # Connector-level analysis
9
+ * pfscan analyze --session <id> # Session-level analysis (replaces permissions)
10
+ */
11
+ import { Command } from 'commander';
12
+ import { ConfigManager } from '../config/index.js';
13
+ import { output, getOutputOptions } from '../utils/output.js';
14
+ import { resolveSession, isSessionError, formatSessionError, } from '../utils/session-resolver.js';
15
+ import { shortenId } from '../eventline/types.js';
16
+ import { CATEGORY_ORDER, CATEGORY_ORDER_FRIENDLY, getCategoryLabel, classifyTool, extractToolsFromSession, extractToolCallCounts, groupByCategory, getConnectorSummaries, getAllToolUsage, getToolUsageForConnector, getMethodCounts, getSessionDateRange, getLatestToolsForConnector, getSessionsForConnector, } from '../db/tool-analysis.js';
17
+ import { t } from '../i18n/index.js';
18
+ // ============================================================
19
+ // Data Generation
20
+ // ============================================================
21
+ /**
22
+ * Generate overall analysis
23
+ */
24
+ function generateOverallAnalysis(configDir) {
25
+ const connectors = getConnectorSummaries(configDir);
26
+ const dateRange = getSessionDateRange(configDir);
27
+ const methods = getMethodCounts(configDir);
28
+ const toolUsage = getAllToolUsage(configDir);
29
+ // Calculate totals
30
+ const totalSessions = connectors.reduce((sum, c) => sum + c.session_count, 0);
31
+ const totalRpcs = connectors.reduce((sum, c) => sum + c.rpc_count, 0);
32
+ // Calculate by category
33
+ const byCategory = {
34
+ read: 0,
35
+ write: 0,
36
+ network: 0,
37
+ exec: 0,
38
+ other: 0,
39
+ };
40
+ for (const tool of toolUsage) {
41
+ byCategory[tool.category] += tool.call_count;
42
+ }
43
+ return {
44
+ schema_version: 'analyze.overall.v1',
45
+ period: {
46
+ start: dateRange.min,
47
+ end: dateRange.max,
48
+ },
49
+ overview: {
50
+ connector_count: connectors.length,
51
+ session_count: totalSessions,
52
+ rpc_count: totalRpcs,
53
+ },
54
+ by_connector: connectors.map(c => ({
55
+ connector_id: c.connector_id,
56
+ session_count: c.session_count,
57
+ rpc_count: c.rpc_count,
58
+ })),
59
+ methods: Array.from(methods.entries())
60
+ .map(([method, count]) => ({ method, count }))
61
+ .sort((a, b) => b.count - a.count),
62
+ tools_called: toolUsage,
63
+ by_category: byCategory,
64
+ };
65
+ }
66
+ /**
67
+ * Generate connector analysis
68
+ */
69
+ function generateConnectorAnalysis(configDir, connectorId) {
70
+ const sessions = getSessionsForConnector(configDir, connectorId);
71
+ const tools = getLatestToolsForConnector(configDir, connectorId);
72
+ const toolUsage = getToolUsageForConnector(configDir, connectorId);
73
+ // Get date range for this connector
74
+ const startDate = sessions.length > 0 ? sessions[sessions.length - 1].started_at : null;
75
+ const endDate = sessions.length > 0 ? sessions[0].started_at : null;
76
+ // Calculate by category
77
+ const byCategory = {
78
+ read: 0,
79
+ write: 0,
80
+ network: 0,
81
+ exec: 0,
82
+ other: 0,
83
+ };
84
+ for (const tool of toolUsage) {
85
+ byCategory[tool.category] += tool.call_count;
86
+ }
87
+ return {
88
+ schema_version: 'analyze.connector.v1',
89
+ connector_id: connectorId,
90
+ period: {
91
+ start: startDate,
92
+ end: endDate,
93
+ },
94
+ session_count: sessions.length,
95
+ available_tools: tools,
96
+ tool_usage: toolUsage.map(t => ({
97
+ name: t.name,
98
+ call_count: t.call_count,
99
+ category: t.category,
100
+ })),
101
+ by_category: byCategory,
102
+ };
103
+ }
104
+ /**
105
+ * Generate session analysis (replaces permissions)
106
+ */
107
+ function generateSessionAnalysis(configDir, sessionId, connectorId, resolvedBy) {
108
+ const allowedTools = extractToolsFromSession(configDir, sessionId);
109
+ const callCounts = extractToolCallCounts(configDir, sessionId);
110
+ // Initialize categories
111
+ const categories = {
112
+ read: { allowed_tool_count: 0, called_count: 0, tools: [] },
113
+ write: { allowed_tool_count: 0, called_count: 0, tools: [] },
114
+ network: { allowed_tool_count: 0, called_count: 0, tools: [] },
115
+ exec: { allowed_tool_count: 0, called_count: 0, tools: [] },
116
+ other: { allowed_tool_count: 0, called_count: 0, tools: [] },
117
+ };
118
+ // Track which tools are allowed
119
+ const allowedToolNames = new Set(allowedTools.map(t => t.name));
120
+ // Add allowed tools to their categories
121
+ for (const tool of allowedTools) {
122
+ const called = callCounts.get(tool.name) || 0;
123
+ categories[tool.category].tools.push({
124
+ name: tool.name,
125
+ allowed: true,
126
+ called,
127
+ });
128
+ categories[tool.category].allowed_tool_count++;
129
+ categories[tool.category].called_count += called;
130
+ }
131
+ // Add tools that were called but not in allowed list
132
+ for (const [toolName, count] of callCounts) {
133
+ if (!allowedToolNames.has(toolName)) {
134
+ const category = classifyTool(toolName);
135
+ categories[category].tools.push({
136
+ name: toolName,
137
+ allowed: false,
138
+ called: count,
139
+ });
140
+ categories[category].called_count += count;
141
+ }
142
+ }
143
+ // Sort tools: called desc, then name asc
144
+ for (const cat of CATEGORY_ORDER_FRIENDLY) {
145
+ categories[cat].tools.sort((a, b) => {
146
+ if (b.called !== a.called) {
147
+ return b.called - a.called;
148
+ }
149
+ return a.name.localeCompare(b.name);
150
+ });
151
+ }
152
+ // Calculate totals
153
+ const totals = {
154
+ allowed_tool_count: allowedTools.length,
155
+ called_count: Array.from(callCounts.values()).reduce((sum, c) => sum + c, 0),
156
+ };
157
+ return {
158
+ schema_version: 'analyze.session.v1',
159
+ session_id: sessionId,
160
+ connector_id: connectorId,
161
+ resolved_by: resolvedBy,
162
+ categories,
163
+ totals,
164
+ };
165
+ }
166
+ // ============================================================
167
+ // Rendering
168
+ // ============================================================
169
+ /**
170
+ * Format date for display (YYYY-MM-DD)
171
+ */
172
+ function formatDate(isoDate) {
173
+ if (!isoDate)
174
+ return '(no data)';
175
+ return isoDate.slice(0, 10);
176
+ }
177
+ /**
178
+ * Render overall analysis
179
+ */
180
+ function renderOverallAnalysis(data) {
181
+ console.log('proofscan Analysis');
182
+ console.log('==================');
183
+ console.log();
184
+ console.log(`Period: ${formatDate(data.period.start)} ~ ${formatDate(data.period.end)}`);
185
+ console.log();
186
+ console.log('Overview:');
187
+ console.log(` Connectors: ${data.overview.connector_count}`);
188
+ console.log(` Sessions: ${data.overview.session_count}`);
189
+ console.log(` RPC calls: ${data.overview.rpc_count}`);
190
+ console.log();
191
+ if (data.by_connector.length > 0) {
192
+ console.log('By Connector:');
193
+ for (const conn of data.by_connector) {
194
+ const sessions = String(conn.session_count).padStart(3);
195
+ const rpcs = String(conn.rpc_count).padStart(4);
196
+ console.log(` ${conn.connector_id.padEnd(12)} ${sessions} sessions, ${rpcs} RPCs`);
197
+ }
198
+ console.log();
199
+ }
200
+ if (data.methods.length > 0) {
201
+ console.log('Methods:');
202
+ for (const m of data.methods) {
203
+ console.log(` ${m.method.padEnd(14)} ${m.count} calls`);
204
+ }
205
+ console.log();
206
+ }
207
+ if (data.tools_called.length > 0) {
208
+ console.log('Tools Called (across all sessions):');
209
+ for (const tool of data.tools_called.slice(0, 10)) {
210
+ const countStr = tool.call_count === 1 ? '1 call' : `${tool.call_count} calls`;
211
+ console.log(` ${tool.name.padEnd(20)} ${countStr.padStart(8)} (${tool.connector_id})`);
212
+ }
213
+ if (data.tools_called.length > 10) {
214
+ console.log(` ... and ${data.tools_called.length - 10} more`);
215
+ }
216
+ console.log();
217
+ }
218
+ // By category summary
219
+ const totalCalls = Object.values(data.by_category).reduce((a, b) => a + b, 0);
220
+ if (totalCalls > 0) {
221
+ console.log('By Category:');
222
+ for (const cat of CATEGORY_ORDER) {
223
+ const count = data.by_category[cat];
224
+ if (count > 0) {
225
+ const pct = Math.round((count / totalCalls) * 100);
226
+ console.log(` ${getCategoryLabel(cat).padEnd(24)} ${count} calls (${pct}%)`);
227
+ }
228
+ }
229
+ }
230
+ }
231
+ /**
232
+ * Render connector analysis
233
+ */
234
+ function renderConnectorAnalysis(data) {
235
+ console.log(`proofscan Analysis: ${data.connector_id}`);
236
+ console.log('='.repeat(20 + data.connector_id.length));
237
+ console.log();
238
+ console.log(`Period: ${formatDate(data.period.start)} ~ ${formatDate(data.period.end)} (${data.session_count} sessions)`);
239
+ console.log();
240
+ // Available tools
241
+ if (data.available_tools.length > 0) {
242
+ console.log('Available Tools (from latest tools/list):');
243
+ const toolsByCategory = groupByCategory(data.available_tools);
244
+ for (const cat of CATEGORY_ORDER) {
245
+ const tools = toolsByCategory[cat];
246
+ if (tools.length > 0) {
247
+ for (const tool of tools) {
248
+ console.log(` ${tool.name.padEnd(24)} ${getCategoryLabel(cat)}`);
249
+ }
250
+ }
251
+ }
252
+ console.log();
253
+ }
254
+ // Tool usage
255
+ if (data.tool_usage.length > 0) {
256
+ console.log(`Tool Usage (across ${data.session_count} sessions):`);
257
+ for (const tool of data.tool_usage) {
258
+ const countStr = tool.call_count === 1 ? '1 call' : `${tool.call_count} calls`;
259
+ console.log(` ${tool.name.padEnd(24)} ${countStr}`);
260
+ }
261
+ console.log();
262
+ }
263
+ // By category summary
264
+ const totalCalls = Object.values(data.by_category).reduce((a, b) => a + b, 0);
265
+ if (totalCalls > 0) {
266
+ console.log('By Category:');
267
+ for (const cat of CATEGORY_ORDER) {
268
+ const count = data.by_category[cat];
269
+ if (count > 0) {
270
+ const pct = Math.round((count / totalCalls) * 100);
271
+ console.log(` ${getCategoryLabel(cat).padEnd(24)} ${count} calls (${pct}%)`);
272
+ }
273
+ }
274
+ }
275
+ }
276
+ /**
277
+ * Render session analysis (replaces permissions display)
278
+ */
279
+ function renderSessionAnalysis(data) {
280
+ console.log(`${data.connector_id} (session: ${shortenId(data.session_id, 8)}...)`);
281
+ console.log();
282
+ for (const cat of CATEGORY_ORDER_FRIENDLY) {
283
+ const stats = data.categories[cat];
284
+ const label = getCategoryLabel(cat);
285
+ // Category header
286
+ console.log(t('analyze.section.header', { label }));
287
+ // Permission/usage
288
+ const hasPermission = stats.allowed_tool_count > 0;
289
+ console.log(` ${t('analyze.permission.label')}: ${hasPermission ? t('analyze.permission.allowed') : t('analyze.permission.denied')}`);
290
+ console.log(` ${t('analyze.usage.label')}: ${t('analyze.usage.count', { count: stats.called_count })}`);
291
+ // Tool list
292
+ if (stats.tools.length > 0) {
293
+ console.log();
294
+ for (const tool of stats.tools) {
295
+ const allowedMark = tool.allowed ? '' : ` ${t('analyze.notAllowed')}`;
296
+ console.log(` ${tool.name}: ${t('analyze.usage.count', { count: tool.called })}${allowedMark}`);
297
+ }
298
+ }
299
+ console.log();
300
+ }
301
+ // Totals
302
+ console.log('─'.repeat(40));
303
+ console.log(t('analyze.total', { allowed: data.totals.allowed_tool_count, count: data.totals.called_count }));
304
+ }
305
+ // ============================================================
306
+ // Command
307
+ // ============================================================
308
+ export function createAnalyzeCommand(getConfigPath) {
309
+ const cmd = new Command('analyze')
310
+ .description('Analyze tool usage across sessions and connectors')
311
+ .addHelpText('after', `
312
+ Examples:
313
+ pfscan analyze # Overall analysis
314
+ pfscan analyze time # Connector-level analysis
315
+ pfscan analyze --session abc123 # Session-level analysis
316
+ pfscan analyze --latest # Latest session analysis
317
+ pfscan analyze --json # JSON output
318
+ `)
319
+ .argument('[connector]', 'Connector ID for connector-level analysis')
320
+ .option('--session <id>', 'Session ID for session-level analysis')
321
+ .option('--latest', 'Use the latest session')
322
+ .option('--connector <id>', 'Filter by connector (with --latest)')
323
+ .action(async (connectorArg, options) => {
324
+ try {
325
+ const manager = new ConfigManager(getConfigPath());
326
+ const configDir = manager.getConfigDir();
327
+ const jsonMode = getOutputOptions().json;
328
+ // Determine analysis mode
329
+ if (options.session || options.latest) {
330
+ // Session-level analysis (replaces permissions)
331
+ const connectorId = connectorArg || options.connector;
332
+ const result = resolveSession({
333
+ sessionId: options.session,
334
+ latest: options.latest || !!connectorId,
335
+ connectorId,
336
+ configDir,
337
+ });
338
+ if (isSessionError(result)) {
339
+ console.error(formatSessionError(result));
340
+ process.exit(1);
341
+ }
342
+ const data = generateSessionAnalysis(configDir, result.sessionId, result.connectorId, result.resolvedBy);
343
+ if (jsonMode) {
344
+ output(data);
345
+ }
346
+ else {
347
+ renderSessionAnalysis(data);
348
+ }
349
+ }
350
+ else if (connectorArg) {
351
+ // Connector-level analysis
352
+ const data = generateConnectorAnalysis(configDir, connectorArg);
353
+ if (jsonMode) {
354
+ output(data);
355
+ }
356
+ else {
357
+ renderConnectorAnalysis(data);
358
+ }
359
+ }
360
+ else {
361
+ // Overall analysis
362
+ const data = generateOverallAnalysis(configDir);
363
+ if (jsonMode) {
364
+ output(data);
365
+ }
366
+ else {
367
+ renderOverallAnalysis(data);
368
+ }
369
+ }
370
+ }
371
+ catch (error) {
372
+ if (error instanceof Error && error.message.includes('no such table')) {
373
+ console.log('No data yet. Run a scan first:');
374
+ console.log(' pfscan scan start --id <connector>');
375
+ return;
376
+ }
377
+ throw error;
378
+ }
379
+ });
380
+ return cmd;
381
+ }
382
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0DpC,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,MAAM,GAAG,OAAO,CAwNzE"}
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/commands/archive.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+IpC,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,MAAM,GAAG,OAAO,CAgHzE"}
@@ -44,72 +44,95 @@ async function computeArchivePlan(eventsStore, proofsStore, retention, configDir
44
44
  estimated_savings_mb: estimatedSavingsMb,
45
45
  };
46
46
  }
47
- export function createArchiveCommand(getConfigPath) {
48
- const cmd = new Command('archive')
49
- .description('Manage data retention and cleanup');
50
- cmd
51
- .command('plan')
52
- .description('Show what would be archived based on retention settings')
53
- .action(async () => {
54
- try {
55
- const manager = new ConfigManager(getConfigPath());
56
- const config = await manager.load();
57
- const eventsStore = new EventsStore(manager.getConfigDir());
58
- const proofsStore = new ProofsStore(manager.getConfigDir());
59
- // Get retention settings with defaults
60
- const retention = {
61
- keep_last_sessions: config.retention?.keep_last_sessions ?? 50,
62
- raw_days: config.retention?.raw_days ?? 7,
63
- max_db_mb: config.retention?.max_db_mb ?? 500,
64
- };
65
- const plan = await computeArchivePlan(eventsStore, proofsStore, retention, manager.getConfigDir());
66
- const dbSizes = getDbSizes(manager.getConfigDir());
67
- if (getOutputOptions().json) {
68
- output({
69
- retention,
70
- plan,
71
- current_db_size_mb: dbSizes.events / (1024 * 1024),
72
- });
47
+ /**
48
+ * Show archive status and plan (default action)
49
+ */
50
+ async function showStatusAndPlan(getConfigPath) {
51
+ try {
52
+ const manager = new ConfigManager(getConfigPath());
53
+ const config = await manager.load();
54
+ const eventsStore = new EventsStore(manager.getConfigDir());
55
+ const proofsStore = new ProofsStore(manager.getConfigDir());
56
+ // Get retention settings with defaults
57
+ const retention = {
58
+ keep_last_sessions: config.retention?.keep_last_sessions ?? 50,
59
+ raw_days: config.retention?.raw_days ?? 7,
60
+ max_db_mb: config.retention?.max_db_mb ?? 500,
61
+ };
62
+ const plan = await computeArchivePlan(eventsStore, proofsStore, retention, manager.getConfigDir());
63
+ const dbSizes = getDbSizes(manager.getConfigDir());
64
+ // Get current data stats
65
+ const sessions = eventsStore.getAllSessions();
66
+ const protectedIds = proofsStore.getProtectedSessionIds();
67
+ if (getOutputOptions().json) {
68
+ output({
69
+ database: {
70
+ events_db_size: dbSizes.events,
71
+ proofs_db_size: dbSizes.proofs,
72
+ },
73
+ current_data: {
74
+ total_sessions: sessions.length,
75
+ protected_sessions: protectedIds.length,
76
+ },
77
+ retention,
78
+ plan,
79
+ });
80
+ }
81
+ else {
82
+ console.log('Archive Status & Plan');
83
+ console.log('=====================\n');
84
+ console.log('Database:');
85
+ console.log(` events.db: ${formatBytes(dbSizes.events)}`);
86
+ console.log(` proofs.db: ${formatBytes(dbSizes.proofs)}`);
87
+ console.log();
88
+ console.log('Current Data:');
89
+ console.log(` Sessions: ${sessions.length} (${protectedIds.length} protected)`);
90
+ console.log();
91
+ console.log('Retention Settings:');
92
+ console.log(` keep_last_sessions: ${retention.keep_last_sessions}`);
93
+ console.log(` raw_days: ${retention.raw_days}`);
94
+ console.log(` max_db_mb: ${retention.max_db_mb}`);
95
+ console.log();
96
+ console.log('Cleanup Plan:');
97
+ if (plan.sessions_to_delete.length > 0) {
98
+ console.log(` Sessions to delete: ${plan.sessions_to_delete.length}`);
99
+ const headers = ['Session ID', 'Connector', 'Events', 'Reason'];
100
+ const rows = plan.sessions_to_delete.slice(0, 5).map(s => [
101
+ s.session_id.slice(0, 8) + '...',
102
+ s.connector_id,
103
+ String(s.event_count),
104
+ s.reason,
105
+ ]);
106
+ outputTable(headers, rows);
107
+ if (plan.sessions_to_delete.length > 5) {
108
+ console.log(` ... and ${plan.sessions_to_delete.length - 5} more`);
109
+ }
73
110
  }
74
111
  else {
75
- console.log('Archive Plan');
76
- console.log('============\n');
77
- console.log('Retention Settings:');
78
- console.log(` keep_last_sessions: ${retention.keep_last_sessions}`);
79
- console.log(` raw_days: ${retention.raw_days}`);
80
- console.log(` max_db_mb: ${retention.max_db_mb}`);
81
- console.log();
82
- console.log('Current Status:');
83
- console.log(` events.db size: ${formatBytes(dbSizes.events)}`);
84
- console.log(` proofs.db size: ${formatBytes(dbSizes.proofs)}`);
85
- console.log();
86
- console.log('Planned Actions:');
87
- if (plan.sessions_to_delete.length > 0) {
88
- console.log(`\n Sessions to delete: ${plan.sessions_to_delete.length}`);
89
- const headers = ['Session ID', 'Connector', 'Events', 'Reason'];
90
- const rows = plan.sessions_to_delete.slice(0, 10).map(s => [
91
- s.session_id.slice(0, 8) + '...',
92
- s.connector_id,
93
- String(s.event_count),
94
- s.reason,
95
- ]);
96
- outputTable(headers, rows);
97
- if (plan.sessions_to_delete.length > 10) {
98
- console.log(` ... and ${plan.sessions_to_delete.length - 10} more`);
99
- }
100
- }
101
- else {
102
- console.log(' Sessions to delete: 0');
103
- }
104
- console.log(`\n raw_json to clear: ${plan.raw_json_to_clear} events`);
105
- console.log(` Estimated savings: ~${plan.estimated_savings_mb.toFixed(1)} MB`);
106
- console.log('\nRun "pfscan archive run" to execute (or "pfscan archive run --yes" to confirm).');
112
+ console.log(' Sessions to delete: 0 (within limit)');
107
113
  }
114
+ console.log(` raw_json to clear: ${plan.raw_json_to_clear} events (older than ${retention.raw_days} days)`);
115
+ console.log(` Estimated savings: ~${plan.estimated_savings_mb.toFixed(1)} MB`);
116
+ console.log('\nRun "pfscan archive run --yes" to execute.');
108
117
  }
109
- catch (error) {
110
- outputError('Failed to compute archive plan', error instanceof Error ? error : undefined);
111
- process.exit(1);
112
- }
118
+ }
119
+ catch (error) {
120
+ outputError('Failed to compute archive plan', error instanceof Error ? error : undefined);
121
+ process.exit(1);
122
+ }
123
+ }
124
+ export function createArchiveCommand(getConfigPath) {
125
+ const cmd = new Command('archive')
126
+ .description('Manage data retention and cleanup')
127
+ .addHelpText('after', `
128
+ Examples:
129
+ pfscan archive # Show status and cleanup plan
130
+ pfscan archive run # Dry run (show what would be done)
131
+ pfscan archive run --yes # Execute cleanup
132
+ `)
133
+ .action(async () => {
134
+ // Default action: show status and plan
135
+ await showStatusAndPlan(getConfigPath);
113
136
  });
114
137
  cmd
115
138
  .command('run')
@@ -197,47 +220,6 @@ export function createArchiveCommand(getConfigPath) {
197
220
  process.exit(1);
198
221
  }
199
222
  });
200
- cmd
201
- .command('status')
202
- .description('Show current database status')
203
- .action(async () => {
204
- try {
205
- const manager = new ConfigManager(getConfigPath());
206
- const eventsStore = new EventsStore(manager.getConfigDir());
207
- const proofsStore = new ProofsStore(manager.getConfigDir());
208
- const dbSizes = getDbSizes(manager.getConfigDir());
209
- const sessions = eventsStore.getAllSessions();
210
- const proofCount = proofsStore.countProofs();
211
- const protectedIds = proofsStore.getProtectedSessionIds();
212
- const rawJsonSize = eventsStore.getRawJsonSize();
213
- const status = {
214
- events_db_size: dbSizes.events,
215
- proofs_db_size: dbSizes.proofs,
216
- total_sessions: sessions.length,
217
- protected_sessions: protectedIds.length,
218
- total_proofs: proofCount,
219
- raw_json_size: rawJsonSize,
220
- };
221
- if (getOutputOptions().json) {
222
- output(status);
223
- }
224
- else {
225
- console.log('Database Status');
226
- console.log('===============\n');
227
- console.log(`events.db size: ${formatBytes(dbSizes.events)}`);
228
- console.log(`proofs.db size: ${formatBytes(dbSizes.proofs)}`);
229
- console.log();
230
- console.log(`Total sessions: ${sessions.length}`);
231
- console.log(`Protected sessions: ${protectedIds.length}`);
232
- console.log(`Total proofs: ${proofCount}`);
233
- console.log(`raw_json storage: ${formatBytes(rawJsonSize)}`);
234
- }
235
- }
236
- catch (error) {
237
- outputError('Failed to get status', error instanceof Error ? error : undefined);
238
- process.exit(1);
239
- }
240
- });
241
223
  return cmd;
242
224
  }
243
225
  //# sourceMappingURL=archive.js.map