dsh-composer-plus 1.1.1 → 1.2.1
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 +55 -18
- package/assets/features/allowForChat.webp +0 -0
- package/assets/features/autoUpdate.webp +0 -0
- package/assets/features/changesPanel.webp +0 -0
- package/assets/features/continueButton.webp +0 -0
- package/assets/features/copyDeeplink.webp +0 -0
- package/assets/features/inputHistory.webp +0 -0
- package/assets/features/language.webp +0 -0
- package/assets/features/notifications.webp +0 -0
- package/assets/features/planToggle.webp +0 -0
- package/assets/features/projectStatus.webp +0 -0
- package/assets/features/queueReorder.webp +0 -0
- package/assets/icon.svg +13 -0
- package/client.js +232 -8
- package/index.js +53 -0
- package/locale/de.json +6 -0
- package/locale/en.json +6 -0
- package/locale/es.json +6 -0
- package/locale/fr.json +6 -0
- package/locale/hi.json +6 -0
- package/locale/id.json +6 -0
- package/locale/ja.json +6 -0
- package/locale/ko.json +6 -0
- package/locale/pt-BR.json +6 -0
- package/locale/ru.json +6 -0
- package/locale/tr.json +6 -0
- package/locale/vi.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +27 -5
package/index.js
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
* - Message-free Continue: authenticated resume through public agent lifecycle hooks.
|
|
4
4
|
* - Changes panel: read-only git status/diff for a session's working directory, served on the authenticated `/api` channel.
|
|
5
5
|
* - Persistent Auto Review grants: per-session tool names saved under the dsh home, so "Allow for this chat" survives a restart.
|
|
6
|
+
* - Update check: the latest GitHub release, offered only once npm serves that exact version (the client installs it
|
|
7
|
+
* through dsh's own plugin manager).
|
|
6
8
|
*/
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
7
10
|
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
8
11
|
import { randomUUID } from 'node:crypto';
|
|
9
12
|
import { homedir } from 'node:os';
|
|
@@ -16,6 +19,14 @@ export const CHANGES_PATH = '/api/composer-plus.changes';
|
|
|
16
19
|
export const DIFF_PATH = '/api/composer-plus.diff';
|
|
17
20
|
export const GRANTS_PATH = '/api/composer-plus.grants';
|
|
18
21
|
export const CONTINUE_PATH = '/api/composer-plus.continue';
|
|
22
|
+
export const UPDATE_PATH = '/api/composer-plus.update';
|
|
23
|
+
export const SHOT_PATH = '/api/composer-plus.shot';
|
|
24
|
+
/** Feature screenshots shipped in assets/features/<id>.webp; only these ids are served (no path input). */
|
|
25
|
+
export const SHOTS = ['changesPanel', 'projectStatus', 'notifications', 'allowForChat', 'continueButton', 'inputHistory', 'planToggle',
|
|
26
|
+
'queueReorder', 'copyDeeplink', 'language', 'autoUpdate'];
|
|
27
|
+
const PACKAGE = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'));
|
|
28
|
+
const NPM_NAME = 'dsh-composer-plus';
|
|
29
|
+
const RELEASES_URL = 'https://api.github.com/repos/furkancak1r/dsh-composer-plus/releases/latest';
|
|
19
30
|
const CONTINUE_SOURCE = 'composer-plus-continue';
|
|
20
31
|
const CONTINUE_TEXT = 'The previous turn stopped before it finished (it was interrupted or failed). Continue the task from where it stopped. Do not repeat completed work.';
|
|
21
32
|
const continueMessage = () => Object.freeze({ id: randomUUID(), role: 'user', content: Object.freeze([Object.freeze({ type: 'text', text: CONTINUE_TEXT })]),
|
|
@@ -158,6 +169,31 @@ export function grantsStore(file) {
|
|
|
158
169
|
};
|
|
159
170
|
}
|
|
160
171
|
|
|
172
|
+
/** `1.2.3` / `v1.2.3` -> [1, 2, 3]; anything else (pre-releases, ranges) is not an update target. */
|
|
173
|
+
export const parseVersion = (text) => {
|
|
174
|
+
const m = /^v?(\d{1,6})\.(\d{1,6})\.(\d{1,6})$/.exec(String(text ?? '').trim());
|
|
175
|
+
return m === null ? undefined : m.slice(1).map(Number);
|
|
176
|
+
};
|
|
177
|
+
export const newer = (a, b) => { for (let i = 0; i < 3; i++) if (a[i] !== b[i]) return a[i] > b[i]; return false; };
|
|
178
|
+
/** Latest GitHub release vs this copy. `managed` is false for a renamed or linked local copy, which pnpm can't upgrade. */
|
|
179
|
+
export async function checkUpdate(fetchImpl = fetch, pkg = PACKAGE, signal) {
|
|
180
|
+
const current = parseVersion(pkg.version);
|
|
181
|
+
const managed = pkg.name === NPM_NAME && current !== undefined;
|
|
182
|
+
const timeout = AbortSignal.timeout(10000);
|
|
183
|
+
const opts = { signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]) };
|
|
184
|
+
const response = await fetchImpl(RELEASES_URL, { ...opts, headers: { accept: 'application/vnd.github+json', 'user-agent': NPM_NAME } });
|
|
185
|
+
if (!response.ok) throw new Error(`GitHub answered ${response.status}`);
|
|
186
|
+
const release = await response.json();
|
|
187
|
+
const latest = parseVersion(release?.tag_name);
|
|
188
|
+
if (latest === undefined) throw new Error('latest release has no x.y.z tag');
|
|
189
|
+
const info = { name: NPM_NAME, current: pkg.version, latest: latest.join('.'), managed, newer: false,
|
|
190
|
+
url: typeof release.html_url === 'string' && release.html_url.startsWith('https://github.com/') ? release.html_url : undefined };
|
|
191
|
+
if (current === undefined || !newer(latest, current)) return info;
|
|
192
|
+
// A release can go out before `npm publish`; offer only what pnpm can install.
|
|
193
|
+
const npm = await fetchImpl(`https://registry.npmjs.org/${NPM_NAME}/${info.latest}`, opts);
|
|
194
|
+
return { ...info, newer: npm.ok };
|
|
195
|
+
}
|
|
196
|
+
|
|
161
197
|
const json = (value, status = 200) => Response.json(value, { status, headers: { 'cache-control': 'no-store' } });
|
|
162
198
|
const isText = (v, max = 512) => typeof v === 'string' && v.length > 0 && v.length <= max;
|
|
163
199
|
|
|
@@ -239,6 +275,23 @@ export function apply(ctx) {
|
|
|
239
275
|
} catch (error) { return json({ error: String(error?.message ?? error) }, 500); }
|
|
240
276
|
},
|
|
241
277
|
});
|
|
278
|
+
ctx.connection.fetch.register({
|
|
279
|
+
path: SHOT_PATH, methods: ['GET'], requestBody: 'buffered',
|
|
280
|
+
fetch: async (request) => {
|
|
281
|
+
const id = new URL(request.url).searchParams.get('id');
|
|
282
|
+
if (!SHOTS.includes(id)) return json({ error: 'not found' }, 404);
|
|
283
|
+
try {
|
|
284
|
+
const bytes = await readFile(new URL(`./assets/features/${id}.webp`, import.meta.url));
|
|
285
|
+
return new Response(bytes, { headers: { 'content-type': 'image/webp', 'cache-control': 'private, max-age=86400' } });
|
|
286
|
+
} catch { return json({ error: 'not found' }, 404); }
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
ctx.connection.fetch.register({
|
|
290
|
+
path: UPDATE_PATH, methods: ['GET'], requestBody: 'buffered',
|
|
291
|
+
fetch: async (request) => {
|
|
292
|
+
try { return json(await checkUpdate(fetch, PACKAGE, request.signal)); } catch (error) { return json({ error: String(error?.message ?? error) }, 502); }
|
|
293
|
+
},
|
|
294
|
+
});
|
|
242
295
|
const store = grantsStore(join(process.env.DSH_HOME || join(homedir(), '.dsh'), 'storages', 'dsh-composer-plus', 'grants.json'));
|
|
243
296
|
ctx.connection.fetch.register({
|
|
244
297
|
path: GRANTS_PATH, methods: ['GET', 'POST'], requestBody: 'buffered',
|
package/locale/de.json
ADDED
package/locale/en.json
ADDED
package/locale/es.json
ADDED
package/locale/fr.json
ADDED
package/locale/hi.json
ADDED
package/locale/id.json
ADDED
package/locale/ja.json
ADDED
package/locale/ko.json
ADDED
package/locale/ru.json
ADDED
package/locale/tr.json
ADDED
package/locale/vi.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,35 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-composer-plus",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "DeepSeek Harness helpers: 11 extra UI languages (Türkçe, Español, Français, Deutsch, 日本語…), Changes panel, input history, Shift+Tab /plan, one-click Continue, queue drag-and-drop, deeplinks, Auto Review allow-for-chat, notifications",
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "DeepSeek Harness helpers: 11 extra UI languages (Türkçe, Español, Français, Deutsch, 日本語…), Changes panel, input history, Shift+Tab /plan, one-click Continue, queue drag-and-drop, deeplinks, Auto Review allow-for-chat, notifications, automatic updates",
|
|
5
|
+
"icon": "./assets/icon.svg",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"keywords": [
|
|
9
|
+
"auto-review",
|
|
10
|
+
"auto-update",
|
|
8
11
|
"changes",
|
|
12
|
+
"claude-code",
|
|
13
|
+
"codex",
|
|
14
|
+
"composer-plus",
|
|
15
|
+
"continue",
|
|
16
|
+
"deeplink",
|
|
17
|
+
"deepseek",
|
|
9
18
|
"deepseek-harness",
|
|
19
|
+
"deepseek-harness-plugin",
|
|
20
|
+
"drag-and-drop",
|
|
10
21
|
"dsh",
|
|
22
|
+
"dsh-composer-plus",
|
|
11
23
|
"dsh-plugin",
|
|
24
|
+
"dsh-plugins",
|
|
12
25
|
"git",
|
|
26
|
+
"git-diff",
|
|
13
27
|
"i18n",
|
|
28
|
+
"input-history",
|
|
14
29
|
"localization",
|
|
15
30
|
"notifications",
|
|
31
|
+
"plan-mode",
|
|
16
32
|
"plugin",
|
|
33
|
+
"queue",
|
|
17
34
|
"translation"
|
|
18
35
|
],
|
|
19
36
|
"exports": {
|
|
20
37
|
".": "./index.js",
|
|
21
|
-
"./client": "./client.js"
|
|
38
|
+
"./client": "./client.js",
|
|
39
|
+
"./locale/*.json": "./locale/*.json",
|
|
40
|
+
"./package.json": "./package.json"
|
|
22
41
|
},
|
|
23
42
|
"files": [
|
|
24
43
|
"index.js",
|
|
25
44
|
"client.js",
|
|
45
|
+
"locale/*.json",
|
|
46
|
+
"assets/icon.svg",
|
|
26
47
|
"cordis.patch.yml",
|
|
27
48
|
"README.md",
|
|
28
49
|
"LICENSE",
|
|
29
|
-
"locales/LICENSE"
|
|
50
|
+
"locales/LICENSE",
|
|
51
|
+
"assets/features/*.webp"
|
|
30
52
|
],
|
|
31
53
|
"scripts": {
|
|
32
|
-
"test": "node scripts/build-locales.mjs --check && node test/locale.test.mjs && node test/continue.test.mjs && node test/continue-host.test.mjs && node test/queue-drag.test.mjs && node test/plan-toggle.test.mjs && node test/deeplink.test.mjs && node test/chat-grant.test.mjs && node test/notify.test.mjs && node test/changes.test.mjs && node test/project-status.test.mjs && node test/toggles.test.mjs",
|
|
54
|
+
"test": "node scripts/build-locales.mjs --check && node test/locale.test.mjs && node test/continue.test.mjs && node test/continue-host.test.mjs && node test/queue-drag.test.mjs && node test/plan-toggle.test.mjs && node test/deeplink.test.mjs && node test/chat-grant.test.mjs && node test/notify.test.mjs && node test/changes.test.mjs && node test/project-status.test.mjs && node test/toggles.test.mjs && node test/update.test.mjs && node test/meta.test.mjs && node test/shots.test.mjs",
|
|
33
55
|
"build:locales": "node scripts/build-locales.mjs",
|
|
34
56
|
"prepublishOnly": "npm test"
|
|
35
57
|
},
|