jfl 0.2.0 → 0.2.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/clawdbot-skill/index.ts +40 -13
- package/package.json +1 -1
package/clawdbot-skill/index.ts
CHANGED
|
@@ -75,19 +75,40 @@ function setState(threadId: string, s: SessionState) {
|
|
|
75
75
|
// OpenClaw helpers
|
|
76
76
|
// ============================================================================
|
|
77
77
|
|
|
78
|
-
async function openclaw(cmd: string): Promise<string> {
|
|
78
|
+
async function openclaw(cmd: string, cwd?: string): Promise<string> {
|
|
79
79
|
const { stdout } = await execAsync(`jfl openclaw ${cmd}`, {
|
|
80
80
|
timeout: 30000,
|
|
81
81
|
env: { ...process.env },
|
|
82
|
+
cwd,
|
|
82
83
|
})
|
|
83
84
|
return stdout.trim()
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
async function openclawJSON(cmd: string): Promise<any> {
|
|
87
|
-
const raw = await openclaw(`${cmd} --json
|
|
87
|
+
async function openclawJSON(cmd: string, cwd?: string): Promise<any> {
|
|
88
|
+
const raw = await openclaw(`${cmd} --json`, cwd)
|
|
88
89
|
return JSON.parse(raw)
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
async function ensureContextHub(gtmPath: string): Promise<boolean> {
|
|
93
|
+
try {
|
|
94
|
+
// Check if hub is healthy
|
|
95
|
+
const status = await openclawJSON("status", gtmPath)
|
|
96
|
+
if (status.context_hub?.healthy) return true
|
|
97
|
+
} catch { /* hub not running */ }
|
|
98
|
+
|
|
99
|
+
// Start hub from within GTM directory
|
|
100
|
+
try {
|
|
101
|
+
await execAsync("jfl context-hub start", {
|
|
102
|
+
cwd: gtmPath,
|
|
103
|
+
timeout: 15000,
|
|
104
|
+
env: { ...process.env },
|
|
105
|
+
})
|
|
106
|
+
return true
|
|
107
|
+
} catch {
|
|
108
|
+
return false
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
91
112
|
async function ensureJFL(): Promise<boolean> {
|
|
92
113
|
try {
|
|
93
114
|
await execAsync("jfl --version", { timeout: 5000 })
|
|
@@ -200,10 +221,13 @@ async function activateGTM(gtmPath: string, ctx: Context) {
|
|
|
200
221
|
|
|
201
222
|
try {
|
|
202
223
|
// Register agent with GTM (idempotent)
|
|
203
|
-
await openclawJSON(`register -g "${gtmPath}" -a ${agent}
|
|
224
|
+
await openclawJSON(`register -g "${gtmPath}" -a ${agent}`, gtmPath)
|
|
225
|
+
|
|
226
|
+
// Ensure context hub is running from the GTM directory
|
|
227
|
+
await ensureContextHub(gtmPath)
|
|
204
228
|
|
|
205
229
|
// Start session
|
|
206
|
-
const session = await openclawJSON(`session-start -a ${agent} -g "${gtmPath}"
|
|
230
|
+
const session = await openclawJSON(`session-start -a ${agent} -g "${gtmPath}"`, gtmPath)
|
|
207
231
|
|
|
208
232
|
setState(ctx.threadId, {
|
|
209
233
|
gtmPath,
|
|
@@ -522,8 +546,11 @@ export async function onSessionStart(event: { agentId: string; platform: string;
|
|
|
522
546
|
const agent = existing.agentId || event.agentId || `clawd-${event.platform}`
|
|
523
547
|
|
|
524
548
|
try {
|
|
549
|
+
// Ensure context hub is running from the GTM directory
|
|
550
|
+
await ensureContextHub(existing.gtmPath)
|
|
551
|
+
|
|
525
552
|
// Try to resume or start a new session
|
|
526
|
-
const session = await openclawJSON(`session-start -a ${agent} -g "${existing.gtmPath}"
|
|
553
|
+
const session = await openclawJSON(`session-start -a ${agent} -g "${existing.gtmPath}"`, existing.gtmPath)
|
|
527
554
|
setState(event.threadId, { ...existing, sessionBranch: session.session_id })
|
|
528
555
|
|
|
529
556
|
return {
|
|
@@ -564,13 +591,13 @@ export async function onSessionStart(event: { agentId: string; platform: string;
|
|
|
564
591
|
*/
|
|
565
592
|
export async function onBeforeTurn(event: { agentId: string; threadId: string; message?: string }) {
|
|
566
593
|
const s = getState(event.threadId)
|
|
567
|
-
if (!s?.activated || !s?.sessionBranch) return { prependContext: "" }
|
|
594
|
+
if (!s?.activated || !s?.sessionBranch || !s?.gtmPath) return { prependContext: "" }
|
|
568
595
|
|
|
569
596
|
let contextBlock = ""
|
|
570
597
|
try {
|
|
571
598
|
const query = event.message?.slice(0, 100) || ""
|
|
572
599
|
if (query.length > 10) {
|
|
573
|
-
const items = await openclawJSON(`context -q "${query.replace(/"/g, '\\"')}"
|
|
600
|
+
const items = await openclawJSON(`context -q "${query.replace(/"/g, '\\"')}"`, s.gtmPath)
|
|
574
601
|
if (Array.isArray(items) && items.length > 0) {
|
|
575
602
|
const relevant = items.slice(0, 3).map((i: any) =>
|
|
576
603
|
`- [${i.type}] ${i.title}: ${(i.content || "").slice(0, 150)}`
|
|
@@ -594,11 +621,11 @@ export async function onAfterTurn(event: {
|
|
|
594
621
|
detectedIntent?: string
|
|
595
622
|
}) {
|
|
596
623
|
const s = getState(event.threadId)
|
|
597
|
-
if (!s?.activated || !s?.sessionBranch) return
|
|
624
|
+
if (!s?.activated || !s?.sessionBranch || !s?.gtmPath) return
|
|
598
625
|
|
|
599
626
|
// Heartbeat (auto-commit)
|
|
600
627
|
try {
|
|
601
|
-
await openclaw("heartbeat --json")
|
|
628
|
+
await openclaw("heartbeat --json", s.gtmPath)
|
|
602
629
|
} catch { /* non-fatal */ }
|
|
603
630
|
|
|
604
631
|
// Auto-capture decisions/completions
|
|
@@ -613,7 +640,7 @@ export async function onAfterTurn(event: {
|
|
|
613
640
|
if (type) {
|
|
614
641
|
const title = event.response.slice(0, 80).replace(/\n/g, " ")
|
|
615
642
|
try {
|
|
616
|
-
await openclaw(`journal --type ${type} --title "${title.replace(/"/g, '\\"')}" --summary "${title.replace(/"/g, '\\"')}"
|
|
643
|
+
await openclaw(`journal --type ${type} --title "${title.replace(/"/g, '\\"')}" --summary "${title.replace(/"/g, '\\"')}"`, s.gtmPath)
|
|
617
644
|
} catch { /* non-fatal */ }
|
|
618
645
|
}
|
|
619
646
|
}
|
|
@@ -625,10 +652,10 @@ export async function onAfterTurn(event: {
|
|
|
625
652
|
*/
|
|
626
653
|
export async function onSessionEnd(event: { agentId: string; threadId: string }) {
|
|
627
654
|
const s = getState(event.threadId)
|
|
628
|
-
if (!s?.activated || !s?.sessionBranch) return
|
|
655
|
+
if (!s?.activated || !s?.sessionBranch || !s?.gtmPath) return
|
|
629
656
|
|
|
630
657
|
try {
|
|
631
|
-
await openclawJSON("session-end --sync")
|
|
658
|
+
await openclawJSON("session-end --sync", s.gtmPath)
|
|
632
659
|
} catch { /* never block shutdown */ }
|
|
633
660
|
|
|
634
661
|
// Keep activated state but clear session
|