swallowkit 1.0.0-beta.57 → 1.0.0-beta.59

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 (73) hide show
  1. package/README.ja.md +1 -0
  2. package/README.md +1 -0
  3. package/dist/cli/commands/add-auth.d.ts +3 -1
  4. package/dist/cli/commands/add-auth.d.ts.map +1 -1
  5. package/dist/cli/commands/add-auth.js +55 -21
  6. package/dist/cli/commands/add-auth.js.map +1 -1
  7. package/dist/cli/commands/init.d.ts.map +1 -1
  8. package/dist/cli/commands/init.js +12 -498
  9. package/dist/cli/commands/init.js.map +1 -1
  10. package/dist/cli/index.d.ts.map +1 -1
  11. package/dist/cli/index.js +2 -0
  12. package/dist/cli/index.js.map +1 -1
  13. package/dist/core/operations/auth-operations.d.ts +4 -0
  14. package/dist/core/operations/auth-operations.d.ts.map +1 -1
  15. package/dist/core/operations/auth-operations.js +5 -2
  16. package/dist/core/operations/auth-operations.js.map +1 -1
  17. package/dist/core/operations/create-model.d.ts.map +1 -1
  18. package/dist/core/operations/create-model.js +6 -2
  19. package/dist/core/operations/create-model.js.map +1 -1
  20. package/dist/core/project/agent-instructions.d.ts +29 -0
  21. package/dist/core/project/agent-instructions.d.ts.map +1 -0
  22. package/dist/core/project/agent-instructions.js +159 -0
  23. package/dist/core/project/agent-instructions.js.map +1 -0
  24. package/dist/core/project/capabilities.d.ts +58 -0
  25. package/dist/core/project/capabilities.d.ts.map +1 -0
  26. package/dist/core/project/capabilities.js +135 -0
  27. package/dist/core/project/capabilities.js.map +1 -0
  28. package/dist/core/project/validation.d.ts.map +1 -1
  29. package/dist/core/project/validation.js +48 -0
  30. package/dist/core/project/validation.js.map +1 -1
  31. package/dist/core/project/workflows.d.ts.map +1 -1
  32. package/dist/core/project/workflows.js +46 -2
  33. package/dist/core/project/workflows.js.map +1 -1
  34. package/dist/core/scaffold/auth-generator.d.ts.map +1 -1
  35. package/dist/core/scaffold/auth-generator.js +6 -2
  36. package/dist/core/scaffold/auth-generator.js.map +1 -1
  37. package/dist/core/verify/index.d.ts +7 -0
  38. package/dist/core/verify/index.d.ts.map +1 -1
  39. package/dist/core/verify/index.js +69 -0
  40. package/dist/core/verify/index.js.map +1 -1
  41. package/dist/machine/index.d.ts.map +1 -1
  42. package/dist/machine/index.js +117 -41
  43. package/dist/machine/index.js.map +1 -1
  44. package/dist/mcp/index.d.ts.map +1 -1
  45. package/dist/mcp/index.js +32 -10
  46. package/dist/mcp/index.js.map +1 -1
  47. package/package.json +1 -1
  48. package/src/__tests__/agent-instructions.test.ts +237 -0
  49. package/src/__tests__/agent-loop-phase34.test.ts +66 -2
  50. package/src/__tests__/auth.test.ts +9 -0
  51. package/src/__tests__/init.test.ts +2 -0
  52. package/src/__tests__/machine.test.ts +15 -0
  53. package/src/__tests__/multi-auth.test.ts +12 -0
  54. package/src/__tests__/plan-apply.test.ts +38 -0
  55. package/src/cli/commands/add-auth.ts +59 -21
  56. package/src/cli/commands/init.ts +19 -525
  57. package/src/cli/index.ts +2 -0
  58. package/src/core/operations/auth-operations.ts +9 -2
  59. package/src/core/operations/create-model.ts +7 -2
  60. package/src/core/project/agent-instructions.ts +167 -0
  61. package/src/core/project/agent-templates/AGENTS.md +502 -0
  62. package/src/core/project/agent-templates/CLAUDE.md +31 -0
  63. package/src/core/project/agent-templates/azure-functions.instructions.md +22 -0
  64. package/src/core/project/agent-templates/bff-routes.instructions.md +18 -0
  65. package/src/core/project/agent-templates/copilot-instructions.md +27 -0
  66. package/src/core/project/agent-templates/shared-models.instructions.md +72 -0
  67. package/src/core/project/capabilities.ts +193 -0
  68. package/src/core/project/validation.ts +50 -0
  69. package/src/core/project/workflows.ts +48 -2
  70. package/src/core/scaffold/auth-generator.ts +7 -2
  71. package/src/core/verify/index.ts +76 -0
  72. package/src/machine/index.ts +133 -45
  73. package/src/mcp/index.ts +28 -10
@@ -18,6 +18,7 @@ import {
18
18
  } from "../../utils/package-manager";
19
19
  import { syncProjectManifest } from "../../core/project/manifest";
20
20
  import { writeWorkflowDocs, writeAgentSkills } from "../../core/project/workflows";
21
+ import { writeAgentInstructionFiles } from "../../core/project/agent-instructions";
21
22
  import {
22
23
  buildCSharpCodegenToolManifestSource,
23
24
  buildPythonCodegenRequirementsSource,
@@ -789,7 +790,7 @@ function runSimple(command: string, args: string[], cwd: string): Promise<void>
789
790
  export function injectSwallowKitNextConfig(nextConfigContent: string, projectName: string): string {
790
791
  return nextConfigContent.replace(
791
792
  /(const\s+nextConfig[:\s]*(?::\s*NextConfig\s*)?=\s*\{)(\s*\/\*[^*]*\*\/)?/,
792
- `$1\n output: 'standalone',\n transpilePackages: ['@${projectName}/shared'],\n serverExternalPackages: ['applicationinsights', 'diagnostic-channel-publishers'],$2`
793
+ `$1\n output: 'standalone',\n agentRules: false, // SwallowKit owns the canonical root AGENTS.md contract\n transpilePackages: ['@${projectName}/shared'],\n serverExternalPackages: ['applicationinsights', 'diagnostic-channel-publishers'],$2`
793
794
  );
794
795
  }
795
796
 
@@ -2105,532 +2106,34 @@ This project was generated by SwallowKit. If you encounter any issues or have su
2105
2106
  console.log('✅ README.md created\n');
2106
2107
  }
2107
2108
 
2108
- function createAiAgentFiles(projectDir: string, projectName: string, backendLanguage: BackendLanguage, pm: PackageManager) {
2109
+ function createAiAgentFiles(
2110
+ projectDir: string,
2111
+ projectName: string,
2112
+ backendLanguage: BackendLanguage,
2113
+ pm: PackageManager
2114
+ ) {
2109
2115
  console.log('🤖 Creating AI agent instruction files...\n');
2110
- const backendLanguageLabel = getBackendLanguageLabel(backendLanguage);
2111
2116
  const runCmd = pm === 'pnpm' ? 'pnpm' : 'npx';
2112
- const projectMcpConfigSource = buildSwallowKitMcpProjectConfigSource(pm);
2113
- const functionsStructureLine = backendLanguage === 'typescript'
2114
- ? `│ └── src/ # HTTP trigger handlers with Cosmos DB bindings`
2115
- : backendLanguage === 'csharp'
2116
- ? `│ ├── Crud/ # C# HTTP trigger handlers\n│ └── generated/ # Native-generated C# schema assets`
2117
- : `│ ├── blueprints/ # Python HTTP trigger handlers\n│ └── generated/ # Native-generated Python schema assets`;
2118
- const backendSchemaNote = backendLanguage === 'typescript'
2119
- ? `- The shared package (\`@${projectName}/shared\`) is consumed by both Next.js and Azure Functions as a workspace dependency.`
2120
- : `- The frontend/BFF source of truth stays in \`shared/models/\` as Zod schemas.\n- \`swallowkit scaffold\` exports OpenAPI into \`functions/openapi/\` and generates ${backendLanguageLabel} schema assets into \`functions/generated/\` with native ${backendLanguageLabel} tooling.`;
2121
- const backendRulesNote = backendLanguage === 'typescript'
2122
- ? `- All CRUD operations and business logic live in \`functions/src/\`.\n- Use Azure Functions Cosmos DB **input/output bindings** (\`extraInputs\`/\`extraOutputs\`) for reads and writes.\n- Use the Cosmos DB SDK client directly **only** for delete operations (bindings do not support delete).\n- Validate all data against Zod schemas before writing to Cosmos DB.\n- The backend auto-generates \`id\` (UUID), \`createdAt\`, and \`updatedAt\` — never trust client-sent values for these fields.`
2123
- : `- All business logic lives in \`functions/\` and the generated handlers perform real Cosmos DB CRUD.\n- Keep Zod schemas in \`shared/models/\` as the source of truth.\n- Regenerate backend contracts with \`swallowkit scaffold shared/models/<name>.ts\` whenever a schema changes.\n- Use the native-generated schema assets in \`functions/generated/\` to keep backend contracts aligned.\n- The backend should still own \`id\`, \`createdAt\`, and \`updatedAt\`.`;
2124
-
2125
- // ── 1. AGENTS.md (Codex / generic agents) ──────────────────────────
2126
-
2127
- const agentsMd = `# AGENTS.md
2128
-
2129
- This project was generated by **SwallowKit**.
2130
- All coding agents **must** follow the architecture and conventions described below.
2131
-
2132
- ## Architecture Overview
2133
-
2134
- This is a full-stack application deployed on Azure with a TypeScript frontend/BFF and an Azure Functions backend in ${backendLanguageLabel}.
2135
-
2136
- \`\`\`
2137
- Frontend (React / Next.js App Router)
2138
- ↓ fetch('/api/{model}', ...)
2139
- BFF Layer (Next.js API Routes)
2140
- ↓ HTTP → Azure Functions
2141
- Backend (Azure Functions)
2142
- ↓
2143
- Azure Cosmos DB (Document Database)
2144
- \`\`\`
2145
-
2146
- ### Project Structure
2147
-
2148
- \`\`\`
2149
- ${projectName}/
2150
- ├── app/ # Next.js App Router
2151
- │ ├── api/ # BFF API routes (proxy to Azure Functions)
2152
- │ └── {model}/ # UI pages per model (list, detail, create, edit)
2153
- ├── functions/ # Azure Functions (backend)
2154
- ${functionsStructureLine}
2155
- ├── shared/ # Shared workspace package
2156
- │ ├── models/ # Zod schema definitions (single source of truth)
2157
- │ └── index.ts # Re-exports all models
2158
- ├── lib/
2159
- │ └── api/ # API client utilities (backend.ts, call-function.ts)
2160
- ├── components/ # Shared React components
2161
- ├── infra/ # Bicep infrastructure-as-code files
2162
- │ ├── main.bicep
2163
- │ └── modules/
2164
- ├── .mcp.json # Project-scoped MCP bootstrap resolving SwallowKit on each launch
2165
- └── .github/workflows/ # CI/CD workflows (if configured)
2166
- \`\`\`
2167
-
2168
- ## Setup & Everyday Commands
2169
-
2170
- \`\`\`bash
2171
- ${pm} install # install dependencies
2172
- ${runCmd} swallowkit dev # Next.js (3000) + Azure Functions (7071)
2173
- ${pm} run build # production build
2174
- ${pm} run lint # ESLint (generated code must stay error-free)
2175
- ${runCmd} swallowkit verify # structure / drift / typecheck (exit 1 on failure)
2176
- \`\`\`
2177
-
2178
- Run \`${runCmd} swallowkit verify\` (or \`machine verify project\`) before finishing any task.
2179
-
2180
- ## SwallowKit MCP / Machine Workflow
2181
-
2182
- - This repository includes a project-scoped \`.mcp.json\` file that resolves and starts the latest SwallowKit MCP server on each launch. Set \`SWALLOWKIT_MCP_VERSION\` in that file to pin a specific version.
2183
- - Prefer the \`swallowkit_*\` MCP tools for framework-owned inspection, validation, and generation when they are available.
2184
- - If MCP is unavailable in your runtime, fall back to the machine CLI:
2185
- - \`${runCmd} swallowkit machine inspect project\`
2186
- - \`${runCmd} swallowkit machine inspect boundaries\` — responsibility boundary contract (which files you may edit freely)
2187
- - \`${runCmd} swallowkit machine validate project\`
2188
- - \`${runCmd} swallowkit machine plan scaffold <name>\` → \`apply scaffold --plan <planId>\` — safe two-phase generation
2189
- - \`${runCmd} swallowkit machine verify project\` → \`explain failure\` — verification loop
2190
- - Do not hand-edit framework-owned artifacts when the MCP or machine interface can generate or validate them for you.
2191
- - The MCP bootstrap uses ${pm} and requires network access when the selected version is not cached.
2192
- - **Always invoke SwallowKit via \`${runCmd}\`.** Do not mix package manager commands.
2193
-
2194
- ## Autonomous Loop (Plan / Apply / Verify)
2195
-
2196
- Machine commands return a \`status\` terminal state (\`complete\` / \`in-progress\` / \`blocked\` / \`requires-human\` / \`failed\`) and \`nextActions\`. Standard loop:
2197
-
2198
- 1. \`plan scaffold <model>\` — compute changes without writing (get \`planId\`)
2199
- 2. \`apply scaffold --plan <planId>\` — apply with freshness + approval checks
2200
- 3. \`verify project\` — structure / drift / typecheck (and project-specific checks)
2201
- 4. \`explain failure\` — evidence and repair actions when verification fails
2202
-
2203
- Step-by-step runbooks live in \`.swallowkit/workflows/\` (agent-agnostic Markdown):
2204
-
2205
- - \`.swallowkit/workflows/add-model.md\`
2206
- - \`.swallowkit/workflows/modify-model.md\`
2207
- - \`.swallowkit/workflows/verify-and-repair.md\`
2208
- - \`.swallowkit/workflows/provision.md\`
2209
-
2210
- The same runbooks are installed as **Agent Skills** ([agentskills.io](https://agentskills.io/) open standard) under \`.github/skills/\`:
2211
-
2212
- | Skill | Use when |
2213
- |-------|----------|
2214
- | \`swallowkit-add-model\` | adding a new model / entity / CRUD feature |
2215
- | \`swallowkit-modify-model\` | changing an existing schema and re-aligning artifacts |
2216
- | \`swallowkit-verify-repair\` | converging to a verified state after any change |
2217
- | \`swallowkit-provision\` | provisioning Azure infrastructure (human approval required) |
2218
-
2219
- Skills-aware agents (GitHub Copilot in VS Code / CLI / cloud agent, and other agents supporting the standard) discover these automatically from their \`name\`/\`description\` and load the body on demand. If your agent does not support skills, read the equivalent runbook in \`.swallowkit/workflows/\` before performing these tasks.
2220
-
2221
- ## Responsibility Boundary (AI × Deterministic Generation)
2222
-
2223
- - **ai-authored (write freely)**: \`shared/models/\`, business logic, custom pages/components, tests.
2224
- - **deterministic (never hand-edit)**: artifacts recorded in \`.swallowkit/artifacts.json\` with \`managed\` ownership, and \`.swallowkit/\` metadata. Change the model/config and regenerate via plan/apply instead.
2225
- - **shared (edit outside markers)**: \`infra/main.bicep\`, \`functions/function_app.py\`, \`shared/index.ts\`.
2226
- - Full machine-readable contract: \`${runCmd} swallowkit machine inspect boundaries\`
2227
-
2228
- ## Critical Design Principles
2229
-
2230
- ### 1. Next.js API Routes Are Strictly a BFF (Backend for Frontend)
2231
-
2232
- - \`app/api/\` routes exist **only** to proxy requests to Azure Functions.
2233
- - **Never** place business logic, database access, or direct Cosmos DB calls in Next.js API routes.
2234
- - The BFF layer may validate input/output with Zod schemas before forwarding to Functions.
2235
- - Use the \`callFunction\` helper (\`lib/api/call-function.ts\`) or the \`api\` client (\`lib/api/backend.ts\`) to call Azure Functions.
2236
-
2237
- Example BFF route pattern:
2238
-
2239
- \`\`\`typescript
2240
- // app/api/{model}/route.ts
2241
- import { callFunction } from '@/lib/api/call-function';
2242
- import { ModelSchema } from '@${projectName}/shared';
2243
- import { z } from 'zod/v4';
2244
-
2245
- export async function GET() {
2246
- return callFunction({
2247
- method: 'GET',
2248
- path: '/api/{model}',
2249
- responseSchema: z.array(ModelSchema),
2250
- });
2251
- }
2252
-
2253
- export async function POST(request: NextRequest) {
2254
- const body = await request.json();
2255
- return callFunction({
2256
- method: 'POST',
2257
- path: '/api/{model}',
2258
- body,
2259
- inputSchema: ModelSchema.omit({ id: true, createdAt: true, updatedAt: true }),
2260
- responseSchema: ModelSchema,
2261
- successStatus: 201,
2262
- });
2263
- }
2264
- \`\`\`
2265
-
2266
- ### 2. Zod Schemas Are the Single Source of Truth
2267
-
2268
- - All data models are defined **once** as Zod schemas in \`shared/models/\`.
2269
- - TypeScript types are derived with \`z.infer<typeof Schema>\` — never define types separately.
2270
- - ${backendSchemaNote}
2271
-
2272
- Model definition pattern:
2273
-
2274
- \`\`\`typescript
2275
- // shared/models/{model}.ts
2276
- import { z } from 'zod/v4';
2277
-
2278
- export const Todo = z.object({
2279
- id: z.string(),
2280
- name: z.string().min(1),
2281
- // ... your fields
2282
- createdAt: z.string().optional(),
2283
- updatedAt: z.string().optional(),
2284
- });
2285
-
2286
- export type Todo = z.infer<typeof Todo>;
2287
- export const displayName = 'Todo';
2288
- \`\`\`
2289
-
2290
- Key rules:
2291
- - Use the **Zod official pattern**: the schema constant and the TypeScript type share the same name.
2292
- - \`id\`, \`createdAt\`, and \`updatedAt\` are auto-managed by the backend. Mark them as \`optional()\` in the schema.
2293
- - Always re-export models from \`shared/index.ts\`.
2294
-
2295
- ### 3. Azure Functions Own All Business Logic and Data Access
2296
-
2297
- - ${backendRulesNote}
2298
-
2299
- ${backendLanguage === 'typescript' ? 'Azure Functions handler pattern:' : `Generated ${backendLanguageLabel} handlers live under \`functions/\`. Re-run \`swallowkit scaffold shared/models/<name>.ts\` after schema changes to keep generated CRUD handlers and the native schema assets under \`functions/generated/\` in sync.`}
2300
-
2301
- ${backendLanguage === 'typescript' ? `\`\`\`typescript
2302
- // functions/src/{model}.ts
2303
- import { app } from '@azure/functions';
2304
- import { ModelSchema } from '@${projectName}/shared';
2305
-
2306
- const containerName = 'Models'; // PascalCase + 's'
2307
-
2308
- app.http('{model}-get-all', {
2309
- methods: ['GET'],
2310
- route: '{model}',
2311
- authLevel: 'function',
2312
- extraInputs: [{ type: 'cosmosDB', name: 'cosmosInput', containerName, ... }],
2313
- handler: async (request, context) => {
2314
- const documents = context.extraInputs.get('cosmosInput');
2315
- const validated = z.array(ModelSchema).parse(documents);
2316
- return { status: 200, jsonBody: validated };
2317
- },
2318
- });
2319
- \`\`\`` : ''}
2320
-
2321
- ## Naming Conventions
2322
-
2323
- | Item | Convention | Example |
2324
- |------|-----------|---------|
2325
- | Model schema file | \`shared/models/{kebab-case}.ts\` | \`shared/models/todo.ts\` |
2326
- | Schema/type name | PascalCase (same name for both) | \`export const Todo = z.object({...}); export type Todo = z.infer<typeof Todo>;\` |
2327
- | Functions handler file | backend-language specific under \`functions/\` | \`${backendLanguage === 'typescript' ? 'functions/src/todo.ts' : backendLanguage === 'csharp' ? 'functions/Crud/TodoCrudFunctions.cs' : 'functions/blueprints/todo.py'}\` |
2328
- | Functions handler name | \`{camelCase}-{operation}\` | \`todo-get-all\`, \`todo-create\` |
2329
- | API route path | \`/api/{camelCase}\` | \`/api/todo\`, \`/api/todo/{id}\` |
2330
- | BFF route file | \`app/api/{kebab-case}/route.ts\` | \`app/api/todo/route.ts\` |
2331
- | BFF detail route | \`app/api/{kebab-case}/[id]/route.ts\` | \`app/api/todo/[id]/route.ts\` |
2332
- | UI page directory | \`app/{kebab-case}/\` | \`app/todo/page.tsx\` |
2333
- | React component | PascalCase | \`TodoForm.tsx\` |
2334
- | Cosmos DB container | PascalCase + 's' | \`Todos\` |
2335
- | Cosmos DB partition key | \`/id\` (default) | Custom: \`export const partitionKey = '/field'\` |
2336
- | Bicep container file | \`infra/containers/{kebab-case}-container.bicep\` | \`infra/containers/todo-container.bicep\` |
2337
-
2338
- ## Adding New Models (SwallowKit CLI)
2339
-
2340
- Use the SwallowKit CLI — do **not** manually create model files or CRUD boilerplate.
2341
- For autonomous agents, prefer the plan/apply loop above (or the \`swallowkit-add-model\` skill); the commands below are the human-friendly equivalents.
2342
-
2343
- ### Create a new data model
2344
-
2345
- \`\`\`bash
2346
- ${runCmd} swallowkit create-model <name>
2347
- # Multiple models at once:
2348
- ${runCmd} swallowkit create-model user post comment
2349
- \`\`\`
2350
-
2351
- Creates \`shared/models/<name>.ts\` with a Zod schema template including \`id\`, \`createdAt\`, \`updatedAt\`.
2352
- Edit the generated file to add your domain-specific fields, then run scaffold.
2353
-
2354
- ### Generate full CRUD from a model
2355
-
2356
- \`\`\`bash
2357
- ${runCmd} swallowkit scaffold shared/models/<name>.ts
2358
- \`\`\`
2359
-
2360
- Generates:
2361
- - Azure Functions handlers (${backendLanguage === 'typescript' ? '`functions/src/<name>.ts`' : '`functions/` language-specific CRUD files + `functions/generated/` schema assets'})
2362
- - BFF API routes (\`app/api/<name>/route.ts\`, \`app/api/<name>/[id]/route.ts\`)
2363
- - UI pages (\`app/<name>/page.tsx\`, detail, create, edit pages)
2364
- - Cosmos DB Bicep container config (\`infra/containers/<name>-container.bicep\`)
2365
-
2366
- ### Start development servers
2367
-
2368
- \`\`\`bash
2369
- ${runCmd} swallowkit dev
2370
- \`\`\`
2371
2117
 
2372
- Runs Next.js (http://localhost:3000) and Azure Functions (http://localhost:7071) concurrently.
2373
- Checks for Cosmos DB Emulator availability.
2374
-
2375
- ### Provision Azure resources
2376
-
2377
- \`\`\`bash
2378
- ${runCmd} swallowkit provision --resource-group <name> --location <region>
2379
- \`\`\`
2380
-
2381
- Deploys Bicep infrastructure: Static Web Apps, Functions, Cosmos DB, Storage, Managed Identity.
2382
-
2383
- ### Typical workflow for "add a new feature/model"
2384
-
2385
- 1. \`${runCmd} swallowkit create-model <name>\`
2386
- 2. Edit \`shared/models/<name>.ts\` — add fields
2387
- 3. \`${runCmd} swallowkit scaffold shared/models/<name>.ts\`
2388
- 4. \`${runCmd} swallowkit dev\` — verify at http://localhost:3000/<name>
2389
- 5. If \`dev-seeds/\` already exists, update the seed JSON files to include realistic data for the new model and adjust existing seeds if relationships changed.
2390
-
2391
- ## Do NOT
2392
-
2393
- - **Do not** put business logic or database calls in \`app/api/\` routes. They are BFF only.
2394
- - **Do not** define TypeScript interfaces/types separately from Zod schemas. Always derive types with \`z.infer<>\`.
2395
- - **Do not** manually duplicate model definitions across layers. Use the shared package.
2396
- - **Do not** manually create CRUD boilerplate. Use \`swallowkit scaffold\`.
2397
- - **Do not** hardcode Cosmos DB connection strings. Use Managed Identity (\`CosmosDBConnection__accountEndpoint\`) in production and emulator settings locally.
2398
- - By default, all containers use \`/id\` as the partition key. To use a custom partition key, add \`export const partitionKey = '/yourField'\` to the model file. The scaffold command will apply it across all layers.
2399
-
2400
- ## Technology Stack
2401
-
2402
- - **Frontend**: Next.js (App Router), React, TypeScript, Tailwind CSS
2403
- - **BFF**: Next.js API Routes (proxy only)
2404
- - **Backend**: Azure Functions (${backendLanguageLabel})
2405
- - **Database**: Azure Cosmos DB (NoSQL)
2406
- - **Schema**: Zod (shared across all layers via workspace package)
2407
- - **Infrastructure**: Bicep (IaC)
2408
- - **Hosting**: Azure Static Web Apps (frontend) + Azure Functions Flex Consumption (backend)
2409
- - **Auth**: Azure Managed Identity (no connection strings in production)
2410
- - **Monitoring**: Application Insights
2411
- `;
2412
-
2413
- fs.writeFileSync(path.join(projectDir, 'AGENTS.md'), agentsMd);
2414
- console.log(' ✅ AGENTS.md (Codex / generic agents)');
2415
-
2416
- // ── 2. CLAUDE.md (Claude Code) ─────────────────────────────────────
2417
-
2418
- const claudeMd = `# CLAUDE.md
2419
-
2420
- This file is for Claude Code. Read AGENTS.md in the project root for the full architecture, conventions, and rules.
2421
-
2422
- ## Quick Reference
2423
-
2424
- - **Architecture**: Next.js (frontend) → BFF (API routes, proxy only) → Azure Functions (backend) → Cosmos DB
2425
- - **Schema**: Zod schemas in \`shared/models/\` are the single source of truth. Never define types separately.
2426
- - **BFF rule**: \`app/api/\` routes must ONLY proxy to Azure Functions via \`callFunction()\`. No business logic.
2427
- - **Backend language**: ${backendLanguageLabel}
2428
- - **Backend rule**: Regenerate backend contracts with \`swallowkit scaffold\` after schema changes and keep \`functions/generated/\` in sync.
2429
-
2430
- ## SwallowKit MCP
2431
-
2432
- - This repository includes a project-scoped \`.mcp.json\` that resolves and starts the latest SwallowKit MCP server on each launch. Set \`SWALLOWKIT_MCP_VERSION\` in that file to pin a specific version.
2433
- - When the \`swallowkit_*\` tools are available, prefer them for inspect / validate / generate tasks.
2434
- - If MCP is unavailable, use \`${runCmd} swallowkit machine ...\` instead.
2435
- - For generation, prefer the two-phase flow: \`plan scaffold <name>\` → \`apply scaffold --plan <planId>\` → \`verify project\`. Runbooks: \`.swallowkit/workflows/\`.
2436
- - Agent Skills (agentskills.io) for the same workflows live in \`.github/skills/\` (\`swallowkit-add-model\`, \`swallowkit-modify-model\`, \`swallowkit-verify-repair\`, \`swallowkit-provision\`). If your runtime does not auto-discover them, read the relevant \`SKILL.md\` before performing these tasks.
2437
- - Boundary contract (what you may edit freely vs what SwallowKit regenerates): \`${runCmd} swallowkit machine inspect boundaries\`
2438
- - **Always invoke SwallowKit via \`${runCmd}\`.** Do not mix package manager commands.
2439
-
2440
- ## SwallowKit CLI Commands
2441
-
2442
- | Task | Command |
2443
- |------|---------|
2444
- | Create model | \`${runCmd} swallowkit create-model <name>\` |
2445
- | Generate CRUD | \`${runCmd} swallowkit scaffold shared/models/<name>.ts\` |
2446
- | Dev servers | \`${runCmd} swallowkit dev\` |
2447
- | Provision Azure | \`${runCmd} swallowkit provision --resource-group <rg> --location <region>\` |
2448
-
2449
- ## Workflow: Add a new model
2450
-
2451
- 1. \`${runCmd} swallowkit create-model <name>\`
2452
- 2. Edit \`shared/models/<name>.ts\` — add your fields
2453
- 3. \`${runCmd} swallowkit scaffold shared/models/<name>.ts\`
2454
- 4. \`${runCmd} swallowkit dev\` — verify at http://localhost:3000/<name>
2455
- 5. If \`dev-seeds/\` exists, update the seed JSON files to include data for the new model and adjust existing seeds if relationships changed.
2456
- `;
2457
-
2458
- fs.writeFileSync(path.join(projectDir, 'CLAUDE.md'), claudeMd);
2459
- console.log(' ✅ CLAUDE.md (Claude Code)');
2460
-
2461
- fs.writeFileSync(path.join(projectDir, '.mcp.json'), projectMcpConfigSource);
2462
- console.log(' ✅ .mcp.json (project-scoped MCP bootstrap)');
2463
-
2464
- // ── 3. .github/copilot-instructions.md (GitHub Copilot) ────────────
2465
-
2466
- const ghDir = path.join(projectDir, '.github');
2467
- fs.mkdirSync(ghDir, { recursive: true });
2468
-
2469
- const copilotInstructions = `# Copilot Instructions
2470
-
2471
- This project was generated by **SwallowKit**. See \`AGENTS.md\` in the project root for the full specification.
2472
-
2473
- ## Architecture (3-layer)
2474
-
2475
- \`\`\`
2476
- Frontend (Next.js App Router) → BFF (Next.js API Routes) → Backend (Azure Functions) → Cosmos DB
2477
- \`\`\`
2478
-
2479
- ## Key Rules
2480
-
2481
- 1. **BFF is proxy only** — \`app/api/\` routes call Azure Functions via \`callFunction()\`. No business logic, no direct DB access.
2482
- 2. **Zod = single source of truth** — Models live in \`shared/models/\`. Types are derived with \`z.infer<>\`. Never define types separately.
2483
- 3. **Backend owns data** — All CRUD and business logic stay in \`functions/\`, and generated contract assets under \`functions/generated/\` must stay aligned with \`shared/models/\`.
2484
- 4. **Use the CLI** — Run \`${runCmd} swallowkit create-model <name>\` then \`${runCmd} swallowkit scaffold shared/models/<name>.ts\` to add models. Do not create boilerplate manually.
2485
- 5. **Maintain seed data** — When adding models or changing schemas, update the JSON files under \`dev-seeds/\` to keep seed data consistent with the current schema.
2486
-
2487
- ## SwallowKit Framework Operations
2488
-
2489
- - Prefer the SwallowKit MCP or machine interface for framework-owned inspection, validation, and generation instead of hand-editing generated files.
2490
- - If your runtime loads project-scoped MCP config from \`.mcp.json\`, use the \`swallowkit_*\` tools.
2491
- - Otherwise use \`${runCmd} swallowkit machine inspect project\`, \`${runCmd} swallowkit machine validate project\`, and the two-phase flow \`${runCmd} swallowkit machine plan scaffold <name>\` → \`apply scaffold --plan <planId>\` → \`verify project\`.
2492
- - Agent Skills in \`.github/skills/\` (\`swallowkit-add-model\`, \`swallowkit-modify-model\`, \`swallowkit-verify-repair\`, \`swallowkit-provision\`) cover these workflows — load them when the task matches.
2493
- - Boundary contract: \`${runCmd} swallowkit machine inspect boundaries\` tells you which files are free to edit and which are regenerated. Runbooks live in \`.swallowkit/workflows/\`.
2494
- - **Always invoke SwallowKit via \`${runCmd}\`.** Do not mix package manager commands.
2495
-
2496
- ## Naming
2497
-
2498
- - Schema/type: PascalCase, same name for both (\`export const Todo = z.object({...}); export type Todo = z.infer<typeof Todo>;\`)
2499
- - Files: kebab-case (\`shared/models/todo.ts\`, backend handlers under \`functions/\`)
2500
- - Cosmos DB containers: PascalCase + 's' (\`Todos\`), partition key default \`/id\` (customizable via \`export const partitionKey\`)
2501
-
2502
- ## Managed Fields
2503
-
2504
- \`id\`, \`createdAt\`, \`updatedAt\` are auto-managed by the backend. Define them as \`optional()\` in schemas. Never trust client-sent values.
2505
- `;
2506
-
2507
- fs.writeFileSync(path.join(ghDir, 'copilot-instructions.md'), copilotInstructions);
2508
- console.log(' ✅ .github/copilot-instructions.md (GitHub Copilot)');
2509
-
2510
- // ── 4. .github/instructions/*.instructions.md (Copilot layer-specific) ──
2511
-
2512
- const instructionsDir = path.join(ghDir, 'instructions');
2513
- fs.mkdirSync(instructionsDir, { recursive: true });
2514
-
2515
- // 4a. shared/models — Zod schema layer
2516
- const sharedModelsInstructions = `---
2517
- applyTo: "shared/models/**"
2518
- ---
2519
-
2520
- # Shared Models — Zod Schema Rules
2521
-
2522
- Files in this directory are the **single source of truth** for data models across the entire application.
2523
-
2524
- ## Rules
2525
-
2526
- - Define Zod schemas using \`zod/v4\` (\`import { z } from 'zod/v4'\`).
2527
- - Use the **Zod official pattern**: the schema constant and the TypeScript type share the same name.
2528
- \`\`\`typescript
2529
- export const Todo = z.object({ ... });
2530
- export type Todo = z.infer<typeof Todo>;
2531
- \`\`\`
2532
- - Always include \`id: z.string()\`, \`createdAt: z.string().optional()\`, \`updatedAt: z.string().optional()\`. These are managed by the backend.
2533
- - Export a \`displayName\` string constant for UI display.
2534
- - Re-export every model from \`shared/index.ts\`.
2535
- - For relationships, use **nested schemas** (import and embed the related schema), not ID references.
2536
- - After editing a model, run \`${runCmd} swallowkit scaffold shared/models/<name>.ts\` to regenerate CRUD code.
2537
- `;
2538
-
2539
- fs.writeFileSync(
2540
- path.join(instructionsDir, 'shared-models.instructions.md'),
2541
- sharedModelsInstructions
2542
- );
2543
-
2544
- // 4b. app/api — BFF layer
2545
- const bffInstructions = `---
2546
- applyTo: "app/api/**"
2547
- ---
2548
-
2549
- # BFF API Routes — Rules
2550
-
2551
- Files in \`app/api/\` are the **BFF (Backend for Frontend)** layer. They exist solely to proxy requests to Azure Functions.
2552
-
2553
- ## Rules
2554
-
2555
- - **Never** put business logic, database access, or direct Cosmos DB calls here.
2556
- - Use \`callFunction()\` from \`@/lib/api/call-function\` to forward requests to Azure Functions.
2557
- - You may validate input/output with Zod schemas before forwarding.
2558
- - Import schemas from \`@${projectName}/shared\`.
2559
-
2560
- ## Pattern
2561
-
2562
- \`\`\`typescript
2563
- import { callFunction } from '@/lib/api/call-function';
2564
- import { ModelSchema } from '@${projectName}/shared';
2565
- import { z } from 'zod/v4';
2566
-
2567
- export async function GET() {
2568
- return callFunction({
2569
- method: 'GET',
2570
- path: '/api/{model}',
2571
- responseSchema: z.array(ModelSchema),
2118
+ writeAgentInstructionFiles(projectDir, {
2119
+ projectName,
2120
+ backendLanguage,
2121
+ packageManager: pm,
2572
2122
  });
2573
- }
2574
- \`\`\`
2575
- `;
2576
-
2577
- fs.writeFileSync(
2578
- path.join(instructionsDir, 'bff-routes.instructions.md'),
2579
- bffInstructions
2580
- );
2581
-
2582
- // 4c. functions — Azure Functions backend layer
2583
- const functionsInstructions = `---
2584
- applyTo: "functions/**"
2585
- ---
2586
-
2587
- # Azure Functions — Backend Rules
2588
-
2589
- Files in \`functions/\` contain all business logic and data access for this application.
2590
-
2591
- ## Rules
2592
-
2593
- - Keep backend contracts aligned with \`shared/models/\` by rerunning \`swallowkit scaffold\` after schema changes.
2594
- - For TypeScript backends, use Cosmos DB **input/output bindings** (\`extraInputs\`/\`extraOutputs\`) for reads and writes.
2595
- - For C#/Python backends, consume the native-generated assets in \`functions/generated/\`.
2596
- - Auto-generate \`id\` (UUID), \`createdAt\`, and \`updatedAt\` on the backend. Never trust client-sent values.
2597
- - Container names are PascalCase + 's' (e.g., \`Todos\`). Partition key defaults to \`/id\` but can be customized per model.
2598
-
2599
- ## Handler Pattern
2600
-
2601
- \`\`\`typescript
2602
- import { app } from '@azure/functions';
2603
- import { ModelSchema } from '@${projectName}/shared';
2604
-
2605
- app.http('{model}-get-all', {
2606
- methods: ['GET'],
2607
- route: '{model}',
2608
- authLevel: 'function',
2609
- extraInputs: [cosmosInput],
2610
- handler: async (request, context) => {
2611
- const documents = context.extraInputs.get(cosmosInput);
2612
- const validated = z.array(ModelSchema).parse(documents);
2613
- return { status: 200, jsonBody: validated };
2614
- },
2615
- });
2616
- \`\`\`
2617
- `;
2123
+ console.log(' ✅ AGENTS.md (canonical project contract)');
2124
+ console.log(' ✅ CLAUDE.md (Claude Code adapter)');
2125
+ console.log(' ✅ .github/copilot-instructions.md (GitHub Copilot adapter)');
2126
+ console.log(' ✅ .github/instructions/ (path-specific instructions)');
2618
2127
 
2619
2128
  fs.writeFileSync(
2620
- path.join(instructionsDir, 'azure-functions.instructions.md'),
2621
- functionsInstructions
2129
+ path.join(projectDir, '.mcp.json'),
2130
+ buildSwallowKitMcpProjectConfigSource(pm)
2622
2131
  );
2132
+ console.log(' ✅ .mcp.json (project-scoped MCP bootstrap)');
2623
2133
 
2624
- console.log(' ✅ .github/instructions/ (Copilot layer-specific instructions)');
2625
- console.log(' - shared-models.instructions.md');
2626
- console.log(' - bff-routes.instructions.md');
2627
- console.log(' - azure-functions.instructions.md');
2628
-
2629
- // ── 5. .swallowkit/workflows/*.md (agent-agnostic runbooks) ────────
2630
2134
  writeWorkflowDocs(projectDir, runCmd);
2631
2135
  console.log(' ✅ .swallowkit/workflows/ (agent-agnostic autonomous-loop runbooks)');
2632
2136
 
2633
- // ── 6. .github/skills/<name>/SKILL.md (Agent Skills, agentskills.io) ─
2634
2137
  const skillPaths = writeAgentSkills(projectDir, runCmd);
2635
2138
  console.log(' ✅ .github/skills/ (Agent Skills — agentskills.io open standard)');
2636
2139
  for (const skillPath of skillPaths) {
@@ -2638,16 +2141,7 @@ app.http('{model}-get-all', {
2638
2141
  }
2639
2142
 
2640
2143
  console.log('\n✅ AI agent files created\n');
2641
- console.log(' Supported agents:');
2642
- console.log(' - OpenAI Codex → AGENTS.md');
2643
- console.log(' - Claude Code → CLAUDE.md (+ AGENTS.md)');
2644
- console.log(' - Project MCP runtimes → .mcp.json');
2645
- console.log(' - GitHub Copilot → .github/copilot-instructions.md');
2646
- console.log(' - GitHub Copilot (edit) → .github/instructions/*.instructions.md');
2647
- console.log(' - Skills-aware agents → .github/skills/*/SKILL.md');
2648
- console.log('');
2649
2144
  }
2650
-
2651
2145
  export function buildFunctionsHostKeyBicepExpression(): string {
2652
2146
  return "listKeys('${resourceId('Microsoft.Web/sites', functionsAppName)}/host/default', '2023-12-01').functionKeys.default";
2653
2147
  }
package/src/cli/index.ts CHANGED
@@ -189,10 +189,12 @@ export function createProgram(devCommandOverride: Command = devCommand): Command
189
189
  .description("Add authentication and authorization to the project")
190
190
  .option("--provider <provider>", "Auth provider: custom-jwt | swa | external-token | swa-custom | none", "custom-jwt")
191
191
  .option("--scheme <name>", "Add a named authentication scheme")
192
+ .option("--allowed-providers <list>", "Comma-separated SWA identity providers to allow (e.g. github,aad); defaults to aad")
192
193
  .action((options) => {
193
194
  addAuthCommand({
194
195
  provider: options.provider,
195
196
  scheme: options.scheme,
197
+ allowedProviders: options.allowedProviders ? String(options.allowedProviders).split(",") : undefined,
196
198
  });
197
199
  });
198
200
 
@@ -27,6 +27,8 @@ import {
27
27
  export interface PlanAuthOptions {
28
28
  provider: string;
29
29
  scheme?: string;
30
+ /** SWA の許可 identity provider。未指定時は add-auth 側の既定 (['aad'])。 */
31
+ allowedProviders?: string[];
30
32
  }
31
33
 
32
34
  export type AuthPlanAction = "create" | "update" | "overwrite" | "append" | "delete" | "skip";
@@ -44,6 +46,7 @@ export interface AuthPlanData {
44
46
  planType: "auth";
45
47
  provider: string;
46
48
  scheme?: string;
49
+ allowedProviders?: string[];
47
50
  createdAt: string;
48
51
  swallowkitVersion: string;
49
52
  operations: AuthPlanOperation[];
@@ -70,7 +73,7 @@ async function collectAuthOperations(options: PlanAuthOptions): Promise<FileOper
70
73
  const captured = await captureConsoleMessagesWithError(async () => {
71
74
  await interceptProcessExit(async () => {
72
75
  await runWithFileSession(session, async () => {
73
- await addAuthCommand({ provider: options.provider, scheme: options.scheme });
76
+ await addAuthCommand({ provider: options.provider, scheme: options.scheme, allowedProviders: options.allowedProviders });
74
77
  });
75
78
  });
76
79
  });
@@ -166,6 +169,7 @@ export async function planAuthOperation(options: PlanAuthOptions): Promise<AuthP
166
169
  JSON.stringify({
167
170
  provider: options.provider,
168
171
  scheme: options.scheme,
172
+ allowedProviders: options.allowedProviders,
169
173
  operations: operations.map((op) => ({ path: op.path, action: op.action })),
170
174
  fingerprints,
171
175
  })
@@ -178,6 +182,7 @@ export async function planAuthOperation(options: PlanAuthOptions): Promise<AuthP
178
182
  planType: "auth",
179
183
  provider: options.provider,
180
184
  ...(options.scheme ? { scheme: options.scheme } : {}),
185
+ ...(options.allowedProviders && options.allowedProviders.length > 0 ? { allowedProviders: options.allowedProviders } : {}),
181
186
  createdAt: new Date().toISOString(),
182
187
  swallowkitVersion: getSwallowKitVersion(),
183
188
  operations,
@@ -208,6 +213,7 @@ export function verifyAuthPlanFingerprints(
208
213
  export interface ApplyAuthOptions {
209
214
  provider?: string;
210
215
  scheme?: string;
216
+ allowedProviders?: string[];
211
217
  planId?: string;
212
218
  approve?: boolean;
213
219
  }
@@ -241,7 +247,7 @@ async function runCommitAuthOperation(options: PlanAuthOptions): Promise<{
241
247
  const tracked = await trackFileMutations(async () => {
242
248
  const captured = await captureConsoleMessagesWithError(async () => {
243
249
  await interceptProcessExit(async () => {
244
- await addAuthCommand({ provider: options.provider, scheme: options.scheme });
250
+ await addAuthCommand({ provider: options.provider, scheme: options.scheme, allowedProviders: options.allowedProviders });
245
251
  });
246
252
  });
247
253
 
@@ -318,6 +324,7 @@ export async function applyAuthOperation(options: ApplyAuthOptions): Promise<App
318
324
  const effectiveOptions: PlanAuthOptions = {
319
325
  provider,
320
326
  scheme: options.scheme ?? basePlan?.scheme,
327
+ allowedProviders: options.allowedProviders ?? basePlan?.allowedProviders,
321
328
  };
322
329
 
323
330
  // 常に最新状態で collect し、競合を再確認する