@pellux/goodvibes-agent 0.1.2 → 0.1.4

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +12 -1
  4. package/docs/README.md +2 -0
  5. package/docs/getting-started.md +19 -1
  6. package/docs/release-and-publishing.md +3 -1
  7. package/package.json +10 -1
  8. package/src/agent/persona-registry.ts +379 -0
  9. package/src/agent/skill-registry.ts +360 -0
  10. package/src/audio/spoken-turn-model-routing.ts +2 -1
  11. package/src/cli/agent-knowledge-command.ts +46 -10
  12. package/src/cli/management-commands.ts +3 -1
  13. package/src/config/surface.ts +1 -0
  14. package/src/input/agent-workspace.ts +32 -2
  15. package/src/input/command-registry.ts +4 -1
  16. package/src/input/commands/agent-skills-runtime.ts +216 -0
  17. package/src/input/commands/knowledge.ts +18 -18
  18. package/src/input/commands/personas-runtime.ts +219 -0
  19. package/src/input/commands/skills-runtime.ts +7 -2
  20. package/src/input/commands.ts +4 -0
  21. package/src/input/panel-integration-actions.ts +0 -52
  22. package/src/main.ts +2 -1
  23. package/src/panels/builtin/session.ts +4 -3
  24. package/src/panels/index.ts +0 -5
  25. package/src/panels/orchestration-panel.ts +4 -5
  26. package/src/panels/qr-panel.ts +3 -2
  27. package/src/panels/tasks-panel.ts +4 -4
  28. package/src/renderer/agent-workspace.ts +2 -0
  29. package/src/runtime/bootstrap-command-context.ts +3 -0
  30. package/src/runtime/bootstrap-command-parts.ts +6 -2
  31. package/src/runtime/bootstrap-core.ts +9 -5
  32. package/src/runtime/bootstrap-shell.ts +3 -1
  33. package/src/runtime/bootstrap.ts +10 -2
  34. package/src/runtime/cloudflare-control-plane.ts +2 -1
  35. package/src/runtime/services.ts +3 -3
  36. package/src/version.ts +1 -1
  37. package/src/daemon/cli.ts +0 -55
  38. package/src/daemon/safe-serve.ts +0 -61
  39. package/src/panels/diff-panel.ts +0 -520
  40. package/src/panels/file-explorer-panel.ts +0 -584
  41. package/src/panels/file-preview-panel.ts +0 -434
  42. package/src/panels/git-panel.ts +0 -638
  43. package/src/panels/sandbox-panel.ts +0 -283
  44. package/src/panels/symbol-outline-panel.ts +0 -486
  45. package/src/panels/worktree-panel.ts +0 -182
  46. package/src/panels/wrfc-panel.ts +0 -609
@@ -14,6 +14,7 @@ import {
14
14
  buildCompanionConnectionInfo,
15
15
  } from '@pellux/goodvibes-sdk/platform/pairing';
16
16
  import { copyToClipboard } from '../../utils/clipboard.ts';
17
+ import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../../config/surface.ts';
17
18
 
18
19
  function getLocalNetworkIp(): string {
19
20
  const nets = networkInterfaces();
@@ -51,7 +52,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
51
52
  factory: () => {
52
53
  if (!deps.daemonHomeDir) throw new Error('daemonHomeDir must be provided to the session panel factory via BuiltinPanelDeps');
53
54
  const daemonHomeDir = deps.daemonHomeDir;
54
- const tokenRecord = getOrCreateCompanionToken('tui', { daemonHomeDir });
55
+ const tokenRecord = getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir });
55
56
  const daemonPort = deps.configManager.get('controlPlane.port');
56
57
  const daemonHost = String(process.env['GOODVIBES_DAEMON_HOST'] ?? getLocalNetworkIp());
57
58
  const daemonUrl = `http://${daemonHost}:${daemonPort}`;
@@ -60,7 +61,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
60
61
  daemonUrl,
61
62
  token: tokenRecord.token,
62
63
  password: bootstrapPassword,
63
- surface: 'tui',
64
+ surface: GOODVIBES_AGENT_PAIRING_SURFACE,
64
65
  });
65
66
  const regenerate = (): typeof connectionInfo => {
66
67
  const newRecord = regenerateCompanionToken({ daemonHomeDir });
@@ -68,7 +69,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
68
69
  daemonUrl,
69
70
  token: newRecord.token,
70
71
  password: bootstrapPassword,
71
- surface: 'tui',
72
+ surface: GOODVIBES_AGENT_PAIRING_SURFACE,
72
73
  });
73
74
  };
74
75
  return new QrPanel(connectionInfo, regenerate, copyToClipboard);
@@ -6,13 +6,9 @@ export { TokenBudgetPanel } from './token-budget-panel.ts';
6
6
  export { CostTrackerPanel } from './cost-tracker-panel.ts';
7
7
  export { AgentInspectorPanel } from './agent-inspector-panel.ts';
8
8
  export { AgentLogsPanel } from './agent-logs-panel.ts';
9
- export { WrfcPanel } from './wrfc-panel.ts';
10
9
  export { ProviderHealthPanel } from './provider-health-panel.ts';
11
10
  export { ProviderHealthTracker } from './provider-health-tracker.ts';
12
11
  export type { ProviderHealth, ProviderStatus } from './provider-health-tracker.ts';
13
- export { GitPanel } from './git-panel.ts';
14
- export { SymbolOutlinePanel } from './symbol-outline-panel.ts';
15
- export type { SymbolEntry, SymbolKind } from './symbol-outline-panel.ts';
16
12
  export { ProviderStatsPanel } from './provider-stats-panel.ts';
17
13
  export { SessionBrowserPanel } from './session-browser-panel.ts';
18
14
  export { DocsPanel } from './docs-panel.ts';
@@ -38,7 +34,6 @@ export { SubscriptionPanel } from './subscription-panel.ts';
38
34
  export { HooksPanel } from './hooks-panel.ts';
39
35
  export { SecurityPanel } from './security-panel.ts';
40
36
  export { MarketplacePanel } from './marketplace-panel.ts';
41
- export { SandboxPanel } from './sandbox-panel.ts';
42
37
  export { ApprovalPanel } from './approval-panel.ts';
43
38
  export { KnowledgePanel } from './knowledge-panel.ts';
44
39
  export { SystemMessagesPanel } from './system-messages-panel.ts';
@@ -1,6 +1,5 @@
1
1
  /**
2
- * OrchestrationPanel — displays task graphs, node contracts, recursion guards,
3
- * and WRFC-visible orchestration state.
2
+ * OrchestrationPanel — displays task graphs, node contracts, and recursion guards.
4
3
  *
5
4
  * Migrated (Wave B2): extends ScrollableListPanel<OrchestrationGraphRecord>.
6
5
  * Navigation (up/down/j/k) is handled by the base class.
@@ -102,7 +101,7 @@ export class OrchestrationPanel extends ScrollableListPanel<OrchestrationGraphRe
102
101
  // ---------------------------------------------------------------------------
103
102
 
104
103
  public render(width: number, height: number): Line[] {
105
- const intro = 'Task graphs, node contracts, recursion guards, and WRFC-visible orchestration state.';
104
+ const intro = 'Read-only task graph posture, node contracts, and recursion guard state. Agent does not start local worker chains.';
106
105
 
107
106
  if (!this.readModel) {
108
107
  this.needsRender = false;
@@ -134,7 +133,7 @@ export class OrchestrationPanel extends ScrollableListPanel<OrchestrationGraphRe
134
133
  { label: 'failed', value: String(snapshot.totalFailedGraphs), valueColor: snapshot.totalFailedGraphs > 0 ? C.failed : C.dim },
135
134
  { label: 'guards', value: String(snapshot.recursionGuardTrips), valueColor: snapshot.recursionGuardTrips > 0 ? C.blocked : C.dim },
136
135
  ], C),
137
- buildGuidanceLine(width, '/orchestration', 'inspect recursive execution posture, graph health, and node contract flow', C),
136
+ buildGuidanceLine(width, '/orchestration', 'inspect graph health without spawning local workers', C),
138
137
  ];
139
138
  if (graphs.length === 0) {
140
139
  this.needsRender = false;
@@ -148,7 +147,7 @@ export class OrchestrationPanel extends ScrollableListPanel<OrchestrationGraphRe
148
147
  ...buildEmptyState(
149
148
  width,
150
149
  this.getEmptyStateMessage(),
151
- 'Graphs, nodes, child contracts, and recursion guard trips will appear here as orchestration starts.',
150
+ 'Graphs, nodes, child contracts, and recursion guard trips appear here only if a runtime record already exists.',
152
151
  [
153
152
  { command: '/tasks', summary: 'create or inspect task flows that feed orchestration graphs' },
154
153
  { command: '/communication', summary: 'review structured agent communication alongside graph execution' },
@@ -7,6 +7,7 @@ import {
7
7
  } from './polish.ts';
8
8
  import { renderQrMatrix, generateQrMatrix } from '../renderer/qr-renderer.ts';
9
9
  import { encodeConnectionPayload } from '@pellux/goodvibes-sdk/platform/pairing';
10
+ import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
10
11
 
11
12
  const C = {
12
13
  ...DEFAULT_PANEL_PALETTE,
@@ -32,7 +33,7 @@ export interface QrPanelConnectionInfo {
32
33
  readonly password?: string;
33
34
  /** SDK/surface version (defaults to '0.0.0' if omitted) */
34
35
  readonly version?: string;
35
- /** Surface identifier (defaults to 'tui' if omitted) */
36
+ /** Surface identifier (defaults to GoodVibes Agent if omitted) */
36
37
  readonly surface?: string;
37
38
  }
38
39
 
@@ -139,7 +140,7 @@ export class QrPanel extends BasePanel {
139
140
  username: this.connectionInfo.username,
140
141
  ...(this.connectionInfo.password !== undefined ? { password: this.connectionInfo.password } : {}),
141
142
  version: this.connectionInfo.version ?? '0.0.0',
142
- surface: this.connectionInfo.surface ?? 'tui',
143
+ surface: this.connectionInfo.surface ?? GOODVIBES_AGENT_PAIRING_SURFACE,
143
144
  });
144
145
  const matrix = generateQrMatrix(payload);
145
146
  const qrLines = renderQrMatrix(matrix.modules, width, { fg: C.qrFg, bg: C.qrBg });
@@ -179,7 +179,7 @@ export class TasksPanel extends ScrollableListPanel<RuntimeTask> {
179
179
  protected override getEmptyStateActions() {
180
180
  return [
181
181
  { command: '/tasks create', summary: 'create a tracked task from the shell' },
182
- { command: '/orchestration', summary: 'review graph-native task execution and WRFC flows' },
182
+ { command: '/delegate <task>', summary: 'send explicit build/fix/review work to GoodVibes TUI' },
183
183
  ];
184
184
  }
185
185
 
@@ -276,8 +276,8 @@ export class TasksPanel extends ScrollableListPanel<RuntimeTask> {
276
276
  ]));
277
277
  }
278
278
  postureLines.push(
279
- buildGuidanceLine(width, '/teamwork review', 'inspect task-family posture, archetype metadata, and recovery options for active work', C),
280
- buildGuidanceLine(width, '/worktree task <task-id>', 'review worktree ownership, restore, and merge posture for the selected task', C),
279
+ buildGuidanceLine(width, '/tasks', 'inspect local runtime task posture without starting background agents', C),
280
+ buildGuidanceLine(width, '/delegate <task>', 'delegate explicit build/fix/review work to GoodVibes TUI when code execution is required', C),
281
281
  );
282
282
 
283
283
  const detailRows: Line[] = [];
@@ -354,7 +354,7 @@ export class TasksPanel extends ScrollableListPanel<RuntimeTask> {
354
354
  [String(attachedWorktrees.paused), attachedWorktrees.paused > 0 ? C.blocked : C.dim],
355
355
  ]));
356
356
  detailRows.push(buildPanelLine(width, [[
357
- ` Next: /worktree task ${selected.id} /worktree recover task ${selected.id}`,
357
+ ' Worktree lifecycle is externalized; open GoodVibes TUI in the target workspace for recovery.',
358
358
  C.dim,
359
359
  ]]));
360
360
  for (const record of attachedWorktrees.records.slice(0, 2)) {
@@ -97,6 +97,8 @@ function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspac
97
97
  } else if (category.id === 'memory') {
98
98
  base.push(
99
99
  { text: `Session memories: ${snapshot.sessionMemoryCount}`, fg: PALETTE.info },
100
+ { text: `Local skills: ${snapshot.localSkillCount}; enabled: ${snapshot.enabledSkillCount}`, fg: PALETTE.info },
101
+ { text: `Local personas: ${snapshot.localPersonaCount}; active: ${snapshot.activePersonaName}`, fg: PALETTE.info },
100
102
  { text: 'Durable memory, skills, and personas remain Agent-local until shared registry contracts exist.', fg: PALETTE.good },
101
103
  { text: 'Secrets are rejected/redacted; store secret references instead of secret values.', fg: PALETTE.warn },
102
104
  );
@@ -100,6 +100,7 @@ export type CreateBootstrapCommandContextOptions = {
100
100
  sessionOrchestration?: ShellSessionOrchestrationService;
101
101
  operatorClient?: OperatorClient;
102
102
  peerClient?: PeerClient;
103
+ agentKnowledgeApi?: KnowledgeApi;
103
104
  knowledgeApi?: KnowledgeApi;
104
105
  hookApi?: HookApi;
105
106
  mcpApi?: McpApi;
@@ -170,6 +171,7 @@ export function createBootstrapCommandContext(
170
171
  sessionOrchestration,
171
172
  operatorClient,
172
173
  peerClient,
174
+ agentKnowledgeApi,
173
175
  knowledgeApi,
174
176
  hookApi,
175
177
  mcpApi,
@@ -245,6 +247,7 @@ export function createBootstrapCommandContext(
245
247
  const clients = createBootstrapCommandClientsSection({
246
248
  operatorClient,
247
249
  peerClient,
250
+ agentKnowledgeApi,
248
251
  providerApi,
249
252
  knowledgeApi,
250
253
  hookApi,
@@ -117,6 +117,7 @@ export interface BootstrapCommandSectionOptions {
117
117
  readonly operatorClient?: OperatorClient;
118
118
  readonly peerClient?: PeerClient;
119
119
  readonly providerApi?: ProviderApi;
120
+ readonly agentKnowledgeApi?: KnowledgeApi;
120
121
  readonly knowledgeApi?: KnowledgeApi;
121
122
  readonly hookApi?: HookApi;
122
123
  readonly mcpApi?: McpApi;
@@ -360,23 +361,26 @@ export function createBootstrapCommandExtensionsSection(
360
361
  >,
361
362
  shellServices: BootstrapCommandShellServices,
362
363
  ): BootstrapCommandExtensionSection {
364
+ const shellExtensionServices = shellServices.extensions;
363
365
  return {
364
366
  toolRegistry: options.toolRegistry,
365
367
  mcpRegistry: options.mcpRegistry,
366
- ...shellServices.extensions,
368
+ ...shellExtensionServices,
369
+ agentKnowledgeService: shellExtensionServices.knowledgeService,
367
370
  };
368
371
  }
369
372
 
370
373
  export function createBootstrapCommandClientsSection(
371
374
  options: Pick<
372
375
  BootstrapCommandSectionOptions,
373
- 'operatorClient' | 'peerClient' | 'providerApi' | 'knowledgeApi' | 'hookApi' | 'mcpApi' | 'opsApi' | 'directTransport'
376
+ 'operatorClient' | 'peerClient' | 'providerApi' | 'agentKnowledgeApi' | 'knowledgeApi' | 'hookApi' | 'mcpApi' | 'opsApi' | 'directTransport'
374
377
  >,
375
378
  ): BootstrapCommandClientSection {
376
379
  return {
377
380
  operator: options.operatorClient,
378
381
  peer: options.peerClient,
379
382
  providerApi: options.providerApi,
383
+ agentKnowledgeApi: options.agentKnowledgeApi,
380
384
  knowledgeApi: options.knowledgeApi,
381
385
  hookApi: options.hookApi,
382
386
  mcpApi: options.mcpApi,
@@ -126,16 +126,20 @@ export async function initializeBootstrapCore(
126
126
  isRunning: Boolean(configManager.get('controlPlane.enabled')),
127
127
  }, 'bootstrap.control-plane');
128
128
  domainDispatch.syncControlPlaneClient({
129
- id: 'client:tui',
130
- kind: 'tui',
131
- label: 'Terminal UI',
129
+ id: 'client:goodvibes-agent',
130
+ kind: 'service',
131
+ label: 'GoodVibes Agent',
132
132
  transport: 'local',
133
133
  connected: true,
134
134
  sessionId: userSessionId,
135
135
  authenticatedAt: Date.now(),
136
136
  lastSeenAt: Date.now(),
137
137
  capabilities: ['session', 'panels', 'commands', 'automation'],
138
- metadata: {},
138
+ metadata: {
139
+ product: 'goodvibes-agent',
140
+ surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
141
+ clientKindNote: 'SDK has no dedicated agent client kind yet; using service for the Agent operator surface.',
142
+ },
139
143
  }, 'bootstrap.control-plane');
140
144
 
141
145
  const {
@@ -238,7 +242,7 @@ export async function initializeBootstrapCore(
238
242
  webSearchService: services.webSearchService,
239
243
  channelRegistry: services.channelPlugins,
240
244
  remoteRunnerRegistry: services.remoteRunnerRegistry,
241
- knowledgeService: services.knowledgeService,
245
+ knowledgeService: services.agentKnowledgeService,
242
246
  archetypeLoader: services.archetypeLoader,
243
247
  configManager,
244
248
  providerRegistry: services.providerRegistry,
@@ -177,6 +177,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
177
177
  opsApi,
178
178
  providerApi,
179
179
  } = foundationClients;
180
+ const agentKnowledgeApi = createKnowledgeApi(services.agentKnowledgeService, { memoryRegistry: services.memoryRegistry });
180
181
  const remoteRuntime = createShellRemoteCommandService({
181
182
  readModels: uiServices.readModels,
182
183
  remoteRunnerRegistry: services.remoteRunnerRegistry,
@@ -239,7 +240,8 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
239
240
  sessionOrchestration: services.sessionOrchestration,
240
241
  operatorClient: directTransport.operator,
241
242
  peerClient: directTransport.peer,
242
- knowledgeApi: createKnowledgeApi(services.agentKnowledgeService, { memoryRegistry: services.memoryRegistry }),
243
+ agentKnowledgeApi,
244
+ knowledgeApi: agentKnowledgeApi,
243
245
  hookApi,
244
246
  mcpApi,
245
247
  opsApi,
@@ -42,6 +42,8 @@ import { createBootstrapShell } from './bootstrap-shell.ts';
42
42
  import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
43
43
  import { startMcpConfigAutoReload } from '../mcp/runtime-reload.ts';
44
44
  import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
45
+ import { buildActivePersonaPrompt } from '../agent/persona-registry.ts';
46
+ import { buildEnabledSkillsPrompt } from '../agent/skill-registry.ts';
45
47
 
46
48
  const GOODVIBES_AGENT_OPERATOR_POLICY = [
47
49
  '## GoodVibes Agent Operator Policy',
@@ -50,7 +52,7 @@ const GOODVIBES_AGENT_OPERATOR_POLICY = [
50
52
  '- WRFC is never the default Agent reasoning path. Do not create local WRFC chains for planning, research, operations, knowledge, memory, configuration, approvals, automation observability, or ordinary assistant work.',
51
53
  '- GoodVibes Agent is not the coding TUI. Do not use the `agent` tool to spawn local Engineer, Reviewer, Tester, Verifier, or batch-spawn roots from Agent.',
52
54
  '- When the user explicitly asks to build, implement, fix, patch, or review code, preserve the full original user ask and delegate one build request to GoodVibes TUI through the public shared-session/build-delegation contract. Include clear executionIntent and request WRFC only for explicit build/fix/review work or when the user explicitly asks for WRFC/agent review.',
53
- '- Do not narrow explicit build/fix/review requests into design-only, read-only, or no-write work unless the user explicitly requested that limitation. TUI owns file edits, git/worktree work, sandbox/QEMU UX, and any WRFC owner chain.',
55
+ '- Do not narrow explicit build/fix/review requests into design-only, read-only, or no-write work unless the user explicitly requested that limitation. TUI owns file edits, git/worktree work, sandbox/QEMU UX, and the WRFC owner chain.',
54
56
  '- If a stable public delegation route is unavailable, say that the task needs GoodVibes TUI delegation and report the missing route instead of pretending to implement it locally or spawning sibling local agents.',
55
57
  ].join('\n');
56
58
 
@@ -205,7 +207,13 @@ export async function bootstrapRuntime(
205
207
  const contextWindow = providerRegistry.getContextWindowForModel(currentModel);
206
208
  const tier = getTierForContextWindow(contextWindow);
207
209
  const supplement = getTierPromptSupplement(tier);
208
- return joinPromptParts(runtime.systemPrompt, GOODVIBES_AGENT_OPERATOR_POLICY, supplement);
210
+ return joinPromptParts(
211
+ runtime.systemPrompt,
212
+ GOODVIBES_AGENT_OPERATOR_POLICY,
213
+ buildEnabledSkillsPrompt(services.shellPaths),
214
+ buildActivePersonaPrompt(services.shellPaths),
215
+ supplement,
216
+ );
209
217
  },
210
218
  hookDispatcher,
211
219
  flagManager: services.featureFlags,
@@ -1,6 +1,7 @@
1
1
  import { join } from 'node:path';
2
2
  import { getOrCreateCompanionToken } from '@pellux/goodvibes-sdk/platform/pairing';
3
3
  import type { ConfigManager } from '../config/index.ts';
4
+ import { GOODVIBES_AGENT_PAIRING_SURFACE } from '../config/surface.ts';
4
5
 
5
6
  export const CLOUDFLARE_COMPONENT_IDS = [
6
7
  'workers',
@@ -296,7 +297,7 @@ export function buildDefaultCloudflareDaemonBaseUrl(configManager: Pick<ConfigMa
296
297
 
297
298
  function readDaemonToken(homeDirectory: string): string {
298
299
  const daemonHomeDir = join(homeDirectory, '.goodvibes', 'daemon');
299
- return getOrCreateCompanionToken('tui', { daemonHomeDir }).token;
300
+ return getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir }).token;
300
301
  }
301
302
 
302
303
  async function readJsonResponse<T>(response: Response): Promise<T> {
@@ -440,7 +440,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
440
440
  semanticService: homeGraphSemanticService,
441
441
  });
442
442
  const projectPlanningProjectId = projectPlanningProjectIdFromPath(workingDirectory);
443
- const projectPlanningService = new ProjectPlanningService(knowledgeStore, {
443
+ const projectPlanningService = new ProjectPlanningService(agentKnowledgeStore, {
444
444
  defaultProjectId: projectPlanningProjectId,
445
445
  });
446
446
  const workPlanStore = new WorkPlanStore({
@@ -473,7 +473,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
473
473
  }));
474
474
  const mediaProviders = new MediaProviderRegistry();
475
475
  ensureBuiltinMediaProviders(mediaProviders, artifactStore, providerRegistry);
476
- const multimodalService = new MultimodalService(artifactStore, mediaProviders, voiceService, knowledgeService);
476
+ const multimodalService = new MultimodalService(artifactStore, mediaProviders, voiceService, agentKnowledgeService);
477
477
  const pluginManager = new PluginManager({
478
478
  pathOptions: {
479
479
  cwd: shellPaths.workingDirectory,
@@ -560,7 +560,7 @@ export function createRuntimeServices(options: RuntimeServicesOptions): RuntimeS
560
560
  webSearchService,
561
561
  channelRegistry: channelPlugins,
562
562
  remoteRunnerRegistry,
563
- knowledgeService,
563
+ knowledgeService: agentKnowledgeService,
564
564
  memoryRegistry,
565
565
  archetypeLoader,
566
566
  configManager,
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.2';
9
+ let _version = '0.1.4';
10
10
  try {
11
11
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8'));
12
12
  _version = pkg.version ?? _version;
package/src/daemon/cli.ts DELETED
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env bun
2
- import {
3
- parseGoodVibesCli,
4
- renderGoodVibesDaemonHelp,
5
- renderGoodVibesVersion,
6
- } from '../cli/index.ts';
7
-
8
- function externalDaemonMessage(binary: string): string {
9
- return [
10
- `${binary} is disabled in GoodVibes Agent.`,
11
- 'GoodVibes Agent connects to an already-running GoodVibes daemon and never starts, installs, restarts, or owns daemon/listener lifecycle.',
12
- 'Start or manage the daemon from GoodVibes TUI or your daemon host tooling, then run goodvibes-agent against that external daemon.',
13
- ].join('\n');
14
- }
15
-
16
- async function main(): Promise<void> {
17
- const binary = 'goodvibes-daemon';
18
- const cli = parseGoodVibesCli(process.argv.slice(2), binary);
19
-
20
- if (cli.errors.length > 0) {
21
- console.error(cli.errors.join('\n'));
22
- console.error('');
23
- console.error(renderGoodVibesDaemonHelp(binary));
24
- process.exit(2);
25
- }
26
-
27
- if (cli.flags.help || cli.command === 'help') {
28
- console.log(renderGoodVibesDaemonHelp(binary));
29
- process.exit(0);
30
- }
31
-
32
- if (cli.flags.version || cli.command === 'version') {
33
- console.log(renderGoodVibesVersion('goodvibes-agent'));
34
- process.exit(0);
35
- }
36
-
37
- const message = externalDaemonMessage(binary);
38
- if (cli.flags.outputFormat === 'json') {
39
- console.log(JSON.stringify({
40
- ok: false,
41
- kind: 'daemon_lifecycle_external',
42
- command: binary,
43
- error: message,
44
- }, null, 2));
45
- } else {
46
- console.error(message);
47
- }
48
- process.exit(2);
49
- }
50
-
51
- main().catch((error: unknown) => {
52
- const message = error instanceof Error ? error.message : String(error);
53
- console.error(message);
54
- process.exit(1);
55
- });
@@ -1,61 +0,0 @@
1
- import { logger } from '@pellux/goodvibes-sdk/platform/utils';
2
- import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
3
-
4
- type HostServeFetch = (
5
- request: Request,
6
- server: unknown,
7
- ) => Response | undefined | Promise<Response | undefined>;
8
-
9
- type HostServeOptions = Parameters<typeof Bun.serve>[0] & {
10
- fetch?: HostServeFetch;
11
- };
12
-
13
- function requestPath(request: Request): string {
14
- try {
15
- return new URL(request.url).pathname;
16
- } catch {
17
- return request.url;
18
- }
19
- }
20
-
21
- export function createHostRequestFailureResponse(
22
- surface: string,
23
- request: Request,
24
- error: unknown,
25
- ): Response {
26
- const message = summarizeError(error);
27
- logger.error(`${surface}: request handler failed`, {
28
- method: request.method,
29
- path: requestPath(request),
30
- error: message,
31
- });
32
- return Response.json({
33
- error: message,
34
- code: 'HOST_REQUEST_HANDLER_FAILED',
35
- }, { status: 500 });
36
- }
37
-
38
- export function createSafeHostServeFactory(
39
- surface: string,
40
- baseServeFactory: typeof Bun.serve = Bun.serve,
41
- ): typeof Bun.serve {
42
- return ((options: HostServeOptions) => {
43
- const originalFetch = options.fetch;
44
- if (typeof originalFetch !== 'function') {
45
- return baseServeFactory(options as Parameters<typeof Bun.serve>[0]);
46
- }
47
-
48
- const wrappedFetch: HostServeFetch = async (request, server) => {
49
- try {
50
- return await originalFetch(request, server);
51
- } catch (error) {
52
- return createHostRequestFailureResponse(surface, request, error);
53
- }
54
- };
55
-
56
- return baseServeFactory({
57
- ...options,
58
- fetch: wrappedFetch,
59
- } as Parameters<typeof Bun.serve>[0]);
60
- }) as typeof Bun.serve;
61
- }