kibi-cli 2.14.0 → 2.16.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.
Files changed (135) hide show
  1. package/dist/cli-register-proof.d.ts.map +1 -1
  2. package/dist/cli-register-proof.js +16 -2
  3. package/dist/commands/check.d.ts.map +1 -1
  4. package/dist/commands/check.js +5 -1
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +83 -4
  7. package/dist/commands/prove.js +1 -1
  8. package/dist/engine.d.ts.map +1 -1
  9. package/dist/engine.js +5 -2
  10. package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
  11. package/dist/operations/bootstrap/discovery.js +6 -1
  12. package/dist/operations/bootstrap/generate.d.ts.map +1 -1
  13. package/dist/operations/bootstrap/generate.js +1 -0
  14. package/dist/operations/bootstrap/guidance-actions.d.ts +2 -1
  15. package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
  16. package/dist/operations/bootstrap/guidance-actions.js +10 -1
  17. package/dist/operations/bootstrap/guidance.d.ts +2 -0
  18. package/dist/operations/bootstrap/guidance.d.ts.map +1 -1
  19. package/dist/operations/bootstrap/guidance.js +1 -1
  20. package/dist/operations/bootstrap/plugin-offers.d.ts +16 -0
  21. package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -0
  22. package/dist/operations/bootstrap/plugin-offers.js +66 -0
  23. package/dist/operations/bootstrap/presentation.d.ts +2 -0
  24. package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
  25. package/dist/operations/bootstrap/presentation.js +2 -0
  26. package/dist/operations/bootstrap/types.d.ts +2 -0
  27. package/dist/operations/bootstrap/types.d.ts.map +1 -1
  28. package/dist/operations/modeling/model-requirement.d.ts +5 -0
  29. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  30. package/dist/operations/modeling/model-requirement.js +17 -5
  31. package/dist/operations/modeling/predicate-applicability.d.ts.map +1 -1
  32. package/dist/operations/modeling/predicate-applicability.js +27 -1
  33. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  34. package/dist/operations/modeling/predicate-applyplan.js +16 -6
  35. package/dist/operations/modeling/predicate-binding-hints.d.ts +10 -0
  36. package/dist/operations/modeling/predicate-binding-hints.d.ts.map +1 -1
  37. package/dist/operations/modeling/predicate-binding-hints.js +74 -0
  38. package/dist/operations/modeling/predicate-catalog-5.d.ts +2 -2
  39. package/dist/operations/modeling/predicate-catalog-5.js +2 -2
  40. package/dist/operations/modeling/predicate-catalog-6.d.ts +9 -0
  41. package/dist/operations/modeling/predicate-catalog-6.d.ts.map +1 -0
  42. package/dist/operations/modeling/predicate-catalog-6.js +106 -0
  43. package/dist/operations/modeling/predicate-catalog.d.ts.map +1 -1
  44. package/dist/operations/modeling/predicate-catalog.js +2 -0
  45. package/dist/operations/modeling/predicate-usage-hints-4.d.ts.map +1 -1
  46. package/dist/operations/modeling/predicate-usage-hints-4.js +32 -0
  47. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  48. package/dist/operations/modeling/suggest-predicates.js +32 -11
  49. package/dist/operations/mutation/contradictions.d.ts +8 -0
  50. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  51. package/dist/operations/mutation/contradictions.js +13 -0
  52. package/dist/operations/mutation/source-authoring.d.ts +13 -0
  53. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  54. package/dist/operations/mutation/source-authoring.js +70 -2
  55. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  56. package/dist/operations/mutation/upsert.js +9 -3
  57. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  58. package/dist/operations/mutation/validate-upsert.js +30 -4
  59. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  60. package/dist/operations/planning/apply-plan.js +15 -0
  61. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
  62. package/dist/operations/semantic-advisor/ingestion-boundary.js +20 -1
  63. package/dist/plugins/approved-source-analyzers.generated.d.ts +5 -5
  64. package/dist/plugins/approved-source-analyzers.generated.js +5 -5
  65. package/dist/plugins/check-policies.d.ts +24 -0
  66. package/dist/plugins/check-policies.d.ts.map +1 -0
  67. package/dist/plugins/check-policies.js +73 -0
  68. package/dist/plugins/registry.d.ts.map +1 -1
  69. package/dist/plugins/registry.js +10 -1
  70. package/dist/prolog.d.ts.map +1 -1
  71. package/dist/prolog.js +8 -1
  72. package/dist/proof/inspect.d.ts +18 -1
  73. package/dist/proof/inspect.d.ts.map +1 -1
  74. package/dist/proof/inspect.js +17 -8
  75. package/dist/proof/integration-plan.d.ts +57 -0
  76. package/dist/proof/integration-plan.d.ts.map +1 -0
  77. package/dist/proof/integration-plan.js +331 -0
  78. package/dist/proof/integrations.js +1 -1
  79. package/dist/public/operations/catalog.d.ts +2 -2
  80. package/dist/public/operations/check-executor.d.ts +16 -0
  81. package/dist/public/operations/check-executor.d.ts.map +1 -1
  82. package/dist/public/operations/check-executor.js +83 -0
  83. package/dist/public/operations/check-policy-rules.d.ts +49 -0
  84. package/dist/public/operations/check-policy-rules.d.ts.map +1 -0
  85. package/dist/public/operations/check-policy-rules.js +305 -0
  86. package/dist/public/operations/contracts.d.ts.map +1 -1
  87. package/dist/public/operations/contracts.js +5 -0
  88. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  89. package/dist/public/operations/discovery-executors.js +13 -3
  90. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  91. package/dist/public/operations/migration-plan.js +28 -0
  92. package/dist/public/operations/source-relationship-parity.d.ts.map +1 -1
  93. package/dist/public/operations/source-relationship-parity.js +16 -1
  94. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  95. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  96. package/dist/public/operations/specs/check-rules.generated.js +4 -1
  97. package/dist/public/operations/specs/check.d.ts +1 -1
  98. package/dist/public/operations/specs/composite.d.ts +16 -3
  99. package/dist/public/operations/specs/composite.d.ts.map +1 -1
  100. package/dist/public/operations/specs/composite.js +79 -2
  101. package/dist/public/operations/specs/modeling.d.ts +1 -1
  102. package/dist/public/operations/specs/modeling.js +1 -1
  103. package/dist/public/operations/specs/reporting.d.ts +9 -0
  104. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  105. package/dist/public/operations/specs/reporting.js +6 -2
  106. package/dist/public/skills/kibi-bootstrap/SKILL.md +3 -2
  107. package/dist/public/skills/kibi-usage/SKILL.md +82 -3
  108. package/dist/public/skills/kibi-usage/resources/proof.md +15 -3
  109. package/dist/public/skills/kibi-usage/resources/ui-requirements.md +42 -3
  110. package/dist/report/html-report.d.ts.map +1 -1
  111. package/dist/report/html-report.js +13 -2
  112. package/dist/utils/branch-store.d.ts +32 -0
  113. package/dist/utils/branch-store.d.ts.map +1 -1
  114. package/dist/utils/branch-store.js +122 -1
  115. package/dist/utils/rule-registry.generated.d.ts +15 -0
  116. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  117. package/dist/utils/rule-registry.generated.js +18 -0
  118. package/dist/utils/strict-modeling.d.ts +12 -0
  119. package/dist/utils/strict-modeling.d.ts.map +1 -1
  120. package/dist/utils/strict-modeling.js +12 -1
  121. package/package.json +4 -4
  122. package/src/public/operations/check-executor.ts +112 -0
  123. package/src/public/operations/check-policy-rules.ts +462 -0
  124. package/src/public/operations/contracts.ts +6 -0
  125. package/src/public/operations/discovery-executors.ts +19 -2
  126. package/src/public/operations/migration-plan.ts +35 -0
  127. package/src/public/operations/source-relationship-parity.ts +17 -2
  128. package/src/public/operations/specs/check-rules.generated.ts +4 -1
  129. package/src/public/operations/specs/composite.ts +110 -11
  130. package/src/public/operations/specs/modeling.ts +1 -1
  131. package/src/public/operations/specs/reporting.ts +13 -2
  132. package/src/public/skills/kibi-bootstrap/SKILL.md +3 -2
  133. package/src/public/skills/kibi-usage/SKILL.md +82 -3
  134. package/src/public/skills/kibi-usage/resources/proof.md +15 -3
  135. package/src/public/skills/kibi-usage/resources/ui-requirements.md +42 -3
@@ -1,7 +1,10 @@
1
1
  import { runAggregatedChecks } from "../../commands/aggregated-checks.js";
2
+ import { resolveBranchAttachment } from "../../utils/branch-resolver.js";
3
+ import { BRANCH_STORE_NOT_COMPILED_RULE, inspectBranchStore, uncompiledBranchStoreReason, } from "../../utils/branch-store.js";
2
4
  import { collectFullKbQualityDiagnostics } from "../impact-diagnostics.js";
3
5
  import { buildStructuredContent, buildSummary, } from "./check-format-shared.js";
4
6
  import { analyzeKbCheckImpact, collectQueryPlanSafetyViolations, getEffectiveRules, partitionCheckFindings, qualityDiagnosticsFromImpact, resolveCheckRules, stagedEntityIdStyleDiagnostics, } from "./check-helpers.js";
7
+ import { collectCheckPolicyViolations } from "./check-policy-rules.js";
5
8
  import { executeStatus } from "./discovery-executors.js";
6
9
  import { collectEntityContextViolations } from "./entity-context.js";
7
10
  import { buildActionsFromCheck, buildMigrationPlan, mergeMigrationPlans, } from "./migration-plan.js";
@@ -50,6 +53,44 @@ async function readStatusMigrationPlan(context) {
50
53
  throw error;
51
54
  }
52
55
  }
56
+ /**
57
+ * The one finding for a branch whose store was never compiled while .kb/
58
+ * holds authored sources. Every store-backed rule would read an empty KB
59
+ * (source-relationship-parity alone reports each authored relationship as
60
+ * missing), so kb_check reports this instead of any of them.
61
+ */
62
+ // implements REQ-cli-status-pre-first-sync
63
+ export function uncompiledBranchStoreViolation(context, workspaceRoot) {
64
+ let attachment;
65
+ try {
66
+ attachment =
67
+ context.branchAttachment ?? resolveBranchAttachment(workspaceRoot);
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ if ("error" in attachment)
73
+ return null;
74
+ const store = inspectBranchStore(workspaceRoot, attachment.kbBranch);
75
+ const reason = uncompiledBranchStoreReason(workspaceRoot, store, attachment.kbBranch);
76
+ if (reason === null)
77
+ return null;
78
+ return {
79
+ rule: BRANCH_STORE_NOT_COMPILED_RULE,
80
+ entityId: attachment.kbBranch,
81
+ description: String(reason.detail),
82
+ suggestion: "Run kibi sync to compile this branch's store from the authored .kb/ sources (or apply the branch-store-compile action of the returned migrationPlan with kb_apply_plan), then rerun kb_check. Run kibi init once to install the git hooks that compile a new branch on checkout.",
83
+ source: store.path,
84
+ evidence: {
85
+ store: { state: store.state, path: store.path },
86
+ authoredSources: reason.authoredSources,
87
+ ...(reason.generation !== undefined
88
+ ? { generation: reason.generation }
89
+ : {}),
90
+ remediation: reason.remediation,
91
+ },
92
+ };
93
+ }
53
94
  // implements REQ-kibi-operation-interface-parity, REQ-002
54
95
  export async function executeCheck(args, context, options = {}) {
55
96
  try {
@@ -72,6 +113,46 @@ export async function executeCheck(args, context, options = {}) {
72
113
  const maxDiagnosticsOption = args.maxDiagnostics !== undefined
73
114
  ? { maxDiagnostics: args.maxDiagnostics }
74
115
  : {};
116
+ const uncompiled = context.branchAttachment !== undefined ||
117
+ options.branchStoreAttached === true
118
+ ? uncompiledBranchStoreViolation(context, workspaceRoot)
119
+ : null;
120
+ if (uncompiled !== null) {
121
+ const violations = [uncompiled];
122
+ const statusPlan = await readStatusMigrationPlan(context);
123
+ const migrationPlan = await migrationPlanForCheck(context, violations, [], statusPlan);
124
+ return {
125
+ content: [
126
+ {
127
+ type: "text",
128
+ text: buildSummary({
129
+ violations,
130
+ impactResult,
131
+ qualityDiagnostics: [],
132
+ }),
133
+ },
134
+ ],
135
+ structuredContent: buildStructuredContent({
136
+ violations,
137
+ diagnostics: [
138
+ {
139
+ category: "SYNC_ERROR",
140
+ severity: "error",
141
+ message: uncompiled.description,
142
+ ...(uncompiled.source !== undefined
143
+ ? { file: uncompiled.source }
144
+ : {}),
145
+ ...(uncompiled.suggestion !== undefined
146
+ ? { suggestion: uncompiled.suggestion }
147
+ : {}),
148
+ },
149
+ ],
150
+ qualityDiagnostics: [],
151
+ impactResult,
152
+ migrationPlan,
153
+ }),
154
+ };
155
+ }
75
156
  if (rulesAllowlist.size === 0) {
76
157
  const qualityDiagnostics = hasExplicitRules &&
77
158
  options.collectFullQualityDiagnosticsForExplicitRules !== true
@@ -124,6 +205,7 @@ export async function executeCheck(args, context, options = {}) {
124
205
  : [];
125
206
  const originReviewFindings = await collectOriginReviewViolations(prolog, rulesAllowlist, workspaceRoot);
126
207
  const entityContextFindings = collectEntityContextViolations(rulesAllowlist, workspaceRoot);
208
+ const checkPolicyFindings = await collectCheckPolicyViolations(prolog, rulesAllowlist, workspaceRoot);
127
209
  const partitioned = partitionCheckFindings([
128
210
  ...aggregatedFindings,
129
211
  ...queryPlanViolations,
@@ -132,6 +214,7 @@ export async function executeCheck(args, context, options = {}) {
132
214
  ...predicateConformanceFindings,
133
215
  ...originReviewFindings,
134
216
  ...entityContextFindings,
217
+ ...checkPolicyFindings,
135
218
  ]);
136
219
  const violations = partitioned.violations;
137
220
  const diagnostics = violations.map((v) => ({
@@ -0,0 +1,49 @@
1
+ import { type ActiveCheckPolicy, type CheckPolicyLoadError } from "../../plugins/check-policies.js";
2
+ import type { Violation } from "../../utils/rule-registry.js";
3
+ import type { PrologPort } from "./runtime-types.js";
4
+ /** Symbols in a policy's file set must implement a qualifying requirement. */
5
+ export declare const POLICY_OWNERSHIP_RULE = "policy-ownership";
6
+ /** Files implementing a pattern must keep the pattern's declared markers. */
7
+ export declare const POLICY_MARKERS_RULE = "policy-markers";
8
+ export type PolicySymbol = Readonly<{
9
+ id: string;
10
+ title: string;
11
+ sourceFile: string;
12
+ tags: readonly string[];
13
+ }>;
14
+ export type PolicyPredicateFact = Readonly<{
15
+ id: string;
16
+ name: string;
17
+ args: readonly string[];
18
+ polarity: string;
19
+ }>;
20
+ export type CheckPolicyEvaluationInput = Readonly<{
21
+ policies: readonly ActiveCheckPolicy[];
22
+ loadErrors: readonly CheckPolicyLoadError[];
23
+ /** Production symbols (no `executable_for`) that carry a sourceFile. */
24
+ symbols: readonly PolicySymbol[];
25
+ /** `[symbol, requirement]` implements edges. */
26
+ implementsEdges: readonly (readonly [string, string])[];
27
+ currentRequirements: ReadonlySet<string>;
28
+ /** `[requirement, fact]` requires_predicate edges. */
29
+ requiresPredicateEdges: readonly (readonly [string, string])[];
30
+ predicateFacts: readonly PolicyPredicateFact[];
31
+ /** Workspace-relative file contents, or undefined when unreadable. */
32
+ readFile: (path: string) => string | undefined;
33
+ }>;
34
+ /**
35
+ * Workspace-relative POSIX path of a symbol sourceFile, or undefined when it
36
+ * points outside the workspace. Policies only govern workspace files.
37
+ */
38
+ export declare function workspaceSourcePath(workspaceRoot: string, sourceFile: string): string | undefined;
39
+ /**
40
+ * Evaluate active check policies against the KB. Pure: all KB data and file
41
+ * reads come in through `input`.
42
+ */
43
+ export declare function evaluateCheckPolicies(input: CheckPolicyEvaluationInput, rules: ReadonlySet<string>): Violation[];
44
+ /**
45
+ * Collect policy findings for the selected rules. With no activated check
46
+ * policy this returns at once, so projects without one pay nothing.
47
+ */
48
+ export declare function collectCheckPolicyViolations(prolog: Pick<PrologPort, "query">, rules: ReadonlySet<string>, workspaceRoot: string): Promise<Violation[]>;
49
+ //# sourceMappingURL=check-policy-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-policy-rules.d.ts","sourceRoot":"","sources":["../../../src/public/operations/check-policy-rules.ts"],"names":[],"mappings":"AAkCA,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAE1B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,8EAA8E;AAE9E,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AACxD,6EAA6E;AAE7E,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAKpD,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CACzB,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAGH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC5C,wEAAwE;IACxE,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;IACjC,gDAAgD;IAChD,eAAe,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IACxD,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC,sDAAsD;IACtD,sBAAsB,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;IAC/D,cAAc,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC/C,sEAAsE;IACtE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAChD,CAAC,CAAC;AAiBH;;;GAGG;AAEH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,SAAS,CAOpB;AAkLD;;;GAGG;AAEH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,0BAA0B,EACjC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GACzB,SAAS,EAAE,CAyBb;AA2CD;;;GAGG;AAEH,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAmFtB"}
@@ -0,0 +1,305 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import * as fs from "node:fs";
19
+ import { basename, dirname, extname, isAbsolute, join, posix, relative, } from "node:path";
20
+ import ignore from "ignore";
21
+ import { readActiveCheckPolicies, } from "../../plugins/check-policies.js";
22
+ import { parseListOfLists, parsePrologValue } from "../../prolog/codec.js";
23
+ import { loadEntitiesPaged } from "./discovery-entities.js";
24
+ /** Symbols in a policy's file set must implement a qualifying requirement. */
25
+ // implements REQ-capability-check-policy
26
+ export const POLICY_OWNERSHIP_RULE = "policy-ownership";
27
+ /** Files implementing a pattern must keep the pattern's declared markers. */
28
+ // implements REQ-capability-check-policy
29
+ export const POLICY_MARKERS_RULE = "policy-markers";
30
+ const POLICY_RULES = [POLICY_OWNERSHIP_RULE, POLICY_MARKERS_RULE];
31
+ function toPosix(path) {
32
+ return path.replaceAll("\\", "/").replace(/^\.\//, "");
33
+ }
34
+ /** True for a workspace-relative path that stays inside the workspace. */
35
+ function insideWorkspace(path) {
36
+ return (path !== "" &&
37
+ !path.startsWith("/") &&
38
+ !/^[A-Za-z]:\//.test(path) &&
39
+ path !== ".." &&
40
+ !path.startsWith("../"));
41
+ }
42
+ /**
43
+ * Workspace-relative POSIX path of a symbol sourceFile, or undefined when it
44
+ * points outside the workspace. Policies only govern workspace files.
45
+ */
46
+ // implements REQ-capability-check-policy
47
+ export function workspaceSourcePath(workspaceRoot, sourceFile) {
48
+ const path = posix.normalize(toPosix(isAbsolute(sourceFile) ? relative(workspaceRoot, sourceFile) : sourceFile));
49
+ return insideWorkspace(path) ? path : undefined;
50
+ }
51
+ function matcher(patterns) {
52
+ const matcher = ignore().add([...patterns]);
53
+ return (path) => {
54
+ const relative = toPosix(path);
55
+ // ignore() throws on absolute and ../ paths; neither is in a policy's scope.
56
+ return insideWorkspace(relative) && matcher.ignores(relative);
57
+ };
58
+ }
59
+ function groupBy(pairs) {
60
+ const grouped = new Map();
61
+ for (const [key, value] of pairs) {
62
+ grouped.set(key, [...(grouped.get(key) ?? []), value]);
63
+ }
64
+ return grouped;
65
+ }
66
+ /** Asserted predicate names each current requirement is grounded in. */
67
+ function requirementPredicates(input) {
68
+ const facts = new Map(input.predicateFacts.map((fact) => [fact.id, fact]));
69
+ const grounded = new Map();
70
+ for (const [req, factId] of input.requiresPredicateEdges) {
71
+ const fact = facts.get(factId);
72
+ if (!input.currentRequirements.has(req) || fact === undefined)
73
+ continue;
74
+ if (fact.polarity !== "assert")
75
+ continue;
76
+ grounded.set(req, [...(grounded.get(req) ?? []), fact]);
77
+ }
78
+ return grounded;
79
+ }
80
+ function ownershipViolations(policy, rule, input, grounded, owners) {
81
+ const included = matcher(rule.include);
82
+ const excluded = matcher(rule.exclude ?? []);
83
+ const title = rule.symbolTitlePattern !== undefined
84
+ ? new RegExp(rule.symbolTitlePattern)
85
+ : undefined;
86
+ const qualifying = new Set(rule.requirePredicates);
87
+ const violations = [];
88
+ for (const symbol of input.symbols) {
89
+ if (!included(symbol.sourceFile) || excluded(symbol.sourceFile))
90
+ continue;
91
+ if (title !== undefined && !title.test(symbol.title))
92
+ continue;
93
+ if (rule.exemptTag !== undefined && symbol.tags.includes(rule.exemptTag))
94
+ continue;
95
+ const requirements = owners.get(symbol.id) ?? [];
96
+ const owned = requirements.some((req) => (grounded.get(req) ?? []).some((fact) => qualifying.has(fact.name)));
97
+ if (owned)
98
+ continue;
99
+ violations.push({
100
+ rule: POLICY_OWNERSHIP_RULE,
101
+ entityId: symbol.id,
102
+ description: `${symbol.id} (${symbol.sourceFile}) is in scope of ${policy.packageName} rule '${rule.id}' but implements no current requirement grounded in ${rule.requirePredicates.join(", ")}`,
103
+ suggestion: `${rule.description}. Link the symbol with implements to a requirement that carries one of these predicates via requires_predicate, or create that requirement first${rule.exemptTag !== undefined ? `; tag the symbol '${rule.exemptTag}' only when it is intentionally unconstrained` : ""}.`,
104
+ source: symbol.sourceFile,
105
+ evidence: {
106
+ policy: policy.document.id,
107
+ package: policy.packageName,
108
+ policyRule: rule.id,
109
+ requirePredicates: [...rule.requirePredicates],
110
+ implements: requirements,
111
+ },
112
+ });
113
+ }
114
+ return violations;
115
+ }
116
+ /** Marker text as declared, plus its kebab-case spelling for snake_case atoms. */
117
+ function markerSpellings(marker) {
118
+ return [...new Set([marker, marker.replaceAll("_", "-")])];
119
+ }
120
+ function searchedFiles(sourceFile, rule) {
121
+ const source = toPosix(sourceFile);
122
+ const directory = dirname(source);
123
+ const stem = basename(source, extname(source));
124
+ const siblings = (rule.siblingExtensions ?? []).map((extension) => toPosix(join(directory, `${stem}${extension}`)));
125
+ return [source, ...siblings.filter((path) => path !== source)];
126
+ }
127
+ function markerViolations(policy, rule, input, grounded, owners) {
128
+ const markersByPattern = new Map();
129
+ for (const fact of input.predicateFacts) {
130
+ if (fact.name !== rule.markerPredicate || fact.polarity !== "assert")
131
+ continue;
132
+ const pattern = fact.args[rule.markerPatternArgument];
133
+ const marker = fact.args[rule.markerArgument];
134
+ if (pattern === undefined || marker === undefined)
135
+ continue;
136
+ markersByPattern.set(pattern, [
137
+ ...(markersByPattern.get(pattern) ?? []),
138
+ marker,
139
+ ]);
140
+ }
141
+ const violations = [];
142
+ // Several symbols in one file (component, props, helpers) share its markers;
143
+ // report each missing marker once per file and requirement.
144
+ const reported = new Set();
145
+ for (const symbol of input.symbols) {
146
+ for (const req of owners.get(symbol.id) ?? []) {
147
+ for (const fact of grounded.get(req) ?? []) {
148
+ if (fact.name !== rule.patternPredicate)
149
+ continue;
150
+ const pattern = fact.args[rule.patternArgument];
151
+ if (pattern === undefined)
152
+ continue;
153
+ const files = searchedFiles(symbol.sourceFile, rule);
154
+ const contents = files
155
+ .map((path) => input.readFile(path))
156
+ .filter((content) => content !== undefined);
157
+ for (const marker of [
158
+ ...new Set(markersByPattern.get(pattern) ?? []),
159
+ ]) {
160
+ const present = markerSpellings(marker).some((spelling) => contents.some((content) => content.includes(spelling)));
161
+ const key = JSON.stringify([files[0], req, marker]);
162
+ if (present || reported.has(key))
163
+ continue;
164
+ reported.add(key);
165
+ violations.push({
166
+ rule: POLICY_MARKERS_RULE,
167
+ entityId: symbol.id,
168
+ description: `${symbol.id} implements ${req}, which uses pattern '${pattern}', but none of ${files.join(", ")} contains its marker '${marker}'`,
169
+ suggestion: `${rule.description}. Restore the pattern in the implementation, or if the design changed on purpose, supersede ${req} with a requirement naming the new pattern.`,
170
+ source: symbol.sourceFile,
171
+ evidence: {
172
+ policy: policy.document.id,
173
+ package: policy.packageName,
174
+ policyRule: rule.id,
175
+ requirement: req,
176
+ pattern,
177
+ marker,
178
+ searchedFiles: files,
179
+ },
180
+ });
181
+ }
182
+ }
183
+ }
184
+ }
185
+ return violations;
186
+ }
187
+ function loadErrorViolations(errors, rules) {
188
+ const rule = POLICY_RULES.find((name) => rules.has(name));
189
+ if (rule === undefined)
190
+ return [];
191
+ return errors.map((error) => ({
192
+ rule,
193
+ entityId: error.packageName,
194
+ description: `Check policy from '${error.packageName}' could not be read: ${error.message}`,
195
+ suggestion: "Install the activated plugin package in this workspace, or remove its kibi.check-policy.v1 entry from package.json#kibi.plugins. Kibi does not skip an activated policy it cannot read.",
196
+ evidence: { package: error.packageName },
197
+ }));
198
+ }
199
+ /**
200
+ * Evaluate active check policies against the KB. Pure: all KB data and file
201
+ * reads come in through `input`.
202
+ */
203
+ // implements REQ-capability-check-policy
204
+ export function evaluateCheckPolicies(input, rules) {
205
+ const grounded = requirementPredicates(input);
206
+ const owners = groupBy(input.implementsEdges.filter(([, req]) => input.currentRequirements.has(req)));
207
+ const violations = loadErrorViolations(input.loadErrors, rules);
208
+ for (const policy of input.policies) {
209
+ if (rules.has(POLICY_OWNERSHIP_RULE)) {
210
+ for (const rule of policy.document.ownership ?? []) {
211
+ violations.push(...ownershipViolations(policy, rule, input, grounded, owners));
212
+ }
213
+ }
214
+ if (rules.has(POLICY_MARKERS_RULE)) {
215
+ for (const rule of policy.document.markers ?? []) {
216
+ violations.push(...markerViolations(policy, rule, input, grounded, owners));
217
+ }
218
+ }
219
+ }
220
+ return violations;
221
+ }
222
+ async function rows(prolog, goal, what) {
223
+ const result = await prolog.query(goal);
224
+ if (!result.success) {
225
+ throw new Error(`Unable to read ${what} for check policies: ${result.error ?? "query failed"}`);
226
+ }
227
+ return parseListOfLists(result.bindings.Rows ?? "[]");
228
+ }
229
+ function atom(value) {
230
+ return String(parsePrologValue(value ?? ""));
231
+ }
232
+ function stringList(value) {
233
+ if (Array.isArray(value))
234
+ return value.map(String);
235
+ if (typeof value === "string" && value !== "")
236
+ return [value];
237
+ return [];
238
+ }
239
+ function fileReader(workspaceRoot) {
240
+ const cache = new Map();
241
+ return (path) => {
242
+ if (!insideWorkspace(toPosix(path)))
243
+ return undefined;
244
+ if (!cache.has(path)) {
245
+ try {
246
+ cache.set(path, fs.readFileSync(join(workspaceRoot, path), "utf8"));
247
+ }
248
+ catch {
249
+ cache.set(path, undefined);
250
+ }
251
+ }
252
+ return cache.get(path);
253
+ };
254
+ }
255
+ /**
256
+ * Collect policy findings for the selected rules. With no activated check
257
+ * policy this returns at once, so projects without one pay nothing.
258
+ */
259
+ // implements REQ-capability-check-policy
260
+ export async function collectCheckPolicyViolations(prolog, rules, workspaceRoot) {
261
+ if (!POLICY_RULES.some((rule) => rules.has(rule)))
262
+ return [];
263
+ const { policies, errors } = readActiveCheckPolicies(workspaceRoot);
264
+ if (policies.length === 0) {
265
+ return loadErrorViolations(errors, rules);
266
+ }
267
+ // One Prolog port serves queries in order; read sequentially.
268
+ const symbolEntities = await loadEntitiesPaged(prolog, "symbol", 200);
269
+ const testSymbols = new Set((await rows(prolog, "findall([S], kb:executable_test_symbol(S), Rows0), sort(Rows0, Rows)", "executable test symbols")).map(([id]) => atom(id)));
270
+ const implementsEdges = (await rows(prolog, "findall([S,R], kb_relationship(implements, S, R), Rows)", "implements relationships")).map(([from, to]) => [atom(from), atom(to)]);
271
+ const requiresPredicateEdges = (await rows(prolog, "findall([R,F], kb_relationship(requires_predicate, R, F), Rows)", "requires_predicate relationships")).map(([from, to]) => [atom(from), atom(to)]);
272
+ const currentRequirements = new Set((await rows(prolog, "findall([R], kb:current_req(R), Rows)", "current requirements")).map(([id]) => atom(id)));
273
+ const predicateFacts = (await rows(prolog, "findall([F,Name,Args,Polarity], kb:predicate_fact(F, _, Name, Args, Polarity), Rows)", "predicate facts")).map(([id, name, args, polarity]) => ({
274
+ id: atom(id),
275
+ name: atom(name),
276
+ args: stringList(parsePrologValue(args ?? "[]")),
277
+ polarity: atom(polarity),
278
+ }));
279
+ const symbols = symbolEntities.flatMap((entity) => {
280
+ const id = String(entity.id ?? "");
281
+ const sourceFile = typeof entity.sourceFile === "string"
282
+ ? workspaceSourcePath(workspaceRoot, entity.sourceFile)
283
+ : undefined;
284
+ if (id === "" || testSymbols.has(id) || sourceFile === undefined)
285
+ return [];
286
+ return [
287
+ {
288
+ id,
289
+ title: String(entity.title ?? id),
290
+ sourceFile,
291
+ tags: stringList(entity.tags),
292
+ },
293
+ ];
294
+ });
295
+ return evaluateCheckPolicies({
296
+ policies,
297
+ loadErrors: errors,
298
+ symbols,
299
+ implementsEdges,
300
+ currentRequirements,
301
+ requiresPredicateEdges,
302
+ predicateFacts,
303
+ readFile: fileReader(workspaceRoot),
304
+ }, rules);
305
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/public/operations/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAC1B,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAsZpE;;uEAEuE;AACvE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,mBAAmB,GAC1B,mBAAmB,CAMrB;AA2WD,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAa3C,CAAC;AAmDF,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAClD,YAAY,EAAE,MAAM,GACnB,IAAI,CAIN;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,SAAS,eAAe,EAAE,GAClC,SAAS,0BAA0B,EAAE,CAoBvC"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/public/operations/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,0BAA0B,EAC1B,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,oEAAoE;AACpE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAsZpE;;uEAEuE;AACvE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,mBAAmB,GAC1B,mBAAmB,CAMrB;AAiXD,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAa3C,CAAC;AAmDF,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAClD,YAAY,EAAE,MAAM,GACnB,IAAI,CAIN;AAED,wBAAgB,eAAe,CAC7B,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,SAAS,eAAe,EAAE,GAClC,SAAS,0BAA0B,EAAE,CAoBvC"}
@@ -390,6 +390,7 @@ const BASE_DATA_SCHEMAS = {
390
390
  kb_find_gaps: objectData({
391
391
  rows: recordArray,
392
392
  count: integerValue,
393
+ summary: recordValue,
393
394
  meta: recordValue,
394
395
  }),
395
396
  kb_coverage: objectData({
@@ -498,6 +499,10 @@ const BASE_DATA_SCHEMAS = {
498
499
  tldr: stringValue,
499
500
  promptBlock: stringValue,
500
501
  recommendedActions: recordArray,
502
+ pluginOffers: {
503
+ ...recordArray,
504
+ description: "Optional plugins that fit this workspace and that the project has neither activated nor declined. Ask the operator; on yes install and activate the package, on no add it to package.json kibi.declinedPlugins.",
505
+ },
501
506
  declaredContext: recordValue,
502
507
  discoverySummary: recordValue,
503
508
  candidates: recordArray,
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-executors.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-executors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discovery-executors.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-executors.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { SwiplResolutionError } from "../../prolog/swipl-resolver.js";
7
7
  import { buildSearchAnswer } from "../../search-answer.js";
8
8
  import { rankEntities } from "../../search-ranking.js";
9
9
  import { resolveBranchAttachment } from "../../utils/branch-resolver.js";
10
- import { branchStoreReason, inspectBranchStore, storeLockJournalReason, } from "../../utils/branch-store.js";
10
+ import { BRANCH_STORE_NOT_COMPILED, branchStoreReason, inspectBranchStore, storeLockJournalReason, uncompiledBranchStoreReason, } from "../../utils/branch-store.js";
11
11
  import { loadSearchCandidates, paginateResults, queryEntitiesViaQuery, reloadFullEntities, validateEntityType, } from "./discovery-entities.js";
12
12
  import { buildActionsFromStatus, readMigrationConfigStatus, } from "./migration-plan.js";
13
13
  import { OperationJsonDecodeError, runOperationJsonQuery, } from "./prolog-json.js";
@@ -273,7 +273,12 @@ export async function executeStatus(_input, context) {
273
273
  }
274
274
  const snapshotEvidence = await readWorkspaceSnapshot(context);
275
275
  const existingReasons = payload.staleReasons ?? [];
276
- const storeReason = branchStoreReason(store);
276
+ // implements REQ-cli-status-pre-first-sync
277
+ // A missing or empty store beside authored sources gets the one reason
278
+ // whose remediation works (kibi sync); `kibi branch ensure` alone would
279
+ // leave the store empty.
280
+ const storeReason = uncompiledBranchStoreReason(context.workspaceRoot, store, attachment.kbBranch) ?? branchStoreReason(store);
281
+ const storeUncompiled = storeReason?.code === BRANCH_STORE_NOT_COMPILED;
277
282
  const lockReason = storeLockJournalReason(store.path);
278
283
  const compilerReason = compilerFingerprintReason(store.path);
279
284
  const engineReason = engineStatus
@@ -306,6 +311,11 @@ export async function executeStatus(_input, context) {
306
311
  // Source hashes can all match while the compilation itself is lossy, so
307
312
  // a compiler contract change alone makes the store stale.
308
313
  ...(compilerReason ? { syncState: "stale", dirty: true } : {}),
314
+ // An empty store has no stale file to report, yet nothing in it is
315
+ // current: the authored sources were never compiled.
316
+ ...(storeUncompiled && store.state === "healthy"
317
+ ? { syncState: "stale", dirty: true }
318
+ : {}),
309
319
  branchAttachment: attachment,
310
320
  branchStore: store,
311
321
  ...(engineStatus ? { engineStatus } : {}),
@@ -437,7 +447,7 @@ export async function executeStatus(_input, context) {
437
447
  content: [
438
448
  {
439
449
  type: "text",
440
- text: `Branch ${payload.branch} is ${payload.syncState} (snapshot ${payload.snapshotId}, dirty=${payload.dirty}, proofSnapshot=${enrichedPayload.proofSnapshot})`,
450
+ text: `Branch ${payload.branch} is ${enrichedPayload.syncState} (snapshot ${payload.snapshotId}, dirty=${enrichedPayload.dirty}, proofSnapshot=${enrichedPayload.proofSnapshot})${storeUncompiled ? `. Blocking: ${String(storeReason?.detail)} Run kibi sync.` : ""}`,
441
451
  },
442
452
  ],
443
453
  structuredContent: statusWithPlan,
@@ -1 +1 @@
1
- {"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import * as path from "node:path";
4
+ import { BRANCH_STORE_NOT_COMPILED } from "../../utils/branch-store.js";
4
5
  import { legacyConfigExists } from "../../utils/config.js";
5
6
  import { readKbManifestStatus } from "../../utils/kb-manifest.js";
6
7
  import { getSchemaVersionStatus, normalizeSchemaVersion, } from "../../utils/schema-version.js";
@@ -537,8 +538,35 @@ export function buildActionsFromStatus(input) {
537
538
  autoApplicable: configStatus.status !== "newer",
538
539
  }));
539
540
  }
541
+ // implements REQ-cli-status-pre-first-sync
542
+ // A branch store that was never compiled while .kb/ holds authored sources
543
+ // is fixed only by compiling it: `kibi branch ensure` alone leaves an empty
544
+ // manifest. The compile step runs after the store exists and after any
545
+ // schema migration, so it compiles the migrated sources.
546
+ const uncompiled = (input.staleReasons ?? []).find((reason) => reason.code === BRANCH_STORE_NOT_COMPILED);
547
+ if (uncompiled !== undefined) {
548
+ actions.push(migrationAction({
549
+ id: "branch-store-compile",
550
+ code: BRANCH_STORE_NOT_COMPILED,
551
+ category: "storage",
552
+ safety: "automatic",
553
+ invocation: { kind: "cli", command_argv: ["kibi", "sync"] },
554
+ affectedFiles: [
555
+ typeof store?.path === "string" ? store.path : ".kb/branches",
556
+ ],
557
+ evidence: { reason: uncompiled },
558
+ dependsOn: actions
559
+ .map((action) => action.id)
560
+ .filter((id) => id === "branch-store-ensure" || id === "schema-config-upgrade"),
561
+ postconditions: [{ branchStore: "compiled" }],
562
+ autoApplicable: true,
563
+ }));
564
+ }
540
565
  for (const reason of input.staleReasons ?? []) {
541
566
  const code = typeof reason.code === "string" ? reason.code : "stale_source";
567
+ // Planned above as an automatic compile step, not a review.
568
+ if (code === BRANCH_STORE_NOT_COMPILED)
569
+ continue;
542
570
  const file = typeof reason.path === "string" ? reason.path : "";
543
571
  actions.push(migrationAction({
544
572
  id: `freshness-${code}-${file}`,
@@ -1 +1 @@
1
- {"version":3,"file":"source-relationship-parity.d.ts","sourceRoot":"","sources":["../../../src/public/operations/source-relationship-parity.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACpC,CAAC,CAAC;AAaH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,EAC7C,QAAQ,EAAE,SAAS,wBAAwB,EAAE,GAC5C,SAAS,EAAE,CAwDb;AAuCD,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,wBAAwB,EAAE,CAmB5B;AAaD,wBAAsB,yCAAyC,CAC7D,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC,CA2DtB"}
1
+ {"version":3,"file":"source-relationship-parity.d.ts","sourceRoot":"","sources":["../../../src/public/operations/source-relationship-parity.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;CACpC,CAAC,CAAC;AAaH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,wBAAwB,EAAE,EAC7C,QAAQ,EAAE,SAAS,wBAAwB,EAAE,GAC5C,SAAS,EAAE,CAwDb;AAuCD,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,wBAAwB,EAAE,CAmB5B;AA6BD,wBAAsB,yCAAyC,CAC7D,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC,CA0DtB"}