@nodii/dev 0.6.34 → 0.6.35

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/freeze.js CHANGED
@@ -29,9 +29,43 @@ export function shouldReground(argv) {
29
29
 
30
30
  /**
31
31
  * The only Gather → Freeze shape adapter. Gather may add display metadata,
32
- * but Freeze retains the stable clause identity/tags and full text only for ⚑.
32
+ * but Freeze pins only the ⚑ clauses, in full (hub-58): every other clause
33
+ * stays in the Clause map, which the Freeze references.
33
34
  */
34
35
  export function pinnedClausesFromGather(clauses) {
36
+ return checkedGatherClauses(clauses)
37
+ .filter((clause) => clause.counterInstinct)
38
+ .map((clause) => ({
39
+ documentCode: clause.documentCode,
40
+ documentVersion: clause.documentVersion,
41
+ clauseId: clause.clauseId,
42
+ ...(clause.breadcrumb || clause.sectionId
43
+ ? { section: clause.breadcrumb ?? clause.sectionId }
44
+ : {}),
45
+ gist: clause.gist,
46
+ text: clause.text,
47
+ counterInstinct: true,
48
+ repos: clause.repos,
49
+ steps: clause.steps,
50
+ }));
51
+ }
52
+
53
+ /**
54
+ * The Freeze's reference to the Clause map: its Gather id and the non-flagged
55
+ * clauses' one-line gists in rank order (Dev cuts them at the token cap).
56
+ */
57
+ export function clauseMapFromGather(gather) {
58
+ if (typeof gather?.gatherId !== "string" || !gather.gatherId)
59
+ throw new CliError("GATHER_CLAUSE_MAP_INVALID", "Gather returned no gather id", 1);
60
+ const clauses = checkedGatherClauses(gather.clauses)
61
+ .map((clause, index) => ({ clause, index }))
62
+ .filter(({ clause }) => !clause.counterInstinct)
63
+ .sort((a, b) => (a.clause.rank ?? Infinity) - (b.clause.rank ?? Infinity) || a.index - b.index)
64
+ .map(({ clause }) => ({ clauseId: clause.clauseId, gist: clause.gist }));
65
+ return { gatherId: gather.gatherId, clauses };
66
+ }
67
+
68
+ function checkedGatherClauses(clauses) {
35
69
  if (!Array.isArray(clauses))
36
70
  throw new CliError("GATHER_CLAUSE_MAP_INVALID", "Gather returned no clause map", 1);
37
71
  return clauses.map((clause) => {
@@ -66,25 +100,13 @@ export function pinnedClausesFromGather(clauses) {
66
100
  ].join(", ")}`,
67
101
  1,
68
102
  );
69
- return {
70
- documentCode: clause.documentCode,
71
- documentVersion: clause.documentVersion,
72
- clauseId: clause.clauseId,
73
- ...(clause.breadcrumb || clause.sectionId
74
- ? { section: clause.breadcrumb ?? clause.sectionId }
75
- : {}),
76
- gist: clause.gist,
77
- ...(clause.counterInstinct ? { text: clause.text } : {}),
78
- counterInstinct: clause.counterInstinct,
79
- repos: clause.repos,
80
- steps: clause.steps,
81
- };
103
+ return clause;
82
104
  });
83
105
  }
84
106
 
85
107
  export const GATHER_LOOKUP_IDS = ["figma-guidelines"];
86
108
 
87
- /** Build the six-section stored contract; Delta Gather keeps lane-authored sections. */
109
+ /** Build the stored contract; Delta Gather keeps lane-authored sections. */
88
110
  export function freezeFromGather({
89
111
  gather,
90
112
  boundaries,
@@ -119,6 +141,7 @@ export function freezeFromGather({
119
141
  },
120
142
  boundaries,
121
143
  pinnedClauses: pinnedClausesFromGather(gather.clauses),
144
+ clauseMap: clauseMapFromGather(gather),
122
145
  // Gather owns the lookups it derives (the Figma scope's guidelines): each
123
146
  // Gather replaces them, or drops them when the scope no longer yields any.
124
147
  // Lookups the lane added itself are kept.
package/dist/hooks.js CHANGED
@@ -254,9 +254,13 @@ export async function sessionStartContext(payload, { request = devRequest, confi
254
254
  },
255
255
  { request, config },
256
256
  );
257
+ // A Freeze written before it referenced the Clause map has no pointer to it.
258
+ const pointer = result.shown && !context.includes("lane gather show")
259
+ ? `\nFull Clause map: \`nodii-dev lane gather show ${result.lane.key}\`; one clause in full: \`nodii-dev rules show <ID>\`.`
260
+ : "";
257
261
  return result.shown
258
- ? context.trimEnd()
259
- : "Freeze re-grounding: no active Dev lane with initialized Freeze was available for this worktree; run `nodii-dev lane freeze show <key>` before continuing.";
262
+ ? `${context.trimEnd()}${pointer}`
263
+ : "Freeze re-grounding: no active Dev lane with initialized Freeze was available for this worktree; run `nodii-dev lane freeze show <key>` (and `nodii-dev lane gather show <key>` for its Clause map) before continuing.";
260
264
  }
261
265
 
262
266
  export function workflowSuggestion(payload) {
package/dist/lanes.js CHANGED
@@ -231,6 +231,16 @@ export async function laneCommand(action, args, flags, { request = devRequest, c
231
231
  const payload = await request("POST", `/api/v1/lanes/${encode(key)}/start`, via);
232
232
  return { payload, human: (p) => `Started ${laneLine(p.data)}` };
233
233
  }
234
+ // The Freeze references the Clause map rather than holding it (hub-58).
235
+ if (action === "gather" && args[0] === "show") {
236
+ // A Gather flag here means a Gather was meant: never show silently instead.
237
+ const gatherFlags = ["picker", "shortlist", "documents", "delta", "objective", "done-check", "paths", "components", "limit", "section-limit-per-document"].filter((flag) => flags[flag] !== undefined);
238
+ if (gatherFlags.length)
239
+ throw new CliError("USAGE", `lane gather show takes only [<key>] [--gather ID]; --${gatherFlags.join(", --")} belong to lane gather.`, 2);
240
+ const key = need(args[1] ?? await currentGatherLane(request, config, gitContext), "lane gather show needs <key>");
241
+ const payload = await request("GET", `/api/v1/lanes/${encode(key)}/gather${query({ gatherId: flags.gather })}`);
242
+ return { payload, human: (p) => `Gather ${p.data.gatherId}\n${gatherText(p, p.data.objective ?? "")}` };
243
+ }
234
244
  const ref = need(args[0] ?? (action === "gather" ? await currentGatherLane(request, config, gitContext) : undefined), `lane ${action} needs <key>`);
235
245
  const id = ref;
236
246
  if (action === "show") {
package/dist/upload.js CHANGED
@@ -317,6 +317,15 @@ export async function rulesCommand(action, args, flags, { request = devRequest }
317
317
  const payload = await request("GET", `/api/v1/rules/find${query({ question, limit })}`);
318
318
  return { payload, human: rulesFindText };
319
319
  }
320
+ if (action === "show") {
321
+ const id = args[0]?.trim();
322
+ if (!id) throw new CliError("USAGE", "rules show needs a clause id, for example: nodii-dev rules show S04-7", 2);
323
+ const payload = await request("GET", `/api/v1/rules/clauses/${encode(id)}`);
324
+ return {
325
+ payload,
326
+ human: (p) => p.data.map((c) => `${c.clauseId}${c.counterInstinct ? " ⚑" : ""} · ${c.documentCode}@${c.documentVersion} › ${c.section}\n${c.text}`).join("\n\n"),
327
+ };
328
+ }
320
329
  if (action === "core") {
321
330
  // Dev refuses a core over the cap with CORE_OVER_CAP; that error is the output.
322
331
  const payload = await request("GET", "/api/v1/rules/core");
@@ -347,5 +356,5 @@ export async function rulesCommand(action, args, flags, { request = devRequest }
347
356
  const payload = await request("PUT", "/api/v1/rules/core/cap", { cap });
348
357
  return { payload, human: (p) => `Core cap: ${p.data.previous} -> ${p.data.cap} tokens.` };
349
358
  }
350
- throw new CliError("USAGE", 'rules find "QUESTION" [--limit N] | rules core | rules report [--section rulebook|services|all] [--lane KEY] | rules cap TOKENS', 2);
359
+ throw new CliError("USAGE", 'rules find "QUESTION" [--limit N] | rules show CLAUSE_ID | rules core | rules report [--section rulebook|services|all] [--lane KEY] | rules cap TOKENS', 2);
351
360
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodii/dev",
3
- "version": "0.6.34",
3
+ "version": "0.6.35",
4
4
  "description": "Agent CLI for Nodii Dev, reached through the platform edge",
5
5
  "type": "module",
6
6
  "bin": {