wicked-crew 0.7.28 → 0.7.30

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.
Files changed (146) hide show
  1. package/README.md +12 -1
  2. package/dist/api/chat-scope.d.ts +210 -0
  3. package/dist/api/chat-scope.d.ts.map +1 -0
  4. package/dist/api/chat-scope.js +728 -0
  5. package/dist/api/chat-scope.js.map +1 -0
  6. package/dist/api/diagnostics.d.ts +30 -2
  7. package/dist/api/diagnostics.d.ts.map +1 -1
  8. package/dist/api/diagnostics.js +73 -5
  9. package/dist/api/diagnostics.js.map +1 -1
  10. package/dist/api/governance-health.d.ts +171 -0
  11. package/dist/api/governance-health.d.ts.map +1 -0
  12. package/dist/api/governance-health.js +379 -0
  13. package/dist/api/governance-health.js.map +1 -0
  14. package/dist/api/open-path.d.ts.map +1 -1
  15. package/dist/api/open-path.js +2 -1
  16. package/dist/api/open-path.js.map +1 -1
  17. package/dist/api/post-hoc-deliver.d.ts +9 -5
  18. package/dist/api/post-hoc-deliver.d.ts.map +1 -1
  19. package/dist/api/post-hoc-deliver.js +21 -7
  20. package/dist/api/post-hoc-deliver.js.map +1 -1
  21. package/dist/api/routes.d.ts +70 -12
  22. package/dist/api/routes.d.ts.map +1 -1
  23. package/dist/api/routes.js +375 -60
  24. package/dist/api/routes.js.map +1 -1
  25. package/dist/api/seat-health.d.ts +38 -0
  26. package/dist/api/seat-health.d.ts.map +1 -1
  27. package/dist/api/seat-health.js +88 -5
  28. package/dist/api/seat-health.js.map +1 -1
  29. package/dist/api/seat-signin.d.ts.map +1 -1
  30. package/dist/api/seat-signin.js +49 -23
  31. package/dist/api/seat-signin.js.map +1 -1
  32. package/dist/api/seat-standing.d.ts +101 -0
  33. package/dist/api/seat-standing.d.ts.map +1 -0
  34. package/dist/api/seat-standing.js +138 -0
  35. package/dist/api/seat-standing.js.map +1 -0
  36. package/dist/api/server.d.ts.map +1 -1
  37. package/dist/api/server.js +37 -0
  38. package/dist/api/server.js.map +1 -1
  39. package/dist/campaigns/routes.d.ts +4 -4
  40. package/dist/cli/governance.d.ts +131 -0
  41. package/dist/cli/governance.d.ts.map +1 -0
  42. package/dist/cli/governance.js +354 -0
  43. package/dist/cli/governance.js.map +1 -0
  44. package/dist/cli/index.js +102 -3
  45. package/dist/cli/index.js.map +1 -1
  46. package/dist/core/adapter.d.ts +99 -1
  47. package/dist/core/adapter.d.ts.map +1 -1
  48. package/dist/core/adapter.js +149 -8
  49. package/dist/core/adapter.js.map +1 -1
  50. package/dist/core/bridge-path.d.ts +21 -0
  51. package/dist/core/bridge-path.d.ts.map +1 -1
  52. package/dist/core/bridge-path.js +37 -0
  53. package/dist/core/bridge-path.js.map +1 -1
  54. package/dist/core/bridge-reaper.d.ts.map +1 -1
  55. package/dist/core/bridge-reaper.js +11 -4
  56. package/dist/core/bridge-reaper.js.map +1 -1
  57. package/dist/core/deliver-text.d.ts +184 -0
  58. package/dist/core/deliver-text.d.ts.map +1 -0
  59. package/dist/core/deliver-text.js +434 -0
  60. package/dist/core/deliver-text.js.map +1 -0
  61. package/dist/core/deliver-triage.d.ts +90 -0
  62. package/dist/core/deliver-triage.d.ts.map +1 -0
  63. package/dist/core/deliver-triage.js +106 -0
  64. package/dist/core/deliver-triage.js.map +1 -0
  65. package/dist/core/deliver.d.ts +103 -9
  66. package/dist/core/deliver.d.ts.map +1 -1
  67. package/dist/core/deliver.js +244 -46
  68. package/dist/core/deliver.js.map +1 -1
  69. package/dist/core/estate-mcp-client.d.ts.map +1 -1
  70. package/dist/core/estate-mcp-client.js +7 -2
  71. package/dist/core/estate-mcp-client.js.map +1 -1
  72. package/dist/core/exec.d.ts.map +1 -1
  73. package/dist/core/exec.js +11 -1
  74. package/dist/core/exec.js.map +1 -1
  75. package/dist/core/governance-store.d.ts +219 -0
  76. package/dist/core/governance-store.d.ts.map +1 -0
  77. package/dist/core/governance-store.js +290 -0
  78. package/dist/core/governance-store.js.map +1 -0
  79. package/dist/core/repoPaths.d.ts +36 -5
  80. package/dist/core/repoPaths.d.ts.map +1 -1
  81. package/dist/core/repoPaths.js +46 -4
  82. package/dist/core/repoPaths.js.map +1 -1
  83. package/dist/interactive/bridge-pool.d.ts +29 -24
  84. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  85. package/dist/interactive/bridge-pool.js +74 -7
  86. package/dist/interactive/bridge-pool.js.map +1 -1
  87. package/dist/interactive/chat-events.d.ts.map +1 -1
  88. package/dist/interactive/chat-events.js +5 -2
  89. package/dist/interactive/chat-events.js.map +1 -1
  90. package/dist/interactive/council-outcome.d.ts +28 -0
  91. package/dist/interactive/council-outcome.d.ts.map +1 -0
  92. package/dist/interactive/council-outcome.js +57 -0
  93. package/dist/interactive/council-outcome.js.map +1 -0
  94. package/dist/interactive/demo-events.d.ts.map +1 -1
  95. package/dist/interactive/demo-events.js +5 -2
  96. package/dist/interactive/demo-events.js.map +1 -1
  97. package/dist/interactive/doc-delete-routes.d.ts.map +1 -1
  98. package/dist/interactive/doc-delete-routes.js +3 -2
  99. package/dist/interactive/doc-delete-routes.js.map +1 -1
  100. package/dist/interactive/draft-events.d.ts.map +1 -1
  101. package/dist/interactive/draft-events.js +5 -2
  102. package/dist/interactive/draft-events.js.map +1 -1
  103. package/dist/interactive/edit-events.d.ts.map +1 -1
  104. package/dist/interactive/edit-events.js +5 -2
  105. package/dist/interactive/edit-events.js.map +1 -1
  106. package/dist/projects/auto-refresh.d.ts +54 -0
  107. package/dist/projects/auto-refresh.d.ts.map +1 -0
  108. package/dist/projects/auto-refresh.js +76 -0
  109. package/dist/projects/auto-refresh.js.map +1 -0
  110. package/dist/projects/graph-paths.d.ts +4 -2
  111. package/dist/projects/graph-paths.d.ts.map +1 -1
  112. package/dist/projects/graph-paths.js +4 -2
  113. package/dist/projects/graph-paths.js.map +1 -1
  114. package/dist/projects/graph.d.ts +20 -6
  115. package/dist/projects/graph.d.ts.map +1 -1
  116. package/dist/projects/graph.js +40 -13
  117. package/dist/projects/graph.js.map +1 -1
  118. package/dist/projects/routes.d.ts.map +1 -1
  119. package/dist/projects/routes.js +30 -11
  120. package/dist/projects/routes.js.map +1 -1
  121. package/dist/projects/state-home.d.ts +6 -0
  122. package/dist/projects/state-home.d.ts.map +1 -1
  123. package/dist/projects/state-home.js +9 -1
  124. package/dist/projects/state-home.js.map +1 -1
  125. package/dist/skills/guards.d.ts +17 -6
  126. package/dist/skills/guards.d.ts.map +1 -1
  127. package/dist/skills/guards.js +42 -15
  128. package/dist/skills/guards.js.map +1 -1
  129. package/dist/skills/plugin-source.d.ts.map +1 -1
  130. package/dist/skills/plugin-source.js +3 -0
  131. package/dist/skills/plugin-source.js.map +1 -1
  132. package/dist/skills/refs.d.ts +181 -17
  133. package/dist/skills/refs.d.ts.map +1 -1
  134. package/dist/skills/refs.js +345 -26
  135. package/dist/skills/refs.js.map +1 -1
  136. package/dist/skills/store.d.ts +22 -1
  137. package/dist/skills/store.d.ts.map +1 -1
  138. package/dist/skills/store.js +161 -23
  139. package/dist/skills/store.js.map +1 -1
  140. package/dist/studio/assets/index-CWUS9Ump.js +542 -0
  141. package/dist/studio/assets/{index-CK1uJWs2.css → index-_ydd-jKd.css} +1 -1
  142. package/dist/studio/index.html +2 -2
  143. package/dist/studio/testid-inventory.json +567 -6
  144. package/endpoint-manifest.json +67 -14
  145. package/package.json +4 -4
  146. package/dist/studio/assets/index-CdmCMh2f.js +0 -539
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Deliver-failure triage — wicked-core#431 follow-through (crew consumes wicked-core#433).
3
+ *
4
+ * The deliver phase is a TOOL unit: a bash script the engine spawns (`run_tool_cmd`); no CLI seat
5
+ * runs it. When it exits non-zero the engine still emits `stepFailed {failureKind: "workerError"}` —
6
+ * the Tool path has no finer kind — and hands the excerpt to its agent triage judge, which answers
7
+ * `escalate` (a human decides). Crew's own folds over `stepFailed` must not read that `workerError`
8
+ * literally: `api/seat-health.ts` used to mark the unit's ASSIGNED seat inactive on ANY
9
+ * `workerError`, so a `deliver: LIFT-CONFLICT` refusal blamed a CLI for a git state.
10
+ *
11
+ * Since wicked-core#433 the refusal can also be ENGINE-authored — the deliver LIFT + RE-VERIFY runs
12
+ * BEFORE the script (`wicked-core/src/deliver_lift.rs` `lift_and_reverify`); its texts, in order:
13
+ * - `deliver: the worktree's HEAD is attached to `<ref>` / is detached, not the run branch
14
+ * `wicked/<run>` — nothing was lifted, reset or pushed; …` (the run-branch precondition);
15
+ * - `deliver: the lift onto <base> (<tip>) could not be applied cleanly — …` (a partial worktree);
16
+ * - `deliver: LIFT-CONFLICT — lifting the run's work onto <base> (<tip>) would conflict in: …`
17
+ * (the worktree was left exactly as verified; carries crew's own marker ON PURPOSE so the
18
+ * strand derivation — `completed` + `delivery: 'stranded'`, `POST /runs/:id/deliver` — fires);
19
+ * - `deliver: the worktree could not be snapshotted before delivery (…); nothing was pushed …`;
20
+ * - `deliver: <why>, and the repository's own checks FAILED on it: …` — the RE-VERIFY the engine
21
+ * runs whenever the worktree's tree is not the tree the run verified (`<why>` = "the lift
22
+ * changed the tree" | "the worktree's tree X is not the tree the run verified (Y)" | "the run
23
+ * recorded no verified tree"); the worktree holds an UNVERIFIED tree — NOT a strand, a post-hoc
24
+ * lift would push it;
25
+ * - `deliver: the repository's checks passed but CHANGED the worktree while running …` /
26
+ * `deliver: the repository's checks passed but the worktree could not be re-snapshotted …`
27
+ * (a check script that edits tracked files; inspect).
28
+ * Every one of them — and every refusal crew's own script prints (`core/deliver.ts`: nothing to
29
+ * deliver, the default branch, a moved verified base, a failed `gh`) — is an OPERATOR decision,
30
+ * never a seat fault. This module recognises them from the excerpt the engine puts on
31
+ * `stepFailed.detail` / the unit's `denial_reason` — head 150 + tail 250 chars of the WHOLE Tool
32
+ * output (`bounded_excerpt` in `actor.rs`). The engine's refusals ARE the whole output (the command
33
+ * never ran) and every phrase matched here sits inside the first 150 chars of that text, so they
34
+ * survive in the head. The script's refusals come AFTER real fetch / install / codegen chatter, so
35
+ * only the tail is theirs: every script marker (`LIFT-CONFLICT`, `BASE MOVED`, `PREFLIGHT CHANGED`)
36
+ * TRAILS its last line and lands in the tail-250 (review F-527-001).
37
+ *
38
+ * ORDERING: this is a TEXT classifier and assumes nothing about the event stream. In particular a
39
+ * deliver unit refused for a wrong HEAD ref (`deliver: the worktree's HEAD is attached to …`) emits
40
+ * its `stepFailed` WITHOUT a preceding `deliverLiftEvaluated` — the run-branch precondition runs
41
+ * before any lift — so no consumer (this one, the strand derivation, seat health, the studio's
42
+ * delivery card) may treat the lift event as a prerequisite of a deliver failure.
43
+ */
44
+ /** The engine's lift-conflict remedy (`LiftOutcome::Conflict`) — crew's marker plus the engine's words. */
45
+ export declare const ENGINE_LIFT_CONFLICT_PHRASE = "deliver: LIFT-CONFLICT \u2014 lifting the run's work onto";
46
+ /** The engine refused before any lift: the worktree is not on its run branch (`require_run_branch`). */
47
+ export declare const ENGINE_RUN_BRANCH_PHRASE = "nothing was lifted, reset or pushed; the deliver script only pushes the run branch";
48
+ /** The engine's apply failure (`LiftOutcome::Failed`) — the line starts `deliver: the lift onto`. */
49
+ export declare const ENGINE_LIFT_APPLY_FAILED_PHRASE = "could not be applied cleanly";
50
+ /** The engine could not identify the tree it was about to ship (pre-check snapshot failed). */
51
+ export declare const ENGINE_SNAPSHOT_FAILED_PHRASE = "deliver: the worktree could not be snapshotted before delivery";
52
+ /** The engine's re-verify: the repository's checks FAILED on the tree that would ship. */
53
+ export declare const ENGINE_REVERIFY_FAILED_PHRASE = "repository's own checks FAILED on";
54
+ /** The engine's post-check proof failing: the checks changed the tree, or it could not be re-snapshotted. */
55
+ export declare const ENGINE_CHECKS_MUTATED_PHRASE = "deliver: the repository's checks passed but";
56
+ /**
57
+ * What kind of deliver refusal a failed deliver unit's excerpt carries.
58
+ * - `lift_conflict` — the engine's lift or the script's rebase/push hit a collision (recoverable);
59
+ * - `run_branch_refused` — the worktree is not on its run branch; nothing was touched (engine);
60
+ * - `lift_apply_failed` — the lift could not be applied cleanly, partial worktree (engine);
61
+ * - `snapshot_failed` — the worktree could not be snapshotted before delivery (engine);
62
+ * - `reverify_failed` — the repository's checks FAILED on the tree that would ship (engine);
63
+ * - `checks_mutated` — the checks passed but changed the tree / could not be re-proven (engine);
64
+ * - `base_moved` — the script found origin/<default> past `WICKED_DELIVER_VERIFIED_BASE` (script);
65
+ * - `preflight_changed` — the crew#426 lockfile/codegen re-sync changed the verified tree (script);
66
+ * - `script_refusal` — any other loud `deliver: …` refusal the script prints (script).
67
+ */
68
+ export type DeliverFailureKind = 'lift_conflict' | 'run_branch_refused' | 'lift_apply_failed' | 'snapshot_failed' | 'reverify_failed' | 'checks_mutated' | 'base_moved' | 'preflight_changed' | 'script_refusal';
69
+ export interface DeliverFailureTriage {
70
+ kind: DeliverFailureKind;
71
+ /** Who wrote the refusal: the engine's deliver lift, or crew's own deliver script. */
72
+ author: 'engine' | 'script';
73
+ /** Always `'escalate'`: a deliver refusal is an operator decision, never a seat (worker) fault. */
74
+ disposition: 'escalate';
75
+ /**
76
+ * Whether the run's work is intact and post-hoc deliverable (`POST /runs/:id/deliver` after the
77
+ * operator clears the collision) — `true` only for a lift conflict, the shape crew's strand
78
+ * derivation already keys on (`isDeliverConflictStranded`). A failed re-verify, an apply failure
79
+ * or a moved base must NOT be offered a post-hoc push: that would deliver a tree nobody verified.
80
+ */
81
+ recoverable: boolean;
82
+ }
83
+ /**
84
+ * Classify a failed deliver unit's excerpt (`stepFailed.detail`, or the unit's `denial_reason`).
85
+ * `null` when the text carries no deliver refusal at all — a spawn/infra failure (`bash: gh:
86
+ * command not found`), or a unit that is not the deliver phase — so callers fall back to their
87
+ * default reading of `failureKind`.
88
+ */
89
+ export declare function triageDeliverFailure(detail: string | null | undefined): DeliverFailureTriage | null;
90
+ //# sourceMappingURL=deliver-triage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliver-triage.d.ts","sourceRoot":"","sources":["../../src/core/deliver-triage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAQH,2GAA2G;AAC3G,eAAO,MAAM,2BAA2B,8DAAkE,CAAC;AAC3G,wGAAwG;AACxG,eAAO,MAAM,wBAAwB,uFACiD,CAAC;AACvF,qGAAqG;AACrG,eAAO,MAAM,+BAA+B,iCAAiC,CAAC;AAC9E,+FAA+F;AAC/F,eAAO,MAAM,6BAA6B,mEAAmE,CAAC;AAC9G,0FAA0F;AAC1F,eAAO,MAAM,6BAA6B,sCAAsC,CAAC;AACjF,6GAA6G;AAC7G,eAAO,MAAM,4BAA4B,gDAAgD,CAAC;AAE1F;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,CAAC;AAErB,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,kBAAkB,CAAC;IACzB,sFAAsF;IACtF,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC5B,mGAAmG;IACnG,WAAW,EAAE,UAAU,CAAC;IACxB;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAC;CACtB;AAeD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,oBAAoB,GAAG,IAAI,CAyBnG"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Deliver-failure triage — wicked-core#431 follow-through (crew consumes wicked-core#433).
3
+ *
4
+ * The deliver phase is a TOOL unit: a bash script the engine spawns (`run_tool_cmd`); no CLI seat
5
+ * runs it. When it exits non-zero the engine still emits `stepFailed {failureKind: "workerError"}` —
6
+ * the Tool path has no finer kind — and hands the excerpt to its agent triage judge, which answers
7
+ * `escalate` (a human decides). Crew's own folds over `stepFailed` must not read that `workerError`
8
+ * literally: `api/seat-health.ts` used to mark the unit's ASSIGNED seat inactive on ANY
9
+ * `workerError`, so a `deliver: LIFT-CONFLICT` refusal blamed a CLI for a git state.
10
+ *
11
+ * Since wicked-core#433 the refusal can also be ENGINE-authored — the deliver LIFT + RE-VERIFY runs
12
+ * BEFORE the script (`wicked-core/src/deliver_lift.rs` `lift_and_reverify`); its texts, in order:
13
+ * - `deliver: the worktree's HEAD is attached to `<ref>` / is detached, not the run branch
14
+ * `wicked/<run>` — nothing was lifted, reset or pushed; …` (the run-branch precondition);
15
+ * - `deliver: the lift onto <base> (<tip>) could not be applied cleanly — …` (a partial worktree);
16
+ * - `deliver: LIFT-CONFLICT — lifting the run's work onto <base> (<tip>) would conflict in: …`
17
+ * (the worktree was left exactly as verified; carries crew's own marker ON PURPOSE so the
18
+ * strand derivation — `completed` + `delivery: 'stranded'`, `POST /runs/:id/deliver` — fires);
19
+ * - `deliver: the worktree could not be snapshotted before delivery (…); nothing was pushed …`;
20
+ * - `deliver: <why>, and the repository's own checks FAILED on it: …` — the RE-VERIFY the engine
21
+ * runs whenever the worktree's tree is not the tree the run verified (`<why>` = "the lift
22
+ * changed the tree" | "the worktree's tree X is not the tree the run verified (Y)" | "the run
23
+ * recorded no verified tree"); the worktree holds an UNVERIFIED tree — NOT a strand, a post-hoc
24
+ * lift would push it;
25
+ * - `deliver: the repository's checks passed but CHANGED the worktree while running …` /
26
+ * `deliver: the repository's checks passed but the worktree could not be re-snapshotted …`
27
+ * (a check script that edits tracked files; inspect).
28
+ * Every one of them — and every refusal crew's own script prints (`core/deliver.ts`: nothing to
29
+ * deliver, the default branch, a moved verified base, a failed `gh`) — is an OPERATOR decision,
30
+ * never a seat fault. This module recognises them from the excerpt the engine puts on
31
+ * `stepFailed.detail` / the unit's `denial_reason` — head 150 + tail 250 chars of the WHOLE Tool
32
+ * output (`bounded_excerpt` in `actor.rs`). The engine's refusals ARE the whole output (the command
33
+ * never ran) and every phrase matched here sits inside the first 150 chars of that text, so they
34
+ * survive in the head. The script's refusals come AFTER real fetch / install / codegen chatter, so
35
+ * only the tail is theirs: every script marker (`LIFT-CONFLICT`, `BASE MOVED`, `PREFLIGHT CHANGED`)
36
+ * TRAILS its last line and lands in the tail-250 (review F-527-001).
37
+ *
38
+ * ORDERING: this is a TEXT classifier and assumes nothing about the event stream. In particular a
39
+ * deliver unit refused for a wrong HEAD ref (`deliver: the worktree's HEAD is attached to …`) emits
40
+ * its `stepFailed` WITHOUT a preceding `deliverLiftEvaluated` — the run-branch precondition runs
41
+ * before any lift — so no consumer (this one, the strand derivation, seat health, the studio's
42
+ * delivery card) may treat the lift event as a prerequisite of a deliver failure.
43
+ */
44
+ import { DELIVER_BASE_MOVED_MARKER, DELIVER_LIFT_CONFLICT_MARKER, DELIVER_PREFLIGHT_CHANGED_MARKER, } from './deliver.js';
45
+ /** The engine's lift-conflict remedy (`LiftOutcome::Conflict`) — crew's marker plus the engine's words. */
46
+ export const ENGINE_LIFT_CONFLICT_PHRASE = `${DELIVER_LIFT_CONFLICT_MARKER} — lifting the run's work onto`;
47
+ /** The engine refused before any lift: the worktree is not on its run branch (`require_run_branch`). */
48
+ export const ENGINE_RUN_BRANCH_PHRASE = 'nothing was lifted, reset or pushed; the deliver script only pushes the run branch';
49
+ /** The engine's apply failure (`LiftOutcome::Failed`) — the line starts `deliver: the lift onto`. */
50
+ export const ENGINE_LIFT_APPLY_FAILED_PHRASE = 'could not be applied cleanly';
51
+ /** The engine could not identify the tree it was about to ship (pre-check snapshot failed). */
52
+ export const ENGINE_SNAPSHOT_FAILED_PHRASE = 'deliver: the worktree could not be snapshotted before delivery';
53
+ /** The engine's re-verify: the repository's checks FAILED on the tree that would ship. */
54
+ export const ENGINE_REVERIFY_FAILED_PHRASE = "repository's own checks FAILED on";
55
+ /** The engine's post-check proof failing: the checks changed the tree, or it could not be re-snapshotted. */
56
+ export const ENGINE_CHECKS_MUTATED_PHRASE = "deliver: the repository's checks passed but";
57
+ const APPLY_FAILED = /deliver: the lift onto [^\n]*? could not be applied cleanly/;
58
+ /** A `deliver: …` line of the script's — at the start, after a newline, or after the engine's
59
+ * `Worker FAILED on unit N (triage: …): ` framing. The classifier's informational
60
+ * `deliver: EXCLUDED (<reason>): <path>` lines are not refusals and do not count. */
61
+ const SCRIPT_REFUSAL = /(?:^|\n|\): )deliver: (?!EXCLUDED \()/;
62
+ const ENGINE = (kind) => ({
63
+ kind,
64
+ author: 'engine',
65
+ disposition: 'escalate',
66
+ recoverable: false,
67
+ });
68
+ /**
69
+ * Classify a failed deliver unit's excerpt (`stepFailed.detail`, or the unit's `denial_reason`).
70
+ * `null` when the text carries no deliver refusal at all — a spawn/infra failure (`bash: gh:
71
+ * command not found`), or a unit that is not the deliver phase — so callers fall back to their
72
+ * default reading of `failureKind`.
73
+ */
74
+ export function triageDeliverFailure(detail) {
75
+ if (typeof detail !== 'string' || detail.length === 0)
76
+ return null;
77
+ if (detail.includes(DELIVER_LIFT_CONFLICT_MARKER)) {
78
+ return {
79
+ kind: 'lift_conflict',
80
+ author: detail.includes(ENGINE_LIFT_CONFLICT_PHRASE) ? 'engine' : 'script',
81
+ disposition: 'escalate',
82
+ recoverable: true,
83
+ };
84
+ }
85
+ if (detail.includes(ENGINE_RUN_BRANCH_PHRASE))
86
+ return ENGINE('run_branch_refused');
87
+ if (APPLY_FAILED.test(detail))
88
+ return ENGINE('lift_apply_failed');
89
+ if (detail.includes(ENGINE_SNAPSHOT_FAILED_PHRASE))
90
+ return ENGINE('snapshot_failed');
91
+ if (detail.includes(ENGINE_REVERIFY_FAILED_PHRASE))
92
+ return ENGINE('reverify_failed');
93
+ if (detail.includes(ENGINE_CHECKS_MUTATED_PHRASE))
94
+ return ENGINE('checks_mutated');
95
+ if (detail.includes(DELIVER_BASE_MOVED_MARKER)) {
96
+ return { kind: 'base_moved', author: 'script', disposition: 'escalate', recoverable: false };
97
+ }
98
+ if (detail.includes(DELIVER_PREFLIGHT_CHANGED_MARKER)) {
99
+ return { kind: 'preflight_changed', author: 'script', disposition: 'escalate', recoverable: false };
100
+ }
101
+ if (SCRIPT_REFUSAL.test(detail)) {
102
+ return { kind: 'script_refusal', author: 'script', disposition: 'escalate', recoverable: false };
103
+ }
104
+ return null;
105
+ }
106
+ //# sourceMappingURL=deliver-triage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliver-triage.js","sourceRoot":"","sources":["../../src/core/deliver-triage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,cAAc,CAAC;AAEtB,2GAA2G;AAC3G,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,4BAA4B,gCAAgC,CAAC;AAC3G,wGAAwG;AACxG,MAAM,CAAC,MAAM,wBAAwB,GACnC,oFAAoF,CAAC;AACvF,qGAAqG;AACrG,MAAM,CAAC,MAAM,+BAA+B,GAAG,8BAA8B,CAAC;AAC9E,+FAA+F;AAC/F,MAAM,CAAC,MAAM,6BAA6B,GAAG,gEAAgE,CAAC;AAC9G,0FAA0F;AAC1F,MAAM,CAAC,MAAM,6BAA6B,GAAG,mCAAmC,CAAC;AACjF,6GAA6G;AAC7G,MAAM,CAAC,MAAM,4BAA4B,GAAG,6CAA6C,CAAC;AAwC1F,MAAM,YAAY,GAAG,6DAA6D,CAAC;AACnF;;sFAEsF;AACtF,MAAM,cAAc,GAAG,uCAAuC,CAAC;AAE/D,MAAM,MAAM,GAAG,CAAC,IAAwB,EAAwB,EAAE,CAAC,CAAC;IAClE,IAAI;IACJ,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,UAAU;IACvB,WAAW,EAAE,KAAK;CACnB,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAiC;IACpE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,IAAI,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;QAClD,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;YAC1E,WAAW,EAAE,UAAU;YACvB,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QAAE,OAAO,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACnF,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAClE,IAAI,MAAM,CAAC,QAAQ,CAAC,6BAA6B,CAAC;QAAE,OAAO,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACrF,IAAI,MAAM,CAAC,QAAQ,CAAC,6BAA6B,CAAC;QAAE,OAAO,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACrF,IAAI,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QAAE,OAAO,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACnF,IAAI,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;QAC/C,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAC/F,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACtG,CAAC;IACD,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IACnG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -11,6 +11,15 @@
11
11
  * to the current branch when that ref does not exist;
12
12
  * (b) the script REFUSES to push `main`/`master` (or an empty/detached branch name) — the
13
13
  * deliver phase only ever pushes run branches;
14
+ * (b2) with the engine's `WICKED_DELIVER_VERIFIED_BASE` pin set (wicked-core#431 / #433: the
15
+ * remote-tip commit the engine lifted the work onto and re-verified against), it REFUSES —
16
+ * before staging anything — when origin's default branch no longer resolves to that commit
17
+ * after its own fetch ({@link DELIVER_BASE_MOVED_MARKER}): a base that moved past the verified
18
+ * one is re-verified by the engine's retry, never rebased past by this script;
19
+ * (b3) the crew#426 preflight (lockfile re-sync + codegen) runs AFTER the engine's verification;
20
+ * when it changes the worktree, an engine-driven delivery REFUSES and names the files
21
+ * ({@link DELIVER_PREFLIGHT_CHANGED_MARKER}) — a post-hoc lift ({@link DELIVER_POSTHOC_ENV})
22
+ * keeps the regeneration and says so;
14
23
  * (c) it STAGES AND COMMITS the run's work, then rebases onto origin's default branch before
15
24
  * pushing. A conflict whose conflicted paths are ALL `CHANGELOG.md` is union-merged (both
16
25
  * sides' additive lines kept) and the rebase continues — the crew#418 collision magnet, made
@@ -19,8 +28,15 @@
19
28
  * pushed conflicted tree;
20
29
  * (d) `git push -u origin <branch>` — every rejected push carries the recovery marker. The run
21
30
  * work is already committed locally, so an operator can repair auth/transport and retry;
22
- * (e) `gh pr create --head <branch> --fill`, with gh's output and exit status captured
23
- * SEPARATELY so a gh failure fails the phase carrying gh's own message;
31
+ * (e) `gh pr create --head <branch> --title … --body-file …`, with gh's output and exit status
32
+ * captured SEPARATELY so a gh failure fails the phase carrying gh's own message. The title
33
+ * and body are COMPOSED FROM THE RUN (crew#524 / F-3R2-014, `core/deliver-text.ts`): the
34
+ * script asks the daemon that launched it (`GET /runs/:id/deliver-text`) for the text derived
35
+ * from the persisted run record — intent, `Fixes #N`, run link, phases + seats + gate
36
+ * outcomes, repo checks with exit codes, the evaluator verdict — and falls back to the same
37
+ * composer's launch-time text (embedded in the script) when the daemon cannot answer. The
38
+ * commit the phase makes for uncommitted work carries that same text (`git commit -F`), so
39
+ * ITS subject is the PR title; a run that committed incrementally keeps its own commits;
24
40
  * (f) the PR URL is the last line of the phase output.
25
41
  *
26
42
  * One deliberate change from the field version: NO gh account is baked into crew code (the
@@ -59,6 +75,7 @@
59
75
  * {@link deliverPrPhase}.
60
76
  */
61
77
  import type { PhaseDef, WorkflowDef } from './types.js';
78
+ import { type DeliverTextFacts } from './deliver-text.js';
62
79
  /**
63
80
  * The content-address of wicked-core's built-in evidence floor (`builtin_floors::EVIDENCE_FLOOR_PIN`,
64
81
  * criterion "the run left a change in its worktree (done is re-derived from the diff, never
@@ -89,6 +106,75 @@ export declare const DELIVER_PHASE_ID = "deliver";
89
106
  * terminal run failures exactly as before (the crew#400 refusal-vs-infra posture).
90
107
  */
91
108
  export declare const DELIVER_LIFT_CONFLICT_MARKER = "deliver: LIFT-CONFLICT";
109
+ /** What the script carries for its PR/commit text (crew#524). All optional: the bare script still
110
+ * composes a title and a body from the intent alone. */
111
+ export interface DeliverScriptOptions {
112
+ /** The run this script delivers; names the run in the fallback text. */
113
+ runId?: string;
114
+ /** Everything known when the script was composed — the embedded fallback is built from it.
115
+ * Defaults to the intent + run id alone (no workflow, no phases). */
116
+ facts?: DeliverTextFacts;
117
+ /** The launching daemon's own origin (`http://127.0.0.1:7701`). When set, the script first asks
118
+ * it for the run-derived text; unset (or unreachable) ⇒ the embedded fallback. */
119
+ apiOrigin?: string | null;
120
+ }
121
+ /**
122
+ * The env var the engine hands the deliver command with the remote-tip commit it VERIFIED the
123
+ * run's work against (wicked-core#431 / #433, `deliver_lift.rs` `VERIFIED_BASE_ENV`): set on a
124
+ * lift outcome of `unchanged` or `lifted`, absent when the lift was skipped (no remote, no default
125
+ * ref, a branch carrying its own commits) — and never set on a post-hoc `POST /runs/:id/deliver`,
126
+ * which has no engine verification to pin to (`api/post-hoc-deliver.ts` strips it).
127
+ */
128
+ export declare const DELIVER_VERIFIED_BASE_ENV = "WICKED_DELIVER_VERIFIED_BASE";
129
+ /**
130
+ * The sentinel the deliver script prints when `origin/<default>` no longer resolves to
131
+ * {@link DELIVER_VERIFIED_BASE_ENV} after the script's own fetch: the remote advanced between the
132
+ * engine's re-verify and the push window, so the rebase below would carry the base PAST what was
133
+ * verified. The script refuses BEFORE staging anything. Deliberately NOT a
134
+ * {@link DELIVER_LIFT_CONFLICT_MARKER}: a moved base is not a recoverable strand — a post-hoc lift
135
+ * would push a tree nobody verified on the new base; the remedy is the engine's own retry (approve
136
+ * the deliver gate: it lifts onto the new tip and re-runs the repository's checks first).
137
+ */
138
+ export declare const DELIVER_BASE_MOVED_MARKER = "deliver: BASE MOVED since verification";
139
+ /**
140
+ * The env var the daemon sets on a POST-HOC lift (`POST /runs/:id/deliver`, `api/post-hoc-deliver.ts`)
141
+ * and the engine never does. A post-hoc lift has no engine verification to protect, so the
142
+ * crew#426 preflight may regenerate tracked files and deliver them (disclosed); an engine-driven
143
+ * deliver Tool unit — the variable absent — refuses instead ({@link DELIVER_PREFLIGHT_CHANGED_MARKER}).
144
+ */
145
+ export declare const DELIVER_POSTHOC_ENV = "WICKED_DELIVER_POSTHOC";
146
+ /**
147
+ * The sentinel the deliver script prints when the crew#426 preflight (`npm install` + the
148
+ * `manifest:endpoints` / `generate:api-tests` codegen) CHANGED the worktree AFTER the engine had
149
+ * verified it (wicked-core#433 review addendum): the tree that would ship is then not the tree the
150
+ * repository's checks certified, and the script refuses before staging anything, leaving the
151
+ * regenerated files in the worktree. Not a {@link DELIVER_LIFT_CONFLICT_MARKER}: the remedy is to
152
+ * approve the retry — the engine re-verifies the changed tree first, and the retry's preflight
153
+ * regenerates nothing more.
154
+ */
155
+ export declare const DELIVER_PREFLIGHT_CHANGED_MARKER = "deliver: PREFLIGHT CHANGED the verified tree";
156
+ /**
157
+ * The BASE heredoc delimiter the script writes its fallback text through. A QUOTED heredoc expands
158
+ * nothing — `$`, backticks, quotes and backslashes in the intent are inert — so the only way the
159
+ * caller-supplied text could break out is a line equal to the delimiter. That line is never
160
+ * removed or altered (it may be the title itself — Copilot on #525): {@link heredocDelimiter}
161
+ * picks a delimiter no line of the text equals, so the text rides verbatim and the heredoc still
162
+ * ends exactly where the script says it ends.
163
+ */
164
+ export declare const DELIVER_TEXT_HEREDOC = "WICKED_CREW_DELIVER_TEXT_EOF";
165
+ /**
166
+ * The framed PR/commit text as heredoc body lines. This is a containment boundary, not cosmetics:
167
+ * the intent is caller-supplied free text off `POST /runs` and it is being spliced into a bash
168
+ * script. CR and every control character other than tab and newline are removed (a bare CR could
169
+ * split a line in the CLI's eyes); nothing else is touched.
170
+ */
171
+ export declare function heredocLines(framed: string): string[];
172
+ /**
173
+ * A heredoc delimiter none of `lines` equals: the base, or the base with a numeric suffix
174
+ * (`…_EOF_1`, `…_EOF_2`, …) when the text happens to carry the base as a whole line. The framing
175
+ * (line 1 = title) is therefore never disturbed by containment.
176
+ */
177
+ export declare function heredocDelimiter(lines: readonly string[]): string;
92
178
  /**
93
179
  * The hardened deliver script, run as `bash -lc <script>` (login shell so the operator's PATH —
94
180
  * where `gh` lives — is loaded, same as the field overlay).
@@ -98,10 +184,11 @@ export declare const DELIVER_LIFT_CONFLICT_MARKER = "deliver: LIFT-CONFLICT";
98
184
  * `StepStatus::Failed`. It is no longer the ONLY thing standing between a failed `gh` and a green
99
185
  * phase, though — the gh result is captured explicitly and success is re-derived from evidence.
100
186
  *
101
- * `intent` (the run's problem statement) rides in the commit subject; it is sanitised by
102
- * {@link commitSubjectIntent} before it is spliced in.
187
+ * `intent` (the run's problem statement) is what the PR title and the commit subject are composed
188
+ * from (`core/deliver-text.ts`); `opts` carries the rest of the launch-time facts and the daemon
189
+ * origin the script asks for the run-derived text (crew#524).
103
190
  */
104
- export declare function deliverPrScript(intent?: string): string;
191
+ export declare function deliverPrScript(intent?: string, opts?: DeliverScriptOptions): string;
105
192
  /**
106
193
  * The deliver phase definition — the PhaseDef JSON shape core accepts, fully spelled out so the
107
194
  * composed def round-trips through `registerWorkflow` (core's serde) and crew's own `WorkflowDef`
@@ -133,19 +220,26 @@ export declare function deliverPrScript(intent?: string): string;
133
220
  * deterministic and costs no LLM call. The PR-URL and branch-ahead assertions stay in the script
134
221
  * because no vaulted floor can see the remote.
135
222
  */
136
- export declare function deliverPrPhase(dependsOn?: string[], intent?: string): PhaseDef;
223
+ export declare function deliverPrPhase(dependsOn?: string[], intent?: string, opts?: DeliverScriptOptions): PhaseDef;
137
224
  /**
138
225
  * Compose a PER-RUN workflow def: `base`'s phases (untouched — the shared def is never mutated)
139
226
  * plus the deliver phase appended last, under a run-scoped id. The caller registers the result
140
227
  * with the engine for THIS run only; nothing is written to the overlay dir and the composed id
141
228
  * never enters the user-workflow registry, so the catalog (`GET /workflows`) stays clean.
142
229
  *
143
- * `intent` is the run's problem statement — it names WHAT was delivered in the commit subject
144
- * (`wicked-crew run <run-id>: <intent>`); omit it and the subject carries the run id alone.
230
+ * `intent` is the run's problem statement — the PR title and commit subject are composed from it
231
+ * (`core/deliver-text.ts`); omit it and they name the run id alone. `launch` carries what else is
232
+ * known here (the repo, the daemon's own origin) so the phase's embedded fallback text names the
233
+ * workflow, its phases and the run link, and so the script knows which daemon to ask for the
234
+ * run-derived text at delivery time (crew#524).
145
235
  *
146
236
  * Throws when `base` already carries a `deliver` phase — appending a second phase with the same
147
237
  * id would be ambiguous at best; the caller launches such a def as-is instead (see
148
238
  * `CoreAdapter.launchRun`).
149
239
  */
150
- export declare function composeDeliverWorkflow(base: WorkflowDef, runId: string, intent?: string): WorkflowDef;
240
+ export interface DeliverLaunchContext {
241
+ repoRef?: string | null;
242
+ apiOrigin?: string | null;
243
+ }
244
+ export declare function composeDeliverWorkflow(base: WorkflowDef, runId: string, intent?: string, launch?: DeliverLaunchContext): WorkflowDef;
151
245
  //# sourceMappingURL=deliver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/core/deliver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAErD,2FAA2F;AAC3F,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AA0BrE;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAyMvD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,cAAc,CAAC,SAAS,GAAE,MAAM,EAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAgBlF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd,WAAW,CAmBb"}
1
+ {"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/core/deliver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAErD,2FAA2F;AAC3F,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AAErE;yDACyD;AACzD,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;0EACsE;IACtE,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;uFACmF;IACnF,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,iCAAiC,CAAC;AAExE;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,2CAA2C,CAAC;AAElF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,2BAA2B,CAAC;AAE5D;;;;;;;;GAQG;AACH,eAAO,MAAM,gCAAgC,iDAAiD,CAAC;AAE/F;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,iCAAiC,CAAC;AAEnE;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAIjE;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,MAAM,CAsUxF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,cAAc,CAC5B,SAAS,GAAE,MAAM,EAAO,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,IAAI,GAAE,oBAAyB,GAC9B,QAAQ,CAgBV;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,GAAE,oBAAyB,GAChC,WAAW,CA+Bb"}