@parall/parall 1.12.0 → 1.13.1
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/package.json +4 -3
- package/src/fork.ts +5 -28
- package/src/gateway.ts +210 -1098
- package/src/hooks.ts +6 -26
- package/src/routing.ts +8 -48
- package/src/runtime.ts +30 -101
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parall/parall",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.1",
|
|
4
4
|
"description": "OpenClaw channel plugin for Parall IM",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
"openclaw.plugin.json"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@parall/
|
|
19
|
-
"@parall/cli": "1.
|
|
18
|
+
"@parall/agent-core": "1.13.1",
|
|
19
|
+
"@parall/cli": "1.13.1",
|
|
20
|
+
"@parall/sdk": "1.13.1"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"@types/node": "^22.0.0",
|
package/src/fork.ts
CHANGED
|
@@ -17,20 +17,12 @@ export type ForkSessionResult = {
|
|
|
17
17
|
sessionFile: string;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// Session store helpers — read sessions.json directly (SSOT for file paths)
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
|
|
24
20
|
type SessionStoreEntry = {
|
|
25
21
|
sessionId?: string;
|
|
26
22
|
sessionFile?: string;
|
|
27
23
|
[key: string]: unknown;
|
|
28
24
|
};
|
|
29
25
|
|
|
30
|
-
/**
|
|
31
|
-
* Read sessions.json and find the entry for a given session key.
|
|
32
|
-
* OpenClaw may store keys in lowercase; we try both.
|
|
33
|
-
*/
|
|
34
26
|
function readStoreEntry(sessionsDir: string, sessionKey: string): SessionStoreEntry | null {
|
|
35
27
|
const storeFile = path.join(sessionsDir, "sessions.json");
|
|
36
28
|
try {
|
|
@@ -41,16 +33,15 @@ function readStoreEntry(sessionsDir: string, sessionKey: string): SessionStoreEn
|
|
|
41
33
|
}
|
|
42
34
|
}
|
|
43
35
|
|
|
44
|
-
/**
|
|
45
|
-
* Write or update an entry in sessions.json.
|
|
46
|
-
*/
|
|
47
36
|
function writeStoreEntry(sessionsDir: string, sessionKey: string, entry: SessionStoreEntry): boolean {
|
|
48
37
|
const storeFile = path.join(sessionsDir, "sessions.json");
|
|
49
38
|
try {
|
|
50
39
|
let store: Record<string, SessionStoreEntry> = {};
|
|
51
40
|
try {
|
|
52
41
|
store = JSON.parse(fs.readFileSync(storeFile, "utf-8"));
|
|
53
|
-
} catch {
|
|
42
|
+
} catch {
|
|
43
|
+
// Empty or missing — start fresh.
|
|
44
|
+
}
|
|
54
45
|
store[sessionKey.toLowerCase()] = entry;
|
|
55
46
|
fs.writeFileSync(storeFile, JSON.stringify(store, null, 2), { encoding: "utf-8" });
|
|
56
47
|
return true;
|
|
@@ -59,9 +50,6 @@ function writeStoreEntry(sessionsDir: string, sessionKey: string, entry: Session
|
|
|
59
50
|
}
|
|
60
51
|
}
|
|
61
52
|
|
|
62
|
-
/**
|
|
63
|
-
* Delete an entry from sessions.json.
|
|
64
|
-
*/
|
|
65
53
|
function deleteStoreEntry(sessionsDir: string, sessionKey: string): void {
|
|
66
54
|
const storeFile = path.join(sessionsDir, "sessions.json");
|
|
67
55
|
try {
|
|
@@ -70,23 +58,14 @@ function deleteStoreEntry(sessionsDir: string, sessionKey: string): void {
|
|
|
70
58
|
delete store[sessionKey.toLowerCase()];
|
|
71
59
|
fs.writeFileSync(storeFile, JSON.stringify(store, null, 2), { encoding: "utf-8" });
|
|
72
60
|
} catch {
|
|
73
|
-
// Best-effort
|
|
61
|
+
// Best-effort cleanup.
|
|
74
62
|
}
|
|
75
63
|
}
|
|
76
64
|
|
|
77
|
-
// ---------------------------------------------------------------------------
|
|
78
|
-
// Transcript file resolution (via session store)
|
|
79
|
-
// ---------------------------------------------------------------------------
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Resolve the transcript file for a session key by reading the session store.
|
|
83
|
-
* Returns the absolute path, or null if not found.
|
|
84
|
-
*/
|
|
85
65
|
export function resolveTranscriptFile(sessionsDir: string, sessionKey: string): string | null {
|
|
86
66
|
const entry = readStoreEntry(sessionsDir, sessionKey);
|
|
87
67
|
if (!entry?.sessionId) return null;
|
|
88
68
|
|
|
89
|
-
// Prefer explicit sessionFile field
|
|
90
69
|
if (entry.sessionFile) {
|
|
91
70
|
const resolved = path.isAbsolute(entry.sessionFile)
|
|
92
71
|
? entry.sessionFile
|
|
@@ -94,14 +73,12 @@ export function resolveTranscriptFile(sessionsDir: string, sessionKey: string):
|
|
|
94
73
|
if (fs.existsSync(resolved)) return resolved;
|
|
95
74
|
}
|
|
96
75
|
|
|
97
|
-
// Fallback: conventional {sessionId}.jsonl
|
|
98
76
|
const conventional = path.join(sessionsDir, `${entry.sessionId}.jsonl`);
|
|
99
77
|
if (fs.existsSync(conventional)) return conventional;
|
|
100
78
|
|
|
101
|
-
// Last resort: scan for files containing the sessionId
|
|
102
79
|
try {
|
|
103
80
|
const files = fs.readdirSync(sessionsDir);
|
|
104
|
-
const match = files.find((
|
|
81
|
+
const match = files.find((file) => file.includes(entry.sessionId!) && file.endsWith(".jsonl"));
|
|
105
82
|
return match ? path.join(sessionsDir, match) : null;
|
|
106
83
|
} catch {
|
|
107
84
|
return null;
|