@passioncode-ai/fabric-agent-adapter 0.60.0 → 0.62.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 (56) hide show
  1. package/CHANGELOG.md +246 -0
  2. package/README.md +2 -1
  3. package/package.json +1 -1
  4. package/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
  5. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +4 -1
  6. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/provider-entry.md +4 -2
  7. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_provider.py +1 -1
  8. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_secrets.py +57 -0
  9. package/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +11 -9
  10. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/README.md +8 -1
  11. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/support_agent.py +19 -2
  12. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/board.md +58 -7
  13. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/connectors.md +4 -2
  14. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/delegation.md +2 -2
  15. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/estate-record.md +2 -0
  16. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/interop.md +23 -6
  17. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/kit-modules.md +1 -1
  18. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/lifecycle.md +4 -2
  19. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/migrating-a-service.md +6 -4
  20. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +4 -2
  21. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/remote-placement.md +16 -3
  22. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py +18 -2
  23. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service_rules.py +33 -3
  24. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-auth.mjs +10 -1
  25. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-board-link.mjs +117 -0
  26. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-board-session.mjs +24 -5
  27. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-board.mjs +1 -0
  28. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-delegation.mjs +3 -1
  29. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-descriptor.mjs +33 -3
  30. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-http.mjs +14 -2
  31. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop-rules.mjs +10 -0
  32. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop.mjs +14 -8
  33. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-lock.mjs +24 -4
  34. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-mandate.mjs +3 -0
  35. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-secrets.mjs +57 -0
  36. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-service.mjs +3 -0
  37. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_auth.py +16 -1
  38. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_board.py +1 -0
  39. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_board_link.py +146 -0
  40. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_board_session.py +20 -5
  41. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_descriptor.py +55 -4
  42. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_http.py +5 -0
  43. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop.py +33 -25
  44. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop_rules.py +19 -6
  45. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_jsvalue.py +23 -3
  46. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_lock.py +17 -3
  47. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_mandate.py +86 -7
  48. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_secrets.py +57 -0
  49. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_service.py +4 -0
  50. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/kit.json +217 -29
  51. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample-remote-service.mjs +2 -0
  52. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample_service.py +42 -4
  53. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +1 -1
  54. package/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +23 -23
  55. package/plugins/fabric-agent-adapter/skills/working-with-fabric/references/project-board.md +16 -1
  56. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_env.py +1 -1
@@ -185,3 +185,60 @@ def secret_url(value: str) -> bool:
185
185
  if any((raw != "" and credential_name(name)) or secret_value(raw) for raw in raws):
186
186
  return True
187
187
  return False
188
+
189
+
190
+ _REPOSITORY_URI = re.compile(r"\A([A-Za-z][A-Za-z0-9+.-]*:(?://[^/?#]*)?)([^?#]*)(.*)\Z", re.S)
191
+ _REPOSITORY_NAME = re.compile(r"(?:[a-z0-9._-]+|[A-Za-z._-]+)\Z") # lower case, or letters with no digit (readings 8)
192
+ _REPOSITORY_AUTHORITY = re.compile(r"[A-Za-z][A-Za-z0-9+.-]*://")
193
+ _KEY_AT_A_WORD = re.compile(r"(?:\A|(?<=[._-]))(?:%s)" % SECRET_VALUE.pattern, re.IGNORECASE | re.ASCII)
194
+ _JWT_AT_A_WORD = re.compile(r"(?:\A|(?<=[._-]))%s" % JWT_SHAPE.pattern)
195
+
196
+
197
+ def repository_name(piece: str) -> bool:
198
+ """Whether a path segment reads as a repository's name: lower case, or letters with no digit, with no provider
199
+ key's or JWT's shape (`sk-`, `ghp_`, `xoxb-`, `AKIA`, `eyJ`) at its start or after a `.`, `_` or `-` (0.62.0
200
+ readings 9 and 10), so a letters-only key is still a key while `task-pipeline-dashboard`, which holds an `sk-` shape
201
+ inside a word, is a name."""
202
+ return bool(_REPOSITORY_NAME.match(piece)) and not _KEY_AT_A_WORD.search(piece) and not _JWT_AT_A_WORD.search(piece)
203
+
204
+
205
+ def ascii_decoded(text: str) -> str:
206
+ """Every `%XX` escape of an ASCII character decoded, the rest left as written: how a repository's path and user
207
+ information are read as well as written, since git and hosts decode them (`%73k-` is `sk-`, `u%3Apw` is `u:pw`;
208
+ 0.62.0 readings 11). The Node twin is asciiDecoded."""
209
+ return re.sub(r"%([0-7][0-9A-Fa-f])", lambda escape: chr(int(escape.group(1), 16)), text)
210
+
211
+
212
+ def repository_password(value: str) -> bool:
213
+ """Whether a repository URI's user information holds a password, in any scheme, `file` too: every slash and
214
+ backslash after the colon skipped, then up to the next `/`, `?` or `#`, a backslash kept in the user. That one
215
+ reading holds git's (`https://h\\u:pw@x/r`), curl's (`https:///h\\u:pw@x`) and the URL standard's
216
+ (`https:///u:pw@h`, which stops at a backslash, a prefix of it) (0.62.0 readings 10 to 14). The user information
217
+ ends at the last `@`; a password follows its first `:`, as written or ascii_decoded. The Node twin is
218
+ repositoryPassword."""
219
+ value = re.sub(r"[\t\n\r]", "", value.strip(_C0_OR_SPACE))
220
+ scheme, colon, rest = value.partition(":")
221
+ authorities = [re.match(r"[^/?#]*", rest.lstrip("/\\")).group(0)] if colon else []
222
+ users = [authority.rpartition("@")[0] for authority in authorities]
223
+ return any(user.partition(":")[2] for user in users + [ascii_decoded(user) for user in users])
224
+
225
+
226
+ def repository_credential(value: str) -> bool:
227
+ """FAA-198 (0.62.0 readings 6 and 7): whether a repository URI carries a credential: in its scheme and authority (a
228
+ user), in its query or fragment as secret_url reads them, or as a path segment shaped like a key. A path segment in
229
+ lower case, or of letters with no digit (task-pipeline-dashboard, Task-Pipeline-Dashboard), is the repository's
230
+ name, never a key, though it reads as an `sk-` shape, unless a key's shape starts it or follows a `.`, `_` or `-` in
231
+ it (repository_name); a segment is read as written and ascii_decoded. A
232
+ user outside a URL's authority (an scp form, `https:user@host/path`) counts as one: a user is an authority's."""
233
+ if "@" in value and not _REPOSITORY_AUTHORITY.match(value):
234
+ return True
235
+ match = _REPOSITORY_URI.match(value)
236
+ if not match:
237
+ return secret_argument(value)
238
+ head, path, tail = match.groups()
239
+ if repository_password(value):
240
+ return True
241
+ odd = [piece for written in (path, ascii_decoded(path)) for piece in re.split(r"[/\\:]", written)
242
+ if piece and not repository_name(piece)]
243
+ # the scheme and authority decoded too: git sends `https://%67hp_...@h` with its user decoded (unit reading 12)
244
+ return secret_url(head + tail) or secret_argument(ascii_decoded(head)) or any(secret_argument(piece) for piece in odd)
@@ -231,6 +231,10 @@ from fabric_descriptor import ( # noqa: F401
231
231
  placement_of,
232
232
  remote_origin_problems,
233
233
  port_of,
234
+ NO_SOURCE_REPOSITORY,
235
+ NoSourceRepositoryWarning,
236
+ names_repository,
237
+ source_refusal,
234
238
  write_descriptor,
235
239
  remove_descriptor,
236
240
  build_info,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fabric-service-kit",
3
- "version": "0.60.0",
3
+ "version": "0.62.0",
4
4
  "about": "The service kit's modules in dependency order: a module imports only modules listed before it. Written by fabric_kit.py build; edit the order and layers by hand, never the digests.",
5
5
  "python": [
6
6
  {
@@ -8,7 +8,7 @@
8
8
  "file": "fabric_jsvalue.py",
9
9
  "layer": "L0",
10
10
  "imports": [],
11
- "sha256": "12888a2c934a885d35999ac9782eaedc8d04946d9775213344a235a8814d3d28"
11
+ "sha256": "052f1b40bab18600b3731dbdca27cbff17588c21d9458fa6241efd1340d0e09a"
12
12
  },
13
13
  {
14
14
  "module": "fabric_time",
@@ -31,7 +31,7 @@
31
31
  "file": "fabric_secrets.py",
32
32
  "layer": "L0",
33
33
  "imports": [],
34
- "sha256": "1d0191f0ec108fdc68345056b8c574b1f691509d1c353e41d98bfd58a59e8d3c"
34
+ "sha256": "3939aa8658a92ca387e9f0259538c4849fc407e429355ef9b4829460107a8597"
35
35
  },
36
36
  {
37
37
  "module": "fabric_crypto",
@@ -100,7 +100,7 @@
100
100
  "fabric_jsvalue",
101
101
  "fabric_time"
102
102
  ],
103
- "sha256": "050c43d0166a7dfba82e29c4e978f05c364cf6da06d0a781bd023a566777c17b"
103
+ "sha256": "fb19ce5359606bd6e3352ab02b2a12f49605ec6e5c49b55cce1f79c831325044"
104
104
  },
105
105
  {
106
106
  "module": "fabric_delegation",
@@ -230,7 +230,7 @@
230
230
  "fabric_paths",
231
231
  "fabric_platform"
232
232
  ],
233
- "sha256": "ba2399d2137c7a7791b7133b9db9cca36693f4eb7e30955b25a75ade814e95ba"
233
+ "sha256": "dfaf92a7086cbb097d832a305869b7964e2d2a9da0e3365c8ec1685a7bb4fef9"
234
234
  },
235
235
  {
236
236
  "module": "fabric_usage",
@@ -270,7 +270,7 @@
270
270
  "fabric_secrets",
271
271
  "fabric_usage"
272
272
  ],
273
- "sha256": "a6d7a4a38186f7ef527d16218bbf96e39e255f9547be668adcfbec063dabb7ed"
273
+ "sha256": "0e7b44eef7983c2dffc433173c4e376facb181279d4bfdffa9ae8028216984c0"
274
274
  },
275
275
  {
276
276
  "module": "fabric_context",
@@ -297,7 +297,7 @@
297
297
  "fabric_paths",
298
298
  "fabric_platform"
299
299
  ],
300
- "sha256": "71115d18c67b7b806cb57b64b77e01ad97fc0e63e6f49ee850f778123617d905"
300
+ "sha256": "a7028fa6f8b1c24bc9e2c89adbce8ecb0ae01579d27b1ec4f625ae635e3f17b9"
301
301
  },
302
302
  {
303
303
  "module": "fabric_events",
@@ -354,7 +354,7 @@
354
354
  "fabric_time",
355
355
  "fabric_usage"
356
356
  ],
357
- "sha256": "a2e813469a47d4d3eea996628635c8903007498bdb6a1ae032a7a5ce6f49fe2f"
357
+ "sha256": "4b13f90aa26881fbfe0d9f3077fbb3552f3ce0a3c59279d6baa92df872867d8d"
358
358
  },
359
359
  {
360
360
  "module": "fabric_profiles",
@@ -377,10 +377,11 @@
377
377
  "fabric_actions",
378
378
  "fabric_base",
379
379
  "fabric_delegation",
380
+ "fabric_jsvalue",
380
381
  "fabric_mandate",
381
382
  "fabric_time"
382
383
  ],
383
- "sha256": "82c079a4d9421ea2cd10c1dfa8e1c447b80d5e0dcc8d52d52415bf028e34c91e"
384
+ "sha256": "9bdb7989e57b9d0b0d15eb9982d396499823a5e2c528230b71c67866c736e0f5"
384
385
  },
385
386
  {
386
387
  "module": "fabric_interop",
@@ -391,12 +392,13 @@
391
392
  "fabric_base",
392
393
  "fabric_delegation",
393
394
  "fabric_interop_rules",
395
+ "fabric_jsvalue",
394
396
  "fabric_mandate",
395
397
  "fabric_page_links",
396
398
  "fabric_service",
397
399
  "fabric_time"
398
400
  ],
399
- "sha256": "8f7e43bf01fa5e969d7d819f4b0188b9acfd846f6f85a37ea139e550d61e4e6c"
401
+ "sha256": "d27e31834611a37cf2a117746f2f60fc187ccc48718eb546ff923c5d0fce7dea"
400
402
  },
401
403
  {
402
404
  "module": "fabric_hub",
@@ -424,9 +426,12 @@
424
426
  "imports": [
425
427
  "fabric_board_shapes",
426
428
  "fabric_hub",
427
- "fabric_service"
429
+ "fabric_interop_rules",
430
+ "fabric_mandate",
431
+ "fabric_service",
432
+ "fabric_time"
428
433
  ],
429
- "sha256": "e8d2310e5f53c75e4bf642c3d980b2faba692731eaf56ec245cea05446e38bef"
434
+ "sha256": "052bc3c474ece835bb428c37ca864810d04e394d991ddb9c93989a7a825073a5"
430
435
  },
431
436
  {
432
437
  "module": "fabric_board_slots",
@@ -448,7 +453,7 @@
448
453
  "fabric_hub",
449
454
  "fabric_service"
450
455
  ],
451
- "sha256": "9b299b578ce8b1e834afdbbdb54183281df064302417fe364067e97e9ac23979"
456
+ "sha256": "1fd3c3884f3044b56a40f78b33ff88dcac9272284f6681ea359c662879826f7e"
452
457
  },
453
458
  {
454
459
  "module": "fabric_board_fixture",
@@ -470,7 +475,7 @@
470
475
  "fabric_board_session",
471
476
  "fabric_board_shapes"
472
477
  ],
473
- "sha256": "34c1200860040aa61cdd35f911f70d34d64b4a5cd91f892328d1169e4a89d8cd"
478
+ "sha256": "f86c40b8291f8c818f6924910f4022b013d5fd107abaf8825dd0aa6c5e418638"
474
479
  },
475
480
  {
476
481
  "module": "fabric_http",
@@ -479,7 +484,7 @@
479
484
  "imports": [
480
485
  "fabric_jsvalue"
481
486
  ],
482
- "sha256": "80e22ae0bba91de13a94d64b595108b39c58f16f7b4137f3a48bdd9503f424fe"
487
+ "sha256": "861e8e0978e303455dd6ff4a1b98a8b258600320f2870af0644384196fb03679"
483
488
  },
484
489
  {
485
490
  "module": "fabric_openrouter",
@@ -520,7 +525,7 @@
520
525
  "file": "fabric-secrets.mjs",
521
526
  "layer": "L0",
522
527
  "imports": [],
523
- "sha256": "6ad8ab18ac899ecc2384e8ec6a3fb689b92be3b9a5ce3a59b92a37d52da5d766"
528
+ "sha256": "5822a7e25ecf2e87b5bab4f99c1074af7379d8b49e2784283b5d7d8c25022cde"
524
529
  },
525
530
  {
526
531
  "module": "fabric-crypto",
@@ -589,7 +594,7 @@
589
594
  "fabric-jsvalue",
590
595
  "fabric-time"
591
596
  ],
592
- "sha256": "deaab2bfb929d1bd35ae1bad71e7b9ad9902cc23b8eb51819ed592fd80eddf95"
597
+ "sha256": "b70f3de03a659e60bba7b5a0580b3582825cd7b8a8e30a28c79621919ec5b7bb"
593
598
  },
594
599
  {
595
600
  "module": "fabric-delegation",
@@ -602,7 +607,7 @@
602
607
  "fabric-mandate",
603
608
  "fabric-paths"
604
609
  ],
605
- "sha256": "04eaf6cd1786d4309a253a27dbdb05e27b408cb511aa41b1633a96634b775e65"
610
+ "sha256": "f1b6d156d050f8ceb9a21daaad8d39ab5de5d32e4cfe03817909388fca8ad27e"
606
611
  },
607
612
  {
608
613
  "module": "fabric-share",
@@ -716,7 +721,7 @@
716
721
  "fabric-base",
717
722
  "fabric-paths"
718
723
  ],
719
- "sha256": "ac219ab0a326d5c43c7c4c255e0c3843d4794de795a60e3af661e7d5350ea052"
724
+ "sha256": "02cf833c97a07a8b3c788f9c93f70c4b9c9066efa25318dccf0038e0fc79717f"
720
725
  },
721
726
  {
722
727
  "module": "fabric-usage",
@@ -757,7 +762,7 @@
757
762
  "fabric-secrets",
758
763
  "fabric-usage"
759
764
  ],
760
- "sha256": "243bbce42989f67c4c5ec6b7659e201b3f9a1c08c71d429d88ec934d870f5104"
765
+ "sha256": "7c0ef7d245c037eb9e859ab481f6e66fb3e5ef2cf6d1e0a8d32b6d303097ca43"
761
766
  },
762
767
  {
763
768
  "module": "fabric-context",
@@ -785,7 +790,7 @@
785
790
  "fabric-platform",
786
791
  "fabric-usage"
787
792
  ],
788
- "sha256": "782c2aa732f8320f604194660117640a7ea145e12b8155c04e88cef7c516a5b3"
793
+ "sha256": "10ff37a39f9e3adb4d0f05db66c45f49b10eef582e9220c213907964109d7e52"
789
794
  },
790
795
  {
791
796
  "module": "fabric-events",
@@ -840,7 +845,7 @@
840
845
  "fabric-supervisors",
841
846
  "fabric-usage"
842
847
  ],
843
- "sha256": "6aa673657427211b491a9b63f94b9847a7e6aa3ee1b7353e1af11f46469803a3"
848
+ "sha256": "297fef11ac76dc831d12d24c5581b7a93587c300c20664db703b3f924c0f9f1a"
844
849
  },
845
850
  {
846
851
  "module": "fabric-profiles",
@@ -865,7 +870,7 @@
865
870
  "fabric-jsvalue",
866
871
  "fabric-mandate"
867
872
  ],
868
- "sha256": "e4f8b133138e27353a7976c0360bd1653c90daed43b3f843f85a19f14f5e9221"
873
+ "sha256": "b4e386c359a48e49ffff8a842215760c18a7c98a0af4754a808a35fb2820d458"
869
874
  },
870
875
  {
871
876
  "module": "fabric-interop",
@@ -878,7 +883,7 @@
878
883
  "fabric-page-links",
879
884
  "fabric-service"
880
885
  ],
881
- "sha256": "ee7e6d32be1f42e6d21a943b8886652352408c49c6404d9749b8a02dc3901e92"
886
+ "sha256": "989040aed33b2712a258244192bdf70e811a51076aa1b62f2adc2a6db051dbed"
882
887
  },
883
888
  {
884
889
  "module": "fabric-hub",
@@ -906,9 +911,12 @@
906
911
  "imports": [
907
912
  "fabric-board-shapes",
908
913
  "fabric-hub",
909
- "fabric-service"
914
+ "fabric-interop-rules",
915
+ "fabric-mandate",
916
+ "fabric-service",
917
+ "fabric-time"
910
918
  ],
911
- "sha256": "b1ac329b65b679193b94b81fe735922e14427ed540ba910b1a815ce3447e3220"
919
+ "sha256": "6e7d51f4fd9730d93455f50dd30e97907b8b9e1ca65a1d69f036f2e8ec05cc0d"
912
920
  },
913
921
  {
914
922
  "module": "fabric-board-slots",
@@ -930,7 +938,7 @@
930
938
  "fabric-hub",
931
939
  "fabric-service"
932
940
  ],
933
- "sha256": "b81e74397fbae655183fc0dabb8d7406c9c5e9b6e02d893e046aa3521a3a8619"
941
+ "sha256": "18555962e5f6d18080a3e7971c4c6640452542f6042d07917e7ebc073721c415"
934
942
  },
935
943
  {
936
944
  "module": "fabric-board-fixture",
@@ -952,14 +960,14 @@
952
960
  "fabric-board-session",
953
961
  "fabric-board-shapes"
954
962
  ],
955
- "sha256": "0d75c3e27a0b791bdbc35b2e93b3299e5831d3ab3003ce441e6268397e32b448"
963
+ "sha256": "15fbb4441fcf7d2f285375b75de64ad6cffea129c515084c110245376b07775f"
956
964
  },
957
965
  {
958
966
  "module": "fabric-http",
959
967
  "file": "fabric-http.mjs",
960
968
  "layer": "L4",
961
969
  "imports": [],
962
- "sha256": "9f899829073470b9c2b449605a9371b773848eec4e3a0122ed4ccde5eddcdb4b"
970
+ "sha256": "96aa1730c79cb9a68dcc94642513eb1e88f0c2d99a45ca505c042e8c601d0436"
963
971
  },
964
972
  {
965
973
  "module": "fabric-openrouter",
@@ -4588,6 +4596,186 @@
4588
4596
  "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4589
4597
  "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4590
4598
  "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4599
+ },
4600
+ "0.61.0": {
4601
+ "fabric_jsvalue.py": "052f1b40bab18600b3731dbdca27cbff17588c21d9458fa6241efd1340d0e09a",
4602
+ "fabric_time.py": "588f383da4ac6a243ea95b6ffc3a0aa99ca94245732dc4937734f190b7af4ae9",
4603
+ "fabric_identifiers.py": "0fd814d521ac3aa39907458265870753046a73f48af3d8581ab864b93b211607",
4604
+ "fabric_secrets.py": "1d0191f0ec108fdc68345056b8c574b1f691509d1c353e41d98bfd58a59e8d3c",
4605
+ "fabric_crypto.py": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa",
4606
+ "fabric_base.py": "f62bcc2ed9912660fa875d27a09f60867260cc4925f79873501fd9620be59611",
4607
+ "fabric_platform.py": "a9350dff55ef0fb3a23cdb4d0320a15868b15a8deb10d2eb74d72c58740c284b",
4608
+ "fabric_paths.py": "8a1ee742f80f436e9f28c61b4f049a9545de2a9e0d66bfc61faa6ee5d1ba3734",
4609
+ "fabric_estate_rules.py": "8b36a7f4108d9c2b1fb38c8bff344778c807bed631a99b4a563ecb0a49c10b1c",
4610
+ "fabric_estate.py": "b3cd56dcb86e04d252980322ac8054da1aaef24ac64690f7aa80e7c765ee6f60",
4611
+ "fabric_mandate.py": "fb19ce5359606bd6e3352ab02b2a12f49605ec6e5c49b55cce1f79c831325044",
4612
+ "fabric_delegation.py": "716f0ff7ac01095f54b24970beac1962128e8ff33026b243fc0467876142ab03",
4613
+ "fabric_share.py": "da36a466426fc29dd7dd40013167f3959a18375f8fedd228bf64f298cec1040c",
4614
+ "fabric_ceremonies.py": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f",
4615
+ "fabric_package_schema.py": "e623f0408d38e3343ed66222fb812907c6c52e1a286eb1c1176ab2e64640c9ad",
4616
+ "fabric_package.py": "1f2b9e73b2b32a7e1e887d4b69f87c6e21b4d1227ad924a235334223e6dd51ca",
4617
+ "fabric_protocols.py": "42529a7df4d753544d2e37a18ec81266d6e1e80477cb8558a3ab521416d45791",
4618
+ "fabric_actions.py": "ae21d1199614c4f74d1dcd1e0a87107a9d52434cd9e2d64aa24a7b1e196fb723",
4619
+ "fabric_connections.py": "7de55cb7d808f756d650effabfaa12027d40a5bd5d2f6d448c32969d47529ecb",
4620
+ "fabric_a2a.py": "8b01502131215bb4de1c01866187c56e99b791543923ed8577535573db33b919",
4621
+ "fabric_page_links.py": "1b57ea573c550e2f90d1ec3edcc655917ceaa0db9dd1635fccf422ec3024d25e",
4622
+ "fabric_lock.py": "dfaf92a7086cbb097d832a305869b7964e2d2a9da0e3365c8ec1685a7bb4fef9",
4623
+ "fabric_usage.py": "5cc2e03ccc5b06e81987ed7bc3eead7a7e6cbf1a7cb8e05c6c64315eed9d91b6",
4624
+ "fabric_backups.py": "1f3f0d7ecf361b29e9101e07f1c53e5dc304d598bf26fd59ec89f16b9fed2420",
4625
+ "fabric_descriptor.py": "a6d7a4a38186f7ef527d16218bbf96e39e255f9547be668adcfbec063dabb7ed",
4626
+ "fabric_context.py": "6ae311ddc7217a4aff915e7ce2646486931acd128462b7bebe4a52bbb5fbb6c7",
4627
+ "fabric_auth.py": "71115d18c67b7b806cb57b64b77e01ad97fc0e63e6f49ee850f778123617d905",
4628
+ "fabric_events.py": "cd94b186e2a8f8cb4ad2b6bd44d83ec5021933075e28c5d655f387f16dff42b8",
4629
+ "fabric_logs.py": "86dc55bfafa2a57264722e2403510a249b95de0e4a722b2e4bc3948e3bd93da9",
4630
+ "fabric_supervisors.py": "3c5b2e8c310738720b1c1b779be4710e90251013d9be4c68f9952edc0bf55d5f",
4631
+ "fabric_service.py": "a2e813469a47d4d3eea996628635c8903007498bdb6a1ae032a7a5ce6f49fe2f",
4632
+ "fabric_profiles.py": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b",
4633
+ "fabric_interop_rules.py": "9bdb7989e57b9d0b0d15eb9982d396499823a5e2c528230b71c67866c736e0f5",
4634
+ "fabric_interop.py": "d27e31834611a37cf2a117746f2f60fc187ccc48718eb546ff923c5d0fce7dea",
4635
+ "fabric_hub.py": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a",
4636
+ "fabric_board_shapes.py": "0a0e8d3d40e33dfd8c457aedb85330b2ff25f8c49a33eb6cbd5a5cc8a5007f7e",
4637
+ "fabric_board_link.py": "052bc3c474ece835bb428c37ca864810d04e394d991ddb9c93989a7a825073a5",
4638
+ "fabric_board_slots.py": "92b065e3df935547cf46653245f1129e4a1f8b59b0a41e8fa9ffdc41596ee592",
4639
+ "fabric_board_session.py": "1fd3c3884f3044b56a40f78b33ff88dcac9272284f6681ea359c662879826f7e",
4640
+ "fabric_board_fixture.py": "69761ce205ec640762ec9b591c6903e5a87f844e8d423b041681924027e39d1e",
4641
+ "fabric_board.py": "f86c40b8291f8c818f6924910f4022b013d5fd107abaf8825dd0aa6c5e418638",
4642
+ "fabric_http.py": "80e22ae0bba91de13a94d64b595108b39c58f16f7b4137f3a48bdd9503f424fe",
4643
+ "fabric_openrouter.py": "d06a40f83f2fb8bd441ab3485ae882f1fbdd9cd7a9c1ec175eb47cb8ae2cce81",
4644
+ "fabric-jsvalue.mjs": "dfbdb8c41584972c9389750a41719374a1cfc5652ed438dd1623025190b0106e",
4645
+ "fabric-time.mjs": "3ff932069038a720df1c68c6492976906737b2e67e5c12d9c81c418597f661de",
4646
+ "fabric-identifiers.mjs": "a18c2a501a4aa170bfd3d99e571ad6b7662649b4d3b9d2a540c002ea42811bbf",
4647
+ "fabric-secrets.mjs": "6ad8ab18ac899ecc2384e8ec6a3fb689b92be3b9a5ce3a59b92a37d52da5d766",
4648
+ "fabric-crypto.mjs": "038e03689701e3c9721a1e7f8e0a4d02a52d6a5d1661b0dc84035edc3ebbfcf6",
4649
+ "fabric-base.mjs": "7804b2df7715dbbf9702a9b61b6b8cef2110f9a52b04cabd8fb0a66458d87512",
4650
+ "fabric-platform.mjs": "a8119d95ebba4d589a9e401f5d6fc8dda62d59d44e4c1ff811d97fac3771ac0c",
4651
+ "fabric-paths.mjs": "aa630d611e748a899e7043480f4a4e46b444f2e15ff945f30c2fbef21c1ceea5",
4652
+ "fabric-estate-rules.mjs": "7476be71174aa5b1026134f2b335abf647feaa55584e2f9de8618e3054aa8e1e",
4653
+ "fabric-estate.mjs": "e8a2e62d2313121e6cb502f6e6abad94d1d546a44b4d9b3ce2be29e7808e8cf3",
4654
+ "fabric-mandate.mjs": "b70f3de03a659e60bba7b5a0580b3582825cd7b8a8e30a28c79621919ec5b7bb",
4655
+ "fabric-delegation.mjs": "04eaf6cd1786d4309a253a27dbdb05e27b408cb511aa41b1633a96634b775e65",
4656
+ "fabric-share.mjs": "bfb26581c21ad984c2a337da02429f9f3a165cc582f8ba48de4d3dfb7d163a59",
4657
+ "fabric-ceremonies.mjs": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44",
4658
+ "fabric-package-schema.mjs": "cd28092375db0fc21ffab1f0bb7794f7f8979ee08c64d3b9faf4b3845357caa6",
4659
+ "fabric-package.mjs": "8cfb32eebbd4e1bcf28a6e4437344ae2dd54479b0e7c820f002e9f94ab9ecaad",
4660
+ "fabric-protocols.mjs": "5fd8765fdd3e507cc85c108492682bf5cbb4ae08873245c50374fb01d33c75e4",
4661
+ "fabric-actions.mjs": "06e42f5e24c96311d5417d0d1effa93479ef7128a7ab139903b2bcf59253f6be",
4662
+ "fabric-connections.mjs": "303432e547ce563e90ca9ffcd827f5612f51d3582929834e1add0fdaf6485dcc",
4663
+ "fabric-a2a.mjs": "51b72fe1d80649d659fcad3a8f96370db3476c4a7b30cbabd8522c138be69346",
4664
+ "fabric-page-links.mjs": "a8834926e9d4bbf7c4857f551451d2ebf6ac8873bbccaaf89c5e30cf45b17ee6",
4665
+ "fabric-lock.mjs": "02cf833c97a07a8b3c788f9c93f70c4b9c9066efa25318dccf0038e0fc79717f",
4666
+ "fabric-usage.mjs": "1c4d18004639409624ac3516a02f2b60bbf55abdb612e9a96c37e83666eb87a7",
4667
+ "fabric-backups.mjs": "cfd8c9085e3d597a783099c2bd2ffe2f3faa0daaadab46dedd30523894cfeb06",
4668
+ "fabric-descriptor.mjs": "243bbce42989f67c4c5ec6b7659e201b3f9a1c08c71d429d88ec934d870f5104",
4669
+ "fabric-context.mjs": "1112d695e872f9825cbc94f08484974bff3880087bc29b8be59f885f03e8f7be",
4670
+ "fabric-auth.mjs": "782c2aa732f8320f604194660117640a7ea145e12b8155c04e88cef7c516a5b3",
4671
+ "fabric-events.mjs": "c463d6ffcae24229a5c608d8fcea4268d2ccc5024b19fa10e5a452284068fa71",
4672
+ "fabric-logs.mjs": "58467e5719c16e099d05bbedec47a95712506ab03c33f3cd4be1252e8498a946",
4673
+ "fabric-supervisors.mjs": "d45c38de0cb3ed85e083496c2d3c51dab004454accdd87f4762a512a6d442573",
4674
+ "fabric-service.mjs": "6aa673657427211b491a9b63f94b9847a7e6aa3ee1b7353e1af11f46469803a3",
4675
+ "fabric-profiles.mjs": "314376cf2deb87f235fb18b11d3b532e211f585b9af0a9302b5f4cc39971b532",
4676
+ "fabric-interop-rules.mjs": "b4e386c359a48e49ffff8a842215760c18a7c98a0af4754a808a35fb2820d458",
4677
+ "fabric-interop.mjs": "989040aed33b2712a258244192bdf70e811a51076aa1b62f2adc2a6db051dbed",
4678
+ "fabric-hub.mjs": "c005115a864cfd67daa4862097bb14acfe5a60bf653897e5bf8a570dd80f1070",
4679
+ "fabric-board-shapes.mjs": "c1db7b7bd0d58d82bb6d8dfbc3cd1547a256a333052d367e82ff1b3edf2804d7",
4680
+ "fabric-board-link.mjs": "6e7d51f4fd9730d93455f50dd30e97907b8b9e1ca65a1d69f036f2e8ec05cc0d",
4681
+ "fabric-board-slots.mjs": "fc77a3c6e62aa18575568bef4f703cce2edaba8cef648813ebcdbb21bdc27a11",
4682
+ "fabric-board-session.mjs": "18555962e5f6d18080a3e7971c4c6640452542f6042d07917e7ebc073721c415",
4683
+ "fabric-board-fixture.mjs": "83c4b7e33ee47b68385faf2569d38d5c8a0c5cb0f8656090f41e1b0eed2f436e",
4684
+ "fabric-board.mjs": "15fbb4441fcf7d2f285375b75de64ad6cffea129c515084c110245376b07775f",
4685
+ "fabric-http.mjs": "9f899829073470b9c2b449605a9371b773848eec4e3a0122ed4ccde5eddcdb4b",
4686
+ "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4687
+ "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4688
+ "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4689
+ },
4690
+ "0.62.0": {
4691
+ "fabric_jsvalue.py": "052f1b40bab18600b3731dbdca27cbff17588c21d9458fa6241efd1340d0e09a",
4692
+ "fabric_time.py": "588f383da4ac6a243ea95b6ffc3a0aa99ca94245732dc4937734f190b7af4ae9",
4693
+ "fabric_identifiers.py": "0fd814d521ac3aa39907458265870753046a73f48af3d8581ab864b93b211607",
4694
+ "fabric_secrets.py": "3939aa8658a92ca387e9f0259538c4849fc407e429355ef9b4829460107a8597",
4695
+ "fabric_crypto.py": "9c34aee20dbe4d6742e4fdbaab68ceb934bbe7dbd3a904c0010824ace16cdeaa",
4696
+ "fabric_base.py": "f62bcc2ed9912660fa875d27a09f60867260cc4925f79873501fd9620be59611",
4697
+ "fabric_platform.py": "a9350dff55ef0fb3a23cdb4d0320a15868b15a8deb10d2eb74d72c58740c284b",
4698
+ "fabric_paths.py": "8a1ee742f80f436e9f28c61b4f049a9545de2a9e0d66bfc61faa6ee5d1ba3734",
4699
+ "fabric_estate_rules.py": "8b36a7f4108d9c2b1fb38c8bff344778c807bed631a99b4a563ecb0a49c10b1c",
4700
+ "fabric_estate.py": "b3cd56dcb86e04d252980322ac8054da1aaef24ac64690f7aa80e7c765ee6f60",
4701
+ "fabric_mandate.py": "fb19ce5359606bd6e3352ab02b2a12f49605ec6e5c49b55cce1f79c831325044",
4702
+ "fabric_delegation.py": "716f0ff7ac01095f54b24970beac1962128e8ff33026b243fc0467876142ab03",
4703
+ "fabric_share.py": "da36a466426fc29dd7dd40013167f3959a18375f8fedd228bf64f298cec1040c",
4704
+ "fabric_ceremonies.py": "a59e83cf4adb2669a9b98008e3d3a0cba991a35cbff97bc604fc82fe81cfd49f",
4705
+ "fabric_package_schema.py": "e623f0408d38e3343ed66222fb812907c6c52e1a286eb1c1176ab2e64640c9ad",
4706
+ "fabric_package.py": "1f2b9e73b2b32a7e1e887d4b69f87c6e21b4d1227ad924a235334223e6dd51ca",
4707
+ "fabric_protocols.py": "42529a7df4d753544d2e37a18ec81266d6e1e80477cb8558a3ab521416d45791",
4708
+ "fabric_actions.py": "ae21d1199614c4f74d1dcd1e0a87107a9d52434cd9e2d64aa24a7b1e196fb723",
4709
+ "fabric_connections.py": "7de55cb7d808f756d650effabfaa12027d40a5bd5d2f6d448c32969d47529ecb",
4710
+ "fabric_a2a.py": "8b01502131215bb4de1c01866187c56e99b791543923ed8577535573db33b919",
4711
+ "fabric_page_links.py": "1b57ea573c550e2f90d1ec3edcc655917ceaa0db9dd1635fccf422ec3024d25e",
4712
+ "fabric_lock.py": "dfaf92a7086cbb097d832a305869b7964e2d2a9da0e3365c8ec1685a7bb4fef9",
4713
+ "fabric_usage.py": "5cc2e03ccc5b06e81987ed7bc3eead7a7e6cbf1a7cb8e05c6c64315eed9d91b6",
4714
+ "fabric_backups.py": "1f3f0d7ecf361b29e9101e07f1c53e5dc304d598bf26fd59ec89f16b9fed2420",
4715
+ "fabric_descriptor.py": "0e7b44eef7983c2dffc433173c4e376facb181279d4bfdffa9ae8028216984c0",
4716
+ "fabric_context.py": "6ae311ddc7217a4aff915e7ce2646486931acd128462b7bebe4a52bbb5fbb6c7",
4717
+ "fabric_auth.py": "a7028fa6f8b1c24bc9e2c89adbce8ecb0ae01579d27b1ec4f625ae635e3f17b9",
4718
+ "fabric_events.py": "cd94b186e2a8f8cb4ad2b6bd44d83ec5021933075e28c5d655f387f16dff42b8",
4719
+ "fabric_logs.py": "86dc55bfafa2a57264722e2403510a249b95de0e4a722b2e4bc3948e3bd93da9",
4720
+ "fabric_supervisors.py": "3c5b2e8c310738720b1c1b779be4710e90251013d9be4c68f9952edc0bf55d5f",
4721
+ "fabric_service.py": "4b13f90aa26881fbfe0d9f3077fbb3552f3ce0a3c59279d6baa92df872867d8d",
4722
+ "fabric_profiles.py": "26e21ec29c016000f8ca8053b7b489184854a73be1b7fdc0a18d12990203db9b",
4723
+ "fabric_interop_rules.py": "9bdb7989e57b9d0b0d15eb9982d396499823a5e2c528230b71c67866c736e0f5",
4724
+ "fabric_interop.py": "d27e31834611a37cf2a117746f2f60fc187ccc48718eb546ff923c5d0fce7dea",
4725
+ "fabric_hub.py": "b9ac852e601b1d54cf61351677a628afc69faeed7d1fc74ebe541c1cf38e0c2a",
4726
+ "fabric_board_shapes.py": "0a0e8d3d40e33dfd8c457aedb85330b2ff25f8c49a33eb6cbd5a5cc8a5007f7e",
4727
+ "fabric_board_link.py": "052bc3c474ece835bb428c37ca864810d04e394d991ddb9c93989a7a825073a5",
4728
+ "fabric_board_slots.py": "92b065e3df935547cf46653245f1129e4a1f8b59b0a41e8fa9ffdc41596ee592",
4729
+ "fabric_board_session.py": "1fd3c3884f3044b56a40f78b33ff88dcac9272284f6681ea359c662879826f7e",
4730
+ "fabric_board_fixture.py": "69761ce205ec640762ec9b591c6903e5a87f844e8d423b041681924027e39d1e",
4731
+ "fabric_board.py": "f86c40b8291f8c818f6924910f4022b013d5fd107abaf8825dd0aa6c5e418638",
4732
+ "fabric_http.py": "861e8e0978e303455dd6ff4a1b98a8b258600320f2870af0644384196fb03679",
4733
+ "fabric_openrouter.py": "d06a40f83f2fb8bd441ab3485ae882f1fbdd9cd7a9c1ec175eb47cb8ae2cce81",
4734
+ "fabric-jsvalue.mjs": "dfbdb8c41584972c9389750a41719374a1cfc5652ed438dd1623025190b0106e",
4735
+ "fabric-time.mjs": "3ff932069038a720df1c68c6492976906737b2e67e5c12d9c81c418597f661de",
4736
+ "fabric-identifiers.mjs": "a18c2a501a4aa170bfd3d99e571ad6b7662649b4d3b9d2a540c002ea42811bbf",
4737
+ "fabric-secrets.mjs": "5822a7e25ecf2e87b5bab4f99c1074af7379d8b49e2784283b5d7d8c25022cde",
4738
+ "fabric-crypto.mjs": "038e03689701e3c9721a1e7f8e0a4d02a52d6a5d1661b0dc84035edc3ebbfcf6",
4739
+ "fabric-base.mjs": "7804b2df7715dbbf9702a9b61b6b8cef2110f9a52b04cabd8fb0a66458d87512",
4740
+ "fabric-platform.mjs": "a8119d95ebba4d589a9e401f5d6fc8dda62d59d44e4c1ff811d97fac3771ac0c",
4741
+ "fabric-paths.mjs": "aa630d611e748a899e7043480f4a4e46b444f2e15ff945f30c2fbef21c1ceea5",
4742
+ "fabric-estate-rules.mjs": "7476be71174aa5b1026134f2b335abf647feaa55584e2f9de8618e3054aa8e1e",
4743
+ "fabric-estate.mjs": "e8a2e62d2313121e6cb502f6e6abad94d1d546a44b4d9b3ce2be29e7808e8cf3",
4744
+ "fabric-mandate.mjs": "b70f3de03a659e60bba7b5a0580b3582825cd7b8a8e30a28c79621919ec5b7bb",
4745
+ "fabric-delegation.mjs": "f1b6d156d050f8ceb9a21daaad8d39ab5de5d32e4cfe03817909388fca8ad27e",
4746
+ "fabric-share.mjs": "bfb26581c21ad984c2a337da02429f9f3a165cc582f8ba48de4d3dfb7d163a59",
4747
+ "fabric-ceremonies.mjs": "117d4374c9e95c930a38de7adbd4323774798f4fe6ec6f24afcd6f2c7298ca44",
4748
+ "fabric-package-schema.mjs": "cd28092375db0fc21ffab1f0bb7794f7f8979ee08c64d3b9faf4b3845357caa6",
4749
+ "fabric-package.mjs": "8cfb32eebbd4e1bcf28a6e4437344ae2dd54479b0e7c820f002e9f94ab9ecaad",
4750
+ "fabric-protocols.mjs": "5fd8765fdd3e507cc85c108492682bf5cbb4ae08873245c50374fb01d33c75e4",
4751
+ "fabric-actions.mjs": "06e42f5e24c96311d5417d0d1effa93479ef7128a7ab139903b2bcf59253f6be",
4752
+ "fabric-connections.mjs": "303432e547ce563e90ca9ffcd827f5612f51d3582929834e1add0fdaf6485dcc",
4753
+ "fabric-a2a.mjs": "51b72fe1d80649d659fcad3a8f96370db3476c4a7b30cbabd8522c138be69346",
4754
+ "fabric-page-links.mjs": "a8834926e9d4bbf7c4857f551451d2ebf6ac8873bbccaaf89c5e30cf45b17ee6",
4755
+ "fabric-lock.mjs": "02cf833c97a07a8b3c788f9c93f70c4b9c9066efa25318dccf0038e0fc79717f",
4756
+ "fabric-usage.mjs": "1c4d18004639409624ac3516a02f2b60bbf55abdb612e9a96c37e83666eb87a7",
4757
+ "fabric-backups.mjs": "cfd8c9085e3d597a783099c2bd2ffe2f3faa0daaadab46dedd30523894cfeb06",
4758
+ "fabric-descriptor.mjs": "7c0ef7d245c037eb9e859ab481f6e66fb3e5ef2cf6d1e0a8d32b6d303097ca43",
4759
+ "fabric-context.mjs": "1112d695e872f9825cbc94f08484974bff3880087bc29b8be59f885f03e8f7be",
4760
+ "fabric-auth.mjs": "10ff37a39f9e3adb4d0f05db66c45f49b10eef582e9220c213907964109d7e52",
4761
+ "fabric-events.mjs": "c463d6ffcae24229a5c608d8fcea4268d2ccc5024b19fa10e5a452284068fa71",
4762
+ "fabric-logs.mjs": "58467e5719c16e099d05bbedec47a95712506ab03c33f3cd4be1252e8498a946",
4763
+ "fabric-supervisors.mjs": "d45c38de0cb3ed85e083496c2d3c51dab004454accdd87f4762a512a6d442573",
4764
+ "fabric-service.mjs": "297fef11ac76dc831d12d24c5581b7a93587c300c20664db703b3f924c0f9f1a",
4765
+ "fabric-profiles.mjs": "314376cf2deb87f235fb18b11d3b532e211f585b9af0a9302b5f4cc39971b532",
4766
+ "fabric-interop-rules.mjs": "b4e386c359a48e49ffff8a842215760c18a7c98a0af4754a808a35fb2820d458",
4767
+ "fabric-interop.mjs": "989040aed33b2712a258244192bdf70e811a51076aa1b62f2adc2a6db051dbed",
4768
+ "fabric-hub.mjs": "c005115a864cfd67daa4862097bb14acfe5a60bf653897e5bf8a570dd80f1070",
4769
+ "fabric-board-shapes.mjs": "c1db7b7bd0d58d82bb6d8dfbc3cd1547a256a333052d367e82ff1b3edf2804d7",
4770
+ "fabric-board-link.mjs": "6e7d51f4fd9730d93455f50dd30e97907b8b9e1ca65a1d69f036f2e8ec05cc0d",
4771
+ "fabric-board-slots.mjs": "fc77a3c6e62aa18575568bef4f703cce2edaba8cef648813ebcdbb21bdc27a11",
4772
+ "fabric-board-session.mjs": "18555962e5f6d18080a3e7971c4c6640452542f6042d07917e7ebc073721c415",
4773
+ "fabric-board-fixture.mjs": "83c4b7e33ee47b68385faf2569d38d5c8a0c5cb0f8656090f41e1b0eed2f436e",
4774
+ "fabric-board.mjs": "15fbb4441fcf7d2f285375b75de64ad6cffea129c515084c110245376b07775f",
4775
+ "fabric-http.mjs": "96aa1730c79cb9a68dcc94642513eb1e88f0c2d99a45ca505c042e8c601d0436",
4776
+ "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4777
+ "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4778
+ "share-registration.schema.json": "34b3997eeaf936ebc861342a23045634a7c18c19f01d7ed4198310d81989f5b0"
4591
4779
  }
4592
4780
  },
4593
4781
  "data": {
@@ -52,6 +52,8 @@ function handler(req, res) {
52
52
  startedAt, status: 'ready', degraded: [],
53
53
  surfaces: { dashboard: { path: '/', login: true }, events: { path: '/fabric/v1/events' } },
54
54
  summary: [{ label: 'Jobs today', value: events.length }],
55
+ // FAA-199: it says what it uses; this example calls nothing outside itself, so the list is empty.
56
+ extensions: k.connectionsExtension([]),
55
57
  }));
56
58
  }
57
59
  if (req.method === 'GET' && url.pathname === '/fabric/v1/events') {
@@ -8,7 +8,7 @@ once, and `sample.draft` is a job that stops for a titled choice before it compl
8
8
  `register` also writes the service's manifest, which names this descriptor.
9
9
 
10
10
  sample_service.py serve --port 47190 --data-dir DIR [--id sample] [--instance default]
11
- sample_service.py register --port 47190 --data-dir DIR [--services-dir DIR]
11
+ sample_service.py register --port 47190 --data-dir DIR [--services-dir DIR] [--id ID] [--repository URI]
12
12
 
13
13
  Opt-in, off by default: `serve --board-project <Project uuid>` also answers that Project's `sample.echo` requests on
14
14
  Fabric's project board (fabric-project-comms/0.1, FAA-12b) with fabric_board.Responder, from a board.respond grant whose
@@ -40,6 +40,11 @@ import fabric_board as fbd # noqa: E402 - the board responder (opt-in)
40
40
  import fabric_hub as fhb # noqa: E402
41
41
 
42
42
  VERSION = "0.1.0"
43
+ SAMPLE_REPOSITORY = "https://github.com/passioncode-ai/fabric-agent-adapter" # where this sample is built from (FAA-198)
44
+ # FAA-199: what the sample uses, declared so a host draws its chain (DEC-0096): the template it drafts from, and the
45
+ # demo source `serve --degraded` marks failing (a degraded[].source naming an id is that connection failing).
46
+ CONNECTIONS = [{"id": "template", "kind": "model", "target": "sample-template", "purpose": "drafts the notes"},
47
+ {"id": "demo", "kind": "connector", "target": "demo", "purpose": "the source --degraded marks failing"}]
43
48
  # The dashboard is built from the dashboard kit (fabric-dashboard/0.1, DEC-0036) and declares it
44
49
  # in the well-known document only when the kit is there to serve.
45
50
  KIT_DIR = Path(__file__).resolve().parent.parent / "assets" / "dashboard-kit"
@@ -279,7 +284,8 @@ class Service:
279
284
  "mcp": {"path": "/mcp", "transport": "streamable-http", "capabilities": [c["name"] for c in CAPABILITIES]
280
285
  + ([TAKE_BACK["tool"]] if self.board is not None else [])},
281
286
  "usage": {"path": fs.USAGE_PATH}},
282
- extensions=fs.dashboard_extension() if (KIT_DIR / "fabric-dashboard.css").is_file() else None,
287
+ extensions=dict(fs.dashboard_extension() if (KIT_DIR / "fabric-dashboard.css").is_file() else {},
288
+ **fs.connections_extension(CONNECTIONS, degraded=self.degraded, states={"template": "ok"})),
283
289
  # DEC-0067: listed only when the board is on — a host pinned before DEC-0067 refuses the member.
284
290
  # DEC-0126 OA-7: a server serving a relayed action reads `source`, so it lists operator-source/1 too.
285
291
  protocols=self.mcp.well_known_protocols(["fabric-service/0.1", "fabric-project-comms/0.1"]) if self.board is not None else None,
@@ -540,7 +546,7 @@ def write_manifest(args: argparse.Namespace, data: Path, board: bool = False) ->
540
546
 
541
547
  def register(args: argparse.Namespace) -> int:
542
548
  data = Path(args.data_dir)
543
- manifest = write_manifest(args, data, board=bool(getattr(args, "board_project", None)))
549
+ manifest = data / "fabric-agent.json" # written below, once the descriptor is known to be accepted
544
550
  descriptor = {
545
551
  "protocol": fs.PROTOCOL, "id": args.id, "instance": args.instance, "name": args.name,
546
552
  "summary": "Sample fabric-service/0.1 service.",
@@ -550,11 +556,40 @@ def register(args: argparse.Namespace) -> int:
550
556
  else {"manager": "none"},
551
557
  "paths": {"data": str(data), "logs": []},
552
558
  "fabricManifest": str(manifest),
559
+ "source": {"repository": args.repository},
553
560
  # DEC-0061: who installed it, by role and never by name — a person runs this register command.
554
561
  "installedAt": fs.now_iso(), "installedBy": {"by": "person", "role": "operator", "tool": "sample_service.py register %s" % VERSION},
555
562
  }
563
+ # A refused descriptor leaves no manifest naming it (0.62.0 unit reading 1).
564
+ problems = fs.validate_descriptor(descriptor)
565
+ refusal = ("Descriptor is invalid: %s." % "; ".join(problems) if problems
566
+ else fs.source_refusal(descriptor, Path(args.services_dir) if args.services_dir else None))
567
+ if refusal:
568
+ print(refusal, file=sys.stderr)
569
+ return 1
570
+ services = Path(args.services_dir) if args.services_dir else None
571
+ installed = fs.descriptor_path(args.id, args.instance, services)
572
+ try: # what a failed rewrite puts back (unit reading 4)
573
+ old = installed.read_bytes() if installed.exists() else None
574
+ except OSError as exc: # one it could not put back is never replaced (product reading 5)
575
+ print("The installed descriptor %s cannot be read (%s); nothing was written." % (installed, exc.strerror or exc), file=sys.stderr)
576
+ return 1
556
577
  try:
557
- path = fs.write_descriptor(descriptor, Path(args.services_dir) if args.services_dir else None)
578
+ path = fs.write_descriptor(descriptor, services)
579
+ # After the descriptor, so a refusal of any kind (a port claim too) leaves no manifest naming it (unit reading 2);
580
+ # a manifest that cannot be written takes a new descriptor back with it (unit reading 3).
581
+ try:
582
+ write_manifest(args, data, board=bool(getattr(args, "board_project", None)))
583
+ except OSError as exc:
584
+ undo = ""
585
+ try:
586
+ if old is None:
587
+ fs.remove_descriptor(args.id, args.instance, services)
588
+ else:
589
+ fs.atomic_write(installed, old, 0o600) # its bytes, 0600 as every descriptor the kit writes
590
+ except OSError as again: # said in the same line, never a traceback (seam reading 5)
591
+ undo = "; %s could not be %s either: %s" % (installed, "removed" if old is None else "put back", again.strerror or again)
592
+ raise fs.ServiceError("The manifest %s cannot be written: %s%s." % (manifest, exc.strerror or exc, undo))
558
593
  except fs.ServiceError as exc:
559
594
  print(str(exc), file=sys.stderr)
560
595
  return 1
@@ -584,6 +619,9 @@ def build_parser() -> argparse.ArgumentParser:
584
619
  p.add_argument("--board-project", help="the Project the service will answer on the board: lists its take-back "
585
620
  "tool in the manifest (serve with the same --board-project)")
586
621
  p.add_argument("--services-dir")
622
+ # FAA-198: the repository its code is built from, which a new descriptor names; the sample's own by default.
623
+ # The descriptor runs this sample's code whatever --id names, so its repository is this one by default.
624
+ p.add_argument("--repository", default=SAMPLE_REPOSITORY, help="the repository its code is built from")
587
625
  p.add_argument("--label")
588
626
  p.add_argument("--plist")
589
627
  return parser
@@ -5,7 +5,7 @@ license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
5
5
  compatibility: Requires filesystem access and Python 3.9+. Exact schema checks additionally need git, Node.js, pnpm, and the pinned fabric-agent-contract checkout (a public repository). Works without those tools in an explicitly degraded structural-check mode. Ships in one plugin with adapting-projects-to-fabric, whose scripts it reuses.
6
6
  metadata:
7
7
  author: PassionCode.ai
8
- version: "0.60.0"
8
+ version: "0.62.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "3830a3353923e20f826d466610e1c479f120bec0"
11
11
  ---