chat-history-logger-plugin-opencode-claudecode 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.
@@ -0,0 +1 @@
1
+ enabled
@@ -0,0 +1,91 @@
1
+ ---
2
+ description: Update cloud sync configuration (MongoDB or Supabase)
3
+ ---
4
+
5
+ Update the cloud sync configuration for chat history logging.
6
+
7
+ Follow these steps:
8
+
9
+ 1. Read existing config from `.claude/chat-history-cloud-config.json` if it exists. Show current settings (mask sensitive values).
10
+
11
+ 2. Ask the user what they want to update:
12
+ - **Switch provider** - Change between MongoDB and Supabase
13
+ - **Update connection details** - Update credentials/URLs for the current provider
14
+
15
+ 3. Based on their choice:
16
+
17
+ **For MongoDB:**
18
+ - Ask for: Connection string, Database name, Collection name
19
+ - Show current values as defaults (mask the connection string password)
20
+ - Remind them to install pymongo: `pip install pymongo`
21
+
22
+ **For Supabase:**
23
+ - Ask for: Project URL, API Key, Table name
24
+ - Show current values as defaults (mask the API key)
25
+ - Remind them to install supabase: `pip install supabase`
26
+ - If switching to Supabase, remind them to create the table:
27
+ ```sql
28
+ CREATE TABLE chat_history (
29
+ id BIGSERIAL PRIMARY KEY,
30
+ session_id TEXT NOT NULL,
31
+ timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
32
+ date TEXT NOT NULL,
33
+ role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
34
+ content TEXT NOT NULL,
35
+ source TEXT NOT NULL DEFAULT 'claude-code',
36
+ project_path TEXT,
37
+ project_name TEXT,
38
+ local_file TEXT,
39
+ message_id TEXT
40
+ );
41
+ ```
42
+
43
+ 4. Save the updated configuration to `.claude/chat-history-cloud-config.json`
44
+
45
+ **MongoDB format (use these exact keys):**
46
+ ```json
47
+ {
48
+ "provider": "mongodb",
49
+ "connectionString": "mongodb+srv://username:password@cluster.mongodb.net",
50
+ "database": "your_db_name",
51
+ "collection": "your_collection_name"
52
+ }
53
+ ```
54
+
55
+ **Supabase format (use these exact keys):**
56
+ ```json
57
+ {
58
+ "provider": "supabase",
59
+ "supabase_url": "https://your-project.supabase.co",
60
+ "supabase_key": "your-anon-or-service-key",
61
+ "supabase_table": "chat_history"
62
+ }
63
+ ```
64
+
65
+ 5. If cloud sync is currently enabled (enabled here meas `chat-history-cloud-enabled` exists inside `.claude` folder), inform the user the new settings will take effect on the next hook invocation.
66
+
67
+ 6. If the file `chat-history-cloud-enabled` doesn't exist inside `.claude` folder, create the file `chat-history-cloud-enabled` inside `.claude` folder with the content "enabled".
68
+
69
+ 7. Remind the user to keep `.claude/chat-history-cloud-config.json` in their `.gitignore`.
70
+
71
+ 8. Remind the user that provider in `.claude/chat-history-cloud-config.json` should only have just one provider at a time, it doesn't support having both supabase and mongodb at the same time.
72
+
73
+ 9. Remind the user that if they use Supabase in the `.claude/chat-history-cloud-config.json` as the provider, tell them they need to create the table in Supabase first with this SQL:
74
+ ```sql
75
+ CREATE TABLE chat_history (
76
+ id BIGSERIAL PRIMARY KEY,
77
+ session_id TEXT NOT NULL,
78
+ timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
79
+ date TEXT NOT NULL,
80
+ role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
81
+ content TEXT NOT NULL,
82
+ source TEXT NOT NULL DEFAULT 'claude-code',
83
+ project_path TEXT,
84
+ project_name TEXT,
85
+ local_file TEXT,
86
+ message_id TEXT,
87
+ truncated BOOLEAN DEFAULT FALSE
88
+ );
89
+ ```
90
+
91
+ After completing, respond with: "Cloud sync configuration updated."
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Disable cloud sync for chat history
3
+ ---
4
+
5
+ Disable cloud synchronization for chat history logging. Local logging will continue to work.
6
+
7
+ Steps:
8
+ 1. Delete the file `.claude/chat-history-cloud-enabled` if it exists.
9
+ 2. Keep the `.claude/chat-history-cloud-config.json` file intact so the user can re-enable cloud sync later without reconfiguring.
10
+
11
+ After deleting the file, respond with: "Cloud sync is now OFF. Local chat history logging remains active. Your cloud configuration has been preserved for future use."
@@ -0,0 +1,71 @@
1
+ ---
2
+ description: Enable cloud sync for chat history (MongoDB or Supabase)
3
+ ---
4
+
5
+ Enable cloud synchronization for chat history logging. This syncs your local chat history to a cloud database.
6
+
7
+ Follow these steps:
8
+
9
+ 1. First check if `.claude/chat-history-enabled` exists. If not, create it first since local logging must be on for cloud sync to work. The content should be "enabled" and that's it.
10
+
11
+ 2. Create the file `.claude/chat-history-cloud-enabled` with the content "enabled".
12
+
13
+ 3. Check if `.claude/chat-history-cloud-config.json` exists.
14
+
15
+ 4. If the config file does NOT exist, ask the user which cloud provider they want to use:
16
+ - **MongoDB** - For MongoDB Atlas or self-hosted MongoDB
17
+ - **Supabase** - For Supabase PostgreSQL database
18
+
19
+ 5. Based on their choice, ask for the required connection details:
20
+
21
+ **For MongoDB:**
22
+ - Ask for: Connection string, Database name, Collection name
23
+ - Show current values as defaults (mask the connection string password)
24
+
25
+ Then create `.claude/chat-history-cloud-config.json` with this format (use these exact keys):
26
+ ```json
27
+ {
28
+ "provider": "mongodb",
29
+ "connectionString": "mongodb+srv://username:password@cluster.mongodb.net",
30
+ "database": "your_db_name",
31
+ "collection": "your_collection_name"
32
+ }
33
+ ```
34
+
35
+ **For Supabase:**
36
+ - Ask for: Project URL, API Key, Table name
37
+ - Show current values as defaults (mask the API key)
38
+
39
+ Then create `.claude/chat-history-cloud-config.json` with this format (use these exact keys):
40
+ ```json
41
+ {
42
+ "provider": "supabase",
43
+ "supabase_url": "https://your-project.supabase.co",
44
+ "supabase_key": "your-anon-or-service-key",
45
+ "supabase_table": "chat_history"
46
+ }
47
+ ```
48
+
49
+ **Important for Supabase users:** Tell them they need to create the table in Supabase first with this SQL:
50
+ ```sql
51
+ CREATE TABLE chat_history (
52
+ id BIGSERIAL PRIMARY KEY,
53
+ session_id TEXT NOT NULL,
54
+ timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
55
+ date TEXT NOT NULL,
56
+ role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
57
+ content TEXT NOT NULL,
58
+ source TEXT NOT NULL DEFAULT 'claude-code',
59
+ project_path TEXT,
60
+ project_name TEXT,
61
+ local_file TEXT,
62
+ message_id TEXT,
63
+ truncated BOOLEAN DEFAULT FALSE
64
+ );
65
+ ```
66
+
67
+ 6. If `.claude/chat-history-cloud-config.json` already exists, just confirm cloud sync is now enabled.
68
+
69
+ 7. Remind the user to add `.claude/chat-history-cloud-config.json` to their `.gitignore` to avoid committing credentials.
70
+
71
+ After completing, respond with: "Cloud sync is now ON. Chat history will be synced to [provider name]. Make sure to add `.claude/chat-history-cloud-config.json` to your `.gitignore`."
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: Check cloud sync status and connection info
3
+ ---
4
+
5
+ Check the current status of chat history cloud synchronization.
6
+
7
+ Follow these steps:
8
+
9
+ 1. Check if `.claude/chat-history-enabled` exists:
10
+ - If yes: "Local logging: ON"
11
+ - If no: "Local logging: OFF"
12
+
13
+ 2. Check if `.claude/chat-history-cloud-enabled` exists:
14
+ - If yes: "Cloud sync: ON"
15
+ - If no: "Cloud sync: OFF"
16
+
17
+ 3. If cloud sync is ON, read `.claude/chat-history-cloud-config.json` and display:
18
+ - Cloud Provider: [mongodb or supabase]
19
+ - For MongoDB:
20
+ - Database: [database name]
21
+ - Collection: [collection name]
22
+ - Connection: [mask the connection string - show only the host part, hide username/password]
23
+ - For Supabase:
24
+ - Project URL: [supabase URL]
25
+ - Table: [table name]
26
+ - Key: [show only first 8 characters followed by ****]
27
+
28
+ 4. Provide a summary like:
29
+ ```
30
+ Chat History Logger Status
31
+ -------------------------
32
+ Local logging: ON/OFF
33
+ Cloud sync: ON/OFF
34
+ Cloud provider: MongoDB/Supabase/Not configured
35
+ ```
36
+
37
+ If neither local logging nor cloud sync is enabled, suggest running `/chat-history-on` first, then `/chat-history-cloud-on`.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Turn off chat history logging
3
+ ---
4
+
5
+ Delete the file `.claude/chat-history-enabled` to disable chat history logging.
6
+
7
+ After deleting the file, respond with: "Chat history logging is now OFF. Messages will no longer be saved."
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Turn on chat history logging
3
+ ---
4
+
5
+ Create the file `.claude/chat-history-enabled` with the content "enabled" to enable chat history logging.
6
+
7
+ After creating the file, respond with: "Chat history logging is now ON. All messages will be saved to `chat_history/YYYY_MM_DD.md`"
@@ -0,0 +1,288 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Chat History Logger - Claude Code Hook
4
+ =======================================
5
+ Logs user prompts and assistant responses to daily Markdown files
6
+ in chat_history/YYYY_MM_DD.md
7
+
8
+ This script handles two hook events:
9
+ - UserPromptSubmit: logs the user's prompt directly from the hook input
10
+ - Stop: logs the assistant's response by parsing the transcript JSONL
11
+
12
+ Toggle: create/delete .claude/chat-history-enabled to enable/disable logging.
13
+
14
+ Cloud Sync: create/delete .claude/chat-history-cloud-enabled and configure
15
+ .claude/chat-history-cloud-config.json to enable/disable cloud sync.
16
+ Supports MongoDB and Supabase.
17
+ """
18
+
19
+ import sys
20
+ import json
21
+ import os
22
+ from datetime import datetime, timezone
23
+ from pathlib import Path
24
+
25
+ # Content truncation settings
26
+ MAX_CONTENT_SIZE = 14 * 1024 * 1024 # 14MB (leave 2MB buffer for metadata)
27
+ TRUNCATION_SUFFIX = "...."
28
+
29
+ def truncate_content(content: str) -> tuple[str, bool]:
30
+ """Truncate content if it exceeds the size limit. Returns (content, was_truncated)."""
31
+ if len(content.encode('utf-8')) >= MAX_CONTENT_SIZE:
32
+ truncated = content.encode('utf-8')[:MAX_CONTENT_SIZE - len(TRUNCATION_SUFFIX)].decode('utf-8', errors='ignore')
33
+ return truncated + TRUNCATION_SUFFIX, True
34
+ return content, False
35
+
36
+
37
+ def load_cloud_config(cwd):
38
+ """Load cloud sync configuration from JSON file."""
39
+ config_path = os.path.join(cwd, '.claude', 'chat-history-cloud-config.json')
40
+ if not os.path.exists(config_path):
41
+ return None
42
+ try:
43
+ with open(config_path, 'r') as f:
44
+ return json.load(f)
45
+ except (json.JSONDecodeError, IOError):
46
+ return None
47
+
48
+
49
+ def sync_to_mongodb(config, doc):
50
+ """Sync a chat document to MongoDB."""
51
+ try:
52
+ from pymongo import MongoClient
53
+
54
+ # Support both nested config (config.mongodb.*) and flat config (config.*)
55
+ mongo_cfg = config.get('mongodb', config)
56
+ connection_string = mongo_cfg.get('connection_string', mongo_cfg.get('connectionString', ''))
57
+ database_name = mongo_cfg.get('database_name', mongo_cfg.get('database', 'chat_history'))
58
+ collection_name = mongo_cfg.get('collection_name', mongo_cfg.get('collection', 'conversations'))
59
+
60
+ client = MongoClient(connection_string, serverSelectionTimeoutMS=5000)
61
+ db = client[database_name]
62
+ collection = db[collection_name]
63
+
64
+ # Ensure indexes exist (idempotent)
65
+ collection.create_index('date')
66
+ collection.create_index('project_name')
67
+ collection.create_index([('timestamp', -1)])
68
+ collection.create_index('session_id')
69
+
70
+ doc['_created_at'] = datetime.now(timezone.utc)
71
+ collection.insert_one(doc)
72
+ client.close()
73
+ return True
74
+ except ImportError:
75
+ print("[ChatHistoryLogger] pymongo not installed. Run: pip install pymongo", file=sys.stderr)
76
+ return False
77
+ except Exception as e:
78
+ print(f"[ChatHistoryLogger] MongoDB sync failed: {e}", file=sys.stderr)
79
+ return False
80
+
81
+
82
+ def sync_to_supabase(config, doc):
83
+ """Sync a chat document to Supabase."""
84
+ try:
85
+ from supabase import create_client
86
+
87
+ # Support both nested config (config.supabase.*) and flat config (config.*)
88
+ supa_cfg = config.get('supabase', config)
89
+ supabase_url = supa_cfg.get('supabase_url', supa_cfg.get('url', ''))
90
+ supabase_key = supa_cfg.get('supabase_key', supa_cfg.get('key', ''))
91
+ table_name = supa_cfg.get('supabase_table', supa_cfg.get('table', 'chat_history'))
92
+
93
+ client = create_client(supabase_url, supabase_key)
94
+
95
+ row = {
96
+ 'session_id': doc['session_id'],
97
+ 'timestamp': doc['timestamp'],
98
+ 'date': doc['date'],
99
+ 'role': doc['role'],
100
+ 'content': doc['content'],
101
+ 'source': doc['source'],
102
+ 'project_path': doc['project_path'],
103
+ 'project_name': doc['project_name'],
104
+ 'local_file': doc['metadata']['local_file'],
105
+ 'message_id': doc['metadata']['message_id'],
106
+ 'truncated': doc['metadata'].get('truncated', False),
107
+ }
108
+
109
+ result = client.table(table_name).insert(row).execute()
110
+ return True
111
+ except ImportError:
112
+ print("[ChatHistoryLogger] supabase not installed. Run: pip install supabase", file=sys.stderr)
113
+ return False
114
+ except Exception as e:
115
+ print(f"[ChatHistoryLogger] Supabase sync failed: {e}", file=sys.stderr)
116
+ return False
117
+
118
+
119
+ def sync_to_cloud(cwd, role, content, transcript_path=''):
120
+ """Sync a message to cloud if cloud sync is enabled."""
121
+ cloud_enabled_file = os.path.join(cwd, '.claude', 'chat-history-cloud-enabled')
122
+ if not os.path.exists(cloud_enabled_file):
123
+ return
124
+
125
+ config = load_cloud_config(cwd)
126
+ if not config:
127
+ return
128
+
129
+ truncated_content, was_truncated = truncate_content(content)
130
+
131
+ now = datetime.now(timezone.utc)
132
+ date_str = now.strftime('%Y_%m_%d')
133
+ project_name = os.path.basename(os.path.abspath(cwd))
134
+
135
+ # Use transcript path as session ID for grouping, or generate one
136
+ session_id = transcript_path if transcript_path else f"claude_{int(now.timestamp())}"
137
+
138
+ doc = {
139
+ 'session_id': session_id,
140
+ 'timestamp': now.isoformat(),
141
+ 'date': date_str,
142
+ 'role': role,
143
+ 'content': truncated_content,
144
+ 'source': 'claude-code',
145
+ 'project_path': os.path.abspath(cwd),
146
+ 'project_name': project_name,
147
+ 'metadata': {
148
+ 'local_file': f'chat_history/{date_str}.md',
149
+ 'message_id': f'{role}_{int(now.timestamp())}',
150
+ 'truncated': was_truncated,
151
+ }
152
+ }
153
+
154
+ provider = config.get('provider', '')
155
+ if provider == 'mongodb':
156
+ sync_to_mongodb(config, doc)
157
+ elif provider == 'supabase':
158
+ sync_to_supabase(config, doc)
159
+ else:
160
+ print(f"[ChatHistoryLogger] Unknown cloud provider: {provider}", file=sys.stderr)
161
+
162
+
163
+ def main():
164
+ try:
165
+ # Read JSON input from stdin
166
+ input_data = json.loads(sys.stdin.read())
167
+ except (json.JSONDecodeError, EOFError):
168
+ sys.exit(0)
169
+
170
+ hook_event = input_data.get('hook_event_name', '')
171
+ cwd = input_data.get('cwd', os.getcwd())
172
+ transcript_path = input_data.get('transcript_path', '')
173
+
174
+ # Check if logging is enabled via toggle file
175
+ enabled_file = os.path.join(cwd, '.claude', 'chat-history-enabled')
176
+ if not os.path.exists(enabled_file):
177
+ sys.exit(0)
178
+
179
+ # Set up chat_history directory
180
+ chat_history_dir = os.path.join(cwd, 'chat_history')
181
+ os.makedirs(chat_history_dir, exist_ok=True)
182
+
183
+ # Date formatting
184
+ today = datetime.now()
185
+ date_file = today.strftime('%Y_%m_%d')
186
+ date_header = today.strftime('%A, %B %d, %Y')
187
+ timestamp = today.strftime('%H:%M')
188
+
189
+ file_path = os.path.join(chat_history_dir, f'{date_file}.md')
190
+
191
+ # Create header if file doesn't exist
192
+ if not os.path.exists(file_path):
193
+ with open(file_path, 'w') as f:
194
+ f.write(f'# Chat History - {date_header}\n\n---\n\n')
195
+
196
+ # Handle UserPromptSubmit: log the user's message
197
+ if hook_event == 'UserPromptSubmit':
198
+ prompt = input_data.get('prompt', '')
199
+ if prompt:
200
+ with open(file_path, 'a') as f:
201
+ f.write(f'### User [{timestamp}]\n\n{prompt}\n\n---\n\n')
202
+
203
+ # Cloud sync (non-blocking best effort)
204
+ try:
205
+ sync_to_cloud(cwd, 'user', prompt, transcript_path)
206
+ except Exception:
207
+ pass
208
+
209
+ # Handle Stop: log the assistant's response
210
+ elif hook_event == 'Stop':
211
+ assistant_text = ''
212
+
213
+ # Try to parse the transcript JSONL to extract the latest assistant response
214
+ if transcript_path and os.path.exists(transcript_path):
215
+ import time
216
+ # Small delay to ensure the transcript file is fully written
217
+ time.sleep(0.1)
218
+
219
+ try:
220
+ # Read the transcript file from the end to find the most recent assistant message
221
+ with open(transcript_path, 'r') as f:
222
+ lines = f.readlines()
223
+
224
+ # Search backwards through the JSONL for the last assistant message with text content
225
+ for line in reversed(lines):
226
+ line = line.strip()
227
+ if not line:
228
+ continue
229
+
230
+ try:
231
+ msg = json.loads(line)
232
+ except json.JSONDecodeError:
233
+ continue
234
+
235
+ # Skip non-assistant entries
236
+ if msg.get('type') != 'assistant':
237
+ continue
238
+
239
+ # Check for role="assistant" in a nested message field (most common format)
240
+ message_obj = msg.get('message', {})
241
+ if message_obj.get('role') == 'assistant':
242
+ content = message_obj.get('content', [])
243
+ if isinstance(content, list):
244
+ text_parts = [
245
+ block.get('text', '')
246
+ for block in content
247
+ if block.get('type') == 'text' and block.get('text')
248
+ ]
249
+ if text_parts:
250
+ assistant_text = '\n'.join(text_parts)
251
+ break
252
+
253
+ # Check for role="assistant" at the top level (fallback)
254
+ if msg.get('role') == 'assistant':
255
+ content = msg.get('content', [])
256
+ if isinstance(content, list):
257
+ text_parts = [
258
+ block.get('text', '')
259
+ for block in content
260
+ if block.get('type') == 'text' and block.get('text')
261
+ ]
262
+ if text_parts:
263
+ assistant_text = '\n'.join(text_parts)
264
+ break
265
+
266
+ except Exception:
267
+ pass
268
+
269
+ # Log the assistant response
270
+ if assistant_text:
271
+ with open(file_path, 'a') as f:
272
+ f.write(f'### Assistant [{timestamp}]\n\n{assistant_text}\n\n---\n\n')
273
+
274
+ # Cloud sync (non-blocking best effort)
275
+ try:
276
+ sync_to_cloud(cwd, 'assistant', assistant_text, transcript_path)
277
+ except Exception:
278
+ pass
279
+ else:
280
+ # Fallback: log a placeholder if we couldn't extract the text
281
+ with open(file_path, 'a') as f:
282
+ f.write(f'### Assistant [{timestamp}]\n\n*[Response logged]*\n\n---\n\n')
283
+
284
+ sys.exit(0)
285
+
286
+
287
+ if __name__ == '__main__':
288
+ main()
@@ -0,0 +1,24 @@
1
+ {
2
+ "hooks": {
3
+ "UserPromptSubmit": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/chat-history-logger.sh"
9
+ }
10
+ ]
11
+ }
12
+ ],
13
+ "Stop": [
14
+ {
15
+ "hooks": [
16
+ {
17
+ "type": "command",
18
+ "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/chat-history-logger.sh"
19
+ }
20
+ ]
21
+ }
22
+ ]
23
+ }
24
+ }
@@ -0,0 +1 @@
1
+ enabled
@@ -0,0 +1,74 @@
1
+ ---
2
+ description: Update cloud sync configuration (MongoDB or Supabase)
3
+ ---
4
+
5
+ Update the cloud sync configuration for chat history logging.
6
+
7
+ Follow these steps:
8
+
9
+ 1. Read existing config from `.opencode/chat-history-cloud-config.json` if it exists. Show current settings (mask sensitive values).
10
+
11
+ 2. Ask the user what they want to update:
12
+ - **Switch provider** - Change between MongoDB and Supabase
13
+ - **Update connection details** - Update credentials/URLs for the current provider
14
+
15
+ 3. Based on their choice:
16
+
17
+ **For MongoDB:**
18
+ - Ask for: Connection string, Database name, Collection name
19
+ - Show current values as defaults (mask the connection string password)
20
+
21
+ **For Supabase:**
22
+ - Ask for: Project URL, API Key, Table name
23
+ - Show current values as defaults (mask the API key)
24
+
25
+ 4. Save the updated configuration to `.opencode/chat-history-cloud-config.json`
26
+
27
+ **MongoDB format (use these exact keys):**
28
+ ```json
29
+ {
30
+ "provider": "mongodb",
31
+ "connectionString": "mongodb+srv://username:password@cluster.mongodb.net",
32
+ "database": "your_db_name",
33
+ "collection": "your_collection_name"
34
+ }
35
+ ```
36
+
37
+ **Supabase format (use these exact keys):**
38
+ ```json
39
+ {
40
+ "provider": "supabase",
41
+ "supabase_url": "https://your-project.supabase.co",
42
+ "supabase_key": "your-anon-or-service-key",
43
+ "supabase_table": "chat_history"
44
+ }
45
+ ```
46
+
47
+ 5. If cloud sync is currently enabled (enabled here meas `chat-history-cloud-enabled` exists inside `.opencode` folder), inform the user the new settings will take effect on the next hook invocation.
48
+
49
+ 6. If the file `chat-history-cloud-enabled` doesn't exist inside `.opencode` folder, create the file `chat-history-cloud-enabled` inside `.opencode` folder with the content "enabled".
50
+
51
+ 7. Remind the user to keep `.opencode/chat-history-cloud-config.json` in their `.gitignore`.
52
+
53
+ 8. Remind the user that provider in `.opencode/chat-history-cloud-config.json` should only have just one provider at a time, it doesn't support having both supabase and mongodb at the same time.
54
+
55
+ 9. Remind the user that if they use Supabase in the `.opencode/chat-history-cloud-config.json` as the provider, tell them they need to create the table in Supabase first with this SQL:
56
+ ```sql
57
+ CREATE TABLE chat_history (
58
+ id BIGSERIAL PRIMARY KEY,
59
+ session_id TEXT NOT NULL,
60
+ timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
61
+ date TEXT NOT NULL,
62
+ role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
63
+ content TEXT NOT NULL,
64
+ source TEXT NOT NULL DEFAULT 'opencode',
65
+ project_path TEXT,
66
+ project_name TEXT,
67
+ local_file TEXT,
68
+ message_id TEXT,
69
+ truncated BOOLEAN DEFAULT FALSE
70
+ );
71
+ ```
72
+
73
+ After completing, respond with: "Cloud sync configuration updated."
74
+
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Disable cloud sync for chat history
3
+ ---
4
+
5
+ Disable cloud synchronization for chat history logging. Local logging will continue to work.
6
+
7
+ Steps:
8
+ 1. Delete the file `.opencode/chat-history-cloud-enabled` if it exists.
9
+ 2. Keep the `.opencode/chat-history-cloud-config.json` file intact so the user can re-enable cloud sync later without reconfiguring.
10
+
11
+ After deleting the file, respond with: "Cloud sync is now OFF. Local chat history logging remains active. Your cloud configuration has been preserved for future use."