fito-plugin
Fito Plugin — fetch web content, extract knowledge components (execution facts, domain concepts, usage scenarios) from API/tool documentation, and generate content for social networks.
Package details
Install fito-plugin from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:fito-plugin- Package
fito-plugin- Version
0.1.1- Published
- Jun 24, 2026
- Downloads
- 185/mo · 21/wk
- Author
- pasemes
- License
- unknown
- Types
- extension, skill, prompt
- Size
- 251.2 KB
- Dependencies
- 0 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./extensions"
],
"prompts": [
"./prompts"
],
"skills": [
"./skills"
],
"agents": [
"./agents"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
Fito Plugin
A pi package that turns documentation about a software development subject — a tool, library, framework, API, language, technique, or methodology — into structured, instructional knowledge.
It is built on the Theory of Robust Knowledge of APIs: the idea that to truly know an API (or any development tool) you need three distinct kinds of knowledge — what it is, what it does at runtime, and how to use it. Fito extracts each kind from source documents and expands it into rich, standalone content.
The plugin runs a three-stage pipeline:
- Ingest — fetch and clean web pages and YouTube transcripts into raw markdown.
- Identify — extract three kinds of knowledge components from the ingested docs.
- Generate — expand each identified component into a detailed, audience-calibrated document.
On purpose and scope. The
package.jsondescribes the end goal as producing content for social networks. What the plugin builds today is instructional/reference content (concept explainers, execution-fact references, and cookbook recipes) — the structured raw material such social content would be derived from. This README documents the current behavior.
Table of Contents
- The Knowledge Model
- Pipeline & Architecture
- Components
- Command Reference
- Data Contracts
- The
url-content-fetcherSkill - The
install-agentsExtension - Installation
- Typical Workflow
- File Structure
- Publishing to npm
The Knowledge Model
Everything in this plugin is organized around three knowledge-component types. Keeping them distinct is the central design principle — each identifier and generator agent is specialized for exactly one, and each one carefully draws boundaries against the other two.
| Component | Captures | Form | Quick test |
|---|---|---|---|
| Execution Fact | What the tool does at runtime | Declarative claim: "when X, then Y" / "X causes/requires Y" | Can a developer use it to predict behavior without running the code? |
| Domain Concept | What an idea is, independent of the tool | Definitional: the real-world concept the tool models | Would the idea still exist if this tool had never been created? |
| Usage Scenario | How to accomplish a goal with the tool | Procedural: ordered steps + code + rationale | Would a developer search "how do I do X with this tool?" |
The three interlock: a usage scenario's steps are justified by the execution facts they rely on (or work around) and the domain concepts they are organized around. The identifier agents are explicitly instructed to extract the right type and exclude the other two — for example, a shininess parameter is an execution fact, but the "specular reflection" it encodes is a domain concept.
Examples (Three.js / Spring Boot):
- Execution Fact — "Changes to object properties become visible only on the next rendered frame."
@Serviceregisters the annotated class as a managed bean in the application context. - Domain Concept — "A torus is a doughnut-shaped 3D surface." "Dependency Injection." "Specular highlight."
- Usage Scenario — "Persisting entity data to a relational table using the Data Mapper pattern." "Handling file uploads securely in a Spring Boot service."
Pipeline & Architecture
┌──────────────────────────────────────────────────────────┐
│ 1. INGEST │
urls.txt ───▶ │ /fetch-urls-content │
│ (url-content-fetcher skill: web pages + YouTube) │
└───────────────────────────┬──────────────────────────────┘
│ cleaned markdown docs
┌───────────────────────────▼──────────────────────────────┐
│ 2. IDENTIFY │
│ /identify-execution-facts → execution-fact-identifier │
│ /identify-domain-concepts → domain-concept-identifier │
│ /identify-usage-scenarios → usage-scenario-identifier │
│ (catalog components → .json + .md) │
└───────────────────────────┬──────────────────────────────┘
│ *.json catalogs
┌───────────────────────────▼──────────────────────────────┐
│ 3. GENERATE │
│ /generate-execution-facts → execution-fact-content-gen │
│ /generate-domain-concepts → domain-concept-content-gen │
│ /generate-usage-scenarios → usage-scenario-content-gen │
│ (one rich .json + .md document per component) │
└──────────────────────────────────────────────────────────┘
Each stage consumes the previous stage's output. The generate-* commands can optionally run the identify-* step first (--identify), which can in turn run the fetch step first (--fetch), so the whole pipeline can be triggered from a single command when needed.
A key design note from the generator agents: the Generate stage uses the agent's own training knowledge to author content — the ingested documents serve the Identify stage only. This knowledge source is intentionally isolated so it can later be replaced (e.g., by an MCP-backed knowledge service or retrieval over official docs).
Output Directory Layout
All output is written under ./output/ in the working directory, organized by stage:
output/
├── 1-ingest/
│ └── extracted_links_content/
│ ├── {slugified-title}.md ← one cleaned doc per URL (with frontmatter)
│ └── _errors.md ← log of URLs that failed to fetch
├── 2-identify/
│ ├── execution_facts/
│ │ ├── execution_facts.json ← structured catalog (primary)
│ │ └── execution_facts.md ← human-readable summary
│ ├── domain_concepts/
│ │ ├── domain_concepts.json
│ │ └── domain_concepts.md
│ └── usage_scenarios/
│ ├── usage_scenarios.json
│ └── usage_scenarios.md
└── 3-generate/
├── execution_fact_content/ ← one {nnn}-{slug}.json + .md per fact
├── concept_content/ ← one {id}-{slug}.json + .md per concept
└── usage_scenario_content/ ← one {id}-{slug}.json + .md per scenario
Components
The plugin registers four kinds of resources via the pi manifest in package.json:
"pi": {
"extensions": ["./extensions"],
"prompts": ["./prompts"],
"skills": ["./skills"],
"agents": ["./agents"]
}
Prompts (Slash Commands)
Thin orchestrators that parse arguments, validate prerequisites, and invoke the appropriate agent. See Command Reference for full arguments.
| Command | Stage | Invokes |
|---|---|---|
/fetch-urls-content |
Ingest | url-content-fetcher skill |
/identify-execution-facts |
Identify | execution-fact-identifier |
/identify-domain-concepts |
Identify | domain-concept-identifier |
/identify-usage-scenarios |
Identify | usage-scenario-identifier |
/generate-execution-facts |
Generate | execution-fact-content-generator |
/generate-domain-concepts |
Generate | domain-concept-content-generator |
/generate-usage-scenarios |
Generate | usage-scenario-content-generator |
Agents
Six subagents — an identifier and a content-generator per knowledge type. The full extraction/generation processes, classification tables, JSON schemas, and quality criteria live in each agent file (agents/*.md).
| Agent | Role |
|---|---|
execution-fact-identifier |
Reads docs and catalogs execution facts. Classifies each into one or more of 15 categories (property-effect, constructor-output, parameter-semantics, return-value, side-effect, state-transition, prerequisite, ordering-constraint, environment-dependency, default-behavior, error-condition, performance-characteristic, limitation-or-bug, interaction, metadata-semantics), with abstraction level, confidence, sources, and related constructs. |
domain-concept-identifier |
Surfaces real-world concepts the subject models, organized by domain, marked primary/supporting, with terminology mapping (standard term vs. the subject's term) and prerequisite_knowledge the subject depends on but does not model. |
usage-scenario-identifier |
Identifies goal-oriented scenarios (goal + overview only; details come later). Enforces action-oriented goals (no "understand X") and consolidates sub-steps into meaningful developer problems. |
execution-fact-content-generator |
Expands each fact into a document: TL;DR, Definition, Primitives Involved, optional Formal Signature / Observable Effects, Code Example, Related Facts, Misconceptions. |
domain-concept-content-generator |
Expands each concept into a 9-section document: TL;DR, Definition, Contextualization, Terminology Mapping, Code Example, Practical Relevance, Misconceptions, Key Characteristics, Related Concepts. |
usage-scenario-content-generator |
Expands each scenario into a cookbook recipe: TL;DR, Problem/Motivation, How It Works, ordered Steps (each with description, code, rationale), optional Alternative Flows, Consolidated Example, Related Scenarios, Misconceptions. |
Templates
The content-generator agents follow a strict section template per knowledge type. The templates define section order, per-section guidance, quality gates, and explicit "forbidden patterns" (e.g., generic filler, slug-style titles, restating the source statement). Full detail in templates/*.md.
| Template | Used by |
|---|---|
concept-content-template.md |
domain-concept-content-generator |
execution-fact-content-template.md |
execution-fact-content-generator |
usage-scenario-content-template.md |
usage-scenario-content-generator |
Skill
| Skill | Purpose |
|---|---|
url-content-fetcher |
Fetches and cleans content from a list of URLs (web pages and YouTube transcripts) by writing and running Python in the VM. See The url-content-fetcher Skill. |
Extension
| Extension | Purpose |
|---|---|
install-agents.ts |
On session start, symlinks the package's agents into the project's .pi/agents/ directory when they are missing or stale. See The install-agents Extension. |
Command Reference
All commands take the subject name (a tool, technique, or methodology) as the first positional argument. If it is omitted, the command stops and prints usage.
/fetch-urls-content
/fetch-urls-content <URL list file path>
Reads a URL file (one URL per line; blank lines and # comments skipped), installs any needed Python packages, fetches each URL via the url-content-fetcher skill, and reports how many succeeded/failed. Defaults to urls.txt in the working directory if no path is given.
/identify-execution-facts · /identify-domain-concepts · /identify-usage-scenarios
/identify-<type> <tool-name> [--description "<text>"] [--fetch [<url-file>]] [--urls <file>] [--docs <path>] [--output <path>]
| Flag | Meaning | Default |
|---|---|---|
--description "<text>" |
Brief description of the subject; helps the agent infer relevant domains before reading | — |
--fetch |
Run /fetch-urls-content first |
off |
--urls <file> |
URL list passed to the fetch step (only with --fetch) |
urls.txt |
--docs <path> |
Directory of fetched markdown docs to analyze | ./output/1-ingest/extracted_links_content/ |
--output <path> |
Where to save results | ./output/2-identify/<type>/ |
Each command verifies the docs directory contains at least one .md file (otherwise it tells you to run /fetch-urls-content first), then invokes the matching identifier agent.
/generate-execution-facts · /generate-domain-concepts · /generate-usage-scenarios
/generate-<type> <tool-name> [--version <ver>] [--<input> <path>] [--output <path>]
[--mode one|batch|all] [--select <ids-or-names-or-ranges>]
[--audience beginner|intermediate|advanced] [--language <lang>]
[--identify] [--docs <path>] [--urls <file>]
| Flag | Meaning | Default |
|---|---|---|
--version <ver> |
Target tool version, so code/API/terminology are accurate for it (generators can infer it when omitted) | inferred |
--facts / --concepts / --scenarios <path> |
Path to the stage-2 *.json catalog to expand |
./output/2-identify/<type>/<type>.json |
--output <path> |
Where to save generated documents | ./output/3-generate/<type>_content/ |
--mode one|batch|all |
Process a single component, a selected subset, or all of them | all |
--select <…> |
IDs, names/fragments, or numeric ranges to process (required for one/batch). Ranges like 5-10 and mixed lists like "1-3, 10, Bean" are expanded before generation |
— |
--audience beginner|intermediate|advanced |
Depth and assumed knowledge | intermediate |
--language <lang> |
Natural language for all generated prose (code stays in its language) | English |
--identify |
Run the matching /identify-* step first (use when the catalog does not exist yet) |
off |
--docs <path> |
Fetched-docs path, passed through to --identify |
./output/1-ingest/extracted_links_content/ |
--urls <file> |
URL list, passed through to --identify |
urls.txt |
The command resolves the catalog path and the content template, verifies both exist, creates the output directory, and invokes the matching content-generator agent with the resolved arguments.
Data Contracts
Stage 2 (Identify) writes one *.json catalog (machine-readable, the primary artifact) plus a companion *.md summary per knowledge type. Stage 3 (Generate) reads that catalog and writes one {id}-{slug}.json + .md document per component. The generator agents are constrained to write only these per-component files — no index, manifest, report, or summary files (the run summary is returned in chat).
Each catalog carries a metadata block (subject/tool name, version, documents analyzed, extraction date, totals) and a summary block (counts by category/domain/confidence and key insights). The component arrays carry:
| Catalog | Per-item key fields |
|---|---|
execution_facts.json |
id (EF-001…), statement, categories[], abstraction_level (low/mid/high), confidence, sources[], related_constructs (types/methods/properties/parameters), preconditions[], notes |
domain_concepts.json |
id, name, domain, relevance (primary/supporting), confidence, description, subject_terminology, standard_terminology, parent_concept, related_concepts[], sources[] — plus a separate prerequisite_knowledge[] list |
usage_scenarios.json |
id, title, goal, overview, confidence, sources[], related_scenarios[], notes |
Generated documents mirror their template's sections as JSON fields under content, with a metadata block recording tool, version (and version_inferred), audience level, language, generation date, and the source component's carried-over fields. See the agent files for the complete schemas.
The url-content-fetcher Skill
Processes a list of URLs by writing and executing Python in the VM (it deliberately does not use the built-in WebFetch tool, which can't batch from a file).
- URL detection —
youtube.com/watch,youtu.be/,youtube.com/shorts/are treated as YouTube; everything else as a web page. - YouTube — uses
youtube-transcript-api; accepts transcripts in any language (prefers manual captions over auto-generated); falls back toyt-dlp --write-auto-sub --skip-downloadand.vttcleanup if no transcript is available. - Web pages — uses a content-extraction library (
trafilatura,readability-lxml). Validates the result is substantive (>200 chars); for JS-rendered pages, falls back in order torequests-html, thenplaywright/selenium, and only finally torequests+beautifulsoup4. - Cleaning — strips the extraction library's own metadata block, removes nav/footer/ads/social/related/signup boilerplate, keeps headings/links/lists/code, and breaks YouTube transcripts into natural paragraphs. No language/transcript-type disclaimers are added.
- Output — one file per URL at
./output/1-ingest/extracted_links_content/{slugified-title}.md, each with frontmatter (source_url,title,type,fetched_at,author, and an original ≤50-wordsummary). Failures are logged to_errors.md; duplicate URLs are skipped; web requests use a 15s timeout.
The install-agents Extension
extensions/install-agents.ts keeps the project's agents in sync with the package's agents/ directory so the subagents are available to pi.
- Runs on
session_startwith reasonstartuporreload. - Computes a SHA-256 hash of the package's
agents/*.mdand compares it to a.install-agents-manifestfile in the project's.pi/agents/. If nothing changed, it does no work (zero cost on normal startups). - When it does sync, it symlinks each package agent into
.pi/agents/, removes stale entries (deleted/renamed agents and plain non-symlink files), and rewrites the manifest. The manifest file itself is preserved.
Installation
Install the published package from npm:
# Global (adds to your user settings)
pi install npm:fito-plugin
# Project-local (adds to ./.pi/settings.json in the current repo)
pi install npm:fito-plugin -l
fito-plugin is unscoped, so the source is npm:fito-plugin (the npm:@scope/name form is only for scoped packages).
Once installed, manage it with:
pi list # confirm it's installed
pi config # enable/disable its prompts, agents, and skills
pi update npm:fito-plugin # pull a newer published version
pi remove npm:fito-plugin # uninstall (add -l for the project-local install)
From source (development)
To install a local checkout instead of the published package:
pi install ./fito-plugin # global
pi install -l ./fito-plugin # project-local
Typical Workflow
# 1. Ingest documentation listed in urls.txt
/fetch-urls-content urls.txt
# 2. Identify each kind of knowledge component
/identify-execution-facts <tool-name> --description "what it does"
/identify-domain-concepts <tool-name>
/identify-usage-scenarios <tool-name>
# 3. Generate detailed content for each
/generate-execution-facts <tool-name> --audience intermediate
/generate-domain-concepts <tool-name>
/generate-usage-scenarios <tool-name>
Shortcuts:
# Run identify (and fetch) automatically, then generate everything in one go
/generate-domain-concepts <tool-name> --identify --urls urls.txt
# Generate content for just a subset, at a specific version and audience
/generate-execution-facts <tool-name> --version 3.3 --mode batch --select "1-3, EF-010" --audience advanced
File Structure
fito-plugin/
├── package.json ← pi manifest (extensions, prompts, skills, agents)
├── extensions/
│ └── install-agents.ts ← syncs agents into .pi/agents/ on session start
├── prompts/
│ ├── fetch-urls-content.md
│ ├── identify-execution-facts.md
│ ├── identify-domain-concepts.md
│ ├── identify-usage-scenarios.md
│ ├── generate-execution-facts.md
│ ├── generate-domain-concepts.md
│ └── generate-usage-scenarios.md
├── skills/
│ └── url-content-fetcher/
│ └── SKILL.md
├── agents/
│ ├── execution-fact-identifier.md
│ ├── domain-concept-identifier.md
│ ├── usage-scenario-identifier.md
│ ├── execution-fact-content-generator.md
│ ├── domain-concept-content-generator.md
│ └── usage-scenario-content-generator.md
├── templates/
│ ├── concept-content-template.md
│ ├── execution-fact-content-template.md
│ └── usage-scenario-content-template.md
└── README.md
Publishing to npm
This package is published to npm as fito-plugin — unscoped and public. Publishing is a maintainer task; end users install with pi install npm:fito-plugin.
Prerequisites
- An npm account with publish rights on the
fito-pluginname (npm owner ls fito-pluginto check). - A clean git working tree —
npm versioncreates a release commit and tag.
Release steps
# 1. Authenticate with npm
npm login
# 2. Bump the version. npm refuses to overwrite an already-published
# version, so every release must increment it. This also creates a
# commit and a git tag.
npm version patch # 0.1.0 -> 0.1.1 (use minor/major as appropriate)
# 3. Preview exactly which files will be published
npm publish --dry-run
# 4. Publish (the package is public and unscoped, so no --access flag is needed)
npm publish
# 5. Push the version commit and its tag
git push --follow-tags
# 6. Verify
npm view fito-plugin version
What gets published
There is no files allowlist or .npmignore, so npm falls back to .gitignore. Everything needed at runtime ships: prompts/, agents/, skills/, templates/, extensions/, plus package.json and README.md. Two things to keep in mind:
templates/ships as plain data, not as apiresource. Thegenerate-*commands read the template files directly from the installed package'stemplates/directory, so the files must be present in the published tarball. They are not declared in thepimanifest — and need not be, since the manifest only registers extensions, prompts, skills, and agents. With the current.gitignore-based file selection they are published automatically. Caveat: if you later add an explicitfilesallowlist topackage.json, includetemplates/or generation will break for installed users.extensions/install-agents.tsships as raw TypeScript. There is no build step (and.gitignoreexcludesdist/), consistent withpiloading.tsdirectly — no compile step is required before publishing.