polygram 0.8.0-rc.48 → 0.8.0-rc.49
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/.claude-plugin/plugin.json +1 -1
- package/lib/agent-loader.js +60 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "polygram",
|
|
4
|
-
"version": "0.8.0-rc.
|
|
4
|
+
"version": "0.8.0-rc.49",
|
|
5
5
|
"description": "Telegram integration for Claude Code that preserves the OpenClaw per-chat session model. Migration target for OpenClaw users. Multi-bot, multi-chat, per-topic isolation; SQLite transcripts; inline-keyboard approvals. Bundles /polygram:status|logs|pair-code|approvals admin commands and a history skill.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"telegram",
|
package/lib/agent-loader.js
CHANGED
|
@@ -56,10 +56,69 @@ const cache = new Map(); // cacheKey → AgentBundle
|
|
|
56
56
|
// consecutive dots, slashes, NUL.
|
|
57
57
|
const AGENT_NAME_RE = /^[A-Za-z0-9_]+(?:[.-][A-Za-z0-9_]+)*$/;
|
|
58
58
|
|
|
59
|
+
// rc.49: parse `<plugin>:<agent>` qualified names. Each side must
|
|
60
|
+
// independently satisfy AGENT_NAME_RE. Returns { plugin, agent } or
|
|
61
|
+
// null if not qualified or malformed.
|
|
62
|
+
function parseQualifiedName(name) {
|
|
63
|
+
if (typeof name !== 'string' || !name.includes(':')) return null;
|
|
64
|
+
const parts = name.split(':');
|
|
65
|
+
if (parts.length !== 2) return null;
|
|
66
|
+
const [plugin, agent] = parts;
|
|
67
|
+
if (!AGENT_NAME_RE.test(plugin) || !AGENT_NAME_RE.test(agent)) return null;
|
|
68
|
+
return { plugin, agent };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// rc.49: look up a plugin's installPath in
|
|
72
|
+
// ~/.claude/plugins/installed_plugins.json. Keys are
|
|
73
|
+
// `<name>@<marketplace>` — match by the bare `<name>` prefix and
|
|
74
|
+
// return the first installed entry's `installPath`. Returns null if
|
|
75
|
+
// not enrolled or registry unreadable.
|
|
76
|
+
function lookupInstalledPlugin(pluginName, homeDir) {
|
|
77
|
+
const registryPath = path.join(homeDir, '.claude', 'plugins', 'installed_plugins.json');
|
|
78
|
+
if (!fs.existsSync(registryPath)) return null;
|
|
79
|
+
let registry;
|
|
80
|
+
try {
|
|
81
|
+
registry = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
|
|
82
|
+
} catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const plugins = registry?.plugins || {};
|
|
86
|
+
const prefix = pluginName + '@';
|
|
87
|
+
for (const key of Object.keys(plugins)) {
|
|
88
|
+
if (key.startsWith(prefix)) {
|
|
89
|
+
const entries = plugins[key];
|
|
90
|
+
if (Array.isArray(entries) && entries[0]?.installPath) {
|
|
91
|
+
return entries[0].installPath;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
59
98
|
function resolveAgentLocation(agentName, homeDir, cwd) {
|
|
60
|
-
if (typeof agentName !== 'string'
|
|
99
|
+
if (typeof agentName !== 'string') return null;
|
|
100
|
+
|
|
101
|
+
// rc.49: plugin-qualified `<plugin>:<agent>` names look up the plugin
|
|
102
|
+
// from the installed registry (with fallback to ~/.claude-plugins-local/).
|
|
103
|
+
// Resolution is intentionally NARROW — only the qualified form
|
|
104
|
+
// searches plugin directories. Plain unqualified names keep the
|
|
105
|
+
// pre-rc.49 ~/.claude/agents/ + <cwd>/.claude/agents/ behaviour.
|
|
106
|
+
const qualified = parseQualifiedName(agentName);
|
|
107
|
+
if (qualified) {
|
|
108
|
+
const { plugin, agent } = qualified;
|
|
109
|
+
const installPath = lookupInstalledPlugin(plugin, homeDir);
|
|
110
|
+
if (installPath) {
|
|
111
|
+
const p = path.join(installPath, 'agents', agent + '.md');
|
|
112
|
+
if (fs.existsSync(p)) return { kind: 'file', path: p, dir: null };
|
|
113
|
+
}
|
|
114
|
+
// Fallback: ~/.claude-plugins-local/<plugin>/agents/<agent>.md
|
|
115
|
+
const localPath = path.join(homeDir, '.claude-plugins-local', plugin, 'agents', agent + '.md');
|
|
116
|
+
if (fs.existsSync(localPath)) return { kind: 'file', path: localPath, dir: null };
|
|
61
117
|
return null;
|
|
62
118
|
}
|
|
119
|
+
|
|
120
|
+
if (!AGENT_NAME_RE.test(agentName)) return null;
|
|
121
|
+
|
|
63
122
|
const fileCandidates = [];
|
|
64
123
|
if (cwd) fileCandidates.push(path.join(cwd, '.claude', 'agents', agentName + '.md'));
|
|
65
124
|
fileCandidates.push(path.join(homeDir, '.claude', 'agents', agentName + '.md'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polygram",
|
|
3
|
-
"version": "0.8.0-rc.
|
|
3
|
+
"version": "0.8.0-rc.49",
|
|
4
4
|
"description": "Telegram daemon for Claude Code that preserves the OpenClaw per-chat session model. Migration path for OpenClaw users moving to Claude Code.",
|
|
5
5
|
"main": "lib/ipc-client.js",
|
|
6
6
|
"bin": {
|