@agimon-ai/po 0.0.0-alpha.22 → 0.0.0-alpha.24

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.
@@ -2,7 +2,7 @@
2
2
  "version": 1,
3
3
  "packages": {
4
4
  "@agimon-ai/po": {
5
- "version": "0.0.0-alpha.22",
5
+ "version": "0.0.0-alpha.24",
6
6
  "dependencies": [
7
7
  "@agimon-ai/po-artifact",
8
8
  "@agimon-ai/po-autostop",
@@ -24,7 +24,7 @@
24
24
  ]
25
25
  },
26
26
  "@agimon-ai/po-artifact": {
27
- "version": "0.0.0-alpha.20",
27
+ "version": "0.0.0-alpha.22",
28
28
  "dependencies": [
29
29
  "@agimon-ai/po-core",
30
30
  "@agimon-ai/po-web-components",
@@ -32,7 +32,7 @@
32
32
  ]
33
33
  },
34
34
  "@agimon-ai/po-author": {
35
- "version": "0.0.0-alpha.21",
35
+ "version": "0.0.0-alpha.23",
36
36
  "dependencies": [
37
37
  "@agimon-ai/po-artifact",
38
38
  "@agimon-ai/po-core",
@@ -42,7 +42,7 @@
42
42
  ]
43
43
  },
44
44
  "@agimon-ai/po-autocompact": {
45
- "version": "0.0.0-alpha.21",
45
+ "version": "0.0.0-alpha.23",
46
46
  "dependencies": [
47
47
  "@agimon-ai/po-artifact",
48
48
  "@agimon-ai/po-config",
@@ -51,25 +51,25 @@
51
51
  ]
52
52
  },
53
53
  "@agimon-ai/po-autostop": {
54
- "version": "0.0.0-alpha.21",
54
+ "version": "0.0.0-alpha.23",
55
55
  "dependencies": [
56
56
  "@agimon-ai/po-core",
57
57
  "@agimon-ai/po-telemetry"
58
58
  ]
59
59
  },
60
60
  "@agimon-ai/po-browse": {
61
- "version": "0.0.1-alpha.19",
61
+ "version": "0.0.1-alpha.21",
62
62
  "dependencies": [
63
63
  "@agimon-ai/po-core",
64
64
  "@agimon-ai/po-web-components"
65
65
  ]
66
66
  },
67
67
  "@agimon-ai/po-build": {
68
- "version": "0.0.0-alpha.21",
68
+ "version": "0.0.0-alpha.23",
69
69
  "dependencies": []
70
70
  },
71
71
  "@agimon-ai/po-cache": {
72
- "version": "0.0.0-alpha.21",
72
+ "version": "0.0.0-alpha.23",
73
73
  "dependencies": [
74
74
  "@agimon-ai/po-config",
75
75
  "@agimon-ai/po-core",
@@ -77,11 +77,11 @@
77
77
  ]
78
78
  },
79
79
  "@agimon-ai/po-claude-bridge": {
80
- "version": "0.1.1-alpha.1",
80
+ "version": "0.1.1-alpha.3",
81
81
  "dependencies": []
82
82
  },
83
83
  "@agimon-ai/po-computer-use": {
84
- "version": "0.0.0-alpha.21",
84
+ "version": "0.0.0-alpha.23",
85
85
  "dependencies": [
86
86
  "@agimon-ai/po-config",
87
87
  "@agimon-ai/po-core",
@@ -91,7 +91,7 @@
91
91
  ]
92
92
  },
93
93
  "@agimon-ai/po-config": {
94
- "version": "0.0.0-alpha.21",
94
+ "version": "0.0.0-alpha.23",
95
95
  "dependencies": [
96
96
  "@agimon-ai/po-core",
97
97
  "@agimon-ai/po-telemetry",
@@ -99,14 +99,14 @@
99
99
  ]
100
100
  },
101
101
  "@agimon-ai/po-core": {
102
- "version": "0.0.0-alpha.21",
102
+ "version": "0.0.0-alpha.23",
103
103
  "dependencies": [
104
104
  "@agimon-ai/po-telemetry",
105
105
  "@agimon-ai/po-web-security"
106
106
  ]
107
107
  },
108
108
  "@agimon-ai/po-domain": {
109
- "version": "0.0.0-alpha.21",
109
+ "version": "0.0.0-alpha.23",
110
110
  "dependencies": [
111
111
  "@agimon-ai/po-config",
112
112
  "@agimon-ai/po-core",
@@ -115,7 +115,7 @@
115
115
  ]
116
116
  },
117
117
  "@agimon-ai/po-edit": {
118
- "version": "0.0.0-alpha.21",
118
+ "version": "0.0.0-alpha.23",
119
119
  "dependencies": [
120
120
  "@agimon-ai/po-core",
121
121
  "@agimon-ai/po-hashline",
@@ -124,7 +124,7 @@
124
124
  ]
125
125
  },
126
126
  "@agimon-ai/po-file-edit": {
127
- "version": "0.0.0-alpha.21",
127
+ "version": "0.0.0-alpha.23",
128
128
  "dependencies": [
129
129
  "@agimon-ai/po-config",
130
130
  "@agimon-ai/po-core",
@@ -135,7 +135,7 @@
135
135
  ]
136
136
  },
137
137
  "@agimon-ai/po-git": {
138
- "version": "0.0.0-alpha.21",
138
+ "version": "0.0.0-alpha.23",
139
139
  "dependencies": [
140
140
  "@agimon-ai/po-core",
141
141
  "@agimon-ai/po-session",
@@ -144,7 +144,7 @@
144
144
  ]
145
145
  },
146
146
  "@agimon-ai/po-goal": {
147
- "version": "0.0.0-alpha.21",
147
+ "version": "0.0.0-alpha.23",
148
148
  "dependencies": [
149
149
  "@agimon-ai/po-core",
150
150
  "@agimon-ai/po-minor-mode",
@@ -153,7 +153,7 @@
153
153
  ]
154
154
  },
155
155
  "@agimon-ai/po-grep": {
156
- "version": "0.0.0-alpha.21",
156
+ "version": "0.0.0-alpha.23",
157
157
  "dependencies": [
158
158
  "@agimon-ai/po-core",
159
159
  "@agimon-ai/po-hashline",
@@ -162,11 +162,11 @@
162
162
  ]
163
163
  },
164
164
  "@agimon-ai/po-hashline": {
165
- "version": "0.0.0-alpha.21",
165
+ "version": "0.0.0-alpha.23",
166
166
  "dependencies": []
167
167
  },
168
168
  "@agimon-ai/po-help": {
169
- "version": "0.0.0-alpha.21",
169
+ "version": "0.0.0-alpha.23",
170
170
  "dependencies": [
171
171
  "@agimon-ai/po-core",
172
172
  "@agimon-ai/po-minor-mode",
@@ -174,7 +174,7 @@
174
174
  ]
175
175
  },
176
176
  "@agimon-ai/po-hook": {
177
- "version": "0.0.0-alpha.21",
177
+ "version": "0.0.0-alpha.23",
178
178
  "dependencies": [
179
179
  "@agimon-ai/po-config",
180
180
  "@agimon-ai/po-core",
@@ -182,7 +182,7 @@
182
182
  ]
183
183
  },
184
184
  "@agimon-ai/po-image-gen": {
185
- "version": "0.0.0-alpha.20",
185
+ "version": "0.0.0-alpha.22",
186
186
  "dependencies": [
187
187
  "@agimon-ai/po-core",
188
188
  "@agimon-ai/po-web-components",
@@ -190,7 +190,7 @@
190
190
  ]
191
191
  },
192
192
  "@agimon-ai/po-log": {
193
- "version": "0.0.0-alpha.21",
193
+ "version": "0.0.0-alpha.23",
194
194
  "dependencies": [
195
195
  "@agimon-ai/po-core",
196
196
  "@agimon-ai/po-telemetry",
@@ -199,7 +199,7 @@
199
199
  ]
200
200
  },
201
201
  "@agimon-ai/po-loop": {
202
- "version": "0.0.0-alpha.21",
202
+ "version": "0.0.0-alpha.23",
203
203
  "dependencies": [
204
204
  "@agimon-ai/po-core",
205
205
  "@agimon-ai/po-minor-mode",
@@ -208,7 +208,7 @@
208
208
  ]
209
209
  },
210
210
  "@agimon-ai/po-major-mode": {
211
- "version": "0.0.0-alpha.21",
211
+ "version": "0.0.0-alpha.23",
212
212
  "dependencies": [
213
213
  "@agimon-ai/po-config",
214
214
  "@agimon-ai/po-core",
@@ -217,7 +217,7 @@
217
217
  ]
218
218
  },
219
219
  "@agimon-ai/po-mcp": {
220
- "version": "0.0.0-alpha.21",
220
+ "version": "0.0.0-alpha.23",
221
221
  "dependencies": [
222
222
  "@agimon-ai/po-config",
223
223
  "@agimon-ai/po-core",
@@ -227,37 +227,37 @@
227
227
  ]
228
228
  },
229
229
  "@agimon-ai/po-mcp-proxy": {
230
- "version": "0.0.1-alpha.0",
230
+ "version": "0.0.1-alpha.2",
231
231
  "dependencies": []
232
232
  },
233
233
  "@agimon-ai/po-minor-mode": {
234
- "version": "0.0.0-alpha.21",
234
+ "version": "0.0.0-alpha.23",
235
235
  "dependencies": [
236
236
  "@agimon-ai/po-core",
237
237
  "@agimon-ai/po-telemetry"
238
238
  ]
239
239
  },
240
240
  "@agimon-ai/po-model-guidance": {
241
- "version": "0.0.0-alpha.21",
241
+ "version": "0.0.0-alpha.23",
242
242
  "dependencies": [
243
243
  "@agimon-ai/po-config",
244
244
  "@agimon-ai/po-core"
245
245
  ]
246
246
  },
247
247
  "@agimon-ai/po-native-components": {
248
- "version": "0.0.0-alpha.21",
248
+ "version": "0.0.0-alpha.23",
249
249
  "dependencies": [
250
250
  "@agimon-ai/po-web-components"
251
251
  ]
252
252
  },
253
253
  "@agimon-ai/po-notification": {
254
- "version": "0.0.0-alpha.21",
254
+ "version": "0.0.0-alpha.23",
255
255
  "dependencies": [
256
256
  "@agimon-ai/po-core"
257
257
  ]
258
258
  },
259
259
  "@agimon-ai/po-plan": {
260
- "version": "0.0.0-alpha.21",
260
+ "version": "0.0.0-alpha.23",
261
261
  "dependencies": [
262
262
  "@agimon-ai/po-config",
263
263
  "@agimon-ai/po-core",
@@ -268,7 +268,7 @@
268
268
  ]
269
269
  },
270
270
  "@agimon-ai/po-profile": {
271
- "version": "0.0.0-alpha.21",
271
+ "version": "0.0.0-alpha.23",
272
272
  "dependencies": [
273
273
  "@agimon-ai/po-config",
274
274
  "@agimon-ai/po-core",
@@ -277,7 +277,7 @@
277
277
  ]
278
278
  },
279
279
  "@agimon-ai/po-prompt": {
280
- "version": "0.0.0-alpha.21",
280
+ "version": "0.0.0-alpha.23",
281
281
  "dependencies": [
282
282
  "@agimon-ai/po-core",
283
283
  "@agimon-ai/po-web-components",
@@ -285,7 +285,7 @@
285
285
  ]
286
286
  },
287
287
  "@agimon-ai/po-read": {
288
- "version": "0.0.0-alpha.21",
288
+ "version": "0.0.0-alpha.23",
289
289
  "dependencies": [
290
290
  "@agimon-ai/po-config",
291
291
  "@agimon-ai/po-core",
@@ -295,7 +295,7 @@
295
295
  ]
296
296
  },
297
297
  "@agimon-ai/po-runner": {
298
- "version": "0.0.0-alpha.21",
298
+ "version": "0.0.0-alpha.23",
299
299
  "dependencies": [
300
300
  "@agimon-ai/po-core",
301
301
  "@agimon-ai/po-telemetry",
@@ -305,19 +305,19 @@
305
305
  ]
306
306
  },
307
307
  "@agimon-ai/po-sandbox": {
308
- "version": "0.0.0-alpha.21",
308
+ "version": "0.0.0-alpha.23",
309
309
  "dependencies": [
310
310
  "@agimon-ai/po-core"
311
311
  ]
312
312
  },
313
313
  "@agimon-ai/po-session": {
314
- "version": "0.0.0-alpha.21",
314
+ "version": "0.0.0-alpha.23",
315
315
  "dependencies": [
316
316
  "@agimon-ai/po-core"
317
317
  ]
318
318
  },
319
319
  "@agimon-ai/po-skill": {
320
- "version": "0.0.0-alpha.21",
320
+ "version": "0.0.0-alpha.23",
321
321
  "dependencies": [
322
322
  "@agimon-ai/po-config",
323
323
  "@agimon-ai/po-core",
@@ -327,7 +327,7 @@
327
327
  ]
328
328
  },
329
329
  "@agimon-ai/po-style-system": {
330
- "version": "0.0.0-alpha.21",
330
+ "version": "0.0.0-alpha.23",
331
331
  "dependencies": [
332
332
  "@agimon-ai/po-core",
333
333
  "@agimon-ai/po-web-components",
@@ -335,7 +335,7 @@
335
335
  ]
336
336
  },
337
337
  "@agimon-ai/po-task": {
338
- "version": "0.0.0-alpha.21",
338
+ "version": "0.0.0-alpha.23",
339
339
  "dependencies": [
340
340
  "@agimon-ai/po-core",
341
341
  "@agimon-ai/po-telemetry",
@@ -344,7 +344,7 @@
344
344
  ]
345
345
  },
346
346
  "@agimon-ai/po-team": {
347
- "version": "0.0.0-alpha.21",
347
+ "version": "0.0.0-alpha.23",
348
348
  "dependencies": [
349
349
  "@agimon-ai/po-cache",
350
350
  "@agimon-ai/po-config",
@@ -357,11 +357,11 @@
357
357
  ]
358
358
  },
359
359
  "@agimon-ai/po-telemetry": {
360
- "version": "0.0.0-alpha.21",
360
+ "version": "0.0.0-alpha.23",
361
361
  "dependencies": []
362
362
  },
363
363
  "@agimon-ai/po-template-advanced": {
364
- "version": "0.0.0-alpha.21",
364
+ "version": "0.0.0-alpha.23",
365
365
  "dependencies": [
366
366
  "@agimon-ai/po-core",
367
367
  "@agimon-ai/po-web-components",
@@ -369,7 +369,7 @@
369
369
  ]
370
370
  },
371
371
  "@agimon-ai/po-template-elegant": {
372
- "version": "0.0.0-alpha.21",
372
+ "version": "0.0.0-alpha.23",
373
373
  "dependencies": [
374
374
  "@agimon-ai/po-core",
375
375
  "@agimon-ai/po-web-components",
@@ -377,7 +377,7 @@
377
377
  ]
378
378
  },
379
379
  "@agimon-ai/po-ui": {
380
- "version": "0.0.0-alpha.21",
380
+ "version": "0.0.0-alpha.23",
381
381
  "dependencies": [
382
382
  "@agimon-ai/po-core",
383
383
  "@agimon-ai/po-hashline",
@@ -387,15 +387,16 @@
387
387
  ]
388
388
  },
389
389
  "@agimon-ai/po-user-feedback": {
390
- "version": "0.0.0-alpha.21",
390
+ "version": "0.0.0-alpha.23",
391
391
  "dependencies": [
392
392
  "@agimon-ai/po-core",
393
393
  "@agimon-ai/po-minor-mode",
394
- "@agimon-ai/po-web-components"
394
+ "@agimon-ai/po-web-components",
395
+ "@agimon-ai/po-web-security"
395
396
  ]
396
397
  },
397
398
  "@agimon-ai/po-voice": {
398
- "version": "0.0.0-alpha.21",
399
+ "version": "0.0.0-alpha.23",
399
400
  "dependencies": [
400
401
  "@agimon-ai/po-config",
401
402
  "@agimon-ai/po-core",
@@ -408,11 +409,11 @@
408
409
  ]
409
410
  },
410
411
  "@agimon-ai/po-web-components": {
411
- "version": "0.0.0-alpha.21",
412
+ "version": "0.0.0-alpha.23",
412
413
  "dependencies": []
413
414
  },
414
415
  "@agimon-ai/po-web-dashboard": {
415
- "version": "0.0.0-alpha.21",
416
+ "version": "0.0.0-alpha.23",
416
417
  "dependencies": [
417
418
  "@agimon-ai/po-core",
418
419
  "@agimon-ai/po-web-components",
@@ -420,18 +421,18 @@
420
421
  ]
421
422
  },
422
423
  "@agimon-ai/po-web-search": {
423
- "version": "0.0.0-alpha.20",
424
+ "version": "0.0.0-alpha.22",
424
425
  "dependencies": [
425
426
  "@agimon-ai/po-core",
426
427
  "@agimon-ai/po-web-components"
427
428
  ]
428
429
  },
429
430
  "@agimon-ai/po-web-security": {
430
- "version": "0.0.0-alpha.21",
431
+ "version": "0.0.0-alpha.23",
431
432
  "dependencies": []
432
433
  },
433
434
  "@agimon-ai/po-workflow": {
434
- "version": "0.0.0-alpha.21",
435
+ "version": "0.0.0-alpha.23",
435
436
  "dependencies": [
436
437
  "@agimon-ai/po-core",
437
438
  "@agimon-ai/po-minor-mode",
@@ -11,6 +11,7 @@ let _agimon_ai_po_config_config = require("@agimon-ai/po-config/config");
11
11
  let _agimon_ai_po_config_majorModes = require("@agimon-ai/po-config/majorModes");
12
12
  let _agimon_ai_po_config_profiles = require("@agimon-ai/po-config/profiles");
13
13
  let _agimon_ai_po_core_runtimeLogSinkTelemetry = require("@agimon-ai/po-core/runtimeLogSinkTelemetry");
14
+ let _agimon_ai_po_core_mcpProjection = require("@agimon-ai/po-core/mcpProjection");
14
15
  let _agimon_ai_po_domain_mcp = require("@agimon-ai/po-domain/mcp");
15
16
  let _agimon_ai_po_domain_plugins = require("@agimon-ai/po-domain/plugins");
16
17
  let _agimon_ai_po_domain_resources = require("@agimon-ai/po-domain/resources");
@@ -84,7 +85,8 @@ async function buildHarnessContext(options, telemetry = (0, _agimon_ai_po_core_r
84
85
  skillCacheDirectory: options.resourceDirectory === void 0 ? node_path.default.join((0, _agimon_ai_po_config_config.globalPoConfigDirectory)(options.homeDirectory ?? node_os.default.homedir()), "cache", "skills", node_crypto.default.createHash("sha256").update(node_path.default.resolve(options.repoRoot)).digest("hex").slice(0, 32)) : node_path.default.join(options.resourceDirectory, "cache", "skills"),
85
86
  mcpAllowlist,
86
87
  sharedSkills: configured.sharedSkills,
87
- pluginDataRoot: node_path.default.join((0, _agimon_ai_po_config_config.globalPoConfigDirectory)(options.homeDirectory ?? node_os.default.homedir()), "plugin-data")
88
+ pluginDataRoot: node_path.default.join((0, _agimon_ai_po_config_config.globalPoConfigDirectory)(options.homeDirectory ?? node_os.default.homedir()), "plugin-data"),
89
+ userMcpConfigPath: node_path.default.join((0, _agimon_ai_po_config_config.globalPoConfigDirectory)(options.homeDirectory ?? node_os.default.homedir()), _agimon_ai_po_core_mcpProjection.PO_USER_MCP_CONFIG_FILE)
88
90
  })).catch(async (error) => {
89
91
  await telemetry.recordError(_agimon_ai_po_core_runtimeLogSinkTelemetry.HARNESS_EVENT.resourceCollectionFailed, error, {
90
92
  "harness.phase": COLLECT_RESOURCES_PHASE,
@@ -1 +1 @@
1
- {"version":3,"file":"harnessContext.cjs","names":["resolveProfile","createHarnessTelemetry","loadMajorModesConfig","filterHookDisabledLayers","resolveLayers","fs","layerHookGroups","materializePluginEntries","resolvePluginEntries","resolveMcpAllowlist","resolveSharedSkills","HARNESS_EVENT","collectResources","path","globalPoConfigDirectory","os","crypto","writeDefaultTheme","PO_MCP_SESSION_ENV_VAR","applyProfileEnvironment","DEFAULT_THEME_NAME","buildPersonaPrompt"],"sources":["../../../../src/builders/cli/harnessContext.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalPoConfigDirectory } from '@agimon-ai/po-config/config';\nimport { resolvePluginEntries, resolveSharedSkills } from '@agimon-ai/po-config/domains';\nimport type { DomainMcpAllowlist, PluginEntry } from '@agimon-ai/po-config/domains';\nimport {\n filterHookDisabledLayers,\n layerHookGroups,\n loadMajorModesConfig,\n resolveLayers,\n} from '@agimon-ai/po-config/majorModes';\nimport type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport { applyProfileEnvironment, buildPersonaPrompt, resolveProfile } from '@agimon-ai/po-config/profiles';\nimport type { AgentProfile } from '@agimon-ai/po-config/profiles';\nimport { PO_MCP_SESSION_ENV_VAR } from '@agimon-ai/po-core/mcpSession';\nimport {\n createHarnessTelemetry,\n HARNESS_EVENT,\n type HarnessTelemetry,\n} from '@agimon-ai/po-core/runtimeLogSinkTelemetry';\nimport { resolveMcpAllowlist } from '@agimon-ai/po-domain/mcp';\nimport { materializePluginEntries } from '@agimon-ai/po-domain/plugins';\nimport { collectResources, type HarnessResources } from '@agimon-ai/po-domain/resources';\nimport { DEFAULT_THEME_NAME, writeDefaultTheme } from '@agimon-ai/po-ui/theme';\n\nimport { createHarnessSession } from '../../composition/harnessState';\nimport type { HarnessOptions } from '../../composition/types/harness';\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst RESOLVE_CONFIG_PHASE = 'resolve_config';\nconst COLLECT_RESOURCES_PHASE = 'collect_resources';\nconst BUILD_CONTEXT_PHASE = 'build_context';\n\n/**\n * Everything a command needs, resolved once.\n *\n * All three commands need the same expensive preparation (domains resolved,\n * plugins collected into a temp directory, environment assembled), so it is\n * built here and handed to whichever command runs.\n */\nexport interface HarnessContext {\n options: HarnessOptions;\n environment: NodeJS.ProcessEnv;\n resources: HarnessResources;\n plugins: PluginEntry[];\n profile?: string;\n personaDirectory?: string;\n /** Root personaDirectory resolves against, when a profile supplied one. */\n personaRoot?: string;\n mcpAllowlist?: DomainMcpAllowlist;\n majorModesConfig: MajorModesConfig;\n selectedLayers: string[];\n hookGroups: string[];\n defaultThemePath: string;\n cleanup(): Promise<void>;\n}\n\n/**\n * Applies the provider environment a preset needs.\n *\n * Exported so a session server can apply the same rules before anything reads them.\n */\nexport function configurePreset(\n options: Pick<HarnessOptions, 'preset' | 'piArgs'>,\n environment: NodeJS.ProcessEnv,\n): void {\n if (options.preset === 'kimi') {\n if (!environment.KIMI_API_KEY && environment.KIMI_CODE_API_KEY) {\n environment.KIMI_API_KEY = environment.KIMI_CODE_API_KEY;\n }\n if (!environment.KIMI_API_KEY) {\n throw new Error('KIMI_API_KEY or KIMI_CODE_API_KEY is required for the kimi preset');\n }\n }\n}\n\n/** Resolves the optional persona and environment profile selected for this run. */\nexport function resolveHarnessProfile(options: HarnessOptions): AgentProfile | undefined {\n return options.profile ? resolveProfile(options.configRoot ?? options.repoRoot, options.profile) : undefined;\n}\n\n/**\n * Resolves the full matrix and stages every resource Pi will need.\n *\n * The caller owns the returned cleanup(): the temporary directory holding\n * skills, agents, and the generated MCP config has to outlive this function\n * and be removed once the selected command is done with it.\n */\nexport async function buildHarnessContext(\n options: HarnessOptions,\n telemetry: HarnessTelemetry = createHarnessTelemetry(),\n): Promise<HarnessContext> {\n // A worktree reads its workspace's configuration; resources still come from the checkout.\n const configRoot = options.configRoot ?? options.repoRoot;\n // Everything up to collectResources reads configuration off disk, so a single\n // malformed modes.yaml or profiles.yaml surfaces here as a failed launch\n // with no other record.\n const configured = await telemetry\n .runInSpan(`po_pi.${RESOLVE_CONFIG_PHASE}`, { 'harness.phase': RESOLVE_CONFIG_PHASE }, async () => {\n const majorModesConfig = loadMajorModesConfig(configRoot, options.homeDirectory, options.environment);\n const selectedLayers = filterHookDisabledLayers(\n majorModesConfig,\n resolveLayers(majorModesConfig, options.majorMode),\n options.hooks,\n );\n const profile = resolveHarnessProfile(options);\n if (!fs.existsSync(options.cwd) || !fs.statSync(options.cwd).isDirectory()) {\n throw new Error(`Working directory does not exist: ${options.cwd}`);\n }\n return {\n majorModesConfig,\n selectedLayers,\n hookGroups: layerHookGroups(majorModesConfig, selectedLayers),\n profile,\n plugins: await materializePluginEntries(\n resolvePluginEntries(configRoot, options.domains, options.pluginDirectories),\n ),\n mcpAllowlist: resolveMcpAllowlist(configRoot, options.domains),\n sharedSkills: resolveSharedSkills(configRoot, options.domains),\n };\n })\n .catch(async (error: unknown) => {\n await telemetry.recordError(HARNESS_EVENT.configLoadFailed, error, {\n 'harness.phase': RESOLVE_CONFIG_PHASE,\n 'harness.major_mode': options.majorMode,\n 'harness.domain_count': options.domains.length,\n });\n throw error;\n });\n\n const { majorModesConfig, selectedLayers, hookGroups, profile, plugins, mcpAllowlist } = configured;\n const personaDirectory = profile?.persona;\n // A global profile's persona lives beside the global config, not in the repo.\n const personaRoot = profile?.personaRoot ?? configRoot;\n const resources = await telemetry\n .runInSpan(\n `po_pi.${COLLECT_RESOURCES_PHASE}`,\n { 'harness.plugin.count': plugins.length, 'harness.agents': options.agents, 'harness.mcp': options.mcp },\n () =>\n collectResources(options.repoRoot, plugins, {\n agents: options.agents,\n mcp: options.mcp,\n // Set by a caller that stages into a directory it owns.\n temporaryDirectory: options.resourceDirectory,\n // Per repository, under the global home, so it outlives this process's resources.\n skillCacheDirectory:\n options.resourceDirectory === undefined\n ? path.join(\n globalPoConfigDirectory(options.homeDirectory ?? os.homedir()),\n 'cache',\n 'skills',\n crypto.createHash('sha256').update(path.resolve(options.repoRoot)).digest('hex').slice(0, 32),\n )\n : path.join(options.resourceDirectory, 'cache', 'skills'),\n mcpAllowlist,\n sharedSkills: configured.sharedSkills,\n pluginDataRoot: path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), 'plugin-data'),\n }),\n )\n .catch(async (error: unknown) => {\n // Conflicting skills, agents, or MCP servers all fail here, and the plugin\n // that caused it is only identifiable from the message.\n await telemetry.recordError(HARNESS_EVENT.resourceCollectionFailed, error, {\n 'harness.phase': COLLECT_RESOURCES_PHASE,\n 'harness.plugin.count': plugins.length,\n });\n throw error;\n });\n\n try {\n const defaultThemePath = await writeDefaultTheme(resources.temporaryDirectory);\n const environment = { ...(options.environment ?? process.env) };\n // The file-backed projection published through Cordis is authoritative.\n // Never let a legacy parent-process projection leak into this Po session.\n delete environment[PO_MCP_SESSION_ENV_VAR];\n const profileEnvironment = applyProfileEnvironment(environment, profile?.env ?? {});\n\n configurePreset(options, environment);\n environment.NX_DAEMON ??= 'false';\n environment.PO_THEME ||= DEFAULT_THEME_NAME;\n environment.CLAUDE_PROJECT_DIR = options.repoRoot;\n environment.CODEX_REPO_ROOT = options.repoRoot;\n environment.ORIGINAL_REPO_PATH ||= options.repoRoot;\n environment.MCP_UI_VIEWER = options.automation ? 'none' : (environment.MCP_UI_VIEWER ?? '');\n\n const personaPrompt = personaDirectory ? buildPersonaPrompt(personaRoot, personaDirectory) : undefined;\n let personaFile: string | undefined;\n if (personaPrompt) {\n personaFile = path.join(resources.temporaryDirectory, 'persona.md');\n await fs.promises.writeFile(personaFile, `${personaPrompt}\\n`, { mode: PRIVATE_FILE_MODE });\n }\n\n // One write, describing the child rather than this process. The state file\n // is the child's authority and the environment is what it projects for the\n // hooks and packages that can only read an environment.\n createHarnessSession(\n {\n root: options.repoRoot,\n majorMode: options.majorMode,\n temporaryDirectory: resources.temporaryDirectory,\n domains: options.domains,\n layers: selectedLayers,\n profile: profile?.name,\n profileIdentity: profile?.identity,\n profileVoice: profile?.voice,\n profileEnvironment,\n personaFile,\n skillDirectories: resources.skillDirectories,\n agentDirectories: resources.agentDirectories,\n additionalDirectories: options.additionalDirectories,\n childExtensions: [],\n pluginDirectories: options.pluginDirectories,\n pluginHooks: resources.pluginHooks,\n hookGroups,\n hooks: options.hooks,\n agents: options.agents,\n mcp: options.mcp,\n mcpConfigPath: resources.mcpConfigPath,\n mcpProjection: resources.mcpProjection,\n allowProtectedWrites: options.allowProtectedWrites,\n },\n { directory: resources.temporaryDirectory, environment },\n );\n if (options.agents) {\n environment.PI_SUBAGENT_EXTRA_AGENT_DIRS = resources.agentDirectories.join(path.delimiter);\n environment.PI_SUBAGENT_EXTRA_SKILL_DIRS = resources.skillDirectories.join(path.delimiter);\n }\n\n // Core hook groups load regardless; hookGroups selects the rest. The initial\n // state write includes an empty list deliberately: unset means every group.\n\n return {\n options,\n environment,\n resources,\n plugins,\n profile: profile?.name,\n personaDirectory,\n personaRoot,\n mcpAllowlist,\n majorModesConfig,\n selectedLayers,\n hookGroups,\n defaultThemePath,\n cleanup: resources.cleanup.bind(resources),\n };\n } catch (error) {\n // Preparation failed after the temp directory existed, so nothing will be\n // handed back to clean it up.\n await telemetry.recordError(HARNESS_EVENT.contextBuildFailed, error, {\n 'harness.phase': BUILD_CONTEXT_PHASE,\n 'harness.major_mode': options.majorMode,\n ...(profile?.name ? { 'harness.profile': profile.name } : {}),\n });\n await resources.cleanup();\n throw error;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"harnessContext.cjs","names":["resolveProfile","createHarnessTelemetry","loadMajorModesConfig","filterHookDisabledLayers","resolveLayers","fs","layerHookGroups","materializePluginEntries","resolvePluginEntries","resolveMcpAllowlist","resolveSharedSkills","HARNESS_EVENT","collectResources","path","globalPoConfigDirectory","os","crypto","PO_USER_MCP_CONFIG_FILE","writeDefaultTheme","PO_MCP_SESSION_ENV_VAR","applyProfileEnvironment","DEFAULT_THEME_NAME","buildPersonaPrompt"],"sources":["../../../../src/builders/cli/harnessContext.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalPoConfigDirectory } from '@agimon-ai/po-config/config';\nimport { resolvePluginEntries, resolveSharedSkills } from '@agimon-ai/po-config/domains';\nimport type { DomainMcpAllowlist, PluginEntry } from '@agimon-ai/po-config/domains';\nimport {\n filterHookDisabledLayers,\n layerHookGroups,\n loadMajorModesConfig,\n resolveLayers,\n} from '@agimon-ai/po-config/majorModes';\nimport type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport { applyProfileEnvironment, buildPersonaPrompt, resolveProfile } from '@agimon-ai/po-config/profiles';\nimport type { AgentProfile } from '@agimon-ai/po-config/profiles';\nimport { PO_USER_MCP_CONFIG_FILE } from '@agimon-ai/po-core/mcpProjection';\nimport { PO_MCP_SESSION_ENV_VAR } from '@agimon-ai/po-core/mcpSession';\nimport {\n createHarnessTelemetry,\n HARNESS_EVENT,\n type HarnessTelemetry,\n} from '@agimon-ai/po-core/runtimeLogSinkTelemetry';\nimport { resolveMcpAllowlist } from '@agimon-ai/po-domain/mcp';\nimport { materializePluginEntries } from '@agimon-ai/po-domain/plugins';\nimport { collectResources, type HarnessResources } from '@agimon-ai/po-domain/resources';\nimport { DEFAULT_THEME_NAME, writeDefaultTheme } from '@agimon-ai/po-ui/theme';\n\nimport { createHarnessSession } from '../../composition/harnessState';\nimport type { HarnessOptions } from '../../composition/types/harness';\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst RESOLVE_CONFIG_PHASE = 'resolve_config';\nconst COLLECT_RESOURCES_PHASE = 'collect_resources';\nconst BUILD_CONTEXT_PHASE = 'build_context';\n\n/**\n * Everything a command needs, resolved once.\n *\n * All three commands need the same expensive preparation (domains resolved,\n * plugins collected into a temp directory, environment assembled), so it is\n * built here and handed to whichever command runs.\n */\nexport interface HarnessContext {\n options: HarnessOptions;\n environment: NodeJS.ProcessEnv;\n resources: HarnessResources;\n plugins: PluginEntry[];\n profile?: string;\n personaDirectory?: string;\n /** Root personaDirectory resolves against, when a profile supplied one. */\n personaRoot?: string;\n mcpAllowlist?: DomainMcpAllowlist;\n majorModesConfig: MajorModesConfig;\n selectedLayers: string[];\n hookGroups: string[];\n defaultThemePath: string;\n cleanup(): Promise<void>;\n}\n\n/**\n * Applies the provider environment a preset needs.\n *\n * Exported so a session server can apply the same rules before anything reads them.\n */\nexport function configurePreset(\n options: Pick<HarnessOptions, 'preset' | 'piArgs'>,\n environment: NodeJS.ProcessEnv,\n): void {\n if (options.preset === 'kimi') {\n if (!environment.KIMI_API_KEY && environment.KIMI_CODE_API_KEY) {\n environment.KIMI_API_KEY = environment.KIMI_CODE_API_KEY;\n }\n if (!environment.KIMI_API_KEY) {\n throw new Error('KIMI_API_KEY or KIMI_CODE_API_KEY is required for the kimi preset');\n }\n }\n}\n\n/** Resolves the optional persona and environment profile selected for this run. */\nexport function resolveHarnessProfile(options: HarnessOptions): AgentProfile | undefined {\n return options.profile ? resolveProfile(options.configRoot ?? options.repoRoot, options.profile) : undefined;\n}\n\n/**\n * Resolves the full matrix and stages every resource Pi will need.\n *\n * The caller owns the returned cleanup(): the temporary directory holding\n * skills, agents, and the generated MCP config has to outlive this function\n * and be removed once the selected command is done with it.\n */\nexport async function buildHarnessContext(\n options: HarnessOptions,\n telemetry: HarnessTelemetry = createHarnessTelemetry(),\n): Promise<HarnessContext> {\n // A worktree reads its workspace's configuration; resources still come from the checkout.\n const configRoot = options.configRoot ?? options.repoRoot;\n // Everything up to collectResources reads configuration off disk, so a single\n // malformed modes.yaml or profiles.yaml surfaces here as a failed launch\n // with no other record.\n const configured = await telemetry\n .runInSpan(`po_pi.${RESOLVE_CONFIG_PHASE}`, { 'harness.phase': RESOLVE_CONFIG_PHASE }, async () => {\n const majorModesConfig = loadMajorModesConfig(configRoot, options.homeDirectory, options.environment);\n const selectedLayers = filterHookDisabledLayers(\n majorModesConfig,\n resolveLayers(majorModesConfig, options.majorMode),\n options.hooks,\n );\n const profile = resolveHarnessProfile(options);\n if (!fs.existsSync(options.cwd) || !fs.statSync(options.cwd).isDirectory()) {\n throw new Error(`Working directory does not exist: ${options.cwd}`);\n }\n return {\n majorModesConfig,\n selectedLayers,\n hookGroups: layerHookGroups(majorModesConfig, selectedLayers),\n profile,\n plugins: await materializePluginEntries(\n resolvePluginEntries(configRoot, options.domains, options.pluginDirectories),\n ),\n mcpAllowlist: resolveMcpAllowlist(configRoot, options.domains),\n sharedSkills: resolveSharedSkills(configRoot, options.domains),\n };\n })\n .catch(async (error: unknown) => {\n await telemetry.recordError(HARNESS_EVENT.configLoadFailed, error, {\n 'harness.phase': RESOLVE_CONFIG_PHASE,\n 'harness.major_mode': options.majorMode,\n 'harness.domain_count': options.domains.length,\n });\n throw error;\n });\n\n const { majorModesConfig, selectedLayers, hookGroups, profile, plugins, mcpAllowlist } = configured;\n const personaDirectory = profile?.persona;\n // A global profile's persona lives beside the global config, not in the repo.\n const personaRoot = profile?.personaRoot ?? configRoot;\n const resources = await telemetry\n .runInSpan(\n `po_pi.${COLLECT_RESOURCES_PHASE}`,\n { 'harness.plugin.count': plugins.length, 'harness.agents': options.agents, 'harness.mcp': options.mcp },\n () =>\n collectResources(options.repoRoot, plugins, {\n agents: options.agents,\n mcp: options.mcp,\n // Set by a caller that stages into a directory it owns.\n temporaryDirectory: options.resourceDirectory,\n // Per repository, under the global home, so it outlives this process's resources.\n skillCacheDirectory:\n options.resourceDirectory === undefined\n ? path.join(\n globalPoConfigDirectory(options.homeDirectory ?? os.homedir()),\n 'cache',\n 'skills',\n crypto.createHash('sha256').update(path.resolve(options.repoRoot)).digest('hex').slice(0, 32),\n )\n : path.join(options.resourceDirectory, 'cache', 'skills'),\n mcpAllowlist,\n sharedSkills: configured.sharedSkills,\n pluginDataRoot: path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), 'plugin-data'),\n userMcpConfigPath: path.join(\n globalPoConfigDirectory(options.homeDirectory ?? os.homedir()),\n PO_USER_MCP_CONFIG_FILE,\n ),\n }),\n )\n .catch(async (error: unknown) => {\n // Conflicting skills, agents, or MCP servers all fail here, and the plugin\n // that caused it is only identifiable from the message.\n await telemetry.recordError(HARNESS_EVENT.resourceCollectionFailed, error, {\n 'harness.phase': COLLECT_RESOURCES_PHASE,\n 'harness.plugin.count': plugins.length,\n });\n throw error;\n });\n\n try {\n const defaultThemePath = await writeDefaultTheme(resources.temporaryDirectory);\n const environment = { ...(options.environment ?? process.env) };\n // The file-backed projection published through Cordis is authoritative.\n // Never let a legacy parent-process projection leak into this Po session.\n delete environment[PO_MCP_SESSION_ENV_VAR];\n const profileEnvironment = applyProfileEnvironment(environment, profile?.env ?? {});\n\n configurePreset(options, environment);\n environment.NX_DAEMON ??= 'false';\n environment.PO_THEME ||= DEFAULT_THEME_NAME;\n environment.CLAUDE_PROJECT_DIR = options.repoRoot;\n environment.CODEX_REPO_ROOT = options.repoRoot;\n environment.ORIGINAL_REPO_PATH ||= options.repoRoot;\n environment.MCP_UI_VIEWER = options.automation ? 'none' : (environment.MCP_UI_VIEWER ?? '');\n\n const personaPrompt = personaDirectory ? buildPersonaPrompt(personaRoot, personaDirectory) : undefined;\n let personaFile: string | undefined;\n if (personaPrompt) {\n personaFile = path.join(resources.temporaryDirectory, 'persona.md');\n await fs.promises.writeFile(personaFile, `${personaPrompt}\\n`, { mode: PRIVATE_FILE_MODE });\n }\n\n // One write, describing the child rather than this process. The state file\n // is the child's authority and the environment is what it projects for the\n // hooks and packages that can only read an environment.\n createHarnessSession(\n {\n root: options.repoRoot,\n majorMode: options.majorMode,\n temporaryDirectory: resources.temporaryDirectory,\n domains: options.domains,\n layers: selectedLayers,\n profile: profile?.name,\n profileIdentity: profile?.identity,\n profileVoice: profile?.voice,\n profileEnvironment,\n personaFile,\n skillDirectories: resources.skillDirectories,\n agentDirectories: resources.agentDirectories,\n additionalDirectories: options.additionalDirectories,\n childExtensions: [],\n pluginDirectories: options.pluginDirectories,\n pluginHooks: resources.pluginHooks,\n hookGroups,\n hooks: options.hooks,\n agents: options.agents,\n mcp: options.mcp,\n mcpConfigPath: resources.mcpConfigPath,\n mcpProjection: resources.mcpProjection,\n allowProtectedWrites: options.allowProtectedWrites,\n },\n { directory: resources.temporaryDirectory, environment },\n );\n if (options.agents) {\n environment.PI_SUBAGENT_EXTRA_AGENT_DIRS = resources.agentDirectories.join(path.delimiter);\n environment.PI_SUBAGENT_EXTRA_SKILL_DIRS = resources.skillDirectories.join(path.delimiter);\n }\n\n // Core hook groups load regardless; hookGroups selects the rest. The initial\n // state write includes an empty list deliberately: unset means every group.\n\n return {\n options,\n environment,\n resources,\n plugins,\n profile: profile?.name,\n personaDirectory,\n personaRoot,\n mcpAllowlist,\n majorModesConfig,\n selectedLayers,\n hookGroups,\n defaultThemePath,\n cleanup: resources.cleanup.bind(resources),\n };\n } catch (error) {\n // Preparation failed after the temp directory existed, so nothing will be\n // handed back to clean it up.\n await telemetry.recordError(HARNESS_EVENT.contextBuildFailed, error, {\n 'harness.phase': BUILD_CONTEXT_PHASE,\n 'harness.major_mode': options.majorMode,\n ...(profile?.name ? { 'harness.profile': profile.name } : {}),\n });\n await resources.cleanup();\n throw error;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"harnessContext.d.mts","names":[],"sources":["../../../../src/builders/cli/harnessContext.ts"],"mappings":";;;;;;;;;;;;;;iBA2CiB;EACf,SAAS;EACT,aAAa,OAAO;EACpB,WAAW;EACX,SAAS;EACT;EACA;;EAEA;EACA,eAAe;EACf,kBAAkB;EAClB;EACA;EACA;EACA,WAAW;;;;;;;wBAQG,gBACd,SAAS,KAAK,sCACd,aAAa,OAAO;;wBAaN,sBAAsB,SAAS,iBAAiB;;;;;;;;wBAW1C,oBACpB,SAAS,gBACT,YAAW,mBACV,QAAQ"}
1
+ {"version":3,"file":"harnessContext.d.mts","names":[],"sources":["../../../../src/builders/cli/harnessContext.ts"],"mappings":";;;;;;;;;;;;;;iBA4CiB;EACf,SAAS;EACT,aAAa,OAAO;EACpB,WAAW;EACX,SAAS;EACT;EACA;;EAEA;EACA,eAAe;EACf,kBAAkB;EAClB;EACA;EACA;EACA,WAAW;;;;;;;wBAQG,gBACd,SAAS,KAAK,sCACd,aAAa,OAAO;;wBAaN,sBAAsB,SAAS,iBAAiB;;;;;;;;wBAW1C,oBACpB,SAAS,gBACT,YAAW,mBACV,QAAQ"}
@@ -7,6 +7,7 @@ import { globalPoConfigDirectory } from "@agimon-ai/po-config/config";
7
7
  import { filterHookDisabledLayers, layerHookGroups, loadMajorModesConfig, resolveLayers } from "@agimon-ai/po-config/majorModes";
8
8
  import { applyProfileEnvironment, buildPersonaPrompt, resolveProfile } from "@agimon-ai/po-config/profiles";
9
9
  import { HARNESS_EVENT, createHarnessTelemetry } from "@agimon-ai/po-core/runtimeLogSinkTelemetry";
10
+ import { PO_USER_MCP_CONFIG_FILE } from "@agimon-ai/po-core/mcpProjection";
10
11
  import { resolveMcpAllowlist } from "@agimon-ai/po-domain/mcp";
11
12
  import { materializePluginEntries } from "@agimon-ai/po-domain/plugins";
12
13
  import { collectResources } from "@agimon-ai/po-domain/resources";
@@ -78,7 +79,8 @@ async function buildHarnessContext(options, telemetry = createHarnessTelemetry()
78
79
  skillCacheDirectory: options.resourceDirectory === void 0 ? path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), "cache", "skills", crypto.createHash("sha256").update(path.resolve(options.repoRoot)).digest("hex").slice(0, 32)) : path.join(options.resourceDirectory, "cache", "skills"),
79
80
  mcpAllowlist,
80
81
  sharedSkills: configured.sharedSkills,
81
- pluginDataRoot: path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), "plugin-data")
82
+ pluginDataRoot: path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), "plugin-data"),
83
+ userMcpConfigPath: path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), PO_USER_MCP_CONFIG_FILE)
82
84
  })).catch(async (error) => {
83
85
  await telemetry.recordError(HARNESS_EVENT.resourceCollectionFailed, error, {
84
86
  "harness.phase": COLLECT_RESOURCES_PHASE,
@@ -1 +1 @@
1
- {"version":3,"file":"harnessContext.mjs","names":[],"sources":["../../../../src/builders/cli/harnessContext.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalPoConfigDirectory } from '@agimon-ai/po-config/config';\nimport { resolvePluginEntries, resolveSharedSkills } from '@agimon-ai/po-config/domains';\nimport type { DomainMcpAllowlist, PluginEntry } from '@agimon-ai/po-config/domains';\nimport {\n filterHookDisabledLayers,\n layerHookGroups,\n loadMajorModesConfig,\n resolveLayers,\n} from '@agimon-ai/po-config/majorModes';\nimport type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport { applyProfileEnvironment, buildPersonaPrompt, resolveProfile } from '@agimon-ai/po-config/profiles';\nimport type { AgentProfile } from '@agimon-ai/po-config/profiles';\nimport { PO_MCP_SESSION_ENV_VAR } from '@agimon-ai/po-core/mcpSession';\nimport {\n createHarnessTelemetry,\n HARNESS_EVENT,\n type HarnessTelemetry,\n} from '@agimon-ai/po-core/runtimeLogSinkTelemetry';\nimport { resolveMcpAllowlist } from '@agimon-ai/po-domain/mcp';\nimport { materializePluginEntries } from '@agimon-ai/po-domain/plugins';\nimport { collectResources, type HarnessResources } from '@agimon-ai/po-domain/resources';\nimport { DEFAULT_THEME_NAME, writeDefaultTheme } from '@agimon-ai/po-ui/theme';\n\nimport { createHarnessSession } from '../../composition/harnessState';\nimport type { HarnessOptions } from '../../composition/types/harness';\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst RESOLVE_CONFIG_PHASE = 'resolve_config';\nconst COLLECT_RESOURCES_PHASE = 'collect_resources';\nconst BUILD_CONTEXT_PHASE = 'build_context';\n\n/**\n * Everything a command needs, resolved once.\n *\n * All three commands need the same expensive preparation (domains resolved,\n * plugins collected into a temp directory, environment assembled), so it is\n * built here and handed to whichever command runs.\n */\nexport interface HarnessContext {\n options: HarnessOptions;\n environment: NodeJS.ProcessEnv;\n resources: HarnessResources;\n plugins: PluginEntry[];\n profile?: string;\n personaDirectory?: string;\n /** Root personaDirectory resolves against, when a profile supplied one. */\n personaRoot?: string;\n mcpAllowlist?: DomainMcpAllowlist;\n majorModesConfig: MajorModesConfig;\n selectedLayers: string[];\n hookGroups: string[];\n defaultThemePath: string;\n cleanup(): Promise<void>;\n}\n\n/**\n * Applies the provider environment a preset needs.\n *\n * Exported so a session server can apply the same rules before anything reads them.\n */\nexport function configurePreset(\n options: Pick<HarnessOptions, 'preset' | 'piArgs'>,\n environment: NodeJS.ProcessEnv,\n): void {\n if (options.preset === 'kimi') {\n if (!environment.KIMI_API_KEY && environment.KIMI_CODE_API_KEY) {\n environment.KIMI_API_KEY = environment.KIMI_CODE_API_KEY;\n }\n if (!environment.KIMI_API_KEY) {\n throw new Error('KIMI_API_KEY or KIMI_CODE_API_KEY is required for the kimi preset');\n }\n }\n}\n\n/** Resolves the optional persona and environment profile selected for this run. */\nexport function resolveHarnessProfile(options: HarnessOptions): AgentProfile | undefined {\n return options.profile ? resolveProfile(options.configRoot ?? options.repoRoot, options.profile) : undefined;\n}\n\n/**\n * Resolves the full matrix and stages every resource Pi will need.\n *\n * The caller owns the returned cleanup(): the temporary directory holding\n * skills, agents, and the generated MCP config has to outlive this function\n * and be removed once the selected command is done with it.\n */\nexport async function buildHarnessContext(\n options: HarnessOptions,\n telemetry: HarnessTelemetry = createHarnessTelemetry(),\n): Promise<HarnessContext> {\n // A worktree reads its workspace's configuration; resources still come from the checkout.\n const configRoot = options.configRoot ?? options.repoRoot;\n // Everything up to collectResources reads configuration off disk, so a single\n // malformed modes.yaml or profiles.yaml surfaces here as a failed launch\n // with no other record.\n const configured = await telemetry\n .runInSpan(`po_pi.${RESOLVE_CONFIG_PHASE}`, { 'harness.phase': RESOLVE_CONFIG_PHASE }, async () => {\n const majorModesConfig = loadMajorModesConfig(configRoot, options.homeDirectory, options.environment);\n const selectedLayers = filterHookDisabledLayers(\n majorModesConfig,\n resolveLayers(majorModesConfig, options.majorMode),\n options.hooks,\n );\n const profile = resolveHarnessProfile(options);\n if (!fs.existsSync(options.cwd) || !fs.statSync(options.cwd).isDirectory()) {\n throw new Error(`Working directory does not exist: ${options.cwd}`);\n }\n return {\n majorModesConfig,\n selectedLayers,\n hookGroups: layerHookGroups(majorModesConfig, selectedLayers),\n profile,\n plugins: await materializePluginEntries(\n resolvePluginEntries(configRoot, options.domains, options.pluginDirectories),\n ),\n mcpAllowlist: resolveMcpAllowlist(configRoot, options.domains),\n sharedSkills: resolveSharedSkills(configRoot, options.domains),\n };\n })\n .catch(async (error: unknown) => {\n await telemetry.recordError(HARNESS_EVENT.configLoadFailed, error, {\n 'harness.phase': RESOLVE_CONFIG_PHASE,\n 'harness.major_mode': options.majorMode,\n 'harness.domain_count': options.domains.length,\n });\n throw error;\n });\n\n const { majorModesConfig, selectedLayers, hookGroups, profile, plugins, mcpAllowlist } = configured;\n const personaDirectory = profile?.persona;\n // A global profile's persona lives beside the global config, not in the repo.\n const personaRoot = profile?.personaRoot ?? configRoot;\n const resources = await telemetry\n .runInSpan(\n `po_pi.${COLLECT_RESOURCES_PHASE}`,\n { 'harness.plugin.count': plugins.length, 'harness.agents': options.agents, 'harness.mcp': options.mcp },\n () =>\n collectResources(options.repoRoot, plugins, {\n agents: options.agents,\n mcp: options.mcp,\n // Set by a caller that stages into a directory it owns.\n temporaryDirectory: options.resourceDirectory,\n // Per repository, under the global home, so it outlives this process's resources.\n skillCacheDirectory:\n options.resourceDirectory === undefined\n ? path.join(\n globalPoConfigDirectory(options.homeDirectory ?? os.homedir()),\n 'cache',\n 'skills',\n crypto.createHash('sha256').update(path.resolve(options.repoRoot)).digest('hex').slice(0, 32),\n )\n : path.join(options.resourceDirectory, 'cache', 'skills'),\n mcpAllowlist,\n sharedSkills: configured.sharedSkills,\n pluginDataRoot: path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), 'plugin-data'),\n }),\n )\n .catch(async (error: unknown) => {\n // Conflicting skills, agents, or MCP servers all fail here, and the plugin\n // that caused it is only identifiable from the message.\n await telemetry.recordError(HARNESS_EVENT.resourceCollectionFailed, error, {\n 'harness.phase': COLLECT_RESOURCES_PHASE,\n 'harness.plugin.count': plugins.length,\n });\n throw error;\n });\n\n try {\n const defaultThemePath = await writeDefaultTheme(resources.temporaryDirectory);\n const environment = { ...(options.environment ?? process.env) };\n // The file-backed projection published through Cordis is authoritative.\n // Never let a legacy parent-process projection leak into this Po session.\n delete environment[PO_MCP_SESSION_ENV_VAR];\n const profileEnvironment = applyProfileEnvironment(environment, profile?.env ?? {});\n\n configurePreset(options, environment);\n environment.NX_DAEMON ??= 'false';\n environment.PO_THEME ||= DEFAULT_THEME_NAME;\n environment.CLAUDE_PROJECT_DIR = options.repoRoot;\n environment.CODEX_REPO_ROOT = options.repoRoot;\n environment.ORIGINAL_REPO_PATH ||= options.repoRoot;\n environment.MCP_UI_VIEWER = options.automation ? 'none' : (environment.MCP_UI_VIEWER ?? '');\n\n const personaPrompt = personaDirectory ? buildPersonaPrompt(personaRoot, personaDirectory) : undefined;\n let personaFile: string | undefined;\n if (personaPrompt) {\n personaFile = path.join(resources.temporaryDirectory, 'persona.md');\n await fs.promises.writeFile(personaFile, `${personaPrompt}\\n`, { mode: PRIVATE_FILE_MODE });\n }\n\n // One write, describing the child rather than this process. The state file\n // is the child's authority and the environment is what it projects for the\n // hooks and packages that can only read an environment.\n createHarnessSession(\n {\n root: options.repoRoot,\n majorMode: options.majorMode,\n temporaryDirectory: resources.temporaryDirectory,\n domains: options.domains,\n layers: selectedLayers,\n profile: profile?.name,\n profileIdentity: profile?.identity,\n profileVoice: profile?.voice,\n profileEnvironment,\n personaFile,\n skillDirectories: resources.skillDirectories,\n agentDirectories: resources.agentDirectories,\n additionalDirectories: options.additionalDirectories,\n childExtensions: [],\n pluginDirectories: options.pluginDirectories,\n pluginHooks: resources.pluginHooks,\n hookGroups,\n hooks: options.hooks,\n agents: options.agents,\n mcp: options.mcp,\n mcpConfigPath: resources.mcpConfigPath,\n mcpProjection: resources.mcpProjection,\n allowProtectedWrites: options.allowProtectedWrites,\n },\n { directory: resources.temporaryDirectory, environment },\n );\n if (options.agents) {\n environment.PI_SUBAGENT_EXTRA_AGENT_DIRS = resources.agentDirectories.join(path.delimiter);\n environment.PI_SUBAGENT_EXTRA_SKILL_DIRS = resources.skillDirectories.join(path.delimiter);\n }\n\n // Core hook groups load regardless; hookGroups selects the rest. The initial\n // state write includes an empty list deliberately: unset means every group.\n\n return {\n options,\n environment,\n resources,\n plugins,\n profile: profile?.name,\n personaDirectory,\n personaRoot,\n mcpAllowlist,\n majorModesConfig,\n selectedLayers,\n hookGroups,\n defaultThemePath,\n cleanup: resources.cleanup.bind(resources),\n };\n } catch (error) {\n // Preparation failed after the temp directory existed, so nothing will be\n // handed back to clean it up.\n await telemetry.recordError(HARNESS_EVENT.contextBuildFailed, error, {\n 'harness.phase': BUILD_CONTEXT_PHASE,\n 'harness.major_mode': options.majorMode,\n ...(profile?.name ? { 'harness.profile': profile.name } : {}),\n });\n await resources.cleanup();\n throw error;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"harnessContext.mjs","names":[],"sources":["../../../../src/builders/cli/harnessContext.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalPoConfigDirectory } from '@agimon-ai/po-config/config';\nimport { resolvePluginEntries, resolveSharedSkills } from '@agimon-ai/po-config/domains';\nimport type { DomainMcpAllowlist, PluginEntry } from '@agimon-ai/po-config/domains';\nimport {\n filterHookDisabledLayers,\n layerHookGroups,\n loadMajorModesConfig,\n resolveLayers,\n} from '@agimon-ai/po-config/majorModes';\nimport type { MajorModesConfig } from '@agimon-ai/po-config/majorModes';\nimport { applyProfileEnvironment, buildPersonaPrompt, resolveProfile } from '@agimon-ai/po-config/profiles';\nimport type { AgentProfile } from '@agimon-ai/po-config/profiles';\nimport { PO_USER_MCP_CONFIG_FILE } from '@agimon-ai/po-core/mcpProjection';\nimport { PO_MCP_SESSION_ENV_VAR } from '@agimon-ai/po-core/mcpSession';\nimport {\n createHarnessTelemetry,\n HARNESS_EVENT,\n type HarnessTelemetry,\n} from '@agimon-ai/po-core/runtimeLogSinkTelemetry';\nimport { resolveMcpAllowlist } from '@agimon-ai/po-domain/mcp';\nimport { materializePluginEntries } from '@agimon-ai/po-domain/plugins';\nimport { collectResources, type HarnessResources } from '@agimon-ai/po-domain/resources';\nimport { DEFAULT_THEME_NAME, writeDefaultTheme } from '@agimon-ai/po-ui/theme';\n\nimport { createHarnessSession } from '../../composition/harnessState';\nimport type { HarnessOptions } from '../../composition/types/harness';\n\nconst PRIVATE_FILE_MODE = 0o600;\nconst RESOLVE_CONFIG_PHASE = 'resolve_config';\nconst COLLECT_RESOURCES_PHASE = 'collect_resources';\nconst BUILD_CONTEXT_PHASE = 'build_context';\n\n/**\n * Everything a command needs, resolved once.\n *\n * All three commands need the same expensive preparation (domains resolved,\n * plugins collected into a temp directory, environment assembled), so it is\n * built here and handed to whichever command runs.\n */\nexport interface HarnessContext {\n options: HarnessOptions;\n environment: NodeJS.ProcessEnv;\n resources: HarnessResources;\n plugins: PluginEntry[];\n profile?: string;\n personaDirectory?: string;\n /** Root personaDirectory resolves against, when a profile supplied one. */\n personaRoot?: string;\n mcpAllowlist?: DomainMcpAllowlist;\n majorModesConfig: MajorModesConfig;\n selectedLayers: string[];\n hookGroups: string[];\n defaultThemePath: string;\n cleanup(): Promise<void>;\n}\n\n/**\n * Applies the provider environment a preset needs.\n *\n * Exported so a session server can apply the same rules before anything reads them.\n */\nexport function configurePreset(\n options: Pick<HarnessOptions, 'preset' | 'piArgs'>,\n environment: NodeJS.ProcessEnv,\n): void {\n if (options.preset === 'kimi') {\n if (!environment.KIMI_API_KEY && environment.KIMI_CODE_API_KEY) {\n environment.KIMI_API_KEY = environment.KIMI_CODE_API_KEY;\n }\n if (!environment.KIMI_API_KEY) {\n throw new Error('KIMI_API_KEY or KIMI_CODE_API_KEY is required for the kimi preset');\n }\n }\n}\n\n/** Resolves the optional persona and environment profile selected for this run. */\nexport function resolveHarnessProfile(options: HarnessOptions): AgentProfile | undefined {\n return options.profile ? resolveProfile(options.configRoot ?? options.repoRoot, options.profile) : undefined;\n}\n\n/**\n * Resolves the full matrix and stages every resource Pi will need.\n *\n * The caller owns the returned cleanup(): the temporary directory holding\n * skills, agents, and the generated MCP config has to outlive this function\n * and be removed once the selected command is done with it.\n */\nexport async function buildHarnessContext(\n options: HarnessOptions,\n telemetry: HarnessTelemetry = createHarnessTelemetry(),\n): Promise<HarnessContext> {\n // A worktree reads its workspace's configuration; resources still come from the checkout.\n const configRoot = options.configRoot ?? options.repoRoot;\n // Everything up to collectResources reads configuration off disk, so a single\n // malformed modes.yaml or profiles.yaml surfaces here as a failed launch\n // with no other record.\n const configured = await telemetry\n .runInSpan(`po_pi.${RESOLVE_CONFIG_PHASE}`, { 'harness.phase': RESOLVE_CONFIG_PHASE }, async () => {\n const majorModesConfig = loadMajorModesConfig(configRoot, options.homeDirectory, options.environment);\n const selectedLayers = filterHookDisabledLayers(\n majorModesConfig,\n resolveLayers(majorModesConfig, options.majorMode),\n options.hooks,\n );\n const profile = resolveHarnessProfile(options);\n if (!fs.existsSync(options.cwd) || !fs.statSync(options.cwd).isDirectory()) {\n throw new Error(`Working directory does not exist: ${options.cwd}`);\n }\n return {\n majorModesConfig,\n selectedLayers,\n hookGroups: layerHookGroups(majorModesConfig, selectedLayers),\n profile,\n plugins: await materializePluginEntries(\n resolvePluginEntries(configRoot, options.domains, options.pluginDirectories),\n ),\n mcpAllowlist: resolveMcpAllowlist(configRoot, options.domains),\n sharedSkills: resolveSharedSkills(configRoot, options.domains),\n };\n })\n .catch(async (error: unknown) => {\n await telemetry.recordError(HARNESS_EVENT.configLoadFailed, error, {\n 'harness.phase': RESOLVE_CONFIG_PHASE,\n 'harness.major_mode': options.majorMode,\n 'harness.domain_count': options.domains.length,\n });\n throw error;\n });\n\n const { majorModesConfig, selectedLayers, hookGroups, profile, plugins, mcpAllowlist } = configured;\n const personaDirectory = profile?.persona;\n // A global profile's persona lives beside the global config, not in the repo.\n const personaRoot = profile?.personaRoot ?? configRoot;\n const resources = await telemetry\n .runInSpan(\n `po_pi.${COLLECT_RESOURCES_PHASE}`,\n { 'harness.plugin.count': plugins.length, 'harness.agents': options.agents, 'harness.mcp': options.mcp },\n () =>\n collectResources(options.repoRoot, plugins, {\n agents: options.agents,\n mcp: options.mcp,\n // Set by a caller that stages into a directory it owns.\n temporaryDirectory: options.resourceDirectory,\n // Per repository, under the global home, so it outlives this process's resources.\n skillCacheDirectory:\n options.resourceDirectory === undefined\n ? path.join(\n globalPoConfigDirectory(options.homeDirectory ?? os.homedir()),\n 'cache',\n 'skills',\n crypto.createHash('sha256').update(path.resolve(options.repoRoot)).digest('hex').slice(0, 32),\n )\n : path.join(options.resourceDirectory, 'cache', 'skills'),\n mcpAllowlist,\n sharedSkills: configured.sharedSkills,\n pluginDataRoot: path.join(globalPoConfigDirectory(options.homeDirectory ?? os.homedir()), 'plugin-data'),\n userMcpConfigPath: path.join(\n globalPoConfigDirectory(options.homeDirectory ?? os.homedir()),\n PO_USER_MCP_CONFIG_FILE,\n ),\n }),\n )\n .catch(async (error: unknown) => {\n // Conflicting skills, agents, or MCP servers all fail here, and the plugin\n // that caused it is only identifiable from the message.\n await telemetry.recordError(HARNESS_EVENT.resourceCollectionFailed, error, {\n 'harness.phase': COLLECT_RESOURCES_PHASE,\n 'harness.plugin.count': plugins.length,\n });\n throw error;\n });\n\n try {\n const defaultThemePath = await writeDefaultTheme(resources.temporaryDirectory);\n const environment = { ...(options.environment ?? process.env) };\n // The file-backed projection published through Cordis is authoritative.\n // Never let a legacy parent-process projection leak into this Po session.\n delete environment[PO_MCP_SESSION_ENV_VAR];\n const profileEnvironment = applyProfileEnvironment(environment, profile?.env ?? {});\n\n configurePreset(options, environment);\n environment.NX_DAEMON ??= 'false';\n environment.PO_THEME ||= DEFAULT_THEME_NAME;\n environment.CLAUDE_PROJECT_DIR = options.repoRoot;\n environment.CODEX_REPO_ROOT = options.repoRoot;\n environment.ORIGINAL_REPO_PATH ||= options.repoRoot;\n environment.MCP_UI_VIEWER = options.automation ? 'none' : (environment.MCP_UI_VIEWER ?? '');\n\n const personaPrompt = personaDirectory ? buildPersonaPrompt(personaRoot, personaDirectory) : undefined;\n let personaFile: string | undefined;\n if (personaPrompt) {\n personaFile = path.join(resources.temporaryDirectory, 'persona.md');\n await fs.promises.writeFile(personaFile, `${personaPrompt}\\n`, { mode: PRIVATE_FILE_MODE });\n }\n\n // One write, describing the child rather than this process. The state file\n // is the child's authority and the environment is what it projects for the\n // hooks and packages that can only read an environment.\n createHarnessSession(\n {\n root: options.repoRoot,\n majorMode: options.majorMode,\n temporaryDirectory: resources.temporaryDirectory,\n domains: options.domains,\n layers: selectedLayers,\n profile: profile?.name,\n profileIdentity: profile?.identity,\n profileVoice: profile?.voice,\n profileEnvironment,\n personaFile,\n skillDirectories: resources.skillDirectories,\n agentDirectories: resources.agentDirectories,\n additionalDirectories: options.additionalDirectories,\n childExtensions: [],\n pluginDirectories: options.pluginDirectories,\n pluginHooks: resources.pluginHooks,\n hookGroups,\n hooks: options.hooks,\n agents: options.agents,\n mcp: options.mcp,\n mcpConfigPath: resources.mcpConfigPath,\n mcpProjection: resources.mcpProjection,\n allowProtectedWrites: options.allowProtectedWrites,\n },\n { directory: resources.temporaryDirectory, environment },\n );\n if (options.agents) {\n environment.PI_SUBAGENT_EXTRA_AGENT_DIRS = resources.agentDirectories.join(path.delimiter);\n environment.PI_SUBAGENT_EXTRA_SKILL_DIRS = resources.skillDirectories.join(path.delimiter);\n }\n\n // Core hook groups load regardless; hookGroups selects the rest. The initial\n // state write includes an empty list deliberately: unset means every group.\n\n return {\n options,\n environment,\n resources,\n plugins,\n profile: profile?.name,\n personaDirectory,\n personaRoot,\n mcpAllowlist,\n majorModesConfig,\n selectedLayers,\n hookGroups,\n defaultThemePath,\n cleanup: resources.cleanup.bind(resources),\n };\n } catch (error) {\n // Preparation failed after the temp directory existed, so nothing will be\n // handed back to clean it up.\n await telemetry.recordError(HARNESS_EVENT.contextBuildFailed, error, {\n 'harness.phase': BUILD_CONTEXT_PHASE,\n 'harness.major_mode': options.majorMode,\n ...(profile?.name ? { 'harness.profile': profile.name } : {}),\n });\n await resources.cleanup();\n throw error;\n }\n}\n"],"mappings":"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"}