mop-agent 0.1.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 (86) hide show
  1. package/README.md +177 -0
  2. package/apps/web/.env.example +18 -0
  3. package/apps/web/app/api/actions/[id]/approve/route.ts +15 -0
  4. package/apps/web/app/api/actions/[id]/deny/route.ts +15 -0
  5. package/apps/web/app/api/actions/route.ts +29 -0
  6. package/apps/web/app/api/auth/[...all]/route.ts +4 -0
  7. package/apps/web/app/api/chat/route.ts +50 -0
  8. package/apps/web/app/api/consolidate/route.ts +10 -0
  9. package/apps/web/app/api/graph/route.ts +34 -0
  10. package/apps/web/app/api/invites/route.ts +38 -0
  11. package/apps/web/app/api/link/code/route.ts +13 -0
  12. package/apps/web/app/api/link/pair/route.ts +41 -0
  13. package/apps/web/app/api/me/route.ts +11 -0
  14. package/apps/web/app/api/members/route.ts +16 -0
  15. package/apps/web/app/api/projects/[id]/memory/route.ts +12 -0
  16. package/apps/web/app/api/projects/[id]/state/route.ts +19 -0
  17. package/apps/web/app/api/projects/route.ts +21 -0
  18. package/apps/web/app/api/providers/route.ts +32 -0
  19. package/apps/web/app/api/semantic/route.ts +9 -0
  20. package/apps/web/app/api/setup/status/route.ts +6 -0
  21. package/apps/web/app/api/skills/route.ts +23 -0
  22. package/apps/web/app/brain/[projectId]/page.tsx +50 -0
  23. package/apps/web/app/brain/graph/page.tsx +54 -0
  24. package/apps/web/app/brain/page.tsx +167 -0
  25. package/apps/web/app/chat/[projectId]/page.tsx +113 -0
  26. package/apps/web/app/layout.tsx +24 -0
  27. package/apps/web/app/page.tsx +72 -0
  28. package/apps/web/app/settings/page.tsx +63 -0
  29. package/apps/web/app/setup/page.tsx +113 -0
  30. package/apps/web/app/team/page.tsx +86 -0
  31. package/apps/web/bin/mop-agent.mjs +85 -0
  32. package/apps/web/lib/auth-client.ts +5 -0
  33. package/apps/web/lib/auth.ts +86 -0
  34. package/apps/web/lib/authz.ts +23 -0
  35. package/apps/web/lib/brain/answer.ts +27 -0
  36. package/apps/web/lib/brain/approvals.ts +81 -0
  37. package/apps/web/lib/brain/broker.ts +98 -0
  38. package/apps/web/lib/brain/consolidate.ts +133 -0
  39. package/apps/web/lib/brain/mirror.ts +80 -0
  40. package/apps/web/lib/brain/scheduler.ts +30 -0
  41. package/apps/web/lib/brain/skills.ts +34 -0
  42. package/apps/web/lib/channels/binding.ts +26 -0
  43. package/apps/web/lib/channels/discord.ts +28 -0
  44. package/apps/web/lib/channels/handler.ts +44 -0
  45. package/apps/web/lib/channels/index.ts +18 -0
  46. package/apps/web/lib/channels/telegram.ts +18 -0
  47. package/apps/web/lib/crypto.ts +35 -0
  48. package/apps/web/lib/db/client.ts +34 -0
  49. package/apps/web/lib/db/migrate.ts +116 -0
  50. package/apps/web/lib/db/paths.ts +25 -0
  51. package/apps/web/lib/db/schema.ts +105 -0
  52. package/apps/web/lib/link/store.ts +89 -0
  53. package/apps/web/lib/memory/embed.ts +111 -0
  54. package/apps/web/lib/memory/local-embedder.ts +26 -0
  55. package/apps/web/lib/providers/anthropic.ts +23 -0
  56. package/apps/web/lib/providers/config.ts +55 -0
  57. package/apps/web/lib/providers/echo.ts +26 -0
  58. package/apps/web/lib/providers/index.ts +41 -0
  59. package/apps/web/lib/providers/openrouter.ts +24 -0
  60. package/apps/web/lib/providers/types.ts +14 -0
  61. package/apps/web/lib/ws/gateway.ts +113 -0
  62. package/apps/web/next-env.d.ts +6 -0
  63. package/apps/web/next.config.mjs +9 -0
  64. package/apps/web/package.json +44 -0
  65. package/apps/web/scripts/migrate.ts +12 -0
  66. package/apps/web/server.ts +27 -0
  67. package/apps/web/tsconfig.json +31 -0
  68. package/installer/bootstrap.mjs +161 -0
  69. package/installer/lib.mjs +196 -0
  70. package/installer/mop-agent.mjs +322 -0
  71. package/npm-shrinkwrap.json +5032 -0
  72. package/package.json +71 -0
  73. package/packages/flow-connector/bin/cli.mjs +67 -0
  74. package/packages/flow-connector/package.json +26 -0
  75. package/packages/flow-connector/src/exec.ts +81 -0
  76. package/packages/flow-connector/src/index.ts +17 -0
  77. package/packages/flow-connector/src/linkfile.ts +46 -0
  78. package/packages/flow-connector/src/pair.ts +66 -0
  79. package/packages/flow-connector/src/serve.ts +103 -0
  80. package/packages/flow-connector/src/snapshot.ts +94 -0
  81. package/packages/flow-connector/src/tools.ts +198 -0
  82. package/packages/flow-connector/tsconfig.json +10 -0
  83. package/packages/link-protocol/package.json +17 -0
  84. package/packages/link-protocol/src/index.ts +245 -0
  85. package/packages/link-protocol/tsconfig.json +10 -0
  86. package/tsconfig.base.json +18 -0
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Tool request handler (AGENT -> FLOW).
3
+ *
4
+ * THE capability guard. FLOW is the source of truth for permissions — even if the
5
+ * AGENT claims a write was "approved", FLOW re-checks the capability (and, for
6
+ * writes, a valid session) before doing anything. Defense in depth.
7
+ */
8
+ import { readFile, writeFile, mkdir, appendFile, readdir, stat } from "node:fs/promises";
9
+ import { existsSync } from "node:fs";
10
+ import { dirname, join, resolve } from "node:path";
11
+ import {
12
+ DEFAULT_EXECUTION_POLICY,
13
+ isReadTool,
14
+ TOOL_CAPABILITY,
15
+ type Capabilities,
16
+ type ExecutionPolicy,
17
+ type McpToolName,
18
+ } from "@mop/link-protocol";
19
+ import { runShell } from "./exec.js";
20
+
21
+ export type ToolContext = {
22
+ projectRoot: string;
23
+ capabilities: Capabilities;
24
+ /** Hook into the real .MOP session check (v1.2.0). Returns true if actor holds a valid session. */
25
+ hasValidSession?: (actor?: string) => Promise<boolean> | boolean;
26
+ /** Required for run_shell / edit_code; defaults to host backend. */
27
+ execution?: ExecutionPolicy;
28
+ };
29
+
30
+ export class CapabilityError extends Error {}
31
+
32
+ export async function handleToolRequest(
33
+ tool: McpToolName,
34
+ args: Record<string, unknown>,
35
+ ctx: ToolContext,
36
+ ): Promise<unknown> {
37
+ // 1) Guard
38
+ if (!isReadTool(tool)) {
39
+ const cap = TOOL_CAPABILITY[tool as keyof typeof TOOL_CAPABILITY];
40
+ if (!cap || !ctx.capabilities[cap]) {
41
+ throw new CapabilityError(`capability_denied:${cap ?? tool}`);
42
+ }
43
+ const ok = ctx.hasValidSession ? await ctx.hasValidSession(args.actor as string | undefined) : true;
44
+ if (!ok) throw new CapabilityError("no_valid_session");
45
+ }
46
+
47
+ // 2) Dispatch
48
+ switch (tool) {
49
+ case "get_project_state":
50
+ return readJson(join(ctx.projectRoot, ".MOP", "STATE.json"));
51
+ case "list_memory":
52
+ return listMemory(ctx.projectRoot, Number(args.limit ?? 50));
53
+ case "read_artifact":
54
+ return readText(join(ctx.projectRoot, ".MOP", "artifacts", String(args.path)));
55
+ case "list_artifacts":
56
+ return listArtifacts(ctx.projectRoot);
57
+ case "workflow_status":
58
+ return workflowStatus(ctx.projectRoot);
59
+ case "search_project_context":
60
+ return searchContext(ctx.projectRoot, String(args.query ?? ""));
61
+ case "append_memory":
62
+ return appendMemory(ctx.projectRoot, args);
63
+ case "write_artifact":
64
+ return writeArtifact(ctx.projectRoot, String(args.path), String(args.content));
65
+ case "workflow_next":
66
+ return { note: "TODO: advance workflow via mop-core" };
67
+ case "run_shell": {
68
+ // Reaches here only if capabilities.runShell is granted (see §9.1).
69
+ const policy = ctx.execution ?? DEFAULT_EXECUTION_POLICY;
70
+ return runShell(String(args.command ?? ""), ctx.projectRoot, policy);
71
+ }
72
+ case "edit_code":
73
+ // Reaches here only if capabilities.editCode is granted.
74
+ return editCode(ctx.projectRoot, String(args.path), String(args.content));
75
+ default:
76
+ throw new CapabilityError(`unknown_tool:${tool}`);
77
+ }
78
+ }
79
+
80
+ // --- helpers -------------------------------------------------------------
81
+
82
+ async function readJson(p: string): Promise<unknown> {
83
+ if (!existsSync(p)) return {};
84
+ return JSON.parse(await readFile(p, "utf8"));
85
+ }
86
+
87
+ async function readText(p: string): Promise<string> {
88
+ return readFile(p, "utf8");
89
+ }
90
+
91
+ async function listMemory(projectRoot: string, limit: number): Promise<unknown[]> {
92
+ const dir = join(projectRoot, ".MOP", "memory");
93
+ if (!existsSync(dir)) return [];
94
+ const { readdir } = await import("node:fs/promises");
95
+ const files = (await readdir(dir)).filter((f) => f.endsWith(".jsonl")).sort().reverse();
96
+ const out: unknown[] = [];
97
+ for (const f of files) {
98
+ const raw = await readFile(join(dir, f), "utf8");
99
+ for (const line of raw.split("\n").reverse()) {
100
+ const t = line.trim();
101
+ if (!t) continue;
102
+ try {
103
+ out.push(JSON.parse(t));
104
+ } catch {
105
+ /* skip */
106
+ }
107
+ if (out.length >= limit) return out;
108
+ }
109
+ }
110
+ return out;
111
+ }
112
+
113
+ async function appendMemory(projectRoot: string, args: Record<string, unknown>): Promise<{ ok: true; id: string }> {
114
+ const now = new Date();
115
+ const id = `mem-${now.getTime().toString(36)}-${Math.random().toString(16).slice(2, 6)}`;
116
+ const entry = {
117
+ id,
118
+ at: now.getTime(),
119
+ actor: args.actor ?? "agent",
120
+ kind: args.kind ?? "conversation",
121
+ summary: String(args.summary ?? ""),
122
+ body: args.body,
123
+ };
124
+ const file = join(
125
+ projectRoot,
126
+ ".MOP",
127
+ "memory",
128
+ `${now.getUTCFullYear()}-${String(now.getUTCMonth() + 1).padStart(2, "0")}.jsonl`,
129
+ );
130
+ await mkdir(dirname(file), { recursive: true });
131
+ await appendFile(file, JSON.stringify(entry) + "\n", "utf8");
132
+ return { ok: true, id };
133
+ }
134
+
135
+ async function writeArtifact(projectRoot: string, relPath: string, content: string): Promise<{ ok: true; path: string }> {
136
+ const p = join(projectRoot, ".MOP", "artifacts", relPath);
137
+ await mkdir(dirname(p), { recursive: true });
138
+ await writeFile(p, content, "utf8");
139
+ return { ok: true, path: relPath };
140
+ }
141
+
142
+ async function listArtifacts(projectRoot: string): Promise<Array<{ path: string; updatedAt: number; size: number }>> {
143
+ const dir = join(projectRoot, ".MOP", "artifacts");
144
+ if (!existsSync(dir)) return [];
145
+ const out: Array<{ path: string; updatedAt: number; size: number }> = [];
146
+ const walk = async (d: string, base: string): Promise<void> => {
147
+ for (const name of await readdir(d)) {
148
+ const full = join(d, name);
149
+ const s = await stat(full);
150
+ if (s.isDirectory()) await walk(full, join(base, name));
151
+ else out.push({ path: join(base, name), updatedAt: s.mtimeMs, size: s.size });
152
+ }
153
+ };
154
+ await walk(dir, "");
155
+ return out;
156
+ }
157
+
158
+ async function workflowStatus(projectRoot: string): Promise<unknown> {
159
+ const p = join(projectRoot, ".MOP", "STATE.json");
160
+ if (!existsSync(p)) return { workflow: null };
161
+ const state = JSON.parse(await readFile(p, "utf8")) as { workflow?: unknown };
162
+ return { workflow: state.workflow ?? null };
163
+ }
164
+
165
+ async function searchContext(projectRoot: string, query: string): Promise<Array<{ id: string; summary: string; score: number }>> {
166
+ const terms = query.toLowerCase().split(/\W+/).filter((t) => t.length >= 2);
167
+ if (!terms.length) return [];
168
+ const dir = join(projectRoot, ".MOP", "memory");
169
+ if (!existsSync(dir)) return [];
170
+ const hits: Array<{ id: string; summary: string; score: number }> = [];
171
+ for (const f of (await readdir(dir)).filter((f) => f.endsWith(".jsonl"))) {
172
+ for (const line of (await readFile(join(dir, f), "utf8")).split("\n")) {
173
+ const t = line.trim();
174
+ if (!t) continue;
175
+ try {
176
+ const m = JSON.parse(t) as { id: string; summary?: string; body?: string };
177
+ const hay = `${m.summary ?? ""} ${m.body ?? ""}`.toLowerCase();
178
+ const score = terms.reduce((s, term) => s + (hay.includes(term) ? 1 : 0), 0);
179
+ if (score > 0) hits.push({ id: m.id, summary: m.summary ?? "", score });
180
+ } catch {
181
+ /* skip */
182
+ }
183
+ }
184
+ }
185
+ return hits.sort((a, b) => b.score - a.score).slice(0, 20);
186
+ }
187
+
188
+ /** edit_code: write a project source file, refusing paths that escape the project root. */
189
+ async function editCode(projectRoot: string, relPath: string, content: string): Promise<{ ok: true; path: string }> {
190
+ const root = resolve(projectRoot);
191
+ const target = resolve(root, relPath);
192
+ if (target !== root && !target.startsWith(root + (process.platform === "win32" ? "\\" : "/"))) {
193
+ throw new CapabilityError("path_escapes_project_root");
194
+ }
195
+ await mkdir(dirname(target), { recursive: true });
196
+ await writeFile(target, content, "utf8");
197
+ return { ok: true, path: relPath };
198
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": ".",
5
+ "noEmit": true,
6
+ "lib": ["ES2022"],
7
+ "types": ["node"]
8
+ },
9
+ "include": ["src/**/*", "bin/**/*"]
10
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@mop/link-protocol",
3
+ "version": "0.0.1",
4
+ "description": "Shared types + message schemas for the MOP-AGENT <-> MOP-FLOW link.",
5
+ "type": "module",
6
+ "main": "./src/index.ts",
7
+ "types": "./src/index.ts",
8
+ "exports": {
9
+ ".": "./src/index.ts"
10
+ },
11
+ "scripts": {
12
+ "typecheck": "tsc --noEmit"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^5.5.0"
16
+ }
17
+ }
@@ -0,0 +1,245 @@
1
+ /**
2
+ * @mop/link-protocol
3
+ *
4
+ * Shared types and message schemas for the MOP-AGENT <-> MOP-FLOW link.
5
+ * Imported by both `apps/web` (AGENT side) and `packages/flow-connector` (FLOW side)
6
+ * so the wire contract stays in exactly one place.
7
+ *
8
+ * Transport: FLOW dials OUT to AGENT over WSS (reverse tunnel). See PRD §3 / FLOW §4.
9
+ */
10
+
11
+ export const LINK_PROTOCOL_VERSION = "1.0" as const;
12
+
13
+ /** Default WSS path the AGENT exposes for FLOW connections. */
14
+ export const LINK_WS_PATH = "/link" as const;
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Capabilities — what an AGENT is allowed to do against a linked project.
18
+ // Enforced FLOW-side (defense in depth); AGENT can only request.
19
+ // ---------------------------------------------------------------------------
20
+
21
+ export type Capabilities = {
22
+ readMemory: boolean;
23
+ writeMemory: boolean;
24
+ readArtifacts: boolean;
25
+ writeArtifacts: boolean;
26
+ runWorkflow: boolean;
27
+ runShell: boolean;
28
+ editCode: boolean;
29
+ };
30
+
31
+ /** Where capability-gated execution (run_shell / edit_code) runs (FLOW side). */
32
+ export type ExecutionBackend = "host" | "docker" | "ssh";
33
+
34
+ export type ExecutionPolicy = {
35
+ backend: ExecutionBackend;
36
+ /** "always" = every exec needs owner approval (default); "never" is dangerous. */
37
+ approval?: "always" | "trusted" | "never";
38
+ docker?: { image: string; network?: string };
39
+ ssh?: { host: string; user: string; cwd?: string };
40
+ /** hard ceiling per command (ms) */
41
+ timeoutMs?: number;
42
+ };
43
+
44
+ export const DEFAULT_EXECUTION_POLICY: ExecutionPolicy = {
45
+ backend: "host",
46
+ approval: "always",
47
+ timeoutMs: 60_000,
48
+ };
49
+
50
+ /** Safe defaults: read freely, controlled writes, no shell/code edits. */
51
+ export const DEFAULT_CAPABILITIES: Capabilities = {
52
+ readMemory: true,
53
+ writeMemory: true,
54
+ readArtifacts: true,
55
+ writeArtifacts: true,
56
+ runWorkflow: true,
57
+ runShell: false,
58
+ editCode: false,
59
+ };
60
+
61
+ // ---------------------------------------------------------------------------
62
+ // Project manifest — sent FLOW -> AGENT at pairing time.
63
+ // ---------------------------------------------------------------------------
64
+
65
+ export type Platform = "win32" | "linux" | "darwin" | string;
66
+
67
+ export type ProjectManifest = {
68
+ projectId: string;
69
+ name: string;
70
+ mopFlowVersion: string;
71
+ platform: Platform;
72
+ workflow?: {
73
+ currentPhase?: string;
74
+ profile?: string;
75
+ };
76
+ capabilities: Capabilities;
77
+ };
78
+
79
+ // ---------------------------------------------------------------------------
80
+ // Brain payload types (mirrored on the AGENT side).
81
+ // ---------------------------------------------------------------------------
82
+
83
+ export type MemoryKind =
84
+ | "decision"
85
+ | "conversation"
86
+ | "artifact"
87
+ | "workflow"
88
+ | "problem"
89
+ | "fix"
90
+ | "preference"
91
+ | "skill";
92
+
93
+ export type MemoryEntry = {
94
+ id: string;
95
+ kind: MemoryKind | string;
96
+ summary: string;
97
+ body?: string;
98
+ actor?: string;
99
+ /** epoch millis */
100
+ at: number;
101
+ /** episodic memory is private by default (judgment layer) */
102
+ private?: boolean;
103
+ tags?: string[];
104
+ };
105
+
106
+ export type ArtifactRef = {
107
+ path: string;
108
+ title?: string;
109
+ /** epoch millis */
110
+ updatedAt: number;
111
+ };
112
+
113
+ // ---------------------------------------------------------------------------
114
+ // MCP tool surface FLOW exposes to AGENT (over the live link).
115
+ // ---------------------------------------------------------------------------
116
+
117
+ export type McpReadTool =
118
+ | "get_project_state"
119
+ | "list_artifacts"
120
+ | "read_artifact"
121
+ | "list_memory"
122
+ | "workflow_status"
123
+ | "search_project_context";
124
+
125
+ export type McpWriteTool =
126
+ | "write_artifact"
127
+ | "append_memory"
128
+ | "workflow_next";
129
+
130
+ /** Future, capability-gated, off by default. */
131
+ export type McpDangerousTool = "run_shell" | "edit_code";
132
+
133
+ export type McpToolName = McpReadTool | McpWriteTool | McpDangerousTool;
134
+
135
+ /** Maps each write/dangerous tool to the capability it requires. */
136
+ export const TOOL_CAPABILITY: Record<McpWriteTool | McpDangerousTool, keyof Capabilities> = {
137
+ write_artifact: "writeArtifacts",
138
+ append_memory: "writeMemory",
139
+ workflow_next: "runWorkflow",
140
+ run_shell: "runShell",
141
+ edit_code: "editCode",
142
+ };
143
+
144
+ export const READ_TOOLS: ReadonlySet<string> = new Set<McpReadTool>([
145
+ "get_project_state",
146
+ "list_artifacts",
147
+ "read_artifact",
148
+ "list_memory",
149
+ "workflow_status",
150
+ "search_project_context",
151
+ ]);
152
+
153
+ // ---------------------------------------------------------------------------
154
+ // Wire messages (both directions over the WSS link).
155
+ // `t` is the discriminator.
156
+ // ---------------------------------------------------------------------------
157
+
158
+ export type HelloMessage = {
159
+ t: "hello";
160
+ capabilities: Capabilities;
161
+ /** epoch millis on the AGENT */
162
+ serverTime: number;
163
+ protocolVersion: typeof LINK_PROTOCOL_VERSION;
164
+ };
165
+
166
+ export type SnapshotPushMessage = {
167
+ t: "snapshot.push";
168
+ projectId: string;
169
+ /** redacted STATE.json (secrets stripped FLOW-side) */
170
+ state: unknown;
171
+ memory: MemoryEntry[];
172
+ artifacts: ArtifactRef[];
173
+ };
174
+
175
+ /** AGENT -> FLOW: request a tool call. */
176
+ export type ReqMessage = {
177
+ t: "req";
178
+ id: string;
179
+ tool: McpToolName;
180
+ args: Record<string, unknown>;
181
+ };
182
+
183
+ /** FLOW -> AGENT: response to a `req`. */
184
+ export type ResMessage = {
185
+ t: "res";
186
+ id: string;
187
+ ok: boolean;
188
+ data?: unknown;
189
+ error?: string;
190
+ };
191
+
192
+ /** FLOW -> AGENT: spontaneous events (memory changed, workflow advanced, etc.). */
193
+ export type EventMessage = {
194
+ t: "event";
195
+ name: string;
196
+ payload: unknown;
197
+ };
198
+
199
+ export type PingMessage = { t: "ping" };
200
+ export type PongMessage = { t: "pong" };
201
+
202
+ export type LinkMessage =
203
+ | HelloMessage
204
+ | SnapshotPushMessage
205
+ | ReqMessage
206
+ | ResMessage
207
+ | EventMessage
208
+ | PingMessage
209
+ | PongMessage;
210
+
211
+ // ---------------------------------------------------------------------------
212
+ // Pairing (HTTP, before the WSS link is established).
213
+ // ---------------------------------------------------------------------------
214
+
215
+ /** FLOW -> AGENT POST /api/link/pair */
216
+ export type PairRequest = {
217
+ code: string;
218
+ manifest: ProjectManifest;
219
+ };
220
+
221
+ /** AGENT -> FLOW response */
222
+ export type PairResponse = {
223
+ projectId: string;
224
+ /** bearer token used for the WSS Authorization header; stored in .MOP/link.json */
225
+ linkToken: string;
226
+ wsUrl: string;
227
+ };
228
+
229
+ // ---------------------------------------------------------------------------
230
+ // Helpers
231
+ // ---------------------------------------------------------------------------
232
+
233
+ /** Narrowing helper for received frames. */
234
+ export function parseLinkMessage(raw: string): LinkMessage {
235
+ const msg = JSON.parse(raw) as LinkMessage;
236
+ if (typeof (msg as { t?: unknown }).t !== "string") {
237
+ throw new Error("invalid link message: missing discriminator `t`");
238
+ }
239
+ return msg;
240
+ }
241
+
242
+ /** True if a tool is a read-only tool (no capability required). */
243
+ export function isReadTool(tool: string): boolean {
244
+ return READ_TOOLS.has(tool);
245
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "noEmit": true,
7
+ "lib": ["ES2022"]
8
+ },
9
+ "include": ["src/**/*"]
10
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "compilerOptions": {
4
+ "target": "ES2022",
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
8
+ "strict": true,
9
+ "noUncheckedIndexedAccess": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true,
15
+ "declaration": false,
16
+ "sourceMap": true
17
+ }
18
+ }