@rness/cli 0.6.1 → 0.6.2
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 +18 -0
- package/dist/bin/rness.js +1 -1
- package/dist/{chunk-YAIZOFYV.js → chunk-7TOHFPW6.js} +62 -27
- package/dist/chunk-7TOHFPW6.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/scaffold/.github/workflows/validate.yml +2 -2
- package/dist/chunk-YAIZOFYV.js.map +0 -1
package/README.md
CHANGED
|
@@ -147,6 +147,24 @@ its content does.
|
|
|
147
147
|
Exit codes: 0 success, 1 failure, 2 usage — or a refusal without a TTY.
|
|
148
148
|
`RNESS_DEBUG=1` adds stack traces; `RNESS_NO_DELEGATE=1` skips the delegation.
|
|
149
149
|
|
|
150
|
+
## 0.6.2 — no dialog for the root CLAUDE.md
|
|
151
|
+
|
|
152
|
+
- Opening Claude Code in a repository of the workspace no longer asks "Allow
|
|
153
|
+
external CLAUDE.md file imports?". The workspace root `CLAUDE.md` carried
|
|
154
|
+
`@AGENTS.md`; Claude Code loads that file from every repository below it,
|
|
155
|
+
where the import points outside the working directory. `rness sync` now
|
|
156
|
+
writes the global block into the root `CLAUDE.md` itself; a line that is
|
|
157
|
+
exactly `@AGENTS.md` is dropped there, the rest of the file is kept. The
|
|
158
|
+
`CLAUDE.md` of each repository keeps its `@AGENTS.md`.
|
|
159
|
+
- The root files are not in any repository: run `rness sync` once after the
|
|
160
|
+
upgrade, on every machine. The blocks in the repositories are unchanged.
|
|
161
|
+
- `sync --check` and `validate` cover the root `CLAUDE.md`. At the root, a
|
|
162
|
+
symlink between `CLAUDE.md` and `AGENTS.md` is left as it is and the other
|
|
163
|
+
file is still written.
|
|
164
|
+
- The scaffold's `validate.yml` uses `actions/checkout@v7` and
|
|
165
|
+
`actions/setup-node@v7`, as the rness repositories do. A workspace created
|
|
166
|
+
before keeps its own file.
|
|
167
|
+
|
|
150
168
|
## 0.6.1 — hints you can type
|
|
151
169
|
|
|
152
170
|
- Every hint that names a command to run (`not cloned: …`, `run … sync`,
|
package/dist/bin/rness.js
CHANGED
|
@@ -1637,6 +1637,17 @@ function mergeBlock(existing, block) {
|
|
|
1637
1637
|
}
|
|
1638
1638
|
return { ok: true, text, changed: text !== existing };
|
|
1639
1639
|
}
|
|
1640
|
+
var POINTER = "@AGENTS.md";
|
|
1641
|
+
function claudeMdAtRoot(existing, block) {
|
|
1642
|
+
if (existing === null) return mergeBlock(null, block);
|
|
1643
|
+
const lines = existing.split(/\r?\n/);
|
|
1644
|
+
if (!lines.some((l) => l.trim() === POINTER))
|
|
1645
|
+
return mergeBlock(existing, block);
|
|
1646
|
+
const eol = existing.includes("\r\n") ? "\r\n" : "\n";
|
|
1647
|
+
const rest = lines.filter((l) => l.trim() !== POINTER).join(eol);
|
|
1648
|
+
const merged = mergeBlock(rest.trim() === "" ? null : rest, block);
|
|
1649
|
+
return merged.ok ? { ...merged, changed: merged.text !== existing } : merged;
|
|
1650
|
+
}
|
|
1640
1651
|
async function ensureClaudeMd(dir) {
|
|
1641
1652
|
const file = join8(dir, "CLAUDE.md");
|
|
1642
1653
|
if (await isSymlink(file)) return "unchanged";
|
|
@@ -1849,6 +1860,18 @@ function targetsOf(manifest, root, only) {
|
|
|
1849
1860
|
}
|
|
1850
1861
|
return targets;
|
|
1851
1862
|
}
|
|
1863
|
+
async function syncBlockFile(file, block, check, rootClaudeMd = false) {
|
|
1864
|
+
const existing = await readOrNull(file);
|
|
1865
|
+
const existingLines = existing === null ? [] : existing.split(/\r?\n/);
|
|
1866
|
+
const span = findBlock(existingLines);
|
|
1867
|
+
const current = span.kind === "one" && isCurrentBlock(existingLines.slice(span.begin, span.end + 1), block.hash) && !(rootClaudeMd && existingLines.some((l) => l.trim() === "@AGENTS.md"));
|
|
1868
|
+
const merged = current ? { ok: true, text: existing ?? "", changed: false } : rootClaudeMd ? claudeMdAtRoot(existing, block.text) : mergeBlock(existing, block.text);
|
|
1869
|
+
if (!merged.ok) return { error: merged.error };
|
|
1870
|
+
if (!merged.changed) return "unchanged";
|
|
1871
|
+
if (check) return "stale";
|
|
1872
|
+
await writeFileAtomic(file, merged.text);
|
|
1873
|
+
return "updated";
|
|
1874
|
+
}
|
|
1852
1875
|
var SELECT_ALL = "*";
|
|
1853
1876
|
async function askWhatToSync(input) {
|
|
1854
1877
|
if (!input.terminal.isTty()) {
|
|
@@ -2008,10 +2031,11 @@ async function syncCommand(opts, deps = {}) {
|
|
|
2008
2031
|
lines.push(["skipped", `${t.label} (directory not present)`]);
|
|
2009
2032
|
continue;
|
|
2010
2033
|
}
|
|
2011
|
-
const
|
|
2034
|
+
const [agentsLinked, claudeLinked] = await Promise.all(
|
|
2012
2035
|
MANAGED_FILES.map((f) => isSymlink(join9(t.dir, f)))
|
|
2013
2036
|
);
|
|
2014
|
-
|
|
2037
|
+
const atRoot = t.scope === null;
|
|
2038
|
+
if (!atRoot && (agentsLinked === true || claudeLinked === true)) {
|
|
2015
2039
|
lines.push(["skipped", `${t.label} (symlink)`]);
|
|
2016
2040
|
continue;
|
|
2017
2041
|
}
|
|
@@ -2031,32 +2055,32 @@ async function syncCommand(opts, deps = {}) {
|
|
|
2031
2055
|
`${t.label}: block is ${Math.round(block.bytes / 1024)} KB (over 32 KB)`
|
|
2032
2056
|
);
|
|
2033
2057
|
}
|
|
2034
|
-
const
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
const span = findBlock(existingLines);
|
|
2038
|
-
const current = span.kind === "one" && isCurrentBlock(
|
|
2039
|
-
existingLines.slice(span.begin, span.end + 1),
|
|
2040
|
-
block.hash
|
|
2041
|
-
);
|
|
2042
|
-
const merged = current ? { ok: true, text: existing ?? "", changed: false } : mergeBlock(existing, block.text);
|
|
2043
|
-
if (!merged.ok) {
|
|
2044
|
-
problems.push(`${t.label}: ${merged.error}`);
|
|
2058
|
+
const agents = agentsLinked === true ? "skipped" : await syncBlockFile(join9(t.dir, "AGENTS.md"), block, check);
|
|
2059
|
+
if (typeof agents === "object") {
|
|
2060
|
+
problems.push(`${t.label}: ${agents.error}`);
|
|
2045
2061
|
continue;
|
|
2046
2062
|
}
|
|
2047
|
-
|
|
2048
|
-
|
|
2063
|
+
lines.push(
|
|
2064
|
+
agents === "skipped" ? ["skipped", `${t.label} (symlink)`] : [agents, t.label]
|
|
2065
|
+
);
|
|
2066
|
+
if (agents === "stale") differences += 1;
|
|
2067
|
+
if (!atRoot) {
|
|
2049
2068
|
if (!check) await ensureClaudeMd(t.dir);
|
|
2050
2069
|
continue;
|
|
2051
2070
|
}
|
|
2052
|
-
if (
|
|
2053
|
-
|
|
2054
|
-
|
|
2071
|
+
if (claudeLinked === true) continue;
|
|
2072
|
+
const claude = await syncBlockFile(
|
|
2073
|
+
join9(t.dir, "CLAUDE.md"),
|
|
2074
|
+
block,
|
|
2075
|
+
check,
|
|
2076
|
+
true
|
|
2077
|
+
);
|
|
2078
|
+
if (typeof claude === "object") {
|
|
2079
|
+
problems.push(`CLAUDE.md: ${claude.error}`);
|
|
2055
2080
|
continue;
|
|
2056
2081
|
}
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
lines.push(["updated", `${t.label}`]);
|
|
2082
|
+
if (claude === "stale") differences += 1;
|
|
2083
|
+
if (claude !== agents) lines.push([claude, "CLAUDE.md"]);
|
|
2060
2084
|
}
|
|
2061
2085
|
if (check && differences > 0)
|
|
2062
2086
|
problems.push(
|
|
@@ -2301,7 +2325,7 @@ async function contextCommand(opts) {
|
|
|
2301
2325
|
}
|
|
2302
2326
|
|
|
2303
2327
|
// src/version.ts
|
|
2304
|
-
var VERSION = "0.6.
|
|
2328
|
+
var VERSION = "0.6.2";
|
|
2305
2329
|
|
|
2306
2330
|
// src/core/delegate.ts
|
|
2307
2331
|
import { readFile as readFile6 } from "fs/promises";
|
|
@@ -3872,13 +3896,17 @@ async function checkBlocks({
|
|
|
3872
3896
|
checks
|
|
3873
3897
|
});
|
|
3874
3898
|
if (!await exists(join19(root, "org"))) return derive();
|
|
3875
|
-
const targets = [
|
|
3899
|
+
const targets = [
|
|
3900
|
+
{ scope: null, dir: root, depth: 0, file: "AGENTS.md", label: "AGENTS.md" },
|
|
3901
|
+
{ scope: null, dir: root, depth: 0, file: "CLAUDE.md", label: "CLAUDE.md" }
|
|
3902
|
+
];
|
|
3876
3903
|
for (const [name, entry] of Object.entries(manifest.scopes)) {
|
|
3877
3904
|
const segments = entry.path.split("/");
|
|
3878
3905
|
targets.push({
|
|
3879
3906
|
scope: name,
|
|
3880
3907
|
dir: join19(root, ...segments),
|
|
3881
3908
|
depth: segments.length,
|
|
3909
|
+
file: "AGENTS.md",
|
|
3882
3910
|
label: `${entry.path}/AGENTS.md`
|
|
3883
3911
|
});
|
|
3884
3912
|
}
|
|
@@ -3891,7 +3919,7 @@ async function checkBlocks({
|
|
|
3891
3919
|
);
|
|
3892
3920
|
continue;
|
|
3893
3921
|
}
|
|
3894
|
-
const text = await readOrNull(join19(t.dir,
|
|
3922
|
+
const text = await readOrNull(join19(t.dir, t.file));
|
|
3895
3923
|
const lines = text === null ? [] : text.split(/\r?\n/);
|
|
3896
3924
|
const found = findBlock(lines);
|
|
3897
3925
|
if (found.kind === "none") {
|
|
@@ -3917,7 +3945,8 @@ async function checkBlocks({
|
|
|
3917
3945
|
depth: t.depth,
|
|
3918
3946
|
context
|
|
3919
3947
|
});
|
|
3920
|
-
|
|
3948
|
+
const pointerLeft = t.file === "CLAUDE.md" && lines.some((l) => l.trim() === "@AGENTS.md");
|
|
3949
|
+
if (isCurrentBlock(lines.slice(found.begin, found.end + 1), fresh2.hash) && !pointerLeft)
|
|
3921
3950
|
note(t.label, "current");
|
|
3922
3951
|
else
|
|
3923
3952
|
note(
|
|
@@ -4012,7 +4041,13 @@ async function validateCommand(opts, deps = {}) {
|
|
|
4012
4041
|
return 0;
|
|
4013
4042
|
}
|
|
4014
4043
|
ui.intro(`Validate ${org}`);
|
|
4015
|
-
|
|
4044
|
+
const rootStatus = blocks.checks.find(
|
|
4045
|
+
(c) => c.label === "AGENTS.md"
|
|
4046
|
+
)?.status;
|
|
4047
|
+
const shown = blocks.checks.filter(
|
|
4048
|
+
(c) => !(c.label === "CLAUDE.md" && c.status === rootStatus)
|
|
4049
|
+
);
|
|
4050
|
+
for (const c of shown)
|
|
4016
4051
|
if (c.message === null) ui.line("current", c.label);
|
|
4017
4052
|
else if (c.status === "stale" || c.status === "malformed")
|
|
4018
4053
|
ui.error(c.message);
|
|
@@ -4292,4 +4327,4 @@ export {
|
|
|
4292
4327
|
OWN_COMMANDS,
|
|
4293
4328
|
catchUp
|
|
4294
4329
|
};
|
|
4295
|
-
//# sourceMappingURL=chunk-
|
|
4330
|
+
//# sourceMappingURL=chunk-7TOHFPW6.js.map
|