@sulala/agent 0.1.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/README.md +120 -0
- package/bin/sulala.mjs +7 -0
- package/dist/agent/loop.d.ts +38 -0
- package/dist/agent/loop.d.ts.map +1 -0
- package/dist/agent/loop.js +384 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/session-queue.d.ts +2 -0
- package/dist/agent/session-queue.d.ts.map +1 -0
- package/dist/agent/session-queue.js +13 -0
- package/dist/agent/session-queue.js.map +1 -0
- package/dist/agent/skill-install.d.ts +41 -0
- package/dist/agent/skill-install.d.ts.map +1 -0
- package/dist/agent/skill-install.js +211 -0
- package/dist/agent/skill-install.js.map +1 -0
- package/dist/agent/skills-config.d.ts +24 -0
- package/dist/agent/skills-config.d.ts.map +1 -0
- package/dist/agent/skills-config.js +126 -0
- package/dist/agent/skills-config.js.map +1 -0
- package/dist/agent/skills-watcher.d.ts +7 -0
- package/dist/agent/skills-watcher.d.ts.map +1 -0
- package/dist/agent/skills-watcher.js +32 -0
- package/dist/agent/skills-watcher.js.map +1 -0
- package/dist/agent/skills.d.ts +32 -0
- package/dist/agent/skills.d.ts.map +1 -0
- package/dist/agent/skills.js +208 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/skills.test.d.ts +2 -0
- package/dist/agent/skills.test.d.ts.map +1 -0
- package/dist/agent/skills.test.js +59 -0
- package/dist/agent/skills.test.js.map +1 -0
- package/dist/agent/tools.d.ts +8 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +147 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/ai/orchestrator.d.ts +38 -0
- package/dist/ai/orchestrator.d.ts.map +1 -0
- package/dist/ai/orchestrator.js +360 -0
- package/dist/ai/orchestrator.js.map +1 -0
- package/dist/ai/orchestrator.test.d.ts +2 -0
- package/dist/ai/orchestrator.test.d.ts.map +1 -0
- package/dist/ai/orchestrator.test.js +29 -0
- package/dist/ai/orchestrator.test.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +278 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +77 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +16 -0
- package/dist/config.test.js.map +1 -0
- package/dist/db/index.d.ts +42 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +121 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.sql +74 -0
- package/dist/gateway/server.d.ts +13 -0
- package/dist/gateway/server.d.ts.map +1 -0
- package/dist/gateway/server.js +566 -0
- package/dist/gateway/server.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/index.d.ts +52 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +176 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/scheduler/cron.d.ts +8 -0
- package/dist/scheduler/cron.d.ts.map +1 -0
- package/dist/scheduler/cron.js +31 -0
- package/dist/scheduler/cron.js.map +1 -0
- package/dist/scheduler/queue.d.ts +13 -0
- package/dist/scheduler/queue.d.ts.map +1 -0
- package/dist/scheduler/queue.js +75 -0
- package/dist/scheduler/queue.js.map +1 -0
- package/dist/scheduler/queue.test.d.ts +2 -0
- package/dist/scheduler/queue.test.d.ts.map +1 -0
- package/dist/scheduler/queue.test.js +41 -0
- package/dist/scheduler/queue.test.js.map +1 -0
- package/dist/types.d.ts +149 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/watcher/index.d.ts +15 -0
- package/dist/watcher/index.d.ts.map +1 -0
- package/dist/watcher/index.js +87 -0
- package/dist/watcher/index.js.map +1 -0
- package/dist/webhooks.d.ts +2 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +38 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +62 -0
- package/src/db/schema.sql +74 -0
- package/src/index.ts +83 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, readdirSync, unlinkSync } from 'fs';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const projectRoot = join(__dirname, '..', '..');
|
|
7
|
+
const registryPath = join(projectRoot, 'registry', 'skills-registry.json');
|
|
8
|
+
export async function getRegistrySkills(overrideUrl) {
|
|
9
|
+
const url = overrideUrl?.trim() || process.env.SKILLS_REGISTRY_URL?.trim();
|
|
10
|
+
if (url) {
|
|
11
|
+
try {
|
|
12
|
+
const res = await fetch(url.trim());
|
|
13
|
+
if (!res.ok)
|
|
14
|
+
throw new Error(`HTTP ${res.status}`);
|
|
15
|
+
const data = (await res.json());
|
|
16
|
+
return data.skills || [];
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return getRegistrySkillsLocal();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return getRegistrySkillsLocal();
|
|
23
|
+
}
|
|
24
|
+
export function getRegistrySkillsLocal() {
|
|
25
|
+
if (!existsSync(registryPath))
|
|
26
|
+
return [];
|
|
27
|
+
try {
|
|
28
|
+
const data = JSON.parse(readFileSync(registryPath, 'utf8'));
|
|
29
|
+
return data.skills || [];
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function getRegistryContentPath(slug) {
|
|
36
|
+
return join(projectRoot, 'registry', `${slug}.md`);
|
|
37
|
+
}
|
|
38
|
+
function getInstalledVersionsPath() {
|
|
39
|
+
const base = process.env.SULALA_SKILLS_DIR || join(homedir(), '.sulala', 'skills');
|
|
40
|
+
return join(dirname(base), 'installed-versions.json');
|
|
41
|
+
}
|
|
42
|
+
function loadInstalledVersions() {
|
|
43
|
+
const path = getInstalledVersionsPath();
|
|
44
|
+
if (!existsSync(path))
|
|
45
|
+
return {};
|
|
46
|
+
try {
|
|
47
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function saveInstalledVersions(data) {
|
|
54
|
+
const path = getInstalledVersionsPath();
|
|
55
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
56
|
+
writeFileSync(path, JSON.stringify(data, null, 2), 'utf8');
|
|
57
|
+
}
|
|
58
|
+
/** Compare semver strings; returns -1 if a < b, 0 if equal, 1 if a > b. */
|
|
59
|
+
function compareVersions(a, b) {
|
|
60
|
+
const pa = a.split('.').map(Number);
|
|
61
|
+
const pb = b.split('.').map(Number);
|
|
62
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
63
|
+
const va = pa[i] ?? 0;
|
|
64
|
+
const vb = pb[i] ?? 0;
|
|
65
|
+
if (va < vb)
|
|
66
|
+
return -1;
|
|
67
|
+
if (va > vb)
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
function getManagedDir() {
|
|
73
|
+
return process.env.SULALA_SKILLS_DIR || join(homedir(), '.sulala', 'skills');
|
|
74
|
+
}
|
|
75
|
+
function getWorkspaceDir() {
|
|
76
|
+
const cwd = process.cwd();
|
|
77
|
+
const path = process.env.AGENT_CONTEXT_PATH || 'context';
|
|
78
|
+
return join(cwd, path.trim());
|
|
79
|
+
}
|
|
80
|
+
export async function installSkill(slug, target, opts) {
|
|
81
|
+
const skills = await getRegistrySkills(opts?.registryUrl);
|
|
82
|
+
const entry = skills.find((s) => s.slug === slug);
|
|
83
|
+
if (!entry) {
|
|
84
|
+
return { success: false, path: '', error: `Skill not found: ${slug}` };
|
|
85
|
+
}
|
|
86
|
+
let content;
|
|
87
|
+
if (entry.url) {
|
|
88
|
+
try {
|
|
89
|
+
const res = await fetch(entry.url);
|
|
90
|
+
if (!res.ok)
|
|
91
|
+
throw new Error(`HTTP ${res.status}`);
|
|
92
|
+
content = await res.text();
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
return {
|
|
96
|
+
success: false,
|
|
97
|
+
path: '',
|
|
98
|
+
error: `Failed to fetch ${entry.url}: ${e.message}`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const localPath = getRegistryContentPath(slug);
|
|
104
|
+
if (!existsSync(localPath)) {
|
|
105
|
+
return { success: false, path: '', error: `Registry content missing: ${localPath}` };
|
|
106
|
+
}
|
|
107
|
+
content = readFileSync(localPath, 'utf8');
|
|
108
|
+
}
|
|
109
|
+
const dir = target === 'managed' ? getManagedDir() : getWorkspaceDir();
|
|
110
|
+
mkdirSync(dir, { recursive: true });
|
|
111
|
+
const destPath = join(dir, `${slug}.md`);
|
|
112
|
+
writeFileSync(destPath, content, 'utf8');
|
|
113
|
+
if (entry.version) {
|
|
114
|
+
const versions = loadInstalledVersions();
|
|
115
|
+
versions[slug] = { version: entry.version, target };
|
|
116
|
+
saveInstalledVersions(versions);
|
|
117
|
+
}
|
|
118
|
+
return { success: true, path: destPath };
|
|
119
|
+
}
|
|
120
|
+
export function uninstallSkill(slug, target) {
|
|
121
|
+
const dir = target === 'managed' ? getManagedDir() : getWorkspaceDir();
|
|
122
|
+
const filePath = join(dir, `${slug}.md`);
|
|
123
|
+
if (!existsSync(filePath)) {
|
|
124
|
+
return { success: false, path: '', error: `Skill not installed: ${slug}` };
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
unlinkSync(filePath);
|
|
128
|
+
const versions = loadInstalledVersions();
|
|
129
|
+
delete versions[slug];
|
|
130
|
+
saveInstalledVersions(versions);
|
|
131
|
+
return { success: true, path: filePath };
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
return {
|
|
135
|
+
success: false,
|
|
136
|
+
path: '',
|
|
137
|
+
error: `Failed to remove ${filePath}: ${e.message}`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Get installed skills as { slug, target } where target is where the file lives. */
|
|
142
|
+
function getInstalledSkills() {
|
|
143
|
+
const seen = new Set();
|
|
144
|
+
const out = [];
|
|
145
|
+
const managed = getManagedDir();
|
|
146
|
+
const workspace = getWorkspaceDir();
|
|
147
|
+
const dirs = [
|
|
148
|
+
[workspace, 'workspace'],
|
|
149
|
+
[managed, 'managed'],
|
|
150
|
+
];
|
|
151
|
+
for (const [dir, target] of dirs) {
|
|
152
|
+
if (!existsSync(dir))
|
|
153
|
+
continue;
|
|
154
|
+
try {
|
|
155
|
+
for (const n of readdirSync(dir)) {
|
|
156
|
+
if (!n.endsWith('.md'))
|
|
157
|
+
continue;
|
|
158
|
+
const slug = n.replace(/\.md$/, '');
|
|
159
|
+
if (seen.has(slug))
|
|
160
|
+
continue;
|
|
161
|
+
seen.add(slug);
|
|
162
|
+
out.push({ slug, target });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// skip
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
export async function updateSkillsAll() {
|
|
172
|
+
const installed = getInstalledSkills();
|
|
173
|
+
const registry = await getRegistrySkills();
|
|
174
|
+
const bySlug = new Map(registry.map((s) => [s.slug, s]));
|
|
175
|
+
const updated = [];
|
|
176
|
+
const failed = [];
|
|
177
|
+
for (const { slug, target } of installed) {
|
|
178
|
+
if (!bySlug.has(slug))
|
|
179
|
+
continue;
|
|
180
|
+
const result = await installSkill(slug, target);
|
|
181
|
+
if (result.success)
|
|
182
|
+
updated.push(slug);
|
|
183
|
+
else
|
|
184
|
+
failed.push({ slug, error: result.error || 'unknown' });
|
|
185
|
+
}
|
|
186
|
+
return { updated, failed };
|
|
187
|
+
}
|
|
188
|
+
export async function getAvailableUpdates() {
|
|
189
|
+
const installed = getInstalledSkills();
|
|
190
|
+
const versions = loadInstalledVersions();
|
|
191
|
+
const registry = await getRegistrySkills();
|
|
192
|
+
const bySlug = new Map(registry.map((s) => [s.slug, s]));
|
|
193
|
+
const out = [];
|
|
194
|
+
for (const { slug } of installed) {
|
|
195
|
+
const reg = bySlug.get(slug);
|
|
196
|
+
const inst = versions[slug];
|
|
197
|
+
const instVer = inst?.version;
|
|
198
|
+
const regVer = reg?.version;
|
|
199
|
+
if (!regVer)
|
|
200
|
+
continue;
|
|
201
|
+
const updateAvailable = !instVer || compareVersions(instVer, regVer) < 0;
|
|
202
|
+
out.push({
|
|
203
|
+
slug,
|
|
204
|
+
installedVersion: instVer,
|
|
205
|
+
registryVersion: regVer,
|
|
206
|
+
updateAvailable,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return out.filter((u) => u.updateAvailable);
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=skill-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-install.js","sourceRoot":"","sources":["../../src/agent/skill-install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type SkillEntry = {
|
|
2
|
+
enabled?: boolean;
|
|
3
|
+
handle?: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
};
|
|
7
|
+
export type SkillsConfig = {
|
|
8
|
+
entries?: Record<string, SkillEntry>;
|
|
9
|
+
};
|
|
10
|
+
export type SulalaConfig = {
|
|
11
|
+
skills?: SkillsConfig;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
};
|
|
14
|
+
/** Config path: SULALA_CONFIG_PATH > .sulala/config.json in cwd (if exists) > ~/.sulala/config.json */
|
|
15
|
+
export declare function getConfigPath(): string;
|
|
16
|
+
export declare function loadFullConfig(): SulalaConfig;
|
|
17
|
+
export declare function saveFullConfig(data: SulalaConfig): void;
|
|
18
|
+
export declare function loadSkillsConfig(): SkillsConfig;
|
|
19
|
+
export declare function saveSkillsConfig(cfg: SkillsConfig): void;
|
|
20
|
+
export declare function isSkillEnabled(skillName: string): boolean;
|
|
21
|
+
export declare function setSkillEnabled(skillName: string, enabled: boolean): void;
|
|
22
|
+
/** Build env vars from all skill entries (key = env name, value = string). Used by run_command so curl etc. see PERIGON_API_KEY etc. */
|
|
23
|
+
export declare function getSkillConfigEnv(): Record<string, string>;
|
|
24
|
+
//# sourceMappingURL=skills-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-config.d.ts","sourceRoot":"","sources":["../../src/agent/skills-config.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAEzG,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAcF,uGAAuG;AACvG,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAWD,wBAAgB,cAAc,IAAI,YAAY,CAY7C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAKvD;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAgB/C;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAWxD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAKzD;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAMzE;AAED,wIAAwI;AACxI,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAW1D"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills config: single JSON file, no DB.
|
|
3
|
+
* Path: SULALA_CONFIG_PATH > .sulala/config.json in cwd (if exists) > ~/.sulala/config.json.
|
|
4
|
+
* Read: loadFullConfig/loadSkillsConfig from that path; cache invalidated on file mtime change.
|
|
5
|
+
* Write: saveFullConfig/saveSkillsConfig to the same path.
|
|
6
|
+
* See docs/CONFIG.md for full resolution and read/write flow.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, statSync } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
import { homedir } from 'os';
|
|
11
|
+
import { cwd } from 'process';
|
|
12
|
+
let cached = undefined;
|
|
13
|
+
let cachedPath = null;
|
|
14
|
+
let cachedMtime = 0;
|
|
15
|
+
/** Expand leading ~ to homedir; .env is loaded as-is so ~ is not expanded by the shell. */
|
|
16
|
+
function expandTilde(path) {
|
|
17
|
+
const s = path.trim();
|
|
18
|
+
if (s === '~')
|
|
19
|
+
return homedir();
|
|
20
|
+
if (s.startsWith('~/') || s.startsWith('~\\'))
|
|
21
|
+
return join(homedir(), s.slice(2));
|
|
22
|
+
return path;
|
|
23
|
+
}
|
|
24
|
+
/** Config path: SULALA_CONFIG_PATH > .sulala/config.json in cwd (if exists) > ~/.sulala/config.json */
|
|
25
|
+
export function getConfigPath() {
|
|
26
|
+
const fromEnv = process.env.SULALA_CONFIG_PATH;
|
|
27
|
+
if (fromEnv?.trim())
|
|
28
|
+
return expandTilde(fromEnv.trim());
|
|
29
|
+
const workspaceConfig = join(cwd(), '.sulala', 'config.json');
|
|
30
|
+
if (existsSync(workspaceConfig))
|
|
31
|
+
return workspaceConfig;
|
|
32
|
+
return join(homedir(), '.sulala', 'config.json');
|
|
33
|
+
}
|
|
34
|
+
function getConfigMtime(path) {
|
|
35
|
+
try {
|
|
36
|
+
if (!existsSync(path))
|
|
37
|
+
return 0;
|
|
38
|
+
return statSync(path).mtimeMs;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function loadFullConfig() {
|
|
45
|
+
try {
|
|
46
|
+
const path = getConfigPath();
|
|
47
|
+
if (!existsSync(path)) {
|
|
48
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
49
|
+
writeFileSync(path, '{}', 'utf8');
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function saveFullConfig(data) {
|
|
59
|
+
const path = getConfigPath();
|
|
60
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
61
|
+
writeFileSync(path, JSON.stringify(data, null, 2), 'utf8');
|
|
62
|
+
cached = undefined;
|
|
63
|
+
}
|
|
64
|
+
export function loadSkillsConfig() {
|
|
65
|
+
const path = getConfigPath();
|
|
66
|
+
const mtime = getConfigMtime(path);
|
|
67
|
+
if (cached !== undefined && cachedPath === path && cachedMtime === mtime) {
|
|
68
|
+
return cached ?? {};
|
|
69
|
+
}
|
|
70
|
+
cachedPath = path;
|
|
71
|
+
cachedMtime = mtime;
|
|
72
|
+
try {
|
|
73
|
+
const data = loadFullConfig();
|
|
74
|
+
cached = data.skills ?? {};
|
|
75
|
+
return cached ?? {};
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
cached = {};
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export function saveSkillsConfig(cfg) {
|
|
83
|
+
const full = loadFullConfig();
|
|
84
|
+
const existingEntries = full.skills?.entries ?? {};
|
|
85
|
+
const incomingEntries = cfg.entries ?? {};
|
|
86
|
+
const mergedEntries = { ...existingEntries };
|
|
87
|
+
for (const [name, entry] of Object.entries(incomingEntries)) {
|
|
88
|
+
mergedEntries[name] = { ...existingEntries[name], ...entry };
|
|
89
|
+
}
|
|
90
|
+
full.skills = { ...full.skills, entries: mergedEntries };
|
|
91
|
+
saveFullConfig(full);
|
|
92
|
+
cached = full.skills;
|
|
93
|
+
}
|
|
94
|
+
export function isSkillEnabled(skillName) {
|
|
95
|
+
const cfg = loadSkillsConfig();
|
|
96
|
+
const entry = cfg.entries?.[skillName];
|
|
97
|
+
if (!entry)
|
|
98
|
+
return true;
|
|
99
|
+
return entry.enabled !== false;
|
|
100
|
+
}
|
|
101
|
+
export function setSkillEnabled(skillName, enabled) {
|
|
102
|
+
const cfg = loadSkillsConfig();
|
|
103
|
+
if (!cfg.entries)
|
|
104
|
+
cfg.entries = {};
|
|
105
|
+
if (!cfg.entries[skillName])
|
|
106
|
+
cfg.entries[skillName] = {};
|
|
107
|
+
cfg.entries[skillName].enabled = enabled;
|
|
108
|
+
saveSkillsConfig(cfg);
|
|
109
|
+
}
|
|
110
|
+
/** Build env vars from all skill entries (key = env name, value = string). Used by run_command so curl etc. see PERIGON_API_KEY etc. */
|
|
111
|
+
export function getSkillConfigEnv() {
|
|
112
|
+
const cfg = loadSkillsConfig();
|
|
113
|
+
const out = {};
|
|
114
|
+
for (const entry of Object.values(cfg.entries ?? {})) {
|
|
115
|
+
if (!entry || typeof entry !== 'object')
|
|
116
|
+
continue;
|
|
117
|
+
for (const [key, value] of Object.entries(entry)) {
|
|
118
|
+
if (key === 'enabled')
|
|
119
|
+
continue;
|
|
120
|
+
if (typeof value === 'string' && value.trim())
|
|
121
|
+
out[key] = value;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=skills-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-config.js","sourceRoot":"","sources":["../../src/agent/skills-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type FSWatcher } from 'chokidar';
|
|
2
|
+
import type { Config } from '../types.js';
|
|
3
|
+
export declare function startSkillsWatcher(config: Config, onChanged: (event: {
|
|
4
|
+
type: 'skills_changed';
|
|
5
|
+
ts: number;
|
|
6
|
+
}) => void): FSWatcher | null;
|
|
7
|
+
//# sourceMappingURL=skills-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-watcher.d.ts","sourceRoot":"","sources":["../../src/agent/skills-watcher.ts"],"names":[],"mappings":"AAAA,OAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAGpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,GACjE,SAAS,GAAG,IAAI,CAsBlB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import chokidar from 'chokidar';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { getSkillPaths } from './skills.js';
|
|
4
|
+
let watcher = null;
|
|
5
|
+
export function startSkillsWatcher(config, onChanged) {
|
|
6
|
+
if (!config.skillsWatch)
|
|
7
|
+
return null;
|
|
8
|
+
if (watcher)
|
|
9
|
+
return watcher;
|
|
10
|
+
const paths = getSkillPaths(config).map((p) => p.path);
|
|
11
|
+
const dirs = paths.filter((p) => existsSync(p));
|
|
12
|
+
if (dirs.length === 0)
|
|
13
|
+
return null;
|
|
14
|
+
const debounceMs = 250;
|
|
15
|
+
let timer = null;
|
|
16
|
+
const fire = () => {
|
|
17
|
+
if (timer)
|
|
18
|
+
clearTimeout(timer);
|
|
19
|
+
timer = setTimeout(() => {
|
|
20
|
+
timer = null;
|
|
21
|
+
onChanged({ type: 'skills_changed', ts: Date.now() });
|
|
22
|
+
}, debounceMs);
|
|
23
|
+
};
|
|
24
|
+
watcher = chokidar.watch(dirs, {
|
|
25
|
+
ignoreInitial: true,
|
|
26
|
+
depth: 1,
|
|
27
|
+
ignored: (p) => !/\.(md|txt)$/.test(p),
|
|
28
|
+
});
|
|
29
|
+
watcher.on('add', fire).on('change', fire).on('unlink', fire);
|
|
30
|
+
return watcher;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=skills-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-watcher.js","sourceRoot":"","sources":["../../src/agent/skills-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,QAA4B,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,IAAI,OAAO,GAAqB,IAAI,CAAC;AAErC,MAAM,UAAU,kBAAkB,CAChC,MAAc,EACd,SAAkE;IAElE,IAAI,CAAC,MAAM,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,UAAU,GAAG,GAAG,CAAC;IACvB,IAAI,KAAK,GAAyC,IAAI,CAAC;IACvD,MAAM,IAAI,GAAG,GAAG,EAAE;QAChB,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YACtB,KAAK,GAAG,IAAI,CAAC;YACb,SAAS,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC,EAAE,UAAU,CAAC,CAAC;IACjB,CAAC,CAAC;IACF,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE;QAC7B,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE,CAAC;QACR,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;KACvC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9D,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Config } from '../types.js';
|
|
2
|
+
export type SkillStatus = 'eligible' | 'blocked' | 'unknown';
|
|
3
|
+
export type Skill = {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
filePath: string;
|
|
7
|
+
status: SkillStatus;
|
|
8
|
+
missing?: string[];
|
|
9
|
+
bins?: string[];
|
|
10
|
+
/** Required env vars from metadata sulala.requires.env (e.g. BSKY_HANDLE, BSKY_APP_PASSWORD). */
|
|
11
|
+
env?: string[];
|
|
12
|
+
source?: 'workspace' | 'managed' | 'bundled' | 'plugin' | 'extra';
|
|
13
|
+
};
|
|
14
|
+
export declare function validateSkillContent(content: string): {
|
|
15
|
+
valid: boolean;
|
|
16
|
+
name?: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
bins?: string[];
|
|
19
|
+
errors: string[];
|
|
20
|
+
};
|
|
21
|
+
/** Collect all required bins from enabled skills (for auto-merge with ALLOWED_BINARIES). */
|
|
22
|
+
export declare function getAllRequiredBins(config: Config): string[];
|
|
23
|
+
/** Paths in precedence order: workspace > managed > bundled > extra. */
|
|
24
|
+
export declare function getSkillPaths(config: Config): {
|
|
25
|
+
path: string;
|
|
26
|
+
source: Skill['source'];
|
|
27
|
+
}[];
|
|
28
|
+
/** List skills from all paths with precedence: workspace > managed > bundled > extra. By default filtered by skills.entries.<name>.enabled; set includeDisabled true to return all (e.g. for dashboard). */
|
|
29
|
+
export declare function listSkills(config: Config, options?: {
|
|
30
|
+
includeDisabled?: boolean;
|
|
31
|
+
}): Skill[];
|
|
32
|
+
//# sourceMappingURL=skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/agent/skills.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAE7D,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,iGAAiG;IACjG,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;CACnE,CAAC;AA2CF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG;IACrD,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAaA;AA+CD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAS3D;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;CAAE,EAAE,CAmBzF;AAyDD,4MAA4M;AAC5M,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,KAAK,EAAE,CAW3F"}
|