@pellux/goodvibes-agent 0.1.2 → 0.1.3
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 +6 -0
- package/LICENSE +21 -0
- package/README.md +12 -1
- package/docs/README.md +2 -0
- package/docs/getting-started.md +19 -1
- package/docs/release-and-publishing.md +3 -1
- package/package.json +10 -1
- package/src/agent/persona-registry.ts +379 -0
- package/src/agent/skill-registry.ts +360 -0
- package/src/audio/spoken-turn-model-routing.ts +2 -1
- package/src/cli/management-commands.ts +3 -1
- package/src/config/surface.ts +1 -0
- package/src/input/agent-workspace.ts +32 -2
- package/src/input/command-registry.ts +4 -1
- package/src/input/commands/agent-skills-runtime.ts +216 -0
- package/src/input/commands/knowledge.ts +18 -18
- package/src/input/commands/personas-runtime.ts +219 -0
- package/src/input/commands/skills-runtime.ts +7 -2
- package/src/input/commands.ts +4 -0
- package/src/input/panel-integration-actions.ts +0 -52
- package/src/main.ts +2 -1
- package/src/panels/builtin/session.ts +4 -3
- package/src/panels/index.ts +0 -5
- package/src/panels/orchestration-panel.ts +4 -5
- package/src/panels/qr-panel.ts +3 -2
- package/src/panels/tasks-panel.ts +4 -4
- package/src/renderer/agent-workspace.ts +2 -0
- package/src/runtime/bootstrap-command-context.ts +3 -0
- package/src/runtime/bootstrap-command-parts.ts +6 -2
- package/src/runtime/bootstrap-core.ts +8 -4
- package/src/runtime/bootstrap-shell.ts +3 -1
- package/src/runtime/bootstrap.ts +10 -2
- package/src/runtime/cloudflare-control-plane.ts +2 -1
- package/src/version.ts +1 -1
- package/src/daemon/cli.ts +0 -55
- package/src/daemon/safe-serve.ts +0 -61
- package/src/panels/diff-panel.ts +0 -520
- package/src/panels/file-explorer-panel.ts +0 -584
- package/src/panels/file-preview-panel.ts +0 -434
- package/src/panels/git-panel.ts +0 -638
- package/src/panels/sandbox-panel.ts +0 -283
- package/src/panels/symbol-outline-panel.ts +0 -486
- package/src/panels/worktree-panel.ts +0 -182
- 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(
|
|
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:
|
|
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:
|
|
72
|
+
surface: GOODVIBES_AGENT_PAIRING_SURFACE,
|
|
72
73
|
});
|
|
73
74
|
};
|
|
74
75
|
return new QrPanel(connectionInfo, regenerate, copyToClipboard);
|
package/src/panels/index.ts
CHANGED
|
@@ -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 = '
|
|
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
|
|
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
|
|
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' },
|
package/src/panels/qr-panel.ts
CHANGED
|
@@ -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
|
|
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 ??
|
|
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: '/
|
|
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, '/
|
|
280
|
-
buildGuidanceLine(width, '/
|
|
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
|
-
|
|
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
|
-
...
|
|
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:
|
|
130
|
-
kind: '
|
|
131
|
-
label: '
|
|
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 {
|
|
@@ -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
|
-
|
|
243
|
+
agentKnowledgeApi,
|
|
244
|
+
knowledgeApi: agentKnowledgeApi,
|
|
243
245
|
hookApi,
|
|
244
246
|
mcpApi,
|
|
245
247
|
opsApi,
|
package/src/runtime/bootstrap.ts
CHANGED
|
@@ -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
|
|
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(
|
|
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(
|
|
300
|
+
return getOrCreateCompanionToken(GOODVIBES_AGENT_PAIRING_SURFACE, { daemonHomeDir }).token;
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
async function readJsonResponse<T>(response: Response): Promise<T> {
|
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.3';
|
|
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
|
-
});
|
package/src/daemon/safe-serve.ts
DELETED
|
@@ -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
|
-
}
|