spinup-ts 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 +82 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +17 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +264 -0
- package/dist/prompts.js.map +1 -0
- package/dist/scaffold.d.ts +5 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +128 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/transforms/devcontainer.d.ts +3 -0
- package/dist/transforms/devcontainer.d.ts.map +1 -0
- package/dist/transforms/devcontainer.js +8 -0
- package/dist/transforms/devcontainer.js.map +1 -0
- package/dist/transforms/docker.d.ts +3 -0
- package/dist/transforms/docker.d.ts.map +1 -0
- package/dist/transforms/docker.js +11 -0
- package/dist/transforms/docker.js.map +1 -0
- package/dist/transforms/docs.d.ts +3 -0
- package/dist/transforms/docs.d.ts.map +1 -0
- package/dist/transforms/docs.js +22 -0
- package/dist/transforms/docs.js.map +1 -0
- package/dist/transforms/documentation.d.ts +3 -0
- package/dist/transforms/documentation.d.ts.map +1 -0
- package/dist/transforms/documentation.js +37 -0
- package/dist/transforms/documentation.js.map +1 -0
- package/dist/transforms/github-actions.d.ts +3 -0
- package/dist/transforms/github-actions.d.ts.map +1 -0
- package/dist/transforms/github-actions.js +48 -0
- package/dist/transforms/github-actions.js.map +1 -0
- package/dist/transforms/index.d.ts +3 -0
- package/dist/transforms/index.d.ts.map +1 -0
- package/dist/transforms/index.js +24 -0
- package/dist/transforms/index.js.map +1 -0
- package/dist/transforms/license.d.ts +3 -0
- package/dist/transforms/license.d.ts.map +1 -0
- package/dist/transforms/license.js +19 -0
- package/dist/transforms/license.js.map +1 -0
- package/dist/transforms/npm-publish.d.ts +3 -0
- package/dist/transforms/npm-publish.d.ts.map +1 -0
- package/dist/transforms/npm-publish.js +15 -0
- package/dist/transforms/npm-publish.js.map +1 -0
- package/dist/transforms/package-manager.d.ts +3 -0
- package/dist/transforms/package-manager.d.ts.map +1 -0
- package/dist/transforms/package-manager.js +31 -0
- package/dist/transforms/package-manager.js.map +1 -0
- package/dist/types.d.ts +116 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +52 -0
- package/dist/types.js.map +1 -0
- package/dist/update.d.ts +2 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +207 -0
- package/dist/update.js.map +1 -0
- package/package.json +94 -0
- package/template/.commitlintrc.json +3 -0
- package/template/.devcontainer/.zshrc +159 -0
- package/template/.devcontainer/DISCOVER-DEPS.md +109 -0
- package/template/.devcontainer/README.md +223 -0
- package/template/.devcontainer/SETUP.md +191 -0
- package/template/.devcontainer/TOOLS.md +215 -0
- package/template/.devcontainer/devcontainer.json +106 -0
- package/template/.devcontainer/scripts/init-project.sh +167 -0
- package/template/.editorconfig +12 -0
- package/template/.github/.release-please-manifest.json +3 -0
- package/template/.github/ISSUE_TEMPLATE/bug_report.md +21 -0
- package/template/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
- package/template/.github/PULL_REQUEST_TEMPLATE.md +13 -0
- package/template/.github/actions/setup-node-env/action.yml +20 -0
- package/template/.github/dependabot.yml +17 -0
- package/template/.github/labeler.yml +17 -0
- package/template/.github/release-please-config.json +7 -0
- package/template/.github/workflows/ci.yml +95 -0
- package/template/.github/workflows/codeql.yml +31 -0
- package/template/.github/workflows/labeler.yml +18 -0
- package/template/.github/workflows/release-please.yml +72 -0
- package/template/.github/workflows/stale.yml +32 -0
- package/template/.husky/commit-msg +1 -0
- package/template/.husky/pre-commit +1 -0
- package/template/.nvmrc +1 -0
- package/template/.vscode/extensions.json +11 -0
- package/template/.vscode/settings.json +12 -0
- package/template/AGENTS.md +1 -0
- package/template/CHANGELOG.md +11 -0
- package/template/CLAUDE.md +0 -0
- package/template/CONTRIBUTING.md +22 -0
- package/template/Dockerfile +21 -0
- package/template/LICENSE.Apache-2.0 +17 -0
- package/template/LICENSE.BSD-3-Clause +28 -0
- package/template/LICENSE.GPL-3.0 +17 -0
- package/template/LICENSE.ISC +15 -0
- package/template/LICENSE.MIT +21 -0
- package/template/README.md +62 -0
- package/template/biome.json +49 -0
- package/template/docker-compose.yml +7 -0
- package/template/docs/architecture/api-layer.md +44 -0
- package/template/docs/architecture/constitution.md +24 -0
- package/template/docs/architecture/data-model.md +24 -0
- package/template/docs/architecture/index.md +15 -0
- package/template/docs/architecture/project.md +24 -0
- package/template/docs/architecture/quality-checks.md +28 -0
- package/template/docs/architecture/testing-plan.md +35 -0
- package/template/docs/architecture/ui.md +37 -0
- package/template/docs/changelog.md +9 -0
- package/template/docs/contributing.md +46 -0
- package/template/docs/developer-guide/architecture.md +22 -0
- package/template/docs/developer-guide/contributing.md +30 -0
- package/template/docs/developer-guide/data-model.md +25 -0
- package/template/docs/developer-guide/index.md +12 -0
- package/template/docs/developer-guide/testing.md +40 -0
- package/template/docs/examples.md +37 -0
- package/template/docs/getting-started.md +42 -0
- package/template/docs/installation.md +45 -0
- package/template/docs/intro.md +60 -0
- package/template/docs/post-mortems/.gitkeep +0 -0
- package/template/docs/reference/cli.md +32 -0
- package/template/docs/reference/configuration.md +33 -0
- package/template/docs/reference/hooks.md +27 -0
- package/template/docs/research/competitor-analysis.md +21 -0
- package/template/docs/research/real-world-demand.md +21 -0
- package/template/docs/user-guide/configuration.md +32 -0
- package/template/docs/user-guide/features.md +21 -0
- package/template/docs/user-guide/how-it-works.md +29 -0
- package/template/docs/user-guide/index.md +11 -0
- package/template/docusaurus.config.ts +93 -0
- package/template/eslint.config.mjs +66 -0
- package/template/justfile +51 -0
- package/template/package.json +88 -0
- package/template/pnpm-workspace.yaml +8 -0
- package/template/sidebars.ts +72 -0
- package/template/src/index.ts +3 -0
- package/template/static/img/logo.svg +4 -0
- package/template/tests/index.test.ts +8 -0
- package/template/tsconfig.json +23 -0
- package/template/vitest.config.ts +19 -0
package/dist/update.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import { constants, access } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import * as clack from '@clack/prompts';
|
|
7
|
+
import fs from 'fs-extra';
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
const TEMPLATE_DIR = path.resolve(__dirname, '..', 'template');
|
|
12
|
+
const PKG_FILENAME = 'package.json';
|
|
13
|
+
const BIOME_FILENAME = 'biome.json';
|
|
14
|
+
const ESLINT_FILENAME = 'eslint.config.mjs';
|
|
15
|
+
async function pathExists(p) {
|
|
16
|
+
try {
|
|
17
|
+
await access(p, constants.F_OK);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function applyBiome(dir) {
|
|
25
|
+
await fs.copy(path.join(TEMPLATE_DIR, BIOME_FILENAME), path.join(dir, BIOME_FILENAME), {
|
|
26
|
+
overwrite: false,
|
|
27
|
+
errorOnExist: false,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async function applyTsconfig(dir) {
|
|
31
|
+
const tsconfigPath = path.join(dir, 'tsconfig.json');
|
|
32
|
+
const tsconfig = (await fs.readJson(tsconfigPath));
|
|
33
|
+
tsconfig.compilerOptions = {
|
|
34
|
+
...tsconfig.compilerOptions,
|
|
35
|
+
noUncheckedIndexedAccess: true,
|
|
36
|
+
exactOptionalPropertyTypes: true,
|
|
37
|
+
};
|
|
38
|
+
await fs.writeJson(tsconfigPath, tsconfig, { spaces: 2 });
|
|
39
|
+
}
|
|
40
|
+
async function applyEslint(dir) {
|
|
41
|
+
await fs.copy(path.join(TEMPLATE_DIR, ESLINT_FILENAME), path.join(dir, ESLINT_FILENAME), {
|
|
42
|
+
overwrite: false,
|
|
43
|
+
errorOnExist: false,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
async function applyHusky(dir) {
|
|
47
|
+
const huskyDir = path.join(dir, '.husky');
|
|
48
|
+
await fs.ensureDir(huskyDir);
|
|
49
|
+
await fs.writeFile(path.join(huskyDir, 'pre-commit'), 'pnpm lint-staged\n', 'utf8');
|
|
50
|
+
const packagePath = path.join(dir, PKG_FILENAME);
|
|
51
|
+
const packageJson = (await fs.readJson(packagePath));
|
|
52
|
+
packageJson.scripts = { ...packageJson.scripts };
|
|
53
|
+
packageJson.scripts.prepare ??= 'husky';
|
|
54
|
+
packageJson['lint-staged'] ??= {
|
|
55
|
+
'*.{ts,js,json,md}': [
|
|
56
|
+
'biome check --write --no-errors-on-unmatched --files-ignore-unknown=true',
|
|
57
|
+
],
|
|
58
|
+
'*.ts': ['eslint --fix --max-warnings=0 --no-warn-ignored'],
|
|
59
|
+
};
|
|
60
|
+
await fs.writeJson(packagePath, packageJson, { spaces: 2 });
|
|
61
|
+
}
|
|
62
|
+
async function applyCi(dir) {
|
|
63
|
+
const target = path.join(dir, '.github', 'workflows', 'ci.yml');
|
|
64
|
+
await fs.ensureDir(path.dirname(target));
|
|
65
|
+
await fs.copy(path.join(TEMPLATE_DIR, '.github', 'workflows', 'ci.yml'), target, {
|
|
66
|
+
overwrite: false,
|
|
67
|
+
errorOnExist: false,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
async function applyBeads(dir) {
|
|
71
|
+
try {
|
|
72
|
+
await execAsync('bd init --skip-agents --non-interactive', { cwd: dir });
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// bd not installed; skip silently
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function applySerena(dir) {
|
|
79
|
+
const package_ = (await fs.readJson(path.join(dir, PKG_FILENAME)));
|
|
80
|
+
const slug = (package_.name ?? path.basename(dir)).replaceAll('-', '_');
|
|
81
|
+
const serenaDir = path.join(dir, '.serena');
|
|
82
|
+
await fs.ensureDir(serenaDir);
|
|
83
|
+
await fs.writeFile(path.join(serenaDir, 'project.yml'), `project_name: ${slug}\nlanguages:\n - typescript\n`, 'utf8');
|
|
84
|
+
}
|
|
85
|
+
async function applyVscode(dir) {
|
|
86
|
+
const vscodeDir = path.join(dir, '.vscode');
|
|
87
|
+
await fs.ensureDir(vscodeDir);
|
|
88
|
+
const settingsPath = path.join(vscodeDir, 'settings.json');
|
|
89
|
+
const biomeSettings = {
|
|
90
|
+
'editor.defaultFormatter': 'biomejs.biome',
|
|
91
|
+
'editor.formatOnSave': true,
|
|
92
|
+
'editor.codeActionsOnSave': {
|
|
93
|
+
'quickfix.biome': 'explicit',
|
|
94
|
+
'source.organizeImports.biome': 'explicit',
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
const existing = (await pathExists(settingsPath))
|
|
98
|
+
? (await fs.readJson(settingsPath))
|
|
99
|
+
: {};
|
|
100
|
+
await fs.writeJson(settingsPath, { ...existing, ...biomeSettings }, { spaces: 2 });
|
|
101
|
+
}
|
|
102
|
+
async function needsTsconfigUpdate(targetDir) {
|
|
103
|
+
const tsconfigPath = path.join(targetDir, 'tsconfig.json');
|
|
104
|
+
if (!(await pathExists(tsconfigPath)))
|
|
105
|
+
return false;
|
|
106
|
+
const tsconfig = (await fs.readJson(tsconfigPath));
|
|
107
|
+
const co = tsconfig.compilerOptions ?? {};
|
|
108
|
+
return co.noUncheckedIndexedAccess !== true || co.exactOptionalPropertyTypes !== true;
|
|
109
|
+
}
|
|
110
|
+
async function needsHusky(targetDir) {
|
|
111
|
+
const huskyPreCommit = path.join(targetDir, '.husky', 'pre-commit');
|
|
112
|
+
const packageJson = (await fs.readJson(path.join(targetDir, PKG_FILENAME)));
|
|
113
|
+
return (!(await pathExists(huskyPreCommit)) ||
|
|
114
|
+
!packageJson['lint-staged'] ||
|
|
115
|
+
!packageJson.scripts?.prepare);
|
|
116
|
+
}
|
|
117
|
+
async function detectAvailableUpdates(targetDir) {
|
|
118
|
+
const options = [];
|
|
119
|
+
if (!(await pathExists(path.join(targetDir, BIOME_FILENAME))))
|
|
120
|
+
options.push({
|
|
121
|
+
value: 'biome',
|
|
122
|
+
label: 'Add Biome config',
|
|
123
|
+
hint: 'copy template biome.json',
|
|
124
|
+
apply: applyBiome,
|
|
125
|
+
});
|
|
126
|
+
if (await needsTsconfigUpdate(targetDir))
|
|
127
|
+
options.push({
|
|
128
|
+
value: 'tsconfig',
|
|
129
|
+
label: 'Tighten tsconfig.json',
|
|
130
|
+
hint: 'add noUncheckedIndexedAccess + exactOptionalPropertyTypes',
|
|
131
|
+
apply: applyTsconfig,
|
|
132
|
+
});
|
|
133
|
+
if (!(await pathExists(path.join(targetDir, ESLINT_FILENAME))))
|
|
134
|
+
options.push({
|
|
135
|
+
value: 'eslint',
|
|
136
|
+
label: 'Add ESLint strict config',
|
|
137
|
+
hint: 'copy template eslint.config.mjs',
|
|
138
|
+
apply: applyEslint,
|
|
139
|
+
});
|
|
140
|
+
if (await needsHusky(targetDir))
|
|
141
|
+
options.push({
|
|
142
|
+
value: 'husky',
|
|
143
|
+
label: 'Add Husky + lint-staged',
|
|
144
|
+
hint: 'pre-commit hook with biome + eslint',
|
|
145
|
+
apply: applyHusky,
|
|
146
|
+
});
|
|
147
|
+
if (!(await pathExists(path.join(targetDir, '.github', 'workflows', 'ci.yml'))))
|
|
148
|
+
options.push({
|
|
149
|
+
value: 'ci',
|
|
150
|
+
label: 'Add GitHub Actions CI',
|
|
151
|
+
hint: 'copy template ci.yml',
|
|
152
|
+
apply: applyCi,
|
|
153
|
+
});
|
|
154
|
+
options.push({
|
|
155
|
+
value: 'vscode',
|
|
156
|
+
label: 'Configure VS Code Biome formatter',
|
|
157
|
+
hint: 'merge .vscode/settings.json',
|
|
158
|
+
apply: applyVscode,
|
|
159
|
+
});
|
|
160
|
+
if (!(await pathExists(path.join(targetDir, '.beads'))))
|
|
161
|
+
options.push({
|
|
162
|
+
value: 'beads',
|
|
163
|
+
label: 'Initialize Beads task manager',
|
|
164
|
+
hint: 'bd init --skip-agents',
|
|
165
|
+
apply: applyBeads,
|
|
166
|
+
});
|
|
167
|
+
if (!(await pathExists(path.join(targetDir, '.serena', 'project.yml'))))
|
|
168
|
+
options.push({
|
|
169
|
+
value: 'serena',
|
|
170
|
+
label: 'Initialize Serena',
|
|
171
|
+
hint: 'create .serena/project.yml',
|
|
172
|
+
apply: applySerena,
|
|
173
|
+
});
|
|
174
|
+
return options;
|
|
175
|
+
}
|
|
176
|
+
export async function updateProject(targetDir) {
|
|
177
|
+
if (!(await pathExists(targetDir))) {
|
|
178
|
+
throw new Error(`Target directory does not exist: ${targetDir}`);
|
|
179
|
+
}
|
|
180
|
+
if (!(await pathExists(path.join(targetDir, PKG_FILENAME)))) {
|
|
181
|
+
throw new Error(`No package.json found in ${targetDir}`);
|
|
182
|
+
}
|
|
183
|
+
clack.intro('spinup-ts update');
|
|
184
|
+
const available = await detectAvailableUpdates(targetDir);
|
|
185
|
+
if (available.length === 0) {
|
|
186
|
+
clack.outro('Nothing to update — your project is already up to date!');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const selected = await clack.multiselect({
|
|
190
|
+
message: 'Select updates to apply:',
|
|
191
|
+
options: available.map(({ value, label, hint }) => hint ? { value, label, hint } : { value, label }),
|
|
192
|
+
required: false,
|
|
193
|
+
});
|
|
194
|
+
if (clack.isCancel(selected) || selected.length === 0) {
|
|
195
|
+
clack.cancel('No updates applied.');
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const chosen = available.filter((o) => selected.includes(o.value));
|
|
199
|
+
const spinner = clack.spinner();
|
|
200
|
+
spinner.start('Applying updates...');
|
|
201
|
+
for (const update of chosen) {
|
|
202
|
+
await update.apply(targetDir);
|
|
203
|
+
}
|
|
204
|
+
spinner.stop('Done!');
|
|
205
|
+
clack.outro(`Applied ${chosen.length} update(s). Review changes with \`git diff\`.`);
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "spinup-ts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scaffold a production-ready TypeScript project with opinionated tooling (Biome, ESLint strict, Vitest, Husky, GitHub Actions, Docusaurus, Docker, devcontainer). The TypeScript sibling of spinup-py.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"spinup-ts": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": ["dist", "template"],
|
|
10
|
+
"homepage": "https://github.com/joeblackwaslike/spinup-ts#readme",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/joeblackwaslike/spinup-ts.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/joeblackwaslike/spinup-ts/issues"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"typescript",
|
|
20
|
+
"scaffold",
|
|
21
|
+
"cli",
|
|
22
|
+
"template",
|
|
23
|
+
"boilerplate",
|
|
24
|
+
"starter",
|
|
25
|
+
"biome",
|
|
26
|
+
"eslint",
|
|
27
|
+
"vitest",
|
|
28
|
+
"docusaurus"
|
|
29
|
+
],
|
|
30
|
+
"author": "Joe Black <joeblackwaslike@gmail.com>",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"dev": "tsx src/index.ts",
|
|
35
|
+
"test": "vitest",
|
|
36
|
+
"test:watch": "vitest --watch",
|
|
37
|
+
"test:coverage": "vitest --coverage",
|
|
38
|
+
"lint": "biome ci . && eslint . --max-warnings=0",
|
|
39
|
+
"lint:fix": "biome check --write . && eslint --fix .",
|
|
40
|
+
"format": "biome format --write .",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"check": "pnpm typecheck && pnpm lint",
|
|
43
|
+
"commit": "cz",
|
|
44
|
+
"prepare": "husky",
|
|
45
|
+
"prepublishOnly": "pnpm build"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@clack/prompts": "^0.9.1",
|
|
49
|
+
"degit": "^2.8.4",
|
|
50
|
+
"fs-extra": "^11.2.0",
|
|
51
|
+
"globby": "^14.0.2",
|
|
52
|
+
"picocolors": "^1.1.1",
|
|
53
|
+
"zod": "^3.24.1"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@biomejs/biome": "^1.9.4",
|
|
57
|
+
"@commitlint/cli": "^21.0.2",
|
|
58
|
+
"@commitlint/config-conventional": "^21.0.2",
|
|
59
|
+
"@types/degit": "^2.8.6",
|
|
60
|
+
"@types/fs-extra": "^11.0.4",
|
|
61
|
+
"@types/node": "^22.0.0",
|
|
62
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
63
|
+
"commitizen": "^4.3.1",
|
|
64
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
65
|
+
"eslint": "^9.28.0",
|
|
66
|
+
"eslint-plugin-import-x": "^4.12.2",
|
|
67
|
+
"eslint-plugin-no-secrets": "^1.1.2",
|
|
68
|
+
"eslint-plugin-sonarjs": "^3.0.2",
|
|
69
|
+
"eslint-plugin-unicorn": "^56.0.1",
|
|
70
|
+
"husky": "^9.1.7",
|
|
71
|
+
"lint-staged": "^15.5.2",
|
|
72
|
+
"tsx": "^4.19.2",
|
|
73
|
+
"typescript": "^5.8.3",
|
|
74
|
+
"typescript-eslint": "^8.32.1",
|
|
75
|
+
"vitest": "^3.0.0"
|
|
76
|
+
},
|
|
77
|
+
"lint-staged": {
|
|
78
|
+
"*.{ts,js,json,md}": [
|
|
79
|
+
"biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
|
|
80
|
+
],
|
|
81
|
+
"src/**/*.ts": ["eslint --fix --max-warnings=0 --no-warn-ignored"]
|
|
82
|
+
},
|
|
83
|
+
"config": {
|
|
84
|
+
"commitizen": {
|
|
85
|
+
"path": "cz-conventional-changelog"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"engines": {
|
|
89
|
+
"node": ">=22"
|
|
90
|
+
},
|
|
91
|
+
"publishConfig": {
|
|
92
|
+
"access": "public"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# If you come from bash you might have to change your $PATH.
|
|
2
|
+
# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH
|
|
3
|
+
|
|
4
|
+
# Path to your Oh My Zsh installation.
|
|
5
|
+
export ZSH="$HOME/.oh-my-zsh"
|
|
6
|
+
|
|
7
|
+
# Set name of the theme to load --- if set to "random", it will
|
|
8
|
+
# load a random theme each time Oh My Zsh is loaded, in which case,
|
|
9
|
+
# to know which specific one was loaded, run: echo $RANDOM_THEME
|
|
10
|
+
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
|
|
11
|
+
ZSH_THEME="devcontainers"
|
|
12
|
+
|
|
13
|
+
# Set list of themes to pick from when loading at random
|
|
14
|
+
# Setting this variable when ZSH_THEME="devcontainers"
|
|
15
|
+
# a theme from this variable instead of looking in $ZSH/themes/
|
|
16
|
+
# If set to an empty array, this variable will have no effect.
|
|
17
|
+
# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" )
|
|
18
|
+
|
|
19
|
+
# Uncomment the following line to use case-sensitive completion.
|
|
20
|
+
# CASE_SENSITIVE="true"
|
|
21
|
+
|
|
22
|
+
# Uncomment the following line to use hyphen-insensitive completion.
|
|
23
|
+
# Case-sensitive completion must be off. _ and - will be interchangeable.
|
|
24
|
+
HYPHEN_INSENSITIVE="true"
|
|
25
|
+
|
|
26
|
+
# Uncomment one of the following lines to change the auto-update behavior
|
|
27
|
+
zstyle ':omz:update' mode disabled # disable automatic updates
|
|
28
|
+
# zstyle ':omz:update' mode auto # update automatically without asking
|
|
29
|
+
# zstyle ':omz:update' mode reminder # just remind me to update when it's time
|
|
30
|
+
|
|
31
|
+
# Uncomment the following line to change how often to auto-update (in days).
|
|
32
|
+
# zstyle ':omz:update' frequency 13
|
|
33
|
+
|
|
34
|
+
# Uncomment the following line if pasting URLs and other text is messed up.
|
|
35
|
+
# DISABLE_MAGIC_FUNCTIONS="true"
|
|
36
|
+
|
|
37
|
+
# Uncomment the following line to disable colors in ls.
|
|
38
|
+
# DISABLE_LS_COLORS="true"
|
|
39
|
+
|
|
40
|
+
# Uncomment the following line to disable auto-setting terminal title.
|
|
41
|
+
# DISABLE_AUTO_TITLE="true"
|
|
42
|
+
|
|
43
|
+
# Uncomment the following line to enable command auto-correction.
|
|
44
|
+
# ENABLE_CORRECTION="true"
|
|
45
|
+
|
|
46
|
+
# Uncomment the following line to display red dots whilst waiting for completion.
|
|
47
|
+
# You can also set it to another string to have that shown instead of the default red dots.
|
|
48
|
+
# e.g. COMPLETION_WAITING_DOTS="%F{yellow}waiting...%f"
|
|
49
|
+
# Caution: this setting can cause issues with multiline prompts in zsh < 5.7.1 (see #5765)
|
|
50
|
+
# COMPLETION_WAITING_DOTS="true"
|
|
51
|
+
|
|
52
|
+
# Uncomment the following line if you want to disable marking untracked files
|
|
53
|
+
# under VCS as dirty. This makes repository status check for large repositories
|
|
54
|
+
# much, much faster.
|
|
55
|
+
DISABLE_UNTRACKED_FILES_DIRTY="true"
|
|
56
|
+
|
|
57
|
+
# Uncomment the following line if you want to change the command execution time
|
|
58
|
+
# stamp shown in the history command output.
|
|
59
|
+
# You can set one of the optional three formats:
|
|
60
|
+
# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
|
|
61
|
+
# or set a custom format using the strftime function format specifications,
|
|
62
|
+
# see 'man strftime' for details.
|
|
63
|
+
# HIST_STAMPS="mm/dd/yyyy"
|
|
64
|
+
|
|
65
|
+
# Would you like to use another custom folder than $ZSH/custom?
|
|
66
|
+
# ZSH_CUSTOM=/path/to/new-custom-folder
|
|
67
|
+
|
|
68
|
+
# cut loading time in half
|
|
69
|
+
DISABLE_MAGIC_FUNCTIONS="true"
|
|
70
|
+
DISABLE_COMPFIX="true"
|
|
71
|
+
|
|
72
|
+
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE="20"
|
|
73
|
+
ZSH_AUTOSUGGEST_USE_ASYNC=1
|
|
74
|
+
|
|
75
|
+
# Which plugins would you like to load?
|
|
76
|
+
# Standard plugins can be found in $ZSH/plugins/
|
|
77
|
+
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
|
|
78
|
+
# Example format: plugins=(rails git textmate ruby lighthouse)
|
|
79
|
+
# Add wisely, as too many plugins slow down shell startup.
|
|
80
|
+
plugins=(
|
|
81
|
+
eza
|
|
82
|
+
asdf
|
|
83
|
+
git
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# eza config
|
|
87
|
+
zstyle ':omz:plugins:eza' 'dirs-first' yes
|
|
88
|
+
zstyle ':omz:plugins:eza' 'git-status' yes
|
|
89
|
+
zstyle ':omz:plugins:eza' 'header' yes
|
|
90
|
+
zstyle ':omz:plugins:eza' 'icons' yes
|
|
91
|
+
zstyle ':omz:plugins:eza' 'hyperlink' yes
|
|
92
|
+
|
|
93
|
+
# Skip compaudit check - speeds up compinit
|
|
94
|
+
skip_global_compinit=1
|
|
95
|
+
|
|
96
|
+
# Load compinit with cache checking (once per day)
|
|
97
|
+
autoload -Uz compinit
|
|
98
|
+
if [[ -n ${ZDOTDIR:-$HOME}/.zcompdump(#qNmh+24) ]]; then
|
|
99
|
+
compinit
|
|
100
|
+
else
|
|
101
|
+
compinit -C
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
if [[ -o interactive ]]; then
|
|
105
|
+
source $ZSH/oh-my-zsh.sh
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# User configuration
|
|
109
|
+
export MANPATH="/usr/local/man:$MANPATH"
|
|
110
|
+
export LANG=en_US.UTF-8
|
|
111
|
+
|
|
112
|
+
# moor pager (mirrors local macOS settings)
|
|
113
|
+
if command -v moor >/dev/null 2>&1; then
|
|
114
|
+
export MOOR='-no-clear-on-exit -quit-if-one-screen -reformat -tab-size 4'
|
|
115
|
+
export PAGER=moor
|
|
116
|
+
export MANPAGER=moor
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Claude Code
|
|
120
|
+
export ENABLE_EXPERIMENTAL_MCP_CLI=true
|
|
121
|
+
export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
|
|
122
|
+
|
|
123
|
+
# in-container claude runs without permission prompts
|
|
124
|
+
alias claude='claude --dangerously-skip-permissions'
|
|
125
|
+
|
|
126
|
+
# opencode
|
|
127
|
+
export OPENCODE_AGENT_SKILLS_SUPERPOWERS_MODE=true
|
|
128
|
+
|
|
129
|
+
if command -v eza >/dev/null 2>&1; then
|
|
130
|
+
alias ls='eza --long --all -g --git --sort name --group --group-directories-first --icons'
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# fzf key bindings + completion
|
|
134
|
+
[ -f /usr/share/doc/fzf/examples/key-bindings.zsh ] && source /usr/share/doc/fzf/examples/key-bindings.zsh
|
|
135
|
+
[ -f /usr/share/doc/fzf/examples/completion.zsh ] && source /usr/share/doc/fzf/examples/completion.zsh
|
|
136
|
+
|
|
137
|
+
# zsh shortcuts
|
|
138
|
+
alias reload='source ~/.zshrc'
|
|
139
|
+
|
|
140
|
+
# pnpm
|
|
141
|
+
alias pn=pnpm
|
|
142
|
+
|
|
143
|
+
if [[ -o interactive ]]; then
|
|
144
|
+
eval "$(oh-my-posh init zsh --config ~/.mytheme.omp.yaml)"
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
set -aU path
|
|
148
|
+
|
|
149
|
+
# source optional runtime env files installed by asdf
|
|
150
|
+
set -aU includes
|
|
151
|
+
includes=(
|
|
152
|
+
"${ASDF_DATA_DIR:-/home/vscode/.asdf}/installs/rust/stable/env"
|
|
153
|
+
"${ASDF_DATA_DIR:-/home/vscode/.asdf}/installs/gcloud/"*".0.0/path.zsh.inc"
|
|
154
|
+
"${ASDF_DATA_DIR:-/home/vscode/.asdf}/installs/gcloud/"*".0.0/completion.zsh.inc"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
for file in $includes; do
|
|
158
|
+
[[ -f $file ]] && . $file
|
|
159
|
+
done
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Dependency Auto-Discovery
|
|
2
|
+
|
|
3
|
+
`scripts/discover-deps.sh` runs automatically on every `postAttachCommand` (each time you
|
|
4
|
+
attach VS Code to the running container). It scans the workspace root for known manifest and
|
|
5
|
+
lock files, then installs dependencies using the appropriate tool.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Detection logic
|
|
10
|
+
|
|
11
|
+
Detection runs in this exact order. Within each language, the first matching file wins.
|
|
12
|
+
|
|
13
|
+
| Signal file | Tool invoked | Notes |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `pnpm-lock.yaml` | `pnpm install` | Respects workspace root |
|
|
16
|
+
| `bun.lockb` | `bun install` | |
|
|
17
|
+
| `yarn.lock` | `yarn install` | |
|
|
18
|
+
| `package-lock.json` | `npm ci` | Strict reproducible install |
|
|
19
|
+
| `package.json` (no lock) | `npm install` | Creates a lock file |
|
|
20
|
+
| `pyproject.toml` | `uv sync` | Falls back silently if uv fails |
|
|
21
|
+
| `requirements.txt` | `uv pip install -r` | Falls back to pip if uv unavailable |
|
|
22
|
+
| `Cargo.toml` | `cargo fetch` | Pre-fetches crates; does not build |
|
|
23
|
+
| `go.mod` | `go mod download` | Pre-fetches modules |
|
|
24
|
+
| `Gemfile` | `bundle install` | Only if `bundle` is in PATH |
|
|
25
|
+
| `.devcontainer/custom-setup.sh` | `bash .devcontainer/custom-setup.sh` | Always runs last |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Per-project customization
|
|
30
|
+
|
|
31
|
+
Create `.devcontainer/custom-setup.sh` in the project repo to add anything
|
|
32
|
+
that the auto-detection above doesn't cover.
|
|
33
|
+
|
|
34
|
+
The `init-project.sh` CLI creates a stub for you automatically:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
devcontainer-init # bootstraps .devcontainer/ into the current repo
|
|
38
|
+
devcontainer-init ~/github/myrepo # target a specific directory
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Example `custom-setup.sh`
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
#!/usr/bin/env bash
|
|
45
|
+
# Install a project-specific global CLI
|
|
46
|
+
npm install -g @myorg/internal-cli
|
|
47
|
+
|
|
48
|
+
# Seed the local Postgres database on first attach
|
|
49
|
+
psql -U postgres -c "CREATE DATABASE myapp;" 2>/dev/null || true
|
|
50
|
+
psql -U postgres myapp < db/seed.sql 2>/dev/null || true
|
|
51
|
+
|
|
52
|
+
# Export a project-specific env var into the shell
|
|
53
|
+
echo 'export MY_PROJECT_MODE=devcontainer' >> ~/.zshrc
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Extending for a multi-service repo
|
|
57
|
+
|
|
58
|
+
If your repo has sub-packages in a monorepo layout, the auto-detection only looks at the
|
|
59
|
+
workspace root. Use `custom-setup.sh` to install nested deps:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
#!/usr/bin/env bash
|
|
63
|
+
pnpm install --filter ./packages/api
|
|
64
|
+
pnpm install --filter ./packages/web
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Skipping discovery
|
|
70
|
+
|
|
71
|
+
Set `DISCOVER_DEPS_SKIP=1` to prevent any installation:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
// devcontainer.json
|
|
75
|
+
"remoteEnv": {
|
|
76
|
+
"DISCOVER_DEPS_SKIP": "1"
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Or export it inside the container at runtime:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
export DISCOVER_DEPS_SKIP=1
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Troubleshooting
|
|
89
|
+
|
|
90
|
+
**Discovery ran but dependencies are missing**
|
|
91
|
+
|
|
92
|
+
Check that the lock file is at the workspace root (not in a subfolder). If you have a
|
|
93
|
+
non-standard layout, add the install to `custom-setup.sh`.
|
|
94
|
+
|
|
95
|
+
**`uv sync` failed silently**
|
|
96
|
+
|
|
97
|
+
The script uses `uv sync 2>/dev/null || true` so it doesn't abort a partial environment.
|
|
98
|
+
Run `uv sync` manually to see the full error output.
|
|
99
|
+
|
|
100
|
+
**Discovery is slow on every attach**
|
|
101
|
+
|
|
102
|
+
Package managers like `pnpm install` and `npm ci` are fast when the lock file hasn't
|
|
103
|
+
changed (they skip work). If your repo is large and you want to skip it, set
|
|
104
|
+
`DISCOVER_DEPS_SKIP=1` in `remoteEnv`.
|
|
105
|
+
|
|
106
|
+
**I want to add a new language**
|
|
107
|
+
|
|
108
|
+
Edit `scripts/discover-deps.sh` — the structure is straightforward. Then update the
|
|
109
|
+
detection table above and add the tool to `TOOLS.md`.
|