u-foo 2.2.4 → 2.3.1
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/SKILLS/ufoo/SKILL.md +56 -12
- package/SKILLS/uinit/SKILL.md +3 -2
- package/modules/AGENTS.template.md +2 -1
- package/modules/bus/README.md +1 -1
- package/modules/context/SKILLS/uctx/SKILL.md +6 -4
- package/package.json +1 -1
- package/src/agent/activityStatePublisher.js +6 -2
- package/src/agent/codexThreadProvider.js +2 -2
- package/src/agent/controllerToolExecutor.js +24 -1
- package/src/agent/credentials/claude.js +85 -16
- package/src/agent/credentials/codex.js +251 -23
- package/src/agent/defaultBootstrap.js +3 -1
- package/src/agent/directAuthStatus.js +264 -0
- package/src/agent/internalRunner.js +18 -12
- package/src/agent/loopObservability.js +10 -0
- package/src/agent/loopRuntime.js +19 -0
- package/src/agent/notifier.js +12 -3
- package/src/agent/ufooAgent.js +43 -13
- package/src/agent/upstreamTransport.js +23 -8
- package/src/bus/index.js +6 -1
- package/src/bus/message.js +156 -8
- package/src/chat/commandExecutor.js +187 -7
- package/src/chat/commands.js +23 -4
- package/src/chat/completionController.js +30 -7
- package/src/chat/index.js +3 -5
- package/src/cli/groupCoreCommands.js +5 -0
- package/src/cli.js +309 -0
- package/src/code/UCODE_PROMPT.md +3 -2
- package/src/code/prompts/ufoo.js +3 -2
- package/src/config.js +16 -3
- package/src/context/doctor.js +1 -1
- package/src/daemon/groupOrchestrator.js +13 -9
- package/src/daemon/promptRequest.js +11 -2
- package/src/daemon/soloBootstrap.js +2 -0
- package/src/group/bootstrap.js +1 -1
- package/src/group/promptProfiles.js +106 -22
- package/src/group/templates.js +1 -0
- package/src/init/index.js +4 -0
- package/src/memory/historySearch.js +308 -0
- package/src/memory/index.js +653 -8
- package/src/providerapi/redactor.js +4 -1
- package/src/status/index.js +24 -1
- package/src/tools/handlers/memory.js +168 -0
- package/src/tools/index.js +12 -0
- package/src/tools/registry.js +12 -0
- package/src/tools/schemaFixtures.js +213 -0
- package/src/tools/tier1/editMemory.js +14 -0
- package/src/tools/tier1/forget.js +14 -0
- package/src/tools/tier1/recall.js +14 -0
- package/src/tools/tier1/remember.js +14 -0
- package/src/tools/tier1/searchHistory.js +14 -0
- package/src/tools/tier1/searchMemory.js +14 -0
- package/templates/groups/build-lane.json +44 -6
- package/templates/groups/build-ultra.json +6 -5
- package/templates/groups/design-system.json +84 -0
- package/templates/groups/product-discovery.json +9 -4
- package/templates/groups/ui-plan-review.json +84 -0
- package/templates/groups/ui-polish.json +6 -2
- package/templates/groups/verify-ship.json +9 -4
|
@@ -16,6 +16,10 @@ const { parseIntervalMs, formatIntervalMs } = require("./cronScheduler");
|
|
|
16
16
|
const { isGlobalControllerProjectRoot, resolveGlobalControllerUfooDir } = require("../projects");
|
|
17
17
|
const { loadPromptProfileRegistry } = require("../group/promptProfiles");
|
|
18
18
|
const { resolveSoloAgentType } = require("../solo/commands");
|
|
19
|
+
const {
|
|
20
|
+
inspectDirectAuthStatus,
|
|
21
|
+
formatDirectAuthStatus,
|
|
22
|
+
} = require("../agent/directAuthStatus");
|
|
19
23
|
|
|
20
24
|
function defaultCreateDoctor(projectRoot) {
|
|
21
25
|
const UfooDoctor = require("../doctor");
|
|
@@ -39,6 +43,41 @@ function defaultResolveTerminalApp() {
|
|
|
39
43
|
return "";
|
|
40
44
|
}
|
|
41
45
|
|
|
46
|
+
const SETTINGS_MODEL_DEFAULTS = Object.freeze({
|
|
47
|
+
agent: Object.freeze({
|
|
48
|
+
codex: "gpt-5.5",
|
|
49
|
+
claude: "opus-4.7",
|
|
50
|
+
}),
|
|
51
|
+
router: Object.freeze({
|
|
52
|
+
codex: "gpt-5.4-mini",
|
|
53
|
+
claude: "sonnet-4.7",
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
function normalizeSettingsProvider(value = "", fallback = "codex-cli") {
|
|
58
|
+
const text = String(value || "").trim().toLowerCase();
|
|
59
|
+
if (text === "claude" || text === "claude-cli" || text === "claude-code" || text === "anthropic") {
|
|
60
|
+
return "claude-cli";
|
|
61
|
+
}
|
|
62
|
+
if (text === "codex" || text === "codex-cli" || text === "codex-code" || text === "openai") {
|
|
63
|
+
return "codex-cli";
|
|
64
|
+
}
|
|
65
|
+
return fallback;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function agentProviderKey(value = "") {
|
|
69
|
+
return normalizeSettingsProvider(value) === "claude-cli" ? "claude" : "codex";
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function defaultAgentModelForProvider(value = "") {
|
|
73
|
+
return SETTINGS_MODEL_DEFAULTS.agent[agentProviderKey(value)] || SETTINGS_MODEL_DEFAULTS.agent.codex;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function defaultGateModelForProvider(value = "") {
|
|
77
|
+
const key = agentProviderKey(value);
|
|
78
|
+
return SETTINGS_MODEL_DEFAULTS.router[key] || SETTINGS_MODEL_DEFAULTS.router.codex;
|
|
79
|
+
}
|
|
80
|
+
|
|
42
81
|
function collectHostLaunchRequestContext(env = process.env) {
|
|
43
82
|
const hostInjectSock = String(env.UFOO_HOST_INJECT_SOCK || env.HORIZON_INJECT_SOCK || "").trim();
|
|
44
83
|
const hostDaemonSock = String(env.UFOO_HOST_DAEMON_SOCK || "").trim();
|
|
@@ -102,6 +141,8 @@ function createCommandExecutor(options = {}) {
|
|
|
102
141
|
listCronTasks = () => [],
|
|
103
142
|
stopCronTask = () => false,
|
|
104
143
|
runGroupCore = runGroupCoreCommand,
|
|
144
|
+
inspectDirectAuth = inspectDirectAuthStatus,
|
|
145
|
+
formatDirectAuth = formatDirectAuthStatus,
|
|
105
146
|
requestCron = null,
|
|
106
147
|
globalMode = false,
|
|
107
148
|
listProjects = () => [],
|
|
@@ -164,6 +205,14 @@ function createCommandExecutor(options = {}) {
|
|
|
164
205
|
} else {
|
|
165
206
|
logMessage("system", "{white-fg}✗{/white-fg} Daemon is not running");
|
|
166
207
|
}
|
|
208
|
+
|
|
209
|
+
const authStatus = await inspectDirectAuth({
|
|
210
|
+
projectRoot: getActiveProjectRoot(),
|
|
211
|
+
autoRefresh: false,
|
|
212
|
+
});
|
|
213
|
+
for (const line of formatDirectAuth(authStatus, { compact: true })) {
|
|
214
|
+
logMessage("system", escapeBlessed(line));
|
|
215
|
+
}
|
|
167
216
|
}
|
|
168
217
|
|
|
169
218
|
async function handleDaemonCommand(args = []) {
|
|
@@ -1140,8 +1189,14 @@ function createCommandExecutor(options = {}) {
|
|
|
1140
1189
|
|
|
1141
1190
|
async function handleSettingsCommand(args = []) {
|
|
1142
1191
|
const section = String(args[0] || "").trim().toLowerCase();
|
|
1143
|
-
if (!section) {
|
|
1144
|
-
|
|
1192
|
+
if (!section || section === "show" || section === "status") {
|
|
1193
|
+
await handleSettingsOverviewCommand();
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
if (section === "agent" || section === "ufoo") {
|
|
1198
|
+
const subArgs = args.slice(1);
|
|
1199
|
+
await handleAgentSettingsCommand(subArgs);
|
|
1145
1200
|
return;
|
|
1146
1201
|
}
|
|
1147
1202
|
|
|
@@ -1161,7 +1216,116 @@ function createCommandExecutor(options = {}) {
|
|
|
1161
1216
|
return;
|
|
1162
1217
|
}
|
|
1163
1218
|
|
|
1164
|
-
logMessage("error", "{white-fg}✗{/white-fg} Unknown settings section. Use: router, ucode");
|
|
1219
|
+
logMessage("error", "{white-fg}✗{/white-fg} Unknown settings section. Use: show, agent, router, ucode");
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
async function handleSettingsOverviewCommand() {
|
|
1223
|
+
const config = loadConfig(projectRoot) || {};
|
|
1224
|
+
const agentProvider = normalizeSettingsProvider(config.agentProvider);
|
|
1225
|
+
const agentKey = agentProviderKey(agentProvider);
|
|
1226
|
+
const agentModel = String(config.agentModel || "").trim();
|
|
1227
|
+
const routerMode = normalizeControllerMode(config.controllerMode);
|
|
1228
|
+
const routerProvider = String(config.routerProvider || "").trim();
|
|
1229
|
+
const routerModel = String(config.routerModel || "").trim();
|
|
1230
|
+
const ucodeConfig = loadUcodeConfig() || {};
|
|
1231
|
+
const ucodeProvider = String(ucodeConfig.ucodeProvider || "").trim();
|
|
1232
|
+
const ucodeModel = String(ucodeConfig.ucodeModel || "").trim();
|
|
1233
|
+
|
|
1234
|
+
logMessage("system", "{cyan-fg}settings:{/cyan-fg}");
|
|
1235
|
+
logMessage("system", ` • agent: ${agentKey} · model ${agentModel || `(unset, recommended ${defaultAgentModelForProvider(agentProvider)})`}`);
|
|
1236
|
+
logMessage("system", ` • router: mode ${routerMode} · provider ${routerProvider || "(unset)"} · model ${routerModel || "(unset)"}`);
|
|
1237
|
+
logMessage("system", ` • ucode: provider ${ucodeProvider || "(unset)"} · model ${ucodeModel || "(unset)"}`);
|
|
1238
|
+
logMessage("system", " • use: /settings agent | /settings router | /settings ucode");
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
async function handleAgentSettingsCommand(args = []) {
|
|
1242
|
+
const first = String(args[0] || "").trim().toLowerCase();
|
|
1243
|
+
const hasInlineKv = args.some((item) => String(item || "").includes("="));
|
|
1244
|
+
const action = !first ? "show" : (hasInlineKv ? "set" : first);
|
|
1245
|
+
|
|
1246
|
+
if (action === "show" || action === "status") {
|
|
1247
|
+
const config = loadConfig(projectRoot) || {};
|
|
1248
|
+
const provider = normalizeSettingsProvider(config.agentProvider);
|
|
1249
|
+
const key = agentProviderKey(provider);
|
|
1250
|
+
const model = String(config.agentModel || "").trim();
|
|
1251
|
+
logMessage("system", "{cyan-fg}ufoo-agent config:{/cyan-fg}");
|
|
1252
|
+
logMessage("system", ` • provider: ${key}`);
|
|
1253
|
+
logMessage("system", ` • model: ${model || `(unset, recommended ${defaultAgentModelForProvider(provider)})`}`);
|
|
1254
|
+
logMessage("system", ` • defaults: codex=${SETTINGS_MODEL_DEFAULTS.agent.codex}, claude=${SETTINGS_MODEL_DEFAULTS.agent.claude}`);
|
|
1255
|
+
logMessage("system", " • use: /settings agent set provider=<codex|claude> model=<id>");
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
if (action === "codex" || action === "claude") {
|
|
1260
|
+
const kv = parseKeyValueArgs(args.slice(1));
|
|
1261
|
+
const provider = action === "claude" ? "claude-cli" : "codex-cli";
|
|
1262
|
+
const model = String(kv.model || defaultAgentModelForProvider(provider)).trim();
|
|
1263
|
+
saveConfig(projectRoot, {
|
|
1264
|
+
agentProvider: provider,
|
|
1265
|
+
agentModel: model,
|
|
1266
|
+
});
|
|
1267
|
+
logMessage("system", "{white-fg}✓{/white-fg} ufoo-agent config updated");
|
|
1268
|
+
logMessage("system", ` • provider: ${agentProviderKey(provider)}`);
|
|
1269
|
+
logMessage("system", ` • model: ${model}`);
|
|
1270
|
+
await restartDaemon(projectRoot);
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
if (action === "set") {
|
|
1275
|
+
const kvArgs = hasInlineKv ? args : args.slice(1);
|
|
1276
|
+
const kv = parseKeyValueArgs(kvArgs);
|
|
1277
|
+
const updates = {};
|
|
1278
|
+
let nextProvider = "";
|
|
1279
|
+
|
|
1280
|
+
if (Object.prototype.hasOwnProperty.call(kv, "provider")) {
|
|
1281
|
+
nextProvider = normalizeSettingsProvider(kv.provider, "");
|
|
1282
|
+
if (!nextProvider) {
|
|
1283
|
+
logMessage("error", "{white-fg}✗{/white-fg} Usage: /settings agent set provider=<codex|claude> model=<id>");
|
|
1284
|
+
return;
|
|
1285
|
+
}
|
|
1286
|
+
updates.agentProvider = nextProvider;
|
|
1287
|
+
}
|
|
1288
|
+
if (Object.prototype.hasOwnProperty.call(kv, "model")) {
|
|
1289
|
+
updates.agentModel = String(kv.model || "").trim();
|
|
1290
|
+
} else if (nextProvider) {
|
|
1291
|
+
updates.agentModel = defaultAgentModelForProvider(nextProvider);
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
if (Object.keys(updates).length === 0) {
|
|
1295
|
+
logMessage("error", "{white-fg}✗{/white-fg} Usage: /settings agent set provider=<codex|claude> model=<id>");
|
|
1296
|
+
return;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
saveConfig(projectRoot, updates);
|
|
1300
|
+
logMessage("system", "{white-fg}✓{/white-fg} ufoo-agent config updated");
|
|
1301
|
+
if (Object.prototype.hasOwnProperty.call(updates, "agentProvider")) {
|
|
1302
|
+
logMessage("system", ` • provider: ${agentProviderKey(updates.agentProvider)}`);
|
|
1303
|
+
}
|
|
1304
|
+
if (Object.prototype.hasOwnProperty.call(updates, "agentModel")) {
|
|
1305
|
+
logMessage("system", ` • model: ${updates.agentModel || "(unset)"}`);
|
|
1306
|
+
}
|
|
1307
|
+
await restartDaemon(projectRoot);
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
if (action === "clear") {
|
|
1312
|
+
const fieldsRaw = args.slice(1).map((item) => String(item || "").trim().toLowerCase()).filter(Boolean);
|
|
1313
|
+
const fields = fieldsRaw.length === 0 ? ["model"] : fieldsRaw;
|
|
1314
|
+
const updates = {};
|
|
1315
|
+
const clearAll = fields.includes("all");
|
|
1316
|
+
if (clearAll || fields.includes("provider")) updates.agentProvider = "codex-cli";
|
|
1317
|
+
if (clearAll || fields.includes("model")) updates.agentModel = "";
|
|
1318
|
+
if (Object.keys(updates).length === 0) {
|
|
1319
|
+
logMessage("error", "{white-fg}✗{/white-fg} Usage: /settings agent clear [provider|model|all]");
|
|
1320
|
+
return;
|
|
1321
|
+
}
|
|
1322
|
+
saveConfig(projectRoot, updates);
|
|
1323
|
+
logMessage("system", "{white-fg}✓{/white-fg} ufoo-agent config cleared");
|
|
1324
|
+
await restartDaemon(projectRoot);
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
logMessage("error", "{white-fg}✗{/white-fg} Unknown settings agent action. Use: show, set, clear, codex, claude");
|
|
1165
1329
|
}
|
|
1166
1330
|
|
|
1167
1331
|
async function handleRouterSettingsCommand(args = []) {
|
|
@@ -1172,11 +1336,27 @@ function createCommandExecutor(options = {}) {
|
|
|
1172
1336
|
if (action === "show" || action === "status") {
|
|
1173
1337
|
const config = loadConfig(projectRoot) || {};
|
|
1174
1338
|
const mode = normalizeControllerMode(config.controllerMode);
|
|
1175
|
-
logMessage("system", "{cyan-fg}router config:{/cyan-fg}");
|
|
1339
|
+
logMessage("system", "{cyan-fg}gate router config:{/cyan-fg}");
|
|
1176
1340
|
logMessage("system", ` • controllerMode: ${mode}`);
|
|
1177
1341
|
logMessage("system", ` • provider: ${String(config.routerProvider || "").trim() || "(unset)"}`);
|
|
1178
1342
|
logMessage("system", ` • model: ${String(config.routerModel || "").trim() || "(unset)"}`);
|
|
1179
1343
|
logMessage("system", " • allowed modes: main | loop | legacy | shadow");
|
|
1344
|
+
logMessage("system", ` • defaults: codex=${SETTINGS_MODEL_DEFAULTS.router.codex}, claude=${SETTINGS_MODEL_DEFAULTS.router.claude}`);
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
if (action === "codex" || action === "claude") {
|
|
1349
|
+
const kv = parseKeyValueArgs(args.slice(1));
|
|
1350
|
+
const provider = action;
|
|
1351
|
+
const model = String(kv.model || defaultGateModelForProvider(provider)).trim();
|
|
1352
|
+
saveConfig(projectRoot, {
|
|
1353
|
+
routerProvider: provider,
|
|
1354
|
+
routerModel: model,
|
|
1355
|
+
});
|
|
1356
|
+
logMessage("system", "{white-fg}✓{/white-fg} gate router config updated");
|
|
1357
|
+
logMessage("system", ` • provider: ${provider}`);
|
|
1358
|
+
logMessage("system", ` • model: ${model}`);
|
|
1359
|
+
await restartDaemon(projectRoot);
|
|
1180
1360
|
return;
|
|
1181
1361
|
}
|
|
1182
1362
|
|
|
@@ -1202,7 +1382,7 @@ function createCommandExecutor(options = {}) {
|
|
|
1202
1382
|
}
|
|
1203
1383
|
|
|
1204
1384
|
saveConfig(projectRoot, updates);
|
|
1205
|
-
logMessage("system", "{white-fg}✓{/white-fg} router config updated");
|
|
1385
|
+
logMessage("system", "{white-fg}✓{/white-fg} gate router config updated");
|
|
1206
1386
|
if (Object.prototype.hasOwnProperty.call(updates, "controllerMode")) {
|
|
1207
1387
|
logMessage("system", ` • controllerMode: ${updates.controllerMode}`);
|
|
1208
1388
|
}
|
|
@@ -1229,7 +1409,7 @@ function createCommandExecutor(options = {}) {
|
|
|
1229
1409
|
return;
|
|
1230
1410
|
}
|
|
1231
1411
|
saveConfig(projectRoot, updates);
|
|
1232
|
-
logMessage("system", "{white-fg}✓{/white-fg} router config cleared");
|
|
1412
|
+
logMessage("system", "{white-fg}✓{/white-fg} gate router config cleared");
|
|
1233
1413
|
await restartDaemon(projectRoot);
|
|
1234
1414
|
return;
|
|
1235
1415
|
}
|
|
@@ -1241,7 +1421,7 @@ function createCommandExecutor(options = {}) {
|
|
|
1241
1421
|
}
|
|
1242
1422
|
|
|
1243
1423
|
saveConfig(projectRoot, { controllerMode: nextMode });
|
|
1244
|
-
logMessage("system", `{white-fg}✓{/white-fg} router mode set to ${nextMode}`);
|
|
1424
|
+
logMessage("system", `{white-fg}✓{/white-fg} gate router mode set to ${nextMode}`);
|
|
1245
1425
|
await restartDaemon(projectRoot);
|
|
1246
1426
|
}
|
|
1247
1427
|
|
package/src/chat/commands.js
CHANGED
|
@@ -87,20 +87,39 @@ const COMMAND_TREE = {
|
|
|
87
87
|
"/settings": {
|
|
88
88
|
desc: "Settings operations",
|
|
89
89
|
children: {
|
|
90
|
+
show: {
|
|
91
|
+
desc: "Show settings overview",
|
|
92
|
+
order: 1,
|
|
93
|
+
},
|
|
94
|
+
agent: {
|
|
95
|
+
desc: "Manage main ufoo-agent/router provider/model",
|
|
96
|
+
order: 2,
|
|
97
|
+
children: {
|
|
98
|
+
show: { desc: "Show main agent provider/model", order: 1 },
|
|
99
|
+
set: { desc: "Set provider=<codex|claude> model=<id>", order: 2 },
|
|
100
|
+
clear: { desc: "Clear agent model or reset provider", order: 3 },
|
|
101
|
+
codex: { desc: "Use Codex default model (gpt-5.5)", order: 4 },
|
|
102
|
+
claude: { desc: "Use Claude default model (opus-4.7)", order: 5 },
|
|
103
|
+
},
|
|
104
|
+
},
|
|
90
105
|
router: {
|
|
91
|
-
desc: "Manage
|
|
106
|
+
desc: "Manage gate router mode/provider/model",
|
|
107
|
+
order: 3,
|
|
92
108
|
children: {
|
|
93
|
-
show: { desc: "Show router mode/provider/model", order: 1 },
|
|
94
|
-
set: { desc: "Set
|
|
95
|
-
clear: { desc: "Clear router provider/model or reset mode", order: 3 },
|
|
109
|
+
show: { desc: "Show gate router mode/provider/model", order: 1 },
|
|
110
|
+
set: { desc: "Set mode/provider/model", order: 2 },
|
|
111
|
+
clear: { desc: "Clear gate router provider/model or reset mode", order: 3 },
|
|
96
112
|
main: { desc: "Set router mode to main", order: 4 },
|
|
97
113
|
loop: { desc: "Set router mode to loop", order: 5 },
|
|
98
114
|
legacy: { desc: "Set router mode to legacy", order: 6 },
|
|
99
115
|
shadow: { desc: "Set router mode to shadow", order: 7 },
|
|
116
|
+
codex: { desc: "Use Codex gate model (gpt-5.4-mini)", order: 8 },
|
|
117
|
+
claude: { desc: "Use Claude gate model (sonnet-4.7)", order: 9 },
|
|
100
118
|
},
|
|
101
119
|
},
|
|
102
120
|
ucode: {
|
|
103
121
|
desc: "Manage ucode model provider config",
|
|
122
|
+
order: 4,
|
|
104
123
|
children: {
|
|
105
124
|
show: { desc: "Show ucode provider/model/url/key", order: 1 },
|
|
106
125
|
set: { desc: "Set ucode provider/model/url/key", order: 2 },
|
|
@@ -24,6 +24,34 @@ function mapSubcommandSuggestions(subs = [], parentCmd, tokenIndex, filterText =
|
|
|
24
24
|
.sort(sortSubcommandEntries);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function buildNestedSubcommandSuggestions(subs = [], mainCmd, parts = [], endsWithSpace = false) {
|
|
28
|
+
let currentSubs = Array.isArray(subs) ? subs : [];
|
|
29
|
+
if (currentSubs.length === 0) return [];
|
|
30
|
+
|
|
31
|
+
for (let index = 1; index < parts.length; index += 1) {
|
|
32
|
+
const token = String(parts[index] || "");
|
|
33
|
+
const exact = currentSubs.find((sub) =>
|
|
34
|
+
String(sub && sub.cmd ? sub.cmd : "").toLowerCase() === token.toLowerCase()
|
|
35
|
+
);
|
|
36
|
+
const isLastToken = index === parts.length - 1;
|
|
37
|
+
|
|
38
|
+
if (exact && Array.isArray(exact.subcommands) && exact.subcommands.length > 0) {
|
|
39
|
+
if (!isLastToken || endsWithSpace) {
|
|
40
|
+
currentSubs = exact.subcommands;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (exact && isLastToken && endsWithSpace) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return mapSubcommandSuggestions(currentSubs, mainCmd, index, token);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return mapSubcommandSuggestions(currentSubs, mainCmd, parts.length, "");
|
|
53
|
+
}
|
|
54
|
+
|
|
27
55
|
function createCompletionController(options = {}) {
|
|
28
56
|
const {
|
|
29
57
|
input,
|
|
@@ -230,14 +258,9 @@ function createCompletionController(options = {}) {
|
|
|
230
258
|
subs = Array.from(merged.values());
|
|
231
259
|
}
|
|
232
260
|
if (isLaunch) {
|
|
233
|
-
return mapSubcommandSuggestions(subs, mainCmd, 1,
|
|
234
|
-
}
|
|
235
|
-
const selectedSub = subs.find((sub) => String(sub && sub.cmd ? sub.cmd : "").toLowerCase() === subFilter.toLowerCase());
|
|
236
|
-
if (selectedSub && selectedSub.subcommands && (parts.length > 2 || endsWithSpace)) {
|
|
237
|
-
const nestedFilter = parts[2] || "";
|
|
238
|
-
return mapSubcommandSuggestions(selectedSub.subcommands, mainCmd, 2, nestedFilter);
|
|
261
|
+
return mapSubcommandSuggestions(subs, mainCmd, 1, subFilter);
|
|
239
262
|
}
|
|
240
|
-
return
|
|
263
|
+
return buildNestedSubcommandSuggestions(subs, mainCmd, parts, endsWithSpace);
|
|
241
264
|
}
|
|
242
265
|
return [];
|
|
243
266
|
}
|
package/src/chat/index.js
CHANGED
|
@@ -563,6 +563,7 @@ async function runChat(projectRoot, options = {}) {
|
|
|
563
563
|
return registry.templates.map((item) => ({
|
|
564
564
|
alias: item.alias,
|
|
565
565
|
name: item.templateName || item.templateId || "",
|
|
566
|
+
desc: item.templateDescription || "",
|
|
566
567
|
source: item.source || "",
|
|
567
568
|
}));
|
|
568
569
|
},
|
|
@@ -2103,12 +2104,9 @@ async function runChat(projectRoot, options = {}) {
|
|
|
2103
2104
|
if (runtimeWatchDebounce) return;
|
|
2104
2105
|
runtimeWatchDebounce = setTimeout(() => {
|
|
2105
2106
|
runtimeWatchDebounce = null;
|
|
2106
|
-
const prevCount = projectRuntimes.length;
|
|
2107
2107
|
refreshProjectRuntimes();
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
screen.render();
|
|
2111
|
-
}
|
|
2108
|
+
renderDashboard();
|
|
2109
|
+
screen.render();
|
|
2112
2110
|
}, 300);
|
|
2113
2111
|
});
|
|
2114
2112
|
screen.on("destroy", () => watcher.close());
|
|
@@ -80,6 +80,9 @@ function printList({ templates, errors }, { write, json, cwd }) {
|
|
|
80
80
|
const displayPath = formatDisplayPath(item.filePath, cwd);
|
|
81
81
|
write(`- ${item.alias} [${item.source}]`);
|
|
82
82
|
write(` name: ${nameLabel}`);
|
|
83
|
+
if (item.templateDescription) {
|
|
84
|
+
write(` desc: ${item.templateDescription}`);
|
|
85
|
+
}
|
|
83
86
|
write(` id: ${idLabel} schema: ${verLabel}`);
|
|
84
87
|
write(` file: ${displayPath}`);
|
|
85
88
|
}
|
|
@@ -170,6 +173,7 @@ async function runGroupCoreCommand(subcmd, cmdArgs = [], options = {}) {
|
|
|
170
173
|
filePath: item.filePath,
|
|
171
174
|
templateId: item.templateId || "",
|
|
172
175
|
templateName: item.templateName || "",
|
|
176
|
+
templateDescription: item.templateDescription || "",
|
|
173
177
|
schemaVersion: item.schemaVersion,
|
|
174
178
|
}));
|
|
175
179
|
printList({ templates, errors: registry.errors }, { write, json, cwd });
|
|
@@ -190,6 +194,7 @@ async function runGroupCoreCommand(subcmd, cmdArgs = [], options = {}) {
|
|
|
190
194
|
filePath: item.filePath,
|
|
191
195
|
templateId: item.templateId || "",
|
|
192
196
|
templateName: item.templateName || "",
|
|
197
|
+
templateDescription: item.templateDescription || "",
|
|
193
198
|
schemaVersion: item.schemaVersion,
|
|
194
199
|
}));
|
|
195
200
|
printList({ templates, errors: registry.errors }, { write, json, cwd });
|