Skip to content

Commit 931b5e5

Browse files
author
codewec
committed
chore: prepare release
1 parent 60bc621 commit 931b5e5

13 files changed

Lines changed: 410 additions & 148 deletions

File tree

.changelogenrc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema": "https://unpkg.com/changelogen/schema/changelogen.schema.json",
3+
"types": {
4+
"feat": { "title": "Features" },
5+
"fix": { "title": "Fixes" },
6+
"refactor": { "title": "Refactoring" },
7+
"perf": { "title": "Performance" },
8+
"docs": { "title": "Documentation" },
9+
"build": { "title": "Build System" },
10+
"ci": { "title": "CI/CD" },
11+
"chore": { "title": "Chores" }
12+
}
13+
}

.dockerignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.git
2+
.github
3+
.nuxt
4+
.output
5+
.data
6+
dist
7+
node_modules
8+
npm-debug.log*
9+
pnpm-debug.log*
10+
data
11+
README.md
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Docker Publish
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- '*'
9+
10+
permissions:
11+
contents: read
12+
packages: write
13+
14+
jobs:
15+
publish-dev:
16+
if: github.ref == 'refs/heads/main'
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Docker Buildx
23+
uses: docker/setup-buildx-action@v3
24+
25+
- name: Log in to GHCR
26+
uses: docker/login-action@v3
27+
with:
28+
registry: ghcr.io
29+
username: ${{ github.actor }}
30+
password: ${{ secrets.GITHUB_TOKEN }}
31+
32+
- name: Extract metadata (dev)
33+
id: meta
34+
uses: docker/metadata-action@v5
35+
with:
36+
images: ghcr.io/codewec/editoro
37+
tags: |
38+
type=raw,value=dev
39+
40+
- name: Build and push (dev)
41+
uses: docker/build-push-action@v6
42+
with:
43+
context: .
44+
push: true
45+
tags: ${{ steps.meta.outputs.tags }}
46+
labels: ${{ steps.meta.outputs.labels }}
47+
48+
publish-release:
49+
if: startsWith(github.ref, 'refs/tags/')
50+
runs-on: ubuntu-latest
51+
steps:
52+
- name: Checkout
53+
uses: actions/checkout@v4
54+
55+
- name: Set up Docker Buildx
56+
uses: docker/setup-buildx-action@v3
57+
58+
- name: Log in to GHCR
59+
uses: docker/login-action@v3
60+
with:
61+
registry: ghcr.io
62+
username: ${{ github.actor }}
63+
password: ${{ secrets.GITHUB_TOKEN }}
64+
65+
- name: Extract metadata (release)
66+
id: meta
67+
uses: docker/metadata-action@v5
68+
with:
69+
images: ghcr.io/codewec/editoro
70+
tags: |
71+
type=raw,value=latest
72+
type=ref,event=tag
73+
74+
- name: Build and push (release)
75+
uses: docker/build-push-action@v6
76+
with:
77+
context: .
78+
push: true
79+
tags: ${{ steps.meta.outputs.tags }}
80+
labels: ${{ steps.meta.outputs.labels }}

AGENTS.md

Lines changed: 69 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,137 +1,91 @@
11
# AGENTS.md
22

3-
This document gives AI agents a practical map of the `editoro` codebase.
3+
This file is a practical operating guide for AI agents working on `editoro`.
44

5-
## 1) Project Overview
5+
## 1. Product Summary
66

7-
- Stack: `Nuxt 4`, `Nuxt UI 4`, `Pinia`, `@nuxtjs/i18n`.
8-
- Purpose: local markdown workspace similar to Obsidian.
9-
- Storage: all user files are on disk in `data/`.
10-
- Main UI:
11-
- left: file tree with DnD, create/rename/delete.
12-
- right: editor / image preview / folder browser.
13-
- Supported locales: `en` (default), `ru`.
7+
- App type: local-first markdown workspace (Obsidian-like UX).
8+
- Frontend stack: `Nuxt 4`, `Nuxt UI 4`, `Pinia`, `@nuxtjs/i18n`.
9+
- Storage: filesystem-backed content in `data/`.
10+
- Left panel: tree, DnD, create/rename/delete, hidden files toggle.
11+
- Right panel: markdown editor, image preview, folder browser.
12+
- Locales: `en` (default), `ru`.
1413

15-
## 2) Key Runtime Flows
14+
## 2. Runtime Architecture
1615

17-
1. App mounts `app/pages/index.vue` -> renders `EditoroWorkspace`.
18-
2. `useEditoro()` (`app/composables/useEditoro.ts`) returns grouped API.
19-
3. `useEditoroState()` composes stores + lifecycle + view model + actions.
20-
4. Tree and route query `?file=...` are synchronized in `useEditoroFileSelection`.
21-
5. Markdown content autosaves via editor persistence composable.
22-
6. Image uploads go to sibling `.media` folder of current markdown file.
16+
### Composition Root
2317

24-
## 3) Architecture (Current)
18+
- `app/pages/index.vue` renders `EditoroWorkspace`.
19+
- `app/composables/useEditoro.ts` exposes grouped public API.
20+
- `app/composables/useEditoroState.ts` orchestrates stores + logic.
2521

26-
### UI Components
22+
### Core Components
2723

28-
- `app/components/editoro/Workspace.vue`: top-level layout composition.
29-
- `app/components/editoro/Sidebar.vue`: tree panel + settings modal.
30-
- `app/components/editoro/MainHeader.vue`: file/folder title + actions + save status.
31-
- `app/components/editoro/MainContent.vue`: folder browser / image preview / editor.
32-
- `app/components/editoro/Modals.vue`: create/rename/delete dialogs.
24+
- `app/components/editoro/Workspace.vue` - page-level layout shell.
25+
- `app/components/editoro/Sidebar.vue` - tree panel and sidebar controls.
26+
- `app/components/editoro/MainHeader.vue` - active item title, pinning, actions.
27+
- `app/components/editoro/MainContent.vue` - editor/browser/preview surface.
28+
- `app/components/editoro/Modals.vue` - create/rename/delete/settings modals.
3329

3430
### Stores
3531

36-
- `app/stores/editoroTree.ts`: tree state, loading, selection, DnD.
37-
- `app/stores/editoroEditor.ts`: editor content, mode, save state, upload API.
38-
- `app/stores/editoroPreferences.ts`: locale, color mode, hidden entries.
39-
- `app/stores/editoroUi.ts`: modals and other UI control state.
40-
41-
### Composable Layers
42-
43-
- `app/composables/useEditoroState.ts`: orchestration root.
44-
- `app/composables/useEditoroContext.ts`: internal wiring of stores/actions/view-model.
45-
- `app/composables/useEditoroLifecycle.ts`: SSR+mount hooks/watchers.
46-
- `app/composables/useEditoroFileSelection.ts`: selected node <-> route file query logic.
47-
- `app/composables/useEditoroEntryActions.ts`: create/rename/delete flows.
48-
- `app/composables/useEditoroViewModel.ts`: computed UI-facing derived data.
49-
- `app/composables/api/*`: builders of final public grouped API.
50-
- `app/composables/workspace/*Bindings.ts`: binds state to component props/events.
51-
52-
### Server
53-
54-
- `server/utils/data-storage.ts`: all filesystem operations and invariants.
55-
- `server/api/files/*.ts`: tree/content/create/move/delete/image/media endpoints.
56-
- `app/services/files-api.ts`: client API wrappers for server endpoints.
57-
58-
## 4) Critical Invariants (Do Not Break)
59-
60-
1. Security/path safety:
61-
- Any filesystem path must remain inside `data/`.
62-
- Use existing helpers (`normalizeRelativePath`, `resolveDataPath`).
63-
2. Markdown editing:
64-
- Only markdown files are editable/savable (`.md`).
65-
- Non-markdown files show unsupported format or preview (for images).
66-
3. Route sync:
67-
- Opened file must be reflected in `?file=...`.
68-
- On refresh, restore selection if file exists; clear query if invalid.
69-
4. Tree UX:
70-
- Preserve expanded paths on reload.
71-
- Keep selected node and ancestors expanded when possible.
72-
5. Media handling:
73-
- Uploaded images go to `<markdown-folder>/.media`.
74-
- On markdown save, remove orphan media files.
75-
- Remove empty `.media` directories after cleanup.
76-
6. SSR/hydration:
77-
- Avoid client-only state mismatches that cause hydration warnings.
78-
- Keep lifecycle hooks inside proper setup/composable execution flow.
79-
80-
## 5) File Map for Common Tasks
81-
82-
- Change tree behavior/icons: `server/utils/data-storage.ts`, `Sidebar.vue`, `app/utils/editoro-tree.ts`.
83-
- Change selection/query behavior: `useEditoroFileSelection.ts`, `useEditoroLifecycle.ts`.
84-
- Change autosave/status: `useEditoroEditorPersistence.ts`, `useEditoroEditorStatus.ts`, `MainHeader.vue`.
85-
- Change image upload/DnD in editor: `useEditoroMainContentMedia.ts`, `useEditoroEditorUploads.ts`, `server/api/files/image.post.ts`.
86-
- Change i18n/settings: `editoroPreferences.ts`, `nuxt.config.ts`, `i18n/locales/*.json`.
87-
88-
## 6) Development Commands
89-
90-
Use `pnpm` in normal environment:
32+
- `app/stores/editoroTree.ts` - tree items, selection, expansion, tree loading.
33+
- `app/stores/editoroEditor.ts` - editor content, view mode, save state, media upload.
34+
- `app/stores/editoroPreferences.ts` - locale, theme, hidden files settings.
35+
- `app/stores/editoroUi.ts` - modal states and workspace UI flags.
9136

92-
```bash
93-
pnpm install
94-
pnpm dev
95-
pnpm lint
96-
pnpm typecheck
97-
pnpm build
98-
```
37+
### Server Layer
38+
39+
- `server/utils/data-storage.ts` - path validation + filesystem operations.
40+
- `server/api/files/*.ts` - content/tree/create/rename/delete/move/image endpoints.
41+
- `app/services/files-api.ts` - client wrappers for server API.
9942

100-
## 7) Change Checklist for Agents
43+
## 3. Non-Negotiable Invariants
10144

102-
Before coding:
103-
- Identify impacted layer(s): component, store, composable, server API.
104-
- Prefer existing abstractions over adding logic to `Workspace.vue`.
45+
1. Keep all file operations inside `data/`.
46+
2. Preserve `?file=...` sync with selected file.
47+
3. Keep SSR/hydration stable (no client-only mismatch regressions).
48+
4. Preserve tree expansion/selection behavior across refresh/actions.
49+
5. Markdown media rules: uploads go to sibling `.media`.
50+
6. Markdown media rules: orphan media is removed only when truly unreferenced.
51+
7. Markdown media rules: empty `.media` directory should be removed.
10552

106-
While coding:
107-
- Keep strict TypeScript typing; avoid `any`.
108-
- In composables/helpers, keep comments in English.
109-
- Preserve existing public API shape of `useEditoro()` unless refactor requires migration everywhere.
53+
## 4. Release and Deployment Surface
11054

111-
After coding:
112-
- Run `lint` + `typecheck`.
113-
- Manually verify:
114-
- tree selection and expansion,
115-
- route `?file=...` restore on refresh,
116-
- create/rename/delete for files and folders,
117-
- markdown autosave indicator behavior,
118-
- image upload, preview, and orphan cleanup.
55+
- `Dockerfile` builds and runs Nuxt production output.
56+
- `docker-compose.yml` runs app with `./data:/app/data`.
57+
- `deploy/lxc/lxd-editoro.yaml` provides LXD cloud-init profile.
58+
- `deploy/lxc/lxc.conf` provides classic LXC config example.
59+
- CI workflow: `.github/workflows/docker-publish.yml`.
60+
- Push to `main` publishes `ghcr.io/codewec/editoro:dev`.
61+
- Push tag publishes `ghcr.io/codewec/editoro:latest` and `:<tag>`.
11962

120-
## 8) Preferred Refactoring Direction
63+
## 5. Changelog Workflow
12164

122-
- Keep `Workspace.vue` declarative (bindings only).
123-
- Move heavy logic from components to composables.
124-
- Keep stores focused:
125-
- tree-only concerns in tree store/composables,
126-
- editor-only concerns in editor store/composables,
127-
- preferences-only concerns in preferences store.
128-
- Keep server filesystem logic centralized in `data-storage.ts`.
65+
- Tool: `changelogen`.
66+
- Config: `.changelogenrc`.
67+
- Commands: `pnpm changelog`, `pnpm changelog:release`.
68+
- Conventional commits are expected for clean release notes.
12969

130-
## 9) Notes About Existing UX Decisions
70+
## 6. Development Commands
13171

132-
- Default locale is English.
133-
- Hidden entries toggle exists and hidden folders use a different folder icon.
134-
- Sidebar width is persisted and restored.
135-
- Rich/raw is handled as a toggle mode.
136-
- For folders, right panel shows folder contents with navigation to parent.
72+
```bash
73+
pnpm install
74+
pnpm dev
75+
pnpm lint
76+
pnpm typecheck
77+
pnpm build
78+
pnpm changelog
79+
```
13780

81+
## 7. Agent Working Rules
82+
83+
- Prefer existing composables/stores over adding logic into large UI components.
84+
- Keep strict TypeScript typing, avoid `any`.
85+
- Keep comments in English (especially in composables/helpers).
86+
- For refactors, preserve existing public contracts used by `useEditoro()` and workspace bindings.
87+
- Validate critical flows after changes: tree open/select/expand.
88+
- Validate critical flows after changes: route restore on refresh.
89+
- Validate critical flows after changes: create/rename/delete/move.
90+
- Validate critical flows after changes: markdown autosave and status indicator.
91+
- Validate critical flows after changes: image upload/preview/cleanup.

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
This file is managed with `changelogen`.

Dockerfile

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
FROM node:22-alpine AS deps
2+
WORKDIR /app
3+
4+
ENV PNPM_HOME="/pnpm"
5+
ENV PATH="$PNPM_HOME:$PATH"
6+
7+
RUN apk add --no-cache libc6-compat
8+
RUN npm i -g pnpm@10.28.2
9+
10+
COPY package.json pnpm-lock.yaml ./
11+
RUN pnpm install --frozen-lockfile
12+
13+
FROM node:22-alpine AS build
14+
WORKDIR /app
15+
16+
ENV PNPM_HOME="/pnpm"
17+
ENV PATH="$PNPM_HOME:$PATH"
18+
19+
RUN apk add --no-cache libc6-compat
20+
RUN npm i -g pnpm@10.28.2
21+
22+
COPY --from=deps /app/node_modules ./node_modules
23+
COPY . .
24+
RUN pnpm build
25+
26+
FROM node:22-alpine AS runner
27+
WORKDIR /app
28+
29+
ENV NODE_ENV=production
30+
ENV NITRO_HOST=0.0.0.0
31+
ENV NITRO_PORT=3000
32+
33+
RUN apk add --no-cache libc6-compat
34+
35+
COPY --from=build /app/.output ./.output
36+
37+
RUN mkdir -p /app/data
38+
VOLUME ["/app/data"]
39+
40+
EXPOSE 3000
41+
42+
CMD ["node", ".output/server/index.mjs"]

LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 Nuxt UI Templates
3+
Copyright (c) 2025 codewec
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
21+
SOFTWARE.

0 commit comments

Comments
 (0)