diff --git a/.loopdeck/current-loop.md b/.loopdeck/current-loop.md index a910d2c..1dadb4b 100644 --- a/.loopdeck/current-loop.md +++ b/.loopdeck/current-loop.md @@ -1 +1 @@ -Selasar revamp — prd-rebrand-tokens Phase 1 (design tokens) complete: paper/ink/teak palette + font-display token + toggle verified \ No newline at end of file +Selasar revamp — prd-rebrand-tokens Phase 2 (rebrand copy audit) complete: full-repo audit recorded in PRD, tauri.conf.json/index.html renamed to Selasar, all in-app copy renamed; Phase 3 (visual pass) remains \ No newline at end of file diff --git a/.loopdeck/decisions.md b/.loopdeck/decisions.md index fb97589..636c001 100644 --- a/.loopdeck/decisions.md +++ b/.loopdeck/decisions.md @@ -175,3 +175,8 @@ _Older decisions archived to [decisions-archive.md](./decisions-archive.md)._ - **Status**: accepted - **Context**: The PRD criterion "apply `--font-display` to the wordmark, rail mark, and project-name treatments" had no literal rail-mark text — AppShell's brand tile is an icon-only gradient (Command icon, no wordmark text), and the run interview mapped "rail mark" to the sidebar subtitle. - **Consequences**: New `--font-display: ui-serif, Charter, "Iowan Old Style", "Palatino Linotype", Georgia, serif` token (Tailwind v4 `font-display` utility). Applied to the wordmark + subtitle in `AppShell.tsx`, and to project names at all 3 render sites: `ProjectList.tsx` row, `ProjectDetail.tsx` breadcrumb header, `ProjectDetail.tsx` tab-rail label. + +## 2026-08-05 — Selasar Phase-2 copy audit + rename: full-repo tagged list in the PRD, rename scope incl. bundle id +- **Status**: accepted +- **Context**: `prd-rebrand-tokens` Phase 2 (3 loops, one combined overnight run): audit every user-visible "LoopDeck" occurrence, then rename window title, wordmark, and in-app copy to "Selasar". The run interview resolved the PRD's open questions: rename the macOS bundle identifier too, and update Rust test assertions that assert on renamed copy. +- **Consequences**: Full-repo audit recorded in the PRD (`## Phase 2 Audit — "LoopDeck" occurrences`), every occurrence tagged user-visible / comment / test-assertion / left-intact. Renamed all user-visible copy + comments to "Selasar" (wordmark, error/empty/settings/import copy, agent initial prompts, chat truncation marker, Codex clientInfo title + turn errors, run-queue notification titles, schema/deny error strings, export header, 5 hook templates), updated test assertions + smoke-test-release.sh artifact names in lockstep, and changed the bundle `identifier` to `com.selasar.app`. Left untouched: `.loopdeck/` dir, `project.yaml` schema, `config.rs` `ProjectDirs::from("com","loopdeck","LoopDeck")`, log dir `~/Library/Logs/LoopDeck/`, all lowercase `loopdeck` identifiers, and docs/ (P2 goal, deferred). diff --git a/.loopdeck/loops.md b/.loopdeck/loops.md index 8416b86..68e1c78 100644 --- a/.loopdeck/loops.md +++ b/.loopdeck/loops.md @@ -3,8 +3,11 @@ ## Current - **Started**: 2026-08-05 -- **Goal**: `selasar-revamp` / `prd-rebrand-tokens` Phase 1 — Design tokens (the epic's first, gating PRD): replace `src/styles.css`'s light+dark token values with the paper/ink/teak palette, add a `--font-display` serif token, and verify the light/dark/system toggle against the new values. All three Phase-1 loops ran as one combined unattended overnight run; Phase 2 (rebrand copy audit) and Phase 3 (full visual pass) remain. +- **Goal**: `selasar-revamp` / `prd-rebrand-tokens` Phase 2 — Rebrand copy audit: grep the repo for user-visible "LoopDeck" occurrences and record the full list, rename `src-tauri/tauri.conf.json` productName/window title + `index.html` `` to "Selasar", and rename all in-app user-visible copy to "Selasar" leaving `.loopdeck/`, `project.yaml` schema, and internal identifiers untouched. All three Phase-2 loops ran as one combined unattended overnight run; Phase 3 (full visual pass) remains. - **Status**: in_progress +- ✅ **`selasar-revamp/grep-the-repo-for-user-visible-loopdeck-occurrences-component`** (2026-08-05) — Full-repo grep of every `LoopDeck`/`loopdeck` occurrence, each tagged by category (user-visible copy / comments / test assertions / left-intact on-disk paths + internal identifiers / docs & tooling); the full tagged list appended to the PRD as `## Phase 2 Audit — "LoopDeck" occurrences (2026-08-05)`, the rename source of truth for the two update loops. +- ✅ **`selasar-revamp/update-src-tauri-tauri-conf-json-s-window-title-and-product-name-to`** (2026-08-05) — `src-tauri/tauri.conf.json` `productName` (`:3`) + window `title` (`:16`) → "Selasar"; `index.html:6` `<title>` → "Selasar" (drives the WebView title bar, per the run interview); bundle `identifier` `com.loopdeck.app` → `com.selasar.app` (`:5`, Phase-2 open-question resolution). `scripts/smoke-test-release.sh` artifact names updated to match (`Selasar.app`/`Contents/MacOS/Selasar`/`com.selasar.app`); the real config-dir path `com.loopdeck.LoopDeck` (`:114`) preserved. +- ✅ **`selasar-revamp/update-all-in-app-user-visible-copy-found-in-the-audit-to-selasar`** (2026-08-05) — Renamed every user-visible "LoopDeck" to "Selasar": sidebar wordmark (`AppShell.tsx:138`), error/empty/settings/import copy (`RootErrorBoundary`/`EmptyState`/`Settings`/`ImportFlow`/`NewProjectDialog`/`KnowledgeGraphPanel`), agent initial prompts (`commands/agent.rs:1000,1011` + `run_executor.rs:152,157`), chat truncation marker (`agents.rs:844`), Codex `clientInfo` title + turn errors (`codex_session.rs:655,745,1254`), run-queue notification titles (`run_queue.rs`), schema-version + deny-reason error strings (`execution.rs`/`permission.rs`), exported-summary header (`progress.rs`), 5 hook templates' docstrings + nudge messages, and the smoke script. Comments renamed for consistency (full file list in the PRD audit); test assertions (`skills.rs` hook-content asserts) + hook templates updated in lockstep. Left untouched: `.loopdeck/` dir name, `project.yaml` schema, `config.rs` `ProjectDirs` (`com.loopdeck.LoopDeck`), log dir `~/Library/Logs/LoopDeck/`, and all lowercase `loopdeck` identifiers. Gates green: `cargo fmt --check` / `cargo clippy --lib -- -D warnings` / `cargo test` 590 passed / `tsc --noEmit` / `npm run build`. - ✅ **`selasar-revamp/replace-src-styles-css-s-light-and-dark-token-values-with-the`** (2026-08-05) — Replaced `src/styles.css`'s `:root`/`.dark` token values with the paper/ink/teak palette from the run's 3 anchors only (paper `#F5F1E8`, ink `#241E17`, teak `#8A5A3A`): `--background`/`--foreground`/`--primary` map to the literal anchors in both schemes, neutrals are warm oklch interpolations (hue ≈73–87), functional colors (destructive/success/warning) warmed to the family, `--hljs-*` keyword/name/tag remapped to teak, `--shadow-*` ink-tinted (light) / border-based (dark), and the `card-accent-top` gradient to-color warmed. `--color-*` names unchanged. Gates: `tsc --noEmit` + `npm run build` clean. - ✅ **`selasar-revamp/add-a-font-display-token-for-the-serif-display-font-and-apply-it`** (2026-08-05) — Added `--font-display: ui-serif, Charter, "Iowan Old Style", "Palatino Linotype", Georgia, serif` to the `@theme inline` block (generates the Tailwind `font-display` utility). Applied to the AppShell wordmark + subtitle (rail mark = subtitle per the run interview — the brand tile is icon-only, no wordmark text) and to project names at all 3 render sites (`ProjectList.tsx` row, `ProjectDetail.tsx` breadcrumb header, `ProjectDetail.tsx` tab-rail label). - ✅ **`selasar-revamp/verify-the-existing-light-dark-system-theme-toggle-renders-correctly`** (2026-08-05) — Verified the light/dark/system toggle renders against the new values via build + structural check (the chosen mechanism — no browser/e2e infra in this repo): `tsc --noEmit` and `npm run build` clean; compiled CSS contains all 3 anchors in both `:root` (light: background `#f5f1e8`, foreground `#241e17`, primary `#8a5a3a`) and `.dark` (background `#241e17`, foreground `#f5f1e8`); `theme.tsx` mechanism untouched (`.dark` class toggle + `prefers-color-scheme` listener in auto); `font-display` utility compiled. PASS per the run interview = 3 anchors present at token level. diff --git a/docs/epics/selasar-revamp/prd-rebrand-tokens.md b/docs/epics/selasar-revamp/prd-rebrand-tokens.md index 4dc84ab..93ea4f8 100644 --- a/docs/epics/selasar-revamp/prd-rebrand-tokens.md +++ b/docs/epics/selasar-revamp/prd-rebrand-tokens.md @@ -75,12 +75,12 @@ occurrence sites are Phase 1/Phase 2 outputs, not decided yet._ ### Phase 2 — Rebrand copy audit -- [ ] Grep the repo for user-visible "LoopDeck" occurrences (component +- [x] Grep the repo for user-visible "LoopDeck" occurrences (component copy, `tauri.conf.json` window title/product name, Settings, empty states, error strings) and record the full list. -- [ ] Update `src-tauri/tauri.conf.json`'s window title and product name to +- [x] Update `src-tauri/tauri.conf.json`'s window title and product name to "Selasar". -- [ ] Update all in-app user-visible copy found in the audit to "Selasar", +- [x] Update all in-app user-visible copy found in the audit to "Selasar", leaving `.loopdeck/` directory name, `project.yaml` schema, and internal Rust/TS identifiers untouched. @@ -100,3 +100,61 @@ occurrence sites are Phase 1/Phase 2 outputs, not decided yet._ - Are there `docs/` or `README.md` references that should stay "LoopDeck" because they describe the git repository itself rather than the running app? Resolve case-by-case during the Phase 2 audit. + +## Phase 2 Audit — "LoopDeck" occurrences (2026-08-05) + +Full-repo grep of every `LoopDeck`/`loopdeck` occurrence, tagged by whether it +is user-visible copy, a comment, a test assertion, internal/on-disk state, +docs, or tooling. Loops 2–3 rename the **User-visible** set; the **Comments** +set is renamed for consistency per the Phase-2 interview; the rest is left +intact. This list is the rename source of truth for the Phase-2 update loops. + +### User-visible copy — renamed to "Selasar" +- `index.html:6` — `<title>LoopDeck` (drives the window title bar) +- `src-tauri/tauri.conf.json:3` — `"productName": "LoopDeck"` (product/bundle name) +- `src-tauri/tauri.conf.json:16` — window `"title": "LoopDeck"` +- `src-tauri/tauri.conf.json:5` — bundle `"identifier": "com.loopdeck.app"` → `com.selasar.app` (Phase-2 open-question resolution) +- `src/components/layout/AppShell.tsx:138` — sidebar wordmark text `LoopDeck` +- `src/components/shared/RootErrorBoundary.tsx:106` — "LoopDeck ran into a problem" +- `src/components/settings/Settings.tsx:161` — agent-harness hint "…the local CLI LoopDeck uses…" +- `src/components/import/ImportFlow.tsx:107` — "Pick a folder on disk. LoopDeck discovers repositories…" +- `src/components/import/NewProjectDialog.tsx:67` — "Create a fresh folder with LoopDeck project memory…" +- `src/components/detail/KnowledgeGraphPanel.tsx:100` — "…LoopDeck only reads the output…" +- `src/components/dashboard/EmptyState.tsx:18` — "…LoopDeck stores context inside each repository." +- `src-tauri/src/commands/agent.rs:1000,1011` — agent initial prompt "You are working on this LoopDeck project…" +- `src-tauri/src/run_executor.rs:152,157` — unattended-run agent prompt "…this LoopDeck project…" +- `src-tauri/src/agents.rs:844` — chat truncation marker "[LoopDeck: response truncated — …]" +- `src-tauri/src/codex_session.rs:655,745` — Codex turn error "LoopDeck does not implement …" +- `src-tauri/src/codex_session.rs:1254` — Codex `clientInfo.title: "LoopDeck"` +- `src-tauri/src/commands/run_queue.rs:1118,1127,1286,1403,1429,1436` — notification titles "LoopDeck run killed / completed / parked" +- `src-tauri/src/execution.rs:608-609` — schema-version error "newer than this LoopDeck supports…upgrade LoopDeck…" +- `src-tauri/src/permission.rs:145` — deny reason "no matching allow rule and LoopDeck is deny-by-default" +- `src-tauri/src/progress.rs:302` — exported summary header "" +- `templates/hooks/loopdeck-stop-hook.py:24` — transcript nudge "LoopDeck: if you made an architectural decision…" +- `templates/hooks/loopdeck-decisions-cap.py:72` — transcript message "LoopDeck: auto-archived N decision(s)…" +- `templates/hooks/orchestrator-start.py:58` — additional-context label "LoopDeck: .loopdeck/current-loop.md → …" +- `templates/hooks/loopdeck-memory-write.sh:68` — auto-written decisions.md context "…active on LoopDeck development." + +### Release tooling — updated to match renamed artifact +- `scripts/smoke-test-release.sh` — `LoopDeck.app` / `Contents/MacOS/LoopDeck` / `LoopDeck_*_aarch64.dmg` / `com.loopdeck.app` references updated to `Selasar.*` / `com.selasar.app` to match Loop 2's productName/identifier change; the real config-dir path `com.loopdeck.LoopDeck` (`:114`) is preserved (that on-disk path is unchanged). + +### Comments — renamed for consistency +- Frontend: `src/components/shared/RootErrorBoundary.tsx:26`, `src/components/shared/PermissionModeBadge.tsx:4`, `src/components/shared/Markdown.tsx:15`, `src/components/detail/Chat.tsx:218`, `src/components/detail/ProjectDetail.tsx:139`, `src/hooks/useStuckSessions.ts:24`, `src/types/index.ts:137,434,844,865`, `src/styles.css:175,213` +- Backend: `src-tauri/src/retry.rs:3`, `codex_session.rs:4,650,1245,1247,1264,1342`, `binary.rs:8`, `persist.rs:1`, `execution.rs:23`, `graphify.rs:8`, `harness.rs:3,93`, `agents.rs:180,205`, `runplan.rs:78`, `permission.rs:1,4,178,685,1250`, `scanner.rs:226`, `conversation.rs:143`, `claude_session.rs:531,541,1386`, `commands/agent.rs:552`, `commands/project.rs:359,530`, `skills.rs:517,1156` +- Hook-script docstrings/comments: `templates/hooks/loopdeck-stop-hook.py`, `loopdeck-memory-write.sh`, `loopdeck-dirty-flag.py`, `orchestrator-start.py`, `loopdeck-decisions-cap.py` (all `:2`-ish docstrings + inline "LoopDeck-tracked" gate comments) + +### Test assertions — updated to match renamed copy +- `src-tauri/src/skills.rs:1249` — `assert!(stop_content.contains("LoopDeck Stop hook"))` → `"Selasar Stop hook"` +- `src-tauri/src/skills.rs:1254` — `assert!(mem_content.contains("LoopDeck memory auto-write"))` → `"Selasar memory auto-write"` + +### Left intact — non-copy, on-disk paths, internal identifiers +- `src-tauri/src/config.rs:617` — `ProjectDirs::from("com","loopdeck","LoopDeck")` (global registry at `~/.config/loopdeck/config.yaml`); doc comments at `config.rs:435,501,614` and `secrets.rs:12` reference the same on-disk path +- `src-tauri/src/logging.rs:48` — `APP_NAME = "LoopDeck"` + log-dir comments (`logging.rs:10,190,193,212`) → `~/Library/Logs/LoopDeck/` +- `src-tauri/src/git.rs:495,541,586,730`, `multi_agent.rs:963`, `secret_scan.rs:210`, `run_queue.rs:1844` — `git config user.name "LoopDeck Test"` test fixtures (never user-visible) +- `.loopdeck/` directory name + `project.yaml` schema references throughout — persisted on-disk format +- Lowercase `loopdeck` identifiers: crate/package names (`Cargo.toml`, `package.json`, `package-lock.json`), IPC/store keys, skill names (`loopdeck-orchestrator`, …), api wrapper names — internal identifiers +- `src-tauri/src/codex_session.rs:1253` — `clientInfo.name: "loopdeck"` (protocol identifier; only the display `title` is renamed) + +### Docs & tooling — out of Phase-2 scope (P2 goal) +- `README.md`, `AGENTS.md`, `CLAUDE.md`, `SECURITY.md`, `docs/**`, `docs/epics/**` — project docs; left "LoopDeck" where they describe the repo/module rather than the running app +- `templates/skills/loopdeck-*`, `.agents/skills/loopdeck-*` — developer skills; internal tooling, not in-app copy diff --git a/index.html b/index.html index 641b240..3a19281 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,7 @@ - LoopDeck + Selasar
diff --git a/scripts/smoke-test-release.sh b/scripts/smoke-test-release.sh index ed4d1cc..7d4b84b 100755 --- a/scripts/smoke-test-release.sh +++ b/scripts/smoke-test-release.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# smoke-test-release.sh — verify the LoopDeck install/upgrade/reinstall/rollback +# smoke-test-release.sh — verify the Selasar install/upgrade/reinstall/rollback # contract at the file-system level. # # This is the automated half of the release smoke test defined in @@ -23,14 +23,14 @@ # # Runs anywhere; validates the file-system invariants. Fast pre-tag gate. # scripts/smoke-test-release.sh # -# # Real artifact — copy a built LoopDeck.app and also assert its bundle -# # structure (Contents/MacOS/LoopDeck + Contents/Info.plist). +# # Real artifact — copy a built Selasar.app and also assert its bundle +# # structure (Contents/MacOS/Selasar + Contents/Info.plist). # scripts/smoke-test-release.sh \ -# --app src-tauri/target/release/bundle/macos/LoopDeck.app +# --app src-tauri/target/release/bundle/macos/Selasar.app # -# # Real .dmg — mount, copy LoopDeck.app out, unmount, then assert structure. +# # Real .dmg — mount, copy Selasar.app out, unmount, then assert structure. # scripts/smoke-test-release.sh \ -# --dmg src-tauri/target/release/bundle/dmg/LoopDeck_*_aarch64.dmg +# --dmg src-tauri/target/release/bundle/dmg/Selasar_*_aarch64.dmg # # SAFETY # This script NEVER touches the real ~/Library/Application Support/..., @@ -141,7 +141,7 @@ printf 'name: smoke-repo\ndescription: hermetic smoke repo\n' > "$REPO/.loopdeck printf '# Decisions\n\n## 2026-07-23 — smoke\n- Status: accepted\n' > "$REPO/.loopdeck/decisions.md" printf '# Loops\n\n## Current\n- Status: in_progress\n' > "$REPO/.loopdeck/loops.md" # A transcript with a final user turn (simulating an interrupted run) — the -# contract says LoopDeck reconciles this on next launch; here we only assert it +# contract says Selasar reconciles this on next launch; here we only assert it # is never mutated by an install/upgrade/rollback. printf '{"type":"user","text":"hi"}\n' > "$REPO/.loopdeck/sessions/active.jsonl" @@ -173,9 +173,9 @@ make_skeleton() { # CFBundleExecutable - LoopDeck + Selasar CFBundleIdentifier - com.loopdeck.app + com.selasar.app CFBundleShortVersionString ${label} CFBundleVersion @@ -183,17 +183,17 @@ make_skeleton() { # EOF - printf '#!/bin/sh\n# LoopDeck stub binary (smoke skeleton) %s\nexit 0\n' "$label" \ - > "$app/Contents/MacOS/LoopDeck" - chmod +x "$app/Contents/MacOS/LoopDeck" + printf '#!/bin/sh\n# Selasar stub binary (smoke skeleton) %s\nexit 0\n' "$label" \ + > "$app/Contents/MacOS/Selasar" + chmod +x "$app/Contents/MacOS/Selasar" } -# Assert the bundle internal structure a real LoopDeck.app must have. +# Assert the bundle internal structure a real Selasar.app must have. assert_bundle_structure() { # local app="$1" [ -f "$app/Contents/Info.plist" ] || die "missing $app/Contents/Info.plist" - [ -f "$app/Contents/MacOS/LoopDeck" ] || die "missing $app/Contents/MacOS/LoopDeck (main binary)" - [ -x "$app/Contents/MacOS/LoopDeck" ] || die "LoopDeck binary not executable" + [ -f "$app/Contents/MacOS/Selasar" ] || die "missing $app/Contents/MacOS/Selasar (main binary)" + [ -x "$app/Contents/MacOS/Selasar" ] || die "Selasar binary not executable" ok "bundle structure valid: $app" } @@ -202,8 +202,8 @@ assert_bundle_structure() { # install_app() { # local src="$1" [ -d "$src" ] || die "source app not found: $src" - cp -R "$src" "$APPS/LoopDeck.app" - strip_quarantine "$APPS/LoopDeck.app" + cp -R "$src" "$APPS/Selasar.app" + strip_quarantine "$APPS/Selasar.app" } # Replace the installed .app with a (possibly different) source build. This is @@ -212,9 +212,9 @@ install_app() { # replace_app() { # local src="$1" [ -d "$src" ] || die "source app not found: $src" - rm -rf "$APPS/LoopDeck.app" - cp -R "$src" "$APPS/LoopDeck.app" - strip_quarantine "$APPS/LoopDeck.app" + rm -rf "$APPS/Selasar.app" + cp -R "$src" "$APPS/Selasar.app" + strip_quarantine "$APPS/Selasar.app" } # ---------------------------------------------------------------------------- @@ -245,18 +245,18 @@ if [ -n "$DMG_REAL" ]; then [ "$(uname_s)" = "Darwin" ] || die "--dmg requires macOS (hdiutil)" command -v hdiutil >/dev/null || die "hdiutil not found" [ -f "$DMG_REAL" ] || die "dmg not found: $DMG_REAL" - REAL_APP_SRC="$BUILDS/LoopDeck.app" + REAL_APP_SRC="$BUILDS/Selasar.app" mnt="$WORK/mnt" mkdir -p "$mnt" printf 'mounting %s ...\n' "$DMG_REAL" hdiutil attach -nobrowse -mountpoint "$mnt" "$DMG_REAL" >/dev/null \ || die "hdiutil attach failed for $DMG_REAL" - [ -d "$mnt/LoopDeck.app" ] || { hdiutil detach "$mnt" -quiet; die "no LoopDeck.app in dmg"; } - cp -R "$mnt/LoopDeck.app" "$REAL_APP_SRC" + [ -d "$mnt/Selasar.app" ] || { hdiutil detach "$mnt" -quiet; die "no Selasar.app in dmg"; } + cp -R "$mnt/Selasar.app" "$REAL_APP_SRC" hdiutil detach "$mnt" -quiet || true elif [ -n "$APP_REAL" ]; then [ -d "$APP_REAL" ] || die "app not found: $APP_REAL" - REAL_APP_SRC="$BUILDS/LoopDeck.app" + REAL_APP_SRC="$BUILDS/Selasar.app" cp -R "$APP_REAL" "$REAL_APP_SRC" fi @@ -270,14 +270,14 @@ if [ -n "$REAL_APP_SRC" ]; then APP_NEW="$REAL_APP_SRC" MODE="real-artifact" else - make_skeleton "$BUILDS/LoopDeck-v1.app" "0.1.0" - make_skeleton "$BUILDS/LoopDeck-v2.app" "0.1.1" - APP_PRIOR="$BUILDS/LoopDeck-v1.app" - APP_NEW="$BUILDS/LoopDeck-v2.app" + make_skeleton "$BUILDS/Selasar-v1.app" "0.1.0" + make_skeleton "$BUILDS/Selasar-v2.app" "0.1.1" + APP_PRIOR="$BUILDS/Selasar-v1.app" + APP_NEW="$BUILDS/Selasar-v2.app" MODE="hermetic" fi -printf '\n=== LoopDeck release smoke test [%s] ===\n' "$MODE" +printf '\n=== Selasar release smoke test [%s] ===\n' "$MODE" printf 'workspace: %s\n\n' "$WORK" # Baseline invariants captured before any operation. @@ -297,8 +297,8 @@ fi # ---------------------------------------------------------------------------- printf '\n[1/4] install\n' install_app "$APP_PRIOR" -[ -d "$APPS/LoopDeck.app" ] || die "install did not place LoopDeck.app" -ok "LoopDeck.app present in Applications dir" +[ -d "$APPS/Selasar.app" ] || die "install did not place Selasar.app" +ok "Selasar.app present in Applications dir" [ "$(digest "${INVARIANT_PATHS[@]}")" = "$BASE_INVARIANT" ] \ || die "install mutated user data (invariant paths changed)" [ "$(digest "$REGISTRY_PRIMARY")" = "$BASE_REGISTRY" ] \ @@ -310,8 +310,8 @@ ok "install left config dir, registry, agent_token, and .loopdeck/ untouched" # ---------------------------------------------------------------------------- printf '\n[2/4] upgrade\n' replace_app "$APP_NEW" -[ -d "$APPS/LoopDeck.app" ] || die "upgrade removed LoopDeck.app" -ok "new LoopDeck.app in place after upgrade" +[ -d "$APPS/Selasar.app" ] || die "upgrade removed Selasar.app" +ok "new Selasar.app in place after upgrade" [ "$(digest "${INVARIANT_PATHS[@]}")" = "$BASE_INVARIANT" ] \ || die "upgrade mutated user data" [ "$(digest "$REGISTRY_PRIMARY")" = "$BASE_REGISTRY" ] \ @@ -320,7 +320,7 @@ ok "upgrade left config dir, registry, agent_token, and .loopdeck/ byte-for-byte # In hermetic mode, additionally confirm the bundle actually changed. if [ "$MODE" = "hermetic" ]; then - NEW_VER="$(grep -A1 CFBundleShortVersionString "$APPS/LoopDeck.app/Contents/Info.plist" \ + NEW_VER="$(grep -A1 CFBundleShortVersionString "$APPS/Selasar.app/Contents/Info.plist" \ | grep string | sed -E 's/.*(.*)<\/string>.*/\1/')" assert_eq "$NEW_VER" "0.1.1" "upgrade installed the newer bundle (CFBundleShortVersionString)" fi @@ -372,7 +372,7 @@ printf 'workspace cleaned up: %s\n' "$WORK" if [ "$MODE" = "hermetic" ]; then printf '\nNOTE: hermetic mode validated file-system invariants only.\n' printf 'Before tagging, also run against a real build:\n' - printf ' scripts/smoke-test-release.sh --app src-tauri/target/release/bundle/macos/LoopDeck.app\n' + printf ' scripts/smoke-test-release.sh --app src-tauri/target/release/bundle/macos/Selasar.app\n' printf 'and complete the manual GUI sign-off (docs/release-pipeline.md §6b).\n' fi diff --git a/src-tauri/src/agents.rs b/src-tauri/src/agents.rs index 1336ff7..a03f5a9 100644 --- a/src-tauri/src/agents.rs +++ b/src-tauri/src/agents.rs @@ -177,7 +177,7 @@ pub enum ClaudeEvent { /// `conversation::TaskRecord` so the persisted and live shapes match. task: crate::conversation::TaskRecord, }, - /// A permission decision made by the LoopDeck policy layer in response to a + /// A permission decision made by the Selasar policy layer in response to a /// Claude `control_request`. Ephemeral — not part of the persisted /// transcript. /// @@ -202,7 +202,7 @@ pub enum ClaudeEvent { /// mutating tool without parking). The UI uses `"auto-allow"` to tag /// unattended approvals in the transcript for the morning review. decision: String, - /// Why LoopDeck allowed or denied. Empty for pending and plain allows. + /// Why Selasar allowed or denied. Empty for pending and plain allows. reason: String, }, /// An `AskUserQuestion` tool call that needs the *human's* answer before @@ -841,7 +841,7 @@ pub(crate) struct ResponseAccumulator { /// block/byte budget (PRD FR4). Visible in both the transcript and the streamed /// `ClaudeEvent::Result` so the user can tell the response was bounded. const ACCUMULATOR_TRUNCATION_MARKER: &str = - "\n\n[LoopDeck: response truncated — exceeded block or byte accumulation limit]"; + "\n\n[Selasar: response truncated — exceeded block or byte accumulation limit]"; impl ResponseAccumulator { pub(crate) fn new() -> Self { diff --git a/src-tauri/src/binary.rs b/src-tauri/src/binary.rs index f260fc0..e5e0725 100644 --- a/src-tauri/src/binary.rs +++ b/src-tauri/src/binary.rs @@ -5,7 +5,7 @@ //! module closes: //! //! 1. **cwd hijack via a relative PATH entry.** An empty or `.` component in -//! `$PATH` means "the current directory". LoopDeck spawns `claude` with +//! `$PATH` means "the current directory". Selasar spawns `claude` with //! `current_dir` set to a user-selected project and `git` against a scanned //! repo — so a project shipping a `claude`/`git` script could otherwise run //! that script, with the agent auth token in the child environment for the diff --git a/src-tauri/src/claude_session.rs b/src-tauri/src/claude_session.rs index e20c9fb..89e17d4 100644 --- a/src-tauri/src/claude_session.rs +++ b/src-tauri/src/claude_session.rs @@ -528,7 +528,7 @@ impl ClaudeSession { "stream-json", "--verbose", // Route permission prompts over stdio as `control_request` lines - // so LoopDeck can answer them via `control_response`. Without this, + // so Selasar can answer them via `control_response`. Without this, // un-approved tools would prompt the (absent) TTY and stall. "--permission-prompt-tool", "stdio", @@ -538,7 +538,7 @@ impl ClaudeSession { } // `default` permission mode: every tool call that doesn't match an // allow rule in `.claude/settings.json` emits a `control_request` - // that LoopDeck decides (floor → manual approval → auto-policy). + // that Selasar decides (floor → manual approval → auto-policy). // This is the honest single-source-of-truth: nothing is silently // auto-approved by Claude itself. Earlier iterations used // `acceptEdits`, which auto-approves Edit/Write/NotebookEdit inside @@ -1383,7 +1383,7 @@ impl ClaudeSession { /// `plan_mode` mirrors Claude Code's own shift-tab toggle: when true, the /// CLI restricts the model to read-only tools plus `ExitPlanMode` (which /// `answer_plan_approval` intercepts) for the duration of plan mode — - /// entirely client-enforced, not something LoopDeck's permission layer has + /// entirely client-enforced, not something Selasar's permission layer has /// to police. /// /// Tracks the last mode we asked for in `plan_mode_active` so this is a diff --git a/src-tauri/src/codex_session.rs b/src-tauri/src/codex_session.rs index 74067b3..f850094 100644 --- a/src-tauri/src/codex_session.rs +++ b/src-tauri/src/codex_session.rs @@ -1,7 +1,7 @@ //! Persistent Codex app-server adapter. //! //! The app-server protocol is newline-delimited JSON-RPC over stdio. One -//! process owns one LoopDeck project thread; turns reuse that thread, while a +//! process owns one Selasar project thread; turns reuse that thread, while a //! persisted `codex:` resumes it after an app restart. use crate::agents::{ @@ -647,12 +647,12 @@ impl CodexSession { ); // Code Mode's host currently owns execution. This response is // retained as a truthful fallback for client-declared dynamic - // tools that LoopDeck has not registered. + // tools that Selasar has not registered. self.write_message(json!({ "id": id, "error": { "code": -32601, - "message": "LoopDeck does not implement client-declared dynamic tools" + "message": "Selasar does not implement client-declared dynamic tools" } })) .await?; @@ -742,7 +742,7 @@ impl CodexSession { "id": id, "error": { "code": -32601, - "message": format!("LoopDeck does not implement {method}") + "message": format!("Selasar does not implement {method}") } })) .await?; @@ -1242,16 +1242,16 @@ fn tool_from_item(item: &Value) -> Option<(String, Value)> { } } -/// Build the app-server capability contract advertised by LoopDeck. +/// Build the app-server capability contract advertised by Selasar. /// -/// Code Mode's client-hosted dynamic tools are experimental. LoopDeck does +/// Code Mode's client-hosted dynamic tools are experimental. Selasar does /// not provide their JavaScript runtime, so opting in can leave a turn waiting /// for a tool result that it cannot produce. fn initialize_params() -> Value { json!({ "clientInfo": { "name": "loopdeck", - "title": "LoopDeck", + "title": "Selasar", "version": env!("CARGO_PKG_VERSION") }, "capabilities": { "experimentalApi": false } @@ -1261,7 +1261,7 @@ fn initialize_params() -> Value { /// Build the per-turn security boundary and optional model overrides. /// /// `readOnly` is intentional even for autonomous projects. It makes Codex -/// request approval before commands or edits, allowing LoopDeck's +/// request approval before commands or edits, allowing Selasar's /// `PermissionPolicy` to decide whether to park for the user or auto-allow, /// while always retaining the destructive-command floor. fn turn_start_params( @@ -1339,7 +1339,7 @@ fn approval_tool_context( /// Return an immediate policy decision, or `None` when the user must decide. /// /// The destructive floor is evaluated before autonomous mode so autonomy can -/// never bypass LoopDeck's hard-deny rules. +/// never bypass Selasar's hard-deny rules. fn automatic_permission_decision( policy: &PermissionPolicy, tool_name: &str, diff --git a/src-tauri/src/commands/agent.rs b/src-tauri/src/commands/agent.rs index f051186..ae99d94 100644 --- a/src-tauri/src/commands/agent.rs +++ b/src-tauri/src/commands/agent.rs @@ -549,7 +549,7 @@ pub async fn agent_answer_plan( /// Persist a permission allow-rule into the project's `.claude/settings.local.json`. /// /// "Always allow" affordance for the manual-approval card: alongside the -/// per-call Allow/Deny verdict, the user can ask LoopDeck to remember the +/// per-call Allow/Deny verdict, the user can ask Selasar to remember the /// decision for future calls of the same tool/command. This writes the rule /// into `permissions.allow[]` of the **local** settings file (gitignored by /// Claude Code convention — machine-specific, never shared), deduped against @@ -997,7 +997,7 @@ pub(crate) fn build_next_loop_prompt(path: &Path) -> (String, Option) { match next_step { Some(step) => ( format!( - "You are working on this LoopDeck project. Use the `loopdeck-orchestrator` \ + "You are working on this Selasar project. Use the `loopdeck-orchestrator` \ skill conventions. Read `.loopdeck/loops.md` for full context. The next \ unchecked step is: \"{step}\". Implement it. When done, update \ `.loopdeck/loops.md` (mark the step `[x]`, refresh `## Current`) and \ @@ -1008,7 +1008,7 @@ pub(crate) fn build_next_loop_prompt(path: &Path) -> (String, Option) { ), None => ( String::from( - "You are working on this LoopDeck project. Use the `loopdeck-orchestrator` \ + "You are working on this Selasar project. Use the `loopdeck-orchestrator` \ skill conventions. Review `.loopdeck/loops.md`, then propose and start \ the next loop. When done, update `.loopdeck/loops.md` (refresh \ `## Current`, add new steps under `## Next Steps`) and append any \ diff --git a/src-tauri/src/commands/project.rs b/src-tauri/src/commands/project.rs index 79393a0..31a6963 100644 --- a/src-tauri/src/commands/project.rs +++ b/src-tauri/src/commands/project.rs @@ -356,7 +356,7 @@ pub async fn update_description( /// Set the per-project autonomous-mode flag in the config registry. /// -/// When true, the project's LoopDeck-spawned agent self-approves +/// When true, the project's Selasar-spawned agent self-approves /// floor-clearing tool calls (Edit/Write, safe Bash, MCP, WebFetch) so loops /// can run unattended — the user reviews the resulting PRs instead of each /// tool call. The destructive floor (`rm -rf`, force-push, `curl|sh`, `sudo`, @@ -527,7 +527,7 @@ pub async fn open_in_terminal(path: String, state: State<'_, AppState>) -> Resul let mut cmd = std::process::Command::new(term); cmd.arg("--working-directory").arg(&path_str); // Detach the terminal into its own process group so it keeps running - // independently of LoopDeck (won't receive SIGHUP when we exit). + // independently of Selasar (won't receive SIGHUP when we exit). cmd.process_group(0); if cmd.spawn().is_ok() { spawned = true; diff --git a/src-tauri/src/commands/run_queue.rs b/src-tauri/src/commands/run_queue.rs index ff2fcf1..1c695f6 100644 --- a/src-tauri/src/commands/run_queue.rs +++ b/src-tauri/src/commands/run_queue.rs @@ -1115,7 +1115,7 @@ async fn execute_run( notify_run_terminal( app, root, - "LoopDeck run killed", + "Selasar run killed", "Total run wall-clock budget exceeded", ); return Ok(()); @@ -1124,7 +1124,7 @@ async fn execute_run( kill_batch(&mut plan, &batch, "run cancelled"); plan.environment.worktree_kept = true; runplan::save(root, &plan)?; - notify_run_terminal(app, root, "LoopDeck run killed", "Run was cancelled"); + notify_run_terminal(app, root, "Selasar run killed", "Run was cancelled"); return Ok(()); } @@ -1283,7 +1283,7 @@ async fn execute_run( notify_run_terminal( app, root, - "LoopDeck run killed", + "Selasar run killed", "Phase token budget exceeded", ); return Ok(()); @@ -1400,7 +1400,7 @@ async fn execute_run( notify_run_terminal( app, root, - "LoopDeck run killed", + "Selasar run killed", "Phase wall-clock budget exceeded", ); } @@ -1426,14 +1426,14 @@ async fn execute_run( notify_run_terminal( app, &plan.project, - "LoopDeck run completed", + "Selasar run completed", "All phases passed — morning report ready for review", ); } else if any_parked { notify_run_terminal( app, &plan.project, - "LoopDeck run parked", + "Selasar run parked", "Phases need attention — open the morning report to review parked items", ); } diff --git a/src-tauri/src/conversation.rs b/src-tauri/src/conversation.rs index 083ab5b..7451516 100644 --- a/src-tauri/src/conversation.rs +++ b/src-tauri/src/conversation.rs @@ -140,7 +140,7 @@ pub struct ConversationTurn { /// - `"user"` (default): the human typed it into the composer. /// - `"loop"`: the backend auto-built it from `.loopdeck/loops.md` when the /// user clicked "Start next loop". These prompts are long boilerplate - /// ("You are working on this LoopDeck project… The next unchecked step + /// ("You are working on this Selasar project… The next unchecked step /// is: …") that the human never wrote — without a marker they're /// indistinguishable from real messages and drown out typed ones. /// Absent on assistant turns and on user turns written before this diff --git a/src-tauri/src/execution.rs b/src-tauri/src/execution.rs index ade392f..c6fd505 100644 --- a/src-tauri/src/execution.rs +++ b/src-tauri/src/execution.rs @@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::path::{Path, PathBuf}; -/// Schema version this LoopDeck writes and reads. A file whose +/// Schema version this Selasar writes and reads. A file whose /// `schema_version` differs is handled read-only — it is never rewritten. pub const CURRENT_SCHEMA_VERSION: u32 = 1; @@ -605,8 +605,8 @@ fn check_schema_version(version: u32, path: &Path) -> Result<(), AppError> { if version > CURRENT_SCHEMA_VERSION { Err(AppError::ExecutionState(format!( "execution state at {where_} uses schema_version {version}, newer than this \ - LoopDeck supports ({CURRENT_SCHEMA_VERSION}). The file was not modified — \ - upgrade LoopDeck to read it." + Selasar supports ({CURRENT_SCHEMA_VERSION}). The file was not modified — \ + upgrade Selasar to read it." ))) } else { Err(AppError::ExecutionState(format!( diff --git a/src-tauri/src/graphify.rs b/src-tauri/src/graphify.rs index 7175c28..3b88377 100644 --- a/src-tauri/src/graphify.rs +++ b/src-tauri/src/graphify.rs @@ -5,7 +5,7 @@ //! project it writes `graphify-out/graph.json` (plus `graph.html` and //! `GRAPH_REPORT.md`) into the project root. //! -//! LoopDeck does **not** run Graphify and takes no dependency on Python or the +//! Selasar does **not** run Graphify and takes no dependency on Python or the //! Graphify CLI. This module only reads the JSON metadata that Graphify, if //! installed, has already produced — so the integration is detect-and-surface //! only. If the file is absent or unparseable, every accessor returns a diff --git a/src-tauri/src/harness.rs b/src-tauri/src/harness.rs index 935ffc4..9c6e665 100644 --- a/src-tauri/src/harness.rs +++ b/src-tauri/src/harness.rs @@ -1,6 +1,6 @@ //! Provider-neutral agent session used by the command layer. //! -//! Claude and Codex expose different wire protocols, but LoopDeck's UI expects +//! Claude and Codex expose different wire protocols, but Selasar's UI expects //! one stable stream (`ClaudeEvent`) and one stable terminal response //! (`AgentResponse`). This enum keeps that protocol detail behind a small //! delegation surface so commands, transcript persistence, retry handling, and @@ -90,7 +90,7 @@ impl HarnessSession { ) -> Result { match config.harness { AgentHarness::Claude => { - // Codex ids are explicitly tagged in LoopDeck transcripts. + // Codex ids are explicitly tagged in Selasar transcripts. // Never pass one to Claude's `--resume`. let resume = resume_session_id.filter(|id| !id.starts_with("codex:")); HarnessAdapter::spawn(cwd, config, resume, policy).map(Self::Claude) diff --git a/src-tauri/src/permission.rs b/src-tauri/src/permission.rs index 3a95a26..62207c5 100644 --- a/src-tauri/src/permission.rs +++ b/src-tauri/src/permission.rs @@ -1,7 +1,7 @@ -//! Tool-permission policy for the LoopDeck-spawned Claude agent. +//! Tool-permission policy for the Selasar-spawned Claude agent. //! //! When Claude emits a `control_request` (because a tool call didn't match a -//! `.claude/settings.json` allow rule), this module decides whether LoopDeck +//! `.claude/settings.json` allow rule), this module decides whether Selasar //! answers `allow` or `deny`. The decision is the single source of truth that //! `ClaudeSession` writes back as a `control_response`. //! @@ -142,7 +142,7 @@ impl PermissionPolicy { match self.mode { PermissionMode::ConfirmChanges | PermissionMode::Autonomous => Decision::Allow, PermissionMode::Deny => Decision::Deny(String::from( - "no matching allow rule and LoopDeck is deny-by-default", + "no matching allow rule and Selasar is deny-by-default", )), } } @@ -175,7 +175,7 @@ const MANUAL_APPROVAL_TOOLS: &[&str] = &["Bash", "Edit", "Write", "NotebookEdit" /// how". /// /// **MCP tools** (`mcp____`) are always gated. Their capabilities -/// are unknown to LoopDeck — a server can expose anything from a read-only +/// are unknown to Selasar — a server can expose anything from a read-only /// lookup to a mutating GitHub `create_pull_request` — so the safe default is /// to ask. This also matches Claude Code's own posture, which prompts on every /// MCP call regardless of permission mode. Read-only MCP tools can be added to @@ -682,7 +682,7 @@ mod tests { #[test] fn mcp_tools_require_approval_regardless_of_capability() { - // MCP tool capabilities are opaque to LoopDeck — a server can expose + // MCP tool capabilities are opaque to Selasar — a server can expose // anything from a read-only lookup to a mutating create_pull_request. // The safe default is to gate every mcp__* call; read-only ones can be // allow-listed in .claude/settings.json to short-circuit the prompt. @@ -1247,7 +1247,7 @@ mod tests { // MCP tools: always gated regardless of perceived capability — a server // can expose anything from a read-only lookup to a mutating - // create_pull_request, and LoopDeck can't tell from the tool name. + // create_pull_request, and Selasar can't tell from the tool name. for mcp in [ "mcp__github__create_pull_request", "mcp__filesystem__read_file", diff --git a/src-tauri/src/persist.rs b/src-tauri/src/persist.rs index 2226f07..39fa946 100644 --- a/src-tauri/src/persist.rs +++ b/src-tauri/src/persist.rs @@ -1,4 +1,4 @@ -//! Atomic file writes for critical LoopDeck state. +//! Atomic file writes for critical Selasar state. //! //! `std::fs::write` is truncate-then-write: a crash, full disk, or OS-dropped //! write between the open and the final byte leaves a partial file. For diff --git a/src-tauri/src/progress.rs b/src-tauri/src/progress.rs index f3b5489..68733a0 100644 --- a/src-tauri/src/progress.rs +++ b/src-tauri/src/progress.rs @@ -299,7 +299,7 @@ pub fn export_markdown(repo_path: &Path) -> Result { fn render_markdown(epics: &[Epic], snapshot: &ProgressSnapshot) -> String { let mut out = String::from( - "\n\n# Execution Summary\n\n", + "\n\n# Execution Summary\n\n", ); for epic in epics { let count = snapshot.epics.get(&epic.slug).cloned().unwrap_or_default(); diff --git a/src-tauri/src/retry.rs b/src-tauri/src/retry.rs index d3864fa..a7cb1f3 100644 --- a/src-tauri/src/retry.rs +++ b/src-tauri/src/retry.rs @@ -1,6 +1,6 @@ //! Retry policy for transient gateway errors (e.g. `529 overloaded`). //! -//! LoopDeck doesn't call the LLM gateway directly — it spawns the `claude` CLI +//! Selasar doesn't call the LLM gateway directly — it spawns the `claude` CLI //! subprocess, and a gateway failure surfaces as an //! `AgentResponse { is_error: true, result: "" }`. A //! `529` from `api.z.ai` (or any Anthropic-compatible gateway) arrives as text diff --git a/src-tauri/src/run_executor.rs b/src-tauri/src/run_executor.rs index 1d1f598..1d3d2b3 100644 --- a/src-tauri/src/run_executor.rs +++ b/src-tauri/src/run_executor.rs @@ -149,12 +149,12 @@ pub(crate) fn build_combined_phase_prompt( budgets: ResolvedBudgets, ) -> String { let mut prompt = if phases.len() == 1 { - "You are working on this LoopDeck project as part of an unattended \ + "You are working on this Selasar project as part of an unattended \ overnight run. Use the `loopdeck-orchestrator` skill conventions." .to_string() } else { format!( - "You are working on this LoopDeck project as part of an unattended \ + "You are working on this Selasar project as part of an unattended \ overnight run. Use the `loopdeck-orchestrator` skill conventions. \ This single session covers {count} queued loops — implement all of \ them below, in order, one after another, before running \ diff --git a/src-tauri/src/runplan.rs b/src-tauri/src/runplan.rs index 82c93d9..0632161 100644 --- a/src-tauri/src/runplan.rs +++ b/src-tauri/src/runplan.rs @@ -75,7 +75,7 @@ pub enum InterviewStatus { Skipped, } -/// Queue-time consent for the whole run (ADR-1). LoopDeck never asks again +/// Queue-time consent for the whole run (ADR-1). Selasar never asks again /// once the run starts. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct RunConsent { diff --git a/src-tauri/src/scanner.rs b/src-tauri/src/scanner.rs index a906dfb..2dbdede 100644 --- a/src-tauri/src/scanner.rs +++ b/src-tauri/src/scanner.rs @@ -223,7 +223,7 @@ fn scan_directory_bounded( let has_loopdeck = dir_path.join(".loopdeck").join("project.yaml").exists(); - // Graphify is an optional, externally-managed producer — LoopDeck only + // Graphify is an optional, externally-managed producer — Selasar only // reads its output. Check via the shared helper so the path layout // lives in one place (`graphify::is_present`). let has_graphify = crate::graphify::is_present(dir_path); diff --git a/src-tauri/src/skills.rs b/src-tauri/src/skills.rs index 0994b4c..805febd 100644 --- a/src-tauri/src/skills.rs +++ b/src-tauri/src/skills.rs @@ -514,7 +514,7 @@ pub fn setup_hooks(repo_path: &Path) -> Result<(), AppError> { // list of known-safe read commands means the common dev-loop traffic // (ls, git status, file reads) short-circuits the control protocol // entirely — so it neither stalls nor clutters the permission log/UI. - // Anything not on this list routes through LoopDeck's policy + // Anything not on this list routes through Selasar's policy // (destructive floor -> MANUAL_APPROVAL_TOOLS interception -> auto-allow). // // **What is deliberately NOT here (Phase 1, PRD FR1):** @@ -1153,7 +1153,7 @@ mod tests { assert!(has("Bash(git status:*)"), "vcs inspection missing"); // Phase 1 (PRD FR1): broad mutation + build-runner rules must NOT be - // seeded — they bypass LoopDeck's manual-approval card at the Claude + // seeded — they bypass Selasar's manual-approval card at the Claude // layer. Users add narrow rules via the approval card's "Always allow" // button instead. assert!(!has("Edit(*)"), "broad Edit rule must NOT be seeded"); @@ -1246,12 +1246,12 @@ mod tests { let stop_py = hooks_dir.join("loopdeck-stop-hook.py"); assert!(stop_py.exists()); let stop_content = fs::read_to_string(&stop_py).unwrap(); - assert!(stop_content.contains("LoopDeck Stop hook")); + assert!(stop_content.contains("Selasar Stop hook")); let mem_sh = hooks_dir.join("loopdeck-memory-write.sh"); assert!(mem_sh.exists()); let mem_content = fs::read_to_string(&mem_sh).unwrap(); - assert!(mem_content.contains("LoopDeck memory auto-write")); + assert!(mem_content.contains("Selasar memory auto-write")); let orch_py = hooks_dir.join("orchestrator-start.py"); assert!(orch_py.exists()); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 0c386d3..2608725 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,8 +1,8 @@ { "$schema": "https://raw.githubusercontent.com/nicoverbruggen/tauri-v2-schema/refs/heads/main/schema.json", - "productName": "LoopDeck", + "productName": "Selasar", "version": "0.4.0", - "identifier": "com.loopdeck.app", + "identifier": "com.selasar.app", "build": { "beforeDevCommand": "npm run dev", "devUrl": "http://localhost:1420", @@ -13,7 +13,7 @@ "windows": [ { "label": "main", - "title": "LoopDeck", + "title": "Selasar", "width": 1500, "height": 1000, "resizable": true, diff --git a/src/components/dashboard/EmptyState.tsx b/src/components/dashboard/EmptyState.tsx index 8f82bcf..a2c384b 100644 --- a/src/components/dashboard/EmptyState.tsx +++ b/src/components/dashboard/EmptyState.tsx @@ -15,7 +15,7 @@ export function EmptyState({ onScan, onNewProject }: EmptyStateProps) {

No projects found

Scan a folder to discover repositories and create project memory, or start a - brand-new project from scratch. LoopDeck stores context inside each repository. + brand-new project from scratch. Selasar stores context inside each repository.

- LoopDeck + Selasar Engineering Cockpit diff --git a/src/components/settings/Settings.tsx b/src/components/settings/Settings.tsx index 0401875..cf903a8 100644 --- a/src/components/settings/Settings.tsx +++ b/src/components/settings/Settings.tsx @@ -158,7 +158,7 @@ export function Settings() {