@bodhi-ventures/aiocs 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  unlinkProjectSources,
32
32
  upsertSourceFromSpecFile,
33
33
  verifyCoverage
34
- } from "./chunk-AJ5NZDK4.js";
34
+ } from "./chunk-M7YEYMJL.js";
35
35
 
36
36
  // src/cli.ts
37
37
  import { Command, CommanderError as CommanderError2 } from "commander";
@@ -113,6 +113,9 @@ function renderSearchResult(result) {
113
113
  `Snapshot: ${result.snapshotId}`,
114
114
  ...typeof result.score === "number" ? [`Score: ${result.score.toFixed(4)}`] : [],
115
115
  ...result.signals ? [`Signals: ${result.signals.join(", ")}`] : [],
116
+ ...result.pageKind ? [`Kind: ${result.pageKind}`] : [],
117
+ ...result.filePath ? [`Path: ${result.filePath}`] : [],
118
+ ...result.language ? [`Language: ${result.language}`] : [],
116
119
  `Page: ${result.pageTitle}`,
117
120
  `Section: ${result.sectionTitle}`,
118
121
  `URL: ${result.pageUrl}`,
@@ -339,6 +342,7 @@ source.command("list").action(async (_options, command) => {
339
342
  data: result,
340
343
  human: sources.length === 0 ? "No sources registered." : sources.map((item) => [
341
344
  item.id,
345
+ item.kind,
342
346
  item.label,
343
347
  item.isDue ? "due now" : `next due ${item.nextDueAt}`,
344
348
  `spec ${item.specPath ?? "(inline/unknown)"}`,
@@ -520,7 +524,13 @@ embeddings.command("run").description("Process queued embedding jobs immediately
520
524
  program.command("search").argument("<query>").option("--source <source-id>", "restrict search to a source", (value, current) => {
521
525
  current.push(value);
522
526
  return current;
523
- }, []).option("--snapshot <snapshot-id>", "search a specific snapshot").option("--all", "search across all latest snapshots").option("--project <path>", "resolve search scope as if running from this path").option("--mode <mode>", "search mode: auto, lexical, hybrid, semantic").option("--limit <count>", "maximum number of results to return").option("--offset <count>", "number of results to skip before returning matches").action(async (query, options, command) => {
527
+ }, []).option("--snapshot <snapshot-id>", "search a specific snapshot").option("--all", "search across all latest snapshots").option("--project <path>", "resolve search scope as if running from this path").option("--path <glob>", "restrict search to file paths matching a glob", (value, current) => {
528
+ current.push(value);
529
+ return current;
530
+ }, []).option("--language <name>", "restrict search to a language", (value, current) => {
531
+ current.push(value);
532
+ return current;
533
+ }, []).option("--mode <mode>", "search mode: auto, lexical, hybrid, semantic").option("--limit <count>", "maximum number of results to return").option("--offset <count>", "number of results to skip before returning matches").action(async (query, options, command) => {
524
534
  await executeCommand(command, "search", async () => {
525
535
  const limit = parsePositiveIntegerOption(options.limit, "limit");
526
536
  const offset = parsePositiveIntegerOption(options.offset, "offset");
@@ -530,6 +540,8 @@ program.command("search").argument("<query>").option("--source <source-id>", "re
530
540
  ...options.snapshot ? { snapshot: options.snapshot } : {},
531
541
  ...typeof options.all !== "undefined" ? { all: options.all } : {},
532
542
  ...options.project ? { project: options.project } : {},
543
+ ...options.path && options.path.length > 0 ? { path: options.path } : {},
544
+ ...options.language && options.language.length > 0 ? { language: options.language } : {},
533
545
  ...mode ? { mode } : {},
534
546
  ...typeof limit === "number" ? { limit } : {},
535
547
  ...typeof offset === "number" ? { offset } : {}
@@ -26,7 +26,7 @@ import {
26
26
  unlinkProjectSources,
27
27
  upsertSourceFromSpecFile,
28
28
  verifyCoverage
29
- } from "./chunk-AJ5NZDK4.js";
29
+ } from "./chunk-M7YEYMJL.js";
30
30
 
31
31
  // src/mcp-server.ts
32
32
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -50,6 +50,7 @@ var doctorReportSchema = z.object({
50
50
  });
51
51
  var sourceSchema = z.object({
52
52
  id: z.string(),
53
+ kind: z.enum(["web", "git"]),
53
54
  label: z.string(),
54
55
  specPath: z.string().nullable(),
55
56
  nextDueAt: z.string(),
@@ -77,6 +78,9 @@ var searchResultSchema = z.object({
77
78
  pageTitle: z.string(),
78
79
  sectionTitle: z.string(),
79
80
  markdown: z.string(),
81
+ pageKind: z.enum(["document", "file"]),
82
+ filePath: z.string().nullable(),
83
+ language: z.string().nullable(),
80
84
  score: z.number().optional(),
81
85
  signals: z.array(z.enum(["lexical", "vector"])).optional()
82
86
  });
@@ -123,7 +127,8 @@ var canaryResultSchema = z.object({
123
127
  failCount: z.number().int().nonnegative()
124
128
  }),
125
129
  checks: z.array(z.object({
126
- url: z.string(),
130
+ url: z.string().optional(),
131
+ path: z.string().optional(),
127
132
  status: z.enum(["pass", "fail"]),
128
133
  title: z.string().optional(),
129
134
  markdownLength: z.number().int().nonnegative().optional(),
@@ -142,16 +147,25 @@ var snapshotDiffSchema = z.object({
142
147
  }),
143
148
  addedPages: z.array(z.object({
144
149
  url: z.string(),
145
- title: z.string()
150
+ title: z.string(),
151
+ pageKind: z.enum(["document", "file"]),
152
+ filePath: z.string().nullable(),
153
+ language: z.string().nullable()
146
154
  })),
147
155
  removedPages: z.array(z.object({
148
156
  url: z.string(),
149
- title: z.string()
157
+ title: z.string(),
158
+ pageKind: z.enum(["document", "file"]),
159
+ filePath: z.string().nullable(),
160
+ language: z.string().nullable()
150
161
  })),
151
162
  changedPages: z.array(z.object({
152
163
  url: z.string(),
153
164
  beforeTitle: z.string(),
154
165
  afterTitle: z.string(),
166
+ pageKind: z.enum(["document", "file"]),
167
+ filePath: z.string().nullable(),
168
+ language: z.string().nullable(),
155
169
  lineSummary: z.object({
156
170
  addedLineCount: z.number().int().nonnegative(),
157
171
  removedLineCount: z.number().int().nonnegative()
@@ -256,6 +270,8 @@ var toolHandlers = {
256
270
  ...typeof args.snapshotId === "string" ? { snapshot: args.snapshotId } : {},
257
271
  ...typeof args.all === "boolean" ? { all: args.all } : {},
258
272
  ...typeof args.project === "string" ? { project: args.project } : {},
273
+ ...Array.isArray(args.pathPatterns) ? { path: args.pathPatterns } : {},
274
+ ...Array.isArray(args.languages) ? { language: args.languages } : {},
259
275
  ...typeof args.mode === "string" ? { mode: args.mode } : {},
260
276
  ...typeof args.limit === "number" ? { limit: args.limit } : {},
261
277
  ...typeof args.offset === "number" ? { offset: args.offset } : {}
@@ -507,6 +523,8 @@ registerAiocsTool(
507
523
  snapshotId: z.string().optional(),
508
524
  all: z.boolean().optional(),
509
525
  project: z.string().optional(),
526
+ pathPatterns: z.array(z.string()).optional(),
527
+ languages: z.array(z.string()).optional(),
510
528
  mode: z.enum(["auto", "lexical", "hybrid", "semantic"]).optional(),
511
529
  limit: z.number().int().positive().optional(),
512
530
  offset: z.number().int().nonnegative().optional()
package/docs/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Docs
2
2
 
3
- Keep durable project documentation here.
3
+ Keep stable, user-facing project documentation here.
4
4
 
5
5
  Good candidates:
6
6
 
@@ -9,4 +9,4 @@ Good candidates:
9
9
  - operational runbooks
10
10
  - decisions worth preserving across sessions
11
11
  - Codex integration guidance in `codex-integration.md`
12
- - reusable agent examples under `examples/codex-agents/`
12
+ - reusable repo-managed agent definitions under `../agents/`
@@ -9,7 +9,14 @@ Install the CLI and MCP binary globally:
9
9
  ```bash
10
10
  npm install -g @bodhi-ventures/aiocs
11
11
  docs --version
12
- aiocs-mcp
12
+ command -v aiocs-mcp
13
+ ```
14
+
15
+ If global install is unavailable, use `npx` only as a fallback:
16
+
17
+ ```bash
18
+ npx -y -p @bodhi-ventures/aiocs docs --version
19
+ npx -y -p @bodhi-ventures/aiocs aiocs-mcp
13
20
  ```
14
21
 
15
22
  The `aiocs-mcp` process is an MCP stdio server, so running it directly will wait for MCP clients instead of printing interactive help. The useful validation commands are:
@@ -19,6 +26,13 @@ docs --json doctor
19
26
  docs --json init --no-fetch
20
27
  ```
21
28
 
29
+ Register `aiocs-mcp` as a global Codex MCP server so the main agent can use it directly without shell fallback:
30
+
31
+ ```toml
32
+ [mcp_servers.aiocs]
33
+ command = "aiocs-mcp"
34
+ ```
35
+
22
36
  ## How Codex should use aiocs
23
37
 
24
38
  1. Prefer `aiocs` before live browsing when the requested docs may already exist locally.
@@ -27,41 +41,40 @@ docs --json init --no-fetch
27
41
  4. Check `source_list` before assuming a source is missing or stale.
28
42
  5. Default to `search mode=auto`.
29
43
  6. Use `mode=lexical` for exact identifiers, endpoint names, headings, and error strings.
30
- 7. Prefer `refresh due <source-id>` over force `fetch <source-id>` when the source already exists.
31
- 8. Use MCP `batch` when multiple list/search/show or search/diff/coverage steps are needed.
32
- 9. Cite `sourceId`, `snapshotId`, and `pageUrl` when they materially improve traceability.
44
+ 7. Use `pathPatterns` and `languages` filters when the source is a repo/code source and the question is file- or language-specific.
45
+ 8. Use the `aiocs` skill for read/search flows and `aiocs-curation` only when the task requires source onboarding or refresh.
46
+ 9. Prefer `refresh due <source-id>` over force `fetch <source-id>` when the source already exists.
47
+ 10. Use MCP `batch` when multiple list/search/show or search/diff/coverage steps are needed.
48
+ 11. Cite `sourceId`, `snapshotId`, and `pageUrl` when they materially improve traceability.
33
49
 
34
50
  ## Automatic use in Codex
35
51
 
36
- Codex does not automatically invoke a custom subagent just because one exists. The primary automatic-use mechanism is the `aiocs` skill itself.
52
+ Codex does not automatically invoke a custom subagent just because one exists. The primary automatic-use mechanism is the `aiocs` MCP server plus the `aiocs` skill itself.
37
53
 
38
- To make Codex discover `aiocs` automatically on this machine, expose the skill in the global Codex skill directory:
54
+ To make Codex discover the read/search path automatically, expose the skills in the global Codex skill directory:
39
55
 
40
56
  ```bash
41
57
  AIOCS_REPO=/absolute/path/to/your/aiocs/checkout
42
58
  mkdir -p ~/.codex/skills
43
59
  ln -sfn "$AIOCS_REPO/skills/aiocs" ~/.codex/skills/aiocs
60
+ ln -sfn "$AIOCS_REPO/skills/aiocs-curation" ~/.codex/skills/aiocs-curation
44
61
  ```
45
62
 
46
- Once that symlink exists, Codex can load the `aiocs` skill directly from the global skills catalog and prefer local docs without you explicitly calling a subagent.
63
+ Once those symlinks exist, Codex can load `aiocs` for normal local-doc lookup and `aiocs-curation` only when the task needs source mutation or refresh.
47
64
 
48
65
  ## Subagent options
49
66
 
50
- There are two supported subagent patterns:
51
-
52
- - Repo example for development and debugging:
53
- [`docs/examples/codex-agents/aiocs-docs-specialist.example.toml`](examples/codex-agents/aiocs-docs-specialist.example.toml)
54
- - Install-ready global agent definition:
55
- `ai-skills/agents/aiocs-docs-specialist.toml` from your local `ai-skills` checkout
67
+ The repo ships a ready-to-copy specialist definition at
68
+ [`agents/aiocs-docs-specialist.toml`](../agents/aiocs-docs-specialist.toml).
56
69
 
57
- The repo example is intentionally development-oriented and uses a checkout-local MCP command. The global agent points at the globally installed `aiocs-mcp` binary.
70
+ It points at the globally installed `aiocs-mcp` binary so Codex uses the published package by default.
58
71
 
59
- To expose the install-ready global agent to Codex on this machine:
72
+ To expose that agent to Codex:
60
73
 
61
74
  ```bash
62
- AI_SKILLS_REPO=/absolute/path/to/your/ai-skills/checkout
75
+ AIOCS_REPO=/absolute/path/to/your/aiocs/checkout
63
76
  mkdir -p ~/.codex/agents
64
- ln -sfn "$AI_SKILLS_REPO/agents/aiocs-docs-specialist.toml" ~/.codex/agents/aiocs-docs-specialist.toml
77
+ ln -sfn "$AIOCS_REPO/agents/aiocs-docs-specialist.toml" ~/.codex/agents/aiocs-docs-specialist.toml
65
78
  ```
66
79
 
67
80
  ## Suggested Codex flows
@@ -78,6 +91,7 @@ Local docs lookup:
78
91
  ```bash
79
92
  docs --json source list
80
93
  docs --json search "maker flow" --source hyperliquid --mode auto
94
+ docs --json search "WebSocketTransport" --source nktkas-hyperliquid --path "src/**" --language typescript --mode lexical
81
95
  docs --json show 42
82
96
  ```
83
97
 
@@ -114,14 +128,14 @@ If a Codex agent has access to the `aiocs-mcp` server, prefer these MCP tools ov
114
128
  - `doctor`
115
129
  - `init`
116
130
  - `source_list`
117
- - `source_upsert`
118
131
  - `search`
119
132
  - `show`
120
133
  - `canary`
121
- - `refresh_due`
122
134
  - `diff_snapshots`
123
135
  - `verify_coverage`
124
136
  - `embeddings_status`
125
137
  - `batch`
126
138
 
139
+ Use mutating tools such as `source_upsert`, `refresh_due`, and `fetch` only through the `aiocs-curation` workflow.
140
+
127
141
  The CLI remains the fallback and should always be invoked with `--json` for agent use. For normal answering flows, avoid `fetch all`; use targeted due refresh or explicit user-approved force fetches.
@@ -106,8 +106,8 @@ This section documents the stable top-level `data` payload per command.
106
106
  {
107
107
  "summary": {
108
108
  "status": "healthy",
109
- "checkCount": 10,
110
- "passCount": 10,
109
+ "checkCount": 11,
110
+ "passCount": 11,
111
111
  "warnCount": 0,
112
112
  "failCount": 0
113
113
  },
@@ -125,6 +125,7 @@ This section documents the stable top-level `data` payload per command.
125
125
  Check ids are currently:
126
126
 
127
127
  - `catalog`
128
+ - `git`
128
129
  - `playwright`
129
130
  - `daemon-config`
130
131
  - `source-spec-dirs`
@@ -158,9 +159,13 @@ Summary status values:
158
159
  "sources": [
159
160
  {
160
161
  "id": "hyperliquid",
162
+ "kind": "web",
163
+ "specPath": "/absolute/path/to/spec.yaml",
161
164
  "label": "Hyperliquid",
162
165
  "nextDueAt": "2026-03-26T12:00:00.000Z",
166
+ "isDue": false,
163
167
  "nextCanaryDueAt": "2026-03-26T06:00:00.000Z",
168
+ "isCanaryDue": false,
164
169
  "lastCheckedAt": "2026-03-26T10:00:00.000Z",
165
170
  "lastSuccessfulSnapshotAt": "2026-03-26T10:00:00.000Z",
166
171
  "lastSuccessfulSnapshotId": "snp_...",
@@ -256,7 +261,10 @@ Summary status values:
256
261
  "addedPages": [
257
262
  {
258
263
  "url": "https://example.dev/docs/new-page",
259
- "title": "New page"
264
+ "title": "New page",
265
+ "pageKind": "document",
266
+ "filePath": null,
267
+ "language": null
260
268
  }
261
269
  ],
262
270
  "removedPages": [],
@@ -265,6 +273,9 @@ Summary status values:
265
273
  "url": "https://example.dev/docs/start",
266
274
  "beforeTitle": "Start",
267
275
  "afterTitle": "Start",
276
+ "pageKind": "document",
277
+ "filePath": null,
278
+ "language": null,
268
279
  "lineSummary": {
269
280
  "addedLineCount": 3,
270
281
  "removedLineCount": 2
@@ -293,6 +304,9 @@ Summary status values:
293
304
  "pageUrl": "https://example.dev/docs/maker-flow",
294
305
  "pageTitle": "Maker flow",
295
306
  "sectionTitle": "Order lifecycle",
307
+ "pageKind": "document",
308
+ "filePath": null,
309
+ "language": null,
296
310
  "markdown": "# Order lifecycle\n...",
297
311
  "score": 0.036,
298
312
  "signals": ["lexical", "vector"]
@@ -302,6 +316,7 @@ Summary status values:
302
316
  ```
303
317
 
304
318
  `limit` defaults to `20`. `offset` defaults to `0`.
319
+ `pathPatterns` and `languages` narrow results for git/file sources and are also honored by MCP.
305
320
 
306
321
  `modeRequested` is the requested search mode (`auto`, `lexical`, `hybrid`, `semantic`).
307
322
  `modeUsed` is the actual executed mode after fallbacks. In `auto`, `aiocs` can degrade back to lexical if the vector layer is unavailable or incomplete for the requested scope.
@@ -445,6 +460,9 @@ Summary status values:
445
460
  "pageUrl": "https://example.dev/docs/maker-flow",
446
461
  "pageTitle": "Maker flow",
447
462
  "sectionTitle": "Order lifecycle",
463
+ "pageKind": "document",
464
+ "filePath": null,
465
+ "language": null,
448
466
  "markdown": "# Order lifecycle\n..."
449
467
  }
450
468
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bodhi-ventures/aiocs",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Local-only documentation store, fetcher, and search CLI for AI agents.",
@@ -48,27 +48,27 @@
48
48
  "test:watch": "vitest"
49
49
  },
50
50
  "dependencies": {
51
- "@modelcontextprotocol/sdk": "^1.28.0",
52
- "@mozilla/readability": "^0.6.0",
51
+ "@modelcontextprotocol/sdk": "1.28.0",
52
+ "@mozilla/readability": "0.6.0",
53
53
  "@qdrant/js-client-rest": "1.17.0",
54
- "better-sqlite3": "^12.4.1",
55
- "commander": "^14.0.1",
56
- "jsdom": "^27.0.1",
57
- "playwright": "^1.57.0",
58
- "turndown": "^7.2.1",
59
- "turndown-plugin-gfm": "^1.0.2",
60
- "yaml": "^2.8.1",
61
- "zod": "^4.1.12"
54
+ "better-sqlite3": "12.4.1",
55
+ "commander": "14.0.1",
56
+ "jsdom": "27.0.1",
57
+ "playwright": "1.57.0",
58
+ "turndown": "7.2.1",
59
+ "turndown-plugin-gfm": "1.0.2",
60
+ "yaml": "2.8.1",
61
+ "zod": "4.1.12"
62
62
  },
63
63
  "devDependencies": {
64
- "@types/better-sqlite3": "^7.6.13",
65
- "@types/jsdom": "^21.1.7",
66
- "@types/node": "^24.7.2",
67
- "@types/turndown": "^5.0.5",
68
- "execa": "^9.6.0",
69
- "tsup": "^8.5.0",
70
- "tsx": "^4.20.6",
71
- "typescript": "^5.9.3",
72
- "vitest": "^3.2.4"
64
+ "@types/better-sqlite3": "7.6.13",
65
+ "@types/jsdom": "21.1.7",
66
+ "@types/node": "24.7.2",
67
+ "@types/turndown": "5.0.5",
68
+ "execa": "9.6.0",
69
+ "tsup": "8.5.0",
70
+ "tsx": "4.20.6",
71
+ "typescript": "5.9.3",
72
+ "vitest": "3.2.4"
73
73
  }
74
74
  }
@@ -1,30 +1,31 @@
1
+ ---
2
+ name: aiocs
3
+ description: Use when authoritative local documentation lookup should come from the shared aiocs catalog under ~/.aiocs instead of live browsing.
4
+ ---
5
+
1
6
  # aiocs
2
7
 
3
- Use this skill when you need authoritative local documentation search, inspection, safe refresh, or bootstrap through the shared `aiocs` catalog under `~/.aiocs`.
8
+ Use this skill when you need authoritative local documentation lookup through the shared `aiocs` catalog under `~/.aiocs`.
4
9
 
5
10
  ## When to use it
6
11
 
7
12
  - The user is asking about exchange or product docs that may already exist in the local `aiocs` catalog.
8
13
  - You need authoritative local docs for an exchange, SDK, or product without browsing the live site every time.
9
- - You want machine-readable search/show results for an AI agent.
10
- - You need to detect source drift or compare snapshot changes over time.
11
- - You want hybrid docs retrieval with lexical plus semantic/vector recall.
12
- - You need to bootstrap or validate `aiocs` on a new machine.
13
- - You want to keep the local docs catalog warm through the `aiocs` daemon or MCP server.
14
- - You need to back up or restore the shared catalog.
14
+ - You need reusable reference search over a curated external git repository that already lives in `aiocs`.
15
+ - You want machine-readable search/show/diff/coverage results for an AI agent.
16
+ - You need hybrid docs retrieval with lexical plus semantic/vector recall.
17
+ - You need to validate runtime health before relying on the local docs catalog.
15
18
 
16
19
  ## Trigger guidance for Codex
17
20
 
18
21
  - Prefer `aiocs` before live web browsing when the requested docs may already be in the local catalog.
19
22
  - Check `source_list` or scoped `search` before assuming a source is missing.
20
23
  - Use `aiocs` first for the bundled `hyperliquid` source and for any repo or machine that already relies on `~/.aiocs`.
21
- - If a source is missing, only add it when it is worth curating for future reuse.
22
- - Prefer `refresh due <source-id>` over force `fetch <source-id>` whenever freshness is the real goal.
23
- - Do not use `fetch all` as a normal answering path; reserve it for explicit user requests or maintenance flows.
24
+ - This skill is the default read/search path. If the task requires source creation, force fetch, targeted refresh, or canary remediation, also load `aiocs-curation`.
24
25
  - Only fall back to live browsing when:
25
26
  - the source is not present in `aiocs`
26
27
  - the user explicitly wants the live site
27
- - the local catalog is stale or broken and the answer cannot wait for refresh/canary remediation
28
+ - the local catalog is stale or broken and the answer cannot wait for curation/remediation
28
29
  - If you need multiple docs operations in MCP, use `batch` instead of many small round trips.
29
30
 
30
31
  ## Preferred interfaces
@@ -32,11 +33,14 @@ Use this skill when you need authoritative local documentation search, inspectio
32
33
  1. Prefer `aiocs-mcp` when an MCP client can use it directly.
33
34
  2. Otherwise use the CLI with the root `--json` flag.
34
35
  3. Avoid parsing human-formatted CLI output unless there is no alternative.
36
+ 4. Assume `docs` and `aiocs-mcp` come from the globally installed `@bodhi-ventures/aiocs` package unless the user explicitly asks for a checkout-local development build.
37
+ 5. Use `npx -y -p @bodhi-ventures/aiocs ...` only as a fallback when the global install is unavailable.
35
38
 
36
39
  ## Search defaults for agents
37
40
 
38
41
  - Default to `search` with `mode=auto`.
39
42
  - Use `mode=lexical` for exact identifiers, section titles, endpoint names, and error strings.
43
+ - Use `--path` / `pathPatterns` and `--language` / `languages` when searching repo/code sources.
40
44
  - Use `mode=hybrid` for conceptual questions when embeddings are healthy.
41
45
  - Use `mode=semantic` only when you explicitly want vector-only recall.
42
46
  - When citing results, include `sourceId`, `snapshotId`, and `pageUrl` when they materially help traceability.
@@ -55,12 +59,6 @@ Bootstrap managed sources from the repo bundle and `~/.aiocs/sources`:
55
59
  docs --json init --no-fetch
56
60
  ```
57
61
 
58
- User-managed source specs live under:
59
-
60
- ```bash
61
- ~/.aiocs/sources
62
- ```
63
-
64
62
  ## Core commands
65
63
 
66
64
  Search the shared catalog:
@@ -70,6 +68,7 @@ docs --json search "maker flow" --source hyperliquid
70
68
  docs --json search "maker flow" --all
71
69
  docs --json search "maker flow" --source hyperliquid --limit 5 --offset 0
72
70
  docs --json search "maker flow" --source hyperliquid --mode hybrid
71
+ docs --json search "WebSocketTransport" --source nktkas-hyperliquid --path "src/**" --language typescript --mode lexical
73
72
  ```
74
73
 
75
74
  Inspect a specific chunk:
@@ -78,22 +77,12 @@ Inspect a specific chunk:
78
77
  docs --json show 42
79
78
  ```
80
79
 
81
- Refresh the catalog:
80
+ Inspect source availability and health:
82
81
 
83
82
  ```bash
84
83
  docs --json source list
85
- docs --json refresh due hyperliquid
86
84
  docs --json canary hyperliquid
87
85
  docs --json embeddings status
88
- docs --json embeddings backfill all
89
- docs --json embeddings run
90
- ```
91
-
92
- Force fetch is still available for explicit maintenance:
93
-
94
- ```bash
95
- docs --json fetch hyperliquid
96
- docs --json fetch all
97
86
  ```
98
87
 
99
88
  Inspect what changed between snapshots:
@@ -129,11 +118,8 @@ The `aiocs-mcp` server exposes the same core operations without shell parsing:
129
118
  - `version`
130
119
  - `doctor`
131
120
  - `init`
132
- - `source_upsert`
133
121
  - `source_list`
134
122
  - `canary`
135
- - `fetch`
136
- - `refresh_due`
137
123
  - `snapshot_list`
138
124
  - `diff_snapshots`
139
125
  - `project_link`
@@ -149,15 +135,16 @@ The `aiocs-mcp` server exposes the same core operations without shell parsing:
149
135
  - `verify_coverage`
150
136
  - `batch`
151
137
 
138
+ Mutation-capable MCP tools such as `source_upsert`, `refresh_due`, and `fetch` belong to `aiocs-curation`.
139
+
152
140
  ## Recommended Codex workflow
153
141
 
154
- 1. If runtime health or freshness is in doubt, run `doctor`.
155
- 2. Run `source_list` to see whether the source already exists and whether it is due.
156
- 3. If the source exists and is due, prefer `refresh due <source-id>` over force fetch.
157
- 4. If the source is missing but likely to be reused, add a spec under `~/.aiocs/sources`, upsert it, then refresh only that source.
158
- 5. Use `search` in `auto` mode first, then `show` for the selected chunk.
159
- 6. Use `canary`, `diff_snapshots`, or `verify_coverage` when the question is about drift, changes, or completeness.
160
- 7. Use `batch` when combining list/search/show or diff/coverage checks in one pass.
142
+ 1. If runtime health is in doubt, run `doctor`.
143
+ 2. Run `source_list` to see whether the source already exists.
144
+ 3. Use `search` in `auto` mode first, then `show` for the selected chunk.
145
+ 4. Use `canary`, `diff_snapshots`, or `verify_coverage` when the question is about drift, changes, or completeness.
146
+ 5. If the source is missing or stale and the next step is to mutate `aiocs`, load `aiocs-curation`.
147
+ 6. Use `batch` when combining list/search/show or diff/coverage checks in one pass.
161
148
 
162
149
  ## Operational notes
163
150
 
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: aiocs-curation
3
+ description: Use when aiocs sources or snapshots need mutation, such as source onboarding, targeted refresh, canary remediation, or catalog repair.
4
+ ---
5
+
6
+ # aiocs-curation
7
+
8
+ Use this skill when you need to add, refresh, repair, or otherwise mutate `aiocs` sources under `~/.aiocs`.
9
+
10
+ ## When to use it
11
+
12
+ - The requested docs source is missing from the local `aiocs` catalog and is worth curating for reuse.
13
+ - An existing source is stale and should be refreshed instead of bypassed.
14
+ - A source spec needs to be created, updated, or upserted under `~/.aiocs/sources`.
15
+ - A reusable external git repository should be added as a `kind: git` source under `~/.aiocs/sources`.
16
+ - A canary is failing and the source needs remediation or targeted refetch.
17
+ - The user explicitly wants `aiocs` maintenance, source onboarding, or catalog repair.
18
+
19
+ ## Trigger guidance for Codex
20
+
21
+ - Load this skill when the next step requires a mutating `aiocs` operation.
22
+ - Prefer targeted maintenance:
23
+ - `refresh due <source-id>` for existing sources
24
+ - `source_upsert` plus targeted refresh for newly curated sources
25
+ - Avoid `fetch all` unless the user explicitly asks for broad maintenance.
26
+ - If the source is missing, only curate it when it is likely to be reused across sessions or projects.
27
+ - Keep the read/search path in `aiocs`; use this skill only for the curation step.
28
+
29
+ ## Preferred interfaces
30
+
31
+ 1. Prefer `aiocs-mcp` when an MCP client can use it directly.
32
+ 2. Otherwise use the CLI with the root `--json` flag.
33
+ 3. Assume `docs` and `aiocs-mcp` come from the globally installed `@bodhi-ventures/aiocs` package unless the user explicitly asks for a checkout-local development build.
34
+ 4. Use `npx -y -p @bodhi-ventures/aiocs ...` only as a fallback when the global install is unavailable.
35
+
36
+ ## User-managed sources
37
+
38
+ Machine-local source specs live under:
39
+
40
+ ```bash
41
+ ~/.aiocs/sources
42
+ ```
43
+
44
+ Create or update source specs there instead of editing the bundled repo sources.
45
+
46
+ ## Core commands
47
+
48
+ Validate the machine before curation:
49
+
50
+ ```bash
51
+ docs --json doctor
52
+ docs --json source list
53
+ ```
54
+
55
+ Add or update a machine-local source:
56
+
57
+ ```bash
58
+ mkdir -p ~/.aiocs/sources
59
+ docs --json source upsert ~/.aiocs/sources/my-source.yaml
60
+ ```
61
+
62
+ Refresh only what is needed:
63
+
64
+ ```bash
65
+ docs --json refresh due my-source
66
+ docs --json refresh due hyperliquid
67
+ docs --json refresh due nktkas-hyperliquid
68
+ docs --json fetch my-source
69
+ docs --json canary my-source
70
+ ```
71
+
72
+ Heavy maintenance remains explicit:
73
+
74
+ ```bash
75
+ docs --json fetch all
76
+ docs --json embeddings backfill all
77
+ docs --json embeddings run
78
+ ```
79
+
80
+ ## MCP tools
81
+
82
+ The `aiocs-mcp` server exposes the same curation operations without shell parsing:
83
+
84
+ - `doctor`
85
+ - `source_list`
86
+ - `source_upsert`
87
+ - `canary`
88
+ - `fetch`
89
+ - `refresh_due`
90
+ - `embeddings_status`
91
+ - `embeddings_backfill`
92
+ - `embeddings_clear`
93
+ - `embeddings_run`
94
+ - `batch`
95
+
96
+ ## Recommended Codex workflow
97
+
98
+ 1. Run `doctor` or `source_list` if runtime health, presence, or freshness is unclear.
99
+ 2. If the source already exists and is due, prefer `refresh due <source-id>`.
100
+ 3. If the source is missing but worth curating, create a spec under `~/.aiocs/sources`, then `source_upsert` it.
101
+ 4. After upsert, use `refresh due <source-id>` as the safe first fetch path.
102
+ 5. Use `canary` when the site changed or extraction drift is suspected.
103
+ 6. Escalate to `fetch <source-id>` or `fetch all` only for explicit maintenance or when due-based refresh is not enough.
104
+
105
+ ## Operational notes
106
+
107
+ - New or changed sources become due immediately after `source_upsert`.
108
+ - `~/.aiocs/sources` and bundled repo sources behave the same once bootstrapped into the catalog.
109
+ - Targeted refresh is the default. Broad refresh is a maintenance task, not a normal answering step.
110
+ - Use `aiocs` for read/search flows and this skill only for catalog mutation.