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.
- package/README.ja.md +1 -0
- package/README.md +1 -0
- package/dist/cli/commands/add-auth.d.ts +3 -1
- package/dist/cli/commands/add-auth.d.ts.map +1 -1
- package/dist/cli/commands/add-auth.js +55 -21
- package/dist/cli/commands/add-auth.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +12 -498
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/operations/auth-operations.d.ts +4 -0
- package/dist/core/operations/auth-operations.d.ts.map +1 -1
- package/dist/core/operations/auth-operations.js +5 -2
- package/dist/core/operations/auth-operations.js.map +1 -1
- package/dist/core/operations/create-model.d.ts.map +1 -1
- package/dist/core/operations/create-model.js +6 -2
- package/dist/core/operations/create-model.js.map +1 -1
- package/dist/core/project/agent-instructions.d.ts +29 -0
- package/dist/core/project/agent-instructions.d.ts.map +1 -0
- package/dist/core/project/agent-instructions.js +159 -0
- package/dist/core/project/agent-instructions.js.map +1 -0
- package/dist/core/project/capabilities.d.ts +58 -0
- package/dist/core/project/capabilities.d.ts.map +1 -0
- package/dist/core/project/capabilities.js +135 -0
- package/dist/core/project/capabilities.js.map +1 -0
- package/dist/core/project/validation.d.ts.map +1 -1
- package/dist/core/project/validation.js +48 -0
- package/dist/core/project/validation.js.map +1 -1
- package/dist/core/project/workflows.d.ts.map +1 -1
- package/dist/core/project/workflows.js +46 -2
- package/dist/core/project/workflows.js.map +1 -1
- package/dist/core/scaffold/auth-generator.d.ts.map +1 -1
- package/dist/core/scaffold/auth-generator.js +6 -2
- package/dist/core/scaffold/auth-generator.js.map +1 -1
- package/dist/core/verify/index.d.ts +7 -0
- package/dist/core/verify/index.d.ts.map +1 -1
- package/dist/core/verify/index.js +69 -0
- package/dist/core/verify/index.js.map +1 -1
- package/dist/machine/index.d.ts.map +1 -1
- package/dist/machine/index.js +117 -41
- package/dist/machine/index.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +32 -10
- package/dist/mcp/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/agent-instructions.test.ts +237 -0
- package/src/__tests__/agent-loop-phase34.test.ts +66 -2
- package/src/__tests__/auth.test.ts +9 -0
- package/src/__tests__/init.test.ts +2 -0
- package/src/__tests__/machine.test.ts +15 -0
- package/src/__tests__/multi-auth.test.ts +12 -0
- package/src/__tests__/plan-apply.test.ts +38 -0
- package/src/cli/commands/add-auth.ts +59 -21
- package/src/cli/commands/init.ts +19 -525
- package/src/cli/index.ts +2 -0
- package/src/core/operations/auth-operations.ts +9 -2
- package/src/core/operations/create-model.ts +7 -2
- package/src/core/project/agent-instructions.ts +167 -0
- package/src/core/project/agent-templates/AGENTS.md +502 -0
- package/src/core/project/agent-templates/CLAUDE.md +31 -0
- package/src/core/project/agent-templates/azure-functions.instructions.md +22 -0
- package/src/core/project/agent-templates/bff-routes.instructions.md +18 -0
- package/src/core/project/agent-templates/copilot-instructions.md +27 -0
- package/src/core/project/agent-templates/shared-models.instructions.md +72 -0
- package/src/core/project/capabilities.ts +193 -0
- package/src/core/project/validation.ts +50 -0
- package/src/core/project/workflows.ts +48 -2
- package/src/core/scaffold/auth-generator.ts +7 -2
- package/src/core/verify/index.ts +76 -0
- package/src/machine/index.ts +133 -45
- package/src/mcp/index.ts +28 -10
|
@@ -65,6 +65,7 @@ const prompts_1 = __importDefault(require("prompts"));
|
|
|
65
65
|
const package_manager_1 = require("../../utils/package-manager");
|
|
66
66
|
const manifest_1 = require("../../core/project/manifest");
|
|
67
67
|
const workflows_1 = require("../../core/project/workflows");
|
|
68
|
+
const agent_instructions_1 = require("../../core/project/agent-instructions");
|
|
68
69
|
const native_schema_generator_1 = require("../../core/scaffold/native-schema-generator");
|
|
69
70
|
const python_uv_1 = require("../../utils/python-uv");
|
|
70
71
|
function getStaticWebAppSku(plan) {
|
|
@@ -705,7 +706,7 @@ function runSimple(command, args, cwd) {
|
|
|
705
706
|
});
|
|
706
707
|
}
|
|
707
708
|
function injectSwallowKitNextConfig(nextConfigContent, projectName) {
|
|
708
|
-
return nextConfigContent.replace(/(const\s+nextConfig[:\s]*(?::\s*NextConfig\s*)?=\s*\{)(\s*\/\*[^*]*\*\/)?/, `$1\n output: 'standalone',\n transpilePackages: ['@${projectName}/shared'],\n serverExternalPackages: ['applicationinsights', 'diagnostic-channel-publishers'],$2`);
|
|
709
|
+
return nextConfigContent.replace(/(const\s+nextConfig[:\s]*(?::\s*NextConfig\s*)?=\s*\{)(\s*\/\*[^*]*\*\/)?/, `$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`);
|
|
709
710
|
}
|
|
710
711
|
function buildCSharpFunctionsProgramSource() {
|
|
711
712
|
return `using Microsoft.Azure.Functions.Worker;
|
|
@@ -1881,513 +1882,26 @@ This project was generated by SwallowKit. If you encounter any issues or have su
|
|
|
1881
1882
|
}
|
|
1882
1883
|
function createAiAgentFiles(projectDir, projectName, backendLanguage, pm) {
|
|
1883
1884
|
console.log('🤖 Creating AI agent instruction files...\n');
|
|
1884
|
-
const backendLanguageLabel = getBackendLanguageLabel(backendLanguage);
|
|
1885
1885
|
const runCmd = pm === 'pnpm' ? 'pnpm' : 'npx';
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
:
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
? `- 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.`
|
|
1897
|
-
: `- 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\`.`;
|
|
1898
|
-
// ── 1. AGENTS.md (Codex / generic agents) ──────────────────────────
|
|
1899
|
-
const agentsMd = `# AGENTS.md
|
|
1900
|
-
|
|
1901
|
-
This project was generated by **SwallowKit**.
|
|
1902
|
-
All coding agents **must** follow the architecture and conventions described below.
|
|
1903
|
-
|
|
1904
|
-
## Architecture Overview
|
|
1905
|
-
|
|
1906
|
-
This is a full-stack application deployed on Azure with a TypeScript frontend/BFF and an Azure Functions backend in ${backendLanguageLabel}.
|
|
1907
|
-
|
|
1908
|
-
\`\`\`
|
|
1909
|
-
Frontend (React / Next.js App Router)
|
|
1910
|
-
↓ fetch('/api/{model}', ...)
|
|
1911
|
-
BFF Layer (Next.js API Routes)
|
|
1912
|
-
↓ HTTP → Azure Functions
|
|
1913
|
-
Backend (Azure Functions)
|
|
1914
|
-
↓
|
|
1915
|
-
Azure Cosmos DB (Document Database)
|
|
1916
|
-
\`\`\`
|
|
1917
|
-
|
|
1918
|
-
### Project Structure
|
|
1919
|
-
|
|
1920
|
-
\`\`\`
|
|
1921
|
-
${projectName}/
|
|
1922
|
-
├── app/ # Next.js App Router
|
|
1923
|
-
│ ├── api/ # BFF API routes (proxy to Azure Functions)
|
|
1924
|
-
│ └── {model}/ # UI pages per model (list, detail, create, edit)
|
|
1925
|
-
├── functions/ # Azure Functions (backend)
|
|
1926
|
-
${functionsStructureLine}
|
|
1927
|
-
├── shared/ # Shared workspace package
|
|
1928
|
-
│ ├── models/ # Zod schema definitions (single source of truth)
|
|
1929
|
-
│ └── index.ts # Re-exports all models
|
|
1930
|
-
├── lib/
|
|
1931
|
-
│ └── api/ # API client utilities (backend.ts, call-function.ts)
|
|
1932
|
-
├── components/ # Shared React components
|
|
1933
|
-
├── infra/ # Bicep infrastructure-as-code files
|
|
1934
|
-
│ ├── main.bicep
|
|
1935
|
-
│ └── modules/
|
|
1936
|
-
├── .mcp.json # Project-scoped MCP bootstrap resolving SwallowKit on each launch
|
|
1937
|
-
└── .github/workflows/ # CI/CD workflows (if configured)
|
|
1938
|
-
\`\`\`
|
|
1939
|
-
|
|
1940
|
-
## Setup & Everyday Commands
|
|
1941
|
-
|
|
1942
|
-
\`\`\`bash
|
|
1943
|
-
${pm} install # install dependencies
|
|
1944
|
-
${runCmd} swallowkit dev # Next.js (3000) + Azure Functions (7071)
|
|
1945
|
-
${pm} run build # production build
|
|
1946
|
-
${pm} run lint # ESLint (generated code must stay error-free)
|
|
1947
|
-
${runCmd} swallowkit verify # structure / drift / typecheck (exit 1 on failure)
|
|
1948
|
-
\`\`\`
|
|
1949
|
-
|
|
1950
|
-
Run \`${runCmd} swallowkit verify\` (or \`machine verify project\`) before finishing any task.
|
|
1951
|
-
|
|
1952
|
-
## SwallowKit MCP / Machine Workflow
|
|
1953
|
-
|
|
1954
|
-
- 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.
|
|
1955
|
-
- Prefer the \`swallowkit_*\` MCP tools for framework-owned inspection, validation, and generation when they are available.
|
|
1956
|
-
- If MCP is unavailable in your runtime, fall back to the machine CLI:
|
|
1957
|
-
- \`${runCmd} swallowkit machine inspect project\`
|
|
1958
|
-
- \`${runCmd} swallowkit machine inspect boundaries\` — responsibility boundary contract (which files you may edit freely)
|
|
1959
|
-
- \`${runCmd} swallowkit machine validate project\`
|
|
1960
|
-
- \`${runCmd} swallowkit machine plan scaffold <name>\` → \`apply scaffold --plan <planId>\` — safe two-phase generation
|
|
1961
|
-
- \`${runCmd} swallowkit machine verify project\` → \`explain failure\` — verification loop
|
|
1962
|
-
- Do not hand-edit framework-owned artifacts when the MCP or machine interface can generate or validate them for you.
|
|
1963
|
-
- The MCP bootstrap uses ${pm} and requires network access when the selected version is not cached.
|
|
1964
|
-
- **Always invoke SwallowKit via \`${runCmd}\`.** Do not mix package manager commands.
|
|
1965
|
-
|
|
1966
|
-
## Autonomous Loop (Plan / Apply / Verify)
|
|
1967
|
-
|
|
1968
|
-
Machine commands return a \`status\` terminal state (\`complete\` / \`in-progress\` / \`blocked\` / \`requires-human\` / \`failed\`) and \`nextActions\`. Standard loop:
|
|
1969
|
-
|
|
1970
|
-
1. \`plan scaffold <model>\` — compute changes without writing (get \`planId\`)
|
|
1971
|
-
2. \`apply scaffold --plan <planId>\` — apply with freshness + approval checks
|
|
1972
|
-
3. \`verify project\` — structure / drift / typecheck (and project-specific checks)
|
|
1973
|
-
4. \`explain failure\` — evidence and repair actions when verification fails
|
|
1974
|
-
|
|
1975
|
-
Step-by-step runbooks live in \`.swallowkit/workflows/\` (agent-agnostic Markdown):
|
|
1976
|
-
|
|
1977
|
-
- \`.swallowkit/workflows/add-model.md\`
|
|
1978
|
-
- \`.swallowkit/workflows/modify-model.md\`
|
|
1979
|
-
- \`.swallowkit/workflows/verify-and-repair.md\`
|
|
1980
|
-
- \`.swallowkit/workflows/provision.md\`
|
|
1981
|
-
|
|
1982
|
-
The same runbooks are installed as **Agent Skills** ([agentskills.io](https://agentskills.io/) open standard) under \`.github/skills/\`:
|
|
1983
|
-
|
|
1984
|
-
| Skill | Use when |
|
|
1985
|
-
|-------|----------|
|
|
1986
|
-
| \`swallowkit-add-model\` | adding a new model / entity / CRUD feature |
|
|
1987
|
-
| \`swallowkit-modify-model\` | changing an existing schema and re-aligning artifacts |
|
|
1988
|
-
| \`swallowkit-verify-repair\` | converging to a verified state after any change |
|
|
1989
|
-
| \`swallowkit-provision\` | provisioning Azure infrastructure (human approval required) |
|
|
1990
|
-
|
|
1991
|
-
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.
|
|
1992
|
-
|
|
1993
|
-
## Responsibility Boundary (AI × Deterministic Generation)
|
|
1994
|
-
|
|
1995
|
-
- **ai-authored (write freely)**: \`shared/models/\`, business logic, custom pages/components, tests.
|
|
1996
|
-
- **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.
|
|
1997
|
-
- **shared (edit outside markers)**: \`infra/main.bicep\`, \`functions/function_app.py\`, \`shared/index.ts\`.
|
|
1998
|
-
- Full machine-readable contract: \`${runCmd} swallowkit machine inspect boundaries\`
|
|
1999
|
-
|
|
2000
|
-
## Critical Design Principles
|
|
2001
|
-
|
|
2002
|
-
### 1. Next.js API Routes Are Strictly a BFF (Backend for Frontend)
|
|
2003
|
-
|
|
2004
|
-
- \`app/api/\` routes exist **only** to proxy requests to Azure Functions.
|
|
2005
|
-
- **Never** place business logic, database access, or direct Cosmos DB calls in Next.js API routes.
|
|
2006
|
-
- The BFF layer may validate input/output with Zod schemas before forwarding to Functions.
|
|
2007
|
-
- Use the \`callFunction\` helper (\`lib/api/call-function.ts\`) or the \`api\` client (\`lib/api/backend.ts\`) to call Azure Functions.
|
|
2008
|
-
|
|
2009
|
-
Example BFF route pattern:
|
|
2010
|
-
|
|
2011
|
-
\`\`\`typescript
|
|
2012
|
-
// app/api/{model}/route.ts
|
|
2013
|
-
import { callFunction } from '@/lib/api/call-function';
|
|
2014
|
-
import { ModelSchema } from '@${projectName}/shared';
|
|
2015
|
-
import { z } from 'zod/v4';
|
|
2016
|
-
|
|
2017
|
-
export async function GET() {
|
|
2018
|
-
return callFunction({
|
|
2019
|
-
method: 'GET',
|
|
2020
|
-
path: '/api/{model}',
|
|
2021
|
-
responseSchema: z.array(ModelSchema),
|
|
2022
|
-
});
|
|
2023
|
-
}
|
|
2024
|
-
|
|
2025
|
-
export async function POST(request: NextRequest) {
|
|
2026
|
-
const body = await request.json();
|
|
2027
|
-
return callFunction({
|
|
2028
|
-
method: 'POST',
|
|
2029
|
-
path: '/api/{model}',
|
|
2030
|
-
body,
|
|
2031
|
-
inputSchema: ModelSchema.omit({ id: true, createdAt: true, updatedAt: true }),
|
|
2032
|
-
responseSchema: ModelSchema,
|
|
2033
|
-
successStatus: 201,
|
|
2034
|
-
});
|
|
2035
|
-
}
|
|
2036
|
-
\`\`\`
|
|
2037
|
-
|
|
2038
|
-
### 2. Zod Schemas Are the Single Source of Truth
|
|
2039
|
-
|
|
2040
|
-
- All data models are defined **once** as Zod schemas in \`shared/models/\`.
|
|
2041
|
-
- TypeScript types are derived with \`z.infer<typeof Schema>\` — never define types separately.
|
|
2042
|
-
- ${backendSchemaNote}
|
|
2043
|
-
|
|
2044
|
-
Model definition pattern:
|
|
2045
|
-
|
|
2046
|
-
\`\`\`typescript
|
|
2047
|
-
// shared/models/{model}.ts
|
|
2048
|
-
import { z } from 'zod/v4';
|
|
2049
|
-
|
|
2050
|
-
export const Todo = z.object({
|
|
2051
|
-
id: z.string(),
|
|
2052
|
-
name: z.string().min(1),
|
|
2053
|
-
// ... your fields
|
|
2054
|
-
createdAt: z.string().optional(),
|
|
2055
|
-
updatedAt: z.string().optional(),
|
|
2056
|
-
});
|
|
2057
|
-
|
|
2058
|
-
export type Todo = z.infer<typeof Todo>;
|
|
2059
|
-
export const displayName = 'Todo';
|
|
2060
|
-
\`\`\`
|
|
2061
|
-
|
|
2062
|
-
Key rules:
|
|
2063
|
-
- Use the **Zod official pattern**: the schema constant and the TypeScript type share the same name.
|
|
2064
|
-
- \`id\`, \`createdAt\`, and \`updatedAt\` are auto-managed by the backend. Mark them as \`optional()\` in the schema.
|
|
2065
|
-
- Always re-export models from \`shared/index.ts\`.
|
|
2066
|
-
|
|
2067
|
-
### 3. Azure Functions Own All Business Logic and Data Access
|
|
2068
|
-
|
|
2069
|
-
- ${backendRulesNote}
|
|
2070
|
-
|
|
2071
|
-
${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.`}
|
|
2072
|
-
|
|
2073
|
-
${backendLanguage === 'typescript' ? `\`\`\`typescript
|
|
2074
|
-
// functions/src/{model}.ts
|
|
2075
|
-
import { app } from '@azure/functions';
|
|
2076
|
-
import { ModelSchema } from '@${projectName}/shared';
|
|
2077
|
-
|
|
2078
|
-
const containerName = 'Models'; // PascalCase + 's'
|
|
2079
|
-
|
|
2080
|
-
app.http('{model}-get-all', {
|
|
2081
|
-
methods: ['GET'],
|
|
2082
|
-
route: '{model}',
|
|
2083
|
-
authLevel: 'function',
|
|
2084
|
-
extraInputs: [{ type: 'cosmosDB', name: 'cosmosInput', containerName, ... }],
|
|
2085
|
-
handler: async (request, context) => {
|
|
2086
|
-
const documents = context.extraInputs.get('cosmosInput');
|
|
2087
|
-
const validated = z.array(ModelSchema).parse(documents);
|
|
2088
|
-
return { status: 200, jsonBody: validated };
|
|
2089
|
-
},
|
|
2090
|
-
});
|
|
2091
|
-
\`\`\`` : ''}
|
|
2092
|
-
|
|
2093
|
-
## Naming Conventions
|
|
2094
|
-
|
|
2095
|
-
| Item | Convention | Example |
|
|
2096
|
-
|------|-----------|---------|
|
|
2097
|
-
| Model schema file | \`shared/models/{kebab-case}.ts\` | \`shared/models/todo.ts\` |
|
|
2098
|
-
| Schema/type name | PascalCase (same name for both) | \`export const Todo = z.object({...}); export type Todo = z.infer<typeof Todo>;\` |
|
|
2099
|
-
| Functions handler file | backend-language specific under \`functions/\` | \`${backendLanguage === 'typescript' ? 'functions/src/todo.ts' : backendLanguage === 'csharp' ? 'functions/Crud/TodoCrudFunctions.cs' : 'functions/blueprints/todo.py'}\` |
|
|
2100
|
-
| Functions handler name | \`{camelCase}-{operation}\` | \`todo-get-all\`, \`todo-create\` |
|
|
2101
|
-
| API route path | \`/api/{camelCase}\` | \`/api/todo\`, \`/api/todo/{id}\` |
|
|
2102
|
-
| BFF route file | \`app/api/{kebab-case}/route.ts\` | \`app/api/todo/route.ts\` |
|
|
2103
|
-
| BFF detail route | \`app/api/{kebab-case}/[id]/route.ts\` | \`app/api/todo/[id]/route.ts\` |
|
|
2104
|
-
| UI page directory | \`app/{kebab-case}/\` | \`app/todo/page.tsx\` |
|
|
2105
|
-
| React component | PascalCase | \`TodoForm.tsx\` |
|
|
2106
|
-
| Cosmos DB container | PascalCase + 's' | \`Todos\` |
|
|
2107
|
-
| Cosmos DB partition key | \`/id\` (default) | Custom: \`export const partitionKey = '/field'\` |
|
|
2108
|
-
| Bicep container file | \`infra/containers/{kebab-case}-container.bicep\` | \`infra/containers/todo-container.bicep\` |
|
|
2109
|
-
|
|
2110
|
-
## Adding New Models (SwallowKit CLI)
|
|
2111
|
-
|
|
2112
|
-
Use the SwallowKit CLI — do **not** manually create model files or CRUD boilerplate.
|
|
2113
|
-
For autonomous agents, prefer the plan/apply loop above (or the \`swallowkit-add-model\` skill); the commands below are the human-friendly equivalents.
|
|
2114
|
-
|
|
2115
|
-
### Create a new data model
|
|
2116
|
-
|
|
2117
|
-
\`\`\`bash
|
|
2118
|
-
${runCmd} swallowkit create-model <name>
|
|
2119
|
-
# Multiple models at once:
|
|
2120
|
-
${runCmd} swallowkit create-model user post comment
|
|
2121
|
-
\`\`\`
|
|
2122
|
-
|
|
2123
|
-
Creates \`shared/models/<name>.ts\` with a Zod schema template including \`id\`, \`createdAt\`, \`updatedAt\`.
|
|
2124
|
-
Edit the generated file to add your domain-specific fields, then run scaffold.
|
|
2125
|
-
|
|
2126
|
-
### Generate full CRUD from a model
|
|
2127
|
-
|
|
2128
|
-
\`\`\`bash
|
|
2129
|
-
${runCmd} swallowkit scaffold shared/models/<name>.ts
|
|
2130
|
-
\`\`\`
|
|
2131
|
-
|
|
2132
|
-
Generates:
|
|
2133
|
-
- Azure Functions handlers (${backendLanguage === 'typescript' ? '`functions/src/<name>.ts`' : '`functions/` language-specific CRUD files + `functions/generated/` schema assets'})
|
|
2134
|
-
- BFF API routes (\`app/api/<name>/route.ts\`, \`app/api/<name>/[id]/route.ts\`)
|
|
2135
|
-
- UI pages (\`app/<name>/page.tsx\`, detail, create, edit pages)
|
|
2136
|
-
- Cosmos DB Bicep container config (\`infra/containers/<name>-container.bicep\`)
|
|
2137
|
-
|
|
2138
|
-
### Start development servers
|
|
2139
|
-
|
|
2140
|
-
\`\`\`bash
|
|
2141
|
-
${runCmd} swallowkit dev
|
|
2142
|
-
\`\`\`
|
|
2143
|
-
|
|
2144
|
-
Runs Next.js (http://localhost:3000) and Azure Functions (http://localhost:7071) concurrently.
|
|
2145
|
-
Checks for Cosmos DB Emulator availability.
|
|
2146
|
-
|
|
2147
|
-
### Provision Azure resources
|
|
2148
|
-
|
|
2149
|
-
\`\`\`bash
|
|
2150
|
-
${runCmd} swallowkit provision --resource-group <name> --location <region>
|
|
2151
|
-
\`\`\`
|
|
2152
|
-
|
|
2153
|
-
Deploys Bicep infrastructure: Static Web Apps, Functions, Cosmos DB, Storage, Managed Identity.
|
|
2154
|
-
|
|
2155
|
-
### Typical workflow for "add a new feature/model"
|
|
2156
|
-
|
|
2157
|
-
1. \`${runCmd} swallowkit create-model <name>\`
|
|
2158
|
-
2. Edit \`shared/models/<name>.ts\` — add fields
|
|
2159
|
-
3. \`${runCmd} swallowkit scaffold shared/models/<name>.ts\`
|
|
2160
|
-
4. \`${runCmd} swallowkit dev\` — verify at http://localhost:3000/<name>
|
|
2161
|
-
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.
|
|
2162
|
-
|
|
2163
|
-
## Do NOT
|
|
2164
|
-
|
|
2165
|
-
- **Do not** put business logic or database calls in \`app/api/\` routes. They are BFF only.
|
|
2166
|
-
- **Do not** define TypeScript interfaces/types separately from Zod schemas. Always derive types with \`z.infer<>\`.
|
|
2167
|
-
- **Do not** manually duplicate model definitions across layers. Use the shared package.
|
|
2168
|
-
- **Do not** manually create CRUD boilerplate. Use \`swallowkit scaffold\`.
|
|
2169
|
-
- **Do not** hardcode Cosmos DB connection strings. Use Managed Identity (\`CosmosDBConnection__accountEndpoint\`) in production and emulator settings locally.
|
|
2170
|
-
- 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.
|
|
2171
|
-
|
|
2172
|
-
## Technology Stack
|
|
2173
|
-
|
|
2174
|
-
- **Frontend**: Next.js (App Router), React, TypeScript, Tailwind CSS
|
|
2175
|
-
- **BFF**: Next.js API Routes (proxy only)
|
|
2176
|
-
- **Backend**: Azure Functions (${backendLanguageLabel})
|
|
2177
|
-
- **Database**: Azure Cosmos DB (NoSQL)
|
|
2178
|
-
- **Schema**: Zod (shared across all layers via workspace package)
|
|
2179
|
-
- **Infrastructure**: Bicep (IaC)
|
|
2180
|
-
- **Hosting**: Azure Static Web Apps (frontend) + Azure Functions Flex Consumption (backend)
|
|
2181
|
-
- **Auth**: Azure Managed Identity (no connection strings in production)
|
|
2182
|
-
- **Monitoring**: Application Insights
|
|
2183
|
-
`;
|
|
2184
|
-
fs.writeFileSync(path.join(projectDir, 'AGENTS.md'), agentsMd);
|
|
2185
|
-
console.log(' ✅ AGENTS.md (Codex / generic agents)');
|
|
2186
|
-
// ── 2. CLAUDE.md (Claude Code) ─────────────────────────────────────
|
|
2187
|
-
const claudeMd = `# CLAUDE.md
|
|
2188
|
-
|
|
2189
|
-
This file is for Claude Code. Read AGENTS.md in the project root for the full architecture, conventions, and rules.
|
|
2190
|
-
|
|
2191
|
-
## Quick Reference
|
|
2192
|
-
|
|
2193
|
-
- **Architecture**: Next.js (frontend) → BFF (API routes, proxy only) → Azure Functions (backend) → Cosmos DB
|
|
2194
|
-
- **Schema**: Zod schemas in \`shared/models/\` are the single source of truth. Never define types separately.
|
|
2195
|
-
- **BFF rule**: \`app/api/\` routes must ONLY proxy to Azure Functions via \`callFunction()\`. No business logic.
|
|
2196
|
-
- **Backend language**: ${backendLanguageLabel}
|
|
2197
|
-
- **Backend rule**: Regenerate backend contracts with \`swallowkit scaffold\` after schema changes and keep \`functions/generated/\` in sync.
|
|
2198
|
-
|
|
2199
|
-
## SwallowKit MCP
|
|
2200
|
-
|
|
2201
|
-
- 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.
|
|
2202
|
-
- When the \`swallowkit_*\` tools are available, prefer them for inspect / validate / generate tasks.
|
|
2203
|
-
- If MCP is unavailable, use \`${runCmd} swallowkit machine ...\` instead.
|
|
2204
|
-
- For generation, prefer the two-phase flow: \`plan scaffold <name>\` → \`apply scaffold --plan <planId>\` → \`verify project\`. Runbooks: \`.swallowkit/workflows/\`.
|
|
2205
|
-
- 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.
|
|
2206
|
-
- Boundary contract (what you may edit freely vs what SwallowKit regenerates): \`${runCmd} swallowkit machine inspect boundaries\`
|
|
2207
|
-
- **Always invoke SwallowKit via \`${runCmd}\`.** Do not mix package manager commands.
|
|
2208
|
-
|
|
2209
|
-
## SwallowKit CLI Commands
|
|
2210
|
-
|
|
2211
|
-
| Task | Command |
|
|
2212
|
-
|------|---------|
|
|
2213
|
-
| Create model | \`${runCmd} swallowkit create-model <name>\` |
|
|
2214
|
-
| Generate CRUD | \`${runCmd} swallowkit scaffold shared/models/<name>.ts\` |
|
|
2215
|
-
| Dev servers | \`${runCmd} swallowkit dev\` |
|
|
2216
|
-
| Provision Azure | \`${runCmd} swallowkit provision --resource-group <rg> --location <region>\` |
|
|
2217
|
-
|
|
2218
|
-
## Workflow: Add a new model
|
|
2219
|
-
|
|
2220
|
-
1. \`${runCmd} swallowkit create-model <name>\`
|
|
2221
|
-
2. Edit \`shared/models/<name>.ts\` — add your fields
|
|
2222
|
-
3. \`${runCmd} swallowkit scaffold shared/models/<name>.ts\`
|
|
2223
|
-
4. \`${runCmd} swallowkit dev\` — verify at http://localhost:3000/<name>
|
|
2224
|
-
5. If \`dev-seeds/\` exists, update the seed JSON files to include data for the new model and adjust existing seeds if relationships changed.
|
|
2225
|
-
`;
|
|
2226
|
-
fs.writeFileSync(path.join(projectDir, 'CLAUDE.md'), claudeMd);
|
|
2227
|
-
console.log(' ✅ CLAUDE.md (Claude Code)');
|
|
2228
|
-
fs.writeFileSync(path.join(projectDir, '.mcp.json'), projectMcpConfigSource);
|
|
1886
|
+
(0, agent_instructions_1.writeAgentInstructionFiles)(projectDir, {
|
|
1887
|
+
projectName,
|
|
1888
|
+
backendLanguage,
|
|
1889
|
+
packageManager: pm,
|
|
1890
|
+
});
|
|
1891
|
+
console.log(' ✅ AGENTS.md (canonical project contract)');
|
|
1892
|
+
console.log(' ✅ CLAUDE.md (Claude Code adapter)');
|
|
1893
|
+
console.log(' ✅ .github/copilot-instructions.md (GitHub Copilot adapter)');
|
|
1894
|
+
console.log(' ✅ .github/instructions/ (path-specific instructions)');
|
|
1895
|
+
fs.writeFileSync(path.join(projectDir, '.mcp.json'), buildSwallowKitMcpProjectConfigSource(pm));
|
|
2229
1896
|
console.log(' ✅ .mcp.json (project-scoped MCP bootstrap)');
|
|
2230
|
-
// ── 3. .github/copilot-instructions.md (GitHub Copilot) ────────────
|
|
2231
|
-
const ghDir = path.join(projectDir, '.github');
|
|
2232
|
-
fs.mkdirSync(ghDir, { recursive: true });
|
|
2233
|
-
const copilotInstructions = `# Copilot Instructions
|
|
2234
|
-
|
|
2235
|
-
This project was generated by **SwallowKit**. See \`AGENTS.md\` in the project root for the full specification.
|
|
2236
|
-
|
|
2237
|
-
## Architecture (3-layer)
|
|
2238
|
-
|
|
2239
|
-
\`\`\`
|
|
2240
|
-
Frontend (Next.js App Router) → BFF (Next.js API Routes) → Backend (Azure Functions) → Cosmos DB
|
|
2241
|
-
\`\`\`
|
|
2242
|
-
|
|
2243
|
-
## Key Rules
|
|
2244
|
-
|
|
2245
|
-
1. **BFF is proxy only** — \`app/api/\` routes call Azure Functions via \`callFunction()\`. No business logic, no direct DB access.
|
|
2246
|
-
2. **Zod = single source of truth** — Models live in \`shared/models/\`. Types are derived with \`z.infer<>\`. Never define types separately.
|
|
2247
|
-
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/\`.
|
|
2248
|
-
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.
|
|
2249
|
-
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.
|
|
2250
|
-
|
|
2251
|
-
## SwallowKit Framework Operations
|
|
2252
|
-
|
|
2253
|
-
- Prefer the SwallowKit MCP or machine interface for framework-owned inspection, validation, and generation instead of hand-editing generated files.
|
|
2254
|
-
- If your runtime loads project-scoped MCP config from \`.mcp.json\`, use the \`swallowkit_*\` tools.
|
|
2255
|
-
- 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\`.
|
|
2256
|
-
- 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.
|
|
2257
|
-
- Boundary contract: \`${runCmd} swallowkit machine inspect boundaries\` tells you which files are free to edit and which are regenerated. Runbooks live in \`.swallowkit/workflows/\`.
|
|
2258
|
-
- **Always invoke SwallowKit via \`${runCmd}\`.** Do not mix package manager commands.
|
|
2259
|
-
|
|
2260
|
-
## Naming
|
|
2261
|
-
|
|
2262
|
-
- Schema/type: PascalCase, same name for both (\`export const Todo = z.object({...}); export type Todo = z.infer<typeof Todo>;\`)
|
|
2263
|
-
- Files: kebab-case (\`shared/models/todo.ts\`, backend handlers under \`functions/\`)
|
|
2264
|
-
- Cosmos DB containers: PascalCase + 's' (\`Todos\`), partition key default \`/id\` (customizable via \`export const partitionKey\`)
|
|
2265
|
-
|
|
2266
|
-
## Managed Fields
|
|
2267
|
-
|
|
2268
|
-
\`id\`, \`createdAt\`, \`updatedAt\` are auto-managed by the backend. Define them as \`optional()\` in schemas. Never trust client-sent values.
|
|
2269
|
-
`;
|
|
2270
|
-
fs.writeFileSync(path.join(ghDir, 'copilot-instructions.md'), copilotInstructions);
|
|
2271
|
-
console.log(' ✅ .github/copilot-instructions.md (GitHub Copilot)');
|
|
2272
|
-
// ── 4. .github/instructions/*.instructions.md (Copilot layer-specific) ──
|
|
2273
|
-
const instructionsDir = path.join(ghDir, 'instructions');
|
|
2274
|
-
fs.mkdirSync(instructionsDir, { recursive: true });
|
|
2275
|
-
// 4a. shared/models — Zod schema layer
|
|
2276
|
-
const sharedModelsInstructions = `---
|
|
2277
|
-
applyTo: "shared/models/**"
|
|
2278
|
-
---
|
|
2279
|
-
|
|
2280
|
-
# Shared Models — Zod Schema Rules
|
|
2281
|
-
|
|
2282
|
-
Files in this directory are the **single source of truth** for data models across the entire application.
|
|
2283
|
-
|
|
2284
|
-
## Rules
|
|
2285
|
-
|
|
2286
|
-
- Define Zod schemas using \`zod/v4\` (\`import { z } from 'zod/v4'\`).
|
|
2287
|
-
- Use the **Zod official pattern**: the schema constant and the TypeScript type share the same name.
|
|
2288
|
-
\`\`\`typescript
|
|
2289
|
-
export const Todo = z.object({ ... });
|
|
2290
|
-
export type Todo = z.infer<typeof Todo>;
|
|
2291
|
-
\`\`\`
|
|
2292
|
-
- Always include \`id: z.string()\`, \`createdAt: z.string().optional()\`, \`updatedAt: z.string().optional()\`. These are managed by the backend.
|
|
2293
|
-
- Export a \`displayName\` string constant for UI display.
|
|
2294
|
-
- Re-export every model from \`shared/index.ts\`.
|
|
2295
|
-
- For relationships, use **nested schemas** (import and embed the related schema), not ID references.
|
|
2296
|
-
- After editing a model, run \`${runCmd} swallowkit scaffold shared/models/<name>.ts\` to regenerate CRUD code.
|
|
2297
|
-
`;
|
|
2298
|
-
fs.writeFileSync(path.join(instructionsDir, 'shared-models.instructions.md'), sharedModelsInstructions);
|
|
2299
|
-
// 4b. app/api — BFF layer
|
|
2300
|
-
const bffInstructions = `---
|
|
2301
|
-
applyTo: "app/api/**"
|
|
2302
|
-
---
|
|
2303
|
-
|
|
2304
|
-
# BFF API Routes — Rules
|
|
2305
|
-
|
|
2306
|
-
Files in \`app/api/\` are the **BFF (Backend for Frontend)** layer. They exist solely to proxy requests to Azure Functions.
|
|
2307
|
-
|
|
2308
|
-
## Rules
|
|
2309
|
-
|
|
2310
|
-
- **Never** put business logic, database access, or direct Cosmos DB calls here.
|
|
2311
|
-
- Use \`callFunction()\` from \`@/lib/api/call-function\` to forward requests to Azure Functions.
|
|
2312
|
-
- You may validate input/output with Zod schemas before forwarding.
|
|
2313
|
-
- Import schemas from \`@${projectName}/shared\`.
|
|
2314
|
-
|
|
2315
|
-
## Pattern
|
|
2316
|
-
|
|
2317
|
-
\`\`\`typescript
|
|
2318
|
-
import { callFunction } from '@/lib/api/call-function';
|
|
2319
|
-
import { ModelSchema } from '@${projectName}/shared';
|
|
2320
|
-
import { z } from 'zod/v4';
|
|
2321
|
-
|
|
2322
|
-
export async function GET() {
|
|
2323
|
-
return callFunction({
|
|
2324
|
-
method: 'GET',
|
|
2325
|
-
path: '/api/{model}',
|
|
2326
|
-
responseSchema: z.array(ModelSchema),
|
|
2327
|
-
});
|
|
2328
|
-
}
|
|
2329
|
-
\`\`\`
|
|
2330
|
-
`;
|
|
2331
|
-
fs.writeFileSync(path.join(instructionsDir, 'bff-routes.instructions.md'), bffInstructions);
|
|
2332
|
-
// 4c. functions — Azure Functions backend layer
|
|
2333
|
-
const functionsInstructions = `---
|
|
2334
|
-
applyTo: "functions/**"
|
|
2335
|
-
---
|
|
2336
|
-
|
|
2337
|
-
# Azure Functions — Backend Rules
|
|
2338
|
-
|
|
2339
|
-
Files in \`functions/\` contain all business logic and data access for this application.
|
|
2340
|
-
|
|
2341
|
-
## Rules
|
|
2342
|
-
|
|
2343
|
-
- Keep backend contracts aligned with \`shared/models/\` by rerunning \`swallowkit scaffold\` after schema changes.
|
|
2344
|
-
- For TypeScript backends, use Cosmos DB **input/output bindings** (\`extraInputs\`/\`extraOutputs\`) for reads and writes.
|
|
2345
|
-
- For C#/Python backends, consume the native-generated assets in \`functions/generated/\`.
|
|
2346
|
-
- Auto-generate \`id\` (UUID), \`createdAt\`, and \`updatedAt\` on the backend. Never trust client-sent values.
|
|
2347
|
-
- Container names are PascalCase + 's' (e.g., \`Todos\`). Partition key defaults to \`/id\` but can be customized per model.
|
|
2348
|
-
|
|
2349
|
-
## Handler Pattern
|
|
2350
|
-
|
|
2351
|
-
\`\`\`typescript
|
|
2352
|
-
import { app } from '@azure/functions';
|
|
2353
|
-
import { ModelSchema } from '@${projectName}/shared';
|
|
2354
|
-
|
|
2355
|
-
app.http('{model}-get-all', {
|
|
2356
|
-
methods: ['GET'],
|
|
2357
|
-
route: '{model}',
|
|
2358
|
-
authLevel: 'function',
|
|
2359
|
-
extraInputs: [cosmosInput],
|
|
2360
|
-
handler: async (request, context) => {
|
|
2361
|
-
const documents = context.extraInputs.get(cosmosInput);
|
|
2362
|
-
const validated = z.array(ModelSchema).parse(documents);
|
|
2363
|
-
return { status: 200, jsonBody: validated };
|
|
2364
|
-
},
|
|
2365
|
-
});
|
|
2366
|
-
\`\`\`
|
|
2367
|
-
`;
|
|
2368
|
-
fs.writeFileSync(path.join(instructionsDir, 'azure-functions.instructions.md'), functionsInstructions);
|
|
2369
|
-
console.log(' ✅ .github/instructions/ (Copilot layer-specific instructions)');
|
|
2370
|
-
console.log(' - shared-models.instructions.md');
|
|
2371
|
-
console.log(' - bff-routes.instructions.md');
|
|
2372
|
-
console.log(' - azure-functions.instructions.md');
|
|
2373
|
-
// ── 5. .swallowkit/workflows/*.md (agent-agnostic runbooks) ────────
|
|
2374
1897
|
(0, workflows_1.writeWorkflowDocs)(projectDir, runCmd);
|
|
2375
1898
|
console.log(' ✅ .swallowkit/workflows/ (agent-agnostic autonomous-loop runbooks)');
|
|
2376
|
-
// ── 6. .github/skills/<name>/SKILL.md (Agent Skills, agentskills.io) ─
|
|
2377
1899
|
const skillPaths = (0, workflows_1.writeAgentSkills)(projectDir, runCmd);
|
|
2378
1900
|
console.log(' ✅ .github/skills/ (Agent Skills — agentskills.io open standard)');
|
|
2379
1901
|
for (const skillPath of skillPaths) {
|
|
2380
1902
|
console.log(` - ${skillPath}`);
|
|
2381
1903
|
}
|
|
2382
1904
|
console.log('\n✅ AI agent files created\n');
|
|
2383
|
-
console.log(' Supported agents:');
|
|
2384
|
-
console.log(' - OpenAI Codex → AGENTS.md');
|
|
2385
|
-
console.log(' - Claude Code → CLAUDE.md (+ AGENTS.md)');
|
|
2386
|
-
console.log(' - Project MCP runtimes → .mcp.json');
|
|
2387
|
-
console.log(' - GitHub Copilot → .github/copilot-instructions.md');
|
|
2388
|
-
console.log(' - GitHub Copilot (edit) → .github/instructions/*.instructions.md');
|
|
2389
|
-
console.log(' - Skills-aware agents → .github/skills/*/SKILL.md');
|
|
2390
|
-
console.log('');
|
|
2391
1905
|
}
|
|
2392
1906
|
function buildFunctionsHostKeyBicepExpression() {
|
|
2393
1907
|
return "listKeys('${resourceId('Microsoft.Web/sites', functionsAppName)}/host/default', '2023-12-01').functionKeys.default";
|