@timothyrusso/config-presets 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/.claude/settings.template.json +41 -0
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/biome/base.json +75 -0
- package/commitlint.config.cjs +26 -0
- package/dist/checks/deps.d.ts +22 -0
- package/dist/checks/deps.d.ts.map +1 -0
- package/dist/checks/deps.js +45 -0
- package/dist/checks/deps.js.map +1 -0
- package/dist/checks/files.d.ts +30 -0
- package/dist/checks/files.d.ts.map +1 -0
- package/dist/checks/files.js +70 -0
- package/dist/checks/files.js.map +1 -0
- package/dist/checks/hooks.d.ts +15 -0
- package/dist/checks/hooks.d.ts.map +1 -0
- package/dist/checks/hooks.js +62 -0
- package/dist/checks/hooks.js.map +1 -0
- package/dist/checks/i18n.d.ts +43 -0
- package/dist/checks/i18n.d.ts.map +1 -0
- package/dist/checks/i18n.js +168 -0
- package/dist/checks/i18n.js.map +1 -0
- package/dist/checks/text.d.ts +30 -0
- package/dist/checks/text.d.ts.map +1 -0
- package/dist/checks/text.js +86 -0
- package/dist/checks/text.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +129 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/init/claudeSettings.d.ts +19 -0
- package/dist/init/claudeSettings.d.ts.map +1 -0
- package/dist/init/claudeSettings.js +23 -0
- package/dist/init/claudeSettings.js.map +1 -0
- package/dist/init/init.d.ts +35 -0
- package/dist/init/init.d.ts.map +1 -0
- package/dist/init/init.js +286 -0
- package/dist/init/init.js.map +1 -0
- package/dist/init/packageJson.d.ts +39 -0
- package/dist/init/packageJson.d.ts.map +1 -0
- package/dist/init/packageJson.js +97 -0
- package/dist/init/packageJson.js.map +1 -0
- package/dist/kitConfig.d.ts +69 -0
- package/dist/kitConfig.d.ts.map +1 -0
- package/dist/kitConfig.js +84 -0
- package/dist/kitConfig.js.map +1 -0
- package/dist/kitConfig.schema.json +163 -0
- package/github/ISSUE_TEMPLATE/config.yml +1 -0
- package/github/ISSUE_TEMPLATE/feature.yml +63 -0
- package/github/pr-checks.yml +153 -0
- package/jest/package.json +3 -0
- package/jest/preset.js +18 -0
- package/lefthook.yml +30 -0
- package/package.json +73 -0
- package/templates/dependency-cruiser.template.mjs +13 -0
- package/templates/eslint.config.template.mjs +11 -0
- package/tsconfig/expo.json +14 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://github.com/timothyrusso/agentic-kit/schema/kit.config.schema.json",
|
|
4
|
+
"title": "kit.config.json",
|
|
5
|
+
"description": "Per-app configuration read by every agentic-kit package and by the Claude Code plugin.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["projectName"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": { "type": "string" },
|
|
11
|
+
"projectName": {
|
|
12
|
+
"description": "Human name of the app, used in agent prompts and run markers.",
|
|
13
|
+
"type": "string",
|
|
14
|
+
"minLength": 1
|
|
15
|
+
},
|
|
16
|
+
"featuresRoot": {
|
|
17
|
+
"description": "Folder that holds the feature modules.",
|
|
18
|
+
"enum": ["features", "src/features"],
|
|
19
|
+
"default": "features"
|
|
20
|
+
},
|
|
21
|
+
"appRoot": {
|
|
22
|
+
"description": "expo-router app folder.",
|
|
23
|
+
"type": "string",
|
|
24
|
+
"minLength": 1,
|
|
25
|
+
"default": "app"
|
|
26
|
+
},
|
|
27
|
+
"github": {
|
|
28
|
+
"description": "GitHub Projects board the agents move issues on.",
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"required": ["projectNumber", "projectId", "statusFieldId", "statusOptions"],
|
|
32
|
+
"properties": {
|
|
33
|
+
"projectNumber": { "type": "integer", "minimum": 1 },
|
|
34
|
+
"projectId": { "type": "string", "minLength": 1 },
|
|
35
|
+
"statusFieldId": { "type": "string", "minLength": 1 },
|
|
36
|
+
"statusOptions": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"additionalProperties": false,
|
|
39
|
+
"required": ["todo", "inProgress", "done"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"todo": { "type": "string", "minLength": 1 },
|
|
42
|
+
"inProgress": { "type": "string", "minLength": 1 },
|
|
43
|
+
"done": { "type": "string", "minLength": 1 }
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"labels": {
|
|
47
|
+
"description": "Labels the agents may apply to issues they write.",
|
|
48
|
+
"type": "array",
|
|
49
|
+
"items": { "type": "string", "minLength": 1 },
|
|
50
|
+
"uniqueItems": true,
|
|
51
|
+
"default": []
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"qa": {
|
|
56
|
+
"description": "Where the QA agents run the app.",
|
|
57
|
+
"type": "object",
|
|
58
|
+
"additionalProperties": false,
|
|
59
|
+
"required": ["targets"],
|
|
60
|
+
"properties": {
|
|
61
|
+
"targets": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": { "enum": ["mobile", "web"] },
|
|
64
|
+
"minItems": 1,
|
|
65
|
+
"uniqueItems": true
|
|
66
|
+
},
|
|
67
|
+
"simulator": {
|
|
68
|
+
"description": "Simulator or device name, e.g. iPhone 17 Pro.",
|
|
69
|
+
"type": "string",
|
|
70
|
+
"minLength": 1
|
|
71
|
+
},
|
|
72
|
+
"metroPort": { "type": "integer", "minimum": 1024, "maximum": 65535 },
|
|
73
|
+
"baseline": {
|
|
74
|
+
"description": "App-specific steps of the baseline QA checks that run for every feature.",
|
|
75
|
+
"type": "object",
|
|
76
|
+
"additionalProperties": false,
|
|
77
|
+
"properties": {
|
|
78
|
+
"setup": {
|
|
79
|
+
"description": "What to do before the checks, e.g. how to sign in with the test account.",
|
|
80
|
+
"type": "string",
|
|
81
|
+
"minLength": 1
|
|
82
|
+
},
|
|
83
|
+
"launch": {
|
|
84
|
+
"description": "What a healthy cold launch reaches, e.g. the Home tab with the greeting.",
|
|
85
|
+
"type": "string",
|
|
86
|
+
"minLength": 1
|
|
87
|
+
},
|
|
88
|
+
"firstScreens": {
|
|
89
|
+
"description": "Screens that must render right after launch.",
|
|
90
|
+
"type": "array",
|
|
91
|
+
"items": { "type": "string", "minLength": 1 },
|
|
92
|
+
"uniqueItems": true
|
|
93
|
+
},
|
|
94
|
+
"navigation": {
|
|
95
|
+
"description": "Primary navigation steps to exercise, one per entry.",
|
|
96
|
+
"type": "array",
|
|
97
|
+
"items": { "type": "string", "minLength": 1 },
|
|
98
|
+
"uniqueItems": true
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"lint": {
|
|
105
|
+
"description": "Options for the kit's lint rules.",
|
|
106
|
+
"type": "object",
|
|
107
|
+
"additionalProperties": false,
|
|
108
|
+
"properties": {
|
|
109
|
+
"allowedHooksInViews": {
|
|
110
|
+
"description": "Hooks a view may call besides its own ViewModel hook.",
|
|
111
|
+
"type": "array",
|
|
112
|
+
"items": { "type": "string", "minLength": 1 },
|
|
113
|
+
"uniqueItems": true,
|
|
114
|
+
"default": []
|
|
115
|
+
},
|
|
116
|
+
"dashes": {
|
|
117
|
+
"description": "Whether em and en dashes are forbidden in code, comments and copy.",
|
|
118
|
+
"enum": ["forbid", "allow"],
|
|
119
|
+
"default": "forbid"
|
|
120
|
+
},
|
|
121
|
+
"layoutTokens": {
|
|
122
|
+
"description": "Horizontal spacing tokens checked by the layout rule.",
|
|
123
|
+
"type": "object",
|
|
124
|
+
"additionalProperties": false,
|
|
125
|
+
"required": ["gutterToken", "spacingImport", "allowlistFile"],
|
|
126
|
+
"properties": {
|
|
127
|
+
"gutterToken": {
|
|
128
|
+
"description": "Name of the only horizontal edge token.",
|
|
129
|
+
"type": "string",
|
|
130
|
+
"minLength": 1
|
|
131
|
+
},
|
|
132
|
+
"spacingImport": { "description": "Import path of the spacing tokens.", "type": "string", "minLength": 1 },
|
|
133
|
+
"allowlistFile": {
|
|
134
|
+
"description": "File listing paths exempt from the rule.",
|
|
135
|
+
"type": "string",
|
|
136
|
+
"minLength": 1
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
"singleSpinner": {
|
|
141
|
+
"description": "Forbid ActivityIndicator in favour of the design system spinner.",
|
|
142
|
+
"type": "boolean",
|
|
143
|
+
"default": false
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"i18n": {
|
|
148
|
+
"description": "Translation catalog checked by the parity and unused-key scripts.",
|
|
149
|
+
"type": "object",
|
|
150
|
+
"additionalProperties": false,
|
|
151
|
+
"required": ["catalogPath", "languages"],
|
|
152
|
+
"properties": {
|
|
153
|
+
"catalogPath": { "type": "string", "minLength": 1 },
|
|
154
|
+
"languages": {
|
|
155
|
+
"type": "array",
|
|
156
|
+
"items": { "type": "string", "minLength": 2 },
|
|
157
|
+
"minItems": 1,
|
|
158
|
+
"uniqueItems": true
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Feature
|
|
2
|
+
description: Describe a feature to be implemented, with clear, testable acceptance criteria.
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Please complete every required section and keep the structure intact.
|
|
10
|
+
A clear description and testable acceptance criteria make the feature faster to
|
|
11
|
+
build and easier to verify.
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: description
|
|
15
|
+
attributes:
|
|
16
|
+
label: Description
|
|
17
|
+
description: Everything needed to build the feature - what it does, expected behaviour, and any constraints. Be specific and self-contained.
|
|
18
|
+
placeholder: |
|
|
19
|
+
As a user, I want ...
|
|
20
|
+
The feature should ...
|
|
21
|
+
Constraints / edge cases: ...
|
|
22
|
+
validations:
|
|
23
|
+
required: true
|
|
24
|
+
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: acceptance-criteria
|
|
27
|
+
attributes:
|
|
28
|
+
label: Acceptance criteria
|
|
29
|
+
description: A checklist of observable, verifiable outcomes. Each item should be independently testable on the device.
|
|
30
|
+
placeholder: |
|
|
31
|
+
- [ ] Given ... when ... then ...
|
|
32
|
+
- [ ] The <screen> shows ...
|
|
33
|
+
- [ ] Tapping <element> navigates to ...
|
|
34
|
+
validations:
|
|
35
|
+
required: true
|
|
36
|
+
|
|
37
|
+
- type: input
|
|
38
|
+
id: screens-affected
|
|
39
|
+
attributes:
|
|
40
|
+
label: Screens affected
|
|
41
|
+
description: Which screens or features this touches.
|
|
42
|
+
placeholder: e.g. Home, Settings
|
|
43
|
+
validations:
|
|
44
|
+
required: false
|
|
45
|
+
|
|
46
|
+
- type: textarea
|
|
47
|
+
id: out-of-scope
|
|
48
|
+
attributes:
|
|
49
|
+
label: Out of scope
|
|
50
|
+
description: Anything explicitly NOT part of this issue, to keep the change focused.
|
|
51
|
+
placeholder: |
|
|
52
|
+
- ...
|
|
53
|
+
validations:
|
|
54
|
+
required: false
|
|
55
|
+
|
|
56
|
+
- type: input
|
|
57
|
+
id: design-link
|
|
58
|
+
attributes:
|
|
59
|
+
label: Design link
|
|
60
|
+
description: Link to the design (Figma, Claude design, Notion, etc.), if any.
|
|
61
|
+
placeholder: https://...
|
|
62
|
+
validations:
|
|
63
|
+
required: false
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
name: PR checks
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: pr-checks-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
check:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
pull-requests: write
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v7
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
- uses: actions/setup-node@v7
|
|
23
|
+
with:
|
|
24
|
+
node-version-file: .nvmrc
|
|
25
|
+
cache: npm
|
|
26
|
+
|
|
27
|
+
- run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Commit messages
|
|
30
|
+
if: github.event_name == 'pull_request'
|
|
31
|
+
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
|
|
32
|
+
|
|
33
|
+
# NOTE: the report goes to a file, not a step output, so the comment script reads it as data
|
|
34
|
+
# and a backtick or `${` in a violation cannot break or inject into the script.
|
|
35
|
+
- name: Architecture
|
|
36
|
+
id: arch
|
|
37
|
+
run: |
|
|
38
|
+
set +e
|
|
39
|
+
npm run --silent check:arch > "$RUNNER_TEMP/arch-report.txt" 2>&1
|
|
40
|
+
code=$?
|
|
41
|
+
cat "$RUNNER_TEMP/arch-report.txt"
|
|
42
|
+
echo "exit_code=$code" >> "$GITHUB_OUTPUT"
|
|
43
|
+
exit $code
|
|
44
|
+
|
|
45
|
+
# NOTE: one marker comment per PR, updated in place and deleted once the violations are fixed.
|
|
46
|
+
# Fork PRs get no write token, so they are skipped rather than failing.
|
|
47
|
+
- name: Architecture violations comment
|
|
48
|
+
if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false && steps.arch.outcome != 'skipped'
|
|
49
|
+
uses: actions/github-script@v9
|
|
50
|
+
env:
|
|
51
|
+
ARCH_EXIT_CODE: ${{ steps.arch.outputs.exit_code }}
|
|
52
|
+
ARCH_REPORT: ${{ runner.temp }}/arch-report.txt
|
|
53
|
+
with:
|
|
54
|
+
script: |
|
|
55
|
+
const fs = require('node:fs');
|
|
56
|
+
const marker = '<!-- arch-violations -->';
|
|
57
|
+
const failed = process.env.ARCH_EXIT_CODE !== '0';
|
|
58
|
+
const report = fs.existsSync(process.env.ARCH_REPORT) ? fs.readFileSync(process.env.ARCH_REPORT, 'utf8') : '';
|
|
59
|
+
|
|
60
|
+
const comments = await github.paginate(github.rest.issues.listComments, {
|
|
61
|
+
owner: context.repo.owner,
|
|
62
|
+
repo: context.repo.repo,
|
|
63
|
+
issue_number: context.issue.number,
|
|
64
|
+
per_page: 100,
|
|
65
|
+
});
|
|
66
|
+
const existing = comments.find(c => (c.body ?? '').startsWith(marker));
|
|
67
|
+
|
|
68
|
+
if (!failed) {
|
|
69
|
+
if (existing) {
|
|
70
|
+
await github.rest.issues.deleteComment({
|
|
71
|
+
owner: context.repo.owner,
|
|
72
|
+
repo: context.repo.repo,
|
|
73
|
+
comment_id: existing.id,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const fence = '`'.repeat(Math.max(3, ...[...report.matchAll(/`+/g)].map(m => m[0].length + 1)));
|
|
80
|
+
const body = [
|
|
81
|
+
marker,
|
|
82
|
+
'## Architecture violations found',
|
|
83
|
+
'',
|
|
84
|
+
'The following dependency-cruiser rules were violated. Fix them before merging.',
|
|
85
|
+
'',
|
|
86
|
+
fence,
|
|
87
|
+
report.slice(-60000),
|
|
88
|
+
fence,
|
|
89
|
+
].join('\n');
|
|
90
|
+
|
|
91
|
+
if (existing) {
|
|
92
|
+
await github.rest.issues.updateComment({
|
|
93
|
+
owner: context.repo.owner,
|
|
94
|
+
repo: context.repo.repo,
|
|
95
|
+
comment_id: existing.id,
|
|
96
|
+
body,
|
|
97
|
+
});
|
|
98
|
+
} else {
|
|
99
|
+
await github.rest.issues.createComment({
|
|
100
|
+
owner: context.repo.owner,
|
|
101
|
+
repo: context.repo.repo,
|
|
102
|
+
issue_number: context.issue.number,
|
|
103
|
+
body,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
- run: npm run check
|
|
108
|
+
|
|
109
|
+
- name: Bundle for iOS (JavaScript only, no native build)
|
|
110
|
+
run: npx expo export --platform ios --output-dir "$RUNNER_TEMP/expo-export"
|
|
111
|
+
|
|
112
|
+
native-changes:
|
|
113
|
+
runs-on: ubuntu-latest
|
|
114
|
+
outputs:
|
|
115
|
+
native: ${{ steps.filter.outputs.native }}
|
|
116
|
+
steps:
|
|
117
|
+
- uses: actions/checkout@v7
|
|
118
|
+
- uses: dorny/paths-filter@v4
|
|
119
|
+
id: filter
|
|
120
|
+
with:
|
|
121
|
+
filters: |
|
|
122
|
+
native:
|
|
123
|
+
- 'ios/**'
|
|
124
|
+
- 'android/**'
|
|
125
|
+
- 'targets/**'
|
|
126
|
+
- 'modules/**'
|
|
127
|
+
- 'plugins/**'
|
|
128
|
+
- 'app.json'
|
|
129
|
+
- 'app.config.*'
|
|
130
|
+
- 'package-lock.json'
|
|
131
|
+
|
|
132
|
+
# NOTE: a template. It builds the iOS app for the simulator only when native code, config
|
|
133
|
+
# plugins, native targets (such as a watch app in `targets/`) or dependencies change. Add a step
|
|
134
|
+
# per extra scheme (a watch target) with its own `-scheme`.
|
|
135
|
+
native:
|
|
136
|
+
needs: native-changes
|
|
137
|
+
if: needs.native-changes.outputs.native == 'true'
|
|
138
|
+
runs-on: macos-latest
|
|
139
|
+
steps:
|
|
140
|
+
- uses: actions/checkout@v7
|
|
141
|
+
- uses: actions/setup-node@v7
|
|
142
|
+
with:
|
|
143
|
+
node-version-file: .nvmrc
|
|
144
|
+
cache: npm
|
|
145
|
+
- run: npm ci
|
|
146
|
+
- run: npx expo prebuild --platform ios --clean
|
|
147
|
+
- name: Build for the simulator
|
|
148
|
+
run: |
|
|
149
|
+
workspace=$(ls -d ios/*.xcworkspace | head -n 1)
|
|
150
|
+
scheme=$(basename "$workspace" .xcworkspace)
|
|
151
|
+
xcodebuild -workspace "$workspace" -scheme "$scheme" -configuration Debug \
|
|
152
|
+
-sdk iphonesimulator -destination 'generic/platform=iOS Simulator' \
|
|
153
|
+
CODE_SIGNING_ALLOWED=NO build
|
package/jest/preset.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jest for an Expo app: `jest-expo`, the `@/` alias mapped to the app root, and tests in
|
|
3
|
+
* `__tests__` folders. Use it as the whole config (`jest.config.cjs`):
|
|
4
|
+
*
|
|
5
|
+
* module.exports = require('@timothyrusso/config-presets/jest');
|
|
6
|
+
*
|
|
7
|
+
* `preset` is resolved from the app's root, so `jest-expo` comes from the app's own
|
|
8
|
+
* `node_modules` at the version `npx expo install jest-expo` picked for its SDK. An app whose alias
|
|
9
|
+
* points somewhere else overrides `moduleNameMapper` in its own config.
|
|
10
|
+
*/
|
|
11
|
+
const preset = {
|
|
12
|
+
preset: 'jest-expo',
|
|
13
|
+
testMatch: ['<rootDir>/**/__tests__/**/*.test.{ts,tsx,js,jsx}'],
|
|
14
|
+
testPathIgnorePatterns: ['/node_modules/', '<rootDir>/(ios|android|dist|coverage|\\.expo)/'],
|
|
15
|
+
moduleNameMapper: { '^@/(.*)$': '<rootDir>/$1' },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = preset;
|
package/lefthook.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# NOTE: installed by the app's `prepare` script (`lefthook install`). There is no bypass: agents
|
|
2
|
+
# are denied `--no-verify` in .claude/settings.json, and CI runs the same checks on every pull
|
|
3
|
+
# request, so a hook skipped locally only moves the failure to the PR.
|
|
4
|
+
# NOTE: relative imports are caught by ESLint (`arch/no-relative-imports`), so there is no grep.
|
|
5
|
+
|
|
6
|
+
pre-commit:
|
|
7
|
+
parallel: true
|
|
8
|
+
commands:
|
|
9
|
+
biome:
|
|
10
|
+
glob: "*.{js,jsx,mjs,cjs,ts,tsx,json,jsonc}"
|
|
11
|
+
run: npx --no-install biome check --write --no-errors-on-unmatched --files-ignore-unknown=true {staged_files}
|
|
12
|
+
stage_fixed: true
|
|
13
|
+
eslint:
|
|
14
|
+
glob: "*.{js,jsx,mjs,cjs,ts,tsx}"
|
|
15
|
+
run: npx --no-install eslint --no-warn-ignored {staged_files}
|
|
16
|
+
text:
|
|
17
|
+
run: npx --no-install config-presets check-text {staged_files}
|
|
18
|
+
|
|
19
|
+
commit-msg:
|
|
20
|
+
commands:
|
|
21
|
+
commitlint:
|
|
22
|
+
run: npx --no-install commitlint --edit {1}
|
|
23
|
+
issue-number:
|
|
24
|
+
run: |
|
|
25
|
+
if ! head -n 1 {1} | grep -qE '^(Merge |Revert |fixup! |squash! )|^[a-z]+\([0-9]+\)!?: .+'; then
|
|
26
|
+
echo "Commit message must be type(issue): message, e.g. feat(12): add the settings screen"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
text:
|
|
30
|
+
run: npx --no-install config-presets check-text --message {1}
|
package/package.json
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@timothyrusso/config-presets",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Biome, commitlint, lefthook, tsconfig, Jest and CI presets, the kit.config.json loader, the check scripts and the init command.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/timothyrusso/agentic-kit.git",
|
|
10
|
+
"directory": "packages/config-presets"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./kit.config.schema.json": "./dist/kitConfig.schema.json",
|
|
18
|
+
"./biome": "./biome/base.json",
|
|
19
|
+
"./commitlint": "./commitlint.config.cjs",
|
|
20
|
+
"./tsconfig/expo.json": "./tsconfig/expo.json",
|
|
21
|
+
"./jest": "./jest/preset.js",
|
|
22
|
+
"./lefthook.yml": "./lefthook.yml",
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"bin": {
|
|
28
|
+
"config-presets": "./dist/cli.js"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"biome",
|
|
33
|
+
"jest",
|
|
34
|
+
"tsconfig",
|
|
35
|
+
"github",
|
|
36
|
+
"templates",
|
|
37
|
+
".claude",
|
|
38
|
+
"commitlint.config.cjs",
|
|
39
|
+
"lefthook.yml"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=22"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -p tsconfig.build.json",
|
|
49
|
+
"typecheck": "tsc --noEmit",
|
|
50
|
+
"test": "NODE_OPTIONS=\"--experimental-vm-modules --no-warnings=ExperimentalWarning\" jest"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"ajv": "^8.20.0",
|
|
54
|
+
"jiti": "^2.7.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"@timothyrusso/arch-rules": "0.1.0",
|
|
58
|
+
"@timothyrusso/eslint-plugin-arch": "0.1.0"
|
|
59
|
+
},
|
|
60
|
+
"peerDependenciesMeta": {
|
|
61
|
+
"@timothyrusso/arch-rules": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"@timothyrusso/eslint-plugin-arch": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@commitlint/config-conventional": "^21.2.3",
|
|
70
|
+
"@commitlint/lint": "^21.2.3",
|
|
71
|
+
"@commitlint/load": "^21.2.3"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createDependencyCruiserConfig } from '@timothyrusso/arch-rules';
|
|
2
|
+
import { loadKitConfig } from '@timothyrusso/config-presets';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Architecture rules generated from each feature's `FEATURE_TIER` and `kit.config.json`: tiers,
|
|
6
|
+
* public API boundaries, layers and Effect placement. Run by `npm run check:arch`. Written by
|
|
7
|
+
* `config-presets init`.
|
|
8
|
+
*
|
|
9
|
+
* @type {import('dependency-cruiser').IConfiguration}
|
|
10
|
+
*/
|
|
11
|
+
export default createDependencyCruiserConfig(loadKitConfig({ cwd: import.meta.dirname }), {
|
|
12
|
+
rootDir: import.meta.dirname,
|
|
13
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { loadKitConfig } from '@timothyrusso/config-presets';
|
|
2
|
+
import arch from '@timothyrusso/eslint-plugin-arch';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ESLint covers only what Biome does not: the kit's architecture rules and `no-restricted-syntax`
|
|
6
|
+
* (no `enum`, no `as Error`), driven by `kit.config.json`. Written by `config-presets init`.
|
|
7
|
+
*/
|
|
8
|
+
export default [
|
|
9
|
+
{ ignores: ['**/node_modules/**', '**/dist/**', '**/coverage/**', '**/.expo/**', 'ios/**', 'android/**'] },
|
|
10
|
+
...arch.configs.recommended(loadKitConfig({ cwd: import.meta.dirname })),
|
|
11
|
+
];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"extends": "expo/tsconfig.base",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"strict": true,
|
|
6
|
+
"noUncheckedIndexedAccess": true,
|
|
7
|
+
"noImplicitOverride": true,
|
|
8
|
+
"noFallthroughCasesInSwitch": true,
|
|
9
|
+
"noUnusedLocals": true,
|
|
10
|
+
"noUnusedParameters": true,
|
|
11
|
+
"verbatimModuleSyntax": true,
|
|
12
|
+
"paths": { "@/*": ["${configDir}/*"] }
|
|
13
|
+
}
|
|
14
|
+
}
|