@wingman-ai/gateway 0.4.1 → 0.4.3
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/README.md +14 -0
- package/dist/agent/config/mcpClientManager.cjs +104 -1
- package/dist/agent/config/mcpClientManager.d.ts +30 -0
- package/dist/agent/config/mcpClientManager.js +104 -1
- package/dist/agent/config/modelFactory.cjs +10 -0
- package/dist/agent/config/modelFactory.js +10 -0
- package/dist/agent/config/xaiImageModel.cjs +242 -0
- package/dist/agent/config/xaiImageModel.d.ts +33 -0
- package/dist/agent/config/xaiImageModel.js +202 -0
- package/dist/agent/tests/mcpClientManager.test.cjs +116 -0
- package/dist/agent/tests/mcpClientManager.test.js +117 -1
- package/dist/agent/tests/mcpResourceTools.test.cjs +101 -0
- package/dist/agent/tests/mcpResourceTools.test.d.ts +1 -0
- package/dist/agent/tests/mcpResourceTools.test.js +95 -0
- package/dist/agent/tests/modelFactory.test.cjs +16 -2
- package/dist/agent/tests/modelFactory.test.js +16 -2
- package/dist/agent/tests/xaiImageModel.test.cjs +194 -0
- package/dist/agent/tests/xaiImageModel.test.d.ts +1 -0
- package/dist/agent/tests/xaiImageModel.test.js +188 -0
- package/dist/agent/tools/mcp_resources.cjs +111 -0
- package/dist/agent/tools/mcp_resources.d.ts +3 -0
- package/dist/agent/tools/mcp_resources.js +77 -0
- package/dist/bench/adapters/commandAdapter.cjs +93 -0
- package/dist/bench/adapters/commandAdapter.d.ts +6 -0
- package/dist/bench/adapters/commandAdapter.js +59 -0
- package/dist/bench/adapters/helpers.cjs +170 -0
- package/dist/bench/adapters/helpers.d.ts +7 -0
- package/dist/bench/adapters/helpers.js +133 -0
- package/dist/bench/adapters/index.cjs +41 -0
- package/dist/bench/adapters/index.d.ts +2 -0
- package/dist/bench/adapters/index.js +7 -0
- package/dist/bench/adapters/wingmanCliAdapter.cjs +100 -0
- package/dist/bench/adapters/wingmanCliAdapter.d.ts +6 -0
- package/dist/bench/adapters/wingmanCliAdapter.js +66 -0
- package/dist/bench/cleanup.cjs +122 -0
- package/dist/bench/cleanup.d.ts +9 -0
- package/dist/bench/cleanup.js +85 -0
- package/dist/bench/config.cjs +190 -0
- package/dist/bench/config.d.ts +2 -0
- package/dist/bench/config.js +156 -0
- package/dist/bench/index.cjs +43 -0
- package/dist/bench/index.d.ts +3 -0
- package/dist/bench/index.js +3 -0
- package/dist/bench/official.cjs +616 -0
- package/dist/bench/official.d.ts +80 -0
- package/dist/bench/official.js +546 -0
- package/dist/bench/officialCli.cjs +204 -0
- package/dist/bench/officialCli.d.ts +5 -0
- package/dist/bench/officialCli.js +170 -0
- package/dist/bench/process.cjs +78 -0
- package/dist/bench/process.d.ts +14 -0
- package/dist/bench/process.js +44 -0
- package/dist/bench/runner.cjs +237 -0
- package/dist/bench/runner.d.ts +7 -0
- package/dist/bench/runner.js +197 -0
- package/dist/bench/scoring.cjs +171 -0
- package/dist/bench/scoring.d.ts +9 -0
- package/dist/bench/scoring.js +137 -0
- package/dist/bench/types.cjs +18 -0
- package/dist/bench/types.d.ts +200 -0
- package/dist/bench/types.js +0 -0
- package/dist/bench/validator.cjs +92 -0
- package/dist/bench/validator.d.ts +2 -0
- package/dist/bench/validator.js +58 -0
- package/dist/cli/commands/init.cjs +135 -1
- package/dist/cli/commands/init.js +136 -2
- package/dist/cli/commands/skill.cjs +7 -3
- package/dist/cli/commands/skill.js +7 -3
- package/dist/cli/config/loader.cjs +7 -3
- package/dist/cli/config/loader.js +7 -3
- package/dist/cli/config/schema.cjs +63 -10
- package/dist/cli/config/schema.d.ts +64 -4
- package/dist/cli/config/schema.js +59 -9
- package/dist/cli/config/warnings.cjs +119 -51
- package/dist/cli/config/warnings.js +119 -51
- package/dist/cli/core/agentInvoker.cjs +58 -13
- package/dist/cli/core/agentInvoker.d.ts +1 -0
- package/dist/cli/core/agentInvoker.js +58 -13
- package/dist/cli/core/imagePersistence.cjs +17 -1
- package/dist/cli/core/imagePersistence.d.ts +2 -0
- package/dist/cli/core/imagePersistence.js +13 -3
- package/dist/cli/core/sessionManager.cjs +2 -0
- package/dist/cli/core/sessionManager.js +3 -1
- package/dist/cli/services/skillRepository.cjs +155 -69
- package/dist/cli/services/skillRepository.d.ts +7 -2
- package/dist/cli/services/skillRepository.js +155 -69
- package/dist/cli/services/skillService.cjs +93 -26
- package/dist/cli/services/skillService.d.ts +7 -0
- package/dist/cli/services/skillService.js +96 -29
- package/dist/cli/types/skill.d.ts +8 -3
- package/dist/cli/types.d.ts +18 -0
- package/dist/gateway/adapters/teams.cjs +419 -0
- package/dist/gateway/adapters/teams.d.ts +47 -0
- package/dist/gateway/adapters/teams.js +361 -0
- package/dist/gateway/http/sms.cjs +286 -0
- package/dist/gateway/http/sms.d.ts +4 -0
- package/dist/gateway/http/sms.js +249 -0
- package/dist/gateway/server.cjs +54 -3
- package/dist/gateway/server.d.ts +2 -0
- package/dist/gateway/server.js +54 -3
- package/dist/gateway/sms/commands.cjs +116 -0
- package/dist/gateway/sms/commands.d.ts +15 -0
- package/dist/gateway/sms/commands.js +79 -0
- package/dist/gateway/sms/control.cjs +118 -0
- package/dist/gateway/sms/control.d.ts +18 -0
- package/dist/gateway/sms/control.js +84 -0
- package/dist/gateway/sms/policyStore.cjs +198 -0
- package/dist/gateway/sms/policyStore.d.ts +37 -0
- package/dist/gateway/sms/policyStore.js +161 -0
- package/dist/providers/registry.cjs +1 -0
- package/dist/providers/registry.js +1 -0
- package/dist/skills/activation.cjs +92 -0
- package/dist/skills/activation.d.ts +12 -0
- package/dist/skills/activation.js +58 -0
- package/dist/skills/bin-requirements.cjs +63 -0
- package/dist/skills/bin-requirements.d.ts +3 -0
- package/dist/skills/bin-requirements.js +26 -0
- package/dist/skills/metadata.cjs +141 -0
- package/dist/skills/metadata.d.ts +29 -0
- package/dist/skills/metadata.js +104 -0
- package/dist/skills/overlay.cjs +75 -0
- package/dist/skills/overlay.d.ts +2 -0
- package/dist/skills/overlay.js +38 -0
- package/dist/tests/cli-config-loader.test.cjs +7 -3
- package/dist/tests/cli-config-loader.test.js +7 -3
- package/dist/tests/cli-config-warnings.test.cjs +41 -0
- package/dist/tests/cli-config-warnings.test.js +41 -0
- package/dist/tests/cli-init.test.cjs +86 -26
- package/dist/tests/cli-init.test.js +86 -26
- package/dist/tests/config-json-schema.test.cjs +12 -0
- package/dist/tests/config-json-schema.test.js +12 -0
- package/dist/tests/gateway-http-security.test.cjs +21 -0
- package/dist/tests/gateway-http-security.test.js +21 -0
- package/dist/tests/gateway-origin-policy.test.cjs +22 -0
- package/dist/tests/gateway-origin-policy.test.js +22 -0
- package/dist/tests/gateway.test.cjs +57 -0
- package/dist/tests/gateway.test.js +57 -0
- package/dist/tests/imagePersistence.test.cjs +26 -0
- package/dist/tests/imagePersistence.test.js +27 -1
- package/dist/tests/run-terminal-bench-official-script.test.cjs +61 -0
- package/dist/tests/run-terminal-bench-official-script.test.d.ts +1 -0
- package/dist/tests/run-terminal-bench-official-script.test.js +55 -0
- package/dist/tests/sessions-api.test.cjs +69 -1
- package/dist/tests/sessions-api.test.js +70 -2
- package/dist/tests/skill-activation.test.cjs +86 -0
- package/dist/tests/skill-activation.test.d.ts +1 -0
- package/dist/tests/skill-activation.test.js +80 -0
- package/dist/tests/skill-metadata.test.cjs +119 -0
- package/dist/tests/skill-metadata.test.d.ts +1 -0
- package/dist/tests/skill-metadata.test.js +113 -0
- package/dist/tests/skill-repository.test.cjs +363 -0
- package/dist/tests/skill-repository.test.js +363 -0
- package/dist/tests/sms-api.test.cjs +183 -0
- package/dist/tests/sms-api.test.d.ts +1 -0
- package/dist/tests/sms-api.test.js +177 -0
- package/dist/tests/sms-commands.test.cjs +90 -0
- package/dist/tests/sms-commands.test.d.ts +1 -0
- package/dist/tests/sms-commands.test.js +84 -0
- package/dist/tests/sms-policy-store.test.cjs +69 -0
- package/dist/tests/sms-policy-store.test.d.ts +1 -0
- package/dist/tests/sms-policy-store.test.js +63 -0
- package/dist/tests/teams-adapter.test.cjs +58 -0
- package/dist/tests/teams-adapter.test.d.ts +1 -0
- package/dist/tests/teams-adapter.test.js +52 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.cjs +64 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.d.ts +1 -0
- package/dist/tests/terminal-bench-adapters-helpers.test.js +58 -0
- package/dist/tests/terminal-bench-cleanup.test.cjs +93 -0
- package/dist/tests/terminal-bench-cleanup.test.d.ts +1 -0
- package/dist/tests/terminal-bench-cleanup.test.js +87 -0
- package/dist/tests/terminal-bench-config.test.cjs +62 -0
- package/dist/tests/terminal-bench-config.test.d.ts +1 -0
- package/dist/tests/terminal-bench-config.test.js +56 -0
- package/dist/tests/terminal-bench-official.test.cjs +194 -0
- package/dist/tests/terminal-bench-official.test.d.ts +1 -0
- package/dist/tests/terminal-bench-official.test.js +188 -0
- package/dist/tests/terminal-bench-runner.test.cjs +82 -0
- package/dist/tests/terminal-bench-runner.test.d.ts +1 -0
- package/dist/tests/terminal-bench-runner.test.js +76 -0
- package/dist/tests/terminal-bench-scoring.test.cjs +128 -0
- package/dist/tests/terminal-bench-scoring.test.d.ts +1 -0
- package/dist/tests/terminal-bench-scoring.test.js +122 -0
- package/dist/tools/mcp-fal-ai.cjs +1 -1
- package/dist/tools/mcp-fal-ai.js +1 -1
- package/dist/webui/assets/index-Cyg_Hs57.css +11 -0
- package/dist/webui/assets/{index-BMekSELC.js → index-DZXLLjaA.js} +109 -109
- package/dist/webui/index.html +2 -2
- package/package.json +14 -5
- package/skills/gog/SKILL.md +1 -1
- package/skills/weather/SKILL.md +1 -1
- package/templates/agents/game-dev/agent.md +122 -63
- package/templates/agents/game-dev/art-director.md +106 -0
- package/templates/agents/game-dev/game-designer.md +87 -0
- package/templates/agents/game-dev/scene-engineer.md +474 -0
- package/dist/webui/assets/index-Cwkg4DKj.css +0 -11
- package/skills/ui-registry/SKILL.md +0 -35
- package/templates/agents/game-dev/art-generation.md +0 -38
- package/templates/agents/game-dev/asset-refinement.md +0 -17
- package/templates/agents/game-dev/planning-idea.md +0 -17
- package/templates/agents/game-dev/ui-specialist.md +0 -17
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { getSessionMediaDirectory, persistAssistantImagesToDisk } from "../cli/core/imagePersistence.js";
|
|
5
6
|
import { SessionManager } from "../cli/core/sessionManager.js";
|
|
6
7
|
import { handleSessionsApi } from "../gateway/http/sessions.js";
|
|
7
8
|
const isBunRuntime = void 0 !== globalThis.Bun;
|
|
@@ -9,9 +10,11 @@ const describeIfBun = isBunRuntime ? describe : describe.skip;
|
|
|
9
10
|
describeIfBun("sessions API", ()=>{
|
|
10
11
|
let manager;
|
|
11
12
|
let tempDir;
|
|
13
|
+
let dbPath;
|
|
14
|
+
const PNG_DATA_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO3X6S0AAAAASUVORK5CYII=";
|
|
12
15
|
beforeEach(async ()=>{
|
|
13
16
|
tempDir = mkdtempSync(join(tmpdir(), "wingman-sessions-"));
|
|
14
|
-
|
|
17
|
+
dbPath = join(tempDir, "sessions.db");
|
|
15
18
|
manager = new SessionManager(dbPath);
|
|
16
19
|
await manager.initialize();
|
|
17
20
|
});
|
|
@@ -43,6 +46,23 @@ describeIfBun("sessions API", ()=>{
|
|
|
43
46
|
expect(createRes).not.toBeNull();
|
|
44
47
|
expect(createRes?.ok).toBe(true);
|
|
45
48
|
const created = await createRes.json();
|
|
49
|
+
const mediaDir = getSessionMediaDirectory(dbPath, created.id);
|
|
50
|
+
persistAssistantImagesToDisk({
|
|
51
|
+
dbPath,
|
|
52
|
+
sessionId: created.id,
|
|
53
|
+
messages: [
|
|
54
|
+
{
|
|
55
|
+
role: "assistant",
|
|
56
|
+
attachments: [
|
|
57
|
+
{
|
|
58
|
+
kind: "image",
|
|
59
|
+
dataUrl: PNG_DATA_URL
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
});
|
|
65
|
+
expect(existsSync(mediaDir)).toBe(true);
|
|
46
66
|
manager.updateSession(created.id, {
|
|
47
67
|
messageCount: 2,
|
|
48
68
|
lastMessagePreview: "Hello"
|
|
@@ -55,10 +75,58 @@ describeIfBun("sessions API", ()=>{
|
|
|
55
75
|
expect(deleteRes?.ok).toBe(true);
|
|
56
76
|
const payload = await deleteRes.json();
|
|
57
77
|
expect(payload.messageCount).toBe(0);
|
|
78
|
+
expect(existsSync(mediaDir)).toBe(false);
|
|
58
79
|
const updated = manager.getSession(created.id);
|
|
59
80
|
expect(updated?.messageCount).toBe(0);
|
|
60
81
|
expect(updated?.lastMessagePreview).toBeNull();
|
|
61
82
|
});
|
|
83
|
+
it("removes persisted session media when deleting a session", async ()=>{
|
|
84
|
+
const ctx = {
|
|
85
|
+
getSessionManager: async ()=>manager,
|
|
86
|
+
router: {
|
|
87
|
+
selectAgent: (agentId)=>agentId || "main"
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const createReq = new Request("http://localhost/api/sessions", {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: {
|
|
93
|
+
"Content-Type": "application/json"
|
|
94
|
+
},
|
|
95
|
+
body: JSON.stringify({
|
|
96
|
+
agentId: "main",
|
|
97
|
+
name: "Delete Session Media"
|
|
98
|
+
})
|
|
99
|
+
});
|
|
100
|
+
const createRes = await handleSessionsApi(ctx, createReq, new URL(createReq.url));
|
|
101
|
+
expect(createRes).not.toBeNull();
|
|
102
|
+
expect(createRes?.ok).toBe(true);
|
|
103
|
+
const created = await createRes.json();
|
|
104
|
+
const mediaDir = getSessionMediaDirectory(dbPath, created.id);
|
|
105
|
+
persistAssistantImagesToDisk({
|
|
106
|
+
dbPath,
|
|
107
|
+
sessionId: created.id,
|
|
108
|
+
messages: [
|
|
109
|
+
{
|
|
110
|
+
role: "assistant",
|
|
111
|
+
attachments: [
|
|
112
|
+
{
|
|
113
|
+
kind: "image",
|
|
114
|
+
dataUrl: PNG_DATA_URL
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
});
|
|
120
|
+
expect(existsSync(mediaDir)).toBe(true);
|
|
121
|
+
const deleteReq = new Request(`http://localhost/api/sessions/${encodeURIComponent(created.id)}?agentId=main`, {
|
|
122
|
+
method: "DELETE"
|
|
123
|
+
});
|
|
124
|
+
const deleteRes = await handleSessionsApi(ctx, deleteReq, new URL(deleteReq.url));
|
|
125
|
+
expect(deleteRes).not.toBeNull();
|
|
126
|
+
expect(deleteRes?.ok).toBe(true);
|
|
127
|
+
expect(existsSync(mediaDir)).toBe(false);
|
|
128
|
+
expect(manager.getSession(created.id)).toBeNull();
|
|
129
|
+
});
|
|
62
130
|
it("returns pending messages and clears them via DELETE", async ()=>{
|
|
63
131
|
const ctx = {
|
|
64
132
|
getSessionManager: async ()=>manager,
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
4
|
+
const external_node_os_namespaceObject = require("node:os");
|
|
5
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
6
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
7
|
+
const activation_cjs_namespaceObject = require("../skills/activation.cjs");
|
|
8
|
+
const tempDirs = [];
|
|
9
|
+
const createSkill = (root, skillName, frontmatter)=>{
|
|
10
|
+
const skillDir = (0, external_node_path_namespaceObject.join)(root, skillName);
|
|
11
|
+
(0, external_node_fs_namespaceObject.mkdirSync)(skillDir, {
|
|
12
|
+
recursive: true
|
|
13
|
+
});
|
|
14
|
+
(0, external_node_fs_namespaceObject.writeFileSync)(skillDir + "/SKILL.md", `${frontmatter}\n\n# ${skillName}\n`);
|
|
15
|
+
};
|
|
16
|
+
(0, external_vitest_namespaceObject.afterEach)(()=>{
|
|
17
|
+
for (const dir of tempDirs)(0, external_node_fs_namespaceObject.rmSync)(dir, {
|
|
18
|
+
recursive: true,
|
|
19
|
+
force: true
|
|
20
|
+
});
|
|
21
|
+
tempDirs.length = 0;
|
|
22
|
+
});
|
|
23
|
+
(0, external_vitest_namespaceObject.describe)("resolveSkillActivation", ()=>{
|
|
24
|
+
(0, external_vitest_namespaceObject.it)("deactivates skills with missing required bins", async ()=>{
|
|
25
|
+
const root = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-skill-activation-"));
|
|
26
|
+
tempDirs.push(root);
|
|
27
|
+
createSkill(root, "gog", `---
|
|
28
|
+
name: gog
|
|
29
|
+
description: Google tooling
|
|
30
|
+
metadata:
|
|
31
|
+
wingman:
|
|
32
|
+
requires:
|
|
33
|
+
bins: ["gog"]
|
|
34
|
+
---`);
|
|
35
|
+
createSkill(root, "weather", `---
|
|
36
|
+
name: weather
|
|
37
|
+
description: Weather tooling
|
|
38
|
+
---`);
|
|
39
|
+
const result = await (0, activation_cjs_namespaceObject.resolveSkillActivation)(root, (binName)=>"gog" !== binName);
|
|
40
|
+
(0, external_vitest_namespaceObject.expect)(result.activeSkillNames).toContain("weather");
|
|
41
|
+
(0, external_vitest_namespaceObject.expect)(result.activeSkillNames).not.toContain("gog");
|
|
42
|
+
(0, external_vitest_namespaceObject.expect)(result.inactiveSkills).toEqual([
|
|
43
|
+
{
|
|
44
|
+
name: "gog",
|
|
45
|
+
namespace: "wingman",
|
|
46
|
+
requiredBins: [
|
|
47
|
+
"gog"
|
|
48
|
+
],
|
|
49
|
+
missingBins: [
|
|
50
|
+
"gog"
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
]);
|
|
54
|
+
});
|
|
55
|
+
(0, external_vitest_namespaceObject.it)("ignores unsupported namespaces and keeps skills active", async ()=>{
|
|
56
|
+
const root = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-skill-activation-"));
|
|
57
|
+
tempDirs.push(root);
|
|
58
|
+
createSkill(root, "legacy", `---
|
|
59
|
+
name: legacy
|
|
60
|
+
description: Legacy metadata
|
|
61
|
+
metadata:
|
|
62
|
+
clawdbot:
|
|
63
|
+
requires:
|
|
64
|
+
bins: ["gog"]
|
|
65
|
+
---`);
|
|
66
|
+
const result = await (0, activation_cjs_namespaceObject.resolveSkillActivation)(root, ()=>false);
|
|
67
|
+
(0, external_vitest_namespaceObject.expect)(result.activeSkillNames).toContain("legacy");
|
|
68
|
+
(0, external_vitest_namespaceObject.expect)(result.inactiveSkills).toHaveLength(0);
|
|
69
|
+
});
|
|
70
|
+
(0, external_vitest_namespaceObject.it)("keeps skill active when frontmatter parsing fails", async ()=>{
|
|
71
|
+
const root = (0, external_node_fs_namespaceObject.mkdtempSync)((0, external_node_path_namespaceObject.join)((0, external_node_os_namespaceObject.tmpdir)(), "wingman-skill-activation-"));
|
|
72
|
+
tempDirs.push(root);
|
|
73
|
+
const skillDir = (0, external_node_path_namespaceObject.join)(root, "broken");
|
|
74
|
+
(0, external_node_fs_namespaceObject.mkdirSync)(skillDir, {
|
|
75
|
+
recursive: true
|
|
76
|
+
});
|
|
77
|
+
(0, external_node_fs_namespaceObject.writeFileSync)((0, external_node_path_namespaceObject.join)(skillDir, "SKILL.md"), "---\nname: broken\nnot-valid\n---");
|
|
78
|
+
const result = await (0, activation_cjs_namespaceObject.resolveSkillActivation)(root, ()=>true);
|
|
79
|
+
(0, external_vitest_namespaceObject.expect)(result.activeSkillNames).toContain("broken");
|
|
80
|
+
(0, external_vitest_namespaceObject.expect)(result.inactiveSkills).toHaveLength(0);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
84
|
+
Object.defineProperty(exports, '__esModule', {
|
|
85
|
+
value: true
|
|
86
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { resolveSkillActivation } from "../skills/activation.js";
|
|
6
|
+
const tempDirs = [];
|
|
7
|
+
const createSkill = (root, skillName, frontmatter)=>{
|
|
8
|
+
const skillDir = join(root, skillName);
|
|
9
|
+
mkdirSync(skillDir, {
|
|
10
|
+
recursive: true
|
|
11
|
+
});
|
|
12
|
+
writeFileSync(skillDir + "/SKILL.md", `${frontmatter}\n\n# ${skillName}\n`);
|
|
13
|
+
};
|
|
14
|
+
afterEach(()=>{
|
|
15
|
+
for (const dir of tempDirs)rmSync(dir, {
|
|
16
|
+
recursive: true,
|
|
17
|
+
force: true
|
|
18
|
+
});
|
|
19
|
+
tempDirs.length = 0;
|
|
20
|
+
});
|
|
21
|
+
describe("resolveSkillActivation", ()=>{
|
|
22
|
+
it("deactivates skills with missing required bins", async ()=>{
|
|
23
|
+
const root = mkdtempSync(join(tmpdir(), "wingman-skill-activation-"));
|
|
24
|
+
tempDirs.push(root);
|
|
25
|
+
createSkill(root, "gog", `---
|
|
26
|
+
name: gog
|
|
27
|
+
description: Google tooling
|
|
28
|
+
metadata:
|
|
29
|
+
wingman:
|
|
30
|
+
requires:
|
|
31
|
+
bins: ["gog"]
|
|
32
|
+
---`);
|
|
33
|
+
createSkill(root, "weather", `---
|
|
34
|
+
name: weather
|
|
35
|
+
description: Weather tooling
|
|
36
|
+
---`);
|
|
37
|
+
const result = await resolveSkillActivation(root, (binName)=>"gog" !== binName);
|
|
38
|
+
expect(result.activeSkillNames).toContain("weather");
|
|
39
|
+
expect(result.activeSkillNames).not.toContain("gog");
|
|
40
|
+
expect(result.inactiveSkills).toEqual([
|
|
41
|
+
{
|
|
42
|
+
name: "gog",
|
|
43
|
+
namespace: "wingman",
|
|
44
|
+
requiredBins: [
|
|
45
|
+
"gog"
|
|
46
|
+
],
|
|
47
|
+
missingBins: [
|
|
48
|
+
"gog"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]);
|
|
52
|
+
});
|
|
53
|
+
it("ignores unsupported namespaces and keeps skills active", async ()=>{
|
|
54
|
+
const root = mkdtempSync(join(tmpdir(), "wingman-skill-activation-"));
|
|
55
|
+
tempDirs.push(root);
|
|
56
|
+
createSkill(root, "legacy", `---
|
|
57
|
+
name: legacy
|
|
58
|
+
description: Legacy metadata
|
|
59
|
+
metadata:
|
|
60
|
+
clawdbot:
|
|
61
|
+
requires:
|
|
62
|
+
bins: ["gog"]
|
|
63
|
+
---`);
|
|
64
|
+
const result = await resolveSkillActivation(root, ()=>false);
|
|
65
|
+
expect(result.activeSkillNames).toContain("legacy");
|
|
66
|
+
expect(result.inactiveSkills).toHaveLength(0);
|
|
67
|
+
});
|
|
68
|
+
it("keeps skill active when frontmatter parsing fails", async ()=>{
|
|
69
|
+
const root = mkdtempSync(join(tmpdir(), "wingman-skill-activation-"));
|
|
70
|
+
tempDirs.push(root);
|
|
71
|
+
const skillDir = join(root, "broken");
|
|
72
|
+
mkdirSync(skillDir, {
|
|
73
|
+
recursive: true
|
|
74
|
+
});
|
|
75
|
+
writeFileSync(join(skillDir, "SKILL.md"), "---\nname: broken\nnot-valid\n---");
|
|
76
|
+
const result = await resolveSkillActivation(root, ()=>true);
|
|
77
|
+
expect(result.activeSkillNames).toContain("broken");
|
|
78
|
+
expect(result.inactiveSkills).toHaveLength(0);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_exports__ = {};
|
|
3
|
+
const external_vitest_namespaceObject = require("vitest");
|
|
4
|
+
const metadata_cjs_namespaceObject = require("../skills/metadata.cjs");
|
|
5
|
+
(0, external_vitest_namespaceObject.describe)("parseSkillFrontmatter", ()=>{
|
|
6
|
+
(0, external_vitest_namespaceObject.it)("parses wingman metadata with requires and install recipes", ()=>{
|
|
7
|
+
const content = `---
|
|
8
|
+
name: gog
|
|
9
|
+
description: Google tooling
|
|
10
|
+
metadata:
|
|
11
|
+
wingman:
|
|
12
|
+
emoji: "🎮"
|
|
13
|
+
requires:
|
|
14
|
+
bins: ["gog"]
|
|
15
|
+
install:
|
|
16
|
+
- id: brew
|
|
17
|
+
kind: brew
|
|
18
|
+
formula: steipete/tap/gogcli
|
|
19
|
+
bins: ["gog"]
|
|
20
|
+
label: Install gog (brew)
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# gog
|
|
24
|
+
`;
|
|
25
|
+
const parsed = (0, metadata_cjs_namespaceObject.parseSkillFrontmatter)(content);
|
|
26
|
+
(0, external_vitest_namespaceObject.expect)(parsed.name).toBe("gog");
|
|
27
|
+
(0, external_vitest_namespaceObject.expect)(parsed.description).toBe("Google tooling");
|
|
28
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata?.namespace).toBe("wingman");
|
|
29
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata?.requires.bins).toEqual([
|
|
30
|
+
"gog"
|
|
31
|
+
]);
|
|
32
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata?.install).toEqual([
|
|
33
|
+
{
|
|
34
|
+
id: "brew",
|
|
35
|
+
kind: "brew",
|
|
36
|
+
formula: "steipete/tap/gogcli",
|
|
37
|
+
bins: [
|
|
38
|
+
"gog"
|
|
39
|
+
],
|
|
40
|
+
label: "Install gog (brew)"
|
|
41
|
+
}
|
|
42
|
+
]);
|
|
43
|
+
});
|
|
44
|
+
(0, external_vitest_namespaceObject.it)("prefers wingman over openclaw when both namespaces are present", ()=>{
|
|
45
|
+
const content = `---
|
|
46
|
+
name: dual
|
|
47
|
+
description: Dual namespace
|
|
48
|
+
metadata:
|
|
49
|
+
openclaw:
|
|
50
|
+
requires:
|
|
51
|
+
bins: ["oldbin"]
|
|
52
|
+
wingman:
|
|
53
|
+
requires:
|
|
54
|
+
bins: ["newbin"]
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
# dual
|
|
58
|
+
`;
|
|
59
|
+
const parsed = (0, metadata_cjs_namespaceObject.parseSkillFrontmatter)(content);
|
|
60
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata?.namespace).toBe("wingman");
|
|
61
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata?.requires.bins).toEqual([
|
|
62
|
+
"newbin"
|
|
63
|
+
]);
|
|
64
|
+
});
|
|
65
|
+
(0, external_vitest_namespaceObject.it)("supports openclaw namespace when wingman is absent", ()=>{
|
|
66
|
+
const content = `---
|
|
67
|
+
name: open
|
|
68
|
+
description: Openclaw namespace
|
|
69
|
+
metadata:
|
|
70
|
+
openclaw:
|
|
71
|
+
requires:
|
|
72
|
+
bins: ["gog"]
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
# open
|
|
76
|
+
`;
|
|
77
|
+
const parsed = (0, metadata_cjs_namespaceObject.parseSkillFrontmatter)(content);
|
|
78
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata?.namespace).toBe("openclaw");
|
|
79
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata?.requires.bins).toEqual([
|
|
80
|
+
"gog"
|
|
81
|
+
]);
|
|
82
|
+
});
|
|
83
|
+
(0, external_vitest_namespaceObject.it)("ignores unsupported namespaces like clawdbot", ()=>{
|
|
84
|
+
const content = `---
|
|
85
|
+
name: legacy
|
|
86
|
+
description: Legacy metadata
|
|
87
|
+
metadata:
|
|
88
|
+
clawdbot:
|
|
89
|
+
requires:
|
|
90
|
+
bins: ["gog"]
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
# legacy
|
|
94
|
+
`;
|
|
95
|
+
const parsed = (0, metadata_cjs_namespaceObject.parseSkillFrontmatter)(content);
|
|
96
|
+
(0, external_vitest_namespaceObject.expect)(parsed.runtimeMetadata).toBeNull();
|
|
97
|
+
});
|
|
98
|
+
(0, external_vitest_namespaceObject.it)("normalizes allowed tools from either key", ()=>{
|
|
99
|
+
const content = `---
|
|
100
|
+
name: ui-registry
|
|
101
|
+
description: UI helpers
|
|
102
|
+
allowedTools:
|
|
103
|
+
- ui_registry_list
|
|
104
|
+
- ui_present
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
# ui
|
|
108
|
+
`;
|
|
109
|
+
const parsed = (0, metadata_cjs_namespaceObject.parseSkillFrontmatter)(content);
|
|
110
|
+
(0, external_vitest_namespaceObject.expect)(parsed.allowedTools).toEqual([
|
|
111
|
+
"ui_registry_list",
|
|
112
|
+
"ui_present"
|
|
113
|
+
]);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
117
|
+
Object.defineProperty(exports, '__esModule', {
|
|
118
|
+
value: true
|
|
119
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { parseSkillFrontmatter } from "../skills/metadata.js";
|
|
3
|
+
describe("parseSkillFrontmatter", ()=>{
|
|
4
|
+
it("parses wingman metadata with requires and install recipes", ()=>{
|
|
5
|
+
const content = `---
|
|
6
|
+
name: gog
|
|
7
|
+
description: Google tooling
|
|
8
|
+
metadata:
|
|
9
|
+
wingman:
|
|
10
|
+
emoji: "🎮"
|
|
11
|
+
requires:
|
|
12
|
+
bins: ["gog"]
|
|
13
|
+
install:
|
|
14
|
+
- id: brew
|
|
15
|
+
kind: brew
|
|
16
|
+
formula: steipete/tap/gogcli
|
|
17
|
+
bins: ["gog"]
|
|
18
|
+
label: Install gog (brew)
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# gog
|
|
22
|
+
`;
|
|
23
|
+
const parsed = parseSkillFrontmatter(content);
|
|
24
|
+
expect(parsed.name).toBe("gog");
|
|
25
|
+
expect(parsed.description).toBe("Google tooling");
|
|
26
|
+
expect(parsed.runtimeMetadata?.namespace).toBe("wingman");
|
|
27
|
+
expect(parsed.runtimeMetadata?.requires.bins).toEqual([
|
|
28
|
+
"gog"
|
|
29
|
+
]);
|
|
30
|
+
expect(parsed.runtimeMetadata?.install).toEqual([
|
|
31
|
+
{
|
|
32
|
+
id: "brew",
|
|
33
|
+
kind: "brew",
|
|
34
|
+
formula: "steipete/tap/gogcli",
|
|
35
|
+
bins: [
|
|
36
|
+
"gog"
|
|
37
|
+
],
|
|
38
|
+
label: "Install gog (brew)"
|
|
39
|
+
}
|
|
40
|
+
]);
|
|
41
|
+
});
|
|
42
|
+
it("prefers wingman over openclaw when both namespaces are present", ()=>{
|
|
43
|
+
const content = `---
|
|
44
|
+
name: dual
|
|
45
|
+
description: Dual namespace
|
|
46
|
+
metadata:
|
|
47
|
+
openclaw:
|
|
48
|
+
requires:
|
|
49
|
+
bins: ["oldbin"]
|
|
50
|
+
wingman:
|
|
51
|
+
requires:
|
|
52
|
+
bins: ["newbin"]
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
# dual
|
|
56
|
+
`;
|
|
57
|
+
const parsed = parseSkillFrontmatter(content);
|
|
58
|
+
expect(parsed.runtimeMetadata?.namespace).toBe("wingman");
|
|
59
|
+
expect(parsed.runtimeMetadata?.requires.bins).toEqual([
|
|
60
|
+
"newbin"
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
it("supports openclaw namespace when wingman is absent", ()=>{
|
|
64
|
+
const content = `---
|
|
65
|
+
name: open
|
|
66
|
+
description: Openclaw namespace
|
|
67
|
+
metadata:
|
|
68
|
+
openclaw:
|
|
69
|
+
requires:
|
|
70
|
+
bins: ["gog"]
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
# open
|
|
74
|
+
`;
|
|
75
|
+
const parsed = parseSkillFrontmatter(content);
|
|
76
|
+
expect(parsed.runtimeMetadata?.namespace).toBe("openclaw");
|
|
77
|
+
expect(parsed.runtimeMetadata?.requires.bins).toEqual([
|
|
78
|
+
"gog"
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
81
|
+
it("ignores unsupported namespaces like clawdbot", ()=>{
|
|
82
|
+
const content = `---
|
|
83
|
+
name: legacy
|
|
84
|
+
description: Legacy metadata
|
|
85
|
+
metadata:
|
|
86
|
+
clawdbot:
|
|
87
|
+
requires:
|
|
88
|
+
bins: ["gog"]
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
# legacy
|
|
92
|
+
`;
|
|
93
|
+
const parsed = parseSkillFrontmatter(content);
|
|
94
|
+
expect(parsed.runtimeMetadata).toBeNull();
|
|
95
|
+
});
|
|
96
|
+
it("normalizes allowed tools from either key", ()=>{
|
|
97
|
+
const content = `---
|
|
98
|
+
name: ui-registry
|
|
99
|
+
description: UI helpers
|
|
100
|
+
allowedTools:
|
|
101
|
+
- ui_registry_list
|
|
102
|
+
- ui_present
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
# ui
|
|
106
|
+
`;
|
|
107
|
+
const parsed = parseSkillFrontmatter(content);
|
|
108
|
+
expect(parsed.allowedTools).toEqual([
|
|
109
|
+
"ui_registry_list",
|
|
110
|
+
"ui_present"
|
|
111
|
+
]);
|
|
112
|
+
});
|
|
113
|
+
});
|