@pellux/goodvibes-agent 1.0.17 → 1.0.19
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/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/dist/package/main.js +305 -87
- package/docs/README.md +1 -1
- package/docs/getting-started.md +2 -2
- package/docs/tools-and-commands.md +7 -5
- package/package.json +1 -1
- package/src/tools/agent-harness-cli-metadata.ts +74 -9
- package/src/tools/agent-harness-keybinding-metadata.ts +83 -23
- package/src/tools/agent-harness-panel-metadata.ts +84 -14
- package/src/tools/agent-harness-tool-schema.ts +6 -6
- package/src/tools/agent-harness-tool.ts +7 -7
- package/src/tools/agent-harness-ui-surface-metadata.ts +75 -11
- package/src/version.ts +1 -1
|
@@ -594,10 +594,10 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
|
|
|
594
594
|
workspaceActions: allWorkspaceActions().length,
|
|
595
595
|
tools: deps.toolRegistry.getToolDefinitions().length,
|
|
596
596
|
modelAccess: {
|
|
597
|
-
cliCommands: 'Use mode:"cli_commands" and mode:"cli_command" to inspect package CLI mirrors and their preferred in-process model routes. CLI modes are discovery-only.',
|
|
598
|
-
panels: 'Use mode:"panels" and mode:"panel" to inspect built-in panel catalog/open state; use mode:"open_panel" with confirm:true plus explicitUserRequest to route a visible panel/workspace change.',
|
|
599
|
-
uiSurfaces: 'Use mode:"ui_surfaces" and mode:"ui_surface" to inspect modal/overlay/picker/workspace surfaces; use mode:"open_ui_surface" with confirm:true plus explicitUserRequest to route visible UI navigation.',
|
|
600
|
-
shortcuts: 'Use mode:"shortcuts" to inspect fixed shortcuts plus configurable keybindings. Use mode:"set_keybinding" and mode:"reset_keybinding" with confirm:true plus explicitUserRequest to edit the same config file the user edits.',
|
|
597
|
+
cliCommands: 'Use mode:"cli_commands" to list and mode:"cli_command" with cliCommand, command, commandName, target, or query to inspect package CLI mirrors and their preferred in-process model routes. CLI modes are discovery-only.',
|
|
598
|
+
panels: 'Use mode:"panels" to list and mode:"panel" with panelId, target, or query to inspect built-in panel catalog/open state; use mode:"open_panel" with confirm:true plus explicitUserRequest to route a visible panel/workspace change.',
|
|
599
|
+
uiSurfaces: 'Use mode:"ui_surfaces" to list and mode:"ui_surface" with surfaceId, target, or query to inspect modal/overlay/picker/workspace surfaces; use mode:"open_ui_surface" with confirm:true plus explicitUserRequest to route visible UI navigation.',
|
|
600
|
+
shortcuts: 'Use mode:"shortcuts" to inspect fixed shortcuts plus configurable keybindings. Use mode:"keybinding" with actionId, target, key, or query; use mode:"set_keybinding" and mode:"reset_keybinding" with confirm:true plus explicitUserRequest to edit the same config file the user edits.',
|
|
601
601
|
slashCommands: 'Use mode:"commands" to list slash commands and mode:"command" with command, commandName, target, or query to inspect one command; use mode:"run_command" with confirm:true plus explicitUserRequest to execute.',
|
|
602
602
|
workspace: 'Use mode:"workspace_actions" to list and mode:"workspace_action" with actionId, command, target, or query for one action and editor schema; set includeParameters:true on workspace_actions to inline editor schemas.',
|
|
603
603
|
settings: 'Use mode:"settings" to list and mode:"get_setting" with key, target, or query for one setting. Use mode:"set_setting" or mode:"reset_setting" with key, target, or query plus confirm:true and explicitUserRequest.',
|
|
@@ -633,7 +633,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
|
|
|
633
633
|
}
|
|
634
634
|
if (args.mode === 'panel') {
|
|
635
635
|
const panel = describeHarnessPanel(deps.commandContext, args);
|
|
636
|
-
return panel ? output(panel) : error(`Unknown panel ${readString(args.panelId || args.query) || '<missing>'}.`);
|
|
636
|
+
return panel ? output(panel) : error(`Unknown panel ${readString(args.panelId || args.target || args.query) || '<missing>'}.`);
|
|
637
637
|
}
|
|
638
638
|
if (args.mode === 'open_panel') {
|
|
639
639
|
const confirmationError = requireConfirmedAction(args, 'Panel routing');
|
|
@@ -646,7 +646,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
|
|
|
646
646
|
}
|
|
647
647
|
if (args.mode === 'ui_surface') {
|
|
648
648
|
const surface = describeHarnessUiSurface(deps.commandContext, args);
|
|
649
|
-
return surface ? output(surface) : error(`Unknown UI surface ${readString(args.surfaceId || args.query) || '<missing>'}.`);
|
|
649
|
+
return surface ? output(surface) : error(`Unknown UI surface ${readString(args.surfaceId || args.query || args.target) || '<missing>'}.`);
|
|
650
650
|
}
|
|
651
651
|
if (args.mode === 'open_ui_surface') {
|
|
652
652
|
const confirmationError = requireConfirmedAction(args, 'UI surface routing');
|
|
@@ -657,7 +657,7 @@ export function createAgentHarnessTool(deps: AgentHarnessToolDeps): Tool {
|
|
|
657
657
|
if (args.mode === 'keybindings') return output(listHarnessKeybindings(deps.commandContext, args));
|
|
658
658
|
if (args.mode === 'keybinding') {
|
|
659
659
|
const binding = describeHarnessKeybinding(deps.commandContext, args);
|
|
660
|
-
return binding ? output(binding) : error(`Unknown keybinding action ${readString(args.actionId || args.key || args.query) || '<missing>'}.`);
|
|
660
|
+
return binding ? output(binding) : error(`Unknown keybinding action ${readString(args.actionId || args.target || args.key || args.query) || '<missing>'}.`);
|
|
661
661
|
}
|
|
662
662
|
if (args.mode === 'set_keybinding') {
|
|
663
663
|
const confirmationError = requireConfirmedAction(args, 'Keybinding mutation');
|
|
@@ -27,6 +27,24 @@ interface UiSurfaceDefinition {
|
|
|
27
27
|
readonly open: (context: CommandContext, args: AgentHarnessUiSurfaceArgs) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
interface UiSurfaceLookup {
|
|
31
|
+
readonly source: 'surfaceId' | 'target' | 'query';
|
|
32
|
+
readonly input: string;
|
|
33
|
+
readonly resolvedBy: 'id' | 'case-insensitive-id' | 'label' | 'case-insensitive-label' | 'search';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type UiSurfaceResolution =
|
|
37
|
+
| {
|
|
38
|
+
readonly status: 'found';
|
|
39
|
+
readonly surface: UiSurfaceDefinition;
|
|
40
|
+
readonly lookup: UiSurfaceLookup;
|
|
41
|
+
}
|
|
42
|
+
| {
|
|
43
|
+
readonly status: 'ambiguous';
|
|
44
|
+
readonly input: string;
|
|
45
|
+
readonly candidates: readonly Record<string, unknown>[];
|
|
46
|
+
};
|
|
47
|
+
|
|
30
48
|
function readString(value: unknown): string {
|
|
31
49
|
return typeof value === 'string' ? value.trim() : '';
|
|
32
50
|
}
|
|
@@ -668,7 +686,17 @@ function surfaceMatches(surface: Record<string, unknown>, query: string): boolea
|
|
|
668
686
|
].map((value) => String(value ?? '')).join('\n').toLowerCase().includes(query.toLowerCase());
|
|
669
687
|
}
|
|
670
688
|
|
|
671
|
-
function
|
|
689
|
+
function surfaceLookupFromArgs(args: AgentHarnessUiSurfaceArgs): { readonly source: UiSurfaceLookup['source']; readonly input: string } | null {
|
|
690
|
+
const surfaceId = readString(args.surfaceId);
|
|
691
|
+
if (surfaceId) return { source: 'surfaceId', input: surfaceId };
|
|
692
|
+
const query = readString(args.query);
|
|
693
|
+
if (query) return { source: 'query', input: query };
|
|
694
|
+
const target = readString(args.target);
|
|
695
|
+
if (target) return { source: 'target', input: target };
|
|
696
|
+
return null;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
function surfaceCandidate(surface: UiSurfaceDefinition): Record<string, unknown> {
|
|
672
700
|
return {
|
|
673
701
|
id: surface.id,
|
|
674
702
|
label: surface.label,
|
|
@@ -676,6 +704,38 @@ function describeSurface(context: CommandContext, surface: UiSurfaceDefinition):
|
|
|
676
704
|
summary: surface.summary,
|
|
677
705
|
command: surface.command,
|
|
678
706
|
preferredModelRoute: surface.preferredModelRoute,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
function resolveHarnessUiSurface(args: AgentHarnessUiSurfaceArgs): UiSurfaceResolution | null {
|
|
711
|
+
const lookup = surfaceLookupFromArgs(args);
|
|
712
|
+
if (!lookup) return null;
|
|
713
|
+
const exactId = UI_SURFACES.find((surface) => surface.id === lookup.input);
|
|
714
|
+
if (exactId) return { status: 'found', surface: exactId, lookup: { ...lookup, resolvedBy: 'id' } };
|
|
715
|
+
const exactLabel = UI_SURFACES.find((surface) => surface.label === lookup.input);
|
|
716
|
+
if (exactLabel) return { status: 'found', surface: exactLabel, lookup: { ...lookup, resolvedBy: 'label' } };
|
|
717
|
+
const inputLower = lookup.input.toLowerCase();
|
|
718
|
+
const ciId = UI_SURFACES.filter((surface) => surface.id.toLowerCase() === inputLower);
|
|
719
|
+
if (ciId.length === 1) return { status: 'found', surface: ciId[0]!, lookup: { ...lookup, resolvedBy: 'case-insensitive-id' } };
|
|
720
|
+
if (ciId.length > 1) return { status: 'ambiguous', input: lookup.input, candidates: ciId.map(surfaceCandidate).slice(0, 8) };
|
|
721
|
+
const ciLabel = UI_SURFACES.filter((surface) => surface.label.toLowerCase() === inputLower);
|
|
722
|
+
if (ciLabel.length === 1) return { status: 'found', surface: ciLabel[0]!, lookup: { ...lookup, resolvedBy: 'case-insensitive-label' } };
|
|
723
|
+
if (ciLabel.length > 1) return { status: 'ambiguous', input: lookup.input, candidates: ciLabel.map(surfaceCandidate).slice(0, 8) };
|
|
724
|
+
const search = UI_SURFACES.filter((surface) => surfaceMatches(surfaceCandidate(surface), lookup.input));
|
|
725
|
+
if (search.length === 1) return { status: 'found', surface: search[0]!, lookup: { ...lookup, resolvedBy: 'search' } };
|
|
726
|
+
if (search.length > 1) return { status: 'ambiguous', input: lookup.input, candidates: search.map(surfaceCandidate).slice(0, 8) };
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
function describeSurface(context: CommandContext, surface: UiSurfaceDefinition, lookup?: UiSurfaceLookup): Record<string, unknown> {
|
|
731
|
+
return {
|
|
732
|
+
id: surface.id,
|
|
733
|
+
label: surface.label,
|
|
734
|
+
kind: surface.kind,
|
|
735
|
+
summary: surface.summary,
|
|
736
|
+
command: surface.command,
|
|
737
|
+
...(lookup ? { lookup } : {}),
|
|
738
|
+
preferredModelRoute: surface.preferredModelRoute,
|
|
679
739
|
parameters: surface.parameters ?? [],
|
|
680
740
|
available: surface.available(context),
|
|
681
741
|
policy: {
|
|
@@ -700,25 +760,29 @@ export function listHarnessUiSurfaces(context: CommandContext, args: AgentHarnes
|
|
|
700
760
|
}
|
|
701
761
|
|
|
702
762
|
export function describeHarnessUiSurface(context: CommandContext, args: AgentHarnessUiSurfaceArgs): Record<string, unknown> | null {
|
|
703
|
-
const
|
|
704
|
-
if (
|
|
705
|
-
|
|
706
|
-
|
|
763
|
+
const resolved = resolveHarnessUiSurface(args);
|
|
764
|
+
if (resolved?.status === 'found') return describeSurface(context, resolved.surface, resolved.lookup);
|
|
765
|
+
if (resolved?.status === 'ambiguous') {
|
|
766
|
+
return { status: 'ambiguous', input: resolved.input, candidates: resolved.candidates };
|
|
767
|
+
}
|
|
768
|
+
return null;
|
|
707
769
|
}
|
|
708
770
|
|
|
709
771
|
export async function openHarnessUiSurface(context: CommandContext, args: AgentHarnessUiSurfaceArgs): Promise<Record<string, unknown>> {
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
|
|
772
|
+
const resolved = resolveHarnessUiSurface(args);
|
|
773
|
+
if (resolved?.status === 'ambiguous') {
|
|
774
|
+
return { status: 'ambiguous_ui_surface', input: resolved.input, candidates: resolved.candidates };
|
|
775
|
+
}
|
|
776
|
+
if (!resolved) {
|
|
713
777
|
return {
|
|
714
778
|
status: 'unknown_ui_surface',
|
|
715
|
-
surfaceId: surfaceId || '<missing>',
|
|
779
|
+
surfaceId: readString(args.surfaceId || args.query || args.target) || '<missing>',
|
|
716
780
|
availableSurfaces: UI_SURFACES.map((entry) => entry.id),
|
|
717
781
|
};
|
|
718
782
|
}
|
|
719
|
-
const routed = await surface.open(context, args);
|
|
783
|
+
const routed = await resolved.surface.open(context, args);
|
|
720
784
|
return {
|
|
721
785
|
...routed,
|
|
722
|
-
descriptor: describeSurface(context, surface),
|
|
786
|
+
descriptor: describeSurface(context, resolved.surface, resolved.lookup),
|
|
723
787
|
};
|
|
724
788
|
}
|
package/src/version.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
// The prebuild script updates the fallback value before compilation.
|
|
7
7
|
// Uses import.meta.dir (Bun) to locate package.json relative to this file,
|
|
8
8
|
// which is correct regardless of the process working directory.
|
|
9
|
-
let _version = '1.0.
|
|
9
|
+
let _version = '1.0.19';
|
|
10
10
|
let _sdkVersion = '0.33.35';
|
|
11
11
|
try {
|
|
12
12
|
const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {
|