@pellux/goodvibes-agent 0.1.9 → 0.1.11
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 -0
- package/README.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/release-and-publishing.md +2 -2
- package/package.json +4 -1
- package/src/cli/agent-knowledge-command.ts +46 -20
- package/src/cli/help.ts +15 -2
- package/src/cli/management-commands.ts +3 -3
- package/src/cli/management.ts +7 -1
- package/src/cli/parser.ts +3 -0
- package/src/cli/service-posture.ts +6 -6
- package/src/cli/status.ts +9 -9
- package/src/cli/surface-command.ts +3 -3
- package/src/cli/types.ts +2 -0
- package/src/input/commands/cloudflare-runtime.ts +20 -5
- package/src/input/commands/confirmation.ts +24 -0
- package/src/input/commands/discovery-runtime.ts +16 -7
- package/src/input/commands/eval.ts +27 -14
- package/src/input/commands/experience-runtime.ts +66 -27
- package/src/input/commands/health-runtime.ts +1 -1
- package/src/input/commands/hooks-runtime.ts +79 -20
- package/src/input/commands/incident-runtime.ts +17 -6
- package/src/input/commands/integration-runtime.ts +93 -50
- package/src/input/commands/knowledge.ts +38 -12
- package/src/input/commands/local-auth-runtime.ts +36 -13
- package/src/input/commands/local-provider-runtime.ts +22 -11
- package/src/input/commands/local-runtime.ts +21 -11
- package/src/input/commands/local-setup.ts +35 -16
- package/src/input/commands/managed-runtime.ts +51 -20
- package/src/input/commands/marketplace-runtime.ts +31 -16
- package/src/input/commands/mcp-runtime.ts +65 -34
- package/src/input/commands/memory-product-runtime.ts +72 -35
- package/src/input/commands/memory.ts +9 -9
- package/src/input/commands/notify-runtime.ts +27 -8
- package/src/input/commands/operator-runtime.ts +85 -17
- package/src/input/commands/planning-runtime.ts +14 -2
- package/src/input/commands/platform-access-runtime.ts +88 -45
- package/src/input/commands/platform-services-runtime.ts +51 -25
- package/src/input/commands/product-runtime.ts +54 -27
- package/src/input/commands/profile-sync-runtime.ts +17 -6
- package/src/input/commands/recall-bundle.ts +38 -17
- package/src/input/commands/recall-query.ts +15 -4
- package/src/input/commands/recall-review.ts +9 -3
- package/src/input/commands/remote-runtime-setup.ts +45 -18
- package/src/input/commands/remote-runtime.ts +25 -9
- package/src/input/commands/replay-runtime.ts +9 -2
- package/src/input/commands/services-runtime.ts +21 -10
- package/src/input/commands/session-content.ts +53 -51
- package/src/input/commands/session-workflow.ts +10 -4
- package/src/input/commands/session.ts +1 -1
- package/src/input/commands/settings-sync-runtime.ts +40 -17
- package/src/input/commands/share-runtime.ts +12 -4
- package/src/input/commands/shell-core.ts +3 -3
- package/src/input/commands/subscription-runtime.ts +35 -20
- package/src/input/commands/teleport-runtime.ts +16 -5
- package/src/input/commands/work-plan-runtime.ts +23 -12
- package/src/input/handler-content-actions.ts +11 -62
- package/src/input/handler-interactions.ts +1 -1
- package/src/input/handler-onboarding-cloudflare.ts +48 -117
- package/src/input/handler.ts +1 -0
- package/src/input/keybindings.ts +1 -1
- package/src/input/mcp-workspace.ts +25 -49
- package/src/input/onboarding/onboarding-runtime-status.ts +8 -8
- package/src/input/onboarding/onboarding-wizard-apply.ts +13 -53
- package/src/input/onboarding/onboarding-wizard-cloudflare-step.ts +12 -12
- package/src/input/onboarding/onboarding-wizard-cloudflare.ts +2 -7
- package/src/input/onboarding/onboarding-wizard-constants.ts +7 -7
- package/src/input/onboarding/onboarding-wizard-external-surface-extra-specs.ts +4 -4
- package/src/input/onboarding/onboarding-wizard-steps.ts +13 -13
- package/src/input/profile-picker-modal.ts +13 -31
- package/src/input/session-picker-modal.ts +4 -30
- package/src/input/settings-modal-agent-policy.ts +18 -0
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal-types.ts +17 -0
- package/src/input/settings-modal.ts +30 -29
- package/src/main.ts +3 -26
- package/src/panels/incident-review-panel.ts +1 -1
- package/src/panels/local-auth-panel.ts +4 -4
- package/src/panels/provider-account-snapshot.ts +1 -1
- package/src/panels/provider-health-domains.ts +2 -2
- package/src/panels/settings-sync-panel.ts +2 -2
- package/src/panels/subscription-panel.ts +7 -7
- package/src/renderer/block-actions.ts +1 -1
- package/src/renderer/help-overlay.ts +2 -2
- package/src/renderer/mcp-workspace.ts +12 -12
- package/src/renderer/process-modal.ts +17 -8
- package/src/renderer/profile-picker-modal.ts +3 -11
- package/src/renderer/session-picker-modal.ts +2 -10
- package/src/renderer/settings-modal.ts +12 -8
- package/src/renderer/ui-factory.ts +4 -32
- package/src/runtime/bootstrap-shell.ts +0 -13
- package/src/runtime/bootstrap.ts +0 -10
- package/src/runtime/onboarding/derivation.ts +6 -6
- package/src/verification/live-verifier.ts +148 -13
- package/src/version.ts +10 -3
- package/src/input/commands/quit-shared.ts +0 -162
- package/src/renderer/git-status.ts +0 -89
|
@@ -4,9 +4,6 @@ import {
|
|
|
4
4
|
type CloudflareComponentSelection,
|
|
5
5
|
type CloudflareDaemonClient,
|
|
6
6
|
type CloudflareDiscoverResult,
|
|
7
|
-
type CloudflareOperationalTokenResult,
|
|
8
|
-
type CloudflareProvisionRequest,
|
|
9
|
-
type CloudflareProvisionResult,
|
|
10
7
|
type CloudflareTokenRequirementsResult,
|
|
11
8
|
type CloudflareValidateResult,
|
|
12
9
|
type CloudflareVerifyResult,
|
|
@@ -16,7 +13,6 @@ import type { InputHandler } from './handler.ts';
|
|
|
16
13
|
import type { OnboardingWizardAction, OnboardingWizardApplyFeedback } from './onboarding/onboarding-wizard.ts';
|
|
17
14
|
import {
|
|
18
15
|
buildCloudflareApiTokenRef,
|
|
19
|
-
buildCloudflareProvisionRequest,
|
|
20
16
|
getCloudflareBatchMode,
|
|
21
17
|
getCloudflareComponentSelection,
|
|
22
18
|
getCloudflareSetupSource,
|
|
@@ -113,26 +109,6 @@ function formatCloudflareDiscovery(result: CloudflareDiscoverResult): string[] {
|
|
|
113
109
|
];
|
|
114
110
|
}
|
|
115
111
|
|
|
116
|
-
function formatCloudflareTokenCreate(result: CloudflareOperationalTokenResult): string[] {
|
|
117
|
-
return [
|
|
118
|
-
`token: ${result.tokenName}${result.tokenId ? ` (${result.tokenId})` : ''}`,
|
|
119
|
-
`account: ${result.accountId}`,
|
|
120
|
-
`stored ref: ${result.apiTokenRef ?? 'not stored'}`,
|
|
121
|
-
`permissions: ${result.permissions.length}`,
|
|
122
|
-
'Delete or expire the temporary bootstrap token in Cloudflare after confirming the operational token works.',
|
|
123
|
-
];
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function formatCloudflareProvision(result: CloudflareProvisionResult): string[] {
|
|
127
|
-
return [
|
|
128
|
-
`result: ${result.ok ? 'ok' : 'needs attention'}`,
|
|
129
|
-
...(result.worker ? [`worker: ${result.worker.name}${result.worker.baseUrl ? ` at ${result.worker.baseUrl}` : ''}`] : []),
|
|
130
|
-
...(result.queues ? [`queue: ${result.queues.queueName}; DLQ: ${result.queues.deadLetterQueueName}`] : []),
|
|
131
|
-
...result.steps.map((step) => `${step.status}: ${step.name}${step.message ? ` - ${step.message}` : ''}`),
|
|
132
|
-
...(result.verification ? formatCloudflareVerify(result.verification).map((line) => `verify ${line}`) : []),
|
|
133
|
-
];
|
|
134
|
-
}
|
|
135
|
-
|
|
136
112
|
function formatCloudflareVerify(result: CloudflareVerifyResult): string[] {
|
|
137
113
|
return [
|
|
138
114
|
`worker health: ${result.workerHealth.ok ? 'ok' : 'failed'} (HTTP ${result.workerHealth.status})${result.workerHealth.error ? ` - ${result.workerHealth.error}` : ''}`,
|
|
@@ -171,40 +147,6 @@ function getCloudflareApiTokenRefFromWizard(handler: InputHandler): string {
|
|
|
171
147
|
return wizard.runtimeSnapshot?.config.cloudflare.apiTokenRef ?? '';
|
|
172
148
|
}
|
|
173
149
|
|
|
174
|
-
async function createCloudflareOperationalTokenForHandler(handler: InputHandler): Promise<CloudflareOperationalTokenResult> {
|
|
175
|
-
const wizard = handler.onboardingWizard;
|
|
176
|
-
const bootstrapToken = getCloudflareBootstrapTokenFromWizard(handler);
|
|
177
|
-
if (!bootstrapToken) {
|
|
178
|
-
throw new Error('A bootstrap token is required. Paste it in the wizard or select an environment variable that is set in this TUI process.');
|
|
179
|
-
}
|
|
180
|
-
const accountId = wizard.getStringFieldValue('cloudflare.account-id', wizard.runtimeSnapshot?.config.cloudflare.accountId ?? '');
|
|
181
|
-
const zoneId = wizard.getStringFieldValue('cloudflare.zone-id', wizard.runtimeSnapshot?.config.cloudflare.zoneId ?? '');
|
|
182
|
-
const zoneName = wizard.getStringFieldValue('cloudflare.zone-name', wizard.runtimeSnapshot?.config.cloudflare.zoneName ?? '');
|
|
183
|
-
return await getCloudflareDaemonClientForHandler(handler).createOperationalToken({
|
|
184
|
-
components: getCloudflareComponentSelection(wizard),
|
|
185
|
-
bootstrapToken,
|
|
186
|
-
...(accountId ? { accountId } : {}),
|
|
187
|
-
...(zoneId ? { zoneId } : {}),
|
|
188
|
-
...(zoneName ? { zoneName } : {}),
|
|
189
|
-
storeApiToken: true,
|
|
190
|
-
persistConfig: true,
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async function buildCloudflareProvisionInputForHandler(handler: InputHandler): Promise<CloudflareProvisionRequest> {
|
|
195
|
-
const input = buildCloudflareProvisionRequest(handler.onboardingWizard, { includeTransientSecrets: true });
|
|
196
|
-
const setupSource = getCloudflareSetupSource(handler.onboardingWizard);
|
|
197
|
-
if (setupSource === 'bootstrap-token' || setupSource === 'bootstrap-env') {
|
|
198
|
-
const tokenResult = await createCloudflareOperationalTokenForHandler(handler);
|
|
199
|
-
if (tokenResult.apiTokenRef) {
|
|
200
|
-
const withoutInlineToken = { ...input };
|
|
201
|
-
delete withoutInlineToken.apiToken;
|
|
202
|
-
return { ...withoutInlineToken, apiTokenRef: tokenResult.apiTokenRef };
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return input;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
150
|
function buildCloudflareDiscoveryInputForHandler(handler: InputHandler): Parameters<CloudflareDaemonClient['discover']>[0] {
|
|
209
151
|
const wizard = handler.onboardingWizard;
|
|
210
152
|
const accountId = wizard.getStringFieldValue('cloudflare.account-id', wizard.runtimeSnapshot?.config.cloudflare.accountId ?? '');
|
|
@@ -223,6 +165,34 @@ function buildCloudflareDiscoveryInputForHandler(handler: InputHandler): Paramet
|
|
|
223
165
|
};
|
|
224
166
|
}
|
|
225
167
|
|
|
168
|
+
function blockedCloudflareMutationLines(action: CloudflareOnboardingAction): string[] {
|
|
169
|
+
switch (action) {
|
|
170
|
+
case 'cloudflare-create-operational-token':
|
|
171
|
+
return [
|
|
172
|
+
'Creating and storing Cloudflare tokens is a side-effecting operation.',
|
|
173
|
+
'Run /cloudflare create-token [flags] --yes from the main prompt when you explicitly want that mutation.',
|
|
174
|
+
];
|
|
175
|
+
case 'cloudflare-provision':
|
|
176
|
+
return [
|
|
177
|
+
'Provisioning creates or updates Cloudflare resources.',
|
|
178
|
+
'Run /cloudflare provision [flags] --yes from the main prompt when you explicitly want that mutation.',
|
|
179
|
+
];
|
|
180
|
+
case 'cloudflare-disable':
|
|
181
|
+
return [
|
|
182
|
+
'Disabling Cloudflare changes persisted daemon integration config.',
|
|
183
|
+
'Run /cloudflare disable [flags] --yes from the main prompt when you explicitly want that mutation.',
|
|
184
|
+
];
|
|
185
|
+
default:
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function isBlockedCloudflareMutation(action: CloudflareOnboardingAction): boolean {
|
|
191
|
+
return action === 'cloudflare-create-operational-token'
|
|
192
|
+
|| action === 'cloudflare-provision'
|
|
193
|
+
|| action === 'cloudflare-disable';
|
|
194
|
+
}
|
|
195
|
+
|
|
226
196
|
function buildCloudflareValidateInputForHandler(handler: InputHandler): Parameters<CloudflareDaemonClient['validate']>[0] {
|
|
227
197
|
const wizard = handler.onboardingWizard;
|
|
228
198
|
const accountId = wizard.getStringFieldValue('cloudflare.account-id', wizard.runtimeSnapshot?.config.cloudflare.accountId ?? '');
|
|
@@ -244,6 +214,16 @@ export async function handleCloudflareOnboardingActionForHandler(
|
|
|
244
214
|
handler.onboardingWizard.clearApplyFeedback();
|
|
245
215
|
handler.requestRender();
|
|
246
216
|
try {
|
|
217
|
+
if (isBlockedCloudflareMutation(action)) {
|
|
218
|
+
setCloudflareWizardStatusForHandler(
|
|
219
|
+
handler,
|
|
220
|
+
'Cloudflare mutation requires explicit command',
|
|
221
|
+
blockedCloudflareMutationLines(action),
|
|
222
|
+
'warning',
|
|
223
|
+
);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
|
|
247
227
|
const client = getCloudflareDaemonClientForHandler(handler);
|
|
248
228
|
if (action === 'cloudflare-token-requirements') {
|
|
249
229
|
const result = await client.tokenRequirements({
|
|
@@ -254,13 +234,6 @@ export async function handleCloudflareOnboardingActionForHandler(
|
|
|
254
234
|
return;
|
|
255
235
|
}
|
|
256
236
|
|
|
257
|
-
if (action === 'cloudflare-create-operational-token') {
|
|
258
|
-
const result = await createCloudflareOperationalTokenForHandler(handler);
|
|
259
|
-
setCloudflareWizardStatusForHandler(handler, 'Cloudflare operational token created', formatCloudflareTokenCreate(result));
|
|
260
|
-
await handler.refreshOnboardingHydration({ preserveValues: true, targetStepId: 'cloudflare' });
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
237
|
if (action === 'cloudflare-discover') {
|
|
265
238
|
const result = await client.discover(buildCloudflareDiscoveryInputForHandler(handler));
|
|
266
239
|
if (result.selectedAccount && !handler.onboardingWizard.getStringFieldValue('cloudflare.account-id', '')) {
|
|
@@ -293,19 +266,6 @@ export async function handleCloudflareOnboardingActionForHandler(
|
|
|
293
266
|
return;
|
|
294
267
|
}
|
|
295
268
|
|
|
296
|
-
if (action === 'cloudflare-provision') {
|
|
297
|
-
const input = await buildCloudflareProvisionInputForHandler(handler);
|
|
298
|
-
const result = await client.provision(input);
|
|
299
|
-
setCloudflareWizardStatusForHandler(
|
|
300
|
-
handler,
|
|
301
|
-
result.ok ? 'Cloudflare provisioning completed' : 'Cloudflare provisioning needs attention',
|
|
302
|
-
formatCloudflareProvision(result),
|
|
303
|
-
result.ok ? 'info' : 'warning',
|
|
304
|
-
);
|
|
305
|
-
await handler.refreshOnboardingHydration({ preserveValues: true, targetStepId: 'cloudflare' });
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
269
|
if (action === 'cloudflare-verify') {
|
|
310
270
|
const result = await client.verify({
|
|
311
271
|
workerBaseUrl: handler.onboardingWizard.getStringFieldValue('cloudflare.worker-base-url', handler.onboardingWizard.runtimeSnapshot?.config.cloudflare.workerBaseUrl ?? ''),
|
|
@@ -319,22 +279,6 @@ export async function handleCloudflareOnboardingActionForHandler(
|
|
|
319
279
|
);
|
|
320
280
|
return;
|
|
321
281
|
}
|
|
322
|
-
|
|
323
|
-
if (action === 'cloudflare-disable') {
|
|
324
|
-
const result = await client.disable({
|
|
325
|
-
accountId: handler.onboardingWizard.getStringFieldValue('cloudflare.account-id', handler.onboardingWizard.runtimeSnapshot?.config.cloudflare.accountId ?? ''),
|
|
326
|
-
apiTokenRef: getCloudflareApiTokenRefFromWizard(handler),
|
|
327
|
-
workerName: handler.onboardingWizard.getStringFieldValue('cloudflare.worker-name', handler.onboardingWizard.runtimeSnapshot?.config.cloudflare.workerName ?? 'goodvibes-batch-worker'),
|
|
328
|
-
persistConfig: true,
|
|
329
|
-
});
|
|
330
|
-
setCloudflareWizardStatusForHandler(
|
|
331
|
-
handler,
|
|
332
|
-
result.ok ? 'Cloudflare integration disabled' : 'Cloudflare disable needs attention',
|
|
333
|
-
result.steps.map((step) => `${step.status}: ${step.name}${step.message ? ` - ${step.message}` : ''}`),
|
|
334
|
-
result.ok ? 'info' : 'warning',
|
|
335
|
-
);
|
|
336
|
-
await handler.refreshOnboardingHydration({ preserveValues: true, targetStepId: 'cloudflare' });
|
|
337
|
-
}
|
|
338
282
|
} catch (error) {
|
|
339
283
|
setCloudflareWizardStatusForHandler(handler, 'Cloudflare action failed', [normalizeCloudflareActionError(error)], 'error');
|
|
340
284
|
} finally {
|
|
@@ -365,27 +309,14 @@ export async function maybeProvisionCloudflareOnFinalApplyForHandler(handler: In
|
|
|
365
309
|
}];
|
|
366
310
|
}
|
|
367
311
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
message: result.ok
|
|
379
|
-
? 'Cloudflare resources were provisioned and verified through the daemon SDK route.'
|
|
380
|
-
: 'Cloudflare provisioning returned warnings or failed verification. Settings were saved; rerun the Cloudflare wizard action after correcting token/resource issues.',
|
|
381
|
-
target: 'cloudflare',
|
|
382
|
-
}];
|
|
383
|
-
} catch (error) {
|
|
384
|
-
return [{
|
|
385
|
-
id: 'cloudflare:provision',
|
|
386
|
-
status: 'warn',
|
|
387
|
-
message: `Cloudflare provisioning did not complete: ${normalizeCloudflareActionError(error)} Settings were saved; retry from the Cloudflare wizard or /cloudflare command.`,
|
|
388
|
-
target: 'cloudflare',
|
|
389
|
-
}];
|
|
390
|
-
}
|
|
312
|
+
handler.onboardingWizard.textState.set('cloudflare.action-status', [
|
|
313
|
+
'Cloudflare provisioning was not run during final apply.',
|
|
314
|
+
'GoodVibes Agent requires an explicit /cloudflare provision [flags] --yes command for Cloudflare resource mutations.',
|
|
315
|
+
].join('\n'));
|
|
316
|
+
return [{
|
|
317
|
+
id: 'cloudflare:provision',
|
|
318
|
+
status: 'warn',
|
|
319
|
+
message: 'Cloudflare settings were saved, but provisioning was blocked because Agent onboarding cannot create/update Cloudflare resources. Run /cloudflare provision [flags] --yes explicitly.',
|
|
320
|
+
target: 'cloudflare',
|
|
321
|
+
}];
|
|
391
322
|
}
|
package/src/input/handler.ts
CHANGED
|
@@ -238,6 +238,7 @@ export class InputHandler {
|
|
|
238
238
|
agentManager: uiServices.agents.agentManager,
|
|
239
239
|
processManager: uiServices.shell.processManager,
|
|
240
240
|
wrfcController: uiServices.agents.wrfcController,
|
|
241
|
+
agentEntries: 'hidden',
|
|
241
242
|
});
|
|
242
243
|
this.liveTailModal = new LiveTailModal({
|
|
243
244
|
agentManager: uiServices.agents.agentManager,
|
package/src/input/keybindings.ts
CHANGED
|
@@ -68,7 +68,7 @@ export const ACTION_DESCRIPTIONS: Record<KeyAction, string> = {
|
|
|
68
68
|
'search': 'Toggle conversation search',
|
|
69
69
|
'block-copy': 'Copy nearest block to clipboard',
|
|
70
70
|
'bookmark': 'Bookmark / unbookmark nearest block',
|
|
71
|
-
'block-save': '
|
|
71
|
+
'block-save': 'Block file save blocked; use /share --yes',
|
|
72
72
|
'delete-word': 'Delete word backward',
|
|
73
73
|
'apply-diff-line-start': 'Apply nearest diff / move to line start',
|
|
74
74
|
'next-error-line-end': 'Navigate to next error / move to line end',
|
|
@@ -214,7 +214,7 @@ export class McpWorkspace {
|
|
|
214
214
|
public formIndex = 0;
|
|
215
215
|
public form: McpWorkspaceForm = serverConfigToForm();
|
|
216
216
|
public editingServerName: string | null = null;
|
|
217
|
-
public status = 'Ready.
|
|
217
|
+
public status = 'Ready. Inspect MCP servers and tools. Config writes/reloads require explicit /mcp ... --yes commands.';
|
|
218
218
|
public tools: readonly RegisteredTool[] = [];
|
|
219
219
|
public loadingTools = false;
|
|
220
220
|
public lastError: string | null = null;
|
|
@@ -234,7 +234,7 @@ export class McpWorkspace {
|
|
|
234
234
|
this.formIndex = 0;
|
|
235
235
|
this.lastError = null;
|
|
236
236
|
this.refreshSnapshot();
|
|
237
|
-
void this.refreshTools();
|
|
237
|
+
void this.refreshTools(false);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
reopen(): void {
|
|
@@ -257,8 +257,8 @@ export class McpWorkspace {
|
|
|
257
257
|
get rows(): readonly McpWorkspaceRow[] {
|
|
258
258
|
return [
|
|
259
259
|
...this.snapshot.servers.map((server): McpWorkspaceRow => ({ type: 'server', server })),
|
|
260
|
-
{ type: 'action', id: 'add', label: 'Add server', detail: `
|
|
261
|
-
{ type: 'action', id: 'reload', label: 'Reload
|
|
260
|
+
{ type: 'action', id: 'add', label: 'Add server preview', detail: `Draft server details here, then run /mcp add ... --scope ${this.form.scope} --yes to write config.` },
|
|
261
|
+
{ type: 'action', id: 'reload', label: 'Reload guidance', detail: 'Runtime reload is blocked from the workspace; run /mcp reload --yes explicitly.' },
|
|
262
262
|
{ type: 'action', id: 'refresh-tools', label: 'Refresh tools', detail: 'Fetch the currently available MCP tool list from connected servers.' },
|
|
263
263
|
{ type: 'action', id: 'config', label: 'Config locations', detail: 'Show SDK-scanned config files and writable project/global paths.' },
|
|
264
264
|
];
|
|
@@ -284,7 +284,7 @@ export class McpWorkspace {
|
|
|
284
284
|
{ id: 'env', label: 'Environment', value: this.form.env, help: 'Comma-separated KEY=VALUE entries. Prefer env var references or secure secrets for sensitive values.', editable: true },
|
|
285
285
|
{ id: 'allowedPaths', label: 'Allowed paths', value: this.form.allowedPaths, help: 'Comma-separated path prefixes for filesystem-oriented servers.', editable: true },
|
|
286
286
|
{ id: 'allowedHosts', label: 'Allowed hosts', value: this.form.allowedHosts, help: 'Comma-separated hostnames for network-oriented servers.', editable: true },
|
|
287
|
-
{ id: 'save', label: '
|
|
287
|
+
{ id: 'save', label: 'Show save command', value: '', help: 'No workspace write. Shows the explicit /mcp add ... --yes command to run from the prompt.', editable: false },
|
|
288
288
|
{ id: 'cancel', label: 'Cancel', value: '', help: 'Return to the MCP server browser without changing config.', editable: false },
|
|
289
289
|
];
|
|
290
290
|
}
|
|
@@ -306,14 +306,14 @@ export class McpWorkspace {
|
|
|
306
306
|
this.selectedIndex = Math.max(0, Math.min(this.selectedIndex, this.rows.length - 1));
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
-
async refreshTools(): Promise<void> {
|
|
309
|
+
async refreshTools(updateStatus = true): Promise<void> {
|
|
310
310
|
if (!this.context) return;
|
|
311
311
|
this.loadingTools = true;
|
|
312
312
|
this.lastError = null;
|
|
313
313
|
try {
|
|
314
314
|
const api = requireMcpApi(this.context);
|
|
315
315
|
this.tools = await api.listAllTools();
|
|
316
|
-
this.status = `Tool list refreshed: ${this.tools.length} tool(s) available.`;
|
|
316
|
+
if (updateStatus) this.status = `Tool list refreshed: ${this.tools.length} tool(s) available.`;
|
|
317
317
|
} catch (error) {
|
|
318
318
|
this.lastError = summarizeError(error);
|
|
319
319
|
this.status = `Tool refresh failed: ${this.lastError}`;
|
|
@@ -326,20 +326,8 @@ export class McpWorkspace {
|
|
|
326
326
|
async reloadRuntime(): Promise<void> {
|
|
327
327
|
if (!this.context) return;
|
|
328
328
|
this.lastError = null;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const roots = requireShellPaths(this.context);
|
|
332
|
-
const result = await api.reload(roots);
|
|
333
|
-
this.refreshSnapshot();
|
|
334
|
-
const connected = this.snapshot.servers.filter((server) => server.connected).length;
|
|
335
|
-
this.status = `Reloaded MCP runtime: ${connected}/${this.snapshot.servers.length} server(s) connected. Result: +${result.added} ~${result.changed} -${result.removed}, unchanged ${result.unchanged}.`;
|
|
336
|
-
void this.refreshTools();
|
|
337
|
-
} catch (error) {
|
|
338
|
-
this.lastError = summarizeError(error);
|
|
339
|
-
this.status = `Reload failed: ${this.lastError}`;
|
|
340
|
-
} finally {
|
|
341
|
-
this.context?.renderRequest();
|
|
342
|
-
}
|
|
329
|
+
this.status = 'MCP runtime reload is blocked in the workspace. Run /mcp reload --yes from the prompt to explicitly reload.';
|
|
330
|
+
this.context.renderRequest();
|
|
343
331
|
}
|
|
344
332
|
|
|
345
333
|
openAddForm(): void {
|
|
@@ -347,7 +335,7 @@ export class McpWorkspace {
|
|
|
347
335
|
this.formIndex = 0;
|
|
348
336
|
this.editingServerName = null;
|
|
349
337
|
this.form = serverConfigToForm();
|
|
350
|
-
this.status = '
|
|
338
|
+
this.status = 'Draft an MCP server. Saving from this workspace is blocked; use the shown /mcp add ... --yes command.';
|
|
351
339
|
}
|
|
352
340
|
|
|
353
341
|
openEditForm(serverName: string): void {
|
|
@@ -357,8 +345,8 @@ export class McpWorkspace {
|
|
|
357
345
|
this.editingServerName = serverName;
|
|
358
346
|
this.form = { ...serverConfigToForm(entry?.server), scope: entry?.source.scope === 'global' ? 'global' : 'project' };
|
|
359
347
|
this.status = entry
|
|
360
|
-
? `
|
|
361
|
-
: `
|
|
348
|
+
? `Viewing ${serverName}. Workspace saves are blocked; copy the generated /mcp add ... --yes command if you intend to change it.`
|
|
349
|
+
: `Viewing ${serverName}. Runtime status exists, but no launch config was found.`;
|
|
362
350
|
}
|
|
363
351
|
|
|
364
352
|
requestDelete(serverName: string): void {
|
|
@@ -366,24 +354,23 @@ export class McpWorkspace {
|
|
|
366
354
|
this.editingServerName = serverName;
|
|
367
355
|
const entry = this.snapshot.effectiveConfig.servers.find((configEntry) => configEntry.server.name === serverName);
|
|
368
356
|
const scope = entry?.source.scope === 'global' ? 'global' : 'project';
|
|
369
|
-
this.status = `
|
|
357
|
+
this.status = `MCP server removal is blocked in the workspace. Run /mcp remove ${serverName} --scope ${scope} --yes from the prompt.`;
|
|
370
358
|
}
|
|
371
359
|
|
|
372
360
|
async saveForm(): Promise<void> {
|
|
373
361
|
if (!this.context) return;
|
|
374
362
|
try {
|
|
375
363
|
const server = formToServerConfig(this.form);
|
|
376
|
-
this.status = `Saving ${server.name} to ${this.form.scope} MCP config and reloading runtime...`;
|
|
377
364
|
this.mode = 'browse';
|
|
378
365
|
this.editingServerName = null;
|
|
379
|
-
const
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
this.status = `
|
|
383
|
-
|
|
366
|
+
const args = server.args?.length ? ` ${server.args.join(' ')}` : '';
|
|
367
|
+
const role = server.role ? ` --role ${server.role}` : '';
|
|
368
|
+
const trust = server.trustMode ? ` --trust ${server.trustMode}` : '';
|
|
369
|
+
this.status = `MCP config write blocked here. Run: /mcp add ${server.name} ${server.command}${args} --scope ${this.form.scope}${role}${trust} --yes`;
|
|
370
|
+
this.context.renderRequest();
|
|
384
371
|
} catch (error) {
|
|
385
372
|
this.lastError = summarizeError(error);
|
|
386
|
-
this.status = `Save failed: ${this.lastError}`;
|
|
373
|
+
this.status = `Save command preview failed: ${this.lastError}`;
|
|
387
374
|
this.context.renderRequest();
|
|
388
375
|
}
|
|
389
376
|
}
|
|
@@ -391,23 +378,12 @@ export class McpWorkspace {
|
|
|
391
378
|
async confirmDelete(): Promise<void> {
|
|
392
379
|
if (!this.context || !this.editingServerName) return;
|
|
393
380
|
const name = this.editingServerName;
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
this.editingServerName = null;
|
|
401
|
-
this.refreshSnapshot();
|
|
402
|
-
this.status = result.removed
|
|
403
|
-
? `Removed ${scope} server "${name}" from ${result.path}. Reload result: +${result.reload.added} ~${result.reload.changed} -${result.reload.removed}.`
|
|
404
|
-
: `No ${scope} MCP server named "${name}" exists in ${result.path}.`;
|
|
405
|
-
void this.refreshTools();
|
|
406
|
-
} catch (error) {
|
|
407
|
-
this.lastError = summarizeError(error);
|
|
408
|
-
this.status = `Remove failed: ${this.lastError}`;
|
|
409
|
-
this.context.renderRequest();
|
|
410
|
-
}
|
|
381
|
+
const server = this.snapshot.effectiveConfig.servers.find((entry) => entry.server.name === name);
|
|
382
|
+
const scope = server?.source.scope === 'global' ? 'global' : 'project';
|
|
383
|
+
this.mode = 'browse';
|
|
384
|
+
this.editingServerName = null;
|
|
385
|
+
this.status = `MCP removal blocked here. Run: /mcp remove ${name} --scope ${scope} --yes`;
|
|
386
|
+
this.context.renderRequest();
|
|
411
387
|
}
|
|
412
388
|
|
|
413
389
|
cancelForm(): void {
|
|
@@ -19,24 +19,24 @@ export function runtimePortDiagnostic(
|
|
|
19
19
|
if (status) {
|
|
20
20
|
const reason = status.reason ? ` ${status.reason}` : '';
|
|
21
21
|
if (status.mode === 'blocked') {
|
|
22
|
-
return `The configured endpoint ${status.baseUrl} is occupied but was not usable by this
|
|
22
|
+
return `The configured endpoint ${status.baseUrl} is occupied but was not usable by this Agent instance.${reason}`;
|
|
23
23
|
}
|
|
24
24
|
if (status.mode === 'disabled') {
|
|
25
25
|
return `The configured endpoint ${status.baseUrl} is disabled in the runtime service configuration.${reason}`;
|
|
26
26
|
}
|
|
27
27
|
if (status.mode === 'unavailable') {
|
|
28
|
-
return `The configured endpoint ${status.baseUrl} is unavailable
|
|
28
|
+
return `The configured endpoint ${status.baseUrl} is unavailable to Agent.${reason}`;
|
|
29
29
|
}
|
|
30
30
|
if (status.mode === 'external') {
|
|
31
31
|
const version = status.version ? ` version ${status.version}` : '';
|
|
32
32
|
return `An existing GoodVibes service was verified at ${status.baseUrl}${version}.`;
|
|
33
33
|
}
|
|
34
|
-
return `
|
|
34
|
+
return `A GoodVibes service reports embedded mode at ${status.baseUrl}; Agent still treats daemon lifecycle as external.`;
|
|
35
35
|
}
|
|
36
36
|
if (portInUse) {
|
|
37
|
-
return `The configured port ${binding.host}:${binding.port} is occupied
|
|
37
|
+
return `The configured port ${binding.host}:${binding.port} is occupied; another GoodVibes process or another service may own it.`;
|
|
38
38
|
}
|
|
39
|
-
return `No process is listening on ${binding.host}:${binding.port}
|
|
39
|
+
return `No process is listening on ${binding.host}:${binding.port}.`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export function getRuntimeEndpointStatus(
|
|
@@ -79,9 +79,9 @@ export function formatRuntimeActiveSuccessMessage(
|
|
|
79
79
|
return `${label} is already running as a verified external GoodVibes service at ${status.baseUrl}${version}.`;
|
|
80
80
|
}
|
|
81
81
|
if (status?.mode === 'embedded') {
|
|
82
|
-
return `${label}
|
|
82
|
+
return `${label} reports embedded mode at ${status.baseUrl}; Agent does not own that service lifecycle.`;
|
|
83
83
|
}
|
|
84
84
|
return endpoint === 'daemon'
|
|
85
|
-
? 'The GoodVibes daemon is
|
|
86
|
-
: 'The HTTP listener is
|
|
85
|
+
? 'The GoodVibes daemon is reachable to Agent.'
|
|
86
|
+
: 'The HTTP listener is reachable to Agent.';
|
|
87
87
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
getExternalSurfaceAutoStartFieldId,
|
|
16
16
|
isExternalSurfaceSelectedByDefault,
|
|
17
17
|
} from './onboarding-wizard-external-surfaces.ts';
|
|
18
|
-
import { buildGoodVibesSecretKey, buildGoodVibesSecretRef,
|
|
18
|
+
import { buildGoodVibesSecretKey, buildGoodVibesSecretRef, isSecretReferenceValue } from './onboarding-wizard-helpers.ts';
|
|
19
19
|
import type { OnboardingWizardController } from './onboarding-wizard.ts';
|
|
20
20
|
|
|
21
21
|
export function buildOnboardingApplyRequest(controller: OnboardingWizardController): OnboardingApplyRequest {
|
|
@@ -203,7 +203,7 @@ function addCloudflareOperations(
|
|
|
203
203
|
setConfig('cloudflare.workerCron', controller.getStringFieldValue('cloudflare.worker-cron', config?.workerCron ?? '*/5 * * * *'));
|
|
204
204
|
setConfig('cloudflare.queueName', controller.getStringFieldValue('cloudflare.queue-name', config?.queueName ?? 'goodvibes-batch'));
|
|
205
205
|
setConfig('cloudflare.deadLetterQueueName', controller.getStringFieldValue('cloudflare.dead-letter-queue-name', config?.deadLetterQueueName ?? 'goodvibes-batch-dlq'));
|
|
206
|
-
setConfig('cloudflare.tunnelName', controller.getStringFieldValue('cloudflare.tunnel-name', config?.tunnelName ?? 'goodvibes-daemon'));
|
|
206
|
+
setConfig('cloudflare.tunnelName', controller.getStringFieldValue('cloudflare.tunnel-name', config?.tunnelName ?? 'goodvibes-agent-daemon'));
|
|
207
207
|
setConfig('cloudflare.tunnelId', controller.getStringFieldValue('cloudflare.tunnel-id', config?.tunnelId ?? ''));
|
|
208
208
|
setConfig('cloudflare.tunnelTokenRef', controller.getStringFieldValue('cloudflare.tunnel-token-ref', config?.tunnelTokenRef ?? ''));
|
|
209
209
|
setConfig('cloudflare.accessAppId', controller.getStringFieldValue('cloudflare.access-app-id', config?.accessAppId ?? ''));
|
|
@@ -222,56 +222,16 @@ function addCloudflareOperations(
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
export function addNetworkOperations(
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
225
|
+
_controller: OnboardingWizardController,
|
|
226
|
+
_operations: OnboardingApplyOperation[],
|
|
227
|
+
_customNetwork: boolean,
|
|
228
|
+
_enabled: {
|
|
229
|
+
readonly controlPlane: boolean;
|
|
230
|
+
readonly controlPlaneRemote: boolean;
|
|
231
|
+
readonly httpListener: boolean;
|
|
232
|
+
readonly web: boolean;
|
|
233
|
+
},
|
|
234
234
|
): void {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
value: unknown,
|
|
238
|
-
): void => {
|
|
239
|
-
operations.push({ kind: 'set-config', key, value });
|
|
240
|
-
};
|
|
241
|
-
const networkFacingEnabled = {
|
|
242
|
-
controlPlane: enabled.controlPlaneRemote,
|
|
243
|
-
httpListener: enabled.httpListener,
|
|
244
|
-
web: enabled.web,
|
|
245
|
-
};
|
|
246
|
-
const sharedIpDefault = controller.getSharedIpDefault(networkFacingEnabled);
|
|
247
|
-
const sharedIp = controller.getBooleanFieldValue('network.shared-ip', sharedIpDefault);
|
|
248
|
-
const sharedHost = controller.getStringFieldValue('network.shared-ip-address', controller.getSharedIpHostDefault(networkFacingEnabled)) || '0.0.0.0';
|
|
249
|
-
const controlPlaneHost = sharedIp
|
|
250
|
-
? sharedHost
|
|
251
|
-
: controller.getStringFieldValue('network.service-ip', controller.runtimeSnapshot?.bindSettings.controlPlane.host ?? '0.0.0.0');
|
|
252
|
-
const httpListenerHost = sharedIp
|
|
253
|
-
? sharedHost
|
|
254
|
-
: controller.getStringFieldValue('network.webhook-ip', controller.runtimeSnapshot?.bindSettings.httpListener.host ?? '0.0.0.0');
|
|
255
|
-
const webHost = sharedIp
|
|
256
|
-
? sharedHost
|
|
257
|
-
: controller.getStringFieldValue('network.browser-ip', controller.runtimeSnapshot?.bindSettings.web.host ?? '0.0.0.0');
|
|
258
|
-
|
|
259
|
-
if (enabled.controlPlane) {
|
|
260
|
-
setConfig('controlPlane.hostMode', enabled.controlPlaneRemote ? (customNetwork ? 'custom' : 'network') : 'local');
|
|
261
|
-
setConfig('controlPlane.host', enabled.controlPlaneRemote ? (customNetwork ? controlPlaneHost : '0.0.0.0') : '127.0.0.1');
|
|
262
|
-
setConfig('controlPlane.port', controller.getPortFieldValue('network.service-port', controller.runtimeSnapshot?.bindSettings.controlPlane.port ?? 3421));
|
|
263
|
-
setConfig('controlPlane.allowRemote', enabled.controlPlaneRemote && (customNetwork ? !isLoopbackAddress(controlPlaneHost) : true));
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (enabled.httpListener) {
|
|
267
|
-
setConfig('httpListener.hostMode', customNetwork ? 'custom' : 'network');
|
|
268
|
-
setConfig('httpListener.host', customNetwork ? httpListenerHost : '0.0.0.0');
|
|
269
|
-
setConfig('httpListener.port', controller.getPortFieldValue('network.webhook-port', controller.runtimeSnapshot?.bindSettings.httpListener.port ?? 3422));
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (enabled.web) {
|
|
273
|
-
setConfig('web.hostMode', customNetwork ? 'custom' : 'network');
|
|
274
|
-
setConfig('web.host', customNetwork ? webHost : '0.0.0.0');
|
|
275
|
-
setConfig('web.port', controller.getPortFieldValue('network.browser-port', controller.runtimeSnapshot?.bindSettings.web.port ?? 3423));
|
|
276
|
-
}
|
|
235
|
+
// Agent onboarding intentionally never mutates daemon/listener/web bind posture.
|
|
236
|
+
// Network fields are advisory for the external daemon owner.
|
|
277
237
|
}
|
|
@@ -26,7 +26,7 @@ export function buildCloudflareStep(controller: OnboardingWizardController): Onb
|
|
|
26
26
|
const bind = controller.runtimeSnapshot?.bindSettings.controlPlane;
|
|
27
27
|
const defaultDaemonBaseUrl = normalizeText(config?.daemonBaseUrl)
|
|
28
28
|
|| `http://${bind?.host && bind.host !== '0.0.0.0' && bind.host !== '::' ? bind.host : '127.0.0.1'}:${bind?.port ?? 3421}`;
|
|
29
|
-
const resultMessage = controller.textState.get('cloudflare.action-status') ?? 'No Cloudflare
|
|
29
|
+
const resultMessage = controller.textState.get('cloudflare.action-status') ?? 'No Cloudflare action has run in this wizard session.';
|
|
30
30
|
const fields: OnboardingWizardFieldDefinition[] = [
|
|
31
31
|
{
|
|
32
32
|
kind: 'checklist',
|
|
@@ -96,7 +96,7 @@ export function buildCloudflareStep(controller: OnboardingWizardController): Onb
|
|
|
96
96
|
kind: 'text',
|
|
97
97
|
id: 'cloudflare.bootstrap-env-name',
|
|
98
98
|
label: 'Bootstrap token environment variable',
|
|
99
|
-
hint: '
|
|
99
|
+
hint: 'Agent reads this environment variable once and passes the value to the SDK token-create route. It is not persisted.',
|
|
100
100
|
placeholder: 'GOODVIBES_CLOUDFLARE_BOOTSTRAP_TOKEN',
|
|
101
101
|
defaultValue: 'GOODVIBES_CLOUDFLARE_BOOTSTRAP_TOKEN',
|
|
102
102
|
});
|
|
@@ -227,8 +227,8 @@ export function buildCloudflareStep(controller: OnboardingWizardController): Onb
|
|
|
227
227
|
id: 'cloudflare.tunnel-name',
|
|
228
228
|
label: 'Tunnel name',
|
|
229
229
|
hint: 'Cloudflare Tunnel name to create or reuse.',
|
|
230
|
-
placeholder: 'goodvibes-daemon',
|
|
231
|
-
defaultValue: config?.tunnelName || 'goodvibes-daemon',
|
|
230
|
+
placeholder: 'goodvibes-agent-daemon',
|
|
231
|
+
defaultValue: config?.tunnelName || 'goodvibes-agent-daemon',
|
|
232
232
|
},
|
|
233
233
|
{
|
|
234
234
|
kind: 'text',
|
|
@@ -380,8 +380,8 @@ export function buildCloudflareStep(controller: OnboardingWizardController): Onb
|
|
|
380
380
|
{
|
|
381
381
|
kind: 'radio',
|
|
382
382
|
id: 'cloudflare.provision-on-apply',
|
|
383
|
-
label: '
|
|
384
|
-
hint: '
|
|
383
|
+
label: 'Final apply Cloudflare provisioning',
|
|
384
|
+
hint: 'Agent onboarding saves config only. Run /cloudflare provision [flags] --yes explicitly for resource changes.',
|
|
385
385
|
options: CLOUDFLARE_PROVISION_OPTIONS,
|
|
386
386
|
defaultValue: 'no',
|
|
387
387
|
},
|
|
@@ -404,8 +404,8 @@ export function buildCloudflareStep(controller: OnboardingWizardController): Onb
|
|
|
404
404
|
kind: 'action',
|
|
405
405
|
id: 'cloudflare.create-token',
|
|
406
406
|
action: 'cloudflare-create-operational-token',
|
|
407
|
-
label: '
|
|
408
|
-
hint: '
|
|
407
|
+
label: 'Show create-token command',
|
|
408
|
+
hint: 'Token creation is side-effecting. The wizard shows the explicit /cloudflare create-token ... --yes path instead of running it.',
|
|
409
409
|
defaultValue: 'Action',
|
|
410
410
|
},
|
|
411
411
|
{
|
|
@@ -428,8 +428,8 @@ export function buildCloudflareStep(controller: OnboardingWizardController): Onb
|
|
|
428
428
|
kind: 'action',
|
|
429
429
|
id: 'cloudflare.provision',
|
|
430
430
|
action: 'cloudflare-provision',
|
|
431
|
-
label: '
|
|
432
|
-
hint: '
|
|
431
|
+
label: 'Show provision command',
|
|
432
|
+
hint: 'Provisioning is side-effecting. The wizard shows the explicit /cloudflare provision ... --yes path instead of running it.',
|
|
433
433
|
defaultValue: 'Action',
|
|
434
434
|
},
|
|
435
435
|
{
|
|
@@ -444,8 +444,8 @@ export function buildCloudflareStep(controller: OnboardingWizardController): Onb
|
|
|
444
444
|
kind: 'action',
|
|
445
445
|
id: 'cloudflare.disable',
|
|
446
446
|
action: 'cloudflare-disable',
|
|
447
|
-
label: '
|
|
448
|
-
hint: '
|
|
447
|
+
label: 'Show disable command',
|
|
448
|
+
hint: 'Disabling persists config changes. The wizard shows the explicit /cloudflare disable ... --yes path instead of running it.',
|
|
449
449
|
defaultValue: 'Action',
|
|
450
450
|
},
|
|
451
451
|
);
|
|
@@ -66,12 +66,7 @@ export const CLOUDFLARE_PROVISION_OPTIONS: readonly OnboardingWizardRadioOption[
|
|
|
66
66
|
{
|
|
67
67
|
id: 'no',
|
|
68
68
|
label: 'No, save configuration only',
|
|
69
|
-
hint: 'Final Apply saves the settings.
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
id: 'yes',
|
|
73
|
-
label: 'Yes, create or update Cloudflare resources',
|
|
74
|
-
hint: 'Final Apply asks the daemon SDK route to create/update selected Cloudflare resources and verify the Worker when possible.',
|
|
69
|
+
hint: 'Final Apply saves the settings. Run /cloudflare provision [flags] --yes explicitly when you want resource changes.',
|
|
75
70
|
},
|
|
76
71
|
];
|
|
77
72
|
|
|
@@ -176,7 +171,7 @@ export function buildCloudflareProvisionRequest(controller: OnboardingWizardCont
|
|
|
176
171
|
daemonHostname: controller.getStringFieldValue('cloudflare.daemon-hostname', controller.runtimeSnapshot?.config.cloudflare.daemonHostname ?? ''),
|
|
177
172
|
queueName: controller.getStringFieldValue('cloudflare.queue-name', controller.runtimeSnapshot?.config.cloudflare.queueName ?? 'goodvibes-batch'),
|
|
178
173
|
deadLetterQueueName: controller.getStringFieldValue('cloudflare.dead-letter-queue-name', controller.runtimeSnapshot?.config.cloudflare.deadLetterQueueName ?? 'goodvibes-batch-dlq'),
|
|
179
|
-
tunnelName: controller.getStringFieldValue('cloudflare.tunnel-name', controller.runtimeSnapshot?.config.cloudflare.tunnelName ?? 'goodvibes-daemon'),
|
|
174
|
+
tunnelName: controller.getStringFieldValue('cloudflare.tunnel-name', controller.runtimeSnapshot?.config.cloudflare.tunnelName ?? 'goodvibes-agent-daemon'),
|
|
180
175
|
tunnelId: controller.getStringFieldValue('cloudflare.tunnel-id', controller.runtimeSnapshot?.config.cloudflare.tunnelId ?? ''),
|
|
181
176
|
tunnelServiceUrl: controller.getStringFieldValue('cloudflare.tunnel-service-url', ''),
|
|
182
177
|
tunnelTokenRef: controller.getStringFieldValue('cloudflare.tunnel-token-ref', controller.runtimeSnapshot?.config.cloudflare.tunnelTokenRef ?? ''),
|