prompt-skill-armory 0.4.2 → 0.4.4

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.
Files changed (2) hide show
  1. package/cli.cjs +59 -35
  2. package/package.json +1 -1
package/cli.cjs CHANGED
@@ -2,25 +2,22 @@
2
2
  /**
3
3
  * prompt-skill-armory — one-command installer.
4
4
  *
5
- * npx prompt-skill-armory # install into the DeepSeek Harness web profile
5
+ * npx prompt-skill-armory # install into all DeepSeek Harness profiles
6
6
  * npx prompt-skill-armory --postinstall
7
7
  *
8
8
  * What it does:
9
9
  * 1. Locates the harness home (~/.dsh, or $DSH_HOME).
10
- * 2. Ensures the web profile exists.
11
- * 3. Copies the bundled plugin packages
12
- * (@deepseek-ai/dsh-switchblade + @deepseek-ai/dsh-client-ui-switchblade)
13
- * into the profile's node_modules/@deepseek-ai/.
14
- * 4. Adds the Host bundle to the profile's dsh.profile.bundles.
15
- * 5. Prints next steps (build + launch).
10
+ * 2. Finds every profile under profiles/ (web, desktop, …) and installs the
11
+ * bundled plugin packages into each profile's node_modules/@deepseek-ai/.
12
+ * 3. Adds the Host bundle to each profile's dsh.profile.bundles.
13
+ * 4. Prints next steps (build + launch).
16
14
  *
17
- * The plugin packages ship inside this installer under packages/ (built lib +
18
- * source + manifests), so no separate DSH repo checkout is needed to install
19
- * the plugin itself — the DSH runtime is still required to RUN it.
15
+ * Works with both the official `dsh` and the DSH Desktop client, which use the
16
+ * same ~/.dsh/profiles layout.
20
17
  */
21
18
  'use strict'
22
19
 
23
- const { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } = require('node:fs')
20
+ const { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } = require('node:fs')
24
21
  const { homedir } = require('node:os')
25
22
  const { join } = require('node:path')
26
23
 
@@ -30,9 +27,20 @@ const BUNDLED = join(here, 'packages')
30
27
  /** Harness home; default ~/.dsh, overridable via DSH_HOME. */
31
28
  const dshHome = process.env.DSH_HOME ?? join(homedir(), '.dsh')
32
29
  const profilesDir = join(dshHome, 'profiles')
33
- const webProfile = join(profilesDir, 'web')
34
- const scopedDir = join(webProfile, 'node_modules', '@deepseek-ai')
35
- const manifestPath = join(webProfile, 'package.json')
30
+ const settingsPath = join(dshHome, 'settings.yaml')
31
+
32
+ /** Desktop client's settings limit (from its diagnostics). */
33
+ const SETTINGS_LIMIT = 4 * 1024 * 1024
34
+
35
+ /** Warn if the harness settings document is oversized or has stale blobs. */
36
+ function healthCheck() {
37
+ if (!existsSync(settingsPath)) return
38
+ const size = readFileSync(settingsPath, 'utf8').length
39
+ if (size > SETTINGS_LIMIT) {
40
+ console.error(` ⚠ settings.yaml is ${(size / 1024 / 1024).toFixed(1)}MB — over the ${4}MB client limit.`)
41
+ console.error(' Remove large blobs (e.g. a stale pendingZip) or the client may enter recovery mode.')
42
+ }
43
+ }
36
44
 
37
45
  const HOST_BUNDLE = '@deepseek-ai/dsh-switchblade'
38
46
 
@@ -48,25 +56,34 @@ function bundledPackages() {
48
56
  return out
49
57
  }
50
58
 
51
- /** Copy one bundled package into the profile's @deepseek-ai scope. */
52
- function installPackage(pkg) {
59
+ /** Profiles that exist and look like dsh profiles (have node_modules + package.json). */
60
+ function findProfiles() {
61
+ if (!existsSync(profilesDir)) return []
62
+ const out = []
63
+ for (const name of readdirSync(profilesDir)) {
64
+ const dir = join(profilesDir, name)
65
+ if (!existsSync(join(dir, 'package.json'))) continue
66
+ if (!existsSync(join(dir, 'node_modules'))) continue
67
+ out.push(dir)
68
+ }
69
+ return out
70
+ }
71
+
72
+ /** Copy one bundled package into a profile's @deepseek-ai scope. */
73
+ function installPackage(pkg, profileDir) {
74
+ const scopedDir = join(profileDir, 'node_modules', '@deepseek-ai')
53
75
  const short = pkg.name.slice('@deepseek-ai/'.length)
54
76
  const dest = join(scopedDir, short)
55
77
  mkdirSync(scopedDir, { recursive: true })
78
+ rmSync(dest, { recursive: true, force: true })
56
79
  cpSync(pkg.from, dest, { recursive: true, force: true })
57
80
  console.log(` ✓ ${pkg.name} → ${dest}`)
58
81
  }
59
82
 
60
- /** Add the Host bundle to the web profile's dsh.profile.bundles. */
61
- function addBundle() {
62
- if (!existsSync(manifestPath)) {
63
- writeFileSync(manifestPath, JSON.stringify({
64
- name: 'dsh-profile-web',
65
- private: true,
66
- dependencies: {},
67
- dsh: { profile: { bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'] } },
68
- }, null, 2))
69
- }
83
+ /** Add the Host bundle to a profile's dsh.profile.bundles. */
84
+ function addBundle(profileDir) {
85
+ const manifestPath = join(profileDir, 'package.json')
86
+ if (!existsSync(manifestPath)) return
70
87
  const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
71
88
  const bundles = manifest.dsh?.profile?.bundles ?? []
72
89
  if (!bundles.includes(HOST_BUNDLE)) {
@@ -75,7 +92,7 @@ function addBundle() {
75
92
  writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`)
76
93
  console.log(` ✓ added ${HOST_BUNDLE} to ${manifestPath}`)
77
94
  } else {
78
- console.log(` · ${HOST_BUNDLE} already in bundles`)
95
+ console.log(` · ${HOST_BUNDLE} already in ${manifestPath}`)
79
96
  }
80
97
  }
81
98
 
@@ -86,6 +103,7 @@ function main() {
86
103
  console.log(' (postinstall hook — no profile install here)')
87
104
  return
88
105
  }
106
+ healthCheck()
89
107
 
90
108
  const pkgs = bundledPackages()
91
109
  if (pkgs.length === 0) {
@@ -93,16 +111,22 @@ function main() {
93
111
  process.exit(1)
94
112
  }
95
113
 
96
- mkdirSync(webProfile, { recursive: true })
97
- console.log(` profile: ${webProfile}`)
98
- for (const pkg of pkgs) installPackage(pkg)
99
- addBundle()
114
+ const profiles = findProfiles()
115
+ if (profiles.length === 0) {
116
+ console.error(` no dsh profiles found under ${profilesDir}`)
117
+ console.error(' (start dsh once so the profile is created, then re-run this)')
118
+ process.exit(1)
119
+ }
120
+
121
+ for (const profileDir of profiles) {
122
+ console.log(` profile: ${profileDir}`)
123
+ for (const pkg of pkgs) installPackage(pkg, profileDir)
124
+ addBundle(profileDir)
125
+ }
100
126
 
101
127
  console.log('')
102
- console.log(' Next steps (run in your DeepSeek Harness checkout):')
103
- console.log(' cd deepseek-harness')
104
- console.log(' pnpm run build')
105
- console.log(' pnpm dsh web')
128
+ console.log(' Next steps:')
129
+ console.log(' dsh web (or relaunch the DSH Desktop client)')
106
130
  console.log('')
107
131
  console.log(' Open Settings → Prompt-SkillArmory (book icon).')
108
132
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prompt-skill-armory",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "One-command installer for Prompt-SkillArmory (prompts + skills manager) into a DeepSeek Harness web profile",
5
5
  "type": "module",
6
6
  "bin": {