teamshare-bridge 0.2.5 → 0.4.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 (140) hide show
  1. package/dist/bridge/daemon.js +36 -0
  2. package/dist/bridge/daemon.js.map +1 -1
  3. package/dist/bridge/local-server.d.ts +1 -1
  4. package/dist/bridge/spawn.d.ts +2 -0
  5. package/dist/bridge/spawn.js +17 -0
  6. package/dist/bridge/spawn.js.map +1 -1
  7. package/dist/cli/commands/audit.d.ts +1 -0
  8. package/dist/cli/commands/audit.js +75 -0
  9. package/dist/cli/commands/audit.js.map +1 -0
  10. package/dist/cli/commands/build.js +24 -8
  11. package/dist/cli/commands/build.js.map +1 -1
  12. package/dist/cli/commands/chat.js +1 -1
  13. package/dist/cli/commands/chat.js.map +1 -1
  14. package/dist/cli/commands/doc.js +2 -2
  15. package/dist/cli/commands/doc.js.map +1 -1
  16. package/dist/cli/commands/harness.js +1 -1
  17. package/dist/cli/commands/harness.js.map +1 -1
  18. package/dist/cli/commands/run.js +19 -4
  19. package/dist/cli/commands/run.js.map +1 -1
  20. package/dist/cli/commands/scaffold.d.ts +1 -0
  21. package/dist/cli/commands/scaffold.js +111 -0
  22. package/dist/cli/commands/scaffold.js.map +1 -0
  23. package/dist/cli/commands/worker.d.ts +2 -0
  24. package/dist/cli/commands/worker.js +110 -0
  25. package/dist/cli/commands/worker.js.map +1 -0
  26. package/dist/cli/index.js +16 -0
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/lib/api.d.ts +35 -4
  29. package/dist/lib/api.js +20 -3
  30. package/dist/lib/api.js.map +1 -1
  31. package/dist/lib/audit/docs.d.ts +5 -0
  32. package/dist/lib/audit/docs.js +52 -0
  33. package/dist/lib/audit/docs.js.map +1 -0
  34. package/dist/lib/audit/errors.d.ts +15 -0
  35. package/dist/lib/audit/errors.js +154 -0
  36. package/dist/lib/audit/errors.js.map +1 -0
  37. package/dist/lib/audit/gates.d.ts +2 -0
  38. package/dist/lib/audit/gates.js +57 -0
  39. package/dist/lib/audit/gates.js.map +1 -0
  40. package/dist/lib/audit/modularity.d.ts +13 -0
  41. package/dist/lib/audit/modularity.js +200 -0
  42. package/dist/lib/audit/modularity.js.map +1 -0
  43. package/dist/lib/audit/quality.d.ts +9 -0
  44. package/dist/lib/audit/quality.js +128 -0
  45. package/dist/lib/audit/quality.js.map +1 -0
  46. package/dist/lib/audit/rbac.d.ts +14 -0
  47. package/dist/lib/audit/rbac.js +139 -0
  48. package/dist/lib/audit/rbac.js.map +1 -0
  49. package/dist/lib/audit/reporter.d.ts +5 -0
  50. package/dist/lib/audit/reporter.js +107 -0
  51. package/dist/lib/audit/reporter.js.map +1 -0
  52. package/dist/lib/audit/runner.d.ts +2 -0
  53. package/dist/lib/audit/runner.js +150 -0
  54. package/dist/lib/audit/runner.js.map +1 -0
  55. package/dist/lib/audit/security.d.ts +9 -0
  56. package/dist/lib/audit/security.js +151 -0
  57. package/dist/lib/audit/security.js.map +1 -0
  58. package/dist/lib/audit/types.d.ts +67 -0
  59. package/dist/lib/audit/types.js +26 -0
  60. package/dist/lib/audit/types.js.map +1 -0
  61. package/dist/lib/audit/ux.d.ts +9 -0
  62. package/dist/lib/audit/ux.js +112 -0
  63. package/dist/lib/audit/ux.js.map +1 -0
  64. package/dist/lib/brief.d.ts +4 -0
  65. package/dist/lib/brief.js +78 -40
  66. package/dist/lib/brief.js.map +1 -1
  67. package/dist/lib/chat-reply.js +2 -2
  68. package/dist/lib/chat-reply.js.map +1 -1
  69. package/dist/lib/config.d.ts +1 -1
  70. package/dist/lib/config.js +1 -1
  71. package/dist/lib/doc-reply.js +1 -1
  72. package/dist/lib/doc-reply.js.map +1 -1
  73. package/dist/lib/harness-adapter.d.ts +3 -1
  74. package/dist/lib/harness-adapter.js +19 -16
  75. package/dist/lib/harness-adapter.js.map +1 -1
  76. package/dist/lib/harness.d.ts +3 -1
  77. package/dist/lib/harness.js +8 -5
  78. package/dist/lib/harness.js.map +1 -1
  79. package/dist/lib/llm.js +87 -9
  80. package/dist/lib/llm.js.map +1 -1
  81. package/dist/lib/lock.d.ts +1 -1
  82. package/dist/lib/scaffold/renderer.d.ts +7 -0
  83. package/dist/lib/scaffold/renderer.js +37 -0
  84. package/dist/lib/scaffold/renderer.js.map +1 -0
  85. package/dist/lib/scaffold/structure.d.ts +3 -0
  86. package/dist/lib/scaffold/structure.js +73 -0
  87. package/dist/lib/scaffold/structure.js.map +1 -0
  88. package/dist/lib/scaffold/types.d.ts +34 -0
  89. package/dist/lib/scaffold/types.js +6 -0
  90. package/dist/lib/scaffold/types.js.map +1 -0
  91. package/dist/lib/scaffold/verify.d.ts +9 -0
  92. package/dist/lib/scaffold/verify.js +48 -0
  93. package/dist/lib/scaffold/verify.js.map +1 -0
  94. package/dist/lib/skills.d.ts +2 -2
  95. package/dist/lib/skills.js +2 -1
  96. package/dist/lib/skills.js.map +1 -1
  97. package/package.json +3 -2
  98. package/skills/teamshare-orchestrator-ask/SKILL.md +14 -0
  99. package/skills/teamshare-scaffold/SKILL.md +133 -0
  100. package/templates/backend/.env.example.tpl +13 -0
  101. package/templates/backend/nest-cli.json.tpl +8 -0
  102. package/templates/backend/package.json.tpl +41 -0
  103. package/templates/backend/prisma/schema.prisma.tpl +39 -0
  104. package/templates/backend/src/app.module.ts.tpl +24 -0
  105. package/templates/backend/src/common/filters/all-exceptions.filter.ts.tpl +59 -0
  106. package/templates/backend/src/common/guards/jwt-auth.guard.ts.tpl +27 -0
  107. package/templates/backend/src/common/guards/rbac.guard.ts.tpl +48 -0
  108. package/templates/backend/src/common/interceptors/transform.interceptor.ts.tpl +44 -0
  109. package/templates/backend/src/common/pipes/zod-validation.pipe.ts.tpl +29 -0
  110. package/templates/backend/src/common/swagger/envelope.schemas.ts.tpl +53 -0
  111. package/templates/backend/src/common/swagger/error.schemas.ts.tpl +62 -0
  112. package/templates/backend/src/main.ts.tpl +27 -0
  113. package/templates/backend/src/modules/example/example.controller.ts.tpl +102 -0
  114. package/templates/backend/src/modules/example/example.dto.ts.tpl +14 -0
  115. package/templates/backend/src/modules/example/example.module.ts.tpl +10 -0
  116. package/templates/backend/src/modules/example/example.service.ts.tpl +45 -0
  117. package/templates/backend/tsconfig.json.tpl +26 -0
  118. package/templates/common/.gitignore.tpl +42 -0
  119. package/templates/common/AGENTS.md.tpl +58 -0
  120. package/templates/common/docs/adr/README.md +25 -0
  121. package/templates/common/docs/api-contract.md.tpl +72 -0
  122. package/templates/web/next.config.ts.tpl +7 -0
  123. package/templates/web/package.json.tpl +37 -0
  124. package/templates/web/src/app/globals.css.tpl +48 -0
  125. package/templates/web/src/app/layout.tsx.tpl +25 -0
  126. package/templates/web/src/components/shared/app-button.tsx.tpl +59 -0
  127. package/templates/web/src/components/shared/app-empty-state.tsx.tpl +39 -0
  128. package/templates/web/src/components/shared/app-list-toolbar.tsx.tpl +63 -0
  129. package/templates/web/src/components/shared/app-skeleton.tsx.tpl +14 -0
  130. package/templates/web/src/components/shared/app-table.tsx.tpl +128 -0
  131. package/templates/web/src/components/shared/index.ts.tpl +5 -0
  132. package/templates/web/src/hooks/use-list-state.ts.tpl +72 -0
  133. package/templates/web/src/hooks/use-url-tab.ts.tpl +25 -0
  134. package/templates/web/src/lib/api/client.ts.tpl +123 -0
  135. package/templates/web/src/lib/providers.tsx.tpl +35 -0
  136. package/templates/web/src/lib/query-keys.ts.tpl +21 -0
  137. package/templates/web/src/lib/utils.ts.tpl +7 -0
  138. package/templates/web/src/lib/validation/schemas.ts.tpl +15 -0
  139. package/templates/web/src/modules/example/views/example-list-view.tsx.tpl +98 -0
  140. package/templates/web/tsconfig.json.tpl +23 -0
@@ -0,0 +1,123 @@
1
+ const BASE_URL =
2
+ typeof window !== "undefined"
3
+ ? process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:4000"
4
+ : process.env.NEXT_PUBLIC_API_URL ?? "http://localhost:4000";
5
+
6
+ let _onUnauthorized: (() => void) | null = null;
7
+
8
+ export function onUnauthorized(fn: () => void) {
9
+ _onUnauthorized = fn;
10
+ return () => {
11
+ _onUnauthorized = null;
12
+ };
13
+ }
14
+
15
+ export class ApiError extends Error {
16
+ constructor(
17
+ public code: string,
18
+ message: string,
19
+ public status: number,
20
+ public details?: unknown
21
+ ) {
22
+ super(message);
23
+ this.name = "ApiError";
24
+ }
25
+ }
26
+
27
+ export interface PaginatedResponse<T> {
28
+ data: T[];
29
+ pagination: {
30
+ page: number;
31
+ limit: number;
32
+ total: number;
33
+ totalPages: number;
34
+ };
35
+ }
36
+
37
+ async function getToken(): Promise<string | null> {
38
+ try {
39
+ const mod = await import("next-auth/react");
40
+ const session = await mod.getSession();
41
+ return (session as { user?: { accessToken?: string } })?.user
42
+ ?.accessToken ?? null;
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
47
+
48
+ export async function apiFetch<T>(
49
+ path: string,
50
+ opts: RequestInit = {}
51
+ ): Promise<T> {
52
+ const token = await getToken();
53
+ const headers: Record<string, string> = {
54
+ "Content-Type": "application/json",
55
+ ...(opts.headers as Record<string, string>),
56
+ };
57
+ if (token) {
58
+ headers.Authorization = `Bearer ${token}`;
59
+ }
60
+
61
+ const res = await fetch(`${BASE_URL}${path}`, {
62
+ ...opts,
63
+ headers,
64
+ });
65
+
66
+ if (res.status === 401) {
67
+ _onUnauthorized?.();
68
+ throw new ApiError("UNAUTHORIZED", "Unauthorized", 401);
69
+ }
70
+
71
+ const body = await res.json().catch(() => ({}));
72
+
73
+ if (!res.ok) {
74
+ throw new ApiError(
75
+ body?.error?.code ?? "UNKNOWN_ERROR",
76
+ body?.error?.message ?? "An error occurred",
77
+ res.status,
78
+ body?.error?.details
79
+ );
80
+ }
81
+
82
+ return (body?.data ?? body) as T;
83
+ }
84
+
85
+ export async function apiFetchEnvelope<T>(
86
+ path: string,
87
+ opts: RequestInit = {}
88
+ ): Promise<{ data: T; pagination?: PaginatedResponse<T>["pagination"] }> {
89
+ const token = await getToken();
90
+ const headers: Record<string, string> = {
91
+ "Content-Type": "application/json",
92
+ ...(opts.headers as Record<string, string>),
93
+ };
94
+ if (token) {
95
+ headers.Authorization = `Bearer ${token}`;
96
+ }
97
+
98
+ const res = await fetch(`${BASE_URL}${path}`, {
99
+ ...opts,
100
+ headers,
101
+ });
102
+
103
+ if (res.status === 401) {
104
+ _onUnauthorized?.();
105
+ throw new ApiError("UNAUTHORIZED", "Unauthorized", 401);
106
+ }
107
+
108
+ const body = await res.json().catch(() => ({}));
109
+
110
+ if (!res.ok) {
111
+ throw new ApiError(
112
+ body?.error?.code ?? "UNKNOWN_ERROR",
113
+ body?.error?.message ?? "An error occurred",
114
+ res.status,
115
+ body?.error?.details
116
+ );
117
+ }
118
+
119
+ return {
120
+ data: (body?.data ?? body) as T,
121
+ pagination: body?.pagination,
122
+ };
123
+ }
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import { ThemeProvider } from "next-themes";
4
+ import { SessionProvider } from "next-auth/react";
5
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
6
+ import { useState } from "react";
7
+
8
+ export function Providers({ children }: { children: React.ReactNode }) {
9
+ const [queryClient] = useState(
10
+ () =>
11
+ new QueryClient({
12
+ defaultOptions: {
13
+ queries: {
14
+ retry: 1,
15
+ staleTime: 30_000,
16
+ },
17
+ },
18
+ })
19
+ );
20
+
21
+ return (
22
+ <ThemeProvider
23
+ attribute="class"
24
+ defaultTheme="light"
25
+ enableSystem
26
+ disableTransitionOnChange
27
+ >
28
+ <SessionProvider>
29
+ <QueryClientProvider client={queryClient}>
30
+ {children}
31
+ </QueryClientProvider>
32
+ </SessionProvider>
33
+ </ThemeProvider>
34
+ );
35
+ }
@@ -0,0 +1,21 @@
1
+
2
+ export interface ListQuery {
3
+ page?: number;
4
+ limit?: number;
5
+ search?: string;
6
+ sort?: string;
7
+ order?: "asc" | "desc";
8
+ [key: string]: unknown;
9
+ }
10
+
11
+ export const qk = {
12
+ all: ["api"] as const,
13
+ users: () => [...qk.all, "users"] as const,
14
+ user: (id: string) => [...qk.users(), id] as const,
15
+ projects: () => [...qk.all, "projects"] as const,
16
+ project: (id: string) => [...qk.projects(), id] as const,
17
+ };
18
+
19
+ export function qkList(base: readonly unknown[], query?: ListQuery) {
20
+ return [...base, { ...(query ?? {}) }] as const;
21
+ }
@@ -0,0 +1,7 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ /** Merge Tailwind classes with conflict resolution. */
5
+ export function cn(...inputs: ClassValue[]) {
6
+ return twMerge(clsx(inputs));
7
+ }
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+
3
+ export const emailSchema = z.string().email("Invalid email address");
4
+
5
+ export const passwordSchema = z
6
+ .string()
7
+ .min(8, "Password must be at least 8 characters")
8
+ .max(128, "Password must be at most 128 characters");
9
+
10
+ export const nameSchema = z
11
+ .string()
12
+ .min(1, "Name is required")
13
+ .max(100, "Name must be at most 100 characters");
14
+
15
+ export const uuidSchema = z.string().uuid("Invalid UUID");
@@ -0,0 +1,98 @@
1
+ "use client";
2
+
3
+ import { useMemo } from "react";
4
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5
+ import type { ColumnDef } from "@tanstack/react-table";
6
+ import { Add, DocumentText1, Refresh, Trash } from "iconsax-react";
7
+ import { AppButton, AppListToolbar, AppTable } from "@/components/shared";
8
+ import { useListState } from "@/hooks/use-list-state";
9
+ import { apiFetchEnvelope } from "@/lib/api/client";
10
+ import { qk, qkList } from "@/lib/query-keys";
11
+
12
+ interface ExampleItem {
13
+ id: string;
14
+ name: string;
15
+ createdAt: string;
16
+ }
17
+
18
+ export default function ExampleListView() {
19
+ const { state, setSearch, isPending } = useListState();
20
+ const queryClient = useQueryClient();
21
+
22
+ const query = useQuery({
23
+ queryKey: qkList(qk.all, state),
24
+ queryFn: () =>
25
+ apiFetchEnvelope<{ items: ExampleItem[]; pagination?: { total: number; page: number; totalPages: number } }>(
26
+ `/examples?page=${state.page}&limit=${state.limit}&search=${encodeURIComponent(state.search)}`
27
+ ),
28
+ });
29
+
30
+ const deleteMutation = useMutation({
31
+ mutationFn: (id: string) =>
32
+ apiFetchEnvelope(`/examples/${id}`, { method: "DELETE" }),
33
+ onSuccess: () => void query.invalidateQueries(),
34
+ });
35
+
36
+ function handleDelete(id: string) {
37
+ deleteMutation.mutate(id);
38
+ }
39
+
40
+ const columns = useMemo<ColumnDef<ExampleItem, unknown>[]>(
41
+ () => [
42
+ { accessorKey: "name", header: "Name" },
43
+ {
44
+ accessorKey: "createdAt",
45
+ header: "Created",
46
+ cell: ({ row }) => new Date(row.original.createdAt).toLocaleDateString(),
47
+ },
48
+ {
49
+ id: "actions",
50
+ header: "",
51
+ cell: ({ row }) => (
52
+ <AppButton variant="ghost" onClick={() => handleDelete(row.original.id)}>
53
+ <Trash variant="Outline" color="currentColor" className="h-4 w-4" />
54
+ </AppButton>
55
+ ),
56
+ },
57
+ ],
58
+ [deleteMutation.isPending]
59
+ );
60
+
61
+ return (
62
+ <div className="space-y-6">
63
+ <div className="flex items-center justify-between">
64
+ <h1 className="text-2xl font-bold">Examples</h1>
65
+ <AppButton>
66
+ <Add variant="Outline" color="currentColor" className="h-4 w-4" />
67
+ Create
68
+ </AppButton>
69
+ </div>
70
+
71
+ <AppListToolbar
72
+ search={state.search}
73
+ onSearchChange={setSearch}
74
+ searchPlaceholder="Search examples..."
75
+ resultCount={query.data?.pagination?.total}
76
+ />
77
+
78
+ {query.isError ? (
79
+ <div className="rounded-lg border border-destructive/40 bg-destructive/5 p-8 text-center">
80
+ <p className="text-sm text-muted-foreground">Could not load examples.</p>
81
+ <AppButton variant="outline" className="mt-3" onClick={() => void query.refetch()}>
82
+ <Refresh variant="Outline" color="currentColor" className="h-4 w-4" />
83
+ Retry
84
+ </AppButton>
85
+ </div>
86
+ ) : (
87
+ <AppTable
88
+ columns={columns}
89
+ data={query.data?.items ?? []}
90
+ loading={query.isLoading || isPending}
91
+ emptyIcon={<DocumentText1 variant="TwoTone" color="currentColor" />}
92
+ emptyTitle="No examples"
93
+ emptyDescription="Create your first example to get started."
94
+ />
95
+ )}
96
+ </div>
97
+ );
98
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [{ "name": "next" }],
17
+ "paths": {
18
+ "@/*": ["./src/*"]
19
+ }
20
+ },
21
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
22
+ "exclude": ["node_modules"]
23
+ }