@rness/cli 0.15.1 → 0.16.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 +32 -11
- package/dist/bin/rness.js +1 -1
- package/dist/{chunk-7IVHL744.js → chunk-ABCO6D6B.js} +69 -26
- package/dist/chunk-ABCO6D6B.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7IVHL744.js.map +0 -1
package/README.md
CHANGED
|
@@ -119,9 +119,10 @@ the files a given agent needs, for the agents the team declares in
|
|
|
119
119
|
A new document takes the collection's first status (`Proposed` for an
|
|
120
120
|
ADR, `Draft` otherwise) and the next number of the local checkout; two
|
|
121
121
|
branches can pick the same one. Each skill records its session: it adds
|
|
122
|
-
|
|
123
|
-
writes or closes
|
|
124
|
-
|
|
122
|
+
`{ id: <session id>, agent: <model> }` to `sessions:` in the front matter
|
|
123
|
+
of what it writes or closes. The agent is the model it runs as, as Claude
|
|
124
|
+
Code names it (`Claude Opus 5.5`): no variable gives it to a skill. An
|
|
125
|
+
edit made without a skill leaves none. No skill commits.
|
|
125
126
|
- rness owns values, not files: what is missing is added, nothing else is
|
|
126
127
|
touched, and a file it cannot parse is reported, never rewritten.
|
|
127
128
|
`sync --check` and `validate` report a missing value. Removing an agent
|
|
@@ -234,17 +235,22 @@ in its Settings`.
|
|
|
234
235
|
collection fields' options: every contract status plus the ones found in
|
|
235
236
|
`.rness/`, in lifecycle order, at most 50), `Collection` (one option per tab of
|
|
236
237
|
`rness status`; not `Type`, which is GitHub's own issue-type field and
|
|
237
|
-
filter), `Agent` (`working`), `
|
|
238
|
-
agent type for a subagent
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
238
|
+
filter), `Agent` (`working`), `Working session` (`claude · 1a2b3c4d`,
|
|
239
|
+
plus the agent type for a subagent: the session working on the document
|
|
240
|
+
now, cleared when it ends), `Path`, and `Session history` — the
|
|
241
|
+
document's `sessions:` (see "Agent targets"), each `Claude Opus 5.5 ·
|
|
242
|
+
<id>` (the id alone for an entry without its agent), joined by `, `,
|
|
243
|
+
written by sync and never cleared: which sessions wrote a specification
|
|
244
|
+
or implemented a plan, after they ended (`claude --resume <id>` reopens
|
|
245
|
+
one on the machine it ran on). A board made before 0.15.0 gains
|
|
246
|
+
`Session history` at its next sync; one from 0.15 has its `Session` and
|
|
247
|
+
`Sessions` renamed in place, values and views kept (`renamed field
|
|
248
|
+
Session → Working session`). A board per directory, named as
|
|
243
249
|
`rness status` names its tab, filtered on its `Collection`, its columns
|
|
244
250
|
that collection's own steps: each collection has its own status field
|
|
245
251
|
(`ADR status`, `Specs status`, …; a directory without statuses is columned
|
|
246
252
|
by `Status`, which holds them all for the `All` table). `pulse sync`
|
|
247
|
-
remakes a board built by an earlier version (its URL changes once); a `Working` table, filtered on `Agent: working`. A first view named `View 1` (GitHub's default) becomes `All` when no `All` exists, on create and on sync, showing Title, Collection, Status and
|
|
253
|
+
remakes a board built by an earlier version (its URL changes once); a `Working` table, filtered on `Agent: working`. A first view named `View 1` (GitHub's default) becomes `All` when no `All` exists, on create and on sync, showing Title, Collection, Status and Working session. Options are coloured (statuses by lifecycle: blue proposed, purple approved, yellow in progress, red blocked or rejected, yellow superseded, green done, gray abandoned; collections and `working` too); a sync recolours rness's options and leaves other options' colours alone. rness does
|
|
248
254
|
not set the project's visibility: the project gets GitHub's default for a
|
|
249
255
|
new organization project, which is private (`public: false`). Verified
|
|
250
256
|
with Claude Code 2.1.284 on 2026-09-29.
|
|
@@ -352,7 +358,7 @@ repository, the board).
|
|
|
352
358
|
`contract`, `provider`, `org`, `agents`, `pulse`, `repos`, `scopes`.
|
|
353
359
|
- A provider _written_ in `rness.json` that this version cannot talk to
|
|
354
360
|
(`gitlab`) is refused by `validate`, `create`, `login` and `pulse`:
|
|
355
|
-
`provider "gitlab" is not supported by @rness/cli 0.
|
|
361
|
+
`provider "gitlab" is not supported by @rness/cli 0.16.0 (supported:
|
|
356
362
|
github)`. `add`, `sync` and the local commands never refuse. `null` is not a
|
|
357
363
|
value: an absent key means none.
|
|
358
364
|
|
|
@@ -529,6 +535,21 @@ per repository, the files to commit there.
|
|
|
529
535
|
Exit codes: 0 success, 1 failure, 2 usage — or a refusal without a TTY.
|
|
530
536
|
`RNESS_DEBUG=1` adds stack traces; `RNESS_NO_DELEGATE=1` skips the delegation.
|
|
531
537
|
|
|
538
|
+
## 0.16.0 — Working session and Session history; the agent in the history
|
|
539
|
+
|
|
540
|
+
- Agent Pulse's session fields are renamed so that the names say what
|
|
541
|
+
they hold: `Session` becomes `Working session` (the session working on
|
|
542
|
+
a document now) and `Sessions` becomes `Session history` (every session
|
|
543
|
+
that changed it). The first `pulse sync` with 0.16.0 renames them in
|
|
544
|
+
place: values, ids and views stay. Until then, marks use whichever name
|
|
545
|
+
the board has. See "Pulse".
|
|
546
|
+
- `Session history` names each session's agent: `Claude Opus 5.5 ·
|
|
547
|
+
1e9cb41b-…`. The lifecycle skills now record `{ id, agent }` in
|
|
548
|
+
`sessions:`; a bare id, as 0.15 wrote it, still reads, and shows alone.
|
|
549
|
+
`rness upgrade` rewrites the four skills: commit `.claude/skills/rness/`
|
|
550
|
+
in each repository. See "Agent targets".
|
|
551
|
+
- Blocks are unchanged.
|
|
552
|
+
|
|
532
553
|
## 0.15.1 — upgrade names every file to commit
|
|
533
554
|
|
|
534
555
|
- `rness upgrade`'s next steps name every file the new version's sync
|
package/dist/bin/rness.js
CHANGED
|
@@ -486,7 +486,7 @@ function parseRepoSpec(spec, org, host) {
|
|
|
486
486
|
}
|
|
487
487
|
|
|
488
488
|
// src/version.ts
|
|
489
|
-
var VERSION = "0.
|
|
489
|
+
var VERSION = "0.16.0";
|
|
490
490
|
|
|
491
491
|
// src/core/pm.ts
|
|
492
492
|
import { execFile as execFile2 } from "child_process";
|
|
@@ -1073,10 +1073,17 @@ function statusOf(item) {
|
|
|
1073
1073
|
function sessionsOf(item) {
|
|
1074
1074
|
const listed = item.fields?.["sessions"];
|
|
1075
1075
|
if (!Array.isArray(listed)) return [];
|
|
1076
|
-
const
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1076
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1077
|
+
for (const entry of listed) {
|
|
1078
|
+
const fields2 = typeof entry === "string" ? { id: entry } : entry !== null && typeof entry === "object" ? entry : {};
|
|
1079
|
+
const { id, agent } = fields2;
|
|
1080
|
+
if (typeof id !== "string" || id === "" || entries.has(id)) continue;
|
|
1081
|
+
entries.set(
|
|
1082
|
+
id,
|
|
1083
|
+
typeof agent === "string" && agent !== "" ? { id, agent } : { id }
|
|
1084
|
+
);
|
|
1085
|
+
}
|
|
1086
|
+
return [...entries.values()];
|
|
1080
1087
|
}
|
|
1081
1088
|
function rowOf(dir, item) {
|
|
1082
1089
|
const base = posix3.basename(item.rel, ".md");
|
|
@@ -1410,7 +1417,7 @@ function desiredOf(tabs, org) {
|
|
|
1410
1417
|
status: statusOf2(row.status),
|
|
1411
1418
|
type: tab.label,
|
|
1412
1419
|
statusField: fields2.get(tab.label)?.name ?? null,
|
|
1413
|
-
sessions: row.sessions?.join(", ") ?? null
|
|
1420
|
+
sessions: row.sessions?.map((e) => e.agent === void 0 ? e.id : `${e.agent} \xB7 ${e.id}`).join(", ") ?? null
|
|
1414
1421
|
}))
|
|
1415
1422
|
);
|
|
1416
1423
|
}
|
|
@@ -1991,6 +1998,18 @@ async function setOptions(field, options, o) {
|
|
|
1991
1998
|
);
|
|
1992
1999
|
return toField(d.updateProjectV2Field.projectV2Field);
|
|
1993
2000
|
}
|
|
2001
|
+
async function renameField(fieldId, name, o) {
|
|
2002
|
+
const d = await graphql(
|
|
2003
|
+
`mutation($fieldId: ID!, $name: String!) {
|
|
2004
|
+
updateProjectV2Field(input: { fieldId: $fieldId, name: $name }) {
|
|
2005
|
+
projectV2Field { ${FIELD_SELECTION} }
|
|
2006
|
+
}
|
|
2007
|
+
}`,
|
|
2008
|
+
{ fieldId, name },
|
|
2009
|
+
o
|
|
2010
|
+
);
|
|
2011
|
+
return toField(d.updateProjectV2Field.projectV2Field);
|
|
2012
|
+
}
|
|
1994
2013
|
async function listItems(projectId, o, { bodies = true } = {}) {
|
|
1995
2014
|
const items = [];
|
|
1996
2015
|
let cursor = null;
|
|
@@ -2490,6 +2509,13 @@ var WORKING = "working";
|
|
|
2490
2509
|
var WORKING_VIEW = "Working";
|
|
2491
2510
|
var MEMORY = ".rness";
|
|
2492
2511
|
var LABEL = "rness";
|
|
2512
|
+
var WORKING_SESSION = "Working session";
|
|
2513
|
+
var SESSION_HISTORY = "Session history";
|
|
2514
|
+
var FORMERLY = {
|
|
2515
|
+
[WORKING_SESSION]: "Session",
|
|
2516
|
+
[SESSION_HISTORY]: "Sessions"
|
|
2517
|
+
};
|
|
2518
|
+
var valueOf = (values2, name) => values2[name] ?? values2[FORMERLY[name] ?? ""] ?? null;
|
|
2493
2519
|
var LABEL_COLOR = "5319e7";
|
|
2494
2520
|
var LABEL_DESCRIPTION = "A document of .rness, on Agent Pulse";
|
|
2495
2521
|
var labelled = (labels) => labels.some((l) => l.toLowerCase() === LABEL.toLowerCase());
|
|
@@ -2624,6 +2650,11 @@ var GitHubBoards = class {
|
|
|
2624
2650
|
const text = async (name) => {
|
|
2625
2651
|
const field = fields2.find((f) => f.name === name);
|
|
2626
2652
|
if (field !== void 0) return field;
|
|
2653
|
+
const was = fields2.find((f) => f.name === FORMERLY[name]);
|
|
2654
|
+
if (was !== void 0) {
|
|
2655
|
+
added.push(`renamed field ${was.name} \u2192 ${name}`);
|
|
2656
|
+
return renameField(was.id, name, this.#o);
|
|
2657
|
+
}
|
|
2627
2658
|
added.push(`field ${name}`);
|
|
2628
2659
|
return createField(cache.projectId, name, "TEXT", this.#o);
|
|
2629
2660
|
};
|
|
@@ -2644,9 +2675,9 @@ var GitHubBoards = class {
|
|
|
2644
2675
|
for (const f of layout.fields)
|
|
2645
2676
|
own.set(f.name, await single(f.name, "Status", f.statuses, true));
|
|
2646
2677
|
const agent = await single("Agent", "Agent", [WORKING]);
|
|
2647
|
-
const session = await text(
|
|
2678
|
+
const session = await text(WORKING_SESSION);
|
|
2648
2679
|
const path = await text("Path");
|
|
2649
|
-
const sessions = await text(
|
|
2680
|
+
const sessions = await text(SESSION_HISTORY);
|
|
2650
2681
|
const current = await views(cache.projectId, this.#o);
|
|
2651
2682
|
const first = current[0];
|
|
2652
2683
|
if (first !== void 0 && first.name === DEFAULT_VIEW && !current.some((v) => v.name === ALL_VIEW)) {
|
|
@@ -2748,14 +2779,15 @@ var GitHubBoards = class {
|
|
|
2748
2779
|
collectionStatus: r.values[statusFieldName(r.values[COLLECTION_FIELD] ?? "")] ?? null,
|
|
2749
2780
|
type: r.values[COLLECTION_FIELD] ?? null,
|
|
2750
2781
|
agent: r.values["Agent"] ?? null,
|
|
2751
|
-
session: r.values
|
|
2752
|
-
sessions: r.values
|
|
2782
|
+
session: valueOf(r.values, WORKING_SESSION),
|
|
2783
|
+
sessions: valueOf(r.values, SESSION_HISTORY)
|
|
2753
2784
|
};
|
|
2754
2785
|
});
|
|
2755
2786
|
}
|
|
2756
2787
|
async #set(board, itemId, name, value) {
|
|
2757
2788
|
const cache = await this.#cacheOf(board);
|
|
2758
|
-
const
|
|
2789
|
+
const fields2 = await this.#fields(board);
|
|
2790
|
+
const field = fields2.find((f) => f.name === name) ?? fields2.find((f) => f.name === FORMERLY[name]);
|
|
2759
2791
|
if (field === void 0) throw new Error(`the board has no field ${name}`);
|
|
2760
2792
|
let sent = null;
|
|
2761
2793
|
if (value !== null && field.options === null) sent = { text: value };
|
|
@@ -2768,8 +2800,8 @@ var GitHubBoards = class {
|
|
|
2768
2800
|
await setValue(cache.projectId, itemId, field.id, sent, this.#o);
|
|
2769
2801
|
const known = cache.known.get(itemId);
|
|
2770
2802
|
if (known === void 0) return;
|
|
2771
|
-
if (value === null) delete known.values[name];
|
|
2772
|
-
else known.values[name] = value;
|
|
2803
|
+
if (value === null) delete known.values[field.name];
|
|
2804
|
+
else known.values[field.name] = value;
|
|
2773
2805
|
}
|
|
2774
2806
|
async apply(board, step2) {
|
|
2775
2807
|
if (step2.kind === "unchanged") return null;
|
|
@@ -2903,10 +2935,10 @@ var GitHubBoards = class {
|
|
|
2903
2935
|
[COLLECTION_FIELD, want.type],
|
|
2904
2936
|
[STATUS_FIELD, want.status],
|
|
2905
2937
|
...want.statusField === null ? [] : [[want.statusField, want.status]],
|
|
2906
|
-
[
|
|
2938
|
+
[SESSION_HISTORY, want.sessions]
|
|
2907
2939
|
];
|
|
2908
2940
|
for (const [name, value] of wanted)
|
|
2909
|
-
if ((values2
|
|
2941
|
+
if (valueOf(values2, name) !== value)
|
|
2910
2942
|
await this.#set(board, id, name, value);
|
|
2911
2943
|
}
|
|
2912
2944
|
async #known(board, id) {
|
|
@@ -2932,7 +2964,7 @@ var GitHubBoards = class {
|
|
|
2932
2964
|
async mark(board, itemIds, session) {
|
|
2933
2965
|
for (const id of itemIds) {
|
|
2934
2966
|
await this.#set(board, id, "Agent", session === null ? null : WORKING);
|
|
2935
|
-
await this.#set(board, id,
|
|
2967
|
+
await this.#set(board, id, WORKING_SESSION, session);
|
|
2936
2968
|
}
|
|
2937
2969
|
}
|
|
2938
2970
|
};
|
|
@@ -3681,8 +3713,10 @@ Writing:
|
|
|
3681
3713
|
\`org/\` it affects.
|
|
3682
3714
|
- An ADR it replaces is named in Context. That one becomes \`Superseded\`,
|
|
3683
3715
|
with \`superseded_by:\`, only once the new ADR is \`Accepted\`.
|
|
3684
|
-
- Add
|
|
3685
|
-
unless
|
|
3716
|
+
- Add \`{ id: \${CLAUDE_SESSION_ID}, agent: <model> }\` at the end of
|
|
3717
|
+
\`sessions:\` in the front matter, unless that id is already there.
|
|
3718
|
+
\`<model>\` is the model you run as, as Claude Code names it, after
|
|
3719
|
+
\`Claude\`: for example \`Claude Opus 5.5\`.
|
|
3686
3720
|
- The rness hook checks every edit under \`${rness}/\`: fix what it reports.
|
|
3687
3721
|
|
|
3688
3722
|
After writing: give the path and the Decision section, and say the ADR
|
|
@@ -3720,8 +3754,10 @@ Writing:
|
|
|
3720
3754
|
- What was checked in this session (a document read, a command run) is
|
|
3721
3755
|
written as verified, with the date; everything else as a proposal or an
|
|
3722
3756
|
open question.
|
|
3723
|
-
- Add
|
|
3724
|
-
unless
|
|
3757
|
+
- Add \`{ id: \${CLAUDE_SESSION_ID}, agent: <model> }\` at the end of
|
|
3758
|
+
\`sessions:\` in the front matter, unless that id is already there.
|
|
3759
|
+
\`<model>\` is the model you run as, as Claude Code names it, after
|
|
3760
|
+
\`Claude\`: for example \`Claude Opus 5.5\`.
|
|
3725
3761
|
- The rness hook checks every edit under \`${rness}/\`: fix what it reports.
|
|
3726
3762
|
|
|
3727
3763
|
After writing: give the path and the summary. It stays \`Draft\` until the
|
|
@@ -3762,8 +3798,10 @@ Writing:
|
|
|
3762
3798
|
repository has one.
|
|
3763
3799
|
- Where the plan decides something the specification leaves open, a
|
|
3764
3800
|
section says so.
|
|
3765
|
-
- Add
|
|
3766
|
-
unless
|
|
3801
|
+
- Add \`{ id: \${CLAUDE_SESSION_ID}, agent: <model> }\` at the end of
|
|
3802
|
+
\`sessions:\` in the front matter, unless that id is already there.
|
|
3803
|
+
\`<model>\` is the model you run as, as Claude Code names it, after
|
|
3804
|
+
\`Claude\`: for example \`Claude Opus 5.5\`.
|
|
3767
3805
|
- The rness hook checks every edit under \`${rness}/\`: fix what it reports.
|
|
3768
3806
|
|
|
3769
3807
|
After writing: give the path and the list of tasks. It becomes \`Ready\` when
|
|
@@ -3793,8 +3831,11 @@ Arguments: \`$ARGUMENTS\`.
|
|
|
3793
3831
|
ran, what it showed, what could not run and why;
|
|
3794
3832
|
- the specification: \`Implemented\` once every plan of it is
|
|
3795
3833
|
\`Completed\`; \`updated\` today;
|
|
3796
|
-
- the plan and the specification: add
|
|
3797
|
-
|
|
3834
|
+
- the plan and the specification: add
|
|
3835
|
+
\`{ id: \${CLAUDE_SESSION_ID}, agent: <model> }\` at the end of
|
|
3836
|
+
\`sessions:\` in their front matter, unless that id is already there;
|
|
3837
|
+
\`<model>\` is the model you run as, as Claude Code names it, after
|
|
3838
|
+
\`Claude\`: for example \`Claude Opus 5.5\`;
|
|
3798
3839
|
- the smallest set of documents the work makes inaccurate: \`${rness}/docs/\`,
|
|
3799
3840
|
the READMEs of the repositories it changed.
|
|
3800
3841
|
6. A task not proven: the plan stays \`In progress\` \u2014 or \`Blocked\`, the
|
|
@@ -7931,7 +7972,9 @@ async function declaredBoard(c) {
|
|
|
7931
7972
|
}
|
|
7932
7973
|
var plural = (n) => `${n} item${n === 1 ? "" : "s"}`;
|
|
7933
7974
|
var eachAdded = (ui, added) => {
|
|
7934
|
-
for (const a of added)
|
|
7975
|
+
for (const a of added)
|
|
7976
|
+
if (a.startsWith("renamed ")) ui.line("renamed", a.slice("renamed ".length));
|
|
7977
|
+
else ui.line("added", a);
|
|
7935
7978
|
};
|
|
7936
7979
|
var createdByKind = (ui, added) => {
|
|
7937
7980
|
for (const kind of ["field", "option", "view"]) {
|
|
@@ -8723,4 +8766,4 @@ export {
|
|
|
8723
8766
|
OWN_COMMANDS,
|
|
8724
8767
|
catchUp
|
|
8725
8768
|
};
|
|
8726
|
-
//# sourceMappingURL=chunk-
|
|
8769
|
+
//# sourceMappingURL=chunk-ABCO6D6B.js.map
|