@jml6m/skeletor 0.1.0-alpha.2 → 0.1.0-alpha.6
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 +13 -13
- package/package.json +21 -6
- package/src/index.js +87 -45
- package/templates/csharp/.gitignore.tmpl +16 -0
- package/templates/csharp/Program.cs +1 -1
- package/templates/csharp/ProgramTests.cs +1 -1
- package/templates/csharp/{{{PROJECT_NAME}}.csproj → Project.csproj.tmpl} +1 -1
- package/templates/go/.gitignore.tmpl +24 -0
- package/templates/go/{go.mod → go.mod.tmpl} +1 -1
- package/templates/java/.gitignore.tmpl +16 -0
- package/templates/java/{pom.xml → pom.xml.tmpl} +1 -1
- package/templates/java/src/main/java/{com/example → app}/App.java +2 -2
- package/templates/java/src/test/java/{com/example → app}/AppTest.java +2 -2
- package/templates/javascript/.gitignore.tmpl +31 -0
- package/templates/javascript/.jscpd.json +13 -0
- package/templates/python/.gitignore.tmpl +27 -0
- package/templates/python/{pyproject.toml → pyproject.toml.tmpl} +1 -1
- package/templates/python/template.json +2 -1
- package/templates/rust/.gitignore.tmpl +14 -0
- package/templates/rust/{Cargo.toml → Cargo.toml.tmpl} +1 -0
- package/templates/typescript/.gitignore.tmpl +31 -0
- package/templates/typescript/.jscpd.json +13 -0
- /package/templates/javascript/{package.json → package.json.tmpl} +0 -0
- /package/templates/typescript/{package.json → package.json.tmpl} +0 -0
package/README.md
CHANGED
|
@@ -25,20 +25,20 @@ Each template includes a `template.json` manifest that declares `verifyCommands`
|
|
|
25
25
|
|
|
26
26
|
We use `@clack/prompts` for a modern experience:
|
|
27
27
|
- Beautiful template selector with descriptions/hints when you omit `--template`
|
|
28
|
-
- Prompts for owner and description (
|
|
28
|
+
- Prompts for owner and description (interactive mode only)
|
|
29
29
|
- Confirmation step
|
|
30
30
|
- Proper cancel handling and nice spinners/intro/outro
|
|
31
31
|
|
|
32
|
-
`--
|
|
32
|
+
`--auto` stays fully non-interactive for scripts (requires `--template`). Pass `--owner` / `--description` on the CLI when scaffolding non-interactively.
|
|
33
33
|
|
|
34
34
|
## Pushing to GitHub
|
|
35
35
|
|
|
36
36
|
**Pushing is not automatic.** After every set of changes (new templates, CLI updates, tests, docs), you **must** explicitly:
|
|
37
37
|
1. `git add -A`
|
|
38
38
|
2. `git commit -m "..."` (good message)
|
|
39
|
-
3. `git push origin
|
|
39
|
+
3. `git push -u origin HEAD`
|
|
40
40
|
|
|
41
|
-
See the root `AGENTS.md` for the standing instruction given to agents working on this repo. This ensures the GitHub repo (`https://github.com/jml6m/skeletor`) stays in sync with every request. There is no special Grok Build setting that auto-pushes; it must be done via
|
|
41
|
+
See the root `AGENTS.md` for the standing instruction given to agents working on this repo. This ensures the GitHub repo (`https://github.com/jml6m/skeletor`) stays in sync with every request. There is no special Grok Build setting that auto-pushes; it must be done via explicit git commands in the agent loop (or documented in project instructions like AGENTS.md).
|
|
42
42
|
|
|
43
43
|
## Usage (alpha)
|
|
44
44
|
|
|
@@ -47,18 +47,17 @@ See the root `AGENTS.md` for the standing instruction given to agents working on
|
|
|
47
47
|
node src/index.js new my-project
|
|
48
48
|
|
|
49
49
|
# Or specify
|
|
50
|
-
node src/index.js new my-api --template typescript
|
|
50
|
+
node src/index.js new my-api --template typescript
|
|
51
51
|
|
|
52
|
-
# Non-interactive (
|
|
53
|
-
npx @jml6m/skeletor new my-service --
|
|
52
|
+
# Non-interactive (scripts)
|
|
53
|
+
npx @jml6m/skeletor new my-service --auto --template go --owner jml6m --description "My service"
|
|
54
54
|
```
|
|
55
55
|
|
|
56
56
|
Common flags:
|
|
57
57
|
- `--template <id>` (javascript, typescript, python, go, rust, java, csharp, ...)
|
|
58
|
-
- `--owner
|
|
59
|
-
- `--
|
|
60
|
-
- `--
|
|
61
|
-
- `--no-git`
|
|
58
|
+
- `--owner <user>` / `--description <text>` (for `--auto`, or as interactive defaults)
|
|
59
|
+
- `--auto` (skip all prompts; requires `--template`)
|
|
60
|
+
- `--no-git` (skip git init; git is on by default)
|
|
62
61
|
|
|
63
62
|
After scaffolding, follow the `verifyCommands` from that template's `template.json` (shown in the success message). E.g. for most JS/TS: `npm install && npm run health:full` etc.
|
|
64
63
|
|
|
@@ -84,7 +83,7 @@ Run `skeletor` (or `node src/index.js`) with no args for current help and templa
|
|
|
84
83
|
|
|
85
84
|
```bash
|
|
86
85
|
# From a clone of this repo
|
|
87
|
-
node src/index.js new my-test-project --
|
|
86
|
+
node src/index.js new my-test-project --auto --template javascript
|
|
88
87
|
|
|
89
88
|
cd my-test-project
|
|
90
89
|
npm install
|
|
@@ -124,6 +123,7 @@ The source of truth lives in `templates/<id>/` (each with its own `template.json
|
|
|
124
123
|
|
|
125
124
|
- Edit files inside an existing template → next generation gets the change.
|
|
126
125
|
- Add a whole new `templates/newlang/` with `template.json` + files → it appears in the picker, help, and tests automatically.
|
|
126
|
+
- **Ecosystem manifest files** (e.g. `package.json`, `pyproject.toml`, `Cargo.toml`, `pom.xml`, `*.csproj`, `go.mod`) must be named with a `.tmpl` suffix inside the template (e.g. `package.json.tmpl`). The generator strips the suffix on output, so the generated project sees the conventional filename. This prevents GitHub's dependency graph from treating template dependencies as skeletor's own.
|
|
127
127
|
|
|
128
128
|
Always run `npm test` after template work.
|
|
129
129
|
|
|
@@ -133,7 +133,7 @@ When happy, commit + push (see root `AGENTS.md` for the standing rule).
|
|
|
133
133
|
|
|
134
134
|
Pushing is **explicit** (not automatic). After changes:
|
|
135
135
|
- Run tests
|
|
136
|
-
- `git add -A && git commit -m "..." && git push origin
|
|
136
|
+
- `git add -A && git commit -m "..." && git push -u origin HEAD`
|
|
137
137
|
|
|
138
138
|
See the root `AGENTS.md` (the instruction file for agents) for the exact rule.
|
|
139
139
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jml6m/skeletor",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.6",
|
|
4
4
|
"description": "Efficient scaffolding for custom development. Generates projects wired with personal lint/format/health/release/alias/AGENTS.md conventions.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -9,7 +9,25 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js",
|
|
12
|
-
"test:watch": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --watch"
|
|
12
|
+
"test:watch": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --watch",
|
|
13
|
+
"lint": "npm run lint:encoding",
|
|
14
|
+
"lint:encoding": "node scripts/check-encoding.mjs",
|
|
15
|
+
"audit:ci": "node scripts/audit-ci.mjs",
|
|
16
|
+
"npm:reinstall": "node scripts/reinstall.mjs",
|
|
17
|
+
"git:pull": "node scripts/git-pull-all.mjs",
|
|
18
|
+
"release:patch": "npm version patch && git push --follow-tags",
|
|
19
|
+
"release:minor": "npm version minor && git push --follow-tags",
|
|
20
|
+
"release:major": "npm version major && git push --follow-tags",
|
|
21
|
+
"release:alpha": "npm version prerelease --preid=alpha && git push --follow-tags",
|
|
22
|
+
"publish:dry": "npm publish --dry-run",
|
|
23
|
+
"prepublishOnly": "npm run lint && npm run audit:ci && npm test"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/jml6m/skeletor.git"
|
|
13
31
|
},
|
|
14
32
|
"files": [
|
|
15
33
|
"src",
|
|
@@ -26,7 +44,7 @@
|
|
|
26
44
|
"knip"
|
|
27
45
|
],
|
|
28
46
|
"dependencies": {
|
|
29
|
-
"@clack/prompts": "^
|
|
47
|
+
"@clack/prompts": "^1.5.1"
|
|
30
48
|
},
|
|
31
49
|
"devDependencies": {
|
|
32
50
|
"jest": "^29.7.0"
|
|
@@ -35,8 +53,5 @@
|
|
|
35
53
|
"license": "ISC",
|
|
36
54
|
"engines": {
|
|
37
55
|
"node": ">=20.19.0"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"@clack/prompts": "^1.5.1"
|
|
41
56
|
}
|
|
42
57
|
}
|
package/src/index.js
CHANGED
|
@@ -24,17 +24,19 @@ Usage:
|
|
|
24
24
|
skeletor --help
|
|
25
25
|
|
|
26
26
|
Options:
|
|
27
|
-
--template <name>
|
|
28
|
-
Omit
|
|
29
|
-
--owner <user> GitHub owner/org
|
|
30
|
-
|
|
31
|
-
--
|
|
32
|
-
--
|
|
27
|
+
--template <name> Stack to scaffold (javascript, typescript, python, go, …)
|
|
28
|
+
Omit for an interactive language/stack picker (TTY required)
|
|
29
|
+
--owner <user> GitHub owner/org (default: jml6m; used with --auto or as
|
|
30
|
+
interactive defaults)
|
|
31
|
+
--description <text> Project description (default: generic skeletor blurb)
|
|
32
|
+
--auto Non-interactive; requires --template
|
|
33
|
+
--no-git Skip git init (git is initialized by default)
|
|
33
34
|
|
|
34
35
|
Examples:
|
|
36
|
+
skeletor new my-api # interactive: pick stack, owner, description
|
|
35
37
|
skeletor new my-api --template typescript
|
|
36
|
-
skeletor new my-lib --
|
|
37
|
-
skeletor new my-
|
|
38
|
+
skeletor new my-lib --auto --template go --owner jml6m --description "My CLI tool"
|
|
39
|
+
skeletor new my-lib --auto --template go --no-git
|
|
38
40
|
`;
|
|
39
41
|
|
|
40
42
|
|
|
@@ -47,9 +49,9 @@ function parseArgs(argv) {
|
|
|
47
49
|
command: null,
|
|
48
50
|
name: null,
|
|
49
51
|
template: null, // resolved later, can be interactive
|
|
50
|
-
owner:
|
|
51
|
-
description:
|
|
52
|
-
|
|
52
|
+
owner: null,
|
|
53
|
+
description: null,
|
|
54
|
+
auto: false,
|
|
53
55
|
git: true,
|
|
54
56
|
};
|
|
55
57
|
|
|
@@ -64,9 +66,9 @@ function parseArgs(argv) {
|
|
|
64
66
|
for (let i = 2; i < args.length; i++) {
|
|
65
67
|
const a = args[i];
|
|
66
68
|
if (a === '--template' || a === '-t') result.template = args[++i] || null;
|
|
67
|
-
else if (a === '--owner' || a === '-o') result.owner = args[++i] ||
|
|
68
|
-
else if (a === '--description' || a === '-d') result.description = args[++i] ||
|
|
69
|
-
else if (a === '--
|
|
69
|
+
else if (a === '--owner' || a === '-o') result.owner = args[++i] || null;
|
|
70
|
+
else if (a === '--description' || a === '-d') result.description = args[++i] || null;
|
|
71
|
+
else if (a === '--auto') result.auto = true;
|
|
70
72
|
else if (a === '--no-git') result.git = false;
|
|
71
73
|
else if (!a.startsWith('-') && !result.name) result.name = a;
|
|
72
74
|
}
|
|
@@ -86,6 +88,29 @@ function render(content, vars) {
|
|
|
86
88
|
return out;
|
|
87
89
|
}
|
|
88
90
|
|
|
91
|
+
/** Sanitize a segment for use in Java groupId / Go module paths. */
|
|
92
|
+
function sanitizeIdentifierSegment(value) {
|
|
93
|
+
return String(value).replace(/[^a-zA-Z0-9]/g, '').toLowerCase() || 'example';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Build the full token map passed to copyAndRender. */
|
|
97
|
+
function buildRenderVars({ name, owner, description }) {
|
|
98
|
+
const repoOwner = owner || 'jml6m';
|
|
99
|
+
const ownerSegment = sanitizeIdentifierSegment(repoOwner);
|
|
100
|
+
const namespace = String(name).replace(/-/g, '_');
|
|
101
|
+
return {
|
|
102
|
+
PROJECT_NAME: name,
|
|
103
|
+
REPO_OWNER: repoOwner,
|
|
104
|
+
REPO_NAME: name,
|
|
105
|
+
DESCRIPTION: description || 'A new project scaffolded with skeletor.',
|
|
106
|
+
YEAR: new Date().getFullYear(),
|
|
107
|
+
NAMESPACE: namespace,
|
|
108
|
+
GROUP_ID: `io.github.${ownerSegment}`,
|
|
109
|
+
GO_MODULE: `github.com/${repoOwner}/${name}`,
|
|
110
|
+
REPO_URL: `https://github.com/${repoOwner}/${name}`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
89
114
|
function ensureDir(dir) {
|
|
90
115
|
if (!fs.existsSync(dir)) {
|
|
91
116
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -97,9 +122,11 @@ function copyAndRender(src, dest, vars) {
|
|
|
97
122
|
if (stat.isDirectory()) {
|
|
98
123
|
ensureDir(dest);
|
|
99
124
|
for (const entry of fs.readdirSync(src)) {
|
|
100
|
-
// never copy node_modules
|
|
101
|
-
if (entry === 'node_modules' || entry === '.git') continue;
|
|
102
|
-
|
|
125
|
+
// never copy node_modules, .git, or skeletor manifest inside templates
|
|
126
|
+
if (entry === 'node_modules' || entry === '.git' || entry === 'template.json') continue;
|
|
127
|
+
// strip .tmpl suffix from output filename so e.g. package.json.tmpl → package.json
|
|
128
|
+
const outEntry = entry.endsWith('.tmpl') ? entry.slice(0, -'.tmpl'.length) : entry;
|
|
129
|
+
copyAndRender(path.join(src, entry), path.join(dest, outEntry), vars);
|
|
103
130
|
}
|
|
104
131
|
return;
|
|
105
132
|
}
|
|
@@ -145,13 +172,9 @@ function getTemplatesWithManifests() {
|
|
|
145
172
|
return ids.map((id) => loadTemplateManifest(id));
|
|
146
173
|
}
|
|
147
174
|
|
|
148
|
-
async function chooseTemplateInteractively(templates
|
|
149
|
-
if (
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (!process.stdout.isTTY) {
|
|
154
|
-
return templates[0] ? templates[0].id : null;
|
|
175
|
+
async function chooseTemplateInteractively(templates) {
|
|
176
|
+
if (templates.length === 0) {
|
|
177
|
+
return null;
|
|
155
178
|
}
|
|
156
179
|
|
|
157
180
|
p.intro('💀 Skeletor — pick your scaffolding');
|
|
@@ -163,7 +186,7 @@ async function chooseTemplateInteractively(templates, isYes) {
|
|
|
163
186
|
}));
|
|
164
187
|
|
|
165
188
|
const selected = await p.select({
|
|
166
|
-
message: '
|
|
189
|
+
message: 'What language or stack are you building?',
|
|
167
190
|
options,
|
|
168
191
|
});
|
|
169
192
|
|
|
@@ -175,8 +198,11 @@ async function chooseTemplateInteractively(templates, isYes) {
|
|
|
175
198
|
return selected;
|
|
176
199
|
}
|
|
177
200
|
|
|
201
|
+
const DEFAULT_OWNER = 'jml6m';
|
|
202
|
+
const DEFAULT_DESCRIPTION = 'A new project scaffolded with skeletor.';
|
|
203
|
+
|
|
178
204
|
async function runNew(opts) {
|
|
179
|
-
const { name, git,
|
|
205
|
+
const { name, git, auto } = opts;
|
|
180
206
|
|
|
181
207
|
if (!name || name === '.' || name === '..') {
|
|
182
208
|
logError('❌ Please provide a valid project name (e.g. "my-api").');
|
|
@@ -190,13 +216,28 @@ async function runNew(opts) {
|
|
|
190
216
|
}
|
|
191
217
|
|
|
192
218
|
let chosenTemplateId = opts.template;
|
|
193
|
-
let finalOwner = opts.owner ||
|
|
194
|
-
let finalDesc = opts.description ||
|
|
219
|
+
let finalOwner = opts.owner || DEFAULT_OWNER;
|
|
220
|
+
let finalDesc = opts.description || DEFAULT_DESCRIPTION;
|
|
195
221
|
|
|
196
|
-
const isInteractive = !
|
|
222
|
+
const isInteractive = !auto && process.stdout.isTTY;
|
|
197
223
|
|
|
198
224
|
if (!chosenTemplateId) {
|
|
199
|
-
|
|
225
|
+
if (auto) {
|
|
226
|
+
logError('❌ --auto requires --template <id>. Pick a stack interactively by omitting --auto.');
|
|
227
|
+
logError(` Available: ${allTemplates.map((t) => t.id).join(', ')}`);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
if (!process.stdout.isTTY) {
|
|
231
|
+
logError('❌ No --template provided and this is not an interactive terminal.');
|
|
232
|
+
logError(' Use --auto --template <id> for scripts and piped environments.');
|
|
233
|
+
logError(` Available: ${allTemplates.map((t) => t.id).join(', ')}`);
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
chosenTemplateId = await chooseTemplateInteractively(allTemplates);
|
|
237
|
+
} else if (!process.stdout.isTTY && !auto) {
|
|
238
|
+
logError('❌ --template requires --auto when not running in an interactive terminal.');
|
|
239
|
+
logError(` Example: skeletor new ${name} --auto --template ${chosenTemplateId}`);
|
|
240
|
+
process.exit(1);
|
|
200
241
|
}
|
|
201
242
|
|
|
202
243
|
const templateInfo = allTemplates.find((t) => t.id === chosenTemplateId);
|
|
@@ -206,7 +247,7 @@ async function runNew(opts) {
|
|
|
206
247
|
process.exit(1);
|
|
207
248
|
}
|
|
208
249
|
|
|
209
|
-
//
|
|
250
|
+
// Owner, description, and confirm — interactive only (--auto uses defaults above)
|
|
210
251
|
if (isInteractive) {
|
|
211
252
|
const ownerInput = await p.text({
|
|
212
253
|
message: 'GitHub owner / org',
|
|
@@ -240,14 +281,7 @@ async function runNew(opts) {
|
|
|
240
281
|
process.exit(1);
|
|
241
282
|
}
|
|
242
283
|
|
|
243
|
-
const
|
|
244
|
-
const vars = {
|
|
245
|
-
PROJECT_NAME: name,
|
|
246
|
-
REPO_OWNER: finalOwner,
|
|
247
|
-
REPO_NAME: repoName,
|
|
248
|
-
DESCRIPTION: finalDesc,
|
|
249
|
-
YEAR: new Date().getFullYear(),
|
|
250
|
-
};
|
|
284
|
+
const vars = buildRenderVars({ name, owner: finalOwner, description: finalDesc });
|
|
251
285
|
|
|
252
286
|
p.log.info(`Creating "${name}" using ${templateInfo.name}...`);
|
|
253
287
|
|
|
@@ -266,12 +300,17 @@ async function runNew(opts) {
|
|
|
266
300
|
|
|
267
301
|
p.outro('✅ Done!');
|
|
268
302
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
console.log(
|
|
303
|
+
printPostScaffoldSteps(name, templateInfo.verifyCommands);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Print cd + full verifyCommands list after scaffolding. */
|
|
307
|
+
function printPostScaffoldSteps(projectName, verifyCommands) {
|
|
308
|
+
console.log(` cd ${projectName}`);
|
|
309
|
+
const steps = Array.isArray(verifyCommands) && verifyCommands.length
|
|
310
|
+
? verifyCommands
|
|
311
|
+
: ['Run your language-specific install + test commands'];
|
|
312
|
+
console.log(' Next steps:');
|
|
313
|
+
steps.forEach((cmd) => console.log(` ${cmd}`));
|
|
275
314
|
console.log('\n Edit AGENTS.md (or equivalent) to customize the AI contract.');
|
|
276
315
|
console.log(' Happy scaffolding. Your rules, your choice of stack.\n');
|
|
277
316
|
}
|
|
@@ -303,12 +342,15 @@ function main() {
|
|
|
303
342
|
export {
|
|
304
343
|
parseArgs,
|
|
305
344
|
render,
|
|
345
|
+
buildRenderVars,
|
|
346
|
+
sanitizeIdentifierSegment,
|
|
306
347
|
getAvailableTemplates,
|
|
307
348
|
getTemplatesWithManifests,
|
|
308
349
|
loadTemplateManifest,
|
|
309
350
|
ensureDir,
|
|
310
351
|
copyAndRender,
|
|
311
352
|
runNew,
|
|
353
|
+
printPostScaffoldSteps,
|
|
312
354
|
USAGE,
|
|
313
355
|
};
|
|
314
356
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<TargetFramework>net8.0</TargetFramework>
|
|
6
6
|
<ImplicitUsings>enable</ImplicitUsings>
|
|
7
7
|
<Nullable>enable</Nullable>
|
|
8
|
-
<RootNamespace>{{
|
|
8
|
+
<RootNamespace>{{NAMESPACE}}</RootNamespace>
|
|
9
9
|
</PropertyGroup>
|
|
10
10
|
|
|
11
11
|
<ItemGroup>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
4
4
|
<modelVersion>4.0.0</modelVersion>
|
|
5
5
|
|
|
6
|
-
<groupId>
|
|
6
|
+
<groupId>{{GROUP_ID}}</groupId>
|
|
7
7
|
<artifactId>{{PROJECT_NAME}}</artifactId>
|
|
8
8
|
<version>0.1.0</version>
|
|
9
9
|
<packaging>jar</packaging>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package
|
|
1
|
+
package app;
|
|
2
2
|
|
|
3
3
|
import org.junit.jupiter.api.Test;
|
|
4
4
|
import static org.junit.jupiter.api.Assertions.*;
|
|
@@ -9,4 +9,4 @@ class AppTest {
|
|
|
9
9
|
void helloReturnsGreeting() {
|
|
10
10
|
assertEquals("Hello, tester from {{PROJECT_NAME}}!", App.hello("tester"));
|
|
11
11
|
}
|
|
12
|
-
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
|
|
4
|
+
# Build / output
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
coverage/
|
|
8
|
+
report/
|
|
9
|
+
reports/
|
|
10
|
+
|
|
11
|
+
# Env & secrets
|
|
12
|
+
.env
|
|
13
|
+
.env.*
|
|
14
|
+
*.local
|
|
15
|
+
|
|
16
|
+
# Logs
|
|
17
|
+
*.log
|
|
18
|
+
logs/
|
|
19
|
+
|
|
20
|
+
# OS / editor
|
|
21
|
+
.DS_Store
|
|
22
|
+
Thumbs.db
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
25
|
+
*.swp
|
|
26
|
+
|
|
27
|
+
# Lockfiles that may be noisy in some flows (keep package-lock.json in real projects)
|
|
28
|
+
# package-lock.json
|
|
29
|
+
|
|
30
|
+
# Generated context for AI
|
|
31
|
+
prompt.md
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"threshold": 5,
|
|
3
|
+
"reporters": ["html", "console"],
|
|
4
|
+
"ignore": ["**/node_modules/**", "**/dist/**", "**/build/**", "**/*.spec.ts", "**/*.test.ts"],
|
|
5
|
+
"absolute": true,
|
|
6
|
+
"gitignore": true,
|
|
7
|
+
"minLines": 5,
|
|
8
|
+
"minTokens": 50,
|
|
9
|
+
"formatsExts": {
|
|
10
|
+
"javascript": ["js", "jsx"],
|
|
11
|
+
"typescript": ["ts", "tsx"]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Bytecode / cache
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.pyo
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.mypy_cache/
|
|
7
|
+
.ruff_cache/
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
env/
|
|
13
|
+
|
|
14
|
+
# Build / packaging
|
|
15
|
+
dist/
|
|
16
|
+
build/
|
|
17
|
+
*.egg-info/
|
|
18
|
+
|
|
19
|
+
# Env & secrets
|
|
20
|
+
.env
|
|
21
|
+
.env.*
|
|
22
|
+
|
|
23
|
+
# OS / editor
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
26
|
+
.idea/
|
|
27
|
+
.vscode/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
|
|
4
|
+
# Build / output
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
coverage/
|
|
8
|
+
report/
|
|
9
|
+
reports/
|
|
10
|
+
|
|
11
|
+
# Env & secrets
|
|
12
|
+
.env
|
|
13
|
+
.env.*
|
|
14
|
+
*.local
|
|
15
|
+
|
|
16
|
+
# Logs
|
|
17
|
+
*.log
|
|
18
|
+
logs/
|
|
19
|
+
|
|
20
|
+
# OS / editor
|
|
21
|
+
.DS_Store
|
|
22
|
+
Thumbs.db
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
25
|
+
*.swp
|
|
26
|
+
|
|
27
|
+
# Lockfiles that may be noisy in some flows (keep package-lock.json in real projects)
|
|
28
|
+
# package-lock.json
|
|
29
|
+
|
|
30
|
+
# Generated context for AI
|
|
31
|
+
prompt.md
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"threshold": 5,
|
|
3
|
+
"reporters": ["html", "console"],
|
|
4
|
+
"ignore": ["**/node_modules/**", "**/dist/**", "**/build/**", "**/*.spec.ts", "**/*.test.ts"],
|
|
5
|
+
"absolute": true,
|
|
6
|
+
"gitignore": true,
|
|
7
|
+
"minLines": 5,
|
|
8
|
+
"minTokens": 50,
|
|
9
|
+
"formatsExts": {
|
|
10
|
+
"javascript": ["js", "jsx"],
|
|
11
|
+
"typescript": ["ts", "tsx"]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
File without changes
|
|
File without changes
|