@poping/yome 0.0.2 → 0.0.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/LICENSE +202 -0
- package/NOTICE +11 -0
- package/README.md +308 -27
- package/README.zh-CN.md +335 -0
- package/dist/agent.d.ts +24 -2
- package/dist/agent.js +34 -2
- package/dist/agent.js.map +1 -1
- package/dist/context.d.ts +2 -0
- package/dist/context.js +116 -11
- package/dist/context.js.map +1 -1
- package/dist/index.js +147 -9
- package/dist/index.js.map +1 -1
- package/dist/llm.js +45 -2
- package/dist/llm.js.map +1 -1
- package/dist/loops/chain.js +8 -0
- package/dist/loops/chain.js.map +1 -1
- package/dist/loops/evaluator.js +8 -0
- package/dist/loops/evaluator.js.map +1 -1
- package/dist/loops/orchestrator.js +8 -0
- package/dist/loops/orchestrator.js.map +1 -1
- package/dist/loops/parallel.js.map +1 -1
- package/dist/loops/route.js +8 -0
- package/dist/loops/route.js.map +1 -1
- package/dist/loops/simple.js +15 -0
- package/dist/loops/simple.js.map +1 -1
- package/dist/permissions/index.d.ts +1 -1
- package/dist/permissions/index.js +1 -1
- package/dist/permissions/index.js.map +1 -1
- package/dist/permissions/loader.d.ts +20 -1
- package/dist/permissions/loader.js +51 -0
- package/dist/permissions/loader.js.map +1 -1
- package/dist/redact.d.ts +56 -0
- package/dist/redact.js +191 -0
- package/dist/redact.js.map +1 -0
- package/dist/skills/runner/applescript.d.ts +49 -0
- package/dist/skills/runner/applescript.js +100 -0
- package/dist/skills/runner/applescript.js.map +1 -0
- package/dist/skills/runner/dispatcher.d.ts +57 -0
- package/dist/skills/runner/dispatcher.js +407 -0
- package/dist/skills/runner/dispatcher.js.map +1 -0
- package/dist/skills/runner/kernel.d.ts +8 -0
- package/dist/skills/runner/kernel.js +732 -0
- package/dist/skills/runner/kernel.js.map +1 -0
- package/dist/skills/runner/tokenizer.d.ts +36 -0
- package/dist/skills/runner/tokenizer.js +177 -0
- package/dist/skills/runner/tokenizer.js.map +1 -0
- package/dist/threadCli.d.ts +11 -0
- package/dist/threadCli.js +177 -0
- package/dist/threadCli.js.map +1 -0
- package/dist/threadShare.d.ts +21 -0
- package/dist/threadShare.js +121 -0
- package/dist/threadShare.js.map +1 -0
- package/dist/threadSubmit.d.ts +32 -0
- package/dist/threadSubmit.js +199 -0
- package/dist/threadSubmit.js.map +1 -0
- package/dist/tools/bash.js +68 -13
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/index.d.ts +22 -2
- package/dist/tools/index.js +41 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/skillCall.d.ts +2 -0
- package/dist/tools/skillCall.js +77 -0
- package/dist/tools/skillCall.js.map +1 -0
- package/dist/ui/AgentPicker.js +3 -3
- package/dist/ui/AgentPicker.js.map +1 -1
- package/dist/ui/App.js +214 -61
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/Banner.d.ts +2 -1
- package/dist/ui/Banner.js +23 -4
- package/dist/ui/Banner.js.map +1 -1
- package/dist/ui/InputBar.js +6 -3
- package/dist/ui/InputBar.js.map +1 -1
- package/dist/ui/Markdown.d.ts +2 -2
- package/dist/ui/Markdown.js +22 -7
- package/dist/ui/Markdown.js.map +1 -1
- package/dist/ui/MarketplacePicker.d.ts +7 -0
- package/dist/ui/MarketplacePicker.js +122 -0
- package/dist/ui/MarketplacePicker.js.map +1 -0
- package/dist/ui/MessageList.d.ts +4 -1
- package/dist/ui/MessageList.js +72 -7
- package/dist/ui/MessageList.js.map +1 -1
- package/dist/ui/ModelPicker.js +4 -4
- package/dist/ui/ModelPicker.js.map +1 -1
- package/dist/ui/PermissionPrompt.d.ts +16 -4
- package/dist/ui/PermissionPrompt.js +60 -15
- package/dist/ui/PermissionPrompt.js.map +1 -1
- package/dist/ui/SessionPicker.js +2 -2
- package/dist/ui/SessionPicker.js.map +1 -1
- package/dist/ui/ShimmerText.d.ts +8 -0
- package/dist/ui/ShimmerText.js +40 -0
- package/dist/ui/ShimmerText.js.map +1 -0
- package/dist/ui/Spinner.js +3 -9
- package/dist/ui/Spinner.js.map +1 -1
- package/dist/ui/TogglePicker.js +4 -4
- package/dist/ui/TogglePicker.js.map +1 -1
- package/dist/ui/ToolResult.js +6 -0
- package/dist/ui/ToolResult.js.map +1 -1
- package/dist/ui/UnifiedSkillsPicker.d.ts +10 -0
- package/dist/ui/UnifiedSkillsPicker.js +63 -0
- package/dist/ui/UnifiedSkillsPicker.js.map +1 -0
- package/dist/ui/animation.d.ts +3 -0
- package/dist/ui/animation.js +48 -0
- package/dist/ui/animation.js.map +1 -0
- package/dist/ui/useThrottledStream.d.ts +7 -0
- package/dist/ui/useThrottledStream.js +63 -0
- package/dist/ui/useThrottledStream.js.map +1 -0
- package/dist/yomeSkills/auth.d.ts +20 -0
- package/dist/yomeSkills/auth.js +70 -0
- package/dist/yomeSkills/auth.js.map +1 -0
- package/dist/yomeSkills/blacklist.d.ts +33 -0
- package/dist/yomeSkills/blacklist.js +101 -0
- package/dist/yomeSkills/blacklist.js.map +1 -0
- package/dist/yomeSkills/capabilities.d.ts +54 -0
- package/dist/yomeSkills/capabilities.js +175 -0
- package/dist/yomeSkills/capabilities.js.map +1 -0
- package/dist/yomeSkills/capabilityGuard.d.ts +31 -0
- package/dist/yomeSkills/capabilityGuard.js +113 -0
- package/dist/yomeSkills/capabilityGuard.js.map +1 -0
- package/dist/yomeSkills/cli.d.ts +17 -0
- package/dist/yomeSkills/cli.js +477 -0
- package/dist/yomeSkills/cli.js.map +1 -0
- package/dist/yomeSkills/devLink.d.ts +17 -0
- package/dist/yomeSkills/devLink.js +91 -0
- package/dist/yomeSkills/devLink.js.map +1 -0
- package/dist/yomeSkills/doctor.d.ts +13 -0
- package/dist/yomeSkills/doctor.js +152 -0
- package/dist/yomeSkills/doctor.js.map +1 -0
- package/dist/yomeSkills/enable.d.ts +8 -0
- package/dist/yomeSkills/enable.js +67 -0
- package/dist/yomeSkills/enable.js.map +1 -0
- package/dist/yomeSkills/hubPing.d.ts +1 -0
- package/dist/yomeSkills/hubPing.js +41 -0
- package/dist/yomeSkills/hubPing.js.map +1 -0
- package/dist/yomeSkills/install.d.ts +18 -0
- package/dist/yomeSkills/install.js +143 -0
- package/dist/yomeSkills/install.js.map +1 -0
- package/dist/yomeSkills/installGithub.d.ts +26 -0
- package/dist/yomeSkills/installGithub.js +192 -0
- package/dist/yomeSkills/installGithub.js.map +1 -0
- package/dist/yomeSkills/installMeta.d.ts +8 -0
- package/dist/yomeSkills/installMeta.js +76 -0
- package/dist/yomeSkills/installMeta.js.map +1 -0
- package/dist/yomeSkills/integrity.d.ts +26 -0
- package/dist/yomeSkills/integrity.js +107 -0
- package/dist/yomeSkills/integrity.js.map +1 -0
- package/dist/yomeSkills/invoke.d.ts +29 -0
- package/dist/yomeSkills/invoke.js +103 -0
- package/dist/yomeSkills/invoke.js.map +1 -0
- package/dist/yomeSkills/list.d.ts +11 -0
- package/dist/yomeSkills/list.js +55 -0
- package/dist/yomeSkills/list.js.map +1 -0
- package/dist/yomeSkills/login.d.ts +41 -0
- package/dist/yomeSkills/login.js +221 -0
- package/dist/yomeSkills/login.js.map +1 -0
- package/dist/yomeSkills/manifest.d.ts +60 -0
- package/dist/yomeSkills/manifest.js +47 -0
- package/dist/yomeSkills/manifest.js.map +1 -0
- package/dist/yomeSkills/paths.d.ts +13 -0
- package/dist/yomeSkills/paths.js +33 -0
- package/dist/yomeSkills/paths.js.map +1 -0
- package/dist/yomeSkills/publish.d.ts +16 -0
- package/dist/yomeSkills/publish.js +109 -0
- package/dist/yomeSkills/publish.js.map +1 -0
- package/dist/yomeSkills/rollback.d.ts +10 -0
- package/dist/yomeSkills/rollback.js +83 -0
- package/dist/yomeSkills/rollback.js.map +1 -0
- package/dist/yomeSkills/search.d.ts +21 -0
- package/dist/yomeSkills/search.js +31 -0
- package/dist/yomeSkills/search.js.map +1 -0
- package/dist/yomeSkills/skillsIndex.d.ts +36 -0
- package/dist/yomeSkills/skillsIndex.js +111 -0
- package/dist/yomeSkills/skillsIndex.js.map +1 -0
- package/dist/yomeSkills/unified.d.ts +53 -0
- package/dist/yomeSkills/unified.js +187 -0
- package/dist/yomeSkills/unified.js.map +1 -0
- package/dist/yomeSkills/uninstall.d.ts +7 -0
- package/dist/yomeSkills/uninstall.js +22 -0
- package/dist/yomeSkills/uninstall.js.map +1 -0
- package/dist/yomeSkills/update.d.ts +18 -0
- package/dist/yomeSkills/update.js +75 -0
- package/dist/yomeSkills/update.js.map +1 -0
- package/dist/yomeSkills/validate.d.ts +11 -0
- package/dist/yomeSkills/validate.js +99 -0
- package/dist/yomeSkills/validate.js.map +1 -0
- package/package.json +14 -5
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// `yome skill rollback <slug>` — swap back to the previous version.
|
|
2
|
+
//
|
|
3
|
+
// Spec 11.4-D requires "保留最近 2 个版本目录" — we keep one snapshot
|
|
4
|
+
// (`<slug-dir>.previous/`) created by `install.ts` whenever it overwrites
|
|
5
|
+
// an existing install. This module performs the atomic swap:
|
|
6
|
+
//
|
|
7
|
+
// live : ~/.yome/skills/<owner>/<name> (current)
|
|
8
|
+
// prev : ~/.yome/skills/<owner>/<name>.previous (last good)
|
|
9
|
+
//
|
|
10
|
+
// rollback:
|
|
11
|
+
// prev → swap-tmp → live (i.e. live becomes previous, previous becomes live)
|
|
12
|
+
//
|
|
13
|
+
// After rollback the swap-tmp now holds what was live; we move it to the
|
|
14
|
+
// `.previous` slot so the user can also rollback the rollback (one level
|
|
15
|
+
// of undo, capped to keep disk usage bounded).
|
|
16
|
+
//
|
|
17
|
+
// Edge cases:
|
|
18
|
+
// - No `.previous` snapshot present → tell the user, exit cleanly.
|
|
19
|
+
// - Live install was uninstalled (no live dir) → restore previous in place.
|
|
20
|
+
// - Allowed-capabilities sidecar lives INSIDE the install dir, so it
|
|
21
|
+
// swaps with the rest. No extra work needed.
|
|
22
|
+
// - Index cache may now be stale → we refresh it.
|
|
23
|
+
import { existsSync, renameSync, rmSync, mkdirSync } from 'fs';
|
|
24
|
+
import { dirname } from 'path';
|
|
25
|
+
import { installPathForSlug } from './paths.js';
|
|
26
|
+
import { readManifest } from './manifest.js';
|
|
27
|
+
import { refreshIndex } from './skillsIndex.js';
|
|
28
|
+
export async function rollbackBySlug(slug) {
|
|
29
|
+
const live = installPathForSlug(slug);
|
|
30
|
+
if (!live)
|
|
31
|
+
return { ok: false, reason: `bad slug: ${slug}` };
|
|
32
|
+
const snap = `${live}.previous`;
|
|
33
|
+
if (!existsSync(snap)) {
|
|
34
|
+
return { ok: false, reason: `no rollback snapshot for ${slug} — nothing to roll back to` };
|
|
35
|
+
}
|
|
36
|
+
// Capture versions for the report (best-effort; manifest read is cheap).
|
|
37
|
+
const liveManifest = existsSync(live) ? readManifest(live) : null;
|
|
38
|
+
const prevManifest = readManifest(snap);
|
|
39
|
+
const previousVersion = liveManifest?.version;
|
|
40
|
+
const restoredVersion = prevManifest?.version;
|
|
41
|
+
// Atomic-ish swap. We need a temporary intermediate name because
|
|
42
|
+
// renameSync(live, snap) when snap already exists is destructive on POSIX.
|
|
43
|
+
// Sequence:
|
|
44
|
+
// 1. live → tmp
|
|
45
|
+
// 2. snap → live
|
|
46
|
+
// 3. tmp → snap (overwrite-protected: we rmSync first if it exists,
|
|
47
|
+
// though step 2 just moved it away)
|
|
48
|
+
const tmp = `${live}.swap-${process.pid}-${Date.now()}`;
|
|
49
|
+
try {
|
|
50
|
+
if (existsSync(live)) {
|
|
51
|
+
mkdirSync(dirname(live), { recursive: true });
|
|
52
|
+
renameSync(live, tmp);
|
|
53
|
+
}
|
|
54
|
+
renameSync(snap, live);
|
|
55
|
+
if (existsSync(tmp)) {
|
|
56
|
+
// step 3: archive what was live as the new previous
|
|
57
|
+
if (existsSync(snap))
|
|
58
|
+
rmSync(snap, { recursive: true, force: true });
|
|
59
|
+
renameSync(tmp, snap);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
// Best-effort recovery: try to put live back if we moved it but failed
|
|
64
|
+
// to install snap. Don't pretend everything is fine.
|
|
65
|
+
try {
|
|
66
|
+
if (existsSync(tmp) && !existsSync(live))
|
|
67
|
+
renameSync(tmp, live);
|
|
68
|
+
}
|
|
69
|
+
catch { /* ignore */ }
|
|
70
|
+
return { ok: false, slug, reason: `rename failed during rollback: ${err.message}` };
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
refreshIndex();
|
|
74
|
+
}
|
|
75
|
+
catch { /* best effort */ }
|
|
76
|
+
return {
|
|
77
|
+
ok: true,
|
|
78
|
+
slug,
|
|
79
|
+
restoredVersion,
|
|
80
|
+
previousVersion,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=rollback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollback.js","sourceRoot":"","sources":["../../src/yomeSkills/rollback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface SearchHit {
|
|
2
|
+
slug: string;
|
|
3
|
+
domain: string;
|
|
4
|
+
name: string | null;
|
|
5
|
+
description: string | null;
|
|
6
|
+
is_official: boolean;
|
|
7
|
+
star_count: number;
|
|
8
|
+
install_count: number;
|
|
9
|
+
github_full_name: string | null;
|
|
10
|
+
latest_version: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface SearchOptions {
|
|
13
|
+
hubBase?: string;
|
|
14
|
+
limit?: number;
|
|
15
|
+
fetcher?: typeof fetch;
|
|
16
|
+
}
|
|
17
|
+
export declare function searchHub(query: string, opts?: SearchOptions): Promise<{
|
|
18
|
+
ok: boolean;
|
|
19
|
+
hits: SearchHit[];
|
|
20
|
+
reason?: string;
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// `yome skill search <query>` — call the hub's catalogue and render
|
|
2
|
+
// either a table or JSON.
|
|
3
|
+
const DEFAULT_HUB_BASE = 'https://yome.work';
|
|
4
|
+
export async function searchHub(query, opts = {}) {
|
|
5
|
+
const hubBase = (opts.hubBase ?? process.env.YOME_HUB_BASE ?? DEFAULT_HUB_BASE).replace(/\/$/, '');
|
|
6
|
+
const limit = opts.limit ?? 25;
|
|
7
|
+
const url = `${hubBase}/api/hub/skills?q=${encodeURIComponent(query)}&limit=${limit}`;
|
|
8
|
+
const fetcher = opts.fetcher ?? fetch;
|
|
9
|
+
let resp;
|
|
10
|
+
try {
|
|
11
|
+
resp = await fetcher(url, { headers: { Accept: 'application/json', 'User-Agent': 'yome-cli/0.1' } });
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
return { ok: false, hits: [], reason: `network error: ${e.message}` };
|
|
15
|
+
}
|
|
16
|
+
if (!resp.ok) {
|
|
17
|
+
return { ok: false, hits: [], reason: `hub returned HTTP ${resp.status}` };
|
|
18
|
+
}
|
|
19
|
+
let body;
|
|
20
|
+
try {
|
|
21
|
+
body = await resp.json();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return { ok: false, hits: [], reason: 'invalid JSON from hub' };
|
|
25
|
+
}
|
|
26
|
+
const arr = Array.isArray(body) ? body
|
|
27
|
+
: (body && typeof body === 'object' && 'hits' in body && Array.isArray(body.hits))
|
|
28
|
+
? body.hits : [];
|
|
29
|
+
return { ok: true, hits: arr };
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/yomeSkills/search.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,0BAA0B;AAoB1B,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAa,EAAE,OAAsB,EAAE;IACrE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,GAAG,OAAO,qBAAqB,kBAAkB,CAAC,KAAK,CAAC,UAAU,KAAK,EAAE,CAAC;IACtF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACtC,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;IACvG,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,kBAAmB,CAAW,CAAC,OAAO,EAAE,EAAE,CAAC;IACnF,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,qBAAqB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IAC7E,CAAC;IACD,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QAAC,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAAC,CAAC;IAC5G,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;QACpC,CAAC,CAAC,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAE,IAA0B,CAAC,IAAI,CAAC,CAAC;YACvG,CAAC,CAAE,IAA8B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAkB,EAAE,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface SkillIndexEntry {
|
|
2
|
+
slug: string;
|
|
3
|
+
domain: string;
|
|
4
|
+
version: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
installedAt: string;
|
|
8
|
+
status: 'enabled' | 'disabled';
|
|
9
|
+
is_dev_link: boolean;
|
|
10
|
+
/** What the manifest declares it needs. */
|
|
11
|
+
declared_capabilities: string[];
|
|
12
|
+
/** What the user has granted (subset of declared). */
|
|
13
|
+
allowed_capabilities: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface SkillIndex {
|
|
16
|
+
version: 1;
|
|
17
|
+
built_at: string;
|
|
18
|
+
skills: SkillIndexEntry[];
|
|
19
|
+
}
|
|
20
|
+
export declare function getIndexPath(): string;
|
|
21
|
+
/** Build a fresh index by walking the filesystem. */
|
|
22
|
+
export declare function rebuildIndex(): SkillIndex;
|
|
23
|
+
export declare function writeIndex(idx: SkillIndex): void;
|
|
24
|
+
/** Convenience: rebuild + persist. Call from install / uninstall / enable / disable / link / unlink. */
|
|
25
|
+
export declare function refreshIndex(): SkillIndex;
|
|
26
|
+
/**
|
|
27
|
+
* Read the index from disk. Returns null on any error so the caller can
|
|
28
|
+
* fall back to a full walk via `rebuildIndex()`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function readIndex(): SkillIndex | null;
|
|
31
|
+
/**
|
|
32
|
+
* Get the canonical list of installed skills:
|
|
33
|
+
* - If the index is present and parseable, use it (fast path).
|
|
34
|
+
* - Otherwise, walk the filesystem and silently rebuild the index.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getInstalledFast(): SkillIndexEntry[];
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// skillsIndex.ts — fast lookup table for installed skills.
|
|
2
|
+
//
|
|
3
|
+
// Background: `listInstalled()` walks ~/.yome/skills/<owner>/<name>/
|
|
4
|
+
// and parses every yome-skill.json on every call. With 20+ installed
|
|
5
|
+
// skills + every CLI invocation reloading the agent, that's a measurable
|
|
6
|
+
// startup cost.
|
|
7
|
+
//
|
|
8
|
+
// We maintain a sidecar at ~/.yome/skills/.index.json that mirrors a
|
|
9
|
+
// summary of every install. The CLI updates the index whenever it
|
|
10
|
+
// installs / uninstalls / enables / disables / links / unlinks.
|
|
11
|
+
//
|
|
12
|
+
// The index is treated as a CACHE, not source of truth: any consumer
|
|
13
|
+
// that detects corruption falls back to a full directory walk. Callers
|
|
14
|
+
// who want to be sure the index is current call `rebuildIndex()`.
|
|
15
|
+
//
|
|
16
|
+
// Schema (forward-compatible — missing fields are filled in by reload):
|
|
17
|
+
//
|
|
18
|
+
// {
|
|
19
|
+
// version: 1,
|
|
20
|
+
// built_at: ISO,
|
|
21
|
+
// skills: [
|
|
22
|
+
// { slug, domain, version, name?, description?,
|
|
23
|
+
// installedAt, status: 'enabled'|'disabled',
|
|
24
|
+
// is_dev_link, declared_capabilities, allowed_capabilities }
|
|
25
|
+
// ]
|
|
26
|
+
// }
|
|
27
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, lstatSync } from 'node:fs';
|
|
28
|
+
import { dirname, join } from 'node:path';
|
|
29
|
+
import { listInstalled } from './list.js';
|
|
30
|
+
import { isSkillDisabled } from './enable.js';
|
|
31
|
+
import { readAllowedCapabilities, normaliseDeclared } from './capabilities.js';
|
|
32
|
+
import { getYomeSkillsRoot } from './paths.js';
|
|
33
|
+
export function getIndexPath() {
|
|
34
|
+
return join(getYomeSkillsRoot(), '.index.json');
|
|
35
|
+
}
|
|
36
|
+
/** Build a fresh index by walking the filesystem. */
|
|
37
|
+
export function rebuildIndex() {
|
|
38
|
+
const installed = listInstalled();
|
|
39
|
+
const skills = installed.map((e) => {
|
|
40
|
+
const declared = normaliseDeclared(e.manifest.system_capabilities);
|
|
41
|
+
const allowed = readAllowedCapabilities(e.slug)?.allowed ?? [];
|
|
42
|
+
let isLink = false;
|
|
43
|
+
try {
|
|
44
|
+
isLink = lstatSync(e.installedAt).isSymbolicLink();
|
|
45
|
+
}
|
|
46
|
+
catch { /* ignore */ }
|
|
47
|
+
return {
|
|
48
|
+
slug: e.slug,
|
|
49
|
+
domain: e.domain,
|
|
50
|
+
version: e.version,
|
|
51
|
+
name: e.name,
|
|
52
|
+
description: e.description,
|
|
53
|
+
installedAt: e.installedAt,
|
|
54
|
+
status: isSkillDisabled(e.slug) ? 'disabled' : 'enabled',
|
|
55
|
+
is_dev_link: isLink,
|
|
56
|
+
declared_capabilities: declared,
|
|
57
|
+
allowed_capabilities: allowed,
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
const idx = {
|
|
61
|
+
version: 1,
|
|
62
|
+
built_at: new Date().toISOString(),
|
|
63
|
+
skills,
|
|
64
|
+
};
|
|
65
|
+
return idx;
|
|
66
|
+
}
|
|
67
|
+
export function writeIndex(idx) {
|
|
68
|
+
const f = getIndexPath();
|
|
69
|
+
mkdirSync(dirname(f), { recursive: true });
|
|
70
|
+
writeFileSync(f, JSON.stringify(idx, null, 2) + '\n');
|
|
71
|
+
}
|
|
72
|
+
/** Convenience: rebuild + persist. Call from install / uninstall / enable / disable / link / unlink. */
|
|
73
|
+
export function refreshIndex() {
|
|
74
|
+
const idx = rebuildIndex();
|
|
75
|
+
writeIndex(idx);
|
|
76
|
+
return idx;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Read the index from disk. Returns null on any error so the caller can
|
|
80
|
+
* fall back to a full walk via `rebuildIndex()`.
|
|
81
|
+
*/
|
|
82
|
+
export function readIndex() {
|
|
83
|
+
const f = getIndexPath();
|
|
84
|
+
if (!existsSync(f))
|
|
85
|
+
return null;
|
|
86
|
+
try {
|
|
87
|
+
const obj = JSON.parse(readFileSync(f, 'utf-8'));
|
|
88
|
+
if (!obj || typeof obj !== 'object')
|
|
89
|
+
return null;
|
|
90
|
+
if (obj.version !== 1)
|
|
91
|
+
return null;
|
|
92
|
+
if (!Array.isArray(obj.skills))
|
|
93
|
+
return null;
|
|
94
|
+
return obj;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get the canonical list of installed skills:
|
|
102
|
+
* - If the index is present and parseable, use it (fast path).
|
|
103
|
+
* - Otherwise, walk the filesystem and silently rebuild the index.
|
|
104
|
+
*/
|
|
105
|
+
export function getInstalledFast() {
|
|
106
|
+
const idx = readIndex();
|
|
107
|
+
if (idx)
|
|
108
|
+
return idx.skills;
|
|
109
|
+
return refreshIndex().skills;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=skillsIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillsIndex.js","sourceRoot":"","sources":["../../src/yomeSkills/skillsIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Skill as PromptSkill } from '../skills/types.js';
|
|
2
|
+
export type UnifiedSkillKind = 'prompt' | 'hub';
|
|
3
|
+
export type PromptOrigin = 'yome-user' | 'yome-project';
|
|
4
|
+
export interface UnifiedSkill {
|
|
5
|
+
/** Stable identifier across reloads. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** What the user sees first in the list. */
|
|
8
|
+
name: string;
|
|
9
|
+
/** Long-form, what the skill does. */
|
|
10
|
+
description: string;
|
|
11
|
+
kind: UnifiedSkillKind;
|
|
12
|
+
enabled: boolean;
|
|
13
|
+
/** Path to the skill's directory or main file (for "open" actions). */
|
|
14
|
+
installedAt: string;
|
|
15
|
+
/** ── prompt-only fields ────────────────────────────────────────── */
|
|
16
|
+
promptOrigin?: PromptOrigin;
|
|
17
|
+
promptSkill?: PromptSkill;
|
|
18
|
+
/** ── hub-only fields ───────────────────────────────────────────── */
|
|
19
|
+
slug?: string;
|
|
20
|
+
domain?: string;
|
|
21
|
+
version?: string;
|
|
22
|
+
source?: string;
|
|
23
|
+
declaredCapabilities?: string[];
|
|
24
|
+
allowedCapabilities?: string[];
|
|
25
|
+
isDevLink?: boolean;
|
|
26
|
+
}
|
|
27
|
+
interface RawPromptSkill {
|
|
28
|
+
name: string;
|
|
29
|
+
description: string;
|
|
30
|
+
skillDir: string;
|
|
31
|
+
origin: PromptOrigin;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Discover prompt-style skills under yome's two roots only:
|
|
35
|
+
* ~/.yome/skills/<name>/SKILL.md (user)
|
|
36
|
+
* <cwd>/.yome/skills/<name>/SKILL.md (project)
|
|
37
|
+
* Project-level wins over user-level on name collision.
|
|
38
|
+
*/
|
|
39
|
+
export declare function discoverAllPromptSkills(): RawPromptSkill[];
|
|
40
|
+
/**
|
|
41
|
+
* Returns every skill the agent could currently use, both prompt and hub.
|
|
42
|
+
*
|
|
43
|
+
* Note: yome-style hub skills live at <owner>/<name>/yome-skill.json. The
|
|
44
|
+
* top-level dir under ~/.yome/skills is therefore an OWNER for hub skills
|
|
45
|
+
* but a SKILL NAME for prompt skills. We disambiguate by checking which
|
|
46
|
+
* file lives in the dir — the prompt loader looks for SKILL.md and the
|
|
47
|
+
* hub loader looks for yome-skill.json — so they never accidentally
|
|
48
|
+
* cross-contaminate.
|
|
49
|
+
*/
|
|
50
|
+
export declare function listAllUnified(includeDisabled?: boolean): UnifiedSkill[];
|
|
51
|
+
/** Pretty label for the origin (used in TUI). */
|
|
52
|
+
export declare function originLabel(s: UnifiedSkill): string;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
// cli/src/yomeSkills/unified.ts
|
|
2
|
+
//
|
|
3
|
+
// Unified skill view across the two skill systems Yome supports:
|
|
4
|
+
// 1. Prompt skills (Claude Code-compatible SKILL.md FORMAT)
|
|
5
|
+
// - SKILL.md with optional YAML frontmatter
|
|
6
|
+
// - The body is dropped into the agent prompt when triggered
|
|
7
|
+
// - Discovered under 2 roots (yome's own dirs, NOT ~/.claude):
|
|
8
|
+
// ~/.yome/skills/<name>/SKILL.md (yome global)
|
|
9
|
+
// <cwd>/.yome/skills/<name>/SKILL.md (yome project)
|
|
10
|
+
// - We support the FORMAT (so users can drop a Claude SKILL.md
|
|
11
|
+
// unchanged into our directories) but we don't read Claude's own
|
|
12
|
+
// directories — those belong to Claude Code, not us.
|
|
13
|
+
// 2. Hub skills (yome-skill.json — typed command packages)
|
|
14
|
+
// - Discovered under ~/.yome/skills/<owner>/<name>/yome-skill.json
|
|
15
|
+
// - Carry capability grants, backends, signature contracts
|
|
16
|
+
// - Installed via `yome skill install ...` from local / github
|
|
17
|
+
//
|
|
18
|
+
// Both render in the same /skills TUI; users don't need to remember
|
|
19
|
+
// which kind they're looking at unless they want to. The `kind` field
|
|
20
|
+
// tells the UI which actions apply.
|
|
21
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
import { loadAllSkills, getUserSkillsDir, getProjectSkillsDir } from '../skills/loader.js';
|
|
24
|
+
import { getInstalledFast } from './skillsIndex.js';
|
|
25
|
+
import { isSkillDisabled as isHubSkillDisabled } from './enable.js';
|
|
26
|
+
import { isSkillDisabled as isPromptSkillDisabled } from '../toggleState.js';
|
|
27
|
+
function parseFrontmatterMinimal(raw) {
|
|
28
|
+
const m = raw.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
29
|
+
if (!m)
|
|
30
|
+
return {};
|
|
31
|
+
const fm = {};
|
|
32
|
+
for (const line of m[1].split('\n')) {
|
|
33
|
+
const kv = line.match(/^(\S[\w-]*)\s*:\s*(.*)$/);
|
|
34
|
+
if (!kv)
|
|
35
|
+
continue;
|
|
36
|
+
const k = kv[1];
|
|
37
|
+
const v = kv[2].trim().replace(/^["']|["']$/g, '');
|
|
38
|
+
if (k === 'description')
|
|
39
|
+
fm.description = v;
|
|
40
|
+
else if (k === 'when_to_use')
|
|
41
|
+
fm.whenToUse = v;
|
|
42
|
+
}
|
|
43
|
+
return fm;
|
|
44
|
+
}
|
|
45
|
+
function discoverPromptSkillsAt(dir, origin) {
|
|
46
|
+
if (!existsSync(dir))
|
|
47
|
+
return [];
|
|
48
|
+
const out = [];
|
|
49
|
+
let entries = [];
|
|
50
|
+
try {
|
|
51
|
+
entries = readdirSync(dir).filter((n) => {
|
|
52
|
+
try {
|
|
53
|
+
return statSync(join(dir, n)).isDirectory();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
for (const name of entries) {
|
|
64
|
+
const skillDir = join(dir, name);
|
|
65
|
+
const skillFile = join(skillDir, 'SKILL.md');
|
|
66
|
+
if (!existsSync(skillFile))
|
|
67
|
+
continue;
|
|
68
|
+
let raw = '';
|
|
69
|
+
try {
|
|
70
|
+
raw = readFileSync(skillFile, 'utf-8');
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const fm = parseFrontmatterMinimal(raw);
|
|
76
|
+
const description = fm.description
|
|
77
|
+
?? raw
|
|
78
|
+
.replace(/^---[\s\S]*?---/, '')
|
|
79
|
+
.split('\n')
|
|
80
|
+
.find((l) => l.trim().length > 0 && !l.startsWith('#'))
|
|
81
|
+
?.trim()
|
|
82
|
+
?? `Skill: ${name}`;
|
|
83
|
+
out.push({ name, description, skillDir, origin });
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Discover prompt-style skills under yome's two roots only:
|
|
89
|
+
* ~/.yome/skills/<name>/SKILL.md (user)
|
|
90
|
+
* <cwd>/.yome/skills/<name>/SKILL.md (project)
|
|
91
|
+
* Project-level wins over user-level on name collision.
|
|
92
|
+
*/
|
|
93
|
+
export function discoverAllPromptSkills() {
|
|
94
|
+
const yomeUser = discoverPromptSkillsAt(getUserSkillsDir(), 'yome-user');
|
|
95
|
+
const yomeProject = discoverPromptSkillsAt(getProjectSkillsDir(), 'yome-project');
|
|
96
|
+
const byName = new Map();
|
|
97
|
+
for (const s of [...yomeUser, ...yomeProject]) {
|
|
98
|
+
byName.set(s.name, s);
|
|
99
|
+
}
|
|
100
|
+
return Array.from(byName.values());
|
|
101
|
+
}
|
|
102
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
103
|
+
// Unified loader
|
|
104
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
105
|
+
/**
|
|
106
|
+
* Returns every skill the agent could currently use, both prompt and hub.
|
|
107
|
+
*
|
|
108
|
+
* Note: yome-style hub skills live at <owner>/<name>/yome-skill.json. The
|
|
109
|
+
* top-level dir under ~/.yome/skills is therefore an OWNER for hub skills
|
|
110
|
+
* but a SKILL NAME for prompt skills. We disambiguate by checking which
|
|
111
|
+
* file lives in the dir — the prompt loader looks for SKILL.md and the
|
|
112
|
+
* hub loader looks for yome-skill.json — so they never accidentally
|
|
113
|
+
* cross-contaminate.
|
|
114
|
+
*/
|
|
115
|
+
export function listAllUnified(includeDisabled = true) {
|
|
116
|
+
const out = [];
|
|
117
|
+
// Prompt skills (4 roots, dedup by name).
|
|
118
|
+
const promptSkills = loadAllSkills(true); // includeDisabled — we filter below
|
|
119
|
+
const rawByName = new Map();
|
|
120
|
+
for (const r of discoverAllPromptSkills())
|
|
121
|
+
rawByName.set(r.name, r);
|
|
122
|
+
for (const ps of promptSkills) {
|
|
123
|
+
const raw = rawByName.get(ps.name);
|
|
124
|
+
const origin = raw?.origin ?? (ps.source === 'project' ? 'yome-project' : 'yome-user');
|
|
125
|
+
out.push({
|
|
126
|
+
id: `prompt:${origin}:${ps.name}`,
|
|
127
|
+
name: ps.name,
|
|
128
|
+
description: ps.description,
|
|
129
|
+
kind: 'prompt',
|
|
130
|
+
enabled: !isPromptSkillDisabled(ps.name),
|
|
131
|
+
installedAt: ps.skillDir,
|
|
132
|
+
promptOrigin: origin,
|
|
133
|
+
promptSkill: ps,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// Also surface claude-only skills that loadAllSkills doesn't see (it
|
|
137
|
+
// only walks the .yome/* dirs). discoverAllPromptSkills covers
|
|
138
|
+
// all 4 roots, so anything from .claude/* not already added above
|
|
139
|
+
// gets injected here.
|
|
140
|
+
for (const raw of rawByName.values()) {
|
|
141
|
+
const alreadyAdded = out.some((u) => u.kind === 'prompt' && u.name === raw.name);
|
|
142
|
+
if (alreadyAdded)
|
|
143
|
+
continue;
|
|
144
|
+
out.push({
|
|
145
|
+
id: `prompt:${raw.origin}:${raw.name}`,
|
|
146
|
+
name: raw.name,
|
|
147
|
+
description: raw.description,
|
|
148
|
+
kind: 'prompt',
|
|
149
|
+
enabled: !isPromptSkillDisabled(raw.name),
|
|
150
|
+
installedAt: raw.skillDir,
|
|
151
|
+
promptOrigin: raw.origin,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// Hub skills.
|
|
155
|
+
const hubEntries = getInstalledFast();
|
|
156
|
+
for (const h of hubEntries) {
|
|
157
|
+
out.push({
|
|
158
|
+
id: `hub:${h.slug}`,
|
|
159
|
+
name: h.name ?? h.slug,
|
|
160
|
+
description: h.description ?? `${h.domain} ${h.version}`,
|
|
161
|
+
kind: 'hub',
|
|
162
|
+
enabled: !isHubSkillDisabled(h.slug) && h.status === 'enabled',
|
|
163
|
+
installedAt: h.installedAt,
|
|
164
|
+
slug: h.slug,
|
|
165
|
+
domain: h.domain,
|
|
166
|
+
version: h.version,
|
|
167
|
+
declaredCapabilities: h.declared_capabilities,
|
|
168
|
+
allowedCapabilities: h.allowed_capabilities,
|
|
169
|
+
isDevLink: h.is_dev_link,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
if (!includeDisabled) {
|
|
173
|
+
return out.filter((s) => s.enabled);
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
/** Pretty label for the origin (used in TUI). */
|
|
178
|
+
export function originLabel(s) {
|
|
179
|
+
if (s.kind === 'hub')
|
|
180
|
+
return s.isDevLink ? 'hub (dev-link)' : 'hub';
|
|
181
|
+
switch (s.promptOrigin) {
|
|
182
|
+
case 'yome-user': return 'prompt · ~/.yome';
|
|
183
|
+
case 'yome-project': return 'prompt · .yome';
|
|
184
|
+
default: return 'prompt';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=unified.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unified.js","sourceRoot":"","sources":["../../src/yomeSkills/unified.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// `yome skill uninstall <slug>` — remove a previously installed skill.
|
|
2
|
+
import { existsSync, rmSync } from 'fs';
|
|
3
|
+
import { installPathForSlug, parseSlug } from './paths.js';
|
|
4
|
+
import { refreshIndex } from './skillsIndex.js';
|
|
5
|
+
export function uninstallBySlug(slug) {
|
|
6
|
+
const parts = parseSlug(slug);
|
|
7
|
+
if (!parts)
|
|
8
|
+
return { ok: false, reason: `bad slug "${slug}" (expected @<owner>/<name>)` };
|
|
9
|
+
const dir = installPathForSlug(slug);
|
|
10
|
+
if (!dir)
|
|
11
|
+
return { ok: false, reason: `cannot derive install path for ${slug}` };
|
|
12
|
+
if (!existsSync(dir)) {
|
|
13
|
+
return { ok: false, reason: `${slug} not installed at ${dir}` };
|
|
14
|
+
}
|
|
15
|
+
rmSync(dir, { recursive: true, force: true });
|
|
16
|
+
try {
|
|
17
|
+
refreshIndex();
|
|
18
|
+
}
|
|
19
|
+
catch { /* best effort */ }
|
|
20
|
+
return { ok: true, slug: parts.full, removedFrom: dir };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=uninstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/yomeSkills/uninstall.ts"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAShD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,IAAI,8BAA8B,EAAE,CAAC;IAE1F,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,IAAI,EAAE,EAAE,CAAC;IAEjF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,qBAAqB,GAAG,EAAE,EAAE,CAAC;IAClE,CAAC;IAED,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC;QAAC,YAAY,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACnD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface UpdateOptions {
|
|
2
|
+
verbose?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export interface UpdateRow {
|
|
5
|
+
slug: string;
|
|
6
|
+
source: string | null;
|
|
7
|
+
before: string;
|
|
8
|
+
after: string | null;
|
|
9
|
+
changed: boolean;
|
|
10
|
+
ok: boolean;
|
|
11
|
+
reason?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface UpdateSummary {
|
|
14
|
+
rows: UpdateRow[];
|
|
15
|
+
/** True if every attempted update succeeded (skipped rows count as ok). */
|
|
16
|
+
allOk: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function updateSkills(filterSlug: string | undefined, opts?: UpdateOptions): Promise<UpdateSummary>;
|