diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml
index 1fd90c71..d26aa024 100644
--- a/.github/workflows/build-macos.yml
+++ b/.github/workflows/build-macos.yml
@@ -56,6 +56,9 @@ jobs:
timeout-minutes: 120
permissions:
contents: write
+ env:
+ P12_CHECK: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}
+ API_KEY_CHECK: ${{ secrets.APPLE_API_KEY_P8 }}
steps:
- name: Checkout
@@ -68,7 +71,26 @@ jobs:
with:
node-version: '20.18.2'
cache: 'npm'
- cache-dependency-path: apps/editor/package-lock.json
+ cache-dependency-path: |
+ apps/editor/package-lock.json
+ apps/editor/build/package-lock.json
+
+ - name: Cache node_modules
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ apps/editor/node_modules
+ apps/editor/build/node_modules
+ key: node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('apps/editor/package-lock.json', 'apps/editor/build/package-lock.json') }}
+ restore-keys: |
+ node-modules-${{ runner.os }}-${{ runner.arch }}-
+
+ - name: Cache Electron gyp headers
+ uses: actions/cache@v4
+ with:
+ path: ~/.electron-gyp
+ key: electron-gyp-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('apps/editor/package.json') }}
- name: Stamp release version in product.json
if: startsWith(github.ref, 'refs/tags/')
@@ -92,8 +114,10 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_OPTIONS: --max-old-space-size=7168
+ CI_DEPS_READY: ${{ steps.cache-node-modules.outputs.cache-hit }}
- name: Import certificate to keychain
+ if: ${{ env.P12_CHECK != '' }}
env:
P12_BASE64: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}
P12_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
@@ -112,6 +136,7 @@ jobs:
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "keychain-password" "$KEYCHAIN_PATH"
- name: Sign app
+ if: ${{ env.P12_CHECK != '' }}
env:
CODESIGN_IDENTITY: "Developer ID Application: HITL, Inc (SQZ9VHYXJ3)"
AGENT_BUILDDIRECTORY: ${{ github.workspace }}/apps
@@ -126,6 +151,7 @@ jobs:
zip -Xry "$RUNNER_TEMP/OCcode-${{ matrix.artifact_name }}-${GITHUB_REF_NAME}.zip" "OCcode.app"
- name: Notarize
+ if: ${{ env.P12_CHECK != '' && env.API_KEY_CHECK != '' }}
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
@@ -144,32 +170,40 @@ jobs:
--timeout 30m
- name: Staple notarization ticket
+ if: ${{ env.P12_CHECK != '' && env.API_KEY_CHECK != '' }}
run: |
xcrun stapler staple "$GITHUB_WORKSPACE/apps/${{ matrix.output_dir }}/OCcode.app"
- name: Re-zip stapled app
+ if: ${{ env.P12_CHECK != '' && env.API_KEY_CHECK != '' }}
run: |
cd "$GITHUB_WORKSPACE/apps/${{ matrix.output_dir }}"
zip -Xry "$RUNNER_TEMP/OCcode-${{ matrix.artifact_name }}-${GITHUB_REF_NAME}-signed.zip" "OCcode.app"
- name: Verify signature
+ if: ${{ env.P12_CHECK != '' }}
run: |
codesign -dv --deep --verbose=4 "$GITHUB_WORKSPACE/apps/${{ matrix.output_dir }}/OCcode.app" 2>&1
spctl -a -vvv -t install "$GITHUB_WORKSPACE/apps/${{ matrix.output_dir }}/OCcode.app" 2>&1
- - name: Upload signed app artifact
+ - name: Upload app artifact (signed or unsigned)
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
continue-on-error: true
with:
- name: OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}-signed
- path: ${{ runner.temp }}/OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}-signed.zip
+ name: OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}
+ path: |
+ ${{ runner.temp }}/OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}-signed.zip
+ ${{ runner.temp }}/OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}.zip
retention-days: 30
- name: Create GitHub Release (on tag)
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b
+ continue-on-error: true
with:
- files: ${{ runner.temp }}/OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}-signed.zip
+ files: |
+ ${{ runner.temp }}/OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}-signed.zip
+ ${{ runner.temp }}/OCcode-${{ matrix.artifact_name }}-${{ github.ref_name }}.zip
name: OCcode ${{ github.ref_name }}
body_path: CHANGELOG.md
draft: false
@@ -197,7 +231,26 @@ jobs:
with:
node-version: '20.18.2'
cache: 'npm'
- cache-dependency-path: apps/editor/package-lock.json
+ cache-dependency-path: |
+ apps/editor/package-lock.json
+ apps/editor/build/package-lock.json
+
+ - name: Cache node_modules
+ id: cache-node-modules
+ uses: actions/cache@v4
+ with:
+ path: |
+ apps/editor/node_modules
+ apps/editor/build/node_modules
+ key: node-modules-${{ runner.os }}-x64-${{ hashFiles('apps/editor/package-lock.json', 'apps/editor/build/package-lock.json') }}
+ restore-keys: |
+ node-modules-${{ runner.os }}-x64-
+
+ - name: Cache Electron gyp headers
+ uses: actions/cache@v4
+ with:
+ path: ~/AppData/Roaming/electron-gyp
+ key: electron-gyp-${{ runner.os }}-x64-${{ hashFiles('apps/editor/package.json') }}
- name: Stamp release version in product.json
if: startsWith(github.ref, 'refs/tags/')
@@ -220,6 +273,7 @@ jobs:
run: make build-windows
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CI_DEPS_READY: ${{ steps.cache-node-modules.outputs.cache-hit }}
- name: Sign Windows installers (Azure Trusted Signing)
if: ${{ env.AZURE_CLIENT_ID_CHECK != '' }}
diff --git a/.tickets/ticket-050-ci-build-caching/prd.md b/.tickets/ticket-050-ci-build-caching/prd.md
new file mode 100644
index 00000000..6d548d83
--- /dev/null
+++ b/.tickets/ticket-050-ci-build-caching/prd.md
@@ -0,0 +1,169 @@
+# Ticket 050 — CI build caching for Windows & macOS
+
+## 2.1 Problem Statement
+
+GitHub Actions builds for Windows and macOS take significantly longer than necessary. Each workflow run performs identical work:
+- Re-downloads all npm tarballs (even when `package-lock.json` hasn't changed)
+- Re-downloads Electron gyp headers (~100 MB per architecture per run)
+- Recompiles all native modules from source (Electron 34.3.2, `build_from_source=true` in `.npmrc`)
+
+The `setup-node` action currently caches only `~/.npm` for `apps/editor/package-lock.json`, missing `apps/editor/build/package-lock.json` entirely and providing no cache for compiled `node_modules/` or Electron headers.
+
+## 2.2 Proposed Solution
+
+Implement per-platform caching across the CI workflow:
+
+1. **Extend npm tarball cache** — Fix `cache-dependency-path` in both `build-macos` and `build-windows` jobs to cover both `apps/editor/package-lock.json` AND `apps/editor/build/package-lock.json`. This caches tarballs for the build toolchain, eliminating re-downloads.
+
+2. **Cache compiled node_modules** — Add `actions/cache` step to cache `apps/editor/node_modules/` and `apps/editor/build/node_modules/` keyed on OS + architecture + combined lock file hash. Pass cache-hit status (`CI_DEPS_READY` env var) to the build target.
+
+3. **Cache Electron gyp headers** — Add `actions/cache` step for `~/.electron-gyp` (macOS) and `~/AppData/Roaming/electron-gyp` (Windows), keyed on OS + architecture + Electron version hash.
+
+4. **Conditional npm ci** — Modify Makefile `build-core` to check `CI_DEPS_READY=true` and skip `npm ci` when `node_modules/` are already cached, using a shell conditional:
+ ```makefile
+ if [ "$$CI_DEPS_READY" = "true" ]; then \
+ echo "==> Skipping npm ci (node_modules cache hit)"; \
+ else \
+ ( npm ci --ignore-scripts & (cd build && npm ci --ignore-scripts) & wait ); \
+ fi && \
+ ```
+
+### Architecture
+
+Cache keys guarantee platform isolation:
+- `node-modules-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles(...) }}`
+ - macOS arm64: `node-modules-macOS-arm64-`
+ - macOS x64: `node-modules-macOS-x64-`
+ - Windows x64: `node-modules-Windows-x64-`
+
+- `electron-gyp-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('apps/editor/package.json') }}`
+ - Ensures Electron version changes invalidate the cache
+
+Fallback via `restore-keys` allows partial hits on `runner.os-runner.arch-` when lock files change slightly.
+
+## 2.3 Acceptance Criteria
+
+- [ ] Makefile `build-core` respects `CI_DEPS_READY` env var and skips `npm ci` when set to `true`
+- [ ] `build-macos` job caches both `package-lock.json` files in npm tarball cache
+- [ ] `build-macos` job caches `node_modules/` directories with per-arch key
+- [ ] `build-macos` job caches `~/.electron-gyp` with Electron version key
+- [ ] `build-windows` job has identical cache setup (different header path)
+- [ ] First run on `ci-test` branch: creates cache entries
+- [ ] Second run on `ci-test` branch: cache hits and `npm ci` is skipped (confirmed in logs)
+- [ ] Windows build total time is measurably lower on warm cache (target: >30% reduction)
+- [ ] No regression: build succeeds identically on cold cache (no cache entry)
+
+## 2.4 Technical Considerations
+
+- **Actions/cache v4**: Uses GitHub-provided cache storage (5 GB per repo, LRU eviction). Paths and keys must exactly match across runs for hits.
+- **Shell variable escaping**: Makefile uses `$$CI_DEPS_READY` to ensure shell-level variable expansion, not Make-level.
+- **node_modules deletion by npm ci**: The conditional skip is necessary because `npm ci` always deletes `node_modules/` before installing. Caching `node_modules/` only helps if `npm ci` is skipped.
+- **Extension node_modules**: Not cached (too granular, installed per-extension via `xargs -P8` in `postinstall.js`). Cache focuses on critical path: main editor + build toolchain.
+- **Cross-platform header paths**:
+ - macOS: `~/.electron-gyp`
+ - Windows (bash shell): `~/AppData/Roaming/electron-gyp`
+
+## 2.5 Dependencies
+
+- None. All changes are in CI/CD configuration and Makefile (non-blocking for code changes).
+
+## 2.6 Constraints & Non-Goals
+
+- **Constraint**: Cache storage is limited (5 GB per repo). If cache grows beyond this, GitHub Actions LRU eviction takes effect. Monitor cache size via GHA Settings > Actions > General > Caches.
+- **Non-goal**: Do not cache `~/.npm` (setup-node does this already); do not cache extension-specific node_modules (too granular).
+- **Non-goal**: Do not modify package.json or Makefile scripts; only add conditional logic.
+
+## 2.7 Success Metrics
+
+- **Cache hit rate**: On repeated runs of the same branch, >90% cache hit rate for `node_modules` (confirmed via GHA cache analytics).
+- **Build time savings**:
+ - Windows: baseline ~20-25 min (cold), target ~15-18 min (warm, -25% to -35%)
+ - macOS: baseline ~15-20 min per arch (cold), target ~12-16 min (warm)
+- **No build failures**: All platforms continue to build successfully on cold cache (first run, no entries).
+
+---
+
+## Tasks
+
+### Task 1: Modify Makefile build-core
+
+**Status**: TODO
+**Depends on**: None
+
+- [ ] Subtask 1.1: Add conditional check for `CI_DEPS_READY` in `build-core` target
+ - **Objective**: Wrap the parallel `npm ci` block with a shell `if` statement that skips when `CI_DEPS_READY=true`
+ - **Test**: Run `make build-core` locally with `CI_DEPS_READY=true` and confirm `npm ci` message does not appear
+ - **Depends on**: None
+
+### Task 2: Update build-macos workflow job
+
+**Status**: TODO
+**Depends on**: Task 1
+
+- [ ] Subtask 2.1: Fix `cache-dependency-path` in Setup Node.js
+ - **Objective**: Add `apps/editor/build/package-lock.json` to the multi-line path list
+ - **Test**: Validate YAML syntax
+ - **Depends on**: None
+
+- [ ] Subtask 2.2: Add Cache node_modules step
+ - **Objective**: Insert after Setup Node.js, before Stamp release version. Use OS+arch-specific key with hashFiles.
+ - **Test**: Run on ci-test branch, confirm GHA shows cache step
+ - **Depends on**: Subtask 2.1
+
+- [ ] Subtask 2.3: Add Cache Electron gyp headers step
+ - **Objective**: Insert after Cache node_modules. Cache `~/.electron-gyp` with Electron version key.
+ - **Test**: First run creates cache entry; inspect GHA cache storage
+ - **Depends on**: Subtask 2.2
+
+- [ ] Subtask 2.4: Pass CI_DEPS_READY to Build macOS step
+ - **Objective**: Add `CI_DEPS_READY: ${{ steps.cache-node-modules.outputs.cache-hit }}` to env
+ - **Test**: On second run, confirm logs show "Skipping npm ci" message
+ - **Depends on**: Subtask 2.3
+
+### Task 3: Update build-windows workflow job
+
+**Status**: TODO
+**Depends on**: Task 2
+
+- [ ] Subtask 3.1–3.4: Repeat identical changes to build-windows job
+ - **Objective**: Mirror build-macos changes (different Electron header path for Windows)
+ - **Test**: Validate YAML; run on ci-test, confirm cache behavior
+ - **Depends on**: Subtask 2.4
+
+### Task 4: Test on ci-test branch
+
+**Status**: TODO
+**Depends on**: Task 3
+
+- [ ] Subtask 4.1: Push to ci-test and run first build
+ - **Objective**: Populate cache (no hits expected)
+ - **Test**: Workflow completes; GHA shows cache created entries
+ - **Depends on**: Task 3
+
+- [ ] Subtask 4.2: Re-run same branch
+ - **Objective**: Trigger cache hits
+ - **Test**: Logs show "Skipping npm ci" message in build-core step; cache-hit: true for both cache steps
+ - **Depends on**: Subtask 4.1
+
+- [ ] Subtask 4.3: Measure build time before/after
+ - **Objective**: Document wall-clock time for Windows job (cold vs warm cache)
+ - **Test**: Compare job duration from first vs second run
+ - **Depends on**: Subtask 4.2
+
+## Notes
+
+- Cache keys use `hashFiles()` to detect lock file changes. If lock files change, cache is automatically invalidated.
+- Extensions node_modules (installed via `postinstall.js`) are NOT cached to keep cache size manageable. These install quickly in parallel (xargs -P8).
+- The `restore-keys` fallback allows partial cache hits when lock files change slightly (e.g., one dependency version bump).
+
+## Root Cause & Fix
+
+**Root Cause**:
+- npm tarball cache only covered main `package-lock.json`, not the separate `build/` subdirectory.
+- `node_modules/` was never cached, requiring full recompilation of native modules (Electron headers + `build_from_source=true`).
+- Electron gyp headers were re-downloaded on every run (~100 MB waste).
+
+**Fix**:
+- Extended caching to all lock files and compiled artifacts.
+- Added conditional `npm ci` skip to avoid re-deleting cached `node_modules/`.
+- Ensured cache keys are platform-specific (OS + arch) to prevent cross-platform binary incompatibility.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eed10173..66cf512f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,61 @@
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
+## [3.6.1](https://github.com/asieduernest12/occ/compare/v3.6.0...v3.6.1) (2026-04-17)
+
+
+### Bug Fixes
+
+* **macos-ci:** publish unsigned artifacts when signing secrets missing ([1d5c5b9](https://github.com/asieduernest12/occ/commit/1d5c5b9205c06639bb01a0f26ec1df739c2042a8))
+
+## [3.6.0](https://github.com/asieduernest12/occ/compare/v3.5.4...v3.6.0) (2026-04-17)
+
+
+### Features
+
+* **ci:** per-platform npm and electron caching for Windows & macOS ([797f11f](https://github.com/asieduernest12/occ/commit/797f11f314b54950583545c0bc4cac34b8f41a04))
+* **ci:** skip macOS signing/notarization when secrets missing ([45afba1](https://github.com/asieduernest12/occ/commit/45afba1b282e0e2b421c5966ae83a77ae3f9989e))
+
+
+### Bug Fixes
+
+* **native-modules:** add explicit npm rebuild on Windows for vscode-policy-watcher.node ([cb79286](https://github.com/asieduernest12/occ/commit/cb792862fa5df6671973ee0f1c396437dc9e4fa7))
+* **ticket-039:** apply branded icons across all platforms ([77d7676](https://github.com/asieduernest12/occ/commit/77d7676e7549ccb3ff61fe97a75444108bdb052c))
+* **ticket-039:** remove stale branding across all platform manifests ([e0d8f06](https://github.com/asieduernest12/occ/commit/e0d8f063804a2000b0e7e1552dba71d868039edd))
+* **ticket-039:** replace web server icons and fix manifest branding ([152433e](https://github.com/asieduernest12/occ/commit/152433eac56eeb1493376ee53d8a924422124f5c))
+* **windows-build:** ensure native modules rebuild even on npm cache hit ([46f894e](https://github.com/asieduernest12/occ/commit/46f894e40bee8396b21cd8e7698a2085a9aa05fb))
+
+## [3.6.0](https://github.com/asieduernest12/occ/compare/v3.5.4...v3.6.0) (2026-04-17)
+
+
+### Features
+
+* **ci:** per-platform npm and electron caching for Windows & macOS ([797f11f](https://github.com/asieduernest12/occ/commit/797f11f314b54950583545c0bc4cac34b8f41a04))
+* **ci:** skip macOS signing/notarization when secrets missing ([45afba1](https://github.com/asieduernest12/occ/commit/45afba1b282e0e2b421c5966ae83a77ae3f9989e))
+
+
+### Bug Fixes
+
+* **native-modules:** add explicit npm rebuild on Windows for vscode-policy-watcher.node ([cb79286](https://github.com/asieduernest12/occ/commit/cb792862fa5df6671973ee0f1c396437dc9e4fa7))
+* **ticket-039:** apply branded icons across all platforms ([77d7676](https://github.com/asieduernest12/occ/commit/77d7676e7549ccb3ff61fe97a75444108bdb052c))
+* **ticket-039:** remove stale branding across all platform manifests ([e0d8f06](https://github.com/asieduernest12/occ/commit/e0d8f063804a2000b0e7e1552dba71d868039edd))
+* **ticket-039:** replace web server icons and fix manifest branding ([152433e](https://github.com/asieduernest12/occ/commit/152433eac56eeb1493376ee53d8a924422124f5c))
+* **windows-build:** ensure native modules rebuild even on npm cache hit ([46f894e](https://github.com/asieduernest12/occ/commit/46f894e40bee8396b21cd8e7698a2085a9aa05fb))
+
+## [3.5.4](https://github.com/asieduernest12/occ/compare/v3.5.3...v3.5.4) (2026-04-16)
+
+## [3.5.5](https://github.com/asieduernest12/occ/compare/v3.5.4...v3.5.5) (2026-04-17)
+
+
+### Bug Fixes
+
+* **native-modules:** add explicit npm rebuild on Windows for vscode-policy-watcher.node ([cb79286](https://github.com/asieduernest12/occ/commit/cb792862fa5df6671973ee0f1c396437dc9e4fa7))
+* **ticket-039:** apply branded icons across all platforms ([77d7676](https://github.com/asieduernest12/occ/commit/77d7676e7549ccb3ff61fe97a75444108bdb052c))
+* **ticket-039:** remove stale branding across all platform manifests ([e0d8f06](https://github.com/asieduernest12/occ/commit/e0d8f063804a2000b0e7e1552dba71d868039edd))
+* **ticket-039:** replace web server icons and fix manifest branding ([152433e](https://github.com/asieduernest12/occ/commit/152433eac56eeb1493376ee53d8a924422124f5c))
+
+## [3.5.4](https://github.com/asieduernest12/occ/compare/v3.5.3...v3.5.4) (2026-04-16)
+
## [3.5.4](https://github.com/asieduernest12/occ/compare/v3.5.3...v3.5.4) (2026-04-16)
## [3.5.3](https://github.com/asieduernest12/occ/compare/v3.4.3...v3.5.3) (2026-04-16)
diff --git a/Makefile b/Makefile
index 2a26c5a5..479518b4 100644
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,13 @@ build-core:
cd $(PROJECT_ROOT)/apps/editor && \
export NODE_OPTIONS="--max-old-space-size=7168" && \
echo "==> Install editor + build dependencies (parallel)" && \
- ( npm ci --ignore-scripts & (cd build && npm ci --ignore-scripts) & wait ) && \
+ if [ "$$CI_DEPS_READY" != "true" ]; then \
+ ( npm ci --ignore-scripts & (cd build && npm ci --ignore-scripts) & wait ); \
+ else \
+ echo "==> Skipping npm ci (node_modules cache hit)"; \
+ fi && \
+ echo "==> Rebuild native modules for Electron ($(ELECTRON_ARCH))" && \
+ npx --yes @electron/rebuild -v 34.3.2 -a $(ELECTRON_ARCH) && \
echo "==> Patch compilation.js" && \
node -e " \
const fs = require('fs'); \
diff --git a/apps/editor/build/npm/postinstall.js b/apps/editor/build/npm/postinstall.js
index 7a72694d..96dd751e 100644
--- a/apps/editor/build/npm/postinstall.js
+++ b/apps/editor/build/npm/postinstall.js
@@ -175,6 +175,27 @@ function removeParcelWatcherPrebuild(dir) {
}
}
+/**
+ * Rebuild native modules explicitly on Windows.
+ * @param {string} dir
+ * @param {*} [opts]
+ */
+function npmRebuild(dir, opts) {
+ opts = {
+ env: { ...process.env },
+ ...(opts ?? {}),
+ cwd: dir,
+ stdio: 'inherit',
+ shell: true
+ };
+
+ // Only rebuild on Windows where build_from_source might need explicit rebuild
+ if (process.platform === 'win32') {
+ log(dir, 'Rebuilding native modules...');
+ run(npm, ['rebuild'], opts);
+ }
+}
+
// ── Main ────────────────────────────────────────────────────────────────────
async function main() {
@@ -253,6 +274,13 @@ async function main() {
const elapsed = ((Date.now() - t0) / 1000).toFixed(1);
log('.', `Parallel install done — ${plainDirs.length} dirs in ${elapsed}s`);
+ // ── Native module rebuild (Windows) ─────────────────────────────────────
+ // On Windows, explicitly rebuild native modules after npm install
+ // to ensure modules like vscode-policy-watcher.node are compiled
+ if (process.platform === 'win32') {
+ npmRebuild('', { env: { ...process.env } });
+ }
+
// ── Git config ──────────────────────────────────────────────────────────
try {
cp.execSync('git config pull.rebase merges', { cwd: root });
diff --git a/apps/editor/package-lock.json b/apps/editor/package-lock.json
index 99bea4dc..d19edf01 100644
--- a/apps/editor/package-lock.json
+++ b/apps/editor/package-lock.json
@@ -1,11 +1,11 @@
{
- "name": "code-oss-dev",
+ "name": "occode-dev",
"version": "1.99.3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "code-oss-dev",
+ "name": "occode-dev",
"version": "1.99.3",
"hasInstallScript": true,
"license": "MIT",
diff --git a/package.json b/package.json
index 6f7e3133..79310507 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "occode",
- "version": "3.5.4",
+ "version": "3.6.1",
"private": true,
"description": "OCcode — branded cross-platform IDE wrapper with OpenClaw extension",
"workspaces": [
diff --git a/version.txt b/version.txt
index e5b8a844..d1428a7e 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-3.5.4
\ No newline at end of file
+3.6.1
\ No newline at end of file