@danieljvdm/dev-kit 0.6.0 → 0.7.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 +123 -56
- package/dev-kit.example.jsonc +7 -3
- package/package.json +19 -16
- package/schema/dev-kit.schema.json +38 -0
- package/skill-sources.jsonc +8 -12
- package/skill-sources.lock.json +3 -9
- package/skills/dev-kit/SKILL.md +52 -17
- package/skills/effect-ts/agents/openai.yaml +0 -1
- package/skills/effect-ts/references/audit-services.md +11 -11
- package/skills/effect-ts/references/guide-effect.md +56 -69
- package/skills/effect-ts/references/guide-error-handling.md +64 -73
- package/skills/effect-ts/references/guide-layers.md +187 -215
- package/skills/effect-ts/references/guide-observability.md +91 -116
- package/skills/effect-ts/references/guide-retries.md +32 -44
- package/skills/effect-ts/references/guide-schedule.md +26 -40
- package/skills/effect-ts/references/guide-schema.md +50 -57
- package/skills/effect-ts/references/guide-sql.md +47 -50
- package/skills/effect-ts/references/guide-testing.md +96 -98
- package/skills/effect-ts/references/guide-type-safety-and-boundaries.md +7 -7
- package/skills/effect-ts/references/version-and-source.md +0 -1
- package/src/bin/dev-kit.ts +61 -28
- package/src/catalog-manager.ts +86 -34
- package/src/catalog.ts +71 -33
- package/src/cli-ui.ts +20 -16
- package/src/effect-source.ts +49 -19
- package/src/effect-tsgo.ts +66 -35
- package/src/gitignore.ts +19 -6
- package/src/index.ts +6 -0
- package/src/manifest.ts +38 -3
- package/src/node-symbolic-link.ts +3 -0
- package/src/oxlint-plugin-effect.js +3 -0
- package/src/oxlint-plugin-style.d.ts +8 -0
- package/src/oxlint-plugin-style.js +8 -0
- package/src/oxlint.js +14 -0
- package/src/oxlint.ts +14 -0
- package/src/package-skill-source.ts +189 -52
- package/src/path-digest.ts +31 -11
- package/src/project-package.ts +44 -19
- package/src/project-process-lock.ts +19 -12
- package/src/project-state.ts +11 -0
- package/src/skill-manager.ts +134 -55
- package/src/skill-selector.ts +8 -2
- package/src/source-manifest.ts +2 -6
- package/src/sync.ts +371 -103
- package/src/vendor.ts +112 -42
- package/src/vite-plus-hooks.ts +174 -0
- package/src/vite-plus-quality.ts +49 -0
- package/templates/vite-plus/github-actions-check.yml +44 -0
- package/templates/vite-plus/vite.config.ts +22 -0
|
@@ -46,8 +46,8 @@ repository explicitly owns that workflow.
|
|
|
46
46
|
Preferred imports for Effect tests:
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
|
-
import { assert, describe, it, layer } from "@effect/vitest"
|
|
50
|
-
import { Effect } from "effect"
|
|
49
|
+
import { assert, describe, it, layer } from "@effect/vitest";
|
|
50
|
+
import { Effect } from "effect";
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
`@effect/vitest` re-exports Vitest, so it is the normal entrypoint for test APIs in an Effect codebase.
|
|
@@ -74,15 +74,15 @@ This comes directly from the internal implementation.
|
|
|
74
74
|
Example:
|
|
75
75
|
|
|
76
76
|
```ts
|
|
77
|
-
import { assert, it } from "@effect/vitest"
|
|
78
|
-
import { Effect } from "effect"
|
|
77
|
+
import { assert, it } from "@effect/vitest";
|
|
78
|
+
import { Effect } from "effect";
|
|
79
79
|
|
|
80
80
|
it.effect("loads a user", () =>
|
|
81
|
-
Effect.gen(function*() {
|
|
82
|
-
yield* Effect.void
|
|
83
|
-
assert.isTrue(true)
|
|
84
|
-
})
|
|
85
|
-
)
|
|
81
|
+
Effect.gen(function* () {
|
|
82
|
+
yield* Effect.void;
|
|
83
|
+
assert.isTrue(true);
|
|
84
|
+
}),
|
|
85
|
+
);
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
Use `it.effect` when:
|
|
@@ -100,10 +100,10 @@ Example:
|
|
|
100
100
|
|
|
101
101
|
```ts
|
|
102
102
|
it.live("uses live services", () =>
|
|
103
|
-
Effect.gen(function*() {
|
|
104
|
-
yield* Effect.void
|
|
105
|
-
})
|
|
106
|
-
)
|
|
103
|
+
Effect.gen(function* () {
|
|
104
|
+
yield* Effect.void;
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
Use `it.live` when:
|
|
@@ -123,11 +123,11 @@ Preferred pattern:
|
|
|
123
123
|
|
|
124
124
|
```ts
|
|
125
125
|
it.effect("does something", () =>
|
|
126
|
-
Effect.gen(function*() {
|
|
127
|
-
const value = yield* someEffect
|
|
128
|
-
assert.strictEqual(value, 1)
|
|
129
|
-
})
|
|
130
|
-
)
|
|
126
|
+
Effect.gen(function* () {
|
|
127
|
+
const value = yield* someEffect;
|
|
128
|
+
assert.strictEqual(value, 1);
|
|
129
|
+
}),
|
|
130
|
+
);
|
|
131
131
|
```
|
|
132
132
|
|
|
133
133
|
Prefer `Effect.gen` inside `it.effect` and `it.live` for readability.
|
|
@@ -147,9 +147,9 @@ The canonical source also uses `expect` in some tests, but for skill guidance pr
|
|
|
147
147
|
Examples:
|
|
148
148
|
|
|
149
149
|
```ts
|
|
150
|
-
assert.isTrue(value === 1)
|
|
151
|
-
assert.strictEqual(a + b, b + a)
|
|
152
|
-
assert.include(text, substring)
|
|
150
|
+
assert.isTrue(value === 1);
|
|
151
|
+
assert.strictEqual(a + b, b + a);
|
|
152
|
+
assert.include(text, substring);
|
|
153
153
|
```
|
|
154
154
|
|
|
155
155
|
## Test Context
|
|
@@ -160,12 +160,12 @@ Example:
|
|
|
160
160
|
|
|
161
161
|
```ts
|
|
162
162
|
it.effect("uses context", (ctx) =>
|
|
163
|
-
Effect.gen(function*() {
|
|
163
|
+
Effect.gen(function* () {
|
|
164
164
|
ctx.onTestFailed(() => {
|
|
165
165
|
// cleanup or diagnostics
|
|
166
|
-
})
|
|
167
|
-
})
|
|
168
|
-
)
|
|
166
|
+
});
|
|
167
|
+
}),
|
|
168
|
+
);
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
Use this when you need:
|
|
@@ -201,12 +201,12 @@ Use `it.prop` for non-Effect property tests.
|
|
|
201
201
|
Example:
|
|
202
202
|
|
|
203
203
|
```ts
|
|
204
|
-
import { it } from "@effect/vitest"
|
|
205
|
-
import { FastCheck } from "effect/testing"
|
|
204
|
+
import { it } from "@effect/vitest";
|
|
205
|
+
import { FastCheck } from "effect/testing";
|
|
206
206
|
|
|
207
|
-
const realNumber = FastCheck.float({ noNaN: true, noDefaultInfinity: true })
|
|
207
|
+
const realNumber = FastCheck.float({ noNaN: true, noDefaultInfinity: true });
|
|
208
208
|
|
|
209
|
-
it.prop("symmetry", [realNumber, FastCheck.integer()], ([a, b]) => a + b === b + a)
|
|
209
|
+
it.prop("symmetry", [realNumber, FastCheck.integer()], ([a, b]) => a + b === b + a);
|
|
210
210
|
```
|
|
211
211
|
|
|
212
212
|
Important limitation from the internal implementation:
|
|
@@ -225,17 +225,17 @@ This is the more powerful property-testing mode for Effect code.
|
|
|
225
225
|
Example:
|
|
226
226
|
|
|
227
227
|
```ts
|
|
228
|
-
import { assert, it } from "@effect/vitest"
|
|
229
|
-
import { Effect } from "effect"
|
|
230
|
-
import { FastCheck } from "effect/testing"
|
|
228
|
+
import { assert, it } from "@effect/vitest";
|
|
229
|
+
import { Effect } from "effect";
|
|
230
|
+
import { FastCheck } from "effect/testing";
|
|
231
231
|
|
|
232
|
-
const realNumber = FastCheck.float({ noNaN: true, noDefaultInfinity: true })
|
|
232
|
+
const realNumber = FastCheck.float({ noNaN: true, noDefaultInfinity: true });
|
|
233
233
|
|
|
234
234
|
it.effect.prop("symmetry", [realNumber, FastCheck.integer()], ([a, b]) =>
|
|
235
|
-
Effect.gen(function*() {
|
|
236
|
-
assert.strictEqual(a + b, b + a)
|
|
237
|
-
})
|
|
238
|
-
)
|
|
235
|
+
Effect.gen(function* () {
|
|
236
|
+
assert.strictEqual(a + b, b + a);
|
|
237
|
+
}),
|
|
238
|
+
);
|
|
239
239
|
```
|
|
240
240
|
|
|
241
241
|
Unlike top-level `it.prop`, `it.effect.prop` does support `Schema` inputs by converting them with `Schema.toArbitrary`.
|
|
@@ -260,23 +260,23 @@ This is one of the most important `@effect/vitest` features.
|
|
|
260
260
|
Example:
|
|
261
261
|
|
|
262
262
|
```ts
|
|
263
|
-
import { describe, it, layer } from "@effect/vitest"
|
|
264
|
-
import { Context, Effect, Layer } from "effect"
|
|
263
|
+
import { describe, it, layer } from "@effect/vitest";
|
|
264
|
+
import { Context, Effect, Layer } from "effect";
|
|
265
265
|
|
|
266
266
|
class Foo extends Context.Service<Foo, string>()("Foo") {
|
|
267
|
-
static readonly layer = Layer.succeed(Foo)("foo")
|
|
267
|
+
static readonly layer = Layer.succeed(Foo)("foo");
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
describe("foo", () => {
|
|
271
271
|
layer(Foo.layer)((it) => {
|
|
272
272
|
it.effect("gets foo", () =>
|
|
273
|
-
Effect.gen(function*() {
|
|
274
|
-
const foo = yield* Foo
|
|
275
|
-
return foo
|
|
276
|
-
})
|
|
277
|
-
)
|
|
278
|
-
})
|
|
279
|
-
})
|
|
273
|
+
Effect.gen(function* () {
|
|
274
|
+
const foo = yield* Foo;
|
|
275
|
+
return foo;
|
|
276
|
+
}),
|
|
277
|
+
);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
280
|
```
|
|
281
281
|
|
|
282
282
|
What it does internally:
|
|
@@ -314,14 +314,12 @@ If multiple tests use the same layer, do not write tests like this:
|
|
|
314
314
|
|
|
315
315
|
```ts
|
|
316
316
|
it.effect("creates and lists todos", () =>
|
|
317
|
-
Effect.gen(function*() {
|
|
318
|
-
const service = yield* TodoService
|
|
319
|
-
yield* service.create("write tests")
|
|
320
|
-
yield* service.create("ship feature")
|
|
321
|
-
}).pipe(
|
|
322
|
-
|
|
323
|
-
)
|
|
324
|
-
)
|
|
317
|
+
Effect.gen(function* () {
|
|
318
|
+
const service = yield* TodoService;
|
|
319
|
+
yield* service.create("write tests");
|
|
320
|
+
yield* service.create("ship feature");
|
|
321
|
+
}).pipe(Effect.provide(TodoService.inMemoryLayer)),
|
|
322
|
+
);
|
|
325
323
|
```
|
|
326
324
|
|
|
327
325
|
Why this is the wrong pattern:
|
|
@@ -338,23 +336,23 @@ Prefer:
|
|
|
338
336
|
describe("TodoService", () => {
|
|
339
337
|
layer(TodoService.inMemoryLayer)((it) => {
|
|
340
338
|
it.effect("creates and lists todos", () =>
|
|
341
|
-
Effect.gen(function*() {
|
|
342
|
-
const service = yield* TodoService
|
|
343
|
-
yield* service.create("write tests")
|
|
344
|
-
yield* service.create("ship feature")
|
|
345
|
-
})
|
|
346
|
-
)
|
|
339
|
+
Effect.gen(function* () {
|
|
340
|
+
const service = yield* TodoService;
|
|
341
|
+
yield* service.create("write tests");
|
|
342
|
+
yield* service.create("ship feature");
|
|
343
|
+
}),
|
|
344
|
+
);
|
|
347
345
|
|
|
348
346
|
it.effect("updates completion and deletes todos", () =>
|
|
349
|
-
Effect.gen(function*() {
|
|
350
|
-
const service = yield* TodoService
|
|
351
|
-
const todo = yield* service.create("close issue")
|
|
352
|
-
yield* service.setCompleted(todo.id, true)
|
|
353
|
-
yield* service.remove(todo.id)
|
|
354
|
-
})
|
|
355
|
-
)
|
|
356
|
-
})
|
|
357
|
-
})
|
|
347
|
+
Effect.gen(function* () {
|
|
348
|
+
const service = yield* TodoService;
|
|
349
|
+
const todo = yield* service.create("close issue");
|
|
350
|
+
yield* service.setCompleted(todo.id, true);
|
|
351
|
+
yield* service.remove(todo.id);
|
|
352
|
+
}),
|
|
353
|
+
);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
358
356
|
```
|
|
359
357
|
|
|
360
358
|
Rule:
|
|
@@ -381,14 +379,14 @@ Example:
|
|
|
381
379
|
layer(Foo.layer)((it) => {
|
|
382
380
|
it.layer(Bar.layer)("nested", (it) => {
|
|
383
381
|
it.effect("gets both", () =>
|
|
384
|
-
Effect.gen(function*() {
|
|
385
|
-
const foo = yield* Foo
|
|
386
|
-
const bar = yield* Bar
|
|
387
|
-
return [foo, bar]
|
|
388
|
-
})
|
|
389
|
-
)
|
|
390
|
-
})
|
|
391
|
-
})
|
|
382
|
+
Effect.gen(function* () {
|
|
383
|
+
const foo = yield* Foo;
|
|
384
|
+
const bar = yield* Bar;
|
|
385
|
+
return [foo, bar];
|
|
386
|
+
}),
|
|
387
|
+
);
|
|
388
|
+
});
|
|
389
|
+
});
|
|
392
390
|
```
|
|
393
391
|
|
|
394
392
|
Important behavior from the implementation:
|
|
@@ -476,11 +474,11 @@ It is not needed for ordinary test structure.
|
|
|
476
474
|
|
|
477
475
|
```ts
|
|
478
476
|
it.effect("does work", () =>
|
|
479
|
-
Effect.gen(function*() {
|
|
480
|
-
const value = yield* Effect.succeed(1)
|
|
481
|
-
assert.strictEqual(value, 1)
|
|
482
|
-
})
|
|
483
|
-
)
|
|
477
|
+
Effect.gen(function* () {
|
|
478
|
+
const value = yield* Effect.succeed(1);
|
|
479
|
+
assert.strictEqual(value, 1);
|
|
480
|
+
}),
|
|
481
|
+
);
|
|
484
482
|
```
|
|
485
483
|
|
|
486
484
|
### Pattern: shared layer for a test group
|
|
@@ -488,33 +486,33 @@ it.effect("does work", () =>
|
|
|
488
486
|
```ts
|
|
489
487
|
layer(AppLayer)("app", (it) => {
|
|
490
488
|
it.effect("uses app services", () =>
|
|
491
|
-
Effect.gen(function*() {
|
|
492
|
-
yield* Effect.void
|
|
493
|
-
})
|
|
494
|
-
)
|
|
495
|
-
})
|
|
489
|
+
Effect.gen(function* () {
|
|
490
|
+
yield* Effect.void;
|
|
491
|
+
}),
|
|
492
|
+
);
|
|
493
|
+
});
|
|
496
494
|
```
|
|
497
495
|
|
|
498
496
|
### Pattern: property test with Effect
|
|
499
497
|
|
|
500
498
|
```ts
|
|
501
499
|
it.effect.prop("law", [FastCheck.integer()], ([n]) =>
|
|
502
|
-
Effect.gen(function*() {
|
|
503
|
-
assert.strictEqual(n + 0, n)
|
|
504
|
-
})
|
|
505
|
-
)
|
|
500
|
+
Effect.gen(function* () {
|
|
501
|
+
assert.strictEqual(n + 0, n);
|
|
502
|
+
}),
|
|
503
|
+
);
|
|
506
504
|
```
|
|
507
505
|
|
|
508
506
|
### Pattern: use `TestClock`
|
|
509
507
|
|
|
510
508
|
```ts
|
|
511
509
|
it.effect("uses TestClock", () =>
|
|
512
|
-
Effect.gen(function*() {
|
|
513
|
-
const fiber = yield* Effect.forkChild(Effect.sleep("1 second"))
|
|
514
|
-
yield* TestClock.adjust("1 second")
|
|
515
|
-
yield* Fiber.join(fiber)
|
|
516
|
-
})
|
|
517
|
-
)
|
|
510
|
+
Effect.gen(function* () {
|
|
511
|
+
const fiber = yield* Effect.forkChild(Effect.sleep("1 second"));
|
|
512
|
+
yield* TestClock.adjust("1 second");
|
|
513
|
+
yield* Fiber.join(fiber);
|
|
514
|
+
}),
|
|
515
|
+
);
|
|
518
516
|
```
|
|
519
517
|
|
|
520
518
|
## Anti-Patterns
|
|
@@ -49,13 +49,13 @@ domain policy.
|
|
|
49
49
|
|
|
50
50
|
Choose the Schema adapter that matches the caller's control flow:
|
|
51
51
|
|
|
52
|
-
| Intent
|
|
53
|
-
|
|
|
54
|
-
| Boolean type guard
|
|
55
|
-
| Optional tolerant decode
|
|
56
|
-
| Typed Effect failure
|
|
57
|
-
| JSON string decode
|
|
58
|
-
| Any JSON-compatible value | `Schema.Json`
|
|
52
|
+
| Intent | Adapter |
|
|
53
|
+
| ------------------------- | ----------------------------------- |
|
|
54
|
+
| Boolean type guard | `Schema.is(Model)` |
|
|
55
|
+
| Optional tolerant decode | `Schema.decodeUnknownOption(Model)` |
|
|
56
|
+
| Typed Effect failure | `Schema.decodeUnknownEffect(Model)` |
|
|
57
|
+
| JSON string decode | `Schema.fromJsonString(Model)` |
|
|
58
|
+
| Any JSON-compatible value | `Schema.Json` |
|
|
59
59
|
|
|
60
60
|
Define small schemas for provider responses, SDK payloads, persisted data, and
|
|
61
61
|
other structured external values. Decode once in the adapter and return the
|
package/src/bin/dev-kit.ts
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
2
|
-
import { Argument, CliError, Command as CliCommand, Flag } from "effect/unstable/cli";
|
|
3
2
|
import { Effect, Result } from "effect";
|
|
3
|
+
import { Argument, CliError, Command as CliCommand, Flag } from "effect/unstable/cli";
|
|
4
4
|
|
|
5
|
-
import { printError } from "../cli-ui.ts";
|
|
6
|
-
import { patchEffectTsgo } from "../effect-tsgo.ts";
|
|
7
|
-
import { syncEffectSource } from "../effect-source.ts";
|
|
8
|
-
import { patchProjectGitignore } from "../gitignore.ts";
|
|
9
|
-
import {
|
|
10
|
-
DEFAULT_MANIFEST,
|
|
11
|
-
runProjectSkillPlan,
|
|
12
|
-
} from "../sync.ts";
|
|
13
|
-
import { DEV_KIT_VERSION } from "../tool-metadata.ts";
|
|
14
|
-
import { refreshSkillCatalog } from "../vendor.ts";
|
|
15
5
|
import {
|
|
16
6
|
addCatalogSource,
|
|
17
7
|
listCatalogSources,
|
|
18
8
|
removeCatalogEntry,
|
|
19
9
|
showCatalogSource,
|
|
20
10
|
} from "../catalog-manager.ts";
|
|
11
|
+
import { printError } from "../cli-ui.ts";
|
|
12
|
+
import { syncEffectSource } from "../effect-source.ts";
|
|
13
|
+
import { patchEffectTsgo } from "../effect-tsgo.ts";
|
|
14
|
+
import { patchProjectGitignore } from "../gitignore.ts";
|
|
21
15
|
import {
|
|
22
16
|
addSkills,
|
|
23
17
|
chooseSkillsToAdd,
|
|
@@ -28,6 +22,9 @@ import {
|
|
|
28
22
|
showDashboard,
|
|
29
23
|
showSkill,
|
|
30
24
|
} from "../skill-manager.ts";
|
|
25
|
+
import { DEFAULT_MANIFEST, runProjectSkillPlan } from "../sync.ts";
|
|
26
|
+
import { DEV_KIT_VERSION } from "../tool-metadata.ts";
|
|
27
|
+
import { refreshSkillCatalog } from "../vendor.ts";
|
|
31
28
|
|
|
32
29
|
const projectFlags = {
|
|
33
30
|
manifest: Flag.string("manifest").pipe(
|
|
@@ -80,8 +77,7 @@ const listCommand = CliCommand.make(
|
|
|
80
77
|
all: Flag.boolean("all").pipe(Flag.withDescription("Include unselected skills.")),
|
|
81
78
|
...projectFlags,
|
|
82
79
|
},
|
|
83
|
-
({ all, manifest, projectDir }) =>
|
|
84
|
-
listSkills({ all, manifestPath: manifest, projectDir }),
|
|
80
|
+
({ all, manifest, projectDir }) => listSkills({ all, manifestPath: manifest, projectDir }),
|
|
85
81
|
).pipe(CliCommand.withDescription("List selected skills; use --all to browse the catalog."));
|
|
86
82
|
|
|
87
83
|
const searchCommand = CliCommand.make(
|
|
@@ -113,7 +109,9 @@ const planCommand = CliCommand.make(
|
|
|
113
109
|
manifestPath: manifest,
|
|
114
110
|
projectDir,
|
|
115
111
|
}),
|
|
116
|
-
).pipe(
|
|
112
|
+
).pipe(
|
|
113
|
+
CliCommand.withDescription("Plan ownership-safe project skill changes without writing files."),
|
|
114
|
+
);
|
|
117
115
|
|
|
118
116
|
const applyCommand = CliCommand.make(
|
|
119
117
|
"apply",
|
|
@@ -130,7 +128,9 @@ const applyCommand = CliCommand.make(
|
|
|
130
128
|
manifestPath: manifest,
|
|
131
129
|
projectDir,
|
|
132
130
|
}),
|
|
133
|
-
).pipe(
|
|
131
|
+
).pipe(
|
|
132
|
+
CliCommand.withDescription("Apply ownership-safe project skill changes and update the lock."),
|
|
133
|
+
);
|
|
134
134
|
|
|
135
135
|
const syncCommand = CliCommand.make(
|
|
136
136
|
"sync",
|
|
@@ -166,9 +166,7 @@ const gitignoreCommand = CliCommand.make(
|
|
|
166
166
|
},
|
|
167
167
|
({ dryRun, projectDir }) => patchProjectGitignore({ dryRun, projectDir }),
|
|
168
168
|
).pipe(
|
|
169
|
-
CliCommand.withDescription(
|
|
170
|
-
"Idempotently add .repos/ and .dev-kit/ to the project .gitignore.",
|
|
171
|
-
),
|
|
169
|
+
CliCommand.withDescription("Idempotently add .repos/ and .dev-kit/ to the project .gitignore."),
|
|
172
170
|
);
|
|
173
171
|
|
|
174
172
|
const tsgoPatchCommand = CliCommand.make(
|
|
@@ -177,9 +175,7 @@ const tsgoPatchCommand = CliCommand.make(
|
|
|
177
175
|
dryRun: Flag.boolean("dry-run"),
|
|
178
176
|
force: Flag.boolean("force"),
|
|
179
177
|
projectDir: Flag.string("project-dir").pipe(Flag.withDefault(".")),
|
|
180
|
-
typescriptPackage: Flag.string("typescript-package").pipe(
|
|
181
|
-
Flag.withDefault("typescript"),
|
|
182
|
-
),
|
|
178
|
+
typescriptPackage: Flag.string("typescript-package").pipe(Flag.withDefault("typescript")),
|
|
183
179
|
},
|
|
184
180
|
({ dryRun, force, projectDir, typescriptPackage }) =>
|
|
185
181
|
patchEffectTsgo({ dryRun, force, projectDir, typescriptPackage }),
|
|
@@ -247,9 +243,18 @@ const catalogAddCommand = CliCommand.make(
|
|
|
247
243
|
Flag.withDescription("Approve every skill discovered in this snapshot."),
|
|
248
244
|
),
|
|
249
245
|
dryRun: Flag.boolean("dry-run").pipe(Flag.withDescription("Inspect without writing.")),
|
|
250
|
-
id: Flag.string("id").pipe(
|
|
251
|
-
|
|
252
|
-
|
|
246
|
+
id: Flag.string("id").pipe(
|
|
247
|
+
Flag.withDefault(""),
|
|
248
|
+
Flag.withDescription("Override the inferred source id."),
|
|
249
|
+
),
|
|
250
|
+
license: Flag.string("license").pipe(
|
|
251
|
+
Flag.withDefault(""),
|
|
252
|
+
Flag.withDescription("Repository-relative license path."),
|
|
253
|
+
),
|
|
254
|
+
ref: Flag.string("ref").pipe(
|
|
255
|
+
Flag.withDefault(""),
|
|
256
|
+
Flag.withDescription("Branch, tag, or commit to track."),
|
|
257
|
+
),
|
|
253
258
|
skill: Flag.string("skill").pipe(
|
|
254
259
|
Flag.atLeast(0),
|
|
255
260
|
Flag.withDescription("Approve one skill; repeat for several."),
|
|
@@ -264,7 +269,20 @@ const catalogAddCommand = CliCommand.make(
|
|
|
264
269
|
),
|
|
265
270
|
...catalogFilesFlags,
|
|
266
271
|
},
|
|
267
|
-
({
|
|
272
|
+
({
|
|
273
|
+
repository,
|
|
274
|
+
all,
|
|
275
|
+
dryRun,
|
|
276
|
+
id,
|
|
277
|
+
license,
|
|
278
|
+
ref,
|
|
279
|
+
skill,
|
|
280
|
+
skillsPath,
|
|
281
|
+
stripFrontmatter,
|
|
282
|
+
lockfile,
|
|
283
|
+
repoDir,
|
|
284
|
+
sources,
|
|
285
|
+
}) =>
|
|
268
286
|
addCatalogSource({
|
|
269
287
|
repository,
|
|
270
288
|
all,
|
|
@@ -304,7 +322,13 @@ const catalogRemoveCommand = CliCommand.make(
|
|
|
304
322
|
...catalogFilesFlags,
|
|
305
323
|
},
|
|
306
324
|
({ entry, dryRun, yes, lockfile, repoDir, sources }) =>
|
|
307
|
-
removeCatalogEntry(entry, {
|
|
325
|
+
removeCatalogEntry(entry, {
|
|
326
|
+
dryRun,
|
|
327
|
+
yes,
|
|
328
|
+
lockfilePath: lockfile,
|
|
329
|
+
repoDir,
|
|
330
|
+
sourcesPath: sources,
|
|
331
|
+
}),
|
|
308
332
|
).pipe(CliCommand.withDescription("Revoke an approved source or individual skill."));
|
|
309
333
|
|
|
310
334
|
const catalogRefreshCommand = CliCommand.make(
|
|
@@ -316,7 +340,9 @@ const catalogRefreshCommand = CliCommand.make(
|
|
|
316
340
|
},
|
|
317
341
|
({ dryRun, locked, lockfile, repoDir, sources }) =>
|
|
318
342
|
refreshSkillCatalog({ dryRun, locked, lockfilePath: lockfile, repoDir, sourcesPath: sources }),
|
|
319
|
-
).pipe(
|
|
343
|
+
).pipe(
|
|
344
|
+
CliCommand.withDescription("Approve the current upstream refs as an exact catalog snapshot."),
|
|
345
|
+
);
|
|
320
346
|
|
|
321
347
|
const catalogVerifyCommand = CliCommand.make(
|
|
322
348
|
"verify",
|
|
@@ -349,7 +375,14 @@ const command = CliCommand.make("dev-kit", projectFlags, ({ manifest, projectDir
|
|
|
349
375
|
{ group: "Project", commands: [statusCommand, syncCommand] },
|
|
350
376
|
{
|
|
351
377
|
group: "Advanced",
|
|
352
|
-
commands: [
|
|
378
|
+
commands: [
|
|
379
|
+
planCommand,
|
|
380
|
+
applyCommand,
|
|
381
|
+
gitignoreCommand,
|
|
382
|
+
effectCommand,
|
|
383
|
+
tsgoCommand,
|
|
384
|
+
catalogCommand,
|
|
385
|
+
],
|
|
353
386
|
},
|
|
354
387
|
] as const),
|
|
355
388
|
);
|