@michengai/dsh-codex-suite 0.1.14 → 0.1.16
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 +4 -4
- package/README.zh-CN.md +4 -4
- package/package.json +3 -11
- package/bin.mjs +0 -10
- package/installer.mjs +0 -169
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DSH Codex Suite
|
|
2
2
|
|
|
3
|
-
`@michengai/dsh-codex-suite`
|
|
3
|
+
`@michengai/dsh-codex-suite` remains the compatibility aggregate for profiles installed with the old `dsh plugin add` command. For new installs and migration, use the lightweight `@michengai/dsh-codex-suite-installer`; it adds the six members as **direct dependencies**.
|
|
4
4
|
|
|
5
5
|
## Plugin combo
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| IM Assistant | `@michengai/dsh-im-connect` |
|
|
14
14
|
| Scheduled tasks | `@michengai/dsh-automation` |
|
|
15
15
|
|
|
16
|
-
Each Suite release pins one exact, verified member set.
|
|
16
|
+
Each Suite release pins one exact, verified member set. The separate installer has no member runtime dependency tree of its own, so `npx` can start immediately and let DSH install the members directly. `dshmarket` and `dsh-find-plugin` remain optional and can be installed separately from About.
|
|
17
17
|
|
|
18
18
|
## One-click installation
|
|
19
19
|
|
|
@@ -22,7 +22,7 @@ Node.js 22+ is required, and the current DSH `dsh` command must be on PATH. Run
|
|
|
22
22
|
```powershell
|
|
23
23
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
24
24
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
25
|
-
npx --yes @michengai/dsh-codex-suite@latest --profile web
|
|
25
|
+
npx --yes @michengai/dsh-codex-suite-installer@latest --profile web
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
The installer:
|
|
@@ -39,7 +39,7 @@ Restart DSH Web and hard-refresh the browser afterwards. Set `DSH_BIN` when `dsh
|
|
|
39
39
|
Keep the same `DSH_HOME` and choose another profile name:
|
|
40
40
|
|
|
41
41
|
```powershell
|
|
42
|
-
npx --yes @michengai/dsh-codex-suite@latest --profile codex
|
|
42
|
+
npx --yes @michengai/dsh-codex-suite-installer@latest --profile codex
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
DSH supplies `@deepseek-ai/dsh-base` when it creates a custom profile. The installer places DSH's built-in `@deepseek-ai/dsh-web-app` before the six member bundles without creating a separate Home or reinstalling the official Web package from npm.
|
package/README.zh-CN.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DSH Codex Suite
|
|
2
2
|
|
|
3
|
-
`@michengai/dsh-codex-suite`
|
|
3
|
+
`@michengai/dsh-codex-suite` 保留为兼容旧版 `dsh plugin add` 的聚合包。新安装和旧版迁移请使用轻量的 `@michengai/dsh-codex-suite-installer`,它会把六个成员写成目标 profile 的**直接依赖**。
|
|
4
4
|
|
|
5
5
|
## 插件组合
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| IM 助理 | `@michengai/dsh-im-connect` |
|
|
14
14
|
| 定时任务 | `@michengai/dsh-automation` |
|
|
15
15
|
|
|
16
|
-
每个 Suite
|
|
16
|
+
每个 Suite 版本锁定一组经过验证的成员精确版本。独立安装器自身不携带成员运行时依赖树,因此 `npx` 可以立即启动,再交给 DSH 直接安装成员。`dshmarket` 和 `dsh-find-plugin` 不在套件内,需要时可在「设置 → 关于」中单独安装。
|
|
17
17
|
|
|
18
18
|
## 一键安装
|
|
19
19
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
```powershell
|
|
23
23
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
24
24
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
25
|
-
npx --yes @michengai/dsh-codex-suite@latest --profile web
|
|
25
|
+
npx --yes @michengai/dsh-codex-suite-installer@latest --profile web
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
安装器会:
|
|
@@ -39,7 +39,7 @@ npx --yes @michengai/dsh-codex-suite@latest --profile web
|
|
|
39
39
|
保持同一个 `DSH_HOME`,只需换一个 profile 名:
|
|
40
40
|
|
|
41
41
|
```powershell
|
|
42
|
-
npx --yes @michengai/dsh-codex-suite@latest --profile codex
|
|
42
|
+
npx --yes @michengai/dsh-codex-suite-installer@latest --profile codex
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
DSH 创建自定义 profile 时会提供 `@deepseek-ai/dsh-base`。安装器会再把 DSH 自带的 `@deepseek-ai/dsh-web-app` 放到六个成员 bundle 之前,不会创建独立 Home,也不会通过 npm 重装官方 Web 包。
|
package/package.json
CHANGED
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-codex-suite",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "DSH Codex UI
|
|
3
|
+
"version": "0.1.16",
|
|
4
|
+
"description": "DSH Codex UI 兼容聚合包:保留旧版 dsh plugin add 安装方式",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"engines": {
|
|
8
|
-
"node": ">=22"
|
|
9
|
-
},
|
|
10
7
|
"files": [
|
|
11
|
-
"bin.mjs",
|
|
12
|
-
"installer.mjs",
|
|
13
8
|
"cordis.patch.yml",
|
|
14
9
|
"README.md",
|
|
15
10
|
"README.zh-CN.md"
|
|
16
11
|
],
|
|
17
|
-
"bin": {
|
|
18
|
-
"dsh-codex-suite": "./bin.mjs"
|
|
19
|
-
},
|
|
20
12
|
"dsh": {
|
|
21
13
|
"bundle": {
|
|
22
14
|
"patch": "./cordis.patch.yml"
|
|
@@ -32,6 +24,6 @@
|
|
|
32
24
|
"@michengai/dsh-automation": "0.1.14",
|
|
33
25
|
"@michengai/dsh-im-connect": "0.1.23",
|
|
34
26
|
"@michengai/dsh-skills-manager": "0.1.24",
|
|
35
|
-
"@michengai/dsh-codex-ui": "0.2.
|
|
27
|
+
"@michengai/dsh-codex-ui": "0.2.84"
|
|
36
28
|
}
|
|
37
29
|
}
|
package/bin.mjs
DELETED
package/installer.mjs
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { spawnSync } from 'node:child_process'
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
|
-
import { homedir } from 'node:os'
|
|
4
|
-
import { resolve } from 'node:path'
|
|
5
|
-
|
|
6
|
-
export const SUITE_PACKAGE = '@michengai/dsh-codex-suite'
|
|
7
|
-
export const BASE_BUNDLE = '@deepseek-ai/dsh-base'
|
|
8
|
-
export const WEB_BUNDLE = '@deepseek-ai/dsh-web-app'
|
|
9
|
-
|
|
10
|
-
const suiteManifest = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'))
|
|
11
|
-
|
|
12
|
-
/** Keep the same layer order as the legacy aggregate patch. */
|
|
13
|
-
export const MEMBER_PACKAGES = [
|
|
14
|
-
'@michengai/dsh-archive-manager',
|
|
15
|
-
'@michengai/dsh-codex-ui',
|
|
16
|
-
'@michengai/dsh-skills-manager',
|
|
17
|
-
'@michengai/dsh-agency-agents',
|
|
18
|
-
'@michengai/dsh-im-connect',
|
|
19
|
-
'@michengai/dsh-automation',
|
|
20
|
-
]
|
|
21
|
-
|
|
22
|
-
export function memberSpecs(manifest = suiteManifest) {
|
|
23
|
-
return MEMBER_PACKAGES.map((packageName) => {
|
|
24
|
-
let version = manifest.dependencies?.[packageName]
|
|
25
|
-
if (version?.startsWith('workspace:') === true && packageName === '@michengai/dsh-codex-ui') {
|
|
26
|
-
version = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf8')).version
|
|
27
|
-
}
|
|
28
|
-
if (typeof version !== 'string' || version === '' || version.startsWith('workspace:')) {
|
|
29
|
-
throw new Error(`Suite manifest does not contain a published version for ${packageName}.`)
|
|
30
|
-
}
|
|
31
|
-
return `${packageName}@${version}`
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function parseArgs(argv) {
|
|
36
|
-
const options = {
|
|
37
|
-
profile: 'web',
|
|
38
|
-
registry: 'https://registry.npmjs.org/',
|
|
39
|
-
dryRun: false,
|
|
40
|
-
help: false,
|
|
41
|
-
}
|
|
42
|
-
for (let index = 0; index < argv.length; index += 1) {
|
|
43
|
-
const argument = argv[index]
|
|
44
|
-
if (argument === '--help' || argument === '-h') options.help = true
|
|
45
|
-
else if (argument === '--dry-run') options.dryRun = true
|
|
46
|
-
else if (argument === '--profile') options.profile = argv[++index]
|
|
47
|
-
else if (argument.startsWith('--profile=')) options.profile = argument.slice('--profile='.length)
|
|
48
|
-
else if (argument === '--registry') options.registry = argv[++index]
|
|
49
|
-
else if (argument.startsWith('--registry=')) options.registry = argument.slice('--registry='.length)
|
|
50
|
-
else throw new Error(`Unknown argument: ${argument}`)
|
|
51
|
-
}
|
|
52
|
-
if (typeof options.profile !== 'string' || !/^[0-9A-Za-z][0-9A-Za-z._-]*$/.test(options.profile) || options.profile === 'node_modules') {
|
|
53
|
-
throw new Error(`Invalid DSH profile name: ${JSON.stringify(options.profile)}`)
|
|
54
|
-
}
|
|
55
|
-
let registry
|
|
56
|
-
try {
|
|
57
|
-
registry = new URL(options.registry)
|
|
58
|
-
} catch {
|
|
59
|
-
throw new Error(`Invalid npm registry URL: ${JSON.stringify(options.registry)}`)
|
|
60
|
-
}
|
|
61
|
-
if (registry.protocol !== 'https:' && registry.protocol !== 'http:') throw new Error('npm registry must use HTTP or HTTPS.')
|
|
62
|
-
if (registry.username !== '' || registry.password !== '' || registry.search !== '' || registry.hash !== '' || !/^[0-9A-Za-z._~/-]*$/.test(registry.pathname)) {
|
|
63
|
-
throw new Error('npm registry URL contains unsupported characters.')
|
|
64
|
-
}
|
|
65
|
-
options.registry = registry.href
|
|
66
|
-
return options
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function profileDirectory(profile, env = process.env, home = homedir()) {
|
|
70
|
-
const dshHome = env.DSH_HOME === undefined || env.DSH_HOME === '' ? resolve(home, '.dsh') : resolve(env.DSH_HOME)
|
|
71
|
-
return resolve(dshHome, 'profiles', profile)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function normalizeBundles(bundles = []) {
|
|
75
|
-
const managed = new Set([BASE_BUNDLE, WEB_BUNDLE, SUITE_PACKAGE, ...MEMBER_PACKAGES])
|
|
76
|
-
const unrelated = bundles.filter((name, index) => typeof name === 'string' && !managed.has(name) && bundles.indexOf(name) === index)
|
|
77
|
-
return [BASE_BUNDLE, WEB_BUNDLE, ...unrelated, ...MEMBER_PACKAGES]
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function allowRequiredBuilds(source) {
|
|
81
|
-
const eol = source.includes('\r\n') ? '\r\n' : '\n'
|
|
82
|
-
const lines = source.split(/\r?\n/)
|
|
83
|
-
const start = lines.findIndex(line => line === 'allowBuilds:')
|
|
84
|
-
if (start === -1) return `${source}${source === '' || source.endsWith('\n') ? '' : eol}allowBuilds:${eol} protobufjs: false${eol} koffi: false${eol}`
|
|
85
|
-
let end = start + 1
|
|
86
|
-
while (end < lines.length && (lines[end] === '' || /^\s/.test(lines[end]))) end += 1
|
|
87
|
-
const body = lines.slice(start + 1, end).filter(line => !/^\s{2}(?:protobufjs|koffi):/.test(line))
|
|
88
|
-
lines.splice(start + 1, end - start - 1, ' protobufjs: false', ' koffi: false', ...body)
|
|
89
|
-
return lines.join(eol)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function directInstallArgs(profile, registry, manifest = suiteManifest) {
|
|
93
|
-
return ['plugin', '--profile', profile, 'add', ...memberSpecs(manifest), '--save-exact', `--registry=${registry}`]
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export function helpText() {
|
|
97
|
-
return `Usage: dsh-codex-suite [options]\n\nInstall every Codex Suite member as a direct dependency of one DSH profile.\n\nOptions:\n --profile <name> target profile (default: web)\n --registry <url> npm registry (default: https://registry.npmjs.org/)\n --dry-run print commands without changing the profile\n -h, --help show this help\n`
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function quote(argument) {
|
|
101
|
-
return /[\s"']/u.test(argument) ? JSON.stringify(argument) : argument
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function runDsh(args, { dryRun = false, command = process.env.DSH_BIN || 'dsh' } = {}) {
|
|
105
|
-
process.stdout.write(`> dsh ${args.map(quote).join(' ')}\n`)
|
|
106
|
-
if (dryRun) return
|
|
107
|
-
const result = process.platform === 'win32'
|
|
108
|
-
? spawnSync(process.env.ComSpec || 'cmd.exe', ['/d', '/s', '/c', `call ${/\s/.test(command) ? `"${command.replaceAll('"', '""')}"` : command} ${args.join(' ')}`], { encoding: 'utf8', stdio: 'inherit', windowsHide: true })
|
|
109
|
-
: spawnSync(command, args, { encoding: 'utf8', stdio: 'inherit' })
|
|
110
|
-
if (result.error !== undefined) throw new Error(`Unable to run dsh: ${result.error.message}`)
|
|
111
|
-
if (result.status !== 0) throw new Error(`dsh exited with code ${result.status ?? 1}.`)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function readProfileManifest(path) {
|
|
115
|
-
return JSON.parse(readFileSync(path, 'utf8'))
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function suiteDeclared(manifest) {
|
|
119
|
-
return manifest.dependencies?.[SUITE_PACKAGE] !== undefined
|
|
120
|
-
|| manifest.devDependencies?.[SUITE_PACKAGE] !== undefined
|
|
121
|
-
|| manifest.dsh?.profile?.bundles?.includes(SUITE_PACKAGE) === true
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function legacyDirectPackages(manifest) {
|
|
125
|
-
const declared = { ...manifest.devDependencies, ...manifest.dependencies }
|
|
126
|
-
return [
|
|
127
|
-
...(suiteDeclared(manifest) ? [SUITE_PACKAGE] : []),
|
|
128
|
-
...(declared[WEB_BUNDLE] !== undefined ? [WEB_BUNDLE] : []),
|
|
129
|
-
]
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function writeNormalizedManifest(path) {
|
|
133
|
-
const manifest = readProfileManifest(path)
|
|
134
|
-
manifest.dsh ??= {}
|
|
135
|
-
manifest.dsh.profile ??= {}
|
|
136
|
-
manifest.dsh.profile.bundles = normalizeBundles(manifest.dsh.profile.bundles)
|
|
137
|
-
writeFileSync(path, `${JSON.stringify(manifest, undefined, 2)}\n`, 'utf8')
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function installSuite(argv = process.argv.slice(2)) {
|
|
141
|
-
const options = parseArgs(argv)
|
|
142
|
-
if (options.help) {
|
|
143
|
-
process.stdout.write(helpText())
|
|
144
|
-
return
|
|
145
|
-
}
|
|
146
|
-
const profilePath = profileDirectory(options.profile)
|
|
147
|
-
const manifestPath = resolve(profilePath, 'package.json')
|
|
148
|
-
const workspacePath = resolve(profilePath, 'pnpm-workspace.yaml')
|
|
149
|
-
if (!existsSync(manifestPath)) runDsh(['plugin', '--profile', options.profile, 'install', '--lockfile-only', '--ignore-scripts'], options)
|
|
150
|
-
if (options.dryRun) {
|
|
151
|
-
process.stdout.write(`> ensure protobufjs build scripts stay explicitly disabled in ${workspacePath}\n`)
|
|
152
|
-
} else {
|
|
153
|
-
const workspace = existsSync(workspacePath) ? readFileSync(workspacePath, 'utf8') : ''
|
|
154
|
-
const nextWorkspace = allowRequiredBuilds(workspace)
|
|
155
|
-
if (nextWorkspace !== workspace) writeFileSync(workspacePath, nextWorkspace, 'utf8')
|
|
156
|
-
}
|
|
157
|
-
runDsh(directInstallArgs(options.profile, options.registry), options)
|
|
158
|
-
if (options.dryRun) {
|
|
159
|
-
process.stdout.write(`> ensure ${WEB_BUNDLE} precedes the six member bundles in ${manifestPath}\n`)
|
|
160
|
-
process.stdout.write(`> remove legacy ${SUITE_PACKAGE} and redundant direct ${WEB_BUNDLE} dependencies when present\n`)
|
|
161
|
-
return
|
|
162
|
-
}
|
|
163
|
-
const installedManifest = readProfileManifest(manifestPath)
|
|
164
|
-
const legacyPackages = legacyDirectPackages(installedManifest)
|
|
165
|
-
if (legacyPackages.length > 0) runDsh(['plugin', '--profile', options.profile, 'remove', ...legacyPackages], options)
|
|
166
|
-
writeNormalizedManifest(manifestPath)
|
|
167
|
-
runDsh(['--profile', options.profile, '--dump-config'], options)
|
|
168
|
-
process.stdout.write(`\nCodex Suite members are direct plugins in profile ${options.profile}. Restart DSH and hard-refresh the browser.\n`)
|
|
169
|
-
}
|