Skip to content

Releases: carlosboeing/penmark

Penmark v0.6.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 01:34
61b43bf

Raw-text elements pass through the inline render path

  • The preview now shows the authored value of a self-closing raw-text element such as <textarea/>. markdown-it has no HTML parser, so that spelling used the inline path. The per-text-node source-offset spans then appeared inside the element's value as literal text.
  • A new inline rule turns a raw-text open tag and everything up to its end tag into a single token. It covers script, style, textarea, title, xmp, noembed, noframes and iframe. An element with no end tag continues to the end of the block, matching browser display.
  • The renderer still stamps ordinary inline text with source offsets, and comment highlighting is unchanged.

Markdown links open in a Penmark tab; frontmatter card keeps its state

  • Relative links to markdown files now open in a new Penmark preview tab. The opener is vscode.openWith on penmark.previewEditor, with vscode.open as fallback. Extensionless wiki-links resolve via an existence probe: .md suffix first, then the workspace root.
  • mailto: and ftp: links open in the system handler. file: URIs open inside the IDE. Neither is resolved as a relative file path. Untitled and remote documents skip existence probing, since there is no local directory to probe.
  • The frontmatter card keeps its collapse state across preview re-renders and tab switches. Persistence is getState/setState while the tab is open. Cards with more than three keys still start collapsed. Version 0.6.0.

OSS repository safeguards

  • CI now uses immutable action and browser-container references, explicit least-privilege permissions, timeouts, pull-request run cancellation, and a stable required aggregate check while preserving the full operating-system and VS Code-version matrix.
  • Release verification now runs under bash with safe.directory, --shm-size=2g, and built-in Node ZIP manifest extraction inside the pinned Playwright container, accepts only three-component version tags, repeats the complete suite on the tagged commit, checks VSIX contents and version coherence, writes a checksum, creates an artifact build-provenance attestation (actions/attest-build-provenance), and smoke-tests the downloaded release asset; manual dispatch remains verification-only.
  • Added public runtime dependency notices and removed internal path examples from public artifacts.

Dependabot can read the lockfile again

  • package-lock.json held conflict markers inside the inner packages[""] version hunk. Every Dependabot update job stopped with dependency_file_not_parseable, so no dependency update reached a pull request.
  • The hunk now resolves to 0.6.0, which matches package.json and the lockfile's own top-level version.

Agent-authored character entities render as punctuation

Agent-generated review comments can encode punctuation as decimal HTML character references, such as &#45; for a hyphen. Penmark decoded only its own paired-hyphen storage sentinel (&#45;&#45;), so a single reference reached the drawer and popover as visible source text. Penmark now renders any valid decimal reference as the character it denotes, using markdown-it's own validity rule so surrogates, NUL, control characters and noncharacters stay literal rather than becoming ill-formed text a save could write into the file.

This rendering is a presentation pass, applied where a note is handed to the preview and where one is exported for an agent. An entry's quote is exempt: it stays byte-faithful all the way to the drawer, which renders it at the point of display. Re-anchor re-adds the same quote at a new location, so a rendered quote would be stored and could never match the document again, and the next anchor loss would orphan a comment that would otherwise recover. It is deliberately not part of the storage codec. Decoding at parse time instead would have broken two things: quote recovery matches an entry's quote against raw document bytes, so a quoted passage that itself contains a reference would stop matching and the comment would orphan; and because the writer escapes only --, each read-and-save cycle would strip one more level from text the user never edited. Keeping the pass at the display seam leaves the spec's round-trip guarantee intact for every string. The validity rule is written out rather than imported: pulling markdown-it's helper into the eager extension entry took dist/extension.js from 53 KB to 136 KB, against a sub-50 ms activation budget. A test pins the copy to markdown-it across every code point. Format spec §6 gains a non-normative reader-side rule; regression tests cover the sentinel, standalone references, each rejected range, and the three consumers that need raw bytes.

Commenting no longer breaks the formatting it wraps

Commenting a bullet that opens in bold left the asterisks showing in the preview: **Subscription-billed.** rendered literally instead of bold. Reported from a real review session.

  • An anchor at the start of a line no longer starts an HTML block — CommonMark treats any line beginning with <!-- as raw HTML through the closing -->, so the whole line skipped inline parsing. This was never specific to bold: inline code, links and italics on that line all rendered as source. It fired wherever inline-safety snapping pushed a span opener to the start of a block's content — bullets and ordered items (including nested ones), paragraphs, blockquotes, a paragraph's continuation line, and a closer landing at a line start. The renderer now declines the HTML-block rule for a line that leads with a pmk anchor and still carries content, so those lines take the inline path where the marker passes through verbatim at the exact extent (ADR 0006). Lines holding nothing but a marker keep the old behaviour, because pmk:b and pmk:r anchors own their line by design (§4.2), and a hand-written <!-- note --> still behaves as stock CommonMark.
  • A highlight spanning list items stays visible past the first one — a bullet list is one block, so commenting three of five bullets is a span, not a range. The single <mark> wrapped </li><li>, which is invalid nesting; because <mark> is not an HTML formatting element the browser closes it at </li> and discards the stray closer, silently dropping the highlight from every item after the first. The extent is now split into one <mark> per inline run, all sharing the comment id. An extent inside a single block still produces exactly one <mark>, byte-for-byte as before.
  • The split reads as one control — the fragments of a split highlight would otherwise each become a tab stop announcing the same comment. Only the first carries the keyboard affordance and the gutter dot; clicking any fragment still opens the popover, and all fragments light up together when the comment is active.
  • Tests cover the boundary cases the fixtures missed — the anchored-doc fixture had no line-start anchor, so no snapshot could have caught this. New tests pin each block context that broke, both marker-only-line behaviours, a non-pmk comment at a line start, and the cross-block split down to whitespace handling.

Multi-block selections were already correct and are unchanged: a heading, paragraph, fenced code and list selected together still become one range wrapper with their formatting intact.

What's Changed

  • fix(comments): keep markdown formatting intact around inline anchors by @carlosboeing in #50
  • chore(git): add the private-workbench pre-commit guard by @carlosboeing in #53
  • chore: gitignore local git worktrees by @carlosboeing in #54
  • docs: scope worktrees to implementation work by @carlosboeing in #56
  • docs: stop instructing agents to cite private design docs in public by @carlosboeing in #57
  • Decode agent-authored decimal character references by @carlosboeing in #59
  • chore(governance): align repository with OSS house standard by @carlosboeing in #61
  • chore(governance): add SUPPORT.md to house standard by @carlosboeing in #62
  • feat(preview): open markdown links in new tab and persist frontmatter state by @carlosboeing in #44
  • fix(deps): remove merge markers from package-lock.json by @carlosboeing in #63
  • chore(deps): bump dompurify from 3.4.11 to 3.4.14 by @dependabot[bot] in #48
  • chore(deps-dev): bump undici from 7.28.0 to 7.29.0 by @dependabot[bot] in #45
  • chore(deps-dev): bump fast-uri from 3.1.2 to 3.1.6 by @dependabot[bot] in #46
  • chore(deps-dev): bump postcss from 8.5.16 to 8.5.26 by @dependabot[bot] in #52
  • chore(deps-dev): bump js-yaml from 4.2.0 to 4.3.2 by @dependabot[bot] in #60
  • chore(deps): bump mermaid from 11.16.0 to 11.16.1 by @dependabot[bot] in #47
  • chore(deps-dev): bump brace-expansion from 2.1.1 to 2.1.4 by @dependabot[bot] in #66
  • chore(deps): bump Playwright to 1.62.1 with container image by @carlosboeing in #67
  • chore(deps): bump the minor-and-patch group across 1 directory with 13 updates by @dependabot[bot] in #68
  • fix(render): keep raw-text elements whole on the inline path by @carlosboeing in #69
  • docs(changelog): record raw-text in...
Read more

Penmark v0.5.3

Choose a tag to compare

@github-actions github-actions released this 31 Jul 13:17
7bd4e82

What's Changed

  • chore: ignore .workbench/ and genericize private-repo refs in CLAUDE.md by @carlosboeing in #4
  • chore(git): add Playwright temporary directories to gitignore by @carlosboeing in #5
  • feat(custom-editor): support custom text editors in Penmark by @carlosboeing in #6
  • feat(custom-editor): add direct context menu option to open with Penmark by @carlosboeing in #8
  • feat(v1-polish): implement v1.0 polish features by @carlosboeing in #10
  • feat(ui-ux): audit and implement premium webview UI/UX polish by @carlosboeing in #12
  • feat(export): add HTML and PDF export by @carlosboeing in #22
  • chore(deps): bump js-yaml and markdownlint-cli2 by @dependabot[bot] in #23
  • ci(deps): bump actions/checkout from 6 to 7 by @dependabot[bot] in #15
  • chore(deps-dev): bump @types/node from 25.9.3 to 26.1.0 by @dependabot[bot] in #17
  • chore(deps): bump dompurify from 3.4.10 to 3.4.11 by @dependabot[bot] in #14
  • chore(deps): bump undici from 7.27.2 to 7.28.0 by @dependabot[bot] in #13
  • chore(deps-dev): bump form-data from 4.0.5 to 4.0.6 by @dependabot[bot] in #7
  • chore(deps): bump the minor-and-patch group across 1 directory with 8 updates by @dependabot[bot] in #26
  • chore(deps-dev): bump vitest + @vitest/coverage-v8 to 4.1.10 by @carlosboeing in #27
  • feat(ui): ship adaptive review surface by @carlosboeing in #32
  • feat(find): add in-preview search fallback by @carlosboeing in #35
  • fix(find): restore matching for longer queries, clear search on close by @carlosboeing in #36
  • docs(changelog): mark the find fixes as shipped by @carlosboeing in #37
  • fix(ui): panel, search and typography bug bash by @carlosboeing in #38
  • fix(comments): keep comments readable after a format-on-save by @carlosboeing in #41
  • docs(roadmap): add comment deep links to future considerations by @carlosboeing in #42
  • feat(webview): type-aware frontmatter card lists, status borders, and path links by @carlosboeing in #43

New Contributors

Full Changelog: v0.1.0...v0.5.3

Penmark v0.5.0 — Review MVP

Choose a tag to compare

@carlosboeing carlosboeing released this 15 Jun 03:02

Penmark v0.5.0 — the Review MVP. Penmark now does its differentiating thing: Google-Docs-style inline review comments on rendered markdown, stored in the document itself, built for reviewing AI-authored design docs / plans / research in the IDE.

Local-first: download the VSIX below and sideload into VS Code / Cursor / Antigravity (--install-extension penmark-markdown-review-0.5.0.vsix or Extensions → Install from VSIX…). Compatibility floor engines.vscode ^1.105.0.

Highlights

  • Inline comments — select rendered prose, add a comment; stored as invisible pmk:s/b/r anchors + a single trailing pmk:review block per the frozen public format (spec/penmark-format.md, agent contract in AGENTS-GUIDE.md).
  • Highlights, gutter dots, resolve popover — theme-aware, intensity-configurable; blue (human) / purple (agent) authorship.
  • Comments drawer + needs-attention bucket + attention chip — orphaned / content-removed / degraded comments surfaced by the §8 reconcile degradation ladder, with re-anchor and delete.
  • Add / resolve as one undo step (single WorkspaceEdit), author identity, reconcile on open/change (corruption flagged, never silently swallowed).
  • Export review as an agent-ready prompt for handoff to a coding agent.
  • Release-blocking acceptance gate — golden suite over the §8 desync states + real git merge-file concurrent-merge scenarios, proving the single-file format survives 3-way merges.

Core VSIX 581 KiB (mermaid chunk excluded, lazy-loaded), under the 1 MiB budget.

Known limitation

Resolving a 3-way merge by keeping two pmk:review blocks surfaces the non-EOF block's comments via the corruption flag only, not yet in needs-attention (§8.5, tracked post-v0.5). No data loss; the union resolution is fully lossless.

Verification

CI is billing-blocked, so this release was verified locally per plan D16: build, typecheck, eslint, vitest run --coverage (717 passed; src/core/comments ≥95%), Docker Playwright goldens, and the VSIX size gate. The manual cross-IDE smoke (docs/guides/release-smoke-checklist-v0.5.md) is the remaining human step.

Full notes: CHANGELOG.

🤖 Generated with Claude Code

Penmark v0.1.0

Choose a tag to compare

@carlosboeing carlosboeing released this 15 Jun 03:01

What's Changed

New Contributors

Full Changelog: https://github.com/carlosboeing/penmark/commits/v0.1.0