@passioncode-ai/fabric-agent-adapter 0.4.2 → 0.5.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 (21) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +150 -17
  3. package/README.md +44 -6
  4. package/SECURITY.md +2 -3
  5. package/bin/fabric-agent-adapter.js +1 -1
  6. package/package.json +5 -5
  7. package/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +4 -4
  8. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +25 -6
  9. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/provider-entry.md +53 -0
  10. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/adapt_project.py +15 -2
  11. package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/fabric_provider.py +242 -0
  12. package/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +23 -7
  13. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/interop.md +77 -0
  14. package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +1 -1
  15. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py +174 -0
  16. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop.mjs +188 -0
  17. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-service.mjs +8 -1
  18. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop.py +424 -0
  19. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_service.py +14 -2
  20. package/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample_service.py +116 -1
  21. package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +22 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0 - 2026-09-30
4
+
5
+ ### Added
6
+
7
+ - **`fabric-interop/0.1` in the kits** (Fabric Agent Contract DEC-0016).
8
+ `building-fabric-services/scripts/fabric_interop.py` and its Node twin
9
+ `fabric-interop.mjs`: W3C trace context (`child_traceparent`, `trace_ids`), a
10
+ capability served as the MCP tool of its name with annotations from its effect,
11
+ durable jobs (`JobStore`: ids survive a restart, terminal states never change,
12
+ `unknown-job` for an unknown id), the result envelope with `usage`, and elicitations
13
+ (a titled single-select in form mode, URL mode for secrets; form mode refuses a
14
+ secret field). Python also ships `McpToolServer`, a minimal `tools/list` /
15
+ `tools/call` dispatcher with `fabric.job.get` and `fabric.job.cancel` built in.
16
+ - Events carry `traceId` and `spanId` as a pair (`make_event`, `makeEvent`).
17
+ - The sample service serves MCP at `/mcp`: `sample.echo`, and `sample.draft`, a job
18
+ that stops for a title choice and completes with a traced result. `register` writes
19
+ its manifest and schemas and points the descriptor's `fabricManifest` at it.
20
+ - The probe `check_service.py` gains seven `interop.*` rules: manifest link (G-07),
21
+ capability list, tools equal to the manifest (FAC-SEM-017), job tools, unknown job,
22
+ trace propagation and event trace pairs. It calls only `tools/list` and
23
+ `fabric.job.get` for a made-up id.
24
+ - `adapting-projects-to-fabric/scripts/fabric_provider.py`: writes, validates and
25
+ removes `fabric-provider/0.1` entries for agents that are not services — argv only,
26
+ env values as `secret-ref:` references, never the id of an existing service.
27
+ - `adapt_project.py scaffold --job` writes the capability's interop block; an `mcp`
28
+ capability now requires the tool of its own name instead of `tool:replace-me`, and
29
+ `check` refuses a malformed interop block.
30
+ - Skills teach it: `building-fabric-services` gains `references/interop.md`,
31
+ `adapting-projects-to-fabric` gains `references/provider-entry.md` and step 4b, and
32
+ `creating-fabric-agents` starts new agents on it. Trigger and scenario evals added
33
+ first.
34
+
35
+ ### Changed
36
+
37
+ - **Contract pin** moves from `a5a2709` to `a22dea3` (fabric-agent-contract `main`,
38
+ AR-1: interop, provider entries, runner catalogue, pipelines). The provider profiles
39
+ and every existing schema field are unchanged; the contract added schemas and
40
+ optional fields only (DEC-0016). **One pin**: `fabric-contract.lock.json`, and
41
+ `test/validate.py` fails any live file that names another contract revision (G-11).
42
+ - The README has a newcomer path that starts the sample service and probes it.
43
+
44
+ ## 0.4.3 - 2026-09-29
45
+
46
+ ### Changed
47
+
48
+ - **License.** The adapter is now source-available under
49
+ `PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0`, with a
50
+ commercial license on request (contact@passioncode.ai). Versions up to and including
51
+ v0.4.2, on GitHub and on npm, were released under MIT and remain available under it. The manifests, the three skills' `license:` and the README say the
52
+ same; contributions come in under `CLA.md`, which the new PR template asks for.
53
+ `test/validate.py` fails a tree that slips back to MIT.
54
+ - Author and marketplace owner are PassionCode.ai (`https://passioncode.ai/`).
55
+ - **Contract pin** moves from `20a818e` to `a5a2709` (fabric-agent-contract `main`), the
56
+ commit `building-fabric-services` already pinned. Between the two the provider
57
+ profiles are unchanged — only the `fabric-service/0.1` extension was added — and
58
+ `adapt_project.py check --contract` gives the same verdicts for an MCP, an A2A and a
59
+ local-runner bundle at both commits (declaration shape PASS). One pin for all three
60
+ skills.
61
+ - `creating-fabric-agents` hands the agent's own loop to `agent-orchestrator`, its
62
+ eval suite to `agent-evals` (agent-stack) and plugin packaging to `make-skill`;
63
+ `adapting-projects-to-fabric` sends wire-level MCP/A2A questions to `agent-interop`.
64
+
65
+ ### Fixed
66
+
67
+ - The installer's help names the launcher by its npm org name,
68
+ `npx @passioncode-ai/passioncode@latest update`; the bare `passioncode` is not ours.
69
+ - A distributed eval named a personal agent as its example service; the
70
+ `building-fabric-services` evals use `example-agent`, and its description says "a
71
+ macOS machine" instead of naming whose.
72
+
3
73
  ## 0.4.2 - 2026-09-29
4
74
 
5
75
  - Kit: `LoopbackHTTPServer`, a `ThreadingHTTPServer` whose bind asks no resolver.
package/LICENSE CHANGED
@@ -1,22 +1,155 @@
1
- MIT License
1
+ Copyright (c) 2026 Siarhei Sheleh
2
2
 
3
- Copyright (c) 2026 passioncode-ai
3
+ This software is source-available, not open source. You may use it under
4
+ either of the two licenses below, at your option:
4
5
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
6
+ 1. PolyForm Noncommercial License 1.0.0
7
+ SPDX: PolyForm-Noncommercial-1.0.0
8
+ 2. PolyForm Internal Use License 1.0.0
9
+ SPDX: LicenseRef-PolyForm-Internal-Use-1.0.0
11
10
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
11
+ In short: individuals and noncommercial organisations may use, change and
12
+ share it for noncommercial purposes; any company may use it, and change it,
13
+ for its own internal operations. Distributing it commercially, or building
14
+ this software or its code into a product or service you provide to others,
15
+ needs a separate commercial license: contact@passioncode.ai.
16
+ This summary is not part of either license; the texts below govern.
14
17
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
18
+ Versions up to and including v0.4.2 of this repository, and of its npm package, were
19
+ released under the MIT License; those releases remain available under MIT.
22
20
 
21
+ Required Notice: Copyright (c) 2026 Siarhei Sheleh (https://passioncode.ai)
22
+
23
+ ================================================================================
24
+
25
+ # PolyForm Noncommercial License 1.0.0
26
+
27
+ <https://polyformproject.org/licenses/noncommercial/1.0.0>
28
+
29
+ ## Acceptance
30
+
31
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
32
+
33
+ ## Copyright License
34
+
35
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
36
+
37
+ ## Distribution License
38
+
39
+ The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
40
+
41
+ ## Notices
42
+
43
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
44
+
45
+ > Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
46
+
47
+ ## Changes and New Works License
48
+
49
+ The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
50
+
51
+ ## Patent License
52
+
53
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
54
+
55
+ ## Noncommercial Purposes
56
+
57
+ Any noncommercial purpose is a permitted purpose.
58
+
59
+ ## Personal Uses
60
+
61
+ Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
62
+
63
+ ## Noncommercial Organizations
64
+
65
+ Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
66
+
67
+ ## Fair Use
68
+
69
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
70
+
71
+ ## No Other Rights
72
+
73
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
74
+
75
+ ## Patent Defense
76
+
77
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
78
+
79
+ ## Violations
80
+
81
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
82
+
83
+ ## No Liability
84
+
85
+ ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
86
+
87
+ ## Definitions
88
+
89
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
90
+
91
+ **You** refers to the individual or entity agreeing to these terms.
92
+
93
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
94
+
95
+ **Your licenses** are all the licenses granted to you for the software under these terms.
96
+
97
+ **Use** means anything you do with the software requiring one of your licenses.
98
+
99
+ ================================================================================
100
+
101
+ # PolyForm Internal Use License 1.0.0
102
+
103
+ <https://polyformproject.org/licenses/internal-use/1.0.0>
104
+
105
+ ## Acceptance
106
+
107
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
108
+
109
+ ## Copyright License
110
+
111
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license), and you may not distribute the software.
112
+
113
+ ## Changes and New Works License
114
+
115
+ The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
116
+
117
+ ## Patent License
118
+
119
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
120
+
121
+ ## Fair Use
122
+
123
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
124
+
125
+ ## Internal Business Use
126
+
127
+ Use of the software for the internal business operations of you and your company is use for a permitted purpose.
128
+
129
+ ## No Other Rights
130
+
131
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
132
+
133
+ ## Patent Defense
134
+
135
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
136
+
137
+ ## Violations
138
+
139
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
140
+
141
+ ## No Liability
142
+
143
+ ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
144
+
145
+ ## Definitions
146
+
147
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
148
+
149
+ **You** refers to the individual or entity agreeing to these terms.
150
+
151
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
152
+
153
+ **Your licenses** are all the licenses granted to you for the software under these terms.
154
+
155
+ **Use** means anything you do with the software requiring one of your licenses.
package/README.md CHANGED
@@ -15,9 +15,9 @@ without moving the Project onto one proprietary agent runtime.
15
15
 
16
16
  [![npm](https://img.shields.io/npm/v/%40passioncode-ai%2Ffabric-agent-adapter)](https://www.npmjs.com/package/@passioncode-ai/fabric-agent-adapter)
17
17
  [![validate](https://github.com/passioncode-ai/fabric-agent-adapter/actions/workflows/validate.yml/badge.svg)](https://github.com/passioncode-ai/fabric-agent-adapter/actions/workflows/validate.yml)
18
- [![license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
18
+ [![license](https://img.shields.io/badge/license-source--available-blue.svg)](LICENSE)
19
19
 
20
- Private, portable Agent Skills for the
20
+ Portable Agent Skills that make any agent Fabric-compatible, for the
21
21
  [Fabric Agent Contract](https://github.com/passioncode-ai/fabric-agent-contract):
22
22
  `adapting-projects-to-fabric`, `creating-fabric-agents` and
23
23
  `building-fabric-services`.
@@ -32,6 +32,14 @@ complete `scripts/sample_service.py`, and `scripts/check_service.py`, a live pro
32
32
  python3 plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py example-agent
33
33
  ```
34
34
 
35
+ Services and agents that other agents call follow `fabric-interop/0.1`: each capability
36
+ is the MCP tool of its name, long work is a job with a stable id (`fabric.job.get`,
37
+ `fabric.job.cancel`), a question for a person is an elicitation, and every call carries
38
+ one W3C trace. The kits ship the helpers (`scripts/fabric_interop.py`,
39
+ `scripts/fabric-interop.mjs`), the sample service serves a job end to end, and the probe
40
+ checks the interop rules. An agent that is not a service is announced with a provider
41
+ entry: `adapting-projects-to-fabric/scripts/fabric_provider.py`.
42
+
35
43
  For provider bundles the adapting skill helps an agent author:
36
44
 
37
45
  - inspect the project's stable integration surfaces without executing it;
@@ -46,7 +54,7 @@ yet ship the host registry/runtime needed to connect and authorize a live provid
46
54
 
47
55
  ## Install
48
56
 
49
- The repository is private; the npm package is public. The npm path needs no GitHub access — the GitHub paths do.
57
+ The repository and the npm package are public; neither path needs an account.
50
58
 
51
59
  npm — no GitHub access required:
52
60
 
@@ -110,6 +118,23 @@ python3 "$SKILL_DIR/scripts/adapt_project.py" check /path/to/project \
110
118
  Scaffolding is non-destructive by default. It writes only the paths declared in the
111
119
  [delivery brief](docs/evidence/specs/2026-08-27-brief.md) and refuses collisions.
112
120
 
121
+ ## Verify one service (newcomer path)
122
+
123
+ After installing (above), with Python 3.9+ and no other dependency:
124
+
125
+ ```bash
126
+ KIT=plugins/fabric-agent-adapter/skills/building-fabric-services/scripts # or ~/.agents/skills/building-fabric-services/scripts
127
+ DATA=$(mktemp -d); SERVICES=$(mktemp -d)
128
+ python3 "$KIT/sample_service.py" serve --port 47190 --data-dir "$DATA" &
129
+ python3 "$KIT/sample_service.py" register --port 47190 --data-dir "$DATA" --services-dir "$SERVICES"
130
+ python3 "$KIT/check_service.py" sample --services-dir "$SERVICES" # exit 0: no FAIL
131
+ kill %1
132
+ ```
133
+
134
+ The probe prints one line per rule — `PASS`, `FAIL` or `NOT_RUN` with its evidence — and
135
+ exits 1 on any `FAIL`. Run it against your own service by its id once its installer has
136
+ written the descriptor.
137
+
113
138
  ## Validate this repository
114
139
 
115
140
  ```bash
@@ -125,8 +150,21 @@ checks copies installed elsewhere, such as `~/.agents/skills/*/SKILL.md`.
125
150
 
126
151
  ## Contract pin
127
152
 
153
+ The one pin is [`fabric-contract.lock.json`](fabric-contract.lock.json):
154
+
128
155
  - version: `0.1.0`
129
- - commit: `20a818e648a4c09a60df0126d11626922e8b9094`
156
+ - commit: `a22dea359ba04b8fe549abe81a5131552cb90eff`
157
+
158
+ Every other mention of the contract revision — this section, the skills' metadata, the
159
+ skill card, `adapt_project.py` — must equal it; `python3 test/validate.py` fails a tree
160
+ where one does not. The contract repository is normative. Updating the pin requires a
161
+ new adapter release, fixture review, and a complete validation run.
162
+
163
+ ## License
130
164
 
131
- The contract repository is normative. Updating the pin requires a new adapter release,
132
- fixture review, and a complete validation run.
165
+ Source-available under PolyForm Noncommercial or Internal Use; commercial license on
166
+ request (contact@passioncode.ai). SPDX:
167
+ `PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0` — see
168
+ [LICENSE](LICENSE). Versions up to and including v0.4.2 (on GitHub and on npm) were
169
+ released under the MIT License and remain available under it. Contributions are accepted under
170
+ [CLA.md](CLA.md) ([CONTRIBUTING.md](CONTRIBUTING.md)).
package/SECURITY.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Security
2
2
 
3
- Report vulnerabilities privately to the maintainers of the `passioncode-ai`
4
- organization. Do not open a public issue containing credentials, private provider URLs,
5
- or customer project data.
3
+ Report vulnerabilities privately to contact@passioncode.ai. Do not open a public issue
4
+ containing credentials, private provider URLs, or customer project data.
6
5
 
7
6
  The adapter must not write secret values to manifests, fixtures, probes, logs, or command
8
7
  arguments. Generated and external provider outputs are untrusted. Live probes must be
@@ -35,7 +35,7 @@ Claude Code (recommended):
35
35
  claude plugin marketplace add ${REPO}
36
36
  claude plugin install ${PLUGIN_ID}
37
37
  Every PassionCode.ai skill for every agent at once:
38
- npx passioncode@latest update`);
38
+ npx @passioncode-ai/passioncode@latest update`);
39
39
  }
40
40
 
41
41
  function copyDir(src, dest) {
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@passioncode-ai/fabric-agent-adapter",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "Create Fabric-compatible agents, run them as always-alive local services with dashboards (fabric-service/0.1), and adapt existing projects to the Fabric Agent Contract. This package is the installer CLI.",
5
5
  "scripts": {
6
- "test": "python3 test/validate.py && python3 -m unittest discover -s test -q && node --test test/"
6
+ "test": "python3 test/validate.py && python3 -m unittest discover -s test -q && node --test 'test/*.test.mjs'"
7
7
  },
8
8
  "bin": {
9
9
  "fabric-agent-adapter": "bin/fabric-agent-adapter.js"
@@ -23,10 +23,10 @@
23
23
  ],
24
24
  "repository": "github:passioncode-ai/fabric-agent-adapter",
25
25
  "homepage": "https://github.com/passioncode-ai/fabric-agent-adapter",
26
- "license": "MIT",
26
+ "license": "PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0",
27
27
  "author": {
28
- "name": "passioncode-ai",
29
- "url": "https://github.com/passioncode-ai"
28
+ "name": "PassionCode.ai",
29
+ "url": "https://passioncode.ai/"
30
30
  },
31
31
  "engines": {
32
32
  "node": ">=16"
@@ -3,14 +3,14 @@
3
3
  "name": "fabric-agent-adapter",
4
4
  "displayName": "Fabric Agent Adapter",
5
5
  "description": "Create new Fabric-compatible agents, build them as always-alive local services with dashboards (fabric-service/0.1), and adapt existing projects to the Fabric Agent Contract through evidence-backed MCP, A2A, or local-runner provider bundles.",
6
- "version": "0.4.2",
6
+ "version": "0.5.0",
7
7
  "author": {
8
- "name": "passioncode-ai",
9
- "url": "https://github.com/passioncode-ai"
8
+ "name": "PassionCode.ai",
9
+ "url": "https://passioncode.ai/"
10
10
  },
11
11
  "homepage": "https://github.com/passioncode-ai/fabric-agent-adapter",
12
12
  "repository": "https://github.com/passioncode-ai/fabric-agent-adapter",
13
- "license": "MIT",
13
+ "license": "PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0",
14
14
  "keywords": [
15
15
  "fabric",
16
16
  "agent",
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: adapting-projects-to-fabric
3
3
  description: Use when adapting an existing agent, MCP server, A2A peer, HTTP service, or terminal CLI to the Fabric Agent Contract—choosing MCP/A2A/local-runner, scaffolding a provider bundle, or checking Fabric compatibility; also for «подключить проект к Fabric» or «сделать агента совместимым с Fabric». NOT for building the Fabric host/orchestrator, configuring an MCP client, or a brand-new agent — that is creating-fabric-agents.
4
- license: MIT
4
+ license: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0
5
5
  compatibility: Requires filesystem access and Python 3.9+. Exact schema checks additionally need git, Node.js, pnpm, and the pinned private fabric-agent-contract checkout. Works without those tools in an explicitly degraded structural-check mode.
6
6
  metadata:
7
- author: passioncode-ai
8
- version: "0.4.2"
7
+ author: PassionCode.ai
8
+ version: "0.5.0"
9
9
  contract-version: "0.1.0"
10
- contract-commit: "20a818e648a4c09a60df0126d11626922e8b9094"
10
+ contract-commit: "a22dea359ba04b8fe549abe81a5131552cb90eff"
11
11
  ---
12
12
 
13
13
  # Adapting projects to Fabric
@@ -22,6 +22,9 @@ Use this skill to adapt or assess a provider project. Do not use it to:
22
22
 
23
23
  - design the Fabric host, registry, scheduler, admission service, or project binding runtime;
24
24
  - add an MCP server to Claude Code, Codex, or an agent gateway;
25
+ - answer wire-level MCP or A2A questions (transports, sessions, auth handshakes, task
26
+ states on the wire) — that is `agent-interop` (agent-stack); the pinned contract stays
27
+ normative for what Fabric requires;
25
28
  - design a new agent from scratch — that is the sibling skill creating-fabric-agents;
26
29
  - claim admission merely because generated files or a valid manifest exist.
27
30
 
@@ -67,7 +70,7 @@ Use exactly:
67
70
 
68
71
  - contract version `0.1.0`;
69
72
  - repository `https://github.com/passioncode-ai/fabric-agent-contract`;
70
- - commit `20a818e648a4c09a60df0126d11626922e8b9094`.
73
+ - commit `a22dea359ba04b8fe549abe81a5131552cb90eff`.
71
74
 
72
75
  Read the pinned contract's guide
73
76
  `docs/guides/connecting-compatible-agents.md`, the selected profile specification, and
@@ -90,7 +93,10 @@ python3 <skill-dir>/scripts/adapt_project.py scaffold <project-root> \
90
93
  --schema-base https://agents.example/fabric
91
94
  ```
92
95
 
93
- Valid profiles are `mcp`, `a2a`, and `local-runner`. The helper creates only the locked
96
+ Valid profiles are `mcp`, `a2a`, and `local-runner`. For `mcp` the capability is served
97
+ as the MCP tool of its own name (`requiredFeatures: ["tool:<capability>"]`, contract
98
+ `fabric-interop/0.1`); add `--job` when its work may outlive one request, which writes
99
+ `"job": true` in the capability's interop block. The helper creates only the locked
94
100
  target paths. It refuses any collision. Do not use `--force` unless the user explicitly
95
101
  authorizes replacement after the exact conflicting files and diff are shown.
96
102
 
@@ -105,6 +111,11 @@ Preserve the chosen ownership boundary:
105
111
  - A2A maps the provider's remote task, progress, artifact, cancellation, and terminal
106
112
  states; Fabric does not take over its internal loop.
107
113
  - MCP exposes bounded tools/resources/prompts while Fabric owns planning and retries.
114
+ The served tool's name, input and output schemas equal the manifest's (FAC-SEM-017);
115
+ long work returns a job handle and serves `fabric.job.get` / `fabric.job.cancel`; a
116
+ question for a person is a form-mode choice, a secret goes through URL mode; every call
117
+ runs as a child span of `_meta.traceparent`. The kit for all of it is
118
+ `building-fabric-services`'s `scripts/fabric_interop.py`.
108
119
  - Local runner maps typed input, executable identity, result location, cancellation,
109
120
  heartbeat, and partial results without relying on ambient accounts.
110
121
 
@@ -112,6 +123,14 @@ Keep model selection and provider-internal reasoning outside the Fabric contract
112
123
  typed outcomes, evidence, artifacts, and protocol-visible state—not chain-of-thought.
113
124
  Treat all provider output as untrusted until schemas and semantic assertions pass.
114
125
 
126
+ ### 4b. Announce an agent that is not a service
127
+
128
+ An agent Fabric reaches as a CLI or a stdio MCP server gets a provider entry, written by
129
+ its installer with [`scripts/fabric_provider.py`](scripts/fabric_provider.py) and removed
130
+ by its uninstaller — argv arrays only, env values as `secret-ref:` references, never the
131
+ id of an existing service. Load [provider entries](references/provider-entry.md). An
132
+ agent that runs as a service uses a descriptor instead (`building-fabric-services`).
133
+
115
134
  ### 5. Make probes safe and meaningful
116
135
 
117
136
  For each capability, create at least one bounded fixture that:
@@ -0,0 +1,53 @@
1
+ # Provider entries: agents that are not services
2
+
3
+ Normative source: the Fabric Agent Contract's `docs/specification/provider.md`
4
+ (`fabric-provider/0.1`, DEC-0016) at the commit this plugin pins.
5
+
6
+ An agent Fabric reaches as a CLI or a stdio MCP server — not a long-running service —
7
+ is announced by one entry, `providers/<id>.json`, in the same root as the services
8
+ directory:
9
+
10
+ | Platform | Directory |
11
+ |---|---|
12
+ | macOS | `~/Library/Application Support/ai.passioncode.fabric/providers/` |
13
+ | Linux | `${XDG_DATA_HOME:-~/.local/share}/passioncode-fabric/providers/` |
14
+ | any | `FABRIC_PROVIDERS_DIR` when set |
15
+
16
+ A service uses a descriptor instead (the `building-fabric-services` skill). One id is a
17
+ service or a provider, never both.
18
+
19
+ ## The writer
20
+
21
+ `scripts/fabric_provider.py` is the installer's tool; it writes atomically, mode 0600,
22
+ and refuses what the contract refuses.
23
+
24
+ ```bash
25
+ python3 scripts/fabric_provider.py write --id example-agent --name "Example Agent" \
26
+ --manifest ~/.local/share/example-agent/fabric-agent.json --installed-by "example-agent 1.0.0" \
27
+ --env EXAMPLE_API_KEY=secret-ref:example-agent/EXAMPLE_API_KEY \
28
+ --stdio ~/.local/bin/example-agent mcp
29
+ python3 scripts/fabric_provider.py write ... --url http://127.0.0.1:47201/mcp
30
+ python3 scripts/fabric_provider.py validate ~/Library/Application\ Support/ai.passioncode.fabric/providers/example-agent.json
31
+ python3 scripts/fabric_provider.py remove example-agent # the uninstaller
32
+ ```
33
+
34
+ `--stdio` takes the rest of the line as the argument array; there is no shell string.
35
+
36
+ It refuses, with one sentence that never quotes a value:
37
+
38
+ - an id that is already a service in `services/` (FAC-SEM-013);
39
+ - an env value that is not `secret-ref:<name>`, or a reference that has the shape of a
40
+ credential itself — a token prefix, a private key, a JWT (FAC-SEM-015);
41
+ - a URL other than `http://127.0.0.1:<port>/mcp`, a manifest path that is not an
42
+ absolute or `~/` path to `fabric-agent.json`, a shell-string command, unknown fields.
43
+
44
+ From Python: `write_provider_entry(entry)`, `remove_provider_entry(id)`,
45
+ `validate_provider_entry(entry)`, `providers_dir()`.
46
+
47
+ ## What the entry does not do
48
+
49
+ It grants nothing: Fabric lists the agent, and admission (probes) and a project binding
50
+ still decide what it may do. The manifest it points at is the authority for the
51
+ agent's capabilities. The contract's rule that the manifest's `provider.id` "equals" the
52
+ entry's id cannot hold as written — `provider.id` is a URI, the entry id a slug — so only
53
+ "the manifest resolves" is checked until the contract answers OQ-0001.
@@ -16,7 +16,8 @@ from urllib.parse import urlparse
16
16
 
17
17
  CONTRACT_VERSION = "0.1.0"
18
18
  CONTRACT_REPOSITORY = "https://github.com/passioncode-ai/fabric-agent-contract"
19
- CONTRACT_COMMIT = "20a818e648a4c09a60df0126d11626922e8b9094"
19
+ CONTRACT_COMMIT = "a22dea359ba04b8fe549abe81a5131552cb90eff"
20
+ INTEROP_KEY = "https://fabric.passioncode.ai/agent-contract/extensions/interop/0.1"
20
21
  MCP_REVISION = "2026-07-28"
21
22
  A2A_VERSION = "1.0"
22
23
  LOCAL_VERSION = "fabric-local-runner/0.1"
@@ -167,7 +168,8 @@ def _profile(args: argparse.Namespace, schema_base: str) -> Dict[str, Any]:
167
168
  "kind": "mcp",
168
169
  "protocolRevision": MCP_REVISION,
169
170
  "connection": connection,
170
- "requiredFeatures": ["tool:replace-me"],
171
+ # fabric-interop/0.1 C3.1: the capability is served as the MCP tool of its own name.
172
+ "requiredFeatures": ["tool:%s" % args.capability_name],
171
173
  "probes": [probe],
172
174
  }
173
175
  if profile == "a2a":
@@ -215,6 +217,8 @@ def _generated_files(args: argparse.Namespace) -> Dict[str, str]:
215
217
  _require_absolute_uri(args.agent_card_url, "Agent Card URL")
216
218
  if urlparse(args.agent_card_url).scheme != "https":
217
219
  raise AdaptationError("Agent Card URL must use HTTPS")
220
+ if getattr(args, "job", False) and args.profile != "mcp":
221
+ raise AdaptationError("--job marks an MCP capability as a job (fabric-interop/0.1); %s has no job handle" % args.profile)
218
222
  for runtime_arg in args.runtime_arg:
219
223
  lowered = runtime_arg.lower().replace("_", "").replace("-", "")
220
224
  if any(term in lowered for term in ("password", "apikey", "accesstoken", "clientsecret")):
@@ -249,6 +253,8 @@ def _generated_files(args: argparse.Namespace) -> Dict[str, str]:
249
253
  }
250
254
  ],
251
255
  }
256
+ if getattr(args, "job", False):
257
+ manifest["capabilities"][0]["extensions"] = {INTEROP_KEY: {"job": True}}
252
258
  lock = {
253
259
  "contract": "fabric-agent-contract",
254
260
  "version": CONTRACT_VERSION,
@@ -431,6 +437,12 @@ def check_project(root: Path, contract: Optional[Path]) -> Dict[str, Any]:
431
437
  errors.append("capability[%d] must pin %s=%s" % (index, expected[0], expected[1]))
432
438
  if not profile.get("probes"):
433
439
  errors.append("capability[%d] must declare probes" % index)
440
+ block = (capability.get("extensions") or {}).get(INTEROP_KEY)
441
+ if block is not None:
442
+ if not isinstance(block, dict) or set(block) - {"job"} or not isinstance(block.get("job", False), bool):
443
+ errors.append("capability[%d] interop block must be {\"job\": true|false}" % index)
444
+ elif kind != "mcp":
445
+ errors.append("capability[%d] interop block is for an mcp capability, not %s" % (index, kind))
434
446
  for field in ("inputSchema", "outputSchema"):
435
447
  value = capability.get(field)
436
448
  try:
@@ -503,6 +515,7 @@ def build_parser() -> argparse.ArgumentParser:
503
515
  scaffold.add_argument("--runner-kind", default="replace-me")
504
516
  scaffold.add_argument("--executable-ref", default="urn:executable:replace-me")
505
517
  scaffold.add_argument("--runtime-arg", action="append", default=[])
518
+ scaffold.add_argument("--job", action="store_true", help="the capability's work may outlive one request (fabric-interop/0.1 job)")
506
519
  scaffold.add_argument("--force", action="store_true")
507
520
  scaffold.add_argument("--json", action="store_true")
508
521