Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9c65d94
feat(vscode-moss): phase 1 extension host spike
ankitmukherjee101 Apr 3, 2026
9a6f382
feat(vscode-moss): phase 2 project scaffold vsce ready
ankitmukherjee101 Apr 3, 2026
a2c2245
feat(vscode-moss) phase 4 core modules
ankitmukherjee101 Apr 4, 2026
6bdb7b2
Merge remote-tracking branch 'origin/main' into issue_91_vs_code_exte…
ankitmukherjee101 Apr 4, 2026
abb7ac5
index workspace working
ankitmukherjee101 Apr 4, 2026
6f6cd7b
feat(vscode-moss): working
ankitmukherjee101 Apr 4, 2026
e2c610f
Update packages/vscode-moss/package.json
ankitmukherjee101 Apr 5, 2026
cb3306a
Update packages/vscode-moss/src/searchViewProvider.ts
ankitmukherjee101 Apr 5, 2026
2eb4cc4
chunking strategy changed. tree-sitter support for major languages. w…
ankitmukherjee101 Apr 5, 2026
1094532
made improvements to search UI and added alpha parameter tweaking
ankitmukherjee101 Apr 5, 2026
4283eba
Merge remote-tracking branch 'origin/main' into issue_91_vs_code_exte…
ankitmukherjee101 Apr 6, 2026
8520918
lanch.json modified, @vscode/vscd pinned to 3.7.1, ci no longer runs …
ankitmukherjee101 Apr 6, 2026
22060bd
implemented feedback
ankitmukherjee101 Apr 7, 2026
5c7ea3a
regex backslash issue fixed
ankitmukherjee101 Apr 7, 2026
ee10e59
made an improvement to tree-sitter reliability
ankitmukherjee101 Apr 7, 2026
5884a6f
made some further improvements
ankitmukherjee101 Apr 7, 2026
520eac3
Merge remote-tracking branch 'origin/main' into issue_91_vs_code_exte…
ankitmukherjee101 Apr 9, 2026
e756a89
added a doc explaining indexing flow
ankitmukherjee101 Apr 9, 2026
48f3ca4
fixed bug where you have to re-select the bar after a keystroke
ankitmukherjee101 Apr 9, 2026
3bc77e1
made an audit fix
ankitmukherjee101 Apr 9, 2026
f7b8d5b
added some logging
ankitmukherjee101 Apr 9, 2026
5e1b0a7
Merge remote-tracking branch 'origin/main' into issue_91_vs_code_exte…
ankitmukherjee101 Apr 11, 2026
38de397
added logging for progress incase workspace is large
ankitmukherjee101 Apr 11, 2026
4349352
Merge remote-tracking branch 'origin/main' into issue_91_vs_code_exte…
ankitmukherjee101 Apr 15, 2026
90187b9
Merge remote-tracking branch 'origin/main' into issue_91_vs_code_exte…
ankitmukherjee101 Apr 18, 2026
fb025a0
moss now respects .gitignores by default
ankitmukherjee101 Apr 18, 2026
6701a99
single truth for credentials
ankitmukherjee101 Apr 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,32 @@ jobs:
working-directory: packages/vercel-sdk
run: npm test

vscode-moss-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: packages/vscode-moss/package-lock.json
- name: Install dependencies
working-directory: packages/vscode-moss
run: npm ci
- name: Typecheck
working-directory: packages/vscode-moss
run: npm run check
- name: Unit tests
working-directory: packages/vscode-moss
run: npm test
- name: Compile extension bundle
working-directory: packages/vscode-moss
run: npm run compile
- name: Package VSIX (publishability check)
working-directory: packages/vscode-moss
run: npm run package:ci

vitepress-plugin-test:
runs-on: ubuntu-latest
steps:
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ venv/
*CLAUDE.md

*.egg-info
.moss-cache
.moss-cache

.docs/
.vscode/settings.json
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ const results = await client.query(name, "your query", { topK: 5 });
| [LiveKit](https://github.com/livekit/livekit) | Available | [`apps/livekit-moss-vercel/`](apps/livekit-moss-vercel/) |
| [Next.js](https://nextjs.org) | Available | [`apps/next-js/`](apps/next-js/) |
| [VitePress](https://vitepress.dev) | Available | [`packages/vitepress-plugin-moss/`](packages/vitepress-plugin-moss/) |
| VS Code / Cursor | Available | [`packages/vscode-moss/`](packages/vscode-moss/) (semantic search sidebar; install from VSIX) |
| [Vercel AI SDK](https://sdk.vercel.ai) | Available | [`packages/vercel-sdk/`](packages/vercel-sdk/) |
| [CrewAI](https://github.com/crewAIInc/crewAI) | Coming soon | — |

Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ These are well-scoped and ready for contributors. Each one has (or will have) a
### Developer Tools

- [ ] **Moss CLI** — manage indexes, run queries, import data, and inspect results from the terminal (`moss index create`, `moss query`, `moss import`)
- [ ] **VS Code extension** — semantic search over your codebase directly from the editor sidebar
- [x] **VS Code extension** — semantic search over your codebase from the editor sidebar ([`packages/vscode-moss/`](packages/vscode-moss/); VSIX install, no Marketplace listing)

### Search Quality

Expand Down
3 changes: 3 additions & 0 deletions packages/vscode-moss/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
out/
*.vsix
17 changes: 17 additions & 0 deletions packages/vscode-moss/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension (open this folder as workspace)",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"preLaunchTask": "npm: compile",
"env": {
"MOSS_PROJECT_ID": "${env:MOSS_PROJECT_ID}",
"MOSS_PROJECT_KEY": "${env:MOSS_PROJECT_KEY}"
}
}
]
}
31 changes: 31 additions & 0 deletions packages/vscode-moss/.vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "compile",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true
},
"label": "npm: compile"
},
{
"type": "npm",
"script": "watch",
"problemMatcher": [],
"isBackground": true,
"presentation": { "reveal": "silent" },
"group": "build",
"label": "npm: watch"
},
{
"type": "npm",
"script": "check",
"problemMatcher": "$tsc",
"group": "build",
"label": "npm: check"
}
]
}
10 changes: 10 additions & 0 deletions packages/vscode-moss/.vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.vscode/**
.vscode-test/**
src/**
**/*.map
**/*.ts
esbuild.config.mjs
!out/**/*.js
tsconfig.json
.gitignore
**/.env*
120 changes: 120 additions & 0 deletions packages/vscode-moss/INDEXING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Indexing flow in vscode-moss

This document describes **how workspace indexing works** inside the Moss VS Code extension: entry point, file discovery, chunking, upload, and what happens afterward. For a shorter checklist and code map, see [`WORKFLOW.md`](./WORKFLOW.md). For a Markdown-documentation–oriented pipeline (render → HTML → heading-aware chunks), see the repo’s [**moss-md-indexer** workflow](https://github.com/usemoss/moss/blob/main/packages/moss-md-indexer/INDEXER-WORKFLOW.md).

## Entry point

Indexing runs when the user triggers **`Moss: Index Workspace`** (command `moss.indexWorkspace`), including from the status bar item registered in `extension.ts`. The implementation lives in **`runIndexWorkspace`** in [`src/indexWorkspace.ts`](./src/indexWorkspace.ts).

Preconditions:

- At least one **workspace folder** must be open; otherwise the command shows an error and returns.
- **Credentials** must resolve via `resolveCredentials` / `resolveCredentialsForWorkspace`: **per-workspace credentials blob** (Secret Storage, keyed by workspace folder URI), then environment pair (`MOSS_PROJECT_ID` + `MOSS_PROJECT_KEY`), then migration from the legacy global key + `MOSS_PROJECT_ID`, then env project ID + legacy/`MOSS_PROJECT_KEY`. If missing, the user sees an error and indexing does not start.

The work runs inside **`vscode.window.withProgress`** (notification area, **cancellable**).

## Configuration resolution

Before any I/O, the extension loads **`getMossConfig`** for the **first workspace folder** (`workspaceFolders[0]`). That yields:

- **`indexName`** — from `moss.indexName` or auto-generated from the workspace name when empty.
- **`includeGlobs` / `excludeGlobs`** — merged with extra safe excludes (`EXTRA_SAFE_EXCLUDES`, e.g. `**/.svn/**`) so dangerous paths are always filtered.
- **`respectGitignore`** — when true (default), apply each folder’s root `.gitignore` after the glob scan (see Step 1 below).
- **`maxFileSizeBytes`**, **`chunkMaxLines`**, **`chunkOverlapLines`**, **`modelId`**, etc.

Multi-root workspaces: **all roots are scanned**, but **settings** (globs, index name, chunk options) come from the **primary** folder only, consistent with the extension README.

## Step 1 — Discover files

**`findWorkspaceFiles`** uses `vscode.workspace.findFiles` with:

- **Includes** — from config (default effectively `**/*` if nothing is set).
- **Excludes** — brace-combined when possible, or multiple scans per include pattern.
- **Cap** — at most **`MAX_FILE_SCAN` (80,000)** URIs; if the scan hits the cap, indexing continues with a **warning** so users can narrow `moss.includeGlob` / `moss.excludeGlob`.

Files are **deduped** and **sorted** by `fsPath` for stable ordering.

When **`moss.respectGitignore`** is true (default), **`filterUrisByRootGitignore`** drops URIs that match each workspace folder’s **root** `.gitignore` (via the [`ignore`](https://www.npmjs.com/package/ignore) package, same semantics as Git for that file). **Nested** `.gitignore` files are not loaded. Set **`moss.respectGitignore`** to false to index ignored paths (for example build output).

## Step 2 — Read, filter, and chunk per file

For each URI (with cancellation checks between files):

1. **Workspace membership** — Skip if the file is not under any `WorkspaceFolder`.
2. **Binary extension** — Skip paths whose extension is in a fixed denylist (archives, images, binaries, fonts, etc.).
3. **Size** — Skip if `stat.size > maxFileSizeBytes`.
4. **Text** — Read bytes and decode as **UTF-8** with `fatal: true`; skip if decode fails or a `NUL` byte appears (treated as non-text).
5. **Relative path** — `asRelativePath` must be non-empty.
6. **Chunking** — **`chunkFileContent`** ([`chunking.ts`](./src/chunking.ts)) with:
- `languageId` from the file extension where supported (Markdown, JS/TS, Python, Rust, Go, Java, Ruby, PHP, C/C++, C#, etc.).
- **Structure-aware** chunks when the language is wired for Tree-sitter in [`structureChunking.ts`](./src/structureChunking.ts).
- **Line-window fallback** in [`chunkCore.ts`](./src/chunkCore.ts) when structure-aware splitting is not used.

Each chunk becomes a Moss **`DocumentInfo`**: stable **`id`**, **`text`**, and string **`metadata`** (e.g. `path`, `startLine`, `endLine`; in multi-root, `workspaceFolderIndex` / `workspaceFolderName`).

**Chunk budget** — The in-memory list **`allDocs`** is capped at **`MAX_MOSS_DOCUMENTS` (60,000)**. When the limit is reached, remaining files are skipped and a **warning** is shown.

If no documents are produced (everything skipped or empty), indexing stops with a warning and **no** API upload.

## Step 3 — Upload to Moss

Progress shows **“Uploading index to Moss…”**.

1. Construct **`MossClient(projectId, projectKey)`**.
2. **`deleteIndex(indexName)`** — Wrapped in **`tolerateDeleteIndex`**: “not found” style errors are treated as OK; other failures are logged as warnings but do not necessarily abort (see implementation for exact behavior).
3. **`createIndex(indexName, allDocs, { modelId })`** — Full replace of the remote index content for that name.

On **success**:

- **`notifySearchIndexStale()`** — Tells sidebar search to **`resetSearchSession()`** so stale `loadIndex` / client state is cleared after a full reindex.
- **`workspaceState`** is updated under **`MOSS_LAST_INDEXED_KEY`** with index name, chunk count, file count, and timestamp (drives the status bar “indexed Xm ago” text).
- **`notifyMossIndexed()`** refreshes the status bar immediately.

On **`createIndex` failure**, the user sees an error message; workspace last-indexed state is **not** updated for this run.

## Step 4 — Local search cache warm-up (optional)

After upload, progress shows **“Preparing local search cache…”** and the code **`await sleep(POST_CREATE_SETTLE_MS)`** (**2.5s**) to let the service settle before downloading.

Then **`ensureLocalIndexLoaded(client, cfg.indexName, localState)`** runs on the **same** `MossClient` used for upload. The `localState` object is **fresh** for this call only (not shared with the sidebar session).

- If **`loadIndex`** succeeds, verbose logs note that the local query cache is warmed.
- If it **fails**, indexing still **succeeded**; search falls back to **cloud** `query` until a later successful `loadIndex` (for example from the sidebar). A non-cancellation cancel after upload may skip warm-up and show an informational message.

Finally, an information message summarizes files indexed and chunk count.

## Cancellation

The user can cancel from the progress notification. The implementation checks **`token.isCancellationRequested`** after the scan, during the per-file loop, before upload, before `createIndex`, and before / after the settle delay. Partial work is not uploaded unless `createIndex` already completed.

## Code reference summary

| Concern | Location |
|--------|-----------|
| Command registration | `src/extension.ts` |
| Orchestration, scan, upload, warm-up | `src/indexWorkspace.ts` (`runIndexWorkspace`, `findWorkspaceFiles`, `tolerateDeleteIndex`) |
| Credentials and `moss.*` resolution | `src/config.ts` |
| Chunking | `src/chunking.ts`, `src/chunkCore.ts`, `src/structureChunking.ts` |
| Last-indexed persistence (status bar) | `src/lastIndexed.ts`, `src/mossStatusBar.ts` |
| Invalidate sidebar search after reindex | `src/mossQueryState.ts` (`notifySearchIndexStale`) |
| Local index helper | `src/mossQueryState.ts` (`ensureLocalIndexLoaded`) |

## Diagram (high level)

```mermaid
flowchart TD
A[Moss: Index Workspace] --> B{Open folder + credentials?}
B -->|no| Z[Show error]
B -->|yes| C[Resolve moss config for workspaceFolders0]
C --> D[findWorkspaceFiles capped at 80k]
D --> E[For each file: filter, UTF-8 read, chunkFileContent]
E --> F{Any documents?}
F -->|no| W[Warning and stop]
F -->|yes| G[deleteIndex tolerate missing]
G --> H[createIndex]
H -->|fail| E2[Error and stop]
H -->|ok| I[notifySearchIndexStale + save last indexed + status bar]
I --> J[Sleep 2.5s]
J --> K[ensureLocalIndexLoaded optional]
K --> L[Success message]
```
25 changes: 25 additions & 0 deletions packages/vscode-moss/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
BSD 2-Clause License

Copyright (c) 2026, Moss Team
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Loading
Loading