noggin

Verb demo

Each scenario seeds a fresh temp noggin, then runs the same command twice โ€” once for human output, once with --json โ€” so the two columns describe identical state. Jump to a section:

push

push into an empty store

No seed file. Creates the first root item and makes it active. Target is path `/1`.

before$ noggin show
The noggin is empty.
after ↓
$ noggin push 'ship v1'exit 0
/1 ๐Ÿ“ ship v1
$ noggin push 'ship v1' --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "push",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20261004-131952-0babd1",
    "targetKey": "i-20261004-131952-0babd1",
    "items": [
      {
        "key": "i-20261004-131952-0babd1",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-10-04T13:19:52.917Z",
        "children": []
      }
    ]
  }
}

push a child of the active item

Active is `/1` (ship v1). The new item is appended as the last child of active and becomes the new active. Path was `/1`, now `/1/4`.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin push 'pause to chase a regression'exit 0
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
  /1/4 ๐Ÿ“ pause to chase a regression
$ noggin push 'pause to chase a regression' --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "push",
  "data": {
    "activePath": "/1/4",
    "activeKey": "i-20261004-131953-c00d3e",
    "targetKey": "i-20261004-131953-c00d3e",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20261004-131953-c00d3e",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/4",
            "position": 4,
            "title": "pause to chase a regression",
            "createdAt": "2026-10-04T13:19:53.090Z",
            "children": []
          }
        ]
      }
    ]
  }
}

add

add a child of active (default placement)

Active stays at `/1`. The new item is appended as the last child of active (path `/1/4`). Note the ๐Ÿ“ indicator never moves.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin add 'remember to file an ADO bug'exit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
  /1/4 remember to file an ADO bug
$ noggin add 'remember to file an ADO bug' --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "add",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20261004-131953-ab5455",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20261004-131953-ab5455",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/4",
            "position": 4,
            "title": "remember to file an ADO bug",
            "createdAt": "2026-10-04T13:19:53.257Z",
            "children": []
          }
        ]
      }
    ]
  }
}

add --into <path>

Append under an arbitrary anchor. New item becomes the last child of `/1/3` (write docs), so path `/1/3/3`. Active still `/1`.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin add CONTRIBUTING --into /1/3exit 0
/1 ๐Ÿ“ ship v1
  /1/3 write docs
    /1/3/1 README
    /1/3/2 SKILL
    /1/3/3 CONTRIBUTING
$ noggin add CONTRIBUTING --into /1/3 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "add",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20261004-131953-9e52d8",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z"
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z"
              },
              {
                "key": "i-20261004-131953-9e52d8",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/3",
                "position": 3,
                "title": "CONTRIBUTING",
                "createdAt": "2026-10-04T13:19:53.422Z",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
}

add --before <path>

Insert as a sibling immediately before `/1/3` (write docs). New item takes path `/1/3`; everything from the old `/1/3` onward shifts by one.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin add CHANGELOG --before /1/3exit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 CHANGELOG
  /1/4 write docs
$ noggin add CHANGELOG --before /1/3 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "add",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20261004-131953-32c3e4",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20261004-131953-32c3e4",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "CHANGELOG",
            "createdAt": "2026-10-04T13:19:53.591Z",
            "children": []
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/4",
            "position": 4,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      }
    ]
  }
}

add --after <path>

Insert as a sibling immediately after `/1/3`. New item takes path `/1/4`; `follow-ups` stays at root path `/2`.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin add LICENSE --after /1/3exit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
  /1/4 LICENSE
$ noggin add LICENSE --after /1/3 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "add",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20261004-131953-2fe7ef",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20261004-131953-2fe7ef",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/4",
            "position": 4,
            "title": "LICENSE",
            "createdAt": "2026-10-04T13:19:53.758Z",
            "children": []
          }
        ]
      }
    ]
  }
}

add with --goto

Same default placement (last child of active) but `--goto` with no path activates the new item. ๐Ÿ“ moves from `/1` to `/1/4`.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin add 'now i'm going to do this' --gotoexit 0
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
  /1/4 ๐Ÿ“ now i'm going to do this
$ noggin add 'now i'm going to do this' --goto --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "add",
  "data": {
    "activePath": "/1/4",
    "activeKey": "i-20261004-131953-6467cc",
    "targetKey": "i-20261004-131953-6467cc",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20261004-131953-6467cc",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/4",
            "position": 4,
            "title": "now i'm going to do this",
            "createdAt": "2026-10-04T13:19:53.935Z",
            "children": []
          }
        ]
      }
    ]
  }
}

move

move active --into <path>

Active is the deep leaf `/1/3/2` (SKILL). Move it under `/2` (follow-ups). Active is preserved by key, so ๐Ÿ“ stays on the same item but its path changes from `/1/3/2` to `/2/1`.

before$ noggin show
/1 ship v1
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
after ↓
$ noggin move --into /2exit 0
/2 follow-ups
  /2/1 ๐Ÿ“ SKILL
$ noggin move --into /2 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "move",
  "data": {
    "activePath": "/2/1",
    "activeKey": "i-20260101-000000-000006",
    "targetKey": "i-20260101-000000-000006",
    "items": [
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000006",
            "parentKey": "i-20260101-000000-000007",
            "path": "/2/1",
            "position": 1,
            "title": "SKILL",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": []
          }
        ]
      }
    ]
  }
}

move <path> --before <anchor>

Reorder: move `/1/2` (wire up tests) before `/1/1` (spec the API). Their paths swap; active stays on `/1` (which is a parent and unaffected).

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin move /1/2 --before /1/1exit 0
/1 ๐Ÿ“ ship v1
  /1/1 wire up tests
  /1/2 โœ… spec the API โœ๏ธ
  /1/3 write docs
/2 follow-ups
$ noggin move /1/2 --before /1/1 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "move",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

goto

goto absolute path

Make `/1/3/1` (README) active. The spine is now deep, so the after-view shows every peer at every depth from root to README.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin goto /1/3/1exit 0
/1 ship v1
  /1/3 write docs
    /1/3/1 ๐Ÿ“ README
    /1/3/2 SKILL
$ noggin goto /1/3/1 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "goto",
  "data": {
    "activePath": "/1/3/1",
    "activeKey": "i-20260101-000000-000005",
    "targetKey": "i-20260101-000000-000005",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z",
                "children": []
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z"
              }
            ]
          }
        ]
      }
    ]
  }
}

goto relative (../X)

Active was `/1/3/2` (SKILL). `../1` walks up to the parent (`/1/3` write docs) then descends to its first child โ€” landing on `/1/3/1` (README).

before$ noggin show
/1 ship v1
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
after ↓
$ noggin goto ../1exit 0
/1 ship v1
  /1/3 write docs
    /1/3/1 ๐Ÿ“ README
    /1/3/2 SKILL
$ noggin goto ../1 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "goto",
  "data": {
    "activePath": "/1/3/1",
    "activeKey": "i-20260101-000000-000005",
    "targetKey": "i-20260101-000000-000005",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z",
                "children": []
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z"
              }
            ]
          }
        ]
      }
    ]
  }
}

done

done <path>

Mark `/1/2` (wire up tests) done. A system note `closed` is appended to it, and active shifts to its parent `/1`. The โœ… now sits on `/1/2`. (Idempotent โ€” calling `done` again on an already-closed item is a no-op success.)

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin done /1/2exit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 โœ… wire up tests โœ๏ธ
  /1/3 write docs
/2 follow-ups
$ noggin done /1/2 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "done",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:54.767Z",
                "text": "closed"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

done --close-all (cascade close)

Mark `/1/3` (write docs) done along with its open children (README, SKILL). Without `--close-all` this would error โ€” "2 open descendants". With it, every descendant gets its own `closed` system note, then the target is closed.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin done /1/3 --close-allexit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 โœ… write docs โœ๏ธ
/2 follow-ups
$ noggin done /1/3 --close-all --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "done",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:54.932Z",
                "text": "closed"
              }
            ]
          }
        ]
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

done --force (close anyway, leave kids open)

Closes `/1/3` even though its children remain open. Use sparingly โ€” violates the usual "done items have no open descendants" invariant, but sometimes the right escape hatch.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin done /1/3 --forceexit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 โœ… write docs โœ๏ธ
/2 follow-ups
$ noggin done /1/3 --force --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "done",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:55.094Z",
                "text": "closed"
              }
            ]
          }
        ]
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

pop (= done on active, shorthand)

Active is `/1/1` (a side-quest under `parent`). `pop` closes it and surfaces back to `/1`. Honors `--force` and `--close-all` the same way `done` does.

before$ noggin show
/1 parent
  /1/1 ๐Ÿ“ side-quest
after ↓
$ noggin popexit 0
/1 ๐Ÿ“ parent
  /1/1 โœ… side-quest โœ๏ธ
$ noggin pop --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "pop",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "parent",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "side-quest",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:55.258Z",
                "text": "closed"
              }
            ]
          }
        ]
      }
    ]
  }
}

edit

edit --open (reopen a done item)

Active is `/1/1` (spec the API, previously closed in the seed). Reopening clears its done flag but does NOT touch notes โ€” the historical `closed` note stays in the log. Active is unchanged.

before$ noggin show
/1 ship v1
  /1/1 ๐Ÿ“โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
after ↓
$ noggin edit --openexit 0
/1 ship v1
  /1/1 ๐Ÿ“ spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
$ noggin edit --open --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "edit",
  "data": {
    "activePath": "/1/1",
    "activeKey": "i-20260101-000000-000002",
    "targetKey": "i-20260101-000000-000002",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ],
            "children": []
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      }
    ]
  }
}

edit <path> --done (without surfacing)

Active is `/1/2`. `edit --done` marks it done in place โ€” the โœ… appears but ๐Ÿ“ stays put. (Compare with `done`, which surfaces to the parent.)

before$ noggin show
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 ๐Ÿ“ wire up tests
  /1/3 write docs
after ↓
$ noggin edit --doneexit 0
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 ๐Ÿ“โœ… wire up tests โœ๏ธ
  /1/3 write docs
$ noggin edit --done --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "edit",
  "data": {
    "activePath": "/1/2",
    "activeKey": "i-20260101-000000-000003",
    "targetKey": "i-20260101-000000-000003",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:55.575Z",
                "text": "closed"
              }
            ],
            "children": []
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      }
    ]
  }
}

edit --title <text> (rename)

Active is `/1` (ship v1). Rename it to "ship v1.0". Active and tree shape unchanged โ€” only the label. Before and After both target the same item so you can see exactly what changed.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin edit --title 'ship v1.0'exit 0
/1 ๐Ÿ“ ship v1.0
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
$ noggin edit --title 'ship v1.0' --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "edit",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1.0",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

edit --done --title <text> (combined)

Active is `/1/2` (wire up tests). One call closes it AND renames it. Either operation on its own is idempotent; combining them lets you do both atomically.

before$ noggin show
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 ๐Ÿ“ wire up tests
  /1/3 write docs
after ↓
$ noggin edit --done --title 'tests landed'exit 0
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 ๐Ÿ“โœ… tests landed โœ๏ธ
  /1/3 write docs
$ noggin edit --done --title 'tests landed' --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "edit",
  "data": {
    "activePath": "/1/2",
    "activeKey": "i-20260101-000000-000003",
    "targetKey": "i-20260101-000000-000003",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "tests landed",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:55.892Z",
                "text": "closed"
              }
            ],
            "children": []
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      }
    ]
  }
}

edit --done is idempotent (no extra close note)

Active is `/1/1` (spec the API, already closed in the seed). Calling `edit --done` is a no-op success: no second `closed` note is added, no error returned.

before$ noggin show
/1 ship v1
  /1/1 ๐Ÿ“โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
after ↓
$ noggin edit --doneexit 0
/1 ship v1
  /1/1 ๐Ÿ“โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
$ noggin edit --done --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "edit",
  "data": {
    "activePath": "/1/1",
    "activeKey": "i-20260101-000000-000002",
    "targetKey": "i-20260101-000000-000002",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ],
            "children": []
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      }
    ]
  }
}

edit --done --close-all (cascade close, no surface)

Active is `/1/3` (write docs) with open kids. Like `done --close-all` but stays put on the target instead of surfacing. Useful when you're inspecting an item, decide it's fully done, and don't want active to move.

before$ noggin show
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 ๐Ÿ“ write docs
    /1/3/1 README
    /1/3/2 SKILL
after ↓
$ noggin edit --done --close-allexit 0
/1 ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 ๐Ÿ“โœ… write docs โœ๏ธ
    /1/3/1 โœ… README โœ๏ธ
    /1/3/2 โœ… SKILL โœ๏ธ
$ noggin edit --done --close-all --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "edit",
  "data": {
    "activePath": "/1/3",
    "activeKey": "i-20260101-000000-000004",
    "targetKey": "i-20260101-000000-000004",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:56.206Z",
                "text": "closed"
              }
            ],
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "done": true,
                "createdAt": "2026-01-01T00:00:00.000Z",
                "notes": [
                  {
                    "timestamp": "2026-10-04T13:19:56.206Z",
                    "text": "closed"
                  }
                ]
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "done": true,
                "createdAt": "2026-01-01T00:00:00.000Z",
                "notes": [
                  {
                    "timestamp": "2026-10-04T13:19:56.206Z",
                    "text": "closed"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

show

show (active by default)

Default target is the active item. Full current-tree view: every peer at every depth from root to target, then the target's children. (The Before snapshot here is the same command โ€” included for parity with the others.)

before$ noggin show
/1 ship v1
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
after ↓
$ noggin showexit 0
/1 ship v1
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
$ noggin show --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "show",
  "data": {
    "activePath": "/1/3/2",
    "activeKey": "i-20260101-000000-000006",
    "targetKey": "i-20260101-000000-000006",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z"
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
}

show <path>

Inspect `/1/3` (write docs) without making it active. The spine ends at the requested item; the active ๐Ÿ“ still points to `/1` (where it was).

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin show /1/3exit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
    /1/3/1 README
    /1/3/2 SKILL
$ noggin show /1/3 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "show",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000004",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z"
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z"
              }
            ]
          }
        ]
      }
    ]
  }
}

show --no-children

Hide first-level children. In JSON the target node simply has no `children` field โ€” same shape as a peer (i.e. a leaf of the view).

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin show --no-childrenexit 0
/1 ๐Ÿ“ ship v1
/2 follow-ups
$ noggin show --no-children --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "show",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z"
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

show --with-siblings

Active is `/1/3/2` (SKILL). Default shows the spine root1 โ†’ docs โ†’ README/SKILL. `--with-siblings` also includes the ancestor siblings โ€” `ship v1`'s other children (`spec the API`, `wire up tests`) appear as leaves so you can see the wider context.

before$ noggin show
/1 ship v1
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
after ↓
$ noggin show --with-siblingsexit 0
/1 ship v1
  /1/1 โœ… spec the API
  /1/2 wire up tests
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
$ noggin show --with-siblings --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "show",
  "data": {
    "activePath": "/1/3/2",
    "activeKey": "i-20260101-000000-000006",
    "targetKey": "i-20260101-000000-000006",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z"
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
}

show --with-descendants

Expand the target's subtree recursively. Useful for inspecting a branch in full without walking it node-by-node.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin show /1 --with-descendantsexit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
    /1/3/1 README
    /1/3/2 SKILL
/2 follow-ups
$ noggin show /1 --with-descendants --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "show",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ],
            "children": []
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": []
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z",
                "children": []
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z",
                "children": []
              }
            ]
          }
        ]
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

show --with-all

Shorthand for `--with-siblings --with-descendants`: the full neighborhood around the target.

before$ noggin show
/1 ship v1
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
after ↓
$ noggin show --with-allexit 0
/1 ship v1
  /1/1 โœ… spec the API
  /1/2 wire up tests
  /1/3 write docs
    /1/3/1 README
    /1/3/2 ๐Ÿ“ SKILL
$ noggin show --with-all --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "show",
  "data": {
    "activePath": "/1/3/2",
    "activeKey": "i-20260101-000000-000006",
    "targetKey": "i-20260101-000000-000006",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "children": [
              {
                "key": "i-20260101-000000-000005",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/1",
                "position": 1,
                "title": "README",
                "createdAt": "2026-01-01T00:00:00.000Z"
              },
              {
                "key": "i-20260101-000000-000006",
                "parentKey": "i-20260101-000000-000004",
                "path": "/1/3/2",
                "position": 2,
                "title": "SKILL",
                "createdAt": "2026-01-01T00:00:00.000Z",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
}

show --with-notes

Append note bodies after the tree. (Human only โ€” JSON always carries the notes on the target row in the spine, regardless of this flag.)

before$ noggin show
/1 ๐Ÿ“ investigate the bug โœ๏ธ
after ↓
$ noggin show --with-notesexit 0
/1 ๐Ÿ“ investigate the bug โœ๏ธ
  notes:
    - 2026-01-01T00:00:00.000Z
      repro: it happens on Windows but not macOS
    - 2026-01-01T00:00:00.000Z
      looks like a path-separator issue in tokenizer
$ noggin show --with-notes --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "show",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "investigate the bug",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "notes": [
          {
            "timestamp": "2026-01-01T00:00:00.000Z",
            "text": "repro: it happens on Windows but not macOS"
          },
          {
            "timestamp": "2026-01-01T00:00:00.000Z",
            "text": "looks like a path-separator issue in tokenizer"
          }
        ],
        "children": []
      }
    ]
  }
}

note

note <text> on active

Append a timestamped note to the active item (`/1`). After-view shows โœ๏ธ on that item; the new entry shows up in the target's `notes` array (look in the last spine entry).

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin note 'remembered to update the changelog'exit 0
/1 ๐Ÿ“ ship v1 โœ๏ธ
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
$ noggin note 'remembered to update the changelog' --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "note",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000001",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "notes": [
          {
            "timestamp": "2026-10-04T13:19:57.432Z",
            "text": "remembered to update the changelog"
          }
        ],
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z"
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      },
      {
        "key": "i-20260101-000000-000007",
        "path": "/2",
        "position": 2,
        "title": "follow-ups",
        "createdAt": "2026-01-01T00:00:00.000Z"
      }
    ]
  }
}

note <path> <text>

Annotate an arbitrary item (`/1/2`) without leaving the active spine. Active stays at `/1`.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin note /1/2 'blocked on PR #123'exit 0
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests โœ๏ธ
  /1/3 write docs
$ noggin note /1/2 'blocked on PR #123' --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "note",
  "data": {
    "activePath": "/1",
    "activeKey": "i-20260101-000000-000001",
    "targetKey": "i-20260101-000000-000003",
    "items": [
      {
        "key": "i-20260101-000000-000001",
        "path": "/1",
        "position": 1,
        "title": "ship v1",
        "createdAt": "2026-01-01T00:00:00.000Z",
        "children": [
          {
            "key": "i-20260101-000000-000002",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/1",
            "position": 1,
            "title": "spec the API",
            "done": true,
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-01-01T00:00:00.000Z",
                "text": "decided on stateless verbs"
              }
            ]
          },
          {
            "key": "i-20260101-000000-000003",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/2",
            "position": 2,
            "title": "wire up tests",
            "createdAt": "2026-01-01T00:00:00.000Z",
            "notes": [
              {
                "timestamp": "2026-10-04T13:19:57.595Z",
                "text": "blocked on PR #123"
              }
            ],
            "children": []
          },
          {
            "key": "i-20260101-000000-000004",
            "parentKey": "i-20260101-000000-000001",
            "path": "/1/3",
            "position": 3,
            "title": "write docs",
            "createdAt": "2026-01-01T00:00:00.000Z"
          }
        ]
      }
    ]
  }
}

delete

delete a leaf

Remove `/1/2` (wire up tests). Payload always carries `deleted` (key, path, title) + `descendantCount` + a `view` of what's left. Active was `/1` (a parent) so it survives.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin delete /1/2exit 0
deleted /1/2
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 write docs
/2 follow-ups
$ noggin delete /1/2 --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "delete",
  "data": {
    "deleted": {
      "key": "i-20260101-000000-000003",
      "path": "/1/2",
      "title": "wire up tests"
    },
    "view": {
      "activePath": "/1",
      "activeKey": "i-20260101-000000-000001",
      "targetKey": "i-20260101-000000-000001",
      "items": [
        {
          "key": "i-20260101-000000-000001",
          "path": "/1",
          "position": 1,
          "title": "ship v1",
          "createdAt": "2026-01-01T00:00:00.000Z",
          "children": [
            {
              "key": "i-20260101-000000-000002",
              "parentKey": "i-20260101-000000-000001",
              "path": "/1/1",
              "position": 1,
              "title": "spec the API",
              "done": true,
              "createdAt": "2026-01-01T00:00:00.000Z",
              "notes": [
                {
                  "timestamp": "2026-01-01T00:00:00.000Z",
                  "text": "decided on stateless verbs"
                }
              ]
            },
            {
              "key": "i-20260101-000000-000004",
              "parentKey": "i-20260101-000000-000001",
              "path": "/1/2",
              "position": 2,
              "title": "write docs",
              "createdAt": "2026-01-01T00:00:00.000Z"
            }
          ]
        },
        {
          "key": "i-20260101-000000-000007",
          "path": "/2",
          "position": 2,
          "title": "follow-ups",
          "createdAt": "2026-01-01T00:00:00.000Z"
        }
      ]
    }
  }
}

delete --recursive

Required when the target has descendants. Removes `/1/3` (write docs) and its two children. `descendantCount` is `2`.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin delete /1/3 --recursiveexit 0
deleted /1/3 and 2 descendant(s)
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
/2 follow-ups
$ noggin delete /1/3 --recursive --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "delete",
  "data": {
    "deleted": {
      "key": "i-20260101-000000-000004",
      "path": "/1/3",
      "title": "write docs"
    },
    "descendantCount": 2,
    "view": {
      "activePath": "/1",
      "activeKey": "i-20260101-000000-000001",
      "targetKey": "i-20260101-000000-000001",
      "items": [
        {
          "key": "i-20260101-000000-000001",
          "path": "/1",
          "position": 1,
          "title": "ship v1",
          "createdAt": "2026-01-01T00:00:00.000Z",
          "children": [
            {
              "key": "i-20260101-000000-000002",
              "parentKey": "i-20260101-000000-000001",
              "path": "/1/1",
              "position": 1,
              "title": "spec the API",
              "done": true,
              "createdAt": "2026-01-01T00:00:00.000Z",
              "notes": [
                {
                  "timestamp": "2026-01-01T00:00:00.000Z",
                  "text": "decided on stateless verbs"
                }
              ]
            },
            {
              "key": "i-20260101-000000-000003",
              "parentKey": "i-20260101-000000-000001",
              "path": "/1/2",
              "position": 2,
              "title": "wire up tests",
              "createdAt": "2026-01-01T00:00:00.000Z"
            }
          ]
        },
        {
          "key": "i-20260101-000000-000007",
          "path": "/2",
          "position": 2,
          "title": "follow-ups",
          "createdAt": "2026-01-01T00:00:00.000Z"
        }
      ]
    }
  }
}

delete the last item (tree empties)

When the only root is removed there's nowhere for active to fall back to. `view` is `null` and the human output says so.

before$ noggin show
/1 ๐Ÿ“ only thing
after ↓
$ noggin delete /1 --recursiveexit 0
deleted /1
(tree is now empty)
$ noggin delete /1 --recursive --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "delete",
  "data": {
    "deleted": {
      "key": "i-20260101-000000-000001",
      "path": "/1",
      "title": "only thing"
    }
  }
}

where

where (file resolution)

Reports the resolved file, where it came from (`flag` / `env` / `default`), and whether it exists on disk. The Before snapshot is the seed's `show` for context.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin whereexit 0
/tmp/noggin-demo-MTGjqw/noggin.yaml
$ noggin where --jsonexit 0stdout
{
  "status": "ok",
  "envelopeVersion": 3,
  "verb": "where",
  "data": "/tmp/noggin-demo-85BdVJ/noggin.yaml"
}

errors

usage error: title required

Usage errors exit 2. Plain mode prints `noggin: <msg>` to stderr; `--json` mode emits a full error envelope to stderr instead.

before$ noggin show
The noggin is empty.
after ↓
$ noggin pushexit 2
noggin: push: title required (--title or positional)
$ noggin push --jsonexit 2stderr
{
  "status": "error",
  "envelopeVersion": 3,
  "verb": "push",
  "error": {
    "code": "title-required",
    "message": "push: title required (--title or positional)",
    "exitCode": 2
  }
}

runtime error: open descendants

Refuses to close `/1/3` (write docs) because it has two open children (README, SKILL). Close them first, then retry.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin done /1/3exit 1
noggin: done: /1/3 has 2 open descendant(s); pass --closeall to close them too, or --force to close write docs anyway
$ noggin done /1/3 --jsonexit 1stderr
{
  "status": "error",
  "envelopeVersion": 3,
  "verb": "done",
  "error": {
    "code": "open-descendants",
    "message": "done: /1/3 has 2 open descendant(s); pass --closeall to close them too, or --force to close write docs anyway",
    "exitCode": 1,
    "data": {
      "verb": "done",
      "path": "/1/3",
      "title": "write docs",
      "openCount": 2
    }
  }
}

runtime error: cycle on move

Cannot move `/1` (ship v1) into its own descendant `/1/3` โ€” would create a cycle.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin move /1 --into /1/3exit 1
noggin: move: cannot move /1 into itself or its subtree (would create a cycle)
$ noggin move /1 --into /1/3 --jsonexit 1stderr
{
  "status": "error",
  "envelopeVersion": 3,
  "verb": "move",
  "error": {
    "code": "cycle",
    "message": "move: cannot move /1 into itself or its subtree (would create a cycle)",
    "exitCode": 1,
    "data": {
      "verb": "move",
      "path": "/1",
      "title": "ship v1",
      "placementKind": "into"
    }
  }
}

runtime error: delete with descendants without --recursive

Safety check. Pass `--recursive` to delete the whole subtree, or close/move the children first.

before$ noggin show
/1 ๐Ÿ“ ship v1
  /1/1 โœ… spec the API โœ๏ธ
  /1/2 wire up tests
  /1/3 write docs
/2 follow-ups
after ↓
$ noggin delete /1/3exit 1
noggin: delete: /1/3 has 2 descendant(s); pass --recursive to delete the whole subtree
$ noggin delete /1/3 --jsonexit 1stderr
{
  "status": "error",
  "envelopeVersion": 3,
  "verb": "delete",
  "error": {
    "code": "has-descendants",
    "message": "delete: /1/3 has 2 descendant(s); pass --recursive to delete the whole subtree",
    "exitCode": 1,
    "data": {
      "verb": "delete",
      "path": "/1/3",
      "title": "write docs",
      "descendantCount": 2
    }
  }
}

Generated 2026-10-04T13:19:58.787Z ยท 38 scenarios.