Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 29 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
push:
branches:
- main
- 'codex/**'
- "codex/**"
workflow_dispatch:

permissions:
Expand All @@ -17,11 +17,11 @@ jobs:
timeout-minutes: 20

steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- workflow structure ---'
sed -n '1,130p' .github/workflows/ci.yml

printf '%s\n' '--- checkout and git-related workflow usage ---'
rg -n -C 3 'actions/checkout|persist-credentials|git (clone|fetch|pull|push)|npm (install|ci|run)|pnpm|yarn' .github/workflows/ci.yml

printf '%s\n' '--- repository scripts referenced by the workflow ---'
rg -n -C 3 '"(integration|test|lint|build|compile|prepare|preinstall|postinstall)[^"]*":|run-integration-tests|GITHUB_TOKEN|github.token|git config|git remote' package.json package-lock.json scripts .github 2>/dev/null || true

printf '%s\n' '--- tracked workflow and package files ---'
git ls-files .github/workflows/ci.yml package.json package-lock.json scripts

Repository: Deathcharge/samsarix-vscode

Length of output: 5677


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- package scripts and lifecycle hooks ---'
sed -n '210,245p' package.json
rg -n -C 4 '"(preinstall|install|postinstall|prepare|prepublish|audit:prod|package|test:integration)"' package.json

printf '%s\n' '--- repository-controlled commands and credential references ---'
rg -n -C 3 'process\.env|GITHUB_TOKEN|github\.token|GH_TOKEN|git config|git remote|git (clone|fetch|pull|push)|https://[^ ]+@' --glob '!package-lock.json' --glob '!dist/**' .

printf '%s\n' '--- all workflow permissions and checkout options ---'
rg -n -C 5 '^(permissions:|  [A-Za-z_-]+: (read|write|none)|      - uses: actions/checkout|persist-credentials|run:)' .github/workflows

Repository: Deathcharge/samsarix-vscode

Length of output: 6100


🌐 Web query:

GitHub actions/checkout persist-credentials default true local git config README

💡 Result:

The persist-credentials input for the GitHub actions/checkout action has a default value of true [1][2][3]. When set to true, the action configures the authentication token or SSH key within the local Git configuration of the checked-out repository, allowing subsequent scripts to execute authenticated Git commands [1][4]. In recent versions of actions/checkout, credential security has been improved: instead of writing directly to the repository's.git/config, credentials are stored in a separate file under the runner's temporary directory ($RUNNER_TEMP) and included conditionally using Git's includeIf mechanism [1][2][5]. This sensitive data is automatically removed during the post-job cleanup process [1][3][4]. Users who wish to prevent the action from configuring these credentials in the local Git configuration can explicitly set persist-credentials to false [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

python3 - <<'PY'
import json
from pathlib import Path

for workflow in sorted(Path(".github/workflows").glob("*.yml")):
    text = workflow.read_text()
    lines = text.splitlines()
    print(f"--- {workflow} ---")
    for i, line in enumerate(lines):
        if "actions/checkout@" not in line:
            continue
        indent = len(line) - len(line.lstrip())
        has_persist_false = False
        following = []
        for candidate in lines[i + 1:]:
            candidate_indent = len(candidate) - len(candidate.lstrip())
            if candidate.strip() and candidate_indent <= indent:
                break
            if "persist-credentials:" in candidate:
                has_persist_false = "false" in candidate.split("#", 1)[0].lower()
            if candidate.lstrip().startswith("run:") or "uses:" in candidate:
                following.append(candidate.strip())
        print(f"checkout_line={i + 1} persist_credentials_false={has_persist_false}")
        print("following_steps=" + repr(following))

package = json.loads(Path("package.json").read_text())
print("--- package scripts ---")
for name, command in package.get("scripts", {}).items():
    print(f"{name}: {command}")
PY

Repository: Deathcharge/samsarix-vscode

Length of output: 1175


🏁 Script executed:

#!/bin/bash
set -eu
sed -n '1,90p' .github/workflows/release.yml

Repository: Deathcharge/samsarix-vscode

Length of output: 1323


Disable checkout credential persistence in all workflows.

actions/checkout defaults persist-credentials to true and configures a credential helper for later Git commands. Both workflows run repository-controlled npm commands after checkout. The release workflow also grants contents: write.

Set persist-credentials: false on the checkout steps at .github/workflows/ci.yml:20, .github/workflows/ci.yml:68, and .github/workflows/release.yml:17.

🧰 Tools
🪛 zizmor (1.29.0)

[warning] 20-20: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml at line 20, Update every actions/checkout step in
the CI and release workflows, including the steps near the specified checkout
references, to set persist-credentials to false while preserving the existing
pinned action versions and workflow behavior.

Source: Linters/SAST tools


- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 20
node-version: 22
cache: npm

- name: Install locked dependencies
Expand All @@ -46,7 +46,7 @@ jobs:
run: npm run inspect:package

- name: Upload verified package and evidence
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: samsarix-vsix-${{ github.sha }}
path: |
Expand All @@ -55,3 +55,27 @@ jobs:
dist/*.contents.txt
if-no-files-found: error
retention-days: 14

integration:
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
vscode-version: ["1.85.2", "stable"]

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: npm

- name: Install locked dependencies
run: npm ci

- name: Run Extension Development Host smoke test
run: xvfb-run -a npm run test:integration
env:
SAMSARIX_VSCODE_TEST_VERSION: ${{ matrix.vscode-version }}
49 changes: 49 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Draft GitHub release

on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
timeout-minutes: 25

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Disable persisted checkout credentials.

Line 17 persists the write-capable checkout token in the Git remote configuration. npm ci runs after checkout and can execute dependency lifecycle scripts. A compromised dependency can use that credential to modify repository contents. Set persist-credentials: false. The final gh release create command already receives GH_TOKEN explicitly.

Proposed fix
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+        with:
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 17-17: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml at line 17, Update the actions/checkout step
in the release workflow to set persist-credentials to false, while leaving the
existing explicit GH_TOKEN authentication for gh release create unchanged.

Source: Linters/SAST tools


- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 22
cache: npm

- name: Install locked dependencies
run: npm ci

- name: Verify minimum supported VS Code host
run: xvfb-run -a npm run test:integration
env:
SAMSARIX_VSCODE_TEST_VERSION: "1.85.2"

- name: Verify source and package
run: npm run check

- name: Audit complete dependency graph
run: npm audit --audit-level=high

- name: Create draft release with immutable evidence
env:
GH_TOKEN: ${{ github.token }}
run: >-
gh release create "${GITHUB_REF_NAME}"
dist/*.vsix
dist/*.sha256
dist/*.contents.txt
--draft
--verify-tag
--generate-notes
--title "Samsarix ${GITHUB_REF_NAME}"
Comment on lines +42 to +49

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate the release tag against package.json.

Line 42 creates a release for every v* tag. The package tests require version 1.1.0, so a v1.1.1 tag can publish a release named v1.1.1 with 1.1.0 VSIX evidence. Fail the workflow unless GITHUB_REF_NAME equals v${package.json.version}.

Proposed fix
+      - name: Verify release tag version
+        run: |
+          expected_tag="v$(node -p "require('./package.json').version")"
+          test "${GITHUB_REF_NAME}" = "${expected_tag}"
+
       - name: Create draft release with immutable evidence
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 42 - 49, Update the release
workflow before the gh release create command to read package.json.version and
validate that GITHUB_REF_NAME exactly equals v${package.json.version}; fail the
job with a clear error when they differ, and only continue to create the release
after validation succeeds.

3 changes: 3 additions & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
coverage/**
dist/**
docs/**
integration-fixture/**
media/**
node_modules/**
scripts/**
src/**
out/integration/**
tests/**
.gitignore
.vscodeignore
Expand All @@ -19,6 +21,7 @@ eslint.config.mjs
jest.config.js
package-lock.json
tsconfig.json
tsconfig.integration.json
**/*.map
**/*.ts
**/*.tsx
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## 1.0.0 — unreleased productization candidate
## 1.1.0 — 2026-08-11 productized release candidate

- Reframed Samsarix as an independent local-Ollama, review-first code assistant.
- Removed hosted API, authentication, subscription, marketplace, agent polling, WebSocket, MCP, browser, terminal, mock dashboard, and passive inline-completion surfaces from the release runtime.
Expand All @@ -11,5 +11,11 @@
- Renamed the product and extension identity to Samsarix, owned by Samsarix LLC.
- Replaced the legacy double-helix icon with an original Samsarix S/X mark.
- Replaced contradictory custom licensing terms with the standard Mozilla Public License 2.0, attribution notice, and trademark policy.
- Added an automated Extension Development Host smoke test against the minimum supported VS Code version.
- Added tag-driven draft GitHub release automation with verified VSIX evidence.

## 1.0.0 — historical repository tag

The existing `v1.0.0` tag predates the productized local-only runtime and is retained to avoid rewriting public history. Use `1.1.0` or later for the Samsarix-branded release line.

Marketplace publication remains gated on control of the `samsarix` publisher, brand clearance, and the documented human acceptance run.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Samsarix is a small VS Code coding companion for developers who run [Ollama](htt

This repository is independent: it needs no Samsarix account, subscription, hosted API, marketplace, or companion repository.

> Release status: this is a verified release candidate. Public Marketplace publication still requires control of the `samsarix` publisher, brand/trademark clearance, and a human acceptance run with a chat-capable Ollama model. See [the productization record](docs/PRODUCTIZATION.md#owner-decisions-and-external-gates).
> Release status: `1.1.0` is the first productized release candidate. It has automated unit, package, and Extension Development Host evidence. Public Marketplace publication still requires control of the `samsarix` publisher, brand/trademark clearance, and a human acceptance run with a chat-capable Ollama model. See [the productization record](docs/PRODUCTIZATION.md#owner-decisions-and-external-gates).

## What it does

Expand Down Expand Up @@ -37,7 +37,7 @@ From a clean checkout:
```bash
npm ci
npm run check
code --install-extension dist/samsarix-vscode-1.0.0.vsix
code --install-extension dist/samsarix-vscode-1.1.0.vsix
```

`npm run check` lints, type-checks, tests, packages, normalizes the archive for reproducible hashing, inspects every VSIX entry against an allowlist, and writes adjacent `.sha256` and `.contents.txt` evidence files.
Expand Down Expand Up @@ -128,13 +128,14 @@ See [Privacy](docs/PRIVACY.md), [Architecture](docs/ARCHITECTURE.md), and [Secur

## Development and verification

Use a supported Node.js LTS release (CI uses Node 20):
Use Node.js 22 or later (CI uses Node 22):

```bash
npm ci
npm run lint
npm run typecheck
npm test -- --runInBand
npm run test:integration
npm run package
npm run inspect:package
npm run audit:prod
Expand Down
10 changes: 6 additions & 4 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This roadmap separates four gates: merge, release, publication, and flagship ado
Portfolio role: **integration or extension**. Keep its platform-specific packaging and release lifecycle separate. Any flagship integration should use a documented HTTP, event, or package contract with explicit auth, privacy, and failure ownership.
Planned repository identity: `Deathcharge/samsarix-vscode` (ready).

Current disposition: Merge the productization branch after exact-head verification and rollback-ref creation; release and adoption remain separate decisions.
Current disposition: the productized runtime and competitive local-review milestone are on `main`. Version `1.1.0` is the first non-colliding Samsarix release line because the historical `v1.0.0` tag predates productization. Marketplace publication and broader adoption remain separate owner decisions.

## Stabilize the productized default

Expand All @@ -24,9 +24,9 @@ Current disposition: Merge the productization branch after exact-head verificati

Current hardening backlog:

- No clean-profile, real-Ollama, Extension Development Host acceptance evidence from this audit.
- No Marketplace publisher validation, pre-release, publication automation, or rollback exercise.
- The branch has no cached product PR and changes licensing from a custom BSL baseline to MPL-2.0.
- No real-Ollama acceptance evidence is available on this machine because Ollama is not installed.
- No Marketplace publisher validation, Marketplace publication automation, or rollback exercise.
- Marketplace publisher control and brand/trademark clearance still require owner evidence.
- Remote endpoints have no first-party authentication design; whole-file proposals remain coarse and model-dependent.
- The local IDE-assistant market is crowded, so the narrow safety promise needs user validation.

Expand All @@ -36,6 +36,8 @@ Completed competitive workflow milestone:
- Up to 12 memory-only follow-up turns with an explicit clear action.
- Explicit-selection Explain and Review tasks surfaced in the sidebar and editor context menu.
- On-demand active-file diagnostic repair, bounded to 25 summaries and routed through native diff approval.
- Extension Development Host smoke coverage at VS Code 1.85.2 verifies command registration, no-I/O activation, explicit selection attachment, and restricted configuration declarations.
- Current stable VS Code compatibility is exercised in the CI host-test matrix, and the exact VSIX is installable in an isolated extension directory.

## Samsarix adoption

Expand Down
10 changes: 5 additions & 5 deletions docs/PRODUCTIZATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Status: verified release candidate; Marketplace publication externally gated
Date: 2026-07-28
Release target: `1.0.0` only after every P0 gate below passes
Release target: `1.1.0`; the historical `v1.0.0` tag predates the productized runtime and remains unchanged

## Executive decision

Expand Down Expand Up @@ -101,7 +101,7 @@ This is intentionally narrower than general agents. The goal is trustworthy comp
- **Completed:** multi-turn session history with an explicit clear button, 12-turn request bound, and documented in-memory retention.
- **Completed:** explicit-selection Explain/Review tasks and on-demand active-file diagnostic repair through the existing diff gate.
- Partial edit format with robust conflict handling instead of whole-file proposals.
- First-party VS Code integration tests in an Extension Development Host.
- **Completed:** first-party smoke tests in a VS Code 1.85.2 Extension Development Host.
- Remote Ollama support with an authenticated transport design and per-endpoint disclosure.
- Accessibility and localization review with keyboard-only and screen-reader testing.

Expand Down Expand Up @@ -254,9 +254,9 @@ The official `vsce` flow is the release mechanism. VS Code’s current guidance

The release is blocked unless:

- `npm ci`, `npm run lint`, `npm run compile`, `npm test -- --runInBand`, and `npm run package` succeed from a clean checkout;
- `npm ci`, `npm run lint`, `npm run compile`, `npm test -- --runInBand`, `npm run test:integration`, and `npm run package` succeed from a clean checkout;
- the VSIX contents match the allowlist and contain no source maps, test fixtures, stale webviews, lockfile secrets, `.env` files, or unrelated services;
- `npm audit --omit=dev` has no high/critical production finding, and dev-only exceptions (if any) are recorded with owner and expiry;
- both the complete `npm audit` and production-only audit have no high/critical finding; any future exception must record an owner and expiry;
- the installed VSIX passes the manual core journey;
- the MPL-2.0 license/notice files are present and the intended Marketplace publisher identity is controlled by the owner.

Expand All @@ -277,7 +277,7 @@ The legacy double-helix icon was replaced with a new project-created S/X mark th

Public Marketplace publication remains blocked by:

- **Publisher**: create or confirm control of the exact `samsarix` Visual Studio Marketplace publisher declared by the manifest.
- **Publisher**: create or confirm control of the exact `samsarix` Visual Studio Marketplace publisher declared by the manifest. As checked on 2026-08-11, the public publisher and `samsarix.samsarix-vscode` item URLs both return 404, and this workstation has no authenticated `vsce` publisher.
- **Repository identity (complete)**: the canonical repository and manifest URLs use `Deathcharge/samsarix-vscode`; the post-rename VSIX contents check passes.
- **Brand clearance**: perform a professional trademark search for the Samsarix name and the new S/X mark, document provenance, and decide whether to pursue registration before a broad public launch.
- **Copyright chain**: confirm that Samsarix LLC owns or has assignments for the copyrights it claims. Repository history is overwhelmingly owner-authored but includes automation identities.
Expand Down
9 changes: 5 additions & 4 deletions docs/RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ Public publication is not authorized by repository access alone. Confirm every e
## Technical gates

1. Start from a clean checkout on a protected release branch.
2. Use Node 20 and run `npm ci`.
3. Run `npm run check` and `npm run audit:prod`.
2. Use Node 22 or later and run `npm ci`.
3. Run `npm run check`, `npm audit --audit-level=high`, and `npm run audit:prod`.
4. Build twice from the same checkout and confirm the normalized VSIX SHA-256 is identical. Retain the VSIX, `.sha256`, `.contents.txt`, test output, dependency-audit output, and source revision.
5. Have a second person install that exact VSIX in a clean VS Code profile and sign off on [the manual matrix](TESTING.md#manual-core-journey-matrix).
6. Verify README/settings/commands against the installed artifact.
5. Run `npm run test:integration` and retain the Extension Development Host result.
6. Have a second person install that exact VSIX in a clean VS Code profile with Ollama and sign off on [the manual matrix](TESTING.md#manual-core-journey-matrix).
7. Verify README/settings/commands against the installed artifact.

## Publication

Expand Down
6 changes: 5 additions & 1 deletion docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ npm ci
npm run lint
npm run typecheck
npm test -- --runInBand
npm run test:integration
npm run package
npm run inspect:package
npm run audit:prod
```

Unit tests cover endpoint/model/input/path policy, structured edits, Ollama request/response behavior, failure normalization, release command alignment, and webview injection invariants. Packaging sorts entries and fixes their timestamps before hashing. `inspect:package` reads the built VSIX itself, permits only documented entries, scans runtime text for quarantined capabilities, checks that there are no production dependencies, and writes content/SHA-256 evidence.
Unit tests cover endpoint/model/input/path policy, structured edits, Ollama request/response behavior, failure normalization, release command alignment, and webview injection invariants. The Extension Development Host smoke test runs through the official `@vscode/test-electron` harness at both the minimum supported and current stable VS Code versions in CI; it proves command registration, silent activation, explicit selection attachment, and Workspace Trust metadata. Packaging sorts entries and fixes their timestamps before hashing. `inspect:package` reads the built VSIX itself, permits only documented entries, scans runtime text for quarantined capabilities, checks that there are no production dependencies, and writes content/SHA-256 evidence.

## Manual core-journey matrix

Expand All @@ -22,7 +23,10 @@ Unit tests cover endpoint/model/input/path policy, structured edits, Ollama requ
| Test with Ollama stopped | Actionable endpoint error; no prompt/source in error. |
| Configure with zero models | Exact `ollama pull` next step. |
| Ask without attachment | Only prompt/system message in request. |
| Stream response and cancel | Partial text is visible; cancellation stops consumption with an actionable status. |
| Attach malicious HTML-like filename/text | Displayed literally; no DOM execution. |
| Explain/Review selection | Only the displayed selection, bounded history, and fixed task prompt are sent. |
| Repair diagnostics | At most 25 active-file diagnostic summaries are sent; every write still waits for diff approval. |
| Reject proposal | Diff opens; no file write. |
| Apply proposal | Exactly previewed content in unsaved active buffer. |
| Change file during generation | Stale proposal rejected. |
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Install a locally verified package:
```bash
npm ci
npm run check
code --install-extension dist/samsarix-vscode-1.0.0.vsix
code --install-extension dist/samsarix-vscode-1.1.0.vsix
```

Open **Samsarix: Open Local Chat**, choose **Configure**, confirm the Ollama origin, and select an installed model. No network request happens before a Configure, Test, Send, or Propose-edit action.
Expand Down
1 change: 1 addition & 0 deletions integration-fixture/sample.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const localOnly = true;
Loading