@telepat/snoopy 0.1.4

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +255 -0
  3. package/dist/src/cli/commands/analytics.d.ts +3 -0
  4. package/dist/src/cli/commands/analytics.js +147 -0
  5. package/dist/src/cli/commands/analytics.js.map +1 -0
  6. package/dist/src/cli/commands/daemon.d.ts +5 -0
  7. package/dist/src/cli/commands/daemon.js +85 -0
  8. package/dist/src/cli/commands/daemon.js.map +1 -0
  9. package/dist/src/cli/commands/doctor.d.ts +1 -0
  10. package/dist/src/cli/commands/doctor.js +106 -0
  11. package/dist/src/cli/commands/doctor.js.map +1 -0
  12. package/dist/src/cli/commands/errors.d.ts +3 -0
  13. package/dist/src/cli/commands/errors.js +51 -0
  14. package/dist/src/cli/commands/errors.js.map +1 -0
  15. package/dist/src/cli/commands/export.d.ts +1 -0
  16. package/dist/src/cli/commands/export.js +48 -0
  17. package/dist/src/cli/commands/export.js.map +1 -0
  18. package/dist/src/cli/commands/job.d.ts +16 -0
  19. package/dist/src/cli/commands/job.js +350 -0
  20. package/dist/src/cli/commands/job.js.map +1 -0
  21. package/dist/src/cli/commands/logs.d.ts +3 -0
  22. package/dist/src/cli/commands/logs.js +44 -0
  23. package/dist/src/cli/commands/logs.js.map +1 -0
  24. package/dist/src/cli/commands/selection.d.ts +19 -0
  25. package/dist/src/cli/commands/selection.js +182 -0
  26. package/dist/src/cli/commands/selection.js.map +1 -0
  27. package/dist/src/cli/commands/settings.d.ts +1 -0
  28. package/dist/src/cli/commands/settings.js +31 -0
  29. package/dist/src/cli/commands/settings.js.map +1 -0
  30. package/dist/src/cli/commands/startup.d.ts +5 -0
  31. package/dist/src/cli/commands/startup.js +26 -0
  32. package/dist/src/cli/commands/startup.js.map +1 -0
  33. package/dist/src/cli/flows/jobAddFlow.d.ts +26 -0
  34. package/dist/src/cli/flows/jobAddFlow.js +209 -0
  35. package/dist/src/cli/flows/jobAddFlow.js.map +1 -0
  36. package/dist/src/cli/flows/settingsFlow.d.ts +15 -0
  37. package/dist/src/cli/flows/settingsFlow.js +180 -0
  38. package/dist/src/cli/flows/settingsFlow.js.map +1 -0
  39. package/dist/src/cli/flows/settingsFlowModel.d.ts +47 -0
  40. package/dist/src/cli/flows/settingsFlowModel.js +143 -0
  41. package/dist/src/cli/flows/settingsFlowModel.js.map +1 -0
  42. package/dist/src/cli/index.d.ts +2 -0
  43. package/dist/src/cli/index.js +138 -0
  44. package/dist/src/cli/index.js.map +1 -0
  45. package/dist/src/cli/ui/consoleUi.d.ts +13 -0
  46. package/dist/src/cli/ui/consoleUi.js +165 -0
  47. package/dist/src/cli/ui/consoleUi.js.map +1 -0
  48. package/dist/src/cli/ui/time.d.ts +9 -0
  49. package/dist/src/cli/ui/time.js +35 -0
  50. package/dist/src/cli/ui/time.js.map +1 -0
  51. package/dist/src/index.d.ts +1 -0
  52. package/dist/src/index.js +2 -0
  53. package/dist/src/index.js.map +1 -0
  54. package/dist/src/scripts/e2eSmoke.d.ts +1 -0
  55. package/dist/src/scripts/e2eSmoke.js +102 -0
  56. package/dist/src/scripts/e2eSmoke.js.map +1 -0
  57. package/dist/src/services/analytics/analyticsService.d.ts +50 -0
  58. package/dist/src/services/analytics/analyticsService.js +88 -0
  59. package/dist/src/services/analytics/analyticsService.js.map +1 -0
  60. package/dist/src/services/daemonControl.d.ts +12 -0
  61. package/dist/src/services/daemonControl.js +58 -0
  62. package/dist/src/services/daemonControl.js.map +1 -0
  63. package/dist/src/services/db/repositories/jobsRepo.d.ts +19 -0
  64. package/dist/src/services/db/repositories/jobsRepo.js +164 -0
  65. package/dist/src/services/db/repositories/jobsRepo.js.map +1 -0
  66. package/dist/src/services/db/repositories/runsRepo.d.ts +58 -0
  67. package/dist/src/services/db/repositories/runsRepo.js +190 -0
  68. package/dist/src/services/db/repositories/runsRepo.js.map +1 -0
  69. package/dist/src/services/db/repositories/scanItemsRepo.d.ts +69 -0
  70. package/dist/src/services/db/repositories/scanItemsRepo.js +176 -0
  71. package/dist/src/services/db/repositories/scanItemsRepo.js.map +1 -0
  72. package/dist/src/services/db/repositories/settingsRepo.d.ts +14 -0
  73. package/dist/src/services/db/repositories/settingsRepo.js +132 -0
  74. package/dist/src/services/db/repositories/settingsRepo.js.map +1 -0
  75. package/dist/src/services/db/sqlite.d.ts +2 -0
  76. package/dist/src/services/db/sqlite.js +192 -0
  77. package/dist/src/services/db/sqlite.js.map +1 -0
  78. package/dist/src/services/export/csvResults.d.ts +10 -0
  79. package/dist/src/services/export/csvResults.js +42 -0
  80. package/dist/src/services/export/csvResults.js.map +1 -0
  81. package/dist/src/services/logging/logReader.d.ts +4 -0
  82. package/dist/src/services/logging/logReader.js +230 -0
  83. package/dist/src/services/logging/logReader.js.map +1 -0
  84. package/dist/src/services/logging/logRotation.d.ts +1 -0
  85. package/dist/src/services/logging/logRotation.js +30 -0
  86. package/dist/src/services/logging/logRotation.js.map +1 -0
  87. package/dist/src/services/logging/runLogger.d.ts +9 -0
  88. package/dist/src/services/logging/runLogger.js +42 -0
  89. package/dist/src/services/logging/runLogger.js.map +1 -0
  90. package/dist/src/services/openrouter/client.d.ts +60 -0
  91. package/dist/src/services/openrouter/client.js +437 -0
  92. package/dist/src/services/openrouter/client.js.map +1 -0
  93. package/dist/src/services/openrouter/prompts.d.ts +5 -0
  94. package/dist/src/services/openrouter/prompts.js +48 -0
  95. package/dist/src/services/openrouter/prompts.js.map +1 -0
  96. package/dist/src/services/reddit/client.d.ts +25 -0
  97. package/dist/src/services/reddit/client.js +186 -0
  98. package/dist/src/services/reddit/client.js.map +1 -0
  99. package/dist/src/services/scheduler/cronScheduler.d.ts +11 -0
  100. package/dist/src/services/scheduler/cronScheduler.js +76 -0
  101. package/dist/src/services/scheduler/cronScheduler.js.map +1 -0
  102. package/dist/src/services/scheduler/jobRunner.d.ts +76 -0
  103. package/dist/src/services/scheduler/jobRunner.js +414 -0
  104. package/dist/src/services/scheduler/jobRunner.js.map +1 -0
  105. package/dist/src/services/scheduler/jobRunnerStub.d.ts +5 -0
  106. package/dist/src/services/scheduler/jobRunnerStub.js +11 -0
  107. package/dist/src/services/scheduler/jobRunnerStub.js.map +1 -0
  108. package/dist/src/services/security/secretStore.d.ts +6 -0
  109. package/dist/src/services/security/secretStore.js +193 -0
  110. package/dist/src/services/security/secretStore.js.map +1 -0
  111. package/dist/src/services/startup/index.d.ts +13 -0
  112. package/dist/src/services/startup/index.js +120 -0
  113. package/dist/src/services/startup/index.js.map +1 -0
  114. package/dist/src/services/startup/linuxCronFallback.d.ts +2 -0
  115. package/dist/src/services/startup/linuxCronFallback.js +29 -0
  116. package/dist/src/services/startup/linuxCronFallback.js.map +1 -0
  117. package/dist/src/services/startup/linuxSystemd.d.ts +3 -0
  118. package/dist/src/services/startup/linuxSystemd.js +47 -0
  119. package/dist/src/services/startup/linuxSystemd.js.map +1 -0
  120. package/dist/src/services/startup/macosLaunchd.d.ts +2 -0
  121. package/dist/src/services/startup/macosLaunchd.js +40 -0
  122. package/dist/src/services/startup/macosLaunchd.js.map +1 -0
  123. package/dist/src/services/startup/windowsRunFallback.d.ts +2 -0
  124. package/dist/src/services/startup/windowsRunFallback.js +17 -0
  125. package/dist/src/services/startup/windowsRunFallback.js.map +1 -0
  126. package/dist/src/services/startup/windowsTaskScheduler.d.ts +2 -0
  127. package/dist/src/services/startup/windowsTaskScheduler.js +16 -0
  128. package/dist/src/services/startup/windowsTaskScheduler.js.map +1 -0
  129. package/dist/src/types/job.d.ts +34 -0
  130. package/dist/src/types/job.js +2 -0
  131. package/dist/src/types/job.js.map +1 -0
  132. package/dist/src/types/settings.d.ts +35 -0
  133. package/dist/src/types/settings.js +8 -0
  134. package/dist/src/types/settings.js.map +1 -0
  135. package/dist/src/ui/components/AppFrame.d.ts +17 -0
  136. package/dist/src/ui/components/AppFrame.js +26 -0
  137. package/dist/src/ui/components/AppFrame.js.map +1 -0
  138. package/dist/src/ui/components/CliHeader.d.ts +8 -0
  139. package/dist/src/ui/components/CliHeader.js +8 -0
  140. package/dist/src/ui/components/CliHeader.js.map +1 -0
  141. package/dist/src/ui/components/SubredditMultiSelect.d.ts +7 -0
  142. package/dist/src/ui/components/SubredditMultiSelect.js +91 -0
  143. package/dist/src/ui/components/SubredditMultiSelect.js.map +1 -0
  144. package/dist/src/ui/components/TextPrompt.d.ts +10 -0
  145. package/dist/src/ui/components/TextPrompt.js +13 -0
  146. package/dist/src/ui/components/TextPrompt.js.map +1 -0
  147. package/dist/src/ui/components/YesNoSelector.d.ts +10 -0
  148. package/dist/src/ui/components/YesNoSelector.js +25 -0
  149. package/dist/src/ui/components/YesNoSelector.js.map +1 -0
  150. package/dist/src/ui/components/subredditOptions.d.ts +5 -0
  151. package/dist/src/ui/components/subredditOptions.js +14 -0
  152. package/dist/src/ui/components/subredditOptions.js.map +1 -0
  153. package/dist/src/ui/components/yesNoSelectorModel.d.ts +9 -0
  154. package/dist/src/ui/components/yesNoSelectorModel.js +23 -0
  155. package/dist/src/ui/components/yesNoSelectorModel.js.map +1 -0
  156. package/dist/src/ui/theme.d.ts +26 -0
  157. package/dist/src/ui/theme.js +37 -0
  158. package/dist/src/ui/theme.js.map +1 -0
  159. package/dist/src/utils/logger.d.ts +5 -0
  160. package/dist/src/utils/logger.js +15 -0
  161. package/dist/src/utils/logger.js.map +1 -0
  162. package/dist/src/utils/notify.d.ts +6 -0
  163. package/dist/src/utils/notify.js +14 -0
  164. package/dist/src/utils/notify.js.map +1 -0
  165. package/dist/src/utils/paths.d.ts +10 -0
  166. package/dist/src/utils/paths.js +24 -0
  167. package/dist/src/utils/paths.js.map +1 -0
  168. package/dist/src/utils/scanLogFormatting.d.ts +26 -0
  169. package/dist/src/utils/scanLogFormatting.js +60 -0
  170. package/dist/src/utils/scanLogFormatting.js.map +1 -0
  171. package/package.json +74 -0
@@ -0,0 +1,180 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from 'react';
3
+ import { Box, Text, useApp, useInput } from 'ink';
4
+ import { TextPrompt } from '../../ui/components/TextPrompt.js';
5
+ import { YesNoSelector } from '../../ui/components/YesNoSelector.js';
6
+ import { AppFrame, Panel } from '../../ui/components/AppFrame.js';
7
+ import { uiTheme } from '../../ui/theme.js';
8
+ import { buildSettingsMenuItems, buildSettingsSaveResult, createSettingsDraft } from './settingsFlowModel.js';
9
+ function SettingsFrame({ children, statusText, statusTone = 'info' }) {
10
+ return (_jsx(AppFrame, { subtitle: "Settings", statusText: statusText, statusTone: statusTone, hints: ['Up/Down: move', 'Enter: select/confirm', 'Esc: cancel or exit'], children: children }));
11
+ }
12
+ function labelForSettingKey(key) {
13
+ switch (key) {
14
+ case 'apiKey':
15
+ return 'Set new OpenRouter API key (leave blank to keep current)';
16
+ case 'model':
17
+ return 'Default model';
18
+ case 'temperature':
19
+ return 'Temperature (0.0 - 2.0)';
20
+ case 'maxTokens':
21
+ return 'Max tokens';
22
+ case 'topP':
23
+ return 'Top P (0.0 - 1.0)';
24
+ case 'cronIntervalMinutes':
25
+ return 'Scan interval in minutes (e.g. 30)';
26
+ case 'jobTimeoutMinutes':
27
+ return 'Job timeout in minutes (0 = no timeout)';
28
+ case 'notificationsEnabled':
29
+ return 'Show desktop notifications';
30
+ case 'redditAppName':
31
+ return 'Reddit app name for OAuth fallback';
32
+ case 'redditClientId':
33
+ return 'Reddit client ID for OAuth fallback';
34
+ case 'redditClientSecret':
35
+ return 'Reddit client secret for OAuth fallback (leave blank to keep current)';
36
+ }
37
+ }
38
+ function keyToDraftField(key) {
39
+ switch (key) {
40
+ case 'model':
41
+ return 'model';
42
+ case 'temperature':
43
+ return 'temperature';
44
+ case 'maxTokens':
45
+ return 'maxTokens';
46
+ case 'topP':
47
+ return 'topP';
48
+ case 'cronIntervalMinutes':
49
+ return 'cronIntervalMinutes';
50
+ case 'jobTimeoutMinutes':
51
+ return 'jobTimeoutMinutes';
52
+ case 'notificationsEnabled':
53
+ return 'notificationsEnabled';
54
+ case 'redditAppName':
55
+ return 'redditAppName';
56
+ case 'redditClientId':
57
+ return 'redditClientId';
58
+ }
59
+ }
60
+ export function SettingsFlow({ current, currentRedditCredentials, currentApiKey, onDone }) {
61
+ const { exit } = useApp();
62
+ const [mode, setMode] = useState('menu');
63
+ const [cursor, setCursor] = useState(0);
64
+ const [menuError, setMenuError] = useState(null);
65
+ const [draft, setDraft] = useState(() => createSettingsDraft(current, currentRedditCredentials));
66
+ const [draftSecrets, setDraftSecrets] = useState({});
67
+ const [editingKey, setEditingKey] = useState(null);
68
+ const [clearedFields, setClearedFields] = useState(new Set());
69
+ const menuItems = useMemo(() => buildSettingsMenuItems({
70
+ draft,
71
+ draftSecrets,
72
+ currentApiKey,
73
+ hasCurrentRedditClientSecret: currentRedditCredentials.hasClientSecret,
74
+ clearedFields
75
+ }), [currentApiKey, currentRedditCredentials.hasClientSecret, draft, draftSecrets, clearedFields]);
76
+ useInput((_, key) => {
77
+ if (mode === 'edit' && editingKey === 'notificationsEnabled') {
78
+ if (key.return) {
79
+ setDraft((prev) => ({ ...prev, notificationsEnabled: !prev.notificationsEnabled }));
80
+ setMode('menu');
81
+ setEditingKey(null);
82
+ }
83
+ else if (key.escape) {
84
+ setMode('menu');
85
+ setEditingKey(null);
86
+ }
87
+ return;
88
+ }
89
+ if (mode !== 'menu') {
90
+ return;
91
+ }
92
+ if (key.upArrow) {
93
+ setCursor((prev) => (prev - 1 + menuItems.length) % menuItems.length);
94
+ return;
95
+ }
96
+ if (key.downArrow) {
97
+ setCursor((prev) => (prev + 1) % menuItems.length);
98
+ return;
99
+ }
100
+ if (key.escape) {
101
+ exit();
102
+ return;
103
+ }
104
+ if (!key.return) {
105
+ return;
106
+ }
107
+ const selected = menuItems[cursor];
108
+ if (!selected) {
109
+ return;
110
+ }
111
+ if (selected.key === 'cancel') {
112
+ exit();
113
+ return;
114
+ }
115
+ if (selected.key === 'save') {
116
+ const saveResult = buildSettingsSaveResult(draft, draftSecrets, currentRedditCredentials, clearedFields);
117
+ if (!saveResult.ok) {
118
+ setMenuError(saveResult.error);
119
+ return;
120
+ }
121
+ onDone(saveResult.result);
122
+ exit();
123
+ return;
124
+ }
125
+ setMenuError(null);
126
+ setEditingKey(selected.key);
127
+ setMode('edit');
128
+ });
129
+ if (mode === 'menu') {
130
+ return (_jsx(SettingsFrame, { statusText: menuError ?? 'Ready', statusTone: menuError ? 'danger' : 'info', children: _jsxs(Panel, { title: "Settings Menu", children: [_jsx(Text, { color: uiTheme.ink.accent, children: "Choose a setting to edit. Press Enter to select." }), _jsx(Text, { color: uiTheme.ink.textMuted, children: "Use Up/Down arrows to navigate. Esc or Cancel exits without saving." }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: menuItems.map((item, index) => {
131
+ const isCursor = index === cursor;
132
+ const value = item.summary ? `: ${item.summary}` : '';
133
+ return (_jsxs(Text, { color: isCursor ? uiTheme.ink.focus : uiTheme.ink.textPrimary, inverse: isCursor, children: [isCursor ? '>' : ' ', " ", item.label, value] }, item.key));
134
+ }) })] }) }));
135
+ }
136
+ if (mode === 'confirmClear' && editingKey) {
137
+ return (_jsx(SettingsFrame, { statusText: "Confirm field clear", statusTone: "warning", children: _jsx(Panel, { title: "Confirmation", children: _jsx(YesNoSelector, { label: "Clear this field?", defaultValue: false, onSubmit: (shouldClear) => {
138
+ if (shouldClear) {
139
+ setClearedFields((prev) => new Set([...prev, editingKey]));
140
+ }
141
+ setMode('menu');
142
+ setEditingKey(null);
143
+ } }) }) }));
144
+ }
145
+ if (!editingKey) {
146
+ return (_jsx(SettingsFrame, { statusText: "No setting selected", statusTone: "danger", children: _jsx(Panel, { title: "Error", children: _jsx(Text, { color: uiTheme.ink.danger, children: "No setting selected. Press Esc to exit." }) }) }));
147
+ }
148
+ const isSecret = editingKey === 'apiKey' || editingKey === 'redditClientSecret';
149
+ if (editingKey === 'notificationsEnabled') {
150
+ return (_jsx(SettingsFrame, { statusText: "Toggle notifications", statusTone: "info", children: _jsxs(Panel, { title: "Edit Setting", children: [_jsxs(Text, { children: [labelForSettingKey(editingKey), ": ", draft.notificationsEnabled ? 'Enabled' : 'Disabled'] }), _jsx(Text, { color: uiTheme.ink.textMuted, children: "Press Enter to toggle, Esc to cancel." })] }) }));
151
+ }
152
+ const initialValue = editingKey === 'apiKey' || editingKey === 'redditClientSecret'
153
+ ? ''
154
+ : draft[keyToDraftField(editingKey)];
155
+ const fieldHasCurrentValue = Boolean(initialValue);
156
+ const helpText = fieldHasCurrentValue ? 'Press Enter with empty value to clear' : 'Press Enter to continue';
157
+ return (_jsx(SettingsFrame, { statusText: "Editing setting", statusTone: "info", children: _jsxs(Panel, { title: "Edit Setting", children: [_jsx(TextPrompt, { label: labelForSettingKey(editingKey), initialValue: initialValue, secret: isSecret, onSubmit: (value) => {
158
+ if (value === '' && fieldHasCurrentValue && editingKey !== 'model') {
159
+ setMode('confirmClear');
160
+ return;
161
+ }
162
+ if (editingKey === 'apiKey') {
163
+ if (value) {
164
+ setDraftSecrets((prev) => ({ ...prev, apiKey: value }));
165
+ }
166
+ }
167
+ else if (editingKey === 'redditClientSecret') {
168
+ if (value) {
169
+ setDraftSecrets((prev) => ({ ...prev, redditClientSecret: value }));
170
+ }
171
+ }
172
+ else if (value) {
173
+ const field = keyToDraftField(editingKey);
174
+ setDraft((prev) => ({ ...prev, [field]: value }));
175
+ }
176
+ setMode('menu');
177
+ setEditingKey(null);
178
+ } }), !isSecret ? _jsx(Text, { color: uiTheme.ink.textMuted, children: helpText }) : null] }) }));
179
+ }
180
+ //# sourceMappingURL=settingsFlow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settingsFlow.js","sourceRoot":"","sources":["../../../../src/cli/flows/settingsFlow.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { type AppSettings, type RedditCredentialState, type RedditCredentialsUpdate } from '../../types/settings.js';
2
+ export type EditableSettingKey = 'apiKey' | 'model' | 'temperature' | 'maxTokens' | 'topP' | 'cronIntervalMinutes' | 'jobTimeoutMinutes' | 'notificationsEnabled' | 'redditAppName' | 'redditClientId' | 'redditClientSecret';
3
+ export interface SettingsDraft {
4
+ model: string;
5
+ temperature: string;
6
+ maxTokens: string;
7
+ topP: string;
8
+ cronIntervalMinutes: string;
9
+ jobTimeoutMinutes: string;
10
+ notificationsEnabled: boolean;
11
+ redditAppName: string;
12
+ redditClientId: string;
13
+ }
14
+ export interface SettingsDraftSecrets {
15
+ apiKey?: string;
16
+ redditClientSecret?: string;
17
+ }
18
+ interface BuildMenuItemsInput {
19
+ draft: SettingsDraft;
20
+ draftSecrets: SettingsDraftSecrets;
21
+ currentApiKey: string | null;
22
+ hasCurrentRedditClientSecret: boolean;
23
+ clearedFields?: Set<EditableSettingKey>;
24
+ }
25
+ export interface SettingsMenuItem {
26
+ key: EditableSettingKey | 'save' | 'cancel';
27
+ label: string;
28
+ summary: string;
29
+ editable: boolean;
30
+ }
31
+ interface SettingsSaveResult {
32
+ apiKey?: string;
33
+ redditCredentials?: RedditCredentialsUpdate;
34
+ settings: AppSettings;
35
+ }
36
+ type SaveResult = {
37
+ ok: true;
38
+ result: SettingsSaveResult;
39
+ } | {
40
+ ok: false;
41
+ error: string;
42
+ };
43
+ export declare function maskSecret(value: string, visibleChars?: number): string;
44
+ export declare function createSettingsDraft(current: AppSettings, currentRedditCredentials: RedditCredentialState): SettingsDraft;
45
+ export declare function buildSettingsMenuItems({ draft, draftSecrets, currentApiKey, hasCurrentRedditClientSecret, clearedFields }: BuildMenuItemsInput): SettingsMenuItem[];
46
+ export declare function buildSettingsSaveResult(draft: SettingsDraft, draftSecrets: SettingsDraftSecrets, currentRedditCredentials: RedditCredentialState, clearedFields?: Set<EditableSettingKey>): SaveResult;
47
+ export {};
@@ -0,0 +1,143 @@
1
+ import { DEFAULT_JOB_TIMEOUT_MS } from '../../types/settings.js';
2
+ function parseRequiredNumber(value) {
3
+ if (!value.trim()) {
4
+ return null;
5
+ }
6
+ const parsed = Number(value);
7
+ return Number.isFinite(parsed) ? parsed : null;
8
+ }
9
+ function parseRequiredInteger(value) {
10
+ const parsed = parseRequiredNumber(value);
11
+ if (parsed === null || !Number.isInteger(parsed)) {
12
+ return null;
13
+ }
14
+ return parsed;
15
+ }
16
+ export function maskSecret(value, visibleChars = 4) {
17
+ const trimmed = value.trim();
18
+ if (!trimmed) {
19
+ return '';
20
+ }
21
+ if (trimmed.length <= visibleChars) {
22
+ return '*'.repeat(trimmed.length);
23
+ }
24
+ return `****${trimmed.slice(-visibleChars)}`;
25
+ }
26
+ export function createSettingsDraft(current, currentRedditCredentials) {
27
+ return {
28
+ model: current.model,
29
+ temperature: String(current.modelSettings.temperature),
30
+ maxTokens: String(current.modelSettings.maxTokens),
31
+ topP: String(current.modelSettings.topP),
32
+ cronIntervalMinutes: String(current.cronIntervalMinutes),
33
+ jobTimeoutMinutes: String(Math.round((current.jobTimeoutMs ?? DEFAULT_JOB_TIMEOUT_MS) / 60000)),
34
+ notificationsEnabled: current.notificationsEnabled ?? true,
35
+ redditAppName: currentRedditCredentials.appName,
36
+ redditClientId: currentRedditCredentials.clientId
37
+ };
38
+ }
39
+ export function buildSettingsMenuItems({ draft, draftSecrets, currentApiKey, hasCurrentRedditClientSecret, clearedFields = new Set() }) {
40
+ const apiKeySummary = draftSecrets.apiKey
41
+ ? `Will update (${maskSecret(draftSecrets.apiKey)})`
42
+ : currentApiKey
43
+ ? `Configured (${maskSecret(currentApiKey)})`
44
+ : 'Missing';
45
+ const redditClientIdSummary = clearedFields.has('redditClientId')
46
+ ? 'Cleared'
47
+ : draft.redditClientId
48
+ ? `Configured (${maskSecret(draft.redditClientId)})`
49
+ : 'Missing';
50
+ const redditAppNameSummary = clearedFields.has('redditAppName') ? 'Cleared' : draft.redditAppName || '(empty)';
51
+ const redditClientSecretSummary = draftSecrets.redditClientSecret
52
+ ? 'Will update (hidden)'
53
+ : hasCurrentRedditClientSecret
54
+ ? 'Configured (hidden)'
55
+ : 'Missing';
56
+ return [
57
+ { key: 'apiKey', label: 'OpenRouter API key', summary: apiKeySummary, editable: true },
58
+ { key: 'model', label: 'Default model', summary: draft.model || '(empty)', editable: true },
59
+ { key: 'temperature', label: 'Temperature', summary: draft.temperature, editable: true },
60
+ { key: 'maxTokens', label: 'Max tokens', summary: draft.maxTokens, editable: true },
61
+ { key: 'topP', label: 'Top P', summary: draft.topP, editable: true },
62
+ { key: 'cronIntervalMinutes', label: 'Scan interval', summary: `${draft.cronIntervalMinutes} minutes`, editable: true },
63
+ {
64
+ key: 'jobTimeoutMinutes',
65
+ label: 'Job timeout',
66
+ summary: draft.jobTimeoutMinutes === '0' ? 'No timeout' : `${draft.jobTimeoutMinutes} minutes`,
67
+ editable: true
68
+ },
69
+ {
70
+ key: 'notificationsEnabled',
71
+ label: 'Show desktop notifications',
72
+ summary: draft.notificationsEnabled ? 'Enabled' : 'Disabled',
73
+ editable: true
74
+ },
75
+ { key: 'redditAppName', label: 'Reddit app name', summary: redditAppNameSummary, editable: true },
76
+ { key: 'redditClientId', label: 'Reddit client ID', summary: redditClientIdSummary, editable: true },
77
+ {
78
+ key: 'redditClientSecret',
79
+ label: 'Reddit client secret',
80
+ summary: redditClientSecretSummary,
81
+ editable: true
82
+ },
83
+ { key: 'save', label: 'Save changes', summary: '', editable: false },
84
+ { key: 'cancel', label: 'Cancel', summary: '', editable: false }
85
+ ];
86
+ }
87
+ export function buildSettingsSaveResult(draft, draftSecrets, currentRedditCredentials, clearedFields = new Set()) {
88
+ const model = draft.model.trim();
89
+ if (!model) {
90
+ return { ok: false, error: 'Model cannot be empty.' };
91
+ }
92
+ const temperature = parseRequiredNumber(draft.temperature);
93
+ if (temperature === null || temperature < 0 || temperature > 2) {
94
+ return { ok: false, error: 'Temperature must be a number from 0.0 to 2.0.' };
95
+ }
96
+ const maxTokens = parseRequiredInteger(draft.maxTokens);
97
+ if (maxTokens === null || maxTokens <= 0) {
98
+ return { ok: false, error: 'Max tokens must be a positive integer.' };
99
+ }
100
+ const topP = parseRequiredNumber(draft.topP);
101
+ if (topP === null || topP < 0 || topP > 1) {
102
+ return { ok: false, error: 'Top P must be a number from 0.0 to 1.0.' };
103
+ }
104
+ const cronIntervalMinutes = parseRequiredInteger(draft.cronIntervalMinutes);
105
+ if (cronIntervalMinutes === null || cronIntervalMinutes < 1) {
106
+ return { ok: false, error: 'Scan interval must be an integer greater than or equal to 1.' };
107
+ }
108
+ const jobTimeoutMinutes = parseRequiredInteger(draft.jobTimeoutMinutes);
109
+ if (jobTimeoutMinutes === null || jobTimeoutMinutes < 0) {
110
+ return { ok: false, error: 'Job timeout must be an integer greater than or equal to 0.' };
111
+ }
112
+ const redditCredentials = {
113
+ appName: clearedFields.has('redditAppName') ? '' : draft.redditAppName.trim(),
114
+ clientId: clearedFields.has('redditClientId') ? '' : draft.redditClientId.trim(),
115
+ ...(draftSecrets.redditClientSecret
116
+ ? { clientSecret: draftSecrets.redditClientSecret }
117
+ : {})
118
+ };
119
+ const hasRedditCredentialChange = redditCredentials.appName !== currentRedditCredentials.appName ||
120
+ redditCredentials.clientId !== currentRedditCredentials.clientId ||
121
+ Boolean(redditCredentials.clientSecret) ||
122
+ clearedFields.has('redditAppName') ||
123
+ clearedFields.has('redditClientId');
124
+ return {
125
+ ok: true,
126
+ result: {
127
+ ...(draftSecrets.apiKey ? { apiKey: draftSecrets.apiKey } : {}),
128
+ ...(hasRedditCredentialChange ? { redditCredentials } : {}),
129
+ settings: {
130
+ model,
131
+ modelSettings: {
132
+ temperature,
133
+ maxTokens,
134
+ topP
135
+ },
136
+ cronIntervalMinutes,
137
+ jobTimeoutMs: Math.round(jobTimeoutMinutes * 60000),
138
+ notificationsEnabled: !!draft.notificationsEnabled
139
+ }
140
+ }
141
+ };
142
+ }
143
+ //# sourceMappingURL=settingsFlowModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settingsFlowModel.js","sourceRoot":"","sources":["../../../../src/cli/flows/settingsFlowModel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'module';
3
+ import { Command } from 'commander';
4
+ import { addJob, disableJob, enableJob, listJobRuns, listJobs, removeJob, runJobNow } from './commands/job.js';
5
+ import { openSettings } from './commands/settings.js';
6
+ import { daemonReload, daemonRun, daemonStart, daemonStatus, daemonStop } from './commands/daemon.js';
7
+ import { showRunLogs } from './commands/logs.js';
8
+ import { showJobErrors } from './commands/errors.js';
9
+ import { exportCsv } from './commands/export.js';
10
+ import { showAnalytics } from './commands/analytics.js';
11
+ import { disableStartupCommand, enableStartupCommand, installStartupCommand, startupStatusCommand, uninstallStartupCommand } from './commands/startup.js';
12
+ import { runDoctor } from './commands/doctor.js';
13
+ import { ensureAppDirs } from '../utils/paths.js';
14
+ ensureAppDirs();
15
+ // Resolve the package version from package.json at runtime so the CLI always
16
+ // reports the version that release-please stamped into package.json.
17
+ // Two depths are tried because the source file lives at src/cli/ (2 up) while
18
+ // the compiled output lives at dist/src/cli/ (3 up).
19
+ const _require = createRequire(import.meta.url);
20
+ function readVersion() {
21
+ for (const rel of ['../../../package.json', '../../package.json']) {
22
+ try {
23
+ const pkg = _require(rel);
24
+ if (pkg.name === 'snoopy-cli')
25
+ return pkg.version ?? '0.0.0';
26
+ }
27
+ catch { /* try next depth */ }
28
+ }
29
+ return '0.0.0';
30
+ }
31
+ function parsePositiveInteger(value) {
32
+ const parsed = Number.parseInt(value, 10);
33
+ if (!Number.isInteger(parsed) || parsed <= 0) {
34
+ throw new Error(`Expected a positive integer, received: ${value}`);
35
+ }
36
+ return parsed;
37
+ }
38
+ const program = new Command();
39
+ program.name('snoopy').description('Monitor Reddit conversations with natural language job definitions.').version(readVersion());
40
+ const job = program.command('job').description('Manage monitoring jobs');
41
+ job.command('add').description('Add a monitoring job').action(async () => {
42
+ await addJob();
43
+ });
44
+ job.command('list').description('List monitoring jobs').action(listJobs);
45
+ job.command('remove').argument('[jobRef]', 'Job ID or slug').description('Remove a job').action(removeJob);
46
+ job.command('delete').argument('[jobRef]', 'Job ID or slug').description('Delete a job').action(removeJob);
47
+ job.command('enable').argument('[jobRef]', 'Job ID or slug').description('Enable a job').action(enableJob);
48
+ job.command('disable').argument('[jobRef]', 'Job ID or slug').description('Disable a job').action(disableJob);
49
+ job
50
+ .command('run')
51
+ .argument('[jobRef]', 'Job ID or slug')
52
+ .description('Run a job immediately')
53
+ .option('-l, --limit <count>', 'Maximum number of new post/comment items to qualify', parsePositiveInteger)
54
+ .action(async (jobRef, options) => {
55
+ await runJobNow(jobRef, options);
56
+ });
57
+ job.command('runs').argument('[jobRef]', 'Optional job ID or slug').description('List recent run history').action(listJobRuns);
58
+ const jobs = program.command('jobs').description('Alias for job commands');
59
+ jobs.command('list').description('List monitoring jobs').action(listJobs);
60
+ jobs.command('enable').argument('[jobRef]', 'Job ID or slug').description('Enable a job').action(enableJob);
61
+ jobs.command('disable').argument('[jobRef]', 'Job ID or slug').description('Disable a job').action(disableJob);
62
+ jobs.command('remove').argument('[jobRef]', 'Job ID or slug').description('Remove a job').action(removeJob);
63
+ jobs.command('delete').argument('[jobRef]', 'Job ID or slug').description('Delete a job').action(removeJob);
64
+ jobs
65
+ .command('run')
66
+ .argument('[jobRef]', 'Job ID or slug')
67
+ .description('Run a job immediately')
68
+ .option('-l, --limit <count>', 'Maximum number of new post/comment items to qualify', parsePositiveInteger)
69
+ .action(async (jobRef, options) => {
70
+ await runJobNow(jobRef, options);
71
+ });
72
+ jobs.command('runs').argument('[jobRef]', 'Optional job ID or slug').description('List recent run history').action(listJobRuns);
73
+ program.command('add').description('Alias for job add').action(async () => {
74
+ await addJob();
75
+ });
76
+ program.command('list').description('Alias for jobs list').action(listJobs);
77
+ program.command('delete').argument('[jobRef]', 'Job ID or slug').description('Alias for job delete').action(removeJob);
78
+ program.command('start').argument('[jobRef]', 'Job ID or slug').description('Enable a job').action(enableJob);
79
+ program.command('stop').argument('[jobRef]', 'Job ID or slug').description('Disable a job').action(disableJob);
80
+ program.command('settings').description('Update API key/model/model settings').action(async () => {
81
+ await openSettings();
82
+ });
83
+ const daemon = program.command('daemon').description('Manage Snoopy daemon');
84
+ daemon.command('start').description('Start daemon in background').action(daemonStart);
85
+ daemon.command('stop').description('Stop daemon').action(daemonStop);
86
+ daemon.command('status').description('Show daemon status').action(daemonStatus);
87
+ daemon.command('reload').description('Reload daemon schedules').action(daemonReload);
88
+ daemon.command('run').description('Run daemon in foreground').action(daemonRun);
89
+ const startup = program.command('startup').description('Manage OS startup registration');
90
+ startup.command('install').description('Install startup registration').action(installStartupCommand);
91
+ startup.command('uninstall').description('Remove startup registration').action(uninstallStartupCommand);
92
+ startup.command('enable').description('Enable startup on reboot/login').action(enableStartupCommand);
93
+ startup.command('disable').description('Disable startup on reboot/login').action(disableStartupCommand);
94
+ startup.command('status').description('Show startup on reboot status').action(startupStatusCommand);
95
+ const reboot = program.command('reboot').description('Manage run-on-reboot behavior');
96
+ reboot.command('enable').description('Enable run on reboot/login').action(enableStartupCommand);
97
+ reboot.command('disable').description('Disable run on reboot/login').action(disableStartupCommand);
98
+ reboot.command('status').description('Show run-on-reboot status').action(startupStatusCommand);
99
+ program.command('doctor').description('Run health checks').action(async () => {
100
+ await runDoctor();
101
+ });
102
+ program
103
+ .command('logs')
104
+ .argument('[runId]', 'Run ID')
105
+ .description('Show pretty logs for a specific run')
106
+ .option('--raw', 'Show raw log file content without pretty formatting')
107
+ .action(async (runId, options) => {
108
+ await showRunLogs(runId, options);
109
+ });
110
+ program
111
+ .command('errors')
112
+ .argument('[jobRef]', 'Job ID or slug')
113
+ .description('Show recent errors for a specific job')
114
+ .option('--hours <count>', 'Look back this many hours', parsePositiveInteger)
115
+ .action(async (jobRef, options) => {
116
+ await showJobErrors(jobRef, options);
117
+ });
118
+ program
119
+ .command('analytics')
120
+ .argument('[jobRef]', 'Optional job ID or slug')
121
+ .description('Show analytics for all jobs or a single job')
122
+ .option('-d, --days <count>', 'Look back this many days', parsePositiveInteger)
123
+ .action((jobRef, options) => {
124
+ showAnalytics(jobRef, options);
125
+ });
126
+ const exportCommand = program.command('export').description('Export data artifacts');
127
+ exportCommand
128
+ .command('csv')
129
+ .argument('[jobRef]', 'Optional job ID or slug')
130
+ .description('Regenerate CSV qualified results for one job or all jobs')
131
+ .action((jobRef) => {
132
+ exportCsv(jobRef);
133
+ });
134
+ program.parseAsync(process.argv).catch((error) => {
135
+ console.error(`Error: ${String(error)}`);
136
+ process.exit(1);
137
+ });
138
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type CommentScanLineInput, type PostScanLineInput } from '../../utils/scanLogFormatting.js';
2
+ export declare function isRichTty(): boolean;
3
+ export declare function formatPostScanBlock(input: PostScanLineInput): string;
4
+ export declare function formatCommentScanBlock(input: CommentScanLineInput): string;
5
+ export declare function printCliHeader(subtitle?: string): void;
6
+ export declare function printCommandScreen(title: string, section?: string): void;
7
+ export declare function printSection(title: string): void;
8
+ export declare function printMuted(text: string): void;
9
+ export declare function printSuccess(text: string): void;
10
+ export declare function printWarning(text: string): void;
11
+ export declare function printError(text: string): void;
12
+ export declare function printInfo(text: string): void;
13
+ export declare function printKeyValue(key: string, value: string): void;