@bodhi-ventures/aiocs 0.1.0 → 0.1.1
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/LICENSE +1 -1
- package/README.md +7 -9
- package/dist/{chunk-ID3PUSMY.js → chunk-AJ5NZDK4.js} +11 -6
- package/dist/cli.js +7 -6
- package/dist/mcp-server.js +5 -5
- package/docs/2026-03-28-hybrid-search-design.md +1 -1
- package/docs/codex-integration.md +6 -4
- package/docs/json-contract.md +11 -7
- package/package.json +1 -1
- package/skills/aiocs/SKILL.md +4 -4
- package/sources/ethereal.yaml +0 -20
- package/sources/lighter.yaml +0 -24
- package/sources/nado.yaml +0 -22
- package/sources/synthetix.yaml +0 -24
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -111,17 +111,15 @@ GitHub Actions publishes `@bodhi-ventures/aiocs` publicly to npm and creates the
|
|
|
111
111
|
|
|
112
112
|
For Codex-first setup, automatic-use guidance, MCP recommendations, and subagent examples, see [docs/codex-integration.md](./docs/codex-integration.md).
|
|
113
113
|
|
|
114
|
-
##
|
|
114
|
+
## Managed sources
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
The open-source repo bundles `hyperliquid` in `sources/`. Additional machine-local source specs
|
|
117
|
+
belong in `~/.aiocs/sources`.
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- `lighter`
|
|
121
|
-
- `nado`
|
|
122
|
-
- `ethereal`
|
|
119
|
+
`docs init` bootstraps both managed locations, so source behavior is the same regardless of
|
|
120
|
+
whether a spec lives in the repo or in `~/.aiocs/sources`.
|
|
123
121
|
|
|
124
|
-
Bootstrap
|
|
122
|
+
Bootstrap managed sources in one command:
|
|
125
123
|
|
|
126
124
|
```bash
|
|
127
125
|
docs init --no-fetch
|
|
@@ -416,7 +414,7 @@ Successful MCP results use an envelope:
|
|
|
416
414
|
"ok": true,
|
|
417
415
|
"data": {
|
|
418
416
|
"name": "@bodhi-ventures/aiocs",
|
|
419
|
-
"version": "0.1.
|
|
417
|
+
"version": "0.1.1"
|
|
420
418
|
}
|
|
421
419
|
}
|
|
422
420
|
```
|
|
@@ -3208,7 +3208,7 @@ async function startDaemon(input) {
|
|
|
3208
3208
|
// package.json
|
|
3209
3209
|
var package_default = {
|
|
3210
3210
|
name: "@bodhi-ventures/aiocs",
|
|
3211
|
-
version: "0.1.
|
|
3211
|
+
version: "0.1.1",
|
|
3212
3212
|
license: "MIT",
|
|
3213
3213
|
type: "module",
|
|
3214
3214
|
description: "Local-only documentation store, fetcher, and search CLI for AI agents.",
|
|
@@ -4398,14 +4398,19 @@ async function verifyCoverage(input) {
|
|
|
4398
4398
|
return verifyCoverageAgainstReferences(corpus, input.referenceFiles);
|
|
4399
4399
|
});
|
|
4400
4400
|
}
|
|
4401
|
-
async function
|
|
4402
|
-
const
|
|
4401
|
+
async function initManagedSources(options) {
|
|
4402
|
+
const sourceSpecDirs = uniqueResolvedPaths(
|
|
4403
|
+
options?.sourceSpecDirs ?? [
|
|
4404
|
+
getBundledSourcesDir(),
|
|
4405
|
+
getAiocsSourcesDir()
|
|
4406
|
+
]
|
|
4407
|
+
);
|
|
4403
4408
|
const fetched = options?.fetch ?? false;
|
|
4404
4409
|
const userSourceDir = getAiocsSourcesDir();
|
|
4405
4410
|
return withCatalog(async ({ catalog, dataDir }) => {
|
|
4406
4411
|
const bootstrapped = await bootstrapSourceSpecs({
|
|
4407
4412
|
catalog,
|
|
4408
|
-
sourceSpecDirs
|
|
4413
|
+
sourceSpecDirs,
|
|
4409
4414
|
strictSourceSpecDirs: true
|
|
4410
4415
|
});
|
|
4411
4416
|
const fetchResults = [];
|
|
@@ -4429,7 +4434,7 @@ async function initBuiltInSources(options) {
|
|
|
4429
4434
|
});
|
|
4430
4435
|
}
|
|
4431
4436
|
return {
|
|
4432
|
-
|
|
4437
|
+
sourceSpecDirs,
|
|
4433
4438
|
userSourceDir,
|
|
4434
4439
|
fetched,
|
|
4435
4440
|
initializedSources: bootstrapped.sources,
|
|
@@ -4523,7 +4528,7 @@ export {
|
|
|
4523
4528
|
searchCatalog,
|
|
4524
4529
|
showChunk,
|
|
4525
4530
|
verifyCoverage,
|
|
4526
|
-
|
|
4531
|
+
initManagedSources,
|
|
4527
4532
|
getManagedSourceSpecDirectories,
|
|
4528
4533
|
getDoctorReport,
|
|
4529
4534
|
exportCatalogBackup,
|
package/dist/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getEmbeddingStatus,
|
|
14
14
|
getManagedSourceSpecDirectories,
|
|
15
15
|
importCatalogBackup,
|
|
16
|
-
|
|
16
|
+
initManagedSources,
|
|
17
17
|
linkProjectSources,
|
|
18
18
|
listSnapshotsForSource,
|
|
19
19
|
listSources,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
unlinkProjectSources,
|
|
32
32
|
upsertSourceFromSpecFile,
|
|
33
33
|
verifyCoverage
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-AJ5NZDK4.js";
|
|
35
35
|
|
|
36
36
|
// src/cli.ts
|
|
37
37
|
import { Command, CommanderError as CommanderError2 } from "commander";
|
|
@@ -289,21 +289,22 @@ program.command("version").description("Show the current aiocs version.").action
|
|
|
289
289
|
human: packageVersion
|
|
290
290
|
}));
|
|
291
291
|
});
|
|
292
|
-
program.command("init").description("Register
|
|
292
|
+
program.command("init").description("Register managed source specs from the bundled repo directory and ~/.aiocs/sources, then optionally fetch them.").option("--fetch", "fetch managed sources immediately").option("--no-fetch", "skip immediate fetching after bootstrapping").action(async (options, command) => {
|
|
293
293
|
await executeCommand(command, "init", async () => {
|
|
294
|
-
const result = await
|
|
294
|
+
const result = await initManagedSources({
|
|
295
295
|
fetch: options.fetch ?? false
|
|
296
296
|
});
|
|
297
297
|
return {
|
|
298
298
|
data: result,
|
|
299
299
|
human: [
|
|
300
|
-
`Initialized ${result.initializedSources.length}
|
|
300
|
+
`Initialized ${result.initializedSources.length} managed sources from ${result.sourceSpecDirs.length} directories`,
|
|
301
|
+
...result.sourceSpecDirs.map((directory) => `Managed source dir: ${directory}`),
|
|
301
302
|
`User-managed source specs live under ${getManagedSourceSpecDirectories().userSourceDir}`,
|
|
302
303
|
...result.removedSourceIds.length > 0 ? [`Removed managed sources: ${result.removedSourceIds.join(", ")}`] : [],
|
|
303
304
|
...result.fetchResults.length > 0 ? result.fetchResults.map((entry) => {
|
|
304
305
|
const verb = entry.reused ? "Reused" : "Fetched";
|
|
305
306
|
return `${verb} ${entry.sourceId} -> ${entry.snapshotId} (${entry.pageCount} pages)`;
|
|
306
|
-
}) : [result.fetched ? "No
|
|
307
|
+
}) : [result.fetched ? "No managed sources were fetched." : "Skipped fetching managed sources."]
|
|
307
308
|
]
|
|
308
309
|
};
|
|
309
310
|
});
|
package/dist/mcp-server.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
getDoctorReport,
|
|
11
11
|
getEmbeddingStatus,
|
|
12
12
|
importCatalogBackup,
|
|
13
|
-
|
|
13
|
+
initManagedSources,
|
|
14
14
|
linkProjectSources,
|
|
15
15
|
listSnapshotsForSource,
|
|
16
16
|
listSources,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
unlinkProjectSources,
|
|
27
27
|
upsertSourceFromSpecFile,
|
|
28
28
|
verifyCoverage
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-AJ5NZDK4.js";
|
|
30
30
|
|
|
31
31
|
// src/mcp-server.ts
|
|
32
32
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -235,7 +235,7 @@ var toolHandlers = {
|
|
|
235
235
|
version: packageVersion
|
|
236
236
|
}),
|
|
237
237
|
doctor: async () => getDoctorReport(),
|
|
238
|
-
init: async (args = {}) =>
|
|
238
|
+
init: async (args = {}) => initManagedSources({
|
|
239
239
|
...typeof args.fetch === "boolean" ? { fetch: args.fetch } : {}
|
|
240
240
|
}),
|
|
241
241
|
source_upsert: async (args = {}) => upsertSourceFromSpecFile(args.specFile),
|
|
@@ -350,12 +350,12 @@ registerAiocsTool(
|
|
|
350
350
|
"init",
|
|
351
351
|
{
|
|
352
352
|
title: "Init",
|
|
353
|
-
description: "Bootstrap the bundled
|
|
353
|
+
description: "Bootstrap managed source specs from the bundled repo directory and ~/.aiocs/sources, then optionally fetch them.",
|
|
354
354
|
inputSchema: z.object({
|
|
355
355
|
fetch: z.boolean().optional()
|
|
356
356
|
}),
|
|
357
357
|
outputSchema: z.object({
|
|
358
|
-
|
|
358
|
+
sourceSpecDirs: z.array(z.string()),
|
|
359
359
|
userSourceDir: z.string(),
|
|
360
360
|
fetched: z.boolean(),
|
|
361
361
|
initializedSources: z.array(z.object({
|
|
@@ -24,7 +24,7 @@ This design keeps `aiocs` as the canonical docs system:
|
|
|
24
24
|
|
|
25
25
|
## Why This Shape
|
|
26
26
|
|
|
27
|
-
The current `aiocs` search path in [catalog.ts](
|
|
27
|
+
The current `aiocs` search path in [catalog.ts](../src/catalog/catalog.ts) is pure FTS5 BM25 over the latest successful snapshots. That is excellent for exact docs lookups, versioned terms, and API names. It is weaker for:
|
|
28
28
|
|
|
29
29
|
- synonym-heavy prompts
|
|
30
30
|
- conceptual questions
|
|
@@ -38,8 +38,9 @@ Codex does not automatically invoke a custom subagent just because one exists. T
|
|
|
38
38
|
To make Codex discover `aiocs` automatically on this machine, expose the skill in the global Codex skill directory:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
+
AIOCS_REPO=/absolute/path/to/your/aiocs/checkout
|
|
41
42
|
mkdir -p ~/.codex/skills
|
|
42
|
-
ln -sfn /
|
|
43
|
+
ln -sfn "$AIOCS_REPO/skills/aiocs" ~/.codex/skills/aiocs
|
|
43
44
|
```
|
|
44
45
|
|
|
45
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.
|
|
@@ -49,17 +50,18 @@ Once that symlink exists, Codex can load the `aiocs` skill directly from the glo
|
|
|
49
50
|
There are two supported subagent patterns:
|
|
50
51
|
|
|
51
52
|
- Repo example for development and debugging:
|
|
52
|
-
[`docs/examples/codex-agents/aiocs-docs-specialist.example.toml`](
|
|
53
|
+
[`docs/examples/codex-agents/aiocs-docs-specialist.example.toml`](examples/codex-agents/aiocs-docs-specialist.example.toml)
|
|
53
54
|
- Install-ready global agent definition:
|
|
54
|
-
|
|
55
|
+
`ai-skills/agents/aiocs-docs-specialist.toml` from your local `ai-skills` checkout
|
|
55
56
|
|
|
56
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.
|
|
57
58
|
|
|
58
59
|
To expose the install-ready global agent to Codex on this machine:
|
|
59
60
|
|
|
60
61
|
```bash
|
|
62
|
+
AI_SKILLS_REPO=/absolute/path/to/your/ai-skills/checkout
|
|
61
63
|
mkdir -p ~/.codex/agents
|
|
62
|
-
ln -sfn /
|
|
64
|
+
ln -sfn "$AI_SKILLS_REPO/agents/aiocs-docs-specialist.toml" ~/.codex/agents/aiocs-docs-specialist.toml
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
## Suggested Codex flows
|
package/docs/json-contract.md
CHANGED
|
@@ -73,7 +73,7 @@ This section documents the stable top-level `data` payload per command.
|
|
|
73
73
|
```json
|
|
74
74
|
{
|
|
75
75
|
"name": "@bodhi-ventures/aiocs",
|
|
76
|
-
"version": "0.1.
|
|
76
|
+
"version": "0.1.1"
|
|
77
77
|
}
|
|
78
78
|
```
|
|
79
79
|
|
|
@@ -81,7 +81,11 @@ This section documents the stable top-level `data` payload per command.
|
|
|
81
81
|
|
|
82
82
|
```json
|
|
83
83
|
{
|
|
84
|
-
"
|
|
84
|
+
"sourceSpecDirs": [
|
|
85
|
+
"/absolute/path/to/aiocs/sources",
|
|
86
|
+
"<home>/.aiocs/sources"
|
|
87
|
+
],
|
|
88
|
+
"userSourceDir": "<home>/.aiocs/sources",
|
|
85
89
|
"fetched": false,
|
|
86
90
|
"initializedSources": [
|
|
87
91
|
{
|
|
@@ -402,7 +406,7 @@ Summary status values:
|
|
|
402
406
|
"manifest": {
|
|
403
407
|
"formatVersion": 1,
|
|
404
408
|
"createdAt": "2026-03-26T10:00:00.000Z",
|
|
405
|
-
"packageVersion": "0.1.
|
|
409
|
+
"packageVersion": "0.1.1",
|
|
406
410
|
"entries": [
|
|
407
411
|
{
|
|
408
412
|
"relativePath": "data/catalog.sqlite",
|
|
@@ -419,12 +423,12 @@ Summary status values:
|
|
|
419
423
|
```json
|
|
420
424
|
{
|
|
421
425
|
"inputDir": "/absolute/path/to/backup",
|
|
422
|
-
"dataDir": "
|
|
423
|
-
"configDir": "
|
|
426
|
+
"dataDir": "<home>/.aiocs/data",
|
|
427
|
+
"configDir": "<home>/.aiocs/config",
|
|
424
428
|
"manifest": {
|
|
425
429
|
"formatVersion": 1,
|
|
426
430
|
"createdAt": "2026-03-26T10:00:00.000Z",
|
|
427
|
-
"packageVersion": "0.1.
|
|
431
|
+
"packageVersion": "0.1.1",
|
|
428
432
|
"entries": []
|
|
429
433
|
}
|
|
430
434
|
}
|
|
@@ -495,7 +499,7 @@ Successful MCP tool results:
|
|
|
495
499
|
"ok": true,
|
|
496
500
|
"data": {
|
|
497
501
|
"name": "@bodhi-ventures/aiocs",
|
|
498
|
-
"version": "0.1.
|
|
502
|
+
"version": "0.1.1"
|
|
499
503
|
}
|
|
500
504
|
}
|
|
501
505
|
```
|
package/package.json
CHANGED
package/skills/aiocs/SKILL.md
CHANGED
|
@@ -17,7 +17,7 @@ Use this skill when you need authoritative local documentation search, inspectio
|
|
|
17
17
|
|
|
18
18
|
- Prefer `aiocs` before live web browsing when the requested docs may already be in the local catalog.
|
|
19
19
|
- Check `source_list` or scoped `search` before assuming a source is missing.
|
|
20
|
-
- Use `aiocs` first for
|
|
20
|
+
- Use `aiocs` first for the bundled `hyperliquid` source and for any repo or machine that already relies on `~/.aiocs`.
|
|
21
21
|
- If a source is missing, only add it when it is worth curating for future reuse.
|
|
22
22
|
- Prefer `refresh due <source-id>` over force `fetch <source-id>` whenever freshness is the real goal.
|
|
23
23
|
- Do not use `fetch all` as a normal answering path; reserve it for explicit user requests or maintenance flows.
|
|
@@ -49,7 +49,7 @@ Validate the local runtime:
|
|
|
49
49
|
docs --json doctor
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
Bootstrap the
|
|
52
|
+
Bootstrap managed sources from the repo bundle and `~/.aiocs/sources`:
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
55
|
docs --json init --no-fetch
|
|
@@ -170,5 +170,5 @@ The `aiocs-mcp` server exposes the same core operations without shell parsing:
|
|
|
170
170
|
- Newly added or changed sources become due immediately, so `refresh due <source-id>` is the safe first refresh path after upsert.
|
|
171
171
|
- CLI failures expose machine-readable `error.code` fields in `--json` mode.
|
|
172
172
|
- MCP tool results use `{ ok, data?, error? }` envelopes, and `batch` can reduce multiple small MCP round trips.
|
|
173
|
-
- For exact CLI payloads, see
|
|
174
|
-
- For Codex setup and subagent examples, see
|
|
173
|
+
- For exact CLI payloads, see `docs/json-contract.md`.
|
|
174
|
+
- For Codex setup and subagent examples, see `docs/codex-integration.md`.
|
package/sources/ethereal.yaml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
id: ethereal
|
|
2
|
-
label: Ethereal Docs
|
|
3
|
-
startUrls:
|
|
4
|
-
- https://docs.ethereal.trade/
|
|
5
|
-
allowedHosts:
|
|
6
|
-
- docs.ethereal.trade
|
|
7
|
-
discovery:
|
|
8
|
-
include:
|
|
9
|
-
- https://docs.ethereal.trade/**
|
|
10
|
-
exclude: []
|
|
11
|
-
maxPages: 500
|
|
12
|
-
extract:
|
|
13
|
-
strategy: clipboardButton
|
|
14
|
-
interactions:
|
|
15
|
-
- action: click
|
|
16
|
-
selector: button[aria-label="Copy page"]
|
|
17
|
-
normalize:
|
|
18
|
-
prependSourceComment: true
|
|
19
|
-
schedule:
|
|
20
|
-
everyHours: 24
|
package/sources/lighter.yaml
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
id: lighter
|
|
2
|
-
label: Lighter Docs
|
|
3
|
-
startUrls:
|
|
4
|
-
- https://apidocs.lighter.xyz/docs/get-started
|
|
5
|
-
- https://apidocs.lighter.xyz/reference/status
|
|
6
|
-
allowedHosts:
|
|
7
|
-
- apidocs.lighter.xyz
|
|
8
|
-
discovery:
|
|
9
|
-
include:
|
|
10
|
-
- https://apidocs.lighter.xyz/docs/**
|
|
11
|
-
- https://apidocs.lighter.xyz/reference/**
|
|
12
|
-
exclude: []
|
|
13
|
-
maxPages: 800
|
|
14
|
-
extract:
|
|
15
|
-
strategy: clipboardButton
|
|
16
|
-
interactions:
|
|
17
|
-
- action: click
|
|
18
|
-
selector: 'button:has-text("Ask AI")'
|
|
19
|
-
- action: click
|
|
20
|
-
selector: 'div[role="button"]:has-text("Copy Markdown")'
|
|
21
|
-
normalize:
|
|
22
|
-
prependSourceComment: true
|
|
23
|
-
schedule:
|
|
24
|
-
everyHours: 24
|
package/sources/nado.yaml
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
id: nado
|
|
2
|
-
label: Nado Docs
|
|
3
|
-
startUrls:
|
|
4
|
-
- https://docs.nado.xyz/
|
|
5
|
-
allowedHosts:
|
|
6
|
-
- docs.nado.xyz
|
|
7
|
-
discovery:
|
|
8
|
-
include:
|
|
9
|
-
- https://docs.nado.xyz/**
|
|
10
|
-
exclude: []
|
|
11
|
-
maxPages: 500
|
|
12
|
-
extract:
|
|
13
|
-
strategy: clipboardButton
|
|
14
|
-
interactions:
|
|
15
|
-
- action: click
|
|
16
|
-
selector: button[aria-label="More"]
|
|
17
|
-
- action: click
|
|
18
|
-
selector: '[role="menuitem"]:has-text("Copy page")'
|
|
19
|
-
normalize:
|
|
20
|
-
prependSourceComment: true
|
|
21
|
-
schedule:
|
|
22
|
-
everyHours: 24
|
package/sources/synthetix.yaml
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
id: synthetix
|
|
2
|
-
label: Synthetix Docs
|
|
3
|
-
startUrls:
|
|
4
|
-
- https://developers.synthetix.io/
|
|
5
|
-
allowedHosts:
|
|
6
|
-
- developers.synthetix.io
|
|
7
|
-
discovery:
|
|
8
|
-
include:
|
|
9
|
-
- https://developers.synthetix.io/**
|
|
10
|
-
exclude: []
|
|
11
|
-
maxPages: 500
|
|
12
|
-
extract:
|
|
13
|
-
strategy: clipboardButton
|
|
14
|
-
interactions:
|
|
15
|
-
- action: hover
|
|
16
|
-
selector: .vocs_AiCtaDropdown
|
|
17
|
-
- action: click
|
|
18
|
-
selector: .vocs_AiCtaDropdown_buttonRight
|
|
19
|
-
- action: click
|
|
20
|
-
selector: '[role="menuitem"]:has-text("Copy")'
|
|
21
|
-
normalize:
|
|
22
|
-
prependSourceComment: true
|
|
23
|
-
schedule:
|
|
24
|
-
everyHours: 24
|