elepha 0.1.0

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 (290) hide show
  1. package/LICENSE.md +375 -0
  2. package/README.md +135 -0
  3. package/bin/elepha.js +2 -0
  4. package/dist/adapters/base.js +600 -0
  5. package/dist/adapters/base.js.map +1 -0
  6. package/dist/adapters/claude-code.js +260 -0
  7. package/dist/adapters/claude-code.js.map +1 -0
  8. package/dist/adapters/codex.js +499 -0
  9. package/dist/adapters/codex.js.map +1 -0
  10. package/dist/adapters/discriminators.js +39 -0
  11. package/dist/adapters/discriminators.js.map +1 -0
  12. package/dist/adapters/index.js +6 -0
  13. package/dist/adapters/index.js.map +1 -0
  14. package/dist/adapters/internal-command.js +3 -0
  15. package/dist/adapters/internal-command.js.map +1 -0
  16. package/dist/cli/backup-wizard.js +97 -0
  17. package/dist/cli/backup-wizard.js.map +1 -0
  18. package/dist/cli/capture-service.js +80 -0
  19. package/dist/cli/capture-service.js.map +1 -0
  20. package/dist/cli/commands/backfills.js +336 -0
  21. package/dist/cli/commands/backfills.js.map +1 -0
  22. package/dist/cli/commands/backup.js +234 -0
  23. package/dist/cli/commands/backup.js.map +1 -0
  24. package/dist/cli/commands/config.js +66 -0
  25. package/dist/cli/commands/config.js.map +1 -0
  26. package/dist/cli/commands/consent.js +237 -0
  27. package/dist/cli/commands/consent.js.map +1 -0
  28. package/dist/cli/commands/daemon-control.js +76 -0
  29. package/dist/cli/commands/daemon-control.js.map +1 -0
  30. package/dist/cli/commands/doctor.js +31 -0
  31. package/dist/cli/commands/doctor.js.map +1 -0
  32. package/dist/cli/commands/hook.js +24 -0
  33. package/dist/cli/commands/hook.js.map +1 -0
  34. package/dist/cli/commands/import.js +611 -0
  35. package/dist/cli/commands/import.js.map +1 -0
  36. package/dist/cli/commands/init.js +19 -0
  37. package/dist/cli/commands/init.js.map +1 -0
  38. package/dist/cli/commands/inspect.js +54 -0
  39. package/dist/cli/commands/inspect.js.map +1 -0
  40. package/dist/cli/commands/install.js +49 -0
  41. package/dist/cli/commands/install.js.map +1 -0
  42. package/dist/cli/commands/internal.js +16 -0
  43. package/dist/cli/commands/internal.js.map +1 -0
  44. package/dist/cli/commands/mcp.js +12 -0
  45. package/dist/cli/commands/mcp.js.map +1 -0
  46. package/dist/cli/commands/projects.js +26 -0
  47. package/dist/cli/commands/projects.js.map +1 -0
  48. package/dist/cli/commands/purge.js +216 -0
  49. package/dist/cli/commands/purge.js.map +1 -0
  50. package/dist/cli/commands/reingest.js +80 -0
  51. package/dist/cli/commands/reingest.js.map +1 -0
  52. package/dist/cli/commands/rekey.js +58 -0
  53. package/dist/cli/commands/rekey.js.map +1 -0
  54. package/dist/cli/commands/restore.js +376 -0
  55. package/dist/cli/commands/restore.js.map +1 -0
  56. package/dist/cli/commands/rollup.js +130 -0
  57. package/dist/cli/commands/rollup.js.map +1 -0
  58. package/dist/cli/commands/sanitize.js +72 -0
  59. package/dist/cli/commands/sanitize.js.map +1 -0
  60. package/dist/cli/commands/segment.js +153 -0
  61. package/dist/cli/commands/segment.js.map +1 -0
  62. package/dist/cli/commands/self-update.js +26 -0
  63. package/dist/cli/commands/self-update.js.map +1 -0
  64. package/dist/cli/commands/start.js +53 -0
  65. package/dist/cli/commands/start.js.map +1 -0
  66. package/dist/cli/commands/stats.js +42 -0
  67. package/dist/cli/commands/stats.js.map +1 -0
  68. package/dist/cli/commands/status.js +73 -0
  69. package/dist/cli/commands/status.js.map +1 -0
  70. package/dist/cli/commands/uninstall.js +23 -0
  71. package/dist/cli/commands/uninstall.js.map +1 -0
  72. package/dist/cli/config-wizard.js +104 -0
  73. package/dist/cli/config-wizard.js.map +1 -0
  74. package/dist/cli/destructive-op.js +32 -0
  75. package/dist/cli/destructive-op.js.map +1 -0
  76. package/dist/cli/import-wizard.js +89 -0
  77. package/dist/cli/import-wizard.js.map +1 -0
  78. package/dist/cli/index.js +74 -0
  79. package/dist/cli/index.js.map +1 -0
  80. package/dist/cli/init-wizard.js +80 -0
  81. package/dist/cli/init-wizard.js.map +1 -0
  82. package/dist/cli/init.js +159 -0
  83. package/dist/cli/init.js.map +1 -0
  84. package/dist/cli/launcher-probe.js +71 -0
  85. package/dist/cli/launcher-probe.js.map +1 -0
  86. package/dist/cli/project-path.js +16 -0
  87. package/dist/cli/project-path.js.map +1 -0
  88. package/dist/cli/purge-wizard.js +200 -0
  89. package/dist/cli/purge-wizard.js.map +1 -0
  90. package/dist/cli/restore-wizard.js +101 -0
  91. package/dist/cli/restore-wizard.js.map +1 -0
  92. package/dist/cli/shared.js +128 -0
  93. package/dist/cli/shared.js.map +1 -0
  94. package/dist/cli/status.js +22 -0
  95. package/dist/cli/status.js.map +1 -0
  96. package/dist/cli/wordmark.js +15 -0
  97. package/dist/cli/wordmark.js.map +1 -0
  98. package/dist/config/constants.js +115 -0
  99. package/dist/config/constants.js.map +1 -0
  100. package/dist/config/env.js +168 -0
  101. package/dist/config/env.js.map +1 -0
  102. package/dist/config/memory-config.js +63 -0
  103. package/dist/config/memory-config.js.map +1 -0
  104. package/dist/config/paths.js +343 -0
  105. package/dist/config/paths.js.map +1 -0
  106. package/dist/config/settings.js +132 -0
  107. package/dist/config/settings.js.map +1 -0
  108. package/dist/config/version.js +12 -0
  109. package/dist/config/version.js.map +1 -0
  110. package/dist/daemon/failure-window.js +38 -0
  111. package/dist/daemon/failure-window.js.map +1 -0
  112. package/dist/daemon/heartbeat.js +40 -0
  113. package/dist/daemon/heartbeat.js.map +1 -0
  114. package/dist/daemon/index.js +873 -0
  115. package/dist/daemon/index.js.map +1 -0
  116. package/dist/daemon/log-rotation.js +27 -0
  117. package/dist/daemon/log-rotation.js.map +1 -0
  118. package/dist/daemon/readability-guard.js +89 -0
  119. package/dist/daemon/readability-guard.js.map +1 -0
  120. package/dist/daemon/rollup-service.js +239 -0
  121. package/dist/daemon/rollup-service.js.map +1 -0
  122. package/dist/daemon/update-check.js +87 -0
  123. package/dist/daemon/update-check.js.map +1 -0
  124. package/dist/daemon/work-queue.js +28 -0
  125. package/dist/daemon/work-queue.js.map +1 -0
  126. package/dist/discovery/session-projects.js +242 -0
  127. package/dist/discovery/session-projects.js.map +1 -0
  128. package/dist/hooks/codex-trust.js +80 -0
  129. package/dist/hooks/codex-trust.js.map +1 -0
  130. package/dist/hooks/common.js +81 -0
  131. package/dist/hooks/common.js.map +1 -0
  132. package/dist/hooks/hook-log.js +38 -0
  133. package/dist/hooks/hook-log.js.map +1 -0
  134. package/dist/hooks/installer.js +200 -0
  135. package/dist/hooks/installer.js.map +1 -0
  136. package/dist/hooks/session-start.js +321 -0
  137. package/dist/hooks/session-start.js.map +1 -0
  138. package/dist/hooks/user-prompt-submit.js +248 -0
  139. package/dist/hooks/user-prompt-submit.js.map +1 -0
  140. package/dist/install/binary.js +72 -0
  141. package/dist/install/binary.js.map +1 -0
  142. package/dist/install/config-file.js +119 -0
  143. package/dist/install/config-file.js.map +1 -0
  144. package/dist/install/daemon-health.js +48 -0
  145. package/dist/install/daemon-health.js.map +1 -0
  146. package/dist/install/daemon-service.js +309 -0
  147. package/dist/install/daemon-service.js.map +1 -0
  148. package/dist/install/doctor.js +180 -0
  149. package/dist/install/doctor.js.map +1 -0
  150. package/dist/install/health-checks.js +90 -0
  151. package/dist/install/health-checks.js.map +1 -0
  152. package/dist/install/installer.js +411 -0
  153. package/dist/install/installer.js.map +1 -0
  154. package/dist/install/launchd-backend.js +261 -0
  155. package/dist/install/launchd-backend.js.map +1 -0
  156. package/dist/install/launcher.js +224 -0
  157. package/dist/install/launcher.js.map +1 -0
  158. package/dist/install/markers.js +14 -0
  159. package/dist/install/markers.js.map +1 -0
  160. package/dist/install/platform.js +29 -0
  161. package/dist/install/platform.js.map +1 -0
  162. package/dist/install/present-tools.js +16 -0
  163. package/dist/install/present-tools.js.map +1 -0
  164. package/dist/install/self-update.js +120 -0
  165. package/dist/install/self-update.js.map +1 -0
  166. package/dist/install/service-backend.js +36 -0
  167. package/dist/install/service-backend.js.map +1 -0
  168. package/dist/install/service-manifest.js +36 -0
  169. package/dist/install/service-manifest.js.map +1 -0
  170. package/dist/install/status.js +58 -0
  171. package/dist/install/status.js.map +1 -0
  172. package/dist/install/systemd-backend.js +225 -0
  173. package/dist/install/systemd-backend.js.map +1 -0
  174. package/dist/markers.js +5 -0
  175. package/dist/markers.js.map +1 -0
  176. package/dist/mcp/installer.js +131 -0
  177. package/dist/mcp/installer.js.map +1 -0
  178. package/dist/mcp/server.js +81 -0
  179. package/dist/mcp/server.js.map +1 -0
  180. package/dist/mcp/tools/get-context.js +3 -0
  181. package/dist/mcp/tools/get-context.js.map +1 -0
  182. package/dist/mcp/tools/list-projects.js +3 -0
  183. package/dist/mcp/tools/list-projects.js.map +1 -0
  184. package/dist/mcp/tools/save-memory.js +3 -0
  185. package/dist/mcp/tools/save-memory.js.map +1 -0
  186. package/dist/mcp/tools.js +288 -0
  187. package/dist/mcp/tools.js.map +1 -0
  188. package/dist/rendering/raw-turn-renderer.js +85 -0
  189. package/dist/rendering/raw-turn-renderer.js.map +1 -0
  190. package/dist/security/file-permissions.js +15 -0
  191. package/dist/security/file-permissions.js.map +1 -0
  192. package/dist/security/provider-transcript.js +74 -0
  193. package/dist/security/provider-transcript.js.map +1 -0
  194. package/dist/security/sanitize.js +210 -0
  195. package/dist/security/sanitize.js.map +1 -0
  196. package/dist/security/self-ingestion.js +47 -0
  197. package/dist/security/self-ingestion.js.map +1 -0
  198. package/dist/security/sentinel.js +19 -0
  199. package/dist/security/sentinel.js.map +1 -0
  200. package/dist/security/subprocess-allowlist.js +421 -0
  201. package/dist/security/subprocess-allowlist.js.map +1 -0
  202. package/dist/serving/instructions.js +33 -0
  203. package/dist/serving/instructions.js.map +1 -0
  204. package/dist/serving/lexical-recall.js +249 -0
  205. package/dist/serving/lexical-recall.js.map +1 -0
  206. package/dist/serving/session-reader.js +302 -0
  207. package/dist/serving/session-reader.js.map +1 -0
  208. package/dist/storage/backfill-runner.js +34 -0
  209. package/dist/storage/backfill-runner.js.map +1 -0
  210. package/dist/storage/backup.js +46 -0
  211. package/dist/storage/backup.js.map +1 -0
  212. package/dist/storage/candidate-validator.js +77 -0
  213. package/dist/storage/candidate-validator.js.map +1 -0
  214. package/dist/storage/consent-store.js +198 -0
  215. package/dist/storage/consent-store.js.map +1 -0
  216. package/dist/storage/custom-title-backfill.js +68 -0
  217. package/dist/storage/custom-title-backfill.js.map +1 -0
  218. package/dist/storage/db.js +312 -0
  219. package/dist/storage/db.js.map +1 -0
  220. package/dist/storage/external-agent-import-purge.js +182 -0
  221. package/dist/storage/external-agent-import-purge.js.map +1 -0
  222. package/dist/storage/first-prompt-search-backfill.js +76 -0
  223. package/dist/storage/first-prompt-search-backfill.js.map +1 -0
  224. package/dist/storage/first-prompt-search.js +7 -0
  225. package/dist/storage/first-prompt-search.js.map +1 -0
  226. package/dist/storage/injection-store.js +37 -0
  227. package/dist/storage/injection-store.js.map +1 -0
  228. package/dist/storage/memory-store.js +428 -0
  229. package/dist/storage/memory-store.js.map +1 -0
  230. package/dist/storage/project-resolver.js +294 -0
  231. package/dist/storage/project-resolver.js.map +1 -0
  232. package/dist/storage/project-store.js +104 -0
  233. package/dist/storage/project-store.js.map +1 -0
  234. package/dist/storage/rendered-chars-backfill.js +85 -0
  235. package/dist/storage/rendered-chars-backfill.js.map +1 -0
  236. package/dist/storage/resegmentation.js +582 -0
  237. package/dist/storage/resegmentation.js.map +1 -0
  238. package/dist/storage/rollup-store.js +246 -0
  239. package/dist/storage/rollup-store.js.map +1 -0
  240. package/dist/storage/root-commit-backfill.js +32 -0
  241. package/dist/storage/root-commit-backfill.js.map +1 -0
  242. package/dist/storage/sanitize-backfill.js +184 -0
  243. package/dist/storage/sanitize-backfill.js.map +1 -0
  244. package/dist/storage/segmentation.js +87 -0
  245. package/dist/storage/segmentation.js.map +1 -0
  246. package/dist/storage/session-fields-backfill.js +196 -0
  247. package/dist/storage/session-fields-backfill.js.map +1 -0
  248. package/dist/storage/session-read-model.js +130 -0
  249. package/dist/storage/session-read-model.js.map +1 -0
  250. package/dist/storage/session-store.js +200 -0
  251. package/dist/storage/session-store.js.map +1 -0
  252. package/dist/storage/session-title-backfill.js +75 -0
  253. package/dist/storage/session-title-backfill.js.map +1 -0
  254. package/dist/storage/session-title.js +71 -0
  255. package/dist/storage/session-title.js.map +1 -0
  256. package/dist/storage/shown-session-list-store.js +33 -0
  257. package/dist/storage/shown-session-list-store.js.map +1 -0
  258. package/dist/storage/stats.js +30 -0
  259. package/dist/storage/stats.js.map +1 -0
  260. package/dist/storage/turn-store.js +202 -0
  261. package/dist/storage/turn-store.js.map +1 -0
  262. package/dist/storage/ulid.js +17 -0
  263. package/dist/storage/ulid.js.map +1 -0
  264. package/dist/summarizer/anthropic-call.js +76 -0
  265. package/dist/summarizer/anthropic-call.js.map +1 -0
  266. package/dist/summarizer/call-log.js +120 -0
  267. package/dist/summarizer/call-log.js.map +1 -0
  268. package/dist/summarizer/haiku-provider.js +136 -0
  269. package/dist/summarizer/haiku-provider.js.map +1 -0
  270. package/dist/summarizer/pricing.js +8 -0
  271. package/dist/summarizer/pricing.js.map +1 -0
  272. package/dist/summarizer/prompt-cache.js +6 -0
  273. package/dist/summarizer/prompt-cache.js.map +1 -0
  274. package/dist/summarizer/prompt.js +47 -0
  275. package/dist/summarizer/prompt.js.map +1 -0
  276. package/dist/summarizer/provider-config.js +25 -0
  277. package/dist/summarizer/provider-config.js.map +1 -0
  278. package/dist/summarizer/rollup-prompt.js +225 -0
  279. package/dist/summarizer/rollup-prompt.js.map +1 -0
  280. package/dist/summarizer/rollup-provider.js +224 -0
  281. package/dist/summarizer/rollup-provider.js.map +1 -0
  282. package/dist/types/index.js +10 -0
  283. package/dist/types/index.js.map +1 -0
  284. package/dist/util/error.js +5 -0
  285. package/dist/util/error.js.map +1 -0
  286. package/dist/util/fs.js +97 -0
  287. package/dist/util/fs.js.map +1 -0
  288. package/dist/util/relative-time.js +12 -0
  289. package/dist/util/relative-time.js.map +1 -0
  290. package/package.json +81 -0
@@ -0,0 +1,234 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { copyFileSync, existsSync, lstatSync, renameSync, statSync, unlinkSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import Database from 'better-sqlite3';
5
+ import { PRIVATE_FILE_MODE, USER_BACKUPS_DIR_NAME } from '../../config/constants.js';
6
+ import { canonicalizeExisting, elephaHome, normalizeForCompare } from '../../config/paths.js';
7
+ import { defaultDbPath, openDb } from '../../storage/db.js';
8
+ import { MemoryStore } from '../../storage/memory-store.js';
9
+ import { ProjectResolver } from '../../storage/project-resolver.js';
10
+ import { ensureCreatedDirsPrivate, listRegularFiles, setPrivateFileMode } from '../../util/fs.js';
11
+ import { runBackupWizard } from '../backup-wizard.js';
12
+ const EXPORTED_TABLES = ['projects', 'sessions', 'memories', 'session_rollups'];
13
+ /** Registers portable, user-requested database exports. Safety snapshots remain in storage/backup.ts. */
14
+ export function registerBackup(program) {
15
+ program
16
+ .command('backup')
17
+ .description('Export elepha memory to a portable SQLite file')
18
+ .option('--all', 'export the whole elepha database')
19
+ .option('--project <pathOrName>', 'export one consolidated project set')
20
+ .option('--out <path>', 'write to this file or directory instead of ~/.elepha/backups')
21
+ .option('--force', 'overwrite an existing backup destination')
22
+ .action(async (opts) => {
23
+ const scopes = [opts.all, opts.project !== undefined].filter(Boolean).length;
24
+ if (scopes > 1) {
25
+ console.error('Specify only one of --all or --project <pathOrName>.');
26
+ process.exitCode = 1;
27
+ return;
28
+ }
29
+ if (scopes === 0 && !process.stdin.isTTY) {
30
+ console.error('Specify --all or --project <pathOrName>.');
31
+ process.exitCode = 1;
32
+ return;
33
+ }
34
+ const dbPath = defaultDbPath();
35
+ const db = openDb(dbPath);
36
+ const store = new MemoryStore(db);
37
+ const defaultOutput = (project) => {
38
+ const generated = defaultBackupPath(project);
39
+ return opts.out === undefined ? generated : resolveOutput(opts.out, generated);
40
+ };
41
+ try {
42
+ if (scopes === 0) {
43
+ process.exitCode = await runBackupWizard({
44
+ store,
45
+ defaultOutput,
46
+ backupAll: async (output) => exportAll(db, resolveOutput(output, defaultOutput()), opts.force),
47
+ backupProject: async (project, output) => exportProject(db, project, resolveOutput(output, defaultOutput(project)), opts.force),
48
+ });
49
+ return;
50
+ }
51
+ if (opts.all) {
52
+ const written = exportAll(db, resolveOutput(opts.out, defaultOutput()), opts.force);
53
+ console.log(`Backup written to ${written}.`);
54
+ return;
55
+ }
56
+ const resolution = new ProjectResolver(db).resolve(opts.project ?? '');
57
+ if (!('project' in resolution) || resolution.project === null) {
58
+ console.error(`No project matching "${opts.project}".`);
59
+ process.exitCode = 1;
60
+ return;
61
+ }
62
+ if ('ambiguous' in resolution) {
63
+ console.error(`Project "${opts.project}" is ambiguous. Use a more specific path or name.`);
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+ const written = exportProject(db, resolution.project, resolveOutput(opts.out, defaultOutput(resolution.project)), opts.force);
68
+ console.log(`Backup written to ${written}.`);
69
+ }
70
+ finally {
71
+ db.close();
72
+ }
73
+ });
74
+ }
75
+ function backupDirectory() {
76
+ return path.join(elephaHome(), USER_BACKUPS_DIR_NAME);
77
+ }
78
+ /** Lists complete database exports only; project exports are not valid restore candidates. */
79
+ export function listFullBackups() {
80
+ return listRegularFiles(backupDirectory())
81
+ .filter((file) => /^elepha-full-.*\.db$/.test(path.basename(file)))
82
+ .map((file) => {
83
+ const stats = statSync(file);
84
+ return { path: file, mtimeMs: stats.mtimeMs, bytes: stats.size };
85
+ })
86
+ .sort((a, b) => b.mtimeMs - a.mtimeMs || path.basename(b.path).localeCompare(path.basename(a.path)));
87
+ }
88
+ function timestamp() {
89
+ return new Date().toISOString().replace(/[:.]/g, '-');
90
+ }
91
+ function projectSlug(project) {
92
+ const source = project.displayName || project.paths[0] || 'project';
93
+ const slug = source
94
+ .toLowerCase()
95
+ .replace(/[^a-z0-9]+/g, '-')
96
+ .replace(/^-+|-+$/g, '');
97
+ return slug || 'project';
98
+ }
99
+ export function defaultBackupPath(project) {
100
+ const filename = project ? `elepha-${projectSlug(project)}-${timestamp()}.db` : `elepha-full-${timestamp()}.db`;
101
+ return path.join(backupDirectory(), filename);
102
+ }
103
+ /** Existing directories stay directories; a trailing separator also creates a directory. Other values are file paths. */
104
+ export function resolveOutput(output, defaultPath) {
105
+ if (output === undefined) {
106
+ return defaultPath;
107
+ }
108
+ const resolved = path.resolve(output);
109
+ if ((existsSync(resolved) && statSync(resolved).isDirectory()) || output.endsWith(path.sep)) {
110
+ return path.join(resolved, path.basename(defaultPath));
111
+ }
112
+ return resolved;
113
+ }
114
+ /** Full exports retain the source database bytes after a WAL checkpoint, unlike pruned safety snapshots. */
115
+ export function exportAll(db, destination, force = false) {
116
+ if (db.name === ':memory:') {
117
+ throw new Error('A full backup requires an on-disk database.');
118
+ }
119
+ refuseActiveDatabaseDestination(db.name, destination);
120
+ prepareDestination(destination, force);
121
+ const [checkpoint] = db.pragma('wal_checkpoint(TRUNCATE)');
122
+ if (checkpoint?.busy !== 0) {
123
+ throw new Error("Backup aborted: WAL checkpoint did not complete (the daemon may be writing) — run 'elepha pause' or retry.");
124
+ }
125
+ replaceDestination(destination, (temporary) => copyFileSync(db.name, temporary));
126
+ return destination;
127
+ }
128
+ /** Exports exactly one resolved ProjectSet and the four portable tables that reference it. */
129
+ export function exportProject(source, project, destination, force = false) {
130
+ refuseActiveDatabaseDestination(source.name, destination);
131
+ prepareDestination(destination, force);
132
+ replaceDestination(destination, (temporary) => {
133
+ const target = new Database(temporary);
134
+ setPrivateFileMode(temporary, PRIVATE_FILE_MODE);
135
+ try {
136
+ target.pragma('foreign_keys = ON');
137
+ const exportSnapshot = source.transaction(() => {
138
+ createExportSchema(source, target);
139
+ copyProjectRows(source, target, project.projectIds);
140
+ });
141
+ exportSnapshot();
142
+ }
143
+ finally {
144
+ target.close();
145
+ }
146
+ });
147
+ return destination;
148
+ }
149
+ function refuseActiveDatabaseDestination(activeDatabase, destination) {
150
+ if (activeDatabase === ':memory:') {
151
+ return;
152
+ }
153
+ const canonicalDestination = path.join(canonicalizeExisting(path.dirname(destination)), path.basename(destination));
154
+ if (normalizeForCompare(canonicalDestination) === normalizeForCompare(canonicalizeExisting(activeDatabase))) {
155
+ throw new Error('Backup destination must not be the active database.');
156
+ }
157
+ }
158
+ /** Rejects unsafe destinations before creating a backup file. */
159
+ function prepareDestination(destination, force) {
160
+ let destinationInfo;
161
+ try {
162
+ destinationInfo = lstatSync(destination);
163
+ }
164
+ catch (error) {
165
+ if (error.code !== 'ENOENT') {
166
+ throw error;
167
+ }
168
+ }
169
+ if (destinationInfo?.isSymbolicLink()) {
170
+ throw new Error(`refusing to write a backup through a symlink: ${destination}`);
171
+ }
172
+ if (destinationInfo !== undefined && !force) {
173
+ throw new Error(`Backup destination already exists: ${destination} (pass --force to overwrite)`);
174
+ }
175
+ ensureCreatedDirsPrivate(path.dirname(destination));
176
+ }
177
+ function replaceDestination(destination, writeTemporary) {
178
+ const temporary = `${destination}.${process.pid}.${randomUUID()}.tmp`;
179
+ try {
180
+ writeTemporary(temporary);
181
+ setPrivateFileMode(temporary, PRIVATE_FILE_MODE);
182
+ renameSync(temporary, destination);
183
+ }
184
+ catch (error) {
185
+ try {
186
+ unlinkSync(temporary);
187
+ }
188
+ catch (cleanupError) {
189
+ if (cleanupError.code !== 'ENOENT') {
190
+ throw cleanupError;
191
+ }
192
+ }
193
+ throw error;
194
+ }
195
+ }
196
+ function createExportSchema(source, target) {
197
+ const placeholders = EXPORTED_TABLES.map(() => '?').join(', ');
198
+ const schema = source
199
+ .prepare(`SELECT type, name, sql FROM sqlite_master WHERE type IN ('table', 'index') AND tbl_name IN (${placeholders}) AND sql IS NOT NULL`)
200
+ .all(...EXPORTED_TABLES);
201
+ for (const entry of schema.filter((entry) => entry.type === 'table')) {
202
+ target.exec(entry.sql);
203
+ }
204
+ for (const entry of schema.filter((entry) => entry.type === 'index')) {
205
+ target.exec(entry.sql);
206
+ }
207
+ }
208
+ function copyProjectRows(source, target, projectIds) {
209
+ const ids = projectIds.map(() => '?').join(', ');
210
+ const sessionIds = source.prepare(`SELECT id FROM sessions WHERE project_id IN (${ids})`).all(...projectIds);
211
+ const sessionPlaceholders = sessionIds.map(() => '?').join(', ');
212
+ const targetTransaction = target.transaction(() => {
213
+ copyRows(source, target, 'projects', `SELECT * FROM projects WHERE id IN (${ids})`, projectIds);
214
+ copyRows(source, target, 'sessions', `SELECT * FROM sessions WHERE project_id IN (${ids})`, projectIds);
215
+ if (sessionIds.length > 0) {
216
+ const values = sessionIds.map((session) => session.id);
217
+ copyRows(source, target, 'memories', `SELECT * FROM memories WHERE session_id IN (${sessionPlaceholders})`, values);
218
+ copyRows(source, target, 'session_rollups', `SELECT * FROM session_rollups WHERE session_id IN (${sessionPlaceholders})`, values);
219
+ }
220
+ });
221
+ targetTransaction();
222
+ }
223
+ function copyRows(source, target, table, sql, values) {
224
+ const rows = source.prepare(sql).all(...values);
225
+ if (rows.length === 0) {
226
+ return;
227
+ }
228
+ const columns = Object.keys(rows[0] ?? {});
229
+ const statement = target.prepare(`INSERT INTO ${table} (${columns.join(', ')}) VALUES (${columns.map(() => '?').join(', ')})`);
230
+ for (const row of rows) {
231
+ statement.run(...columns.map((column) => row[column]));
232
+ }
233
+ }
234
+ //# sourceMappingURL=backup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../../src/cli/commands/backup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { getSetting, listSettings, setSetting, unsetSetting } from '../../config/settings.js';
2
+ import { errorMessage } from '../../util/error.js';
3
+ import { renderSetting, renderSettingValue, runConfigWizard } from '../config-wizard.js';
4
+ function printSettings() {
5
+ for (const setting of listSettings()) {
6
+ console.log(renderSetting(setting));
7
+ }
8
+ }
9
+ export function registerConfig(program) {
10
+ const config = program.command('config').description('View and change persistent settings: list / get / set / unset');
11
+ config
12
+ .command('get')
13
+ .argument('<key>')
14
+ .action((key) => {
15
+ try {
16
+ const setting = getSetting(key);
17
+ console.log(renderSettingValue(setting.key, setting.value));
18
+ }
19
+ catch (error) {
20
+ console.error(errorMessage(error));
21
+ process.exitCode = 1;
22
+ }
23
+ });
24
+ config
25
+ .command('set')
26
+ .argument('<key>')
27
+ .argument('<value>')
28
+ .action((key, value) => {
29
+ try {
30
+ const setting = setSetting(key, value);
31
+ console.log(`${setting.key} set to ${renderSettingValue(setting.key, setting.value)}`);
32
+ }
33
+ catch (error) {
34
+ console.error(errorMessage(error));
35
+ process.exitCode = 1;
36
+ }
37
+ });
38
+ config
39
+ .command('unset')
40
+ .argument('<key>')
41
+ .action((key) => {
42
+ try {
43
+ const setting = unsetSetting(key);
44
+ console.log(`${setting.key} unset; effective value: ${renderSettingValue(setting.key, setting.value)}`);
45
+ }
46
+ catch (error) {
47
+ console.error(errorMessage(error));
48
+ process.exitCode = 1;
49
+ }
50
+ });
51
+ config.command('list').action(printSettings);
52
+ config.action(async () => {
53
+ if (!process.stdout.isTTY) {
54
+ printSettings();
55
+ return;
56
+ }
57
+ try {
58
+ process.exitCode = await runConfigWizard();
59
+ }
60
+ catch (error) {
61
+ console.error(errorMessage(error));
62
+ process.exitCode = 1;
63
+ }
64
+ });
65
+ }
66
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/cli/commands/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,237 @@
1
+ import { existsSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { canonicalizeExisting, isRefusedProjectRoot } from '../../config/paths.js';
4
+ import { IngestionDaemon } from '../../daemon/index.js';
5
+ import { reconcileCaptureService, serviceBackend } from '../../install/service-backend.js';
6
+ import { ConsentStore } from '../../storage/consent-store.js';
7
+ import { openDb } from '../../storage/db.js';
8
+ import { MemoryStore } from '../../storage/memory-store.js';
9
+ import { errorMessage } from '../../util/error.js';
10
+ import { runDestructiveOp } from '../destructive-op.js';
11
+ import { runInit } from '../init.js';
12
+ import { confirmYesNo } from '../shared.js';
13
+ class ConsentPruneChangedError extends Error {
14
+ paths;
15
+ constructor(paths) {
16
+ super('Consent roots changed since preview.');
17
+ this.paths = paths;
18
+ this.name = 'ConsentPruneChangedError';
19
+ }
20
+ }
21
+ function resolveConsentPath(rootPath, options) {
22
+ const hasPath = rootPath !== undefined;
23
+ const hasHere = options.here === true;
24
+ if (hasPath === hasHere) {
25
+ console.error('Choose exactly one consent root: provide <path> or pass --here.');
26
+ process.exitCode = 1;
27
+ return undefined;
28
+ }
29
+ return path.resolve(rootPath ?? process.cwd());
30
+ }
31
+ function consentPruneReason(rootPath) {
32
+ if (!existsSync(rootPath)) {
33
+ return 'missing';
34
+ }
35
+ try {
36
+ return isRefusedProjectRoot(canonicalizeExisting(rootPath)) ? 'refused' : undefined;
37
+ }
38
+ catch {
39
+ return 'missing';
40
+ }
41
+ }
42
+ function planConsentPrune(store) {
43
+ return store.list().flatMap((root) => {
44
+ const reason = consentPruneReason(root.path);
45
+ return reason === undefined ? [] : [{ root, reason }];
46
+ });
47
+ }
48
+ async function confirmConsentPrune(count) {
49
+ return confirmYesNo(`Remove these ${count} stale or refused consent root(s) from consent list? Captured memory will be kept. [y/N] `);
50
+ }
51
+ export function registerConsent(program) {
52
+ const consent = program.command('consent').description('Manage the roots elepha may ingest: list / pending / grant / revoke / prune');
53
+ consent.action(async () => {
54
+ try {
55
+ process.exitCode = await runInit({ store: new MemoryStore(openDb()), entry: 'consent' });
56
+ }
57
+ catch (error) {
58
+ console.error(errorMessage(error));
59
+ process.exitCode = 1;
60
+ }
61
+ });
62
+ consent
63
+ .command('list')
64
+ .description('List every approved, denied, and pending memory root')
65
+ .action(() => {
66
+ const roots = new ConsentStore(openDb()).list();
67
+ if (roots.length === 0) {
68
+ console.log('No consent roots recorded.');
69
+ return;
70
+ }
71
+ for (const root of roots) {
72
+ console.log(`${root.state}\t${root.path}\t${root.source}\t${root.decided_at}`);
73
+ }
74
+ });
75
+ consent
76
+ .command('pending')
77
+ .description('List roots seen by the daemon but not yet approved')
78
+ .action(() => {
79
+ const roots = new ConsentStore(openDb()).list('pending');
80
+ if (roots.length === 0) {
81
+ console.log('No pending consent roots.');
82
+ return;
83
+ }
84
+ for (const root of roots) {
85
+ console.log(`${root.path}\t${root.decided_at}`);
86
+ }
87
+ });
88
+ consent
89
+ .command('prune')
90
+ .description('Remove missing or refused roots from consent list without deleting captured memory. Dry-run by default.')
91
+ .option('--apply', 'actually remove the listed consent roots (default is a dry run that only prints the plan)')
92
+ .option('--skip-confirmation', 'remove without the confirmation prompt')
93
+ .action(async (options) => {
94
+ const db = openDb();
95
+ const store = new ConsentStore(db);
96
+ let verificationFailed = false;
97
+ await runDestructiveOp({
98
+ applyRequested: options.apply,
99
+ db,
100
+ operationLabel: 'consent prune',
101
+ plan: () => planConsentPrune(store),
102
+ describe: (plan) => {
103
+ if (plan.length === 0) {
104
+ console.log('No missing or refused consent roots found.');
105
+ return;
106
+ }
107
+ console.log('Consent roots eligible for pruning:');
108
+ for (const candidate of plan) {
109
+ console.log(`${candidate.reason}\t${candidate.root.path}`);
110
+ }
111
+ console.log('\nOnly these consent-list entries are affected; captured memory is kept. ' +
112
+ 'Use elepha purge --orphan to preview orphaned memory.');
113
+ },
114
+ isEmpty: (plan) => plan.length === 0,
115
+ messages: {
116
+ dryRun: '\nThis is a preview — nothing was deleted. Re-run with --apply to remove these consent-list entries.',
117
+ },
118
+ confirm: async (plan) => {
119
+ if (!process.stdout.isTTY || options.skipConfirmation) {
120
+ return true;
121
+ }
122
+ if (await confirmConsentPrune(plan.length)) {
123
+ return true;
124
+ }
125
+ console.log('Cancelled — nothing was deleted.');
126
+ return false;
127
+ },
128
+ apply: (plan) => {
129
+ const removeCandidates = db.transaction((candidates) => {
130
+ const findRoot = db.prepare('SELECT path, state FROM consent_roots WHERE ulid = ?');
131
+ const changedPaths = [];
132
+ let removed = 0;
133
+ for (const candidate of candidates) {
134
+ const current = findRoot.get(candidate.root.ulid);
135
+ const currentReason = current === undefined ? undefined : consentPruneReason(current.path);
136
+ if (current === undefined ||
137
+ current.path !== candidate.root.path ||
138
+ current.state !== candidate.root.state ||
139
+ currentReason !== candidate.reason) {
140
+ changedPaths.push(candidate.root.path);
141
+ continue;
142
+ }
143
+ if (store.remove(candidate.root.ulid)) {
144
+ removed += 1;
145
+ }
146
+ else {
147
+ changedPaths.push(candidate.root.path);
148
+ }
149
+ }
150
+ if (changedPaths.length > 0) {
151
+ throw new ConsentPruneChangedError(changedPaths);
152
+ }
153
+ return removed;
154
+ });
155
+ const removed = removeCandidates(plan);
156
+ console.log(`Removed ${removed} consent root(s). Captured memory was not deleted; use elepha purge --orphan to preview it.`);
157
+ },
158
+ verify: (plan) => {
159
+ const remainingIds = new Set(store.list().map((root) => root.ulid));
160
+ const remaining = plan.filter((candidate) => remainingIds.has(candidate.root.ulid));
161
+ if (remaining.length > 0) {
162
+ verificationFailed = true;
163
+ console.error(`\nVERIFICATION FAILED: ${remaining.length} selected consent root(s) still remain.`);
164
+ process.exitCode = 1;
165
+ }
166
+ },
167
+ }).catch((error) => {
168
+ if (!(error instanceof ConsentPruneChangedError)) {
169
+ throw error;
170
+ }
171
+ console.error(`Consent roots changed since preview:\n${error.paths.map((root) => ` ${root}`).join('\n')}`);
172
+ console.error('Nothing was removed. Re-run elepha consent prune to see a fresh preview.');
173
+ process.exitCode = 1;
174
+ });
175
+ if (verificationFailed) {
176
+ process.exitCode = 1;
177
+ }
178
+ });
179
+ consent
180
+ .command('grant')
181
+ .description('Grant consent to a root and capture its already-written transcripts without calling a synthesis provider')
182
+ .argument('[path]', 'memory root to grant')
183
+ .option('--here', 'use the current working directory as the memory root')
184
+ .action(async (rootPath, options) => {
185
+ const root = resolveConsentPath(rootPath, options);
186
+ if (root === undefined) {
187
+ return;
188
+ }
189
+ if (isRefusedProjectRoot(root)) {
190
+ console.error(`${root} is a refused project root and cannot be granted.`);
191
+ process.exitCode = 1;
192
+ return;
193
+ }
194
+ const db = openDb();
195
+ const consentStore = new ConsentStore(db);
196
+ const store = new MemoryStore(db);
197
+ const consentRoot = consentStore.grant(root);
198
+ const daemon = new IngestionDaemon({ store, log: (message) => console.log(message) });
199
+ const ingested = await daemon.backfillApprovedRoot(consentRoot.path);
200
+ console.log(ingested > 0
201
+ ? `Granted ${consentRoot.path}; backfilled ${ingested} turn(s) without synthesis.`
202
+ : `Granted ${consentRoot.path}; no new turns to backfill.`);
203
+ try {
204
+ const service = reconcileCaptureService(serviceBackend(), consentStore.list('approved').length);
205
+ if (service === 'not installed') {
206
+ console.log('capture awaits elepha install');
207
+ }
208
+ }
209
+ catch (error) {
210
+ console.error(`consent recorded; capture service failed to activate: ${errorMessage(error)}`);
211
+ process.exitCode = 1;
212
+ }
213
+ });
214
+ consent
215
+ .command('revoke')
216
+ .description('Revoke consent for a root without deleting its captured memory')
217
+ .argument('[path]', 'memory root to revoke')
218
+ .option('--here', 'use the current working directory as the memory root')
219
+ .action((rootPath, options) => {
220
+ const root = resolveConsentPath(rootPath, options);
221
+ if (root === undefined) {
222
+ return;
223
+ }
224
+ const db = openDb();
225
+ const consentStore = new ConsentStore(db);
226
+ const revoked = consentStore.revoke(root);
227
+ try {
228
+ reconcileCaptureService(serviceBackend(), consentStore.list('approved').length);
229
+ console.log(`Revoked ${revoked.path}; captured memory retained.`);
230
+ }
231
+ catch (error) {
232
+ console.error(`consent revoked; capture service failed to reconcile: ${errorMessage(error)}`);
233
+ process.exitCode = 1;
234
+ }
235
+ });
236
+ }
237
+ //# sourceMappingURL=consent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consent.js","sourceRoot":"","sources":["../../../src/cli/commands/consent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAC3F,OAAO,EAAoB,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAkB5C,MAAM,wBAAyB,SAAQ,KAAK;IACnB,KAAK;IAA1B,YAAqB,KAAe;QAChC,KAAK,CAAC,sCAAsC,CAAC,CAAC;qBAD7B,KAAK;QAEtB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IAC3C,CAAC;CACJ;AAED,SAAS,kBAAkB,CAAC,QAA4B,EAAE,OAA2B;IACjF,MAAM,OAAO,GAAG,QAAQ,KAAK,SAAS,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;IACtC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACjF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IACxC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,IAAI,CAAC;QACD,OAAO,oBAAoB,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAmB;IACzC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,KAAa;IAC5C,OAAO,YAAY,CAAC,gBAAgB,KAAK,2FAA2F,CAAC,CAAC;AAC1I,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,6EAA6E,CAAC,CAAC;IAEtI,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;QACtB,IAAI,CAAC;YACD,OAAO,CAAC,QAAQ,GAAG,MAAM,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;YACnC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO;SACF,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,GAAG,EAAE;QACT,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,OAAO;QACX,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACnF,CAAC;IACL,CAAC,CAAC,CAAC;IAEP,OAAO;SACF,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,GAAG,EAAE;QACT,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,OAAO;QACX,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACpD,CAAC;IACL,CAAC,CAAC,CAAC;IAEP,OAAO;SACF,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,yGAAyG,CAAC;SACtH,MAAM,CAAC,SAAS,EAAE,2FAA2F,CAAC;SAC9G,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;SACvE,MAAM,CAAC,KAAK,EAAE,OAA4B,EAAE,EAAE;QAC3C,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,kBAAkB,GAAG,KAAK,CAAC;QAC/B,MAAM,gBAAgB,CAAC;YACnB,cAAc,EAAE,OAAO,CAAC,KAAK;YAC7B,EAAE;YACF,cAAc,EAAE,eAAe;YAC/B,IAAI,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC;YACnC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;gBACf,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;oBAC1D,OAAO;gBACX,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;gBACnD,KAAK,MAAM,SAAS,IAAI,IAAI,EAAE,CAAC;oBAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC/D,CAAC;gBACD,OAAO,CAAC,GAAG,CACP,2EAA2E;oBACvE,uDAAuD,CAC9D,CAAC;YACN,CAAC;YACD,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YACpC,QAAQ,EAAE;gBACN,MAAM,EAAE,sGAAsG;aACjH;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;oBACpD,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,IAAI,MAAM,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBACzC,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;gBAChD,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;gBACZ,MAAM,gBAAgB,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,UAAmC,EAAE,EAAE;oBAC5E,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC;oBACpF,MAAM,YAAY,GAAa,EAAE,CAAC;oBAClC,IAAI,OAAO,GAAG,CAAC,CAAC;oBAChB,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;wBACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAoD,CAAC;wBACrG,MAAM,aAAa,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;wBAC3F,IACI,OAAO,KAAK,SAAS;4BACrB,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI;4BACpC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK;4BACtC,aAAa,KAAK,SAAS,CAAC,MAAM,EACpC,CAAC;4BACC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACvC,SAAS;wBACb,CAAC;wBACD,IAAI,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;4BACpC,OAAO,IAAI,CAAC,CAAC;wBACjB,CAAC;6BAAM,CAAC;4BACJ,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC3C,CAAC;oBACL,CAAC;oBACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC1B,MAAM,IAAI,wBAAwB,CAAC,YAAY,CAAC,CAAC;oBACrD,CAAC;oBACD,OAAO,OAAO,CAAC;gBACnB,CAAC,CAAC,CAAC;gBACH,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;gBACvC,OAAO,CAAC,GAAG,CACP,WAAW,OAAO,6FAA6F,CAClH,CAAC;YACN,CAAC;YACD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACb,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBACpE,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBACpF,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,kBAAkB,GAAG,IAAI,CAAC;oBAC1B,OAAO,CAAC,KAAK,CAAC,0BAA0B,SAAS,CAAC,MAAM,yCAAyC,CAAC,CAAC;oBACnG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACzB,CAAC;YACL,CAAC;SACJ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,IAAI,CAAC,CAAC,KAAK,YAAY,wBAAwB,CAAC,EAAE,CAAC;gBAC/C,MAAM,KAAK,CAAC;YAChB,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,yCAAyC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5G,OAAO,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;YAC1F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,IAAI,kBAAkB,EAAE,CAAC;YACrB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,CAAC;IACL,CAAC,CAAC,CAAC;IAEP,OAAO;SACF,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,0GAA0G,CAAC;SACvH,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;SAC1C,MAAM,CAAC,QAAQ,EAAE,sDAAsD,CAAC;SACxE,MAAM,CAAC,KAAK,EAAE,QAA4B,EAAE,OAA2B,EAAE,EAAE;QACxE,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,OAAO;QACX,CAAC;QACD,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,mDAAmD,CAAC,CAAC;YAC1E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACX,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CACP,QAAQ,GAAG,CAAC;YACR,CAAC,CAAC,WAAW,WAAW,CAAC,IAAI,gBAAgB,QAAQ,6BAA6B;YAClF,CAAC,CAAC,WAAW,WAAW,CAAC,IAAI,6BAA6B,CACjE,CAAC;QACF,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,uBAAuB,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;YAChG,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACjD,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yDAAyD,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,CAAC;IACL,CAAC,CAAC,CAAC;IAEP,OAAO;SACF,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gEAAgE,CAAC;SAC7E,QAAQ,CAAC,QAAQ,EAAE,uBAAuB,CAAC;SAC3C,MAAM,CAAC,QAAQ,EAAE,sDAAsD,CAAC;SACxE,MAAM,CAAC,CAAC,QAA4B,EAAE,OAA2B,EAAE,EAAE;QAClE,MAAM,IAAI,GAAG,kBAAkB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,OAAO;QACX,CAAC;QACD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC;YACD,uBAAuB,CAAC,cAAc,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;YAChF,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,CAAC,IAAI,6BAA6B,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yDAAyD,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,CAAC;IACL,CAAC,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,76 @@
1
+ import { errorMessage } from '../../util/error.js';
2
+ import { defaultDaemonControlRuntime, pauseCaptureService, resolveCaptureService, resumeCaptureService, } from '../capture-service.js';
3
+ const SERVICE_CONTROL_GUIDANCE = 'elepha capture service control is available on macOS and Linux after `elepha install`';
4
+ export function registerDaemonControl(program, runtime = defaultDaemonControlRuntime) {
5
+ program
6
+ .command('pause')
7
+ .description('Pause background capture until elepha resume')
8
+ .action(() => pauseCapture(runtime));
9
+ program
10
+ .command('resume')
11
+ .description('Resume background capture')
12
+ .action(() => resumeCapture(runtime));
13
+ program
14
+ .command('restart')
15
+ .description('Restart background capture (pause then resume)')
16
+ .action(() => restartCapture(runtime));
17
+ }
18
+ function pauseCapture(runtime) {
19
+ const service = serviceForControl(runtime);
20
+ if (!service) {
21
+ return;
22
+ }
23
+ try {
24
+ const result = pauseCaptureService(service);
25
+ printState(result.changed ? 'Capture daemon paused' : 'Capture daemon already paused', result.state);
26
+ }
27
+ catch (error) {
28
+ console.error(errorMessage(error));
29
+ process.exitCode = 1;
30
+ }
31
+ }
32
+ function resumeCapture(runtime) {
33
+ const service = serviceForControl(runtime);
34
+ if (!service) {
35
+ return;
36
+ }
37
+ try {
38
+ const result = resumeCaptureService(service, runtime);
39
+ printHealth(result.changed ? 'Capture daemon running' : 'Capture daemon already running', result.health.state);
40
+ }
41
+ catch (error) {
42
+ console.error(errorMessage(error));
43
+ process.exitCode = 1;
44
+ }
45
+ }
46
+ function restartCapture(runtime) {
47
+ const service = serviceForControl(runtime);
48
+ if (!service) {
49
+ return;
50
+ }
51
+ try {
52
+ pauseCaptureService(service);
53
+ const result = resumeCaptureService(service, runtime);
54
+ printHealth('Capture daemon restarted', result.health.state);
55
+ }
56
+ catch (error) {
57
+ console.error(errorMessage(error));
58
+ process.exitCode = 1;
59
+ }
60
+ }
61
+ function serviceForControl(runtime) {
62
+ const service = resolveCaptureService(runtime);
63
+ if (!service) {
64
+ console.error(SERVICE_CONTROL_GUIDANCE);
65
+ process.exitCode = 1;
66
+ }
67
+ return service;
68
+ }
69
+ function printState(prefix, state) {
70
+ const unknown = state.unknown ? ', unknown: true' : '';
71
+ console.log(`${prefix} (loaded: ${state.loaded}, disabled: ${state.disabled}${unknown}).`);
72
+ }
73
+ function printHealth(prefix, state) {
74
+ console.log(`${prefix} (${state}).`);
75
+ }
76
+ //# sourceMappingURL=daemon-control.js.map