@danieljvdm/dev-kit 0.17.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.
- package/README.md +148 -648
- package/package.json +19 -62
- package/skills/dev-kit/SKILL.md +42 -213
- package/skills/dev-kit/agents/openai.yaml +2 -2
- package/skills/dev-kit/references/cloudflare-worker-api.md +37 -0
- package/skills/dev-kit/references/default-typescript-repository.md +43 -0
- package/skills/dev-kit/references/legacy-eject.md +46 -0
- package/skills/dev-kit/references/repository-setup.md +53 -0
- package/skills/dev-kit/references/skills.md +35 -0
- package/src/bin/dev-kit.ts +153 -134
- package/src/catalog-manager.ts +23 -18
- package/src/catalog.ts +8 -5
- package/src/cli-ui.ts +2 -2
- package/src/effect-tsgo.ts +10 -6
- package/src/eject.ts +715 -0
- package/src/gitignore.ts +6 -3
- package/src/legacy-project.ts +67 -0
- package/src/oxfmt.ts +1 -4
- package/src/oxlint-plugin-anti-slop/LICENSE +21 -0
- package/src/oxlint-plugin-anti-slop/index.ts +43 -0
- package/src/oxlint-plugin-anti-slop/rules/no-chained-type-assertions.ts +79 -0
- package/src/oxlint-plugin-anti-slop/rules/no-conditional-empty-object-spread.ts +51 -0
- package/src/oxlint-plugin-anti-slop/rules/no-known-value-widening.ts +267 -0
- package/src/oxlint-plugin-anti-slop/rules/no-module-mocking.ts +105 -0
- package/src/oxlint-plugin-anti-slop/rules/no-object-parameters.ts +141 -0
- package/src/oxlint-plugin-anti-slop/rules/no-reflect-apply.ts +28 -0
- package/src/oxlint-plugin-anti-slop/rules/no-reflect-get.ts +28 -0
- package/src/oxlint-plugin-anti-slop/rules/no-runtime-typeof.ts +25 -0
- package/src/oxlint-plugin-anti-slop/rules/no-shape-in-symbol-names.ts +38 -0
- package/src/oxlint-plugin-anti-slop/rules/no-unknown-parameters.ts +86 -0
- package/src/oxlint-plugin-anti-slop/rules/no-unknown-returns.ts +125 -0
- package/src/oxlint-plugin-anti-slop/rules/no-unknown-type-aliases.ts +73 -0
- package/src/oxlint-plugin-anti-slop/rules/no-unsafe-dictionary-type.ts +139 -0
- package/src/oxlint-plugin-anti-slop/rules/no-widen-then-assert.ts +396 -0
- package/src/oxlint-plugin-anti-slop/rules/require-safety-comment-for-type-assertion.ts +61 -0
- package/src/oxlint-plugin-anti-slop/runtime.js +1209 -0
- package/src/oxlint-plugin-anti-slop/shared/dictionary-types.ts +555 -0
- package/src/oxlint-plugin-anti-slop/shared/reflect-method.ts +40 -0
- package/src/oxlint.ts +26 -14
- package/src/package-skill-source.ts +17 -25
- package/src/path-digest.ts +62 -1
- package/src/project-package.ts +14 -12
- package/src/project-skills.ts +722 -0
- package/src/tool-metadata.ts +0 -2
- package/src/vendor.ts +35 -21
- package/src/vite-plus.ts +1 -3
- package/dev-kit.example.jsonc +0 -22
- package/schema/dev-kit.schema.json +0 -218
- package/schema/skill-sources.schema.json +0 -83
- package/src/index.ts +0 -125
- package/src/manifest.ts +0 -216
- package/src/oxfmt.js +0 -23
- package/src/oxlint-plugin-effect.d.ts +0 -17
- package/src/oxlint-plugin-style.d.ts +0 -8
- package/src/oxlint.js +0 -94
- package/src/project-state.ts +0 -122
- package/src/scaffold.ts +0 -79
- package/src/skill-manager.ts +0 -515
- package/src/sync.ts +0 -1919
- package/src/tool-ignore-patterns.js +0 -9
- package/src/vite-plus-dependency.ts +0 -69
- package/src/vite-plus-hooks.ts +0 -175
- package/src/vite-plus-workflow.ts +0 -82
- package/src/vite-plus.js +0 -88
- package/src/worktrunk-config.ts +0 -88
- package/templates/AGENTS.md +0 -11
- package/templates/vite-plus/github-actions-check.yml +0 -51
- package/templates/worktrunk/wt.toml +0 -27
package/src/manifest.ts
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import { Schema } from "effect";
|
|
2
|
-
|
|
3
|
-
import { SKILL_SELECTOR_PATTERN } from "./skill-selector.ts";
|
|
4
|
-
import { TYPESCRIPT_PACKAGE_NAME_PATTERN } from "./typescript-package-name.ts";
|
|
5
|
-
|
|
6
|
-
export type HarnessTarget = "agents" | "claude" | "opencode";
|
|
7
|
-
|
|
8
|
-
export const SyncMode = Schema.Literals(["copy", "symlink"]);
|
|
9
|
-
export type SyncMode = "copy" | "symlink";
|
|
10
|
-
|
|
11
|
-
export const TargetConfigSchema = Schema.Struct({
|
|
12
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
13
|
-
mode: Schema.optional(SyncMode),
|
|
14
|
-
path: Schema.optional(Schema.String),
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
export type TargetConfig = typeof TargetConfigSchema.Type;
|
|
18
|
-
|
|
19
|
-
export const EffectTsgoSetupSchema = Schema.Struct({
|
|
20
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
21
|
-
force: Schema.optional(Schema.Boolean),
|
|
22
|
-
typescriptPackage: Schema.optional(
|
|
23
|
-
Schema.String.check(Schema.isPattern(TYPESCRIPT_PACKAGE_NAME_PATTERN)),
|
|
24
|
-
),
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
export type EffectTsgoSetup = typeof EffectTsgoSetupSchema.Type;
|
|
28
|
-
|
|
29
|
-
export const EffectSourceSetupSchema = Schema.Struct({
|
|
30
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
31
|
-
packageName: Schema.optional(
|
|
32
|
-
Schema.String.check(Schema.isPattern(TYPESCRIPT_PACKAGE_NAME_PATTERN)),
|
|
33
|
-
),
|
|
34
|
-
path: Schema.optional(Schema.String),
|
|
35
|
-
repository: Schema.optional(Schema.String),
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
export type EffectSourceSetup = typeof EffectSourceSetupSchema.Type;
|
|
39
|
-
|
|
40
|
-
export const AgentInstructionsSetupSchema = Schema.Struct({
|
|
41
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
export type AgentInstructionsSetup = typeof AgentInstructionsSetupSchema.Type;
|
|
45
|
-
|
|
46
|
-
export const ClaudeInstructionsSetupSchema = Schema.Struct({
|
|
47
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
export type ClaudeInstructionsSetup = typeof ClaudeInstructionsSetupSchema.Type;
|
|
51
|
-
|
|
52
|
-
export const VitePlusHooksSetupSchema = Schema.Struct({
|
|
53
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
export const VitePlusWorkflowSetupSchema = Schema.Struct({
|
|
57
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
58
|
-
});
|
|
59
|
-
export type VitePlusWorkflowSetup = typeof VitePlusWorkflowSetupSchema.Type;
|
|
60
|
-
|
|
61
|
-
export const VitePlusSetupSchema = Schema.Struct({
|
|
62
|
-
hooks: Schema.optional(VitePlusHooksSetupSchema),
|
|
63
|
-
workflow: Schema.optional(VitePlusWorkflowSetupSchema),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
export type VitePlusSetup = typeof VitePlusSetupSchema.Type;
|
|
67
|
-
|
|
68
|
-
export const WorktrunkConfigSetupSchema = Schema.Struct({
|
|
69
|
-
enabled: Schema.optional(Schema.Boolean),
|
|
70
|
-
});
|
|
71
|
-
export type WorktrunkConfigSetup = typeof WorktrunkConfigSetupSchema.Type;
|
|
72
|
-
|
|
73
|
-
export const WorktrunkSetupSchema = Schema.Struct({
|
|
74
|
-
config: Schema.optional(WorktrunkConfigSetupSchema),
|
|
75
|
-
});
|
|
76
|
-
export type WorktrunkSetup = typeof WorktrunkSetupSchema.Type;
|
|
77
|
-
|
|
78
|
-
export const DevKitManifestSchema = Schema.Struct({
|
|
79
|
-
$schema: Schema.optional(Schema.String),
|
|
80
|
-
include: Schema.Array(Schema.String.check(Schema.isPattern(SKILL_SELECTOR_PATTERN))),
|
|
81
|
-
exclude: Schema.optional(
|
|
82
|
-
Schema.Array(Schema.String.check(Schema.isPattern(SKILL_SELECTOR_PATTERN))),
|
|
83
|
-
),
|
|
84
|
-
setup: Schema.optional(
|
|
85
|
-
Schema.Struct({
|
|
86
|
-
agentInstructions: Schema.optional(AgentInstructionsSetupSchema),
|
|
87
|
-
claudeInstructions: Schema.optional(ClaudeInstructionsSetupSchema),
|
|
88
|
-
effectSource: Schema.optional(EffectSourceSetupSchema),
|
|
89
|
-
effectTsgo: Schema.optional(EffectTsgoSetupSchema),
|
|
90
|
-
vitePlus: Schema.optional(VitePlusSetupSchema),
|
|
91
|
-
worktrunk: Schema.optional(WorktrunkSetupSchema),
|
|
92
|
-
}),
|
|
93
|
-
),
|
|
94
|
-
targets: Schema.optional(
|
|
95
|
-
Schema.Struct({
|
|
96
|
-
agents: Schema.optional(TargetConfigSchema),
|
|
97
|
-
claude: Schema.optional(TargetConfigSchema),
|
|
98
|
-
opencode: Schema.optional(TargetConfigSchema),
|
|
99
|
-
}),
|
|
100
|
-
),
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
export type DevKitManifest = typeof DevKitManifestSchema.Type;
|
|
104
|
-
|
|
105
|
-
export type NormalizedTargetConfig = {
|
|
106
|
-
readonly enabled: boolean;
|
|
107
|
-
readonly mode: SyncMode;
|
|
108
|
-
readonly path: string;
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
export type NormalizedManifest = {
|
|
112
|
-
readonly include: ReadonlyArray<string>;
|
|
113
|
-
readonly exclude: ReadonlyArray<string>;
|
|
114
|
-
readonly setup: {
|
|
115
|
-
readonly agentInstructions: {
|
|
116
|
-
readonly enabled: boolean;
|
|
117
|
-
};
|
|
118
|
-
readonly claudeInstructions: {
|
|
119
|
-
readonly enabled: boolean;
|
|
120
|
-
};
|
|
121
|
-
readonly effectSource: {
|
|
122
|
-
readonly enabled: boolean;
|
|
123
|
-
readonly packageName: string;
|
|
124
|
-
readonly path: string;
|
|
125
|
-
readonly repository: string;
|
|
126
|
-
};
|
|
127
|
-
readonly effectTsgo: {
|
|
128
|
-
readonly enabled: boolean;
|
|
129
|
-
readonly force: boolean;
|
|
130
|
-
readonly typescriptPackage: string;
|
|
131
|
-
};
|
|
132
|
-
readonly vitePlus: {
|
|
133
|
-
readonly hooks: {
|
|
134
|
-
readonly enabled: boolean;
|
|
135
|
-
};
|
|
136
|
-
readonly workflow: {
|
|
137
|
-
readonly enabled: boolean;
|
|
138
|
-
};
|
|
139
|
-
};
|
|
140
|
-
readonly worktrunk: {
|
|
141
|
-
readonly config: {
|
|
142
|
-
readonly enabled: boolean;
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
};
|
|
146
|
-
readonly targets: Readonly<Record<HarnessTarget, NormalizedTargetConfig>>;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const DEFAULT_TARGET_PATHS: Readonly<Record<HarnessTarget, string>> = {
|
|
150
|
-
agents: ".agents/skills",
|
|
151
|
-
claude: ".claude/skills",
|
|
152
|
-
opencode: ".opencode/skills",
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const DEFAULT_TARGETS: Readonly<Record<HarnessTarget, NormalizedTargetConfig>> = {
|
|
156
|
-
agents: { enabled: true, mode: "copy", path: DEFAULT_TARGET_PATHS.agents },
|
|
157
|
-
claude: { enabled: false, mode: "symlink", path: DEFAULT_TARGET_PATHS.claude },
|
|
158
|
-
opencode: { enabled: false, mode: "symlink", path: DEFAULT_TARGET_PATHS.opencode },
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
export const normalizeManifest = (manifest: DevKitManifest): NormalizedManifest => {
|
|
162
|
-
const targets = {
|
|
163
|
-
...DEFAULT_TARGETS,
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
for (const key of ["agents", "claude", "opencode"] as const) {
|
|
167
|
-
const override = manifest.targets?.[key];
|
|
168
|
-
|
|
169
|
-
if (override) {
|
|
170
|
-
targets[key] = {
|
|
171
|
-
enabled: override.enabled ?? DEFAULT_TARGETS[key].enabled,
|
|
172
|
-
mode: override.mode ?? DEFAULT_TARGETS[key].mode,
|
|
173
|
-
path: override.path ?? DEFAULT_TARGETS[key].path,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
exclude: manifest.exclude ?? [],
|
|
180
|
-
include: manifest.include,
|
|
181
|
-
setup: {
|
|
182
|
-
agentInstructions: {
|
|
183
|
-
enabled: manifest.setup?.agentInstructions?.enabled ?? false,
|
|
184
|
-
},
|
|
185
|
-
claudeInstructions: {
|
|
186
|
-
enabled: manifest.setup?.claudeInstructions?.enabled ?? false,
|
|
187
|
-
},
|
|
188
|
-
effectSource: {
|
|
189
|
-
enabled: manifest.setup?.effectSource?.enabled ?? false,
|
|
190
|
-
packageName: manifest.setup?.effectSource?.packageName ?? "effect",
|
|
191
|
-
path: manifest.setup?.effectSource?.path ?? ".repos/effect",
|
|
192
|
-
repository:
|
|
193
|
-
manifest.setup?.effectSource?.repository ?? "https://github.com/Effect-TS/effect.git",
|
|
194
|
-
},
|
|
195
|
-
effectTsgo: {
|
|
196
|
-
enabled: manifest.setup?.effectTsgo?.enabled ?? false,
|
|
197
|
-
force: manifest.setup?.effectTsgo?.force ?? false,
|
|
198
|
-
typescriptPackage: manifest.setup?.effectTsgo?.typescriptPackage ?? "typescript",
|
|
199
|
-
},
|
|
200
|
-
vitePlus: {
|
|
201
|
-
hooks: {
|
|
202
|
-
enabled: manifest.setup?.vitePlus?.hooks?.enabled ?? false,
|
|
203
|
-
},
|
|
204
|
-
workflow: {
|
|
205
|
-
enabled: manifest.setup?.vitePlus?.workflow?.enabled ?? false,
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
worktrunk: {
|
|
209
|
-
config: {
|
|
210
|
-
enabled: manifest.setup?.worktrunk?.config?.enabled ?? false,
|
|
211
|
-
},
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
targets,
|
|
215
|
-
};
|
|
216
|
-
};
|
package/src/oxfmt.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime form of the typed preset declared in oxfmt.ts.
|
|
3
|
-
*
|
|
4
|
-
* This file is intentionally plain JavaScript because Node does not strip
|
|
5
|
-
* TypeScript from packages in node_modules when tools load their config.
|
|
6
|
-
*/
|
|
7
|
-
import { devKitToolIgnorePatterns } from "./tool-ignore-patterns.js";
|
|
8
|
-
|
|
9
|
-
export { devKitToolIgnorePatterns } from "./tool-ignore-patterns.js";
|
|
10
|
-
|
|
11
|
-
export const recommendedOxfmtConfig = {
|
|
12
|
-
arrowParens: "always",
|
|
13
|
-
endOfLine: "lf",
|
|
14
|
-
ignorePatterns: [...devKitToolIgnorePatterns],
|
|
15
|
-
printWidth: 100,
|
|
16
|
-
semi: true,
|
|
17
|
-
singleQuote: false,
|
|
18
|
-
sortImports: true,
|
|
19
|
-
sortPackageJson: true,
|
|
20
|
-
tabWidth: 2,
|
|
21
|
-
trailingComma: "all",
|
|
22
|
-
useTabs: false,
|
|
23
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
interface EffectOxlintRule {
|
|
2
|
-
readonly meta: {
|
|
3
|
-
readonly type: "problem";
|
|
4
|
-
readonly docs: { readonly description: string };
|
|
5
|
-
readonly messages: Readonly<Record<string, string>>;
|
|
6
|
-
};
|
|
7
|
-
readonly create: (context: {
|
|
8
|
-
report(descriptor: { node: unknown; messageId: string }): void;
|
|
9
|
-
}) => Readonly<Record<string, (node: unknown) => void>>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
declare const effectOxlintPlugin: {
|
|
13
|
-
readonly meta: { readonly name: "dev-kit-effect" };
|
|
14
|
-
readonly rules: Readonly<Record<string, EffectOxlintRule>>;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default effectOxlintPlugin;
|
package/src/oxlint.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime form of the typed preset declared in oxlint.ts.
|
|
3
|
-
*
|
|
4
|
-
* This file is intentionally plain JavaScript because Node does not strip
|
|
5
|
-
* TypeScript from packages in node_modules when Vite+ loads vite.config.ts.
|
|
6
|
-
*/
|
|
7
|
-
import { devKitToolIgnorePatterns } from "./tool-ignore-patterns.js";
|
|
8
|
-
|
|
9
|
-
export { devKitToolIgnorePatterns } from "./tool-ignore-patterns.js";
|
|
10
|
-
|
|
11
|
-
export const createAbsoluteImportsOxlintOverride = (options) => {
|
|
12
|
-
if (options.files.length === 0) {
|
|
13
|
-
throw new Error("absolute imports enforcement requires at least one file glob");
|
|
14
|
-
}
|
|
15
|
-
const files = [...new Set(options.files)];
|
|
16
|
-
|
|
17
|
-
if (files.length !== options.files.length) {
|
|
18
|
-
throw new Error("absolute imports file globs must be unique");
|
|
19
|
-
}
|
|
20
|
-
for (const glob of files) {
|
|
21
|
-
if (glob.trim().length === 0) {
|
|
22
|
-
throw new Error("absolute imports file globs must not be blank");
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
files,
|
|
28
|
-
rules: {
|
|
29
|
-
"import/no-relative-parent-imports": "error",
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const recommendedOxlintConfig = {
|
|
35
|
-
ignorePatterns: [...devKitToolIgnorePatterns],
|
|
36
|
-
options: {
|
|
37
|
-
typeAware: true,
|
|
38
|
-
},
|
|
39
|
-
jsPlugins: [
|
|
40
|
-
{
|
|
41
|
-
name: "effect",
|
|
42
|
-
specifier: "@danieljvdm/dev-kit/oxlint-plugin-effect",
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
name: "stylistic",
|
|
46
|
-
specifier: "@danieljvdm/dev-kit/oxlint-plugin-style",
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
plugins: ["import", "react", "vitest"],
|
|
50
|
-
rules: {
|
|
51
|
-
eqeqeq: "error",
|
|
52
|
-
"import/default": "off",
|
|
53
|
-
"import/namespace": "off",
|
|
54
|
-
"import/no-cycle": "error",
|
|
55
|
-
"import/no-duplicates": ["error", { preferInline: true }],
|
|
56
|
-
"import/no-self-import": "error",
|
|
57
|
-
"react/exhaustive-deps": "error",
|
|
58
|
-
"react/rules-of-hooks": "error",
|
|
59
|
-
"stylistic/padding-line-between-statements": [
|
|
60
|
-
"error",
|
|
61
|
-
{ blankLine: "always", prev: ["const", "let", "var"], next: "*" },
|
|
62
|
-
{
|
|
63
|
-
blankLine: "any",
|
|
64
|
-
prev: ["const", "let", "var"],
|
|
65
|
-
next: ["const", "let", "var"],
|
|
66
|
-
},
|
|
67
|
-
{ blankLine: "always", prev: "*", next: "return" },
|
|
68
|
-
],
|
|
69
|
-
"typescript/consistent-type-imports": [
|
|
70
|
-
"error",
|
|
71
|
-
{ fixStyle: "inline-type-imports", prefer: "type-imports" },
|
|
72
|
-
],
|
|
73
|
-
"typescript/no-floating-promises": "off",
|
|
74
|
-
"typescript/no-explicit-any": "error",
|
|
75
|
-
"typescript/no-misused-spread": "off",
|
|
76
|
-
"typescript/no-non-null-assertion": "error",
|
|
77
|
-
"typescript/require-array-sort-compare": "off",
|
|
78
|
-
"typescript/restrict-template-expressions": "off",
|
|
79
|
-
"typescript/switch-exhaustiveness-check": "error",
|
|
80
|
-
"unicorn/prefer-node-protocol": "error",
|
|
81
|
-
"vitest/no-focused-tests": "error",
|
|
82
|
-
"vitest/no-identical-title": "error",
|
|
83
|
-
"vitest/no-standalone-expect": "off",
|
|
84
|
-
"vitest/valid-expect": "error",
|
|
85
|
-
},
|
|
86
|
-
overrides: [
|
|
87
|
-
{
|
|
88
|
-
files: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
|
|
89
|
-
rules: {
|
|
90
|
-
"typescript/no-non-null-assertion": "off",
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
],
|
|
94
|
-
};
|
package/src/project-state.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { Schema } from "effect";
|
|
2
|
-
|
|
3
|
-
import { DigestSchema } from "./path-digest.ts";
|
|
4
|
-
|
|
5
|
-
export const CatalogProvenanceSchema = Schema.Union([
|
|
6
|
-
Schema.Struct({
|
|
7
|
-
source: Schema.String,
|
|
8
|
-
repository: Schema.String,
|
|
9
|
-
resolved: Schema.String,
|
|
10
|
-
}),
|
|
11
|
-
Schema.Struct({
|
|
12
|
-
package: Schema.String,
|
|
13
|
-
version: Schema.String,
|
|
14
|
-
skill: Schema.String,
|
|
15
|
-
digest: DigestSchema,
|
|
16
|
-
}),
|
|
17
|
-
]);
|
|
18
|
-
export type CatalogProvenance = typeof CatalogProvenanceSchema.Type;
|
|
19
|
-
|
|
20
|
-
export const ManagedSkillOutputSchema = Schema.Struct({
|
|
21
|
-
resourceId: Schema.String,
|
|
22
|
-
path: Schema.String,
|
|
23
|
-
skill: Schema.String,
|
|
24
|
-
target: Schema.Literals(["agents", "claude", "opencode"]),
|
|
25
|
-
mode: Schema.Literals(["copy", "symlink"]),
|
|
26
|
-
kind: Schema.Literals(["directory", "symlink"]),
|
|
27
|
-
digest: DigestSchema,
|
|
28
|
-
catalog: Schema.optional(CatalogProvenanceSchema),
|
|
29
|
-
});
|
|
30
|
-
export type ManagedSkillOutput = typeof ManagedSkillOutputSchema.Type;
|
|
31
|
-
|
|
32
|
-
export const ManagedAgentInstructionsOutputSchema = Schema.Struct({
|
|
33
|
-
resourceId: Schema.Literal("setup:agent-instructions"),
|
|
34
|
-
path: Schema.String,
|
|
35
|
-
sourcePath: Schema.String,
|
|
36
|
-
mode: Schema.Literal("copy"),
|
|
37
|
-
kind: Schema.Literal("file"),
|
|
38
|
-
digest: DigestSchema,
|
|
39
|
-
});
|
|
40
|
-
export type ManagedAgentInstructionsOutput = typeof ManagedAgentInstructionsOutputSchema.Type;
|
|
41
|
-
|
|
42
|
-
export const ManagedClaudeInstructionsOutputSchema = Schema.Struct({
|
|
43
|
-
resourceId: Schema.Literal("setup:claude-instructions"),
|
|
44
|
-
path: Schema.String,
|
|
45
|
-
sourcePath: Schema.String,
|
|
46
|
-
mode: Schema.Literal("symlink"),
|
|
47
|
-
kind: Schema.Literal("symlink"),
|
|
48
|
-
digest: DigestSchema,
|
|
49
|
-
});
|
|
50
|
-
export type ManagedClaudeInstructionsOutput = typeof ManagedClaudeInstructionsOutputSchema.Type;
|
|
51
|
-
|
|
52
|
-
// Legacy (dev-kit ≤0.14) lock entry for the previously managed check workflow.
|
|
53
|
-
// Kept only so old locks and receipts still decode; planning discards these
|
|
54
|
-
// entries, releasing the file to the repository. Never produced anymore.
|
|
55
|
-
export const ManagedGeneratedFileOutputSchema = Schema.Struct({
|
|
56
|
-
resourceId: Schema.Literal("setup:vite-plus-github-actions"),
|
|
57
|
-
path: Schema.String,
|
|
58
|
-
sourcePath: Schema.String,
|
|
59
|
-
mode: Schema.Literal("copy"),
|
|
60
|
-
kind: Schema.Literal("file"),
|
|
61
|
-
digest: DigestSchema,
|
|
62
|
-
});
|
|
63
|
-
export type ManagedGeneratedFileOutput = typeof ManagedGeneratedFileOutputSchema.Type;
|
|
64
|
-
|
|
65
|
-
export const ManagedInstructionOutputSchema = Schema.Union([
|
|
66
|
-
ManagedAgentInstructionsOutputSchema,
|
|
67
|
-
ManagedClaudeInstructionsOutputSchema,
|
|
68
|
-
]);
|
|
69
|
-
export type ManagedInstructionOutput = typeof ManagedInstructionOutputSchema.Type;
|
|
70
|
-
|
|
71
|
-
export const ManagedOutputSchema = Schema.Union([
|
|
72
|
-
ManagedSkillOutputSchema,
|
|
73
|
-
ManagedInstructionOutputSchema,
|
|
74
|
-
ManagedGeneratedFileOutputSchema,
|
|
75
|
-
]);
|
|
76
|
-
export type ManagedOutput = typeof ManagedOutputSchema.Type;
|
|
77
|
-
|
|
78
|
-
export const EffectTsgoLockSchema = Schema.Struct({
|
|
79
|
-
effectTsgoVersion: Schema.String,
|
|
80
|
-
typescriptPackage: Schema.String,
|
|
81
|
-
typescriptVersion: Schema.String,
|
|
82
|
-
});
|
|
83
|
-
export type EffectTsgoLock = typeof EffectTsgoLockSchema.Type;
|
|
84
|
-
|
|
85
|
-
export const EffectSourceLockSchema = Schema.Struct({
|
|
86
|
-
packageName: Schema.String,
|
|
87
|
-
packageVersion: Schema.String,
|
|
88
|
-
path: Schema.String,
|
|
89
|
-
repository: Schema.String,
|
|
90
|
-
tag: Schema.String,
|
|
91
|
-
});
|
|
92
|
-
export type EffectSourceLock = typeof EffectSourceLockSchema.Type;
|
|
93
|
-
|
|
94
|
-
export const DevKitLockSchema = Schema.Struct({
|
|
95
|
-
version: Schema.Literal(1),
|
|
96
|
-
toolVersion: Schema.String,
|
|
97
|
-
manifestDigest: DigestSchema,
|
|
98
|
-
setup: Schema.optional(
|
|
99
|
-
Schema.Struct({
|
|
100
|
-
effectSource: Schema.optional(EffectSourceLockSchema),
|
|
101
|
-
effectTsgo: Schema.optional(EffectTsgoLockSchema),
|
|
102
|
-
}),
|
|
103
|
-
),
|
|
104
|
-
outputs: Schema.Array(ManagedOutputSchema),
|
|
105
|
-
});
|
|
106
|
-
export type DevKitLock = typeof DevKitLockSchema.Type;
|
|
107
|
-
|
|
108
|
-
export const OwnershipReceiptSchema = Schema.Struct({
|
|
109
|
-
resourceId: Schema.String,
|
|
110
|
-
path: Schema.String,
|
|
111
|
-
mode: Schema.Literals(["copy", "symlink"]),
|
|
112
|
-
kind: Schema.Literals(["file", "directory", "symlink"]),
|
|
113
|
-
digest: DigestSchema,
|
|
114
|
-
});
|
|
115
|
-
export type OwnershipReceipt = typeof OwnershipReceiptSchema.Type;
|
|
116
|
-
|
|
117
|
-
export const AppliedStateSchema = Schema.Struct({
|
|
118
|
-
version: Schema.Literal(1),
|
|
119
|
-
appliedLockDigest: DigestSchema,
|
|
120
|
-
outputs: Schema.Array(OwnershipReceiptSchema),
|
|
121
|
-
});
|
|
122
|
-
export type AppliedState = typeof AppliedStateSchema.Type;
|
package/src/scaffold.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { Effect, FileSystem, Path, Schema } from "effect";
|
|
2
|
-
|
|
3
|
-
import { observeSymbolicLink } from "./node-symbolic-link.ts";
|
|
4
|
-
|
|
5
|
-
export class ScaffoldTemplateError extends Schema.TaggedError<ScaffoldTemplateError>()(
|
|
6
|
-
"ScaffoldTemplateError",
|
|
7
|
-
{ message: Schema.String },
|
|
8
|
-
) {}
|
|
9
|
-
|
|
10
|
-
export type ScaffoldPlan = {
|
|
11
|
-
readonly action: "scaffold" | "unchanged";
|
|
12
|
-
readonly path: string;
|
|
13
|
-
readonly destination: string;
|
|
14
|
-
readonly content?: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const replaceUniqueTemplateMarker = (
|
|
18
|
-
template: string,
|
|
19
|
-
marker: string,
|
|
20
|
-
replacement: string,
|
|
21
|
-
): string => {
|
|
22
|
-
const parts = template.split(marker);
|
|
23
|
-
|
|
24
|
-
if (parts.length !== 2) {
|
|
25
|
-
throw new Error(`expected exactly one generated template marker: ${marker}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return `${parts[0]}${replacement}${parts[1]}`;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const readScaffoldTemplate = Effect.fn("readScaffoldTemplate")(function* (
|
|
32
|
-
packageRoot: string,
|
|
33
|
-
templatePath: string,
|
|
34
|
-
) {
|
|
35
|
-
const fs = yield* FileSystem.FileSystem;
|
|
36
|
-
const path = yield* Path.Path;
|
|
37
|
-
const absolute = path.join(packageRoot, templatePath);
|
|
38
|
-
|
|
39
|
-
if (!(yield* fs.exists(absolute))) {
|
|
40
|
-
return yield* ScaffoldTemplateError.make({
|
|
41
|
-
message: `dev-kit scaffold template is missing: ${templatePath}`,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return yield* fs.readFileString(absolute);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// Scaffolds are created once and repository-owned afterwards: an existing
|
|
49
|
-
// destination is never read, compared, updated, or removed, and `content` is
|
|
50
|
-
// only computed (and validated) when the file is actually being created.
|
|
51
|
-
export const planScaffold = Effect.fn("planScaffold")(function* <E, R>(options: {
|
|
52
|
-
readonly projectDir: string;
|
|
53
|
-
readonly path: string;
|
|
54
|
-
readonly content: Effect.Effect<string, E, R>;
|
|
55
|
-
}) {
|
|
56
|
-
const path = yield* Path.Path;
|
|
57
|
-
const destination = path.join(options.projectDir, ...options.path.split("/"));
|
|
58
|
-
const observed = yield* observeSymbolicLink(destination);
|
|
59
|
-
|
|
60
|
-
if (observed.kind !== "missing") {
|
|
61
|
-
return { action: "unchanged", path: options.path, destination } satisfies ScaffoldPlan;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
action: "scaffold",
|
|
66
|
-
path: options.path,
|
|
67
|
-
destination,
|
|
68
|
-
content: yield* options.content,
|
|
69
|
-
} satisfies ScaffoldPlan;
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
export const applyScaffoldPlan = Effect.fn("applyScaffoldPlan")(function* (plan: ScaffoldPlan) {
|
|
73
|
-
if (plan.action !== "scaffold" || plan.content === undefined) return;
|
|
74
|
-
const fs = yield* FileSystem.FileSystem;
|
|
75
|
-
const path = yield* Path.Path;
|
|
76
|
-
|
|
77
|
-
yield* fs.makeDirectory(path.dirname(plan.destination), { recursive: true });
|
|
78
|
-
yield* fs.writeFileString(plan.destination, plan.content);
|
|
79
|
-
});
|