@danieljvdm/dev-kit 0.18.0 → 1.0.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.
Files changed (43) hide show
  1. package/README.md +148 -659
  2. package/package.json +8 -62
  3. package/skills/dev-kit/SKILL.md +42 -212
  4. package/skills/dev-kit/agents/openai.yaml +2 -2
  5. package/skills/dev-kit/references/cloudflare-worker-api.md +37 -0
  6. package/skills/dev-kit/references/default-typescript-repository.md +43 -0
  7. package/skills/dev-kit/references/legacy-eject.md +46 -0
  8. package/skills/dev-kit/references/repository-setup.md +53 -0
  9. package/skills/dev-kit/references/skills.md +35 -0
  10. package/src/bin/dev-kit.ts +142 -127
  11. package/src/eject.ts +715 -0
  12. package/src/legacy-project.ts +67 -0
  13. package/src/oxfmt.ts +1 -4
  14. package/src/oxlint.ts +5 -10
  15. package/src/path-digest.ts +60 -0
  16. package/src/project-skills.ts +722 -0
  17. package/src/tool-metadata.ts +0 -2
  18. package/src/vendor.ts +0 -5
  19. package/src/vite-plus.ts +1 -3
  20. package/dev-kit.example.jsonc +0 -22
  21. package/schema/dev-kit.schema.json +0 -218
  22. package/schema/skill-sources.schema.json +0 -83
  23. package/scripts/sync-anti-slop-runtime.mjs +0 -19
  24. package/src/index.ts +0 -125
  25. package/src/manifest.ts +0 -224
  26. package/src/oxfmt.js +0 -23
  27. package/src/oxlint-plugin-anti-slop/runtime.d.ts +0 -22
  28. package/src/oxlint-plugin-effect.d.ts +0 -19
  29. package/src/oxlint-plugin-style.d.ts +0 -8
  30. package/src/oxlint.js +0 -113
  31. package/src/project-state.ts +0 -122
  32. package/src/scaffold.ts +0 -79
  33. package/src/skill-manager.ts +0 -527
  34. package/src/sync.ts +0 -1935
  35. package/src/tool-ignore-patterns.js +0 -9
  36. package/src/vite-plus-dependency.ts +0 -69
  37. package/src/vite-plus-hooks.ts +0 -175
  38. package/src/vite-plus-workflow.ts +0 -82
  39. package/src/vite-plus.js +0 -88
  40. package/src/worktrunk-config.ts +0 -88
  41. package/templates/AGENTS.md +0 -11
  42. package/templates/vite-plus/github-actions-check.yml +0 -51
  43. package/templates/worktrunk/wt.toml +0 -27
@@ -1,9 +0,0 @@
1
- /** Tool-owned paths excluded by Dev Kit's lint and format presets. */
2
- export const devKitToolIgnorePatterns = [
3
- ".agents/**",
4
- ".claude/**",
5
- ".dev-kit/**",
6
- ".opencode/**",
7
- ".repos/**",
8
- ".vite-hooks/_/**",
9
- ];
@@ -1,69 +0,0 @@
1
- import { Effect, FileSystem, Path, Schema } from "effect";
2
- import semver from "semver";
3
-
4
- import { readDirectDependencyNames } from "./project-package.ts";
5
- import { VITE_PLUS_SUPPORTED_RANGE } from "./tool-metadata.ts";
6
-
7
- const InstalledVitePlusPackageSchema = Schema.fromJsonString(
8
- Schema.Struct({ version: Schema.String }),
9
- );
10
-
11
- export class VitePlusDependencyError extends Schema.TaggedError<VitePlusDependencyError>()(
12
- "VitePlusDependencyError",
13
- { message: Schema.String },
14
- ) {}
15
-
16
- export type InstalledVitePlus = {
17
- readonly version: string;
18
- readonly vpBin: string;
19
- };
20
-
21
- export const validateInstalledVitePlus = Effect.fn("validateInstalledVitePlus")(function* (
22
- projectDir: string,
23
- ) {
24
- const fs = yield* FileSystem.FileSystem;
25
- const path = yield* Path.Path;
26
- const dependencies = yield* readDirectDependencyNames(projectDir);
27
-
28
- if (!dependencies.includes("vite-plus")) {
29
- return yield* VitePlusDependencyError.make({
30
- message: "vite-plus must be a direct project dependency",
31
- });
32
- }
33
- const packagePath = path.join(projectDir, "node_modules", "vite-plus", "package.json");
34
-
35
- if (!(yield* fs.exists(packagePath))) {
36
- return yield* VitePlusDependencyError.make({
37
- message:
38
- "vite-plus must be installed before enabling this setup: node_modules/vite-plus/package.json is missing",
39
- });
40
- }
41
- const installed = yield* fs.readFileString(packagePath).pipe(
42
- Effect.flatMap(Schema.decodeUnknownEffect(InstalledVitePlusPackageSchema)),
43
- Effect.mapError(() =>
44
- VitePlusDependencyError.make({
45
- message: "installed vite-plus package metadata has no valid version",
46
- }),
47
- ),
48
- );
49
-
50
- if (!semver.valid(installed.version)) {
51
- return yield* VitePlusDependencyError.make({
52
- message: `installed vite-plus package metadata has invalid version: ${installed.version}`,
53
- });
54
- }
55
- if (!semver.satisfies(installed.version, VITE_PLUS_SUPPORTED_RANGE)) {
56
- return yield* VitePlusDependencyError.make({
57
- message: `installed vite-plus ${installed.version} is incompatible with @danieljvdm/dev-kit; supported range: ${VITE_PLUS_SUPPORTED_RANGE}`,
58
- });
59
- }
60
- const vpBin = path.join(projectDir, "node_modules", ".bin", "vp");
61
-
62
- if (!(yield* fs.exists(vpBin))) {
63
- return yield* VitePlusDependencyError.make({
64
- message: "vite-plus is installed but node_modules/.bin/vp is missing",
65
- });
66
- }
67
-
68
- return { version: installed.version, vpBin } satisfies InstalledVitePlus;
69
- });
@@ -1,175 +0,0 @@
1
- import { Config, Effect, FileSystem, Path, Schema, Stream } from "effect";
2
- import { ChildProcess } from "effect/unstable/process";
3
-
4
- import { validateInstalledVitePlus } from "./vite-plus-dependency.ts";
5
-
6
- export const VITE_PLUS_HOOKS_DIR = ".vite-hooks";
7
- export const VITE_PLUS_HOOKS_PATH = `${VITE_PLUS_HOOKS_DIR}/_`;
8
-
9
- export type VitePlusHooksPlan = {
10
- readonly action: "configure" | "unchanged" | "skipped";
11
- readonly hooksDir: string;
12
- readonly hooksPath: string;
13
- readonly projectDir: string;
14
- readonly vpBin: string;
15
- };
16
-
17
- export class VitePlusHooksDependencyError extends Schema.TaggedError<VitePlusHooksDependencyError>()(
18
- "VitePlusHooksDependencyError",
19
- { message: Schema.String },
20
- ) {}
21
-
22
- export class VitePlusHooksConflictError extends Schema.TaggedError<VitePlusHooksConflictError>()(
23
- "VitePlusHooksConflictError",
24
- { hooksPath: Schema.String },
25
- ) {
26
- override get message() {
27
- return `core.hooksPath is already set to "${this.hooksPath}"; refusing to replace another Git hook manager`;
28
- }
29
- }
30
-
31
- class VitePlusHooksCommandError extends Schema.TaggedError<VitePlusHooksCommandError>()(
32
- "VitePlusHooksCommandError",
33
- { command: Schema.String, exitCode: Schema.Int, output: Schema.String },
34
- ) {
35
- override get message() {
36
- return this.output.length > 0
37
- ? `${this.command} exited with code ${this.exitCode}: ${this.output}`
38
- : `${this.command} exited with code ${this.exitCode}`;
39
- }
40
- }
41
-
42
- class VitePlusHooksConvergenceError extends Schema.TaggedError<VitePlusHooksConvergenceError>()(
43
- "VitePlusHooksConvergenceError",
44
- { message: Schema.String },
45
- ) {}
46
-
47
- const runCommand = Effect.fn("runVitePlusHooksCommand")(function* (
48
- cwd: string,
49
- command: string,
50
- args: ReadonlyArray<string>,
51
- allowedExitCodes: ReadonlyArray<number> = [0],
52
- ) {
53
- const child = yield* ChildProcess.make(command, args, {
54
- cwd,
55
- stderr: "pipe",
56
- stdout: "pipe",
57
- });
58
- const [output, exitCode] = yield* Effect.all([
59
- Stream.mkString(Stream.decodeText(child.all)),
60
- child.exitCode,
61
- ]);
62
- const trimmed = output.trim();
63
-
64
- if (!allowedExitCodes.includes(exitCode)) {
65
- return yield* VitePlusHooksCommandError.make({
66
- command: [command, ...args].join(" "),
67
- exitCode,
68
- output: trimmed,
69
- });
70
- }
71
-
72
- return { exitCode, output: trimmed };
73
- });
74
-
75
- const hasExecutableFile = Effect.fn("hasExecutableVitePlusHookFile")(function* (filePath: string) {
76
- const fs = yield* FileSystem.FileSystem;
77
-
78
- if (!(yield* fs.exists(filePath))) return false;
79
- const info = yield* fs.stat(filePath);
80
-
81
- return info.type === "File" && (info.mode & 0o111) !== 0;
82
- });
83
-
84
- const hasVitePlusPreCommitHook = Effect.fn("hasVitePlusPreCommitHook")(function* (
85
- filePath: string,
86
- ) {
87
- const fs = yield* FileSystem.FileSystem;
88
-
89
- if (!(yield* fs.exists(filePath))) return false;
90
- const info = yield* fs.stat(filePath);
91
-
92
- return info.type === "File" && (yield* fs.readFileString(filePath)).includes("vp staged");
93
- });
94
-
95
- const inspectVitePlusHooks = Effect.fn("inspectVitePlusHooks")(function* (projectDir: string) {
96
- const path = yield* Path.Path;
97
- const configuredPath = yield* runCommand(
98
- projectDir,
99
- "git",
100
- ["config", "--local", "--get", "core.hooksPath"],
101
- [0, 1],
102
- );
103
- const hooksPath = configuredPath.exitCode === 0 ? configuredPath.output : "";
104
-
105
- if (
106
- hooksPath.length > 0 &&
107
- hooksPath !== VITE_PLUS_HOOKS_PATH &&
108
- hooksPath !== ".husky" &&
109
- !hooksPath.startsWith(".husky/")
110
- ) {
111
- return yield* VitePlusHooksConflictError.make({ hooksPath });
112
- }
113
- const internalDir = path.join(projectDir, VITE_PLUS_HOOKS_DIR, "_");
114
- const [hasLauncher, hasDispatcher, hasPreCommit, hasInternalIgnore] = yield* Effect.all([
115
- hasExecutableFile(path.join(internalDir, "h")),
116
- hasExecutableFile(path.join(internalDir, "pre-commit")),
117
- hasVitePlusPreCommitHook(path.join(projectDir, VITE_PLUS_HOOKS_DIR, "pre-commit")),
118
- FileSystem.FileSystem.pipe(
119
- Effect.flatMap((fs) => fs.readFileString(path.join(internalDir, ".gitignore"))),
120
- Effect.map((contents) => contents.split(/\r?\n/).includes("*")),
121
- Effect.orElseSucceed(() => false),
122
- ),
123
- ]);
124
-
125
- return (
126
- hooksPath === VITE_PLUS_HOOKS_PATH &&
127
- hasLauncher &&
128
- hasDispatcher &&
129
- hasPreCommit &&
130
- hasInternalIgnore
131
- );
132
- });
133
-
134
- export const planVitePlusHooks = Effect.fn("planVitePlusHooks")(function* (projectDir: string) {
135
- const { vpBin } = yield* validateInstalledVitePlus(projectDir).pipe(
136
- Effect.mapError((error) =>
137
- VitePlusHooksDependencyError.make({
138
- message: `${error.message} before enabling setup.vitePlus.hooks`,
139
- }),
140
- ),
141
- );
142
- const viteGitHooks = yield* Config.string("VITE_GIT_HOOKS").pipe(Config.withDefault(""));
143
- const husky = yield* Config.string("HUSKY").pipe(Config.withDefault(""));
144
- const action =
145
- viteGitHooks === "0" || husky === "0"
146
- ? "skipped"
147
- : (yield* inspectVitePlusHooks(projectDir))
148
- ? "unchanged"
149
- : "configure";
150
-
151
- return {
152
- action,
153
- hooksDir: VITE_PLUS_HOOKS_DIR,
154
- hooksPath: VITE_PLUS_HOOKS_PATH,
155
- projectDir,
156
- vpBin,
157
- } satisfies VitePlusHooksPlan;
158
- });
159
-
160
- export const applyVitePlusHooksPlan = Effect.fn("applyVitePlusHooksPlan")(function* (
161
- plan: VitePlusHooksPlan,
162
- ) {
163
- if (plan.action !== "configure") return;
164
- yield* runCommand(plan.projectDir, plan.vpBin, [
165
- "config",
166
- "--no-agent",
167
- "--hooks-dir",
168
- plan.hooksDir,
169
- ]);
170
- if (!(yield* inspectVitePlusHooks(plan.projectDir))) {
171
- return yield* VitePlusHooksConvergenceError.make({
172
- message: `Vite+ hook setup did not converge at ${plan.hooksPath}`,
173
- });
174
- }
175
- });
@@ -1,82 +0,0 @@
1
- import { Effect, Schema } from "effect";
2
-
3
- import { readDirectDependencyNames } from "./project-package.ts";
4
- import { planScaffold, readScaffoldTemplate, replaceUniqueTemplateMarker } from "./scaffold.ts";
5
- import { validateInstalledVitePlus } from "./vite-plus-dependency.ts";
6
-
7
- export const VITE_PLUS_GITHUB_ACTIONS_PATH = ".github/workflows/check.yml";
8
- export const VITE_PLUS_GITHUB_ACTIONS_TEMPLATE = "templates/vite-plus/github-actions-check.yml";
9
-
10
- export class VitePlusWorkflowSupportError extends Schema.TaggedError<VitePlusWorkflowSupportError>()(
11
- "VitePlusWorkflowSupportError",
12
- { message: Schema.String },
13
- ) {}
14
-
15
- const LOCKED_DEV_KIT_COMMAND =
16
- "bun ./node_modules/@danieljvdm/dev-kit/bin/dev-kit.mjs apply --locked";
17
-
18
- export const renderVitePlusWorkflowTemplate = (
19
- template: string,
20
- options: { readonly devKitCommand?: string } = {},
21
- ): string => {
22
- const devKitCommand = options.devKitCommand;
23
-
24
- return devKitCommand === undefined || devKitCommand === LOCKED_DEV_KIT_COMMAND
25
- ? template
26
- : replaceUniqueTemplateMarker(template, LOCKED_DEV_KIT_COMMAND, devKitCommand);
27
- };
28
-
29
- export const validateVitePlusWorkflowSupport = Effect.fn("validateVitePlusWorkflowSupport")(
30
- function* (projectDir: string, packageRoot: string, typescriptPackage: string) {
31
- const dependencies = yield* readDirectDependencyNames(projectDir);
32
- const required = new Set(["effect", "@effect/tsgo", typescriptPackage]);
33
-
34
- yield* validateInstalledVitePlus(projectDir).pipe(
35
- Effect.mapError((error) => VitePlusWorkflowSupportError.make({ message: error.message })),
36
- );
37
-
38
- if (projectDir !== packageRoot) required.add("@danieljvdm/dev-kit");
39
- const missing = [...required].filter((dependency) => !dependencies.includes(dependency));
40
-
41
- if (missing.length > 0) {
42
- return yield* VitePlusWorkflowSupportError.make({
43
- message: `setup.vitePlus.workflow requires direct dependencies: ${missing.join(", ")}`,
44
- });
45
- }
46
- },
47
- );
48
-
49
- export const planVitePlusWorkflow = (options: {
50
- readonly packageRoot: string;
51
- readonly projectDir: string;
52
- readonly effectTsgoEnabled: boolean;
53
- readonly typescriptPackage: string;
54
- }) =>
55
- planScaffold({
56
- projectDir: options.projectDir,
57
- path: VITE_PLUS_GITHUB_ACTIONS_PATH,
58
- content: Effect.gen(function* () {
59
- if (!options.effectTsgoEnabled) {
60
- return yield* VitePlusWorkflowSupportError.make({
61
- message:
62
- "setup.vitePlus.workflow requires setup.effectTsgo.enabled so the scaffolded workflow's typecheck uses the Effect-patched compiler",
63
- });
64
- }
65
- yield* validateVitePlusWorkflowSupport(
66
- options.projectDir,
67
- options.packageRoot,
68
- options.typescriptPackage,
69
- );
70
- const template = yield* readScaffoldTemplate(
71
- options.packageRoot,
72
- VITE_PLUS_GITHUB_ACTIONS_TEMPLATE,
73
- );
74
-
75
- return renderVitePlusWorkflowTemplate(
76
- template,
77
- options.projectDir === options.packageRoot
78
- ? { devKitCommand: "./bin/dev-kit.mjs apply --locked" }
79
- : {},
80
- );
81
- }),
82
- });
package/src/vite-plus.js DELETED
@@ -1,88 +0,0 @@
1
- import { recommendedOxfmtConfig } from "./oxfmt.js";
2
- import { createAbsoluteImportsOxlintOverride, recommendedOxlintConfig } from "./oxlint.js";
3
- import { devKitToolIgnorePatterns } from "./tool-ignore-patterns.js";
4
-
5
- export { devKitToolIgnorePatterns } from "./tool-ignore-patterns.js";
6
-
7
- const shellQuote = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
8
-
9
- const validateWorkspacePackage = (packageDir) => {
10
- const segments = packageDir.split(/[\\/]/);
11
-
12
- if (
13
- packageDir.trim().length === 0 ||
14
- packageDir === "." ||
15
- packageDir === "./" ||
16
- packageDir === ".\\" ||
17
- packageDir.startsWith("/") ||
18
- packageDir.startsWith("\\") ||
19
- /^[A-Za-z]:[\\/]/.test(packageDir) ||
20
- segments.includes("..")
21
- ) {
22
- throw new Error(`workspace package must be a project-relative subdirectory: ${packageDir}`);
23
- }
24
- };
25
-
26
- const createTypecheckTask = (options) => {
27
- if (options?.strategy !== "workspace") {
28
- const command = options?.command ?? "tsc --noEmit";
29
-
30
- if (command.trim().length === 0) throw new Error("typecheck command must not be empty");
31
-
32
- return command;
33
- }
34
- const concurrency = options.concurrency ?? 4;
35
-
36
- if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 32) {
37
- throw new Error("workspace typecheck concurrency must be between 1 and 32");
38
- }
39
- if (options.packages.length === 0) {
40
- throw new Error("workspace typechecking requires at least one package directory");
41
- }
42
- const packages = [...new Set(options.packages)];
43
-
44
- if (packages.length !== options.packages.length) {
45
- throw new Error("workspace typecheck packages must be unique");
46
- }
47
- for (const packageDir of packages) validateWorkspacePackage(packageDir);
48
- const filters = packages
49
- .map((packageDir) => `--filter ${shellQuote(`./${packageDir}`)}`)
50
- .join(" ");
51
-
52
- return {
53
- command: `vp run --cache --concurrency-limit ${concurrency} ${filters} --fail-if-no-match typecheck`,
54
- cache: false,
55
- };
56
- };
57
-
58
- /** Build composable quality defaults for a project-owned Vite+ config. */
59
- export const createRecommendedVitePlusConfig = (options = {}) => {
60
- const ignorePatterns = [...devKitToolIgnorePatterns, ...(options.ignorePatterns ?? [])];
61
- const lintOverrides = options.absoluteImports
62
- ? [
63
- ...recommendedOxlintConfig.overrides,
64
- createAbsoluteImportsOxlintOverride(options.absoluteImports),
65
- ]
66
- : recommendedOxlintConfig.overrides;
67
-
68
- return {
69
- staged: {
70
- "*": "vp check --fix",
71
- },
72
- fmt: {
73
- ...recommendedOxfmtConfig,
74
- ignorePatterns,
75
- },
76
- lint: {
77
- ...recommendedOxlintConfig,
78
- ignorePatterns,
79
- overrides: lintOverrides,
80
- },
81
- run: {
82
- tasks: {
83
- check: ["vp fmt --check", "vp lint", "vp test", "vp run typecheck"],
84
- typecheck: createTypecheckTask(options.typecheck),
85
- },
86
- },
87
- };
88
- };
@@ -1,88 +0,0 @@
1
- import { Effect, Schema } from "effect";
2
-
3
- import {
4
- detectPackageManager,
5
- PACKAGE_MANAGER_COMMANDS,
6
- readDirectDependencyNames,
7
- readProjectPackage,
8
- } from "./project-package.ts";
9
- import { planScaffold, readScaffoldTemplate, replaceUniqueTemplateMarker } from "./scaffold.ts";
10
-
11
- export const WORKTRUNK_CONFIG_PATH = ".config/wt.toml";
12
- export const WORKTRUNK_CONFIG_TEMPLATE = "templates/worktrunk/wt.toml";
13
-
14
- export class WorktrunkConfigSupportError extends Schema.TaggedError<WorktrunkConfigSupportError>()(
15
- "WorktrunkConfigSupportError",
16
- { message: Schema.String },
17
- ) {}
18
-
19
- export type WorktrunkConfigCommands = {
20
- readonly preMerge: string;
21
- readonly install: string;
22
- readonly dev: string;
23
- };
24
-
25
- const TEMPLATE_COMMANDS: WorktrunkConfigCommands = {
26
- preMerge: "vp run check",
27
- install: "vp install",
28
- dev: "vp dev",
29
- };
30
-
31
- export const renderWorktrunkConfigTemplate = (
32
- template: string,
33
- commands: WorktrunkConfigCommands = TEMPLATE_COMMANDS,
34
- ): string => {
35
- const replacements: ReadonlyArray<readonly [string, string]> = [
36
- [`pre-merge = "${TEMPLATE_COMMANDS.preMerge}"`, `pre-merge = "${commands.preMerge}"`],
37
- [`install = "${TEMPLATE_COMMANDS.install}"`, `install = "${commands.install}"`],
38
- [TEMPLATE_COMMANDS.dev, commands.dev],
39
- ];
40
- let rendered = template;
41
-
42
- for (const [marker, replacement] of replacements) {
43
- if (marker === replacement) continue;
44
- rendered = replaceUniqueTemplateMarker(rendered, marker, replacement);
45
- }
46
-
47
- return rendered;
48
- };
49
-
50
- export const resolveWorktrunkConfigCommands = Effect.fn("resolveWorktrunkConfigCommands")(
51
- function* (projectDir: string) {
52
- const dependencies = yield* readDirectDependencyNames(projectDir);
53
-
54
- if (dependencies.includes("vite-plus")) return TEMPLATE_COMMANDS;
55
- const projectPackage = yield* readProjectPackage(projectDir).pipe(
56
- Effect.catchTag("ProjectPackageError", (error) =>
57
- error.message.startsWith("package.json not found:") ? Effect.void : Effect.fail(error),
58
- ),
59
- );
60
- const scripts = projectPackage?.scripts ?? {};
61
-
62
- if (scripts["check"] === undefined) {
63
- return yield* WorktrunkConfigSupportError.make({
64
- message:
65
- 'setup.worktrunk.config requires a direct vite-plus dependency or a root "check" package script for the pre-merge hook',
66
- });
67
- }
68
- const manager = yield* detectPackageManager(projectDir, projectPackage?.packageManager);
69
-
70
- return {
71
- preMerge: "bun run check",
72
- install: PACKAGE_MANAGER_COMMANDS[manager ?? "bun"].install,
73
- dev: "bun run dev",
74
- } satisfies WorktrunkConfigCommands;
75
- },
76
- );
77
-
78
- export const planWorktrunkConfig = (packageRoot: string, projectDir: string) =>
79
- planScaffold({
80
- projectDir,
81
- path: WORKTRUNK_CONFIG_PATH,
82
- content: Effect.gen(function* () {
83
- const template = yield* readScaffoldTemplate(packageRoot, WORKTRUNK_CONFIG_TEMPLATE);
84
- const commands = yield* resolveWorktrunkConfigCommands(projectDir);
85
-
86
- return renderWorktrunkConfigTemplate(template, commands);
87
- }),
88
- });
@@ -1,11 +0,0 @@
1
- <!-- DEV KIT START -->
2
-
3
- # Dev Kit
4
-
5
- This project uses `@danieljvdm/dev-kit` to manage portable agent skills and reproducible setup from `dev-kit.jsonc` and `dev-kit.lock.json`.
6
-
7
- For dev-kit operations, use the `dev-kit` skill and read `{{DEV_KIT_SKILL_PATH}}` before changing managed outputs.
8
-
9
- {{EFFECT_INSTRUCTIONS}}{{PROJECT_COMMAND_POLICY}}
10
-
11
- <!-- DEV KIT END -->
@@ -1,51 +0,0 @@
1
- name: Check
2
-
3
- on:
4
- pull_request:
5
- push:
6
- branches:
7
- - main
8
-
9
- permissions:
10
- contents: read
11
-
12
- concurrency:
13
- group: ${{ github.workflow }}-${{ github.ref }}
14
- cancel-in-progress: true
15
-
16
- jobs:
17
- check:
18
- runs-on: ubuntu-latest
19
- steps:
20
- - name: Check out repository
21
- uses: actions/checkout@v7
22
- with:
23
- persist-credentials: false
24
-
25
- # setup-bun resolves the consumer's packageManager or engines.bun version.
26
- - name: Set up Bun
27
- uses: oven-sh/setup-bun@v2
28
-
29
- - name: Set up Vite+ and install dependencies
30
- uses: voidzero-dev/setup-vp@v1.16.1
31
- with:
32
- # Vite+ version intentionally resolves from the consumer manifest/lock.
33
- node-version: "24"
34
- cache: true
35
- run-install: |
36
- args: ["--frozen-lockfile", "--ignore-scripts"]
37
-
38
- - name: Verify locked Dev Kit setup
39
- run: bun ./node_modules/@danieljvdm/dev-kit/bin/dev-kit.mjs apply --locked
40
-
41
- - name: Check formatting
42
- run: vp fmt --check
43
-
44
- - name: Lint
45
- run: vp lint
46
-
47
- - name: Run tests
48
- run: vp test
49
-
50
- - name: Type check with Effect TypeScript-Go
51
- run: vp run typecheck
@@ -1,27 +0,0 @@
1
- # Worktrunk project hooks, scaffolded by @danieljvdm/dev-kit (setup.worktrunk.config).
2
- # This repository owns the file — edit hooks freely; dev-kit never rewrites it.
3
- # Hooks never run until each user reviews and approves them: wt config approvals add
4
- # Reference: https://worktrunk.dev/hooks/
5
-
6
- # Full validation before a worktree merges back.
7
- pre-merge = "vp run check"
8
-
9
- # Copy gitignored files matched by .worktreeinclude (.env, local caches) from
10
- # the source worktree; without a .worktreeinclude file this is a no-op.
11
- [[pre-start]]
12
- copy-ignored = "wt step copy-ignored --require-include"
13
-
14
- # Install dependencies after ignored files land so the new worktree is runnable.
15
- [[pre-start]]
16
- install = "vp install"
17
-
18
- # Optional per-worktree dev server on a stable branch-derived port; tether stops
19
- # the server when its worktree is removed. Point the command at this
20
- # repository's dev entrypoint (for example add `apps/web` in a monorepo) and
21
- # uncomment:
22
- # [post-start]
23
- # dev = "wt step tether -- vp dev --host 127.0.0.1 --port {{ branch | hash_port }} --strictPort"
24
-
25
- # Optional: show each worktree's dev-server URL in `wt list`:
26
- # [list]
27
- # url = "http://localhost:{{ branch | hash_port }}"