Skip to content

Latest commit

 

History

History
292 lines (197 loc) · 52 KB

PROJECT_ROOM.md

File metadata and controls

292 lines (197 loc) · 52 KB

Project Room · repository contract

Project Room is an installable desktop workspace for a software repository. It reads only .projectroom/project.yaml from the selected project folder and renders a connected map of applications, backend services, databases, storage, and long-running command servers. Specifications, tests, issue sources, and external links have their own views. The YAML belongs in the project repository so other developers see the same product model. Local events.jsonl and command logs under .productview/ are ignored by Git by default because they may contain private data.

The Overview page groups launchable applications and backend services with Start/Stop controls and summarizes their state, recorded test runs, issue sources, performance availability and specifications. Its Performance card plots CPU and memory on one shared time axis, with separate left and right scales and a clearly labeled curve for each metric. It also shows a compact, read-only Project Map preview of up to six runtime components and their configured connections; Open full map opens the complete map. Launch and Performance stack on the left; Inspect shortcuts and Project Map stack on the right. Each column follows its own content height, avoiding empty gaps beside shorter cards. Narrow windows place the cards in Launch, Inspect, Map, Performance order. In the interactive demo it shows clearly labeled sample results. In a local workspace it uses recorded data and marks integrations that are not connected. The full Project Map is a detail view for the complete topology and arrangement, reached from Overview rather than the main navigation. Set workspace.startPage: overview to open the summary first, or workspace.startPage: map to open the map. Other page names in the schema are also valid start pages.

The Run & Verify pages use the same browse-and-act rhythm. Applications and Services put Build, Start/Stop and Open next to each configured component, with the selected process's resource use beside the list when space permits. MCP shows server capabilities immediately after connection; connection metadata is expandable below. API shows endpoints and the request composer first, with source and authentication details below. CLI keeps configured commands first and offers additional discovered candidates separately. Data selects the first source and lists its tables or files when the page opens; it does not read table rows or file contents until an entry is selected. Test Explorer has a searchable suite list on the left and the selected suite's individual cases, run controls and results on the right. The first suite is selected automatically. The Overview's Data and Tests shortcuts land in those open workbenches. No shortcut starts a process, test, CLI command, MCP tool or API request automatically.

On the full Project Map, drag a card to separate overlapping components. Dropping it in a local project updates that component's position in .projectroom/project.yaml, so teammates see the same layout. A click without dragging still opens its details. The Overview preview stays read-only and arranges its small selection independently.

The interface uses neutral light surfaces, compact spacing, lighter text weights and a restrained slate-blue accent. Green is reserved for successful or running states, amber for warnings, and red for errors. The same palette applies to Overview, product pages, Project Map, CLI Explorer, and the floating chat panel.

When a local launch, build, test or CLI trial fails, its view offers Investigate problem. Project Room sends the failed command, working folder, exit code and at most 6,000 characters of redacted output to the coding agent selected in Settings. This investigation always runs in read-only mode, independently of Product Chat's permission setting. It checks the project and environment before proposing a cause, concrete file changes or commands, and a verification step. The dialog immediately shows which step is running, a spinner and elapsed time while waiting for the agent. Project Room displays the plan before Apply fix enables an edit-mode agent request, which gets its own visible working state and result. The agent is instructed to make only the approved repository-local changes; system-wide installs and secret changes remain manual. Run again reloads the project file and repeats the same action only after a separate click, also showing progress until it finishes. Failure context and repair state are kept in app memory for the open session; they are not a new repository contract.

The desktop opens the last available project directly. While it loads, only a neutral opening state is shown; sample data never appears between launch and the real project. The packaged interactive demo appears automatically only on the first launch when no project has ever been opened. It is labeled as sample data and offers Open my project and Done exploring. After that first launch, Project Room shows an empty project chooser when no local project is available. The working example remains available manually from the project menu. This first-run choice is local to the computer, not part of project YAML. The project picker identifies the open repository folder. The navigation has no persistent Project Room logo or wordmark; the desktop title bar keeps a clear area for macOS window controls.

The sidebar button in the title bar, directly beside the macOS window controls, expands the compact left navigation into a readable sidebar with page names and workspace details. Clicking it again collapses the sidebar into a 56 px icon rail with compact rows, group dividers, a restrained active marker, and title tooltips. At window widths of 900 px or less, the sidebar starts collapsed and collapses when the window crosses into that size. Opening it manually afterward keeps it open while the window stays compact; a new compact launch starts collapsed again. Manual choices are saved locally for wider launches, while automatic collapse does not overwrite that preference. The sidebar state does not change the repository configuration.

The expanded navigation shows entry counts beside product collections and Run & Verify views. Services, CLI tools, MCP servers, APIs, test suites and data sources count configured or linked entries, not running processes or successful checks. Environment counts distinct declared variable names, never their secret values. Backlog and Documentation counts refresh after their repository files have been read. Backlog counts local issues and discovered Spec Kit work once, merging a linked issue with its artifact. A zero means no entry is currently available in that view; live state remains inside the view.

The desktop workbench has one title bar above a flexible workspace. There is no second row of navigation tabs: the left sidebar selects pages, and the title-bar Open menu gives quick access to workspace, product, Run & Verify, and Activity views. A single file explorer appears beside the navigation only on Files; folders start collapsed and open individually. Closing it leaves the file reader visible; Command-B opens Files or toggles the explorer. The optional bottom event panel is available from Open or Command-J. It shows recorded workspace events; process output remains on the relevant service or command page. The native macOS window controls remain at the top of the Electron window. The title-bar Chat button shows or hides the right panel, which stays in the chosen state across pages and app restarts. The panel's close button hides it too; selecting a map component opens its details in the panel. Opening a file shows its read-only content in the center. These layout choices are local display state, not repository configuration.

The sidebar starts with a Project group containing Overview, Files and Onboarding in that order. The full map is absent from both the sidebar and title-bar Open menu; Overview's preview opens it. The map offers Map and List views of the configured components plus a read-only Source view of the exact .projectroom/project.yaml text. The desktop app reads the selected repository file again when Source opens; the web demo reads its packaged YAML snapshot. Add applications from Applications, backend services from Services, and databases or storage from Data Explorer; their connections then appear on the full map. The YAML describes the product workspace and its components; application source files remain in Files. Product has Backlog and Documentation by default; Run & Verify has Services, MCP Explorer, API Explorer, Test Explorer, Data Explorer and Environment; Activity is its own page. Vision, Roadmap, North Star and CLI Explorer are hidden from the sidebar and title-bar Open menu by default. Settings → Preferences → Additional views switches them on or off in the repository's workspace.additionalViews list, so teammates and coding agents see the same navigation after opening the project. The content remains in the repository when a view is hidden. The file explorer opens source files in the central reader. The footer opens Settings, with Preferences, Project & Connections, and Agent Access.

workspace:
  startPage: overview
  additionalViews: [vision, roadmap] # Also: north-star, commands. Omit or use [] to hide all four.

An agent should add a view when it finds meaningful existing content for that page or creates it with the product owner's direction. vision uses product.vision, roadmap uses product.roadmap, north-star uses product.northStar, and commands can discover local CLI candidates and display linked commandTool components. If an optional page is chosen as workspace.startPage, include it in additionalViews too. Editing this list changes navigation, not the underlying specs, documents, services or agent access.

Workspace onboarding and Files

Onboarding is the fourth item under Project until the user completes it. It reads setup evidence from the open project: selected folder, valid YAML, runtime map, applications, backend services, test suites, data sources, specification or documentation files, linked MCP servers, CLI tools and APIs. The progress denominator includes only detected sections; missing optional integrations appear as Not detected · optional rather than failed setup. A green Configured state means the relevant entry exists, not that its command, connection or viewer works. Separate Mark as verified buttons record hands-on checks locally per project; they do not change YAML. When all detected sections are configured, Complete onboarding appears at the top, even if hands-on checks remain unverified; the card states how many remain. Clicking it remembers completion locally for that project and hides Onboarding from the sidebar and Open menu on subsequent launches from the first render. Settings → Project & Connections → Reopen onboarding restores the page and navigation item without deleting the verification checks. Completion is personal UI state, not part of the shared YAML. The read-only review checks referenced paths, local commands, declared environment names, and detached service lifecycle definitions without running project commands. An optional agent-help section offers the project-specific prompt and Agent Access. The prompt asks for an inspection and waits for the user's reply before writing YAML. Refresh analysis revalidates and reloads configuration. Verify each application, service, test and data source deliberately in its own view.

The recommended first setup has two starts: for a new app, ask a coding agent to initialize Git and the official GitHub Spec Kit workflow while creating the app and its Project Room YAML; for an existing repository, ask the agent already working there to inspect what exists. On the existing-repository path, the agent first reports its findings, checks whether Spec Kit is present, asks only necessary questions, and waits for the user's answer before changing files. Spec Kit is optional for this path and must not be added silently. Both website prompts point to this repository's public guide. After configuration, the agent's handoff gives the Mac download and installation steps if needed, names the exact local folder to open, explains the verified configuration and uncertainties, and identifies the first service, test and data source to check. The user launches Project Room, opens that same folder, refreshes analysis if it was already open, and reviews Onboarding and the Overview map preview before running anything manually. The full map is available when connections need closer inspection. The app's project-specific prompt is an optional alternative when the folder is already open in Project Room.

Detached services such as Docker Compose stacks need explicit lifecycle commands. runtime.command starts the stack, statusCommand returns 0 only when the intended stack is running, 1 when stopped and 2 or higher on error, and stopCommand stops the stack without deleting its data. Project Room executes these commands only after a user action, checks status after Start and Stop, and polls a confirmed running stack while the app remains open. An unknown state after opening a project is deliberate: Check status runs the project command. Process CPU and memory sampling remains available for foreground services; a detached controller does not invent per-container metrics.

Services and command tools whose verified launch path needs Docker declare runtime.requires: [docker], including commands that hide Compose behind a repository script. Before manual Start, Project Room checks that the Docker CLI and Engine are available. If Docker is missing or stopped, it does not launch the project command and shows an actionable error beside the service with a Retry button. It never starts Docker itself. An omitted requirement does not mean the app has proven that Docker is unnecessary; the coding agent must trace the start command through wrappers and record only verified prerequisites.

runtime:
  command: [./my-project, up]
  requires: [docker]
  statusCommand: [./my-project, project-room-status]
  stopCommand: [./my-project, down]
  lifecycle: detached
  cwd: .
  startup: manual

Files uses one explorer beside the reader. Directories start collapsed and expand on click. Closing the explorer leaves the selected file open without showing a second folder tree. Use Show explorer, the Files navigation item, or Command-B to bring it back. Refresh files reloads the repository tree and selected file without switching layouts.

API Explorer

Run & Verify → API Explorer discovers OpenAPI 3.x YAML and JSON files named openapi.* or swagger.* in the local project without contacting a server. A registered source in workspace.apiSources has a stable ID, display name, clean baseUrl, optional relative spec, and an optional authentication declaration. The existing authEnv Bearer field remains valid. New entries can choose no auth, Bearer, API key in a header or query parameter, or browser OAuth with authorization code and PKCE. Add API and Add to project YAML write validated entries to .projectroom/project.yaml; Remove deletes only that YAML entry. There is no limit to one API per project. An OpenAPI file supplies an endpoint catalog; an API without a spec still supports manually entered paths.

The request composer supports GET, POST, PUT, PATCH, DELETE, HEAD and OPTIONS; editable relative path, JSON headers and optional body; and a response view with HTTP status, time, content type and bounded body preview. When an OpenAPI file is linked, the selected endpoint also shows path, query and header parameters, request media types and editable examples, response schemas, declared security and deprecation. Local $ref components are resolved for these previews. JSON and form-encoded examples are prepared as a starting point; complex schemas remain inspectable and editable as text. Cookie parameters and multipart uploads are documented but cannot be sent by this composer. Send is the only action that makes an API request. The desktop main process restricts it to the selected registered origin, disables redirects, times out after 15 seconds and limits response previews. Bearer and API-key values come from the project's local .env and never enter the renderer as configuration. OAuth uses a public client ID, PKCE, a browser sign-in and loopback callback at http://127.0.0.1:48271/oauth/callback; access and refresh tokens are encrypted with macOS secure storage outside the repository. Register that callback with the provider before signing in. Project Room refreshes an expired access token when a refresh token is available. Forget sign-in removes local tokens; it does not revoke them at the provider. OAuth client-secret flows, Basic, cookies and mTLS are not implemented. Query API keys can appear in server or proxy logs, so use a header when the API allows it. Do not put tokens or query values in baseUrl or secrets in prompts. Activity records request metadata (API ID, method, path, status and duration), not headers, query string or body.

workspace:
  apiSources:
    - id: orders-api
      name: Orders API
      baseUrl: http://127.0.0.1:4000
      spec: specs/001-orders/contracts/openapi.yaml
      authEnv: ORDERS_API_TOKEN

Use the existing Spec Kit contracts/ file when available; do not create a parallel API specification tree. authEnv is optional and contains only a variable name. For an API key, use auth: {type: apiKey, env: ORDERS_API_KEY, in: header, name: X-API-Key}. For OAuth, auth contains type: oauth2, HTTPS authorizationUrl and tokenUrl, a public clientId, and optional scopes and issuer; no tokens or client secrets belong in YAML. Open the included Hello Workspace, start its Notes service, then visit API Explorer to try its two real endpoints.

MCP Explorer

Run & Verify → MCP Explorer finds the built-in read-only Project Room server plus project servers declared in workspace.mcpServers, .mcp.json, .cursor/mcp.json, .vscode/mcp.json or mcp.json. Discovery only reads these files. Add MCP server registers another stdio, HTTP or SSE server in .projectroom/project.yaml; use Add to project YAML on a discovered project server to link its safe connection metadata. Each YAML server is an independent entry, with no fixed count limit. A discovered source linked in YAML remains visible with a Linked label. Remove deletes only a YAML entry and closes that server's connection; original MCP config files and executables stay in place. Multiple servers can remain connected at the same time. Connect starts a local stdio command or contacts a Streamable HTTP or legacy SSE endpoint, then reads advertised tools, resources, resource templates and prompts. Select an item to see its description, input and output schemas and annotations. Simple tool parameters and prompt arguments have fields; complex tool schemas remain editable as JSON. Results show structured content, text, supported images and audio, resource links and prompt messages. Run tool, Read resource and Get prompt are explicit actions with visible arguments and results. Disconnect closes only the selected session. The built-in server gives every configured workspace an example to inspect.

The connected server's capability tabs and the first item's inspector appear directly below a compact server header. Disconnect stays in that header. Endpoint, environment names and long server instructions remain available under Connection and server details below the workbench. CLI Explorer keeps the selected tool header and its launch controls compact, then shows the command once in Explore immediately above the argument entry and explicit test action. Removal is available from Definition; help-derived commands and options are expandable below the result. API Explorer keeps endpoints and the request composer directly below a compact source header.

Use repository YAML for shared endpoints. Linking a discovered server records its source ID in linkedFrom and copies its command or clean endpoint URL. Environment names are copied, never the values from project MCP files. Set static Bearer values in the project .env through Environment. Linking rejects URLs with credentials or query strings and unsupported custom headers; define a clean endpoint and Bearer variable manually when needed. Remote servers can instead declare auth: {type: oauth2} with optional public clientId and scopes. Connect uses the MCP SDK's OAuth discovery, browser authorization and PKCE flow; the local callback is http://127.0.0.1:48271/oauth/callback. Dynamic client registration works when the authorization server offers it; otherwise supply a registered public client ID. Credentials are encrypted with macOS secure storage outside the repository, and Forget sign-in removes the local session. It records connection and action metadata in .productview/events.jsonl, without tool arguments, resource content or results.

workspace:
  mcpServers:
    - id: docs-mcp
      name: Documentation MCP
      transport: stdio
      command: node
      args: [tools/docs-mcp/server.js]
      cwd: .
      environment: [DOCS_API_TOKEN]
    - id: remote-mcp
      name: Remote MCP
      transport: http
      url: https://example.com/mcp
      authEnv: REMOTE_MCP_TOKEN

Settings and issue-source locations

AI & Chat connects the installed Codex CLI or Claude Code to Product Chat. The provider and permission mode are personal settings in Electron's application data folder, not in .projectroom/project.yaml. Ask & inspect is the default; Allow project edits grants the selected CLI its normal project editing capability. Project Room launches the CLI in the open repository and adds its read-only MCP server for the selected workspace while retaining the CLI's existing user tools. The same MCP tools available to external agents provide the YAML, vision and roadmap, components, Spec Kit artifacts, safe project files, and activity. The desktop chat reports agent errors instead of generating a mock answer. The browser demo still uses sample configuration answers. Sent messages go to the selected CLI's configured model provider; Project Room does not add locally stored environment values to prompts or MCP responses.

The Product Chat microphone starts macOS on-device speech recognition for the current system language. Project Room requests microphone and speech permission when first used, inserts partial transcription into the composer, and stops when pressed again. Audio is not stored by Project Room and the recognition request requires on-device processing. If macOS lacks on-device recognition for the language, the button reports that limitation. The user reviews the text before sending it to the agent.

The profile button at the top right opens Personal settings. Appearance can follow the system or be set to Light or Dark. Settings → Preferences → Version & updates shows the installed version, offers an immediate update check in packaged desktop builds, and can restart to install a downloaded update. Automatic checks remain active after launch and every six hours. English is the only interface language in this prototype. Appearance and sidebar width are local preferences; they are never written to .projectroom/project.yaml.

Project & Connections is available in Settings and from the profile menu. It shows the shared project repository and issue sources. In the desktop app, adding or editing an issue source updates its issues component in .projectroom/project.yaml and records an event. Additional views in Preferences also update .projectroom/project.yaml; appearance and sidebar width remain local preferences. The web demo only previews changes for its current session. A GitHub source stores integration.provider: github and integration.repository: owner/repository; a Linear source stores integration.provider: linear and integration.teamId. Both may store an optional HTTPS integration.url for display. The project repository URL belongs in project.repository. Agents can read these fields from the YAML or the local read-only MCP server.

These fields describe where a source is; they do not grant API access. The current desktop prototype has no OAuth flow, token store, or live issue adapter. A future connection flow should keep credentials outside the repository in a local secure store, show the authorized account and scope, test the connection, and fetch issues without implying that a configured source is already connected. Do not put API keys or OAuth tokens in YAML, Markdown, .productview/ logs, or MCP output.

Local environment values

Run & Verify → Environment lists variable names declared in workspace.environment, runtime.environment, tests.environment, cli.environment, and database data.connectionEnv. The shared YAML contains only names and optional descriptions:

workspace:
  environment:
    - name: API_TOKEN
      description: Credential for the local API integration
components:
  - id: api
    kind: service
    name: API
    position: { x: 30, y: 100 }
    runtime:
      command: [npm, run, api]
      cwd: .
      startup: manual
      environment: [API_TOKEN]
connections: []

The desktop app reads the existing .env at the selected repository root. Set value, Change, and Remove edit that file while preserving unrelated entries and comments. Project Room adds /.env to the repository's .gitignore when needed and refuses to edit a tracked .env. Values from the former encrypted app store are moved once into .env; existing .env entries win. The page also shows variables inherited from the app's launch environment. Show current reveals a file value only on explicit click. Copy value copies the parsed .env value directly to the Mac clipboard on click without showing it in the page. workspace.environment names are available to all local commands; component environment names are passed to that component, and database connectionEnv is passed to directly connected components. This applies to services, tests, command tools and CLI help processes launched by Project Room. The web demo never accepts a value. Product Chat, the agent guide, .projectroom/project.yaml and the Project Room MCP server receive no .env values through Project Room. The MCP file reader rejects .env* and .productview/ paths. Known exact values are masked in Project Room command output and logs, including values split across output chunks. A coding agent with direct filesystem access can read .env independently; a process can also transform a secret before printing it, so review prompts and logs before sharing them.

Product pages: vision, roadmap and documentation

The optional product block in .projectroom/project.yaml points to a Markdown vision, declares a docsRoot folder, lists roadmap items, and registers Markdown documentation pages. Vision, North Star, Roadmap and Documentation are separate pages. In a local workspace, it can edit the vision and registered documents, create documentation pages, and add or update roadmap entries. North Star defines one outcome metric and records dated values manually. Its historical plot appears below the current value, followed by all recorded entries. The chart and history use observations from product.northStar; no automatic measurement source is connected. The web demo simulates changes for the current session only. Existing workspaces without a product block can use Set up Product Hub to create a vision and getting-started page inside the repository.

Roadmap entries have stable IDs, titles, summaries, statuses (draft, planned, in-progress, done) and optional relatedComponents IDs. draft and planned describe intended work, not finished features. The roadmap lives in .projectroom/project.yaml; the vision and documentation live in ordinary repository Markdown files. Editors should review and commit these files with the code. workspace.startPage accepts vision, north-star, roadmap or docs; legacy product opens Vision.

The Documentation page has its own folder tree and reader. It scans every Markdown file recursively below product.docsRoot, including files that are not listed in product.documentation. The YAML entries add stable IDs, titles and summaries for selected documents; all documentation files must stay below docsRoot. Select a file to preview it, use Edit Markdown to change a .md file, or New document to add one. When the folder is missing or empty, the page explains the state and offers Create first document; creating it also creates the folder. The local MCP get_product_context exposes discovered Markdown files from this folder and local backlog issues.

The optional product.northStar has a metric name, a clear counting description, unit, cadence (daily, weekly, or monthly), optional numeric target, and dated numeric measurements with optional notes. The dedicated North Star page shows the latest value, a historical plot and the full list of entries. Measurements are entered or corrected manually in the desktop app and saved in the repository YAML. A target is a goal, not a measurement; the chart stays empty until an observed value is recorded. Vision uses the same Markdown editing pattern as Documentation: Edit Markdown is inside the document header, with Cancel and Save in the editor. macOS Dictation remains available through the system keyboard shortcut while the editor is focused; Project Room does not record or transcribe audio itself.

Local backlog

Backlog works without GitHub or Linear. Its default repository folder is backlog/; optional product.backlogRoot selects another folder. Project Room creates the folder when the first issue is saved. Each issue is one Markdown file with YAML frontmatter: stable id, title, status, priority, type, dates, and an optional spec link. The Markdown body holds the problem, outcome and acceptance criteria. The page lists local entries beside Spec Kit feature, bug and idea artifacts, with All, Ideas, Features and Bugs filters and a detail reader. Spec Kit tasks.md progress belongs to its feature, not a separate Backlog filter. Existing local entries of type task remain visible under All. Local entries can be created or edited. Changing status updates frontmatter without moving the file. Review and commit the issue files with the project.

A typical issue file is backlog/pv-001-improve-onboarding.md:

---
id: PV-001
title: Improve onboarding
status: inbox
priority: medium
type: feature
created: 2026-11-04
updated: 2026-11-04
spec: specs/onboarding/spec.md
---

Explain the user problem and acceptance criteria here.

Link a local issue to specs/<feature>/spec.md, .specify/bugs/<slug>/assessment.md or .specify/assessments/<slug>/intake.md when they describe the same work. The linked artifact stays in place and the Backlog shows one combined item. External issue source components are optional metadata; live GitHub or Linear synchronization is not implemented. The web demo keeps backlog edits in the current session.

Spec Kit and other specifications

Spec Kit is one way to keep requirements and implementation plans in Markdown. Set views.specifications.roots to one or more repository subfolders, such as [specs]. Backlog recognizes feature folders under those roots; the original files remain available through Files. Refresh the project after adding artifacts outside Project Room. In the desktop app the files are read from the selected repository; the web demo uses a packaged snapshot. Existing specification components remain valid for references but are hidden from the runtime Project Map. Project Room is the operational view of the repository; it does not replace the specification workflow.

For a Spec Kit layout, Backlog also detects .specify/memory/constitution.md, the active directory recorded in .specify/feature.json, and each <root>/<feature>/spec.md. Feature cards show available plan/research/data-model/quickstart/tasks artifacts, FR and SC IDs, clarification markers, checklist counts, and T001-style task checkbox progress. These are observations of files, not a claim that a feature is deployed. A flat specs/ folder remains available under Files and is not mislabeled as Spec Kit. The bundled bug and assess extensions use .specify/bugs/ and .specify/assessments/; Backlog reads their Markdown artifacts without modifying them.

Connect a feature to actual Project Room components with views.specifications.links, without adding a map card for every feature. The same read-only feature model is available to agents through the get_spec_kit MCP tool:

views:
  specifications:
    roots: [specs]
    links:
      - spec: specs/001-auth/spec.md
        requirements: [FR-001, FR-002]
        components: [api]
        tests: [api-tests]

Component and test IDs must exist in components; test IDs must be testSuite items. The desktop view compares linked test suites with recorded Project Room runs, identifies never-run, failed and older-than-spec results, and shows whether linked services are running in this Project Room session. It also reports linked requirement IDs missing from spec.md and missing relative executables. A recorded passing test is evidence about that test command, not automatic proof that every linked requirement passes. Stopped manual services are observed state, not necessarily defects. Start commands, credentials, live health and external test evidence still need separate configuration or adapters.

Components and configuration

kind Main fields Current app behavior
application application.platform: web / desktop / mobile, optional application.target; runtime.command, cwd, startup: manual, optional local url Applications tabs, Overview, Map, manual Start/Stop and output log
service runtime.command, cwd, startup: manual, optional port, url, health Backend Services, Overview, Map, manual Start/Stop and output log
testSuite tests.command, cwd, optional categories, cases Expandable suite with manual suite and individual runs, exit result and output log
commandTool runtime.command, cwd; cli.mode, protocol, usage, optional source, helpCommand, commands, options, examples, environment CLI Explorer reference, manual Start/Stop or Run, on-demand help, live and saved output
specification path Legacy linkable document; its file stays in the repository, outside the runtime map
database data.engine, connectionEnv for PostgreSQL/MySQL/MariaDB or path for SQLite Manual read-only structure inspection and limited row preview
storage data.path Local file tree and small text/JSON preview
issues integration.provider, repository for GitHub or teamId for Linear, optional HTTPS url Source card and editable project location; live GitHub/Linear sync is planned
external url External dependency card

Each component needs a stable unique id, a display name, and position: {x, y}. position.x is a percentage from 0 to 100, and position.y is a nonnegative pixel value. The runtime map shows applications, backend services, databases, storage and persistent CLI servers; it omits specs, tests, issues, external links and one-off CLI tasks. Only connections between visible runtime resources appear there, with labels such as calls, stores and reads-writes. Hidden entries remain in YAML and their own views. The current model does not discover or control Docker Compose containers as first-class runtime nodes; a Compose service must not be conflated with a local source runner. The JSON schema is schemas/projectroom.schema.json; validate with npm run validate:config in this source checkout.

Data source mini viewer

Run & Verify → Data Explorer uses the database, storage, and external components in .projectroom/project.yaml. It recognizes engine names containing PostgreSQL, MySQL, MariaDB or SQLite. PostgreSQL and MySQL/MariaDB use the named local Environment value as a connection URL; SQLite uses a relative data.path to an existing database file. A storage component uses a relative folder or file path. Add data source opens a repository-backed dialog when automatic detection missed a source. Remove deletes only its YAML entry, map connections and related Spec Kit or roadmap references; it does not delete project data or files. Credentials remain in the local .env and are never written to YAML.

Onboarding also scans for local SQLite files, conventional storage folders and PostgreSQL/MySQL/MariaDB images in Compose files. It shows these as candidates, not verified or automatically registered components. The coding agent should check the actual project before adding them to YAML.

Select a source to connect or list files immediately. Choose a table or file to load its preview; merely opening the page does not connect or read rows. Refresh repeats the listing, and Retry appears after a failed inspection. Database queries are generated by Project Room, use read-only connections/transactions, and return at most 100 tables, 40 columns and 20 rows. Text files show at most 64 KB, and only paths within the declared storage source can be opened. This is for inspection, not editing or arbitrary SQL. An unavailable database or missing local variable is shown as an error instead of a fabricated preview. Other engines remain metadata-only until an adapter is added.

- id: app-db
  kind: database
  name: App database
  position: { x: 36, y: 280 }
  data: { engine: PostgreSQL, connectionEnv: DATABASE_URL }
- id: local-cache
  kind: database
  name: Local cache
  position: { x: 68, y: 280 }
  data: { engine: SQLite, path: data/cache.sqlite }

Individual tests

Open Test Explorer and expand a suite to inspect its entries. Project Room recognizes test files from a simple npm, pnpm, Yarn or Bun script, or a direct Node command, whose final command is node ... --test tests/*.test.* (explicit file paths work too). Earlier && commands remain setup steps. It reads JavaScript and TypeScript source to list literal test and it names, including names inside describe or suite, without loading or executing project code. Refresh test names rereads files after an edit. Each named entry runs that file with Node's exact --test-name-pattern filter; the file entry still runs every test in that file. Dynamic or duplicate names, skipped or todo tests, files over 1 MB, and unsupported runners fall back to file-level or explicitly configured tests.cases entries. For cargo test suites, click Discover Rust tests; this runs Cargo with --list, which may compile test binaries but does not run tests. Both full-suite and individual runs require a manual click, record their actual exit code and offer saved output. Running one Node test still loads its file and can run file-level hooks or setup code; it is not a sandbox.

For other runners, declare individual commands under tests.cases instead of showing guessed test names:

tests:
  command: [pytest, tests]
  cwd: .
  cases:
    - id: smoke
      name: Smoke checks
      command: [pytest, tests/test_smoke.py]

Each case ID must be unique within its suite. Case commands run in the suite working directory with the suite's local environment declarations. Results and command output are written to .productview/; review logs before committing them.

Add application in Applications and Add service in Services write their respective runtime entries. Add data source in Data Explorer handles databases and storage. Each can declare an optional dependency on another visible resource. In the desktop app, this writes a validated .projectroom/project.yaml entry and a component.created history event; the full map reflects it afterward. In the web demo, application and service additions only change the current session. Adding a service does not run it. Test suites belong in Test Explorer, Spec Kit work in Backlog, issue sources in Project settings, and CLI tasks or servers in CLI Explorer.

Commands are arrays of arguments such as [npm, run, dev]. The app runs them without a shell and only after a user clicks Start or Run. Command working directories must stay inside the project. Do not store credentials in YAML; use environment variable names such as DATABASE_URL.

Build identity for executable components

When a launchable application, backend service or CLI tool needs a separate local build, its runtime may declare buildCommand in the same argument-array format as command, for example buildCommand: [npm, run, build]. A local stdio MCP server can declare the same field in its workspace.mcpServers entry. The source-auditing agent must follow the real build script and wrapper before adding it. A source development command that builds on launch needs no separate entry. Rebuild appears beside Start/Stop or Connect only where a verified build command is configured. It runs the build on explicit click in the component's working directory with the declared local environment, while the component is stopped or the MCP server is disconnected; it writes a local build log and Activity result. It never starts or restarts the component. A successful build gives a confirmed build time for this app session when no fresh build.file metadata is produced; a failed build leaves the previous identity unchanged. Stop a detached stack before rebuilding it.

Applications, services, linked CLI tools and explicitly configured local MCP servers can show a verified build time, source commit and optional version. For a service or CLI tool, add build: {file: dist/build-info.json} to its component in .projectroom/project.yaml; an MCP entry under workspace.mcpServers accepts the same field. The path is relative to the repository root. For a service or CLI tool without build.file, Project Room checks build-info.json and dist/build-info.json under its runtime.cwd. Use an explicit path if multiple artifacts share that directory.

The build pipeline should write a small JSON file after a successful build, for example {"builtAt":"2026-11-05T11:34:56Z","revision":"aabbccddeeff0011","version":"1.2.3"}. builtAt needs an ISO timestamp with timezone; revision is the commit used to produce the artifact. A project may omit version. The UI labels current Git HEAD as source, artifact revision as build, and the actual process time as Started. It never converts a file modification or commit time into a build time. Development commands without build metadata show Build time unavailable and, once launched, their start time. Build identity is captured at launch, so rebuilding later cannot silently change the label of a running process. Start events also save the snapshot in .productview/events.jsonl. MCP Explorer separately shows the protocol-reported server version and connection time.

CLI Explorer

CLI Explorer, available in Run & Verify, follows MCP Explorer's browse and test layout: registered project commands appear in the main catalog on the left, with an interactive inspector on the right. Find more CLIs expands available, unregistered source discoveries; unbuilt candidates stay out of the interactive catalog. Discovery scans package bins, Python project scripts, Cargo binaries, Go commands and executable CLI files without running them. This bounded scan is a list of candidates, not a claim that all commands or parameters are known. Explore shows the exact invocation, accepts additional arguments one per line, and runs a bounded local trial only when Test command is clicked. Suggestions come from YAML or actual help; the result shows output and exit status. Read help explicitly runs --help, -h or help and displays the real output with a parsed synopsis and options where possible. Some programs can have side effects even while printing help. Add to project YAML links a discovered candidate as a help-only commandTool. Add CLI tool registers one missed by discovery using an exact executable and argument list, mode, summary and synopsis. Both paths enable the optional navigation view. Remove deletes a configured tool's YAML entry and connected references while leaving its executable and saved logs in place. The app supports multiple tools without a fixed map slot limit. Linked tools retain the manpage, manual Start/Stop or Run controls, and current or saved output. The web preview does not run commands. See docs/product/command-tools.md for the configuration contract.

Project folders

The project name in the title bar opens the project picker. Open project folder is the main action: choose an ordinary repository folder. If .projectroom/project.yaml is valid, Project Room opens it. Otherwise it shows the coding-agent setup dialog for that same folder. The picker also lists recent projects and a working example. More setup options contains parent-folder discovery, direct agent setup, auto-detection and a blank configuration. Auto-detection checks package.json scripts and a few common specification paths. The blank option creates a minimal product specification. The recent-project registry is local to Project Room; each project's YAML remains in its own repository.

For an existing folder without a valid YAML, Open project folder opens a read-only agent setup dialog. Set up folder with a coding agent under More setup options opens the same dialog for any chosen folder. It lists candidate specification/documentation folders, Compose files, package scripts and CLI entry points, exports the bundled agent guide and JSON schema to the app's local data folder, and copies a project-specific prompt for the user's coding agent. Project Room does not invoke or authenticate an LLM. While the dialog is open, it checks for .projectroom/project.yaml every three seconds and shows validation errors or the components and connections. Once valid, Open workspace and verify opens Onboarding in the same folder. The initial scan and dialog do not write into the chosen repository; the coding agent writes the YAML when the user gives it the copied task. The old auto-detect and blank-template actions remain available.

While a project is open, Project Room watches its .projectroom/project.yaml and .env. When a coding agent, an editor or a Git checkout changes the YAML, a banner offers Reload; the current page stays open and running services keep running. Reloading resets detached-service polling and disconnects MCP Explorer sessions, so it never happens without that click. If the edited YAML is invalid, the banner shows the error and the previous configuration stays in use until the file is fixed. Edits made inside Project Room are not reported back. A changed .env refreshes the Environment page directly, without a banner. Refresh analysis in Onboarding and the window's View → Reload (Command-R) still reload on demand.

Project history

The desktop app writes .productview/events.jsonl and .productview/logs/ inside the selected project folder. Events include workspace opens, process starts and exits, test runs, chat prompts and replies with provider and mode, MCP agent connections, and MCP tool calls. Raw filesystem changes are not activity events: generated runtime files can change thousands of times without a meaningful user action. The event file is compacted when it exceeds 4 MB, keeping up to 5,000 recent actions within 2 MB. Opening an older oversized history also removes legacy file.changed noise while preserving recent real actions. Logs contain output from project commands and are separate from the bounded event list. These files are ignored by Git by default; review them for sensitive data before deliberately sharing any evidence. Project Room does not make Git commits automatically.

Local service performance

Project Room samples CPU and resident memory for each service it starts, including its child processes, every five seconds. The Overview shows their combined CPU and memory usage at the same time in separate, scaled charts; Services shows current values and the selected service's history. Sampling starts with the service and stops when its process exits. The last run remains visible until that service starts again, the workspace changes, or Project Room closes. Measurements are kept only in app memory, never written to YAML, Activity, or the repository. Long sessions retain older measurements at lower resolution to bound memory use. The CPU reading is an approximate process usage value from the operating system; memory is summed resident memory, so shared pages may be counted more than once. External processes, detached containers, response latency and disk usage are not measured by this collector. The packaged browser demo continues to show sample data.

Agent Access and MCP

The exportable agent skill is agent/project-room/SKILL.md. Settings → Agent Access displays the exact skill text, product context, JSON schema, current project YAML, and a launch configuration for the local read-only MCP server. The server exposes get_product_view, get_product_context, list_components, read_project_file, and get_product_history. get_product_context returns the vision, roadmap, and Markdown documentation discovered below product.docsRoot. It records connections, disconnects and tool calls in the project's history. Agents use their normal repository tools to edit code and YAML; the MCP server itself does not run commands or write project code.

The server uses a local stdio connection and the MCP 2025-11-25 handshake. If a newer client probes a newer protocol first, it can fall back to this supported revision. The MCP command shown in Agent Access uses the installed Electron binary in Node mode and points to the current workspace. The prototype does not provide network-hosted MCP access.

Desktop build

The first-run Try working example action copies examples/hello-workspace to ~/Documents/Project Room Examples/hello-workspace and opens it. The copied project is independent of the installed app and remains editable. It includes a real Node.js service, two route tests, local JSON storage and standard Spec Kit artifacts. Node.js 20+ is required to run its service and tests. The existing Blackbox Agent B packaged demo remains clearly labeled as a simulation.

Run npm ci and npm start for development. On Apple Silicon macOS, npm run package:mac:app builds an unsigned local app bundle in outputs/project-room-desktop relative to this workspace. npm run package:mac requires a Developer ID Application certificate and Apple notarization credentials; it produces a signed DMG, ZIP and update metadata. The tag-triggered release workflow publishes those artifacts to GitHub Releases after its secrets are configured. Only signed releases can serve as a reliable in-app update baseline. The existing .projectroom/project.yaml filename and MCP tool names remain stable while the public app name changes to Project Room.

Live GitHub/Linear synchronization, external telemetry adapters, database editing and arbitrary SQL are not implemented. The web prototype is a visual simulation. The desktop app can open local workspaces, start configured processes, sample their CPU and memory, run tests, inspect supported data sources, record history and chat through a locally installed coding agent.

Applications and backend services

Use kind: application for a user-facing Web, Desktop or Mobile app, with application.platform set to web, desktop or mobile. runtime.command is the verified development launch command. For Web apps, a local runtime.url enables Open in the Applications view. A Desktop or Mobile launch command opens its own window or simulator; Project Room does not install SDKs or choose devices automatically. If a launcher exits but leaves an app running, configure runtime.lifecycle: detached with truthful status and stop commands. Backend APIs, workers and other background processes use kind: service and remain in Services. Both kinds appear in Overview and Project Map, and foreground processes contribute session CPU and memory samples. Explorer pages inspect interfaces, tests and data exposed by those running components.