@synap-core/workspace-templates 0.24.0 → 0.24.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.
- package/README.md +29 -45
- package/automations/bookmark-enrichment.catalog.json +16 -0
- package/automations/github-pr-events.catalog.json +18 -0
- package/automations/ship-a-change-checks-green.catalog.json +18 -0
- package/automations/ship-a-change-checks-red.catalog.json +18 -0
- package/automations/ship-a-change-deployed.catalog.json +18 -0
- package/automations/ship-a-change-pr-merged.catalog.json +18 -0
- package/automations/ship-a-change-pr-opened.catalog.json +18 -0
- package/automations/url-bookmark-capture.catalog.json +17 -0
- package/package.json +1 -1
- package/skills/bookmark-enrichment.catalog.json +16 -0
- package/skills/mapping-the-server.catalog.json +18 -0
- package/skills/routing-to-channels.catalog.json +16 -0
package/README.md
CHANGED
|
@@ -21,10 +21,10 @@ How installs, reconciles and tiers work is in the `synap-market` skill
|
|
|
21
21
|
| Dir | Kind | Format | Published today? |
|
|
22
22
|
|---|---|---|---|
|
|
23
23
|
| `src/*.yaml` | `workspace` (and `pack`, for a suite) | Legacy workspace YAML (`meta:` plus body). A thin adapter reads it as `{kind: workspace, meta, spec}` | Yes. 31 entries, CI on every push to main |
|
|
24
|
-
| `capabilities/<key>.capability.json` | `capability` | Manifest (below). `meta` carries the listing and visibility; `spec` is the CapabilityDefinition | Yes,
|
|
25
|
-
| `skills/<slug>/` | `skill` | Either a manifest `<slug>.skill.json` (`creative-director`), or an Agent-Skills folder (`SKILL.md` plus references) with a header `skills/<slug>.catalog.json` beside it | The manifest: yes. A folder: only with its header, and only when it holds no reference files (a skill package carries no documents).
|
|
26
|
-
| `views/<slug>.view.json` | `view` | Manifest; `spec.views` in the canonical shape the CP stores (`{slug, displayName, type, config, scopeProfileSlugs}`) | Category `view`. Three today (`bookmark-views-pack`, `event-views-pack`, `task-views-pack`), moved from the old CP pack fragments on 2026-11-05. CI
|
|
27
|
-
| `automations/<slug>.automation.json` | `automation` | bridge-setup `flowDefinition` form, plus a header `automations/<slug>.catalog.json` beside it | Only with its header, and only without apply-time placeholders.
|
|
24
|
+
| `capabilities/<key>.capability.json` | `capability` | Manifest (below). `meta` carries the listing and visibility; `spec` is the CapabilityDefinition | Yes, CI on every push to main (§4) |
|
|
25
|
+
| `skills/<slug>/` | `skill` | Either a manifest `<slug>.skill.json` (`creative-director`), or an Agent-Skills folder (`SKILL.md` plus references) with a header `skills/<slug>.catalog.json` beside it | The manifest: yes. A folder: only with its header, and only when it holds no reference files (a skill package carries no documents). Headers decided by the founder on 2026-11-05: `bookmark-enrichment` and `routing-to-channels` public, `mapping-the-server` unlisted (private to the official owner); `reading-client-progress` and the parked `stellar-scf-grants-advisor` stay **staged** |
|
|
26
|
+
| `views/<slug>.view.json` | `view` | Manifest; `spec.views` in the canonical shape the CP stores (`{slug, displayName, type, config, scopeProfileSlugs}`) | Category `view`. Three today (`bookmark-views-pack`, `event-views-pack`, `task-views-pack`), moved from the old CP pack fragments on 2026-11-05. CI on every push to main |
|
|
27
|
+
| `automations/<slug>.automation.json` | `automation` | bridge-setup `flowDefinition` form, plus a header `automations/<slug>.catalog.json` beside it | Only with its header, and only without apply-time placeholders. Headers decided by the founder on 2026-11-05: `bookmark-enrichment` public; `url-bookmark-capture`, `github-pr-events` and the five `ship-a-change-*` unlisted. `mail-feed` stays **staged**: it carries two placeholders bridge-setup fills |
|
|
28
28
|
| `schema/` | | Zod manifest schema: `header.ts`, plus one body per kind (`workspace`, `capability`, `skill`, `automation`, `playbook`) | |
|
|
29
29
|
| `standards/*.standard.yaml` | | Quality standard per workspace (`pnpm eval`) | |
|
|
30
30
|
| `scripts/catalog-lib.mjs` | | **The ONE lib**: `loadCatalog` → `validateCatalog` → `diffCatalog` → `publishCatalog` | |
|
|
@@ -86,12 +86,8 @@ only when it is strictly newer than their bundle.
|
|
|
86
86
|
|
|
87
87
|
**Capability.** Edit `capabilities/<key>.capability.json`. The listing and
|
|
88
88
|
visibility go in `meta`; the definition goes in `spec`.
|
|
89
|
-
-
|
|
90
|
-
`
|
|
91
|
-
whose content must equal `spec`. Its header lives in `capability-listings.ts` and
|
|
92
|
-
`CAPABILITY_VISIBILITY` in the seeder, and must equal `meta`. Change both sides.
|
|
93
|
-
The CP tripwire `catalog-mirror.tripwire.test.ts` turns red otherwise.
|
|
94
|
-
- A **new** capability is authored here only: catalog-only files are allowed.
|
|
89
|
+
- This file is the only copy. The CP's insert-only bootstrap reads this package's
|
|
90
|
+
`capabilities/` (installed from npm); it holds no copy of its own.
|
|
95
91
|
- **A reader** is an ordinary verb that reads one link: `intent: "read_webpage"`, `metadata.readOnly: true`,
|
|
96
92
|
a required `url` parameter, and `urls: [...]` declaring the links it handles (`host[/path]`, `*.host`,
|
|
97
93
|
or `"*"`; the grammar lives in `@synap-core/types/url-read`). The pod's one read door routes by those
|
|
@@ -121,12 +117,9 @@ folder (`skill-documents`), `metadata.auto_load: true` (`skill-auto-load`), a
|
|
|
121
117
|
frontmatter name that is not `meta.slug` (`skill-slug`). Without a header the folder
|
|
122
118
|
is staged. Deciding which folders get a header (their listing and visibility) is a
|
|
123
119
|
content decision; `reading-client-progress` and `stellar-scf-grants-advisor` are
|
|
124
|
-
client-specific.
|
|
125
|
-
-
|
|
126
|
-
|
|
127
|
-
`stellar-scf-grants-advisor`) must stay byte-identical to
|
|
128
|
-
`synap-cli/templates/skills/<slug>/`, because `bridge-setup` still reads them
|
|
129
|
-
there. The guard is the CLI's `test/catalog-mirror.tripwire.test.ts`.
|
|
120
|
+
client-specific. A private (unlisted) header carries `"isPublic": false, "owner":
|
|
121
|
+
"template-owner"`. `synap bridge-setup` reads these folders from the installed
|
|
122
|
+
package; the CLI holds no copy (synap-cli#91).
|
|
130
123
|
|
|
131
124
|
**View.** Add or edit `views/<slug>.view.json`:
|
|
132
125
|
|
|
@@ -154,8 +147,9 @@ description?, triggerType, triggerConfig, flowDefinition, status }] }`, i.e. the
|
|
|
154
147
|
file minus its `metadata` notes. Refused: an apply-time placeholder
|
|
155
148
|
(`apply-time-placeholder`: an empty or `<…>` connection id, a `<…>` output channel,
|
|
156
149
|
a skill node without `skillId`) and any raw key a package cannot carry (`state`).
|
|
157
|
-
|
|
158
|
-
`
|
|
150
|
+
`synap bridge-setup` reads `bookmark-enrichment`, `mail-feed` and
|
|
151
|
+
`url-bookmark-capture` from the installed package; the CLI holds no copy
|
|
152
|
+
(synap-cli#91).
|
|
159
153
|
|
|
160
154
|
**Every kind.** Run the gate before you push:
|
|
161
155
|
|
|
@@ -350,12 +344,11 @@ wrapper `scripts/publish-official.mjs`, which uses the same lib):
|
|
|
350
344
|
| Event | What runs |
|
|
351
345
|
|---|---|
|
|
352
346
|
| PR touching the catalog | Job `validate` only: build, validate every kind, print the **offline** preview (each entry and the version the CP will derive, where knowable offline). It holds **no secret and no `id-token`**: a PR runs its own lockfile and scripts. Guarded by `scripts/publish-workflow.guard.test.ts`. |
|
|
353
|
-
| Push to `main` (or manual) | `validate`, then job `publish` (environment `catalog-publish`): a read-only preview against the live CP, then publish live `--kind
|
|
347
|
+
| Push to `main` (or manual) | `validate`, then job `publish` (environment `catalog-publish`): a read-only preview against the live CP, then publish EVERY kind live (no `--kind`), tombstones included, then npm publish, only if the `package.json` version is new on npm. |
|
|
354
348
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
only after runbook §5 A. Secrets: `SYNAP_CP_URL`, `SYNAP_CP_PUBLISH_TOKEN`
|
|
349
|
+
Main publishes every kind (founder, 2026-11-05: "remove the blocker that only do
|
|
350
|
+
workspace, we will do ALL"); the old `SYNAP_CATALOG_LIVE_KINDS` variable is not
|
|
351
|
+
read. Secrets: `SYNAP_CP_URL`, `SYNAP_CP_PUBLISH_TOKEN`
|
|
359
352
|
(a CP PAT of the `synap-official` owner; humans use `synap login`), `NPM_TOKEN`.
|
|
360
353
|
|
|
361
354
|
**One-time setup of the `catalog-publish` environment** (GitHub → synap-app →
|
|
@@ -377,18 +370,13 @@ row. A tripwire (`no-template-reseed-on-deploy-tripwire.test.ts`) guards this.
|
|
|
377
370
|
key gets 409 `OFFICIAL_CAPABILITY_KEY_RESERVED`, and the CP serves the official row
|
|
378
371
|
first for a key.
|
|
379
372
|
|
|
380
|
-
**
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
| Copy | Guard | Retires when |
|
|
389
|
-
|---|---|---|
|
|
390
|
-
| ~~CP `src/seeds/capability-templates/`, `templates/packs/`~~ | | **Retired 2026-11-05** (founder: one source). The CP seeders read the installed package; its tripwire `no-catalog-copy.tripwire.test.ts` fails on any copy |
|
|
391
|
-
| CLI `templates/skills/<5 moved>/`, `templates/automations/*.automation.json` | CLI `test/catalog-mirror.tripwire.test.ts` (byte-equal, both directions) | the CLI's pin admits a package release that ships them: `bridge-setup` already reads the installed package first, and the CLI's retirement test fails while both exist |
|
|
373
|
+
**No copies.** Since 2026-11-05 (founder: "keep one source only") neither the CP
|
|
374
|
+
nor the CLI holds a copy of any catalog file: both read this package from npm. The
|
|
375
|
+
CP's `no-catalog-copy.tripwire.test.ts` fails on a copy there. Two cross-repo guards
|
|
376
|
+
stay **local-only** (they skip when the CP is not a sibling checkout):
|
|
377
|
+
`schema/header.mirror.tripwire.test.ts` (header limits ↔ the CP `publishSchema`) and
|
|
378
|
+
`scripts/catalog-lib.columns.tripwire.test.ts` (the preview's columns and adoption
|
|
379
|
+
rule ↔ the CP publish core); their CI-safe halves are snapshots.
|
|
392
380
|
|
|
393
381
|
## 5. Founder runbook: deploy, publish, retire the copies
|
|
394
382
|
|
|
@@ -454,13 +442,10 @@ Do these in order. The runbook only names the commands; it does not run anything
|
|
|
454
442
|
`description` (the catalog's copy, which never reached the CP), `source:
|
|
455
443
|
"file-seed" → "api"` and `vendorId: null → synap-official` (the publish adopts
|
|
456
444
|
the unowned seeded row). The views themselves are byte-equal to the live rows.
|
|
457
|
-
|
|
458
|
-
8. **
|
|
459
|
-
`SYNAP_CATALOG_LIVE_KINDS=workspace,capability,skill,automation,view`. A skill
|
|
460
|
-
folder or raw automation publishes only once it has a header.
|
|
461
|
-
9. On a **brand-new, empty** CP only: run
|
|
445
|
+
CI publishes them with every other kind on the next push to main.
|
|
446
|
+
8. On a **brand-new, empty** CP only: run
|
|
462
447
|
`docker compose -f docker-compose.prod.yml run --rm control-plane pnpm seed:capabilities`
|
|
463
|
-
(and `seed:templates`) once, then step 6
|
|
448
|
+
(and `seed:templates`) once, then publish (step 6). `seed:templates` seeds
|
|
464
449
|
workspaces only: views reach an empty CP through the publish.
|
|
465
450
|
|
|
466
451
|
### B. Publish the package and retire the mirrors
|
|
@@ -480,13 +465,12 @@ Do these in order. The runbook only names the commands; it does not run anything
|
|
|
480
465
|
- the CP seeder and capability resolver (`capability-template-dir.ts`) read
|
|
481
466
|
`node_modules/@synap-core/workspace-templates/capabilities/` (done 2026-11-05;
|
|
482
467
|
`seed-templates.ts` no longer seeds packs: views publish through the door);
|
|
483
|
-
- `synap bridge-setup`
|
|
484
|
-
|
|
468
|
+
- `synap bridge-setup` reads the skill and automation files from the installed
|
|
469
|
+
package (done, synap-cli#91).
|
|
485
470
|
4. **Delete the copies and their tripwires in the same change:**
|
|
486
471
|
- CP: done 2026-11-05 (copies, listing and visibility literals, and both
|
|
487
472
|
tripwires deleted);
|
|
488
|
-
- CLI:
|
|
489
|
-
`test/catalog-mirror.tripwire.test.ts`.
|
|
473
|
+
- CLI: done (synap-cli#91).
|
|
490
474
|
|
|
491
475
|
### C. Coordinated rename (planned)
|
|
492
476
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "bookmark-enrichment-auto",
|
|
6
|
+
"name": "Bookmark enrichment (auto)",
|
|
7
|
+
"description": "When a bookmark is saved, enrich it: what the pod already connects to it first, then the page itself, classified and linked into the graph.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"bookmarks",
|
|
11
|
+
"enrichment"
|
|
12
|
+
],
|
|
13
|
+
"isPublic": true
|
|
14
|
+
},
|
|
15
|
+
"dependencies": []
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "github-pr-events",
|
|
6
|
+
"name": "GitHub pull requests and checks to dev-loop facts",
|
|
7
|
+
"description": "Reads the GitHub org webhook (one inbound source named GitHub) and records what happened as dev-loop observations: a pull request opened or reopened → dev.pr_opened, merged → dev.pr_merged, closed unmerged → dev.pr_closed; a check suite completed → ci.finished. The pod's own consumers (the merge sweeper, the Ship a change automations) take it from there.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"github",
|
|
11
|
+
"dev-loop",
|
|
12
|
+
"builder"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": false,
|
|
15
|
+
"owner": "template-owner"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "ship-a-change-checks-green",
|
|
6
|
+
"name": "CI green to Ship a change waits on the merge",
|
|
7
|
+
"description": "When a CI run on a pull request's head finishes green, grade the session's checks-green criterion and move its Ship a change step to Merged.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"dev-loop",
|
|
11
|
+
"builder",
|
|
12
|
+
"ship-a-change"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": false,
|
|
15
|
+
"owner": "template-owner"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "ship-a-change-checks-red",
|
|
6
|
+
"name": "CI red to Ship a change goes back to Building",
|
|
7
|
+
"description": "When a CI run on a pull request's head fails, grade the session's checks-green criterion as failed and send its Ship a change step back to Building (the Checks green stage's onFail).",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"dev-loop",
|
|
11
|
+
"builder",
|
|
12
|
+
"ship-a-change"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": false,
|
|
15
|
+
"owner": "template-owner"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "ship-a-change-deployed",
|
|
6
|
+
"name": "Deployed to the devbox worker dogfoods it",
|
|
7
|
+
"description": "When this pod reports a new build live (dev.deployed, recorded by the pod itself after a successful update), start a Dogfood a change run handed to the devbox worker, filed into the goal.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"dev-loop",
|
|
11
|
+
"builder",
|
|
12
|
+
"ship-a-change"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": false,
|
|
15
|
+
"owner": "template-owner"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "ship-a-change-pr-merged",
|
|
6
|
+
"name": "PR merged to Ship a change waits on the lab deploy",
|
|
7
|
+
"description": "When a PR merges: the merge sweeper (built in, backend#283) already marks the session's pr-* outcome met. This automation grades the session's `merged` criterion and moves its Ship a change step to Deployed to lab, where the person approves the deploy.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"dev-loop",
|
|
11
|
+
"builder",
|
|
12
|
+
"ship-a-change"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": false,
|
|
15
|
+
"owner": "template-owner"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "ship-a-change-pr-opened",
|
|
6
|
+
"name": "PR opened to Ship a change waits on its checks",
|
|
7
|
+
"description": "When a pull request opens with a `Pod session:` line, grade the session's pr-opened criterion and move its Ship a change step to Checks green.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"dev-loop",
|
|
11
|
+
"builder",
|
|
12
|
+
"ship-a-change"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": false,
|
|
15
|
+
"owner": "template-owner"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "automation",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "url-bookmark-capture",
|
|
6
|
+
"name": "Discord links to bookmarks",
|
|
7
|
+
"description": "Every link posted in a Discord message becomes a bookmark, with the message's context kept. No AI.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"automation",
|
|
10
|
+
"bookmarks",
|
|
11
|
+
"discord"
|
|
12
|
+
],
|
|
13
|
+
"isPublic": false,
|
|
14
|
+
"owner": "template-owner"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": []
|
|
17
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "bookmark-enrichment",
|
|
6
|
+
"name": "Bookmark enrichment",
|
|
7
|
+
"description": "Enrich a saved bookmark from the page it points to: read the link, extract its title and description, classify it, and link it to what your pod already knows.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"skill",
|
|
10
|
+
"bookmarks",
|
|
11
|
+
"enrichment"
|
|
12
|
+
],
|
|
13
|
+
"isPublic": true
|
|
14
|
+
},
|
|
15
|
+
"dependencies": []
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "mapping-the-server",
|
|
6
|
+
"name": "Mapping the server",
|
|
7
|
+
"description": "Read a Discord server's structure (categories, channels, members) and propose one reviewable graph of clients, partners, companies, people and channel bindings, accepted in a single move.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"skill",
|
|
10
|
+
"discord",
|
|
11
|
+
"crm",
|
|
12
|
+
"onboarding"
|
|
13
|
+
],
|
|
14
|
+
"isPublic": false,
|
|
15
|
+
"owner": "template-owner"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": []
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"apiVersion": "synap/v1",
|
|
3
|
+
"kind": "skill",
|
|
4
|
+
"meta": {
|
|
5
|
+
"slug": "routing-to-channels",
|
|
6
|
+
"name": "Routing to channels",
|
|
7
|
+
"description": "Route a message to the right channel, and create a channel, room or thread when one is warranted.",
|
|
8
|
+
"tags": [
|
|
9
|
+
"skill",
|
|
10
|
+
"channels",
|
|
11
|
+
"messaging"
|
|
12
|
+
],
|
|
13
|
+
"isPublic": true
|
|
14
|
+
},
|
|
15
|
+
"dependencies": []
|
|
16
|
+
}
|