@hasna/skills 0.1.63 → 0.1.66

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 (42) hide show
  1. package/README.md +61 -22
  2. package/bin/index.js +2120 -670
  3. package/bin/mcp.js +555 -249
  4. package/bin/migrate.js +229 -33
  5. package/bin/server.js +1542 -327
  6. package/bin/worker.js +716 -207
  7. package/dist/cli/commands/registry-reconcile.d.ts +2 -0
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.js +682 -276
  10. package/dist/lib/agent-sync.d.ts +26 -6
  11. package/dist/lib/auth-store.d.ts +37 -0
  12. package/dist/lib/config.d.ts +51 -0
  13. package/dist/lib/home-census.d.ts +4 -0
  14. package/dist/lib/home-migration.d.ts +8 -9
  15. package/dist/lib/native-storage.d.ts +29 -1
  16. package/dist/lib/portable-skills.d.ts +49 -6
  17. package/dist/lib/pull.d.ts +31 -0
  18. package/dist/lib/registry-reconcile.d.ts +114 -0
  19. package/dist/lib/registry-types.d.ts +9 -0
  20. package/dist/lib/registry.d.ts +7 -4
  21. package/dist/lib/remote-client.d.ts +118 -1
  22. package/dist/lib/remote-registry.d.ts +26 -0
  23. package/dist/lib/revision.d.ts +29 -0
  24. package/dist/lib/run-routing.d.ts +60 -0
  25. package/dist/sdk/index.js +14412 -13338
  26. package/dist/server/app.d.ts +4 -1
  27. package/dist/server/config.d.ts +12 -2
  28. package/dist/server/rows.d.ts +2 -1
  29. package/dist/server/skills-api.d.ts +108 -6
  30. package/dist/server/sqlite-store.d.ts +20 -3
  31. package/dist/server/store-fixtures.d.ts +6 -0
  32. package/dist/server/store.d.ts +31 -5
  33. package/dist/server/types.d.ts +98 -3
  34. package/dist/storage.d.ts +1 -1
  35. package/dist/storage.js +57 -2
  36. package/migrations/postgres/0004_hosted_pins.sql +28 -0
  37. package/migrations/postgres/0005_revision_tombstone_registry.sql +37 -0
  38. package/migrations/postgres/0005_tag_projection.sql +36 -0
  39. package/migrations/sqlite/0004_hosted_pins.sql +21 -0
  40. package/migrations/sqlite/0005_revision_tombstone_registry.sql +18 -0
  41. package/migrations/sqlite/0005_tag_projection.sql +25 -0
  42. package/package.json +3 -2
@@ -0,0 +1,36 @@
1
+ -- The hosted tag surface (T7) queries tag membership from this relational
2
+ -- projection of skills_registry.tags_json, in both dialects with one identical
3
+ -- shape. SQLite cannot index json_each() over the JSON column, and Postgres
4
+ -- rows written by the current path hold the array text inside a jsonb scalar
5
+ -- (bun's driver binds a JS string against a ::jsonb cast as a JSON string), so
6
+ -- neither dialect can serve an indexed array-expansion query directly. The
7
+ -- projection turns tag membership into a plain indexed lookup: the PRIMARY KEY
8
+ -- serves (org_id, slug) maintenance and the org_tag index serves (org_id, tag)
9
+ -- filters. The write paths keep it in step; the backfill below covers rows
10
+ -- that predate it.
11
+ -- No composite FK to skills_registry: the schema-parity parser cannot
12
+ -- represent a multi-column FK identically in both dialects, and every write
13
+ -- path here maintains the projection explicitly (publish/update replace its
14
+ -- rows, the tombstone purge removes them with the row), so the constraint
15
+ -- would be redundancy.
16
+ CREATE TABLE skills_tags (
17
+ org_id text NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
18
+ slug text NOT NULL,
19
+ tag text NOT NULL,
20
+ PRIMARY KEY (org_id, slug, tag)
21
+ );
22
+
23
+ CREATE INDEX skills_tags_org_tag_idx ON skills_tags (org_id, tag);
24
+
25
+ -- Backfill every existing row's tags. tags_json may be a real array or,
26
+ -- because of the jsonb-scalar write path, the array text inside a jsonb
27
+ -- string; both shapes are expanded here.
28
+ INSERT INTO skills_tags (org_id, slug, tag)
29
+ SELECT DISTINCT r.org_id, r.slug, t.tag
30
+ FROM skills_registry r
31
+ CROSS JOIN LATERAL jsonb_array_elements_text(
32
+ CASE WHEN jsonb_typeof(r.tags_json) = 'array' THEN r.tags_json
33
+ WHEN jsonb_typeof(r.tags_json) = 'string' THEN (r.tags_json #>> '{}')::jsonb
34
+ ELSE '[]'::jsonb END
35
+ ) AS t(tag)
36
+ WHERE t.tag <> '';
@@ -0,0 +1,21 @@
1
+ -- Hosted pins: the cloud becomes a source of truth for what the user selected.
2
+ --
3
+ -- SQLite dialect of 0004_hosted_pins. Read the Postgres file for the why; the
4
+ -- only differences here are the documented dialect mapping:
5
+ -- * timestamptz -> text holding a UTC ISO-8601 instant (pinned_at).
6
+ -- * jsonb -> text holding JSON (metadata_json).
7
+ --
8
+ -- No RLS: the tenant fence on this table is the org-scoped predicate in the
9
+ -- store, exactly as it is for skills_registry and skills_bundles. RLS was
10
+ -- armed in 0003 only for the run-output tables, where a worker path writes
11
+ -- outside a tenant context; pins are written and read only by the API under
12
+ -- the requesting principal's org, so there is no context-less writer to fence.
13
+
14
+ CREATE TABLE IF NOT EXISTS skills_pins (
15
+ org_id text NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
16
+ principal text NOT NULL,
17
+ slug text NOT NULL,
18
+ pinned_at text NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
19
+ metadata_json text NOT NULL DEFAULT '{}',
20
+ PRIMARY KEY (org_id, principal, slug)
21
+ );
@@ -0,0 +1,18 @@
1
+ -- SQLite dialect of 0005_revision_tombstone_registry.
2
+ --
3
+ -- Hand-written parallel of migrations/postgres/0005_revision_tombstone_registry.sql. Read
4
+ -- that file for why the registry gains revision_id/revision_number (immutable revision
5
+ -- identity), the optimistic-concurrency guard, and the tombstone contract; the rationale
6
+ -- is not repeated here, only the dialect differences are.
7
+ --
8
+ -- Deliberate, shape-preserving dialect differences (same set as 0001):
9
+ -- * timestamptz -> text holding a UTC ISO-8601 instant.
10
+ --
11
+ -- SQLite requires a non-null literal DEFAULT for a NOT NULL ADD COLUMN; the '' default is
12
+ -- the legacy-row marker the store's backfill (src/lib/revision.ts) replaces with a
13
+ -- content sha on first open, exactly as on Postgres.
14
+
15
+ ALTER TABLE skills_registry ADD COLUMN revision_id text NOT NULL DEFAULT '';
16
+ ALTER TABLE skills_registry ADD COLUMN revision_number integer NOT NULL DEFAULT 0;
17
+ ALTER TABLE skills_registry ADD COLUMN tombstoned_at text;
18
+ ALTER TABLE skills_registry ADD COLUMN tombstone_purge_after text;
@@ -0,0 +1,25 @@
1
+ -- The hosted tag surface (T7) queries tag membership from this relational
2
+ -- projection of skills_registry.tags_json, in both dialects with one identical
3
+ -- shape. SQLite cannot index json_each() over the JSON column, so the tag
4
+ -- lookup becomes an indexed read here: the PRIMARY KEY serves (org_id, slug)
5
+ -- maintenance and the org_tag index serves (org_id, tag) filters. The write
6
+ -- paths keep it in step; the backfill below covers rows that predate it.
7
+ -- No composite FK to skills_registry: the schema-parity parser cannot
8
+ -- represent a multi-column FK identically in both dialects, and every write
9
+ -- path here maintains the projection explicitly (publish/update replace its
10
+ -- rows, the tombstone purge removes them with the row), so the constraint
11
+ -- would be redundancy.
12
+ CREATE TABLE skills_tags (
13
+ org_id text NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
14
+ slug text NOT NULL,
15
+ tag text NOT NULL,
16
+ PRIMARY KEY (org_id, slug, tag)
17
+ );
18
+
19
+ CREATE INDEX skills_tags_org_tag_idx ON skills_tags (org_id, tag);
20
+
21
+ -- Backfill every existing row's tags from the stored JSON array.
22
+ INSERT INTO skills_tags (org_id, slug, tag)
23
+ SELECT DISTINCT r.org_id, r.slug, je.value
24
+ FROM skills_registry r, json_each(r.tags_json) AS je
25
+ WHERE je.value <> '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.1.63",
3
+ "version": "0.1.66",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -74,6 +74,7 @@
74
74
  "license": "Apache-2.0",
75
75
  "devDependencies": {
76
76
  "@types/bun": "latest",
77
+ "@types/node": "25.2.3",
77
78
  "@types/react": "^18.2.0",
78
79
  "bun-types": "1.3.14",
79
80
  "react-devtools-core": "^7.0.1",
@@ -82,7 +83,7 @@
82
83
  "dependencies": {
83
84
  "@aws-sdk/client-ecs": "^3.1079.0",
84
85
  "@aws-sdk/client-s3": "^3.1079.0",
85
- "@hasna/events": "0.1.7",
86
+ "@hasna/events": "0.1.16",
86
87
  "@modelcontextprotocol/sdk": "^1.26.0",
87
88
  "chalk": "^5.3.0",
88
89
  "commander": "^12.1.0",