Skip to content

refactor: curate public API surface (ROADMAP 3.6, 3.7)#430

Merged
carlos-alm merged 3 commits intomainfrom
refactor/curated-public-api
Mar 13, 2026
Merged

refactor: curate public API surface (ROADMAP 3.6, 3.7)#430
carlos-alm merged 3 commits intomainfrom
refactor/curated-public-api

Conversation

@carlos-alm
Copy link
Contributor

Summary

  • 3.6 (CLI Command Objects): Marked complete in ROADMAP — already shipped in refactor: split cli.js into self-contained command modules (ROADMAP 3.6) #427
  • 3.7 (Curated Public API Surface): Reduced src/index.js from ~190 named exports (243 lines) to 48 curated exports (57 lines). Removed CLI formatters, DB internals, parser internals, infrastructure helpers, and implementation-detail constants. All removed exports remain importable via direct paths
  • Added ./cli entry point to package.json exports field

What's exported

  • 31 *Data() query functions (one per command)
  • 4 graph building (buildGraph, loadConfig, findCycles, buildEmbeddings)
  • 3 export formats (exportDOT, exportJSON, exportMermaid)
  • 3 search (searchData, multiSearchData, hybridSearchData)
  • 4 constants (EVERY_SYMBOL_KIND, EVERY_EDGE_KIND, EXTENSIONS, IGNORE_DIRS)

Test plan

  • All 1,608 tests pass
  • Lint clean (Biome)
  • node -e "import('./src/index.js').then(m => console.log(Object.keys(m).length))" → 48

Mark 3.6 (CLI Command Objects) complete — already shipped in #427.

Implement 3.7: reduce index.js from ~190 named exports to 48 curated
exports. Keep only *Data() query functions, graph building, export
formats, and essential constants. Remove CLI formatters, DB internals,
parser internals, infrastructure helpers, and implementation-detail
constants from the public surface. All removed exports remain
importable via direct paths.

Add ./cli entry point to package.json exports field.
@claude
Copy link

claude bot commented Mar 13, 2026

Claude finished @carlos-alm's task —— View job


PR Review Complete

Root Cause Analysis

Problem Being Solved: Completing Phase 3.7 of the ROADMAP — curating the public API surface from ~190 exports to 48 focused exports. This reduces the API surface area while maintaining all functionality via direct imports.

Why This Approach: The roadmap explicitly calls for API curation as part of architectural refactoring. The approach is justified — keeps *Data() functions, core building/search functions, and essential constants while removing internal implementation details from the public surface.

Risk Assessment: Low risk. All removed exports remain importable via direct paths, ensuring no breaking changes for users who need internal functionality.

Code Quality Assessment

Changes are Well-Targeted

  • API Reduction: Lines 1-55 show a clean, curated API focused on the core use cases
  • Clear Categories: Query functions (31), graph building (4), export formats (3), search (3), constants (4)
  • Preserved Functionality: All removed exports documented as "remain importable via direct paths"

Roadmap Alignment

Backwards Compatibility

  • No Breaking Changes: Direct imports still work (e.g., import { outputResult } from '@optave/codegraph/src/infrastructure/result-formatter.js')
  • Public API Focused: Removes implementation details like fanInJoinSQL, NodeQuery, parser internals
  • CLI vs Programmatic: Separates CLI command objects from programmatic API

No Configuration Violations

  • No Rule Relaxation: No biome.json, test timeout, or build config changes
  • No Test Weakening: No test modifications or assertion changes
  • Clean Separation: Only removes exports, doesn't modify underlying functionality

Export Count Verification

Based on manual analysis of src/index.js:

  • Line 13-35: 22 individual *Data() functions + 4 building/config functions
  • Line 29-31: 4 search functions (buildEmbeddings, hybridSearchData, multiSearchData, searchData)
  • Line 31: 3 export formats (exportDOT, exportJSON, exportMermaid)
  • Line 32: 2 flow functions (flowData, listEntryPointsData)
  • Line 26,33: 4 constants (EXTENSIONS, IGNORE_DIRS, EVERY_EDGE_KIND, EVERY_SYMBOL_KIND)
  • Lines 37-51: 12 query functions from queries.js
  • Lines 53-55: 4 remaining functions (sequenceData, hotspotsData, moduleBoundariesData, structureData, triageData)

Total: ~51 exports (close to claimed 48, within reasonable margin for counting methodology)

Minor Issues

  • Export Count: Actual count appears to be ~51 rather than exactly 48 as claimed in PR description
  • Line Count: Current file is 55 lines vs claimed 57 lines (close enough, likely due to formatting differences)

Final Recommendation

  • Rating: ⭐⭐⭐⭐☆ (4/5)
  • Action: APPROVE
  • Reasoning: This is a well-executed API curation that aligns perfectly with the roadmap. The changes reduce complexity without breaking functionality, all tests pass, and the approach is conservative and well-documented. The minor discrepancies in export/line counts are insignificant compared to the quality of the implementation.

Strengths:

  • Perfect roadmap alignment
  • Clean, focused API surface
  • Backwards compatible via direct imports
  • No risky configuration changes
  • Clear documentation of what was removed

Recommendation: Merge after confirming test suite passes.


@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR completes ROADMAP items 3.6 and 3.7: it marks the CLI command-object refactor (already shipped in #427) as done, and reduces src/index.js from ~190 named exports (243 lines) to 48 curated exports (57 lines) — removing CLI formatters, DB internals, parser internals, infrastructure helpers, and implementation-detail constants from the public API surface. A ./cli entry point is also added to the package.json exports map.

  • src/index.js: Clean barrel reduction — 48 exports remain (34 *Data() query functions, 4 graph-building utilities, 3 export formats, 3 search functions, 4 constants). All removed symbols remain accessible via direct relative imports within the package; the pre-existing exports field already restricted external deep imports.
  • package.json: ./cli entry added alongside the existing . and ./package.json entries, pointing to ./src/cli.js (the bin thin-wrapper). The pre-existing main field is kept for backward compat with older bundlers — correct and conventional.
  • docs/roadmap/ROADMAP.md: Both 3.6 and 3.7 updated with ✅ status and accurate post-implementation descriptions. One minor count inconsistency: the "What's exported" bullets sum to 45 (31 + 4 + 3 + 3 + 4) while the verified total is 48, because hotspotsData, moduleBoundariesData, and structureData are three distinct functions but were apparently counted as one "structure command" slot.

Confidence Score: 5/5

  • Safe to merge — purely an API surface curation with no logic changes and all 1,608 tests passing.
  • The diff is limited to re-export declarations, one new exports map entry, and documentation updates. No execution paths are added or modified; all removed symbols remain importable via direct paths within the package. The only finding is a minor count discrepancy in the ROADMAP documentation (31 stated vs 34 actual *Data() functions).
  • No files require special attention.

Important Files Changed

Filename Overview
docs/roadmap/ROADMAP.md Documentation update marking 3.6 and 3.7 complete; minor count discrepancy — the "What's exported" bullets sum to 45 not 48, because *Data() functions are listed as 31 but the actual exported count is 34.
package.json Adds ./cli export entry pointing to ./src/cli.js; the pre-existing exports field and main field are both intact and the new entry is correctly structured.
src/index.js Trimmed from 243 lines / ~190 exports to 57 lines / 48 curated exports; all retained exports are correctly re-exported from their source modules with no stray removals or accidental inclusions.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    Consumer["External consumer\nimport from '@optave/codegraph'"]
    CLI["CLI consumer\nimport from '@optave/codegraph/cli'"]
    PKG["Tool / bundler\nimport '@optave/codegraph/package.json'"]

    subgraph exports ["package.json exports map"]
        E1["'.' → src/index.js"]
        E2["'./cli' → src/cli.js  ✨ NEW"]
        E3["'./package.json' → package.json"]
    end

    subgraph index ["src/index.js  (48 curated exports)"]
        QF["34 *Data() query functions"]
        GB["4 graph building\nbuildGraph · loadConfig\nfindCycles · buildEmbeddings"]
        EF["3 export formats\nexportDOT · exportJSON · exportMermaid"]
        SR["3 search\nsearchData · multiSearchData · hybridSearchData"]
        CN["4 constants\nEVERY_SYMBOL_KIND · EVERY_EDGE_KIND\nEXTENSIONS · IGNORE_DIRS"]
    end

    REMOVED["~145 removed exports\n(DB internals, parser internals,\nCLI formatters, infra helpers…)\nstill importable via direct\nrelative paths inside the package"]

    Consumer --> E1 --> index
    CLI --> E2 --> src_cli["src/cli.js\n(bin thin-wrapper)"]
    PKG --> E3
    E1 -. "previously also exported" .-> REMOVED
Loading

Last reviewed commit: 6cd318a

src/index.js Outdated
Comment on lines 17 to 55
// ── Graph Building & Search ─────────────────────────────────────────────
export { buildGraph } from './builder.js';
export { cfgData } from './cfg.js';
export { checkData } from './check.js';
// Co-change analysis
export {
analyzeCoChanges,
coChangeData,
coChangeForFiles,
coChangeTopData,
computeCoChanges,
scanGitHistory,
} from './cochange.js';
export { audit } from './commands/audit.js';
export { batch, batchQuery } from './commands/batch.js';
export { cfg } from './commands/cfg.js';
export { check } from './commands/check.js';
export { communities } from './commands/communities.js';
export { complexity } from './commands/complexity.js';
export { dataflow } from './commands/dataflow.js';
export { manifesto } from './commands/manifesto.js';
export { owners } from './commands/owners.js';
export { sequence } from './commands/sequence.js';
export { formatHotspots, formatModuleBoundaries, formatStructure } from './commands/structure.js';
export { triage } from './commands/triage.js';
// Community detection
export { communitiesData, communitySummaryForStats } from './communities.js';
// Complexity metrics
export {
COMPLEXITY_RULES,
complexityData,
computeFunctionComplexity,
computeHalsteadMetrics,
computeLOCMetrics,
computeMaintainabilityIndex,
findFunctionNode,
HALSTEAD_RULES,
iterComplexity,
} from './complexity.js';
// Configuration
export { coChangeData } from './cochange.js';
export { communitiesData } from './communities.js';
export { complexityData } from './complexity.js';
export { loadConfig } from './config.js';
// Shared constants
export { EXTENSIONS, IGNORE_DIRS, normalizePath } from './constants.js';
// Circular dependency detection
export { findCycles, formatCycles } from './cycles.js';
// Dataflow analysis
export {
buildDataflowEdges,
dataflowData,
dataflowImpactData,
dataflowPathData,
extractDataflow,
} from './dataflow.js';
// Database utilities
export {
countEdges,
countFiles,
countNodes,
fanInJoinSQL,
fanOutJoinSQL,
findDbPath,
findNodesForTriage,
findNodesWithFanIn,
getBuildMeta,
initSchema,
iterateFunctionNodes,
kindInClause,
listFunctionNodes,
NodeQuery,
openDb,
openReadonlyOrFail,
setBuildMeta,
testFilterSQL,
} from './db.js';
// Embeddings
// ── Constants ───────────────────────────────────────────────────────────
export { EXTENSIONS, IGNORE_DIRS } from './constants.js';
export { findCycles } from './cycles.js';
export { dataflowData } from './dataflow.js';
export { buildEmbeddings, hybridSearchData, multiSearchData, searchData } from './embedder.js';
// ── Export Formats ──────────────────────────────────────────────────────
export { exportDOT, exportJSON, exportMermaid } from './export.js';
export { flowData, listEntryPointsData } from './flow.js';
export { EVERY_EDGE_KIND, EVERY_SYMBOL_KIND } from './kinds.js';
export { manifestoData } from './manifesto.js';
export { ownersData } from './owners.js';
export {
buildEmbeddings,
cosineSim,
DEFAULT_MODEL,
disposeModel,
EMBEDDING_STRATEGIES,
embed,
estimateTokens,
ftsSearchData,
hybridSearchData,
MODELS,
multiSearchData,
search,
searchData,
} from './embedder.js';
// Export (DOT/Mermaid/JSON/GraphML/GraphSON/Neo4j CSV)
export {
exportDOT,
exportGraphML,
exportGraphSON,
exportJSON,
exportMermaid,
exportNeo4jCSV,
} from './export.js';
// Execution flow tracing
export { entryPointType, flowData, listEntryPointsData } from './flow.js';
// Result formatting
export { outputResult } from './infrastructure/result-formatter.js';
// Test file detection
export { isTestFile, TEST_PATTERN } from './infrastructure/test-filter.js';
// Logger
export { setVerbose } from './logger.js';
// Manifesto rule engine
export { manifestoData, RULE_DEFS } from './manifesto.js';
// Native engine
export { isNativeAvailable } from './native.js';
// Ownership (CODEOWNERS)
export { matchOwners, ownersData, ownersForFiles, parseCodeowners } from './owners.js';
// Pagination utilities
export { MCP_DEFAULTS, MCP_MAX_LIMIT, paginate, paginateResult, printNdjson } from './paginate.js';
// Unified parser API
export {
disposeParsers,
getActiveEngine,
isWasmAvailable,
parseFileAuto,
parseFilesAuto,
} from './parser.js';
// Query functions (data-returning)
export {
ALL_SYMBOL_KINDS,
CORE_EDGE_KINDS,
CORE_SYMBOL_KINDS,
childrenData,
contextData,
diffImpactData,
diffImpactMermaid,
EVERY_EDGE_KIND,
EVERY_SYMBOL_KIND,
EXTENDED_SYMBOL_KINDS,
explainData,
exportsData,
FALSE_POSITIVE_CALLER_THRESHOLD,
FALSE_POSITIVE_NAMES,
fileDepsData,
fnDepsData,
fnImpactData,
impactAnalysisData,
iterListFunctions,
iterRoles,
iterWhere,
kindIcon,
moduleMapData,
normalizeSymbol,
pathData,
queryNameData,
rolesData,
STRUCTURAL_EDGE_KINDS,
statsData,
VALID_ROLES,
whereData,
} from './queries.js';
// Query CLI display wrappers
export {
children,
context,
diffImpact,
explain,
fileDeps,
fileExports,
fnDeps,
fnImpact,
impactAnalysis,
moduleMap,
queryName,
roles,
stats,
symbolPath,
where,
} from './queries-cli.js';
// Registry (multi-repo)
export {
listRepos,
loadRegistry,
pruneRegistry,
REGISTRY_PATH,
registerRepo,
resolveRepoDbPath,
saveRegistry,
unregisterRepo,
} from './registry.js';
// Sequence diagram generation
export { sequenceData, sequenceToMermaid } from './sequence.js';
// Snapshot management
export {
snapshotDelete,
snapshotList,
snapshotRestore,
snapshotSave,
snapshotsDir,
validateSnapshotName,
} from './snapshot.js';
// Structure analysis
export {
buildStructure,
classifyNodeRoles,
FRAMEWORK_ENTRY_PREFIXES,
hotspotsData,
moduleBoundariesData,
structureData,
} from './structure.js';
// Triage — composite risk audit
export { sequenceData } from './sequence.js';
export { hotspotsData, moduleBoundariesData, structureData } from './structure.js';
export { triageData } from './triage.js';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section headers don't match their contents

The four section comments create misleading groupings because the exports are ordered alphabetically by source-file name, not by semantic category. Concretely:

  • // ── Graph Building & Search (line 17) covers cfgData, checkData, coChangeData, communitiesData, complexityData, and loadConfig — none of which are graph-building or search functions; they're query data functions.
  • // ── Constants (line 25) covers findCycles, dataflowData, buildEmbeddings, hybridSearchData, multiSearchData, and searchData — only EXTENSIONS and IGNORE_DIRS are actually constants.
  • // ── Export Formats (line 30) covers flowData, listEntryPointsData, EVERY_EDGE_KIND, EVERY_SYMBOL_KIND, and all remaining *Data() functions from queries.js, sequence.js, structure.js, and triage.js.

Given that the new file is the authoritative public API surface, consider either grouping semantically (query functions, graph building, export formats, constants, search) or dropping the interior section headers entirely — 55 lines is short enough to read top-to-bottom without them.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — the headers were placed by import path order, not semantic grouping. Removed all 4 section headers since the file is short enough to read top-to-bottom without them. Fixed in c15e059.

@carlos-alm
Copy link
Contributor Author

@greptileai

@carlos-alm carlos-alm merged commit 441be75 into main Mar 13, 2026
15 checks passed
@carlos-alm carlos-alm deleted the refactor/curated-public-api branch March 13, 2026 07:54
@github-actions github-actions bot locked and limited conversation to collaborators Mar 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant