Content Management
Markdown editing, review workflows, content lab, transcript pipelines, and backend abstraction for Arcturus-Prime content
Content Management
Arcturus-Prime manages all written content as Markdown files with YAML frontmatter, stored in Astro content collections. The admin panel provides a full editorial workflow: browser-based editing, a review queue with editorial flags, an AI-assisted content lab, and a transcript-to-post pipeline. On the backend, a content abstraction layer switches between direct filesystem access in development and the Gitea API in production.
Editor (/admin/edit)
The content editor at /admin/edit is a browser-based Markdown editor capable of creating and modifying files in any content collection (posts, journal, docs, projects, learn). The editor loads a file list from /api/admin/content-index and renders a split-pane interface: file browser on the left, editor on the right, and a live preview panel that can be toggled.
Editor Features
- Syntax highlighting for Markdown, YAML frontmatter, code blocks, and embedded HTML
- Frontmatter form — a structured form view for editing frontmatter fields without touching raw YAML. Fields are typed: text, date, boolean toggle, tag array, and select dropdowns for known enumerations like
sectionandcategory - Auto-save — drafts are saved to localStorage every 30 seconds and can be recovered on reload
- Image upload — drag-and-drop or click-to-upload images. Files are uploaded to
/api/admin/uploadand stored inpublic/images/. The editor inserts the Markdown image syntax at the cursor position - Keyboard shortcuts — Ctrl+S saves, Ctrl+B toggles bold, Ctrl+I toggles italic, Ctrl+K inserts a link template, Ctrl+Shift+P toggles preview
Content Collections
The editor supports all Astro content collections defined in the project:
| Collection | Path | Description |
|---|---|---|
| posts | src/content/posts/ | Blog posts with full frontmatter |
| journal | src/content/journal/ | Personal journal entries from sessions |
| docs | src/content/docs/ | Documentation pages (this site) |
| projects | src/content/projects/ | Project showcase entries |
| learn | src/content/learn/ | Learning path content |
Review Queue (/admin/review)
The review queue at /admin/review surfaces all content that needs editorial attention. It reads two frontmatter flags to drive the workflow:
reviewed: true/false— indicates whether the content has been reviewed by an editorneedsWork: true/false— flags content that was reviewed but requires revisions
The queue displays content in three tabs:
- Pending Review — content where
reviewedisfalseor absent. Sorted by publish date descending so the newest content appears first. - Needs Work — content where
needsWorkistrue. Each entry shows thereviewNotesfrontmatter field explaining what needs to change. - Recently Reviewed — content where
reviewedistrueandneedsWorkisfalse. Sorted by review date for audit purposes.
Reviewers can click any item to open it in the editor with the review panel active. The review panel provides buttons to mark content as reviewed, flag it as needs-work with a note, or send it back to draft status. These actions call the /api/admin/mark-reviewed endpoint which updates the frontmatter in-place.
Content Lab (/admin/content-lab)
The content lab at /admin/content-lab is an AI-assisted content creation environment. It combines the Markdown editor with AI generation capabilities driven by the Arcturus-Prime voice profile stored at data/voice-profile.md.
Voice Profile Integration
Every AI generation request in the content lab includes the voice profile as system context. This ensures generated content matches the Arcturus-Prime writing style: technically precise, conversational but not casual, first-person where appropriate, and grounded in real infrastructure experience. The voice profile defines tone, vocabulary preferences, sentence structure patterns, and topic expertise areas.
Lab Features
- Draft generation — provide a topic and outline, and the AI generates a full draft matching the voice profile. Uses the
/api/admin/content-genendpoint. - Section expansion — highlight a section heading and generate expanded content for that section
- Rewrite — select text and request a rewrite with specific instructions (make it shorter, more technical, add examples)
- Title and description generation — auto-generate SEO-friendly titles and meta descriptions from content
- Tag suggestion — AI analyzes content and suggests relevant tags from the existing tag taxonomy
Pipeline (/admin/pipeline)
The pipeline page at /admin/pipeline manages the transcript-to-post conversion workflow. This is designed for turning raw session transcripts (from Claude Code sessions, pair programming sessions, or voice recordings) into polished journal entries or blog posts.
View Transitions note: The pipeline uses
<script is:inline>with all state in a top-levelvar PS = {...}object. Thevarkeyword (notconst) is required because View Transitions re-executes inline scripts on each navigation —constwould throw “Identifier has already been declared” on the second visit. Functions are exposed toonclickhandlers via explicitwindow.fn = fnassignments.
Pipeline Stages
- Ingest — raw transcripts are uploaded or pasted into the pipeline input. Supported formats: plain text, Markdown, and JSON chat logs.
- Parse — the system extracts structured information: topics discussed, code snippets, decisions made, problems solved, and tools used.
- Transform — the parsed content is restructured into the target format (journal entry or blog post) with appropriate frontmatter generated.
- Voice Align — the transformed content is run through the voice engine to match the Arcturus-Prime writing style. The voice score endpoint at
/api/admin/voice-checkrates the output. - Review — the final draft is placed in the review queue for human approval before publishing.
Pipeline Scripts
Several scripts support the pipeline:
sanitize_journal_entry.py— Python script that strips sensitive information from journal entries. Removes API keys, tokens, passwords, and personal identifiers that may appear in raw transcripts. Applies regex patterns from a configurable rules file.convert_session_to_journal.py— Python script that converts a Claude Code session export into a formatted journal entry. Extracts the conversation flow, identifies key decisions, and structures the output with appropriate headings and code blocks.session-to-blog.js— Node.js script that converts session transcripts into blog post format. More aggressive restructuring than the journal converter: it identifies the core narrative, removes back-and-forth conversational artifacts, and produces a coherent tutorial or write-up style post.
Content API Endpoints
All content operations flow through a set of API endpoints under /api/admin/:
/api/admin/create-content (POST)
Creates a new content file. Accepts a JSON body with collection, slug, frontmatter, and content fields. The endpoint validates frontmatter against the collection schema, generates the file path, and writes the file through the content backend.
/api/admin/update-content (POST)
Updates an existing content file. Accepts collection, slug, and content. Performs a full file overwrite. The endpoint checks that the file exists before writing and returns a 404 if the slug is not found.
/api/admin/update-frontmatter (POST)
Partial frontmatter update without touching the body content. Accepts collection, slug, and a frontmatter object with only the fields to update. The endpoint parses the existing file, merges the new frontmatter fields, and writes the file back. This is used by the review queue to update flags without risk of corrupting content.
/api/admin/content-index (GET)
Returns a JSON index of all content files, optionally filtered by collection query parameter. Each entry includes the slug, title, publish date, tags, draft status, reviewed status, and needsWork status. The index is used by the editor file browser, the review queue, and the dashboard statistics.
/api/admin/mark-reviewed (POST)
Specialized endpoint for the review workflow. Accepts collection, slug, reviewed (boolean), needsWork (boolean), and optional reviewNotes (string). Updates the corresponding frontmatter fields and records the reviewer’s user ID and timestamp.
Content Backend Abstraction
The content API endpoints do not read or write files directly. Instead, they use a content backend abstraction defined in src/lib/content-backend.ts that provides a unified interface with two implementations:
Development: node:fs
In development mode (import.meta.env.DEV), the backend reads and writes directly to the filesystem using Node.js fs module. File paths are resolved relative to the project root. This provides instant feedback during development without requiring a running Gitea instance.
Production: Gitea API
In production, the backend communicates with the Gitea instance at gitea.Arcturus-Prime.com using the Gitea API. All file operations are translated into API calls:
- Read:
GET /api/v1/repos/{owner}/{repo}/contents/{path} - Write:
PUT /api/v1/repos/{owner}/{repo}/contents/{path}(with SHA for updates) - Create:
POST /api/v1/repos/{owner}/{repo}/contents/{path} - Delete:
DELETE /api/v1/repos/{owner}/{repo}/contents/{path}
The Gitea backend authenticates using an access token stored in the GITEA_TOKEN environment variable. Every write operation creates a commit in the repository, providing full version history for all content changes. The commit message includes the editor user’s display name and the type of operation performed.
This abstraction means content editors in the admin panel are always working with the canonical repository, and changes are immediately reflected in the Git history. Deployments are triggered by Gitea webhooks when commits land on the main branch.