@goodandready/dsh-opencode-provider 0.5.20 → 0.5.21
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/CHANGELOG.md +5 -0
- package/README.md +3 -3
- package/README.ru.md +3 -3
- package/README.zh.md +3 -3
- package/lib/client.js +6 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +26 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.21
|
|
4
|
+
|
|
5
|
+
- **Analytics completeness**: projection scans above 5000 files now select the newest files by metadata instead of an arbitrary readdir page; file-limit and unreadable-projection cases set `AnalyticsReport.partial`, surfaced in the dashboard.
|
|
6
|
+
- 113 tests.
|
|
7
|
+
|
|
3
8
|
## 0.5.20
|
|
4
9
|
|
|
5
10
|
- **CI/reproducibility**: regenerated `package-lock.json` with the normal npm resolver; clean `npm ci --ignore-scripts` now succeeds and `npm run check` passes.
|
package/README.md
CHANGED
|
@@ -130,12 +130,12 @@ npm pack
|
|
|
130
130
|
Install the **packed tarball** into a profile:
|
|
131
131
|
|
|
132
132
|
```bash
|
|
133
|
-
dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.
|
|
133
|
+
dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.21.tgz
|
|
134
134
|
# DSH Desktop:
|
|
135
|
-
dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.
|
|
135
|
+
dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.21.tgz
|
|
136
136
|
|
|
137
137
|
# Or install the published package:
|
|
138
|
-
dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.
|
|
138
|
+
dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.21
|
|
139
139
|
```
|
|
140
140
|
|
|
141
141
|
Restart dsh (or DSH Desktop), then pick **OpenCode (plugin)** or **OpenCode Go (plugin)** in the model picker.
|
package/README.ru.md
CHANGED
|
@@ -129,12 +129,12 @@ npm pack
|
|
|
129
129
|
Установка из **упакованного tarball**:
|
|
130
130
|
|
|
131
131
|
```bash
|
|
132
|
-
dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.
|
|
132
|
+
dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.21.tgz
|
|
133
133
|
# DSH Desktop:
|
|
134
|
-
dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.
|
|
134
|
+
dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.21.tgz
|
|
135
135
|
|
|
136
136
|
# Либо установка опубликованного пакета из npm:
|
|
137
|
-
dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.
|
|
137
|
+
dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.21
|
|
138
138
|
```
|
|
139
139
|
|
|
140
140
|
После установки перезапустите dsh (или DSH Desktop) и выберите **OpenCode (plugin)** или **OpenCode Go (plugin)** в списке моделей.
|
package/README.zh.md
CHANGED
|
@@ -124,12 +124,12 @@ npm pack
|
|
|
124
124
|
通过**打包文件 (.tgz)**安装:
|
|
125
125
|
|
|
126
126
|
```bash
|
|
127
|
-
dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.
|
|
127
|
+
dsh plugin --profile web add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.21.tgz
|
|
128
128
|
# DSH 桌面端:
|
|
129
|
-
dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.
|
|
129
|
+
dsh plugin --profile desktop add /absolute/path/to/goodandready-dsh-opencode-provider-0.5.21.tgz
|
|
130
130
|
|
|
131
131
|
# 或从 npm 安装已发布版本:
|
|
132
|
-
dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.
|
|
132
|
+
dsh plugin --profile web add @goodandready/dsh-opencode-provider@0.5.21
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
安装完成后重启 dsh 或 DSH 桌面端,在模型选择器中选择 **OpenCode (plugin)** 或 **OpenCode Go (plugin)** 即可。
|
package/lib/client.js
CHANGED
|
@@ -138,6 +138,7 @@ window.__ModuleLoader__.load({
|
|
|
138
138
|
heatmapByAccount: "Account",
|
|
139
139
|
heatmapAllAccounts: "All accounts",
|
|
140
140
|
analyticsHint: "Aggregated from local session metadata by last activity. A session that switched models is counted under its last model; failures are not exposed by the projection. Only plugin routes are counted; legacy opencode sessions belong to the built-in catalog.",
|
|
141
|
+
analyticsPartial: "This report is partial: the projection scan hit its file limit or skipped unreadable files.",
|
|
141
142
|
analyticsEmpty: "No plugin sessions in this window. Legacy opencode sessions belong to the built-in catalog.",
|
|
142
143
|
showAll: "Show all",
|
|
143
144
|
modelSearch: "Search models…",
|
|
@@ -343,6 +344,7 @@ window.__ModuleLoader__.load({
|
|
|
343
344
|
heatmapByAccount: "账户",
|
|
344
345
|
heatmapAllAccounts: "全部账户",
|
|
345
346
|
analyticsHint: "按最后活动时间聚合本地会话元数据。切换过模型的会话计入最后使用的模型;本地投影不暴露失败。仅统计插件路由;旧 opencode 会话属于内置目录。",
|
|
347
|
+
analyticsPartial: "此报告不完整:投影扫描达到文件上限或跳过了不可读文件。",
|
|
346
348
|
analyticsEmpty: "此窗口内没有插件会话。旧 opencode 会话属于内置目录。",
|
|
347
349
|
showAll: "显示全部",
|
|
348
350
|
modelSearch: "搜索模型…",
|
|
@@ -923,6 +925,10 @@ window.__ModuleLoader__.load({
|
|
|
923
925
|
})
|
|
924
926
|
]
|
|
925
927
|
}),
|
|
928
|
+
analytics.partial === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
929
|
+
className: "oc-hint",
|
|
930
|
+
children: t("analyticsPartial")
|
|
931
|
+
}) : null,
|
|
926
932
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
927
933
|
className: "oc-hint",
|
|
928
934
|
children: t("analyticsHint")
|
package/lib/index.d.ts
CHANGED
|
@@ -352,6 +352,8 @@ interface AnalyticsReport {
|
|
|
352
352
|
summary: AnalyticsSummary;
|
|
353
353
|
days: DayUsageRow[];
|
|
354
354
|
sessions: SessionUsageRow[];
|
|
355
|
+
/** True when the projection scan hit a cap or skipped unreadable files. */
|
|
356
|
+
partial?: boolean;
|
|
355
357
|
}
|
|
356
358
|
interface RouteDeps {
|
|
357
359
|
readonly config: () => ResolvedConfig;
|
package/lib/index.js
CHANGED
|
@@ -18,7 +18,7 @@ const DEFAULT_GO_API_BASE = "https://opencode.ai/inference/go";
|
|
|
18
18
|
const DEFAULT_GO_ZEN_BASE = "https://opencode.ai/zen/go/v1";
|
|
19
19
|
const DEFAULT_USAGE_URL = "https://opencode.ai/zen/go/v1/usage";
|
|
20
20
|
const DEFAULT_AUTH_ENTRY = "opencode-go";
|
|
21
|
-
const DEFAULT_USER_AGENT = "dsh-opencode-provider/0.5.
|
|
21
|
+
const DEFAULT_USER_AGENT = "dsh-opencode-provider/0.5.21";
|
|
22
22
|
const DEFAULT_CONTEXT_WINDOW = 262144;
|
|
23
23
|
const DEFAULT_MAX_TOKENS = 32768;
|
|
24
24
|
const DEFAULT_GENERATE_MAX_TOKENS = 32768;
|
|
@@ -4502,8 +4502,25 @@ async function readModelAnalytics(days = 30) {
|
|
|
4502
4502
|
if (cached !== void 0 && Date.now() - cached.at < CACHE_TTL_MS) return cached.report;
|
|
4503
4503
|
const dir = projectionDirectory();
|
|
4504
4504
|
const sessions = [];
|
|
4505
|
+
let partial = false;
|
|
4505
4506
|
try {
|
|
4506
|
-
|
|
4507
|
+
let files = (await readdir(dir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".json"));
|
|
4508
|
+
if (files.length > MAX_FILES) {
|
|
4509
|
+
files = (await Promise.all(files.map(async (entry) => {
|
|
4510
|
+
try {
|
|
4511
|
+
return {
|
|
4512
|
+
entry,
|
|
4513
|
+
at: (await stat(join(dir, entry.name))).mtimeMs
|
|
4514
|
+
};
|
|
4515
|
+
} catch {
|
|
4516
|
+
return {
|
|
4517
|
+
entry,
|
|
4518
|
+
at: 0
|
|
4519
|
+
};
|
|
4520
|
+
}
|
|
4521
|
+
}))).sort((left, right) => right.at - left.at).slice(0, MAX_FILES).map((item) => item.entry);
|
|
4522
|
+
partial = true;
|
|
4523
|
+
}
|
|
4507
4524
|
let cursor = 0;
|
|
4508
4525
|
const workers = Array.from({ length: Math.min(16, files.length) }, async () => {
|
|
4509
4526
|
while (true) {
|
|
@@ -4517,12 +4534,17 @@ async function readModelAnalytics(days = 30) {
|
|
|
4517
4534
|
meta.id = entry.name.replace(/\.json$/i, "");
|
|
4518
4535
|
sessions.push(meta);
|
|
4519
4536
|
}
|
|
4520
|
-
} catch {
|
|
4537
|
+
} catch {
|
|
4538
|
+
partial = true;
|
|
4539
|
+
}
|
|
4521
4540
|
}
|
|
4522
4541
|
});
|
|
4523
4542
|
await Promise.all(workers);
|
|
4524
|
-
} catch {
|
|
4543
|
+
} catch {
|
|
4544
|
+
partial = true;
|
|
4545
|
+
}
|
|
4525
4546
|
const report = aggregateSessions(sessions, clamped);
|
|
4547
|
+
report.partial = partial;
|
|
4526
4548
|
cache.set(clamped, {
|
|
4527
4549
|
at: Date.now(),
|
|
4528
4550
|
report
|