@vybestack/llxprt-code 0.4.8 → 0.5.0-nightly.251102.6bb3db7a
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/dist/package.json +5 -3
- package/dist/src/auth/__tests__/oauthManager.safety.test.d.ts +6 -0
- package/dist/src/auth/__tests__/oauthManager.safety.test.js +49 -0
- package/dist/src/auth/__tests__/oauthManager.safety.test.js.map +1 -0
- package/dist/src/auth/oauth-manager.d.ts +11 -0
- package/dist/src/auth/oauth-manager.js +62 -29
- package/dist/src/auth/oauth-manager.js.map +1 -1
- package/dist/src/auth/oauth-manager.spec.js +7 -2
- package/dist/src/auth/oauth-manager.spec.js.map +1 -1
- package/dist/src/config/__tests__/nonInteractiveTools.test.d.ts +6 -0
- package/dist/src/config/__tests__/nonInteractiveTools.test.js +13 -0
- package/dist/src/config/__tests__/nonInteractiveTools.test.js.map +1 -0
- package/dist/src/config/__tests__/profileBootstrap.test.d.ts +6 -0
- package/dist/src/config/__tests__/profileBootstrap.test.js +91 -0
- package/dist/src/config/__tests__/profileBootstrap.test.js.map +1 -0
- package/dist/src/config/config.d.ts +6 -2
- package/dist/src/config/config.js +219 -18
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/profileBootstrap.d.ts +64 -0
- package/dist/src/config/profileBootstrap.js +140 -0
- package/dist/src/config/profileBootstrap.js.map +1 -0
- package/dist/src/gemini.js +68 -23
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +1 -2
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.js +110 -450
- package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -1
- package/dist/src/integration-tests/model-params-isolation.integration.test.js +101 -539
- package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -1
- package/dist/src/integration-tests/modelParams.integration.test.js +86 -761
- package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -1
- package/dist/src/integration-tests/provider-multi-runtime.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/provider-multi-runtime.integration.test.js +198 -0
- package/dist/src/integration-tests/provider-multi-runtime.integration.test.js.map +1 -0
- package/dist/src/integration-tests/provider-switching.integration.test.js +97 -151
- package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -1
- package/dist/src/integration-tests/runtime-isolation.test.d.ts +13 -0
- package/dist/src/integration-tests/runtime-isolation.test.js +170 -0
- package/dist/src/integration-tests/runtime-isolation.test.js.map +1 -0
- package/dist/src/integration-tests/test-utils.js +19 -2
- package/dist/src/integration-tests/test-utils.js.map +1 -1
- package/dist/src/integration-tests/test-utils.test.js +9 -8
- package/dist/src/integration-tests/test-utils.test.js.map +1 -1
- package/dist/src/integration-tests/todo-continuation.integration.test.js +5 -2
- package/dist/src/integration-tests/todo-continuation.integration.test.js.map +1 -1
- package/dist/src/integration-tests/tools-governance.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/tools-governance.integration.test.js +98 -0
- package/dist/src/integration-tests/tools-governance.integration.test.js.map +1 -0
- package/dist/src/nonInteractiveCli.js +36 -11
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/providers/logging/git-stats.test.js +11 -1
- package/dist/src/providers/logging/git-stats.test.js.map +1 -1
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js +1 -2
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -1
- package/dist/src/providers/logging/performance.test.js +1 -1
- package/dist/src/providers/logging/performance.test.js.map +1 -1
- package/dist/src/providers/oauth-provider-registration.d.ts +2 -2
- package/dist/src/providers/oauth-provider-registration.js +25 -9
- package/dist/src/providers/oauth-provider-registration.js.map +1 -1
- package/dist/src/providers/provider-gemini-switching.test.js +67 -89
- package/dist/src/providers/provider-gemini-switching.test.js.map +1 -1
- package/dist/src/providers/provider-switching.integration.test.js +42 -98
- package/dist/src/providers/provider-switching.integration.test.js.map +1 -1
- package/dist/src/providers/providerConfigUtils.d.ts +12 -7
- package/dist/src/providers/providerConfigUtils.js +31 -99
- package/dist/src/providers/providerConfigUtils.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.d.ts +17 -1
- package/dist/src/providers/providerManagerInstance.js +157 -175
- package/dist/src/providers/providerManagerInstance.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.oauthRegistration.test.js +19 -15
- package/dist/src/providers/providerManagerInstance.oauthRegistration.test.js.map +1 -1
- package/dist/src/providers/providerManagerInstance.test.js +2 -5
- package/dist/src/providers/providerManagerInstance.test.js.map +1 -1
- package/dist/src/runtime/__tests__/profileApplication.test.d.ts +5 -0
- package/dist/src/runtime/__tests__/profileApplication.test.js +232 -0
- package/dist/src/runtime/__tests__/profileApplication.test.js.map +1 -0
- package/dist/src/runtime/__tests__/runtimeIsolation.test.d.ts +5 -0
- package/dist/src/runtime/__tests__/runtimeIsolation.test.js +376 -0
- package/dist/src/runtime/__tests__/runtimeIsolation.test.js.map +1 -0
- package/dist/src/runtime/agentRuntimeAdapter.d.ts +249 -0
- package/dist/src/runtime/agentRuntimeAdapter.js +506 -0
- package/dist/src/runtime/agentRuntimeAdapter.js.map +1 -0
- package/dist/src/runtime/agentRuntimeAdapter.spec.d.ts +6 -0
- package/dist/src/runtime/agentRuntimeAdapter.spec.js +866 -0
- package/dist/src/runtime/agentRuntimeAdapter.spec.js.map +1 -0
- package/dist/src/runtime/messages.d.ts +28 -0
- package/dist/src/runtime/messages.js +64 -0
- package/dist/src/runtime/messages.js.map +1 -0
- package/dist/src/runtime/profileApplication.d.ts +33 -0
- package/dist/src/runtime/profileApplication.js +191 -0
- package/dist/src/runtime/profileApplication.js.map +1 -0
- package/dist/src/runtime/providerConfigUtils.test.d.ts +1 -0
- package/dist/src/runtime/providerConfigUtils.test.js +68 -0
- package/dist/src/runtime/providerConfigUtils.test.js.map +1 -0
- package/dist/src/runtime/runtimeContextFactory.d.ts +102 -0
- package/dist/src/runtime/runtimeContextFactory.js +190 -0
- package/dist/src/runtime/runtimeContextFactory.js.map +1 -0
- package/dist/src/runtime/runtimeSettings.d.ts +217 -0
- package/dist/src/runtime/runtimeSettings.js +1094 -0
- package/dist/src/runtime/runtimeSettings.js.map +1 -0
- package/dist/src/runtime/runtimeSettings.test.d.ts +1 -0
- package/dist/src/runtime/runtimeSettings.test.js +320 -0
- package/dist/src/runtime/runtimeSettings.test.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.d.ts +13 -4
- package/dist/src/services/BuiltinCommandLoader.js +17 -4
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.js +34 -13
- package/dist/src/services/McpPromptLoader.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +5 -2
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/ui/App.js +29 -49
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/commands/aboutCommand.js +59 -38
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/authCommand.js +7 -9
- package/dist/src/ui/commands/authCommand.js.map +1 -1
- package/dist/src/ui/commands/baseurlCommand.js +8 -44
- package/dist/src/ui/commands/baseurlCommand.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +28 -12
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.d.ts +0 -3
- package/dist/src/ui/commands/diagnosticsCommand.js +45 -191
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.js +9 -58
- package/dist/src/ui/commands/keyCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.test.js +48 -102
- package/dist/src/ui/commands/keyCommand.test.js.map +1 -1
- package/dist/src/ui/commands/keyfileCommand.js +42 -93
- package/dist/src/ui/commands/keyfileCommand.js.map +1 -1
- package/dist/src/ui/commands/logoutCommand.js +2 -2
- package/dist/src/ui/commands/logoutCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.js +29 -7
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/modelCommand.js +8 -59
- package/dist/src/ui/commands/modelCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.js +151 -267
- package/dist/src/ui/commands/profileCommand.js.map +1 -1
- package/dist/src/ui/commands/profileCommand.test.js +88 -344
- package/dist/src/ui/commands/profileCommand.test.js.map +1 -1
- package/dist/src/ui/commands/providerCommand.js +9 -3
- package/dist/src/ui/commands/providerCommand.js.map +1 -1
- package/dist/src/ui/commands/restoreCommand.js +38 -18
- package/dist/src/ui/commands/restoreCommand.js.map +1 -1
- package/dist/src/ui/commands/schema/argumentResolver.test.d.ts +6 -0
- package/dist/src/ui/commands/schema/argumentResolver.test.js +619 -0
- package/dist/src/ui/commands/schema/argumentResolver.test.js.map +1 -0
- package/dist/src/ui/commands/schema/index.d.ts +15 -0
- package/dist/src/ui/commands/schema/index.js +320 -0
- package/dist/src/ui/commands/schema/index.js.map +1 -0
- package/dist/src/ui/commands/schema/types.d.ts +61 -0
- package/dist/src/ui/commands/schema/types.js +12 -0
- package/dist/src/ui/commands/schema/types.js.map +1 -0
- package/dist/src/ui/commands/setCommand.js +641 -325
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.test.js +92 -388
- package/dist/src/ui/commands/setCommand.test.js.map +1 -1
- package/dist/src/ui/commands/statusCommand.js +2 -2
- package/dist/src/ui/commands/statusCommand.js.map +1 -1
- package/dist/src/ui/commands/subagentCommand.d.ts +16 -0
- package/dist/src/ui/commands/subagentCommand.js +674 -0
- package/dist/src/ui/commands/subagentCommand.js.map +1 -0
- package/dist/src/ui/commands/test/setCommand.mutation.test.d.ts +6 -0
- package/dist/src/ui/commands/test/setCommand.mutation.test.js +132 -0
- package/dist/src/ui/commands/test/setCommand.mutation.test.js.map +1 -0
- package/dist/src/ui/commands/test/setCommand.phase09.test.d.ts +6 -0
- package/dist/src/ui/commands/test/setCommand.phase09.test.js +222 -0
- package/dist/src/ui/commands/test/setCommand.phase09.test.js.map +1 -0
- package/dist/src/ui/commands/test/subagentCommand.schema.test.d.ts +6 -0
- package/dist/src/ui/commands/test/subagentCommand.schema.test.js +125 -0
- package/dist/src/ui/commands/test/subagentCommand.schema.test.js.map +1 -0
- package/dist/src/ui/commands/test/subagentCommand.test.d.ts +1 -0
- package/dist/src/ui/commands/test/subagentCommand.test.js +598 -0
- package/dist/src/ui/commands/test/subagentCommand.test.js.map +1 -0
- package/dist/src/ui/commands/toolformatCommand.js +25 -98
- package/dist/src/ui/commands/toolformatCommand.js.map +1 -1
- package/dist/src/ui/commands/toolformatCommand.test.js +56 -102
- package/dist/src/ui/commands/toolformatCommand.test.js.map +1 -1
- package/dist/src/ui/commands/toolsCommand.js +187 -31
- package/dist/src/ui/commands/toolsCommand.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +11 -2
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.js +16 -55
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/Footer.js +4 -5
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +1 -1
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.js +6 -11
- package/dist/src/ui/components/StatsDisplay.js.map +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.d.ts +13 -1
- package/dist/src/ui/components/SuggestionsDisplay.js +22 -3
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.d.ts +1 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.js +14 -14
- package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +1 -0
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
- package/dist/src/ui/containers/SessionController.js +61 -117
- package/dist/src/ui/containers/SessionController.js.map +1 -1
- package/dist/src/ui/contexts/RuntimeContext.d.ts +61 -0
- package/dist/src/ui/contexts/RuntimeContext.js +118 -0
- package/dist/src/ui/contexts/RuntimeContext.js.map +1 -0
- package/dist/src/ui/contexts/TodoProvider.d.ts +1 -0
- package/dist/src/ui/contexts/TodoProvider.js +10 -8
- package/dist/src/ui/contexts/TodoProvider.js.map +1 -1
- package/dist/src/ui/contexts/ToolCallProvider.d.ts +1 -0
- package/dist/src/ui/contexts/ToolCallProvider.js +10 -9
- package/dist/src/ui/contexts/ToolCallProvider.js.map +1 -1
- package/dist/src/ui/hooks/__tests__/useSlashCompletion.set.phase09.test.d.ts +6 -0
- package/dist/src/ui/hooks/__tests__/useSlashCompletion.set.phase09.test.js +39 -0
- package/dist/src/ui/hooks/__tests__/useSlashCompletion.set.phase09.test.js.map +1 -0
- package/dist/src/ui/hooks/atCommandProcessor.js +11 -3
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +3 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.js +4 -1
- package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +1 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js +27 -1
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAuthCommand.js +11 -3
- package/dist/src/ui/hooks/useAuthCommand.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.d.ts +1 -0
- package/dist/src/ui/hooks/useCommandCompletion.js +2 -0
- package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +37 -11
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.subagent.spec.d.ts +6 -0
- package/dist/src/ui/hooks/useGeminiStream.subagent.spec.js +232 -0
- package/dist/src/ui/hooks/useGeminiStream.subagent.spec.js.map +1 -0
- package/dist/src/ui/hooks/useLoadProfileDialog.d.ts +1 -1
- package/dist/src/ui/hooks/useLoadProfileDialog.js +18 -57
- package/dist/src/ui/hooks/useLoadProfileDialog.js.map +1 -1
- package/dist/src/ui/hooks/useOpenAIProviderInfo.d.ts +1 -1
- package/dist/src/ui/hooks/useOpenAIProviderInfo.js +12 -7
- package/dist/src/ui/hooks/useOpenAIProviderInfo.js.map +1 -1
- package/dist/src/ui/hooks/useProviderDialog.d.ts +1 -1
- package/dist/src/ui/hooks/useProviderDialog.js +17 -90
- package/dist/src/ui/hooks/useProviderDialog.js.map +1 -1
- package/dist/src/ui/hooks/useProviderModelDialog.d.ts +2 -2
- package/dist/src/ui/hooks/useProviderModelDialog.js +11 -12
- package/dist/src/ui/hooks/useProviderModelDialog.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +3 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +144 -34
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.d.ts +32 -0
- package/dist/src/ui/hooks/useSlashCompletion.js +154 -77
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js +39 -14
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +108 -79
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/types.d.ts +1 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/utils/sandbox.js +7 -5
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +4 -2
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +30 -30
- package/dist/src/zed-integration/zedIntegration.js +112 -39
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +5 -3
- package/dist/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Vybestack LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/* @jsxImportSource react */
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { Text } from 'ink';
|
|
9
|
+
import { CommandKind, } from './types.js';
|
|
10
|
+
import { Colors } from '../colors.js';
|
|
11
|
+
import { FunctionCallingConfigMode } from '@google/genai';
|
|
12
|
+
import { spawnSync } from 'child_process';
|
|
13
|
+
import * as fs from 'fs';
|
|
14
|
+
import * as os from 'os';
|
|
15
|
+
import * as path from 'path';
|
|
16
|
+
import { getRuntimeBridge } from '../contexts/RuntimeContext.js';
|
|
17
|
+
/**
|
|
18
|
+
* Parse save command arguments
|
|
19
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P12
|
|
20
|
+
* @requirement:REQ-004
|
|
21
|
+
* @requirement:REQ-011
|
|
22
|
+
* @pseudocode SubagentCommand.md lines 1-17
|
|
23
|
+
*/
|
|
24
|
+
function parseSaveArgs(args) {
|
|
25
|
+
const match = args.match(/^(\S+)\s+(\S+)\s+(auto|manual)\s+"((?:[^"\\]|\\.)*)("|"?)/);
|
|
26
|
+
if (!match) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const [, name, profile, mode, input] = match;
|
|
30
|
+
return { name, profile, mode: mode, input };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Handle manual mode subagent save
|
|
34
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P12
|
|
35
|
+
* @requirement:REQ-004
|
|
36
|
+
* @pseudocode SubagentCommand.md lines 61-66
|
|
37
|
+
*/
|
|
38
|
+
const handleManualMode = async (context, name, profile, systemPrompt, options) => {
|
|
39
|
+
const existed = options?.existed ?? false;
|
|
40
|
+
return saveSubagent(context, name, profile, systemPrompt, existed);
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Shared save subagent logic
|
|
44
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
45
|
+
* @requirement:REQ-002
|
|
46
|
+
* @requirement:REQ-004
|
|
47
|
+
* @requirement:REQ-014
|
|
48
|
+
* @pseudocode SubagentCommand.md lines 67-93
|
|
49
|
+
*/
|
|
50
|
+
async function saveSubagent(context, name, profile, systemPrompt, existed) {
|
|
51
|
+
const manager = context.services.subagentManager;
|
|
52
|
+
if (!manager) {
|
|
53
|
+
return {
|
|
54
|
+
type: 'message',
|
|
55
|
+
messageType: 'error',
|
|
56
|
+
content: 'Service not available. Run system integration (Phase 15).',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
await manager.saveSubagent(name, profile, systemPrompt);
|
|
61
|
+
const status = existed ? 'updated' : 'created';
|
|
62
|
+
return {
|
|
63
|
+
type: 'message',
|
|
64
|
+
messageType: 'info',
|
|
65
|
+
content: `Subagent '${name}' ${status} successfully with profile '${profile}'.`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return {
|
|
70
|
+
type: 'message',
|
|
71
|
+
messageType: 'error',
|
|
72
|
+
content: error instanceof Error
|
|
73
|
+
? `Failed to save subagent: ${error.message}`
|
|
74
|
+
: 'Failed to save subagent due to an unknown error.',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* @plan:PLAN-20251013-AUTOCOMPLETE.P08
|
|
80
|
+
* @requirement:REQ-002
|
|
81
|
+
* @requirement:REQ-003
|
|
82
|
+
* @requirement:REQ-004
|
|
83
|
+
* @pseudocode ArgumentSchema.md lines 91-104
|
|
84
|
+
* Schema definition for subagent command completion
|
|
85
|
+
*/
|
|
86
|
+
const subagentSchema = [
|
|
87
|
+
{
|
|
88
|
+
kind: 'value',
|
|
89
|
+
name: 'name',
|
|
90
|
+
description: 'Enter subagent name',
|
|
91
|
+
completer: async (ctx, partialArg) => {
|
|
92
|
+
const manager = ctx.services.subagentManager;
|
|
93
|
+
if (!manager) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
const names = await manager.listSubagents();
|
|
97
|
+
const normalizedPartial = partialArg.toLowerCase();
|
|
98
|
+
const matchingNames = names.filter((name) => normalizedPartial.length === 0
|
|
99
|
+
? true
|
|
100
|
+
: name.toLowerCase().startsWith(normalizedPartial));
|
|
101
|
+
const suggestions = await Promise.all(matchingNames.map(async (name) => {
|
|
102
|
+
try {
|
|
103
|
+
const details = await manager.loadSubagent(name);
|
|
104
|
+
return {
|
|
105
|
+
value: name,
|
|
106
|
+
description: `Profile: ${details.profile}`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return {
|
|
111
|
+
value: name,
|
|
112
|
+
description: 'Subagent',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}));
|
|
116
|
+
return suggestions;
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
kind: 'value',
|
|
121
|
+
name: 'profile',
|
|
122
|
+
description: 'Select profile configuration',
|
|
123
|
+
completer: async (ctx, partialArg) => {
|
|
124
|
+
const profileManager = ctx.services.profileManager;
|
|
125
|
+
if (!profileManager ||
|
|
126
|
+
typeof profileManager.listProfiles !== 'function') {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const profiles = await profileManager.listProfiles();
|
|
131
|
+
const normalizedPartial = partialArg.toLowerCase();
|
|
132
|
+
const filtered = profiles.filter((name) => normalizedPartial.length === 0
|
|
133
|
+
? true
|
|
134
|
+
: name.toLowerCase().startsWith(normalizedPartial));
|
|
135
|
+
return filtered.map((name) => ({
|
|
136
|
+
value: name,
|
|
137
|
+
description: 'Saved profile',
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.warn('Error loading profiles for subagent completion:', error);
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
kind: 'literal',
|
|
148
|
+
value: 'auto',
|
|
149
|
+
description: 'Automatic mode',
|
|
150
|
+
next: [
|
|
151
|
+
{
|
|
152
|
+
kind: 'value',
|
|
153
|
+
name: 'prompt',
|
|
154
|
+
description: 'Enter system prompt for automatic mode',
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
kind: 'literal',
|
|
160
|
+
value: 'manual',
|
|
161
|
+
description: 'Manual mode',
|
|
162
|
+
next: [
|
|
163
|
+
{
|
|
164
|
+
kind: 'value',
|
|
165
|
+
name: 'prompt',
|
|
166
|
+
description: 'Enter system prompt for manual mode',
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
/**
|
|
172
|
+
* /subagent save command - Auto and Manual modes
|
|
173
|
+
*
|
|
174
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P14
|
|
175
|
+
* @requirement:REQ-003
|
|
176
|
+
* @requirement:REQ-004
|
|
177
|
+
* @requirement:REQ-014
|
|
178
|
+
* @requirement:REQ-015
|
|
179
|
+
* @pseudocode SubagentCommand.md lines 1-90
|
|
180
|
+
*/
|
|
181
|
+
const saveCommand = {
|
|
182
|
+
name: 'save',
|
|
183
|
+
altNames: ['create'],
|
|
184
|
+
description: 'Save a subagent configuration (auto or manual mode)',
|
|
185
|
+
kind: CommandKind.BUILT_IN,
|
|
186
|
+
// Schema-based completion replaces legacy completion function
|
|
187
|
+
schema: subagentSchema,
|
|
188
|
+
action: async (context, args) => {
|
|
189
|
+
// Parse arguments: <name> <profile> <mode> "<text>"
|
|
190
|
+
const parsedArgs = parseSaveArgs(args);
|
|
191
|
+
if (!parsedArgs) {
|
|
192
|
+
return {
|
|
193
|
+
type: 'message',
|
|
194
|
+
messageType: 'error',
|
|
195
|
+
content: 'Usage: /subagent save <name> <profile> auto|manual "<text>"',
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const { name, profile, mode, input } = parsedArgs;
|
|
199
|
+
const { services, overwriteConfirmed, invocation } = context;
|
|
200
|
+
const subagentManager = services.subagentManager; // @plan:PLAN-20250117-SUBAGENTCONFIG.P14 @requirement:REQ-003
|
|
201
|
+
if (!subagentManager) {
|
|
202
|
+
return {
|
|
203
|
+
type: 'message',
|
|
204
|
+
messageType: 'error',
|
|
205
|
+
content: 'SubagentManager service is unavailable. Please run integration (Phase 15) before using /subagent.',
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// Validate profile exists (pseudocode lines 263-281 cover this)
|
|
209
|
+
const profileExists = await subagentManager.validateProfileReference(profile);
|
|
210
|
+
if (!profileExists) {
|
|
211
|
+
return {
|
|
212
|
+
type: 'message',
|
|
213
|
+
messageType: 'error',
|
|
214
|
+
content: `Profile '${profile}' not found. Use '/profile list' to see available profiles.`,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
// Check if exists for overwrite confirmation
|
|
218
|
+
const exists = await subagentManager.subagentExists(name);
|
|
219
|
+
if (exists && !overwriteConfirmed) {
|
|
220
|
+
return {
|
|
221
|
+
type: 'confirm_action',
|
|
222
|
+
prompt: React.createElement(Text, null, 'A subagent with the name ', React.createElement(Text, { color: Colors.AccentPurple }, name), ' already exists. Do you want to overwrite it?'),
|
|
223
|
+
originalInvocation: {
|
|
224
|
+
raw: invocation?.raw || '',
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
let finalSystemPrompt;
|
|
229
|
+
if (mode === 'manual') {
|
|
230
|
+
// Manual mode: use input directly
|
|
231
|
+
finalSystemPrompt = input;
|
|
232
|
+
return handleManualMode(context, name, profile, finalSystemPrompt, {
|
|
233
|
+
existed: exists,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
// Auto mode: generate using LLM
|
|
238
|
+
const configService = services.config; // @plan:PLAN-20250117-SUBAGENTCONFIG.P14 @requirement:REQ-003
|
|
239
|
+
if (!configService) {
|
|
240
|
+
return {
|
|
241
|
+
type: 'message',
|
|
242
|
+
messageType: 'error',
|
|
243
|
+
content: 'Configuration service unavailable. Set up the CLI before using auto mode.',
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
const client = configService.getGeminiClient();
|
|
248
|
+
if (!client) {
|
|
249
|
+
return {
|
|
250
|
+
type: 'message',
|
|
251
|
+
messageType: 'error',
|
|
252
|
+
content: 'Unable to access Gemini client. Run /auth login or try manual mode.',
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
// Construct prompt
|
|
256
|
+
const autoModePrompt = `Generate a detailed system prompt for a subagent with the following purpose:\n\n${input}\n\nRequirements:\n- Create a comprehensive system prompt that defines the subagent's role, capabilities, and behavior\n- Be specific and actionable\n- Use clear, professional language\n- Output ONLY the system prompt text, no explanations or metadata`;
|
|
257
|
+
// Call LLM with a direct request that bypasses tool declarations and history
|
|
258
|
+
let response;
|
|
259
|
+
try {
|
|
260
|
+
const runtimeBridge = getRuntimeBridge();
|
|
261
|
+
response = await runtimeBridge.runWithScope(() => client.generateDirectMessage({
|
|
262
|
+
message: autoModePrompt,
|
|
263
|
+
config: {
|
|
264
|
+
tools: [],
|
|
265
|
+
toolConfig: {
|
|
266
|
+
functionCallingConfig: {
|
|
267
|
+
mode: FunctionCallingConfigMode.NONE,
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
}, 'subagent-auto-prompt'));
|
|
272
|
+
}
|
|
273
|
+
catch (_runtimeError) {
|
|
274
|
+
response = await client.generateDirectMessage({
|
|
275
|
+
message: autoModePrompt,
|
|
276
|
+
config: {
|
|
277
|
+
tools: [],
|
|
278
|
+
toolConfig: {
|
|
279
|
+
functionCallingConfig: {
|
|
280
|
+
mode: FunctionCallingConfigMode.NONE,
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
}, 'subagent-auto-prompt');
|
|
285
|
+
}
|
|
286
|
+
finalSystemPrompt = response.text || '';
|
|
287
|
+
if (finalSystemPrompt.trim() === '') {
|
|
288
|
+
return {
|
|
289
|
+
type: 'message',
|
|
290
|
+
messageType: 'error',
|
|
291
|
+
content: 'Error: Model returned empty response. Try manual mode or rephrase your description.',
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch (_error) {
|
|
296
|
+
return {
|
|
297
|
+
type: 'message',
|
|
298
|
+
messageType: 'error',
|
|
299
|
+
content: 'Error: Failed to generate system prompt. Try manual mode or check your connection.',
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
// Dispatch to shared save logic for auto mode
|
|
303
|
+
return saveSubagent(context, name, profile, finalSystemPrompt, exists);
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
/**
|
|
308
|
+
* /subagent list command
|
|
309
|
+
*
|
|
310
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
311
|
+
* @requirement:REQ-005
|
|
312
|
+
* @pseudocode SubagentCommand.md lines 135-182
|
|
313
|
+
*/
|
|
314
|
+
const listCommand = {
|
|
315
|
+
name: 'list',
|
|
316
|
+
description: 'List all saved subagents',
|
|
317
|
+
kind: CommandKind.BUILT_IN,
|
|
318
|
+
action: async (context, _args) => {
|
|
319
|
+
const { services } = context;
|
|
320
|
+
const subagentManager = services.subagentManager;
|
|
321
|
+
if (!subagentManager) {
|
|
322
|
+
return {
|
|
323
|
+
type: 'message',
|
|
324
|
+
messageType: 'error',
|
|
325
|
+
content: 'SubagentManager service is unavailable. Please run integration (Phase 15) before using /subagent.',
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
try {
|
|
329
|
+
const names = await subagentManager.listSubagents();
|
|
330
|
+
if (names.length === 0) {
|
|
331
|
+
return {
|
|
332
|
+
type: 'message',
|
|
333
|
+
messageType: 'info',
|
|
334
|
+
content: "No subagents found. Use '/subagent save' to create one.",
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
// Load each subagent for details
|
|
338
|
+
const details = await Promise.all(names.map(async (n) => {
|
|
339
|
+
const config = await subagentManager.loadSubagent(n);
|
|
340
|
+
return { name: n, config };
|
|
341
|
+
})); // @plan:PLAN-20250117-SUBAGENTCONFIG.P08 @requirement:REQ-005
|
|
342
|
+
/**
|
|
343
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
344
|
+
* @requirement:REQ-005
|
|
345
|
+
* @requirement:REQ-009
|
|
346
|
+
* @pseudocode SubagentCommand.md lines 159-166
|
|
347
|
+
*/
|
|
348
|
+
// Sort by creation date (oldest first as per pseudocode)
|
|
349
|
+
details.sort((itemA, itemB) => new Date(itemA.config.createdAt).getTime() -
|
|
350
|
+
new Date(itemB.config.createdAt).getTime()); // @plan:PLAN-20250117-SUBAGENTCONFIG.P09 @requirement:REQ-009
|
|
351
|
+
// Format output
|
|
352
|
+
const lines = ['List of saved subagents:\n'];
|
|
353
|
+
for (const { name, config } of details) {
|
|
354
|
+
const createdDate = new Date(config.createdAt).toLocaleString();
|
|
355
|
+
lines.push(` - ${name} (profile: ${config.profile}, created: ${createdDate})`);
|
|
356
|
+
}
|
|
357
|
+
lines.push("\nNote: Use '/subagent show <name>' to view full configuration");
|
|
358
|
+
return {
|
|
359
|
+
type: 'message',
|
|
360
|
+
messageType: 'info',
|
|
361
|
+
content: lines.join('\n'),
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
catch (_error) {
|
|
365
|
+
return {
|
|
366
|
+
type: 'message',
|
|
367
|
+
messageType: 'error',
|
|
368
|
+
content: 'Failed to list subagents',
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* /subagent show command
|
|
375
|
+
*
|
|
376
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
377
|
+
* @requirement:REQ-006
|
|
378
|
+
* @pseudocode SubagentCommand.md lines 183-234
|
|
379
|
+
*/
|
|
380
|
+
const showCommand = {
|
|
381
|
+
name: 'show',
|
|
382
|
+
description: 'Show detailed subagent configuration',
|
|
383
|
+
kind: CommandKind.BUILT_IN,
|
|
384
|
+
action: async (context, args) => {
|
|
385
|
+
const name = args.trim();
|
|
386
|
+
if (!name) {
|
|
387
|
+
return {
|
|
388
|
+
type: 'message',
|
|
389
|
+
messageType: 'error',
|
|
390
|
+
content: 'Usage: /subagent show <name>',
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
const { services } = context;
|
|
394
|
+
const subagentManager = services.subagentManager;
|
|
395
|
+
if (!subagentManager) {
|
|
396
|
+
return {
|
|
397
|
+
type: 'message',
|
|
398
|
+
messageType: 'error',
|
|
399
|
+
content: 'SubagentManager service is unavailable. Please run integration (Phase 15) before using /subagent.',
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
try {
|
|
403
|
+
const config = await subagentManager.loadSubagent(name);
|
|
404
|
+
const createdDate = new Date(config.createdAt).toLocaleString();
|
|
405
|
+
const updatedDate = new Date(config.updatedAt).toLocaleString();
|
|
406
|
+
const separator = '-'.repeat(60);
|
|
407
|
+
const output = [
|
|
408
|
+
`Subagent: ${config.name}`,
|
|
409
|
+
`Profile: ${config.profile}`,
|
|
410
|
+
`Created: ${createdDate}`,
|
|
411
|
+
`Updated: ${updatedDate}`,
|
|
412
|
+
'',
|
|
413
|
+
'System Prompt:',
|
|
414
|
+
separator,
|
|
415
|
+
config.systemPrompt,
|
|
416
|
+
separator,
|
|
417
|
+
].join('\n');
|
|
418
|
+
return {
|
|
419
|
+
type: 'message',
|
|
420
|
+
messageType: 'info',
|
|
421
|
+
content: output,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
catch (_error) {
|
|
425
|
+
return {
|
|
426
|
+
type: 'message',
|
|
427
|
+
messageType: 'error',
|
|
428
|
+
content: `Error: Subagent '${name}' not found. Use /subagent list to see available subagents.`,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
* /subagent delete command
|
|
435
|
+
*
|
|
436
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
437
|
+
* @requirement:REQ-007
|
|
438
|
+
* @requirement:REQ-015
|
|
439
|
+
* @pseudocode SubagentCommand.md lines 235-291
|
|
440
|
+
*/
|
|
441
|
+
const deleteCommand = {
|
|
442
|
+
name: 'delete',
|
|
443
|
+
description: 'Delete a subagent configuration',
|
|
444
|
+
kind: CommandKind.BUILT_IN,
|
|
445
|
+
action: async (context, args) => {
|
|
446
|
+
const name = args.trim();
|
|
447
|
+
if (!name) {
|
|
448
|
+
return {
|
|
449
|
+
type: 'message',
|
|
450
|
+
messageType: 'error',
|
|
451
|
+
content: 'Usage: /subagent delete <name>',
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
const { services, overwriteConfirmed, invocation } = context;
|
|
455
|
+
const subagentManager = services.subagentManager;
|
|
456
|
+
if (!subagentManager) {
|
|
457
|
+
return {
|
|
458
|
+
type: 'message',
|
|
459
|
+
messageType: 'error',
|
|
460
|
+
content: 'SubagentManager service is unavailable. Please run integration (Phase 15) before using /subagent.',
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
465
|
+
* @requirement:REQ-007
|
|
466
|
+
* @pseudocode SubagentCommand.md lines 258-264
|
|
467
|
+
*/
|
|
468
|
+
// Check if subagent exists
|
|
469
|
+
const exists = await subagentManager.subagentExists(name);
|
|
470
|
+
if (!exists) {
|
|
471
|
+
return {
|
|
472
|
+
type: 'message',
|
|
473
|
+
messageType: 'error',
|
|
474
|
+
content: `Subagent '${name}' not found.`,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
479
|
+
* @requirement:REQ-007
|
|
480
|
+
* @pseudocode SubagentCommand.md lines 265-274
|
|
481
|
+
*/
|
|
482
|
+
// Prompt for confirmation if not already given
|
|
483
|
+
if (!overwriteConfirmed) {
|
|
484
|
+
return {
|
|
485
|
+
type: 'confirm_action',
|
|
486
|
+
prompt: React.createElement(Text, null, 'Are you sure you want to delete subagent ', React.createElement(Text, { color: Colors.AccentPurple }, name), '? This action cannot be undone.'),
|
|
487
|
+
originalInvocation: {
|
|
488
|
+
raw: invocation?.raw || '',
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P08
|
|
494
|
+
* @requirement:REQ-007
|
|
495
|
+
* @pseudocode SubagentCommand.md lines 276-283
|
|
496
|
+
*/
|
|
497
|
+
try {
|
|
498
|
+
await subagentManager.deleteSubagent(name);
|
|
499
|
+
return {
|
|
500
|
+
type: 'message',
|
|
501
|
+
messageType: 'info',
|
|
502
|
+
content: `Successfully deleted subagent '${name}'.`,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
return {
|
|
507
|
+
type: 'message',
|
|
508
|
+
messageType: 'error',
|
|
509
|
+
content: error instanceof Error
|
|
510
|
+
? `Failed to delete subagent: ${error.message}`
|
|
511
|
+
: 'Failed to delete subagent due to an unknown error.',
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
};
|
|
516
|
+
/**
|
|
517
|
+
* /subagent edit command
|
|
518
|
+
*
|
|
519
|
+
* @plan:PLAN-20250117-SUBAGENTCONFIG.P11
|
|
520
|
+
* @requirement:REQ-008
|
|
521
|
+
* @requirement:REQ-015
|
|
522
|
+
* @pseudocode SubagentCommand.md lines 166-210
|
|
523
|
+
*
|
|
524
|
+
* Pattern: Uses spawnSync approach from text-buffer.ts
|
|
525
|
+
*/
|
|
526
|
+
const editCommand = {
|
|
527
|
+
name: 'edit',
|
|
528
|
+
description: 'Edit subagent configuration in system editor',
|
|
529
|
+
kind: CommandKind.BUILT_IN,
|
|
530
|
+
action: async (context, args) => {
|
|
531
|
+
const name = args.trim();
|
|
532
|
+
if (!name) {
|
|
533
|
+
return {
|
|
534
|
+
type: 'message',
|
|
535
|
+
messageType: 'error',
|
|
536
|
+
content: 'Usage: /subagent edit <name>',
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
const { services } = context;
|
|
540
|
+
const subagentManager = services.subagentManager; // @plan:PLAN-20250117-SUBAGENTCONFIG.P11 @requirement:REQ-008
|
|
541
|
+
if (!subagentManager) {
|
|
542
|
+
return {
|
|
543
|
+
type: 'message',
|
|
544
|
+
messageType: 'error',
|
|
545
|
+
content: 'SubagentManager service is unavailable. Please run integration (Phase 15) before using /subagent.',
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
// Check if subagent exists
|
|
549
|
+
const exists = await subagentManager.subagentExists(name);
|
|
550
|
+
if (!exists) {
|
|
551
|
+
return {
|
|
552
|
+
type: 'message',
|
|
553
|
+
messageType: 'error',
|
|
554
|
+
content: `Error: Subagent '${name}' not found.`,
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
// Load current config
|
|
558
|
+
const config = await subagentManager.loadSubagent(name);
|
|
559
|
+
// Create temp file (like text-buffer.ts does)
|
|
560
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subagent-edit-'));
|
|
561
|
+
const filePath = path.join(tmpDir, `${name}.json`);
|
|
562
|
+
try {
|
|
563
|
+
// Write current config to temp file
|
|
564
|
+
fs.writeFileSync(filePath, JSON.stringify(config, null, 2), 'utf8');
|
|
565
|
+
// Determine editor (like text-buffer.ts)
|
|
566
|
+
const editor = process.env.VISUAL || process.env.EDITOR || 'vi';
|
|
567
|
+
// Launch editor with spawnSync (BLOCKS until editor closes)
|
|
568
|
+
const { status, error } = spawnSync(editor, [filePath], {
|
|
569
|
+
stdio: 'inherit',
|
|
570
|
+
});
|
|
571
|
+
if (error) {
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
if (typeof status === 'number' && status !== 0) {
|
|
575
|
+
throw new Error(`Editor exited with status ${status}`);
|
|
576
|
+
}
|
|
577
|
+
// Read edited content
|
|
578
|
+
const editedContent = fs.readFileSync(filePath, 'utf8');
|
|
579
|
+
// Parse and validate JSON
|
|
580
|
+
let editedConfig;
|
|
581
|
+
try {
|
|
582
|
+
editedConfig = JSON.parse(editedContent);
|
|
583
|
+
}
|
|
584
|
+
catch (_error) {
|
|
585
|
+
return {
|
|
586
|
+
type: 'message',
|
|
587
|
+
messageType: 'error',
|
|
588
|
+
content: 'Error: Invalid JSON after edit. Changes not saved.',
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
// Validate required fields
|
|
592
|
+
if (!editedConfig.name ||
|
|
593
|
+
!editedConfig.profile ||
|
|
594
|
+
!editedConfig.systemPrompt) {
|
|
595
|
+
return {
|
|
596
|
+
type: 'message',
|
|
597
|
+
messageType: 'error',
|
|
598
|
+
content: 'Error: Required fields missing. Changes not saved.',
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
// Validate profile exists
|
|
602
|
+
const profileValid = await subagentManager.validateProfileReference(editedConfig.profile);
|
|
603
|
+
if (!profileValid) {
|
|
604
|
+
return {
|
|
605
|
+
type: 'message',
|
|
606
|
+
messageType: 'error',
|
|
607
|
+
content: `Error: Profile '${editedConfig.profile}' not found. Changes not saved.`,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
// Save the edited config (updates updatedAt timestamp)
|
|
611
|
+
await subagentManager.saveSubagent(editedConfig.name, editedConfig.profile, editedConfig.systemPrompt);
|
|
612
|
+
return {
|
|
613
|
+
type: 'message',
|
|
614
|
+
messageType: 'info',
|
|
615
|
+
content: `Subagent '${name}' updated successfully.`,
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
return {
|
|
620
|
+
type: 'message',
|
|
621
|
+
messageType: 'error',
|
|
622
|
+
content: error instanceof Error ? error.message : 'Failed to edit subagent',
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
finally {
|
|
626
|
+
// Cleanup temp file and directory (like text-buffer.ts)
|
|
627
|
+
try {
|
|
628
|
+
fs.unlinkSync(filePath);
|
|
629
|
+
}
|
|
630
|
+
catch {
|
|
631
|
+
/* ignore */
|
|
632
|
+
}
|
|
633
|
+
try {
|
|
634
|
+
fs.rmdirSync(tmpDir);
|
|
635
|
+
}
|
|
636
|
+
catch {
|
|
637
|
+
/* ignore */
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
},
|
|
641
|
+
};
|
|
642
|
+
/**
|
|
643
|
+
* /subagent parent command with schema-based completion
|
|
644
|
+
*
|
|
645
|
+
* @plan:PLAN-20251013-AUTOCOMPLETE.P08
|
|
646
|
+
* @requirement:REQ-002
|
|
647
|
+
* @requirement:REQ-003
|
|
648
|
+
* @requirement:REQ-004
|
|
649
|
+
* Legacy completion removed - now fully schema-driven
|
|
650
|
+
*/
|
|
651
|
+
export const subagentCommand = {
|
|
652
|
+
name: 'subagent',
|
|
653
|
+
description: 'Manage subagent configurations.',
|
|
654
|
+
kind: CommandKind.BUILT_IN,
|
|
655
|
+
subCommands: [
|
|
656
|
+
saveCommand,
|
|
657
|
+
listCommand,
|
|
658
|
+
showCommand,
|
|
659
|
+
deleteCommand,
|
|
660
|
+
editCommand,
|
|
661
|
+
],
|
|
662
|
+
action: async (_context, _args) => {
|
|
663
|
+
// No default action, list subcommands in a message.
|
|
664
|
+
const subCommandsList = subagentCommand.subCommands
|
|
665
|
+
?.map((cmd) => ` - ${cmd.name}: ${cmd.description}`)
|
|
666
|
+
.join('\n') || 'No subcommands available.';
|
|
667
|
+
return {
|
|
668
|
+
type: 'message',
|
|
669
|
+
messageType: 'info',
|
|
670
|
+
content: `Available subagent subcommands:\n${subCommandsList}`,
|
|
671
|
+
};
|
|
672
|
+
},
|
|
673
|
+
};
|
|
674
|
+
//# sourceMappingURL=subagentCommand.js.map
|