@provos/ironcurtain 0.6.0 → 0.7.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 (187) hide show
  1. package/README.md +21 -2
  2. package/dist/cli-help.d.ts +63 -0
  3. package/dist/cli-help.js +102 -0
  4. package/dist/cli-help.js.map +1 -0
  5. package/dist/cli.js +73 -56
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config/config-command.js +136 -2
  8. package/dist/config/config-command.js.map +1 -1
  9. package/dist/config/generated/tool-annotations.json +487 -338
  10. package/dist/config/index.d.ts +21 -1
  11. package/dist/config/index.js +12 -4
  12. package/dist/config/index.js.map +1 -1
  13. package/dist/config/mcp-servers.json +2 -8
  14. package/dist/config/paths.d.ts +30 -0
  15. package/dist/config/paths.js +58 -0
  16. package/dist/config/paths.js.map +1 -1
  17. package/dist/config/tool-description-hints.json +15 -0
  18. package/dist/config/types.d.ts +7 -0
  19. package/dist/config/user-config.d.ts +21 -0
  20. package/dist/config/user-config.js +8 -0
  21. package/dist/config/user-config.js.map +1 -1
  22. package/dist/cron/compile-task-policy.d.ts +17 -0
  23. package/dist/cron/compile-task-policy.js +39 -0
  24. package/dist/cron/compile-task-policy.js.map +1 -0
  25. package/dist/cron/cron-scheduler.d.ts +65 -0
  26. package/dist/cron/cron-scheduler.js +184 -0
  27. package/dist/cron/cron-scheduler.js.map +1 -0
  28. package/dist/cron/file-lock.d.ts +41 -0
  29. package/dist/cron/file-lock.js +156 -0
  30. package/dist/cron/file-lock.js.map +1 -0
  31. package/dist/cron/format-utils.d.ts +18 -0
  32. package/dist/cron/format-utils.js +145 -0
  33. package/dist/cron/format-utils.js.map +1 -0
  34. package/dist/cron/git-sync.d.ts +22 -0
  35. package/dist/cron/git-sync.js +121 -0
  36. package/dist/cron/git-sync.js.map +1 -0
  37. package/dist/cron/headless-transport.d.ts +27 -0
  38. package/dist/cron/headless-transport.js +43 -0
  39. package/dist/cron/headless-transport.js.map +1 -0
  40. package/dist/cron/job-commands.d.ts +39 -0
  41. package/dist/cron/job-commands.js +522 -0
  42. package/dist/cron/job-commands.js.map +1 -0
  43. package/dist/cron/job-store.d.ts +35 -0
  44. package/dist/cron/job-store.js +111 -0
  45. package/dist/cron/job-store.js.map +1 -0
  46. package/dist/cron/types.d.ts +127 -0
  47. package/dist/cron/types.js +25 -0
  48. package/dist/cron/types.js.map +1 -0
  49. package/dist/daemon/control-socket.d.ts +127 -0
  50. package/dist/daemon/control-socket.js +261 -0
  51. package/dist/daemon/control-socket.js.map +1 -0
  52. package/dist/daemon/daemon-command.d.ts +13 -0
  53. package/dist/daemon/daemon-command.js +230 -0
  54. package/dist/daemon/daemon-command.js.map +1 -0
  55. package/dist/daemon/ironcurtain-daemon.d.ts +90 -0
  56. package/dist/daemon/ironcurtain-daemon.js +548 -0
  57. package/dist/daemon/ironcurtain-daemon.js.map +1 -0
  58. package/dist/docker/adapters/claude-code.js +7 -47
  59. package/dist/docker/adapters/claude-code.js.map +1 -1
  60. package/dist/docker/adapters/goose.d.ts +58 -0
  61. package/dist/docker/adapters/goose.js +250 -0
  62. package/dist/docker/adapters/goose.js.map +1 -0
  63. package/dist/docker/adapters/shared-scripts.d.ts +29 -0
  64. package/dist/docker/adapters/shared-scripts.js +80 -0
  65. package/dist/docker/adapters/shared-scripts.js.map +1 -0
  66. package/dist/docker/agent-adapter.d.ts +12 -0
  67. package/dist/docker/agent-adapter.js.map +1 -1
  68. package/dist/docker/agent-registry.d.ts +6 -1
  69. package/dist/docker/agent-registry.js +10 -1
  70. package/dist/docker/agent-registry.js.map +1 -1
  71. package/dist/docker/docker-agent-session.d.ts +2 -25
  72. package/dist/docker/docker-agent-session.js +7 -106
  73. package/dist/docker/docker-agent-session.js.map +1 -1
  74. package/dist/docker/docker-infrastructure.d.ts +8 -0
  75. package/dist/docker/docker-infrastructure.js +12 -11
  76. package/dist/docker/docker-infrastructure.js.map +1 -1
  77. package/dist/docker/pty-session.js +7 -4
  78. package/dist/docker/pty-session.js.map +1 -1
  79. package/dist/escalation/escalation-watcher.d.ts +2 -0
  80. package/dist/escalation/escalation-watcher.js +3 -0
  81. package/dist/escalation/escalation-watcher.js.map +1 -1
  82. package/dist/escalation/session-registry.js +1 -14
  83. package/dist/escalation/session-registry.js.map +1 -1
  84. package/dist/index.js +30 -1
  85. package/dist/index.js.map +1 -1
  86. package/dist/mux/mux-app.js +11 -6
  87. package/dist/mux/mux-app.js.map +1 -1
  88. package/dist/mux/mux-command.js +20 -9
  89. package/dist/mux/mux-command.js.map +1 -1
  90. package/dist/mux/mux-input-handler.d.ts +5 -0
  91. package/dist/mux/mux-input-handler.js +64 -9
  92. package/dist/mux/mux-input-handler.js.map +1 -1
  93. package/dist/mux/mux-renderer.d.ts +20 -0
  94. package/dist/mux/mux-renderer.js +127 -35
  95. package/dist/mux/mux-renderer.js.map +1 -1
  96. package/dist/mux/mux-splash.js +2 -1
  97. package/dist/mux/mux-splash.js.map +1 -1
  98. package/dist/mux/paste-interceptor.d.ts +22 -0
  99. package/dist/mux/paste-interceptor.js +143 -0
  100. package/dist/mux/paste-interceptor.js.map +1 -0
  101. package/dist/mux/pty-bridge.js +1 -1
  102. package/dist/mux/pty-bridge.js.map +1 -1
  103. package/dist/mux/types.d.ts +8 -1
  104. package/dist/mux/types.js +17 -5
  105. package/dist/mux/types.js.map +1 -1
  106. package/dist/pipeline/annotate.js +2 -1
  107. package/dist/pipeline/annotate.js.map +1 -1
  108. package/dist/pipeline/compile.d.ts +4 -34
  109. package/dist/pipeline/compile.js +29 -568
  110. package/dist/pipeline/compile.js.map +1 -1
  111. package/dist/pipeline/constitution-compiler.js +1 -1
  112. package/dist/pipeline/mcp-connections.d.ts +16 -0
  113. package/dist/pipeline/mcp-connections.js +61 -0
  114. package/dist/pipeline/mcp-connections.js.map +1 -0
  115. package/dist/pipeline/pipeline-runner.d.ts +86 -0
  116. package/dist/pipeline/pipeline-runner.js +554 -0
  117. package/dist/pipeline/pipeline-runner.js.map +1 -0
  118. package/dist/pipeline/pipeline-shared.d.ts +29 -2
  119. package/dist/pipeline/pipeline-shared.js +68 -12
  120. package/dist/pipeline/pipeline-shared.js.map +1 -1
  121. package/dist/pipeline/refresh-lists.js +38 -12
  122. package/dist/pipeline/refresh-lists.js.map +1 -1
  123. package/dist/pipeline/scenario-generator.js +2 -1
  124. package/dist/pipeline/scenario-generator.js.map +1 -1
  125. package/dist/pipeline/tool-annotator.d.ts +3 -3
  126. package/dist/pipeline/tool-annotator.js +96 -4
  127. package/dist/pipeline/tool-annotator.js.map +1 -1
  128. package/dist/pipeline/types.d.ts +52 -0
  129. package/dist/sandbox/index.js +36 -1
  130. package/dist/sandbox/index.js.map +1 -1
  131. package/dist/session/agent-session.d.ts +3 -0
  132. package/dist/session/agent-session.js +10 -1
  133. package/dist/session/agent-session.js.map +1 -1
  134. package/dist/session/index.js +54 -5
  135. package/dist/session/index.js.map +1 -1
  136. package/dist/session/preflight.js +26 -6
  137. package/dist/session/preflight.js.map +1 -1
  138. package/dist/session/prompts.d.ts +14 -0
  139. package/dist/session/prompts.js +39 -2
  140. package/dist/session/prompts.js.map +1 -1
  141. package/dist/session/session-manager.d.ts +105 -0
  142. package/dist/session/session-manager.js +134 -0
  143. package/dist/session/session-manager.js.map +1 -0
  144. package/dist/session/types.d.ts +27 -0
  145. package/dist/session/workspace-validation.d.ts +2 -0
  146. package/dist/session/workspace-validation.js +6 -5
  147. package/dist/session/workspace-validation.js.map +1 -1
  148. package/dist/signal/bot-command.d.ts +2 -0
  149. package/dist/signal/bot-command.js +8 -0
  150. package/dist/signal/bot-command.js.map +1 -1
  151. package/dist/signal/format.d.ts +27 -0
  152. package/dist/signal/format.js +59 -0
  153. package/dist/signal/format.js.map +1 -1
  154. package/dist/signal/signal-bot-daemon.d.ts +27 -25
  155. package/dist/signal/signal-bot-daemon.js +145 -130
  156. package/dist/signal/signal-bot-daemon.js.map +1 -1
  157. package/dist/signal/signal-container.js +63 -19
  158. package/dist/signal/signal-container.js.map +1 -1
  159. package/dist/signal/signal-transport.js +3 -8
  160. package/dist/signal/signal-transport.js.map +1 -1
  161. package/dist/trusted-process/domain-utils.d.ts +38 -4
  162. package/dist/trusted-process/domain-utils.js +118 -11
  163. package/dist/trusted-process/domain-utils.js.map +1 -1
  164. package/dist/trusted-process/index.js +6 -2
  165. package/dist/trusted-process/index.js.map +1 -1
  166. package/dist/trusted-process/mcp-client-manager.js +11 -5
  167. package/dist/trusted-process/mcp-client-manager.js.map +1 -1
  168. package/dist/trusted-process/mcp-proxy-server.d.ts +2 -0
  169. package/dist/trusted-process/mcp-proxy-server.js +59 -16
  170. package/dist/trusted-process/mcp-proxy-server.js.map +1 -1
  171. package/dist/trusted-process/permissive-output-validator.d.ts +23 -0
  172. package/dist/trusted-process/permissive-output-validator.js +10 -0
  173. package/dist/trusted-process/permissive-output-validator.js.map +1 -0
  174. package/dist/trusted-process/policy-engine.d.ts +27 -4
  175. package/dist/trusted-process/policy-engine.js +152 -57
  176. package/dist/trusted-process/policy-engine.js.map +1 -1
  177. package/dist/trusted-process/tool-description-hints.d.ts +19 -0
  178. package/dist/trusted-process/tool-description-hints.js +53 -0
  179. package/dist/trusted-process/tool-description-hints.js.map +1 -0
  180. package/dist/types/argument-roles.d.ts +33 -1
  181. package/dist/types/argument-roles.js +129 -1
  182. package/dist/types/argument-roles.js.map +1 -1
  183. package/docker/Dockerfile.goose +34 -0
  184. package/docker/entrypoint-goose.sh +30 -0
  185. package/package.json +1 -1
  186. package/src/config/generated/tool-annotations.json +487 -338
  187. package/src/config/mcp-servers.json +2 -8
@@ -0,0 +1,13 @@
1
+ /**
2
+ * CLI entry point for `ironcurtain daemon` and its subcommands.
3
+ *
4
+ * When no sub-subcommand is given, starts the unified daemon.
5
+ * Subcommands: add-job, list-jobs, run-job, remove-job,
6
+ * disable-job, enable-job, recompile-job, logs
7
+ *
8
+ * Commands that modify daemon state (remove-job, enable-job, disable-job,
9
+ * recompile-job, run-job) first check if a daemon is running via the
10
+ * control socket. If running, the command is forwarded to the daemon.
11
+ * Otherwise, the command operates directly on the filesystem.
12
+ */
13
+ export declare function runDaemonCommand(argv: string[]): Promise<void>;
@@ -0,0 +1,230 @@
1
+ /**
2
+ * CLI entry point for `ironcurtain daemon` and its subcommands.
3
+ *
4
+ * When no sub-subcommand is given, starts the unified daemon.
5
+ * Subcommands: add-job, list-jobs, run-job, remove-job,
6
+ * disable-job, enable-job, recompile-job, logs
7
+ *
8
+ * Commands that modify daemon state (remove-job, enable-job, disable-job,
9
+ * recompile-job, run-job) first check if a daemon is running via the
10
+ * control socket. If running, the command is forwarded to the daemon.
11
+ * Otherwise, the command operates directly on the filesystem.
12
+ */
13
+ import { parseArgs } from 'node:util';
14
+ import { IronCurtainDaemon } from './ironcurtain-daemon.js';
15
+ import { sendControlRequest } from './control-socket.js';
16
+ import { formatDuration } from '../cron/format-utils.js';
17
+ import { checkHelp } from '../cli-help.js';
18
+ const daemonSpec = {
19
+ name: 'ironcurtain daemon',
20
+ description: 'Unified Signal + cron daemon',
21
+ usage: [
22
+ 'ironcurtain daemon [options] Start the daemon',
23
+ 'ironcurtain daemon <subcommand> [options] Manage jobs',
24
+ ],
25
+ subcommands: [
26
+ { name: 'add-job', description: 'Add a new scheduled job (interactive)' },
27
+ { name: 'edit-job <id>', description: 'Edit an existing job (interactive)' },
28
+ { name: 'list-jobs', description: 'List all jobs with schedule info' },
29
+ { name: 'run-job <id>', description: 'Manually trigger a job run' },
30
+ { name: 'status', description: 'Show daemon status' },
31
+ { name: 'remove-job <id>', description: 'Delete a job and all artifacts' },
32
+ { name: 'disable-job <id>', description: 'Stop scheduling a job' },
33
+ { name: 'enable-job <id>', description: 'Resume scheduling a job' },
34
+ { name: 'recompile-job <id>', description: 'Re-run policy compilation' },
35
+ { name: 'logs <id>', description: 'Show recent run summaries' },
36
+ ],
37
+ options: [
38
+ { flag: 'agent', short: 'a', description: 'Agent mode (same as start)', placeholder: '<name>' },
39
+ { flag: 'force', short: 'f', description: 'Skip confirmation prompts' },
40
+ { flag: 'no-signal', description: 'Skip Signal transport (cron-only mode)' },
41
+ { flag: 'runs', description: 'Number of recent runs to show (for logs)', placeholder: '<N>' },
42
+ ],
43
+ };
44
+ /** Extracts a required job-id positional, exiting with usage if missing. */
45
+ function requireJobIdArg(positionals) {
46
+ const jobId = positionals[1];
47
+ if (!jobId) {
48
+ console.error('Usage: ironcurtain daemon <subcommand> <job-id>');
49
+ process.exit(1);
50
+ }
51
+ return jobId;
52
+ }
53
+ /**
54
+ * Attempts to forward a command to a running daemon.
55
+ * Returns the response if the daemon handled it, or null if no daemon
56
+ * is running (caller should fall back to local filesystem operations).
57
+ */
58
+ async function tryForwardToDaemon(request) {
59
+ return sendControlRequest(request);
60
+ }
61
+ /**
62
+ * Handles a forwarded response: prints success/error and exits.
63
+ * Returns true if the response was handled (caller should return).
64
+ */
65
+ function handleForwardedResponse(response, successMessage) {
66
+ if (response === null)
67
+ return false;
68
+ if (!response.ok) {
69
+ console.error(`Error from daemon: ${response.error}`);
70
+ process.exit(1);
71
+ }
72
+ if (successMessage) {
73
+ console.error(successMessage);
74
+ }
75
+ return true;
76
+ }
77
+ export async function runDaemonCommand(argv) {
78
+ const { values, positionals } = parseArgs({
79
+ args: argv,
80
+ options: {
81
+ agent: { type: 'string', short: 'a' },
82
+ 'no-signal': { type: 'boolean' },
83
+ force: { type: 'boolean', short: 'f' },
84
+ runs: { type: 'string' },
85
+ help: { type: 'boolean', short: 'h' },
86
+ },
87
+ allowPositionals: true,
88
+ strict: false,
89
+ });
90
+ if (checkHelp(values, daemonSpec)) {
91
+ return;
92
+ }
93
+ const subcommand = positionals[0];
94
+ // Resolve session mode (same as `start` command)
95
+ const { resolveSessionMode } = await import('../session/preflight.js');
96
+ const { loadConfig } = await import('../config/index.js');
97
+ const preflight = await resolveSessionMode({
98
+ config: loadConfig(),
99
+ requestedAgent: values.agent ? values.agent : undefined,
100
+ });
101
+ const mode = preflight.mode;
102
+ console.error(`Mode: ${mode.kind} (${preflight.reason})`);
103
+ if (!subcommand) {
104
+ // Start the daemon
105
+ const daemon = new IronCurtainDaemon({
106
+ mode,
107
+ noSignal: values['no-signal'],
108
+ });
109
+ // Handle shutdown signals
110
+ const shutdownHandler = async () => {
111
+ await daemon.shutdown();
112
+ process.exit(0);
113
+ };
114
+ process.on('SIGINT', () => void shutdownHandler());
115
+ process.on('SIGTERM', () => void shutdownHandler());
116
+ await daemon.start();
117
+ return;
118
+ }
119
+ // Sub-subcommands that work without a running daemon
120
+ switch (subcommand) {
121
+ case 'add-job': {
122
+ const { runAddJobWizard } = await import('../cron/job-commands.js');
123
+ await runAddJobWizard();
124
+ break;
125
+ }
126
+ case 'edit-job': {
127
+ const jobId = requireJobIdArg(positionals);
128
+ const { runEditJobWizard } = await import('../cron/job-commands.js');
129
+ await runEditJobWizard(jobId);
130
+ break;
131
+ }
132
+ case 'status': {
133
+ const { sendControlRequest: sendReq } = await import('./control-socket.js');
134
+ const resp = await sendReq({ command: 'status' });
135
+ if (!resp || !resp.ok) {
136
+ console.error('Daemon is not running.');
137
+ break;
138
+ }
139
+ const status = resp.data;
140
+ const uptimeStr = formatDuration(status.uptimeSeconds);
141
+ console.error('Daemon is running.');
142
+ console.error(` Uptime: ${uptimeStr}`);
143
+ console.error(` Jobs: ${status.jobs.total} total, ${status.jobs.enabled} enabled, ${status.jobs.running} running`);
144
+ console.error(` Signal transport: ${status.signalConnected ? 'connected' : 'not configured'}`);
145
+ if (status.nextFireTime) {
146
+ const { formatRelativeTime } = await import('../cron/format-utils.js');
147
+ console.error(` Next scheduled run: ${formatRelativeTime(new Date(status.nextFireTime))}`);
148
+ }
149
+ else {
150
+ console.error(' Next scheduled run: none');
151
+ }
152
+ break;
153
+ }
154
+ case 'list-jobs': {
155
+ const resp = await tryForwardToDaemon({ command: 'list-jobs' });
156
+ if (handleForwardedResponse(resp)) {
157
+ const { formatDaemonJobList } = await import('../cron/job-commands.js');
158
+ formatDaemonJobList(resp.data);
159
+ break;
160
+ }
161
+ const { runListJobs } = await import('../cron/job-commands.js');
162
+ runListJobs();
163
+ break;
164
+ }
165
+ case 'run-job': {
166
+ const jobId = requireJobIdArg(positionals);
167
+ const resp = await tryForwardToDaemon({ command: 'run-job', jobId });
168
+ if (handleForwardedResponse(resp)) {
169
+ const record = resp.data;
170
+ console.error(`Job "${jobId}" completed via daemon.`);
171
+ console.error(` Outcome: ${record.outcome.kind}`);
172
+ console.error(` Duration: ${record.budget.elapsedSeconds.toFixed(0)}s`);
173
+ console.error(` Cost: $${record.budget.estimatedCostUsd.toFixed(2)}`);
174
+ break;
175
+ }
176
+ const { runJobCommand } = await import('../cron/job-commands.js');
177
+ await runJobCommand(jobId);
178
+ break;
179
+ }
180
+ case 'remove-job': {
181
+ const jobId = requireJobIdArg(positionals);
182
+ // When forwarding to daemon via control socket, skip interactive prompt
183
+ const resp = await tryForwardToDaemon({ command: 'remove-job', jobId });
184
+ if (handleForwardedResponse(resp, `Job "${jobId}" removed (daemon notified).`))
185
+ break;
186
+ const { runRemoveJob } = await import('../cron/job-commands.js');
187
+ await runRemoveJob(jobId, values.force);
188
+ break;
189
+ }
190
+ case 'disable-job': {
191
+ const jobId = requireJobIdArg(positionals);
192
+ const resp = await tryForwardToDaemon({ command: 'disable-job', jobId });
193
+ if (handleForwardedResponse(resp, `Job "${jobId}" disabled (daemon notified).`))
194
+ break;
195
+ const { runDisableJob } = await import('../cron/job-commands.js');
196
+ await runDisableJob(jobId);
197
+ break;
198
+ }
199
+ case 'enable-job': {
200
+ const jobId = requireJobIdArg(positionals);
201
+ const resp = await tryForwardToDaemon({ command: 'enable-job', jobId });
202
+ if (handleForwardedResponse(resp, `Job "${jobId}" enabled (daemon notified).`))
203
+ break;
204
+ const { runEnableJob } = await import('../cron/job-commands.js');
205
+ await runEnableJob(jobId);
206
+ break;
207
+ }
208
+ case 'recompile-job': {
209
+ const jobId = requireJobIdArg(positionals);
210
+ const resp = await tryForwardToDaemon({ command: 'recompile-job', jobId });
211
+ if (handleForwardedResponse(resp, `Job "${jobId}" policy recompiled (daemon notified).`))
212
+ break;
213
+ const { runRecompileJob } = await import('../cron/job-commands.js');
214
+ await runRecompileJob(jobId);
215
+ break;
216
+ }
217
+ case 'logs': {
218
+ const jobId = requireJobIdArg(positionals);
219
+ const limit = values.runs ? parseInt(values.runs, 10) : 5;
220
+ const { runShowLogs } = await import('../cron/job-commands.js');
221
+ runShowLogs(jobId, limit);
222
+ break;
223
+ }
224
+ default:
225
+ console.error(`Unknown daemon subcommand: ${subcommand}\n`);
226
+ checkHelp({ help: true }, daemonSpec);
227
+ process.exit(1);
228
+ }
229
+ }
230
+ //# sourceMappingURL=daemon-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-command.js","sourceRoot":"","sources":["../../src/daemon/daemon-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAA6C,MAAM,qBAAqB,CAAC;AAEpG,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAoB,MAAM,gBAAgB,CAAC;AAE7D,MAAM,UAAU,GAAgB;IAC9B,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EAAE,8BAA8B;IAC3C,KAAK,EAAE;QACL,4DAA4D;QAC5D,wDAAwD;KACzD;IACD,WAAW,EAAE;QACX,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,uCAAuC,EAAE;QACzE,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,oCAAoC,EAAE;QAC5E,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,kCAAkC,EAAE;QACtE,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,4BAA4B,EAAE;QACnE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;QACrD,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,gCAAgC,EAAE;QAC1E,EAAE,IAAI,EAAE,kBAAkB,EAAE,WAAW,EAAE,uBAAuB,EAAE;QAClE,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,yBAAyB,EAAE;QACnE,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,2BAA2B,EAAE;QACxE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,2BAA2B,EAAE;KAChE;IACD,OAAO,EAAE;QACP,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,4BAA4B,EAAE,WAAW,EAAE,QAAQ,EAAE;QAC/F,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,2BAA2B,EAAE;QACvE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,wCAAwC,EAAE;QAC5E,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,0CAA0C,EAAE,WAAW,EAAE,KAAK,EAAE;KAC9F;CACF,CAAC;AAEF,4EAA4E;AAC5E,SAAS,eAAe,CAAC,WAAqB;IAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAAC,OAAuB;IACvD,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,SAAS,uBAAuB,CAAC,QAAgC,EAAE,cAAuB;IACxF,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAEpC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,sBAAsB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAc;IACnD,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,EAAE,IAAI;QACV,OAAO,EAAE;YACP,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YACrC,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;YAChC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;YACtC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;SACtC;QACD,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE,KAAK;KACd,CAAC,CAAC;IAEH,IAAI,SAAS,CAAC,MAA4B,EAAE,UAAU,CAAC,EAAE,CAAC;QACxD,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAElC,iDAAiD;IACjD,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;IACvE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC;QACzC,MAAM,EAAE,UAAU,EAAE;QACpB,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,MAAM,CAAC,KAAiB,CAAC,CAAC,CAAC,SAAS;KACrE,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAE1D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,mBAAmB;QACnB,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC;YACnC,IAAI;YACJ,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAwB;SACrD,CAAC,CAAC;QAEH,0BAA0B;QAC1B,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;YACjC,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC;QACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,eAAe,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,eAAe,EAAE,CAAC,CAAC;QAEpD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IAED,qDAAqD;IACrD,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YACpE,MAAM,eAAe,EAAE,CAAC;YACxB,MAAM;QACR,CAAC;QACD,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YACrE,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC9B,MAAM;QACR,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;YAC5E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACtB,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBACxC,MAAM;YACR,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAqD,CAAC;YAC1E,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACvD,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACpC,OAAO,CAAC,KAAK,CAAC,yBAAyB,SAAS,EAAE,CAAC,CAAC;YACpD,OAAO,CAAC,KAAK,CACX,yBAAyB,MAAM,CAAC,IAAI,CAAC,KAAK,WAAW,MAAM,CAAC,IAAI,CAAC,OAAO,aAAa,MAAM,CAAC,IAAI,CAAC,OAAO,UAAU,CACnH,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,yBAAyB,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAClG,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;gBACvE,OAAO,CAAC,KAAK,CAAC,yBAAyB,kBAAkB,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9F,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC9C,CAAC;YACD,MAAM;QACR,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YAChE,IAAI,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;gBACxE,mBAAmB,CAChB,IAAuC,CAAC,IAA8D,CACxG,CAAC;gBACF,MAAM;YACR,CAAC;YACD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YAChE,WAAW,EAAE,CAAC;YACd,MAAM;QACR,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACrE,IAAI,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,MAAM,MAAM,GAAI,IAAuC,CAAC,IAA4C,CAAC;gBACrG,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,yBAAyB,CAAC,CAAC;gBACtD,OAAO,CAAC,KAAK,CAAC,cAAc,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBACnD,OAAO,CAAC,KAAK,CAAC,eAAe,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACzE,OAAO,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvE,MAAM;YACR,CAAC;YACD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YAClE,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM;QACR,CAAC;QACD,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC3C,wEAAwE;YACxE,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;YACxE,IAAI,uBAAuB,CAAC,IAAI,EAAE,QAAQ,KAAK,8BAA8B,CAAC;gBAAE,MAAM;YACtF,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YACjE,MAAM,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,KAA4B,CAAC,CAAC;YAC/D,MAAM;QACR,CAAC;QACD,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;YACzE,IAAI,uBAAuB,CAAC,IAAI,EAAE,QAAQ,KAAK,+BAA+B,CAAC;gBAAE,MAAM;YACvF,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YAClE,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM;QACR,CAAC;QACD,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;YACxE,IAAI,uBAAuB,CAAC,IAAI,EAAE,QAAQ,KAAK,8BAA8B,CAAC;gBAAE,MAAM;YACtF,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YACjE,MAAM,YAAY,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM;QACR,CAAC;QACD,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3E,IAAI,uBAAuB,CAAC,IAAI,EAAE,QAAQ,KAAK,wCAAwC,CAAC;gBAAE,MAAM;YAChG,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YACpE,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC;YAC7B,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAc,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;YAChE,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC1B,MAAM;QACR,CAAC;QACD;YACE,OAAO,CAAC,KAAK,CAAC,8BAA8B,UAAU,IAAI,CAAC,CAAC;YAC5D,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * IronCurtainDaemon -- Unified daemon managing both Signal-initiated
3
+ * interactive sessions and cron-scheduled headless sessions.
4
+ *
5
+ * Lifecycle:
6
+ * 1. start() -- loads jobs, starts Signal (if configured), schedules jobs
7
+ * 2. Runs indefinitely, processing Signal messages and cron triggers
8
+ * 3. shutdown() -- unschedules all jobs, ends all sessions, disconnects
9
+ *
10
+ * Both Signal and cron sessions are managed through a shared SessionManager
11
+ * instance. This enables unified escalation routing: `approve #N` from
12
+ * Signal works for both Signal-initiated and cron-initiated sessions.
13
+ */
14
+ import type { SessionMode } from '../session/types.js';
15
+ import type { JobDefinition, JobId, RunRecord } from '../cron/types.js';
16
+ import { type DaemonStatus } from './control-socket.js';
17
+ export type { SessionSource, ManagedSession } from '../session/session-manager.js';
18
+ export interface IronCurtainDaemonOptions {
19
+ /** Session mode for both Signal and cron sessions. */
20
+ readonly mode: SessionMode;
21
+ /** When true, skip starting Signal transport. */
22
+ readonly noSignal?: boolean;
23
+ }
24
+ export declare class IronCurtainDaemon {
25
+ private readonly mode;
26
+ private readonly noSignal;
27
+ private readonly sessionManager;
28
+ private readonly scheduler;
29
+ /** Time the daemon was started (for uptime calculation). */
30
+ private startTime;
31
+ /** Tracks which jobs are currently running (jobId -> session label). */
32
+ private readonly activeJobRuns;
33
+ /** Control socket server for CLI communication. */
34
+ private controlSocket;
35
+ /** Signal daemon instance (null if Signal not configured). */
36
+ private signalDaemon;
37
+ /** Resolve to exit the daemon. */
38
+ private exitResolve;
39
+ constructor(options: IronCurtainDaemonOptions);
40
+ /**
41
+ * Starts the daemon. Loads all enabled jobs, schedules them,
42
+ * optionally starts the Signal transport.
43
+ */
44
+ start(): Promise<void>;
45
+ /** Graceful shutdown. */
46
+ shutdown(): Promise<void>;
47
+ /**
48
+ * Adds a new job. Runs the full policy compilation pipeline
49
+ * before confirming. Schedules the job if enabled.
50
+ */
51
+ addJob(job: JobDefinition): Promise<void>;
52
+ /** Removes a job. Stops any active run, unschedules, deletes files. */
53
+ removeJob(jobId: JobId): Promise<void>;
54
+ /** Enables a previously disabled job. Schedules it. */
55
+ enableJob(jobId: JobId): Promise<void>;
56
+ /** Disables a job. Unschedules it but preserves files. */
57
+ disableJob(jobId: JobId): Promise<void>;
58
+ /** Reloads a job definition from disk and reschedules it. */
59
+ reloadJob(jobId: JobId): Promise<void>;
60
+ /** Re-runs policy compilation for an existing job. */
61
+ recompileJob(jobId: JobId): Promise<void>;
62
+ /**
63
+ * Manually triggers a job run (for testing).
64
+ * Does not affect the cron schedule.
65
+ */
66
+ runJobNow(jobId: JobId): Promise<RunRecord>;
67
+ /** Lists all jobs with their schedules and last run status. */
68
+ listJobs(): Array<{
69
+ job: JobDefinition;
70
+ nextRun: Date | undefined;
71
+ lastRun: RunRecord | undefined;
72
+ isRunning: boolean;
73
+ }>;
74
+ /** Returns a status snapshot for the control socket. */
75
+ getStatus(): DaemonStatus;
76
+ /**
77
+ * Called when a scheduled job fires.
78
+ * Checks for overlap, creates a session, and runs the job.
79
+ */
80
+ private onJobTrigger;
81
+ /**
82
+ * Executes a job: creates a session with the job's workspace and
83
+ * per-job policy, runs it to completion, and records the outcome.
84
+ */
85
+ private executeJob;
86
+ private handleCronEscalation;
87
+ private startSignalDaemon;
88
+ private startControlSocket;
89
+ private readLastRunSummary;
90
+ }