symphony-github 0.1.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.
Files changed (166) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +341 -0
  3. package/config.example.yaml +101 -0
  4. package/dist/agents/launcher.d.ts +24 -0
  5. package/dist/agents/launcher.d.ts.map +1 -0
  6. package/dist/agents/launcher.js +152 -0
  7. package/dist/agents/launcher.js.map +1 -0
  8. package/dist/agents/registry.d.ts +10 -0
  9. package/dist/agents/registry.d.ts.map +1 -0
  10. package/dist/agents/registry.js +324 -0
  11. package/dist/agents/registry.js.map +1 -0
  12. package/dist/agents/runner.d.ts +58 -0
  13. package/dist/agents/runner.d.ts.map +1 -0
  14. package/dist/agents/runner.js +1190 -0
  15. package/dist/agents/runner.js.map +1 -0
  16. package/dist/app.d.ts +11 -0
  17. package/dist/app.d.ts.map +1 -0
  18. package/dist/app.js +829 -0
  19. package/dist/app.js.map +1 -0
  20. package/dist/components/ActivityView.d.ts +9 -0
  21. package/dist/components/ActivityView.d.ts.map +1 -0
  22. package/dist/components/ActivityView.js +73 -0
  23. package/dist/components/ActivityView.js.map +1 -0
  24. package/dist/components/Header.d.ts +12 -0
  25. package/dist/components/Header.d.ts.map +1 -0
  26. package/dist/components/Header.js +44 -0
  27. package/dist/components/Header.js.map +1 -0
  28. package/dist/components/IssueList.d.ts +10 -0
  29. package/dist/components/IssueList.d.ts.map +1 -0
  30. package/dist/components/IssueList.js +119 -0
  31. package/dist/components/IssueList.js.map +1 -0
  32. package/dist/components/Onboarding.d.ts +26 -0
  33. package/dist/components/Onboarding.d.ts.map +1 -0
  34. package/dist/components/Onboarding.js +948 -0
  35. package/dist/components/Onboarding.js.map +1 -0
  36. package/dist/components/PaneView.d.ts +9 -0
  37. package/dist/components/PaneView.d.ts.map +1 -0
  38. package/dist/components/PaneView.js +74 -0
  39. package/dist/components/PaneView.js.map +1 -0
  40. package/dist/components/StartupRecoveryView.d.ts +13 -0
  41. package/dist/components/StartupRecoveryView.d.ts.map +1 -0
  42. package/dist/components/StartupRecoveryView.js +85 -0
  43. package/dist/components/StartupRecoveryView.js.map +1 -0
  44. package/dist/components/StatusBar.d.ts +9 -0
  45. package/dist/components/StatusBar.d.ts.map +1 -0
  46. package/dist/components/StatusBar.js +70 -0
  47. package/dist/components/StatusBar.js.map +1 -0
  48. package/dist/components/TableView.d.ts +8 -0
  49. package/dist/components/TableView.d.ts.map +1 -0
  50. package/dist/components/TableView.js +87 -0
  51. package/dist/components/TableView.js.map +1 -0
  52. package/dist/config/index.d.ts +18 -0
  53. package/dist/config/index.d.ts.map +1 -0
  54. package/dist/config/index.js +357 -0
  55. package/dist/config/index.js.map +1 -0
  56. package/dist/git/merge.d.ts +23 -0
  57. package/dist/git/merge.d.ts.map +1 -0
  58. package/dist/git/merge.js +131 -0
  59. package/dist/git/merge.js.map +1 -0
  60. package/dist/git/utils.d.ts +34 -0
  61. package/dist/git/utils.d.ts.map +1 -0
  62. package/dist/git/utils.js +214 -0
  63. package/dist/git/utils.js.map +1 -0
  64. package/dist/git/worktree.d.ts +23 -0
  65. package/dist/git/worktree.d.ts.map +1 -0
  66. package/dist/git/worktree.js +116 -0
  67. package/dist/git/worktree.js.map +1 -0
  68. package/dist/index.d.ts +3 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +225 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/paths.d.ts +21 -0
  73. package/dist/paths.d.ts.map +1 -0
  74. package/dist/paths.js +59 -0
  75. package/dist/paths.js.map +1 -0
  76. package/dist/runModes.d.ts +7 -0
  77. package/dist/runModes.d.ts.map +1 -0
  78. package/dist/runModes.js +36 -0
  79. package/dist/runModes.js.map +1 -0
  80. package/dist/services/daemon.d.ts +85 -0
  81. package/dist/services/daemon.d.ts.map +1 -0
  82. package/dist/services/daemon.js +836 -0
  83. package/dist/services/daemon.js.map +1 -0
  84. package/dist/services/github.d.ts +101 -0
  85. package/dist/services/github.d.ts.map +1 -0
  86. package/dist/services/github.js +367 -0
  87. package/dist/services/github.js.map +1 -0
  88. package/dist/services/githubProgressReporter.d.ts +33 -0
  89. package/dist/services/githubProgressReporter.d.ts.map +1 -0
  90. package/dist/services/githubProgressReporter.js +272 -0
  91. package/dist/services/githubProgressReporter.js.map +1 -0
  92. package/dist/services/runtime.d.ts +43 -0
  93. package/dist/services/runtime.d.ts.map +1 -0
  94. package/dist/services/runtime.js +126 -0
  95. package/dist/services/runtime.js.map +1 -0
  96. package/dist/services/state.d.ts +43 -0
  97. package/dist/services/state.d.ts.map +1 -0
  98. package/dist/services/state.js +176 -0
  99. package/dist/services/state.js.map +1 -0
  100. package/dist/services/tmux.d.ts +50 -0
  101. package/dist/services/tmux.d.ts.map +1 -0
  102. package/dist/services/tmux.js +157 -0
  103. package/dist/services/tmux.js.map +1 -0
  104. package/dist/swarm/backlog.d.ts +25 -0
  105. package/dist/swarm/backlog.d.ts.map +1 -0
  106. package/dist/swarm/backlog.js +83 -0
  107. package/dist/swarm/backlog.js.map +1 -0
  108. package/dist/swarm/config.d.ts +14 -0
  109. package/dist/swarm/config.d.ts.map +1 -0
  110. package/dist/swarm/config.js +112 -0
  111. package/dist/swarm/config.js.map +1 -0
  112. package/dist/swarm/dependencies.d.ts +36 -0
  113. package/dist/swarm/dependencies.d.ts.map +1 -0
  114. package/dist/swarm/dependencies.js +141 -0
  115. package/dist/swarm/dependencies.js.map +1 -0
  116. package/dist/swarm/director.d.ts +67 -0
  117. package/dist/swarm/director.d.ts.map +1 -0
  118. package/dist/swarm/director.js +358 -0
  119. package/dist/swarm/director.js.map +1 -0
  120. package/dist/swarm/directorPrompt.d.ts +15 -0
  121. package/dist/swarm/directorPrompt.d.ts.map +1 -0
  122. package/dist/swarm/directorPrompt.js +60 -0
  123. package/dist/swarm/directorPrompt.js.map +1 -0
  124. package/dist/swarm/index.d.ts +7 -0
  125. package/dist/swarm/index.d.ts.map +1 -0
  126. package/dist/swarm/index.js +6 -0
  127. package/dist/swarm/index.js.map +1 -0
  128. package/dist/swarm/proposals.d.ts +29 -0
  129. package/dist/swarm/proposals.d.ts.map +1 -0
  130. package/dist/swarm/proposals.js +141 -0
  131. package/dist/swarm/proposals.js.map +1 -0
  132. package/dist/swarm/types.d.ts +65 -0
  133. package/dist/swarm/types.d.ts.map +1 -0
  134. package/dist/swarm/types.js +3 -0
  135. package/dist/swarm/types.js.map +1 -0
  136. package/dist/theme.d.ts +64 -0
  137. package/dist/theme.d.ts.map +1 -0
  138. package/dist/theme.js +161 -0
  139. package/dist/theme.js.map +1 -0
  140. package/dist/triggers/index.d.ts +17 -0
  141. package/dist/triggers/index.d.ts.map +1 -0
  142. package/dist/triggers/index.js +124 -0
  143. package/dist/triggers/index.js.map +1 -0
  144. package/dist/types.d.ts +327 -0
  145. package/dist/types.d.ts.map +1 -0
  146. package/dist/types.js +6 -0
  147. package/dist/types.js.map +1 -0
  148. package/dist/utils/duplicateDetection.d.ts +14 -0
  149. package/dist/utils/duplicateDetection.d.ts.map +1 -0
  150. package/dist/utils/duplicateDetection.js +45 -0
  151. package/dist/utils/duplicateDetection.js.map +1 -0
  152. package/dist/utils/shell.d.ts +46 -0
  153. package/dist/utils/shell.d.ts.map +1 -0
  154. package/dist/utils/shell.js +79 -0
  155. package/dist/utils/shell.js.map +1 -0
  156. package/dist/utils/slug.d.ts +13 -0
  157. package/dist/utils/slug.d.ts.map +1 -0
  158. package/dist/utils/slug.js +32 -0
  159. package/dist/utils/slug.js.map +1 -0
  160. package/dist/version.d.ts +28 -0
  161. package/dist/version.d.ts.map +1 -0
  162. package/dist/version.js +105 -0
  163. package/dist/version.js.map +1 -0
  164. package/examples/run-claude.example.sh +11 -0
  165. package/examples/run-codex.example.sh +11 -0
  166. package/package.json +68 -0
@@ -0,0 +1,141 @@
1
+ import { readFileSync, writeFileSync, readdirSync, existsSync, mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { proposalsDirPath } from './config.js';
4
+ /**
5
+ * File-based proposal store.
6
+ * Workers write proposals to ~/.symphony/swarm/proposals/<id>.json
7
+ * Director/daemon reads and processes them.
8
+ */
9
+ export class ProposalStore {
10
+ dir;
11
+ constructor(dir) {
12
+ this.dir = dir || proposalsDirPath();
13
+ if (!existsSync(this.dir)) {
14
+ mkdirSync(this.dir, { recursive: true });
15
+ }
16
+ }
17
+ /** List all proposals with a given status. */
18
+ listByStatus(status) {
19
+ const proposals = [];
20
+ const files = this.listProposalFiles();
21
+ for (const file of files) {
22
+ try {
23
+ const proposal = this.readProposal(file);
24
+ if (proposal && proposal.status === status) {
25
+ proposals.push(proposal);
26
+ }
27
+ }
28
+ catch {
29
+ // Skip malformed files
30
+ }
31
+ }
32
+ return proposals.sort((a, b) => a.created_at.localeCompare(b.created_at));
33
+ }
34
+ /** List all pending proposals. */
35
+ listPending() {
36
+ return this.listByStatus('pending');
37
+ }
38
+ /** Get a proposal by ID. */
39
+ get(id) {
40
+ const filePath = join(this.dir, `${id}.json`);
41
+ if (!existsSync(filePath))
42
+ return null;
43
+ try {
44
+ return this.readProposal(filePath);
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ /** Write a new proposal. Returns the proposal with generated ID. */
51
+ write(proposal) {
52
+ const id = this.generateId(proposal.title);
53
+ const full = {
54
+ ...proposal,
55
+ id,
56
+ status: 'pending',
57
+ created_at: new Date().toISOString(),
58
+ };
59
+ const filePath = join(this.dir, `${id}.json`);
60
+ writeFileSync(filePath, JSON.stringify(full, null, 2));
61
+ return full;
62
+ }
63
+ /** Approve a proposal. */
64
+ approve(id, createdIssueNumber) {
65
+ return this.updateStatus(id, 'approved', { created_issue_number: createdIssueNumber });
66
+ }
67
+ /** Reject a proposal with a reason. */
68
+ reject(id, reason) {
69
+ return this.updateStatus(id, 'rejected', { reject_reason: reason });
70
+ }
71
+ /** Remove proposals older than the given duration in milliseconds. */
72
+ cleanup(olderThanMs) {
73
+ const cutoff = Date.now() - olderThanMs;
74
+ let removed = 0;
75
+ for (const file of this.listProposalFiles()) {
76
+ try {
77
+ const proposal = this.readProposal(file);
78
+ if (!proposal)
79
+ continue;
80
+ if (proposal.status !== 'pending') {
81
+ const processedAt = proposal.processed_at ? new Date(proposal.processed_at).getTime() : 0;
82
+ if (processedAt > 0 && processedAt < cutoff) {
83
+ const { unlinkSync } = require('node:fs');
84
+ unlinkSync(file);
85
+ removed++;
86
+ }
87
+ }
88
+ }
89
+ catch {
90
+ // Skip
91
+ }
92
+ }
93
+ return removed;
94
+ }
95
+ updateStatus(id, status, extra = {}) {
96
+ const filePath = join(this.dir, `${id}.json`);
97
+ if (!existsSync(filePath))
98
+ return null;
99
+ try {
100
+ const proposal = this.readProposal(filePath);
101
+ if (!proposal)
102
+ return null;
103
+ const updated = {
104
+ ...proposal,
105
+ ...extra,
106
+ status,
107
+ processed_at: new Date().toISOString(),
108
+ };
109
+ writeFileSync(filePath, JSON.stringify(updated, null, 2));
110
+ return updated;
111
+ }
112
+ catch {
113
+ return null;
114
+ }
115
+ }
116
+ readProposal(filePath) {
117
+ const content = readFileSync(filePath, 'utf-8');
118
+ const parsed = JSON.parse(content);
119
+ if (!parsed || typeof parsed !== 'object' || !parsed.id || !parsed.title) {
120
+ return null;
121
+ }
122
+ return parsed;
123
+ }
124
+ listProposalFiles() {
125
+ if (!existsSync(this.dir))
126
+ return [];
127
+ return readdirSync(this.dir)
128
+ .filter(f => f.endsWith('.json'))
129
+ .map(f => join(this.dir, f));
130
+ }
131
+ generateId(title) {
132
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
133
+ const slug = title
134
+ .toLowerCase()
135
+ .replace(/[^a-z0-9]+/g, '-')
136
+ .replace(/^-|-$/g, '')
137
+ .slice(0, 40);
138
+ return `${timestamp}-${slug}`;
139
+ }
140
+ }
141
+ //# sourceMappingURL=proposals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proposals.js","sourceRoot":"","sources":["../../src/swarm/proposals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ export type DirectorScope = 'session' | 'organization' | 'repo';
2
+ export type ProposalApprovalMode = 'auto' | 'director_review' | 'human_approval';
3
+ export type ProposalType = 'bug' | 'improvement' | 'task';
4
+ export type ProposalUrgency = 'blocker' | 'high' | 'normal' | 'low';
5
+ export type ProposalStatus = 'pending' | 'approved' | 'rejected';
6
+ export interface DirectorSettings {
7
+ agent: string;
8
+ model?: string;
9
+ scope: DirectorScope;
10
+ analyze_interval_min: number;
11
+ max_proposed_issues: number;
12
+ }
13
+ export interface SwarmLabels {
14
+ paused: string;
15
+ blocker: string;
16
+ proposed: string;
17
+ }
18
+ export interface BacklogSettings {
19
+ enabled: boolean;
20
+ file: string;
21
+ github_issue: boolean;
22
+ }
23
+ export interface SwarmSettings {
24
+ enabled: boolean;
25
+ director: DirectorSettings;
26
+ proposals: {
27
+ approval_mode: ProposalApprovalMode;
28
+ };
29
+ labels: SwarmLabels;
30
+ backlog: BacklogSettings;
31
+ }
32
+ export interface IssueRef {
33
+ repo: string;
34
+ number: number;
35
+ }
36
+ export interface IssueProposal {
37
+ id: string;
38
+ proposed_by_run_id: string;
39
+ parent_issue: IssueRef;
40
+ title: string;
41
+ body: string;
42
+ labels: string[];
43
+ type: ProposalType;
44
+ urgency: ProposalUrgency;
45
+ status: ProposalStatus;
46
+ reject_reason?: string;
47
+ created_issue_number?: number;
48
+ created_at: string;
49
+ processed_at?: string;
50
+ }
51
+ export interface IssueDependency {
52
+ issue: IssueRef;
53
+ blocked_by: IssueRef[];
54
+ status: 'blocked' | 'ready';
55
+ }
56
+ export interface BacklogEntry {
57
+ repo: string;
58
+ issue_number: number;
59
+ title: string;
60
+ status: 'active' | 'blocked' | 'proposed' | 'completed';
61
+ blocked_by?: IssueRef[];
62
+ agent_name?: string;
63
+ updated_at: string;
64
+ }
65
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/swarm/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,cAAc,GAAG,MAAM,CAAC;AAChE,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AACjF,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,aAAa,GAAG,MAAM,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AACpE,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,EAAE;QACT,aAAa,EAAE,oBAAoB,CAAC;KACrC,CAAC;IACF,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,QAAQ,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,EAAE,QAAQ,EAAE,CAAC;IACvB,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IACxD,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,3 @@
1
+ // ── Swarm mode types ──
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/swarm/types.ts"],"names":[],"mappings":"AAAA,yBAAyB"}
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ export declare const gradient: {
3
+ readonly blue1: "#1e3a5f";
4
+ readonly blue2: "#1e5090";
5
+ readonly blue3: "#2563eb";
6
+ readonly blue4: "#3b82f6";
7
+ readonly blue5: "#60a5fa";
8
+ readonly blue6: "#93c5fd";
9
+ };
10
+ export declare const logoGradient: readonly ["#93c5fd", "#60a5fa", "#3b82f6", "#2563eb", "#1e5090", "#1e3a5f"];
11
+ export declare const colors: {
12
+ readonly primary: "#3b82f6";
13
+ readonly primaryLight: "#60a5fa";
14
+ readonly primaryDim: "#1e5090";
15
+ readonly accent: "#06b6d4";
16
+ readonly accentDim: "#0e7490";
17
+ readonly success: "#22c55e";
18
+ readonly warning: "#eab308";
19
+ readonly error: "#ef4444";
20
+ readonly running: "#f59e0b";
21
+ readonly text: "#e2e8f0";
22
+ readonly textDim: "#94a3b8";
23
+ readonly muted: "#64748b";
24
+ readonly border: "#334155";
25
+ readonly borderLight: "#475569";
26
+ readonly surface: "#1e293b";
27
+ readonly selected: "#2563eb";
28
+ readonly selectedText: "#dbeafe";
29
+ readonly key: "#fbbf24";
30
+ };
31
+ export declare function statusColor(status: string): string;
32
+ export declare function statusIcon(status: string): string;
33
+ export declare function useSpinner(active?: boolean, intervalMs?: number): string;
34
+ export declare const divider: {
35
+ readonly thin: "─";
36
+ readonly thick: "━";
37
+ readonly dotted: "┈";
38
+ readonly double: "═";
39
+ };
40
+ export declare function sectionHeader(label: string, width?: number): string;
41
+ export declare function progressBar(current: number, total: number, width?: number): string;
42
+ /**
43
+ * Renders text with a horizontal gradient between two hex colors.
44
+ * Per-character coloring via nested <Text> elements.
45
+ */
46
+ export declare function GradientText({ text, from, to, bold }: {
47
+ text: string;
48
+ from: string;
49
+ to: string;
50
+ bold?: boolean;
51
+ }): React.ReactElement;
52
+ /**
53
+ * Returns a sparkline string from an array of numeric values.
54
+ */
55
+ export declare function sparkline(values: number[]): string;
56
+ /**
57
+ * Hook that maintains a rolling window of numeric samples for sparkline display.
58
+ */
59
+ export declare function useSparkline(maxSamples?: number): {
60
+ values: number[];
61
+ push: (value: number) => void;
62
+ line: string;
63
+ };
64
+ //# sourceMappingURL=theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,eAAO,MAAM,QAAQ;;;;;;;CAOX,CAAC;AAEX,eAAO,MAAM,YAAY,6EAOf,CAAC;AAIX,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;CAwBT,CAAC;AAIX,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWlD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWjD;AAMD,wBAAgB,UAAU,CAAC,MAAM,GAAE,OAAc,EAAE,UAAU,GAAE,MAAW,GAAG,MAAM,CAelF;AAID,eAAO,MAAM,OAAO;;;;;CAKV,CAAC;AAEX,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAKvE;AAID,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAKtF;AA4BD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,KAAK,CAAC,YAAY,CAUrB;AAMD;;GAEG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAOlD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,GAAE,MAAW,GAAG;IACrD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd,CAUA"}
package/dist/theme.js ADDED
@@ -0,0 +1,161 @@
1
+ import React from 'react';
2
+ import { Text } from 'ink';
3
+ import { useState, useEffect, useRef } from 'react';
4
+ // ── Blue gradient palette ──────────────────────────────────────────
5
+ export const gradient = {
6
+ blue1: '#1e3a5f', // deepest
7
+ blue2: '#1e5090',
8
+ blue3: '#2563eb',
9
+ blue4: '#3b82f6',
10
+ blue5: '#60a5fa',
11
+ blue6: '#93c5fd', // lightest
12
+ };
13
+ export const logoGradient = [
14
+ '#93c5fd',
15
+ '#60a5fa',
16
+ '#3b82f6',
17
+ '#2563eb',
18
+ '#1e5090',
19
+ '#1e3a5f',
20
+ ];
21
+ // ── UI colors ──────────────────────────────────────────────────────
22
+ export const colors = {
23
+ primary: '#3b82f6',
24
+ primaryLight: '#60a5fa',
25
+ primaryDim: '#1e5090',
26
+ accent: '#06b6d4',
27
+ accentDim: '#0e7490',
28
+ success: '#22c55e',
29
+ warning: '#eab308',
30
+ error: '#ef4444',
31
+ running: '#f59e0b',
32
+ text: '#e2e8f0',
33
+ textDim: '#94a3b8',
34
+ muted: '#64748b',
35
+ border: '#334155',
36
+ borderLight: '#475569',
37
+ surface: '#1e293b',
38
+ selected: '#2563eb',
39
+ selectedText: '#dbeafe',
40
+ key: '#fbbf24',
41
+ };
42
+ // ── Status ─────────────────────────────────────────────────────────
43
+ export function statusColor(status) {
44
+ switch (status) {
45
+ case 'running': return colors.running;
46
+ case 'awaiting_review': return colors.accent;
47
+ case 'needs_attention': return '#a855f7';
48
+ case 'success': return colors.success;
49
+ case 'failed': return colors.error;
50
+ case 'timeout': return colors.error;
51
+ case 'pending': return colors.muted;
52
+ default: return colors.text;
53
+ }
54
+ }
55
+ export function statusIcon(status) {
56
+ switch (status) {
57
+ case 'running': return '●';
58
+ case 'awaiting_review': return '◉';
59
+ case 'needs_attention': return '!';
60
+ case 'success': return '✔';
61
+ case 'failed': return '✖';
62
+ case 'timeout': return '⏱';
63
+ case 'pending': return '○';
64
+ default: return '?';
65
+ }
66
+ }
67
+ // ── Animated spinner hook (kept for inline-text usage) ─────────────
68
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
69
+ export function useSpinner(active = true, intervalMs = 80) {
70
+ const [frame, setFrame] = useState(0);
71
+ const intervalRef = useRef();
72
+ useEffect(() => {
73
+ if (!active)
74
+ return;
75
+ intervalRef.current = setInterval(() => {
76
+ setFrame(prev => (prev + 1) % SPINNER_FRAMES.length);
77
+ }, intervalMs);
78
+ return () => {
79
+ if (intervalRef.current)
80
+ clearInterval(intervalRef.current);
81
+ };
82
+ }, [active, intervalMs]);
83
+ return active ? SPINNER_FRAMES[frame] : '';
84
+ }
85
+ // ── Box-drawing helpers ────────────────────────────────────────────
86
+ export const divider = {
87
+ thin: '─',
88
+ thick: '━',
89
+ dotted: '┈',
90
+ double: '═',
91
+ };
92
+ export function sectionHeader(label, width = 36) {
93
+ const pad = width - label.length - 4;
94
+ const left = Math.floor(pad / 2);
95
+ const right = pad - left;
96
+ return `${divider.thin.repeat(Math.max(0, left))} ${label} ${divider.thin.repeat(Math.max(0, right))}`;
97
+ }
98
+ // ── Progress bar ───────────────────────────────────────────────────
99
+ export function progressBar(current, total, width = 20) {
100
+ const ratio = total > 0 ? current / total : 0;
101
+ const filled = Math.round(ratio * width);
102
+ const empty = width - filled;
103
+ return '█'.repeat(filled) + '░'.repeat(empty);
104
+ }
105
+ // ── Gradient text (custom, since ink-gradient requires ink>=6) ─────
106
+ function hexToRgb(hex) {
107
+ const h = hex.replace('#', '');
108
+ return [
109
+ parseInt(h.slice(0, 2), 16),
110
+ parseInt(h.slice(2, 4), 16),
111
+ parseInt(h.slice(4, 6), 16),
112
+ ];
113
+ }
114
+ function rgbToHex(r, g, b) {
115
+ const toHex = (n) => Math.round(n).toString(16).padStart(2, '0');
116
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
117
+ }
118
+ function interpolateColor(from, to, t) {
119
+ const [r1, g1, b1] = hexToRgb(from);
120
+ const [r2, g2, b2] = hexToRgb(to);
121
+ return rgbToHex(r1 + (r2 - r1) * t, g1 + (g2 - g1) * t, b1 + (b2 - b1) * t);
122
+ }
123
+ /**
124
+ * Renders text with a horizontal gradient between two hex colors.
125
+ * Per-character coloring via nested <Text> elements.
126
+ */
127
+ export function GradientText({ text, from, to, bold }) {
128
+ const chars = [...text];
129
+ const len = Math.max(chars.length - 1, 1);
130
+ return React.createElement(Text, { bold }, ...chars.map((ch, i) => React.createElement(Text, { key: i, color: interpolateColor(from, to, i / len) }, ch)));
131
+ }
132
+ // ── Sparkline ──────────────────────────────────────────────────────
133
+ const SPARK_CHARS = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
134
+ /**
135
+ * Returns a sparkline string from an array of numeric values.
136
+ */
137
+ export function sparkline(values) {
138
+ if (values.length === 0)
139
+ return '';
140
+ const max = Math.max(...values, 1);
141
+ return values.map(v => {
142
+ const idx = Math.round((v / max) * (SPARK_CHARS.length - 1));
143
+ return SPARK_CHARS[idx];
144
+ }).join('');
145
+ }
146
+ /**
147
+ * Hook that maintains a rolling window of numeric samples for sparkline display.
148
+ */
149
+ export function useSparkline(maxSamples = 30) {
150
+ const [values, setValues] = useState(new Array(maxSamples).fill(0));
151
+ const push = (value) => {
152
+ setValues(prev => {
153
+ const next = [...prev, value];
154
+ if (next.length > maxSamples)
155
+ next.shift();
156
+ return next;
157
+ });
158
+ };
159
+ return { values, push, line: sparkline(values) };
160
+ }
161
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { GitHubIssue, GitHubComment, TriggerSettings, TriggerDecision } from '../types.js';
2
+ /**
3
+ * Evaluate whether an issue should trigger an agent run.
4
+ * Ported from symphony Python's triggers.py.
5
+ */
6
+ export declare function evaluateTrigger(issue: GitHubIssue, comments: GitHubComment[], trigger: TriggerSettings, context: {
7
+ isHandled: boolean;
8
+ hasActiveRun: boolean;
9
+ hasOpenPr: boolean;
10
+ isClaimed: boolean;
11
+ processedCommentIds: Set<number>;
12
+ }): TriggerDecision;
13
+ /**
14
+ * Find which agent was mentioned (for routing).
15
+ */
16
+ export declare function findMentionedAgent(issue: GitHubIssue, comments: GitHubComment[], mentionMap: Record<string, string>): string | null;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/triggers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAC7D,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IACP,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC,GACA,eAAe,CA8FjB;AAmCD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,aAAa,EAAE,EACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,MAAM,GAAG,IAAI,CAYf"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Evaluate whether an issue should trigger an agent run.
3
+ * Ported from symphony Python's triggers.py.
4
+ */
5
+ export function evaluateTrigger(issue, comments, trigger, context) {
6
+ // Disabled mode
7
+ if (trigger.mode === 'disabled') {
8
+ return { should_run: false, reason: 'Triggers are disabled' };
9
+ }
10
+ // Skip checks
11
+ if (context.hasActiveRun) {
12
+ return { should_run: false, reason: 'Issue already has an active run' };
13
+ }
14
+ if (trigger.skip_if_handled && context.isHandled) {
15
+ return { should_run: false, reason: 'Issue already handled' };
16
+ }
17
+ if (trigger.skip_if_open_pr && context.hasOpenPr) {
18
+ return { should_run: false, reason: 'Issue already has an open PR' };
19
+ }
20
+ if (trigger.skip_if_claimed && context.isClaimed) {
21
+ return { should_run: false, reason: 'Issue is claimed by another runner' };
22
+ }
23
+ // Check ignore labels
24
+ const issueLabels = issue.labels.map(l => l.name.toLowerCase());
25
+ for (const ignoreLabel of trigger.ignore_labels) {
26
+ if (issueLabels.includes(ignoreLabel.toLowerCase())) {
27
+ return { should_run: false, reason: `Issue has ignore label: ${ignoreLabel}` };
28
+ }
29
+ }
30
+ // Check author association
31
+ if (trigger.allowed_author_associations.length > 0 && issue.author_association) {
32
+ if (!trigger.allowed_author_associations.includes(issue.author_association)) {
33
+ return {
34
+ should_run: false,
35
+ reason: `Author association "${issue.author_association}" not in allowed list`,
36
+ };
37
+ }
38
+ }
39
+ // Check assignee requirement
40
+ if (trigger.require_assignee && issue.assignees.length === 0) {
41
+ return { should_run: false, reason: 'Issue has no assignee (required)' };
42
+ }
43
+ // Yolo mode - always run
44
+ if (trigger.mode === 'yolo') {
45
+ return { should_run: true, reason: 'Yolo mode', matched_by: 'yolo' };
46
+ }
47
+ // Check label match
48
+ const hasLabel = trigger.labels.some(triggerLabel => issueLabels.includes(triggerLabel.toLowerCase()));
49
+ // Check mention match (in issue body and unprocessed comments)
50
+ const hasMention = checkMentions(issue, comments, trigger.mentions, context.processedCommentIds);
51
+ // Evaluate based on mode
52
+ switch (trigger.mode) {
53
+ case 'label_only':
54
+ if (hasLabel) {
55
+ return { should_run: true, reason: 'Label matched', matched_by: 'label' };
56
+ }
57
+ return { should_run: false, reason: 'No matching label found' };
58
+ case 'mention_only':
59
+ if (hasMention) {
60
+ return { should_run: true, reason: 'Mention matched', matched_by: 'mention' };
61
+ }
62
+ return { should_run: false, reason: 'No matching mention found' };
63
+ case 'mention_or_label':
64
+ if (hasLabel) {
65
+ return { should_run: true, reason: 'Label matched', matched_by: 'label' };
66
+ }
67
+ if (hasMention) {
68
+ return { should_run: true, reason: 'Mention matched', matched_by: 'mention' };
69
+ }
70
+ return { should_run: false, reason: 'Neither mention nor label matched' };
71
+ case 'mention_and_label':
72
+ if (hasLabel && hasMention) {
73
+ return { should_run: true, reason: 'Both mention and label matched', matched_by: 'both' };
74
+ }
75
+ return {
76
+ should_run: false,
77
+ reason: `Need both mention and label. Has label: ${hasLabel}, has mention: ${hasMention}`,
78
+ };
79
+ default:
80
+ return { should_run: false, reason: `Unknown trigger mode: ${trigger.mode}` };
81
+ }
82
+ }
83
+ /**
84
+ * Check if any configured mentions appear in the issue body or recent comments.
85
+ */
86
+ function checkMentions(issue, comments, mentions, processedCommentIds) {
87
+ if (mentions.length === 0)
88
+ return false;
89
+ // Check issue body
90
+ const bodyLower = (issue.body || '').toLowerCase();
91
+ for (const mention of mentions) {
92
+ if (bodyLower.includes(mention.toLowerCase())) {
93
+ return true;
94
+ }
95
+ }
96
+ // Check unprocessed comments
97
+ for (const comment of comments) {
98
+ if (processedCommentIds.has(comment.id))
99
+ continue;
100
+ const commentLower = comment.body.toLowerCase();
101
+ for (const mention of mentions) {
102
+ if (commentLower.includes(mention.toLowerCase())) {
103
+ return true;
104
+ }
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+ /**
110
+ * Find which agent was mentioned (for routing).
111
+ */
112
+ export function findMentionedAgent(issue, comments, mentionMap) {
113
+ const allText = [
114
+ issue.body || '',
115
+ ...comments.map(c => c.body),
116
+ ].join('\n').toLowerCase();
117
+ for (const [mention, agent] of Object.entries(mentionMap)) {
118
+ if (allText.includes(mention.toLowerCase())) {
119
+ return agent;
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/triggers/index.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAkB,EAClB,QAAyB,EACzB,OAAwB,EACxB,OAMC;IAED,gBAAgB;IAChB,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAChC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAChE,CAAC;IAED,cAAc;IACd,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;IAC1E,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACjD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACjD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;IACvE,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACjD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC;IAC7E,CAAC;IAED,sBAAsB;IACtB,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAChE,KAAK,MAAM,WAAW,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAChD,IAAI,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACpD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,WAAW,EAAE,EAAE,CAAC;QACjF,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,IAAI,OAAO,CAAC,2BAA2B,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAC/E,IAAI,CAAC,OAAO,CAAC,2BAA2B,CAAC,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC5E,OAAO;gBACL,UAAU,EAAE,KAAK;gBACjB,MAAM,EAAE,uBAAuB,KAAK,CAAC,kBAAkB,uBAAuB;aAC/E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,IAAI,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7D,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC;IAC3E,CAAC;IAED,yBAAyB;IACzB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IACvE,CAAC;IAED,oBAAoB;IACpB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAClD,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CACjD,CAAC;IAEF,+DAA+D;IAC/D,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEjG,yBAAyB;IACzB,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,YAAY;YACf,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;YAC5E,CAAC;YACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;QAElE,KAAK,cAAc;YACjB,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;YAChF,CAAC;YACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;QAEpE,KAAK,kBAAkB;YACrB,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;YAC5E,CAAC;YACD,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;YAChF,CAAC;YACD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,mCAAmC,EAAE,CAAC;QAE5E,KAAK,mBAAmB;YACtB,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;gBAC3B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,gCAAgC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;YAC5F,CAAC;YACD,OAAO;gBACL,UAAU,EAAE,KAAK;gBACjB,MAAM,EAAE,2CAA2C,QAAQ,kBAAkB,UAAU,EAAE;aAC1F,CAAC;QAEJ;YACE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;IAClF,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,KAAkB,EAClB,QAAyB,EACzB,QAAkB,EAClB,mBAAgC;IAEhC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAExC,mBAAmB;IACnB,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACnD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAAE,SAAS;QAClD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAChD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBACjD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAkB,EAClB,QAAyB,EACzB,UAAkC;IAElC,MAAM,OAAO,GAAG;QACd,KAAK,CAAC,IAAI,IAAI,EAAE;QAChB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;KAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAE3B,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1D,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}