chatroom-cli 1.0.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 (81) hide show
  1. package/dist/api.d.ts +86 -0
  2. package/dist/api.d.ts.map +1 -0
  3. package/dist/api.js +29 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/commands/auth-login.d.ts +10 -0
  6. package/dist/commands/auth-login.d.ts.map +1 -0
  7. package/dist/commands/auth-login.js +165 -0
  8. package/dist/commands/auth-login.js.map +1 -0
  9. package/dist/commands/auth-logout.d.ts +6 -0
  10. package/dist/commands/auth-logout.d.ts.map +1 -0
  11. package/dist/commands/auth-logout.js +21 -0
  12. package/dist/commands/auth-logout.js.map +1 -0
  13. package/dist/commands/auth-status.d.ts +6 -0
  14. package/dist/commands/auth-status.d.ts.map +1 -0
  15. package/dist/commands/auth-status.js +50 -0
  16. package/dist/commands/auth-status.js.map +1 -0
  17. package/dist/commands/complete.d.ts +5 -0
  18. package/dist/commands/complete.d.ts.map +1 -0
  19. package/dist/commands/complete.js +36 -0
  20. package/dist/commands/complete.js.map +1 -0
  21. package/dist/commands/create.d.ts +9 -0
  22. package/dist/commands/create.d.ts.map +1 -0
  23. package/dist/commands/create.js +58 -0
  24. package/dist/commands/create.js.map +1 -0
  25. package/dist/commands/init.d.ts +9 -0
  26. package/dist/commands/init.d.ts.map +1 -0
  27. package/dist/commands/init.js +45 -0
  28. package/dist/commands/init.js.map +1 -0
  29. package/dist/commands/list.d.ts +5 -0
  30. package/dist/commands/list.d.ts.map +1 -0
  31. package/dist/commands/list.js +22 -0
  32. package/dist/commands/list.js.map +1 -0
  33. package/dist/commands/send.d.ts +11 -0
  34. package/dist/commands/send.d.ts.map +1 -0
  35. package/dist/commands/send.js +55 -0
  36. package/dist/commands/send.js.map +1 -0
  37. package/dist/commands/task-complete.d.ts +12 -0
  38. package/dist/commands/task-complete.d.ts.map +1 -0
  39. package/dist/commands/task-complete.js +58 -0
  40. package/dist/commands/task-complete.js.map +1 -0
  41. package/dist/commands/wait-for-message.d.ts +11 -0
  42. package/dist/commands/wait-for-message.d.ts.map +1 -0
  43. package/dist/commands/wait-for-message.js +249 -0
  44. package/dist/commands/wait-for-message.js.map +1 -0
  45. package/dist/config/defaults.d.ts +16 -0
  46. package/dist/config/defaults.d.ts.map +1 -0
  47. package/dist/config/defaults.js +78 -0
  48. package/dist/config/defaults.js.map +1 -0
  49. package/dist/config/loader.d.ts +52 -0
  50. package/dist/config/loader.d.ts.map +1 -0
  51. package/dist/config/loader.js +204 -0
  52. package/dist/config/loader.js.map +1 -0
  53. package/dist/config/schema.d.ts +56 -0
  54. package/dist/config/schema.d.ts.map +1 -0
  55. package/dist/config/schema.js +106 -0
  56. package/dist/config/schema.js.map +1 -0
  57. package/dist/config.d.ts +18 -0
  58. package/dist/config.d.ts.map +1 -0
  59. package/dist/config.js +18 -0
  60. package/dist/config.js.map +1 -0
  61. package/dist/index.d.ts +9 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +132 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/infrastructure/auth/middleware.d.ts +20 -0
  66. package/dist/infrastructure/auth/middleware.d.ts.map +1 -0
  67. package/dist/infrastructure/auth/middleware.js +86 -0
  68. package/dist/infrastructure/auth/middleware.js.map +1 -0
  69. package/dist/infrastructure/auth/storage.d.ts +44 -0
  70. package/dist/infrastructure/auth/storage.d.ts.map +1 -0
  71. package/dist/infrastructure/auth/storage.js +113 -0
  72. package/dist/infrastructure/auth/storage.js.map +1 -0
  73. package/dist/infrastructure/convex/client.d.ts +16 -0
  74. package/dist/infrastructure/convex/client.d.ts.map +1 -0
  75. package/dist/infrastructure/convex/client.js +52 -0
  76. package/dist/infrastructure/convex/client.js.map +1 -0
  77. package/dist/infrastructure/history/storage.d.ts +21 -0
  78. package/dist/infrastructure/history/storage.d.ts.map +1 -0
  79. package/dist/infrastructure/history/storage.js +56 -0
  80. package/dist/infrastructure/history/storage.js.map +1 -0
  81. package/package.json +40 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Authentication middleware
3
+ * Verifies CLI is authenticated before running commands
4
+ */
5
+ import { getSessionId, isAuthenticated, getAuthFilePath } from './storage.js';
6
+ import { api } from '../../api.js';
7
+ import { getConvexClient } from '../convex/client.js';
8
+ /**
9
+ * Require authentication before running a command
10
+ * Exits with error if not authenticated
11
+ */
12
+ export async function requireAuth() {
13
+ // Check local auth file first
14
+ if (!isAuthenticated()) {
15
+ console.error(`\n❌ Error: Not authenticated`);
16
+ console.error(`\n Please authenticate first by running:`);
17
+ console.error(` $ chatroom auth login\n`);
18
+ process.exit(1);
19
+ }
20
+ const sessionId = getSessionId();
21
+ if (!sessionId) {
22
+ console.error(`\n❌ Error: Invalid auth file`);
23
+ console.error(` Path: ${getAuthFilePath()}`);
24
+ console.error(`\n Please re-authenticate:`);
25
+ console.error(` $ chatroom auth login\n`);
26
+ process.exit(1);
27
+ }
28
+ // Validate session with backend
29
+ try {
30
+ const client = await getConvexClient();
31
+ const validation = (await client.query(api.cliAuth.validateSession, {
32
+ sessionId,
33
+ }));
34
+ if (!validation.valid) {
35
+ console.error(`\n❌ Error: Session invalid - ${validation.reason}`);
36
+ console.error(`\n Please re-authenticate:`);
37
+ console.error(` $ chatroom auth login\n`);
38
+ process.exit(1);
39
+ }
40
+ // Touch the session to keep it fresh
41
+ await client.mutation(api.cliAuth.touchSession, { sessionId });
42
+ return {
43
+ sessionId,
44
+ userId: validation.userId,
45
+ userName: validation.userName,
46
+ };
47
+ }
48
+ catch (error) {
49
+ const err = error;
50
+ console.error(`\n❌ Error: Could not validate session`);
51
+ console.error(` ${err.message}`);
52
+ console.error(`\n Please check your connection and try again.`);
53
+ process.exit(1);
54
+ }
55
+ }
56
+ /**
57
+ * Check if authenticated without exiting
58
+ * Returns auth context if authenticated, null otherwise
59
+ */
60
+ export async function checkAuth() {
61
+ if (!isAuthenticated()) {
62
+ return null;
63
+ }
64
+ const sessionId = getSessionId();
65
+ if (!sessionId) {
66
+ return null;
67
+ }
68
+ try {
69
+ const client = await getConvexClient();
70
+ const validation = (await client.query(api.cliAuth.validateSession, {
71
+ sessionId,
72
+ }));
73
+ if (!validation.valid) {
74
+ return null;
75
+ }
76
+ return {
77
+ sessionId,
78
+ userId: validation.userId,
79
+ userName: validation.userName,
80
+ };
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/infrastructure/auth/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * CLI Authentication Storage
3
+ * Manages CLI session storage in ~/.chatroom/auth.jsonc
4
+ */
5
+ interface AuthData {
6
+ sessionId: string;
7
+ createdAt: string;
8
+ deviceName?: string;
9
+ cliVersion?: string;
10
+ }
11
+ /**
12
+ * Get the path to the auth file
13
+ */
14
+ export declare function getAuthFilePath(): string;
15
+ /**
16
+ * Load the stored authentication data
17
+ */
18
+ export declare function loadAuthData(): AuthData | null;
19
+ /**
20
+ * Save authentication data
21
+ */
22
+ export declare function saveAuthData(data: AuthData): void;
23
+ /**
24
+ * Clear authentication data (logout)
25
+ */
26
+ export declare function clearAuthData(): boolean;
27
+ /**
28
+ * Check if CLI is authenticated
29
+ */
30
+ export declare function isAuthenticated(): boolean;
31
+ /**
32
+ * Get the current session ID
33
+ */
34
+ export declare function getSessionId(): string | null;
35
+ /**
36
+ * Get device name for auth requests
37
+ */
38
+ export declare function getDeviceName(): string;
39
+ /**
40
+ * Get CLI version for auth requests
41
+ */
42
+ export declare function getCliVersion(): string;
43
+ export {};
44
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/auth/storage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,UAAU,QAAQ;IAEhB,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAWD;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,QAAQ,GAAG,IAAI,CAkB9C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAejD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAavC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAG5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAQtC"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * CLI Authentication Storage
3
+ * Manages CLI session storage in ~/.chatroom/auth.jsonc
4
+ */
5
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
6
+ import { homedir } from 'node:os';
7
+ import { join } from 'node:path';
8
+ const CHATROOM_DIR = join(homedir(), '.chatroom');
9
+ const AUTH_FILE = 'auth.jsonc';
10
+ /**
11
+ * Ensure the chatroom config directory exists
12
+ */
13
+ function ensureConfigDir() {
14
+ if (!existsSync(CHATROOM_DIR)) {
15
+ mkdirSync(CHATROOM_DIR, { recursive: true });
16
+ }
17
+ }
18
+ /**
19
+ * Get the path to the auth file
20
+ */
21
+ export function getAuthFilePath() {
22
+ return join(CHATROOM_DIR, AUTH_FILE);
23
+ }
24
+ /**
25
+ * Load the stored authentication data
26
+ */
27
+ export function loadAuthData() {
28
+ const authPath = getAuthFilePath();
29
+ if (!existsSync(authPath)) {
30
+ return null;
31
+ }
32
+ try {
33
+ const content = readFileSync(authPath, 'utf-8');
34
+ // Remove comments for JSON parsing (JSONC support)
35
+ const jsonContent = content
36
+ .split('\n')
37
+ .filter((line) => !line.trim().startsWith('//'))
38
+ .join('\n');
39
+ return JSON.parse(jsonContent);
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ /**
46
+ * Save authentication data
47
+ */
48
+ export function saveAuthData(data) {
49
+ ensureConfigDir();
50
+ const authPath = getAuthFilePath();
51
+ const content = `// Chatroom CLI Authentication
52
+ // This file is auto-generated. Do not edit manually.
53
+ // To re-authenticate, run: chatroom auth login
54
+ // To logout, run: chatroom auth logout
55
+ {
56
+ "sessionId": "${data.sessionId}",
57
+ "createdAt": "${data.createdAt}"${data.deviceName ? `,\n "deviceName": "${data.deviceName}"` : ''}${data.cliVersion ? `,\n "cliVersion": "${data.cliVersion}"` : ''}
58
+ }
59
+ `;
60
+ writeFileSync(authPath, content, 'utf-8');
61
+ }
62
+ /**
63
+ * Clear authentication data (logout)
64
+ */
65
+ export function clearAuthData() {
66
+ const authPath = getAuthFilePath();
67
+ if (!existsSync(authPath)) {
68
+ return false;
69
+ }
70
+ try {
71
+ unlinkSync(authPath);
72
+ return true;
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ /**
79
+ * Check if CLI is authenticated
80
+ */
81
+ export function isAuthenticated() {
82
+ const data = loadAuthData();
83
+ return data !== null && !!data.sessionId;
84
+ }
85
+ /**
86
+ * Get the current session ID
87
+ */
88
+ export function getSessionId() {
89
+ const data = loadAuthData();
90
+ return data?.sessionId ?? null;
91
+ }
92
+ /**
93
+ * Get device name for auth requests
94
+ */
95
+ export function getDeviceName() {
96
+ const os = process.platform;
97
+ const hostname = require('node:os').hostname();
98
+ return `${hostname} (${os})`;
99
+ }
100
+ /**
101
+ * Get CLI version for auth requests
102
+ */
103
+ export function getCliVersion() {
104
+ // Try to get version from package.json
105
+ try {
106
+ // This will be resolved at runtime
107
+ return '1.0.0';
108
+ }
109
+ catch {
110
+ return 'unknown';
111
+ }
112
+ }
113
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/infrastructure/auth/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ConvexHttpClient } from 'convex/browser';
2
+ /**
3
+ * Get a singleton Convex HTTP client instance.
4
+ * The client is lazily initialized on first use.
5
+ */
6
+ export declare function getConvexClient(): Promise<ConvexHttpClient>;
7
+ /**
8
+ * Get the current Convex URL (for logging/display purposes)
9
+ * Returns null if client hasn't been initialized yet
10
+ */
11
+ export declare function getCurrentConvexUrl(): string | null;
12
+ /**
13
+ * Reset the client (useful for testing or reconnection)
14
+ */
15
+ export declare function resetConvexClient(): void;
16
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/convex/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAkClD;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAMjE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAEnD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
@@ -0,0 +1,52 @@
1
+ import { ConvexHttpClient } from 'convex/browser';
2
+ import { findConfigPath, loadConfigFromPath, getGlobalConfigPath } from '../../config/loader.js';
3
+ let client = null;
4
+ let cachedConvexUrl = null;
5
+ /**
6
+ * Get the Convex URL from the nearest config file
7
+ */
8
+ function resolveConvexUrl() {
9
+ const configPath = findConfigPath();
10
+ if (!configPath) {
11
+ console.error('❌ No chatroom configuration found');
12
+ console.error('');
13
+ console.error("Please run 'chatroom init' to set up your configuration,");
14
+ console.error('or create a config file at: ' + getGlobalConfigPath());
15
+ process.exit(1);
16
+ }
17
+ const config = loadConfigFromPath(configPath);
18
+ if (!config.convexUrl) {
19
+ console.error('❌ No convexUrl found in configuration');
20
+ console.error(` Config file: ${configPath}`);
21
+ console.error('');
22
+ console.error('Please add "convexUrl" to your config file.');
23
+ process.exit(1);
24
+ }
25
+ return config.convexUrl;
26
+ }
27
+ /**
28
+ * Get a singleton Convex HTTP client instance.
29
+ * The client is lazily initialized on first use.
30
+ */
31
+ export async function getConvexClient() {
32
+ if (!client) {
33
+ cachedConvexUrl = resolveConvexUrl();
34
+ client = new ConvexHttpClient(cachedConvexUrl);
35
+ }
36
+ return client;
37
+ }
38
+ /**
39
+ * Get the current Convex URL (for logging/display purposes)
40
+ * Returns null if client hasn't been initialized yet
41
+ */
42
+ export function getCurrentConvexUrl() {
43
+ return cachedConvexUrl;
44
+ }
45
+ /**
46
+ * Reset the client (useful for testing or reconnection)
47
+ */
48
+ export function resetConvexClient() {
49
+ client = null;
50
+ cachedConvexUrl = null;
51
+ }
52
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/infrastructure/convex/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEjG,IAAI,MAAM,GAA4B,IAAI,CAAC;AAC3C,IAAI,eAAe,GAAkB,IAAI,CAAC;AAE1C;;GAEG;AACH,SAAS,gBAAgB;IACvB,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IAEpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1E,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,mBAAmB,EAAE,CAAC,CAAC;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAE9C,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,OAAO,CAAC,KAAK,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,MAAM,CAAC,SAAS,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,eAAe,GAAG,gBAAgB,EAAE,CAAC;QACrC,MAAM,GAAG,IAAI,gBAAgB,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,IAAI,CAAC;IACd,eAAe,GAAG,IAAI,CAAC;AACzB,CAAC"}
@@ -0,0 +1,21 @@
1
+ interface ChatroomHistoryEntry {
2
+ chatroomId: string;
3
+ teamId: string;
4
+ teamName: string;
5
+ teamRoles: string[];
6
+ createdAt: string;
7
+ }
8
+ /**
9
+ * Load the chatroom history
10
+ */
11
+ export declare function listChatroomHistory(): Promise<ChatroomHistoryEntry[]>;
12
+ /**
13
+ * Save a chatroom to the history
14
+ */
15
+ export declare function saveChatroomHistory(entry: ChatroomHistoryEntry): Promise<void>;
16
+ /**
17
+ * Get the most recent chatroom from history
18
+ */
19
+ export declare function getMostRecentChatroom(): Promise<ChatroomHistoryEntry | null>;
20
+ export {};
21
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/history/storage.ts"],"names":[],"mappings":"AAOA,UAAU,oBAAoB;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAkBD;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAc3E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAWpF;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAGlF"}
@@ -0,0 +1,56 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ const HISTORY_DIR = join(homedir(), '.chatroom', 'history');
5
+ const HISTORY_FILE = 'chatrooms.json';
6
+ /**
7
+ * Ensure the history directory exists
8
+ */
9
+ function ensureHistoryDir() {
10
+ if (!existsSync(HISTORY_DIR)) {
11
+ mkdirSync(HISTORY_DIR, { recursive: true });
12
+ }
13
+ }
14
+ /**
15
+ * Get the path to the history file
16
+ */
17
+ function getHistoryPath() {
18
+ return join(HISTORY_DIR, HISTORY_FILE);
19
+ }
20
+ /**
21
+ * Load the chatroom history
22
+ */
23
+ export async function listChatroomHistory() {
24
+ const historyPath = getHistoryPath();
25
+ if (!existsSync(historyPath)) {
26
+ return [];
27
+ }
28
+ try {
29
+ const content = readFileSync(historyPath, 'utf-8');
30
+ return JSON.parse(content);
31
+ }
32
+ catch {
33
+ console.warn('Warning: Could not read chatroom history');
34
+ return [];
35
+ }
36
+ }
37
+ /**
38
+ * Save a chatroom to the history
39
+ */
40
+ export async function saveChatroomHistory(entry) {
41
+ ensureHistoryDir();
42
+ const history = await listChatroomHistory();
43
+ history.unshift(entry); // Add to beginning
44
+ // Keep only the last 100 entries
45
+ const trimmedHistory = history.slice(0, 100);
46
+ const historyPath = getHistoryPath();
47
+ writeFileSync(historyPath, JSON.stringify(trimmedHistory, null, 2), 'utf-8');
48
+ }
49
+ /**
50
+ * Get the most recent chatroom from history
51
+ */
52
+ export async function getMostRecentChatroom() {
53
+ const history = await listChatroomHistory();
54
+ return history.length > 0 ? history[0] : null;
55
+ }
56
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/infrastructure/history/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;AAC5D,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAUtC;;GAEG;AACH,SAAS,gBAAgB;IACvB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc;IACrB,OAAO,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAA2B,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAA2B;IACnE,gBAAgB,EAAE,CAAC;IAEnB,MAAM,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC5C,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB;IAE3C,iCAAiC;IACjC,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE7C,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC/E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC5C,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "chatroom-cli",
3
+ "version": "1.0.0",
4
+ "description": "CLI for multi-agent chatroom collaboration",
5
+ "type": "module",
6
+ "bin": {
7
+ "chatroom": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "dev": "bun run src/index.ts",
12
+ "typecheck": "tsc --noEmit",
13
+ "chatroom": "bun run src/index.ts",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "dependencies": {
17
+ "commander": "^14.0.0",
18
+ "convex": "^1.31.0",
19
+ "node-notifier": "^10.0.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/bun": "latest",
23
+ "@types/node": "^20.0.0",
24
+ "@types/node-notifier": "^8.0.5",
25
+ "typescript": "^5.0.0"
26
+ },
27
+ "keywords": [
28
+ "cli",
29
+ "chatroom",
30
+ "multi-agent",
31
+ "convex"
32
+ ],
33
+ "author": "",
34
+ "license": "ISC",
35
+ "files": [
36
+ "dist",
37
+ "package.json",
38
+ "README.md"
39
+ ]
40
+ }