@promptctl/cc-candybar 1.29.0 → 1.31.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.
@@ -27,16 +27,20 @@ import { toString as varToString } from "../var-system/types.js";
27
27
  import { buildScope } from "../template-engine/scope.js";
28
28
  import type { ActionDecl } from "../config/action.js";
29
29
  import { resolveOptionDomain } from "../config/option-domain.js";
30
+ import { encodeLayoutOp, type LayoutOp } from "../config/layout-ops.js";
30
31
  import type { StripStyle } from "../themes/policy.js";
31
32
  import {
32
33
  effectsUrl,
34
+ VERB_APPLY_LAYOUT_OP,
33
35
  VERB_COPY,
34
36
  VERB_OPEN_VSCODE,
37
+ VERB_REDO,
35
38
  VERB_RESET_CONFIG,
36
39
  VERB_SET_CONFIG,
37
40
  VERB_SET_STATE,
38
41
  VERB_STEP_CONFIG,
39
42
  VERB_STEP_STATE,
43
+ VERB_UNDO,
40
44
  type Effect,
41
45
  } from "../click/wire.js";
42
46
 
@@ -135,7 +139,18 @@ export type CompiledActionDecl =
135
139
  // one config-overrides key. Carries only the key — there is no value to
136
140
  // realize, so it shares copy/open's "no gate" shape at compile time (the
137
141
  // GATE is the key-membership check the reset-config verb handler applies).
138
- | { readonly kind: "reset"; readonly key: string };
142
+ | { readonly kind: "reset"; readonly key: string }
143
+ // [LAW:one-source-of-truth] brandon-layout-edit-2gc.1's structural-edit
144
+ // arms. Fully literal at compile time (the op IS the declaration — no
145
+ // template-bound option, unlike persist-option), so `op` is precomputed
146
+ // here rather than reconstructed from raw fields at every realize() call.
147
+ | { readonly kind: "layout-op"; readonly key: string; readonly op: LayoutOp }
148
+ // [LAW:one-source-of-truth] brandon-layout-edit-2gc.2's global history
149
+ // step over the overrides layer — `reset`'s fine-grained sibling. No key:
150
+ // there is nothing to carry, since the history stack (not this action) is
151
+ // what decides which entry moves.
152
+ | { readonly kind: "undo" }
153
+ | { readonly kind: "redo" };
139
154
 
140
155
  export type CompiledActions = ReadonlyMap<string, CompiledActionDecl>;
141
156
 
@@ -294,6 +309,25 @@ function compileAction(
294
309
  members: action.cycle,
295
310
  };
296
311
  }
312
+ if ("removeSegment" in action) {
313
+ return {
314
+ kind: "layout-op",
315
+ key: action.persist,
316
+ op: { op: "remove", target: action.removeSegment },
317
+ };
318
+ }
319
+ if ("insertSegment" in action) {
320
+ return {
321
+ kind: "layout-op",
322
+ key: action.persist,
323
+ op: {
324
+ op: "insert",
325
+ segment: action.insertSegment,
326
+ anchor: action.anchor,
327
+ relation: action.relation,
328
+ },
329
+ };
330
+ }
297
331
  return {
298
332
  kind: "persist-bounded",
299
333
  key: action.persist,
@@ -312,7 +346,10 @@ function compileAction(
312
346
  target: parseActionTemplate(parse, action.open, name),
313
347
  };
314
348
  }
315
- return { kind: "reset", key: action.reset };
349
+ if ("reset" in action) {
350
+ return { kind: "reset", key: action.reset };
351
+ }
352
+ return "undo" in action ? { kind: "undo" } : { kind: "redo" };
316
353
  }
317
354
 
318
355
  function parseActionTemplate(
@@ -522,6 +559,34 @@ function realize(
522
559
  effect: { verb: VERB_RESET_CONFIG, args: [sessionId, c.key] },
523
560
  active: false,
524
561
  };
562
+ // [LAW:one-source-of-truth] No key to carry — the click just says "step
563
+ // the history", and which entry moves is entirely server-side state
564
+ // (never wire input, so there is nothing here to gate). Never "active":
565
+ // a history step is a one-shot trigger, not a current-selection toggle.
566
+ case "undo":
567
+ return {
568
+ effect: { verb: VERB_UNDO, args: [sessionId] },
569
+ active: false,
570
+ };
571
+ case "redo":
572
+ return {
573
+ effect: { verb: VERB_REDO, args: [sessionId] },
574
+ active: false,
575
+ };
576
+ // [LAW:one-source-of-truth] The op is fixed at compile time (see
577
+ // compileAction) — the click just delivers it. `apply-layout-op`'s
578
+ // handler does read-current-append-write (see verbs/index.ts), unlike
579
+ // persist-literal's plain overwrite, so it is its own verb rather than
580
+ // VERB_SET_CONFIG. Never "active": a structural edit is a one-shot
581
+ // trigger, not a current-selection toggle.
582
+ case "layout-op":
583
+ return {
584
+ effect: {
585
+ verb: VERB_APPLY_LAYOUT_OP,
586
+ args: [sessionId, c.key, encodeLayoutOp(c.op)],
587
+ },
588
+ active: false,
589
+ };
525
590
  }
526
591
  }
527
592