@shirlytaylor73/smart-search 0.2.0-beta.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 +21 -0
- package/README.md +188 -0
- package/README.zh-CN.md +180 -0
- package/npm/bin/smart-search.js +68 -0
- package/npm/scripts/postinstall.js +87 -0
- package/npm/scripts/resolve-prerelease-version.js +108 -0
- package/npm/scripts/set-package-version.js +35 -0
- package/npm/scripts/sync-python-version.js +22 -0
- package/npm/scripts/test-wrapper-repair.js +137 -0
- package/npm/scripts/test.js +76 -0
- package/package.json +42 -0
- package/pyproject.toml +36 -0
- package/skills/smart-search-cli/SKILL.md +41 -0
- package/skills/smart-search-cli/agents/openai.yaml +3 -0
- package/skills/smart-search-cli/references/cli-contract.md +7 -0
- package/skills/smart-search-cli/references/cli-core.md +5 -0
- package/skills/smart-search-cli/references/command-patterns.md +12 -0
- package/skills/smart-search-cli/references/provider-routing.md +3 -0
- package/skills/smart-search-cli/references/regression-release.md +28 -0
- package/skills/smart-search-cli/references/setup-config.md +3 -0
- package/src/smart_search/__init__.py +1 -0
- package/src/smart_search/assets/skills/smart-search-cli/SKILL.md +41 -0
- package/src/smart_search/assets/skills/smart-search-cli/agents/openai.yaml +3 -0
- package/src/smart_search/assets/skills/smart-search-cli/references/cli-contract.md +7 -0
- package/src/smart_search/assets/skills/smart-search-cli/references/cli-core.md +5 -0
- package/src/smart_search/assets/skills/smart-search-cli/references/command-patterns.md +12 -0
- package/src/smart_search/assets/skills/smart-search-cli/references/provider-routing.md +3 -0
- package/src/smart_search/assets/skills/smart-search-cli/references/regression-release.md +28 -0
- package/src/smart_search/assets/skills/smart-search-cli/references/setup-config.md +3 -0
- package/src/smart_search/cli.py +3118 -0
- package/src/smart_search/config.py +809 -0
- package/src/smart_search/embedding_presets.py +40 -0
- package/src/smart_search/intent_router.py +757 -0
- package/src/smart_search/logger.py +43 -0
- package/src/smart_search/providers/__init__.py +20 -0
- package/src/smart_search/providers/base.py +41 -0
- package/src/smart_search/providers/context7.py +141 -0
- package/src/smart_search/providers/exa.py +206 -0
- package/src/smart_search/providers/jina.py +136 -0
- package/src/smart_search/providers/openai_compatible.py +541 -0
- package/src/smart_search/providers/xai_responses.py +117 -0
- package/src/smart_search/providers/zhipu.py +143 -0
- package/src/smart_search/providers/zhipu_mcp.py +230 -0
- package/src/smart_search/service.py +3445 -0
- package/src/smart_search/skill_installer.py +342 -0
- package/src/smart_search/sources.py +429 -0
- package/src/smart_search/utils.py +220 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const fs = require("node:fs");
|
|
2
|
+
const path = require("node:path");
|
|
3
|
+
|
|
4
|
+
const packageRoot = path.resolve(__dirname, "..", "..");
|
|
5
|
+
const packageJson = JSON.parse(
|
|
6
|
+
fs.readFileSync(path.join(packageRoot, "package.json"), "utf8")
|
|
7
|
+
);
|
|
8
|
+
const pyprojectPath = path.join(packageRoot, "pyproject.toml");
|
|
9
|
+
const pyproject = fs.readFileSync(pyprojectPath, "utf8");
|
|
10
|
+
const versionPattern = /^version = ".*"$/m;
|
|
11
|
+
|
|
12
|
+
if (!versionPattern.test(pyproject)) {
|
|
13
|
+
console.error("Could not find the project.version field in pyproject.toml.");
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const updated = pyproject.replace(versionPattern, `version = "${packageJson.version}"`);
|
|
18
|
+
if (updated !== pyproject) {
|
|
19
|
+
fs.writeFileSync(pyprojectPath, updated);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log(`Synced pyproject.toml to ${packageJson.version}.`);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const assert = require("node:assert");
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const vm = require("node:vm");
|
|
5
|
+
|
|
6
|
+
const wrapperPath = path.resolve(__dirname, "..", "bin", "smart-search.js");
|
|
7
|
+
const wrapperSource = fs.readFileSync(wrapperPath, "utf8");
|
|
8
|
+
|
|
9
|
+
function runWrapper({ runtimeExists, repairStatus = 0, repairCreatesRuntime = true }) {
|
|
10
|
+
let repairedRuntimeExists = runtimeExists;
|
|
11
|
+
const spawnSyncCalls = [];
|
|
12
|
+
const spawnCalls = [];
|
|
13
|
+
const exits = [];
|
|
14
|
+
const stderr = [];
|
|
15
|
+
|
|
16
|
+
const fakeFs = {
|
|
17
|
+
existsSync(filePath) {
|
|
18
|
+
const normalized = filePath.replaceAll("\\", "/");
|
|
19
|
+
if (
|
|
20
|
+
normalized.endsWith("/.smart-search-python/Scripts/python.exe") ||
|
|
21
|
+
normalized.endsWith("/.smart-search-python/bin/python")
|
|
22
|
+
) {
|
|
23
|
+
return repairedRuntimeExists;
|
|
24
|
+
}
|
|
25
|
+
return fs.existsSync(filePath);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const fakeProcess = {
|
|
30
|
+
...process,
|
|
31
|
+
argv: ["node", wrapperPath, "--version"],
|
|
32
|
+
env: {},
|
|
33
|
+
cwd: () => "C:\\caller",
|
|
34
|
+
exit(code) {
|
|
35
|
+
exits.push(code);
|
|
36
|
+
throw new Error(`process.exit(${code})`);
|
|
37
|
+
},
|
|
38
|
+
kill() {}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const fakeChildProcess = {
|
|
42
|
+
spawnSync(command, args, options) {
|
|
43
|
+
spawnSyncCalls.push({ command, args, options });
|
|
44
|
+
if (repairStatus instanceof Error) {
|
|
45
|
+
return { error: repairStatus };
|
|
46
|
+
}
|
|
47
|
+
if (repairCreatesRuntime) {
|
|
48
|
+
repairedRuntimeExists = true;
|
|
49
|
+
}
|
|
50
|
+
return { status: repairStatus };
|
|
51
|
+
},
|
|
52
|
+
spawn(command, args, options) {
|
|
53
|
+
spawnCalls.push({ command, args, options });
|
|
54
|
+
return {
|
|
55
|
+
on() {
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const context = {
|
|
63
|
+
__dirname: path.dirname(wrapperPath),
|
|
64
|
+
console: { error(message = "") { stderr.push(String(message)); }, log() {} },
|
|
65
|
+
process: fakeProcess,
|
|
66
|
+
require(moduleName) {
|
|
67
|
+
if (moduleName === "node:child_process") {
|
|
68
|
+
return fakeChildProcess;
|
|
69
|
+
}
|
|
70
|
+
if (moduleName === "node:fs") {
|
|
71
|
+
return fakeFs;
|
|
72
|
+
}
|
|
73
|
+
if (moduleName === "node:path") {
|
|
74
|
+
return path;
|
|
75
|
+
}
|
|
76
|
+
return require(moduleName);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
vm.runInNewContext(wrapperSource, context, { filename: wrapperPath });
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (!String(error.message).startsWith("process.exit(")) {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { spawnSyncCalls, spawnCalls, exits, stderr };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const healthy = runWrapper({ runtimeExists: true });
|
|
92
|
+
assert.strictEqual(healthy.spawnSyncCalls.length, 0);
|
|
93
|
+
assert.strictEqual(healthy.spawnCalls.length, 1);
|
|
94
|
+
|
|
95
|
+
const repaired = runWrapper({ runtimeExists: false });
|
|
96
|
+
assert.strictEqual(repaired.spawnSyncCalls.length, 1);
|
|
97
|
+
assert(
|
|
98
|
+
repaired.spawnSyncCalls[0].args[0].replaceAll("\\", "/").endsWith("/npm/scripts/postinstall.js"),
|
|
99
|
+
"missing runtime should invoke package postinstall repair"
|
|
100
|
+
);
|
|
101
|
+
assert.strictEqual(repaired.spawnCalls.length, 1);
|
|
102
|
+
assert.deepStrictEqual(Array.from(repaired.spawnCalls[0].args.slice(0, 2)), ["-m", "smart_search.cli"]);
|
|
103
|
+
assert.strictEqual(repaired.exits.length, 0);
|
|
104
|
+
|
|
105
|
+
const failedRepair = runWrapper({
|
|
106
|
+
runtimeExists: false,
|
|
107
|
+
repairStatus: 1,
|
|
108
|
+
repairCreatesRuntime: false
|
|
109
|
+
});
|
|
110
|
+
assert.strictEqual(failedRepair.spawnSyncCalls.length, 1);
|
|
111
|
+
assert.strictEqual(failedRepair.spawnCalls.length, 0);
|
|
112
|
+
assert.deepStrictEqual(failedRepair.exits, [1]);
|
|
113
|
+
assert(
|
|
114
|
+
failedRepair.stderr.includes(" npm install -g @shirlytaylor73/smart-search"),
|
|
115
|
+
"failed repair should recommend reinstalling the stable package"
|
|
116
|
+
);
|
|
117
|
+
assert(
|
|
118
|
+
!failedRepair.stderr.some((message) => message.includes("@next")),
|
|
119
|
+
"failed repair should not recommend the next release tag"
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const repairSpawnError = runWrapper({
|
|
123
|
+
runtimeExists: false,
|
|
124
|
+
repairStatus: new Error("postinstall unavailable"),
|
|
125
|
+
repairCreatesRuntime: false
|
|
126
|
+
});
|
|
127
|
+
assert.strictEqual(repairSpawnError.spawnSyncCalls.length, 1);
|
|
128
|
+
assert.strictEqual(repairSpawnError.spawnCalls.length, 0);
|
|
129
|
+
assert.deepStrictEqual(repairSpawnError.exits, [5]);
|
|
130
|
+
assert(
|
|
131
|
+
repairSpawnError.stderr.includes(" npm install -g @shirlytaylor73/smart-search"),
|
|
132
|
+
"repair spawn errors should recommend reinstalling the stable package"
|
|
133
|
+
);
|
|
134
|
+
assert(
|
|
135
|
+
!repairSpawnError.stderr.some((message) => message.includes("@next")),
|
|
136
|
+
"repair spawn errors should not recommend the next release tag"
|
|
137
|
+
);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const { spawnSync } = require("node:child_process");
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
|
|
5
|
+
const packageRoot = path.resolve(__dirname, "..", "..");
|
|
6
|
+
const venvDir = path.join(packageRoot, ".smart-search-python");
|
|
7
|
+
const pythonPath =
|
|
8
|
+
process.platform === "win32"
|
|
9
|
+
? path.join(venvDir, "Scripts", "python.exe")
|
|
10
|
+
: path.join(venvDir, "bin", "python");
|
|
11
|
+
|
|
12
|
+
function run(command, args, options = {}) {
|
|
13
|
+
const result = spawnSync(command, args, {
|
|
14
|
+
cwd: packageRoot,
|
|
15
|
+
stdio: "inherit",
|
|
16
|
+
shell: options.shell || false,
|
|
17
|
+
windowsHide: true
|
|
18
|
+
});
|
|
19
|
+
if (result.error) {
|
|
20
|
+
console.error(result.error.message);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (result.status !== 0) {
|
|
24
|
+
process.exit(result.status || 1);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function capture(command, args) {
|
|
29
|
+
const result = spawnSync(command, args, {
|
|
30
|
+
cwd: packageRoot,
|
|
31
|
+
encoding: "utf8",
|
|
32
|
+
windowsHide: true
|
|
33
|
+
});
|
|
34
|
+
if (result.error) {
|
|
35
|
+
console.error(result.error.message);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
if (result.status !== 0) {
|
|
39
|
+
process.stdout.write(result.stdout || "");
|
|
40
|
+
process.stderr.write(result.stderr || "");
|
|
41
|
+
process.exit(result.status || 1);
|
|
42
|
+
}
|
|
43
|
+
return result.stdout || "";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function runNpm(args) {
|
|
47
|
+
if (process.env.npm_execpath) {
|
|
48
|
+
run(process.execPath, [process.env.npm_execpath, ...args]);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
run("npm", args, { shell: process.platform === "win32" });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!fs.existsSync(pythonPath)) {
|
|
55
|
+
console.error("Missing .smart-search-python runtime. Run npm install first.");
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
run(pythonPath, ["-m", "pip", "install", "--disable-pip-version-check", "-e", ".[dev]"]);
|
|
60
|
+
run(pythonPath, ["-m", "pytest"]);
|
|
61
|
+
run(process.execPath, ["npm/scripts/test-wrapper-repair.js"]);
|
|
62
|
+
run(process.execPath, ["npm/bin/smart-search.js", "--help"]);
|
|
63
|
+
const routeJson = capture(process.execPath, [
|
|
64
|
+
"npm/bin/smart-search.js",
|
|
65
|
+
"diagnose",
|
|
66
|
+
"route",
|
|
67
|
+
"深度搜索一下最近的比特币行情",
|
|
68
|
+
"--format",
|
|
69
|
+
"json"
|
|
70
|
+
]);
|
|
71
|
+
const routeResult = JSON.parse(routeJson);
|
|
72
|
+
if (routeResult.query !== "深度搜索一下最近的比特币行情") {
|
|
73
|
+
console.error("npm wrapper must preserve non-ASCII CLI arguments and JSON output as UTF-8.");
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
runNpm(["pack", "--dry-run"]);
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shirlytaylor73/smart-search",
|
|
3
|
+
"version": "0.2.0-beta.1",
|
|
4
|
+
"description": "CLI-first provider-independent web and documentation retrieval for AI agents.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://github.com/ShirlyTaylor73/smartsearch#readme",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ShirlyTaylor73/smartsearch.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/ShirlyTaylor73/smartsearch/issues"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"smart-search": "npm/bin/smart-search.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"npm/",
|
|
19
|
+
"skills/smart-search-cli/**",
|
|
20
|
+
"src/smart_search/**/*.py",
|
|
21
|
+
"src/smart_search/assets/skills/smart-search-cli/**",
|
|
22
|
+
"pyproject.toml",
|
|
23
|
+
"README.md",
|
|
24
|
+
"README.zh-CN.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"postinstall": "node npm/scripts/postinstall.js",
|
|
29
|
+
"test": "node npm/scripts/test.js",
|
|
30
|
+
"set-version": "node npm/scripts/set-package-version.js",
|
|
31
|
+
"sync:python-version": "node npm/scripts/sync-python-version.js",
|
|
32
|
+
"version": "node npm/scripts/sync-python-version.js && git add pyproject.toml package.json package-lock.json",
|
|
33
|
+
"pack:dry": "npm pack --dry-run",
|
|
34
|
+
"publish:dry": "npm publish --dry-run --access public"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/pyproject.toml
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "smart-search"
|
|
7
|
+
version = "0.2.0-beta.1"
|
|
8
|
+
description = "CLI-first provider-independent web and documentation retrieval for AI agents."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"httpx[socks]>=0.28.0",
|
|
13
|
+
"InquirerPy>=0.3.4,<0.4",
|
|
14
|
+
"pyfiglet>=1.0,<2",
|
|
15
|
+
"rich>=13.9,<16",
|
|
16
|
+
"tenacity>=8.0.0",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
dev = [
|
|
21
|
+
"pytest>=8.0.0",
|
|
22
|
+
"pytest-asyncio>=0.23.0",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[tool.setuptools.packages.find]
|
|
26
|
+
where = ["src"]
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.package-data]
|
|
29
|
+
smart_search = [
|
|
30
|
+
"assets/skills/smart-search-cli/SKILL.md",
|
|
31
|
+
"assets/skills/smart-search-cli/agents/*.yaml",
|
|
32
|
+
"assets/skills/smart-search-cli/references/*.md",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
smart-search = "smart_search.cli:main"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: smart-search-cli
|
|
3
|
+
description: "CLI-first web and documentation retrieval through four provider-independent capability namespaces."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Smart Search CLI
|
|
7
|
+
|
|
8
|
+
Use the local `smart-search` command. Choose an operation by task intent; never choose or manage providers.
|
|
9
|
+
|
|
10
|
+
## Query operations
|
|
11
|
+
|
|
12
|
+
- `smart-search search answer QUERY --format json`: generate a web-backed answer.
|
|
13
|
+
- `smart-search search sources QUERY --limit 5 --format json`: retrieve source-first web results.
|
|
14
|
+
- `smart-search search similar URL --limit 5 --format json`: find similar pages.
|
|
15
|
+
- `smart-search docs resolve NAME [QUERY] --format json`: resolve a library/documentation source.
|
|
16
|
+
- `smart-search docs search QUERY [--source SOURCE] --format json`: search technical docs or repository knowledge.
|
|
17
|
+
- `smart-search docs tree REPO [--path PATH] [--ref REF] --format json`: inspect repository structure.
|
|
18
|
+
- `smart-search docs read REPO PATH [--ref REF] --format content`: read a repository file.
|
|
19
|
+
- `smart-search fetch content URL --format content`: retrieve readable page/PDF content.
|
|
20
|
+
- `smart-search fetch extract URL --format json`: retrieve structured data or raw evidence.
|
|
21
|
+
- `smart-search map site URL --limit 50 --format json`: discover URLs and link structure within a site.
|
|
22
|
+
|
|
23
|
+
## Selection rules
|
|
24
|
+
|
|
25
|
+
- Use `search answer` for a direct current-web answer.
|
|
26
|
+
- Use `search sources` when the agent needs candidate URLs or filtering.
|
|
27
|
+
- Use `docs` for libraries, APIs, SDKs, repositories, directory trees, and files.
|
|
28
|
+
- Use `fetch content` after a URL is known and readable evidence is required.
|
|
29
|
+
- Use `fetch extract` only when structured fields/evidence are required.
|
|
30
|
+
- Use `map site` only for site URL discovery; it is not page extraction or repository structure.
|
|
31
|
+
|
|
32
|
+
Provider selection, credentials, ordering, feature matching, timeout, and fallback are configuration concerns and MUST NOT be managed by the agent.
|
|
33
|
+
|
|
34
|
+
## Output and errors
|
|
35
|
+
|
|
36
|
+
- Default to `--format json` for results and `--format content` for long readable bodies.
|
|
37
|
+
- Treat `config_error` as a maintainer configuration issue.
|
|
38
|
+
- Treat `capability_error` as an unsupported operation/feature combination; do not retry with provider-specific commands.
|
|
39
|
+
- Use `doctor` or `diagnose` only when the user explicitly asks for troubleshooting.
|
|
40
|
+
|
|
41
|
+
The calling agent owns research orchestration; future paper/vertical retrieval is handled separately.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# CLI Contract
|
|
2
|
+
|
|
3
|
+
Public query namespaces are `search`, `docs`, `fetch`, and `map`.
|
|
4
|
+
|
|
5
|
+
Operations: `search answer|sources|similar`, `docs resolve|search|tree|read`, `fetch content|extract`, and `map site`.
|
|
6
|
+
|
|
7
|
+
All operations return `ok`, `capability`, `operation`, `content`, `sources`, and `elapsed_ms`; failures add `error_type` and `error`. Provider details are debug-only.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# CLI Core
|
|
2
|
+
|
|
3
|
+
Use operation names to express task intent. Do not select providers or fallback paths. Use JSON for structured results and content format for long bodies.
|
|
4
|
+
|
|
5
|
+
Research planning, decomposition, evidence comparison, and final writing belong to the calling agent.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Command Patterns
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
smart-search search answer "QUESTION" --format json
|
|
5
|
+
smart-search search sources "QUERY" --limit 5 --format json
|
|
6
|
+
smart-search docs search "QUERY" --source owner/repo --format json
|
|
7
|
+
smart-search docs tree owner/repo --path src --format json
|
|
8
|
+
smart-search docs read owner/repo README.md --format content
|
|
9
|
+
smart-search fetch content URL --format content
|
|
10
|
+
smart-search fetch extract URL --format json
|
|
11
|
+
smart-search map site URL --limit 50 --format json
|
|
12
|
+
```
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Operation Routing
|
|
2
|
+
|
|
3
|
+
Provider ordering, supported features, timeouts, credentials, and fallback are configured internally per operation. Fallback never crosses operation boundaries: tree is not search, structured extract is not readable content, and site map is not repository structure.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Regression and Release
|
|
2
|
+
|
|
3
|
+
Maintainers run `smart-search dev regression`, relevant pytest suites,
|
|
4
|
+
`npm test`, and verify that the public and packaged skill directories are
|
|
5
|
+
byte-identical before release.
|
|
6
|
+
|
|
7
|
+
## Release Lanes
|
|
8
|
+
|
|
9
|
+
- The fork-owned package is `@shirlytaylor73/smart-search`.
|
|
10
|
+
- Beta releases are started manually with `workflow_dispatch`, an exact
|
|
11
|
+
`0.2.0-beta.N` version, and npm dist-tag `next`.
|
|
12
|
+
- Stable `v0.2.0` and later `vX.Y.Z` Git tags publish npm dist-tag
|
|
13
|
+
`latest`.
|
|
14
|
+
- GitHub Actions authenticates with the repository secret `NPM_TOKEN` and
|
|
15
|
+
publishes with npm provenance.
|
|
16
|
+
- Stable release notes live at `.github/releases/vX.Y.Z.md`.
|
|
17
|
+
- npm versions are immutable; published versions cannot be renamed in place.
|
|
18
|
+
|
|
19
|
+
## Release Verification
|
|
20
|
+
|
|
21
|
+
- Confirm package metadata and tags with
|
|
22
|
+
`npm view @shirlytaylor73/smart-search --json`.
|
|
23
|
+
- Install the exact beta or stable package and run
|
|
24
|
+
`smart-search --version`, `smart-search dev regression`, and
|
|
25
|
+
`smart-search diagnose smoke --mode mock --format json`.
|
|
26
|
+
- Verify the Windows npm/mise wrapper emits UTF-8 JSON with a non-ASCII query
|
|
27
|
+
piped through `ConvertFrom-Json`.
|
|
28
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__all__ = []
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: smart-search-cli
|
|
3
|
+
description: "CLI-first web and documentation retrieval through four provider-independent capability namespaces."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Smart Search CLI
|
|
7
|
+
|
|
8
|
+
Use the local `smart-search` command. Choose an operation by task intent; never choose or manage providers.
|
|
9
|
+
|
|
10
|
+
## Query operations
|
|
11
|
+
|
|
12
|
+
- `smart-search search answer QUERY --format json`: generate a web-backed answer.
|
|
13
|
+
- `smart-search search sources QUERY --limit 5 --format json`: retrieve source-first web results.
|
|
14
|
+
- `smart-search search similar URL --limit 5 --format json`: find similar pages.
|
|
15
|
+
- `smart-search docs resolve NAME [QUERY] --format json`: resolve a library/documentation source.
|
|
16
|
+
- `smart-search docs search QUERY [--source SOURCE] --format json`: search technical docs or repository knowledge.
|
|
17
|
+
- `smart-search docs tree REPO [--path PATH] [--ref REF] --format json`: inspect repository structure.
|
|
18
|
+
- `smart-search docs read REPO PATH [--ref REF] --format content`: read a repository file.
|
|
19
|
+
- `smart-search fetch content URL --format content`: retrieve readable page/PDF content.
|
|
20
|
+
- `smart-search fetch extract URL --format json`: retrieve structured data or raw evidence.
|
|
21
|
+
- `smart-search map site URL --limit 50 --format json`: discover URLs and link structure within a site.
|
|
22
|
+
|
|
23
|
+
## Selection rules
|
|
24
|
+
|
|
25
|
+
- Use `search answer` for a direct current-web answer.
|
|
26
|
+
- Use `search sources` when the agent needs candidate URLs or filtering.
|
|
27
|
+
- Use `docs` for libraries, APIs, SDKs, repositories, directory trees, and files.
|
|
28
|
+
- Use `fetch content` after a URL is known and readable evidence is required.
|
|
29
|
+
- Use `fetch extract` only when structured fields/evidence are required.
|
|
30
|
+
- Use `map site` only for site URL discovery; it is not page extraction or repository structure.
|
|
31
|
+
|
|
32
|
+
Provider selection, credentials, ordering, feature matching, timeout, and fallback are configuration concerns and MUST NOT be managed by the agent.
|
|
33
|
+
|
|
34
|
+
## Output and errors
|
|
35
|
+
|
|
36
|
+
- Default to `--format json` for results and `--format content` for long readable bodies.
|
|
37
|
+
- Treat `config_error` as a maintainer configuration issue.
|
|
38
|
+
- Treat `capability_error` as an unsupported operation/feature combination; do not retry with provider-specific commands.
|
|
39
|
+
- Use `doctor` or `diagnose` only when the user explicitly asks for troubleshooting.
|
|
40
|
+
|
|
41
|
+
The calling agent owns research orchestration; future paper/vertical retrieval is handled separately.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# CLI Contract
|
|
2
|
+
|
|
3
|
+
Public query namespaces are `search`, `docs`, `fetch`, and `map`.
|
|
4
|
+
|
|
5
|
+
Operations: `search answer|sources|similar`, `docs resolve|search|tree|read`, `fetch content|extract`, and `map site`.
|
|
6
|
+
|
|
7
|
+
All operations return `ok`, `capability`, `operation`, `content`, `sources`, and `elapsed_ms`; failures add `error_type` and `error`. Provider details are debug-only.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# CLI Core
|
|
2
|
+
|
|
3
|
+
Use operation names to express task intent. Do not select providers or fallback paths. Use JSON for structured results and content format for long bodies.
|
|
4
|
+
|
|
5
|
+
Research planning, decomposition, evidence comparison, and final writing belong to the calling agent.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Command Patterns
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
smart-search search answer "QUESTION" --format json
|
|
5
|
+
smart-search search sources "QUERY" --limit 5 --format json
|
|
6
|
+
smart-search docs search "QUERY" --source owner/repo --format json
|
|
7
|
+
smart-search docs tree owner/repo --path src --format json
|
|
8
|
+
smart-search docs read owner/repo README.md --format content
|
|
9
|
+
smart-search fetch content URL --format content
|
|
10
|
+
smart-search fetch extract URL --format json
|
|
11
|
+
smart-search map site URL --limit 50 --format json
|
|
12
|
+
```
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Operation Routing
|
|
2
|
+
|
|
3
|
+
Provider ordering, supported features, timeouts, credentials, and fallback are configured internally per operation. Fallback never crosses operation boundaries: tree is not search, structured extract is not readable content, and site map is not repository structure.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Regression and Release
|
|
2
|
+
|
|
3
|
+
Maintainers run `smart-search dev regression`, relevant pytest suites,
|
|
4
|
+
`npm test`, and verify that the public and packaged skill directories are
|
|
5
|
+
byte-identical before release.
|
|
6
|
+
|
|
7
|
+
## Release Lanes
|
|
8
|
+
|
|
9
|
+
- The fork-owned package is `@shirlytaylor73/smart-search`.
|
|
10
|
+
- Beta releases are started manually with `workflow_dispatch`, an exact
|
|
11
|
+
`0.2.0-beta.N` version, and npm dist-tag `next`.
|
|
12
|
+
- Stable `v0.2.0` and later `vX.Y.Z` Git tags publish npm dist-tag
|
|
13
|
+
`latest`.
|
|
14
|
+
- GitHub Actions authenticates with the repository secret `NPM_TOKEN` and
|
|
15
|
+
publishes with npm provenance.
|
|
16
|
+
- Stable release notes live at `.github/releases/vX.Y.Z.md`.
|
|
17
|
+
- npm versions are immutable; published versions cannot be renamed in place.
|
|
18
|
+
|
|
19
|
+
## Release Verification
|
|
20
|
+
|
|
21
|
+
- Confirm package metadata and tags with
|
|
22
|
+
`npm view @shirlytaylor73/smart-search --json`.
|
|
23
|
+
- Install the exact beta or stable package and run
|
|
24
|
+
`smart-search --version`, `smart-search dev regression`, and
|
|
25
|
+
`smart-search diagnose smoke --mode mock --format json`.
|
|
26
|
+
- Verify the Windows npm/mise wrapper emits UTF-8 JSON with a non-ASCII query
|
|
27
|
+
piped through `ConvertFrom-Json`.
|
|
28
|
+
|