@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,70 @@
|
|
|
1
|
+
// CLI-side auth state for `yome login` / `yome whoami` / hub-authenticated
|
|
2
|
+
// commands like `yome skill publish`.
|
|
3
|
+
//
|
|
4
|
+
// Yome's identity model:
|
|
5
|
+
// - Yome user (Supabase auth.users) is the principal.
|
|
6
|
+
// - GitHub / Apple / WeChat / email are *providers* attached to that user.
|
|
7
|
+
// - The CLI cannot hold a Supabase session, so after the user authenticates
|
|
8
|
+
// against any provider, the hub mints us an opaque "yome_token" tied to
|
|
9
|
+
// the Yome user_id. That token is what we persist here.
|
|
10
|
+
//
|
|
11
|
+
// We store a single JSON file at ~/.yome/auth.json with mode 0600. Token is
|
|
12
|
+
// plaintext — same trust model as gh CLI's keyring fallback / npm's
|
|
13
|
+
// authToken — but with strict perms so other local users cannot read it.
|
|
14
|
+
//
|
|
15
|
+
// Why no encryption: a passphrase prompt every command would defeat the
|
|
16
|
+
// point of CLI auth, and any keychain integration is platform-specific
|
|
17
|
+
// (macOS Security framework, Linux libsecret). Plain mode 0600 is the
|
|
18
|
+
// pragmatic baseline.
|
|
19
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, chmodSync, } from 'fs';
|
|
20
|
+
import { homedir } from 'os';
|
|
21
|
+
import { join, dirname } from 'path';
|
|
22
|
+
export function getAuthFilePath() {
|
|
23
|
+
return join(homedir(), '.yome', 'auth.json');
|
|
24
|
+
}
|
|
25
|
+
export function readAuthState() {
|
|
26
|
+
const f = getAuthFilePath();
|
|
27
|
+
if (!existsSync(f))
|
|
28
|
+
return null;
|
|
29
|
+
try {
|
|
30
|
+
const text = readFileSync(f, 'utf-8');
|
|
31
|
+
const obj = JSON.parse(text);
|
|
32
|
+
if (typeof obj !== 'object' || obj == null)
|
|
33
|
+
return null;
|
|
34
|
+
if (typeof obj.yome_token !== 'string' || typeof obj.yome_user_id !== 'string')
|
|
35
|
+
return null;
|
|
36
|
+
return obj;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function writeAuthState(state) {
|
|
43
|
+
const f = getAuthFilePath();
|
|
44
|
+
mkdirSync(dirname(f), { recursive: true });
|
|
45
|
+
writeFileSync(f, JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
|
|
46
|
+
// mode in writeFileSync only applies on file CREATION; chmod again to
|
|
47
|
+
// guarantee the perms even when the file existed already.
|
|
48
|
+
try {
|
|
49
|
+
chmodSync(f, 0o600);
|
|
50
|
+
}
|
|
51
|
+
catch { /* best effort on Windows */ }
|
|
52
|
+
}
|
|
53
|
+
export function clearAuthState() {
|
|
54
|
+
const f = getAuthFilePath();
|
|
55
|
+
if (!existsSync(f))
|
|
56
|
+
return false;
|
|
57
|
+
try {
|
|
58
|
+
unlinkSync(f);
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** Bearer header object suitable for fetch({headers}). null if logged out. */
|
|
66
|
+
export function bearerHeader() {
|
|
67
|
+
const s = readAuthState();
|
|
68
|
+
return s ? { Authorization: `Bearer ${s.yome_token}` } : null;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/yomeSkills/auth.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,sCAAsC;AACtC,EAAE;AACF,yBAAyB;AACzB,wDAAwD;AACxD,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,4DAA4D;AAC5D,EAAE;AACF,4EAA4E;AAC5E,oEAAoE;AACpE,yEAAyE;AACzE,EAAE;AACF,wEAAwE;AACxE,uEAAuE;AACvE,sEAAsE;AACtE,sBAAsB;AAEtB,OAAO,EACL,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,GAC1E,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAiBrC,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,CAAC,GAAG,eAAe,EAAE,CAAC;IAC5B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QACxD,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC5F,OAAO,GAAoB,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,MAAM,CAAC,GAAG,eAAe,EAAE,CAAC;IAC5B,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzE,sEAAsE;IACtE,0DAA0D;IAC1D,IAAI,CAAC;QAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,4BAA4B,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,CAAC,GAAG,eAAe,EAAE,CAAC;IAC5B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACjC,IAAI,CAAC;QAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC7D,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY;IAC1B,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC;IAC1B,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface BlacklistEntry {
|
|
2
|
+
slug: string;
|
|
3
|
+
reason: string;
|
|
4
|
+
detail?: string | null;
|
|
5
|
+
added_at: string;
|
|
6
|
+
}
|
|
7
|
+
export interface BlacklistCache {
|
|
8
|
+
fetched_at: string;
|
|
9
|
+
entries: BlacklistEntry[];
|
|
10
|
+
}
|
|
11
|
+
export declare const DEFAULT_HUB_BASE = "https://yome.work";
|
|
12
|
+
export declare function getCachePath(): string;
|
|
13
|
+
export declare function readBlacklistCache(): BlacklistCache | null;
|
|
14
|
+
export declare function writeBlacklistCache(c: BlacklistCache): void;
|
|
15
|
+
export interface RefreshOptions {
|
|
16
|
+
/** Hub base URL override; default = env YOME_HUB_BASE or https://yome.work. */
|
|
17
|
+
hubBase?: string;
|
|
18
|
+
/** Test seam — replaces global fetch. */
|
|
19
|
+
fetcher?: typeof fetch;
|
|
20
|
+
/** Force refresh even if the cache is still fresh. */
|
|
21
|
+
force?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Pull the latest blacklist from the hub if needed, write it to the
|
|
25
|
+
* cache, return whatever we ended up with. Network errors are swallowed
|
|
26
|
+
* — the previous cache is returned instead so install never breaks
|
|
27
|
+
* because of a transient hub outage.
|
|
28
|
+
*/
|
|
29
|
+
export declare function refreshBlacklist(opts?: RefreshOptions): Promise<BlacklistCache>;
|
|
30
|
+
/** Sync lookup against the cache only. Returns the entry or null. */
|
|
31
|
+
export declare function isBlacklistedSync(slug: string): BlacklistEntry | null;
|
|
32
|
+
/** Fetch + check. Use during install. */
|
|
33
|
+
export declare function pingBlacklist(slug: string, opts?: RefreshOptions): Promise<BlacklistEntry | null>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// blacklist.ts — local cache + lookups for the hub's skill blacklist.
|
|
2
|
+
//
|
|
3
|
+
// Lifecycle:
|
|
4
|
+
// - `yome skill install` calls `pingBlacklist(slug)` which (a) refreshes
|
|
5
|
+
// the cache if older than 5 min, (b) returns the matching entry if
|
|
6
|
+
// the slug is denied.
|
|
7
|
+
// - `yome skill list` consults the cache (no network) so it's instant.
|
|
8
|
+
// - The CLI agent runtime, on every skill load, checks
|
|
9
|
+
// `isBlacklistedSync(slug)` against the cache.
|
|
10
|
+
//
|
|
11
|
+
// The cache lives at ~/.yome/blacklist-cache.json. Format:
|
|
12
|
+
//
|
|
13
|
+
// { fetched_at: ISO,
|
|
14
|
+
// entries: [{ slug, reason, detail?, added_at }] }
|
|
15
|
+
//
|
|
16
|
+
// We intentionally cache even when `entries` is empty so the next `list`
|
|
17
|
+
// doesn't need a network call.
|
|
18
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
20
|
+
import { dirname, join } from 'node:path';
|
|
21
|
+
export const DEFAULT_HUB_BASE = 'https://yome.work';
|
|
22
|
+
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
23
|
+
export function getCachePath() {
|
|
24
|
+
return join(homedir(), '.yome', 'blacklist-cache.json');
|
|
25
|
+
}
|
|
26
|
+
export function readBlacklistCache() {
|
|
27
|
+
const f = getCachePath();
|
|
28
|
+
if (!existsSync(f))
|
|
29
|
+
return null;
|
|
30
|
+
try {
|
|
31
|
+
const obj = JSON.parse(readFileSync(f, 'utf-8'));
|
|
32
|
+
if (!obj || typeof obj !== 'object')
|
|
33
|
+
return null;
|
|
34
|
+
if (!Array.isArray(obj.entries))
|
|
35
|
+
return null;
|
|
36
|
+
return obj;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function writeBlacklistCache(c) {
|
|
43
|
+
const f = getCachePath();
|
|
44
|
+
mkdirSync(dirname(f), { recursive: true });
|
|
45
|
+
writeFileSync(f, JSON.stringify(c, null, 2) + '\n');
|
|
46
|
+
}
|
|
47
|
+
function isFresh(c) {
|
|
48
|
+
const t = Date.parse(c.fetched_at);
|
|
49
|
+
if (!Number.isFinite(t))
|
|
50
|
+
return false;
|
|
51
|
+
return (Date.now() - t) < CACHE_TTL_MS;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Pull the latest blacklist from the hub if needed, write it to the
|
|
55
|
+
* cache, return whatever we ended up with. Network errors are swallowed
|
|
56
|
+
* — the previous cache is returned instead so install never breaks
|
|
57
|
+
* because of a transient hub outage.
|
|
58
|
+
*/
|
|
59
|
+
export async function refreshBlacklist(opts = {}) {
|
|
60
|
+
const cached = readBlacklistCache();
|
|
61
|
+
if (cached && isFresh(cached) && !opts.force)
|
|
62
|
+
return cached;
|
|
63
|
+
const hubBase = (opts.hubBase ?? process.env.YOME_HUB_BASE ?? DEFAULT_HUB_BASE).replace(/\/+$/, '');
|
|
64
|
+
const fetcher = opts.fetcher ?? fetch;
|
|
65
|
+
try {
|
|
66
|
+
const resp = await fetcher(`${hubBase}/api/hub/blacklist`, { headers: { Accept: 'application/json' } });
|
|
67
|
+
if (!resp.ok)
|
|
68
|
+
return cached ?? { fetched_at: new Date().toISOString(), entries: [] };
|
|
69
|
+
const j = (await resp.json());
|
|
70
|
+
if (!j || j.ok !== true || !Array.isArray(j.entries)) {
|
|
71
|
+
return cached ?? { fetched_at: new Date().toISOString(), entries: [] };
|
|
72
|
+
}
|
|
73
|
+
const fresh = {
|
|
74
|
+
fetched_at: new Date().toISOString(),
|
|
75
|
+
entries: j.entries.map((e) => ({
|
|
76
|
+
slug: e.slug,
|
|
77
|
+
reason: e.reason,
|
|
78
|
+
detail: e.detail ?? null,
|
|
79
|
+
added_at: e.added_at,
|
|
80
|
+
})),
|
|
81
|
+
};
|
|
82
|
+
writeBlacklistCache(fresh);
|
|
83
|
+
return fresh;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return cached ?? { fetched_at: new Date().toISOString(), entries: [] };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Sync lookup against the cache only. Returns the entry or null. */
|
|
90
|
+
export function isBlacklistedSync(slug) {
|
|
91
|
+
const c = readBlacklistCache();
|
|
92
|
+
if (!c)
|
|
93
|
+
return null;
|
|
94
|
+
return c.entries.find((e) => e.slug === slug) ?? null;
|
|
95
|
+
}
|
|
96
|
+
/** Fetch + check. Use during install. */
|
|
97
|
+
export async function pingBlacklist(slug, opts = {}) {
|
|
98
|
+
const c = await refreshBlacklist(opts);
|
|
99
|
+
return c.entries.find((e) => e.slug === slug) ?? null;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=blacklist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blacklist.js","sourceRoot":"","sources":["../../src/yomeSkills/blacklist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const KNOWN_CAPABILITIES: readonly ["fs:read", "fs:write", "fs:delete", "applescript", "network", "shell"];
|
|
2
|
+
export type Capability = (typeof KNOWN_CAPABILITIES)[number];
|
|
3
|
+
export interface AllowedCapabilities {
|
|
4
|
+
/** Schema version for forward compatibility. */
|
|
5
|
+
version: 1;
|
|
6
|
+
/** ISO-8601 timestamp when the user (or auto-grant) decided. */
|
|
7
|
+
granted_at: string;
|
|
8
|
+
/** Subset of the manifest's declared capabilities the user said yes to. */
|
|
9
|
+
allowed: Capability[];
|
|
10
|
+
/** "user" / "auto-official" / "yes-flag". */
|
|
11
|
+
granted_by: 'user' | 'auto-official' | 'yes-flag';
|
|
12
|
+
}
|
|
13
|
+
export declare function describeCapability(c: Capability): string;
|
|
14
|
+
/** Strip duplicates and unknown entries from a manifest's `capabilities`. */
|
|
15
|
+
export declare function normaliseDeclared(declared: readonly string[] | undefined): Capability[];
|
|
16
|
+
export declare function isOfficialSlug(slug: string): boolean;
|
|
17
|
+
export declare function readAllowedCapabilities(slug: string): AllowedCapabilities | null;
|
|
18
|
+
export declare function writeAllowedCapabilities(slug: string, ac: AllowedCapabilities): void;
|
|
19
|
+
/**
|
|
20
|
+
* Decide which capabilities to grant during a fresh install.
|
|
21
|
+
*
|
|
22
|
+
* Rules:
|
|
23
|
+
* - Empty declared → grant nothing (no prompt).
|
|
24
|
+
* - Official slug → auto-grant everything declared.
|
|
25
|
+
* - `assumeYes` (--yes) → grant everything declared, mark "yes-flag".
|
|
26
|
+
* - Otherwise → ask the user (TTY).
|
|
27
|
+
* - In non-TTY, default to **deny** (return ok=false, reason).
|
|
28
|
+
*/
|
|
29
|
+
export interface GrantOptions {
|
|
30
|
+
/** Bypass the prompt and grant everything (CI / -y). */
|
|
31
|
+
assumeYes?: boolean;
|
|
32
|
+
/** Test seam: replace the prompt with a deterministic answer. */
|
|
33
|
+
prompt?: (declared: readonly Capability[], slug: string) => Promise<boolean>;
|
|
34
|
+
/** Test seam: control TTY detection. */
|
|
35
|
+
isTty?: boolean;
|
|
36
|
+
/** Override clock for tests. */
|
|
37
|
+
now?: () => Date;
|
|
38
|
+
}
|
|
39
|
+
export interface GrantResult {
|
|
40
|
+
ok: boolean;
|
|
41
|
+
granted?: AllowedCapabilities;
|
|
42
|
+
/** Set when ok=false (user declined / non-TTY). */
|
|
43
|
+
reason?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function decideCapabilities(slug: string, declared: readonly string[] | undefined, opts?: GrantOptions): Promise<GrantResult>;
|
|
46
|
+
/** True iff the skill is currently allowed to use `cap`. */
|
|
47
|
+
export declare function isCapabilityAllowed(slug: string, cap: Capability): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Revoke a single capability from an installed skill.
|
|
50
|
+
* Returns true if the file was modified.
|
|
51
|
+
*/
|
|
52
|
+
export declare function revokeCapability(slug: string, cap: Capability, now?: () => Date): boolean;
|
|
53
|
+
/** Re-grant a previously revoked capability (must be in the manifest's declared list to take effect). */
|
|
54
|
+
export declare function grantCapability(slug: string, cap: Capability, now?: () => Date): boolean;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// capabilities.ts — declared / granted *system* capabilities for installed
|
|
2
|
+
// skills.
|
|
3
|
+
//
|
|
4
|
+
// Note on naming: yome-skill.json has had a `capabilities` field since
|
|
5
|
+
// schema v1, but it's used for *semantic* labels ("calendar:read",
|
|
6
|
+
// "ppt:write") that drive the marketplace UI. M9 introduces a separate
|
|
7
|
+
// `system_capabilities` field for the security model — the OS-level
|
|
8
|
+
// resources a skill needs (fs:read, network, applescript, …). At install
|
|
9
|
+
// time we show the user the system_capabilities list and ask "Allow?".
|
|
10
|
+
// The decision is persisted to <skillDir>/allowed-capabilities.json. The
|
|
11
|
+
// agent runtime later refuses any command that exercises a system
|
|
12
|
+
// capability that isn't allowed.
|
|
13
|
+
//
|
|
14
|
+
// "Official" first-party skills (slug starts with "@yome/") get an
|
|
15
|
+
// auto-allow grant — we trust ourselves and don't want to badger the
|
|
16
|
+
// user during the bundled install path. Third-party skills always
|
|
17
|
+
// prompt unless the user passes `--yes`.
|
|
18
|
+
//
|
|
19
|
+
// The system-capability vocabulary is deliberately small + frozen for
|
|
20
|
+
// v0.1. Anything not in KNOWN_CAPABILITIES is silently dropped from a
|
|
21
|
+
// manifest (so the prompt only ever shows things we actually enforce).
|
|
22
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
23
|
+
import { join } from 'node:path';
|
|
24
|
+
import { createInterface } from 'node:readline';
|
|
25
|
+
import { installPathForSlug } from './paths.js';
|
|
26
|
+
export const KNOWN_CAPABILITIES = [
|
|
27
|
+
'fs:read',
|
|
28
|
+
'fs:write',
|
|
29
|
+
'fs:delete',
|
|
30
|
+
'applescript',
|
|
31
|
+
'network',
|
|
32
|
+
'shell',
|
|
33
|
+
];
|
|
34
|
+
const HUMAN_DESCRIPTIONS = {
|
|
35
|
+
'fs:read': 'read files in your home / working directory',
|
|
36
|
+
'fs:write': 'create or modify files in your home / working directory',
|
|
37
|
+
'fs:delete': 'delete files in your home / working directory',
|
|
38
|
+
applescript: 'drive macOS applications via Apple Events (PowerPoint, Calendar, Reminders, …)',
|
|
39
|
+
network: 'make outbound HTTP/HTTPS requests',
|
|
40
|
+
shell: 'run arbitrary shell commands',
|
|
41
|
+
};
|
|
42
|
+
export function describeCapability(c) {
|
|
43
|
+
return HUMAN_DESCRIPTIONS[c] ?? c;
|
|
44
|
+
}
|
|
45
|
+
/** Strip duplicates and unknown entries from a manifest's `capabilities`. */
|
|
46
|
+
export function normaliseDeclared(declared) {
|
|
47
|
+
if (!declared)
|
|
48
|
+
return [];
|
|
49
|
+
const seen = new Set();
|
|
50
|
+
for (const c of declared) {
|
|
51
|
+
if (KNOWN_CAPABILITIES.includes(c)) {
|
|
52
|
+
seen.add(c);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return [...seen].sort();
|
|
56
|
+
}
|
|
57
|
+
export function isOfficialSlug(slug) {
|
|
58
|
+
return slug.startsWith('@yome/');
|
|
59
|
+
}
|
|
60
|
+
function allowedFilePath(slug) {
|
|
61
|
+
const dir = installPathForSlug(slug);
|
|
62
|
+
return dir ? join(dir, 'allowed-capabilities.json') : null;
|
|
63
|
+
}
|
|
64
|
+
export function readAllowedCapabilities(slug) {
|
|
65
|
+
const f = allowedFilePath(slug);
|
|
66
|
+
if (!f || !existsSync(f))
|
|
67
|
+
return null;
|
|
68
|
+
try {
|
|
69
|
+
const obj = JSON.parse(readFileSync(f, 'utf-8'));
|
|
70
|
+
if (obj && typeof obj === 'object' && Array.isArray(obj.allowed)) {
|
|
71
|
+
return obj;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch { /* ignored */ }
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
export function writeAllowedCapabilities(slug, ac) {
|
|
78
|
+
const f = allowedFilePath(slug);
|
|
79
|
+
if (!f)
|
|
80
|
+
throw new Error(`cannot derive install dir for ${slug}`);
|
|
81
|
+
writeFileSync(f, JSON.stringify(ac, null, 2) + '\n');
|
|
82
|
+
}
|
|
83
|
+
export async function decideCapabilities(slug, declared, opts = {}) {
|
|
84
|
+
const norm = normaliseDeclared(declared);
|
|
85
|
+
const now = (opts.now ?? (() => new Date()))().toISOString();
|
|
86
|
+
if (norm.length === 0) {
|
|
87
|
+
return {
|
|
88
|
+
ok: true,
|
|
89
|
+
granted: { version: 1, allowed: [], granted_at: now, granted_by: 'auto-official' },
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (isOfficialSlug(slug)) {
|
|
93
|
+
return {
|
|
94
|
+
ok: true,
|
|
95
|
+
granted: { version: 1, allowed: norm, granted_at: now, granted_by: 'auto-official' },
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (opts.assumeYes) {
|
|
99
|
+
return {
|
|
100
|
+
ok: true,
|
|
101
|
+
granted: { version: 1, allowed: norm, granted_at: now, granted_by: 'yes-flag' },
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Need a yes/no decision from the human.
|
|
105
|
+
const answer = opts.prompt
|
|
106
|
+
? await opts.prompt(norm, slug)
|
|
107
|
+
: await defaultPrompt(norm, slug, opts.isTty);
|
|
108
|
+
if (!answer) {
|
|
109
|
+
return { ok: false, reason: 'user declined the capability grant' };
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
ok: true,
|
|
113
|
+
granted: { version: 1, allowed: norm, granted_at: now, granted_by: 'user' },
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async function defaultPrompt(declared, slug, isTtyOverride) {
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
|
+
const stdinTty = (typeof process.stdin === 'object' && process.stdin.isTTY) === true;
|
|
119
|
+
const isTty = isTtyOverride ?? stdinTty;
|
|
120
|
+
if (!isTty) {
|
|
121
|
+
process.stderr.write(`! ${slug} requires capabilities (${declared.join(', ')}). ` +
|
|
122
|
+
`Re-run with --yes to allow non-interactively, or in a TTY.\n`);
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
process.stdout.write(`\n${slug} requests the following capabilities:\n`);
|
|
126
|
+
for (const c of declared) {
|
|
127
|
+
process.stdout.write(` - ${c}: ${describeCapability(c)}\n`);
|
|
128
|
+
}
|
|
129
|
+
process.stdout.write('Allow? [y/N]: ');
|
|
130
|
+
return await new Promise((resolve) => {
|
|
131
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: false });
|
|
132
|
+
rl.once('line', (line) => {
|
|
133
|
+
rl.close();
|
|
134
|
+
resolve(/^y(es)?$/i.test(line.trim()));
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/** True iff the skill is currently allowed to use `cap`. */
|
|
139
|
+
export function isCapabilityAllowed(slug, cap) {
|
|
140
|
+
const ac = readAllowedCapabilities(slug);
|
|
141
|
+
if (!ac)
|
|
142
|
+
return false;
|
|
143
|
+
return ac.allowed.includes(cap);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Revoke a single capability from an installed skill.
|
|
147
|
+
* Returns true if the file was modified.
|
|
148
|
+
*/
|
|
149
|
+
export function revokeCapability(slug, cap, now = () => new Date()) {
|
|
150
|
+
const ac = readAllowedCapabilities(slug);
|
|
151
|
+
if (!ac)
|
|
152
|
+
return false;
|
|
153
|
+
const before = ac.allowed.length;
|
|
154
|
+
ac.allowed = ac.allowed.filter((x) => x !== cap);
|
|
155
|
+
if (ac.allowed.length === before)
|
|
156
|
+
return false;
|
|
157
|
+
ac.granted_at = now().toISOString();
|
|
158
|
+
ac.granted_by = 'user';
|
|
159
|
+
writeAllowedCapabilities(slug, ac);
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
/** Re-grant a previously revoked capability (must be in the manifest's declared list to take effect). */
|
|
163
|
+
export function grantCapability(slug, cap, now = () => new Date()) {
|
|
164
|
+
const ac = readAllowedCapabilities(slug) ?? {
|
|
165
|
+
version: 1, allowed: [], granted_at: now().toISOString(), granted_by: 'user',
|
|
166
|
+
};
|
|
167
|
+
if (ac.allowed.includes(cap))
|
|
168
|
+
return false;
|
|
169
|
+
ac.allowed = [...ac.allowed, cap].sort();
|
|
170
|
+
ac.granted_at = now().toISOString();
|
|
171
|
+
ac.granted_by = 'user';
|
|
172
|
+
writeAllowedCapabilities(slug, ac);
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/yomeSkills/capabilities.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,UAAU;AACV,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AACnE,uEAAuE;AACvE,oEAAoE;AACpE,yEAAyE;AACzE,uEAAuE;AACvE,yEAAyE;AACzE,kEAAkE;AAClE,iCAAiC;AACjC,EAAE;AACF,mEAAmE;AACnE,qEAAqE;AACrE,kEAAkE;AAClE,yCAAyC;AACzC,EAAE;AACF,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AAEvE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,SAAS;IACT,UAAU;IACV,WAAW;IACX,aAAa;IACb,SAAS;IACT,OAAO;CACC,CAAC;AAcX,MAAM,kBAAkB,GAA+B;IACrD,SAAS,EAAE,6CAA6C;IACxD,UAAU,EAAE,yDAAyD;IACrE,WAAW,EAAE,+CAA+C;IAC5D,WAAW,EAAE,gFAAgF;IAC7F,OAAO,EAAE,mCAAmC;IAC5C,KAAK,EAAE,8BAA8B;CACtC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,CAAa;IAC9C,OAAO,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,iBAAiB,CAAC,QAAuC;IACvE,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAc,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAK,kBAAwC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,IAAI,CAAC,GAAG,CAAC,CAAe,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,2BAA2B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACjE,OAAO,GAA0B,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAY,EAAE,EAAuB;IAC5E,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;IACjE,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC;AA8BD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,QAAuC,EACvC,OAAqB,EAAE;IAEvB,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;IAE7D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,eAAe,EAAE;SACnF,CAAC;IACJ,CAAC;IAED,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,eAAe,EAAE;SACrF,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE;SAChF,CAAC;IACJ,CAAC;IAED,yCAAyC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM;QACxB,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC;QAC/B,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAEhD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC;IACrE,CAAC;IACD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE;KAC5E,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,QAA+B,EAC/B,IAAY,EACZ,aAAuB;IAEvB,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,CAAC,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAK,OAAO,CAAC,KAAa,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;IAC9F,MAAM,KAAK,GAAG,aAAa,IAAI,QAAQ,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,KAAK,IAAI,2BAA2B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YAC5D,8DAA8D,CAC/D,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,yCAAyC,CAAC,CAAC;IACzE,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAEvC,OAAO,MAAM,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QAC5C,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9F,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACvB,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,GAAe;IAC/D,MAAM,EAAE,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACtB,OAAO,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,GAAe,EAAE,MAAkB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IAChG,MAAM,EAAE,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACtB,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;IACjC,EAAE,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IACjD,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC/C,EAAE,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC;IACvB,wBAAwB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,GAAe,EAAE,MAAkB,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;IAC/F,MAAM,EAAE,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI;QAC1C,OAAO,EAAE,CAAU,EAAE,OAAO,EAAE,EAAkB,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,EAAE,UAAU,EAAE,MAAe;KAC/G,CAAC;IACF,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,EAAE,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,EAAE,CAAC,UAAU,GAAG,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC;IACvB,wBAAwB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Capability } from './capabilities.js';
|
|
2
|
+
export interface CapDecision {
|
|
3
|
+
allowed: boolean;
|
|
4
|
+
/** Human-readable reason on denial (suitable for printing to the user). */
|
|
5
|
+
reason?: string;
|
|
6
|
+
/** Where the decision came from — useful in logs. */
|
|
7
|
+
source: 'sidecar' | 'official-no-sidecar' | 'unknown-skill' | 'unknown-cap';
|
|
8
|
+
}
|
|
9
|
+
/** Snapshot of denials since process start. Used by `yome skill doctor` v2. */
|
|
10
|
+
export declare function getDenialCounts(): Array<{
|
|
11
|
+
slug: string;
|
|
12
|
+
capability: string;
|
|
13
|
+
count: number;
|
|
14
|
+
}>;
|
|
15
|
+
/** Reset counters (test seam). */
|
|
16
|
+
export declare function resetDenialCounts(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Synchronous capability check — safe to call from inside a tool dispatch
|
|
19
|
+
* hot path. Reads two small files (manifest + allowed-cap sidecar) but
|
|
20
|
+
* does not block on network or DB.
|
|
21
|
+
*
|
|
22
|
+
* @returns Decision with `allowed: true` ⇒ proceed; otherwise deny and
|
|
23
|
+
* surface `reason` to the LLM so it can pick a different action.
|
|
24
|
+
*/
|
|
25
|
+
export declare function checkCapability(slug: string, cap: Capability | string): CapDecision;
|
|
26
|
+
/**
|
|
27
|
+
* Throwing variant — convenience for dispatchers that prefer exceptions
|
|
28
|
+
* over decision objects. Errors are tagged so callers can render them
|
|
29
|
+
* cleanly to the LLM.
|
|
30
|
+
*/
|
|
31
|
+
export declare function assertCapability(slug: string, cap: Capability | string): void;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// capabilityGuard.ts — runtime gate that the bash-tool intercept layer
|
|
2
|
+
// (and any future skill dispatcher) calls before letting an installed
|
|
3
|
+
// skill exercise an OS capability.
|
|
4
|
+
//
|
|
5
|
+
// Spec ref: 7.6 ("capability 强制 — runtime dispatch 前检查命令是否在 skill
|
|
6
|
+
// 声明的 capabilities 内,越权拒绝") + 11.4-D row "permissions/ —
|
|
7
|
+
// checkSkillCapability".
|
|
8
|
+
//
|
|
9
|
+
// The actual dispatcher is M5+ (spec §11.4-F step 3). This module exists
|
|
10
|
+
// so the security primitive is in place and unit-testable now: when the
|
|
11
|
+
// dispatcher lands, the only call site is `assertCapability(slug, cap)`
|
|
12
|
+
// and we get a single source of truth for the allow/deny logic.
|
|
13
|
+
//
|
|
14
|
+
// Design choices:
|
|
15
|
+
// * We consult the same `allowed-capabilities.json` sidecar that the
|
|
16
|
+
// install-time prompt writes — there is no separate "runtime" grant
|
|
17
|
+
// store. Symmetry between install-time consent and run-time check is
|
|
18
|
+
// the whole point.
|
|
19
|
+
// * We DO NOT consult the *manifest's* declared list at runtime. A skill
|
|
20
|
+
// that revoked a capability via `yome skill perms <slug> --revoke`
|
|
21
|
+
// should be denied even if the manifest still declares it.
|
|
22
|
+
// * Bundled official skills (slug starts with `@yome/`) are treated as
|
|
23
|
+
// pre-trusted IF their allowed-cap sidecar is missing — they ship
|
|
24
|
+
// with the binary, so they never went through the prompt. If a
|
|
25
|
+
// sidecar IS present (e.g. user revoked one), it wins.
|
|
26
|
+
// * Telemetry: every denial increments an in-memory counter the doctor
|
|
27
|
+
// command can surface as "skill X tried to use Y N times — investigate".
|
|
28
|
+
import { readAllowedCapabilities, normaliseDeclared } from './capabilities.js';
|
|
29
|
+
import { readManifest } from './manifest.js';
|
|
30
|
+
import { installPathForSlug } from './paths.js';
|
|
31
|
+
const denialCounters = new Map(); // `${slug}::${cap}` → count
|
|
32
|
+
function bumpDenial(slug, cap) {
|
|
33
|
+
const k = `${slug}::${cap}`;
|
|
34
|
+
denialCounters.set(k, (denialCounters.get(k) ?? 0) + 1);
|
|
35
|
+
}
|
|
36
|
+
/** Snapshot of denials since process start. Used by `yome skill doctor` v2. */
|
|
37
|
+
export function getDenialCounts() {
|
|
38
|
+
return Array.from(denialCounters.entries())
|
|
39
|
+
.map(([k, count]) => {
|
|
40
|
+
const [slug, capability] = k.split('::');
|
|
41
|
+
return { slug, capability, count };
|
|
42
|
+
})
|
|
43
|
+
.sort((a, b) => b.count - a.count);
|
|
44
|
+
}
|
|
45
|
+
/** Reset counters (test seam). */
|
|
46
|
+
export function resetDenialCounts() {
|
|
47
|
+
denialCounters.clear();
|
|
48
|
+
}
|
|
49
|
+
const isOfficial = (slug) => slug.startsWith('@yome/');
|
|
50
|
+
/**
|
|
51
|
+
* Synchronous capability check — safe to call from inside a tool dispatch
|
|
52
|
+
* hot path. Reads two small files (manifest + allowed-cap sidecar) but
|
|
53
|
+
* does not block on network or DB.
|
|
54
|
+
*
|
|
55
|
+
* @returns Decision with `allowed: true` ⇒ proceed; otherwise deny and
|
|
56
|
+
* surface `reason` to the LLM so it can pick a different action.
|
|
57
|
+
*/
|
|
58
|
+
export function checkCapability(slug, cap) {
|
|
59
|
+
const dir = installPathForSlug(slug);
|
|
60
|
+
if (!dir) {
|
|
61
|
+
return { allowed: false, source: 'unknown-skill', reason: `unknown skill slug: ${slug}` };
|
|
62
|
+
}
|
|
63
|
+
const manifest = readManifest(dir);
|
|
64
|
+
if (!manifest) {
|
|
65
|
+
return { allowed: false, source: 'unknown-skill', reason: `${slug}: manifest missing` };
|
|
66
|
+
}
|
|
67
|
+
const declared = new Set(normaliseDeclared(manifest.system_capabilities));
|
|
68
|
+
if (!declared.has(cap)) {
|
|
69
|
+
bumpDenial(slug, String(cap));
|
|
70
|
+
return {
|
|
71
|
+
allowed: false,
|
|
72
|
+
source: 'unknown-cap',
|
|
73
|
+
reason: `${slug} did not declare capability "${cap}" in its manifest — refused.`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const allowed = readAllowedCapabilities(slug);
|
|
77
|
+
if (!allowed) {
|
|
78
|
+
// No sidecar: official skills are pre-trusted; everyone else is denied
|
|
79
|
+
// (defensive default — better to fail closed than to silently grant).
|
|
80
|
+
if (isOfficial(slug)) {
|
|
81
|
+
return { allowed: true, source: 'official-no-sidecar' };
|
|
82
|
+
}
|
|
83
|
+
bumpDenial(slug, String(cap));
|
|
84
|
+
return {
|
|
85
|
+
allowed: false,
|
|
86
|
+
source: 'sidecar',
|
|
87
|
+
reason: `${slug} has no capability grant on file — run \`yome skill perms ${slug} --grant=${cap}\` first.`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (allowed.allowed.includes(cap)) {
|
|
91
|
+
return { allowed: true, source: 'sidecar' };
|
|
92
|
+
}
|
|
93
|
+
bumpDenial(slug, String(cap));
|
|
94
|
+
return {
|
|
95
|
+
allowed: false,
|
|
96
|
+
source: 'sidecar',
|
|
97
|
+
reason: `${slug}: capability "${cap}" was revoked. Re-grant with \`yome skill perms ${slug} --grant=${cap}\`.`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Throwing variant — convenience for dispatchers that prefer exceptions
|
|
102
|
+
* over decision objects. Errors are tagged so callers can render them
|
|
103
|
+
* cleanly to the LLM.
|
|
104
|
+
*/
|
|
105
|
+
export function assertCapability(slug, cap) {
|
|
106
|
+
const d = checkCapability(slug, cap);
|
|
107
|
+
if (!d.allowed) {
|
|
108
|
+
const err = new Error(d.reason ?? 'capability denied');
|
|
109
|
+
err.code = 'YOME_CAPABILITY_DENIED';
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=capabilityGuard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilityGuard.js","sourceRoot":"","sources":["../../src/yomeSkills/capabilityGuard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface SkillCliFlags {
|
|
2
|
+
force?: boolean;
|
|
3
|
+
verbose?: boolean;
|
|
4
|
+
json?: boolean;
|
|
5
|
+
/** --yes: bypass capability prompt during install. */
|
|
6
|
+
yes?: boolean;
|
|
7
|
+
/** --revoke <cap>: capability to revoke (yome skill perms). */
|
|
8
|
+
revoke?: string;
|
|
9
|
+
/** --grant <cap>: capability to grant (yome skill perms). */
|
|
10
|
+
grant?: string;
|
|
11
|
+
/** --skip-verify: bypass post-install sha256 check. Only for dev. */
|
|
12
|
+
skipVerify?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function runSkillSubcommand(args: string[], flags: SkillCliFlags): Promise<number>;
|
|
15
|
+
export declare function runLogin(): Promise<number>;
|
|
16
|
+
export declare function runLogout(): Promise<number>;
|
|
17
|
+
export declare function runWhoami(): Promise<number>;
|