@zibby/skill-ids 0.1.0 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +71 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/skill-ids",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Single authoritative Zibby skill-id map (zero-dep leaf). The one source of truth for well-known skill ids — every consumer (agent-workflow, core, skills, backend, templates) imports it, so the ids can never drift.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/index.js CHANGED
@@ -83,6 +83,14 @@ export const SKILL_IDS = Object.freeze({
83
83
  // `linkedin` — publish to the connected PERSONAL LinkedIn profile
84
84
  // (linkedinSkill → linkedin_publish_post).
85
85
  LINKEDIN: 'linkedin',
86
+ // `hubspot` — HubSpot CRM (contacts/companies/deals/tickets/notes/tasks/
87
+ // feedback_submissions/custom) over the HubSpot REST API. OAuth 2.0
88
+ // integration: the user connects HubSpot in Integrations; the backend
89
+ // (handlers/hubspot.js) auto-refreshes the access token and the skill
90
+ // resolves it via resolveIntegrationToken('hubspot'). Declaring SKILLS.HUBSPOT
91
+ // gates deploy on a connected HubSpot (backend SKILL_INTEGRATION_MAP:
92
+ // 'hubspot' → INTEGRATIONS.HUBSPOT). Backed by hubspotSkill in @zibby/skills.
93
+ HUBSPOT: 'hubspot',
86
94
  // `chat_notify` — provider-agnostic chat notification. Routes to Slack OR Lark
87
95
  // depending on which integration the project has connected. Backend renders
88
96
  // this as "Slack OR Lark" via {any:[...]}.
@@ -142,9 +150,67 @@ export const SKILL_IDS = Object.freeze({
142
150
 
143
151
  /**
144
152
  * SKILL_META — pure-data static metadata per id (toggleable / requiresIntegration
145
- * / tier / display / binary). STUB for now: Phase 2 of the skills-platform
146
- * migration populates this and points each skill object's `meta` at
147
- * SKILL_META[id]. Exported empty today so P2 can fill it without another wiring
148
- * change. See strategy/skills-platform-architecture.md.
153
+ * / tier / display / binary). Phase 2 of the skills-platform migration.
154
+ *
155
+ * This is the SINGLE SOURCE OF TRUTH for a skill's toggle metadata. Every one of
156
+ * the five toggle surfaces derives from here:
157
+ * 1. engine gate — the skill object sets `meta = SKILL_META[id]` by
158
+ * reference (@zibby/skills), and claude-strategy's
159
+ * isToggleableOff() reads `skill.meta.toggleable`.
160
+ * 2. backend registry — a build-emitted JSON manifest (backend cannot ESM-
161
+ * import() this ESM leaf: it's CJS, this isn't a backend
162
+ * dep, and the .jsc control-plane can't dynamic-import) —
163
+ * see backend/scripts/gen-skill-meta.mjs →
164
+ * backend/src/services/skill-meta.json.
165
+ * 3. cloud marketplace sync, 4. self-host deploy, 5. self-host catalog list —
166
+ * all flow from the backend registry (#2).
167
+ *
168
+ * Shape per id:
169
+ * { toggleable, requiresIntegration, tier, display:{ name, description },
170
+ * binary?:{ name, version, sha256 } }
171
+ *
172
+ * A skill absent from this map is "not toggleable" (the default for everything
173
+ * except the two no-connection toggleable skills). Ids are append-only (see the
174
+ * governance note above). Objects are DEEP-frozen so a skill object that shares a
175
+ * `meta` reference cannot mutate the static map.
176
+ *
177
+ * NOTE (byte-identical contract): `display.name`/`display.description` MUST equal
178
+ * the strings the backend previously hardcoded in NO_INTEGRATION_TOGGLEABLE_SKILLS
179
+ * (skill-integrations.js) — the backend now derives that map from here, so any
180
+ * edit changes the marketplace/status display. See strategy/skills-platform-architecture.md.
149
181
  */
150
- export const SKILL_META = Object.freeze({});
182
+ const deepFreeze = (o) => {
183
+ if (o && typeof o === 'object' && !Object.isFrozen(o)) {
184
+ Object.values(o).forEach(deepFreeze);
185
+ Object.freeze(o);
186
+ }
187
+ return o;
188
+ };
189
+
190
+ export const SKILL_META = deepFreeze({
191
+ 'codebase-memory': {
192
+ toggleable: true,
193
+ requiresIntegration: false,
194
+ tier: 2,
195
+ display: {
196
+ name: 'Codebase memory',
197
+ description:
198
+ 'Code-graph + semantic index over the checked-out repo (architecture map, '
199
+ + 'dependency/call-path tracing, change detection). Runs locally on the '
200
+ + 'agent image — no connection required.',
201
+ },
202
+ },
203
+ 'code-scan': {
204
+ toggleable: true,
205
+ requiresIntegration: false,
206
+ tier: 2,
207
+ display: {
208
+ name: 'Code scan',
209
+ description:
210
+ 'Stack-smart deterministic linter (oxlint for JS/TS, …). Detects the repo\'s '
211
+ + 'stack and runs the matching baked linter over the changed code, feeding '
212
+ + 'structured findings to the reviewer. Runs locally on the agent image — '
213
+ + 'no connection required.',
214
+ },
215
+ },
216
+ });