create-ailk 0.12.1 → 0.13.0

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 (55) hide show
  1. package/dist/module-architecture.js +27 -0
  2. package/package.json +3 -3
  3. package/templates/.env.example +23 -9
  4. package/templates/apps/api/CLAUDE.md +21 -17
  5. package/templates/apps/api/src/__tests__/factories/agent-caller.ts +98 -0
  6. package/templates/apps/api/src/__tests__/factories/in-memory-prisma.ts +321 -0
  7. package/templates/apps/api/src/__tests__/schedule-forwarded-rate-limit.test.ts +117 -0
  8. package/templates/apps/api/src/config/__tests__/hub-require-spoke-key.test.ts +39 -14
  9. package/templates/apps/api/src/config/index.ts +35 -20
  10. package/templates/apps/api/src/lib/__mocks__/prisma-client.js +3 -0
  11. package/templates/apps/api/src/lib/__mocks__/prisma.ts +14 -0
  12. package/templates/apps/api/src/lib/__tests__/agent-store.test.ts +468 -0
  13. package/templates/apps/api/src/lib/__tests__/spoke-store.test.ts +32 -2
  14. package/templates/apps/api/src/lib/agent-store.ts +521 -0
  15. package/templates/apps/api/src/lib/spoke-store.ts +13 -2
  16. package/templates/apps/api/src/middleware/__tests__/auth.bearer-path.test.ts +384 -1
  17. package/templates/apps/api/src/middleware/__tests__/auth.cookie-path.test.ts +61 -0
  18. package/templates/apps/api/src/middleware/__tests__/default-tenant.test.ts +176 -0
  19. package/templates/apps/api/src/middleware/__tests__/rate-limit.test.ts +76 -0
  20. package/templates/apps/api/src/middleware/auth.ts +219 -5
  21. package/templates/apps/api/src/middleware/default-tenant.ts +29 -8
  22. package/templates/apps/api/src/middleware/rate-limit.ts +35 -13
  23. package/templates/apps/api/src/routes/leads/__tests__/spoke.test.ts +76 -15
  24. package/templates/apps/api/src/routes/leads/index.ts +14 -6
  25. package/templates/apps/api/src/routes/project-listings/__tests__/me.test.ts +5 -6
  26. package/templates/apps/api/src/routes/project-listings/index.ts +14 -9
  27. package/templates/apps/api/src/routes/project-listings/me.ts +4 -3
  28. package/templates/apps/api/src/routes/project-listings/patch-copy.ts +7 -5
  29. package/templates/apps/api/src/routes/workspaces/__tests__/inbox-wire-schemas.test.ts +198 -0
  30. package/templates/apps/api/src/server.ts +27 -0
  31. package/templates/apps/api/src/services/__tests__/audit-log.test.ts +374 -57
  32. package/templates/apps/api/src/services/__tests__/leads-inbox.test.ts +25 -2
  33. package/templates/apps/api/src/services/__tests__/spoke-resolution.test.ts +303 -17
  34. package/templates/apps/api/src/services/audit-log.ts +278 -47
  35. package/templates/apps/api/src/services/default-tenant.ts +55 -5
  36. package/templates/apps/api/src/services/leads-inbox.ts +12 -21
  37. package/templates/apps/api/src/services/project-listings.ts +1 -21
  38. package/templates/apps/api/src/services/public-site-resolver.ts +103 -13
  39. package/templates/apps/mcp/CLAUDE.md +44 -5
  40. package/templates/apps/mcp/__tests__/parity.test.ts +53 -1
  41. package/templates/apps/mcp/__tests__/workspace-surface.test.ts +364 -0
  42. package/templates/apps/mcp/src/http-transport.ts +107 -1
  43. package/templates/apps/mcp/src/workspace-server.ts +193 -0
  44. package/templates/apps/web/.env.example +64 -37
  45. package/templates/apps/web/app/v1/[...path]/route.ts +16 -0
  46. package/templates/apps/web/lib/__tests__/relay.test.ts +515 -0
  47. package/templates/apps/web/lib/relay.ts +279 -0
  48. package/templates/apps/web/middleware.ts +5 -4
  49. package/templates/apps/web/next.config.mjs +6 -0
  50. package/templates/database/CHANGELOG.md +15 -0
  51. package/templates/database/__tests__/agents.db.test.ts +235 -0
  52. package/templates/database/auth/schema.prisma +61 -0
  53. package/templates/database/migrations/20261005120000_agents/migration.sql +84 -0
  54. package/templates/database/package.json +1 -1
  55. package/versions.json +34 -34
@@ -0,0 +1,84 @@
1
+ -- #3591 — the agent seat, step A (spec
2
+ -- docs/specs/3591-tenant-scoped-agent-auth-secure-spec.md D1).
3
+ --
4
+ -- agents (auth) — one row per agent: a stored delegate of ONE person (its
5
+ -- responsible Membership), bound to ONE workspace. It stores
6
+ -- the SHA-256 digest of the agent's key, never the key.
7
+ -- Deleting the organization, the workspace or the person's
8
+ -- membership deletes the agent; deleting the membership of
9
+ -- the person who was last shown its key sets
10
+ -- key_issued_to_membership_id null, which the guard refuses
11
+ -- until the agent is re-keyed. created_by_user_id is a plain
12
+ -- column with no foreign key, so deleting the creator does
13
+ -- not delete the agents they made for someone else.
14
+ --
15
+ -- PURELY ADDITIVE: one new enum, one new table, its indexes and four FKs (to
16
+ -- "organizations", "workspaces" and twice to "memberships"). No statement
17
+ -- touches an existing table's rows or columns, so there is no pre-assertion
18
+ -- block — this migration cannot lose a row.
19
+ --
20
+ -- Rollback: DROP TABLE "agents"; DROP TYPE "AgentPermissionLevel". Safe while
21
+ -- nothing but #3591's own code reads them.
22
+
23
+ -- CreateEnum
24
+ CREATE TYPE "AgentPermissionLevel" AS ENUM ('member');
25
+
26
+ -- CreateTable
27
+ CREATE TABLE "agents" (
28
+ "id" TEXT NOT NULL DEFAULT ('agent_'::text || (uuidv7())::text),
29
+ "organization_id" TEXT NOT NULL,
30
+ "workspace_id" TEXT NOT NULL,
31
+ "responsible_membership_id" TEXT NOT NULL,
32
+ "name" VARCHAR(80) NOT NULL,
33
+ "permission_level" "AgentPermissionLevel" NOT NULL DEFAULT 'member',
34
+ "enabled" BOOLEAN NOT NULL DEFAULT true,
35
+ "credential_hash" CHAR(64) NOT NULL,
36
+ "credential_prefix" VARCHAR(24) NOT NULL,
37
+ "last_active_at" TIMESTAMP(3),
38
+ "created_by_user_id" TEXT NOT NULL,
39
+ "key_issued_to_membership_id" TEXT,
40
+ "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
41
+ "updated_at" TIMESTAMP(3) NOT NULL,
42
+
43
+ CONSTRAINT "agents_pkey" PRIMARY KEY ("id")
44
+ );
45
+
46
+ -- CreateIndex
47
+ -- The lookup an agent's every request makes (`findAgentByKeyHash`).
48
+ CREATE UNIQUE INDEX "agents_credential_hash_key" ON "agents"("credential_hash");
49
+
50
+ -- CreateIndex
51
+ CREATE INDEX "agents_organization_id_idx" ON "agents"("organization_id");
52
+
53
+ -- CreateIndex
54
+ CREATE INDEX "agents_workspace_id_idx" ON "agents"("workspace_id");
55
+
56
+ -- CreateIndex
57
+ CREATE INDEX "agents_responsible_membership_id_idx" ON "agents"("responsible_membership_id");
58
+
59
+ -- AddForeignKey
60
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_organization_id_fkey" FOREIGN KEY ("organization_id") REFERENCES "organizations"("id") ON DELETE CASCADE ON UPDATE CASCADE;
61
+
62
+ -- AddForeignKey
63
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE ON UPDATE CASCADE;
64
+
65
+ -- AddForeignKey
66
+ -- Leaving stops the agent: removing the person's membership deletes it.
67
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_responsible_membership_id_fkey" FOREIGN KEY ("responsible_membership_id") REFERENCES "memberships"("id") ON DELETE CASCADE ON UPDATE CASCADE;
68
+
69
+ -- AddForeignKey
70
+ -- A key dies with the person who received it: SET NULL, which the guard refuses.
71
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_key_issued_to_membership_id_fkey" FOREIGN KEY ("key_issued_to_membership_id") REFERENCES "memberships"("id") ON DELETE SET NULL ON UPDATE CASCADE;
72
+
73
+ -- ADR-0031 rule 3 — agents: agent_ (registered in packages/ids/src/registry.ts;
74
+ -- this migration's path is added to migration-sync.test.ts's
75
+ -- PK_CHECK_MIGRATIONS). Each reference column carries the format CHECK of the
76
+ -- entity it names, in the exact pattern the spoke migration uses.
77
+ ALTER TABLE "agents" ALTER COLUMN "id" TYPE text COLLATE "C";
78
+ ALTER TABLE "agents" ALTER COLUMN "id" SET DEFAULT ('agent_'::text || (uuidv7())::text);
79
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_id_format" CHECK ("id" ~ '^agent_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
80
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_organization_id_format" CHECK ("organization_id" ~ '^org_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
81
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_workspace_id_format" CHECK ("workspace_id" ~ '^wksp_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
82
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_responsible_membership_id_format" CHECK ("responsible_membership_id" ~ '^member_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
83
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_key_issued_to_membership_id_format" CHECK ("key_issued_to_membership_id" ~ '^member_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
84
+ ALTER TABLE "agents" ADD CONSTRAINT "agents_created_by_user_id_format" CHECK ("created_by_user_id" ~ '^user_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$');
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@working-theory/database",
3
- "version": "0.34.1",
3
+ "version": "0.35.0",
4
4
  "license": "Apache-2.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/versions.json CHANGED
@@ -1,52 +1,52 @@
1
1
  {
2
- "@working-theory/admin-ui": "0.34.1",
3
- "@working-theory/aeo": "0.34.1",
4
- "@working-theory/agent-context": "0.34.1",
2
+ "@working-theory/admin-ui": "0.35.0",
3
+ "@working-theory/aeo": "0.35.0",
4
+ "@working-theory/agent-context": "0.35.0",
5
5
  "@working-theory/agent-contract": "0.1.0",
6
6
  "@working-theory/agent-memory": "0.0.0",
7
7
  "@working-theory/ai": "0.1.0",
8
- "@working-theory/analytics": "0.34.1",
9
- "@working-theory/api-client": "0.34.1",
8
+ "@working-theory/analytics": "0.35.0",
9
+ "@working-theory/api-client": "0.35.0",
10
10
  "@working-theory/cda-filesystem": "0.0.0",
11
- "@working-theory/cli": "0.34.1",
12
- "@working-theory/common": "0.34.1",
11
+ "@working-theory/cli": "0.35.0",
12
+ "@working-theory/common": "0.35.0",
13
13
  "@working-theory/consent": "0.1.0",
14
- "@working-theory/content-adapters": "0.34.1",
15
- "@working-theory/content-projection": "0.34.1",
16
- "@working-theory/email": "0.34.1",
14
+ "@working-theory/content-adapters": "0.35.0",
15
+ "@working-theory/content-projection": "0.35.0",
16
+ "@working-theory/email": "0.35.0",
17
17
  "@working-theory/env": "0.0.0",
18
- "@working-theory/eslint-config": "0.34.1",
19
- "@working-theory/fumadocs-schema": "0.34.1",
20
- "@working-theory/ids": "0.9.1",
21
- "@working-theory/jsonld": "0.34.1",
22
- "@working-theory/license": "0.34.1",
23
- "@working-theory/metadata": "0.34.1",
24
- "@working-theory/observability": "0.34.1",
25
- "@working-theory/page-renderer": "0.34.1",
18
+ "@working-theory/eslint-config": "0.35.0",
19
+ "@working-theory/fumadocs-schema": "0.35.0",
20
+ "@working-theory/ids": "0.10.0",
21
+ "@working-theory/jsonld": "0.35.0",
22
+ "@working-theory/license": "0.35.0",
23
+ "@working-theory/metadata": "0.35.0",
24
+ "@working-theory/observability": "0.35.0",
25
+ "@working-theory/page-renderer": "0.35.0",
26
26
  "@working-theory/plugin-mcp": "0.1.1",
27
- "@working-theory/schema": "0.34.1",
28
- "@working-theory/schema-pack-registry": "0.34.1",
29
- "@working-theory/schema-validator": "0.34.1",
30
- "@working-theory/sections-registry": "0.34.1",
31
- "@working-theory/site-config": "0.34.1",
32
- "@working-theory/stripe-client": "0.34.1",
33
- "@working-theory/templates": "0.34.1",
34
- "@working-theory/theme": "0.34.1",
35
- "@working-theory/ui": "0.34.1",
36
- "@working-theory/validation": "0.34.1",
37
- "@working-theory/web-i18n": "0.34.1",
27
+ "@working-theory/schema": "0.35.0",
28
+ "@working-theory/schema-pack-registry": "0.35.0",
29
+ "@working-theory/schema-validator": "0.35.0",
30
+ "@working-theory/sections-registry": "0.35.0",
31
+ "@working-theory/site-config": "0.35.0",
32
+ "@working-theory/stripe-client": "0.35.0",
33
+ "@working-theory/templates": "0.35.0",
34
+ "@working-theory/theme": "0.35.0",
35
+ "@working-theory/ui": "0.35.0",
36
+ "@working-theory/validation": "0.35.0",
37
+ "@working-theory/web-i18n": "0.35.0",
38
38
  "@working-theory/billing-client": "0.0.0",
39
39
  "@working-theory/branding": "0.0.0",
40
40
  "@working-theory/license-client": "0.0.0",
41
41
  "@working-theory/license-manifest": "0.0.0",
42
42
  "@working-theory/partner-session": "0.0.0",
43
43
  "@working-theory/preview-protocol": "0.0.0",
44
- "@working-theory/ui-commerce": "0.23.12",
45
- "@working-theory/ui-docs-blog": "0.23.12",
46
- "@working-theory/ui-scheduling": "0.23.12",
47
- "@working-theory/ui-signal-collectors": "0.25.1",
44
+ "@working-theory/ui-commerce": "0.23.13",
45
+ "@working-theory/ui-docs-blog": "0.23.13",
46
+ "@working-theory/ui-scheduling": "0.23.13",
47
+ "@working-theory/ui-signal-collectors": "0.25.2",
48
48
  "@working-theory/web": "0.0.0",
49
49
  "@working-theory/api": "1.0.0",
50
50
  "@working-theory/mcp": "0.0.0",
51
- "@working-theory/database": "0.34.1"
51
+ "@working-theory/database": "0.35.0"
52
52
  }