@toddzheng024/dscode 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Todd Zheng
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/cli.mjs ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import { run } from './manager.mjs';
4
+ const release = JSON.parse(readFileSync(new URL('./release.json', import.meta.url), 'utf8'));
5
+ const args = process.argv.slice(2);
6
+ if (args[0] === '--version') console.log(release.version);
7
+ else if (args[0] === '--help' || args[0] === '-h') console.log(`DSCODE ${release.version}\n\n dscode Start; first launch installs the Hub preset\n dscode install [version] Install an exact preset release\n dscode update [version] Upgrade (default: launcher release)\n dscode history List retained preset revisions\n dscode rollback [revision] Restore a retained revision\n dscode doctor Check the installed Hub profile\n dscode --continue Continue the previous session\n dscode --resume SESSION_ID Resume a session\n dscode --cwd DIRECTORY Work in a directory\n\nState: $DSCODE_HOME or ~/.local/share/dscode-hub\nModel credentials: configure /model in the TUI or set DEEPSEEK_API_KEY.`);
8
+ else run(args, release).catch(error => { console.error(error.message); process.exitCode = 1; });
package/manager.mjs ADDED
@@ -0,0 +1,84 @@
1
+ import { mkdirSync, readFileSync, existsSync, openSync, closeSync, unlinkSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { homedir } from 'node:os';
5
+ import { createRequire } from 'node:module';
6
+ import { spawn } from 'node:child_process';
7
+ const require = createRequire(import.meta.url);
8
+ export function stateHome(env = process.env) {
9
+ return resolve(env.DSCODE_HOME || join(homedir(), '.local/share/dscode-hub'));
10
+ }
11
+ export function acquireLock(home) {
12
+ mkdirSync(home, { recursive: true });
13
+ const path = join(home, '.launcher.lock');
14
+ for (let attempt = 0; attempt < 2; attempt++) {
15
+ try { const fd = openSync(path, 'wx', 0o600); writeFileSync(fd, String(process.pid)); closeSync(fd); return () => unlinkSync(path); }
16
+ catch (error) {
17
+ if (error.code !== 'EEXIST') throw error;
18
+ const pid = Number(readFileSync(path, 'utf8'));
19
+ if (!Number.isSafeInteger(pid) || pid <= 0) throw Error('Invalid DSCODE lock; inspect ' + path);
20
+ try { process.kill(pid, 0); }
21
+ catch (error) { if (error.code === 'ESRCH') { unlinkSync(path); continue; } throw error; }
22
+ throw Error(`DSCODE is already running (pid ${pid}). Exit it before launching or changing versions.`);
23
+ }
24
+ }
25
+ throw Error('Could not acquire DSCODE lock');
26
+ }
27
+ export function commandPlan(args, release, installed) {
28
+ const [command, ...rest] = args;
29
+ const flags = ['--profile', 'dscode'];
30
+ if (command === 'install' || command === 'update') {
31
+ if (rest.length > 1 || rest[0] && !/^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(rest[0])) throw Error('Usage: dscode install|update [exact-version]');
32
+ return { hub: ['profile', installed ? 'upgrade' : 'apply', release.slug, '--version', rest[0] ?? release.version, ...flags] };
33
+ }
34
+ if (command === 'rollback') {
35
+ if (rest.length > 1 || rest[0]?.startsWith('-')) throw Error('Usage: dscode rollback [revision]');
36
+ return { hub: ['profile', 'rollback', ...rest, ...flags] };
37
+ }
38
+ if (command === 'history' || command === 'doctor') {
39
+ if (rest.length) throw Error('Usage: dscode ' + command);
40
+ return { hub: ['profile', command, ...flags] };
41
+ }
42
+ return { launch: args, install: !installed };
43
+ }
44
+ export async function run(args, release) {
45
+ const home = stateHome();
46
+ const envFile = join(home, '.env');
47
+ if (existsSync(envFile)) process.loadEnvFile(envFile);
48
+ const hub = join(dirname(require.resolve('@dsh-plugin-hub/cli')), 'bin.js');
49
+ const pnpm = join(dirname(fileURLToPath(import.meta.url)), 'tools');
50
+ const env = { ...process.env, DSH_HOME: home, DSH_AGENTS_HOME: join(home, 'agents'), PATH: process.env.PATH };
51
+ const exec = (entry, argv, cwd = process.cwd()) => new Promise((resolvePromise, reject) => {
52
+ const child = spawn(process.execPath, [entry, ...argv], { env: entry === hub ? { ...env, PATH: pnpm + ':' + env.PATH, npm_config_ignore_scripts: 'true', DSH_HUB_MACHINE: '1' } : env, cwd, stdio: 'inherit' });
53
+ const forward = signal => child.kill(signal);
54
+ const handlers = ['SIGTERM','SIGHUP'].map(signal => { const handler = () => forward(signal); process.on(signal,handler); return [signal,handler]; });
55
+ const cleanup = () => handlers.forEach(([signal,handler]) => process.off(signal,handler));
56
+ child.once('error', error => { cleanup(); reject(error); });
57
+ child.once('exit', (code, signal) => { cleanup(); code === 0 ? resolvePromise() : reject(Error(`DSCODE process exited: ${signal ?? code}`)); });
58
+ });
59
+ const releaseLock = acquireLock(home);
60
+ try {
61
+ const profile = join(home, 'profiles/dscode');
62
+ const state = join(home, '.hub/installations/dscode/current.json');
63
+ const installed = existsSync(state) && existsSync(join(profile, 'package.json'));
64
+ if (!installed && existsSync(profile)) throw Error('Existing unmanaged/incomplete dscode profile; inspect ' + profile);
65
+ const plan = commandPlan(args, release, installed);
66
+ if (plan.hub) return await exec(hub, plan.hub);
67
+ if (plan.install) {
68
+ console.log(`Installing DSCODE ${release.version} from dshpluginhub.ai…`);
69
+ await exec(hub, ['profile','apply',release.slug,'--version',release.version,'--profile','dscode']);
70
+ }
71
+ const metadata = JSON.parse(readFileSync(join(profile,'node_modules',release.bundle,'package.json'),'utf8'));
72
+ if (metadata.name !== release.bundle) throw Error('Unexpected DSCODE bundle');
73
+ const dshPackage = join(profile, 'node_modules/@deepseek-ai/dsh/package.json');
74
+ const dsh = join(dirname(dshPackage),'lib/bin.js');
75
+ const overlays = ['mcp.local.yml','harness.local.yml'].flatMap(file => {
76
+ const path=join(home,'config',file); return existsSync(path) ? ['--patch',path] : [];
77
+ });
78
+ const launch = [...plan.launch];
79
+ let cwd = process.cwd();
80
+ const index = launch.indexOf('--cwd');
81
+ if(index >= 0) { if(!launch[index+1]) throw Error('--cwd requires a directory'); cwd=resolve(launch[index+1]); launch.splice(index,2); }
82
+ await exec(dsh, ['--profile','dscode',...overlays,...launch], cwd);
83
+ } finally { releaseLock(); }
84
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "version": "0.1.0",
3
+ "type": "module",
4
+ "license": "MIT",
5
+ "author": "Todd Zheng",
6
+ "engines": {
7
+ "node": "^22.19.0 || >=24.0.0"
8
+ },
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/qiz029/dscode.git"
15
+ },
16
+ "name": "@toddzheng024/dscode",
17
+ "description": "One-command launcher for the DSCODE Hub coding harness preset.",
18
+ "bin": {
19
+ "dscode": "./cli.mjs"
20
+ },
21
+ "files": [
22
+ "cli.mjs",
23
+ "manager.mjs",
24
+ "release.json",
25
+ "tools"
26
+ ],
27
+ "dependencies": {
28
+ "@dsh-plugin-hub/cli": "0.2.0",
29
+ "pnpm": "10.15.1"
30
+ }
31
+ }
package/release.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "slug": "dscode",
3
+ "version": "0.1.0",
4
+ "runtime": "0.1.5-rc.1",
5
+ "bundle": "@toddzheng024/dscode-bundle"
6
+ }
package/tools/npx ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ // Hub invokes npx for its exact DSH runner. npm exec rewrites PATH; include
3
+ // pnpm explicitly in that same execution environment so global pnpm cannot win.
4
+ import { spawn } from 'node:child_process';
5
+ const [yes, spec, ...args] = process.argv.slice(2);
6
+ if (yes !== '-y' || !/^@deepseek-ai\/dsh@\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(spec ?? '')) {
7
+ console.error('DSCODE installer received an unsupported runtime command.');process.exit(1);
8
+ }
9
+ const child = spawn('npm', ['exec','--yes','--ignore-scripts',`--package=${spec}`,'--package=pnpm@10.15.1','--','dsh',...args], {stdio:'inherit'});
10
+ for (const signal of ['SIGTERM','SIGHUP']) process.on(signal,()=>child.kill(signal));
11
+ child.on('error',error=>{console.error(error.message);process.exitCode=1;});
12
+ child.on('exit',(code)=>{process.exitCode=code??1;});
package/tools/pnpm ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { dirname, join } from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ const require = createRequire(import.meta.url);
6
+ await import(pathToFileURL(join(dirname(require.resolve('pnpm')), 'bin/pnpm.cjs')).href);