@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,152 @@
|
|
|
1
|
+
// `yome skill doctor` — sanity-check the local registry.
|
|
2
|
+
//
|
|
3
|
+
// Detects:
|
|
4
|
+
// - Skills present on disk but with broken / missing yome-skill.json
|
|
5
|
+
// - Stale .index.json (entries that no longer have a backing dir)
|
|
6
|
+
// - Capability grants for skills whose declared system_capabilities have
|
|
7
|
+
// since shrunk (orphan grants — safe but noisy)
|
|
8
|
+
// - Dev-link symlinks pointing at deleted source dirs
|
|
9
|
+
// - Missing .install-meta.json (legacy; warn-only — can't update)
|
|
10
|
+
//
|
|
11
|
+
// Exit codes: 0 = no issues, 1 = at least one issue.
|
|
12
|
+
//
|
|
13
|
+
// `doctor` does NOT fix anything by itself — it just reports. The user
|
|
14
|
+
// follows up with `yome skill uninstall <slug>` or `yome skill install
|
|
15
|
+
// <source> --force` as appropriate.
|
|
16
|
+
import { existsSync, readdirSync, statSync, lstatSync, readlinkSync } from 'fs';
|
|
17
|
+
import { join } from 'path';
|
|
18
|
+
import { getYomeSkillsRoot } from './paths.js';
|
|
19
|
+
import { readManifest } from './manifest.js';
|
|
20
|
+
import { readInstallMeta } from './installMeta.js';
|
|
21
|
+
import { readAllowedCapabilities, normaliseDeclared, KNOWN_CAPABILITIES, } from './capabilities.js';
|
|
22
|
+
import { readIndex } from './skillsIndex.js';
|
|
23
|
+
function listInstallDirs() {
|
|
24
|
+
const root = getYomeSkillsRoot();
|
|
25
|
+
if (!existsSync(root))
|
|
26
|
+
return [];
|
|
27
|
+
const out = [];
|
|
28
|
+
for (const owner of readdirSync(root)) {
|
|
29
|
+
if (owner.startsWith('.'))
|
|
30
|
+
continue;
|
|
31
|
+
const ownerPath = join(root, owner);
|
|
32
|
+
if (!statSync(ownerPath).isDirectory())
|
|
33
|
+
continue;
|
|
34
|
+
for (const name of readdirSync(ownerPath)) {
|
|
35
|
+
if (name.startsWith('.'))
|
|
36
|
+
continue;
|
|
37
|
+
const dir = join(ownerPath, name);
|
|
38
|
+
const lst = lstatSync(dir);
|
|
39
|
+
const isLink = lst.isSymbolicLink();
|
|
40
|
+
const linkTarget = isLink ? readlinkSync(dir) : undefined;
|
|
41
|
+
// Only treat as a real install if it's a directory or a symlink to one.
|
|
42
|
+
try {
|
|
43
|
+
const target = isLink ? statSync(dir) : lst;
|
|
44
|
+
if (!target.isDirectory())
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Broken symlink — surface this as an issue below.
|
|
49
|
+
out.push({ slug: `@${owner}/${name}`, dir, isLink: true, linkTarget });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
out.push({ slug: `@${owner}/${name}`, dir, isLink, linkTarget });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
export function runDoctor() {
|
|
58
|
+
const issues = [];
|
|
59
|
+
const installs = listInstallDirs();
|
|
60
|
+
const seenSlugs = new Set();
|
|
61
|
+
for (const it of installs) {
|
|
62
|
+
seenSlugs.add(it.slug);
|
|
63
|
+
// Broken symlink (dev-link target deleted)
|
|
64
|
+
if (it.isLink) {
|
|
65
|
+
try {
|
|
66
|
+
statSync(it.dir);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
issues.push({
|
|
70
|
+
level: 'error',
|
|
71
|
+
slug: it.slug,
|
|
72
|
+
path: it.dir,
|
|
73
|
+
message: `dev-link points at deleted target ${it.linkTarget}`,
|
|
74
|
+
});
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Manifest readable + slug consistent
|
|
79
|
+
const m = readManifest(it.dir);
|
|
80
|
+
if (!m) {
|
|
81
|
+
issues.push({
|
|
82
|
+
level: 'error',
|
|
83
|
+
slug: it.slug,
|
|
84
|
+
path: it.dir,
|
|
85
|
+
message: 'yome-skill.json missing or unparseable',
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (m.slug !== it.slug) {
|
|
90
|
+
issues.push({
|
|
91
|
+
level: 'error',
|
|
92
|
+
slug: it.slug,
|
|
93
|
+
path: it.dir,
|
|
94
|
+
message: `slug mismatch — directory says ${it.slug} but manifest says ${m.slug}`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// install-meta presence (legacy installs may lack it)
|
|
98
|
+
if (!readInstallMeta(it.slug)) {
|
|
99
|
+
issues.push({
|
|
100
|
+
level: 'warning',
|
|
101
|
+
slug: it.slug,
|
|
102
|
+
message: '.install-meta.json missing — `yome skill update` will not know how to refresh this skill',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Capability grants vs current declared set
|
|
106
|
+
const allowed = readAllowedCapabilities(it.slug);
|
|
107
|
+
if (allowed) {
|
|
108
|
+
const declared = new Set(normaliseDeclared(m.system_capabilities));
|
|
109
|
+
const orphan = allowed.allowed.filter(c => !declared.has(c));
|
|
110
|
+
if (orphan.length > 0) {
|
|
111
|
+
issues.push({
|
|
112
|
+
level: 'warning',
|
|
113
|
+
slug: it.slug,
|
|
114
|
+
message: `granted capabilities not declared in current manifest: ${orphan.join(', ')} — consider \`yome skill perms ${it.slug} --revoke=<cap>\``,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// Also surface any grant for a cap we no longer recognise
|
|
118
|
+
const unknown = allowed.allowed.filter(c => !KNOWN_CAPABILITIES.includes(c));
|
|
119
|
+
if (unknown.length > 0) {
|
|
120
|
+
issues.push({
|
|
121
|
+
level: 'warning',
|
|
122
|
+
slug: it.slug,
|
|
123
|
+
message: `granted unknown capabilities: ${unknown.join(', ')} (CLI version mismatch?)`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Index stale check
|
|
129
|
+
const idx = readIndex();
|
|
130
|
+
if (idx) {
|
|
131
|
+
for (const entry of idx.skills) {
|
|
132
|
+
if (!seenSlugs.has(entry.slug)) {
|
|
133
|
+
issues.push({
|
|
134
|
+
level: 'warning',
|
|
135
|
+
slug: entry.slug,
|
|
136
|
+
message: '.index.json lists this skill but no install dir was found — run `yome skill list` to refresh',
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
console.log('DOCTOR REPORT:', JSON.stringify({
|
|
142
|
+
ok: issues.filter(i => i.level === 'error').length === 0,
|
|
143
|
+
scanned: installs.length,
|
|
144
|
+
issues,
|
|
145
|
+
}, null, 2));
|
|
146
|
+
return {
|
|
147
|
+
ok: issues.filter(i => i.level === 'error').length === 0,
|
|
148
|
+
scanned: installs.length,
|
|
149
|
+
issues,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/yomeSkills/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ToggleResult {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
slug: string;
|
|
4
|
+
state?: 'enabled' | 'disabled';
|
|
5
|
+
reason?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function isSkillDisabled(slug: string): boolean;
|
|
8
|
+
export declare function setSkillEnabled(slug: string, enabled: boolean): ToggleResult;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// `yome skill enable / disable <slug>` — toggle whether the agent
|
|
2
|
+
// runtime should load this installed skill.
|
|
3
|
+
//
|
|
4
|
+
// We persist state as a sentinel file `.yome-disabled` inside the skill's
|
|
5
|
+
// install directory. Rationale (vs a central registry.json):
|
|
6
|
+
// - zero schema migration; uninstall just `rm -rf` the dir, taking the
|
|
7
|
+
// sentinel with it.
|
|
8
|
+
// - works for dev-linked skills too (the flag lives on the symlink
|
|
9
|
+
// target's view but writing is naturally scoped per-skill).
|
|
10
|
+
//
|
|
11
|
+
// `isSkillDisabled()` is exported so the loader (Server side) can read
|
|
12
|
+
// the same flag once we wire the generated registry to honour it.
|
|
13
|
+
import { existsSync, writeFileSync, unlinkSync, mkdirSync } from 'fs';
|
|
14
|
+
import { join, dirname } from 'path';
|
|
15
|
+
import { installPathForSlug } from './paths.js';
|
|
16
|
+
import { refreshIndex } from './skillsIndex.js';
|
|
17
|
+
const DISABLED_MARKER = '.yome-disabled';
|
|
18
|
+
function markerPath(slug) {
|
|
19
|
+
const dir = installPathForSlug(slug);
|
|
20
|
+
if (!dir)
|
|
21
|
+
return null;
|
|
22
|
+
return join(dir, DISABLED_MARKER);
|
|
23
|
+
}
|
|
24
|
+
export function isSkillDisabled(slug) {
|
|
25
|
+
const m = markerPath(slug);
|
|
26
|
+
if (!m)
|
|
27
|
+
return false;
|
|
28
|
+
return existsSync(m);
|
|
29
|
+
}
|
|
30
|
+
export function setSkillEnabled(slug, enabled) {
|
|
31
|
+
const m = markerPath(slug);
|
|
32
|
+
if (!m)
|
|
33
|
+
return { ok: false, slug, reason: 'invalid slug shape (expected @owner/name)' };
|
|
34
|
+
const dir = dirname(m);
|
|
35
|
+
if (!existsSync(dir)) {
|
|
36
|
+
return { ok: false, slug, reason: `skill not installed at ${dir}` };
|
|
37
|
+
}
|
|
38
|
+
if (enabled) {
|
|
39
|
+
if (existsSync(m)) {
|
|
40
|
+
try {
|
|
41
|
+
unlinkSync(m);
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
return { ok: false, slug, reason: e.message };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
refreshIndex();
|
|
49
|
+
}
|
|
50
|
+
catch { /* best effort */ }
|
|
51
|
+
return { ok: true, slug, state: 'enabled' };
|
|
52
|
+
}
|
|
53
|
+
// disabling: write a tiny marker (no schema needed inside)
|
|
54
|
+
try {
|
|
55
|
+
mkdirSync(dir, { recursive: true });
|
|
56
|
+
writeFileSync(m, `disabled at ${new Date().toISOString()}\n`, { mode: 0o644 });
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
return { ok: false, slug, reason: e.message };
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
refreshIndex();
|
|
63
|
+
}
|
|
64
|
+
catch { /* best effort */ }
|
|
65
|
+
return { ok: true, slug, state: 'disabled' };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=enable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enable.js","sourceRoot":"","sources":["../../src/yomeSkills/enable.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,4CAA4C;AAC5C,EAAE;AACF,0EAA0E;AAC1E,6DAA6D;AAC7D,yEAAyE;AACzE,wBAAwB;AACxB,qEAAqE;AACrE,gEAAgE;AAChE,EAAE;AACF,uEAAuE;AACvE,kEAAkE;AAElE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,eAAe,GAAG,gBAAgB,CAAC;AASzC,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAgB;IAC5D,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,2CAA2C,EAAE,CAAC;IACxF,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,0BAA0B,GAAG,EAAE,EAAE,CAAC;IACtE,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,IAAI,CAAC;gBAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;YAAC,CAAC;QAChG,CAAC;QACD,IAAI,CAAC;YAAC,YAAY,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC9C,CAAC;IACD,2DAA2D;IAC3D,IAAI,CAAC;QACH,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,aAAa,CAAC,CAAC,EAAE,eAAe,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACjF,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC;IAC3D,CAAC;IACD,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,EAAE,UAAU,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function pingHubInstall(slug: string): Promise<void>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Best-effort ping to the hub so install_count goes up.
|
|
2
|
+
//
|
|
3
|
+
// Intentionally:
|
|
4
|
+
// - never throws (catches everything)
|
|
5
|
+
// - never blocks longer than ~3s
|
|
6
|
+
// - does nothing if YOME_HUB_PING_DISABLED=1 or YOME_HUB_BASE points
|
|
7
|
+
// at a non-http(s) value
|
|
8
|
+
// - silent on success, only logs on failure when YOME_VERBOSE=1
|
|
9
|
+
//
|
|
10
|
+
// The hub endpoint /api/hub/skills/<slug>/install is anonymous (rate-limited
|
|
11
|
+
// per IP) so we don't need to send any credentials.
|
|
12
|
+
//
|
|
13
|
+
// Returns a promise the caller MAY await. The CLI awaits a short bounded
|
|
14
|
+
// time so the request actually leaves the box before the process exits;
|
|
15
|
+
// other callers can ignore the promise.
|
|
16
|
+
const DEFAULT_HUB_BASE = 'https://yome.work';
|
|
17
|
+
export function pingHubInstall(slug) {
|
|
18
|
+
if (process.env.YOME_HUB_PING_DISABLED === '1')
|
|
19
|
+
return Promise.resolve();
|
|
20
|
+
if (!slug)
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
const base = (process.env.YOME_HUB_BASE || DEFAULT_HUB_BASE).replace(/\/$/, '');
|
|
23
|
+
if (!/^https?:\/\//.test(base))
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
const url = `${base}/api/hub/skills/${encodeURIComponent(slug)}/install`;
|
|
26
|
+
const verbose = process.env.YOME_VERBOSE === '1';
|
|
27
|
+
const ctrl = new AbortController();
|
|
28
|
+
const timer = setTimeout(() => ctrl.abort(), 3000);
|
|
29
|
+
return fetch(url, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: { 'Content-Type': 'application/json', 'User-Agent': 'yome-cli/0.1' },
|
|
32
|
+
body: '{}',
|
|
33
|
+
signal: ctrl.signal,
|
|
34
|
+
})
|
|
35
|
+
.then((r) => { if (verbose)
|
|
36
|
+
console.error(`hub ping ${slug}: ${r.status}`); })
|
|
37
|
+
.catch((e) => { if (verbose)
|
|
38
|
+
console.error(`hub ping ${slug} failed: ${e.message}`); })
|
|
39
|
+
.finally(() => clearTimeout(timer));
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=hubPing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hubPing.js","sourceRoot":"","sources":["../../src/yomeSkills/hubPing.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,iBAAiB;AACjB,wCAAwC;AACxC,mCAAmC;AACnC,uEAAuE;AACvE,6BAA6B;AAC7B,kEAAkE;AAClE,EAAE;AACF,6EAA6E;AAC7E,oDAAoD;AACpD,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,wCAAwC;AAExC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAE7C,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,GAAG;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IACzE,IAAI,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAEzD,MAAM,GAAG,GAAG,GAAG,IAAI,mBAAmB,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;IACzE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC;IAEjD,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;IAEnD,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,YAAY,EAAE,cAAc,EAAE;QAC7E,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC;SACC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,OAAO;QAAE,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SAC7E,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,OAAO;QAAE,OAAO,CAAC,KAAK,CAAC,YAAY,IAAI,YAAa,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACjG,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface InstallOptions {
|
|
2
|
+
/** Overwrite an existing install of the same slug. */
|
|
3
|
+
force?: boolean;
|
|
4
|
+
/** Print verbose progress. */
|
|
5
|
+
verbose?: boolean;
|
|
6
|
+
/** Skip the capability prompt — auto-grant everything declared. CI / scripted use. */
|
|
7
|
+
yes?: boolean;
|
|
8
|
+
/** Skip blacklist check (NEVER do this in production). Default false. */
|
|
9
|
+
skipBlacklist?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface InstallResult {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
slug?: string;
|
|
14
|
+
installedAt?: string;
|
|
15
|
+
copiedFiles?: number;
|
|
16
|
+
reason?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function installFromLocal(source: string, opts?: InstallOptions): Promise<InstallResult>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// `yome skill install <source>` — install a skill into ~/.yome/skills/.
|
|
2
|
+
//
|
|
3
|
+
// During Phase 1 (per spec 8.5) we support local-path installs only:
|
|
4
|
+
// yome skill install ./skills/yome-skill-ppt
|
|
5
|
+
// yome skill install /abs/path/to/yome-skill-foo
|
|
6
|
+
// Phase 2 will add registry / git installs:
|
|
7
|
+
// yome skill install @yome/ppt (registry resolution)
|
|
8
|
+
// yome skill install github:owner/repo (git clone)
|
|
9
|
+
//
|
|
10
|
+
// Install strategy:
|
|
11
|
+
// - Read source/yome-skill.json, validate slug+domain+version
|
|
12
|
+
// - Compute install path ~/.yome/skills/<owner>/<name>/
|
|
13
|
+
// - If already installed and not --force, error out
|
|
14
|
+
// - Recursively copy source → install path (skip node_modules / .git / dist)
|
|
15
|
+
// - Done; no post-install hooks in this phase
|
|
16
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, renameSync, rmSync, statSync } from 'fs';
|
|
17
|
+
import { join, resolve } from 'path';
|
|
18
|
+
import { readManifest, validateManifest } from './manifest.js';
|
|
19
|
+
import { installPathForSlug, parseSlug } from './paths.js';
|
|
20
|
+
import { writeInstallMeta } from './installMeta.js';
|
|
21
|
+
import { decideCapabilities, writeAllowedCapabilities } from './capabilities.js';
|
|
22
|
+
import { refreshIndex } from './skillsIndex.js';
|
|
23
|
+
import { pingBlacklist } from './blacklist.js';
|
|
24
|
+
const IGNORE = new Set(['node_modules', '.git', 'dist', '.DS_Store', '.next', '.turbo', 'coverage']);
|
|
25
|
+
function copyDir(src, dest, log) {
|
|
26
|
+
let count = 0;
|
|
27
|
+
if (!existsSync(dest))
|
|
28
|
+
mkdirSync(dest, { recursive: true });
|
|
29
|
+
for (const entry of readdirSync(src)) {
|
|
30
|
+
if (IGNORE.has(entry))
|
|
31
|
+
continue;
|
|
32
|
+
const s = join(src, entry);
|
|
33
|
+
const d = join(dest, entry);
|
|
34
|
+
const st = statSync(s);
|
|
35
|
+
if (st.isDirectory()) {
|
|
36
|
+
count += copyDir(s, d, log);
|
|
37
|
+
}
|
|
38
|
+
else if (st.isFile()) {
|
|
39
|
+
copyFileSync(s, d);
|
|
40
|
+
log?.(` + ${entry}`);
|
|
41
|
+
count++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return count;
|
|
45
|
+
}
|
|
46
|
+
export async function installFromLocal(source, opts = {}) {
|
|
47
|
+
const abs = resolve(source);
|
|
48
|
+
if (!existsSync(abs))
|
|
49
|
+
return { ok: false, reason: `source path does not exist: ${abs}` };
|
|
50
|
+
if (!statSync(abs).isDirectory())
|
|
51
|
+
return { ok: false, reason: `source is not a directory: ${abs}` };
|
|
52
|
+
const manifest = readManifest(abs);
|
|
53
|
+
if (!manifest)
|
|
54
|
+
return { ok: false, reason: `${abs}/yome-skill.json missing or unreadable` };
|
|
55
|
+
const v = validateManifest(manifest);
|
|
56
|
+
if (!v.ok)
|
|
57
|
+
return { ok: false, reason: `manifest invalid: ${v.errors.join('; ')}` };
|
|
58
|
+
const slugParts = parseSlug(manifest.slug);
|
|
59
|
+
if (!slugParts)
|
|
60
|
+
return { ok: false, reason: `slug "${manifest.slug}" is malformed` };
|
|
61
|
+
const dest = installPathForSlug(manifest.slug);
|
|
62
|
+
if (!dest)
|
|
63
|
+
return { ok: false, reason: `cannot derive install path for ${manifest.slug}` };
|
|
64
|
+
// Blacklist gate — done before we touch the filesystem.
|
|
65
|
+
if (!opts.skipBlacklist) {
|
|
66
|
+
try {
|
|
67
|
+
const hit = await pingBlacklist(manifest.slug);
|
|
68
|
+
if (hit) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
reason: `${manifest.slug} is on the yome.work blacklist (${hit.reason})${hit.detail ? `: ${hit.detail}` : ''}`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch { /* offline → ignore, conservative no-block */ }
|
|
76
|
+
}
|
|
77
|
+
// Capability prompt — done before we touch the filesystem so a
|
|
78
|
+
// declined install leaves no trace.
|
|
79
|
+
const decision = await decideCapabilities(manifest.slug, manifest.system_capabilities, { assumeYes: opts.yes });
|
|
80
|
+
if (!decision.ok) {
|
|
81
|
+
return { ok: false, reason: decision.reason ?? 'capability grant declined' };
|
|
82
|
+
}
|
|
83
|
+
if (existsSync(dest)) {
|
|
84
|
+
if (!opts.force) {
|
|
85
|
+
return { ok: false, reason: `${manifest.slug} already installed at ${dest} (use --force to overwrite)` };
|
|
86
|
+
}
|
|
87
|
+
// Move the existing install aside as the rollback snapshot. We keep
|
|
88
|
+
// exactly ONE previous version (per spec 11.4-D "保留最近 2 个版本").
|
|
89
|
+
// The snapshot lives next to the install dir so it shares the slug's
|
|
90
|
+
// capability grant / parent directory layout.
|
|
91
|
+
try {
|
|
92
|
+
const snap = `${dest}.previous`;
|
|
93
|
+
if (existsSync(snap))
|
|
94
|
+
rmSync(snap, { recursive: true, force: true });
|
|
95
|
+
// os.rename is atomic; if it fails (cross-filesystem etc) we fall
|
|
96
|
+
// back to copy-then-delete via a recursive helper inlined below.
|
|
97
|
+
try {
|
|
98
|
+
renameSync(dest, snap);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
copyDir(dest, snap);
|
|
102
|
+
rmSync(dest, { recursive: true, force: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// If snapshotting fails for any reason we still proceed — losing
|
|
107
|
+
// rollback ability is better than losing the install itself.
|
|
108
|
+
try {
|
|
109
|
+
rmSync(dest, { recursive: true, force: true });
|
|
110
|
+
}
|
|
111
|
+
catch { /* ignore */ }
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const log = opts.verbose ? (s) => process.stdout.write(s + '\n') : undefined;
|
|
115
|
+
const copied = copyDir(abs, dest, log);
|
|
116
|
+
// Persist how we got here so `yome skill update` can replay later.
|
|
117
|
+
try {
|
|
118
|
+
writeInstallMeta(manifest.slug, {
|
|
119
|
+
source: `local:${abs}`,
|
|
120
|
+
installed_at: new Date().toISOString(),
|
|
121
|
+
manifest_version: manifest.version,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
catch { /* best effort */ }
|
|
125
|
+
// Write the capability grant alongside the install meta.
|
|
126
|
+
try {
|
|
127
|
+
if (decision.granted)
|
|
128
|
+
writeAllowedCapabilities(manifest.slug, decision.granted);
|
|
129
|
+
}
|
|
130
|
+
catch { /* best effort */ }
|
|
131
|
+
// Refresh the fast lookup index.
|
|
132
|
+
try {
|
|
133
|
+
refreshIndex();
|
|
134
|
+
}
|
|
135
|
+
catch { /* best effort */ }
|
|
136
|
+
return {
|
|
137
|
+
ok: true,
|
|
138
|
+
slug: manifest.slug,
|
|
139
|
+
installedAt: dest,
|
|
140
|
+
copiedFiles: copied,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/yomeSkills/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type InstallOptions, type InstallResult } from './install.js';
|
|
2
|
+
export interface ParsedGithubSource {
|
|
3
|
+
owner: string;
|
|
4
|
+
repo: string;
|
|
5
|
+
ref?: string;
|
|
6
|
+
subPath?: string;
|
|
7
|
+
/** The https clone URL we will hand to `git clone`. */
|
|
8
|
+
cloneUrl: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseGithubSource(source: string): ParsedGithubSource | null;
|
|
11
|
+
export declare function isGithubSource(source: string): boolean;
|
|
12
|
+
interface GithubInstallExtra {
|
|
13
|
+
/** When set, after install we recompute sha256 of the install dir and
|
|
14
|
+
* compare against this value. Mismatch → uninstall + error.
|
|
15
|
+
* When omitted (e.g. older publish without sha256), verification is skipped. */
|
|
16
|
+
expectedSha256?: string | null;
|
|
17
|
+
/** Disable post-install sha256 verification entirely (dev/debug). */
|
|
18
|
+
skipVerify?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Clone the repo into a tmp dir, then delegate to `installFromLocal`. Always
|
|
22
|
+
* cleans up the tmp clone, even on failure. If `expectedSha256` is provided,
|
|
23
|
+
* we verify the installed bytes match before declaring success.
|
|
24
|
+
*/
|
|
25
|
+
export declare function installFromGithub(source: string, opts?: InstallOptions & GithubInstallExtra): Promise<InstallResult>;
|
|
26
|
+
export {};
|