@haaaiawd/second-nature 0.1.10 → 0.1.11

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/index.js CHANGED
@@ -16,10 +16,16 @@
16
16
  * - structured mutating flows such as policy set / credential verify remain unavailable here
17
17
  * - full evidence-backed workspace runtime can be reintroduced later behind a host-safe boundary
18
18
  *
19
+ * OpenClaw operator norm (T1.1.4 / T1.1.5): set `SECOND_NATURE_WORKSPACE_ROOT` or tool `workspaceRoot` to the
20
+ * **same absolute path** as the OpenClaw **agent workspace** (default `~/.openclaw/workspace`, or
21
+ * `agents.defaults.workspace` in `~/.openclaw/openclaw.json`). Do **not** infer that root from the plugin
22
+ * install directory. With **sandbox** or **per-agent workspaces**, use the path where `data/state.db` and
23
+ * `workspace/` anchors actually live. See `explore/reports/2026-05-04_openclaw-plugin-install-vs-workspace-root.md`.
24
+ *
19
25
  * Test coverage:
20
26
  * - tests/integration/cli/plugin-runtime-registration.test.ts
21
27
  * - tests/integration/cli/plugin-packaging-walkthrough.test.ts
22
- * - tests/integration/cli/plugin-workspace-ops-bridge.test.ts (T1.1.4)
28
+ * - tests/integration/cli/plugin-workspace-ops-bridge.test.ts (T1.1.4 / CH-13 matrix, T1.1.5 ops docs cross-ref)
23
29
  */
24
30
  import { startRuntimeService, } from "./runtime/core/second-nature/runtime/service-entry.js";
25
31
  import { getLifecycleState, recordRegistration, } from "./runtime/core/second-nature/runtime/lifecycle-service.js";
@@ -376,14 +382,50 @@ function buildFallbackHostSafePayload(ref) {
376
382
  }
377
383
  return createUnavailableActionError("HOST_SAFE_FALLBACK_VIEW_UNAVAILABLE", "Operator fallback view requires workspace state database; host-safe plugin cannot read persisted fallback artifacts.", ["ref"], "run_workspace_second_nature_cli_or_full_runtime_package");
378
384
  }
385
+ function isProbeOnlyInput(input) {
386
+ const v = input?.probeOnly;
387
+ return v === true || v === "true" || v === 1 || v === "1";
388
+ }
379
389
  function buildHeartbeatCheckPayload(spine, input) {
380
390
  const runtimeEvidence = latestRuntimeEvidence(spine);
381
391
  const updatedAt = runtimeEvidence?.createdAt ?? new Date(spine.lifecycleState.lastChangedAt).toISOString();
382
392
  const timestamp = typeof input?.timestamp === "string" && input.timestamp.trim().length > 0 ? input.timestamp : updatedAt;
383
393
  const wr = spine.workspaceRootContext;
394
+ if (isProbeOnlyInput(input)) {
395
+ return {
396
+ ok: true,
397
+ status: "heartbeat_ok",
398
+ surfaceMode: "capability_probe",
399
+ reasons: ["probe_only"],
400
+ livedExperienceLoopClaimed: false,
401
+ scope: "rhythm",
402
+ trigger: "heartbeat_bridge",
403
+ message: "Capability probe only on the host-safe carrier surface; does not claim a full lived-experience decision loop.",
404
+ data: {
405
+ workspaceRootResolution: wr.resolution,
406
+ runtime: {
407
+ host: "openclaw-plugin",
408
+ serviceStatus: spine.runtimeHandle.ready ? "running" : "idle",
409
+ updatedAt,
410
+ },
411
+ surface: {
412
+ tool: "second_nature_ops",
413
+ command: "second-nature heartbeat_check",
414
+ },
415
+ bridge: {
416
+ timestamp,
417
+ probeOnly: true,
418
+ sessionContextProvided: typeof input?.sessionContext === "string" && input.sessionContext.trim().length > 0,
419
+ heartbeatChecklistProvided: typeof input?.heartbeatChecklist === "string" && input.heartbeatChecklist.trim().length > 0,
420
+ serviceEntryMode: "capability_probe",
421
+ },
422
+ },
423
+ };
424
+ }
384
425
  return {
385
426
  ok: true,
386
427
  status: "runtime_carrier_only",
428
+ surfaceMode: "host_safe_carrier",
387
429
  livedExperienceLoopClaimed: false,
388
430
  scope: "rhythm",
389
431
  trigger: "heartbeat_bridge",
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "id": "second-nature",
3
3
  "name": "Second Nature",
4
- "version": "0.1.10",
4
+ "version": "0.1.11",
5
5
  "entry": "./index.js",
6
- "description": "OpenClaw native plugin package with synchronous surface registration and a bundled runtime spine.",
6
+ "description": "OpenClaw native plugin with synchronous surface registration and bundled runtime spine. Set SECOND_NATURE_WORKSPACE_ROOT or tool workspaceRoot to the same path as the agent workspace (see README / T1.1.4 ops norm).",
7
7
  "capabilities": {
8
8
  "commands": [
9
9
  "second-nature"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haaaiawd/second-nature",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "OpenClaw native plugin with synchronous registration, a packaged runtime artifact, and operator-facing status/explain flows.",
5
5
  "keywords": [
6
6
  "openclaw",
@@ -3,6 +3,10 @@
3
3
  */
4
4
  import { heartbeatCheck } from "./heartbeat-surface.js";
5
5
  import { showOperatorFallback, OperatorFallbackNotFoundError } from "./show-operator-fallback.js";
6
+ function coerceProbeOnlyFlag(input) {
7
+ const v = input?.probeOnly;
8
+ return v === true || v === "true" || v === 1 || v === "1";
9
+ }
6
10
  export function createOpsRouter(deps) {
7
11
  return {
8
12
  heartbeatCheck: (input) => heartbeatCheck({
@@ -14,12 +18,12 @@ export function createOpsRouter(deps) {
14
18
  if (command === "heartbeat_check") {
15
19
  const runtimeAvailable = typeof input?.runtimeAvailable === "boolean" ? input.runtimeAvailable : deps.runtimeAvailable;
16
20
  return heartbeatCheck({
17
- probeOnly: Boolean(input?.probeOnly),
21
+ probeOnly: coerceProbeOnlyFlag(input),
18
22
  runtimeAvailable,
19
23
  fakeControlPlanePassthrough: input?.fakeControlPlanePassthrough && typeof input.fakeControlPlanePassthrough === "object"
20
24
  ? input.fakeControlPlanePassthrough
21
25
  : undefined,
22
- readModels: deps.readModels,
26
+ readModels: input?.readModels ?? deps.readModels,
23
27
  timestamp: typeof input?.timestamp === "string" ? input.timestamp : undefined,
24
28
  sessionContext: typeof input?.sessionContext === "string" ? input.sessionContext : undefined,
25
29
  scopeHint: input?.scopeHint,
@@ -26,7 +26,8 @@ export function startRuntimeService(ctx) {
26
26
  // - observability-system (event store setup)
27
27
  // - control-plane-system (heartbeat bridge preparation)
28
28
  const workspaceRoot = ctx?.workspaceRoot ?? process.cwd();
29
- const version = "0.1.0";
29
+ /** Keep in sync with `plugin/package.json` when cutting releases. */
30
+ const version = "0.1.11";
30
31
  activeHandle = {
31
32
  ready: true,
32
33
  version,