@metaobjectsdev/sdk 0.23.1 → 0.24.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/agent-context/skills/metaobjects-audit/SKILL.md +20 -7
- package/agent-context/skills/metaobjects-audit/references/capability-checklist.md +64 -18
- package/agent-context/skills/metaobjects-audit/references/csharp.md +2 -1
- package/agent-context/skills/metaobjects-audit/references/java.md +3 -2
- package/agent-context/skills/metaobjects-audit/references/kotlin.md +2 -1
- package/agent-context/skills/metaobjects-audit/references/requirements.md +3 -4
- package/agent-context/skills/metaobjects-audit/references/typescript.md +1 -1
- package/agent-context/skills/metaobjects-authoring/SKILL.md +28 -3
- package/agent-context/skills/metaobjects-authoring/references/requirements.md +49 -23
- package/agent-context/skills/metaobjects-codegen/SKILL.md +4 -3
- package/agent-context/skills/metaobjects-codegen/references/csharp.md +2 -2
- package/agent-context/skills/metaobjects-codegen/references/java.md +3 -3
- package/agent-context/skills/metaobjects-codegen/references/kotlin.md +4 -4
- package/agent-context/skills/metaobjects-codegen/references/python.md +2 -2
- package/agent-context/skills/metaobjects-codegen/references/typescript.md +3 -3
- package/agent-context/skills/metaobjects-fit-assessment/SKILL.md +4 -4
- package/agent-context/skills/metaobjects-prompts/SKILL.md +53 -32
- package/agent-context/skills/metaobjects-prompts/references/csharp.md +26 -21
- package/agent-context/skills/metaobjects-prompts/references/java.md +24 -18
- package/agent-context/skills/metaobjects-prompts/references/kotlin.md +25 -20
- package/agent-context/skills/metaobjects-prompts/references/python.md +68 -26
- package/agent-context/skills/metaobjects-prompts/references/typescript.md +29 -23
- package/agent-context/skills/metaobjects-verify/references/migration.md +1 -1
- package/agent-context/skills/metaobjects-verify/references/requirements.md +36 -22
- package/agent-context/templates/always-on.md.mustache +3 -1
- package/dist/agent-docs/body.d.ts +1 -1
- package/dist/agent-docs/body.d.ts.map +1 -1
- package/dist/agent-docs/body.js +24 -2
- package/dist/agent-docs/body.js.map +1 -1
- package/dist/collection.d.ts +71 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +121 -0
- package/dist/collection.js.map +1 -0
- package/dist/config.d.ts +51 -21
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +76 -10
- package/dist/config.js.map +1 -1
- package/dist/discovery.d.ts +43 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +100 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/memory.d.ts +42 -19
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +38 -95
- package/dist/memory.js.map +1 -1
- package/dist/metadata-files.d.ts +67 -0
- package/dist/metadata-files.d.ts.map +1 -0
- package/dist/metadata-files.js +155 -0
- package/dist/metadata-files.js.map +1 -0
- package/dist/records/any.d.ts +8 -8
- package/dist/records/decision.d.ts +2 -2
- package/dist/records/glossary.d.ts +4 -4
- package/dist/records/principle.d.ts +2 -2
- package/dist/scope.d.ts +16 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +75 -0
- package/dist/scope.js.map +1 -0
- package/dist/sources.d.ts +86 -0
- package/dist/sources.d.ts.map +1 -0
- package/dist/sources.js +130 -0
- package/dist/sources.js.map +1 -0
- package/package.json +2 -2
- package/src/agent-docs/body.ts +24 -2
- package/src/collection.ts +183 -0
- package/src/config.ts +80 -12
- package/src/discovery.ts +110 -0
- package/src/index.ts +26 -9
- package/src/memory.ts +65 -99
- package/src/metadata-files.ts +158 -0
- package/src/scope.ts +95 -0
- package/src/sources.ts +160 -0
package/dist/records/any.d.ts
CHANGED
|
@@ -127,6 +127,7 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
127
127
|
scope: z.ZodUnion<[z.ZodLiteral<"global">, z.ZodArray<z.ZodString, "many">]>;
|
|
128
128
|
}, "strip", z.ZodTypeAny, {
|
|
129
129
|
type: "decision";
|
|
130
|
+
scope: string[] | "global";
|
|
130
131
|
schema_version: 1;
|
|
131
132
|
id: string;
|
|
132
133
|
title: string;
|
|
@@ -141,7 +142,6 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
141
142
|
}[];
|
|
142
143
|
rationale: string;
|
|
143
144
|
alternatives_considered: string[];
|
|
144
|
-
scope: string[] | "global";
|
|
145
145
|
superseded_by?: string | undefined;
|
|
146
146
|
evidence?: {
|
|
147
147
|
commits?: string[] | undefined;
|
|
@@ -150,6 +150,7 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
150
150
|
} | undefined;
|
|
151
151
|
}, {
|
|
152
152
|
type: "decision";
|
|
153
|
+
scope: string[] | "global";
|
|
153
154
|
schema_version: 1;
|
|
154
155
|
id: string;
|
|
155
156
|
title: string;
|
|
@@ -159,7 +160,6 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
159
160
|
last_validated_against_commit: string;
|
|
160
161
|
rationale: string;
|
|
161
162
|
alternatives_considered: string[];
|
|
162
|
-
scope: string[] | "global";
|
|
163
163
|
superseded_by?: string | undefined;
|
|
164
164
|
evidence?: {
|
|
165
165
|
commits?: string[] | undefined;
|
|
@@ -216,6 +216,7 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
216
216
|
enforcement: z.ZodDefault<z.ZodEnum<["advisory", "block"]>>;
|
|
217
217
|
}, "strip", z.ZodTypeAny, {
|
|
218
218
|
type: "principle";
|
|
219
|
+
scope: string[];
|
|
219
220
|
schema_version: 1;
|
|
220
221
|
id: string;
|
|
221
222
|
title: string;
|
|
@@ -230,7 +231,6 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
230
231
|
}[];
|
|
231
232
|
examples: string[];
|
|
232
233
|
rationale: string;
|
|
233
|
-
scope: string[];
|
|
234
234
|
statement: string;
|
|
235
235
|
counter_examples: string[];
|
|
236
236
|
enforcement: "advisory" | "block";
|
|
@@ -242,6 +242,7 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
242
242
|
} | undefined;
|
|
243
243
|
}, {
|
|
244
244
|
type: "principle";
|
|
245
|
+
scope: string[];
|
|
245
246
|
schema_version: 1;
|
|
246
247
|
id: string;
|
|
247
248
|
title: string;
|
|
@@ -251,7 +252,6 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
251
252
|
last_validated_against_commit: string;
|
|
252
253
|
examples: string[];
|
|
253
254
|
rationale: string;
|
|
254
|
-
scope: string[];
|
|
255
255
|
statement: string;
|
|
256
256
|
counter_examples: string[];
|
|
257
257
|
superseded_by?: string | undefined;
|
|
@@ -310,11 +310,11 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
310
310
|
entity: z.ZodOptional<z.ZodString>;
|
|
311
311
|
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
312
312
|
}, "strip", z.ZodTypeAny, {
|
|
313
|
-
entity?: string | undefined;
|
|
314
313
|
files?: string[] | undefined;
|
|
315
|
-
}, {
|
|
316
314
|
entity?: string | undefined;
|
|
315
|
+
}, {
|
|
317
316
|
files?: string[] | undefined;
|
|
317
|
+
entity?: string | undefined;
|
|
318
318
|
}>;
|
|
319
319
|
see_also: z.ZodArray<z.ZodString, "many">;
|
|
320
320
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -335,8 +335,8 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
335
335
|
synonyms: string[];
|
|
336
336
|
definition: string;
|
|
337
337
|
code_anchors: {
|
|
338
|
-
entity?: string | undefined;
|
|
339
338
|
files?: string[] | undefined;
|
|
339
|
+
entity?: string | undefined;
|
|
340
340
|
};
|
|
341
341
|
see_also: string[];
|
|
342
342
|
superseded_by?: string | undefined;
|
|
@@ -358,8 +358,8 @@ export declare const AnyRecord: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
|
358
358
|
synonyms: string[];
|
|
359
359
|
definition: string;
|
|
360
360
|
code_anchors: {
|
|
361
|
-
entity?: string | undefined;
|
|
362
361
|
files?: string[] | undefined;
|
|
362
|
+
entity?: string | undefined;
|
|
363
363
|
};
|
|
364
364
|
see_also: string[];
|
|
365
365
|
superseded_by?: string | undefined;
|
|
@@ -41,6 +41,7 @@ export declare const DecisionRecord: z.ZodObject<{
|
|
|
41
41
|
scope: z.ZodUnion<[z.ZodLiteral<"global">, z.ZodArray<z.ZodString, "many">]>;
|
|
42
42
|
}, "strip", z.ZodTypeAny, {
|
|
43
43
|
type: "decision";
|
|
44
|
+
scope: string[] | "global";
|
|
44
45
|
schema_version: 1;
|
|
45
46
|
id: string;
|
|
46
47
|
title: string;
|
|
@@ -55,7 +56,6 @@ export declare const DecisionRecord: z.ZodObject<{
|
|
|
55
56
|
}[];
|
|
56
57
|
rationale: string;
|
|
57
58
|
alternatives_considered: string[];
|
|
58
|
-
scope: string[] | "global";
|
|
59
59
|
superseded_by?: string | undefined;
|
|
60
60
|
evidence?: {
|
|
61
61
|
commits?: string[] | undefined;
|
|
@@ -64,6 +64,7 @@ export declare const DecisionRecord: z.ZodObject<{
|
|
|
64
64
|
} | undefined;
|
|
65
65
|
}, {
|
|
66
66
|
type: "decision";
|
|
67
|
+
scope: string[] | "global";
|
|
67
68
|
schema_version: 1;
|
|
68
69
|
id: string;
|
|
69
70
|
title: string;
|
|
@@ -73,7 +74,6 @@ export declare const DecisionRecord: z.ZodObject<{
|
|
|
73
74
|
last_validated_against_commit: string;
|
|
74
75
|
rationale: string;
|
|
75
76
|
alternatives_considered: string[];
|
|
76
|
-
scope: string[] | "global";
|
|
77
77
|
superseded_by?: string | undefined;
|
|
78
78
|
evidence?: {
|
|
79
79
|
commits?: string[] | undefined;
|
|
@@ -43,11 +43,11 @@ export declare const GlossaryRecord: z.ZodObject<{
|
|
|
43
43
|
entity: z.ZodOptional<z.ZodString>;
|
|
44
44
|
files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
45
45
|
}, "strip", z.ZodTypeAny, {
|
|
46
|
-
entity?: string | undefined;
|
|
47
46
|
files?: string[] | undefined;
|
|
48
|
-
}, {
|
|
49
47
|
entity?: string | undefined;
|
|
48
|
+
}, {
|
|
50
49
|
files?: string[] | undefined;
|
|
50
|
+
entity?: string | undefined;
|
|
51
51
|
}>;
|
|
52
52
|
see_also: z.ZodArray<z.ZodString, "many">;
|
|
53
53
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -68,8 +68,8 @@ export declare const GlossaryRecord: z.ZodObject<{
|
|
|
68
68
|
synonyms: string[];
|
|
69
69
|
definition: string;
|
|
70
70
|
code_anchors: {
|
|
71
|
-
entity?: string | undefined;
|
|
72
71
|
files?: string[] | undefined;
|
|
72
|
+
entity?: string | undefined;
|
|
73
73
|
};
|
|
74
74
|
see_also: string[];
|
|
75
75
|
superseded_by?: string | undefined;
|
|
@@ -91,8 +91,8 @@ export declare const GlossaryRecord: z.ZodObject<{
|
|
|
91
91
|
synonyms: string[];
|
|
92
92
|
definition: string;
|
|
93
93
|
code_anchors: {
|
|
94
|
-
entity?: string | undefined;
|
|
95
94
|
files?: string[] | undefined;
|
|
95
|
+
entity?: string | undefined;
|
|
96
96
|
};
|
|
97
97
|
see_also: string[];
|
|
98
98
|
superseded_by?: string | undefined;
|
|
@@ -44,6 +44,7 @@ export declare const PrincipleRecord: z.ZodObject<{
|
|
|
44
44
|
enforcement: z.ZodDefault<z.ZodEnum<["advisory", "block"]>>;
|
|
45
45
|
}, "strip", z.ZodTypeAny, {
|
|
46
46
|
type: "principle";
|
|
47
|
+
scope: string[];
|
|
47
48
|
schema_version: 1;
|
|
48
49
|
id: string;
|
|
49
50
|
title: string;
|
|
@@ -58,7 +59,6 @@ export declare const PrincipleRecord: z.ZodObject<{
|
|
|
58
59
|
}[];
|
|
59
60
|
examples: string[];
|
|
60
61
|
rationale: string;
|
|
61
|
-
scope: string[];
|
|
62
62
|
statement: string;
|
|
63
63
|
counter_examples: string[];
|
|
64
64
|
enforcement: "advisory" | "block";
|
|
@@ -70,6 +70,7 @@ export declare const PrincipleRecord: z.ZodObject<{
|
|
|
70
70
|
} | undefined;
|
|
71
71
|
}, {
|
|
72
72
|
type: "principle";
|
|
73
|
+
scope: string[];
|
|
73
74
|
schema_version: 1;
|
|
74
75
|
id: string;
|
|
75
76
|
title: string;
|
|
@@ -79,7 +80,6 @@ export declare const PrincipleRecord: z.ZodObject<{
|
|
|
79
80
|
last_validated_against_commit: string;
|
|
80
81
|
examples: string[];
|
|
81
82
|
rationale: string;
|
|
82
|
-
scope: string[];
|
|
83
83
|
statement: string;
|
|
84
84
|
counter_examples: string[];
|
|
85
85
|
superseded_by?: string | undefined;
|
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** A consumer-side output filter over fully-qualified node names. */
|
|
2
|
+
export interface Scope {
|
|
3
|
+
/** Absent or empty means "everything". */
|
|
4
|
+
readonly include?: readonly string[];
|
|
5
|
+
/** Applied after `include`. */
|
|
6
|
+
readonly exclude?: readonly string[];
|
|
7
|
+
}
|
|
8
|
+
export interface CompiledScope {
|
|
9
|
+
readonly include: readonly RegExp[];
|
|
10
|
+
readonly exclude: readonly RegExp[];
|
|
11
|
+
}
|
|
12
|
+
export declare function compilePattern(pattern: string): RegExp;
|
|
13
|
+
export declare function compileScope(scope: Scope): CompiledScope;
|
|
14
|
+
/** True when `fqn` is inside the scope. An empty `include` means everything. */
|
|
15
|
+
export declare function matchesScope(fqn: string, compiled: CompiledScope): boolean;
|
|
16
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAkBA,qEAAqE;AACrE,MAAM,WAAW,KAAK;IACpB,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAuCD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAYtD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,aAAa,CAKxD;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAI1E"}
|
package/dist/scope.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// server/typescript/packages/sdk/src/scope.ts
|
|
2
|
+
//
|
|
3
|
+
// Phase-1 metadata-source-resolution — the scope pattern engine.
|
|
4
|
+
//
|
|
5
|
+
// A pure, no-I/O module deciding whether a fully-qualified node name falls
|
|
6
|
+
// inside a consumer's declared `include`/`exclude` scope. Source resolution
|
|
7
|
+
// and discovery (later phase-1 tasks) build on this; a cross-language
|
|
8
|
+
// conformance corpus pins its semantics, so exact pattern behavior matters.
|
|
9
|
+
// NOTE: PACKAGE_SEPARATOR is NOT re-exported from the browser-safe
|
|
10
|
+
// `@metaobjectsdev/metadata/constants` barrel (that barrel only re-exports
|
|
11
|
+
// the per-concern `*-constants.ts` modules; `PACKAGE_SEPARATOR` lives in
|
|
12
|
+
// `shared/structural.ts`, exported from the package root). This package
|
|
13
|
+
// (`@metaobjectsdev/sdk`) is server-side, not a `client/web/**` browser
|
|
14
|
+
// package, so importing metamodel values from the root — the same thing
|
|
15
|
+
// `memory.ts` and `forge-types.ts` in this package already do — is correct.
|
|
16
|
+
import { PACKAGE_SEPARATOR, ParseError, codeSource } from "@metaobjectsdev/metadata";
|
|
17
|
+
/** One package segment: any run of characters containing no separator char. */
|
|
18
|
+
const SEGMENT = "[^:]+";
|
|
19
|
+
/** One or more segments, separator-joined — the `**` expansion. */
|
|
20
|
+
const SEGMENTS = `${SEGMENT}(?:${PACKAGE_SEPARATOR}${SEGMENT})*`;
|
|
21
|
+
function escapeLiteral(text) {
|
|
22
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
23
|
+
}
|
|
24
|
+
/** Compile one segment. `**` spans segments; `*` never crosses a separator. */
|
|
25
|
+
function compileSegment(segment, pattern) {
|
|
26
|
+
if (segment.length === 0) {
|
|
27
|
+
throw new ParseError(`empty segment in scope pattern "${pattern}"`, {
|
|
28
|
+
code: "ERR_SCOPE_PATTERN_INVALID",
|
|
29
|
+
source: codeSource("compileSegment"),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
// A segment surviving the split on the two-character PACKAGE_SEPARATOR
|
|
33
|
+
// ("::") can still contain a lone ":" when the pattern has an odd colon
|
|
34
|
+
// run — e.g. "acme:::Order".split("::") => ["acme", ":Order"]. SEGMENT
|
|
35
|
+
// ([^:]+) already excludes ":" from a well-formed segment, so a leftover
|
|
36
|
+
// ":" here means the separator was malformed, not that ":" is meant
|
|
37
|
+
// literally. Left unchecked, escapeLiteral treats it as a literal
|
|
38
|
+
// character and compiles a regex requiring three colons in a row — which
|
|
39
|
+
// no legal "::"-joined fully-qualified name can ever contain, so the
|
|
40
|
+
// pattern silently matches nothing instead of failing loud.
|
|
41
|
+
if (segment.includes(":")) {
|
|
42
|
+
throw new ParseError(`scope pattern "${pattern}" has a malformed separator (an odd run of ":") — segments are joined by "::", never a single ":"`, { code: "ERR_SCOPE_PATTERN_INVALID", source: codeSource("compileSegment") });
|
|
43
|
+
}
|
|
44
|
+
if (segment === "**")
|
|
45
|
+
return `(?:${SEGMENTS})`;
|
|
46
|
+
// `*` inside a segment matches any characters except the separator char.
|
|
47
|
+
return segment.split("*").map(escapeLiteral).join("[^:]*");
|
|
48
|
+
}
|
|
49
|
+
export function compilePattern(pattern) {
|
|
50
|
+
if (pattern.length === 0) {
|
|
51
|
+
throw new ParseError(`scope pattern must not be empty`, {
|
|
52
|
+
code: "ERR_SCOPE_PATTERN_INVALID",
|
|
53
|
+
source: codeSource("compilePattern"),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const body = pattern
|
|
57
|
+
.split(PACKAGE_SEPARATOR)
|
|
58
|
+
.map((segment) => compileSegment(segment, pattern))
|
|
59
|
+
.join(PACKAGE_SEPARATOR);
|
|
60
|
+
return new RegExp(`^${body}$`);
|
|
61
|
+
}
|
|
62
|
+
export function compileScope(scope) {
|
|
63
|
+
return {
|
|
64
|
+
include: (scope.include ?? []).map(compilePattern),
|
|
65
|
+
exclude: (scope.exclude ?? []).map(compilePattern),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** True when `fqn` is inside the scope. An empty `include` means everything. */
|
|
69
|
+
export function matchesScope(fqn, compiled) {
|
|
70
|
+
const included = compiled.include.length === 0 || compiled.include.some((re) => re.test(fqn));
|
|
71
|
+
if (!included)
|
|
72
|
+
return false;
|
|
73
|
+
return !compiled.exclude.some((re) => re.test(fqn));
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/** Tagged union of source kinds. `resource` and `package` are declared now so
|
|
2
|
+
* the config shape is stable across phases; only `path` resolves in phase 1 —
|
|
3
|
+
* `resource`/`package` throw `ERR_SOURCE_KIND_UNSUPPORTED`. */
|
|
4
|
+
export type SourceSpec = {
|
|
5
|
+
readonly path: string;
|
|
6
|
+
} | {
|
|
7
|
+
readonly resource: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly package: string;
|
|
10
|
+
};
|
|
11
|
+
export interface ResolvedSource {
|
|
12
|
+
/** Absolute path of one metadata file. */
|
|
13
|
+
readonly file: string;
|
|
14
|
+
/** The spec that contributed it — provenance for diagnostics. */
|
|
15
|
+
readonly spec: SourceSpec;
|
|
16
|
+
}
|
|
17
|
+
/** Used when `sources` is absent or empty in `.metaobjects/config.json`. A
|
|
18
|
+
* DEFAULT, never a requirement — a project that declares `sources` explicitly
|
|
19
|
+
* need not include the default directory at all. Built from
|
|
20
|
+
* `DEFAULT_METADATA_DIR` (`metadata-files.ts`'s single definition) rather than
|
|
21
|
+
* restating that name here: a second independent encoding of the same
|
|
22
|
+
* default would let `resolveCollection`'s "does the default dir exist"
|
|
23
|
+
* check (`collection.ts`) desync from what `resolveSources` actually
|
|
24
|
+
* resolves the moment the default ever changed — silently reproducing the
|
|
25
|
+
* "two code paths disagree about where metadata lives" class of bug this
|
|
26
|
+
* whole mechanism exists to eliminate. */
|
|
27
|
+
export declare const DEFAULT_SOURCES: readonly SourceSpec[];
|
|
28
|
+
/**
|
|
29
|
+
* The declared source SET in CANONICAL order — kind-validated, then sorted by
|
|
30
|
+
* spec CONTENT rather than by declaration order.
|
|
31
|
+
*
|
|
32
|
+
* This is the ONE place declaration order is discarded, and the module's "pure
|
|
33
|
+
* function of the SET" invariant rests on it: the emitted file order, the spec
|
|
34
|
+
* attributed to a file two specs both reach, and which of several unresolvable
|
|
35
|
+
* paths reports its `ERR_SOURCE_UNRESOLVED` first are all decided here.
|
|
36
|
+
* Validation runs across the WHOLE list before any sorting or filesystem I/O —
|
|
37
|
+
* interleaved with resolution, which error code came back would depend on
|
|
38
|
+
* declaration order, contradicting that same invariant.
|
|
39
|
+
*
|
|
40
|
+
* Exported because `resolveCollection` derives `sourceRoots` from the declared
|
|
41
|
+
* specs and must use this identical ordering; a second sort would be a second
|
|
42
|
+
* definition of "canonical".
|
|
43
|
+
*/
|
|
44
|
+
export declare function orderedPathSpecs(specs: readonly SourceSpec[]): {
|
|
45
|
+
readonly path: string;
|
|
46
|
+
}[];
|
|
47
|
+
/**
|
|
48
|
+
* Where a declared `path` source lives on disk: absolute as written, otherwise
|
|
49
|
+
* relative to the DECLARING config's directory — never to ambient
|
|
50
|
+
* `process.cwd()`.
|
|
51
|
+
*
|
|
52
|
+
* One definition, because this expression *is* the rule for where a declared
|
|
53
|
+
* source lives, which is the single piece of knowledge this module exists to
|
|
54
|
+
* own. A caller that needs a source's root directory (rather than its files)
|
|
55
|
+
* calls this rather than restating it.
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveSpecPath(configDir: string, spec: {
|
|
58
|
+
readonly path: string;
|
|
59
|
+
}): string;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve a declared source SET to a canonically-ordered list of metadata files.
|
|
62
|
+
*
|
|
63
|
+
* The full result — each entry's `.file` AND its `.spec` — is a pure function
|
|
64
|
+
* of the SET of `specs`: permuting `specs` cannot change the output. One thing
|
|
65
|
+
* makes that hold: the specs are processed in CONTENT order
|
|
66
|
+
* (`JSON.stringify(spec)`, ascending) rather than declared order, so both the
|
|
67
|
+
* emitted file order and the spec attributed to a file overlapping two specs
|
|
68
|
+
* are decided by content alone. Declared order carries no information anywhere
|
|
69
|
+
* in this function.
|
|
70
|
+
*
|
|
71
|
+
* Within one directory spec the file order is `listMetadataFiles`'s — files at
|
|
72
|
+
* a level, then that level's subdirectories, depth-first. That is deliberately
|
|
73
|
+
* NOT a flat sort of absolute paths: see the file header, and
|
|
74
|
+
* `test/source-order.test.ts`.
|
|
75
|
+
*
|
|
76
|
+
* Only `path` specs resolve in phase 1: a directory is walked recursively, a
|
|
77
|
+
* file is taken as-is. An unresolvable `path` throws `ERR_SOURCE_UNRESOLVED`
|
|
78
|
+
* rather than silently contributing nothing; `resource`/`package` specs throw
|
|
79
|
+
* `ERR_SOURCE_KIND_UNSUPPORTED`.
|
|
80
|
+
*
|
|
81
|
+
* @param configDir absolute directory of the declaring config (the parent of
|
|
82
|
+
* `.metaobjects/`) — relative `path` specs resolve against it, never against
|
|
83
|
+
* ambient `process.cwd()`.
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveSources(configDir: string, specs: readonly SourceSpec[]): Promise<ResolvedSource[]>;
|
|
86
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../src/sources.ts"],"names":[],"mappings":"AA2BA;;gEAEgE;AAChE,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAED;;;;;;;;;2CAS2C;AAC3C,eAAO,MAAM,eAAe,EAAE,SAAS,UAAU,EAAqC,CAAC;AAgBvF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAK1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,UAAU,EAAE,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC,CA0B3B"}
|
package/dist/sources.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// server/typescript/packages/sdk/src/sources.ts
|
|
2
|
+
//
|
|
3
|
+
// Phase-1 metadata-source-resolution — source spec resolution.
|
|
4
|
+
//
|
|
5
|
+
// Turns a declared source SET (`.metaobjects/config.json`'s `sources`) into a
|
|
6
|
+
// canonically-ordered, de-duplicated list of metadata file paths. The FULL
|
|
7
|
+
// result — including which spec each entry attributes to — is a pure
|
|
8
|
+
// function of the source SET, never of declaration order: permuting `specs`
|
|
9
|
+
// cannot change the output, even when two specs overlap on the same file.
|
|
10
|
+
// `test/order-independence.test.ts` pins that (the design's linchpin), so the
|
|
11
|
+
// canonical spec ordering below is load-bearing.
|
|
12
|
+
//
|
|
13
|
+
// Canonical is NOT the same as "flat-sorted". Within one directory spec the
|
|
14
|
+
// order is `listMetadataFiles`'s (metadata-files.ts) — files at a level, then
|
|
15
|
+
// that level's subdirectories, depth-first — because that is the order production
|
|
16
|
+
// has always handed the loader, and declaration order survives into generated
|
|
17
|
+
// output (the barrel's export list, the shared `enums.ts`, `meta docs` page
|
|
18
|
+
// order, `meta export`'s sibling order). A flat sort of absolute paths
|
|
19
|
+
// silently reorders any project with a subdirectory whose name sorts before a
|
|
20
|
+
// sibling file. Across specs, order is decided by spec CONTENT, which is what
|
|
21
|
+
// keeps the whole result permutation-invariant. `test/source-order.test.ts`
|
|
22
|
+
// pins both halves.
|
|
23
|
+
import { stat } from "node:fs/promises";
|
|
24
|
+
import { isAbsolute, resolve } from "node:path";
|
|
25
|
+
import { ParseError, codeSource } from "@metaobjectsdev/metadata";
|
|
26
|
+
import { DEFAULT_METADATA_DIR, listMetadataFiles } from "./metadata-files.js";
|
|
27
|
+
/** Used when `sources` is absent or empty in `.metaobjects/config.json`. A
|
|
28
|
+
* DEFAULT, never a requirement — a project that declares `sources` explicitly
|
|
29
|
+
* need not include the default directory at all. Built from
|
|
30
|
+
* `DEFAULT_METADATA_DIR` (`metadata-files.ts`'s single definition) rather than
|
|
31
|
+
* restating that name here: a second independent encoding of the same
|
|
32
|
+
* default would let `resolveCollection`'s "does the default dir exist"
|
|
33
|
+
* check (`collection.ts`) desync from what `resolveSources` actually
|
|
34
|
+
* resolves the moment the default ever changed — silently reproducing the
|
|
35
|
+
* "two code paths disagree about where metadata lives" class of bug this
|
|
36
|
+
* whole mechanism exists to eliminate. */
|
|
37
|
+
export const DEFAULT_SOURCES = [{ path: DEFAULT_METADATA_DIR }];
|
|
38
|
+
/** Narrows `spec` to its `path` arm, throwing `ERR_SOURCE_KIND_UNSUPPORTED`
|
|
39
|
+
* for `resource`/`package` — phase 1 resolves `path` only. Returns rather than
|
|
40
|
+
* asserting so one call both validates and narrows: an `asserts` signature has
|
|
41
|
+
* to be re-invoked wherever TypeScript's control-flow analysis cannot carry the
|
|
42
|
+
* narrowing, which is a language workaround masquerading as a second check. */
|
|
43
|
+
function toPathSpec(spec) {
|
|
44
|
+
if ("path" in spec)
|
|
45
|
+
return spec;
|
|
46
|
+
const kind = "resource" in spec ? "resource" : "package";
|
|
47
|
+
throw new ParseError(`source kind "${kind}" is not supported by this toolchain yet; use a "path" source`, { code: "ERR_SOURCE_KIND_UNSUPPORTED", source: codeSource("resolveSources") });
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The declared source SET in CANONICAL order — kind-validated, then sorted by
|
|
51
|
+
* spec CONTENT rather than by declaration order.
|
|
52
|
+
*
|
|
53
|
+
* This is the ONE place declaration order is discarded, and the module's "pure
|
|
54
|
+
* function of the SET" invariant rests on it: the emitted file order, the spec
|
|
55
|
+
* attributed to a file two specs both reach, and which of several unresolvable
|
|
56
|
+
* paths reports its `ERR_SOURCE_UNRESOLVED` first are all decided here.
|
|
57
|
+
* Validation runs across the WHOLE list before any sorting or filesystem I/O —
|
|
58
|
+
* interleaved with resolution, which error code came back would depend on
|
|
59
|
+
* declaration order, contradicting that same invariant.
|
|
60
|
+
*
|
|
61
|
+
* Exported because `resolveCollection` derives `sourceRoots` from the declared
|
|
62
|
+
* specs and must use this identical ordering; a second sort would be a second
|
|
63
|
+
* definition of "canonical".
|
|
64
|
+
*/
|
|
65
|
+
export function orderedPathSpecs(specs) {
|
|
66
|
+
return specs.map(toPathSpec).sort((a, b) => {
|
|
67
|
+
const [ja, jb] = [JSON.stringify(a), JSON.stringify(b)];
|
|
68
|
+
return ja < jb ? -1 : ja > jb ? 1 : 0;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Where a declared `path` source lives on disk: absolute as written, otherwise
|
|
73
|
+
* relative to the DECLARING config's directory — never to ambient
|
|
74
|
+
* `process.cwd()`.
|
|
75
|
+
*
|
|
76
|
+
* One definition, because this expression *is* the rule for where a declared
|
|
77
|
+
* source lives, which is the single piece of knowledge this module exists to
|
|
78
|
+
* own. A caller that needs a source's root directory (rather than its files)
|
|
79
|
+
* calls this rather than restating it.
|
|
80
|
+
*/
|
|
81
|
+
export function resolveSpecPath(configDir, spec) {
|
|
82
|
+
return isAbsolute(spec.path) ? spec.path : resolve(configDir, spec.path);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Resolve a declared source SET to a canonically-ordered list of metadata files.
|
|
86
|
+
*
|
|
87
|
+
* The full result — each entry's `.file` AND its `.spec` — is a pure function
|
|
88
|
+
* of the SET of `specs`: permuting `specs` cannot change the output. One thing
|
|
89
|
+
* makes that hold: the specs are processed in CONTENT order
|
|
90
|
+
* (`JSON.stringify(spec)`, ascending) rather than declared order, so both the
|
|
91
|
+
* emitted file order and the spec attributed to a file overlapping two specs
|
|
92
|
+
* are decided by content alone. Declared order carries no information anywhere
|
|
93
|
+
* in this function.
|
|
94
|
+
*
|
|
95
|
+
* Within one directory spec the file order is `listMetadataFiles`'s — files at
|
|
96
|
+
* a level, then that level's subdirectories, depth-first. That is deliberately
|
|
97
|
+
* NOT a flat sort of absolute paths: see the file header, and
|
|
98
|
+
* `test/source-order.test.ts`.
|
|
99
|
+
*
|
|
100
|
+
* Only `path` specs resolve in phase 1: a directory is walked recursively, a
|
|
101
|
+
* file is taken as-is. An unresolvable `path` throws `ERR_SOURCE_UNRESOLVED`
|
|
102
|
+
* rather than silently contributing nothing; `resource`/`package` specs throw
|
|
103
|
+
* `ERR_SOURCE_KIND_UNSUPPORTED`.
|
|
104
|
+
*
|
|
105
|
+
* @param configDir absolute directory of the declaring config (the parent of
|
|
106
|
+
* `.metaobjects/`) — relative `path` specs resolve against it, never against
|
|
107
|
+
* ambient `process.cwd()`.
|
|
108
|
+
*/
|
|
109
|
+
export async function resolveSources(configDir, specs) {
|
|
110
|
+
// Kind-validated and content-ordered in one pass — see `orderedPathSpecs`.
|
|
111
|
+
const ordered = orderedPathSpecs(specs);
|
|
112
|
+
// Insertion order IS output order — a Map preserves it, so the per-spec walk
|
|
113
|
+
// order above survives to the caller. First contributor wins a shared file,
|
|
114
|
+
// which is content-determined because `ordered` is.
|
|
115
|
+
const byFile = new Map();
|
|
116
|
+
for (const spec of ordered) {
|
|
117
|
+
const target = resolveSpecPath(configDir, spec);
|
|
118
|
+
const stats = await stat(target).catch(() => undefined);
|
|
119
|
+
if (stats === undefined) {
|
|
120
|
+
throw new ParseError(`source path "${spec.path}" does not exist (resolved to ${target}, relative to ${configDir})`, { code: "ERR_SOURCE_UNRESOLVED", source: codeSource("resolveSources") });
|
|
121
|
+
}
|
|
122
|
+
const found = stats.isDirectory() ? await listMetadataFiles(target) : [target];
|
|
123
|
+
for (const file of found) {
|
|
124
|
+
if (!byFile.has(file))
|
|
125
|
+
byFile.set(file, spec);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return [...byFile].map(([file, spec]) => ({ file, spec }));
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../src/sources.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaobjectsdev/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Workspace helpers and agent-docs utilities for MetaObjects projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@metaobjectsdev/metadata": "0.
|
|
59
|
+
"@metaobjectsdev/metadata": "0.24.0",
|
|
60
60
|
"zod": "^3.23.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
package/src/agent-docs/body.ts
CHANGED
|
@@ -222,7 +222,7 @@ export default defineConfig({
|
|
|
222
222
|
|
|
223
223
|
Filters live on the generator entry: \`routesFile({ filter: e => e.name !== "AuditLog" })\`
|
|
224
224
|
|
|
225
|
-
\`.metaobjects/config.json\`
|
|
225
|
+
\`.metaobjects/config.json\` holds static project state (schema_version, pending_in_git, confidence_thresholds) **and \`sources\` — the set of places your metadata comes from** (see "Where metadata comes from" below). Generator wiring belongs in \`metaobjects.config.ts\` so TypeScript can type-check the imports.
|
|
226
226
|
|
|
227
227
|
## Generated hooks + grids (TanStack)
|
|
228
228
|
|
|
@@ -503,13 +503,35 @@ metaobjects/
|
|
|
503
503
|
└── _pending/<pkg>.json proposed packages awaiting review
|
|
504
504
|
|
|
505
505
|
.metaobjects/
|
|
506
|
-
├── config.json static project state
|
|
506
|
+
├── config.json static project state + \`sources\`
|
|
507
507
|
├── migrations/ written by meta migrate
|
|
508
508
|
└── .gen-state/ codegen merge base (gitignored)
|
|
509
509
|
|
|
510
510
|
metaobjects.config.ts generator wiring (committed)
|
|
511
511
|
\`\`\`
|
|
512
512
|
|
|
513
|
+
### Where metadata comes from — the \`sources\` set
|
|
514
|
+
|
|
515
|
+
**\`metaobjects/\` is the DEFAULT VALUE of \`sources\`, not a requirement.** When \`sources\` is absent or empty in \`.metaobjects/config.json\`, it takes that default — the \`metaobjects/\` directory beside the \`.metaobjects/\` folder holding the config. \`meta init\` scaffolds \`"sources": []\`, so a project that does nothing takes the default.
|
|
516
|
+
|
|
517
|
+
Do NOT assume that directory exists. A project may declare \`sources\` and put its metadata anywhere — a sibling module, a shared model repository, a single file — and need not have a directory of that name at all:
|
|
518
|
+
|
|
519
|
+
\`\`\`json
|
|
520
|
+
{
|
|
521
|
+
"schema_version": 1,
|
|
522
|
+
"sources": [
|
|
523
|
+
{ "path": "../model/src/main/resources/metadata" },
|
|
524
|
+
{ "path": "metaobjects" }
|
|
525
|
+
]
|
|
526
|
+
}
|
|
527
|
+
\`\`\`
|
|
528
|
+
|
|
529
|
+
\`meta gen\`, \`meta migrate\`, \`meta verify\`, \`meta docs\` and \`meta export\` all read exactly that set, so pointing \`sources\` elsewhere moves every command together. A \`path\` is read **in place and never installed** or copied.
|
|
530
|
+
|
|
531
|
+
\`sources\` is read by **all four CLI surfaces** — the Node \`meta\` CLI, \`dotnet meta\` (C#), \`metaobjects\` (Python) and \`metaobjects:generate\` (Java and Kotlin, via Maven). Each resolves the same files from the same declaration.
|
|
532
|
+
|
|
533
|
+
**\`sources\` is a set, not an ordered list** — resolution is order-independent, so declaration order never changes what loads. \`config.json\` also rejects unknown top-level keys, so a misspelled key is an error rather than a silently ignored one.
|
|
534
|
+
|
|
513
535
|
## Worked example
|
|
514
536
|
|
|
515
537
|
\`\`\`json
|