@1agents/session-reader 0.6.2 → 0.7.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.
- package/README.md +12 -0
- package/cordis.patch.yml +4 -0
- package/dist/bin/1session.js +26 -1
- package/dist/src/dsh/adapter.d.ts +18 -0
- package/dist/src/dsh/adapter.js +198 -0
- package/dist/src/dsh/client.d.ts +2 -0
- package/dist/src/dsh/client.js +18997 -0
- package/dist/src/dsh/index.d.ts +2 -0
- package/dist/src/dsh/index.js +2 -0
- package/dist/src/dsh/plugin.d.ts +3 -0
- package/dist/src/dsh/plugin.js +392 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/resolver.d.ts +7 -0
- package/dist/src/resolver.js +13 -8
- package/dist/src/store/read.d.ts +6 -2
- package/dist/src/store/read.js +14 -12
- package/dist/src/web/api.d.ts +72 -0
- package/dist/src/web/api.js +126 -0
- package/dist/src/web/app.d.ts +1 -0
- package/dist/src/web/app.js +18975 -0
- package/dist/src/web/server.d.ts +20 -0
- package/dist/src/web/server.js +126 -0
- package/package.json +25 -4
- package/skills/1session/SKILL.md +2 -1
- package/skills/1session/references/cli.md +16 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { buildOverview, displayPath, fileLedger, listRecentSessions, loadSession, searchSessions, summarizeTurns, } from '../index.js';
|
|
2
|
+
export function resolveListWorkspace(scope, workspace, fallbackCwd) {
|
|
3
|
+
if (scope === 'global')
|
|
4
|
+
return undefined;
|
|
5
|
+
if (workspace)
|
|
6
|
+
return workspace;
|
|
7
|
+
if (scope && scope !== 'cwd')
|
|
8
|
+
return scope;
|
|
9
|
+
return fallbackCwd;
|
|
10
|
+
}
|
|
11
|
+
/** Chat-preview turns. Built only after the user clicks a session. */
|
|
12
|
+
export function previewTurns(normalized) {
|
|
13
|
+
return summarizeTurns(normalized).map((ts) => {
|
|
14
|
+
const evs = (normalized.turns || []).slice(ts.events[0], ts.events[1] + 1);
|
|
15
|
+
const thinkingEvents = evs.filter((e) => e.kind === 'thinking');
|
|
16
|
+
const assistantEvents = evs.filter((e) => e.kind === 'assistant');
|
|
17
|
+
const toolCalls = [];
|
|
18
|
+
for (let i = 0; i < evs.length; i++) {
|
|
19
|
+
const e = evs[i];
|
|
20
|
+
if (e.kind === 'tool_call') {
|
|
21
|
+
const result = evs.slice(i + 1).find((r) => r.kind === 'tool_result' && (r.toolName === e.toolName || !r.toolName));
|
|
22
|
+
toolCalls.push({
|
|
23
|
+
id: e.id,
|
|
24
|
+
toolName: e.toolName,
|
|
25
|
+
args: e.toolArgs,
|
|
26
|
+
result: result?.toolResult,
|
|
27
|
+
exitCode: result?.exitCode,
|
|
28
|
+
isError: result?.isError,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
no: ts.no,
|
|
34
|
+
turn: ts.no,
|
|
35
|
+
status: ts.status,
|
|
36
|
+
prompt: ts.prompt,
|
|
37
|
+
userPrompt: ts.prompt,
|
|
38
|
+
outcome: ts.outcome,
|
|
39
|
+
assistantReply: assistantEvents.map((a) => a.text).filter(Boolean).join('\n\n') || ts.outcome,
|
|
40
|
+
thinking: thinkingEvents.map((t) => t.text).filter(Boolean).join('\n\n'),
|
|
41
|
+
thinkingBlocks: thinkingEvents.map((t) => t.text).filter(Boolean),
|
|
42
|
+
toolCalls,
|
|
43
|
+
files: ts.files,
|
|
44
|
+
commands: ts.commands,
|
|
45
|
+
errors: ts.errors,
|
|
46
|
+
startedAt: ts.startedAt,
|
|
47
|
+
endedAt: ts.endedAt,
|
|
48
|
+
durationMs: ts.durationMs,
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export async function sessionPreview(sessionId) {
|
|
53
|
+
const normalized = await loadSession(sessionId, { useIndex: true });
|
|
54
|
+
const workspace = normalized.ref.workspace;
|
|
55
|
+
return {
|
|
56
|
+
ref: normalized.ref,
|
|
57
|
+
stats: normalized.stats,
|
|
58
|
+
overview: buildOverview(normalized),
|
|
59
|
+
turns: previewTurns(normalized),
|
|
60
|
+
files: fileLedger(normalized).map((record) => ({
|
|
61
|
+
...record,
|
|
62
|
+
displayPath: displayPath(record, workspace),
|
|
63
|
+
})),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export async function listSessionsForUi(options) {
|
|
67
|
+
const limit = options.limit ?? 50;
|
|
68
|
+
return listRecentSessions({
|
|
69
|
+
limit,
|
|
70
|
+
provider: options.provider,
|
|
71
|
+
since: options.since,
|
|
72
|
+
workspace: options.workspace,
|
|
73
|
+
useIndex: false,
|
|
74
|
+
scan: Math.min(Math.max(limit * 4, 80), 200),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function sendJson(res, status, body) {
|
|
78
|
+
const payload = JSON.stringify(body);
|
|
79
|
+
res.statusCode = status;
|
|
80
|
+
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
81
|
+
res.end(payload);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Shared JSON API used by the DSH plugin and `1session web`.
|
|
85
|
+
* Path is already stripped of `/api/session-reader`. Returns false if unmatched.
|
|
86
|
+
*/
|
|
87
|
+
export async function handleSessionApi(pathname, url, res, options) {
|
|
88
|
+
if (pathname === '/sessions' || pathname === '' || pathname === '/') {
|
|
89
|
+
const limit = url.searchParams.get('limit') ? Number(url.searchParams.get('limit')) : 50;
|
|
90
|
+
const scope = url.searchParams.get('scope');
|
|
91
|
+
const provider = url.searchParams.get('provider') || undefined;
|
|
92
|
+
const since = url.searchParams.get('since') ?? undefined;
|
|
93
|
+
const workspace = resolveListWorkspace(scope, url.searchParams.get('workspace'), options.fallbackCwd);
|
|
94
|
+
const sessions = await listSessionsForUi({ limit, provider, since, workspace });
|
|
95
|
+
sendJson(res, 200, { sessions });
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
if (pathname === '/search') {
|
|
99
|
+
const query = url.searchParams.get('q') ?? '';
|
|
100
|
+
const scope = url.searchParams.get('scope');
|
|
101
|
+
const since = url.searchParams.get('since') ?? undefined;
|
|
102
|
+
const provider = url.searchParams.get('provider') ?? undefined;
|
|
103
|
+
const limit = url.searchParams.get('limit') ? Number(url.searchParams.get('limit')) : 20;
|
|
104
|
+
const workspace = resolveListWorkspace(scope, url.searchParams.get('workspace'), options.fallbackCwd);
|
|
105
|
+
const hits = await searchSessions(query, { workspace, since, provider, limit });
|
|
106
|
+
sendJson(res, 200, { hits });
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
const matchSession = pathname.match(/^\/session\/([^/]+)$/);
|
|
110
|
+
if (matchSession) {
|
|
111
|
+
const sessionId = decodeURIComponent(matchSession[1]);
|
|
112
|
+
try {
|
|
113
|
+
sendJson(res, 200, await sessionPreview(sessionId));
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
117
|
+
if (/session not found/i.test(msg)) {
|
|
118
|
+
sendJson(res, 404, { error: `Session not found: ${sessionId}` });
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
throw err;
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|