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,261 @@
1
+ import { existsSync, readFileSync, statSync, unlinkSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { DAEMON_BOOTOUT_DEADLINE_MS, DAEMON_HEALTH_CHECK_POLL_MS, DAEMON_STATE_CHECK_ATTEMPTS, PLIST_PATH, PLIST_THROTTLE_INTERVAL_SECONDS, PLIST_UMASK, PRIVATE_DIR_MODE, PRIVATE_FILE_MODE, } from '../config/constants.js';
4
+ import { elephaPaths, elephaServiceLabel } from '../config/paths.js';
5
+ import { clearHeartbeat } from '../daemon/heartbeat.js';
6
+ import { atomicWrite, readJson } from '../util/fs.js';
7
+ import { boundedDaemonOutput, daemonHealthFailure, defaultDaemonHealthCheckRuntime, healthyHeartbeat, waitForHealthyHeartbeat, } from './daemon-health.js';
8
+ import { launcherHash } from './launcher.js';
9
+ import { managedServiceEnvironment, physicalInstallPath } from './service-manifest.js';
10
+ export { physicalInstallPath } from './service-manifest.js';
11
+ export function defaultLaunchdServicePaths(home = homedir()) {
12
+ const elepha = elephaPaths(home);
13
+ const label = elephaServiceLabel();
14
+ return {
15
+ home,
16
+ label,
17
+ launcher: elepha.launcher,
18
+ plist: elepha.launchAgent,
19
+ state: elepha.installState,
20
+ transaction: elepha.installTransaction,
21
+ heartbeat: elepha.heartbeat,
22
+ stdout: elepha.stdout,
23
+ stderr: elepha.stderr,
24
+ };
25
+ }
26
+ export function serviceDomain(uid = process.getuid?.()) {
27
+ if (typeof uid !== 'number') {
28
+ throw new Error('launchd requires a numeric user id');
29
+ }
30
+ return `gui/${uid}`;
31
+ }
32
+ export function serviceTarget(uid = process.getuid?.(), label = elephaServiceLabel()) {
33
+ return `${serviceDomain(uid)}/${label}`;
34
+ }
35
+ function xml(value) {
36
+ return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
37
+ }
38
+ /**
39
+ * The launchd process starts with a minimal environment. Propagate only
40
+ * location overrides needed to keep an explicitly isolated install together;
41
+ * secrets remain in the daemon's isolated .env file and never enter a plist.
42
+ * Values are rendered physical and absolute so the plist hash does not depend
43
+ * on how the installing shell spelled them.
44
+ */
45
+ export function managedPlistEnvironment(environment = process.env) {
46
+ return managedServiceEnvironment(environment);
47
+ }
48
+ /** Deterministic plist with no Node/package/repository path. */
49
+ export function renderDaemonPlist(paths, environment = process.env) {
50
+ const string = (value) => `<string>${xml(value)}</string>`;
51
+ const physical = (value) => string(physicalInstallPath(value));
52
+ const overrides = managedPlistEnvironment(environment)
53
+ .map(([key, value]) => `<key>${xml(key)}</key>${string(value)}`)
54
+ .join('');
55
+ return `<?xml version="1.0" encoding="UTF-8"?>
56
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
57
+ <plist version="1.0"><dict>
58
+ <key>Label</key>${string(paths.label)}
59
+ <key>ProgramArguments</key><array>${physical(paths.launcher)}${string('start')}</array>
60
+ <key>WorkingDirectory</key>${physical(paths.home)}
61
+ <key>RunAtLoad</key><true/>
62
+ <key>KeepAlive</key><dict><key>SuccessfulExit</key><false/></dict>
63
+ <key>ThrottleInterval</key><integer>${PLIST_THROTTLE_INTERVAL_SECONDS}</integer>
64
+ <key>ProcessType</key>${string('Background')}
65
+ <key>Umask</key><integer>${PLIST_UMASK}</integer>
66
+ <key>StandardOutPath</key>${physical(paths.stdout)}
67
+ <key>StandardErrorPath</key>${physical(paths.stderr)}
68
+ <key>EnvironmentVariables</key><dict><key>HOME</key>${physical(paths.home)}<key>PATH</key>${string(PLIST_PATH)}<key>ELEPHA_SERVICE</key>${string('1')}${overrides}</dict>
69
+ </dict></plist>
70
+ `;
71
+ }
72
+ export function readServiceManifest(file) {
73
+ const manifest = readJson(file);
74
+ return manifest?.version === 1 ? manifest : undefined;
75
+ }
76
+ export function launchdArtifactsMatch(paths) {
77
+ const manifest = readServiceManifest(paths.state);
78
+ if (!manifest || !existsSync(paths.launcher) || !existsSync(paths.plist)) {
79
+ return false;
80
+ }
81
+ return (launcherHash(readFileSync(paths.launcher, 'utf8')) === manifest.launcherHash &&
82
+ launcherHash(readFileSync(paths.plist, 'utf8')) === manifest.plistHash &&
83
+ (statSync(paths.launcher).mode & 0o777) === manifest.launcherMode &&
84
+ (statSync(paths.plist).mode & 0o777) === manifest.plistMode);
85
+ }
86
+ export class LaunchdBackend {
87
+ paths;
88
+ executor;
89
+ uid;
90
+ healthCheck;
91
+ lastBootstrapAttempt;
92
+ constructor(paths = defaultLaunchdServicePaths(), executor, uid = process.getuid?.(), healthCheck = defaultDaemonHealthCheckRuntime) {
93
+ this.paths = paths;
94
+ this.executor = executor;
95
+ this.uid = uid;
96
+ this.healthCheck = healthCheck;
97
+ }
98
+ get launcherPath() {
99
+ return this.paths.launcher;
100
+ }
101
+ get manifestPath() {
102
+ return this.paths.state;
103
+ }
104
+ get transactionPath() {
105
+ return this.paths.transaction;
106
+ }
107
+ get artifactPaths() {
108
+ return [this.paths.launcher, this.paths.plist, this.paths.state];
109
+ }
110
+ target() {
111
+ return serviceTarget(this.uid, this.paths.label);
112
+ }
113
+ isLoaded() {
114
+ return this.executor.run(['print', this.target()]).status === 0;
115
+ }
116
+ isDisabled() {
117
+ const result = this.executor.run(['print-disabled', serviceDomain(this.uid)]);
118
+ const label = this.paths.label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
119
+ return result.status === 0 && new RegExp(`^\\s*"${label}"\\s*=>\\s*(?:true|disabled)\\s*$`, 'm').test(result.stdout);
120
+ }
121
+ status() {
122
+ return { loaded: this.isLoaded(), disabled: this.isDisabled(), unknown: false };
123
+ }
124
+ waitFor(condition) {
125
+ // launchctl applies these per-user state changes synchronously in the
126
+ // normal case. Re-reading a bounded number of times still covers the
127
+ // short propagation window without turning lifecycle calls into an
128
+ // unbounded wait.
129
+ for (let attempt = 0; attempt < DAEMON_STATE_CHECK_ATTEMPTS; attempt++) {
130
+ if (condition()) {
131
+ return true;
132
+ }
133
+ }
134
+ return false;
135
+ }
136
+ boundedOutput(output) {
137
+ return boundedDaemonOutput(output);
138
+ }
139
+ formatLaunchctlResult(args, result) {
140
+ const stderr = this.boundedOutput(result.stderr);
141
+ const stdout = this.boundedOutput(result.stdout);
142
+ return `launchctl ${args.join(' ')} (status ${result.status}; stderr: ${stderr || 'no stderr'}; stdout: ${stdout || 'no stdout'})`;
143
+ }
144
+ launchctlFailure(args, result, details = []) {
145
+ return new Error(`${this.formatLaunchctlResult(args, result)} failed${details.length > 0 ? `; ${details.join('; ')}` : ''}`);
146
+ }
147
+ stop() {
148
+ if (!this.isLoaded()) {
149
+ return;
150
+ }
151
+ const result = this.executor.run(['bootout', this.target()]);
152
+ const deadline = this.healthCheck.now() + DAEMON_BOOTOUT_DEADLINE_MS;
153
+ while (this.isLoaded()) {
154
+ const remaining = deadline - this.healthCheck.now();
155
+ if (remaining <= 0) {
156
+ if (result.status !== 0) {
157
+ throw new Error('launchctl bootout failed');
158
+ }
159
+ throw new Error('launchctl bootout did not unload the service within 20s');
160
+ }
161
+ this.healthCheck.sleep(Math.min(DAEMON_HEALTH_CHECK_POLL_MS, remaining));
162
+ }
163
+ clearHeartbeat(this.paths.heartbeat);
164
+ }
165
+ disable() {
166
+ if (this.isDisabled()) {
167
+ return;
168
+ }
169
+ const result = this.executor.run(['disable', this.target()]);
170
+ // An unloaded target can still be enabled for the next login. Only
171
+ // launchd's explicit disabled state proves automatic restart is off.
172
+ if (!this.waitFor(() => this.isDisabled())) {
173
+ throw this.launchctlFailure(['disable', this.target()], result);
174
+ }
175
+ }
176
+ enable() {
177
+ const result = this.executor.run(['enable', this.target()]);
178
+ if (result.status !== 0 || this.isDisabled()) {
179
+ throw this.launchctlFailure(['enable', this.target()], result);
180
+ }
181
+ }
182
+ start() {
183
+ const target = this.target();
184
+ const args = ['bootstrap', serviceDomain(this.uid), this.paths.plist];
185
+ const before = this.executor.run(['print', target]);
186
+ if (before.status === 0) {
187
+ this.lastBootstrapAttempt = { args, print: before };
188
+ return;
189
+ }
190
+ const result = this.executor.run(args);
191
+ const print = this.executor.run(['print', target]);
192
+ this.lastBootstrapAttempt = { args, result, print };
193
+ if (result.status !== 0 || print.status !== 0) {
194
+ throw this.launchctlFailure(args, result, [
195
+ `post-bootstrap ${this.formatLaunchctlResult(['print', target], print)} ${print.status === 0 ? 'found service' : 'did not find service'}`,
196
+ ]);
197
+ }
198
+ }
199
+ restart() {
200
+ this.stop();
201
+ this.start();
202
+ }
203
+ hasArtifacts() {
204
+ return existsSync(this.paths.state);
205
+ }
206
+ isInstalled() {
207
+ return launchdArtifactsMatch(this.paths);
208
+ }
209
+ installationMatches(renderedLauncher) {
210
+ const manifest = readServiceManifest(this.paths.state);
211
+ if (!manifest || !existsSync(this.paths.launcher) || !existsSync(this.paths.plist)) {
212
+ return false;
213
+ }
214
+ if (!this.isInstalled()) {
215
+ throw new Error('managed daemon service artifact was modified; refusing to overwrite it');
216
+ }
217
+ const renderedPlist = renderDaemonPlist(this.paths);
218
+ return !(manifest.launcherHash !== launcherHash(renderedLauncher) || manifest.plistHash !== launcherHash(renderedPlist));
219
+ }
220
+ install(launcher, backend) {
221
+ const plist = renderDaemonPlist(this.paths);
222
+ atomicWrite(this.paths.launcher, launcher, PRIVATE_DIR_MODE);
223
+ atomicWrite(this.paths.plist, plist, PRIVATE_FILE_MODE);
224
+ const manifest = {
225
+ version: 1,
226
+ backend,
227
+ launcherHash: launcherHash(launcher),
228
+ launcherMode: PRIVATE_DIR_MODE,
229
+ plistHash: launcherHash(plist),
230
+ plistMode: PRIVATE_FILE_MODE,
231
+ };
232
+ atomicWrite(this.paths.state, `${JSON.stringify(manifest)}\n`, PRIVATE_FILE_MODE);
233
+ }
234
+ uninstall() {
235
+ for (const file of [this.paths.state, this.paths.plist, this.paths.launcher]) {
236
+ if (existsSync(file)) {
237
+ unlinkSync(file);
238
+ }
239
+ }
240
+ }
241
+ healthy() {
242
+ return healthyHeartbeat(this.paths.heartbeat, this.healthCheck.now());
243
+ }
244
+ /** Wait for launchd's launcher and daemon to produce a fresh healthy heartbeat. */
245
+ waitForHealthy() {
246
+ return waitForHealthyHeartbeat(() => this.healthy(), this.healthCheck);
247
+ }
248
+ healthFailure() {
249
+ const bootstrap = this.lastBootstrapAttempt;
250
+ const bootstrapDetail = bootstrap
251
+ ? bootstrap.result
252
+ ? this.formatLaunchctlResult(bootstrap.args, bootstrap.result)
253
+ : `launchctl ${bootstrap.args.join(' ')} skipped because the service was already loaded`
254
+ : 'launchctl bootstrap was not attempted';
255
+ const printDetail = bootstrap
256
+ ? `post-bootstrap ${this.formatLaunchctlResult(['print', this.target()], bootstrap.print)} ${bootstrap.print.status === 0 ? 'found service' : 'did not find service'}`
257
+ : `post-bootstrap launchctl print ${this.target()} was not recorded`;
258
+ return daemonHealthFailure(this.paths.stderr, [bootstrapDetail, printDetail]);
259
+ }
260
+ }
261
+ //# sourceMappingURL=launchd-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launchd-backend.js","sourceRoot":"","sources":["../../src/install/launchd-backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,224 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { accessSync, readdirSync, readFileSync, realpathSync, statSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { LAUNCHER_MARKER } from './markers.js';
5
+ const VERSION_STORE = /(?:^|\/)(?:versions\/node|node-versions|installs\/nodejs|Cellar\/node[^/]*)\//;
6
+ const FIXED_PROBE = "var n=+process.versions.node.split('.')[0],m=+process.argv[1];process.exit(n>=m?0:65)";
7
+ function executable(file) {
8
+ try {
9
+ return statSync(file).isFile() && (statSync(file).mode & 0o111) !== 0;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ function executableOnPath(name, value) {
16
+ return value
17
+ ?.split(path.delimiter)
18
+ .filter(Boolean)
19
+ .map((directory) => path.resolve(directory, name))
20
+ .find(executable);
21
+ }
22
+ function readable(file) {
23
+ try {
24
+ accessSync(file, 4);
25
+ return true;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ function shellQuote(value) {
32
+ return `'${value.replaceAll("'", "'\\''")}'`;
33
+ }
34
+ function readNodeMajor(packageRoot) {
35
+ let engines;
36
+ try {
37
+ engines = JSON.parse(readFileSync(path.join(packageRoot, 'package.json'), 'utf8')).engines;
38
+ }
39
+ catch {
40
+ throw new Error('package-invalid: elepha package.json is unreadable');
41
+ }
42
+ const node = engines && typeof engines === 'object' ? engines.node : undefined;
43
+ const match = typeof node === 'string' ? /^>=(\d+)$/.exec(node) : null;
44
+ if (!match) {
45
+ throw new Error('package-invalid: elepha engines.node must use the canonical >=N form');
46
+ }
47
+ return Number(match[1]);
48
+ }
49
+ function resolveDefaultNvm(root) {
50
+ const aliasDir = path.join(root, 'alias');
51
+ const defaultPath = path.join(aliasDir, 'default');
52
+ if (!readable(defaultPath)) {
53
+ return undefined;
54
+ }
55
+ let value = readFileSync(defaultPath, 'utf8').trim();
56
+ const seen = new Set();
57
+ for (let depth = 0; depth < 16; depth++) {
58
+ if (seen.has(value)) {
59
+ return undefined;
60
+ }
61
+ seen.add(value);
62
+ if (value === 'node') {
63
+ return readVersions(path.join(root, 'versions', 'node')).at(-1);
64
+ }
65
+ if (value.startsWith('lts/')) {
66
+ const lts = path.join(aliasDir, 'lts', value.slice(4));
67
+ if (!readable(lts)) {
68
+ return undefined;
69
+ }
70
+ value = readFileSync(lts, 'utf8').trim();
71
+ continue;
72
+ }
73
+ const alias = path.join(aliasDir, value);
74
+ if (readable(alias)) {
75
+ value = readFileSync(alias, 'utf8').trim();
76
+ continue;
77
+ }
78
+ const versions = readVersions(path.join(root, 'versions', 'node'));
79
+ const partial = /^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?$/.exec(value);
80
+ if (!partial) {
81
+ return undefined;
82
+ }
83
+ const [, major, minor, patch] = partial;
84
+ return versions
85
+ .filter((version) => {
86
+ const installed = /^v(\d+)\.(\d+)\.(\d+)$/.exec(version);
87
+ return !!installed && installed[1] === major && (!minor || installed[2] === minor) && (!patch || installed[3] === patch);
88
+ })
89
+ .at(-1);
90
+ }
91
+ return undefined;
92
+ }
93
+ function readVersions(dir) {
94
+ try {
95
+ return readdirSync(dir)
96
+ .filter((entry) => /^v\d+\.\d+\.\d+$/.test(entry))
97
+ .sort(compareNodeVersions);
98
+ }
99
+ catch {
100
+ return [];
101
+ }
102
+ }
103
+ function compareNodeVersions(left, right) {
104
+ const leftParts = left.slice(1).split('.').map(Number);
105
+ const rightParts = right.slice(1).split('.').map(Number);
106
+ return leftParts[0] - rightParts[0] || leftParts[1] - rightParts[1] || leftParts[2] - rightParts[2];
107
+ }
108
+ function nvmDefaultMismatchError(defaultVersion, activeVersion) {
109
+ return new Error(`elepha install must run from the Node manager's default (default resolves to ${defaultVersion ?? 'no installed version'}, active is ${activeVersion}); switch to that default or reinstall elepha under it.`);
110
+ }
111
+ /**
112
+ * Select the manager that owns process.execPath. Discovery is only metadata and
113
+ * stable control files; no manager binary or shell is executed here.
114
+ */
115
+ export function detectLauncherBackend(options) {
116
+ const execPath = realpathSync(options.execPath ?? process.execPath);
117
+ const env = options.env ?? process.env;
118
+ const home = options.home ?? env.HOME;
119
+ const min = readNodeMajor(options.packageRoot);
120
+ if (min !== options.minimumNodeMajor) {
121
+ throw new Error('package-invalid: launcher minimum Node major disagrees with package');
122
+ }
123
+ const nvmMarker = '/versions/node/';
124
+ const nvmIndex = execPath.indexOf(nvmMarker);
125
+ if (nvmIndex >= 0) {
126
+ const root = execPath.slice(0, nvmIndex);
127
+ const active = path.basename(path.dirname(path.dirname(execPath)));
128
+ const nvmExec = path.join(root, 'nvm-exec');
129
+ const defaultVersion = resolveDefaultNvm(root);
130
+ if (executable(nvmExec) && readable(path.join(root, 'nvm.sh')) && defaultVersion === active) {
131
+ return { kind: 'nvm', command: nvmExec, root };
132
+ }
133
+ throw nvmDefaultMismatchError(defaultVersion, active);
134
+ }
135
+ const fnmMarker = '/node-versions/';
136
+ const fnmIndex = execPath.indexOf(fnmMarker);
137
+ if (fnmIndex >= 0) {
138
+ const root = execPath.slice(0, fnmIndex);
139
+ const fnm = env.FNM_DIR ? path.join(env.FNM_DIR, 'fnm') : undefined;
140
+ const stable = [executableOnPath('fnm', env.PATH), fnm, '/opt/homebrew/bin/fnm', '/usr/local/bin/fnm'].find((candidate) => !!candidate && executable(candidate));
141
+ if (!stable || !readable(path.join(root, 'aliases', 'default'))) {
142
+ throw new Error("elepha install must run from the selected Node manager's current default");
143
+ }
144
+ return { kind: 'fnm', command: stable, root };
145
+ }
146
+ const asdfMarker = '/installs/nodejs/';
147
+ const asdfIndex = execPath.indexOf(asdfMarker);
148
+ if (asdfIndex >= 0) {
149
+ const root = execPath.slice(0, asdfIndex);
150
+ const asdf = [executableOnPath('asdf', env.PATH), '/opt/homebrew/bin/asdf', '/usr/local/bin/asdf', path.join(root, 'asdf')].find((candidate) => !!candidate && executable(candidate));
151
+ const toolVersions = home ? path.join(home, '.tool-versions') : '';
152
+ const active = path.basename(path.dirname(path.dirname(execPath)));
153
+ const nodeVersion = readable(toolVersions) ? /^nodejs\s+(\S+)/m.exec(readFileSync(toolVersions, 'utf8'))?.[1] : undefined;
154
+ if (!asdf || !nodeVersion || nodeVersion !== active || !executable(path.join(root, 'shims', 'elepha'))) {
155
+ throw new Error("elepha install must run from the selected Node manager's current default");
156
+ }
157
+ return { kind: 'asdf', command: asdf, root };
158
+ }
159
+ const cellar = /^(\/opt\/homebrew|\/usr\/local)\/Cellar\/(node[^/]*)\/[^/]+\/bin\/node$/.exec(execPath);
160
+ if (cellar) {
161
+ const opt = path.join(cellar[1], 'opt', cellar[2]);
162
+ const node = path.join(opt, 'bin', 'node');
163
+ if (!executable(node) || VERSION_STORE.test(options.sourceBin)) {
164
+ throw new Error('unsupported or ambiguous Node installation');
165
+ }
166
+ return { kind: 'homebrew', command: options.sourceBin, node, npmBin: path.dirname(options.sourceBin) };
167
+ }
168
+ if ((execPath === '/usr/local/bin/node' || execPath === '/usr/bin/node') &&
169
+ ['/usr/local/bin', '/usr/bin'].includes(path.dirname(options.sourceBin))) {
170
+ return { kind: 'standalone', command: options.sourceBin, node: execPath, npmBin: path.dirname(options.sourceBin) };
171
+ }
172
+ throw new Error('unsupported or ambiguous Node installation');
173
+ }
174
+ function probe(backend, executableName, args) {
175
+ const quotedArgs = args;
176
+ if (backend.kind === 'nvm') {
177
+ return `NVM_DIR=${shellQuote(requiredPath(backend.root))} NODE_VERSION=default ${shellQuote(backend.command)} ${executableName} ${quotedArgs}`;
178
+ }
179
+ if (backend.kind === 'fnm') {
180
+ return `FNM_DIR=${shellQuote(requiredPath(backend.root))} ${shellQuote(backend.command)} exec --using=default -- ${executableName} ${quotedArgs}`;
181
+ }
182
+ if (backend.kind === 'asdf') {
183
+ return `(cd "$HOME" && ASDF_DATA_DIR=${shellQuote(requiredPath(backend.root))} ${shellQuote(backend.command)} exec ${executableName} ${quotedArgs})`;
184
+ }
185
+ if (executableName === 'node') {
186
+ return `${shellQuote(requiredPath(backend.node))} ${quotedArgs}`;
187
+ }
188
+ return `${shellQuote(backend.command)} ${quotedArgs}`;
189
+ }
190
+ function run(backend) {
191
+ if (backend.kind === 'nvm') {
192
+ return `NVM_DIR=${shellQuote(requiredPath(backend.root))} NODE_VERSION=default exec ${shellQuote(backend.command)} elepha "$@"`;
193
+ }
194
+ if (backend.kind === 'fnm') {
195
+ return `FNM_DIR=${shellQuote(requiredPath(backend.root))} exec ${shellQuote(backend.command)} exec --using=default -- elepha "$@"`;
196
+ }
197
+ if (backend.kind === 'asdf') {
198
+ return `cd "$HOME" && ASDF_DATA_DIR=${shellQuote(requiredPath(backend.root))} exec ${shellQuote(backend.command)} exec elepha "$@"`;
199
+ }
200
+ return `exec ${shellQuote(backend.command)} "$@"`;
201
+ }
202
+ function requiredPath(value) {
203
+ if (!value) {
204
+ throw new Error('launcher backend is missing its required stable path');
205
+ }
206
+ return value;
207
+ }
208
+ /** Render the stable, version-free POSIX launcher. */
209
+ export function renderLauncher(backend, minimumNodeMajor) {
210
+ const versionProbe = `${shellQuote('-e')} ${shellQuote(FIXED_PROBE)} ${minimumNodeMajor}`;
211
+ const packageProbe = `internal launcher-probe ${minimumNodeMajor}`;
212
+ const launch = run(backend);
213
+ const base = ['#!/bin/sh', LAUNCHER_MARKER, 'set -eu', 'umask 077', 'PATH=/usr/bin:/bin:/usr/sbin:/sbin', 'export PATH'];
214
+ if (backend.npmBin) {
215
+ base.push(`PATH=${shellQuote(backend.npmBin)}:$PATH`, 'export PATH');
216
+ }
217
+ base.push(`if [ "\${ELEPHA_MANAGED_LAUNCHER:-}" = "1" ]; then printf "%s\\n" "elepha launcher failed: recursion" >&2; exit 126; fi`, 'export ELEPHA_MANAGED_LAUNCHER=1', `if ! ${probe(backend, 'node', versionProbe)} >/dev/null 2>&1; then printf "%s\\n" "elepha launcher failed: default-missing" >&2; exit 69; fi`, `if ! ${probe(backend, 'elepha', packageProbe)} >/dev/null 2>&1; then printf "%s\\n" "elepha launcher failed: package-invalid" >&2; exit 66; fi`, launch, '');
218
+ return base.join('\n');
219
+ }
220
+ export function launcherHash(text) {
221
+ // Hashing is implemented without exposing a parser/executor surface.
222
+ return createHash('sha256').update(text).digest('hex');
223
+ }
224
+ //# sourceMappingURL=launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.js","sourceRoot":"","sources":["../../src/install/launcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /** Exact bytes owned by elepha's installed configuration and launcher formats. */
2
+ export const LAUNCHER_MARKER = '# elepha-managed-launcher: v1';
3
+ export const CODEX_SESSION_START_BEGIN = '# elepha-session-start: begin';
4
+ export const CODEX_SESSION_START_END = '# elepha-session-start: end';
5
+ export const CODEX_USER_PROMPT_SUBMIT_BEGIN = '# elepha-user-prompt-submit: begin';
6
+ export const CODEX_USER_PROMPT_SUBMIT_END = '# elepha-user-prompt-submit: end';
7
+ export const CODEX_MCP_START = '# elepha-mcp: begin';
8
+ export const CODEX_MCP_END = '# elepha-mcp: end';
9
+ export const CODEX_SESSION_START_TABLE = '[[hooks.SessionStart]]';
10
+ export const CODEX_SESSION_START_HOOK_TABLE = '[[hooks.SessionStart.hooks]]';
11
+ export const CODEX_USER_PROMPT_SUBMIT_TABLE = '[[hooks.UserPromptSubmit]]';
12
+ export const CODEX_USER_PROMPT_SUBMIT_HOOK_TABLE = '[[hooks.UserPromptSubmit.hooks]]';
13
+ export const CODEX_ADDITIONAL_CONTEXT_LIMIT = 'additionalContextLimit = 0';
14
+ //# sourceMappingURL=markers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markers.js","sourceRoot":"","sources":["../../src/install/markers.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,CAAC,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAE/D,MAAM,CAAC,MAAM,yBAAyB,GAAG,+BAA+B,CAAC;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAAG,6BAA6B,CAAC;AACrE,MAAM,CAAC,MAAM,8BAA8B,GAAG,oCAAoC,CAAC;AACnF,MAAM,CAAC,MAAM,4BAA4B,GAAG,kCAAkC,CAAC;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,qBAAqB,CAAC;AACrD,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAEjD,MAAM,CAAC,MAAM,yBAAyB,GAAG,wBAAwB,CAAC;AAClE,MAAM,CAAC,MAAM,8BAA8B,GAAG,8BAA8B,CAAC;AAC7E,MAAM,CAAC,MAAM,8BAA8B,GAAG,4BAA4B,CAAC;AAC3E,MAAM,CAAC,MAAM,mCAAmC,GAAG,kCAAkC,CAAC;AACtF,MAAM,CAAC,MAAM,8BAA8B,GAAG,4BAA4B,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { readFileSync } from 'node:fs';
2
+ export function isSupportedPlatform(platform = process.platform) {
3
+ return platform === 'darwin' || platform === 'linux';
4
+ }
5
+ export function isWsl(env = process.env, procVersion) {
6
+ if (env.WSL_DISTRO_NAME !== undefined || env.WSL_INTEROP !== undefined) {
7
+ return true;
8
+ }
9
+ let version = procVersion;
10
+ if (version === undefined) {
11
+ try {
12
+ version = readFileSync('/proc/version', 'utf8');
13
+ }
14
+ catch {
15
+ version = '';
16
+ }
17
+ }
18
+ return /microsoft/i.test(version);
19
+ }
20
+ export function linuxServiceManagerError(input) {
21
+ if (input.hasSystemd) {
22
+ return undefined;
23
+ }
24
+ if (input.isWsl) {
25
+ return 'elepha install requires systemd. Add [boot] and systemd=true to /etc/wsl.conf, run wsl --shutdown, reopen the distro, then re-run elepha install.';
26
+ }
27
+ return "elepha's capture service requires systemd (systemctl) as the init, but this system is not running it.";
28
+ }
29
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/install/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,UAAU,mBAAmB,CAAC,QAAQ,GAAoB,OAAO,CAAC,QAAQ;IAC5E,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,OAAO,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG,EAAE,WAAoB;IAC5E,IAAI,GAAG,CAAC,eAAe,KAAK,SAAS,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACrE,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,GAAG,WAAW,CAAC;IAC1B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,CAAC;YACD,OAAO,GAAG,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,GAAG,EAAE,CAAC;QACjB,CAAC;IACL,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAA8C;IACnF,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,mJAAmJ,CAAC;IAC/J,CAAC;IACD,OAAO,uGAAuG,CAAC;AACnH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { existsSync, statSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ function isDirectory(file) {
4
+ return statSync(file, { throwIfNoEntry: false })?.isDirectory() ?? false;
5
+ }
6
+ /**
7
+ * Presence is intentionally filesystem-only: registering a config for a tool
8
+ * that is not installed creates an orphan entry that status can never mark ready.
9
+ */
10
+ export function detectPresentTools(paths) {
11
+ return {
12
+ claude: isDirectory(path.dirname(paths.claudeSettings)) || existsSync(paths.claudeMcp),
13
+ codex: isDirectory(path.dirname(paths.codexConfig)),
14
+ };
15
+ }
16
+ //# sourceMappingURL=present-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present-tools.js","sourceRoot":"","sources":["../../src/install/present-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,IAAI,MAAM,WAAW,CAAC;AAa7B,SAAS,WAAW,CAAC,IAAY;IAC7B,OAAO,QAAQ,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,IAAI,KAAK,CAAC;AAC7E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACrD,OAAO;QACH,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;QACtF,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;KACtD,CAAC;AACN,CAAC"}