ctxr-cli 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +6 -1
  2. package/dist/commands/graph-diff.d.ts +33 -0
  3. package/dist/commands/graph-diff.d.ts.map +1 -0
  4. package/dist/commands/graph-diff.js +52 -0
  5. package/dist/commands/graph-diff.js.map +1 -0
  6. package/dist/commands/publish-check.d.ts +6 -0
  7. package/dist/commands/publish-check.d.ts.map +1 -1
  8. package/dist/commands/publish-check.js +78 -3
  9. package/dist/commands/publish-check.js.map +1 -1
  10. package/dist/commands/publish-gather.d.ts.map +1 -1
  11. package/dist/commands/publish-gather.js +4 -1
  12. package/dist/commands/publish-gather.js.map +1 -1
  13. package/dist/commands/publish-new.d.ts +5 -0
  14. package/dist/commands/publish-new.d.ts.map +1 -1
  15. package/dist/commands/publish-new.js +30 -10
  16. package/dist/commands/publish-new.js.map +1 -1
  17. package/dist/commands/publish-stamp.d.ts +32 -0
  18. package/dist/commands/publish-stamp.d.ts.map +1 -0
  19. package/dist/commands/publish-stamp.js +78 -0
  20. package/dist/commands/publish-stamp.js.map +1 -0
  21. package/dist/commands/publish-urls.d.ts +6 -0
  22. package/dist/commands/publish-urls.d.ts.map +1 -1
  23. package/dist/commands/publish-urls.js +10 -1
  24. package/dist/commands/publish-urls.js.map +1 -1
  25. package/dist/commands/serve.d.ts.map +1 -1
  26. package/dist/commands/serve.js +83 -5
  27. package/dist/commands/serve.js.map +1 -1
  28. package/dist/core/browse/diagram-assets.d.ts +15 -0
  29. package/dist/core/browse/diagram-assets.d.ts.map +1 -0
  30. package/dist/core/browse/diagram-assets.js +35 -0
  31. package/dist/core/browse/diagram-assets.js.map +1 -0
  32. package/dist/core/browse/page-url.d.ts +22 -0
  33. package/dist/core/browse/page-url.d.ts.map +1 -1
  34. package/dist/core/browse/page-url.js +31 -0
  35. package/dist/core/browse/page-url.js.map +1 -1
  36. package/dist/core/browse/render.d.ts +10 -1
  37. package/dist/core/browse/render.d.ts.map +1 -1
  38. package/dist/core/browse/render.js +23 -1
  39. package/dist/core/browse/render.js.map +1 -1
  40. package/dist/core/browse/templates.d.ts +4 -1
  41. package/dist/core/browse/templates.d.ts.map +1 -1
  42. package/dist/core/browse/templates.js +18 -2
  43. package/dist/core/browse/templates.js.map +1 -1
  44. package/dist/core/checks/organize-checks.d.ts +17 -0
  45. package/dist/core/checks/organize-checks.d.ts.map +1 -1
  46. package/dist/core/checks/organize-checks.js +116 -0
  47. package/dist/core/checks/organize-checks.js.map +1 -1
  48. package/dist/core/errors.d.ts +43 -0
  49. package/dist/core/errors.d.ts.map +1 -1
  50. package/dist/core/errors.js +105 -0
  51. package/dist/core/errors.js.map +1 -1
  52. package/dist/core/git/exec.d.ts +10 -0
  53. package/dist/core/git/exec.d.ts.map +1 -1
  54. package/dist/core/git/exec.js +52 -2
  55. package/dist/core/git/exec.js.map +1 -1
  56. package/dist/core/graph/diff-block.d.ts +6 -0
  57. package/dist/core/graph/diff-block.d.ts.map +1 -0
  58. package/dist/core/graph/diff-block.js +54 -0
  59. package/dist/core/graph/diff-block.js.map +1 -0
  60. package/dist/core/graph/diff-document.d.ts +37 -0
  61. package/dist/core/graph/diff-document.d.ts.map +1 -0
  62. package/dist/core/graph/diff-document.js +119 -0
  63. package/dist/core/graph/diff-document.js.map +1 -0
  64. package/dist/core/graph/diff.d.ts +123 -0
  65. package/dist/core/graph/diff.d.ts.map +1 -0
  66. package/dist/core/graph/diff.js +253 -0
  67. package/dist/core/graph/diff.js.map +1 -0
  68. package/dist/core/graph/tree.d.ts +24 -0
  69. package/dist/core/graph/tree.d.ts.map +1 -0
  70. package/dist/core/graph/tree.js +45 -0
  71. package/dist/core/graph/tree.js.map +1 -0
  72. package/dist/core/notes/list.d.ts +10 -0
  73. package/dist/core/notes/list.d.ts.map +1 -1
  74. package/dist/core/notes/list.js +35 -12
  75. package/dist/core/notes/list.js.map +1 -1
  76. package/dist/core/publish/filing.d.ts +12 -12
  77. package/dist/core/publish/filing.d.ts.map +1 -1
  78. package/dist/core/publish/filing.js +20 -18
  79. package/dist/core/publish/filing.js.map +1 -1
  80. package/dist/core/publish/lifespan.d.ts +37 -0
  81. package/dist/core/publish/lifespan.d.ts.map +1 -0
  82. package/dist/core/publish/lifespan.js +59 -0
  83. package/dist/core/publish/lifespan.js.map +1 -0
  84. package/dist/core/publish/represents.d.ts +72 -0
  85. package/dist/core/publish/represents.d.ts.map +1 -0
  86. package/dist/core/publish/represents.js +83 -0
  87. package/dist/core/publish/represents.js.map +1 -0
  88. package/dist/run.d.ts.map +1 -1
  89. package/dist/run.js +34 -4
  90. package/dist/run.js.map +1 -1
  91. package/dist/version.d.ts +1 -1
  92. package/dist/version.js +1 -1
  93. package/package.json +2 -1
  94. package/templates/conventions/baseline-conventions.md +6 -0
  95. package/templates/graph/knowledge-changes/archived.md +1 -0
  96. package/templates/graph/knowledge-changes/bare-route.md +2 -0
  97. package/templates/graph/knowledge-changes/block.md +10 -0
  98. package/templates/graph/knowledge-changes/counts.md +1 -0
  99. package/templates/graph/knowledge-changes/dangling.md +1 -0
  100. package/templates/graph/knowledge-changes/empty.md +1 -0
  101. package/templates/graph/knowledge-changes/review.md +4 -0
  102. package/templates/serve/diagrams.mjs +136 -0
  103. package/templates/serve/shell.html +1 -1
  104. package/templates/serve/style.css +27 -0
  105. package/templates/skills/ctxr-organize-audit.md +19 -0
  106. package/templates/skills/ctxr-publish.md +100 -45
  107. package/templates/skills/ctxr-submit.md +24 -15
@@ -2,12 +2,28 @@ Turn store content into a shareable HTML page for a subject — a store subtree,
2
2
  concept whose sources aren't co-located. Deciding what belongs on the page is the one step no
3
3
  convention can enforce for you; everything else here is a decision procedure, not a mechanism.
4
4
 
5
- ## 1. Does this earn a page over a note?
5
+ ## 1. Permanent or disposable? Decide first
6
6
 
7
- Reach for a page when the reader needs to compare options side by side, see spatial structure, manipulate
8
- something, navigate non-linearly, or share a link — and the store's own notes genuinely can't. A page
9
- costs several times the effort of the markdown it's drawn from; don't build one to restate a note in a
10
- different font. If a note would do the job, the note is the deliverable.
7
+ Decide the page's lifespan before you do anything else. A page has one of two lifespans:
8
+
9
+ - **Permanent.** The page is the rendered form of one note that will keep changing. Keep it, and
10
+ update it when the note changes.
11
+ - **Disposable.** The page helps somebody understand something once. Examples are an explainer, a
12
+ report on one week of agent work, or a comparison for one decision. Nobody updates it.
13
+
14
+ Choose disposable when you cannot name the one note that the page represents. Why: a kept page that
15
+ names no note holds facts that live nowhere else, and nothing can tell when they go out of date.
16
+
17
+ The location of the page sets its lifespan. Nothing in the page declares it. A disposable page sits
18
+ under `disposable/` directly below the store's published-pages location. Every other page is
19
+ permanent.
20
+
21
+ For a permanent page, make sure that the page earns its place over a note. Use a page when the reader
22
+ must compare options side by side, see spatial structure, manipulate something, navigate
23
+ non-linearly, or open a link. Use it only when the store's own notes cannot do this. Why: a page
24
+ costs several times the effort of the markdown it comes from. If a note does the job, the note is the
25
+ deliverable. Do not apply this test to a disposable page. Why: a disposable page is cheap on purpose,
26
+ and it is the cheap way to understand something once.
11
27
 
12
28
  ## 2. Name the subject, let the selector produce the set
13
29
 
@@ -28,46 +44,61 @@ content belongs in front of this page's intended readers — a page written for
28
44
  not carry material written about that party, or about anyone else who did not expect to be quoted.
29
45
  When you are unsure about a note, leave it out and name it to the operator rather than guessing.
30
46
 
31
- ## 4. Fix the identity once, at the path `gather` reported
47
+ ## 4. Fix the identity once
48
+
49
+ **A disposable page.** Run `ctxr publish new --disposable <name>`. The command creates the folder
50
+ `disposable/<YYYY-MM-DD>-<name>` with today's date, and its sibling README. Give the name alone. Why:
51
+ the command supplies the date, and it refuses a name that starts with one. Do not use the path that
52
+ `gather` reported. Why: disposable pages sit in one flat folder, sorted by date, not by subject.
32
53
 
33
- Step 2 reported the path under the store's published-pages location at which a page for this subject
34
- belongs, derived from where the subject's notes live. Take it verbatim, append the page's own name,
35
- and hand the result to `ctxr publish new <slug>`, which creates the folder and its sibling README:
54
+ **A permanent page.** Step 2 reported the path at which a page for this subject belongs. That path is
55
+ under the store's published-pages location, and comes from where the subject's notes live.
56
+ Take it verbatim, append the page's own name, and give the result to `ctxr publish new <slug>`. The
57
+ command creates the folder and its sibling README:
36
58
 
37
59
  ```sh
38
60
  ctxr publish new <reported path>/<page-name>
39
61
  ```
40
62
 
41
- The depth is the store's own, not a fixed number of levels — a subject whose notes live four folders
42
- deep files four folders deep. That is what makes the published-pages navigation read like the store
43
- instead of like one long list. `ctxr publish check` reports a page filed flat at the published-pages
44
- root as a failing check, and checks nothing further about the location, because which folder is
45
- right is the question `gather` already answered.
63
+ The depth is the store's own, not a fixed number of levels. A subject whose notes are four folders
64
+ deep gets a page four folders deep. Why: then the published-pages navigation reads like the store, not
65
+ like one long list. `ctxr publish check` fails a page filed flat at the published-pages root. It
66
+ checks nothing more about the location. Why: `gather` already answered which folder is correct.
46
67
 
47
- Name the page for what it *is*, never for its subject. The folders above it already carry the
48
- subject, so `<reported path>/<subject>` says one word twice while `<reported path>/decision-board`
68
+ Name the page for what it *is*, never for its subject. Why: the folders above it already name the
69
+ subject. `<reported path>/<subject>` says one word two times, and `<reported path>/decision-board`
49
70
  says something.
50
71
 
51
- When `gather` reports that an existing page belongs at the reported path too, it is because this
52
- subject is acquiring a second page, and a subject's pages collect under one folder naming it. Move
53
- that page there before you scaffold the new one, and tell the operator its URL changed — somebody
54
- may already be holding that link. `ctxr publish urls` reports the old address beside the new one, and
55
- `ctxr-submit` carries both into the pull request. `gather` moves nothing itself, and it names which signal counted
56
- the page as this subject's; read that before you move anything, because the signal is a reading of
57
- the page's README and can be wrong. Lead a page's source notes with the note it is a representation
58
- of — that lead link is what says whose page this is, and everything after it is a citation.
59
-
60
- When `gather` reports that no path derives — the subject names the store root itself, so no folder
61
- names it — the choice is yours to make and to own: pick the folder that best names the subject to
62
- the reader, write that choice and your reason into the page's README, and name it to the operator.
63
- Nothing checks this for you, by design. Filing a page under a word that names nothing serves nobody
64
- who reads it.
65
-
66
- A slug starting with a date (`YYYY-` or `YYYY-MM-DD-`) is reserved for a frozen snapshot — never used
67
- for a page you intend to keep updating. That rule binds the page's own final segment, not the folders
68
- it is filed under. The command refuses to overwrite an existing folder; if one already exists for
69
- this subject, edit its files directly rather than re-running `publish new` — a rename or an overwrite
70
- breaks any link already handed out.
72
+ Sometimes `gather` reports that an existing page also belongs at the reported path. This subject then
73
+ gets a second page, and the pages of a subject collect under one folder that names it. Move that page
74
+ there before you create the new one, and tell the operator its URL changed. Why: somebody can already
75
+ have that link. `ctxr publish urls` reports the old address next to the new one, and `ctxr-submit`
76
+ puts both into the pull request. `gather` moves nothing. It names the signal that counted the page as
77
+ this subject's page. Read that signal before you move anything. Why: the signal is a reading of the
78
+ page's README, and it can be wrong.
79
+
80
+ Lead a page's source notes with the note it is a representation of. `ctxr publish check` fails a
81
+ permanent page whose README does not start with a wikilink to exactly one note. For a page that comes
82
+ from a store folder, that note is the folder's hub note. If the folder has no hub note, write one, or
83
+ make the page disposable. The page can link to many more notes after the lead link. Why: the lead link
84
+ says which note the page represents, and each link after it is a citation.
85
+
86
+ After you write the README, run `ctxr publish stamp <path>`. The command records the represented
87
+ note's hash on the lead-link line. Why: `ctxr publish check` then reports the page as stale when that
88
+ note changes.
89
+
90
+ Sometimes `gather` reports that no path derives. One reason is that the subject is the store root, so
91
+ no folder names it. The other reason is that the path would start with `disposable/`, a segment that
92
+ only disposable pages can use. Then you choose the folder, and you own that choice. Pick the folder
93
+ that best names the subject to the reader.
94
+ Then write that choice and your reason into the page's README, and tell the operator. Nothing checks
95
+ this choice. Why: a page filed under a word that names nothing helps no reader.
96
+
97
+ Never start the page's own name with a date (`YYYY-` or `YYYY-MM-DD-`). That naming is reserved for
98
+ the frozen pages that `ctxr publish new --disposable` makes. The rule applies to the final segment, not
99
+ to the folders above it. The command refuses to overwrite an existing folder. If a folder already
100
+ exists for this subject, edit its files directly. Do not run `publish new` again. Why: a rename or an
101
+ overwrite breaks a link that somebody already has.
71
102
 
72
103
  ## 5. Choose the form, then delegate the craft
73
104
 
@@ -93,11 +124,20 @@ lower is the same material in shorter words.
93
124
 
94
125
  ## 6. Verify the output invariants
95
126
 
96
- `ctxr publish check <path>` runs the mechanical half of the checklist — no external network address,
97
- a viewport meta tag, at least one print rule, a provenance line, a sibling README, balanced tags,
98
- valid syntax in every embedded script, and the page's filing location from step 4. It exits non-zero naming every failing check; fix all of them
99
- before reporting the page as ready. It answers only what's derivable from the file itself — the DO-test
100
- in step 1, the form and reader choices in step 5, and factual accuracy stay judgment calls, not checker output.
127
+ Run `ctxr publish check <path>`. It runs the mechanical half of the checklist:
128
+
129
+ - no external network address, a viewport meta tag, at least one print rule, and a provenance line;
130
+ - a sibling README, balanced tags, and valid syntax in every embedded script;
131
+ - the page's filing location from step 4;
132
+ - for a disposable page, its shape (`disposable-shape`): one folder directly under `disposable/`,
133
+ with a real date at the start of its name;
134
+ - for a permanent page, the note it represents (`represented-note`) and that note's recorded hash
135
+ (`represented-note-hash`).
136
+
137
+ The command reports the page's lifespan. It exits non-zero and names every failing check. Fix all of
138
+ them before you report the page as ready. The command answers only what the files can show. Why: the
139
+ lifespan choice and the DO-test in step 1, the form and reader choices in step 5, and factual accuracy
140
+ are judgment calls, not checker output.
101
141
 
102
142
  `ctxr publish new` and `ctxr publish check` each end by naming the address `ctxr serve` answers for
103
143
  this page. Look at the page before you hand it on. Whether the form works, whether the prose reads,
@@ -131,10 +171,25 @@ anything else the store retrieves. Confirm with `ctxr lint` after landing.
131
171
 
132
172
  ## 8. Provenance and drift
133
173
 
134
- The source notes are the fact of record. When a fact changes, change the note first, then the page —
135
- and grep the page for every place that fact was echoed (a summary line, a total, a status badge) before
136
- declaring the update done; a page that repeats a number in three places goes stale in all three if only
137
- one is touched.
174
+ The source notes are the fact of record. When a fact changes, change the note first, then the page.
175
+ Search the page for every place that repeats the fact, such as a summary line, a total, or a status
176
+ badge. Update each one before you say the update is done. Why: a page that repeats a number in three
177
+ places goes stale in all three if you change only one.
178
+
179
+ `ctxr publish check` and `ctxr lint` report a permanent page as stale when its represented note
180
+ changed after the stamp. To confirm a stale page, do these steps in order:
181
+
182
+ 1. Review the page against the note, and update the page where the two disagree.
183
+ 2. Remove the `<!-- hash:… -->` marker from the README's lead-link line.
184
+ 3. Run `ctxr publish stamp <path>` again.
185
+
186
+ `ctxr publish stamp` never overwrites a marker. Why: a stamp without a review confirms nothing, so
187
+ the stale report stays until somebody removes the marker.
188
+
189
+ Never revise a disposable page after it lands. Why: it is a snapshot of one moment, and its link
190
+ shows that moment. Make a new disposable page instead. Do not remove a disposable page yourself.
191
+ `ctxr lint` lists disposable pages that are older than 30 days, and the operator decides which to
192
+ remove (`ctxr-organize-audit`).
138
193
 
139
194
  ## 9. Landing
140
195
 
@@ -56,21 +56,30 @@ Every pull request takes one of three routes. Say which, and why, in its body:
56
56
  `git branch -m "<name>"` before pushing — never
57
57
  let a generated name reach the forge. A name given at `ctxr session start` does not settle this: it
58
58
  named a worktree when the work began, and what ships is decided here.
59
- 8. Before opening the pull request, run `ctxr publish urls --since origin/__DEFAULT_BRANCH__ --json`. When it
60
- lists any page, the body gets a **Pages** section: a table with one row per page giving its status, its
61
- preview address, and its published address — copied from the report, never rebuilt by hand. Mark a moved
62
- page's old address as one that stops working, and a removed page's the same. Under the table state the
63
- condition once: a preview resolves only while this pull request is open and the server can see this
64
- session's worktree, and the published address resolves once the served checkout takes the landed commit.
65
- When the report carries no preview, leave that column out; when it says no base URL is declared, say the
66
- addresses are bare routes. When it lists no page, add no section.
67
- Then run: `git push -u origin "<branch>"`, then `gh pr create --base __DEFAULT_BRANCH__ --title "<title>" --body
68
- "<why / what changed / route / verification / follow-ups>"`. `gh` authenticates from its own credential
69
- file: never export or interpolate a token, and never rewrite the origin's URL — it is a credential. The body answers those five questions; write the
70
- why so a reviewer need not re-derive it. Do not stop to confirm first — the request to
71
- submit is the consent for both, and `ctxr doctor` in step 5 is the gate on this path. If `gh` has no
72
- reachable GitHub remote for this repository, `git push` still succeeds on its own — report the pushed
73
- branch and give the operator the manual pull-request instructions instead of retrying `gh`.
59
+ 8. Before you open the pull request, run `ctxr publish urls --since origin/__DEFAULT_BRANCH__ --json`.
60
+ When it lists a page, add a **Pages** section to the body. The section is a table with one row per page.
61
+ Each row gives the page's status, its lifespan (permanent or disposable), its preview address, and its
62
+ published address. Copy every value from the report, never rebuilt by hand. Why: the report reads the
63
+ change set, and a guess from the path can be wrong. Mark the old address of a moved page as one that
64
+ stops working. Mark the address of a removed page the same way. Under the table, state the condition
65
+ one time: a preview resolves only while this pull request is open and the server can see this
66
+ session's worktree, and the published address resolves when the served checkout has the landed commit.
67
+ When the report has no preview, leave out that column. When it says that no base URL is declared, say
68
+ that the addresses are bare routes. When it lists no page, add no section.
69
+ Then run `ctxr graph diff --since origin/__DEFAULT_BRANCH__ --format markdown`. Paste its output into the
70
+ body verbatim, as the **Knowledge changes** section. Do not add, remove, or change a word of it. Why: you
71
+ wrote the change, and the reviewer checks your account against this record, which the command wrote.
72
+ Always paste the block, also when it says that the range changes no note. Why: a missing section looks the
73
+ same as a skipped step. The block is the record of the change. The review address in the block is a
74
+ convenience only. Why: it resolves only while this session's worktree exists and the server can reach it.
75
+ Then run `git push -u origin "<branch>"`. Then run `gh pr create --base __DEFAULT_BRANCH__ --title "<title>"
76
+ --body "<why / what changed / route / verification / follow-ups>"`. `gh` reads its own credential file, so
77
+ never export or interpolate a token, and never rewrite the origin's URL. Why: that URL can hold a
78
+ credential. The body answers those five questions and carries the sections above. Write the why so that a
79
+ reviewer does not have to find it again. Do not stop to confirm first. Why: the request to submit is the
80
+ consent for both, and `ctxr doctor` in step 5 is the gate on this path. If `gh` has no reachable GitHub
81
+ remote for this repository, `git push` still succeeds alone. Then report the pushed branch, and give the
82
+ operator the manual pull-request instructions. Do not retry `gh`.
74
83
  9. Verify before any retry: a transport error can arrive AFTER the push or the pull-request open already
75
84
  succeeded. Before retrying anything, `git ls-remote origin <branch>` and `gh pr list --head <branch>` —
76
85
  never replay a push or a pull-request open blindly.