@fenglimg/fabric-shared 2.2.0-rc.9 → 2.3.0-rc.1

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.
@@ -18,6 +18,7 @@ import { z as z2 } from "zod";
18
18
  var PERSONAL_SCOPE = "personal";
19
19
  var KNOWN_SCOPE_PREFIXES = ["personal", "team", "project", "org"];
20
20
  var SCOPE_COORDINATE_PATTERN = /^[a-z0-9_-]+(:[a-z0-9_-]+)*$/u;
21
+ var SCOPE_COORDINATE_HINT = 'scope coordinate must look like "project:fabric-v2", "team", or "personal" \u2014 lowercase [a-z0-9_-] segments joined by ":"';
21
22
  var scopeCoordinateSchema = z2.string().min(1).regex(
22
23
  SCOPE_COORDINATE_PATTERN,
23
24
  "scope coordinate must be ':'-joined lowercase [a-z0-9_-] segments"
@@ -129,6 +130,7 @@ var _preflightDiagnosticSchema = z3.object({
129
130
  stable_ids: z3.array(z3.string()).optional(),
130
131
  path: z3.string().optional()
131
132
  });
133
+ var _recallDropReasonSchema = z3.enum(["retrieval_budget", "payload_budget"]);
132
134
  var planContextOutputSchema = z3.object({
133
135
  revision_hash: z3.string(),
134
136
  stale: z3.boolean(),
@@ -143,12 +145,16 @@ var planContextOutputSchema = z3.object({
143
145
  // duplicated into every entry's requirement_profile). Omitted when no intent.
144
146
  intent: z3.string().optional(),
145
147
  candidates: z3.array(_descriptionIndexItemSchema),
146
- // v2.2 A-INFRA-3 (W1-T3-TOPK) / MC4-payload-budget (W1-T4): number of
147
- // lower-ranked candidates dropped by the unified truncation chain (top_k cap
148
- // + payload-budget trim). Present and > 0 ONLY when truncation fired, so the
149
- // steady-state wire shape is unchanged. Lets the LLM know the returned set is
150
- // not exhaustive ("N more exist; narrow your intent").
151
- omitted_candidate_count: z3.number().int().nonnegative().optional(),
148
+ // v2.2 A-INFRA-3 (W1-T3-TOPK) / MC4-payload-budget (W1-T4) / K6 (W3-K):
149
+ // structured list of lower-ranked candidates dropped by the unified truncation
150
+ // chain, each tagged with WHY it was dropped (`retrieval_budget` = top_k cap +
151
+ // ratio-to-top floor; `payload_budget` = MCP payload-byte trim). Present and
152
+ // non-empty ONLY when truncation fired, so the steady-state wire shape is
153
+ // unchanged. Replaces the bare numeric omission count so the LLM sees WHICH
154
+ // candidates were dropped and can act ("these N exist; narrow your intent").
155
+ // Reuses the archive-scan {key,reason} omission convention
156
+ // (_recallDropReasonSchema, keyed on id here).
157
+ dropped: z3.array(z3.object({ id: z3.string(), reason: _recallDropReasonSchema })).optional(),
152
158
  preflight_diagnostics: z3.array(_preflightDiagnosticSchema),
153
159
  warnings: z3.array(structuredWarningSchema).optional(),
154
160
  // v2.0.0-rc.22 Scope D T-D2: optional auto-heal banner fields. Surfaced
@@ -293,39 +299,40 @@ var recallInputSchema = z3.object({
293
299
  "When true, also surface the one-hop `related` graph neighbours (of the surfaced entries) that are present in the candidate set \u2014 their descriptions and read paths, NOT their bodies."
294
300
  )
295
301
  });
302
+ var _recallEntrySchema = z3.object({
303
+ stable_id: z3.string(),
304
+ // 1-based relevance rank (entries are returned best-first). The surfaced
305
+ // ranking signal — entries are already sorted, rank makes the order explicit.
306
+ rank: z3.number().int().positive(),
307
+ // The DESCRIPTION (summary / intent_clues / must_read_if / related ...). No body.
308
+ description: _ruleDescriptionSchema,
309
+ // on-disk knowledge file to Read for the full body. Omitted when the entry has
310
+ // no resolvable file (description-only discovery) or was scoped out by `ids`.
311
+ read_path: z3.string().optional(),
312
+ // originating store alias (omitted for unqualified / single-store entries).
313
+ store: z3.object({ alias: z3.string() }).optional(),
314
+ // true when this entry's body is ALSO injected at SessionStart (broad
315
+ // model/guideline "ALWAYS-ACTIVE") — skip the Read, it is already in context.
316
+ body_in_context: z3.boolean().optional()
317
+ });
296
318
  var recallOutputSchema = z3.object({
297
319
  revision_hash: z3.string(),
298
320
  stale: z3.boolean(),
299
- // v2.0.0-rc.38 UX-1/UX-4: mirrors planContextOutputSchema fold per-path
300
- // description_index collapsed into a single top-level `candidates`, and
301
- // `preflight_diagnostics` lifted out of the removed `shared` wrapper.
302
- entries: z3.array(
303
- z3.object({
304
- path: z3.string(),
305
- requirement_profile: _requirementProfileSchema
306
- })
307
- ),
308
- // v2.2 payload de-dup: single top-level echo of the caller's `intent` (was
309
- // duplicated into every entry's requirement_profile). Omitted when no intent.
321
+ // ux-w2-4: single unified entry list (was candidates[] + paths[] + per-path
322
+ // requirement-profile entries[]). Each item carries description + read_path +
323
+ // rank + body_in_context, so the agent never joins two arrays on stable_id.
324
+ entries: z3.array(_recallEntrySchema),
325
+ // v2.2 payload de-dup: single top-level echo of the caller's `intent`.
326
+ // Omitted when no intent.
310
327
  intent: z3.string().optional(),
311
- // W1 (KT-DEC-0026): the discovery index every surfaced candidate's
312
- // DESCRIPTION (summary / intent_clues / must_read_if / related ...). No body.
313
- candidates: z3.array(_descriptionIndexItemSchema),
314
- // W1 (KT-DEC-0026): the read-path indexone entry per surfaced candidate
315
- // (scoped by `ids` when provided), in ranked order. `path` is the on-disk
316
- // knowledge file the agent Reads to load the body on demand; `store` is the
317
- // originating store alias (omitted for unqualified entries).
318
- paths: z3.array(
319
- z3.object({
320
- stable_id: z3.string(),
321
- path: z3.string(),
322
- store: z3.object({ alias: z3.string() }).optional()
323
- })
324
- ),
325
- // Number of lower-ranked candidates dropped by the retrieval budget. Present
326
- // (and > 0) ONLY when truncation fired — keeps the steady-state wire shape
327
- // unchanged while signalling "more exist; narrow your intent".
328
- omitted_candidate_count: z3.number().int().nonnegative().optional(),
328
+ // K6 (W3-K): structured list of lower-ranked candidates dropped by the
329
+ // retrieval pipeline, each tagged with WHY (`retrieval_budget` = top_k cap +
330
+ // ratio-to-top floor; `payload_budget` = MCP payload-byte trim). Present (and
331
+ // non-empty) ONLY when truncation fired keeps the steady-state wire shape
332
+ // unchanged while signalling which entries exist ("narrow your intent"), now
333
+ // with a controlled reason instead of a bare count. Reuses the archive-scan
334
+ // {key,reason} omission convention (_recallDropReasonSchema, keyed on id).
335
+ dropped: z3.array(z3.object({ id: z3.string(), reason: _recallDropReasonSchema })).optional(),
329
336
  preflight_diagnostics: z3.array(_preflightDiagnosticSchema),
330
337
  warnings: z3.array(structuredWarningSchema).optional(),
331
338
  auto_healed: z3.boolean().optional(),
@@ -366,6 +373,8 @@ var archiveScanOutputSchema = z3.object({
366
373
  // in first-seen order — ready for the Skill to load digests + stitch.
367
374
  session_ids: z3.array(z3.string()),
368
375
  // Sessions dropped by the filter, with the rule that fired (audit/debug).
376
+ // Shares the {key,reason} omission convention with recall's dropped[] above
377
+ // (keys on session_id here, on id in recall).
369
378
  dropped: z3.array(
370
379
  z3.object({
371
380
  session_id: z3.string(),
@@ -428,15 +437,19 @@ var _FabExtractKnowledgeInputBaseSchema = z3.object({
428
437
  user_messages_summary: z3.string().describe("Skill-side summary of the user's intent/messages, kept compact"),
429
438
  type: z3.enum(["decisions", "pitfalls", "guidelines", "models", "processes"]).describe("Knowledge type bucket (plural form, mirrors directory layout)"),
430
439
  slug: z3.string().describe("URL-safe short identifier proposed by the Skill; server may sanitize"),
431
- // Store-only cutover: layer is a compatibility audience hint. The server
432
- // resolves the actual write target through semantic_scope/write_routes and
433
- // writes to the selected mounted store's knowledge/pending/<type>/ tree.
434
- // Defaults to 'team' to preserve existing call sites (Skill bumps as needed).
435
- layer: z3.enum(["team", "personal"]).optional().describe(
436
- "Compatibility storage audience. 'personal' writes to the personal store; non-personal writes resolve by semantic_scope/write_routes. Defaults to 'team'."
437
- ),
438
- semantic_scope: z3.string().regex(SCOPE_COORDINATE_PATTERN).optional().describe(
439
- "Logical audience/write route coordinate for this pending entry, e.g. personal, team, project:fabric-v2, org:acme:team:platform. Server validates and resolves it through write_routes."
440
+ // v2.2 C1 (W1) — author-facing scope is now TWO fields only: `audience` +
441
+ // `paths`. Everything else (layer / visibility_store / relevance_scope /
442
+ // store) is engine-derived, never author input (C1 §一.1). The physical write
443
+ // store is the hard privacy boundary (cross-store-write R5#3); `audience` only
444
+ // subdivides WHO within that boundary.
445
+ //
446
+ // audience — the open scope coordinate describing WHO the entry is for
447
+ // (personal | team | project:x | org:y...). Replaces the old
448
+ // `layer` + `semantic_scope` pair: a `personal` coordinate routes
449
+ // to the personal store; everything else resolves via write_routes.
450
+ // Omit → engine defaults to project:<active> (bound repo) or team.
451
+ audience: z3.string().regex(SCOPE_COORDINATE_PATTERN, { message: SCOPE_COORDINATE_HINT }).optional().describe(
452
+ "WHO this entry is for \u2014 an open scope coordinate (personal | team | project:x | org:y...). The sole author-facing audience field; the engine derives layer/visibility_store/store from it + the physical write store. Omit to default to project:<active> (bound repo) or team."
440
453
  ),
441
454
  // v2.0.0-rc.7 T6: proposed_reason — required enum that drives `## Why
442
455
  // proposed` rendering. Skills (archive / import / review) infer the
@@ -462,11 +475,16 @@ var _FabExtractKnowledgeInputBaseSchema = z3.object({
462
475
  // a `knowledge_scope_degraded` event keyed by `pending:<idempotency_key>`.
463
476
  // NOTE: these fields MUST NOT be part of the idempotency hash inputs at
464
477
  // extract-knowledge.ts:78 — preserves rc.5→rc.7 collision detection.
465
- relevance_scope: z3.enum(["narrow", "broad"]).optional().describe(
466
- "Optional relevance scope. 'narrow' restricts plan-context-hint surfacing to relevance_paths; 'broad' always surfaces. Omit to let the meta-builder default to 'broad'. Personal + narrow is silently degraded to broad + []."
467
- ),
468
- relevance_paths: z3.array(z3.string()).optional().describe(
469
- "Optional path anchors for narrow scope. Workspace-relative globs or paths. Omit to let the meta-builder default to []. Ignored when scope is broad (server preserves the array for audit)."
478
+ // paths — relevance anchors (workspace-relative globs/paths). The engine
479
+ // DERIVES relevance_scope from this field's presence: non-empty
480
+ // narrow (surface only when an edit matches an anchor); empty/omitted
481
+ // → broad (always surface). This eliminates the old separate
482
+ // relevance_scope flag and its narrow+empty illegal state by
483
+ // construction (KT-MOD-0001). Glob syntax follows Copilot `applyTo`
484
+ // / Cursor `globs` (cross-client moat). Personal audience forces
485
+ // broad+[] (workspace-relative paths cross-project lose meaning).
486
+ paths: z3.array(z3.string()).optional().describe(
487
+ "Relevance anchors (workspace-relative globs/paths). Non-empty \u2192 narrow (surface only on matching edits); empty/omitted \u2192 broad (always surface). The engine derives relevance_scope from this \u2014 there is no separate scope flag."
470
488
  ),
471
489
  // v2.0.0-rc.23 TASK-006 (a-C1): four optional structured fields that the
472
490
  // skill-side LLM populates from raw observations. The same information
@@ -512,7 +530,7 @@ var _FabExtractKnowledgeInputBaseSchema = z3.object({
512
530
  // discover unclaimed slots, then propagates the chosen slot label here
513
531
  // so the resulting pending entry counts toward coverage.
514
532
  //
515
- // STRICT optionality: every non-onboard fab_extract_knowledge call MUST
533
+ // STRICT optionality: every non-onboard fab_propose call MUST
516
534
  // omit this field. The skill is the only producer; downstream consumers
517
535
  // (plan_context retrieval, doctor lints) treat missing as a steady-state
518
536
  // signal that the entry was NOT part of an onboard pass.
@@ -627,10 +645,6 @@ var _fabReviewModifyChangesSchema = z3.object({
627
645
  related: z3.array(z3.string()).optional()
628
646
  });
629
647
  var FabReviewInputSchema = z3.discriminatedUnion("action", [
630
- z3.object({
631
- action: z3.literal("list"),
632
- filters: _fabReviewFiltersSchema
633
- }),
634
648
  z3.object({
635
649
  action: z3.literal("approve"),
636
650
  pending_paths: z3.array(z3.string()).min(1)
@@ -663,11 +677,6 @@ var FabReviewInputSchema = z3.discriminatedUnion("action", [
663
677
  layer: z3.enum(["team", "personal"])
664
678
  })
665
679
  }),
666
- z3.object({
667
- action: z3.literal("search"),
668
- query: z3.string().min(1),
669
- filters: _fabReviewFiltersSchema
670
- }),
671
680
  z3.object({
672
681
  action: z3.literal("defer"),
673
682
  pending_paths: z3.array(z3.string()).min(1),
@@ -675,13 +684,32 @@ var FabReviewInputSchema = z3.discriminatedUnion("action", [
675
684
  reason: z3.string().optional()
676
685
  })
677
686
  ]);
678
- var FabReviewInputShape = {
679
- action: z3.enum(["list", "approve", "reject", "modify", "modify-content", "modify-layer", "search", "defer"]).describe(
680
- "Action selector. Discriminates the per-action fields below; required. modify-content edits scalars (no layer); modify-layer is the layer-flip path (changes.layer required); modify is the legacy combined alias."
687
+ var FabPendingInputSchema = z3.discriminatedUnion("action", [
688
+ z3.object({
689
+ action: z3.literal("list"),
690
+ filters: _fabReviewFiltersSchema
691
+ }),
692
+ z3.object({
693
+ action: z3.literal("search"),
694
+ query: z3.string().min(1),
695
+ filters: _fabReviewFiltersSchema
696
+ })
697
+ ]);
698
+ var FabPendingInputShape = {
699
+ action: z3.enum(["list", "search"]).describe(
700
+ "Action selector. Discriminates the per-action fields below; required. list browses pending entries; search ranges over pending + canonical knowledge."
681
701
  ),
682
702
  filters: _fabReviewFiltersSchema.describe(
683
703
  "Optional filters (type/layer/maturity/tags/created_after). Used by action=list and action=search."
684
704
  ),
705
+ query: z3.string().min(1).optional().describe(
706
+ "Substring query against title/summary/tags/path. Required (non-empty) when action=search."
707
+ )
708
+ };
709
+ var FabReviewInputShape = {
710
+ action: z3.enum(["approve", "reject", "modify", "modify-content", "modify-layer", "defer"]).describe(
711
+ "Action selector. Discriminates the per-action fields below; required. modify-content edits scalars (no layer); modify-layer is the layer-flip path (changes.layer required); modify is the legacy combined alias. (list/search moved to the read-only fab_pending tool.)"
712
+ ),
685
713
  pending_paths: z3.array(z3.string()).min(1).optional().describe(
686
714
  "Workspace-relative pending entry paths. Required when action=approve|reject|defer (non-empty array)."
687
715
  ),
@@ -694,9 +722,6 @@ var FabReviewInputShape = {
694
722
  changes: _fabReviewModifyChangesSchema.optional().describe(
695
723
  "Frontmatter scalar patches (title/summary/layer/maturity/tags/relevance_*/semantic_scope/related). Required when action=modify. semantic_scope re-scopes the entry's resolution coordinate in place (e.g. team \u2192 project:<id>) without moving stores; personal-root coordinates are rejected (use modify-layer)."
696
724
  ),
697
- query: z3.string().min(1).optional().describe(
698
- "Substring query against title/summary/tags/path. Required (non-empty) when action=search."
699
- ),
700
725
  until: z3.string().datetime().optional().describe(
701
726
  "ISO-8601 datetime upper bound for the deferral. Optional; used only when action=defer."
702
727
  )
@@ -757,11 +782,6 @@ var _fabReviewSearchItemSchema = z3.object({
757
782
  stable_id: z3.string().optional()
758
783
  });
759
784
  var FabReviewOutputSchema = z3.discriminatedUnion("action", [
760
- z3.object({
761
- action: z3.literal("list"),
762
- items: z3.array(_fabReviewListItemSchema),
763
- warnings: z3.array(structuredWarningSchema).optional()
764
- }),
765
785
  z3.object({
766
786
  action: z3.literal("approve"),
767
787
  approved: z3.array(z3.object({ pending_path: z3.string(), stable_id: z3.string() })),
@@ -781,25 +801,36 @@ var FabReviewOutputSchema = z3.discriminatedUnion("action", [
781
801
  warnings: z3.array(structuredWarningSchema).optional()
782
802
  }),
783
803
  z3.object({
784
- action: z3.literal("search"),
785
- // v2.0.0-rc.29 TASK-007 (BUG-M4): search returns the new search-item
786
- // shape with `area` discriminator + neutrally-named `path` field.
787
- items: z3.array(_fabReviewSearchItemSchema),
804
+ action: z3.literal("defer"),
805
+ deferred: z3.array(z3.string()),
806
+ warnings: z3.array(structuredWarningSchema).optional()
807
+ })
808
+ ]);
809
+ var FabPendingOutputSchema = z3.discriminatedUnion("action", [
810
+ z3.object({
811
+ action: z3.literal("list"),
812
+ items: z3.array(_fabReviewListItemSchema),
788
813
  warnings: z3.array(structuredWarningSchema).optional()
789
814
  }),
790
815
  z3.object({
791
- action: z3.literal("defer"),
792
- deferred: z3.array(z3.string()),
816
+ action: z3.literal("search"),
817
+ items: z3.array(_fabReviewSearchItemSchema),
793
818
  warnings: z3.array(structuredWarningSchema).optional()
794
819
  })
795
820
  ]);
796
- var FabReviewOutputShape = {
797
- action: z3.enum(["list", "approve", "reject", "modify", "search", "defer"]).describe(
821
+ var FabPendingOutputShape = {
822
+ action: z3.enum(["list", "search"]).describe(
798
823
  "Echoes the input action; clients can switch on it for per-variant fields below."
799
824
  ),
800
825
  items: z3.array(z3.union([_fabReviewListItemSchema, _fabReviewSearchItemSchema])).optional().describe(
801
826
  "Pending entries (action=list, `pending_path` shape) or pending+canonical entries (action=search, `area`+`path` shape)."
802
827
  ),
828
+ warnings: z3.array(structuredWarningSchema).optional()
829
+ };
830
+ var FabReviewOutputShape = {
831
+ action: z3.enum(["approve", "reject", "modify", "defer"]).describe(
832
+ "Echoes the input action; clients can switch on it for per-variant fields below. (list/search results moved to the read-only fab_pending tool.)"
833
+ ),
803
834
  approved: z3.array(z3.object({ pending_path: z3.string(), stable_id: z3.string() })).optional().describe(
804
835
  "Allocated stable ids paired with their original pending paths. Present when action=approve."
805
836
  ),
@@ -829,6 +860,13 @@ var fabReviewAnnotations = {
829
860
  openWorldHint: false,
830
861
  title: "Review pending knowledge entries"
831
862
  };
863
+ var fabPendingAnnotations = {
864
+ readOnlyHint: true,
865
+ idempotentHint: true,
866
+ destructiveHint: false,
867
+ openWorldHint: false,
868
+ title: "Browse and search pending knowledge entries"
869
+ };
832
870
  var citeContractMetricsSchema = z3.object({
833
871
  decisions_cited: z3.number().int().nonnegative(),
834
872
  pitfalls_cited: z3.number().int().nonnegative(),
@@ -1071,6 +1109,7 @@ export {
1071
1109
  PERSONAL_SCOPE,
1072
1110
  KNOWN_SCOPE_PREFIXES,
1073
1111
  SCOPE_COORDINATE_PATTERN,
1112
+ SCOPE_COORDINATE_HINT,
1074
1113
  scopeCoordinateSchema,
1075
1114
  scopeRoot,
1076
1115
  isPersonalScope,
@@ -1097,10 +1136,15 @@ export {
1097
1136
  FabExtractKnowledgeOutputSchema,
1098
1137
  fabExtractKnowledgeAnnotations,
1099
1138
  FabReviewInputSchema,
1139
+ FabPendingInputSchema,
1140
+ FabPendingInputShape,
1100
1141
  FabReviewInputShape,
1101
1142
  FabReviewOutputSchema,
1143
+ FabPendingOutputSchema,
1144
+ FabPendingOutputShape,
1102
1145
  FabReviewOutputShape,
1103
1146
  fabReviewAnnotations,
1147
+ fabPendingAnnotations,
1104
1148
  citeContractMetricsSchema,
1105
1149
  citeLayerTypeBreakdownSchema,
1106
1150
  citeCoverageReportSchema,