@guildai/cli 0.10.0 → 0.12.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 (203) hide show
  1. package/dist/auth-CRMO5O3N.js +29 -0
  2. package/dist/auth-CRMO5O3N.js.map +7 -0
  3. package/dist/chat-5VX2WJH2.js +303 -0
  4. package/dist/chat-5VX2WJH2.js.map +7 -0
  5. package/dist/chat-SIKDYZQK.js +31 -0
  6. package/dist/chat-SIKDYZQK.js.map +7 -0
  7. package/dist/chunk-56YCMGL3.js +522 -0
  8. package/dist/chunk-56YCMGL3.js.map +7 -0
  9. package/dist/chunk-6EX6E7WP.js +7042 -0
  10. package/dist/chunk-6EX6E7WP.js.map +7 -0
  11. package/dist/chunk-B7VAF5UG.js +532 -0
  12. package/dist/chunk-B7VAF5UG.js.map +7 -0
  13. package/dist/chunk-DOIYVBNY.js +3057 -0
  14. package/dist/chunk-DOIYVBNY.js.map +7 -0
  15. package/dist/chunk-ENKEEJ45.js +17 -0
  16. package/dist/chunk-ENKEEJ45.js.map +7 -0
  17. package/dist/chunk-IBRKVGMZ.js +97041 -0
  18. package/dist/chunk-IBRKVGMZ.js.map +7 -0
  19. package/dist/chunk-LFMQJOKC.js +19778 -0
  20. package/dist/chunk-LFMQJOKC.js.map +7 -0
  21. package/dist/chunk-M347HP6M.js +22896 -0
  22. package/dist/chunk-M347HP6M.js.map +7 -0
  23. package/dist/chunk-OYQ476FQ.js +44 -0
  24. package/dist/chunk-OYQ476FQ.js.map +7 -0
  25. package/dist/chunk-PNCUR4OB.js +257 -0
  26. package/dist/chunk-PNCUR4OB.js.map +7 -0
  27. package/dist/chunk-RIG2HZWM.js +317 -0
  28. package/dist/chunk-RIG2HZWM.js.map +7 -0
  29. package/dist/chunk-SPZPZXUN.js +826 -0
  30. package/dist/chunk-SPZPZXUN.js.map +7 -0
  31. package/dist/chunk-VVSOU6ON.js +53 -0
  32. package/dist/chunk-VVSOU6ON.js.map +7 -0
  33. package/dist/chunk-X3ADGWOF.js +3643 -0
  34. package/dist/chunk-X3ADGWOF.js.map +7 -0
  35. package/dist/commands/agent/logs.d.ts +3 -0
  36. package/dist/commands/setup.d.ts +16 -0
  37. package/dist/commands/skill/create.d.ts +3 -0
  38. package/dist/commands/skill/get.d.ts +3 -0
  39. package/dist/commands/skill/list.d.ts +3 -0
  40. package/dist/commands/skill/update.d.ts +3 -0
  41. package/dist/commands/skill/version/create.d.ts +3 -0
  42. package/dist/commands/skill/version/get.d.ts +3 -0
  43. package/dist/commands/skill/version/list.d.ts +3 -0
  44. package/dist/devtools-AO7YSDOD.js +67 -0
  45. package/dist/devtools-AO7YSDOD.js.map +7 -0
  46. package/dist/dist-4CBK6X5H.js +1566 -0
  47. package/dist/dist-4CBK6X5H.js.map +7 -0
  48. package/dist/esm-FRAVZP4J.js +13 -0
  49. package/dist/esm-FRAVZP4J.js.map +7 -0
  50. package/dist/execa-XQMWSABC.js +35 -0
  51. package/dist/execa-XQMWSABC.js.map +7 -0
  52. package/dist/index.js +8231 -253
  53. package/dist/index.js.map +7 -0
  54. package/dist/lib/api-types.d.ts +44 -0
  55. package/dist/lib/auth.d.ts +1 -1
  56. package/dist/lib/config.d.ts +9 -0
  57. package/dist/lib/errors.d.ts +1 -1
  58. package/dist/lib/output-mode.d.ts +9 -2
  59. package/dist/lib/output.d.ts +17 -1
  60. package/dist/lib/session-events.d.ts +14 -3
  61. package/dist/lib/session-polling.d.ts +24 -1
  62. package/dist/lib/session-resume.d.ts +15 -1
  63. package/dist/lib/stdin.d.ts +5 -1
  64. package/dist/lib/websocket-client.d.ts +46 -0
  65. package/dist/open-RF4X5MOP.js +13 -0
  66. package/dist/open-RF4X5MOP.js.map +7 -0
  67. package/dist/server-JYVH64FD.js +27659 -0
  68. package/dist/server-JYVH64FD.js.map +7 -0
  69. package/dist/test-SNIYRJ32.js +692 -0
  70. package/dist/test-SNIYRJ32.js.map +7 -0
  71. package/docs/skills/codex-agent-dev.md +2 -2
  72. package/package.json +8 -12
  73. package/dist/commands/agent/chat.js +0 -278
  74. package/dist/commands/agent/clone.js +0 -116
  75. package/dist/commands/agent/code.js +0 -87
  76. package/dist/commands/agent/fork.js +0 -218
  77. package/dist/commands/agent/get.js +0 -37
  78. package/dist/commands/agent/grep.js +0 -107
  79. package/dist/commands/agent/init.js +0 -390
  80. package/dist/commands/agent/list.js +0 -110
  81. package/dist/commands/agent/owners.js +0 -74
  82. package/dist/commands/agent/publish.js +0 -91
  83. package/dist/commands/agent/pull.js +0 -198
  84. package/dist/commands/agent/revalidate.js +0 -56
  85. package/dist/commands/agent/save.js +0 -346
  86. package/dist/commands/agent/search.js +0 -61
  87. package/dist/commands/agent/tags/add.js +0 -73
  88. package/dist/commands/agent/tags/list.js +0 -43
  89. package/dist/commands/agent/tags/remove.js +0 -84
  90. package/dist/commands/agent/tags/set.js +0 -71
  91. package/dist/commands/agent/test.js +0 -486
  92. package/dist/commands/agent/unpublish.js +0 -64
  93. package/dist/commands/agent/update.js +0 -110
  94. package/dist/commands/agent/versions.js +0 -55
  95. package/dist/commands/agent/workspaces.js +0 -54
  96. package/dist/commands/auth/login.js +0 -33
  97. package/dist/commands/auth/logout.js +0 -24
  98. package/dist/commands/auth/status.js +0 -38
  99. package/dist/commands/auth/token.js +0 -19
  100. package/dist/commands/chat.js +0 -1345
  101. package/dist/commands/config/get.js +0 -64
  102. package/dist/commands/config/list.js +0 -47
  103. package/dist/commands/config/path.js +0 -38
  104. package/dist/commands/config/set.js +0 -132
  105. package/dist/commands/credentials/endpoint-list.js +0 -88
  106. package/dist/commands/credentials/list.js +0 -50
  107. package/dist/commands/credentials/policy-create.js +0 -66
  108. package/dist/commands/credentials/policy-delete.js +0 -33
  109. package/dist/commands/credentials/policy-list.js +0 -45
  110. package/dist/commands/credentials/policy-update.js +0 -66
  111. package/dist/commands/doctor.js +0 -233
  112. package/dist/commands/integration/connect.js +0 -76
  113. package/dist/commands/integration/create.js +0 -298
  114. package/dist/commands/integration/get.js +0 -95
  115. package/dist/commands/integration/list.js +0 -62
  116. package/dist/commands/integration/operation/create.js +0 -164
  117. package/dist/commands/integration/operation/list.js +0 -92
  118. package/dist/commands/integration/update.js +0 -139
  119. package/dist/commands/integration/version/build.js +0 -86
  120. package/dist/commands/integration/version/create.js +0 -45
  121. package/dist/commands/integration/version/get.js +0 -72
  122. package/dist/commands/integration/version/list.js +0 -45
  123. package/dist/commands/integration/version/publish.js +0 -79
  124. package/dist/commands/integration/version/test.js +0 -104
  125. package/dist/commands/job/get-step.js +0 -40
  126. package/dist/commands/job/get.js +0 -44
  127. package/dist/commands/mcp.js +0 -34
  128. package/dist/commands/session/create.js +0 -59
  129. package/dist/commands/session/events.js +0 -56
  130. package/dist/commands/session/get.js +0 -33
  131. package/dist/commands/session/interrupt.js +0 -33
  132. package/dist/commands/session/list.js +0 -59
  133. package/dist/commands/session/send.js +0 -54
  134. package/dist/commands/session/tasks.js +0 -45
  135. package/dist/commands/setup.js +0 -230
  136. package/dist/commands/trigger/activate.js +0 -41
  137. package/dist/commands/trigger/create.js +0 -197
  138. package/dist/commands/trigger/deactivate.js +0 -41
  139. package/dist/commands/trigger/get.js +0 -33
  140. package/dist/commands/trigger/list.js +0 -57
  141. package/dist/commands/trigger/sessions.js +0 -48
  142. package/dist/commands/trigger/update.js +0 -128
  143. package/dist/commands/version.js +0 -24
  144. package/dist/commands/workspace/agent/add.js +0 -114
  145. package/dist/commands/workspace/agent/list.js +0 -78
  146. package/dist/commands/workspace/agent/remove.js +0 -78
  147. package/dist/commands/workspace/clear.js +0 -45
  148. package/dist/commands/workspace/context/edit.js +0 -107
  149. package/dist/commands/workspace/context/get.js +0 -47
  150. package/dist/commands/workspace/context/list.js +0 -51
  151. package/dist/commands/workspace/context/publish.js +0 -42
  152. package/dist/commands/workspace/create.js +0 -51
  153. package/dist/commands/workspace/current.js +0 -63
  154. package/dist/commands/workspace/get.js +0 -39
  155. package/dist/commands/workspace/list.js +0 -70
  156. package/dist/commands/workspace/select.js +0 -184
  157. package/dist/components/AgentInstallPrompt.js +0 -97
  158. package/dist/components/SplashAnimation.js +0 -321
  159. package/dist/components/TaskView.js +0 -268
  160. package/dist/lib/agent-helpers.js +0 -306
  161. package/dist/lib/alternate-screen.js +0 -59
  162. package/dist/lib/api-client.js +0 -154
  163. package/dist/lib/api-types.js +0 -10
  164. package/dist/lib/auth.js +0 -284
  165. package/dist/lib/braille-canvas.js +0 -321
  166. package/dist/lib/colors.js +0 -46
  167. package/dist/lib/config-cache.js +0 -45
  168. package/dist/lib/config.js +0 -153
  169. package/dist/lib/did-you-mean.js +0 -144
  170. package/dist/lib/errors.js +0 -375
  171. package/dist/lib/event-filter.js +0 -91
  172. package/dist/lib/generated-types.js +0 -56
  173. package/dist/lib/git.js +0 -176
  174. package/dist/lib/gk.js +0 -91
  175. package/dist/lib/guild-config.js +0 -178
  176. package/dist/lib/iap.js +0 -117
  177. package/dist/lib/integration-helpers.js +0 -38
  178. package/dist/lib/loading-messages.js +0 -72
  179. package/dist/lib/logo.js +0 -141
  180. package/dist/lib/lottie-serverside.js +0 -181
  181. package/dist/lib/markdown.js +0 -38
  182. package/dist/lib/npmrc.js +0 -59
  183. package/dist/lib/output-mode.js +0 -33
  184. package/dist/lib/output.js +0 -591
  185. package/dist/lib/owner-helpers.js +0 -112
  186. package/dist/lib/polling.js +0 -76
  187. package/dist/lib/progress.js +0 -324
  188. package/dist/lib/session-events-fetch.js +0 -25
  189. package/dist/lib/session-events.js +0 -112
  190. package/dist/lib/session-polling.js +0 -160
  191. package/dist/lib/session-resume.js +0 -96
  192. package/dist/lib/spinners.js +0 -770
  193. package/dist/lib/splash.js +0 -41
  194. package/dist/lib/stdin.js +0 -84
  195. package/dist/lib/svg-to-braille.js +0 -76
  196. package/dist/lib/table.js +0 -59
  197. package/dist/lib/update-check.js +0 -65
  198. package/dist/lib/validate-input-schema.js +0 -208
  199. package/dist/lib/version-helpers.js +0 -121
  200. package/dist/lib/workspace-helpers.js +0 -49
  201. package/dist/mcp/resources.js +0 -67
  202. package/dist/mcp/server.js +0 -64
  203. package/dist/mcp/tools.js +0 -753
@@ -1,97 +0,0 @@
1
- // Copyright 2026 Guild.ai
2
- // SPDX-License-Identifier: Apache-2.0
3
- import React, { useState } from 'react';
4
- import { Box, Text, useInput } from 'ink';
5
- import chalk from 'chalk';
6
- // Brand color for Guild
7
- const brand = (text) => chalk.hex('#F97316')(text);
8
- /**
9
- * AgentInstallPrompt - Interactive prompt for agent installation requests
10
- *
11
- * Shows agent info and prompts user to approve or decline installation.
12
- */
13
- export function AgentInstallPrompt({ event, onApprove, onDecline, onComplete, }) {
14
- const [state, setState] = useState('waiting');
15
- const [errorMessage, setErrorMessage] = useState('');
16
- useInput((input, key) => {
17
- if (state !== 'waiting')
18
- return;
19
- const lowerInput = input.toLowerCase();
20
- if (lowerInput === 'y' || key.return) {
21
- // Approve
22
- setState('approving');
23
- onApprove()
24
- .then(() => {
25
- setState('approved');
26
- setTimeout(onComplete, 500);
27
- })
28
- .catch((err) => {
29
- setState('error');
30
- setErrorMessage(err.message);
31
- setTimeout(onComplete, 2000);
32
- });
33
- }
34
- else if (lowerInput === 'n' || key.escape) {
35
- // Decline
36
- setState('declining');
37
- onDecline()
38
- .then(() => {
39
- setState('declined');
40
- setTimeout(onComplete, 500);
41
- })
42
- .catch((err) => {
43
- setState('error');
44
- setErrorMessage(err.message);
45
- setTimeout(onComplete, 2000);
46
- });
47
- }
48
- });
49
- const agent = event.requested_agent;
50
- // Render based on state
51
- if (state === 'approved') {
52
- return (React.createElement(Box, { marginY: 1 },
53
- React.createElement(Text, { color: "green" },
54
- " Agent \"",
55
- agent.name,
56
- "\" has been installed")));
57
- }
58
- if (state === 'declined') {
59
- return (React.createElement(Box, { marginY: 1 },
60
- React.createElement(Text, { dimColor: true }, " Agent installation skipped")));
61
- }
62
- if (state === 'error') {
63
- return (React.createElement(Box, { marginY: 1 },
64
- React.createElement(Text, { color: "red" },
65
- " Error: ",
66
- errorMessage)));
67
- }
68
- if (state === 'approving') {
69
- return (React.createElement(Box, { marginY: 1 },
70
- React.createElement(Text, { dimColor: true }, " Installing agent...")));
71
- }
72
- if (state === 'declining') {
73
- return (React.createElement(Box, { marginY: 1 },
74
- React.createElement(Text, { dimColor: true }, " Skipping...")));
75
- }
76
- // Waiting state - show prompt
77
- return (React.createElement(Box, { flexDirection: "column", marginY: 1 },
78
- React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 2, paddingY: 1 },
79
- React.createElement(Text, { bold: true, color: "yellow" }, "Agent Installation Request"),
80
- React.createElement(Text, null, " "),
81
- React.createElement(Text, null, "The assistant found an agent that could help with your request:"),
82
- React.createElement(Text, null, " "),
83
- React.createElement(Box, { paddingLeft: 2, flexDirection: "column" },
84
- React.createElement(Text, null,
85
- React.createElement(Text, { bold: true }, "Name:"),
86
- " ",
87
- brand(agent.name)),
88
- React.createElement(Text, null,
89
- React.createElement(Text, { bold: true }, "Description:"),
90
- " ",
91
- agent.description)),
92
- React.createElement(Text, null, " "),
93
- React.createElement(Text, null,
94
- "Install this agent? ",
95
- React.createElement(Text, { dimColor: true }, "[Y/n]")))));
96
- }
97
- //# sourceMappingURL=AgentInstallPrompt.js.map
@@ -1,321 +0,0 @@
1
- // Copyright 2026 Guild.ai
2
- // SPDX-License-Identifier: Apache-2.0
3
- import React, { useState, useEffect, useRef, useCallback } from 'react';
4
- import { Box, Text, useStdout, useInput } from 'ink';
5
- import chalk from 'chalk';
6
- import { getRandomMessage, LOADING_TIMINGS } from '../lib/loading-messages.js';
7
- import { renderLottieFrameToBraille, } from '../lib/lottie-serverside.js';
8
- import * as fs from 'fs';
9
- import * as path from 'path';
10
- import { fileURLToPath } from 'url';
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = path.dirname(__filename);
13
- // Frame rate tuning
14
- const FRAME_INTERVAL = 33; // ~30fps
15
- const FADE_INTERVAL = 16; // ~60fps
16
- // Star/particle characters with varying brightness
17
- const STAR_CHARS = ['·', '✦', '✧', '⋆', '∗', '˖'];
18
- // Guild orange palette (matching www TetrisBlocksBackground)
19
- const GUILD_ORANGE_COLORS = [
20
- { r: 255, g: 85, b: 0 }, // #FF5500 - Primary
21
- { r: 255, g: 132, b: 64 }, // #FF8440
22
- { r: 255, g: 179, b: 128 }, // #FFB380
23
- { r: 255, g: 204, b: 170 }, // #FFCCAA
24
- ];
25
- /**
26
- * Animated full-screen splash animation for Guild CLI
27
- * Features:
28
- * - SVG logo rendered to braille with fade-in effect
29
- * - Particle/starfield background with twinkling
30
- * - Rotating loading messages
31
- * - Full screen centered layout
32
- */
33
- export function SplashAnimation({ status, onComplete, onEscapePress, version, isFinalizing = false, }) {
34
- const { stdout } = useStdout();
35
- // Track terminal size with resize handler
36
- const [terminalSize, setTerminalSize] = useState({
37
- width: stdout?.columns || 80,
38
- height: stdout?.rows || 24,
39
- });
40
- useEffect(() => {
41
- const handleResize = () => {
42
- setTerminalSize({
43
- width: process.stdout.columns || 80,
44
- height: process.stdout.rows || 24,
45
- });
46
- };
47
- process.stdout.on('resize', handleResize);
48
- return () => {
49
- process.stdout.off('resize', handleResize);
50
- };
51
- }, []);
52
- const width = terminalSize.width;
53
- const height = terminalSize.height;
54
- // All hooks must be called before any conditional returns
55
- const [tick, setTick] = useState(0);
56
- const [message, setMessage] = useState(getRandomMessage());
57
- const [messageOpacity, setMessageOpacity] = useState(0);
58
- const [particles, setParticles] = useState([]);
59
- const [currentFrame, setCurrentFrame] = useState(0);
60
- const [animationData, setAnimationData] = useState(null);
61
- const [totalFrames, setTotalFrames] = useState(0);
62
- const [renderedFrame, setRenderedFrame] = useState(null);
63
- const lastRenderedFrame = useRef(-1); // Track which frame was rendered (ref to avoid state churn)
64
- const renderingFrame = useRef(-1); // Track which frame is currently being rendered
65
- const lastDimensions = useRef({ width: 0, height: 0 }); // Track dimensions for resize detection
66
- const startTime = useRef(Date.now());
67
- const messageStartTime = useRef(Date.now());
68
- // Reset frame rendering when terminal dimensions change (for resize support)
69
- useEffect(() => {
70
- if (lastDimensions.current.width !== width ||
71
- lastDimensions.current.height !== height) {
72
- lastDimensions.current = { width, height };
73
- // Force re-render of current frame at new dimensions
74
- lastRenderedFrame.current = -1;
75
- renderingFrame.current = -1;
76
- setRenderedFrame(null);
77
- }
78
- }, [width, height]);
79
- // Handle Esc key or Ctrl-C to exit splash screen early
80
- useInput((input, key) => {
81
- if (key.escape && onEscapePress) {
82
- onEscapePress();
83
- }
84
- // Ctrl-C should exit the CLI entirely
85
- if (input === 'c' && key.ctrl) {
86
- process.exit(0);
87
- }
88
- });
89
- // Calculate logo dimensions - use full terminal space
90
- const logoWidthChars = width;
91
- const logoHeightChars = height;
92
- const centerX = 0;
93
- const centerY = 0;
94
- // Load Lottie animation data (for real-time rendering)
95
- useEffect(() => {
96
- const possiblePaths = [
97
- path.resolve(__dirname, '../assets/logo-animation.json'),
98
- path.resolve(__dirname, '../../src/assets/logo-animation.json'),
99
- ];
100
- let loadedData = null;
101
- for (const animPath of possiblePaths) {
102
- if (fs.existsSync(animPath)) {
103
- const content = fs.readFileSync(animPath, 'utf-8');
104
- loadedData = JSON.parse(content);
105
- break;
106
- }
107
- }
108
- if (loadedData) {
109
- setAnimationData(loadedData);
110
- setTotalFrames(Math.floor(loadedData.op || 0));
111
- // Reset start time so animation begins from frame 0 after loading
112
- startTime.current = Date.now();
113
- }
114
- }, []);
115
- // Update current frame - sequential for intro, time-based after
116
- useEffect(() => {
117
- if (totalFrames === 0)
118
- return;
119
- const maxFrame = Math.floor(totalFrames * 0.9);
120
- // For first 45 frames (1.5 sec of intro), use sequential advancement
121
- // This ensures the intro animation plays smoothly without skipping
122
- // After that, allow time-based advancement to catch up if needed
123
- const introFrames = 45;
124
- const useSequential = lastRenderedFrame.current < introFrames;
125
- let targetFrame;
126
- if (useSequential) {
127
- // Sequential: advance as soon as previous frame has rendered
128
- if (lastRenderedFrame.current >= currentFrame) {
129
- targetFrame = currentFrame + 1;
130
- }
131
- else {
132
- targetFrame = currentFrame; // Hold until render completes
133
- }
134
- }
135
- else {
136
- // Time-based: follow the clock after intro
137
- const elapsed = Date.now() - startTime.current;
138
- const fps = 30;
139
- const frameNumber = Math.floor((elapsed / 1000) * fps);
140
- targetFrame = Math.min(frameNumber, lastRenderedFrame.current + 1);
141
- }
142
- targetFrame = Math.min(targetFrame, maxFrame);
143
- if (targetFrame >= maxFrame) {
144
- // Animation complete
145
- setCurrentFrame(maxFrame);
146
- if (onComplete) {
147
- onComplete();
148
- }
149
- }
150
- else if (targetFrame !== currentFrame) {
151
- setCurrentFrame(targetFrame);
152
- }
153
- }, [tick, totalFrames, onComplete, currentFrame]);
154
- // Render the current frame asynchronously
155
- useEffect(() => {
156
- if (!animationData || currentFrame >= totalFrames)
157
- return;
158
- // Don't re-render a frame we've already rendered or are currently rendering
159
- if (currentFrame <= lastRenderedFrame.current ||
160
- currentFrame === renderingFrame.current) {
161
- return;
162
- }
163
- // Mark this frame as being rendered
164
- const frameToRender = currentFrame;
165
- renderingFrame.current = frameToRender;
166
- let cancelled = false;
167
- renderLottieFrameToBraille(animationData, frameToRender, logoWidthChars, logoHeightChars)
168
- .then((lines) => {
169
- if (!cancelled && frameToRender > lastRenderedFrame.current) {
170
- setRenderedFrame(lines);
171
- lastRenderedFrame.current = frameToRender;
172
- }
173
- })
174
- .catch((error) => {
175
- console.error('Error rendering Lottie frame:', error);
176
- });
177
- return () => {
178
- cancelled = true;
179
- };
180
- }, [animationData, currentFrame, totalFrames, logoWidthChars, logoHeightChars]);
181
- // Initialize particles for starfield background
182
- useEffect(() => {
183
- const newParticles = [];
184
- const particleCount = Math.floor((width * height) / 100);
185
- for (let i = 0; i < particleCount; i++) {
186
- newParticles.push({
187
- x: Math.random() * width,
188
- y: Math.random() * height,
189
- char: STAR_CHARS[Math.floor(Math.random() * STAR_CHARS.length)],
190
- opacity: 0.1 + Math.random() * 0.4,
191
- twinkleSpeed: 0.5 + Math.random() * 1.5,
192
- twinklePhase: Math.random() * Math.PI * 2,
193
- colorIndex: Math.floor(Math.random() * GUILD_ORANGE_COLORS.length),
194
- });
195
- }
196
- setParticles(newParticles);
197
- }, [width, height]);
198
- // Animation loop for particle updates
199
- useEffect(() => {
200
- const interval = setInterval(() => {
201
- setTick((t) => t + 1);
202
- }, FRAME_INTERVAL);
203
- return () => clearInterval(interval);
204
- }, []);
205
- // Animate loading message opacity (fade in/out)
206
- useEffect(() => {
207
- // Start with fade in
208
- messageStartTime.current = Date.now();
209
- const interval = setInterval(() => {
210
- const elapsed = Date.now() - messageStartTime.current;
211
- const cycleTime = LOADING_TIMINGS.messageRotation;
212
- const fadeTime = LOADING_TIMINGS.messageFade;
213
- const position = elapsed % cycleTime;
214
- if (position < fadeTime) {
215
- // Fade in
216
- setMessageOpacity(position / fadeTime);
217
- }
218
- else if (position < cycleTime - fadeTime) {
219
- // Hold at full opacity
220
- setMessageOpacity(1);
221
- }
222
- else {
223
- // Fade out
224
- const fadeOutProgress = (position - (cycleTime - fadeTime)) / fadeTime;
225
- setMessageOpacity(1 - fadeOutProgress);
226
- }
227
- }, FADE_INTERVAL);
228
- return () => clearInterval(interval);
229
- }, []);
230
- // Rotate loading messages
231
- useEffect(() => {
232
- const interval = setInterval(() => {
233
- setMessage(getRandomMessage());
234
- messageStartTime.current = Date.now();
235
- setMessageOpacity(0);
236
- }, LOADING_TIMINGS.messageRotation);
237
- return () => clearInterval(interval);
238
- }, []);
239
- // Render particles with twinkling effect
240
- const renderParticles = useCallback(() => {
241
- const chars = Array(height)
242
- .fill(null)
243
- .map(() => Array(width).fill(' '));
244
- particles.forEach((p) => {
245
- const x = Math.floor(p.x);
246
- const y = Math.floor(p.y);
247
- if (x >= 0 && x < width && y >= 0 && y < height) {
248
- // Twinkle effect
249
- const twinkle = Math.sin(tick * 0.1 * p.twinkleSpeed + p.twinklePhase) * 0.5 + 0.5;
250
- const brightness = p.opacity * (0.3 + twinkle * 0.7);
251
- // Edge fade (vignette effect)
252
- const distFromCenterX = Math.abs(x - width / 2) / (width / 2);
253
- const distFromCenterY = Math.abs(y - height / 2) / (height / 2);
254
- const distFromCenter = Math.sqrt(distFromCenterX * distFromCenterX + distFromCenterY * distFromCenterY);
255
- const edgeFade = Math.max(0, 1 - distFromCenter * 0.8);
256
- const finalBrightness = brightness * edgeFade;
257
- if (finalBrightness > 0.1) {
258
- // Use Guild orange colors instead of grayscale
259
- const color = GUILD_ORANGE_COLORS[p.colorIndex];
260
- const r = Math.floor(color.r * finalBrightness);
261
- const g = Math.floor(color.g * finalBrightness);
262
- const b = Math.floor(color.b * finalBrightness);
263
- chars[y][x] = chalk.rgb(r, g, b)(p.char);
264
- }
265
- }
266
- });
267
- return chars;
268
- }, [particles, tick, width, height]);
269
- // Render the Lottie frame (uses pre-rendered frame from state)
270
- const renderLogo = useCallback((chars) => {
271
- // Don't render until we have a rendered frame
272
- if (!renderedFrame)
273
- return;
274
- renderedFrame.forEach((line, row) => {
275
- const y = centerY + row;
276
- if (y >= 0 && y < height) {
277
- [...line].forEach((char, col) => {
278
- const x = centerX + col;
279
- if (x >= 0 && x < width && char !== '⠀') {
280
- // Use default terminal text color for compatibility with all themes
281
- chars[y][x] = char;
282
- }
283
- });
284
- }
285
- });
286
- }, [centerX, centerY, width, height, renderedFrame]);
287
- // Build the frame
288
- const chars = renderParticles();
289
- renderLogo(chars);
290
- // Convert to lines
291
- const lines = chars.map((row) => row.join(''));
292
- // Message positions
293
- // Rotating messages: below logo (about 75% down the screen)
294
- // Status ticker: near the bottom
295
- const loadingMessageY = Math.floor(height * 0.68);
296
- const statusY = height - 2;
297
- // Apply opacity for fade effect
298
- // Use a range that works on both light and dark terminals
299
- const applyOpacity = (text, opacity) => {
300
- // Map opacity 0-1 to grayscale range 150-255 for better visibility on dark backgrounds
301
- const minBrightness = 150;
302
- const maxBrightness = 255;
303
- const gray = Math.floor(minBrightness + opacity * (maxBrightness - minBrightness));
304
- return chalk.rgb(gray, gray, gray)(text);
305
- };
306
- // When finalizing, show final frame with version text (no status line)
307
- if (isFinalizing) {
308
- const versionText = version ? `Guild CLI v${version}` : 'Guild CLI';
309
- return (React.createElement(Box, { flexDirection: "column", width: width, height: height },
310
- lines.map((line, i) => (React.createElement(Text, { key: i }, line))),
311
- React.createElement(Box, { position: "absolute", marginTop: loadingMessageY, width: width, justifyContent: "center" },
312
- React.createElement(Text, null, chalk.bold(versionText)))));
313
- }
314
- return (React.createElement(Box, { flexDirection: "column", width: width, height: height },
315
- lines.map((line, i) => (React.createElement(Text, { key: i }, line))),
316
- React.createElement(Box, { position: "absolute", marginTop: statusY, width: width, justifyContent: "center" },
317
- React.createElement(Text, null, chalk.dim(status))),
318
- React.createElement(Box, { position: "absolute", marginTop: loadingMessageY, width: width, justifyContent: "center" },
319
- React.createElement(Text, null, applyOpacity(message, messageOpacity)))));
320
- }
321
- //# sourceMappingURL=SplashAnimation.js.map
@@ -1,268 +0,0 @@
1
- // Copyright 2026 Guild.ai
2
- // SPDX-License-Identifier: Apache-2.0
3
- import React, { useState, useEffect } from 'react';
4
- import { Box, Text, useInput } from 'ink';
5
- import { getTaskDisplayName, isFilteredTaskName, } from '../lib/session-events.js';
6
- // Status colors (matching web: bg-status-* Tailwind classes)
7
- const STATUS_COLORS = {
8
- CREATED: '#6b7280', // gray (pending)
9
- STARTED: '#6b7280', // gray (pending)
10
- RUNNING: '#3b82f6', // blue (info)
11
- WAITING: '#b8860b', // dark goldenrod (readable on light and dark terminals)
12
- DONE: '#22c55e', // green (success)
13
- ERROR: '#ef4444', // red (error)
14
- INTERRUPTED: '#b8860b', // dark goldenrod (warning)
15
- };
16
- // Status icons (for completed/static states)
17
- const STATUS_ICONS = {
18
- CREATED: '○',
19
- STARTED: '○',
20
- RUNNING: '●',
21
- WAITING: '◐',
22
- DONE: '✓',
23
- ERROR: '✗',
24
- INTERRUPTED: '⊘',
25
- };
26
- // Animation frames for running tasks (alternates between empty and filled)
27
- const RUNNING_ANIMATION_FRAMES = ['○', '●'];
28
- const RUNNING_ANIMATION_INTERVAL_MS = 1000; // Toggle every 1s
29
- // Show this many completed tasks before collapsing the rest
30
- const VISIBLE_COMPLETED_COUNT = 5;
31
- /**
32
- * Get status color for a task
33
- */
34
- export function getStatusColor(status) {
35
- return STATUS_COLORS[status] || STATUS_COLORS.CREATED;
36
- }
37
- /**
38
- * Get status icon for a task
39
- */
40
- export function getStatusIcon(status) {
41
- return STATUS_ICONS[status] || STATUS_ICONS.CREATED;
42
- }
43
- /**
44
- * Check if a task status is "active" (not completed)
45
- */
46
- function isActiveStatus(status) {
47
- return (status === 'CREATED' ||
48
- status === 'STARTED' ||
49
- status === 'RUNNING' ||
50
- status === 'WAITING');
51
- }
52
- /**
53
- * Check if a task is completed (done or error)
54
- */
55
- function isCompletedStatus(status) {
56
- return status === 'DONE' || status === 'ERROR';
57
- }
58
- /**
59
- * Format task duration in compact form
60
- * For completed tasks: duration from created_at to updated_at
61
- * For active tasks: elapsed time since created_at
62
- * Returns empty string for very short durations (<5s)
63
- */
64
- function formatTaskDuration(task) {
65
- const createdAt = new Date(task.created_at);
66
- const endTime = isActiveStatus(task.status) ? new Date() : new Date(task.updated_at);
67
- const diffMs = endTime.getTime() - createdAt.getTime();
68
- const diffSec = Math.floor(diffMs / 1000);
69
- const diffMin = Math.floor(diffSec / 60);
70
- const diffHr = Math.floor(diffMin / 60);
71
- if (diffSec < 5)
72
- return '';
73
- if (diffSec < 60)
74
- return `${diffSec}s`;
75
- if (diffMin < 60)
76
- return `${diffMin}m`;
77
- if (diffHr < 24)
78
- return `${diffHr}h`;
79
- return createdAt.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
80
- }
81
- /**
82
- * Calculate depth for each task based on parent chain
83
- * Returns a Map of task ID -> depth (0 for root tasks)
84
- */
85
- function calculateTaskDepths(tasks) {
86
- const depthMap = new Map();
87
- const taskMap = new Map(tasks.map((t) => [t.id, t]));
88
- function getDepth(taskId) {
89
- if (depthMap.has(taskId))
90
- return depthMap.get(taskId) ?? 0;
91
- const task = taskMap.get(taskId);
92
- const parentId = task?.parent_task?.id;
93
- if (!parentId) {
94
- depthMap.set(taskId, 0);
95
- return 0;
96
- }
97
- const parentDepth = getDepth(parentId);
98
- const depth = parentDepth + 1;
99
- depthMap.set(taskId, depth);
100
- return depth;
101
- }
102
- tasks.forEach((t) => getDepth(t.id));
103
- return depthMap;
104
- }
105
- /**
106
- * TaskView - Hierarchical task tree display (matching web SessionDetailsSidebar)
107
- *
108
- * Shows tasks in a tree format with colored status dots:
109
- * ● assistant 19s
110
- * └ ✓ coding 15s
111
- *
112
- * Features:
113
- * - Tree prefixes (└) for child tasks
114
- * - Colored status dots (gray=pending, blue=running, yellow=waiting, green=done, red=error)
115
- * - Animated icons for running tasks (alternates between ○ and ●)
116
- * - Duration display (elapsed for active, final for completed)
117
- * - Collapsible completed tasks (Ctrl+O to expand/collapse)
118
- */
119
- export function TaskView({ tasks }) {
120
- // Animation state for running tasks
121
- const [animationFrame, setAnimationFrame] = useState(0);
122
- // Expanded state for completed tasks
123
- const [expanded, setExpanded] = useState(false);
124
- // Handle Ctrl+O to toggle expand/collapse
125
- useInput((input, key) => {
126
- if (input === 'o' && key.ctrl) {
127
- setExpanded((e) => !e);
128
- }
129
- });
130
- // Check if we have any running tasks that need animation
131
- const hasRunningTasks = tasks.some((t) => t.status === 'RUNNING' || t.status === 'STARTED');
132
- // Animate running task icons
133
- useEffect(() => {
134
- if (!hasRunningTasks)
135
- return;
136
- const interval = setInterval(() => {
137
- setAnimationFrame((f) => (f + 1) % RUNNING_ANIMATION_FRAMES.length);
138
- }, RUNNING_ANIMATION_INTERVAL_MS);
139
- return () => clearInterval(interval);
140
- }, [hasRunningTasks]);
141
- if (tasks.length === 0)
142
- return null;
143
- // Filter out internal tasks (ui_prompt, etc.)
144
- const filteredTasks = tasks.filter((task) => {
145
- const name = getTaskDisplayName(task);
146
- return !isFilteredTaskName(name);
147
- });
148
- if (filteredTasks.length === 0)
149
- return null;
150
- // Sort by created_at (chronological order like web)
151
- const sortedTasks = [...filteredTasks].sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
152
- // Calculate depth for each task
153
- const depthMap = calculateTaskDepths(sortedTasks);
154
- // Build display items (collapsing completed tasks when not expanded)
155
- const displayItems = [];
156
- if (expanded) {
157
- // Show all tasks when expanded
158
- sortedTasks.forEach((task) => {
159
- displayItems.push({ type: 'task', task, depth: depthMap.get(task.id) || 0 });
160
- });
161
- }
162
- else {
163
- // Group tasks by parent and collapse completed ones
164
- const tasksByParent = new Map();
165
- sortedTasks.forEach((task) => {
166
- const parentId = task.parent_task?.id || null;
167
- if (!tasksByParent.has(parentId)) {
168
- tasksByParent.set(parentId, []);
169
- }
170
- tasksByParent.get(parentId)?.push(task);
171
- });
172
- // Process root tasks first, then children
173
- const processedIds = new Set();
174
- const processTasksAtLevel = (parentId) => {
175
- const tasksAtLevel = tasksByParent.get(parentId) || [];
176
- // Separate active and completed tasks
177
- const activeTasks = tasksAtLevel.filter((t) => !isCompletedStatus(t.status));
178
- const completedTasks = tasksAtLevel.filter((t) => isCompletedStatus(t.status));
179
- // Always show active tasks
180
- activeTasks.forEach((task) => {
181
- if (!processedIds.has(task.id)) {
182
- processedIds.add(task.id);
183
- displayItems.push({ type: 'task', task, depth: depthMap.get(task.id) || 0 });
184
- // Process children of this task
185
- processTasksAtLevel(task.id);
186
- }
187
- });
188
- // For completed tasks: show first N, then collapse the rest
189
- const visibleCompleted = completedTasks.slice(0, VISIBLE_COMPLETED_COUNT);
190
- const hiddenCompleted = completedTasks.slice(VISIBLE_COMPLETED_COUNT);
191
- // Show visible completed tasks
192
- visibleCompleted.forEach((task) => {
193
- if (!processedIds.has(task.id)) {
194
- processedIds.add(task.id);
195
- displayItems.push({
196
- type: 'task',
197
- task,
198
- depth: depthMap.get(task.id) || 0,
199
- });
200
- // Process children of this task
201
- processTasksAtLevel(task.id);
202
- }
203
- });
204
- // Show collapsed summary for hidden tasks
205
- if (hiddenCompleted.length > 0) {
206
- const depth = hiddenCompleted[0] ? depthMap.get(hiddenCompleted[0].id) || 0 : 1;
207
- displayItems.push({ type: 'collapsed', count: hiddenCompleted.length, depth });
208
- hiddenCompleted.forEach((t) => processedIds.add(t.id));
209
- }
210
- };
211
- processTasksAtLevel(null);
212
- }
213
- // Count total collapsed tasks for the hint
214
- const totalCompletedTasks = sortedTasks.filter((t) => isCompletedStatus(t.status)).length;
215
- const hasCollapsedTasks = totalCompletedTasks > VISIBLE_COMPLETED_COUNT;
216
- return (React.createElement(Box, { flexDirection: "column" },
217
- displayItems.map((item, index) => {
218
- if (item.type === 'collapsed') {
219
- const indent = ' '.repeat(item.depth);
220
- const treeChar = item.depth > 0 ? '└ ' : '';
221
- return (React.createElement(Box, { key: `collapsed-${index}` },
222
- React.createElement(Text, { dimColor: true },
223
- indent,
224
- treeChar,
225
- "\u2026 +",
226
- item.count,
227
- " more",
228
- ' '),
229
- React.createElement(Text, { dimColor: true }, "(ctrl+o to expand)")));
230
- }
231
- const task = item.task;
232
- const name = getTaskDisplayName(task);
233
- const status = task.status;
234
- const statusColor = STATUS_COLORS[status] || STATUS_COLORS.CREATED;
235
- const depth = item.depth;
236
- const duration = formatTaskDuration(task);
237
- // Animate running/started tasks, static icon for others
238
- const icon = status === 'RUNNING' || status === 'STARTED'
239
- ? RUNNING_ANIMATION_FRAMES[animationFrame]
240
- : STATUS_ICONS[status];
241
- // Tree structure: indent based on depth, show └ for children
242
- const indent = ' '.repeat(depth);
243
- const treeChar = depth > 0 ? '└ ' : '';
244
- // Hide duration for root tasks (depth 0) - they run for entire session
245
- const showDuration = depth > 0 && duration;
246
- return (React.createElement(Box, { key: task.id },
247
- React.createElement(Text, { dimColor: true },
248
- indent,
249
- treeChar),
250
- React.createElement(Text, { color: statusColor }, icon),
251
- React.createElement(Text, null,
252
- " ",
253
- name),
254
- showDuration && React.createElement(Text, { dimColor: true },
255
- " (",
256
- duration,
257
- ")")));
258
- }),
259
- expanded && hasCollapsedTasks && (React.createElement(Box, null,
260
- React.createElement(Text, { dimColor: true }, " (ctrl+o to collapse)")))));
261
- }
262
- /**
263
- * Check if any task is active (not completed)
264
- */
265
- export function hasActiveTasks(tasks) {
266
- return tasks.some((t) => isActiveStatus(t.status));
267
- }
268
- //# sourceMappingURL=TaskView.js.map