@lihuu/dsh-about 0.1.2 → 0.1.3
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 +9 -1
- package/cordis.patch.yml +6 -0
- package/lib/client.js +2 -2
- package/lib/index.d.ts +6 -7
- package/lib/index.js +76 -31
- package/package.json +9 -1
- package/src/index.ts +73 -29
package/README.md
CHANGED
|
@@ -14,11 +14,19 @@ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin tha
|
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
17
|
+
The package is a **bundle**: it ships its own configuration layer, so installing it into a profile activates the plugin automatically.
|
|
18
|
+
|
|
17
19
|
```sh
|
|
18
20
|
dsh plugin --profile web add @lihuu/dsh-about
|
|
19
21
|
```
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
`dsh plugin add` appends the bundle to the profile's layer stack (`dsh.profile.bundles`), and the bundle's patch file mounts the plugin row. No manual patch editing is needed.
|
|
24
|
+
|
|
25
|
+
> If you previously mounted this plugin by hand (a `dsh-about` row in `~/.dsh/cordis.patch.yml`), remove that row before installing the bundle — the duplicate row id fails the boot.
|
|
26
|
+
|
|
27
|
+
Restart the web service once after installing (bundle layers are composed at boot). Later edits to your own patch files hot-reload on profiles with `patchReload: live`.
|
|
28
|
+
|
|
29
|
+
Then open **Settings → About** in the GUI.
|
|
22
30
|
|
|
23
31
|
## License
|
|
24
32
|
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# The dsh-about bundle patch: mounts the About page plugin row.
|
|
2
|
+
# Applied as a profile layer when the profile lists this bundle; the row
|
|
3
|
+
# references the package by name so Node resolution finds the installed code.
|
|
4
|
+
- insert:
|
|
5
|
+
- id: dsh-about
|
|
6
|
+
name: '@lihuu/dsh-about'
|
package/lib/client.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* dsh-about — independent "About" settings section (BROWSER half).
|
|
3
3
|
*
|
|
4
|
-
* Plain-JS client bundle served as `/plugins/@
|
|
5
|
-
* Registers the "
|
|
4
|
+
* Plain-JS client bundle served as `/plugins/@lihuu/dsh-about/client.js`.
|
|
5
|
+
* Registers the "About" page into the settings.section list slot and resolves
|
|
6
6
|
* the running version + build date through the host's runtime Typert Remote
|
|
7
7
|
* endpoint `aboutInfo/get` via the generic `/api` RPC channel — no generated
|
|
8
8
|
* artifacts, no main-repo changes.
|
package/lib/index.d.ts
CHANGED
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
* (HOST half).
|
|
4
4
|
*
|
|
5
5
|
* Provides the `aboutInfo` Typert Remote service: the browser half's settings
|
|
6
|
-
* "
|
|
6
|
+
* "About" page resolves the running version and build date through the runtime
|
|
7
7
|
* `aboutInfo/get` endpoint. The host gateway (`dsh-api-gateway`) dispatches
|
|
8
8
|
* `/api/aboutInfo/get` to this live service via source-mode discovery
|
|
9
|
-
* (`typertRemote` binding + `Remote` markers), so
|
|
10
|
-
* artifacts and
|
|
11
|
-
* an installable `@local` plugin.
|
|
9
|
+
* (`typertRemote` binding + `Remote` markers), so no compile-time generated
|
|
10
|
+
* artifacts and no main-repo changes are involved.
|
|
12
11
|
*
|
|
13
12
|
* @module dsh-about
|
|
14
13
|
*/
|
|
@@ -18,9 +17,9 @@ import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
|
18
17
|
export declare const name = "dsh-about";
|
|
19
18
|
/** The about payload the settings page renders. */
|
|
20
19
|
export interface AboutInfo {
|
|
21
|
-
/** Running version, read from
|
|
20
|
+
/** Running version, read from the dsh CLI's package.json. */
|
|
22
21
|
readonly version: string;
|
|
23
|
-
/** Build date, from the built CLI's mtime. */
|
|
22
|
+
/** Build date, from the built CLI entry's mtime. */
|
|
24
23
|
readonly buildDate: string;
|
|
25
24
|
}
|
|
26
25
|
/**
|
|
@@ -37,7 +36,7 @@ export declare class AboutInfoService extends TypertRemoteService {
|
|
|
37
36
|
constructor(ctx: Context);
|
|
38
37
|
/**
|
|
39
38
|
* Read the running version and build date.
|
|
40
|
-
* @Remote('get') — invoked by the host gateway
|
|
39
|
+
* @Remote('get') — invoked by the host gateway.
|
|
41
40
|
* @returns version + build date; unknown fields degrade to 'unknown'.
|
|
42
41
|
*/
|
|
43
42
|
get(): Promise<AboutInfo>;
|
package/lib/index.js
CHANGED
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
* (HOST half).
|
|
4
4
|
*
|
|
5
5
|
* Provides the `aboutInfo` Typert Remote service: the browser half's settings
|
|
6
|
-
* "
|
|
6
|
+
* "About" page resolves the running version and build date through the runtime
|
|
7
7
|
* `aboutInfo/get` endpoint. The host gateway (`dsh-api-gateway`) dispatches
|
|
8
8
|
* `/api/aboutInfo/get` to this live service via source-mode discovery
|
|
9
|
-
* (`typertRemote` binding + `Remote` markers), so
|
|
10
|
-
* artifacts and
|
|
11
|
-
* an installable `@local` plugin.
|
|
9
|
+
* (`typertRemote` binding + `Remote` markers), so no compile-time generated
|
|
10
|
+
* artifacts and no main-repo changes are involved.
|
|
12
11
|
*
|
|
13
12
|
* @module dsh-about
|
|
14
13
|
*/
|
|
@@ -46,17 +45,56 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
46
45
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
47
46
|
done = true;
|
|
48
47
|
};
|
|
48
|
+
import { realpathSync } from 'node:fs';
|
|
49
|
+
import { dirname, join } from 'node:path';
|
|
49
50
|
import { TypertRemoteService, Remote } from '@deepseek-ai/dsh-typert-protocol';
|
|
50
51
|
/** Stable plugin row name (used by the cordis loader entry). */
|
|
51
52
|
export const name = 'dsh-about';
|
|
52
53
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
54
|
+
* Absolute paths of the running dsh CLI's package.json, most specific first.
|
|
55
|
+
* Mirrors the CLI's own version resolution (`../package.json` relative to its
|
|
56
|
+
* entry script) so any install layout resolves: a source checkout exporting
|
|
57
|
+
* `$DSH_REPO`, the running CLI entry (`process.argv[1]`, symlink-resolved for
|
|
58
|
+
* npm-installed bins), or a source checkout launched from its root.
|
|
58
59
|
*/
|
|
59
|
-
|
|
60
|
+
function cliManifestCandidates() {
|
|
61
|
+
const candidates = [];
|
|
62
|
+
const repo = process.env.DSH_REPO;
|
|
63
|
+
if (repo !== undefined)
|
|
64
|
+
candidates.push(join(repo, 'apps/cli/package.json'));
|
|
65
|
+
const entry = process.argv[1];
|
|
66
|
+
if (entry !== undefined) {
|
|
67
|
+
try {
|
|
68
|
+
candidates.push(join(dirname(realpathSync(entry)), '../package.json'));
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// entry path unresolvable — try the remaining candidates
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
candidates.push(join(process.cwd(), 'apps/cli/package.json'));
|
|
75
|
+
return candidates;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Absolute paths of the running dsh CLI's built entry file, most specific
|
|
79
|
+
* first; its mtime is the build date.
|
|
80
|
+
*/
|
|
81
|
+
function cliEntryCandidates() {
|
|
82
|
+
const candidates = [];
|
|
83
|
+
const entry = process.argv[1];
|
|
84
|
+
if (entry !== undefined) {
|
|
85
|
+
try {
|
|
86
|
+
candidates.push(realpathSync(entry));
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// entry path unresolvable — try the remaining candidates
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const repo = process.env.DSH_REPO;
|
|
93
|
+
if (repo !== undefined)
|
|
94
|
+
candidates.push(join(repo, 'apps/cli/lib/bin.js'));
|
|
95
|
+
candidates.push(join(process.cwd(), 'apps/cli/lib/bin.js'));
|
|
96
|
+
return candidates;
|
|
97
|
+
}
|
|
60
98
|
/**
|
|
61
99
|
* About info remote service. Registered under `aboutInfo`; the `get` method is
|
|
62
100
|
* the single `@Remote` endpoint the browser half calls through
|
|
@@ -85,36 +123,43 @@ let AboutInfoService = (() => {
|
|
|
85
123
|
}
|
|
86
124
|
/**
|
|
87
125
|
* Read the running version and build date.
|
|
88
|
-
* @Remote('get') — invoked by the host gateway
|
|
126
|
+
* @Remote('get') — invoked by the host gateway.
|
|
89
127
|
* @returns version + build date; unknown fields degrade to 'unknown'.
|
|
90
128
|
*/
|
|
91
129
|
async get() {
|
|
92
130
|
let version = 'unknown';
|
|
93
131
|
let buildDate = 'unknown';
|
|
94
132
|
if (this.fs !== undefined) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
133
|
+
for (const manifest of cliManifestCandidates()) {
|
|
134
|
+
try {
|
|
135
|
+
const target = await this.fs.resolve(manifest);
|
|
136
|
+
const text = await this.fs.readText(target);
|
|
137
|
+
const m = text.match(/"version"\s*:\s*"([^"]+)"/);
|
|
138
|
+
if (m !== null) {
|
|
139
|
+
version = m[1];
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// candidate unreadable — try the next one
|
|
145
|
+
}
|
|
104
146
|
}
|
|
105
147
|
}
|
|
106
148
|
if (this.shell !== undefined) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
149
|
+
const flag = process.platform === 'darwin' ? '-f "%Sm" -t "%Y-%m-%d %H:%M"' : '-c "%y"';
|
|
150
|
+
for (const entry of cliEntryCandidates()) {
|
|
151
|
+
try {
|
|
152
|
+
const spec = this.shell.resolve({ command: `stat ${flag} "${entry}"` });
|
|
153
|
+
const result = await this.shell.run(spec);
|
|
154
|
+
const out = result.stdout.text.trim();
|
|
155
|
+
if (out !== '') {
|
|
156
|
+
buildDate = out;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// candidate unstat-able — try the next one
|
|
162
|
+
}
|
|
118
163
|
}
|
|
119
164
|
}
|
|
120
165
|
return { version, buildDate };
|
package/package.json
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lihuu/dsh-about",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "DeepSeek Harness plugin: adds an About page to the web GUI settings showing the running version and build date.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": "./lib/index.js",
|
|
9
9
|
"./client": "./lib/client.js",
|
|
10
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
10
11
|
"./package.json": "./package.json"
|
|
11
12
|
},
|
|
12
13
|
"dsh": {
|
|
13
14
|
"client": {
|
|
14
15
|
"platform": "web"
|
|
16
|
+
},
|
|
17
|
+
"bundle": {
|
|
18
|
+
"patch": "./cordis.patch.yml"
|
|
15
19
|
}
|
|
16
20
|
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
17
24
|
"files": [
|
|
18
25
|
"lib",
|
|
19
26
|
"src",
|
|
27
|
+
"cordis.patch.yml",
|
|
20
28
|
"README.md"
|
|
21
29
|
],
|
|
22
30
|
"scripts": {
|
package/src/index.ts
CHANGED
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
* (HOST half).
|
|
4
4
|
*
|
|
5
5
|
* Provides the `aboutInfo` Typert Remote service: the browser half's settings
|
|
6
|
-
* "
|
|
6
|
+
* "About" page resolves the running version and build date through the runtime
|
|
7
7
|
* `aboutInfo/get` endpoint. The host gateway (`dsh-api-gateway`) dispatches
|
|
8
8
|
* `/api/aboutInfo/get` to this live service via source-mode discovery
|
|
9
|
-
* (`typertRemote` binding + `Remote` markers), so
|
|
10
|
-
* artifacts and
|
|
11
|
-
* an installable `@local` plugin.
|
|
9
|
+
* (`typertRemote` binding + `Remote` markers), so no compile-time generated
|
|
10
|
+
* artifacts and no main-repo changes are involved.
|
|
12
11
|
*
|
|
13
12
|
* @module dsh-about
|
|
14
13
|
*/
|
|
15
14
|
|
|
15
|
+
import { realpathSync } from 'node:fs'
|
|
16
|
+
import { dirname, join } from 'node:path'
|
|
16
17
|
import type { Context } from '@deepseek-ai/cordis'
|
|
17
18
|
import { TypertRemoteService, Remote } from '@deepseek-ai/dsh-typert-protocol'
|
|
18
19
|
|
|
@@ -21,9 +22,9 @@ export const name = 'dsh-about'
|
|
|
21
22
|
|
|
22
23
|
/** The about payload the settings page renders. */
|
|
23
24
|
export interface AboutInfo {
|
|
24
|
-
/** Running version, read from
|
|
25
|
+
/** Running version, read from the dsh CLI's package.json. */
|
|
25
26
|
readonly version: string
|
|
26
|
-
/** Build date, from the built CLI's mtime. */
|
|
27
|
+
/** Build date, from the built CLI entry's mtime. */
|
|
27
28
|
readonly buildDate: string
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -43,13 +44,47 @@ interface ShellLike {
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
47
|
+
* Absolute paths of the running dsh CLI's package.json, most specific first.
|
|
48
|
+
* Mirrors the CLI's own version resolution (`../package.json` relative to its
|
|
49
|
+
* entry script) so any install layout resolves: a source checkout exporting
|
|
50
|
+
* `$DSH_REPO`, the running CLI entry (`process.argv[1]`, symlink-resolved for
|
|
51
|
+
* npm-installed bins), or a source checkout launched from its root.
|
|
51
52
|
*/
|
|
52
|
-
|
|
53
|
+
function cliManifestCandidates(): string[] {
|
|
54
|
+
const candidates: string[] = []
|
|
55
|
+
const repo = process.env.DSH_REPO
|
|
56
|
+
if (repo !== undefined) candidates.push(join(repo, 'apps/cli/package.json'))
|
|
57
|
+
const entry = process.argv[1]
|
|
58
|
+
if (entry !== undefined) {
|
|
59
|
+
try {
|
|
60
|
+
candidates.push(join(dirname(realpathSync(entry)), '../package.json'))
|
|
61
|
+
} catch {
|
|
62
|
+
// entry path unresolvable — try the remaining candidates
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
candidates.push(join(process.cwd(), 'apps/cli/package.json'))
|
|
66
|
+
return candidates
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Absolute paths of the running dsh CLI's built entry file, most specific
|
|
71
|
+
* first; its mtime is the build date.
|
|
72
|
+
*/
|
|
73
|
+
function cliEntryCandidates(): string[] {
|
|
74
|
+
const candidates: string[] = []
|
|
75
|
+
const entry = process.argv[1]
|
|
76
|
+
if (entry !== undefined) {
|
|
77
|
+
try {
|
|
78
|
+
candidates.push(realpathSync(entry))
|
|
79
|
+
} catch {
|
|
80
|
+
// entry path unresolvable — try the remaining candidates
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const repo = process.env.DSH_REPO
|
|
84
|
+
if (repo !== undefined) candidates.push(join(repo, 'apps/cli/lib/bin.js'))
|
|
85
|
+
candidates.push(join(process.cwd(), 'apps/cli/lib/bin.js'))
|
|
86
|
+
return candidates
|
|
87
|
+
}
|
|
53
88
|
|
|
54
89
|
/**
|
|
55
90
|
* About info remote service. Registered under `aboutInfo`; the `get` method is
|
|
@@ -71,7 +106,7 @@ export class AboutInfoService extends TypertRemoteService {
|
|
|
71
106
|
|
|
72
107
|
/**
|
|
73
108
|
* Read the running version and build date.
|
|
74
|
-
* @Remote('get') — invoked by the host gateway
|
|
109
|
+
* @Remote('get') — invoked by the host gateway.
|
|
75
110
|
* @returns version + build date; unknown fields degrade to 'unknown'.
|
|
76
111
|
*/
|
|
77
112
|
@Remote('get')
|
|
@@ -80,26 +115,35 @@ export class AboutInfoService extends TypertRemoteService {
|
|
|
80
115
|
let buildDate = 'unknown'
|
|
81
116
|
|
|
82
117
|
if (this.fs !== undefined) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
118
|
+
for (const manifest of cliManifestCandidates()) {
|
|
119
|
+
try {
|
|
120
|
+
const target = await this.fs.resolve(manifest)
|
|
121
|
+
const text = await this.fs.readText(target)
|
|
122
|
+
const m = text.match(/"version"\s*:\s*"([^"]+)"/)
|
|
123
|
+
if (m !== null) {
|
|
124
|
+
version = m[1]
|
|
125
|
+
break
|
|
126
|
+
}
|
|
127
|
+
} catch {
|
|
128
|
+
// candidate unreadable — try the next one
|
|
129
|
+
}
|
|
90
130
|
}
|
|
91
131
|
}
|
|
92
132
|
|
|
93
133
|
if (this.shell !== undefined) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
134
|
+
const flag = process.platform === 'darwin' ? '-f "%Sm" -t "%Y-%m-%d %H:%M"' : '-c "%y"'
|
|
135
|
+
for (const entry of cliEntryCandidates()) {
|
|
136
|
+
try {
|
|
137
|
+
const spec = this.shell.resolve({ command: `stat ${flag} "${entry}"` })
|
|
138
|
+
const result = await this.shell.run(spec)
|
|
139
|
+
const out = result.stdout.text.trim()
|
|
140
|
+
if (out !== '') {
|
|
141
|
+
buildDate = out
|
|
142
|
+
break
|
|
143
|
+
}
|
|
144
|
+
} catch {
|
|
145
|
+
// candidate unstat-able — try the next one
|
|
146
|
+
}
|
|
103
147
|
}
|
|
104
148
|
}
|
|
105
149
|
|