@gowelle/stint-agent 1.1.0 → 1.2.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.
- package/README.md +44 -34
- package/dist/StatusDashboard-7ZIGEOQ4.js +232 -0
- package/dist/api-HLTR2LTF.js +7 -0
- package/dist/{chunk-OHOFKJL7.js → chunk-FBQA4K5J.js} +95 -207
- package/dist/chunk-IJUJ6NEL.js +369 -0
- package/dist/chunk-RHMTZK2J.js +297 -0
- package/dist/{chunk-IAERVP6F.js → chunk-W4JGOGR7.js} +42 -291
- package/dist/daemon/runner.js +8 -236
- package/dist/index.js +577 -70
- package/package.json +23 -1
- package/dist/api-YI2HWZGL.js +0 -6
package/README.md
CHANGED
|
@@ -15,7 +15,13 @@ The official CLI agent for [Stint](https://stint.codes) — a lightweight daemon
|
|
|
15
15
|
- 📦 Automatic commit execution
|
|
16
16
|
- 🔍 Repository status syncing
|
|
17
17
|
- 🖥️ Background daemon process
|
|
18
|
-
- 📝 Comprehensive logging
|
|
18
|
+
- 📝 Comprehensive logging and filtering
|
|
19
|
+
- 📊 Interactive status dashboard
|
|
20
|
+
- 🚀 Multiple release channels (stable/beta/nightly)
|
|
21
|
+
- 🔍 Built-in environment diagnostics
|
|
22
|
+
- 📈 Resource usage monitoring
|
|
23
|
+
|
|
24
|
+
For detailed feature documentation, see the **[Features Guide](docs/features.md)**.
|
|
19
25
|
|
|
20
26
|
## Installation
|
|
21
27
|
|
|
@@ -49,47 +55,47 @@ stint daemon status
|
|
|
49
55
|
|
|
50
56
|
### General
|
|
51
57
|
|
|
52
|
-
| Command
|
|
53
|
-
|
|
54
|
-
| `stint --version`, `stint -V` | Show current agent version
|
|
55
|
-
| `stint --help`, `stint -h`
|
|
56
|
-
| `stint update`
|
|
58
|
+
| Command | Description |
|
|
59
|
+
| ----------------------------- | ---------------------------------- |
|
|
60
|
+
| `stint --version`, `stint -V` | Show current agent version |
|
|
61
|
+
| `stint --help`, `stint -h` | Show help information |
|
|
62
|
+
| `stint update` | Update agent to the latest version |
|
|
57
63
|
|
|
58
64
|
### Authentication
|
|
59
65
|
|
|
60
|
-
| Command
|
|
61
|
-
|
|
62
|
-
| `stint login`
|
|
63
|
-
| `stint logout` | Remove stored credentials
|
|
64
|
-
| `stint whoami` | Show current user and machine information
|
|
66
|
+
| Command | Description |
|
|
67
|
+
| -------------- | ------------------------------------------------- |
|
|
68
|
+
| `stint login` | Authenticate with Stint (opens browser for OAuth) |
|
|
69
|
+
| `stint logout` | Remove stored credentials |
|
|
70
|
+
| `stint whoami` | Show current user and machine information |
|
|
65
71
|
|
|
66
72
|
### Daemon Lifecycle
|
|
67
73
|
|
|
68
|
-
| Command
|
|
69
|
-
|
|
70
|
-
| `stint install`
|
|
71
|
-
| `stint uninstall`
|
|
72
|
-
| `stint daemon start`
|
|
73
|
-
| `stint daemon stop`
|
|
74
|
-
| `stint daemon status`
|
|
75
|
-
| `stint daemon logs [--lines N]` | View daemon logs (default: 50 lines)
|
|
76
|
-
| `stint daemon restart`
|
|
74
|
+
| Command | Description |
|
|
75
|
+
| ------------------------------- | --------------------------------------------------------- |
|
|
76
|
+
| `stint install` | Register daemon to run on system startup (Login required) |
|
|
77
|
+
| `stint uninstall` | Remove daemon from system startup |
|
|
78
|
+
| `stint daemon start` | Start background daemon manually |
|
|
79
|
+
| `stint daemon stop` | Stop daemon gracefully |
|
|
80
|
+
| `stint daemon status` | Check if daemon is running |
|
|
81
|
+
| `stint daemon logs [--lines N]` | View daemon logs (default: 50 lines) |
|
|
82
|
+
| `stint daemon restart` | Restart the daemon |
|
|
77
83
|
|
|
78
84
|
### Project Management
|
|
79
85
|
|
|
80
|
-
| Command
|
|
81
|
-
|
|
82
|
-
| `stint link`
|
|
83
|
-
| `stint unlink [--force]`
|
|
84
|
-
| `stint status` | Show
|
|
85
|
-
| `stint sync`
|
|
86
|
+
| Command | Description |
|
|
87
|
+
| ---------------------------- | --------------------------------------------------------------- |
|
|
88
|
+
| `stint link` | Link current directory to a Stint project (or create a new one) |
|
|
89
|
+
| `stint unlink [--force]` | Remove project link |
|
|
90
|
+
| `stint status [--dashboard]` | Show status (use `-d` for interactive dashboard) |
|
|
91
|
+
| `stint sync` | Manually sync repository information to server |
|
|
86
92
|
|
|
87
93
|
### Commit Operations
|
|
88
94
|
|
|
89
|
-
| Command
|
|
90
|
-
|
|
91
|
-
| `stint commits`
|
|
92
|
-
| `stint commit <id>` | Execute a specific pending commit
|
|
95
|
+
| Command | Description |
|
|
96
|
+
| ------------------- | ---------------------------------------- |
|
|
97
|
+
| `stint commits` | List pending commits for this repository |
|
|
98
|
+
| `stint commit <id>` | Execute a specific pending commit |
|
|
93
99
|
|
|
94
100
|
## Complete Workflow
|
|
95
101
|
|
|
@@ -118,11 +124,13 @@ For comprehensive troubleshooting help, see the **[Troubleshooting Guide](docs/T
|
|
|
118
124
|
### Quick Tips
|
|
119
125
|
|
|
120
126
|
**"Not authenticated" error**
|
|
127
|
+
|
|
121
128
|
```bash
|
|
122
129
|
stint login
|
|
123
130
|
```
|
|
124
131
|
|
|
125
132
|
**Daemon won't start**
|
|
133
|
+
|
|
126
134
|
```bash
|
|
127
135
|
stint daemon status # Check if already running
|
|
128
136
|
stint daemon logs # Check logs for errors
|
|
@@ -130,6 +138,7 @@ stint daemon restart # Restart daemon
|
|
|
130
138
|
```
|
|
131
139
|
|
|
132
140
|
**For detailed solutions**, including:
|
|
141
|
+
|
|
133
142
|
- Connection issues (WebSocket, API, Circuit Breaker)
|
|
134
143
|
- Daemon problems (crashes, autostart)
|
|
135
144
|
- Authentication errors
|
|
@@ -142,13 +151,14 @@ See the **[Troubleshooting Guide](docs/TROUBLESHOOTING.md)**.
|
|
|
142
151
|
|
|
143
152
|
Logs are stored in your system's config directory:
|
|
144
153
|
|
|
145
|
-
| Platform
|
|
146
|
-
|
|
147
|
-
| **macOS**
|
|
148
|
-
| **Linux**
|
|
154
|
+
| Platform | Log Location |
|
|
155
|
+
| ----------- | ----------------------------------- |
|
|
156
|
+
| **macOS** | `~/.config/stint/logs/` |
|
|
157
|
+
| **Linux** | `~/.config/stint/logs/` |
|
|
149
158
|
| **Windows** | `%USERPROFILE%\.config\stint\logs\` |
|
|
150
159
|
|
|
151
160
|
Log files:
|
|
161
|
+
|
|
152
162
|
- `agent.log` - General CLI operations
|
|
153
163
|
- `daemon.log` - Daemon process logs
|
|
154
164
|
- `error.log` - Error details
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import {
|
|
2
|
+
gitService,
|
|
3
|
+
projectService,
|
|
4
|
+
validatePidFile
|
|
5
|
+
} from "./chunk-FBQA4K5J.js";
|
|
6
|
+
import {
|
|
7
|
+
authService
|
|
8
|
+
} from "./chunk-RHMTZK2J.js";
|
|
9
|
+
|
|
10
|
+
// src/components/StatusDashboard.tsx
|
|
11
|
+
import { useState, useEffect } from "react";
|
|
12
|
+
import { Box as Box3, Text as Text3, useApp, useInput } from "ink";
|
|
13
|
+
|
|
14
|
+
// src/components/Panel.tsx
|
|
15
|
+
import { Box, Text } from "ink";
|
|
16
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
17
|
+
function Panel({ title, icon, children }) {
|
|
18
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
19
|
+
/* @__PURE__ */ jsxs(Text, { color: "blue", children: [
|
|
20
|
+
icon ? `${icon} ` : "",
|
|
21
|
+
title,
|
|
22
|
+
":"
|
|
23
|
+
] }),
|
|
24
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2500".repeat(50) }),
|
|
25
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingLeft: 0, children })
|
|
26
|
+
] });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// src/components/StatusRow.tsx
|
|
30
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
31
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
32
|
+
function StatusRow({ label, value, labelWidth = 12 }) {
|
|
33
|
+
return /* @__PURE__ */ jsxs2(Box2, { children: [
|
|
34
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, children: label.padEnd(labelWidth) }),
|
|
35
|
+
typeof value === "string" ? /* @__PURE__ */ jsx2(Text2, { children: value }) : value
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/components/StatusDashboard.tsx
|
|
40
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
41
|
+
function StatusDashboard({ cwd }) {
|
|
42
|
+
const { exit } = useApp();
|
|
43
|
+
const [state, setState] = useState({
|
|
44
|
+
linkedProject: null,
|
|
45
|
+
repoInfo: null,
|
|
46
|
+
user: null,
|
|
47
|
+
daemonRunning: false,
|
|
48
|
+
daemonPid: null,
|
|
49
|
+
isRepo: false,
|
|
50
|
+
loading: true,
|
|
51
|
+
lastRefresh: /* @__PURE__ */ new Date(),
|
|
52
|
+
error: null
|
|
53
|
+
});
|
|
54
|
+
const [showHelp, setShowHelp] = useState(false);
|
|
55
|
+
const refreshStatus = async () => {
|
|
56
|
+
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
57
|
+
try {
|
|
58
|
+
const [linkedProject2, user2, isRepo2] = await Promise.all([
|
|
59
|
+
projectService.getLinkedProject(cwd),
|
|
60
|
+
authService.validateToken(),
|
|
61
|
+
gitService.isRepo(cwd)
|
|
62
|
+
]);
|
|
63
|
+
let repoInfo2 = null;
|
|
64
|
+
if (isRepo2) {
|
|
65
|
+
try {
|
|
66
|
+
repoInfo2 = await gitService.getRepoInfo(cwd);
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const { valid, pid } = validatePidFile();
|
|
71
|
+
setState({
|
|
72
|
+
linkedProject: linkedProject2,
|
|
73
|
+
repoInfo: repoInfo2,
|
|
74
|
+
user: user2,
|
|
75
|
+
daemonRunning: valid,
|
|
76
|
+
daemonPid: pid,
|
|
77
|
+
isRepo: isRepo2,
|
|
78
|
+
loading: false,
|
|
79
|
+
lastRefresh: /* @__PURE__ */ new Date(),
|
|
80
|
+
error: null
|
|
81
|
+
});
|
|
82
|
+
} catch (error2) {
|
|
83
|
+
setState((prev) => ({
|
|
84
|
+
...prev,
|
|
85
|
+
loading: false,
|
|
86
|
+
error: error2.message
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
refreshStatus();
|
|
92
|
+
const interval = setInterval(refreshStatus, 5e3);
|
|
93
|
+
return () => clearInterval(interval);
|
|
94
|
+
}, [cwd]);
|
|
95
|
+
useInput((input, key) => {
|
|
96
|
+
if (input === "q" || key.escape) {
|
|
97
|
+
exit();
|
|
98
|
+
} else if (input === "r") {
|
|
99
|
+
refreshStatus();
|
|
100
|
+
} else if (input === "?") {
|
|
101
|
+
setShowHelp((prev) => !prev);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const { linkedProject, repoInfo, user, daemonRunning, daemonPid, isRepo, loading, lastRefresh, error } = state;
|
|
105
|
+
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", padding: 1, children: [
|
|
106
|
+
/* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E" }) }),
|
|
107
|
+
/* @__PURE__ */ jsxs3(Box3, { marginBottom: 1, children: [
|
|
108
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "\u2502" }),
|
|
109
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, children: " \u{1F4CA} Stint Status Dashboard " }),
|
|
110
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "\u2502" })
|
|
111
|
+
] }),
|
|
112
|
+
/* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F" }) }),
|
|
113
|
+
error && /* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsxs3(Text3, { color: "red", children: [
|
|
114
|
+
"\u26A0 Error: ",
|
|
115
|
+
error
|
|
116
|
+
] }) }),
|
|
117
|
+
loading && /* @__PURE__ */ jsx3(Box3, { marginBottom: 1, children: /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "\u27F3 Refreshing..." }) }),
|
|
118
|
+
/* @__PURE__ */ jsx3(Panel, { title: "Project Status", icon: "\u{1F4E6}", children: linkedProject ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
119
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Status:", value: /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2713 Linked" }) }),
|
|
120
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Project ID:", value: linkedProject.projectId }),
|
|
121
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Linked At:", value: new Date(linkedProject.linkedAt).toLocaleString() })
|
|
122
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
123
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Status:", value: /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "Not linked" }) }),
|
|
124
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", children: 'Run "stint link" to link this directory to a project.' })
|
|
125
|
+
] }) }),
|
|
126
|
+
/* @__PURE__ */ jsx3(Panel, { title: "Git Repository", icon: "\u{1F4C2}", children: isRepo && repoInfo ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
127
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Branch:", value: /* @__PURE__ */ jsx3(Text3, { color: "cyan", children: repoInfo.currentBranch }) }),
|
|
128
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Remote:", value: repoInfo.remoteUrl || /* @__PURE__ */ jsx3(Text3, { color: "gray", children: "None" }) }),
|
|
129
|
+
/* @__PURE__ */ jsx3(
|
|
130
|
+
StatusRow,
|
|
131
|
+
{
|
|
132
|
+
label: "Last Commit:",
|
|
133
|
+
value: `${repoInfo.lastCommitSha.substring(0, 7)} - ${repoInfo.lastCommitMessage.substring(0, 40)}${repoInfo.lastCommitMessage.length > 40 ? "..." : ""}`
|
|
134
|
+
}
|
|
135
|
+
),
|
|
136
|
+
renderGitChanges(repoInfo)
|
|
137
|
+
] }) : /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "Not a git repository" }) }),
|
|
138
|
+
/* @__PURE__ */ jsx3(Panel, { title: "Authentication", icon: "\u{1F510}", children: user ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
139
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Status:", value: /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2713 Authenticated" }) }),
|
|
140
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "User:", value: `${user.name} (${user.email})` }),
|
|
141
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Machine:", value: authService.getMachineName() })
|
|
142
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
143
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Status:", value: /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "Not logged in" }) }),
|
|
144
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", children: 'Run "stint login" to authenticate.' })
|
|
145
|
+
] }) }),
|
|
146
|
+
/* @__PURE__ */ jsx3(Panel, { title: "Daemon", icon: "\u2699\uFE0F", children: daemonRunning ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
147
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Status:", value: /* @__PURE__ */ jsx3(Text3, { color: "green", children: "\u2713 Running" }) }),
|
|
148
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "PID:", value: String(daemonPid) })
|
|
149
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
150
|
+
/* @__PURE__ */ jsx3(StatusRow, { label: "Status:", value: /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "Not running" }) }),
|
|
151
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", children: 'Run "stint daemon start" to start the background agent.' })
|
|
152
|
+
] }) }),
|
|
153
|
+
/* @__PURE__ */ jsxs3(Box3, { marginTop: 1, flexDirection: "column", children: [
|
|
154
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", children: "\u2500".repeat(50) }),
|
|
155
|
+
/* @__PURE__ */ jsxs3(Box3, { children: [
|
|
156
|
+
/* @__PURE__ */ jsxs3(Text3, { color: "gray", children: [
|
|
157
|
+
"Last refresh: ",
|
|
158
|
+
lastRefresh.toLocaleTimeString()
|
|
159
|
+
] }),
|
|
160
|
+
/* @__PURE__ */ jsx3(Text3, { color: "gray", children: " \u2502 Auto-refresh: 5s" })
|
|
161
|
+
] }),
|
|
162
|
+
/* @__PURE__ */ jsxs3(Box3, { marginTop: 1, children: [
|
|
163
|
+
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "[q]" }),
|
|
164
|
+
/* @__PURE__ */ jsx3(Text3, { children: " Quit " }),
|
|
165
|
+
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "[r]" }),
|
|
166
|
+
/* @__PURE__ */ jsx3(Text3, { children: " Refresh " }),
|
|
167
|
+
/* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "[?]" }),
|
|
168
|
+
/* @__PURE__ */ jsx3(Text3, { children: " Help" })
|
|
169
|
+
] })
|
|
170
|
+
] }),
|
|
171
|
+
showHelp && /* @__PURE__ */ jsxs3(
|
|
172
|
+
Box3,
|
|
173
|
+
{
|
|
174
|
+
flexDirection: "column",
|
|
175
|
+
marginTop: 1,
|
|
176
|
+
borderStyle: "round",
|
|
177
|
+
borderColor: "cyan",
|
|
178
|
+
padding: 1,
|
|
179
|
+
children: [
|
|
180
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "Keyboard Shortcuts" }),
|
|
181
|
+
/* @__PURE__ */ jsx3(Text3, { children: " q, Esc - Exit dashboard" }),
|
|
182
|
+
/* @__PURE__ */ jsx3(Text3, { children: " r - Refresh status immediately" }),
|
|
183
|
+
/* @__PURE__ */ jsx3(Text3, { children: " ? - Toggle this help" })
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
] });
|
|
188
|
+
}
|
|
189
|
+
function renderGitChanges(repoInfo) {
|
|
190
|
+
const { staged, unstaged, untracked, ahead, behind } = repoInfo.status;
|
|
191
|
+
const totalChanges = staged.length + unstaged.length + untracked.length;
|
|
192
|
+
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
|
|
193
|
+
totalChanges > 0 ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
194
|
+
/* @__PURE__ */ jsx3(
|
|
195
|
+
StatusRow,
|
|
196
|
+
{
|
|
197
|
+
label: "Changes:",
|
|
198
|
+
value: /* @__PURE__ */ jsxs3(Text3, { color: "yellow", children: [
|
|
199
|
+
totalChanges,
|
|
200
|
+
" file(s)"
|
|
201
|
+
] })
|
|
202
|
+
}
|
|
203
|
+
),
|
|
204
|
+
staged.length > 0 && /* @__PURE__ */ jsx3(Box3, { paddingLeft: 2, children: /* @__PURE__ */ jsxs3(Text3, { color: "green", children: [
|
|
205
|
+
"Staged: ",
|
|
206
|
+
staged.length
|
|
207
|
+
] }) }),
|
|
208
|
+
unstaged.length > 0 && /* @__PURE__ */ jsx3(Box3, { paddingLeft: 2, children: /* @__PURE__ */ jsxs3(Text3, { color: "yellow", children: [
|
|
209
|
+
"Unstaged: ",
|
|
210
|
+
unstaged.length
|
|
211
|
+
] }) }),
|
|
212
|
+
untracked.length > 0 && /* @__PURE__ */ jsx3(Box3, { paddingLeft: 2, children: /* @__PURE__ */ jsxs3(Text3, { color: "gray", children: [
|
|
213
|
+
"Untracked: ",
|
|
214
|
+
untracked.length
|
|
215
|
+
] }) })
|
|
216
|
+
] }) : /* @__PURE__ */ jsx3(StatusRow, { label: "Changes:", value: /* @__PURE__ */ jsx3(Text3, { color: "green", children: "Clean working tree" }) }),
|
|
217
|
+
(ahead > 0 || behind > 0) && /* @__PURE__ */ jsx3(
|
|
218
|
+
StatusRow,
|
|
219
|
+
{
|
|
220
|
+
label: "Sync:",
|
|
221
|
+
value: /* @__PURE__ */ jsxs3(Text3, { color: "yellow", children: [
|
|
222
|
+
ahead > 0 ? `\u2191${ahead}` : "",
|
|
223
|
+
" ",
|
|
224
|
+
behind > 0 ? `\u2193${behind}` : ""
|
|
225
|
+
] })
|
|
226
|
+
}
|
|
227
|
+
)
|
|
228
|
+
] });
|
|
229
|
+
}
|
|
230
|
+
export {
|
|
231
|
+
StatusDashboard
|
|
232
|
+
};
|