@dexto/tui 1.10.4 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-backend.cjs +1 -1
- package/dist/agent-backend.d.ts +2 -2
- package/dist/agent-backend.d.ts.map +1 -1
- package/dist/agent-backend.js +1 -1
- package/dist/agent-backend.test.cjs +7 -10
- package/dist/agent-backend.test.js +7 -10
- package/dist/index.d.cts +2 -2
- package/dist/interactive-commands/commands.test.cjs +22 -24
- package/dist/interactive-commands/commands.test.js +22 -24
- package/dist/interactive-commands/skill-commands.cjs +14 -19
- package/dist/interactive-commands/skill-commands.d.ts +1 -1
- package/dist/interactive-commands/skill-commands.d.ts.map +1 -1
- package/dist/interactive-commands/skill-commands.js +14 -19
- package/package.json +5 -5
package/dist/agent-backend.cjs
CHANGED
|
@@ -67,7 +67,7 @@ function getTuiCapabilities(agent) {
|
|
|
67
67
|
};
|
|
68
68
|
return {
|
|
69
69
|
...mergedCapabilities,
|
|
70
|
-
skills: mergedCapabilities.skills === false ? false : Boolean(agent.
|
|
70
|
+
skills: mergedCapabilities.skills === false ? false : Boolean(agent.skills),
|
|
71
71
|
...agent.capabilities?.supportedCommands ? {
|
|
72
72
|
supportedCommands: agent.capabilities.supportedCommands.map(normalizeCommandName)
|
|
73
73
|
} : {}
|
package/dist/agent-backend.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentEventMap, DextoAgent, EventArgs, EventListener, SessionMetadata,
|
|
1
|
+
import type { AgentEventMap, DextoAgent, EventArgs, EventListener, SessionMetadata, Skills } from '@dexto/core';
|
|
2
2
|
import type { CommandDefinition } from './interactive-commands/command-parser.js';
|
|
3
3
|
export interface TuiAgentCapabilities {
|
|
4
4
|
supportedCommands?: readonly string[];
|
|
@@ -68,7 +68,7 @@ export interface TuiAgentBackend extends Pick<DextoAgent, 'stream' | 'stop' | 'r
|
|
|
68
68
|
getHookNames: () => string[];
|
|
69
69
|
};
|
|
70
70
|
};
|
|
71
|
-
|
|
71
|
+
skills?: Skills | undefined;
|
|
72
72
|
capabilities?: TuiAgentCapabilities;
|
|
73
73
|
}
|
|
74
74
|
export declare function getTuiCapabilities(agent: TuiAgentBackend): TuiAgentCapabilities;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-backend.d.ts","sourceRoot":"","sources":["../src/agent-backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,aAAa,EACb,UAAU,EACV,SAAS,EACT,aAAa,EACb,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"agent-backend.d.ts","sourceRoot":"","sources":["../src/agent-backend.ts"],"names":[],"mappings":"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"}
|
package/dist/agent-backend.js
CHANGED
|
@@ -35,7 +35,7 @@ function getTuiCapabilities(agent) {
|
|
|
35
35
|
};
|
|
36
36
|
return {
|
|
37
37
|
...mergedCapabilities,
|
|
38
|
-
skills: mergedCapabilities.skills === false ? false : Boolean(agent.
|
|
38
|
+
skills: mergedCapabilities.skills === false ? false : Boolean(agent.skills),
|
|
39
39
|
...agent.capabilities?.supportedCommands ? {
|
|
40
40
|
supportedCommands: agent.capabilities.supportedCommands.map(normalizeCommandName)
|
|
41
41
|
} : {}
|
|
@@ -4,14 +4,11 @@ var import_agent_backend = require("./agent-backend.js");
|
|
|
4
4
|
function createAgent(capabilities, options = {}) {
|
|
5
5
|
return {
|
|
6
6
|
capabilities,
|
|
7
|
-
...options.
|
|
8
|
-
|
|
7
|
+
...options.hasSkills ? {
|
|
8
|
+
skills: {
|
|
9
9
|
list: async () => [],
|
|
10
|
-
|
|
11
|
-
readFile: async () => null
|
|
12
|
-
invoke: async () => null,
|
|
13
|
-
refresh: async () => {
|
|
14
|
-
}
|
|
10
|
+
load: async () => null,
|
|
11
|
+
readFile: async () => null
|
|
15
12
|
}
|
|
16
13
|
} : {}
|
|
17
14
|
};
|
|
@@ -38,8 +35,8 @@ function createAgent(capabilities, options = {}) {
|
|
|
38
35
|
(0, import_vitest.expect)((0, import_agent_backend.isCommandSupported)(agent, "help", { name: "help", aliases: ["h"] })).toBe(true);
|
|
39
36
|
});
|
|
40
37
|
(0, import_vitest.it)("gates skill commands separately from prompt commands", () => {
|
|
41
|
-
const promptlessAgent = createAgent({ prompts: false }, {
|
|
42
|
-
const skilllessAgent = createAgent({ skills: false }, {
|
|
38
|
+
const promptlessAgent = createAgent({ prompts: false }, { hasSkills: true });
|
|
39
|
+
const skilllessAgent = createAgent({ skills: false }, { hasSkills: true });
|
|
43
40
|
(0, import_vitest.expect)((0, import_agent_backend.isCommandSupported)(promptlessAgent, "skills", { name: "skills", aliases: [] })).toBe(
|
|
44
41
|
true
|
|
45
42
|
);
|
|
@@ -47,7 +44,7 @@ function createAgent(capabilities, options = {}) {
|
|
|
47
44
|
false
|
|
48
45
|
);
|
|
49
46
|
});
|
|
50
|
-
(0, import_vitest.it)("requires a real
|
|
47
|
+
(0, import_vitest.it)("requires a real Skills implementation for skill commands", () => {
|
|
51
48
|
const agent = createAgent();
|
|
52
49
|
(0, import_vitest.expect)((0, import_agent_backend.isCommandSupported)(agent, "skills", { name: "skills", aliases: [] })).toBe(false);
|
|
53
50
|
});
|
|
@@ -5,14 +5,11 @@ import {
|
|
|
5
5
|
function createAgent(capabilities, options = {}) {
|
|
6
6
|
return {
|
|
7
7
|
capabilities,
|
|
8
|
-
...options.
|
|
9
|
-
|
|
8
|
+
...options.hasSkills ? {
|
|
9
|
+
skills: {
|
|
10
10
|
list: async () => [],
|
|
11
|
-
|
|
12
|
-
readFile: async () => null
|
|
13
|
-
invoke: async () => null,
|
|
14
|
-
refresh: async () => {
|
|
15
|
-
}
|
|
11
|
+
load: async () => null,
|
|
12
|
+
readFile: async () => null
|
|
16
13
|
}
|
|
17
14
|
} : {}
|
|
18
15
|
};
|
|
@@ -39,8 +36,8 @@ describe("isCommandSupported", () => {
|
|
|
39
36
|
expect(isCommandSupported(agent, "help", { name: "help", aliases: ["h"] })).toBe(true);
|
|
40
37
|
});
|
|
41
38
|
it("gates skill commands separately from prompt commands", () => {
|
|
42
|
-
const promptlessAgent = createAgent({ prompts: false }, {
|
|
43
|
-
const skilllessAgent = createAgent({ skills: false }, {
|
|
39
|
+
const promptlessAgent = createAgent({ prompts: false }, { hasSkills: true });
|
|
40
|
+
const skilllessAgent = createAgent({ skills: false }, { hasSkills: true });
|
|
44
41
|
expect(isCommandSupported(promptlessAgent, "skills", { name: "skills", aliases: [] })).toBe(
|
|
45
42
|
true
|
|
46
43
|
);
|
|
@@ -48,7 +45,7 @@ describe("isCommandSupported", () => {
|
|
|
48
45
|
false
|
|
49
46
|
);
|
|
50
47
|
});
|
|
51
|
-
it("requires a real
|
|
48
|
+
it("requires a real Skills implementation for skill commands", () => {
|
|
52
49
|
const agent = createAgent();
|
|
53
50
|
expect(isCommandSupported(agent, "skills", { name: "skills", aliases: [] })).toBe(false);
|
|
54
51
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { DextoAgent, AgentEventMap, EventListener, EventArgs, SessionMetadata,
|
|
2
|
+
import { DextoAgent, AgentEventMap, EventListener, EventArgs, SessionMetadata, Skills } from '@dexto/core';
|
|
3
3
|
import { LLMProvider } from '@dexto/llm';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -262,7 +262,7 @@ interface TuiAgentBackend extends Pick<DextoAgent, 'stream' | 'stop' | 'run' | '
|
|
|
262
262
|
getHookNames: () => string[];
|
|
263
263
|
};
|
|
264
264
|
};
|
|
265
|
-
|
|
265
|
+
skills?: Skills | undefined;
|
|
266
266
|
capabilities?: TuiAgentCapabilities;
|
|
267
267
|
}
|
|
268
268
|
declare function getTuiCapabilities(agent: TuiAgentBackend): TuiAgentCapabilities;
|
|
@@ -2,17 +2,15 @@
|
|
|
2
2
|
var import_vitest = require("vitest");
|
|
3
3
|
var import_commands = require("./commands.js");
|
|
4
4
|
function createAgent(capabilities) {
|
|
5
|
-
const
|
|
5
|
+
const skills = {
|
|
6
6
|
list: import_vitest.vi.fn().mockResolvedValue([]),
|
|
7
|
-
|
|
8
|
-
readFile: import_vitest.vi.fn()
|
|
9
|
-
invoke: import_vitest.vi.fn(),
|
|
10
|
-
refresh: import_vitest.vi.fn()
|
|
7
|
+
load: import_vitest.vi.fn().mockResolvedValue(null),
|
|
8
|
+
readFile: import_vitest.vi.fn()
|
|
11
9
|
};
|
|
12
10
|
return {
|
|
13
11
|
capabilities,
|
|
14
12
|
listPrompts: import_vitest.vi.fn(),
|
|
15
|
-
|
|
13
|
+
skills,
|
|
16
14
|
logger: {
|
|
17
15
|
debug: import_vitest.vi.fn(),
|
|
18
16
|
info: import_vitest.vi.fn(),
|
|
@@ -34,37 +32,37 @@ function createAgent(capabilities) {
|
|
|
34
32
|
const result = await (0, import_commands.executeCommand)("prompts", [], agent);
|
|
35
33
|
(0, import_vitest.expect)(result).toBe("\u26A0\uFE0F Command /prompts is not available for this chat target.");
|
|
36
34
|
});
|
|
37
|
-
(0, import_vitest.it)("lists skills through
|
|
35
|
+
(0, import_vitest.it)("lists skills through Skills when prompt commands are disabled", async () => {
|
|
38
36
|
const agent = createAgent({ prompts: false });
|
|
39
|
-
const
|
|
40
|
-
if (!
|
|
41
|
-
import_vitest.vi.mocked(
|
|
37
|
+
const skills = agent.skills;
|
|
38
|
+
if (!skills) throw new Error("Expected test agent to have skills");
|
|
39
|
+
import_vitest.vi.mocked(skills.list).mockResolvedValue([
|
|
42
40
|
{
|
|
43
|
-
|
|
44
|
-
displayName: "Code Review",
|
|
41
|
+
name: "review",
|
|
45
42
|
description: "Review code changes"
|
|
46
43
|
}
|
|
47
44
|
]);
|
|
48
45
|
const result = await (0, import_commands.executeCommand)("skills", [], agent);
|
|
49
|
-
(0, import_vitest.expect)(
|
|
46
|
+
(0, import_vitest.expect)(skills.list).toHaveBeenCalled();
|
|
50
47
|
(0, import_vitest.expect)(agent.listPrompts).not.toHaveBeenCalled();
|
|
51
48
|
(0, import_vitest.expect)(result).toContain("Available Skills");
|
|
52
|
-
(0, import_vitest.expect)(result).toContain("
|
|
49
|
+
(0, import_vitest.expect)(result).toContain("review");
|
|
53
50
|
});
|
|
54
|
-
(0, import_vitest.it)("
|
|
51
|
+
(0, import_vitest.it)("loads one skill through Skills", async () => {
|
|
55
52
|
const agent = createAgent();
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
58
|
-
import_vitest.vi.mocked(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
const skills = agent.skills;
|
|
54
|
+
if (!skills) throw new Error("Expected test agent to have skills");
|
|
55
|
+
import_vitest.vi.mocked(skills.load).mockResolvedValue({
|
|
56
|
+
name: "review",
|
|
57
|
+
instructions: "Check tests and edge cases.",
|
|
58
|
+
supportingFiles: [],
|
|
59
|
+
filesLocation: "hosted",
|
|
60
|
+
baseDirectory: null
|
|
63
61
|
});
|
|
64
62
|
const result = await (0, import_commands.executeCommand)("skills", ["review"], agent);
|
|
65
|
-
(0, import_vitest.expect)(
|
|
63
|
+
(0, import_vitest.expect)(skills.load).toHaveBeenCalledWith("review");
|
|
66
64
|
(0, import_vitest.expect)(agent.listPrompts).not.toHaveBeenCalled();
|
|
67
|
-
(0, import_vitest.expect)(result).toContain("
|
|
65
|
+
(0, import_vitest.expect)(result).toContain("review");
|
|
68
66
|
(0, import_vitest.expect)(result).toContain("Check tests and edge cases.");
|
|
69
67
|
});
|
|
70
68
|
});
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { executeCommand } from "./commands.js";
|
|
3
3
|
function createAgent(capabilities) {
|
|
4
|
-
const
|
|
4
|
+
const skills = {
|
|
5
5
|
list: vi.fn().mockResolvedValue([]),
|
|
6
|
-
|
|
7
|
-
readFile: vi.fn()
|
|
8
|
-
invoke: vi.fn(),
|
|
9
|
-
refresh: vi.fn()
|
|
6
|
+
load: vi.fn().mockResolvedValue(null),
|
|
7
|
+
readFile: vi.fn()
|
|
10
8
|
};
|
|
11
9
|
return {
|
|
12
10
|
capabilities,
|
|
13
11
|
listPrompts: vi.fn(),
|
|
14
|
-
|
|
12
|
+
skills,
|
|
15
13
|
logger: {
|
|
16
14
|
debug: vi.fn(),
|
|
17
15
|
info: vi.fn(),
|
|
@@ -33,37 +31,37 @@ describe("executeCommand", () => {
|
|
|
33
31
|
const result = await executeCommand("prompts", [], agent);
|
|
34
32
|
expect(result).toBe("\u26A0\uFE0F Command /prompts is not available for this chat target.");
|
|
35
33
|
});
|
|
36
|
-
it("lists skills through
|
|
34
|
+
it("lists skills through Skills when prompt commands are disabled", async () => {
|
|
37
35
|
const agent = createAgent({ prompts: false });
|
|
38
|
-
const
|
|
39
|
-
if (!
|
|
40
|
-
vi.mocked(
|
|
36
|
+
const skills = agent.skills;
|
|
37
|
+
if (!skills) throw new Error("Expected test agent to have skills");
|
|
38
|
+
vi.mocked(skills.list).mockResolvedValue([
|
|
41
39
|
{
|
|
42
|
-
|
|
43
|
-
displayName: "Code Review",
|
|
40
|
+
name: "review",
|
|
44
41
|
description: "Review code changes"
|
|
45
42
|
}
|
|
46
43
|
]);
|
|
47
44
|
const result = await executeCommand("skills", [], agent);
|
|
48
|
-
expect(
|
|
45
|
+
expect(skills.list).toHaveBeenCalled();
|
|
49
46
|
expect(agent.listPrompts).not.toHaveBeenCalled();
|
|
50
47
|
expect(result).toContain("Available Skills");
|
|
51
|
-
expect(result).toContain("
|
|
48
|
+
expect(result).toContain("review");
|
|
52
49
|
});
|
|
53
|
-
it("
|
|
50
|
+
it("loads one skill through Skills", async () => {
|
|
54
51
|
const agent = createAgent();
|
|
55
|
-
const
|
|
56
|
-
if (!
|
|
57
|
-
vi.mocked(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
const skills = agent.skills;
|
|
53
|
+
if (!skills) throw new Error("Expected test agent to have skills");
|
|
54
|
+
vi.mocked(skills.load).mockResolvedValue({
|
|
55
|
+
name: "review",
|
|
56
|
+
instructions: "Check tests and edge cases.",
|
|
57
|
+
supportingFiles: [],
|
|
58
|
+
filesLocation: "hosted",
|
|
59
|
+
baseDirectory: null
|
|
62
60
|
});
|
|
63
61
|
const result = await executeCommand("skills", ["review"], agent);
|
|
64
|
-
expect(
|
|
62
|
+
expect(skills.load).toHaveBeenCalledWith("review");
|
|
65
63
|
expect(agent.listPrompts).not.toHaveBeenCalled();
|
|
66
|
-
expect(result).toContain("
|
|
64
|
+
expect(result).toContain("review");
|
|
67
65
|
expect(result).toContain("Check tests and edge cases.");
|
|
68
66
|
});
|
|
69
67
|
});
|
|
@@ -25,39 +25,34 @@ var import_format_output = require("./utils/format-output.js");
|
|
|
25
25
|
const skillCommands = [
|
|
26
26
|
{
|
|
27
27
|
name: "skills",
|
|
28
|
-
description: "List available skills, or read one skill by
|
|
29
|
-
usage: "/skills [skill-
|
|
28
|
+
description: "List available skills, or read one skill by exact name",
|
|
29
|
+
usage: "/skills [skill-name]",
|
|
30
30
|
category: "Skill Management",
|
|
31
31
|
handler: async (args, agent, _ctx) => {
|
|
32
|
-
const
|
|
33
|
-
if (!
|
|
32
|
+
const skills = agent.skills;
|
|
33
|
+
if (!skills) {
|
|
34
34
|
return (0, import_format_output.formatForInkCli)("\u26A0\uFE0F Skills are not available for this chat target.");
|
|
35
35
|
}
|
|
36
|
-
const
|
|
36
|
+
const skillName = args[0];
|
|
37
37
|
try {
|
|
38
|
-
if (
|
|
39
|
-
const skill = await
|
|
38
|
+
if (skillName) {
|
|
39
|
+
const skill = await skills.load(skillName);
|
|
40
40
|
if (!skill) {
|
|
41
|
-
return (0, import_format_output.formatForInkCli)(`\u26A0\uFE0F Skill '${
|
|
41
|
+
return (0, import_format_output.formatForInkCli)(`\u26A0\uFE0F Skill '${skillName}' not found`);
|
|
42
42
|
}
|
|
43
43
|
const outputLines2 = [`
|
|
44
|
-
\u{1F9E9} ${skill.
|
|
45
|
-
if (skill.description) {
|
|
46
|
-
outputLines2.push(`Description: ${skill.description}`);
|
|
47
|
-
}
|
|
48
|
-
outputLines2.push("", skill.instructions);
|
|
44
|
+
\u{1F9E9} ${skill.name}`, "", skill.instructions];
|
|
49
45
|
return (0, import_format_output.formatForInkCli)(outputLines2.join("\n"));
|
|
50
46
|
}
|
|
51
|
-
const
|
|
52
|
-
if (
|
|
47
|
+
const summaries = await skills.list();
|
|
48
|
+
if (summaries.length === 0) {
|
|
53
49
|
return (0, import_format_output.formatForInkCli)("\n\u26A0\uFE0F No skills available");
|
|
54
50
|
}
|
|
55
51
|
const outputLines = ["\n\u{1F9E9} Available Skills:\n"];
|
|
56
|
-
for (const skill of
|
|
57
|
-
|
|
58
|
-
outputLines.push(` ${skill.displayName} (${skill.id})${desc}`);
|
|
52
|
+
for (const skill of summaries) {
|
|
53
|
+
outputLines.push(` ${skill.name} - ${skill.description}`);
|
|
59
54
|
}
|
|
60
|
-
outputLines.push("", `Total: ${
|
|
55
|
+
outputLines.push("", `Total: ${summaries.length} skills`);
|
|
61
56
|
return (0, import_format_output.formatForInkCli)(outputLines.join("\n"));
|
|
62
57
|
} catch (error) {
|
|
63
58
|
const errorMsg = `Error loading skills: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Skill Commands Module
|
|
3
3
|
*
|
|
4
|
-
* Skills are first-class agent capabilities backed by
|
|
4
|
+
* Skills are first-class agent capabilities backed by the Core Skills contract. They are
|
|
5
5
|
* listed/read separately from slash prompt commands.
|
|
6
6
|
*/
|
|
7
7
|
import type { CommandDefinition } from './command-parser.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-commands.d.ts","sourceRoot":"","sources":["../../src/interactive-commands/skill-commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAkB,iBAAiB,EAAwB,MAAM,qBAAqB,CAAC;AAInG,eAAO,MAAM,aAAa,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"skill-commands.d.ts","sourceRoot":"","sources":["../../src/interactive-commands/skill-commands.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAkB,iBAAiB,EAAwB,MAAM,qBAAqB,CAAC;AAInG,eAAO,MAAM,aAAa,EAAE,iBAAiB,EA+C5C,CAAC"}
|
|
@@ -2,39 +2,34 @@ import { formatForInkCli } from "./utils/format-output.js";
|
|
|
2
2
|
const skillCommands = [
|
|
3
3
|
{
|
|
4
4
|
name: "skills",
|
|
5
|
-
description: "List available skills, or read one skill by
|
|
6
|
-
usage: "/skills [skill-
|
|
5
|
+
description: "List available skills, or read one skill by exact name",
|
|
6
|
+
usage: "/skills [skill-name]",
|
|
7
7
|
category: "Skill Management",
|
|
8
8
|
handler: async (args, agent, _ctx) => {
|
|
9
|
-
const
|
|
10
|
-
if (!
|
|
9
|
+
const skills = agent.skills;
|
|
10
|
+
if (!skills) {
|
|
11
11
|
return formatForInkCli("\u26A0\uFE0F Skills are not available for this chat target.");
|
|
12
12
|
}
|
|
13
|
-
const
|
|
13
|
+
const skillName = args[0];
|
|
14
14
|
try {
|
|
15
|
-
if (
|
|
16
|
-
const skill = await
|
|
15
|
+
if (skillName) {
|
|
16
|
+
const skill = await skills.load(skillName);
|
|
17
17
|
if (!skill) {
|
|
18
|
-
return formatForInkCli(`\u26A0\uFE0F Skill '${
|
|
18
|
+
return formatForInkCli(`\u26A0\uFE0F Skill '${skillName}' not found`);
|
|
19
19
|
}
|
|
20
20
|
const outputLines2 = [`
|
|
21
|
-
\u{1F9E9} ${skill.
|
|
22
|
-
if (skill.description) {
|
|
23
|
-
outputLines2.push(`Description: ${skill.description}`);
|
|
24
|
-
}
|
|
25
|
-
outputLines2.push("", skill.instructions);
|
|
21
|
+
\u{1F9E9} ${skill.name}`, "", skill.instructions];
|
|
26
22
|
return formatForInkCli(outputLines2.join("\n"));
|
|
27
23
|
}
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
24
|
+
const summaries = await skills.list();
|
|
25
|
+
if (summaries.length === 0) {
|
|
30
26
|
return formatForInkCli("\n\u26A0\uFE0F No skills available");
|
|
31
27
|
}
|
|
32
28
|
const outputLines = ["\n\u{1F9E9} Available Skills:\n"];
|
|
33
|
-
for (const skill of
|
|
34
|
-
|
|
35
|
-
outputLines.push(` ${skill.displayName} (${skill.id})${desc}`);
|
|
29
|
+
for (const skill of summaries) {
|
|
30
|
+
outputLines.push(` ${skill.name} - ${skill.description}`);
|
|
36
31
|
}
|
|
37
|
-
outputLines.push("", `Total: ${
|
|
32
|
+
outputLines.push("", `Total: ${summaries.length} skills`);
|
|
38
33
|
return formatForInkCli(outputLines.join("\n"));
|
|
39
34
|
} catch (error) {
|
|
40
35
|
const errorMsg = `Error loading skills: ${error instanceof Error ? error.message : String(error)}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexto/tui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Interactive terminal UI for Dexto CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"string-width": "^8.1.0",
|
|
29
29
|
"strip-ansi": "^7.1.2",
|
|
30
30
|
"wrap-ansi": "^9.0.2",
|
|
31
|
-
"@dexto/agent-management": "1.
|
|
32
|
-
"@dexto/core": "1.
|
|
33
|
-
"@dexto/
|
|
34
|
-
"@dexto/
|
|
31
|
+
"@dexto/agent-management": "1.11.0",
|
|
32
|
+
"@dexto/core": "1.11.0",
|
|
33
|
+
"@dexto/registry": "1.11.0",
|
|
34
|
+
"@dexto/llm": "1.11.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/react": "^19.0.0",
|