@coralai/sps-cli 0.48.1 → 0.49.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 (147) hide show
  1. package/dist/console-assets/assets/{index-BR3iEolY.js → index-Co0H5e5_.js} +85 -85
  2. package/dist/console-assets/assets/{index-lsG7ZrzD.css → index-DNKOkgDj.css} +1 -1
  3. package/dist/console-assets/index.html +2 -2
  4. package/dist/console-server/routes/system.d.ts.map +1 -1
  5. package/dist/console-server/routes/system.js +30 -0
  6. package/dist/console-server/routes/system.js.map +1 -1
  7. package/package.json +4 -1
  8. package/dist/commands/cardMarkComplete.test.d.ts +0 -2
  9. package/dist/commands/cardMarkComplete.test.d.ts.map +0 -1
  10. package/dist/commands/cardMarkComplete.test.js +0 -142
  11. package/dist/commands/cardMarkComplete.test.js.map +0 -1
  12. package/dist/commands/cardMarkStarted.test.d.ts +0 -2
  13. package/dist/commands/cardMarkStarted.test.d.ts.map +0 -1
  14. package/dist/commands/cardMarkStarted.test.js +0 -98
  15. package/dist/commands/cardMarkStarted.test.js.map +0 -1
  16. package/dist/commands/projectInit.test.d.ts +0 -2
  17. package/dist/commands/projectInit.test.d.ts.map +0 -1
  18. package/dist/commands/projectInit.test.js +0 -126
  19. package/dist/commands/projectInit.test.js.map +0 -1
  20. package/dist/commands/tick-heartbeat.test.d.ts +0 -2
  21. package/dist/commands/tick-heartbeat.test.d.ts.map +0 -1
  22. package/dist/commands/tick-heartbeat.test.js +0 -89
  23. package/dist/commands/tick-heartbeat.test.js.map +0 -1
  24. package/dist/core/checklist.test.d.ts +0 -2
  25. package/dist/core/checklist.test.d.ts.map +0 -1
  26. package/dist/core/checklist.test.js +0 -74
  27. package/dist/core/checklist.test.js.map +0 -1
  28. package/dist/core/config.test.d.ts +0 -2
  29. package/dist/core/config.test.d.ts.map +0 -1
  30. package/dist/core/config.test.js +0 -352
  31. package/dist/core/config.test.js.map +0 -1
  32. package/dist/core/lock.test.d.ts +0 -2
  33. package/dist/core/lock.test.d.ts.map +0 -1
  34. package/dist/core/lock.test.js +0 -118
  35. package/dist/core/lock.test.js.map +0 -1
  36. package/dist/core/markerFile.test.d.ts +0 -2
  37. package/dist/core/markerFile.test.d.ts.map +0 -1
  38. package/dist/core/markerFile.test.js +0 -111
  39. package/dist/core/markerFile.test.js.map +0 -1
  40. package/dist/core/queue.test.d.ts +0 -2
  41. package/dist/core/queue.test.d.ts.map +0 -1
  42. package/dist/core/queue.test.js +0 -114
  43. package/dist/core/queue.test.js.map +0 -1
  44. package/dist/core/sessionCleanup.test.d.ts +0 -2
  45. package/dist/core/sessionCleanup.test.d.ts.map +0 -1
  46. package/dist/core/sessionCleanup.test.js +0 -158
  47. package/dist/core/sessionCleanup.test.js.map +0 -1
  48. package/dist/core/shellEnv.test.d.ts +0 -2
  49. package/dist/core/shellEnv.test.d.ts.map +0 -1
  50. package/dist/core/shellEnv.test.js +0 -116
  51. package/dist/core/shellEnv.test.js.map +0 -1
  52. package/dist/core/skillStore.test.d.ts +0 -2
  53. package/dist/core/skillStore.test.d.ts.map +0 -1
  54. package/dist/core/skillStore.test.js +0 -203
  55. package/dist/core/skillStore.test.js.map +0 -1
  56. package/dist/core/state.test.d.ts +0 -2
  57. package/dist/core/state.test.d.ts.map +0 -1
  58. package/dist/core/state.test.js +0 -336
  59. package/dist/core/state.test.js.map +0 -1
  60. package/dist/engines/CloseoutEngine.d.ts +0 -72
  61. package/dist/engines/CloseoutEngine.d.ts.map +0 -1
  62. package/dist/engines/CloseoutEngine.js +0 -648
  63. package/dist/engines/CloseoutEngine.js.map +0 -1
  64. package/dist/engines/EventHandler.test.d.ts +0 -2
  65. package/dist/engines/EventHandler.test.d.ts.map +0 -1
  66. package/dist/engines/EventHandler.test.js +0 -169
  67. package/dist/engines/EventHandler.test.js.map +0 -1
  68. package/dist/engines/ExecutionEngine.d.ts +0 -125
  69. package/dist/engines/ExecutionEngine.d.ts.map +0 -1
  70. package/dist/engines/ExecutionEngine.js +0 -766
  71. package/dist/engines/ExecutionEngine.js.map +0 -1
  72. package/dist/engines/MonitorEngine.test.d.ts +0 -2
  73. package/dist/engines/MonitorEngine.test.d.ts.map +0 -1
  74. package/dist/engines/MonitorEngine.test.js +0 -355
  75. package/dist/engines/MonitorEngine.test.js.map +0 -1
  76. package/dist/engines/engine-pipeline-adapter.test.d.ts +0 -17
  77. package/dist/engines/engine-pipeline-adapter.test.d.ts.map +0 -1
  78. package/dist/engines/engine-pipeline-adapter.test.js +0 -707
  79. package/dist/engines/engine-pipeline-adapter.test.js.map +0 -1
  80. package/dist/interfaces/HookProvider.d.ts +0 -9
  81. package/dist/interfaces/HookProvider.d.ts.map +0 -1
  82. package/dist/interfaces/HookProvider.js +0 -2
  83. package/dist/interfaces/HookProvider.js.map +0 -1
  84. package/dist/manager/completion-judge.test.d.ts +0 -17
  85. package/dist/manager/completion-judge.test.d.ts.map +0 -1
  86. package/dist/manager/completion-judge.test.js +0 -233
  87. package/dist/manager/completion-judge.test.js.map +0 -1
  88. package/dist/manager/integration-queue.d.ts +0 -71
  89. package/dist/manager/integration-queue.d.ts.map +0 -1
  90. package/dist/manager/integration-queue.js +0 -137
  91. package/dist/manager/integration-queue.js.map +0 -1
  92. package/dist/manager/integration-queue.test.d.ts +0 -17
  93. package/dist/manager/integration-queue.test.d.ts.map +0 -1
  94. package/dist/manager/integration-queue.test.js +0 -210
  95. package/dist/manager/integration-queue.test.js.map +0 -1
  96. package/dist/manager/pm-client.d.ts +0 -10
  97. package/dist/manager/pm-client.d.ts.map +0 -1
  98. package/dist/manager/pm-client.js +0 -260
  99. package/dist/manager/pm-client.js.map +0 -1
  100. package/dist/manager/resource-limiter.d.ts +0 -56
  101. package/dist/manager/resource-limiter.d.ts.map +0 -1
  102. package/dist/manager/resource-limiter.js +0 -116
  103. package/dist/manager/resource-limiter.js.map +0 -1
  104. package/dist/manager/resource-limiter.test.d.ts +0 -17
  105. package/dist/manager/resource-limiter.test.d.ts.map +0 -1
  106. package/dist/manager/resource-limiter.test.js +0 -118
  107. package/dist/manager/resource-limiter.test.js.map +0 -1
  108. package/dist/manager/supervisor.test.d.ts +0 -17
  109. package/dist/manager/supervisor.test.d.ts.map +0 -1
  110. package/dist/manager/supervisor.test.js +0 -216
  111. package/dist/manager/supervisor.test.js.map +0 -1
  112. package/dist/manager/worker-manager-impl.test.d.ts +0 -17
  113. package/dist/manager/worker-manager-impl.test.d.ts.map +0 -1
  114. package/dist/manager/worker-manager-impl.test.js +0 -446
  115. package/dist/manager/worker-manager-impl.test.js.map +0 -1
  116. package/dist/providers/PlaneTaskBackend.d.ts +0 -83
  117. package/dist/providers/PlaneTaskBackend.d.ts.map +0 -1
  118. package/dist/providers/PlaneTaskBackend.js +0 -461
  119. package/dist/providers/PlaneTaskBackend.js.map +0 -1
  120. package/dist/providers/TrelloTaskBackend.d.ts +0 -64
  121. package/dist/providers/TrelloTaskBackend.d.ts.map +0 -1
  122. package/dist/providers/TrelloTaskBackend.js +0 -298
  123. package/dist/providers/TrelloTaskBackend.js.map +0 -1
  124. package/dist/providers/adapters/acp-fs-handlers.test.d.ts +0 -2
  125. package/dist/providers/adapters/acp-fs-handlers.test.d.ts.map +0 -1
  126. package/dist/providers/adapters/acp-fs-handlers.test.js +0 -80
  127. package/dist/providers/adapters/acp-fs-handlers.test.js.map +0 -1
  128. package/dist/providers/adapters/acp-permissions.test.d.ts +0 -2
  129. package/dist/providers/adapters/acp-permissions.test.d.ts.map +0 -1
  130. package/dist/providers/adapters/acp-permissions.test.js +0 -103
  131. package/dist/providers/adapters/acp-permissions.test.js.map +0 -1
  132. package/dist/providers/adapters/acp-session-accumulator.test.d.ts +0 -2
  133. package/dist/providers/adapters/acp-session-accumulator.test.d.ts.map +0 -1
  134. package/dist/providers/adapters/acp-session-accumulator.test.js +0 -88
  135. package/dist/providers/adapters/acp-session-accumulator.test.js.map +0 -1
  136. package/dist/providers/adapters/acp-terminal-manager.test.d.ts +0 -2
  137. package/dist/providers/adapters/acp-terminal-manager.test.d.ts.map +0 -1
  138. package/dist/providers/adapters/acp-terminal-manager.test.js +0 -86
  139. package/dist/providers/adapters/acp-terminal-manager.test.js.map +0 -1
  140. package/dist/providers/outputParser.test.d.ts +0 -2
  141. package/dist/providers/outputParser.test.d.ts.map +0 -1
  142. package/dist/providers/outputParser.test.js +0 -185
  143. package/dist/providers/outputParser.test.js.map +0 -1
  144. package/dist/test-setup.d.ts +0 -2
  145. package/dist/test-setup.d.ts.map +0 -1
  146. package/dist/test-setup.js +0 -27
  147. package/dist/test-setup.js.map +0 -1
@@ -1,352 +0,0 @@
1
- /**
2
- * @module config.test
3
- * @description 项目配置加载与校验的单元测试
4
- *
5
- * @author eddy
6
- * @organization wykj
7
- * @ownership wykj/eddy
8
- *
9
- * @created 2026-03-29
10
- * @updated 2026-04-03
11
- *
12
- * @role test
13
- * @layer core
14
- * @boundedContext configuration
15
- */
16
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
17
- import { tmpdir } from 'node:os';
18
- import { join } from 'node:path';
19
- import { afterEach, beforeEach, describe, expect, it, } from 'vitest';
20
- import { loadGlobalEnv, loadProjectConf, validateConfig } from './config.js';
21
- // ─── Helpers ──────────────────────────────────────────────────────
22
- function makeConfig(overrides) {
23
- return {
24
- PROJECT_NAME: 'test-project',
25
- GITLAB_PROJECT: 'group/test-project',
26
- GITLAB_PROJECT_ID: '42',
27
- GITLAB_MERGE_BRANCH: 'develop',
28
- PM_TOOL: 'markdown',
29
- MR_MODE: 'none',
30
- WORKER_TRANSPORT: 'acp-sdk',
31
- MAX_CONCURRENT_WORKERS: 3,
32
- WORKER_RESTART_LIMIT: 2,
33
- MAX_ACTIONS_PER_TICK: 1,
34
- WORKER_LAUNCH_TIMEOUT_S: 120,
35
- WORKER_IDLE_TIMEOUT_M: 15,
36
- INPROGRESS_TIMEOUT_HOURS: 8,
37
- MONITOR_AUTO_QA: false,
38
- CONFLICT_DEFAULT: 'serial',
39
- TICK_LOCK_TIMEOUT_MINUTES: 30,
40
- WORKER_ACK_TIMEOUT_S: 60,
41
- WORKER_ACK_MAX_RETRIES: 1,
42
- raw: {},
43
- ...overrides,
44
- };
45
- }
46
- // ─── Tests ────────────────────────────────────────────────────────
47
- describe('validateConfig', () => {
48
- it('returns no errors for a complete config', () => {
49
- const config = makeConfig();
50
- const errors = validateConfig(config);
51
- expect(errors).toEqual([]);
52
- });
53
- it('reports missing PROJECT_NAME', () => {
54
- const config = makeConfig({ PROJECT_NAME: '' });
55
- const errors = validateConfig(config);
56
- expect(errors).toHaveLength(1);
57
- expect(errors[0].field).toBe('PROJECT_NAME');
58
- });
59
- it('reports missing GITLAB_PROJECT', () => {
60
- const config = makeConfig({ GITLAB_PROJECT: '' });
61
- const errors = validateConfig(config);
62
- expect(errors).toHaveLength(1);
63
- expect(errors[0].field).toBe('GITLAB_PROJECT');
64
- });
65
- it('reports missing GITLAB_MERGE_BRANCH', () => {
66
- const config = makeConfig({ GITLAB_MERGE_BRANCH: '' });
67
- const errors = validateConfig(config);
68
- expect(errors).toHaveLength(1);
69
- expect(errors[0].field).toBe('GITLAB_MERGE_BRANCH');
70
- });
71
- it('reports multiple missing fields', () => {
72
- const config = makeConfig({
73
- PROJECT_NAME: '',
74
- GITLAB_PROJECT: '',
75
- GITLAB_MERGE_BRANCH: '',
76
- });
77
- const errors = validateConfig(config);
78
- expect(errors).toHaveLength(3);
79
- const fields = errors.map(e => e.field);
80
- expect(fields).toContain('PROJECT_NAME');
81
- expect(fields).toContain('GITLAB_PROJECT');
82
- expect(fields).toContain('GITLAB_MERGE_BRANCH');
83
- });
84
- it('does not require optional fields like GITLAB_PROJECT_ID', () => {
85
- const config = makeConfig({ GITLAB_PROJECT_ID: '' });
86
- const errors = validateConfig(config);
87
- expect(errors).toEqual([]);
88
- });
89
- });
90
- describe('resolveWorkflowTransport', () => {
91
- it('defaults to acp-sdk when no WORKER_TRANSPORT set', async () => {
92
- const { resolveWorkflowTransport } = await import('./config.js');
93
- const config = makeConfig();
94
- expect(resolveWorkflowTransport(config)).toBe('acp-sdk');
95
- });
96
- it('maps acp to acp-sdk', async () => {
97
- const { resolveWorkflowTransport } = await import('./config.js');
98
- const config = makeConfig({ raw: { WORKER_TRANSPORT: 'acp' } });
99
- expect(resolveWorkflowTransport(config)).toBe('acp-sdk');
100
- });
101
- it('always returns acp-sdk regardless of config', async () => {
102
- const { resolveWorkflowTransport } = await import('./config.js');
103
- const config = makeConfig({ raw: { WORKER_TRANSPORT: 'unknown' } });
104
- expect(resolveWorkflowTransport(config)).toBe('acp-sdk');
105
- });
106
- });
107
- describe('loadProjectConf', () => {
108
- let fakeHome;
109
- let originalHome;
110
- beforeEach(() => {
111
- fakeHome = mkdtempSync(join(tmpdir(), 'sps-config-test-'));
112
- originalHome = process.env.HOME;
113
- process.env.HOME = fakeHome;
114
- });
115
- afterEach(() => {
116
- process.env.HOME = originalHome;
117
- rmSync(fakeHome, { recursive: true, force: true });
118
- });
119
- function writeConf(projectName, content) {
120
- const confDir = join(fakeHome, '.coral', 'projects', projectName);
121
- mkdirSync(confDir, { recursive: true });
122
- writeFileSync(join(confDir, 'conf'), content);
123
- }
124
- function writeGlobalEnv(content) {
125
- const envDir = join(fakeHome, '.coral');
126
- mkdirSync(envDir, { recursive: true });
127
- writeFileSync(join(envDir, 'env'), content);
128
- }
129
- it('throws when conf file does not exist', () => {
130
- expect(() => loadProjectConf('nonexistent')).toThrow('Project conf not found');
131
- });
132
- it('parses simple KEY=value assignments', () => {
133
- writeConf('myapp', [
134
- 'PROJECT_NAME=myapp',
135
- 'GITLAB_PROJECT=group/myapp',
136
- 'GITLAB_MERGE_BRANCH=develop',
137
- ].join('\n'));
138
- const config = loadProjectConf('myapp');
139
- expect(config.PROJECT_NAME).toBe('myapp');
140
- expect(config.GITLAB_PROJECT).toBe('group/myapp');
141
- expect(config.GITLAB_MERGE_BRANCH).toBe('develop');
142
- });
143
- it('parses export KEY="value" syntax', () => {
144
- writeConf('quoted', [
145
- 'export PROJECT_NAME="my-project"',
146
- 'export GITLAB_PROJECT="ns/repo"',
147
- 'export GITLAB_MERGE_BRANCH="main"',
148
- ].join('\n'));
149
- const config = loadProjectConf('quoted');
150
- expect(config.PROJECT_NAME).toBe('my-project');
151
- expect(config.GITLAB_PROJECT).toBe('ns/repo');
152
- });
153
- it('skips comments and blank lines', () => {
154
- writeConf('comments', [
155
- '# This is a comment',
156
- '',
157
- 'PROJECT_NAME=test',
158
- '# Another comment',
159
- 'GITLAB_PROJECT=g/t',
160
- 'GITLAB_MERGE_BRANCH=main',
161
- ].join('\n'));
162
- const config = loadProjectConf('comments');
163
- expect(config.PROJECT_NAME).toBe('test');
164
- });
165
- it('applies default values for missing fields', () => {
166
- writeConf('minimal', [
167
- 'PROJECT_NAME=min',
168
- 'GITLAB_PROJECT=g/min',
169
- 'GITLAB_MERGE_BRANCH=develop',
170
- ].join('\n'));
171
- const config = loadProjectConf('minimal');
172
- expect(config.WORKER_TRANSPORT).toBe('acp-sdk');
173
- expect(config.MAX_CONCURRENT_WORKERS).toBe(3);
174
- expect(config.WORKER_RESTART_LIMIT).toBe(2);
175
- expect(config.MR_MODE).toBe('none');
176
- expect(config.PM_TOOL).toBe('markdown');
177
- expect(config.CONFLICT_DEFAULT).toBe('serial');
178
- expect(config.MONITOR_AUTO_QA).toBe(false);
179
- });
180
- it('parses numeric fields correctly', () => {
181
- writeConf('nums', [
182
- 'PROJECT_NAME=nums',
183
- 'GITLAB_PROJECT=g/nums',
184
- 'GITLAB_MERGE_BRANCH=main',
185
- 'MAX_CONCURRENT_WORKERS=10',
186
- 'WORKER_RESTART_LIMIT=5',
187
- 'MAX_ACTIONS_PER_TICK=3',
188
- 'WORKER_LAUNCH_TIMEOUT_S=300',
189
- 'WORKER_IDLE_TIMEOUT_M=30',
190
- 'INPROGRESS_TIMEOUT_HOURS=24',
191
- ].join('\n'));
192
- const config = loadProjectConf('nums');
193
- expect(config.MAX_CONCURRENT_WORKERS).toBe(10);
194
- expect(config.WORKER_RESTART_LIMIT).toBe(5);
195
- expect(config.MAX_ACTIONS_PER_TICK).toBe(3);
196
- expect(config.WORKER_LAUNCH_TIMEOUT_S).toBe(300);
197
- expect(config.WORKER_IDLE_TIMEOUT_M).toBe(30);
198
- expect(config.INPROGRESS_TIMEOUT_HOURS).toBe(24);
199
- });
200
- it('parses boolean fields correctly', () => {
201
- writeConf('bools', [
202
- 'PROJECT_NAME=bools',
203
- 'GITLAB_PROJECT=g/bools',
204
- 'GITLAB_MERGE_BRANCH=main',
205
- 'MONITOR_AUTO_QA=true',
206
- ].join('\n'));
207
- const config = loadProjectConf('bools');
208
- expect(config.MONITOR_AUTO_QA).toBe(true);
209
- });
210
- it('strips __PLACEHOLDER__ values', () => {
211
- writeConf('placeholders', [
212
- 'PROJECT_NAME=ph',
213
- 'GITLAB_PROJECT=g/ph',
214
- 'GITLAB_MERGE_BRANCH=main',
215
- 'GITLAB_PROJECT_ID=__PROJECT_ID__',
216
- ].join('\n'));
217
- const config = loadProjectConf('placeholders');
218
- expect(config.GITLAB_PROJECT_ID).toBe('');
219
- });
220
- it('uses project name as fallback for PROJECT_NAME', () => {
221
- writeConf('fallback', [
222
- 'GITLAB_PROJECT=g/fb',
223
- 'GITLAB_MERGE_BRANCH=main',
224
- ].join('\n'));
225
- const config = loadProjectConf('fallback');
226
- expect(config.PROJECT_NAME).toBe('fallback');
227
- });
228
- it('merges global env with project conf', () => {
229
- writeGlobalEnv([
230
- 'GITLAB_URL=https://git.example.com',
231
- 'GITLAB_TOKEN=secret-token',
232
- ].join('\n'));
233
- writeConf('merged', [
234
- 'PROJECT_NAME=merged',
235
- 'GITLAB_PROJECT=g/merged',
236
- 'GITLAB_MERGE_BRANCH=main',
237
- ].join('\n'));
238
- const config = loadProjectConf('merged');
239
- expect(config.raw.GITLAB_URL).toBe('https://git.example.com');
240
- expect(config.raw.GITLAB_TOKEN).toBe('secret-token');
241
- });
242
- it('forces PM_TOOL to "markdown" regardless of legacy conf value (v0.42+)', () => {
243
- // v0.42.0 removed Plane/Trello. Legacy conf files with PM_TOOL=plane/trello
244
- // still load, but the effective value is always 'markdown'. This ensures
245
- // smooth upgrade path for configs left over from v0.41.x and earlier.
246
- for (const tool of ['plane', 'trello', 'markdown']) {
247
- writeConf(`pm-${tool}`, [
248
- 'PROJECT_NAME=test',
249
- 'GITLAB_PROJECT=g/test',
250
- 'GITLAB_MERGE_BRANCH=main',
251
- `PM_TOOL=${tool}`,
252
- ].join('\n'));
253
- const config = loadProjectConf(`pm-${tool}`);
254
- expect(config.PM_TOOL).toBe('markdown');
255
- }
256
- });
257
- it('silently ignores deprecated WORKER_TOOL without failing', () => {
258
- // WORKER_TOOL was removed in v0.38.0 (claude-only). Legacy configs must
259
- // still load without errors; the field is simply dropped.
260
- writeConf('legacy-wt', [
261
- 'PROJECT_NAME=test',
262
- 'GITLAB_PROJECT=g/test',
263
- 'GITLAB_MERGE_BRANCH=main',
264
- 'WORKER_TOOL=codex',
265
- ].join('\n'));
266
- const config = loadProjectConf('legacy-wt');
267
- expect(config.PROJECT_NAME).toBe('test');
268
- });
269
- it('handles shell variable interpolation via bash sourcing', () => {
270
- writeGlobalEnv('PLANE_URL=https://plane.example.com');
271
- writeConf('interp', [
272
- 'PROJECT_NAME=interp',
273
- 'GITLAB_PROJECT=g/interp',
274
- 'GITLAB_MERGE_BRANCH=main',
275
- 'PLANE_API_URL="${PLANE_URL}/api/v1"',
276
- ].join('\n'));
277
- const config = loadProjectConf('interp');
278
- // bash sourcing should interpolate ${PLANE_URL}
279
- expect(config.raw.PLANE_API_URL).toBe('https://plane.example.com/api/v1');
280
- });
281
- it('loads conf without global env file', () => {
282
- // No writeGlobalEnv — ~/.coral/env does not exist
283
- writeConf('no-env', [
284
- 'PROJECT_NAME=no-env',
285
- 'GITLAB_PROJECT=g/no-env',
286
- 'GITLAB_MERGE_BRANCH=main',
287
- ].join('\n'));
288
- const config = loadProjectConf('no-env');
289
- expect(config.PROJECT_NAME).toBe('no-env');
290
- });
291
- it('parses single-quoted values', () => {
292
- writeConf('sq', [
293
- "PROJECT_NAME='single-quoted'",
294
- "GITLAB_PROJECT='g/sq'",
295
- "GITLAB_MERGE_BRANCH='develop'",
296
- ].join('\n'));
297
- const config = loadProjectConf('sq');
298
- expect(config.PROJECT_NAME).toBe('single-quoted');
299
- });
300
- it('parses all MR_MODE variants', () => {
301
- for (const mr of ['none', 'create']) {
302
- writeConf(`mr-${mr}`, [
303
- 'PROJECT_NAME=test',
304
- 'GITLAB_PROJECT=g/test',
305
- 'GITLAB_MERGE_BRANCH=main',
306
- `MR_MODE=${mr}`,
307
- ].join('\n'));
308
- expect(loadProjectConf(`mr-${mr}`).MR_MODE).toBe(mr);
309
- }
310
- });
311
- it('exposes raw config for PM-specific fields', () => {
312
- writeConf('raw', [
313
- 'PROJECT_NAME=raw',
314
- 'GITLAB_PROJECT=g/raw',
315
- 'GITLAB_MERGE_BRANCH=main',
316
- 'TRELLO_BOARD_ID=abc123',
317
- 'PLANE_STATE_PLANNING=uuid-1',
318
- ].join('\n'));
319
- const config = loadProjectConf('raw');
320
- expect(config.raw.TRELLO_BOARD_ID).toBe('abc123');
321
- expect(config.raw.PLANE_STATE_PLANNING).toBe('uuid-1');
322
- });
323
- });
324
- describe('loadGlobalEnv', () => {
325
- let fakeHome;
326
- let originalHome;
327
- beforeEach(() => {
328
- fakeHome = mkdtempSync(join(tmpdir(), 'sps-env-test-'));
329
- originalHome = process.env.HOME;
330
- process.env.HOME = fakeHome;
331
- });
332
- afterEach(() => {
333
- process.env.HOME = originalHome;
334
- rmSync(fakeHome, { recursive: true, force: true });
335
- });
336
- it('returns empty object when env file does not exist', () => {
337
- const env = loadGlobalEnv();
338
- expect(env).toEqual({});
339
- });
340
- it('loads variables from ~/.coral/env', () => {
341
- const envDir = join(fakeHome, '.coral');
342
- mkdirSync(envDir, { recursive: true });
343
- writeFileSync(join(envDir, 'env'), [
344
- 'GITLAB_URL=https://git.test.com',
345
- 'PLANE_API_KEY=pk-123',
346
- ].join('\n'));
347
- const env = loadGlobalEnv();
348
- expect(env.GITLAB_URL).toBe('https://git.test.com');
349
- expect(env.PLANE_API_KEY).toBe('pk-123');
350
- });
351
- });
352
- //# sourceMappingURL=config.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/core/config.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=lock.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.test.d.ts","sourceRoot":"","sources":["../../src/core/lock.test.ts"],"names":[],"mappings":""}
@@ -1,118 +0,0 @@
1
- /**
2
- * @module lock.test
3
- * @description Tick 锁获取与释放的单元测试
4
- *
5
- * @author eddy
6
- * @organization wykj
7
- * @ownership wykj/eddy
8
- *
9
- * @created 2026-03-29
10
- * @updated 2026-04-03
11
- *
12
- * @role test
13
- * @layer core
14
- * @boundedContext concurrency
15
- */
16
- import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
17
- import { tmpdir } from 'node:os';
18
- import { join } from 'node:path';
19
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
20
- import { acquireTickLock, releaseTickLock } from './lock.js';
21
- function makeTempDir() {
22
- return mkdtempSync(join(tmpdir(), 'sps-lock-test-'));
23
- }
24
- describe('acquireTickLock', () => {
25
- let tempDir;
26
- beforeEach(() => { tempDir = makeTempDir(); });
27
- afterEach(() => { rmSync(tempDir, { recursive: true, force: true }); });
28
- it('acquires lock when no lock file exists (reason undefined)', () => {
29
- const lockFile = join(tempDir, 'tick.lock');
30
- const result = acquireTickLock(lockFile, 30);
31
- expect(result.acquired).toBe(true);
32
- expect(result.reason).toBeUndefined();
33
- expect(existsSync(lockFile)).toBe(true);
34
- const content = JSON.parse(readFileSync(lockFile, 'utf-8'));
35
- expect(content.pid).toBe(process.pid);
36
- expect(content.startedAt).toBeDefined();
37
- });
38
- it('rejects when another live process holds the lock', () => {
39
- const lockFile = join(tempDir, 'tick.lock');
40
- // Write a lock with current PID (which is alive)
41
- writeFileSync(lockFile, JSON.stringify({
42
- pid: process.pid,
43
- startedAt: new Date().toISOString(),
44
- }) + '\n');
45
- const result = acquireTickLock(lockFile, 30);
46
- expect(result.acquired).toBe(false);
47
- expect(result.reason).toBe('another_tick_running');
48
- });
49
- it('reclaims lock when PID is dead (reason stale_lock_reclaimed)', () => {
50
- const lockFile = join(tempDir, 'tick.lock');
51
- writeFileSync(lockFile, JSON.stringify({
52
- pid: 4_000_000,
53
- startedAt: new Date().toISOString(),
54
- }) + '\n');
55
- const result = acquireTickLock(lockFile, 30);
56
- expect(result.acquired).toBe(true);
57
- expect(result.reason).toBe('stale_lock_reclaimed');
58
- const content = JSON.parse(readFileSync(lockFile, 'utf-8'));
59
- expect(content.pid).toBe(process.pid);
60
- });
61
- it('reclaims lock when timed out even if PID is alive', () => {
62
- const lockFile = join(tempDir, 'tick.lock');
63
- // Write a lock from current process but started 60 minutes ago
64
- const pastTime = new Date(Date.now() - 60 * 60 * 1000).toISOString();
65
- writeFileSync(lockFile, JSON.stringify({
66
- pid: process.pid,
67
- startedAt: pastTime,
68
- }) + '\n');
69
- const result = acquireTickLock(lockFile, 30); // 30 min timeout, 60 min elapsed
70
- expect(result.acquired).toBe(true);
71
- });
72
- it('does not reclaim when within timeout', () => {
73
- const lockFile = join(tempDir, 'tick.lock');
74
- // Write lock from current process, started just now
75
- writeFileSync(lockFile, JSON.stringify({
76
- pid: process.pid,
77
- startedAt: new Date().toISOString(),
78
- }) + '\n');
79
- const result = acquireTickLock(lockFile, 30);
80
- expect(result.acquired).toBe(false);
81
- });
82
- it('handles corrupt lock file', () => {
83
- const lockFile = join(tempDir, 'tick.lock');
84
- writeFileSync(lockFile, 'NOT VALID JSON\n');
85
- const result = acquireTickLock(lockFile, 30);
86
- expect(result.acquired).toBe(true);
87
- });
88
- it('creates parent directories if needed', () => {
89
- const lockFile = join(tempDir, 'deep', 'nested', 'tick.lock');
90
- const result = acquireTickLock(lockFile, 30);
91
- expect(result.acquired).toBe(true);
92
- expect(existsSync(lockFile)).toBe(true);
93
- });
94
- });
95
- describe('releaseTickLock', () => {
96
- let tempDir;
97
- beforeEach(() => { tempDir = makeTempDir(); });
98
- afterEach(() => { rmSync(tempDir, { recursive: true, force: true }); });
99
- it('removes the lock file', () => {
100
- const lockFile = join(tempDir, 'tick.lock');
101
- acquireTickLock(lockFile, 30);
102
- expect(existsSync(lockFile)).toBe(true);
103
- releaseTickLock(lockFile);
104
- expect(existsSync(lockFile)).toBe(false);
105
- });
106
- it('does nothing when lock file does not exist', () => {
107
- const lockFile = join(tempDir, 'nonexistent.lock');
108
- expect(() => releaseTickLock(lockFile)).not.toThrow();
109
- });
110
- it('acquire then release then re-acquire works', () => {
111
- const lockFile = join(tempDir, 'tick.lock');
112
- acquireTickLock(lockFile, 30);
113
- releaseTickLock(lockFile);
114
- const result = acquireTickLock(lockFile, 30);
115
- expect(result.acquired).toBe(true);
116
- });
117
- });
118
- //# sourceMappingURL=lock.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.test.js","sourceRoot":"","sources":["../../src/core/lock.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=markerFile.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"markerFile.test.d.ts","sourceRoot":"","sources":["../../src/core/markerFile.test.ts"],"names":[],"mappings":""}
@@ -1,111 +0,0 @@
1
- /**
2
- * @module markerFile.test
3
- * @description marker 文件读/写/合并工具单元测试
4
- */
5
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
6
- import { tmpdir } from 'node:os';
7
- import { join, resolve } from 'node:path';
8
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
9
- import { getMarkerPath, getMarkerPathFromStateFile, patchCurrentCardFile, readCurrentCardMarker, writeCurrentCardFile, } from './markerFile.js';
10
- describe('markerFile', () => {
11
- const originalHome = process.env.HOME;
12
- let tmpHome;
13
- beforeEach(() => {
14
- tmpHome = mkdtempSync(join(tmpdir(), 'marker-test-'));
15
- mkdirSync(join(tmpHome, '.coral', 'projects', 'p', 'runtime'), { recursive: true });
16
- process.env.HOME = tmpHome;
17
- });
18
- afterEach(() => {
19
- rmSync(tmpHome, { recursive: true, force: true });
20
- if (originalHome !== undefined)
21
- process.env.HOME = originalHome;
22
- else
23
- delete process.env.HOME;
24
- });
25
- describe('writeCurrentCardFile', () => {
26
- it('writes cardId/stage/dispatchedAt atomically', () => {
27
- const path = getMarkerPath('p', 'worker-1');
28
- writeCurrentCardFile(path, '42', 'develop');
29
- expect(existsSync(path)).toBe(true);
30
- const contents = JSON.parse(readFileSync(path, 'utf-8'));
31
- expect(contents.cardId).toBe('42');
32
- expect(contents.stage).toBe('develop');
33
- expect(contents.dispatchedAt).toBeDefined();
34
- });
35
- it('includes sessionId and pid when passed in extra', () => {
36
- const path = getMarkerPath('p', 'worker-1');
37
- writeCurrentCardFile(path, '42', 'develop', undefined, { sessionId: 'sess-1', pid: 1234 });
38
- const contents = JSON.parse(readFileSync(path, 'utf-8'));
39
- expect(contents.sessionId).toBe('sess-1');
40
- expect(contents.pid).toBe(1234);
41
- });
42
- it('overwrites existing marker on subsequent call', () => {
43
- const path = getMarkerPath('p', 'worker-1');
44
- writeCurrentCardFile(path, '1', 'develop');
45
- writeCurrentCardFile(path, '2', 'develop');
46
- const contents = JSON.parse(readFileSync(path, 'utf-8'));
47
- expect(contents.cardId).toBe('2');
48
- });
49
- });
50
- describe('patchCurrentCardFile', () => {
51
- it('preserves existing fields and adds sessionId + pid', () => {
52
- const path = getMarkerPath('p', 'worker-1');
53
- writeCurrentCardFile(path, '42', 'develop');
54
- const originalAt = JSON.parse(readFileSync(path, 'utf-8')).dispatchedAt;
55
- patchCurrentCardFile(path, { sessionId: 'sess-abc', pid: 99999 });
56
- const contents = JSON.parse(readFileSync(path, 'utf-8'));
57
- expect(contents.cardId).toBe('42'); // unchanged
58
- expect(contents.stage).toBe('develop'); // unchanged
59
- expect(contents.dispatchedAt).toBe(originalAt); // NOT reset — ACK timeout clock preserved
60
- expect(contents.sessionId).toBe('sess-abc'); // new
61
- expect(contents.pid).toBe(99999); // new
62
- });
63
- it('is a no-op with onError callback when marker file missing', () => {
64
- const path = getMarkerPath('p', 'worker-ghost');
65
- let errorCaught = null;
66
- patchCurrentCardFile(path, { sessionId: 'x' }, (err) => { errorCaught = err; });
67
- expect(errorCaught).toBeTruthy();
68
- expect(existsSync(path)).toBe(false); // did not create
69
- });
70
- });
71
- describe('readCurrentCardMarker', () => {
72
- it('returns null when file missing', () => {
73
- expect(readCurrentCardMarker('p', 'worker-ghost')).toBeNull();
74
- });
75
- it('reads cardId/stage/dispatchedAt', () => {
76
- const path = getMarkerPath('p', 'worker-1');
77
- writeCurrentCardFile(path, '42', 'review');
78
- const marker = readCurrentCardMarker('p', 'worker-1');
79
- expect(marker?.cardId).toBe('42');
80
- expect(marker?.stage).toBe('review');
81
- });
82
- it('reads sessionId/pid when present (new format)', () => {
83
- const path = getMarkerPath('p', 'worker-1');
84
- writeFileSync(path, JSON.stringify({
85
- cardId: '7', stage: 'develop', dispatchedAt: '2026-04-20T00:00:00Z',
86
- sessionId: 'sess-x', pid: 42,
87
- }));
88
- const marker = readCurrentCardMarker('p', 'worker-1');
89
- expect(marker?.sessionId).toBe('sess-x');
90
- expect(marker?.pid).toBe(42);
91
- });
92
- it('is backward-compatible with old markers (no sessionId/pid)', () => {
93
- const path = getMarkerPath('p', 'worker-1');
94
- writeFileSync(path, JSON.stringify({
95
- cardId: '7', stage: 'develop', dispatchedAt: '2026-04-20T00:00:00Z',
96
- }));
97
- const marker = readCurrentCardMarker('p', 'worker-1');
98
- expect(marker?.cardId).toBe('7');
99
- expect(marker?.sessionId).toBeUndefined();
100
- expect(marker?.pid).toBeUndefined();
101
- });
102
- });
103
- describe('getMarkerPathFromStateFile', () => {
104
- it('builds path in the same directory as state.json', () => {
105
- const stateFile = '/tmp/sps/runtime/state.json';
106
- const markerPath = getMarkerPathFromStateFile(stateFile, 'worker-1');
107
- expect(markerPath).toBe(resolve('/tmp/sps/runtime/worker-worker-1-current.json'));
108
- });
109
- });
110
- });
111
- //# sourceMappingURL=markerFile.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"markerFile.test.js","sourceRoot":"","sources":["../../src/core/markerFile.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=queue.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"queue.test.d.ts","sourceRoot":"","sources":["../../src/core/queue.test.ts"],"names":[],"mappings":""}