@cogito.ai/cli 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/registry.json +3 -13
  2. package/dist/templates/web-nextjs/.github/copilot-instructions.md +36 -14
  3. package/dist/templates/web-nextjs/AGENTS.md +14 -11
  4. package/dist/templates/web-nextjs/README.md +37 -30
  5. package/dist/templates/web-nextjs/apps/docs/.source/browser.ts +12 -0
  6. package/dist/templates/web-nextjs/apps/docs/.source/dynamic.ts +8 -0
  7. package/dist/templates/web-nextjs/apps/docs/.source/server.ts +19 -0
  8. package/dist/templates/web-nextjs/apps/docs/.source/source.config.mjs +10 -0
  9. package/dist/templates/web-nextjs/apps/docs/app/(home)/page.tsx +5 -0
  10. package/dist/templates/web-nextjs/apps/docs/app/api/search/route.ts +4 -0
  11. package/dist/templates/web-nextjs/apps/docs/app/docs/[[...slug]]/page.tsx +41 -0
  12. package/dist/templates/web-nextjs/apps/docs/app/docs/layout.tsx +14 -0
  13. package/dist/templates/web-nextjs/apps/docs/app/global.css +3 -0
  14. package/dist/templates/web-nextjs/apps/docs/app/layout.tsx +13 -0
  15. package/dist/templates/web-nextjs/apps/docs/app/llms-full.txt/route.ts +11 -0
  16. package/dist/templates/web-nextjs/apps/docs/app/llms.txt/route.ts +8 -0
  17. package/dist/templates/web-nextjs/apps/docs/content/docs/changelog/.gitkeep +2 -0
  18. package/dist/templates/web-nextjs/apps/docs/content/docs/changelog/index.mdx +9 -0
  19. package/dist/templates/web-nextjs/apps/docs/content/docs/changelog/meta.json +3 -0
  20. package/dist/templates/web-nextjs/apps/docs/content/docs/decisions/.gitkeep +0 -0
  21. package/dist/templates/web-nextjs/apps/docs/content/docs/decisions/meta.json +4 -0
  22. package/dist/templates/web-nextjs/apps/docs/content/docs/features/hello.mdx +29 -0
  23. package/dist/templates/web-nextjs/apps/docs/content/docs/features/meta.json +4 -0
  24. package/dist/templates/web-nextjs/apps/docs/content/docs/index.mdx +6 -0
  25. package/dist/templates/web-nextjs/apps/docs/content/docs/meta.json +4 -0
  26. package/dist/templates/web-nextjs/apps/docs/content/docs/roadmap/.gitkeep +2 -0
  27. package/dist/templates/web-nextjs/apps/docs/content/docs/roadmap/index.mdx +29 -0
  28. package/dist/templates/web-nextjs/apps/docs/content/docs/roadmap/meta.json +3 -0
  29. package/dist/templates/web-nextjs/apps/docs/eslint.config.js +10 -0
  30. package/dist/templates/web-nextjs/apps/docs/lib/source.ts +7 -0
  31. package/dist/templates/web-nextjs/apps/docs/next.config.ts +14 -0
  32. package/dist/templates/web-nextjs/apps/docs/package.json +38 -0
  33. package/dist/templates/web-nextjs/apps/docs/postcss.config.mjs +8 -0
  34. package/dist/templates/web-nextjs/apps/docs/source.config.ts +7 -0
  35. package/dist/templates/web-nextjs/apps/docs/tsconfig.json +26 -0
  36. package/dist/templates/web-nextjs/apps/web/.github/copilot-instructions.md +65 -0
  37. package/dist/templates/web-nextjs/apps/web/next-env.d.ts +6 -0
  38. package/dist/templates/web-nextjs/{next.config.ts → apps/web/next.config.ts} +6 -1
  39. package/dist/templates/web-nextjs/apps/web/package.json +33 -0
  40. package/dist/templates/web-nextjs/openspec/config.yaml +20 -7
  41. package/dist/templates/web-nextjs/openspec/roadmap.yaml +31 -0
  42. package/dist/templates/web-nextjs/package.json +10 -21
  43. package/dist/templates/web-nextjs/packages/eslint-config/CHANGELOG.md +7 -0
  44. package/dist/templates/web-nextjs/packages/eslint-config/base.js +34 -0
  45. package/dist/templates/web-nextjs/packages/eslint-config/features.js +86 -0
  46. package/dist/templates/web-nextjs/packages/eslint-config/next.js +24 -0
  47. package/dist/templates/web-nextjs/packages/eslint-config/package.json +22 -0
  48. package/dist/templates/web-nextjs/packages/openspec-docs-sync/package.json +24 -0
  49. package/dist/templates/web-nextjs/packages/openspec-docs-sync/src/index.ts +290 -0
  50. package/dist/templates/web-nextjs/packages/openspec-docs-sync/tsconfig.json +17 -0
  51. package/dist/templates/web-nextjs/packages/tsconfig/CHANGELOG.md +7 -0
  52. package/dist/templates/web-nextjs/packages/tsconfig/base.json +11 -0
  53. package/dist/templates/web-nextjs/packages/tsconfig/package.json +10 -0
  54. package/dist/templates/web-nextjs/pnpm-lock.yaml +6722 -0
  55. package/dist/templates/web-nextjs/pnpm-workspace.yaml +3 -0
  56. package/dist/templates/web-nextjs/roadmap.yaml +31 -0
  57. package/dist/templates/web-nextjs/turbo.json +18 -0
  58. package/package.json +1 -1
  59. /package/dist/templates/web-nextjs/{next-env.d.ts → apps/docs/next-env.d.ts} +0 -0
  60. /package/dist/templates/web-nextjs/{eslint.config.js → apps/web/eslint.config.js} +0 -0
  61. /package/dist/templates/web-nextjs/{messages → apps/web/messages}/en.json +0 -0
  62. /package/dist/templates/web-nextjs/{messages → apps/web/messages}/zh.json +0 -0
  63. /package/dist/templates/web-nextjs/{middleware.ts → apps/web/middleware.ts} +0 -0
  64. /package/dist/templates/web-nextjs/{src → apps/web/src}/app/[locale]/globals.css +0 -0
  65. /package/dist/templates/web-nextjs/{src → apps/web/src}/app/[locale]/hello/page.tsx +0 -0
  66. /package/dist/templates/web-nextjs/{src → apps/web/src}/app/[locale]/layout.tsx +0 -0
  67. /package/dist/templates/web-nextjs/{src → apps/web/src}/app/[locale]/page.tsx +0 -0
  68. /package/dist/templates/web-nextjs/{src → apps/web/src}/core/repositories/.gitkeep +0 -0
  69. /package/dist/templates/web-nextjs/{src → apps/web/src}/core/repositories/IGreetingRepository.ts +0 -0
  70. /package/dist/templates/web-nextjs/{src → apps/web/src}/core/types/.gitkeep +0 -0
  71. /package/dist/templates/web-nextjs/{src → apps/web/src}/core/types/greeting.ts +0 -0
  72. /package/dist/templates/web-nextjs/{src → apps/web/src}/features/_experiments/.gitkeep +0 -0
  73. /package/dist/templates/web-nextjs/{src → apps/web/src}/features/hello/__contract__.ts +0 -0
  74. /package/dist/templates/web-nextjs/{src → apps/web/src}/features/hello/hello.test.ts +0 -0
  75. /package/dist/templates/web-nextjs/{src → apps/web/src}/features/hello/index.ts +0 -0
  76. /package/dist/templates/web-nextjs/{src → apps/web/src}/features/hello/service.ts +0 -0
  77. /package/dist/templates/web-nextjs/{src → apps/web/src}/i18n/request.ts +0 -0
  78. /package/dist/templates/web-nextjs/{src → apps/web/src}/infra/db/.gitkeep +0 -0
  79. /package/dist/templates/web-nextjs/{src → apps/web/src}/infra/db/SupabaseGreetingRepository.ts +0 -0
  80. /package/dist/templates/web-nextjs/{src → apps/web/src}/infra/db/client.ts +0 -0
  81. /package/dist/templates/web-nextjs/{src → apps/web/src}/infra/db/schema.ts +0 -0
  82. /package/dist/templates/web-nextjs/{tailwind.config.ts → apps/web/tailwind.config.ts} +0 -0
  83. /package/dist/templates/web-nextjs/{tsconfig.json → apps/web/tsconfig.json} +0 -0
  84. /package/dist/templates/web-nextjs/{vitest.config.ts → apps/web/vitest.config.ts} +0 -0
@@ -4,22 +4,12 @@
4
4
  {
5
5
  "id": "web-nextjs",
6
6
  "name": "@cogito.ai/template-web-nextjs",
7
- "description": "Full-stack Next.js 16 starter with Supabase, next-intl, Tailwind CSS and Vitest",
7
+ "description": "Full-stack Next.js 16 monorepo starter with Supabase, next-intl, Tailwind CSS, Vitest and built-in Fumadocs docs site",
8
8
  "minCliVersion": "0.1.0",
9
9
  "source": "templates/web-nextjs",
10
10
  "resolvedDependencies": {
11
- "@supabase/ssr": "^0.10.3",
12
- "next": "16",
13
- "next-intl": "^4.13.0",
14
- "react": "19",
15
- "react-dom": "19",
16
- "@vitejs/plugin-react": "^6.0.2",
17
- "tailwindcss": "^4.3.0",
18
- "typescript": "^6.0.3",
19
- "vitest": "^4.1.8",
20
- "@cogito.ai/eslint-config": "^0.2.0",
21
- "@cogito.ai/tsconfig": "^0.2.0",
22
- "@fission-ai/openspec": "^1.3.1"
11
+ "@fission-ai/openspec": "^1.3.1",
12
+ "turbo": "latest"
23
13
  }
24
14
  }
25
15
  ]
@@ -2,25 +2,45 @@
2
2
 
3
3
  > Applies to: GitHub Copilot (chat + completions) in any project generated from this template.
4
4
 
5
+ ## Monorepo Structure
6
+
7
+ This project is a turborepo + pnpm monorepo with two applications:
8
+
9
+ | Directory | Purpose |
10
+ | ------------ | -------------------------------------------------------------------- |
11
+ | `apps/web/` | Main Next.js 16 application (four-layer contract, features, i18n) |
12
+ | `apps/docs/` | Fumadocs documentation site (features, decisions, changelog, roadmap)|
13
+ | `packages/` | Shared tooling packages (eslint-config, tsconfig) |
14
+
15
+ Run all commands from the monorepo root: `pnpm build`, `pnpm lint`, `pnpm test`, `pnpm check-types`.
16
+
5
17
  ## Directory Contract
6
18
 
7
- This project enforces a four-layer directory contract. **Before placing any code**, confirm which layer it belongs to:
19
+ This project enforces a four-layer directory contract inside `apps/web/`. **Before placing any code**, confirm which layer it belongs to:
8
20
 
9
- | Layer | Path | Purpose | Rules |
10
- | --------------- | ---------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------- |
11
- | **core** | `src/core/` | Stable domain layer — types, repository interfaces, pure logic | No framework imports, no DB clients, read-only |
12
- | **features** | `src/features/` | AI coding zone — business features | Must have `__contract__.ts`; no direct DB access; no cross-feature imports |
13
- | **infra** | `src/infra/` | Infrastructure — Supabase clients, third-party SDKs | Requires approval; only `core/repositories` implementations live here |
14
- | **experiments** | `src/features/_experiments/` | Sandbox | Never imported by non-experimental features |
21
+ | Layer | Path | Purpose | Rules |
22
+ | --------------- | ------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------- |
23
+ | **core** | `apps/web/src/core/` | Stable domain layer — types, repository interfaces, pure logic | No framework imports, no DB clients, read-only |
24
+ | **features** | `apps/web/src/features/` | AI coding zone — business features | Must have `__contract__.ts`; no direct DB access; no cross-feature imports |
25
+ | **infra** | `apps/web/src/infra/` | Infrastructure — Supabase clients, third-party SDKs | Requires approval; only `core/repositories` implementations live here |
26
+ | **experiments** | `apps/web/src/features/_experiments/` | Sandbox | Never imported by non-experimental features |
15
27
 
16
28
  ## Layer 2 Architecture Rules (error-level, enforced by ESLint)
17
29
 
18
- Four rules are enforced at `error` severity in `src/features/**`. Violations fail `pnpm lint`.
30
+ Four rules are enforced at `error` severity in `apps/web/src/features/**`. Violations fail `pnpm lint`.
19
31
 
20
- 1. **`no-direct-db-in-features`** — Features must not import from `infra/db`. Use repository interfaces from `src/core/repositories/` instead.
32
+ 1. **`no-direct-db-in-features`** — Features must not import from `infra/db`. Use repository interfaces from `apps/web/src/core/repositories/` instead.
21
33
  2. **`require-feature-contract`** — Every feature subdirectory must contain `__contract__.ts` declaring its public API boundary.
22
34
  3. **`no-cross-feature`** — Features must not directly import from sibling feature internals. Import through the feature's `index.ts` only.
23
- 4. **`no-core-mutation`** — `src/core/` is read-only. Features and infra must not modify core types or interfaces in-place.
35
+ 4. **`no-core-mutation`** — `apps/web/src/core/` is read-only. Features and infra must not modify core types or interfaces in-place.
36
+
37
+ ## Docs Co-evolution
38
+
39
+ Documentation lives alongside the application and grows with it:
40
+
41
+ - **Feature docs**: When adding a new feature, create `apps/docs/content/docs/features/<name>.mdx` documenting its purpose, API, and architecture notes.
42
+ - **Architecture decisions**: Record significant decisions in `apps/docs/content/docs/decisions/<adr-id>.mdx` (e.g., `001-database-choice.mdx`).
43
+ - **Changelog & Roadmap**: After archiving a change in `openspec/`, run `pnpm docs:sync` from the monorepo root to auto-generate changelog and roadmap pages in `apps/docs/`.
24
44
 
25
45
  ## Hard Rules
26
46
 
@@ -28,16 +48,18 @@ Four rules are enforced at `error` severity in `src/features/**`. Violations fai
28
48
  2. **TypeScript strict** — `strict: true` enforced. No `any`, no `// @ts-ignore` without explanation.
29
49
  3. **Conventional commits** — `type(scope): summary` format required.
30
50
  4. **pnpm only** — Do not use `npm install` or `yarn`. Always `pnpm add`.
31
- 5. **ESLint config** — Architecture rules come from `packages/eslint-config/features.js` in the AgentDock platform.
51
+ 5. **ESLint config** — Architecture rules come from `packages/eslint-config/features.js`.
32
52
 
33
53
  ## Feature Development Pattern
34
54
 
35
- When adding a new feature `src/features/<name>/`:
55
+ When adding a new feature `apps/web/src/features/<name>/`:
36
56
 
37
57
  1. Create `__contract__.ts` first — declare input/output types and public API.
38
58
  2. Create `service.ts` — pure business logic, no side effects.
39
59
  3. Create `index.ts` — only export what `__contract__.ts` declares.
40
60
  4. Create `<name>.test.ts` — Vitest unit tests.
41
- 5. Create page/component in `src/app/[locale]/` to consume the feature.
61
+ 5. Create page/component in `apps/web/src/app/[locale]/` to consume the feature.
62
+ 6. Create `apps/docs/content/docs/features/<name>.mdx` — feature documentation.
63
+
64
+ Reference implementation: `apps/web/src/features/hello/`.
42
65
 
43
- Reference implementation: `src/features/hello/`.
@@ -11,36 +11,39 @@
11
11
 
12
12
  ### May execute autonomously
13
13
 
14
- - `pnpm install`, `pnpm build`, `pnpm check-types`, `pnpm lint`, `pnpm test`
14
+ - `pnpm install`, `pnpm build`, `pnpm check-types`, `pnpm lint`, `pnpm test`, `pnpm docs:sync`
15
15
  - Creating / editing files within the current task scope
16
- - Adding new features inside `src/features/` (following the contract pattern)
17
- - Adding repository interfaces to `src/core/repositories/`
18
- - Updating translations in `messages/`
19
- - Writing or updating tests in `src/**/*.test.ts`
16
+ - Adding new features inside `apps/web/src/features/` (following the contract pattern)
17
+ - Adding repository interfaces to `apps/web/src/core/repositories/`
18
+ - Updating translations in `apps/web/messages/`
19
+ - Writing or updating tests in `apps/web/src/**/*.test.ts`
20
+ - Creating / updating MDX documentation in `apps/docs/content/` (feature docs, ADRs)
20
21
  - Running `openspec` CLI commands (read-only: `list`, `status`, `instructions`, `validate`)
21
22
 
22
23
  ### Must pause and confirm
23
24
 
24
25
  - Any `git push`, `git push --force`, or publishing to a registry
25
26
  - Deleting files (including tracked files)
26
- - Adding new **top-level** directories outside the four-layer contract (`core/`, `features/`, `infra/`, `app/`)
27
- - Adding new `dependencies` or `devDependencies` to `package.json`
27
+ - Adding new **top-level** directories outside the monorepo contract (`apps/`, `packages/`)
28
+ - Adding new directories outside the four-layer contract inside `apps/web/src/` (`core/`, `features/`, `infra/`, `app/`)
29
+ - Adding new `dependencies` or `devDependencies` to any `package.json`
28
30
  - Any change to `openspec/config.yaml`
29
- - Modifying `middleware.ts` (affects routing for all locales)
31
+ - Modifying `apps/web/middleware.ts` (affects routing for all locales)
30
32
 
31
33
  ### Prohibited
32
34
 
33
35
  - Writing real secrets, API keys, or credentials anywhere
34
36
  - Running `rm -rf` on tracked directories
35
37
  - Bypassing git hooks with `--no-verify`
36
- - Importing from `src/infra/db/` inside `src/features/**` (violates Layer 2 rules)
38
+ - Importing from `apps/web/src/infra/db/` inside `apps/web/src/features/**` (violates Layer 2 rules)
37
39
  - Creating features without `__contract__.ts` (violates require-feature-contract)
38
40
 
39
41
  ## Acceptance Criteria (before marking a task done)
40
42
 
41
- 1. `pnpm lint` — exits 0, no Layer 2 violations in `src/features/`
43
+ 1. `pnpm lint` — exits 0, no Layer 2 violations in `apps/web/src/features/`
42
44
  2. ESLint ignores build artifacts (at minimum `.next/**`) so generated files are never linted.
43
45
  3. `pnpm build && pnpm lint` — both exit 0 (lint remains stable after a build).
44
46
  4. `pnpm test` — all unit tests pass
45
- 5. `pnpm check-types` — TypeScript strict mode, no errors
47
+ 5. `pnpm check-types` — TypeScript strict mode, no errors in `apps/web` and `apps/docs`
46
48
  6. New features include `__contract__.ts`, `index.ts`, and at least one test
49
+ 7. New features have a corresponding `apps/docs/content/docs/features/<name>.mdx`
@@ -2,7 +2,8 @@
2
2
 
3
3
  > Generated from the [AgentDock](https://github.com/CogitoTech/agentdock) `web-nextjs` template.
4
4
 
5
- Full-stack Next.js 16 starter with Supabase, i18n, Tailwind CSS and strict TypeScript.
5
+ Full-stack Next.js 16 monorepo starter with Supabase, i18n, Tailwind CSS, strict TypeScript,
6
+ and a built-in Fumadocs documentation site.
6
7
  Designed for both human developers and AI coding agents.
7
8
 
8
9
  ## Tech Stack
@@ -18,20 +19,24 @@ Designed for both human developers and AI coding agents.
18
19
  | Package manager | [pnpm](https://pnpm.io) ≥ 9 |
19
20
  | Runtime | Node.js ≥ 18 |
20
21
  | Governance | [OpenSpec](https://github.com/fission-ai/openspec) (`@fission-ai/openspec`) |
22
+ | Monorepo | [Turborepo](https://turbo.build/repo) + pnpm workspaces |
21
23
 
22
24
  ## Directory Structure
23
25
 
24
- ```
25
- src/
26
- ├── app/ # Next.js App Router — pages and layouts (per-locale)
27
- ├── core/ # Domain types + repository interfaces (no framework deps)
28
- ├── features/ # AI coding zoneone directory per feature
29
- └── hello/ # Reference feature (copy this pattern)
30
- ├── infra/ # Supabase implementations (requires human review to edit)
31
- └── db/ # Supabase client + repository implementations
32
- └── i18n/ # next-intl configuration
33
- messages/ # Translation files (en.json, zh.json)
34
- openspec/ # Project governance changes and specs
26
+ ```text
27
+ apps/
28
+ ├── web/
29
+ ├── src/
30
+ │ │ ├── app/ # Next.js App Routerpages and layouts (per-locale)
31
+ │ ├── core/ # Domain types + repository interfaces (no framework deps)
32
+ │ │ ├── features/ # AI coding zone one directory per feature
33
+ │ ├── infra/ # Supabase implementations (requires human review to edit)
34
+ │ │ └── i18n/ # next-intl request configuration
35
+ │ ├── messages/ # Translation files (en.json, zh.json)
36
+ │ └── middleware.ts # Locale routing guard + next-intl middleware
37
+ ├── docs/ # Fumadocs site (features, decisions, changelog, roadmap)
38
+ packages/ # Shared tooling packages (eslint-config, tsconfig, docs sync)
39
+ openspec/ # Project governance — changes and specs
35
40
  ```
36
41
 
37
42
  > **Four-layer contract** is enforced by ESLint Layer 2 rules.
@@ -72,48 +77,50 @@ Open `.env.local` and fill in your values:
72
77
  pnpm dev
73
78
  ```
74
79
 
75
- Open [http://localhost:3000](http://localhost:3000) in your browser.
80
+ Open [http://localhost:3000](http://localhost:3000) for the app and
81
+ [http://localhost:3001](http://localhost:3001) for docs.
76
82
 
77
83
  ## Development
78
84
 
79
85
  ### Common commands
80
86
 
81
87
  ```bash
82
- pnpm dev # Start dev server (http://localhost:3000)
83
- pnpm build # Production build
84
- pnpm start # Serve production build
85
- pnpm test # Run Vitest unit tests
86
- pnpm check-types # TypeScript type check (no emit)
88
+ pnpm dev # Start all workspace dev tasks
89
+ pnpm build # Build all workspace packages/apps
90
+ pnpm test # Run tests (currently apps/web Vitest)
91
+ pnpm check-types # TypeScript check across apps/web and apps/docs
87
92
  pnpm lint # ESLint (includes Layer 2 architectural rules)
93
+ pnpm docs:sync # Generate changelog/roadmap docs from openspec archive
88
94
  ```
89
95
 
90
96
  ### Adding a new feature
91
97
 
92
- Features live in `src/features/`. Follow the reference implementation in `src/features/hello/`:
98
+ Features live in `apps/web/src/features/`. Follow the reference implementation in `apps/web/src/features/hello/`:
93
99
 
94
100
  ```
95
- src/features/<your-feature>/
101
+ apps/web/src/features/<your-feature>/
96
102
  ├── __contract__.ts # Public API surface (required — export types and functions)
97
103
  ├── index.ts # Re-exports from __contract__.ts
98
104
  └── *.test.ts # Vitest unit tests
99
105
  ```
100
106
 
101
107
  Rules:
102
- - Features import from `src/core/` (domain interfaces) — never from `src/infra/` directly.
108
+ - Features import from `apps/web/src/core/` (domain interfaces) — never from `apps/web/src/infra/` directly.
103
109
  - Every feature directory **must** have `__contract__.ts` (ESLint enforces this).
104
- - Add translations to `messages/en.json` and `messages/zh.json`.
110
+ - Add translations to `apps/web/messages/en.json` and `apps/web/messages/zh.json`.
105
111
 
106
112
  ### Adding a language
107
113
 
108
- 1. Add locale to `src/i18n/routing.ts` and `middleware.ts`.
109
- 2. Create `messages/<locale>.json` with translated keys.
114
+ 1. Add locale to `apps/web/middleware.ts` routing config.
115
+ 2. Create `apps/web/messages/<locale>.json` with translated keys.
116
+ 3. Ensure `apps/web/src/i18n/request.ts` can load the new locale JSON.
110
117
 
111
118
  ### Running tests
112
119
 
113
120
  ```bash
114
121
  pnpm test # Run all tests once
115
- pnpm test --watch # Watch mode
116
- pnpm test --coverage # With coverage report
122
+ pnpm --filter @cogito.ai/web test --watch # Watch mode
123
+ pnpm --filter @cogito.ai/web test --coverage # With coverage report
117
124
  ```
118
125
 
119
126
  ## Deployment
@@ -129,7 +136,7 @@ pnpm test --coverage # With coverage report
129
136
 
130
137
  ```bash
131
138
  pnpm build
132
- pnpm start
139
+ pnpm --filter @cogito.ai/web start
133
140
  ```
134
141
 
135
142
  Ensure all `NEXT_PUBLIC_*` variables are set at **build time** (they are inlined by Next.js).
@@ -178,16 +185,16 @@ See `openspec/config.yaml` for project-specific governance rules.
178
185
  A: The `@cogito.ai/tsconfig` and `@cogito.ai/eslint-config` packages must be published to npm before use. If you generated this project before the packages were published, run `pnpm install` again after they are live at [npmjs.com/@agentdock](https://www.npmjs.com/org/cogito.ai).
179
186
 
180
187
  **Q: How do I add a new Supabase table?**
181
- A: Create the table in the Supabase Dashboard, then add a repository interface to `src/core/repositories/` and implement it in `src/infra/db/`. Do not call Supabase directly from `src/features/` — use the interface.
188
+ A: Create the table in the Supabase Dashboard, then add a repository interface to `apps/web/src/core/repositories/` and implement it in `apps/web/src/infra/db/`. Do not call Supabase directly from `apps/web/src/features/` — use the interface.
182
189
 
183
190
  **Q: How do I disable i18n and use a single language?**
184
- A: Set a single locale in `src/i18n/routing.ts` and remove the `[locale]` segment handling in `middleware.ts`. Keep `messages/en.json` and remove unused locale files.
191
+ A: Set a single locale in `apps/web/middleware.ts` and simplify locale segment handling there. Keep `apps/web/messages/en.json` and remove unused locale files.
185
192
 
186
193
  **Q: TypeScript is strict — how do I handle `!` assertions?**
187
194
  A: Prefer explicit checks (`if (!value) throw new Error(...)`) over `!` assertions. If you must use one, add a comment explaining why the value is guaranteed non-null.
188
195
 
189
196
  **Q: Can AI agents work in this project?**
190
- A: Yes. See `AGENTS.md` for the autonomy boundary contract. AI agents may freely edit `src/features/` but must pause for human review before editing `src/infra/` or `middleware.ts`.
197
+ A: Yes. See `AGENTS.md` for the autonomy boundary contract. AI agents may freely edit `apps/web/src/features/` but must pause for human review before editing `apps/web/src/infra/` or `apps/web/middleware.ts`.
191
198
 
192
199
  ## Contributing
193
200
 
@@ -0,0 +1,12 @@
1
+ // @ts-nocheck
2
+ import { browser } from 'fumadocs-mdx/runtime/browser';
3
+ import type * as Config from '../source.config';
4
+
5
+ const create = browser<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
6
+ DocData: {
7
+ }
8
+ }>();
9
+ const browserCollections = {
10
+ docs: create.doc("docs", {"index.mdx": () => import("../content/docs/index.mdx?collection=docs"), "changelog/index.mdx": () => import("../content/docs/changelog/index.mdx?collection=docs"), "features/hello.mdx": () => import("../content/docs/features/hello.mdx?collection=docs"), "roadmap/index.mdx": () => import("../content/docs/roadmap/index.mdx?collection=docs"), }),
11
+ };
12
+ export default browserCollections;
@@ -0,0 +1,8 @@
1
+ // @ts-nocheck
2
+ import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
3
+ import * as Config from '../source.config';
4
+
5
+ const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
6
+ DocData: {
7
+ }
8
+ }>(Config, {"configPath":"source.config.ts","environment":"next","outDir":".source"}, {"doc":{"passthroughs":["extractedReferences"]}});
@@ -0,0 +1,19 @@
1
+ // @ts-nocheck
2
+ import * as __fd_glob_8 from "../content/docs/roadmap/index.mdx?collection=docs"
3
+ import * as __fd_glob_7 from "../content/docs/features/hello.mdx?collection=docs"
4
+ import * as __fd_glob_6 from "../content/docs/changelog/index.mdx?collection=docs"
5
+ import * as __fd_glob_5 from "../content/docs/index.mdx?collection=docs"
6
+ import { default as __fd_glob_4 } from "../content/docs/roadmap/meta.json?collection=docs"
7
+ import { default as __fd_glob_3 } from "../content/docs/features/meta.json?collection=docs"
8
+ import { default as __fd_glob_2 } from "../content/docs/decisions/meta.json?collection=docs"
9
+ import { default as __fd_glob_1 } from "../content/docs/changelog/meta.json?collection=docs"
10
+ import { default as __fd_glob_0 } from "../content/docs/meta.json?collection=docs"
11
+ import { server } from 'fumadocs-mdx/runtime/server';
12
+ import type * as Config from '../source.config';
13
+
14
+ const create = server<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
15
+ DocData: {
16
+ }
17
+ }>({"doc":{"passthroughs":["extractedReferences"]}});
18
+
19
+ export const docs = await create.docs("docs", "content/docs", {"meta.json": __fd_glob_0, "changelog/meta.json": __fd_glob_1, "decisions/meta.json": __fd_glob_2, "features/meta.json": __fd_glob_3, "roadmap/meta.json": __fd_glob_4, }, {"index.mdx": __fd_glob_5, "changelog/index.mdx": __fd_glob_6, "features/hello.mdx": __fd_glob_7, "roadmap/index.mdx": __fd_glob_8, });
@@ -0,0 +1,10 @@
1
+ // source.config.ts
2
+ import { defineConfig, defineDocs } from "fumadocs-mdx/config";
3
+ var docs = defineDocs({
4
+ dir: "content/docs"
5
+ });
6
+ var source_config_default = defineConfig({});
7
+ export {
8
+ source_config_default as default,
9
+ docs
10
+ };
@@ -0,0 +1,5 @@
1
+ import { redirect } from 'next/navigation'
2
+
3
+ export default function HomePage() {
4
+ redirect('/docs')
5
+ }
@@ -0,0 +1,4 @@
1
+ import { source } from '@/lib/source'
2
+ import { createFromSource } from 'fumadocs-core/search/server'
3
+
4
+ export const { GET } = createFromSource(source)
@@ -0,0 +1,41 @@
1
+ import { source } from '@/lib/source'
2
+ import {
3
+ DocsBody,
4
+ DocsDescription,
5
+ DocsPage,
6
+ DocsTitle,
7
+ } from 'fumadocs-ui/layouts/docs/page'
8
+ import { notFound } from 'next/navigation'
9
+
10
+ export default async function Page(props: { params: Promise<{ slug?: string[] }> }) {
11
+ const params = await props.params
12
+ const page = source.getPage(params.slug)
13
+ if (!page) notFound()
14
+
15
+ const MDX = page.data.body
16
+
17
+ return (
18
+ <DocsPage toc={page.data.toc}>
19
+ <DocsTitle>{page.data.title}</DocsTitle>
20
+ <DocsDescription>{page.data.description}</DocsDescription>
21
+ <DocsBody>
22
+ <MDX />
23
+ </DocsBody>
24
+ </DocsPage>
25
+ )
26
+ }
27
+
28
+ export async function generateStaticParams() {
29
+ return source.generateParams()
30
+ }
31
+
32
+ export async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {
33
+ const params = await props.params
34
+ const page = source.getPage(params.slug)
35
+ if (!page) notFound()
36
+
37
+ return {
38
+ title: page.data.title,
39
+ description: page.data.description,
40
+ }
41
+ }
@@ -0,0 +1,14 @@
1
+ import { source } from '@/lib/source'
2
+ import { DocsLayout } from 'fumadocs-ui/layouts/docs'
3
+ import type { ReactNode } from 'react'
4
+
5
+ export default function Layout({ children }: { children: ReactNode }) {
6
+ return (
7
+ <DocsLayout
8
+ tree={source.getPageTree()}
9
+ nav={{ title: 'Docs' }}
10
+ >
11
+ {children}
12
+ </DocsLayout>
13
+ )
14
+ }
@@ -0,0 +1,3 @@
1
+ @import 'tailwindcss';
2
+ @import 'fumadocs-ui/css/neutral.css';
3
+ @import 'fumadocs-ui/css/preset.css';
@@ -0,0 +1,13 @@
1
+ import { RootProvider } from 'fumadocs-ui/provider/next'
2
+ import './global.css'
3
+ import type { ReactNode } from 'react'
4
+
5
+ export default function Layout({ children }: { children: ReactNode }) {
6
+ return (
7
+ <html lang="en" suppressHydrationWarning>
8
+ <body>
9
+ <RootProvider>{children}</RootProvider>
10
+ </body>
11
+ </html>
12
+ )
13
+ }
@@ -0,0 +1,11 @@
1
+ import { source } from '@/lib/source'
2
+
3
+ export const revalidate = false
4
+
5
+ export async function GET() {
6
+ const pages = source.getPages()
7
+ const texts = await Promise.all(
8
+ pages.map(async (page) => `# ${page.data.title} (${page.url})\n\n${page.data.description ?? ''}`)
9
+ )
10
+ return new Response(texts.join('\n\n'))
11
+ }
@@ -0,0 +1,8 @@
1
+ import { source } from '@/lib/source'
2
+ import { llms } from 'fumadocs-core/source'
3
+
4
+ export const revalidate = false
5
+
6
+ export function GET() {
7
+ return new Response(llms(source).index())
8
+ }
@@ -0,0 +1,2 @@
1
+ <!-- AUTO-GENERATED by openspec-docs-sync. Do not edit manually. -->
2
+ <!-- Run `pnpm docs:sync` from the monorepo root to regenerate this directory. -->
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: "Changelog"
3
+ description: "Archived changes and decision log, newest first."
4
+ ---
5
+
6
+ {/* <!-- AUTO-GENERATED by openspec-docs-sync. Do not edit manually. --> */}
7
+
8
+ Archived changes in reverse-chronological order.
9
+
@@ -0,0 +1,3 @@
1
+ {
2
+ "title": "Changelog"
3
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "Decisions",
3
+ "pages": []
4
+ }
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: "Hello Feature"
3
+ description: "Reference implementation of the feature contract pattern."
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ The `hello` feature demonstrates the four-layer directory contract in practice:
9
+
10
+ - `__contract__.ts` — declares input/output types and public API
11
+ - `service.ts` — pure business logic, no side effects
12
+ - `index.ts` — exports only what the contract declares
13
+ - `hello.test.ts` — Vitest unit tests
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { getGreeting } from '@/features/hello'
19
+
20
+ const result = getGreeting({ name: 'World' })
21
+ // { message: 'Hello, World!' }
22
+ ```
23
+
24
+ ## Architecture Notes
25
+
26
+ This feature follows Layer 2 rules:
27
+ - No direct database access (uses repository interfaces from `core/`)
28
+ - No cross-feature imports
29
+ - Contract-first design
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "Features",
3
+ "pages": ["hello"]
4
+ }
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: "Welcome"
3
+ description: "Documentation for your project."
4
+ ---
5
+
6
+ Welcome to the project documentation. Use the navigation to explore features, architectural decisions, changelog, and roadmap.
@@ -0,0 +1,4 @@
1
+ {
2
+ "title": "Documentation",
3
+ "pages": ["features", "decisions", "changelog", "roadmap"]
4
+ }
@@ -0,0 +1,2 @@
1
+ <!-- AUTO-GENERATED by openspec-docs-sync. Do not edit manually. -->
2
+ <!-- Run `pnpm docs:sync` from the monorepo root to regenerate this directory. -->
@@ -0,0 +1,29 @@
1
+ ---
2
+ title: "Roadmap"
3
+ description: "Current platform roadmap — four-bucket view (Now / Next / Later / Won't)."
4
+ ---
5
+
6
+ {/* <!-- AUTO-GENERATED by openspec-docs-sync. Do not edit manually. --> */}
7
+
8
+ > Auto-generated from `roadmap.yaml`. To update, edit the YAML and re-run `pnpm docs:sync`.
9
+
10
+ ## Now
11
+
12
+ - 🔄 **Web Next.js built-in suite (monorepo + docs + auth + payments)** `web-nextjs-builtin-suite`
13
+ Status: in-progress · Owner: @team
14
+
15
+ ## Next
16
+
17
+ - 📋 **Add authentication feature (Supabase Auth)** `web-nextjs-auth`
18
+ Status: planned · Owner: @team
19
+ - 📋 **Add payments feature (Stripe)** `web-nextjs-payments`
20
+ Status: planned · Owner: @team
21
+
22
+ ## Later
23
+
24
+ - 📋 **Add analytics feature** `web-nextjs-analytics`
25
+ Status: planned · Owner: @team
26
+
27
+ ## Won't
28
+
29
+ _No items._
@@ -0,0 +1,3 @@
1
+ {
2
+ "title": "Roadmap"
3
+ }
@@ -0,0 +1,10 @@
1
+ // @ts-check
2
+ const base = require("@cogito.ai/eslint-config/base");
3
+
4
+ /** @type {import("eslint").Linter.Config[]} */
5
+ module.exports = [
6
+ {
7
+ ignores: [".next/**", ".source/**"],
8
+ },
9
+ ...base,
10
+ ];
@@ -0,0 +1,7 @@
1
+ import { docs } from 'collections/server'
2
+ import { loader } from 'fumadocs-core/source'
3
+
4
+ export const source = loader({
5
+ baseUrl: '/docs',
6
+ source: docs.toFumadocsSource(),
7
+ })
@@ -0,0 +1,14 @@
1
+ import { createMDX } from 'fumadocs-mdx/next'
2
+ import type { NextConfig } from 'next'
3
+ import path from 'node:path'
4
+
5
+ const withMDX = createMDX()
6
+
7
+ const config: NextConfig = {
8
+ reactStrictMode: true,
9
+ turbopack: {
10
+ root: path.resolve(process.cwd(), '../..'),
11
+ },
12
+ }
13
+
14
+ export default withMDX(config)