@pellux/goodvibes-agent 0.1.114 → 0.1.117
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 +41 -650
- package/README.md +40 -50
- package/dist/package/main.js +38224 -35673
- package/docs/README.md +5 -4
- package/docs/{connected-services.md → connected-host.md} +18 -10
- package/docs/getting-started.md +43 -42
- package/docs/release-and-publishing.md +6 -4
- package/package.json +3 -3
- package/src/agent/behavior-discovery-summary.ts +165 -0
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +5 -3
- package/src/agent/reminder-schedule-format.ts +6 -6
- package/src/agent/reminder-schedule.ts +1 -1
- package/src/agent/routine-registry.ts +43 -4
- package/src/agent/routine-schedule-format.ts +6 -6
- package/src/agent/routine-schedule-promotion.ts +1 -1
- package/src/agent/routine-schedule-receipts.ts +1 -1
- package/src/agent/runtime-profile-starters.ts +331 -0
- package/src/agent/runtime-profile.ts +228 -330
- package/src/agent/skill-registry.ts +190 -13
- package/src/cli/agent-knowledge-command.ts +2 -2
- package/src/cli/agent-knowledge-format.ts +2 -2
- package/src/cli/agent-knowledge-runtime.ts +1 -1
- package/src/cli/bundle-command.ts +1 -1
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/help.ts +26 -19
- package/src/cli/local-library-command.ts +75 -21
- package/src/cli/management-commands.ts +7 -6
- package/src/cli/management.ts +6 -51
- package/src/cli/parser.ts +23 -2
- package/src/cli/profiles-command.ts +247 -1
- package/src/cli/routines-command.ts +139 -11
- package/src/cli/service-posture.ts +11 -11
- package/src/cli/status.ts +21 -25
- package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
- package/src/input/agent-workspace-access-command-editors.ts +170 -0
- package/src/input/agent-workspace-activation.ts +2 -1
- package/src/input/agent-workspace-basic-command-editor-submission.ts +787 -0
- package/src/input/agent-workspace-basic-command-editors.ts +524 -459
- package/src/input/agent-workspace-categories.ts +177 -14
- package/src/input/agent-workspace-channel-command-editor-submission.ts +49 -0
- package/src/input/agent-workspace-channel-command-editors.ts +47 -0
- package/src/input/agent-workspace-command-editor.ts +25 -1
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +27 -0
- package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
- package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
- package/src/input/agent-workspace-learned-behavior.ts +67 -0
- package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
- package/src/input/agent-workspace-library-command-editors.ts +35 -0
- package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
- package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
- package/src/input/agent-workspace-memory-command-editors.ts +180 -0
- package/src/input/agent-workspace-navigation.ts +45 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +107 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +146 -0
- package/src/input/agent-workspace-operations-command-editors.ts +119 -0
- package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
- package/src/input/agent-workspace-provider-command-editors.ts +93 -0
- package/src/input/agent-workspace-requirements.ts +11 -0
- package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
- package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
- package/src/input/agent-workspace-session-command-editors.ts +249 -0
- package/src/input/agent-workspace-setup.ts +49 -19
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
- package/src/input/agent-workspace-snapshot.ts +56 -8
- package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
- package/src/input/agent-workspace-task-command-editors.ts +47 -0
- package/src/input/agent-workspace-types.ts +124 -0
- package/src/input/agent-workspace-voice-media.ts +1 -1
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +47 -37
- package/src/input/command-registry.ts +1 -1
- package/src/input/commands/agent-runtime-profile-runtime.ts +160 -6
- package/src/input/commands/agent-skills-runtime.ts +76 -12
- package/src/input/commands/agent-workspace-runtime.ts +4 -3
- package/src/input/commands/brief-runtime.ts +38 -9
- package/src/input/commands/channels-runtime.ts +3 -3
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/health-runtime.ts +22 -24
- package/src/input/commands/knowledge.ts +26 -5
- package/src/input/commands/local-provider-runtime.ts +7 -3
- package/src/input/commands/local-setup-review.ts +4 -14
- package/src/input/commands/mcp-runtime.ts +8 -12
- package/src/input/commands/operator-runtime.ts +8 -67
- package/src/input/commands/personas-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +7 -70
- package/src/input/commands/policy-dispatch.ts +1 -1
- package/src/input/commands/policy.ts +1 -5
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/qrcode-runtime.ts +6 -4
- package/src/input/commands/routines-runtime.ts +44 -6
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/security-runtime.ts +3 -8
- package/src/input/commands/session-content.ts +1 -1
- package/src/input/commands/session-workflow.ts +5 -14
- package/src/input/commands/shell-core.ts +8 -2
- package/src/input/commands/subscription-runtime.ts +1 -6
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +2 -2
- package/src/input/commands.ts +4 -0
- package/src/input/feed-context-factory.ts +0 -1
- package/src/input/handler-content-actions.ts +0 -25
- package/src/input/handler-feed.ts +0 -2
- package/src/input/handler-interactions.ts +2 -31
- package/src/input/handler-onboarding.ts +29 -12
- package/src/input/handler-shortcuts.ts +1 -3
- package/src/input/handler.ts +4 -7
- package/src/input/keybindings.ts +9 -9
- package/src/input/mcp-workspace.ts +90 -26
- package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +49 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +126 -11
- package/src/input/onboarding/onboarding-wizard-steps.ts +15 -8
- package/src/input/onboarding/onboarding-wizard-types.ts +1 -0
- package/src/input/onboarding/onboarding-wizard.ts +19 -2
- package/src/input/profile-picker-modal.ts +2 -2
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal.ts +14 -14
- package/src/main.ts +0 -2
- package/src/panels/automation-control-panel.ts +3 -3
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +2 -2
- package/src/panels/builtin/session.ts +26 -18
- package/src/panels/builtin/shared.ts +6 -6
- package/src/panels/project-planning-panel.ts +1 -1
- package/src/panels/provider-health-domains.ts +3 -3
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/subscription-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +2 -2
- package/src/panels/tasks-panel.ts +4 -4
- package/src/planning/project-planning-coordinator.ts +2 -2
- package/src/renderer/agent-workspace.ts +52 -5
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/help-overlay.ts +13 -8
- package/src/renderer/mcp-workspace.ts +32 -13
- package/src/renderer/model-picker-overlay.ts +0 -1
- package/src/renderer/model-workspace.ts +0 -2
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/panel-picker-overlay.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +2 -2
- package/src/renderer/settings-modal-helpers.ts +23 -23
- package/src/renderer/settings-modal.ts +18 -18
- package/src/renderer/system-message.ts +1 -1
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-parts.ts +3 -2
- package/src/runtime/bootstrap-core.ts +4 -64
- package/src/runtime/bootstrap-shell.ts +42 -4
- package/src/runtime/bootstrap.ts +8 -27
- package/src/runtime/connected-host-auth.ts +42 -0
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/index.ts +1 -5
- package/src/runtime/onboarding/apply.ts +213 -0
- package/src/runtime/onboarding/derivation.ts +25 -6
- package/src/runtime/onboarding/snapshot.ts +4 -2
- package/src/runtime/onboarding/types.ts +28 -1
- package/src/runtime/onboarding/verify.ts +81 -2
- package/src/runtime/operator-token-cleanup.ts +2 -2
- package/src/runtime/services.ts +27 -12
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +27 -38
- package/src/tools/agent-local-registry-tool.ts +10 -4
- package/src/tools/agent-tool-policy-guard.ts +5 -7
- package/src/version.ts +1 -1
- package/src/cli/package-verification.ts +0 -274
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ConfigKey } from '@pellux/goodvibes-sdk/platform/config';
|
|
2
2
|
import type { CliServiceRuntime } from '../cli/service-posture.ts';
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const AGENT_EXTERNAL_HOST_SERVICE_MESSAGE = 'GoodVibes Agent uses a connected GoodVibes host and does not install, start, stop, restart, or uninstall it. Manage host lifecycle outside Agent.';
|
|
5
5
|
|
|
6
6
|
export interface ServiceSettingsSyncChange {
|
|
7
7
|
readonly key: ConfigKey;
|
|
@@ -11,13 +11,13 @@ export interface ServiceSettingsSyncChange {
|
|
|
11
11
|
|
|
12
12
|
export interface ServiceSettingsSyncResult {
|
|
13
13
|
readonly handled: boolean;
|
|
14
|
-
readonly action?: '
|
|
14
|
+
readonly action?: 'connected-host-blocked' | 'unchanged';
|
|
15
15
|
readonly message?: string;
|
|
16
16
|
readonly error?: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export interface ServiceSettingsSyncOptions {
|
|
20
|
-
readonly
|
|
20
|
+
readonly allowExternalHostMutation?: false;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export function syncServiceSettingToPlatform(
|
|
@@ -30,15 +30,15 @@ export function syncServiceSettingToPlatform(
|
|
|
30
30
|
return {
|
|
31
31
|
handled: true,
|
|
32
32
|
action: 'unchanged',
|
|
33
|
-
message: '
|
|
33
|
+
message: 'Connected-host setting unchanged',
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
runtime.configManager.setDynamic(change.key, change.previousValue);
|
|
38
38
|
return {
|
|
39
39
|
handled: true,
|
|
40
|
-
action: '
|
|
41
|
-
message:
|
|
42
|
-
error: '
|
|
40
|
+
action: 'connected-host-blocked',
|
|
41
|
+
message: AGENT_EXTERNAL_HOST_SERVICE_MESSAGE,
|
|
42
|
+
error: 'connected_host_lifecycle_external',
|
|
43
43
|
};
|
|
44
44
|
}
|
package/src/shell/ui-openers.ts
CHANGED
|
@@ -78,6 +78,17 @@ function buildConfiguredViaMap(
|
|
|
78
78
|
return map;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
function agentWorkspaceCategoryForPanel(panelId: string): string {
|
|
82
|
+
if (panelId === 'knowledge') return 'knowledge';
|
|
83
|
+
if (panelId === 'memory') return 'memory';
|
|
84
|
+
if (panelId === 'work-plan' || panelId === 'tasks' || panelId === 'approval') return 'work';
|
|
85
|
+
if (panelId === 'automation' || panelId === 'schedule') return 'automation';
|
|
86
|
+
if (panelId === 'provider-health' || panelId === 'providers' || panelId === 'accounts' || panelId === 'subscription') return 'setup';
|
|
87
|
+
if (panelId === 'security' || panelId === 'policy') return 'tools';
|
|
88
|
+
if (panelId === 'qr-code') return 'channels';
|
|
89
|
+
return 'home';
|
|
90
|
+
}
|
|
91
|
+
|
|
81
92
|
export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
82
93
|
const {
|
|
83
94
|
commandContext,
|
|
@@ -284,8 +295,8 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
284
295
|
render();
|
|
285
296
|
};
|
|
286
297
|
|
|
287
|
-
commandContext.openAgentWorkspace = () => {
|
|
288
|
-
input.openAgentWorkspace(commandContext);
|
|
298
|
+
commandContext.openAgentWorkspace = (categoryId?: string) => {
|
|
299
|
+
input.openAgentWorkspace(commandContext, categoryId);
|
|
289
300
|
render();
|
|
290
301
|
};
|
|
291
302
|
|
|
@@ -296,42 +307,18 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
296
307
|
};
|
|
297
308
|
|
|
298
309
|
commandContext.openPanelPicker = () => {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
panelManager.show();
|
|
308
|
-
input.panelFocused = true;
|
|
309
|
-
conversation.setSplashSuppressed(true);
|
|
310
|
-
conversation.rebuildHistory();
|
|
311
|
-
} else if (!input.panelFocused) {
|
|
312
|
-
if (panelManager.getAllOpen().length === 0) {
|
|
313
|
-
try {
|
|
314
|
-
panelManager.open('panel-list');
|
|
315
|
-
} catch {
|
|
316
|
-
// non-fatal
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
panelManager.show();
|
|
320
|
-
input.panelFocused = true;
|
|
321
|
-
conversation.setSplashSuppressed(true);
|
|
322
|
-
conversation.rebuildHistory();
|
|
323
|
-
} else {
|
|
324
|
-
panelManager.hide();
|
|
325
|
-
input.panelFocused = false;
|
|
326
|
-
conversation.setSplashSuppressed(false);
|
|
327
|
-
conversation.rebuildHistory();
|
|
328
|
-
}
|
|
310
|
+
panelManager.hide();
|
|
311
|
+
input.panelFocused = false;
|
|
312
|
+
conversation.setSplashSuppressed(false);
|
|
313
|
+
conversation.log('Panel picker is deferred in GoodVibes Agent. Opening the Agent operator workspace instead.', { fg: '214' });
|
|
314
|
+
input.openAgentWorkspace(commandContext, 'home');
|
|
315
|
+
conversation.rebuildHistory();
|
|
329
316
|
render();
|
|
330
317
|
};
|
|
331
318
|
|
|
332
319
|
commandContext.focusPanels = () => {
|
|
333
|
-
|
|
334
|
-
input.
|
|
320
|
+
input.panelFocused = false;
|
|
321
|
+
input.openAgentWorkspace(commandContext, 'home');
|
|
335
322
|
render();
|
|
336
323
|
};
|
|
337
324
|
|
|
@@ -342,10 +329,12 @@ export function wireShellUiOpeners(options: WireShellUiOpenersOptions): void {
|
|
|
342
329
|
};
|
|
343
330
|
|
|
344
331
|
commandContext.showPanel = (panelId, pane) => {
|
|
345
|
-
|
|
346
|
-
panelManager.
|
|
347
|
-
input.panelFocused =
|
|
348
|
-
conversation.setSplashSuppressed(
|
|
332
|
+
void pane;
|
|
333
|
+
panelManager.hide();
|
|
334
|
+
input.panelFocused = false;
|
|
335
|
+
conversation.setSplashSuppressed(false);
|
|
336
|
+
conversation.log(`Panel "${panelId}" is not part of the Agent front door yet. Opening the matching Agent workspace.`, { fg: '214' });
|
|
337
|
+
input.openAgentWorkspace(commandContext, agentWorkspaceCategoryForPanel(panelId));
|
|
349
338
|
conversation.rebuildHistory();
|
|
350
339
|
render();
|
|
351
340
|
};
|
|
@@ -137,6 +137,12 @@ function requireDescription(args: AgentLocalRegistryToolArgs): string {
|
|
|
137
137
|
return description;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
+
function requireTextField(value: unknown, fieldName: string): string {
|
|
141
|
+
const text = readString(value);
|
|
142
|
+
if (!text) throw new Error(`${fieldName} is required.`);
|
|
143
|
+
return text;
|
|
144
|
+
}
|
|
145
|
+
|
|
140
146
|
function requireSummary(args: AgentLocalRegistryToolArgs): string {
|
|
141
147
|
const summary = readString(args.summary || args.description);
|
|
142
148
|
if (!summary) throw new Error('summary is required.');
|
|
@@ -299,7 +305,7 @@ function handlePersona(shellPaths: ShellPathService, action: AgentLocalRegistryA
|
|
|
299
305
|
const persona = registry.create({
|
|
300
306
|
name: requireName(args),
|
|
301
307
|
description: requireDescription(args),
|
|
302
|
-
body:
|
|
308
|
+
body: requireTextField(args.body, 'body'),
|
|
303
309
|
tags: readStringList(args.tags),
|
|
304
310
|
triggers: readStringList(args.triggers),
|
|
305
311
|
source: 'agent',
|
|
@@ -350,7 +356,7 @@ function handleSkill(shellPaths: ShellPathService, action: AgentLocalRegistryAct
|
|
|
350
356
|
const skill = registry.create({
|
|
351
357
|
name: requireName(args),
|
|
352
358
|
description: requireDescription(args),
|
|
353
|
-
procedure:
|
|
359
|
+
procedure: requireTextField(args.procedure, 'procedure'),
|
|
354
360
|
triggers: readStringList(args.triggers),
|
|
355
361
|
tags: readStringList(args.tags),
|
|
356
362
|
enabled: args.enabled === true,
|
|
@@ -441,7 +447,7 @@ function handleRoutine(shellPaths: ShellPathService, action: AgentLocalRegistryA
|
|
|
441
447
|
const routine = registry.create({
|
|
442
448
|
name: requireName(args),
|
|
443
449
|
description: requireDescription(args),
|
|
444
|
-
steps:
|
|
450
|
+
steps: requireTextField(args.steps, 'steps'),
|
|
445
451
|
triggers: readStringList(args.triggers),
|
|
446
452
|
tags: readStringList(args.tags),
|
|
447
453
|
enabled: args.enabled === true,
|
|
@@ -469,7 +475,7 @@ function handleRoutine(shellPaths: ShellPathService, action: AgentLocalRegistryA
|
|
|
469
475
|
const routine = registry.markStarted(requireId(args));
|
|
470
476
|
return [
|
|
471
477
|
`Started Agent-local routine ${routine.id}: ${routine.name}`,
|
|
472
|
-
'Policy: same main conversation; no hidden background job,
|
|
478
|
+
'Policy: same main conversation; no hidden background job, connected-host mutation, or external side effect was started.',
|
|
473
479
|
'',
|
|
474
480
|
routine.steps,
|
|
475
481
|
].join('\n');
|
|
@@ -83,8 +83,6 @@ const READ_ONLY_AGENT_TOOL_MODES = [
|
|
|
83
83
|
'templates',
|
|
84
84
|
'get',
|
|
85
85
|
'budget',
|
|
86
|
-
'wrfc-chains',
|
|
87
|
-
'wrfc-history',
|
|
88
86
|
'cohort-status',
|
|
89
87
|
'cohort-report',
|
|
90
88
|
] as const;
|
|
@@ -174,7 +172,7 @@ const STATE_MUTATION_DENIAL = [
|
|
|
174
172
|
const SETTINGS_MUTATION_DENIAL = [
|
|
175
173
|
'GoodVibes Agent does not mutate configuration through model tools in the main conversation.',
|
|
176
174
|
'Use explicit Agent CLI/slash settings commands for intentional config changes.',
|
|
177
|
-
'Secrets, tokens, passwords,
|
|
175
|
+
'Secrets, tokens, passwords, connected-host lifecycle settings, and connected-host exposure settings require explicit user action outside the model tool surface.',
|
|
178
176
|
].join(' ');
|
|
179
177
|
|
|
180
178
|
const INSPECT_WRITE_DENIAL = [
|
|
@@ -191,8 +189,8 @@ const DURABLE_WORKFLOW_MUTATION_DENIAL = [
|
|
|
191
189
|
|
|
192
190
|
const CONTROL_MUTATION_DENIAL = [
|
|
193
191
|
'GoodVibes Agent only inspects runtime-owned product-control surfaces from the main conversation.',
|
|
194
|
-
'Product-control mutation,
|
|
195
|
-
'Use explicit Agent CLI/slash commands for Agent-owned changes, and keep
|
|
192
|
+
'Product-control mutation, connected-host lifecycle, and connected-host posture changes are disabled here.',
|
|
193
|
+
'Use explicit Agent CLI/slash commands for Agent-owned changes, and keep connected-host lifecycle external.',
|
|
196
194
|
].join(' ');
|
|
197
195
|
|
|
198
196
|
export function installAgentToolPolicyGuard(registry: ToolRegistry, options: AgentToolPolicyGuardOptions = {}): void {
|
|
@@ -250,7 +248,7 @@ export function installAgentToolPolicyGuard(registry: ToolRegistry, options: Age
|
|
|
250
248
|
modeSet: READ_ONLY_CONTROL_TOOL_MODE_SET,
|
|
251
249
|
description: [
|
|
252
250
|
'Read-only product-control inspection for GoodVibes Agent.',
|
|
253
|
-
'Command, panel, and subscription catalogs can be inspected, but product-control mutation and
|
|
251
|
+
'Command, panel, and subscription catalogs can be inspected, but product-control mutation and connected-host lifecycle are external.',
|
|
254
252
|
].join(' '),
|
|
255
253
|
denial: CONTROL_MUTATION_DENIAL,
|
|
256
254
|
});
|
|
@@ -363,7 +361,7 @@ export function wrapBlockedSettingsToolForAgentPolicy(tool: Tool): void {
|
|
|
363
361
|
tool.definition.description = [
|
|
364
362
|
'Blocked in GoodVibes Agent main conversation: configuration mutation.',
|
|
365
363
|
'Use explicit Agent CLI/slash settings commands for intentional config changes.',
|
|
366
|
-
'
|
|
364
|
+
'Connected-host lifecycle and service exposure remain externally managed outside GoodVibes Agent.',
|
|
367
365
|
].join(' ');
|
|
368
366
|
tool.definition.sideEffects = [];
|
|
369
367
|
tool.definition.parameters = {
|
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 = '0.1.
|
|
9
|
+
let _version = '0.1.117';
|
|
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 {
|
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
2
|
-
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { CommandRegistry } from '../input/command-registry.ts';
|
|
5
|
-
import { registerBuiltinCommands } from '../input/commands.ts';
|
|
6
|
-
|
|
7
|
-
export interface PackageCliBinVerification {
|
|
8
|
-
readonly command: 'goodvibes-agent';
|
|
9
|
-
readonly target: string;
|
|
10
|
-
readonly exists: boolean;
|
|
11
|
-
readonly executable: boolean;
|
|
12
|
-
readonly usesBunShebang: boolean;
|
|
13
|
-
readonly hasSourceEntrypoint: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface PackageCliVerificationReport {
|
|
17
|
-
readonly packageName: string;
|
|
18
|
-
readonly version: string;
|
|
19
|
-
readonly bins: readonly PackageCliBinVerification[];
|
|
20
|
-
readonly tarball: {
|
|
21
|
-
readonly entryCount: number;
|
|
22
|
-
readonly unpackedSize: number;
|
|
23
|
-
readonly requiredPathsPresent: readonly string[];
|
|
24
|
-
readonly forbiddenPaths: readonly string[];
|
|
25
|
-
};
|
|
26
|
-
readonly packageFacingText: {
|
|
27
|
-
readonly checkedPaths: readonly string[];
|
|
28
|
-
readonly failures: readonly string[];
|
|
29
|
-
};
|
|
30
|
-
readonly issues: readonly string[];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const REQUIRED_BIN_COMMANDS = ['goodvibes-agent'] as const;
|
|
34
|
-
const REQUIRED_TARBALL_PATHS = [
|
|
35
|
-
'README.md',
|
|
36
|
-
'CHANGELOG.md',
|
|
37
|
-
'LICENSE',
|
|
38
|
-
'package.json',
|
|
39
|
-
'src/main.ts',
|
|
40
|
-
'dist/package/main.js',
|
|
41
|
-
'bin/goodvibes-agent.ts',
|
|
42
|
-
'tsconfig.json',
|
|
43
|
-
'docs/README.md',
|
|
44
|
-
'docs/getting-started.md',
|
|
45
|
-
'docs/connected-services.md',
|
|
46
|
-
'docs/release-and-publishing.md',
|
|
47
|
-
] as const;
|
|
48
|
-
const FORBIDDEN_TARBALL_PREFIXES = ['.github/', 'src/test/', 'src/.test/', '.goodvibes/', 'vendor/'] as const;
|
|
49
|
-
const FORBIDDEN_TARBALL_DOCS = [
|
|
50
|
-
['docs/cloud', 'flare-batch.md'].join(''),
|
|
51
|
-
['docs/home', 'assistant-surface.md'].join(''),
|
|
52
|
-
'docs/wrfc/',
|
|
53
|
-
] as const;
|
|
54
|
-
const FORBIDDEN_TARBALL_FILES = new Set([
|
|
55
|
-
'src/panels/agent-inspector-panel.ts',
|
|
56
|
-
'src/panels/agent-inspector-shared.ts',
|
|
57
|
-
'src/panels/agent-logs-panel.ts',
|
|
58
|
-
'src/panels/agent-logs-shared.ts',
|
|
59
|
-
'src/tools/wrfc-agent-guard.ts',
|
|
60
|
-
'src/renderer/agent-detail-modal.ts',
|
|
61
|
-
'src/renderer/process-summary.ts',
|
|
62
|
-
]);
|
|
63
|
-
const PACKAGE_FACING_TEXT_PATHS = [
|
|
64
|
-
'README.md',
|
|
65
|
-
'CHANGELOG.md',
|
|
66
|
-
'docs/README.md',
|
|
67
|
-
'docs/getting-started.md',
|
|
68
|
-
'docs/connected-services.md',
|
|
69
|
-
'docs/release-and-publishing.md',
|
|
70
|
-
] as const;
|
|
71
|
-
const PACKAGE_FACING_FORBIDDEN_TEXT = [
|
|
72
|
-
['/api/', 'knowledge'].join(''),
|
|
73
|
-
['/api/home', 'assistant'].join(''),
|
|
74
|
-
['home', 'assistant.home', 'Graph'].join(''),
|
|
75
|
-
['include', 'AllSpaces'].join(''),
|
|
76
|
-
['knowledge', 'SpaceId'].join(''),
|
|
77
|
-
['@pellux/goodvibes-', 'tui'].join(''),
|
|
78
|
-
['@pellux/goodvibes-', 'daemon'].join(''),
|
|
79
|
-
['goodvibes-', 'daemon'].join(''),
|
|
80
|
-
['~/.goodvibes/', 'tui'].join(''),
|
|
81
|
-
['Home', ' Assistant'].join(''),
|
|
82
|
-
['Home', 'Graph'].join(''),
|
|
83
|
-
['Cloud', 'flare'].join(''),
|
|
84
|
-
['Open', 'Claw'].join(''),
|
|
85
|
-
['Her', 'mes'].join(''),
|
|
86
|
-
['cap', 'abilities audit'].join(''),
|
|
87
|
-
['cap', 'abilities command'].join(''),
|
|
88
|
-
['near', '-fork'].join(''),
|
|
89
|
-
['Optional ', 'Browser Access'].join(''),
|
|
90
|
-
['Optional ', 'Other-Device Access'].join(''),
|
|
91
|
-
['Optional ', 'Incoming Events'].join(''),
|
|
92
|
-
['Service ', '& Network'].join(''),
|
|
93
|
-
['Surfaces ', '& Integrations'].join(''),
|
|
94
|
-
['runtime', '-isolation'].join(''),
|
|
95
|
-
['goodvibes-agent', 'serve'].join(' '),
|
|
96
|
-
['goodvibes-agent', 'service'].join(' '),
|
|
97
|
-
['goodvibes-agent', 'services'].join(' '),
|
|
98
|
-
['goodvibes-agent', 'surfaces'].join(' '),
|
|
99
|
-
['goodvibes-agent', 'surface'].join(' '),
|
|
100
|
-
['goodvibes-agent', 'listener'].join(' '),
|
|
101
|
-
['goodvibes-agent', 'control-plane'].join(' '),
|
|
102
|
-
['goodvibes-agent', 'remote'].join(' '),
|
|
103
|
-
['goodvibes-agent', 'bridge'].join(' '),
|
|
104
|
-
['goodvibes-agent', 'web'].join(' '),
|
|
105
|
-
['goodvibes-agent', 'launch'].join(' '),
|
|
106
|
-
['goodvibes-agent', 'start'].join(' '),
|
|
107
|
-
['tui ', '[path]'].join(''),
|
|
108
|
-
['tui', '|launch'].join(''),
|
|
109
|
-
['tui', '|launch|start'].join(''),
|
|
110
|
-
'Every plan must have a multi-agent execution strategy',
|
|
111
|
-
'NEVER skip WRFC',
|
|
112
|
-
'ALWAYS work in parallel when implementing a plan',
|
|
113
|
-
'PRIMARY GOAL: Fully complete and functional code',
|
|
114
|
-
'You are a code reviewer for the WRFC',
|
|
115
|
-
'ReviewerReport',
|
|
116
|
-
'"wrfcId"',
|
|
117
|
-
] as const;
|
|
118
|
-
const PACKAGE_FACING_REQUIRED_TEXT: readonly {
|
|
119
|
-
readonly path: typeof PACKAGE_FACING_TEXT_PATHS[number];
|
|
120
|
-
readonly required: readonly string[];
|
|
121
|
-
}[] = [
|
|
122
|
-
{ path: 'README.md', required: ['/api/goodvibes-agent/knowledge', 'bun add -g @pellux/goodvibes-agent'] },
|
|
123
|
-
{ path: 'docs/README.md', required: ['/api/goodvibes-agent/knowledge'] },
|
|
124
|
-
{ path: 'docs/getting-started.md', required: ['/api/goodvibes-agent/knowledge', 'bun add -g @pellux/goodvibes-agent'] },
|
|
125
|
-
{ path: 'docs/connected-services.md', required: ['/api/goodvibes-agent/knowledge'] },
|
|
126
|
-
{ path: 'docs/release-and-publishing.md', required: ['/api/goodvibes-agent/knowledge', 'bun add -g @pellux/goodvibes-agent'] },
|
|
127
|
-
];
|
|
128
|
-
const NON_COMMAND_ROUTE_ROOTS = new Set(['api', 'status']);
|
|
129
|
-
|
|
130
|
-
function readPackageJson(root: string): Record<string, unknown> {
|
|
131
|
-
return JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8')) as Record<string, unknown>;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function buildRegisteredSlashCommandNames(): ReadonlySet<string> {
|
|
135
|
-
const registry = new CommandRegistry();
|
|
136
|
-
registerBuiltinCommands(registry);
|
|
137
|
-
const names = new Set<string>();
|
|
138
|
-
for (const command of registry.list()) {
|
|
139
|
-
names.add(command.name);
|
|
140
|
-
for (const alias of command.aliases ?? []) names.add(alias);
|
|
141
|
-
}
|
|
142
|
-
return names;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function verifyPackageFacingSlashCommands(path: string, content: string, registeredCommands: ReadonlySet<string>): readonly string[] {
|
|
146
|
-
const failures: string[] = [];
|
|
147
|
-
const commandPattern = /(^|[\s`([])\/([a-z][a-z0-9_-]*)(?=$|[\s`.,;:)\]])/g;
|
|
148
|
-
const lines = content.split(/\r?\n/);
|
|
149
|
-
for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
|
|
150
|
-
const line = lines[lineIndex] ?? '';
|
|
151
|
-
commandPattern.lastIndex = 0;
|
|
152
|
-
for (let match = commandPattern.exec(line); match !== null; match = commandPattern.exec(line)) {
|
|
153
|
-
const root = match[2] ?? '';
|
|
154
|
-
if (NON_COMMAND_ROUTE_ROOTS.has(root)) continue;
|
|
155
|
-
if (registeredCommands.has(root)) continue;
|
|
156
|
-
failures.push(`package-facing text ${path}:${lineIndex + 1} references unknown Agent slash command: /${root}`);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return failures;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function hasExecutableBit(path: string): boolean {
|
|
163
|
-
return existsSync(path) && (statSync(path).mode & 0o111) !== 0;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
function verifyBin(root: string, command: typeof REQUIRED_BIN_COMMANDS[number], target: string | undefined): PackageCliBinVerification {
|
|
167
|
-
const binPath = target ? join(root, target) : '';
|
|
168
|
-
const source = target && existsSync(binPath) ? readFileSync(binPath, 'utf-8') : '';
|
|
169
|
-
return {
|
|
170
|
-
command,
|
|
171
|
-
target: target ?? '',
|
|
172
|
-
exists: Boolean(target) && existsSync(binPath),
|
|
173
|
-
executable: Boolean(target) && hasExecutableBit(binPath),
|
|
174
|
-
usesBunShebang: source.startsWith('#!/usr/bin/env bun'),
|
|
175
|
-
hasSourceEntrypoint: source.includes('dist') && source.includes('package') && source.includes('main.js'),
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function registryPackDryRun(root: string): { readonly files: readonly string[]; readonly entryCount: number; readonly unpackedSize: number } {
|
|
180
|
-
execSync('bun run build:package-runtime', {
|
|
181
|
-
cwd: root,
|
|
182
|
-
stdio: 'inherit',
|
|
183
|
-
});
|
|
184
|
-
const raw = execSync('npm pack --json --dry-run', {
|
|
185
|
-
cwd: root,
|
|
186
|
-
encoding: 'utf-8',
|
|
187
|
-
stdio: ['ignore', 'pipe', 'inherit'],
|
|
188
|
-
});
|
|
189
|
-
const [packResult] = JSON.parse(raw) as Array<{ files?: Array<{ path?: string }>; entryCount?: number; unpackedSize?: number }>;
|
|
190
|
-
return {
|
|
191
|
-
files: Array.isArray(packResult?.files) ? packResult.files.map((entry) => String(entry.path ?? '')) : [],
|
|
192
|
-
entryCount: Number(packResult?.entryCount ?? 0),
|
|
193
|
-
unpackedSize: Number(packResult?.unpackedSize ?? 0),
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export function verifyPackageFacingText(root: string): { readonly checkedPaths: readonly string[]; readonly failures: readonly string[] } {
|
|
198
|
-
const failures: string[] = [];
|
|
199
|
-
const registeredCommands = buildRegisteredSlashCommandNames();
|
|
200
|
-
for (const path of PACKAGE_FACING_TEXT_PATHS) {
|
|
201
|
-
const absolutePath = join(root, path);
|
|
202
|
-
if (!existsSync(absolutePath)) {
|
|
203
|
-
failures.push(`package-facing text is missing: ${path}`);
|
|
204
|
-
continue;
|
|
205
|
-
}
|
|
206
|
-
const content = readFileSync(absolutePath, 'utf-8');
|
|
207
|
-
if (path !== 'CHANGELOG.md') {
|
|
208
|
-
failures.push(...verifyPackageFacingSlashCommands(path, content, registeredCommands));
|
|
209
|
-
}
|
|
210
|
-
for (const forbidden of PACKAGE_FACING_FORBIDDEN_TEXT) {
|
|
211
|
-
if (content.includes(forbidden)) {
|
|
212
|
-
failures.push(`package-facing text ${path} contains forbidden default/TUI route or policy: ${forbidden}`);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
const requirement = PACKAGE_FACING_REQUIRED_TEXT.find((entry) => entry.path === path);
|
|
216
|
-
if (requirement) {
|
|
217
|
-
for (const required of requirement.required) {
|
|
218
|
-
if (!content.includes(required)) {
|
|
219
|
-
failures.push(`package-facing text ${path} is missing required Agent route/policy text: ${required}`);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
checkedPaths: PACKAGE_FACING_TEXT_PATHS,
|
|
226
|
-
failures,
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function verifyPackageCliInstall(root: string): PackageCliVerificationReport {
|
|
231
|
-
const pkg = readPackageJson(root);
|
|
232
|
-
const bin = pkg.bin && typeof pkg.bin === 'object' ? pkg.bin as Record<string, string | undefined> : {};
|
|
233
|
-
const bins = REQUIRED_BIN_COMMANDS.map((command) => verifyBin(root, command, bin[command]));
|
|
234
|
-
const pack = registryPackDryRun(root);
|
|
235
|
-
const requiredPathsPresent = REQUIRED_TARBALL_PATHS.filter((path) => pack.files.includes(path));
|
|
236
|
-
const forbiddenPaths = pack.files.filter((path) => {
|
|
237
|
-
if (FORBIDDEN_TARBALL_PREFIXES.some((prefix) => path.startsWith(prefix))) return true;
|
|
238
|
-
if (FORBIDDEN_TARBALL_FILES.has(path)) return true;
|
|
239
|
-
return FORBIDDEN_TARBALL_DOCS.some((docPath) => path === docPath || path.startsWith(docPath));
|
|
240
|
-
});
|
|
241
|
-
const issues: string[] = [];
|
|
242
|
-
const packageFacingText = verifyPackageFacingText(root);
|
|
243
|
-
|
|
244
|
-
for (const item of bins) {
|
|
245
|
-
if (!item.target) issues.push(`package.json bin is missing ${item.command}.`);
|
|
246
|
-
if (!item.exists) issues.push(`bin target does not exist: ${item.command} -> ${item.target}`);
|
|
247
|
-
if (!item.executable) issues.push(`bin target is not executable: ${item.command} -> ${item.target}`);
|
|
248
|
-
if (!item.usesBunShebang) issues.push(`bin target does not use Bun shebang: ${item.command} -> ${item.target}`);
|
|
249
|
-
if (!item.hasSourceEntrypoint) issues.push(`bin target does not load the packaged Agent runtime: ${item.command}`);
|
|
250
|
-
}
|
|
251
|
-
for (const path of REQUIRED_TARBALL_PATHS) {
|
|
252
|
-
if (!pack.files.includes(path)) issues.push(`registry tarball missing required path: ${path}`);
|
|
253
|
-
}
|
|
254
|
-
for (const path of forbiddenPaths) {
|
|
255
|
-
issues.push(`registry tarball includes forbidden path: ${path}`);
|
|
256
|
-
}
|
|
257
|
-
for (const failure of packageFacingText.failures) {
|
|
258
|
-
issues.push(failure);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
packageName: String(pkg.name ?? ''),
|
|
263
|
-
version: String(pkg.version ?? ''),
|
|
264
|
-
bins,
|
|
265
|
-
tarball: {
|
|
266
|
-
entryCount: pack.entryCount,
|
|
267
|
-
unpackedSize: pack.unpackedSize,
|
|
268
|
-
requiredPathsPresent,
|
|
269
|
-
forbiddenPaths,
|
|
270
|
-
},
|
|
271
|
-
packageFacingText,
|
|
272
|
-
issues,
|
|
273
|
-
};
|
|
274
|
-
}
|