@chatpanel/bridge 0.10.28 → 0.10.29
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/package.json +1 -1
- package/src/server.js +1 -1
- package/src/skills.js +45 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatpanel/bridge",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Local bridge that exposes the AI coding agents installed on your machine \u2014 Claude Code (CLI), Codex (CLI), and Antigravity CLI (formerly Gemini CLI, which remains available for business/enterprise) \u2014 to the ChatPanel Chrome extension over a localhost SSE endpoint. Bring your own agent.",
|
|
6
6
|
"keywords": [
|
package/src/server.js
CHANGED
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
// Hardcoded (not read from package.json) so it survives Bun's single-file
|
|
65
65
|
// --compile, where package.json isn't on a readable FS. CI fails the publish if
|
|
66
66
|
// this drifts from package.json, so the two can't silently diverge.
|
|
67
|
-
const VERSION = '0.10.
|
|
67
|
+
const VERSION = '0.10.29';
|
|
68
68
|
const HOST = process.env.CHATPANEL_BRIDGE_HOST || '127.0.0.1';
|
|
69
69
|
const PORT = Number(process.env.CHATPANEL_BRIDGE_PORT) || 4319;
|
|
70
70
|
|
package/src/skills.js
CHANGED
|
@@ -45,11 +45,40 @@ const MAX_SKILLS = 500; // a scan is bounded work, not "whatever is o
|
|
|
45
45
|
const MAX_DEPTH = 2; // <root>/<name>/ and <root>/<category>/<name>/
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
49
|
-
* which makes ChatPanel's own directory authoritative over a shared one.
|
|
48
|
+
* The agent CLIs that keep skills in a well-known directory, and what to call each one.
|
|
50
49
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* Every one of these stores the SAME agentskills.io layout — `<name>/SKILL.md` plus
|
|
51
|
+
* optional `references/`. In practice a machine ends up with the same skill copied into
|
|
52
|
+
* several of them, which is the duplication the shared `~/.agents/skills` convention
|
|
53
|
+
* exists to end and has not yet. Reading all of them is what lets ChatPanel show the
|
|
54
|
+
* user's actual skills rather than the subset that happens to live in one folder.
|
|
55
|
+
*
|
|
56
|
+
* Ordered: ChatPanel's own directory, then the cross-tool convention, then each agent.
|
|
57
|
+
* The order IS the precedence — see skillRoots.
|
|
58
|
+
*/
|
|
59
|
+
export const AGENT_SKILL_DIRS = Object.freeze([
|
|
60
|
+
{ source: 'local', label: 'ChatPanel', segments: ['.chatpanel', 'skills'], writable: true },
|
|
61
|
+
{ source: 'agents-dir', label: 'Shared (~/.agents)', segments: ['.agents', 'skills'] },
|
|
62
|
+
{ source: 'claude', label: 'Claude Code', segments: ['.claude', 'skills'] },
|
|
63
|
+
{ source: 'codex', label: 'Codex', segments: ['.codex', 'skills'] },
|
|
64
|
+
{ source: 'copilot', label: 'GitHub Copilot', segments: ['.copilot', 'skills'] },
|
|
65
|
+
{ source: 'gemini', label: 'Antigravity / Gemini', segments: ['.gemini', 'skills'] },
|
|
66
|
+
{ source: 'opencode', label: 'OpenCode', segments: ['.opencode', 'skills'] },
|
|
67
|
+
{ source: 'kiro', label: 'Kiro', segments: ['.kiro', 'skills'] },
|
|
68
|
+
{ source: 'pi', label: 'Pi', segments: ['.pi', 'skills'] },
|
|
69
|
+
{ source: 'hermes', label: 'Hermes', segments: ['.hermes', 'skills'] },
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Where skills are scanned from, in precedence order — first hit wins on a name clash.
|
|
74
|
+
*
|
|
75
|
+
* ChatPanel's own directory is authoritative, then the shared cross-tool one, then each
|
|
76
|
+
* agent's. That order matters because the same skill genuinely does exist in several of
|
|
77
|
+
* these at once: whichever root answers first is the copy that gets shown, and a stable
|
|
78
|
+
* order means the answer does not change between scans.
|
|
79
|
+
*
|
|
80
|
+
* Only the first is written. The rest belong to whatever else the user runs, and a tool
|
|
81
|
+
* that edits another tool's configuration directory is a tool people uninstall.
|
|
53
82
|
*/
|
|
54
83
|
export function skillRoots(env = process.env, home = os.homedir()) {
|
|
55
84
|
const extra = String(env.CHATPANEL_SKILL_DIRS || '')
|
|
@@ -57,9 +86,13 @@ export function skillRoots(env = process.env, home = os.homedir()) {
|
|
|
57
86
|
.map((s) => s.trim())
|
|
58
87
|
.filter(Boolean);
|
|
59
88
|
return [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
89
|
+
...AGENT_SKILL_DIRS.map((d) => ({
|
|
90
|
+
dir: join(home, ...d.segments),
|
|
91
|
+
source: d.source,
|
|
92
|
+
label: d.label,
|
|
93
|
+
writable: !!d.writable,
|
|
94
|
+
})),
|
|
95
|
+
...extra.map((dir) => ({ dir: resolve(dir), source: 'external', label: 'Custom', writable: false })),
|
|
63
96
|
];
|
|
64
97
|
}
|
|
65
98
|
|
|
@@ -289,9 +322,13 @@ export function clearSkillCache() { cached = null; }
|
|
|
289
322
|
/** The `/health` summary — counts and roots, never contents. */
|
|
290
323
|
export async function skillsHealth() {
|
|
291
324
|
const { index, problems } = await skillIndex();
|
|
325
|
+
const used = new Set([...index.values()].map((v) => v.root));
|
|
292
326
|
return {
|
|
293
327
|
count: index.size,
|
|
294
|
-
roots
|
|
328
|
+
// Only roots that actually contributed. A list of every path we looked in would be
|
|
329
|
+
// mostly absent directories, and would say nothing about what the user has.
|
|
330
|
+
roots: skillRoots().filter((r) => used.has(r.dir)).map((r) => r.dir),
|
|
331
|
+
sources: [...new Set([...index.values()].map((v) => v.source))].sort(),
|
|
295
332
|
...(problems.length ? { problems: problems.length } : {}),
|
|
296
333
|
};
|
|
297
334
|
}
|