@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.
Files changed (185) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +11 -0
  3. package/README.md +308 -27
  4. package/README.zh-CN.md +335 -0
  5. package/dist/agent.d.ts +24 -2
  6. package/dist/agent.js +34 -2
  7. package/dist/agent.js.map +1 -1
  8. package/dist/context.d.ts +2 -0
  9. package/dist/context.js +116 -11
  10. package/dist/context.js.map +1 -1
  11. package/dist/index.js +147 -9
  12. package/dist/index.js.map +1 -1
  13. package/dist/llm.js +45 -2
  14. package/dist/llm.js.map +1 -1
  15. package/dist/loops/chain.js +8 -0
  16. package/dist/loops/chain.js.map +1 -1
  17. package/dist/loops/evaluator.js +8 -0
  18. package/dist/loops/evaluator.js.map +1 -1
  19. package/dist/loops/orchestrator.js +8 -0
  20. package/dist/loops/orchestrator.js.map +1 -1
  21. package/dist/loops/parallel.js.map +1 -1
  22. package/dist/loops/route.js +8 -0
  23. package/dist/loops/route.js.map +1 -1
  24. package/dist/loops/simple.js +15 -0
  25. package/dist/loops/simple.js.map +1 -1
  26. package/dist/permissions/index.d.ts +1 -1
  27. package/dist/permissions/index.js +1 -1
  28. package/dist/permissions/index.js.map +1 -1
  29. package/dist/permissions/loader.d.ts +20 -1
  30. package/dist/permissions/loader.js +51 -0
  31. package/dist/permissions/loader.js.map +1 -1
  32. package/dist/redact.d.ts +56 -0
  33. package/dist/redact.js +191 -0
  34. package/dist/redact.js.map +1 -0
  35. package/dist/skills/runner/applescript.d.ts +49 -0
  36. package/dist/skills/runner/applescript.js +100 -0
  37. package/dist/skills/runner/applescript.js.map +1 -0
  38. package/dist/skills/runner/dispatcher.d.ts +57 -0
  39. package/dist/skills/runner/dispatcher.js +407 -0
  40. package/dist/skills/runner/dispatcher.js.map +1 -0
  41. package/dist/skills/runner/kernel.d.ts +8 -0
  42. package/dist/skills/runner/kernel.js +732 -0
  43. package/dist/skills/runner/kernel.js.map +1 -0
  44. package/dist/skills/runner/tokenizer.d.ts +36 -0
  45. package/dist/skills/runner/tokenizer.js +177 -0
  46. package/dist/skills/runner/tokenizer.js.map +1 -0
  47. package/dist/threadCli.d.ts +11 -0
  48. package/dist/threadCli.js +177 -0
  49. package/dist/threadCli.js.map +1 -0
  50. package/dist/threadShare.d.ts +21 -0
  51. package/dist/threadShare.js +121 -0
  52. package/dist/threadShare.js.map +1 -0
  53. package/dist/threadSubmit.d.ts +32 -0
  54. package/dist/threadSubmit.js +199 -0
  55. package/dist/threadSubmit.js.map +1 -0
  56. package/dist/tools/bash.js +68 -13
  57. package/dist/tools/bash.js.map +1 -1
  58. package/dist/tools/index.d.ts +22 -2
  59. package/dist/tools/index.js +41 -5
  60. package/dist/tools/index.js.map +1 -1
  61. package/dist/tools/skillCall.d.ts +2 -0
  62. package/dist/tools/skillCall.js +77 -0
  63. package/dist/tools/skillCall.js.map +1 -0
  64. package/dist/ui/AgentPicker.js +3 -3
  65. package/dist/ui/AgentPicker.js.map +1 -1
  66. package/dist/ui/App.js +214 -61
  67. package/dist/ui/App.js.map +1 -1
  68. package/dist/ui/Banner.d.ts +2 -1
  69. package/dist/ui/Banner.js +23 -4
  70. package/dist/ui/Banner.js.map +1 -1
  71. package/dist/ui/InputBar.js +6 -3
  72. package/dist/ui/InputBar.js.map +1 -1
  73. package/dist/ui/Markdown.d.ts +2 -2
  74. package/dist/ui/Markdown.js +22 -7
  75. package/dist/ui/Markdown.js.map +1 -1
  76. package/dist/ui/MarketplacePicker.d.ts +7 -0
  77. package/dist/ui/MarketplacePicker.js +122 -0
  78. package/dist/ui/MarketplacePicker.js.map +1 -0
  79. package/dist/ui/MessageList.d.ts +4 -1
  80. package/dist/ui/MessageList.js +72 -7
  81. package/dist/ui/MessageList.js.map +1 -1
  82. package/dist/ui/ModelPicker.js +4 -4
  83. package/dist/ui/ModelPicker.js.map +1 -1
  84. package/dist/ui/PermissionPrompt.d.ts +16 -4
  85. package/dist/ui/PermissionPrompt.js +60 -15
  86. package/dist/ui/PermissionPrompt.js.map +1 -1
  87. package/dist/ui/SessionPicker.js +2 -2
  88. package/dist/ui/SessionPicker.js.map +1 -1
  89. package/dist/ui/ShimmerText.d.ts +8 -0
  90. package/dist/ui/ShimmerText.js +40 -0
  91. package/dist/ui/ShimmerText.js.map +1 -0
  92. package/dist/ui/Spinner.js +3 -9
  93. package/dist/ui/Spinner.js.map +1 -1
  94. package/dist/ui/TogglePicker.js +4 -4
  95. package/dist/ui/TogglePicker.js.map +1 -1
  96. package/dist/ui/ToolResult.js +6 -0
  97. package/dist/ui/ToolResult.js.map +1 -1
  98. package/dist/ui/UnifiedSkillsPicker.d.ts +10 -0
  99. package/dist/ui/UnifiedSkillsPicker.js +63 -0
  100. package/dist/ui/UnifiedSkillsPicker.js.map +1 -0
  101. package/dist/ui/animation.d.ts +3 -0
  102. package/dist/ui/animation.js +48 -0
  103. package/dist/ui/animation.js.map +1 -0
  104. package/dist/ui/useThrottledStream.d.ts +7 -0
  105. package/dist/ui/useThrottledStream.js +63 -0
  106. package/dist/ui/useThrottledStream.js.map +1 -0
  107. package/dist/yomeSkills/auth.d.ts +20 -0
  108. package/dist/yomeSkills/auth.js +70 -0
  109. package/dist/yomeSkills/auth.js.map +1 -0
  110. package/dist/yomeSkills/blacklist.d.ts +33 -0
  111. package/dist/yomeSkills/blacklist.js +101 -0
  112. package/dist/yomeSkills/blacklist.js.map +1 -0
  113. package/dist/yomeSkills/capabilities.d.ts +54 -0
  114. package/dist/yomeSkills/capabilities.js +175 -0
  115. package/dist/yomeSkills/capabilities.js.map +1 -0
  116. package/dist/yomeSkills/capabilityGuard.d.ts +31 -0
  117. package/dist/yomeSkills/capabilityGuard.js +113 -0
  118. package/dist/yomeSkills/capabilityGuard.js.map +1 -0
  119. package/dist/yomeSkills/cli.d.ts +17 -0
  120. package/dist/yomeSkills/cli.js +477 -0
  121. package/dist/yomeSkills/cli.js.map +1 -0
  122. package/dist/yomeSkills/devLink.d.ts +17 -0
  123. package/dist/yomeSkills/devLink.js +91 -0
  124. package/dist/yomeSkills/devLink.js.map +1 -0
  125. package/dist/yomeSkills/doctor.d.ts +13 -0
  126. package/dist/yomeSkills/doctor.js +152 -0
  127. package/dist/yomeSkills/doctor.js.map +1 -0
  128. package/dist/yomeSkills/enable.d.ts +8 -0
  129. package/dist/yomeSkills/enable.js +67 -0
  130. package/dist/yomeSkills/enable.js.map +1 -0
  131. package/dist/yomeSkills/hubPing.d.ts +1 -0
  132. package/dist/yomeSkills/hubPing.js +41 -0
  133. package/dist/yomeSkills/hubPing.js.map +1 -0
  134. package/dist/yomeSkills/install.d.ts +18 -0
  135. package/dist/yomeSkills/install.js +143 -0
  136. package/dist/yomeSkills/install.js.map +1 -0
  137. package/dist/yomeSkills/installGithub.d.ts +26 -0
  138. package/dist/yomeSkills/installGithub.js +192 -0
  139. package/dist/yomeSkills/installGithub.js.map +1 -0
  140. package/dist/yomeSkills/installMeta.d.ts +8 -0
  141. package/dist/yomeSkills/installMeta.js +76 -0
  142. package/dist/yomeSkills/installMeta.js.map +1 -0
  143. package/dist/yomeSkills/integrity.d.ts +26 -0
  144. package/dist/yomeSkills/integrity.js +107 -0
  145. package/dist/yomeSkills/integrity.js.map +1 -0
  146. package/dist/yomeSkills/invoke.d.ts +29 -0
  147. package/dist/yomeSkills/invoke.js +103 -0
  148. package/dist/yomeSkills/invoke.js.map +1 -0
  149. package/dist/yomeSkills/list.d.ts +11 -0
  150. package/dist/yomeSkills/list.js +55 -0
  151. package/dist/yomeSkills/list.js.map +1 -0
  152. package/dist/yomeSkills/login.d.ts +41 -0
  153. package/dist/yomeSkills/login.js +221 -0
  154. package/dist/yomeSkills/login.js.map +1 -0
  155. package/dist/yomeSkills/manifest.d.ts +60 -0
  156. package/dist/yomeSkills/manifest.js +47 -0
  157. package/dist/yomeSkills/manifest.js.map +1 -0
  158. package/dist/yomeSkills/paths.d.ts +13 -0
  159. package/dist/yomeSkills/paths.js +33 -0
  160. package/dist/yomeSkills/paths.js.map +1 -0
  161. package/dist/yomeSkills/publish.d.ts +16 -0
  162. package/dist/yomeSkills/publish.js +109 -0
  163. package/dist/yomeSkills/publish.js.map +1 -0
  164. package/dist/yomeSkills/rollback.d.ts +10 -0
  165. package/dist/yomeSkills/rollback.js +83 -0
  166. package/dist/yomeSkills/rollback.js.map +1 -0
  167. package/dist/yomeSkills/search.d.ts +21 -0
  168. package/dist/yomeSkills/search.js +31 -0
  169. package/dist/yomeSkills/search.js.map +1 -0
  170. package/dist/yomeSkills/skillsIndex.d.ts +36 -0
  171. package/dist/yomeSkills/skillsIndex.js +111 -0
  172. package/dist/yomeSkills/skillsIndex.js.map +1 -0
  173. package/dist/yomeSkills/unified.d.ts +53 -0
  174. package/dist/yomeSkills/unified.js +187 -0
  175. package/dist/yomeSkills/unified.js.map +1 -0
  176. package/dist/yomeSkills/uninstall.d.ts +7 -0
  177. package/dist/yomeSkills/uninstall.js +22 -0
  178. package/dist/yomeSkills/uninstall.js.map +1 -0
  179. package/dist/yomeSkills/update.d.ts +18 -0
  180. package/dist/yomeSkills/update.js +75 -0
  181. package/dist/yomeSkills/update.js.map +1 -0
  182. package/dist/yomeSkills/validate.d.ts +11 -0
  183. package/dist/yomeSkills/validate.js +99 -0
  184. package/dist/yomeSkills/validate.js.map +1 -0
  185. package/package.json +14 -5
@@ -0,0 +1,192 @@
1
+ // cli/src/yomeSkills/installGithub.ts — install a skill from a GitHub repo.
2
+ //
3
+ // Phase 2 source forms (per spec 8.5 / 11.2):
4
+ // yome skill install github:owner/repo
5
+ // yome skill install github:owner/repo@v1.2.0 (tag/branch/sha)
6
+ // yome skill install github:owner/repo#path/to/skill (subdir within repo)
7
+ // yome skill install https://github.com/owner/repo
8
+ // yome skill install https://github.com/owner/repo/tree/<ref>/path/to/skill
9
+ //
10
+ // Strategy:
11
+ // 1. Parse source → { owner, repo, ref?, subPath? }
12
+ // 2. git clone --depth=1 [-b ref] <https-url> <tmp-dir>
13
+ // 3. cd into <tmp-dir>/<subPath?> and treat it as a local skill
14
+ // 4. Delegate to installFromLocal() — same manifest validation,
15
+ // same install location, same overwrite/force semantics.
16
+ //
17
+ // We deliberately use plain `git clone` (no `gh`) because public skill repos
18
+ // don't require auth and we want install to work for anonymous users too.
19
+ import { spawnSync } from 'node:child_process';
20
+ import { existsSync, mkdtempSync, rmSync } from 'node:fs';
21
+ import { tmpdir } from 'node:os';
22
+ import { join, resolve } from 'node:path';
23
+ import { installFromLocal } from './install.js';
24
+ import { writeInstallMeta } from './installMeta.js';
25
+ import { readManifest } from './manifest.js';
26
+ const DEFAULT_HUB_BASE = 'https://yome.work';
27
+ function getHubBase() {
28
+ return (process.env.YOME_HUB_BASE ?? DEFAULT_HUB_BASE).replace(/\/+$/, '');
29
+ }
30
+ /**
31
+ * Best-effort hub lookup for a skill's expected sha256 fingerprint at
32
+ * the given version. Returns null if the hub doesn't know about this
33
+ * slug, doesn't have a fingerprint for that version (older publish), or
34
+ * is unreachable. The caller treats null as "no verification possible,
35
+ * proceed".
36
+ */
37
+ async function fetchExpectedSha256(slug, version) {
38
+ try {
39
+ const url = `${getHubBase()}/api/hub/skills/${encodeURIComponent(slug)}?version=${encodeURIComponent(version)}`;
40
+ const r = await fetch(url, { headers: { Accept: 'application/json' } });
41
+ if (!r.ok)
42
+ return null;
43
+ const j = (await r.json());
44
+ if (!j || j.ok !== true)
45
+ return null;
46
+ const sha = j.version?.tarball_sha256 ?? null;
47
+ return sha && sha.length >= 32 ? sha : null;
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ const GITHUB_SHORT_RE = /^github:([^/]+)\/([^@#]+)(?:@([^#]+))?(?:#(.+))?$/i;
54
+ const GITHUB_HTTPS_RE = /^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/(?:tree|blob)\/([^/]+)(?:\/(.+))?)?\/?$/i;
55
+ export function parseGithubSource(source) {
56
+ const trimmed = source.trim();
57
+ let owner = null;
58
+ let repo = null;
59
+ let ref;
60
+ let subPath;
61
+ const short = GITHUB_SHORT_RE.exec(trimmed);
62
+ if (short) {
63
+ [, owner, repo, ref, subPath] = short;
64
+ }
65
+ else {
66
+ const long = GITHUB_HTTPS_RE.exec(trimmed);
67
+ if (long) {
68
+ [, owner, repo, ref, subPath] = long;
69
+ }
70
+ }
71
+ if (!owner || !repo)
72
+ return null;
73
+ return {
74
+ owner,
75
+ repo,
76
+ ref: ref || undefined,
77
+ subPath: subPath ? subPath.replace(/^\/+|\/+$/g, '') : undefined,
78
+ cloneUrl: `https://github.com/${owner}/${repo}.git`,
79
+ };
80
+ }
81
+ export function isGithubSource(source) {
82
+ return /^github:/i.test(source) || /^https?:\/\/github\.com\//i.test(source);
83
+ }
84
+ function shallowClone(parsed, verbose) {
85
+ const root = mkdtempSync(join(tmpdir(), 'yome-skill-clone-'));
86
+ const cloneDir = join(root, parsed.repo);
87
+ const args = ['clone', '--depth=1'];
88
+ if (parsed.ref)
89
+ args.push('-b', parsed.ref);
90
+ args.push(parsed.cloneUrl, cloneDir);
91
+ if (verbose)
92
+ console.log(`$ git ${args.join(' ')}`);
93
+ const r = spawnSync('git', args, { encoding: 'utf-8' });
94
+ if (verbose && r.stdout)
95
+ console.log(r.stdout.trimEnd());
96
+ if (verbose && r.stderr)
97
+ console.error(r.stderr.trimEnd());
98
+ if (r.status !== 0) {
99
+ rmSync(root, { recursive: true, force: true });
100
+ const detail = r.stderr?.trim() || `git exited with status ${r.status ?? 'unknown'}`;
101
+ return { ok: false, reason: `git clone failed: ${detail}` };
102
+ }
103
+ return { ok: true, cloneDir };
104
+ }
105
+ /**
106
+ * Clone the repo into a tmp dir, then delegate to `installFromLocal`. Always
107
+ * cleans up the tmp clone, even on failure. If `expectedSha256` is provided,
108
+ * we verify the installed bytes match before declaring success.
109
+ */
110
+ export async function installFromGithub(source, opts = {}) {
111
+ const parsed = parseGithubSource(source);
112
+ if (!parsed) {
113
+ return { ok: false, reason: `not a GitHub source: ${source}` };
114
+ }
115
+ // git availability check — `git --version` should always succeed if installed.
116
+ const probe = spawnSync('git', ['--version'], { encoding: 'utf-8' });
117
+ if (probe.status !== 0) {
118
+ return { ok: false, reason: 'git is not installed or not in PATH' };
119
+ }
120
+ const cloned = shallowClone(parsed, !!opts.verbose);
121
+ if (!cloned.ok)
122
+ return cloned;
123
+ let cleanupRoot = resolve(cloned.cloneDir, '..');
124
+ try {
125
+ const skillDir = parsed.subPath ? join(cloned.cloneDir, parsed.subPath) : cloned.cloneDir;
126
+ if (!existsSync(skillDir)) {
127
+ return { ok: false, reason: `subpath "${parsed.subPath}" does not exist in ${parsed.owner}/${parsed.repo}` };
128
+ }
129
+ if (!existsSync(join(skillDir, 'yome-skill.json'))) {
130
+ return { ok: false, reason: `${parsed.owner}/${parsed.repo}${parsed.subPath ? `/${parsed.subPath}` : ''} has no yome-skill.json` };
131
+ }
132
+ // If the caller didn't pre-fetch an expectedSha256, do it now from
133
+ // the hub. Best-effort — hub unreachable or no fingerprint → null,
134
+ // and the install proceeds without verification (back-compat).
135
+ if (!opts.skipVerify && !opts.expectedSha256) {
136
+ const cloneManifest = readManifest(skillDir);
137
+ if (cloneManifest) {
138
+ opts.expectedSha256 = await fetchExpectedSha256(cloneManifest.slug, cloneManifest.version);
139
+ }
140
+ }
141
+ const result = await installFromLocal(skillDir, opts);
142
+ if (result.ok && result.slug) {
143
+ // installFromLocal stamped the meta with `local:<tmp clone path>`; rewrite
144
+ // it to the github: shorthand so `yome skill update` knows what to refetch.
145
+ try {
146
+ writeInstallMeta(result.slug, {
147
+ source: githubSourceToShorthand(parsed),
148
+ installed_at: new Date().toISOString(),
149
+ manifest_version: result.slug ? '' : '',
150
+ });
151
+ // Keep the version field accurate by reading the manifest at dest.
152
+ const m = readManifest(result.installedAt);
153
+ if (m) {
154
+ writeInstallMeta(result.slug, {
155
+ source: githubSourceToShorthand(parsed),
156
+ installed_at: new Date().toISOString(),
157
+ manifest_version: m.version,
158
+ });
159
+ }
160
+ }
161
+ catch { /* best effort */ }
162
+ // Post-install sha256 verification. If the hub had no fingerprint
163
+ // for this version (older publish), expectedSha256 is null/undefined
164
+ // and we skip — the install proceeds. If it doesn't match, we
165
+ // tear down the install dir to leave the system in a clean state.
166
+ if (!opts.skipVerify && opts.expectedSha256 && result.installedAt) {
167
+ const { verifySkillSha256 } = await import('./integrity.js');
168
+ const v = verifySkillSha256(result.installedAt, opts.expectedSha256);
169
+ if (!v.ok) {
170
+ rmSync(result.installedAt, { recursive: true, force: true });
171
+ return {
172
+ ok: false,
173
+ reason: `sha256 mismatch — refusing install. expected ${v.expected.slice(0, 12)}…, got ${v.computed.slice(0, 12)}…`,
174
+ };
175
+ }
176
+ }
177
+ }
178
+ return result;
179
+ }
180
+ finally {
181
+ rmSync(cleanupRoot, { recursive: true, force: true });
182
+ }
183
+ }
184
+ function githubSourceToShorthand(p) {
185
+ let s = `github:${p.owner}/${p.repo}`;
186
+ if (p.ref)
187
+ s += `@${p.ref}`;
188
+ if (p.subPath)
189
+ s += `#${p.subPath}`;
190
+ return s;
191
+ }
192
+ //# sourceMappingURL=installGithub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installGithub.js","sourceRoot":"","sources":["../../src/yomeSkills/installGithub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface InstallMeta {
2
+ source: string;
3
+ installed_at: string;
4
+ manifest_version: string;
5
+ }
6
+ export declare function readInstallMeta(slugOrDir: string): InstallMeta | null;
7
+ export declare function writeInstallMeta(slugOrDir: string, meta: InstallMeta): void;
8
+ export declare function clearInstallMeta(slugOrDir: string): void;
@@ -0,0 +1,76 @@
1
+ // `.install-meta.json` — small per-skill sidecar capturing how the skill
2
+ // was installed. Used by `yome skill update` (to know what to re-pull)
3
+ // and `yome skill list` (to render the source column).
4
+ //
5
+ // Schema (intentionally tiny so it's easy to bump):
6
+ // {
7
+ // "source": "github:owner/repo[@ref][#subpath]"
8
+ // | "local:/abs/path"
9
+ // | "dev-link:/abs/path"
10
+ // | "hub:@owner/name"
11
+ // | "url:<https url>",
12
+ // "installed_at": "<ISO-8601>",
13
+ // "manifest_version": "<from yome-skill.json at install time>"
14
+ // }
15
+ //
16
+ // Missing file = legacy install (pre-meta); `update` treats it as
17
+ // "source unknown — please reinstall manually".
18
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, } from 'fs';
19
+ import { join, dirname } from 'path';
20
+ import { installPathForSlug } from './paths.js';
21
+ const META_FILENAME = '.install-meta.json';
22
+ function metaPath(slugOrDir) {
23
+ // Accept either a slug like @yome/ppt OR an absolute install dir.
24
+ if (slugOrDir.startsWith('/') || slugOrDir.startsWith('.')) {
25
+ return join(slugOrDir, META_FILENAME);
26
+ }
27
+ const dir = installPathForSlug(slugOrDir);
28
+ if (!dir)
29
+ throw new Error(`invalid slug: ${slugOrDir}`);
30
+ return join(dir, META_FILENAME);
31
+ }
32
+ export function readInstallMeta(slugOrDir) {
33
+ let f;
34
+ try {
35
+ f = metaPath(slugOrDir);
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ if (!existsSync(f))
41
+ return null;
42
+ try {
43
+ const obj = JSON.parse(readFileSync(f, 'utf-8'));
44
+ if (typeof obj?.source !== 'string')
45
+ return null;
46
+ return {
47
+ source: String(obj.source),
48
+ installed_at: String(obj.installed_at ?? ''),
49
+ manifest_version: String(obj.manifest_version ?? ''),
50
+ };
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ export function writeInstallMeta(slugOrDir, meta) {
57
+ const f = metaPath(slugOrDir);
58
+ mkdirSync(dirname(f), { recursive: true });
59
+ writeFileSync(f, JSON.stringify(meta, null, 2) + '\n');
60
+ }
61
+ export function clearInstallMeta(slugOrDir) {
62
+ let f;
63
+ try {
64
+ f = metaPath(slugOrDir);
65
+ }
66
+ catch {
67
+ return;
68
+ }
69
+ if (existsSync(f)) {
70
+ try {
71
+ unlinkSync(f);
72
+ }
73
+ catch { /* ignore */ }
74
+ }
75
+ }
76
+ //# sourceMappingURL=installMeta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installMeta.js","sourceRoot":"","sources":["../../src/yomeSkills/installMeta.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,uEAAuE;AACvE,uDAAuD;AACvD,EAAE;AACF,oDAAoD;AACpD,MAAM;AACN,oDAAoD;AACpD,kCAAkC;AAClC,qCAAqC;AACrC,kCAAkC;AAClC,mCAAmC;AACnC,oCAAoC;AACpC,mEAAmE;AACnE,MAAM;AACN,EAAE;AACF,kEAAkE;AAClE,gDAAgD;AAEhD,OAAO,EACL,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,GAC/D,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAQhD,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAE3C,SAAS,QAAQ,CAAC,SAAiB;IACjC,kEAAkE;IAClE,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,GAAG,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,SAAS,EAAE,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,IAAI,CAAS,CAAC;IACd,IAAI,CAAC;QAAC,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,IAAI,OAAO,GAAG,EAAE,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACjD,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;YAC1B,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;YAC5C,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;SACrD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,IAAiB;IACnE,MAAM,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC9B,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,IAAI,CAAS,CAAC;IACd,IAAI,CAAC;QAAC,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO;IAAC,CAAC;IAClD,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC;YAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Files & directories that should never contribute to a skill hash.
3
+ * - VCS plumbing (.git/) is environmental, not skill content.
4
+ * - .install-meta.json / .yome-disabled / allowed-capabilities.json are
5
+ * per-install state files we write *after* the bytes land — including
6
+ * them would create chicken-and-egg.
7
+ * - Build artefacts (node_modules, dist, .DS_Store) are noise.
8
+ */
9
+ export declare const DEFAULT_IGNORES: ReadonlySet<string>;
10
+ export interface ComputeOptions {
11
+ /** Override the default ignore set entirely. */
12
+ ignores?: ReadonlySet<string>;
13
+ }
14
+ /**
15
+ * Compute the canonical sha256 of a skill directory.
16
+ * Returns the hex digest (64 chars).
17
+ */
18
+ export declare function computeSkillSha256(skillDir: string, opts?: ComputeOptions): string;
19
+ export interface VerifyResult {
20
+ ok: boolean;
21
+ /** Always present so callers can log. */
22
+ computed: string;
23
+ expected: string;
24
+ }
25
+ /** Recompute and compare against an expected hex digest. */
26
+ export declare function verifySkillSha256(skillDir: string, expected: string, opts?: ComputeOptions): VerifyResult;
@@ -0,0 +1,107 @@
1
+ // integrity.ts — content-addressed hash of an installed/source skill.
2
+ //
3
+ // Threat model: a user runs `yome skill install github:Whopus/foo`. Between
4
+ // `git clone` and the bytes landing in ~/.yome/skills the network /
5
+ // CDN / GitHub mirror could substitute different content. We give the
6
+ // hub a sha256 fingerprint at publish time; install verifies it matches.
7
+ //
8
+ // Algorithm (deliberately simple, deterministic, and language-agnostic):
9
+ //
10
+ // 1. Walk the skill directory recursively, collect every file path
11
+ // relative to the skill root, except those in DEFAULT_IGNORES.
12
+ // 2. Sort paths byte-wise (NFC, no normalisation — "what's on disk").
13
+ // 3. Build a stream of records:
14
+ // <relative path> NUL <byte length, ASCII> NUL <file bytes> NUL
15
+ // 4. Return the SHA-256 hex digest of the concatenated stream.
16
+ //
17
+ // Properties:
18
+ // - Same directory tree → same digest, regardless of OS readdir order.
19
+ // - Adding/removing/renaming any file changes the digest.
20
+ // - Filesystem perms / mtime do NOT affect the digest (intentionally —
21
+ // `git clone` resets times, and installing copies don't preserve them).
22
+ import { createHash } from 'node:crypto';
23
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
24
+ import { join, relative, sep } from 'node:path';
25
+ /**
26
+ * Files & directories that should never contribute to a skill hash.
27
+ * - VCS plumbing (.git/) is environmental, not skill content.
28
+ * - .install-meta.json / .yome-disabled / allowed-capabilities.json are
29
+ * per-install state files we write *after* the bytes land — including
30
+ * them would create chicken-and-egg.
31
+ * - Build artefacts (node_modules, dist, .DS_Store) are noise.
32
+ */
33
+ export const DEFAULT_IGNORES = new Set([
34
+ '.git',
35
+ 'node_modules',
36
+ 'dist',
37
+ '.next',
38
+ '.turbo',
39
+ 'coverage',
40
+ '.DS_Store',
41
+ '.install-meta.json',
42
+ '.yome-disabled',
43
+ 'allowed-capabilities.json',
44
+ ]);
45
+ /**
46
+ * Walk dir → return relative paths (slash-separated for portability)
47
+ * sorted byte-wise.
48
+ */
49
+ function listFiles(root, ignores) {
50
+ const out = [];
51
+ function walk(abs) {
52
+ let entries;
53
+ try {
54
+ entries = readdirSync(abs);
55
+ }
56
+ catch {
57
+ return;
58
+ }
59
+ for (const e of entries) {
60
+ if (ignores.has(e))
61
+ continue;
62
+ const p = join(abs, e);
63
+ let st;
64
+ try {
65
+ st = statSync(p);
66
+ }
67
+ catch {
68
+ continue;
69
+ }
70
+ if (st.isDirectory())
71
+ walk(p);
72
+ else if (st.isFile()) {
73
+ // Normalise to forward-slash so digests are stable cross-platform.
74
+ out.push(relative(root, p).split(sep).join('/'));
75
+ }
76
+ }
77
+ }
78
+ walk(root);
79
+ out.sort();
80
+ return out;
81
+ }
82
+ /**
83
+ * Compute the canonical sha256 of a skill directory.
84
+ * Returns the hex digest (64 chars).
85
+ */
86
+ export function computeSkillSha256(skillDir, opts = {}) {
87
+ const ignores = opts.ignores ?? DEFAULT_IGNORES;
88
+ const files = listFiles(skillDir, ignores);
89
+ const h = createHash('sha256');
90
+ const NUL = Buffer.from([0]);
91
+ for (const rel of files) {
92
+ const bytes = readFileSync(join(skillDir, rel));
93
+ h.update(rel, 'utf-8');
94
+ h.update(NUL);
95
+ h.update(String(bytes.byteLength), 'utf-8');
96
+ h.update(NUL);
97
+ h.update(bytes);
98
+ h.update(NUL);
99
+ }
100
+ return h.digest('hex');
101
+ }
102
+ /** Recompute and compare against an expected hex digest. */
103
+ export function verifySkillSha256(skillDir, expected, opts = {}) {
104
+ const computed = computeSkillSha256(skillDir, opts);
105
+ return { ok: computed.toLowerCase() === expected.toLowerCase(), computed, expected };
106
+ }
107
+ //# sourceMappingURL=integrity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrity.js","sourceRoot":"","sources":["../../src/yomeSkills/integrity.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,4EAA4E;AAC5E,oEAAoE;AACpE,sEAAsE;AACtE,yEAAyE;AACzE,EAAE;AACF,yEAAyE;AACzE,EAAE;AACF,qEAAqE;AACrE,oEAAoE;AACpE,wEAAwE;AACxE,kCAAkC;AAClC,uEAAuE;AACvE,iEAAiE;AACjE,EAAE;AACF,cAAc;AACd,yEAAyE;AACzE,4DAA4D;AAC5D,yEAAyE;AACzE,4EAA4E;AAE5E,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC;IAC1D,MAAM;IACN,cAAc;IACd,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,WAAW;IACX,oBAAoB;IACpB,gBAAgB;IAChB,2BAA2B;CAC5B,CAAC,CAAC;AAOH;;;GAGG;AACH,SAAS,SAAS,CAAC,IAAY,EAAE,OAA4B;IAC3D,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,SAAS,IAAI,CAAC,GAAW;QACvB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YAAC,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;QACnC,MAAM,CAAC;YAAC,OAAO;QAAC,CAAC;QACjB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,SAAS;YAC7B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACvB,IAAI,EAAE,CAAC;YACP,IAAI,CAAC;gBAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC7C,IAAI,EAAE,CAAC,WAAW,EAAE;gBAAE,IAAI,CAAC,CAAC,CAAC,CAAC;iBACzB,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC;gBACrB,mEAAmE;gBACnE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,CAAC;IACX,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,OAAuB,EAAE;IAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC;IAChD,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;QAChD,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACvB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;QAC5C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AASD,4DAA4D;AAC5D,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,QAAgB,EAAE,OAAuB,EAAE;IAC7F,MAAM,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACvF,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { type SkillIndexEntry } from './skillsIndex.js';
2
+ export interface InvokeRequest {
3
+ /** Either '@owner/name' (preferred) or just a domain like 'ppt'. */
4
+ slugOrDomain: string;
5
+ /** Action name, e.g. 'new', 'slide.add'. */
6
+ action: string;
7
+ positionals?: string[];
8
+ flags?: Record<string, string | boolean | number | undefined>;
9
+ }
10
+ export interface InvokeResult {
11
+ ok: boolean;
12
+ stdout: string;
13
+ stderr: string;
14
+ exitCode: number;
15
+ /** Diagnostic — which skill we resolved to. */
16
+ resolvedSlug?: string;
17
+ }
18
+ /**
19
+ * Find the installed skill record for either `@owner/name` or `<domain>`.
20
+ * Domain lookup picks the first installed skill that owns that domain;
21
+ * if you have multiple, prefer the explicit slug.
22
+ */
23
+ export declare function resolveSkill(slugOrDomain: string): SkillIndexEntry | null;
24
+ /**
25
+ * Run an action. Honors capability grants — anything the manifest
26
+ * declares as required (and that hasn't been allowed by the user) blocks
27
+ * the call before we touch osascript.
28
+ */
29
+ export declare function invokeSkill(req: InvokeRequest): Promise<InvokeResult>;
@@ -0,0 +1,103 @@
1
+ // cli/src/yomeSkills/invoke.ts
2
+ //
3
+ // Top-level entry point for "execute an action on an installed hub
4
+ // skill". Handles slug/domain resolution, capability enforcement, and
5
+ // platform/backend selection. Both the `SkillCall` agent tool and the
6
+ // `yome <domain> <action>` CLI route through this.
7
+ import { homedir } from 'os';
8
+ import { getInstalledFast } from './skillsIndex.js';
9
+ import { readManifest } from './manifest.js';
10
+ import { isCapabilityAllowed } from './capabilities.js';
11
+ import { dispatchMacos, } from '../skills/runner/dispatcher.js';
12
+ /** Expand ~ in a path arg the same way a shell would. */
13
+ function expandTilde(v) {
14
+ if (typeof v !== 'string')
15
+ return v;
16
+ if (v === '~')
17
+ return homedir();
18
+ if (v.startsWith('~/'))
19
+ return homedir() + v.slice(1);
20
+ return v;
21
+ }
22
+ /**
23
+ * Find the installed skill record for either `@owner/name` or `<domain>`.
24
+ * Domain lookup picks the first installed skill that owns that domain;
25
+ * if you have multiple, prefer the explicit slug.
26
+ */
27
+ export function resolveSkill(slugOrDomain) {
28
+ const installed = getInstalledFast();
29
+ if (slugOrDomain.startsWith('@')) {
30
+ return installed.find((s) => s.slug === slugOrDomain) ?? null;
31
+ }
32
+ return installed.find((s) => s.domain === slugOrDomain) ?? null;
33
+ }
34
+ /**
35
+ * Run an action. Honors capability grants — anything the manifest
36
+ * declares as required (and that hasn't been allowed by the user) blocks
37
+ * the call before we touch osascript.
38
+ */
39
+ export async function invokeSkill(req) {
40
+ const entry = resolveSkill(req.slugOrDomain);
41
+ if (!entry) {
42
+ return {
43
+ ok: false, stdout: '', stderr: `skill not installed: ${req.slugOrDomain}`,
44
+ exitCode: 127,
45
+ };
46
+ }
47
+ if (entry.status !== 'enabled') {
48
+ return {
49
+ ok: false, stdout: '', stderr: `skill ${entry.slug} is disabled — enable it via /skills`,
50
+ exitCode: 1, resolvedSlug: entry.slug,
51
+ };
52
+ }
53
+ const manifest = readManifest(entry.installedAt);
54
+ if (!manifest) {
55
+ return {
56
+ ok: false, stdout: '', stderr: `failed to read manifest at ${entry.installedAt}`,
57
+ exitCode: 1, resolvedSlug: entry.slug,
58
+ };
59
+ }
60
+ // Enforce declared OS-level capabilities (security model).
61
+ // Note: manifest.capabilities holds *semantic* labels (calendar:read);
62
+ // system_capabilities holds the OS-level set we actually gate on.
63
+ const declared = (manifest.system_capabilities ?? []);
64
+ const missing = [];
65
+ for (const cap of declared) {
66
+ if (!isCapabilityAllowed(entry.slug, cap))
67
+ missing.push(cap);
68
+ }
69
+ if (missing.length > 0) {
70
+ return {
71
+ ok: false, stdout: '',
72
+ stderr: `capability not granted: ${missing.join(', ')}\n` +
73
+ `Run: yome skill perms ${entry.slug} --grant ${missing[0]}`,
74
+ exitCode: 13, resolvedSlug: entry.slug,
75
+ };
76
+ }
77
+ // Pick the right backend for this host. We're CLI-on-macOS so the
78
+ // delivery.macos slot is what we want; if the skill only ships a node
79
+ // backend, dispatch to that instead (M1 — node backend not implemented
80
+ // yet, returns an explanatory error).
81
+ const platform = process.platform;
82
+ if (platform !== 'darwin') {
83
+ return {
84
+ ok: false, stdout: '',
85
+ stderr: `hub skill execution currently requires macOS (got ${platform})`,
86
+ exitCode: 1, resolvedSlug: entry.slug,
87
+ };
88
+ }
89
+ const r = await runMacos(entry, req);
90
+ return { ...r, resolvedSlug: entry.slug };
91
+ }
92
+ async function runMacos(entry, req) {
93
+ // Expand ~ everywhere — AppleScript's `POSIX file "..."` doesn't honour
94
+ // tilde, and forcing the LLM to spell out /Users/me/... is annoying.
95
+ const positionals = (req.positionals ?? []).map((p) => typeof p === 'string' ? expandTilde(p) : p);
96
+ const flags = {};
97
+ for (const [k, v] of Object.entries(req.flags ?? {})) {
98
+ flags[k] = expandTilde(v);
99
+ }
100
+ const call = { positionals, flags };
101
+ return dispatchMacos(entry.installedAt, req.action, call);
102
+ }
103
+ //# sourceMappingURL=invoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../src/yomeSkills/invoke.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type SkillManifest } from './manifest.js';
2
+ export interface InstalledEntry {
3
+ slug: string;
4
+ domain: string;
5
+ version: string;
6
+ name?: string;
7
+ description?: string;
8
+ installedAt: string;
9
+ manifest: SkillManifest;
10
+ }
11
+ export declare function listInstalled(): InstalledEntry[];
@@ -0,0 +1,55 @@
1
+ // `yome skill list` — enumerate installed yome-skill.json skills under
2
+ // ~/.yome/skills/<owner>/<name>/. Skills using the legacy SKILL.md
3
+ // markdown format are silently ignored (different system, see existing
4
+ // cli/src/skills/loader.ts).
5
+ import { existsSync, readdirSync, statSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { readManifest } from './manifest.js';
8
+ import { getYomeSkillsRoot } from './paths.js';
9
+ function listChildDirs(dir) {
10
+ if (!existsSync(dir))
11
+ return [];
12
+ try {
13
+ return readdirSync(dir).filter((n) => {
14
+ // Skip rollback snapshots — install.ts moves the previous version
15
+ // sideways to <slug>.previous before overwriting. They have a valid
16
+ // yome-skill.json so they'd otherwise look like a duplicate install.
17
+ if (n.endsWith('.previous'))
18
+ return false;
19
+ try {
20
+ return statSync(join(dir, n)).isDirectory();
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ });
26
+ }
27
+ catch {
28
+ return [];
29
+ }
30
+ }
31
+ export function listInstalled() {
32
+ const root = getYomeSkillsRoot();
33
+ const out = [];
34
+ for (const owner of listChildDirs(root)) {
35
+ const ownerDir = join(root, owner);
36
+ for (const name of listChildDirs(ownerDir)) {
37
+ const skillDir = join(ownerDir, name);
38
+ const manifest = readManifest(skillDir);
39
+ if (!manifest)
40
+ continue;
41
+ out.push({
42
+ slug: manifest.slug,
43
+ domain: manifest.domain,
44
+ version: manifest.version,
45
+ name: manifest.name,
46
+ description: manifest.description,
47
+ installedAt: skillDir,
48
+ manifest,
49
+ });
50
+ }
51
+ }
52
+ out.sort((a, b) => a.slug.localeCompare(b.slug));
53
+ return out;
54
+ }
55
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/yomeSkills/list.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,mEAAmE;AACnE,uEAAuE;AACvE,6BAA6B;AAE7B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAsB,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAY/C,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACnC,kEAAkE;YAClE,oEAAoE;YACpE,qEAAqE;YACrE,IAAI,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC1C,IAAI,CAAC;gBAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,KAAK,CAAC;YAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IACjC,MAAM,GAAG,GAAqB,EAAE,CAAC;IAEjC,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACxC,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACxB,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,WAAW,EAAE,QAAQ;gBACrB,QAAQ;aACT,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,OAAO,GAAG,CAAC;AACb,CAAC"}