ctxr-cli 0.11.0 → 0.12.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.
- package/README.md +3 -1
- package/dist/core/note-templates.d.ts +27 -20
- package/dist/core/note-templates.d.ts.map +1 -1
- package/dist/core/note-templates.js +47 -65
- package/dist/core/note-templates.js.map +1 -1
- package/dist/core/reconcile.d.ts.map +1 -1
- package/dist/core/reconcile.js +5 -4
- package/dist/core/reconcile.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/templates/agents/canonical.md +1 -1
- package/templates/skills/ctxr-session-lifecycle.md +10 -0
- package/templates/skills/ctxr-submit.md +27 -2
- package/templates/skills/ctxr-upgrade.md +2 -1
package/README.md
CHANGED
|
@@ -20,6 +20,8 @@ Requires Node 22.13 or newer.
|
|
|
20
20
|
|
|
21
21
|
The package is `ctxr-cli`, the command it installs is `ctxr`, and the project is Contexture — which is why a store’s own files keep the full name (`contexture.yaml`, `.contexture/`, `CONTEXTURE_*`). A `contexture` alias executable is installed too; docs and generated files always say `ctxr`.
|
|
22
22
|
|
|
23
|
+
Running an agent harness in a container? [contexture-images](https://github.com/ayxuerui/contexture-images) publishes harness runtimes with `ctxr` already installed — currently `ghcr.io/ayxuerui/contexture-hermes`, tagged by the `ctxr` version it carries. Nothing here depends on it; `ctxr` itself is distributed only through npm.
|
|
24
|
+
|
|
23
25
|
## Quickstart
|
|
24
26
|
|
|
25
27
|
```sh
|
|
@@ -234,7 +236,7 @@ ctxr catalog check --stale
|
|
|
234
236
|
ctxr archive <path>
|
|
235
237
|
```
|
|
236
238
|
|
|
237
|
-
A new note starts from a template under `templates.path` (`.contexture/templates/` by default), never from a blank file and never by copying whichever sibling is nearest — that's how a store's notes drift out of any shape at all. `templates.installed` says which of the packaged library a store wants, defaulting to all of it and meaning "install none" when empty, exactly like `skills.vendored`; your own kinds sit in the same directory and are never touched, since contexture only
|
|
239
|
+
A new note starts from a template under `templates.path` (`.contexture/templates/` by default), never from a blank file and never by copying whichever sibling is nearest — that's how a store's notes drift out of any shape at all. `templates.installed` says which of the packaged library a store wants, defaulting to all of it and meaning "install none" when empty, exactly like `skills.vendored`; your own kinds sit in the same directory and are never touched, since contexture only owns the names it packages. A shipped template is contexture's: edit one and `ctxr update` puts it back. A house variant lives under a name the packaged set doesn't use, which nothing touches. A template is fixed content — the same bytes in every store — so the idea template carries the four relation sections literally, each with a note on what belongs under it, plus a `## Source` section for the prose account of where an idea came from (distinct from the `sources:` frontmatter `ctxr ingest` writes). `{{title}}` and `{{date}}` are the whole placeholder vocabulary; the agent substitutes them as it writes, no command expands them, and `ctxr lint` reports a note that landed with one still in it. An existing note is extended in place, never re-cut from a template.
|
|
238
240
|
|
|
239
241
|
The `lint` / `doctor` split is the point: lint reports what's *worth reviewing* and never blocks; doctor reports what's *broken* and does. `ctxr archive` retires a note as a single tracked rename into `organize.archive_destination`, leaving its frontmatter byte-identical and reporting every note that linked to it — move it, don't tag it, or the active layers stop meaning anything. (The note must be committed first; archive won't rename something git isn't tracking.)
|
|
240
242
|
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import type { StoreConfig } from '../config/schema.js';
|
|
2
2
|
import type { Finding } from './envelope.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* The note templates a store starts a note from.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `skills.ts` — a record with a content hash, not a marker in the file.
|
|
6
|
+
* A template is FIXED content — the same bytes in every store, no substitution —
|
|
7
|
+
* so this module delivers files rather than rendering them. That was a
|
|
8
|
+
* deliberate narrowing: making a template follow a per-store vocabulary bought
|
|
9
|
+
* synchronisation between two things only one of which needed to exist.
|
|
11
10
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
11
|
+
* Ownership follows the NAME, and the record is a list of the names contexture
|
|
12
|
+
* delivered. It cannot be a marker inside the file: a template's bytes are
|
|
13
|
+
* copied into a note, so an "Owned by contexture" comment would appear at the
|
|
14
|
+
* top of every note the store ever writes. This module stays separate from
|
|
15
|
+
* `skills.ts` for that reason — a vendored skill's contract looks alike and is
|
|
16
|
+
* the opposite, preserving an operator's edit because contexture may not modify
|
|
17
|
+
* a file it did not author. It authored every one of these.
|
|
17
18
|
*/
|
|
18
19
|
/** The record naming what contexture delivered, sibling to the templates it names. */
|
|
19
20
|
export declare const TEMPLATES_RECORD_FILE_NAME = ".ctxr-templates.json";
|
|
@@ -26,8 +27,14 @@ export declare const TEMPLATES_RECORD_FILE_NAME = ".ctxr-templates.json";
|
|
|
26
27
|
*/
|
|
27
28
|
export declare const NOTE_TEMPLATE_PLACEHOLDERS: readonly ['{{title}}', '{{date}}'];
|
|
28
29
|
export interface NoteTemplateRecord {
|
|
29
|
-
/**
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* The template names contexture delivered. Not hashes: ownership follows the
|
|
32
|
+
* packaged library's names, and byte-stability is decided by comparing a file
|
|
33
|
+
* to the bytes it should have. The record's only job is remembering that a
|
|
34
|
+
* name was contexture's, so a template the library later drops can still be
|
|
35
|
+
* removed — nothing else remembers that.
|
|
36
|
+
*/
|
|
37
|
+
templates: string[];
|
|
31
38
|
ctxrVersion?: string;
|
|
32
39
|
}
|
|
33
40
|
/**
|
|
@@ -45,14 +52,14 @@ export declare function renderNoteTemplate(name: string, _config: StoreConfig):
|
|
|
45
52
|
export declare function packagedTemplateNames(): string[];
|
|
46
53
|
/**
|
|
47
54
|
* Brings every note template a store declares (`config.templates.installed`) to
|
|
48
|
-
* the packaged version
|
|
49
|
-
* installed template the store no longer wants.
|
|
55
|
+
* the packaged version, and removes one it no longer declares.
|
|
50
56
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* removed
|
|
57
|
+
* own-the-shipped-templates: ownership follows the NAME. A name the packaged
|
|
58
|
+
* library uses is contexture's and is rewritten unconditionally — a shipped
|
|
59
|
+
* template is a starting shape, not content, so an edit to one is a divergence
|
|
60
|
+
* rather than operator work to preserve. Every other name at the path is the
|
|
61
|
+
* store's own kind and is never read, rewritten, or removed; that is where a
|
|
62
|
+
* house variant belongs.
|
|
56
63
|
*/
|
|
57
64
|
export declare function syncNoteTemplates(root: string, config: StoreConfig, ctxrVersion: string): Promise<{
|
|
58
65
|
changed: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note-templates.d.ts","sourceRoot":"","sources":["../../src/core/note-templates.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"note-templates.d.ts","sourceRoot":"","sources":["../../src/core/note-templates.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAI7C;;;;;;;;;;;;;;;GAeG;AAEH,sFAAsF;AACtF,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AAEjE;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,YAAI,WAAW,EAAE,UAAU,CAAU,CAAC;AAE7E,MAAM,WAAW,kBAAkB;IACjC;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAUD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,MAAM,CAE7E;AAED,mFAAmF;AACnF,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AA6BD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAwCrD"}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
1
|
import { mkdir, readFile, readdir, rm } from 'node:fs/promises';
|
|
3
2
|
import path from 'node:path';
|
|
4
3
|
import { DEFAULT_INSTALLED_TEMPLATES } from '../config/defaults.js';
|
|
5
4
|
import { writeFileAtomic } from './fs/atomic.js';
|
|
6
5
|
import { packagedTemplate } from './templates.js';
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
7
|
+
* The note templates a store starts a note from.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* `skills.ts` — a record with a content hash, not a marker in the file.
|
|
9
|
+
* A template is FIXED content — the same bytes in every store, no substitution —
|
|
10
|
+
* so this module delivers files rather than rendering them. That was a
|
|
11
|
+
* deliberate narrowing: making a template follow a per-store vocabulary bought
|
|
12
|
+
* synchronisation between two things only one of which needed to exist.
|
|
15
13
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
14
|
+
* Ownership follows the NAME, and the record is a list of the names contexture
|
|
15
|
+
* delivered. It cannot be a marker inside the file: a template's bytes are
|
|
16
|
+
* copied into a note, so an "Owned by contexture" comment would appear at the
|
|
17
|
+
* top of every note the store ever writes. This module stays separate from
|
|
18
|
+
* `skills.ts` for that reason — a vendored skill's contract looks alike and is
|
|
19
|
+
* the opposite, preserving an operator's edit because contexture may not modify
|
|
20
|
+
* a file it did not author. It authored every one of these.
|
|
21
21
|
*/
|
|
22
22
|
/** The record naming what contexture delivered, sibling to the templates it names. */
|
|
23
23
|
export const TEMPLATES_RECORD_FILE_NAME = '.ctxr-templates.json';
|
|
@@ -29,9 +29,6 @@ export const TEMPLATES_RECORD_FILE_NAME = '.ctxr-templates.json';
|
|
|
29
29
|
* still in it.
|
|
30
30
|
*/
|
|
31
31
|
export const NOTE_TEMPLATE_PLACEHOLDERS = ['{{title}}', '{{date}}'];
|
|
32
|
-
function sha256(text) {
|
|
33
|
-
return createHash('sha256').update(text, 'utf8').digest('hex');
|
|
34
|
-
}
|
|
35
32
|
async function readIfExists(absolutePath) {
|
|
36
33
|
try {
|
|
37
34
|
return await readFile(absolutePath, 'utf8');
|
|
@@ -70,7 +67,15 @@ async function readRecord(templatesDir) {
|
|
|
70
67
|
return undefined;
|
|
71
68
|
try {
|
|
72
69
|
const parsed = JSON.parse(raw);
|
|
73
|
-
|
|
70
|
+
// own-the-shipped-templates: the previous shape was `{name: hash}`. Read the
|
|
71
|
+
// names out of either form so a store converges on its next update with
|
|
72
|
+
// nothing to run.
|
|
73
|
+
const names = Array.isArray(parsed.templates)
|
|
74
|
+
? parsed.templates.filter((n) => typeof n === 'string')
|
|
75
|
+
: parsed.templates && typeof parsed.templates === 'object'
|
|
76
|
+
? Object.keys(parsed.templates)
|
|
77
|
+
: undefined;
|
|
78
|
+
return names === undefined ? undefined : { templates: names, ctxrVersion: parsed.ctxrVersion };
|
|
74
79
|
}
|
|
75
80
|
catch {
|
|
76
81
|
return undefined;
|
|
@@ -78,77 +83,54 @@ async function readRecord(templatesDir) {
|
|
|
78
83
|
}
|
|
79
84
|
/**
|
|
80
85
|
* Brings every note template a store declares (`config.templates.installed`) to
|
|
81
|
-
* the packaged version
|
|
82
|
-
* installed template the store no longer wants.
|
|
86
|
+
* the packaged version, and removes one it no longer declares.
|
|
83
87
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* removed
|
|
88
|
+
* own-the-shipped-templates: ownership follows the NAME. A name the packaged
|
|
89
|
+
* library uses is contexture's and is rewritten unconditionally — a shipped
|
|
90
|
+
* template is a starting shape, not content, so an edit to one is a divergence
|
|
91
|
+
* rather than operator work to preserve. Every other name at the path is the
|
|
92
|
+
* store's own kind and is never read, rewritten, or removed; that is where a
|
|
93
|
+
* house variant belongs.
|
|
89
94
|
*/
|
|
90
95
|
export async function syncNoteTemplates(root, config, ctxrVersion) {
|
|
91
96
|
const changed = [];
|
|
92
|
-
const findings = [];
|
|
93
97
|
const templatesDir = path.join(root, config.templates.path);
|
|
94
98
|
const packaged = new Set(PACKAGED_TEMPLATE_NAMES);
|
|
95
99
|
const wanted = config.templates.installed.filter((name) => packaged.has(name));
|
|
96
|
-
const previous = (await readRecord(templatesDir))?.templates ??
|
|
97
|
-
const
|
|
100
|
+
const previous = (await readRecord(templatesDir))?.templates ?? [];
|
|
101
|
+
const delivered = [];
|
|
98
102
|
function relative(name) {
|
|
99
103
|
return path.join(config.templates.path, `${name}.md`).split(path.sep).join('/');
|
|
100
104
|
}
|
|
101
105
|
for (const name of wanted) {
|
|
102
106
|
const target = path.join(templatesDir, `${name}.md`);
|
|
103
|
-
const onDisk = await readIfExists(target);
|
|
104
|
-
const recorded = previous[name];
|
|
105
|
-
if (onDisk !== undefined && recorded === undefined) {
|
|
106
|
-
// The record never named it, so it is the store's own file at a packaged
|
|
107
|
-
// name. Leave it alone rather than claiming it.
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (onDisk !== undefined && recorded !== undefined && sha256(onDisk) !== recorded) {
|
|
111
|
-
findings.push({
|
|
112
|
-
code: 'templates.locally_modified',
|
|
113
|
-
severity: 'warning',
|
|
114
|
-
message: `"${relative(name)}" has been modified locally — left unchanged rather than refreshed.`,
|
|
115
|
-
subject: name,
|
|
116
|
-
});
|
|
117
|
-
next[name] = recorded;
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
107
|
const rendered = renderNoteTemplate(name, config);
|
|
121
|
-
|
|
122
|
-
|
|
108
|
+
delivered.push(name);
|
|
109
|
+
// Unconditional: a local edit is a divergence from the shape every store
|
|
110
|
+
// shares, not operator work to preserve. Comparing the bytes is what keeps a
|
|
111
|
+
// second update from writing anything.
|
|
112
|
+
if ((await readIfExists(target)) === rendered)
|
|
123
113
|
continue;
|
|
124
114
|
await mkdir(templatesDir, { recursive: true });
|
|
125
115
|
await writeFileAtomic(target, rendered);
|
|
126
116
|
changed.push(relative(name));
|
|
127
117
|
}
|
|
128
|
-
// A
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
118
|
+
// A name the record remembers that the store no longer declares, or that the
|
|
119
|
+
// library no longer carries. Removed whether or not it was edited: an edited
|
|
120
|
+
// copy of a retired template is a file at a contexture-shaped name that
|
|
121
|
+
// contexture no longer explains.
|
|
122
|
+
const keep = new Set(delivered);
|
|
123
|
+
for (const name of previous) {
|
|
124
|
+
if (keep.has(name))
|
|
132
125
|
continue;
|
|
133
126
|
const target = path.join(templatesDir, `${name}.md`);
|
|
134
|
-
|
|
135
|
-
if (onDisk === undefined)
|
|
136
|
-
continue;
|
|
137
|
-
if (sha256(onDisk) !== recorded) {
|
|
138
|
-
findings.push({
|
|
139
|
-
code: 'templates.locally_modified',
|
|
140
|
-
severity: 'warning',
|
|
141
|
-
message: `"${relative(name)}" is no longer installed but has been modified locally — left on disk rather than removed.`,
|
|
142
|
-
subject: name,
|
|
143
|
-
});
|
|
144
|
-
next[name] = recorded;
|
|
127
|
+
if ((await readIfExists(target)) === undefined)
|
|
145
128
|
continue;
|
|
146
|
-
}
|
|
147
129
|
await rm(target, { force: true });
|
|
148
130
|
changed.push(relative(name));
|
|
149
131
|
}
|
|
150
|
-
await writeRecord(templatesDir, config,
|
|
151
|
-
return { changed, findings };
|
|
132
|
+
await writeRecord(templatesDir, config, delivered, ctxrVersion, changed);
|
|
133
|
+
return { changed, findings: [] };
|
|
152
134
|
}
|
|
153
135
|
/**
|
|
154
136
|
* Byte-stable: the record is rewritten only when its content changes, so a
|
|
@@ -158,9 +140,9 @@ export async function syncNoteTemplates(root, config, ctxrVersion) {
|
|
|
158
140
|
*/
|
|
159
141
|
async function writeRecord(templatesDir, config, templates, ctxrVersion, changed) {
|
|
160
142
|
const recordPath = path.join(templatesDir, TEMPLATES_RECORD_FILE_NAME);
|
|
161
|
-
const sorted =
|
|
143
|
+
const sorted = [...templates].sort((a, b) => a.localeCompare(b));
|
|
162
144
|
const existing = await readIfExists(recordPath);
|
|
163
|
-
if (
|
|
145
|
+
if (sorted.length === 0) {
|
|
164
146
|
if (existing !== undefined) {
|
|
165
147
|
await rm(recordPath, { force: true });
|
|
166
148
|
changed.push(path.join(config.templates.path, TEMPLATES_RECORD_FILE_NAME).split(path.sep).join('/'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"note-templates.js","sourceRoot":"","sources":["../../src/core/note-templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"note-templates.js","sourceRoot":"","sources":["../../src/core/note-templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAS7C,eAAO,MAAM,yBAAyB,8BAA4B,CAAC;AAwBnE,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAS7C,eAAO,MAAM,yBAAyB,8BAA4B,CAAC;AAwBnE,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAsE7G"}
|
package/dist/core/reconcile.js
CHANGED
|
@@ -55,10 +55,11 @@ export async function reconcileStore(env, root, config) {
|
|
|
55
55
|
const vendoredResult = await syncVendoredSkills(root, config, CLI_VERSION);
|
|
56
56
|
changed.push(...vendoredResult.changed);
|
|
57
57
|
const findings = [...vendoredResult.findings];
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
58
|
+
// own-the-shipped-templates: the note templates a store declares, delivered
|
|
59
|
+
// as fixed content and rewritten unconditionally — unlike a vendored skill,
|
|
60
|
+
// contexture authored these, so an edit is a divergence rather than operator
|
|
61
|
+
// work. The findings array stays in the signature because the sync is a
|
|
62
|
+
// sibling of the two above and a future check may use it; it is empty today.
|
|
62
63
|
const templatesResult = await syncNoteTemplates(root, config, CLI_VERSION);
|
|
63
64
|
changed.push(...templatesResult.changed);
|
|
64
65
|
findings.push(...templatesResult.findings);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,sCAAsC,EAAE,MAAM,uBAAuB,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACzH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,gCAAgC,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,yCAAyC,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;AASxF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAY,EAAE,MAAmB;IACjF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,YAAoB,EAAE,SAAkB,EAAQ,EAAE;QAC9D,IAAI,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,uBAAuB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3H,IAAI,CACF,YAAY,EACZ,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,yBAAyB,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CACpH,CAAC;IAEF,0EAA0E;IAC1E,2EAA2E;IAC3E,uEAAuE;IACvE,gEAAgE;IAChE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3E,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAc,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzD,4EAA4E;IAC5E,
|
|
1
|
+
{"version":3,"file":"reconcile.js","sourceRoot":"","sources":["../../src/core/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,sCAAsC,EAAE,MAAM,uBAAuB,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EACL,YAAY,EACZ,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACzH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,gCAAgC,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,yCAAyC,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;AASxF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW,EAAE,IAAY,EAAE,MAAmB;IACjF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,CAAC,YAAoB,EAAE,SAAkB,EAAQ,EAAE;QAC9D,IAAI,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,uBAAuB,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3H,IAAI,CACF,YAAY,EACZ,CAAC,MAAM,wBAAwB,CAAC,aAAa,EAAE,yBAAyB,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CACpH,CAAC;IAEF,0EAA0E;IAC1E,2EAA2E;IAC3E,uEAAuE;IACvE,gEAAgE;IAChE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3E,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAc,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzD,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,wEAAwE;IACxE,6EAA6E;IAC7E,MAAM,eAAe,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3E,OAAO,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE3C,qEAAqE;IACrE,gEAAgE;IAChE,uEAAuE;IACvE,uCAAuC;IACvC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAE9E,wEAAwE;IACxE,+EAA+E;IAC/E,kFAAkF;IAClF,IAAI,CACF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,sCAAsC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACzG,CAAC,MAAM,yBAAyB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CACxD,CAAC;IAEF,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI;QAClB,4BAA4B;QAC5B,yBAAyB;QACzB,2BAA2B;QAC3B,2BAA2B;QAC3B,yBAAyB;QACzB,6BAA6B;KAC9B,EAAE,CAAC;QACF,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO;YAAE,aAAa,GAAG,IAAI,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,MAAM,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,gCAAgC,CAAC,CAAC,CAAC,OAAO;QAAE,aAAa,GAAG,IAAI,CAAC;IAC3H,IAAI,CAAC,MAAM,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,yCAAyC,CAAC,CAAC,CAAC,OAAO;QAAE,aAAa,GAAG,IAAI,CAAC;IACpI,yEAAyE;IACzE,yEAAyE;IACzE,yEAAyE;IACzE,8EAA8E;IAC9E,IAAI,CAAC,MAAM,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC,OAAO;QAAE,aAAa,GAAG,IAAI,CAAC;IAClH,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAEjC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACnF,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IAC3B,MAAM,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAExC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;AACtD,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Kept in sync with package.json's "version" field. */
|
|
2
|
-
export declare const CLI_VERSION = "0.
|
|
2
|
+
export declare const CLI_VERSION = "0.12.0";
|
|
3
3
|
/**
|
|
4
4
|
* The npm package this executable is published as. Bound here, beside the
|
|
5
5
|
* version, because the release check resolves the latest published release by
|
package/dist/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Kept in sync with package.json's "version" field. */
|
|
2
|
-
export const CLI_VERSION = '0.
|
|
2
|
+
export const CLI_VERSION = '0.12.0';
|
|
3
3
|
/**
|
|
4
4
|
* The npm package this executable is published as. Bound here, beside the
|
|
5
5
|
* version, because the release check resolves the latest published release by
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@ A new note starts from a template under `__TEMPLATES_PATH__`, not from a blank f
|
|
|
14
14
|
|
|
15
15
|
### Write path
|
|
16
16
|
|
|
17
|
-
Every write to this store happens inside a session worktree, never directly on the default branch: `ctxr session start` creates one,
|
|
17
|
+
Every write to this store happens inside a session worktree, never directly on the default branch: `ctxr session start` creates one, and the work stays there for as long as the session runs. When the operator asks to wrap up, `ctxr-submit` validates with `ctxr doctor`, commits, pushes, and opens (or reports how to open) a pull request — that request is what triggers it, not having finished a piece of work. Do not edit files in the store root directly.
|
|
18
18
|
|
|
19
19
|
### Identity and memory
|
|
20
20
|
|
|
@@ -29,6 +29,16 @@ deferring is a normal answer, and the session is unaffected by it. A `cli.update
|
|
|
29
29
|
means the check could not be completed; it says nothing about whether an upgrade is due, so proceed
|
|
30
30
|
without mentioning it.
|
|
31
31
|
|
|
32
|
+
## Between turns
|
|
33
|
+
|
|
34
|
+
A session is not a turn. The worktree persists across as many exchanges as the work takes, and ending a
|
|
35
|
+
turn with uncommitted changes on the branch is the session's normal resting state — not an obligation to
|
|
36
|
+
discharge before replying. Say in one line what is uncommitted and which worktree holds it, then stop.
|
|
37
|
+
|
|
38
|
+
Nothing about a finished piece of work ends the session. `ctxr-submit` is what ends it, and it waits to
|
|
39
|
+
be asked — see its own entry condition. An agent that treats delivering the thing it was asked for as the
|
|
40
|
+
signal to wrap up will submit into the middle of a conversation that had more coming.
|
|
41
|
+
|
|
32
42
|
## Re-scan before any plan
|
|
33
43
|
|
|
34
44
|
Re-scan whenever state may have moved under you — before presenting a plan, before running `ctxr-submit`,
|
|
@@ -2,6 +2,29 @@ The submit half of the session lifecycle — everything up to and including open
|
|
|
2
2
|
`ctxr-land` is the other half, after review; `ctxr-session-lifecycle` covers what surrounds both (starting
|
|
3
3
|
a session, the conflict playbook, sequencing several pull requests) and is not repeated here.
|
|
4
4
|
|
|
5
|
+
## When
|
|
6
|
+
|
|
7
|
+
Fires on an explicit request to wrap up — "submit", "open the PR", "push it", "ship it" — or on the
|
|
8
|
+
operator's own closing utterance ("done", "that's all", a sign-off). That request is the whole reason step 8
|
|
9
|
+
needs no further confirmation: it is the consent for the push and the pull-request open. Enter without
|
|
10
|
+
one and there is nothing behind those steps.
|
|
11
|
+
|
|
12
|
+
Anti-triggers — do not enter this skill when: you have merely finished the task you were given (a
|
|
13
|
+
delivered piece of work is not a closing signal, and the next message is as likely to extend it as to
|
|
14
|
+
end it); a question, an error, or a requested follow-up is still outstanding; the operator's last message
|
|
15
|
+
asked for more work. Your own judgment that the work looks complete is never the signal, and neither is
|
|
16
|
+
your own summary saying so.
|
|
17
|
+
|
|
18
|
+
Two tells that you are here uninvited. Reaching for `ctxr doctor`, `ctxr lint`, or `ctxr catalog check`
|
|
19
|
+
to decide *whether* to submit — those live at step 5 and after, inside a submit already asked for, and
|
|
20
|
+
running them ahead of one is a rehearsal, not a check. And composing a question like "shall I open the
|
|
21
|
+
pull request?" — needing to ask is itself the answer: leave, and let the work continue.
|
|
22
|
+
|
|
23
|
+
Ending a turn without that signal is normal and is not this skill. Say in one line what is uncommitted
|
|
24
|
+
and which worktree holds it, then stop. The work is safe on the branch and the next message picks it up.
|
|
25
|
+
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
5
28
|
1. Re-scan (mandatory — never replay a plan from an earlier snapshot): `git fetch origin`,
|
|
6
29
|
`git status --short`, `git diff --stat`, `git diff --cached --stat`,
|
|
7
30
|
`git ls-files --others --exclude-standard`, `git log --oneline origin/__DEFAULT_BRANCH__..HEAD`. State moves
|
|
@@ -26,5 +49,7 @@ a session, the conflict playbook, sequencing several pull requests) and is not r
|
|
|
26
49
|
9. Verify before any retry: a transport error can arrive AFTER the push or the pull-request open already
|
|
27
50
|
succeeded. Before retrying anything, `git ls-remote origin <branch>` and `gh pr list --head <branch>` —
|
|
28
51
|
never replay a push or a pull-request open blindly.
|
|
29
|
-
10. Hand off: report the pull request
|
|
30
|
-
|
|
52
|
+
10. Hand off: report the pull request's number and its url, and name what landing it takes —
|
|
53
|
+
`ctxr-land`, targeting that number — so the next step is one word away instead of something to
|
|
54
|
+
reconstruct later. Landing stays a separate decision and keeps its own explicit confirmation; never
|
|
55
|
+
run it from here.
|
|
@@ -37,7 +37,8 @@ step 3 gates on the operator rather than proceeding from the fact that a newer r
|
|
|
37
37
|
|
|
38
38
|
6. Land the re-render as its own pull request. `ctxr update` produces generated-file churn — AGENTS.md
|
|
39
39
|
sections, skill copies, hooks, adapter outputs — and mixing it into unrelated work makes both
|
|
40
|
-
harder to review.
|
|
40
|
+
harder to review. Submit it with `ctxr-submit` when the re-render is ready to go out; landing it is a
|
|
41
|
+
separate decision afterwards, and `ctxr-land` keeps its own confirmation.
|
|
41
42
|
|
|
42
43
|
If step 4 or 5 fails, say which step and what the command reported. A partial upgrade — new executable,
|
|
43
44
|
un-re-rendered store — is a real state worth naming: the store still works, and step 5 can be re-run on
|