@dsh-plugin-hub/dsh-plugin 0.1.0

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 ADDED
@@ -0,0 +1,19 @@
1
+ # DSH Plugin Hub tools
2
+
3
+ Install into a Profile:
4
+
5
+ ```sh
6
+ dsh plugin --profile web add @dsh-plugin-hub/dsh-plugin
7
+ ```
8
+
9
+ The bundle exposes five DSH tools backed by the local `dsh-hub` CLI:
10
+
11
+ - `dsh_hub_profile_plan` creates a read-only, expiring install plan.
12
+ - `dsh_hub_profile_share_plan` captures an exact, read-only publication plan.
13
+ - `dsh_hub_profile_rollback_plan` selects a complete recoverable revision.
14
+ - `dsh_hub_operation_apply` applies that plan after explicit confirmation.
15
+ - `dsh_hub_profile_history` lists recoverable local revisions.
16
+
17
+ Every machine-triggered mutation uses an expiring, single-use, preconditioned
18
+ plan and the same staging, validation, atomic switch and rollback implementation
19
+ as direct CLI use.
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: dsh-plugin-hub-tools
3
+ name: '@dsh-plugin-hub/dsh-plugin'
package/index.js ADDED
@@ -0,0 +1,115 @@
1
+ import { spawn } from 'node:child_process'
2
+ import { fileURLToPath } from 'node:url'
3
+ import { defineTool } from '@deepseek-ai/dsh-tools'
4
+
5
+ export const name = 'dsh-plugin-hub-tools'
6
+ export const inject = ['tools']
7
+
8
+ const cli = fileURLToPath(import.meta.resolve('@dsh-plugin-hub/cli/bin'))
9
+
10
+ function run(args, signal) {
11
+ return new Promise((resolve, reject) => {
12
+ const child = spawn(process.execPath, [cli, ...args], {
13
+ env: process.env,
14
+ stdio: ['ignore', 'pipe', 'pipe'],
15
+ signal,
16
+ })
17
+ let stdout = ''
18
+ let stderr = ''
19
+ child.stdout.on('data', (chunk) => { if (stdout.length < 1_000_000) stdout += chunk })
20
+ child.stderr.on('data', (chunk) => { if (stderr.length < 100_000) stderr += chunk })
21
+ child.once('error', reject)
22
+ child.once('exit', (code) => {
23
+ if (code !== 0) reject(new Error(stderr.trim() || `dsh-hub exited ${code}`))
24
+ else resolve(stdout.trim().split('\n').filter(Boolean).map((line) => JSON.parse(line)))
25
+ })
26
+ })
27
+ }
28
+
29
+ const output = {
30
+ schema: { type: 'object', additionalProperties: true },
31
+ render: (_args, value) => [{ type: 'text', text: JSON.stringify(value, null, 2) }],
32
+ }
33
+
34
+ export function apply(ctx) {
35
+ ctx.tools.register(defineTool({
36
+ name: 'dsh_hub_profile_plan',
37
+ description: 'Create a non-mutating, exact and preconditioned plan to install or upgrade a public DSH Hub Profile. Present the plan to the user before applying it.',
38
+ parameters: {
39
+ slug: { type: 'string', required: true, description: 'Hub Profile slug.' },
40
+ profile: { type: 'string', description: 'Local target Profile name (default web).' },
41
+ version: { type: 'string', description: 'Profile Release version (default latest).' },
42
+ },
43
+ output,
44
+ async execute(args, exec) {
45
+ const values = ['profile', 'apply', args.slug, '--profile', args.profile ?? 'web', '--version', args.version ?? 'latest', '--plan', '--json']
46
+ const events = await run(values, exec.signal)
47
+ return events[0] ?? {}
48
+ },
49
+ }))
50
+
51
+ ctx.tools.register(defineTool({
52
+ name: 'dsh_hub_operation_apply',
53
+ description: 'Apply a previously reviewed DSH Hub install, share, or rollback plan. Set confirmed=true only after the user explicitly confirms that exact plan.',
54
+ parameters: {
55
+ planId: { type: 'string', required: true, description: 'Plan UUID returned by any DSH Hub planning tool.' },
56
+ confirmed: { type: 'boolean', required: true, description: 'Must reflect explicit user confirmation of this plan.' },
57
+ },
58
+ output,
59
+ async execute(args, exec) {
60
+ if (args.confirmed !== true) throw new Error('Explicit user confirmation is required')
61
+ const events = await run(['operation', 'apply', args.planId, '--json'], exec.signal)
62
+ return { planId: args.planId, events }
63
+ },
64
+ }))
65
+
66
+ ctx.tools.register(defineTool({
67
+ name: 'dsh_hub_profile_share_plan',
68
+ description: 'Create a non-mutating plan to publish the exact current local Profile as an immutable Hub Release. Review the captured layers and local input contract before applying it.',
69
+ parameters: {
70
+ slug: { type: 'string', required: true, description: 'New or owned Hub Profile slug.' },
71
+ version: { type: 'string', required: true, description: 'Exact SemVer for the immutable Release.' },
72
+ profile: { type: 'string', description: 'Local source Profile name (default web).' },
73
+ displayName: { type: 'string', description: 'Public Profile name.' },
74
+ description: { type: 'string', description: 'Public Profile description.' },
75
+ runtimeVersion: { type: 'string', description: 'Exact DSH runtime; auto-detected when omitted.' },
76
+ },
77
+ output,
78
+ async execute(args, exec) {
79
+ const values = ['profile', 'share', args.slug, '--profile', args.profile ?? 'web', '--version', args.version, '--plan', '--json']
80
+ if (args.displayName) values.push('--display-name', args.displayName)
81
+ if (args.description) values.push('--description', args.description)
82
+ if (args.runtimeVersion) values.push('--runtime-version', args.runtimeVersion)
83
+ const events = await run(values, exec.signal)
84
+ return events[0] ?? {}
85
+ },
86
+ }))
87
+
88
+ ctx.tools.register(defineTool({
89
+ name: 'dsh_hub_profile_rollback_plan',
90
+ description: 'Create a non-mutating plan to restore one complete local Profile revision. Review the exact target revision before applying it.',
91
+ parameters: {
92
+ profile: { type: 'string', description: 'Local Profile name (default web).' },
93
+ revision: { type: 'string', description: 'Revision ID; defaults to the newest recoverable revision.' },
94
+ },
95
+ output,
96
+ async execute(args, exec) {
97
+ const values = ['profile', 'rollback']
98
+ if (args.revision) values.push(args.revision)
99
+ values.push('--profile', args.profile ?? 'web', '--plan', '--json')
100
+ const events = await run(values, exec.signal)
101
+ return events[0] ?? {}
102
+ },
103
+ }))
104
+
105
+ ctx.tools.register(defineTool({
106
+ name: 'dsh_hub_profile_history',
107
+ description: 'List locally recoverable revisions for a DSH Profile. This is read-only.',
108
+ parameters: { profile: { type: 'string', description: 'Local Profile name (default web).' } },
109
+ output,
110
+ async execute(args, exec) {
111
+ const events = await run(['profile', 'history', '--profile', args.profile ?? 'web', '--json'], exec.signal)
112
+ return { revisions: events[0] ?? [] }
113
+ },
114
+ }))
115
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@dsh-plugin-hub/dsh-plugin",
3
+ "version": "0.1.0",
4
+ "description": "DSH tools for planning and applying reproducible Plugin Hub Profiles through the local dsh-hub CLI",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "files": [
8
+ "index.js",
9
+ "cordis.patch.yml",
10
+ "README.md"
11
+ ],
12
+ "dependencies": {
13
+ "@dsh-plugin-hub/cli": "0.1.0"
14
+ },
15
+ "peerDependencies": {
16
+ "@deepseek-ai/cordis": "^4.0.1",
17
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.1"
18
+ },
19
+ "engines": {
20
+ "node": ">=22.13.0"
21
+ },
22
+ "dsh": {
23
+ "bundle": {
24
+ "patch": "./cordis.patch.yml"
25
+ }
26
+ },
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "provenance": true
30
+ },
31
+ "license": "MIT"
32
+ }