@passioncode-ai/fabric-agent-adapter 0.61.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 (36) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/package.json +1 -1
  3. package/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
  4. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +4 -1
  5. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/provider-entry.md +4 -2
  6. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_provider.py +1 -1
  7. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_secrets.py +57 -0
  8. package/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +11 -9
  9. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/README.md +8 -1
  10. package/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/support_agent.py +19 -2
  11. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/connectors.md +4 -2
  12. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/delegation.md +2 -2
  13. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/estate-record.md +2 -0
  14. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/lifecycle.md +4 -2
  15. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/migrating-a-service.md +6 -4
  16. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +4 -2
  17. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/remote-placement.md +16 -3
  18. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py +18 -2
  19. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service_rules.py +33 -3
  20. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-auth.mjs +10 -1
  21. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-delegation.mjs +3 -1
  22. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-descriptor.mjs +33 -3
  23. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-http.mjs +14 -2
  24. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-secrets.mjs +57 -0
  25. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-service.mjs +3 -0
  26. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_auth.py +16 -1
  27. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_descriptor.py +55 -4
  28. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_http.py +5 -0
  29. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_secrets.py +57 -0
  30. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_service.py +4 -0
  31. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/kit.json +102 -12
  32. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample-remote-service.mjs +2 -0
  33. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample_service.py +42 -4
  34. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +1 -1
  35. package/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +1 -1
  36. package/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_env.py +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fabric-service-kit",
3
- "version": "0.61.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
  {
@@ -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",
@@ -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",
@@ -484,7 +484,7 @@
484
484
  "imports": [
485
485
  "fabric_jsvalue"
486
486
  ],
487
- "sha256": "80e22ae0bba91de13a94d64b595108b39c58f16f7b4137f3a48bdd9503f424fe"
487
+ "sha256": "861e8e0978e303455dd6ff4a1b98a8b258600320f2870af0644384196fb03679"
488
488
  },
489
489
  {
490
490
  "module": "fabric_openrouter",
@@ -525,7 +525,7 @@
525
525
  "file": "fabric-secrets.mjs",
526
526
  "layer": "L0",
527
527
  "imports": [],
528
- "sha256": "6ad8ab18ac899ecc2384e8ec6a3fb689b92be3b9a5ce3a59b92a37d52da5d766"
528
+ "sha256": "5822a7e25ecf2e87b5bab4f99c1074af7379d8b49e2784283b5d7d8c25022cde"
529
529
  },
530
530
  {
531
531
  "module": "fabric-crypto",
@@ -607,7 +607,7 @@
607
607
  "fabric-mandate",
608
608
  "fabric-paths"
609
609
  ],
610
- "sha256": "04eaf6cd1786d4309a253a27dbdb05e27b408cb511aa41b1633a96634b775e65"
610
+ "sha256": "f1b6d156d050f8ceb9a21daaad8d39ab5de5d32e4cfe03817909388fca8ad27e"
611
611
  },
612
612
  {
613
613
  "module": "fabric-share",
@@ -762,7 +762,7 @@
762
762
  "fabric-secrets",
763
763
  "fabric-usage"
764
764
  ],
765
- "sha256": "243bbce42989f67c4c5ec6b7659e201b3f9a1c08c71d429d88ec934d870f5104"
765
+ "sha256": "7c0ef7d245c037eb9e859ab481f6e66fb3e5ef2cf6d1e0a8d32b6d303097ca43"
766
766
  },
767
767
  {
768
768
  "module": "fabric-context",
@@ -790,7 +790,7 @@
790
790
  "fabric-platform",
791
791
  "fabric-usage"
792
792
  ],
793
- "sha256": "782c2aa732f8320f604194660117640a7ea145e12b8155c04e88cef7c516a5b3"
793
+ "sha256": "10ff37a39f9e3adb4d0f05db66c45f49b10eef582e9220c213907964109d7e52"
794
794
  },
795
795
  {
796
796
  "module": "fabric-events",
@@ -845,7 +845,7 @@
845
845
  "fabric-supervisors",
846
846
  "fabric-usage"
847
847
  ],
848
- "sha256": "6aa673657427211b491a9b63f94b9847a7e6aa3ee1b7353e1af11f46469803a3"
848
+ "sha256": "297fef11ac76dc831d12d24c5581b7a93587c300c20664db703b3f924c0f9f1a"
849
849
  },
850
850
  {
851
851
  "module": "fabric-profiles",
@@ -967,7 +967,7 @@
967
967
  "file": "fabric-http.mjs",
968
968
  "layer": "L4",
969
969
  "imports": [],
970
- "sha256": "9f899829073470b9c2b449605a9371b773848eec4e3a0122ed4ccde5eddcdb4b"
970
+ "sha256": "96aa1730c79cb9a68dcc94642513eb1e88f0c2d99a45ca505c042e8c601d0436"
971
971
  },
972
972
  {
973
973
  "module": "fabric-openrouter",
@@ -4686,6 +4686,96 @@
4686
4686
  "fabric-openrouter.mjs": "6041f3ab30f516658e1dbab4897a651cc8509b2136cfa8e769802c6b40ec2f35",
4687
4687
  "fabric-package.schema.json": "2ba799f576fad0f608029223c4ccccd122152f1c5dbfa8ce8b31cd63ac92ad44",
4688
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"
4689
4779
  }
4690
4780
  },
4691
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.61.0"
8
+ version: "0.62.0"
9
9
  contract-version: "0.1.0"
10
10
  contract-commit: "3830a3353923e20f826d466610e1c479f120bec0"
11
11
  ---
@@ -18,7 +18,7 @@ compatibility: >-
18
18
  this plugin; Codex/Kimi use command hooks; Hermes/OpenCode/OpenClaw/Pi use native context plugins after opt-in.
19
19
  metadata:
20
20
  author: PassionCode.ai
21
- version: "0.61.0"
21
+ version: "0.62.0"
22
22
  ---
23
23
 
24
24
  # Working with Fabric
@@ -58,7 +58,7 @@ SESSION_ID = re.compile(r"[A-Za-z0-9._:-]{1,128}")
58
58
  LOOPBACK_ORIGIN = re.compile(r"http://127\.0\.0\.1:(\d{1,5})")
59
59
 
60
60
 
61
- VERSION = "0.61.0"
61
+ VERSION = "0.62.0"
62
62
 
63
63
 
64
64
  HOSTS = {"claude": "Claude Code", "codex": "Codex", "kimi": "Kimi Code",