shine-code-submit 1.0.4 → 1.0.6

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.
@@ -1,5 +1,6 @@
1
- // 「设置」模块:上报地址 + 自动上报间隔(分钟)。
2
- // GET /api/settings 读、PUT /api/settings 写。daemon 侧按间隔定时 POST 报表到上报地址。
1
+ // 「设置」模块:上报 + 自动更新 + 版本显示。
2
+ // GET /api/settings 读、PUT /api/settings 写;GET /api/health 取当前版本。
3
+ // daemon 侧按间隔定时 POST 报表 + 定时检测 npm 新版本自动升级。
3
4
  import { useEffect, useState } from "react";
4
5
  import { useApi } from "../hooks/useApi";
5
6
  import { useApp } from "../state/AppContext";
@@ -7,6 +8,9 @@ import { useApp } from "../state/AppContext";
7
8
  interface Settings {
8
9
  reportUrl?: string | null;
9
10
  reportIntervalMin?: number | null;
11
+ autoUpdate?: boolean | null;
12
+ autoUpdateIntervalMin?: number | null;
13
+ latestVersion?: string | null;
10
14
  }
11
15
 
12
16
  export function SettingsModule() {
@@ -15,30 +19,44 @@ export function SettingsModule() {
15
19
  const base = location.origin;
16
20
  const [url, setUrl] = useState("");
17
21
  const [intervalStr, setIntervalStr] = useState("");
22
+ const [autoUpdate, setAutoUpdate] = useState(true);
23
+ const [updateIntervalStr, setUpdateIntervalStr] = useState("");
24
+ const [currentVersion, setCurrentVersion] = useState("");
25
+ const [latestVersion, setLatestVersion] = useState<string | null>(null);
18
26
  const [loading, setLoading] = useState(true);
19
27
  const [saving, setSaving] = useState(false);
20
28
  const [msg, setMsg] = useState<{ kind: "ok" | "err"; text: string } | null>(null);
21
29
 
22
30
  useEffect(() => {
23
- api<Settings>("/api/settings")
24
- .then((s) => {
31
+ Promise.all([
32
+ api<Settings>("/api/settings"),
33
+ fetch(base + "/api/health").then((r) => r.json() as Promise<{ version?: string }>),
34
+ ])
35
+ .then(([s, h]) => {
25
36
  setUrl(s.reportUrl ?? "");
26
37
  setIntervalStr(s.reportIntervalMin != null ? String(s.reportIntervalMin) : "");
38
+ setAutoUpdate(s.autoUpdate !== false);
39
+ setUpdateIntervalStr(s.autoUpdateIntervalMin != null ? String(s.autoUpdateIntervalMin) : "");
40
+ setLatestVersion(s.latestVersion ?? null);
41
+ setCurrentVersion(h.version ?? "");
27
42
  setLoading(false);
28
43
  })
29
44
  .catch(() => {
30
45
  setMsg({ kind: "err", text: "读取设置失败" });
31
46
  setLoading(false);
32
47
  });
33
- }, [api]);
48
+ }, [api, base]);
34
49
 
35
50
  const save = async () => {
36
51
  setSaving(true);
37
52
  setMsg(null);
38
53
  const iv = parseInt(intervalStr, 10);
54
+ const uiv = parseInt(updateIntervalStr, 10);
39
55
  const body = {
40
56
  reportUrl: url.trim() || null,
41
57
  reportIntervalMin: Number.isFinite(iv) && iv > 0 ? iv : null,
58
+ autoUpdate,
59
+ autoUpdateIntervalMin: Number.isFinite(uiv) && uiv > 0 ? uiv : null,
42
60
  };
43
61
  try {
44
62
  const res = await fetch(base + "/api/settings", {
@@ -50,6 +68,8 @@ export function SettingsModule() {
50
68
  const s = (await res.json()) as Settings;
51
69
  setUrl(s.reportUrl ?? "");
52
70
  setIntervalStr(s.reportIntervalMin != null ? String(s.reportIntervalMin) : "");
71
+ setAutoUpdate(s.autoUpdate !== false);
72
+ setUpdateIntervalStr(s.autoUpdateIntervalMin != null ? String(s.autoUpdateIntervalMin) : "");
53
73
  setMsg({ kind: "ok", text: "已保存" });
54
74
  setTimeout(() => setMsg(null), 2000);
55
75
  } catch {
@@ -100,6 +120,50 @@ export function SettingsModule() {
100
120
  分钟(填了地址且间隔大于 0 才会自动上报)
101
121
  </span>
102
122
  </div>
123
+ <div className="field-hint">
124
+ daemon 每分钟检查一次:地址 + 间隔都配了,就把「报表」数据 POST 到该地址;留空 / 间隔 0 = 不上报。改完无需重启。
125
+ </div>
126
+ </section>
127
+
128
+ <section className="sum-section">
129
+ <div className="sum-head">
130
+ <h3>自动更新</h3>
131
+ </div>
132
+ <div className="field-row">
133
+ <label>版本</label>
134
+ <span className="field-hint" style={{ padding: 0 }}>
135
+ 当前 v{currentVersion || "?"}
136
+ {latestVersion && latestVersion !== currentVersion
137
+ ? `(npm 最新 v${latestVersion})`
138
+ : "(已是最新)"}
139
+ </span>
140
+ </div>
141
+ <div className="field-row">
142
+ <label>自动更新</label>
143
+ <input
144
+ type="checkbox"
145
+ checked={autoUpdate}
146
+ onChange={(e) => setAutoUpdate(e.target.checked)}
147
+ />
148
+ <span className="field-hint" style={{ padding: 0 }}>
149
+ 开启后 daemon 启动时 + 定时检测 npm 新版本,有新版自动后台升级
150
+ </span>
151
+ </div>
152
+ <div className="field-row">
153
+ <label>检测间隔</label>
154
+ <input
155
+ className="field-input"
156
+ type="number"
157
+ min={1}
158
+ placeholder="60"
159
+ value={updateIntervalStr}
160
+ onChange={(e) => setUpdateIntervalStr(e.target.value)}
161
+ style={{ flex: "0 0 120px" }}
162
+ />
163
+ <span className="field-hint" style={{ padding: 0 }}>
164
+ 分钟(daemon 每分钟 tick,按此间隔节流)
165
+ </span>
166
+ </div>
103
167
  <div className="field-row">
104
168
  <label /> {/* 占位对齐 */}
105
169
  <button
@@ -116,7 +180,7 @@ export function SettingsModule() {
116
180
  )}
117
181
  </div>
118
182
  <div className="field-hint">
119
- daemon 每分钟检查一次:地址 + 间隔都配了,就把「报表」数据 POST 到该地址;留空 / 间隔 0 = 不上报。改完无需重启。
183
+ 升级后 daemon 自动重启到新版(版本感知);plugin 需重启 Claude Code 生效。也可命令行手动 <code>shine-code-submit update</code>。
120
184
  </div>
121
185
  </section>
122
186
  </>