@passioncode-ai/fabric-agent-adapter 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/package.json +1 -1
- package/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
- package/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +1 -1
- package/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +13 -5
- package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/lifecycle.md +21 -0
- package/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.3 - 2026-10-04
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **Agents and services get every credential from Project Observatory, by name.**
|
|
8
|
+
`building-fabric-services` principle 5: a service takes its provider credentials from the vault
|
|
9
|
+
through `use_secret.py serve` (Project Observatory 0.15.0), never from a copy beside the service;
|
|
10
|
+
a remote service's platform copy is recorded with `vault.py moved`. `creating-fabric-agents`
|
|
11
|
+
carries the same rule for agents from their first commit: no `.env` of their own, no key file
|
|
12
|
+
beside their data, no value in code, configuration or a commit, and `use_secret.py run
|
|
13
|
+
--vault-only` at launch.
|
|
14
|
+
|
|
15
|
+
## 0.6.2 - 2026-10-03
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **`building-fabric-services` says how a product behaves under a host lifecycle broker** — the
|
|
20
|
+
always-on per-user service agents ask to start, stop and restart products
|
|
21
|
+
(`references/lifecycle.md`, "Being managed by a host lifecycle broker"): quit through both the
|
|
22
|
+
platform's quit and `SIGTERM`, stay in the background when opened non-activating, keep the
|
|
23
|
+
designated requirement stable, expose honest readiness. Measured on the first broker that
|
|
24
|
+
stops apps: a desktop app that closes its window on `SIGTERM` and keeps running, and one that
|
|
25
|
+
takes focus when launched in the background — both are what this section prevents.
|
|
26
|
+
|
|
3
27
|
## 0.6.1 - 2026-10-03
|
|
4
28
|
|
|
5
29
|
### Fixed
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@passioncode-ai/fabric-agent-adapter",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
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
6
|
"test": "python3 test/validate.py && python3 -m unittest discover -s test -q && node --test 'test/*.test.mjs'"
|
|
@@ -3,7 +3,7 @@
|
|
|
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.6.
|
|
6
|
+
"version": "0.6.3",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "PassionCode.ai",
|
|
9
9
|
"url": "https://passioncode.ai/"
|
|
@@ -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.
|
|
6
6
|
metadata:
|
|
7
7
|
author: PassionCode.ai
|
|
8
|
-
version: "0.6.
|
|
8
|
+
version: "0.6.3"
|
|
9
9
|
contract-version: "0.1.0"
|
|
10
10
|
contract-commit: "2ce392291c6668598d12cd38327e24696b5ca15c"
|
|
11
11
|
---
|
|
@@ -15,7 +15,7 @@ license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
|
|
|
15
15
|
compatibility: Python 3.9+ or Node.js 20+ for the kits; the probe needs Python 3.9+. launchd steps are macOS-only (Linux services use lifecycle manager none until a systemd adapter exists). Dashboard handoff optionally uses Fabric Dashboards MCP link/host_status/open; without it, report unresolved host capability. The contract checkout is optional.
|
|
16
16
|
metadata:
|
|
17
17
|
author: PassionCode.ai
|
|
18
|
-
version: "0.6.
|
|
18
|
+
version: "0.6.3"
|
|
19
19
|
contract-version: "0.1.0"
|
|
20
20
|
extension: "fabric-service/0.1"
|
|
21
21
|
extension-commit: "2ce392291c6668598d12cd38327e24696b5ca15c"
|
|
@@ -101,8 +101,12 @@ are in [`scripts/fabric_interop.py`](scripts/fabric_interop.py) and
|
|
|
101
101
|
digest and the process start time. *(A service ran on stale code after an edit and
|
|
102
102
|
burned budget; nothing showed which build was answering.)*
|
|
103
103
|
5. **State outside code.** Data and config in `~/Library/Application Support/<id>/`,
|
|
104
|
-
logs in `~/Library/Logs/<id>/`, cache in `~/Library/Caches/<id>/`;
|
|
105
|
-
|
|
104
|
+
logs in `~/Library/Logs/<id>/`, cache in `~/Library/Caches/<id>/`; the service's own
|
|
105
|
+
access token in a 0600 file it generates (principle 6). **Every provider credential the
|
|
106
|
+
service uses comes from Project Observatory, by name** — the plist starts the service
|
|
107
|
+
with `use_secret.py serve --consumer <label> <project> <NAME>[,<NAME>] -- <command>`, which
|
|
108
|
+
reads the vault only and records the consumer so a rotation names it; never a copy of a
|
|
109
|
+
key in a `.env`, a config file or the plist. Never inside the service's own code checkout or a release directory; a
|
|
106
110
|
repository that versions the data itself is a store and is fine — declare
|
|
107
111
|
`source.repository` so the probe can tell them apart. *(Deleting a checkout left a
|
|
108
112
|
plist launchd retried every 10 s, and the data went with it.)*
|
|
@@ -176,7 +180,8 @@ The installer, not the service, owns the plist and the descriptor. Sequence:
|
|
|
176
180
|
|
|
177
181
|
Code runs from an immutable release directory; an upgrade writes a new release,
|
|
178
182
|
rewrites the plist and restarts. Read [the lifecycle reference](references/lifecycle.md)
|
|
179
|
-
for the plist fields, the release layout, log rotation
|
|
183
|
+
for the plist fields, the release layout, log rotation, behaving under a host lifecycle broker
|
|
184
|
+
and the Linux case.
|
|
180
185
|
|
|
181
186
|
## Step 5 — the dashboard and the events
|
|
182
187
|
|
|
@@ -253,7 +258,10 @@ things change and the kits implement each:
|
|
|
253
258
|
example is [`scripts/sample-remote-service.mjs`](scripts/sample-remote-service.mjs): it runs
|
|
254
259
|
with its own TLS or behind a platform router.
|
|
255
260
|
2. **Secrets live on the platform:** the service token and the session key (32 bytes) are
|
|
256
|
-
platform secrets, never in the repository, a URL or an argument vector.
|
|
261
|
+
platform secrets, never in the repository, a URL or an argument vector. A provider key the
|
|
262
|
+
remote service needs is issued and kept in Project Observatory, pushed to the platform, and
|
|
263
|
+
the movement recorded with `vault.py moved --at <provider>`, so the platform's copy is
|
|
264
|
+
known rather than invisible.
|
|
257
265
|
3. **Register it on the operator's computer** — the installer side, run there:
|
|
258
266
|
`registerRemote({ id, name, origin, token })` / `register_remote(...)` writes the token file
|
|
259
267
|
(0600) and the descriptor; pass the token from a file or stdin, never in argv. Public names
|
package/plugins/fabric-agent-adapter/skills/building-fabric-services/references/lifecycle.md
CHANGED
|
@@ -56,6 +56,27 @@ On `SIGTERM`: stop accepting new work, append a `service.stopping` event, drain
|
|
|
56
56
|
in-flight work until `ExitTimeOut` minus a margin, persist what was interrupted so the
|
|
57
57
|
next start resumes it, release the lock, exit 0.
|
|
58
58
|
|
|
59
|
+
## Being managed by a host lifecycle broker
|
|
60
|
+
|
|
61
|
+
A host may run a lifecycle broker: one always-on per-user service that agents ask to start,
|
|
62
|
+
stop and restart products, instead of launching or killing them themselves. A product it manages
|
|
63
|
+
has to survive being driven from outside:
|
|
64
|
+
|
|
65
|
+
- **Quit reaches exit through both doors.** A broker asks the platform's own quit first — on
|
|
66
|
+
macOS `NSRunningApplication.terminate()`, the path Cmd+Q and the Dock take — and `SIGTERM` a few
|
|
67
|
+
seconds later. Handle both and exit inside the deadline (fabric-workspace LC-01). A desktop app
|
|
68
|
+
that answers `SIGTERM` by closing its window and staying alive is stopped late or not at all.
|
|
69
|
+
- **A background launch stays in the background.** A broker opens the app non-activating
|
|
70
|
+
(`NSWorkspace.OpenConfiguration.activates = false`); do not call `app.focus()`, `show()` on a
|
|
71
|
+
focused window, or activate on `ready` when nobody asked for a window. Taking focus from the
|
|
72
|
+
person is the one side effect they always notice.
|
|
73
|
+
- **Identity is the designated requirement.** A broker pins the app by team + bundle id, so an
|
|
74
|
+
update signed by the same team keeps working and anything else is refused (LC-05). Never ship an
|
|
75
|
+
ad-hoc or differently signed build to a machine that pins you.
|
|
76
|
+
- **Starting is not ready.** Expose readiness the broker can probe without a person — the
|
|
77
|
+
well-known document for a service, a process-level answer for a plain app — and keep it honest
|
|
78
|
+
while the app is still starting.
|
|
79
|
+
|
|
59
80
|
## Linux
|
|
60
81
|
|
|
61
82
|
Until a systemd adapter exists, declare `lifecycle.manager: "none"`. A `systemd --user`
|
|
@@ -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.6.
|
|
8
|
+
version: "0.6.3"
|
|
9
9
|
contract-version: "0.1.0"
|
|
10
10
|
contract-commit: "2ce392291c6668598d12cd38327e24696b5ca15c"
|
|
11
11
|
---
|
|
@@ -94,6 +94,13 @@ first commit:
|
|
|
94
94
|
- an `AGENTS.md` that opens with the template's *Read first* block and closes with *After work*,
|
|
95
95
|
and a `CLAUDE.md` whose first line is `@AGENTS.md`.
|
|
96
96
|
|
|
97
|
+
**Every credential the agent uses comes from Project Observatory, by name**, from its first
|
|
98
|
+
commit: the README's Configure section lists key NAMES; the agent finds them with
|
|
99
|
+
`observatory_credentials` and runs with `use_secret.py run --vault-only` (a long-running
|
|
100
|
+
service: `use_secret.py serve`), with `OBSERVATORY_VAULT_ONLY=1` in its environment. No `.env`
|
|
101
|
+
of its own, no key file beside its data, no value in code, configuration or a commit. A
|
|
102
|
+
workflow names the keys it needs in its checkpoint (`credentials`), never their values.
|
|
103
|
+
|
|
97
104
|
org-index `scripts/check_format.py` reports 0 findings for it before it is called done. **An agent
|
|
98
105
|
someone builds for themselves is not a PassionCode.ai repository:** its licence is its owner's
|
|
99
106
|
choice, nothing about it is published or listed by the organization, and none of these files is
|