Best for
- You need to define skills — bundles of related tools bound to the
- You are configuring tools for data queries, actions, or integrations.
- You want to index ObjectStack data as a knowledge source for RAG
objectstack-ai/objectstack/skills/objectstack-ai/SKILL.md
Design ObjectStack AI skills, tools, knowledge sources, conversations, model registry entries, and MCP integrations. Use when the user is adding `*.skill.ts` / `*.tool.ts`, configuring an LLM provider, wiring agent tools, or indexing ObjectStack data as a knowledge source for RAG. Agents themselves are platform-internal (`ask` / `build`) — third parties extend them via skills and tools, not by authoring `*.agent.ts`. Do not use for general LLM prompting questions unrelated to ObjectStack metadat
Decision brief
Expert instructions for designing AI skills, tools, and knowledge sources — and the platform agents they plug into — using the ObjectStack specification. This skill covers the Agent → Skill → Tool three-tier architecture aligned with Salesforce Agentforce, Microsoft Copilot Stud…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/objectstack-ai/objectstack --skill "skills/objectstack-ai"Inspect the Agent Skill "objectstack-ai" from https://github.com/objectstack-ai/objectstack/blob/2cc71222459e91964e883419611a820c28302429/skills/objectstack-ai/SKILL.md at commit 2cc71222459e91964e883419611a820c28302429. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
You need to define skills — bundles of related tools bound to the
Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.
Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.
The runtime ships exactly two platform agents, bound by surface — the user never picks from a roster; the surface they are in selects the agent:
Every skill declares which surface it binds to via surface: 'ask' | 'build' | 'both' (defaults to 'ask'). A skill may bind only to an agent whose surface it matches; 'both' binds to either. The runtime enforces this in resolveActiveSkills at load time — an incompatible binding i…
Permission review
The documentation includes network, browsing, or remote request actions.
│ │ └─ Atomic operation (query, action, flow, API call)Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 94/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 39 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Expert instructions for designing AI skills, tools, and knowledge sources — and the platform agents they plug into — using the ObjectStack specification. This skill covers the Agent → Skill → Tool three-tier architecture aligned with Salesforce Agentforce, Microsoft Copilot Studio, and ServiceNow Now Assist patterns.
Edition boundary (
service-ai→ cloud; open = MCP-only). The in-UI AI runtime — theask/buildagents, in-product chat, and the/api/v1/ai/*routes (@objectstack/service-ai) — ships in the cloud / Enterprise distribution, not the open framework. The agent / skill / tool schemas in@objectstack/spec/aistay open, so you author*.skill.ts/*.tool.tsas source either way (*.agent.tsis platform-internal) — but they only execute in a cloud / EE host. On the open edition there is no in-product agent: expose the app to your own AI via@objectstack/mcp(BYO-AI) for data query, and author metadata in source mode with an AI coding agent (Claude Code, Cursor).
ask / build surfaces.Agent → Skill → Tool
│ │ │
│ │ └─ Atomic operation (query, action, flow, API call)
│ └─ Capability bundle with instructions & trigger phrases
└─ Autonomous actor with role, instructions, and guardrails
| Tier | Analogy | Reuse Level |
|---|---|---|
| Agent | Job role (e.g., "Help Desk Agent") | Per use-case |
| Skill | Competency (e.g., "Case Management") | Across agents |
| Tool | Specific operation (e.g., "create_record") | Across skills |
Best practice: Always model via Skills first. Direct tool assignment to agents is supported but considered legacy. Skills provide better discoverability, instruction scoping, and reuse.
ask & build (ADR-0063 / ADR-0064)The runtime ships exactly two platform agents, bound by surface — the user never picks from a roster; the surface they are in selects the agent:
ask — the data product (≈ Claude Chat). Conversational read / query /
explore over records, plus running the business actions the app already
exposes. End-user audience, RLS-bounded. Canonical id ask (ASK_AGENT_NAME).
Cloud / Enterprise — the ask runtime ships in the closed cloud AI runtime
(@objectstack/service-ai); it is the implicit copilot for any cloud / EE app
that does not pin app.defaultAgent. (Open editions have no in-product ask;
use MCP.)build — the authoring product (≈ Claude Code). Agentic authoring of
metadata (objects, fields, views, flows) through plan → draft → verify →
publish. Builder audience, governance-gated. Canonical id build. Cloud-only ·
paid — ships in the cloud AI Studio plugin; Studio pins it via app.defaultAgent.There is no per-turn intent classifier: a build-shaped request arriving at
ask is declined and redirected to the Builder, never silently re-routed into
authoring (ADR-0063 §1/§5).
Legacy names are aliases only.
data_chat→askandmetadata_assistant→buildresolve through the alias table for old bookmarks and persistedagent_ids; they are not vocabulary — always writeask/build.*.agent.tsis closed to third parties (agenttype isallowRuntimeCreate:false, allowOrgOverride:false): you extend the platform with skills, never by authoring an agent (ADR-0063 §2).
surface field (ADR-0063 §3)Every skill declares which surface it binds to via
surface: 'ask' | 'build' | 'both' (defaults to 'ask'). A skill may bind only
to an agent whose surface it matches; 'both' binds to either. The runtime
enforces this in resolveActiveSkills at load time — an incompatible binding is a
fast load error, not a silent mis-scope. An agent's tool set is the union of
its surface-compatible skills' tools — there is no global fall-through
(ADR-0064), so ask cannot author by construction.
The built-in skills and their affinities:
| Skill | surface | Owns | Edition |
|---|---|---|---|
schema_reader | both | list_objects, describe_object, query_data | OSS |
data_explorer | ask | query_records, get_record, aggregate_data, visualize_data | OSS |
actions_executor | ask | action_* (the business actions an object exposes) | OSS |
metadata_authoring + solution_design | build | metadata draft / verify / publish + blueprint propose / apply | cloud only |
To grant data exploration to your own (platform-internal) agent, add
data_explorer / schema_reader to its skills[]; deactivating a skill
(active: false) revokes that capability for every agent that references it.
surface:'build'skills are inert on OSS — by design, not a bug. The open single-env framework ships only theaskagent;metadata_authoring/solution_design(and any third-partysurface:'build'skill) are supplied by the cloud AI Studio plugin and simply do not resolve in OSS. Abuild-intent turn on OSS degrades gracefully ("authoring lives in the cloud Build assistant") instead of dead-ending — this is intentional tiering. Do not assume authoring tools resolve in the open framework.
visualize_data: the only built-in tool that draws a chart — it aggregates an object and emits an inlinedata-chartpart. Auto-registered only when an analytics service (IAnalyticsService) is wired;query_data/aggregate_datareturn numbers, not charts.
Ops: set
AI_DAILY_USER_MESSAGES=<N>to cap user turns per user per day (backed by theai_usage_dailyobject; no-op if unset). Adapter health is observable atGET /api/v1/ai/status; invalidaisettings are rejected at save time.
Reference only — third parties do not author agents. The
agenttype is closed (allowRuntimeCreate:false; ADR-0063 §2): the platform ships exactlyaskandbuild, maintained by platform / cloud plugin authors. You extend the platform with skills + tools (and knowledge sources) — never by adding an agent. This section documentsAgentSchemafor reading existing agents and for platform-internal work.
| Property | Type | Description |
|---|---|---|
name | snake_case | Unique agent identifier |
label | string | Human-readable name |
role | string | Agent's persona/role description |
instructions | string | System prompt — detailed behavioural guidance |
| Property | Purpose |
|---|---|
skills | Array of skill names — primary capability model |
tools | Direct tool references — legacy fallback |
surface | 'ask' | 'build' — the product surface this agent is (default 'ask') |
model | LLM model configuration — provider, model, temperature, maxTokens, topP |
knowledge | REMOVED in protocol 17 — declaring sources/indexes on an agent never scoped retrieval (search_knowledge takes sourceIds from the LLM's tool-call arguments). Restrict at the knowledge-service/source level; describe intended grounding in instructions |
guardrails | maxTokensPerInvocation, maxExecutionTimeSec, blockedTopics |
structuredOutput | Output format (JSON schema, regex, etc.) |
planning | Autonomous reasoning — maxIterations (default 10) |
memory | longTerm persistence + reflectionInterval |
permissions | Permission-set capabilities required to use the agent |
active | Enable/disable the agent |
There is no top-level temperature / maxTokens on an agent — sampling
parameters live under model (AIModelConfigSchema).
import { defineAgent } from '@objectstack/spec';
export default defineAgent({
name: 'support_tier_1',
label: 'First Line Support',
role: 'Help Desk Assistant for customer support cases',
instructions: `
You are a friendly and professional help desk assistant.
RULES:
- Always greet the customer by name if available.
- Search the knowledge base before creating a new case.
- Escalate to a human agent if the issue is critical or security-related.
- Never share internal system details with customers.
- Respond in the customer's preferred language.
`,
skills: ['case_management', 'knowledge_search'],
model: {
provider: 'openai',
model: 'gpt-4o',
temperature: 0.3,
},
guardrails: {
blockedTopics: ['internal_pricing', 'employee_data'], // forbidden topics / action names
maxTokensPerInvocation: 8000, // token budget per invocation
maxExecutionTimeSec: 60, // wall-clock cap per invocation
},
});
A Skill is a named bundle of tools with dedicated instructions and trigger conditions.
| Property | Type | Description |
|---|---|---|
name | snake_case | Unique skill identifier (/^[a-z_][a-z0-9_]*$/) |
label | string | Human-readable name |
tools | string[] | Tool names this skill grants access to (trailing wildcard allowed, e.g. action_*) |
| Property | Purpose |
|---|---|
surface | 'ask' | 'build' | 'both' — agent surface affinity (default 'ask'; see above) |
description | What the skill does — helps the agent decide when to use it |
instructions | LLM prompt guidance specific to this skill's context |
triggerPhrases | Natural language phrases that activate the skill |
triggerConditions | Programmatic activation rules |
active | Is the skill enabled (default: true) |
A skill has no
permissionskey — it was removed in 16.x. Skill invocation was never gated by it (the registry reads onlyactive/triggerConditions/tools), and a security-shaped field that enforces nothing is worse than no field at all. Gate access at the agent instead —access/permissionsondefineAgentare enforced at the chat route — or on the underlying actions the skill's tools call (permission sets, ADR-0066).
import { defineSkill } from '@objectstack/spec';
export default defineSkill({
name: 'case_management',
label: 'Case Management',
description: 'Create, update, query, and escalate support cases.',
instructions: `
When managing cases:
- Always check for duplicate cases before creating a new one.
- Set priority based on customer tier: Enterprise → High, Pro → Medium, Free → Low.
- Escalated cases must include a summary of actions already taken.
`,
tools: [
'query_support_case',
'create_support_case',
'update_support_case',
'escalate_case',
],
triggerConditions: [
{ field: 'objectName', operator: 'eq', value: 'support_case' },
],
active: true,
});
| Operator | Meaning |
|---|---|
eq | Equals |
neq | Not equals |
in | Value is in array |
not_in | Value is not in array |
contains | String contains substring |
Tools are the atomic operations that skills expose to agents.
defineTool)A tool authored as metadata (type: 'tool', *.tool.ts) is validated by
ToolSchema: required name / label / description, a JSON Schema
parameters object, plus optional objectName and outputSchema. ToolSchema
is strict — an unknown key (a typo, or a retired key) is a parse error, not
a silent strip. Retired in protocol 17: category, permissions,
active and builtIn (all were authorable and inert; permissions gated
nothing and active: false withdrew nothing — the rejection message carries
each key's replacement), joining requiresConfirmation.
import { defineTool } from '@objectstack/spec';
export default defineTool({
name: 'create_case',
label: 'Create Support Case',
description: 'Creates a new support case record',
parameters: {
type: 'object',
properties: {
subject: { type: 'string', description: 'Case subject' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
},
required: ['subject'],
},
objectName: 'support_case',
});
To gate what a tool can do, gate the underlying action
(action.requiredPermissions, ADR-0066) or the objects it touches; to withdraw
a tool, remove it from the skills/agents that reference it. Categorization, if
you need it, belongs on the action side (action.ai.category — a live,
enforced surface).
Tool metadata is a read-only projection — not an execution entry point.
ToolSchemahas nohandler/implementationfield, and no framework executor loads a metadata-authored tool. The runtime executes a separately-registeredAIToolDefinition(cloud@objectstack/service-ai); tool metadata is a one-way projection for Studio / discovery. Do not expect a hand-authored tool to run in the open edition.
tools[] (legacy)Entries in an agent's inline tools[] array are a different, legacy shape
(AIToolSchema): { type: 'action' | 'flow' | 'query' | 'vector_search', name, description? } — references to existing actions / flows / queries, not
tool definitions. Prefer skills + first-class tool names.
Cloud / EE runtime.
registerActionsAsTools(),AIServicePlugin, and the HITL approval queue below ship in@objectstack/service-ai— the closed cloud / Enterprise runtime, not an open package. On the open edition, expose actions to your own AI via@objectstack/mcpinstead.
You usually don't author tool definitions by hand for action invocation. Every Action you attach to an object via defineObject({ actions: [...] }) is auto-exposed as a tool named action_<actionName> by registerActionsAsTools() (invoked from AIServicePlugin).
Three action types dispatch headlessly:
action.type | Dispatch | Wiring |
|---|---|---|
script | IDataEngine.executeAction(object, target, ctx) — same as Studio's row toolbar | none |
api | HTTP call to action.target (fetch-based by default) | AIServicePlugin({ apiActionBaseUrl, apiActionHeaders }) or custom apiClient |
flow | IAutomationService.execute(target, { triggerData }) | automation service registered with the kernel |
Skipped automatically:
url, modal, form).confirmText set, mode: 'delete', variant: 'danger') — unless the plugin is started with enableActionApproval: true, in which case they route through the HITL approval queue (see below).aiExposed: false).type:'api' body assembly (last wins): user params → recordIdParam (using recordIdField, default 'id') → bodyExtra. bodyShape: { wrap: 'data' } nests user params under data while keeping recordIdParam flat.
Use actionSkipReason(action, ctx) (exported from @objectstack/service-ai — cloud-only, not importable on the open edition) when authoring an action and you want to know why it isn't surfacing in chat. Studio's "AI exposure" diagnostics use the same predicate. Pair with actionRequiresApproval(action) to know whether a registered action will be routed through HITL.
Cloud / EE runtime. The HITL approval queue is part of
@objectstack/service-aiand is not available in the open framework.
kernel.use(new AIServicePlugin({
enableActionApproval: true, // opt in; default is false
apiActionBaseUrl: process.env.OS_AI_ACTION_API_BASE_URL,
}));
Flow:
action_delete_task → runtime persists an ai_pending_actions row and returns { status: 'pending_approval', pendingActionId }.GET/POST /api/v1/ai/pending-actions/...).executed / failed.rejected with an optional reason.Programmatic API on IAIService: proposePendingAction, approvePendingAction, rejectPendingAction, listPendingActions. All are optional (returns clear error when no IDataEngine is wired).
The platform's RAG primitive is the KnowledgeSource
(KnowledgeSourceSchema in @objectstack/spec/ai): declarative metadata
pairing what to index with the id of an IKnowledgeAdapter that does the
work. Sources are registered at runtime via
IKnowledgeService.registerSource() (there is no defineStack collection for
them), and the search_knowledge tool exposes registered sources to agents.
| Property | Purpose |
|---|---|
id | Snake_case source id |
label / description | Display metadata |
adapter | Adapter id (e.g. 'ragflow', 'memory'), resolved via IKnowledgeService.registerAdapter |
adapterConfig | Adapter-specific configuration (opaque to the service) |
source | What gets indexed — discriminated on kind: 'object' | 'file' | 'http' |
embedding | Optional EmbeddingModelSchema ref (provider, model, dimensions) — adapters that manage embeddings internally (RAGFlow, Dify, Vectara) may ignore it |
vectorStore | Optional VectorStoreSchema ref (provider, collection) — same caveat |
refresh | onRecordChange (default true for object sources) + optional cron (surfaced for an external scheduler, not self-scheduled) |
aiExposed | Whether search_knowledge may expose this source to agents (default true) |
Source kinds:
source.kind | Fields |
|---|---|
object | object, contentFields[] (min 1; * = every readable text field), metadataFields?, where? (ObjectQL where syntax) |
file | prefix (storage prefix, e.g. kb/handbooks/), mimeTypes? |
http | urls[], userAgent? |
import { KnowledgeSourceSchema, type KnowledgeSource } from '@objectstack/spec/ai';
export const supportKb: KnowledgeSource = KnowledgeSourceSchema.parse({
id: 'support_kb',
label: 'Support Knowledge Base',
adapter: 'ragflow', // or 'memory' for dev/test
source: {
kind: 'object',
object: 'kb_article',
contentFields: ['title', 'body'], // concatenated into document content
metadataFields: ['category', 'owner_id'], // projected for search-time filtering
where: { published: true }, // index published articles only
},
refresh: { onRecordChange: true }, // re-index on record.* events
});
Chunking, top-K, score thresholds, and rerankers are NOT platform metadata. The spec deliberately scopes them out (
embedding.zod.ts): chunking strategies, retrieval pipelines, and RAG orchestration belong to the adapter (adapterConfig) or application code. The platform only carries the embed + vector primitives so any RAG strategy can be built on top.
where. Index only published/active records
(where: { published: true }) so draft or archived content never enters
the index.contentFields. Do not include system
fields or IDs; use * (all readable text fields) sparingly.metadataFields (e.g. status, owner_id,
tags) so searches can be narrowed at query time.aiExposed: false when a source should be indexed but not
agent-searchable.adapterConfig), not in
ObjectStack metadata.| Provider | Models | Use Case |
|---|---|---|
openai | GPT-4o, GPT-4o-mini, o1, o3-mini | General purpose, reasoning |
anthropic | Claude Sonnet 4, Claude Haiku | Long context, safety |
azure_openai | Same as OpenAI, enterprise managed | Compliance, data residency |
local | Ollama, vLLM, llama.cpp | On-premise, air-gapped |
The inline agent
model.providerenum is the narrow set above (openai/azure_openai/anthropic/local). Model-registry entries (ModelProviderSchema) accept a wider set: alsocohere,huggingface,custom.
| Scenario | Recommended |
|---|---|
| Complex reasoning, multi-step planning | GPT-4o / Claude Sonnet 4 |
| High-volume, low-latency | GPT-4o-mini / Claude Haiku |
| Sensitive data, on-premise | Local models via Ollama |
| Structured data extraction | Any model + structuredOutput config |
| Value | Use Case |
|---|---|
0.0–0.3 | Factual Q&A, data extraction, code generation |
0.3–0.7 | Conversational agents, customer support |
0.7–1.0 | Creative writing, brainstorming |
> 1.0 | Experimental / highly creative (use with caution) |
Force the agent to respond in a specific format:
structuredOutput: {
format: 'json_schema',
schema: {
type: 'object',
properties: {
summary: { type: 'string' },
priority: { type: 'string', enum: ['low', 'medium', 'high'] },
action_items: { type: 'array', items: { type: 'string' } },
},
required: ['summary', 'priority'],
},
strict: true, // enforce exact schema compliance (default: false)
maxRetries: 3, // max retries on validation failure (default: 3)
}
On validation failure the runtime retries by default
(retryOnValidationFailure: true). Optional extras: fallbackFormat and a
transformPipeline of post-processing steps (trim, parse_json,
validate, coerce_types). There is no retry object — the knobs are
retryOnValidationFailure + maxRetries.
blockedTopics (plus the
token / time budgets) in agent guardrails; for destructive operations put
a human in the loop with a gate that is actually enforced —
enableActionApproval: true (HITL queue, cloud) for auto-exposed actions,
ai.requiresConfirmation on the action, or approval: 'always' on an
MCP tool binding. AI metadata edits are already gated: they land as drafts a
human must publish (ADR-0033).
⚠️ requiresConfirmation on the tool was REMOVED (ADR-0033 §2) —
it was read by no execution path, so it produced no pause. ToolSchema is
strict, so authoring it now fails the parse with the migration attached.
There is no requireApprovalFor field.description to decide
when to call it. Poor descriptions = wrong tool selection.where filter and
curated contentFields fills the index with drafts and boilerplate that
pollute retrieval. Source hygiene is the metadata's job; relevance tuning
(top-K, thresholds, reranking) belongs to the adapter.Reference layout for a scaffolded app:
| Layer | File | Pattern |
|---|---|---|
| Reusable skill | src/skills/lead-qualification.skill.ts | defineSkill — trigger phrases + trigger conditions + bounded toolset; pick a surface |
| Tool metadata | src/tools/query-leads.tool.ts | defineTool — JSON-Schema parameters; a discovery projection, not an executor (see caveat above) |
| Knowledge source | src/knowledge/sales-kb.ts | KnowledgeSourceSchema metadata, registered at runtime via IKnowledgeService.registerSource() |
| Central registration | defineStack({ skills: [...], tools: [...] }) | agents / tools / skills are the only AI stack collections — knowledge sources have none; agents are platform-supplied |
Default for metadata apps: push business capability logic into skills, keep tools atomic, and wire domain knowledge through knowledge sources.
After authoring a *.skill.ts / *.tool.ts (or platform-internal
*.agent.ts) or a model-registry entry, run the author-time gate before
reporting done:
os validate # Zod schema + CEL predicate validation + bindings (no artifact)
# or: os build # the same gates, plus emits dist/
It confirms the agent/tool/model metadata conforms to the protocol and that any
CEL predicate (e.g. a tool's availability condition) parses and resolves. In a
scaffolded project the gate is npm run validate. See objectstack-platform →
Verify your work.
See references/_index.md for the full list of Zod
schemas (with one-line descriptions) — pointers into
node_modules/@objectstack/spec/src/. Always Read the source for exact field
shapes; do not rely on memory of property names.
Frequently asked questions
Expert instructions for designing AI skills, tools, and knowledge sources — and the platform agents they plug into — using the ObjectStack specification. This skill covers the Agent → Skill → Tool three-tier architecture aligned with Salesforce Agentforce, Microsoft Copilot Stud…
The source record exposes this install command: npx skills add https://github.com/objectstack-ai/objectstack --skill "skills/objectstack-ai". Inspect the command and pinned source before running it.
Static rules flagged network in the source; the page lists the matching lines and excerpts.
Alternatives
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
coreyhaines31/marketingskills
When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o
prowler-cloud/prowler
PostgreSQL indexing best practices for Prowler: index design, partial indexes, partitioned table indexing, EXPLAIN ANALYZE validation, concurrent operations, monitoring, and maintenance. Trigger: When creating or modifying PostgreSQL indexes, analyzing query performance with EXPLAIN, debugging slow queries, reviewing index usage statistics, reindexing, dropping indexes, or working with partitioned table indexes. Also trigger when discussing index strategies, partial indexes, or index maintenance
oaustegard/claude-skills
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre