@gengjiawen/os-init 1.4.0 → 1.5.1
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/.github/workflows/release-please.yml +1 -2
- package/CHANGELOG.md +15 -0
- package/README.md +50 -9
- package/bin/bin.js +24 -0
- package/build/dev-setup.d.ts +3 -0
- package/build/dev-setup.js +92 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +3 -0
- package/dev-setup/Dockerfile.txt +19 -0
- package/dev-setup/docker-compose.yml +15 -0
- package/dev-setup/sshd_config.txt +31 -0
- package/libs/dev-setup.ts +118 -0
- package/libs/index.ts +3 -0
- package/package.json +7 -1
|
@@ -6,6 +6,7 @@ on:
|
|
|
6
6
|
workflow_dispatch:
|
|
7
7
|
|
|
8
8
|
permissions:
|
|
9
|
+
id-token: write # Required for OIDC
|
|
9
10
|
contents: write
|
|
10
11
|
issues: write
|
|
11
12
|
pull-requests: write
|
|
@@ -44,7 +45,5 @@ jobs:
|
|
|
44
45
|
if: ${{ steps.release.outputs.release_created }}
|
|
45
46
|
|
|
46
47
|
- name: Publish
|
|
47
|
-
env:
|
|
48
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
49
48
|
run: npm publish
|
|
50
49
|
if: ${{ steps.release.outputs.release_created }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.5.1](https://github.com/gengjiawen/os-init/compare/v1.5.0...v1.5.1) (2025-10-25)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* add 'ip' dependency to package.json ([195b0d0](https://github.com/gengjiawen/os-init/commit/195b0d06b158962d57060336629e0666b726b9d9))
|
|
9
|
+
* add repository information to package.json ([441f752](https://github.com/gengjiawen/os-init/commit/441f7525a44af7a96b0f2916e2228439e89bb1d7))
|
|
10
|
+
|
|
11
|
+
## [1.5.0](https://github.com/gengjiawen/os-init/compare/v1.4.0...v1.5.0) (2025-10-25)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* add dev environment setup command and update dependencies ([3bd05ae](https://github.com/gengjiawen/os-init/commit/3bd05aec3ba20c55e0b2323fb0da390eb4de539d))
|
|
17
|
+
|
|
3
18
|
## [1.4.0](https://github.com/gengjiawen/os-init/compare/v1.3.2...v1.4.0) (2025-10-25)
|
|
4
19
|
|
|
5
20
|
|
package/README.md
CHANGED
|
@@ -1,16 +1,57 @@
|
|
|
1
1
|
## os-init CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A CLI tool to quickly configure AI development tools and environments.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Configure Codex CLI with your API key (writes `~/.codex/config.toml` and `~/.codex/auth.json`).
|
|
7
|
-
- Configure Raycast AI with your API key (writes `~/.config/raycast/ai/providers.yaml`).
|
|
8
|
-
- Install global tools: `@anthropic-ai/claude-code`, `@musistudio/claude-code-router`, `@openai/codex`.
|
|
5
|
+
## Usage
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
### Configure Claude Code
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
```bash
|
|
10
|
+
pnpx @gengjiawen/os-init set-cc <API_KEY>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Configures Claude Code Router with your API key. This command will:
|
|
14
|
+
- Write `~/.claude-code-router/config.json`
|
|
15
|
+
- Write `~/.claude/settings.json`
|
|
16
|
+
- Install global tools: `@anthropic-ai/claude-code`, `@musistudio/claude-code-router`
|
|
17
|
+
|
|
18
|
+
### Configure Codex CLI
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpx @gengjiawen/os-init set-codex <API_KEY>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Configures Codex CLI with your API key. This command will:
|
|
25
|
+
- Write `~/.codex/config.toml`
|
|
26
|
+
- Write `~/.codex/auth.json`
|
|
27
|
+
- Install global tool: `@openai/codex`
|
|
28
|
+
|
|
29
|
+
### Configure Raycast AI
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pnpx @gengjiawen/os-init set-raycast-ai <API_KEY>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Configures Raycast AI providers with your API key. This command will:
|
|
36
|
+
- Write `~/.config/raycast/ai/providers.yaml`
|
|
37
|
+
|
|
38
|
+
### Setup Dev Environment
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pnpx @gengjiawen/os-init set-dev <SSH_PUBLIC_KEY>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Sets up a Docker-based development environment with SSH access. This command will:
|
|
45
|
+
- Copy `dev-setup` directory to your current directory (or specify with `-t, --target <dir>`)
|
|
46
|
+
- Configure SSH public key in Dockerfile
|
|
47
|
+
- Automatically run `docker-compose build && docker-compose up -d` (if docker-compose is available)
|
|
48
|
+
- Display SSH connection command with your local IP address
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
```bash
|
|
52
|
+
pnpx @gengjiawen/os-init set-dev "ssh-rsa AAAAB3NzaC1yc2..."
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
15
56
|
|
|
16
57
|
Project generated by [gengjiawen/ts-scaffold](https://github.com/gengjiawen/ts-scaffold)
|
package/bin/bin.js
CHANGED
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
writeCodexConfig,
|
|
8
8
|
installCodexDeps,
|
|
9
9
|
writeRaycastConfig,
|
|
10
|
+
setupDevEnvironment,
|
|
10
11
|
} = require('../build')
|
|
11
12
|
|
|
12
13
|
const program = new Command()
|
|
@@ -78,4 +79,27 @@ program
|
|
|
78
79
|
console.log('Raycast AI is ready to use')
|
|
79
80
|
})
|
|
80
81
|
|
|
82
|
+
program
|
|
83
|
+
.command('set-dev')
|
|
84
|
+
.description('setup dev environment with SSH access')
|
|
85
|
+
.argument('<sshPublicKey>', 'SSH public key to set')
|
|
86
|
+
.option('-t, --target <dir>', 'Target directory for dev-setup')
|
|
87
|
+
.action(async (sshPublicKey, options) => {
|
|
88
|
+
if (!sshPublicKey || String(sshPublicKey).trim().length === 0) {
|
|
89
|
+
console.error('Missing required argument: <sshPublicKey>')
|
|
90
|
+
program.help({ error: true })
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const { targetPath } = await setupDevEnvironment(
|
|
95
|
+
sshPublicKey,
|
|
96
|
+
options.target
|
|
97
|
+
)
|
|
98
|
+
console.log(`\n✅ Dev environment setup completed at: ${targetPath}`)
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.error('Failed to setup dev environment:', err.message)
|
|
101
|
+
process.exit(1)
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
81
105
|
program.parse(process.argv)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupDevEnvironment = setupDevEnvironment;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const execa_1 = require("execa");
|
|
7
|
+
const ip = require("ip");
|
|
8
|
+
function ensureDir(dirPath) {
|
|
9
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
function copyDirSync(src, dest) {
|
|
12
|
+
ensureDir(dest);
|
|
13
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
14
|
+
for (const entry of entries) {
|
|
15
|
+
const srcPath = path.join(src, entry.name);
|
|
16
|
+
const destPath = path.join(dest, entry.name);
|
|
17
|
+
if (entry.isDirectory()) {
|
|
18
|
+
copyDirSync(srcPath, destPath);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
fs.copyFileSync(srcPath, destPath);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function commandExists(command) {
|
|
26
|
+
try {
|
|
27
|
+
const { failed } = await (0, execa_1.execa)(command, ['--version'], {
|
|
28
|
+
stdio: 'ignore',
|
|
29
|
+
reject: false,
|
|
30
|
+
});
|
|
31
|
+
return !failed;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function setupDevEnvironment(sshPublicKey, targetDir) {
|
|
38
|
+
const sourceDir = path.join(__dirname, '..', 'dev-setup');
|
|
39
|
+
const defaultTargetDir = path.join(process.cwd(), 'dev-setup');
|
|
40
|
+
const targetPath = targetDir || defaultTargetDir;
|
|
41
|
+
if (!fs.existsSync(sourceDir)) {
|
|
42
|
+
throw new Error(`Source directory not found: ${sourceDir}`);
|
|
43
|
+
}
|
|
44
|
+
console.log(`Copying dev-setup to: ${targetPath}`);
|
|
45
|
+
copyDirSync(sourceDir, targetPath);
|
|
46
|
+
const dockerfilePath = path.join(targetPath, 'Dockerfile.txt');
|
|
47
|
+
if (fs.existsSync(dockerfilePath)) {
|
|
48
|
+
let content = fs.readFileSync(dockerfilePath, 'utf-8');
|
|
49
|
+
content = content.replace('ssh-public-key-placeholder', sshPublicKey);
|
|
50
|
+
fs.writeFileSync(dockerfilePath, content);
|
|
51
|
+
console.log('SSH public key has been configured in Dockerfile.txt');
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
throw new Error(`Dockerfile.txt not found in ${targetPath}`);
|
|
55
|
+
}
|
|
56
|
+
const hasDockerCompose = await commandExists('docker-compose');
|
|
57
|
+
if (hasDockerCompose) {
|
|
58
|
+
console.log('\n🐳 Docker Compose detected. Building and starting containers...');
|
|
59
|
+
try {
|
|
60
|
+
console.log('Running: docker-compose build');
|
|
61
|
+
await (0, execa_1.execa)('docker-compose', ['build'], {
|
|
62
|
+
cwd: targetPath,
|
|
63
|
+
stdio: 'inherit',
|
|
64
|
+
});
|
|
65
|
+
console.log('Running: docker-compose up -d');
|
|
66
|
+
await (0, execa_1.execa)('docker-compose', ['up', '-d'], {
|
|
67
|
+
cwd: targetPath,
|
|
68
|
+
stdio: 'inherit',
|
|
69
|
+
});
|
|
70
|
+
console.log('\n✅ Dev environment is up and running!');
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
74
|
+
console.error('\n⚠️ Failed to start containers:', errorMessage);
|
|
75
|
+
console.log('\nYou can manually start the containers with:');
|
|
76
|
+
console.log(` cd ${targetPath}`);
|
|
77
|
+
console.log(' docker-compose build && docker-compose up -d');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
console.log('\n⚠️ Docker Compose not found.');
|
|
82
|
+
console.log('\nTo start the dev environment, run:');
|
|
83
|
+
console.log(` cd ${targetPath}`);
|
|
84
|
+
console.log(' docker-compose build && docker-compose up -d');
|
|
85
|
+
}
|
|
86
|
+
const localIp = ip.address();
|
|
87
|
+
console.log('\n📡 SSH Connection:');
|
|
88
|
+
console.log(` ssh gitpod@${localIp} -p 2222`);
|
|
89
|
+
console.log('\nOr use localhost if connecting from the same machine:');
|
|
90
|
+
console.log(' ssh gitpod@localhost -p 2222');
|
|
91
|
+
return { targetPath };
|
|
92
|
+
}
|
package/build/index.d.ts
CHANGED
package/build/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupDevEnvironment = void 0;
|
|
3
4
|
exports.writeClaudeConfig = writeClaudeConfig;
|
|
4
5
|
exports.installDeps = installDeps;
|
|
5
6
|
exports.writeCodexConfig = writeCodexConfig;
|
|
@@ -162,3 +163,5 @@ function writeRaycastConfig(apiKey) {
|
|
|
162
163
|
fs.writeFileSync(configPath, content);
|
|
163
164
|
return { configPath };
|
|
164
165
|
}
|
|
166
|
+
var dev_setup_1 = require("./dev-setup");
|
|
167
|
+
Object.defineProperty(exports, "setupDevEnvironment", { enumerable: true, get: function () { return dev_setup_1.setupDevEnvironment; } });
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
FROM gengjiawen/node-build
|
|
2
|
+
|
|
3
|
+
# SSHD configuration
|
|
4
|
+
COPY sshd_config /etc/ssh/sshd_config
|
|
5
|
+
|
|
6
|
+
ENV SSH_PUBLIC_KEY="ssh-public-key-placeholder"
|
|
7
|
+
RUN set -eux; \
|
|
8
|
+
if id -u gitpod >/dev/null 2>&1; then \
|
|
9
|
+
userhome="$(getent passwd gitpod | cut -d: -f6)"; \
|
|
10
|
+
install -o gitpod -g gitpod -m 700 -d "$userhome/.ssh"; \
|
|
11
|
+
printf '%s\n' "$SSH_PUBLIC_KEY" > "$userhome/.ssh/authorized_keys"; \
|
|
12
|
+
chown gitpod:gitpod "$userhome/.ssh/authorized_keys"; \
|
|
13
|
+
chmod 600 "$userhome/.ssh/authorized_keys"; \
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# Run sshd in foreground
|
|
17
|
+
USER root
|
|
18
|
+
EXPOSE 22
|
|
19
|
+
CMD ["/usr/sbin/sshd", "-D", "-e"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Port 22
|
|
2
|
+
Protocol 2
|
|
3
|
+
|
|
4
|
+
# Host keys are generated at runtime with `ssh-keygen -A`
|
|
5
|
+
HostKey /etc/ssh/ssh_host_rsa_key
|
|
6
|
+
HostKey /etc/ssh/ssh_host_ed25519_key
|
|
7
|
+
|
|
8
|
+
SyslogFacility AUTHPRIV
|
|
9
|
+
LogLevel VERBOSE
|
|
10
|
+
|
|
11
|
+
# Disallow root login; use non-root user (e.g., gitpod)
|
|
12
|
+
PermitRootLogin no
|
|
13
|
+
PasswordAuthentication no
|
|
14
|
+
KbdInteractiveAuthentication no
|
|
15
|
+
ChallengeResponseAuthentication no
|
|
16
|
+
PubkeyAuthentication yes
|
|
17
|
+
|
|
18
|
+
# Use per-user authorized_keys in each home directory
|
|
19
|
+
AuthorizedKeysFile .ssh/authorized_keys
|
|
20
|
+
|
|
21
|
+
PermitEmptyPasswords no
|
|
22
|
+
X11Forwarding no
|
|
23
|
+
AllowAgentForwarding yes
|
|
24
|
+
AllowTcpForwarding yes
|
|
25
|
+
ClientAliveInterval 120
|
|
26
|
+
ClientAliveCountMax 3
|
|
27
|
+
PrintMotd no
|
|
28
|
+
AcceptEnv LANG LC_*
|
|
29
|
+
|
|
30
|
+
# SFTP Subsystem
|
|
31
|
+
Subsystem sftp /usr/lib/openssh/sftp-server
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as fs from 'fs'
|
|
2
|
+
import * as path from 'path'
|
|
3
|
+
import { execa } from 'execa'
|
|
4
|
+
import * as ip from 'ip'
|
|
5
|
+
|
|
6
|
+
/** Ensure directory exists */
|
|
7
|
+
function ensureDir(dirPath: string): void {
|
|
8
|
+
fs.mkdirSync(dirPath, { recursive: true })
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Copy directory recursively */
|
|
12
|
+
function copyDirSync(src: string, dest: string): void {
|
|
13
|
+
ensureDir(dest)
|
|
14
|
+
const entries = fs.readdirSync(src, { withFileTypes: true })
|
|
15
|
+
|
|
16
|
+
for (const entry of entries) {
|
|
17
|
+
const srcPath = path.join(src, entry.name)
|
|
18
|
+
const destPath = path.join(dest, entry.name)
|
|
19
|
+
|
|
20
|
+
if (entry.isDirectory()) {
|
|
21
|
+
copyDirSync(srcPath, destPath)
|
|
22
|
+
} else {
|
|
23
|
+
fs.copyFileSync(srcPath, destPath)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Check if a command exists */
|
|
29
|
+
async function commandExists(command: string): Promise<boolean> {
|
|
30
|
+
try {
|
|
31
|
+
const { failed } = await execa(command, ['--version'], {
|
|
32
|
+
stdio: 'ignore',
|
|
33
|
+
reject: false,
|
|
34
|
+
})
|
|
35
|
+
return !failed
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Setup dev environment by copying dev-setup directory and replacing SSH public key */
|
|
42
|
+
export async function setupDevEnvironment(
|
|
43
|
+
sshPublicKey: string,
|
|
44
|
+
targetDir?: string
|
|
45
|
+
): Promise<{ targetPath: string }> {
|
|
46
|
+
// Determine source and target paths
|
|
47
|
+
const sourceDir = path.join(__dirname, '..', 'dev-setup')
|
|
48
|
+
const defaultTargetDir = path.join(process.cwd(), 'dev-setup')
|
|
49
|
+
const targetPath = targetDir || defaultTargetDir
|
|
50
|
+
|
|
51
|
+
// Check if source directory exists
|
|
52
|
+
if (!fs.existsSync(sourceDir)) {
|
|
53
|
+
throw new Error(`Source directory not found: ${sourceDir}`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Copy dev-setup directory
|
|
57
|
+
console.log(`Copying dev-setup to: ${targetPath}`)
|
|
58
|
+
copyDirSync(sourceDir, targetPath)
|
|
59
|
+
|
|
60
|
+
// Replace SSH_PUBLIC_KEY placeholder in Dockerfile.txt
|
|
61
|
+
const dockerfilePath = path.join(targetPath, 'Dockerfile.txt')
|
|
62
|
+
if (fs.existsSync(dockerfilePath)) {
|
|
63
|
+
let content = fs.readFileSync(dockerfilePath, 'utf-8')
|
|
64
|
+
content = content.replace('ssh-public-key-placeholder', sshPublicKey)
|
|
65
|
+
fs.writeFileSync(dockerfilePath, content)
|
|
66
|
+
console.log('SSH public key has been configured in Dockerfile.txt')
|
|
67
|
+
} else {
|
|
68
|
+
throw new Error(`Dockerfile.txt not found in ${targetPath}`)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check if docker-compose is available
|
|
72
|
+
const hasDockerCompose = await commandExists('docker-compose')
|
|
73
|
+
|
|
74
|
+
if (hasDockerCompose) {
|
|
75
|
+
console.log(
|
|
76
|
+
'\n🐳 Docker Compose detected. Building and starting containers...'
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
// Run docker-compose build
|
|
81
|
+
console.log('Running: docker-compose build')
|
|
82
|
+
await execa('docker-compose', ['build'], {
|
|
83
|
+
cwd: targetPath,
|
|
84
|
+
stdio: 'inherit',
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// Run docker-compose up -d
|
|
88
|
+
console.log('Running: docker-compose up -d')
|
|
89
|
+
await execa('docker-compose', ['up', '-d'], {
|
|
90
|
+
cwd: targetPath,
|
|
91
|
+
stdio: 'inherit',
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
console.log('\n✅ Dev environment is up and running!')
|
|
95
|
+
} catch (error) {
|
|
96
|
+
const errorMessage =
|
|
97
|
+
error instanceof Error ? error.message : String(error)
|
|
98
|
+
console.error('\n⚠️ Failed to start containers:', errorMessage)
|
|
99
|
+
console.log('\nYou can manually start the containers with:')
|
|
100
|
+
console.log(` cd ${targetPath}`)
|
|
101
|
+
console.log(' docker-compose build && docker-compose up -d')
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
console.log('\n⚠️ Docker Compose not found.')
|
|
105
|
+
console.log('\nTo start the dev environment, run:')
|
|
106
|
+
console.log(` cd ${targetPath}`)
|
|
107
|
+
console.log(' docker-compose build && docker-compose up -d')
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Display SSH connection instructions
|
|
111
|
+
const localIp = ip.address()
|
|
112
|
+
console.log('\n📡 SSH Connection:')
|
|
113
|
+
console.log(` ssh gitpod@${localIp} -p 2222`)
|
|
114
|
+
console.log('\nOr use localhost if connecting from the same machine:')
|
|
115
|
+
console.log(' ssh gitpod@localhost -p 2222')
|
|
116
|
+
|
|
117
|
+
return { targetPath }
|
|
118
|
+
}
|
package/libs/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gengjiawen/os-init",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"bin": {
|
|
@@ -20,15 +20,21 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"commander": "^12.1.0",
|
|
23
|
+
"ip": "^2.0.1",
|
|
23
24
|
"execa": "^8.0.1"
|
|
24
25
|
},
|
|
25
26
|
"publishConfig": {
|
|
26
27
|
"access": "public"
|
|
27
28
|
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/gengjiawen/os-init"
|
|
32
|
+
},
|
|
28
33
|
"engines": {
|
|
29
34
|
"node": ">22.12.0"
|
|
30
35
|
},
|
|
31
36
|
"devDependencies": {
|
|
37
|
+
"@types/ip": "^1.1.3",
|
|
32
38
|
"@types/jest": "29.5.12",
|
|
33
39
|
"@types/node": "24.1.0",
|
|
34
40
|
"cpy-cli": "^4.2.0",
|