kibi-cli 0.11.1 → 0.12.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/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +1 -1
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +2 -3
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +7 -2
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/sync/manifest.d.ts +1 -1
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +7 -4
- package/dist/commands/sync/staging.d.ts.map +1 -1
- package/dist/commands/sync/staging.js +2 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +3 -1
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +3 -1
- package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
- package/dist/extractors/symbol-coordinates.js +1 -1
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +2 -1
- package/dist/extractors/symbols-ts.d.ts.map +1 -1
- package/dist/extractors/symbols-ts.js +3 -1
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +14 -1
- package/dist/public/ignore-policy.d.ts.map +1 -1
- package/dist/public/ignore-policy.js +8 -4
- package/dist/public/operational-artifacts.d.ts.map +1 -1
- package/dist/public/operational-artifacts.js +1 -0
- package/dist/public/schemas/entity.d.ts +1 -127
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +79 -2
- package/dist/public/schemas/relationship.d.ts.map +1 -1
- package/dist/public/schemas/relationship.js +1 -0
- package/dist/public/skills/kibi-usage/SKILL.md +80 -0
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +78 -0
- package/dist/public/skills/kibi-usage/resources/workflows.md +0 -7
- package/dist/public/skills.d.ts.map +1 -1
- package/dist/public/skills.js +12 -4
- package/dist/schemas/entity.schema.json +81 -4
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/traceability/evidence-model.d.ts.map +1 -1
- package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
- package/dist/traceability/staged-diagnostics.js +1 -1
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +8 -2
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +4 -1
- package/dist/types/entities.d.ts +11 -2
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/types/relationships.d.ts +1 -1
- package/dist/types/relationships.d.ts.map +1 -1
- package/dist/utils/config.d.ts +3 -18
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +4 -40
- package/dist/utils/manifest-paths.d.ts.map +1 -1
- package/dist/utils/manifest-paths.js +3 -1
- package/dist/utils/schema-version.d.ts.map +1 -1
- package/dist/utils/strict-modeling.d.ts +1 -1
- package/dist/utils/strict-modeling.d.ts.map +1 -1
- package/dist/utils/strict-modeling.js +13 -3
- package/package.json +3 -13
- package/schema/config.json +0 -68
- package/src/public/ignore-policy.ts +26 -10
- package/src/public/operational-artifacts.ts +2 -1
- package/src/public/schemas/entity.ts +89 -5
- package/src/public/schemas/relationship.ts +1 -0
- package/src/public/skills/kibi-usage/SKILL.md +80 -0
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +78 -0
- package/src/public/skills/kibi-usage/resources/workflows.md +0 -7
- package/src/public/skills.ts +93 -25
- package/src/schemas/entity.schema.json +81 -4
- package/src/schemas/relationship.schema.json +1 -0
- package/dist/public/brief-config.d.ts +0 -4
- package/dist/public/brief-config.d.ts.map +0 -1
- package/dist/public/brief-config.js +0 -21
- package/src/public/brief-config.ts +0 -25
|
@@ -24,6 +24,84 @@ value_type: int
|
|
|
24
24
|
value_int: 3
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
## Granular Facts for Coherence Checks
|
|
28
|
+
|
|
29
|
+
Granular strict facts work best when each `property_value` represents one semantic claim about one `subject_key` and one `property_key`. This lets `domain-contradictions` compare current requirements that constrain the same subject and require incompatible values.
|
|
30
|
+
|
|
31
|
+
### Role set conflict
|
|
32
|
+
|
|
33
|
+
`REQ-ROLE-SET-2` and `REQ-ROLE-SET-3` are incoherent if both are current: they each define the exact allowed role set, but one allows two roles and the other allows three.
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
subject:
|
|
37
|
+
id: FACT-USER-ROLES
|
|
38
|
+
title: User roles
|
|
39
|
+
status: active
|
|
40
|
+
fact_kind: subject
|
|
41
|
+
subject_key: user.roles
|
|
42
|
+
|
|
43
|
+
property_values:
|
|
44
|
+
- id: FACT-USER-ROLES-ALLOWED-2
|
|
45
|
+
title: User and admin roles only
|
|
46
|
+
status: active
|
|
47
|
+
fact_kind: property_value
|
|
48
|
+
subject_key: user.roles
|
|
49
|
+
property_key: user.roles.allowed_set
|
|
50
|
+
operator: eq
|
|
51
|
+
value_type: list
|
|
52
|
+
value_json: '["user", "admin"]'
|
|
53
|
+
- id: FACT-USER-ROLES-ALLOWED-3
|
|
54
|
+
title: User, admin, and superadmin roles
|
|
55
|
+
status: active
|
|
56
|
+
fact_kind: property_value
|
|
57
|
+
subject_key: user.roles
|
|
58
|
+
property_key: user.roles.allowed_set
|
|
59
|
+
operator: eq
|
|
60
|
+
value_type: list
|
|
61
|
+
value_json: '["user", "admin", "superadmin"]'
|
|
62
|
+
|
|
63
|
+
relationships:
|
|
64
|
+
- { type: constrains, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES }
|
|
65
|
+
- { type: requires_property, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES-ALLOWED-2 }
|
|
66
|
+
- { type: constrains, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES }
|
|
67
|
+
- { type: requires_property, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES-ALLOWED-3 }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Permission actor conflict
|
|
71
|
+
|
|
72
|
+
`REQ-ADMIN-CAN-MANAGE-BILLING` and `REQ-ONLY-SUPERADMIN-MANAGES-BILLING` conflict when both define the exact allowed actor for the same permission.
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
subject:
|
|
76
|
+
id: FACT-BILLING-MANAGE
|
|
77
|
+
title: Billing management permission
|
|
78
|
+
status: active
|
|
79
|
+
fact_kind: subject
|
|
80
|
+
subject_key: billing.manage
|
|
81
|
+
|
|
82
|
+
property_values:
|
|
83
|
+
- id: FACT-BILLING-MANAGE-ACTOR-ADMIN
|
|
84
|
+
title: Admin can manage billing
|
|
85
|
+
status: active
|
|
86
|
+
fact_kind: property_value
|
|
87
|
+
subject_key: billing.manage
|
|
88
|
+
property_key: billing.manage.allowed_actor
|
|
89
|
+
operator: eq
|
|
90
|
+
value_type: string
|
|
91
|
+
value_string: admin
|
|
92
|
+
- id: FACT-BILLING-MANAGE-ACTOR-SUPERADMIN
|
|
93
|
+
title: Only superadmin can manage billing
|
|
94
|
+
status: active
|
|
95
|
+
fact_kind: property_value
|
|
96
|
+
subject_key: billing.manage
|
|
97
|
+
property_key: billing.manage.allowed_actor
|
|
98
|
+
operator: eq
|
|
99
|
+
value_type: string
|
|
100
|
+
value_string: superadmin
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
When a contradiction is intentional evolution rather than a real conflict, link the replaced requirement to the replacement requirement with `supersedes`.
|
|
104
|
+
|
|
27
105
|
## Context Lane (Non-Blocking)
|
|
28
106
|
|
|
29
107
|
### fact_kind: observation
|
|
@@ -26,10 +26,3 @@ The canonical workflow for any KB operation follows this pattern:
|
|
|
26
26
|
3. kb_upsert to add missing relationship rows (sequential)
|
|
27
27
|
4. kb_check with rules: ["no-dangling-refs", "symbol-traceability"]
|
|
28
28
|
```
|
|
29
|
-
|
|
30
|
-
## Before Risky Work
|
|
31
|
-
```
|
|
32
|
-
1. /brief-kibi or kb_briefing_generate for citation-backed briefing
|
|
33
|
-
2. Inspect briefingState; proceed only if ready
|
|
34
|
-
3. Use constraints, regressionRisks, and cited entities from the briefing
|
|
35
|
-
```
|
package/src/public/skills.ts
CHANGED
|
@@ -84,14 +84,17 @@ export class SkillOversizeError extends Error {
|
|
|
84
84
|
readonly actualBytes: number;
|
|
85
85
|
|
|
86
86
|
constructor(pathLike: string, maxBytes: number, actualBytes: number) {
|
|
87
|
-
super(
|
|
87
|
+
super(
|
|
88
|
+
`Skill file exceeds ${maxBytes} bytes: ${pathLike} (${actualBytes} bytes)`,
|
|
89
|
+
);
|
|
88
90
|
this.name = "SkillOversizeError";
|
|
89
91
|
this.maxBytes = maxBytes;
|
|
90
92
|
this.actualBytes = actualBytes;
|
|
91
93
|
}
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
export function listBundledSkills(): SkillManifest[] {
|
|
96
|
+
export function listBundledSkills(): SkillManifest[] {
|
|
97
|
+
// implements REQ-001
|
|
95
98
|
if (!existsSync(bundledSkillsDir)) {
|
|
96
99
|
return [];
|
|
97
100
|
}
|
|
@@ -104,7 +107,8 @@ export function listBundledSkills(): SkillManifest[] { // implements REQ-001
|
|
|
104
107
|
.sort((left, right) => left.id.localeCompare(right.id));
|
|
105
108
|
}
|
|
106
109
|
|
|
107
|
-
export function loadBundledSkill(id: string): SkillBundle {
|
|
110
|
+
export function loadBundledSkill(id: string): SkillBundle {
|
|
111
|
+
// implements REQ-001
|
|
108
112
|
const rootDir = findBundledSkillRoot(id);
|
|
109
113
|
if (!rootDir) {
|
|
110
114
|
throw new SkillNotFoundError(id);
|
|
@@ -116,7 +120,8 @@ export function loadBundledSkill(id: string): SkillBundle { // implements REQ-00
|
|
|
116
120
|
export function readBundledSkillResource(
|
|
117
121
|
id: string,
|
|
118
122
|
resourcePath: string,
|
|
119
|
-
): string {
|
|
123
|
+
): string {
|
|
124
|
+
// implements REQ-001
|
|
120
125
|
const bundle = loadBundledSkill(id);
|
|
121
126
|
const declaredResource = normalizeResourcePath(resourcePath);
|
|
122
127
|
|
|
@@ -146,14 +151,18 @@ export function readBundledSkillResource(
|
|
|
146
151
|
return readFileSync(candidatePath, "utf8");
|
|
147
152
|
}
|
|
148
153
|
|
|
149
|
-
export function validateSkillBundle(
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
export function validateSkillBundle(pathLike: string): {
|
|
155
|
+
valid: boolean;
|
|
156
|
+
errors: SkillValidationError[];
|
|
157
|
+
} {
|
|
158
|
+
// implements REQ-001
|
|
152
159
|
const skillFilePath = resolveSkillFilePath(pathLike);
|
|
153
160
|
const errors: SkillValidationError[] = [];
|
|
154
161
|
|
|
155
162
|
if (!existsSync(skillFilePath)) {
|
|
156
|
-
errors.push(
|
|
163
|
+
errors.push(
|
|
164
|
+
new SkillValidationError("SKILL.md", `Missing ${SKILL_FILE_NAME}`),
|
|
165
|
+
);
|
|
157
166
|
return { valid: false, errors };
|
|
158
167
|
}
|
|
159
168
|
|
|
@@ -175,7 +184,12 @@ function validateBundleContents(
|
|
|
175
184
|
try {
|
|
176
185
|
assertMaxBytes(skillFilePath, SKILL_MARKDOWN_MAX_BYTES);
|
|
177
186
|
} catch (error) {
|
|
178
|
-
errors.push(
|
|
187
|
+
errors.push(
|
|
188
|
+
new SkillValidationError(
|
|
189
|
+
"SKILL.md",
|
|
190
|
+
error instanceof Error ? error.message : String(error),
|
|
191
|
+
),
|
|
192
|
+
);
|
|
179
193
|
}
|
|
180
194
|
|
|
181
195
|
const rootDir = dirname(skillFilePath);
|
|
@@ -183,7 +197,12 @@ function validateBundleContents(
|
|
|
183
197
|
try {
|
|
184
198
|
realRootDir = realpathSync(rootDir);
|
|
185
199
|
} catch (error) {
|
|
186
|
-
errors.push(
|
|
200
|
+
errors.push(
|
|
201
|
+
new SkillValidationError(
|
|
202
|
+
"SKILL.md",
|
|
203
|
+
error instanceof Error ? error.message : String(error),
|
|
204
|
+
),
|
|
205
|
+
);
|
|
187
206
|
return;
|
|
188
207
|
}
|
|
189
208
|
|
|
@@ -191,19 +210,34 @@ function validateBundleContents(
|
|
|
191
210
|
const resourcePath = resolve(rootDir, resource);
|
|
192
211
|
try {
|
|
193
212
|
if (!existsSync(resourcePath)) {
|
|
194
|
-
errors.push(
|
|
213
|
+
errors.push(
|
|
214
|
+
new SkillValidationError(
|
|
215
|
+
"resources",
|
|
216
|
+
`Missing skill resource: ${resource}`,
|
|
217
|
+
),
|
|
218
|
+
);
|
|
195
219
|
continue;
|
|
196
220
|
}
|
|
197
221
|
|
|
198
222
|
const realResourcePath = realpathSync(resourcePath);
|
|
199
223
|
if (!isWithinRoot(realRootDir, realResourcePath)) {
|
|
200
|
-
errors.push(
|
|
224
|
+
errors.push(
|
|
225
|
+
new SkillValidationError(
|
|
226
|
+
"resources",
|
|
227
|
+
`Skill resource escapes bundle root: ${resource}`,
|
|
228
|
+
),
|
|
229
|
+
);
|
|
201
230
|
continue;
|
|
202
231
|
}
|
|
203
232
|
|
|
204
233
|
assertMaxBytes(resourcePath, RESOURCE_MAX_BYTES);
|
|
205
234
|
} catch (error) {
|
|
206
|
-
errors.push(
|
|
235
|
+
errors.push(
|
|
236
|
+
new SkillValidationError(
|
|
237
|
+
"resources",
|
|
238
|
+
error instanceof Error ? error.message : String(error),
|
|
239
|
+
),
|
|
240
|
+
);
|
|
207
241
|
}
|
|
208
242
|
}
|
|
209
243
|
}
|
|
@@ -250,7 +284,9 @@ function parseSkillBundle(rootDir: string): SkillBundle {
|
|
|
250
284
|
};
|
|
251
285
|
}
|
|
252
286
|
|
|
253
|
-
function validateManifestData(
|
|
287
|
+
function validateManifestData(
|
|
288
|
+
data: Record<string, unknown>,
|
|
289
|
+
): SkillValidationError[] {
|
|
254
290
|
const errors: SkillValidationError[] = [];
|
|
255
291
|
const requiredFields = [
|
|
256
292
|
"id",
|
|
@@ -262,12 +298,25 @@ function validateManifestData(data: Record<string, unknown>): SkillValidationErr
|
|
|
262
298
|
|
|
263
299
|
for (const field of requiredFields) {
|
|
264
300
|
if (typeof data[field] !== "string" || data[field].trim() === "") {
|
|
265
|
-
errors.push(
|
|
301
|
+
errors.push(
|
|
302
|
+
new SkillValidationError(
|
|
303
|
+
field,
|
|
304
|
+
`Missing required skill field: ${field}`,
|
|
305
|
+
),
|
|
306
|
+
);
|
|
266
307
|
}
|
|
267
308
|
}
|
|
268
309
|
|
|
269
|
-
if (
|
|
270
|
-
|
|
310
|
+
if (
|
|
311
|
+
typeof data.version === "string" &&
|
|
312
|
+
!/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(data.version)
|
|
313
|
+
) {
|
|
314
|
+
errors.push(
|
|
315
|
+
new SkillValidationError(
|
|
316
|
+
"version",
|
|
317
|
+
`Invalid skill version: ${data.version}`,
|
|
318
|
+
),
|
|
319
|
+
);
|
|
271
320
|
}
|
|
272
321
|
|
|
273
322
|
if (data.tags !== undefined && !isStringArray(data.tags)) {
|
|
@@ -276,13 +325,21 @@ function validateManifestData(data: Record<string, unknown>): SkillValidationErr
|
|
|
276
325
|
|
|
277
326
|
if (data.resources !== undefined) {
|
|
278
327
|
if (!isStringArray(data.resources)) {
|
|
279
|
-
errors.push(
|
|
328
|
+
errors.push(
|
|
329
|
+
new SkillValidationError(
|
|
330
|
+
"resources",
|
|
331
|
+
"Skill resources must be strings",
|
|
332
|
+
),
|
|
333
|
+
);
|
|
280
334
|
} else {
|
|
281
335
|
for (const resource of data.resources) {
|
|
282
336
|
const normalized = normalizeResourcePath(resource);
|
|
283
337
|
if (!normalized || isPathOutOfBounds(resource)) {
|
|
284
338
|
errors.push(
|
|
285
|
-
new SkillValidationError(
|
|
339
|
+
new SkillValidationError(
|
|
340
|
+
"resources",
|
|
341
|
+
`Invalid skill resource: ${resource}`,
|
|
342
|
+
),
|
|
286
343
|
);
|
|
287
344
|
}
|
|
288
345
|
}
|
|
@@ -306,14 +363,18 @@ function coerceManifest(data: Record<string, unknown>): SkillManifest {
|
|
|
306
363
|
}
|
|
307
364
|
|
|
308
365
|
if (isStringArray(data.resources)) {
|
|
309
|
-
manifest.resources = data.resources.map((resource) =>
|
|
366
|
+
manifest.resources = data.resources.map((resource) =>
|
|
367
|
+
normalizeResourcePath(resource),
|
|
368
|
+
);
|
|
310
369
|
}
|
|
311
370
|
|
|
312
371
|
return manifest;
|
|
313
372
|
}
|
|
314
373
|
|
|
315
374
|
function isStringArray(value: unknown): value is string[] {
|
|
316
|
-
return
|
|
375
|
+
return (
|
|
376
|
+
Array.isArray(value) && value.every((item) => typeof item === "string")
|
|
377
|
+
);
|
|
317
378
|
}
|
|
318
379
|
|
|
319
380
|
function normalizeResourcePath(pathLike: string): string {
|
|
@@ -330,7 +391,10 @@ function isPathOutOfBounds(pathLike: string): boolean {
|
|
|
330
391
|
);
|
|
331
392
|
}
|
|
332
393
|
|
|
333
|
-
function isDeclaredResource(
|
|
394
|
+
function isDeclaredResource(
|
|
395
|
+
manifest: SkillManifest,
|
|
396
|
+
resourcePath: string,
|
|
397
|
+
): boolean {
|
|
334
398
|
return (manifest.resources ?? []).some(
|
|
335
399
|
(declared) => normalizeResourcePath(declared) === resourcePath,
|
|
336
400
|
);
|
|
@@ -338,7 +402,10 @@ function isDeclaredResource(manifest: SkillManifest, resourcePath: string): bool
|
|
|
338
402
|
|
|
339
403
|
function isWithinRoot(rootDir: string, candidatePath: string): boolean {
|
|
340
404
|
const relativePath = relative(rootDir, candidatePath);
|
|
341
|
-
return
|
|
405
|
+
return (
|
|
406
|
+
relativePath === "" ||
|
|
407
|
+
(!relativePath.startsWith("..") && !isAbsolute(relativePath))
|
|
408
|
+
);
|
|
342
409
|
}
|
|
343
410
|
|
|
344
411
|
function assertMaxBytes(pathLike: string, maxBytes: number): void {
|
|
@@ -354,6 +421,7 @@ function resolveSkillFilePath(pathLike: string): string {
|
|
|
354
421
|
return join(resolved, SKILL_FILE_NAME);
|
|
355
422
|
}
|
|
356
423
|
|
|
357
|
-
return resolved.endsWith(SKILL_FILE_NAME)
|
|
424
|
+
return resolved.endsWith(SKILL_FILE_NAME)
|
|
425
|
+
? resolved
|
|
426
|
+
: join(resolved, SKILL_FILE_NAME);
|
|
358
427
|
}
|
|
359
|
-
|
|
@@ -62,7 +62,14 @@
|
|
|
62
62
|
},
|
|
63
63
|
"fact_kind": {
|
|
64
64
|
"type": "string",
|
|
65
|
-
"enum": [
|
|
65
|
+
"enum": [
|
|
66
|
+
"subject",
|
|
67
|
+
"property_value",
|
|
68
|
+
"observation",
|
|
69
|
+
"meta",
|
|
70
|
+
"predicate_schema",
|
|
71
|
+
"predicate"
|
|
72
|
+
]
|
|
66
73
|
},
|
|
67
74
|
"subject_key": { "type": "string" },
|
|
68
75
|
"property_key": { "type": "string" },
|
|
@@ -80,11 +87,26 @@
|
|
|
80
87
|
"value_bool": { "type": "boolean" },
|
|
81
88
|
"unit": { "type": "string" },
|
|
82
89
|
"scope": { "type": "string" },
|
|
83
|
-
"polarity": {
|
|
90
|
+
"polarity": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"enum": ["require", "forbid", "assert", "deny"]
|
|
93
|
+
},
|
|
84
94
|
"closed_world": { "type": "boolean" },
|
|
85
95
|
"valid_from": { "type": "string" },
|
|
86
96
|
"valid_to": { "type": "string" },
|
|
87
|
-
"canonical_key": { "type": "string" }
|
|
97
|
+
"canonical_key": { "type": "string" },
|
|
98
|
+
"predicate_name": { "type": "string" },
|
|
99
|
+
"predicate_namespace": { "type": "string" },
|
|
100
|
+
"predicate_arity": { "type": "integer", "minimum": 1 },
|
|
101
|
+
"argument_names": { "type": "array", "items": { "type": "string" } },
|
|
102
|
+
"argument_types": { "type": "array", "items": { "type": "string" } },
|
|
103
|
+
"argument_descriptions": {
|
|
104
|
+
"type": "array",
|
|
105
|
+
"items": { "type": "string" }
|
|
106
|
+
},
|
|
107
|
+
"aliases": { "type": "array", "items": { "type": "string" } },
|
|
108
|
+
"examples": { "type": "array", "items": { "type": "string" } },
|
|
109
|
+
"predicate_args": { "type": "array", "items": { "type": "string" } }
|
|
88
110
|
},
|
|
89
111
|
"required": [
|
|
90
112
|
"id",
|
|
@@ -133,10 +155,65 @@
|
|
|
133
155
|
{ "required": ["closed_world"] },
|
|
134
156
|
{ "required": ["valid_from"] },
|
|
135
157
|
{ "required": ["valid_to"] },
|
|
136
|
-
{ "required": ["canonical_key"] }
|
|
158
|
+
{ "required": ["canonical_key"] },
|
|
159
|
+
{ "required": ["predicate_name"] },
|
|
160
|
+
{ "required": ["predicate_namespace"] },
|
|
161
|
+
{ "required": ["predicate_arity"] },
|
|
162
|
+
{ "required": ["argument_names"] },
|
|
163
|
+
{ "required": ["argument_types"] },
|
|
164
|
+
{ "required": ["argument_descriptions"] },
|
|
165
|
+
{ "required": ["aliases"] },
|
|
166
|
+
{ "required": ["examples"] },
|
|
167
|
+
{ "required": ["predicate_args"] }
|
|
137
168
|
]
|
|
138
169
|
}
|
|
139
170
|
}
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"if": {
|
|
174
|
+
"properties": {
|
|
175
|
+
"type": { "const": "fact" },
|
|
176
|
+
"fact_kind": { "const": "predicate_schema" }
|
|
177
|
+
},
|
|
178
|
+
"required": ["type", "fact_kind"]
|
|
179
|
+
},
|
|
180
|
+
"then": {
|
|
181
|
+
"required": [
|
|
182
|
+
"predicate_name",
|
|
183
|
+
"predicate_arity",
|
|
184
|
+
"argument_names",
|
|
185
|
+
"argument_types"
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"if": {
|
|
191
|
+
"properties": {
|
|
192
|
+
"type": { "const": "fact" },
|
|
193
|
+
"fact_kind": { "const": "predicate" }
|
|
194
|
+
},
|
|
195
|
+
"required": ["type", "fact_kind"]
|
|
196
|
+
},
|
|
197
|
+
"then": {
|
|
198
|
+
"required": ["predicate_name", "predicate_args", "canonical_key"],
|
|
199
|
+
"properties": {
|
|
200
|
+
"polarity": { "enum": ["assert", "deny"] }
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"if": {
|
|
206
|
+
"properties": {
|
|
207
|
+
"type": { "const": "fact" },
|
|
208
|
+
"fact_kind": { "const": "property_value" }
|
|
209
|
+
},
|
|
210
|
+
"required": ["type", "fact_kind"]
|
|
211
|
+
},
|
|
212
|
+
"then": {
|
|
213
|
+
"properties": {
|
|
214
|
+
"polarity": { "enum": ["require", "forbid"] }
|
|
215
|
+
}
|
|
216
|
+
}
|
|
140
217
|
}
|
|
141
218
|
],
|
|
142
219
|
"additionalProperties": false
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"brief-config.d.ts","sourceRoot":"","sources":["../../src/public/brief-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEnE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,YAAY,CAoBzE"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { loadConfig } from "../utils/config.js";
|
|
2
|
-
export function loadBriefConfig(cwd = process.cwd()) {
|
|
3
|
-
const briefs = loadConfig(cwd).briefs;
|
|
4
|
-
return {
|
|
5
|
-
enabled: briefs?.enabled ?? true,
|
|
6
|
-
retention: {
|
|
7
|
-
maxPerBranch: briefs?.retention?.maxPerBranch ?? 200,
|
|
8
|
-
maxAgeDays: briefs?.retention?.maxAgeDays ?? 14,
|
|
9
|
-
keepUnread: briefs?.retention?.keepUnread ?? true,
|
|
10
|
-
},
|
|
11
|
-
channels: {
|
|
12
|
-
vscode: briefs?.channels?.vscode ?? true,
|
|
13
|
-
tui: briefs?.channels?.tui ?? true,
|
|
14
|
-
},
|
|
15
|
-
tui: {
|
|
16
|
-
toast: briefs?.tui?.toast ?? true,
|
|
17
|
-
appendPrompt: briefs?.tui?.appendPrompt ?? true,
|
|
18
|
-
idleDelayMs: briefs?.tui?.idleDelayMs ?? 1500,
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { loadConfig, type BriefsConfig } from "../utils/config.js";
|
|
2
|
-
|
|
3
|
-
export type { BriefsConfig } from "../utils/config.js";
|
|
4
|
-
|
|
5
|
-
export function loadBriefConfig(cwd: string = process.cwd()): BriefsConfig { // implements REQ-003
|
|
6
|
-
const briefs = loadConfig(cwd).briefs;
|
|
7
|
-
|
|
8
|
-
return {
|
|
9
|
-
enabled: briefs?.enabled ?? true,
|
|
10
|
-
retention: {
|
|
11
|
-
maxPerBranch: briefs?.retention?.maxPerBranch ?? 200,
|
|
12
|
-
maxAgeDays: briefs?.retention?.maxAgeDays ?? 14,
|
|
13
|
-
keepUnread: briefs?.retention?.keepUnread ?? true,
|
|
14
|
-
},
|
|
15
|
-
channels: {
|
|
16
|
-
vscode: briefs?.channels?.vscode ?? true,
|
|
17
|
-
tui: briefs?.channels?.tui ?? true,
|
|
18
|
-
},
|
|
19
|
-
tui: {
|
|
20
|
-
toast: briefs?.tui?.toast ?? true,
|
|
21
|
-
appendPrompt: briefs?.tui?.appendPrompt ?? true,
|
|
22
|
-
idleDelayMs: briefs?.tui?.idleDelayMs ?? 1500,
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
}
|