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,72 @@
1
+ import { openDb } from '../../storage/db.js';
2
+ import { applySanitize, planSanitize, verifySanitize } from '../../storage/sanitize-backfill.js';
3
+ import { runDestructiveOp } from '../destructive-op.js';
4
+ export function registerSanitize(program) {
5
+ program
6
+ .command('sanitize', { hidden: true })
7
+ .description('Neutralize shell-active syntax already stored in rollups and turn rows. ' +
8
+ 'New writes are cleaned at the store choke points; this cleans what predates them. Dry-run by default.')
9
+ .option('--apply', 'actually rewrite the affected fields (default is a dry run that only prints them)')
10
+ .action(async (opts) => {
11
+ const db = openDb();
12
+ // Preview before acting, every time - including under --apply, and
13
+ // with the actual before/after text rather than a count. A backfill
14
+ // that rewrites stored memory is a destructive operation even though
15
+ // it deletes nothing.
16
+ await runDestructiveOp({
17
+ applyRequested: opts.apply,
18
+ db,
19
+ operationLabel: 'sanitize',
20
+ plan: () => planSanitize(db),
21
+ describe: printSanitizePlan,
22
+ isEmpty: (plan) => plan.changes.length === 0,
23
+ onEmpty: () => reportResidue(verifySanitize(db)),
24
+ messages: { dryRun: '\nDry run only - nothing was written. Re-run with --apply to rewrite these fields.' },
25
+ backupLog: console.log,
26
+ apply: (plan) => {
27
+ applySanitize(db);
28
+ console.log(`Rewrote ${plan.changes.length} field(s).`);
29
+ },
30
+ // Post-verification re-reads from SQL rather than trusting the plan
31
+ // that was just applied. A backfill that reports success without
32
+ // checking is exactly the silent-degradation shape this rule exists
33
+ // to close.
34
+ verify: () => reportResidue(verifySanitize(db)),
35
+ });
36
+ });
37
+ }
38
+ function reportResidue(residue) {
39
+ if (residue.length === 0) {
40
+ console.log('Verified: no stored field carries shell-active syntax.');
41
+ return;
42
+ }
43
+ console.error(`\nVERIFICATION FAILED: ${residue.length} stored value(s) still carry shell-active syntax:`);
44
+ for (const r of residue.slice(0, 20)) {
45
+ console.error(` ${r.table}#${r.rowId}.${r.field}: ${truncateForDisplay(r.text)}`);
46
+ }
47
+ if (residue.length > 20) {
48
+ console.error(` … and ${residue.length - 20} more.`);
49
+ }
50
+ process.exitCode = 1;
51
+ }
52
+ function printSanitizePlan(plan) {
53
+ if (plan.changes.length === 0) {
54
+ console.log('No stored field carries shell-active syntax. Nothing to sanitize.');
55
+ return;
56
+ }
57
+ console.log('The following stored fields would be rewritten:\n');
58
+ for (const c of plan.changes) {
59
+ console.log(` ${c.table}#${c.rowId}.${c.field}`);
60
+ console.log(` before: ${truncateForDisplay(c.before)}`);
61
+ console.log(` after: ${truncateForDisplay(c.after)}`);
62
+ }
63
+ console.log(`\n${plan.changes.length} field(s) across ${plan.rollupRows} rollup row(s) and ${plan.memoryRows} memory row(s).`);
64
+ }
65
+ function truncateForDisplay(s) {
66
+ if (!s) {
67
+ return '';
68
+ }
69
+ const oneLine = s.replace(/\n/g, '\\n');
70
+ return oneLine.length <= 200 ? oneLine : `${oneLine.slice(0, 200)}…`;
71
+ }
72
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../../src/cli/commands/sanitize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ import { ClaudeCodeAdapter } from '../../adapters/claude-code.js';
2
+ import { CodexAdapter } from '../../adapters/codex.js';
3
+ import { openDb } from '../../storage/db.js';
4
+ import { applyManualMerge, applyManualSplit, applyResegmentation, planManualMerge, planManualSplit, planResegmentation, verifyResegmentation, } from '../../storage/resegmentation.js';
5
+ import { prepareDestructiveApply } from '../shared.js';
6
+ export function registerSegment(program) {
7
+ program
8
+ .command('segment', { hidden: true })
9
+ .description('Preview or apply session re-segmentation, or manually correct one boundary. Dry-run by default; applied changes back up first.')
10
+ .option('--resegment', 'replay every retained native session through the current boundary evaluator')
11
+ .option('--split <sessionId>', 'split an integer session id')
12
+ .option('--at <turnIndex>', 'first retained turn_index of the new right-hand segment')
13
+ .option('--merge <sessionIds...>', 'merge two adjacent integer session ids')
14
+ .option('--apply', 'apply the previewed change (default is read-only preview)')
15
+ .action(async (opts) => {
16
+ const operations = Number(opts.resegment) + Number(opts.split !== undefined) + Number(opts.merge !== undefined);
17
+ if (operations !== 1) {
18
+ console.error('Choose exactly one: --resegment, --split <id> --at <turn_index>, or --merge <id> <id>.');
19
+ process.exitCode = 1;
20
+ return;
21
+ }
22
+ const db = openDb();
23
+ const adapters = {
24
+ 'claude-code': new ClaudeCodeAdapter(),
25
+ codex: new CodexAdapter(),
26
+ };
27
+ if (opts.resegment) {
28
+ const preview = await planResegmentation(db, adapters);
29
+ printResegmentationPlan(preview);
30
+ if (preview.affectedGroups === 0) {
31
+ console.log('\nNothing needs re-segmentation. Nothing was written.');
32
+ return;
33
+ }
34
+ if (!opts.apply) {
35
+ console.log('\nDry run only - nothing was written. Re-run with --apply to apply this exact migration shape.');
36
+ return;
37
+ }
38
+ if (!prepareDestructiveApply(db, 'destructive segmentation')) {
39
+ return;
40
+ }
41
+ applyResegmentation(db, preview);
42
+ const verification = verifyResegmentation(db, preview);
43
+ if (!verification.ok) {
44
+ console.error(`\nVERIFICATION FAILED:\n${verification.errors.map((error) => ` - ${error}`).join('\n')}`);
45
+ process.exitCode = 1;
46
+ return;
47
+ }
48
+ console.log(`\nApplied ${preview.affectedGroups} native-session migration(s); invalidated affected rollups. ` +
49
+ 'Verified retained-turn partitions, trailing state, and foreign keys.');
50
+ return;
51
+ }
52
+ if (opts.split !== undefined) {
53
+ const sessionId = parseIntegerOption(opts.split, '--split');
54
+ const atTurnIndex = parseIntegerOption(opts.at, '--at');
55
+ if (sessionId === undefined || atTurnIndex === undefined) {
56
+ return;
57
+ }
58
+ let preview;
59
+ try {
60
+ preview = await planManualSplit(db, adapters, sessionId, atTurnIndex);
61
+ }
62
+ catch (error) {
63
+ console.error(`Cannot split: ${error.message}`);
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+ console.log(`Split preview: session ${preview.source.id} (${preview.source.tool}:${preview.source.native_id}, segment ${preview.source.segment_index}) ` +
68
+ `at turn ${preview.atTurnIndex}: ${preview.left.turnIndexes.length} turn(s) + ${preview.right.turnIndexes.length} turn(s).`);
69
+ console.log(`Resulting indexes: ${preview.left.segmentIndex}, ${preview.right.segmentIndex}; ` +
70
+ `${preview.laterSessionIds.length} later segment(s) shift up; ${preview.rollupsInvalidated} rollup(s) invalidated.`);
71
+ if (!opts.apply) {
72
+ console.log('\nDry run only - nothing was written. Re-run with --apply to split.');
73
+ return;
74
+ }
75
+ if (!prepareDestructiveApply(db, 'destructive segmentation')) {
76
+ return;
77
+ }
78
+ const newId = applyManualSplit(db, preview);
79
+ verifyForeignKeysOrFail(db);
80
+ console.log(`\nSplit applied: session ${preview.source.id} + new session ${newId}. Correction direction recorded as split.`);
81
+ return;
82
+ }
83
+ if (opts.merge?.length !== 2) {
84
+ console.error('--merge requires exactly two integer session ids.');
85
+ process.exitCode = 1;
86
+ return;
87
+ }
88
+ const firstId = parseIntegerOption(opts.merge[0], '--merge');
89
+ const secondId = parseIntegerOption(opts.merge[1], '--merge');
90
+ if (firstId === undefined || secondId === undefined) {
91
+ return;
92
+ }
93
+ let preview;
94
+ try {
95
+ preview = await planManualMerge(db, adapters, firstId, secondId);
96
+ }
97
+ catch (error) {
98
+ console.error(`Cannot merge: ${error.message}`);
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+ console.log(`Merge preview: sessions ${preview.left.id} + ${preview.right.id} ` +
103
+ `(${preview.left.tool}:${preview.left.native_id}, indexes ${preview.left.segment_index}/${preview.right.segment_index}) ` +
104
+ `into ${preview.merged.turnIndexes.length} retained turn(s).`);
105
+ console.log(`${preview.laterSessionIds.length} later segment(s) shift down; ${preview.rollupsInvalidated} rollup(s) invalidated.`);
106
+ if (!opts.apply) {
107
+ console.log('\nDry run only - nothing was written. Re-run with --apply to merge.');
108
+ return;
109
+ }
110
+ if (!prepareDestructiveApply(db, 'destructive segmentation')) {
111
+ return;
112
+ }
113
+ const keptId = applyManualMerge(db, preview);
114
+ verifyForeignKeysOrFail(db);
115
+ console.log(`\nMerge applied: kept session ${keptId}. Correction direction recorded as merge.`);
116
+ });
117
+ }
118
+ function parseIntegerOption(value, name) {
119
+ if (value === undefined || !/^\d+$/.test(value)) {
120
+ console.error(`${name} requires a non-negative integer.`);
121
+ process.exitCode = 1;
122
+ return undefined;
123
+ }
124
+ return Number(value);
125
+ }
126
+ function verifyForeignKeysOrFail(db) {
127
+ const violations = db.pragma('foreign_key_check');
128
+ if (violations.length > 0) {
129
+ throw new Error(`foreign_key_check returned ${violations.length} violation(s)`);
130
+ }
131
+ }
132
+ function printResegmentationPlan(plan) {
133
+ console.log(`Re-segmentation preview: ${plan.sessionsScanned} existing row(s), ${plan.nativeSessionsScanned} native session(s), ` +
134
+ `${plan.retainedTurnsScanned} retained turn(s).`);
135
+ for (const group of plan.groups) {
136
+ if (group.status === 'skipped') {
137
+ console.log(`SKIP ${group.existingSessionIds.join(',')} ${group.tool}:${group.nativeId}: ${group.issue ?? 'unknown reason'} ` +
138
+ `(${group.retainedTurnCount} retained turn(s)).`);
139
+ continue;
140
+ }
141
+ const state = group.requiresWrite ? 'CHANGE' : 'UNCHANGED';
142
+ console.log(`${state} ${group.existingSessionIds.join(',')} ${group.tool}:${group.nativeId}: ` +
143
+ `${group.existingSegmentCount} -> ${group.resultingSegments.length} segment(s), ${group.retainedTurnCount} retained turn(s), ` +
144
+ `${group.rollupsInvalidated} rollup(s) invalidated.`);
145
+ for (const cut of group.cuts) {
146
+ const overlap = cut.fileOverlap === null ? 'unavailable' : cut.fileOverlap.toFixed(3);
147
+ console.log(` cut before turn ${cut.atTurnIndex}: gap ${cut.gapHours.toFixed(2)}h; evidence ${cut.evidence.join('+')}; file overlap ${overlap}`);
148
+ }
149
+ }
150
+ console.log(`\nResult: ${plan.affectedGroups} changed, ${plan.readyGroups - plan.affectedGroups} unchanged, ${plan.skippedGroups} skipped; ` +
151
+ `${plan.resultingSessionRows} resulting row(s) across processable native sessions.`);
152
+ }
153
+ //# sourceMappingURL=segment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment.js","sourceRoot":"","sources":["../../../src/cli/commands/segment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { selfUpdate } from '../../install/self-update.js';
2
+ import { ConsentStore } from '../../storage/consent-store.js';
3
+ import { openDb } from '../../storage/db.js';
4
+ import { errorMessage } from '../../util/error.js';
5
+ export function registerSelfUpdate(program) {
6
+ program
7
+ .command('self-update')
8
+ .description('Update the global build, restart capture, and verify the daemon is healthy')
9
+ .action(() => {
10
+ try {
11
+ const approvedRoots = new ConsentStore(openDb()).countApproved();
12
+ const result = selfUpdate({ approvedRoots });
13
+ if (result.status === 'updated') {
14
+ console.log(`elepha updated: ${result.previousVersion} → ${result.version}`);
15
+ return;
16
+ }
17
+ console.error(`elepha update to ${result.attemptedVersion} failed; restored ${result.previousVersion} and verified capture is healthy: ${result.failure}`);
18
+ process.exitCode = 1;
19
+ }
20
+ catch (error) {
21
+ console.error(errorMessage(error));
22
+ process.exitCode = 1;
23
+ }
24
+ });
25
+ }
26
+ //# sourceMappingURL=self-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-update.js","sourceRoot":"","sources":["../../../src/cli/commands/self-update.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IAC/C,OAAO;SACF,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,4EAA4E,CAAC;SACzF,MAAM,CAAC,GAAG,EAAE;QACT,IAAI,CAAC;YACD,MAAM,aAAa,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC;YACjE,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;YAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,eAAe,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7E,OAAO;YACX,CAAC;YACD,OAAO,CAAC,KAAK,CACT,oBAAoB,MAAM,CAAC,gBAAgB,qBAAqB,MAAM,CAAC,eAAe,qCAAqC,MAAM,CAAC,OAAO,EAAE,CAC9I,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,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;AACX,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { unlinkSync } from 'node:fs';
2
+ import { elephaLaunchFailurePath } from '../../config/paths.js';
3
+ import { IngestionDaemon } from '../../daemon/index.js';
4
+ import { RollupService } from '../../daemon/rollup-service.js';
5
+ import { openDb } from '../../storage/db.js';
6
+ import { MemoryStore } from '../../storage/memory-store.js';
7
+ import { RollupStore } from '../../storage/rollup-store.js';
8
+ import { createConfiguredSynthesisProviders } from '../../summarizer/provider-config.js';
9
+ export function registerStart(program) {
10
+ program
11
+ .command('start', { hidden: true })
12
+ .description('Run the ingestion daemon in the foreground, watching sessions from supported AI coding tools')
13
+ .action(() => {
14
+ const log = (msg) => console.log(msg);
15
+ const logError = (msg) => console.error(msg);
16
+ const db = openDb();
17
+ const store = new MemoryStore(db);
18
+ if (store.consent.list('approved').length === 0) {
19
+ console.log('capture is awaiting consent; run `elepha init` to choose projects, nothing to do, exiting.');
20
+ return;
21
+ }
22
+ const rollups = new RollupStore(db);
23
+ const providers = createConfiguredSynthesisProviders();
24
+ const rollupService = providers
25
+ ? new RollupService({
26
+ store,
27
+ rollups,
28
+ provider: providers.rollupMerge,
29
+ log,
30
+ logError,
31
+ })
32
+ : undefined;
33
+ log(providers
34
+ ? `[elepha] synthesis provider: ${providers.name}`
35
+ : '[elepha] no synthesis provider configured; running capture-only');
36
+ const daemon = new IngestionDaemon({ store, summarizer: providers?.turnExtraction, rollupService, rollups, log, logError });
37
+ daemon.start();
38
+ // A successful watcher plus first heartbeat is the only event that
39
+ // clears a prior launcher failure; probes and status must preserve it.
40
+ try {
41
+ unlinkSync(elephaLaunchFailurePath());
42
+ }
43
+ catch {
44
+ // No diagnostic record is the normal case.
45
+ }
46
+ const shutdown = () => {
47
+ void daemon.stop().then(() => process.exit(0));
48
+ };
49
+ process.on('SIGINT', shutdown);
50
+ process.on('SIGTERM', shutdown);
51
+ });
52
+ }
53
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,kCAAkC,EAAE,MAAM,qCAAqC,CAAC;AAEzF,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC1C,OAAO;SACF,OAAO,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SAClC,WAAW,CAAC,8FAA8F,CAAC;SAC3G,MAAM,CAAC,GAAG,EAAE;QACT,MAAM,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAC;YAC1G,OAAO;QACX,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,kCAAkC,EAAE,CAAC;QACvD,MAAM,aAAa,GAAG,SAAS;YAC3B,CAAC,CAAC,IAAI,aAAa,CAAC;gBACd,KAAK;gBACL,OAAO;gBACP,QAAQ,EAAE,SAAS,CAAC,WAAW;gBAC/B,GAAG;gBACH,QAAQ;aACX,CAAC;YACJ,CAAC,CAAC,SAAS,CAAC;QAChB,GAAG,CACC,SAAS;YACL,CAAC,CAAC,gCAAgC,SAAS,CAAC,IAAI,EAAE;YAClD,CAAC,CAAC,iEAAiE,CAC1E,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5H,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,mEAAmE;QACnE,uEAAuE;QACvE,IAAI,CAAC;YACD,UAAU,CAAC,uBAAuB,EAAE,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACL,2CAA2C;QAC/C,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,EAAE;YAClB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { openDb } from '../../storage/db.js';
2
+ import { MemoryStore } from '../../storage/memory-store.js';
3
+ import { parseSince } from '../../storage/stats.js';
4
+ export function registerStats(program) {
5
+ program
6
+ .command('stats', { hidden: true })
7
+ .description('Dogfooding instrumentation: ingestion volume, summarizer noise rate, pending_items accumulation, files_touched miss rate')
8
+ .option('--since <window>', 'time window: "24h", "7d", "30m", or an ISO date', '24h')
9
+ .action((opts) => {
10
+ const store = new MemoryStore(openDb());
11
+ const sinceIso = parseSince(opts.since);
12
+ printStats(store.getStats(sinceIso));
13
+ });
14
+ }
15
+ function printStats(s) {
16
+ console.log(`stats since ${s.since} (${s.totalMemories} memories total)\n`);
17
+ console.log('sessions/turns by tool:');
18
+ for (const t of s.byTool) {
19
+ console.log(` ${t.tool}: ${t.sessions} sessions, ${t.turns} turns`);
20
+ }
21
+ const mps = s.memoriesPerSession;
22
+ console.log(`\nmemories per session: min ${mps.min} / median ${mps.median} / max ${mps.max} (n=${mps.count} sessions)`);
23
+ const pps = s.pendingItemsPerSession;
24
+ console.log(`pending_items per session: min ${pps.min} / median ${pps.median} / max ${pps.max}`);
25
+ const noisePct = s.noise.total > 0 ? ((100 * s.noise.count) / s.noise.total).toFixed(1) : '0.0';
26
+ console.log(`\nnoise (empty decisions AND empty pending_items): ${s.noise.count}/${s.noise.total} (${noisePct}%)`);
27
+ console.log('\nby summarizer_status (breaks noise into genuine-silence vs pipeline-failure):');
28
+ for (const s2 of s.byStatus) {
29
+ const pct = s.noise.total > 0 ? ((100 * s2.count) / s.noise.total).toFixed(1) : '0.0';
30
+ console.log(` ${s2.summarizer_status}: ${s2.count} (${pct}%)`);
31
+ }
32
+ console.log('\nfiles_touched = zero paths, by tool:');
33
+ for (const f of s.filesTouchedZero) {
34
+ const pct = f.total > 0 ? ((100 * f.zero_paths) / f.total).toFixed(1) : '0.0';
35
+ console.log(` ${f.tool}: ${f.zero_paths}/${f.total} (${pct}%)`);
36
+ }
37
+ console.log('\nby project (memories / open pending_items):');
38
+ for (const p of s.byProject) {
39
+ console.log(` ${p.project}: ${p.memories} / ${p.open_pending_items ?? 0}`);
40
+ }
41
+ }
42
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/cli/commands/stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { daemonHealth, integrationHealth } from '../../install/health-checks.js';
2
+ import { openDb } from '../../storage/db.js';
3
+ import { MemoryStore } from '../../storage/memory-store.js';
4
+ import { parseSince } from '../../storage/stats.js';
5
+ import { SummarizerCallLog } from '../../summarizer/call-log.js';
6
+ import { synthesisProviderName } from '../../summarizer/provider-config.js';
7
+ import { errorMessage } from '../../util/error.js';
8
+ import { synthesisStatusReport } from '../status.js';
9
+ /**
10
+ * Daemon liveness, derived from the same heartbeat file `status` reports.
11
+ * `daemonHealth` is shared so `rollup --rebuild` can refuse to race a live
12
+ * daemon without duplicating the pid/staleness logic.
13
+ */
14
+ export function registerStatus(program) {
15
+ program
16
+ .command('status')
17
+ .description('One-line daemon health check: running/stuck/not-running, last ingest time, turns in the last 24h')
18
+ .action(() => {
19
+ const now = Date.now();
20
+ const { state, healthy } = daemonHealth();
21
+ const store = new MemoryStore(openDb());
22
+ const lastIngestedAt = store.getLastIngestedAt();
23
+ const lastIngestStr = lastIngestedAt
24
+ ? `${lastIngestedAt} (${humanAge(now - new Date(lastIngestedAt).getTime())} ago)`
25
+ : 'never';
26
+ const turns24h = store.getStats(parseSince('24h')).totalMemories;
27
+ const pendingConsent = store.consent.list('pending').length;
28
+ // Provider health is part of the verdict only when synthesis is
29
+ // configured. Capture-only is the normal default, so historical call
30
+ // failures cannot make an intentionally unconfigured daemon degraded.
31
+ const callLogEntries24h = new SummarizerCallLog().readEntriesSince(parseSince('24h'));
32
+ const synthesis = synthesisStatusReport(synthesisProviderName(), callLogEntries24h);
33
+ console.log(`${state} — last ingest: ${lastIngestStr} — ${turns24h} turns in last 24h`);
34
+ if (pendingConsent > 0) {
35
+ console.log(`consent: ${pendingConsent} root(s) pending approval`);
36
+ }
37
+ console.log(synthesis.line);
38
+ try {
39
+ const integration = integrationHealth();
40
+ const { bin, status: install } = integration;
41
+ console.log(`install binary: ${bin}`);
42
+ console.log(`Claude hook: ${install.claudeHook}`);
43
+ console.log(`Claude UserPromptSubmit hook: ${install.claudeUserPromptSubmitHook}`);
44
+ console.log(`Codex hook: ${install.codexHook}`);
45
+ console.log(`Codex UserPromptSubmit hook: ${install.codexUserPromptSubmitHook}`);
46
+ console.log(`Claude MCP: ${install.claudeMcp}`);
47
+ console.log(`Codex MCP: ${install.codexMcp}`);
48
+ console.log(`install: ${install.ready ? 'ready' : 'action required'}`);
49
+ process.exitCode = healthy && synthesis.healthy && install.ready ? 0 : 1;
50
+ }
51
+ catch (error) {
52
+ console.log(`install binary: ${errorMessage(error)}`);
53
+ console.log('install: action required');
54
+ process.exitCode = 1;
55
+ }
56
+ });
57
+ }
58
+ function humanAge(ms) {
59
+ const s = Math.max(0, Math.round(ms / 1000));
60
+ if (s < 60) {
61
+ return `${s}s`;
62
+ }
63
+ const m = Math.round(s / 60);
64
+ if (m < 60) {
65
+ return `${m}m`;
66
+ }
67
+ const h = Math.round(m / 60);
68
+ if (h < 24) {
69
+ return `${h}h`;
70
+ }
71
+ return `${Math.round(h / 24)}d`;
72
+ }
73
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { uninstallElepha } from '../../install/installer.js';
2
+ import { ConsentStore } from '../../storage/consent-store.js';
3
+ import { openDb } from '../../storage/db.js';
4
+ import { errorMessage } from '../../util/error.js';
5
+ import { printInstallation } from '../shared.js';
6
+ export function registerUninstall(program) {
7
+ const hook = program.commands.find((command) => command.name() === 'hook');
8
+ if (!hook) {
9
+ throw new Error('Uninstall hooks require the hidden hook command to be registered first.');
10
+ }
11
+ program.command('uninstall').description('Remove only elepha global registrations').action(runUninstall);
12
+ hook.command('uninstall').action(runUninstall);
13
+ }
14
+ function runUninstall() {
15
+ try {
16
+ printInstallation(uninstallElepha(undefined, { approvedRoots: new ConsentStore(openDb()).countApproved() }), 'uninstall');
17
+ }
18
+ catch (error) {
19
+ console.error(errorMessage(error));
20
+ process.exitCode = 1;
21
+ }
22
+ }
23
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../../src/cli/commands/uninstall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,MAAM,CAAC,CAAC;IAC3E,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC/F,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,yCAAyC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACzG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,YAAY;IACjB,IAAI,CAAC;QACD,iBAAiB,CAAC,eAAe,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IAC9H,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzB,CAAC;AACL,CAAC"}
@@ -0,0 +1,104 @@
1
+ import * as clack from '@clack/prompts';
2
+ import { elephaConfigPath } from '../config/paths.js';
3
+ import { listSettings, SETTING_SCHEMA, setSetting, unsetSetting } from '../config/settings.js';
4
+ import { errorMessage } from '../util/error.js';
5
+ import { printTagline } from './wordmark.js';
6
+ function clackPrompts(input, output) {
7
+ const common = { input, output };
8
+ return {
9
+ intro: (title) => clack.intro(title, common),
10
+ note: (message, title) => clack.note(message, title, common),
11
+ select: (options) => clack.select({ ...options, ...common }),
12
+ isCancel: clack.isCancel,
13
+ cancel: (message) => clack.cancel(message, common),
14
+ outro: (message) => clack.outro(message, common),
15
+ };
16
+ }
17
+ function cancelled(prompts) {
18
+ prompts.cancel('Operation cancelled. No changes were made.');
19
+ return 0;
20
+ }
21
+ export function renderSettingValue(key, value) {
22
+ if (SETTING_SCHEMA[key].kind === 'boolean') {
23
+ const enabled = typeof value === 'boolean' ? value : value === 'on';
24
+ return enabled ? 'On' : 'Off';
25
+ }
26
+ return String(value);
27
+ }
28
+ function sourceMarker(setting) {
29
+ return setting.source === 'config' ? '' : ` (${setting.source})`;
30
+ }
31
+ export function renderSetting(setting) {
32
+ return `${setting.key} = ${renderSettingValue(setting.key, setting.value)}${sourceMarker(setting)}`;
33
+ }
34
+ function settingOptions(settings) {
35
+ return settings.map((setting) => ({
36
+ value: setting.key,
37
+ label: renderSetting(setting),
38
+ }));
39
+ }
40
+ function isDefaultChoice(key, value) {
41
+ const schema = SETTING_SCHEMA[key];
42
+ if (schema.kind === 'boolean') {
43
+ return (value === 'on') === schema.default;
44
+ }
45
+ return value === schema.default;
46
+ }
47
+ function settingChoices(key) {
48
+ const schema = SETTING_SCHEMA[key];
49
+ const values = schema.kind === 'boolean' ? schema.values.filter((value) => value === 'on' || value === 'off') : schema.values;
50
+ return values.map((value) => ({
51
+ value,
52
+ label: `${renderSettingValue(key, value)}${isDefaultChoice(key, value) ? ' (default)' : ''}`,
53
+ }));
54
+ }
55
+ /** Interactive settings picker for bare `elepha config`. */
56
+ export async function runConfigWizard(options = {}) {
57
+ const input = options.input ?? process.stdin;
58
+ const output = options.output ?? process.stdout;
59
+ const prompts = options.prompts ?? clackPrompts(input, output);
60
+ const configPath = options.configPath ?? elephaConfigPath();
61
+ const environment = options.environment ?? process.env;
62
+ printTagline(output);
63
+ prompts.intro('Configure elepha');
64
+ while (true) {
65
+ const settings = listSettings(environment, configPath);
66
+ const selected = await prompts.select({
67
+ message: 'Which setting should elepha change?',
68
+ options: settingOptions(settings),
69
+ });
70
+ if (prompts.isCancel(selected) || typeof selected !== 'string') {
71
+ return cancelled(prompts);
72
+ }
73
+ const setting = settings.find((candidate) => candidate.key === selected);
74
+ if (!setting) {
75
+ return cancelled(prompts);
76
+ }
77
+ if (setting.source === 'env') {
78
+ prompts.note('ELEPHA_NO_UPDATE_CHECK currently overrides this setting for this run. Your config preference will still be saved.', 'Environment override');
79
+ }
80
+ const choices = settingChoices(setting.key);
81
+ const choice = await prompts.select({
82
+ message: `How should ${setting.key} be configured?`,
83
+ options: choices,
84
+ });
85
+ if (prompts.isCancel(choice) || typeof choice !== 'string' || !choices.some((option) => option.value === choice)) {
86
+ return cancelled(prompts);
87
+ }
88
+ try {
89
+ if (isDefaultChoice(setting.key, choice)) {
90
+ unsetSetting(setting.key, configPath);
91
+ prompts.outro(`${setting.key} returned to its default.`);
92
+ }
93
+ else {
94
+ setSetting(setting.key, choice, configPath);
95
+ prompts.outro(`${setting.key} set to ${renderSettingValue(setting.key, choice)}.`);
96
+ }
97
+ return 0;
98
+ }
99
+ catch (error) {
100
+ prompts.note(errorMessage(error), 'Setting unchanged');
101
+ }
102
+ }
103
+ }
104
+ //# sourceMappingURL=config-wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-wizard.js","sourceRoot":"","sources":["../../src/cli/config-wizard.ts"],"names":[],"mappings":"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"}