@agimon-ai/po 0.0.0-alpha.35 → 0.0.0-alpha.36

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 (36) hide show
  1. package/dist/catalog/index.json +55 -55
  2. package/dist/src/builders/server/backgroundSync.cjs +4 -1
  3. package/dist/src/builders/server/backgroundSync.cjs.map +1 -1
  4. package/dist/src/builders/server/backgroundSync.mjs +4 -1
  5. package/dist/src/builders/server/backgroundSync.mjs.map +1 -1
  6. package/dist/src/builders/server/runtime.cjs +177 -60
  7. package/dist/src/builders/server/runtime.cjs.map +1 -1
  8. package/dist/src/builders/server/runtime.mjs +177 -61
  9. package/dist/src/builders/server/runtime.mjs.map +1 -1
  10. package/dist/src/builders/server/shutdown.cjs +23 -0
  11. package/dist/src/builders/server/shutdown.cjs.map +1 -1
  12. package/dist/src/builders/server/shutdown.mjs +21 -1
  13. package/dist/src/builders/server/shutdown.mjs.map +1 -1
  14. package/dist/src/builders/server/workspaceCheckout.cjs +4 -1
  15. package/dist/src/builders/server/workspaceCheckout.cjs.map +1 -1
  16. package/dist/src/builders/server/workspaceCheckout.mjs +4 -1
  17. package/dist/src/builders/server/workspaceCheckout.mjs.map +1 -1
  18. package/dist/src/cli/commands/sync/help.cjs +2 -1
  19. package/dist/src/cli/commands/sync/help.cjs.map +1 -1
  20. package/dist/src/cli/commands/sync/help.mjs +2 -1
  21. package/dist/src/cli/commands/sync/help.mjs.map +1 -1
  22. package/dist/src/cli/commands/sync/index.cjs +7 -3
  23. package/dist/src/cli/commands/sync/index.cjs.map +1 -1
  24. package/dist/src/cli/commands/sync/index.d.mts.map +1 -1
  25. package/dist/src/cli/commands/sync/index.mjs +7 -3
  26. package/dist/src/cli/commands/sync/index.mjs.map +1 -1
  27. package/dist/src/cli/server/options.cjs +18 -2
  28. package/dist/src/cli/server/options.cjs.map +1 -1
  29. package/dist/src/cli/server/options.mjs +18 -2
  30. package/dist/src/cli/server/options.mjs.map +1 -1
  31. package/dist/src/composition/syncService/index.cjs +26 -10
  32. package/dist/src/composition/syncService/index.cjs.map +1 -1
  33. package/dist/src/composition/syncService/index.d.mts.map +1 -1
  34. package/dist/src/composition/syncService/index.mjs +27 -11
  35. package/dist/src/composition/syncService/index.mjs.map +1 -1
  36. package/package.json +20 -20
@@ -2,7 +2,7 @@
2
2
  "version": 1,
3
3
  "packages": {
4
4
  "@agimon-ai/po": {
5
- "version": "0.0.0-alpha.35",
5
+ "version": "0.0.0-alpha.36",
6
6
  "dependencies": [
7
7
  "@agimon-ai/po-artifact",
8
8
  "@agimon-ai/po-autostop",
@@ -23,7 +23,7 @@
23
23
  ]
24
24
  },
25
25
  "@agimon-ai/po-artifact": {
26
- "version": "0.0.0-alpha.33",
26
+ "version": "0.0.0-alpha.34",
27
27
  "dependencies": [
28
28
  "@agimon-ai/po-core",
29
29
  "@agimon-ai/po-web-components",
@@ -31,7 +31,7 @@
31
31
  ]
32
32
  },
33
33
  "@agimon-ai/po-author": {
34
- "version": "0.0.0-alpha.34",
34
+ "version": "0.0.0-alpha.35",
35
35
  "dependencies": [
36
36
  "@agimon-ai/po-artifact",
37
37
  "@agimon-ai/po-core",
@@ -41,7 +41,7 @@
41
41
  ]
42
42
  },
43
43
  "@agimon-ai/po-autocompact": {
44
- "version": "0.0.0-alpha.34",
44
+ "version": "0.0.0-alpha.35",
45
45
  "dependencies": [
46
46
  "@agimon-ai/po-artifact",
47
47
  "@agimon-ai/po-config",
@@ -49,24 +49,24 @@
49
49
  ]
50
50
  },
51
51
  "@agimon-ai/po-autostop": {
52
- "version": "0.0.0-alpha.34",
52
+ "version": "0.0.0-alpha.35",
53
53
  "dependencies": [
54
54
  "@agimon-ai/po-core"
55
55
  ]
56
56
  },
57
57
  "@agimon-ai/po-browse": {
58
- "version": "0.0.1-alpha.32",
58
+ "version": "0.0.1-alpha.33",
59
59
  "dependencies": [
60
60
  "@agimon-ai/po-core",
61
61
  "@agimon-ai/po-web-components"
62
62
  ]
63
63
  },
64
64
  "@agimon-ai/po-build": {
65
- "version": "0.0.0-alpha.34",
65
+ "version": "0.0.0-alpha.35",
66
66
  "dependencies": []
67
67
  },
68
68
  "@agimon-ai/po-cache": {
69
- "version": "0.0.0-alpha.34",
69
+ "version": "0.0.0-alpha.35",
70
70
  "dependencies": [
71
71
  "@agimon-ai/po-config",
72
72
  "@agimon-ai/po-core",
@@ -74,11 +74,11 @@
74
74
  ]
75
75
  },
76
76
  "@agimon-ai/po-claude-bridge": {
77
- "version": "0.1.1-alpha.14",
77
+ "version": "0.1.1-alpha.15",
78
78
  "dependencies": []
79
79
  },
80
80
  "@agimon-ai/po-codemode": {
81
- "version": "0.0.1-alpha.7",
81
+ "version": "0.0.1-alpha.8",
82
82
  "dependencies": [
83
83
  "@agimon-ai/po-config",
84
84
  "@agimon-ai/po-core",
@@ -86,7 +86,7 @@
86
86
  ]
87
87
  },
88
88
  "@agimon-ai/po-computer-use": {
89
- "version": "0.0.0-alpha.34",
89
+ "version": "0.0.0-alpha.35",
90
90
  "dependencies": [
91
91
  "@agimon-ai/po-config",
92
92
  "@agimon-ai/po-core",
@@ -96,20 +96,20 @@
96
96
  ]
97
97
  },
98
98
  "@agimon-ai/po-config": {
99
- "version": "0.0.0-alpha.34",
99
+ "version": "0.0.0-alpha.35",
100
100
  "dependencies": [
101
101
  "@agimon-ai/po-core",
102
102
  "@agimon-ai/po-web-components"
103
103
  ]
104
104
  },
105
105
  "@agimon-ai/po-core": {
106
- "version": "0.0.0-alpha.34",
106
+ "version": "0.0.0-alpha.35",
107
107
  "dependencies": [
108
108
  "@agimon-ai/po-web-security"
109
109
  ]
110
110
  },
111
111
  "@agimon-ai/po-domain": {
112
- "version": "0.0.0-alpha.34",
112
+ "version": "0.0.0-alpha.35",
113
113
  "dependencies": [
114
114
  "@agimon-ai/po-config",
115
115
  "@agimon-ai/po-core",
@@ -117,7 +117,7 @@
117
117
  ]
118
118
  },
119
119
  "@agimon-ai/po-dynamic-workflow": {
120
- "version": "0.0.1-alpha.2",
120
+ "version": "0.0.1-alpha.3",
121
121
  "dependencies": [
122
122
  "@agimon-ai/po-core",
123
123
  "@agimon-ai/po-native-components",
@@ -125,7 +125,7 @@
125
125
  ]
126
126
  },
127
127
  "@agimon-ai/po-edit": {
128
- "version": "0.0.0-alpha.34",
128
+ "version": "0.0.0-alpha.35",
129
129
  "dependencies": [
130
130
  "@agimon-ai/po-core",
131
131
  "@agimon-ai/po-hashline",
@@ -134,7 +134,7 @@
134
134
  ]
135
135
  },
136
136
  "@agimon-ai/po-file-edit": {
137
- "version": "0.0.0-alpha.34",
137
+ "version": "0.0.0-alpha.35",
138
138
  "dependencies": [
139
139
  "@agimon-ai/po-config",
140
140
  "@agimon-ai/po-core",
@@ -144,7 +144,7 @@
144
144
  ]
145
145
  },
146
146
  "@agimon-ai/po-git": {
147
- "version": "0.0.0-alpha.34",
147
+ "version": "0.0.0-alpha.35",
148
148
  "dependencies": [
149
149
  "@agimon-ai/po-core",
150
150
  "@agimon-ai/po-session",
@@ -153,7 +153,7 @@
153
153
  ]
154
154
  },
155
155
  "@agimon-ai/po-goal": {
156
- "version": "0.0.0-alpha.34",
156
+ "version": "0.0.0-alpha.35",
157
157
  "dependencies": [
158
158
  "@agimon-ai/po-core",
159
159
  "@agimon-ai/po-minor-mode",
@@ -162,7 +162,7 @@
162
162
  ]
163
163
  },
164
164
  "@agimon-ai/po-grep": {
165
- "version": "0.0.0-alpha.34",
165
+ "version": "0.0.0-alpha.35",
166
166
  "dependencies": [
167
167
  "@agimon-ai/po-core",
168
168
  "@agimon-ai/po-hashline",
@@ -171,11 +171,11 @@
171
171
  ]
172
172
  },
173
173
  "@agimon-ai/po-hashline": {
174
- "version": "0.0.0-alpha.34",
174
+ "version": "0.0.0-alpha.35",
175
175
  "dependencies": []
176
176
  },
177
177
  "@agimon-ai/po-help": {
178
- "version": "0.0.0-alpha.34",
178
+ "version": "0.0.0-alpha.35",
179
179
  "dependencies": [
180
180
  "@agimon-ai/po-core",
181
181
  "@agimon-ai/po-minor-mode",
@@ -183,14 +183,14 @@
183
183
  ]
184
184
  },
185
185
  "@agimon-ai/po-hook": {
186
- "version": "0.0.0-alpha.34",
186
+ "version": "0.0.0-alpha.35",
187
187
  "dependencies": [
188
188
  "@agimon-ai/po-config",
189
189
  "@agimon-ai/po-core"
190
190
  ]
191
191
  },
192
192
  "@agimon-ai/po-image-gen": {
193
- "version": "0.0.0-alpha.33",
193
+ "version": "0.0.0-alpha.34",
194
194
  "dependencies": [
195
195
  "@agimon-ai/po-core",
196
196
  "@agimon-ai/po-web-components",
@@ -198,7 +198,7 @@
198
198
  ]
199
199
  },
200
200
  "@agimon-ai/po-log": {
201
- "version": "0.0.0-alpha.34",
201
+ "version": "0.0.0-alpha.35",
202
202
  "dependencies": [
203
203
  "@agimon-ai/po-core",
204
204
  "@agimon-ai/po-web-components",
@@ -206,7 +206,7 @@
206
206
  ]
207
207
  },
208
208
  "@agimon-ai/po-loop": {
209
- "version": "0.0.0-alpha.34",
209
+ "version": "0.0.0-alpha.35",
210
210
  "dependencies": [
211
211
  "@agimon-ai/po-core",
212
212
  "@agimon-ai/po-minor-mode",
@@ -215,7 +215,7 @@
215
215
  ]
216
216
  },
217
217
  "@agimon-ai/po-major-mode": {
218
- "version": "0.0.0-alpha.34",
218
+ "version": "0.0.0-alpha.35",
219
219
  "dependencies": [
220
220
  "@agimon-ai/po-config",
221
221
  "@agimon-ai/po-core",
@@ -223,7 +223,7 @@
223
223
  ]
224
224
  },
225
225
  "@agimon-ai/po-mcp": {
226
- "version": "0.0.0-alpha.34",
226
+ "version": "0.0.0-alpha.35",
227
227
  "dependencies": [
228
228
  "@agimon-ai/po-config",
229
229
  "@agimon-ai/po-core",
@@ -233,36 +233,36 @@
233
233
  ]
234
234
  },
235
235
  "@agimon-ai/po-mcp-proxy": {
236
- "version": "0.0.1-alpha.13",
236
+ "version": "0.0.1-alpha.14",
237
237
  "dependencies": []
238
238
  },
239
239
  "@agimon-ai/po-minor-mode": {
240
- "version": "0.0.0-alpha.34",
240
+ "version": "0.0.0-alpha.35",
241
241
  "dependencies": [
242
242
  "@agimon-ai/po-core"
243
243
  ]
244
244
  },
245
245
  "@agimon-ai/po-model-guidance": {
246
- "version": "0.0.0-alpha.34",
246
+ "version": "0.0.0-alpha.35",
247
247
  "dependencies": [
248
248
  "@agimon-ai/po-config",
249
249
  "@agimon-ai/po-core"
250
250
  ]
251
251
  },
252
252
  "@agimon-ai/po-native-components": {
253
- "version": "0.0.0-alpha.34",
253
+ "version": "0.0.0-alpha.35",
254
254
  "dependencies": [
255
255
  "@agimon-ai/po-web-components"
256
256
  ]
257
257
  },
258
258
  "@agimon-ai/po-notification": {
259
- "version": "0.0.0-alpha.34",
259
+ "version": "0.0.0-alpha.35",
260
260
  "dependencies": [
261
261
  "@agimon-ai/po-core"
262
262
  ]
263
263
  },
264
264
  "@agimon-ai/po-plan": {
265
- "version": "0.0.0-alpha.34",
265
+ "version": "0.0.0-alpha.35",
266
266
  "dependencies": [
267
267
  "@agimon-ai/po-config",
268
268
  "@agimon-ai/po-core",
@@ -272,7 +272,7 @@
272
272
  ]
273
273
  },
274
274
  "@agimon-ai/po-profile": {
275
- "version": "0.0.0-alpha.34",
275
+ "version": "0.0.0-alpha.35",
276
276
  "dependencies": [
277
277
  "@agimon-ai/po-config",
278
278
  "@agimon-ai/po-core",
@@ -280,7 +280,7 @@
280
280
  ]
281
281
  },
282
282
  "@agimon-ai/po-prompt": {
283
- "version": "0.0.0-alpha.34",
283
+ "version": "0.0.0-alpha.35",
284
284
  "dependencies": [
285
285
  "@agimon-ai/po-core",
286
286
  "@agimon-ai/po-web-components",
@@ -288,7 +288,7 @@
288
288
  ]
289
289
  },
290
290
  "@agimon-ai/po-read": {
291
- "version": "0.0.0-alpha.34",
291
+ "version": "0.0.0-alpha.35",
292
292
  "dependencies": [
293
293
  "@agimon-ai/po-config",
294
294
  "@agimon-ai/po-core",
@@ -298,7 +298,7 @@
298
298
  ]
299
299
  },
300
300
  "@agimon-ai/po-runner": {
301
- "version": "0.0.0-alpha.34",
301
+ "version": "0.0.0-alpha.35",
302
302
  "dependencies": [
303
303
  "@agimon-ai/po-core",
304
304
  "@agimon-ai/po-ui",
@@ -307,19 +307,19 @@
307
307
  ]
308
308
  },
309
309
  "@agimon-ai/po-sandbox": {
310
- "version": "0.0.0-alpha.34",
310
+ "version": "0.0.0-alpha.35",
311
311
  "dependencies": [
312
312
  "@agimon-ai/po-core"
313
313
  ]
314
314
  },
315
315
  "@agimon-ai/po-session": {
316
- "version": "0.0.0-alpha.34",
316
+ "version": "0.0.0-alpha.35",
317
317
  "dependencies": [
318
318
  "@agimon-ai/po-core"
319
319
  ]
320
320
  },
321
321
  "@agimon-ai/po-skill": {
322
- "version": "0.0.0-alpha.34",
322
+ "version": "0.0.0-alpha.35",
323
323
  "dependencies": [
324
324
  "@agimon-ai/po-config",
325
325
  "@agimon-ai/po-core",
@@ -328,7 +328,7 @@
328
328
  ]
329
329
  },
330
330
  "@agimon-ai/po-style-system": {
331
- "version": "0.0.0-alpha.34",
331
+ "version": "0.0.0-alpha.35",
332
332
  "dependencies": [
333
333
  "@agimon-ai/po-core",
334
334
  "@agimon-ai/po-web-components",
@@ -336,7 +336,7 @@
336
336
  ]
337
337
  },
338
338
  "@agimon-ai/po-task": {
339
- "version": "0.0.0-alpha.34",
339
+ "version": "0.0.0-alpha.35",
340
340
  "dependencies": [
341
341
  "@agimon-ai/po-core",
342
342
  "@agimon-ai/po-ui",
@@ -344,7 +344,7 @@
344
344
  ]
345
345
  },
346
346
  "@agimon-ai/po-team": {
347
- "version": "0.0.0-alpha.34",
347
+ "version": "0.0.0-alpha.35",
348
348
  "dependencies": [
349
349
  "@agimon-ai/po-cache",
350
350
  "@agimon-ai/po-config",
@@ -356,7 +356,7 @@
356
356
  ]
357
357
  },
358
358
  "@agimon-ai/po-template-advanced": {
359
- "version": "0.0.0-alpha.34",
359
+ "version": "0.0.0-alpha.35",
360
360
  "dependencies": [
361
361
  "@agimon-ai/po-core",
362
362
  "@agimon-ai/po-web-components",
@@ -364,7 +364,7 @@
364
364
  ]
365
365
  },
366
366
  "@agimon-ai/po-template-elegant": {
367
- "version": "0.0.0-alpha.34",
367
+ "version": "0.0.0-alpha.35",
368
368
  "dependencies": [
369
369
  "@agimon-ai/po-core",
370
370
  "@agimon-ai/po-web-components",
@@ -372,7 +372,7 @@
372
372
  ]
373
373
  },
374
374
  "@agimon-ai/po-ui": {
375
- "version": "0.0.0-alpha.34",
375
+ "version": "0.0.0-alpha.35",
376
376
  "dependencies": [
377
377
  "@agimon-ai/po-core",
378
378
  "@agimon-ai/po-hashline",
@@ -381,7 +381,7 @@
381
381
  ]
382
382
  },
383
383
  "@agimon-ai/po-user-feedback": {
384
- "version": "0.0.0-alpha.34",
384
+ "version": "0.0.0-alpha.35",
385
385
  "dependencies": [
386
386
  "@agimon-ai/po-core",
387
387
  "@agimon-ai/po-minor-mode",
@@ -390,7 +390,7 @@
390
390
  ]
391
391
  },
392
392
  "@agimon-ai/po-vibe-lint": {
393
- "version": "0.0.1-alpha.3",
393
+ "version": "0.0.1-alpha.4",
394
394
  "dependencies": [
395
395
  "@agimon-ai/po-config",
396
396
  "@agimon-ai/po-core",
@@ -400,7 +400,7 @@
400
400
  ]
401
401
  },
402
402
  "@agimon-ai/po-voice": {
403
- "version": "0.0.0-alpha.34",
403
+ "version": "0.0.0-alpha.35",
404
404
  "dependencies": [
405
405
  "@agimon-ai/po-config",
406
406
  "@agimon-ai/po-core",
@@ -412,11 +412,11 @@
412
412
  ]
413
413
  },
414
414
  "@agimon-ai/po-web-components": {
415
- "version": "0.0.0-alpha.34",
415
+ "version": "0.0.0-alpha.35",
416
416
  "dependencies": []
417
417
  },
418
418
  "@agimon-ai/po-web-dashboard": {
419
- "version": "0.0.0-alpha.34",
419
+ "version": "0.0.0-alpha.35",
420
420
  "dependencies": [
421
421
  "@agimon-ai/po-core",
422
422
  "@agimon-ai/po-web-components",
@@ -424,18 +424,18 @@
424
424
  ]
425
425
  },
426
426
  "@agimon-ai/po-web-search": {
427
- "version": "0.0.0-alpha.33",
427
+ "version": "0.0.0-alpha.34",
428
428
  "dependencies": [
429
429
  "@agimon-ai/po-core",
430
430
  "@agimon-ai/po-web-components"
431
431
  ]
432
432
  },
433
433
  "@agimon-ai/po-web-security": {
434
- "version": "0.0.0-alpha.34",
434
+ "version": "0.0.0-alpha.35",
435
435
  "dependencies": []
436
436
  },
437
437
  "@agimon-ai/po-workflow": {
438
- "version": "0.0.0-alpha.34",
438
+ "version": "0.0.0-alpha.35",
439
439
  "dependencies": [
440
440
  "@agimon-ai/po-core",
441
441
  "@agimon-ai/po-minor-mode",
@@ -30,6 +30,7 @@ const AUTO_SYNC_OFF = "0";
30
30
  const ROOT_ENV = "PO_ROOT";
31
31
  const SYNC_ARGS = ["sync", "--json"];
32
32
  const GLOBAL_OPTION = "--global";
33
+ const SKIP_ARTIFACT_BUILDS_OPTION = "--skip-artifact-builds";
33
34
  const CLI_ENTRY_SEGMENTS = [
34
35
  "dist",
35
36
  "bin",
@@ -77,11 +78,13 @@ function createBackgroundSync(options) {
77
78
  let child;
78
79
  try {
79
80
  const scope = options.repoRoot === void 0 ? [GLOBAL_OPTION] : [];
81
+ const skip = options.skipArtifactBuilds === true ? [SKIP_ARTIFACT_BUILDS_OPTION] : [];
80
82
  child = (options.spawn ?? node_child_process.spawn)(process.execPath, [
81
83
  ...process.execArgv,
82
84
  entry,
83
85
  ...SYNC_ARGS,
84
- ...scope
86
+ ...scope,
87
+ ...skip
85
88
  ], {
86
89
  ...options.repoRoot === void 0 ? {} : { cwd: options.repoRoot },
87
90
  env: {
@@ -1 +1 @@
1
- {"version":3,"file":"backgroundSync.cjs","names":["HARNESS_STATE_POINTER","HARNESS_STATE_KEYS","path","poPackageRoot","fs","spawnProcess","syncHostIdentity","rootSelectionFingerprint","readSyncPointer","packageCatalogHash","readSyncLastAttempt"],"sources":["../../../../src/builders/server/backgroundSync.ts"],"sourcesContent":["import { type ChildProcess, spawn as spawnProcess, type SpawnOptions } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { HARNESS_STATE_KEYS, HARNESS_STATE_POINTER } from '../../composition/harnessState';\nimport { packageCatalogHash } from '../../composition/layerPackageInstaller';\nimport {\n readSyncLastAttempt,\n readSyncPointer,\n rootSelectionFingerprint,\n SYNC_EXIT_BUSY,\n SYNC_EXIT_OK,\n type SyncPointer,\n syncHostIdentity,\n} from '../../composition/syncService';\nimport { poPackageRoot } from '../cli/entryResolution';\n\n/**\n * Background sync: hosts that only read what sync prepared start `po sync --json --global` as\n * a child process when a root is out of date, and pick its artifacts up when it exits. The\n * terminal app instead syncs from its repository without `--global`, which registers it.\n *\n * At most one job runs per host. Requests that arrive while it runs merge into one rerun, and\n * nothing waits on a job, so admission and session open never block on sync.\n *\n * ponytail: there is no fs.watch on `.po`, so a config edit syncs at the next checkpoint\n * (server start, admission, session open). Add a watcher if edits must apply sooner.\n */\n\n/** Set on every background sync child to the pid of the host that started it. */\nexport const SYNC_PARENT_PID_ENV = 'PO_SYNC_PARENT_PID';\n/** `PO_AUTO_SYNC=0` turns background sync off, for CI and the system test. */\nexport const AUTO_SYNC_ENV = 'PO_AUTO_SYNC';\nconst AUTO_SYNC_OFF = '0';\nconst ROOT_ENV = 'PO_ROOT';\nconst SYNC_ARGS = ['sync', '--json'] as const;\nconst GLOBAL_OPTION = '--global';\nconst CLI_ENTRY_SEGMENTS = ['dist', 'bin', 'cli.mjs'] as const;\n\n/** The host pid a sync child was started by, or undefined when this process is not one. */\nexport function syncParentPid(environment: NodeJS.ProcessEnv): number | undefined {\n const pid = Number(environment[SYNC_PARENT_PID_ENV]);\n return Number.isInteger(pid) && pid > 0 ? pid : undefined;\n}\n\n/**\n * The environment a sync child runs under, and the one a host compares root fingerprints\n * with: no harness state and no root of the host's own, so both resolve every root alike.\n */\nexport function syncEnvironment(environment: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const scoped = { ...environment };\n for (const key of [ROOT_ENV, HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete scoped[key];\n return scoped;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport interface BackgroundSyncOptions {\n environment: NodeJS.ProcessEnv;\n onNotice: (message: string) => void;\n /** Runs after each job's child exits, before a merged rerun starts. */\n onExit?: (code: number | null) => void | Promise<void>;\n /** Lets the child outlive this process, for a terminal app that exits before sync finishes. */\n detached?: boolean;\n /**\n * The repository the child syncs from, without `--global`, so sync registers it as a workspace.\n * Without one the child runs with `--global` and registers nothing.\n */\n repoRoot?: string;\n /** Test seams. */\n spawn?: (command: string, args: readonly string[], options: SpawnOptions) => ChildProcess;\n cliEntry?: string;\n parentPid?: number;\n}\n\nexport interface BackgroundSync {\n /** Starts a job, or merges into the rerun of the running one. False when background sync is off. */\n request(reason: string): boolean;\n /** Whether a job runs or a rerun is queued. */\n readonly syncing: boolean;\n /** Resolves once no job runs and none is queued. */\n idle(): Promise<void>;\n}\n\n/** Whether this host may start background sync: on unless `PO_AUTO_SYNC=0`, and never inside a sync child. */\nexport function autoSyncEnabled(environment: NodeJS.ProcessEnv): boolean {\n return environment[AUTO_SYNC_ENV] !== AUTO_SYNC_OFF && syncParentPid(environment) === undefined;\n}\n\nexport function createBackgroundSync(options: BackgroundSyncOptions): BackgroundSync {\n const enabled = autoSyncEnabled(options.environment);\n let running = false;\n let rerun = false;\n const waiters: (() => void)[] = [];\n const settle = (): void => {\n if (!running) for (const resolve of waiters.splice(0)) resolve();\n };\n const start = (): boolean => {\n const entry = options.cliEntry ?? path.join(poPackageRoot(), ...CLI_ENTRY_SEGMENTS);\n if (!fs.existsSync(entry)) {\n options.onNotice(`Background sync is unavailable because '${entry}' is missing; run po sync.`);\n return false;\n }\n let child: ChildProcess;\n try {\n // On desktop the child inherits ELECTRON_RUN_AS_NODE, so the app binary runs it as node.\n const scope = options.repoRoot === undefined ? [GLOBAL_OPTION] : [];\n child = (options.spawn ?? spawnProcess)(process.execPath, [...process.execArgv, entry, ...SYNC_ARGS, ...scope], {\n ...(options.repoRoot === undefined ? {} : { cwd: options.repoRoot }),\n env: {\n ...syncEnvironment(options.environment),\n [SYNC_PARENT_PID_ENV]: String(options.parentPid ?? process.pid),\n },\n stdio: 'ignore',\n detached: options.detached === true,\n windowsHide: true,\n });\n } catch (error) {\n options.onNotice(`Background sync could not start: ${errorMessage(error)}`);\n return false;\n }\n running = true;\n if (options.detached === true) child.unref();\n let finished = false;\n const finish = (code: number | null): void => {\n if (finished) return;\n finished = true;\n if (code !== null && code !== SYNC_EXIT_OK && code !== SYNC_EXIT_BUSY)\n options.onNotice(`Background sync exited with code ${String(code)}.`);\n void Promise.resolve()\n .then(() => options.onExit?.(code))\n .catch((error: unknown) => options.onNotice(`Picking up background sync failed: ${errorMessage(error)}`))\n .finally(() => {\n running = false;\n if (rerun) {\n rerun = false;\n start();\n }\n settle();\n });\n };\n child.once('error', (error) => {\n options.onNotice(`Background sync could not start: ${error.message}`);\n finish(null);\n });\n child.once('exit', (code) => finish(code));\n return true;\n };\n return {\n request(): boolean {\n if (!enabled) return false;\n if (running) {\n rerun = true;\n return true;\n }\n return start();\n },\n get syncing() {\n return running || rerun;\n },\n idle() {\n return new Promise<void>((resolve) => {\n waiters.push(resolve);\n settle();\n });\n },\n };\n}\n\n/**\n * Publishes a build only when the key it is given differs from the last one published, so a\n * sync that changed nothing republishes nothing. A key whose build cannot be read is skipped.\n */\nexport function createKeyedPickup<T>(\n read: (key: string) => T | undefined,\n publish: (build: T, key: string) => void,\n): (key: string | null | undefined) => 'published' | 'unchanged' | 'missing' {\n let current: string | undefined;\n return (key) => {\n if (key === null || key === undefined || key === current) return 'unchanged';\n const build = read(key);\n if (build === undefined) return 'missing';\n current = key;\n publish(build, key);\n return 'published';\n };\n}\n\nexport interface SyncedBuildKeys {\n webKey: string | null | undefined;\n nativeKey: string | null | undefined;\n}\n\nexport interface SyncedBuildKeysInput {\n pointer: SyncPointer | undefined;\n /** Whether this host's own Po install wrote `pointer`. */\n ownsPointer: boolean;\n /** The kinds this host already publishes. */\n published: { web: boolean; native: boolean };\n /** The keys this install derives the way sync does, each only when its build exists. */\n ownKeys: () => { webKey?: string; nativeKey?: string };\n /** The newest web build in the Po home, whichever install made it. */\n newestWebKey: () => string | undefined;\n}\n\n/**\n * The build keys a host publishes. Its own pointer names them. Before sync ever wrote one (the\n * first start after an upgrade), this install's derived keys, else the newest web build. A\n * pointer another Po install wrote is refused: what the host already publishes stays (an\n * undefined key changes nothing), and a kind it has not published yet takes only this\n * install's own build while its own sync runs, never the other install's.\n */\nexport function syncedBuildKeys(input: SyncedBuildKeysInput): SyncedBuildKeys {\n const { pointer, published } = input;\n if (input.ownsPointer && pointer !== undefined) return { webKey: pointer.webKey, nativeKey: pointer.nativeKey };\n if (pointer === undefined) {\n const own = input.ownKeys();\n return { webKey: own.webKey ?? input.newestWebKey(), nativeKey: own.nativeKey };\n }\n if (published.web && published.native) return { webKey: undefined, nativeKey: undefined };\n const own = input.ownKeys();\n return {\n webKey: published.web ? undefined : own.webKey,\n nativeKey: published.native ? undefined : own.nativeKey,\n };\n}\n\nexport interface SyncCheckpointsInput {\n globalRoot: string;\n homeDirectory: string;\n environment: NodeJS.ProcessEnv;\n background: BackgroundSync;\n onNotice: (message: string) => void;\n}\n\nexport interface RootSyncCheck {\n root: string;\n /** How the root is named in a warning, such as `Workspace 'po'`. */\n label: string;\n /** The selectors this host left out because they are not synced. */\n unsynced: readonly string[];\n}\n\nexport interface RootSyncStatus {\n syncing: boolean;\n /** One line per unsynced selector: why sync could not prepare it, or that it is still syncing. */\n reasons: string[];\n}\n\n/**\n * The checkpoints a host runs when it admits a root or opens a session: request a background\n * job when the root changed since the last sync, and warn about what it opened without. Each\n * root's warning is emitted once until it changes.\n */\nexport function createSyncCheckpoints(input: SyncCheckpointsInput) {\n const fingerprintEnvironment = syncEnvironment(input.environment);\n const warned = new Map<string, string>();\n /** The state each root last requested a sync for: pointer generation, catalogue and selection. */\n const requested = new Map<string, string>();\n /** This host's install, compared with the one that wrote the pointer. */\n const host = (): string => syncHostIdentity(input.globalRoot, fingerprintEnvironment);\n /** The last foreign pointer (install and generation) this host warned about. */\n let warnedTakeover: string | undefined;\n /** Each root's selection fingerprint, kept until `invalidate`: resolving it composes every mode. */\n const fingerprints = new Map<string, string>();\n const fingerprintFor = (root: string): string => {\n let fingerprint = fingerprints.get(root);\n if (fingerprint === undefined) {\n fingerprint = rootSelectionFingerprint(root, input.homeDirectory, fingerprintEnvironment);\n fingerprints.set(root, fingerprint);\n }\n return fingerprint;\n };\n /**\n * The root's state when it is stale (no pointer, a pointer another Po install wrote, a changed\n * catalogue, or a selection that differs from the pointer's), else undefined.\n *\n * A foreign pointer's state includes its generation, which every sync moves, so each takeover\n * of the shared runtime is one new stale state and gets one resync. That settles: the resync\n * writes this host's own pointer, which is never stale for being foreign.\n */\n const staleState = (root: string): string | undefined => {\n const pointer = readSyncPointer(input.globalRoot);\n const catalogueHash = packageCatalogHash(input.environment);\n const fingerprint = fingerprintFor(root);\n if (pointer !== undefined && pointer.host !== host())\n return JSON.stringify(['host', pointer.host ?? null, pointer.generation, catalogueHash, fingerprint]);\n if (pointer?.catalogueHash === catalogueHash && pointer.fingerprints?.[root] === fingerprint) return undefined;\n return JSON.stringify([pointer?.generation ?? null, catalogueHash, fingerprint]);\n };\n const stale = (root: string): boolean => staleState(root) !== undefined;\n /**\n * Requests one sync per stale state of a root. A sync that ran and could not change the\n * pointer (it failed) is not requested again until the root, the catalogue or the pointer\n * moves, so a broken root never makes every checkpoint start another full sync.\n */\n const requestIfStale = (check: RootSyncCheck): boolean => {\n const state = staleState(check.root);\n if (state === undefined) return false;\n if (requested.get(check.root) === state) return true;\n if (!input.background.request(`${check.label} changed since the last sync`)) return false;\n requested.set(check.root, state);\n return true;\n };\n /** The missing artifacts a sync was requested for, each with the pointer state it was missing under. */\n const requestedMissing = new Set<string>();\n /** Why the last attempt, or failing that the pointer, could not prepare each selector. */\n const failures = (root: string): Map<string, string> => {\n const reports = [readSyncLastAttempt(input.globalRoot), readSyncPointer(input.globalRoot)];\n const reasons = new Map<string, string>();\n for (const report of reports)\n for (const entry of report?.roots.find((candidate) => candidate.root === root)?.unsynced ?? [])\n if (!reasons.has(entry.selector)) reasons.set(entry.selector, entry.reason);\n return reasons;\n };\n return {\n stale,\n /** Forgets every root's fingerprint; the caller runs it when a root's selection may have moved. */\n invalidate: (): void => fingerprints.clear(),\n /**\n * Whether this host may publish the builds `pointer` names: only when its own Po install wrote\n * it. Every pointer another install writes (each sync moves its generation) is refused, and\n * gets one background sync of the global root and one warning, so this host keeps its previous\n * publication until its own sync replaces the pointer.\n */\n ownsPointer(pointer: SyncPointer | undefined): pointer is SyncPointer {\n if (pointer === undefined) return false;\n const own = host();\n if (pointer.host === own) return true;\n const foreign = pointer.host ?? 'an older Po';\n const resyncing = requestIfStale({ root: input.globalRoot, label: 'The global scope', unsynced: [] });\n const takeover = JSON.stringify([foreign, pointer.generation]);\n if (warnedTakeover !== takeover) {\n warnedTakeover = takeover;\n input.onNotice(\n `Another Po install (${foreign}) replaced the shared packages; ${resyncing ? `resyncing with this install (${own})` : 'run po sync from this install to resync'}. Use one Po install so they stop replacing each other.`,\n );\n }\n return false;\n },\n /**\n * Requests one sync per missing artifact (such as an MCP app build key) and pointer state,\n * the same limit stale roots get: a sync that ran and still did not produce it is not\n * requested again until the pointer or the catalogue moves.\n */\n requestMissing(artifact: string, reason: string): boolean {\n const pointer = readSyncPointer(input.globalRoot);\n const state = JSON.stringify([artifact, pointer?.generation ?? null, packageCatalogHash(input.environment)]);\n if (requestedMissing.has(state) || !input.background.request(reason)) return false;\n requestedMissing.add(state);\n return true;\n },\n /** Requests a job when `request` allows and the root is stale, then warns about `unsynced`. */\n check(check: RootSyncCheck, request = true): RootSyncStatus {\n if (request) requestIfStale(check);\n const syncing = input.background.syncing;\n if (check.unsynced.length === 0) {\n warned.delete(check.root);\n return { syncing, reasons: [] };\n }\n const known = failures(check.root);\n const count = check.unsynced.length;\n const noun = count === 1 ? 'extension' : 'extensions';\n const reasons = check.unsynced.map((selector) => {\n const reason = known.get(selector);\n if (syncing || reason === undefined) return `${selector} is not synced yet`;\n return `Sync could not prepare ${selector}: ${reason}.`;\n });\n const message = syncing\n ? `${check.label} opened without ${String(count)} ${noun} that ${count === 1 ? 'is' : 'are'} still syncing: ${check.unsynced.join(', ')}. ${count === 1 ? 'It loads' : 'They load'} when sync finishes.`\n : check.unsynced.every((selector) => known.has(selector))\n ? reasons.join(' ')\n : `${check.label} opened without ${String(count)} ${noun} that ${count === 1 ? 'is' : 'are'} not synced: ${check.unsynced.join(', ')}. Run po sync to prepare them.`;\n if (warned.get(check.root) !== message) {\n warned.set(check.root, message);\n input.onNotice(message);\n }\n return { syncing, reasons };\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"backgroundSync.cjs","names":["HARNESS_STATE_POINTER","HARNESS_STATE_KEYS","path","poPackageRoot","fs","spawnProcess","syncHostIdentity","rootSelectionFingerprint","readSyncPointer","packageCatalogHash","readSyncLastAttempt"],"sources":["../../../../src/builders/server/backgroundSync.ts"],"sourcesContent":["import { type ChildProcess, spawn as spawnProcess, type SpawnOptions } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport { HARNESS_STATE_KEYS, HARNESS_STATE_POINTER } from '../../composition/harnessState';\nimport { packageCatalogHash } from '../../composition/layerPackageInstaller';\nimport {\n readSyncLastAttempt,\n readSyncPointer,\n rootSelectionFingerprint,\n SYNC_EXIT_BUSY,\n SYNC_EXIT_OK,\n type SyncPointer,\n syncHostIdentity,\n} from '../../composition/syncService';\nimport { poPackageRoot } from '../cli/entryResolution';\n\n/**\n * Background sync: hosts that only read what sync prepared start `po sync --json --global` as\n * a child process when a root is out of date, and pick its artifacts up when it exits. The\n * terminal app instead syncs from its repository without `--global`, which registers it.\n *\n * At most one job runs per host. Requests that arrive while it runs merge into one rerun, and\n * nothing waits on a job, so admission and session open never block on sync.\n *\n * ponytail: there is no fs.watch on `.po`, so a config edit syncs at the next checkpoint\n * (server start, admission, session open). Add a watcher if edits must apply sooner.\n */\n\n/** Set on every background sync child to the pid of the host that started it. */\nexport const SYNC_PARENT_PID_ENV = 'PO_SYNC_PARENT_PID';\n/** `PO_AUTO_SYNC=0` turns background sync off, for CI and the system test. */\nexport const AUTO_SYNC_ENV = 'PO_AUTO_SYNC';\nconst AUTO_SYNC_OFF = '0';\nconst ROOT_ENV = 'PO_ROOT';\nconst SYNC_ARGS = ['sync', '--json'] as const;\nconst GLOBAL_OPTION = '--global';\nconst SKIP_ARTIFACT_BUILDS_OPTION = '--skip-artifact-builds';\nconst CLI_ENTRY_SEGMENTS = ['dist', 'bin', 'cli.mjs'] as const;\n\n/** The host pid a sync child was started by, or undefined when this process is not one. */\nexport function syncParentPid(environment: NodeJS.ProcessEnv): number | undefined {\n const pid = Number(environment[SYNC_PARENT_PID_ENV]);\n return Number.isInteger(pid) && pid > 0 ? pid : undefined;\n}\n\n/**\n * The environment a sync child runs under, and the one a host compares root fingerprints\n * with: no harness state and no root of the host's own, so both resolve every root alike.\n */\nexport function syncEnvironment(environment: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n const scoped = { ...environment };\n for (const key of [ROOT_ENV, HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete scoped[key];\n return scoped;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport interface BackgroundSyncOptions {\n environment: NodeJS.ProcessEnv;\n onNotice: (message: string) => void;\n /** Runs after each job's child exits, before a merged rerun starts. */\n onExit?: (code: number | null) => void | Promise<void>;\n /** Lets the child outlive this process, for a terminal app that exits before sync finishes. */\n detached?: boolean;\n /**\n * The repository the child syncs from, without `--global`, so sync registers it as a workspace.\n * Without one the child runs with `--global` and registers nothing.\n */\n repoRoot?: string;\n /** Runs the child with `--skip-artifact-builds`: packages only, no web, native or MCP app build. */\n skipArtifactBuilds?: boolean;\n /** Test seams. */\n spawn?: (command: string, args: readonly string[], options: SpawnOptions) => ChildProcess;\n cliEntry?: string;\n parentPid?: number;\n}\n\nexport interface BackgroundSync {\n /** Starts a job, or merges into the rerun of the running one. False when background sync is off. */\n request(reason: string): boolean;\n /** Whether a job runs or a rerun is queued. */\n readonly syncing: boolean;\n /** Resolves once no job runs and none is queued. */\n idle(): Promise<void>;\n}\n\n/** Whether this host may start background sync: on unless `PO_AUTO_SYNC=0`, and never inside a sync child. */\nexport function autoSyncEnabled(environment: NodeJS.ProcessEnv): boolean {\n return environment[AUTO_SYNC_ENV] !== AUTO_SYNC_OFF && syncParentPid(environment) === undefined;\n}\n\nexport function createBackgroundSync(options: BackgroundSyncOptions): BackgroundSync {\n const enabled = autoSyncEnabled(options.environment);\n let running = false;\n let rerun = false;\n const waiters: (() => void)[] = [];\n const settle = (): void => {\n if (!running) for (const resolve of waiters.splice(0)) resolve();\n };\n const start = (): boolean => {\n const entry = options.cliEntry ?? path.join(poPackageRoot(), ...CLI_ENTRY_SEGMENTS);\n if (!fs.existsSync(entry)) {\n options.onNotice(`Background sync is unavailable because '${entry}' is missing; run po sync.`);\n return false;\n }\n let child: ChildProcess;\n try {\n // On desktop the child inherits ELECTRON_RUN_AS_NODE, so the app binary runs it as node.\n const scope = options.repoRoot === undefined ? [GLOBAL_OPTION] : [];\n const skip = options.skipArtifactBuilds === true ? [SKIP_ARTIFACT_BUILDS_OPTION] : [];\n child = (options.spawn ?? spawnProcess)(\n process.execPath,\n [...process.execArgv, entry, ...SYNC_ARGS, ...scope, ...skip],\n {\n ...(options.repoRoot === undefined ? {} : { cwd: options.repoRoot }),\n env: {\n ...syncEnvironment(options.environment),\n [SYNC_PARENT_PID_ENV]: String(options.parentPid ?? process.pid),\n },\n stdio: 'ignore',\n detached: options.detached === true,\n windowsHide: true,\n },\n );\n } catch (error) {\n options.onNotice(`Background sync could not start: ${errorMessage(error)}`);\n return false;\n }\n running = true;\n if (options.detached === true) child.unref();\n let finished = false;\n const finish = (code: number | null): void => {\n if (finished) return;\n finished = true;\n if (code !== null && code !== SYNC_EXIT_OK && code !== SYNC_EXIT_BUSY)\n options.onNotice(`Background sync exited with code ${String(code)}.`);\n void Promise.resolve()\n .then(() => options.onExit?.(code))\n .catch((error: unknown) => options.onNotice(`Picking up background sync failed: ${errorMessage(error)}`))\n .finally(() => {\n running = false;\n if (rerun) {\n rerun = false;\n start();\n }\n settle();\n });\n };\n child.once('error', (error) => {\n options.onNotice(`Background sync could not start: ${error.message}`);\n finish(null);\n });\n child.once('exit', (code) => finish(code));\n return true;\n };\n return {\n request(): boolean {\n if (!enabled) return false;\n if (running) {\n rerun = true;\n return true;\n }\n return start();\n },\n get syncing() {\n return running || rerun;\n },\n idle() {\n return new Promise<void>((resolve) => {\n waiters.push(resolve);\n settle();\n });\n },\n };\n}\n\n/**\n * Publishes a build only when the key it is given differs from the last one published, so a\n * sync that changed nothing republishes nothing. A key whose build cannot be read is skipped.\n */\nexport function createKeyedPickup<T>(\n read: (key: string) => T | undefined,\n publish: (build: T, key: string) => void,\n): (key: string | null | undefined) => 'published' | 'unchanged' | 'missing' {\n let current: string | undefined;\n return (key) => {\n if (key === null || key === undefined || key === current) return 'unchanged';\n const build = read(key);\n if (build === undefined) return 'missing';\n current = key;\n publish(build, key);\n return 'published';\n };\n}\n\nexport interface SyncedBuildKeys {\n webKey: string | null | undefined;\n nativeKey: string | null | undefined;\n}\n\nexport interface SyncedBuildKeysInput {\n pointer: SyncPointer | undefined;\n /** Whether this host's own Po install wrote `pointer`. */\n ownsPointer: boolean;\n /** The kinds this host already publishes. */\n published: { web: boolean; native: boolean };\n /** The keys this install derives the way sync does, each only when its build exists. */\n ownKeys: () => { webKey?: string; nativeKey?: string };\n /** The newest web build in the Po home, whichever install made it. */\n newestWebKey: () => string | undefined;\n}\n\n/**\n * The build keys a host publishes. Its own pointer names them. Before sync ever wrote one (the\n * first start after an upgrade), this install's derived keys, else the newest web build. A\n * pointer another Po install wrote is refused: what the host already publishes stays (an\n * undefined key changes nothing), and a kind it has not published yet takes only this\n * install's own build while its own sync runs, never the other install's.\n */\nexport function syncedBuildKeys(input: SyncedBuildKeysInput): SyncedBuildKeys {\n const { pointer, published } = input;\n if (input.ownsPointer && pointer !== undefined) return { webKey: pointer.webKey, nativeKey: pointer.nativeKey };\n if (pointer === undefined) {\n const own = input.ownKeys();\n return { webKey: own.webKey ?? input.newestWebKey(), nativeKey: own.nativeKey };\n }\n if (published.web && published.native) return { webKey: undefined, nativeKey: undefined };\n const own = input.ownKeys();\n return {\n webKey: published.web ? undefined : own.webKey,\n nativeKey: published.native ? undefined : own.nativeKey,\n };\n}\n\nexport interface SyncCheckpointsInput {\n globalRoot: string;\n homeDirectory: string;\n environment: NodeJS.ProcessEnv;\n background: BackgroundSync;\n onNotice: (message: string) => void;\n}\n\nexport interface RootSyncCheck {\n root: string;\n /** How the root is named in a warning, such as `Workspace 'po'`. */\n label: string;\n /** The selectors this host left out because they are not synced. */\n unsynced: readonly string[];\n}\n\nexport interface RootSyncStatus {\n syncing: boolean;\n /** One line per unsynced selector: why sync could not prepare it, or that it is still syncing. */\n reasons: string[];\n}\n\n/**\n * The checkpoints a host runs when it admits a root or opens a session: request a background\n * job when the root changed since the last sync, and warn about what it opened without. Each\n * root's warning is emitted once until it changes.\n */\nexport function createSyncCheckpoints(input: SyncCheckpointsInput) {\n const fingerprintEnvironment = syncEnvironment(input.environment);\n const warned = new Map<string, string>();\n /** The state each root last requested a sync for: pointer generation, catalogue and selection. */\n const requested = new Map<string, string>();\n /** This host's install, compared with the one that wrote the pointer. */\n const host = (): string => syncHostIdentity(input.globalRoot, fingerprintEnvironment);\n /** The last foreign pointer (install and generation) this host warned about. */\n let warnedTakeover: string | undefined;\n /** Each root's selection fingerprint, kept until `invalidate`: resolving it composes every mode. */\n const fingerprints = new Map<string, string>();\n const fingerprintFor = (root: string): string => {\n let fingerprint = fingerprints.get(root);\n if (fingerprint === undefined) {\n fingerprint = rootSelectionFingerprint(root, input.homeDirectory, fingerprintEnvironment);\n fingerprints.set(root, fingerprint);\n }\n return fingerprint;\n };\n /**\n * The root's state when it is stale (no pointer, a pointer another Po install wrote, a changed\n * catalogue, or a selection that differs from the pointer's), else undefined.\n *\n * A foreign pointer's state includes its generation, which every sync moves, so each takeover\n * of the shared runtime is one new stale state and gets one resync. That settles: the resync\n * writes this host's own pointer, which is never stale for being foreign.\n */\n const staleState = (root: string): string | undefined => {\n const pointer = readSyncPointer(input.globalRoot);\n const catalogueHash = packageCatalogHash(input.environment);\n const fingerprint = fingerprintFor(root);\n if (pointer !== undefined && pointer.host !== host())\n return JSON.stringify(['host', pointer.host ?? null, pointer.generation, catalogueHash, fingerprint]);\n if (pointer?.catalogueHash === catalogueHash && pointer.fingerprints?.[root] === fingerprint) return undefined;\n return JSON.stringify([pointer?.generation ?? null, catalogueHash, fingerprint]);\n };\n const stale = (root: string): boolean => staleState(root) !== undefined;\n /**\n * Requests one sync per stale state of a root. A sync that ran and could not change the\n * pointer (it failed) is not requested again until the root, the catalogue or the pointer\n * moves, so a broken root never makes every checkpoint start another full sync.\n */\n const requestIfStale = (check: RootSyncCheck): boolean => {\n const state = staleState(check.root);\n if (state === undefined) return false;\n if (requested.get(check.root) === state) return true;\n if (!input.background.request(`${check.label} changed since the last sync`)) return false;\n requested.set(check.root, state);\n return true;\n };\n /** The missing artifacts a sync was requested for, each with the pointer state it was missing under. */\n const requestedMissing = new Set<string>();\n /** Why the last attempt, or failing that the pointer, could not prepare each selector. */\n const failures = (root: string): Map<string, string> => {\n const reports = [readSyncLastAttempt(input.globalRoot), readSyncPointer(input.globalRoot)];\n const reasons = new Map<string, string>();\n for (const report of reports)\n for (const entry of report?.roots.find((candidate) => candidate.root === root)?.unsynced ?? [])\n if (!reasons.has(entry.selector)) reasons.set(entry.selector, entry.reason);\n return reasons;\n };\n return {\n stale,\n /** Forgets every root's fingerprint; the caller runs it when a root's selection may have moved. */\n invalidate: (): void => fingerprints.clear(),\n /**\n * Whether this host may publish the builds `pointer` names: only when its own Po install wrote\n * it. Every pointer another install writes (each sync moves its generation) is refused, and\n * gets one background sync of the global root and one warning, so this host keeps its previous\n * publication until its own sync replaces the pointer.\n */\n ownsPointer(pointer: SyncPointer | undefined): pointer is SyncPointer {\n if (pointer === undefined) return false;\n const own = host();\n if (pointer.host === own) return true;\n const foreign = pointer.host ?? 'an older Po';\n const resyncing = requestIfStale({ root: input.globalRoot, label: 'The global scope', unsynced: [] });\n const takeover = JSON.stringify([foreign, pointer.generation]);\n if (warnedTakeover !== takeover) {\n warnedTakeover = takeover;\n input.onNotice(\n `Another Po install (${foreign}) replaced the shared packages; ${resyncing ? `resyncing with this install (${own})` : 'run po sync from this install to resync'}. Use one Po install so they stop replacing each other.`,\n );\n }\n return false;\n },\n /**\n * Requests one sync per missing artifact (such as an MCP app build key) and pointer state,\n * the same limit stale roots get: a sync that ran and still did not produce it is not\n * requested again until the pointer or the catalogue moves.\n */\n requestMissing(artifact: string, reason: string): boolean {\n const pointer = readSyncPointer(input.globalRoot);\n const state = JSON.stringify([artifact, pointer?.generation ?? null, packageCatalogHash(input.environment)]);\n if (requestedMissing.has(state) || !input.background.request(reason)) return false;\n requestedMissing.add(state);\n return true;\n },\n /** Requests a job when `request` allows and the root is stale, then warns about `unsynced`. */\n check(check: RootSyncCheck, request = true): RootSyncStatus {\n if (request) requestIfStale(check);\n const syncing = input.background.syncing;\n if (check.unsynced.length === 0) {\n warned.delete(check.root);\n return { syncing, reasons: [] };\n }\n const known = failures(check.root);\n const count = check.unsynced.length;\n const noun = count === 1 ? 'extension' : 'extensions';\n const reasons = check.unsynced.map((selector) => {\n const reason = known.get(selector);\n if (syncing || reason === undefined) return `${selector} is not synced yet`;\n return `Sync could not prepare ${selector}: ${reason}.`;\n });\n const message = syncing\n ? `${check.label} opened without ${String(count)} ${noun} that ${count === 1 ? 'is' : 'are'} still syncing: ${check.unsynced.join(', ')}. ${count === 1 ? 'It loads' : 'They load'} when sync finishes.`\n : check.unsynced.every((selector) => known.has(selector))\n ? reasons.join(' ')\n : `${check.label} opened without ${String(count)} ${noun} that ${count === 1 ? 'is' : 'are'} not synced: ${check.unsynced.join(', ')}. Run po sync to prepare them.`;\n if (warned.get(check.root) !== message) {\n warned.set(check.root, message);\n input.onNotice(message);\n }\n return { syncing, reasons };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAa,sBAAsB;;AAEnC,MAAa,gBAAgB;AAC7B,MAAM,gBAAgB;AACtB,MAAM,WAAW;AACjB,MAAM,YAAY,CAAC,QAAQ,QAAQ;AACnC,MAAM,gBAAgB;AACtB,MAAM,8BAA8B;AACpC,MAAM,qBAAqB;CAAC;CAAQ;CAAO;AAAS;;AAGpD,SAAgB,cAAc,aAAoD;CAChF,MAAM,MAAM,OAAO,YAAY,oBAAoB;CACnD,OAAO,OAAO,UAAU,GAAG,KAAK,MAAM,IAAI,MAAM,KAAA;AAClD;;;;;AAMA,SAAgB,gBAAgB,aAAmD;CACjF,MAAM,SAAS,EAAE,GAAG,YAAY;CAChC,KAAK,MAAM,OAAO;EAAC;EAAUA,kCAAAA;EAAuB,GAAG,OAAO,OAAOC,kCAAAA,kBAAkB;CAAC,GAAG,OAAO,OAAO;CACzG,OAAO;AACT;AAEA,SAAS,aAAa,OAAwB;CAC5C,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC9D;;AAgCA,SAAgB,gBAAgB,aAAyC;CACvE,OAAO,YAAA,oBAA+B,iBAAiB,cAAc,WAAW,MAAM,KAAA;AACxF;AAEA,SAAgB,qBAAqB,SAAgD;CACnF,MAAM,UAAU,gBAAgB,QAAQ,WAAW;CACnD,IAAI,UAAU;CACd,IAAI,QAAQ;CACZ,MAAM,UAA0B,CAAC;CACjC,MAAM,eAAqB;EACzB,IAAI,CAAC,SAAS,KAAK,MAAM,WAAW,QAAQ,OAAO,CAAC,GAAG,QAAQ;CACjE;CACA,MAAM,cAAuB;EAC3B,MAAM,QAAQ,QAAQ,YAAYC,UAAAA,QAAK,KAAKC,wBAAAA,cAAc,GAAG,GAAG,kBAAkB;EAClF,IAAI,CAACC,QAAAA,QAAG,WAAW,KAAK,GAAG;GACzB,QAAQ,SAAS,2CAA2C,MAAM,2BAA2B;GAC7F,OAAO;EACT;EACA,IAAI;EACJ,IAAI;GAEF,MAAM,QAAQ,QAAQ,aAAa,KAAA,IAAY,CAAC,aAAa,IAAI,CAAC;GAClE,MAAM,OAAO,QAAQ,uBAAuB,OAAO,CAAC,2BAA2B,IAAI,CAAC;GACpF,SAAS,QAAQ,SAASC,mBAAAA,MAAAA,CACxB,QAAQ,UACR;IAAC,GAAG,QAAQ;IAAU;IAAO,GAAG;IAAW,GAAG;IAAO,GAAG;GAAI,GAC5D;IACE,GAAI,QAAQ,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK,QAAQ,SAAS;IAClE,KAAK;KACH,GAAG,gBAAgB,QAAQ,WAAW;MACrC,sBAAsB,OAAO,QAAQ,aAAa,QAAQ,GAAG;IAChE;IACA,OAAO;IACP,UAAU,QAAQ,aAAa;IAC/B,aAAa;GACf,CACF;EACF,SAAS,OAAO;GACd,QAAQ,SAAS,oCAAoC,aAAa,KAAK,GAAG;GAC1E,OAAO;EACT;EACA,UAAU;EACV,IAAI,QAAQ,aAAa,MAAM,MAAM,MAAM;EAC3C,IAAI,WAAW;EACf,MAAM,UAAU,SAA8B;GAC5C,IAAI,UAAU;GACd,WAAW;GACX,IAAI,SAAS,QAAQ,SAAA,KAAyB,SAAA,IAC5C,QAAQ,SAAS,oCAAoC,OAAO,IAAI,EAAE,EAAE;GACtE,QAAa,QAAQ,CAAC,CACnB,WAAW,QAAQ,SAAS,IAAI,CAAC,CAAC,CAClC,OAAO,UAAmB,QAAQ,SAAS,sCAAsC,aAAa,KAAK,GAAG,CAAC,CAAC,CACxG,cAAc;IACb,UAAU;IACV,IAAI,OAAO;KACT,QAAQ;KACR,MAAM;IACR;IACA,OAAO;GACT,CAAC;EACL;EACA,MAAM,KAAK,UAAU,UAAU;GAC7B,QAAQ,SAAS,oCAAoC,MAAM,SAAS;GACpE,OAAO,IAAI;EACb,CAAC;EACD,MAAM,KAAK,SAAS,SAAS,OAAO,IAAI,CAAC;EACzC,OAAO;CACT;CACA,OAAO;EACL,UAAmB;GACjB,IAAI,CAAC,SAAS,OAAO;GACrB,IAAI,SAAS;IACX,QAAQ;IACR,OAAO;GACT;GACA,OAAO,MAAM;EACf;EACA,IAAI,UAAU;GACZ,OAAO,WAAW;EACpB;EACA,OAAO;GACL,OAAO,IAAI,SAAe,YAAY;IACpC,QAAQ,KAAK,OAAO;IACpB,OAAO;GACT,CAAC;EACH;CACF;AACF;;;;;AAMA,SAAgB,kBACd,MACA,SAC2E;CAC3E,IAAI;CACJ,QAAQ,QAAQ;EACd,IAAI,QAAQ,QAAQ,QAAQ,KAAA,KAAa,QAAQ,SAAS,OAAO;EACjE,MAAM,QAAQ,KAAK,GAAG;EACtB,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,UAAU;EACV,QAAQ,OAAO,GAAG;EAClB,OAAO;CACT;AACF;;;;;;;;AA0BA,SAAgB,gBAAgB,OAA8C;CAC5E,MAAM,EAAE,SAAS,cAAc;CAC/B,IAAI,MAAM,eAAe,YAAY,KAAA,GAAW,OAAO;EAAE,QAAQ,QAAQ;EAAQ,WAAW,QAAQ;CAAU;CAC9G,IAAI,YAAY,KAAA,GAAW;EACzB,MAAM,MAAM,MAAM,QAAQ;EAC1B,OAAO;GAAE,QAAQ,IAAI,UAAU,MAAM,aAAa;GAAG,WAAW,IAAI;EAAU;CAChF;CACA,IAAI,UAAU,OAAO,UAAU,QAAQ,OAAO;EAAE,QAAQ,KAAA;EAAW,WAAW,KAAA;CAAU;CACxF,MAAM,MAAM,MAAM,QAAQ;CAC1B,OAAO;EACL,QAAQ,UAAU,MAAM,KAAA,IAAY,IAAI;EACxC,WAAW,UAAU,SAAS,KAAA,IAAY,IAAI;CAChD;AACF;;;;;;AA6BA,SAAgB,sBAAsB,OAA6B;CACjE,MAAM,yBAAyB,gBAAgB,MAAM,WAAW;CAChE,MAAM,yBAAS,IAAI,IAAoB;;CAEvC,MAAM,4BAAY,IAAI,IAAoB;;CAE1C,MAAM,aAAqBC,gBAAAA,iBAAiB,MAAM,YAAY,sBAAsB;;CAEpF,IAAI;;CAEJ,MAAM,+BAAe,IAAI,IAAoB;CAC7C,MAAM,kBAAkB,SAAyB;EAC/C,IAAI,cAAc,aAAa,IAAI,IAAI;EACvC,IAAI,gBAAgB,KAAA,GAAW;GAC7B,cAAcC,gBAAAA,yBAAyB,MAAM,MAAM,eAAe,sBAAsB;GACxF,aAAa,IAAI,MAAM,WAAW;EACpC;EACA,OAAO;CACT;;;;;;;;;CASA,MAAM,cAAc,SAAqC;EACvD,MAAM,UAAUC,gBAAAA,gBAAgB,MAAM,UAAU;EAChD,MAAM,gBAAgBC,gBAAAA,mBAAmB,MAAM,WAAW;EAC1D,MAAM,cAAc,eAAe,IAAI;EACvC,IAAI,YAAY,KAAA,KAAa,QAAQ,SAAS,KAAK,GACjD,OAAO,KAAK,UAAU;GAAC;GAAQ,QAAQ,QAAQ;GAAM,QAAQ;GAAY;GAAe;EAAW,CAAC;EACtG,IAAI,SAAS,kBAAkB,iBAAiB,QAAQ,eAAe,UAAU,aAAa,OAAO,KAAA;EACrG,OAAO,KAAK,UAAU;GAAC,SAAS,cAAc;GAAM;GAAe;EAAW,CAAC;CACjF;CACA,MAAM,SAAS,SAA0B,WAAW,IAAI,MAAM,KAAA;;;;;;CAM9D,MAAM,kBAAkB,UAAkC;EACxD,MAAM,QAAQ,WAAW,MAAM,IAAI;EACnC,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,IAAI,UAAU,IAAI,MAAM,IAAI,MAAM,OAAO,OAAO;EAChD,IAAI,CAAC,MAAM,WAAW,QAAQ,GAAG,MAAM,MAAM,6BAA6B,GAAG,OAAO;EACpF,UAAU,IAAI,MAAM,MAAM,KAAK;EAC/B,OAAO;CACT;;CAEA,MAAM,mCAAmB,IAAI,IAAY;;CAEzC,MAAM,YAAY,SAAsC;EACtD,MAAM,UAAU,CAACC,gBAAAA,oBAAoB,MAAM,UAAU,GAAGF,gBAAAA,gBAAgB,MAAM,UAAU,CAAC;EACzF,MAAM,0BAAU,IAAI,IAAoB;EACxC,KAAK,MAAM,UAAU,SACnB,KAAK,MAAM,SAAS,QAAQ,MAAM,MAAM,cAAc,UAAU,SAAS,IAAI,CAAC,EAAE,YAAY,CAAC,GAC3F,IAAI,CAAC,QAAQ,IAAI,MAAM,QAAQ,GAAG,QAAQ,IAAI,MAAM,UAAU,MAAM,MAAM;EAC9E,OAAO;CACT;CACA,OAAO;EACL;;EAEA,kBAAwB,aAAa,MAAM;;;;;;;EAO3C,YAAY,SAA0D;GACpE,IAAI,YAAY,KAAA,GAAW,OAAO;GAClC,MAAM,MAAM,KAAK;GACjB,IAAI,QAAQ,SAAS,KAAK,OAAO;GACjC,MAAM,UAAU,QAAQ,QAAQ;GAChC,MAAM,YAAY,eAAe;IAAE,MAAM,MAAM;IAAY,OAAO;IAAoB,UAAU,CAAC;GAAE,CAAC;GACpG,MAAM,WAAW,KAAK,UAAU,CAAC,SAAS,QAAQ,UAAU,CAAC;GAC7D,IAAI,mBAAmB,UAAU;IAC/B,iBAAiB;IACjB,MAAM,SACJ,uBAAuB,QAAQ,kCAAkC,YAAY,gCAAgC,IAAI,KAAK,0CAA0C,wDAClK;GACF;GACA,OAAO;EACT;;;;;;EAMA,eAAe,UAAkB,QAAyB;GACxD,MAAM,UAAUA,gBAAAA,gBAAgB,MAAM,UAAU;GAChD,MAAM,QAAQ,KAAK,UAAU;IAAC;IAAU,SAAS,cAAc;IAAMC,gBAAAA,mBAAmB,MAAM,WAAW;GAAC,CAAC;GAC3G,IAAI,iBAAiB,IAAI,KAAK,KAAK,CAAC,MAAM,WAAW,QAAQ,MAAM,GAAG,OAAO;GAC7E,iBAAiB,IAAI,KAAK;GAC1B,OAAO;EACT;;EAEA,MAAM,OAAsB,UAAU,MAAsB;GAC1D,IAAI,SAAS,eAAe,KAAK;GACjC,MAAM,UAAU,MAAM,WAAW;GACjC,IAAI,MAAM,SAAS,WAAW,GAAG;IAC/B,OAAO,OAAO,MAAM,IAAI;IACxB,OAAO;KAAE;KAAS,SAAS,CAAC;IAAE;GAChC;GACA,MAAM,QAAQ,SAAS,MAAM,IAAI;GACjC,MAAM,QAAQ,MAAM,SAAS;GAC7B,MAAM,OAAO,UAAU,IAAI,cAAc;GACzC,MAAM,UAAU,MAAM,SAAS,KAAK,aAAa;IAC/C,MAAM,SAAS,MAAM,IAAI,QAAQ;IACjC,IAAI,WAAW,WAAW,KAAA,GAAW,OAAO,GAAG,SAAS;IACxD,OAAO,0BAA0B,SAAS,IAAI,OAAO;GACvD,CAAC;GACD,MAAM,UAAU,UACZ,GAAG,MAAM,MAAM,kBAAkB,OAAO,KAAK,EAAE,GAAG,KAAK,QAAQ,UAAU,IAAI,OAAO,MAAM,kBAAkB,MAAM,SAAS,KAAK,IAAI,EAAE,IAAI,UAAU,IAAI,aAAa,YAAY,wBACjL,MAAM,SAAS,OAAO,aAAa,MAAM,IAAI,QAAQ,CAAC,IACpD,QAAQ,KAAK,GAAG,IAChB,GAAG,MAAM,MAAM,kBAAkB,OAAO,KAAK,EAAE,GAAG,KAAK,QAAQ,UAAU,IAAI,OAAO,MAAM,eAAe,MAAM,SAAS,KAAK,IAAI,EAAE;GACzI,IAAI,OAAO,IAAI,MAAM,IAAI,MAAM,SAAS;IACtC,OAAO,IAAI,MAAM,MAAM,OAAO;IAC9B,MAAM,SAAS,OAAO;GACxB;GACA,OAAO;IAAE;IAAS;GAAQ;EAC5B;CACF;AACF"}
@@ -25,6 +25,7 @@ const AUTO_SYNC_OFF = "0";
25
25
  const ROOT_ENV = "PO_ROOT";
26
26
  const SYNC_ARGS = ["sync", "--json"];
27
27
  const GLOBAL_OPTION = "--global";
28
+ const SKIP_ARTIFACT_BUILDS_OPTION = "--skip-artifact-builds";
28
29
  const CLI_ENTRY_SEGMENTS = [
29
30
  "dist",
30
31
  "bin",
@@ -72,11 +73,13 @@ function createBackgroundSync(options) {
72
73
  let child;
73
74
  try {
74
75
  const scope = options.repoRoot === void 0 ? [GLOBAL_OPTION] : [];
76
+ const skip = options.skipArtifactBuilds === true ? [SKIP_ARTIFACT_BUILDS_OPTION] : [];
75
77
  child = (options.spawn ?? spawn)(process.execPath, [
76
78
  ...process.execArgv,
77
79
  entry,
78
80
  ...SYNC_ARGS,
79
- ...scope
81
+ ...scope,
82
+ ...skip
80
83
  ], {
81
84
  ...options.repoRoot === void 0 ? {} : { cwd: options.repoRoot },
82
85
  env: {