opensyn 0.1.0 → 0.1.3

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 CHANGED
@@ -18,6 +18,7 @@ Default workspace behavior:
18
18
  - `openclaw enable_opensyn` uses the current OpenClaw workspace if no project path is provided
19
19
  - `openclaw enable_opensyn` also bootstraps the managed shell hook, starts the plugin-managed background `watch-linux` collector, and starts the plugin-managed host-model distillation worker
20
20
  - `openclaw status_opensyn` returns a compact `next=...` hint so the customer can see the next required action immediately
21
+ - add `--json` only when full diagnostics are needed
21
22
 
22
23
  Fallback local-dev install:
23
24
 
package/README.zh-CN.md CHANGED
@@ -18,6 +18,7 @@ openclaw status_opensyn
18
18
  - `openclaw enable_opensyn` 如果不传项目路径,会直接使用当前 OpenClaw workspace
19
19
  - `openclaw enable_opensyn` 还会完成托管 shell hook 自举,并拉起插件托管的后台 `watch-linux` 采集器和 host-model distillation worker
20
20
  - `openclaw status_opensyn` 会直接返回统一的 `next=...` 提示,让客户马上知道下一步动作
21
+ - 只有在排障时才需要追加 `--json` 查看完整诊断信息
21
22
 
22
23
  本地开发联调安装:
23
24
 
package/index.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  openSync,
10
10
  readFileSync,
11
11
  readdirSync,
12
+ renameSync,
12
13
  realpathSync,
13
14
  rmSync,
14
15
  statSync,
@@ -456,6 +457,23 @@ function defaultProjectionBundleRoot(): string {
456
457
  return path.join(home, ".openclaw", "workspace");
457
458
  }
458
459
 
460
+ function syncRuntimeFile(sourcePath: string, destPath: string): void {
461
+ const sourceStat = statSync(sourcePath);
462
+ const needsCopy =
463
+ !existsSync(destPath) ||
464
+ statSync(destPath).size !== sourceStat.size ||
465
+ statSync(destPath).mtimeMs < sourceStat.mtimeMs;
466
+ if (!needsCopy) {
467
+ return;
468
+ }
469
+
470
+ mkdirSync(path.dirname(destPath), { recursive: true });
471
+ const tempPath = `${destPath}.tmp-${process.pid}-${Date.now()}`;
472
+ copyFileSync(sourcePath, tempPath);
473
+ chmodSync(tempPath, sourceStat.mode);
474
+ renameSync(tempPath, destPath);
475
+ }
476
+
459
477
  function syncRuntimeTree(sourceDir: string, destDir: string): void {
460
478
  if (!existsSync(sourceDir)) {
461
479
  return;
@@ -469,17 +487,7 @@ function syncRuntimeTree(sourceDir: string, destDir: string): void {
469
487
  syncRuntimeTree(sourcePath, destPath);
470
488
  continue;
471
489
  }
472
- const sourceStat = statSync(sourcePath);
473
- const needsCopy =
474
- !existsSync(destPath) ||
475
- statSync(destPath).size !== sourceStat.size ||
476
- statSync(destPath).mtimeMs < sourceStat.mtimeMs;
477
- if (!needsCopy) {
478
- continue;
479
- }
480
- mkdirSync(path.dirname(destPath), { recursive: true });
481
- copyFileSync(sourcePath, destPath);
482
- chmodSync(destPath, sourceStat.mode);
490
+ syncRuntimeFile(sourcePath, destPath);
483
491
  }
484
492
  }
485
493
 
@@ -1585,6 +1593,16 @@ function summarizeAssetApprovalResult(result: {
1585
1593
  return `${base} | synced_records=${String(sync.applied_record_count ?? 0)} | host=${sync.host || "unknown"}`;
1586
1594
  }
1587
1595
 
1596
+ function extractNextStep(result: unknown): UserNextStep | undefined {
1597
+ if (typeof result !== "object" || result === null) {
1598
+ return undefined;
1599
+ }
1600
+ if ("next_step" in result) {
1601
+ return (result as { next_step?: UserNextStep }).next_step;
1602
+ }
1603
+ return undefined;
1604
+ }
1605
+
1588
1606
  function looksLikeContextObject(result: unknown): boolean {
1589
1607
  return (
1590
1608
  typeof result === "object" &&
@@ -2087,11 +2105,21 @@ async function repairAutonomousCollection(
2087
2105
  };
2088
2106
  }
2089
2107
 
2090
- function printCliResult(result: unknown): void {
2108
+ function printCliResult(result: unknown, jsonOutput = false): void {
2091
2109
  const summary = summarizeResult(result);
2092
2110
  if (summary) {
2093
2111
  console.log(summary);
2094
2112
  }
2113
+ const nextStep = extractNextStep(result);
2114
+ if (!jsonOutput) {
2115
+ if (nextStep && nextStep.code !== "none") {
2116
+ console.log(`Next: ${nextStep.summary}`);
2117
+ if (nextStep.action) {
2118
+ console.log(`Action: ${nextStep.action}`);
2119
+ }
2120
+ }
2121
+ return;
2122
+ }
2095
2123
  console.log(JSON.stringify(result, null, 2));
2096
2124
  }
2097
2125
 
@@ -2134,7 +2162,8 @@ export default {
2134
2162
  )
2135
2163
  .argument("[project_root]", "Optional project root. Defaults to the current OpenClaw workspace.")
2136
2164
  .option("--shell <shell>", "Shell to manage for command capture.")
2137
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2165
+ .option("--json", "Print the full JSON result.")
2166
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2138
2167
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2139
2168
  const resolved = await resolveCliConfig(projectRoot, true);
2140
2169
  const result = await enableAutonomousCollection(resolved, {
@@ -2142,7 +2171,7 @@ export default {
2142
2171
  shell: opts?.shell,
2143
2172
  updated_by: "openclaw_cli",
2144
2173
  });
2145
- printCliResult(result);
2174
+ printCliResult(result, opts?.json);
2146
2175
  });
2147
2176
 
2148
2177
  program
@@ -2152,7 +2181,8 @@ export default {
2152
2181
  )
2153
2182
  .argument("[project_root]", "Optional project root. Defaults to the current OpenClaw workspace.")
2154
2183
  .option("--shell <shell>", "Shell to stop managing for command capture.")
2155
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2184
+ .option("--json", "Print the full JSON result.")
2185
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2156
2186
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2157
2187
  const resolved = await resolveCliConfig(projectRoot, true);
2158
2188
  const result = await disableAutonomousCollection(resolved, {
@@ -2160,7 +2190,7 @@ export default {
2160
2190
  shell: opts?.shell,
2161
2191
  updated_by: "openclaw_cli",
2162
2192
  });
2163
- printCliResult(result);
2193
+ printCliResult(result, opts?.json);
2164
2194
  });
2165
2195
 
2166
2196
  program
@@ -2170,14 +2200,15 @@ export default {
2170
2200
  )
2171
2201
  .argument("[project_root]", "Optional project root. Defaults to the current OpenClaw workspace.")
2172
2202
  .option("--shell <shell>", "Shell to inspect for command capture.")
2173
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2203
+ .option("--json", "Print the full JSON result.")
2204
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2174
2205
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2175
2206
  const resolved = await resolveCliConfig(projectRoot);
2176
2207
  const result = await getAutonomousCollectionStatus(resolved, {
2177
2208
  project_root: projectRoot,
2178
2209
  shell: opts?.shell,
2179
2210
  });
2180
- printCliResult(result);
2211
+ printCliResult(result, opts?.json);
2181
2212
  });
2182
2213
 
2183
2214
  program
@@ -2187,14 +2218,15 @@ export default {
2187
2218
  )
2188
2219
  .argument("[project_root]", "Optional project root. Defaults to the current OpenClaw workspace.")
2189
2220
  .option("--shell <shell>", "Shell to inspect for command capture.")
2190
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2221
+ .option("--json", "Print the full JSON result.")
2222
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2191
2223
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2192
2224
  const resolved = await resolveCliConfig(projectRoot);
2193
2225
  const result = await getAutonomousCollectionStatus(resolved, {
2194
2226
  project_root: projectRoot,
2195
2227
  shell: opts?.shell,
2196
2228
  });
2197
- printCliResult(result);
2229
+ printCliResult(result, opts?.json);
2198
2230
  });
2199
2231
 
2200
2232
  program
@@ -2204,14 +2236,15 @@ export default {
2204
2236
  )
2205
2237
  .argument("[project_root]", "Optional project root. Defaults to the current OpenClaw workspace.")
2206
2238
  .option("--shell <shell>", "Shell to inspect for command capture.")
2207
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2239
+ .option("--json", "Print the full JSON result.")
2240
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2208
2241
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2209
2242
  const resolved = await resolveCliConfig(projectRoot);
2210
2243
  const result = await getAutonomousCollectionStatus(resolved, {
2211
2244
  project_root: projectRoot,
2212
2245
  shell: opts?.shell,
2213
2246
  });
2214
- printCliResult(result);
2247
+ printCliResult(result, opts?.json);
2215
2248
  });
2216
2249
 
2217
2250
  program
@@ -2224,14 +2257,15 @@ export default {
2224
2257
  "Optional project root. Defaults to the current OpenClaw workspace.",
2225
2258
  )
2226
2259
  .option("--shell <shell>", "Shell to repair for command capture.")
2227
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2260
+ .option("--json", "Print the full JSON result.")
2261
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2228
2262
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2229
2263
  const resolved = await resolveCliConfig(projectRoot, true);
2230
2264
  const result = await repairAutonomousCollection(resolved, {
2231
2265
  project_root: projectRoot,
2232
2266
  shell: opts?.shell,
2233
2267
  });
2234
- printCliResult(result);
2268
+ printCliResult(result, opts?.json);
2235
2269
  });
2236
2270
 
2237
2271
  const opensyn = program
@@ -2243,7 +2277,8 @@ export default {
2243
2277
  .description("Alias for openclaw enable_opensyn.")
2244
2278
  .argument("[project_root]")
2245
2279
  .option("--shell <shell>")
2246
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2280
+ .option("--json", "Print the full JSON result.")
2281
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2247
2282
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2248
2283
  const resolved = await resolveCliConfig(projectRoot, true);
2249
2284
  const result = await enableAutonomousCollection(resolved, {
@@ -2251,7 +2286,7 @@ export default {
2251
2286
  shell: opts?.shell,
2252
2287
  updated_by: "openclaw_cli",
2253
2288
  });
2254
- printCliResult(result);
2289
+ printCliResult(result, opts?.json);
2255
2290
  });
2256
2291
 
2257
2292
  opensyn
@@ -2259,7 +2294,8 @@ export default {
2259
2294
  .description("Alias for openclaw disable_opensyn.")
2260
2295
  .argument("[project_root]")
2261
2296
  .option("--shell <shell>")
2262
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2297
+ .option("--json", "Print the full JSON result.")
2298
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2263
2299
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2264
2300
  const resolved = await resolveCliConfig(projectRoot, true);
2265
2301
  const result = await disableAutonomousCollection(resolved, {
@@ -2267,7 +2303,7 @@ export default {
2267
2303
  shell: opts?.shell,
2268
2304
  updated_by: "openclaw_cli",
2269
2305
  });
2270
- printCliResult(result);
2306
+ printCliResult(result, opts?.json);
2271
2307
  });
2272
2308
 
2273
2309
  opensyn
@@ -2275,14 +2311,15 @@ export default {
2275
2311
  .description("Alias for openclaw status_opensyn.")
2276
2312
  .argument("[project_root]")
2277
2313
  .option("--shell <shell>")
2278
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2314
+ .option("--json", "Print the full JSON result.")
2315
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2279
2316
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2280
2317
  const resolved = await resolveCliConfig(projectRoot);
2281
2318
  const result = await getAutonomousCollectionStatus(resolved, {
2282
2319
  project_root: projectRoot,
2283
2320
  shell: opts?.shell,
2284
2321
  });
2285
- printCliResult(result);
2322
+ printCliResult(result, opts?.json);
2286
2323
  });
2287
2324
 
2288
2325
  opensyn
@@ -2290,14 +2327,15 @@ export default {
2290
2327
  .description("Alias for openclaw doctor_opensyn.")
2291
2328
  .argument("[project_root]")
2292
2329
  .option("--shell <shell>")
2293
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2330
+ .option("--json", "Print the full JSON result.")
2331
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2294
2332
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2295
2333
  const resolved = await resolveCliConfig(projectRoot);
2296
2334
  const result = await getAutonomousCollectionStatus(resolved, {
2297
2335
  project_root: projectRoot,
2298
2336
  shell: opts?.shell,
2299
2337
  });
2300
- printCliResult(result);
2338
+ printCliResult(result, opts?.json);
2301
2339
  });
2302
2340
 
2303
2341
  opensyn
@@ -2305,14 +2343,15 @@ export default {
2305
2343
  .description("Repair OpenSyn runtime and refresh the managed shell hook.")
2306
2344
  .argument("[project_root]")
2307
2345
  .option("--shell <shell>")
2308
- .action(async (projectRootArg?: string, opts?: { shell?: string }) => {
2346
+ .option("--json", "Print the full JSON result.")
2347
+ .action(async (projectRootArg?: string, opts?: { shell?: string; json?: boolean }) => {
2309
2348
  const projectRoot = resolveCliProjectRoot(projectRootArg);
2310
2349
  const resolved = await resolveCliConfig(projectRoot, true);
2311
2350
  const result = await repairAutonomousCollection(resolved, {
2312
2351
  project_root: projectRoot,
2313
2352
  shell: opts?.shell,
2314
2353
  });
2315
- printCliResult(result);
2354
+ printCliResult(result, opts?.json);
2316
2355
  });
2317
2356
  },
2318
2357
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opensyn",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "OpenClaw plugin for OpenSyn autonomous local collection, distillation, and host overlay projection.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -148,12 +148,17 @@ async function main() {
148
148
  stdout: result.stdout?.trim() || "",
149
149
  stderr: result.stderr?.trim() || "",
150
150
  };
151
+ const computedLastError =
152
+ result.status && result.status !== 0
153
+ ? payload.error || payload.stderr || ""
154
+ : payload.error || "";
151
155
  updateState(options.statePath, {
152
156
  last_started_at: startedAt,
153
157
  last_finished_at: finishedAt,
154
158
  last_exit_code: result.status,
155
159
  last_signal: result.signal,
156
- last_error: payload.error || payload.stderr || "",
160
+ last_error: computedLastError,
161
+ last_stderr: payload.stderr,
157
162
  last_stdout: payload.stdout,
158
163
  last_command: payload.command,
159
164
  last_command_args: payload.command_args,