@crossdelta/platform-sdk 0.25.7 → 0.26.1

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.
@@ -10,47 +10,19 @@ generators/
10
10
  ├── service.md # Main service generator instructions
11
11
  ├── code-style.md # Code style, formatting, naming conventions
12
12
  ├── testing.md # Testing rules and patterns
13
+ ├── natural-language.md # Natural-language prompt pipeline
13
14
  ├── hono-bun.md # Hono with Bun runtime specifics
14
15
  ├── hono-node.md # Hono with Node.js runtime specifics
15
16
  └── nest.md # NestJS framework specifics
16
17
  ```
17
18
 
18
- ## How Instructions Are Loaded
19
-
20
- Instructions are configured in `package.json` under `generatorConfig.docs`:
21
-
22
- ```json
23
- {
24
- "generatorConfig": {
25
- "docs": {
26
- "base": ["service.md", "code-style.md", "testing.md"],
27
- "frameworks": {
28
- "hono": { "bun": "hono-bun.md", "node": "hono-node.md" },
29
- "nest": "nest.md"
30
- }
31
- }
32
- }
33
- }
34
- ```
19
+ ## How Instructions Are Served
35
20
 
36
- **Load Order:**
37
- 1. **Base docs** - Always loaded (service.md, code-style.md, testing.md)
38
- 2. **Framework-specific** - Based on `serviceType` and `packageManager`
39
- 3. **Workspace instructions** - every one of `CLAUDE.md`, `AGENTS.md`, `.github/copilot-instructions.md`, `docs/ai-guidelines.md` that the workspace carries. Missing files are skipped; the token budget is split across the ones found.
21
+ The pf MCP server lists the `.md` files in this directory as the resource `docs://generators` and serves each one as `docs://generators/<name>` (`packages/pf-mcp/src/resources/generator-docs.ts`; the directory is read by `listGeneratorDocs` in `cli/src/core/facade/index.ts`). The build copies the directory to `bin/docs/generators` (`build:copy` in `package.json`). An agent reads the file it needs; nothing is merged or loaded in a fixed order.
40
22
 
41
23
  ## Adding New Generators
42
24
 
43
25
  To add instructions for a new framework:
44
26
 
45
27
  1. Create `<framework>.md` in this directory
46
- 2. Add to `generatorConfig.docs.frameworks` in `package.json`
47
- 3. Follow the existing format from `hono-bun.md` or `nest.md`
48
-
49
- ## Template Variables
50
-
51
- The following variables are replaced at runtime:
52
-
53
- | Variable | Description |
54
- |----------|-------------|
55
- | `{{scope}}` | Package scope (e.g., `@orderboss`) |
56
- | `{{AVAILABLE_CONTRACTS}}` | Auto-generated list of existing contracts |
28
+ 2. Follow the existing format from `hono-bun.md` or `nest.md`
@@ -53,7 +53,7 @@ Rules for working with the CloudEvents package and event handlers.
53
53
 
54
54
  ## NATS Migrations
55
55
 
56
- See [Infrastructure](infrastructure.md) for migration conventions (`infra/migrations/`).
56
+ Stream migrations live in `infra/migrations/`.
57
57
 
58
58
  ## Publishing Checklist
59
59
 
@@ -61,7 +61,6 @@ See [Infrastructure](infrastructure.md) for migration conventions (`infra/migrat
61
61
  2. Update `CHANGELOG.md`
62
62
  3. **Push to remote before publishing** — npm publish reads from the repo
63
63
  4. Trigger workflow: `gh workflow run publish-packages.yml -f package=cloudevents`
64
- 5. After publishing: the `sync-templates` pre-commit hook auto-updates downstream `package.json` references
65
64
 
66
65
  ## Distributed Tracing
67
66
 
@@ -295,6 +295,20 @@ jobs:
295
295
  pattern: changed-*
296
296
  path: .artifacts
297
297
 
298
+ # download-artifact puts each matching artifact into its own `changed-<scope>/` directory only
299
+ # when it matches several. A single match is extracted straight into `.artifacts/`, where no
300
+ # later step looks for it: the scope's image tag then came from GHCR instead of its marker, and
301
+ # the Studio smoke check and client broadcast were skipped (stage run 38151120673, 11.10.2026).
302
+ - name: Normalize change marker layout
303
+ run: |
304
+ if [ -f .artifacts/metadata.json ]; then
305
+ SHORT=$(jq -er '.shortName' .artifacts/metadata.json)
306
+ mkdir -p ".artifacts/changed-${SHORT}"
307
+ for marker_file in metadata.json scope.txt; do
308
+ if [ -f ".artifacts/${marker_file}" ]; then mv ".artifacts/${marker_file}" ".artifacts/changed-${SHORT}/"; fi
309
+ done
310
+ fi
311
+
298
312
  - name: Resolve scope image tags
299
313
  id: resolve_scope_tags
300
314
  shell: bash
@@ -371,6 +385,7 @@ jobs:
371
385
  # mid-update: DigitalOcean finishes the resize server-side anyway, while Pulumi never writes
372
386
  # the result back and leaves a stack lock and a pending operation behind.
373
387
  - name: Pulumi up
388
+ id: pulumi-up
374
389
  uses: pulumi/actions@v7
375
390
  timeout-minutes: 15
376
391
  with:
@@ -417,3 +432,8 @@ jobs:
417
432
  done
418
433
  curl "${curl_opts[@]}" "${STUDIO_URL}/health" || exit 1
419
434
 
435
+ # The topic carries no `realtime:` prefix: the REST endpoint adds it, and a client subscribed to
436
+ # `system:deploy` listens on `realtime:system:deploy`. With the prefix spelled out the message
437
+ # went to `realtime:realtime:system:deploy`, a channel nobody listened on (listener log, stage,
438
+ # 11.10.2026). `-f` makes a refused broadcast fail the command, so the warning below can fire.
439
+
@@ -26,6 +26,14 @@ jobs:
26
26
  - name: Run Linter
27
27
  run: bun run --if-present lint
28
28
 
29
+ - name: Component manifest
30
+ run: |
31
+ git fetch --depth=1 origin main
32
+ bun run --if-present manifest:check
33
+
34
+ - name: Pattern manifest
35
+ run: bun run --if-present patterns:check
36
+
29
37
  test:
30
38
  runs-on: ubuntu-latest
31
39
  env:
@@ -16,9 +16,9 @@ on:
16
16
  default: all
17
17
  required: true
18
18
 
19
+ # id-token: write only where it is used: the publish job sets it itself.
19
20
  permissions:
20
21
  contents: read
21
- id-token: write
22
22
 
23
23
  jobs:
24
24
  determine-packages:
@@ -211,6 +211,25 @@ jobs:
211
211
  fi
212
212
  echo "✅ Workspace template complete"
213
213
 
214
+ # The kit is published for other people's repositories: nothing of this one may ride along. The check packs
215
+ # the package as npm receives it and scans every text file against the kit's built-in patterns.
216
+ - name: Setup Bun for the leak check
217
+ if: matrix.package.name == 'jackherd' || matrix.package.name == '@crossdelta/agent-kit'
218
+ # Pinned to a commit: this job holds id-token: write, which npm Trusted Publishing accepts.
219
+ uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
220
+ with:
221
+ bun-version-file: package.json
222
+
223
+ - name: Leak check on the jackherd tarball
224
+ if: matrix.package.name == 'jackherd'
225
+ working-directory: ${{ matrix.package.dir }}
226
+ run: bun scripts/check-package-leaks.ts
227
+
228
+ - name: Leak check on the agent-kit shell tarball
229
+ if: matrix.package.name == '@crossdelta/agent-kit'
230
+ working-directory: ${{ matrix.package.dir }}
231
+ run: bun ../jackherd/scripts/check-package-leaks.ts .
232
+
214
233
  - name: Publish to npm
215
234
  working-directory: ${{ matrix.package.dir }}
216
235
  run: |
@@ -25,7 +25,7 @@ You are assisting in TypeScript-first monorepos using modern TypeScript tooling
25
25
 
26
26
  - **Test consumers**: When changing a shared package (`packages/*`), run tests in **all consuming services**, not just the package itself. Changes to shared code have blast radius.
27
27
  - **Push before publish**: Always push commits to remote before triggering npm publish workflows. The CI reads from the repo, not your local machine.
28
- - **Pre-commit hooks exist**: The repo has a `sync-templates` hook that auto-updates downstream `package.json` refs after version bumps. Never bypass with `--no-verify`.
28
+ - **Pre-commit hooks**: Never bypass them with `--no-verify`.
29
29
  - **Capture lessons**: When a convention or pitfall emerges, propose updating a scoped `.claude/rules/` file. Ask before creating new files. Keep `CLAUDE.md` project-agnostic; domain-specific rules go in scoped files with `paths:`.
30
30
 
31
31
  ## Monorepo Awareness
@@ -52,6 +52,10 @@ regardless of which file is open, because that cost is paid on every turn.
52
52
  Code style and testing conventions are not rules here: the `pf` generators carry their own, and they
53
53
  load whenever the generator writes code.
54
54
 
55
+ ## jackherd
56
+
57
+ Skills, agents and general rules under `.claude/` come from `jackherd` and are listed in `.jackherd/lock.json`. Project values (languages, plan directory, models, checks) live in `.jackherd/config.json`. Update with `pf agents sync`; a conflicting local edit lands as `<file>.kit-new`. Put project knowledge into `.claude/project/<skill>.md` or a rule beside `.claude/rules/kit/`, so the kit files stay updatable. `pf plans` shows the plan progress of the current sprint.
58
+
55
59
  ## Key Packages
56
60
 
57
61
  Installed from npm, not vendored into this repo. Read their APIs in `node_modules/`, not from memory.
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@crossdelta/cloudevents": "^0.10.0",
11
- "@crossdelta/infrastructure": "^0.16.0",
11
+ "@crossdelta/infrastructure": "^0.18.1",
12
12
  "{{scope}}/contracts": "workspace:*",
13
13
  "@pulumi/digitalocean": "^4.55.0",
14
14
  "@pulumi/kubernetes": "^4.21.0",
@@ -17,6 +17,14 @@
17
17
  "commands": {
18
18
  "pulumi": {
19
19
  "cwd": "infra"
20
+ },
21
+ "agents": {
22
+ "command": "bunx jackherd",
23
+ "description": "jackherd: init, sync, check, plans"
24
+ },
25
+ "plans": {
26
+ "command": "bunx jackherd plans",
27
+ "description": "Live view of the sprint's lanes and their plan progress"
20
28
  }
21
29
  },
22
30
  "paths": {
@@ -45,6 +53,7 @@
45
53
  "@biomejs/biome": "2.3.7",
46
54
  "@crossdelta/platform-sdk": "latest",
47
55
  "dotenv-cli": "^8.0.0",
56
+ "jackherd": "latest",
48
57
  "turbo": "^2.5.6"
49
58
  },
50
59
  "packageManager": "{{packageManagerVersion}}",
@@ -89,7 +89,7 @@ Contracts are **auto-generated** when you create event handlers:
89
89
 
90
90
  ```bash
91
91
  # 1. Create service with event handler
92
- pf new hono-micro notifications --ai -d "Sends emails on order.created events"
92
+ pf new hono-micro notifications
93
93
 
94
94
  # 2. Add event (creates contract, mock, handler)
95
95
  pf cloudevents add order.created --service services/notifications
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "dependencies": {
22
22
  "@crossdelta/cloudevents": "^0.10.0",
23
- "@crossdelta/infrastructure": "^0.16.0",
23
+ "@crossdelta/infrastructure": "^0.18.1",
24
24
  "zod": "^4.0.0"
25
25
  },
26
26
  "devDependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossdelta/platform-sdk",
3
- "version": "0.25.7",
3
+ "version": "0.26.1",
4
4
  "description": "Platform toolkit for event-driven microservices — keeping code and infrastructure in lockstep.",
5
5
  "keywords": [
6
6
  "cli",
@@ -65,42 +65,6 @@
65
65
  "name": "Marcelle Hövelmanns",
66
66
  "email": "mail@hoevelmanns.io"
67
67
  },
68
- "generatorConfig": {
69
- "docs": {
70
- "base": [
71
- "service.md",
72
- "code-style.md",
73
- "testing.md"
74
- ],
75
- "frameworks": {
76
- "hono": {
77
- "bun": "hono-bun.md",
78
- "node": "hono-node.md"
79
- },
80
- "nest": "nest.md"
81
- }
82
- },
83
- "serviceTypes": {
84
- "hono": {
85
- "commandType": "hono-micro",
86
- "entryPoint": "src/index.ts",
87
- "skipFiles": [
88
- "package.json",
89
- "tsconfig.json",
90
- "Dockerfile"
91
- ]
92
- },
93
- "nest": {
94
- "commandType": "nest-micro",
95
- "entryPoint": "src/main.ts",
96
- "skipFiles": [
97
- "package.json",
98
- "tsconfig.json",
99
- "Dockerfile"
100
- ]
101
- }
102
- }
103
- },
104
68
  "scripts": {
105
69
  "dev": "tsup --watch",
106
70
  "build:copy": "cp cli/integration.collection.json bin/integration.collection.json && rm -rf bin/templates && mkdir -p bin/templates && cp -r cli/src/commands/create/workspace/templates bin/templates/workspace && cp -r cli/src/commands/create/hono-microservice/templates bin/templates/hono-microservice && cp -r cli/src/commands/create/nest-microservice/templates bin/templates/nest-microservice && mkdir -p bin/docs/generators && cp -r docs/generators/* bin/docs/generators/",
@@ -115,20 +79,15 @@
115
79
  },
116
80
  "schematics": "./dist/schematics/collection.json",
117
81
  "dependencies": {
118
- "@ai-sdk/anthropic": "^2.0.53",
119
- "@ai-sdk/openai": "^2.0.79",
120
82
  "@angular-devkit/core": "^21.0.0",
121
83
  "@crossdelta/cloudevents": "^0.10.0",
122
84
  "@crossdelta/flowcore": "^0.1.2",
123
85
  "@faker-js/faker": "^9.8.0",
124
- "@inquirer/prompts": "^7.5.0",
125
86
  "@listr2/prompt-adapter-enquirer": "^2.0.15",
126
- "ai": "^5.0.108",
127
87
  "chalk": "^5.4.1",
128
88
  "chokidar": "^5.0.0",
129
89
  "cli-table3": "^0.6.5",
130
90
  "commander": "^13.1.0",
131
- "dotenv": "^17.2.3",
132
91
  "enquirer": "^2.4.1",
133
92
  "execa": "^9.5.2",
134
93
  "fs-extra": "^11.3.0",
@@ -136,13 +95,11 @@
136
95
  "handlebars": "^4.7.8",
137
96
  "jiti": "^2.6.1",
138
97
  "listr2": "^8.3.2",
139
- "ora": "^8.2.0",
140
98
  "package-up": "^5.0.0",
141
99
  "rimraf": "^6.1.2",
142
100
  "terminal-link": "^4.0.0",
143
- "ts-morph": "^27.0.0",
144
101
  "zod": "^4.0.0",
145
- "@crossdelta/infrastructure": "^0.16.0"
102
+ "@crossdelta/infrastructure": "^0.18.1"
146
103
  },
147
104
  "peerDependencies": {
148
105
  "@nestjs/schematics": "^11.0.5",
@@ -1,33 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "title": "Service Types Configuration",
4
- "description": "Configuration for different microservice types in the Platform SDK",
5
- "type": "object",
6
- "properties": {
7
- "serviceTypes": {
8
- "type": "object",
9
- "additionalProperties": {
10
- "type": "object",
11
- "required": ["commandType", "entryPoint", "skipFiles"],
12
- "properties": {
13
- "commandType": {
14
- "type": "string",
15
- "description": "CLI command type for scaffolding (e.g., 'hono-micro', 'nest-micro')"
16
- },
17
- "entryPoint": {
18
- "type": "string",
19
- "description": "Relative path to the service entry point file"
20
- },
21
- "skipFiles": {
22
- "type": "array",
23
- "description": "Files that should not be overwritten by AI generation",
24
- "items": {
25
- "type": "string"
26
- }
27
- }
28
- }
29
- }
30
- }
31
- },
32
- "required": ["serviceTypes"]
33
- }