Skip to content

Releases

v0.2.3 - 技能保真度:点明被编辑的 code 格会补上 outputs/execution_count

Choose a tag to compare

@Boenxia Boenxia released this 15 Oct 13:50

[0.2.3] - 2026-10-15

Fixed

  • The skill's fidelity section claimed that nothing is ever invented, full stop.
    The cell you edit is the exception: editing a code cell writes outputs and
    execution_count — that is what "clear the outputs" means — so a cell that
    carried neither key gains both, appended at the end of its key order. Only
    untouched cells keep their exact shape. The wording now says so, bullet by
    bullet, instead of leaving the reader to discover it from a byte diff.
    Verified end to end against a hand-written nbformat 4.4 file (2-space indent,
    CRLF, no trailing newline, no cell ids): the untouched cells kept their array
    source and their outputs/execution_count and were not given an id; the
    file kept its indent, its CRLF and its missing trailing newline; the edited
    cell alone came back with the two keys appended.

v0.2.2 - compare the peeled tag commit so re-runs are a no-op

Choose a tag to compare

@Boenxia Boenxia released this 15 Oct 02:45

[0.2.2] - 2026-10-15

Fixed

  • npm run release compared the tag with HEAD through the bare ref, which for
    an annotated tag yields the tag object rather than the commit it marks — so
    a tag that did point at HEAD was reported as pointing somewhere else, and
    re-running a finished release failed. It now compares the peeled commit
    (refs/tags/v<x.y.z>^{commit}). As a result a completed release is a clean
    no-op: the push and the tag are skipped and the existing GitHub Release is
    reported instead of being posted a second time.

Added

  • test/release.test.js pins the peeling down against a throwaway repository.

v0.2.1 - npm run release: tag, push and GitHub Release in one command

Choose a tag to compare

@Boenxia Boenxia released this 15 Oct 02:44

[0.2.1] - 2026-10-15

Releases are a script now, not a habit: npm run release verifies the version
against the CHANGELOG, runs the tests, tags, pushes, and publishes the GitHub
Release.

Added

  • npm run release (scripts/release.mjs): reads the version from
    package.json and refuses to run unless CHANGELOG.md carries a matching,
    non-empty ## [x.y.z] section and a [x.y.z]: link reference; requires a
    clean working tree on the release branch with the version bump already
    committed; runs node --test; pushes the release branch; creates the
    annotated tag v<x.y.z>; pushes it; and creates the GitHub Release through
    the REST API, using the tag annotation as the release title and the CHANGELOG
    section as its body.
    Credentials come from GITHUB_TOKEN / GH_TOKEN or git credential fill
    and are never printed. Flags: --title, --dry-run, --skip-tests,
    --branch, --remote.
  • test/release.test.js: covers the argument parser, remote URL parsing,
    CHANGELOG section and link-reference extraction, and token resolution.

Changed

  • package.json gains the release script. No published file changed.

v0.2.0 - byte-faithful writes and content-hash guards

Choose a tag to compare

@Boenxia Boenxia released this 15 Oct 02:36

[0.2.0] - 2026-10-15

Fidelity and guard hardening: a notebook now survives a write untouched except
for the edit you asked for, and every mutating tool can be guarded by a content
hash rather than a timestamp. Ported back from the Python CLI skill that had
grown these properties first.

Added

  • Layout-preserving serialization. lib/nb/style.js probes the layout a
    notebook already uses — JSON indent (0/1/2/4), CRLF vs LF, and whether the
    file ends with a newline — and writes it back in that same layout. Cells whose
    source is a plain string stay a string; keys that were absent
    (outputs, execution_count, metadata) are not invented. A file that is
    read and written back unmodified is byte-identical, which makes the plugin
    safe to point at notebooks produced by JupyterLab, nbformat.writes, or hand
    editing. Known limits: tab indentation, \uXXXX-escaped non-ASCII (Python's
    ensure_ascii=True), and more than one trailing newline are normalized to the
    tool's defaults.
  • expected_file_sha256 on all four mutating tools. expected_file_mtime_ms
    cannot see a rewrite that happens inside the same millisecond; the content
    hash can. notebook_read and notebook_list_cells now return file_sha256
    so the value never has to be guessed.
  • expected_source_sha256 on notebook_insert_cell (its anchor cell) and
    notebook_clear_outputs (its target cell).
    Every mutating tool now accepts
    the same three guards.
  • Deterministic ids for notebooks too old to store them. A missing cell id
    is derived from sha256("v1|<ordinal>|<source>") instead of random bytes, so
    the same cell gets the same id on every load, across processes.
  • Structure validation before every write. The save path runs the deep
    audit and refuses to write a notebook that fails it — cell ids must match
    ^[A-Za-z0-9_-]{1,64}$ and be unique, metadata must be an object when
    present, a code cell's outputs must be an array when present, and every
    element of a source array must be a string. notebook_validate reports the
    same deep problems.
  • test/fidelity.test.js — byte-for-byte round trips across six file layouts,
    deterministic id behavior at nbformat 4.4 and 4.5, guard coverage for all four
    writers, append-only behavior for an unedited cell, and the documented
    non-preservable cases. Suite: 61 → 75 assertions.

Changed

  • Writes no longer reformat the whole file. The old save path rebuilt the
    document and forced a 1-space indent, which reformatted every notebook it
    touched (and silently dropped unknown root keys).
  • nbformat_minor is no longer bumped. Backfilling an id never changes the
    declared notebook format.

Fixed

  • README and CHANGELOG claimed id backfill "bumps nbformat_minor to 5". No
    code path ever did that; the documentation now matches the implementation.
  • A notebook that is valid enough to inspect but structurally broken is now
    reported by notebook_validate and refused by the writers, instead of being
    silently loaded and rewritten.

v0.1.2 — cell_type self-check in the companion skill

Choose a tag to compare

@Boenxia Boenxia released this 14 Oct 15:57

Documentation release: the companion skill now knows about the one failure mode that its own structure checks cannot see.

Added

  • A cell_type self-check in the style section: the first cell and every ## N. heading cell must be markdown. Markdown prose typed as code is executed as Python and dies on the first non-comment line with SyntaxError: invalid character '(' (U+FF08) — a failure reported several cells away from the cell that actually has the wrong type.
  • A wrong-type trap in the "after editing" checklist: after any layout refactor, re-check cell types with notebook_list_cells. notebook_validate only validates structure, so a markdown body sitting in a code cell passes it and still breaks Run All on the first cell.

Changed

  • The troubleshooting order for "the notebook won't run" is now: check cell_type first, then check for a cell stuck waiting on input().

No runtime code changed — lib/ is byte-identical to v0.1.1. 61 package tests pass.

v0.1.1 - notebook authoring style in the skill

Choose a tag to compare

@Boenxia Boenxia released this 14 Oct 11:28

Codifies the notebook authoring style in the companion skill. This is the layout these tools were originally used to produce — now written down instead of left to the model's habits.

Added

A new 写法约定(风格) section in skill/notebook-tools/SKILL.md:

  • Section commentary belongs in its own markdown cell — never as a # 1. 标题 banner inside a code cell.
  • Each section = 1 markdown cell + 1..n code cells. The markdown cell carries ## N. 中文标题 (numbered from 1) plus a sentence or two of prose, and an optional - bullet list.
  • The first cell carries # <filename without extension> → one sentence on what the script does → optional ## 使用方法 + ordered list → a single closing ---.
  • Callouts use blockquotes: > **注意**: …, > ✅ 已完成 ….
  • Multiple code cells in one section share a single markdown header.
  • An explicit user request for a different layout still wins.

Changed

  • The skill description and whenToUse now list creating/authoring notebooks as a trigger, not only reading and cleaning them.

Full diff: v0.1.0...v0.1.1

v0.1.0 - initial public release

Choose a tag to compare

@Boenxia Boenxia released this 14 Oct 11:22

First release: a DSH port of OpenClaw's openclaw-notebook-tools (MIT).

Nine cell-aware Jupyter notebook tools, zero runtime dependencies, node: builtins only.

Tools

Tool Writes Purpose
notebook_create yes Create a notebook from structured cells
notebook_read no Structured read, optionally with outputs
notebook_list_cells no Cheap index: id, type, preview, counts
notebook_search no Find cells by text or regex
notebook_validate no Validate structure and report facts
notebook_edit_cell yes Replace a cell's source / type
notebook_insert_cell yes Insert a new cell at a position
notebook_delete_cell yes Delete a cell by id or index
notebook_clear_outputs yes Clear outputs (all or one cell)

Semantics

  • Atomic saves — 1-space indent, sibling temp file, fsync, rename. A killed process cannot leave a half-written notebook, and temp files never land in the system temp directory.
  • Cell ids over indexes — reads always return an id; missing ids are backfilled in memory and persisted on the next save (bumping nbformat_minor to 5).
  • Editing a code cell clears its outputs and execution_count.
  • Stale-edit guards — expected_source_sha256 / expected_file_mtime_ms fail before any write; mtime comparison tolerates sub-millisecond jitter.
  • Source on disk is a string array (one element per line, trailing newline preserved).
  • nbformat 4 only. No kernel execution, ever.

Install

dsh plugin --profile desktop add --config.minimumReleaseAge=0 <path-or-tarball>

Then restart DSH: the cordis.patch.yml row is composed at boot. The companion skill lives at skill/notebook-tools/SKILL.md — copy it into <DSH_HOME>\skills\ and DSH hot-reloads it.

Verification

61 node:test assertions plus an end-to-end pass in a live DSH session covering all nine tools, both stale guards, and output clearing on disk.

Credits

Upstream tool surface, behavioral spec, and companion skill by Kittipos Sirivongrungson (Lightbridge-KS/openclaw-notebook-tools, MIT). This port re-implements the behavior for the DSH plugin host. LICENSE carries both copyright notices.