@percena/weft 0.4.0-next.2 → 0.4.0-next.4

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.
Files changed (50) hide show
  1. package/dist/action-bridge.cjs +180 -3
  2. package/dist/action-bridge.d.cts +112 -23
  3. package/dist/action-bridge.d.ts +112 -23
  4. package/dist/action-bridge.js +169 -2
  5. package/dist/chat.cjs +982 -3
  6. package/dist/chat.d.cts +30 -1
  7. package/dist/chat.d.ts +30 -1
  8. package/dist/chat.js +981 -2
  9. package/dist/index.cjs +341 -1616
  10. package/dist/index.d.cts +4 -274
  11. package/dist/index.d.ts +4 -274
  12. package/dist/index.js +174 -1408
  13. package/dist/styles/index.css +2 -212
  14. package/package.json +28 -55
  15. package/dist/auth.cjs +0 -241
  16. package/dist/auth.d.cts +0 -1
  17. package/dist/auth.d.ts +0 -1
  18. package/dist/auth.js +0 -208
  19. package/dist/automations.cjs +0 -3044
  20. package/dist/automations.d.cts +0 -4774
  21. package/dist/automations.d.ts +0 -4774
  22. package/dist/automations.js +0 -2965
  23. package/dist/factory.cjs +0 -5057
  24. package/dist/factory.d.cts +0 -7909
  25. package/dist/factory.d.ts +0 -7909
  26. package/dist/factory.js +0 -5008
  27. package/dist/local-runtime.cjs +0 -1387
  28. package/dist/local-runtime.d.cts +0 -3314
  29. package/dist/local-runtime.d.ts +0 -3314
  30. package/dist/local-runtime.js +0 -1345
  31. package/dist/providers.cjs +0 -6154
  32. package/dist/providers.d.cts +0 -6024
  33. package/dist/providers.d.ts +0 -6024
  34. package/dist/providers.js +0 -6110
  35. package/dist/server.cjs +0 -9137
  36. package/dist/server.d.cts +0 -9868
  37. package/dist/server.d.ts +0 -9868
  38. package/dist/server.js +0 -9118
  39. package/dist/skills-browser.cjs +0 -118
  40. package/dist/skills-browser.d.cts +0 -105
  41. package/dist/skills-browser.d.ts +0 -105
  42. package/dist/skills-browser.js +0 -88
  43. package/dist/skills.cjs +0 -505
  44. package/dist/skills.d.cts +0 -218
  45. package/dist/skills.d.ts +0 -218
  46. package/dist/skills.js +0 -458
  47. package/dist/sources.cjs +0 -1710
  48. package/dist/sources.d.cts +0 -3978
  49. package/dist/sources.d.ts +0 -3978
  50. package/dist/sources.js +0 -1675
package/dist/skills.js DELETED
@@ -1,458 +0,0 @@
1
- // ../packages/skills/dist/chunk-IAAI7RH5.js
2
- var AGENTS_PLUGIN_NAME = ".agents";
3
- function createSkillActivationPlan(options) {
4
- const enabledSources = new Set(options.enabledSourceSlugs ?? []);
5
- const selected = new Set(options.selectedSkillSlugs ?? []);
6
- const promptMentions = parseSkillMentions(options.prompt ?? "");
7
- const filePaths = options.filePaths ?? [];
8
- const activations = [];
9
- const seen = /* @__PURE__ */ new Set();
10
- for (const skill of options.skills) {
11
- const reason = activationReason(skill, {
12
- selected,
13
- promptMentions,
14
- filePaths
15
- });
16
- if (!reason || seen.has(skill.slug)) continue;
17
- seen.add(skill.slug);
18
- activations.push({ skill, reason });
19
- }
20
- const requiredSourceSlugs = unique(activations.flatMap(
21
- (activation) => activation.skill.metadata.requiredSources ?? []
22
- ));
23
- const missingRequiredSourceSlugs = requiredSourceSlugs.filter((source) => !enabledSources.has(source));
24
- const policyExtensions = activations.flatMap(({ skill }) => (skill.metadata.alwaysAllow ?? []).map((toolName) => ({
25
- toolName,
26
- scope: { type: "skill", skillSlug: skill.slug }
27
- })));
28
- const prerequisiteFiles = activations.map(({ skill }) => `${skill.path}/SKILL.md`).filter((path) => options.prerequisiteFileExists?.(path) ?? true);
29
- return {
30
- activeSkillSlugs: activations.map((activation) => activation.skill.slug),
31
- activations,
32
- requiredSourceSlugs,
33
- missingRequiredSourceSlugs,
34
- policyExtensions,
35
- providerInstructions: buildProviderInstructions(activations),
36
- prerequisiteFiles
37
- };
38
- }
39
- function activationReason(skill, context) {
40
- if (context.promptMentions.has(skill.slug)) return "prompt-mention";
41
- if (context.selected.has(skill.slug)) return "host-selection";
42
- if (matchesAnyGlob(skill.metadata.globs ?? [], context.filePaths)) return "file-glob";
43
- return void 0;
44
- }
45
- function parseSkillMentions(prompt) {
46
- const mentions = /* @__PURE__ */ new Set();
47
- for (const match of prompt.matchAll(/@([A-Za-z0-9_-]+)/g)) {
48
- mentions.add(match[1]);
49
- }
50
- return mentions;
51
- }
52
- function matchesAnyGlob(globs, filePaths) {
53
- return globs.some((glob) => filePaths.some((filePath) => globMatches(glob, filePath)));
54
- }
55
- function buildProviderInstructions(activations) {
56
- return activations.map(({ skill }) => `# ${skill.metadata.name}
57
-
58
- ${skill.content}`).join("\n\n");
59
- }
60
- function unique(values) {
61
- return [...new Set(values)];
62
- }
63
- function globMatches(pattern, value) {
64
- const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "__DOUBLE_STAR__").replace(/\*/g, "[^/]*").replace(/__DOUBLE_STAR__/g, ".*");
65
- return new RegExp(`^${escaped}$`).test(value);
66
- }
67
- function formatSkillDirective(prerequisiteFiles) {
68
- if (prerequisiteFiles.length === 0) return void 0;
69
- const fileList = prerequisiteFiles.map((f) => `- ${f}`).join("\n");
70
- return [
71
- "Before proceeding with the user's request, you MUST read the following skill instruction files:",
72
- fileList,
73
- "Do not take any other action until you have read these files."
74
- ].join("\n");
75
- }
76
- function prependSkillDirective(message, prerequisiteFiles) {
77
- const directive = formatSkillDirective(prerequisiteFiles);
78
- if (!directive) return message;
79
- return `${directive}
80
-
81
- ${message}`;
82
- }
83
-
84
- // ../packages/skills/dist/index.js
85
- import matter from "gray-matter";
86
- import {
87
- existsSync,
88
- mkdirSync,
89
- readFileSync,
90
- readdirSync,
91
- rmSync,
92
- statSync,
93
- writeFileSync
94
- } from "fs";
95
- import { homedir } from "os";
96
- import { join as join2 } from "path";
97
- import matter2 from "gray-matter";
98
- import { join } from "path";
99
- function validateSkillDefinitionContent(content, file = "SKILL.md") {
100
- const errors = [];
101
- const warnings = [];
102
- let parsed;
103
- try {
104
- parsed = matter(content);
105
- } catch (error) {
106
- errors.push(issue(
107
- file,
108
- "frontmatter",
109
- `Invalid skill frontmatter: ${error instanceof Error ? error.message : "Unknown error"}`,
110
- "error"
111
- ));
112
- return result(errors, warnings);
113
- }
114
- const data = parsed.data && typeof parsed.data === "object" ? parsed.data : {};
115
- if (!isNonEmptyString(data.name)) {
116
- errors.push(issue(file, "frontmatter.name", "Skill metadata requires name", "error"));
117
- }
118
- if (!isNonEmptyString(data.description)) {
119
- errors.push(issue(file, "frontmatter.description", "Skill metadata requires description", "error"));
120
- }
121
- validateStringArray(data.globs, "frontmatter.globs", file, errors);
122
- validateStringArray(data.alwaysAllow, "frontmatter.alwaysAllow", file, errors);
123
- validateRequiredSources(data.requiredSources, file, errors);
124
- if (!data.globs && !data.requiredSources) {
125
- warnings.push(issue(
126
- file,
127
- "frontmatter",
128
- "Skill has no activation metadata",
129
- "warning",
130
- "Add globs, requiredSources, or select the skill explicitly from the host UI."
131
- ));
132
- }
133
- if (!parsed.content.trim()) {
134
- warnings.push(issue(
135
- file,
136
- "content",
137
- "Skill body is empty",
138
- "warning",
139
- "Add provider instructions to make the skill useful when activated."
140
- ));
141
- }
142
- return result(errors, warnings);
143
- }
144
- function validateRequiredSources(value, file, errors) {
145
- if (value === void 0) return;
146
- if (typeof value === "string") return;
147
- validateStringArray(value, "frontmatter.requiredSources", file, errors);
148
- }
149
- function validateStringArray(value, path, file, errors) {
150
- if (value === void 0) return;
151
- if (!Array.isArray(value)) {
152
- errors.push(issue(file, path, `${leafName(path)} must be an array of strings`, "error"));
153
- return;
154
- }
155
- value.forEach((entry, index) => {
156
- if (typeof entry !== "string") {
157
- errors.push(issue(file, `${path}[${index}]`, `${leafName(path)} entries must be strings`, "error"));
158
- }
159
- });
160
- }
161
- function issue(file, path, message, severity, suggestion) {
162
- return {
163
- file,
164
- path,
165
- message,
166
- severity,
167
- ...suggestion ? { suggestion } : {}
168
- };
169
- }
170
- function result(errors, warnings) {
171
- return {
172
- valid: errors.length === 0,
173
- errors,
174
- warnings
175
- };
176
- }
177
- function isNonEmptyString(value) {
178
- return typeof value === "string" && value.trim().length > 0;
179
- }
180
- function leafName(path) {
181
- return path.split(".").at(-1) ?? path;
182
- }
183
- function getWorkspaceSkillsPath(workspaceRoot) {
184
- return join(workspaceRoot, "skills");
185
- }
186
- function validateIconValue(value, context) {
187
- if (value === void 0 || value === null) return void 0;
188
- if (typeof value !== "string") return void 0;
189
- if (/^[\p{Emoji}\u200d\ufe0f]+$/u.test(value)) return value;
190
- if (value.startsWith("http://") || value.startsWith("https://")) return value;
191
- console.warn(`[${context}] Invalid icon value: "${value}". Only emoji and URLs are supported.`);
192
- return void 0;
193
- }
194
- function findIconFile(dirPath) {
195
- return void 0;
196
- }
197
- async function downloadIcon(dirPath, iconUrl, context) {
198
- console.warn(`[${context}] Icon download stub: would download ${iconUrl}`);
199
- return null;
200
- }
201
- function needsIconDownload(icon, iconPath) {
202
- if (!icon) return false;
203
- if (icon.startsWith("http://") || icon.startsWith("https://")) {
204
- return !iconPath;
205
- }
206
- return false;
207
- }
208
- var GLOBAL_AGENT_SKILLS_DIR = join2(homedir(), ".agents", "skills");
209
- var PROJECT_AGENT_SKILLS_DIR = ".agents/skills";
210
- function normalizeRequiredSources(value) {
211
- const asArray = typeof value === "string" ? [value] : Array.isArray(value) ? value : void 0;
212
- if (!asArray) return void 0;
213
- const normalized = Array.from(new Set(
214
- asArray.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean)
215
- ));
216
- return normalized.length > 0 ? normalized : void 0;
217
- }
218
- function parseSkillFile(content) {
219
- try {
220
- const parsed = matter2(content);
221
- if (!parsed.data.name || !parsed.data.description) {
222
- return null;
223
- }
224
- const icon = validateIconValue(parsed.data.icon, "Skills");
225
- return {
226
- metadata: {
227
- name: parsed.data.name,
228
- description: parsed.data.description,
229
- globs: parsed.data.globs,
230
- alwaysAllow: parsed.data.alwaysAllow,
231
- icon,
232
- requiredSources: normalizeRequiredSources(parsed.data.requiredSources)
233
- },
234
- body: parsed.content
235
- };
236
- } catch {
237
- return null;
238
- }
239
- }
240
- function loadSkillFromDir(skillsDir, slug, source) {
241
- const skillDir = join2(skillsDir, slug);
242
- const skillFile = join2(skillDir, "SKILL.md");
243
- if (!existsSync(skillDir) || !statSync(skillDir).isDirectory()) {
244
- return null;
245
- }
246
- if (!existsSync(skillFile)) {
247
- return null;
248
- }
249
- let content;
250
- try {
251
- content = readFileSync(skillFile, "utf-8");
252
- } catch {
253
- return null;
254
- }
255
- const parsed = parseSkillFile(content);
256
- if (!parsed) {
257
- return null;
258
- }
259
- return {
260
- slug,
261
- metadata: parsed.metadata,
262
- content: parsed.body,
263
- iconPath: findIconFile(skillDir),
264
- path: skillDir,
265
- source
266
- };
267
- }
268
- function loadSkillsFromDir(skillsDir, source) {
269
- if (!existsSync(skillsDir)) {
270
- return [];
271
- }
272
- const skills = [];
273
- try {
274
- const entries = readdirSync(skillsDir, { withFileTypes: true });
275
- for (const entry of entries) {
276
- if (!entry.isDirectory()) continue;
277
- const skill = loadSkillFromDir(skillsDir, entry.name, source);
278
- if (skill) {
279
- skills.push(skill);
280
- }
281
- }
282
- } catch {
283
- }
284
- return skills;
285
- }
286
- function loadSkill(workspaceRoot, slug) {
287
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
288
- return loadSkillFromDir(skillsDir, slug, "workspace");
289
- }
290
- function loadWorkspaceSkills(workspaceRoot) {
291
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
292
- return loadSkillsFromDir(skillsDir, "workspace");
293
- }
294
- var skillsCache = /* @__PURE__ */ new Map();
295
- var SKILLS_CACHE_TTL = 5 * 6e4;
296
- function invalidateSkillsCache() {
297
- skillsCache.clear();
298
- }
299
- function loadAllSkills(workspaceRoot, projectRoot) {
300
- const cacheKey = `${workspaceRoot}::${projectRoot ?? ""}`;
301
- const now = Date.now();
302
- const cached = skillsCache.get(cacheKey);
303
- if (cached && now - cached.ts < SKILLS_CACHE_TTL) {
304
- return cached.skills;
305
- }
306
- const skillsBySlug = /* @__PURE__ */ new Map();
307
- for (const skill of loadSkillsFromDir(GLOBAL_AGENT_SKILLS_DIR, "global")) {
308
- skillsBySlug.set(skill.slug, skill);
309
- }
310
- for (const skill of loadWorkspaceSkills(workspaceRoot)) {
311
- skillsBySlug.set(skill.slug, skill);
312
- }
313
- if (projectRoot) {
314
- const projectSkillsDir = join2(projectRoot, PROJECT_AGENT_SKILLS_DIR);
315
- for (const skill of loadSkillsFromDir(projectSkillsDir, "project")) {
316
- skillsBySlug.set(skill.slug, skill);
317
- }
318
- }
319
- const result2 = Array.from(skillsBySlug.values());
320
- skillsCache.set(cacheKey, { skills: result2, ts: now });
321
- return result2;
322
- }
323
- function loadSkillBySlug(workspaceRoot, slug, projectRoot) {
324
- if (projectRoot) {
325
- const projectSkillsDir = join2(projectRoot, PROJECT_AGENT_SKILLS_DIR);
326
- const skill = loadSkillFromDir(projectSkillsDir, slug, "project");
327
- if (skill) return skill;
328
- }
329
- const workspaceSkill = loadSkillFromDir(getWorkspaceSkillsPath(workspaceRoot), slug, "workspace");
330
- if (workspaceSkill) return workspaceSkill;
331
- return loadSkillFromDir(GLOBAL_AGENT_SKILLS_DIR, slug, "global");
332
- }
333
- function getSkillIconPath(workspaceRoot, slug) {
334
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
335
- const skillDir = join2(skillsDir, slug);
336
- if (!existsSync(skillDir)) {
337
- return null;
338
- }
339
- return findIconFile(skillDir) || null;
340
- }
341
- function deleteSkill(workspaceRoot, slug) {
342
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
343
- const skillDir = join2(skillsDir, slug);
344
- if (!existsSync(skillDir)) {
345
- return false;
346
- }
347
- try {
348
- rmSync(skillDir, { recursive: true });
349
- return true;
350
- } catch {
351
- return false;
352
- }
353
- }
354
- function createSkill(workspaceRoot, input) {
355
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
356
- const skillDir = join2(skillsDir, input.slug);
357
- const skillFile = join2(skillDir, "SKILL.md");
358
- const frontmatter = {
359
- name: input.name,
360
- description: input.description
361
- };
362
- if (input.globs) frontmatter.globs = input.globs;
363
- if (input.alwaysAllow) frontmatter.alwaysAllow = input.alwaysAllow;
364
- if (input.icon) {
365
- const validated = validateIconValue(input.icon, "Skills");
366
- if (validated) frontmatter.icon = validated;
367
- }
368
- if (input.requiredSources) frontmatter.requiredSources = input.requiredSources;
369
- const fileContent = matter2.stringify(input.content, frontmatter);
370
- mkdirSync(skillDir, { recursive: true });
371
- writeFileSync(skillFile, fileContent, "utf-8");
372
- invalidateSkillsCache();
373
- const loaded = loadSkillFromDir(skillsDir, input.slug, "workspace");
374
- if (!loaded) {
375
- throw new Error(`Failed to load newly created skill: ${input.slug}`);
376
- }
377
- return loaded;
378
- }
379
- function updateSkill(workspaceRoot, slug, patch) {
380
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
381
- const existing = loadSkillFromDir(skillsDir, slug, "workspace");
382
- if (!existing) {
383
- throw new Error(`Skill not found: ${slug}`);
384
- }
385
- const frontmatter = {
386
- name: patch.name ?? existing.metadata.name,
387
- description: patch.description ?? existing.metadata.description
388
- };
389
- const globs = patch.globs ?? existing.metadata.globs;
390
- if (globs) frontmatter.globs = globs;
391
- const alwaysAllow = patch.alwaysAllow ?? existing.metadata.alwaysAllow;
392
- if (alwaysAllow) frontmatter.alwaysAllow = alwaysAllow;
393
- const icon = patch.icon ?? existing.metadata.icon;
394
- if (icon) {
395
- const validated = validateIconValue(icon, "Skills");
396
- if (validated) frontmatter.icon = validated;
397
- }
398
- const requiredSources = patch.requiredSources ?? existing.metadata.requiredSources;
399
- if (requiredSources) frontmatter.requiredSources = requiredSources;
400
- const content = patch.content ?? existing.content;
401
- const fileContent = matter2.stringify(content, frontmatter);
402
- const skillFile = join2(skillsDir, slug, "SKILL.md");
403
- writeFileSync(skillFile, fileContent, "utf-8");
404
- invalidateSkillsCache();
405
- const loaded = loadSkillFromDir(skillsDir, slug, "workspace");
406
- if (!loaded) {
407
- throw new Error(`Failed to load updated skill: ${slug}`);
408
- }
409
- return loaded;
410
- }
411
- function skillExists(workspaceRoot, slug) {
412
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
413
- const skillDir = join2(skillsDir, slug);
414
- const skillFile = join2(skillDir, "SKILL.md");
415
- return existsSync(skillDir) && existsSync(skillFile);
416
- }
417
- function listSkillSlugs(workspaceRoot) {
418
- const skillsDir = getWorkspaceSkillsPath(workspaceRoot);
419
- if (!existsSync(skillsDir)) {
420
- return [];
421
- }
422
- try {
423
- return readdirSync(skillsDir, { withFileTypes: true }).filter((entry) => {
424
- if (!entry.isDirectory()) return false;
425
- const skillFile = join2(skillsDir, entry.name, "SKILL.md");
426
- return existsSync(skillFile);
427
- }).map((entry) => entry.name);
428
- } catch {
429
- return [];
430
- }
431
- }
432
- async function downloadSkillIcon(skillDir, iconUrl) {
433
- return downloadIcon(skillDir, iconUrl, "Skills");
434
- }
435
- function skillNeedsIconDownload(skill) {
436
- return needsIconDownload(skill.metadata.icon, skill.iconPath);
437
- }
438
- export {
439
- AGENTS_PLUGIN_NAME,
440
- GLOBAL_AGENT_SKILLS_DIR,
441
- PROJECT_AGENT_SKILLS_DIR,
442
- createSkill,
443
- createSkillActivationPlan,
444
- deleteSkill,
445
- downloadSkillIcon,
446
- formatSkillDirective,
447
- getSkillIconPath,
448
- invalidateSkillsCache,
449
- listSkillSlugs,
450
- loadAllSkills,
451
- loadSkill,
452
- loadSkillBySlug,
453
- prependSkillDirective,
454
- skillExists,
455
- skillNeedsIconDownload,
456
- updateSkill,
457
- validateSkillDefinitionContent
458
- };