Skip to content

v0.8.8

Choose a tag to compare

@github-actions github-actions released this 08 May 17:19
· 8 commits to main since this release

[0.8.8] - 2026-05-08

Added

  • bundleWorkspace() (src/workspace/bundle.ts) — single-call workspace bundle that fans out across describeWorkspace, analyzeWorkspace, inspectWorkspaceDocumentSet, previewCodebaseSize, buildCodebaseIndexIsolated, and chunkDocument, returning a versioned WorkspaceBundle (schemaVersion: 1) with description, analysis, documents, codePreview, codeIndex (slim by default), documentChunks, a hierarchical outline (root → projects → top modules → documents → sections), per-symbol codeDocumentReferences (regex symbol matches in markdown content), and a unified errors array. Configurable via includeDescription/includeAnalysis/includeDocuments/includeCode/includeDocumentChunks/includeCodeDocumentReferences/maxDocumentFiles/maxReferenceFiles/maxCodeFiles/maxCodeBytes/maxDocumentChunks/maxCodeDocumentReferences/slimCodeIndex/contentMode and the existing ignore/overlay knobs. Exposed as createOcc().workspace.bundle and on the @cesarandreslopez/occ/workspace/bundle subpath
  • chunkDocument() (src/doc/chunk.ts) — heading-aware, token-budgeted document chunker. Converts DOCX/PDF/PPTX/XLSX/ODT/ODS/ODP/MD/MDX/TXT/RST/AsciiDoc to markdown, splits along the heading tree from extractFromMarkdown, and packs each section into chunks under maxTokens (default 800) with configurable overlapTokens (default 80) and an injectable countTokens. Each DocumentChunk carries chunkId, anchor slug, headingPath, startLine/endLine, tokenEstimate, and wordCount. Exposed as createOcc().doc.chunk and on the @cesarandreslopez/occ/doc/chunk subpath
  • summarizeModule() and toMermaid() (src/code/query.ts) — summarizeModule(index, modulePath, { maxClasses, maxFunctions, maxEdges }) returns a ModuleSummary (coupling + key classes + key functions ranked by call activity + import edges + exported API). toMermaid(index, kind, target, { maxNodes, maxEdges }) renders Mermaid diagrams for 'import-graph', 'class-hierarchy', and 'call-graph'. Both methods are also exposed on CodeQuerySession and re-exported from @cesarandreslopez/occ. analyzeModuleCoupling now treats '.' / '' as "the whole repository" and additionally matches by relativePath exact equality and moduleName, fixing single-file modules and root-module queries
  • tsconfig.json / jsconfig.json compilerOptions.paths resolution for TS/JS/Vue imports (src/code/languages.ts:resolveTsconfigImport) — wildcard and exact patterns, baseUrl honored, results cached per repo. Imports with ? / # query/fragment suffixes are stripped before resolution (Vite-style ?raw, ?url, ?worker). Asset specifiers (.css, .scss, .svg, .png, .wasm, ...) are now classified as external rather than unresolved, removing a long tail of false unresolved import edges from frontend repos
  • Symbol position metadata on parsed symbols and graph nodes — ParsedSymbol/CodeNode now carry optional endLine, startColumn, endColumn (TS compiler API powered for TS/JS/Vue). Useful for IDE-style navigation and slicing source ranges out of content: 'full' indexes
  • NormalizedSymbolKind union ('file' | 'module' | 'function' | 'method' | 'class' | 'interface' | 'type' | 'enum' | 'variable' | 'parameter' | 'other') and toNormalizedSymbolKind(type, containerName) helper — folds function with a container into method, type-alias into type, etc., for downstream consumers that want LSP-style symbol kinds without re-implementing the mapping. Exported from the facade
  • Builtin call-noise filter (src/code/build.ts:isBuiltinNoiseCall) — drops false-positive calls edges to standard-library globals (Array, JSON, Promise, console, setTimeout, fetch, ...) and ubiquitous member methods (map, filter, then, push, forEach, ...) when no local symbol shadows them. Calls qualified by this/self/cls/super are preserved. Significantly reduces graph noise in TS/JS repos
  • health() (src/health.ts) — lightweight liveness probe returning { available, version, capabilities }. Exposed as createOcc().health and on the @cesarandreslopez/occ/health subpath
  • OccAbortError / OCC_ABORTED / isOccAbortError (src/errors.ts) — typed abort error replacing the previous DOMException('...', 'AbortError') usage in abortIfNeeded, buildCodebaseIndexIsolated, and prepareWorkspaceContext. The new error keeps name: 'AbortError' for duck-typed compatibility, but adds error.code === 'OCC_ABORTED' and survives instanceof across forked subprocesses (where DOMException does not). Exposed on the @cesarandreslopez/occ/errors subpath
  • Document discovery now includes prose formats by default — discoverDocumentSet() / discoverDocuments() accept md, markdown, mdx, txt, rst, adoc, asciidoc alongside the seven office formats, and the new includeDataFiles: true flag also pulls in yaml, yml, json, jsonc, toml. documentToMarkdown() reads these raw text formats directly. inspectWorkspaceDocumentSet and bundleWorkspace forward the flag, so workspaces with markdown-only docs are no longer empty
  • New discoverDocumentSet() API alongside discoverDocuments() — same signature, but returns { documents, skipped } where skipped carries { path, reason, size } entries for over-size files (including the actual byte count) and EACCES/other I/O failures (previously silently dropped)
  • tryParseSlimIndex(value) — non-throwing variant of parseSlimIndex returning CodebaseIndexSlim | undefined, for IPC and persistence boundaries where validation is best-effort. Exported from the facade and @cesarandreslopez/occ/code/slim
  • CodeIndexStore.update(changedFiles?, options?) — explicit refresh hook (currently equivalent to refresh(), takes a changedFiles argument for forward compatibility). Letting consumers signal incremental change without re-deriving freshness from manifests
  • ProgressPhase gains 'bundle', 'description', 'stats', 'code-preview', 'document-chunk', and 'outline' for the new workspace bundle pipeline. ProgressEvent gains optional scope, currentPath, bytesProcessed, totalBytes, startedAt, and elapsedMs fields so progress consumers can render rich UIs without needing a sidecar event stream. inspectWorkspaceDocumentSet and the workspace pipeline now emit currentPath on every event
  • sanitizeForkExecArgv() (src/utils.ts) and integration in buildCodebaseIndexIsolated and prepareWorkspaceContext — strips --input-type from process.execArgv before forking the JS runners, so OCC works under loaders like tsx / node --import tsx that set --input-type=module on the parent (which previously crashed the child runner with Module did not self-register)
  • Programmatic subpath exports (with matching typesVersions): @cesarandreslopez/occ/doc/chunk, @cesarandreslopez/occ/workspace/bundle, @cesarandreslopez/occ/table/types, @cesarandreslopez/occ/health, @cesarandreslopez/occ/errors

Changed

  • src/errors.ts is a new Layer 0 module and src/health.ts is a new top-level module; both registered in the import-DAG checker (scripts/check-imports.mjs) so the architecture invariant continues to hold (Checked 86 files, 0 violations)
  • analyzeModuleCoupling widens "module belongs to this path" matching beyond dirPrefix — exact relativePath equality and moduleName equality are now also accepted, fixing coupling reports for top-level single-file modules
  • inspectWorkspaceDocumentSet switched off findFiles and now consumes discoverDocumentSet directly, picking up the new prose/data formats, the skipped reporting, and the per-event currentPath enrichment without behavior change for existing callers (default still 50 docs, includeMarkdown still defaults to false)

Migration notes

  • Existing callers see no behavior change: discoverDocuments() keeps its array shape, all new options are opt-in, and the import-DAG plus type-check plus 208-test suite pass. To opt into the new bundle/chunk/health/errors paths, use the named exports from the facade (createOcc().workspace.bundle, createOcc().doc.chunk, createOcc().health) or the new subpath exports
  • Code reading error instanceof DOMException to detect aborts should switch to isOccAbortError(error) or error.name === 'AbortError' / error.code === 'OCC_ABORTED'. The previous DOMException instances would have failed instanceof across subprocess boundaries anyway

Install

Global install (requires Node.js 18+):

npm i -g @cesarandreslopez/occ

No-install usage:

npx @cesarandreslopez/occ [directories...]