diff --git a/drizzle/0016_petite_thanos.sql b/drizzle/0016_petite_thanos.sql
new file mode 100644
index 0000000..709b44c
--- /dev/null
+++ b/drizzle/0016_petite_thanos.sql
@@ -0,0 +1 @@
+ALTER TABLE `messages` ADD `source_commit_hash` text;
\ No newline at end of file
diff --git a/drizzle/meta/0016_snapshot.json b/drizzle/meta/0016_snapshot.json
new file mode 100644
index 0000000..24a9044
--- /dev/null
+++ b/drizzle/meta/0016_snapshot.json
@@ -0,0 +1,760 @@
+{
+ "version": "6",
+ "dialect": "sqlite",
+ "id": "c0a49147-ac92-4046-afe8-42f20df9314b",
+ "prevId": "41549b62-b247-48d5-90e1-6bfc70f02040",
+ "tables": {
+ "apps": {
+ "name": "apps",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ },
+ "github_org": {
+ "name": "github_org",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "github_repo": {
+ "name": "github_repo",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "github_branch": {
+ "name": "github_branch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "supabase_project_id": {
+ "name": "supabase_project_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "supabase_parent_project_id": {
+ "name": "supabase_parent_project_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "neon_project_id": {
+ "name": "neon_project_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "neon_development_branch_id": {
+ "name": "neon_development_branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "neon_preview_branch_id": {
+ "name": "neon_preview_branch_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "vercel_project_id": {
+ "name": "vercel_project_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "vercel_project_name": {
+ "name": "vercel_project_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "vercel_team_id": {
+ "name": "vercel_team_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "vercel_deployment_url": {
+ "name": "vercel_deployment_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "install_command": {
+ "name": "install_command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "start_command": {
+ "name": "start_command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "chat_context": {
+ "name": "chat_context",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "is_favorite": {
+ "name": "is_favorite",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "0"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "chats": {
+ "name": "chats",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "app_id": {
+ "name": "app_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "initial_commit_hash": {
+ "name": "initial_commit_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "chats_app_id_apps_id_fk": {
+ "name": "chats_app_id_apps_id_fk",
+ "tableFrom": "chats",
+ "tableTo": "apps",
+ "columnsFrom": [
+ "app_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "language_model_providers": {
+ "name": "language_model_providers",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "api_base_url": {
+ "name": "api_base_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "env_var_name": {
+ "name": "env_var_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "language_models": {
+ "name": "language_models",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "display_name": {
+ "name": "display_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "api_name": {
+ "name": "api_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "builtin_provider_id": {
+ "name": "builtin_provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "custom_provider_id": {
+ "name": "custom_provider_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "max_output_tokens": {
+ "name": "max_output_tokens",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "context_window": {
+ "name": "context_window",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "language_models_custom_provider_id_language_model_providers_id_fk": {
+ "name": "language_models_custom_provider_id_language_model_providers_id_fk",
+ "tableFrom": "language_models",
+ "tableTo": "language_model_providers",
+ "columnsFrom": [
+ "custom_provider_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "mcp_servers": {
+ "name": "mcp_servers",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "transport": {
+ "name": "transport",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "command": {
+ "name": "command",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "args": {
+ "name": "args",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "env_json": {
+ "name": "env_json",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "url": {
+ "name": "url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "enabled": {
+ "name": "enabled",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "0"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "mcp_tool_consents": {
+ "name": "mcp_tool_consents",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "server_id": {
+ "name": "server_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "tool_name": {
+ "name": "tool_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "consent": {
+ "name": "consent",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "'ask'"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {
+ "uniq_mcp_consent": {
+ "name": "uniq_mcp_consent",
+ "columns": [
+ "server_id",
+ "tool_name"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "mcp_tool_consents_server_id_mcp_servers_id_fk": {
+ "name": "mcp_tool_consents_server_id_mcp_servers_id_fk",
+ "tableFrom": "mcp_tool_consents",
+ "tableTo": "mcp_servers",
+ "columnsFrom": [
+ "server_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "messages": {
+ "name": "messages",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "chat_id": {
+ "name": "chat_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "approval_state": {
+ "name": "approval_state",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "source_commit_hash": {
+ "name": "source_commit_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "commit_hash": {
+ "name": "commit_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "request_id": {
+ "name": "request_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "messages_chat_id_chats_id_fk": {
+ "name": "messages_chat_id_chats_id_fk",
+ "tableFrom": "messages",
+ "tableTo": "chats",
+ "columnsFrom": [
+ "chat_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "prompts": {
+ "name": "prompts",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ },
+ "versions": {
+ "name": "versions",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "integer",
+ "primaryKey": true,
+ "notNull": true,
+ "autoincrement": true
+ },
+ "app_id": {
+ "name": "app_id",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "commit_hash": {
+ "name": "commit_hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false
+ },
+ "neon_db_timestamp": {
+ "name": "neon_db_timestamp",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "autoincrement": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "autoincrement": false,
+ "default": "(unixepoch())"
+ }
+ },
+ "indexes": {
+ "versions_app_commit_unique": {
+ "name": "versions_app_commit_unique",
+ "columns": [
+ "app_id",
+ "commit_hash"
+ ],
+ "isUnique": true
+ }
+ },
+ "foreignKeys": {
+ "versions_app_id_apps_id_fk": {
+ "name": "versions_app_id_apps_id_fk",
+ "tableFrom": "versions",
+ "tableTo": "apps",
+ "columnsFrom": [
+ "app_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "checkConstraints": {}
+ }
+ },
+ "views": {},
+ "enums": {},
+ "_meta": {
+ "schemas": {},
+ "tables": {},
+ "columns": {}
+ },
+ "internal": {
+ "indexes": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json
index 1e2a0d2..6ba6f69 100644
--- a/drizzle/meta/_journal.json
+++ b/drizzle/meta/_journal.json
@@ -113,6 +113,13 @@
"when": 1760474402750,
"tag": "0015_complete_old_lace",
"breakpoints": true
+ },
+ {
+ "idx": 16,
+ "version": "6",
+ "when": 1762297039106,
+ "tag": "0016_petite_thanos",
+ "breakpoints": true
}
]
}
\ No newline at end of file
diff --git a/e2e-tests/engine.spec.ts b/e2e-tests/engine.spec.ts
index 693165b..48f52ed 100644
--- a/e2e-tests/engine.spec.ts
+++ b/e2e-tests/engine.spec.ts
@@ -9,23 +9,6 @@ testSkipIfWindows("send message to engine", async ({ po }) => {
await po.snapshotMessages({ replaceDumpPath: true });
});
-testSkipIfWindows(
- "send message to engine - smart context conservative",
- async ({ po }) => {
- await po.setUpDyadPro();
- const proModesDialog = await po.openProModesDialog({
- location: "home-chat-input-container",
- });
- await proModesDialog.setSmartContextMode("conservative");
- await proModesDialog.close();
- await po.selectModel({ provider: "Google", model: "Gemini 2.5 Pro" });
- await po.sendPrompt("[dump] tc=turbo-edits");
-
- await po.snapshotServerDump("request");
- await po.snapshotMessages({ replaceDumpPath: true });
- },
-);
-
testSkipIfWindows("send message to engine - openai gpt-5", async ({ po }) => {
await po.setUpDyadPro();
// By default, it's using auto which points to Flash 2.5 and doesn't
diff --git a/e2e-tests/fixtures/engine/read-index.md b/e2e-tests/fixtures/engine/read-index.md
new file mode 100644
index 0000000..b995d26
--- /dev/null
+++ b/e2e-tests/fixtures/engine/read-index.md
@@ -0,0 +1,3 @@
+Read the index page:
+
+Done.
\ No newline at end of file
diff --git a/e2e-tests/fixtures/engine/update-index-1.md b/e2e-tests/fixtures/engine/update-index-1.md
new file mode 100644
index 0000000..78397b8
--- /dev/null
+++ b/e2e-tests/fixtures/engine/update-index-1.md
@@ -0,0 +1,4 @@
+First read
+
+// this file has been replaced
+
\ No newline at end of file
diff --git a/e2e-tests/helpers/test_helper.ts b/e2e-tests/helpers/test_helper.ts
index 11a8064..b5aa2de 100644
--- a/e2e-tests/helpers/test_helper.ts
+++ b/e2e-tests/helpers/test_helper.ts
@@ -71,7 +71,7 @@ class ProModesDialog {
public close: () => Promise,
) {}
- async setSmartContextMode(mode: "balanced" | "off" | "conservative") {
+ async setSmartContextMode(mode: "balanced" | "off" | "deep") {
await this.page
.getByTestId("smart-context-selector")
.getByRole("button", {
diff --git a/e2e-tests/smart_context_deep.spec.ts b/e2e-tests/smart_context_deep.spec.ts
new file mode 100644
index 0000000..6828d3b
--- /dev/null
+++ b/e2e-tests/smart_context_deep.spec.ts
@@ -0,0 +1,18 @@
+import { testSkipIfWindows } from "./helpers/test_helper";
+
+testSkipIfWindows("smart context deep - read write read", async ({ po }) => {
+ await po.setUpDyadPro({ autoApprove: true });
+ const proModesDialog = await po.openProModesDialog({
+ location: "home-chat-input-container",
+ });
+ await proModesDialog.setSmartContextMode("deep");
+ await proModesDialog.close();
+
+ await po.sendPrompt("tc=read-index");
+ await po.sendPrompt("tc=update-index-1");
+ await po.sendPrompt("tc=read-index");
+ await po.sendPrompt("[dump]");
+
+ await po.snapshotServerDump("request");
+ await po.snapshotMessages({ replaceDumpPath: true });
+});
diff --git a/e2e-tests/smart_context_options.spec.ts b/e2e-tests/smart_context_options.spec.ts
index 2b7b77e..8acf28b 100644
--- a/e2e-tests/smart_context_options.spec.ts
+++ b/e2e-tests/smart_context_options.spec.ts
@@ -10,6 +10,6 @@ test("switching smart context mode saves the right setting", async ({ po }) => {
await po.snapshotSettings();
await proModesDialog.setSmartContextMode("off");
await po.snapshotSettings();
- await proModesDialog.setSmartContextMode("conservative");
+ await proModesDialog.setSmartContextMode("deep");
await po.snapshotSettings();
});
diff --git a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context---auto-includes-only-1.txt b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context---auto-includes-only-1.txt
index c2e539c..19c1842 100644
--- a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context---auto-includes-only-1.txt
+++ b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context---auto-includes-only-1.txt
@@ -99,7 +99,8 @@
],
"enable_lazy_edits": true,
"enable_smart_files_context": true,
- "smart_context_mode": "balanced"
+ "smart_context_mode": "balanced",
+ "app_id": 1
}
},
"headers": {
diff --git a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-1.txt b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-1.txt
index e67f4db..8fcd5a4 100644
--- a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-1.txt
+++ b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-1.txt
@@ -69,7 +69,8 @@
],
"enable_lazy_edits": true,
"enable_smart_files_context": true,
- "smart_context_mode": "balanced"
+ "smart_context_mode": "balanced",
+ "app_id": 1
}
},
"headers": {
diff --git a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-3.txt b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-3.txt
index d34619f..2f82336 100644
--- a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-3.txt
+++ b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-3.txt
@@ -57,7 +57,8 @@
],
"enable_lazy_edits": true,
"enable_smart_files_context": false,
- "smart_context_mode": "balanced"
+ "smart_context_mode": "balanced",
+ "app_id": 1
}
},
"headers": {
diff --git a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-4.txt b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-4.txt
index 35c9a03..7d5411c 100644
--- a/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-4.txt
+++ b/e2e-tests/snapshots/context_manage.spec.ts_manage-context---smart-context-4.txt
@@ -115,7 +115,8 @@
],
"enable_lazy_edits": true,
"enable_smart_files_context": false,
- "smart_context_mode": "balanced"
+ "smart_context_mode": "balanced",
+ "app_id": 1
}
},
"headers": {
diff --git a/e2e-tests/snapshots/engine.spec.ts_regular-auto-should-send-message-to-engine-1.txt b/e2e-tests/snapshots/engine.spec.ts_regular-auto-should-send-message-to-engine-1.txt
index 3fbec28..b273363 100644
--- a/e2e-tests/snapshots/engine.spec.ts_regular-auto-should-send-message-to-engine-1.txt
+++ b/e2e-tests/snapshots/engine.spec.ts_regular-auto-should-send-message-to-engine-1.txt
@@ -414,7 +414,8 @@
],
"enable_lazy_edits": true,
"enable_smart_files_context": false,
- "smart_context_mode": "balanced"
+ "smart_context_mode": "balanced",
+ "app_id": 1
}
},
"headers": {
diff --git a/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---anthropic-claude-sonnet-4-1.txt b/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---anthropic-claude-sonnet-4-1.txt
index c913bf7..bcdae55 100644
--- a/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---anthropic-claude-sonnet-4-1.txt
+++ b/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---anthropic-claude-sonnet-4-1.txt
@@ -409,7 +409,8 @@
],
"enable_lazy_edits": true,
"enable_smart_files_context": true,
- "smart_context_mode": "balanced"
+ "smart_context_mode": "balanced",
+ "app_id": 1
}
},
"headers": {
diff --git a/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---openai-gpt-5-1.txt b/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---openai-gpt-5-1.txt
index 4d49f0f..93cde2c 100644
--- a/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---openai-gpt-5-1.txt
+++ b/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---openai-gpt-5-1.txt
@@ -409,7 +409,8 @@
],
"enable_lazy_edits": true,
"enable_smart_files_context": true,
- "smart_context_mode": "balanced"
+ "smart_context_mode": "balanced",
+ "app_id": 1
}
},
"headers": {
diff --git a/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---smart-context-conservative-1.txt b/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---smart-context-conservative-1.txt
deleted file mode 100644
index d8734f3..0000000
--- a/e2e-tests/snapshots/engine.spec.ts_send-message-to-engine---smart-context-conservative-1.txt
+++ /dev/null
@@ -1,423 +0,0 @@
-{
- "body": {
- "model": "gemini/gemini-2.5-pro",
- "max_tokens": 65535,
- "temperature": 0,
- "messages": [
- {
- "role": "system",
- "content": "[[SYSTEM_MESSAGE]]"
- },
- {
- "role": "user",
- "content": "[dump] tc=turbo-edits"
- }
- ],
- "stream": true,
- "thinking": {
- "type": "enabled",
- "include_thoughts": true,
- "budget_tokens": 4000
- },
- "dyad_options": {
- "files": [
- {
- "path": ".gitignore",
- "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.local\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n",
- "force": false
- },
- {
- "path": "AI_RULES.md",
- "content": "# Tech Stack\n\n- You are building a React application.\n- Use TypeScript.\n- Use React Router. KEEP the routes in src/App.tsx\n- Always put source code in the src folder.\n- Put pages into src/pages/\n- Put components into src/components/\n- The main page (default page) is src/pages/Index.tsx\n- UPDATE the main page to include the new components. OTHERWISE, the user can NOT see any components!\n- ALWAYS try to use the shadcn/ui library.\n- Tailwind CSS: always use Tailwind CSS for styling components. Utilize Tailwind classes extensively for layout, spacing, colors, and other design aspects.\n\nAvailable packages and libraries:\n\n- The lucide-react package is installed for icons.\n- You ALREADY have ALL the shadcn/ui components and their dependencies installed. So you don't need to install them again.\n- You have ALL the necessary Radix UI components installed.\n- Use prebuilt components from the shadcn/ui library after importing them. Note that these files shouldn't be edited, so make new components if you need to change them.\n",
- "force": false
- },
- {
- "path": "components.json",
- "content": "{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n \"style\": \"default\",\n \"rsc\": false,\n \"tsx\": true,\n \"tailwind\": {\n \"config\": \"tailwind.config.ts\",\n \"css\": \"src/index.css\",\n \"baseColor\": \"slate\",\n \"cssVariables\": true,\n \"prefix\": \"\"\n },\n \"aliases\": {\n \"components\": \"@/components\",\n \"utils\": \"@/lib/utils\",\n \"ui\": \"@/components/ui\",\n \"lib\": \"@/lib\",\n \"hooks\": \"@/hooks\"\n }\n}\n",
- "force": false
- },
- {
- "path": "eslint.config.js",
- "content": "import js from \"@eslint/js\";\nimport globals from \"globals\";\nimport reactHooks from \"eslint-plugin-react-hooks\";\nimport reactRefresh from \"eslint-plugin-react-refresh\";\nimport tseslint from \"typescript-eslint\";\n\nexport default tseslint.config(\n { ignores: [\"dist\"] },\n {\n extends: [js.configs.recommended, ...tseslint.configs.recommended],\n files: [\"**/*.{ts,tsx}\"],\n languageOptions: {\n ecmaVersion: 2020,\n globals: globals.browser,\n },\n plugins: {\n \"react-hooks\": reactHooks,\n \"react-refresh\": reactRefresh,\n },\n rules: {\n ...reactHooks.configs.recommended.rules,\n \"react-refresh/only-export-components\": [\n \"warn\",\n { allowConstantExport: true },\n ],\n \"@typescript-eslint/no-unused-vars\": \"off\",\n },\n },\n);\n",
- "force": false
- },
- {
- "path": "index.html",
- "content": "\n\n \n \n \n dyad-generated-app\n \n\n \n \n \n \n\n",
- "force": false
- },
- {
- "path": "package.json",
- "content": "{\n \"name\": \"vite_react_shadcn_ts\",\n \"private\": true,\n \"version\": \"0.0.0\",\n \"type\": \"module\",\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"vite build\",\n \"build:dev\": \"vite build --mode development\",\n \"lint\": \"eslint .\",\n \"preview\": \"vite preview\"\n },\n \"dependencies\": {\n \"@hookform/resolvers\": \"^3.9.0\",\n \"@radix-ui/react-accordion\": \"^1.2.0\",\n \"@radix-ui/react-alert-dialog\": \"^1.1.1\",\n \"@radix-ui/react-aspect-ratio\": \"^1.1.0\",\n \"@radix-ui/react-avatar\": \"^1.1.0\",\n \"@radix-ui/react-checkbox\": \"^1.1.1\",\n \"@radix-ui/react-collapsible\": \"^1.1.0\",\n \"@radix-ui/react-context-menu\": \"^2.2.1\",\n \"@radix-ui/react-dialog\": \"^1.1.2\",\n \"@radix-ui/react-dropdown-menu\": \"^2.1.1\",\n \"@radix-ui/react-hover-card\": \"^1.1.1\",\n \"@radix-ui/react-label\": \"^2.1.0\",\n \"@radix-ui/react-menubar\": \"^1.1.1\",\n \"@radix-ui/react-navigation-menu\": \"^1.2.0\",\n \"@radix-ui/react-popover\": \"^1.1.1\",\n \"@radix-ui/react-progress\": \"^1.1.0\",\n \"@radix-ui/react-radio-group\": \"^1.2.0\",\n \"@radix-ui/react-scroll-area\": \"^1.1.0\",\n \"@radix-ui/react-select\": \"^2.1.1\",\n \"@radix-ui/react-separator\": \"^1.1.0\",\n \"@radix-ui/react-slider\": \"^1.2.0\",\n \"@radix-ui/react-slot\": \"^1.1.0\",\n \"@radix-ui/react-switch\": \"^1.1.0\",\n \"@radix-ui/react-tabs\": \"^1.1.0\",\n \"@radix-ui/react-toast\": \"^1.2.1\",\n \"@radix-ui/react-toggle\": \"^1.1.0\",\n \"@radix-ui/react-toggle-group\": \"^1.1.0\",\n \"@radix-ui/react-tooltip\": \"^1.1.4\",\n \"@tanstack/react-query\": \"^5.56.2\",\n \"class-variance-authority\": \"^0.7.1\",\n \"clsx\": \"^2.1.1\",\n \"cmdk\": \"^1.0.0\",\n \"date-fns\": \"^3.6.0\",\n \"embla-carousel-react\": \"^8.3.0\",\n \"input-otp\": \"^1.2.4\",\n \"lucide-react\": \"^0.462.0\",\n \"next-themes\": \"^0.3.0\",\n \"react\": \"^18.3.1\",\n \"react-day-picker\": \"^8.10.1\",\n \"react-dom\": \"^18.3.1\",\n \"react-hook-form\": \"^7.53.0\",\n \"react-resizable-panels\": \"^2.1.3\",\n \"react-router-dom\": \"^6.26.2\",\n \"recharts\": \"^2.12.7\",\n \"sonner\": \"^1.5.0\",\n \"tailwind-merge\": \"^2.5.2\",\n \"tailwindcss-animate\": \"^1.0.7\",\n \"vaul\": \"^0.9.3\",\n \"zod\": \"^3.23.8\"\n },\n \"devDependencies\": {\n \"@dyad-sh/react-vite-component-tagger\": \"^0.8.0\",\n \"@eslint/js\": \"^9.9.0\",\n \"@tailwindcss/typography\": \"^0.5.15\",\n \"@types/node\": \"^22.5.5\",\n \"@types/react\": \"^18.3.3\",\n \"@types/react-dom\": \"^18.3.0\",\n \"@vitejs/plugin-react-swc\": \"^3.9.0\",\n \"autoprefixer\": \"^10.4.20\",\n \"eslint\": \"^9.9.0\",\n \"eslint-plugin-react-hooks\": \"^5.1.0-rc.0\",\n \"eslint-plugin-react-refresh\": \"^0.4.9\",\n \"globals\": \"^15.9.0\",\n \"postcss\": \"^8.4.47\",\n \"tailwindcss\": \"^3.4.11\",\n \"typescript\": \"^5.5.3\",\n \"typescript-eslint\": \"^8.0.1\",\n \"vite\": \"^6.3.4\"\n }\n}\n",
- "force": false
- },
- {
- "path": "postcss.config.js",
- "content": "export default {\n plugins: {\n tailwindcss: {},\n autoprefixer: {},\n },\n};\n",
- "force": false
- },
- {
- "path": "public/favicon.ico",
- "content": "// File contents excluded from context",
- "force": false
- },
- {
- "path": "public/placeholder.svg",
- "content": "// File contents excluded from context",
- "force": false
- },
- {
- "path": "public/robots.txt",
- "content": "// File contents excluded from context",
- "force": false
- },
- {
- "path": "README.md",
- "content": "# Welcome to your Dyad app\n",
- "force": false
- },
- {
- "path": "src/App.css",
- "content": "#root {\n max-width: 1280px;\n margin: 0 auto;\n padding: 2rem;\n text-align: center;\n}\n\n.logo {\n height: 6em;\n padding: 1.5em;\n will-change: filter;\n transition: filter 300ms;\n}\n.logo:hover {\n filter: drop-shadow(0 0 2em #646cffaa);\n}\n.logo.react:hover {\n filter: drop-shadow(0 0 2em #61dafbaa);\n}\n\n@keyframes logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n@media (prefers-reduced-motion: no-preference) {\n a:nth-of-type(2) .logo {\n animation: logo-spin infinite 20s linear;\n }\n}\n\n.card {\n padding: 2em;\n}\n\n.read-the-docs {\n color: #888;\n}\n",
- "force": false
- },
- {
- "path": "src/App.tsx",
- "content": "import { Toaster } from \"@/components/ui/toaster\";\nimport { Toaster as Sonner } from \"@/components/ui/sonner\";\nimport { TooltipProvider } from \"@/components/ui/tooltip\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { BrowserRouter, Routes, Route } from \"react-router-dom\";\nimport Index from \"./pages/Index\";\nimport NotFound from \"./pages/NotFound\";\n\nconst queryClient = new QueryClient();\n\nconst App = () => (\n \n \n \n \n \n \n } />\n {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL \"*\" ROUTE */}\n } />\n \n \n \n \n);\n\nexport default App;\n",
- "force": false
- },
- {
- "path": "src/components/made-with-dyad.tsx",
- "content": "export const MadeWithDyad = () => {\n return (\n \n );\n};\n",
- "force": false
- },
- {
- "path": "src/components/ui/accordion.tsx",
- "content": "import * as React from \"react\";\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\";\nimport { ChevronDown } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst Accordion = AccordionPrimitive.Root;\n\nconst AccordionItem = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAccordionItem.displayName = \"AccordionItem\";\n\nconst AccordionTrigger = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n svg]:rotate-180\",\n className,\n )}\n {...props}\n >\n {children}\n \n \n \n));\nAccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;\n\nconst AccordionContent = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n {children}
\n \n));\n\nAccordionContent.displayName = AccordionPrimitive.Content.displayName;\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\n",
- "force": false
- },
- {
- "path": "src/components/ui/alert-dialog.tsx",
- "content": "import * as React from \"react\";\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\n\nimport { cn } from \"@/lib/utils\";\nimport { buttonVariants } from \"@/components/ui/button\";\n\nconst AlertDialog = AlertDialogPrimitive.Root;\n\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\n\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst AlertDialogContent = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n \n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nconst AlertDialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n \n);\nAlertDialogHeader.displayName = \"AlertDialogHeader\";\n\nconst AlertDialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n \n);\nAlertDialogFooter.displayName = \"AlertDialogFooter\";\n\nconst AlertDialogTitle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAlertDialogDescription.displayName =\n AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n",
- "force": false
- },
- {
- "path": "src/components/ui/alert.tsx",
- "content": "import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground\",\n {\n variants: {\n variant: {\n default: \"bg-background text-foreground\",\n destructive:\n \"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nconst Alert = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes & VariantProps\n>(({ className, variant, ...props }, ref) => (\n \n));\nAlert.displayName = \"Alert\";\n\nconst AlertTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nAlertTitle.displayName = \"AlertTitle\";\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nAlertDescription.displayName = \"AlertDescription\";\n\nexport { Alert, AlertTitle, AlertDescription };\n",
- "force": false
- },
- {
- "path": "src/components/ui/aspect-ratio.tsx",
- "content": "import * as AspectRatioPrimitive from \"@radix-ui/react-aspect-ratio\";\n\nconst AspectRatio = AspectRatioPrimitive.Root;\n\nexport { AspectRatio };\n",
- "force": false
- },
- {
- "path": "src/components/ui/avatar.tsx",
- "content": "import * as React from \"react\";\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst Avatar = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAvatar.displayName = AvatarPrimitive.Root.displayName;\n\nconst AvatarImage = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAvatarImage.displayName = AvatarPrimitive.Image.displayName;\n\nconst AvatarFallback = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nAvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;\n\nexport { Avatar, AvatarImage, AvatarFallback };\n",
- "force": false
- },
- {
- "path": "src/components/ui/badge.tsx",
- "content": "import * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst badgeVariants = cva(\n \"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n {\n variants: {\n variant: {\n default:\n \"border-transparent bg-primary text-primary-foreground hover:bg-primary/80\",\n secondary:\n \"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n destructive:\n \"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80\",\n outline: \"text-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n },\n);\n\nexport interface BadgeProps\n extends React.HTMLAttributes,\n VariantProps {}\n\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n return (\n \n );\n}\n\nexport { Badge, badgeVariants };\n",
- "force": false
- },
- {
- "path": "src/components/ui/breadcrumb.tsx",
- "content": "import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<\"nav\"> & {\n separator?: React.ReactNode;\n }\n>(({ ...props }, ref) => );\nBreadcrumb.displayName = \"Breadcrumb\";\n\nconst BreadcrumbList = React.forwardRef<\n HTMLOListElement,\n React.ComponentPropsWithoutRef<\"ol\">\n>(({ className, ...props }, ref) => (\n
\n));\nBreadcrumbList.displayName = \"BreadcrumbList\";\n\nconst BreadcrumbItem = React.forwardRef<\n HTMLLIElement,\n React.ComponentPropsWithoutRef<\"li\">\n>(({ className, ...props }, ref) => (\n \n));\nBreadcrumbItem.displayName = \"BreadcrumbItem\";\n\nconst BreadcrumbLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentPropsWithoutRef<\"a\"> & {\n asChild?: boolean;\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : \"a\";\n\n return (\n \n );\n});\nBreadcrumbLink.displayName = \"BreadcrumbLink\";\n\nconst BreadcrumbPage = React.forwardRef<\n HTMLSpanElement,\n React.ComponentPropsWithoutRef<\"span\">\n>(({ className, ...props }, ref) => (\n \n));\nBreadcrumbPage.displayName = \"BreadcrumbPage\";\n\nconst BreadcrumbSeparator = ({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) => (\n svg]:size-3.5\", className)}\n {...props}\n >\n {children ?? }\n \n);\nBreadcrumbSeparator.displayName = \"BreadcrumbSeparator\";\n\nconst BreadcrumbEllipsis = ({\n className,\n ...props\n}: React.ComponentProps<\"span\">) => (\n \n \n More\n \n);\nBreadcrumbEllipsis.displayName = \"BreadcrumbElipssis\";\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n",
- "force": false
- },
- {
- "path": "src/components/ui/button.tsx",
- "content": "import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-destructive-foreground hover:bg-destructive/90\",\n outline:\n \"border border-input bg-background hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3\",\n lg: \"h-11 rounded-md px-8\",\n icon: \"h-10 w-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes,\n VariantProps {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : \"button\";\n return (\n \n );\n },\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n",
- "force": false
- },
- {
- "path": "src/components/ui/calendar.tsx",
- "content": "import * as React from \"react\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { DayPicker } from \"react-day-picker\";\n\nimport { cn } from \"@/lib/utils\";\nimport { buttonVariants } from \"@/components/ui/button\";\n\nexport type CalendarProps = React.ComponentProps;\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n ,\n IconRight: ({ ..._props }) => ,\n }}\n {...props}\n />\n );\n}\nCalendar.displayName = \"Calendar\";\n\nexport { Calendar };\n",
- "force": false
- },
- {
- "path": "src/components/ui/card.tsx",
- "content": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nCard.displayName = \"Card\";\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nCardHeader.displayName = \"CardHeader\";\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nCardTitle.displayName = \"CardTitle\";\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nCardDescription.displayName = \"CardDescription\";\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nCardContent.displayName = \"CardContent\";\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => (\n \n));\nCardFooter.displayName = \"CardFooter\";\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardDescription,\n CardContent,\n};\n",
- "force": false
- },
- {
- "path": "src/components/ui/carousel.tsx",
- "content": "import * as React from \"react\";\nimport useEmblaCarousel, {\n type UseEmblaCarouselType,\n} from \"embla-carousel-react\";\nimport { ArrowLeft, ArrowRight } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\n\ntype CarouselApi = UseEmblaCarouselType[1];\ntype UseCarouselParameters = Parameters;\ntype CarouselOptions = UseCarouselParameters[0];\ntype CarouselPlugin = UseCarouselParameters[1];\n\ntype CarouselProps = {\n opts?: CarouselOptions;\n plugins?: CarouselPlugin;\n orientation?: \"horizontal\" | \"vertical\";\n setApi?: (api: CarouselApi) => void;\n};\n\ntype CarouselContextProps = {\n carouselRef: ReturnType[0];\n api: ReturnType[1];\n scrollPrev: () => void;\n scrollNext: () => void;\n canScrollPrev: boolean;\n canScrollNext: boolean;\n} & CarouselProps;\n\nconst CarouselContext = React.createContext(null);\n\nfunction useCarousel() {\n const context = React.useContext(CarouselContext);\n\n if (!context) {\n throw new Error(\"useCarousel must be used within a \");\n }\n\n return context;\n}\n\nconst Carousel = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes & CarouselProps\n>(\n (\n {\n orientation = \"horizontal\",\n opts,\n setApi,\n plugins,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const [carouselRef, api] = useEmblaCarousel(\n {\n ...opts,\n axis: orientation === \"horizontal\" ? \"x\" : \"y\",\n },\n plugins,\n );\n const [canScrollPrev, setCanScrollPrev] = React.useState(false);\n const [canScrollNext, setCanScrollNext] = React.useState(false);\n\n const onSelect = React.useCallback((api: CarouselApi) => {\n if (!api) {\n return;\n }\n\n setCanScrollPrev(api.canScrollPrev());\n setCanScrollNext(api.canScrollNext());\n }, []);\n\n const scrollPrev = React.useCallback(() => {\n api?.scrollPrev();\n }, [api]);\n\n const scrollNext = React.useCallback(() => {\n api?.scrollNext();\n }, [api]);\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === \"ArrowLeft\") {\n event.preventDefault();\n scrollPrev();\n } else if (event.key === \"ArrowRight\") {\n event.preventDefault();\n scrollNext();\n }\n },\n [scrollPrev, scrollNext],\n );\n\n React.useEffect(() => {\n if (!api || !setApi) {\n return;\n }\n\n setApi(api);\n }, [api, setApi]);\n\n React.useEffect(() => {\n if (!api) {\n return;\n }\n\n onSelect(api);\n api.on(\"reInit\", onSelect);\n api.on(\"select\", onSelect);\n\n return () => {\n api?.off(\"select\", onSelect);\n };\n }, [api, onSelect]);\n\n return (\n \n \n {children}\n
\n \n );\n },\n);\nCarousel.displayName = \"Carousel\";\n\nconst CarouselContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => {\n const { carouselRef, orientation } = useCarousel();\n\n return (\n \n );\n});\nCarouselContent.displayName = \"CarouselContent\";\n\nconst CarouselItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes\n>(({ className, ...props }, ref) => {\n const { orientation } = useCarousel();\n\n return (\n \n );\n});\nCarouselItem.displayName = \"CarouselItem\";\n\nconst CarouselPrevious = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps\n>(({ className, variant = \"outline\", size = \"icon\", ...props }, ref) => {\n const { orientation, scrollPrev, canScrollPrev } = useCarousel();\n\n return (\n \n );\n});\nCarouselPrevious.displayName = \"CarouselPrevious\";\n\nconst CarouselNext = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps\n>(({ className, variant = \"outline\", size = \"icon\", ...props }, ref) => {\n const { orientation, scrollNext, canScrollNext } = useCarousel();\n\n return (\n \n );\n});\nCarouselNext.displayName = \"CarouselNext\";\n\nexport {\n type CarouselApi,\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselPrevious,\n CarouselNext,\n};\n",
- "force": false
- },
- {
- "path": "src/components/ui/chart.tsx",
- "content": "import * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\n\nimport { cn } from \"@/lib/utils\";\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nexport type ChartConfig = {\n [k in string]: {\n label?: React.ReactNode;\n icon?: React.ComponentType;\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record }\n );\n};\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nconst ChartContext = React.createContext(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error(\"useChart must be used within a \");\n }\n\n return context;\n}\n\nconst ChartContainer = React.forwardRef<\n HTMLDivElement,\n React.ComponentProps<\"div\"> & {\n config: ChartConfig;\n children: React.ComponentProps<\n typeof RechartsPrimitive.ResponsiveContainer\n >[\"children\"];\n }\n>(({ id, className, children, config, ...props }, ref) => {\n const uniqueId = React.useId();\n const chartId = `chart-${id || uniqueId.replace(/:/g, \"\")}`;\n\n return (\n \n \n \n \n {children}\n \n
\n \n );\n});\nChartContainer.displayName = \"Chart\";\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(\n ([_, config]) => config.theme || config.color,\n );\n\n if (!colorConfig.length) {\n return null;\n }\n\n return (\n