@nexrall/code-core 1.4.76 → 1.4.77

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 (110) hide show
  1. package/dist/agent/goal.d.ts +55 -0
  2. package/dist/agent/goal.d.ts.map +1 -0
  3. package/dist/agent/goal.js +120 -0
  4. package/dist/agent/handoffBrief.d.ts +82 -0
  5. package/dist/agent/handoffBrief.d.ts.map +1 -0
  6. package/dist/agent/handoffBrief.js +121 -0
  7. package/dist/agent/modelCatalogue.d.ts +23 -0
  8. package/dist/agent/modelCatalogue.d.ts.map +1 -1
  9. package/dist/agent/modelCatalogue.js +28 -0
  10. package/dist/agent/outputStyles.d.ts +27 -0
  11. package/dist/agent/outputStyles.d.ts.map +1 -0
  12. package/dist/agent/outputStyles.js +174 -0
  13. package/dist/agent/skills.d.ts.map +1 -1
  14. package/dist/agent/skills.js +7 -0
  15. package/dist/api/billingLines.d.ts +11 -0
  16. package/dist/api/billingLines.d.ts.map +1 -0
  17. package/dist/api/billingLines.js +56 -0
  18. package/dist/api/client.d.ts +2 -0
  19. package/dist/api/client.d.ts.map +1 -1
  20. package/dist/api/scheduleLines.d.ts +53 -0
  21. package/dist/api/scheduleLines.d.ts.map +1 -0
  22. package/dist/api/scheduleLines.js +150 -0
  23. package/dist/context/contextFiles.d.ts +81 -0
  24. package/dist/context/contextFiles.d.ts.map +1 -0
  25. package/dist/context/contextFiles.js +310 -0
  26. package/dist/diff/collect.d.ts +25 -0
  27. package/dist/diff/collect.d.ts.map +1 -0
  28. package/dist/diff/collect.js +169 -0
  29. package/dist/diff/diffView.d.ts +57 -0
  30. package/dist/diff/diffView.d.ts.map +1 -0
  31. package/dist/diff/diffView.js +231 -0
  32. package/dist/diff/reviewQueue.d.ts +53 -0
  33. package/dist/diff/reviewQueue.d.ts.map +1 -0
  34. package/dist/diff/reviewQueue.js +349 -0
  35. package/dist/events/recap.d.ts +54 -0
  36. package/dist/events/recap.d.ts.map +1 -0
  37. package/dist/events/recap.js +161 -0
  38. package/dist/events/sessionEvents.d.ts +54 -0
  39. package/dist/events/sessionEvents.d.ts.map +1 -0
  40. package/dist/events/sessionEvents.js +324 -0
  41. package/dist/events/sessionStats.d.ts +89 -0
  42. package/dist/events/sessionStats.d.ts.map +1 -0
  43. package/dist/events/sessionStats.js +264 -0
  44. package/dist/import/claudeImport.d.ts +44 -0
  45. package/dist/import/claudeImport.d.ts.map +1 -0
  46. package/dist/import/claudeImport.js +337 -0
  47. package/dist/index.d.ts +33 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +33 -0
  50. package/dist/project/projectCommands.d.ts +33 -0
  51. package/dist/project/projectCommands.d.ts.map +1 -0
  52. package/dist/project/projectCommands.js +246 -0
  53. package/dist/search/conversationTurns.d.ts +53 -0
  54. package/dist/search/conversationTurns.d.ts.map +1 -0
  55. package/dist/search/conversationTurns.js +170 -0
  56. package/dist/search/globalSearch.d.ts +144 -0
  57. package/dist/search/globalSearch.d.ts.map +1 -0
  58. package/dist/search/globalSearch.js +350 -0
  59. package/dist/share/sessionChannel.d.ts +136 -0
  60. package/dist/share/sessionChannel.d.ts.map +1 -0
  61. package/dist/share/sessionChannel.js +373 -0
  62. package/dist/share/sessionShare.d.ts +104 -0
  63. package/dist/share/sessionShare.d.ts.map +1 -0
  64. package/dist/share/sessionShare.js +336 -0
  65. package/dist/ui/configCmd.d.ts +48 -0
  66. package/dist/ui/configCmd.d.ts.map +1 -0
  67. package/dist/ui/configCmd.js +146 -0
  68. package/dist/ui/deployPanel.d.ts +91 -0
  69. package/dist/ui/deployPanel.d.ts.map +1 -0
  70. package/dist/ui/deployPanel.js +442 -0
  71. package/dist/ui/mergeAssistant.d.ts +120 -0
  72. package/dist/ui/mergeAssistant.d.ts.map +1 -0
  73. package/dist/ui/mergeAssistant.js +391 -0
  74. package/dist/ui/notify.d.ts +114 -0
  75. package/dist/ui/notify.d.ts.map +1 -0
  76. package/dist/ui/notify.js +235 -0
  77. package/dist/ui/promptSuggest.d.ts +56 -0
  78. package/dist/ui/promptSuggest.d.ts.map +1 -0
  79. package/dist/ui/promptSuggest.js +160 -0
  80. package/dist/ui/taskGraph.d.ts +44 -0
  81. package/dist/ui/taskGraph.d.ts.map +1 -0
  82. package/dist/ui/taskGraph.js +289 -0
  83. package/dist/util/addDir.d.ts +31 -0
  84. package/dist/util/addDir.d.ts.map +1 -0
  85. package/dist/util/addDir.js +124 -0
  86. package/dist/util/batch.d.ts +16 -0
  87. package/dist/util/batch.d.ts.map +1 -0
  88. package/dist/util/batch.js +92 -0
  89. package/dist/util/cellWidth.d.ts +12 -0
  90. package/dist/util/cellWidth.d.ts.map +1 -0
  91. package/dist/util/cellWidth.js +161 -0
  92. package/dist/util/duration.d.ts +8 -0
  93. package/dist/util/duration.d.ts.map +1 -0
  94. package/dist/util/duration.js +50 -0
  95. package/dist/util/loopJobs.d.ts +67 -0
  96. package/dist/util/loopJobs.d.ts.map +1 -0
  97. package/dist/util/loopJobs.js +169 -0
  98. package/dist/util/settingsFile.d.ts +14 -0
  99. package/dist/util/settingsFile.d.ts.map +1 -0
  100. package/dist/util/settingsFile.js +99 -0
  101. package/dist/util/toolLabel.d.ts +2 -0
  102. package/dist/util/toolLabel.d.ts.map +1 -0
  103. package/dist/util/toolLabel.js +17 -0
  104. package/dist/verify/failureTimeline.d.ts +100 -0
  105. package/dist/verify/failureTimeline.d.ts.map +1 -0
  106. package/dist/verify/failureTimeline.js +253 -0
  107. package/dist/verify/verification.d.ts +75 -0
  108. package/dist/verify/verification.d.ts.map +1 -0
  109. package/dist/verify/verification.js +315 -0
  110. package/package.json +5 -4
@@ -0,0 +1,55 @@
1
+ export type GoalVerdictKind = 'met' | 'not_yet' | 'impossible';
2
+ export interface GoalVerdict {
3
+ kind: GoalVerdictKind;
4
+ reason: string;
5
+ }
6
+ /** Hard ceiling on automatic continuations for one goal: a goal must never be an infinite spend. */
7
+ export declare const MAX_GOAL_TURNS = 25;
8
+ /** Longest condition accepted — it is pasted into every judge prompt. */
9
+ export declare const MAX_GOAL_CHARS = 2000;
10
+ export type GoalArgs = {
11
+ kind: 'show';
12
+ } | {
13
+ kind: 'clear';
14
+ } | {
15
+ kind: 'set';
16
+ condition: string;
17
+ } | {
18
+ kind: 'error';
19
+ message: string;
20
+ };
21
+ /** `/goal` → show, `/goal clear|off|stop|none|cancel` → clear, anything else → the condition. */
22
+ export declare function parseGoalArgs(arg: string): GoalArgs;
23
+ export declare function buildJudgePrompt(condition: string, lastReply: string, turnsSoFar: number): string;
24
+ /**
25
+ * Read the judge's reply. Anything that is not a clear verdict becomes `not_yet`
26
+ * with an honest reason — an unparseable judge must never count as "met" (that would
27
+ * stop work early and report success nobody checked).
28
+ */
29
+ export declare function parseJudgeReply(reply: string): GoalVerdict;
30
+ /** The prompt that goes back to the agent when the goal is not met yet. */
31
+ export declare function continuationPrompt(condition: string, reason: string): string;
32
+ export interface GoalState {
33
+ condition: string;
34
+ /** Automatic continuations spent on this goal (a turn the user typed does not count). */
35
+ turns: number;
36
+ startedAt: number;
37
+ }
38
+ export type GoalStep = {
39
+ action: 'stop-met';
40
+ reason: string;
41
+ } | {
42
+ action: 'stop-impossible';
43
+ reason: string;
44
+ } | {
45
+ action: 'stop-limit';
46
+ } | {
47
+ action: 'stop-aborted';
48
+ } | {
49
+ action: 'continue';
50
+ prompt: string;
51
+ };
52
+ /** What to do after a turn, given the verdict. The turn cap is checked BEFORE continuing. */
53
+ export declare function nextGoalStep(state: GoalState, verdict: GoalVerdict, aborted: boolean): GoalStep;
54
+ export declare function formatGoalStatus(state: GoalState | null): string[];
55
+ //# sourceMappingURL=goal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal.d.ts","sourceRoot":"","sources":["../../src/agent/goal.ts"],"names":[],"mappings":"AAaA,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;AAC/D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oGAAoG;AACpG,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,yEAAyE;AACzE,eAAO,MAAM,cAAc,OAAO,CAAC;AAInC,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,iGAAiG;AACjG,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAQnD;AAWD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAajG;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAmB1D;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,QAAQ,GAChB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,GAC1B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,CAM/F;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAclE"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ // Lives in core (moved from the CLI's ui/goal.ts, 2026-10-04) so the VS Code
3
+ // panel runs the same judge loop; the CLI module is a re-export shim.
4
+ // /goal — a session-scoped completion condition. After every turn a small judge
5
+ // model reads what the agent just did and answers one of three things:
6
+ //
7
+ // met the condition is satisfied → the loop stops, goal clears
8
+ // not_yet still work to do → the reason is fed back as the next prompt
9
+ // impossible it cannot be reached from here → stop and say why (never loop forever)
10
+ //
11
+ // This file is pure: parsing, prompt building, argument handling and the loop's
12
+ // stop rules. chat.ts owns the model call and the turn runner, so every rule that
13
+ // decides "keep going or stop" can be tested without a network.
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MAX_GOAL_CHARS = exports.MAX_GOAL_TURNS = void 0;
16
+ exports.parseGoalArgs = parseGoalArgs;
17
+ exports.buildJudgePrompt = buildJudgePrompt;
18
+ exports.parseJudgeReply = parseJudgeReply;
19
+ exports.continuationPrompt = continuationPrompt;
20
+ exports.nextGoalStep = nextGoalStep;
21
+ exports.formatGoalStatus = formatGoalStatus;
22
+ /** Hard ceiling on automatic continuations for one goal: a goal must never be an infinite spend. */
23
+ exports.MAX_GOAL_TURNS = 25;
24
+ /** Longest condition accepted — it is pasted into every judge prompt. */
25
+ exports.MAX_GOAL_CHARS = 2000;
26
+ /** How much of the agent's last reply the judge sees. */
27
+ const MAX_EVIDENCE_CHARS = 6000;
28
+ /** `/goal` → show, `/goal clear|off|stop|none|cancel` → clear, anything else → the condition. */
29
+ function parseGoalArgs(arg) {
30
+ const text = String(arg ?? '').trim();
31
+ if (!text)
32
+ return { kind: 'show' };
33
+ if (/^(clear|off|stop|none|cancel|reset)$/i.test(text))
34
+ return { kind: 'clear' };
35
+ if (text.length > exports.MAX_GOAL_CHARS) {
36
+ return { kind: 'error', message: `The goal is ${text.length} characters; keep it under ${exports.MAX_GOAL_CHARS}.` };
37
+ }
38
+ return { kind: 'set', condition: text };
39
+ }
40
+ const JUDGE_RULES = 'You judge whether a coding agent has finished a task. You are given the completion condition and ' +
41
+ "the agent's latest report. Judge ONLY from that evidence — if the report does not show the condition " +
42
+ 'holds (for example it claims success without naming a check that was run), it is NOT met. ' +
43
+ 'Reply with ONLY one JSON object and nothing else: ' +
44
+ '{"verdict":"met"|"not_yet"|"impossible","reason":"one short sentence"}. ' +
45
+ 'Use "impossible" only when the condition cannot be reached without something the agent does not have ' +
46
+ '(a missing credential, a contradiction, an unavailable service) — not merely because it is hard.';
47
+ function buildJudgePrompt(condition, lastReply, turnsSoFar) {
48
+ const evidence = String(lastReply ?? '').trim();
49
+ const clipped = evidence.length > MAX_EVIDENCE_CHARS ? '…' + evidence.slice(evidence.length - MAX_EVIDENCE_CHARS) : evidence;
50
+ return [
51
+ JUDGE_RULES,
52
+ '',
53
+ `Completion condition:\n${condition}`,
54
+ '',
55
+ `Turns spent so far on this goal: ${turnsSoFar}`,
56
+ '',
57
+ `Agent's latest report:\n${clipped || '(the agent produced no text this turn)'}`,
58
+ ].join('\n');
59
+ }
60
+ /**
61
+ * Read the judge's reply. Anything that is not a clear verdict becomes `not_yet`
62
+ * with an honest reason — an unparseable judge must never count as "met" (that would
63
+ * stop work early and report success nobody checked).
64
+ */
65
+ function parseJudgeReply(reply) {
66
+ const text = String(reply ?? '');
67
+ const start = text.indexOf('{');
68
+ const end = text.lastIndexOf('}');
69
+ if (start >= 0 && end > start) {
70
+ try {
71
+ const j = JSON.parse(text.slice(start, end + 1));
72
+ const v = String(j.verdict ?? '')
73
+ .toLowerCase()
74
+ .replace(/[\s-]+/g, '_');
75
+ const reason = typeof j.reason === 'string' && j.reason.trim() ? j.reason.trim() : '';
76
+ if (v === 'met')
77
+ return { kind: 'met', reason: reason || 'condition satisfied' };
78
+ if (v === 'impossible')
79
+ return { kind: 'impossible', reason: reason || 'cannot be reached' };
80
+ if (v === 'not_yet' || v === 'notyet')
81
+ return { kind: 'not_yet', reason: reason || 'not done yet' };
82
+ }
83
+ catch {
84
+ /* fall through */
85
+ }
86
+ }
87
+ return { kind: 'not_yet', reason: 'the judge gave no usable verdict' };
88
+ }
89
+ /** The prompt that goes back to the agent when the goal is not met yet. */
90
+ function continuationPrompt(condition, reason) {
91
+ return `The goal is not met yet. Goal: ${condition}\nWhy: ${reason}\nKeep working until it is satisfied; when you think it is, say what you ran or checked that proves it.`;
92
+ }
93
+ /** What to do after a turn, given the verdict. The turn cap is checked BEFORE continuing. */
94
+ function nextGoalStep(state, verdict, aborted) {
95
+ if (aborted)
96
+ return { action: 'stop-aborted' };
97
+ if (verdict.kind === 'met')
98
+ return { action: 'stop-met', reason: verdict.reason };
99
+ if (verdict.kind === 'impossible')
100
+ return { action: 'stop-impossible', reason: verdict.reason };
101
+ if (state.turns >= exports.MAX_GOAL_TURNS)
102
+ return { action: 'stop-limit' };
103
+ return { action: 'continue', prompt: continuationPrompt(state.condition, verdict.reason) };
104
+ }
105
+ function formatGoalStatus(state) {
106
+ if (!state) {
107
+ return [
108
+ 'No goal is set.',
109
+ 'Set one: /goal <condition> e.g. /goal all tests in packages/cli pass',
110
+ 'Clear it: /goal clear',
111
+ ];
112
+ }
113
+ const mins = Math.max(0, Math.round((Date.now() - state.startedAt) / 60000));
114
+ return [
115
+ `Goal: ${state.condition}`,
116
+ `${state.turns} automatic turn${state.turns === 1 ? '' : 's'} so far (max ${exports.MAX_GOAL_TURNS}) · ${mins} min`,
117
+ 'Clear it with /goal clear; Esc stops the current turn and the goal with it.',
118
+ ];
119
+ }
120
+ //# sourceMappingURL=goal.js.map
@@ -0,0 +1,82 @@
1
+ export interface HandoffFile {
2
+ path: string;
3
+ status: string;
4
+ additions: number;
5
+ deletions: number;
6
+ }
7
+ export interface HandoffFailure {
8
+ command: string;
9
+ exitCode: number | null;
10
+ files: string[];
11
+ retests?: {
12
+ command: string;
13
+ ok: boolean;
14
+ }[];
15
+ }
16
+ export interface HandoffCriterion {
17
+ label: string;
18
+ status: 'pass' | 'fail' | 'pending';
19
+ }
20
+ export interface HandoffCheck {
21
+ kind: string;
22
+ ok: boolean;
23
+ command: string;
24
+ testsPassed?: number;
25
+ }
26
+ /** Everything a receiving agent should know, gathered from the live session. */
27
+ export interface HandoffState {
28
+ /** The last real user prompt — what the session is working on. */
29
+ goal?: string;
30
+ /** Where the handoff goes (agent type); absent in print mode. */
31
+ to?: string;
32
+ /** The user's extra instructions for the receiving agent. */
33
+ instructions?: string;
34
+ branch?: string;
35
+ /** Uncommitted changes, straight from the diff. */
36
+ files?: HandoffFile[];
37
+ /** The most recent failure chain that never passed a re-run. */
38
+ failure?: HandoffFailure;
39
+ /** Criteria the user accepted via /accept, with their current verdicts. */
40
+ criteria?: HandoffCriterion[];
41
+ /** Latest check run per kind, from the §83 ledger. */
42
+ checks?: HandoffCheck[];
43
+ /** One-line extras (worktree isolation, pins, …). */
44
+ notes?: string[];
45
+ }
46
+ export declare const MAX_HANDOFF_FILES = 15;
47
+ export declare const MAX_HANDOFF_RETESTS = 3;
48
+ export declare const MAX_HANDOFF_CRITERIA = 8;
49
+ export declare const MAX_HANDOFF_NOTES = 6;
50
+ /**
51
+ * Plain-text sections with tail caps, no width fitting — the single source both the
52
+ * printed panel (fitted per line) and the delegation prompt (full width) render from.
53
+ */
54
+ export declare function briefSections(state: HandoffState): {
55
+ heading: string;
56
+ lines: string[];
57
+ }[];
58
+ /**
59
+ * The turn text for `/handoff <type> …`: an instruction to delegate through the task
60
+ * tool, the brief itself, and the user's extra instructions. The wording closes the two
61
+ * ways this goes wrong — the main agent doing the work itself, or paraphrasing the
62
+ * brief into something the sub-agent that sees only this text cannot recover from.
63
+ */
64
+ export declare function handoffPrompt(state: HandoffState & {
65
+ to: string;
66
+ }): string;
67
+ export type ParsedHandoff = {
68
+ mode: 'print';
69
+ } | {
70
+ mode: 'delegate';
71
+ agentType: string;
72
+ instructions?: string;
73
+ } | {
74
+ error: string;
75
+ };
76
+ /**
77
+ * First token selects the agent type, case-insensitively. No args means "print the
78
+ * brief"; an unknown first token is an error rather than a silent print, so a typo
79
+ * never looks like a successful delegation.
80
+ */
81
+ export declare function parseHandoffArgs(arg: string, knownTypes: string[]): ParsedHandoff;
82
+ //# sourceMappingURL=handoffBrief.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoffBrief.d.ts","sourceRoot":"","sources":["../../src/agent/handoffBrief.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAC9C;AACD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACrC;AACD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,gEAAgE;IAChE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B,sDAAsD;IACtD,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAWnC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAwDzF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgB1E;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,aAAa,CAgBjF"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ // The pure half of /handoff (spec §81): types, section building, the delegation
3
+ // prompt and argument parsing. Moved to core from the CLI's ui/handoffBrief.ts
4
+ // (2026-10-04) so the VS Code panel builds the SAME brief; the CLI module keeps
5
+ // the ANSI-rendered formatter and re-exports everything else.
6
+ // Spec §81 — Agent Handoff: one agent hands a task to another with the structured
7
+ // state a fresh context window needs — the goal, the files in play, the open
8
+ // failure, the accepted criteria and the latest check runs. Pure parsing and
9
+ // formatting; chat.ts gathers the live session state and either prints the brief
10
+ // or turns it into the prompt for a task-tool delegation.
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MAX_HANDOFF_NOTES = exports.MAX_HANDOFF_CRITERIA = exports.MAX_HANDOFF_RETESTS = exports.MAX_HANDOFF_FILES = void 0;
13
+ exports.briefSections = briefSections;
14
+ exports.handoffPrompt = handoffPrompt;
15
+ exports.parseHandoffArgs = parseHandoffArgs;
16
+ exports.MAX_HANDOFF_FILES = 15;
17
+ exports.MAX_HANDOFF_RETESTS = 3;
18
+ exports.MAX_HANDOFF_CRITERIA = 8;
19
+ exports.MAX_HANDOFF_NOTES = 6;
20
+ const STATUS_LETTER = {
21
+ added: 'A',
22
+ modified: 'M',
23
+ deleted: 'D',
24
+ renamed: 'R',
25
+ binary: 'B',
26
+ };
27
+ const VERDICT_GLYPH = { pass: '✓', fail: '✗', pending: '·' };
28
+ /**
29
+ * Plain-text sections with tail caps, no width fitting — the single source both the
30
+ * printed panel (fitted per line) and the delegation prompt (full width) render from.
31
+ */
32
+ function briefSections(state) {
33
+ const out = [];
34
+ const push = (heading, lines, cap) => {
35
+ if (!lines.length)
36
+ return;
37
+ const shown = lines.length > cap ? [...lines.slice(0, cap), `… +${lines.length - cap} more`] : lines;
38
+ out.push({ heading, lines: shown });
39
+ };
40
+ if (state.goal)
41
+ push('Goal', [state.goal], 1);
42
+ const context = [];
43
+ if (state.branch)
44
+ context.push(`branch ${state.branch}`);
45
+ if (state.notes?.length)
46
+ context.push(...state.notes.slice(0, exports.MAX_HANDOFF_NOTES));
47
+ push('Context', context, context.length);
48
+ if (state.files?.length) {
49
+ push('Files in play', state.files.map((f) => `${STATUS_LETTER[f.status] ?? '?'} ${f.path} (+${f.additions} −${f.deletions})`), exports.MAX_HANDOFF_FILES);
50
+ }
51
+ if (state.failure) {
52
+ const lines = [state.failure.command];
53
+ if (state.failure.exitCode !== null && state.failure.exitCode !== undefined) {
54
+ lines.push(`exited ${state.failure.exitCode}`);
55
+ }
56
+ if (state.failure.files.length) {
57
+ lines.push(`files touched while it was open: ${state.failure.files.slice(0, 5).join(', ')}`);
58
+ }
59
+ for (const r of (state.failure.retests ?? []).slice(-exports.MAX_HANDOFF_RETESTS)) {
60
+ lines.push(`retest ${r.ok ? 'passed' : 'failed'}: ${r.command}`);
61
+ }
62
+ out.push({ heading: 'Unresolved failure', lines });
63
+ }
64
+ if (state.criteria?.length) {
65
+ push('Accepted criteria', state.criteria.map((c) => `${VERDICT_GLYPH[c.status]} ${c.label}`), exports.MAX_HANDOFF_CRITERIA);
66
+ }
67
+ if (state.checks?.length) {
68
+ push('Checks (latest per kind)', state.checks.map((c) => {
69
+ const tests = c.testsPassed !== undefined ? ` · ${c.testsPassed} tests passed` : '';
70
+ return `${c.ok ? '✓' : '✗'} ${c.kind}${tests} · ${c.command}`;
71
+ }), state.checks.length);
72
+ }
73
+ return out;
74
+ }
75
+ /**
76
+ * The turn text for `/handoff <type> …`: an instruction to delegate through the task
77
+ * tool, the brief itself, and the user's extra instructions. The wording closes the two
78
+ * ways this goes wrong — the main agent doing the work itself, or paraphrasing the
79
+ * brief into something the sub-agent that sees only this text cannot recover from.
80
+ */
81
+ function handoffPrompt(state) {
82
+ const sections = briefSections(state);
83
+ const brief = sections.length
84
+ ? sections.map((s) => `${s.heading}:\n${s.lines.map((l) => ` ${l}`).join('\n')}`).join('\n\n')
85
+ : '(nothing was recorded — use the user instructions below as the whole task)';
86
+ const lines = [
87
+ `Hand this off to a \`${state.to}\` sub-agent with the task tool (subagent_type: "${state.to}").`,
88
+ 'Pass the brief below as its `prompt` — the sub-agent sees ONLY that, never this conversation. ' +
89
+ 'Do not do the work yourself in this turn; after it returns, relay the parts of its report that matter.',
90
+ '',
91
+ brief,
92
+ ];
93
+ if (state.instructions) {
94
+ lines.push('', `Extra instructions from the user (include them in the prompt): ${state.instructions}`);
95
+ }
96
+ return lines.join('\n');
97
+ }
98
+ /**
99
+ * First token selects the agent type, case-insensitively. No args means "print the
100
+ * brief"; an unknown first token is an error rather than a silent print, so a typo
101
+ * never looks like a successful delegation.
102
+ */
103
+ function parseHandoffArgs(arg, knownTypes) {
104
+ const trimmed = arg.trim();
105
+ if (!trimmed)
106
+ return { mode: 'print' };
107
+ const sp = trimmed.search(/\s/);
108
+ const head = (sp === -1 ? trimmed : trimmed.slice(0, sp)).toLowerCase();
109
+ const rest = sp === -1 ? '' : trimmed.slice(sp + 1).trim();
110
+ const match = knownTypes.find((t) => t.toLowerCase() === head);
111
+ if (!match) {
112
+ if (!knownTypes.length) {
113
+ return { error: 'no sub-agent types are configured in this project — /agents types shows what exists' };
114
+ }
115
+ return {
116
+ error: `unknown agent type "${sp === -1 ? trimmed : trimmed.slice(0, sp)}". Available: ${knownTypes.join(', ')}`,
117
+ };
118
+ }
119
+ return { mode: 'delegate', agentType: match, instructions: rest || undefined };
120
+ }
121
+ //# sourceMappingURL=handoffBrief.js.map
@@ -56,6 +56,29 @@ export declare function liveVendorFor(id: string | undefined): string | undefine
56
56
  export declare function liveLabelFor(id: string | undefined, fallback: string): string;
57
57
  /** Live relative cost multiplier for `id`, or `fallback` when unknown. */
58
58
  export declare function liveCostMultiplierFor(id: string | undefined, fallback: number | undefined): number | undefined;
59
+ /**
60
+ * Live per-1M-token prices (USD, input/output) for `id`, or `fallback` when
61
+ * the catalogue has not loaded or predates the price fields. Mirrors
62
+ * liveCostMultiplierFor's contract exactly; render the result with
63
+ * formatModelPrice below so every client shows the identical string.
64
+ */
65
+ export declare function livePriceFor(id: string | undefined, fallback?: {
66
+ input: number;
67
+ output: number;
68
+ }): {
69
+ input: number;
70
+ output: number;
71
+ } | undefined;
72
+ /**
73
+ * `$2/$10` — the ONE label for a per-1M price pair (USD, vendor list before
74
+ * markup). Trailing zeros are trimmed on purpose to fit the fixed-width
75
+ * picker rows. The VS Code webview's inline twin and web/app's
76
+ * formatModelPrice must render the identical string; keep all three in step.
77
+ */
78
+ export declare function formatModelPrice(p: {
79
+ input: number;
80
+ output: number;
81
+ }): string;
59
82
  /**
60
83
  * The list of selectable model ids the live catalogue offers, or null when
61
84
  * no catalogue has been fetched yet — callers fall back to their own static
@@ -1 +1 @@
1
- {"version":3,"file":"modelCatalogue.d.ts","sourceRoot":"","sources":["../../src/agent/modelCatalogue.ts"],"names":[],"mappings":"AAgDA,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAiBlE;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAuBnE;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,IAAI;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAElG;AAOD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,sDAAsD;AACtD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAGzF;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAGvF;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEnF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG9G;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,GAAG,IAAI,CAExD;AAED,kEAAkE;AAClE,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAU/C,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAW3F;AAED,6GAA6G;AAC7G,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,GAAG,SAAS,CAIpB;AAED,8DAA8D;AAC9D,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,GAAG,IAAI,CAE9E"}
1
+ {"version":3,"file":"modelCatalogue.d.ts","sourceRoot":"","sources":["../../src/agent/modelCatalogue.ts"],"names":[],"mappings":"AAgDA,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAiBlE;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7B,OAAO,CAAC;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAuBnE;AAED,iFAAiF;AACjF,wBAAgB,uBAAuB,IAAI;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAElG;AAOD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,sDAAsD;AACtD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAGzF;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAGvF;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEnF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7E;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG9G;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,QAAQ,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAM/C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,GAAG,IAAI,CAExD;AAED,kEAAkE;AAClE,wBAAgB,iCAAiC,IAAI,IAAI,CAGxD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAU/C,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAW3F;AAED,6GAA6G;AAC7G,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,GAAG,SAAS,CAIpB;AAED,8DAA8D;AAC9D,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,GAAG,IAAI,CAE9E"}
@@ -58,6 +58,8 @@ exports.liveReasoningEffortStyle = liveReasoningEffortStyle;
58
58
  exports.liveVendorFor = liveVendorFor;
59
59
  exports.liveLabelFor = liveLabelFor;
60
60
  exports.liveCostMultiplierFor = liveCostMultiplierFor;
61
+ exports.livePriceFor = livePriceFor;
62
+ exports.formatModelPrice = formatModelPrice;
61
63
  exports.liveSelectableModelIds = liveSelectableModelIds;
62
64
  exports._resetModelCatalogueCacheForTests = _resetModelCatalogueCacheForTests;
63
65
  exports.cheapestSameVendorModel = cheapestSameVendorModel;
@@ -171,6 +173,32 @@ function liveCostMultiplierFor(id, fallback) {
171
173
  const m = findModel(id);
172
174
  return m && typeof m.costMultiplier === 'number' ? m.costMultiplier : fallback;
173
175
  }
176
+ /**
177
+ * Live per-1M-token prices (USD, input/output) for `id`, or `fallback` when
178
+ * the catalogue has not loaded or predates the price fields. Mirrors
179
+ * liveCostMultiplierFor's contract exactly; render the result with
180
+ * formatModelPrice below so every client shows the identical string.
181
+ */
182
+ function livePriceFor(id, fallback) {
183
+ const m = findModel(id);
184
+ if (m && typeof m.inputPrice === 'number' && typeof m.outputPrice === 'number') {
185
+ return { input: m.inputPrice, output: m.outputPrice };
186
+ }
187
+ return fallback;
188
+ }
189
+ /**
190
+ * `$2/$10` — the ONE label for a per-1M price pair (USD, vendor list before
191
+ * markup). Trailing zeros are trimmed on purpose to fit the fixed-width
192
+ * picker rows. The VS Code webview's inline twin and web/app's
193
+ * formatModelPrice must render the identical string; keep all three in step.
194
+ */
195
+ function formatModelPrice(p) {
196
+ // '—' rather than 'NaN' if a caller ever hands in a non-finite number: the
197
+ // wire cannot actually carry one (JSON turns NaN into null, and a null pair
198
+ // fails livePriceFor's typeof check), so this is display insurance only.
199
+ const fmt = (n) => (Number.isFinite(n) ? String(Math.round(n * 1000) / 1000) : '—');
200
+ return `$${fmt(p.input)}/$${fmt(p.output)}`;
201
+ }
174
202
  /**
175
203
  * The list of selectable model ids the live catalogue offers, or null when
176
204
  * no catalogue has been fetched yet — callers fall back to their own static
@@ -0,0 +1,27 @@
1
+ export interface OutputStyle {
2
+ name: string;
3
+ description: string;
4
+ /** The instructions added to the system prompt. Empty for the default style. */
5
+ prompt: string;
6
+ source: 'built-in' | 'user' | 'project';
7
+ }
8
+ export declare const DEFAULT_STYLE = "default";
9
+ /** A style is injected into every prompt; cap it so a stray huge file cannot eat the context. */
10
+ export declare const MAX_STYLE_CHARS = 4000;
11
+ export declare const BUILT_IN_STYLES: readonly OutputStyle[];
12
+ /** Splits optional `---` front matter off a style file. Unknown keys are ignored. */
13
+ export declare function parseStyleFile(text: string): {
14
+ description: string;
15
+ body: string;
16
+ };
17
+ export declare function listOutputStyles(workDir: string, home?: string): OutputStyle[];
18
+ export declare function findOutputStyle(styles: readonly OutputStyle[], name: string): OutputStyle | undefined;
19
+ /** The settings value → a style name, defaulting safely for anything unusable. */
20
+ export declare function readStyleSetting(raw: Record<string, unknown> | undefined | null): string;
21
+ /**
22
+ * The text to add to the system prompt for the chosen style, or undefined for none.
23
+ * A style that no longer exists (file deleted) resolves to none rather than failing the session.
24
+ */
25
+ export declare function styleInstructions(styles: readonly OutputStyle[], name: string): string | undefined;
26
+ export declare function formatStyleList(styles: readonly OutputStyle[], current: string): string[];
27
+ //# sourceMappingURL=outputStyles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputStyles.d.ts","sourceRoot":"","sources":["../../src/agent/outputStyles.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,iGAAiG;AACjG,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,eAAO,MAAM,eAAe,EAAE,SAAS,WAAW,EAuBjD,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUlF;AAsCD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAqB,GAAG,WAAW,EAAE,CAS5F;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAKrG;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAGxF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIlG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAUzF"}