@botdocs/cli 0.5.0 → 0.8.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/README.md +134 -6
- package/dist/commands/delete.d.ts +23 -0
- package/dist/commands/delete.js +106 -0
- package/dist/commands/ingest.d.ts +97 -1
- package/dist/commands/ingest.js +512 -19
- package/dist/commands/install.js +11 -0
- package/dist/commands/publish.d.ts +29 -1
- package/dist/commands/publish.js +85 -1
- package/dist/commands/unpublish.d.ts +16 -0
- package/dist/commands/unpublish.js +53 -0
- package/dist/commands/views/ingest-discover-app.d.ts +26 -0
- package/dist/commands/views/ingest-discover-app.js +186 -0
- package/dist/index.js +27 -5
- package/dist/lib/auto-detect.js +19 -0
- package/dist/lib/ingest-discover.d.ts +128 -0
- package/dist/lib/ingest-discover.js +271 -0
- package/dist/lib/ref.d.ts +42 -0
- package/dist/lib/ref.js +60 -0
- package/package.json +1 -1
- package/templates/agents.md +3 -2
package/README.md
CHANGED
|
@@ -55,12 +55,14 @@ botdocs publish my-skill/
|
|
|
55
55
|
| `edit <ref>` | LLM-assisted revision of a published skill ecosystem file (BYOK). |
|
|
56
56
|
| `validate <source>` | Pre-publish structural check on a directory or file. |
|
|
57
57
|
| `search <query>` | Search the public registry. |
|
|
58
|
-
| `publish <source>` | Publish from a file, directory, or zip archive. |
|
|
58
|
+
| `publish <source>` | Publish from a file, directory, or zip archive — or pass `@user/slug` to mark an existing draft live. |
|
|
59
|
+
| `unpublish <ref>` | Hide a published BotDoc from `/explore` (sets the `draft` flag back). |
|
|
60
|
+
| `delete <ref>` | Delete a BotDoc. Drafts are hard-deleted (row + all children); published BotDocs are soft-deleted (hidden, version history preserved). |
|
|
59
61
|
| `install <ref>` | Install a skill or bundle (auto-detects destinations). |
|
|
60
62
|
| `sync [ref]` | Check installed skills/bundles for updates and apply. |
|
|
61
63
|
| `uninstall <ref>` | Remove an installed skill or bundle. |
|
|
62
64
|
| `list` | Show installed skills and bundles. |
|
|
63
|
-
| `ingest
|
|
65
|
+
| `ingest [path]` | Scan your system (or a directory), detect existing skills, upload as drafts. |
|
|
64
66
|
| `team list` / `show` / `create` / `add` / `remove` / `push` / `unpush` | Manage teams: shared skill libraries for your org. |
|
|
65
67
|
| `undo` | Restore the most recent backup run (reversible). |
|
|
66
68
|
| `backups list` / `restore` / `diff` / `clear` | Browse, restore, diff, and prune backup runs. |
|
|
@@ -290,10 +292,28 @@ ambiguously (e.g. paths containing `_`).
|
|
|
290
292
|
|
|
291
293
|
Authors who want to share their existing collection of skills run
|
|
292
294
|
`botdocs ingest <path>` — the CLI walks the directory, detects each
|
|
293
|
-
skill across all
|
|
294
|
-
chatgpt, codex, copilot, windsurf, gemini,
|
|
295
|
-
uploads them as drafts in your BotDocs
|
|
296
|
-
publishing.
|
|
295
|
+
skill across all 11 supported ecosystems (claude, claude-code,
|
|
296
|
+
claude-code-agents, cursor, chatgpt, codex, copilot, windsurf, gemini,
|
|
297
|
+
antigravity, opencode), and uploads them as drafts in your BotDocs
|
|
298
|
+
account for review before publishing.
|
|
299
|
+
|
|
300
|
+
For nested ecosystems (claude SKILL.md, claude-code-agents AGENT.md),
|
|
301
|
+
ingest also sweeps adjacent files inside the skill directory —
|
|
302
|
+
`scripts/*.sh`, `templates/*`, reference docs — and uploads them with
|
|
303
|
+
their original POSIX file mode so the executable bit on helper scripts
|
|
304
|
+
survives the round-trip. `botdocs install` restores the mode on disk.
|
|
305
|
+
|
|
306
|
+
Per-skill size limits (enforced both client- and server-side):
|
|
307
|
+
|
|
308
|
+
- 64 KB per file
|
|
309
|
+
- 512 KB total per skill
|
|
310
|
+
- 25 files per skill
|
|
311
|
+
|
|
312
|
+
Binary files are detected by a null-byte sniff on the first 8 KB and
|
|
313
|
+
skipped with an inline warning. Cap violations warn and skip without
|
|
314
|
+
failing the ingest. Skipped dirs: `node_modules/`, `.git/`, `dist/`,
|
|
315
|
+
`build/`, `.next/`, `.turbo/`, `__pycache__/`, `venv/`, `.venv/`, plus
|
|
316
|
+
all dotfiles, `.DS_Store`, `*.log`, `*.lock`.
|
|
297
317
|
|
|
298
318
|
By default `ingest` expects the canonical BotDocs layout (e.g.
|
|
299
319
|
`claude-code/commands/<slug>.md`, `cursor/rules/<slug>.mdc`). If your
|
|
@@ -316,6 +336,114 @@ The upload always uses the canonical BotDocs filename, so when someone
|
|
|
316
336
|
else `botdocs install`s the resulting skill it lands in the right
|
|
317
337
|
on-disk location.
|
|
318
338
|
|
|
339
|
+
### Publishing drafts (and taking them back down)
|
|
340
|
+
|
|
341
|
+
`botdocs ingest` and `botdocs edit` both create drafts — hidden from
|
|
342
|
+
`/explore`, 404 for everyone but the author. To flip a draft live:
|
|
343
|
+
|
|
344
|
+
```bash
|
|
345
|
+
botdocs publish @me/my-skill # → ✓ Published @me/my-skill
|
|
346
|
+
botdocs publish @me/my-skill --json
|
|
347
|
+
# → {"ok":true,"ref":"@me/my-skill","status":"published"}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
`botdocs publish` is overloaded by argument shape: a local path
|
|
351
|
+
(`./my-skill/`) runs the existing upload flow unchanged; a
|
|
352
|
+
`@user/slug` ref toggles the publish flag via the API.
|
|
353
|
+
|
|
354
|
+
To hide a published BotDoc again (e.g. you want to revise it without
|
|
355
|
+
the in-progress version visible publicly):
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
botdocs unpublish @me/my-skill # prompts to confirm
|
|
359
|
+
botdocs unpublish @me/my-skill --yes # skip the prompt (scripts/CI)
|
|
360
|
+
botdocs unpublish @me/my-skill --json # implies --yes, emits JSON
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Unpublishing sets the `draft` flag back; the URL 404s for non-authors
|
|
364
|
+
and the BotDoc disappears from `/explore`. It's idempotent — calling
|
|
365
|
+
it on something already a draft is a no-op.
|
|
366
|
+
|
|
367
|
+
To delete a BotDoc entirely:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
botdocs delete @me/my-skill # state-aware confirm prompt
|
|
371
|
+
botdocs delete @me/my-skill --yes # skip the prompt (scripts/CI)
|
|
372
|
+
botdocs delete @me/my-skill --json # implies --yes, emits JSON
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
`delete` behaves differently depending on what's there:
|
|
376
|
+
|
|
377
|
+
- **Draft** → *hard delete*. The row and all children (files, version
|
|
378
|
+
history, bundle pins, team pins) are removed. The confirm prompt is a
|
|
379
|
+
single yes/no.
|
|
380
|
+
- **Published** → *soft delete*. Sets `deletedAt`; the BotDoc disappears
|
|
381
|
+
from `/explore` and the public URL 404s, but version history is kept.
|
|
382
|
+
The confirm prompt requires typing the full ref (`@user/slug`) so a
|
|
383
|
+
fat-finger doesn't strand bookmarks at a 404.
|
|
384
|
+
|
|
385
|
+
JSON output is `{ok, ref, mode}` where `mode` is `"hard"` or `"soft"`,
|
|
386
|
+
mirroring the server's decision.
|
|
387
|
+
|
|
388
|
+
### Zero-argument discovery mode
|
|
389
|
+
|
|
390
|
+
Run `botdocs ingest` (no path) and the CLI scans your machine across
|
|
391
|
+
every known on-disk location for the ten supported ecosystems:
|
|
392
|
+
|
|
393
|
+
- `~/.claude/commands/` and `<repo>/.claude/commands/` (Claude Code)
|
|
394
|
+
- `~/.claude/agents/**/AGENT.md` and `<repo>/.claude/agents/**/AGENT.md`
|
|
395
|
+
(Claude Code agents, multi-file)
|
|
396
|
+
- `~/.claude/skills/**/SKILL.md` (Claude skills, nested by scope)
|
|
397
|
+
- `<repo>/.cursor/rules/` (Cursor)
|
|
398
|
+
- `<repo>/.codex/skills/` (Codex)
|
|
399
|
+
- `<repo>/.github/instructions/` (GitHub Copilot)
|
|
400
|
+
- `<repo>/.codeium/windsurf-rules/` (Windsurf)
|
|
401
|
+
- `~/.gemini/instructions/` (Gemini CLI)
|
|
402
|
+
- `~/.gemini/antigravity/skills/` (Antigravity)
|
|
403
|
+
- `~/.config/opencode/instructions/` (OpenCode)
|
|
404
|
+
|
|
405
|
+
Project-scoped scans (Cursor, Codex, Copilot, Windsurf, the project
|
|
406
|
+
flavor of Claude Code) only run when the current directory is inside
|
|
407
|
+
a git repo.
|
|
408
|
+
|
|
409
|
+
A scan opens an interactive Ink TUI sectioned by ecosystem. Multi-file
|
|
410
|
+
skills show their aggregate size + file count instead of per-file lines:
|
|
411
|
+
|
|
412
|
+
```text
|
|
413
|
+
BotDocs ingest
|
|
414
|
+
Found 7 skills across 4 tools:
|
|
415
|
+
|
|
416
|
+
Claude Code:
|
|
417
|
+
[x] scx-pr-craft 2.1 KB · 67 lines
|
|
418
|
+
[x] pr-review-craft 1.8 KB · 54 lines
|
|
419
|
+
[ ] generic-test-cmd 0.1 KB · 4 lines ← unchecked (< 100 bytes)
|
|
420
|
+
|
|
421
|
+
Claude skills:
|
|
422
|
+
[x] code-review 12.4 KB · 4 files ← SKILL.md + 3 adjacent
|
|
423
|
+
|
|
424
|
+
Cursor rules:
|
|
425
|
+
[x] typescript-strict 0.8 KB · 25 lines
|
|
426
|
+
|
|
427
|
+
Gemini CLI:
|
|
428
|
+
[x] research-protocol 2.4 KB · 81 lines
|
|
429
|
+
|
|
430
|
+
↑/↓ navigate · space toggle · a select all · n select none · enter confirm · q cancel
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Useful flags:
|
|
434
|
+
|
|
435
|
+
- `--auto` — skip the TUI and upload everything discovery finds
|
|
436
|
+
(with the < 100-byte stub filter applied).
|
|
437
|
+
- `--dry-run` — list what discovery found in plain text; don't upload.
|
|
438
|
+
- `--json` — emit the discovery as JSON; don't upload.
|
|
439
|
+
- `--no-ink` — disable the TUI on TTYs (for screen readers or simple
|
|
440
|
+
terminals). Falls back to plain-text listing without uploading;
|
|
441
|
+
combine with `--auto` if you want one-shot ingestion.
|
|
442
|
+
|
|
443
|
+
When the discovery returns nothing the CLI prints a hint pointing at
|
|
444
|
+
`botdocs init` (to scaffold a new skill) or `botdocs ingest <dir>`
|
|
445
|
+
(to ingest from a specific path).
|
|
446
|
+
|
|
319
447
|
## Development
|
|
320
448
|
|
|
321
449
|
```bash
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface DeleteOptions {
|
|
2
|
+
yes?: boolean;
|
|
3
|
+
json?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Delete a BotDoc by ref. Behavior split (decided server-side):
|
|
7
|
+
*
|
|
8
|
+
* - Draft → hard delete with cascade. The row and all children (files,
|
|
9
|
+
* versions, version files, bundle pins, team pins) go away.
|
|
10
|
+
* - Published → soft delete (sets `deletedAt`). Hidden from /explore;
|
|
11
|
+
* the public URL 404s; version history is preserved.
|
|
12
|
+
*
|
|
13
|
+
* Prompts unless `--yes` (or `--json`, which implies `--yes`). Draft
|
|
14
|
+
* deletes get a single yes/no confirm; published deletes require typing
|
|
15
|
+
* the ref exactly because the effect is visible to anyone who had the
|
|
16
|
+
* URL bookmarked. The CLI does a preflight GET to know which prompt to
|
|
17
|
+
* show before the user commits.
|
|
18
|
+
*
|
|
19
|
+
* Errors flow through the shared `handlePublishToggleError` so 401/403/
|
|
20
|
+
* 404 messages stay in sync with publish/unpublish.
|
|
21
|
+
*/
|
|
22
|
+
export declare function delete_(rawRef: string, options: DeleteOptions): Promise<void>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import { apiFetch } from '../lib/api.js';
|
|
3
|
+
import { parseRef } from '../lib/ref.js';
|
|
4
|
+
import { handlePublishToggleError } from './publish.js';
|
|
5
|
+
/**
|
|
6
|
+
* Delete a BotDoc by ref. Behavior split (decided server-side):
|
|
7
|
+
*
|
|
8
|
+
* - Draft → hard delete with cascade. The row and all children (files,
|
|
9
|
+
* versions, version files, bundle pins, team pins) go away.
|
|
10
|
+
* - Published → soft delete (sets `deletedAt`). Hidden from /explore;
|
|
11
|
+
* the public URL 404s; version history is preserved.
|
|
12
|
+
*
|
|
13
|
+
* Prompts unless `--yes` (or `--json`, which implies `--yes`). Draft
|
|
14
|
+
* deletes get a single yes/no confirm; published deletes require typing
|
|
15
|
+
* the ref exactly because the effect is visible to anyone who had the
|
|
16
|
+
* URL bookmarked. The CLI does a preflight GET to know which prompt to
|
|
17
|
+
* show before the user commits.
|
|
18
|
+
*
|
|
19
|
+
* Errors flow through the shared `handlePublishToggleError` so 401/403/
|
|
20
|
+
* 404 messages stay in sync with publish/unpublish.
|
|
21
|
+
*/
|
|
22
|
+
export async function delete_(rawRef, options) {
|
|
23
|
+
let parsed;
|
|
24
|
+
try {
|
|
25
|
+
parsed = parseRef(rawRef);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const { username, slug } = parsed;
|
|
32
|
+
const refLabel = `@${username}/${slug}`;
|
|
33
|
+
// Preflight to determine state — we need to know draft vs published so
|
|
34
|
+
// we can show the right confirm prompt. Skip the network round-trip
|
|
35
|
+
// when prompts are disabled (`--yes`/`--json`): the server returns the
|
|
36
|
+
// resolved mode in the DELETE response anyway, and skipping the GET
|
|
37
|
+
// avoids a double-fail if the user has a stale token.
|
|
38
|
+
if (!options.yes && !options.json) {
|
|
39
|
+
let info;
|
|
40
|
+
try {
|
|
41
|
+
info = await apiFetch(`/api/botdocs/${username}/${slug}`, {
|
|
42
|
+
method: 'GET',
|
|
43
|
+
auth: true,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
handlePublishToggleError(err, refLabel, options);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const confirmed = await promptConfirm(refLabel, info.isDraft);
|
|
51
|
+
if (!confirmed) {
|
|
52
|
+
console.log(' Cancelled.\n');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
let result;
|
|
57
|
+
try {
|
|
58
|
+
result = await apiFetch(`/api/botdocs/${username}/${slug}`, {
|
|
59
|
+
method: 'DELETE',
|
|
60
|
+
auth: true,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
handlePublishToggleError(err, refLabel, options);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (options.json) {
|
|
68
|
+
console.log(JSON.stringify({ ok: true, ref: refLabel, mode: result.mode }));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (result.mode === 'hard') {
|
|
72
|
+
console.log(`✓ Deleted draft ${refLabel}.`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(`✓ Deleted ${refLabel} — hidden from /explore (version history preserved).`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Show the appropriate confirm prompt for the BotDoc's state.
|
|
80
|
+
*
|
|
81
|
+
* Draft → simple yes/no confirm.
|
|
82
|
+
* Published → type-the-ref. We don't accept anything else — a fat-finger
|
|
83
|
+
* on a soft delete still strands public bookmarks at a 404.
|
|
84
|
+
*
|
|
85
|
+
* Returns `false` for any non-positive outcome (ctrl-C, no, wrong text).
|
|
86
|
+
*/
|
|
87
|
+
async function promptConfirm(refLabel, isDraft) {
|
|
88
|
+
if (isDraft) {
|
|
89
|
+
const confirmed = await p.confirm({
|
|
90
|
+
message: `Delete draft ${refLabel}? This can't be undone.`,
|
|
91
|
+
initialValue: false,
|
|
92
|
+
});
|
|
93
|
+
if (p.isCancel(confirmed))
|
|
94
|
+
return false;
|
|
95
|
+
return confirmed === true;
|
|
96
|
+
}
|
|
97
|
+
const typed = await p.text({
|
|
98
|
+
message: `Delete ${refLabel}? This hides it from /explore (version history is kept). ` +
|
|
99
|
+
`Bookmarks will 404. Confirm by typing the ref:`,
|
|
100
|
+
placeholder: refLabel,
|
|
101
|
+
validate: (v) => (v === refLabel ? undefined : `Must match ${refLabel} exactly`),
|
|
102
|
+
});
|
|
103
|
+
if (p.isCancel(typed))
|
|
104
|
+
return false;
|
|
105
|
+
return typed === refLabel;
|
|
106
|
+
}
|
|
@@ -2,8 +2,104 @@ interface IngestOptions {
|
|
|
2
2
|
bundle?: string;
|
|
3
3
|
dryRun?: boolean;
|
|
4
4
|
json?: boolean;
|
|
5
|
+
/** Force every file in the path to belong to a single ecosystem, instead of
|
|
6
|
+
* relying on the canonical-layout auto-detect. Set via `--from-tool=<x>`. */
|
|
5
7
|
fromTool?: string;
|
|
8
|
+
/** Skip the TUI and ingest everything discovery finds (with the default
|
|
9
|
+
* stub filter applied). Set via `--auto`. */
|
|
10
|
+
auto?: boolean;
|
|
11
|
+
/** Force the plain-text rendering path — disables the Ink TUI. Mirrors the
|
|
12
|
+
* `--no-ink` flag on `login` and `sync`. */
|
|
13
|
+
noInk?: boolean;
|
|
6
14
|
}
|
|
15
|
+
/** Per-file size cap. Any file larger than this is skipped with a warning. */
|
|
16
|
+
export declare const PER_FILE_BYTE_CAP: number;
|
|
17
|
+
/** Total bytes across all files in a single skill. */
|
|
18
|
+
export declare const PER_SKILL_BYTE_CAP: number;
|
|
19
|
+
/** Total file count in a single skill. */
|
|
20
|
+
export declare const PER_SKILL_FILE_CAP = 25;
|
|
21
|
+
export interface AdjacentSweepFile {
|
|
22
|
+
/** Absolute path on disk. */
|
|
23
|
+
absPath: string;
|
|
24
|
+
/** Path relative to the skill root, forward-slashed (`scripts/helper.sh`). */
|
|
25
|
+
relPath: string;
|
|
26
|
+
/** File contents (text). Binary files are skipped before this is read. */
|
|
27
|
+
content: string;
|
|
28
|
+
/** Low 9 bits of st_mode, captured before reading. */
|
|
29
|
+
mode: number;
|
|
30
|
+
/** Size in bytes. */
|
|
31
|
+
sizeBytes: number;
|
|
32
|
+
}
|
|
33
|
+
export interface AdjacentSweepWarning {
|
|
34
|
+
relPath: string;
|
|
35
|
+
reason: 'binary' | 'oversize' | 'cap-total-size' | 'cap-file-count';
|
|
36
|
+
}
|
|
37
|
+
export interface AdjacentSweepResult {
|
|
38
|
+
files: AdjacentSweepFile[];
|
|
39
|
+
warnings: AdjacentSweepWarning[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Walk a skill root recursively and return every non-skipped file the caller
|
|
43
|
+
* should ingest as an adjacent file. Applies dir-skip, dotfile, binary, and
|
|
44
|
+
* cap rules. Stops collecting once total caps are exceeded — remaining files
|
|
45
|
+
* land in `warnings`. The root file (e.g. SKILL.md) is excluded so the caller
|
|
46
|
+
* can handle it separately.
|
|
47
|
+
*/
|
|
48
|
+
export declare function sweepSkillRoot(skillRoot: string, rootFileAbs: string): AdjacentSweepResult;
|
|
49
|
+
/** Format a sweep warning summary line for a single skill. Empty string when
|
|
50
|
+
* there are no warnings — caller can use that to suppress the line. */
|
|
51
|
+
export declare function formatSweepWarnings(slug: string, warnings: AdjacentSweepWarning[]): string;
|
|
52
|
+
export interface EcosystemDetector {
|
|
53
|
+
/** Path prefix the file's root-relative path must start with for auto-detect mode. */
|
|
54
|
+
pathPrefix: string;
|
|
55
|
+
/** Extension suffixes the filename must match. Tested via endsWith. */
|
|
56
|
+
extensions: string[];
|
|
57
|
+
/** Whether this ecosystem uses a nested SKILL.md layout (claude) vs flat.
|
|
58
|
+
* Discovery uses this to decide whether to recurse the scan directories. */
|
|
59
|
+
nested: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Given an absolute file path and the source root, return the slug or null
|
|
62
|
+
* if the file doesn't match this ecosystem's layout (e.g. wrong nesting).
|
|
63
|
+
*/
|
|
64
|
+
slugFor: (absPath: string, root: string) => string | null;
|
|
65
|
+
/** Canonical filename inside a BotDoc directory, given the slug. */
|
|
66
|
+
canonicalFilename: (slug: string) => string;
|
|
67
|
+
/**
|
|
68
|
+
* Absolute directories to scan during zero-arg discovery mode. Receives the
|
|
69
|
+
* user's home dir, the current project root (cwd), and whether the project
|
|
70
|
+
* root is inside a git repo. Project-scoped paths should return `[]` when
|
|
71
|
+
* `isGitRepo` is false. Return `[]` for ecosystems that have no canonical
|
|
72
|
+
* on-disk location (e.g. chatgpt — manual-paste only).
|
|
73
|
+
*/
|
|
74
|
+
scanPaths: (homeDir: string, projectRoot: string, isGitRepo: boolean) => string[];
|
|
75
|
+
/**
|
|
76
|
+
* When true, ingest sweeps the skill directory and uploads adjacent files
|
|
77
|
+
* (scripts/, templates/, etc.) alongside the root file. Today this is only
|
|
78
|
+
* meaningful for `claude` and `claude-code-agents` — flat-file ecosystems
|
|
79
|
+
* leave it false. `claude-code` (commands) keeps it as `true` for forward-
|
|
80
|
+
* compat but is a no-op since commands have no enclosing directory.
|
|
81
|
+
*/
|
|
82
|
+
includeAdjacent?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Given the absolute path to a matched root file, return the directory that
|
|
85
|
+
* counts as the "skill root" — everything below it is eligible for the
|
|
86
|
+
* adjacent-file sweep. For nested ecosystems this is the parent dir of the
|
|
87
|
+
* root file. Only invoked when `includeAdjacent` is true.
|
|
88
|
+
*/
|
|
89
|
+
skillRoot?: (absPath: string) => string;
|
|
90
|
+
/**
|
|
91
|
+
* Build the canonical filename for an adjacent file given its skill slug
|
|
92
|
+
* and the path relative to the skill root (e.g. `scripts/helper.sh`). Only
|
|
93
|
+
* invoked when `includeAdjacent` is true.
|
|
94
|
+
*/
|
|
95
|
+
canonicalAdjacentFilename?: (slug: string, relPath: string) => string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Single source of truth for ecosystem detection. New ecosystems should be
|
|
99
|
+
* added here — both auto-detect mode and future `--from-tool` mode consult
|
|
100
|
+
* this table.
|
|
101
|
+
*/
|
|
102
|
+
export declare const DETECTORS: Record<string, EcosystemDetector>;
|
|
7
103
|
export declare const SUPPORTED_TOOLS: readonly string[];
|
|
8
|
-
export declare function ingest(rootPath: string, options: IngestOptions): Promise<void>;
|
|
104
|
+
export declare function ingest(rootPath: string | undefined, options: IngestOptions): Promise<void>;
|
|
9
105
|
export {};
|