Skip to content

Releases: ctcstack/ctcdocs

v0.24.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 23:14

Changed

  • A sync exports only what a change reaches. Adding, removing or moving
    a document no longer exports the whole corpus again, nor does renaming a
    folder. A document is exported again when its own file changed, when a
    folder above it was renamed or moved, or when an item it links to
    started or stopped being published; a full sync and a converter upgrade
    still export everything. A narrow run produces the same bytes a full
    run would, which a property test checks over random corpora and changes
    (ADR-053).
  • A sync runs the content gate, not the project's full gate. When
    anything changed, it validates the output, builds once, and runs the
    denial suite and the search check; with nothing changed it checks
    nothing. Formatting, lint, types, unit tests and the browser suite are
    code checks and no longer run on every sync, nor does the denial suite
    run twice (ADR-053).
  • Callers: drafts wait, merges are verified once. The NEW_PROJECT.md
    templates run ci.yml on pull requests that are not drafts and weekly,
    and verify a merge in deploy.yml before deploying it, instead of
    verifying it in both. The platform's own CI skips drafts too.
  • Eight exports at a time. SYNC_CONCURRENCY defaults to 8 instead of
    4: most of a full export is waiting on Google, so this about halves it.

Upgrade note

Replace .github/workflows/ci.yml and deploy.yml with the templates in
docs/NEW_PROJECT.md. Until then, a merge is still verified twice.

v0.23.2

Choose a tag to compare

@github-actions github-actions released this 27 Oct 14:33

Added

  • Phase timings. ctcdocs-sync sync prints how long the inventory,
    planning, export, assembly, validation and write took, and how many
    times it planned the corpus. They go to the log only; nothing generated
    carries them.

Changed

  • A held document is not exported again until it changes. A document
    the sync could not export for a reason of its own (too large, download
    restricted, content refused) is recorded in the manifest under held,
    with the Drive version it failed at. Later syncs keep it held without
    exporting it again until Drive reports a newer version; a full sync, or
    a converter upgrade, tries it again. Before, every sync exported it again
    and planned the corpus twice (ADR-053).

Security

  • Dependencies past new advisories. zod 4.6.6 in the sync and site
    packages; the lockfile takes patched undici, vite, dompurify,
    fast-uri and postcss-selector-parser, and the override for
    Miniflare's pinned undici moves to 7.30.1. vitest is 4.1.12.
    katex stays at 0.16 with one low advisory: its fix is a new minor line.

Upgrade note

The first sync after the upgrade records any held document in
data/sync-manifest.json, so it changes that file once.

v0.23.1

Choose a tag to compare

@github-actions github-actions released this 17 Oct 11:07

Added

  • Connectors show the site's mark. The MCP server names the brand icons
    in its implementation info, and a private deployment serves them before
    sign-in, so Claude, ChatGPT and other clients show the mark beside the
    connector. The build renders the favicon as /icon-192.png and
    /favicon.ico unless public/ holds its own; those, the favicon and its
    dark variant are the only paths an anonymous request is answered with
    (ADR-052).

Upgrade note

Bump the packages and the workflow pins, and deploy. A connector added
before the upgrade may keep showing no icon until it is added again, since
assistants cache what they fetched.

v0.23.0

Choose a tag to compare

@github-actions github-actions released this 11 Oct 23:01

Added

  • Assistants search in the documents' language. A project that sets
    mcp.language, such as en, has the MCP server's instructions, the
    search description and its query field tell an assistant that the
    documents are written in it and that a query in it finds more.
  • Content health names near-duplicate documents. A document whose text is
    at least 80% the same as another's, or stands 95% inside a longer one, is
    noted under Fix next with the other named (ADR-049).
  • What people and assistants could not find. With insights.enabled,
    the Worker records each MCP call and each settled search on the site in a
    D1 database of its own, by the access classes the reader may read and
    never the reader, and every Monday, in UTC, reports the week before: what was not
    found, grouped by its words, what is asked most, what is found and not
    opened, and how the server is used. Admins read it on the content health
    page, under What people could not find; ctcdocs-insights prints it for
    maintainers and writes the week's misses as candidate evaluation
    questions. Records are kept insights.retentionDays, 90 unless set
    (ADR-050, ADR-051).
  • The deploy workflow migrates the state database. With insights on,
    project-deploy.yml applies the platform's migrations to the
    environment's database before it deploys the Worker.
  • Content health asks for the review of stale documents. A document not
    edited in Drive for sync.staleAfterMonths, 12 by default, is noted under
    Improve with the day of its last edit; sync.staleFolders gives a folder
    its own line, 0 for none (ADR-049).

Upgrade note

Bump the packages and the workflow pins, set mcp.language if the documents
are in one language, and deploy. Nothing in R2 or the search index changes.
The two notes appear after the next sync.

Insights are off unless a project turns them on, and need nothing until
then. To turn them on: add D1 Edit to each environment's deploy token, create
each environment's database and bind it as KB_STATE_DB with the platform's
migrations_dir, then set insights.enabled; it needs mcp.enabled and
access.admins. The next deployment applies the migrations
(Cloudflare setup). Running
the platform's tests now needs Node 22.13 or newer.

v0.22.3

Choose a tag to compare

@github-actions github-actions released this 10 Oct 09:51

Added

  • Documents by format, for assistants. The MCP server's search and
    recent give each document its format — doc, pdf, sheet, video
    or audio, the value fetch reports — and browse gives it to each
    document that is not a Google Doc. Every folder of a browse tree, and the
    answer itself, counts its documents by format in formats beside count,
    collapsed folders included, so one browse without a folder says how many
    documents of each format a reader may open, without reading any. All three
    tools take an optional format to keep to one, and the descriptions and
    the server's instructions say so (ADR-044).

Fixed

  • A browse tree that leaves documents out keeps to its budget. The
    omitted count was added after the budget was spent, and could take the
    answer a few dozen characters past mcp.browseCharacters.

Upgrade note

Bump the packages and the workflow pins, and deploy. No sync is needed: the
build already records each document's format.

v0.22.2

Choose a tag to compare

@github-actions github-actions released this 09 Oct 20:17

Fixed

  • A PDF shows on its page again. 0.22.0 gave the private deployment's
    Content Security Policy a frame-src for Google Drive's player, which
    replaced the default for frames rather than adding to it, and browsers
    frame a PDF's <object>: every PDF was blocked. frame-src now admits the
    site's own files beside Drive, and the Worker's test asserts both.

Upgrade note

Bump the packages and the workflow pins. No sync is needed.

v0.22.1

Choose a tag to compare

@github-actions github-actions released this 09 Oct 16:54

A calmer reading interface, and one statement of the kinds of published page.

Changed

  • The sidebar. Folders are named at the size of the documents in them,
    at weight 600 in the muted ink; the folders that hold the current page take
    the strong ink. Rows are taller, with 0.4rem of inline padding, a thin
    chevron and clearer hover and current-page fills. The sidebar is 20.75rem
    wide.
  • Format icons. A PDF, spreadsheet, video or audio page carries a colored
    tile of its format — the letters PDF, a grid, a play button, sound bars —
    after its title in the sidebar, and before it in the section listing, the
    full index, the recency band and the home page's folder cards, in place of
    a badge or the outline of a page. The file-type colors are the one
    exemption from the reserved accent in DESIGN.md.
  • Breadcrumbs are set at 0.8125rem and weight 500 with chevron
    separators, and the title sits 1rem below them.
  • Headings. The sync drops bold that covers a whole heading, as editors
    add it in Google Docs, and the page draws bold inside a heading at 700.
  • A spreadsheet's page records whether it is a Google Sheet, which the
    source link's label reads instead of the address.
  • The header's mark is the project's brand.faviconPath, not a fixed
    /favicon.svg, and keeps the file's own shape.

Added

  • brand.faviconDarkPath, optional: the mark drawn for a dark ground. The
    header shows it under the dark theme the reader chose on the site, whatever
    the system's setting, and a browser with a dark interface shows it in the
    tab.

Internal

  • @ctcstack/ctcdocs-core/document-format names the kinds of page, their
    sourceType, badges, nouns and MCP formats once. The sync, the site and
    the Worker read them from there, and the PDF, spreadsheet and recording
    facts a page records are one zod schema each.

Upgrade note

Bump the packages and the workflow pins, then run a sync. NORMALIZER_VERSION
and SHEET_VERSION moved, so that sync exports every Google Doc and reads
every spreadsheet again once, and the MCP server stores every document again
on its next schedule. Until it runs, headings keep their bold and a Google
Sheet's label is read from its address, as before.

v0.22.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 01:48

Video and audio files get pages
(ADR-047,
proposed): every video or audio file, and every Google Vids video, in a
published folder gets a page written from its Drive metadata, and an uploaded
one plays on it in Google Drive's own player. Nothing is downloaded, hosted
or transcribed.

Added

  • Recording pages. sourceType: drive-media, marked Video or Audio in
    the sidebar, video or audio in data/docs-index.json, llms.txt and the
    MCP server's format. The title is the Drive name without its extension.
    The page opens with a sentence of facts, its length and frame size when
    Drive reports them, then the description written in Drive, whose first line
    is its summary; its web and mail addresses become links.
  • Drive's player on the page. An uploaded recording's card frames
    drive.google.com/file/d/<id>/preview in the video's own shape, with a link
    to it in Drive below. Drive's sharing decides who may play it. Google Vids
    has no player to frame, so its card has the link alone.
  • Content health notes a recording with no description in Drive
    (media-undescribed). The sync report's summary.published gains media.
  • The manifest records exportMode: video or audio, and for a recording
    a sourceChecksum of the metadata its page is written from, so a page is
    written again when its description or length changes.
  • The inventory asks Drive for each file's description and
    videoMediaMetadata.

Changed

  • The private deployment's Content Security Policy admits frames from
    https://drive.google.com, and from nowhere else.
  • A link to a recording, by its Drive or Google Vids address, leads to its
    page, as a link to a published PDF does.
  • Video and audio are no longer listed as not on the site. The
    media-file reason is retired; a report that names it still validates until
    the next sync replaces it.

Upgrade note

Bump the packages and the workflow pins, then run a sync: every recording in
the published folders gets a page on it. No existing page changes. In Safari,
or any browser that blocks third-party cookies, Drive's player cannot use the
reader's Google sign-in and shows an error or a sign-in request; the link
below it always opens the recording in Drive.

v0.21.4

Choose a tag to compare

@github-actions github-actions released this 08 Oct 22:30

Fixed

  • A deployment no longer fails between a platform upgrade and the next
    sync.
    The sync report records the version of the Markdown its lengths
    were measured on, documentLengths.markdownVersion, and the gate compares
    the content health page's length notes with what the MCP server returns
    only when that version is the one the build writes. After 0.21.0 changed
    the Markdown, every deployment before the first sync failed on notes the
    last sync had measured on the old text.

PUBLISHED_MARKDOWN_VERSION in @ctcstack/ctcdocs-core/published-markdown
moves whenever the Markdown version of a page changes.

v0.21.3

Choose a tag to compare

@github-actions github-actions released this 08 Oct 17:50

Fixed

Spreadsheet pages read the way a model is laid out:

  • A note beside an input stays with it. A column of text beside a
    block, on rows the block fills, joins it even across an empty column, and
    a label and value with notes reads Label: value — note. It used to be cut
    off into a list of its own after the inputs.
  • A table split by empty rows keeps its header. A table whose first row
    is data, written with a currency, a percent, a fraction or more than four
    digits, takes the header of the table above it on the same columns, and
    its formulas are named by that header. It used to take its first row of
    data for a header. A header of years is still a header.
  • A sentence on its own line is a paragraph. A caption is a heading when
    it is at most 80 characters and does not end like a sentence.
  • An empty column a block spans is no column of its table.

sheetVersion moves to 2, so the next sync reads every spreadsheet again
once, unchanged uploaded files included.