Compare commits
10 Commits
feat/confi
...
feat/prime
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90c49bcb22 | ||
|
|
0a29c2fd7f | ||
|
|
3061435399 | ||
|
|
a1893a7578 | ||
|
|
64503e8924 | ||
|
|
ba05b2865c | ||
|
|
3f93f0798f | ||
|
|
ce7df10e06 | ||
|
|
25c1bffdd0 | ||
| d56a074733 |
File diff suppressed because one or more lines are too long
@@ -510,6 +510,59 @@ describe('config prime-agent', () => {
|
||||
expect(exceptionSafeRead(join(tmpDir, '.mcpctl-project'))).toBeNull();
|
||||
});
|
||||
|
||||
it('the installed switcher extension publishes the active project to the footer', async () => {
|
||||
const settingsPath = join(tmpDir, 'settings.json');
|
||||
const cmd = createConfigCommand(
|
||||
{ configDeps: { configDir: tmpDir }, log },
|
||||
{ client, credentialsDeps: { configDir: tmpDir }, log },
|
||||
);
|
||||
await cmd.parseAsync(['prime-agent', '--project', 'ha', '-o', settingsPath, '--skip-skills', '--token', 'mcpctl_pat_x'], { from: 'user' });
|
||||
|
||||
const ext = readFileSync(join(tmpDir, 'extensions', 'mcpctl-switch.ts'), 'utf-8');
|
||||
// Footer status, refreshed on startup and on every reload (which is what
|
||||
// the switch itself triggers) — the mcpctl equivalent of the model name.
|
||||
expect(ext).toContain("pi.on('session_start'");
|
||||
expect(ext).toContain('ctx.ui.setStatus(STATUS_KEY');
|
||||
expect(ext).toContain('`mcpctl:${active}`');
|
||||
// notify() only accepts info|warning|error — 'success' is not a valid type.
|
||||
expect(ext).not.toContain("'success'");
|
||||
});
|
||||
|
||||
it('the installed switcher shows the active project via a widget, not just setStatus', async () => {
|
||||
const settingsPath = join(tmpDir, 'settings.json');
|
||||
const cmd = createConfigCommand(
|
||||
{ configDeps: { configDir: tmpDir }, log },
|
||||
{ client, credentialsDeps: { configDir: tmpDir }, log },
|
||||
);
|
||||
await cmd.parseAsync(['prime-agent', '--project', 'ha', '-o', settingsPath, '--skip-skills', '--token', 'mcpctl_pat_x'], { from: 'user' });
|
||||
|
||||
const ext = readFileSync(join(tmpDir, 'extensions', 'mcpctl-switch.ts'), 'utf-8');
|
||||
// Both hosts render statuses next to the model name (pi in its footer,
|
||||
// prime-agent in the tray — the latter via prime-agent-extension-status.patch).
|
||||
expect(ext).toContain('ctx.ui.setStatus(STATUS_KEY');
|
||||
// The widget was a workaround for the unpatched tray; it scrolled away with
|
||||
// the transcript, so it is not a status line and must not come back.
|
||||
expect(ext).not.toContain('setWidget');
|
||||
// prime-agent emits session_start only from reload(), never at startup, so
|
||||
// a session_start-only indicator stays blank until the first switch.
|
||||
expect(ext).toContain("pi.on('turn_start'");
|
||||
});
|
||||
|
||||
it('the installed switcher filters the project list before showing it', async () => {
|
||||
const settingsPath = join(tmpDir, 'settings.json');
|
||||
const cmd = createConfigCommand(
|
||||
{ configDeps: { configDir: tmpDir }, log },
|
||||
{ client, credentialsDeps: { configDir: tmpDir }, log },
|
||||
);
|
||||
await cmd.parseAsync(['prime-agent', '--project', 'ha', '-o', settingsPath, '--skip-skills', '--token', 'mcpctl_pat_x'], { from: 'user' });
|
||||
|
||||
const ext = readFileSync(join(tmpDir, 'extensions', 'mcpctl-switch.ts'), 'utf-8');
|
||||
// Hundreds of projects in a plain arrow-key list is unusable.
|
||||
expect(ext).toContain('export function filterProjects');
|
||||
expect(ext).toContain('ctx.ui.input(');
|
||||
expect(ext).toContain('FILTER_THRESHOLD');
|
||||
});
|
||||
|
||||
it('the installed switcher extension passes --skip-marker', async () => {
|
||||
const settingsPath = join(tmpDir, 'settings.json');
|
||||
const cmd = createConfigCommand(
|
||||
|
||||
Reference in New Issue
Block a user