ocsmarttools 0.1.3 → 0.1.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to `ocsmarttools` are documented here.
4
4
 
5
+ ## [0.1.4] - 2026-02-22
6
+
7
+ ### Changed
8
+ - Broadened peer compatibility range to `openclaw >=2026.2.19` for easier installs across existing instances.
9
+
10
+ ### Fixed
11
+ - Routing policy sync is now fail-safe on restricted/read-only environments (never breaks plugin startup).
12
+ - Setup/config flows now return clear messages when routing sync is skipped due to filesystem permissions/path issues.
13
+
5
14
  ## [0.1.3] - 2026-02-22
6
15
 
7
16
  ### Added
package/README.md CHANGED
@@ -23,6 +23,10 @@ flowchart LR
23
23
 
24
24
  ## Install
25
25
 
26
+ Compatibility:
27
+ - OpenClaw: `>=2026.2.19`
28
+ - Works with existing installed instances (no core patch required)
29
+
26
30
  ### npm
27
31
 
28
32
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocsmarttools",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Provider-agnostic advanced tool orchestration plugin for OpenClaw with search, dispatch, and batching",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -24,7 +24,7 @@
24
24
  ],
25
25
  "license": "MIT",
26
26
  "peerDependencies": {
27
- "openclaw": ">=2026.2.21"
27
+ "openclaw": ">=2026.2.19"
28
28
  },
29
29
  "devDependencies": {
30
30
  "typescript": "^5.8.0",
@@ -280,7 +280,10 @@ export async function setConfigKey(
280
280
  await writeConfig(api, next);
281
281
 
282
282
  if (key === "autoInjectRoutingGuide" && parsed.value === true) {
283
- await syncRoutingGuide(api, next);
283
+ const sync = await syncRoutingGuide(api, next);
284
+ if (sync.error) {
285
+ return `Config updated: ${key}=${JSON.stringify(parsed.value)} (routing sync skipped: ${sync.error}).`;
286
+ }
284
287
  }
285
288
 
286
289
  return `Config updated: ${key}=${JSON.stringify(parsed.value)}.`;
@@ -299,7 +302,10 @@ export async function resetConfig(api: OpenClawPluginApi, key?: string): Promise
299
302
  }
300
303
  await writeConfig(api, next);
301
304
  if (DEFAULT_SETTINGS.autoInjectRoutingGuide) {
302
- await syncRoutingGuide(api, next);
305
+ const sync = await syncRoutingGuide(api, next);
306
+ if (sync.error) {
307
+ return `Config reset to plugin defaults (routing sync skipped: ${sync.error}).`;
308
+ }
303
309
  }
304
310
  return "Config reset to plugin defaults.";
305
311
  }
@@ -311,7 +317,10 @@ export async function resetConfig(api: OpenClawPluginApi, key?: string): Promise
311
317
  setValueAtPath(pluginCfg, key, DEFAULT_BY_KEY[key]);
312
318
  await writeConfig(api, next);
313
319
  if (key === "autoInjectRoutingGuide" && DEFAULT_BY_KEY[key] === true) {
314
- await syncRoutingGuide(api, next);
320
+ const sync = await syncRoutingGuide(api, next);
321
+ if (sync.error) {
322
+ return `Config key reset: ${key}=${JSON.stringify(DEFAULT_BY_KEY[key])} (routing sync skipped: ${sync.error}).`;
323
+ }
315
324
  }
316
325
  return `Config key reset: ${key}=${JSON.stringify(DEFAULT_BY_KEY[key])}.`;
317
326
  }
@@ -361,12 +370,16 @@ export async function applySetup(api: OpenClawPluginApi, mode: AdvToolsMode): Pr
361
370
  );
362
371
 
363
372
  await writeConfig(api, next);
364
- await syncRoutingGuide(api, next);
373
+ const sync = await syncRoutingGuide(api, next);
374
+ const syncLine = sync.error
375
+ ? `- routing guide sync skipped: ${sync.error}`
376
+ : `- routing guide ${sync.changed ? "synced" : "already up to date"} (${sync.filePath ?? "AGENTS.md"})`;
365
377
 
366
378
  return [
367
379
  "OCSmartTools setup applied.",
368
380
  `- mode: ${mode}`,
369
381
  "- autoInjectRoutingGuide: true",
382
+ syncLine,
370
383
  `- ensured tools.allow includes: ${ADVTOOLS_TOOL_NAMES.join(", ")}`,
371
384
  "- config written via runtime config writer",
372
385
  "If your gateway does not hot-apply this change, run: openclaw gateway restart",
@@ -395,6 +408,9 @@ export async function syncManagedRouting(api: OpenClawPluginApi): Promise<string
395
408
  return "Routing guide sync skipped: autoInjectRoutingGuide=false.";
396
409
  }
397
410
  const result = await syncRoutingGuide(api, loaded);
411
+ if (result.error) {
412
+ return `Routing guide sync skipped: ${result.error}`;
413
+ }
398
414
  if (!result.changed) {
399
415
  return `Routing guide already up to date (${result.filePath ?? "AGENTS.md"}).`;
400
416
  }
@@ -119,7 +119,9 @@ export async function autoBootstrap(api: OpenClawPluginApi): Promise<{ changed:
119
119
  : DEFAULT_SETTINGS.autoInjectRoutingGuide;
120
120
  if (routingGuideEnabled) {
121
121
  const sync = await syncRoutingGuide(api, next);
122
- if (sync.changed) {
122
+ if (sync.error) {
123
+ notes.push(`routing guide skipped: ${sync.error}`);
124
+ } else if (sync.changed) {
123
125
  notes.push(`synced routing guide (${sync.filePath ?? "AGENTS.md"})`);
124
126
  }
125
127
  }
@@ -60,6 +60,7 @@ function upsertRoutingBlock(raw: string): string {
60
60
  export async function syncRoutingGuide(api: OpenClawPluginApi, cfg: OpenClawConfig): Promise<{
61
61
  changed: boolean;
62
62
  filePath?: string;
63
+ error?: string;
63
64
  }> {
64
65
  const workspaceDir = resolveWorkspaceDir(cfg);
65
66
  const filePath = path.join(workspaceDir, "AGENTS.md");
@@ -68,7 +69,11 @@ export async function syncRoutingGuide(api: OpenClawPluginApi, cfg: OpenClawConf
68
69
  current = await fs.readFile(filePath, "utf8");
69
70
  } catch (error) {
70
71
  if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
71
- throw error;
72
+ return {
73
+ changed: false,
74
+ filePath,
75
+ error: `read failed: ${error instanceof Error ? error.message : String(error)}`,
76
+ };
72
77
  }
73
78
  }
74
79
 
@@ -77,8 +82,16 @@ export async function syncRoutingGuide(api: OpenClawPluginApi, cfg: OpenClawConf
77
82
  return { changed: false, filePath };
78
83
  }
79
84
 
80
- await fs.mkdir(workspaceDir, { recursive: true });
81
- await fs.writeFile(filePath, next, "utf8");
85
+ try {
86
+ await fs.mkdir(workspaceDir, { recursive: true });
87
+ await fs.writeFile(filePath, next, "utf8");
88
+ } catch (error) {
89
+ return {
90
+ changed: false,
91
+ filePath,
92
+ error: `write failed: ${error instanceof Error ? error.message : String(error)}`,
93
+ };
94
+ }
82
95
  api.logger.info(`[ocsmarttools] routing policy synced: ${filePath}`);
83
96
  return { changed: true, filePath };
84
97
  }