@intentius/chant 0.0.16 → 0.0.22
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/bin/chant +4 -1
- package/package.json +20 -1
- package/src/build.test.ts +4 -2
- package/src/build.ts +3 -0
- package/src/builder.test.ts +3 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/astro.config.mjs +0 -3
- package/src/cli/commands/build.ts +5 -12
- package/src/cli/commands/diff.test.ts +2 -1
- package/src/cli/commands/diff.ts +2 -1
- package/src/cli/commands/init-lexicon.test.ts +0 -9
- package/src/cli/commands/init-lexicon.ts +0 -94
- package/src/cli/commands/init.ts +2 -20
- package/src/cli/handlers/build.ts +3 -3
- package/src/cli/handlers/lint.ts +2 -2
- package/src/cli/handlers/spell.ts +396 -0
- package/src/cli/handlers/state.ts +230 -0
- package/src/cli/lsp/server.test.ts +4 -0
- package/src/cli/main.ts +37 -3
- package/src/cli/mcp/server.test.ts +13 -9
- package/src/cli/mcp/server.ts +220 -6
- package/src/cli/mcp/tools/build.ts +2 -1
- package/src/cli/plugins.ts +1 -1
- package/src/cli/reporters/stylish.test.ts +2 -2
- package/src/cli/reporters/stylish.ts +1 -1
- package/src/codegen/docs.ts +13 -2
- package/src/composite.test.ts +1 -1
- package/src/config.ts +4 -0
- package/src/declarable.test.ts +2 -1
- package/src/declarable.ts +1 -1
- package/src/discovery/graph.test.ts +40 -0
- package/src/discovery/import.test.ts +5 -5
- package/src/discovery/resolve.test.ts +20 -0
- package/src/discovery/resolve.ts +2 -2
- package/src/index.ts +2 -0
- package/src/lexicon.ts +24 -0
- package/src/lint/rule-options.test.ts +3 -3
- package/src/lint/rule-registry.test.ts +1 -1
- package/src/lint/rules/composite-scope.ts +1 -1
- package/src/serializer-walker.ts +2 -1
- package/src/spell/discovery.ts +183 -0
- package/src/spell/index.ts +3 -0
- package/src/spell/prompt.ts +133 -0
- package/src/spell/types.ts +89 -0
- package/src/state/digest.ts +88 -0
- package/src/state/git.ts +317 -0
- package/src/state/index.ts +4 -0
- package/src/state/snapshot.ts +179 -0
- package/src/state/types.ts +59 -0
- package/src/types.ts +2 -1
- package/src/utils.test.ts +16 -3
- package/src/utils.ts +31 -1
- package/src/validation.test.ts +11 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/getting-started.mdx +0 -6
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/lint-rules.mdx +0 -6
- package/src/cli/commands/__fixtures__/init-lexicon-output/docs/src/content/docs/serialization.mdx +0 -6
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/actions/.gitkeep +0 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/composites/.gitkeep +0 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/coverage.ts +0 -11
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/import/generator.ts +0 -10
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/import/parser.ts +0 -10
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/lint/post-synth/.gitkeep +0 -0
package/bin/chant
CHANGED
|
@@ -15,6 +15,9 @@ MAIN_TS="$SCRIPT_DIR/../src/cli/main.ts"
|
|
|
15
15
|
|
|
16
16
|
if command -v bun >/dev/null 2>&1; then
|
|
17
17
|
exec bun "$MAIN_TS" "$@"
|
|
18
|
-
|
|
18
|
+
elif command -v npx >/dev/null 2>&1; then
|
|
19
19
|
exec npx tsx "$MAIN_TS" "$@"
|
|
20
|
+
else
|
|
21
|
+
echo "error: chant requires Bun (https://bun.sh) or Node.js (https://nodejs.org)" >&2
|
|
22
|
+
exit 1
|
|
20
23
|
fi
|
package/package.json
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
|
+
"description": "Declarative infrastructure-as-code toolkit — TypeScript on Bun",
|
|
4
5
|
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://intentius.io/chant",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/intentius/chant.git",
|
|
10
|
+
"directory": "packages/core"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/intentius/chant/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"infrastructure-as-code",
|
|
17
|
+
"iac",
|
|
18
|
+
"typescript",
|
|
19
|
+
"declarative",
|
|
20
|
+
"cloudformation",
|
|
21
|
+
"aws",
|
|
22
|
+
"devops"
|
|
23
|
+
],
|
|
5
24
|
"type": "module",
|
|
6
25
|
"files": [
|
|
7
26
|
"src/",
|
package/src/build.test.ts
CHANGED
|
@@ -189,10 +189,12 @@ export const betaEntity = {
|
|
|
189
189
|
expect(result.outputs.has("alpha")).toBe(true);
|
|
190
190
|
expect(result.outputs.has("beta")).toBe(true);
|
|
191
191
|
|
|
192
|
-
const
|
|
192
|
+
const alphaRaw = result.outputs.get("alpha")!;
|
|
193
|
+
const alphaOutput = JSON.parse(typeof alphaRaw === "string" ? alphaRaw : alphaRaw.primary);
|
|
193
194
|
expect(alphaOutput.alpha).toContain("alphaEntity");
|
|
194
195
|
|
|
195
|
-
const
|
|
196
|
+
const betaRaw = result.outputs.get("beta")!;
|
|
197
|
+
const betaOutput = JSON.parse(typeof betaRaw === "string" ? betaRaw : betaRaw.primary);
|
|
196
198
|
expect(betaOutput.beta).toContain("betaEntity");
|
|
197
199
|
});
|
|
198
200
|
|
package/src/build.ts
CHANGED
|
@@ -29,6 +29,8 @@ export interface BuildResult {
|
|
|
29
29
|
outputs: Map<string, string | SerializerResult>;
|
|
30
30
|
/** Map of entity name to Declarable entity */
|
|
31
31
|
entities: Map<string, Declarable>;
|
|
32
|
+
/** Resource-level dependency graph from discovery */
|
|
33
|
+
dependencies: Map<string, Set<string>>;
|
|
32
34
|
/** Array of warnings encountered during the build */
|
|
33
35
|
warnings: string[];
|
|
34
36
|
/** Array of errors encountered during discovery and build */
|
|
@@ -430,6 +432,7 @@ export async function build(
|
|
|
430
432
|
return {
|
|
431
433
|
outputs,
|
|
432
434
|
entities: discoveryResult.entities,
|
|
435
|
+
dependencies: discoveryResult.dependencies,
|
|
433
436
|
warnings,
|
|
434
437
|
errors,
|
|
435
438
|
manifest,
|
package/src/builder.test.ts
CHANGED
|
@@ -36,6 +36,7 @@ class SimpleResourceBuilder extends Builder<TestResource> {
|
|
|
36
36
|
throw new Error("Name and type are required");
|
|
37
37
|
}
|
|
38
38
|
return {
|
|
39
|
+
lexicon: "test",
|
|
39
40
|
entityType: "TestResource",
|
|
40
41
|
[DECLARABLE_MARKER]: true,
|
|
41
42
|
name: this.name,
|
|
@@ -72,6 +73,7 @@ class ValidatedResourceBuilder extends Builder<TestResource> {
|
|
|
72
73
|
throw new Error("Name and type are required");
|
|
73
74
|
}
|
|
74
75
|
return {
|
|
76
|
+
lexicon: "test",
|
|
75
77
|
entityType: "TestResource",
|
|
76
78
|
[DECLARABLE_MARKER]: true,
|
|
77
79
|
name: this.name,
|
|
@@ -103,6 +105,7 @@ class DefaultsResourceBuilder extends Builder<TestResource> {
|
|
|
103
105
|
|
|
104
106
|
build(): TestResource {
|
|
105
107
|
return {
|
|
108
|
+
lexicon: "test",
|
|
106
109
|
entityType: "TestResource",
|
|
107
110
|
[DECLARABLE_MARKER]: true,
|
|
108
111
|
name: this.name,
|
|
@@ -8,9 +8,6 @@ export default defineConfig({
|
|
|
8
8
|
title: 'Fixture',
|
|
9
9
|
sidebar: [
|
|
10
10
|
{ label: 'Overview', slug: '' },
|
|
11
|
-
{ label: 'Getting Started', slug: 'getting-started' },
|
|
12
|
-
{ label: 'Serialization', slug: 'serialization' },
|
|
13
|
-
{ label: 'Lint Rules', slug: 'lint-rules' },
|
|
14
11
|
],
|
|
15
12
|
}),
|
|
16
13
|
],
|
|
@@ -3,6 +3,7 @@ import type { Serializer, SerializerResult } from "../../serializer";
|
|
|
3
3
|
import type { LexiconPlugin } from "../../lexicon";
|
|
4
4
|
import { runPostSynthChecks } from "../../lint/post-synth";
|
|
5
5
|
import type { PostSynthCheck } from "../../lint/post-synth";
|
|
6
|
+
import { sortedJsonReplacer } from "../../utils";
|
|
6
7
|
import { formatError, formatWarning, formatSuccess, formatBold, formatInfo } from "../format";
|
|
7
8
|
import { writeFileSync } from "fs";
|
|
8
9
|
import { resolve, dirname, join } from "path";
|
|
@@ -214,6 +215,10 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
|
|
|
214
215
|
const resourceCount = result.entities.size;
|
|
215
216
|
const fileCount = result.sourceFileCount;
|
|
216
217
|
|
|
218
|
+
if (fileCount === 0 && errors.length === 0) {
|
|
219
|
+
console.error(formatInfo("No source files found — create .ts files in the target directory"));
|
|
220
|
+
}
|
|
221
|
+
|
|
217
222
|
if (options.verbose && errors.length === 0) {
|
|
218
223
|
console.error(
|
|
219
224
|
formatSuccess(
|
|
@@ -231,18 +236,6 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
|
|
|
231
236
|
};
|
|
232
237
|
}
|
|
233
238
|
|
|
234
|
-
/**
|
|
235
|
-
* JSON.stringify replacer that sorts object keys for deterministic output
|
|
236
|
-
*/
|
|
237
|
-
function sortedJsonReplacer(_key: string, value: unknown): unknown {
|
|
238
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
239
|
-
return Object.fromEntries(
|
|
240
|
-
Object.entries(value as Record<string, unknown>).sort(([a], [b]) => a.localeCompare(b))
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
return value;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
239
|
/**
|
|
247
240
|
* Simple JSON to YAML converter
|
|
248
241
|
*/
|
|
@@ -86,7 +86,8 @@ export const myBucket = {
|
|
|
86
86
|
const combined: Record<string, unknown> = {};
|
|
87
87
|
const sortedSerializerNames = [...buildResult.outputs.keys()].sort();
|
|
88
88
|
for (const serializerName of sortedSerializerNames) {
|
|
89
|
-
|
|
89
|
+
const raw = buildResult.outputs.get(serializerName)!;
|
|
90
|
+
combined[serializerName] = JSON.parse(typeof raw === "string" ? raw : raw.primary);
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
// Sort keys to match diffCommand behavior
|
package/src/cli/commands/diff.ts
CHANGED
|
@@ -46,7 +46,8 @@ export async function diffCommand(options: DiffOptions): Promise<DiffResult> {
|
|
|
46
46
|
const combined: Record<string, unknown> = {};
|
|
47
47
|
const sortedLexiconNames = [...result.outputs.keys()].sort();
|
|
48
48
|
for (const lexiconName of sortedLexiconNames) {
|
|
49
|
-
|
|
49
|
+
const raw = result.outputs.get(lexiconName)!;
|
|
50
|
+
combined[lexiconName] = JSON.parse(typeof raw === "string" ? raw : raw.primary);
|
|
50
51
|
}
|
|
51
52
|
const currentOutput = JSON.stringify(combined, sortedJsonReplacer, 2);
|
|
52
53
|
|
|
@@ -51,9 +51,6 @@ describe("initLexiconCommand", () => {
|
|
|
51
51
|
"src/lsp/hover.ts",
|
|
52
52
|
"src/lsp/completions.test.ts",
|
|
53
53
|
"src/lsp/hover.test.ts",
|
|
54
|
-
"src/import/parser.ts",
|
|
55
|
-
"src/import/generator.ts",
|
|
56
|
-
"src/coverage.ts",
|
|
57
54
|
"src/validate.ts",
|
|
58
55
|
"src/validate-cli.ts",
|
|
59
56
|
"package.json",
|
|
@@ -66,15 +63,9 @@ describe("initLexiconCommand", () => {
|
|
|
66
63
|
"docs/astro.config.mjs",
|
|
67
64
|
"docs/src/content.config.ts",
|
|
68
65
|
"docs/src/content/docs/index.mdx",
|
|
69
|
-
"docs/src/content/docs/getting-started.mdx",
|
|
70
|
-
"docs/src/content/docs/serialization.mdx",
|
|
71
|
-
"docs/src/content/docs/lint-rules.mdx",
|
|
72
66
|
"examples/getting-started/package.json",
|
|
73
67
|
"examples/getting-started/src/infra.ts",
|
|
74
68
|
"src/generated/.gitkeep",
|
|
75
|
-
"src/composites/.gitkeep",
|
|
76
|
-
"src/actions/.gitkeep",
|
|
77
|
-
"src/lint/post-synth/.gitkeep",
|
|
78
69
|
];
|
|
79
70
|
|
|
80
71
|
for (const file of expectedFiles) {
|
|
@@ -498,49 +498,6 @@ export function hover(ctx: HoverContext): HoverInfo | undefined {
|
|
|
498
498
|
`;
|
|
499
499
|
}
|
|
500
500
|
|
|
501
|
-
function generateImportParserTs(name: string): string {
|
|
502
|
-
return `import type { TemplateParser } from "@intentius/chant/import/parser";
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Template parser for importing external ${name} templates.
|
|
506
|
-
*
|
|
507
|
-
* TODO: Implement the TemplateParser interface for your format.
|
|
508
|
-
*/
|
|
509
|
-
// export class ${name.charAt(0).toUpperCase() + name.slice(1)}Parser implements TemplateParser {
|
|
510
|
-
// parse(data: unknown): IR { ... }
|
|
511
|
-
// }
|
|
512
|
-
`;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
function generateImportGeneratorTs(name: string): string {
|
|
516
|
-
return `import type { TypeScriptGenerator } from "@intentius/chant/import/generator";
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* TypeScript generator for converting imported ${name} templates.
|
|
520
|
-
*
|
|
521
|
-
* TODO: Implement the TypeScriptGenerator interface for your format.
|
|
522
|
-
*/
|
|
523
|
-
// export class ${name.charAt(0).toUpperCase() + name.slice(1)}Generator implements TypeScriptGenerator {
|
|
524
|
-
// generate(ir: IR): string { ... }
|
|
525
|
-
// }
|
|
526
|
-
`;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
function generateCoverageTs(name: string): string {
|
|
530
|
-
return `/**
|
|
531
|
-
* Coverage analysis for the ${name} lexicon.
|
|
532
|
-
*
|
|
533
|
-
* TODO: Implement coverage analysis that checks how much of the
|
|
534
|
-
* upstream spec is covered by the generated types.
|
|
535
|
-
*/
|
|
536
|
-
export async function analyzeCoverage(options?: { verbose?: boolean }): Promise<void> {
|
|
537
|
-
console.error("Coverage analysis not yet implemented");
|
|
538
|
-
// TODO: Read generated lexicon JSON, compare against upstream spec,
|
|
539
|
-
// and report coverage metrics.
|
|
540
|
-
}
|
|
541
|
-
`;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
501
|
function generateValidateTs(name: string): string {
|
|
545
502
|
return `/**
|
|
546
503
|
* Validate generated lexicon-${name} artifacts.
|
|
@@ -795,41 +752,6 @@ function generateExampleInfraTs(name: string, names: ReturnType<typeof deriveNam
|
|
|
795
752
|
`;
|
|
796
753
|
}
|
|
797
754
|
|
|
798
|
-
// ── Additional doc page generators ───────────────────────────────────
|
|
799
|
-
|
|
800
|
-
function generateDocsGettingStartedMdx(name: string): string {
|
|
801
|
-
const displayName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
802
|
-
return `---
|
|
803
|
-
title: Getting Started
|
|
804
|
-
description: Get started with the ${displayName} lexicon
|
|
805
|
-
---
|
|
806
|
-
|
|
807
|
-
TODO: Document how to set up a project using the ${displayName} lexicon.
|
|
808
|
-
`;
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
function generateDocsSerializationMdx(name: string): string {
|
|
812
|
-
const displayName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
813
|
-
return `---
|
|
814
|
-
title: Serialization
|
|
815
|
-
description: ${displayName} output format
|
|
816
|
-
---
|
|
817
|
-
|
|
818
|
-
TODO: Document the ${displayName} serialization format and output structure.
|
|
819
|
-
`;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
function generateDocsLintRulesMdx(name: string): string {
|
|
823
|
-
const displayName = name.charAt(0).toUpperCase() + name.slice(1);
|
|
824
|
-
return `---
|
|
825
|
-
title: Lint Rules
|
|
826
|
-
description: ${displayName} lint rules reference
|
|
827
|
-
---
|
|
828
|
-
|
|
829
|
-
TODO: Document the lint rules provided by the ${displayName} lexicon.
|
|
830
|
-
`;
|
|
831
|
-
}
|
|
832
|
-
|
|
833
755
|
// ── Docs site skeleton generators ────────────────────────────────────
|
|
834
756
|
|
|
835
757
|
function generateDocsPackageJson(name: string): string {
|
|
@@ -879,9 +801,6 @@ export default defineConfig({
|
|
|
879
801
|
title: '${displayName}',
|
|
880
802
|
sidebar: [
|
|
881
803
|
{ label: 'Overview', slug: '' },
|
|
882
|
-
{ label: 'Getting Started', slug: 'getting-started' },
|
|
883
|
-
{ label: 'Serialization', slug: 'serialization' },
|
|
884
|
-
{ label: 'Lint Rules', slug: 'lint-rules' },
|
|
885
804
|
],
|
|
886
805
|
}),
|
|
887
806
|
],
|
|
@@ -953,10 +872,6 @@ export async function initLexiconCommand(options: InitLexiconOptions): Promise<I
|
|
|
953
872
|
"src/lint",
|
|
954
873
|
"src/lint/rules",
|
|
955
874
|
"src/lsp",
|
|
956
|
-
"src/import",
|
|
957
|
-
"src/composites",
|
|
958
|
-
"src/actions",
|
|
959
|
-
"src/lint/post-synth",
|
|
960
875
|
"src/generated",
|
|
961
876
|
"docs",
|
|
962
877
|
"docs/src",
|
|
@@ -991,9 +906,6 @@ export async function initLexiconCommand(options: InitLexiconOptions): Promise<I
|
|
|
991
906
|
"src/lsp/hover.ts": generateLspHoverTs(name),
|
|
992
907
|
"src/lsp/completions.test.ts": generateCompletionsTestTs(),
|
|
993
908
|
"src/lsp/hover.test.ts": generateHoverTestTs(),
|
|
994
|
-
"src/import/parser.ts": generateImportParserTs(name),
|
|
995
|
-
"src/import/generator.ts": generateImportGeneratorTs(name),
|
|
996
|
-
"src/coverage.ts": generateCoverageTs(name),
|
|
997
909
|
"src/plugin.test.ts": generatePluginTestTs(name, names),
|
|
998
910
|
"src/serializer.test.ts": generateSerializerTestTs(name, names),
|
|
999
911
|
"src/validate.ts": generateValidateTs(name),
|
|
@@ -1008,9 +920,6 @@ export async function initLexiconCommand(options: InitLexiconOptions): Promise<I
|
|
|
1008
920
|
"docs/astro.config.mjs": generateDocsAstroConfig(name),
|
|
1009
921
|
"docs/src/content.config.ts": generateDocsContentConfig(),
|
|
1010
922
|
"docs/src/content/docs/index.mdx": generateDocsIndexMdx(name),
|
|
1011
|
-
"docs/src/content/docs/getting-started.mdx": generateDocsGettingStartedMdx(name),
|
|
1012
|
-
"docs/src/content/docs/serialization.mdx": generateDocsSerializationMdx(name),
|
|
1013
|
-
"docs/src/content/docs/lint-rules.mdx": generateDocsLintRulesMdx(name),
|
|
1014
923
|
"examples/getting-started/package.json": generateExamplePackageJson(name),
|
|
1015
924
|
"examples/getting-started/src/infra.ts": generateExampleInfraTs(name, names),
|
|
1016
925
|
};
|
|
@@ -1018,9 +927,6 @@ export async function initLexiconCommand(options: InitLexiconOptions): Promise<I
|
|
|
1018
927
|
// Write .gitkeep files
|
|
1019
928
|
const gitkeeps = [
|
|
1020
929
|
"src/generated/.gitkeep",
|
|
1021
|
-
"src/composites/.gitkeep",
|
|
1022
|
-
"src/actions/.gitkeep",
|
|
1023
|
-
"src/lint/post-synth/.gitkeep",
|
|
1024
930
|
];
|
|
1025
931
|
|
|
1026
932
|
for (const gk of gitkeeps) {
|
package/src/cli/commands/init.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { join, resolve, dirname } from "path";
|
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
import { homedir } from "os";
|
|
5
5
|
import { createInterface } from "readline";
|
|
6
|
-
import { z } from "zod";
|
|
7
6
|
import { formatSuccess, formatWarning } from "../format";
|
|
8
7
|
import { loadPlugin } from "../plugins";
|
|
9
8
|
|
|
@@ -18,17 +17,6 @@ function getChantVersion(): string {
|
|
|
18
17
|
}
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
/**
|
|
22
|
-
* Schema for validating generated package.json — catches template bugs early.
|
|
23
|
-
*/
|
|
24
|
-
const GeneratedPackageJsonSchema = z.object({
|
|
25
|
-
name: z.string().min(1),
|
|
26
|
-
version: z.string(),
|
|
27
|
-
type: z.literal("module"),
|
|
28
|
-
scripts: z.record(z.string(), z.string()),
|
|
29
|
-
dependencies: z.record(z.string(), z.string()),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
20
|
/**
|
|
33
21
|
* Init command options
|
|
34
22
|
*/
|
|
@@ -128,12 +116,6 @@ function generatePackageJson(lexicon: string, extraScripts?: Record<string, stri
|
|
|
128
116
|
},
|
|
129
117
|
};
|
|
130
118
|
|
|
131
|
-
// Validate generated output to catch template bugs
|
|
132
|
-
const result = GeneratedPackageJsonSchema.safeParse(pkg);
|
|
133
|
-
if (!result.success) {
|
|
134
|
-
throw new Error(`Bug: generated package.json is invalid: ${result.error.issues[0].message}`);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
119
|
return JSON.stringify(pkg, null, 2);
|
|
138
120
|
}
|
|
139
121
|
|
|
@@ -240,7 +222,7 @@ export interface ChantConfig {
|
|
|
240
222
|
/**
|
|
241
223
|
* Generate MCP config
|
|
242
224
|
*/
|
|
243
|
-
function generateMcpConfig(
|
|
225
|
+
function generateMcpConfig(pm: "bun" | "npm"): string {
|
|
244
226
|
const config = {
|
|
245
227
|
mcpServers: {
|
|
246
228
|
chant: {
|
|
@@ -454,7 +436,7 @@ export async function initCommand(options: InitOptions): Promise<InitResult> {
|
|
|
454
436
|
|
|
455
437
|
writeIfNotExists(
|
|
456
438
|
join(mcpDir, "mcp.json"),
|
|
457
|
-
generateMcpConfig(
|
|
439
|
+
generateMcpConfig(detectPackageManager(targetDir)),
|
|
458
440
|
`~/.${ide === "generic" ? "config/mcp" : ide}/mcp.json`,
|
|
459
441
|
createdFiles,
|
|
460
442
|
warnings,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildCommand, buildCommandWatch, printErrors, printWarnings } from "../commands/build";
|
|
2
|
-
import { formatInfo } from "../format";
|
|
2
|
+
import { formatError, formatInfo } from "../format";
|
|
3
3
|
import type { CommandContext } from "../registry";
|
|
4
4
|
|
|
5
5
|
export async function runBuild(ctx: CommandContext): Promise<number> {
|
|
@@ -10,14 +10,14 @@ export async function runBuild(ctx: CommandContext): Promise<number> {
|
|
|
10
10
|
if (args.lexicon) {
|
|
11
11
|
serializers = serializers.filter((s) => s.name === args.lexicon);
|
|
12
12
|
if (serializers.length === 0) {
|
|
13
|
-
console.error(`No serializer found for lexicon "${args.lexicon}". Available: ${ctx.serializers.map((s) => s.name).join(", ")}`);
|
|
13
|
+
console.error(formatError({ message: `No serializer found for lexicon "${args.lexicon}". Available: ${ctx.serializers.map((s) => s.name).join(", ")}` }));
|
|
14
14
|
return 1;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const buildFormat = (args.format || "json") as "json" | "yaml";
|
|
19
19
|
if (buildFormat !== "json" && buildFormat !== "yaml") {
|
|
20
|
-
console.error(`Invalid format for build: ${buildFormat}. Expected 'json' or 'yaml'.`);
|
|
20
|
+
console.error(formatError({ message: `Invalid format for build: ${buildFormat}. Expected 'json' or 'yaml'.` }));
|
|
21
21
|
return 1;
|
|
22
22
|
}
|
|
23
23
|
|
package/src/cli/handlers/lint.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { lintCommand, lintCommandWatch, printLintResult } from "../commands/lint";
|
|
2
|
-
import { formatInfo } from "../format";
|
|
2
|
+
import { formatError, formatInfo } from "../format";
|
|
3
3
|
import type { CommandContext } from "../registry";
|
|
4
4
|
|
|
5
5
|
export async function runLint(ctx: CommandContext): Promise<number> {
|
|
@@ -7,7 +7,7 @@ export async function runLint(ctx: CommandContext): Promise<number> {
|
|
|
7
7
|
|
|
8
8
|
const lintFormat = (args.format || "stylish") as "stylish" | "json" | "sarif";
|
|
9
9
|
if (lintFormat !== "stylish" && lintFormat !== "json" && lintFormat !== "sarif") {
|
|
10
|
-
console.error(`Invalid format for lint: ${lintFormat}. Expected 'stylish', 'json', or 'sarif'.`);
|
|
10
|
+
console.error(formatError({ message: `Invalid format for lint: ${lintFormat}. Expected 'stylish', 'json', or 'sarif'.` }));
|
|
11
11
|
return 1;
|
|
12
12
|
}
|
|
13
13
|
|