Summary
Add document metadata (properties): tags, status (draft / in review / approved), client/project label, owner, and custom key-values — stored in the project-store, not inside the OOXML — surfaced as an editable properties bar in the editor and filters on Home. The agent (AI panel) can read and update these, giving it cheap context without re-reading file content.
Motivation
- Office files are workflow objects: "which proposals are still drafts?", "what's tagged for the board?", "who owns this?" — currently answerable only by opening files or asking the agent.
- Obsidian's frontmatter is one of its most-used features; the docx equivalent must NOT touch the XML (byte-preserving engine fidelity is a hard constraint of this fork). Project-store is the right home: it already maps
absolute path → projectId and keeps per-file data (chatIdByPath).
- Cheap AI context: the agent gets tags/status per document via IPC/MCP instead of re-extracting text — faster sessions, better routing (
/board-intelligence on tagged files, etc.).
Proposed UX
- Editor: a collapsible Properties section (like frontmatter in Obsidian): key-value rows; built-in keys (Tags, Status, Client, Owner, Created, Modified) + custom keys added inline. Editing persists to project-store (not the file).
- Home: file rows show tag chips + status badge; filters: "Status: draft", "Tag: board".
- Quick Switcher / search (future): results can be filtered by tag (
tag:board).
- AI panel: agent can read properties (tool) and update them (e.g. after producing a report, mark status=approved) — expose via MCP connector or shell IPC.
Implementation notes
- Schema: extend
packages/project-store/src/types.ts — propertiesByPath: Record<path, { [key: string]: string | string[] }> + validation for built-in keys (status enum: draft|review|approved|archived). Persist in the same store file; migrate safely if the store schema changes (check existing migration pattern in store.ts).
- Editor UI: properties bar in the shell renderer. It must work for all four app types — since editors are separate WebContentsViews, the cleanest v1 is a shell-level side panel that receives the active tab's path (via
TABS_CHANNELS focus events) and CRUDs properties over new IPC (props:get, props:set, props:list-keys) in home-api.ts + preload. Alternatively an in-editor panel per app — but that means touching 4 apps; prefer the shell-level panel to keep the fork thin.
- Home filters:
apps/shell/src/renderer/src/Home.tsx — add status/tag filter rows next to the existing Recent/Starred nav; extend the recents IPC to accept optional { status?, tags? } filters (main-process side in apps/shell/src/main/index.ts).
- Agent access: expose properties to the agent — either (a) MCP connector tool (preferred, works from both chat and AI panel) or (b) a shell IPC the AiPanel can call. If MCP: the connector runs outside the app; the project-store is app-side, so (a) needs a tiny bridge — evaluate effort vs (b) which is app-internal. Decide in implementation; note the tradeoff in the PR.
Acceptance criteria
Out of scope
- Properties embedded in the file itself (explicitly rejected — byte-preserving engine fidelity).
- Cross-machine property sync.
- Property-driven automation rules (e.g. auto-archive on status change) — later.
Summary
Add document metadata (properties): tags, status (draft / in review / approved), client/project label, owner, and custom key-values — stored in the project-store, not inside the OOXML — surfaced as an editable properties bar in the editor and filters on Home. The agent (AI panel) can read and update these, giving it cheap context without re-reading file content.
Motivation
absolute path → projectIdand keeps per-file data (chatIdByPath)./board-intelligenceon tagged files, etc.).Proposed UX
tag:board).Implementation notes
packages/project-store/src/types.ts—propertiesByPath: Record<path, { [key: string]: string | string[] }>+ validation for built-in keys (status enum: draft|review|approved|archived). Persist in the same store file; migrate safely if the store schema changes (check existing migration pattern instore.ts).TABS_CHANNELSfocus events) and CRUDs properties over new IPC (props:get,props:set,props:list-keys) inhome-api.ts+ preload. Alternatively an in-editor panel per app — but that means touching 4 apps; prefer the shell-level panel to keep the fork thin.apps/shell/src/renderer/src/Home.tsx— add status/tag filter rows next to the existing Recent/Starred nav; extend the recents IPC to accept optional{ status?, tags? }filters (main-process side inapps/shell/src/main/index.ts).Acceptance criteria
chatIdByPathstability mechanism).sha256of the file before/after editing properties is identical.Out of scope