@controlflow-ai/daemon 0.1.1 → 0.1.2
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.
- package/README.md +12 -18
- package/package.json +14 -3
- package/src/agent-runtime.ts +15 -0
- package/src/app.ts +217 -4
- package/src/client.ts +11 -3
- package/src/console.ts +243 -19
- package/src/daemon.ts +25 -6
- package/src/db.ts +101 -4
- package/src/lark/app-registration.ts +141 -0
- package/src/lark/cli.ts +4 -134
- package/src/lark/credentials.ts +36 -3
- package/src/lark/event-router.ts +1 -1
- package/src/lark/setup.ts +74 -5
- package/src/local-api.ts +69 -2
- package/src/local-auth.ts +4 -3
- package/src/migrations/023_projects.ts +65 -0
- package/src/migrations.ts +2 -1
- package/src/types.ts +32 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Database } from 'bun:sqlite';
|
|
2
|
+
|
|
3
|
+
export const version = 23;
|
|
4
|
+
export const name = 'projects';
|
|
5
|
+
|
|
6
|
+
function hasColumn(db: Database, table: string, column: string): boolean {
|
|
7
|
+
const rows = db.query(`PRAGMA table_info(${table})`).all() as Array<{ name: string }>;
|
|
8
|
+
return rows.some((row) => row.name === column);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function addColumnIfMissing(db: Database, table: string, column: string, ddl: string): void {
|
|
12
|
+
if (!hasColumn(db, table, column)) {
|
|
13
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${ddl}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function up(db: Database): void {
|
|
18
|
+
db.exec(`
|
|
19
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
name TEXT NOT NULL,
|
|
22
|
+
computer_id TEXT NOT NULL REFERENCES computers(id) ON DELETE RESTRICT,
|
|
23
|
+
root_path TEXT NOT NULL,
|
|
24
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
25
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_projects_computer
|
|
29
|
+
ON projects(computer_id, name);
|
|
30
|
+
`);
|
|
31
|
+
|
|
32
|
+
addColumnIfMissing(db, 'chats', 'project_id', 'project_id TEXT REFERENCES projects(id) ON DELETE SET NULL');
|
|
33
|
+
addColumnIfMissing(db, 'computer_connections', 'local_control_token', 'local_control_token TEXT');
|
|
34
|
+
|
|
35
|
+
db.exec(`
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_chats_project
|
|
37
|
+
ON chats(project_id, provider, kind);
|
|
38
|
+
|
|
39
|
+
DROP VIEW IF EXISTS chat_stats;
|
|
40
|
+
CREATE VIEW chat_stats AS
|
|
41
|
+
SELECT
|
|
42
|
+
c.id,
|
|
43
|
+
c.name,
|
|
44
|
+
c.display_name,
|
|
45
|
+
c.kind,
|
|
46
|
+
c.server_id,
|
|
47
|
+
c.provider,
|
|
48
|
+
c.dm_type,
|
|
49
|
+
c.capabilities_json,
|
|
50
|
+
c.audit_visibility,
|
|
51
|
+
c.project_id,
|
|
52
|
+
p.name AS project_name,
|
|
53
|
+
p.root_path AS project_root_path,
|
|
54
|
+
p.computer_id AS project_computer_id,
|
|
55
|
+
pc.name AS project_computer_name,
|
|
56
|
+
c.created_at,
|
|
57
|
+
COUNT(m.id) AS message_count,
|
|
58
|
+
MAX(m.created_at) AS last_message_at
|
|
59
|
+
FROM chats c
|
|
60
|
+
LEFT JOIN projects p ON p.id = c.project_id
|
|
61
|
+
LEFT JOIN computers pc ON pc.id = p.computer_id
|
|
62
|
+
LEFT JOIN messages m ON m.chat_id = c.id
|
|
63
|
+
GROUP BY c.id;
|
|
64
|
+
`);
|
|
65
|
+
}
|
package/src/migrations.ts
CHANGED
|
@@ -21,6 +21,7 @@ import * as computerConnections from './migrations/019_computer_connections.js';
|
|
|
21
21
|
import * as computerAgentAssignments from './migrations/020_computer_agent_assignments.js';
|
|
22
22
|
import * as providerIdentityBindings from './migrations/021_provider_identity_bindings.js';
|
|
23
23
|
import * as larkAuthorizedUsers from './migrations/022_lark_authorized_users.js';
|
|
24
|
+
import * as projects from './migrations/023_projects.js';
|
|
24
25
|
|
|
25
26
|
interface Migration {
|
|
26
27
|
version: number;
|
|
@@ -28,7 +29,7 @@ interface Migration {
|
|
|
28
29
|
up(db: Database): void;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
const migrations: Migration[] = [initial, daemonDeliveries, sessionsRuns, messageIdempotency, artifacts, larkChannelFoundation, agentsA0, b0ChatHistory, b0TranscriptIngestSeq, b0TranscriptShadowExternalIds, b0ChannelConversationAuditOnly, b0CrossConversationInvariant, b10EngInboundRawEvents, agentsRuntime, agentRuntimeSessions, roomParticipants, unifiedRoomDelivery, roomDisplayNames, computerConnections, computerAgentAssignments, providerIdentityBindings, larkAuthorizedUsers].sort((a, b) => a.version - b.version);
|
|
32
|
+
const migrations: Migration[] = [initial, daemonDeliveries, sessionsRuns, messageIdempotency, artifacts, larkChannelFoundation, agentsA0, b0ChatHistory, b0TranscriptIngestSeq, b0TranscriptShadowExternalIds, b0ChannelConversationAuditOnly, b0CrossConversationInvariant, b10EngInboundRawEvents, agentsRuntime, agentRuntimeSessions, roomParticipants, unifiedRoomDelivery, roomDisplayNames, computerConnections, computerAgentAssignments, providerIdentityBindings, larkAuthorizedUsers, projects].sort((a, b) => a.version - b.version);
|
|
32
33
|
|
|
33
34
|
function assertContiguousMigrations(): void {
|
|
34
35
|
for (let index = 0; index < migrations.length; index += 1) {
|
package/src/types.ts
CHANGED
|
@@ -16,11 +16,43 @@ export interface Chat {
|
|
|
16
16
|
dm_type: 'agent_agent' | 'user_agent' | 'user_user' | null;
|
|
17
17
|
capabilities_json: string;
|
|
18
18
|
audit_visibility: 'members' | 'admins';
|
|
19
|
+
project_id: string | null;
|
|
20
|
+
project_name: string | null;
|
|
21
|
+
project_root_path: string | null;
|
|
22
|
+
project_computer_id: string | null;
|
|
23
|
+
project_computer_name: string | null;
|
|
19
24
|
created_at: string;
|
|
20
25
|
message_count: number;
|
|
21
26
|
last_message_at: string | null;
|
|
22
27
|
}
|
|
23
28
|
|
|
29
|
+
export interface Project {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
computer_id: string;
|
|
33
|
+
computer_name: string | null;
|
|
34
|
+
root_path: string;
|
|
35
|
+
room_count: number;
|
|
36
|
+
created_at: string;
|
|
37
|
+
updated_at: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface RemoteFileEntry {
|
|
41
|
+
name: string;
|
|
42
|
+
path: string;
|
|
43
|
+
type: 'directory' | 'file' | 'other';
|
|
44
|
+
hidden: boolean;
|
|
45
|
+
readable: boolean;
|
|
46
|
+
selectable: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface RemoteFileList {
|
|
50
|
+
path: string;
|
|
51
|
+
parent: string | null;
|
|
52
|
+
home: string;
|
|
53
|
+
entries: RemoteFileEntry[];
|
|
54
|
+
}
|
|
55
|
+
|
|
24
56
|
export type RoomParticipantKind = 'user' | 'bot' | 'agent';
|
|
25
57
|
export type RoomParticipantSource = 'lark_member_api' | 'known_bot' | 'event' | 'local_agent';
|
|
26
58
|
|