@axhub/genie 0.2.10 → 0.2.12
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/api-docs.html +2 -2
- package/dist/assets/App-Clb2COtW.js +274 -0
- package/dist/assets/ImagePlaygroundPage-DqhMSbM8.js +106 -0
- package/dist/assets/ImagePlaygroundPage-MEn3NN80.css +1 -0
- package/dist/assets/ReviewApp-CDcLYe-u.js +1 -0
- package/dist/assets/{_basePickBy-DVVb07UV.js → _basePickBy-jUZsM51q.js} +1 -1
- package/dist/assets/{_baseUniq-BtbziL5G.js → _baseUniq-BXglE6_v.js} +1 -1
- package/dist/assets/{arc-BsCC8yBD.js → arc-D-oFCFBv.js} +1 -1
- package/dist/assets/{architectureDiagram-2XIMDMQ5-woFp6eNI.js → architectureDiagram-2XIMDMQ5-DC8bAnQt.js} +1 -1
- package/dist/assets/{blockDiagram-WCTKOSBZ-ya8VAc2k.js → blockDiagram-WCTKOSBZ-C4semIRc.js} +1 -1
- package/dist/assets/{c4Diagram-IC4MRINW-CY1dZmIZ.js → c4Diagram-IC4MRINW-FHj1QO3y.js} +1 -1
- package/dist/assets/channel-BF4woPXX.js +1 -0
- package/dist/assets/{chunk-4BX2VUAB-CR1lAd74.js → chunk-4BX2VUAB-D-LjsQ_s.js} +1 -1
- package/dist/assets/{chunk-55IACEB6-CP98WcFC.js → chunk-55IACEB6-DI3j_d7A.js} +1 -1
- package/dist/assets/{chunk-FMBD7UC4-D9c7ijAB.js → chunk-FMBD7UC4-BEVnaLFN.js} +1 -1
- package/dist/assets/{chunk-JSJVCQXG-DQAGYOn-.js → chunk-JSJVCQXG-CSxpcErk.js} +1 -1
- package/dist/assets/{chunk-KX2RTZJC-BbTXiDq7.js → chunk-KX2RTZJC-BbuhDN4h.js} +1 -1
- package/dist/assets/{chunk-NQ4KR5QH-BI6AX0dr.js → chunk-NQ4KR5QH-C3x61XQa.js} +1 -1
- package/dist/assets/{chunk-QZHKN3VN-DB3V2Ifo.js → chunk-QZHKN3VN-DxWOFtPh.js} +1 -1
- package/dist/assets/{chunk-WL4C6EOR-DhzTthv6.js → chunk-WL4C6EOR-Bt2OauD2.js} +1 -1
- package/dist/assets/classDiagram-VBA2DB6C-D2kHlnQ7.js +1 -0
- package/dist/assets/classDiagram-v2-RAHNMMFH-D2kHlnQ7.js +1 -0
- package/dist/assets/clone-CqBvwCJW.js +1 -0
- package/dist/assets/{cose-bilkent-S5V4N54A-BQ09ZE2j.js → cose-bilkent-S5V4N54A-Dexadrue.js} +1 -1
- package/dist/assets/{dagre-KLK3FWXG-Dc2ueD_R.js → dagre-KLK3FWXG-F9U4X2xC.js} +1 -1
- package/dist/assets/{diagram-E7M64L7V-DP-LsQoL.js → diagram-E7M64L7V-B3V17aH3.js} +1 -1
- package/dist/assets/{diagram-IFDJBPK2-Cg6r42cB.js → diagram-IFDJBPK2-CdHAmLL1.js} +1 -1
- package/dist/assets/{diagram-P4PSJMXO-aHsfoUZE.js → diagram-P4PSJMXO-CrTNfk8K.js} +1 -1
- package/dist/assets/{erDiagram-INFDFZHY-qBXJ4aAz.js → erDiagram-INFDFZHY-vDh9SWK9.js} +1 -1
- package/dist/assets/{flowDiagram-PKNHOUZH-D_13emJM.js → flowDiagram-PKNHOUZH-DpltMg7L.js} +1 -1
- package/dist/assets/{ganttDiagram-A5KZAMGK-BvIcOLwz.js → ganttDiagram-A5KZAMGK-COTk2xur.js} +1 -1
- package/dist/assets/{gitGraphDiagram-K3NZZRJ6-ad0vvNcU.js → gitGraphDiagram-K3NZZRJ6-BNV7bvvj.js} +1 -1
- package/dist/assets/{graph-CeJCMjan.js → graph-Dkeg9oys.js} +1 -1
- package/dist/assets/{highlighted-body-TPN3WLV5-B_novwSz.js → highlighted-body-TPN3WLV5-DaiQEBwR.js} +1 -1
- package/dist/assets/index-DgGmiqsP.css +1 -0
- package/dist/assets/index-DvA901Vs.js +2 -0
- package/dist/assets/{infoDiagram-LFFYTUFH-lOxAqb3m.js → infoDiagram-LFFYTUFH-CZioW3Gt.js} +1 -1
- package/dist/assets/{ishikawaDiagram-PHBUUO56-DIr-51gj.js → ishikawaDiagram-PHBUUO56-BbqR3i1B.js} +1 -1
- package/dist/assets/{journeyDiagram-4ABVD52K-CYcIW0ZU.js → journeyDiagram-4ABVD52K-wfb-WHzl.js} +1 -1
- package/dist/assets/{kanban-definition-K7BYSVSG-C1ZK616a.js → kanban-definition-K7BYSVSG-B3c4y3VN.js} +1 -1
- package/dist/assets/{layout-CI2RM-v6.js → layout-Xr9Z2VGF.js} +1 -1
- package/dist/assets/{linear-DE7bISck.js → linear-JBmzAJtl.js} +1 -1
- package/dist/assets/{mermaid-O7DHMXV3-XxAJo8EK.js → mermaid-O7DHMXV3-fDuyNLKe.js} +238 -220
- package/dist/assets/{mindmap-definition-YRQLILUH-Dz6EFjmn.js → mindmap-definition-YRQLILUH-B5NTN_jD.js} +1 -1
- package/dist/assets/{pieDiagram-SKSYHLDU-DPpEzUed.js → pieDiagram-SKSYHLDU-CuO98GVu.js} +1 -1
- package/dist/assets/{quadrantDiagram-337W2JSQ-xdoXNet7.js → quadrantDiagram-337W2JSQ-LL3f4vLf.js} +1 -1
- package/dist/assets/{requirementDiagram-Z7DCOOCP-DUq8H3CL.js → requirementDiagram-Z7DCOOCP-Di-2O6LH.js} +1 -1
- package/dist/assets/{sankeyDiagram-WA2Y5GQK-CmqEUxRu.js → sankeyDiagram-WA2Y5GQK-9lHqrXqR.js} +1 -1
- package/dist/assets/{sequenceDiagram-2WXFIKYE-DhtXRNiH.js → sequenceDiagram-2WXFIKYE-BQu-SoGr.js} +1 -1
- package/dist/assets/{stateDiagram-RAJIS63D-Dj0HOlbN.js → stateDiagram-RAJIS63D-BUxvd2BC.js} +1 -1
- package/dist/assets/stateDiagram-v2-FVOUBMTO-CDVexTiR.js +1 -0
- package/dist/assets/{timeline-definition-YZTLITO2-DUuJzZB5.js → timeline-definition-YZTLITO2-oP47UEU6.js} +1 -1
- package/dist/assets/{treemap-KZPCXAKY-DpYBQ0qr.js → treemap-KZPCXAKY-BRjDo2aE.js} +1 -1
- package/dist/assets/{vendor-codemirror-CMHSJ_9p.js → vendor-codemirror-BiCeS-y4.js} +1 -1
- package/dist/assets/{vendor-react-xmA_f8ig.js → vendor-react-DVlYPmi3.js} +1 -1
- package/dist/assets/{vennDiagram-LZ73GAT5-DpePUyOd.js → vennDiagram-LZ73GAT5-DrRqcDqo.js} +1 -1
- package/dist/assets/{xychartDiagram-JWTSCODW-Cfp1I4_U.js → xychartDiagram-JWTSCODW-DUXrymAi.js} +1 -1
- package/dist/index.html +4 -4
- package/package.json +25 -6
- package/scripts/refresh-acp-default-capabilities.mjs +160 -0
- package/server/acp-runtime/client.js +1137 -181
- package/server/acp-runtime/command-overrides.js +48 -0
- package/server/acp-runtime/index.js +576 -16
- package/server/acp-runtime/registry.js +6 -4
- package/server/acp-runtime/session-store.js +235 -92
- package/server/database/db.js +12 -3
- package/server/external-agent/ws.js +212 -11
- package/server/index.js +156 -53
- package/server/projects-watcher-config.js +4 -0
- package/server/projects.js +485 -125
- package/server/routes/cc-connect.js +5 -4
- package/server/routes/codex.js +24 -0
- package/server/routes/commands.js +166 -10
- package/server/routes/runs.js +641 -0
- package/server/routes/session-core.js +357 -109
- package/server/session-core/eventStore.js +0 -121
- package/server/session-core/providerAdapters.js +644 -163
- package/server/session-core/providerDiscovery.js +66 -38
- package/server/session-core/runRegistry.js +244 -0
- package/server/session-core/runtimeState.js +75 -3
- package/server/session-core/runtimeWriter.js +132 -10
- package/server/utils/codexImagePlayground.js +479 -0
- package/server/utils/localTerminal.js +56 -0
- package/server/utils/shellCommand.js +70 -0
- package/shared/acpCapabilities.js +393 -0
- package/shared/acpDefaultCapabilities.generated.json +141 -0
- package/shared/conversationEvents.js +425 -121
- package/dist/assets/App-CYCCsgwf.js +0 -264
- package/dist/assets/ReviewApp-0srHIXwb.js +0 -1
- package/dist/assets/channel-BMhScXFe.js +0 -1
- package/dist/assets/classDiagram-VBA2DB6C-CMIxlWcT.js +0 -1
- package/dist/assets/classDiagram-v2-RAHNMMFH-CMIxlWcT.js +0 -1
- package/dist/assets/clone-BPqOt4r3.js +0 -1
- package/dist/assets/index-C514cLyb.js +0 -2
- package/dist/assets/index-h1DBl_g3.css +0 -1
- package/dist/assets/stateDiagram-v2-FVOUBMTO-C9utf5gv.js +0 -1
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
const router = express.Router();
|
|
28
28
|
|
|
29
29
|
const CC_CONNECT_COMMAND = 'cc-connect';
|
|
30
|
+
const CC_CONNECT_NPM_PACKAGE = 'cc-connect@latest';
|
|
30
31
|
const COMMAND_TIMEOUT_MS = 5000;
|
|
31
32
|
const INSTALL_TIMEOUT_MS = 120000;
|
|
32
33
|
const DAEMON_COMMAND_TIMEOUT_MS = 20000;
|
|
@@ -772,17 +773,17 @@ router.get('/platforms', async (req, res) => {
|
|
|
772
773
|
router.post('/install', async (req, res) => {
|
|
773
774
|
try {
|
|
774
775
|
const existing = await getCcConnectStatus();
|
|
775
|
-
if (existing.installed && existing.isBeta) {
|
|
776
|
+
if (existing.installed && !existing.isBeta) {
|
|
776
777
|
return res.json({
|
|
777
778
|
success: true,
|
|
778
779
|
version: existing.version,
|
|
779
|
-
message: 'cc-connect
|
|
780
|
+
message: 'cc-connect is already installed.'
|
|
780
781
|
});
|
|
781
782
|
}
|
|
782
783
|
|
|
783
784
|
const result = runCommandSync({
|
|
784
785
|
command: getNpmCommand(),
|
|
785
|
-
args: ['install', '-g',
|
|
786
|
+
args: ['install', '-g', CC_CONNECT_NPM_PACKAGE],
|
|
786
787
|
timeoutMs: INSTALL_TIMEOUT_MS,
|
|
787
788
|
env: buildCommandEnv()
|
|
788
789
|
});
|
|
@@ -798,7 +799,7 @@ router.post('/install', async (req, res) => {
|
|
|
798
799
|
return res.json({
|
|
799
800
|
success: true,
|
|
800
801
|
version: installed.version,
|
|
801
|
-
message: 'cc-connect
|
|
802
|
+
message: 'cc-connect installed successfully.'
|
|
802
803
|
});
|
|
803
804
|
} catch (error) {
|
|
804
805
|
return res.status(500).json({ success: false, error: error.message });
|
package/server/routes/codex.js
CHANGED
|
@@ -8,6 +8,10 @@ import {
|
|
|
8
8
|
getCodexSessionMessages,
|
|
9
9
|
getCodexSessions
|
|
10
10
|
} from '../projects.js';
|
|
11
|
+
import {
|
|
12
|
+
buildCodexImagePlaygroundLaunch,
|
|
13
|
+
resolveCodexImagePlaygroundConfig
|
|
14
|
+
} from '../utils/codexImagePlayground.js';
|
|
11
15
|
|
|
12
16
|
const router = express.Router();
|
|
13
17
|
const CODEX_CONFIG_PATH = path.join(os.homedir(), '.codex', 'config.toml');
|
|
@@ -66,6 +70,26 @@ router.get('/config', async (_req, res) => {
|
|
|
66
70
|
}
|
|
67
71
|
});
|
|
68
72
|
|
|
73
|
+
router.get('/image-playground/launch', async (req, res) => {
|
|
74
|
+
try {
|
|
75
|
+
const projectPath = typeof req.query.projectPath === 'string' && req.query.projectPath.trim()
|
|
76
|
+
? req.query.projectPath.trim()
|
|
77
|
+
: null;
|
|
78
|
+
const config = await resolveCodexImagePlaygroundConfig({ projectPath });
|
|
79
|
+
const routePath = typeof req.query.routePath === 'string' && req.query.routePath.trim()
|
|
80
|
+
? req.query.routePath.trim()
|
|
81
|
+
: '/image-playground';
|
|
82
|
+
|
|
83
|
+
res.json({
|
|
84
|
+
success: true,
|
|
85
|
+
launch: buildCodexImagePlaygroundLaunch({ routePath, config })
|
|
86
|
+
});
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error('Error building Codex image playground launch:', error);
|
|
89
|
+
res.status(500).json({ success: false, error: error.message });
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
69
93
|
router.get('/sessions', async (req, res) => {
|
|
70
94
|
const projectPath = String(req.query.projectPath || '').trim();
|
|
71
95
|
|
|
@@ -4,6 +4,7 @@ import os from 'os';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import matter from 'gray-matter';
|
|
7
|
+
import { spawnCommand } from '../utils/spawnCommand.js';
|
|
7
8
|
import {
|
|
8
9
|
CLAUDE_MODELS,
|
|
9
10
|
CODEX_MODELS,
|
|
@@ -17,15 +18,16 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
17
18
|
const __dirname = path.dirname(__filename);
|
|
18
19
|
const PACKAGE_JSON_PATH = path.join(__dirname, '..', '..', 'package.json');
|
|
19
20
|
|
|
20
|
-
const BUILTIN_COMMANDS = [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
const BUILTIN_COMMANDS = [];
|
|
22
|
+
const DISABLED_BUILTIN_COMMANDS = new Set([
|
|
23
|
+
'/help',
|
|
24
|
+
'/clear',
|
|
25
|
+
'/model',
|
|
26
|
+
'/memory',
|
|
27
|
+
'/config',
|
|
28
|
+
'/status',
|
|
29
|
+
'/rewind',
|
|
30
|
+
]);
|
|
29
31
|
|
|
30
32
|
const FALLBACK_PROVIDER_MODELS = {
|
|
31
33
|
claude: CLAUDE_MODELS.OPTIONS.map((option) => option.value),
|
|
@@ -34,6 +36,15 @@ const FALLBACK_PROVIDER_MODELS = {
|
|
|
34
36
|
opencode: OPENCODE_MODELS.OPTIONS.map((option) => option.value)
|
|
35
37
|
};
|
|
36
38
|
|
|
39
|
+
const SKILLS_LIST_TIMEOUT_MS = 5000;
|
|
40
|
+
const PROVIDER_AGENT_NAMES = {
|
|
41
|
+
claude: 'Claude Code',
|
|
42
|
+
codex: 'Codex',
|
|
43
|
+
openai: 'Codex',
|
|
44
|
+
gemini: 'Gemini',
|
|
45
|
+
opencode: 'OpenCode'
|
|
46
|
+
};
|
|
47
|
+
|
|
37
48
|
function trimText(value) {
|
|
38
49
|
return typeof value === 'string' ? value.trim() : '';
|
|
39
50
|
}
|
|
@@ -79,6 +90,136 @@ function inferDescription(frontmatter, markdownBody) {
|
|
|
79
90
|
return firstMeaningfulLine.replace(/^#+\s*/, '').trim() || 'Custom slash command';
|
|
80
91
|
}
|
|
81
92
|
|
|
93
|
+
function providerAgentName(provider) {
|
|
94
|
+
return PROVIDER_AGENT_NAMES[trimText(provider).toLowerCase()] || '';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function normalizeSlashName(value) {
|
|
98
|
+
const normalized = trimText(value);
|
|
99
|
+
if (!normalized) return '';
|
|
100
|
+
return normalized.startsWith('/') ? normalized : `/${normalized}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function inferSkillDescription(skillPath) {
|
|
104
|
+
const normalizedPath = trimText(skillPath);
|
|
105
|
+
if (!normalizedPath) {
|
|
106
|
+
return 'Project skill';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
const rawDocument = await fs.readFile(path.join(normalizedPath, 'SKILL.md'), 'utf8');
|
|
111
|
+
const parsedDocument = matter(rawDocument);
|
|
112
|
+
const explicit = trimText(parsedDocument.data?.description);
|
|
113
|
+
if (explicit) {
|
|
114
|
+
return explicit;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const firstMeaningfulLine = parsedDocument.content
|
|
118
|
+
.split('\n')
|
|
119
|
+
.map((line) => line.trim())
|
|
120
|
+
.find((line) => line && !line.startsWith('---'));
|
|
121
|
+
|
|
122
|
+
return firstMeaningfulLine?.replace(/^#+\s*/, '').trim() || 'Project skill';
|
|
123
|
+
} catch {
|
|
124
|
+
return 'Project skill';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function parseSkillsListOutput(stdout) {
|
|
129
|
+
if (!trimText(stdout)) {
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const parsed = JSON.parse(stdout);
|
|
134
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function runProjectSkillsList(projectPath) {
|
|
138
|
+
return new Promise((resolve) => {
|
|
139
|
+
const command = process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
140
|
+
let stdout = '';
|
|
141
|
+
let stderr = '';
|
|
142
|
+
let settled = false;
|
|
143
|
+
const child = spawnCommand(command, ['skills', 'ls', '--json'], {
|
|
144
|
+
cwd: projectPath,
|
|
145
|
+
env: {
|
|
146
|
+
...process.env,
|
|
147
|
+
DISABLE_TELEMETRY: process.env.DISABLE_TELEMETRY ?? '1'
|
|
148
|
+
},
|
|
149
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const finish = (value) => {
|
|
153
|
+
if (settled) return;
|
|
154
|
+
settled = true;
|
|
155
|
+
clearTimeout(timer);
|
|
156
|
+
resolve(value);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const timer = setTimeout(() => {
|
|
160
|
+
child.kill?.();
|
|
161
|
+
finish([]);
|
|
162
|
+
}, SKILLS_LIST_TIMEOUT_MS);
|
|
163
|
+
|
|
164
|
+
child.stdout?.setEncoding?.('utf8');
|
|
165
|
+
child.stderr?.setEncoding?.('utf8');
|
|
166
|
+
child.stdout?.on('data', (chunk) => {
|
|
167
|
+
stdout += chunk;
|
|
168
|
+
});
|
|
169
|
+
child.stderr?.on('data', (chunk) => {
|
|
170
|
+
stderr += chunk;
|
|
171
|
+
});
|
|
172
|
+
child.on('error', () => finish([]));
|
|
173
|
+
child.on('close', (code) => {
|
|
174
|
+
if (code !== 0) {
|
|
175
|
+
finish([]);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
finish(parseSkillsListOutput(stdout));
|
|
181
|
+
} catch {
|
|
182
|
+
finish([]);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
async function listProjectSkills(projectPath, provider) {
|
|
189
|
+
const normalizedProjectPath = trimText(projectPath);
|
|
190
|
+
const targetAgent = providerAgentName(provider);
|
|
191
|
+
if (!normalizedProjectPath || !targetAgent) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const rawSkills = await runProjectSkillsList(normalizedProjectPath);
|
|
196
|
+
const normalizedSkills = [];
|
|
197
|
+
|
|
198
|
+
for (const skill of rawSkills) {
|
|
199
|
+
if (!skill || typeof skill !== 'object') continue;
|
|
200
|
+
|
|
201
|
+
const name = normalizeSlashName(skill.name);
|
|
202
|
+
const agents = Array.isArray(skill.agents)
|
|
203
|
+
? skill.agents.map((agent) => trimText(agent)).filter(Boolean)
|
|
204
|
+
: [];
|
|
205
|
+
if (!name || !agents.includes(targetAgent)) continue;
|
|
206
|
+
|
|
207
|
+
const skillPath = trimText(skill.path);
|
|
208
|
+
normalizedSkills.push({
|
|
209
|
+
name,
|
|
210
|
+
path: skillPath,
|
|
211
|
+
scope: trimText(skill.scope) || 'project',
|
|
212
|
+
agents,
|
|
213
|
+
namespace: 'skill',
|
|
214
|
+
type: 'skill',
|
|
215
|
+
source: 'skill',
|
|
216
|
+
description: await inferSkillDescription(skillPath)
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return normalizedSkills.sort((left, right) => left.name.localeCompare(right.name));
|
|
221
|
+
}
|
|
222
|
+
|
|
82
223
|
async function walkCommandTree(rootPath, namespace) {
|
|
83
224
|
const collected = [];
|
|
84
225
|
|
|
@@ -216,6 +357,10 @@ async function buildModelPayload(context) {
|
|
|
216
357
|
}
|
|
217
358
|
|
|
218
359
|
async function runBuiltinCommand(commandName, args, context) {
|
|
360
|
+
if (BUILTIN_COMMANDS.length === 0) {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
|
|
219
364
|
switch (commandName) {
|
|
220
365
|
case '/help':
|
|
221
366
|
return {
|
|
@@ -340,9 +485,11 @@ async function runBuiltinCommand(commandName, args, context) {
|
|
|
340
485
|
router.post('/list', async (req, res) => {
|
|
341
486
|
try {
|
|
342
487
|
const projectPath = trimText(req.body?.projectPath);
|
|
488
|
+
const provider = trimText(req.body?.provider);
|
|
343
489
|
const builtin = BUILTIN_COMMANDS.map(toBuiltinRecord);
|
|
344
490
|
const discoveredRoots = commandRootsFor(projectPath);
|
|
345
491
|
const custom = [];
|
|
492
|
+
const skills = await listProjectSkills(projectPath, provider);
|
|
346
493
|
|
|
347
494
|
for (const root of discoveredRoots) {
|
|
348
495
|
custom.push(...await walkCommandTree(root.rootPath, root.namespace));
|
|
@@ -350,8 +497,9 @@ router.post('/list', async (req, res) => {
|
|
|
350
497
|
|
|
351
498
|
res.json({
|
|
352
499
|
builtIn: builtin,
|
|
500
|
+
skills,
|
|
353
501
|
custom,
|
|
354
|
-
count: builtin.length + custom.length
|
|
502
|
+
count: builtin.length + skills.length + custom.length
|
|
355
503
|
});
|
|
356
504
|
} catch (error) {
|
|
357
505
|
console.error('Error listing commands:', error);
|
|
@@ -402,6 +550,14 @@ router.post('/execute', async (req, res) => {
|
|
|
402
550
|
});
|
|
403
551
|
}
|
|
404
552
|
|
|
553
|
+
if (DISABLED_BUILTIN_COMMANDS.has(commandName)) {
|
|
554
|
+
return res.status(404).json({
|
|
555
|
+
error: 'Command not found',
|
|
556
|
+
message: `${commandName} is currently disabled`,
|
|
557
|
+
command: commandName
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
|
|
405
561
|
try {
|
|
406
562
|
const builtinResult = await runBuiltinCommand(commandName, args, context);
|
|
407
563
|
if (builtinResult) {
|