@lyupro/skillforge-mcp 1.2.0 → 1.4.0
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +47 -0
- package/README.md +27 -12
- package/dist/cli/dispatcher.d.ts.map +1 -1
- package/dist/cli/dispatcher.js +13 -10
- package/dist/cli/dispatcher.js.map +1 -1
- package/dist/cli/folders-format.d.ts +10 -0
- package/dist/cli/folders-format.d.ts.map +1 -0
- package/dist/cli/folders-format.js +41 -0
- package/dist/cli/folders-format.js.map +1 -0
- package/dist/cli/folders-handlers.d.ts +16 -0
- package/dist/cli/folders-handlers.d.ts.map +1 -0
- package/dist/cli/folders-handlers.js +195 -0
- package/dist/cli/folders-handlers.js.map +1 -0
- package/dist/cli/folders-shared.d.ts +29 -0
- package/dist/cli/folders-shared.d.ts.map +1 -0
- package/dist/cli/folders-shared.js +82 -0
- package/dist/cli/folders-shared.js.map +1 -0
- package/dist/cli/folders.d.ts +7 -2
- package/dist/cli/folders.d.ts.map +1 -1
- package/dist/cli/folders.js +28 -177
- package/dist/cli/folders.js.map +1 -1
- package/dist/cli/skills-format.d.ts +15 -0
- package/dist/cli/skills-format.d.ts.map +1 -0
- package/dist/cli/skills-format.js +84 -0
- package/dist/cli/skills-format.js.map +1 -0
- package/dist/cli/skills-handlers.d.ts +15 -0
- package/dist/cli/skills-handlers.d.ts.map +1 -0
- package/dist/cli/skills-handlers.js +112 -0
- package/dist/cli/skills-handlers.js.map +1 -0
- package/dist/cli/skills-shared.d.ts +32 -0
- package/dist/cli/skills-shared.d.ts.map +1 -0
- package/dist/cli/skills-shared.js +90 -0
- package/dist/cli/skills-shared.js.map +1 -0
- package/dist/cli/skills.d.ts +46 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/cli/skills.js +107 -0
- package/dist/cli/skills.js.map +1 -0
- package/dist/cli/tools.d.ts.map +1 -1
- package/dist/cli/tools.js +6 -0
- package/dist/cli/tools.js.map +1 -1
- package/dist/config/config-schema.d.ts +248 -136
- package/dist/config/config-schema.d.ts.map +1 -1
- package/dist/config/config-schema.js +34 -14
- package/dist/config/config-schema.js.map +1 -1
- package/dist/detect/skill-source-conflict.d.ts +24 -7
- package/dist/detect/skill-source-conflict.d.ts.map +1 -1
- package/dist/detect/skill-source-conflict.js +62 -10
- package/dist/detect/skill-source-conflict.js.map +1 -1
- package/dist/reconcile.d.ts +5 -0
- package/dist/reconcile.d.ts.map +1 -0
- package/dist/reconcile.js +20 -0
- package/dist/reconcile.js.map +1 -0
- package/dist/runtime.d.ts +14 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +29 -0
- package/dist/runtime.js.map +1 -0
- package/dist/server-deps.d.ts +3 -1
- package/dist/server-deps.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +26 -9
- package/dist/server.js.map +1 -1
- package/dist/tools/configure.d.ts +2 -0
- package/dist/tools/configure.d.ts.map +1 -1
- package/dist/tools/configure.js +22 -26
- package/dist/tools/configure.js.map +1 -1
- package/dist/tools/list.d.ts +2 -0
- package/dist/tools/list.d.ts.map +1 -1
- package/dist/tools/list.js +12 -0
- package/dist/tools/list.js.map +1 -1
- package/dist/watcher/config-watcher.d.ts +25 -0
- package/dist/watcher/config-watcher.d.ts.map +1 -0
- package/dist/watcher/config-watcher.js +92 -0
- package/dist/watcher/config-watcher.js.map +1 -0
- package/dist/watcher/index.d.ts +2 -0
- package/dist/watcher/index.d.ts.map +1 -1
- package/dist/watcher/index.js +1 -0
- package/dist/watcher/index.js.map +1 -1
- package/manifest.json +3 -3
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"package": "@lyupro/skillforge-mcp"
|
|
15
15
|
},
|
|
16
16
|
"description": "Universal Skills MCP server — load Markdown skills from arbitrary folders, lazy-by-design, cross-tool.",
|
|
17
|
-
"version": "1.
|
|
17
|
+
"version": "1.4.0",
|
|
18
18
|
"author": {
|
|
19
19
|
"name": "Lyu Pro",
|
|
20
20
|
"email": "lyupro.dev@gmail.com"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "skillforge",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"description": "Universal Skills MCP server — load Markdown skills from arbitrary folders, lazy-by-design, cross-tool.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Lyu Pro",
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to **SkillForge MCP** are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
+
## [1.4.0] — 2026-05-17
|
|
6
|
+
|
|
7
|
+
Config live-reload, a new `skills` CLI subcommand, more accurate conflict detection, and forward-compatible config schemas.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`ConfigWatcher`** (`src/watcher/config-watcher.ts`) — watches the config directory and reconciles the folder list and skill registry whenever `config.json` changes on disk. Previously a long-lived MCP server held a startup snapshot and never saw edits made by the `skillforge folders` CLI (which writes from a separate process) until the server was restarted. `skills__configure` `list_folders` and `get_blacklist` now report current disk state instead of the in-memory snapshot.
|
|
12
|
+
- **`skillforge skills` CLI subcommand** (`src/cli/skills.ts`) — terminal-side skill inspection without an LLM session. Three commands:
|
|
13
|
+
- `skills list` — prints a table of all registered skills. Filters: `--search <text>`, `--source <name>`, `--folder <path|alias>`, `--folder-tag <name>`. Display options: `--json`, `--folder-fmt alias|path` (the `FOLDER` column shows the alias by default when one is set).
|
|
14
|
+
- `skills get <name>` — prints the full SKILL.md body and frontmatter for a single skill.
|
|
15
|
+
- `skills reload` — forces a full registry rescan and prints folder/skill counts.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **Conflict-hint accuracy** (`src/detect/skill-source-conflict.ts`) — the skill-source conflict detector (warns when a registered folder overlaps with a host plugin's native store, which would double-load skills) previously ran on path logic alone and warned even for plugins the user had already disabled. It now reads the host's plugin enable state: a disabled plugin produces no warning; an unknown/unreadable enable state produces a softened conditional hint.
|
|
20
|
+
- **Config schema forward-compatibility** (`src/config/config-schema.ts`) — all Zod config schemas previously used the default `strip` mode, silently dropping unknown keys on load/save. Any config written by a newer version of SkillForge would lose unrecognised fields when read by an older version. All schemas now use `passthrough`, so unknown keys survive a full load/save round-trip.
|
|
21
|
+
|
|
22
|
+
### Verified
|
|
23
|
+
|
|
24
|
+
- 609 / 609 tests passing + 1 win32-skip (610 total).
|
|
25
|
+
- `pnpm lint` (`tsc --noEmit`) clean.
|
|
26
|
+
- `pnpm build` clean.
|
|
27
|
+
- `pnpm check:size` — all 68 source files ≤ 400 lines.
|
|
28
|
+
|
|
29
|
+
## [1.3.0] — 2026-05-16
|
|
30
|
+
|
|
31
|
+
Folder ergonomics — address folders by a short alias, toggle them on and off, and filter skills by folder tag.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- Folder alias. A folder entry now carries an optional kebab-case `alias` — a single short handle for a folder. `skillforge folders add <path> --alias <name>` registers it; `skillforge folders remove <name>` and the new `skillforge folders alias <path|alias> <name>` accept the alias in place of the full absolute path. The full path keeps working everywhere. Aliases are validated kebab-case and unique across registered folders — a collision fails with exit ≠ 0 and leaves the config untouched. The `skills__configure` `add_folder` action accepts an `alias` field too, and `folders list` shows an `ALIAS` column.
|
|
36
|
+
- `skillforge folders enable <path|alias>` / `skillforge folders disable <path|alias>` — a two-way toggle for the `enabled` flag. `folders add --disabled` previously had no inverse; re-activating a folder meant hand-editing `config.json`. A disabled folder stays in the config but is skipped on scan.
|
|
37
|
+
- Folder-tag filtering. Folder `tags` were written to the config but never read. `skills__list` now accepts a `folderTag` argument that keeps only skills under folders carrying that tag, and `skillforge folders list --tag <name>` filters the listing the same way. `docs/CONFIGURATION.md` gains a "tags vs alias" section: `alias` is one unique handle per folder for addressing, `tags` are many shared labels for grouping.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
|
|
41
|
+
- `src/cli/folders.ts` split into four flat sibling modules (`folders.ts`, `folders-handlers.ts`, `folders-format.ts`, `folders-shared.ts`) to stay under the 400-line file gate. The `dispatcher.ts` import path is unchanged.
|
|
42
|
+
|
|
43
|
+
### Verified
|
|
44
|
+
|
|
45
|
+
- 561 / 561 tests passing + 1 win32-skip.
|
|
46
|
+
- `pnpm lint` (`tsc --noEmit`) clean.
|
|
47
|
+
- `pnpm build` clean.
|
|
48
|
+
- `pnpm check:size` — all source files ≤ 400 lines.
|
|
49
|
+
|
|
5
50
|
## [1.2.0] — 2026-05-16
|
|
6
51
|
|
|
7
52
|
Terminal-side tooling — inspect MCP tools and manage skill folders without an LLM session, plus repo-local install scope and Claude Code plugin packaging.
|
|
@@ -157,6 +202,8 @@ All 10 verified through real parse pipeline + `StrategyFactory.create()` correct
|
|
|
157
202
|
- **`pnpm build`** clean.
|
|
158
203
|
- **`pnpm smoke`** end-to-end via subprocess `dist/server.js` — LoggingDecorator trace visible.
|
|
159
204
|
|
|
205
|
+
[1.4.0]: https://github.com/lyupro/skillforge-mcp/releases/tag/v1.4.0
|
|
206
|
+
[1.3.0]: https://github.com/lyupro/skillforge-mcp/releases/tag/v1.3.0
|
|
160
207
|
[1.2.0]: https://github.com/lyupro/skillforge-mcp/releases/tag/v1.2.0
|
|
161
208
|
[1.1.1]: https://github.com/lyupro/skillforge-mcp/releases/tag/v1.1.1
|
|
162
209
|
[1.1.0]: https://github.com/lyupro/skillforge-mcp/releases/tag/v1.1.0
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://nodejs.org)
|
|
7
7
|
[](https://modelcontextprotocol.io)
|
|
8
8
|
|
|
9
|
-
**v1.
|
|
9
|
+
**v1.4.0** — 5 MCP tools, one-command install across Claude Code / Codex CLI / Cursor, terminal `tools` + `folders` + `skills` subcommands, config live-reload, forward-compatible config schemas, global/project install scopes, Claude Code plugin packaging, 609 tests, 10 sample skills, modular architecture (all source files ≤ 400 lines).
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -105,7 +105,8 @@ The `skillforge` / `skillforge-mcp` binary is a dispatcher — the first positio
|
|
|
105
105
|
| `install` | Wire SkillForge into Claude Code / Codex CLI / Cursor. Flags: `--claude` / `--codex` / `--cursor` / `--all`, `--dry-run`, `--uninstall`, `--force`, `--entry npx\|local`, `--binary-path <path>`, `--scope global\|project`. |
|
|
106
106
|
| `uninstall` | Reverse a previous install. Accepts the same `--scope global\|project` flag. |
|
|
107
107
|
| `tools` | Print the 5 MCP tools the server exposes (name, description, parameters, example). Pass `--json` for machine-readable output. |
|
|
108
|
-
| `folders` | Manage skill folders from the terminal — `list` / `add` / `remove` / `reset`. |
|
|
108
|
+
| `folders` | Manage skill folders from the terminal — `list` / `add` / `remove` / `alias` / `enable` / `disable` / `reset`. |
|
|
109
|
+
| `skills` | Inspect the skill registry from the terminal — `list` (with `--search`, `--source`, `--folder`, `--folder-tag`, `--json`, `--folder-fmt`), `get <name>`, `reload`. |
|
|
109
110
|
| `--version`, `-v` | Print the package version. |
|
|
110
111
|
| `--help`, `-h` | Print combined usage. |
|
|
111
112
|
|
|
@@ -123,22 +124,30 @@ Prints every MCP tool the server exposes (`skills__list`, `skills__get`, `skills
|
|
|
123
124
|
Folder management is also available from the shell, not just via the `skills__configure` MCP tool inside an LLM session:
|
|
124
125
|
|
|
125
126
|
```bash
|
|
126
|
-
skillforge folders list [--json]
|
|
127
|
-
skillforge folders add <path> [flags]
|
|
128
|
-
skillforge folders remove <path>
|
|
129
|
-
skillforge folders
|
|
127
|
+
skillforge folders list [--json] [--tag <name>] # print registered folders
|
|
128
|
+
skillforge folders add <path> [flags] # register a folder
|
|
129
|
+
skillforge folders remove <path|alias> # remove a folder entry
|
|
130
|
+
skillforge folders alias <path|alias> <name> # set or change a folder alias
|
|
131
|
+
skillforge folders enable <path|alias> # re-activate a disabled folder
|
|
132
|
+
skillforge folders disable <path|alias> # deactivate a folder (kept in config)
|
|
133
|
+
skillforge folders reset --yes # reset folders to the default (empty) list
|
|
130
134
|
```
|
|
131
135
|
|
|
132
136
|
`add` flags:
|
|
133
137
|
|
|
134
138
|
- `--priority <n>` — folder priority (default `100`; higher wins on name collisions).
|
|
135
|
-
- `--
|
|
139
|
+
- `--alias <name>` — a short kebab-case handle, unique across folders. Lets `remove` / `enable` / `disable` target the folder without typing the full path.
|
|
140
|
+
- `--tags <a,b,c>` — comma-separated tags. Filter on them via `folders list --tag <name>` or the `skills__list` `folderTag` argument.
|
|
136
141
|
- `--disabled` — register the folder disabled.
|
|
137
142
|
|
|
138
143
|
```bash
|
|
139
|
-
skillforge folders add ~/.lyupro/skills --priority 50 --tags work,review
|
|
144
|
+
skillforge folders add ~/.lyupro/skills --priority 50 --alias core --tags work,review
|
|
145
|
+
skillforge folders disable core # address it by alias, not by path
|
|
146
|
+
skillforge folders list --tag work # only folders tagged "work"
|
|
140
147
|
```
|
|
141
148
|
|
|
149
|
+
`alias` is one unique handle per folder (addressing); `tags` are many shared labels (grouping and filtering) — see [docs/CONFIGURATION.md](./docs/CONFIGURATION.md) for the full contrast.
|
|
150
|
+
|
|
142
151
|
`reset` requires `--yes` to apply — without it, the command prints what would change and makes no edits. All `folders` actions read and write the same persisted config (`~/.lyupro/.skillforge/config.json`) as the `skills__configure` MCP tool.
|
|
143
152
|
|
|
144
153
|
If you register a folder that already lives inside another tool's native skill store (a Claude Code plugin cache or a Gemini CLI extension), `folders add` prints a hint to disable the duplicate source so the same skills don't load twice. SkillForge only prints the hint — it never edits another tool's config.
|
|
@@ -147,7 +156,7 @@ If you register a folder that already lives inside another tool's native skill s
|
|
|
147
156
|
|
|
148
157
|
| Tool | Purpose |
|
|
149
158
|
|------|---------|
|
|
150
|
-
| `skills__list` | Enumerate available skills (metadata only). Filters: `folder`, `search`, `source`. |
|
|
159
|
+
| `skills__list` | Enumerate available skills (metadata only). Filters: `folder`, `search`, `source`, `folderTag`. |
|
|
151
160
|
| `skills__get` | Fetch full SKILL.md body + metadata for one skill. |
|
|
152
161
|
| `skills__invoke` | Execute a skill via its assigned strategy, wrapped in the decorator chain (Logging → Timeout → Cache). Composite skills (`metadata.skills: [a, b]`) walk nested skills sequentially with DFS cycle detection. |
|
|
153
162
|
| `skills__configure` | Manage configured folders + manual blacklist. Actions: `add_folder`, `remove_folder`, `list_folders`, `set_blacklist`, `get_blacklist`, `reset`. Persists to the config file and reconciles in-process state without restart. |
|
|
@@ -233,15 +242,21 @@ For production use with untrusted skill authors, run SkillForge inside Docker or
|
|
|
233
242
|
|
|
234
243
|
## Updating
|
|
235
244
|
|
|
245
|
+
Pick the block that matches how you installed.
|
|
246
|
+
|
|
236
247
|
```bash
|
|
237
|
-
#
|
|
248
|
+
# Installed as a Claude Code plugin
|
|
238
249
|
/plugin update skillforge
|
|
239
250
|
|
|
240
|
-
# npm
|
|
251
|
+
# Installed via the install CLI (global npm package)
|
|
252
|
+
npm install -g @lyupro/skillforge-mcp@latest
|
|
253
|
+
# host wiring already points at the global bin — restart the host session
|
|
254
|
+
|
|
255
|
+
# Installed as a bare MCP server (npx)
|
|
241
256
|
claude mcp remove skillforge
|
|
242
257
|
claude mcp add skillforge -- npx -y @lyupro/skillforge-mcp@latest
|
|
243
258
|
|
|
244
|
-
# Local-build install
|
|
259
|
+
# Local-build install (git clone)
|
|
245
260
|
cd skillforge-mcp
|
|
246
261
|
git pull
|
|
247
262
|
pnpm install
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/cli/dispatcher.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/cli/dispatcher.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA+CH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAa1D;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAeD;;;;;;GAMG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAO,GACnD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAqCxB"}
|
package/dist/cli/dispatcher.js
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
import { main as installMain } from './install.js';
|
|
27
27
|
import { main as toolsMain } from './tools.js';
|
|
28
28
|
import { main as foldersMain } from './folders.js';
|
|
29
|
+
import { main as skillsMain } from './skills.js';
|
|
29
30
|
const USAGE = `skillforge-mcp — universal Skills MCP server + install CLI.
|
|
30
31
|
|
|
31
32
|
Usage:
|
|
@@ -49,6 +50,12 @@ Commands:
|
|
|
49
50
|
folders Manage skill folders from the terminal (list/add/remove/reset).
|
|
50
51
|
Run "skillforge-mcp folders" for sub-action usage.
|
|
51
52
|
Example: skillforge-mcp folders add ~/.lyupro/skills
|
|
53
|
+
skills View and reload skills from the terminal (list/get/reload).
|
|
54
|
+
The CLI reads disk, not a live server session.
|
|
55
|
+
Run "skillforge-mcp skills" for sub-action usage.
|
|
56
|
+
Example: skillforge-mcp skills list
|
|
57
|
+
Example: skillforge-mcp skills get code-review
|
|
58
|
+
Example: skillforge-mcp skills reload
|
|
52
59
|
|
|
53
60
|
Options:
|
|
54
61
|
--help, -h Show this message.
|
|
@@ -75,20 +82,13 @@ export async function readPackageVersion() {
|
|
|
75
82
|
}
|
|
76
83
|
async function defaultStartServe() {
|
|
77
84
|
const { buildDeps, buildServer } = await import('../server.js');
|
|
85
|
+
const { startRuntime, registerShutdown } = await import('../runtime.js');
|
|
78
86
|
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
79
87
|
const deps = await buildDeps();
|
|
80
88
|
const server = buildServer(deps);
|
|
81
89
|
await server.connect(new StdioServerTransport());
|
|
82
|
-
await deps
|
|
83
|
-
|
|
84
|
-
await deps.folderWatcher.stop();
|
|
85
|
-
};
|
|
86
|
-
process.once('SIGTERM', () => {
|
|
87
|
-
void shutdown();
|
|
88
|
-
});
|
|
89
|
-
process.once('SIGINT', () => {
|
|
90
|
-
void shutdown();
|
|
91
|
-
});
|
|
90
|
+
await startRuntime(deps);
|
|
91
|
+
registerShutdown(deps);
|
|
92
92
|
}
|
|
93
93
|
/**
|
|
94
94
|
* Dispatcher entry. Returns:
|
|
@@ -120,6 +120,9 @@ export async function main(rawArgv, overrides = {}) {
|
|
|
120
120
|
if (first === 'folders') {
|
|
121
121
|
return foldersMain(rawArgv.slice(1));
|
|
122
122
|
}
|
|
123
|
+
if (first === 'skills') {
|
|
124
|
+
return skillsMain(rawArgv.slice(1));
|
|
125
|
+
}
|
|
123
126
|
if (first === 'serve' || first === undefined) {
|
|
124
127
|
const start = overrides.startServe ?? defaultStartServe;
|
|
125
128
|
await start();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/cli/dispatcher.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/cli/dispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table rendering for the `folders list` subcommand.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `folders.ts` so the entry module stays under the 400-line
|
|
5
|
+
* file-size gate. Pure formatting — no I/O.
|
|
6
|
+
*/
|
|
7
|
+
import type { FolderEntry } from '../config/config-schema.js';
|
|
8
|
+
/** Render the registered folders as a fixed-width text table. */
|
|
9
|
+
export declare function formatFoldersTable(folders: FolderEntry[]): string;
|
|
10
|
+
//# sourceMappingURL=folders-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folders-format.d.ts","sourceRoot":"","sources":["../../src/cli/folders-format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAkCjE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table rendering for the `folders list` subcommand.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `folders.ts` so the entry module stays under the 400-line
|
|
5
|
+
* file-size gate. Pure formatting — no I/O.
|
|
6
|
+
*/
|
|
7
|
+
/** Render the registered folders as a fixed-width text table. */
|
|
8
|
+
export function formatFoldersTable(folders) {
|
|
9
|
+
if (folders.length === 0) {
|
|
10
|
+
return 'No folders registered.\n';
|
|
11
|
+
}
|
|
12
|
+
const rows = folders.map((f) => ({
|
|
13
|
+
priority: String(f.priority),
|
|
14
|
+
enabled: f.enabled ? 'yes' : 'no',
|
|
15
|
+
alias: f.alias !== undefined && f.alias.length > 0 ? f.alias : '-',
|
|
16
|
+
tags: f.tags.length > 0 ? f.tags.join(',') : '-',
|
|
17
|
+
path: f.path,
|
|
18
|
+
}));
|
|
19
|
+
const headers = {
|
|
20
|
+
priority: 'PRIORITY',
|
|
21
|
+
enabled: 'ENABLED',
|
|
22
|
+
alias: 'ALIAS',
|
|
23
|
+
tags: 'TAGS',
|
|
24
|
+
path: 'PATH',
|
|
25
|
+
};
|
|
26
|
+
const width = {
|
|
27
|
+
priority: Math.max(headers.priority.length, ...rows.map((r) => r.priority.length)),
|
|
28
|
+
enabled: Math.max(headers.enabled.length, ...rows.map((r) => r.enabled.length)),
|
|
29
|
+
alias: Math.max(headers.alias.length, ...rows.map((r) => r.alias.length)),
|
|
30
|
+
tags: Math.max(headers.tags.length, ...rows.map((r) => r.tags.length)),
|
|
31
|
+
};
|
|
32
|
+
const pad = (text, len) => text.padEnd(len);
|
|
33
|
+
const lines = [
|
|
34
|
+
`${pad(headers.priority, width.priority)} ${pad(headers.enabled, width.enabled)} ${pad(headers.alias, width.alias)} ${pad(headers.tags, width.tags)} ${headers.path}`,
|
|
35
|
+
];
|
|
36
|
+
for (const r of rows) {
|
|
37
|
+
lines.push(`${pad(r.priority, width.priority)} ${pad(r.enabled, width.enabled)} ${pad(r.alias, width.alias)} ${pad(r.tags, width.tags)} ${r.path}`);
|
|
38
|
+
}
|
|
39
|
+
return `${lines.join('\n')}\n`;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=folders-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folders-format.js","sourceRoot":"","sources":["../../src/cli/folders-format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action handlers for the `folders` subcommand.
|
|
3
|
+
*
|
|
4
|
+
* Each handler takes a `ConfigStore`, the post-action args, and stdout/stderr
|
|
5
|
+
* sinks; it returns a process exit code. Split out of `folders.ts` so the
|
|
6
|
+
* entry module stays under the 400-line file-size gate.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConfigStore } from '../config/config-store.js';
|
|
9
|
+
export declare function handleList(store: ConfigStore, rest: string[], stdout: (t: string) => void, stderr: (t: string) => void): Promise<number>;
|
|
10
|
+
export declare function handleAdd(store: ConfigStore, rest: string[], stdout: (t: string) => void, stderr: (t: string) => void, isDirectory: (p: string) => Promise<boolean>): Promise<number>;
|
|
11
|
+
export declare function handleRemove(store: ConfigStore, rest: string[], stdout: (t: string) => void, stderr: (t: string) => void): Promise<number>;
|
|
12
|
+
export declare function handleAlias(store: ConfigStore, rest: string[], stdout: (t: string) => void, stderr: (t: string) => void): Promise<number>;
|
|
13
|
+
export declare function handleEnable(store: ConfigStore, rest: string[], stdout: (t: string) => void, stderr: (t: string) => void): Promise<number>;
|
|
14
|
+
export declare function handleDisable(store: ConfigStore, rest: string[], stdout: (t: string) => void, stderr: (t: string) => void): Promise<number>;
|
|
15
|
+
export declare function handleReset(store: ConfigStore, rest: string[], stdout: (t: string) => void, stderr: (t: string) => void): Promise<number>;
|
|
16
|
+
//# sourceMappingURL=folders-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folders-handlers.d.ts","sourceRoot":"","sources":["../../src/cli/folders-handlers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAU7D,wBAAsB,UAAU,CAC9B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,MAAM,CAAC,CAkCjB;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAC3C,OAAO,CAAC,MAAM,CAAC,CAqDjB;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAED,wBAAsB,YAAY,CAChC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,EAC3B,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,MAAM,CAAC,CAqBjB"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Action handlers for the `folders` subcommand.
|
|
3
|
+
*
|
|
4
|
+
* Each handler takes a `ConfigStore`, the post-action args, and stdout/stderr
|
|
5
|
+
* sinks; it returns a process exit code. Split out of `folders.ts` so the
|
|
6
|
+
* entry module stays under the 400-line file-size gate.
|
|
7
|
+
*/
|
|
8
|
+
import { resolve } from 'node:path';
|
|
9
|
+
import { defaultConfig } from '../config/config-schema.js';
|
|
10
|
+
import { detectSkillSourceConflict, formatConflictHint, } from '../detect/skill-source-conflict.js';
|
|
11
|
+
import { formatFoldersTable } from './folders-format.js';
|
|
12
|
+
import { findFolderEntry, isValidAlias, parseAddFlags } from './folders-shared.js';
|
|
13
|
+
export async function handleList(store, rest, stdout, stderr) {
|
|
14
|
+
let asJson = false;
|
|
15
|
+
let tagFilter;
|
|
16
|
+
for (let i = 0; i < rest.length; i += 1) {
|
|
17
|
+
const arg = rest[i];
|
|
18
|
+
if (arg === '--json') {
|
|
19
|
+
asJson = true;
|
|
20
|
+
}
|
|
21
|
+
else if (arg === '--tag') {
|
|
22
|
+
const value = rest[i + 1];
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
stderr(`skillforge folders list: --tag requires a value\n`);
|
|
25
|
+
return 2;
|
|
26
|
+
}
|
|
27
|
+
tagFilter = value;
|
|
28
|
+
i += 1;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
stderr(`skillforge folders list: unknown flag: ${arg}\n`);
|
|
32
|
+
return 2;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const config = await store.load();
|
|
36
|
+
const folders = tagFilter !== undefined
|
|
37
|
+
? config.folders.filter((f) => f.tags.includes(tagFilter))
|
|
38
|
+
: config.folders;
|
|
39
|
+
if (asJson) {
|
|
40
|
+
stdout(`${JSON.stringify({ folders }, null, 2)}\n`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
stdout(formatFoldersTable(folders));
|
|
44
|
+
}
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
export async function handleAdd(store, rest, stdout, stderr, isDirectory) {
|
|
48
|
+
const rawPath = rest[0];
|
|
49
|
+
if (rawPath === undefined || rawPath.startsWith('--')) {
|
|
50
|
+
stderr(`skillforge folders add: missing <path>\n`);
|
|
51
|
+
return 2;
|
|
52
|
+
}
|
|
53
|
+
const flags = parseAddFlags(rest.slice(1));
|
|
54
|
+
if (flags === null) {
|
|
55
|
+
stderr(`skillforge folders add: invalid or malformed flag\n`);
|
|
56
|
+
return 2;
|
|
57
|
+
}
|
|
58
|
+
if (flags.alias !== undefined && !isValidAlias(flags.alias)) {
|
|
59
|
+
stderr(`skillforge folders add: invalid --alias "${flags.alias}" — use kebab-case (e.g. my-folder)\n`);
|
|
60
|
+
return 2;
|
|
61
|
+
}
|
|
62
|
+
const absPath = resolve(rawPath);
|
|
63
|
+
if (!(await isDirectory(absPath))) {
|
|
64
|
+
stderr(`skillforge folders add: path does not exist or is not a directory: ${absPath}\n`);
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
const config = await store.load();
|
|
68
|
+
const alreadyPresent = config.folders.some((f) => resolve(f.path) === absPath);
|
|
69
|
+
if (alreadyPresent) {
|
|
70
|
+
stdout(`Folder already registered: ${absPath}\n`);
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
if (flags.alias !== undefined) {
|
|
74
|
+
const aliasTaken = config.folders.some((f) => f.alias === flags.alias);
|
|
75
|
+
if (aliasTaken) {
|
|
76
|
+
stderr(`skillforge folders add: alias already in use: ${flags.alias}\n`);
|
|
77
|
+
return 2;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const entry = {
|
|
81
|
+
path: absPath,
|
|
82
|
+
priority: flags.priority ?? 100,
|
|
83
|
+
enabled: !flags.disabled,
|
|
84
|
+
tags: flags.tags ?? [],
|
|
85
|
+
...(flags.alias !== undefined ? { alias: flags.alias } : {}),
|
|
86
|
+
};
|
|
87
|
+
config.folders.push(entry);
|
|
88
|
+
await store.save(config);
|
|
89
|
+
stdout(`Registered folder: ${absPath}\n`);
|
|
90
|
+
// Informational only: a conflict does not block the add or change the exit code.
|
|
91
|
+
const conflict = await detectSkillSourceConflict(absPath);
|
|
92
|
+
if (conflict !== null) {
|
|
93
|
+
stdout(`${formatConflictHint(conflict)}\n`);
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
export async function handleRemove(store, rest, stdout, stderr) {
|
|
98
|
+
const token = rest[0];
|
|
99
|
+
if (token === undefined || token.startsWith('--')) {
|
|
100
|
+
stderr(`skillforge folders remove: missing <path>\n`);
|
|
101
|
+
return 2;
|
|
102
|
+
}
|
|
103
|
+
const config = await store.load();
|
|
104
|
+
const entry = findFolderEntry(config.folders, token);
|
|
105
|
+
if (entry === null) {
|
|
106
|
+
stderr(`skillforge folders remove: no registered folder matches: ${token}\n`);
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
config.folders = config.folders.filter((f) => f !== entry);
|
|
110
|
+
await store.save(config);
|
|
111
|
+
stdout(`Removed folder: ${entry.path}\n`);
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
export async function handleAlias(store, rest, stdout, stderr) {
|
|
115
|
+
const token = rest[0];
|
|
116
|
+
const name = rest[1];
|
|
117
|
+
if (token === undefined || token.startsWith('--') || name === undefined) {
|
|
118
|
+
stderr(`skillforge folders alias: usage: folders alias <path> <name>\n`);
|
|
119
|
+
return 2;
|
|
120
|
+
}
|
|
121
|
+
if (!isValidAlias(name)) {
|
|
122
|
+
stderr(`skillforge folders alias: invalid alias "${name}" — use kebab-case (e.g. my-folder)\n`);
|
|
123
|
+
return 2;
|
|
124
|
+
}
|
|
125
|
+
const config = await store.load();
|
|
126
|
+
const entry = findFolderEntry(config.folders, token);
|
|
127
|
+
if (entry === null) {
|
|
128
|
+
stderr(`skillforge folders alias: no registered folder matches: ${token}\n`);
|
|
129
|
+
return 1;
|
|
130
|
+
}
|
|
131
|
+
const aliasTaken = config.folders.some((f) => f !== entry && f.alias === name);
|
|
132
|
+
if (aliasTaken) {
|
|
133
|
+
stderr(`skillforge folders alias: alias already in use: ${name}\n`);
|
|
134
|
+
return 2;
|
|
135
|
+
}
|
|
136
|
+
entry.alias = name;
|
|
137
|
+
await store.save(config);
|
|
138
|
+
stdout(`Set alias "${name}" for folder: ${entry.path}\n`);
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
export async function handleEnable(store, rest, stdout, stderr) {
|
|
142
|
+
const token = rest[0];
|
|
143
|
+
if (token === undefined || token.startsWith('--')) {
|
|
144
|
+
stderr(`skillforge folders enable: missing <path|alias>\n`);
|
|
145
|
+
return 2;
|
|
146
|
+
}
|
|
147
|
+
const config = await store.load();
|
|
148
|
+
const entry = findFolderEntry(config.folders, token);
|
|
149
|
+
if (entry === null) {
|
|
150
|
+
stderr(`skillforge folders enable: no registered folder matches: ${token}\n`);
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
entry.enabled = true;
|
|
154
|
+
await store.save(config);
|
|
155
|
+
stdout(`Enabled folder: ${entry.path}\n`);
|
|
156
|
+
return 0;
|
|
157
|
+
}
|
|
158
|
+
export async function handleDisable(store, rest, stdout, stderr) {
|
|
159
|
+
const token = rest[0];
|
|
160
|
+
if (token === undefined || token.startsWith('--')) {
|
|
161
|
+
stderr(`skillforge folders disable: missing <path|alias>\n`);
|
|
162
|
+
return 2;
|
|
163
|
+
}
|
|
164
|
+
const config = await store.load();
|
|
165
|
+
const entry = findFolderEntry(config.folders, token);
|
|
166
|
+
if (entry === null) {
|
|
167
|
+
stderr(`skillforge folders disable: no registered folder matches: ${token}\n`);
|
|
168
|
+
return 1;
|
|
169
|
+
}
|
|
170
|
+
entry.enabled = false;
|
|
171
|
+
await store.save(config);
|
|
172
|
+
stdout(`Disabled folder: ${entry.path}\n`);
|
|
173
|
+
return 0;
|
|
174
|
+
}
|
|
175
|
+
export async function handleReset(store, rest, stdout, stderr) {
|
|
176
|
+
const confirmed = rest.includes('--yes');
|
|
177
|
+
for (const arg of rest) {
|
|
178
|
+
if (arg !== '--yes') {
|
|
179
|
+
stderr(`skillforge folders reset: unknown flag: ${arg}\n`);
|
|
180
|
+
return 2;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (!confirmed) {
|
|
184
|
+
const config = await store.load();
|
|
185
|
+
stdout(`Would reset ${config.folders.length} folder(s) to the default (empty) list.\n` +
|
|
186
|
+
`Re-run with --yes to apply. No changes were made.\n`);
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
const config = await store.load();
|
|
190
|
+
config.folders = defaultConfig().folders;
|
|
191
|
+
await store.save(config);
|
|
192
|
+
stdout(`Reset folders to the default (empty) list.\n`);
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=folders-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folders-handlers.js","sourceRoot":"","sources":["../../src/cli/folders-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for the `folders` subcommand modules.
|
|
3
|
+
*
|
|
4
|
+
* Holds pure parsing/lookup logic split out of `folders.ts` so the entry
|
|
5
|
+
* module stays small and the handler modules can reuse it.
|
|
6
|
+
*/
|
|
7
|
+
import type { FolderEntry } from '../config/config-schema.js';
|
|
8
|
+
/** Kebab-case shape required for a folder alias (lowercase words joined by `-`). */
|
|
9
|
+
export declare const ALIAS_PATTERN: RegExp;
|
|
10
|
+
/** Whether `name` is a valid kebab-case alias token. */
|
|
11
|
+
export declare function isValidAlias(name: string): boolean;
|
|
12
|
+
/** Check whether a path exists and is a directory. Overridable for tests. */
|
|
13
|
+
export declare function defaultIsDirectory(p: string): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Locate a registered folder by `token`, matching an alias first and falling
|
|
16
|
+
* back to a resolved-path comparison. Shared so `remove`/`alias` address the
|
|
17
|
+
* same entry the same way.
|
|
18
|
+
*/
|
|
19
|
+
export declare function findFolderEntry(folders: FolderEntry[], token: string): FolderEntry | null;
|
|
20
|
+
/** Parsed result of the flags accepted by `add`. */
|
|
21
|
+
export interface ParsedAddFlags {
|
|
22
|
+
priority?: number;
|
|
23
|
+
tags?: string[];
|
|
24
|
+
disabled: boolean;
|
|
25
|
+
alias?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Parse the flags accepted by `add`. Returns null on a malformed flag. */
|
|
28
|
+
export declare function parseAddFlags(args: string[]): ParsedAddFlags | null;
|
|
29
|
+
//# sourceMappingURL=folders-shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folders-shared.d.ts","sourceRoot":"","sources":["../../src/cli/folders-shared.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,oFAAoF;AACpF,eAAO,MAAM,aAAa,QAA6B,CAAC;AAExD,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,6EAA6E;AAC7E,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOpE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAMzF;AAED,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,GAAG,IAAI,CAmCnE"}
|