Skip to content

fix(engine): CRLF frontmatter, shared per-OS paths, multi-platform spec amendments - #173

Merged
siracusa5 merged 3 commits into
mainfrom
c/multi-platform-downloads-ca2eb1
Sep 17, 2026
Merged

siracusa5 merged 3 commits into
mainfrom
c/multi-platform-downloads-ca2eb1

Conversation

@siracusa5

Copy link
Copy Markdown
Collaborator

Summary

First slice of the multi-platform downloads work: Intel Mac, a Linux .deb, a CLI that installs and runs without the Mac app, and the Windows MCPB. This PR records those decisions in the specs and lands two engine fixes the rest builds on. A file saved with Windows line endings now keeps its frontmatter. The app, its bundled CLI, and the npm CLI now agree on where the manifest lives on every OS.

Changes

  • Specs (dated amendments, originals kept):
    • Distribution spec: new "Platforms" acceptance criteria. Intel Mac and Linux .deb x64 are in scope; AppImage, a Windows desktop app, and non-macOS self-update stay out, with the reasons.
    • Distribution design: new §11 covering the release platform table, per-OS install and config locations, Linux .deb specifics, and split release jobs.
    • Control-plane spec and design: npm before Homebrew, dispatcher moves into the engine, npm package ships fixtures/*.json, Windows milestone starts with the read path.
    • Channels and site specs: out-of-scope and /install requirements updated.
  • CRLF frontmatter (packages/core/src/frontmatter.mjs):
    • Four readers each checked startsWith("---\n"): okf-local, files, layer-files, promote. A CRLF file lost its type, title, and dates without warning.
    • Past that check, the last field kept a trailing \r and was dropped.
    • All four now use one helper, and frontmatter writes keep the file's line endings.
  • Shared per-OS paths (packages/core/src/platform-paths.mjs):
    • Config, data, and cache for macOS, Linux (XDG), and Windows, per control-plane §5.12, with CONTEXTCAKE_* overrides.
    • The app-bundled CLI always answered the macOS path; the npm CLI answered ~/.config on Windows. Both now read their default manifest from the helper.
  • Promotion bindings now live in the data directory:
    • On macOS they used to sit in a Local State folder inside Electron's userData. Chromium keeps a file of that name there, so staging a promotion failed with ENOTDIR on any Mac that had run the app.
    • Bindings already staged in the old location are still read and cleaned up.
  • CLAUDE.md key-files rows for both new modules; the desktop "pinned three places" gotcha now names platform-paths.mjs.

Test Plan

  • Root npm test: 65/65 suites, retrieval eval shows no regression
  • apps/desktop: npm test 153/153 on Node 22, test:cli-status, test:navigation
  • New frontmatter suite: CRLF and LF parse identically; a CRLF frontmatter write reads the last field and keeps CRLF
  • New platform-paths suite covering darwin, linux (incl. relative XDG ignored), win32, overrides
  • Staged npm package test: the built CLI resolves its default manifest through platform-paths.mjs
  • ENOTDIR fix verified: profile-runtime-test.sh run without CONTEXTCAKE_LOCAL_STATE_DIR under a HOME where Local State is a file. It passes; the old path fails with ENOTDIR.
  • CI checks pass

Notes

  • No user-visible behavior changes on macOS except the promotion fix. The CLI's default manifest path on macOS is unchanged.
  • Linux users of the (unpublished) npm CLI would have used ~/.config/ContextCake; it is now ~/.config/contextcake per §5.12. Nothing has shipped there.
  • apps/desktop npm run smoke was not run: it needs a console build, and nothing here touches app startup.
  • Before the npm step: contextcake and context-cake are both unregistered on npm. Reserve them with hand-published 0.0.0 placeholders.

🤖 Generated with Claude Code

siracusa5 and others added 2 commits September 16, 2026 23:20
…bution

Record the 2026-09-16 platform decisions as dated amendments beside the
original text:

- distribution spec: Intel Mac (x64) and Linux .deb (x64) in scope, with
  EARS criteria; AppImage, a Windows desktop app, and non-macOS
  self-update stay out. Fix the stale npm package name.
- distribution design: new §11 (one release platform table, per-platform
  install locations and CLI channel, Linux .deb specifics, split release
  jobs).
- control-plane: npm publishes before Homebrew; the CLI dispatcher moves
  into the engine; the npm package ships the policy fixtures; milestone 7
  starts with the Windows read path.
- channels and site specs: native Intel Mac and Linux downloads, npm CLI
  as the no-app route.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: John Siracusa <siracusa5@users.noreply.github.com>
CRLF: every frontmatter reader tested startsWith("---\n"), so a file saved
with Windows line endings parsed as having no frontmatter and silently lost
its type, title, and dates; past the fence, the last field kept a trailing
\r and was dropped too. okf-local, files, layer-files, and promote now go
through one splitFrontmatter helper, and frontmatter writes keep the file's
line endings.

Paths: new platform-paths.mjs answers where config, data, and cache live on
macOS, Linux (XDG), and Windows, per control-plane spec §5.12, with
CONTEXTCAKE_* overrides. The app-bundled CLI (always the macOS path before)
and the npm CLI (~/.config on Windows before) both read their default
manifest from it.

Promotion bindings move to the data directory. Their macOS home was a
"Local State" folder inside Electron's userData, where Chromium keeps a file
of that name, so staging a promotion failed with ENOTDIR on any Mac that had
run the app. Bindings staged in the old location are still read and removed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: John Siracusa <siracusa5@users.noreply.github.com>
@siracusa5 siracusa5 added bug Something isn't working documentation Improvements or additions to documentation labels Sep 17, 2026
The SQLite store reuses postings by file fingerprint (size, mtime), which a
parser change never touches. Without a format bump, an unchanged CRLF note
indexed before the frontmatter fix would keep postings and a `type` column
from its old frontmatter-less parse until someone edited it. Bump
FORMAT_VERSION to 6, test that an older-format store re-analyzes every
document, and record the rule in CLAUDE.md.

Also note in the manifest trust gotcha that CONTEXTCAKE_MANIFEST and
CONTEXTCAKE_CONFIG_DIR select the CLI's default manifest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: John Siracusa <siracusa5@users.noreply.github.com>
@siracusa5
siracusa5 merged commit 16f261e into main Sep 17, 2026
9 checks passed
@siracusa5
siracusa5 deleted the c/multi-platform-downloads-ca2eb1 branch September 17, 2026 20:15
siracusa5 added a commit that referenced this pull request Sep 17, 2026
main moved while this PR was open: #173 landed as a squash commit, and #174
(homepage hero) and #183 (version 0.9.4) landed beside it. The squash gave
#173's content a new identity, so the three files this branch already carries
from it conflicted; this branch's versions supersede them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: John Siracusa <siracusa5@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant