@haaaiawd/second-nature 0.1.43 → 0.1.51
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/openclaw.plugin.json +29 -29
- package/package.json +55 -55
- package/runtime/cli/commands/index.js +325 -325
- package/runtime/cli/ops/heartbeat-surface.d.ts +84 -75
- package/runtime/cli/ops/heartbeat-surface.js +100 -97
- package/runtime/cli/ops/ops-router.js +1482 -1454
- package/runtime/cli/ops/workspace-heartbeat-runner.d.ts +85 -76
- package/runtime/cli/ops/workspace-heartbeat-runner.js +242 -236
- package/runtime/connectors/base/contract.d.ts +111 -111
- package/runtime/connectors/base/failure-taxonomy.d.ts +13 -13
- package/runtime/connectors/base/failure-taxonomy.js +186 -186
- package/runtime/connectors/base/map-life-evidence.js +137 -137
- package/runtime/connectors/base/policy-layer.js +202 -202
- package/runtime/connectors/manifest/manifest-schema.d.ts +152 -152
- package/runtime/connectors/manifest/manifest-schema.js +54 -54
- package/runtime/connectors/services/connector-executor-adapter.d.ts +20 -20
- package/runtime/connectors/services/connector-executor-adapter.js +645 -645
- package/runtime/core/second-nature/heartbeat/goal-lifecycle-policy.d.ts +24 -37
- package/runtime/core/second-nature/heartbeat/goal-lifecycle-policy.js +61 -61
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.d.ts +97 -88
- package/runtime/core/second-nature/heartbeat/heartbeat-loop.js +397 -329
- package/runtime/core/second-nature/orchestrator/platform-capability-router.js +149 -131
|
@@ -1,325 +1,325 @@
|
|
|
1
|
-
import { credentialVerify } from "./credential.js";
|
|
2
|
-
import { connectorInit } from "./connector-init.js";
|
|
3
|
-
import { formatExplanation } from "../explain/format-explanation.js";
|
|
4
|
-
import { explainSurfaceSubject } from "../explain/explain-surface-subject.js";
|
|
5
|
-
import { showOperatorFallback, OperatorFallbackNotFoundError, } from "../ops/show-operator-fallback.js";
|
|
6
|
-
import { runStorageModeSmoke } from "../../storage/bootstrap/storage-mode-smoke.js";
|
|
7
|
-
import { policySet } from "./policy.js";
|
|
8
|
-
const notImplemented = async (command) => ({
|
|
9
|
-
ok: false,
|
|
10
|
-
command,
|
|
11
|
-
message: "Command shell registered. Implementation lands in later Wave tasks.",
|
|
12
|
-
});
|
|
13
|
-
function explainSubjectError(code, message) {
|
|
14
|
-
return {
|
|
15
|
-
ok: false,
|
|
16
|
-
error: {
|
|
17
|
-
code,
|
|
18
|
-
message,
|
|
19
|
-
requiredUserInput: ["subject"],
|
|
20
|
-
nextStep: "reinvoke_explain_with_supported_subject",
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
export function createCliCommands(deps) {
|
|
25
|
-
const { readModels, actionBridge, opsRouter } = deps;
|
|
26
|
-
const opsCommand = (name, description) => ({
|
|
27
|
-
name,
|
|
28
|
-
description,
|
|
29
|
-
execute: async (input) => {
|
|
30
|
-
const surface = await Promise.resolve(opsRouter.dispatch(name, input));
|
|
31
|
-
return surface;
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
return [
|
|
35
|
-
{
|
|
36
|
-
name: "status",
|
|
37
|
-
description: "T1.2.6 — Show v6 aggregated Second Nature status (narrative + dream + cycles + runtime)",
|
|
38
|
-
execute: async (input) => {
|
|
39
|
-
const scope = typeof input?.scope === "string" ? input.scope : undefined;
|
|
40
|
-
const data = await readModels.loadV6Status(scope);
|
|
41
|
-
return { ok: true, data };
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
name: "policy",
|
|
46
|
-
description: "Write or inspect policy state",
|
|
47
|
-
execute: async (input) => {
|
|
48
|
-
const action = typeof input?.action === "string" ? input.action : "show";
|
|
49
|
-
if (action === "set") {
|
|
50
|
-
return policySet(actionBridge, input);
|
|
51
|
-
}
|
|
52
|
-
// T1.2.6 (SN-CODE-01): `policy show` (default) returns the current rhythm policy
|
|
53
|
-
// snapshot. Returns workspace defaults when no policy row has been persisted yet.
|
|
54
|
-
const data = await readModels.loadPolicy();
|
|
55
|
-
return { ok: true, data };
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: "credential",
|
|
60
|
-
description: "Inspect or recover credential state",
|
|
61
|
-
execute: async (input) => {
|
|
62
|
-
const action = typeof input?.action === "string" ? input.action : "show";
|
|
63
|
-
if (action === "verify") {
|
|
64
|
-
return credentialVerify(actionBridge, input);
|
|
65
|
-
}
|
|
66
|
-
const platformId = typeof input?.platformId === "string" ? input.platformId : "unknown";
|
|
67
|
-
const data = await readModels.loadCredential(platformId);
|
|
68
|
-
return { ok: true, data };
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
name: "quiet",
|
|
73
|
-
description: "Inspect Quiet lifecycle state",
|
|
74
|
-
execute: async (input) => {
|
|
75
|
-
const scope = typeof input?.scope === "string" ? input.scope : undefined;
|
|
76
|
-
const data = await readModels.loadQuiet(scope);
|
|
77
|
-
return { ok: true, data };
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: "report",
|
|
82
|
-
description: "Show daily report artifacts",
|
|
83
|
-
execute: async (input) => {
|
|
84
|
-
const day = typeof input?.day === "string"
|
|
85
|
-
? input.day
|
|
86
|
-
: new Date().toISOString().slice(0, 10);
|
|
87
|
-
const data = await readModels.loadDailyReport(day);
|
|
88
|
-
return { ok: true, data };
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
name: "session",
|
|
93
|
-
description: "Inspect continuity session details",
|
|
94
|
-
execute: async (input) => {
|
|
95
|
-
const sessionId = typeof input?.sessionId === "string" ? input.sessionId : "";
|
|
96
|
-
if (!sessionId) {
|
|
97
|
-
return {
|
|
98
|
-
ok: false,
|
|
99
|
-
error: {
|
|
100
|
-
code: "MISSING_SESSION_ID",
|
|
101
|
-
message: "session show requires sessionId",
|
|
102
|
-
requiredUserInput: ["session_id"],
|
|
103
|
-
nextStep: "reinvoke_session_with_session_id",
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
const data = await readModels.loadSession(sessionId);
|
|
108
|
-
return { ok: true, data };
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
name: "audit",
|
|
113
|
-
description: "Inspect audit and evidence views",
|
|
114
|
-
execute: async () => {
|
|
115
|
-
// T1.2.7 (SN-CODE-02): minimal read-side view — list all in-memory audit events.
|
|
116
|
-
// Empty store returns { totalEvents: 0, events: [] } (honest empty, not an error).
|
|
117
|
-
const data = await readModels.loadAuditSummary();
|
|
118
|
-
return { ok: true, data };
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: "explain",
|
|
123
|
-
description: "Answer why-question explain requests",
|
|
124
|
-
execute: async (input) => {
|
|
125
|
-
const subjectRaw = typeof input?.subject === "string" ? input.subject.trim() : "";
|
|
126
|
-
if (!subjectRaw) {
|
|
127
|
-
return {
|
|
128
|
-
ok: false,
|
|
129
|
-
error: {
|
|
130
|
-
code: "MISSING_EXPLAIN_SUBJECT",
|
|
131
|
-
message: "explain requires subject",
|
|
132
|
-
requiredUserInput: ["subject"],
|
|
133
|
-
nextStep: "reinvoke_explain_with_subject",
|
|
134
|
-
},
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
let model;
|
|
138
|
-
try {
|
|
139
|
-
model = await explainSurfaceSubject(subjectRaw, readModels);
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
const code = error.message;
|
|
143
|
-
if (code === "explain_subject_requires_id") {
|
|
144
|
-
return explainSubjectError("EXPLAIN_SUBJECT_REQUIRES_ID", "subject must include identifier");
|
|
145
|
-
}
|
|
146
|
-
if (code === "explain_subject_unsupported") {
|
|
147
|
-
return explainSubjectError("EXPLAIN_SUBJECT_UNSUPPORTED", "supported subjects include decision:, platform:, outreach:, soul:, fallback:, delivery:, probe:, report:, source:, relationship:");
|
|
148
|
-
}
|
|
149
|
-
return explainSubjectError("EXPLAIN_SUBJECT_INVALID", "invalid explain subject");
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
ok: true,
|
|
153
|
-
data: formatExplanation(model),
|
|
154
|
-
};
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
name: "heartbeat_check",
|
|
159
|
-
description: "Workspace heartbeat_check ops surface (v5 HeartbeatSurfaceResult)",
|
|
160
|
-
execute: async (input) => {
|
|
161
|
-
const surface = await Promise.resolve(opsRouter.dispatch("heartbeat_check", input));
|
|
162
|
-
return surface;
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
name: "storage_smoke",
|
|
167
|
-
description: "T4.1.4 — report sql.js vs native SQLite probe and optional artifact→index repair fixture",
|
|
168
|
-
execute: async (input) => {
|
|
169
|
-
const runRepairFixture = Boolean(input?.runRepairFixture);
|
|
170
|
-
const workspaceRoot = typeof input?.workspaceRoot === "string"
|
|
171
|
-
? input.workspaceRoot
|
|
172
|
-
: undefined;
|
|
173
|
-
const data = await runStorageModeSmoke({
|
|
174
|
-
runRepairFixture,
|
|
175
|
-
workspaceRoot,
|
|
176
|
-
});
|
|
177
|
-
return { ok: true, data };
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
name: "fallback",
|
|
182
|
-
description: "Operator-visible delivery fallback view (status always not_sent)",
|
|
183
|
-
execute: async (input) => {
|
|
184
|
-
const ref = typeof input?.ref === "string" ? input.ref.trim() : "";
|
|
185
|
-
if (!ref) {
|
|
186
|
-
return {
|
|
187
|
-
ok: false,
|
|
188
|
-
error: {
|
|
189
|
-
code: "MISSING_FALLBACK_REF",
|
|
190
|
-
message: "fallback requires ref (e.g. fallback:…)",
|
|
191
|
-
requiredUserInput: ["ref"],
|
|
192
|
-
nextStep: "reinvoke_with_ref",
|
|
193
|
-
},
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
try {
|
|
197
|
-
const data = await showOperatorFallback(ref, readModels);
|
|
198
|
-
return { ok: true, data };
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
if (error instanceof OperatorFallbackNotFoundError) {
|
|
202
|
-
return {
|
|
203
|
-
ok: false,
|
|
204
|
-
error: {
|
|
205
|
-
code: error.code,
|
|
206
|
-
message: error.message,
|
|
207
|
-
requiredUserInput: ["ref"],
|
|
208
|
-
nextStep: "verify_fallback_ref_from_delivery_audit",
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
throw error;
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: "capability_probe",
|
|
218
|
-
description: "T1.2.8 — probe host capabilities and persist report (static unknown adapter in CLI context)",
|
|
219
|
-
execute: async (input) => {
|
|
220
|
-
const surface = await Promise.resolve(opsRouter.dispatch("capability_probe", input));
|
|
221
|
-
return surface;
|
|
222
|
-
},
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
name: "near_real_smoke",
|
|
226
|
-
description: "T3.3.2 — run near-real connector smoke (sentinel Moltbook + EvoMap, no live HTTP)",
|
|
227
|
-
execute: async (input) => {
|
|
228
|
-
const surface = await Promise.resolve(opsRouter.dispatch("near_real_smoke", input));
|
|
229
|
-
return surface;
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
name: "connector_init",
|
|
234
|
-
description: "T1.3.1 — generate connector manifest stub under .second-nature/connectors/{platformId}/",
|
|
235
|
-
execute: async (input) => {
|
|
236
|
-
const result = await connectorInit({
|
|
237
|
-
platformId: typeof input?.platformId === "string" ? input.platformId : "",
|
|
238
|
-
family: typeof input?.family === "string"
|
|
239
|
-
? input.family
|
|
240
|
-
: undefined,
|
|
241
|
-
displayName: typeof input?.displayName === "string"
|
|
242
|
-
? input.displayName
|
|
243
|
-
: undefined,
|
|
244
|
-
runnerKind: typeof input?.runnerKind === "string"
|
|
245
|
-
? input.runnerKind
|
|
246
|
-
: undefined,
|
|
247
|
-
force: Boolean(input?.force),
|
|
248
|
-
workspaceRoot: typeof input?.workspaceRoot === "string"
|
|
249
|
-
? input.workspaceRoot
|
|
250
|
-
: undefined,
|
|
251
|
-
});
|
|
252
|
-
return result;
|
|
253
|
-
},
|
|
254
|
-
},
|
|
255
|
-
{
|
|
256
|
-
name: "connector_behavior_add",
|
|
257
|
-
description: "Add a workspace-defined connector behavior to an existing manifest without executing custom code",
|
|
258
|
-
execute: async (input) => {
|
|
259
|
-
const surface = await Promise.resolve(opsRouter.dispatch("connector_behavior_add", input));
|
|
260
|
-
return surface;
|
|
261
|
-
},
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
name: "connector_status",
|
|
265
|
-
description: "T1.2.3 — show connector inventory, trust/executable/conflict summary",
|
|
266
|
-
execute: async (input) => {
|
|
267
|
-
const surface = await Promise.resolve(opsRouter.dispatch("connector_status", input));
|
|
268
|
-
return surface;
|
|
269
|
-
},
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
name: "connector_test",
|
|
273
|
-
description: "T1.2.3 — dry-run test a connector by platformId (default dry-run)",
|
|
274
|
-
execute: async (input) => {
|
|
275
|
-
const surface = await Promise.resolve(opsRouter.dispatch("connector_test", input));
|
|
276
|
-
return surface;
|
|
277
|
-
},
|
|
278
|
-
},
|
|
279
|
-
opsCommand("connector:run", "T-ROS.C.3 — manually execute a connector capability outside heartbeat cadence"),
|
|
280
|
-
opsCommand("self_health", "T-ROS.C.1 — show v7 self-health snapshot and degraded dimensions"),
|
|
281
|
-
opsCommand("tool_affordance", "T-ROS.C.1 — show v7 tool affordance map or explicit unavailable state"),
|
|
282
|
-
opsCommand("heartbeat_digest", "T-ROS.C.1 — assemble v7 heartbeat digest for a day"),
|
|
283
|
-
opsCommand("snapshot:capture", "T-V7C.C.1 — capture restore snapshot and narrative timeline version"),
|
|
284
|
-
opsCommand("narrative:diff", "T-ROS.C.1 — compare two narrative timeline versions"),
|
|
285
|
-
opsCommand("timeline", "T-ROS.C.1 — query v7 narrative timeline with cursor pagination"),
|
|
286
|
-
opsCommand("restore", "T-ROS.C.1 — apply bounded restore and write restore audit"),
|
|
287
|
-
opsCommand("runtime_secret_bootstrap", "T-ROS.C.1 — inspect runtime secret anchor health without exposing plaintext"),
|
|
288
|
-
opsCommand("guidance_payload", "T-V7C.C.4R — assemble impulse + atmosphere for a scene context"),
|
|
289
|
-
{
|
|
290
|
-
name: "goal",
|
|
291
|
-
description: "T1.2.4 — owner-governed goal operations: set, list, accept, reject",
|
|
292
|
-
execute: async (input) => {
|
|
293
|
-
const surface = await Promise.resolve(opsRouter.dispatch("goal", input));
|
|
294
|
-
return surface;
|
|
295
|
-
},
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
name: "narrative",
|
|
299
|
-
description: "T1.2.1 — show current NarrativeState: focus, progress, next intent, source refs, grounding status",
|
|
300
|
-
execute: async (input) => {
|
|
301
|
-
const narrativeId = typeof input?.narrativeId === "string" ? input.narrativeId : undefined;
|
|
302
|
-
const data = await readModels.loadNarrative(narrativeId);
|
|
303
|
-
return { ok: true, data };
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
name: "dream:recent",
|
|
308
|
-
description: "T1.2.2 — show recent Dream run results, candidate/accepted status, fallback/partial summary",
|
|
309
|
-
execute: async (input) => {
|
|
310
|
-
const limit = typeof input?.limit === "number" ? input.limit : 5;
|
|
311
|
-
const data = await readModels.loadDreamRecent(limit);
|
|
312
|
-
return { ok: true, data };
|
|
313
|
-
},
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
name: "cycle:recent",
|
|
317
|
-
description: "T1.2.5 — aggregate recent heartbeat, narrative, Dream, delivery, connector cycle summary",
|
|
318
|
-
execute: async (input) => {
|
|
319
|
-
const limit = typeof input?.limit === "number" ? input.limit : 5;
|
|
320
|
-
const data = await readModels.loadCycleRecent(limit);
|
|
321
|
-
return { ok: true, data };
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
];
|
|
325
|
-
}
|
|
1
|
+
import { credentialVerify } from "./credential.js";
|
|
2
|
+
import { connectorInit } from "./connector-init.js";
|
|
3
|
+
import { formatExplanation } from "../explain/format-explanation.js";
|
|
4
|
+
import { explainSurfaceSubject } from "../explain/explain-surface-subject.js";
|
|
5
|
+
import { showOperatorFallback, OperatorFallbackNotFoundError, } from "../ops/show-operator-fallback.js";
|
|
6
|
+
import { runStorageModeSmoke } from "../../storage/bootstrap/storage-mode-smoke.js";
|
|
7
|
+
import { policySet } from "./policy.js";
|
|
8
|
+
const notImplemented = async (command) => ({
|
|
9
|
+
ok: false,
|
|
10
|
+
command,
|
|
11
|
+
message: "Command shell registered. Implementation lands in later Wave tasks.",
|
|
12
|
+
});
|
|
13
|
+
function explainSubjectError(code, message) {
|
|
14
|
+
return {
|
|
15
|
+
ok: false,
|
|
16
|
+
error: {
|
|
17
|
+
code,
|
|
18
|
+
message,
|
|
19
|
+
requiredUserInput: ["subject"],
|
|
20
|
+
nextStep: "reinvoke_explain_with_supported_subject",
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function createCliCommands(deps) {
|
|
25
|
+
const { readModels, actionBridge, opsRouter } = deps;
|
|
26
|
+
const opsCommand = (name, description) => ({
|
|
27
|
+
name,
|
|
28
|
+
description,
|
|
29
|
+
execute: async (input) => {
|
|
30
|
+
const surface = await Promise.resolve(opsRouter.dispatch(name, input));
|
|
31
|
+
return surface;
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
return [
|
|
35
|
+
{
|
|
36
|
+
name: "status",
|
|
37
|
+
description: "T1.2.6 — Show v6 aggregated Second Nature status (narrative + dream + cycles + runtime)",
|
|
38
|
+
execute: async (input) => {
|
|
39
|
+
const scope = typeof input?.scope === "string" ? input.scope : undefined;
|
|
40
|
+
const data = await readModels.loadV6Status(scope);
|
|
41
|
+
return { ok: true, data };
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "policy",
|
|
46
|
+
description: "Write or inspect policy state",
|
|
47
|
+
execute: async (input) => {
|
|
48
|
+
const action = typeof input?.action === "string" ? input.action : "show";
|
|
49
|
+
if (action === "set") {
|
|
50
|
+
return policySet(actionBridge, input);
|
|
51
|
+
}
|
|
52
|
+
// T1.2.6 (SN-CODE-01): `policy show` (default) returns the current rhythm policy
|
|
53
|
+
// snapshot. Returns workspace defaults when no policy row has been persisted yet.
|
|
54
|
+
const data = await readModels.loadPolicy();
|
|
55
|
+
return { ok: true, data };
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "credential",
|
|
60
|
+
description: "Inspect or recover credential state",
|
|
61
|
+
execute: async (input) => {
|
|
62
|
+
const action = typeof input?.action === "string" ? input.action : "show";
|
|
63
|
+
if (action === "verify") {
|
|
64
|
+
return credentialVerify(actionBridge, input);
|
|
65
|
+
}
|
|
66
|
+
const platformId = typeof input?.platformId === "string" ? input.platformId : "unknown";
|
|
67
|
+
const data = await readModels.loadCredential(platformId);
|
|
68
|
+
return { ok: true, data };
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "quiet",
|
|
73
|
+
description: "Inspect Quiet lifecycle state",
|
|
74
|
+
execute: async (input) => {
|
|
75
|
+
const scope = typeof input?.scope === "string" ? input.scope : undefined;
|
|
76
|
+
const data = await readModels.loadQuiet(scope);
|
|
77
|
+
return { ok: true, data };
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "report",
|
|
82
|
+
description: "Show daily report artifacts",
|
|
83
|
+
execute: async (input) => {
|
|
84
|
+
const day = typeof input?.day === "string"
|
|
85
|
+
? input.day
|
|
86
|
+
: new Date().toISOString().slice(0, 10);
|
|
87
|
+
const data = await readModels.loadDailyReport(day);
|
|
88
|
+
return { ok: true, data };
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: "session",
|
|
93
|
+
description: "Inspect continuity session details",
|
|
94
|
+
execute: async (input) => {
|
|
95
|
+
const sessionId = typeof input?.sessionId === "string" ? input.sessionId : "";
|
|
96
|
+
if (!sessionId) {
|
|
97
|
+
return {
|
|
98
|
+
ok: false,
|
|
99
|
+
error: {
|
|
100
|
+
code: "MISSING_SESSION_ID",
|
|
101
|
+
message: "session show requires sessionId",
|
|
102
|
+
requiredUserInput: ["session_id"],
|
|
103
|
+
nextStep: "reinvoke_session_with_session_id",
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const data = await readModels.loadSession(sessionId);
|
|
108
|
+
return { ok: true, data };
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "audit",
|
|
113
|
+
description: "Inspect audit and evidence views",
|
|
114
|
+
execute: async () => {
|
|
115
|
+
// T1.2.7 (SN-CODE-02): minimal read-side view — list all in-memory audit events.
|
|
116
|
+
// Empty store returns { totalEvents: 0, events: [] } (honest empty, not an error).
|
|
117
|
+
const data = await readModels.loadAuditSummary();
|
|
118
|
+
return { ok: true, data };
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: "explain",
|
|
123
|
+
description: "Answer why-question explain requests",
|
|
124
|
+
execute: async (input) => {
|
|
125
|
+
const subjectRaw = typeof input?.subject === "string" ? input.subject.trim() : "";
|
|
126
|
+
if (!subjectRaw) {
|
|
127
|
+
return {
|
|
128
|
+
ok: false,
|
|
129
|
+
error: {
|
|
130
|
+
code: "MISSING_EXPLAIN_SUBJECT",
|
|
131
|
+
message: "explain requires subject",
|
|
132
|
+
requiredUserInput: ["subject"],
|
|
133
|
+
nextStep: "reinvoke_explain_with_subject",
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
let model;
|
|
138
|
+
try {
|
|
139
|
+
model = await explainSurfaceSubject(subjectRaw, readModels);
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
const code = error.message;
|
|
143
|
+
if (code === "explain_subject_requires_id") {
|
|
144
|
+
return explainSubjectError("EXPLAIN_SUBJECT_REQUIRES_ID", "subject must include identifier");
|
|
145
|
+
}
|
|
146
|
+
if (code === "explain_subject_unsupported") {
|
|
147
|
+
return explainSubjectError("EXPLAIN_SUBJECT_UNSUPPORTED", "supported subjects include decision:, platform:, outreach:, soul:, fallback:, delivery:, probe:, report:, source:, relationship:");
|
|
148
|
+
}
|
|
149
|
+
return explainSubjectError("EXPLAIN_SUBJECT_INVALID", "invalid explain subject");
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
ok: true,
|
|
153
|
+
data: formatExplanation(model),
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "heartbeat_check",
|
|
159
|
+
description: "Workspace heartbeat_check ops surface (v5 HeartbeatSurfaceResult)",
|
|
160
|
+
execute: async (input) => {
|
|
161
|
+
const surface = await Promise.resolve(opsRouter.dispatch("heartbeat_check", input));
|
|
162
|
+
return surface;
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: "storage_smoke",
|
|
167
|
+
description: "T4.1.4 — report sql.js vs native SQLite probe and optional artifact→index repair fixture",
|
|
168
|
+
execute: async (input) => {
|
|
169
|
+
const runRepairFixture = Boolean(input?.runRepairFixture);
|
|
170
|
+
const workspaceRoot = typeof input?.workspaceRoot === "string"
|
|
171
|
+
? input.workspaceRoot
|
|
172
|
+
: undefined;
|
|
173
|
+
const data = await runStorageModeSmoke({
|
|
174
|
+
runRepairFixture,
|
|
175
|
+
workspaceRoot,
|
|
176
|
+
});
|
|
177
|
+
return { ok: true, data };
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "fallback",
|
|
182
|
+
description: "Operator-visible delivery fallback view (status always not_sent)",
|
|
183
|
+
execute: async (input) => {
|
|
184
|
+
const ref = typeof input?.ref === "string" ? input.ref.trim() : "";
|
|
185
|
+
if (!ref) {
|
|
186
|
+
return {
|
|
187
|
+
ok: false,
|
|
188
|
+
error: {
|
|
189
|
+
code: "MISSING_FALLBACK_REF",
|
|
190
|
+
message: "fallback requires ref (e.g. fallback:…)",
|
|
191
|
+
requiredUserInput: ["ref"],
|
|
192
|
+
nextStep: "reinvoke_with_ref",
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
const data = await showOperatorFallback(ref, readModels);
|
|
198
|
+
return { ok: true, data };
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (error instanceof OperatorFallbackNotFoundError) {
|
|
202
|
+
return {
|
|
203
|
+
ok: false,
|
|
204
|
+
error: {
|
|
205
|
+
code: error.code,
|
|
206
|
+
message: error.message,
|
|
207
|
+
requiredUserInput: ["ref"],
|
|
208
|
+
nextStep: "verify_fallback_ref_from_delivery_audit",
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: "capability_probe",
|
|
218
|
+
description: "T1.2.8 — probe host capabilities and persist report (static unknown adapter in CLI context)",
|
|
219
|
+
execute: async (input) => {
|
|
220
|
+
const surface = await Promise.resolve(opsRouter.dispatch("capability_probe", input));
|
|
221
|
+
return surface;
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: "near_real_smoke",
|
|
226
|
+
description: "T3.3.2 — run near-real connector smoke (sentinel Moltbook + EvoMap, no live HTTP)",
|
|
227
|
+
execute: async (input) => {
|
|
228
|
+
const surface = await Promise.resolve(opsRouter.dispatch("near_real_smoke", input));
|
|
229
|
+
return surface;
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: "connector_init",
|
|
234
|
+
description: "T1.3.1 — generate connector manifest stub under .second-nature/connectors/{platformId}/",
|
|
235
|
+
execute: async (input) => {
|
|
236
|
+
const result = await connectorInit({
|
|
237
|
+
platformId: typeof input?.platformId === "string" ? input.platformId : "",
|
|
238
|
+
family: typeof input?.family === "string"
|
|
239
|
+
? input.family
|
|
240
|
+
: undefined,
|
|
241
|
+
displayName: typeof input?.displayName === "string"
|
|
242
|
+
? input.displayName
|
|
243
|
+
: undefined,
|
|
244
|
+
runnerKind: typeof input?.runnerKind === "string"
|
|
245
|
+
? input.runnerKind
|
|
246
|
+
: undefined,
|
|
247
|
+
force: Boolean(input?.force),
|
|
248
|
+
workspaceRoot: typeof input?.workspaceRoot === "string"
|
|
249
|
+
? input.workspaceRoot
|
|
250
|
+
: undefined,
|
|
251
|
+
});
|
|
252
|
+
return result;
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: "connector_behavior_add",
|
|
257
|
+
description: "Add a workspace-defined connector behavior to an existing manifest without executing custom code",
|
|
258
|
+
execute: async (input) => {
|
|
259
|
+
const surface = await Promise.resolve(opsRouter.dispatch("connector_behavior_add", input));
|
|
260
|
+
return surface;
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "connector_status",
|
|
265
|
+
description: "T1.2.3 — show connector inventory, trust/executable/conflict summary",
|
|
266
|
+
execute: async (input) => {
|
|
267
|
+
const surface = await Promise.resolve(opsRouter.dispatch("connector_status", input));
|
|
268
|
+
return surface;
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: "connector_test",
|
|
273
|
+
description: "T1.2.3 — dry-run test a connector by platformId (default dry-run)",
|
|
274
|
+
execute: async (input) => {
|
|
275
|
+
const surface = await Promise.resolve(opsRouter.dispatch("connector_test", input));
|
|
276
|
+
return surface;
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
opsCommand("connector:run", "T-ROS.C.3 — manually execute a connector capability outside heartbeat cadence"),
|
|
280
|
+
opsCommand("self_health", "T-ROS.C.1 — show v7 self-health snapshot and degraded dimensions"),
|
|
281
|
+
opsCommand("tool_affordance", "T-ROS.C.1 — show v7 tool affordance map or explicit unavailable state"),
|
|
282
|
+
opsCommand("heartbeat_digest", "T-ROS.C.1 — assemble v7 heartbeat digest for a day"),
|
|
283
|
+
opsCommand("snapshot:capture", "T-V7C.C.1 — capture restore snapshot and narrative timeline version"),
|
|
284
|
+
opsCommand("narrative:diff", "T-ROS.C.1 — compare two narrative timeline versions"),
|
|
285
|
+
opsCommand("timeline", "T-ROS.C.1 — query v7 narrative timeline with cursor pagination"),
|
|
286
|
+
opsCommand("restore", "T-ROS.C.1 — apply bounded restore and write restore audit"),
|
|
287
|
+
opsCommand("runtime_secret_bootstrap", "T-ROS.C.1 — inspect runtime secret anchor health without exposing plaintext"),
|
|
288
|
+
opsCommand("guidance_payload", "T-V7C.C.4R — assemble impulse + atmosphere for a scene context"),
|
|
289
|
+
{
|
|
290
|
+
name: "goal",
|
|
291
|
+
description: "T1.2.4 — owner-governed goal operations: set, list, accept, reject",
|
|
292
|
+
execute: async (input) => {
|
|
293
|
+
const surface = await Promise.resolve(opsRouter.dispatch("goal", input));
|
|
294
|
+
return surface;
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
name: "narrative",
|
|
299
|
+
description: "T1.2.1 — show current NarrativeState: focus, progress, next intent, source refs, grounding status",
|
|
300
|
+
execute: async (input) => {
|
|
301
|
+
const narrativeId = typeof input?.narrativeId === "string" ? input.narrativeId : undefined;
|
|
302
|
+
const data = await readModels.loadNarrative(narrativeId);
|
|
303
|
+
return { ok: true, data };
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: "dream:recent",
|
|
308
|
+
description: "T1.2.2 — show recent Dream run results, candidate/accepted status, fallback/partial summary",
|
|
309
|
+
execute: async (input) => {
|
|
310
|
+
const limit = typeof input?.limit === "number" ? input.limit : 5;
|
|
311
|
+
const data = await readModels.loadDreamRecent(limit);
|
|
312
|
+
return { ok: true, data };
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: "cycle:recent",
|
|
317
|
+
description: "T1.2.5 — aggregate recent heartbeat, narrative, Dream, delivery, connector cycle summary",
|
|
318
|
+
execute: async (input) => {
|
|
319
|
+
const limit = typeof input?.limit === "number" ? input.limit : 5;
|
|
320
|
+
const data = await readModels.loadCycleRecent(limit);
|
|
321
|
+
return { ok: true, data };
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
];
|
|
325
|
+
}
|