@fenglimg/fabric-shared 1.0.0 → 1.1.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/dist/index.js CHANGED
@@ -6,22 +6,79 @@ import {
6
6
  enMessages,
7
7
  normalizeLocale,
8
8
  zhCNMessages
9
- } from "./chunk-2MXNG23L.js";
9
+ } from "./chunk-WAVM556O.js";
10
10
  import "./chunk-LXNCAKJZ.js";
11
11
 
12
12
  // src/schemas/agents-meta.ts
13
13
  import { z } from "zod";
14
- var agentsMetaNodeSchema = z.object({
14
+ var FABRIC_AGENTS_PREFIX = ".fabric/agents/";
15
+ var AGENTS_META_LAYERS = ["L0", "L1", "L2"];
16
+ var AGENTS_META_TOPOLOGY_TYPES = ["mirror", "cross-cutting"];
17
+ var agentsLayerSchema = z.enum(AGENTS_META_LAYERS);
18
+ var agentsTopologyTypeSchema = z.enum(AGENTS_META_TOPOLOGY_TYPES);
19
+ var agentsMetaNodeBaseSchema = z.object({
15
20
  file: z.string(),
16
21
  scope_glob: z.string(),
17
22
  deps: z.array(z.string()),
18
23
  priority: z.enum(["high", "medium", "low"]),
24
+ layer: agentsLayerSchema,
25
+ topology_type: agentsTopologyTypeSchema,
19
26
  hash: z.string()
20
27
  });
28
+ var agentsMetaNodeSchema = z.preprocess((value) => {
29
+ if (!isRecord(value) || typeof value.file !== "string") {
30
+ return value;
31
+ }
32
+ return withDerivedAgentsMetaNodeDefaults(value);
33
+ }, agentsMetaNodeBaseSchema);
21
34
  var agentsMetaSchema = z.object({
22
35
  revision: z.string(),
23
36
  nodes: z.record(agentsMetaNodeSchema)
24
37
  });
38
+ function withDerivedAgentsMetaNodeDefaults(node) {
39
+ return {
40
+ ...node,
41
+ layer: node.layer ?? deriveAgentsMetaLayer(node.file),
42
+ topology_type: node.topology_type ?? deriveAgentsMetaTopologyType(node.file)
43
+ };
44
+ }
45
+ function deriveAgentsMetaLayer(file) {
46
+ const normalized = normalizePath(file);
47
+ if (normalized === "AGENTS.md") {
48
+ return "L0";
49
+ }
50
+ if (hasCrossCuttingSegment(normalized)) {
51
+ return "L1";
52
+ }
53
+ const depthSource = getDepthSource(normalized);
54
+ const directoryDepth = getDirectoryDepth(depthSource);
55
+ if (directoryDepth === 0) {
56
+ return "L0";
57
+ }
58
+ if (directoryDepth <= 2) {
59
+ return "L1";
60
+ }
61
+ return "L2";
62
+ }
63
+ function deriveAgentsMetaTopologyType(file) {
64
+ return hasCrossCuttingSegment(normalizePath(file)) ? "cross-cutting" : "mirror";
65
+ }
66
+ function getDepthSource(file) {
67
+ return file.startsWith(FABRIC_AGENTS_PREFIX) ? file.slice(FABRIC_AGENTS_PREFIX.length) : file;
68
+ }
69
+ function getDirectoryDepth(file) {
70
+ const segments = file.split("/").filter(Boolean);
71
+ return Math.max(segments.length - 1, 0);
72
+ }
73
+ function hasCrossCuttingSegment(file) {
74
+ return file.split("/").includes("_cross");
75
+ }
76
+ function normalizePath(value) {
77
+ return value.replaceAll("\\", "/");
78
+ }
79
+ function isRecord(value) {
80
+ return typeof value === "object" && value !== null;
81
+ }
25
82
 
26
83
  // src/schemas/api-contracts.ts
27
84
  import { z as z2 } from "zod";
@@ -123,6 +180,7 @@ var humanLockFileSchema = z4.object({
123
180
 
124
181
  // src/schemas/fabric-config.ts
125
182
  import { z as z5 } from "zod";
183
+ var auditModeSchema = z5.enum(["strict", "warn", "off"]);
126
184
  var clientPathsSchema = z5.object({
127
185
  claudeCodeCLI: z5.string().optional(),
128
186
  claudeCodeDesktop: z5.string().optional(),
@@ -135,7 +193,9 @@ var clientPathsSchema = z5.object({
135
193
  var fabricConfigSchema = z5.object({
136
194
  clientPaths: clientPathsSchema.optional(),
137
195
  externalFixturePath: z5.string().optional(),
138
- scanIgnores: z5.array(z5.string()).optional()
196
+ scanIgnores: z5.array(z5.string()).optional(),
197
+ auditMode: auditModeSchema.optional(),
198
+ audit_mode: auditModeSchema.optional()
139
199
  });
140
200
 
141
201
  // src/schemas/forensic-report.ts
@@ -146,6 +206,26 @@ var forensicCodeSampleSchema = z6.object({
146
206
  snippet: z6.string(),
147
207
  pattern_hint: z6.string()
148
208
  });
209
+ var forensicEvidenceAnchorSchema = z6.object({
210
+ file: z6.string(),
211
+ line: z6.string(),
212
+ snippet: z6.string()
213
+ });
214
+ var forensicAssertionCoverageSchema = z6.object({
215
+ ratio: z6.number().min(0).max(1),
216
+ total: z6.number().int().nonnegative(),
217
+ matched: z6.number().int().nonnegative(),
218
+ co_occurring_patterns: z6.array(z6.string())
219
+ });
220
+ var forensicAssertionSchema = z6.object({
221
+ type: z6.enum(["framework", "pattern", "invariant", "domain"]),
222
+ statement: z6.string(),
223
+ confidence: z6.enum(["HIGH", "MEDIUM", "LOW"]),
224
+ evidence: z6.array(forensicEvidenceAnchorSchema),
225
+ coverage: forensicAssertionCoverageSchema,
226
+ proposed_rule: z6.string().optional(),
227
+ alternatives: z6.array(z6.string()).optional()
228
+ });
149
229
  var forensicTopologySchema = z6.object({
150
230
  total_files: z6.number().int().nonnegative(),
151
231
  by_ext: z6.record(z6.number().int().nonnegative()),
@@ -168,6 +248,15 @@ var forensicReadmeSchema = z6.object({
168
248
  line_count: z6.number().int().nonnegative(),
169
249
  has_contributing: z6.boolean()
170
250
  });
251
+ var candidateFileEntrySchema = z6.object({
252
+ path: z6.string(),
253
+ family: z6.enum(["entry", "component", "config", "test", "domain"]),
254
+ rationale: z6.string()
255
+ });
256
+ var forensicSamplingBudgetSchema = z6.object({
257
+ max_files: z6.literal(15),
258
+ max_lines_per_file: z6.literal(100)
259
+ });
171
260
  var forensicReportSchema = z6.object({
172
261
  version: z6.string(),
173
262
  generated_at: z6.string(),
@@ -178,8 +267,11 @@ var forensicReportSchema = z6.object({
178
267
  topology: forensicTopologySchema,
179
268
  entry_points: z6.array(forensicEntryPointSchema),
180
269
  code_samples: z6.array(forensicCodeSampleSchema),
270
+ assertions: z6.array(forensicAssertionSchema),
271
+ candidate_files: z6.array(candidateFileEntrySchema),
272
+ sampling_budget: forensicSamplingBudgetSchema,
181
273
  readme: forensicReadmeSchema,
182
- recommendations_for_skill: z6.array(z6.string())
274
+ recommendations_for_skill: z6.array(z6.string()).optional()
183
275
  });
184
276
 
185
277
  // src/schemas/init-context.ts
@@ -189,20 +281,34 @@ var initContextFrameworkSchema = z7.object({
189
281
  version: z7.string(),
190
282
  subkind: z7.string()
191
283
  });
284
+ var initContextInvariantConfidenceSnapshotSchema = z7.object({
285
+ confidence: z7.enum(["HIGH", "MEDIUM", "LOW"]),
286
+ evidence_refs: z7.array(z7.string())
287
+ });
288
+ var initContextSourceEvidenceSchema = z7.object({
289
+ file: z7.string(),
290
+ lines: z7.string()
291
+ });
192
292
  var initContextInvariantSchema = z7.object({
193
293
  type: z7.enum(["ban", "require", "protect"]),
194
294
  rule: z7.string(),
195
- rationale: z7.string().optional()
295
+ rationale: z7.string().optional(),
296
+ confidence_snapshot: initContextInvariantConfidenceSnapshotSchema.optional(),
297
+ source_evidence: z7.array(initContextSourceEvidenceSchema).optional()
196
298
  });
197
299
  var initContextDomainGroupSchema = z7.object({
198
300
  name: z7.string(),
199
301
  paths: z7.array(z7.string()),
200
- summary: z7.string().optional()
302
+ summary: z7.string().optional(),
303
+ topology_type: z7.enum(["mirror", "cross-cutting"]).optional(),
304
+ target_path: z7.string().optional()
201
305
  });
202
306
  var initContextInterviewTrailEntrySchema = z7.object({
203
307
  phase: z7.string(),
204
308
  question: z7.string(),
205
- answer: z7.string()
309
+ answer: z7.string(),
310
+ presentation: z7.string().optional(),
311
+ user_corrections: z7.array(z7.string()).optional()
206
312
  });
207
313
  var initContextSchema = z7.object({
208
314
  framework: initContextFrameworkSchema,
@@ -248,135 +354,37 @@ var fabricEventSchema = z8.discriminatedUnion("type", [
248
354
  ledgerAppendedEventSchema,
249
355
  driftDetectedEventSchema
250
356
  ]);
251
-
252
- // src/detector.ts
253
- import { existsSync, readFileSync } from "fs";
254
- import { join } from "path";
255
- function detectFramework(root) {
256
- const evidence = [];
257
- const creatorConfigPath = join(root, "project.config.json");
258
- if (existsSync(creatorConfigPath)) {
259
- const version = readCreatorVersion(creatorConfigPath);
260
- return {
261
- kind: "cocos-creator",
262
- version,
263
- subkind: inferCocosSubkind(root, version),
264
- evidence: version === "unknown" ? ["project.config.json"] : [`project.config.json: creator.version=${version}`]
265
- };
266
- }
267
- const packageJsonPath = join(root, "package.json");
268
- if (existsSync(packageJsonPath)) {
269
- const packageJson = readPackageJson(packageJsonPath);
270
- const deps = collectDependencyVersions(packageJson);
271
- for (const [dependencyName, kind] of [
272
- ["next", "next"],
273
- ["vite", "vite"],
274
- ["react", "react"],
275
- ["vue", "vue"]
276
- ]) {
277
- if (deps.has(dependencyName)) {
278
- const version = deps.get(dependencyName) ?? "unknown";
279
- evidence.push(`package.json dependency: ${dependencyName}@${version}`);
280
- return {
281
- kind,
282
- version,
283
- subkind: inferPackageSubkind(kind),
284
- evidence
285
- };
286
- }
287
- }
288
- evidence.push("package.json");
289
- }
290
- if (existsSync(join(root, "Cargo.toml"))) {
291
- return {
292
- kind: "rust",
293
- version: "unknown",
294
- subkind: "cargo-project",
295
- evidence: ["Cargo.toml"]
296
- };
297
- }
298
- if (existsSync(join(root, "pyproject.toml"))) {
299
- return {
300
- kind: "python",
301
- version: "unknown",
302
- subkind: "pyproject",
303
- evidence: ["pyproject.toml"]
304
- };
305
- }
306
- return {
307
- kind: "unknown",
308
- version: "unknown",
309
- subkind: "unknown",
310
- evidence
311
- };
312
- }
313
- function readPackageJson(packageJsonPath) {
314
- try {
315
- return JSON.parse(readFileSync(packageJsonPath, "utf8"));
316
- } catch {
317
- return {};
318
- }
319
- }
320
- function readCreatorVersion(creatorConfigPath) {
321
- try {
322
- const creatorConfig = JSON.parse(readFileSync(creatorConfigPath, "utf8"));
323
- return creatorConfig.creator?.version ?? "unknown";
324
- } catch {
325
- return "unknown";
326
- }
327
- }
328
- function collectDependencyVersions(packageJson) {
329
- return new Map([
330
- ...Object.entries(packageJson.dependencies ?? {}),
331
- ...Object.entries(packageJson.devDependencies ?? {}),
332
- ...Object.entries(packageJson.peerDependencies ?? {}),
333
- ...Object.entries(packageJson.optionalDependencies ?? {})
334
- ]);
335
- }
336
- function inferCocosSubkind(root, version) {
337
- const majorVersion = Number.parseInt(version.split(".")[0] ?? "", 10);
338
- if (majorVersion === 2) {
339
- return "javascript-traditional";
340
- }
341
- if (majorVersion >= 3) {
342
- return "typescript-component";
343
- }
344
- return existsSync(join(root, "tsconfig.json")) ? "typescript-component" : "javascript-traditional";
345
- }
346
- function inferPackageSubkind(kind) {
347
- switch (kind) {
348
- case "next":
349
- return "next-application";
350
- case "vite":
351
- return "vite-application";
352
- case "react":
353
- return "react-application";
354
- case "vue":
355
- return "vue-application";
356
- default:
357
- return "unknown";
358
- }
359
- }
360
357
  export {
358
+ AGENTS_META_LAYERS,
359
+ AGENTS_META_TOPOLOGY_TYPES,
361
360
  PROTECTED_TOKENS,
361
+ agentsLayerSchema,
362
362
  agentsMetaNodeSchema,
363
363
  agentsMetaSchema,
364
+ agentsTopologyTypeSchema,
364
365
  aiLedgerEntrySchema,
365
366
  annotateIntentRequestSchema,
367
+ auditModeSchema,
368
+ candidateFileEntrySchema,
366
369
  clientPathsSchema,
367
370
  createTranslator,
368
371
  defaultMessages,
369
- detectFramework,
372
+ deriveAgentsMetaLayer,
373
+ deriveAgentsMetaTopologyType,
370
374
  detectNodeLocale,
371
375
  driftDetectedEventSchema,
372
376
  enMessages,
373
377
  fabricConfigSchema,
374
378
  fabricEventSchema,
379
+ forensicAssertionCoverageSchema,
380
+ forensicAssertionSchema,
375
381
  forensicCodeSampleSchema,
376
382
  forensicEntryPointSchema,
383
+ forensicEvidenceAnchorSchema,
377
384
  forensicFrameworkSchema,
378
385
  forensicReadmeSchema,
379
386
  forensicReportSchema,
387
+ forensicSamplingBudgetSchema,
380
388
  forensicTopologySchema,
381
389
  historyStateQuerySchema,
382
390
  humanLedgerEntrySchema,
@@ -387,8 +395,10 @@ export {
387
395
  initContextDomainGroupSchema,
388
396
  initContextFrameworkSchema,
389
397
  initContextInterviewTrailEntrySchema,
398
+ initContextInvariantConfidenceSnapshotSchema,
390
399
  initContextInvariantSchema,
391
400
  initContextSchema,
401
+ initContextSourceEvidenceSchema,
392
402
  ledgerAppendedEventSchema,
393
403
  ledgerEntrySchema,
394
404
  ledgerQuerySchema,
@@ -397,5 +407,6 @@ export {
397
407
  lockDriftEventSchema,
398
408
  metaUpdatedEventSchema,
399
409
  normalizeLocale,
410
+ withDerivedAgentsMetaNodeDefaults,
400
411
  zhCNMessages
401
412
  };
package/dist/node.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ type FrameworkInfo = {
2
+ kind: "vite" | "next" | "react" | "vue" | "cocos-creator" | "rust" | "python" | "unknown";
3
+ version: string;
4
+ subkind: string;
5
+ evidence: string[];
6
+ };
7
+ declare function detectFramework(root: string): FrameworkInfo;
8
+
9
+ export { type FrameworkInfo, detectFramework };
package/dist/node.js ADDED
@@ -0,0 +1,111 @@
1
+ // src/detector.ts
2
+ import { existsSync, readFileSync } from "fs";
3
+ import { join } from "path";
4
+ function detectFramework(root) {
5
+ const evidence = [];
6
+ const creatorConfigPath = join(root, "project.config.json");
7
+ if (existsSync(creatorConfigPath)) {
8
+ const version = readCreatorVersion(creatorConfigPath);
9
+ return {
10
+ kind: "cocos-creator",
11
+ version,
12
+ subkind: inferCocosSubkind(root, version),
13
+ evidence: version === "unknown" ? ["project.config.json"] : [`project.config.json: creator.version=${version}`]
14
+ };
15
+ }
16
+ const packageJsonPath = join(root, "package.json");
17
+ if (existsSync(packageJsonPath)) {
18
+ const packageJson = readPackageJson(packageJsonPath);
19
+ const deps = collectDependencyVersions(packageJson);
20
+ for (const [dependencyName, kind] of [
21
+ ["next", "next"],
22
+ ["vite", "vite"],
23
+ ["react", "react"],
24
+ ["vue", "vue"]
25
+ ]) {
26
+ if (deps.has(dependencyName)) {
27
+ const version = deps.get(dependencyName) ?? "unknown";
28
+ evidence.push(`package.json dependency: ${dependencyName}@${version}`);
29
+ return {
30
+ kind,
31
+ version,
32
+ subkind: inferPackageSubkind(kind),
33
+ evidence
34
+ };
35
+ }
36
+ }
37
+ evidence.push("package.json");
38
+ }
39
+ if (existsSync(join(root, "Cargo.toml"))) {
40
+ return {
41
+ kind: "rust",
42
+ version: "unknown",
43
+ subkind: "cargo-project",
44
+ evidence: ["Cargo.toml"]
45
+ };
46
+ }
47
+ if (existsSync(join(root, "pyproject.toml"))) {
48
+ return {
49
+ kind: "python",
50
+ version: "unknown",
51
+ subkind: "pyproject",
52
+ evidence: ["pyproject.toml"]
53
+ };
54
+ }
55
+ return {
56
+ kind: "unknown",
57
+ version: "unknown",
58
+ subkind: "unknown",
59
+ evidence
60
+ };
61
+ }
62
+ function readPackageJson(packageJsonPath) {
63
+ try {
64
+ return JSON.parse(readFileSync(packageJsonPath, "utf8"));
65
+ } catch {
66
+ return {};
67
+ }
68
+ }
69
+ function readCreatorVersion(creatorConfigPath) {
70
+ try {
71
+ const creatorConfig = JSON.parse(readFileSync(creatorConfigPath, "utf8"));
72
+ return creatorConfig.creator?.version ?? "unknown";
73
+ } catch {
74
+ return "unknown";
75
+ }
76
+ }
77
+ function collectDependencyVersions(packageJson) {
78
+ return new Map([
79
+ ...Object.entries(packageJson.dependencies ?? {}),
80
+ ...Object.entries(packageJson.devDependencies ?? {}),
81
+ ...Object.entries(packageJson.peerDependencies ?? {}),
82
+ ...Object.entries(packageJson.optionalDependencies ?? {})
83
+ ]);
84
+ }
85
+ function inferCocosSubkind(root, version) {
86
+ const majorVersion = Number.parseInt(version.split(".")[0] ?? "", 10);
87
+ if (majorVersion === 2) {
88
+ return "javascript-traditional";
89
+ }
90
+ if (majorVersion >= 3) {
91
+ return "typescript-component";
92
+ }
93
+ return existsSync(join(root, "tsconfig.json")) ? "typescript-component" : "javascript-traditional";
94
+ }
95
+ function inferPackageSubkind(kind) {
96
+ switch (kind) {
97
+ case "next":
98
+ return "next-application";
99
+ case "vite":
100
+ return "vite-application";
101
+ case "react":
102
+ return "react-application";
103
+ case "vue":
104
+ return "vue-application";
105
+ default:
106
+ return "unknown";
107
+ }
108
+ }
109
+ export {
110
+ detectFramework
111
+ };
@@ -1,8 +1,12 @@
1
+ type AgentsLayer = "L0" | "L1" | "L2";
2
+ type AgentsTopologyType = "mirror" | "cross-cutting";
1
3
  interface AgentsMetaNode {
2
4
  file: string;
3
5
  scope_glob: string;
4
6
  deps: string[];
5
7
  priority: "high" | "medium" | "low";
8
+ layer: AgentsLayer;
9
+ topology_type: AgentsTopologyType;
6
10
  hash: string;
7
11
  }
8
12
  interface AgentsMeta {
@@ -46,10 +50,13 @@ interface ClientPaths {
46
50
  geminiCLI?: string;
47
51
  codexCLI?: string;
48
52
  }
53
+ type AuditMode = "strict" | "warn" | "off";
49
54
  interface FabricConfig {
50
55
  clientPaths?: ClientPaths;
51
56
  externalFixturePath?: string;
52
57
  scanIgnores?: string[];
58
+ auditMode?: AuditMode;
59
+ audit_mode?: AuditMode;
53
60
  }
54
61
 
55
- export type { AgentsMeta, AgentsMetaNode, AiLedgerEntry, ClientPaths, FabricConfig, HumanLedgerEntry, HumanLockEntry, LedgerEntry };
62
+ export type { AgentsLayer, AgentsMeta, AgentsMetaNode, AgentsTopologyType, AiLedgerEntry, AuditMode, ClientPaths, FabricConfig, HumanLedgerEntry, HumanLockEntry, LedgerEntry };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fenglimg/fabric-shared",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -16,6 +16,10 @@
16
16
  "./types": {
17
17
  "types": "./dist/types/index.d.ts",
18
18
  "import": "./dist/types/index.js"
19
+ },
20
+ "./node": {
21
+ "types": "./dist/node.d.ts",
22
+ "import": "./dist/node.js"
19
23
  }
20
24
  },
21
25
  "files": [
@@ -25,11 +29,12 @@
25
29
  "zod": "^3.25.0"
26
30
  },
27
31
  "devDependencies": {
32
+ "@types/node": "^22.15.0",
28
33
  "tsup": "^8.5.0",
29
34
  "typescript": "^5.8.3"
30
35
  },
31
36
  "scripts": {
32
- "build": "tsup src/index.ts src/i18n/index.ts src/types/index.ts --format esm --dts --clean",
33
- "dev": "tsup src/index.ts src/i18n/index.ts src/types/index.ts --format esm --dts --watch"
37
+ "build": "tsup src/index.ts src/i18n/index.ts src/types/index.ts src/node.ts --format esm --dts --clean",
38
+ "dev": "tsup src/index.ts src/i18n/index.ts src/types/index.ts src/node.ts --format esm --dts --watch"
34
39
  }
35
40
  }