Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,67 @@ bun add -g skillkit # bun
npx skillkit <command> # no install
```

### Install sizes

Core commands — `install`, `list`, `find`, `translate`, `recommend`, `publish` —
ship in the default package. Four power features are shipped as **optional
dependencies** so a bare CLI install stays small:

| Feature | Package | Command |
| ------------------------ | -------------------- | --------------------------- |
| Interactive terminal UI | `@skillkit/tui` | `skillkit ui` / `skillkit tui` |
| REST/OpenAPI server | `@skillkit/api` | `skillkit serve` |
| Peer mesh networking | `@skillkit/mesh` | `skillkit mesh …` |
| Inter-agent messaging | `@skillkit/messaging`| `skillkit message …` |

```bash
# Full install — every feature, everything works out of the box (default):
npm install -g skillkit

# Slim install — core commands only, ~75% smaller, no native addons:
npm install -g skillkit --omit=optional
pnpm add -g skillkit --prod --no-optional
```

Cold `npm install` measurements on a fresh cache:

| Install mode | Packages | Time | Deprecations |
| --------------------- | -------- | ---- | ------------ |
| `skillkit` | 475 | 18 s | 3 |
| `skillkit --omit=optional` | 118 | 9 s | 0 |

If you skipped optional deps and later want the UI, server, mesh, or
messaging, add just the one you need:

```bash
npm install -g @skillkit/tui # skillkit ui
npm install -g @skillkit/api # skillkit serve
npm install -g @skillkit/mesh # skillkit mesh
npm install -g @skillkit/messaging # skillkit message
```

### Using `npx` (no install)

`npx skillkit add <owner/repo>` is the fastest way to try it. First run
downloads the package into the npx cache (`~/.npm/_npx/`); every run
after that is instant.

```bash
# Full (defaults to installing optional features):
npx skillkit add anthropics/skills

# Slim — core commands only, ~75% fewer packages, 0 warnings:
npx --omit=optional skillkit add anthropics/skills
```

Run `npx skillkit` a few times and you will want the global install —
it skips the prompt-to-proceed and kills the per-release cache refetch:

```bash
npm install -g skillkit --omit=optional # 9 s, 118 packages, one time
skillkit add anthropics/skills # instant every run
```

## License

Apache License 2.0 — see [LICENSE](LICENSE).
Expand Down
38 changes: 38 additions & 0 deletions apps/skillkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,45 @@ Universal skills manager for AI coding agents. Install, manage, and sync skills
## Installation

```bash
# Full install (default) — every feature, everything works:
npm install -g skillkit

# Slim install — core commands only, ~75% smaller, no native addons:
npm install -g skillkit --omit=optional
```

### What's optional

Four power features ship as **optional dependencies** so the core CLI
stays lean. They install automatically with `npm install -g skillkit`,
and are skipped with `--omit=optional`:

| Feature | Package | Command |
| ------------------------ | -------------------- | ------------------------------ |
| Interactive terminal UI | `@skillkit/tui` | `skillkit ui` / `skillkit tui` |
| REST/OpenAPI server | `@skillkit/api` | `skillkit serve` |
| Peer mesh networking | `@skillkit/mesh` | `skillkit mesh …` |
| Inter-agent messaging | `@skillkit/messaging`| `skillkit message …` |

Add one later with `npm install -g @skillkit/tui` (or `api` / `mesh` / `messaging`).

### Using `npx`

`npx skillkit add <owner/repo>` works with zero install. First run pulls
the package into the npx cache (`~/.npm/_npx/`); every subsequent run
from the same cache is instant.

```bash
npx skillkit add anthropics/skills # full
npx --omit=optional skillkit add anthropics/skills # slim, 118 pkgs, 9 s
```

Running `npx` more than a couple of times? Install globally — no
prompt-to-proceed, no refetch on each release:

```bash
npm install -g skillkit --omit=optional
skillkit add anthropics/skills
```

## Quick Start
Expand Down
9 changes: 5 additions & 4 deletions apps/skillkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,16 @@
"node": ">=18.0.0"
},
"dependencies": {
"@skillkit/api": "workspace:*",
"@skillkit/core": "workspace:*",
"@skillkit/agents": "workspace:*",
"@skillkit/cli": "workspace:*",
"clipanion": "^4.0.0-rc.4"
},
"optionalDependencies": {
"@skillkit/api": "workspace:*",
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Static re-export of optional dependency @skillkit/tui will crash the package entry point when the dep is not installed

apps/skillkit/src/index.ts:6 has a static re-export: export { startTUI } from '@skillkit/tui'. However, this PR moved @skillkit/tui from dependencies to optionalDependencies in apps/skillkit/package.json:62. Optional dependencies may not be installed, and a static import/re-export will throw a module-not-found error at load time, crashing the entire skillkit package's main entry point (./dist/index.js). This defeats the purpose of making the dependency optional. All other usages of the now-optional packages (in packages/cli/src) correctly use dynamic await import() inside try/catch blocks, but this static export was missed.

Prompt for agents
The file apps/skillkit/src/index.ts line 6 has a static re-export of @skillkit/tui:

  export { startTUI } from '@skillkit/tui';

But @skillkit/tui was moved to optionalDependencies in apps/skillkit/package.json. When the optional dep is not installed, this static export will crash the entire module (the package's main entry point).

To fix this, either:
1. Remove the static re-export from apps/skillkit/src/index.ts entirely, or
2. Keep @skillkit/tui in regular dependencies (not optionalDependencies) in apps/skillkit/package.json, or
3. Replace the static re-export with a dynamic export pattern, e.g. export an async function that dynamically imports @skillkit/tui and returns startTUI.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

"@skillkit/tui": "workspace:*",
"@skillkit/memory": "workspace:*",
"@skillkit/mesh": "workspace:*",
"@skillkit/messaging": "workspace:*",
"clipanion": "^4.0.0-rc.4"
"@skillkit/messaging": "workspace:*"
},
"devDependencies": {
"@types/node": "^22.10.5",
Expand Down
7 changes: 4 additions & 3 deletions apps/skillkit/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Re-export all public APIs from packages
export * from '@skillkit/core';
export * from '@skillkit/agents';

// Re-export TUI entry point
export { startTUI } from '@skillkit/tui';
export async function startTUI(...args: unknown[]): Promise<unknown> {
const mod = await import('@skillkit/tui');
return mod.startTUI(...(args as Parameters<typeof mod.startTUI>));
}
Comment on lines +4 to +7
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Confirm the wrapper signature diverges from the actual `@skillkit/tui` startTUI signature.

printf '\napps/skillkit wrapper:\n'
rg -n -C2 'export async function startTUI' apps/skillkit/src/index.ts

printf '\n@skillkit/tui implementation:\n'
rg -n -C2 'export async function startTUI\(\): Promise<never>' packages/tui/src/index.tsx

Repository: rohitg00/skillkit

Length of output: 499


Preserve the original startTUI public signature.

The dynamic import approach is correct, but this wrapper widens the API from startTUI(): Promise<never> to startTUI(...args: unknown[]): Promise<unknown>. The type cast on line 6 is compile-time only and does not affect runtime behavior. Since @skillkit/tui.startTUI takes no parameters, restore the wrapper to the original signature to avoid confusion and maintain API compatibility.

Suggested fix
-export async function startTUI(...args: unknown[]): Promise<unknown> {
+export async function startTUI(): Promise<never> {
   const mod = await import('@skillkit/tui');
-  return mod.startTUI(...(args as Parameters<typeof mod.startTUI>));
+  return mod.startTUI();
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function startTUI(...args: unknown[]): Promise<unknown> {
const mod = await import('@skillkit/tui');
return mod.startTUI(...(args as Parameters<typeof mod.startTUI>));
}
export async function startTUI(): Promise<never> {
const mod = await import('@skillkit/tui');
return mod.startTUI();
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/skillkit/src/index.ts` around lines 4 - 7, The wrapper widened the
public API by accepting unknown args and returning Promise<unknown>; restore the
original signature by changing export async function startTUI to accept no
parameters and return the original Promise<never> (or the exact return type of
`@skillkit/tui.startTUI`), then dynamically import '@skillkit/tui' and call
mod.startTUI() with no arguments (you can narrow the return with a type
assertion to the original Promise<never> if needed), ensuring the exported
startTUI exactly matches the original public signature and runtime behavior.

Comment on lines +4 to +7
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Public API type regression: startTUI signature loosened from () => Promise<never> to (...args: unknown[]) => Promise<unknown>

The startTUI wrapper in apps/skillkit/src/index.ts uses ...args: unknown[] and returns Promise<unknown>, whereas the original re-export (export { startTUI } from '@skillkit/tui') exposed the actual signature (): Promise<never> (see packages/tui/src/index.tsx:25). This is a breaking change to the public TypeScript API of the skillkit package—any downstream consumer that relied on the return type being Promise<never> or the zero-argument signature will now get type errors. The wrapper could be correctly typed as (): Promise<never> since startTUI takes no arguments.

Suggested change
export async function startTUI(...args: unknown[]): Promise<unknown> {
const mod = await import('@skillkit/tui');
return mod.startTUI(...(args as Parameters<typeof mod.startTUI>));
}
export async function startTUI(): Promise<never> {
const mod = await import('@skillkit/tui');
return mod.startTUI();
}
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

3 changes: 3 additions & 0 deletions apps/skillkit/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ export default defineConfig({
splitting: false,
sourcemap: true,
clean: true,
platform: 'node',
target: 'node18',
skipNodeModulesBundle: true,
});
55 changes: 55 additions & 0 deletions docs/fumadocs/content/docs/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,61 @@ bun add -g skillkit

Both `skillkit` and `sk` work as command aliases.

## Full vs slim install

SkillKit ships four power features as **optional dependencies** so the
core install stays small. The default `npm install -g skillkit` installs
every feature; `--omit=optional` installs only the core CLI.

| Feature | Package | Command |
| ------------------------ | -------------------- | ------------------------------ |
| Interactive terminal UI | `@skillkit/tui` | `skillkit ui` / `skillkit tui` |
| REST/OpenAPI server | `@skillkit/api` | `skillkit serve` |
| Peer mesh networking | `@skillkit/mesh` | `skillkit mesh …` |
| Inter-agent messaging | `@skillkit/messaging`| `skillkit message …` |

```bash
# Full (default) — every feature works out of the box:
npm install -g skillkit

# Slim — core commands only, ~75% smaller, no native addons, 0 deprecation warnings:
npm install -g skillkit --omit=optional
```

Add one later:

```bash
npm install -g @skillkit/tui # enables: skillkit ui
npm install -g @skillkit/api # enables: skillkit serve
npm install -g @skillkit/mesh # enables: skillkit mesh
npm install -g @skillkit/messaging # enables: skillkit message
```

The CLI catches a missing optional feature and prints a one-line hint,
so you'll never see an unhandled stack trace.

## Using `npx`

`npx skillkit add <owner/repo>` runs without a global install. First run
downloads into the npx cache (`~/.npm/_npx/`); every call after that is
instant until the cache expires or a new version ships.

```bash
# Full — every feature works:
npx skillkit add anthropics/skills

# Slim — core commands only, 75% fewer packages, 0 warnings:
npx --omit=optional skillkit add anthropics/skills
```

If you use `npx skillkit` more than a couple of times, install globally
to skip the prompt-to-proceed and avoid the per-release cache refetch:

```bash
npm install -g skillkit --omit=optional
skillkit add anthropics/skills
```

## Verify

```bash
Expand Down
38 changes: 33 additions & 5 deletions docs/fumadocs/src/components/Documentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,42 @@ const sections: DocSection[] = [
content: (
<div className="space-y-4">
<h3 className="text-lg font-semibold text-white">Quick Start</h3>
<CodeBlock>{`# Install globally via npm
<CodeBlock>{`# Full install — every feature works out of the box (default):
npm install -g skillkit

# Or use npx directly
npx skillkit --help
# Slim install — core commands only, ~75% smaller, 0 deprecation warnings:
npm install -g skillkit --omit=optional

# Or install via pnpm
pnpm add -g skillkit`}</CodeBlock>
# Or use npx directly:
npx skillkit --help`}</CodeBlock>

<h3 className="text-lg font-semibold text-white mt-6">Optional Features</h3>
<p className="text-zinc-300 text-sm">
TUI, REST server, peer mesh, and inter-agent messaging ship as optional
dependencies. They install by default, or add later à la carte:
</p>
<CodeBlock>{`npm install -g @skillkit/tui # enables: skillkit ui
npm install -g @skillkit/api # enables: skillkit serve
npm install -g @skillkit/mesh # enables: skillkit mesh
npm install -g @skillkit/messaging # enables: skillkit message`}</CodeBlock>

<h3 className="text-lg font-semibold text-white mt-6">Using npx (no install)</h3>
<p className="text-zinc-300 text-sm">
<code className="text-zinc-200">npx skillkit add &lt;owner/repo&gt;</code> runs with zero install.
First call caches the package at <code className="text-zinc-200">~/.npm/_npx/</code>; every
run after that is instant until a new version ships.
</p>
<CodeBlock>{`# Full (default):
npx skillkit add anthropics/skills

# Slim — core only, 75% fewer packages, 0 warnings:
npx --omit=optional skillkit add anthropics/skills`}</CodeBlock>
<p className="text-zinc-300 text-sm">
Using npx more than a couple times? Install globally to skip the
prompt-to-proceed and avoid the per-release cache refetch:
</p>
<CodeBlock>{`npm install -g skillkit --omit=optional
skillkit add anthropics/skills`}</CodeBlock>

<h3 className="text-lg font-semibold text-white mt-6">Verify Installation</h3>
<CodeBlock>{`skillkit --version
Expand Down
38 changes: 33 additions & 5 deletions docs/skillkit/components/Documentation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,42 @@ const sections: DocSection[] = [
content: (
<div className="space-y-4">
<h3 className="text-lg font-semibold text-white">Quick Start</h3>
<CodeBlock>{`# Install globally via npm
<CodeBlock>{`# Full install — every feature works out of the box (default):
npm install -g skillkit

# Or use npx directly
npx skillkit --help
# Slim install — core commands only, ~75% smaller, 0 deprecation warnings:
npm install -g skillkit --omit=optional

# Or install via pnpm
pnpm add -g skillkit`}</CodeBlock>
# Or use npx directly:
npx skillkit --help`}</CodeBlock>

<h3 className="text-lg font-semibold text-white mt-6">Optional Features</h3>
<p className="text-zinc-300 text-sm">
TUI, REST server, peer mesh, and inter-agent messaging ship as optional
dependencies. They install by default, or add later à la carte:
</p>
<CodeBlock>{`npm install -g @skillkit/tui # enables: skillkit ui
npm install -g @skillkit/api # enables: skillkit serve
npm install -g @skillkit/mesh # enables: skillkit mesh
npm install -g @skillkit/messaging # enables: skillkit message`}</CodeBlock>

<h3 className="text-lg font-semibold text-white mt-6">Using npx (no install)</h3>
<p className="text-zinc-300 text-sm">
<code className="text-zinc-200">npx skillkit add &lt;owner/repo&gt;</code> runs with zero install.
First call caches the package at <code className="text-zinc-200">~/.npm/_npx/</code>; every
run after that is instant until a new version ships.
</p>
<CodeBlock>{`# Full (default):
npx skillkit add anthropics/skills

# Slim — core only, 75% fewer packages, 0 warnings:
npx --omit=optional skillkit add anthropics/skills`}</CodeBlock>
<p className="text-zinc-300 text-sm">
Using npx more than a couple times? Install globally to skip the
prompt-to-proceed and avoid the per-release cache refetch:
</p>
<CodeBlock>{`npm install -g skillkit --omit=optional
skillkit add anthropics/skills`}</CodeBlock>

<h3 className="text-lg font-semibold text-white mt-6">Verify Installation</h3>
<CodeBlock>{`skillkit --version
Expand Down
11 changes: 6 additions & 5 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,9 @@
},
"dependencies": {
"@clack/prompts": "^0.11.0",
"@skillkit/api": "workspace:*",
"@skillkit/core": "workspace:*",
"@skillkit/agents": "workspace:*",
"@skillkit/resources": "workspace:*",
"@skillkit/tui": "workspace:*",
"@skillkit/memory": "workspace:*",
"@skillkit/mesh": "workspace:*",
"@skillkit/messaging": "workspace:*",
"chalk": "^5.3.0",
"clipanion": "^4.0.0-rc.4",
"got": "^14.4.1",
Expand All @@ -38,6 +33,12 @@
"picocolors": "^1.1.1",
"yaml": "^2.7.0"
},
"optionalDependencies": {
"@skillkit/api": "workspace:*",
"@skillkit/tui": "workspace:*",
"@skillkit/mesh": "workspace:*",
"@skillkit/messaging": "workspace:*"
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"devDependencies": {
"@types/node": "^22.10.5",
"tsup": "^8.3.5",
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/src/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,16 @@ export class InstallCommand extends Command {
if (isInteractive) {
const allAgentTypes = getAllAdapters().map((a) => a.type);
const lastAgents = getLastAgents();
const rawDetected = await detectAgent().catch(() => undefined);
const detectedAgent = rawDetected && rawDetected !== 'universal' ? rawDetected : undefined;

step(`Detected ${allAgentTypes.length} agents`);

const agentResult = await quickAgentSelect({
message: "Install to",
agents: allAgentTypes,
lastSelected: lastAgents,
detected: detectedAgent,
});

if (isCancel(agentResult)) {
Expand All @@ -372,6 +375,10 @@ export class InstallCommand extends Command {
}

const targetAgents = (agentResult as { agents: string[] }).agents as AgentType[];
if (targetAgents.length === 0) {
cancel("Installation cancelled");
return { agents: null, exitCode: 0 };
}
saveLastAgents(targetAgents);
return { agents: targetAgents, exitCode: 0 };
}
Expand Down
Loading
Loading