@gengjiawen/os-init 1.2.1 → 1.3.2

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.
@@ -10,14 +10,22 @@ jobs:
10
10
  operating-system: [ubuntu-latest, windows-latest, macOS-latest]
11
11
 
12
12
  steps:
13
- - uses: actions/checkout@v1
13
+ - uses: actions/checkout@v4
14
+ - name: Setup Node.js (LTS)
15
+ uses: actions/setup-node@v4
16
+ with:
17
+ node-version: 'lts/*'
18
+ - name: Setup pnpm
19
+ uses: pnpm/action-setup@v4
20
+ with:
21
+ version: 9
14
22
  - name: Envinfo
15
23
  run: npx envinfo
16
- - name: npm install, build, and test
24
+ - name: Install, build, and test (pnpm)
17
25
  run: |
18
- yarn
19
- yarn build
20
- yarn format-check
21
- yarn test
26
+ pnpm install --frozen-lockfile=false
27
+ pnpm build
28
+ pnpm format:check
29
+ pnpm test
22
30
  env:
23
31
  CI: true
@@ -0,0 +1,50 @@
1
+ name: Release Please
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+ issues: write
11
+ pull-requests: write
12
+
13
+ jobs:
14
+ release-please:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - id: release
18
+ uses: googleapis/release-please-action@v4
19
+ with:
20
+ token: ${{ secrets.GITHUB_TOKEN }}
21
+ release-type: node
22
+
23
+ - name: Checkout
24
+ uses: actions/checkout@v4
25
+
26
+ - name: Setup Node.js
27
+ uses: actions/setup-node@v4
28
+ with:
29
+ node-version: '24.x'
30
+ registry-url: 'https://registry.npmjs.org'
31
+
32
+ - name: Setup pnpm
33
+ uses: pnpm/action-setup@v4
34
+ if: ${{ steps.release.outputs.release_created }}
35
+ with:
36
+ version: 9
37
+
38
+ - name: Install dependencies
39
+ run: pnpm install --frozen-lockfile=false
40
+ if: ${{ steps.release.outputs.release_created }}
41
+
42
+ - name: Build
43
+ run: pnpm run build
44
+ if: ${{ steps.release.outputs.release_created }}
45
+
46
+ - name: Publish
47
+ env:
48
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
49
+ run: npm publish
50
+ if: ${{ steps.release.outputs.release_created }}
package/CHANGELOG.md ADDED
@@ -0,0 +1,38 @@
1
+ # Changelog
2
+
3
+ ## [1.3.2](https://github.com/gengjiawen/os-init/compare/v1.3.1...v1.3.2) (2025-10-19)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * release process again ([d436b08](https://github.com/gengjiawen/os-init/commit/d436b0891c4ce2262339b2b36107a5c65abdbf83))
9
+
10
+ ## [1.3.1](https://github.com/gengjiawen/os-init/compare/v1.3.0...v1.3.1) (2025-10-19)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * release process ([a833c10](https://github.com/gengjiawen/os-init/commit/a833c1046247bb033a286d6173f493c1984f1150))
16
+
17
+ ## 1.3.0 (2025-10-19)
18
+
19
+
20
+ ### Features
21
+
22
+ * add cc support ([6bf77d8](https://github.com/gengjiawen/os-init/commit/6bf77d8d01b24babfa8c61e14cb1600b5efea309))
23
+ * bump deps and updatete cchoco scritp ([f47c982](https://github.com/gengjiawen/os-init/commit/f47c982e163c8396ef579becd869ae0ae0124c2c))
24
+ * support codex ([1b95737](https://github.com/gengjiawen/os-init/commit/1b957378dbfce4945aea74f3d84326dc5e657cc6))
25
+ * update configuration handling for Claude integration and enhance .gitignore ([5c59ed8](https://github.com/gengjiawen/os-init/commit/5c59ed85125e3247c97dd6d339584fe6d9aa63a2))
26
+ * update macOS commands ([b1d80cf](https://github.com/gengjiawen/os-init/commit/b1d80cf8fa06360fff2be1e188b7d09cfb2d8479))
27
+
28
+
29
+ ### Bug Fixes
30
+
31
+ * choco install ([9af90d2](https://github.com/gengjiawen/os-init/commit/9af90d299b5865d54b7b3eff467f086dacdd175d))
32
+ * correct format-check command to format:check in CI workflow ([3befc98](https://github.com/gengjiawen/os-init/commit/3befc989086cc04da5306b42159bcd2b751451b6))
33
+ * publish ([3ea009e](https://github.com/gengjiawen/os-init/commit/3ea009e1634e94e7b8c1801ff6754cb7a5012ccf))
34
+
35
+
36
+ ### Miscellaneous Chores
37
+
38
+ * release 1.3.0 ([588992a](https://github.com/gengjiawen/os-init/commit/588992ab4565e792900e1efa50ebdedca9fca91d))
package/README.md CHANGED
@@ -1,10 +1,14 @@
1
- ## Setup
1
+ ## os-init CLI
2
2
 
3
- My OS setup and mostly used script.
3
+ What it does
4
4
 
5
- ```
6
- npm install
7
- npm start
8
- ```
5
+ - Configure Claude Code Router with your API key (writes `~/.claude-code-router/config.json`).
6
+ - Configure Codex CLI with your API key (writes `~/.codex/config.toml` and `~/.codex/auth.json`).
7
+ - Install global tools: `@anthropic-ai/claude-code`, `@musistudio/claude-code-router`, `@openai/codex`.
8
+
9
+ Usage
10
+
11
+ - `pnpx @gengjiawen/os-init set-cc <API_KEY>`
12
+ - `pnpx @gengjiawen/os-init set-codex <API_KEY>`
9
13
 
10
14
  Project generated by [gengjiawen/ts-scaffold](https://github.com/gengjiawen/ts-scaffold)
package/bin/bin.js CHANGED
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const { Command } = require('commander')
4
- const { writeConfig, installDeps, writeCodexConfig, installCodexDeps } = require('../build')
4
+ const {
5
+ writeClaudeConfig,
6
+ installDeps,
7
+ writeCodexConfig,
8
+ installCodexDeps,
9
+ } = require('../build')
5
10
 
6
11
  const program = new Command()
7
12
 
@@ -17,8 +22,9 @@ program
17
22
  return
18
23
  }
19
24
  try {
20
- const configPath = writeConfig(apiKey)
21
- console.log(`Config written to: ${configPath}`)
25
+ const { routerConfigPath, settingsPath } = writeClaudeConfig(apiKey)
26
+ console.log(`Claude router config written to: ${routerConfigPath}`)
27
+ console.log(`Claude settings written to: ${settingsPath}`)
22
28
  await installDeps()
23
29
  } catch (err) {
24
30
  console.error('Failed to complete setup:', err.message)
package/build/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- export declare function writeConfig(apiKey: string): string;
1
+ export declare function writeClaudeConfig(apiKey: string): {
2
+ routerConfigPath: string;
3
+ settingsPath: string;
4
+ };
2
5
  export declare function installDeps(): Promise<void>;
3
6
  export declare function writeCodexConfig(apiKey: string): {
4
7
  configPath: string;
package/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.writeConfig = writeConfig;
3
+ exports.writeClaudeConfig = writeClaudeConfig;
4
4
  exports.installDeps = installDeps;
5
5
  exports.writeCodexConfig = writeCodexConfig;
6
6
  exports.installCodexDeps = installCodexDeps;
@@ -20,7 +20,7 @@ const DEFAULT_TEMPLATE = `{
20
20
  "name": "jw",
21
21
  "api_base_url": "https://ai.gengjiawen.com/api/openai/v1/chat/completions",
22
22
  "api_key": "API_KEY_PLACEHOLDER",
23
- "models": ["code", "free", "free-thinking"],
23
+ "models": ["code", "free"],
24
24
  "transformer": {
25
25
  "use": ["openrouter"]
26
26
  }
@@ -33,17 +33,43 @@ const DEFAULT_TEMPLATE = `{
33
33
  "longContext": "jw,code"
34
34
  }
35
35
  }`;
36
- function writeConfig(apiKey) {
37
- const configDir = getDefaultConfigDir();
38
- const configPath = path.join(configDir, 'config.json');
39
- ensureDir(configDir);
40
- const content = DEFAULT_TEMPLATE.replace('API_KEY_PLACEHOLDER', apiKey);
41
- fs.writeFileSync(configPath, content);
42
- return configPath;
36
+ function getClaudeSettingsDir() {
37
+ return path.join(os.homedir(), '.claude');
38
+ }
39
+ const CLAUDE_SETTINGS_TEMPLATE = `{
40
+ "env": {
41
+ "DISABLE_TELEMETRY": "1",
42
+ "OTEL_METRICS_EXPORTER": "otlp",
43
+ "ANTHROPIC_API_KEY": "API_KEY_PLACEHOLDER",
44
+ "ANTHROPIC_BASE_URL": "https://ai.gengjiawen.com/api/claude/",
45
+ "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
46
+ },
47
+ "includeCoAuthoredBy": false,
48
+ "apiKeyHelper": "echo 'API_KEY_PLACEHOLDER'",
49
+ "permissions": {
50
+ "allow": [],
51
+ "deny": []
52
+ }
53
+ }`;
54
+ function writeClaudeConfig(apiKey) {
55
+ const routerConfigDir = getDefaultConfigDir();
56
+ const routerConfigPath = path.join(routerConfigDir, 'config.json');
57
+ ensureDir(routerConfigDir);
58
+ const routerContent = DEFAULT_TEMPLATE.replace('API_KEY_PLACEHOLDER', apiKey);
59
+ fs.writeFileSync(routerConfigPath, routerContent);
60
+ const settingsDir = getClaudeSettingsDir();
61
+ const settingsPath = path.join(settingsDir, 'settings.json');
62
+ ensureDir(settingsDir);
63
+ const settingsContent = CLAUDE_SETTINGS_TEMPLATE.replace(/API_KEY_PLACEHOLDER/g, apiKey);
64
+ fs.writeFileSync(settingsPath, settingsContent);
65
+ return { routerConfigPath, settingsPath };
43
66
  }
44
67
  async function commandExists(command) {
45
68
  try {
46
- const { failed } = await (0, execa_1.execa)(command, ['--version'], { stdio: 'ignore', reject: false });
69
+ const { failed } = await (0, execa_1.execa)(command, ['--version'], {
70
+ stdio: 'ignore',
71
+ reject: false,
72
+ });
47
73
  return !failed;
48
74
  }
49
75
  catch (error) {
@@ -51,7 +77,10 @@ async function commandExists(command) {
51
77
  }
52
78
  }
53
79
  async function installDeps() {
54
- const packages = ['@anthropic-ai/claude-code', '@musistudio/claude-code-router'];
80
+ const packages = [
81
+ '@anthropic-ai/claude-code',
82
+ '@musistudio/claude-code-router',
83
+ ];
55
84
  const usePnpm = await commandExists('pnpm');
56
85
  if (usePnpm) {
57
86
  console.log('pnpm detected. Installing dependencies with pnpm...');
package/libs/index.ts CHANGED
@@ -20,7 +20,7 @@ const DEFAULT_TEMPLATE = `{
20
20
  "name": "jw",
21
21
  "api_base_url": "https://ai.gengjiawen.com/api/openai/v1/chat/completions",
22
22
  "api_key": "API_KEY_PLACEHOLDER",
23
- "models": ["code", "free", "free-thinking"],
23
+ "models": ["code", "free"],
24
24
  "transformer": {
25
25
  "use": ["openrouter"]
26
26
  }
@@ -34,21 +34,61 @@ const DEFAULT_TEMPLATE = `{
34
34
  }
35
35
  }`
36
36
 
37
- /** Write config by simple string replacement */
38
- export function writeConfig(apiKey: string): string {
39
- const configDir = getDefaultConfigDir()
40
- const configPath = path.join(configDir, 'config.json')
41
- ensureDir(configDir)
42
- const content = DEFAULT_TEMPLATE.replace('API_KEY_PLACEHOLDER', apiKey)
43
- fs.writeFileSync(configPath, content)
44
- return configPath
37
+ /** Return Claude settings directory path */
38
+ function getClaudeSettingsDir(): string {
39
+ return path.join(os.homedir(), '.claude')
40
+ }
41
+
42
+ /** Template for Claude settings.json */
43
+ const CLAUDE_SETTINGS_TEMPLATE = `{
44
+ "env": {
45
+ "DISABLE_TELEMETRY": "1",
46
+ "OTEL_METRICS_EXPORTER": "otlp",
47
+ "ANTHROPIC_API_KEY": "API_KEY_PLACEHOLDER",
48
+ "ANTHROPIC_BASE_URL": "https://ai.gengjiawen.com/api/claude/",
49
+ "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
50
+ },
51
+ "includeCoAuthoredBy": false,
52
+ "apiKeyHelper": "echo 'API_KEY_PLACEHOLDER'",
53
+ "permissions": {
54
+ "allow": [],
55
+ "deny": []
56
+ }
57
+ }`
58
+
59
+ /** Write Claude config files (both router config and settings) */
60
+ export function writeClaudeConfig(apiKey: string): {
61
+ routerConfigPath: string
62
+ settingsPath: string
63
+ } {
64
+ // Write claude-code-router config
65
+ const routerConfigDir = getDefaultConfigDir()
66
+ const routerConfigPath = path.join(routerConfigDir, 'config.json')
67
+ ensureDir(routerConfigDir)
68
+ const routerContent = DEFAULT_TEMPLATE.replace('API_KEY_PLACEHOLDER', apiKey)
69
+ fs.writeFileSync(routerConfigPath, routerContent)
70
+
71
+ // Write Claude settings
72
+ const settingsDir = getClaudeSettingsDir()
73
+ const settingsPath = path.join(settingsDir, 'settings.json')
74
+ ensureDir(settingsDir)
75
+ const settingsContent = CLAUDE_SETTINGS_TEMPLATE.replace(
76
+ /API_KEY_PLACEHOLDER/g,
77
+ apiKey
78
+ )
79
+ fs.writeFileSync(settingsPath, settingsContent)
80
+
81
+ return { routerConfigPath, settingsPath }
45
82
  }
46
83
 
47
84
  /** Check if a command exists */
48
85
  async function commandExists(command: string): Promise<boolean> {
49
86
  try {
50
87
  // execa with reject: false will not throw on non-zero exit codes.
51
- const { failed } = await execa(command, ['--version'], { stdio: 'ignore', reject: false })
88
+ const { failed } = await execa(command, ['--version'], {
89
+ stdio: 'ignore',
90
+ reject: false,
91
+ })
52
92
  return !failed
53
93
  } catch (error) {
54
94
  // Catch errors for commands that don't support --version or other issues
@@ -58,7 +98,10 @@ async function commandExists(command: string): Promise<boolean> {
58
98
 
59
99
  /** Install global dependencies */
60
100
  export async function installDeps(): Promise<void> {
61
- const packages = ['@anthropic-ai/claude-code', '@musistudio/claude-code-router']
101
+ const packages = [
102
+ '@anthropic-ai/claude-code',
103
+ '@musistudio/claude-code-router',
104
+ ]
62
105
  const usePnpm = await commandExists('pnpm')
63
106
 
64
107
  if (usePnpm) {
@@ -71,7 +114,6 @@ export async function installDeps(): Promise<void> {
71
114
  console.log('Dependencies installed successfully.')
72
115
  }
73
116
 
74
-
75
117
  /** Return Codex configuration directory path */
76
118
  function getCodexConfigDir(): string {
77
119
  return path.join(os.homedir(), '.codex')
@@ -91,7 +133,10 @@ wire_api = "responses"
91
133
  `
92
134
 
93
135
  /** Write Codex config.toml and auth.json */
94
- export function writeCodexConfig(apiKey: string): { configPath: string; authPath: string } {
136
+ export function writeCodexConfig(apiKey: string): {
137
+ configPath: string
138
+ authPath: string
139
+ } {
95
140
  const configDir = getCodexConfigDir()
96
141
  ensureDir(configDir)
97
142
 
@@ -119,4 +164,3 @@ export async function installCodexDeps(): Promise<void> {
119
164
  }
120
165
  console.log('Codex dependency installed successfully.')
121
166
  }
122
-
package/macOS-init.md CHANGED
@@ -23,6 +23,9 @@ brew install omnidisksweeper
23
23
  brew install git-lfs
24
24
  brew install jordanbaird-ice
25
25
  sudo git lfs install --system
26
+ npm i -g pnpm yarn && pnpm setup
27
+ pnpm i -g vite 7zip-bin-full
28
+ sudo ln -s "$(NODE_PATH="$(pnpm root -g)" node -p "require('7zip-bin-full').path7za")" /usr/local/bin/7z
26
29
  ```
27
30
 
28
31
 
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@gengjiawen/os-init",
3
3
  "private": false,
4
- "version": "1.2.1",
4
+ "version": "1.3.2",
5
5
  "description": "",
6
6
  "main": "index.js",
7
7
  "bin": {
8
8
  "os-init": "bin/bin.js"
9
9
  },
10
10
  "scripts": {
11
- "start": "tsc -w",
11
+ "dev": "tsc -w",
12
12
  "server": "nodemon --exec ts-node libs/index.ts",
13
13
  "prepare": "husky install",
14
14
  "clean": "rimraf build",
@@ -25,6 +25,9 @@
25
25
  "publishConfig": {
26
26
  "access": "public"
27
27
  },
28
+ "engines": {
29
+ "node": ">22.12.0"
30
+ },
28
31
  "devDependencies": {
29
32
  "@types/jest": "29.5.12",
30
33
  "@types/node": "24.1.0",
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) gengjiawen <technicalcute@gmail.com>
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
13
- all 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
21
- THE SOFTWARE.
@@ -1,8 +0,0 @@
1
- ### Setup
2
-
3
- ```
4
- npm install
5
- npm start
6
- ```
7
-
8
- Project generated by [gengjiawen/ts-scaffold](https://github.com/gengjiawen/ts-scaffold)
@@ -1,5 +0,0 @@
1
- import { list } from '../libs'
2
-
3
- test('packages', () => {
4
- expect(() => list()).not.toThrow()
5
- })
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const program = require('commander')
4
-
5
- const { init, list } = require('../build')
6
-
7
- program
8
- .version(require('../package.json').version)
9
- .command('init')
10
- .action(() => {
11
- init()
12
- })
13
-
14
- program
15
- .version(require('../package.json').version)
16
- .command('list')
17
- .action(() => {
18
- list()
19
- })
20
-
21
- program.parse(process.argv)
@@ -1,15 +0,0 @@
1
- import { packages } from './packages'
2
- import * as execa from 'execa'
3
-
4
- export const psPolicy = `Set-ExecutionPolicy -ExecutionPolicy ByPass`
5
-
6
- export async function init() {
7
- const cmd = `Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))`
8
- console.log(`need to ${psPolicy} if you are not`)
9
- console.log(cmd)
10
- await execa.command(cmd, { shell: 'powershell', stdio: 'inherit' })
11
- }
12
-
13
- export function list() {
14
- console.log(packages.join('\n'))
15
- }
@@ -1,8 +0,0 @@
1
- export const packages = [
2
- 'git',
3
- 'nodejs',
4
- 'jdk8',
5
- 'vscode',
6
- 'visualstudio2022enterprise',
7
- 'jetbrainstoolbox',
8
- ]
@@ -1,33 +0,0 @@
1
- {
2
- "name": "@gengjiawen/win",
3
- "version": "0.0.4",
4
- "description": "my groovy project",
5
- "author": "gengjiawen <technicalcute@gmail.com>",
6
- "bin": {
7
- "init": "bin/init.js"
8
- },
9
- "scripts": {
10
- "start": "tsc -w",
11
- "clean": "rimraf build",
12
- "test": "jest",
13
- "build": "npm run clean && tsc -p ./tsconfig.json"
14
- },
15
- "dependencies": {
16
- "commander": "^8.2.0",
17
- "execa": "^5.1.1"
18
- },
19
- "devDependencies": {
20
- "@types/jest": "27.0.2",
21
- "jest": "27.3.0",
22
- "ts-jest": "27.0.7"
23
- },
24
- "publishConfig": {
25
- "access": "public"
26
- },
27
- "jest": {
28
- "testEnvironment": "node",
29
- "transform": {
30
- "^.+\\.tsx?$": "ts-jest"
31
- }
32
- }
33
- }
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "./build"
5
- },
6
- "exclude": [
7
- "build",
8
- "__tests__",
9
- "test"
10
- ]
11
- }