@passioncode-ai/passioncode 0.2.38 → 0.2.40
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 +16 -0
- package/family.json +1 -1
- package/package.json +1 -1
- package/payload/.claude-plugin/marketplace.json +2 -2
- package/payload/manifest.json +8 -8
- package/payload/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
- package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +29 -11
- package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/dashboard-links.md +58 -5
- package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/references/operator-channel-and-repository.md +11 -3
- package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/adapt_project.py +2 -2
- package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/check_dashboard_link.py +8 -6
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +50 -12
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/fabric-button.js +5 -4
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/fabric-dashboard.css +1 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/fabric-dashboard.js +2 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/assets/dashboard-kit/kit.json +9 -4
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/recipes/support-agent/README.md +5 -3
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/board.md +3 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/dashboard-kit.md +3 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/dashboard-links.md +58 -5
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/dashboard.md +13 -4
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/delegation.md +13 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/estate-record.md +60 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/interop.md +159 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/kit-modules.md +8 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/package.md +4 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +14 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/settings-backups.md +2 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/surfaces-and-auth.md +40 -3
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_dashboard_link.py +8 -6
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py +67 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service_rules.py +371 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-a2a.mjs +170 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-actions.mjs +275 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-backups.mjs +3 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-context.mjs +151 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-delegation.mjs +38 -8
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-descriptor.mjs +31 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-estate.mjs +6 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop-rules.mjs +68 -3
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop.mjs +31 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-mandate.mjs +247 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-page-links.mjs +144 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-paths.mjs +22 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-protocols.mjs +2 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-service.mjs +1 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-share.mjs +30 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-supervisors.mjs +5 -4
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_a2a.py +209 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_actions.py +340 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_backups.py +2 -1
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_context.py +170 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_delegation.py +36 -12
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_descriptor.py +36 -3
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_estate.py +7 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop.py +242 -11
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop_rules.py +70 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_mandate.py +324 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_page_links.py +559 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_paths.py +21 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_protocols.py +2 -2
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_service.py +9 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_share.py +35 -0
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_supervisors.py +6 -4
- package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/kit.json +413 -25
- package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +29 -11
- package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/dashboard-links.md +58 -5
- package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/references/operator-channel-and-repository.md +11 -3
- package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/scripts/check_dashboard_link.py +8 -6
- package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/SKILL.md +87 -10
- package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/references/project-board.md +12 -0
- package/payload/plugins/fabric-agent-adapter/skills/working-with-fabric/scripts/fabric_session_env.py +1 -1
- package/payload/plugins/passioncode/.claude-plugin/plugin.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.40 - 2026-10-26
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- **Fabric Agent Adapter is pinned at `v0.51.1`** (it was `v0.50.0`): the contract release `v0.1.0+2026-10-26.2` with
|
|
8
|
+
the operator's mandate (one approval carried with a call, refused outside its scope with the order to follow), page
|
|
9
|
+
links handed over as Fabric Dashboards links, and the A2A surface. Notes are in the adapter's CHANGELOG.
|
|
10
|
+
|
|
11
|
+
## 0.2.39 - 2026-10-26
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **Fabric Agent Adapter is pinned at `v0.50.0`** (it was `v0.49.3`): the contract release `v0.1.0+2026-10-25` with
|
|
16
|
+
dashboard action parity (every dashboard button has an agent tool, and the operator's agent relays their decision),
|
|
17
|
+
agent pages that open only in Fabric Dashboards, and new probe rules. Notes are in the adapter's CHANGELOG.
|
|
18
|
+
|
|
3
19
|
## 0.2.38 - 2026-10-26
|
|
4
20
|
|
|
5
21
|
### Changed
|
package/family.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@passioncode-ai/passioncode",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.40",
|
|
4
4
|
"description": "Set up PassionCode.ai on a computer with one command — the apps from their verified releases, their MCP servers for every coding agent and the PassionCode.ai skills — and check and repair it with the same command or `doctor`.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"passioncode": "bin/passioncode.js"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"name": "fabric-agent-adapter",
|
|
12
12
|
"displayName": "Fabric Agent Adapter",
|
|
13
13
|
"source": "./plugins/fabric-agent-adapter",
|
|
14
|
-
"version": "0.
|
|
14
|
+
"version": "0.51.1",
|
|
15
15
|
"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; and teach a coding agent to work in a project through Fabric (fabric-mcp, fabric_whoami, claim and release), with Claude Code session hooks.",
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "PassionCode.ai",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"name": "passioncode",
|
|
36
36
|
"displayName": "PassionCode.ai",
|
|
37
37
|
"source": "./plugins/passioncode",
|
|
38
|
-
"version": "0.2.
|
|
38
|
+
"version": "0.2.40",
|
|
39
39
|
"description": "Set up and check PassionCode.ai on a computer with one command (setting-up-passioncode), the organisation's working rules for every contributor's agent (working-in-passioncode), and a once-a-day check that keeps the PassionCode.ai set current.",
|
|
40
40
|
"author": {
|
|
41
41
|
"name": "PassionCode.ai",
|
package/payload/manifest.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"family": "passioncode",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.40",
|
|
4
4
|
"release": true,
|
|
5
5
|
"members": [
|
|
6
6
|
{
|
|
7
7
|
"name": "fabric-agent-adapter",
|
|
8
8
|
"displayName": "Fabric Agent Adapter",
|
|
9
9
|
"repo": "passioncode-ai/fabric-agent-adapter",
|
|
10
|
-
"ref": "v0.
|
|
11
|
-
"commit": "
|
|
12
|
-
"version": "0.
|
|
10
|
+
"ref": "v0.51.1",
|
|
11
|
+
"commit": "37a3dee395a5cfbcc86b8523bcfcbb50111d82d4",
|
|
12
|
+
"version": "0.51.1",
|
|
13
13
|
"via": "clone of https://***@github.com/passioncode-ai/fabric-agent-adapter.git",
|
|
14
14
|
"skills": [
|
|
15
15
|
"adapting-projects-to-fabric",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"legacyMarketplaces": [
|
|
24
24
|
"fabric-agent-adapter"
|
|
25
25
|
],
|
|
26
|
-
"contentHash": "sha256:
|
|
26
|
+
"contentHash": "sha256:73fca6258f066f80776eae0a3abc2cd23c09e2de77ba0d47d24681ac25e7b0e5",
|
|
27
27
|
"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; and teach a coding agent to work in a project through Fabric (fabric-mcp, fabric_whoami, claim and release), with Claude Code session hooks.",
|
|
28
28
|
"author": {
|
|
29
29
|
"name": "PassionCode.ai",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"name": "passioncode",
|
|
63
63
|
"displayName": "PassionCode.ai",
|
|
64
64
|
"repo": "passioncode-ai/passioncode",
|
|
65
|
-
"ref": "v0.2.
|
|
65
|
+
"ref": "v0.2.40",
|
|
66
66
|
"commit": null,
|
|
67
|
-
"version": "0.2.
|
|
67
|
+
"version": "0.2.40",
|
|
68
68
|
"via": "this repository",
|
|
69
69
|
"skills": [
|
|
70
70
|
"setting-up-passioncode",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
],
|
|
73
73
|
"legacyPluginIds": [],
|
|
74
74
|
"legacyMarketplaces": [],
|
|
75
|
-
"contentHash": "sha256:
|
|
75
|
+
"contentHash": "sha256:8528f506d1851ce653316227bfa9d25db9cffa54a8e0b4ebccb2eb272338eaf2",
|
|
76
76
|
"description": "Set up and check PassionCode.ai on a computer with one command (setting-up-passioncode), the organisation's working rules for every contributor's agent (working-in-passioncode), and a once-a-day check that keeps the PassionCode.ai set current.",
|
|
77
77
|
"author": {
|
|
78
78
|
"name": "PassionCode.ai",
|
|
@@ -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; and teach a coding agent to work in a project through Fabric (fabric-mcp, fabric_whoami, claim and release), with Claude Code session hooks.",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.51.1",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "PassionCode.ai",
|
|
9
9
|
"url": "https://passioncode.ai/"
|
|
@@ -5,9 +5,9 @@ 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.
|
|
8
|
+
version: "0.51.1"
|
|
9
9
|
contract-version: "0.1.0"
|
|
10
|
-
contract-commit: "
|
|
10
|
+
contract-commit: "e6c4fc16b415eec3190dd34d924d269405359dc9"
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
# Adapting projects to Fabric
|
|
@@ -76,7 +76,7 @@ Use exactly:
|
|
|
76
76
|
|
|
77
77
|
- contract version `0.1.0`;
|
|
78
78
|
- repository `https://github.com/passioncode-ai/fabric-agent-contract`;
|
|
79
|
-
- commit `
|
|
79
|
+
- commit `e6c4fc16b415eec3190dd34d924d269405359dc9`.
|
|
80
80
|
|
|
81
81
|
This is the default for new bundles. When checking an issued legacy bundle, preserve its
|
|
82
82
|
explicit supported lock and use that exact clean checkout. Never silently upgrade or
|
|
@@ -218,9 +218,9 @@ not a connected provider.
|
|
|
218
218
|
If the agent has a human stop (a choice, an approval, a confirmation) or emits `notify: true`
|
|
219
219
|
events, propose its operator channel (`fabric-operator-channel/0.1`, OC-11) to the operator once,
|
|
220
220
|
now, as [the operator channel and the repository standard](references/operator-channel-and-repository.md)
|
|
221
|
-
describes: the operator's four steps, the answer recorded and never asked again,
|
|
222
|
-
token and enabling the channel
|
|
223
|
-
skips this step.
|
|
221
|
+
describes: the operator's four steps, the answer recorded and never asked again, the bot and the
|
|
222
|
+
token left to the person, and enabling the channel to the operator's decision (on the page or
|
|
223
|
+
relayed, DEC-0121). An agent with neither stops nor notify events skips this step.
|
|
224
224
|
|
|
225
225
|
## The repository around the provider
|
|
226
226
|
|
|
@@ -245,8 +245,26 @@ Report:
|
|
|
245
245
|
Never summarize the outcome as “Fabric-compatible” unless all required admission gates
|
|
246
246
|
passed against a real provider and the project binding is valid.
|
|
247
247
|
|
|
248
|
-
##
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
248
|
+
## Agent pages open only in Fabric Dashboards
|
|
249
|
+
|
|
250
|
+
The operator's rule (2026-10-24) for every page of an agent or a local Fabric service, in any host: a
|
|
251
|
+
link in an answer or a notification, `<tool> dashboard`, a completion message, a page the agent opens
|
|
252
|
+
itself. Hand over the `open_link` the `fabric-dashboards` MCP's `link` tool returns for the exact
|
|
253
|
+
registered service key (`list_services`, never guessed) and the page's path; open it only with the
|
|
254
|
+
host's `open` and `fallback=never`. Never `open <url>`, `open -a Safari`, `xdg-open`,
|
|
255
|
+
`webbrowser.open` or `shell.openExternal` aimed at the agent's pages. A browser only on a confirmed
|
|
256
|
+
`not_installed` host; an installed host that failed to open is reported, never replaced by HTTP.
|
|
257
|
+
Links carry no token or login code.
|
|
258
|
+
|
|
259
|
+
The agent's `AGENTS.md` carries this as its dashboard rule block, and its checks run the adapter's link gate
|
|
260
|
+
(`scripts/check_dashboard_link.py` from this skill's own directory; it is not copied into the project) on every
|
|
261
|
+
completion and notification action before delivery:
|
|
262
|
+
[dashboard links](references/dashboard-links.md) has the block, the gate's input and the remote case.
|
|
263
|
+
Headless agents need no dashboard.
|
|
264
|
+
|
|
265
|
+
## An agent with a page and no service descriptor
|
|
266
|
+
|
|
267
|
+
A local page no service descriptor names cannot open in Fabric Dashboards. Never open it in a browser
|
|
268
|
+
instead: make the agent a `fabric-service/0.1` service with `building-fabric-services` (the descriptor,
|
|
269
|
+
the well-known document, the login-code routes and a declared dashboard), and until that lands file a
|
|
270
|
+
board row for it and say the page waits on it.
|
|
@@ -5,6 +5,19 @@ an existing Fabric service dashboard to a person. This also applies to generated
|
|
|
5
5
|
agent instructions and completion messages. Headless agents need no dashboard;
|
|
6
6
|
API origins, external docs and OAuth links are not dashboard actions.
|
|
7
7
|
|
|
8
|
+
The rule (the operator's, 2026-10-24): every page of an agent or a local Fabric
|
|
9
|
+
service opens only in Fabric Dashboards, never in Safari, Dia, Chrome or any
|
|
10
|
+
other browser, unless Fabric Dashboards is confirmed not installed.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- Resolve, then hand over
|
|
15
|
+
- The block a generated AGENTS.md carries
|
|
16
|
+
- An agent with a page and no service descriptor
|
|
17
|
+
- Device and channel
|
|
18
|
+
- Portable output gate
|
|
19
|
+
- Degradation
|
|
20
|
+
|
|
8
21
|
## Resolve, then hand over
|
|
9
22
|
|
|
10
23
|
1. Discover the target computer and exact registered `service.id.instance`.
|
|
@@ -20,9 +33,12 @@ API origins, external docs and OAuth links are not dashboard actions.
|
|
|
20
33
|
compatible host resolver or report the limitation, not presumed absence.
|
|
21
34
|
4. A request for a link opens nothing. A request to open uses the host `open`
|
|
22
35
|
tool/approved opener, which starts or focuses the existing Fabric Dashboards
|
|
23
|
-
and reuses the service view
|
|
24
|
-
permits one only for confirmed absence. Discover schema support
|
|
25
|
-
`open` implementations may silently fall back on failure and are
|
|
36
|
+
and reuses the service view, with `fallback=never`: it forbids a browser.
|
|
37
|
+
`if_absent` permits one only for confirmed absence. Discover schema support
|
|
38
|
+
first: older `open` implementations may silently fall back on failure and are
|
|
39
|
+
not strict. Never
|
|
40
|
+
`open <url>`, `open -a Safari`, `xdg-open`, `start <url>`, `webbrowser.open`
|
|
41
|
+
or `shell.openExternal` aimed at the service's pages.
|
|
26
42
|
5. An installed host that failed to open is **not absent**. Report the failure;
|
|
27
43
|
do not silently launch HTTP in a browser, a second server, `npm run dev`, or
|
|
28
44
|
another standalone dashboard. A stopped backend stays on its host status/Start
|
|
@@ -31,6 +47,40 @@ API origins, external docs and OAuth links are not dashboard actions.
|
|
|
31
47
|
not page readiness, a successful login, or a completed job. Links carry no
|
|
32
48
|
bearer tokens or login codes. The host handles dashboard authentication.
|
|
33
49
|
|
|
50
|
+
## The block a generated AGENTS.md carries
|
|
51
|
+
|
|
52
|
+
An agent with a page carries this block in its `AGENTS.md` (its `CLAUDE.md` reads
|
|
53
|
+
it through `@AGENTS.md`), beside its browser rule, and its completion and
|
|
54
|
+
notification renderers follow it:
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
## Pages open only in Fabric Dashboards
|
|
58
|
+
|
|
59
|
+
Every page of this agent (its dashboard, a job, an approval, a report) opens in
|
|
60
|
+
Fabric Dashboards, never in a browser. Resolve the registered service key with
|
|
61
|
+
the fabric-dashboards MCP (`list_services`, never guessed) and hand over the
|
|
62
|
+
`open_link` its `link` tool returns for the page's path; to open it, call the
|
|
63
|
+
host's `open` with `fallback=never`. Never `open <url>`, `open -a Safari`,
|
|
64
|
+
`xdg-open`, `start <url>`, `webbrowser.open` or `shell.openExternal` on this
|
|
65
|
+
agent's pages. A browser only when `host_status` confirms `not_installed`; an
|
|
66
|
+
installed host that failed to open is reported, not replaced by HTTP. Links
|
|
67
|
+
carry no token or login code. Every completion and notification action passes
|
|
68
|
+
the Fabric Agent Adapter's link gate before delivery: `check_dashboard_link.py`
|
|
69
|
+
in its `building-fabric-services/scripts`, run from that skill's directory;
|
|
70
|
+
where it cannot run, the action is compared by hand and the check is NOT_RUN.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The project's checks run the gate below on each renderer's action, and a test
|
|
74
|
+
holds a raw-HTTP primary action beside an available host refused.
|
|
75
|
+
|
|
76
|
+
## An agent with a page and no service descriptor
|
|
77
|
+
|
|
78
|
+
Fabric Dashboards opens only a page a service descriptor names. An agent that
|
|
79
|
+
serves a local page without one cannot be opened there, and a browser is not the
|
|
80
|
+
workaround. Make it a `fabric-service/0.1` service (`building-fabric-services`:
|
|
81
|
+
the descriptor, the well-known document, the login-code routes and a declared
|
|
82
|
+
dashboard); until that lands, file a board row for it and say the page waits on it.
|
|
83
|
+
|
|
34
84
|
## Device and channel
|
|
35
85
|
|
|
36
86
|
A custom scheme opens on the device receiving it. A phone's localhost is not the
|
|
@@ -90,5 +140,8 @@ or instructions alone do not prove all final answers from every agent are filter
|
|
|
90
140
|
|
|
91
141
|
Syntax is owned by Fabric Dashboards and `@passioncode-ai/fabric-service-host`:
|
|
92
142
|
[ADR-0005](https://github.com/passioncode-ai/fabric-dashboards/blob/51a7a80acf42781d7bec304cc87c655d48cc309b/docs/adr/0005-service-links.md).
|
|
93
|
-
The gate accepts
|
|
94
|
-
|
|
143
|
+
The gate accepts only the service form, `fabric-dashboards://service/SERVICE_ID.INSTANCE`
|
|
144
|
+
with at most one `path`; since 0.51.0 it refuses the legacy `open?service=` form, as contract
|
|
145
|
+
DEC-0123 (PL-1, checker rule `FAC-SEM-143`) and its vectors do. A host that still returns the
|
|
146
|
+
legacy form fails the gate: report it as an installed host that did not open the page. The gate
|
|
147
|
+
does not generate links or redefine the Fabric wire contract.
|
|
@@ -26,9 +26,12 @@ bare `/command` in a group is not addressed), and a channel nobody receives on i
|
|
|
26
26
|
|
|
27
27
|
Record the answer (`accepted`, `declined` or `later`) in the agent's state and in its conformance
|
|
28
28
|
report, and do not ask again; an agent that serves `surfaces.operatorChannel` also shows it as
|
|
29
|
-
`proposal` in its status document. Creating the bot
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
`proposal` in its status document. Creating the bot and putting its token into the secret store
|
|
30
|
+
stay the person's (a `secret` step, contract DEC-0121 AP-4): never create the bot, or ask for or
|
|
31
|
+
store the token's value. Enabling the channel, and removing a webhook found on its token, are the
|
|
32
|
+
operator's decision, taken by them on the agent's page or relayed to its agent in their own words
|
|
33
|
+
with `_meta.decision` (OC-1, OC-2, DEC-0121 AP-2); never enable it on your own account. The default
|
|
34
|
+
pin carries DEC-0034 and DEC-0035: a served status document is
|
|
32
35
|
checked against the pinned `schemas/operator-channel-status.schema.json`; the channel's runtime
|
|
33
36
|
rules have no probe rule here yet, so report them `NOT_RUN`. An agent with neither stops nor notify
|
|
34
37
|
events skips this.
|
|
@@ -49,6 +52,11 @@ For a PassionCode.ai repository, the agent's repository follows the organization
|
|
|
49
52
|
- an `AGENTS.md` that opens with the template's *Read first* block and closes with *After work*,
|
|
50
53
|
and a `CLAUDE.md` whose first line is `@AGENTS.md`.
|
|
51
54
|
|
|
55
|
+
Whoever owns the repository, an agent with a page gets the dashboard rule block in its `AGENTS.md`
|
|
56
|
+
(pages open only in Fabric Dashboards; the block is in `references/dashboard-links.md`), and its
|
|
57
|
+
checks run the adapter's link gate (`scripts/check_dashboard_link.py` from the skill's own directory, not a copy in
|
|
58
|
+
the project).
|
|
59
|
+
|
|
52
60
|
org-index `scripts/check_format.py` reports 0 findings for it before it is called done. An agent
|
|
53
61
|
someone builds for themselves is not a PassionCode.ai repository: its licence is its owner's
|
|
54
62
|
choice, nothing about it is published or listed by the organization, and none of these files is
|
|
@@ -22,10 +22,10 @@ import fabric_secrets as _secrets # noqa: E402 - the contract's credential dete
|
|
|
22
22
|
|
|
23
23
|
CONTRACT_VERSION = "0.1.0"
|
|
24
24
|
CONTRACT_REPOSITORY = "https://github.com/passioncode-ai/fabric-agent-contract"
|
|
25
|
-
CONTRACT_COMMIT = "
|
|
25
|
+
CONTRACT_COMMIT = "e6c4fc16b415eec3190dd34d924d269405359dc9"
|
|
26
26
|
# #region supported-contract-revisions — docs: README.md#contract-pin
|
|
27
27
|
# Only this declaration may name a legacy revision in live files.
|
|
28
|
-
SUPPORTED_CONTRACT_COMMITS = (CONTRACT_COMMIT, "87d384ffce2757081b7ab227e5dad3dddd08328f", "0a4ce773c4b9e6bec40c6387eb3f988af7152c0e", "e742016dc396aa31e5a13a893489e43f15786c69", "bfa9a67aa3c6cb808c093e7d83cd59799f1ee7d0", "c55f2d5a11c9a0197e958e87212fca7ae1154769", "07042181bfae2a481aa0da1a5651f24c76669c48", "d8146cfb0a1c74fc6432284c4356bb0c864b37b5", "82e163665e156a08aa3b92e4711015582c06162c", "1636fa97262f4a26e2086572d540c2ee701e0010", "f00a7685e3861c27f7899c033fb850a145a1708f", "a046f57cf46ea9e3da57ff8ce6a3ed4d26d8774b", "fe55fc67cba1a9e34a736da7d148d4fe2a8fbfa0", "b291bf09e0a9f9fd3c16cf540832cd021203b7d1", "0cacd08b0e95b6abf131eae1206b60792138bc3c", "2eb91c00e852d9c31d804310d38fad91589fcbac", "8e49fbd5fbbf230e32c1969cd24ac3c22422f0a5", "a83bec6b47776af688402c18efec507143061f68", "52da526d7cc1e063d74c5b520dbc03d0ace15246", "78b2da018d2c4bd9ac1bde1dc3b7f1a110a175f5", "623bf61358c339cb10297807b3f024b5d9f1f327", "23f9fda4c05f8a3852246ee98d4f2adf74ed0875", "9091d3d6606b0c4b5591a38c3674356a01fd7f55", "df55c8c54a23251342a7ee57ba95642b7eb39e61", "2ce392291c6668598d12cd38327e24696b5ca15c")
|
|
28
|
+
SUPPORTED_CONTRACT_COMMITS = (CONTRACT_COMMIT, "a3a66eb0052043847f6556348e37d34ca873a629", "52c7d798b9f4eb784eb4e29e717038a8912c759d", "2f020a696453ae299b123517f14957f6a1354379", "87d384ffce2757081b7ab227e5dad3dddd08328f", "0a4ce773c4b9e6bec40c6387eb3f988af7152c0e", "e742016dc396aa31e5a13a893489e43f15786c69", "bfa9a67aa3c6cb808c093e7d83cd59799f1ee7d0", "c55f2d5a11c9a0197e958e87212fca7ae1154769", "07042181bfae2a481aa0da1a5651f24c76669c48", "d8146cfb0a1c74fc6432284c4356bb0c864b37b5", "82e163665e156a08aa3b92e4711015582c06162c", "1636fa97262f4a26e2086572d540c2ee701e0010", "f00a7685e3861c27f7899c033fb850a145a1708f", "a046f57cf46ea9e3da57ff8ce6a3ed4d26d8774b", "fe55fc67cba1a9e34a736da7d148d4fe2a8fbfa0", "b291bf09e0a9f9fd3c16cf540832cd021203b7d1", "0cacd08b0e95b6abf131eae1206b60792138bc3c", "2eb91c00e852d9c31d804310d38fad91589fcbac", "8e49fbd5fbbf230e32c1969cd24ac3c22422f0a5", "a83bec6b47776af688402c18efec507143061f68", "52da526d7cc1e063d74c5b520dbc03d0ace15246", "78b2da018d2c4bd9ac1bde1dc3b7f1a110a175f5", "623bf61358c339cb10297807b3f024b5d9f1f327", "23f9fda4c05f8a3852246ee98d4f2adf74ed0875", "9091d3d6606b0c4b5591a38c3674356a01fd7f55", "df55c8c54a23251342a7ee57ba95642b7eb39e61", "2ce392291c6668598d12cd38327e24696b5ca15c")
|
|
29
29
|
# #endregion supported-contract-revisions
|
|
30
30
|
INTEROP_KEY = "https://fabric.passioncode.ai/agent-contract/extensions/interop/0.1"
|
|
31
31
|
MCP_REVISION = "2026-07-28"
|
|
@@ -74,7 +74,9 @@ def login_path(path):
|
|
|
74
74
|
|
|
75
75
|
def safe_path(path):
|
|
76
76
|
return (isinstance(path, str) and path.startswith('/') and not path.startswith('//')
|
|
77
|
-
and len(path) <= 2048 and not re.search(r'[\\\x00-\x1f\x7f]', path)
|
|
77
|
+
and len(path) <= 2048 and not re.search(r'[\\\x00-\x1f\x7f]', path)
|
|
78
|
+
# JavaScript's whitespace (\s), which the contract's parseDashboardsLink refuses in a page (DEC-0123)
|
|
79
|
+
and not re.search('[ \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]', path))
|
|
78
80
|
|
|
79
81
|
|
|
80
82
|
def check(data):
|
|
@@ -87,11 +89,11 @@ def check(data):
|
|
|
87
89
|
require(not re.search(r'[\\\x00-\x20\x7f]', native + http), 'unsafe_url')
|
|
88
90
|
deep, plain = urlsplit(native), urlsplit(http)
|
|
89
91
|
require(deep.scheme == 'fabric-dashboards' and not deep.username and not deep.password and not deep.port and not deep.fragment, 'invalid_deep_link')
|
|
90
|
-
query
|
|
91
|
-
if deep.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
# An empty query is no fields: Python 3.9's strict parse_qs raises on '' where 3.11 and later answer {}.
|
|
93
|
+
query = parse_qs(deep.query, keep_blank_values=True, strict_parsing=True) if deep.query else {}
|
|
94
|
+
# DEC-0123 PL-1: only the service form; the legacy open?service= link is refused (FAC-SEM-143, since 0.51.0).
|
|
95
|
+
require(deep.netloc == 'service', 'not_service_link')
|
|
96
|
+
require(deep.path in ('/' + service, '/' + service + '/') and set(query) <= {'path'}, 'wrong_service_or_parameter')
|
|
95
97
|
require('path' not in query or len(query['path']) == 1, 'duplicate_path')
|
|
96
98
|
page = query.get('path', [None])[0]
|
|
97
99
|
require(page is None or safe_path(page), 'unsafe_path')
|
|
@@ -14,10 +14,10 @@ license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
|
|
|
14
14
|
compatibility: Python 3.9+ or Node.js 20+ for the kits (Node.js 22+ for a Linux service's instance lock); the probe needs Python 3.9+. launchd steps are macOS-only; Linux services install a systemd user unit and Windows ones a per-user Scheduled Task with the kits' writers. Dashboard handoff optionally uses Fabric Dashboards MCP link/host_status/open; without it, report unresolved host capability. The contract checkout is optional.
|
|
15
15
|
metadata:
|
|
16
16
|
author: PassionCode.ai
|
|
17
|
-
version: "0.
|
|
17
|
+
version: "0.51.1"
|
|
18
18
|
contract-version: "0.1.0"
|
|
19
19
|
extension: "fabric-service/0.1"
|
|
20
|
-
extension-commit: "
|
|
20
|
+
extension-commit: "e6c4fc16b415eec3190dd34d924d269405359dc9"
|
|
21
21
|
---
|
|
22
22
|
|
|
23
23
|
# Building Fabric services
|
|
@@ -70,9 +70,10 @@ Answer before writing code, and record the answers in the project README:
|
|
|
70
70
|
| Caller | Surface | Why |
|
|
71
71
|
|---|---|---|
|
|
72
72
|
| Another agent on this machine | MCP `2026-07-28`, `streamable-http`, at `/mcp` on the service origin, token in a header | one process serves every session; stdio-per-session once left twenty stray servers on this machine |
|
|
73
|
-
| The operator or a script | a CLI: `<tool> service status\|start\|stop\|restart`, `<tool> dashboard
|
|
73
|
+
| The operator or a script | a CLI: `<tool> service status\|start\|stop\|restart`, `<tool> dashboard` (opens only in Fabric Dashboards, below), `<tool> doctor --json` | every verb delegates to launchd and the well-known document, never to its own process table |
|
|
74
74
|
| A remote agent | A2A `1.0` over HTTPS, or MCP behind an authenticated gateway | loopback reachability is not authorization |
|
|
75
|
-
|
|
|
75
|
+
| An A2A peer on this computer | `surfaces.a2a` names a public Agent Card, served without the token; its interface URLs are loopback (DEC-0122); the kits read it, serving one is FAA-10 | the card carries no credential, process member or required Fabric extension |
|
|
76
|
+
| The dashboard page | same-origin REST under `/api`, session cookie plus a custom request header; every button on it also a tool on the MCP surface (Step 5) | the CSRF defence all four existing dashboards use |
|
|
76
77
|
|
|
77
78
|
Read [the surfaces and auth reference](references/surfaces-and-auth.md) when wiring
|
|
78
79
|
MCP registration into a client config, the login flow or the CSRF header.
|
|
@@ -248,6 +249,16 @@ and declare it with `extensions=fs.dashboard_extension()`. Read
|
|
|
248
249
|
declaration and how to upgrade a dashboard built before the kit: an upgrade you may make yourself,
|
|
249
250
|
which the plugin's session-start notice offers in a repository that owns the service.
|
|
250
251
|
|
|
252
|
+
**Every button has a tool** (`fabric-actions/0.1`, contract DEC-0121 AP-1). Each action the page lets a
|
|
253
|
+
person take is a tool on the MCP surface with the same effect, checks, audit record and an idempotency key,
|
|
254
|
+
registered with `server.add_tool(tool, handler, action={id, title, tool, gate})` (`gate` is `none`, `relayed`
|
|
255
|
+
or `human` with its `humanStep`) and declared with `build_well_known(actions=server.action_table())` under
|
|
256
|
+
`extensions/actions/0.1`. A `relayed` action called by the operator's own agent with their decision in
|
|
257
|
+
`_meta.decision` is the operator's act: never answer it "operator session required" or send them to the page.
|
|
258
|
+
A service adopts the relayed gate once Fabric's hub forwards decisions (CT-125), as the contract says; until then its tools
|
|
259
|
+
answer as today. Read the interop reference's *Actions* section for when to adopt, the gate, its hooks and its
|
|
260
|
+
refusals.
|
|
261
|
+
|
|
251
262
|
**Say what the agent uses** (`fabric-connections/0.1`, DEC-0096) so Fabric Dashboards draws its chain: the other
|
|
252
263
|
agents, models, connectors, stores and channels, each with its state, from
|
|
253
264
|
`connections_extension()` / `connectionsExtension()` in `fabric_connections`. Never a credential in it, never a call
|
|
@@ -283,10 +294,15 @@ python3 <skill-dir>/scripts/check_service.py <id>[.<instance>]
|
|
|
283
294
|
It reports `PASS`, `FAIL` or `NOT_RUN` per rule (descriptor, port claim, well-known
|
|
284
295
|
shape, identity, latency, Host/Origin/cross-site guards, loopback bind, token file,
|
|
285
296
|
events auth and shape, single-use login, state outside code, instance lock, plist,
|
|
286
|
-
launchd pid equals answering pid, `dashboard.declared` (ED-9),
|
|
297
|
+
launchd pid equals answering pid, `dashboard.declared` (ED-9), `well-known.actions` (DEC-0121),
|
|
298
|
+
`dashboard.actions-declared` (`NOT_RUN` when a dashboard declares no actions), `dashboard.opens-in-host` (no browser
|
|
299
|
+
opener aimed at the service's pages in its checkout; `--repo PATH` names the checkout, and a service installed
|
|
300
|
+
from a release folder needs it), and the `interop.*` rules:
|
|
287
301
|
manifest link, capability list, tools equal to the manifest, job tools, unknown job, trace
|
|
288
|
-
propagation, event trace pairs,
|
|
289
|
-
|
|
302
|
+
propagation, event trace pairs, `interop.action-tools` (every declared action's tool is served), `well-known.a2a` and
|
|
303
|
+
`a2a.card` (DEC-0122: the card is fetched without the token and its interfaces are never called; the surfaces
|
|
304
|
+
reference's *A2A for remote agents* section), and
|
|
305
|
+
`board.responder` for a service that declares the project board) and exits 1 on any `FAIL`. A `NOT_RUN` is not a pass;
|
|
290
306
|
name it in the report. A service with a dashboard also runs the layout probe,
|
|
291
307
|
`node <skill-dir>/scripts/check_dashboard_layout.mjs --service <id>` (WebKit at 360, 480, 768
|
|
292
308
|
and 1280 px; needs Playwright, else `NOT_RUN` and exit 3: nothing was measured).
|
|
@@ -328,7 +344,8 @@ first commit:
|
|
|
328
344
|
- an `AGENTS.md` that opens with the template's *Read first* block and closes with *After work*,
|
|
329
345
|
and a `CLAUDE.md` whose first line is `@AGENTS.md`.
|
|
330
346
|
|
|
331
|
-
|
|
347
|
+
Whoever owns the repository, an agent with a page gets the dashboard rule block in its `AGENTS.md`
|
|
348
|
+
(below). org-index `scripts/check_format.py` reports 0 findings for it before it is called done. **An agent
|
|
332
349
|
someone builds for themselves is not a PassionCode.ai repository:** its licence is its owner's
|
|
333
350
|
choice, nothing about it is published or listed by the organization, and none of these files is
|
|
334
351
|
required of it, though the verified MCP quick start is still how anyone learns to drive it.
|
|
@@ -418,8 +435,29 @@ the probe table verbatim with every `NOT_RUN` explained; the lock and kill-9 res
|
|
|
418
435
|
with pids; and the one next command. Never call a service conformant while the probe
|
|
419
436
|
reports a `FAIL`.
|
|
420
437
|
|
|
421
|
-
##
|
|
438
|
+
## Agent pages open only in Fabric Dashboards
|
|
439
|
+
|
|
440
|
+
The operator's rule (2026-10-24) for every page of an agent or a local Fabric service, in any host: a link in an
|
|
441
|
+
answer or a notification, `<tool> dashboard`, a completion message, a page the agent opens itself.
|
|
442
|
+
|
|
443
|
+
1. Resolve the exact registered service key (`id.instance`) with the `fabric-dashboards` MCP (`list_services`);
|
|
444
|
+
never guess it from a project name or a port.
|
|
445
|
+
2. Hand over the `open_link` its `link` tool returns for the service and the page's path, as the primary action.
|
|
446
|
+
3. To open it, use the host's `open` with `fallback=never`. Never `open <url>`, `open -a Safari`, `xdg-open`,
|
|
447
|
+
`start <url>`, `webbrowser.open` or `shell.openExternal` aimed at the service's pages.
|
|
448
|
+
4. A browser only on a confirmed `not_installed` host (`host_status`); an installed host that failed to open is
|
|
449
|
+
reported, never replaced by HTTP.
|
|
450
|
+
5. Links carry no token or login code: the host signs in.
|
|
451
|
+
|
|
452
|
+
Run `scripts/check_dashboard_link.py` (from this skill's own directory; it is not copied into the project) on an
|
|
453
|
+
action before it is printed or opened, and have the project's checks run it for every completion and notification
|
|
454
|
+
renderer. The generated `AGENTS.md` carries the rule as its dashboard
|
|
455
|
+
rule block; [dashboard links](references/dashboard-links.md) has the block, the gate's input and the remote case. The
|
|
456
|
+
probe's `dashboard.opens-in-host` fails a tracked file that opens the dashboard with a browser opener. Headless agents
|
|
457
|
+
need no dashboard.
|
|
458
|
+
|
|
459
|
+
## An agent with a page and no service descriptor
|
|
422
460
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
and
|
|
461
|
+
A local page no service descriptor names cannot open in Fabric Dashboards. Never open it in a browser instead:
|
|
462
|
+
make the agent a `fabric-service/0.1` service (this skill: the descriptor, the well-known document, the login-code
|
|
463
|
+
routes and a declared dashboard), and until that lands file a board row for it and say the page waits on it.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* fabric-dashboard-kit@1.1.
|
|
1
|
+
/* fabric-dashboard-kit@1.1.5 · Fabric's button (Fabric Agent Contract DEC-0040, FB-1…FB-8, FL-1…FL-6)
|
|
2
2
|
Load it same-origin, after fabric-dashboard.css, with the service it opens Fabric on:
|
|
3
3
|
<script src="fabric-button.js" defer data-service="example-agent.default" data-service-name="Example Agent"
|
|
4
4
|
data-project="project-a" data-project-name="Project A"></script>
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
(function (root) {
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var VERSION = '1.1.
|
|
14
|
+
var VERSION = '1.1.5';
|
|
15
15
|
var COOKIE = 'fabric_button';
|
|
16
16
|
var GET_FABRIC = 'https://passioncode.ai/fabric';
|
|
17
17
|
var ABSENT_AFTER_MS = 1500;
|
|
@@ -165,13 +165,14 @@
|
|
|
165
165
|
absent: 'Fabric \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d. \u0421\u043a\u0430\u0447\u0430\u0439\u0442\u0435 \u0435\u0433\u043e \u043d\u0430' }
|
|
166
166
|
};
|
|
167
167
|
|
|
168
|
-
/** The labels for a page language, each one replaced by a non-blank string the page gives (data-label-*)
|
|
168
|
+
/** The labels for a page language, each one replaced by a non-blank string the page gives (data-label-*) that keeps
|
|
169
|
+
the word Fabric: the visible label stays inside the name and each item (DEC-0124, WCAG 2.2 SC 2.5.3). */
|
|
169
170
|
function labelsFor(lang, overrides) {
|
|
170
171
|
var base = LABELS[/^ru(-|$)/i.test(String(lang || '')) ? 'ru' : 'en'];
|
|
171
172
|
var out = {};
|
|
172
173
|
Object.keys(base).forEach(function (k) {
|
|
173
174
|
var own = overrides ? overrides[k] : undefined;
|
|
174
|
-
out[k] = typeof own === 'string' && own.trim() ? own.trim() : base[k];
|
|
175
|
+
out[k] = typeof own === 'string' && own.trim() && own.indexOf('Fabric') >= 0 ? own.trim() : base[k];
|
|
175
176
|
});
|
|
176
177
|
return out;
|
|
177
178
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* fabric-dashboard-kit@1.1.
|
|
1
|
+
/* fabric-dashboard-kit@1.1.5 · fabric-dashboard/0.1 (Fabric Agent Contract DEC-0036)
|
|
2
2
|
A Fabric service dashboard shown inside a host pane: usable from 360 CSS px up, navigation always
|
|
3
3
|
reachable, wide content in its own scroll box, one vertical scroller, appearance from the host.
|
|
4
4
|
Copy this file next to fabric-dashboard.js; do not edit it in place. Put the page's own rules in
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* fabric-dashboard-kit@1.1.
|
|
1
|
+
/* fabric-dashboard-kit@1.1.5 · fabric-dashboard/0.1 (Fabric Agent Contract DEC-0036)
|
|
2
2
|
Load it same-origin with <script src="fabric-dashboard.js" defer></script>: no inline script, no
|
|
3
3
|
eval, nothing from a CDN. It applies the host's appearance (ED-6, ED-8), folds navigation that
|
|
4
4
|
does not fit into a More menu (ED-3), makes wide boxes keyboard-reachable (ED-4) and keeps
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
'use strict';
|
|
9
9
|
|
|
10
10
|
var KIT = 'fabric-dashboard-kit';
|
|
11
|
-
var VERSION = '1.1.
|
|
11
|
+
var VERSION = '1.1.5';
|
|
12
12
|
/* fabric-dashboard-kit:theme-ids:begin */
|
|
13
13
|
var THEMES = ['graphite', 'fabric', 'paper', 'forest', 'ocean', 'ember', 'contrast'];
|
|
14
14
|
/* fabric-dashboard-kit:theme-ids:end */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fabric-dashboard-kit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"profile": "fabric-dashboard/0.1",
|
|
5
5
|
"decision": "DEC-0036",
|
|
6
6
|
"declarationKey": "https://fabric.passioncode.ai/agent-contract/extensions/dashboard/0.1",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"contrast"
|
|
16
16
|
],
|
|
17
17
|
"files": {
|
|
18
|
-
"fabric-dashboard.css": "
|
|
19
|
-
"fabric-dashboard.js": "
|
|
20
|
-
"fabric-button.js": "
|
|
18
|
+
"fabric-dashboard.css": "cc7a96fa2c5eeb03d113e7a543ed88d43ce78c2808c411de199ea0fc6d55b957",
|
|
19
|
+
"fabric-dashboard.js": "5df01193c590a1d8aa82a521954902fecf2d7f655df482165f90d7291b00087f",
|
|
20
|
+
"fabric-button.js": "e945b3252f9a246826d06dbe7bd4be66e82d539a33728c3d3043fd61d4cbd681",
|
|
21
21
|
"themes.json": "511839f1a1a83eb37fadfd132791474497d5c28c5091700b9aa31ad076e359b5"
|
|
22
22
|
},
|
|
23
23
|
"history": {
|
|
@@ -49,6 +49,11 @@
|
|
|
49
49
|
"fabric-dashboard.css": "c9367aad04c662547aec61e67e10b99d80ec1d1c4618b4473bc2db882d80db94",
|
|
50
50
|
"fabric-dashboard.js": "5f157d185d9b04e9a11e680399503bbae924520ed0c112b734bf59fc8ee6bb49",
|
|
51
51
|
"fabric-button.js": "2906d3533635df2ed1f2f071abe00238d30ea81666ff34c3456b376526b66859"
|
|
52
|
+
},
|
|
53
|
+
"1.1.5": {
|
|
54
|
+
"fabric-dashboard.css": "cc7a96fa2c5eeb03d113e7a543ed88d43ce78c2808c411de199ea0fc6d55b957",
|
|
55
|
+
"fabric-dashboard.js": "5df01193c590a1d8aa82a521954902fecf2d7f655df482165f90d7291b00087f",
|
|
56
|
+
"fabric-button.js": "e945b3252f9a246826d06dbe7bd4be66e82d539a33728c3d3043fd61d4cbd681"
|
|
52
57
|
}
|
|
53
58
|
}
|
|
54
59
|
}
|
|
@@ -101,7 +101,9 @@ version is still read and never written; delete it once its messages are past th
|
|
|
101
101
|
- Replace the example knowledge with the product's own, and run real past questions through it ([practices](../../../creating-fabric-agents/references/practices.md#judges-and-evals), *Judges
|
|
102
102
|
and evals*): count handoffs and read a sample of replies.
|
|
103
103
|
- Show spend: `fabric_usage.usage_report` over the ledger, or `fabric_openrouter.totals`.
|
|
104
|
-
- One decision per message id holds in one process
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
- One decision per message id holds in one process. Each process reads `decisions.jsonl` once and keeps the index in
|
|
105
|
+
memory, so a second process writing the same state folder is not seen: a service runs one instance per context with
|
|
106
|
+
`fabric_context.hold_context_instance` (Node: `holdContextInstance`) and points `stateDir` at that instance's data
|
|
107
|
+
folder, so a second copy for the same context exits 75 and an organization's copy keeps its own folder
|
|
108
|
+
([one instance per context](../../references/estate-record.md#one-instance-per-context-the-helper)).
|
|
107
109
|
- Set the outbox's retention and schedule `prune`.
|
package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/board.md
CHANGED
|
@@ -86,7 +86,9 @@ from `leaseExpiresAt`.
|
|
|
86
86
|
why not; a refusal accepts the request and completes it `failed_known` with that sentence, so the requester learns it
|
|
87
87
|
and the request does not bounce. A redacted body is refused the same way. The kit never hands a body to a model, a
|
|
88
88
|
shell or a tool; what the handler does with an admitted body (and the checks it needs before a model, a tool or a
|
|
89
|
-
spend sees it) is the service's own responsibility.
|
|
89
|
+
spend sees it) is the service's own responsibility. The kit's responder reads no approval or mandate from a message in
|
|
90
|
+
0.51.0: a request from the operator's own Project may carry `mandate/1` (DEC-0125 MD-3), and a handler acts on it only
|
|
91
|
+
once the kit reads it (FAA-135).
|
|
90
92
|
|
|
91
93
|
## Effects, observation, evidence and the reply
|
|
92
94
|
|
|
@@ -96,7 +96,8 @@ service. Load it after the stylesheet, with ids only:
|
|
|
96
96
|
- **Words (since 1.1.4):** English by default, Russian when the page says `<html lang="ru">` (any `ru-*`). The page
|
|
97
97
|
sets its own with `data-label-chat` and `data-label-session` (`{name}` is the service or the project),
|
|
98
98
|
`data-label-open` (the button's accessible name) and `data-label-absent` (the sentence before the link to
|
|
99
|
-
passioncode.ai/fabric).
|
|
99
|
+
passioncode.ai/fabric). Each keeps the word *Fabric* (since 1.1.5, contract DEC-0124, WCAG 2.2 SC 2.5.3 Label in
|
|
100
|
+
Name): an attribute without it, or a blank one, keeps the built-in words; `FabricButton.labelsFor(lang, overrides)` returns
|
|
100
101
|
what a page gets. Product names stay in English in every language.
|
|
101
102
|
- **Placement and look (FB-2, FB-3):** bottom-right (bottom-left right-to-left), 16 px off and clear of the safe
|
|
102
103
|
area, above the sticky chrome and below dialogs; the page keeps its height plus 16 px free at the end of the
|
|
@@ -136,7 +137,7 @@ and promises nothing else.
|
|
|
136
137
|
```bash
|
|
137
138
|
node <skill-dir>/scripts/check_dashboard_layout.mjs --service <id>[.<instance>] # signs in with a login code
|
|
138
139
|
node <skill-dir>/scripts/check_dashboard_layout.mjs http://127.0.0.1:<port>/dashboard
|
|
139
|
-
python3 <skill-dir>/scripts/check_service.py <id> # dashboard.declared (ED-9)
|
|
140
|
+
python3 <skill-dir>/scripts/check_service.py <id> # dashboard.declared (ED-9), dashboard.actions-declared, dashboard.opens-in-host
|
|
140
141
|
```
|
|
141
142
|
|
|
142
143
|
The layout probe renders the page in WebKit (Safari's engine; `--browser chromium` on request) at
|