@coralai/sps-cli 0.49.16 → 0.50.1

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 (177) hide show
  1. package/dist/commands/cardAdd.d.ts.map +1 -1
  2. package/dist/commands/cardAdd.js +47 -67
  3. package/dist/commands/cardAdd.js.map +1 -1
  4. package/dist/commands/cardMarkComplete.js +1 -1
  5. package/dist/commands/cardMarkComplete.js.map +1 -1
  6. package/dist/commands/cardMarkStarted.js +1 -1
  7. package/dist/commands/cardMarkStarted.js.map +1 -1
  8. package/dist/commands/consoleCommand.js +3 -3
  9. package/dist/commands/consoleCommand.js.map +1 -1
  10. package/dist/commands/hookCommand.d.ts +25 -0
  11. package/dist/commands/hookCommand.d.ts.map +1 -1
  12. package/dist/commands/hookCommand.js +2 -2
  13. package/dist/commands/hookCommand.js.map +1 -1
  14. package/dist/console/index.d.ts +15 -0
  15. package/dist/console/index.d.ts.map +1 -0
  16. package/dist/console/index.js +180 -0
  17. package/dist/console/index.js.map +1 -0
  18. package/dist/console/lib/lockFile.d.ts +17 -0
  19. package/dist/console/lib/lockFile.d.ts.map +1 -0
  20. package/dist/console/lib/lockFile.js +61 -0
  21. package/dist/console/lib/lockFile.js.map +1 -0
  22. package/dist/console/lib/portPicker.d.ts +3 -0
  23. package/dist/console/lib/portPicker.d.ts.map +1 -0
  24. package/dist/console/lib/portPicker.js +25 -0
  25. package/dist/console/lib/portPicker.js.map +1 -0
  26. package/dist/console/lib/resultToJson.d.ts +18 -0
  27. package/dist/console/lib/resultToJson.d.ts.map +1 -0
  28. package/dist/console/lib/resultToJson.js +19 -0
  29. package/dist/console/lib/resultToJson.js.map +1 -0
  30. package/dist/console/routes/cards.d.ts +26 -0
  31. package/dist/console/routes/cards.d.ts.map +1 -0
  32. package/dist/console/routes/cards.js +85 -0
  33. package/dist/console/routes/cards.js.map +1 -0
  34. package/dist/console/routes/chat.d.ts +37 -0
  35. package/dist/console/routes/chat.d.ts.map +1 -0
  36. package/dist/console/routes/chat.js +378 -0
  37. package/dist/console/routes/chat.js.map +1 -0
  38. package/dist/console/routes/logs.d.ts +17 -0
  39. package/dist/console/routes/logs.d.ts.map +1 -0
  40. package/dist/console/routes/logs.js +159 -0
  41. package/dist/console/routes/logs.js.map +1 -0
  42. package/dist/console/routes/pipeline.d.ts +10 -0
  43. package/dist/console/routes/pipeline.d.ts.map +1 -0
  44. package/dist/console/routes/pipeline.js +39 -0
  45. package/dist/console/routes/pipeline.js.map +1 -0
  46. package/dist/console/routes/projects.d.ts +15 -0
  47. package/dist/console/routes/projects.d.ts.map +1 -0
  48. package/dist/console/routes/projects.js +132 -0
  49. package/dist/console/routes/projects.js.map +1 -0
  50. package/dist/console/routes/skills.d.ts +4 -0
  51. package/dist/console/routes/skills.d.ts.map +1 -0
  52. package/dist/console/routes/skills.js +91 -0
  53. package/dist/console/routes/skills.js.map +1 -0
  54. package/dist/console/routes/system.d.ts +10 -0
  55. package/dist/console/routes/system.d.ts.map +1 -0
  56. package/dist/console/routes/system.js +84 -0
  57. package/dist/console/routes/system.js.map +1 -0
  58. package/dist/console/routes/workers.d.ts +5 -0
  59. package/dist/console/routes/workers.d.ts.map +1 -0
  60. package/dist/console/routes/workers.js +149 -0
  61. package/dist/console/routes/workers.js.map +1 -0
  62. package/dist/console/sse/eventBus.d.ts +25 -0
  63. package/dist/console/sse/eventBus.d.ts.map +1 -0
  64. package/dist/console/sse/eventBus.js +32 -0
  65. package/dist/console/sse/eventBus.js.map +1 -0
  66. package/dist/console/sse/projectStream.d.ts +13 -0
  67. package/dist/console/sse/projectStream.d.ts.map +1 -0
  68. package/dist/console/sse/projectStream.js +84 -0
  69. package/dist/console/sse/projectStream.js.map +1 -0
  70. package/dist/core/checklist.d.ts +1 -1
  71. package/dist/core/state.d.ts +1 -1
  72. package/dist/engines/MonitorEngine.d.ts +1 -1
  73. package/dist/engines/SchedulerEngine.d.ts +1 -1
  74. package/dist/engines/StageEngine.d.ts +1 -1
  75. package/dist/infra/chokidarWatchers.d.ts +38 -0
  76. package/dist/infra/chokidarWatchers.d.ts.map +1 -0
  77. package/dist/infra/chokidarWatchers.js +213 -0
  78. package/dist/infra/chokidarWatchers.js.map +1 -0
  79. package/dist/infra/clock.d.ts +35 -0
  80. package/dist/infra/clock.d.ts.map +1 -0
  81. package/dist/infra/clock.js +45 -0
  82. package/dist/infra/clock.js.map +1 -0
  83. package/dist/infra/filesystem.d.ts +89 -0
  84. package/dist/infra/filesystem.d.ts.map +1 -0
  85. package/dist/infra/filesystem.js +247 -0
  86. package/dist/infra/filesystem.js.map +1 -0
  87. package/dist/infra/spawn.d.ts +67 -0
  88. package/dist/infra/spawn.d.ts.map +1 -0
  89. package/dist/infra/spawn.js +116 -0
  90. package/dist/infra/spawn.js.map +1 -0
  91. package/dist/infra/sseBus.d.ts +36 -0
  92. package/dist/infra/sseBus.d.ts.map +1 -0
  93. package/dist/infra/sseBus.js +72 -0
  94. package/dist/infra/sseBus.js.map +1 -0
  95. package/dist/interfaces/ACPClient.d.ts +1 -1
  96. package/dist/interfaces/ACPClient.d.ts.map +1 -1
  97. package/dist/interfaces/RepoBackend.d.ts +1 -1
  98. package/dist/interfaces/TaskBackend.d.ts +1 -1
  99. package/dist/main.js +1 -1
  100. package/dist/main.js.map +1 -1
  101. package/dist/providers/GitLabRepoBackend.d.ts +1 -1
  102. package/dist/providers/LocalACPClient.d.ts +1 -1
  103. package/dist/providers/LocalACPClient.d.ts.map +1 -1
  104. package/dist/providers/MarkdownTaskBackend.d.ts +1 -1
  105. package/dist/services/CardService.d.ts +86 -0
  106. package/dist/services/CardService.d.ts.map +1 -0
  107. package/dist/services/CardService.js +313 -0
  108. package/dist/services/CardService.js.map +1 -0
  109. package/dist/services/ChatService.d.ts +62 -0
  110. package/dist/services/ChatService.d.ts.map +1 -0
  111. package/dist/services/ChatService.js +157 -0
  112. package/dist/services/ChatService.js.map +1 -0
  113. package/dist/services/LogService.d.ts +46 -0
  114. package/dist/services/LogService.d.ts.map +1 -0
  115. package/dist/services/LogService.js +185 -0
  116. package/dist/services/LogService.js.map +1 -0
  117. package/dist/services/PipelineService.d.ts +71 -0
  118. package/dist/services/PipelineService.d.ts.map +1 -0
  119. package/dist/services/PipelineService.js +349 -0
  120. package/dist/services/PipelineService.js.map +1 -0
  121. package/dist/services/ProjectService.d.ts +105 -0
  122. package/dist/services/ProjectService.d.ts.map +1 -0
  123. package/dist/services/ProjectService.js +346 -0
  124. package/dist/services/ProjectService.js.map +1 -0
  125. package/dist/services/SkillService.d.ts +38 -0
  126. package/dist/services/SkillService.d.ts.map +1 -0
  127. package/dist/services/SkillService.js +301 -0
  128. package/dist/services/SkillService.js.map +1 -0
  129. package/dist/services/SystemService.d.ts +67 -0
  130. package/dist/services/SystemService.d.ts.map +1 -0
  131. package/dist/services/SystemService.js +278 -0
  132. package/dist/services/SystemService.js.map +1 -0
  133. package/dist/services/WorkerService.d.ts +83 -0
  134. package/dist/services/WorkerService.d.ts.map +1 -0
  135. package/dist/services/WorkerService.js +262 -0
  136. package/dist/services/WorkerService.js.map +1 -0
  137. package/dist/services/container.d.ts +44 -0
  138. package/dist/services/container.d.ts.map +1 -0
  139. package/dist/services/container.js +104 -0
  140. package/dist/services/container.js.map +1 -0
  141. package/dist/services/defaults.d.ts +15 -0
  142. package/dist/services/defaults.d.ts.map +1 -0
  143. package/dist/services/defaults.js +11 -0
  144. package/dist/services/defaults.js.map +1 -0
  145. package/dist/services/executors.d.ts +38 -0
  146. package/dist/services/executors.d.ts.map +1 -0
  147. package/dist/services/executors.js +157 -0
  148. package/dist/services/executors.js.map +1 -0
  149. package/dist/services/ports.d.ts +17 -0
  150. package/dist/services/ports.d.ts.map +1 -0
  151. package/dist/services/ports.js +2 -0
  152. package/dist/services/ports.js.map +1 -0
  153. package/dist/shared/domainEvents.d.ts +118 -0
  154. package/dist/shared/domainEvents.d.ts.map +1 -0
  155. package/dist/shared/domainEvents.js +40 -0
  156. package/dist/shared/domainEvents.js.map +1 -0
  157. package/dist/shared/errors.d.ts +59 -0
  158. package/dist/shared/errors.d.ts.map +1 -0
  159. package/dist/shared/errors.js +79 -0
  160. package/dist/shared/errors.js.map +1 -0
  161. package/dist/shared/result.d.ts +51 -0
  162. package/dist/shared/result.d.ts.map +1 -0
  163. package/dist/shared/result.js +48 -0
  164. package/dist/shared/result.js.map +1 -0
  165. package/dist/shared/runtimePaths.d.ts +78 -0
  166. package/dist/shared/runtimePaths.d.ts.map +1 -0
  167. package/dist/shared/runtimePaths.js +179 -0
  168. package/dist/shared/runtimePaths.js.map +1 -0
  169. package/dist/shared/runtimeSchemas.d.ts +324 -0
  170. package/dist/shared/runtimeSchemas.d.ts.map +1 -0
  171. package/dist/shared/runtimeSchemas.js +124 -0
  172. package/dist/shared/runtimeSchemas.js.map +1 -0
  173. package/dist/shared/types.d.ts +97 -0
  174. package/dist/shared/types.d.ts.map +1 -0
  175. package/dist/shared/types.js +11 -0
  176. package/dist/shared/types.js.map +1 -0
  177. package/package.json +1 -1
@@ -0,0 +1,349 @@
1
+ /**
2
+ * @module services/PipelineService
3
+ * @description Pipeline 控制 + yaml CRUD service
4
+ *
5
+ * @layer services
6
+ *
7
+ * 职责:
8
+ * - start:spawn 后台 supervisor(唯一允许用 ProcessSpawner 的 service)
9
+ * - stop:注入 PipelineExecutor.stop 调 CLI 停止(Phase 3 会接到 Domain 内部实现)
10
+ * - reset:注入 PipelineExecutor.reset
11
+ * - status:读 supervisor.pid 判进程活
12
+ * - pipelines yaml CRUD:list / get / write / create / delete / switch active
13
+ */
14
+ import { createHash } from 'node:crypto';
15
+ import { resolve } from 'node:path';
16
+ import YAML from 'yaml';
17
+ import { domainError } from '../shared/errors.js';
18
+ import { err, ok } from '../shared/result.js';
19
+ import { activePipelineFile, logsDir, PipelineFilenameRe, pipelineFile, pipelinesDir, projectDir, supervisorPidFile, } from '../shared/runtimePaths.js';
20
+ export class PipelineService {
21
+ deps;
22
+ constructor(deps) {
23
+ this.deps = deps;
24
+ }
25
+ /** 启动 pipeline —— 已在跑直接返当前 pid。 */
26
+ async start(project) {
27
+ if (!isValidProject(project))
28
+ return err(invalidProject());
29
+ if (!this.deps.fs.exists(projectDir(project))) {
30
+ return err(projectNotFound(project));
31
+ }
32
+ const existing = this.readSupervisorPid(project);
33
+ if (existing) {
34
+ return ok({ status: 'running', pid: existing });
35
+ }
36
+ if (!this.deps.fs.exists(logsDir(project))) {
37
+ this.deps.fs.mkdir(logsDir(project), { recursive: true });
38
+ }
39
+ const date = this.deps.clock.nowIso().slice(0, 10);
40
+ const logPath = resolve(logsDir(project), `console-tick-${date}.log`);
41
+ try {
42
+ const child = this.deps.spawner.spawnSupervisor({
43
+ args: ['tick', project],
44
+ logPath,
45
+ });
46
+ const pid = child.pid ?? null;
47
+ this.deps.events.emit({
48
+ type: 'pipeline.started',
49
+ project,
50
+ pid: pid ?? 0,
51
+ ts: this.deps.clock.now(),
52
+ });
53
+ return ok({ status: 'running', pid });
54
+ }
55
+ catch (cause) {
56
+ return err(domainError('external', 'PIPELINE_SPAWN_FAIL', '启动 pipeline 失败', {
57
+ cause,
58
+ details: { message: cause instanceof Error ? cause.message : String(cause) },
59
+ }));
60
+ }
61
+ }
62
+ async stop(project) {
63
+ if (!isValidProject(project))
64
+ return err(invalidProject());
65
+ if (!this.deps.executor) {
66
+ return err(domainError('internal', 'EXECUTOR_MISSING', 'PipelineExecutor 未注入'));
67
+ }
68
+ try {
69
+ await this.deps.executor.stop(project);
70
+ }
71
+ catch (cause) {
72
+ return err(domainError('external', 'PIPELINE_STOP_FAIL', 'stop pipeline 失败', {
73
+ cause,
74
+ details: { message: cause instanceof Error ? cause.message : String(cause) },
75
+ }));
76
+ }
77
+ this.deps.events.emit({
78
+ type: 'pipeline.stopped',
79
+ project,
80
+ ts: this.deps.clock.now(),
81
+ });
82
+ return ok(undefined);
83
+ }
84
+ async reset(project, opts = {}) {
85
+ if (!isValidProject(project))
86
+ return err(invalidProject());
87
+ if (!this.deps.executor) {
88
+ return err(domainError('internal', 'EXECUTOR_MISSING', 'PipelineExecutor 未注入'));
89
+ }
90
+ try {
91
+ await this.deps.executor.reset(project, opts);
92
+ }
93
+ catch (cause) {
94
+ return err(domainError('external', 'PIPELINE_RESET_FAIL', 'reset pipeline 失败', {
95
+ cause,
96
+ }));
97
+ }
98
+ return ok(undefined);
99
+ }
100
+ async status(project) {
101
+ if (!isValidProject(project))
102
+ return err(invalidProject());
103
+ const pid = this.readSupervisorPid(project);
104
+ return ok({ status: pid ? 'running' : 'idle', pid });
105
+ }
106
+ // ─── Pipeline yaml CRUD ──────────────────────────────────────────
107
+ async listPipelines(project) {
108
+ if (!isValidProject(project))
109
+ return err(invalidProject());
110
+ const dir = pipelinesDir(project);
111
+ if (!this.deps.fs.exists(dir)) {
112
+ return ok({ active: null, available: [] });
113
+ }
114
+ let files;
115
+ try {
116
+ files = this.deps.fs
117
+ .readDir(dir)
118
+ .filter((e) => e.isFile && e.name.endsWith('.yaml'))
119
+ .map((e) => e.name)
120
+ .sort();
121
+ }
122
+ catch (cause) {
123
+ return err(domainError('internal', 'PIPELINES_READ_FAIL', 'pipelines 目录读取失败', { cause }));
124
+ }
125
+ const activePath = activePipelineFile(project);
126
+ let activeHash = null;
127
+ if (this.deps.fs.exists(activePath)) {
128
+ try {
129
+ const content = this.deps.fs.readFile(activePath);
130
+ activeHash = createHash('sha256').update(content).digest('hex');
131
+ }
132
+ catch {
133
+ /* ignore */
134
+ }
135
+ }
136
+ const available = files
137
+ .filter((f) => f !== 'project.yaml')
138
+ .map((name) => {
139
+ const full = resolve(dir, name);
140
+ let isActive = false;
141
+ try {
142
+ const content = this.deps.fs.readFile(full);
143
+ isActive = activeHash !== null && createHash('sha256').update(content).digest('hex') === activeHash;
144
+ }
145
+ catch {
146
+ /* ignore */
147
+ }
148
+ return { name, isActive };
149
+ });
150
+ return ok({ active: activeHash ? 'project.yaml' : null, available });
151
+ }
152
+ async readPipeline(project, filename) {
153
+ if (!isValidProject(project))
154
+ return err(invalidProject());
155
+ if (!PipelineFilenameRe.test(filename)) {
156
+ return err(domainError('validation', 'INVALID_FILENAME', 'pipeline 文件名非法'));
157
+ }
158
+ const path = pipelineFile(project, filename);
159
+ if (!this.deps.fs.exists(path)) {
160
+ return err(domainError('not-found', 'PIPELINE_NOT_FOUND', 'pipeline 文件不存在'));
161
+ }
162
+ let content;
163
+ try {
164
+ content = this.deps.fs.readFile(path);
165
+ }
166
+ catch (cause) {
167
+ return err(domainError('internal', 'PIPELINE_READ_FAIL', '读取失败', { cause }));
168
+ }
169
+ const etag = hashEtag(content);
170
+ let parsed = null;
171
+ let parseError = null;
172
+ try {
173
+ parsed = YAML.parse(content);
174
+ }
175
+ catch (e) {
176
+ parseError = e instanceof Error ? e.message : String(e);
177
+ }
178
+ return ok({
179
+ content,
180
+ etag,
181
+ parsed,
182
+ parseError,
183
+ isActive: filename === 'project.yaml',
184
+ });
185
+ }
186
+ async writePipeline(project, filename, content, etag) {
187
+ if (!isValidProject(project))
188
+ return err(invalidProject());
189
+ if (!PipelineFilenameRe.test(filename)) {
190
+ return err(domainError('validation', 'INVALID_FILENAME', 'pipeline 文件名非法'));
191
+ }
192
+ if (!etag) {
193
+ return err(domainError('validation', 'ETAG_REQUIRED', 'etag 必填'));
194
+ }
195
+ const path = pipelineFile(project, filename);
196
+ if (!this.deps.fs.exists(path)) {
197
+ return err(domainError('not-found', 'PIPELINE_NOT_FOUND', 'pipeline 文件不存在'));
198
+ }
199
+ let current;
200
+ try {
201
+ current = this.deps.fs.readFile(path);
202
+ }
203
+ catch (cause) {
204
+ return err(domainError('internal', 'PIPELINE_READ_FAIL', '读取失败', { cause }));
205
+ }
206
+ if (hashEtag(current) !== etag) {
207
+ return err(domainError('conflict', 'PIPELINE_ETAG_MISMATCH', 'pipeline 被其它人修改,请重新加载'));
208
+ }
209
+ try {
210
+ YAML.parse(content);
211
+ }
212
+ catch (e) {
213
+ return err(domainError('validation', 'YAML_INVALID', 'YAML 语法错误', {
214
+ details: { message: e instanceof Error ? e.message : String(e) },
215
+ }));
216
+ }
217
+ try {
218
+ this.deps.fs.writeFileAtomic(path, content);
219
+ }
220
+ catch (cause) {
221
+ return err(domainError('internal', 'PIPELINE_WRITE_FAIL', '写入失败', { cause }));
222
+ }
223
+ return ok({ etag: hashEtag(content) });
224
+ }
225
+ async createPipeline(project, input) {
226
+ if (!isValidProject(project))
227
+ return err(invalidProject());
228
+ if (!PipelineFilenameRe.test(input.name)) {
229
+ return err(domainError('validation', 'INVALID_FILENAME', '文件名非法'));
230
+ }
231
+ const dir = pipelinesDir(project);
232
+ if (!this.deps.fs.exists(dir)) {
233
+ return err(domainError('not-found', 'PIPELINES_DIR_NOT_FOUND', 'pipelines 目录不存在'));
234
+ }
235
+ const path = pipelineFile(project, input.name);
236
+ if (this.deps.fs.exists(path)) {
237
+ return err(domainError('conflict', 'PIPELINE_EXISTS', 'pipeline 已存在'));
238
+ }
239
+ const template = input.template ?? 'blank';
240
+ let content;
241
+ if (template === 'sample') {
242
+ const src = resolve(dir, 'sample.yaml.example');
243
+ if (!this.deps.fs.exists(src)) {
244
+ return err(domainError('not-found', 'SAMPLE_NOT_FOUND', 'sample 模板不存在'));
245
+ }
246
+ content = this.deps.fs.readFile(src);
247
+ }
248
+ else if (template === 'active') {
249
+ const src = activePipelineFile(project);
250
+ if (!this.deps.fs.exists(src)) {
251
+ return err(domainError('not-found', 'ACTIVE_NOT_FOUND', '当前 active pipeline 不存在'));
252
+ }
253
+ content = this.deps.fs.readFile(src);
254
+ }
255
+ else {
256
+ content = `mode: project\n\nstages:\n - name: develop\n on_complete: "move_card Done"\n on_fail:\n action: "label NEEDS-FIX"\n halt: true\n`;
257
+ }
258
+ try {
259
+ this.deps.fs.writeFileAtomic(path, content);
260
+ }
261
+ catch (cause) {
262
+ return err(domainError('internal', 'PIPELINE_WRITE_FAIL', '写入失败', { cause }));
263
+ }
264
+ return ok({ name: input.name, content, etag: hashEtag(content) });
265
+ }
266
+ async deletePipeline(project, filename) {
267
+ if (!isValidProject(project))
268
+ return err(invalidProject());
269
+ if (!PipelineFilenameRe.test(filename)) {
270
+ return err(domainError('validation', 'INVALID_FILENAME', '文件名非法'));
271
+ }
272
+ if (filename === 'project.yaml') {
273
+ return err(domainError('conflict', 'CANNOT_DELETE_ACTIVE', '当前 active pipeline 不能删,先切换再删'));
274
+ }
275
+ if (filename === 'sample.yaml.example') {
276
+ return err(domainError('conflict', 'CANNOT_DELETE_SAMPLE', 'sample 模板不能删'));
277
+ }
278
+ const path = pipelineFile(project, filename);
279
+ if (!this.deps.fs.exists(path)) {
280
+ return err(domainError('not-found', 'PIPELINE_NOT_FOUND', 'pipeline 不存在'));
281
+ }
282
+ try {
283
+ this.deps.fs.unlink(path);
284
+ }
285
+ catch (cause) {
286
+ return err(domainError('internal', 'PIPELINE_DELETE_FAIL', '删除失败', { cause }));
287
+ }
288
+ return ok(undefined);
289
+ }
290
+ /** 切换 active pipeline —— 复制指定文件到 project.yaml。 */
291
+ async switchActive(project, filename) {
292
+ if (!isValidProject(project))
293
+ return err(invalidProject());
294
+ if (!PipelineFilenameRe.test(filename) || filename === 'project.yaml') {
295
+ return err(domainError('validation', 'INVALID_FILENAME', 'pipeline 文件名非法或不能是 project.yaml'));
296
+ }
297
+ if (this.readSupervisorPid(project)) {
298
+ return err(domainError('conflict', 'PIPELINE_RUNNING', 'pipeline 正在跑,先停止再切换'));
299
+ }
300
+ const src = pipelineFile(project, filename);
301
+ if (!this.deps.fs.exists(src)) {
302
+ return err(domainError('not-found', 'PIPELINE_NOT_FOUND', '源 pipeline 不存在'));
303
+ }
304
+ try {
305
+ const content = this.deps.fs.readFile(src);
306
+ this.deps.fs.writeFileAtomic(activePipelineFile(project), content);
307
+ }
308
+ catch (cause) {
309
+ return err(domainError('internal', 'PIPELINE_SWITCH_FAIL', '切换失败', { cause }));
310
+ }
311
+ return ok({ activePipeline: filename });
312
+ }
313
+ // ─── 内部 ─────────────────────────────────────────────────────────
314
+ readSupervisorPid(project) {
315
+ const path = supervisorPidFile(project);
316
+ if (!this.deps.fs.exists(path))
317
+ return null;
318
+ try {
319
+ const raw = this.deps.fs.readFile(path);
320
+ const pid = Number.parseInt(raw.trim(), 10);
321
+ if (!Number.isFinite(pid) || pid <= 0)
322
+ return null;
323
+ try {
324
+ process.kill(pid, 0);
325
+ return pid;
326
+ }
327
+ catch {
328
+ return null;
329
+ }
330
+ }
331
+ catch {
332
+ return null;
333
+ }
334
+ }
335
+ }
336
+ // ─── helpers ──────────────────────────────────────────────────────
337
+ function hashEtag(content) {
338
+ return createHash('sha256').update(content).digest('hex').slice(0, 16);
339
+ }
340
+ function isValidProject(project) {
341
+ return typeof project === 'string' && /^[a-zA-Z0-9_-]+$/.test(project);
342
+ }
343
+ function invalidProject() {
344
+ return domainError('validation', 'INVALID_PROJECT_NAME', '项目名非法');
345
+ }
346
+ function projectNotFound(name) {
347
+ return domainError('not-found', 'PROJECT_NOT_FOUND', `项目 ${name} 不存在`);
348
+ }
349
+ //# sourceMappingURL=PipelineService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PipelineService.js","sourceRoot":"","sources":["../../src/services/PipelineService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import type { Clock } from '../infra/clock.js';
2
+ import type { FileSystem } from '../infra/filesystem.js';
3
+ import type { DomainEventBus } from '../shared/domainEvents.js';
4
+ import { type Result } from '../shared/result.js';
5
+ export type PipelineStatus = 'idle' | 'running' | 'stopping' | 'error';
6
+ export interface ProjectSummary {
7
+ readonly name: string;
8
+ readonly repoDir: string | null;
9
+ readonly pmBackend: string;
10
+ readonly agentProvider: string;
11
+ readonly cards: {
12
+ total: number;
13
+ inprogress: number;
14
+ done: number;
15
+ };
16
+ readonly workers: {
17
+ total: number;
18
+ active: number;
19
+ };
20
+ readonly pipelineStatus: PipelineStatus;
21
+ readonly lastActivityAt: string | null;
22
+ }
23
+ export interface ConfContent {
24
+ readonly content: string;
25
+ readonly etag: string;
26
+ }
27
+ export interface ProjectInitExecutor {
28
+ /**
29
+ * 由 Phase 3 的 delivery 层注入。默认 container 未注入时 create() 会返 external 错误。
30
+ * 拆出 port 是因为:
31
+ * - executeProjectInit 目前深度依赖 process.exit / 交互 readline,短期迁不进来
32
+ * - 重构期间保留命令层调 Service,Service 再回调命令层的 port 实现
33
+ */
34
+ init(project: string, opts: ProjectInitOpts): Promise<void>;
35
+ }
36
+ export interface ProjectInitOpts {
37
+ projectDir: string;
38
+ mergeBranch: string;
39
+ maxWorkers: string;
40
+ gitlabProject?: string;
41
+ gitlabProjectId?: string;
42
+ matrixRoomId?: string;
43
+ }
44
+ export interface CreateProjectInput extends ProjectInitOpts {
45
+ name: string;
46
+ }
47
+ export interface DeleteProjectOpts {
48
+ includeClaudeDir?: boolean;
49
+ }
50
+ export interface DeleteProjectReport {
51
+ readonly name: string;
52
+ readonly claudeRemoved: Array<{
53
+ path: string;
54
+ ok: boolean;
55
+ error?: string;
56
+ }>;
57
+ }
58
+ export interface ProjectServiceDeps {
59
+ readonly fs: FileSystem;
60
+ readonly clock: Clock;
61
+ readonly events: DomainEventBus;
62
+ readonly initExecutor?: ProjectInitExecutor;
63
+ }
64
+ export declare class ProjectService {
65
+ private readonly deps;
66
+ constructor(deps: ProjectServiceDeps);
67
+ /** 列出 ~/.coral/projects/ 下所有项目的概览。 */
68
+ list(): Promise<Result<ProjectSummary[]>>;
69
+ /** 获取单个项目概览。找不到返 not-found。 */
70
+ get(name: string): Promise<Result<ProjectSummary>>;
71
+ /**
72
+ * 创建项目。需要 ProjectInitExecutor 注入。
73
+ * 已存在返 conflict。
74
+ */
75
+ create(input: CreateProjectInput): Promise<Result<ProjectSummary>>;
76
+ /**
77
+ * 删除项目。pipeline 在跑时拒绝(conflict)。
78
+ * opts.includeClaudeDir 默认 true,也会删对应 repo 的 .claude/。
79
+ */
80
+ delete(name: string, opts?: DeleteProjectOpts): Promise<Result<DeleteProjectReport>>;
81
+ /** 读 conf 文件 —— 返回 content + etag(SHA-256 前 16 位)。 */
82
+ readConf(name: string): Promise<Result<ConfContent>>;
83
+ /**
84
+ * 写 conf —— etag 乐观锁。mismatch 返 conflict;内容相同 etag 不变。
85
+ * 文件权限保持 0600(conf 可能含 secret)。
86
+ */
87
+ writeConf(name: string, content: string, etag: string): Promise<Result<{
88
+ etag: string;
89
+ }>>;
90
+ private isValidName;
91
+ private readSummary;
92
+ private parseConf;
93
+ /**
94
+ * 卡片计数 —— 遍历 cards/<state>/*.md 子目录。
95
+ * v0.49.15 修过同一个坑,现在统一走 runtimePaths + 在 service 层单点实现。
96
+ */
97
+ private countCards;
98
+ /**
99
+ * Worker marker 计数 —— 匹配双前缀 + 老单前缀两种格式(v0.49.16 之前遗留)。
100
+ * 活跃判定:marker 最近 5 分钟内更新。
101
+ */
102
+ private countWorkers;
103
+ private isPipelineRunning;
104
+ }
105
+ //# sourceMappingURL=ProjectService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectService.d.ts","sourceRoot":"","sources":["../../src/services/ProjectService.ts"],"names":[],"mappings":"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"}