@pellux/goodvibes-agent 0.1.116 → 1.0.0
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 +48 -661
- package/README.md +64 -57
- package/bin/goodvibes-agent.ts +16 -2
- package/dist/package/main.js +199180 -192185
- package/docs/README.md +15 -8
- package/docs/channels-remote-and-api.md +50 -0
- package/docs/connected-host.md +59 -0
- package/docs/getting-started.md +61 -50
- package/docs/knowledge-artifacts-and-multimodal.md +91 -0
- package/docs/project-planning.md +79 -0
- package/docs/providers-and-routing.md +46 -0
- package/docs/release-and-publishing.md +48 -11
- package/docs/tools-and-commands.md +123 -0
- package/docs/voice-and-live-tts.md +51 -0
- package/package.json +3 -6
- package/src/agent/behavior-discovery-summary.ts +1 -3
- package/src/agent/channel-delivery.ts +201 -0
- package/src/agent/media-generation.ts +159 -0
- package/src/agent/memory-prompt.ts +0 -1
- package/src/agent/note-registry.ts +329 -0
- package/src/agent/operator-actions.ts +343 -0
- package/src/agent/persona-discovery.ts +1 -3
- package/src/agent/persona-registry.ts +19 -16
- package/src/agent/record-labels.ts +107 -0
- package/src/agent/reminder-schedule-format.ts +33 -24
- package/src/agent/reminder-schedule.ts +27 -26
- package/src/agent/routine-registry.ts +54 -14
- package/src/agent/routine-schedule-args.ts +2 -1
- package/src/agent/routine-schedule-format.ts +77 -53
- package/src/agent/routine-schedule-promotion.ts +35 -33
- package/src/agent/routine-schedule-receipts.ts +29 -27
- package/src/agent/runtime-profile-starters.ts +5 -5
- package/src/agent/runtime-profile.ts +91 -12
- package/src/agent/skill-registry.ts +210 -32
- package/src/cli/agent-knowledge-args.ts +5 -1
- package/src/cli/agent-knowledge-command.ts +40 -34
- package/src/cli/agent-knowledge-format.ts +80 -67
- package/src/cli/agent-knowledge-methods.ts +1 -1
- package/src/cli/agent-knowledge-runtime.ts +32 -26
- package/src/cli/bundle-command.ts +14 -9
- package/src/cli/config-overrides.ts +37 -36
- package/src/cli/entrypoint.ts +16 -7
- package/src/cli/external-runtime.ts +10 -4
- package/src/cli/help.ts +54 -29
- package/src/cli/local-library-command.ts +203 -83
- package/src/cli/management-commands.ts +105 -68
- package/src/cli/management.ts +55 -74
- package/src/cli/memory-command.ts +66 -32
- package/src/cli/parser.ts +37 -3
- package/src/cli/profiles-command.ts +166 -31
- package/src/cli/provider-auth-routes.ts +2 -1
- package/src/cli/routines-command.ts +176 -40
- package/src/cli/service-posture.ts +16 -16
- package/src/cli/status.ts +56 -135
- package/src/core/conversation-message-snapshot.ts +131 -0
- package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
- package/src/input/agent-workspace-access-command-editors.ts +170 -0
- package/src/input/agent-workspace-activation.ts +35 -8
- package/src/input/agent-workspace-basic-command-editor-submission.ts +351 -94
- package/src/input/agent-workspace-basic-command-editors.ts +502 -9
- package/src/input/agent-workspace-categories.ts +423 -51
- package/src/input/agent-workspace-channel-command-editor-submission.ts +83 -0
- package/src/input/agent-workspace-channel-command-editors.ts +65 -0
- package/src/input/agent-workspace-channels.ts +35 -2
- package/src/input/agent-workspace-command-editor.ts +41 -3
- package/src/input/agent-workspace-config-reader.ts +16 -0
- package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
- package/src/input/agent-workspace-editors.ts +166 -1
- package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
- package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
- package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
- package/src/input/agent-workspace-learned-behavior.ts +67 -0
- package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
- package/src/input/agent-workspace-library-command-editors.ts +35 -0
- package/src/input/agent-workspace-local-operations.ts +218 -0
- package/src/input/agent-workspace-local-selection.ts +75 -0
- package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
- package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
- package/src/input/agent-workspace-media-command-editors.ts +27 -0
- package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
- package/src/input/agent-workspace-memory-command-editors.ts +180 -0
- package/src/input/agent-workspace-memory-editor.ts +2 -2
- package/src/input/agent-workspace-navigation.ts +81 -0
- package/src/input/agent-workspace-notify-editor-submission.ts +121 -0
- package/src/input/agent-workspace-operations-command-editor-submission.ts +208 -0
- package/src/input/agent-workspace-operations-command-editors.ts +196 -0
- package/src/input/agent-workspace-panel-route.ts +43 -0
- package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
- package/src/input/agent-workspace-provider-command-editors.ts +93 -0
- package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
- package/src/input/agent-workspace-requirements.ts +11 -0
- package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
- package/src/input/agent-workspace-search.ts +169 -0
- package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
- package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
- package/src/input/agent-workspace-session-command-editors.ts +249 -0
- package/src/input/agent-workspace-setup.ts +37 -16
- package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
- package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
- package/src/input/agent-workspace-snapshot.ts +162 -21
- package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
- package/src/input/agent-workspace-task-command-editors.ts +47 -0
- package/src/input/agent-workspace-token.ts +18 -2
- package/src/input/agent-workspace-types.ts +212 -4
- package/src/input/agent-workspace-voice-media.ts +4 -7
- package/src/input/agent-workspace-web-research-editor.ts +104 -0
- package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
- package/src/input/agent-workspace.ts +178 -240
- package/src/input/command-registry.ts +5 -2
- package/src/input/commands/agent-runtime-profile-runtime.ts +126 -37
- package/src/input/commands/agent-skills-runtime.ts +149 -72
- package/src/input/commands/agent-workspace-runtime.ts +23 -6
- package/src/input/commands/brief-runtime.ts +55 -25
- package/src/input/commands/channels-runtime.ts +147 -33
- package/src/input/commands/compat-runtime.ts +32 -0
- package/src/input/commands/delegation-runtime.ts +29 -23
- package/src/input/commands/experience-runtime.ts +6 -4
- package/src/input/commands/guidance-runtime.ts +4 -4
- package/src/input/commands/health-runtime.ts +149 -126
- package/src/input/commands/knowledge.ts +82 -60
- package/src/input/commands/local-provider-runtime.ts +43 -21
- package/src/input/commands/local-runtime.ts +138 -16
- package/src/input/commands/local-setup-review.ts +10 -20
- package/src/input/commands/mcp-runtime.ts +63 -46
- package/src/input/commands/notify-runtime.ts +38 -9
- package/src/input/commands/operator-actions-runtime.ts +138 -0
- package/src/input/commands/operator-runtime.ts +6 -76
- package/src/input/commands/personas-runtime.ts +46 -31
- package/src/input/commands/planning-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +35 -98
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/provider-accounts-runtime.ts +60 -39
- package/src/input/commands/qrcode-runtime.ts +50 -9
- package/src/input/commands/recall-bundle.ts +11 -11
- package/src/input/commands/recall-capture.ts +13 -11
- package/src/input/commands/recall-query.ts +29 -21
- package/src/input/commands/recall-review.ts +2 -1
- package/src/input/commands/routines-runtime.ts +99 -45
- package/src/input/commands/runtime-services.ts +1 -14
- package/src/input/commands/schedule-runtime.ts +33 -20
- package/src/input/commands/security-runtime.ts +6 -11
- package/src/input/commands/session-content.ts +80 -78
- package/src/input/commands/session-workflow.ts +134 -104
- package/src/input/commands/session.ts +3 -174
- package/src/input/commands/shell-core.ts +38 -17
- package/src/input/commands/subscription-runtime.ts +54 -185
- package/src/input/commands/support-bundle-runtime.ts +53 -0
- package/src/input/commands/tasks-runtime.ts +21 -21
- package/src/input/commands/work-plan-runtime.ts +33 -8
- package/src/input/commands.ts +6 -2
- package/src/input/feed-context-factory.ts +2 -2
- package/src/input/file-picker.ts +3 -2
- package/src/input/handler-command-route.ts +4 -7
- package/src/input/handler-content-actions.ts +89 -26
- package/src/input/handler-feed-routes.ts +19 -12
- package/src/input/handler-feed.ts +6 -5
- package/src/input/handler-interactions.ts +9 -36
- package/src/input/handler-modal-stack.ts +3 -3
- package/src/input/handler-onboarding.ts +52 -91
- package/src/input/handler-shortcuts.ts +16 -7
- package/src/input/handler.ts +50 -23
- package/src/input/input-history.ts +5 -6
- package/src/input/keybindings.ts +27 -16
- package/src/input/mcp-workspace.ts +90 -26
- package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
- package/src/input/onboarding/onboarding-wizard-apply.ts +62 -0
- package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
- package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
- package/src/input/onboarding/onboarding-wizard-operator-steps.ts +223 -55
- package/src/input/onboarding/onboarding-wizard-steps.ts +59 -35
- package/src/input/onboarding/onboarding-wizard-types.ts +4 -1
- package/src/input/onboarding/onboarding-wizard.ts +87 -2
- package/src/input/profile-picker-modal.ts +31 -12
- package/src/input/session-picker-modal.ts +21 -4
- package/src/input/settings-modal-agent-policy.ts +6 -6
- package/src/input/settings-modal-behavior.ts +0 -3
- package/src/input/settings-modal-subscriptions.ts +3 -3
- package/src/input/settings-modal-types.ts +2 -13
- package/src/input/settings-modal.ts +20 -66
- package/src/input/submission-intent.ts +0 -1
- package/src/input/submission-router.ts +3 -3
- package/src/main.ts +18 -10
- package/src/panels/approval-panel.ts +8 -8
- package/src/panels/automation-control-panel.ts +4 -4
- package/src/panels/base-panel.ts +1 -1
- package/src/panels/builtin/agent.ts +1 -1
- package/src/panels/builtin/operations.ts +3 -12
- package/src/panels/builtin/session.ts +32 -24
- package/src/panels/builtin/shared.ts +7 -7
- package/src/panels/cost-tracker-panel.ts +1 -1
- package/src/panels/docs-panel.ts +5 -3
- package/src/panels/index.ts +0 -1
- package/src/panels/knowledge-panel.ts +6 -5
- package/src/panels/memory-panel.ts +7 -6
- package/src/panels/panel-list-panel.ts +36 -80
- package/src/panels/project-planning-panel.ts +19 -12
- package/src/panels/provider-account-snapshot.ts +51 -25
- package/src/panels/provider-accounts-panel.ts +33 -18
- package/src/panels/provider-health-domains.ts +48 -7
- package/src/panels/provider-health-panel.ts +5 -4
- package/src/panels/qr-panel.ts +44 -20
- package/src/panels/schedule-panel.ts +9 -17
- package/src/panels/security-panel.ts +8 -8
- package/src/panels/session-browser-panel.ts +10 -10
- package/src/panels/subscription-panel.ts +6 -6
- package/src/panels/system-messages-panel.ts +3 -3
- package/src/panels/tasks-panel.ts +21 -14
- package/src/panels/tool-inspector-panel.ts +19 -12
- package/src/panels/work-plan-panel.ts +5 -5
- package/src/planning/project-planning-coordinator.ts +3 -3
- package/src/provider-auth-route-display.ts +9 -0
- package/src/renderer/agent-workspace-style.ts +34 -0
- package/src/renderer/agent-workspace.ts +254 -57
- package/src/renderer/autocomplete-overlay.ts +25 -6
- package/src/renderer/block-actions.ts +1 -3
- package/src/renderer/bookmark-modal.ts +19 -4
- package/src/renderer/buffer.ts +4 -2
- package/src/renderer/context-inspector.ts +50 -13
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +19 -6
- package/src/renderer/help-overlay.ts +112 -34
- package/src/renderer/history-search-overlay.ts +19 -4
- package/src/renderer/live-tail-modal.ts +27 -5
- package/src/renderer/mcp-workspace.ts +176 -43
- package/src/renderer/model-picker-overlay.ts +58 -3
- package/src/renderer/model-workspace.ts +104 -22
- package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
- package/src/renderer/process-modal.ts +27 -6
- package/src/renderer/profile-picker-modal.ts +21 -5
- package/src/renderer/search-overlay.ts +25 -5
- package/src/renderer/selection-modal-overlay.ts +46 -14
- package/src/renderer/session-picker-modal.ts +18 -1
- package/src/renderer/settings-modal-helpers.ts +2 -40
- package/src/renderer/settings-modal.ts +88 -55
- package/src/renderer/system-message.ts +1 -1
- package/src/renderer/tool-call.ts +20 -11
- package/src/runtime/agent-runtime-events.ts +129 -0
- package/src/runtime/bootstrap-command-context.ts +7 -1
- package/src/runtime/bootstrap-command-parts.ts +11 -8
- package/src/runtime/bootstrap-core.ts +23 -65
- package/src/runtime/bootstrap-hook-bridge.ts +7 -18
- package/src/runtime/bootstrap-shell.ts +46 -8
- package/src/runtime/bootstrap.ts +36 -46
- package/src/runtime/connected-host-auth.ts +47 -0
- package/src/runtime/diagnostics/panels/index.ts +2 -2
- package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
- package/src/runtime/diagnostics/panels/policy.ts +7 -7
- package/src/runtime/index.ts +2 -5
- package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
- package/src/runtime/onboarding/apply.ts +288 -74
- package/src/runtime/onboarding/derivation.ts +10 -13
- package/src/runtime/onboarding/snapshot.ts +2 -17
- package/src/runtime/onboarding/types.ts +34 -20
- package/src/runtime/onboarding/verify.ts +105 -4
- package/src/runtime/operator-token-cleanup.ts +3 -3
- package/src/runtime/services.ts +95 -11
- package/src/runtime/store/selectors/index.ts +3 -3
- package/src/runtime/store/state.ts +1 -4
- package/src/runtime/surface-feature-flags.ts +41 -6
- package/src/runtime/ui-read-models.ts +3 -4
- package/src/runtime/ui-services.ts +6 -6
- package/src/shell/blocking-input.ts +2 -1
- package/src/shell/service-settings-sync.ts +7 -7
- package/src/shell/ui-openers.ts +17 -38
- package/src/tools/agent-analysis-registry-policy.ts +0 -1
- package/src/tools/agent-channel-send-tool.ts +133 -0
- package/src/tools/agent-context-policy.ts +1 -1
- package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
- package/src/tools/agent-knowledge-tool.ts +170 -0
- package/src/tools/agent-local-registry-tool.ts +279 -73
- package/src/tools/agent-media-generate-tool.ts +133 -0
- package/src/tools/agent-notify-tool.ts +143 -0
- package/src/tools/agent-operator-action-tool.ts +137 -0
- package/src/tools/agent-operator-briefing-tool.ts +217 -0
- package/src/tools/agent-reminder-schedule-tool.ts +237 -0
- package/src/tools/agent-tool-policy-guard.ts +13 -15
- package/src/tools/agent-work-plan-tool.ts +256 -0
- package/src/version.ts +1 -1
- package/docs/connected-services.md +0 -51
- package/src/cli/package-verification.ts +0 -274
- package/src/input/commands/policy-dispatch.ts +0 -339
- package/src/input/commands/policy.ts +0 -17
- package/src/panels/panel-picker.ts +0 -105
- package/src/panels/policy-panel.ts +0 -308
- package/src/renderer/panel-picker-overlay.ts +0 -202
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, resolve } from 'node:path';
|
|
3
3
|
import type { CommandContext, CommandRegistry } from '../command-registry.ts';
|
|
4
|
-
import { createOAuthLocalListener } from '@pellux/goodvibes-sdk/platform/config';
|
|
5
4
|
import { beginOpenAICodexLogin, exchangeOpenAICodexCode } from '@pellux/goodvibes-sdk/platform/config';
|
|
6
5
|
import type { OAuthProviderConfig, ProviderSubscription } from '@pellux/goodvibes-sdk/platform/config';
|
|
7
6
|
import { getSubscriptionProviderConfig, listAvailableSubscriptionProviders } from '@pellux/goodvibes-sdk/platform/config';
|
|
8
7
|
import { inspectProviderAuth } from '@/runtime/index.ts';
|
|
8
|
+
import { formatAgentRecordSource } from '../../agent/record-labels.ts';
|
|
9
9
|
import { openExternalUrl } from '@pellux/goodvibes-sdk/platform/utils';
|
|
10
10
|
import { requireSecretsManager, requireServiceRegistry, requireShellPaths, requireSubscriptionManager } from './runtime-services.ts';
|
|
11
|
-
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
|
|
12
11
|
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
13
12
|
|
|
14
13
|
interface SubscriptionBundle {
|
|
@@ -24,13 +23,13 @@ function buildReviewText(ctx: CommandContext): string {
|
|
|
24
23
|
return [
|
|
25
24
|
'Subscription Review',
|
|
26
25
|
' No provider subscriptions stored yet.',
|
|
27
|
-
...(available.length > 0 ? [` available providers
|
|
26
|
+
...(available.length > 0 ? [` available providers ${available.map((entry) => entry.provider).join(', ')}`] : []),
|
|
28
27
|
].join('\n');
|
|
29
28
|
}
|
|
30
29
|
return [
|
|
31
30
|
`Subscription Review`,
|
|
32
31
|
...subscriptions.map((subscription) => (
|
|
33
|
-
` ${subscription.provider} ${subscription.authMode} token
|
|
32
|
+
` ${subscription.provider} auth mode ${subscription.authMode} token ${subscription.tokenType} expires ${subscription.expiresAt ? new Date(subscription.expiresAt).toISOString() : 'n/a'}`
|
|
34
33
|
)),
|
|
35
34
|
].join('\n');
|
|
36
35
|
}
|
|
@@ -39,8 +38,8 @@ function inspectBundle(path: string): string {
|
|
|
39
38
|
const bundle = JSON.parse(readFileSync(path, 'utf-8')) as SubscriptionBundle;
|
|
40
39
|
return [
|
|
41
40
|
'Subscription Bundle Review',
|
|
42
|
-
`
|
|
43
|
-
` subscriptions
|
|
41
|
+
` exported at ${new Date(bundle.exportedAt).toISOString()}`,
|
|
42
|
+
` subscriptions ${bundle.subscriptions.length}`,
|
|
44
43
|
...bundle.subscriptions.map((subscription) => ` ${subscription.provider} ${subscription.authMode}`),
|
|
45
44
|
].join('\n');
|
|
46
45
|
}
|
|
@@ -57,19 +56,16 @@ function extractAuthorizationCode(input: string): string | null {
|
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
: config;
|
|
65
|
-
}
|
|
66
|
-
return config;
|
|
59
|
+
function resolveManualLoginConfig(config: OAuthProviderConfig): OAuthProviderConfig {
|
|
60
|
+
return config.manualRedirectUri
|
|
61
|
+
? { ...config, redirectUri: config.manualRedirectUri }
|
|
62
|
+
: config;
|
|
67
63
|
}
|
|
68
64
|
|
|
69
65
|
function describePrecedence(record: Pick<ProviderSubscription, 'overrideAmbientApiKeys'>): string {
|
|
70
66
|
return record.overrideAmbientApiKeys
|
|
71
|
-
? ' precedence
|
|
72
|
-
: ' precedence
|
|
67
|
+
? ' precedence this now overrides ambient API keys for the provider'
|
|
68
|
+
: ' precedence stored for subscription-backed flows only; ambient API keys are unchanged';
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
export function registerSubscriptionRuntimeCommands(registry: CommandRegistry): void {
|
|
@@ -77,15 +73,10 @@ export function registerSubscriptionRuntimeCommands(registry: CommandRegistry):
|
|
|
77
73
|
name: 'subscription',
|
|
78
74
|
aliases: ['subs'],
|
|
79
75
|
description: 'Manage provider subscription sessions and, when supported, let them override ambient API keys for matching providers',
|
|
80
|
-
usage: '[review|list|providers|inspect <provider>|login <provider> start [--no-browser]
|
|
76
|
+
usage: '[review|list|providers|inspect <provider>|login <provider> start [--no-browser] --yes|login <provider> finish <code-or-url> --yes|logout <provider> --yes|bundle export <path> --yes|bundle inspect <path>]',
|
|
81
77
|
async handler(args, ctx) {
|
|
82
78
|
const parsed = stripYesFlag(args);
|
|
83
79
|
const commandArgs = [...parsed.rest];
|
|
84
|
-
const shellPaths = requireShellPaths(ctx);
|
|
85
|
-
if (args.length === 0 && ctx.openSubscriptionPanel) {
|
|
86
|
-
ctx.openSubscriptionPanel();
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
80
|
const sub = (commandArgs[0] ?? 'review').toLowerCase();
|
|
90
81
|
const manager = requireSubscriptionManager(ctx);
|
|
91
82
|
const services = requireServiceRegistry(ctx);
|
|
@@ -104,7 +95,7 @@ export function registerSubscriptionRuntimeCommands(registry: CommandRegistry):
|
|
|
104
95
|
ctx.print([
|
|
105
96
|
'Available Subscription Providers',
|
|
106
97
|
...available.map((provider) => (
|
|
107
|
-
` ${provider.provider}
|
|
98
|
+
` ${provider.provider} origin ${formatAgentRecordSource(provider.source)} redirect ${provider.oauth.redirectUri}`
|
|
108
99
|
)),
|
|
109
100
|
].join('\n'));
|
|
110
101
|
return;
|
|
@@ -128,29 +119,28 @@ export function registerSubscriptionRuntimeCommands(registry: CommandRegistry):
|
|
|
128
119
|
});
|
|
129
120
|
ctx.print([
|
|
130
121
|
`Subscription ${provider}`,
|
|
131
|
-
` configured
|
|
132
|
-
` freshness
|
|
133
|
-
|
|
122
|
+
` configured ${inspection.configured ? 'yes' : 'no'}`,
|
|
123
|
+
` freshness ${inspection.freshness}`,
|
|
124
|
+
' finish mode explicit manual',
|
|
134
125
|
...(resolved ? [
|
|
135
|
-
`
|
|
136
|
-
`
|
|
137
|
-
`
|
|
138
|
-
`
|
|
139
|
-
...(inspection.localCallback ? [` localCallback: ${inspection.localCallback}`] : []),
|
|
126
|
+
` origin ${formatAgentRecordSource(resolved.source)}`,
|
|
127
|
+
` redirect URI ${resolved.oauth.redirectUri}`,
|
|
128
|
+
` auth URL ${resolved.oauth.authUrl}`,
|
|
129
|
+
` token URL ${resolved.oauth.tokenUrl}`,
|
|
140
130
|
] : []),
|
|
141
131
|
...(inspection.activeSubscription ? [
|
|
142
|
-
`
|
|
143
|
-
`
|
|
144
|
-
`
|
|
145
|
-
`
|
|
146
|
-
`
|
|
147
|
-
`
|
|
132
|
+
` auth mode ${manager.get(provider)?.authMode ?? 'oauth'}`,
|
|
133
|
+
` token type ${inspection.tokenType ?? 'n/a'}`,
|
|
134
|
+
` created at ${manager.get(provider)?.createdAt ? new Date(manager.get(provider)!.createdAt).toISOString() : 'n/a'}`,
|
|
135
|
+
` updated at ${manager.get(provider)?.updatedAt ? new Date(manager.get(provider)!.updatedAt).toISOString() : 'n/a'}`,
|
|
136
|
+
` expires at ${inspection.expiresAt ? new Date(inspection.expiresAt).toISOString() : 'n/a'}`,
|
|
137
|
+
` refresh token ${manager.get(provider)?.refreshToken ? 'present' : 'absent'}`,
|
|
148
138
|
describePrecedence(manager.get(provider)!),
|
|
149
139
|
] : [
|
|
150
|
-
` state
|
|
140
|
+
` state ${inspection.freshness === 'pending' ? 'pending login' : 'available for login'}`,
|
|
151
141
|
]),
|
|
152
|
-
...inspection.issues.map((issue) => ` issue
|
|
153
|
-
...inspection.nextActions.map((action) => ` next
|
|
142
|
+
...inspection.issues.map((issue) => ` issue ${issue}`),
|
|
143
|
+
...inspection.nextActions.map((action) => ` next ${action}`),
|
|
154
144
|
].join('\n'));
|
|
155
145
|
return;
|
|
156
146
|
}
|
|
@@ -179,7 +169,6 @@ export function registerSubscriptionRuntimeCommands(registry: CommandRegistry):
|
|
|
179
169
|
if (mode === 'start') {
|
|
180
170
|
const flags = new Set(commandArgs.slice(3));
|
|
181
171
|
const openBrowser = !flags.has('--no-browser');
|
|
182
|
-
const useManualMode = flags.has('--manual');
|
|
183
172
|
if (provider === 'openai' && resolved.source === 'builtin') {
|
|
184
173
|
const started = await beginOpenAICodexLogin();
|
|
185
174
|
manager.savePending({
|
|
@@ -190,158 +179,38 @@ export function registerSubscriptionRuntimeCommands(registry: CommandRegistry):
|
|
|
190
179
|
createdAt: Date.now(),
|
|
191
180
|
});
|
|
192
181
|
|
|
193
|
-
let listener: Awaited<ReturnType<typeof createOAuthLocalListener>> | null = null;
|
|
194
|
-
if (!useManualMode) {
|
|
195
|
-
try {
|
|
196
|
-
listener = await createOAuthLocalListener({
|
|
197
|
-
expectedState: started.state,
|
|
198
|
-
host: '127.0.0.1',
|
|
199
|
-
port: 1455,
|
|
200
|
-
path: '/auth/callback',
|
|
201
|
-
}).catch(() => null); // best-effort: listener creation is optional; null triggers manual flow
|
|
202
|
-
} catch {
|
|
203
|
-
listener = null;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
182
|
const browserOpened = openBrowser
|
|
208
183
|
? await openExternalUrl(started.authorizationUrl)
|
|
209
184
|
: false;
|
|
210
185
|
|
|
211
|
-
if (listener && browserOpened) {
|
|
212
|
-
try {
|
|
213
|
-
const callback = await listener.waitForCode();
|
|
214
|
-
const token = await exchangeOpenAICodexCode(callback.code, started.verifier);
|
|
215
|
-
const now = Date.now();
|
|
216
|
-
const record = manager.saveSubscription({
|
|
217
|
-
provider,
|
|
218
|
-
accessToken: token.accessToken,
|
|
219
|
-
refreshToken: token.refreshToken,
|
|
220
|
-
tokenType: token.tokenType,
|
|
221
|
-
expiresAt: token.expiresAt,
|
|
222
|
-
...(token.scopes ? { scopes: token.scopes } : {}),
|
|
223
|
-
authMode: 'oauth',
|
|
224
|
-
overrideAmbientApiKeys: false,
|
|
225
|
-
createdAt: manager.get(provider)?.createdAt ?? now,
|
|
226
|
-
updatedAt: now,
|
|
227
|
-
});
|
|
228
|
-
ctx.print([
|
|
229
|
-
`Subscription OAuth Start: ${provider}`,
|
|
230
|
-
` source: ${resolved.source}`,
|
|
231
|
-
` state: ${started.state}`,
|
|
232
|
-
` redirectUri: ${started.redirectUri}`,
|
|
233
|
-
` browser: ${openBrowser ? (browserOpened ? 'opened' : 'open failed') : 'skipped'}`,
|
|
234
|
-
' authorizationUrl:',
|
|
235
|
-
` ${started.authorizationUrl}`,
|
|
236
|
-
`Subscription OAuth Complete: ${provider}`,
|
|
237
|
-
` tokenType: ${record.tokenType}`,
|
|
238
|
-
` expiresAt: ${record.expiresAt ? new Date(record.expiresAt).toISOString() : 'n/a'}`,
|
|
239
|
-
describePrecedence(record),
|
|
240
|
-
].join('\n'));
|
|
241
|
-
return;
|
|
242
|
-
} catch (error) {
|
|
243
|
-
listener.close();
|
|
244
|
-
ctx.print([
|
|
245
|
-
`Subscription OAuth Start: ${provider}`,
|
|
246
|
-
` source: ${resolved.source}`,
|
|
247
|
-
` state: ${started.state}`,
|
|
248
|
-
` redirectUri: ${started.redirectUri}`,
|
|
249
|
-
` browser: ${openBrowser ? (browserOpened ? 'opened' : 'open failed') : 'skipped'}`,
|
|
250
|
-
` next: /subscription login ${provider} finish <code-or-url> --yes`,
|
|
251
|
-
` listener: ${summarizeError(error)}`,
|
|
252
|
-
' authorizationUrl:',
|
|
253
|
-
` ${started.authorizationUrl}`,
|
|
254
|
-
].join('\n'));
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
listener?.close();
|
|
260
186
|
ctx.print([
|
|
261
|
-
`Subscription OAuth
|
|
262
|
-
`
|
|
263
|
-
` state
|
|
264
|
-
`
|
|
265
|
-
` browser
|
|
266
|
-
|
|
267
|
-
|
|
187
|
+
`Subscription OAuth start ${provider}`,
|
|
188
|
+
` origin ${formatAgentRecordSource(resolved.source)}`,
|
|
189
|
+
` state ${started.state}`,
|
|
190
|
+
` redirect URI ${started.redirectUri}`,
|
|
191
|
+
` browser ${openBrowser ? (browserOpened ? 'opened' : 'open failed') : 'skipped'}`,
|
|
192
|
+
' completion paste the callback code or redirect URL into the finish command',
|
|
193
|
+
` next /subscription login ${provider} finish <code-or-url> --yes`,
|
|
194
|
+
' authorization URL',
|
|
268
195
|
` ${started.authorizationUrl}`,
|
|
269
196
|
].join('\n'));
|
|
270
197
|
return;
|
|
271
198
|
}
|
|
272
|
-
const
|
|
273
|
-
let activeConfig = resolveLoginConfig(resolved.oauth, useLocalCallback);
|
|
274
|
-
let listener: Awaited<ReturnType<typeof createOAuthLocalListener>> | null = null;
|
|
275
|
-
|
|
276
|
-
if (useLocalCallback && resolved.oauth.localCallback) {
|
|
277
|
-
listener = await createOAuthLocalListener({
|
|
278
|
-
expectedState: '',
|
|
279
|
-
host: resolved.oauth.localCallback.host,
|
|
280
|
-
port: resolved.oauth.localCallback.port,
|
|
281
|
-
path: resolved.oauth.localCallback.path,
|
|
282
|
-
}).catch(() => null); // best-effort: local callback listener is optional; null falls back to manual redirect
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (listener) {
|
|
286
|
-
activeConfig = { ...activeConfig, redirectUri: listener.redirectUri };
|
|
287
|
-
}
|
|
288
|
-
|
|
199
|
+
const activeConfig = resolveManualLoginConfig(resolved.oauth);
|
|
289
200
|
const started = await manager.beginOAuthLogin(provider, activeConfig);
|
|
290
|
-
if (listener) {
|
|
291
|
-
listener.setExpectedState(started.pending.state);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
201
|
const browserOpened = openBrowser
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const shouldAutoComplete = Boolean(listener) && (resolved.oauth.localCallback?.autoComplete ?? true) && browserOpened;
|
|
299
|
-
|
|
300
|
-
if (shouldAutoComplete && listener) {
|
|
301
|
-
try {
|
|
302
|
-
const callback = await listener.waitForCode();
|
|
303
|
-
const record = await manager.completeOAuthLogin(provider, activeConfig, callback.code);
|
|
304
|
-
ctx.print([
|
|
305
|
-
`Subscription OAuth Start: ${provider}`,
|
|
306
|
-
` source: ${resolved.source}`,
|
|
307
|
-
` state: ${started.pending.state}`,
|
|
308
|
-
` redirectUri: ${activeConfig.redirectUri}`,
|
|
309
|
-
` browser: ${openBrowser ? (browserOpened ? 'opened' : 'open failed') : 'skipped'}`,
|
|
310
|
-
' authorizationUrl:',
|
|
311
|
-
` ${started.authorizationUrl}`,
|
|
312
|
-
`Subscription OAuth Complete: ${provider}`,
|
|
313
|
-
` tokenType: ${record.tokenType}`,
|
|
314
|
-
` expiresAt: ${record.expiresAt ? new Date(record.expiresAt).toISOString() : 'n/a'}`,
|
|
315
|
-
describePrecedence(record),
|
|
316
|
-
].join('\n'));
|
|
317
|
-
return;
|
|
318
|
-
} catch (error) {
|
|
319
|
-
listener.close();
|
|
320
|
-
ctx.print([
|
|
321
|
-
`Subscription OAuth Start: ${provider}`,
|
|
322
|
-
` source: ${resolved.source}`,
|
|
323
|
-
` state: ${started.pending.state}`,
|
|
324
|
-
` redirectUri: ${activeConfig.redirectUri}`,
|
|
325
|
-
` browser: ${openBrowser ? (browserOpened ? 'opened' : 'open failed') : 'skipped'}`,
|
|
326
|
-
` next: /subscription login ${provider} finish <code-or-url> --yes`,
|
|
327
|
-
` listener: ${summarizeError(error)}`,
|
|
328
|
-
' authorizationUrl:',
|
|
329
|
-
` ${started.authorizationUrl}`,
|
|
330
|
-
].join('\n'));
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
listener?.close();
|
|
202
|
+
? await openExternalUrl(started.authorizationUrl)
|
|
203
|
+
: false;
|
|
336
204
|
|
|
337
205
|
ctx.print([
|
|
338
|
-
`Subscription OAuth
|
|
339
|
-
`
|
|
340
|
-
` state
|
|
341
|
-
`
|
|
342
|
-
` browser
|
|
343
|
-
|
|
344
|
-
|
|
206
|
+
`Subscription OAuth start ${provider}`,
|
|
207
|
+
` origin ${formatAgentRecordSource(resolved.source)}`,
|
|
208
|
+
` state ${started.pending.state}`,
|
|
209
|
+
` redirect URI ${activeConfig.redirectUri}`,
|
|
210
|
+
` browser ${openBrowser ? (browserOpened ? 'opened' : 'open failed') : 'skipped'}`,
|
|
211
|
+
' completion paste the callback code or redirect URL into the finish command',
|
|
212
|
+
` next /subscription login ${provider} finish <code-or-url> --yes`,
|
|
213
|
+
' authorization URL',
|
|
345
214
|
` ${started.authorizationUrl}`,
|
|
346
215
|
].join('\n'));
|
|
347
216
|
return;
|
|
@@ -375,18 +244,18 @@ export function registerSubscriptionRuntimeCommands(registry: CommandRegistry):
|
|
|
375
244
|
});
|
|
376
245
|
ctx.print([
|
|
377
246
|
`Stored subscription session for ${provider}.`,
|
|
378
|
-
`
|
|
379
|
-
`
|
|
247
|
+
` token type ${record.tokenType}`,
|
|
248
|
+
` expires at ${record.expiresAt ? new Date(record.expiresAt).toISOString() : 'n/a'}`,
|
|
380
249
|
describePrecedence(record),
|
|
381
250
|
].join('\n'));
|
|
382
251
|
return;
|
|
383
252
|
}
|
|
384
|
-
const activeConfig =
|
|
253
|
+
const activeConfig = resolveManualLoginConfig(resolved.oauth);
|
|
385
254
|
const record = await manager.completeOAuthLogin(provider, activeConfig, code);
|
|
386
255
|
ctx.print([
|
|
387
256
|
`Stored subscription session for ${provider}.`,
|
|
388
|
-
`
|
|
389
|
-
`
|
|
257
|
+
` token type ${record.tokenType}`,
|
|
258
|
+
` expires at ${record.expiresAt ? new Date(record.expiresAt).toISOString() : 'n/a'}`,
|
|
390
259
|
describePrecedence(record),
|
|
391
260
|
].join('\n'));
|
|
392
261
|
return;
|
|
@@ -419,7 +288,7 @@ export function registerSubscriptionRuntimeCommands(registry: CommandRegistry):
|
|
|
419
288
|
ctx.print('Usage: /subscription bundle <export|inspect> <path>');
|
|
420
289
|
return;
|
|
421
290
|
}
|
|
422
|
-
const targetPath =
|
|
291
|
+
const targetPath = requireShellPaths(ctx).resolveWorkspacePath(pathArg);
|
|
423
292
|
if (mode === 'export') {
|
|
424
293
|
if (!parsed.yes) {
|
|
425
294
|
requireYesFlag(ctx, `export subscription bundle to ${pathArg}`, '/subscription bundle export <path> --yes');
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { CommandRegistry } from '../command-registry.ts';
|
|
2
|
+
import type { CliCommandRuntime } from '../../cli/management.ts';
|
|
3
|
+
import { handleBundleCommand } from '../../cli/bundle-command.ts';
|
|
4
|
+
import { parseGoodVibesCli } from '../../cli/parser.ts';
|
|
5
|
+
import { requireShellPaths } from './runtime-services.ts';
|
|
6
|
+
import { requireYesFlag, stripYesFlag } from './confirmation.ts';
|
|
7
|
+
|
|
8
|
+
function bundleUsageFor(subcommand: string | undefined): string {
|
|
9
|
+
if (subcommand === 'export') return '/bundle export [path] --yes';
|
|
10
|
+
if (subcommand === 'import') return '/bundle import <path> --yes';
|
|
11
|
+
if (subcommand === 'inspect') return '/bundle inspect <path>';
|
|
12
|
+
return '/bundle [export [path] --yes|inspect <path>|import <path> --yes]';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function bundleActionFor(subcommand: string): string | null {
|
|
16
|
+
if (subcommand === 'export') return 'export Agent support bundle';
|
|
17
|
+
if (subcommand === 'import') return 'import Agent support bundle';
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function registerSupportBundleRuntimeCommands(registry: CommandRegistry): void {
|
|
22
|
+
registry.register({
|
|
23
|
+
name: 'bundle',
|
|
24
|
+
description: 'Export, inspect, or import redacted Agent support bundles from the TUI',
|
|
25
|
+
usage: '[export [path] --yes|inspect <path>|import <path> --yes]',
|
|
26
|
+
argsHint: 'export|inspect|import',
|
|
27
|
+
async handler(args, ctx) {
|
|
28
|
+
const confirmation = stripYesFlag(args);
|
|
29
|
+
const cli = parseGoodVibesCli(['bundle', ...confirmation.rest], 'goodvibes-agent');
|
|
30
|
+
if (cli.errors.length > 0) {
|
|
31
|
+
ctx.print(cli.errors.join('\n'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const subcommand = cli.commandArgs[0] ?? 'inspect';
|
|
36
|
+
const guardedAction = bundleActionFor(subcommand);
|
|
37
|
+
if (guardedAction !== null && !confirmation.yes) {
|
|
38
|
+
requireYesFlag(ctx, guardedAction, bundleUsageFor(subcommand));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const shellPaths = requireShellPaths(ctx);
|
|
43
|
+
const runtime: CliCommandRuntime = {
|
|
44
|
+
cli,
|
|
45
|
+
configManager: ctx.platform.configManager,
|
|
46
|
+
workingDirectory: shellPaths.workingDirectory,
|
|
47
|
+
homeDirectory: shellPaths.homeDirectory,
|
|
48
|
+
};
|
|
49
|
+
const result = await handleBundleCommand(runtime);
|
|
50
|
+
ctx.print(result.output);
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
}
|
|
@@ -16,10 +16,10 @@ const BLOCKED_TASK_MUTATIONS: ReadonlySet<string> = new Set([
|
|
|
16
16
|
function printTaskMutationBlocked(print: (text: string) => void, subcommand: string): void {
|
|
17
17
|
print([
|
|
18
18
|
`Task mutation "${subcommand}" is blocked in GoodVibes Agent.`,
|
|
19
|
-
' policy
|
|
20
|
-
' durable tasks
|
|
21
|
-
' build/fix/review
|
|
22
|
-
' result
|
|
19
|
+
' policy connected-host tasks are read-only from the Agent TUI; normal work stays in the main conversation.',
|
|
20
|
+
' durable tasks use /workplan for visible planning and task tracking.',
|
|
21
|
+
' build/fix/review use /delegate <task> to hand explicit implementation work to GoodVibes TUI.',
|
|
22
|
+
' result no local task state was changed.',
|
|
23
23
|
].join('\n'));
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -51,12 +51,12 @@ export function registerTasksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
51
51
|
registry.register({
|
|
52
52
|
name: 'tasks',
|
|
53
53
|
aliases: ['task'],
|
|
54
|
-
description: 'Inspect connected-
|
|
54
|
+
description: 'Inspect connected-host tasks without starting or mutating local background work',
|
|
55
55
|
usage: '[list [status|kind] | show <taskId> | output <taskId>]',
|
|
56
56
|
handler(args, ctx) {
|
|
57
57
|
const subcommand = args[0]?.toLowerCase() ?? 'list';
|
|
58
58
|
if (subcommand === 'open' || subcommand === 'panel') {
|
|
59
|
-
ctx.print('
|
|
59
|
+
ctx.print('Open Agent Workspace -> Work -> Host tasks for the workspace view, or run /tasks list for compact command output.');
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -76,7 +76,7 @@ export function registerTasksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
ctx.print([
|
|
79
|
-
`
|
|
79
|
+
`Connected-host Tasks (${filtered.length})`,
|
|
80
80
|
...filtered.slice(0, 20).map((task) => ` ${task.id} ${task.status.padEnd(9)} ${task.kind.padEnd(11)} ${task.owner} ${task.title}`),
|
|
81
81
|
].join('\n'));
|
|
82
82
|
return;
|
|
@@ -90,23 +90,23 @@ export function registerTasksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
90
90
|
}
|
|
91
91
|
const task = operatorClient.tasks.get(taskId);
|
|
92
92
|
if (!task) {
|
|
93
|
-
ctx.print(`Unknown task
|
|
93
|
+
ctx.print(`Unknown task ${taskId}`);
|
|
94
94
|
return;
|
|
95
95
|
}
|
|
96
96
|
ctx.print([
|
|
97
97
|
`Task ${task.id}`,
|
|
98
|
-
` title
|
|
98
|
+
` title ${task.title}`,
|
|
99
99
|
` kind: ${task.kind}`,
|
|
100
|
-
` status
|
|
101
|
-
` owner
|
|
102
|
-
` cancellable
|
|
103
|
-
`
|
|
104
|
-
`
|
|
105
|
-
`
|
|
106
|
-
` parent
|
|
107
|
-
` children
|
|
108
|
-
`
|
|
109
|
-
` summary
|
|
100
|
+
` status ${task.status}`,
|
|
101
|
+
` owner ${task.owner}`,
|
|
102
|
+
` cancellable ${task.cancellable ? 'yes' : 'no'}`,
|
|
103
|
+
` queued at ${new Date(task.queuedAt).toISOString()}`,
|
|
104
|
+
` started at ${task.startedAt ? new Date(task.startedAt).toISOString() : 'n/a'}`,
|
|
105
|
+
` ended at ${task.endedAt ? new Date(task.endedAt).toISOString() : 'n/a'}`,
|
|
106
|
+
` parent ${task.parentTaskId ?? 'none'}`,
|
|
107
|
+
` children ${task.childTaskIds.join(', ') || '(none)'}`,
|
|
108
|
+
` correlation ID ${task.correlationId ?? 'n/a'}`,
|
|
109
|
+
` summary ${summarizeTaskResult(task)}`,
|
|
110
110
|
].join('\n'));
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
@@ -119,7 +119,7 @@ export function registerTasksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
119
119
|
}
|
|
120
120
|
const task = operatorClient.tasks.get(taskId);
|
|
121
121
|
if (!task) {
|
|
122
|
-
ctx.print(`Unknown task
|
|
122
|
+
ctx.print(`Unknown task ${taskId}`);
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
const payload = typeof task.result === 'string'
|
|
@@ -131,7 +131,7 @@ export function registerTasksRuntimeCommands(registry: CommandRegistry): void {
|
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
ctx.print(`Unknown tasks subcommand
|
|
134
|
+
ctx.print(`Unknown tasks subcommand ${subcommand}`);
|
|
135
135
|
},
|
|
136
136
|
});
|
|
137
137
|
}
|
|
@@ -26,7 +26,12 @@ function getStore(ctx: import('../command-registry.ts').CommandContext): WorkPla
|
|
|
26
26
|
|
|
27
27
|
function formatList(store: WorkPlanStore): string {
|
|
28
28
|
const items = store.listItems();
|
|
29
|
-
if (items.length === 0)
|
|
29
|
+
if (items.length === 0) {
|
|
30
|
+
return [
|
|
31
|
+
'Work plan is empty',
|
|
32
|
+
' next /workplan add <title>',
|
|
33
|
+
].join('\n');
|
|
34
|
+
}
|
|
30
35
|
return [
|
|
31
36
|
`Work Plan (${items.length})`,
|
|
32
37
|
...items.map((item) => {
|
|
@@ -83,7 +88,7 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
83
88
|
const subcommand = (commandArgs[0] ?? 'list').toLowerCase();
|
|
84
89
|
try {
|
|
85
90
|
if (subcommand === 'panel' || subcommand === 'open') {
|
|
86
|
-
ctx.print('
|
|
91
|
+
ctx.print('Open Agent Workspace -> Work -> Work plan for the workspace view, or run /workplan list for compact command output.');
|
|
87
92
|
return;
|
|
88
93
|
}
|
|
89
94
|
if (subcommand === 'list') {
|
|
@@ -106,7 +111,12 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
106
111
|
...(addArgs.notes ? { notes: addArgs.notes } : {}),
|
|
107
112
|
};
|
|
108
113
|
const item = store.addItem(addArgs.title, addOptions);
|
|
109
|
-
ctx.print(
|
|
114
|
+
ctx.print([
|
|
115
|
+
'Added work plan item',
|
|
116
|
+
` id ${item.id}`,
|
|
117
|
+
` title ${item.title}`,
|
|
118
|
+
' next open Agent Workspace -> Work -> Work plan to review',
|
|
119
|
+
].join('\n'));
|
|
110
120
|
return;
|
|
111
121
|
}
|
|
112
122
|
if (subcommand === 'remove' || subcommand === 'delete' || subcommand === 'rm') {
|
|
@@ -120,7 +130,11 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
120
130
|
return;
|
|
121
131
|
}
|
|
122
132
|
const item = store.removeItem(id);
|
|
123
|
-
ctx.print(
|
|
133
|
+
ctx.print([
|
|
134
|
+
'Removed work plan item',
|
|
135
|
+
` id ${item.id}`,
|
|
136
|
+
` title ${item.title}`,
|
|
137
|
+
].join('\n'));
|
|
124
138
|
return;
|
|
125
139
|
}
|
|
126
140
|
if (subcommand === 'clear-done' || subcommand === 'clear-completed') {
|
|
@@ -129,7 +143,10 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
129
143
|
return;
|
|
130
144
|
}
|
|
131
145
|
const count = store.clearCompleted();
|
|
132
|
-
ctx.print(
|
|
146
|
+
ctx.print([
|
|
147
|
+
'Cleared completed/cancelled work plan items',
|
|
148
|
+
` count ${count}`,
|
|
149
|
+
].join('\n'));
|
|
133
150
|
return;
|
|
134
151
|
}
|
|
135
152
|
if (subcommand === 'cycle' || subcommand === 'toggle') {
|
|
@@ -139,7 +156,11 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
139
156
|
return;
|
|
140
157
|
}
|
|
141
158
|
const item = store.cycleItemStatus(id);
|
|
142
|
-
ctx.print(
|
|
159
|
+
ctx.print([
|
|
160
|
+
'Updated work plan item',
|
|
161
|
+
` id ${item.id}`,
|
|
162
|
+
` status ${item.status}`,
|
|
163
|
+
].join('\n'));
|
|
143
164
|
return;
|
|
144
165
|
}
|
|
145
166
|
const status = STATUS_COMMANDS[subcommand];
|
|
@@ -150,14 +171,18 @@ export function registerWorkPlanRuntimeCommands(registry: CommandRegistry): void
|
|
|
150
171
|
return;
|
|
151
172
|
}
|
|
152
173
|
const item = store.setItemStatus(id, status);
|
|
153
|
-
ctx.print(
|
|
174
|
+
ctx.print([
|
|
175
|
+
'Updated work plan item',
|
|
176
|
+
` id ${item.id}`,
|
|
177
|
+
` status ${item.status}`,
|
|
178
|
+
].join('\n'));
|
|
154
179
|
return;
|
|
155
180
|
}
|
|
156
181
|
if (WORK_PLAN_STATUSES.includes(subcommand as WorkPlanItemStatus)) {
|
|
157
182
|
ctx.print(`Usage: /workplan ${subcommand} <id>`);
|
|
158
183
|
return;
|
|
159
184
|
}
|
|
160
|
-
ctx.print(`Unknown workplan subcommand
|
|
185
|
+
ctx.print(`Unknown workplan subcommand ${subcommand}`);
|
|
161
186
|
} catch (error) {
|
|
162
187
|
ctx.print(summarizeError(error));
|
|
163
188
|
}
|
package/src/input/commands.ts
CHANGED
|
@@ -36,6 +36,9 @@ import { registerAgentSkillsRuntimeCommands } from './commands/agent-skills-runt
|
|
|
36
36
|
import { registerRoutinesRuntimeCommands } from './commands/routines-runtime.ts';
|
|
37
37
|
import { registerChannelsRuntimeCommands } from './commands/channels-runtime.ts';
|
|
38
38
|
import { registerBriefRuntimeCommands } from './commands/brief-runtime.ts';
|
|
39
|
+
import { registerSupportBundleRuntimeCommands } from './commands/support-bundle-runtime.ts';
|
|
40
|
+
import { registerCompatRuntimeCommands } from './commands/compat-runtime.ts';
|
|
41
|
+
import { registerOperatorActionRuntimeCommands } from './commands/operator-actions-runtime.ts';
|
|
39
42
|
|
|
40
43
|
function registerAgentMemoryCommand(registry: CommandRegistry): void {
|
|
41
44
|
registry.register({
|
|
@@ -58,6 +61,9 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
|
|
|
58
61
|
registerShellCoreCommands(registry);
|
|
59
62
|
registerAgentWorkspaceRuntimeCommands(registry);
|
|
60
63
|
registerBriefRuntimeCommands(registry);
|
|
64
|
+
registerSupportBundleRuntimeCommands(registry);
|
|
65
|
+
registerCompatRuntimeCommands(registry);
|
|
66
|
+
registerOperatorActionRuntimeCommands(registry);
|
|
61
67
|
registerAgentRuntimeProfileRuntimeCommands(registry);
|
|
62
68
|
registerPersonasRuntimeCommands(registry);
|
|
63
69
|
registerAgentSkillsRuntimeCommands(registry);
|
|
@@ -66,7 +72,6 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
|
|
|
66
72
|
registerDelegationRuntimeCommands(registry);
|
|
67
73
|
registerConfigCommand(registry);
|
|
68
74
|
registerOperatorRuntimeCommands(registry);
|
|
69
|
-
registry.unregister('profiles');
|
|
70
75
|
registerNotifyRuntimeCommands(registry);
|
|
71
76
|
registerProductRuntimeCommands(registry);
|
|
72
77
|
registerPlatformAccessRuntimeCommands(registry);
|
|
@@ -89,7 +94,6 @@ export function registerBuiltinCommands(registry: CommandRegistry): void {
|
|
|
89
94
|
registerPlanningRuntimeCommands(registry);
|
|
90
95
|
registerScheduleRuntimeCommands(registry);
|
|
91
96
|
registerSessionContentCommands(registry);
|
|
92
|
-
registry.unregister('session-memory');
|
|
93
97
|
registerAgentMemoryCommand(registry);
|
|
94
98
|
|
|
95
99
|
// ── /session ─────────────────────────────────────────────────────────────
|
|
@@ -140,7 +140,6 @@ export interface FeedContextClosures {
|
|
|
140
140
|
handleBlockCopy: () => void;
|
|
141
141
|
handleBookmark: () => void;
|
|
142
142
|
handleBlockSave: () => void;
|
|
143
|
-
handleDiffApply: () => boolean;
|
|
144
143
|
handleUndo: () => void;
|
|
145
144
|
handleRedo: () => void;
|
|
146
145
|
handlePaste: () => void;
|
|
@@ -148,7 +147,8 @@ export interface FeedContextClosures {
|
|
|
148
147
|
ensureInputCursorVisible: (contentWidth?: number) => void;
|
|
149
148
|
registerPaste: (content: string) => string;
|
|
150
149
|
executeBlockAction: (id: string) => void;
|
|
151
|
-
|
|
150
|
+
cycleAgentWorkspaceCategory: (direction: 'next' | 'prev') => void;
|
|
151
|
+
dismissAgentWorkspace: () => boolean;
|
|
152
152
|
onPanelInputConsumed: (activePanel: Panel | null, key: string) => void;
|
|
153
153
|
getWrappedPromptInfo: (contentWidth: number) => WrappedPromptInfo;
|
|
154
154
|
moveCursorVertical: (direction: -1 | 1) => boolean;
|