{"_id":"@abhinavravich1999/skill-forge","_rev":"2-0f020be6cfb3d7ba5adc0f627d96d3eb","name":"@abhinavravich1999/skill-forge","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@abhinavravich1999/skill-forge","version":"0.1.0","keywords":["career","interview","claude-code","ai"],"author":"","license":"MIT","_id":"@abhinavravich1999/skill-forge@0.1.0","maintainers":[{"name":"abhinavravich1999","email":"abhinavkarthikeyan1999@gmail.com"}],"bin":{"skill-forge":"dist/index.js","skill-forge-mcp":"dist/mcp/server.js"},"dist":{"shasum":"f97c8bb028ecebd724786e9f25942e73e342a10c","tarball":"https://registry.npmjs.org/@abhinavravich1999/skill-forge/-/skill-forge-0.1.0.tgz","fileCount":32,"integrity":"sha512-+eJAxFxPAbCHBLw5bEsma8y5bNx30ShIQ1WbiOuBO+TOGt9OcrWa6UmpTD0/OJTDpB2Gu5oKZEZ9NV9V4Fbpxg==","signatures":[{"sig":"MEQCIBHFSn7RBSgR5XP3vwP30Q6++/oTSAahZFIt7dolv3JpAiB808KPVt43UdpIZvvjBry3cZoMQZixj/4iG+pVaHG/6Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58715},"main":"dist/index.js","type":"module","gitHead":"9c3ba6fe1371e437c87814879104bddcbe887a2e","scripts":{"dev":"tsx src/index.ts","mcp":"tsx src/mcp/server.ts","build":"rimraf dist && tsc && node -e \"require('fs').cpSync('src/prompts','dist/prompts',{recursive:true})\"","start":"node dist/index.js","prepublishOnly":"npm run build"},"_npmUser":{"name":"abhinavravich1999","email":"abhinavkarthikeyan1999@gmail.com"},"_npmVersion":"11.12.1","description":"Turn your coding sessions into interview-ready stories, portfolio bullets, and technical deep-dive Q&A","directories":{},"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","uuid":"^14.0.0","yaml":"^2.9.0","dotenv":"^17.4.2","openai":"^6.42.0","commander":"^15.0.0","@anthropic-ai/sdk":"^0.104.1","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.4","rimraf":"^6.1.3","typescript":"^6.0.3","@types/node":"^25.9.3","@types/uuid":"^10.0.0"},"_npmOperationalInternal":{"tmp":"tmp/skill-forge_0.1.0_1786868790575_0.9620384211311097","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"_id":"@abhinavravich1999/skill-forge@0.2.0","bin":{"skill-forge":"dist/index.js","skill-forge-mcp":"dist/mcp/server.js"},"bugs":{"url":"https://github.com/Abinav-karthikeyan/skillforge/issues"},"dist":{"shasum":"abd6d04ff1bbd809bfc518f287e5fc11aa3127b8","tarball":"https://registry.npmjs.org/@abhinavravich1999/skill-forge/-/skill-forge-0.2.0.tgz","fileCount":51,"integrity":"sha512-GwvJUOSt1mhJ0PdLenEoYj7e7gjeYaQPDlfXdizlGpCHNgfdfjbZC6HAS5HN4D1MtbSiBcWUvkCEqdcV7KB4BA==","signatures":[{"sig":"MEUCIQDLh7eC1iTxZglwLiK/LLyVQ4kQwfSAcZPfm5NzCHgkrAIgYc1HBVG9IUpTfnSmaV0ZIYCuF4DNiCSQYMMqtl3TCKc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIH2gRZhWtnZEp7T0AKRyBV4CsES+wkE2Bc4fuJ/B7VumAiBjRVMXRUH+Y6D4r1vsU9FYXYoT954NEr6DGDZWexdhxA=="}],"unpackedSize":143576},"main":"dist/index.js","name":"@abhinavravich1999/skill-forge","type":"module","author":{"name":"Abinav Karthikeyan"},"engines":{"node":">=20"},"gitHead":"a5c048260aa9dac07be26ab196bda8b3121754e2","license":"MIT","scripts":{"dev":"tsx src/index.ts","mcp":"tsx src/mcp/server.ts","test":"vitest run","build":"rimraf dist && tsc && node -e \"require('fs').cpSync('src/prompts','dist/prompts',{recursive:true})\"","start":"node dist/index.js","typecheck":"tsc -p tsconfig.test.json --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"version":"0.2.0","_npmUser":{"name":"abhinavravich1999","email":"abhinavkarthikeyan1999@gmail.com"},"homepage":"https://github.com/Abinav-karthikeyan/skillforge#readme","keywords":["career","interview","mcp","claude-code","ai","agent"],"repository":{"url":"git+https://github.com/Abinav-karthikeyan/skillforge.git","type":"git"},"_npmVersion":"11.12.1","description":"Turn your coding sessions into interview-ready stories, portfolio bullets, and technical deep-dive Q&A","directories":{},"maintainers":[{"name":"abhinavravich1999","email":"abhinavkarthikeyan1999@gmail.com"}],"_nodeVersion":"24.15.0","dependencies":{"zod":"^4.4.3","uuid":"^14.0.0","yaml":"^2.9.0","dotenv":"^17.4.2","openai":"^6.42.0","commander":"^15.0.0","@notionhq/client":"^5.25.2","@anthropic-ai/sdk":"^0.104.1","@modelcontextprotocol/sdk":"^1.30.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.4","rimraf":"^6.1.3","vitest":"^3.2.6","typescript":"^6.0.3","@types/node":"^25.9.3","@types/uuid":"^10.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/skill-forge_0.2.0_1789925774368_0.07770950641893526"}}},"time":{"created":"2026-08-16T08:26:30.255Z","modified":"2026-09-20T17:36:14.584Z","0.1.0":"2026-08-16T08:26:30.727Z","0.2.0":"2026-09-20T17:36:14.447Z"},"license":"MIT","keywords":["career","interview","mcp","claude-code","ai","agent"],"description":"Turn your coding sessions into interview-ready stories, portfolio bullets, and technical deep-dive Q&A","maintainers":[{"name":"abhinavravich1999","email":"abhinavkarthikeyan1999@gmail.com"}],"readme":"# skill-forge\n\n[![npm version](https://img.shields.io/npm/v/@abhinavravich1999/skill-forge)](https://www.npmjs.com/package/@abhinavravich1999/skill-forge)\n[![CI](https://github.com/Abinav-karthikeyan/skillforge/actions/workflows/ci.yml/badge.svg)](https://github.com/Abinav-karthikeyan/skillforge/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n> Your sessions already contain your best career stories. skill-forge extracts them before you forget.\n\nYou just spent four hours debugging a race condition, or designed a provider abstraction that handles five LLM backends, or ripped out legacy auth middleware because legal flagged a compliance gap. In a week you'll remember \"fixed some bug.\" In six months, nothing. Interviews and resumes are reconstructed from faded memory, months after the specifics vanished.\n\n**skill-forge captures session context at peak richness** — right now, while the conversation is still open — and translates it into artifacts you can actually use: STAR-format interview answers, XYZ resume bullets, and technical narratives ready for a portfolio or blog post.\n\n---\n\n## \"Couldn't you just write a skill for this?\"\n\nYes — and that's exactly what skill-forge is *not*.\n\nskill-forge is a different category of thing:\n\n\nThe slash command (`/skill-forge`) is the lowest-friction entry point. It is not the whole product.\n\n---\n\n## How it works\n\nA single pipeline — `ingestor → translators → output` — exposed four ways:\n\n| Surface | When you'd use it | Context source |\n|---|---|---|\n| **`/skill-forge`** slash command | End of a Claude Code session | Full conversation transcript — richest signal |\n| **MCP server** (`skill-forge-mcp`) | Any MCP-capable host: Claude Desktop, custom tooling | Tool call args (`session_summary`), or git fallback |\n| **CLI** (`skill-forge generate`) | Scripts, CI, or piping a git diff | `--json` file, or local git log/diff |\n| **git commit hook** | Every commit, zero extra steps | git log + diff — no session required |\n\nAll four surfaces feed the same pipeline. The `/skill-forge` slash command produces the richest output because it has the full conversation; the git hook produces the leanest because it works purely from diff context. Same typed contract at the output end either way.\n\n---\n\n## The pipeline\n\n```\nsession context  →  ingestor  →  SessionSummary  →  translators  →  connector  →  artifact\n```\n\n**Ingestor** normalizes raw context — a conversation transcript, a git diff, or a JSON blob — into a validated `SessionSummary` schema:\n\n```ts\n{\n  one_liner, problem_statement, approach,\n  tradeoffs: [{ decision, reasoning, alternative_considered }],\n  dead_ends: string[],\n  technologies: string[],\n  patterns_used: string[],\n  complexity_signals: { files_touched, lines_changed, test_coverage, debugging_involved }\n}\n```\n\nThis typed contract is what makes translators swappable. Adding a new output mode means writing a new translator against the schema — not re-engineering context extraction.\n\n**Translators** are per-mode LLM calls against versioned prompt templates. Prompt quality is iterable independently of code — pin a version, A/B test, roll back. A skill's prompt is frozen in the `.md` file.\n\n**Connectors** are swappable output destinations. `local` writes `.md` files and maintains `index.yml`. `gist` pushes each artifact to a GitHub Gist and returns a shareable URL. `notion` creates a page in a Notion database with structured properties. `return_only` writes locally **and returns the fully rendered artifact to the caller** so the *host* delivers it via a connector it already has — Slack, LinkedIn, Google Docs, or a **Gemini Notebook / NotebookLM** source (see [Connect to Gemini Notebook](#7-optional-connect-to-gemini-notebook--notebooklm)). All non-local connectors also write locally so `index.yml` stays authoritative.\n\n---\n\n## Quickstart\n\n### 1. Install\n\n```bash\nnpm install -g @abhinavravich1999/skill-forge\n```\n\nOr run without installing:\n\n```bash\nnpx @abhinavravich1999/skill-forge generate --help\n```\n\n> **Upgrading from `career-mode`?** This release renames everything to `skill-forge`, with\n> one-release fallbacks so nothing breaks: your existing `~/.career-mode/` corpus and\n> `career-mode.config.yaml` are still read, the `CAREER_MODE_PROMPT_VERSION` env var still\n> works, and the old MCP tool names (`generate_career_artifact`, `list_career_artifacts`)\n> still resolve (deprecated — switch to the `*_skill_forge_*` names). The one thing to do by\n> hand: if you installed the old slash command, delete `~/.claude/commands/career-mode.md`\n> and install `/skill-forge` (step 3) so you don't have both. These fallbacks are removed in\n> the next release.\n\n### 2. Configure your LLM provider\n\nskill-forge has its own LLM client, independent of whatever powers your Claude Code session. The recommended path is `openai-compatible` — it works with DeepSeek, Groq, Together, Fireworks, xAI, LM Studio, vLLM, Ollama, and OpenAI itself.\n\n```bash\ncp skill-forge.config.yaml ~/.skill-forge/config.yaml\ncp .env.example .env\n```\n\nEdit `~/.skill-forge/config.yaml`. DeepSeek is fast and cheap — a good default:\n\n```yaml\nprovider: openai-compatible\nmodel: deepseek-chat\nbase_url: https://api.deepseek.com/v1\napi_key: ${DEEPSEEK_API_KEY}       # resolved from .env — secrets stay out of yaml\n```\n\nAdd the key to `.env`:\n\n```\nDEEPSEEK_API_KEY=sk-...\n```\n\n`.env` is loaded from project root first, then `~/.skill-forge/.env`. Shell env always wins.\n\n**Skip the config file entirely** and the provider auto-detects from env:\n\n| Env var set | Provider used |\n|---|---|\n| `ANTHROPIC_API_KEY` | Anthropic (Claude, native SDK) |\n| `OPENAI_API_KEY` | OpenAI (`api.openai.com`) |\n| Neither | Ollama at `localhost:11434` |\n\n### 3. Install the slash command\n\n```bash\n# macOS / Linux\ncp claude-code-integration/commands/skill-forge.md ~/.claude/commands/skill-forge.md\n\n# Windows (PowerShell)\nCopy-Item claude-code-integration\\commands\\skill-forge.md \"$env:USERPROFILE\\.claude\\commands\\skill-forge.md\"\n```\n\nRestart Claude Code. `/skill-forge` is now available in any session.\n\n### 4. (Optional) Register the MCP server\n\nRegister skill-forge as an MCP server so any MCP-capable client can call it as a tool — including Claude Code, Claude Desktop, or your own tooling:\n\n```bash\nclaude mcp add skill-forge -- npx --package=@abhinavravich1999/skill-forge skill-forge-mcp\n```\n\nOr add it to `.mcp.json` directly — see [claude-code-integration/mcp/.mcp.json](claude-code-integration/mcp/.mcp.json). Full tool schemas and the reasoning for running both the slash command and MCP server: [docs/mcp-server.md](docs/mcp-server.md).\n\n### 5. (Optional) Install the git commit hook\n\nFire skill-forge on every commit — no session required, no extra steps:\n\n```json\n{\n  \"hooks\": {\n    \"PostToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"pattern\": \"git commit\",\n        \"command\": \"npx @abhinavravich1999/skill-forge generate --mode portfolio-bullet\"\n      }\n    ]\n  }\n}\n```\n\nAdd this to `~/.claude/settings.json` under `hooks`.\n\n### 6. (Optional) Connect to Notion\n\nPush artifacts directly into a Notion database — turn skill-forge into a living brag doc.\n\n**One command does everything** — token validation, database creation, config write:\n\n```bash\nskill-forge auth notion\n```\n\nThe guided flow:\n\n1. Creates a Notion integration at https://www.notion.so/profile/integrations\n2. Shares a page with the integration in the Notion UI\n3. Pastes the integration token when prompted (input is hidden — never logged)\n4. Picks the parent page from a list (or pastes a URL/ID)\n5. Done — the database is created, credentials written to `~/.skill-forge/.env`, config updated\n\nArtifacts now land in Notion with full metadata (Mode, Technologies, Patterns) as database properties.\n\n**Check status at any time:**\n\n```bash\nskill-forge auth status\n```\n\n**From an MCP host** (Claude Code, Claude Desktop, etc.) — call `notion_auth_status` to see whether Notion is configured without leaving your session.\n\n<details>\n<summary>Manual / non-interactive setup</summary>\n\n```bash\n# 1. Add NOTION_TOKEN=ntn_... to ~/.skill-forge/.env\n# 2. Create the database:\nnpx tsx scripts/notion-setup.ts <parent-page-id>\n# 3. Add to ~/.skill-forge/config.yaml:\n#   connector: notion\n#   notion_token: ${NOTION_TOKEN}\n#   notion_database_id: <printed-id>\n```\n\n</details>\n\n### 7. (Optional) Connect to Gemini Notebook / NotebookLM\n\nPush artifacts into a **Gemini Notebook** (formerly NotebookLM) so you can chat over your own\ncareer corpus with grounded, cited answers.\n\nThere is a deliberate design choice here: skill-forge does **not** ship a Gemini Notebook\nconnector that holds your Google credentials. Google exposes no official consumer write API,\nso a bespoke connector would mean skill-forge driving a headless Chrome with your cookies —\nfragile and a credential liability. Instead, skill-forge uses **host-delivery**: it renders the\nartifact and hands it back, and a NotebookLM MCP that *you* have authorized does the delivery.\nskill-forge holds zero Google credentials.\n\n**One-time setup** — install a NotebookLM MCP CLI (any that exposes an `add_source` / `source add`\ntool with a text/paste type works; [`notebooklm-mcp-cli`](https://github.com/jacob-bd/notebooklm-mcp-cli)\nis one) and authenticate it once:\n\n```bash\npip install notebooklm-mcp-cli\nnlm login                         # opens Chrome; sign into your Google account once\nnlm notebook create \"My career corpus\"    # prints a notebook id + URL\n```\n\n**Deliver an artifact** — generate with the `return_only` connector, then hand the rendered\nmarkdown to the notebook as a text source:\n\n```bash\n# 1. Render + return (also saved to your local corpus)\nskill-forge generate --mode technical-deep-dive --connector return_only --json session.json\n\n# 2. Add the saved artifact to the notebook as a text source\nnlm source add <notebook-id> --text \"$(cat ~/.skill-forge/artifacts/<file>.md)\" \\\n  --title \"Career artifact\" --wait\n```\n\nInside an MCP host (Claude Code, Claude Desktop) that has *both* skill-forge and a NotebookLM\nMCP connected, this is one sentence: *\"generate a technical deep-dive and add it to my Gemini\nNotebook.\"* The host calls `generate_skill_forge_artifact` with `connector: \"return_only\"`, gets the\nmarkdown back, and calls the NotebookLM MCP's `add_source(type=text)` with it — no glue code.\n\n> **Verified round-trip:** `generate --connector return_only` → `nlm source add --text` ingests\n> cleanly and a grounded query answers while citing the artifact. `technical-deep-dive` and\n> `interview-qa` ground richer \"why\" questions than terse `portfolio-bullet`; the flow is\n> identical across modes.\n\nThe same `return_only` mode is the recommended path for Slack, LinkedIn, and Google Docs too —\nwherever the host already holds the credential.\n\n---\n\n## Using the slash command\n\nAt the end of a Claude Code session:\n\n```\n/skill-forge\n```\n\nClaude synthesizes the session into a structured summary, runs it through the pipeline, and writes an artifact to `~/.skill-forge/artifacts/`. The output path is printed in the terminal.\n\nSpecify the mode:\n\n```\n/skill-forge --mode interview-qa\n/skill-forge --mode portfolio-bullet\n/skill-forge --mode technical-deep-dive\n/skill-forge --mode all\n```\n\nDefault is `interview-qa`. See [docs/slash-command.md](docs/slash-command.md) for a full walkthrough.\n\n---\n\n## Output modes\n\n### `interview-qa`\n2–4 STAR-format interview questions with full answers (Situation, Task, Action, Result), follow-up questions an interviewer would actually ask, and a calibration note on how to pitch the answer for your experience level.\n\n### `portfolio-bullet`\n3–5 resume bullets in XYZ format (\"Accomplished X by doing Y, resulting in Z\"). Calibrated to `experience_level` and `target_role` in config.\n\n### `technical-deep-dive`\nA technical narrative for a blog post, design doc, or engineering portfolio — problem, approach, tradeoffs, and lessons learned, structured for an engineering audience.\n\n### `all`\nAll three modes, separate files.\n\n---\n\n## Custom instructions\n\nskill-forge injects your custom instructions into every translator system prompt — giving the LLM context it cannot infer from git alone.\n\nAdd `custom_instructions` to `~/.skill-forge/config.yaml`:\n\n```yaml\n# Simple: one string applies to all modes\ncustom_instructions: >\n  I'm targeting Staff Engineer roles at fintech companies (Stripe, Plaid, Square).\n  Emphasize reliability, distributed systems, and compliance angles.\n  Tie every technical decision back to business impact.\n```\n\n```yaml\n# Per-mode: global applies everywhere, mode keys add overrides\ncustom_instructions:\n  global: \"Audience is senior engineers and EMs. Prefer precision over broad claims.\"\n  interview-qa: \"Weight cross-team influence and leadership stories more heavily.\"\n  portfolio-bullet: \"Lead with impact metrics. Format: Reduced X by Y, enabling Z.\"\n  technical-deep-dive: \"Write for a principal-level audience; include explicit trade-off reasoning.\"\n```\n\nThe instructions appear as a clearly delimited block at the end of the system prompt — they don't modify the prompt template files, so you can iterate them independently.\n\n---\n\n## Prompt eval\n\nCompare prompt versions across all fixtures to catch regressions before promoting a new version:\n\n```bash\n# Run all fixtures × all modes × all declared versions\nnpx tsx scripts/prompt-eval.ts\n\n# Compare two versions on a single mode\nnpx tsx scripts/prompt-eval.ts --versions v1,v2 --modes interview-qa\n\n# Limit to specific fixtures\nnpx tsx scripts/prompt-eval.ts --fixtures debugging-memory-leak,greenfield-auth-service\n```\n\nOutputs land in `test-output/eval/<timestamp>/` (gitignored). Each file gets frontmatter with fixture name, mode, version, and elapsed time. Diff any two versions:\n\n```bash\ndiff test-output/eval/<timestamp>/debugging-memory-leak/interview-qa-v1.md \\\n     test-output/eval/<timestamp>/debugging-memory-leak/interview-qa-v2.md\n```\n\nTo add a new prompt version: create `src/prompts/<mode>/v2.txt`, add it to `src/prompts/manifest.yaml`, then run eval before updating `active`.\n\n---\n\n## Configuration\n\n`~/.skill-forge/config.yaml` (global) or `<project-root>/skill-forge.config.yaml` (project override — takes precedence):\n\n```yaml\nexperience_level: senior       # junior | mid | senior | staff\ntone: balanced                 # technical | business | balanced\noutput_dir: ~/.skill-forge/artifacts\n\n# Provider — auto-detected from env if omitted\n# provider: anthropic\n# model: claude-sonnet-4-6\n\n# provider: openai\n# model: gpt-4o-mini\n\n# provider: ollama\n# model: llama3.2\n# base_url: http://localhost:11434/v1\n\n# provider: openai-compatible   # Groq, Together AI, LM Studio, DeepSeek, etc.\n# model: mixtral-8x7b-32768\n# base_url: https://api.groq.com/openai/v1\n# api_key: gsk_...\n\n# Optional calibration\n# target_role: Staff Engineer\n# company_size: startup         # startup | mid | enterprise\n# default_mode: portfolio-bullet\n\n# Output connector\n# connector: local              # default — writes ~/.skill-forge/artifacts/\n# connector: gist               # also pushes each artifact to a GitHub Gist\n# gist_token: ghp_...           # or set GITHUB_TOKEN (needs `gist` scope)\n# gist_public: false            # default: secret gist\n# connector: notion             # also creates a Notion page with metadata\n# notion_token: ${NOTION_TOKEN}         # run `skill-forge auth notion` to set up\n# notion_database_id: ${NOTION_DATABASE_ID}\n# connector: return_only        # writes locally AND returns the rendered artifact so the\n#                               # host delivers it (Gemini Notebook, Slack, LinkedIn, Docs).\n#                               # Holds zero third-party credentials — see the README.\n\n# Custom instructions — injected into every translator system prompt.\n# Give skill-forge context it can't infer from git: interview targets, tone, what to emphasize.\n#\n# Flat string (applies to all modes):\n# custom_instructions: >\n#   I'm targeting Staff Engineer roles at fintech companies.\n#   Emphasize reliability, distributed systems, and compliance angles.\n#   Tie technical decisions back to business impact and customer trust.\n#\n# Per-mode object:\n# custom_instructions:\n#   global: \"Targeting infra/platform roles. Prefer precision over broad claims.\"\n#   interview-qa: \"Weight cross-team influence and technical leadership stories.\"\n#   portfolio-bullet: \"Lead with business-impact metrics. Format: Reduced X by Y, enabling Z.\"\n#   technical-deep-dive: \"Write for a principal-level audience. Include explicit trade-off reasoning.\"\n```\n\n---\n\n## CLI reference\n\n```bash\n# Generate from a session JSON (slash command path)\nskill-forge generate --mode interview-qa --json ~/.skill-forge-session.json\n\n# Generate from git context (hook path — no --json)\nskill-forge generate --mode portfolio-bullet\n\n# List all generated artifacts\nskill-forge list\n\n# Push the most recent artifact to a GitHub Gist\nskill-forge share\n\n# Host-delivery: render + return the artifact for the host to deliver (Gemini Notebook, Slack, …)\nskill-forge generate --mode technical-deep-dive --connector return_only --json session.json\n\n# Override output directory\nskill-forge generate --mode all --output-dir ./my-artifacts\n\n# Auth subcommands\nskill-forge auth notion          # guided Notion setup (interactive)\nskill-forge auth status          # show which connectors are authenticated\n```\n\n---\n\n## Project structure\n\n```\nsrc/\n  types/          # Zod schemas — SessionSummary, TranslatorOutput, CalibrationConfig\n  claude/         # LLM client — provider factory + Anthropic / OpenAI-compatible providers\n  config/         # Config loader (project-root → home fallback chain), .env loader\n  adapters/       # Input adapters — git context (hook path), stdin/file (slash command path)\n  ingestor/       # Normalizes all input paths into a typed SessionSummary\n  prompts/        # Versioned prompt templates (.txt) per mode\n  translators/    # One translator per mode — LLM call, validation, markdown render\n  output/         # Renderer (frontmatter + header + content) + connector interface\n    connectors/   # LocalFileConnector, GistConnector, NotionConnector + self-registering registry\n  auth/           # Connector auth flows — notion.ts (interactive), config-writer.ts (env/.yaml merge)\n  mcp/            # server.ts — MCP server: generate, list, share, notion_auth_status tools\n  index.ts        # CLI entry point — generate, list, share, auth subcommands\n\nclaude-code-integration/\n  commands/       # skill-forge.md — install as a Claude Code slash command\n  hooks/          # post-session.json — reference hook config\n  mcp/            # .mcp.json — reference MCP server registration\n\ntests/\n  fixtures/       # Realistic session fixtures for eval (rate limiter, auth service, memory leak, monolith extraction, ML pipeline)\n  ingestor.test.ts, renderer.test.ts, mcp-server.test.ts\n  connectors/     # local-file, gist (mocked fetch), notion (mocked client), notion-blocks\n  translators/    # prompt loading, version resolution, interpolation, custom instructions\nscripts/\n  test-local.ts          # Smoke test: full pipeline against the fixture\n  mcp-smoke-test.ts      # MCP protocol smoke test (spawns dist/mcp/server.js)\n  test-share-notion.ts   # Targeted test: share_last_artifact → notion via MCP\n  notion-setup.ts        # Manual database creation (non-interactive fallback)\n  prompt-eval.ts         # Prompt eval harness: runs fixtures × modes × versions for side-by-side comparison\n```\n\n---\n\n## Development & testing\n\n```bash\nnpm install\nnpm run build       # tsc + copies prompt templates into dist/\nnpm test            # Vitest — unit tests (ingestor, renderer, prompts, connectors) + MCP integration test\nnpm run typecheck   # tsc --noEmit over src + tests\n```\n\nThe MCP integration test (`tests/mcp-server.test.ts`) spawns `dist/mcp/server.js` over stdio and asserts the full tool surface — run `npm run build` before it. CI runs build → test → typecheck on Node 20 and 22, Ubuntu and Windows.\n\n---\n\n## Status\n\nv0.1 — working, weekend-built. Tested on:\n\n- Automated test suite: 74 Vitest tests across 11 files (ingestor, renderer, prompt loader/version resolution, local/gist/notion connectors, return_only host-delivery, orchestrator/scout, MCP server integration) + GitHub Actions CI on Node 20/22, Ubuntu/Windows\n- Anthropic API (Claude Sonnet), Ollama (local, no key), DeepSeek via `openai-compatible`\n- `/skill-forge` slash command path end-to-end\n- CLI (`generate`, `list`, `share`, `auth notion`, `auth status`) against real APIs\n- MCP server: `scripts/mcp-smoke-test.ts` drives `initialize → tools/list → list_skill_forge_artifacts → generate_skill_forge_artifact` over MCP client SDK; `claude mcp add` + `claude mcp get` confirms Claude Code's own MCP client connects (`✔ Connected`)\n- `.env` loading with `${VAR}` config indirection, verified by `scripts/deepseek-smoke-test.ts`\n- Gist connector — offline (mocked fetch) and live via the MCP `share_last_artifact` tool\n- Notion connector — live end-to-end: `generate --connector notion` (both `interview-qa` and `portfolio-bullet`), `share_last_artifact --destination notion` via MCP; properties (Title, Mode, Technologies, Date, Patterns) all populated\n- `return_only` host-delivery — live end-to-end into **Gemini Notebook / NotebookLM** via `notebooklm-mcp-cli`: `generate --connector return_only` → `nlm source add --text` (both `portfolio-bullet` and `technical-deep-dive`); source ingested and a grounded query answered while citing the artifact\n\nNot yet tested end-to-end:\n- OpenAI direct provider (`provider: openai` — the `openai-compatible` path with `base_url: https://api.openai.com/v1` is equivalent and works)\n- git commit hook path\n- `npm link` / `npx skill-forge-mcp` as installed global binaries\n\nContributions and issues welcome.\n","readmeFilename":"README.md","homepage":"https://github.com/Abinav-karthikeyan/skillforge#readme","repository":{"url":"git+https://github.com/Abinav-karthikeyan/skillforge.git","type":"git"},"author":{"name":"Abinav Karthikeyan"},"bugs":{"url":"https://github.com/Abinav-karthikeyan/skillforge/issues"}}