grok-dev 1.0.0-rc1
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/.cursor/rules/development-workflow.mdc +66 -0
- package/.cursor/rules/project-overview.mdc +66 -0
- package/.cursor/rules/react-ink-components.mdc +45 -0
- package/.cursor/rules/tools-and-agent.mdc +62 -0
- package/.cursor/rules/typescript-conventions.mdc +54 -0
- package/.grok/settings.json +3 -0
- package/.husky/pre-commit +1 -0
- package/LICENSE +21 -0
- package/README.md +526 -0
- package/biome.json +51 -0
- package/dist/agent/agent.d.ts +62 -0
- package/dist/agent/agent.js +701 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/delegations.d.ts +42 -0
- package/dist/agent/delegations.js +273 -0
- package/dist/agent/delegations.js.map +1 -0
- package/dist/grok/client.d.ts +12 -0
- package/dist/grok/client.js +37 -0
- package/dist/grok/client.js.map +1 -0
- package/dist/grok/models.d.ts +5 -0
- package/dist/grok/models.js +73 -0
- package/dist/grok/models.js.map +1 -0
- package/dist/grok/tools.d.ts +12 -0
- package/dist/grok/tools.js +230 -0
- package/dist/grok/tools.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +192 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/db.d.ts +18 -0
- package/dist/storage/db.js +71 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/migrations.d.ts +2 -0
- package/dist/storage/migrations.js +92 -0
- package/dist/storage/migrations.js.map +1 -0
- package/dist/storage/sessions.d.ts +15 -0
- package/dist/storage/sessions.js +135 -0
- package/dist/storage/sessions.js.map +1 -0
- package/dist/storage/transcript.d.ts +6 -0
- package/dist/storage/transcript.js +261 -0
- package/dist/storage/transcript.js.map +1 -0
- package/dist/storage/usage.d.ts +9 -0
- package/dist/storage/usage.js +58 -0
- package/dist/storage/usage.js.map +1 -0
- package/dist/storage/workspaces.d.ts +9 -0
- package/dist/storage/workspaces.js +60 -0
- package/dist/storage/workspaces.js.map +1 -0
- package/dist/telegram/bridge.d.ts +39 -0
- package/dist/telegram/bridge.js +164 -0
- package/dist/telegram/bridge.js.map +1 -0
- package/dist/telegram/index.d.ts +3 -0
- package/dist/telegram/index.js +4 -0
- package/dist/telegram/index.js.map +1 -0
- package/dist/telegram/limits.d.ts +3 -0
- package/dist/telegram/limits.js +12 -0
- package/dist/telegram/limits.js.map +1 -0
- package/dist/telegram/pairing.d.ts +9 -0
- package/dist/telegram/pairing.js +30 -0
- package/dist/telegram/pairing.js.map +1 -0
- package/dist/telegram/preview-stream.d.ts +22 -0
- package/dist/telegram/preview-stream.js +181 -0
- package/dist/telegram/preview-stream.js.map +1 -0
- package/dist/telegram/turn-coordinator.d.ts +7 -0
- package/dist/telegram/turn-coordinator.js +14 -0
- package/dist/telegram/turn-coordinator.js.map +1 -0
- package/dist/telegram/typing-refresh.d.ts +3 -0
- package/dist/telegram/typing-refresh.js +12 -0
- package/dist/telegram/typing-refresh.js.map +1 -0
- package/dist/tools/bash.d.ts +27 -0
- package/dist/tools/bash.js +261 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/file.d.ts +15 -0
- package/dist/tools/file.js +94 -0
- package/dist/tools/file.js.map +1 -0
- package/dist/types/index.d.ts +151 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/app.d.ts +15 -0
- package/dist/ui/app.js +1720 -0
- package/dist/ui/app.js.map +1 -0
- package/dist/ui/markdown.d.ts +5 -0
- package/dist/ui/markdown.js +38 -0
- package/dist/ui/markdown.js.map +1 -0
- package/dist/ui/plan.d.ts +24 -0
- package/dist/ui/plan.js +122 -0
- package/dist/ui/plan.js.map +1 -0
- package/dist/ui/terminal-selection-text.d.ts +23 -0
- package/dist/ui/terminal-selection-text.js +59 -0
- package/dist/ui/terminal-selection-text.js.map +1 -0
- package/dist/ui/theme.d.ts +53 -0
- package/dist/ui/theme.js +53 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/git-root.d.ts +1 -0
- package/dist/utils/git-root.js +16 -0
- package/dist/utils/git-root.js.map +1 -0
- package/dist/utils/host-clipboard.d.ts +4 -0
- package/dist/utils/host-clipboard.js +32 -0
- package/dist/utils/host-clipboard.js.map +1 -0
- package/dist/utils/instructions.d.ts +1 -0
- package/dist/utils/instructions.js +73 -0
- package/dist/utils/instructions.js.map +1 -0
- package/dist/utils/settings.d.ts +33 -0
- package/dist/utils/settings.js +88 -0
- package/dist/utils/settings.js.map +1 -0
- package/dist/utils/skills.d.ts +17 -0
- package/dist/utils/skills.js +161 -0
- package/dist/utils/skills.js.map +1 -0
- package/package.json +67 -0
- package/skills-lock.json +10 -0
- package/tmp/large_class.py +633 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const LATEST_DB_VERSION = 1;
|
|
2
|
+
export function applyMigrations(db) {
|
|
3
|
+
const version = Number(db.pragma("user_version", { simple: true })) || 0;
|
|
4
|
+
if (version >= LATEST_DB_VERSION)
|
|
5
|
+
return;
|
|
6
|
+
const migrate = db.transaction(() => {
|
|
7
|
+
if (version < 1) {
|
|
8
|
+
createInitialSchema(db);
|
|
9
|
+
db.pragma("user_version = 1");
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
migrate();
|
|
13
|
+
}
|
|
14
|
+
function createInitialSchema(db) {
|
|
15
|
+
db.exec(`
|
|
16
|
+
CREATE TABLE IF NOT EXISTS workspaces (
|
|
17
|
+
id TEXT PRIMARY KEY,
|
|
18
|
+
scope_key TEXT NOT NULL UNIQUE,
|
|
19
|
+
canonical_path TEXT NOT NULL,
|
|
20
|
+
git_root TEXT,
|
|
21
|
+
display_name TEXT NOT NULL,
|
|
22
|
+
last_seen_at TEXT NOT NULL
|
|
23
|
+
) STRICT;
|
|
24
|
+
|
|
25
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
26
|
+
id TEXT PRIMARY KEY,
|
|
27
|
+
workspace_id TEXT NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
|
|
28
|
+
title TEXT,
|
|
29
|
+
model TEXT NOT NULL,
|
|
30
|
+
mode TEXT NOT NULL,
|
|
31
|
+
cwd_at_start TEXT NOT NULL,
|
|
32
|
+
cwd_last TEXT NOT NULL,
|
|
33
|
+
status TEXT NOT NULL,
|
|
34
|
+
created_at TEXT NOT NULL,
|
|
35
|
+
updated_at TEXT NOT NULL
|
|
36
|
+
) STRICT;
|
|
37
|
+
|
|
38
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
39
|
+
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
40
|
+
seq INTEGER NOT NULL,
|
|
41
|
+
role TEXT NOT NULL,
|
|
42
|
+
message_json TEXT NOT NULL,
|
|
43
|
+
created_at TEXT NOT NULL,
|
|
44
|
+
PRIMARY KEY (session_id, seq)
|
|
45
|
+
) STRICT;
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS tool_calls (
|
|
48
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
49
|
+
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
50
|
+
message_seq INTEGER NOT NULL,
|
|
51
|
+
tool_call_id TEXT NOT NULL,
|
|
52
|
+
tool_name TEXT NOT NULL,
|
|
53
|
+
args_json TEXT NOT NULL,
|
|
54
|
+
status TEXT NOT NULL,
|
|
55
|
+
started_at TEXT NOT NULL,
|
|
56
|
+
completed_at TEXT,
|
|
57
|
+
UNIQUE(session_id, tool_call_id)
|
|
58
|
+
) STRICT;
|
|
59
|
+
|
|
60
|
+
CREATE TABLE IF NOT EXISTS tool_results (
|
|
61
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
62
|
+
tool_call_row_id INTEGER NOT NULL REFERENCES tool_calls(id) ON DELETE CASCADE,
|
|
63
|
+
output_kind TEXT NOT NULL,
|
|
64
|
+
output_json TEXT NOT NULL,
|
|
65
|
+
success INTEGER NOT NULL,
|
|
66
|
+
created_at TEXT NOT NULL
|
|
67
|
+
) STRICT;
|
|
68
|
+
|
|
69
|
+
CREATE TABLE IF NOT EXISTS usage_events (
|
|
70
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
+
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
72
|
+
message_seq INTEGER,
|
|
73
|
+
source TEXT NOT NULL,
|
|
74
|
+
model TEXT NOT NULL,
|
|
75
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
76
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
77
|
+
total_tokens INTEGER NOT NULL DEFAULT 0,
|
|
78
|
+
cost_micros INTEGER NOT NULL DEFAULT 0,
|
|
79
|
+
created_at TEXT NOT NULL
|
|
80
|
+
) STRICT;
|
|
81
|
+
|
|
82
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_workspace_updated
|
|
83
|
+
ON sessions(workspace_id, updated_at DESC);
|
|
84
|
+
CREATE INDEX IF NOT EXISTS idx_messages_session_seq
|
|
85
|
+
ON messages(session_id, seq);
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_tool_calls_session_seq
|
|
87
|
+
ON tool_calls(session_id, message_seq);
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_usage_events_session_created
|
|
89
|
+
ON usage_events(session_id, created_at DESC);
|
|
90
|
+
`);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/storage/migrations.ts"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B,MAAM,UAAU,eAAe,CAAC,EAAkB;IAChD,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACzE,IAAI,OAAO,IAAI,iBAAiB;QAAE,OAAO;IAEzC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QAClC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,mBAAmB,CAAC,EAAE,CAAC,CAAC;YACxB,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,mBAAmB,CAAC,EAAkB;IAC7C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EP,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentMode, SessionInfo, WorkspaceInfo } from "../types/index";
|
|
2
|
+
export declare class SessionStore {
|
|
3
|
+
private readonly workspace;
|
|
4
|
+
constructor(cwd: string);
|
|
5
|
+
getWorkspace(): WorkspaceInfo;
|
|
6
|
+
openSession(selector: string | undefined, model: string, mode: AgentMode, cwd: string): SessionInfo;
|
|
7
|
+
createSession(model: string, mode: AgentMode, cwd: string): SessionInfo;
|
|
8
|
+
getLatestSession(): SessionInfo | null;
|
|
9
|
+
getSessionById(id: string): SessionInfo | null;
|
|
10
|
+
getRequiredSession(id: string): SessionInfo;
|
|
11
|
+
setTitle(id: string, title: string | null): void;
|
|
12
|
+
setModel(id: string, model: string): void;
|
|
13
|
+
setMode(id: string, mode: AgentMode): void;
|
|
14
|
+
touchSession(id: string, cwd: string): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
import { getDatabase } from "./db";
|
|
3
|
+
import { ensureWorkspace } from "./workspaces";
|
|
4
|
+
export class SessionStore {
|
|
5
|
+
workspace;
|
|
6
|
+
constructor(cwd) {
|
|
7
|
+
this.workspace = ensureWorkspace(cwd);
|
|
8
|
+
}
|
|
9
|
+
getWorkspace() {
|
|
10
|
+
return this.workspace;
|
|
11
|
+
}
|
|
12
|
+
openSession(selector, model, mode, cwd) {
|
|
13
|
+
if (!selector) {
|
|
14
|
+
return this.createSession(model, mode, cwd);
|
|
15
|
+
}
|
|
16
|
+
if (selector === "latest") {
|
|
17
|
+
const latest = this.getLatestSession();
|
|
18
|
+
return latest ?? this.createSession(model, mode, cwd);
|
|
19
|
+
}
|
|
20
|
+
const session = this.getSessionById(selector);
|
|
21
|
+
if (!session) {
|
|
22
|
+
throw new Error(`Session "${selector}" was not found.`);
|
|
23
|
+
}
|
|
24
|
+
this.touchSession(session.id, cwd);
|
|
25
|
+
return this.getRequiredSession(session.id);
|
|
26
|
+
}
|
|
27
|
+
createSession(model, mode, cwd) {
|
|
28
|
+
const now = new Date().toISOString();
|
|
29
|
+
const id = createSessionId();
|
|
30
|
+
const db = getDatabase();
|
|
31
|
+
db.prepare(`
|
|
32
|
+
INSERT INTO sessions (
|
|
33
|
+
id, workspace_id, title, model, mode, cwd_at_start, cwd_last, status, created_at, updated_at
|
|
34
|
+
) VALUES (
|
|
35
|
+
@id, @workspace_id, NULL, @model, @mode, @cwd_at_start, @cwd_last, 'active', @created_at, @updated_at
|
|
36
|
+
)
|
|
37
|
+
`).run({
|
|
38
|
+
id,
|
|
39
|
+
workspace_id: this.workspace.id,
|
|
40
|
+
model,
|
|
41
|
+
mode,
|
|
42
|
+
cwd_at_start: cwd,
|
|
43
|
+
cwd_last: cwd,
|
|
44
|
+
created_at: now,
|
|
45
|
+
updated_at: now,
|
|
46
|
+
});
|
|
47
|
+
return this.getRequiredSession(id);
|
|
48
|
+
}
|
|
49
|
+
getLatestSession() {
|
|
50
|
+
const row = getDatabase()
|
|
51
|
+
.prepare(`
|
|
52
|
+
SELECT id, workspace_id, title, model, mode, cwd_at_start, cwd_last, status, created_at, updated_at
|
|
53
|
+
FROM sessions
|
|
54
|
+
WHERE workspace_id = ?
|
|
55
|
+
ORDER BY updated_at DESC
|
|
56
|
+
LIMIT 1
|
|
57
|
+
`)
|
|
58
|
+
.get(this.workspace.id);
|
|
59
|
+
return row ? toSessionInfo(row) : null;
|
|
60
|
+
}
|
|
61
|
+
getSessionById(id) {
|
|
62
|
+
const row = getDatabase()
|
|
63
|
+
.prepare(`
|
|
64
|
+
SELECT id, workspace_id, title, model, mode, cwd_at_start, cwd_last, status, created_at, updated_at
|
|
65
|
+
FROM sessions
|
|
66
|
+
WHERE id = ?
|
|
67
|
+
`)
|
|
68
|
+
.get(id);
|
|
69
|
+
return row ? toSessionInfo(row) : null;
|
|
70
|
+
}
|
|
71
|
+
getRequiredSession(id) {
|
|
72
|
+
const session = this.getSessionById(id);
|
|
73
|
+
if (!session) {
|
|
74
|
+
throw new Error(`Session "${id}" was not found.`);
|
|
75
|
+
}
|
|
76
|
+
return session;
|
|
77
|
+
}
|
|
78
|
+
setTitle(id, title) {
|
|
79
|
+
const now = new Date().toISOString();
|
|
80
|
+
getDatabase()
|
|
81
|
+
.prepare(`
|
|
82
|
+
UPDATE sessions
|
|
83
|
+
SET title = ?, updated_at = ?
|
|
84
|
+
WHERE id = ?
|
|
85
|
+
`)
|
|
86
|
+
.run(title, now, id);
|
|
87
|
+
}
|
|
88
|
+
setModel(id, model) {
|
|
89
|
+
const now = new Date().toISOString();
|
|
90
|
+
getDatabase()
|
|
91
|
+
.prepare(`
|
|
92
|
+
UPDATE sessions
|
|
93
|
+
SET model = ?, updated_at = ?
|
|
94
|
+
WHERE id = ?
|
|
95
|
+
`)
|
|
96
|
+
.run(model, now, id);
|
|
97
|
+
}
|
|
98
|
+
setMode(id, mode) {
|
|
99
|
+
const now = new Date().toISOString();
|
|
100
|
+
getDatabase()
|
|
101
|
+
.prepare(`
|
|
102
|
+
UPDATE sessions
|
|
103
|
+
SET mode = ?, updated_at = ?
|
|
104
|
+
WHERE id = ?
|
|
105
|
+
`)
|
|
106
|
+
.run(mode, now, id);
|
|
107
|
+
}
|
|
108
|
+
touchSession(id, cwd) {
|
|
109
|
+
getDatabase()
|
|
110
|
+
.prepare(`
|
|
111
|
+
UPDATE sessions
|
|
112
|
+
SET cwd_last = ?, updated_at = ?
|
|
113
|
+
WHERE id = ?
|
|
114
|
+
`)
|
|
115
|
+
.run(cwd, new Date().toISOString(), id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function createSessionId() {
|
|
119
|
+
return randomUUID().replace(/-/g, "").slice(0, 12);
|
|
120
|
+
}
|
|
121
|
+
function toSessionInfo(row) {
|
|
122
|
+
return {
|
|
123
|
+
id: row.id,
|
|
124
|
+
workspaceId: row.workspace_id,
|
|
125
|
+
title: row.title,
|
|
126
|
+
model: row.model,
|
|
127
|
+
mode: row.mode,
|
|
128
|
+
cwdAtStart: row.cwd_at_start,
|
|
129
|
+
cwdLast: row.cwd_last,
|
|
130
|
+
status: row.status,
|
|
131
|
+
createdAt: new Date(row.created_at),
|
|
132
|
+
updatedAt: new Date(row.updated_at),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/storage/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAe/C,MAAM,OAAO,YAAY;IACN,SAAS,CAAgB;IAE1C,YAAY,GAAW;QACrB,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,WAAW,CAAC,QAA4B,EAAE,KAAa,EAAE,IAAe,EAAE,GAAW;QACnF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvC,OAAO,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,YAAY,QAAQ,kBAAkB,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,aAAa,CAAC,KAAa,EAAE,IAAe,EAAE,GAAW;QACvD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;QAEzB,EAAE,CAAC,OAAO,CAAC;;;;;;KAMV,CAAC,CAAC,GAAG,CAAC;YACL,EAAE;YACF,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE;YAC/B,KAAK;YACL,IAAI;YACJ,YAAY,EAAE,GAAG;YACjB,QAAQ,EAAE,GAAG;YACb,UAAU,EAAE,GAAG;YACf,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;QACd,MAAM,GAAG,GAAG,WAAW,EAAE;aACtB,OAAO,CAAC;;;;;;KAMV,CAAC;aACC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAA2B,CAAC;QAEpD,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,cAAc,CAAC,EAAU;QACvB,MAAM,GAAG,GAAG,WAAW,EAAE;aACtB,OAAO,CAAC;;;;KAIV,CAAC;aACC,GAAG,CAAC,EAAE,CAA2B,CAAC;QAErC,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED,kBAAkB,CAAC,EAAU;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,QAAQ,CAAC,EAAU,EAAE,KAAoB;QACvC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,WAAW,EAAE;aACV,OAAO,CAAC;;;;KAIV,CAAC;aACC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,QAAQ,CAAC,EAAU,EAAE,KAAa;QAChC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,WAAW,EAAE;aACV,OAAO,CAAC;;;;KAIV,CAAC;aACC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,EAAU,EAAE,IAAe;QACjC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,WAAW,EAAE;aACV,OAAO,CAAC;;;;KAIV,CAAC;aACC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,YAAY,CAAC,EAAU,EAAE,GAAW;QAClC,WAAW,EAAE;aACV,OAAO,CAAC;;;;KAIV,CAAC;aACC,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;CACF;AAED,SAAS,eAAe;IACtB,OAAO,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,aAAa,CAAC,GAAe;IACpC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,UAAU,EAAE,GAAG,CAAC,YAAY;QAC5B,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;QACnC,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;KACpC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
2
|
+
import type { ChatEntry } from "../types/index";
|
|
3
|
+
export declare function loadTranscript(sessionId: string): ModelMessage[];
|
|
4
|
+
export declare function appendMessages(sessionId: string, messages: ModelMessage[]): void;
|
|
5
|
+
export declare function appendSystemMessage(sessionId: string, content: string): void;
|
|
6
|
+
export declare function buildChatEntries(sessionId: string): ChatEntry[];
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { getDatabase, withTransaction } from "./db";
|
|
2
|
+
export function loadTranscript(sessionId) {
|
|
3
|
+
const rows = getDatabase()
|
|
4
|
+
.prepare(`
|
|
5
|
+
SELECT session_id, seq, role, message_json, created_at
|
|
6
|
+
FROM messages
|
|
7
|
+
WHERE session_id = ?
|
|
8
|
+
ORDER BY seq ASC
|
|
9
|
+
`)
|
|
10
|
+
.all(sessionId);
|
|
11
|
+
return rows.map((row) => JSON.parse(row.message_json));
|
|
12
|
+
}
|
|
13
|
+
export function appendMessages(sessionId, messages) {
|
|
14
|
+
if (messages.length === 0)
|
|
15
|
+
return;
|
|
16
|
+
withTransaction((db) => {
|
|
17
|
+
const nextSeq = getNextSequence(db, sessionId);
|
|
18
|
+
const insertMessage = db.prepare(`
|
|
19
|
+
INSERT INTO messages (session_id, seq, role, message_json, created_at)
|
|
20
|
+
VALUES (?, ?, ?, ?, ?)
|
|
21
|
+
`);
|
|
22
|
+
const insertToolCall = db.prepare(`
|
|
23
|
+
INSERT OR IGNORE INTO tool_calls (
|
|
24
|
+
session_id, message_seq, tool_call_id, tool_name, args_json, status, started_at, completed_at
|
|
25
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
26
|
+
`);
|
|
27
|
+
const updateToolCall = db.prepare(`
|
|
28
|
+
UPDATE tool_calls
|
|
29
|
+
SET tool_name = ?, args_json = ?, status = ?, completed_at = ?
|
|
30
|
+
WHERE session_id = ? AND tool_call_id = ?
|
|
31
|
+
`);
|
|
32
|
+
const selectToolCall = db.prepare(`
|
|
33
|
+
SELECT id, tool_call_id, tool_name, args_json
|
|
34
|
+
FROM tool_calls
|
|
35
|
+
WHERE session_id = ? AND tool_call_id = ?
|
|
36
|
+
`);
|
|
37
|
+
const insertToolResult = db.prepare(`
|
|
38
|
+
INSERT INTO tool_results (tool_call_row_id, output_kind, output_json, success, created_at)
|
|
39
|
+
VALUES (?, ?, ?, ?, ?)
|
|
40
|
+
`);
|
|
41
|
+
const updateSession = db.prepare(`
|
|
42
|
+
UPDATE sessions
|
|
43
|
+
SET updated_at = ?
|
|
44
|
+
WHERE id = ?
|
|
45
|
+
`);
|
|
46
|
+
messages.forEach((message, index) => {
|
|
47
|
+
const seq = nextSeq + index;
|
|
48
|
+
const createdAt = new Date().toISOString();
|
|
49
|
+
insertMessage.run(sessionId, seq, message.role, JSON.stringify(message), createdAt);
|
|
50
|
+
if (message.role === "assistant" && Array.isArray(message.content)) {
|
|
51
|
+
for (const part of message.content) {
|
|
52
|
+
if (part.type !== "tool-call")
|
|
53
|
+
continue;
|
|
54
|
+
insertToolCall.run(sessionId, seq, part.toolCallId, part.toolName, JSON.stringify(part.input ?? {}), "completed", createdAt, createdAt);
|
|
55
|
+
updateToolCall.run(part.toolName, JSON.stringify(part.input ?? {}), "completed", createdAt, sessionId, part.toolCallId);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (message.role === "tool" && Array.isArray(message.content)) {
|
|
59
|
+
for (const part of message.content) {
|
|
60
|
+
if (part.type !== "tool-result")
|
|
61
|
+
continue;
|
|
62
|
+
let toolCall = selectToolCall.get(sessionId, part.toolCallId);
|
|
63
|
+
if (!toolCall) {
|
|
64
|
+
insertToolCall.run(sessionId, seq, part.toolCallId, part.toolName, "{}", "completed", createdAt, createdAt);
|
|
65
|
+
toolCall = selectToolCall.get(sessionId, part.toolCallId);
|
|
66
|
+
}
|
|
67
|
+
if (!toolCall)
|
|
68
|
+
continue;
|
|
69
|
+
const extracted = extractToolResultFromOutput(part.output);
|
|
70
|
+
insertToolResult.run(toolCall.id, getOutputKind(part.output), JSON.stringify(extracted ?? part.output), extracted ? Number(extracted.success) : Number(isOutputSuccess(part.output)), createdAt);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
updateSession.run(new Date().toISOString(), sessionId);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export function appendSystemMessage(sessionId, content) {
|
|
78
|
+
appendMessages(sessionId, [{ role: "system", content }]);
|
|
79
|
+
}
|
|
80
|
+
export function buildChatEntries(sessionId) {
|
|
81
|
+
const db = getDatabase();
|
|
82
|
+
const messageRows = db
|
|
83
|
+
.prepare(`
|
|
84
|
+
SELECT session_id, seq, role, message_json, created_at
|
|
85
|
+
FROM messages
|
|
86
|
+
WHERE session_id = ?
|
|
87
|
+
ORDER BY seq ASC
|
|
88
|
+
`)
|
|
89
|
+
.all(sessionId);
|
|
90
|
+
const toolResults = loadStoredToolResults(sessionId);
|
|
91
|
+
const callMap = new Map();
|
|
92
|
+
const entries = [];
|
|
93
|
+
for (const row of messageRows) {
|
|
94
|
+
const message = JSON.parse(row.message_json);
|
|
95
|
+
const timestamp = new Date(row.created_at);
|
|
96
|
+
if (message.role === "user") {
|
|
97
|
+
const content = renderUserContent(message.content);
|
|
98
|
+
if (content) {
|
|
99
|
+
entries.push({ type: "user", content, timestamp });
|
|
100
|
+
}
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (message.role === "system") {
|
|
104
|
+
const content = typeof message.content === "string" ? message.content.trim() : "";
|
|
105
|
+
if (content) {
|
|
106
|
+
entries.push({ type: "assistant", content, timestamp });
|
|
107
|
+
}
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (message.role === "assistant") {
|
|
111
|
+
const text = renderAssistantContent(message.content, callMap);
|
|
112
|
+
if (text) {
|
|
113
|
+
entries.push({ type: "assistant", content: text, timestamp });
|
|
114
|
+
}
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (message.role === "tool" && Array.isArray(message.content)) {
|
|
118
|
+
for (const part of message.content) {
|
|
119
|
+
if (part.type !== "tool-result")
|
|
120
|
+
continue;
|
|
121
|
+
const toolCall = callMap.get(part.toolCallId) ?? toFallbackToolCall(part.toolCallId, part.toolName);
|
|
122
|
+
const toolResult = toolResults.get(part.toolCallId) ??
|
|
123
|
+
extractToolResultFromOutput(part.output) ?? {
|
|
124
|
+
success: isOutputSuccess(part.output),
|
|
125
|
+
output: JSON.stringify(part.output),
|
|
126
|
+
};
|
|
127
|
+
entries.push({
|
|
128
|
+
type: "tool_result",
|
|
129
|
+
content: toolResult.success ? toolResult.output || "Success" : toolResult.error || "Error",
|
|
130
|
+
timestamp,
|
|
131
|
+
toolCall,
|
|
132
|
+
toolResult,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return entries;
|
|
138
|
+
}
|
|
139
|
+
function getNextSequence(db, sessionId) {
|
|
140
|
+
const row = db
|
|
141
|
+
.prepare(`
|
|
142
|
+
SELECT COALESCE(MAX(seq), 0) AS max_seq
|
|
143
|
+
FROM messages
|
|
144
|
+
WHERE session_id = ?
|
|
145
|
+
`)
|
|
146
|
+
.get(sessionId);
|
|
147
|
+
return (row?.max_seq ?? 0) + 1;
|
|
148
|
+
}
|
|
149
|
+
function renderUserContent(content) {
|
|
150
|
+
if (typeof content === "string")
|
|
151
|
+
return content.trim();
|
|
152
|
+
if (!Array.isArray(content))
|
|
153
|
+
return "";
|
|
154
|
+
return content
|
|
155
|
+
.map((part) => {
|
|
156
|
+
if (part.type === "text")
|
|
157
|
+
return part.text;
|
|
158
|
+
if (part.type === "image")
|
|
159
|
+
return "[Image]";
|
|
160
|
+
if (part.type === "file")
|
|
161
|
+
return part.filename ? `[File: ${part.filename}]` : "[File]";
|
|
162
|
+
return "";
|
|
163
|
+
})
|
|
164
|
+
.filter(Boolean)
|
|
165
|
+
.join("\n")
|
|
166
|
+
.trim();
|
|
167
|
+
}
|
|
168
|
+
function renderAssistantContent(content, callMap) {
|
|
169
|
+
if (typeof content === "string")
|
|
170
|
+
return content.trim();
|
|
171
|
+
if (!Array.isArray(content))
|
|
172
|
+
return "";
|
|
173
|
+
const textParts = [];
|
|
174
|
+
for (const part of content) {
|
|
175
|
+
if (part.type === "text") {
|
|
176
|
+
textParts.push(part.text);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (part.type === "tool-call") {
|
|
180
|
+
callMap.set(part.toolCallId, {
|
|
181
|
+
id: part.toolCallId,
|
|
182
|
+
type: "function",
|
|
183
|
+
function: {
|
|
184
|
+
name: part.toolName,
|
|
185
|
+
arguments: JSON.stringify(part.input ?? {}),
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return textParts.join("").trim();
|
|
191
|
+
}
|
|
192
|
+
function loadStoredToolResults(sessionId) {
|
|
193
|
+
const rows = getDatabase()
|
|
194
|
+
.prepare(`
|
|
195
|
+
SELECT tc.tool_call_id, tr.output_json
|
|
196
|
+
FROM tool_results tr
|
|
197
|
+
JOIN tool_calls tc ON tc.id = tr.tool_call_row_id
|
|
198
|
+
WHERE tc.session_id = ?
|
|
199
|
+
ORDER BY tr.id ASC
|
|
200
|
+
`)
|
|
201
|
+
.all(sessionId);
|
|
202
|
+
return new Map(rows.map((row) => [row.tool_call_id, JSON.parse(row.output_json)]));
|
|
203
|
+
}
|
|
204
|
+
function toFallbackToolCall(toolCallId, toolName) {
|
|
205
|
+
return {
|
|
206
|
+
id: toolCallId,
|
|
207
|
+
type: "function",
|
|
208
|
+
function: {
|
|
209
|
+
name: toolName,
|
|
210
|
+
arguments: "{}",
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function extractToolResultFromOutput(output) {
|
|
215
|
+
if (!output || typeof output !== "object")
|
|
216
|
+
return null;
|
|
217
|
+
if ("success" in output) {
|
|
218
|
+
const result = output;
|
|
219
|
+
return {
|
|
220
|
+
success: Boolean(result.success),
|
|
221
|
+
output: result.output,
|
|
222
|
+
error: result.error,
|
|
223
|
+
diff: result.diff,
|
|
224
|
+
plan: result.plan,
|
|
225
|
+
task: result.task,
|
|
226
|
+
delegation: result.delegation,
|
|
227
|
+
backgroundProcess: result.backgroundProcess,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if ("type" in output && output.type === "json" && "value" in output) {
|
|
231
|
+
return extractToolResultFromOutput(output.value);
|
|
232
|
+
}
|
|
233
|
+
if ("type" in output && output.type === "error-text" && "value" in output) {
|
|
234
|
+
return {
|
|
235
|
+
success: false,
|
|
236
|
+
error: String(output.value),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if ("type" in output && output.type === "text" && "value" in output) {
|
|
240
|
+
return {
|
|
241
|
+
success: true,
|
|
242
|
+
output: String(output.value),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
function getOutputKind(output) {
|
|
248
|
+
if (output && typeof output === "object" && "type" in output && typeof output.type === "string") {
|
|
249
|
+
return output.type;
|
|
250
|
+
}
|
|
251
|
+
return "json";
|
|
252
|
+
}
|
|
253
|
+
function isOutputSuccess(output) {
|
|
254
|
+
if (!output || typeof output !== "object")
|
|
255
|
+
return true;
|
|
256
|
+
if ("type" in output) {
|
|
257
|
+
return !String(output.type).startsWith("error");
|
|
258
|
+
}
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=transcript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../src/storage/transcript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { UsageEvent, UsageSource } from "../types/index";
|
|
2
|
+
export interface TokenUsageLike {
|
|
3
|
+
inputTokens?: number;
|
|
4
|
+
outputTokens?: number;
|
|
5
|
+
totalTokens?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function recordUsageEvent(sessionId: string, source: UsageSource, model: string, usage?: TokenUsageLike, messageSeq?: number | null): void;
|
|
8
|
+
export declare function getSessionTotalTokens(sessionId: string): number;
|
|
9
|
+
export declare function listSessionUsage(sessionId: string): UsageEvent[];
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getModelInfo } from "../grok/models";
|
|
2
|
+
import { getDatabase } from "./db";
|
|
3
|
+
export function recordUsageEvent(sessionId, source, model, usage, messageSeq) {
|
|
4
|
+
if (!usage)
|
|
5
|
+
return;
|
|
6
|
+
const inputTokens = usage.inputTokens ?? 0;
|
|
7
|
+
const outputTokens = usage.outputTokens ?? 0;
|
|
8
|
+
const totalTokens = usage.totalTokens ?? inputTokens + outputTokens;
|
|
9
|
+
if (inputTokens <= 0 && outputTokens <= 0 && totalTokens <= 0)
|
|
10
|
+
return;
|
|
11
|
+
const costMicros = estimateCostMicros(model, inputTokens, outputTokens);
|
|
12
|
+
getDatabase()
|
|
13
|
+
.prepare(`
|
|
14
|
+
INSERT INTO usage_events (
|
|
15
|
+
session_id, message_seq, source, model, input_tokens, output_tokens, total_tokens, cost_micros, created_at
|
|
16
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
17
|
+
`)
|
|
18
|
+
.run(sessionId, messageSeq ?? null, source, model, inputTokens, outputTokens, totalTokens, costMicros, new Date().toISOString());
|
|
19
|
+
}
|
|
20
|
+
export function getSessionTotalTokens(sessionId) {
|
|
21
|
+
const row = getDatabase()
|
|
22
|
+
.prepare(`
|
|
23
|
+
SELECT COALESCE(SUM(total_tokens), 0) AS total_tokens
|
|
24
|
+
FROM usage_events
|
|
25
|
+
WHERE session_id = ?
|
|
26
|
+
`)
|
|
27
|
+
.get(sessionId);
|
|
28
|
+
return row?.total_tokens ?? 0;
|
|
29
|
+
}
|
|
30
|
+
export function listSessionUsage(sessionId) {
|
|
31
|
+
const rows = getDatabase()
|
|
32
|
+
.prepare(`
|
|
33
|
+
SELECT id, session_id, message_seq, source, model, input_tokens, output_tokens, total_tokens, cost_micros, created_at
|
|
34
|
+
FROM usage_events
|
|
35
|
+
WHERE session_id = ?
|
|
36
|
+
ORDER BY id ASC
|
|
37
|
+
`)
|
|
38
|
+
.all(sessionId);
|
|
39
|
+
return rows.map((row) => ({
|
|
40
|
+
id: row.id,
|
|
41
|
+
sessionId: row.session_id,
|
|
42
|
+
messageSeq: row.message_seq,
|
|
43
|
+
source: row.source,
|
|
44
|
+
model: row.model,
|
|
45
|
+
inputTokens: row.input_tokens,
|
|
46
|
+
outputTokens: row.output_tokens,
|
|
47
|
+
totalTokens: row.total_tokens,
|
|
48
|
+
costMicros: row.cost_micros,
|
|
49
|
+
createdAt: new Date(row.created_at),
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
function estimateCostMicros(model, inputTokens, outputTokens) {
|
|
53
|
+
const info = getModelInfo(model);
|
|
54
|
+
if (!info)
|
|
55
|
+
return 0;
|
|
56
|
+
return Math.round(inputTokens * info.inputPrice + outputTokens * info.outputPrice);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/storage/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAqBnC,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,MAAmB,EACnB,KAAa,EACb,KAAsB,EACtB,UAA0B;IAE1B,IAAI,CAAC,KAAK;QAAE,OAAO;IAEnB,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,WAAW,GAAG,YAAY,CAAC;IACpE,IAAI,WAAW,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO;IAEtE,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IACxE,WAAW,EAAE;SACV,OAAO,CAAC;;;;GAIV,CAAC;SACC,GAAG,CACF,SAAS,EACT,UAAU,IAAI,IAAI,EAClB,MAAM,EACN,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CACzB,CAAC;AACN,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,MAAM,GAAG,GAAG,WAAW,EAAE;SACtB,OAAO,CAAC;;;;GAIV,CAAC;SACC,GAAG,CAAC,SAAS,CAAyC,CAAC;IAE1D,OAAO,GAAG,EAAE,YAAY,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,IAAI,GAAG,WAAW,EAAE;SACvB,OAAO,CAAC;;;;;GAKV,CAAC;SACC,GAAG,CAAC,SAAS,CAAe,CAAC;IAEhC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,YAAY,EAAE,GAAG,CAAC,aAAa;QAC/B,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC;KACpC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,WAAmB,EAAE,YAAoB;IAClF,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,GAAG,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WorkspaceInfo } from "../types/index";
|
|
2
|
+
export interface ResolvedWorkspace {
|
|
3
|
+
scopeKey: string;
|
|
4
|
+
canonicalPath: string;
|
|
5
|
+
gitRoot: string | null;
|
|
6
|
+
displayName: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function ensureWorkspace(cwd: string): WorkspaceInfo;
|
|
9
|
+
export declare function resolveWorkspace(cwd: string): ResolvedWorkspace;
|