@danieljvdm/dev-kit 0.11.3 → 0.13.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 (79) hide show
  1. package/README.md +111 -78
  2. package/dev-kit.example.jsonc +0 -4
  3. package/package.json +10 -6
  4. package/schema/dev-kit.schema.json +1 -46
  5. package/skills/build-effect-apis/SKILL.md +77 -0
  6. package/skills/build-effect-apis/agents/openai.yaml +4 -0
  7. package/skills/build-effect-apis/references/cloudflare-workers.md +71 -0
  8. package/skills/build-effect-apis/references/effect-atom-client.md +161 -0
  9. package/skills/build-effect-apis/references/effect-atom-lifecycle.md +78 -0
  10. package/skills/build-effect-apis/references/effect-atom-testing.md +74 -0
  11. package/skills/build-effect-apis/references/runtime-assembly.md +56 -0
  12. package/skills/build-effect-apis/references/server-and-middleware.md +174 -0
  13. package/skills/build-effect-apis/references/shared-contracts.md +108 -0
  14. package/skills/build-effect-apis/references/tanstack-start.md +86 -0
  15. package/skills/build-effect-apis/references/verification.md +50 -0
  16. package/skills/build-effect-clis/SKILL.md +61 -0
  17. package/skills/build-effect-clis/agents/openai.yaml +4 -0
  18. package/skills/build-effect-clis/references/command-design.md +93 -0
  19. package/skills/build-effect-clis/references/entrypoints-and-testing.md +59 -0
  20. package/skills/build-effect-clis/references/processes-and-platform.md +73 -0
  21. package/skills/dev-kit/SKILL.md +77 -48
  22. package/skills/effect-architecture-audit/SKILL.md +26 -0
  23. package/skills/effect-architecture-audit/agents/openai.yaml +4 -0
  24. package/skills/effect-architecture-audit/references/service-and-boundary-audit.md +150 -0
  25. package/skills/effect-ts/SKILL.md +21 -256
  26. package/skills/effect-ts/agents/openai.yaml +3 -3
  27. package/skills/testing/SKILL.md +5 -0
  28. package/src/catalog-manager.ts +16 -17
  29. package/src/catalog.ts +71 -16
  30. package/src/effect-source.ts +46 -24
  31. package/src/effect-tsgo.ts +86 -24
  32. package/src/gitignore.ts +5 -5
  33. package/src/index.ts +3 -6
  34. package/src/manifest.ts +0 -34
  35. package/src/node-symbolic-link.ts +2 -2
  36. package/src/oxfmt.js +5 -0
  37. package/src/oxfmt.ts +5 -0
  38. package/src/oxlint.js +5 -0
  39. package/src/oxlint.ts +5 -0
  40. package/src/package-skill-source.ts +51 -59
  41. package/src/path-digest.ts +7 -7
  42. package/src/project-package.ts +8 -7
  43. package/src/project-process-lock.ts +17 -12
  44. package/src/project-state.ts +1 -1
  45. package/src/skill-manager.ts +18 -16
  46. package/src/skill-selector.ts +12 -0
  47. package/src/sync.ts +181 -131
  48. package/src/tool-ignore-patterns.js +9 -0
  49. package/src/tool-ignore-patterns.ts +15 -0
  50. package/src/vendor.ts +67 -61
  51. package/src/vite-plus-dependency.ts +10 -11
  52. package/src/vite-plus-hooks.ts +24 -14
  53. package/src/vite-plus-quality.ts +21 -172
  54. package/src/vite-plus.js +81 -0
  55. package/src/vite-plus.ts +102 -0
  56. package/templates/AGENTS.md +1 -1
  57. package/skills/effect-ts/UPSTREAM.md +0 -28
  58. package/skills/effect-ts/references/atom-cache-lifecycle.md +0 -78
  59. package/skills/effect-ts/references/atom-http-and-invalidation.md +0 -97
  60. package/skills/effect-ts/references/atom-tanstack-start.md +0 -69
  61. package/skills/effect-ts/references/atom-testing.md +0 -67
  62. package/skills/effect-ts/references/audit-services.md +0 -144
  63. package/skills/effect-ts/references/features.md +0 -525
  64. package/skills/effect-ts/references/guide-atom-data-fetching.md +0 -44
  65. package/skills/effect-ts/references/guide-cli.md +0 -107
  66. package/skills/effect-ts/references/guide-datetime.md +0 -72
  67. package/skills/effect-ts/references/guide-effect.md +0 -440
  68. package/skills/effect-ts/references/guide-error-handling.md +0 -565
  69. package/skills/effect-ts/references/guide-http-boundaries.md +0 -55
  70. package/skills/effect-ts/references/guide-layers.md +0 -989
  71. package/skills/effect-ts/references/guide-observability.md +0 -746
  72. package/skills/effect-ts/references/guide-retries.md +0 -434
  73. package/skills/effect-ts/references/guide-schedule.md +0 -343
  74. package/skills/effect-ts/references/guide-schema.md +0 -664
  75. package/skills/effect-ts/references/guide-sql.md +0 -536
  76. package/skills/effect-ts/references/guide-testing.md +0 -532
  77. package/skills/effect-ts/references/guide-type-safety-and-boundaries.md +0 -131
  78. package/skills/effect-ts/references/version-and-source.md +0 -86
  79. package/templates/vite-plus/vite.config.ts +0 -22
@@ -9,7 +9,7 @@ import { DevKitManifestSchema } from "./manifest.ts";
9
9
  import { observeSymbolicLink } from "./node-symbolic-link.ts";
10
10
  import { runProjectSkillPlan } from "./sync.ts";
11
11
 
12
- class SkillManagerError extends Schema.TaggedErrorClass<SkillManagerError>()("SkillManagerError", {
12
+ class SkillManagerError extends Schema.TaggedError<SkillManagerError>()("SkillManagerError", {
13
13
  message: Schema.String,
14
14
  }) {}
15
15
 
@@ -32,7 +32,7 @@ const resolvePaths = Effect.fn("resolveSkillManagerPaths")(function* (options: M
32
32
  const candidate = options.manifestPath ?? "dev-kit.jsonc";
33
33
 
34
34
  if (candidate.length === 0 || path.isAbsolute(candidate)) {
35
- return yield* new SkillManagerError({
35
+ return yield* SkillManagerError.make({
36
36
  message: "--manifest must be a non-empty project-relative path",
37
37
  });
38
38
  }
@@ -40,7 +40,7 @@ const resolvePaths = Effect.fn("resolveSkillManagerPaths")(function* (options: M
40
40
  const relative = path.relative(projectDir, manifestPath);
41
41
 
42
42
  if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
43
- return yield* new SkillManagerError({
43
+ return yield* SkillManagerError.make({
44
44
  message: "--manifest must resolve inside the project",
45
45
  });
46
46
  }
@@ -49,7 +49,7 @@ const resolvePaths = Effect.fn("resolveSkillManagerPaths")(function* (options: M
49
49
  for (const segment of relative.split(path.sep).slice(0, -1)) {
50
50
  ancestor = path.join(ancestor, segment);
51
51
  if ((yield* observeSymbolicLink(ancestor)).kind === "symlink") {
52
- return yield* new SkillManagerError({
52
+ return yield* SkillManagerError.make({
53
53
  message: `manifest ancestor is a symlink: ${path.relative(projectDir, ancestor)}`,
54
54
  });
55
55
  }
@@ -57,10 +57,12 @@ const resolvePaths = Effect.fn("resolveSkillManagerPaths")(function* (options: M
57
57
  const destination = yield* observeSymbolicLink(manifestPath);
58
58
 
59
59
  if (destination.kind === "symlink") {
60
- return yield* new SkillManagerError({ message: `manifest is a symlink: ${relative}` });
60
+ return yield* SkillManagerError.make({ message: `manifest is a symlink: ${relative}` });
61
61
  }
62
62
  if (destination.kind === "not-symlink" && (yield* fs.stat(manifestPath)).type !== "File") {
63
- return yield* new SkillManagerError({ message: `manifest is not a regular file: ${relative}` });
63
+ return yield* SkillManagerError.make({
64
+ message: `manifest is not a regular file: ${relative}`,
65
+ });
64
66
  }
65
67
 
66
68
  return {
@@ -128,7 +130,7 @@ const readManifest = Effect.fn("readManagedSkillManifest")(function* (
128
130
 
129
131
  if (!(yield* fs.exists(paths.manifestPath))) {
130
132
  if (!create) {
131
- return yield* new SkillManagerError({
133
+ return yield* SkillManagerError.make({
132
134
  message: "dev-kit.jsonc not found. Run `dev-kit init` first.",
133
135
  });
134
136
  }
@@ -139,11 +141,11 @@ const readManifest = Effect.fn("readManagedSkillManifest")(function* (
139
141
  const parsed = parseJsonc(raw, errors, { allowTrailingComma: true });
140
142
 
141
143
  if (errors.length > 0) {
142
- return yield* new SkillManagerError({ message: `could not parse ${paths.manifestPath}` });
144
+ return yield* SkillManagerError.make({ message: `could not parse ${paths.manifestPath}` });
143
145
  }
144
- const manifest = yield* Schema.decodeUnknownEffect(DevKitManifestSchema)(parsed).pipe(
145
- Effect.mapError((error) => new SkillManagerError({ message: error.message })),
146
- );
146
+ const manifest = yield* Schema.decodeUnknownEffect(DevKitManifestSchema, {
147
+ onExcessProperty: "error",
148
+ })(parsed).pipe(Effect.mapError((error) => SkillManagerError.make({ message: error.message })));
147
149
 
148
150
  return { ...paths, manifest, raw };
149
151
  });
@@ -272,7 +274,7 @@ export const addSkills = Effect.fn("addManagedSkills")(function* (
272
274
  const unknown = names.filter((name) => !known.has(name));
273
275
 
274
276
  if (unknown.length > 0) {
275
- return yield* new SkillManagerError({
277
+ return yield* SkillManagerError.make({
276
278
  message: `unknown skill${unknown.length === 1 ? "" : "s"}: ${unknown.join(", ")}. Try \`dev-kit search ${unknown[0]}\`.`,
277
279
  });
278
280
  }
@@ -319,7 +321,7 @@ export const removeSkills = Effect.fn("removeManagedSkills")(function* (
319
321
  );
320
322
 
321
323
  if (absent.length > 0) {
322
- return yield* new SkillManagerError({ message: `not selected: ${absent.join(", ")}` });
324
+ return yield* SkillManagerError.make({ message: `not selected: ${absent.join(", ")}` });
323
325
  }
324
326
  const include = current.manifest.include.filter((name) => !names.includes(name));
325
327
  const excluded = new Set(current.manifest.exclude ?? []);
@@ -399,7 +401,7 @@ export const showSkill = Effect.fn("showCatalogSkill")(function* (
399
401
  const catalog = yield* loadSkillCatalog(yield* packageRoot(), paths.projectDir);
400
402
  const skill = catalog.skills.find((candidate) => candidate.selector === name);
401
403
 
402
- if (!skill) return yield* new SkillManagerError({ message: `unknown skill: ${name}` });
404
+ if (!skill) return yield* SkillManagerError.make({ message: `unknown skill: ${name}` });
403
405
  yield* printLine(skill.selector);
404
406
  if (skill.description) yield* printLine(displayValue(skill.description));
405
407
  if (skill.package) {
@@ -436,7 +438,7 @@ export const chooseSkillsToAdd = Effect.fn("chooseSkillsToAdd")(function* (
436
438
  options: ManagerOptions,
437
439
  ) {
438
440
  if (!(yield* isInteractiveTerminal)) {
439
- return yield* new SkillManagerError({
441
+ return yield* SkillManagerError.make({
440
442
  message: "pass one or more skill names, or run this command in a terminal",
441
443
  });
442
444
  }
@@ -471,7 +473,7 @@ export const chooseSkillsToRemove = Effect.fn("chooseSkillsToRemove")(function*
471
473
  options: ManagerOptions,
472
474
  ) {
473
475
  if (!(yield* isInteractiveTerminal)) {
474
- return yield* new SkillManagerError({
476
+ return yield* SkillManagerError.make({
475
477
  message: "pass one or more skill names, or run this command in a terminal",
476
478
  });
477
479
  }
@@ -28,6 +28,18 @@ export const SKILL_SELECTOR_PATTERN =
28
28
 
29
29
  export const isSkillName = (value: string): boolean => SKILL_NAME_PATTERN.test(value);
30
30
 
31
+ /**
32
+ * The package-qualified directory name for an installed package skill. The npm
33
+ * package name keeps its identity in the flattened output: `@` is dropped,
34
+ * every other non-alphanumeric run becomes one dash, and the bare skill name
35
+ * is appended. `@tanstack/table-core#core` installs as
36
+ * `tanstack-table-core-core`.
37
+ */
38
+ export const packageSkillInstallName = (packageName: string, skillName: string): string =>
39
+ `${packageName.replaceAll("@", "")}-${skillName}`
40
+ .replace(/[^a-z0-9]+/g, "-")
41
+ .replace(/^-+|-+$/g, "");
42
+
31
43
  /** Parse an exact, canonical manifest skill selector. */
32
44
  export const parseSkillSelector = (value: string): SkillSelector | undefined => {
33
45
  if (isSkillName(value)) return { type: "static", name: value };