@cogito.ai/cli 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +19 -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
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@cogito.ai/docs",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev --port 3001",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "eslint .",
10
+ "check-types": "tsc --noEmit",
11
+ "docs:sync": "openspec-docs-sync",
12
+ "postinstall": "fumadocs-mdx"
13
+ },
14
+ "dependencies": {
15
+ "fumadocs-core": "16.9.3",
16
+ "fumadocs-mdx": "15.0.10",
17
+ "fumadocs-ui": "16.9.3",
18
+ "next": "16",
19
+ "react": "^19.0.0",
20
+ "react-dom": "^19.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@cogito.ai/eslint-config": "workspace:*",
24
+ "@cogito.ai/tsconfig": "workspace:*",
25
+ "@cogito.ai/openspec-docs-sync": "workspace:*",
26
+ "@tailwindcss/postcss": "^4.3.0",
27
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
28
+ "@typescript-eslint/parser": "^8.0.0",
29
+ "@types/mdx": "^2.0.13",
30
+ "@types/node": "^25.0.0",
31
+ "@types/react": "^19.0.0",
32
+ "@types/react-dom": "^19.0.0",
33
+ "eslint": "^9.0.0",
34
+ "postcss": "^8.5.15",
35
+ "tailwindcss": "^4.3.0",
36
+ "typescript": "^6.0.3"
37
+ }
38
+ }
@@ -0,0 +1,8 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ '@tailwindcss/postcss': {},
5
+ },
6
+ }
7
+
8
+ export default config
@@ -0,0 +1,7 @@
1
+ import { defineConfig, defineDocs } from 'fumadocs-mdx/config'
2
+
3
+ export const docs = defineDocs({
4
+ dir: 'content/docs',
5
+ })
6
+
7
+ export default defineConfig({})
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "extends": "@cogito.ai/tsconfig/base.json",
4
+ "compilerOptions": {
5
+ "target": "ESNext",
6
+ "lib": ["dom", "dom.iterable", "esnext"],
7
+ "allowJs": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "noEmit": true,
11
+ "esModuleInterop": true,
12
+ "module": "esnext",
13
+ "moduleResolution": "bundler",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "jsx": "react-jsx",
17
+ "incremental": true,
18
+ "paths": {
19
+ "@/*": ["./*"],
20
+ "collections/*": ["./.source/*"]
21
+ },
22
+ "plugins": [{ "name": "next" }]
23
+ },
24
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25
+ "exclude": ["node_modules"]
26
+ }
@@ -0,0 +1,65 @@
1
+ # AgentDock Web-Next.js Template — Copilot Instructions
2
+
3
+ > Applies to: GitHub Copilot (chat + completions) in any project generated from this template.
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
+
17
+ ## Directory Contract
18
+
19
+ This project enforces a four-layer directory contract inside `apps/web/`. **Before placing any code**, confirm which layer it belongs to:
20
+
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 |
27
+
28
+ ## Layer 2 Architecture Rules (error-level, enforced by ESLint)
29
+
30
+ Four rules are enforced at `error` severity in `apps/web/src/features/**`. Violations fail `pnpm lint`.
31
+
32
+ 1. **`no-direct-db-in-features`** — Features must not import from `infra/db`. Use repository interfaces from `apps/web/src/core/repositories/` instead.
33
+ 2. **`require-feature-contract`** — Every feature subdirectory must contain `__contract__.ts` declaring its public API boundary.
34
+ 3. **`no-cross-feature`** — Features must not directly import from sibling feature internals. Import through the feature's `index.ts` only.
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/`.
44
+
45
+ ## Hard Rules
46
+
47
+ 1. **No secrets** — Never write real API keys, tokens, or passwords. Use placeholders: `YOUR_KEY_HERE`, `process.env.YOUR_VAR`.
48
+ 2. **TypeScript strict** — `strict: true` enforced. No `any`, no `// @ts-ignore` without explanation.
49
+ 3. **Conventional commits** — `type(scope): summary` format required.
50
+ 4. **pnpm only** — Do not use `npm install` or `yarn`. Always `pnpm add`.
51
+ 5. **ESLint config** — Architecture rules come from `packages/eslint-config/features.js`.
52
+
53
+ ## Feature Development Pattern
54
+
55
+ When adding a new feature `apps/web/src/features/<name>/`:
56
+
57
+ 1. Create `__contract__.ts` first — declare input/output types and public API.
58
+ 2. Create `service.ts` — pure business logic, no side effects.
59
+ 3. Create `index.ts` — only export what `__contract__.ts` declares.
60
+ 4. Create `<name>.test.ts` — Vitest unit tests.
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/`.
65
+
@@ -0,0 +1,6 @@
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+ import "./.next/types/routes.d.ts";
4
+
5
+ // NOTE: This file should not be edited
6
+ // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -1,8 +1,13 @@
1
1
  import type { NextConfig } from 'next'
2
2
  import createNextIntlPlugin from 'next-intl/plugin'
3
+ import path from 'node:path'
3
4
 
4
5
  const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts')
5
6
 
6
- const nextConfig: NextConfig = {}
7
+ const nextConfig: NextConfig = {
8
+ turbopack: {
9
+ root: path.resolve(process.cwd(), '../..'),
10
+ },
11
+ }
7
12
 
8
13
  export default withNextIntl(nextConfig)
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@cogito.ai/web",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "eslint .",
10
+ "test": "vitest run",
11
+ "check-types": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "@supabase/ssr": "^0.10.3",
15
+ "next": "16",
16
+ "next-intl": "^4.13.0",
17
+ "react": "19",
18
+ "react-dom": "19"
19
+ },
20
+ "devDependencies": {
21
+ "@cogito.ai/eslint-config": "workspace:*",
22
+ "@cogito.ai/tsconfig": "workspace:*",
23
+ "@types/node": "25.9.1",
24
+ "@types/react": "19.2.16",
25
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
26
+ "@typescript-eslint/parser": "^8.0.0",
27
+ "@vitejs/plugin-react": "^6.0.2",
28
+ "eslint": "^9.0.0",
29
+ "tailwindcss": "^4.3.0",
30
+ "typescript": "^6.0.3",
31
+ "vitest": "^4.1.8"
32
+ }
33
+ }
@@ -4,14 +4,27 @@ schema: spec-driven
4
4
  context: |
5
5
  You are working in a project generated from the AgentDock web-nextjs template.
6
6
 
7
- Tech stack: Next.js 16 (App Router), React 19, TypeScript 5+ (strict), Tailwind CSS,
7
+ Monorepo structure (turborepo + pnpm):
8
+ apps/web/ — Main Next.js 16 application
9
+ apps/docs/ — Fumadocs documentation site (features, decisions, changelog, roadmap)
10
+ packages/ — Shared tooling packages (eslint-config, tsconfig)
11
+
12
+ Tech stack (apps/web): Next.js 16 (App Router), React 19, TypeScript 5+ (strict), Tailwind CSS,
8
13
  Supabase (@supabase/ssr), next-intl (i18n), Vitest (unit tests), pnpm ≥9, Node ≥18.
9
14
 
10
- Four-layer directory contract (enforced by ESLint Layer 2 rules at error severity):
11
- src/core/ — domain types + repository interfaces (no framework deps, read-only)
12
- src/features/ — AI coding zone; each feature needs __contract__.ts + index.ts + tests
13
- src/infra/ — Supabase implementation (requires human approval before editing)
14
- src/app/ Next.js App Router pages and layouts
15
+ Tech stack (apps/docs): Fumadocs (fumadocs-core, fumadocs-ui, fumadocs-mdx), Next.js 16,
16
+ openspec-docs-sync (auto-generates changelog + roadmap from openspec/changes/archive/).
17
+
18
+ Four-layer directory contract in apps/web/src/ (enforced by ESLint Layer 2 rules at error severity):
19
+ apps/web/src/core/ domain types + repository interfaces (no framework deps, read-only)
20
+ apps/web/src/features/ — AI coding zone; each feature needs __contract__.ts + index.ts + tests
21
+ apps/web/src/infra/ — Supabase implementation (requires human approval before editing)
22
+ apps/web/src/app/ — Next.js App Router pages and layouts
23
+
24
+ Docs co-evolution convention:
25
+ - New feature → create apps/docs/content/docs/features/<name>.mdx
26
+ - Architecture decision → create apps/docs/content/docs/decisions/<adr-id>.mdx
27
+ - After archiving a change → run `pnpm docs:sync` to update changelog + roadmap pages
15
28
 
16
29
  Governance rules:
17
30
  - Conventional commits: type(scope): summary
@@ -20,7 +33,7 @@ context: |
20
33
  - Features must not import from infra/db directly (use core/repositories interfaces)
21
34
  - Every feature directory must have __contract__.ts
22
35
 
23
- Reference feature: src/features/hello/ (complete example of the four-layer pattern)
36
+ Reference feature: apps/web/src/features/hello/ (complete example of the four-layer pattern)
24
37
 
25
38
  # Workflow rules
26
39
  rules:
@@ -0,0 +1,31 @@
1
+ # Project Roadmap
2
+ # Human-owned intent map. AI cannot modify this in ordinary changes.
3
+ #
4
+ # Buckets: Now | Next | Later | Won't
5
+ # Entry fields: id (kebab-case, globally unique) | title | status | owner
6
+ # Status values: planned | in-progress | done
7
+
8
+ now:
9
+ - id: web-nextjs-builtin-suite
10
+ title: Web Next.js built-in suite (monorepo + docs + auth + payments)
11
+ status: in-progress
12
+ owner: "@team"
13
+
14
+ next:
15
+ - id: web-nextjs-auth
16
+ title: Add authentication feature (Supabase Auth)
17
+ status: planned
18
+ owner: "@team"
19
+
20
+ - id: web-nextjs-payments
21
+ title: Add payments feature (Stripe)
22
+ status: planned
23
+ owner: "@team"
24
+
25
+ later:
26
+ - id: web-nextjs-analytics
27
+ title: Add analytics feature
28
+ status: planned
29
+ owner: "@team"
30
+
31
+ wont: []
@@ -1,35 +1,24 @@
1
1
  {
2
2
  "name": "@cogito.ai/template-web-nextjs",
3
3
  "version": "0.1.0",
4
- "description": "Full-stack Next.js 16 starter with Supabase, next-intl, Tailwind CSS and Vitest",
4
+ "description": "Full-stack Next.js 16 monorepo starter with Supabase, next-intl, Tailwind CSS, Vitest and built-in Fumadocs docs site",
5
5
  "private": true,
6
6
  "engines": {
7
7
  "pnpm": ">=9",
8
8
  "node": ">=18"
9
9
  },
10
+ "packageManager": "pnpm@9.0.0",
10
11
  "scripts": {
11
- "dev": "next dev",
12
- "build": "next build",
13
- "start": "next start",
14
- "lint": "eslint .",
15
- "test": "vitest run",
16
- "check-types": "tsc --noEmit"
17
- },
18
- "dependencies": {
19
- "@supabase/ssr": "^0.10.3",
20
- "next": "16",
21
- "next-intl": "^4.13.0",
22
- "react": "19",
23
- "react-dom": "19"
12
+ "build": "pnpm -r run build",
13
+ "dev": "turbo run dev",
14
+ "lint": "pnpm -r run lint",
15
+ "test": "pnpm -r run test",
16
+ "check-types": "pnpm -r run check-types",
17
+ "docs:sync": "pnpm --filter @cogito.ai/docs docs:sync"
24
18
  },
25
19
  "devDependencies": {
26
- "@vitejs/plugin-react": "^6.0.2",
27
- "tailwindcss": "^4.3.0",
28
- "typescript": "^6.0.3",
29
- "vitest": "^4.1.8",
30
- "@cogito.ai/eslint-config": "workspace:*",
31
- "@cogito.ai/tsconfig": "workspace:*",
32
- "@fission-ai/openspec": "^1.3.1"
20
+ "@fission-ai/openspec": "^1.3.1",
21
+ "turbo": "latest"
33
22
  },
34
23
  "agentdock": {
35
24
  "minCliVersion": "0.1.0"
@@ -0,0 +1,7 @@
1
+ # @cogito.ai/eslint-config
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Initial release: shared ESLint config and TypeScript config for AgentDock platform packages and templates
@@ -0,0 +1,34 @@
1
+ // @ts-check
2
+ // Base ESLint config — TypeScript-safe rules for all packages
3
+ // Compatible with ESLint v9 flat config format
4
+ "use strict";
5
+
6
+ const tseslint = require("@typescript-eslint/eslint-plugin");
7
+ const tsParser = require("@typescript-eslint/parser");
8
+
9
+ /** @type {import("eslint").Linter.Config[]} */
10
+ const base = [
11
+ {
12
+ files: ["**/*.{ts,tsx}"],
13
+ plugins: {
14
+ "@typescript-eslint": tseslint,
15
+ },
16
+ languageOptions: {
17
+ parser: tsParser,
18
+ },
19
+ rules: {
20
+ // @ts-ignore without an explanation is a code smell and bypasses type safety.
21
+ // Developers must justify why TypeScript's type system cannot handle the situation.
22
+ "@typescript-eslint/ban-ts-comment": [
23
+ "error",
24
+ {
25
+ "ts-ignore": "allow-with-description",
26
+ "ts-expect-error": "allow-with-description",
27
+ minimumDescriptionLength: 10,
28
+ },
29
+ ],
30
+ },
31
+ },
32
+ ];
33
+
34
+ module.exports = base;
@@ -0,0 +1,86 @@
1
+ // @ts-check
2
+ // Feature-layer architecture rules — applies only to src/features/**
3
+ // These are "teeth" rules: error from day one, no grace period.
4
+ // Templates must explicitly extend this config to activate these rules.
5
+ "use strict";
6
+
7
+ const path = require("path");
8
+ const fs = require("fs");
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // Custom rule: require-feature-contract
12
+ // Every src/features/<name>/ directory MUST contain __contract__.ts.
13
+ // ---------------------------------------------------------------------------
14
+ /** @type {import("eslint").Rule.RuleModule} */
15
+ const requireFeatureContractRule = {
16
+ meta: {
17
+ type: "problem",
18
+ schema: [],
19
+ messages: {
20
+ missingContract:
21
+ "Feature '{{ featureName }}' is missing __contract__.ts. Every feature directory must export a typed contract.",
22
+ },
23
+ },
24
+ create(context) {
25
+ const filePath = context.filename;
26
+ // Match the feature root directory: .../src/features/<name>/...
27
+ const match = filePath.match(
28
+ /^(.*[/\\]src[/\\]features[/\\][^/\\]+)[/\\]/
29
+ );
30
+ if (!match) return {};
31
+
32
+ const featureDir = match[1];
33
+ const featureName = path.basename(featureDir);
34
+ const contractPath = path.join(featureDir, "__contract__.ts");
35
+
36
+ if (!fs.existsSync(contractPath)) {
37
+ return {
38
+ Program(node) {
39
+ context.report({
40
+ node,
41
+ messageId: "missingContract",
42
+ data: { featureName },
43
+ });
44
+ },
45
+ };
46
+ }
47
+ return {};
48
+ },
49
+ };
50
+
51
+ /** @type {import("eslint").Linter.Config[]} */
52
+ const features = [
53
+ {
54
+ // Scope these rules to feature-layer source files only.
55
+ // Exclude type declarations and test fixtures to avoid false positives.
56
+ files: ["**/src/features/**/*.{ts,tsx}"],
57
+ ignores: ["**/*.d.ts", "**/__fixtures__/**", "**/__tests__/**"],
58
+ plugins: {
59
+ "agentdock-arch": {
60
+ rules: {
61
+ "require-feature-contract": requireFeatureContractRule,
62
+ },
63
+ },
64
+ },
65
+ rules: {
66
+ // Features must not directly access DB clients — use repositories from core.
67
+ // Handles path aliases (@/infra/db/**) and relative imports.
68
+ "no-restricted-imports": [
69
+ "error",
70
+ {
71
+ patterns: [
72
+ {
73
+ group: ["**/infra/db/**", "**/infra/db"],
74
+ message:
75
+ "Direct DB access in features is not allowed. Use repositories from src/core/repositories instead.",
76
+ },
77
+ ],
78
+ },
79
+ ],
80
+ // Each feature directory must export a typed __contract__.ts.
81
+ "agentdock-arch/require-feature-contract": "error",
82
+ },
83
+ },
84
+ ];
85
+
86
+ module.exports = features;
@@ -0,0 +1,24 @@
1
+ // @ts-check
2
+ // Next.js specific ESLint config — extends base with Next.js conventions
3
+ // Compatible with ESLint v9 flat config format
4
+ "use strict";
5
+
6
+ /** @type {import("eslint").Linter.Config[]} */
7
+ const next = [
8
+ {
9
+ files: ["**/*.{ts,tsx}"],
10
+ rules: {
11
+ // Discourage console.log in production code; warn so devs notice but are not blocked
12
+ "no-console": ["warn", { allow: ["warn", "error"] }],
13
+ },
14
+ },
15
+ {
16
+ // Route handlers and server components may use console for server-side logging
17
+ files: ["**/app/**/*.{ts,tsx}", "**/pages/api/**/*.{ts,tsx}"],
18
+ rules: {
19
+ "no-console": "off",
20
+ },
21
+ },
22
+ ];
23
+
24
+ module.exports = next;
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@cogito.ai/eslint-config",
3
+ "version": "0.2.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "exports": {
8
+ "./base": "./base.js",
9
+ "./features": "./features.js",
10
+ "./next": "./next.js"
11
+ },
12
+ "peerDependencies": {
13
+ "@typescript-eslint/eslint-plugin": ">=7.0.0",
14
+ "@typescript-eslint/parser": ">=7.0.0",
15
+ "eslint": ">=9.0.0"
16
+ },
17
+ "devDependencies": {
18
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
19
+ "@typescript-eslint/parser": "^8.0.0",
20
+ "eslint": "^9.0.0"
21
+ }
22
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@cogito.ai/openspec-docs-sync",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "bin": {
7
+ "openspec-docs-sync": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "tsc --watch",
12
+ "check-types": "tsc --noEmit"
13
+ },
14
+ "devDependencies": {
15
+ "@cogito.ai/tsconfig": "workspace:*",
16
+ "@types/js-yaml": "^4.0.9",
17
+ "@types/node": "^22.0.0",
18
+ "typescript": "5.9.2"
19
+ },
20
+ "dependencies": {
21
+ "js-yaml": "^4.1.0",
22
+ "gray-matter": "^4.0.3"
23
+ }
24
+ }