dsh-edge 0.1.0 → 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.
Files changed (64) hide show
  1. package/LICENSE +1 -1
  2. package/README.i18n.yaml +2 -2
  3. package/README.md +6 -4
  4. package/README.zh.md +6 -4
  5. package/THIRD_PARTY_NOTICES.md +42 -14
  6. package/dist/index.html +1 -1
  7. package/dist/plugins/@deepseek-ai/dsh-client-locale/client.js +7 -7
  8. package/dist/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js +61 -61
  9. package/dist/plugins/@deepseek-ai/dsh-client-ui-commands/client.js +14 -14
  10. package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +287 -287
  11. package/dist/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js +10 -10
  12. package/dist/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js +11 -11
  13. package/dist/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js +15 -15
  14. package/dist/plugins/@deepseek-ai/dsh-client-ui-layout/client.js +8 -8
  15. package/dist/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js +27 -27
  16. package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +8 -8
  17. package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js +31 -31
  18. package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +23 -23
  19. package/dist/plugins/@deepseek-ai/dsh-client-ui-skill/client.js +19 -19
  20. package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +29 -29
  21. package/dist/plugins/@deepseek-ai/dsh-client-ui-theme/client.js +7 -7
  22. package/dist/plugins/@deepseek-ai/dsh-client-ui-tool/client.js +64 -64
  23. package/dist/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js +183 -183
  24. package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +44 -44
  25. package/dist/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js +24 -24
  26. package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +79 -79
  27. package/dist/plugins/{@deepseek-ai/dsh-client-ui-edge → dsh-edge-client-ui}/client.js +12 -12
  28. package/package.json +26 -23
  29. package/scripts/assemble-web.mjs +1 -1
  30. package/scripts/bundle.mjs +41 -8
  31. package/scripts/cli.d.mts +1 -0
  32. package/scripts/cli.mjs +37 -6
  33. package/scripts/install.d.mts +6 -6
  34. package/scripts/install.mjs +36 -19
  35. package/scripts/legal-files.mjs +65 -7
  36. package/scripts/smoke-installed.mjs +47 -0
  37. package/scripts/verify-packed.d.mts +24 -0
  38. package/scripts/verify-packed.mjs +85 -23
  39. package/scripts/wrangler-config.d.mts +19 -2
  40. package/scripts/wrangler-config.mjs +68 -27
  41. package/worker/direct/index.js +2347 -0
  42. package/worker/isolated/index.js +44491 -0
  43. package/src/agent.ts +0 -119
  44. package/src/auth.ts +0 -352
  45. package/src/deepseek.ts +0 -231
  46. package/src/deployment.ts +0 -147
  47. package/src/direct-shell-core-empty.ts +0 -10
  48. package/src/direct-shell-protocol.ts +0 -5
  49. package/src/direct-shell.ts +0 -341
  50. package/src/do-session-persistence.ts +0 -1064
  51. package/src/edge-api.ts +0 -796
  52. package/src/edge-credentials.ts +0 -56
  53. package/src/edge-remotes.ts +0 -41
  54. package/src/edge-workspace-store.ts +0 -339
  55. package/src/http.ts +0 -212
  56. package/src/index.ts +0 -196
  57. package/src/instance.ts +0 -1007
  58. package/src/isolated-direct-shell-unavailable.ts +0 -11
  59. package/src/protocol.ts +0 -39
  60. package/src/release.ts +0 -9
  61. package/src/session-store.ts +0 -1110
  62. package/src/sse.ts +0 -86
  63. package/src/web-search.ts +0 -38
  64. package/src/workspace.ts +0 -270
@@ -0,0 +1,24 @@
1
+ export interface NpmInvocationOptions {
2
+ platform?: NodeJS.Platform
3
+ nodeExecutable?: string
4
+ environment?: NodeJS.ProcessEnv
5
+ pathExists?: (path: string) => boolean
6
+ }
7
+
8
+ export interface NpmInvocation {
9
+ command: string
10
+ args: string[]
11
+ }
12
+
13
+ /**
14
+ * Resolve npm to a directly executable command on the current platform.
15
+ * @param options Resolution inputs used by the release verifier.
16
+ * @returns The executable and leading arguments for npm.
17
+ */
18
+ export function resolveNpmInvocation(options?: NpmInvocationOptions): NpmInvocation
19
+
20
+ /**
21
+ * Install and exercise one packed dsh-edge artifact outside the workspace.
22
+ * @param input Tarball path from the command line.
23
+ */
24
+ export function verifyPacked(input?: string): void
@@ -1,32 +1,94 @@
1
1
  import { execFileSync } from 'node:child_process'
2
- import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs'
2
+ import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync } from 'node:fs'
3
3
  import { tmpdir } from 'node:os'
4
- import { isAbsolute, join, resolve } from 'node:path'
4
+ import { isAbsolute, join, resolve, win32 } from 'node:path'
5
+ import { fileURLToPath } from 'node:url'
5
6
 
6
- const input = process.argv[2]
7
- if (input === undefined) throw new Error('Usage: node scripts/verify-packed.mjs <tarball>')
8
- const tarball = isAbsolute(input) ? input : resolve(process.cwd(), input)
9
- const directory = mkdtempSync(join(tmpdir(), 'dsh-edge-packed-'))
7
+ /**
8
+ * Resolve npm without asking Windows to execute its `.cmd` shim.
9
+ * @param {{ platform?: NodeJS.Platform, nodeExecutable?: string, environment?: NodeJS.ProcessEnv, pathExists?: (path: string) => boolean }} [options] Resolution inputs.
10
+ * @returns {{ command: string, args: string[] }} Executable and leading arguments for npm.
11
+ */
12
+ export function resolveNpmInvocation(options = {}) {
13
+ const platform = options.platform ?? process.platform
14
+ if (platform !== 'win32') return { command: 'npm', args: [] }
10
15
 
11
- function run(command, args) {
12
- execFileSync(command, args, { cwd: directory, stdio: 'inherit' })
16
+ const environment = options.environment ?? process.env
17
+ const path = Object.entries(environment)
18
+ .find(([name]) => name.toUpperCase() === 'PATH')?.[1]
19
+ if (path === undefined || path === '') {
20
+ throw new Error('Cannot run npm on Windows because PATH is unavailable')
21
+ }
22
+
23
+ const pathExists = options.pathExists ?? existsSync
24
+ for (const rawDirectory of path.split(win32.delimiter)) {
25
+ const directory = rawDirectory.startsWith('"') && rawDirectory.endsWith('"')
26
+ ? rawDirectory.slice(1, -1)
27
+ : rawDirectory
28
+ if (directory === '') continue
29
+ const shim = win32.join(directory, 'npm.cmd')
30
+ const cli = win32.join(directory, 'node_modules', 'npm', 'bin', 'npm-cli.js')
31
+ if (pathExists(shim) && pathExists(cli)) {
32
+ return { command: options.nodeExecutable ?? process.execPath, args: [cli] }
33
+ }
34
+ }
35
+
36
+ throw new Error('Cannot run npm on Windows because npm-cli.js is not adjacent to an npm.cmd entry on PATH')
13
37
  }
14
38
 
15
- try {
16
- run('npm', ['install', '--ignore-scripts', '--no-audit', '--no-fund', tarball])
17
- const packageDirectory = join(directory, 'node_modules', 'dsh-edge')
18
- const license = join(packageDirectory, 'LICENSE')
19
- const notices = join(packageDirectory, 'THIRD_PARTY_NOTICES.md')
20
- if (!existsSync(license) || !readFileSync(license, 'utf8').startsWith('MIT License')) {
21
- throw new Error('packed dsh-edge is missing its MIT license')
39
+ /**
40
+ * Install and exercise one packed dsh-edge artifact outside the workspace.
41
+ * @param {string | undefined} input Tarball path from the command line.
42
+ */
43
+ export function verifyPacked(input) {
44
+ if (input === undefined) throw new Error('Usage: node scripts/verify-packed.mjs <tarball>')
45
+ const tarball = isAbsolute(input) ? input : resolve(process.cwd(), input)
46
+ const directory = mkdtempSync(join(tmpdir(), 'dsh-edge-packed-'))
47
+
48
+ function run(command, args) {
49
+ execFileSync(command, args, { cwd: directory, stdio: 'inherit' })
22
50
  }
23
- if (!existsSync(notices) || !readFileSync(notices, 'utf8').includes('# Third-Party Notices')) {
24
- throw new Error('packed dsh-edge is missing third-party notices')
51
+
52
+ try {
53
+ const npm = resolveNpmInvocation()
54
+ run(npm.command, [...npm.args, 'install', '--ignore-scripts', '--no-audit', '--no-fund', tarball])
55
+ const packageDirectory = join(directory, 'node_modules', 'dsh-edge')
56
+ const manifest = JSON.parse(readFileSync(join(packageDirectory, 'package.json'), 'utf8'))
57
+ const dependencies = Object.keys(manifest.dependencies ?? {})
58
+ const sourceRuntimeDependency = dependencies.find(name => (
59
+ name.startsWith('@deepseek-ai/')
60
+ || name === '@cloudflare/computer'
61
+ || name === 'just-bash'
62
+ ))
63
+ if (sourceRuntimeDependency !== undefined) {
64
+ throw new Error(`packed dsh-edge still installs bundled source dependency ${sourceRuntimeDependency}`)
65
+ }
66
+ const license = join(packageDirectory, 'LICENSE')
67
+ const notices = join(packageDirectory, 'THIRD_PARTY_NOTICES.md')
68
+ const licenseText = existsSync(license) ? readFileSync(license, 'utf8') : ''
69
+ if (!licenseText.startsWith('MIT License') || !licenseText.includes('Copyright (c) 2026 pawaca')) {
70
+ throw new Error('packed dsh-edge is missing its MIT license')
71
+ }
72
+ if (licenseText.includes('Copyright (c) 2026 DeepSeek')) {
73
+ throw new Error('packed dsh-edge incorrectly assigns its copyright to DeepSeek')
74
+ }
75
+ const noticesText = existsSync(notices) ? readFileSync(notices, 'utf8') : ''
76
+ if (
77
+ !noticesText.includes('# Third-Party Notices')
78
+ || !noticesText.includes('not affiliated with or endorsed by DeepSeek')
79
+ || !noticesText.includes('Copyright (c) 2026 DeepSeek')
80
+ ) {
81
+ throw new Error('packed dsh-edge is missing third-party notices')
82
+ }
83
+ run(process.execPath, [join(packageDirectory, 'scripts', 'cli.mjs'), '--version'])
84
+ run(process.execPath, [join(packageDirectory, 'scripts', 'cli.mjs'), '--help'])
85
+ run(process.execPath, [join(packageDirectory, 'scripts', 'smoke-installed.mjs')])
86
+ } finally {
87
+ rmSync(directory, { recursive: true, force: true })
25
88
  }
26
- run(process.execPath, [join(packageDirectory, 'scripts', 'cli.mjs'), '--version'])
27
- run(process.execPath, [join(packageDirectory, 'scripts', 'cli.mjs'), '--help'])
28
- run(process.execPath, [join(packageDirectory, 'scripts', 'bundle.mjs'), 'direct'])
29
- run(process.execPath, [join(packageDirectory, 'scripts', 'bundle.mjs'), 'isolated'])
30
- } finally {
31
- rmSync(directory, { recursive: true, force: true })
89
+ }
90
+
91
+ if (process.argv[1] !== undefined
92
+ && realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url))) {
93
+ verifyPacked(process.argv[2])
32
94
  }
@@ -5,14 +5,31 @@ export interface WranglerConfigOptions {
5
5
  sourceConfigPath?: string
6
6
  }
7
7
 
8
- export function renderModeWranglerConfig(
8
+ export function renderSourceModeWranglerConfig(
9
9
  mode: RuntimeMode,
10
10
  source: string,
11
11
  options?: WranglerConfigOptions,
12
12
  ): string
13
13
 
14
- export function writeModeWranglerConfig(
14
+ export function renderPrebuiltModeWranglerConfig(
15
+ mode: RuntimeMode,
16
+ source: string,
17
+ options?: WranglerConfigOptions,
18
+ ): string
19
+
20
+ export function writeSourceModeWranglerConfig(
15
21
  mode: RuntimeMode,
16
22
  destination: string,
17
23
  options?: WranglerConfigOptions,
18
24
  ): Promise<void>
25
+
26
+ export function writePrebuiltModeWranglerConfig(
27
+ mode: RuntimeMode,
28
+ destination: string,
29
+ options?: WranglerConfigOptions,
30
+ ): Promise<void>
31
+
32
+ export function workerArtifactPath(
33
+ mode: RuntimeMode,
34
+ options?: Pick<WranglerConfigOptions, 'appDirectory'>,
35
+ ): string
@@ -10,11 +10,76 @@ const DIRECT_SHELL_CORE_REPLACEMENT = 'src/direct-shell-core-empty.ts'
10
10
  const ISOLATED_DIRECT_SHELL = './direct-shell.ts'
11
11
  const ISOLATED_DIRECT_SHELL_REPLACEMENT = 'src/isolated-direct-shell-unavailable.ts'
12
12
  const RESERVED_ALIASES = new Set([DIRECT_SHELL_CORE, ISOLATED_DIRECT_SHELL])
13
+ const WORKER_ARTIFACTS = Object.freeze({
14
+ direct: 'worker/direct/index.js',
15
+ isolated: 'worker/isolated/index.js',
16
+ })
13
17
 
14
- /** Render one absolute-path Wrangler configuration from the repository source. */
15
- export function renderModeWranglerConfig(mode, source, options = {}) {
18
+ /** Render one mode-specific build configuration from the repository source. */
19
+ export function renderSourceModeWranglerConfig(mode, source, options = {}) {
16
20
  requireRuntimeMode(mode)
17
21
  const root = options.appDirectory ?? appDirectory
22
+ const parsed = parseSourceConfig(source)
23
+ const config = structuredClone(parsed)
24
+ delete config.$schema
25
+ config.main = resolve(root, parsed.main)
26
+ config.assets.directory = resolve(root, parsed.assets.directory)
27
+ config.minify = true
28
+ if (mode === 'direct') {
29
+ config.alias = {
30
+ ...config.alias,
31
+ [DIRECT_SHELL_CORE]: resolve(root, DIRECT_SHELL_CORE_REPLACEMENT),
32
+ }
33
+ } else {
34
+ config.alias = {
35
+ ...config.alias,
36
+ [ISOLATED_DIRECT_SHELL]: resolve(root, ISOLATED_DIRECT_SHELL_REPLACEMENT),
37
+ }
38
+ }
39
+ return `${JSON.stringify(config, undefined, 2)}\n`
40
+ }
41
+
42
+ /** Render an upload configuration that deploys the released Worker without rebuilding it. */
43
+ export function renderPrebuiltModeWranglerConfig(mode, source, options = {}) {
44
+ requireRuntimeMode(mode)
45
+ const root = options.appDirectory ?? appDirectory
46
+ const parsed = parseSourceConfig(source)
47
+ const config = structuredClone(parsed)
48
+ delete config.$schema
49
+ delete config.alias
50
+ delete config.minify
51
+ config.main = resolve(root, WORKER_ARTIFACTS[mode])
52
+ config.assets.directory = resolve(root, parsed.assets.directory)
53
+ config.no_bundle = true
54
+ config.find_additional_modules = false
55
+ return `${JSON.stringify(config, undefined, 2)}\n`
56
+ }
57
+
58
+ /** Write the source configuration used to build one released Worker artifact. */
59
+ export async function writeSourceModeWranglerConfig(mode, destination, options = {}) {
60
+ const source = await readFile(options.sourceConfigPath ?? sourceConfigPath, 'utf8')
61
+ const rendered = renderSourceModeWranglerConfig(mode, source, options)
62
+ await writePrivateConfig(destination, rendered)
63
+ }
64
+
65
+ /** Write the private no-bundle configuration used by one installation attempt. */
66
+ export async function writePrebuiltModeWranglerConfig(mode, destination, options = {}) {
67
+ const source = await readFile(options.sourceConfigPath ?? sourceConfigPath, 'utf8')
68
+ const rendered = renderPrebuiltModeWranglerConfig(mode, source, options)
69
+ await writePrivateConfig(destination, rendered)
70
+ }
71
+
72
+ /** Return the released entrypoint for a runtime mode. */
73
+ export function workerArtifactPath(mode, options = {}) {
74
+ requireRuntimeMode(mode)
75
+ return resolve(options.appDirectory ?? appDirectory, WORKER_ARTIFACTS[mode])
76
+ }
77
+
78
+ async function writePrivateConfig(destination, rendered) {
79
+ await writeFile(destination, rendered, { encoding: 'utf8', mode: 0o600, flag: 'wx' })
80
+ }
81
+
82
+ function parseSourceConfig(source) {
18
83
  const errors = []
19
84
  const parsed = parse(source, errors, {
20
85
  allowEmptyContent: false,
@@ -42,31 +107,7 @@ export function renderModeWranglerConfig(mode, source, options = {}) {
42
107
  if (reservedAlias !== undefined) {
43
108
  throw new Error(`wrangler.jsonc reserves the ${reservedAlias} alias for mode builds.`)
44
109
  }
45
-
46
- const config = structuredClone(parsed)
47
- delete config.$schema
48
- config.main = resolve(root, parsed.main)
49
- config.assets.directory = resolve(root, parsed.assets.directory)
50
- config.minify = true
51
- if (mode === 'direct') {
52
- config.alias = {
53
- ...config.alias,
54
- [DIRECT_SHELL_CORE]: resolve(root, DIRECT_SHELL_CORE_REPLACEMENT),
55
- }
56
- } else {
57
- config.alias = {
58
- ...config.alias,
59
- [ISOLATED_DIRECT_SHELL]: resolve(root, ISOLATED_DIRECT_SHELL_REPLACEMENT),
60
- }
61
- }
62
- return `${JSON.stringify(config, undefined, 2)}\n`
63
- }
64
-
65
- /** Write the private Wrangler configuration used by one installation attempt. */
66
- export async function writeModeWranglerConfig(mode, destination, options = {}) {
67
- const source = await readFile(options.sourceConfigPath ?? sourceConfigPath, 'utf8')
68
- const rendered = renderModeWranglerConfig(mode, source, options)
69
- await writeFile(destination, rendered, { encoding: 'utf8', mode: 0o600, flag: 'wx' })
110
+ return parsed
70
111
  }
71
112
 
72
113
  function requireRuntimeMode(mode) {