@cosmicdrift/kumiko-cli 0.334.0 → 0.335.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/package.json +7 -7
- package/src/changes.json +12 -0
- package/src/commands/agent.ts +3 -3
- package/src/commands/check.ts +20 -4
- package/src/commands/consumer.ts +3 -3
- package/src/commands/load-app-config.ts +32 -0
- package/src/commands/project.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.335.0",
|
|
4
4
|
"description": "CLI for Kumiko apps. `bunx @cosmicdrift/kumiko-cli new app <name>` scaffolds a runnable workspace; `add feature <name>` mounts a feature; `check` runs boot validation plus the guard suites with the step list derived from kumiko.json; `agent lint`, `project` and `consumer` operate on an existing app.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
39
|
-
"@cosmicdrift/kumiko-dev-server": "0.
|
|
40
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
41
|
-
"@cosmicdrift/kumiko-guards": "0.
|
|
42
|
-
"@cosmicdrift/kumiko-repo-manifest": "0.
|
|
43
|
-
"@cosmicdrift/kumiko-testing": "0.
|
|
38
|
+
"@cosmicdrift/kumiko-bundled-features": "0.335.0",
|
|
39
|
+
"@cosmicdrift/kumiko-dev-server": "0.335.0",
|
|
40
|
+
"@cosmicdrift/kumiko-framework": "0.335.0",
|
|
41
|
+
"@cosmicdrift/kumiko-guards": "0.335.0",
|
|
42
|
+
"@cosmicdrift/kumiko-repo-manifest": "0.335.0",
|
|
43
|
+
"@cosmicdrift/kumiko-testing": "0.335.0",
|
|
44
44
|
"zod": "^4.4.3"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
package/src/changes.json
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.335.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "kumiko check runs boot validation against the repo root when started from a subdirectory",
|
|
6
|
+
"detail": "`kumiko check` now runs the boot validation against the repo root instead of the current directory, so running it from a subdirectory no longer reports a missing `kumiko/schema.ts`."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.335.0",
|
|
10
|
+
"type": "fix",
|
|
11
|
+
"title": "kumiko check survives throwing steps, config loading validates its shape",
|
|
12
|
+
"detail": "`kumiko check` counts a step that throws as a failure and still runs the remaining steps, and `--explain` now returns the guards' exit code. The `agent`, `consumer` and `project` commands report a readable message when `kumiko.config.ts` has no default export with a `features` array instead of crashing. Invalid-manifest errors name the root as `<root>` instead of an empty path."
|
|
13
|
+
},
|
|
2
14
|
{
|
|
3
15
|
"version": "0.292.0",
|
|
4
16
|
"type": "improvement",
|
package/src/commands/agent.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
+
import { loadAppConfig } from "./load-app-config";
|
|
2
3
|
import type { CliCommand } from "./types";
|
|
3
4
|
|
|
4
5
|
const LINT_SUBCOMMAND = "lint";
|
|
@@ -29,9 +30,8 @@ export const agentCommand: CliCommand = {
|
|
|
29
30
|
return 1;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
const config =
|
|
33
|
-
|
|
34
|
-
};
|
|
33
|
+
const config = await loadAppConfig(ctx, configPath);
|
|
34
|
+
if (config === null) return 1;
|
|
35
35
|
const { findAgentDocGaps, formatAgentDocGap } = await import(
|
|
36
36
|
"@cosmicdrift/kumiko-bundled-features/agent-tools"
|
|
37
37
|
);
|
package/src/commands/check.ts
CHANGED
|
@@ -144,28 +144,44 @@ export async function runCheck(
|
|
|
144
144
|
|
|
145
145
|
if (ctx.argv.includes("--explain")) {
|
|
146
146
|
// The guard suite is the only one with its own --explain; pass it through.
|
|
147
|
-
|
|
148
|
-
return 0;
|
|
147
|
+
return steps.some((step) => step.id === "guards") ? guards.runGuardsCli(["--explain"]) : 0;
|
|
149
148
|
}
|
|
150
149
|
|
|
151
150
|
let failed = 0;
|
|
152
151
|
for (const step of steps) {
|
|
153
152
|
ctx.out.log(` ▸ ${step.label}`);
|
|
154
|
-
failed += await
|
|
153
|
+
failed += await runStepReportingThrow(step, ctx, repo.absPath, guards, deps);
|
|
155
154
|
}
|
|
156
155
|
return failed > 0 ? 1 : 0;
|
|
157
156
|
}
|
|
158
157
|
|
|
158
|
+
async function runStepReportingThrow(
|
|
159
|
+
step: { readonly id: CheckStepId; readonly label: string },
|
|
160
|
+
ctx: CliCommandContext,
|
|
161
|
+
repoRoot: string,
|
|
162
|
+
guards: GuardsCli,
|
|
163
|
+
deps: CheckDeps,
|
|
164
|
+
): Promise<number> {
|
|
165
|
+
try {
|
|
166
|
+
return await runStep(step.id, ctx, repoRoot, guards, deps);
|
|
167
|
+
} catch (e) {
|
|
168
|
+
ctx.out.err(` ✗ ${step.label}: ${e instanceof Error ? e.message : String(e)}`);
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
159
173
|
async function runStep(
|
|
160
174
|
id: CheckStepId,
|
|
161
175
|
ctx: CliCommandContext,
|
|
176
|
+
repoRoot: string,
|
|
162
177
|
guards: GuardsCli,
|
|
163
178
|
deps: CheckDeps,
|
|
164
179
|
): Promise<number> {
|
|
165
180
|
switch (id) {
|
|
166
181
|
case "boot": {
|
|
167
182
|
const { runSchemaCli } = await deps.loadSchemaCli();
|
|
168
|
-
|
|
183
|
+
// findLocalRepo walks upwards, so ctx.cwd may be a subdirectory without kumiko/schema.ts.
|
|
184
|
+
return await runSchemaCli(["validate"], repoRoot, ctx.out);
|
|
169
185
|
}
|
|
170
186
|
case "guards":
|
|
171
187
|
return guards.runGuardsCli([]);
|
package/src/commands/consumer.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
+
import { loadAppConfig } from "./load-app-config";
|
|
2
3
|
import type { CliCommand, CliCommandContext } from "./types";
|
|
3
4
|
|
|
4
5
|
export const consumerCommand: CliCommand = {
|
|
@@ -25,9 +26,8 @@ export const consumerCommand: CliCommand = {
|
|
|
25
26
|
return 1;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
const config =
|
|
29
|
-
|
|
30
|
-
};
|
|
29
|
+
const config = await loadAppConfig(ctx, configPath);
|
|
30
|
+
if (config === null) return 1;
|
|
31
31
|
const { createRegistry } = await import("@cosmicdrift/kumiko-framework/engine");
|
|
32
32
|
const { createDbConnection } = await import("@cosmicdrift/kumiko-framework/db");
|
|
33
33
|
const {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
import type { CliCommandContext } from "./types";
|
|
3
|
+
|
|
4
|
+
export type AppConfig = { readonly features: readonly FeatureDefinition[] };
|
|
5
|
+
|
|
6
|
+
function isAppConfig(value: unknown): value is AppConfig {
|
|
7
|
+
return (
|
|
8
|
+
typeof value === "object" &&
|
|
9
|
+
value !== null &&
|
|
10
|
+
"features" in value &&
|
|
11
|
+
Array.isArray(value.features)
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// kumiko.config.ts is user-authored: a missing default export or `features`
|
|
16
|
+
// array must produce a readable message, not a TypeError further down.
|
|
17
|
+
export async function loadAppConfig(
|
|
18
|
+
ctx: CliCommandContext,
|
|
19
|
+
configPath: string,
|
|
20
|
+
): Promise<AppConfig | null> {
|
|
21
|
+
const mod: unknown = await import(configPath);
|
|
22
|
+
const config =
|
|
23
|
+
typeof mod === "object" && mod !== null && "default" in mod ? mod.default : undefined;
|
|
24
|
+
if (!isAppConfig(config)) {
|
|
25
|
+
ctx.out.err("");
|
|
26
|
+
ctx.out.err(` ${configPath} must default-export an object with a "features" array:`);
|
|
27
|
+
ctx.out.err(" export default { features: [myFeature] };");
|
|
28
|
+
ctx.out.err("");
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return config;
|
|
32
|
+
}
|
package/src/commands/project.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
|
+
import { loadAppConfig } from "./load-app-config";
|
|
2
3
|
import type { CliCommand, CliCommandContext } from "./types";
|
|
3
4
|
|
|
4
5
|
export const projectCommand: CliCommand = {
|
|
@@ -30,9 +31,8 @@ export const projectCommand: CliCommand = {
|
|
|
30
31
|
return 1;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
const config =
|
|
34
|
-
|
|
35
|
-
};
|
|
34
|
+
const config = await loadAppConfig(ctx, configPath);
|
|
35
|
+
if (config === null) return 1;
|
|
36
36
|
const { createRegistry } = await import("@cosmicdrift/kumiko-framework/engine");
|
|
37
37
|
const { createDbConnection } = await import("@cosmicdrift/kumiko-framework/db");
|
|
38
38
|
const {
|