codesift-mcp 0.5.21 → 0.5.27
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/README.md +9 -9
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +28 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/hooks.d.ts +4 -0
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +15 -4
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/journal-commands.d.ts +9 -0
- package/dist/cli/journal-commands.d.ts.map +1 -0
- package/dist/cli/journal-commands.js +160 -0
- package/dist/cli/journal-commands.js.map +1 -0
- package/dist/cli/wiki-commands.d.ts.map +1 -1
- package/dist/cli/wiki-commands.js +5 -0
- package/dist/cli/wiki-commands.js.map +1 -1
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +41 -47
- package/dist/instructions.js.map +1 -1
- package/dist/parser/extractors/_shared.d.ts +2 -0
- package/dist/parser/extractors/_shared.d.ts.map +1 -1
- package/dist/parser/extractors/_shared.js +4 -0
- package/dist/parser/extractors/_shared.js.map +1 -1
- package/dist/parser/extractors/typescript.d.ts.map +1 -1
- package/dist/parser/extractors/typescript.js +606 -31
- package/dist/parser/extractors/typescript.js.map +1 -1
- package/dist/parser/parse-worker.d.ts +2 -0
- package/dist/parser/parse-worker.d.ts.map +1 -0
- package/dist/parser/parse-worker.js +47 -0
- package/dist/parser/parse-worker.js.map +1 -0
- package/dist/parser/parser-manager.d.ts +10 -1
- package/dist/parser/parser-manager.d.ts.map +1 -1
- package/dist/parser/parser-manager.js +40 -2
- package/dist/parser/parser-manager.js.map +1 -1
- package/dist/parser/parser-pool.d.ts +31 -0
- package/dist/parser/parser-pool.d.ts.map +1 -0
- package/dist/parser/parser-pool.js +211 -0
- package/dist/parser/parser-pool.js.map +1 -0
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +394 -35
- package/dist/register-tools.js.map +1 -1
- package/dist/retrieval/codebase-retrieval.d.ts.map +1 -1
- package/dist/retrieval/codebase-retrieval.js +9 -1
- package/dist/retrieval/codebase-retrieval.js.map +1 -1
- package/dist/search/chunker.d.ts +1 -0
- package/dist/search/chunker.d.ts.map +1 -1
- package/dist/search/chunker.js +8 -1
- package/dist/search/chunker.js.map +1 -1
- package/dist/server-helpers.d.ts +27 -0
- package/dist/server-helpers.d.ts.map +1 -1
- package/dist/server-helpers.js +90 -9
- package/dist/server-helpers.js.map +1 -1
- package/dist/server.js +31 -0
- package/dist/server.js.map +1 -1
- package/dist/storage/index-store.d.ts +41 -4
- package/dist/storage/index-store.d.ts.map +1 -1
- package/dist/storage/index-store.js +89 -6
- package/dist/storage/index-store.js.map +1 -1
- package/dist/storage/watcher.d.ts +33 -6
- package/dist/storage/watcher.d.ts.map +1 -1
- package/dist/storage/watcher.js +73 -34
- package/dist/storage/watcher.js.map +1 -1
- package/dist/storage/workspace-resolver.d.ts +15 -0
- package/dist/storage/workspace-resolver.d.ts.map +1 -0
- package/dist/storage/workspace-resolver.js +130 -0
- package/dist/storage/workspace-resolver.js.map +1 -0
- package/dist/tools/_helpers.d.ts +37 -0
- package/dist/tools/_helpers.d.ts.map +1 -0
- package/dist/tools/_helpers.js +31 -0
- package/dist/tools/_helpers.js.map +1 -0
- package/dist/tools/constant-resolution-tools.d.ts +8 -0
- package/dist/tools/constant-resolution-tools.d.ts.map +1 -0
- package/dist/tools/constant-resolution-tools.js +68 -0
- package/dist/tools/constant-resolution-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +27 -5
- package/dist/tools/graph-tools.d.ts.map +1 -1
- package/dist/tools/graph-tools.js +141 -18
- package/dist/tools/graph-tools.js.map +1 -1
- package/dist/tools/hotspot-tools.d.ts +6 -0
- package/dist/tools/hotspot-tools.d.ts.map +1 -1
- package/dist/tools/hotspot-tools.js +48 -8
- package/dist/tools/hotspot-tools.js.map +1 -1
- package/dist/tools/impact-tools.d.ts.map +1 -1
- package/dist/tools/impact-tools.js +9 -2
- package/dist/tools/impact-tools.js.map +1 -1
- package/dist/tools/index-tools.d.ts +15 -1
- package/dist/tools/index-tools.d.ts.map +1 -1
- package/dist/tools/index-tools.js +161 -16
- package/dist/tools/index-tools.js.map +1 -1
- package/dist/tools/journal-generator-helpers.d.ts +55 -0
- package/dist/tools/journal-generator-helpers.d.ts.map +1 -0
- package/dist/tools/journal-generator-helpers.js +250 -0
- package/dist/tools/journal-generator-helpers.js.map +1 -0
- package/dist/tools/journal-generator.d.ts +48 -0
- package/dist/tools/journal-generator.d.ts.map +1 -0
- package/dist/tools/journal-generator.js +204 -0
- package/dist/tools/journal-generator.js.map +1 -0
- package/dist/tools/journal-git-client.d.ts +20 -0
- package/dist/tools/journal-git-client.d.ts.map +1 -0
- package/dist/tools/journal-git-client.js +57 -0
- package/dist/tools/journal-git-client.js.map +1 -0
- package/dist/tools/journal-llm-client.d.ts +57 -0
- package/dist/tools/journal-llm-client.d.ts.map +1 -0
- package/dist/tools/journal-llm-client.js +175 -0
- package/dist/tools/journal-llm-client.js.map +1 -0
- package/dist/tools/journal-migrator.d.ts +22 -0
- package/dist/tools/journal-migrator.d.ts.map +1 -0
- package/dist/tools/journal-migrator.js +183 -0
- package/dist/tools/journal-migrator.js.map +1 -0
- package/dist/tools/journal-phase-detector.d.ts +26 -0
- package/dist/tools/journal-phase-detector.d.ts.map +1 -0
- package/dist/tools/journal-phase-detector.js +126 -0
- package/dist/tools/journal-phase-detector.js.map +1 -0
- package/dist/tools/journal-sentinel.d.ts +15 -0
- package/dist/tools/journal-sentinel.d.ts.map +1 -0
- package/dist/tools/journal-sentinel.js +110 -0
- package/dist/tools/journal-sentinel.js.map +1 -0
- package/dist/tools/journal-templates.d.ts +28 -0
- package/dist/tools/journal-templates.d.ts.map +1 -0
- package/dist/tools/journal-templates.js +93 -0
- package/dist/tools/journal-templates.js.map +1 -0
- package/dist/tools/pattern-tools.d.ts +2 -0
- package/dist/tools/pattern-tools.d.ts.map +1 -1
- package/dist/tools/pattern-tools.js +73 -0
- package/dist/tools/pattern-tools.js.map +1 -1
- package/dist/tools/perf-tools.d.ts.map +1 -1
- package/dist/tools/perf-tools.js +6 -0
- package/dist/tools/perf-tools.js.map +1 -1
- package/dist/tools/plan-turn-tools.d.ts.map +1 -1
- package/dist/tools/plan-turn-tools.js +38 -2
- package/dist/tools/plan-turn-tools.js.map +1 -1
- package/dist/tools/project-tools.d.ts +6 -0
- package/dist/tools/project-tools.d.ts.map +1 -1
- package/dist/tools/project-tools.js +65 -25
- package/dist/tools/project-tools.js.map +1 -1
- package/dist/tools/python-constants-tools.d.ts +6 -0
- package/dist/tools/python-constants-tools.d.ts.map +1 -1
- package/dist/tools/python-constants-tools.js.map +1 -1
- package/dist/tools/react-tools.d.ts +44 -1
- package/dist/tools/react-tools.d.ts.map +1 -1
- package/dist/tools/react-tools.js +142 -9
- package/dist/tools/react-tools.js.map +1 -1
- package/dist/tools/search-tools.d.ts.map +1 -1
- package/dist/tools/search-tools.js +21 -2
- package/dist/tools/search-tools.js.map +1 -1
- package/dist/tools/status-tools.d.ts +10 -0
- package/dist/tools/status-tools.d.ts.map +1 -1
- package/dist/tools/status-tools.js +53 -2
- package/dist/tools/status-tools.js.map +1 -1
- package/dist/tools/symbol-tools.d.ts +13 -0
- package/dist/tools/symbol-tools.d.ts.map +1 -1
- package/dist/tools/symbol-tools.js +38 -0
- package/dist/tools/symbol-tools.js.map +1 -1
- package/dist/tools/typescript-constants-tools.d.ts +6 -0
- package/dist/tools/typescript-constants-tools.d.ts.map +1 -0
- package/dist/tools/typescript-constants-tools.js +687 -0
- package/dist/tools/typescript-constants-tools.js.map +1 -0
- package/dist/tools/wiki-hub-ranker.d.ts +36 -0
- package/dist/tools/wiki-hub-ranker.d.ts.map +1 -0
- package/dist/tools/wiki-hub-ranker.js +72 -0
- package/dist/tools/wiki-hub-ranker.js.map +1 -0
- package/dist/tools/wiki-lint.d.ts +7 -2
- package/dist/tools/wiki-lint.d.ts.map +1 -1
- package/dist/tools/wiki-lint.js +73 -1
- package/dist/tools/wiki-lint.js.map +1 -1
- package/dist/tools/wiki-manifest.d.ts +129 -21
- package/dist/tools/wiki-manifest.d.ts.map +1 -1
- package/dist/tools/wiki-manifest.js +16 -9
- package/dist/tools/wiki-manifest.js.map +1 -1
- package/dist/tools/wiki-module-builder.d.ts +42 -0
- package/dist/tools/wiki-module-builder.d.ts.map +1 -0
- package/dist/tools/wiki-module-builder.js +449 -0
- package/dist/tools/wiki-module-builder.js.map +1 -0
- package/dist/tools/wiki-overview-sources.d.ts +26 -0
- package/dist/tools/wiki-overview-sources.d.ts.map +1 -0
- package/dist/tools/wiki-overview-sources.js +128 -0
- package/dist/tools/wiki-overview-sources.js.map +1 -0
- package/dist/tools/wiki-page-generators.d.ts +19 -3
- package/dist/tools/wiki-page-generators.d.ts.map +1 -1
- package/dist/tools/wiki-page-generators.js +156 -22
- package/dist/tools/wiki-page-generators.js.map +1 -1
- package/dist/tools/wiki-tools.d.ts +20 -0
- package/dist/tools/wiki-tools.d.ts.map +1 -1
- package/dist/tools/wiki-tools.js +181 -29
- package/dist/tools/wiki-tools.js.map +1 -1
- package/dist/tools/workspace-scope-helper.d.ts +21 -0
- package/dist/tools/workspace-scope-helper.d.ts.map +1 -0
- package/dist/tools/workspace-scope-helper.js +50 -0
- package/dist/tools/workspace-scope-helper.js.map +1 -0
- package/dist/tools/workspace-tools.d.ts +74 -0
- package/dist/tools/workspace-tools.d.ts.map +1 -0
- package/dist/tools/workspace-tools.js +366 -0
- package/dist/tools/workspace-tools.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/import-graph.d.ts +27 -0
- package/dist/utils/import-graph.d.ts.map +1 -1
- package/dist/utils/import-graph.js +331 -8
- package/dist/utils/import-graph.js.map +1 -1
- package/dist/utils/ts-imports.d.ts +30 -0
- package/dist/utils/ts-imports.d.ts.map +1 -0
- package/dist/utils/ts-imports.js +168 -0
- package/dist/utils/ts-imports.js.map +1 -0
- package/dist/utils/tsconfig-paths.d.ts +59 -0
- package/dist/utils/tsconfig-paths.d.ts.map +1 -0
- package/dist/utils/tsconfig-paths.js +176 -0
- package/dist/utils/tsconfig-paths.js.map +1 -0
- package/dist/utils/walk.d.ts.map +1 -1
- package/dist/utils/walk.js +1 -0
- package/dist/utils/walk.js.map +1 -1
- package/package.json +13 -3
- package/rules/codesift.md +19 -2
- package/rules/codesift.mdc +2 -2
- package/rules/codex.md +13 -2
- package/rules/gemini.md +13 -2
package/dist/register-tools.js
CHANGED
|
@@ -246,6 +246,71 @@ const FRAMEWORK_TOOL_GROUPS = {
|
|
|
246
246
|
"extract_kotlin_serialization_contract",
|
|
247
247
|
"trace_flow_chain",
|
|
248
248
|
],
|
|
249
|
+
// Python — detected by pyproject.toml (poetry/pdm/uv/hatch) or requirements.txt
|
|
250
|
+
"pyproject.toml": [
|
|
251
|
+
"get_model_graph",
|
|
252
|
+
"get_test_fixtures",
|
|
253
|
+
"find_framework_wiring",
|
|
254
|
+
"run_ruff",
|
|
255
|
+
"parse_pyproject",
|
|
256
|
+
"find_python_callers",
|
|
257
|
+
"analyze_django_settings",
|
|
258
|
+
"run_mypy",
|
|
259
|
+
"run_pyright",
|
|
260
|
+
"analyze_python_deps",
|
|
261
|
+
"trace_fastapi_depends",
|
|
262
|
+
"analyze_async_correctness",
|
|
263
|
+
"get_pydantic_models",
|
|
264
|
+
"python_audit",
|
|
265
|
+
],
|
|
266
|
+
"requirements.txt": [
|
|
267
|
+
"get_model_graph",
|
|
268
|
+
"get_test_fixtures",
|
|
269
|
+
"find_framework_wiring",
|
|
270
|
+
"run_ruff",
|
|
271
|
+
"find_python_callers",
|
|
272
|
+
"analyze_django_settings",
|
|
273
|
+
"run_mypy",
|
|
274
|
+
"run_pyright",
|
|
275
|
+
"analyze_python_deps",
|
|
276
|
+
"trace_fastapi_depends",
|
|
277
|
+
"analyze_async_correctness",
|
|
278
|
+
"get_pydantic_models",
|
|
279
|
+
"python_audit",
|
|
280
|
+
],
|
|
281
|
+
// TypeScript baseline — auto-enabled on any project with tsconfig.json.
|
|
282
|
+
// Promotes 3 high-value but historically dark tools so that vanilla TS /
|
|
283
|
+
// library / monorepo repos get a proper entry point beyond search_text.
|
|
284
|
+
"tsconfig.json": [
|
|
285
|
+
"dependency_audit",
|
|
286
|
+
"check_boundaries",
|
|
287
|
+
"architecture_summary",
|
|
288
|
+
],
|
|
289
|
+
// Monorepo signals — orchestration-level analysis is most useful when
|
|
290
|
+
// there are >1 packages. Each of these files alone is enough to fire.
|
|
291
|
+
"pnpm-workspace.yaml": [
|
|
292
|
+
"check_boundaries",
|
|
293
|
+
"architecture_summary",
|
|
294
|
+
],
|
|
295
|
+
"lerna.json": [
|
|
296
|
+
"check_boundaries",
|
|
297
|
+
"architecture_summary",
|
|
298
|
+
],
|
|
299
|
+
"nx.json": [
|
|
300
|
+
"check_boundaries",
|
|
301
|
+
"architecture_summary",
|
|
302
|
+
],
|
|
303
|
+
"turbo.json": [
|
|
304
|
+
"check_boundaries",
|
|
305
|
+
"architecture_summary",
|
|
306
|
+
],
|
|
307
|
+
// Prisma — root-level schema. Nested prisma/schema.prisma handled in
|
|
308
|
+
// detectAutoLoadTools after the loop. drizzle-kit dep handled in
|
|
309
|
+
// detectFromPackageJson.
|
|
310
|
+
"schema.prisma": [
|
|
311
|
+
"analyze_prisma_schema",
|
|
312
|
+
"migration_lint",
|
|
313
|
+
],
|
|
249
314
|
};
|
|
250
315
|
/**
|
|
251
316
|
* React-specific tools — auto-enabled when a React project is detected.
|
|
@@ -282,6 +347,22 @@ const HONO_TOOLS = [
|
|
|
282
347
|
"detect_hono_modules",
|
|
283
348
|
"find_dead_hono_routes",
|
|
284
349
|
];
|
|
350
|
+
/**
|
|
351
|
+
* Monorepo tools — auto-enabled when `pkg.workspaces` field is present
|
|
352
|
+
* (mirror of the file-based monorepo signals in FRAMEWORK_TOOL_GROUPS).
|
|
353
|
+
*/
|
|
354
|
+
const MONOREPO_TOOLS = [
|
|
355
|
+
"check_boundaries",
|
|
356
|
+
"architecture_summary",
|
|
357
|
+
];
|
|
358
|
+
/**
|
|
359
|
+
* Prisma tools — auto-enabled when `prisma` or `drizzle-kit` is in deps
|
|
360
|
+
* (mirror of the schema.prisma file signal in FRAMEWORK_TOOL_GROUPS).
|
|
361
|
+
*/
|
|
362
|
+
const PRISMA_TOOLS = [
|
|
363
|
+
"analyze_prisma_schema",
|
|
364
|
+
"migration_lint",
|
|
365
|
+
];
|
|
285
366
|
const AUTO_LOAD_CACHE_TTL_MS = 5_000;
|
|
286
367
|
const autoLoadToolsCache = new Map();
|
|
287
368
|
/**
|
|
@@ -290,6 +371,8 @@ const autoLoadToolsCache = new Map();
|
|
|
290
371
|
* Exported for unit testing.
|
|
291
372
|
*/
|
|
292
373
|
export async function detectAutoLoadTools(cwd) {
|
|
374
|
+
// Kill switch: spec D-FB. Skip workspace walk entirely when set.
|
|
375
|
+
const killSwitchOff = process.env.CODESIFT_DISABLE_MONOREPO !== "1";
|
|
293
376
|
const { existsSync, readFileSync, readdirSync } = await import("node:fs");
|
|
294
377
|
const { join } = await import("node:path");
|
|
295
378
|
const toEnable = [];
|
|
@@ -298,30 +381,79 @@ export async function detectAutoLoadTools(cwd) {
|
|
|
298
381
|
toEnable.push(...tools);
|
|
299
382
|
}
|
|
300
383
|
}
|
|
301
|
-
//
|
|
302
|
-
|
|
303
|
-
if (existsSync(
|
|
384
|
+
// Nested Prisma schema — `prisma/schema.prisma` is the more common layout
|
|
385
|
+
// than root-level. The root-level case is covered by FRAMEWORK_TOOL_GROUPS.
|
|
386
|
+
if (existsSync(join(cwd, "prisma", "schema.prisma"))) {
|
|
387
|
+
toEnable.push(...PRISMA_TOOLS);
|
|
388
|
+
}
|
|
389
|
+
const detectFromPackageJson = (pkgRoot) => {
|
|
390
|
+
const enabled = [];
|
|
391
|
+
const pkgPath = join(pkgRoot, "package.json");
|
|
392
|
+
if (!existsSync(pkgPath))
|
|
393
|
+
return enabled;
|
|
304
394
|
try {
|
|
305
395
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
306
396
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
397
|
+
const hasReact = !!(allDeps["react"] ||
|
|
398
|
+
allDeps["next"] ||
|
|
399
|
+
allDeps["@remix-run/react"] ||
|
|
400
|
+
allDeps["@xyflow/react"] ||
|
|
401
|
+
allDeps["preact"]);
|
|
402
|
+
if (hasReact && hasJsxFilesShallow(pkgRoot, readdirSync)) {
|
|
403
|
+
enabled.push(...REACT_TOOLS);
|
|
404
|
+
}
|
|
315
405
|
const hasHono = !!(allDeps["hono"] ||
|
|
316
406
|
allDeps["@hono/zod-openapi"] ||
|
|
317
407
|
allDeps["@hono/node-server"] ||
|
|
318
408
|
allDeps["hono-openapi"] ||
|
|
319
409
|
allDeps["chanfana"]);
|
|
320
|
-
if (hasHono)
|
|
321
|
-
|
|
410
|
+
if (hasHono)
|
|
411
|
+
enabled.push(...HONO_TOOLS);
|
|
412
|
+
// Prisma / Drizzle — schema-driven DB stacks. analyze_prisma_schema
|
|
413
|
+
// works for Prisma; migration_lint (squawk) works for any SQL migration
|
|
414
|
+
// dir, useful for both. We don't condition on @prisma/client because
|
|
415
|
+
// it's runtime-only — the schema work belongs to the `prisma` CLI dep.
|
|
416
|
+
const hasPrismaLike = !!(allDeps["prisma"] ||
|
|
417
|
+
allDeps["@prisma/client"] ||
|
|
418
|
+
allDeps["drizzle-kit"] ||
|
|
419
|
+
allDeps["drizzle-orm"]);
|
|
420
|
+
if (hasPrismaLike)
|
|
421
|
+
enabled.push(...PRISMA_TOOLS);
|
|
422
|
+
// npm/yarn/pnpm workspaces field — content-based monorepo signal.
|
|
423
|
+
// Complements the file-based signals (pnpm-workspace.yaml, lerna.json,
|
|
424
|
+
// nx.json, turbo.json) so plain `"workspaces": [...]` setups also fire.
|
|
425
|
+
const hasWorkspaces = Array.isArray(pkg.workspaces) ||
|
|
426
|
+
(pkg.workspaces && typeof pkg.workspaces === "object" &&
|
|
427
|
+
Array.isArray(pkg.workspaces.packages));
|
|
428
|
+
if (hasWorkspaces)
|
|
429
|
+
enabled.push(...MONOREPO_TOOLS);
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
/* malformed package.json */
|
|
433
|
+
}
|
|
434
|
+
return enabled;
|
|
435
|
+
};
|
|
436
|
+
// Root-level detection (existing behavior — unchanged for flat repos).
|
|
437
|
+
toEnable.push(...detectFromPackageJson(cwd));
|
|
438
|
+
// Monorepo workspace walk (Task 15). When monorepo detected at cwd, union
|
|
439
|
+
// each workspace's framework signals into the auto-load set. Hard cap at 50
|
|
440
|
+
// workspaces to bound startup cost (sync FS reads at module-init time);
|
|
441
|
+
// very large monorepos (>50 packages) fall back to root-only auto-load —
|
|
442
|
+
// discover_tools / describe_tools still work for any framework tool needed
|
|
443
|
+
// at query time.
|
|
444
|
+
if (killSwitchOff) {
|
|
445
|
+
try {
|
|
446
|
+
const { resolveWorkspaces } = await import("./storage/workspace-resolver.js");
|
|
447
|
+
const resolved = await resolveWorkspaces(cwd);
|
|
448
|
+
if (resolved && resolved.workspaces.length > 0 && resolved.workspaces.length <= 50) {
|
|
449
|
+
for (const ws of resolved.workspaces) {
|
|
450
|
+
toEnable.push(...detectFromPackageJson(ws.root));
|
|
451
|
+
}
|
|
322
452
|
}
|
|
323
453
|
}
|
|
324
|
-
catch {
|
|
454
|
+
catch {
|
|
455
|
+
/* monorepo resolver failure is non-fatal; flat-repo behavior preserved */
|
|
456
|
+
}
|
|
325
457
|
}
|
|
326
458
|
return toEnable;
|
|
327
459
|
}
|
|
@@ -487,6 +619,7 @@ export const CORE_TOOL_NAMES = new Set([
|
|
|
487
619
|
"discover_tools", // meta: discovers remaining hidden tools
|
|
488
620
|
"describe_tools", // meta: full schema for hidden tools
|
|
489
621
|
"plan_turn", // meta: route query to best tools/symbols/files
|
|
622
|
+
"initial_instructions", // meta: Serena-style onboarding tool, "must call first"
|
|
490
623
|
"get_session_snapshot", // session: compaction survival
|
|
491
624
|
"analyze_project", // project profile
|
|
492
625
|
"get_extractor_versions", // cache invalidation
|
|
@@ -526,11 +659,15 @@ const TOOL_DEFINITIONS = [
|
|
|
526
659
|
path: z.string().describe("Absolute path to the folder to index"),
|
|
527
660
|
incremental: zBool().describe("Only re-index changed files"),
|
|
528
661
|
include_paths: z.union([z.array(z.string()), z.string().transform((s) => JSON.parse(s))]).optional().describe("Glob patterns to include. Can be passed as JSON string."),
|
|
662
|
+
max_files: z.number().int().positive().optional().describe("Cap on files indexed. Default 50000 (or CODESIFT_MAX_FILES env). Walker stops at this count and returns partial results — protects against OOM on huge repos. Use include_paths to scope instead of raising this for large vendored trees."),
|
|
663
|
+
watch: zBool().describe("Whether to set up a chokidar file watcher for incremental updates after indexing. Default true. Pass false for bulk/CI indexing scenarios — file watchers consume system file descriptors (1+ per repo on macOS FSEvents); indexing many repos with watchers active can exhaust the system file table (ENFILE)."),
|
|
529
664
|
})),
|
|
530
665
|
handler: async (args) => {
|
|
531
666
|
const result = await indexFolder(args.path, {
|
|
532
667
|
incremental: args.incremental,
|
|
533
668
|
include_paths: args.include_paths,
|
|
669
|
+
max_files: args.max_files,
|
|
670
|
+
watch: args.watch,
|
|
534
671
|
});
|
|
535
672
|
// Auto-enable framework tools based on indexed path (not CWD)
|
|
536
673
|
try {
|
|
@@ -696,15 +833,40 @@ const TOOL_DEFINITIONS = [
|
|
|
696
833
|
auto_group: zBool().describe("Auto group_by_file when >50 matches."),
|
|
697
834
|
ranked: z.boolean().optional().describe("Classify hits by containing symbol and rank by centrality"),
|
|
698
835
|
})),
|
|
699
|
-
handler: (args) =>
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
836
|
+
handler: async (args) => {
|
|
837
|
+
const result = await searchText(args.repo, args.query, {
|
|
838
|
+
regex: args.regex,
|
|
839
|
+
context_lines: args.context_lines,
|
|
840
|
+
file_pattern: args.file_pattern,
|
|
841
|
+
max_results: args.max_results,
|
|
842
|
+
group_by_file: args.group_by_file,
|
|
843
|
+
auto_group: args.auto_group,
|
|
844
|
+
ranked: args.ranked,
|
|
845
|
+
});
|
|
846
|
+
// Zero-result hint: 41% of search_text calls return nothing in telemetry.
|
|
847
|
+
// Suggest the most likely fix based on query shape so the agent doesn't
|
|
848
|
+
// burn 2-3 follow-up turns guessing.
|
|
849
|
+
const isEmpty = (Array.isArray(result) && result.length === 0)
|
|
850
|
+
|| (typeof result === "string" && result.length === 0);
|
|
851
|
+
if (isEmpty) {
|
|
852
|
+
const q = args.query;
|
|
853
|
+
const fp = args.file_pattern;
|
|
854
|
+
const looksLikeSymbol = /::|->|\.[a-z][a-zA-Z0-9_]*\(/.test(q)
|
|
855
|
+
|| /^(class|function|def|fn|interface|type)\s+\w/.test(q)
|
|
856
|
+
|| (/^[A-Z][a-zA-Z0-9_]+$|^[a-z][a-zA-Z0-9_]+$/.test(q.trim()) && !q.includes(" "));
|
|
857
|
+
const hints = ["No matches."];
|
|
858
|
+
if (looksLikeSymbol)
|
|
859
|
+
hints.push("Query looks like a symbol — try search_symbols(query=...) instead.");
|
|
860
|
+
if (fp)
|
|
861
|
+
hints.push(`Try without file_pattern="${fp}" to widen scope.`);
|
|
862
|
+
if (args.regex === true)
|
|
863
|
+
hints.push("Try regex=false (literal) — escapes may be off.");
|
|
864
|
+
if (!fp && !looksLikeSymbol)
|
|
865
|
+
hints.push("Try a shorter substring, or add file_pattern= to scope.");
|
|
866
|
+
return { matches: [], hint: hints.join(" ") };
|
|
867
|
+
}
|
|
868
|
+
return result;
|
|
869
|
+
},
|
|
708
870
|
},
|
|
709
871
|
// --- Outline ---
|
|
710
872
|
{
|
|
@@ -792,10 +954,19 @@ const TOOL_DEFINITIONS = [
|
|
|
792
954
|
const opts = {};
|
|
793
955
|
if (args.include_related != null)
|
|
794
956
|
opts.include_related = args.include_related;
|
|
795
|
-
const
|
|
957
|
+
const symbolId = args.symbol_id;
|
|
958
|
+
const result = await getSymbol(args.repo, symbolId, opts);
|
|
796
959
|
if (!result) {
|
|
960
|
+
// Telemetry: 24% of get_symbol calls return null (hallucinated IDs).
|
|
961
|
+
// Suggest closest matches by name so the agent doesn't burn turns guessing.
|
|
962
|
+
const { findSimilarSymbols } = await import("./tools/symbol-tools.js");
|
|
963
|
+
const similar = await findSimilarSymbols(args.repo, symbolId, 3);
|
|
964
|
+
if (similar.length > 0) {
|
|
965
|
+
const suggestions = similar.map((s) => ` ${s.id} (${s.kind} ${s.name} @ ${s.file}:${s.start_line})`).join("\n");
|
|
966
|
+
return `Symbol "${symbolId}" not found. Did you mean:\n${suggestions}`;
|
|
967
|
+
}
|
|
797
968
|
const hint = await checkTextStubHint(args.repo, "get_symbol", true);
|
|
798
|
-
return hint ??
|
|
969
|
+
return hint ?? `Symbol "${symbolId}" not found. Use search_symbols(query=...) to discover available IDs.`;
|
|
799
970
|
}
|
|
800
971
|
let text = await formatSymbolCompact(result.symbol);
|
|
801
972
|
if (result.related && result.related.length > 0) {
|
|
@@ -817,10 +988,31 @@ const TOOL_DEFINITIONS = [
|
|
|
817
988
|
]).describe("Array of symbol identifiers. Can be passed as JSON string."),
|
|
818
989
|
})),
|
|
819
990
|
handler: async (args) => {
|
|
820
|
-
const
|
|
991
|
+
const ids = args.symbol_ids;
|
|
992
|
+
const syms = await getSymbols(args.repo, ids);
|
|
821
993
|
const output = await formatSymbolsCompact(syms);
|
|
994
|
+
// Surface fuzzy suggestions for missing IDs (telemetry: 26% zero rate).
|
|
995
|
+
let suggestions = "";
|
|
996
|
+
if (syms.length < ids.length) {
|
|
997
|
+
const foundIds = new Set(syms.map((s) => s.id));
|
|
998
|
+
const missing = ids.filter((id) => !foundIds.has(id));
|
|
999
|
+
if (missing.length > 0) {
|
|
1000
|
+
const { findSimilarSymbols } = await import("./tools/symbol-tools.js");
|
|
1001
|
+
const lines = [];
|
|
1002
|
+
for (const m of missing.slice(0, 5)) {
|
|
1003
|
+
const sims = await findSimilarSymbols(args.repo, m, 2);
|
|
1004
|
+
if (sims.length > 0) {
|
|
1005
|
+
lines.push(` ${m} → ${sims.map((s) => s.id).join(", ")}`);
|
|
1006
|
+
}
|
|
1007
|
+
else {
|
|
1008
|
+
lines.push(` ${m} → no similar symbols`);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
suggestions = `\n\n--- not found (${missing.length}) — suggestions ---\n${lines.join("\n")}`;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
822
1014
|
const hint = await checkTextStubHint(args.repo, "get_symbols", syms.length === 0);
|
|
823
|
-
return hint ? hint + output : output;
|
|
1015
|
+
return (hint ? hint + output : output) + suggestions;
|
|
824
1016
|
},
|
|
825
1017
|
},
|
|
826
1018
|
{
|
|
@@ -1583,6 +1775,9 @@ const TOOL_DEFINITIONS = [
|
|
|
1583
1775
|
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
1584
1776
|
focus: z.string().optional().describe("Scope to directory (e.g., 'src/tools')"),
|
|
1585
1777
|
output_dir: z.string().optional().describe("Output directory (default: {repo_root}/.codesift/wiki)"),
|
|
1778
|
+
journal_mode: z.enum(["skip", "refresh-overview", "append", "full"]).optional().default("skip").describe("Journal integration mode (default: skip)"),
|
|
1779
|
+
journal_since_ref: z.string().optional().describe("git-relative ref for journal_mode=append (e.g., '2 weeks ago' or ISO date)"),
|
|
1780
|
+
journal_bulk_fill: z.boolean().optional().describe("Bulk-fill all phases when journal_mode=full"),
|
|
1586
1781
|
})),
|
|
1587
1782
|
handler: async (args) => {
|
|
1588
1783
|
const opts = {};
|
|
@@ -1590,10 +1785,39 @@ const TOOL_DEFINITIONS = [
|
|
|
1590
1785
|
opts.focus = args.focus;
|
|
1591
1786
|
if (args.output_dir !== undefined)
|
|
1592
1787
|
opts.output_dir = args.output_dir;
|
|
1788
|
+
if (args.journal_mode !== undefined)
|
|
1789
|
+
opts.journal_mode = args.journal_mode;
|
|
1790
|
+
if (args.journal_since_ref !== undefined)
|
|
1791
|
+
opts.journal_since_ref = args.journal_since_ref;
|
|
1792
|
+
if (args.journal_bulk_fill !== undefined)
|
|
1793
|
+
opts.journal_bulk_fill = args.journal_bulk_fill;
|
|
1593
1794
|
const result = await generateWiki(args.repo, opts);
|
|
1594
1795
|
return JSON.stringify(result, null, 2);
|
|
1595
1796
|
},
|
|
1596
1797
|
},
|
|
1798
|
+
{
|
|
1799
|
+
name: "journal_append",
|
|
1800
|
+
category: "reporting",
|
|
1801
|
+
searchHint: "journal append phases git commits since wiki journal",
|
|
1802
|
+
description: "Append new journal phases for commits since the given git ref. Dispatches to runJournalAppend.",
|
|
1803
|
+
schema: lazySchema(() => ({
|
|
1804
|
+
since: z.string().describe("git-relative string like '2 weeks ago' or ISO date"),
|
|
1805
|
+
max_cost_usd: z.number().optional().default(2.0).describe("Maximum LLM cost cap in USD (default: 2.0)"),
|
|
1806
|
+
dry_run: z.boolean().optional().default(false).describe("Plan phases without writing files (default: false)"),
|
|
1807
|
+
})),
|
|
1808
|
+
handler: async (args) => {
|
|
1809
|
+
const { runJournalAppend } = await import("./tools/journal-generator.js");
|
|
1810
|
+
const opts = {
|
|
1811
|
+
cwd: process.cwd(),
|
|
1812
|
+
outputDir: ".codesift/wiki",
|
|
1813
|
+
since: args.since,
|
|
1814
|
+
};
|
|
1815
|
+
if (args.dry_run !== undefined)
|
|
1816
|
+
opts.dryRun = args.dry_run;
|
|
1817
|
+
const r = await runJournalAppend(opts);
|
|
1818
|
+
return JSON.stringify(r, null, 2);
|
|
1819
|
+
},
|
|
1820
|
+
},
|
|
1597
1821
|
// --- Conversations ---
|
|
1598
1822
|
{
|
|
1599
1823
|
name: "index_conversations",
|
|
@@ -1650,6 +1874,85 @@ const TOOL_DEFINITIONS = [
|
|
|
1650
1874
|
return formatConversations(result);
|
|
1651
1875
|
},
|
|
1652
1876
|
},
|
|
1877
|
+
// --- Monorepo Workspaces (Tasks 8-11 of monorepo workspace intelligence plan) ---
|
|
1878
|
+
{
|
|
1879
|
+
name: "list_workspaces",
|
|
1880
|
+
category: "analysis",
|
|
1881
|
+
searchHint: "monorepo workspace list packages turbo pnpm yarn npm",
|
|
1882
|
+
description: "List workspace packages for a JS/TS monorepo (Turbo / pnpm / yarn / npm / Nx). Returns shape-stable empty result on flat repos.",
|
|
1883
|
+
schema: lazySchema(() => ({
|
|
1884
|
+
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
1885
|
+
})),
|
|
1886
|
+
handler: async (args) => {
|
|
1887
|
+
const { listWorkspacesHandler } = await import("./tools/workspace-tools.js");
|
|
1888
|
+
return listWorkspacesHandler(args.repo ? { repo: args.repo } : {});
|
|
1889
|
+
},
|
|
1890
|
+
},
|
|
1891
|
+
{
|
|
1892
|
+
name: "workspace_graph",
|
|
1893
|
+
category: "analysis",
|
|
1894
|
+
searchHint: "monorepo workspace dependency graph turbo nx mermaid dot",
|
|
1895
|
+
description: "Build the workspace-to-workspace dependency DAG of a monorepo. Output formats: json (default), mermaid, dot.",
|
|
1896
|
+
schema: lazySchema(() => ({
|
|
1897
|
+
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
1898
|
+
format: z.enum(["json", "mermaid", "dot"]).optional().describe("Output format (default: json)"),
|
|
1899
|
+
})),
|
|
1900
|
+
handler: async (args) => {
|
|
1901
|
+
const { workspaceGraphHandler } = await import("./tools/workspace-tools.js");
|
|
1902
|
+
const opts = {};
|
|
1903
|
+
if (args.repo)
|
|
1904
|
+
opts.repo = args.repo;
|
|
1905
|
+
if (args.format)
|
|
1906
|
+
opts.format = args.format;
|
|
1907
|
+
return workspaceGraphHandler(opts);
|
|
1908
|
+
},
|
|
1909
|
+
},
|
|
1910
|
+
{
|
|
1911
|
+
name: "affected_workspaces",
|
|
1912
|
+
category: "analysis",
|
|
1913
|
+
searchHint: "monorepo affected workspaces git diff impact transitive turbo nx",
|
|
1914
|
+
description: "Compute affected workspaces for a git diff. File changes -> containing workspace -> reverse-dep walk. Lockfile-only commits surface separately and never fan out.",
|
|
1915
|
+
schema: lazySchema(() => ({
|
|
1916
|
+
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
1917
|
+
since: z.string().describe("Git ref to diff against (e.g. HEAD~1, main, <sha>)"),
|
|
1918
|
+
include_transitive: zBool().describe("Include transitive reverse-deps (default: true)"),
|
|
1919
|
+
})),
|
|
1920
|
+
handler: async (args) => {
|
|
1921
|
+
const { affectedWorkspacesHandler } = await import("./tools/workspace-tools.js");
|
|
1922
|
+
const opts = {
|
|
1923
|
+
since: args.since,
|
|
1924
|
+
};
|
|
1925
|
+
if (args.repo)
|
|
1926
|
+
opts.repo = args.repo;
|
|
1927
|
+
if (args.include_transitive !== undefined)
|
|
1928
|
+
opts.include_transitive = args.include_transitive;
|
|
1929
|
+
return affectedWorkspacesHandler(opts);
|
|
1930
|
+
},
|
|
1931
|
+
},
|
|
1932
|
+
{
|
|
1933
|
+
name: "workspace_boundaries",
|
|
1934
|
+
category: "analysis",
|
|
1935
|
+
searchHint: "monorepo boundary rules workspace import violations enforce",
|
|
1936
|
+
description: "Enforce workspace-level import boundaries. Walks ALL cross-workspace import edges (relative + bare/tsconfig-alias) and reports rule violations.",
|
|
1937
|
+
schema: lazySchema(() => ({
|
|
1938
|
+
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
1939
|
+
rules: z
|
|
1940
|
+
.array(z.object({
|
|
1941
|
+
from_workspace: z.string().describe("Workspace name OR glob (e.g. 'apps/*')"),
|
|
1942
|
+
cannot_import_workspaces: z.array(z.string()).describe("Names, globs, or negation entries"),
|
|
1943
|
+
}))
|
|
1944
|
+
.describe("Workspace boundary rules"),
|
|
1945
|
+
})),
|
|
1946
|
+
handler: async (args) => {
|
|
1947
|
+
const { workspaceBoundariesHandler } = await import("./tools/workspace-tools.js");
|
|
1948
|
+
const opts = {
|
|
1949
|
+
rules: args.rules,
|
|
1950
|
+
};
|
|
1951
|
+
if (args.repo)
|
|
1952
|
+
opts.repo = args.repo;
|
|
1953
|
+
return workspaceBoundariesHandler(opts);
|
|
1954
|
+
},
|
|
1955
|
+
},
|
|
1653
1956
|
// --- Security ---
|
|
1654
1957
|
{
|
|
1655
1958
|
name: "scan_secrets",
|
|
@@ -2581,6 +2884,16 @@ const TOOL_DEFINITIONS = [
|
|
|
2581
2884
|
handler: async (args) => {
|
|
2582
2885
|
const result = await indexStatus(args.repo);
|
|
2583
2886
|
if (!result.indexed) {
|
|
2887
|
+
// Stale: index file exists but extractor_version drifted. Distinct
|
|
2888
|
+
// from "never indexed" — agents seeing "STALE" know that re-running
|
|
2889
|
+
// index_folder will fix it without wondering whether earlier indexing
|
|
2890
|
+
// attempts silently failed.
|
|
2891
|
+
if (result.stale) {
|
|
2892
|
+
return (`index_status: STALE — extractor_version_mismatch ` +
|
|
2893
|
+
`(${result.stale.language}: indexed at ${result.stale.actual_version}, ` +
|
|
2894
|
+
`current ${result.stale.expected_version}). ` +
|
|
2895
|
+
`Run index_folder to refresh.`);
|
|
2896
|
+
}
|
|
2584
2897
|
// If no repo specified, list available repos so the agent can pick one
|
|
2585
2898
|
if (!args.repo) {
|
|
2586
2899
|
const { listAllRepos } = await import("./tools/index-tools.js");
|
|
@@ -2752,15 +3065,28 @@ const TOOL_DEFINITIONS = [
|
|
|
2752
3065
|
{
|
|
2753
3066
|
name: "nest_audit",
|
|
2754
3067
|
category: "nestjs",
|
|
2755
|
-
searchHint: "nestjs audit analysis comprehensive module di guard route lifecycle pattern graphql websocket schedule typeorm microservice hook onModuleInit onApplicationBootstrap shutdown dependency graph circular import boundary injection provider constructor inject cycle interceptor pipe filter middleware chain security endpoint api map inventory list all params resolver query mutation subscription apollo gateway subscribemessage socketio realtime event cron interval timeout scheduled job task onevent listener entity relation onetomany manytoone database schema messagepattern eventpattern kafka rabbitmq nats transport request pipeline handler execution flow visualization bull bullmq queue processor process background worker scope transient singleton performance escalation swagger openapi documentation apiproperty apioperation apiresponse contract extract",
|
|
2756
|
-
description: "One-call NestJS architecture audit: modules, DI, guards, routes, lifecycle, patterns, GraphQL, WebSocket, schedule, TypeORM, microservices.",
|
|
3068
|
+
searchHint: "nestjs audit analysis comprehensive module di guard route lifecycle pattern graphql websocket schedule typeorm microservice hook onModuleInit onApplicationBootstrap shutdown dependency graph circular import boundary injection provider constructor inject cycle interceptor pipe filter middleware chain security endpoint api map inventory list all params resolver query mutation subscription apollo gateway subscribemessage socketio realtime event cron interval timeout scheduled job task onevent listener entity relation onetomany manytoone database schema messagepattern eventpattern kafka rabbitmq nats transport request pipeline handler execution flow visualization bull bullmq queue processor process background worker scope transient singleton performance escalation swagger openapi documentation apiproperty apioperation apiresponse contract extract workspace monorepo",
|
|
3069
|
+
description: "One-call NestJS architecture audit: modules, DI, guards, routes, lifecycle, patterns, GraphQL, WebSocket, schedule, TypeORM, microservices. Pass workspace=<name|path> in monorepos to scope to a single workspace.",
|
|
2757
3070
|
schema: lazySchema(() => ({
|
|
2758
3071
|
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
3072
|
+
workspace: z.string().optional().describe("Monorepo workspace name or path. Scopes the audit to that workspace's files."),
|
|
2759
3073
|
checks: z.string().optional().describe("Comma-separated checks (default: all). Options: modules,routes,di,guards,lifecycle,patterns,graphql,websocket,schedule,typeorm,microservice"),
|
|
2760
3074
|
})),
|
|
2761
3075
|
handler: async (args) => {
|
|
3076
|
+
const { resolveWorkspaceScope } = await import("./tools/workspace-scope-helper.js");
|
|
2762
3077
|
const checks = args.checks?.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2763
|
-
|
|
3078
|
+
const scope = await resolveWorkspaceScope(args.repo ?? "", args.workspace, "nestjs");
|
|
3079
|
+
if ("error" in scope) {
|
|
3080
|
+
return { error: scope.error, input: scope.input, available: scope.available };
|
|
3081
|
+
}
|
|
3082
|
+
const opts = {};
|
|
3083
|
+
if (checks)
|
|
3084
|
+
opts.checks = checks;
|
|
3085
|
+
if (scope.rootPaths.length > 0) {
|
|
3086
|
+
// Pass first matched workspace path through the existing file_pattern-style hook
|
|
3087
|
+
opts.file_pattern = `${scope.rootPaths[0]}/**`;
|
|
3088
|
+
}
|
|
3089
|
+
return nestAudit(args.repo ?? "", opts);
|
|
2764
3090
|
},
|
|
2765
3091
|
},
|
|
2766
3092
|
// --- Agent config audit ---
|
|
@@ -3099,18 +3425,27 @@ const TOOL_DEFINITIONS = [
|
|
|
3099
3425
|
{
|
|
3100
3426
|
name: "astro_audit",
|
|
3101
3427
|
category: "analysis",
|
|
3102
|
-
searchHint: "astro meta audit full health check score gates recommendations islands hydration routes config actions content migration patterns",
|
|
3103
|
-
description: "One-call Astro project health check: runs all 7 Astro tools + 13 Astro patterns in parallel, returns unified {score, gates, sections, recommendations}.
|
|
3428
|
+
searchHint: "astro meta audit full health check score gates recommendations islands hydration routes config actions content migration patterns workspace monorepo",
|
|
3429
|
+
description: "One-call Astro project health check: runs all 7 Astro tools + 13 Astro patterns in parallel, returns unified {score, gates, sections, recommendations}. Pass workspace=<name|path> in monorepos to scope to a single workspace.",
|
|
3104
3430
|
schema: lazySchema(() => ({
|
|
3105
3431
|
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
3432
|
+
workspace: z.string().optional().describe("Monorepo workspace name or path. Scopes the audit to that workspace."),
|
|
3106
3433
|
skip: z.array(z.string()).optional().describe("Sections to skip: config, hydration, routes, actions, content, migration, patterns"),
|
|
3107
3434
|
})),
|
|
3108
3435
|
handler: async (args) => {
|
|
3436
|
+
const { resolveWorkspaceScope } = await import("./tools/workspace-scope-helper.js");
|
|
3437
|
+
const scope = await resolveWorkspaceScope(args.repo ?? "", args.workspace, "astro");
|
|
3438
|
+
if ("error" in scope) {
|
|
3439
|
+
return { error: scope.error, input: scope.input, available: scope.available };
|
|
3440
|
+
}
|
|
3109
3441
|
const opts = {};
|
|
3110
3442
|
if (args.repo != null)
|
|
3111
3443
|
opts.repo = args.repo;
|
|
3112
3444
|
if (args.skip != null)
|
|
3113
3445
|
opts.skip = args.skip;
|
|
3446
|
+
if (scope.rootPaths.length > 0) {
|
|
3447
|
+
opts.file_pattern = `${scope.rootPaths[0]}/**`;
|
|
3448
|
+
}
|
|
3114
3449
|
return await astroAudit(opts);
|
|
3115
3450
|
},
|
|
3116
3451
|
},
|
|
@@ -3140,16 +3475,29 @@ const TOOL_DEFINITIONS = [
|
|
|
3140
3475
|
{
|
|
3141
3476
|
name: "analyze_hono_app",
|
|
3142
3477
|
category: "analysis",
|
|
3143
|
-
searchHint: "hono overview analyze app routes middleware runtime env bindings rpc",
|
|
3144
|
-
description: "Complete Hono application overview: routes grouped by method/scope, middleware map, context vars, OpenAPI status, RPC exports (flags Issue #3869 slow pattern), runtime, env bindings.
|
|
3478
|
+
searchHint: "hono overview analyze app routes middleware runtime env bindings rpc workspace monorepo",
|
|
3479
|
+
description: "Complete Hono application overview: routes grouped by method/scope, middleware map, context vars, OpenAPI status, RPC exports (flags Issue #3869 slow pattern), runtime, env bindings. Pass workspace=<name|path> in monorepos to scope to a single workspace.",
|
|
3145
3480
|
schema: lazySchema(() => ({
|
|
3146
3481
|
repo: z.string().optional().describe("Repository identifier (default: auto-detected from CWD)"),
|
|
3147
3482
|
entry_file: z.string().optional().describe("Hono entry file (auto-detected if omitted)"),
|
|
3483
|
+
workspace: z.string().optional().describe("Monorepo workspace name or path (e.g. '@org/api' or 'apps/api'). Scopes Hono entry resolution to that workspace."),
|
|
3148
3484
|
force_refresh: z.boolean().optional().describe("Clear cache and rebuild"),
|
|
3149
3485
|
})),
|
|
3150
3486
|
handler: async (args) => {
|
|
3151
3487
|
const { analyzeHonoApp } = await import("./tools/hono-analyze-app.js");
|
|
3152
|
-
|
|
3488
|
+
const { resolveWorkspaceScope } = await import("./tools/workspace-scope-helper.js");
|
|
3489
|
+
const repo = args.repo;
|
|
3490
|
+
const scope = await resolveWorkspaceScope(repo, args.workspace, "hono");
|
|
3491
|
+
if ("error" in scope) {
|
|
3492
|
+
return { error: scope.error, input: scope.input, available: scope.available };
|
|
3493
|
+
}
|
|
3494
|
+
// If workspace scoping resolved to a path, prefer it as entry_file root hint.
|
|
3495
|
+
let entry = args.entry_file;
|
|
3496
|
+
if (!entry && scope.rootPaths.length === 1) {
|
|
3497
|
+
// Hono's entry resolver searches src/index.ts under the path provided
|
|
3498
|
+
entry = scope.rootPaths[0];
|
|
3499
|
+
}
|
|
3500
|
+
return await analyzeHonoApp(repo, entry, args.force_refresh);
|
|
3153
3501
|
},
|
|
3154
3502
|
},
|
|
3155
3503
|
{
|
|
@@ -3596,6 +3944,17 @@ const TOOL_DEFINITIONS = [
|
|
|
3596
3944
|
},
|
|
3597
3945
|
},
|
|
3598
3946
|
// --- Discovery / concierge ---
|
|
3947
|
+
{
|
|
3948
|
+
name: "initial_instructions",
|
|
3949
|
+
category: "meta",
|
|
3950
|
+
searchHint: "initial instructions onboarding setup start session",
|
|
3951
|
+
description: "IMPORTANT: Call this tool IMMEDIATELY after the user gives you a task, BEFORE any other tool calls. Returns CodeSift's full instruction manual which critically informs how to use the 146 code intelligence tools. Skipping this tool causes the agent to miss CodeSift's pre-built BM25 + semantic index and waste tokens on Grep/Read instead.",
|
|
3952
|
+
schema: lazySchema(() => ({})),
|
|
3953
|
+
handler: async () => {
|
|
3954
|
+
const { CODESIFT_INSTRUCTIONS } = await import("./instructions.js");
|
|
3955
|
+
return CODESIFT_INSTRUCTIONS;
|
|
3956
|
+
},
|
|
3957
|
+
},
|
|
3599
3958
|
{
|
|
3600
3959
|
name: "plan_turn",
|
|
3601
3960
|
category: "discovery",
|