{"_id":"@amit-t/stet-md","name":"@amit-t/stet-md","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@amit-t/stet-md","version":"0.1.0","description":"Local Markdown review utility for engineers and AI agents: threaded comments that live inside Markdown files with byte-splice persistence.","keywords":["markdown","review","comments","annotations","local-first","cli","agents"],"license":"MIT","type":"module","engines":{"node":">=20.10"},"bin":{"stet-md":"dist/cli/main.js","stmd":"dist/cli/main.js"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./core":{"types":"./dist/core/index.d.ts","import":"./dist/core/index.js"},"./safety":{"types":"./dist/safety/index.d.ts","import":"./dist/safety/index.js"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.js"}},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit","test":"vitest run tests/core tests/cli tests/safety tests/server tests/security tests/browser","test:core":"vitest run tests/core","test:cli":"vitest run tests/cli","test:server":"vitest run tests/server tests/security","test:browser":"vitest run tests/browser","test:packaging":"pnpm run build && vitest run tests/packaging","ci":"pnpm run typecheck && pnpm test && pnpm run test:packaging","pack:dry":"pnpm pack --dry-run","prepack":"pnpm run build","prepublishOnly":"pnpm run ci"},"dependencies":{"js-yaml":"^4.2.0","remark-parse":"^11.0.0","unified":"^11.0.5"},"devDependencies":{"@types/js-yaml":"^4.0.9","@types/mdast":"^4.0.4","@types/node":"^22.10.0","happy-dom":"latest","typescript":"^5.7.0","vitest":"^4.1.8"},"repository":{"type":"git","url":"git+https://github.com/amit-t/stet-md.git"},"homepage":"https://github.com/amit-t/stet-md#readme","bugs":{"url":"https://github.com/amit-t/stet-md/issues"},"packageManager":"pnpm@10.33.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"gitHead":"59dd2c6fa56427a5da0951e785a9c30f153d58c1","_id":"@amit-t/stet-md@0.1.0","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-jDZCn3AQ12yixpqHiFH+4OKGNe+Ox3dVIeqeNYYYKWLwMyWST7lFWGqqYG+KU3Tnj4IzqXs6y60WrZKpjS+vkw==","shasum":"fd76821607e46f0ce413a7a93caab18657a7e6e7","tarball":"https://registry.npmjs.org/@amit-t/stet-md/-/stet-md-0.1.0.tgz","fileCount":167,"unpackedSize":380663,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBGmSmIG/44NLSsfVWZ9EA43W5l+JuuKESO8XRcQWFSfAiBz1VUny1/zq/6idpFI/TkFUxWfpLGNOhBvsZLSb9xVgw=="}]},"_npmUser":{"name":"amit-t","email":"tiwari.m.amit@gmail.com"},"directories":{},"maintainers":[{"name":"amit-t","email":"tiwari.m.amit@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stet-md_0.1.0_1780916728844_0.6614008276743515"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-08T11:05:28.738Z","0.1.0":"2026-06-08T11:05:28.980Z","modified":"2026-06-08T11:05:29.483Z"},"maintainers":[{"name":"amit-t","email":"tiwari.m.amit@gmail.com"}],"description":"Local Markdown review utility for engineers and AI agents: threaded comments that live inside Markdown files with byte-splice persistence.","homepage":"https://github.com/amit-t/stet-md#readme","keywords":["markdown","review","comments","annotations","local-first","cli","agents"],"repository":{"type":"git","url":"git+https://github.com/amit-t/stet-md.git"},"bugs":{"url":"https://github.com/amit-t/stet-md/issues"},"license":"MIT","readme":"# Stet.md\n\nStet.md is a local-first Markdown review utility. It opens one Markdown file in a loopback browser UI, lets humans add threaded review comments, saves those threads back into the same Markdown file, and lets AI agents reply through a safe CLI.\n\n- npm package: `@amit-t/stet-md`\n- binaries: `stet-md`, `stmd`\n- marker: `stet:thread`\n- thread IDs: `stt_...`\n- transient state: `.stet/`\n\n## Documentation\n\nBrowsable docs site (GitHub Pages): **https://amit-t.github.io/stet-md/**\n\nThe site is a static neo-brutalist index served from [`docs/`](docs/): a capability explorer (Browser UI, Agent CLI, Storage, Safety, Security) with per-capability commands, a changelog, search/filter, dark mode, and copy-to-clipboard. It was scaffolded with the `gh-repo-mirror` skill design system; source lives in [`docs/index.html`](docs/index.html), [`docs/site.css`](docs/site.css), and [`docs/site.js`](docs/site.js).\n\nDeeper references:\n\n- [`docs/AGENT_PROTOCOL.md`](docs/AGENT_PROTOCOL.md) — full agent CLI protocol.\n- [`docs/RELEASE_NOTES.md`](docs/RELEASE_NOTES.md) — MVP limitations and release notes.\n- [`docs/prd/`](docs/prd/) — product requirement docs per subsystem.\n\nEnable Pages once: repo **Settings → Pages → Source: Deploy from a branch → `main` / `/docs`**. `docs/.nojekyll` is present so asset paths are served verbatim.\n\n## Install\n\nPackage metadata targets [`@amit-t/stet-md`](https://www.npmjs.com/package/@amit-t/stet-md). Requires Node `>=20.10`.\n\n### Install from local checkout\n\nUse this before the npm package is published:\n\n```zsh\npnpm install\npnpm run build\npnpm link --global\nrehash\nstet-md --version\nstmd --help\n```\n\nIf `pnpm link --global` says the global bin directory is not configured, run `pnpm setup`, restart the shell, then repeat `pnpm link --global`.\n\n### Run without installing after npm publish\n\n```zsh\nnpx @amit-t/stet-md@latest README.md\n# or\npnpm dlx @amit-t/stet-md README.md\n```\n\n`npx`/`pnpm dlx` downloads the package to a temporary tool cache, runs the `stet-md` binary, and leaves no project dependency behind. Pass the same flags you would pass to `stet-md`:\n\n```zsh\nnpx @amit-t/stet-md@latest --author \"Amit\" --app \"Google Chrome\" docs/prd/00-stet-master-prd.md\npnpm dlx @amit-t/stet-md --no-open --port 43117 docs/prd/00-stet-master-prd.md\n```\n\n### Persistent install after npm publish\n\nFor a permanent terminal command:\n\n```zsh\npnpm add --global @amit-t/stet-md\n# or, if you prefer npm for global tools:\nnpm install -g @amit-t/stet-md\n\nstet-md --version\nstet-md README.md\n```\n\n## Quick start\n\n```zsh\nstet-md README.md\n# or\nstmd README.md\n```\n\nUseful launch flags:\n\n```zsh\nstet-md --author \"Amit\" README.md\nstet-md --app \"Google Chrome\" README.md\nstet-md --port 43117 README.md\nstet-md --no-open README.md\n```\n\nThe server binds to `127.0.0.1`, sets an HttpOnly `SameSite=Strict` cookie, and opens `http://127.0.0.1:<port>/`. The token is never placed in the URL.\n\n## Browser review UI\n\nThe UI includes:\n\n- top bar with file name, dirty/saved state, open-thread count, Save, Reload, and patch preview;\n- rendered Markdown body with commentable headings and paragraphs;\n- `+` affordances, double-click comments, keyboard `c` on focused blocks, and document-level comments;\n- side-panel thread cards with replies, resolve/reopen controls, orphan and content-drift warnings;\n- localStorage draft recovery keyed by file path and loaded file hash;\n- conflict banner when the file changes on disk before save.\n\nResolved threads are collapsed by default. Orphaned threads appear under **Needs re-attach** and remain preserved in the Markdown file.\n\n## Agent CLI\n\nAgents should use CLI commands instead of hand-editing markers:\n\n```zsh\nstet-md list --json FILE.md\nstet-md reply FILE.md --thread stt_... --author Claude --message \"I updated the paragraph above.\"\nstet-md resolve FILE.md --thread stt_... --author Claude --message \"Resolved by the edit above.\"\nstet-md --print-agent-protocol\n```\n\nA helper exists for smoke tests and scripts:\n\n```zsh\nstet-md comment FILE.md --target paragraph:0 --author Amit --message \"Please tighten this.\"\n```\n\nFull protocol: [`docs/AGENT_PROTOCOL.md`](docs/AGENT_PROTOCOL.md).\n\n## Storage format\n\nThreads are stored inline as structured HTML-comment markers plus a generated visible blockquote:\n\n```markdown\n<!-- stet:thread\nversion: 1\nid: stt_20260607_150015_7f3a9c\nstatus: open\ncreated_at: 2026-06-07T15:00:15Z\nupdated_at: 2026-06-07T15:00:15Z\ntarget:\n  kind: paragraph\n  heading_path:\n    - Product goals\n  block_ordinal: 0\n  source_hash: sha256:...\n  quote: Product goals\nmessages:\n  - author: Amit\n    created_at: 2026-06-07T15:00:15Z\n    body: |-\n      This needs a clearer agent workflow.\n-->\n> [!NOTE]\n> **Review thread `stt_20260607_150015_7f3a9c` — open**\n>\n> **Amit** · 2026-06-07 15:00 UTC\n>\n> This needs a clearer agent workflow.\n<!-- /stet:thread -->\n```\n\nThe structured marker is the source of truth. The blockquote is regenerated from marker data on save. Message bodies containing unsafe `--` sequences are escaped in the structured marker so they cannot terminate the HTML comment early, then decoded losslessly when Stet.md parses the thread.\n\n## Write safety and formatter caveats\n\nStet.md saves by byte splices only. It does not stringify or reformat the whole Markdown document. Tests cover preservation of LF, CRLF, BOM, final-newline state, trailing spaces, list markers, reference links, and paragraph wrapping outside expected splice ranges.\n\nFormatter caveat: if an external formatter rewrites the file while Stet.md is open, Stet.md detects the file hash change and blocks save. Reload before saving staged comments. MVP intentionally has no force-save.\n\nBackups are written before replacement:\n\n```text\n.stet/\n  .gitignore      # contains *\n  backups/\n  locks/\n```\n\n## Security model\n\nStet.md is local-only and has no telemetry.\n\n- Binds to `127.0.0.1` by default.\n- Serves only the selected Markdown file and bundled UI assets.\n- Uses an HttpOnly `SameSite=Strict` cookie token; missing/wrong tokens are rejected for API routes.\n- Validates `Host` to reject DNS rebinding attempts.\n- Sends `Referrer-Policy: no-referrer`.\n- Sends restrictive CSP: self-only scripts/styles, self/data images, no objects/forms/framing.\n- Escapes raw Markdown HTML by default.\n- Blocks remote Markdown images/resources by default.\n\n## Development\n\nStet.md uses pnpm for repository development. Keep `pnpm-lock.yaml` as the only package-manager lockfile.\n\n```zsh\npnpm install\npnpm run typecheck\npnpm test\npnpm run test:packaging\npnpm run ci\npnpm run pack:dry\n```\n\nTest groups:\n\n- `tests/core/` parser, anchors, thread serialization, byte-splice writer.\n- `tests/server/` local server save/reopen/conflict flow.\n- `tests/security/` token, Host, CSP, no-referrer, remote-resource blocking.\n- `tests/browser/` browser UI smoke using a DOM-compatible runtime.\n- `tests/packaging/` package metadata and built CLI smoke.\n\n## Release gates\n\nMVP release requires:\n\n1. core parser/splice tests pass;\n2. server, security, and browser smoke tests pass;\n3. `stet-md --version`, `stet-md --help`, `stet-md --print-agent-protocol`, and `stmd --help` work;\n4. README documents install, usage, storage, security, formatter caveats, and agent protocol;\n5. release notes list MVP limitations;\n6. dogfood run against the master PRD or a byte-identical copy.\n\n## MVP limitations\n\nSee [`docs/RELEASE_NOTES.md`](docs/RELEASE_NOTES.md). Current MVP does not support list-item, table-row, or text-range comments.\n","readmeFilename":"README.md","_rev":"1-78c043ca56e144e8dac033b4539e56c2"}