agentvigil 1.0.8 → 1.0.9

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 (60) hide show
  1. package/dist/commands/daemon.d.ts.map +1 -1
  2. package/dist/commands/daemon.js +3 -0
  3. package/dist/commands/daemon.js.map +1 -1
  4. package/dist/commands/setup.d.ts.map +1 -1
  5. package/dist/commands/setup.js +2 -1
  6. package/dist/commands/setup.js.map +1 -1
  7. package/dist/hooks/hook-handler.d.ts.map +1 -1
  8. package/dist/hooks/hook-handler.js +7 -0
  9. package/dist/hooks/hook-handler.js.map +1 -1
  10. package/dist/index.js +9 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/notifications/mac-notifier.d.ts +11 -0
  13. package/dist/notifications/mac-notifier.d.ts.map +1 -0
  14. package/dist/notifications/mac-notifier.js +28 -0
  15. package/dist/notifications/mac-notifier.js.map +1 -0
  16. package/dist/notifications/ntfy-client.d.ts +2 -0
  17. package/dist/notifications/ntfy-client.d.ts.map +1 -1
  18. package/dist/notifications/ntfy-client.js +10 -0
  19. package/dist/notifications/ntfy-client.js.map +1 -1
  20. package/dist/relay/relay-handler.d.ts.map +1 -1
  21. package/dist/relay/relay-handler.js +3 -0
  22. package/dist/relay/relay-handler.js.map +1 -1
  23. package/dist/sessions/process-detector.d.ts +9 -0
  24. package/dist/sessions/process-detector.d.ts.map +1 -1
  25. package/dist/sessions/process-detector.js +63 -1
  26. package/dist/sessions/process-detector.js.map +1 -1
  27. package/dist/sessions/session-manager.d.ts.map +1 -1
  28. package/dist/sessions/session-manager.js +17 -1
  29. package/dist/sessions/session-manager.js.map +1 -1
  30. package/dist/sessions/token-calculator.d.ts +15 -0
  31. package/dist/sessions/token-calculator.d.ts.map +1 -0
  32. package/dist/sessions/token-calculator.js +94 -0
  33. package/dist/sessions/token-calculator.js.map +1 -0
  34. package/dist/stats/daily-tracker.d.ts +114 -0
  35. package/dist/stats/daily-tracker.d.ts.map +1 -0
  36. package/dist/stats/daily-tracker.js +484 -0
  37. package/dist/stats/daily-tracker.js.map +1 -0
  38. package/dist/stats/session-utils.d.ts +2 -0
  39. package/dist/stats/session-utils.d.ts.map +1 -0
  40. package/dist/stats/session-utils.js +11 -0
  41. package/dist/stats/session-utils.js.map +1 -0
  42. package/dist/stats/summary-formatter.d.ts +67 -0
  43. package/dist/stats/summary-formatter.d.ts.map +1 -0
  44. package/dist/stats/summary-formatter.js +116 -0
  45. package/dist/stats/summary-formatter.js.map +1 -0
  46. package/dist/stats/transcript-sync.d.ts +18 -0
  47. package/dist/stats/transcript-sync.d.ts.map +1 -0
  48. package/dist/stats/transcript-sync.js +143 -0
  49. package/dist/stats/transcript-sync.js.map +1 -0
  50. package/dist/types.d.ts +4 -1
  51. package/dist/types.d.ts.map +1 -1
  52. package/dist/utils/config.d.ts +4 -0
  53. package/dist/utils/config.d.ts.map +1 -1
  54. package/dist/utils/config.js +2 -0
  55. package/dist/utils/config.js.map +1 -1
  56. package/dist/utils/prompt.d.ts +3 -0
  57. package/dist/utils/prompt.d.ts.map +1 -0
  58. package/dist/utils/prompt.js +14 -0
  59. package/dist/utils/prompt.js.map +1 -0
  60. package/package.json +2 -2
@@ -0,0 +1,116 @@
1
+ function formatDuration(ms) {
2
+ const totalMinutes = Math.round(ms / 60_000);
3
+ const hours = Math.floor(totalMinutes / 60);
4
+ const minutes = totalMinutes % 60;
5
+ if (hours === 0)
6
+ return `${minutes}m`;
7
+ return `${hours}h ${minutes}m`;
8
+ }
9
+ function formatTokenCount(tokens) {
10
+ if (tokens >= 1_000_000)
11
+ return `${(tokens / 1_000_000).toFixed(1)}M`;
12
+ if (tokens >= 1_000)
13
+ return `${(tokens / 1_000).toFixed(1)}k`;
14
+ return `${tokens}`;
15
+ }
16
+ function formatCost(usd) {
17
+ return `$${usd.toFixed(2)}`;
18
+ }
19
+ function toIsoString(value, fallback = new Date()) {
20
+ const date = value instanceof Date && !Number.isNaN(value.getTime()) ? value : fallback;
21
+ return date.toISOString();
22
+ }
23
+ /**
24
+ * `Title` is sent as an ntfy HTTP header, which must be Latin-1 — keep it
25
+ * emoji-free. The real notification text is rendered client-side by the
26
+ * Flutter app from the JSON payload (see `buildSummaryPayload`).
27
+ */
28
+ export function formatSummaryForPhone(summary) {
29
+ const projectLabel = summary.totalSessions === 1 ? 'project' : 'projects';
30
+ return {
31
+ title: `Daily Summary - ${summary.totalSessions} ${projectLabel}, ${formatTokenCount(summary.totalTokens)} tokens, ${formatDuration(summary.totalActiveTimeMs)}`,
32
+ };
33
+ }
34
+ export function formatSummaryForMac(summary) {
35
+ const projectLabel = summary.totalSessions === 1 ? 'project' : 'projects';
36
+ const lines = [
37
+ `${summary.totalSessions} ${projectLabel} · ${formatDuration(summary.totalActiveTimeMs)} active`,
38
+ `${formatTokenCount(summary.totalTokens)} tokens (${formatTokenCount(summary.totalOutputTokens)} output)`,
39
+ `${summary.totalTasksCompleted} tasks · ${summary.totalFilesModified} files modified`,
40
+ `Est. API equivalent: ${formatCost(summary.totalCostUsd)} (not your subscription bill)`,
41
+ ];
42
+ if (summary.totalPermissionPrompts > 0) {
43
+ lines.push(`${summary.totalPermissionPrompts} permission prompts (${summary.permissionsApproved} approved, ${summary.permissionsDenied} denied)`);
44
+ }
45
+ if (summary.topProject !== 'none') {
46
+ lines.push(`Top project: ${summary.topProject} (${formatCost(summary.topProjectCost)} est.)`);
47
+ }
48
+ return {
49
+ title: '📊 Daily Summary',
50
+ subtitle: summary.date,
51
+ body: lines.join('\n'),
52
+ };
53
+ }
54
+ /** Builds the wire shape shared by the once-daily ntfy payload and the live WS broadcast. */
55
+ export function buildSummaryObject(summary) {
56
+ const n = summary.totalSessions;
57
+ const usageSummary = `${formatTokenCount(summary.totalTokens)} tokens · ${formatDuration(summary.totalActiveTimeMs)} · ${summary.totalTasksCompleted} tasks`;
58
+ return {
59
+ type: 'daily_summary',
60
+ date: summary.date,
61
+ total_sessions: n,
62
+ total_active_time_ms: summary.totalActiveTimeMs,
63
+ total_input_tokens: summary.totalInputTokens,
64
+ total_output_tokens: summary.totalOutputTokens,
65
+ total_cache_read_tokens: summary.totalCacheReadTokens,
66
+ total_tokens: summary.totalTokens,
67
+ total_cost_usd: summary.totalCostUsd,
68
+ usage_summary: usageSummary,
69
+ cost_label: 'Est. API equivalent',
70
+ cost_note: 'Compares usage to pay-as-you-go API rates — not your Claude subscription bill.',
71
+ cost_is_api_estimate: true,
72
+ total_tasks_completed: summary.totalTasksCompleted,
73
+ total_files_modified: summary.totalFilesModified,
74
+ total_permission_prompts: summary.totalPermissionPrompts,
75
+ permissions_approved: summary.permissionsApproved,
76
+ permissions_denied: summary.permissionsDenied,
77
+ average_tokens_per_session: n > 0 ? summary.totalTokens / n : 0,
78
+ average_spend_per_session: n > 0 ? summary.totalCostUsd / n : 0,
79
+ top_project: summary.topProject,
80
+ top_project_cost: summary.topProjectCost,
81
+ top_project_time_ms: summary.topProjectTimeMs,
82
+ sessions: summary.sessions.map((s) => ({
83
+ session_id: s.sessionId,
84
+ project: s.projectName,
85
+ agent: s.agentType,
86
+ start_time: toIsoString(s.startTime),
87
+ end_time: s.endTime ? toIsoString(s.endTime, s.startTime) : null,
88
+ last_activity: toIsoString(s.lastActivityAt, s.endTime ?? s.startTime),
89
+ duration_ms: s.durationMs,
90
+ input_tokens: s.inputTokens,
91
+ output_tokens: s.outputTokens,
92
+ tokens: s.totalTokens,
93
+ cost_usd: s.costUsd,
94
+ tasks: s.tasksCompleted,
95
+ })),
96
+ generated_at: toIsoString(summary.generatedAt),
97
+ };
98
+ }
99
+ /** JSON payload sent as the ntfy message body — parsed by the Flutter app's `DailySummary.fromJson`. */
100
+ export function buildSummaryPayload(summary) {
101
+ return JSON.stringify(buildSummaryObject(summary));
102
+ }
103
+ /** Live WS event broadcast to the phone whenever today's stats change. */
104
+ export function buildDailyStatsEvent(summary) {
105
+ return {
106
+ type: 'daily_stats_update',
107
+ session_id: 'daily_stats',
108
+ project_name: 'AgentVigil',
109
+ cwd: '',
110
+ agent: 'claude-code',
111
+ message: 'daily_stats_update',
112
+ timestamp: new Date().toISOString(),
113
+ summary: buildSummaryObject(summary),
114
+ };
115
+ }
116
+ //# sourceMappingURL=summary-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary-formatter.js","sourceRoot":"","sources":["../../src/stats/summary-formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface TranscriptRef {
2
+ sessionId: string;
3
+ filePath: string;
4
+ }
5
+ export interface TranscriptTimeline {
6
+ firstActivity?: Date;
7
+ lastActivity?: Date;
8
+ stopCount: number;
9
+ }
10
+ /** Stop hooks in the transcript, or 1 if the session did real work without a Stop hook. */
11
+ export declare function inferTaskCount(stopHooks: number, totalTokens: number): number;
12
+ export declare function parseTranscriptTimeline(filePath: string, date?: string): Promise<TranscriptTimeline>;
13
+ /** Timeline scoped to a stats day, with fallbacks when lines lack timestamps. */
14
+ export declare function timelineForStatsDate(filePath: string, date: string): Promise<TranscriptTimeline>;
15
+ export declare function transcriptActiveOnDate(filePath: string, date: string): Promise<boolean>;
16
+ /** Finds every Claude Code transcript with activity on `date` (YYYY-MM-DD). */
17
+ export declare function listTranscriptsForDate(date: string): Promise<TranscriptRef[]>;
18
+ //# sourceMappingURL=transcript-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-sync.d.ts","sourceRoot":"","sources":["../../src/stats/transcript-sync.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAI7E;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;AAED,iFAAiF;AACjF,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,CAAC,CAgC7B;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAqB7F;AAED,+EAA+E;AAC/E,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAgCnF"}
@@ -0,0 +1,143 @@
1
+ import fs from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { isBlocklisted, extractCwdFromPath } from '../sessions/session-watcher.js';
5
+ import { isTrackableClaudeSession } from './session-utils.js';
6
+ function entryTimestamp(entry) {
7
+ const ts = entry.timestamp ?? entry.message?.timestamp;
8
+ if (typeof ts !== 'string')
9
+ return undefined;
10
+ const d = new Date(ts);
11
+ return Number.isNaN(d.getTime()) ? undefined : d;
12
+ }
13
+ /** Stop hooks in the transcript, or 1 if the session did real work without a Stop hook. */
14
+ export function inferTaskCount(stopHooks, totalTokens) {
15
+ if (stopHooks > 0)
16
+ return stopHooks;
17
+ if (totalTokens > 0)
18
+ return 1;
19
+ return 0;
20
+ }
21
+ export async function parseTranscriptTimeline(filePath, date) {
22
+ let firstActivity;
23
+ let lastActivity;
24
+ let stopCount = 0;
25
+ try {
26
+ const content = await fs.readFile(filePath, 'utf-8');
27
+ for (const line of content.trim().split('\n')) {
28
+ if (!line.trim())
29
+ continue;
30
+ try {
31
+ const entry = JSON.parse(line);
32
+ if (entry.hook_event_name === 'Stop')
33
+ stopCount++;
34
+ const d = entryTimestamp(entry);
35
+ if (!d)
36
+ continue;
37
+ if (date && !d.toISOString().startsWith(date))
38
+ continue;
39
+ if (!firstActivity || d < firstActivity)
40
+ firstActivity = d;
41
+ if (!lastActivity || d > lastActivity)
42
+ lastActivity = d;
43
+ }
44
+ catch {
45
+ continue;
46
+ }
47
+ }
48
+ }
49
+ catch {
50
+ // unreadable transcript
51
+ }
52
+ return { firstActivity, lastActivity, stopCount };
53
+ }
54
+ /** Timeline scoped to a stats day, with fallbacks when lines lack timestamps. */
55
+ export async function timelineForStatsDate(filePath, date) {
56
+ const onDate = await parseTranscriptTimeline(filePath, date);
57
+ if (onDate.firstActivity && onDate.lastActivity)
58
+ return onDate;
59
+ const full = await parseTranscriptTimeline(filePath);
60
+ const dayStart = new Date(`${date}T00:00:00.000Z`);
61
+ const dayEnd = new Date(`${date}T23:59:59.999Z`);
62
+ if (full.firstActivity && full.lastActivity) {
63
+ if (full.lastActivity >= dayStart && full.firstActivity <= dayEnd) {
64
+ return {
65
+ firstActivity: full.firstActivity < dayStart ? dayStart : full.firstActivity,
66
+ lastActivity: full.lastActivity > dayEnd ? dayEnd : full.lastActivity,
67
+ stopCount: full.stopCount,
68
+ };
69
+ }
70
+ }
71
+ try {
72
+ const fileStat = await fs.stat(filePath);
73
+ if (fileStat.mtime.toISOString().startsWith(date)) {
74
+ return {
75
+ firstActivity: dayStart,
76
+ lastActivity: fileStat.mtime,
77
+ stopCount: full.stopCount,
78
+ };
79
+ }
80
+ }
81
+ catch {
82
+ // unreadable
83
+ }
84
+ return onDate;
85
+ }
86
+ export async function transcriptActiveOnDate(filePath, date) {
87
+ try {
88
+ const fileStat = await fs.stat(filePath);
89
+ if (fileStat.mtime.toISOString().startsWith(date))
90
+ return true;
91
+ const content = await fs.readFile(filePath, 'utf-8');
92
+ for (const line of content.trim().split('\n')) {
93
+ if (!line.trim())
94
+ continue;
95
+ try {
96
+ const entry = JSON.parse(line);
97
+ const ts = entry.timestamp ?? entry.message?.timestamp;
98
+ if (typeof ts === 'string' && ts.startsWith(date))
99
+ return true;
100
+ }
101
+ catch {
102
+ continue;
103
+ }
104
+ }
105
+ }
106
+ catch {
107
+ // missing or unreadable
108
+ }
109
+ return false;
110
+ }
111
+ /** Finds every Claude Code transcript with activity on `date` (YYYY-MM-DD). */
112
+ export async function listTranscriptsForDate(date) {
113
+ const projectsDir = path.join(os.homedir(), '.claude', 'projects');
114
+ const results = [];
115
+ try {
116
+ const entries = await fs.readdir(projectsDir, { withFileTypes: true });
117
+ for (const entry of entries) {
118
+ if (!entry.isDirectory())
119
+ continue;
120
+ const dirPath = path.join(projectsDir, entry.name);
121
+ const files = await fs.readdir(dirPath);
122
+ for (const file of files) {
123
+ if (!file.endsWith('.jsonl'))
124
+ continue;
125
+ const sessionId = file.slice(0, -'.jsonl'.length);
126
+ if (!isTrackableClaudeSession(sessionId))
127
+ continue;
128
+ const filePath = path.join(dirPath, file);
129
+ const cwdGuess = extractCwdFromPath(filePath);
130
+ if (isBlocklisted(cwdGuess))
131
+ continue;
132
+ if (await transcriptActiveOnDate(filePath, date)) {
133
+ results.push({ sessionId, filePath });
134
+ }
135
+ }
136
+ }
137
+ }
138
+ catch {
139
+ // projects dir missing
140
+ }
141
+ return results;
142
+ }
143
+ //# sourceMappingURL=transcript-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-sync.js","sourceRoot":"","sources":["../../src/stats/transcript-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAa9D,SAAS,cAAc,CAAC,KAA8B;IACpD,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAK,KAAK,CAAC,OAA+C,EAAE,SAAS,CAAC;IAChG,IAAI,OAAO,EAAE,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;IACvB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,WAAmB;IACnE,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACpC,IAAI,WAAW,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAgB,EAChB,IAAa;IAEb,IAAI,aAA+B,CAAC;IACpC,IAAI,YAA8B,CAAC;IACnC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;gBAC1D,IAAI,KAAK,CAAC,eAAe,KAAK,MAAM;oBAAE,SAAS,EAAE,CAAC;gBAElD,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;gBAChC,IAAI,CAAC,CAAC;oBAAE,SAAS;gBACjB,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;oBAAE,SAAS;gBAExD,IAAI,CAAC,aAAa,IAAI,CAAC,GAAG,aAAa;oBAAE,aAAa,GAAG,CAAC,CAAC;gBAC3D,IAAI,CAAC,YAAY,IAAI,CAAC,GAAG,YAAY;oBAAE,YAAY,GAAG,CAAC,CAAC;YAC1D,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACpD,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAgB,EAChB,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7D,IAAI,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,YAAY;QAAE,OAAO,MAAM,CAAC;IAE/D,MAAM,IAAI,GAAG,MAAM,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC;IAEjD,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,IAAI,CAAC,YAAY,IAAI,QAAQ,IAAI,IAAI,CAAC,aAAa,IAAI,MAAM,EAAE,CAAC;YAClE,OAAO;gBACL,aAAa,EAAE,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa;gBAC5E,YAAY,EAAE,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY;gBACrE,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAClD,OAAO;gBACL,aAAa,EAAE,QAAQ;gBACvB,YAAY,EAAE,QAAQ,CAAC,KAAK;gBAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,aAAa;IACf,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,QAAgB,EAAE,IAAY;IACzE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE/D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC/B,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,EAAE,SAAS,CAAC;gBACvD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;oBAAE,OAAO,IAAI,CAAC;YACjE,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAY;IACvD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACnE,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACvE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBAAE,SAAS;YAEnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAExC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBAEvC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAClD,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC;oBAAE,SAAS;gBAEnD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC1C,MAAM,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;gBAC9C,IAAI,aAAa,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBAEtC,IAAI,MAAM,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;oBACjD,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,uBAAuB;IACzB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { DailySummaryWirePayload } from './stats/summary-formatter.js';
1
2
  export interface HookPayload {
2
3
  session_id: string;
3
4
  transcript_path: string;
@@ -6,7 +7,7 @@ export interface HookPayload {
6
7
  notification_type?: string;
7
8
  message?: string;
8
9
  }
9
- export type AgentEventType = 'permission_prompt' | 'task_complete' | 'session_error' | 'idle_waiting' | 'session_started' | 'session_ended' | 'session_updated' | 'heartbeat' | 'full_sync';
10
+ export type AgentEventType = 'permission_prompt' | 'task_complete' | 'session_error' | 'idle_waiting' | 'session_started' | 'session_ended' | 'session_updated' | 'heartbeat' | 'full_sync' | 'daily_stats_update';
10
11
  export interface AgentEvent {
11
12
  type: AgentEventType;
12
13
  session_id: string;
@@ -19,6 +20,8 @@ export interface AgentEvent {
19
20
  tool_input?: string;
20
21
  timestamp: string;
21
22
  pid?: string;
23
+ /** Present only when type === 'daily_stats_update'. */
24
+ summary?: DailySummaryWirePayload;
22
25
  }
23
26
  export interface FullSyncEvent extends AgentEvent {
24
27
  type: 'full_sync';
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GACtB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,aAAa,GAAG,OAAO,GAAG,KAAK,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,oBAAoB,CAAC;AAEvG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5E,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,cAAc,GACtB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,eAAe,GACf,iBAAiB,GACjB,WAAW,GACX,WAAW,GACX,oBAAoB,CAAC;AAEzB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,aAAa,GAAG,OAAO,GAAG,KAAK,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACnC;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,oBAAoB,CAAC;AAEvG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -14,6 +14,10 @@ export interface Config {
14
14
  tunnel_url?: string;
15
15
  /** Phone's FCM registration token — enables direct push when the app is killed. */
16
16
  fcm_token?: string;
17
+ /** Hour (0-23, local time) the daily summary notification is sent. Defaults to 23. */
18
+ dailySummaryHour: number;
19
+ /** Minute (0-59, local time) the daily summary notification is sent. Defaults to 59. */
20
+ dailySummaryMinute: number;
17
21
  }
18
22
  export declare function createDefaultConfig(): Config;
19
23
  export declare function getConfig(): Promise<Config>;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAQ5C;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAajD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9D;AAQD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAEzD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,YAAY,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,gBAAgB,EAAE,MAAM,CAAC;IACzB,wFAAwF;IACxF,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAU5C;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAajD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9D;AAQD,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO1D;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC,CAEzD"}
@@ -14,6 +14,8 @@ export function createDefaultConfig() {
14
14
  ntfy_topic: `agentvigil-${randomBytes(16).toString('hex')}`,
15
15
  paired_devices: [],
16
16
  ws_port: 3847,
17
+ dailySummaryHour: 23,
18
+ dailySummaryMinute: 59,
17
19
  };
18
20
  }
19
21
  export async function getConfig() {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAqBzD,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,MAAM,EAAE;QACnB,UAAU,EAAE,cAAc,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAC3D,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAW,CAAC;IACnC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;YACzF,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,WAAW,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;QACrC,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,MAAM,aAAa,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpD,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACrC,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACtD,MAAM,CAAC,IAAI,CAAC,8FAA8F,CAAC,CAAC;IAC5G,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,aAAa,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAyBzD,MAAM,UAAU,mBAAmB;IACjC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,MAAM,EAAE;QACnB,UAAU,EAAE,cAAc,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;QAC3D,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,IAAI;QACb,gBAAgB,EAAE,EAAE;QACpB,kBAAkB,EAAE,EAAE;KACvB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAW,CAAC;IACnC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;YACzF,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,WAAW,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;QACrC,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,MAAM,aAAa,CAAC,aAAa,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpD,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACrC,MAAM,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACtD,MAAM,CAAC,IAAI,CAAC,8FAA8F,CAAC,CAAC;IAC5G,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,aAAa,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Prompts the user on stdin/stdout and resolves with their trimmed answer. */
2
+ export declare function promptUser(question: string): Promise<string>;
3
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAGA,+EAA+E;AAC/E,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlE"}
@@ -0,0 +1,14 @@
1
+ import readline from 'node:readline/promises';
2
+ import { stdin, stdout } from 'node:process';
3
+ /** Prompts the user on stdin/stdout and resolves with their trimmed answer. */
4
+ export async function promptUser(question) {
5
+ const rl = readline.createInterface({ input: stdin, output: stdout });
6
+ try {
7
+ const answer = await rl.question(question);
8
+ return answer.trim();
9
+ }
10
+ finally {
11
+ rl.close();
12
+ }
13
+ }
14
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE7C,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC3C,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentvigil",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Fleet watchdog for AI coding agent sessions — monitor Claude Code, Codex and Amp from your phone",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -12,7 +12,7 @@
12
12
  "README.md",
13
13
  "LICENSE"
14
14
  ],
15
- "homepage": "https://agentvigil.app",
15
+ "homepage": "https://agentvigil.stacktreelabs.com/",
16
16
  "bugs": {
17
17
  "url": "https://github.com/mdusaama0/agentvigil-mac/issues"
18
18
  },