@passioncode-ai/passioncode 0.1.28 → 0.1.30

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 (30) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/COMMERCIAL-LICENSE.md +1 -1
  3. package/README.md +1 -1
  4. package/family.json +2 -2
  5. package/package.json +1 -1
  6. package/payload/.claude-plugin/marketplace.json +3 -3
  7. package/payload/manifest.json +12 -12
  8. package/payload/plugins/fabric-agent-adapter/.claude-plugin/plugin.json +1 -1
  9. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/SKILL.md +9 -3
  10. package/payload/plugins/fabric-agent-adapter/skills/adapting-projects-to-fabric/scripts/adapt_project.py +39 -10
  11. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/SKILL.md +23 -10
  12. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/lifecycle.md +77 -14
  13. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/protocol.md +5 -3
  14. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/surfaces-and-auth.md +6 -0
  15. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/references/usage.md +63 -0
  16. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/check_service.py +106 -3
  17. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-interop.mjs +42 -0
  18. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric-service.mjs +317 -8
  19. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_interop.py +53 -1
  20. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/fabric_service.py +472 -15
  21. package/payload/plugins/fabric-agent-adapter/skills/building-fabric-services/scripts/sample_service.py +23 -10
  22. package/payload/plugins/fabric-agent-adapter/skills/creating-fabric-agents/SKILL.md +7 -3
  23. package/payload/plugins/observatory-log/.claude-plugin/plugin.json +1 -1
  24. package/payload/plugins/observatory-log/hooks/session-start.sh +91 -4
  25. package/payload/plugins/observatory-log/skills/explaining-changes/SKILL.md +1 -1
  26. package/payload/plugins/observatory-log/skills/handling-secrets/SKILL.md +12 -2
  27. package/payload/plugins/observatory-log/skills/tracking-resources/SKILL.md +1 -1
  28. package/payload/plugins/passioncode/.claude-plugin/plugin.json +1 -1
  29. package/payload/plugins/passioncode/skills/working-in-passioncode/SKILL.md +6 -4
  30. package/payload/plugins/passioncode/skills/working-in-passioncode/references/publishing.md +4 -3
@@ -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. 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.3"
8
+ version: "0.8.0"
9
9
  contract-version: "0.1.0"
10
- contract-commit: "2ce392291c6668598d12cd38327e24696b5ca15c"
10
+ contract-commit: "23f9fda4c05f8a3852246ee98d4f2adf74ed0875"
11
11
  ---
12
12
 
13
13
  # Creating Fabric-compatible agents
@@ -119,12 +119,16 @@ python3 <plugin-dir>/skills/adapting-projects-to-fabric/scripts/adapt_project.py
119
119
  --schema-base <immutable-base-uri>
120
120
  ```
121
121
 
122
- Pin exactly contract `0.1.0` at commit `2ce392291c6668598d12cd38327e24696b5ca15c` and
122
+ Pin exactly contract `0.1.0` at commit `23f9fda4c05f8a3852246ee98d4f2adf74ed0875` and
123
123
  read the pinned guide before implementing protocol details. If this skill is installed
124
124
  without its sibling, the scaffolder is absent: create the bundle by hand from the pinned
125
125
  contract's `docs/guides/connecting-compatible-agents.md` and mark the structural check
126
126
  `NOT_RUN` — do not reconstruct normative rules from memory.
127
127
 
128
+ This default accepts underscore capability names; a declared communications name does
129
+ not grant COM access or prove runtime admission. Existing bundles retain their explicit
130
+ supported revision and require its exact checkout; never silently migrate their lock.
131
+
128
132
  The generated placeholders are deliberate blockers; a bundle still containing one is not
129
133
  ready for admission.
130
134
 
@@ -3,7 +3,7 @@
3
3
  "name": "observatory-log",
4
4
  "displayName": "Observatory Log",
5
5
  "description": "Records what changed in a watched project at the end of every turn, and asks for the one thing a diff cannot contain: why.",
6
- "version": "0.16.0",
6
+ "version": "0.18.0",
7
7
  "license": "AGPL-3.0-only OR LicenseRef-PassionCode-Commercial",
8
8
  "author": {
9
9
  "name": "PassionCode.ai",
@@ -18,10 +18,97 @@ if [ -z "$root" ] && [ -n "${CLAUDE_PLUGIN_ROOT:-}" ]; then
18
18
  c="$n"
19
19
  done
20
20
  fi
21
+ if [ -z "$root" ] && command -v project-observatory >/dev/null 2>&1; then
22
+ # Installed by the PassionCode launcher with no `full agent install`: ask the engine.
23
+ root="$(project-observatory full-path 2>/dev/null || true)"
24
+ fi
21
25
  [ -n "$root" ] || exit 0
22
- [ -f "$root/tools/session_start.py" ] || exit 0
23
- py="${OBSERVATORY_PYTHON:-$root/.venv/bin/python}" # set by `full agent install`
24
- [ -x "$py" ] || py="$(command -v python3 2>/dev/null)"
26
+ [ -d "$root" ] || exit 0
27
+
28
+ # The engine's own virtual environment (the ancestor holding pyvenv.cfg), so the jobs
29
+ # below run the installed package and never whichever python3 is first on PATH.
30
+ venv=""; c="$root"
31
+ for _ in 1 2 3 4 5 6 7 8; do
32
+ [ -f "$c/pyvenv.cfg" ] && { venv="$c"; break; }
33
+ n="$(dirname "$c")"; [ "$n" = "$c" ] && break; c="$n"
34
+ done
35
+ py="${OBSERVATORY_PYTHON:-}" # set by `full agent install`
36
+ [ -n "$py" ] && [ -x "$py" ] || py=""
37
+ [ -z "$py" ] && [ -n "$venv" ] && [ -x "$venv/bin/python" ] && py="$venv/bin/python"
38
+ [ -z "$py" ] && [ -x "$root/.venv/bin/python" ] && py="$root/.venv/bin/python"
39
+ [ -z "$py" ] && py="$(command -v python3 2>/dev/null)"
25
40
  [ -n "$py" ] || exit 0
26
- printf '%s' "$payload" | "$py" "$root/tools/session_start.py" 2>/dev/null || true
41
+
42
+ if [ -f "$root/tools/session_start.py" ]; then
43
+ printf '%s' "$payload" | "$py" "$root/tools/session_start.py" 2>/dev/null || true
44
+ fi
45
+
46
+ # Updates that arrive by themselves (docs/runs/2026-10-05-auto-update, D8). Detached and
47
+ # rate-limited, so a session never waits for it and never fails because of it.
48
+ stamps="${XDG_STATE_HOME:-$HOME/.local/state}/project-observatory"
49
+ mkdir -p "$stamps" 2>/dev/null && chmod 700 "$stamps" 2>/dev/null
50
+ # claim NAME SECONDS: true for exactly one caller per window. The check and the stamp happen
51
+ # under one exclusive lock, so twenty sessions starting at once start one job, not twenty —
52
+ # also when the previous window has just expired (audit A20).
53
+ claim() {
54
+ "$py" - "$stamps/$1.at" "$2" <<'PYCLAIM' 2>/dev/null
55
+ import fcntl, os, sys, time
56
+ path, window = sys.argv[1], int(sys.argv[2])
57
+ fd = os.open(path + ".lock", os.O_CREAT | os.O_RDWR, 0o600)
58
+ try:
59
+ fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
60
+ except BlockingIOError:
61
+ sys.exit(1)
62
+ try:
63
+ last = os.stat(path).st_mtime
64
+ except OSError:
65
+ last = 0
66
+ if time.time() - last < window:
67
+ sys.exit(1)
68
+ with open(path, "a"):
69
+ pass
70
+ os.utime(path, None)
71
+ PYCLAIM
72
+ }
73
+ # detach LOG CMD...: a new session of its own, so ending this session or its process group
74
+ # cannot stop an install half-way (review F8).
75
+ detach() {
76
+ local log="$1"; shift
77
+ "$py" -c 'import subprocess, sys
78
+ log = open(sys.argv[1], "a")
79
+ subprocess.Popen(sys.argv[2:], stdin=subprocess.DEVNULL, stdout=log, stderr=log, start_new_session=True)' \
80
+ "$log" "$@" 2>/dev/null || true
81
+ }
82
+ if [ -f "$root/tools/maintain.py" ]; then
83
+ # 0.17.0 and later: schedule the hourly job where it is missing, or run a pass where
84
+ # this machine has no scheduler. At most every six hours.
85
+ if claim maintain-hook 21600; then
86
+ OBSERVATORY_SYSTEM_SETUP=1 detach "$stamps/maintain-hook.log" "$py" "$root/tools/maintain.py" hook
87
+ fi
88
+ else
89
+ # The bridge for engines from before 0.17.0, which carry no updater of their own:
90
+ # once a day, check; when a newer stable release exists and the person has not turned
91
+ # automatic updates off (`updates.auto` false), install it with `full update --apply`.
92
+ po=""
93
+ [ -n "$venv" ] && [ -x "$venv/bin/project-observatory" ] && po="$venv/bin/project-observatory"
94
+ [ -n "$po" ] || po="$(command -v project-observatory 2>/dev/null)"
95
+ if [ -n "$po" ] && claim update-bridge 86400; then
96
+ detach "$stamps/update-bridge.log" /bin/bash -c '
97
+ po="$1"; py="$2"
98
+ home="${OBSERVATORY_FULL_HOME:-${OBSERVATORY_HOME:-$HOME/.local/share/project-observatory-full}}"
99
+ off="$("$py" -c "import json,sys
100
+ try: d=json.load(open(sys.argv[1]))
101
+ except Exception: d={}
102
+ print(1 if (d.get(\"updates\") or {}).get(\"auto\") is False else 0)" "$home/config/settings.json" 2>/dev/null)"
103
+ [ "$off" = "1" ] && { echo "$(date -u +%FT%TZ) automatic updates are off"; exit 0; }
104
+ "$po" full update --check >/dev/null 2>&1; rc=$?
105
+ echo "$(date -u +%FT%TZ) check exit $rc"
106
+ [ "$rc" = "10" ] || exit 0
107
+ # No launchd (Linux): nothing for the update to stop, and saying so lets it run (A02).
108
+ if command -v launchctl >/dev/null 2>&1; then "$po" full update --apply
109
+ else "$po" full update --apply --writers-stopped; fi
110
+ echo "$(date -u +%FT%TZ) apply exit $?"
111
+ ' _ "$po" "$py"
112
+ fi
113
+ fi
27
114
  exit 0
@@ -15,7 +15,7 @@ description: >-
15
15
  decision with different evidence.
16
16
  license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
17
17
  metadata:
18
- version: "0.16.0"
18
+ version: "0.18.0"
19
19
  compatibility: >-
20
20
  Requires an initialized full Project Observatory installation to persist
21
21
  records. Uses its MCP server when available in the current host; the bundled
@@ -10,7 +10,7 @@ description: >-
10
10
  provider permissions or choosing a project's authentication architecture.
11
11
  license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
12
12
  metadata:
13
- version: "0.16.0"
13
+ version: "0.18.0"
14
14
  compatibility: >-
15
15
  Requires an initialized full Project Observatory installation, Python 3.11+
16
16
  and local shell access on macOS or Linux. Provider operations additionally
@@ -30,7 +30,7 @@ names. Never ask the user to paste a credential into the conversation.
30
30
  2. Select the user's initialized `OBSERVATORY_HOME`. Run
31
31
  `project-observatory full doctor`. A missing workspace
32
32
  needs the documented onboarding before secret operations.
33
- 3. Run `"$OBSERVATORY_PYTHON" "$OBSERVATORY_ROOT/tools/skill_check.py" handling-secrets 0.16.0`
33
+ 3. Run `"$OBSERVATORY_PYTHON" "$OBSERVATORY_ROOT/tools/skill_check.py" handling-secrets 0.18.0`
34
34
  (`full agent install` records that interpreter; the stock macOS `python3` is too old).
35
35
  If stale, read the installed skill once and follow its compatible commands.
36
36
  Do not turn an unavailable version check into a retry loop.
@@ -154,6 +154,16 @@ bucket's resource only. Before anything is delivered, the S3 pair must prove a
154
154
  put, a get and a delete, and must be refused a bucket list. It lands in three
155
155
  slots on stdin: `<PREFIX>_ACCESS_KEY_ID`, `<PREFIX>_SECRET_ACCESS_KEY` and
156
156
  `<PREFIX>_ENDPOINT`. A second issue rolls the same token and keeps the key id.
157
+ The lifecycle is `--expire-days` over the whole bucket (30 when nothing else is
158
+ given) plus one rule per repeatable `--lifecycle-rule PREFIX:DAYS`, for example
159
+ `--lifecycle-rule staging/:2`: objects under the prefix are deleted after DAYS,
160
+ and its unfinished multipart uploads are aborted after a day. Each run replaces
161
+ the bucket's lifecycle with exactly that set and reads every rule back. A rule
162
+ that could never fire is refused, such as a prefix kept longer than the
163
+ whole-bucket rule. To change only an existing bucket's rules, run
164
+ `cloudflare.py lifecycle --account <slug> --bucket <name> [--jurisdiction eu]
165
+ [--expire-days N] [--lifecycle-rule PREFIX:DAYS ...]`. It mints only the setup
166
+ token, never creates a bucket and never mints, rolls or delivers a key.
157
167
 
158
168
  An application that sends transactional email through Cloudflare Email Service
159
169
  gets `cloudflare.py issue --preset email-send --account <slug> --vault
@@ -15,7 +15,7 @@ description: >-
15
15
  the repository.
16
16
  license: AGPL-3.0-only OR LicenseRef-PassionCode-Commercial
17
17
  metadata:
18
- version: "0.16.0"
18
+ version: "0.18.0"
19
19
  compatibility: >-
20
20
  Requires a full Project Observatory installation with organizations.json
21
21
  configured; the observatory MCP server or its local CLI. Creating the resource
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "passioncode",
4
4
  "displayName": "PassionCode.ai",
5
- "version": "0.1.28",
5
+ "version": "0.1.30",
6
6
  "description": "The organisation's working rules for every contributor's agent (working-in-passioncode), and a once-a-day check at session start that keeps the PassionCode.ai skill set current.",
7
7
  "author": {
8
8
  "name": "PassionCode.ai",
@@ -152,16 +152,18 @@ Fabric's workspace sync, and check the published source commit before calling it
152
152
  ## 6. Licensing and the repository standard
153
153
 
154
154
  - **Every repository** is open source under the GNU AGPL-3.0, or available under a commercial
155
- license from PassionCode.ai (contact@passioncode.ai):
156
- `AGPL-3.0-only OR LicenseRef-PassionCode-Commercial` (Fabric ADR-0092; the knowledge base
157
- `licensing.md` owns it). Copyright: Siarhei Sheleh. No price or term is stated anywhere.
155
+ license from PassionCode.ai — the request form https://passioncode.ai/business/, or
156
+ commercial@passioncode.ai: `AGPL-3.0-only OR LicenseRef-PassionCode-Commercial` (Fabric
157
+ ADR-0092; the knowledge base `licensing.md` owns it). Copyright: Siarhei Sheleh. No price or
158
+ term is stated anywhere; every commercial path points to the form. Security reports stay at
159
+ contact@passioncode.ai.
158
160
  - `LICENSE`, `COMMERCIAL-LICENSE.md` and `CLA.md` are copied **byte for byte** from the knowledge
159
161
  base's `templates/`; every manifest and SKILL.md `license:` carries the expression.
160
162
  - A version released earlier keeps its licence — MIT or PolyForm Noncommercial or Internal Use —
161
163
  and the README may say which. Never write that a released version changed.
162
164
  - The README's `## License` section uses the knowledge base wording and names the earlier
163
165
  licences: "Open source under the GNU AGPL-3.0. A commercial license is available for use that
164
- does not meet the AGPL's terms — contact@passioncode.ai."
166
+ does not meet the AGPL's terms — [passioncode.ai/business](https://passioncode.ai/business/)."
165
167
  - Contributions are accepted under the repository's `CLA.md`; opening a pull request is the
166
168
  agreement, so a PR template never carries a CLA checkbox.
167
169
  - **The repository standard** (the knowledge base `repository-standard.md`): README first heading
@@ -14,7 +14,7 @@ change to a license, a manifest's `license` field, `CLA.md` or a PR template.
14
14
  ## The license, file by file
15
15
 
16
16
  Every repository is open source under the GNU AGPL-3.0, or available under a commercial
17
- license from PassionCode.ai (contact@passioncode.ai): SPDX
17
+ license from PassionCode.ai (https://passioncode.ai/business/, commercial@passioncode.ai): SPDX
18
18
  `AGPL-3.0-only OR LicenseRef-PassionCode-Commercial` (Fabric ADR-0092). The owning page is the
19
19
  knowledge base's `licensing.md`; the file list is its `repository-standard.md`, and org-index
20
20
  `scripts/check_format.py` (rules F7–F11) checks it. The three licence files are **copied byte
@@ -47,14 +47,15 @@ for byte** from the knowledge base's `templates/` — never retyped, reflowed or
47
47
  ## License
48
48
 
49
49
  Open source under the [GNU AGPL-3.0](LICENSE). A [commercial license](COMMERCIAL-LICENSE.md) is
50
- available for use that does not meet the AGPL's terms — contact@passioncode.ai.
50
+ available for use that does not meet the AGPL's terms — [passioncode.ai/business](https://passioncode.ai/business/).
51
51
  Versions before <first AGPL version> were released under <MIT | PolyForm Noncommercial or Internal Use>.
52
52
  ```
53
53
 
54
54
  - "Source-available" and the PolyForm expression describe past releases only; never state
55
55
  them as the current licence.
56
56
  - No price or term for the commercial licence is stated anywhere; point to
57
- contact@passioncode.ai.
57
+ https://passioncode.ai/business/ (commercial@passioncode.ai is the commercial contact). Security
58
+ reports stay at contact@passioncode.ai.
58
59
  - Positioning and names come from the knowledge base (`vision.md`, `principles.md` §2); do not
59
60
  restate a tagline from memory.
60
61