u-foo 2.2.4 → 2.3.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.
Files changed (57) hide show
  1. package/SKILLS/ufoo/SKILL.md +56 -12
  2. package/SKILLS/uinit/SKILL.md +3 -2
  3. package/modules/AGENTS.template.md +2 -1
  4. package/modules/bus/README.md +1 -1
  5. package/modules/context/SKILLS/uctx/SKILL.md +6 -4
  6. package/package.json +1 -1
  7. package/src/agent/codexThreadProvider.js +2 -2
  8. package/src/agent/controllerToolExecutor.js +24 -1
  9. package/src/agent/credentials/claude.js +85 -16
  10. package/src/agent/credentials/codex.js +251 -23
  11. package/src/agent/defaultBootstrap.js +3 -1
  12. package/src/agent/directAuthStatus.js +264 -0
  13. package/src/agent/internalRunner.js +18 -12
  14. package/src/agent/loopObservability.js +10 -0
  15. package/src/agent/loopRuntime.js +19 -0
  16. package/src/agent/ufooAgent.js +43 -13
  17. package/src/agent/upstreamTransport.js +23 -8
  18. package/src/bus/index.js +6 -1
  19. package/src/bus/message.js +156 -8
  20. package/src/chat/commandExecutor.js +187 -7
  21. package/src/chat/commands.js +23 -4
  22. package/src/chat/completionController.js +30 -7
  23. package/src/chat/index.js +3 -5
  24. package/src/cli/groupCoreCommands.js +5 -0
  25. package/src/cli.js +309 -0
  26. package/src/code/UCODE_PROMPT.md +3 -2
  27. package/src/code/prompts/ufoo.js +3 -2
  28. package/src/config.js +16 -3
  29. package/src/context/doctor.js +1 -1
  30. package/src/daemon/groupOrchestrator.js +13 -9
  31. package/src/daemon/promptRequest.js +11 -2
  32. package/src/daemon/soloBootstrap.js +2 -0
  33. package/src/group/bootstrap.js +1 -1
  34. package/src/group/promptProfiles.js +106 -22
  35. package/src/group/templates.js +1 -0
  36. package/src/init/index.js +4 -0
  37. package/src/memory/historySearch.js +308 -0
  38. package/src/memory/index.js +653 -8
  39. package/src/providerapi/redactor.js +4 -1
  40. package/src/status/index.js +24 -1
  41. package/src/tools/handlers/memory.js +168 -0
  42. package/src/tools/index.js +12 -0
  43. package/src/tools/registry.js +12 -0
  44. package/src/tools/schemaFixtures.js +213 -0
  45. package/src/tools/tier1/editMemory.js +14 -0
  46. package/src/tools/tier1/forget.js +14 -0
  47. package/src/tools/tier1/recall.js +14 -0
  48. package/src/tools/tier1/remember.js +14 -0
  49. package/src/tools/tier1/searchHistory.js +14 -0
  50. package/src/tools/tier1/searchMemory.js +14 -0
  51. package/templates/groups/build-lane.json +44 -6
  52. package/templates/groups/build-ultra.json +6 -5
  53. package/templates/groups/design-system.json +84 -0
  54. package/templates/groups/product-discovery.json +9 -4
  55. package/templates/groups/ui-plan-review.json +84 -0
  56. package/templates/groups/ui-polish.json +6 -2
  57. 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
- logMessage("error", "{white-fg}✗{/white-fg} Usage: /settings <router|ucode> ...");
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
 
@@ -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 controller routing mode/provider/model",
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 router mode/provider/model", order: 2 },
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 mapSubcommandSuggestions(subs, mainCmd, 1, subFilter);
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
- if (projectRuntimes.length !== prevCount) {
2109
- renderDashboard();
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 });