@cogito.ai/cli 0.2.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 (40) hide show
  1. package/LICENSE +23 -0
  2. package/dist/index.js +17870 -0
  3. package/dist/registry.json +26 -0
  4. package/dist/templates/web-nextjs/.env.example +22 -0
  5. package/dist/templates/web-nextjs/.github/copilot-instructions.md +43 -0
  6. package/dist/templates/web-nextjs/AGENTS.md +46 -0
  7. package/dist/templates/web-nextjs/README.md +204 -0
  8. package/dist/templates/web-nextjs/eslint.config.js +12 -0
  9. package/dist/templates/web-nextjs/messages/en.json +10 -0
  10. package/dist/templates/web-nextjs/messages/zh.json +10 -0
  11. package/dist/templates/web-nextjs/middleware.ts +34 -0
  12. package/dist/templates/web-nextjs/next-env.d.ts +6 -0
  13. package/dist/templates/web-nextjs/next.config.ts +8 -0
  14. package/dist/templates/web-nextjs/openspec/changes/.gitkeep +0 -0
  15. package/dist/templates/web-nextjs/openspec/changes/archive/.gitkeep +0 -0
  16. package/dist/templates/web-nextjs/openspec/config.yaml +28 -0
  17. package/dist/templates/web-nextjs/openspec/specs/.gitkeep +0 -0
  18. package/dist/templates/web-nextjs/package.json +37 -0
  19. package/dist/templates/web-nextjs/src/app/[locale]/globals.css +3 -0
  20. package/dist/templates/web-nextjs/src/app/[locale]/hello/page.tsx +45 -0
  21. package/dist/templates/web-nextjs/src/app/[locale]/layout.tsx +37 -0
  22. package/dist/templates/web-nextjs/src/app/[locale]/page.tsx +12 -0
  23. package/dist/templates/web-nextjs/src/core/repositories/.gitkeep +2 -0
  24. package/dist/templates/web-nextjs/src/core/repositories/IGreetingRepository.ts +14 -0
  25. package/dist/templates/web-nextjs/src/core/types/.gitkeep +3 -0
  26. package/dist/templates/web-nextjs/src/core/types/greeting.ts +9 -0
  27. package/dist/templates/web-nextjs/src/features/_experiments/.gitkeep +2 -0
  28. package/dist/templates/web-nextjs/src/features/hello/__contract__.ts +16 -0
  29. package/dist/templates/web-nextjs/src/features/hello/hello.test.ts +16 -0
  30. package/dist/templates/web-nextjs/src/features/hello/index.ts +5 -0
  31. package/dist/templates/web-nextjs/src/features/hello/service.ts +12 -0
  32. package/dist/templates/web-nextjs/src/i18n/request.ts +11 -0
  33. package/dist/templates/web-nextjs/src/infra/db/.gitkeep +3 -0
  34. package/dist/templates/web-nextjs/src/infra/db/SupabaseGreetingRepository.ts +58 -0
  35. package/dist/templates/web-nextjs/src/infra/db/client.ts +55 -0
  36. package/dist/templates/web-nextjs/src/infra/db/schema.ts +19 -0
  37. package/dist/templates/web-nextjs/tailwind.config.ts +11 -0
  38. package/dist/templates/web-nextjs/tsconfig.json +22 -0
  39. package/dist/templates/web-nextjs/vitest.config.ts +16 -0
  40. package/package.json +37 -0
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Contract for the `hello` feature.
3
+ *
4
+ * Defines the public API boundary: input/output types and the exported function signature.
5
+ * Only symbols declared here may be exported from `index.ts`.
6
+ */
7
+
8
+ /** Input accepted by the hello feature. */
9
+ export interface HelloInput {
10
+ name: string
11
+ }
12
+
13
+ /** Output returned by the hello feature. */
14
+ export interface HelloOutput {
15
+ greeting: string
16
+ }
@@ -0,0 +1,16 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { greet } from './index'
3
+
4
+ describe('hello feature — greet()', () => {
5
+ it('returns a greeting with the provided name', () => {
6
+ expect(greet('Alice')).toBe('Hello, Alice!')
7
+ })
8
+
9
+ it("returns a greeting with 'World' when name is an empty string", () => {
10
+ expect(greet('')).toBe('Hello, World!')
11
+ })
12
+
13
+ it("returns a greeting with 'World' when name is only whitespace", () => {
14
+ expect(greet(' ')).toBe('Hello, World!')
15
+ })
16
+ })
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Public API for the `hello` feature.
3
+ * Only exports declared in __contract__.ts are exposed here.
4
+ */
5
+ export { greet } from './service'
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Hello feature — pure business logic, no side effects.
3
+ */
4
+
5
+ /**
6
+ * Returns a greeting string for the given name.
7
+ * Falls back to "World" when name is empty.
8
+ */
9
+ export function greet(name: string): string {
10
+ const target = name.trim() || 'World'
11
+ return `Hello, ${target}!`
12
+ }
@@ -0,0 +1,11 @@
1
+ import { getRequestConfig } from 'next-intl/server'
2
+
3
+ export default getRequestConfig(async ({ requestLocale }) => {
4
+ const locale = (await requestLocale) ?? 'en'
5
+
6
+ return {
7
+ locale,
8
+ // Dynamic import keyed by locale — type is `any` from JSON, acceptable here.
9
+ messages: (await import(`../../messages/${locale}.json`)).default as Record<string, unknown>,
10
+ }
11
+ })
@@ -0,0 +1,3 @@
1
+ # src/infra/db
2
+ # Supabase implementation layer.
3
+ # Only core/repositories implementations are allowed to live here.
@@ -0,0 +1,58 @@
1
+ import type { IGreetingRepository } from '@/core/repositories/IGreetingRepository'
2
+ import type { Greeting } from '@/core/types/greeting'
3
+ import { getServerClient } from './client'
4
+
5
+ /**
6
+ * Supabase implementation of IGreetingRepository.
7
+ * Operates on the `greetings` table.
8
+ *
9
+ * Table schema (create in Supabase SQL editor):
10
+ * ```sql
11
+ * create table greetings (
12
+ * id uuid primary key default gen_random_uuid(),
13
+ * name text not null,
14
+ * created_at timestamptz not null default now()
15
+ * );
16
+ * ```
17
+ */
18
+ export class SupabaseGreetingRepository implements IGreetingRepository {
19
+ async save(name: string): Promise<Greeting> {
20
+ const supabase = await getServerClient()
21
+
22
+ const { data, error } = await supabase
23
+ .from('greetings')
24
+ .insert({ name })
25
+ .select('id, name, created_at')
26
+ .single()
27
+
28
+ if (error !== null || data === null) {
29
+ throw new Error(`Failed to save greeting: ${error?.message ?? 'unknown'}`)
30
+ }
31
+
32
+ return {
33
+ id: data.id as string,
34
+ name: data.name as string,
35
+ createdAt: (data.created_at as string) ?? new Date().toISOString(),
36
+ }
37
+ }
38
+
39
+ async findRecent(): Promise<Greeting[]> {
40
+ const supabase = await getServerClient()
41
+
42
+ const { data, error } = await supabase
43
+ .from('greetings')
44
+ .select('id, name, created_at')
45
+ .order('created_at', { ascending: false })
46
+ .limit(10)
47
+
48
+ if (error !== null) {
49
+ throw new Error(`Failed to fetch greetings: ${error.message}`)
50
+ }
51
+
52
+ return (data ?? []).map((row) => ({
53
+ id: row.id as string,
54
+ name: row.name as string,
55
+ createdAt: (row.created_at as string) ?? '',
56
+ }))
57
+ }
58
+ }
@@ -0,0 +1,55 @@
1
+ import { createServerClient } from '@supabase/ssr'
2
+ import { createBrowserClient } from '@supabase/ssr'
3
+ import { cookies } from 'next/headers'
4
+
5
+ /**
6
+ * Returns a Supabase client safe for use in Server Components and Server Actions.
7
+ *
8
+ * Usage:
9
+ * ```ts
10
+ * // In a Server Component or Server Action:
11
+ * const supabase = await getServerClient();
12
+ * const { data } = await supabase.from('greetings').select('*');
13
+ * ```
14
+ *
15
+ * Requires env vars: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY
16
+ */
17
+ export async function getServerClient() {
18
+ const cookieStore = await cookies()
19
+
20
+ return createServerClient(
21
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
22
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
23
+ {
24
+ cookies: {
25
+ getAll() {
26
+ return cookieStore.getAll()
27
+ },
28
+ setAll(cookiesToSet) {
29
+ for (const { name, value, options } of cookiesToSet) {
30
+ cookieStore.set(name, value, options)
31
+ }
32
+ },
33
+ },
34
+ },
35
+ )
36
+ }
37
+
38
+ /**
39
+ * Returns a Supabase client safe for use in Client Components (browser).
40
+ *
41
+ * Usage:
42
+ * ```ts
43
+ * // In a 'use client' component:
44
+ * const supabase = getBrowserClient();
45
+ * const { data } = await supabase.from('greetings').select('*');
46
+ * ```
47
+ *
48
+ * Requires env vars: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY
49
+ */
50
+ export function getBrowserClient() {
51
+ return createBrowserClient(
52
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
53
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
54
+ )
55
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Drizzle extension point — not implemented in Supabase MVP stage.
3
+ *
4
+ * When the team decides to adopt Drizzle ORM, implement the schema here.
5
+ * The IGreetingRepository interface in src/core/repositories/ does not need
6
+ * to change — only the implementation in SupabaseGreetingRepository.ts.
7
+ *
8
+ * Example future implementation:
9
+ *
10
+ * import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
11
+ *
12
+ * export const greetings = pgTable("greetings", {
13
+ * id: text("id").primaryKey(),
14
+ * name: text("name").notNull(),
15
+ * createdAt: timestamp("created_at").notNull().defaultNow(),
16
+ * });
17
+ */
18
+
19
+ export {}
@@ -0,0 +1,11 @@
1
+ import type { Config } from 'tailwindcss'
2
+
3
+ const config: Config = {
4
+ content: ['./src/**/*.{ts,tsx}'],
5
+ theme: {
6
+ extend: {},
7
+ },
8
+ plugins: [],
9
+ }
10
+
11
+ export default config
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "extends": "@cogito.ai/tsconfig/base.json",
4
+ "compilerOptions": {
5
+ "target": "ES2022",
6
+ "lib": ["dom", "dom.iterable", "ES2022"],
7
+ "jsx": "preserve",
8
+ "module": "ESNext",
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "skipLibCheck": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+ "plugins": [{ "name": "next" }],
16
+ "paths": {
17
+ "@/*": ["./src/*"]
18
+ }
19
+ },
20
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
21
+ "exclude": ["node_modules"]
22
+ }
@@ -0,0 +1,16 @@
1
+ import { defineConfig } from 'vitest/config'
2
+ import react from '@vitejs/plugin-react'
3
+ import path from 'path'
4
+
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ test: {
8
+ environment: 'node',
9
+ include: ['src/**/*.test.ts'],
10
+ },
11
+ resolve: {
12
+ alias: {
13
+ '@': path.resolve(__dirname, './src'),
14
+ },
15
+ },
16
+ })
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@cogito.ai/cli",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "AgentDock CLI – scaffold projects for humans and AI agents",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "bin": {
10
+ "agentdock": "./dist/index.js"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "files": [
14
+ "dist/"
15
+ ],
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "dependencies": {
20
+ "citty": "^0.1.6",
21
+ "@clack/prompts": "^0.9.1",
22
+ "@modelcontextprotocol/sdk": "^1.0.0",
23
+ "giget": "^1.2.4"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^20.0.0",
27
+ "bun": "latest",
28
+ "vitest": "^4.1.8",
29
+ "@cogito.ai/tsconfig": "0.2.0"
30
+ },
31
+ "scripts": {
32
+ "build": "pnpm run generate-registry && bun build bin/agentdock.ts --outfile dist/index.js --target node && cp src/registry.json dist/registry.json && rm -rf dist/templates && mkdir -p dist/templates && rsync -a --exclude='node_modules/' --exclude='.next/' --exclude='.turbo/' ../../templates/ dist/templates/",
33
+ "generate-registry": "tsx ../../scripts/generate-registry/index.ts",
34
+ "check-types": "tsc --noEmit",
35
+ "test": "vitest run"
36
+ }
37
+ }