mirror of
https://github.com/NeuralNomadsAI/CodeNomad.git
synced 2026-10-21 22:02:03 +00:00
17 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f314123dd1
|
fix(opencode): qualify and require 2.1.2 for correct Code Mode execution (#1078)
Raise the approved external runtime minimum and recommendation to 2.1.2 after reproducing incorrect native Code Mode job ordering on 2.1.0/2.1.1. Keep the independently qualified 2.1.0 client/plugin build pins and preserve bounded contract recognition for custom/future runtimes. Add the real isolated execute regression to the minimum/latest compatibility matrix, align supported installer fixtures without weakening assertions, and update setup/help in all ten locales. Two author-side review passes found no blockers; the final focused set passes 93/93 and native Code Mode passes. Qualification includes builds/typechecks, UI/browser, native pruning/Missions/recurrence, migrations and isolated installation/upgrade. Record the broad server shutdown timeout and its two unchanged isolated passes precisely. Admin merge explicitly authorized by the maintainer without waiting for CI. |
||
|
|
6a6367b560
|
chore(opencode): retire adaptations for runtimes and events OpenCode V2 no longer produces (#1034)
## Summary This PR removes OpenCode compatibility code that nothing can reach any more: - Code that was already dead at the former 2.0.27 minimum, and is still dead at the current 2.1.0 minimum (#1029). - Handlers for events and data shapes that OpenCode V2 never produces. Each item was checked against the upstream 2.0.27 and 2.1.0 sources before removal. Kept on purpose: - Workarounds for upstream bugs or limits that are still present in 2.1.0. - Code that reads conversations written by older runtimes: V1-migrated tool names and metadata, `workspaceID` data, task summary titles, `session-legacy` replay. - Code that recognises and upgrades old CLIs and live older daemons: 1.x replacement, beta recognition, 2.0.11 service discovery, 2.0.15 native upgrade, `/api/status` and `/api/health` identification. ## Removed or changed **Server** - Negotiation: one "not modern → `canonical_api`" rule replaces the pre-2.0.4 legacy schema recognition, and runs before #1029's `native_contract` check. - The transport no longer rewrites `/api/status`. - Desktop skills no longer send the pre-2.0.4 `location` and `slash` fields. - The legacy `auth.json` usage fallback for daemons without `credential.list` (pre-2.0.20) is removed, along with its UI reason and the i18n key in 10 locales. A missing endpoint still fails safely. - Workspace selectors are rejected up front, without a native resolution request. - CLI service probes try `/api/info` first. An admitted daemon no longer costs two authenticated 404s on every check. **UI** - Remaining V1 `session.idle`/`session.status` branches: Missions store, pending discovery (UI and server), `eventAffectsMessages`. - `server.instance.disposed` and the now-unused `rehydrateInstance`. - The V1 `worktree.ready` envelope (the handler now reads the V2 shape). - V1 tool-state titles and the `success` status alias. - Part `time.start` and `time.end`. - Text stored as objects or segment arrays. - `deriveMessageStatus`. - The V1 `error.data.message` shape. - `projectID` and `location` fallbacks on `session.created`. - The replay-only `session.message.content.updated`. - The unreachable `output.answers` fallback. **Fixtures, Missions and docs** - Legacy branches removed from the location, fork, families, pruning and automation native fixtures. The WSL setup fixture now compares against the reported version instead of 2.0.11. - Unused 2.0.21 launch helpers removed. - The Missions native and trajectory fixtures also run on the minimum lane. - The capability proof checks the reported version. - Stale 2.0.2x labels now say "as of the 2.1.0 minimum". **Follow-ups from the #1029 post-merge review** - Test fixtures no longer send the ignored `recent: ""` compaction field (18 sites). - The manual compaction-isolation fixture accepts any published version at or above the minimum. - `CONTRIBUTING.md` wording updated. 114 files, +319 / −1117: source +90 / −487, tests/fixtures/CI +214 / −604, i18n −10, docs +15 / −16. ## Validation (rebased on dev with #1029) **Typechecks:** server and UI pass. **Server tests** - Touched areas: 480/480. - Full server CI step: 2430 pass, 0 fail, 7 skipped, 1 cancelled. The cancelled test is the `index.test.ts` real-process shutdown test; it hit its 5 s timeout under load. It passes alone (4/4), and that file is unchanged versus dev. **UI unit tests** - Touched files: 230/230. - CI steps: 574/574, 200/200 and 519/519. **Browser suites**, one at a time: - Provider and service usage: provider-usage 13/13, service-usage 3/3. - Missions: mission-visibility 3/3, mission-control-feedback 5/5, mission-lifecycle-revision 10/10, mission-lifecycle-navigation 10/10, mission-current-passage 1/1, mission-native-family 11/11. - Transcript and rendering: compaction-responsiveness 5/5, session-rendering 47/47, reasoning-collapse 3/3, render-cost 17/17, tool-images 4/4, system-messages 10/10. - Other: search-highlight 11 pass (1 skipped by its env gate), panel-extensions 13/13. **Native fixtures on an isolated 2.1.0 CLI:** location, session-fork, automation, session-pruning, missions native, missions trajectory, provider-usage, Missions capability proof and compaction-isolation all pass. The WSL setup fixture was not run (it needs a WSL distro with a Linux CLI). ## Left for later - `RuntimeIdentity.discovery` is now write-only. - `ownsLocation` has an unused `_client` parameter (about 30 callers). - A test-only V1 translation in `auto-accept-manager.test.ts`. - Out of scope: HTML-entity decoding (a product decision), the `MutableHashMap` loop, the pruning-UI import-order workaround, unused log-based Missions readers, and the unshipped managed-owner module with its 2.0.24-pinned test. Oversized source files touched: `stores/instances.ts` ~2,209, `message-block.tsx` ~1,601, `workspaces/manager.ts` ~1,104, `tool-call.css` ~1,047, `tool-call.tsx` ~865, `opencode-data.ts` ~865, `api-types.ts` ~784, `session-events.ts` ~606, `recurring-day-fixture.ts` ~535. |
||
|
|
d6a890fba7
|
chore(opencode): qualify 2.1.0 and adopt its native contracts (#1029)
Adopt the OpenCode 2.1 native replay and compaction contracts, align client/plugin pins and set minimum and recommended runtime to 2.1.0. Preserve authenticated contract recognition for future/custom runtimes and explicit installation/restart boundaries. Preserve historical conversations through official projection-based pruning revisions and independently checked migrations from 2.0.3, beta-19271 and 2.0.32. Retain ownership, execution claims, stale-selection checks and transaction fences. Update setup, help and qualification evidence. Isolated Windows native qualification and integration checks cover pruning UI, historical reimport, Compare/Wayfinder, recurring Missions, builds and typechecks. Document broad-suite limitations and outstanding platform/package/mobile acceptance; this merge does not publish CodeNomad 1.0.0. |
||
|
|
1ce629b9a6
|
docs(sidecars): document SideCars as trusted same-origin extensions (#1001)
## Summary Documentation only. SideCars are now documented as **trusted same-origin extensions** of CodeNomad, replacing the "temporary exception / isolation follow-up" wording introduced with #994. ## Why The isolation follow-up was prototyped, measured and reviewed, then rejected: - **Opaque sandbox:** the frame loses cookies and storage, so the service's own login and state break. - **Separate origin:** keeping service cookies requires a same-site origin (another port or subdomain). Chromium still sends the application's `Lax` cookie across ports of the same host, and CORS alone did not block authenticated writes, so every API would need an origin barrier. - **Per-view ports:** these are unreachable through a single exposed port, reverse proxy or tunnel, and reset service storage on every opening. - **IP and single port:** with a literal IP and one exposed port, no frame topology gives both isolation and working `Lax` cookies. ## Changes - **`dev-docs/architecture.md`:** records the decision and these constraints. - **`AGENTS.md` and the architecture-guide `desktop-conventions.md`:** refer to the decision instead of a pending prototype. - **`CONTRIBUTING.md`:** no longer claims SideCar frames are sandboxed. - **`README.md`:** tells users to add only services whose content they trust. The #995 cookie filtering stays as is; no behavior change. |
||
|
|
db6685cb55
|
fix(workspaces): closing a project tab closes the project in CodeNomad (#970)
## Problem
Closing a project tab only hid it in that window. The backend workspace
record kept routing the folder's events, notifications, auto-accept and
pending-request recovery, invisibly, until the palette-only **Stop
Workspace** command was run on the active tab. That command still showed
the V1 message "Stop OpenCode instance? This will stop the server."
although V2 has one shared OpenCode service, and it called
`debug.location.evict`, which (per OpenCode source) rejects pending
permissions, cancels pending Forms, fails plugin RPC and kills terminals
of that directory, even for sessions started elsewhere. OpenCode loads
locations on demand and unloads idle ones itself.
## Change
- **Closing a project tab** (×, Ctrl/Cmd+W) removes that tab's backend
workspace record. CodeNomad stops following it; sessions keep running in
OpenCode and reappear when the project is reopened.
- **Another tab of the same folder** has its own record and is
unaffected.
- **The same record shown in another window**: that window's tab closes
through the existing `workspace.stopped` broadcast, with an info
notification ("closed from another window"); the initiating window shows
nothing.
- **CodeNomad never evicts OpenCode locations**: eviction, its
serialization helpers and `locationOwned` bookkeeping are removed. A
failed launch now always removes its logical record (the retention only
existed to retry a failed eviction).
- **Stop Workspace removed** (command, confirm dialog, i18n keys in all
locales).
- Unchanged: opening an open project still offers a new tab (recent row)
or switching (switch button); temporary projects keep Keep / Discard /
Cancel; window close, app quit, reload, restore and backend shutdown
delete nothing; disconnected-instance dismissal stays local.
- Delete failure: error toast, record kept and reachable from the home
page, no automatic retry.
## Docs
Help in all 10 locales (`projects`, `index`, `desktop`, `server`,
`opencode`, `missions`), `AGENTS.md`, `CONTRIBUTING.md`,
`dev-docs/architecture.md`, `packages/server/README.md` and the
architecture-guide skill now describe the new contract.
## Validation
- UI store tests (`--conditions=browser`): app-tabs,
temporary-instances, workspace-list-reconciliation-fence,
instances-restore-ownership — 30/30.
- Server: manager + shared service 54/54; event ownership and workspace
identity suites pass.
- New real-component browser regression (click ×, Ctrl+W, Cmd+W): 3/3;
project restoration (Electron/Tauri) and new-instance launcher browser
suites pass.
- `npm run test:help` 9/9 (250 pages); UI, server and Electron
typechecks.
|
||
|
|
8e8ca15934
|
chore(opencode): qualify runtime 2.0.29 and align client/plugin pins (#948)
## Summary - Recommend and pin OpenCode **2.0.29** (`@opencode/client`, `@opencode/plugin`); the technical minimum stays **2.0.27** since 2.0.28/2.0.29 keep Effect 4.0.1. - Add 2.0.29 as a reviewed contract profile beside 2.0.27; 2.0.28 and future/custom labels keep authenticated negotiation. - Test fixture only: the recurring Missions host declares the `credential` domain that the 2.0.29 Promise adapter reads eagerly (the managed owner spreads `ctx`, dropping the Proxy fallback). No product code change. - Two new isolated fixtures for upstream behavior changes: bounded output-length continuation, and rejected Promise tools / native denial. - Compatibility docs, CONTRIBUTING, AGENTS and architecture guide updated. ## Upstream review - OpenAPI: same 118 paths; additive schema changes (config `policies`, provider/model `compatibility`, `encoding`). - Private LocationServiceMap/Form/Permission/queue contracts used by the pending snapshot: unchanged. - Effect stays 4.0.1. ## Validation (Windows, isolated CLIs/databases, never the shared daemon) - 2.0.29: plugin runtime, automation, pruning/history/proxy, Missions contract/family control/full journey, session environment, fork, aside, prompt skills, Git degraded/init, provider usage/accounts, temporary workspaces, blank-session cleanup, output-limit continuation, Promise tool failure, system settings discovery, native upgrade 2.0.15→2.0.29. - 2.0.27 (minimum): plugin runtime, automation, pruning, Missions contract/family, session environment, fork, aside, prompt skills, blank cleanup. - Server: 2235 passed / 7 skipped / 0 failed. UI: 1524 passed. Tauri crate 268/268, updater handoff 1/1, UI updater flow 13/13 (dev base includes #786). ## Known, not caused by this change `scripts/test-permission-receipts-native.mjs` times out identically on 2.0.27 with the previous pins; tracked separately. |
||
|
|
dd5a1f387d
|
fix(opencode): share host plugin runtime and require 2.0.27 (#920)
## Résultat Corrige le chargement des plugins CodeNomad avec OpenCode 2.0.27 et établit cette version comme minimum pour les prochaines releases et les prereleases dev. Aucun déploiement de l’application active ni redémarrage du daemon partagé. ## Cause démontrée - Le runtime natif passe d’Effect 4.0.0-rc.112 à 4.0.1. Le bundle précédent reproduit `cache.stackFrame` sur une CLI 2.0.27 isolée. - Embarquer Effect 4.0.1 ne préserve pas la 2.0.26 : échec inverse `cache.scheduler`. - Les schémas 2.0.27 consomment `Schema.isStartingWith`, absent du moteur 2.0.26. Le plancher est fondé sur cette rupture mesurée, pas sur une liste de versions testées. ## Implémentation - Pins client/plugin synchronisés à 2.0.27 ; Effect et le SDK public des plugins sont fournis par OpenCode, hors bundles natifs pruning/Missions/automation. - Réglages de build partagés et régression qui interdit une seconde copie du runtime ; smoke natif ajouté à la matrice minimum/latest. - Diagnostic `plugin_runtime` traduit dans les dix locales ; versions futures et personnalisées conservent la reconnaissance authentifiée du contrat. - Adaptations du SDK : annulation des lectures projet, références de credentials externes et connexion fournisseur externe avec formulaire natif, sans fallback OAuth/API key ni rejeu. - Le runtime OpenTunnel du backend reste isolé et inchangé. Aucun tunnel, route ou identité distant n’est modifié. ## Validation locale - Échec reproduit sur 2.0.26 et réussite sur 2.0.27 pour les variantes de bundle comparées. - Suites natives isolées automation, pruning/historique/proxy/concurrence/redémarrage et Missions réussies sur 2.0.27. - Régressions ciblées de build, store/serveur et navigateur (diagnostic du minimum, connexion externe et brouillon conservé) réussies ; typechecks UI/serveur/Electron/OpenTunnel réussis. - Suite serveur complète et CI multiplateforme encore en validation à l’ouverture ; aucun résultat entièrement vert anticipé. La revue gatekeeper indépendante sera publiée ici avant fusion. Les anciennes preuves de qualification restent historiques, pas une promesse de support des moteurs antérieurs au nouveau plancher. |
||
|
|
81fb513558
|
feat(missions): native project coordination, briefings and tracking (#866)
# Missions: product specification ## Product goal Missions coordinates complex work through native OpenCode conversations. CodeNomad provides creation, controls, human attention and result reading; OpenCode owns execution. One-time objectives and finite daily recurring passages share the same planning and reading experience. No OpenCode modification is required. ## Create and configure - **Flexible mission**: free-form objectives and bounded delegation. - **Debugging**: diagnosis, implementation, independent standards/specification reviews and fresh validation. - **Exploration**: bounded decisions and parallel investigation, with explicit native human questions where required. Creation presents an objective, a short optional title, verbatim working notes, coordinator/task profiles and native or independent task-session policy. Optional choices stay collapsed. A single **Create** button saves a prepared one-time mission or paused recurring schedule without starting anything. **Play** is a separate explicit action for both. Settings → Missions contains defaults for **all new missions**, with optional exceptions for each of the three types, including Flexible. A type exception overrides the global value; an unset field shows the inherited value. Defaults never reconfigure existing missions or busy actors. Reusable briefs contain creation inputs only; loading copies them into a normal draft and deletion preserves executions. **Save as brief** is also available from a selected one-time mission, including a completed mission: it copies objective, verbatim notes, template, stored profile choices and task-session policy; the mission title prefills the brief name, never copying execution identities or results. Profiles choose an agent, model and optional reasoning variant. Coordinators use primary/all profiles; native task actors use subagent/all and independent actors use primary/all. Business roles remain separate from native session identities. Actor continuation preserves the accepted profile. The native subagent-depth editor is separately Location-scoped and applies to all OpenCode conversations there, not just missions. It shows the configuration file, effective value and override. Conditional Save preserves the original file expectation and never automatically reloads or restarts OpenCode. ## Missions panel The first toolbar holds only general actions: **Create**, **Settings** and **Refresh**, aligned right. Settings opens the Missions settings section directly, using the existing native Preferences window on desktop. A native refusal shows an error rather than opening a second embedded window; browser and remote windows retain their embedded settings. The current-mission line contains a leading chevron, the selected title and a small status mark: - Clicking the **chevron** expands a persistent inline list; selection leaves it open. - Clicking the **title** opens a transient popup; selection, outside interaction or Escape closes it. - Both lists show titles and status marks, with full labels in tooltips and accessible text. Titles truncate only at the available row edge. - Search appears only when the measured list exceeds its maximum height, and remains available while a query is present. - The closed chevron indicates activity/attention in other missions using the same visual vocabulary as the session list. - Only the picker changes the selection, remembered per project; opening a mission's conversation never reselects a mission. Selected-mission controls are separate: **Play/Pause**, **Stop**, optional recurring **Run now**, then **Summary**, **Open coordinator conversation**, **Edit** and **Delete**. Destructive actions require confirmation. **Request an update** is a text button below the icons, available only while meaningful; its pending/uncertain state is retained without automatic replay. The **Tasks** disclosure contains only the declared dependency tree, not a duplicate task list. It is initially open, remembers its state and uses the remaining panel height down to the window bottom rather than a fixed task-height cap. Rows retain full-width selected/hover backgrounds across connectors and controls. A task's exact conversation shortcut appears on desktop hover/keyboard focus, and remains visible on touch. Mission selection is remembered per project and changes only through explicit mission selection/creation. Opening a coordinator or task conversation in the session list never changes the selected mission. Conversation shortcuts remain available from the mission panel to the coordinator and exact task conversations. The session-list files are unchanged relative to `dev`; restoring the full cached session hierarchy is supplied by the separately merged #841. ## Plan and native execution The coordinator declares tasks, dependencies, roles and expected outcomes. Ready work can run in parallel through ordinary native subagents. Recursive decomposition follows OpenCode permissions and configured depth; the product imposes no delegation target or root fallback. Independent sessions remain available for an explicit Location, lifetime or existing-root requirement. The task-session policy is frozen per mission. Tasks have stable keys/generations; conversations have exact native identities. Business dependency edges never stand in for native ancestry. Native task returns and business settlement are separate: a coordinator records the actual returned result/evidence, then finalizes the mission. A notification/admission acknowledgement is not proof of consumption or completion. ## Results and human interaction Long objectives, briefings, task results, evidence and plan history open in the central reader above the transcript. Reader eyes toggle the exact target and highlight it. Task results come before the original brief and technical details. A missing/unavailable reader target must not leave the transcript hidden. The coordinator publishes dated, bounded briefings explaining delivered results, remaining work, obstacles and the next step in plain language. Briefings remain separate from task settlement and observed activity; exact request identity is required to acknowledge an explicitly requested update. Attention contains real native Forms and permissions. Obstacles reported in prose are not automatically human requests. Native interruptions retain conversation provenance and drafts in the shared interruption dock. A template's required human decision counts only when answered through the CodeNomad UI, locally or from a live paired Remote Control device; a simple UI-answer mark records that provenance. Users give direction or ask questions by writing in the coordinator conversation (**Open coordinator conversation**). From the panel itself, the only coordinator message is **Request an update**; its pending/uncertain state is retained by identity and never replayed automatically. Reports, plan history and cleanup receipts stay secondary in reader/technical surfaces. Optional managed-session cleanup preserves coordinators, shared/reused/moved sessions and roots with descendants. ## Lifecycle and recovery For one-time missions: - **Play** starts/resumes explicit mission intent; **Pause** parks mission dispatch/notifications and interrupts the observed active native family. - **Stop** is terminal and interrupts observed descendants deepest-first, then registered roots/coordinator, with bounded rechecks for parent wakes caused by child cancellation. - Native inbox cancellation uses exact authorized mission/subagent work. Pause preserves deferred results for explicit Play; Stop removes the identified queued work/results that would wake a stopped coordinator. - Per-target receipts record observed interruption and family coverage. Incomplete or unconfirmed interruption is shown as **Some sub-agents may still be running**, never as proven recursive suspension. - **Refresh** reconciles state first; an explicit refresh click may retry a still-unconfirmed lifecycle action under its original identity. Reconnect and ordinary display reads never resend mutations. - **Play** offers targeted recovery only when native observation establishes the applicable interrupted state, not merely because activity is unknown. Active background descendants retain the active/Pause presentation. Native interruption does not undo completed filesystem/tool effects. Resuming a paused mission lets the coordinator decide how to continue or re-delegate interrupted work; there is no hidden task replay engine. ## Recurring missions Recurring setup adds permanent instructions, a title, a daily local time/timezone and explicitly followed project conversations. Saving creates a paused schedule; Play arms it and Run now requests one finite passage. The OpenCode service/plugin owns scheduled passages while both CodeNomad UI and its intermediary backend are closed. One native Job per running schedule sleeps until the earlier of the next due time and one hour. On waking it rereads the clock/document and admits only the latest due civil day newer than the stored daily cursor; there is no backlog. Native execution terminal events also wake observation after a debounce, but are not settlement evidence. Before native effects, conditional storage records deterministic passage, coordinator and start-message identities. Lost replies reconcile those exact identities rather than creating new attempts. A passage archives only after the coordinator and descendants are inactive, inboxes are empty and no relevant native Form, permission, Shell or background subagent remains. Unknown coverage stays pending. Passages end as completed with a final report, native terminal failed, or ended-without-report/interrupted. Only completed passages advance followed-conversation cursors. Schedule history is bounded to 30 passages. Civil-time DST gaps/repeated times and entirely skipped days resolve deterministically. Pause/Stop cancel the schedule Job; those schedule actions do not prove an already-running passage family stopped. Stopped is terminal. After service restart, a desired-running schedule without its Job is **Interrupted**, awaiting explicit Resume. Resume reconciles pending work, never sends a continuation; a turn cut by restart settles interrupted/ended-without-report. ## Durability and UX Mission journals and schedule documents retain tasks, roles/profiles, results, plan revisions, controls, notifications and bounded history. Conditional writes and original request identities protect mutation retry. Authority, Location ownership, fresh per-send environment and connection/deletion fences are checked at admission. Ordinary native permissions govern tool use. UI remains compact and square, localized in all supported languages, keyboard-accessible and usable on touch/narrow/RTL layouts. Cache-first display reads revalidate on visible demand and native invalidation, without polling or clearing known data on uncertain recovery. Loading, missing capability and uncertain effects remain explicit. ## Shared integration scope The PR also includes supporting shared-runtime corrections; these are not limited to the Missions tab: - Session outcome and generation-recovery reconciliation retains uncertain interruption state across reconnects and checks native outcomes before clearing it. Native message pages clamp to the service's 200-message limit. - Pending-request recovery retains known requests through incomplete coverage and connection transitions; native ownership and deletion fences remain authoritative. - Keyboard offset and the compact composer help strip preserve reachable input controls without changing composer height limits. Touch overflow actions suppress duplicate compatibility clicks. - Workspace text saves enter the existing worktree mutation fence; sandboxed panel asset reads fence connection changes. Worktree scans retain validated family identity and custody. - The worker-based Git process runner uses an ESM-safe worker entry, and CLI service discovery shares bounded command deadlines. - Desktop/backend profile identity is explicit for Missions' owned storage. Profile-scoping signals are internal to that relationship, not permission for independently launched applications to inherit a profile. - Shared rendering/localization includes a Turkish tool-call label correction. - Session-list startup restoration exposes a settled signal (`stores/session-list-restoration.ts`, hooked in `session-api.ts` and `instances.ts`). Missions display reads wait for it so the session list loads first; it settles on success, failure, timeout or abandonment and is reset when a workspace is removed. Session-list components and styles are unchanged. These callers are included in integration review and their regression tests, rather than treated as an unchanged dependency surface. ## Current limitations - Editing/deleting recurring schedules is not implemented; those icons in the selected mission's action bar are disabled for schedules. - An uncertain one-time creation (lost reply after the request was sent) is held in window memory with no status endpoint; Create stays blocked for that window until reload. Definitive refusals before any native effect re-enable Create immediately. - Saving a brief from an existing recurring schedule is not implemented; the selected-mission action currently covers one-time missions only. - Task conversation lookup for older unbound native tasks reads a bounded coordinator-message window and recognized exact assignment evidence. Older/unrecognized delegations may have no shortcut; no conversation is guessed from titles or timings. - Running native calls may not expose their child ID until completion. The panel can instead identify a direct child by its first canonical assignment message, within a bounded direct-child page; unrecognized or out-of-bound children remain unlinked. - Native task profiles are recorded, but ordinary subagent launch still relies on the coordinator passing the declared agent/model/variant to OpenCode. Omitted model parameters can inherit the coordinator's model; profile storage alone does not enforce launch parameters. - One-time recursive interruption is best-effort and bounded, not a durable guarantee that every descendant stays stopped. Partial/unknown coverage remains visible. - Recurring Pause/Stop cancel scheduling, not guaranteed recursive suspension of a running passage. - Native qualification uses isolated services; mock-only and source-review evidence never substitute for real native acceptance. Final validation results are published separately in the PR reviews. - Managed-service restart and some lost-reply/clock-conflict/human-decision journeys still have offline-only evidence. - If an admitted passage start is removed by pruning before its lost durable write is reconciled, that original start identity can become unavailable for deduplication. ## References - [Mission contract](https://github.com/NeuralNomadsAI/CodeNomad/blob/experiment/missions-native-subsessions-20261003/dev-docs/MISSIONS.md) - [Recurring contract](https://github.com/NeuralNomadsAI/CodeNomad/blob/experiment/missions-native-subsessions-20261003/dev-docs/MISSIONS_RECURRING_SIMPLE.md) - [Native qualification](https://github.com/NeuralNomadsAI/CodeNomad/blob/experiment/missions-native-subsessions-20261003/dev-docs/MISSIONS_RECURRING_SIMPLE_QUALIFICATION.md) |
||
|
|
c954841f09
|
revert(missions): undo PR #673 without dropping later dev changes
Revert merge
|
||
|
|
b584ffcb3a
|
merge(dev): reconcile Missions with the current V2 baseline
Integrate dev into the Missions PR without rewriting its reviewed history. Retain mission CRUD routes, authenticated report admission and the 512 KiB bridge limit alongside inspected-window automation and plugin controls. Keep dev's canonical transport, clean builds and 2.0.18 client/plugin dependencies; align the local plugin contract check with the same SDK. Combine architecture guidance and preserve the technical runtime minimum of 2.0.7. Keep the isolated Missions fixture in the latest-runtime CI lane because its test-only ctx.tool.list driver is absent at that minimum; do not reintroduce legacy compatibility paths. Validation: server, UI and plugin-contract typechecks; full server/UI/plugin build; 84 backend/compatibility/packaging tests; 59 UI/persistence/browser tests; isolated OpenCode 2.0.18 Missions fixture and workflow YAML parsing. Merge resolutions have no conflict markers or diff-check errors relative to dev. |
||
|
|
4d7408631d
|
feat(missions): bundle project coordination with the desktop runtime
Provision codenomad.missions through connected-daemon discovery and independent backend presence instead of requiring a source plugin in every project. Bundle the integration for Electron and Tauri, retain project-scoped mission journals across shutdown, and use the same secondary surface as Status. Complete the existing native actor execution work: persist explicit agent/model/variant choices, validate catalog selections and avoid switching busy actors. Admit assignment and report writes through the authenticated desktop bridge with durable-contract verification, session ownership, connection and worktree fences, and per-send profile environment synchronization. Advance the older source branch client/plugin pin to 2.0.11 and retain its bounded runtime metadata adaptation. The isolated 2.0.16 mission fixture passes native catalog, selection, busy queues, conflict, environment, reports, reconnect and idempotence checks. Server, UI and plugin typechecks, 31 mission tests, 10 lifecycle/transport tests and six resource-layout tests pass. |
||
|
|
d873cfd2ee
|
docs: refresh README and workspace screenshot for 0.20 (#782)
## Summary - Update the main README for the shared OpenCode V2 service, current features, managed desktop setup, minimum/recommended OpenCode versions, and explicit service restart behavior. - Correct release links, actual Electron/Tauri artifact formats and architectures, Node guidance, remote authentication and SideCar configuration fields. - Align server and contributor documentation with the 0.20 baseline. - Replace the old hero screenshot with a current 1600x900 workspace rendered using real Solid components and synthetic demo data. - Include a reproducible Chromium capture script and provenance notes; external traffic is blocked and no user backend, daemon or provider is used. ## Preview  ## Validation - UI typecheck passes. - Chromium capture passes transcript, connected-state, agent, timeline and MCP readiness checks, with no uncaught renderer errors. - Resulting image inspected visually. - 20 local Markdown/image targets verified. - Staged git diff --check passes. Regenerate with: node packages/ui/scripts/capture-readme.mjs Documentation and capture tooling only; CI is not being monitored. |
||
|
|
83a4124b37
|
feat(v2): manage session families across worktrees (#649)
## Summary Manage complete session families across the opened local repository's native OpenCode worktrees. This supersedes #642 with the V2 implementation and addresses #319. - OpenCode owns `worktree.refresh/list/create/remove`; CodeNomad supplies the default directory, named-branch policy, local repository scope and verified family transactions. - A project is the opened local checkout and its registered worktrees, identified through the physical Git common directory. Independent clones sharing an OpenCode project ID stay separate. - Session rows, composer selection, search and the Git panel follow native `SessionInfo.location.directory`. Durable metadata is preserved, but old `worktreeSlug` metadata does not override native placement. - Creation uses the selected checkout's revision and the main local checkout's `.codenomad/worktrees` parent. Uncommitted edits stay in the source checkout. External registered worktrees remain discoverable. - Keep copy/open/delete actions in the accessible selector, remove the redundant action bar, hide root-workspace badges, and explain “Create and use” in all ten locales. ## Current base and native contract This branch includes merged `dev@e47e01c6`, including #697's separately reviewed discovery/status compatibility fix. UI/server pin `@opencode/client@2.0.4`; the independently managed daemon has no exact-version startup gate. - Complete bounded inventories use opaque native cursors; continuations send only the cursor. - Moves are serialized across complete families, block active sessions, verify authoritative native locations and roll back partial failures. - Native move events refresh placement and the catalogue without speculative cross-project transfers. - Opaque worktree identifiers are separate from mutable branch labels. The main checkout cannot be removed. - Native detached creation is followed by ordinary Git branch selection, preserving Git's refusal to reuse a checked-out branch; branch-attachment failure cleans up through the native API. - Agent placement instructions distinguish creating a checkout, one-off commands and moving the conversation's execution context. Explicit attachment choices are preserved. ## Deletion safety - Physical checkout reservations cover published and in-flight logical workspaces. - Project serialization and deletion fences cover all family source/destination checkouts. - Complete inventories and cross-project checks run inside the deletion fence, including nested workspaces and owned Shell/PTY resources. - Canonical path, filesystem identity, registration, branch, HEAD and active sessions are rechecked before removal. Replacement checkouts fail closed; rollback requires the original identity. ## Recovery and Git-panel corrections Validation on the real repository exposed serial enumeration of 162 worktrees and concurrent ownership misses launching overlapping inventories. Git annotations now run with bounded concurrency, pending catalogue reads are shared, and negative ownership results are snapshot-cached. A regression exercises 40 concurrent misses. The Git panel now treats its complete local staged/unstaged inventory as authoritative instead of resurrecting native-only stale rows. It also rechecks the selected worktree/request after waiting for native VCS status. ## Validation Latest integration validation: - Isolated official **OpenCode 2.0.0 and 2.0.7**: production discovery/status, native worktree discovery/create/remove, selected HEAD/default parent/named branches, independent-clone scope, stable IDs, nested paths, checked-out/dirty guards, complete family moves and rollback. - Real Solid selector browser tests: mouse, keyboard, touch, actions without session movement, creation source and returned stable ID. - Targeted server ownership/cache/manager/proxy/route/location tests; UI session projection/request-authority/lifecycle tests; family evacuation/rollback and Git model regressions. - UI/server typechecks and production server build including the UI. - Installed Windows Tauri application on the actual repository: dedicated session creation/use, native location and row/composer badges, Git marker visibility, move back, and agent `session_move` reflected in both badges. - Rebuilt UI/server resources installed; full Developer Mode restart restored the original conversation. Disposable sessions, marker, worktrees and branches cleaned up. The original conversation remained attached to `pr649-final`. - `git diff --check`. An immediate post-restart desktop run exceeded a 30-second refresh-button wait; the subsequent completed run passed. These checks validate the workflows, not a startup latency bound or exhaustive compatibility of every OpenCode payload. Earlier branch validation also covered Electron/Tauri native actions, packaging and desktop parity; those results remain in the PR's historical validation comments. Detailed contract and latest evidence: `dev-docs/WORKTREE_SESSION_PLACEMENT.md`. ## Residual limit OpenCode and Git expose no shared snapshot/CAS transaction. CodeNomad narrows races with reservations, locks, fences and repeated authoritative checks; unrelated processes can still mutate state outside those controls. |
||
|
|
aa51cbb9ff
|
fix(opencode): support earlier and modern V2 runtime contracts (#695)
Closes #694 ## Status This PR contains the stable 2.0.4 client migration, authenticated V2 discovery fallback and shared cross-runtime compatibility implementation. The validation results below are local execution evidence; the newly added CI matrix must also run on the updated PR head. ## Published changes - Pin UI/server to official `@opencode/client@2.0.4` and the bundled pruning plugin to `@opencode/plugin@2.0.4`, with the corresponding lockfile migration. - Probe authenticated `/api/status` first. Fall back to earlier V2 `/api/health` **only on HTTP 404**, retaining the endpoint, credentials, 64 KiB response bound and absolute deadline. Authentication, transport, server and malformed-status failures do not trigger fallback. - Migrate the canonical UI/server contract to stable Forms, permission decisions, command names, interrupts, renaming, forks, message lookup and inbox delivery. - Update the guarded proxy for stable methods/paths, native active-session envelopes, native `cursor.next`, global Form directory headers and current resource/plugin events. - Follow the renamed upstream platform binary `bin/opencode(.exe)` while retaining public CLI aliases. Discovery success alone does not establish compatibility with an earlier runtime's conversation APIs. ## Shared cross-runtime compatibility ### Shared cross-runtime integration - Introduce one connection-scoped adapter under `packages/server/src/opencode/compatibility/`, used by both the guarded UI proxy and direct server callers, including Yolo. - Select the contract using authenticated daemon identity rather than the CLI executable's version. Recognize unknown publications through authenticated, bounded OpenAPI negotiation instead of an exact runtime-version gate. - Bind authorization, client, transport and profile to one connection generation. Fence actual mutation dispatch after asynchronous body preparation; prevent late old streams from publishing or invalidating their replacement. - Translate earlier V2 routes, methods and payloads before sending. Never retry a mutation speculatively after 400, 404, authentication or transport failures. - Normalize legacy HTTP inbox timestamps, including compaction admission, before the pinned Solid reducer. Preserve the distinct native SSE inbox schema and durable event metadata. - Restore legacy catalog/content invalidation and permission-event convergence. Preserve meaningful method/path/status/profile diagnostics and native 401 error envelopes. ### Location authority and pruning - Preserve legacy workspace identity internally through request serialization, catalog/cache keys, Forms, imports, cursors, events and exact move rollback. Modern public APIs continue to reject obsolete workspace selectors. - Authorize complete locations before translating directories or synthesizing upstream Form/location headers. Keep native cursor tokens unchanged. - Preserve session/path ownership, worktree mutation fences and the restricted proxy allowlist. Generic RPC, plugin management and destructive revert commit remain blocked. - Carry verified legacy identity through pruning membership checks, preview and the existing transactional storage/claim fence; do not relax deletion checks. - Treat native idle records as control records, retaining identity/outcome without fabricated assistant text. - Add a common multi-runtime CI matrix and the audit/evidence register in `dev-docs/OPENCODE_V2_COMPATIBILITY.md`, including preserved historical architecture findings. ## Local validation All native tests use isolated synthetic daemons, configuration and databases, never the shared daemon or user storage. | Check | Result | | --- | --- | | Same native suite on beta-19271, 2.0.3, 2.0.4 and 2.0.5 with pinned client/plugin 2.0.4 | Passed | | Full native pruning suite with non-null legacy workspace identity on beta-19271 and 2.0.3 | Passed | | Rendered UI on modern 2.0.5 and beta-19271 with non-null identity | Passed | | Native 2.0.5 suite inside Ubuntu/WSL, using a temporary Linux filesystem root | Passed | | Server tests (after CI follow-up) | 500 passed, 2 skipped | | UI store tests | 441 passed | | Electron native tests | 194 passed, 4 skipped | | UI/server/Electron typechecks | Passed | | UI/server and Electron production builds | Passed | | Windows Tauri release executable (`--no-bundle`) | Passed | | Electron/Tauri packaged-resource smoke checks | Passed | | Desktop packaging invariants | 4 passed | | `git diff --check` | Passed | The native matrix exercises the actual shared connection, generated client, UI fetch adapter and guarded proxy: voice-off/on instructions, prompts, commands, session Shell, background Shell output cursors/removal, UI/Yolo permission acceptance and rejection, busy inbox delivery/cancellation, interrupt/wait, staged revert clearing, session/global/worktree Forms, native pagination, export/import, same-directory legacy identities, scoped events, foreign authority refusal and exact rollback. Pruning coverage includes actual storage identity and execution claims, busy refusal, idempotency, competing admission, next-model payload, fork isolation, pre-compaction history, restart, backend presence disposal/reopening and crash expiry. Rendered tests cover individual/group/response/session cleanup, confirmation counts, persistence and reload. ## Autonomous gatekeeper review Review/fix/retest loops concluded with no remaining actionable findings in the reviewed transport/lifecycle/proxy, identity/UI/events/pruning/rollback, scripts/CI and rendered-fixture scopes. Corrections included dispatch-generation races, compaction admission normalization, independent negotiation cancellation, first-request profile resolution, preservation of streamed 401 envelopes and direct Shell/PTY identity propagation. A final rendered failure was traced to the fixture awaiting only the first RPC of a cross-message deletion; the fixture and regression now await every affected message. Production deletion guards were not relaxed. This scoped approval does not close the separately preserved historical architecture findings. ## Validation boundaries ### CI follow-up The first run on `a0c1c943` ([35142559235](https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/35142559235)) failed in five native jobs. The local bundle tests had missed the standalone npm archive's missing sibling import, and Windows legacy jobs exposed a short-path versus canonical-path project comparison. The dependent artifact-comment job reported that same build failure. The follow-up makes the plugin's identity primitives self-contained, adds an isolated npm-file-list regression for all exported entrypoints, and corrects project identity selection with alias and nested-repository regressions. The packed-plugin failure was reproduced before correction; the corrected installed package passes the native suite on Windows 2.0.4 and Linux/WSL 2.0.4/2.0.5. The corrected 2.0.4 shipped bundle also passes rendered/native pruning. Fresh full beta-19271 and 2.0.3 `--legacy-pruning` suites pass under a reproducing Windows short-path TEMP root after the final exact-directory fix. Independent final reviews approve packaging/documentation and worktree identity with zero actionable findings. Remote checks on the new head remain the CI authority; these are local follow-up results. - Full interaction with the installed desktop application through Developer Mode was not verified because Developer Mode is inactive. The release executable and packaged-resource checks above are build/smoke evidence, not a fresh-install interactive certification. - Remote run [35146390688](https://github.com/NeuralNomadsAI/CodeNomad/actions/runs/35146390688) at `486e856d` passes all runtime-contract jobs, Windows/Linux native pruning, service compatibility, general tests and both Tauri checks. macOS passes packed-plugin loading/pruning, then times out on late bundle discovery. The fixture now canonicalizes its root before daemon startup to align `/var` configuration paths with `/private/var` FSEvents paths. Late installation remains mandatory and asserts the plugin was initially absent; failures now upload isolated diagnostic logs/inventory/captures. Actual macOS confirmation remains pending on the new head. - Interactive native TUI validation was not performed. - The passing WSL result is Linux-native execution inside WSL, not a complete Windows-host/WSL desktop traversal. With the fixture's configuration directory under `/mnt/c`, conversation/proxy checks passed but late plugin discovery timed out; the otherwise equivalent Linux-filesystem run passed. Mounted-configuration late discovery remains a documented environment limitation. - Other audited publications are declaration-reviewed, not individually native-certified. The four-runtime matrix does not imply universal V2 compatibility. - Earlier PR artifacts do not contain the completed cross-runtime implementation; use artifacts built from the updated head. Local passing results do not imply that the updated remote CI has completed. |
||
|
|
52f0e62935
|
feat(opencode): migrate CodeNomad to native V2 (#647)
# OpenCode V2 Migration and Desktop Restructuring ## Summary This branch replaces CodeNomad's OpenCode V1 SDK, custom plugin, and per-workspace runtime architecture with the native OpenCode V2 client and one shared OpenCode service. It intentionally ships no V1 runtime fallback. The scope includes native location ownership, Forms and Shell resources, project-wide cursor pagination, bounded resident message windows, streaming reconciliation, duplicate-folder instances, multi-window Electron/Tauri behavior, content-addressed restore, worktree mutation fencing, and reproducible desktop packaging. The reviewed implementation head is `dea20996`. UI and server resolve `@opencode-ai/client@beta` to `beta-18999`; the runtime CLI is managed independently. The official comparison baseline remains `upstream/beta` at `eb1ac54d73`. Full details: [`MIGRATION_V2.md`](./MIGRATION_V2.md), [`DESKTOP_V2_COMPARISON.md`](./DESKTOP_V2_COMPARISON.md), and [`dev-docs/DEV_V2_CODE_REDUCTION.md`](./dev-docs/DEV_V2_CODE_REDUCTION.md). ## Stabilization Fixes - Preserve manual scroll escape across pagination, remote updates, capped-window shifts, tab changes, and desktop restore; only a local prompt submission forces the bottom. - Keep the timeline resident window capped at 200 messages. Ordered window slides use Virtua shift, while reorder, pagination, and non-aligned replacement remount with a fresh measurement epoch. - Finalize the temporary `200 -> 201 -> 200` transition in a generation-guarded microtask before paint and compensate followed content growth from a `ResizeObserver` attached to the mounted Virtua root. - Keep all pending inbox prompts after delivered transcript messages in native inbox admission order. - Add a persisted `steer`/`queue` follow-up preference; the alternate shortcut uses the inverse while idle sends remain `steer`. - Edit a pending prompt only after authoritative inbox cancellation succeeds, then restore its text, structured payload, files, and agent references to the composer. - Expose native `session.background` through the ownership-checked proxy, a prompt action, and `Ctrl/Cmd+B`. - Remove the duplicate model-selector "show all" action and make the favorites toggle label reflect its current action. - Restore permission/Form synchronization plus skill, reference, MCP-resource, and websearch-provider reads in the reviewed proxy allowlist. - Validate and preserve native location workspace identities for root/worktree requests, session moves/imports, cursors, and global Forms. ## Capability Decisions | Capability | Native V2 availability | CodeNomad `DEV-v2` decision | Revisit or complete when | | --- | --- | --- | --- | | Assistant content mutation | `session.messageUpdate` authoritatively replaces the text, reasoning, and tool content of a completed assistant message. There is still no generic deletion of a complete delivered message or mutation of user messages. | Restores individual tool/reasoning deletion through the native update route. Arbitrary whole-message deletion remains absent rather than locally simulated. | Add broader deletion only if V2 exposes an authoritative operation for the required message type. | | Bulk tool and reasoning cleanup | No native bulk operation, but `session.messageUpdate` can safely compose cleanup one assistant message at a time. | Restores selected-group and full-session technical-part cleanup through authoritative per-message updates. | A native bulk operation is only needed if per-message updates become a measured performance problem. | | Delete-to-boundary / undo | `session.revert.stage` and `session.revert.clear` use V2 staged-revert semantics instead of arbitrary deletion. | Command-palette Undo uses `revert.stage`; Redo clears the staged revert through `revert.clear`. | Revisit only if V2 adds broader authoritative transcript deletion. | | Compaction | Native checkpoint compaction summarizes the older head and retains a server-selected recent tail controlled by `compaction.keep.tokens`. | Uses `session.compact`; there is no message-level selective compaction. CodeNomad displays the partial summary through the same reactive streaming path as text and reasoning, then replaces it with the terminal summary. | Add scoped controls only if V2 defines scoped compaction semantics. | | Transcript pagination authority | Message pages expose only opaque previous/next cursors. They provide no transcript revision, total, absolute range, position, or random seek target. | Uses bounded cursor traversal and a 200-message resident window, with defensive reconciliation after destructive events. It cannot prove that pages loaded across compaction or revert belong to one snapshot. | V2 adds snapshot revision authority ([#43766](https://github.com/anomalyco/opencode/issues/43766)) and navigable position metadata ([#44660](https://github.com/anomalyco/opencode/issues/44660)). | | Full-session search | `session.list(search)` filters session titles only. There is no server transcript-search endpoint returning message identity, excerpt, navigable position, and transcript revision. | Retained through exhaustive message-cursor traversal while keeping only the 200-message resident window and collected matches. Large searches still fetch every page. | V2 exposes transcript search ([#45801](https://github.com/anomalyco/opencode/issues/45801)) with a target that composes with transcript revision and seek metadata. | | Queued prompt management | Native inbox list, cancel, steer, and queue operations cover authoritative follow-up delivery. The TUI's edit action cancels a queued prompt before restoring it to the composer; it is not an atomic inbox update. | Implements persisted primary `steer`/`queue` delivery, inverse alternate shortcut, delivery switching, cancellation, cancel-first composer restoration with structured payload retention, and native-order timeline projection. | Revisit atomic editing or reordering only if V2 adds an authoritative operation and a concrete product need is established. | | Background execution | Native `session.background` moves blocking tools out of the foreground; Shell resources separately support listing, bounded output, and removal. | Exposes `session.background` through the proxy and UI with `Ctrl/Cmd+B`, and replaces the custom process manager with native Shells. Unsupported controls such as rename remain removed. | Add controls only when the native session or Shell APIs support them. | | Service lifecycle | V2 uses one shared externally owned service rather than one runtime per workspace. | CodeNomad discovers or starts the service. Stop Workspace evicts the native location after its final logical owner is removed; application shutdown never stops the daemon. | No parity work planned unless V2 changes service ownership semantics. | ## Validation Migration gate (`878550ca`): - UI and server TypeScript typechecks. - 86 focused UI tests covering follow, pagination, queue ordering, bottom pinning, shortcuts, delivery resolution, and model visibility. - 64 focused server tests covering proxy ownership/location enforcement and shared-service workspace identity. - Production UI/server build. - Tauri `cargo check` and all 121 Rust tests. - `git diff --check`. Timeline stabilization (`dea20996`): - UI TypeScript typecheck and all 68 focused timeline, pagination, request-authority, and restore tests. - Tauri release build against the `beta-18999` lock. - Native Developer Mode validation: no remount or empty frame during capped shifts, same-cycle growth compensation, preserved manual escape, and inactive-tab anchor restore within 0.3125 px. ## Remaining Gaps - Active-session-location authority for MCP/plugin status. - Optional interactive PTY, session export, and reference/MCP-resource attachment UI. - Desktop release signing/notarization hardening. |
||
|
|
14586cb33e
|
feat(ui): add Turkish localization (#662)
Adds Turkish (tr-TR) as a supported UI language, following the same structure as the existing German/Nepali localization (#523). ## What's included - `packages/ui/src/lib/i18n/messages/tr/` — all 16 message modules + `index.ts`, mirroring the English files. **1,602/1,602 keys translated** (verified against `en/`: no missing, no extra, every `{placeholder}` preserved). - `packages/ui/src/lib/i18n/index.tsx` — `tr` added to the `Locale` union, `SUPPORTED_LOCALES`, and `localeLoaders` (lazy import, same as other locales). - `packages/ui/src/components/locale-selector.tsx` — `Türkçe` added to the language options. - `CONTRIBUTING.md` — translation-files row updated to list the current locale set. ## Translation conventions Following the repo's i18n rule ("add to `en/` first, then every other locale"), plus the convention visible in existing locales: - Developer jargon stays English: session, workspace, instance, provider, agent, prompt, token, diff, commit, worktree, branch, SideCar, plugin. - Product names and acronyms stay literal: CodeNomad, OpenCode, GitHub, VS Code, API, CLI, SSH, TLS, TTS/STT. - Turkish orthography (İ/ı casing, apostrophe suffixes on jargon: session'ın, agent'ler). ## Verification - `npx tsc --noEmit -p tsconfig.json` (packages/ui) — pass - `npx vite build` (packages/ui) — pass (build also exercises `mergeMessageParts`, so no duplicate keys) - Runtime check on `vite dev`: with a Turkish browser locale the app auto-detects and renders fully in Turkish; the language picker lists and selects `Türkçe` (screenshots below) ## Screenshots **Before — English UI (fresh profile, en-US locale):** <img width="640" alt="before-english" src="https://raw.githubusercontent.com/fitzgpt/CodeNomad/tr-evidence/evidence/cn-before-english-home.png" /> **After — Turkish UI (auto-detected from browser locale):** <img width="640" alt="after-turkish" src="https://raw.githubusercontent.com/fitzgpt/CodeNomad/tr-evidence/evidence/cn-after-turkish-home.png" /> **After — language picker with Türkçe selected:** <img width="640" alt="after-picker" src="https://raw.githubusercontent.com/fitzgpt/CodeNomad/tr-evidence/evidence/cn-after-turkish-picker-open.png" /> --------- Co-authored-by: fitzgpt <fitzgpt@users.noreply.github.com> |
||
|
|
17547a15d8
|
docs: add CONTRIBUTING.md guide for new contributors (#484)
## Summary Adds a CONTRIBUTING.md file to help new contributors get started. ## Contents - Quick start setup - Finding issues to work on (label guide) - Branch naming conventions - Development workflow (fork, branch, commit, PR) - Project structure overview with key file paths - Styling conventions and file size guidelines - i18n workflow for adding translations - Code principles (KISS, DRY, single responsibility) This gives new contributors everything they need in one place to start contributing effectively. --------- |