pi-orchestrator-config 4.1.5

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 (175) hide show
  1. package/README.md +808 -0
  2. package/agents/api-documenter.md +32 -0
  3. package/agents/bash-expert.md +53 -0
  4. package/agents/code-reviewer-docs.md +145 -0
  5. package/agents/code-reviewer-guidelines.md +97 -0
  6. package/agents/code-reviewer-quality.md +142 -0
  7. package/agents/code-reviewer-security.md +107 -0
  8. package/agents/code-reviewer-spec.md +164 -0
  9. package/agents/debugger.md +63 -0
  10. package/agents/docker-expert.md +40 -0
  11. package/agents/docs-fetcher.md +48 -0
  12. package/agents/git-expert.md +63 -0
  13. package/agents/github-expert.md +83 -0
  14. package/agents/go-expert.md +62 -0
  15. package/agents/issue-reviewer-feasibility.md +60 -0
  16. package/agents/issue-reviewer-scope.md +63 -0
  17. package/agents/issue-reviewer-spec.md +77 -0
  18. package/agents/java-expert.md +31 -0
  19. package/agents/jenkins-expert.md +38 -0
  20. package/agents/kubernetes-expert.md +40 -0
  21. package/agents/planner.md +42 -0
  22. package/agents/python-expert.md +61 -0
  23. package/agents/reviewer.md +26 -0
  24. package/agents/scout.md +40 -0
  25. package/agents/security-auditor.md +254 -0
  26. package/agents/technical-documentation-writer.md +37 -0
  27. package/agents/test-automator.md +55 -0
  28. package/agents/test-runner.md +47 -0
  29. package/agents/ts-expert.md +23 -0
  30. package/agents/worker.md +30 -0
  31. package/extensions/acpx-provider/index.ts +104 -0
  32. package/extensions/acpx-provider/load-runtime.ts +99 -0
  33. package/extensions/acpx-provider/runtime-models.ts +40 -0
  34. package/extensions/cli-provider/agents/claude.ts +128 -0
  35. package/extensions/cli-provider/agents/cursor.ts +84 -0
  36. package/extensions/cli-provider/agents/gemini.ts +100 -0
  37. package/extensions/cli-provider/discover.ts +77 -0
  38. package/extensions/cli-provider/index.ts +57 -0
  39. package/extensions/cli-provider/parsers.ts +304 -0
  40. package/extensions/cli-provider/providers.ts +58 -0
  41. package/extensions/cli-provider/runner.ts +225 -0
  42. package/extensions/cli-provider/runtime-models.ts +32 -0
  43. package/extensions/cli-provider/session-reaper.ts +122 -0
  44. package/extensions/cli-provider/sessions.ts +533 -0
  45. package/extensions/cli-provider/shared/discover-cache.ts +235 -0
  46. package/extensions/cli-provider/types.ts +48 -0
  47. package/extensions/coms/coms-net-server.ts +1642 -0
  48. package/extensions/coms/coms-net-wrapper.ts +521 -0
  49. package/extensions/coms/coms-net.ts +1589 -0
  50. package/extensions/coms/coms-p2p.ts +1879 -0
  51. package/extensions/coms/coms-shared.ts +510 -0
  52. package/extensions/coms/coms-wrapper.ts +138 -0
  53. package/extensions/coms/index.ts +20 -0
  54. package/extensions/coms/themeMap.ts +147 -0
  55. package/extensions/image-gen/image-gen.ts +332 -0
  56. package/extensions/image-gen/index.ts +14 -0
  57. package/extensions/orchestrator/agents.ts +134 -0
  58. package/extensions/orchestrator/ask-user.ts +293 -0
  59. package/extensions/orchestrator/async-agents.ts +1037 -0
  60. package/extensions/orchestrator/async-capability.ts +129 -0
  61. package/extensions/orchestrator/async-runner.ts +324 -0
  62. package/extensions/orchestrator/async-status-parse.ts +31 -0
  63. package/extensions/orchestrator/async-status-ui.ts +201 -0
  64. package/extensions/orchestrator/async-wait.ts +36 -0
  65. package/extensions/orchestrator/btw.ts +210 -0
  66. package/extensions/orchestrator/cron-status-format.ts +126 -0
  67. package/extensions/orchestrator/cron-status-ui.ts +132 -0
  68. package/extensions/orchestrator/cron.ts +730 -0
  69. package/extensions/orchestrator/dreaming.ts +355 -0
  70. package/extensions/orchestrator/enforcement-helpers.ts +530 -0
  71. package/extensions/orchestrator/enforcement-rules.ts +329 -0
  72. package/extensions/orchestrator/enforcement.ts +828 -0
  73. package/extensions/orchestrator/extended-autocomplete.ts +593 -0
  74. package/extensions/orchestrator/git-helpers.ts +420 -0
  75. package/extensions/orchestrator/github-autocomplete.ts +250 -0
  76. package/extensions/orchestrator/icons.ts +17 -0
  77. package/extensions/orchestrator/index.ts +100 -0
  78. package/extensions/orchestrator/memory-embeddings.ts +281 -0
  79. package/extensions/orchestrator/memory-promotion.ts +449 -0
  80. package/extensions/orchestrator/memory-provenance.ts +80 -0
  81. package/extensions/orchestrator/memory-query-class.ts +90 -0
  82. package/extensions/orchestrator/memory-scoring.ts +434 -0
  83. package/extensions/orchestrator/memory-tools.ts +883 -0
  84. package/extensions/orchestrator/memory-tree.ts +212 -0
  85. package/extensions/orchestrator/nvim.ts +169 -0
  86. package/extensions/orchestrator/overlay-dashboard-utils.ts +25 -0
  87. package/extensions/orchestrator/overlay-dashboard.ts +512 -0
  88. package/extensions/orchestrator/pi-config-review-state.ts +303 -0
  89. package/extensions/orchestrator/preference-extractor.ts +106 -0
  90. package/extensions/orchestrator/project-settings.ts +468 -0
  91. package/extensions/orchestrator/promotion-queue.ts +311 -0
  92. package/extensions/orchestrator/resolve-agent-model.ts +32 -0
  93. package/extensions/orchestrator/review-ui.ts +204 -0
  94. package/extensions/orchestrator/rule-placeholders.ts +12 -0
  95. package/extensions/orchestrator/rules.ts +481 -0
  96. package/extensions/orchestrator/session-search.ts +243 -0
  97. package/extensions/orchestrator/session-validation.ts +374 -0
  98. package/extensions/orchestrator/situation-report.ts +370 -0
  99. package/extensions/orchestrator/status-bar.ts +31 -0
  100. package/extensions/orchestrator/status-line.ts +192 -0
  101. package/extensions/orchestrator/status.ts +110 -0
  102. package/extensions/orchestrator/subagent-tool.ts +1748 -0
  103. package/extensions/orchestrator/task-lifecycle.ts +88 -0
  104. package/extensions/orchestrator/utils.ts +227 -0
  105. package/extensions/pidash/index.ts +15 -0
  106. package/extensions/pidash/pidash.ts +941 -0
  107. package/extensions/pidiff/index.ts +13 -0
  108. package/extensions/pidiff/pidiff.ts +369 -0
  109. package/extensions/providers/acpx-driver.ts +479 -0
  110. package/extensions/providers/built-in-drivers.ts +52 -0
  111. package/extensions/providers/claude-driver.ts +319 -0
  112. package/extensions/providers/cursor-acpx-driver.ts +398 -0
  113. package/extensions/providers/cursor-cli-driver.ts +484 -0
  114. package/extensions/providers/gemini-driver.ts +302 -0
  115. package/extensions/providers/index.ts +513 -0
  116. package/extensions/shared/build-system-prompt.ts +57 -0
  117. package/extensions/shared/create-runtime-provider.ts +190 -0
  118. package/extensions/shared/daemon-manager.ts +248 -0
  119. package/extensions/shared/file-logger.ts +115 -0
  120. package/extensions/shared/managed-refresh.ts +211 -0
  121. package/extensions/shared/provider-driver.ts +295 -0
  122. package/extensions/shared/provider-errors.ts +305 -0
  123. package/extensions/shared/provider-registry.ts +388 -0
  124. package/extensions/shared/stream-builder.ts +275 -0
  125. package/extensions/shared/types.ts +20 -0
  126. package/extensions/shared/ui/README.md +10 -0
  127. package/extensions/shared/ui/badge.tsx +52 -0
  128. package/extensions/shared/ui/button.tsx +58 -0
  129. package/extensions/shared/ui/collapsible.tsx +21 -0
  130. package/extensions/shared/ui/dropdown-menu.tsx +266 -0
  131. package/extensions/shared/ui/input.tsx +20 -0
  132. package/extensions/shared/ui/popover.tsx +114 -0
  133. package/extensions/shared/ui/resizable.tsx +48 -0
  134. package/extensions/shared/ui/scroll-area.tsx +53 -0
  135. package/extensions/shared/ui/select.tsx +201 -0
  136. package/extensions/shared/ui/separator.tsx +25 -0
  137. package/extensions/shared/ui/tooltip.tsx +64 -0
  138. package/extensions/shared/ws-client.ts +74 -0
  139. package/package.json +59 -0
  140. package/prompts/coderabbit-rate-limit.md +95 -0
  141. package/prompts/create-coms-feature-manager.md +186 -0
  142. package/prompts/create-skill.md +128 -0
  143. package/prompts/domain-model.md +109 -0
  144. package/prompts/external-ai.md +665 -0
  145. package/prompts/implement-and-review.md +25 -0
  146. package/prompts/implement.md +26 -0
  147. package/prompts/issue-review.md +256 -0
  148. package/prompts/pr-review.md +753 -0
  149. package/prompts/query-db.md +154 -0
  150. package/prompts/refine-review.md +208 -0
  151. package/prompts/release.md +235 -0
  152. package/prompts/remember.md +33 -0
  153. package/prompts/review-handler-status.md +27 -0
  154. package/prompts/review-handler.md +677 -0
  155. package/prompts/review-local.md +159 -0
  156. package/prompts/scout-and-plan.md +21 -0
  157. package/rules/00-orchestrator-core.md +42 -0
  158. package/rules/05-issue-first-workflow.md +119 -0
  159. package/rules/10-agent-routing.md +58 -0
  160. package/rules/15-mcp-launchpad.md +46 -0
  161. package/rules/20-code-review-loop.md +234 -0
  162. package/rules/25-documentation-updates.md +15 -0
  163. package/rules/30-prompt-templates.md +19 -0
  164. package/rules/35-memory.md +240 -0
  165. package/rules/40-critical-rules.md +124 -0
  166. package/rules/45-file-preview.md +29 -0
  167. package/rules/50-agent-bug-reporting.md +90 -0
  168. package/rules/55-coms-protocol.md +63 -0
  169. package/rules/60-task-tracking.md +66 -0
  170. package/skills/conflict-resolver/SKILL.md +213 -0
  171. package/skills/skill-creator/SKILL.md +85 -0
  172. package/skills/systematic-debugging/SKILL.md +353 -0
  173. package/skills/test-driven-development/SKILL.md +335 -0
  174. package/skills/update-agents-md/SKILL.md +282 -0
  175. package/templates/coms-feature-manager-prompt.md +313 -0
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Shared stream builder — assembles DriverStreamEvents into pi's
3
+ * AssistantMessageEventStream.
4
+ *
5
+ * Both cli-provider and acpx-provider had near-identical ~100-line blocks
6
+ * for mapping text_delta/thinking_delta events into the pi event stream
7
+ * format. This module unifies that into a single, testable function.
8
+ *
9
+ * @module shared/stream-builder
10
+ */
11
+
12
+ import type {
13
+ AssistantMessage,
14
+ AssistantMessageEventStream,
15
+ } from "@earendil-works/pi-ai";
16
+ import type { DriverStreamEvent } from "./provider-driver.js";
17
+
18
+ /**
19
+ * State tracker for building AssistantMessage content blocks from
20
+ * a stream of DriverStreamEvents. Manages thinking/text block indices
21
+ * and emits the correct pi event stream events.
22
+ */
23
+ export class StreamAssembler {
24
+ private thinkingIndex = -1;
25
+ private textIndex = -1;
26
+ private thinkingClosed = false;
27
+
28
+ constructor(
29
+ private readonly output: AssistantMessage,
30
+ private readonly stream: AssistantMessageEventStream,
31
+ ) {}
32
+
33
+ /** Process a single driver event and emit corresponding pi stream events. */
34
+ handleEvent(event: DriverStreamEvent): void {
35
+ switch (event.kind) {
36
+ case "thinking_delta":
37
+ this.handleThinkingDelta(event.text);
38
+ break;
39
+ case "text_delta":
40
+ this.handleTextDelta(event.text);
41
+ break;
42
+ case "session":
43
+ // Session events are handled by the driver adapter, not the stream builder.
44
+ break;
45
+ case "turn_complete":
46
+ // Handled by finalize().
47
+ break;
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Finalize the stream — close any open content blocks and emit done.
53
+ * Call after all events have been processed or when the turn completes.
54
+ *
55
+ * @param finalText - Authoritative final text from the parser (may differ from accumulated deltas).
56
+ * @param finalThinking - Authoritative final thinking from the parser.
57
+ * @param stopReason - Stop reason for the done event.
58
+ */
59
+ finalize(opts?: {
60
+ finalText?: string;
61
+ finalThinking?: string;
62
+ stopReason?: string;
63
+ usage?: import("./provider-driver.js").DriverUsage;
64
+ }): void {
65
+ const finalText = opts?.finalText;
66
+ const finalThinking = opts?.finalThinking;
67
+
68
+ // Close thinking block if still open
69
+ if (this.thinkingIndex >= 0 && !this.thinkingClosed) {
70
+ const block = this.output.content[this.thinkingIndex];
71
+ if (block.type === "thinking") {
72
+ // Apply authoritative thinking if available and block was empty
73
+ if (!block.thinking && finalThinking) {
74
+ block.thinking = finalThinking;
75
+ this.stream.push({
76
+ type: "thinking_delta",
77
+ contentIndex: this.thinkingIndex,
78
+ delta: finalThinking,
79
+ partial: this.output,
80
+ });
81
+ }
82
+ this.stream.push({
83
+ type: "thinking_end",
84
+ contentIndex: this.thinkingIndex,
85
+ content: block.thinking,
86
+ partial: this.output,
87
+ });
88
+ }
89
+ this.thinkingClosed = true;
90
+ }
91
+
92
+ // Handle text: either apply authoritative final text or close existing block
93
+ if (this.textIndex < 0 && finalText) {
94
+ // No text block yet but parser returned text — create and emit it
95
+ this.output.content.push({ type: "text", text: finalText });
96
+ this.textIndex = this.output.content.length - 1;
97
+ this.stream.push({
98
+ type: "text_start",
99
+ contentIndex: this.textIndex,
100
+ partial: this.output,
101
+ });
102
+ this.stream.push({
103
+ type: "text_delta",
104
+ contentIndex: this.textIndex,
105
+ delta: finalText,
106
+ partial: this.output,
107
+ });
108
+ } else if (this.textIndex >= 0 && finalText) {
109
+ const block = this.output.content[this.textIndex];
110
+ if (block.type === "text") {
111
+ // Prefer authoritative final text if it differs
112
+ if (finalText !== block.text) {
113
+ const missing = finalText.startsWith(block.text)
114
+ ? finalText.slice(block.text.length)
115
+ : "";
116
+ if (missing) {
117
+ block.text = finalText;
118
+ this.stream.push({
119
+ type: "text_delta",
120
+ contentIndex: this.textIndex,
121
+ delta: missing,
122
+ partial: this.output,
123
+ });
124
+ } else {
125
+ block.text = finalText;
126
+ }
127
+ }
128
+ }
129
+ }
130
+
131
+ // Close text block
132
+ if (this.textIndex >= 0) {
133
+ const block = this.output.content[this.textIndex];
134
+ if (block.type === "text") {
135
+ this.stream.push({
136
+ type: "text_end",
137
+ contentIndex: this.textIndex,
138
+ content: block.text,
139
+ partial: this.output,
140
+ });
141
+ }
142
+ }
143
+
144
+ // Map driver usage to pi's usage format
145
+ if (opts?.usage) {
146
+ const u = opts.usage;
147
+ this.output.usage = {
148
+ input: u.inputTokens ?? 0,
149
+ output: u.outputTokens ?? 0,
150
+ cacheRead: u.cachedReadTokens ?? 0,
151
+ cacheWrite: u.cachedWriteTokens ?? 0,
152
+ totalTokens: u.totalTokens ?? ((u.inputTokens ?? 0) + (u.outputTokens ?? 0)),
153
+ cost: {
154
+ input: 0,
155
+ output: 0,
156
+ cacheRead: 0,
157
+ cacheWrite: 0,
158
+ total: u.costUsd ?? 0,
159
+ },
160
+ };
161
+ }
162
+
163
+ // AssistantMessage.stopReason keeps the full driver value (length, toolUse, …).
164
+ // pi's done-event reason is only "stop" | "aborted" — map everything else to "stop".
165
+ const stopReason = this.output.stopReason = opts?.stopReason || "stop";
166
+ const reason = (stopReason === "aborted" ? "aborted" : "stop") as "stop" | "aborted";
167
+ this.stream.push({ type: "done", reason, message: this.output });
168
+ this.stream.end();
169
+ }
170
+
171
+ /**
172
+ * Emit an error event and end the stream.
173
+ */
174
+ emitError(error: unknown, aborted?: boolean): void {
175
+ this.output.stopReason = aborted ? "aborted" : "error";
176
+ this.output.errorMessage =
177
+ error instanceof Error ? error.message : String(error);
178
+ this.stream.push({
179
+ type: "error",
180
+ reason: this.output.stopReason as "aborted" | "error",
181
+ error: this.output,
182
+ });
183
+ this.stream.end();
184
+ }
185
+
186
+ // -------------------------------------------------------------------------
187
+ // Private
188
+ // -------------------------------------------------------------------------
189
+
190
+ private handleThinkingDelta(text: string): void {
191
+ if (this.thinkingIndex < 0) {
192
+ this.output.content.push({ type: "thinking", thinking: "" });
193
+ this.thinkingIndex = this.output.content.length - 1;
194
+ this.stream.push({
195
+ type: "thinking_start",
196
+ contentIndex: this.thinkingIndex,
197
+ partial: this.output,
198
+ });
199
+ }
200
+ const block = this.output.content[this.thinkingIndex];
201
+ if (block.type === "thinking") {
202
+ block.thinking += text;
203
+ this.stream.push({
204
+ type: "thinking_delta",
205
+ contentIndex: this.thinkingIndex,
206
+ delta: text,
207
+ partial: this.output,
208
+ });
209
+ }
210
+ }
211
+
212
+ private handleTextDelta(text: string): void {
213
+ // Close thinking block on first text delta
214
+ if (this.thinkingIndex >= 0 && !this.thinkingClosed) {
215
+ this.thinkingClosed = true;
216
+ const thinkBlock = this.output.content[this.thinkingIndex];
217
+ if (thinkBlock.type === "thinking") {
218
+ this.stream.push({
219
+ type: "thinking_end",
220
+ contentIndex: this.thinkingIndex,
221
+ content: thinkBlock.thinking,
222
+ partial: this.output,
223
+ });
224
+ }
225
+ }
226
+
227
+ if (this.textIndex < 0) {
228
+ this.output.content.push({ type: "text", text: "" });
229
+ this.textIndex = this.output.content.length - 1;
230
+ this.stream.push({
231
+ type: "text_start",
232
+ contentIndex: this.textIndex,
233
+ partial: this.output,
234
+ });
235
+ }
236
+ const block = this.output.content[this.textIndex];
237
+ if (block.type === "text") {
238
+ block.text += text;
239
+ this.stream.push({
240
+ type: "text_delta",
241
+ contentIndex: this.textIndex,
242
+ delta: text,
243
+ partial: this.output,
244
+ });
245
+ }
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Create a fresh AssistantMessage output object for stream building.
251
+ * Reusable across all drivers.
252
+ */
253
+ export function createAssistantMessageOutput(model: {
254
+ api: string;
255
+ provider: string;
256
+ id: string;
257
+ }): AssistantMessage {
258
+ return {
259
+ role: "assistant",
260
+ content: [],
261
+ api: model.api,
262
+ provider: model.provider,
263
+ model: model.id,
264
+ usage: {
265
+ input: 0,
266
+ output: 0,
267
+ cacheRead: 0,
268
+ cacheWrite: 0,
269
+ totalTokens: 0,
270
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
271
+ },
272
+ stopReason: "stop",
273
+ timestamp: Date.now(),
274
+ } as AssistantMessage;
275
+ }
@@ -0,0 +1,20 @@
1
+ /** Session info shared between pidash-server and pidash-ui. */
2
+ export interface SessionInfo {
3
+ sessionId: string;
4
+ pid: number;
5
+ cwd: string;
6
+ branch: string;
7
+ model: string;
8
+ startedAt: string;
9
+ lastActivity: number;
10
+ active: boolean;
11
+ sessionFile?: string;
12
+ gitDirty?: boolean;
13
+ gitChanges?: number;
14
+ container?: boolean;
15
+ contextWindow?: number;
16
+ thinkingLevel?: string;
17
+ diffPort?: number | null;
18
+ working?: boolean;
19
+ name?: string;
20
+ }
@@ -0,0 +1,10 @@
1
+ # Shared UI Components
2
+
3
+ shadcn/ui components shared between pidash-ui and pidiff-ui.
4
+ Both UIs import these via the `@ui` Vite alias.
5
+
6
+ To add a new shared component, place it here and it's automatically
7
+ available in both UIs via `import { X } from "@ui/component-name"`.
8
+
9
+ Components unique to one UI (e.g. pidiff's `switch.tsx`) stay in that UI's
10
+ local `components/ui/` directory.
@@ -0,0 +1,52 @@
1
+ import { mergeProps } from "@base-ui/react/merge-props"
2
+ import { useRender } from "@base-ui/react/use-render"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const badgeVariants = cva(
8
+ "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
13
+ secondary:
14
+ "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
15
+ destructive:
16
+ "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
17
+ outline:
18
+ "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
19
+ ghost:
20
+ "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
21
+ link: "text-primary underline-offset-4 hover:underline",
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ variant: "default",
26
+ },
27
+ }
28
+ )
29
+
30
+ function Badge({
31
+ className,
32
+ variant = "default",
33
+ render,
34
+ ...props
35
+ }: useRender.ComponentProps<"span"> & VariantProps<typeof badgeVariants>) {
36
+ return useRender({
37
+ defaultTagName: "span",
38
+ props: mergeProps<"span">(
39
+ {
40
+ className: cn(badgeVariants({ variant }), className),
41
+ },
42
+ props
43
+ ),
44
+ render,
45
+ state: {
46
+ slot: "badge",
47
+ variant,
48
+ },
49
+ })
50
+ }
51
+
52
+ export { Badge, badgeVariants }
@@ -0,0 +1,58 @@
1
+ import { Button as ButtonPrimitive } from "@base-ui/react/button"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ const buttonVariants = cva(
7
+ "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
12
+ outline:
13
+ "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
14
+ secondary:
15
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
16
+ ghost:
17
+ "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
18
+ destructive:
19
+ "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
20
+ link: "text-primary underline-offset-4 hover:underline",
21
+ },
22
+ size: {
23
+ default:
24
+ "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
25
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
26
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
27
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
28
+ icon: "size-8",
29
+ "icon-xs":
30
+ "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
31
+ "icon-sm":
32
+ "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
33
+ "icon-lg": "size-9",
34
+ },
35
+ },
36
+ defaultVariants: {
37
+ variant: "default",
38
+ size: "default",
39
+ },
40
+ }
41
+ )
42
+
43
+ function Button({
44
+ className,
45
+ variant = "default",
46
+ size = "default",
47
+ ...props
48
+ }: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {
49
+ return (
50
+ <ButtonPrimitive
51
+ data-slot="button"
52
+ className={cn(buttonVariants({ variant, size, className }))}
53
+ {...props}
54
+ />
55
+ )
56
+ }
57
+
58
+ export { Button, buttonVariants }
@@ -0,0 +1,21 @@
1
+ "use client"
2
+
3
+ import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible"
4
+
5
+ function Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {
6
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
7
+ }
8
+
9
+ function CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {
10
+ return (
11
+ <CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />
12
+ )
13
+ }
14
+
15
+ function CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {
16
+ return (
17
+ <CollapsiblePrimitive.Panel data-slot="collapsible-content" {...props} />
18
+ )
19
+ }
20
+
21
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }