berget 2.2.10 → 2.2.11
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.
- package/dist/package.json +1 -1
- package/dist/src/commands/code/__tests__/setup-flow.test.js +13 -3
- package/dist/src/commands/code/setup.js +56 -58
- package/package.json +1 -1
- package/src/commands/code/__tests__/setup-flow.test.ts +13 -3
- package/src/commands/code/ports/prompter.ts +1 -0
- package/src/commands/code/setup.ts +68 -71
package/dist/package.json
CHANGED
|
@@ -75,6 +75,7 @@ function makeJwt(payload) {
|
|
|
75
75
|
prompter: new fake_prompter_1.FakePrompter([
|
|
76
76
|
(0, fake_prompter_1.select)('pi'),
|
|
77
77
|
(0, fake_prompter_1.select)('project'),
|
|
78
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
78
79
|
(0, fake_prompter_1.select)('fullstack'), // Agent selection
|
|
79
80
|
(0, fake_prompter_1.confirm)(true, 'Create'),
|
|
80
81
|
]),
|
|
@@ -93,7 +94,7 @@ function makeJwt(payload) {
|
|
|
93
94
|
prompter: new fake_prompter_1.FakePrompter([
|
|
94
95
|
(0, fake_prompter_1.select)('pi'),
|
|
95
96
|
(0, fake_prompter_1.select)('project'),
|
|
96
|
-
(0, fake_prompter_1.
|
|
97
|
+
(0, fake_prompter_1.confirm)(false, 'Set up an agent for Pi?'),
|
|
97
98
|
]),
|
|
98
99
|
});
|
|
99
100
|
await (0, setup_1.runSetup)(deps);
|
|
@@ -150,6 +151,7 @@ function makeJwt(payload) {
|
|
|
150
151
|
prompter: new fake_prompter_1.FakePrompter([
|
|
151
152
|
(0, fake_prompter_1.select)('pi'),
|
|
152
153
|
(0, fake_prompter_1.select)('project'),
|
|
154
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
153
155
|
(0, fake_prompter_1.select)('fullstack'),
|
|
154
156
|
(0, fake_prompter_1.confirm)(false, /Create|Overwrite/),
|
|
155
157
|
]),
|
|
@@ -227,6 +229,7 @@ function makeJwt(payload) {
|
|
|
227
229
|
prompter: new fake_prompter_1.FakePrompter([
|
|
228
230
|
(0, fake_prompter_1.select)('pi'),
|
|
229
231
|
(0, fake_prompter_1.select)('project'),
|
|
232
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
230
233
|
(0, fake_prompter_1.select)('fullstack'),
|
|
231
234
|
(0, fake_prompter_1.confirm)(true, 'Create'),
|
|
232
235
|
]),
|
|
@@ -265,6 +268,7 @@ function makeJwt(payload) {
|
|
|
265
268
|
prompter: new fake_prompter_1.FakePrompter([
|
|
266
269
|
(0, fake_prompter_1.select)('pi'),
|
|
267
270
|
(0, fake_prompter_1.select)('project'),
|
|
271
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
268
272
|
(0, fake_prompter_1.select)('fullstack'),
|
|
269
273
|
(0, fake_prompter_1.confirm)(true, 'Create'),
|
|
270
274
|
]),
|
|
@@ -316,6 +320,7 @@ function makeJwt(payload) {
|
|
|
316
320
|
prompter: new fake_prompter_1.FakePrompter([
|
|
317
321
|
(0, fake_prompter_1.select)('pi'),
|
|
318
322
|
(0, fake_prompter_1.select)('project'),
|
|
323
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
319
324
|
(0, fake_prompter_1.select)('fullstack'),
|
|
320
325
|
(0, fake_prompter_1.confirm)(true, 'Create'),
|
|
321
326
|
]),
|
|
@@ -336,6 +341,7 @@ function makeJwt(payload) {
|
|
|
336
341
|
(0, fake_prompter_1.select)('pi'),
|
|
337
342
|
(0, fake_prompter_1.select)('project'),
|
|
338
343
|
(0, fake_prompter_1.confirm)(true), // API key creation prompt
|
|
344
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
339
345
|
(0, fake_prompter_1.select)('fullstack'),
|
|
340
346
|
(0, fake_prompter_1.confirm)(true, 'Create'),
|
|
341
347
|
]),
|
|
@@ -424,6 +430,7 @@ function makeJwt(payload) {
|
|
|
424
430
|
prompter: new fake_prompter_1.FakePrompter([
|
|
425
431
|
(0, fake_prompter_1.select)('pi'),
|
|
426
432
|
(0, fake_prompter_1.select)('project'),
|
|
433
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
427
434
|
(0, fake_prompter_1.select)('fullstack'),
|
|
428
435
|
(0, fake_prompter_1.confirm)(true, 'Create'),
|
|
429
436
|
]),
|
|
@@ -439,6 +446,7 @@ function makeJwt(payload) {
|
|
|
439
446
|
prompter: new fake_prompter_1.FakePrompter([
|
|
440
447
|
(0, fake_prompter_1.select)('pi'),
|
|
441
448
|
(0, fake_prompter_1.select)('global'),
|
|
449
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
442
450
|
(0, fake_prompter_1.select)('backend'),
|
|
443
451
|
(0, fake_prompter_1.confirm)(true, 'Create'),
|
|
444
452
|
]),
|
|
@@ -467,13 +475,14 @@ function makeJwt(payload) {
|
|
|
467
475
|
const firstFrontend = files
|
|
468
476
|
.getWrittenFiles()
|
|
469
477
|
.get('/home/user/project/.opencode/agents/frontend.md');
|
|
470
|
-
// Second run with exact same content should
|
|
478
|
+
// Second run with exact same content should prompt for confirmation
|
|
471
479
|
const deps2 = makeDeps({
|
|
472
480
|
files,
|
|
473
481
|
prompter: new fake_prompter_1.FakePrompter([
|
|
474
482
|
(0, fake_prompter_1.select)('opencode'),
|
|
475
483
|
(0, fake_prompter_1.select)('project'),
|
|
476
484
|
(0, fake_prompter_1.multiselect)(['backend', 'frontend']),
|
|
485
|
+
(0, fake_prompter_1.confirm)(true, 'Write'),
|
|
477
486
|
]),
|
|
478
487
|
});
|
|
479
488
|
await (0, setup_1.runSetup)(deps2);
|
|
@@ -490,8 +499,9 @@ function makeJwt(payload) {
|
|
|
490
499
|
prompter: new fake_prompter_1.FakePrompter([
|
|
491
500
|
(0, fake_prompter_1.select)('pi'),
|
|
492
501
|
(0, fake_prompter_1.select)('project'),
|
|
502
|
+
(0, fake_prompter_1.confirm)(true, 'Set up an agent for Pi?'),
|
|
493
503
|
(0, fake_prompter_1.select)('fullstack'),
|
|
494
|
-
(0, fake_prompter_1.confirm)(true, '
|
|
504
|
+
(0, fake_prompter_1.confirm)(true, 'SYSTEM.md already exists'),
|
|
495
505
|
]),
|
|
496
506
|
});
|
|
497
507
|
await (0, setup_1.runSetup)(deps);
|
|
@@ -338,41 +338,43 @@ async function setupOpenCodeAgents(deps) {
|
|
|
338
338
|
const { cwd, files, homeDir, prompter, scope } = deps;
|
|
339
339
|
const agents = (0, index_js_1.getAllAgents)().filter((a) => a.config.mode === 'primary');
|
|
340
340
|
if (agents.length === 0) {
|
|
341
|
-
return;
|
|
341
|
+
return false;
|
|
342
342
|
}
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
343
|
+
const agentsDir = scope === 'project'
|
|
344
|
+
? pathJoin(cwd, '.opencode', 'agents')
|
|
345
|
+
: pathJoin(homeDir, '.config', 'opencode', 'agents');
|
|
346
|
+
prompter.note('Space to toggle, Enter to confirm.', 'Agent Setup');
|
|
347
|
+
const agentOptions = await Promise.all(agents.map(async (agent) => {
|
|
348
|
+
const agentPath = pathJoin(agentsDir, `${agent.config.name}.md`);
|
|
349
|
+
const exists = await files.exists(agentPath);
|
|
350
|
+
return {
|
|
351
|
+
hint: exists ? 'already configured' : agent.config.description,
|
|
347
352
|
label: agent.config.name,
|
|
348
353
|
value: agent.config.name,
|
|
349
|
-
}
|
|
354
|
+
};
|
|
355
|
+
}));
|
|
356
|
+
const selectedAgents = await prompter.multiselect({
|
|
357
|
+
message: 'Select agents to set up:',
|
|
358
|
+
options: agentOptions,
|
|
359
|
+
required: false,
|
|
350
360
|
});
|
|
351
361
|
if (selectedAgents.length === 0) {
|
|
352
|
-
return;
|
|
362
|
+
return false;
|
|
353
363
|
}
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
await files.mkdir(agentsDir);
|
|
358
|
-
const hasChanges = await Promise.all(selectedAgents.map(async (agentName) => {
|
|
359
|
-
const agent = agents.find((a) => a.config.name === agentName);
|
|
360
|
-
if (!agent)
|
|
361
|
-
return false;
|
|
364
|
+
const newAgents = [];
|
|
365
|
+
const existingAgents = [];
|
|
366
|
+
await Promise.all(selectedAgents.map(async (agentName) => {
|
|
362
367
|
const agentPath = pathJoin(agentsDir, `${agentName}.md`);
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
if (existing === newContent) {
|
|
366
|
-
return false;
|
|
367
|
-
}
|
|
368
|
-
if (existing) {
|
|
369
|
-
prompter.note(generateDiff(existing, newContent, agentPath), `Changes to ${agentName} agent`);
|
|
370
|
-
}
|
|
371
|
-
return true;
|
|
368
|
+
const exists = await files.exists(agentPath);
|
|
369
|
+
(exists ? existingAgents : newAgents).push(agentName);
|
|
372
370
|
}));
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
371
|
+
const summaryParts = [];
|
|
372
|
+
if (newAgents.length > 0)
|
|
373
|
+
summaryParts.push(`New: ${newAgents.join(', ')}`);
|
|
374
|
+
if (existingAgents.length > 0)
|
|
375
|
+
summaryParts.push(`Replaced: ${existingAgents.join(', ')}`);
|
|
376
|
+
if (summaryParts.length > 0) {
|
|
377
|
+
prompter.note(` Agent Setup Summary:\n${summaryParts.map((part) => ` ${part}`).join('\n')}`, 'Agent Setup');
|
|
376
378
|
}
|
|
377
379
|
const shouldWrite = await prompter.confirm({
|
|
378
380
|
initialValue: true,
|
|
@@ -381,6 +383,7 @@ async function setupOpenCodeAgents(deps) {
|
|
|
381
383
|
if (!shouldWrite) {
|
|
382
384
|
throw new errors_1.CancelledError();
|
|
383
385
|
}
|
|
386
|
+
await files.mkdir(agentsDir);
|
|
384
387
|
const s = prompter.spinner();
|
|
385
388
|
s.start('Writing agent configurations...');
|
|
386
389
|
for (const agentName of selectedAgents) {
|
|
@@ -392,6 +395,7 @@ async function setupOpenCodeAgents(deps) {
|
|
|
392
395
|
await files.writeFile(agentPath, content);
|
|
393
396
|
}
|
|
394
397
|
s.stop(`Wrote ${selectedAgents.length} agent(s) to ${agentsDir}`);
|
|
398
|
+
return true;
|
|
395
399
|
}
|
|
396
400
|
async function setupPi(deps) {
|
|
397
401
|
const { commands, cwd, files, homeDir, prompter, scope } = deps;
|
|
@@ -440,43 +444,36 @@ async function setupPiAgent(deps) {
|
|
|
440
444
|
const { cwd, files, homeDir, prompter, scope } = deps;
|
|
441
445
|
const agents = (0, index_js_1.getAllAgents)().filter((a) => a.config.mode === 'primary');
|
|
442
446
|
if (agents.length === 0) {
|
|
443
|
-
return;
|
|
447
|
+
return false;
|
|
444
448
|
}
|
|
449
|
+
const systemPath = scope === 'project'
|
|
450
|
+
? pathJoin(cwd, '.pi', 'SYSTEM.md')
|
|
451
|
+
: pathJoin(homeDir, '.pi', 'agent', 'SYSTEM.md');
|
|
452
|
+
prompter.note('Pi uses a single system prompt.', 'Agent Setup');
|
|
453
|
+
const setupAgent = await prompter.confirm({
|
|
454
|
+
initialValue: false,
|
|
455
|
+
message: 'Set up an agent for Pi?',
|
|
456
|
+
});
|
|
457
|
+
if (!setupAgent)
|
|
458
|
+
return false;
|
|
445
459
|
const selectedAgentName = await prompter.select({
|
|
446
|
-
message: '
|
|
447
|
-
options:
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
value: agent.config.name,
|
|
453
|
-
})),
|
|
454
|
-
],
|
|
460
|
+
message: 'Choose an agent:',
|
|
461
|
+
options: agents.map((agent) => ({
|
|
462
|
+
hint: agent.config.description,
|
|
463
|
+
label: agent.config.name,
|
|
464
|
+
value: agent.config.name,
|
|
465
|
+
})),
|
|
455
466
|
});
|
|
456
|
-
if (selectedAgentName === '__skip__') {
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
467
|
const agent = agents.find((a) => a.config.name === selectedAgentName);
|
|
460
468
|
if (!agent)
|
|
461
|
-
return;
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
const newContent = (0, index_js_1.toPiPrompt)(agent);
|
|
467
|
-
if (existing === newContent) {
|
|
468
|
-
prompter.note('Agent configuration is already up to date.', 'No changes needed');
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
if (existing) {
|
|
472
|
-
prompter.note(generateDiff(existing, newContent, systemPath), 'Changes to agent configuration');
|
|
473
|
-
}
|
|
474
|
-
else {
|
|
475
|
-
prompter.note(newContent, 'New agent configuration');
|
|
476
|
-
}
|
|
469
|
+
return false;
|
|
470
|
+
const systemExists = await files.exists(systemPath);
|
|
471
|
+
const confirmMsg = systemExists
|
|
472
|
+
? `SYSTEM.md already exists. Replace with ${agent.config.name}?`
|
|
473
|
+
: 'Create agent configuration?';
|
|
477
474
|
const shouldWrite = await prompter.confirm({
|
|
478
475
|
initialValue: true,
|
|
479
|
-
message:
|
|
476
|
+
message: confirmMsg,
|
|
480
477
|
});
|
|
481
478
|
if (!shouldWrite) {
|
|
482
479
|
throw new errors_1.CancelledError();
|
|
@@ -485,8 +482,9 @@ async function setupPiAgent(deps) {
|
|
|
485
482
|
s.start('Writing agent configuration...');
|
|
486
483
|
const systemDir = scope === 'project' ? pathJoin(cwd, '.pi') : pathJoin(homeDir, '.pi', 'agent');
|
|
487
484
|
await files.mkdir(systemDir);
|
|
488
|
-
await files.writeFile(systemPath,
|
|
485
|
+
await files.writeFile(systemPath, (0, index_js_1.toPiPrompt)(agent));
|
|
489
486
|
s.stop(`Wrote agent configuration to ${systemPath}`);
|
|
487
|
+
return true;
|
|
490
488
|
}
|
|
491
489
|
function stripJsoncComments(content) {
|
|
492
490
|
content = content.replaceAll(/\/\/.*$/gm, '');
|
package/package.json
CHANGED
|
@@ -95,6 +95,7 @@ describe('runSetup', () => {
|
|
|
95
95
|
prompter: new FakePrompter([
|
|
96
96
|
select('pi'),
|
|
97
97
|
select('project'),
|
|
98
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
98
99
|
select('fullstack'), // Agent selection
|
|
99
100
|
confirm(true, 'Create'),
|
|
100
101
|
]),
|
|
@@ -116,7 +117,7 @@ describe('runSetup', () => {
|
|
|
116
117
|
prompter: new FakePrompter([
|
|
117
118
|
select('pi'),
|
|
118
119
|
select('project'),
|
|
119
|
-
|
|
120
|
+
confirm(false, 'Set up an agent for Pi?'),
|
|
120
121
|
]),
|
|
121
122
|
});
|
|
122
123
|
|
|
@@ -184,6 +185,7 @@ describe('runSetup', () => {
|
|
|
184
185
|
prompter: new FakePrompter([
|
|
185
186
|
select('pi'),
|
|
186
187
|
select('project'),
|
|
188
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
187
189
|
select('fullstack'),
|
|
188
190
|
confirm(false, /Create|Overwrite/),
|
|
189
191
|
]),
|
|
@@ -288,6 +290,7 @@ describe('runSetup', () => {
|
|
|
288
290
|
prompter: new FakePrompter([
|
|
289
291
|
select('pi'),
|
|
290
292
|
select('project'),
|
|
293
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
291
294
|
select('fullstack'),
|
|
292
295
|
confirm(true, 'Create'),
|
|
293
296
|
]),
|
|
@@ -336,6 +339,7 @@ describe('runSetup', () => {
|
|
|
336
339
|
prompter: new FakePrompter([
|
|
337
340
|
select('pi'),
|
|
338
341
|
select('project'),
|
|
342
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
339
343
|
select('fullstack'),
|
|
340
344
|
confirm(true, 'Create'),
|
|
341
345
|
]),
|
|
@@ -399,6 +403,7 @@ describe('runSetup', () => {
|
|
|
399
403
|
prompter: new FakePrompter([
|
|
400
404
|
select('pi'),
|
|
401
405
|
select('project'),
|
|
406
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
402
407
|
select('fullstack'),
|
|
403
408
|
confirm(true, 'Create'),
|
|
404
409
|
]),
|
|
@@ -423,6 +428,7 @@ describe('runSetup', () => {
|
|
|
423
428
|
select('pi'),
|
|
424
429
|
select('project'),
|
|
425
430
|
confirm(true), // API key creation prompt
|
|
431
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
426
432
|
select('fullstack'),
|
|
427
433
|
confirm(true, 'Create'),
|
|
428
434
|
]),
|
|
@@ -530,6 +536,7 @@ describe('runSetup', () => {
|
|
|
530
536
|
prompter: new FakePrompter([
|
|
531
537
|
select('pi'),
|
|
532
538
|
select('project'),
|
|
539
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
533
540
|
select('fullstack'),
|
|
534
541
|
confirm(true, 'Create'),
|
|
535
542
|
]),
|
|
@@ -548,6 +555,7 @@ describe('runSetup', () => {
|
|
|
548
555
|
prompter: new FakePrompter([
|
|
549
556
|
select('pi'),
|
|
550
557
|
select('global'),
|
|
558
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
551
559
|
select('backend'),
|
|
552
560
|
confirm(true, 'Create'),
|
|
553
561
|
]),
|
|
@@ -582,13 +590,14 @@ describe('runSetup', () => {
|
|
|
582
590
|
.getWrittenFiles()
|
|
583
591
|
.get('/home/user/project/.opencode/agents/frontend.md');
|
|
584
592
|
|
|
585
|
-
// Second run with exact same content should
|
|
593
|
+
// Second run with exact same content should prompt for confirmation
|
|
586
594
|
const deps2 = makeDeps({
|
|
587
595
|
files,
|
|
588
596
|
prompter: new FakePrompter([
|
|
589
597
|
select('opencode'),
|
|
590
598
|
select('project'),
|
|
591
599
|
multiselect(['backend', 'frontend']),
|
|
600
|
+
confirm(true, 'Write'),
|
|
592
601
|
]),
|
|
593
602
|
});
|
|
594
603
|
|
|
@@ -613,8 +622,9 @@ describe('runSetup', () => {
|
|
|
613
622
|
prompter: new FakePrompter([
|
|
614
623
|
select('pi'),
|
|
615
624
|
select('project'),
|
|
625
|
+
confirm(true, 'Set up an agent for Pi?'),
|
|
616
626
|
select('fullstack'),
|
|
617
|
-
confirm(true, '
|
|
627
|
+
confirm(true, 'SYSTEM.md already exists'),
|
|
618
628
|
]),
|
|
619
629
|
});
|
|
620
630
|
|
|
@@ -404,26 +404,13 @@ async function setupOpenCodeAgents(deps: {
|
|
|
404
404
|
homeDir: string;
|
|
405
405
|
prompter: Prompter;
|
|
406
406
|
scope: 'global' | 'project';
|
|
407
|
-
}): Promise<
|
|
407
|
+
}): Promise<boolean> {
|
|
408
408
|
const { cwd, files, homeDir, prompter, scope } = deps;
|
|
409
409
|
|
|
410
410
|
const agents = getAllAgents().filter((a) => a.config.mode === 'primary');
|
|
411
411
|
|
|
412
412
|
if (agents.length === 0) {
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
const selectedAgents = await prompter.multiselect({
|
|
417
|
-
message: 'Select agents to set up (optional - press enter to skip):',
|
|
418
|
-
options: agents.map((agent) => ({
|
|
419
|
-
hint: agent.config.description,
|
|
420
|
-
label: agent.config.name,
|
|
421
|
-
value: agent.config.name,
|
|
422
|
-
})),
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
if (selectedAgents.length === 0) {
|
|
426
|
-
return;
|
|
413
|
+
return false;
|
|
427
414
|
}
|
|
428
415
|
|
|
429
416
|
const agentsDir =
|
|
@@ -431,35 +418,48 @@ async function setupOpenCodeAgents(deps: {
|
|
|
431
418
|
? pathJoin(cwd, '.opencode', 'agents')
|
|
432
419
|
: pathJoin(homeDir, '.config', 'opencode', 'agents');
|
|
433
420
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
const hasChanges = await Promise.all(
|
|
437
|
-
selectedAgents.map(async (agentName) => {
|
|
438
|
-
const agent = agents.find((a) => a.config.name === agentName);
|
|
439
|
-
if (!agent) return false;
|
|
421
|
+
prompter.note('Space to toggle, Enter to confirm.', 'Agent Setup');
|
|
440
422
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const
|
|
423
|
+
const agentOptions = await Promise.all(
|
|
424
|
+
agents.map(async (agent) => {
|
|
425
|
+
const agentPath = pathJoin(agentsDir, `${agent.config.name}.md`);
|
|
426
|
+
const exists = await files.exists(agentPath);
|
|
427
|
+
return {
|
|
428
|
+
hint: exists ? 'already configured' : agent.config.description,
|
|
429
|
+
label: agent.config.name,
|
|
430
|
+
value: agent.config.name,
|
|
431
|
+
};
|
|
432
|
+
}),
|
|
433
|
+
);
|
|
444
434
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
435
|
+
const selectedAgents = await prompter.multiselect({
|
|
436
|
+
message: 'Select agents to set up:',
|
|
437
|
+
options: agentOptions,
|
|
438
|
+
required: false,
|
|
439
|
+
});
|
|
448
440
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
`Changes to ${agentName} agent`,
|
|
453
|
-
);
|
|
454
|
-
}
|
|
441
|
+
if (selectedAgents.length === 0) {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
455
444
|
|
|
456
|
-
|
|
445
|
+
const newAgents: string[] = [];
|
|
446
|
+
const existingAgents: string[] = [];
|
|
447
|
+
await Promise.all(
|
|
448
|
+
selectedAgents.map(async (agentName) => {
|
|
449
|
+
const agentPath = pathJoin(agentsDir, `${agentName}.md`);
|
|
450
|
+
const exists = await files.exists(agentPath);
|
|
451
|
+
(exists ? existingAgents : newAgents).push(agentName);
|
|
457
452
|
}),
|
|
458
453
|
);
|
|
459
454
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
455
|
+
const summaryParts: string[] = [];
|
|
456
|
+
if (newAgents.length > 0) summaryParts.push(`New: ${newAgents.join(', ')}`);
|
|
457
|
+
if (existingAgents.length > 0) summaryParts.push(`Replaced: ${existingAgents.join(', ')}`);
|
|
458
|
+
if (summaryParts.length > 0) {
|
|
459
|
+
prompter.note(
|
|
460
|
+
` Agent Setup Summary:\n${summaryParts.map((part) => ` ${part}`).join('\n')}`,
|
|
461
|
+
'Agent Setup',
|
|
462
|
+
);
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
const shouldWrite = await prompter.confirm({
|
|
@@ -471,6 +471,8 @@ async function setupOpenCodeAgents(deps: {
|
|
|
471
471
|
throw new CancelledError();
|
|
472
472
|
}
|
|
473
473
|
|
|
474
|
+
await files.mkdir(agentsDir);
|
|
475
|
+
|
|
474
476
|
const s = prompter.spinner();
|
|
475
477
|
s.start('Writing agent configurations...');
|
|
476
478
|
|
|
@@ -484,6 +486,7 @@ async function setupOpenCodeAgents(deps: {
|
|
|
484
486
|
}
|
|
485
487
|
|
|
486
488
|
s.stop(`Wrote ${selectedAgents.length} agent(s) to ${agentsDir}`);
|
|
489
|
+
return true;
|
|
487
490
|
}
|
|
488
491
|
|
|
489
492
|
async function setupPi(deps: {
|
|
@@ -551,56 +554,49 @@ async function setupPiAgent(deps: {
|
|
|
551
554
|
homeDir: string;
|
|
552
555
|
prompter: Prompter;
|
|
553
556
|
scope: 'global' | 'project';
|
|
554
|
-
}): Promise<
|
|
557
|
+
}): Promise<boolean> {
|
|
555
558
|
const { cwd, files, homeDir, prompter, scope } = deps;
|
|
556
559
|
|
|
557
560
|
const agents = getAllAgents().filter((a) => a.config.mode === 'primary');
|
|
558
561
|
|
|
559
562
|
if (agents.length === 0) {
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
const selectedAgentName = await prompter.select({
|
|
564
|
-
message: 'Select an agent (optional - press enter to skip):',
|
|
565
|
-
options: [
|
|
566
|
-
{ label: 'Skip agent setup', value: '__skip__' },
|
|
567
|
-
...agents.map((agent) => ({
|
|
568
|
-
hint: agent.config.description,
|
|
569
|
-
label: agent.config.name,
|
|
570
|
-
value: agent.config.name,
|
|
571
|
-
})),
|
|
572
|
-
],
|
|
573
|
-
});
|
|
574
|
-
|
|
575
|
-
if (selectedAgentName === '__skip__') {
|
|
576
|
-
return;
|
|
563
|
+
return false;
|
|
577
564
|
}
|
|
578
565
|
|
|
579
|
-
const agent = agents.find((a) => a.config.name === selectedAgentName);
|
|
580
|
-
if (!agent) return;
|
|
581
|
-
|
|
582
566
|
const systemPath =
|
|
583
567
|
scope === 'project'
|
|
584
568
|
? pathJoin(cwd, '.pi', 'SYSTEM.md')
|
|
585
569
|
: pathJoin(homeDir, '.pi', 'agent', 'SYSTEM.md');
|
|
586
570
|
|
|
587
|
-
|
|
588
|
-
const newContent = toPiPrompt(agent);
|
|
571
|
+
prompter.note('Pi uses a single system prompt.', 'Agent Setup');
|
|
589
572
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
}
|
|
573
|
+
const setupAgent = await prompter.confirm({
|
|
574
|
+
initialValue: false,
|
|
575
|
+
message: 'Set up an agent for Pi?',
|
|
576
|
+
});
|
|
594
577
|
|
|
595
|
-
if (
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
578
|
+
if (!setupAgent) return false;
|
|
579
|
+
|
|
580
|
+
const selectedAgentName = await prompter.select({
|
|
581
|
+
message: 'Choose an agent:',
|
|
582
|
+
options: agents.map((agent) => ({
|
|
583
|
+
hint: agent.config.description,
|
|
584
|
+
label: agent.config.name,
|
|
585
|
+
value: agent.config.name,
|
|
586
|
+
})),
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
const agent = agents.find((a) => a.config.name === selectedAgentName);
|
|
590
|
+
if (!agent) return false;
|
|
591
|
+
|
|
592
|
+
const systemExists = await files.exists(systemPath);
|
|
593
|
+
const confirmMsg = systemExists
|
|
594
|
+
? `SYSTEM.md already exists. Replace with ${agent.config.name}?`
|
|
595
|
+
: 'Create agent configuration?';
|
|
600
596
|
|
|
601
597
|
const shouldWrite = await prompter.confirm({
|
|
602
598
|
initialValue: true,
|
|
603
|
-
message:
|
|
599
|
+
message: confirmMsg,
|
|
604
600
|
});
|
|
605
601
|
|
|
606
602
|
if (!shouldWrite) {
|
|
@@ -612,9 +608,10 @@ async function setupPiAgent(deps: {
|
|
|
612
608
|
|
|
613
609
|
const systemDir = scope === 'project' ? pathJoin(cwd, '.pi') : pathJoin(homeDir, '.pi', 'agent');
|
|
614
610
|
await files.mkdir(systemDir);
|
|
615
|
-
await files.writeFile(systemPath,
|
|
611
|
+
await files.writeFile(systemPath, toPiPrompt(agent));
|
|
616
612
|
|
|
617
613
|
s.stop(`Wrote agent configuration to ${systemPath}`);
|
|
614
|
+
return true;
|
|
618
615
|
}
|
|
619
616
|
|
|
620
617
|
function stripJsoncComments(content: string): string {
|