@wowok/agent-mcp 2.3.14 → 2.3.16
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/dist/config/index.d.ts +1 -0
- package/dist/config/index.js +1 -0
- package/dist/config/runtime.d.ts +26 -0
- package/dist/config/runtime.js +217 -0
- package/dist/customer/industry-risks.d.ts +36 -0
- package/dist/customer/industry-risks.js +424 -0
- package/dist/customer/info-puzzle.d.ts +102 -0
- package/dist/customer/info-puzzle.js +312 -0
- package/dist/customer/order-monitor.d.ts +75 -0
- package/dist/customer/order-monitor.js +327 -0
- package/dist/customer/order-strategy.d.ts +36 -0
- package/dist/customer/order-strategy.js +373 -0
- package/dist/customer/post-purchase.d.ts +42 -0
- package/dist/customer/post-purchase.js +350 -0
- package/dist/customer/reminder-system.d.ts +42 -0
- package/dist/customer/reminder-system.js +295 -0
- package/dist/customer/risk-assessment.d.ts +8 -0
- package/dist/customer/risk-assessment.js +337 -0
- package/dist/customer/types.d.ts +193 -0
- package/dist/customer/types.js +13 -0
- package/dist/customer/user-preferences.d.ts +67 -0
- package/dist/customer/user-preferences.js +451 -0
- package/dist/experience/experience-reuse.d.ts +10 -0
- package/dist/experience/experience-reuse.js +103 -0
- package/dist/experience/index.d.ts +6 -0
- package/dist/experience/index.js +5 -0
- package/dist/experience/intent-distill.d.ts +3 -0
- package/dist/experience/intent-distill.js +83 -0
- package/dist/experience/realtime-feedback.d.ts +5 -0
- package/dist/experience/realtime-feedback.js +77 -0
- package/dist/experience/types.d.ts +50 -0
- package/dist/experience/types.js +1 -0
- package/dist/experience/user-profile.d.ts +25 -0
- package/dist/experience/user-profile.js +171 -0
- package/dist/index.js +570 -186
- package/dist/knowledge/acquisition-flywheel.d.ts +50 -0
- package/dist/knowledge/acquisition-flywheel.js +183 -0
- package/dist/knowledge/arbitration-trust.d.ts +24 -0
- package/dist/knowledge/arbitration-trust.js +117 -0
- package/dist/knowledge/audit-rules.d.ts +28 -0
- package/dist/knowledge/audit-rules.js +141 -0
- package/dist/knowledge/demand-matching.d.ts +29 -0
- package/dist/knowledge/demand-matching.js +132 -0
- package/dist/knowledge/dynamic-pricing.d.ts +31 -0
- package/dist/knowledge/dynamic-pricing.js +87 -0
- package/dist/knowledge/flywheel-loop.d.ts +87 -0
- package/dist/knowledge/flywheel-loop.js +378 -0
- package/dist/knowledge/glossary.d.ts +18 -0
- package/dist/knowledge/glossary.js +209 -0
- package/dist/knowledge/index.d.ts +64 -0
- package/dist/knowledge/index.js +66 -0
- package/dist/knowledge/industry-evolution.d.ts +82 -0
- package/dist/knowledge/industry-evolution.js +323 -0
- package/dist/knowledge/industry-generalizer.d.ts +17 -0
- package/dist/knowledge/industry-generalizer.js +381 -0
- package/dist/knowledge/industry-registry.d.ts +49 -0
- package/dist/knowledge/industry-registry.js +167 -0
- package/dist/knowledge/intent-metrics.d.ts +42 -0
- package/dist/knowledge/intent-metrics.js +566 -0
- package/dist/knowledge/process-model.d.ts +24 -0
- package/dist/knowledge/process-model.js +160 -0
- package/dist/knowledge/reputation-rules.d.ts +42 -0
- package/dist/knowledge/reputation-rules.js +99 -0
- package/dist/knowledge/reward-templates.d.ts +25 -0
- package/dist/knowledge/reward-templates.js +125 -0
- package/dist/knowledge/safety-rules.d.ts +36 -0
- package/dist/knowledge/safety-rules.js +171 -0
- package/dist/knowledge/tool-constraints.d.ts +30 -0
- package/dist/knowledge/tool-constraints.js +185 -0
- package/dist/knowledge/trust-metrics.d.ts +37 -0
- package/dist/knowledge/trust-metrics.js +138 -0
- package/dist/loop-engineering/diagnose.d.ts +3 -2
- package/dist/loop-engineering/diagnose.js +94 -0
- package/dist/loop-engineering/improve.d.ts +1 -1
- package/dist/loop-engineering/improve.js +52 -1
- package/dist/project/graph.d.ts +71 -0
- package/dist/project/graph.js +314 -0
- package/dist/project/index.d.ts +62 -0
- package/dist/project/index.js +167 -0
- package/dist/project/namespace.d.ts +62 -0
- package/dist/project/namespace.js +181 -0
- package/dist/project/query.d.ts +40 -0
- package/dist/project/query.js +110 -0
- package/dist/safety/confirm-gate.d.ts +15 -0
- package/dist/safety/confirm-gate.js +44 -0
- package/dist/safety/index.d.ts +3 -0
- package/dist/safety/index.js +3 -0
- package/dist/safety/preview.d.ts +2 -0
- package/dist/safety/preview.js +36 -0
- package/dist/schema/call/allocation.d.ts +15 -0
- package/dist/schema/call/arbitration.d.ts +111 -96
- package/dist/schema/call/base.d.ts +1070 -44
- package/dist/schema/call/base.js +69 -1
- package/dist/schema/call/bridge.d.ts +709 -52
- package/dist/schema/call/bridge.js +13 -2
- package/dist/schema/call/contact.d.ts +15 -0
- package/dist/schema/call/demand.d.ts +69 -54
- package/dist/schema/call/guard.d.ts +125 -80
- package/dist/schema/call/handler.d.ts +3 -0
- package/dist/schema/call/handler.js +14 -0
- package/dist/schema/call/machine.d.ts +830 -800
- package/dist/schema/call/order.d.ts +15 -0
- package/dist/schema/call/payment.d.ts +15 -0
- package/dist/schema/call/permission.d.ts +15 -0
- package/dist/schema/call/personal.d.ts +15 -0
- package/dist/schema/call/progress.d.ts +15 -0
- package/dist/schema/call/proof.d.ts +42 -12
- package/dist/schema/call/proof.js +3 -3
- package/dist/schema/call/repository.d.ts +91 -76
- package/dist/schema/call/reward.d.ts +45 -30
- package/dist/schema/call/semantic.d.ts +1 -0
- package/dist/schema/call/semantic.js +217 -0
- package/dist/schema/call/service.d.ts +407 -392
- package/dist/schema/call/treasury.d.ts +15 -0
- package/dist/schema/common/index.js +3 -3
- package/dist/schema/local/index.d.ts +228 -72
- package/dist/schema/local/index.js +33 -6
- package/dist/schema/messenger/index.d.ts +668 -50
- package/dist/schema/messenger/index.js +9 -0
- package/dist/schema/operations.d.ts +1693 -1369
- package/dist/schema/operations.js +2 -2
- package/dist/schema/query/index.d.ts +1614 -1614
- package/dist/schema/query/index.js +30 -27
- package/dist/schemas/account_operation.output.json +25 -16
- package/dist/schemas/account_operation.schema.json +1 -1
- package/dist/schemas/bridge_operation.output.json +520 -0
- package/dist/schemas/bridge_operation.schema.json +15 -0
- package/dist/schemas/guard2file.schema.json +15 -0
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/local_info_operation.output.json +23 -0
- package/dist/schemas/local_info_operation.schema.json +1 -1
- package/dist/schemas/local_mark_operation.output.json +24 -1
- package/dist/schemas/local_mark_operation.schema.json +4 -4
- package/dist/schemas/machineNode2file.schema.json +15 -0
- package/dist/schemas/messenger_operation.output.json +528 -0
- package/dist/schemas/onchain_operations.output.json +350 -16
- package/dist/schemas/onchain_operations.schema.json +96 -23
- package/dist/schemas/onchain_operations_allocation.schema.json +15 -0
- package/dist/schemas/onchain_operations_arbitration.schema.json +15 -0
- package/dist/schemas/onchain_operations_contact.schema.json +15 -0
- package/dist/schemas/onchain_operations_demand.schema.json +15 -0
- package/dist/schemas/onchain_operations_gen_passport.schema.json +30 -0
- package/dist/schemas/onchain_operations_guard.schema.json +15 -0
- package/dist/schemas/onchain_operations_machine.schema.json +81 -23
- package/dist/schemas/onchain_operations_order.schema.json +15 -0
- package/dist/schemas/onchain_operations_payment.schema.json +15 -0
- package/dist/schemas/onchain_operations_permission.schema.json +15 -0
- package/dist/schemas/onchain_operations_personal.schema.json +15 -0
- package/dist/schemas/onchain_operations_progress.schema.json +15 -0
- package/dist/schemas/onchain_operations_repository.schema.json +15 -0
- package/dist/schemas/onchain_operations_reward.schema.json +15 -0
- package/dist/schemas/onchain_operations_service.schema.json +15 -0
- package/dist/schemas/onchain_operations_treasury.schema.json +15 -0
- package/dist/schemas/onchain_table_data.output.json +221 -69
- package/dist/schemas/onchain_table_data.schema.json +2 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5,13 +5,18 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
5
5
|
import { readFileSync } from "fs";
|
|
6
6
|
import { resolve } from "path";
|
|
7
7
|
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
8
|
-
import { MachineNode2File_InputSchema, MachineNode2File_OutputWrappedSchema, Guard2File_InputSchema, Guard2File_OutputWrappedSchema, strictParse, CallOutputSchema, handleCallResult, createServerConfig, createCapabilitiesConfig, createToolMeta, transformSubmission, getEnvConfig, OnchainEventsInputSchema, OnchainEventsResultSchema, ProtocolInfoQuerySchema, ProtocolInfoResultSchema, AccountOperationOutputWrappedSchema, LocalMarkOperationOutputWrappedSchema, LocalInfoOperationOutputWrappedSchema, WipOperationOutputSchema, MessengerOperationOutputSchema, AccountOperationSchema, LocalMarkOperationSchema, LocalInfoOperationSchema, parseMachineNodesFromText, formatNodeErrors as formatMachineNodeErrors, MessengerOperationInputSchema, BridgeOperationsSchema, BridgeCallOutputSchema, OnchainOperationsSchema, WipOperationsSchema, OnchainTableDataSchema, OnchainTableDataResultSchema, WatchQueryOperationsSchema, } from "./schema/index.js";
|
|
8
|
+
import { MachineNode2File_InputSchema, MachineNode2File_OutputWrappedSchema, Guard2File_InputSchema, Guard2File_OutputWrappedSchema, strictParse, CallOutputSchema, handleCallResult, createServerConfig, createCapabilitiesConfig, createToolMeta, transformSubmission, getEnvConfig, OnchainEventsInputSchema, OnchainEventsResultSchema, ProtocolInfoQuerySchema, ProtocolInfoResultSchema, AccountOperationOutputWrappedSchema, LocalMarkOperationOutputWrappedSchema, LocalInfoOperationOutputWrappedSchema, WipOperationOutputSchema, MessengerOperationOutputSchema, AccountOperationSchema, LocalMarkOperationSchema, LocalInfoOperationSchema, parseMachineNodesFromText, formatNodeErrors as formatMachineNodeErrors, MessengerOperationInputSchema, BridgeOperationsSchema, BridgeCallOutputSchema, OnchainOperationsSchema, WipOperationsSchema, OnchainTableDataSchema, OnchainTableDataResultSchema, WatchQueryOperationsSchema, registerSuccessHook, } from "./schema/index.js";
|
|
9
9
|
import { handleBridgeOperations } from "./schema/call/bridge-handler.js";
|
|
10
10
|
import { buildDataSemantic, classifyError } from "./schema/call/semantic.js";
|
|
11
11
|
import { getHarness } from "./harness/index.js";
|
|
12
|
-
|
|
12
|
+
import { confirmGate } from "./safety/confirm-gate.js";
|
|
13
|
+
import { renderPreview } from "./safety/preview.js";
|
|
14
|
+
import { isProjectServiceEnabled, normalize as projectNormalize, observe as projectObserve, queryProjects, queryProjectObjects, queryShareableObjects, queryDependencies, queryReferencedBy, queryPrePublishCheck, queryCrossProjectReferences, queryGraphStats, saveGraph, loadGraph, } from "./project/index.js";
|
|
15
|
+
import { isEnabled as isRuntimeEnabled, listServices, getServiceInfo, toggle as toggleService, setEnabled as setServiceEnabled, reset as resetService, } from "./config/index.js";
|
|
16
|
+
import { validateOperation, hasBlockingViolations, getWarningViolations, } from "./knowledge/index.js";
|
|
17
|
+
const HARNESS_ENABLED = () => isRuntimeEnabled("harness");
|
|
13
18
|
function withHarness(base, operation, intent) {
|
|
14
|
-
if (!HARNESS_ENABLED)
|
|
19
|
+
if (!HARNESS_ENABLED())
|
|
15
20
|
return base;
|
|
16
21
|
try {
|
|
17
22
|
const harness = getHarness();
|
|
@@ -27,6 +32,58 @@ function withHarness(base, operation, intent) {
|
|
|
27
32
|
return base;
|
|
28
33
|
}
|
|
29
34
|
}
|
|
35
|
+
function buildPendingConfirmation(operation_type, data, env) {
|
|
36
|
+
const gate = confirmGate(operation_type, data, env, env?.user_intent_phrases);
|
|
37
|
+
if (gate.pass)
|
|
38
|
+
return { content: [], structuredContent: null };
|
|
39
|
+
const preview = gate.preview;
|
|
40
|
+
const rendered = renderPreview(preview);
|
|
41
|
+
const output = {
|
|
42
|
+
message: rendered,
|
|
43
|
+
result: {
|
|
44
|
+
type: "pending_confirmation",
|
|
45
|
+
preview,
|
|
46
|
+
rule_id: gate.rule_id,
|
|
47
|
+
},
|
|
48
|
+
semantic: {
|
|
49
|
+
intent: `${operation_type}_awaiting_confirmation`,
|
|
50
|
+
status: "pending_input",
|
|
51
|
+
summary: `Operation blocked by ConfirmGate (${gate.level}). Review the preview and re-call with env.confirmed=true to proceed.`,
|
|
52
|
+
next_actions: [
|
|
53
|
+
{
|
|
54
|
+
action: "confirm: re-call the SAME operation with env.confirmed=true",
|
|
55
|
+
reason: `ConfirmGate rule '${gate.rule_id}' matched. The operation was NOT executed.`,
|
|
56
|
+
tool: "onchain_operations",
|
|
57
|
+
priority: "required",
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
warnings: preview.warnings ?? [],
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
content: [{ type: "text", text: rendered }],
|
|
65
|
+
structuredContent: output,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function buildConstraintError(operation_type, violations) {
|
|
69
|
+
const errors = violations.filter((v) => v.severity === "error");
|
|
70
|
+
const errorList = errors.map((v) => ` • [${v.field}] ${v.message}`).join("\n");
|
|
71
|
+
const message = `Pre-call constraint violations for '${operation_type}':\n${errorList}\n\nFix the listed field(s) and retry.`;
|
|
72
|
+
const output = {
|
|
73
|
+
message,
|
|
74
|
+
result: {
|
|
75
|
+
type: "error",
|
|
76
|
+
error: message,
|
|
77
|
+
error_code: "invalid_parameter",
|
|
78
|
+
retryable: false,
|
|
79
|
+
recovery_hint: "Review the constraint violations above and correct the corresponding fields.",
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
content: [{ type: "text", text: message }],
|
|
84
|
+
structuredContent: output,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
30
87
|
import { CallService, CallMachine, CallProgress, CallPermission, CallGuard, CallArbitration, CallRepository, CallContact, CallTreasury, CallReward, CallAllocation, CallPersonal, CallPayment, CallDemand, CallOrder, gen_passport, CallProof, gen_proof, guard2file, parseGuardFile, formatGuardParseErrors, machineNode2file, generateNodeComments, generate_wip, verify_wip, sign_wip, wip2html, account_operation, local_mark_operation, local_info_operation, watch_conversations, send_message, send_file, watch_messages, extract_zip_messages, pull_messages, generate_wts, verify_wts, sign_wts, wts2html, proof_message, mark_messages_as_viewed, mark_conversation_as_viewed, query_local_mark_list, query_account_list, query_local_info_list, query_local_token_list, query_account, GetLocalNamesByAddresses, query_personal, query_objects, query_table, query_tableItem, queryProtocolInfo, query_received, queryTableItem_RepositoryData, queryTableItem_PermissionPerm, queryTableItem_RewardRecord, queryTableItem_DemandPresenter, queryTableItem_TreasuryHistory, queryTableItem_MachineNode, queryTableItem_ProgressHistory, queryTableItem_AddressMark, queryTableItem_EntityRegistrar, queryTableItem_EntityLinker, query_events, blacklist, friendslist, guardlist, settings, AmountType, } from "@wowok/wowok";
|
|
31
88
|
import { areSchemasAvailable, getSchemaIndex, processSchemaQuery, } from "./schema-query/index.js";
|
|
32
89
|
const SERVER_DESCRIPTION = `WoWok MCP Server - Making It Easy for AI Agents to Communicate, Collaborate, Trade, and Trust.
|
|
@@ -141,8 +198,73 @@ import { withTelemetry, setTelemetryEnabled } from "./telemetry/index.js";
|
|
|
141
198
|
if (process.env.WOWOK_TELEMETRY === "false" || process.env.WOWOK_TELEMETRY === "0") {
|
|
142
199
|
setTelemetryEnabled(false);
|
|
143
200
|
}
|
|
144
|
-
function
|
|
145
|
-
|
|
201
|
+
function buildClassifiedErrorResult(base, error, classified) {
|
|
202
|
+
const result = { ...base, error };
|
|
203
|
+
if (classified.error_code !== undefined)
|
|
204
|
+
result.error_code = classified.error_code;
|
|
205
|
+
if (classified.retryable !== undefined)
|
|
206
|
+
result.retryable = classified.retryable;
|
|
207
|
+
if (classified.recovery_hint !== undefined)
|
|
208
|
+
result.recovery_hint = classified.recovery_hint;
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
const statusErrorShape = (error, classified, ctx) => ({
|
|
212
|
+
result: buildClassifiedErrorResult({ status: "error" }, error, classified),
|
|
213
|
+
semantic: buildDataSemantic(undefined, ctx, true, error),
|
|
214
|
+
});
|
|
215
|
+
const operationErrorShape = (error, classified, ctx) => ({
|
|
216
|
+
result: buildClassifiedErrorResult({ operation: "error" }, error, classified),
|
|
217
|
+
semantic: buildDataSemantic(undefined, ctx, true, error),
|
|
218
|
+
});
|
|
219
|
+
const strictStatusErrorShape = (error, _classified, _ctx) => ({
|
|
220
|
+
result: { status: "error", error },
|
|
221
|
+
});
|
|
222
|
+
function reg(name, config, handler, errorShapeBuilder, customTimeoutMs) {
|
|
223
|
+
const timeoutMs = customTimeoutMs ?? 60000;
|
|
224
|
+
const wrappedHandler = wrapHandlerWithErrorShape(handler, timeoutMs, name, errorShapeBuilder);
|
|
225
|
+
server.registerTool(name, config, withTelemetry(name, wrappedHandler));
|
|
226
|
+
}
|
|
227
|
+
function withTimeout(promise, timeoutMs = 30000, operationName = "operation") {
|
|
228
|
+
let timer;
|
|
229
|
+
return Promise.race([
|
|
230
|
+
promise.finally(() => {
|
|
231
|
+
if (timer)
|
|
232
|
+
clearTimeout(timer);
|
|
233
|
+
}),
|
|
234
|
+
new Promise((_, reject) => {
|
|
235
|
+
timer = setTimeout(() => {
|
|
236
|
+
let hint = "";
|
|
237
|
+
if (operationName.includes("messenger")) {
|
|
238
|
+
hint = " This is a messenger network operation. Possible causes: " +
|
|
239
|
+
"(1) messenger server (https://messenger.wowok.net) unreachable, " +
|
|
240
|
+
"(2) no messenger-enabled account configured (use account_operation to set messenger name), " +
|
|
241
|
+
"(3) network connectivity issue. " +
|
|
242
|
+
"Ensure you have a messenger-enabled account and the server is reachable.";
|
|
243
|
+
}
|
|
244
|
+
reject(new Error(`Operation '${operationName}' timed out after ${timeoutMs}ms.${hint}`));
|
|
245
|
+
}, timeoutMs);
|
|
246
|
+
}),
|
|
247
|
+
]);
|
|
248
|
+
}
|
|
249
|
+
function wrapHandlerWithErrorShape(handler, timeoutMs, toolName, errorShapeBuilder) {
|
|
250
|
+
return async (args) => {
|
|
251
|
+
try {
|
|
252
|
+
return await withTimeout(handler(args), timeoutMs, toolName);
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
if (errorShapeBuilder) {
|
|
256
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
257
|
+
const classified = classifyError(errorMessage);
|
|
258
|
+
const ctx = { operation_type: toolName, data: args };
|
|
259
|
+
const structuredContent = errorShapeBuilder(errorMessage, classified, ctx);
|
|
260
|
+
return {
|
|
261
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
262
|
+
structuredContent,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
throw error;
|
|
266
|
+
}
|
|
267
|
+
};
|
|
146
268
|
}
|
|
147
269
|
function convertAmountType(type) {
|
|
148
270
|
if (typeof type === "number")
|
|
@@ -261,6 +383,7 @@ async function handleOnchainTableData(args) {
|
|
|
261
383
|
}
|
|
262
384
|
async function handleOnchainOperations(args) {
|
|
263
385
|
let validated;
|
|
386
|
+
let constraintWarnings = [];
|
|
264
387
|
try {
|
|
265
388
|
if (typeof args === 'object' && args !== null && args.description && !args.operation_type) {
|
|
266
389
|
const hasWrappedParams = typeof args.description === 'string' &&
|
|
@@ -273,6 +396,29 @@ async function handleOnchainOperations(args) {
|
|
|
273
396
|
}
|
|
274
397
|
validated = strictParse(OnchainOperationsSchema, args, "onchain_operations input");
|
|
275
398
|
const env = getEnvConfig(validated.env);
|
|
399
|
+
const gateResult = buildPendingConfirmation(validated.operation_type, validated.data, env);
|
|
400
|
+
if (gateResult.structuredContent) {
|
|
401
|
+
return gateResult;
|
|
402
|
+
}
|
|
403
|
+
const constraintViolations = validateOperation(validated.operation_type, validated.data);
|
|
404
|
+
if (hasBlockingViolations(constraintViolations)) {
|
|
405
|
+
return buildConstraintError(validated.operation_type, constraintViolations);
|
|
406
|
+
}
|
|
407
|
+
constraintWarnings = getWarningViolations(constraintViolations).map((v) => `[PRE-CHECK] ${v.message}`);
|
|
408
|
+
const projectEnvPrefix = env?.project;
|
|
409
|
+
if (isProjectServiceEnabled()) {
|
|
410
|
+
const pn = projectNormalize({
|
|
411
|
+
operation_type: validated.operation_type,
|
|
412
|
+
data: validated.data,
|
|
413
|
+
projectPrefix: projectEnvPrefix,
|
|
414
|
+
});
|
|
415
|
+
validated.data = pn.data;
|
|
416
|
+
}
|
|
417
|
+
if (env && typeof env === "object") {
|
|
418
|
+
delete env.confirmed;
|
|
419
|
+
delete env.user_intent_phrases;
|
|
420
|
+
delete env.project;
|
|
421
|
+
}
|
|
276
422
|
switch (validated.operation_type) {
|
|
277
423
|
case "service": {
|
|
278
424
|
const callService = new CallService(validated.data);
|
|
@@ -281,7 +427,7 @@ async function handleOnchainOperations(args) {
|
|
|
281
427
|
: await callService.call(env);
|
|
282
428
|
const data = validated.data;
|
|
283
429
|
const intent = data?.publish ? "publish service" : data?.bPublished !== undefined ? "modify service" : "create service";
|
|
284
|
-
return handleCallResult(result, withHarness({ operation_type: validated.operation_type, data }, "service", intent));
|
|
430
|
+
return handleCallResult(result, withHarness({ operation_type: validated.operation_type, data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined }, "service", intent));
|
|
285
431
|
}
|
|
286
432
|
case "machine": {
|
|
287
433
|
if (validated.data.node && typeof validated.data.node === 'object' && 'json_or_markdown_file' in validated.data.node) {
|
|
@@ -312,42 +458,42 @@ async function handleOnchainOperations(args) {
|
|
|
312
458
|
const result = validated.submission
|
|
313
459
|
? await callMachine.call_with_submission(env, await transformSubmission(validated.submission))
|
|
314
460
|
: await callMachine.call(env);
|
|
315
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
461
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
316
462
|
}
|
|
317
463
|
case "progress": {
|
|
318
464
|
const callProgress = new CallProgress(validated.data);
|
|
319
465
|
const result = validated.submission
|
|
320
466
|
? await callProgress.call_with_submission(env, await transformSubmission(validated.submission))
|
|
321
467
|
: await callProgress.call(env);
|
|
322
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
468
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
323
469
|
}
|
|
324
470
|
case "repository": {
|
|
325
471
|
const callRepository = new CallRepository(validated.data);
|
|
326
472
|
const result = validated.submission
|
|
327
473
|
? await callRepository.call_with_submission(env, await transformSubmission(validated.submission))
|
|
328
474
|
: await callRepository.call(env);
|
|
329
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
475
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
330
476
|
}
|
|
331
477
|
case "arbitration": {
|
|
332
478
|
const callArbitration = new CallArbitration(validated.data);
|
|
333
479
|
const result = validated.submission
|
|
334
480
|
? await callArbitration.call_with_submission(env, await transformSubmission(validated.submission))
|
|
335
481
|
: await callArbitration.call(env);
|
|
336
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
482
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
337
483
|
}
|
|
338
484
|
case "contact": {
|
|
339
485
|
const callContact = new CallContact(validated.data);
|
|
340
486
|
const result = validated.submission
|
|
341
487
|
? await callContact.call_with_submission(env, await transformSubmission(validated.submission))
|
|
342
488
|
: await callContact.call(env);
|
|
343
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
489
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
344
490
|
}
|
|
345
491
|
case "treasury": {
|
|
346
492
|
const callTreasury = new CallTreasury(validated.data);
|
|
347
493
|
const result = validated.submission
|
|
348
494
|
? await callTreasury.call_with_submission(env, await transformSubmission(validated.submission))
|
|
349
495
|
: await callTreasury.call(env);
|
|
350
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
496
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
351
497
|
}
|
|
352
498
|
case "reward": {
|
|
353
499
|
const transformedData = transformRewardData(validated.data);
|
|
@@ -355,19 +501,19 @@ async function handleOnchainOperations(args) {
|
|
|
355
501
|
const result = validated.submission
|
|
356
502
|
? await callReward.call_with_submission(env, await transformSubmission(validated.submission))
|
|
357
503
|
: await callReward.call(env);
|
|
358
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
504
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
359
505
|
}
|
|
360
506
|
case "allocation": {
|
|
361
507
|
const callAllocation = new CallAllocation(validated.data);
|
|
362
508
|
const result = validated.submission
|
|
363
509
|
? await callAllocation.call_with_submission(env, await transformSubmission(validated.submission))
|
|
364
510
|
: await callAllocation.call(env);
|
|
365
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
511
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
366
512
|
}
|
|
367
513
|
case "permission": {
|
|
368
514
|
const callPermission = new CallPermission(validated.data);
|
|
369
515
|
const result = await callPermission.call(env);
|
|
370
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
516
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
371
517
|
}
|
|
372
518
|
case "guard": {
|
|
373
519
|
const validatedData = validated.data;
|
|
@@ -414,7 +560,7 @@ async function handleOnchainOperations(args) {
|
|
|
414
560
|
}
|
|
415
561
|
const callGuard = new CallGuard(validatedData);
|
|
416
562
|
const result = await callGuard.call(env);
|
|
417
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
563
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
418
564
|
}
|
|
419
565
|
case "personal": {
|
|
420
566
|
const transformPersonalData = (data) => {
|
|
@@ -467,48 +613,48 @@ async function handleOnchainOperations(args) {
|
|
|
467
613
|
const transformedData = transformPersonalData(validated.data);
|
|
468
614
|
const callPersonal = new CallPersonal(transformedData);
|
|
469
615
|
const result = await callPersonal.call(env);
|
|
470
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
616
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
471
617
|
}
|
|
472
618
|
case "payment": {
|
|
473
619
|
const callPayment = new CallPayment(validated.data);
|
|
474
620
|
const result = await callPayment.call(env);
|
|
475
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
621
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
476
622
|
}
|
|
477
623
|
case "demand": {
|
|
478
624
|
const callDemand = new CallDemand(validated.data);
|
|
479
625
|
const result = validated.submission
|
|
480
626
|
? await callDemand.call_with_submission(env, await transformSubmission(validated.submission))
|
|
481
627
|
: await callDemand.call(env);
|
|
482
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
628
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
483
629
|
}
|
|
484
630
|
case "order": {
|
|
485
631
|
const callOrder = new CallOrder(validated.data);
|
|
486
632
|
const result = validated.submission
|
|
487
633
|
? await callOrder.call_with_submission(env, await transformSubmission(validated.submission))
|
|
488
634
|
: await callOrder.call(env);
|
|
489
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
635
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
490
636
|
}
|
|
491
637
|
case "gen_passport": {
|
|
492
638
|
const result = await gen_passport(env, validated.guard, validated.info);
|
|
493
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
639
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
494
640
|
}
|
|
495
641
|
case "proof": {
|
|
496
642
|
const callProof = new CallProof(validated.data);
|
|
497
643
|
const result = validated.submission
|
|
498
644
|
? await callProof.call_with_submission(env, await transformSubmission(validated.submission))
|
|
499
645
|
: await callProof.call(env);
|
|
500
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
646
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
501
647
|
}
|
|
502
648
|
case "gen_proof": {
|
|
503
649
|
const result = await gen_proof(env, validated.proof, validated.server_pubkey, validated.server_signature, validated.proof_type, validated.description, validated.item_count, validated.about_address);
|
|
504
|
-
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data });
|
|
650
|
+
return handleCallResult(result, { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined });
|
|
505
651
|
}
|
|
506
652
|
}
|
|
507
653
|
throw new Error(`Unknown on-chain operation type: ${validated.operation_type}`);
|
|
508
654
|
}
|
|
509
655
|
catch (error) {
|
|
510
656
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
511
|
-
return handleCallResult({ error: errorMessage }, validated ? { operation_type: validated.operation_type, data: validated.data } : undefined);
|
|
657
|
+
return handleCallResult({ error: errorMessage }, validated ? { operation_type: validated.operation_type, data: validated.data, pre_warnings: constraintWarnings.length ? constraintWarnings : undefined } : undefined);
|
|
512
658
|
}
|
|
513
659
|
}
|
|
514
660
|
async function handleAccountOperation(args) {
|
|
@@ -532,16 +678,20 @@ async function handleAccountOperation(args) {
|
|
|
532
678
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
533
679
|
const ctx = validated ? { operation_type: "account_" + validated.operation_type, data: validated } : undefined;
|
|
534
680
|
const classified = classifyError(errorMessage);
|
|
681
|
+
const errorResult = {
|
|
682
|
+
status: "error",
|
|
683
|
+
error: errorMessage,
|
|
684
|
+
};
|
|
685
|
+
if (classified.error_code !== undefined)
|
|
686
|
+
errorResult.error_code = classified.error_code;
|
|
687
|
+
if (classified.retryable !== undefined)
|
|
688
|
+
errorResult.retryable = classified.retryable;
|
|
689
|
+
if (classified.recovery_hint !== undefined)
|
|
690
|
+
errorResult.recovery_hint = classified.recovery_hint;
|
|
535
691
|
return {
|
|
536
692
|
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
537
693
|
structuredContent: {
|
|
538
|
-
result:
|
|
539
|
-
status: "error",
|
|
540
|
-
error: errorMessage,
|
|
541
|
-
error_code: classified.error_code,
|
|
542
|
-
retryable: classified.retryable,
|
|
543
|
-
recovery_hint: classified.recovery_hint,
|
|
544
|
-
},
|
|
694
|
+
result: errorResult,
|
|
545
695
|
semantic: buildDataSemantic(undefined, ctx, true, errorMessage),
|
|
546
696
|
},
|
|
547
697
|
};
|
|
@@ -568,16 +718,17 @@ async function handleMarkOperation(args) {
|
|
|
568
718
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
569
719
|
const ctx = validated ? { operation_type: "mark_" + validated.operation_type, data: validated } : undefined;
|
|
570
720
|
const classified = classifyError(errorMessage);
|
|
721
|
+
const errorResult = { status: "error", error: errorMessage };
|
|
722
|
+
if (classified.error_code !== undefined)
|
|
723
|
+
errorResult.error_code = classified.error_code;
|
|
724
|
+
if (classified.retryable !== undefined)
|
|
725
|
+
errorResult.retryable = classified.retryable;
|
|
726
|
+
if (classified.recovery_hint !== undefined)
|
|
727
|
+
errorResult.recovery_hint = classified.recovery_hint;
|
|
571
728
|
return {
|
|
572
729
|
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
573
730
|
structuredContent: {
|
|
574
|
-
result:
|
|
575
|
-
status: "error",
|
|
576
|
-
error: errorMessage,
|
|
577
|
-
error_code: classified.error_code,
|
|
578
|
-
retryable: classified.retryable,
|
|
579
|
-
recovery_hint: classified.recovery_hint,
|
|
580
|
-
},
|
|
731
|
+
result: errorResult,
|
|
581
732
|
semantic: buildDataSemantic(undefined, ctx, true, errorMessage),
|
|
582
733
|
},
|
|
583
734
|
};
|
|
@@ -604,16 +755,17 @@ async function handleInfoOperation(args) {
|
|
|
604
755
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
605
756
|
const ctx = validated ? { operation_type: "local_info", data: validated } : undefined;
|
|
606
757
|
const classified = classifyError(errorMessage);
|
|
758
|
+
const errorResult = { status: "error", error: errorMessage };
|
|
759
|
+
if (classified.error_code !== undefined)
|
|
760
|
+
errorResult.error_code = classified.error_code;
|
|
761
|
+
if (classified.retryable !== undefined)
|
|
762
|
+
errorResult.retryable = classified.retryable;
|
|
763
|
+
if (classified.recovery_hint !== undefined)
|
|
764
|
+
errorResult.recovery_hint = classified.recovery_hint;
|
|
607
765
|
return {
|
|
608
766
|
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
609
767
|
structuredContent: {
|
|
610
|
-
result:
|
|
611
|
-
status: "error",
|
|
612
|
-
error: errorMessage,
|
|
613
|
-
error_code: classified.error_code,
|
|
614
|
-
retryable: classified.retryable,
|
|
615
|
-
recovery_hint: classified.recovery_hint,
|
|
616
|
-
},
|
|
768
|
+
result: errorResult,
|
|
617
769
|
semantic: buildDataSemantic(undefined, ctx, true, errorMessage),
|
|
618
770
|
},
|
|
619
771
|
};
|
|
@@ -780,168 +932,304 @@ async function handleOnchainEvents(args) {
|
|
|
780
932
|
},
|
|
781
933
|
};
|
|
782
934
|
}
|
|
783
|
-
function
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
return input;
|
|
788
|
-
}
|
|
789
|
-
function normalizeManyAccountOrMark(input) {
|
|
790
|
-
if (Array.isArray(input)) {
|
|
791
|
-
return {
|
|
792
|
-
entities: input.map(item => typeof item === 'string' ? { name_or_address: item, local_mark_first: true } : item),
|
|
793
|
-
check_all_founded: true
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
return input;
|
|
797
|
-
}
|
|
798
|
-
async function handleMessengerOperation(args) {
|
|
799
|
-
const validated = strictParse(MessengerOperationInputSchema, args, "messenger_operation input");
|
|
935
|
+
async function handleProjectOperation(args) {
|
|
936
|
+
const action = args.action;
|
|
937
|
+
const project = args.project;
|
|
938
|
+
const object = args.object;
|
|
800
939
|
let result;
|
|
801
|
-
switch (
|
|
802
|
-
case "
|
|
803
|
-
|
|
804
|
-
result = { operation: "watch_conversations", result: conversations };
|
|
940
|
+
switch (action) {
|
|
941
|
+
case "list_projects":
|
|
942
|
+
result = await queryProjects();
|
|
805
943
|
break;
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
...sendResult,
|
|
811
|
-
merkleData: sendResult.merkleData ? {
|
|
812
|
-
leafIndex: sendResult.merkleData.leafIndex,
|
|
813
|
-
prevRoot: sendResult.merkleData.prevRoot,
|
|
814
|
-
newRoot: sendResult.merkleData.newRoot,
|
|
815
|
-
serverSignature: sendResult.merkleData.serverSignature,
|
|
816
|
-
serverTimestamp: sendResult.merkleData.serverTimestamp,
|
|
817
|
-
serverPublicKey: sendResult.merkleData.serverPublicKey,
|
|
818
|
-
} : undefined,
|
|
819
|
-
};
|
|
820
|
-
result = { operation: "send_message", result: filteredResult };
|
|
944
|
+
case "list_objects":
|
|
945
|
+
if (!project)
|
|
946
|
+
throw new Error("'project' param is required for list_objects");
|
|
947
|
+
result = await queryProjectObjects(project);
|
|
821
948
|
break;
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
const sendResult = await send_file(validated.from, normalizeAccountOrMark(validated.to), validated.filePath, validated.options);
|
|
825
|
-
const filteredResult = {
|
|
826
|
-
...sendResult,
|
|
827
|
-
merkleData: sendResult.merkleData ? {
|
|
828
|
-
leafIndex: sendResult.merkleData.leafIndex,
|
|
829
|
-
prevRoot: sendResult.merkleData.prevRoot,
|
|
830
|
-
newRoot: sendResult.merkleData.newRoot,
|
|
831
|
-
serverSignature: sendResult.merkleData.serverSignature,
|
|
832
|
-
serverTimestamp: sendResult.merkleData.serverTimestamp,
|
|
833
|
-
serverPublicKey: sendResult.merkleData.serverPublicKey,
|
|
834
|
-
} : undefined,
|
|
835
|
-
};
|
|
836
|
-
result = { operation: "send_file", result: filteredResult };
|
|
949
|
+
case "shareable":
|
|
950
|
+
result = await queryShareableObjects();
|
|
837
951
|
break;
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
peerAddress: validated.filter.peerAddress ? normalizeAccountOrMark(validated.filter.peerAddress) : undefined
|
|
843
|
-
} : undefined;
|
|
844
|
-
const messages = await watch_messages(filter);
|
|
845
|
-
result = { operation: "watch_messages", result: messages };
|
|
952
|
+
case "dependencies":
|
|
953
|
+
if (!object)
|
|
954
|
+
throw new Error("'object' param is required for dependencies");
|
|
955
|
+
result = queryDependencies(object);
|
|
846
956
|
break;
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
result =
|
|
957
|
+
case "referenced_by":
|
|
958
|
+
if (!object)
|
|
959
|
+
throw new Error("'object' param is required for referenced_by");
|
|
960
|
+
result = queryReferencedBy(object);
|
|
851
961
|
break;
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
peerAccount: normalizeAccountOrMark(validated.params.peerAccount)
|
|
857
|
-
} : undefined;
|
|
858
|
-
const wtsResult = await generate_wts(params);
|
|
859
|
-
result = { operation: "generate_wts", result: wtsResult };
|
|
962
|
+
case "pre_publish_check":
|
|
963
|
+
if (!object)
|
|
964
|
+
throw new Error("'object' param is required for pre_publish_check");
|
|
965
|
+
result = { warnings: queryPrePublishCheck(object) };
|
|
860
966
|
break;
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
const verifyResult = await verify_wts(validated.wtsFilePath);
|
|
864
|
-
result = { operation: "verify_wts", result: verifyResult };
|
|
967
|
+
case "cross_project_refs":
|
|
968
|
+
result = queryCrossProjectReferences();
|
|
865
969
|
break;
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
const signedPath = await sign_wts(validated.wtsFilePath, validated.account, validated.outputPath);
|
|
869
|
-
result = { operation: "sign_wts", result: signedPath };
|
|
970
|
+
case "graph_stats":
|
|
971
|
+
result = queryGraphStats();
|
|
870
972
|
break;
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
const htmlResult = await wts2html(validated.wtsPath, validated.options);
|
|
874
|
-
result = { operation: "wts2html", result: htmlResult };
|
|
973
|
+
case "save_graph":
|
|
974
|
+
result = { saved: true, path: saveGraph() };
|
|
875
975
|
break;
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
const proofResult = await proof_message(validated.account, validated.messageId, validated.network);
|
|
879
|
-
result = { operation: "proof_message", result: proofResult };
|
|
976
|
+
case "load_graph":
|
|
977
|
+
result = { loaded: loadGraph() };
|
|
880
978
|
break;
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
979
|
+
default:
|
|
980
|
+
throw new Error(`Unknown project_operation action: ${action}`);
|
|
981
|
+
}
|
|
982
|
+
return {
|
|
983
|
+
content: [{ type: "text", text: JSON.stringify({ result }) }],
|
|
984
|
+
structuredContent: { result },
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
async function handleConfigOperation(args) {
|
|
988
|
+
const action = args.action;
|
|
989
|
+
let result;
|
|
990
|
+
switch (action) {
|
|
991
|
+
case "list":
|
|
992
|
+
result = { services: listServices() };
|
|
892
993
|
break;
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
friendslistParams.users = normalizeManyAccountOrMark(validated.friendslist.users);
|
|
994
|
+
case "toggle": {
|
|
995
|
+
const service = args.service;
|
|
996
|
+
if (!service)
|
|
997
|
+
throw new Error("'service' param is required for toggle");
|
|
998
|
+
const validServices = ["confirm_gate", "project_service", "harness", "graph_persist", "semantic_rich"];
|
|
999
|
+
if (!validServices.includes(service)) {
|
|
1000
|
+
throw new Error(`Unknown service: ${service}. Valid: ${validServices.join(", ")}`);
|
|
901
1001
|
}
|
|
902
|
-
const
|
|
903
|
-
|
|
1002
|
+
const newState = toggleService(service);
|
|
1003
|
+
const info = getServiceInfo(service);
|
|
1004
|
+
result = { service, enabled: newState, reminder: info?.reminder };
|
|
904
1005
|
break;
|
|
905
1006
|
}
|
|
906
|
-
case "
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
1007
|
+
case "enable": {
|
|
1008
|
+
const service = args.service;
|
|
1009
|
+
if (!service)
|
|
1010
|
+
throw new Error("'service' param is required for enable");
|
|
1011
|
+
setServiceEnabled(service, true);
|
|
1012
|
+
const info = getServiceInfo(service);
|
|
1013
|
+
result = { service, enabled: true, reminder: info?.reminder };
|
|
912
1014
|
break;
|
|
913
1015
|
}
|
|
914
|
-
case "
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
1016
|
+
case "disable": {
|
|
1017
|
+
const service = args.service;
|
|
1018
|
+
if (!service)
|
|
1019
|
+
throw new Error("'service' param is required for disable");
|
|
1020
|
+
setServiceEnabled(service, false);
|
|
1021
|
+
const info = getServiceInfo(service);
|
|
1022
|
+
result = { service, enabled: false, reminder: info?.reminder };
|
|
920
1023
|
break;
|
|
921
1024
|
}
|
|
922
|
-
case "
|
|
923
|
-
const
|
|
924
|
-
|
|
1025
|
+
case "reset": {
|
|
1026
|
+
const service = args.service;
|
|
1027
|
+
if (!service)
|
|
1028
|
+
throw new Error("'service' param is required for reset");
|
|
1029
|
+
resetService(service);
|
|
1030
|
+
const info = getServiceInfo(service);
|
|
1031
|
+
result = { service, enabled: info?.enabled, reminder: info?.reminder, reset: true };
|
|
925
1032
|
break;
|
|
926
1033
|
}
|
|
927
|
-
case "
|
|
928
|
-
const
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
case "pull_messages": {
|
|
933
|
-
const messages = await pull_messages(validated.account, validated.limit);
|
|
934
|
-
result = { operation: "pull_messages", result: messages };
|
|
1034
|
+
case "info": {
|
|
1035
|
+
const service = args.service;
|
|
1036
|
+
if (!service)
|
|
1037
|
+
throw new Error("'service' param is required for info");
|
|
1038
|
+
result = getServiceInfo(service);
|
|
935
1039
|
break;
|
|
936
1040
|
}
|
|
937
1041
|
default:
|
|
938
|
-
throw new Error(`Unknown
|
|
1042
|
+
throw new Error(`Unknown config_operation action: ${action}`);
|
|
939
1043
|
}
|
|
940
1044
|
return {
|
|
941
|
-
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
1045
|
+
content: [{ type: "text", text: JSON.stringify({ result }) }],
|
|
942
1046
|
structuredContent: { result },
|
|
943
1047
|
};
|
|
944
1048
|
}
|
|
1049
|
+
function normalizeAccountOrMark(input) {
|
|
1050
|
+
if (typeof input === 'string') {
|
|
1051
|
+
return { name_or_address: input, local_mark_first: true };
|
|
1052
|
+
}
|
|
1053
|
+
return input;
|
|
1054
|
+
}
|
|
1055
|
+
function normalizeManyAccountOrMark(input) {
|
|
1056
|
+
if (Array.isArray(input)) {
|
|
1057
|
+
return {
|
|
1058
|
+
entities: input.map(item => typeof item === 'string' ? { name_or_address: item, local_mark_first: true } : item),
|
|
1059
|
+
check_all_founded: true
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
return input;
|
|
1063
|
+
}
|
|
1064
|
+
async function handleMessengerOperation(args) {
|
|
1065
|
+
let validated;
|
|
1066
|
+
try {
|
|
1067
|
+
validated = strictParse(MessengerOperationInputSchema, args, "messenger_operation input");
|
|
1068
|
+
let result;
|
|
1069
|
+
switch (validated.operation) {
|
|
1070
|
+
case "watch_conversations": {
|
|
1071
|
+
const conversations = await watch_conversations(validated.filter);
|
|
1072
|
+
result = { operation: "watch_conversations", result: conversations };
|
|
1073
|
+
break;
|
|
1074
|
+
}
|
|
1075
|
+
case "send_message": {
|
|
1076
|
+
const sendResult = await send_message(validated.from, normalizeAccountOrMark(validated.to), validated.content, validated.options);
|
|
1077
|
+
const filteredResult = {
|
|
1078
|
+
...sendResult,
|
|
1079
|
+
merkleData: sendResult.merkleData ? {
|
|
1080
|
+
leafIndex: sendResult.merkleData.leafIndex,
|
|
1081
|
+
prevRoot: sendResult.merkleData.prevRoot,
|
|
1082
|
+
newRoot: sendResult.merkleData.newRoot,
|
|
1083
|
+
serverSignature: sendResult.merkleData.serverSignature,
|
|
1084
|
+
serverTimestamp: sendResult.merkleData.serverTimestamp,
|
|
1085
|
+
serverPublicKey: sendResult.merkleData.serverPublicKey,
|
|
1086
|
+
} : undefined,
|
|
1087
|
+
};
|
|
1088
|
+
result = { operation: "send_message", result: filteredResult };
|
|
1089
|
+
break;
|
|
1090
|
+
}
|
|
1091
|
+
case "send_file": {
|
|
1092
|
+
const sendResult = await send_file(validated.from, normalizeAccountOrMark(validated.to), validated.filePath, validated.options);
|
|
1093
|
+
const filteredResult = {
|
|
1094
|
+
...sendResult,
|
|
1095
|
+
merkleData: sendResult.merkleData ? {
|
|
1096
|
+
leafIndex: sendResult.merkleData.leafIndex,
|
|
1097
|
+
prevRoot: sendResult.merkleData.prevRoot,
|
|
1098
|
+
newRoot: sendResult.merkleData.newRoot,
|
|
1099
|
+
serverSignature: sendResult.merkleData.serverSignature,
|
|
1100
|
+
serverTimestamp: sendResult.merkleData.serverTimestamp,
|
|
1101
|
+
serverPublicKey: sendResult.merkleData.serverPublicKey,
|
|
1102
|
+
} : undefined,
|
|
1103
|
+
};
|
|
1104
|
+
result = { operation: "send_file", result: filteredResult };
|
|
1105
|
+
break;
|
|
1106
|
+
}
|
|
1107
|
+
case "watch_messages": {
|
|
1108
|
+
const filter = validated.filter ? {
|
|
1109
|
+
...validated.filter,
|
|
1110
|
+
peerAddress: validated.filter.peerAddress ? normalizeAccountOrMark(validated.filter.peerAddress) : undefined
|
|
1111
|
+
} : undefined;
|
|
1112
|
+
const messages = await watch_messages(filter);
|
|
1113
|
+
result = { operation: "watch_messages", result: messages };
|
|
1114
|
+
break;
|
|
1115
|
+
}
|
|
1116
|
+
case "extract_zip_messages": {
|
|
1117
|
+
const extractedPaths = await extract_zip_messages(validated.account, validated.messages, validated.outputDir);
|
|
1118
|
+
result = { operation: "extract_zip_messages", result: extractedPaths };
|
|
1119
|
+
break;
|
|
1120
|
+
}
|
|
1121
|
+
case "generate_wts": {
|
|
1122
|
+
const params = validated.params ? {
|
|
1123
|
+
...validated.params,
|
|
1124
|
+
peerAccount: normalizeAccountOrMark(validated.params.peerAccount)
|
|
1125
|
+
} : undefined;
|
|
1126
|
+
const wtsResult = await generate_wts(params);
|
|
1127
|
+
result = { operation: "generate_wts", result: wtsResult };
|
|
1128
|
+
break;
|
|
1129
|
+
}
|
|
1130
|
+
case "verify_wts": {
|
|
1131
|
+
const verifyResult = await verify_wts(validated.wtsFilePath);
|
|
1132
|
+
result = { operation: "verify_wts", result: verifyResult };
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
case "sign_wts": {
|
|
1136
|
+
const signedPath = await sign_wts(validated.wtsFilePath, validated.account, validated.outputPath);
|
|
1137
|
+
result = { operation: "sign_wts", result: signedPath };
|
|
1138
|
+
break;
|
|
1139
|
+
}
|
|
1140
|
+
case "wts2html": {
|
|
1141
|
+
const htmlResult = await wts2html(validated.wtsPath, validated.options);
|
|
1142
|
+
result = { operation: "wts2html", result: htmlResult };
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
case "proof_message": {
|
|
1146
|
+
const proofResult = await proof_message(validated.account, validated.messageId, validated.network);
|
|
1147
|
+
result = { operation: "proof_message", result: proofResult };
|
|
1148
|
+
break;
|
|
1149
|
+
}
|
|
1150
|
+
case "blacklist": {
|
|
1151
|
+
const blacklistParams = {
|
|
1152
|
+
account: validated.account,
|
|
1153
|
+
op: validated.blacklist.op
|
|
1154
|
+
};
|
|
1155
|
+
if ('users' in validated.blacklist) {
|
|
1156
|
+
blacklistParams.users = normalizeManyAccountOrMark(validated.blacklist.users);
|
|
1157
|
+
}
|
|
1158
|
+
const blacklistResult = await blacklist(blacklistParams);
|
|
1159
|
+
result = { operation: "blacklist", op: validated.blacklist.op, result: blacklistResult.result };
|
|
1160
|
+
break;
|
|
1161
|
+
}
|
|
1162
|
+
case "friendslist": {
|
|
1163
|
+
const friendslistParams = {
|
|
1164
|
+
account: validated.account,
|
|
1165
|
+
op: validated.friendslist.op
|
|
1166
|
+
};
|
|
1167
|
+
if ('users' in validated.friendslist) {
|
|
1168
|
+
friendslistParams.users = normalizeManyAccountOrMark(validated.friendslist.users);
|
|
1169
|
+
}
|
|
1170
|
+
const friendslistResult = await friendslist(friendslistParams);
|
|
1171
|
+
result = { operation: "friendslist", op: validated.friendslist.op, result: friendslistResult.result };
|
|
1172
|
+
break;
|
|
1173
|
+
}
|
|
1174
|
+
case "guardlist": {
|
|
1175
|
+
const guardlistResult = await guardlist({
|
|
1176
|
+
account: validated.account,
|
|
1177
|
+
...validated.guardlist
|
|
1178
|
+
});
|
|
1179
|
+
result = { operation: "guardlist", op: validated.guardlist.op, result: guardlistResult.result };
|
|
1180
|
+
break;
|
|
1181
|
+
}
|
|
1182
|
+
case "settings": {
|
|
1183
|
+
const settingsResult = await settings({
|
|
1184
|
+
account: validated.account,
|
|
1185
|
+
...validated.settings
|
|
1186
|
+
});
|
|
1187
|
+
result = { operation: "settings", op: validated.settings.op, result: settingsResult.result };
|
|
1188
|
+
break;
|
|
1189
|
+
}
|
|
1190
|
+
case "mark_messages_as_viewed": {
|
|
1191
|
+
const markedCount = await mark_messages_as_viewed(validated.messageIds, validated.account);
|
|
1192
|
+
result = { operation: "mark_messages_as_viewed", result: markedCount };
|
|
1193
|
+
break;
|
|
1194
|
+
}
|
|
1195
|
+
case "mark_conversation_as_viewed": {
|
|
1196
|
+
const markedCount = await mark_conversation_as_viewed(normalizeAccountOrMark(validated.peerAddress), validated.account);
|
|
1197
|
+
result = { operation: "mark_conversation_as_viewed", result: markedCount };
|
|
1198
|
+
break;
|
|
1199
|
+
}
|
|
1200
|
+
case "pull_messages": {
|
|
1201
|
+
const messages = await pull_messages(validated.account, validated.limit);
|
|
1202
|
+
result = { operation: "pull_messages", result: messages };
|
|
1203
|
+
break;
|
|
1204
|
+
}
|
|
1205
|
+
default:
|
|
1206
|
+
throw new Error(`Unknown messenger operation: ${validated.operation}`);
|
|
1207
|
+
}
|
|
1208
|
+
return {
|
|
1209
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
1210
|
+
structuredContent: { result },
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
catch (error) {
|
|
1214
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1215
|
+
const ctx = validated ? { operation_type: "messenger_" + validated.operation, data: validated } : undefined;
|
|
1216
|
+
const classified = classifyError(errorMessage);
|
|
1217
|
+
const errorResult = { operation: "error", error: errorMessage };
|
|
1218
|
+
if (classified.error_code !== undefined)
|
|
1219
|
+
errorResult.error_code = classified.error_code;
|
|
1220
|
+
if (classified.retryable !== undefined)
|
|
1221
|
+
errorResult.retryable = classified.retryable;
|
|
1222
|
+
if (classified.recovery_hint !== undefined)
|
|
1223
|
+
errorResult.recovery_hint = classified.recovery_hint;
|
|
1224
|
+
return {
|
|
1225
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
1226
|
+
structuredContent: {
|
|
1227
|
+
result: errorResult,
|
|
1228
|
+
semantic: buildDataSemantic(undefined, ctx, true, errorMessage),
|
|
1229
|
+
},
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
945
1233
|
async function handleGuard2File(args) {
|
|
946
1234
|
const validated = strictParse(Guard2File_InputSchema, args, "guard2file input");
|
|
947
1235
|
const env = getEnvConfig(validated.env);
|
|
@@ -980,6 +1268,24 @@ async function handleMachineNode2File(args) {
|
|
|
980
1268
|
const env = getEnvConfig(validated.env);
|
|
981
1269
|
try {
|
|
982
1270
|
await machineNode2file(validated.machine, validated.file_path, validated.format || "json", env.network);
|
|
1271
|
+
let node_count = undefined;
|
|
1272
|
+
try {
|
|
1273
|
+
const filePath = resolve(validated.file_path);
|
|
1274
|
+
const fileContent = await import('fs/promises').then(fs => fs.readFile(filePath, 'utf-8'));
|
|
1275
|
+
if ((validated.format || "json") === "json") {
|
|
1276
|
+
const parsed = JSON.parse(fileContent);
|
|
1277
|
+
if (Array.isArray(parsed)) {
|
|
1278
|
+
node_count = parsed.length;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
else {
|
|
1282
|
+
const nodeMatches = fileContent.match(/^##\s+Node:/gm);
|
|
1283
|
+
node_count = nodeMatches ? nodeMatches.length : 0;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
catch {
|
|
1287
|
+
node_count = undefined;
|
|
1288
|
+
}
|
|
983
1289
|
const result = {
|
|
984
1290
|
result: {
|
|
985
1291
|
status: "success",
|
|
@@ -987,10 +1293,12 @@ async function handleMachineNode2File(args) {
|
|
|
987
1293
|
file_path: resolve(validated.file_path),
|
|
988
1294
|
format: validated.format || "json",
|
|
989
1295
|
machine_object: validated.machine,
|
|
990
|
-
node_count: 0,
|
|
991
1296
|
},
|
|
992
1297
|
},
|
|
993
1298
|
};
|
|
1299
|
+
if (node_count !== undefined) {
|
|
1300
|
+
result.result.data.node_count = node_count;
|
|
1301
|
+
}
|
|
994
1302
|
return {
|
|
995
1303
|
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
996
1304
|
structuredContent: result,
|
|
@@ -1020,6 +1328,16 @@ async function main() {
|
|
|
1020
1328
|
else {
|
|
1021
1329
|
console.error("Schema files not available. Run 'npm run generate:schemas' to generate them.");
|
|
1022
1330
|
}
|
|
1331
|
+
if (isProjectServiceEnabled()) {
|
|
1332
|
+
registerSuccessHook((result, context) => {
|
|
1333
|
+
if (context?.operation_type && context?.data) {
|
|
1334
|
+
projectObserve(context.operation_type, context.data, result);
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
console.error("ProjectService enabled — object graph observe active");
|
|
1338
|
+
}
|
|
1339
|
+
const activeServices = listServices().filter((s) => s.enabled).map((s) => s.name);
|
|
1340
|
+
console.error(`Phase 2 active services: ${activeServices.join(", ") || "none"}`);
|
|
1023
1341
|
reg("onchain_operations", {
|
|
1024
1342
|
title: "⛓️ On-chain Operations",
|
|
1025
1343
|
description: "On-chain operations for WoWok object: service (marketplace listings), machine (workflow templates), progress (order tracking), repository (on-chain database), arbitration (dispute resolution), contact (IM management), treasury (team funds), reward (incentive pools), allocation (auto-distribution), permission (access control), guard (programmable trust rules), personal (public profile), payment (direct coin transfers), demand (service requests), order (order management), gen_passport (verified credentials), proof (on-chain proof objects), gen_proof (generate proof shortcut).",
|
|
@@ -1035,7 +1353,7 @@ async function main() {
|
|
|
1035
1353
|
outputSchema: AccountOperationOutputWrappedSchema,
|
|
1036
1354
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
1037
1355
|
_meta: createToolMeta("operation", ["account", "local", "private", "wallet", "off-chain"]),
|
|
1038
|
-
}, handleAccountOperation);
|
|
1356
|
+
}, handleAccountOperation, statusErrorShape);
|
|
1039
1357
|
reg("local_mark_operation", {
|
|
1040
1358
|
title: "🔒 LOCAL ONLY: LocalMark - Address Book Management",
|
|
1041
1359
|
description: "100% LOCAL, NEVER ON-CHAIN 🔒 Manage ID names and tags stored ONLY on your local device for easy identification of user address or object IDs by name.",
|
|
@@ -1043,7 +1361,7 @@ async function main() {
|
|
|
1043
1361
|
outputSchema: LocalMarkOperationOutputWrappedSchema,
|
|
1044
1362
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
1045
1363
|
_meta: createToolMeta("operation", ["mark", "local", "private", "address-book", "off-chain"]),
|
|
1046
|
-
}, handleMarkOperation);
|
|
1364
|
+
}, handleMarkOperation, statusErrorShape);
|
|
1047
1365
|
reg("local_info_operation", {
|
|
1048
1366
|
title: "🔒 LOCAL ONLY: LocalInfo - Private Data Management",
|
|
1049
1367
|
description: "100% LOCAL, NEVER ON-CHAIN 🔒 Manage sensitive personal information stored ONLY on your device: delivery addresses, phone numbers, contacts.",
|
|
@@ -1051,7 +1369,7 @@ async function main() {
|
|
|
1051
1369
|
outputSchema: LocalInfoOperationOutputWrappedSchema,
|
|
1052
1370
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
1053
1371
|
_meta: createToolMeta("operation", ["info", "local", "private", "data-management", "off-chain"]),
|
|
1054
|
-
}, handleInfoOperation);
|
|
1372
|
+
}, handleInfoOperation, statusErrorShape);
|
|
1055
1373
|
reg("wip_file", {
|
|
1056
1374
|
title: "🤝 Witness Immutable Promise File Operations",
|
|
1057
1375
|
description: "generate (create WIP files from markdown and images), verify (integrity check), sign (add signatures), or wip2html (convert to HTML).",
|
|
@@ -1069,7 +1387,7 @@ async function main() {
|
|
|
1069
1387
|
outputSchema: MessengerOperationOutputSchema,
|
|
1070
1388
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
1071
1389
|
_meta: createToolMeta("operation", ["messenger", "message", "file", "wts", "blacklist", "friendslist", "guardlist", "settings", "proof", "communication"]),
|
|
1072
|
-
}, handleMessengerOperation);
|
|
1390
|
+
}, handleMessengerOperation, operationErrorShape, 30000);
|
|
1073
1391
|
reg("guard2file", {
|
|
1074
1392
|
title: "📄 Guard to File - Export Guard Definition",
|
|
1075
1393
|
description: "Export a Guard object's definition from the blockchain to a local JSON or Markdown file for editing and creating new Guard objects. Note: To query on-chain object information, use the 'query_toolkit' tool instead.",
|
|
@@ -1077,7 +1395,7 @@ async function main() {
|
|
|
1077
1395
|
outputSchema: Guard2File_OutputWrappedSchema,
|
|
1078
1396
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
1079
1397
|
_meta: createToolMeta("generate file", ["guard", "export", "file", "json", "markdown", "on-chain"]),
|
|
1080
|
-
}, handleGuard2File);
|
|
1398
|
+
}, handleGuard2File, strictStatusErrorShape);
|
|
1081
1399
|
reg("machineNode2file", {
|
|
1082
1400
|
title: "⚙️ Machine Node to File - Export Machine Node Definition",
|
|
1083
1401
|
description: "Export a Machine object's node definition from the blockchain to a local JSON or Markdown file for editing and creating new Machine objects. Note: To query on-chain object information, use the 'query_toolkit' tool instead.",
|
|
@@ -1085,7 +1403,7 @@ async function main() {
|
|
|
1085
1403
|
outputSchema: MachineNode2File_OutputWrappedSchema,
|
|
1086
1404
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
1087
1405
|
_meta: createToolMeta("generate file", ["machine", "export", "file", "json", "markdown", "on-chain", "workflow"]),
|
|
1088
|
-
}, handleMachineNode2File);
|
|
1406
|
+
}, handleMachineNode2File, strictStatusErrorShape);
|
|
1089
1407
|
reg("query_toolkit", {
|
|
1090
1408
|
title: "🔍 Data Query Toolkit",
|
|
1091
1409
|
description: "WOWOK data query toolkit — 9 query types covering local device data and on-chain blockchain data:\n\n"
|
|
@@ -1103,7 +1421,8 @@ async function main() {
|
|
|
1103
1421
|
+ "For dynamic table data queries (pagination, table items), use the 'onchain_table_data' tool.",
|
|
1104
1422
|
inputSchema: WatchQueryOperationsSchema,
|
|
1105
1423
|
outputSchema: z.object({
|
|
1106
|
-
result: z.
|
|
1424
|
+
result: z.unknown().describe("Query result — type depends on query_type. Local queries return arrays (MarkData[], AccountData[], InfoData[], TokenTypeInfo[]). account_balance returns { address, balance? | coin? }. Onchain queries return typed objects or undefined. onchain_received returns ReceivedBalance | ReceivedNormal[]."),
|
|
1425
|
+
semantic: z.unknown().optional().describe("Business semantic summary for the query operation"),
|
|
1107
1426
|
}),
|
|
1108
1427
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
1109
1428
|
_meta: createToolMeta("query", ["watch", "query", "on-chain", "local", "events", "objects", "tokens", "balance", "profile"]),
|
|
@@ -1285,6 +1604,71 @@ async function main() {
|
|
|
1285
1604
|
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
1286
1605
|
_meta: createToolMeta("operation", ["bridge", "cross-chain", "evm", "ethereum", "wow", "transfer", "rpc"]),
|
|
1287
1606
|
}, handleBridgeOperations);
|
|
1607
|
+
reg("project_operation", {
|
|
1608
|
+
title: "🗂️ Project - Namespace & Object Graph",
|
|
1609
|
+
description: "Phase 2 project namespace service — manage and query the local object dependency graph (DAG) " +
|
|
1610
|
+
"built on top of local_mark tags. No on-chain writes; all data comes from local marks tagged " +
|
|
1611
|
+
"`project:<prefix>` (auto-injected by the ProjectService when enabled, default ON).\n\n" +
|
|
1612
|
+
"Actions:\n" +
|
|
1613
|
+
" • list_projects — List all discovered projects (grouped by `project:<prefix>` tag) with object counts.\n" +
|
|
1614
|
+
" • list_objects — List objects in a project (requires `project` param).\n" +
|
|
1615
|
+
" • shareable — List objects tagged `shareable:true` (cross-project reusable: common Permission, 3rd-party Arb).\n" +
|
|
1616
|
+
" • dependencies — Trace forward dependencies of an object (BFS transitive closure + dangling refs).\n" +
|
|
1617
|
+
" • referenced_by — Reverse query: who references this object?\n" +
|
|
1618
|
+
" • pre_publish_check — Pre-publish sanity check for a service (dangling deps + cycles).\n" +
|
|
1619
|
+
" • cross_project_refs — Find edges that cross project boundaries.\n" +
|
|
1620
|
+
" • graph_stats — Graph statistics (node/edge counts, cycles, dangling deps).\n" +
|
|
1621
|
+
" • save_graph — Save the in-memory graph to ~/.wowok/project-graph.json (persist across sessions).\n" +
|
|
1622
|
+
" • load_graph — Load the graph from file (restore after restart).\n\n" +
|
|
1623
|
+
"NOTE: The graph is in-memory by default. Use save_graph/load_graph for cross-session persistence " +
|
|
1624
|
+
"(or toggle graph_persist via config_operation for auto-save). " +
|
|
1625
|
+
"list_projects/shareable always query local_mark (persistent).",
|
|
1626
|
+
inputSchema: z.object({
|
|
1627
|
+
action: z.enum([
|
|
1628
|
+
"list_projects", "list_objects", "shareable",
|
|
1629
|
+
"dependencies", "referenced_by", "pre_publish_check",
|
|
1630
|
+
"cross_project_refs", "graph_stats",
|
|
1631
|
+
"save_graph", "load_graph",
|
|
1632
|
+
]).describe("Query/action to perform"),
|
|
1633
|
+
project: z.string().optional().describe("Project prefix (for list_objects)"),
|
|
1634
|
+
object: z.string().optional().describe("Object name or address (for dependencies / referenced_by / pre_publish_check)"),
|
|
1635
|
+
}),
|
|
1636
|
+
outputSchema: z.object({
|
|
1637
|
+
result: z.any().describe("Query result — shape depends on action"),
|
|
1638
|
+
}),
|
|
1639
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
1640
|
+
_meta: createToolMeta("project", ["project", "namespace", "graph", "dag", "dependency", "reference", "organization"]),
|
|
1641
|
+
}, handleProjectOperation);
|
|
1642
|
+
reg("config_operation", {
|
|
1643
|
+
title: "⚙️ Config - Runtime Service Toggles",
|
|
1644
|
+
description: "Phase 2 runtime configuration — toggle Phase 2 services on/off at runtime WITHOUT restarting the MCP server. " +
|
|
1645
|
+
"This is the session-level switch mechanism: AI can toggle based on user conversation context, or users can " +
|
|
1646
|
+
"directly control which Phase 2 features are active.\n\n" +
|
|
1647
|
+
"Actions:\n" +
|
|
1648
|
+
" • list — List all services with current state + reminders.\n" +
|
|
1649
|
+
" • toggle — Toggle a service on/off (requires `service` param). Returns reminder text.\n" +
|
|
1650
|
+
" • enable — Enable a service (requires `service` param).\n" +
|
|
1651
|
+
" • disable — Disable a service (requires `service` param).\n" +
|
|
1652
|
+
" • reset — Reset a service to its default (requires `service` param).\n" +
|
|
1653
|
+
" • info — Get detailed info about a service (requires `service` param).\n\n" +
|
|
1654
|
+
"Services:\n" +
|
|
1655
|
+
" • confirm_gate — Safety Confirmation Gate (default ON)\n" +
|
|
1656
|
+
" • project_service — Project Namespace + Dependency Graph (default ON)\n" +
|
|
1657
|
+
" • harness — L4 Verify/Recover Loop (default OFF)\n" +
|
|
1658
|
+
" • graph_persist — Graph Persistence to File (default OFF)\n" +
|
|
1659
|
+
" • semantic_rich — Semantic Layer Enrichment Reminder (default ON)\n\n" +
|
|
1660
|
+
"NOTE: Toggles persist for the MCP process lifetime. Set WOWOK_RUNTIME_CONFIG_PERSIST=1 " +
|
|
1661
|
+
"to persist across sessions to ~/.wowok/runtime-config.json.",
|
|
1662
|
+
inputSchema: z.object({
|
|
1663
|
+
action: z.enum(["list", "toggle", "enable", "disable", "reset", "info"]).describe("Config action to perform"),
|
|
1664
|
+
service: z.string().optional().describe("Service name (required for toggle/enable/disable/reset/info)"),
|
|
1665
|
+
}),
|
|
1666
|
+
outputSchema: z.object({
|
|
1667
|
+
result: z.any().describe("Config result — shape depends on action"),
|
|
1668
|
+
}),
|
|
1669
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
1670
|
+
_meta: createToolMeta("config", ["config", "toggle", "service", "runtime", "switch", "enable", "disable"]),
|
|
1671
|
+
}, handleConfigOperation);
|
|
1288
1672
|
const transport = new StdioServerTransport();
|
|
1289
1673
|
await server.connect(transport);
|
|
1290
1674
|
process.on("SIGINT", async () => {
|