@coralai/sps-cli 0.44.0 → 0.45.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 (62) hide show
  1. package/README.md +1 -1
  2. package/dist/console-assets/assets/index-COKveGOw.js +231 -0
  3. package/dist/console-assets/assets/index-DTOYQgOY.css +1 -0
  4. package/dist/console-assets/index.html +2 -2
  5. package/dist/console-server/index.d.ts.map +1 -1
  6. package/dist/console-server/index.js +25 -5
  7. package/dist/console-server/index.js.map +1 -1
  8. package/dist/console-server/lib/cardReader.d.ts +27 -0
  9. package/dist/console-server/lib/cardReader.d.ts.map +1 -0
  10. package/dist/console-server/lib/cardReader.js +131 -0
  11. package/dist/console-server/lib/cardReader.js.map +1 -0
  12. package/dist/console-server/lib/spawnCli.d.ts +31 -0
  13. package/dist/console-server/lib/spawnCli.d.ts.map +1 -0
  14. package/dist/console-server/lib/spawnCli.js +64 -0
  15. package/dist/console-server/lib/spawnCli.js.map +1 -0
  16. package/dist/console-server/routes/cards.d.ts +7 -0
  17. package/dist/console-server/routes/cards.d.ts.map +1 -0
  18. package/dist/console-server/routes/cards.js +81 -0
  19. package/dist/console-server/routes/cards.js.map +1 -0
  20. package/dist/console-server/routes/chat.d.ts +21 -0
  21. package/dist/console-server/routes/chat.d.ts.map +1 -0
  22. package/dist/console-server/routes/chat.js +233 -0
  23. package/dist/console-server/routes/chat.js.map +1 -0
  24. package/dist/console-server/routes/logs.d.ts +14 -0
  25. package/dist/console-server/routes/logs.d.ts.map +1 -0
  26. package/dist/console-server/routes/logs.js +215 -0
  27. package/dist/console-server/routes/logs.js.map +1 -0
  28. package/dist/console-server/routes/pipeline.d.ts +8 -0
  29. package/dist/console-server/routes/pipeline.d.ts.map +1 -0
  30. package/dist/console-server/routes/pipeline.js +96 -0
  31. package/dist/console-server/routes/pipeline.js.map +1 -0
  32. package/dist/console-server/routes/skills.d.ts +7 -0
  33. package/dist/console-server/routes/skills.d.ts.map +1 -0
  34. package/dist/console-server/routes/skills.js +242 -0
  35. package/dist/console-server/routes/skills.js.map +1 -0
  36. package/dist/console-server/routes/system.d.ts +1 -1
  37. package/dist/console-server/routes/system.d.ts.map +1 -1
  38. package/dist/console-server/routes/system.js +78 -1
  39. package/dist/console-server/routes/system.js.map +1 -1
  40. package/dist/console-server/routes/workers.d.ts +7 -0
  41. package/dist/console-server/routes/workers.d.ts.map +1 -0
  42. package/dist/console-server/routes/workers.js +133 -0
  43. package/dist/console-server/routes/workers.js.map +1 -0
  44. package/dist/console-server/sse/projectStream.d.ts +10 -0
  45. package/dist/console-server/sse/projectStream.d.ts.map +1 -0
  46. package/dist/console-server/sse/projectStream.js +86 -0
  47. package/dist/console-server/sse/projectStream.js.map +1 -0
  48. package/dist/console-server/watchers/cardWatcher.d.ts +1 -3
  49. package/dist/console-server/watchers/cardWatcher.d.ts.map +1 -1
  50. package/dist/console-server/watchers/cardWatcher.js +28 -22
  51. package/dist/console-server/watchers/cardWatcher.js.map +1 -1
  52. package/dist/console-server/watchers/markerWatcher.d.ts +7 -0
  53. package/dist/console-server/watchers/markerWatcher.d.ts.map +1 -0
  54. package/dist/console-server/watchers/markerWatcher.js +53 -0
  55. package/dist/console-server/watchers/markerWatcher.js.map +1 -0
  56. package/dist/console-server/watchers/pipelinePoller.d.ts +2 -0
  57. package/dist/console-server/watchers/pipelinePoller.d.ts.map +1 -0
  58. package/dist/console-server/watchers/pipelinePoller.js +52 -0
  59. package/dist/console-server/watchers/pipelinePoller.js.map +1 -0
  60. package/package.json +1 -1
  61. package/dist/console-assets/assets/index-Bhd2f9AP.js +0 -125
  62. package/dist/console-assets/assets/index-bsAN2a12.css +0 -1
@@ -1,8 +1,6 @@
1
1
  /**
2
2
  * @module console-server/watchers/cardWatcher
3
- * @description chokidar 监听 ~/.coral/cards 目录,变化推 eventBus
4
- *
5
- * 文件变化 → card.created / card.updated / card.deleted 事件
3
+ * @description chokidar 监听 cards 目录变化,推 card.created/updated/deleted 事件
6
4
  */
7
5
  import { type FSWatcher } from 'chokidar';
8
6
  export declare function startCardWatcher(coralRoot: string): FSWatcher;
@@ -1 +1 @@
1
- {"version":3,"file":"cardWatcher.d.ts","sourceRoot":"","sources":["../../../src/console-server/watchers/cardWatcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAWpD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAuB7D"}
1
+ {"version":3,"file":"cardWatcher.d.ts","sourceRoot":"","sources":["../../../src/console-server/watchers/cardWatcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AA+BpD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAY7D"}
@@ -1,42 +1,48 @@
1
1
  /**
2
2
  * @module console-server/watchers/cardWatcher
3
- * @description chokidar 监听 ~/.coral/cards 目录,变化推 eventBus
4
- *
5
- * 文件变化 → card.created / card.updated / card.deleted 事件
3
+ * @description chokidar 监听 cards 目录变化,推 card.created/updated/deleted 事件
6
4
  */
7
5
  import chokidar from 'chokidar';
8
- import { basename } from 'node:path';
6
+ import { resolve } from 'node:path';
7
+ import { readCard } from '../lib/cardReader.js';
9
8
  import { eventBus } from '../sse/eventBus.js';
9
+ const HOME = process.env.HOME || '/home/coral';
10
10
  function extractProjectAndSeq(path) {
11
- // 路径形如 ~/.coral/projects/<project>/cards/<seq>-<slug>.md
12
11
  const match = path.match(/projects\/([^/]+)\/cards\/(\d+)(?:-[^/]*)?\.md$/);
13
12
  if (!match)
14
13
  return null;
15
- return { project: match[1], seq: Number.parseInt(match[2], 10) };
14
+ const seq = Number.parseInt(match[2] ?? '', 10);
15
+ if (!Number.isFinite(seq))
16
+ return null;
17
+ return { project: match[1] ?? '', seq };
18
+ }
19
+ function publishCardEvent(event, path) {
20
+ const info = extractProjectAndSeq(path);
21
+ if (!info)
22
+ return;
23
+ const projectDir = resolve(HOME, '.coral', 'projects', info.project);
24
+ if (event === 'card.deleted') {
25
+ eventBus.publish('card.deleted', info);
26
+ return;
27
+ }
28
+ const card = readCard(projectDir, info.seq);
29
+ eventBus.publish(event, {
30
+ project: info.project,
31
+ seq: info.seq,
32
+ card: card ?? null,
33
+ });
16
34
  }
17
35
  export function startCardWatcher(coralRoot) {
18
- const pattern = `${coralRoot}/cards 目录`;
36
+ const pattern = `${coralRoot}/projects/*/cards/*.md`;
19
37
  const watcher = chokidar.watch(pattern, {
20
38
  persistent: true,
21
39
  ignoreInitial: true,
22
40
  awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },
23
41
  });
24
42
  watcher
25
- .on('add', (path) => {
26
- const info = extractProjectAndSeq(path);
27
- if (info)
28
- eventBus.publish('card.created', { ...info, path: basename(path) });
29
- })
30
- .on('change', (path) => {
31
- const info = extractProjectAndSeq(path);
32
- if (info)
33
- eventBus.publish('card.updated', { ...info, path: basename(path) });
34
- })
35
- .on('unlink', (path) => {
36
- const info = extractProjectAndSeq(path);
37
- if (info)
38
- eventBus.publish('card.deleted', info);
39
- });
43
+ .on('add', (path) => publishCardEvent('card.created', path))
44
+ .on('change', (path) => publishCardEvent('card.updated', path))
45
+ .on('unlink', (path) => publishCardEvent('card.deleted', path));
40
46
  return watcher;
41
47
  }
42
48
  //# sourceMappingURL=cardWatcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cardWatcher.js","sourceRoot":"","sources":["../../../src/console-server/watchers/cardWatcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,QAA4B,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,SAAS,oBAAoB,CAAC,IAAY;IACxC,yDAAyD;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,OAAO,GAAG,GAAG,SAAS,WAAW,CAAC;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE;QACtC,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE;KAChE,CAAC,CAAC;IAEH,OAAO;SACJ,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;QAClB,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI;YAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC;SACD,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI;YAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC;SACD,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,IAAI;YAAE,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"cardWatcher.js","sourceRoot":"","sources":["../../../src/console-server/watchers/cardWatcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,QAA4B,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,aAAa,CAAC;AAE/C,SAAS,oBAAoB,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,IAAY;IACnD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACrE,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;QAC7B,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE;QACtB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,IAAI,IAAI;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,OAAO,GAAG,GAAG,SAAS,wBAAwB,CAAC;IACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE;QACtC,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE;KAChE,CAAC,CAAC;IACH,OAAO;SACJ,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;SAC3D,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;SAC9D,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;IAClE,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @module console-server/watchers/markerWatcher
3
+ * @description 监听 runtime/worker-*-current.json,推 worker.updated 事件
4
+ */
5
+ import { type FSWatcher } from 'chokidar';
6
+ export declare function startMarkerWatcher(coralRoot: string): FSWatcher;
7
+ //# sourceMappingURL=markerWatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markerWatcher.d.ts","sourceRoot":"","sources":["../../../src/console-server/watchers/markerWatcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAkCpD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAY/D"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @module console-server/watchers/markerWatcher
3
+ * @description 监听 runtime/worker-*-current.json,推 worker.updated 事件
4
+ */
5
+ import chokidar from 'chokidar';
6
+ import { existsSync, readFileSync } from 'node:fs';
7
+ import { basename } from 'node:path';
8
+ import { eventBus } from '../sse/eventBus.js';
9
+ function extractProjectAndSlot(path) {
10
+ const m = path.match(/projects\/([^/]+)\/runtime\/worker-(\d+)-current\.json$/);
11
+ if (!m)
12
+ return null;
13
+ const slot = Number.parseInt(m[2] ?? '', 10);
14
+ if (!Number.isFinite(slot))
15
+ return null;
16
+ return { project: m[1] ?? '', slot };
17
+ }
18
+ function publishMarker(event, path) {
19
+ const info = extractProjectAndSlot(path);
20
+ if (!info)
21
+ return;
22
+ let marker = null;
23
+ if (event !== 'worker.deleted' && existsSync(path)) {
24
+ try {
25
+ marker = JSON.parse(readFileSync(path, 'utf-8'));
26
+ }
27
+ catch {
28
+ // 写入中,下次再推
29
+ return;
30
+ }
31
+ }
32
+ eventBus.publish('worker.updated', {
33
+ project: info.project,
34
+ slot: info.slot,
35
+ marker,
36
+ markerFile: basename(path),
37
+ deleted: event === 'worker.deleted',
38
+ });
39
+ }
40
+ export function startMarkerWatcher(coralRoot) {
41
+ const pattern = `${coralRoot}/projects/*/runtime/worker-*-current.json`;
42
+ const watcher = chokidar.watch(pattern, {
43
+ persistent: true,
44
+ ignoreInitial: true,
45
+ awaitWriteFinish: { stabilityThreshold: 80, pollInterval: 40 },
46
+ });
47
+ watcher
48
+ .on('add', (path) => publishMarker('worker.added', path))
49
+ .on('change', (path) => publishMarker('worker.updated', path))
50
+ .on('unlink', (path) => publishMarker('worker.deleted', path));
51
+ return watcher;
52
+ }
53
+ //# sourceMappingURL=markerWatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markerWatcher.js","sourceRoot":"","sources":["../../../src/console-server/watchers/markerWatcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,QAA4B,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,SAAS,qBAAqB,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAChF,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,IAAY;IAChD,MAAM,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,IAAI,MAAM,GAAY,IAAI,CAAC;IAC3B,IAAI,KAAK,KAAK,gBAAgB,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,WAAW;YACX,OAAO;QACT,CAAC;IACH,CAAC;IACD,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE;QACjC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM;QACN,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC;QAC1B,OAAO,EAAE,KAAK,KAAK,gBAAgB;KACpC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,OAAO,GAAG,GAAG,SAAS,2CAA2C,CAAC;IACxE,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE;QACtC,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;KAC/D,CAAC,CAAC;IACH,OAAO;SACJ,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;SACxD,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;SAC7D,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC;IACjE,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function startPipelinePoller(coralRoot: string, intervalMs?: number): () => void;
2
+ //# sourceMappingURL=pipelinePoller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipelinePoller.d.ts","sourceRoot":"","sources":["../../../src/console-server/watchers/pipelinePoller.ts"],"names":[],"mappings":"AA+BA,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,SAAO,GAAG,MAAM,IAAI,CAwBpF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @module console-server/watchers/pipelinePoller
3
+ * @description 轮询每个项目的 supervisor.pid,状态变化推 pipeline.status
4
+ * 用 2s 间隔;chokidar 对 pid 变化不敏感,所以用 setInterval
5
+ */
6
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
7
+ import { resolve } from 'node:path';
8
+ import { eventBus } from '../sse/eventBus.js';
9
+ function pipelineState(projectDir) {
10
+ const pidFile = resolve(projectDir, 'runtime', 'supervisor.pid');
11
+ if (!existsSync(pidFile))
12
+ return { pid: null, status: 'idle' };
13
+ try {
14
+ const pid = Number.parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
15
+ if (!Number.isFinite(pid) || pid <= 0)
16
+ return { pid: null, status: 'idle' };
17
+ try {
18
+ process.kill(pid, 0);
19
+ return { pid, status: 'running' };
20
+ }
21
+ catch {
22
+ return { pid: null, status: 'idle' };
23
+ }
24
+ }
25
+ catch {
26
+ return { pid: null, status: 'idle' };
27
+ }
28
+ }
29
+ export function startPipelinePoller(coralRoot, intervalMs = 2000) {
30
+ const projectsDir = resolve(coralRoot, 'projects');
31
+ const previous = new Map();
32
+ const tick = () => {
33
+ if (!existsSync(projectsDir))
34
+ return;
35
+ const projects = readdirSync(projectsDir, { withFileTypes: true })
36
+ .filter((e) => e.isDirectory())
37
+ .map((e) => e.name);
38
+ for (const name of projects) {
39
+ const state = pipelineState(resolve(projectsDir, name));
40
+ const prev = previous.get(name);
41
+ if (!prev || prev.status !== state.status || prev.pid !== state.pid) {
42
+ eventBus.publish('pipeline.status', { project: name, ...state });
43
+ previous.set(name, state);
44
+ }
45
+ }
46
+ };
47
+ const id = setInterval(tick, intervalMs);
48
+ // 启动时跑一次,让 UI 得到初始值
49
+ tick();
50
+ return () => clearInterval(id);
51
+ }
52
+ //# sourceMappingURL=pipelinePoller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipelinePoller.js","sourceRoot":"","sources":["../../../src/console-server/watchers/pipelinePoller.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAO9C,SAAS,aAAa,CAAC,UAAkB;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACjE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC/D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;YAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC5E,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACrB,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACvC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACvC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,UAAU,GAAG,IAAI;IACtE,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE9C,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO;QACrC,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;aAC/D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;aAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;YACxD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;gBACpE,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;gBACjE,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,oBAAoB;IACpB,IAAI,EAAE,CAAC;IAEP,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;AACjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralai/sps-cli",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "SPS CLI — AI-driven development pipeline orchestrator",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",