When in doubt, choose the simplest solution that works. KISS and YAGNI are project rules, not preferences.
This repository contains Devsync: a filesystem-first system for managing team project documentation, resources, work, and activity logs.
Main structure:
server/: Node/Fastify backend, HTTP API, filesystem storage, MCP server.web/: React/Vite frontend.data/<vault>/: local runtime data. The vault name is defined byDEVSYNC_VAULT_NAME.data/<vault>/projects/: local projects. Each folder is one project.- root: Docker, compose, README, shared config.
Operating rule:
- If the request concerns APIs, storage, MCP, or filesystem behavior, work in
server/. - If it concerns UI/UX, components, or client state, work in
web/. - Touch both only for end-to-end integrations or API contract changes.
Devsync must stay simple, readable, and maintainable by AI agents.
Non-negotiable principles:
- KISS: fewer moving parts, fewer abstractions, less magic.
- YAGNI: do not build future layers until the current product path needs them.
- Filesystem first: data must remain inspectable and versionable with git.
- No database until it is truly needed. If needed, prefer SQLite.
- Make the real path work first, then refine.
- If a feature requires a lot of architecture, it is probably too early.
Guiding question: what is the smallest, clearest, most predictable solution that solves the current need?
A Devsync project is a folder under data/<vault>/projects/.
Core concepts:
project.json: project metadata such as name, owner, status, and tags.README.md: base project notes.resources/: raw material, input, sources, uploads, links, notes, images, and PDFs.logs/activity.md: append-only project activity log.work/: material produced or refined by Assistant, automations, or people.
Activity log:
- Must behave like a chat: older entries above, newer entries below.
- The input must stay sticky at the bottom in the UI.
- If a text log is long, store it as a
.mdresource and keep only the link in the log. - Uploads must add an entry to the log.
Current scope includes:
- project management;
- resource/work file management;
- ingestion from uploads, links, and textarea;
- activity log;
- project metadata;
- Assistant chat;
- assistant roles and project/vault instructions;
- automation definitions, manual runs, event triggers, and scheduled runs;
- MCP server with authenticated tools.
Still out of scope unless explicitly requested:
- live external integrations beyond configured tools;
- automatic commit import;
- complex RBAC or organization permissions.
Stack:
- Node ESM.
- Fastify.
- Filesystem storage.
- Node MCP server.
Patterns:
- Keep APIs thin in
server/src/index.js. - Keep filesystem logic in
server/src/storage.js. - Keep MCP logic in
server/src/mcp.js. - Avoid additional frameworks unless there is a concrete need.
- Prefer small, testable functions over premature classes or service layers.
Filesystem rules:
- Never save outside
data/<vault>/. - Always validate project ids and relative paths.
- Prevent path traversal.
- Do not read binary files as UTF-8 unless they are known text files.
- For download/preview, use streams or buffers with the correct MIME type.
- Do not delete user data without explicit confirmation.
Stack:
- React + Vite + TypeScript.
- TanStack Query.
- Tailwind/shadcn style.
- Hugeicons where already used.
UI principles:
- Operational tool, not a landing page.
- Dense, readable, predictable layout.
- No useless decorative components.
- Avoid hidden state or magic behavior.
- Every destructive action must be confirmed.
Project view:
- Left sidebar: global navigation and projects.
- Center area: selected content.
- Right rail: activity log, Assistant/automations, resources, work, tasks.
- Activity input always visible at the bottom.
Keep files human-friendly and agent-friendly.
Preferences:
- Small, stable JSON for structured metadata.
- Markdown for narrative content.
- Append-only activity log with machine-readable markers.
- Readable, safe file names.
- No complex index if a directory scan is enough.
Before changing a data format:
- Verify compatibility with existing data.
- Keep migration simple or preserve backward compatibility.
- Update the README if the contract changes.
Use pragmatic tests for the touched path.
Useful commands:
npm start
npm run build
npm --prefix web run lint
node --check server/src/index.js
npm run mcpE2E/UI rule:
- Do not run e2e tests automatically.
- Do not start servers automatically.
- Do not open browsers automatically.
- Do not perform interactive UI verification unless the user explicitly asks for it.
For visual bugs:
- Verify raw data through the API before changing CSS.
- For file previews, check bytes, MIME type, and browser rendering.
- Do not guess through trial and error when the cause is unclear.
Default: Builder Mode.
- Read the minimum useful context.
- Make small, local changes.
- Do not introduce unrelated refactors.
- Do not install dependencies without a strong reason.
- Do not create abstractions "for the future".
- Explain tradeoffs only when they are needed for a decision.
If a solution looks elegant but increases moving parts, choose a simpler one.
Always preserve:
- Data readable from the filesystem.
- Git/version-control compatibility.
- Small, predictable APIs.
- No hardcoded secrets.
- Assistant and automation writes must stay permission-scoped, auditable, and filesystem-first.
- UI consistent with dark/light themes.
- Explicit errors, no dangerous silent fallbacks.
Every change must improve at least one of:
simplicity, reliability, readability, operability.
If it improves nothing, do not make it.