@rness/cli 0.20.0 → 0.21.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/dist/index.js CHANGED
@@ -1,68 +1,72 @@
1
1
  import {
2
2
  BEGIN,
3
3
  BLOCK_SIZE_WARNING,
4
- COLLECTIONS,
5
- DEFAULT_HOST,
6
4
  END,
7
5
  GITHUB_HOSTS,
6
+ SCAFFOLD_FILES,
7
+ addCommand,
8
+ blockHash,
9
+ bodyOf,
10
+ catchUp,
11
+ checkBlocks,
12
+ contextCommand,
13
+ copyScaffold,
14
+ createCommand,
15
+ defaultTransport,
16
+ detectGithubSsh,
17
+ ensureClaudeMd,
18
+ findBlock,
19
+ logoutCommand,
20
+ mergeBlock,
21
+ parseHeader,
22
+ renderBlock,
23
+ renderMarkdown,
24
+ run,
25
+ scaffoldDir,
26
+ syncCommand,
27
+ upgradeCommand,
28
+ validateCommand
29
+ } from "./chunk-T5PINUCP.js";
30
+ import {
31
+ BoardRefused,
32
+ COLLECTIONS,
33
+ DEFAULT_HOST,
8
34
  GitHubOAuthProvider,
9
35
  NAME,
10
36
  NAME_RULE,
11
37
  ORG_NAME,
12
38
  PACKAGE_MANAGERS,
13
- SCAFFOLD_FILES,
14
39
  SSH_HOST,
15
40
  STATUSES,
16
41
  VERSION,
17
- addCommand,
18
42
  addRepository,
19
43
  assembleContext,
20
- blockHash,
21
- bodyOf,
22
- catchUp,
23
- checkBlocks,
24
44
  checkContract,
25
45
  classifyProbe,
26
46
  collectMarkdown,
27
- contextCommand,
28
- copyScaffold,
29
- createCommand,
30
47
  defaultTerminal,
31
- defaultTransport,
32
- detectGithubSsh,
33
48
  detectPackageManager,
34
- ensureClaudeMd,
35
49
  exists,
36
50
  extractTitle,
37
- findBlock,
38
51
  findWorkspace,
39
52
  githubProvider,
40
53
  installDependencies,
41
54
  isPackageManager,
42
55
  loadManifest,
43
56
  loginCommand,
44
- logoutCommand,
45
- mergeBlock,
46
57
  packageManagerVersion,
58
+ parseBoard,
47
59
  parseFrontMatter,
48
- parseHeader,
49
60
  parseRepoSpec,
50
61
  probeRemote,
51
62
  readOrNull,
52
- renderBlock,
53
- renderMarkdown,
54
63
  repoUrl,
55
64
  resolveScope,
56
- run,
57
- scaffoldDir,
58
65
  scopeChain,
59
- syncCommand,
60
- upgradeCommand,
61
- validateCommand,
62
66
  workspaceDirs,
63
67
  writeFileAtomic,
64
68
  writeManifest
65
- } from "./chunk-WIZHU4WT.js";
69
+ } from "./chunk-D3D2WCGW.js";
66
70
 
67
71
  // src/index.ts
68
72
  async function run2(argv) {
@@ -71,6 +75,7 @@ async function run2(argv) {
71
75
  export {
72
76
  BEGIN,
73
77
  BLOCK_SIZE_WARNING,
78
+ BoardRefused,
74
79
  COLLECTIONS,
75
80
  DEFAULT_HOST,
76
81
  END,
@@ -113,6 +118,7 @@ export {
113
118
  logoutCommand,
114
119
  mergeBlock,
115
120
  packageManagerVersion,
121
+ parseBoard,
116
122
  parseFrontMatter,
117
123
  parseHeader,
118
124
  parseRepoSpec,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { run as runCli } from './cli.ts'\nimport { catchUp } from './core/catch-up.ts'\n\n/**\n * What a launcher calls when it delegates to this copy. A launcher older than\n * 0.5.1 knows nothing about a pin that moved, so the check runs here as well\n * (spec 0008 §4); a launcher that already looked says so, and this is a no-op.\n */\nexport async function run(argv: string[]): Promise<number> {\n return (await catchUp(argv)) ?? runCli(argv)\n}\n\nexport { VERSION } from './version.ts'\nexport {\n contextCommand,\n renderMarkdown,\n type ContextOptions,\n} from './commands/context.ts'\nexport { validateCommand, type ValidateOptions } from './commands/validate.ts'\nexport { addCommand, type AddOptions } from './commands/add.ts'\nexport {\n createCommand,\n type CreateDeps,\n type CreateOptions,\n type Prompts,\n} from './commands/create.ts'\nexport { parseFrontMatter, extractTitle } from './core/frontmatter.ts'\nexport { collectMarkdown } from './core/collect.ts'\nexport {\n loadManifest,\n NAME,\n NAME_RULE,\n ORG_NAME,\n parseRepoSpec,\n writeManifest,\n} from './core/manifest.ts'\nexport { findWorkspace } from './core/workspace.ts'\nexport { resolveScope, scopeChain } from './core/scope.ts'\nexport {\n assembleContext,\n COLLECTIONS,\n type AssembleInput,\n} from './core/context.ts'\nexport { checkContract, STATUSES } from './core/contract.ts'\nexport { scaffoldDir, SCAFFOLD_FILES } from './core/scaffold.ts'\nexport type * from './core/types.ts'\nexport { syncCommand, type SyncOptions } from './commands/sync.ts'\nexport { loginCommand, type LoginOptions } from './commands/login.ts'\nexport { logoutCommand } from './commands/logout.ts'\nexport type { CommandDeps } from './core/deps.ts'\nexport type {\n GitCredentials,\n GitProvider,\n Provider,\n Organization,\n OrganizationAccess,\n} from './core/provider.ts'\nexport {\n GitHubOAuthProvider,\n githubProvider,\n} from './core/github-oauth-provider.ts'\nexport { upgradeCommand, type UpgradeOptions } from './commands/upgrade.ts'\nexport { defaultTerminal, type Terminal } from './core/terminal.ts'\nexport {\n renderBlock,\n blockHash,\n parseHeader,\n bodyOf,\n BEGIN,\n END,\n BLOCK_SIZE_WARNING,\n type BlockInput,\n type RenderedBlock,\n type BlockHeader,\n} from './core/block.ts'\nexport {\n mergeBlock,\n findBlock,\n ensureClaudeMd,\n type MergeResult,\n type FindResult,\n} from './core/merge.ts'\nexport { exists, readOrNull, writeFileAtomic } from './core/fs.ts'\nexport {\n checkBlocks,\n type CheckBlocksInput,\n type CheckBlocksResult,\n} from './core/blocks.ts'\nexport {\n addRepository,\n workspaceDirs,\n type AddRepositoryInput,\n type AddRepositoryResult,\n} from './core/repos.ts'\nexport { copyScaffold, type ScaffoldTokens } from './core/scaffold-copy.ts'\nexport {\n detectPackageManager,\n isPackageManager,\n packageManagerVersion,\n installDependencies,\n PACKAGE_MANAGERS,\n type PackageManager,\n} from './core/pm.ts'\nexport {\n repoUrl,\n probeRemote,\n classifyProbe,\n DEFAULT_HOST,\n SSH_HOST,\n type Probe,\n} from './core/remote.ts'\nexport {\n detectGithubSsh,\n defaultTransport,\n GITHUB_HOSTS,\n type DetectSsh,\n type Hosts,\n type SshAccess,\n type Transport,\n} from './core/transport.ts'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,eAAsBA,KAAI,MAAiC;AACzD,SAAQ,MAAM,QAAQ,IAAI,KAAM,IAAO,IAAI;AAC7C;","names":["run"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { run as runCli } from './cli.ts'\nimport { catchUp } from './core/catch-up.ts'\n\n/**\n * What a launcher calls when it delegates to this copy. A launcher older than\n * 0.5.1 knows nothing about a pin that moved, so the check runs here as well\n * (spec 0008 §4); a launcher that already looked says so, and this is a no-op.\n */\nexport async function run(argv: string[]): Promise<number> {\n return (await catchUp(argv)) ?? runCli(argv)\n}\n\nexport { VERSION } from './version.ts'\nexport {\n contextCommand,\n renderMarkdown,\n type ContextOptions,\n} from './commands/context.ts'\nexport { validateCommand, type ValidateOptions } from './commands/validate.ts'\nexport { addCommand, type AddOptions } from './commands/add.ts'\nexport {\n createCommand,\n type CreateDeps,\n type CreateOptions,\n type Prompts,\n} from './commands/create.ts'\nexport { parseFrontMatter, extractTitle } from './core/frontmatter.ts'\nexport { collectMarkdown } from './core/collect.ts'\nexport {\n loadManifest,\n NAME,\n NAME_RULE,\n ORG_NAME,\n parseRepoSpec,\n writeManifest,\n} from './core/manifest.ts'\nexport { findWorkspace } from './core/workspace.ts'\nexport { resolveScope, scopeChain } from './core/scope.ts'\nexport {\n assembleContext,\n COLLECTIONS,\n type AssembleInput,\n} from './core/context.ts'\nexport { checkContract, STATUSES } from './core/contract.ts'\nexport { scaffoldDir, SCAFFOLD_FILES } from './core/scaffold.ts'\nexport type * from './core/types.ts'\nexport type * from './core/board-declaration.ts'\nexport { parseBoard, BoardRefused } from './core/board-declaration.ts'\nexport { syncCommand, type SyncOptions } from './commands/sync.ts'\nexport { loginCommand, type LoginOptions } from './commands/login.ts'\nexport { logoutCommand } from './commands/logout.ts'\nexport type { CommandDeps } from './core/deps.ts'\nexport type {\n GitCredentials,\n GitProvider,\n Provider,\n Organization,\n OrganizationAccess,\n} from './core/provider.ts'\nexport {\n GitHubOAuthProvider,\n githubProvider,\n} from './core/github-oauth-provider.ts'\nexport { upgradeCommand, type UpgradeOptions } from './commands/upgrade.ts'\nexport { defaultTerminal, type Terminal } from './core/terminal.ts'\nexport {\n renderBlock,\n blockHash,\n parseHeader,\n bodyOf,\n BEGIN,\n END,\n BLOCK_SIZE_WARNING,\n type BlockInput,\n type RenderedBlock,\n type BlockHeader,\n} from './core/block.ts'\nexport {\n mergeBlock,\n findBlock,\n ensureClaudeMd,\n type MergeResult,\n type FindResult,\n} from './core/merge.ts'\nexport { exists, readOrNull, writeFileAtomic } from './core/fs.ts'\nexport {\n checkBlocks,\n type CheckBlocksInput,\n type CheckBlocksResult,\n} from './core/blocks.ts'\nexport {\n addRepository,\n workspaceDirs,\n type AddRepositoryInput,\n type AddRepositoryResult,\n} from './core/repos.ts'\nexport { copyScaffold, type ScaffoldTokens } from './core/scaffold-copy.ts'\nexport {\n detectPackageManager,\n isPackageManager,\n packageManagerVersion,\n installDependencies,\n PACKAGE_MANAGERS,\n type PackageManager,\n} from './core/pm.ts'\nexport {\n repoUrl,\n probeRemote,\n classifyProbe,\n DEFAULT_HOST,\n SSH_HOST,\n type Probe,\n} from './core/remote.ts'\nexport {\n detectGithubSsh,\n defaultTransport,\n GITHUB_HOSTS,\n type DetectSsh,\n type Hosts,\n type SshAccess,\n type Transport,\n} from './core/transport.ts'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,eAAsBA,KAAI,MAAiC;AACzD,SAAQ,MAAM,QAAQ,IAAI,KAAM,IAAO,IAAI;AAC7C;","names":["run"]}
@@ -0,0 +1,22 @@
1
+ import {
2
+ KINDS,
3
+ NoteRefused,
4
+ githubRepo,
5
+ journalOf,
6
+ planIssue,
7
+ postNote,
8
+ pulseNoteCommand,
9
+ sessionFrom
10
+ } from "./chunk-4BM4FUWO.js";
11
+ import "./chunk-D3D2WCGW.js";
12
+ export {
13
+ KINDS,
14
+ NoteRefused,
15
+ githubRepo,
16
+ journalOf,
17
+ planIssue,
18
+ postNote,
19
+ pulseNoteCommand,
20
+ sessionFrom
21
+ };
22
+ //# sourceMappingURL=note-RBG7OXVI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,91 @@
1
+ import {
2
+ githubRepo,
3
+ journalOf,
4
+ planIssue
5
+ } from "./chunk-4BM4FUWO.js";
6
+ import {
7
+ branchOf,
8
+ commitsBetween,
9
+ forgetNotes,
10
+ forgetStart,
11
+ fromGithub,
12
+ issuesNoted,
13
+ plansInProgress,
14
+ startOf
15
+ } from "./chunk-D3D2WCGW.js";
16
+
17
+ // src/pulse/summary.ts
18
+ import { resolve } from "path";
19
+ var SHOWN = 10;
20
+ function commitsLine(commits) {
21
+ if (commits.length === 0) return "no commit";
22
+ const named = commits.slice(0, SHOWN).map((s) => `\`${s}\``).join(", ");
23
+ const more = commits.length > SHOWN ? ", \u2026" : "";
24
+ return `${commits.length} commit${commits.length === 1 ? "" : "s"} (${named}${more})`;
25
+ }
26
+ async function onePlan(input, repo) {
27
+ const { c } = input;
28
+ const plans = await plansInProgress(
29
+ { root: c.root, rnessDir: c.rnessDir },
30
+ c.manifest,
31
+ input.scope
32
+ );
33
+ const plan = plans.length === 1 ? plans[0] : void 0;
34
+ if (plan === void 0) return [];
35
+ if (journalOf([input.board])?.journal.to === "repo" && repo !== null) {
36
+ const there = await fromGithub(
37
+ c.provider.journalIssue(repo.owner, repo.name, plan)
38
+ );
39
+ if (there !== null)
40
+ return [
41
+ { id: there.id, reference: `${there.repository}#${there.number}` }
42
+ ];
43
+ }
44
+ const issue = await planIssue(c, input.board, plan);
45
+ return [{ id: issue.id, reference: `${issue.repository}#${issue.number}` }];
46
+ }
47
+ async function postSummary(input) {
48
+ const { c, session } = input;
49
+ const url = input.clone === void 0 ? void 0 : c.manifest.repos[input.clone]?.url;
50
+ const dir = url === void 0 || input.clone === void 0 ? null : resolve(c.root, "org", input.clone);
51
+ try {
52
+ const start = dir === null ? null : await startOf(dir, session);
53
+ const commits = dir === null || start === null ? [] : await commitsBetween(dir, start.head).catch(() => []);
54
+ const found = url === void 0 ? null : githubRepo(url);
55
+ const repo = found !== null && found.owner.toLowerCase() === c.org.toLowerCase() ? found : null;
56
+ const noted = await issuesNoted(c.rnessDir, session);
57
+ const targets = noted.length > 0 ? noted : commits.length > 0 ? await onePlan(input, repo) : [];
58
+ if (targets.length === 0) return [];
59
+ const branch = dir === null ? null : await branchOf(dir);
60
+ const pr = repo === null || branch === null ? null : await fromGithub(
61
+ c.provider.pullRequestFor(repo.owner, repo.name, branch)
62
+ );
63
+ const id = session.split(" \xB7 ").at(-1) ?? session;
64
+ const minutes = start === null ? null : Math.max(1, Math.round((Date.now() - start.at) / 6e4));
65
+ const details = [
66
+ ...branch === null || start === null ? [] : [`Branch \`${branch}\` \xB7 ${commitsLine(commits)}`],
67
+ ...pr === null || repo === null ? [] : [
68
+ `Pull request ${repo.owner}/${repo.name}#${pr.number} (${pr.state.toLowerCase()})`
69
+ ]
70
+ ];
71
+ const body = [
72
+ [
73
+ "**Session summary**",
74
+ session,
75
+ ...minutes === null ? [] : [`${minutes} min`]
76
+ ].join(" \xB7 "),
77
+ "",
78
+ ...details.length === 0 ? [] : [...details, ""],
79
+ `<!-- rness note ${id} summary -->`
80
+ ].join("\n");
81
+ for (const t of targets) await fromGithub(c.provider.comment(t.id, body));
82
+ return targets.map((t) => t.reference);
83
+ } finally {
84
+ if (dir !== null) await forgetStart(dir, session);
85
+ await forgetNotes(c.rnessDir, session);
86
+ }
87
+ }
88
+ export {
89
+ postSummary
90
+ };
91
+ //# sourceMappingURL=summary-UCMFESSA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pulse/summary.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport { type Context, type Declared, fromGithub } from '../commands/pulse.ts'\nimport { branchOf, commitsBetween } from '../core/git.ts'\nimport { plansInProgress } from '../core/status.ts'\nimport {\n type NotedIssue,\n forgetNotes,\n forgetStart,\n issuesNoted,\n startOf,\n} from './journal-state.ts'\nimport { githubRepo, journalOf, planIssue } from './note.ts'\n\n/**\n * The session-end summary (spec 0030 §6): the commits since the session's\n * start on the current branch, the branch's pull request, the duration; on\n * each issue the session's notes went to, else on the one plan in progress\n * of its scope when there is a commit. No note of the limit. Loaded\n * through `import()` only.\n */\n\nexport interface SummaryInput {\n c: Context\n /** The board that declares `journal-summary`, and so `journal`. */\n board: Declared\n session: string\n /** The session's scope; null, the root's. */\n scope: string | null\n /** The clone the session worked in: a name of `repos`. */\n clone?: string\n}\n\n/** The commits a summary names; the rest are counted. */\nconst SHOWN = 10\n\nfunction commitsLine(commits: readonly string[]): string {\n if (commits.length === 0) return 'no commit'\n const named = commits\n .slice(0, SHOWN)\n .map((s) => `\\`${s}\\``)\n .join(', ')\n const more = commits.length > SHOWN ? ', …' : ''\n return `${commits.length} commit${commits.length === 1 ? '' : 's'} (${named}${more})`\n}\n\n/** The issue of the one plan in progress of the scope: its implementation issue in `repo` mode when there is one. */\nasync function onePlan(\n input: SummaryInput,\n repo: { owner: string; name: string } | null\n): Promise<NotedIssue[]> {\n const { c } = input\n const plans = await plansInProgress(\n { root: c.root, rnessDir: c.rnessDir },\n c.manifest,\n input.scope\n )\n const plan = plans.length === 1 ? plans[0] : undefined\n if (plan === undefined) return []\n if (journalOf([input.board])?.journal.to === 'repo' && repo !== null) {\n const there = await fromGithub(\n c.provider.journalIssue(repo.owner, repo.name, plan)\n )\n if (there !== null)\n return [\n { id: there.id, reference: `${there.repository}#${there.number}` },\n ]\n }\n const issue = await planIssue(c, input.board, plan)\n return [{ id: issue.id, reference: `${issue.repository}#${issue.number}` }]\n}\n\n/** Posts the summary; the issues it went to, none when skipped. The session's records are forgotten either way. */\nexport async function postSummary(input: SummaryInput): Promise<string[]> {\n const { c, session } = input\n const url =\n input.clone === undefined ? undefined : c.manifest.repos[input.clone]?.url\n const dir =\n url === undefined || input.clone === undefined\n ? null\n : resolve(c.root, 'org', input.clone)\n try {\n const start = dir === null ? null : await startOf(dir, session)\n const commits =\n dir === null || start === null\n ? []\n : await commitsBetween(dir, start.head).catch(() => [])\n const found = url === undefined ? null : githubRepo(url)\n // A repository of another owner is not the workspace's (spec 0030 §3.4).\n const repo =\n found !== null && found.owner.toLowerCase() === c.org.toLowerCase()\n ? found\n : null\n const noted = await issuesNoted(c.rnessDir, session)\n const targets =\n noted.length > 0\n ? noted\n : commits.length > 0\n ? await onePlan(input, repo)\n : []\n if (targets.length === 0) return []\n\n const branch = dir === null ? null : await branchOf(dir)\n const pr =\n repo === null || branch === null\n ? null\n : await fromGithub(\n c.provider.pullRequestFor(repo.owner, repo.name, branch)\n )\n const id = session.split(' · ').at(-1) ?? session\n const minutes =\n start === null\n ? null\n : Math.max(1, Math.round((Date.now() - start.at) / 60_000))\n const details = [\n ...(branch === null || start === null\n ? []\n : [`Branch \\`${branch}\\` · ${commitsLine(commits)}`]),\n ...(pr === null || repo === null\n ? []\n : [\n `Pull request ${repo.owner}/${repo.name}#${pr.number} (${pr.state.toLowerCase()})`,\n ]),\n ]\n const body = [\n [\n '**Session summary**',\n session,\n ...(minutes === null ? [] : [`${minutes} min`]),\n ].join(' · '),\n '',\n ...(details.length === 0 ? [] : [...details, '']),\n `<!-- rness note ${id} summary -->`,\n ].join('\\n')\n for (const t of targets) await fromGithub(c.provider.comment(t.id, body))\n return targets.map((t) => t.reference)\n } finally {\n if (dir !== null) await forgetStart(dir, session)\n await forgetNotes(c.rnessDir, session)\n }\n}\n"],"mappings":"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","names":[]}
@@ -79,7 +79,7 @@ const openNow = async ($: EngineInterface) =>
79
79
  (await $.state.get(OPEN)).value ?? null
80
80
 
81
81
  /**
82
- * Reads the snapshot from the pinned CLI and keeps it; the status line
82
+ * Reads the snapshot from the pinned CLI and keeps it; the footer's label
83
83
  * follows, and so does the document open in the pane, read again. No
84
84
  * pinned copy, or a run that fails: no snapshot, nothing drawn.
85
85
  */
@@ -89,9 +89,13 @@ async function refresh($: EngineInterface): Promise<RnessSnapshot | null> {
89
89
  const project = projectOf($.plugin.root)
90
90
  const bin = `${project}/${RNESS}/${BIN}`
91
91
  if (await $.fs.exists(bin)) {
92
+ // `RNESS_NO_DELEGATE`: a pin that drifts is reported (a note, in the
93
+ // band), never installed from inside the session, as the settings
94
+ // hooks have it (spec 0015 §3). `status` is not among the commands
95
+ // catch-up spares, and its install would replace a local copy.
92
96
  const ran = await $.process.run(
93
97
  ['node', bin, 'status', '--json', '--cwd', project],
94
- { cwd: project, timeoutMs: 20_000 }
98
+ { cwd: project, timeoutMs: 20_000, env: { RNESS_NO_DELEGATE: '1' } }
95
99
  )
96
100
  if (ran.exitCode === 0) next = JSON.parse(ran.stdout) as RnessSnapshot
97
101
  }
@@ -99,7 +103,6 @@ async function refresh($: EngineInterface): Promise<RnessSnapshot | null> {
99
103
  next = null
100
104
  }
101
105
  await update($, snapshot, () => next)
102
- $.ui.status(next?.statusLine)
103
106
  const opened = await openNow($)
104
107
  if (opened !== null) await show($, opened.path)
105
108
  return next
@@ -252,6 +255,20 @@ export const register: Register = (on) => {
252
255
  )
253
256
  })
254
257
 
258
+ // The workspace's label among the session modes at the right of the
259
+ // prompt footer (plan 0044): `rness · <scope> · <n> in progress`, worded
260
+ // by the CLI, after the engine's own (`focus`). A mode is dim and carries
261
+ // no sign; `$.ui.status` would draw it as a warning. No snapshot: the
262
+ // footer as the engine has it.
263
+ on('ui.render', { component: 'SessionMode' }, async ($, e, next) => {
264
+ const shown = await read($, snapshot)
265
+ if (shown === null) return next(e)
266
+ return next({
267
+ ...e,
268
+ props: { modes: [...e.props.modes, shown.statusLine] },
269
+ })
270
+ })
271
+
255
272
  // `/rness:status` is the skill's name: answered here with the pane, it
256
273
  // runs no model turn; with no snapshot, or no one to see a pane, the
257
274
  // skill's tables answer it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rness/cli",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Configuration-plane CLI for rness workspaces: resolve, validate and sync org-level context for AI coding agents",
5
5
  "license": "MIT",
6
6
  "type": "module",