simmer-automaton 0.7.1 → 0.7.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.
Files changed (3) hide show
  1. package/dist/index.js +16 -32
  2. package/package.json +1 -1
  3. package/src/index.ts +17 -38
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ let currentTier = "normal";
20
20
  let cycleCount = 0;
21
21
  let lastUpdateCheckCycle = 0;
22
22
  const UPDATE_CHECK_INTERVAL = 50; // cycles between version checks
23
- const INSTALL_TIMEOUT_MS = 30_000; // 30s per skill install
23
+ let cachedSkillUpdates = [];
24
24
  let currentSelectedMeta = [];
25
25
  let lastExecutionResults = [];
26
26
  let cachedPortfolio = null;
@@ -196,6 +196,14 @@ function buildPromptContext() {
196
196
  }
197
197
  }
198
198
  }
199
+ // --- Outdated skills ---
200
+ if (cachedSkillUpdates.length > 0) {
201
+ lines.push("");
202
+ lines.push("**Skill updates available:**");
203
+ for (const u of cachedSkillUpdates) {
204
+ lines.push(`- ${u.slug}: ${u.current} → ${u.latest} — run \`clawhub install ${u.slug}\` to update`);
205
+ }
206
+ }
199
207
  // --- Tier warnings ---
200
208
  if (currentTier === "critical") {
201
209
  lines.push("");
@@ -240,7 +248,7 @@ function formatStatus() {
240
248
  return lines.join("\n");
241
249
  }
242
250
  // =============================================================================
243
- // Skill auto-updatekeep installed skills at latest ClawHub version
251
+ // Skill version detection surface outdated skills in prompt context
244
252
  // =============================================================================
245
253
  /**
246
254
  * Read installed skill versions from SKILL.md frontmatter.
@@ -265,30 +273,6 @@ function getLocalSkillVersions(workspaceDir) {
265
273
  }
266
274
  return versions;
267
275
  }
268
- /**
269
- * Check for outdated skills and auto-install updates.
270
- * Uses the skill_updates from the most recent briefing response.
271
- */
272
- async function checkAndUpdateSkills(skillUpdates, workspaceDir, logger) {
273
- if (!runtime || skillUpdates.length === 0)
274
- return;
275
- const cwd = workspaceDir || process.cwd();
276
- logger.info(`[simmer] ${skillUpdates.length} skill update(s) available: ${skillUpdates.map((u) => `${u.slug} ${u.current}→${u.latest}`).join(", ")}`);
277
- for (const update of skillUpdates) {
278
- try {
279
- const result = await runtime.system.runCommandWithTimeout(["npx", "clawhub@latest", "install", update.slug, "--force"], { timeoutMs: INSTALL_TIMEOUT_MS, cwd });
280
- if (result.code === 0) {
281
- logger.info(`[simmer] Updated ${update.slug} to ${update.latest}`);
282
- }
283
- else {
284
- logger.warn(`[simmer] Failed to update ${update.slug}: exit ${result.code} — ${result.stderr.slice(0, 200)}`);
285
- }
286
- }
287
- catch (e) {
288
- logger.warn(`[simmer] Failed to update ${update.slug}: ${e}`);
289
- }
290
- }
291
- }
292
276
  // =============================================================================
293
277
  // Skill execution — deterministic, no LLM in the loop
294
278
  // =============================================================================
@@ -425,13 +409,14 @@ export default function register(pluginApi) {
425
409
  catch (e) {
426
410
  ctx.logger.warn(`[simmer] Failed to restore bandit state: ${e}`);
427
411
  }
428
- // Check for skill updates on startup
412
+ // Check for skill updates on startup (notification only — surfaced in prompt context)
429
413
  try {
430
414
  const skillVersions = getLocalSkillVersions(ctx.workspaceDir);
431
415
  if (Object.keys(skillVersions).length > 0) {
432
416
  const briefing = await api.getBriefing(skillVersions);
433
417
  if (briefing.skill_updates && briefing.skill_updates.length > 0) {
434
- await checkAndUpdateSkills(briefing.skill_updates, ctx.workspaceDir, ctx.logger);
418
+ cachedSkillUpdates = briefing.skill_updates;
419
+ ctx.logger.info(`[simmer] ${briefing.skill_updates.length} skill update(s) available: ${briefing.skill_updates.map((u) => `${u.slug} ${u.current}→${u.latest}`).join(", ")}`);
435
420
  }
436
421
  }
437
422
  }
@@ -564,11 +549,10 @@ export default function register(pluginApi) {
564
549
  positions: attentionPositions,
565
550
  recentTradeCount: 0,
566
551
  };
567
- // Periodic skill auto-update
568
- if (briefing.skill_updates && briefing.skill_updates.length > 0 &&
569
- thisCycleNumber - lastUpdateCheckCycle >= UPDATE_CHECK_INTERVAL) {
552
+ // Cache skill update notifications (surfaced in prompt context)
553
+ if (thisCycleNumber - lastUpdateCheckCycle >= UPDATE_CHECK_INTERVAL) {
570
554
  lastUpdateCheckCycle = thisCycleNumber;
571
- await checkAndUpdateSkills(briefing.skill_updates, ctx.workspaceDir, ctx.logger);
555
+ cachedSkillUpdates = briefing.skill_updates || [];
572
556
  }
573
557
  }
574
558
  catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simmer-automaton",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Simmer Automaton plugin for OpenClaw — autonomous trading skill orchestration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -58,7 +58,7 @@ let currentTier: Tier = "normal";
58
58
  let cycleCount = 0;
59
59
  let lastUpdateCheckCycle = 0;
60
60
  const UPDATE_CHECK_INTERVAL = 50; // cycles between version checks
61
- const INSTALL_TIMEOUT_MS = 30_000; // 30s per skill install
61
+ let cachedSkillUpdates: Array<{ slug: string; current: string; latest: string; message: string }> = [];
62
62
  let currentSelectedMeta: Array<{ slug: string; reason: string; score: number | null }> = [];
63
63
  let lastExecutionResults: Array<{ slug: string; ok: boolean; detail: string }> = [];
64
64
  let cachedPortfolio: { totalPnl: number; positionCount: number; positions: BriefingPosition[]; recentTradeCount: number } | null = null;
@@ -238,6 +238,15 @@ function buildPromptContext(): string {
238
238
  }
239
239
  }
240
240
 
241
+ // --- Outdated skills ---
242
+ if (cachedSkillUpdates.length > 0) {
243
+ lines.push("");
244
+ lines.push("**Skill updates available:**");
245
+ for (const u of cachedSkillUpdates) {
246
+ lines.push(`- ${u.slug}: ${u.current} → ${u.latest} — run \`clawhub install ${u.slug}\` to update`);
247
+ }
248
+ }
249
+
241
250
  // --- Tier warnings ---
242
251
  if (currentTier === "critical") {
243
252
  lines.push("");
@@ -289,7 +298,7 @@ function formatStatus(): string {
289
298
  }
290
299
 
291
300
  // =============================================================================
292
- // Skill auto-updatekeep installed skills at latest ClawHub version
301
+ // Skill version detection surface outdated skills in prompt context
293
302
  // =============================================================================
294
303
 
295
304
  /**
@@ -315,36 +324,6 @@ function getLocalSkillVersions(workspaceDir: string | undefined): Record<string,
315
324
  return versions;
316
325
  }
317
326
 
318
- /**
319
- * Check for outdated skills and auto-install updates.
320
- * Uses the skill_updates from the most recent briefing response.
321
- */
322
- async function checkAndUpdateSkills(
323
- skillUpdates: Array<{ slug: string; current: string; latest: string; message: string }>,
324
- workspaceDir: string | undefined,
325
- logger: { info: (m: string) => void; warn: (m: string) => void; error: (m: string) => void },
326
- ): Promise<void> {
327
- if (!runtime || skillUpdates.length === 0) return;
328
-
329
- const cwd = workspaceDir || process.cwd();
330
- logger.info(`[simmer] ${skillUpdates.length} skill update(s) available: ${skillUpdates.map((u) => `${u.slug} ${u.current}→${u.latest}`).join(", ")}`);
331
-
332
- for (const update of skillUpdates) {
333
- try {
334
- const result = await runtime.system.runCommandWithTimeout(
335
- ["npx", "clawhub@latest", "install", update.slug, "--force"],
336
- { timeoutMs: INSTALL_TIMEOUT_MS, cwd },
337
- );
338
- if (result.code === 0) {
339
- logger.info(`[simmer] Updated ${update.slug} to ${update.latest}`);
340
- } else {
341
- logger.warn(`[simmer] Failed to update ${update.slug}: exit ${result.code} — ${result.stderr.slice(0, 200)}`);
342
- }
343
- } catch (e) {
344
- logger.warn(`[simmer] Failed to update ${update.slug}: ${e}`);
345
- }
346
- }
347
- }
348
327
 
349
328
  // =============================================================================
350
329
  // Skill execution — deterministic, no LLM in the loop
@@ -502,13 +481,14 @@ export default function register(pluginApi: PluginApi) {
502
481
  ctx.logger.warn(`[simmer] Failed to restore bandit state: ${e}`);
503
482
  }
504
483
 
505
- // Check for skill updates on startup
484
+ // Check for skill updates on startup (notification only — surfaced in prompt context)
506
485
  try {
507
486
  const skillVersions = getLocalSkillVersions(ctx.workspaceDir);
508
487
  if (Object.keys(skillVersions).length > 0) {
509
488
  const briefing = await api.getBriefing(skillVersions);
510
489
  if (briefing.skill_updates && briefing.skill_updates.length > 0) {
511
- await checkAndUpdateSkills(briefing.skill_updates, ctx.workspaceDir, ctx.logger);
490
+ cachedSkillUpdates = briefing.skill_updates;
491
+ ctx.logger.info(`[simmer] ${briefing.skill_updates.length} skill update(s) available: ${briefing.skill_updates.map((u) => `${u.slug} ${u.current}→${u.latest}`).join(", ")}`);
512
492
  }
513
493
  }
514
494
  } catch (e) {
@@ -650,11 +630,10 @@ export default function register(pluginApi: PluginApi) {
650
630
  recentTradeCount: 0,
651
631
  };
652
632
 
653
- // Periodic skill auto-update
654
- if (briefing.skill_updates && briefing.skill_updates.length > 0 &&
655
- thisCycleNumber - lastUpdateCheckCycle >= UPDATE_CHECK_INTERVAL) {
633
+ // Cache skill update notifications (surfaced in prompt context)
634
+ if (thisCycleNumber - lastUpdateCheckCycle >= UPDATE_CHECK_INTERVAL) {
656
635
  lastUpdateCheckCycle = thisCycleNumber;
657
- await checkAndUpdateSkills(briefing.skill_updates, ctx.workspaceDir, ctx.logger);
636
+ cachedSkillUpdates = briefing.skill_updates || [];
658
637
  }
659
638
  } catch (e) {
660
639
  ctx.logger.warn(`[simmer] Failed to fetch briefing: ${e}`);