ctxr-cli 0.9.0 → 0.11.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 (211) hide show
  1. package/README.md +28 -11
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +10 -2
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/publish-check.d.ts.map +1 -1
  6. package/dist/commands/publish-check.js +8 -0
  7. package/dist/commands/publish-check.js.map +1 -1
  8. package/dist/commands/publish-new.d.ts.map +1 -1
  9. package/dist/commands/publish-new.js +15 -0
  10. package/dist/commands/publish-new.js.map +1 -1
  11. package/dist/commands/serve.d.ts.map +1 -1
  12. package/dist/commands/serve.js +33 -11
  13. package/dist/commands/serve.js.map +1 -1
  14. package/dist/commands/session-start.d.ts.map +1 -1
  15. package/dist/commands/session-start.js +9 -1
  16. package/dist/commands/session-start.js.map +1 -1
  17. package/dist/commands/source-check.d.ts.map +1 -1
  18. package/dist/commands/source-check.js +28 -3
  19. package/dist/commands/source-check.js.map +1 -1
  20. package/dist/commands/update.d.ts.map +1 -1
  21. package/dist/commands/update.js +7 -1
  22. package/dist/commands/update.js.map +1 -1
  23. package/dist/commands/verify.d.ts +11 -2
  24. package/dist/commands/verify.d.ts.map +1 -1
  25. package/dist/commands/verify.js +86 -5
  26. package/dist/commands/verify.js.map +1 -1
  27. package/dist/commands/version.d.ts +31 -0
  28. package/dist/commands/version.d.ts.map +1 -0
  29. package/dist/commands/version.js +87 -0
  30. package/dist/commands/version.js.map +1 -0
  31. package/dist/config/defaults.d.ts +71 -5
  32. package/dist/config/defaults.d.ts.map +1 -1
  33. package/dist/config/defaults.js +70 -5
  34. package/dist/config/defaults.js.map +1 -1
  35. package/dist/config/load.d.ts +2 -2
  36. package/dist/config/load.d.ts.map +1 -1
  37. package/dist/config/load.js +13 -3
  38. package/dist/config/load.js.map +1 -1
  39. package/dist/config/render.d.ts +0 -6
  40. package/dist/config/render.d.ts.map +1 -1
  41. package/dist/config/render.js +4 -27
  42. package/dist/config/render.js.map +1 -1
  43. package/dist/config/schema.d.ts +21 -67
  44. package/dist/config/schema.d.ts.map +1 -1
  45. package/dist/config/schema.js +73 -112
  46. package/dist/config/schema.js.map +1 -1
  47. package/dist/core/agents-doc.d.ts.map +1 -1
  48. package/dist/core/agents-doc.js +2 -1
  49. package/dist/core/agents-doc.js.map +1 -1
  50. package/dist/core/browse/nav.d.ts.map +1 -1
  51. package/dist/core/browse/nav.js +4 -1
  52. package/dist/core/browse/nav.js.map +1 -1
  53. package/dist/core/browse/preferences.d.ts +26 -0
  54. package/dist/core/browse/preferences.d.ts.map +1 -0
  55. package/dist/core/browse/preferences.js +74 -0
  56. package/dist/core/browse/preferences.js.map +1 -0
  57. package/dist/core/browse/routes.d.ts +10 -8
  58. package/dist/core/browse/routes.d.ts.map +1 -1
  59. package/dist/core/browse/routes.js +113 -24
  60. package/dist/core/browse/routes.js.map +1 -1
  61. package/dist/core/browse/templates.d.ts +14 -4
  62. package/dist/core/browse/templates.d.ts.map +1 -1
  63. package/dist/core/browse/templates.js +22 -4
  64. package/dist/core/browse/templates.js.map +1 -1
  65. package/dist/core/checks/harness-portability-checks.d.ts +21 -0
  66. package/dist/core/checks/harness-portability-checks.d.ts.map +1 -1
  67. package/dist/core/checks/harness-portability-checks.js +46 -1
  68. package/dist/core/checks/harness-portability-checks.js.map +1 -1
  69. package/dist/core/checks/integrity-checks.d.ts +0 -2
  70. package/dist/core/checks/integrity-checks.d.ts.map +1 -1
  71. package/dist/core/checks/integrity-checks.js +38 -27
  72. package/dist/core/checks/integrity-checks.js.map +1 -1
  73. package/dist/core/checks/manifest.d.ts.map +1 -1
  74. package/dist/core/checks/manifest.js +2 -0
  75. package/dist/core/checks/manifest.js.map +1 -1
  76. package/dist/core/checks/store-checks.d.ts +12 -0
  77. package/dist/core/checks/store-checks.d.ts.map +1 -0
  78. package/dist/core/checks/store-checks.js +37 -0
  79. package/dist/core/checks/store-checks.js.map +1 -0
  80. package/dist/core/command.d.ts +6 -0
  81. package/dist/core/command.d.ts.map +1 -1
  82. package/dist/core/convention-doc.d.ts.map +1 -1
  83. package/dist/core/convention-doc.js +15 -9
  84. package/dist/core/convention-doc.js.map +1 -1
  85. package/dist/core/env.d.ts +5 -0
  86. package/dist/core/env.d.ts.map +1 -1
  87. package/dist/core/env.js +3 -0
  88. package/dist/core/env.js.map +1 -1
  89. package/dist/core/environment/probe.d.ts +12 -0
  90. package/dist/core/environment/probe.d.ts.map +1 -0
  91. package/dist/core/environment/probe.js +36 -0
  92. package/dist/core/environment/probe.js.map +1 -0
  93. package/dist/core/errors.d.ts +16 -3
  94. package/dist/core/errors.d.ts.map +1 -1
  95. package/dist/core/errors.js +41 -15
  96. package/dist/core/errors.js.map +1 -1
  97. package/dist/core/git/worktree.d.ts +22 -0
  98. package/dist/core/git/worktree.d.ts.map +1 -1
  99. package/dist/core/git/worktree.js +34 -0
  100. package/dist/core/git/worktree.js.map +1 -1
  101. package/dist/core/graph/model.d.ts +7 -6
  102. package/dist/core/graph/model.d.ts.map +1 -1
  103. package/dist/core/graph/model.js +11 -7
  104. package/dist/core/graph/model.js.map +1 -1
  105. package/dist/core/harness/isolated-run.d.ts +52 -0
  106. package/dist/core/harness/isolated-run.d.ts.map +1 -0
  107. package/dist/core/harness/isolated-run.js +100 -0
  108. package/dist/core/harness/isolated-run.js.map +1 -0
  109. package/dist/core/install-kind.d.ts +25 -0
  110. package/dist/core/install-kind.d.ts.map +1 -0
  111. package/dist/core/install-kind.js +56 -0
  112. package/dist/core/install-kind.js.map +1 -0
  113. package/dist/core/note-templates.d.ts +61 -0
  114. package/dist/core/note-templates.d.ts.map +1 -0
  115. package/dist/core/note-templates.js +188 -0
  116. package/dist/core/note-templates.js.map +1 -0
  117. package/dist/core/notes/list.d.ts.map +1 -1
  118. package/dist/core/notes/list.js +5 -0
  119. package/dist/core/notes/list.js.map +1 -1
  120. package/dist/core/publish/script-check.d.ts +5 -2
  121. package/dist/core/publish/script-check.d.ts.map +1 -1
  122. package/dist/core/publish/script-check.js +5 -2
  123. package/dist/core/publish/script-check.js.map +1 -1
  124. package/dist/core/reconcile.d.ts.map +1 -1
  125. package/dist/core/reconcile.js +8 -0
  126. package/dist/core/reconcile.js.map +1 -1
  127. package/dist/core/registry.d.ts +40 -0
  128. package/dist/core/registry.d.ts.map +1 -0
  129. package/dist/core/registry.js +55 -0
  130. package/dist/core/registry.js.map +1 -0
  131. package/dist/core/root.d.ts +11 -5
  132. package/dist/core/root.d.ts.map +1 -1
  133. package/dist/core/root.js +20 -8
  134. package/dist/core/root.js.map +1 -1
  135. package/dist/core/skills.d.ts.map +1 -1
  136. package/dist/core/skills.js +32 -15
  137. package/dist/core/skills.js.map +1 -1
  138. package/dist/core/version-check.d.ts +63 -0
  139. package/dist/core/version-check.d.ts.map +1 -0
  140. package/dist/core/version-check.js +181 -0
  141. package/dist/core/version-check.js.map +1 -0
  142. package/dist/core/write-lifecycle/path-gate.d.ts.map +1 -1
  143. package/dist/core/write-lifecycle/path-gate.js +4 -1
  144. package/dist/core/write-lifecycle/path-gate.js.map +1 -1
  145. package/dist/run.d.ts +1 -1
  146. package/dist/run.d.ts.map +1 -1
  147. package/dist/run.js +38 -16
  148. package/dist/run.js.map +1 -1
  149. package/dist/version.d.ts +8 -1
  150. package/dist/version.d.ts.map +1 -1
  151. package/dist/version.js +8 -1
  152. package/dist/version.js.map +1 -1
  153. package/package.json +1 -1
  154. package/templates/agents/canonical.md +5 -1
  155. package/templates/notes/Company.md +25 -0
  156. package/templates/notes/Concept.md +29 -0
  157. package/templates/notes/Deal.md +25 -0
  158. package/templates/notes/Note.md +6 -0
  159. package/templates/notes/People.md +19 -0
  160. package/templates/notes/Project.md +19 -0
  161. package/templates/serve/shell.html +16 -2
  162. package/templates/serve/style.css +145 -3
  163. package/templates/skills/ctxr-ingest-orchestration.md +4 -1
  164. package/templates/skills/ctxr-placement.md +21 -2
  165. package/templates/skills/ctxr-session-capture.md +5 -1
  166. package/templates/skills/ctxr-session-lifecycle.md +20 -0
  167. package/templates/skills/ctxr-upgrade.md +44 -0
  168. package/dist/commands/migrate.d.ts +0 -30
  169. package/dist/commands/migrate.d.ts.map +0 -1
  170. package/dist/commands/migrate.js +0 -56
  171. package/dist/commands/migrate.js.map +0 -1
  172. package/dist/core/migrations/add-explanation-craft-skill.d.ts +0 -26
  173. package/dist/core/migrations/add-explanation-craft-skill.d.ts.map +0 -1
  174. package/dist/core/migrations/add-explanation-craft-skill.js +0 -94
  175. package/dist/core/migrations/add-explanation-craft-skill.js.map +0 -1
  176. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts +0 -35
  177. package/dist/core/migrations/archive-destination-from-taxonomy.d.ts.map +0 -1
  178. package/dist/core/migrations/archive-destination-from-taxonomy.js +0 -109
  179. package/dist/core/migrations/archive-destination-from-taxonomy.js.map +0 -1
  180. package/dist/core/migrations/config-defaults-as-the-convention.d.ts +0 -21
  181. package/dist/core/migrations/config-defaults-as-the-convention.d.ts.map +0 -1
  182. package/dist/core/migrations/config-defaults-as-the-convention.js +0 -54
  183. package/dist/core/migrations/config-defaults-as-the-convention.js.map +0 -1
  184. package/dist/core/migrations/drop-access-axes.d.ts +0 -24
  185. package/dist/core/migrations/drop-access-axes.d.ts.map +0 -1
  186. package/dist/core/migrations/drop-access-axes.js +0 -54
  187. package/dist/core/migrations/drop-access-axes.js.map +0 -1
  188. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts +0 -19
  189. package/dist/core/migrations/drop-forge-and-workspaces-external.d.ts.map +0 -1
  190. package/dist/core/migrations/drop-forge-and-workspaces-external.js +0 -49
  191. package/dist/core/migrations/drop-forge-and-workspaces-external.js.map +0 -1
  192. package/dist/core/migrations/registry.d.ts +0 -16
  193. package/dist/core/migrations/registry.d.ts.map +0 -1
  194. package/dist/core/migrations/registry.js +0 -34
  195. package/dist/core/migrations/registry.js.map +0 -1
  196. package/dist/core/migrations/rename-conventions-path.d.ts +0 -26
  197. package/dist/core/migrations/rename-conventions-path.d.ts.map +0 -1
  198. package/dist/core/migrations/rename-conventions-path.js +0 -86
  199. package/dist/core/migrations/rename-conventions-path.js.map +0 -1
  200. package/dist/core/migrations/rename-procedures-path.d.ts +0 -17
  201. package/dist/core/migrations/rename-procedures-path.d.ts.map +0 -1
  202. package/dist/core/migrations/rename-procedures-path.js +0 -45
  203. package/dist/core/migrations/rename-procedures-path.js.map +0 -1
  204. package/dist/core/migrations/retain-captures-as-provenance.d.ts +0 -22
  205. package/dist/core/migrations/retain-captures-as-provenance.d.ts.map +0 -1
  206. package/dist/core/migrations/retain-captures-as-provenance.js +0 -133
  207. package/dist/core/migrations/retain-captures-as-provenance.js.map +0 -1
  208. package/dist/core/migrations/types.d.ts +0 -27
  209. package/dist/core/migrations/types.d.ts.map +0 -1
  210. package/dist/core/migrations/types.js +0 -2
  211. package/dist/core/migrations/types.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ ---
2
+ date_created: "{{date}}"
3
+ title: "{{title}}"
4
+ tags:
5
+ - Deal
6
+ ---
7
+ # {{title}}
8
+
9
+ ## Terms
10
+ <!-- Round size, valuation, instrument, lead, board seat. -->
11
+
12
+ ## Counterparty
13
+ <!-- [[Company]] — what they do, team, key metrics. -->
14
+
15
+ ## Thesis
16
+ <!-- Why this is compelling. -->
17
+
18
+ ## Key relationships
19
+ <!-- [[wikilinks]] to investors, advisors, co-investors. -->
20
+
21
+ ## Interactions
22
+ <!-- Dated entries: ### YYYY-MM-DD — stage or event -->
23
+
24
+ ## Follow-ups
25
+ <!-- - [ ] Task text (added YYYY-MM-DD, due YYYY-MM-DD) -->
@@ -0,0 +1,6 @@
1
+ ---
2
+ date_created: "{{date}}"
3
+ title: "{{title}}"
4
+ tags: []
5
+ ---
6
+ # {{title}}
@@ -0,0 +1,19 @@
1
+ ---
2
+ date_created: "{{date}}"
3
+ title: "{{title}}"
4
+ tags:
5
+ - People
6
+ ---
7
+ # {{title}}
8
+
9
+ ## Bio
10
+ <!-- Who they are: current role, organization, relevant history. -->
11
+
12
+ ## Relationship
13
+ <!-- How you know them, and in what context. -->
14
+
15
+ ## Communication Log
16
+ <!-- Dated entries, one per exchange: ### YYYY-MM-DD — context -->
17
+
18
+ ## Follow-ups
19
+ <!-- - [ ] Task text (added YYYY-MM-DD, due YYYY-MM-DD) -->
@@ -0,0 +1,19 @@
1
+ ---
2
+ date_created: "{{date}}"
3
+ title: "{{title}}"
4
+ tags:
5
+ - Project
6
+ ---
7
+ # {{title}}
8
+
9
+ ## Goal
10
+ <!-- What done looks like. Work with no end state is an area, not a project. -->
11
+
12
+ ## Open threads
13
+ <!-- Unresolved decisions and blockers; each links where it was raised. -->
14
+
15
+ ## Follow-ups
16
+ <!-- - [ ] Task text (added YYYY-MM-DD, due YYYY-MM-DD) -->
17
+
18
+ ## Related
19
+ <!-- Links out to related notes. -->
@@ -1,5 +1,5 @@
1
1
  <!doctype html>
2
- <html lang="en">
2
+ <html lang="en" data-ctxr-theme="{{THEME}}" data-ctxr-nav="{{NAV_STATE}}">
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
@@ -7,7 +7,21 @@
7
7
  <link rel="stylesheet" href="/assets/style.css">
8
8
  </head>
9
9
  <body>
10
- <header class="ctxr-shell-header"><a href="/">contexture</a></header>
10
+ <input type="checkbox" id="ctxr-nav-toggle" class="ctxr-visually-hidden">
11
+ <header class="ctxr-shell-header">
12
+ <div class="ctxr-shell-header-start">
13
+ <label for="ctxr-nav-toggle" class="ctxr-nav-toggle-label"><span aria-hidden="true">☰</span><span class="ctxr-visually-hidden">Navigation</span></label>
14
+ <a href="/" class="ctxr-shell-title">contexture</a>
15
+ </div>
16
+ <div class="ctxr-shell-header-end">
17
+ <a class="ctxr-nav-collapse-link" href="{{NAV_TOGGLE_HREF}}"><span aria-hidden="true">☰</span><span class="ctxr-visually-hidden">{{NAV_TOGGLE_LABEL}}</span></a>
18
+ <nav class="ctxr-theme-switcher" aria-label="Display theme">
19
+ <a href="?ctxr-theme=light">Light</a>
20
+ <a href="?ctxr-theme=dark">Dark</a>
21
+ <a href="?ctxr-theme=system">System</a>
22
+ </nav>
23
+ </div>
24
+ </header>
11
25
  <div class="ctxr-layout">
12
26
  {{NAV}}
13
27
  <main>
@@ -1,5 +1,12 @@
1
+ /*
2
+ * serve-page-names-theme-and-nav-toggle design.md D8: the light palette
3
+ * lives on :root as the shared baseline. "light" mode needs nothing more
4
+ * than to pin color-scheme; "dark" overrides every custom property at
5
+ * higher specificity (html[data-ctxr-theme=...] beats a bare :root
6
+ * regardless of source order); "system" keeps the light baseline unless the
7
+ * dark media query — scoped to system alone, never left unscoped — applies.
8
+ */
1
9
  :root {
2
- color-scheme: light dark;
3
10
  --ctxr-fg: #1a1a1a;
4
11
  --ctxr-bg: #ffffff;
5
12
  --ctxr-muted: #6b6b6b;
@@ -8,8 +15,26 @@
8
15
  --ctxr-broken: #b3261e;
9
16
  }
10
17
 
18
+ html[data-ctxr-theme="light"] {
19
+ color-scheme: light;
20
+ }
21
+
22
+ html[data-ctxr-theme="system"] {
23
+ color-scheme: light dark;
24
+ }
25
+
26
+ html[data-ctxr-theme="dark"] {
27
+ color-scheme: dark;
28
+ --ctxr-fg: #e8e8e8;
29
+ --ctxr-bg: #121212;
30
+ --ctxr-muted: #9b9b9b;
31
+ --ctxr-border: #3a3a3a;
32
+ --ctxr-code-bg: #1e1e1e;
33
+ --ctxr-broken: #ff8a80;
34
+ }
35
+
11
36
  @media (prefers-color-scheme: dark) {
12
- :root {
37
+ html[data-ctxr-theme="system"] {
13
38
  --ctxr-fg: #e8e8e8;
14
39
  --ctxr-bg: #121212;
15
40
  --ctxr-muted: #9b9b9b;
@@ -28,6 +53,10 @@ body {
28
53
  }
29
54
 
30
55
  .ctxr-shell-header {
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: space-between;
59
+ gap: 1rem;
31
60
  padding: 0.75rem 1.5rem;
32
61
  border-bottom: 1px solid var(--ctxr-border);
33
62
  }
@@ -35,9 +64,96 @@ body {
35
64
  .ctxr-shell-header a {
36
65
  color: inherit;
37
66
  text-decoration: none;
67
+ }
68
+
69
+ .ctxr-shell-header-start,
70
+ .ctxr-shell-header-end {
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 0.75rem;
74
+ }
75
+
76
+ .ctxr-shell-title {
38
77
  font-weight: 600;
39
78
  }
40
79
 
80
+ .ctxr-theme-switcher {
81
+ display: flex;
82
+ gap: 0.75rem;
83
+ font-size: 0.85rem;
84
+ }
85
+
86
+ .ctxr-theme-switcher a {
87
+ color: var(--ctxr-muted);
88
+ }
89
+
90
+ .ctxr-theme-switcher a:hover,
91
+ .ctxr-theme-switcher a:focus-visible {
92
+ color: var(--ctxr-fg);
93
+ }
94
+
95
+ /*
96
+ * serve-page-names-theme-and-nav-toggle design.md D12: hidden off-screen
97
+ * rather than with display:none or visibility:hidden, either of which would
98
+ * drop the checkbox from the tab order and make the navigation unreachable
99
+ * by keyboard. Reused for the accessible-name text spans inside the two nav
100
+ * controls below, which need the identical off-screen treatment.
101
+ */
102
+ .ctxr-visually-hidden {
103
+ position: absolute;
104
+ width: 1px;
105
+ height: 1px;
106
+ overflow: hidden;
107
+ clip-path: inset(50%);
108
+ white-space: nowrap;
109
+ }
110
+
111
+ /* design.md D12: the checkbox is the first element in <body>, so this general-sibling selector can reach the visible label on :checked. */
112
+ #ctxr-nav-toggle:focus-visible ~ header .ctxr-nav-toggle-label {
113
+ outline: 2px solid currentColor;
114
+ outline-offset: 2px;
115
+ }
116
+
117
+ .ctxr-nav-toggle-label,
118
+ .ctxr-nav-collapse-link {
119
+ display: none;
120
+ align-items: center;
121
+ justify-content: center;
122
+ min-width: 2.75rem;
123
+ min-height: 2.75rem;
124
+ padding: 0.25rem 0.5rem;
125
+ border-radius: 4px;
126
+ cursor: pointer;
127
+ color: var(--ctxr-muted);
128
+ }
129
+
130
+ .ctxr-nav-toggle-label:hover,
131
+ .ctxr-nav-collapse-link:hover,
132
+ .ctxr-nav-toggle-label:focus-visible,
133
+ .ctxr-nav-collapse-link:focus-visible {
134
+ color: var(--ctxr-fg);
135
+ }
136
+
137
+ /*
138
+ * design.md D9: shown by default at a wide viewport, since a collapsed
139
+ * sidebar there must persist across navigation via the ctxr_nav cookie, not
140
+ * reset every page load the way the narrow-viewport checkbox does.
141
+ */
142
+ .ctxr-nav-collapse-link {
143
+ display: inline-flex;
144
+ }
145
+
146
+ /* design.md D9/D10: gated to a viewport wide enough to show the navigation alongside the content, so it can never contradict the narrow-viewport checkbox below. */
147
+ @media (min-width: 52.0625rem) {
148
+ html[data-ctxr-nav="collapsed"] .ctxr-layout {
149
+ grid-template-columns: minmax(0, 1fr);
150
+ }
151
+
152
+ html[data-ctxr-nav="collapsed"] .ctxr-nav {
153
+ display: none;
154
+ }
155
+ }
156
+
41
157
  .ctxr-layout {
42
158
  display: grid;
43
159
  grid-template-columns: minmax(14rem, 18rem) minmax(0, 1fr);
@@ -54,7 +170,12 @@ body {
54
170
  font-size: 0.9rem;
55
171
  }
56
172
 
57
- /* Stack the navigation above the content once two columns stop fitting. */
173
+ /*
174
+ * Stack the navigation above the content once two columns stop fitting, and
175
+ * hide it by default (design.md D9: a narrow viewport starts with the
176
+ * navigation hidden, revealed only by the checkbox below — the desktop
177
+ * ctxr_nav cookie above this breakpoint plays no part here).
178
+ */
58
179
  @media (max-width: 52rem) {
59
180
  .ctxr-layout {
60
181
  grid-template-columns: minmax(0, 1fr);
@@ -65,6 +186,27 @@ body {
65
186
  max-height: none;
66
187
  border-right: none;
67
188
  border-bottom: 1px solid var(--ctxr-border);
189
+ display: none;
190
+ }
191
+
192
+ #ctxr-nav-toggle:checked ~ .ctxr-layout .ctxr-nav {
193
+ display: block;
194
+ }
195
+
196
+ .ctxr-nav-toggle-label {
197
+ display: inline-flex;
198
+ }
199
+
200
+ .ctxr-nav-collapse-link {
201
+ display: none;
202
+ }
203
+ }
204
+
205
+ @media print {
206
+ .ctxr-nav,
207
+ .ctxr-nav-toggle-label,
208
+ .ctxr-nav-collapse-link {
209
+ display: none;
68
210
  }
69
211
  }
70
212
 
@@ -38,7 +38,10 @@ to put the file — "create a new note" is one option among several, never the d
38
38
  - Source discipline: a field the source does not confirm is "not reported" — never inferred from
39
39
  silence in either direction.
40
40
  5. Write the note the decision calls for — create it, expand it, merge, restructure, or add a section —
41
- preserving prior content in every case but the deliberate rewrite.
41
+ preserving prior content in every case but the deliberate rewrite. A NEW note starts from a template
42
+ under `__TEMPLATES_PATH__`, with `{{title}}` and `{{date}}` substituted as you write (`ctxr-placement`
43
+ picks which). An EXISTING note is extended in place — never re-cut from a template, which would throw
44
+ away the content that made it worth expanding.
42
45
  6. Register the source against whatever note you just wrote:
43
46
  `ctxr ingest <path> --into <note> --source-type <type> --source-id <id>`. Every row of the table above
44
47
  ends here, not just the first: the command retains the capture under the capture tier's month, freezes
@@ -9,8 +9,20 @@ __LAYER_STEP__
9
9
  - Match on what the content IS. When two sibling locations both seem to fit, name the distinction between
10
10
  them (abstract vs concrete; outward-facing vs inward-facing; who-we-are vs how-it-runs) and pick by
11
11
  altitude and audience, not by keyword.
12
- - Read one or two sibling notes in the chosen location and match their shape — frontmatter keys, heading
13
- style, bullets vs prose — before writing.
12
+ - If the chosen location has a `README.md`, read it first: a folder with one answer about what its notes
13
+ look like states it there, and that answer wins over anything you would infer.
14
+
15
+ ## 2b. Which template?
16
+
17
+ Start a new note from a template under `__TEMPLATES_PATH__` — never a blank file, and never by copying a
18
+ sibling wholesale. List that directory and pick the kind the content actually is; `Note` is the base when
19
+ nothing more specific fits, and it is also the file to copy when this store needs a kind it does not have.
20
+ Substitute `{{title}}` and `{{date}}` as you write — no command expands them, and `ctxr lint` reports a
21
+ note that lands with one still in it.
22
+
23
+ The template is the starting shape, not a cage: delete a section that does not apply rather than leaving
24
+ it empty, and add one the note needs. Read a sibling note only for what the template leaves open — house
25
+ phrasing, bullets vs prose, which tags this location uses.
14
26
 
15
27
  ## 3. Sub-item under an existing location, or a new top-level one?
16
28
 
@@ -37,6 +49,13 @@ manufactures an artifact for the graveyard; capture the durable slice by hand in
37
49
  Add a one-line wikilink from the relevant hub note so the new note is not an orphan; `ctxr lint` flags
38
50
  orphans and notes without a catalog entry.
39
51
 
52
+ ## An existing note
53
+
54
+ A note that already exists is EXTENDED, never restarted from a template: add the section it now needs,
55
+ preserve what is there, and leave its frontmatter alone. Re-cutting a note from a template to "bring it up
56
+ to standard" destroys the content that made it worth keeping — a note that has outgrown its starting shape
57
+ is doing the right thing.
58
+
40
59
  ## Relocating an existing note
41
60
 
42
61
  `ctxr archive <path>` to retire it; a plain tracked `git mv` for an ordinary re-placement. Either way the
@@ -84,7 +84,11 @@ notes:
84
84
  path: <layer>/<location>/<Title>.md
85
85
  mode: create # or: append
86
86
  body: |
87
- matching the frontmatter and style of the sibling notes (`ctxr-placement` decides the location)
87
+ for create: started from a template under `__TEMPLATES_PATH__`, with {{title}} and {{date}}
88
+ substituted, sections that do not apply deleted rather than left empty
89
+ for append: only the new material, extending the note rather than restarting it — the
90
+ command appends your body verbatim and never rewrites what is already there
91
+ (`ctxr-placement` decides both the location and the template)
88
92
  ```
89
93
 
90
94
  Then run `ctxr session capture --proposal <file>`. It validates and writes every item independently —
@@ -9,6 +9,26 @@ the two verbs at the seams; their steps are not repeated here.
9
9
  If you find yourself on the default branch or in the root checkout, stop — `ctxr session list` shows the
10
10
  active sessions to work in instead.
11
11
 
12
+ Before starting, bring the store's canonical clone up to date — the repository's main worktree, not
13
+ whichever checkout you are standing in. From the canonical clone: `git fetch origin`, then
14
+ `git merge --ff-only origin/__DEFAULT_BRANCH__`. If it is on another branch, carries uncommitted
15
+ changes, or the fast-forward fails because it has diverged from origin, report exactly that and start
16
+ the session anyway — never check it out, reset it, stash, or force the merge to make it comply. The
17
+ session's base is unaffected either way, because `ctxr session start` branches from the
18
+ `origin/__DEFAULT_BRANCH__` it fetches itself. What a stale clone costs is the context you read out of
19
+ it: notes, catalog sections, the graph document, and AGENTS.md would all be the versions it last had.
20
+
21
+ `ctxr session start` names the start point it used. If it reports that it did not fetch, there was no
22
+ remote branch to fetch from and it branched from the local default branch instead — say so plainly,
23
+ because the session is then based on whatever that clone last had rather than on origin.
24
+
25
+ If `ctxr session start` reports a `cli.update_available` finding, a newer `ctxr` than the one installed
26
+ has been published. Name both versions to the operator and offer `ctxr-upgrade`; then continue the
27
+ session either way. Do not upgrade unasked, and do not make continuing conditional on the answer —
28
+ deferring is a normal answer, and the session is unaffected by it. A `cli.update_check_failed` finding
29
+ means the check could not be completed; it says nothing about whether an upgrade is due, so proceed
30
+ without mentioning it.
31
+
12
32
  ## Re-scan before any plan
13
33
 
14
34
  Re-scan whenever state may have moved under you — before presenting a plan, before running `ctxr-submit`,
@@ -0,0 +1,44 @@
1
+ Upgrade the installed `ctxr` to the latest published release, then bring this store's
2
+ contexture-owned files up to it. `ctxr-session-lifecycle` offers this skill at the start of a session
3
+ when a newer release is published; it is equally valid to run it directly.
4
+
5
+ Upgrading replaces the executable for every store on this machine, not only this one. That is why
6
+ step 3 gates on the operator rather than proceeding from the fact that a newer release exists.
7
+
8
+ 1. Read the live answer — never act on a notice from earlier in the conversation, which may be
9
+ minutes stale: `ctxr version --check --json`. The envelope's `data` carries `version` (installed),
10
+ `latest` (published), `release_status`, `install_path`, and `install_kind`. Exit code `0` means
11
+ already current: say so and stop. A non-zero exit with `release_status` of `undetermined` means the
12
+ published version could not be resolved — report the reason the finding names, and stop; do not
13
+ guess whether an upgrade is due.
14
+
15
+ 2. Check `install_kind` before proposing anything.
16
+ - `global` — proceed to step 3.
17
+ - `linked` — this executable resolves to a working copy at `install_path`, not a package
18
+ installation. A global install would upgrade a different `ctxr` than the one running. Report the
19
+ path and stop.
20
+ - `undetermined` — the executable is inside a `node_modules` that is not the global one: a project
21
+ dependency, or an `npx` invocation. Report `install_path` and stop; upgrading it is the
22
+ operator's call about that project, not a global install.
23
+
24
+ 3. Gate on the operator. Name the installed version, the published version, and `install_path`, and
25
+ ask whether to upgrade. Wait for an explicit go. Having approval for the session's other work is
26
+ not approval for this — it changes software outside the store.
27
+
28
+ 4. Upgrade, then confirm: `npm install -g ctxr-cli@latest`, then `ctxr version`. Confirm the reported
29
+ version is the published one before continuing. If it still reports the old version, the shell is
30
+ resolving a different `ctxr` than the one npm wrote — report that and stop rather than continuing
31
+ into step 5, where the re-render would be performed by the executable you just tried to replace.
32
+
33
+ 5. Re-render this store with the upgraded executable, in that order — the generated files come from
34
+ the binary, so re-rendering first would only rewrite them at the old version. Work in a session
35
+ worktree (`ctxr session start`), never the root checkout: `ctxr update` writes contexture-owned
36
+ files, and those writes land through a reviewed pull request like any other change.
37
+
38
+ 6. Land the re-render as its own pull request. `ctxr update` produces generated-file churn — AGENTS.md
39
+ sections, skill copies, hooks, adapter outputs — and mixing it into unrelated work makes both
40
+ harder to review. Follow `ctxr-submit`, then `ctxr-land`.
41
+
42
+ If step 4 or 5 fails, say which step and what the command reported. A partial upgrade — new executable,
43
+ un-re-rendered store — is a real state worth naming: the store still works, and step 5 can be re-run on
44
+ its own at any time.
@@ -1,30 +0,0 @@
1
- import type { CommandOutcome, CommandRequires } from '../core/command.js';
2
- import type { MigrationDelta } from '../core/migrations/types.js';
3
- import type { Store } from '../core/store.js';
4
- export declare const requires: CommandRequires;
5
- export interface MigrateFlags {
6
- dryRun?: boolean;
7
- }
8
- export interface MigrateMigrationResult {
9
- id: string;
10
- fromVersion: number;
11
- toVersion: number;
12
- deltas: MigrationDelta[];
13
- }
14
- export interface MigrateData {
15
- currentVersion: number;
16
- targetVersion: number;
17
- applied: boolean;
18
- migrations: MigrateMigrationResult[];
19
- }
20
- /**
21
- * store-lifecycle spec: `--dry-run` reports exact deltas with nothing
22
- * applied; a real run applies each pending migration in order, reloading
23
- * the store's config after each one so a later migration in the chain
24
- * (none exist yet, but the mechanism supports it) sees the version it
25
- * actually needs to start from. Resumability is a property of each
26
- * migration's own plan()/apply() (see core/migrations/types.ts) — this
27
- * command does no extra bookkeeping of its own.
28
- */
29
- export declare function execute(store: Store, flags: MigrateFlags): Promise<CommandOutcome<MigrateData>>;
30
- //# sourceMappingURL=migrate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,QAAQ,EAAE,eAAuC,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CA4CrG"}
@@ -1,56 +0,0 @@
1
- import { readConfig } from '../config/load.js';
2
- import { SUPPORTED_SCHEMA_VERSION } from '../config/schema.js';
3
- import { ExitCode } from '../core/exit-codes.js';
4
- import { pendingMigrations } from '../core/migrations/registry.js';
5
- export const requires = { store: 'required' };
6
- /**
7
- * store-lifecycle spec: `--dry-run` reports exact deltas with nothing
8
- * applied; a real run applies each pending migration in order, reloading
9
- * the store's config after each one so a later migration in the chain
10
- * (none exist yet, but the mechanism supports it) sees the version it
11
- * actually needs to start from. Resumability is a property of each
12
- * migration's own plan()/apply() (see core/migrations/types.ts) — this
13
- * command does no extra bookkeeping of its own.
14
- */
15
- export async function execute(store, flags) {
16
- const pending = pendingMigrations(store.config.schema_version);
17
- const startingVersion = store.config.schema_version;
18
- if (pending.length === 0) {
19
- return {
20
- exitCode: ExitCode.Ok,
21
- data: { currentVersion: startingVersion, targetVersion: SUPPORTED_SCHEMA_VERSION, applied: false, migrations: [] },
22
- findings: [],
23
- humanSummary: `Already at schema_version ${startingVersion}; nothing to migrate.`,
24
- storeRoot: store.root,
25
- schemaVersion: store.config.schema_version,
26
- };
27
- }
28
- const results = [];
29
- let workingStore = store;
30
- for (const migration of pending) {
31
- if (flags.dryRun) {
32
- const deltas = await migration.plan(workingStore);
33
- results.push({ id: migration.id, fromVersion: migration.fromVersion, toVersion: migration.toVersion, deltas });
34
- continue;
35
- }
36
- const deltas = await migration.apply(workingStore);
37
- results.push({ id: migration.id, fromVersion: migration.fromVersion, toVersion: migration.toVersion, deltas });
38
- workingStore = { root: workingStore.root, config: await readConfig(workingStore.root) };
39
- }
40
- return {
41
- exitCode: ExitCode.Ok,
42
- data: {
43
- currentVersion: startingVersion,
44
- targetVersion: SUPPORTED_SCHEMA_VERSION,
45
- applied: !flags.dryRun,
46
- migrations: results,
47
- },
48
- findings: [],
49
- humanSummary: flags.dryRun
50
- ? `--dry-run: ${results.reduce((n, r) => n + r.deltas.length, 0)} change(s) would be made across ${results.length} migration(s).`
51
- : `Applied ${results.length} migration(s), now at schema_version ${workingStore.config.schema_version}.`,
52
- storeRoot: store.root,
53
- schemaVersion: flags.dryRun ? store.config.schema_version : workingStore.config.schema_version,
54
- };
55
- }
56
- //# sourceMappingURL=migrate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- import type { Migration } from './types.js';
2
- /**
3
- * vendor-explanation-craft-skill: the shipped vendored set grew a second craft
4
- * skill, and `init` writes the RESOLVED list into `contexture.yaml` while
5
- * `reconcileStore` never rewrites configuration. So a change to the shipped
6
- * default reaches new stores only; without this migration every store already
7
- * on disk would keep a one-entry list and silently never receive the skill the
8
- * publish skill now tells it to load.
9
- *
10
- * The uncomfortable part, stated rather than implied: `config/schema.ts` says
11
- * the schema version bumps "only on a genuinely incompatible change, never on
12
- * an additive one," and adding a skill is additive. This bumps it anyway, which
13
- * means every existing store reports as needing `ctxr migrate` because a skill
14
- * was added. That was the accepted price of guaranteed propagation — the
15
- * alternatives were leaving the shipped default a lie for every store predating
16
- * it, or an update-time nag that would never stop firing in a store that
17
- * deliberately opted out. Do not read this as license to bump the version for
18
- * the next additive change; weigh that one on its own.
19
- *
20
- * Pending-ness is the recorded schema version, never the list's contents — the
21
- * rule 0002, 0004, 0005, and 0006 all follow, because the config schema fills
22
- * `skills.vendored` from the shipped default when the key is absent, so an
23
- * unmigrated store already reads as though it declared the new set.
24
- */
25
- export declare const addExplanationCraftSkillMigration: Migration;
26
- //# sourceMappingURL=add-explanation-craft-skill.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"add-explanation-craft-skill.d.ts","sourceRoot":"","sources":["../../../src/core/migrations/add-explanation-craft-skill.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,YAAY,CAAC;AA6C5D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,iCAAiC,EAAE,SA8B/C,CAAC"}
@@ -1,94 +0,0 @@
1
- import path from 'node:path';
2
- import { DEFAULT_VENDORED_SKILLS } from '../../config/defaults.js';
3
- import { readConfig } from '../../config/load.js';
4
- import { renderStoreConfig } from '../../config/render.js';
5
- import { writeFileAtomic } from '../fs/atomic.js';
6
- /**
7
- * The shipped set as it stood before this change — a fixed historical literal,
8
- * never derived from `DEFAULT_VENDORED_SKILLS`. Deriving it would make the
9
- * "was this list ever customized?" test drift every time the shipped set grows
10
- * again, silently re-adding to lists a later operator had curated.
11
- */
12
- const PREVIOUS_SHIPPED_SET = ['frontend-design'];
13
- const SCHEMA_VERSION = 7;
14
- function configDelta(next) {
15
- return {
16
- path: 'contexture.yaml',
17
- description: `set skills.vendored to [${next.join(', ')}] and schema_version to ${SCHEMA_VERSION}`,
18
- };
19
- }
20
- function versionOnlyDelta() {
21
- return {
22
- path: 'contexture.yaml',
23
- description: `set schema_version to ${SCHEMA_VERSION}, leaving this store's own skills.vendored list untouched`,
24
- };
25
- }
26
- /**
27
- * The list to write, or undefined when this store's is not ours to rewrite.
28
- *
29
- * The heuristic 0004 and 0006 both used: a list still sitting exactly on the
30
- * previous shipped default was never curated, so growing it matches what the
31
- * operator already accepted. A list that was reordered, added to, or emptied to
32
- * opt out is a decision, and re-adding to it would overwrite that decision —
33
- * such a store gets the version bump alone.
34
- */
35
- function nextVendoredList(current) {
36
- const unchanged = current.length === PREVIOUS_SHIPPED_SET.length && current.every((name, i) => name === PREVIOUS_SHIPPED_SET[i]);
37
- if (!unchanged)
38
- return undefined;
39
- const shipped = [...DEFAULT_VENDORED_SKILLS];
40
- const added = shipped.filter((name) => !current.includes(name));
41
- return added.length > 0 ? shipped : undefined;
42
- }
43
- /**
44
- * vendor-explanation-craft-skill: the shipped vendored set grew a second craft
45
- * skill, and `init` writes the RESOLVED list into `contexture.yaml` while
46
- * `reconcileStore` never rewrites configuration. So a change to the shipped
47
- * default reaches new stores only; without this migration every store already
48
- * on disk would keep a one-entry list and silently never receive the skill the
49
- * publish skill now tells it to load.
50
- *
51
- * The uncomfortable part, stated rather than implied: `config/schema.ts` says
52
- * the schema version bumps "only on a genuinely incompatible change, never on
53
- * an additive one," and adding a skill is additive. This bumps it anyway, which
54
- * means every existing store reports as needing `ctxr migrate` because a skill
55
- * was added. That was the accepted price of guaranteed propagation — the
56
- * alternatives were leaving the shipped default a lie for every store predating
57
- * it, or an update-time nag that would never stop firing in a store that
58
- * deliberately opted out. Do not read this as license to bump the version for
59
- * the next additive change; weigh that one on its own.
60
- *
61
- * Pending-ness is the recorded schema version, never the list's contents — the
62
- * rule 0002, 0004, 0005, and 0006 all follow, because the config schema fills
63
- * `skills.vendored` from the shipped default when the key is absent, so an
64
- * unmigrated store already reads as though it declared the new set.
65
- */
66
- export const addExplanationCraftSkillMigration = {
67
- id: '0007-add-explanation-craft-skill',
68
- fromVersion: 6,
69
- toVersion: SCHEMA_VERSION,
70
- description: `Add the explanation craft skill to a store whose skills.vendored list still sits at the previous shipped default, and bump schema_version to ${SCHEMA_VERSION}.`,
71
- async plan(store) {
72
- if (store.config.schema_version >= SCHEMA_VERSION)
73
- return [];
74
- const next = nextVendoredList(store.config.skills.vendored);
75
- return [next ? configDelta(next) : versionOnlyDelta()];
76
- },
77
- async apply(store) {
78
- if (store.config.schema_version >= SCHEMA_VERSION)
79
- return [];
80
- // Re-read from disk rather than trusting the store snapshot: an interrupted
81
- // run may have written the config already, and resumability means deciding
82
- // from current state.
83
- const currentConfig = await readConfig(store.root);
84
- const next = nextVendoredList(currentConfig.skills.vendored);
85
- const nextConfig = {
86
- ...currentConfig,
87
- schema_version: SCHEMA_VERSION,
88
- skills: { ...currentConfig.skills, vendored: next ?? currentConfig.skills.vendored },
89
- };
90
- await writeFileAtomic(path.join(store.root, 'contexture.yaml'), renderStoreConfig(nextConfig));
91
- return [next ? configDelta(next) : versionOnlyDelta()];
92
- },
93
- };
94
- //# sourceMappingURL=add-explanation-craft-skill.js.map