@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,182 @@
1
+ import { createInterface } from 'node:readline/promises';
2
+ import readline from 'node:readline';
3
+ import { printError, printInfo, printWarning } from '../ui/consoleUi.js';
4
+ import { formatRunDisplayLabel } from '../ui/time.js';
5
+ function truncateForTerminalRow(value, reservedColumns = 2) {
6
+ const totalColumns = process.stdout.columns ?? 120;
7
+ const maxColumns = Math.max(20, totalColumns - reservedColumns);
8
+ if (value.length <= maxColumns) {
9
+ return value;
10
+ }
11
+ if (maxColumns <= 3) {
12
+ return '.'.repeat(maxColumns);
13
+ }
14
+ return `${value.slice(0, maxColumns - 3)}...`;
15
+ }
16
+ async function promptFromStdin(message) {
17
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
18
+ try {
19
+ return await rl.question(message);
20
+ }
21
+ finally {
22
+ rl.close();
23
+ }
24
+ }
25
+ async function selectIndexWithArrowKeys(lines, kind) {
26
+ if (!process.stdin.isTTY || !process.stdout.isTTY || typeof process.stdin.setRawMode !== 'function') {
27
+ return null;
28
+ }
29
+ let cursor = 0;
30
+ let renderedLineCount = 0;
31
+ const render = () => {
32
+ if (renderedLineCount > 0) {
33
+ process.stdout.write(`\u001b[${renderedLineCount}F`);
34
+ }
35
+ const outputLines = [`Select ${kind} (up/down arrows + Enter, q to cancel):`];
36
+ lines.forEach((line, index) => {
37
+ const prefix = `${index === cursor ? '>' : ' '} `;
38
+ outputLines.push(`${prefix}${truncateForTerminalRow(line, prefix.length)}`);
39
+ });
40
+ process.stdout.write('\u001b[J');
41
+ process.stdout.write(`${outputLines.join('\n')}\n`);
42
+ renderedLineCount = outputLines.length;
43
+ };
44
+ return await new Promise((resolve) => {
45
+ const stdin = process.stdin;
46
+ const wasRawMode = stdin.isRaw;
47
+ const cleanup = () => {
48
+ stdin.off('keypress', onKeypress);
49
+ if (typeof stdin.setRawMode === 'function') {
50
+ stdin.setRawMode(Boolean(wasRawMode));
51
+ }
52
+ stdin.pause();
53
+ process.stdout.write('\u001b[?25h');
54
+ };
55
+ const finish = (value) => {
56
+ cleanup();
57
+ resolve(value);
58
+ };
59
+ const onKeypress = (_str, key) => {
60
+ if (key.ctrl && key.name === 'c') {
61
+ finish(null);
62
+ return;
63
+ }
64
+ if (key.name === 'up') {
65
+ cursor = cursor === 0 ? lines.length - 1 : cursor - 1;
66
+ render();
67
+ return;
68
+ }
69
+ if (key.name === 'down') {
70
+ cursor = cursor === lines.length - 1 ? 0 : cursor + 1;
71
+ render();
72
+ return;
73
+ }
74
+ if (key.name === 'return' || key.name === 'enter') {
75
+ finish(cursor);
76
+ return;
77
+ }
78
+ if (key.name === 'escape' || key.name === 'q') {
79
+ finish(null);
80
+ }
81
+ };
82
+ readline.emitKeypressEvents(stdin);
83
+ if (typeof stdin.setRawMode === 'function') {
84
+ stdin.setRawMode(true);
85
+ }
86
+ stdin.resume();
87
+ process.stdout.write('\u001b[?25l');
88
+ stdin.on('keypress', onKeypress);
89
+ render();
90
+ });
91
+ }
92
+ function isInteractiveSelectionAvailable() {
93
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY);
94
+ }
95
+ function selectionCancelled() {
96
+ printWarning('Selection cancelled.');
97
+ return null;
98
+ }
99
+ async function pickIndexWithFallback(lines, kind, selectIndex = selectIndexWithArrowKeys) {
100
+ if (lines.length === 0) {
101
+ return null;
102
+ }
103
+ const keyboardChoice = await selectIndex(lines, kind);
104
+ if (keyboardChoice !== null) {
105
+ return keyboardChoice;
106
+ }
107
+ const answer = (await promptFromStdin(`Choose ${kind} [1-${lines.length}] (or q to cancel): `)).trim().toLowerCase();
108
+ if (answer === 'q' || answer === 'quit' || answer === 'exit') {
109
+ return selectionCancelled();
110
+ }
111
+ const parsed = Number.parseInt(answer, 10);
112
+ if (Number.isInteger(parsed) && parsed >= 1 && parsed <= lines.length) {
113
+ return parsed - 1;
114
+ }
115
+ printWarning(`Invalid selection. Enter a number from 1-${lines.length}, or q to cancel.`);
116
+ while (true) {
117
+ const retryAnswer = (await promptFromStdin(`Choose ${kind} [1-${lines.length}] (or q to cancel): `)).trim().toLowerCase();
118
+ if (retryAnswer === 'q' || retryAnswer === 'quit' || retryAnswer === 'exit') {
119
+ return selectionCancelled();
120
+ }
121
+ const retryParsed = Number.parseInt(retryAnswer, 10);
122
+ if (Number.isInteger(retryParsed) && retryParsed >= 1 && retryParsed <= lines.length) {
123
+ return retryParsed - 1;
124
+ }
125
+ printWarning(`Invalid selection. Enter a number from 1-${lines.length}, or q to cancel.`);
126
+ }
127
+ }
128
+ export async function resolveJobFromArgOrPrompt(jobsRepo, jobRef, options = {}) {
129
+ if (jobRef) {
130
+ const job = jobsRepo.getByRef(jobRef);
131
+ if (!job) {
132
+ printError(`Job not found: ${jobRef}`);
133
+ return null;
134
+ }
135
+ return job;
136
+ }
137
+ if (!isInteractiveSelectionAvailable()) {
138
+ const suffix = options.requiredForMessage ? ` for ${options.requiredForMessage}` : '';
139
+ printError(`Missing job reference${suffix}. Provide <jobRef> when running non-interactively.`);
140
+ return null;
141
+ }
142
+ const jobs = jobsRepo.list();
143
+ if (jobs.length === 0) {
144
+ printWarning('No jobs configured yet.');
145
+ return null;
146
+ }
147
+ const jobLines = jobs.map((job, index) => {
148
+ const state = job.enabled ? 'on' : 'off';
149
+ return `${index + 1}. ${job.name} (${job.slug}) [${job.id}] state=${state}`;
150
+ });
151
+ const selectedIndex = await pickIndexWithFallback(jobLines, 'job', options.selectIndex);
152
+ if (selectedIndex === null) {
153
+ return null;
154
+ }
155
+ return jobs[selectedIndex] ?? null;
156
+ }
157
+ export async function resolveRunFromArgOrPrompt(runsRepo, runId, selectedJob, options = {}) {
158
+ if (runId) {
159
+ const run = runsRepo.getById(runId);
160
+ if (!run) {
161
+ printError(`Run not found: ${runId}`);
162
+ return null;
163
+ }
164
+ return run;
165
+ }
166
+ const runs = runsRepo.listByJob(selectedJob.id, 20);
167
+ if (runs.length === 0) {
168
+ printWarning(`No run history found for ${selectedJob.name} (${selectedJob.slug}).`);
169
+ return null;
170
+ }
171
+ printInfo(`Runs for ${selectedJob.name} (${selectedJob.slug}):`);
172
+ const runLines = runs.map((run, index) => {
173
+ const status = run.status;
174
+ return `${index + 1}. ${run.id} ${status} ${formatRunDisplayLabel(run)}`;
175
+ });
176
+ const selectedIndex = await pickIndexWithFallback(runLines, 'run', options.selectIndex);
177
+ if (selectedIndex === null) {
178
+ return null;
179
+ }
180
+ return runs[selectedIndex] ?? null;
181
+ }
182
+ //# sourceMappingURL=selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../../src/cli/commands/selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function openSettings(): Promise<void>;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render } from 'ink';
3
+ import { SettingsFlow } from '../flows/settingsFlow.js';
4
+ import { SettingsRepository } from '../../services/db/repositories/settingsRepo.js';
5
+ import { getOpenRouterApiKey, setOpenRouterApiKey } from '../../services/security/secretStore.js';
6
+ import { printSuccess, printWarning } from '../ui/consoleUi.js';
7
+ export async function openSettings() {
8
+ const settingsRepo = new SettingsRepository();
9
+ const current = settingsRepo.getAppSettings();
10
+ const currentRedditCredentials = await settingsRepo.getRedditCredentialState();
11
+ const currentApiKey = await getOpenRouterApiKey();
12
+ let result = null;
13
+ const app = render(_jsx(SettingsFlow, { current: current, currentRedditCredentials: currentRedditCredentials, currentApiKey: currentApiKey, onDone: (value) => {
14
+ result = value;
15
+ } }));
16
+ await app.waitUntilExit();
17
+ const finalResult = result;
18
+ if (!finalResult) {
19
+ printWarning('Settings unchanged.');
20
+ return;
21
+ }
22
+ if (finalResult.apiKey) {
23
+ await setOpenRouterApiKey(finalResult.apiKey);
24
+ }
25
+ if (finalResult.redditCredentials) {
26
+ await settingsRepo.setRedditCredentials(finalResult.redditCredentials);
27
+ }
28
+ settingsRepo.setAppSettings(finalResult.settings);
29
+ printSuccess('Settings saved.');
30
+ }
31
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../src/cli/commands/settings.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAmBhE,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,YAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,YAAY,CAAC,cAAc,EAAE,CAAC;IAC9C,MAAM,wBAAwB,GAAG,MAAM,YAAY,CAAC,wBAAwB,EAAE,CAAC;IAC/E,MAAM,aAAa,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAElD,IAAI,MAAM,GAA8B,IAAI,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,CAChB,KAAC,YAAY,IACX,OAAO,EAAE,OAAO,EAChB,wBAAwB,EAAE,wBAAwB,EAClD,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC,GACD,CACH,CAAC;IAEF,MAAM,GAAG,CAAC,aAAa,EAAE,CAAC;IAC1B,MAAM,WAAW,GAAG,MAAmC,CAAC;IACxD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,YAAY,CAAC,qBAAqB,CAAC,CAAC;QACpC,OAAO;IACT,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,mBAAmB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,WAAW,CAAC,iBAAiB,EAAE,CAAC;QAClC,MAAM,YAAY,CAAC,oBAAoB,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;IACzE,CAAC;IAED,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAClD,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function enableStartupCommand(): void;
2
+ export declare function disableStartupCommand(): void;
3
+ export declare function startupStatusCommand(): void;
4
+ export declare const installStartupCommand: typeof enableStartupCommand;
5
+ export declare const uninstallStartupCommand: typeof disableStartupCommand;
@@ -0,0 +1,26 @@
1
+ import { getStartupStatus, installStartup, uninstallStartup } from '../../services/startup/index.js';
2
+ import { printCommandScreen, printInfo, printSuccess, printWarning } from '../ui/consoleUi.js';
3
+ export function enableStartupCommand() {
4
+ printCommandScreen('Startup configuration', 'Startup Enable');
5
+ const result = installStartup(process.argv[1]);
6
+ if (result.success) {
7
+ printSuccess(`Startup enabled using ${result.method}: ${result.detail}`);
8
+ return;
9
+ }
10
+ printWarning(`Startup enable failed: ${result.detail}`);
11
+ }
12
+ export function disableStartupCommand() {
13
+ printCommandScreen('Startup configuration', 'Startup Disable');
14
+ uninstallStartup();
15
+ printSuccess('Startup registration disabled (where present).');
16
+ }
17
+ export function startupStatusCommand() {
18
+ printCommandScreen('Startup configuration', 'Startup Status');
19
+ const status = getStartupStatus();
20
+ printInfo(`Startup reboot mode: ${status.method}`);
21
+ printInfo(`Startup enabled: ${status.enabled ? 'yes' : 'no'}`);
22
+ printInfo(`Details: ${status.detail}`);
23
+ }
24
+ export const installStartupCommand = enableStartupCommand;
25
+ export const uninstallStartupCommand = disableStartupCommand;
26
+ //# sourceMappingURL=startup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup.js","sourceRoot":"","sources":["../../../../src/cli/commands/startup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACrG,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE/F,MAAM,UAAU,oBAAoB;IAClC,kBAAkB,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,YAAY,CAAC,yBAAyB,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACzE,OAAO;IACT,CAAC;IAED,YAAY,CAAC,0BAA0B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,kBAAkB,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,CAAC;IAC/D,gBAAgB,EAAE,CAAC;IACnB,YAAY,CAAC,gDAAgD,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,kBAAkB,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,SAAS,CAAC,wBAAwB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,SAAS,CAAC,oBAAoB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/D,SAAS,CAAC,YAAY,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,qBAAqB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import type { AppSettings } from '../../types/settings.js';
3
+ interface JobAddResult {
4
+ apiKey?: string;
5
+ installStartup?: boolean;
6
+ settings: AppSettings;
7
+ job: {
8
+ slug: string;
9
+ name: string;
10
+ description: string;
11
+ qualificationPrompt: string;
12
+ subreddits: string[];
13
+ monitorComments: boolean;
14
+ };
15
+ }
16
+ interface JobAddFlowProps {
17
+ hasApiKey: boolean;
18
+ existingApiKey: string | null;
19
+ startupAlreadyEnabled: boolean;
20
+ initialSettings: AppSettings;
21
+ onApiKeyCaptured?: (apiKey: string) => Promise<void> | void;
22
+ onAuthFailure?: () => Promise<void> | void;
23
+ onDone: (result: JobAddResult) => void;
24
+ }
25
+ export declare function JobAddFlow({ hasApiKey, existingApiKey, startupAlreadyEnabled, initialSettings, onApiKeyCaptured, onAuthFailure, onDone }: JobAddFlowProps): React.JSX.Element;
26
+ export {};
@@ -0,0 +1,209 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { Text, useApp } from 'ink';
4
+ import { Spinner } from '@inkjs/ui';
5
+ import { TextPrompt } from '../../ui/components/TextPrompt.js';
6
+ import { YesNoSelector } from '../../ui/components/YesNoSelector.js';
7
+ import { SubredditMultiSelect } from '../../ui/components/SubredditMultiSelect.js';
8
+ import { AppFrame, Panel } from '../../ui/components/AppFrame.js';
9
+ import { OpenRouterClient, OpenRouterClientError } from '../../services/openrouter/client.js';
10
+ import { DEFAULT_MODEL } from '../../types/settings.js';
11
+ import { uiTheme } from '../../ui/theme.js';
12
+ function FlowFrame({ transcript, children, statusText, statusTone = 'info' }) {
13
+ return (_jsxs(AppFrame, { subtitle: "Add job wizard", statusText: statusText, statusTone: statusTone, hints: ['Enter: confirm', 'Esc: cancel current step'], children: [transcript.length > 0 ? (_jsx(Panel, { title: "Session Transcript", children: transcript.map((entry, index) => (_jsxs(Text, { color: entry.muted ? uiTheme.ink.textMuted : uiTheme.ink.textPrimary, children: [_jsxs(Text, { color: uiTheme.ink.accent, children: [entry.label, ":"] }), " ", entry.value] }, `${entry.label}-${index}`))) })) : null, children] }));
14
+ }
15
+ export function JobAddFlow({ hasApiKey, existingApiKey, startupAlreadyEnabled, initialSettings, onApiKeyCaptured, onAuthFailure, onDone }) {
16
+ const defaultModel = initialSettings.model.trim() || DEFAULT_MODEL;
17
+ const { exit } = useApp();
18
+ const [stage, setStage] = useState('criteria');
19
+ const [criteria, setCriteria] = useState('');
20
+ const [apiKey, setApiKey] = useState(undefined);
21
+ const [model, setModel] = useState(defaultModel);
22
+ const [questions, setQuestions] = useState([]);
23
+ const [answers, setAnswers] = useState([]);
24
+ const [questionIndex, setQuestionIndex] = useState(0);
25
+ const [spec, setSpec] = useState(null);
26
+ const [selectedSubreddits, setSelectedSubreddits] = useState([]);
27
+ const [monitorComments, setMonitorComments] = useState(true);
28
+ const [pendingResult, setPendingResult] = useState(null);
29
+ const [errorMessage, setErrorMessage] = useState(null);
30
+ const [loadingLabel, setLoadingLabel] = useState('Talking to model...');
31
+ const [transcript, setTranscript] = useState([]);
32
+ const currentQuestion = useMemo(() => questions[questionIndex], [questions, questionIndex]);
33
+ const appendTranscript = (label, value, muted = false) => {
34
+ setTranscript((previous) => [...previous, { label, value, muted }]);
35
+ };
36
+ useEffect(() => {
37
+ if (stage !== 'generating') {
38
+ return;
39
+ }
40
+ const run = async () => {
41
+ try {
42
+ const keyToUse = hasApiKey ? existingApiKey : apiKey;
43
+ if (!keyToUse) {
44
+ throw new Error('Missing API key');
45
+ }
46
+ const client = new OpenRouterClient(keyToUse);
47
+ const generated = await client.generateJobSpec(criteria, answers, model.trim() || defaultModel);
48
+ appendTranscript('Generated name', generated.name);
49
+ appendTranscript('Generated slug', generated.slug);
50
+ appendTranscript('Generated description', generated.description);
51
+ setSpec(generated);
52
+ setStage('subreddits');
53
+ }
54
+ catch (error) {
55
+ if (error instanceof OpenRouterClientError && error.kind === 'auth') {
56
+ await onAuthFailure?.();
57
+ }
58
+ setErrorMessage(error instanceof Error ? error.message : 'Failed to generate job spec.');
59
+ appendTranscript('OpenRouter', 'Failed to generate job spec', true);
60
+ setStage('error');
61
+ }
62
+ };
63
+ void run();
64
+ }, [answers, apiKey, criteria, defaultModel, existingApiKey, hasApiKey, model, onAuthFailure, stage]);
65
+ useEffect(() => {
66
+ if (stage !== 'error') {
67
+ return;
68
+ }
69
+ const timeoutId = setTimeout(() => {
70
+ exit();
71
+ }, 1200);
72
+ return () => {
73
+ clearTimeout(timeoutId);
74
+ };
75
+ }, [exit, stage]);
76
+ const beginClarification = async () => {
77
+ setLoadingLabel('Generating clarification questions...');
78
+ setStage('clarifying');
79
+ try {
80
+ const keyToUse = hasApiKey ? existingApiKey : apiKey;
81
+ if (!keyToUse) {
82
+ throw new Error('Missing API key');
83
+ }
84
+ const client = new OpenRouterClient(keyToUse);
85
+ const generatedQuestions = await client.generateClarificationQuestions(criteria, model.trim() || defaultModel);
86
+ setQuestions(generatedQuestions);
87
+ appendTranscript('Snoopy', `Generated ${generatedQuestions.length} clarification question(s).`, true);
88
+ setStage('clarifications');
89
+ }
90
+ catch (error) {
91
+ if (error instanceof OpenRouterClientError && error.kind === 'auth') {
92
+ await onAuthFailure?.();
93
+ }
94
+ setErrorMessage(error instanceof Error ? error.message : 'Failed to generate clarification questions.');
95
+ appendTranscript('OpenRouter', 'Failed to generate clarification questions', true);
96
+ setStage('error');
97
+ }
98
+ };
99
+ if (stage === 'criteria') {
100
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "Define monitoring criteria", statusTone: "info", children: _jsx(Panel, { title: "Step 1: Criteria", children: _jsx(TextPrompt, { label: "Describe the conversations you want to monitor", onSubmit: (value) => {
101
+ setCriteria(value);
102
+ appendTranscript('Criteria', value);
103
+ setStage(hasApiKey ? 'model' : 'apiKey');
104
+ } }) }) }));
105
+ }
106
+ if (stage === 'apiKey') {
107
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "First-time setup required", statusTone: "warning", children: _jsxs(Panel, { title: "Step 2: Authentication", children: [_jsx(Text, { color: uiTheme.ink.warning, children: "First-time setup: OpenRouter API key required." }), _jsx(TextPrompt, { label: "Paste OpenRouter API key", secret: true, onSubmit: (value) => {
108
+ setApiKey(value);
109
+ appendTranscript('OpenRouter API key', '********');
110
+ void onApiKeyCaptured?.(value);
111
+ setStage('model');
112
+ } })] }) }));
113
+ }
114
+ if (stage === 'model') {
115
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "Choose model", statusTone: "info", children: _jsxs(Panel, { title: "Step 3: Model", children: [_jsx(Text, { color: uiTheme.ink.warning, children: "Model selection (default moonshotai/kimi-k2.5)" }), _jsx(TextPrompt, { label: "Model ID", initialValue: model.trim() || defaultModel, onSubmit: (value) => {
116
+ const chosenModel = value.trim() || defaultModel;
117
+ setModel(chosenModel);
118
+ appendTranscript('Model', chosenModel);
119
+ void beginClarification();
120
+ } })] }) }));
121
+ }
122
+ if (stage === 'clarifying') {
123
+ return (_jsxs(FlowFrame, { transcript: transcript, statusText: "Generating clarification questions", statusTone: "info", children: [_jsx(Spinner, { label: loadingLabel }), _jsx(Text, { color: uiTheme.ink.textMuted, children: "Snoopy is coming up with follow-up questions." })] }));
124
+ }
125
+ if (stage === 'clarifications' && currentQuestion) {
126
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: `Clarification ${questionIndex + 1}/${questions.length}`, statusTone: "info", children: _jsxs(Panel, { title: "Step 4: Clarifications", children: [_jsxs(Text, { color: uiTheme.ink.accent, children: ["Clarification ", questionIndex + 1, "/", questions.length] }), _jsx(TextPrompt, { label: currentQuestion.question, onSubmit: (value) => {
127
+ appendTranscript(`Q${questionIndex + 1}`, `${currentQuestion.question} -> ${value}`);
128
+ const next = [...answers, { question: currentQuestion.question, answer: value }];
129
+ setAnswers(next);
130
+ const nextIndex = questionIndex + 1;
131
+ if (nextIndex < questions.length) {
132
+ setQuestionIndex(nextIndex);
133
+ }
134
+ else {
135
+ setLoadingLabel('Generating job artifacts...');
136
+ setStage('generating');
137
+ }
138
+ } })] }) }));
139
+ }
140
+ if (stage === 'generating') {
141
+ return (_jsxs(FlowFrame, { transcript: transcript, statusText: "Generating job artifacts", statusTone: "info", children: [_jsx(Spinner, { label: loadingLabel }), _jsx(Text, { color: uiTheme.ink.textMuted, children: "Snoopy is generating the job name, slug, prompt, and subreddit suggestions." })] }));
142
+ }
143
+ if (stage === 'subreddits' && spec) {
144
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "Review generated job draft", statusTone: "success", children: _jsxs(Panel, { title: "Step 5: Subreddits", children: [_jsxs(Text, { color: uiTheme.ink.success, children: ["Generated name: ", spec.name] }), _jsxs(Text, { color: uiTheme.ink.success, children: ["Generated slug: ", spec.slug] }), _jsxs(Text, { color: uiTheme.ink.success, children: ["Generated description: ", spec.description] }), _jsxs(Text, { color: uiTheme.ink.textMuted, children: ["Prompt: ", spec.qualificationPrompt] }), _jsx(SubredditMultiSelect, { options: spec.suggestedSubreddits, onDone: (subreddits) => {
145
+ setSelectedSubreddits(subreddits);
146
+ appendTranscript('Subreddits', subreddits.map((subreddit) => `r/${subreddit}`).join(', '));
147
+ setStage('monitorComments');
148
+ } })] }) }));
149
+ }
150
+ if (stage === 'monitorComments') {
151
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "Choose comment monitoring", statusTone: "info", children: _jsx(Panel, { title: "Step 6: Comment Coverage", children: _jsx(YesNoSelector, { label: "Also monitor comments in these subreddits?", defaultValue: true, onSubmit: (shouldMonitorComments) => {
152
+ setMonitorComments(shouldMonitorComments);
153
+ appendTranscript('Monitor comments', shouldMonitorComments ? 'yes' : 'no');
154
+ setStage('confirm');
155
+ } }) }) }));
156
+ }
157
+ if (stage === 'confirm' && spec) {
158
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "Confirm generated job", statusTone: "success", children: _jsxs(Panel, { title: "Step 7: Review", children: [_jsx(Text, { color: uiTheme.ink.success, bold: true, children: "Review" }), _jsxs(Text, { children: ["Name: ", spec.name] }), _jsxs(Text, { children: ["Slug: ", spec.slug] }), _jsxs(Text, { children: ["Description: ", spec.description] }), _jsxs(Text, { children: ["Subreddits: ", selectedSubreddits.join(', ')] }), _jsxs(Text, { children: ["Monitor comments: ", monitorComments ? 'yes' : 'no'] }), _jsx(YesNoSelector, { label: "Save this job?", defaultValue: true, onSubmit: (shouldSave) => {
159
+ if (shouldSave) {
160
+ appendTranscript('Save job', 'yes');
161
+ const result = {
162
+ apiKey,
163
+ settings: {
164
+ model,
165
+ modelSettings: initialSettings.modelSettings,
166
+ cronIntervalMinutes: initialSettings.cronIntervalMinutes,
167
+ jobTimeoutMs: initialSettings.jobTimeoutMs,
168
+ notificationsEnabled: initialSettings.notificationsEnabled
169
+ },
170
+ job: {
171
+ slug: spec.slug,
172
+ name: spec.name,
173
+ description: spec.description,
174
+ qualificationPrompt: spec.qualificationPrompt,
175
+ subreddits: selectedSubreddits,
176
+ monitorComments
177
+ }
178
+ };
179
+ if (startupAlreadyEnabled) {
180
+ onDone(result);
181
+ exit();
182
+ return;
183
+ }
184
+ setPendingResult(result);
185
+ setStage('startup');
186
+ return;
187
+ }
188
+ else {
189
+ appendTranscript('Save job', 'no', true);
190
+ }
191
+ exit();
192
+ } })] }) }));
193
+ }
194
+ if (stage === 'startup' && pendingResult) {
195
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "Startup registration", statusTone: "info", children: _jsx(Panel, { title: "Step 8: Startup Behavior", children: _jsx(YesNoSelector, { label: "Install OS startup registration so daemon survives reboot?", defaultValue: true, onSubmit: (shouldInstallStartup) => {
196
+ appendTranscript('Install startup registration', shouldInstallStartup ? 'yes' : 'no');
197
+ onDone({
198
+ ...pendingResult,
199
+ installStartup: shouldInstallStartup
200
+ });
201
+ exit();
202
+ } }) }) }));
203
+ }
204
+ if (stage === 'error') {
205
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "OpenRouter request failed", statusTone: "danger", children: _jsxs(Panel, { title: "Error", children: [_jsx(Text, { color: uiTheme.ink.danger, bold: true, children: "OpenRouter request failed" }), _jsx(Text, { children: errorMessage ?? 'Unknown error.' }), _jsx(Text, { color: uiTheme.ink.textMuted, children: "Update your API key or model and try again. Exiting..." })] }) }));
206
+ }
207
+ return (_jsx(FlowFrame, { transcript: transcript, statusText: "Loading", statusTone: "info", children: _jsx(Text, { children: "Loading..." }) }));
208
+ }
209
+ //# sourceMappingURL=jobAddFlow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobAddFlow.js","sourceRoot":"","sources":["../../../../src/cli/flows/jobAddFlow.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { type AppSettings, type RedditCredentialState, type RedditCredentialsUpdate } from '../../types/settings.js';
3
+ interface SettingsResult {
4
+ apiKey?: string;
5
+ redditCredentials?: RedditCredentialsUpdate;
6
+ settings: AppSettings;
7
+ }
8
+ interface SettingsFlowProps {
9
+ current: AppSettings;
10
+ currentRedditCredentials: RedditCredentialState;
11
+ currentApiKey: string | null;
12
+ onDone: (result: SettingsResult) => void;
13
+ }
14
+ export declare function SettingsFlow({ current, currentRedditCredentials, currentApiKey, onDone }: SettingsFlowProps): React.JSX.Element;
15
+ export {};