@wowok/agent-mcp 2.6.1 → 2.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/customer/info-puzzle.d.ts +1 -1
  2. package/dist/customer/info-puzzle.js +4 -2
  3. package/dist/customer/risk-assessment.js +26 -4
  4. package/dist/customer/types.d.ts +2 -0
  5. package/dist/examples/guard-template-balance-check.json +38 -0
  6. package/dist/examples/guard-template-time-lock.json +39 -0
  7. package/dist/examples/machine-template-7node-rental.json +114 -0
  8. package/dist/examples/rental-ziroom-machine-create.json +137 -0
  9. package/dist/examples/rental-ziroom-permission-create.json +35 -0
  10. package/dist/examples/rental-ziroom-service-create.json +80 -0
  11. package/dist/examples/retail-myshop-service-create.json +88 -0
  12. package/dist/extensions/capability-manifest.js +24 -24
  13. package/dist/extensions/constraint-registry.js +18 -18
  14. package/dist/extensions/metric-registry.js +14 -14
  15. package/dist/extensions/mode-evaluator.js +16 -16
  16. package/dist/extensions/modes.js +131 -45
  17. package/dist/extensions/registry.d.ts +2 -0
  18. package/dist/extensions/registry.js +63 -30
  19. package/dist/extensions/types.d.ts +1 -0
  20. package/dist/index.js +50 -0
  21. package/dist/knowledge/deployment-scanner.js +1 -1
  22. package/dist/knowledge/fund-layer.d.ts +72 -0
  23. package/dist/knowledge/fund-layer.js +420 -0
  24. package/dist/knowledge/guard-render.d.ts +57 -0
  25. package/dist/knowledge/guard-render.js +700 -0
  26. package/dist/knowledge/guard-submission-prompt.d.ts +31 -0
  27. package/dist/knowledge/guard-submission-prompt.js +171 -0
  28. package/dist/knowledge/machine-ledger.js +1 -1
  29. package/dist/knowledge/machine-render.d.ts +41 -0
  30. package/dist/knowledge/machine-render.js +565 -0
  31. package/dist/knowledge/machine-templates.js +4 -4
  32. package/dist/knowledge/reward-confirm.js +2 -2
  33. package/dist/knowledge/reward-puzzle.js +1 -1
  34. package/dist/knowledge/reward-risk.js +9 -9
  35. package/dist/knowledge/reward-templates.js +2 -2
  36. package/dist/knowledge/service-confirm.d.ts +1 -1
  37. package/dist/knowledge/service-confirm.js +3 -3
  38. package/dist/knowledge/service-context.js +1 -1
  39. package/dist/knowledge/service-ledger.js +1 -1
  40. package/dist/knowledge/service-risk.d.ts +1 -1
  41. package/dist/knowledge/service-risk.js +3 -3
  42. package/dist/knowledge/service-templates.js +2 -2
  43. package/dist/knowledge/service-translation.d.ts +1 -1
  44. package/dist/knowledge/service-translation.js +7 -7
  45. package/dist/project/deployment-bridge.js +6 -5
  46. package/dist/project/deployment-doc.js +5 -5
  47. package/dist/project/edit-planner.d.ts +123 -0
  48. package/dist/project/edit-planner.js +1371 -0
  49. package/dist/project/evaluation.js +314 -14
  50. package/dist/project/graph-builder.js +6 -1
  51. package/dist/project/handlers.d.ts +99 -2
  52. package/dist/project/handlers.js +358 -16
  53. package/dist/project/stage-gate.js +4 -4
  54. package/dist/schema/call/allocation.js +2 -2
  55. package/dist/schema/call/arbitration.js +19 -6
  56. package/dist/schema/call/contact.js +2 -2
  57. package/dist/schema/call/demand.js +2 -2
  58. package/dist/schema/call/guard.js +1 -1
  59. package/dist/schema/call/machine.d.ts +1975 -777
  60. package/dist/schema/call/machine.js +50 -4
  61. package/dist/schema/call/order.js +3 -6
  62. package/dist/schema/call/permission.js +2 -2
  63. package/dist/schema/call/repository.js +2 -2
  64. package/dist/schema/call/reward.js +3 -3
  65. package/dist/schema/call/semantic.js +7 -1
  66. package/dist/schema/call/service.d.ts +180 -8
  67. package/dist/schema/call/service.js +82 -27
  68. package/dist/schema/call/treasury.js +3 -3
  69. package/dist/schema/common/index.d.ts +2 -0
  70. package/dist/schema/common/index.js +46 -10
  71. package/dist/schema/local/index.js +5 -1
  72. package/dist/schema/operations.d.ts +755 -176
  73. package/dist/schema/operations.js +43 -7
  74. package/dist/schema/project/index.d.ts +969 -6
  75. package/dist/schema/project/index.js +268 -4
  76. package/dist/schema/query/index.d.ts +217 -0
  77. package/dist/schema/query/index.js +63 -33
  78. package/dist/schema/schema-query/index.d.ts +53 -3
  79. package/dist/schema/schema-query/index.js +17 -2
  80. package/dist/schema/utils/node-parser.js +13 -0
  81. package/dist/schema/utils/object-type-utils.d.ts +12 -0
  82. package/dist/schema/utils/object-type-utils.js +35 -0
  83. package/dist/schema/utils/permission-machine-check.d.ts +49 -0
  84. package/dist/schema/utils/permission-machine-check.js +121 -0
  85. package/dist/schema/utils/skills-recommendation.d.ts +2 -0
  86. package/dist/schema/utils/skills-recommendation.js +76 -0
  87. package/dist/schema-query/index.d.ts +14 -1
  88. package/dist/schema-query/index.js +104 -2
  89. package/dist/schemas/account_operation.schema.json +1 -1
  90. package/dist/schemas/index.json +1 -1
  91. package/dist/schemas/onchain_events.output.json +1 -1
  92. package/dist/schemas/onchain_operations.output.json +2820 -0
  93. package/dist/schemas/onchain_operations.schema.json +115 -53
  94. package/dist/schemas/onchain_operations_allocation.schema.json +5 -5
  95. package/dist/schemas/onchain_operations_arbitration.schema.json +9 -7
  96. package/dist/schemas/onchain_operations_contact.schema.json +3 -3
  97. package/dist/schemas/onchain_operations_demand.schema.json +3 -3
  98. package/dist/schemas/onchain_operations_gen_passport.schema.json +2 -2
  99. package/dist/schemas/onchain_operations_guard.schema.json +1 -1
  100. package/dist/schemas/onchain_operations_machine.schema.json +4 -4
  101. package/dist/schemas/onchain_operations_order.schema.json +3 -3
  102. package/dist/schemas/onchain_operations_payment.schema.json +1 -1
  103. package/dist/schemas/onchain_operations_permission.schema.json +2 -2
  104. package/dist/schemas/onchain_operations_progress.schema.json +1 -1
  105. package/dist/schemas/onchain_operations_proof.schema.json +1 -1
  106. package/dist/schemas/onchain_operations_repository.schema.json +3 -3
  107. package/dist/schemas/onchain_operations_reward.schema.json +6 -6
  108. package/dist/schemas/onchain_operations_service.schema.json +77 -17
  109. package/dist/schemas/onchain_operations_treasury.schema.json +4 -4
  110. package/dist/schemas/onchain_table_data.output.json +1 -1
  111. package/dist/schemas/onchain_table_data.schema.json +10 -9
  112. package/dist/schemas/project_operation.output.json +1026 -7
  113. package/dist/schemas/project_operation.schema.json +46 -4
  114. package/dist/schemas/query_toolkit.output.json +15 -15
  115. package/dist/schemas/query_toolkit.schema.json +3 -3
  116. package/dist/schemas/schema_query.output.json +64 -1
  117. package/dist/schemas/schema_query.schema.json +3 -2
  118. package/dist/schemas/wowok_buildin_info.output.json +81 -8
  119. package/dist/schemas/wowok_buildin_info.schema.json +46 -2
  120. package/dist/tools/handlers/onchain.js +571 -6
  121. package/dist/tools/handlers/project.js +25 -2
  122. package/dist/tools/handlers/schema-query.js +24 -1
  123. package/dist/tools/index.d.ts +8 -0
  124. package/dist/tools/index.js +177 -6
  125. package/package.json +2 -2
@@ -3,6 +3,9 @@ import { GraphBuilder } from "./graph-builder.js";
3
3
  import { SemanticAssembler } from "./semantic-assembler.js";
4
4
  import { runEvaluation, compareProjects, } from "./evaluation.js";
5
5
  import { TaskTracker } from "./task-tracker.js";
6
+ import { renderGuardMermaid, renderGuardTreeIndented, renderGuardAscii, renderGuardMarkmap, } from "../knowledge/guard-render.js";
7
+ import { renderMachineMermaid, renderMachineTreeIndented, renderMachineAscii, renderMachineMarkmap, } from "../knowledge/machine-render.js";
8
+ import { isObjectOfType } from "../schema/utils/object-type-utils.js";
6
9
  const localProject = LocalProject.Instance();
7
10
  function requireField(value, name) {
8
11
  if (value === undefined || value === null) {
@@ -41,6 +44,17 @@ async function resolveObjectAddress(v) {
41
44
  }
42
45
  throw new Error("Either 'object_address' or 'object_name_add' is required for add_object");
43
46
  }
47
+ function isDraftObject(obj) {
48
+ if (obj.objectAddress && obj.objectAddress.startsWith("draft:"))
49
+ return true;
50
+ const meta = obj.metadata;
51
+ return !!(meta && meta.status === "draft");
52
+ }
53
+ function isOnchainObject(obj) {
54
+ if (isDraftObject(obj))
55
+ return false;
56
+ return !!obj.objectAddress && obj.objectAddress.startsWith("0x");
57
+ }
44
58
  export async function handleListProjects(v) {
45
59
  const filter = {};
46
60
  if (v.filter_status)
@@ -60,12 +74,13 @@ export async function handleListProjects(v) {
60
74
  if (o.objectType)
61
75
  types.add(o.objectType);
62
76
  }
77
+ const onchainCount = objs.filter(o => isOnchainObject(o)).length;
63
78
  if (p.status === "draft" && objs.length > 0) {
64
79
  const updated = await localProject.updateProject(p.id, { status: "active" });
65
80
  if (updated) {
66
81
  return {
67
82
  ...updated,
68
- objectCount: objs.length,
83
+ objectCount: onchainCount,
69
84
  evaluationCount: evals.length,
70
85
  objectTypes: Array.from(types),
71
86
  };
@@ -73,7 +88,7 @@ export async function handleListProjects(v) {
73
88
  }
74
89
  return {
75
90
  ...p,
76
- objectCount: objs.length,
91
+ objectCount: onchainCount,
77
92
  evaluationCount: evals.length,
78
93
  objectTypes: Array.from(types),
79
94
  };
@@ -85,12 +100,30 @@ export async function handleListProjects(v) {
85
100
  };
86
101
  }
87
102
  export async function handleCreateProject(v) {
88
- const prefix = requireField(v.project, "project (prefix)");
89
103
  const name = requireField(v.project_name, "project_name");
104
+ let prefix = v.project;
105
+ if (!prefix) {
106
+ prefix = name
107
+ .toLowerCase()
108
+ .trim()
109
+ .replace(/[^a-z0-9]+/g, "_")
110
+ .replace(/^_+|_+$/g, "")
111
+ .substring(0, 60);
112
+ if (!prefix) {
113
+ prefix = `proj_${Date.now().toString(36)}`;
114
+ }
115
+ }
90
116
  const existing = await localProject.getProjectByPrefix(prefix);
91
117
  if (existing) {
92
- throw new Error(`Project prefix '${prefix}' already exists (project: '${existing.name}', id: '${existing.id}'). ` +
93
- `Use a different prefix or update the existing project.`);
118
+ if (v.project) {
119
+ throw new Error(`Project prefix '${prefix}' already exists (project: '${existing.name}', id: '${existing.id}'). ` +
120
+ `Use a different prefix or update the existing project.`);
121
+ }
122
+ let suffix = 2;
123
+ while (await localProject.getProjectByPrefix(`${prefix}_${suffix}`)) {
124
+ suffix++;
125
+ }
126
+ prefix = `${prefix}_${suffix}`;
94
127
  }
95
128
  const create = {
96
129
  prefix,
@@ -103,6 +136,26 @@ export async function handleCreateProject(v) {
103
136
  network: v.project_network ?? "testnet",
104
137
  };
105
138
  const project = await localProject.createProject(create);
139
+ if (v.service_address) {
140
+ try {
141
+ await localProject.addObject(project.id, {
142
+ objectAddress: v.service_address,
143
+ objectType: "Service",
144
+ objectName: v.service_address.startsWith("0x")
145
+ ? undefined
146
+ : v.service_address,
147
+ role: "core",
148
+ metadata: {
149
+ auto_added_from_service_address: true,
150
+ added_at: new Date().toISOString(),
151
+ },
152
+ });
153
+ }
154
+ catch (err) {
155
+ console.warn(`[create_project] Failed to auto-add Service '${v.service_address}': ${err.message}. ` +
156
+ `Use add_object action to manually add it.`);
157
+ }
158
+ }
106
159
  const industry = v.project_industry;
107
160
  const skipTemplates = v.skip_templates === true;
108
161
  if (industry && industry !== "general" && !skipTemplates) {
@@ -264,7 +317,11 @@ export async function handleCreateProjectFromOnchain(v) {
264
317
  throw new Error(`Service object not found on ${network}: the address ${serviceAddress} does not exist on this network. ` +
265
318
  `Switch to the ${otherNetwork} network and try again.`);
266
319
  }
267
- if (!rootType.includes("::service::Service")) {
320
+ const normalizedType = rootType.toLowerCase();
321
+ const isService = normalizedType.includes("::service::service") ||
322
+ normalizedType === "service" ||
323
+ normalizedType.endsWith("::service");
324
+ if (!isService) {
268
325
  throw new Error(`Object ${serviceAddress} is not a Service (its on-chain type is "${rootType}"). ` +
269
326
  `Only on-chain Service objects can be imported as a project root.`);
270
327
  }
@@ -406,6 +463,8 @@ export async function handleGetProjectDetail(v) {
406
463
  }
407
464
  }
408
465
  const VALID_ROLES = new Set(["core", "dependency", "reference"]);
466
+ const draftObjs = objects.filter(o => isDraftObject(o));
467
+ const onchainObjs = objects.filter(o => isOnchainObject(o));
409
468
  const core = objects.filter(o => o.role === "core");
410
469
  const dependency = objects.filter(o => o.role === "dependency");
411
470
  const reference = objects.filter(o => o.role === "reference");
@@ -421,8 +480,11 @@ export async function handleGetProjectDetail(v) {
421
480
  dependency,
422
481
  reference,
423
482
  other,
483
+ draft: draftObjs,
424
484
  stats: {
425
485
  total: objects.length,
486
+ onchain_count: onchainObjs.length,
487
+ draft_count: draftObjs.length,
426
488
  core_count: core.length,
427
489
  dependency_count: dependency.length,
428
490
  reference_count: reference.length,
@@ -435,10 +497,17 @@ export async function handleGetProjectDetail(v) {
435
497
  }, {}),
436
498
  },
437
499
  };
500
+ const objectsWithDraftFlag = objects.map(o => ({
501
+ ...o,
502
+ isDraft: isDraftObject(o),
503
+ }));
438
504
  return {
439
505
  action: "get_project_detail",
440
506
  project: effectiveProject,
441
- objects,
507
+ objects: objectsWithDraftFlag,
508
+ objectCount: objects.length,
509
+ onchainCount: onchainObjs.length,
510
+ draftCount: draftObjs.length,
442
511
  objectGroups,
443
512
  graphEdgeCount: edges.length,
444
513
  serviceStatus,
@@ -593,7 +662,8 @@ async function buildGraphSync(projectId, project, v) {
593
662
  if (objects.length === 0) {
594
663
  throw new Error("Cannot build graph: project has no objects and no service_address");
595
664
  }
596
- const coreObj = objects.find(o => o.role === "core");
665
+ const coreObj = objects.find(o => o.role === "core")
666
+ ?? objects.find(o => o.objectType?.includes("service::Service") || o.objectType === "Service");
597
667
  rootAddress = (coreObj ?? objects[0]).objectAddress;
598
668
  }
599
669
  const builder = new GraphBuilder({
@@ -689,6 +759,40 @@ async function verifyServiceBindings(serviceAddress, network) {
689
759
  return null;
690
760
  }
691
761
  }
762
+ function synthesizeOnchainFallbackEdges(serviceAddress, bindings) {
763
+ const edges = [];
764
+ const now = Date.now();
765
+ const fieldMap = [
766
+ { key: "Service.machine", fieldName: "machine", relationshipType: "machine" },
767
+ { key: "Service.permission", fieldName: "permission", relationshipType: "permission" },
768
+ { key: "Service.buy_guard", fieldName: "buy_guard", relationshipType: "guard" },
769
+ { key: "Service.um", fieldName: "um", relationshipType: "um" },
770
+ { key: "Service.order_allocators", fieldName: "order_allocators", relationshipType: "guard" },
771
+ { key: "Service.arbitrations", fieldName: "arbitrations", relationshipType: "arbitration" },
772
+ ];
773
+ for (const fm of fieldMap) {
774
+ const b = bindings.bindings[fm.key];
775
+ if (!b || !b.verified)
776
+ continue;
777
+ const target = b.actual ?? `${serviceAddress}#${fm.fieldName}#synthetic`;
778
+ edges.push({
779
+ id: `onchain-fallback-${fm.fieldName}-${now}`,
780
+ projectId: null,
781
+ sourceObject: serviceAddress,
782
+ targetObject: target,
783
+ edgeSource: "internal",
784
+ relationshipType: fm.relationshipType,
785
+ fieldName: fm.fieldName,
786
+ depth: 1,
787
+ verified: true,
788
+ weight: 1,
789
+ direction: "outbound",
790
+ metadata: { onchain_fallback: true },
791
+ cachedAt: now,
792
+ });
793
+ }
794
+ return edges;
795
+ }
692
796
  function shortLabel(addrOrName) {
693
797
  if (!addrOrName)
694
798
  return "(empty)";
@@ -721,11 +825,26 @@ export async function handleEvaluateProject(v) {
721
825
  const project = await localProject.getProject(projectId);
722
826
  if (!project)
723
827
  throw new Error(`Project not found: ${projectId}`);
724
- if (v.refresh_before_eval) {
725
- await refreshProjectObjects(projectId, project.network);
828
+ let refreshWarning;
829
+ if (v.refresh_before_eval !== false) {
830
+ const refreshResult = await refreshProjectObjects(projectId, project.network);
831
+ if (refreshResult.failedCount > 0) {
832
+ refreshWarning = `Refresh completed with ${refreshResult.failedCount} failed object(s) ` +
833
+ `out of ${refreshResult.refreshedCount + refreshResult.failedCount} total. ` +
834
+ `Evaluation may use stale data for failed objects.`;
835
+ }
726
836
  }
727
837
  const objects = await localProject.listObjects(projectId);
728
- const edges = await localProject.getGraph(projectId);
838
+ let edges = await localProject.getGraph(projectId);
839
+ let graphFallbackWarning;
840
+ if (edges.length === 0 && project.serviceAddress) {
841
+ const bindings = await verifyServiceBindings(project.serviceAddress, project.network);
842
+ if (bindings && Object.values(bindings.bindings).some(b => b.verified)) {
843
+ edges = synthesizeOnchainFallbackEdges(project.serviceAddress, bindings);
844
+ const verifiedCount = Object.values(bindings.bindings).filter(b => b.verified).length;
845
+ graphFallbackWarning = `Graph is empty; fell back to on-chain direct query (${verifiedCount}/${Object.keys(bindings.bindings).length} Service bindings verified). Call build_graph to construct the full relationship graph.`;
846
+ }
847
+ }
729
848
  const addresses = objects.map(o => o.objectAddress);
730
849
  const cacheEntries = await localProject.getCachedObjects(addresses);
731
850
  const objectCache = new Map();
@@ -778,6 +897,8 @@ export async function handleEvaluateProject(v) {
778
897
  needsLlm: result.needsLlm,
779
898
  llmPrompt: result.llmPrompt,
780
899
  evaluationId,
900
+ refreshWarning,
901
+ graphFallbackWarning,
781
902
  };
782
903
  }
783
904
  export async function handleSaveEvaluation(v) {
@@ -930,6 +1051,123 @@ export async function handleCloneProjectToNetwork(v) {
930
1051
  next_steps: `Execute the same onchain_operations sequence with env.network='${targetNetwork}' to deploy objects. Then call update_project to set service_address, and build_graph to construct the new project's relationship graph.`,
931
1052
  };
932
1053
  }
1054
+ export async function handleMigrateToMainnet(v) {
1055
+ const sourceProjectId = await resolveProjectId(v);
1056
+ const sourceProject = await localProject.getProject(sourceProjectId);
1057
+ if (!sourceProject) {
1058
+ throw new Error(`Source project not found: ${sourceProjectId}`);
1059
+ }
1060
+ if (sourceProject.network === "mainnet") {
1061
+ throw new Error(`Source project '${sourceProject.prefix}' is already on mainnet. ` +
1062
+ `migrate_to_mainnet is for testnet→mainnet migration only. ` +
1063
+ `To clone to testnet, use clone_project_to_network with target_network='testnet'.`);
1064
+ }
1065
+ const cloneInput = { ...v, target_network: "mainnet" };
1066
+ const cloneResult = await handleCloneProjectToNetwork(cloneInput);
1067
+ const sourceObjects = await localProject.listObjects(sourceProjectId);
1068
+ const deploymentPlan = sourceObjects
1069
+ .filter(obj => obj.objectType !== null)
1070
+ .map((obj, idx) => ({
1071
+ order: idx + 1,
1072
+ object_type: obj.objectType,
1073
+ object_name: obj.objectName ?? "<unnamed>",
1074
+ operation_type: mapObjectTypeToOperationType(obj.objectType),
1075
+ localmark_name: obj.objectName ?? `<unnamed_${idx + 1}>`,
1076
+ note: `Deploy on mainnet with env.network='mainnet'. Use the SAME LocalMark name '${obj.objectName ?? "<unnamed>"}' — it will resolve to a DIFFERENT mainnet address. The testnet address is NOT reused.`,
1077
+ }));
1078
+ return {
1079
+ action: "migrate_to_mainnet",
1080
+ migration_status: "step_1_complete_steps_2_5_pending_user_action",
1081
+ source_project: {
1082
+ prefix: sourceProject.prefix,
1083
+ network: sourceProject.network,
1084
+ preserved: true,
1085
+ },
1086
+ target_project: {
1087
+ prefix: cloneResult.new_prefix,
1088
+ project_id: cloneResult.new_project_id,
1089
+ network: "mainnet",
1090
+ cloned_objects_count: cloneResult.cloned_objects_count,
1091
+ },
1092
+ key_principle: "testnet and mainnet are DIFFERENT projects. Same LocalMark names may exist in both networks, " +
1093
+ "but they correspond to DIFFERENT on-chain addresses. The testnet project is preserved unchanged. " +
1094
+ "LocalMark names are NETWORK-SCOPED: a name resolves to a testnet address when env.network=testnet, " +
1095
+ "and to a mainnet address when env.network=mainnet. Register the SAME name TWICE (once per network).",
1096
+ migration_plan: [
1097
+ {
1098
+ step: 1,
1099
+ status: "completed",
1100
+ action: "clone_project_to_network",
1101
+ description: "Clone source project metadata to mainnet project",
1102
+ result: `Created mainnet project '${cloneResult.new_prefix}' with ${cloneResult.cloned_objects_count} draft object(s).`,
1103
+ },
1104
+ {
1105
+ step: 2,
1106
+ status: "pending_user_action",
1107
+ action: "onchain_operations",
1108
+ description: "Re-deploy all objects on mainnet. Set env.network='mainnet' and env.project='" +
1109
+ cloneResult.new_prefix + "'. Use the SAME LocalMark names — they will resolve to " +
1110
+ "DIFFERENT mainnet addresses. Mainnet accounts need real (non-test) SUI for gas.",
1111
+ deployment_plan: deploymentPlan,
1112
+ critical_note: "Re-deploy in dependency order: Permission → Machine → Contact → Guard(s) → Service. " +
1113
+ "For the Service↔Guard circular dependency, use the 3-step pattern " +
1114
+ "(Service without order_allocators → Guards → Service with order_allocators + publish).",
1115
+ },
1116
+ {
1117
+ step: 3,
1118
+ status: "pending_user_action",
1119
+ action: "local_mark_operation",
1120
+ description: "Re-register LocalMark names on mainnet. Each name from step 2 must be registered " +
1121
+ "with its NEW mainnet address. The testnet LocalMark entries are NOT migrated " +
1122
+ "automatically — mainnet has its own name registry.",
1123
+ names_to_register: sourceObjects
1124
+ .filter(obj => obj.objectName !== null)
1125
+ .map(obj => obj.objectName),
1126
+ },
1127
+ {
1128
+ step: 4,
1129
+ status: "pending_user_action",
1130
+ action: "update_project",
1131
+ description: "Set service_address on the mainnet project to the mainnet Service address " +
1132
+ "(from step 2). Use project='" + cloneResult.new_prefix + "' and the mainnet " +
1133
+ "Service LocalMark name or 0x address.",
1134
+ },
1135
+ {
1136
+ step: 5,
1137
+ status: "pending_user_action",
1138
+ action: "build_graph",
1139
+ description: "Rebuild the relationship graph on the mainnet project. Use project='" +
1140
+ cloneResult.new_prefix + "'. This constructs edges from the newly-deployed " +
1141
+ "mainnet object bindings (machine, order_allocators, guards, etc.).",
1142
+ },
1143
+ ],
1144
+ summary: "Migration step 1 (clone) complete. Steps 2-5 require user action: deploy objects on mainnet, " +
1145
+ "re-register LocalMark names, set service_address, and rebuild the graph. The testnet project " +
1146
+ "is preserved unchanged — you can run both in parallel until ready to deprecate the testnet version.",
1147
+ };
1148
+ }
1149
+ function mapObjectTypeToOperationType(objectType) {
1150
+ const map = {
1151
+ service: "service",
1152
+ machine: "machine",
1153
+ guard: "guard",
1154
+ permission: "permission",
1155
+ progress: "progress",
1156
+ arb: "arbitration",
1157
+ arbitration: "arbitration",
1158
+ contact: "contact",
1159
+ treasury: "treasury",
1160
+ reward: "reward",
1161
+ allocation: "allocation",
1162
+ repository: "repository",
1163
+ demand: "demand",
1164
+ order: "order",
1165
+ personal: "personal",
1166
+ payment: "payment",
1167
+ proof: "proof",
1168
+ };
1169
+ return map[objectType.toLowerCase()] ?? objectType.toLowerCase();
1170
+ }
933
1171
  export async function handleGetObjectDiff(v) {
934
1172
  const address = requireField(v.diff_address, "diff_address");
935
1173
  const fromTime = requireField(v.diff_from_time, "diff_from_time");
@@ -1082,6 +1320,106 @@ export async function handleGetMachineGraph(v) {
1082
1320
  edges: edgeList,
1083
1321
  published,
1084
1322
  paused,
1323
+ mermaid: renderMachineMermaid(Array.from(nodeMap.values()), edgeList),
1324
+ tree_outline: renderMachineTreeIndented({
1325
+ nodes: Array.from(nodeMap.values()),
1326
+ edges: edgeList,
1327
+ machineName,
1328
+ machineAddress,
1329
+ published,
1330
+ paused,
1331
+ }),
1332
+ ascii_art: renderMachineAscii({
1333
+ nodes: Array.from(nodeMap.values()),
1334
+ edges: edgeList,
1335
+ machineName,
1336
+ machineAddress,
1337
+ published,
1338
+ paused,
1339
+ }),
1340
+ markmap: renderMachineMarkmap({
1341
+ nodes: Array.from(nodeMap.values()),
1342
+ edges: edgeList,
1343
+ machineName,
1344
+ machineAddress,
1345
+ published,
1346
+ paused,
1347
+ }),
1348
+ };
1349
+ }
1350
+ export async function handleGetGuardGraph(v) {
1351
+ const projectId = await resolveProjectId(v);
1352
+ const guardAddress = await resolveObjectAddress(v);
1353
+ const project = await localProject.getProject(projectId);
1354
+ if (!project)
1355
+ throw new Error(`Project not found (id: ${projectId})`);
1356
+ const objects = await localProject.listObjects(projectId);
1357
+ const guardObj = objects.find(o => o.objectAddress === guardAddress);
1358
+ if (!guardObj) {
1359
+ throw new Error(`Object ${guardAddress} is not part of project '${project.prefix}'. ` +
1360
+ `Add it via add_object first.`);
1361
+ }
1362
+ const network = (project.network ?? "testnet");
1363
+ let guardData = null;
1364
+ try {
1365
+ const queryResult = await query_objects({
1366
+ objects: [guardAddress],
1367
+ network,
1368
+ });
1369
+ guardData = queryResult?.objects?.[0] ?? null;
1370
+ }
1371
+ catch (e) {
1372
+ throw new Error(`Failed to query Guard on ${network}: ${e instanceof Error ? e.message : String(e)}`);
1373
+ }
1374
+ if (!guardData) {
1375
+ throw new Error(`Guard ${guardAddress} not found on ${network}. ` +
1376
+ `It may not exist on this network — try switching networks.`);
1377
+ }
1378
+ let guardName = null;
1379
+ try {
1380
+ const mark = await LocalMark.Instance().get(guardAddress);
1381
+ guardName = mark?.name ?? null;
1382
+ }
1383
+ catch {
1384
+ }
1385
+ const root = guardData.root ?? guardData.data?.root ?? null;
1386
+ const table = guardData.table ?? guardData.data?.table ?? [];
1387
+ const rely = guardData.rely ?? guardData.data?.rely ?? null;
1388
+ const immutable = guardData.immutable ?? guardData.data?.immutable ?? null;
1389
+ if (!root) {
1390
+ throw new Error(`Guard ${guardAddress} has no root node. The Guard may be empty or corrupted. ` +
1391
+ `Use query_toolkit to inspect the raw object data.`);
1392
+ }
1393
+ const mermaidStr = renderGuardMermaid(root);
1394
+ const tableForRender = Array.isArray(table) ? table.map((t) => ({
1395
+ identifier: t.identifier,
1396
+ name: t.name,
1397
+ value_type: t.value_type,
1398
+ b_submission: t.b_submission,
1399
+ value: t.value,
1400
+ })) : [];
1401
+ const guardRenderInput = {
1402
+ root: root,
1403
+ table: tableForRender,
1404
+ guardName,
1405
+ guardAddress,
1406
+ rely: rely ?? null,
1407
+ };
1408
+ const treeOutline = renderGuardTreeIndented(guardRenderInput);
1409
+ const asciiArt = renderGuardAscii(guardRenderInput);
1410
+ const markmap = renderGuardMarkmap(guardRenderInput);
1411
+ return {
1412
+ action: "get_guard_graph",
1413
+ guardAddress,
1414
+ guardName,
1415
+ root,
1416
+ table: Array.isArray(table) ? table : [],
1417
+ rely: rely ?? null,
1418
+ immutable: immutable ?? null,
1419
+ mermaid: mermaidStr,
1420
+ tree_outline: treeOutline,
1421
+ ascii_art: asciiArt,
1422
+ markmap: markmap,
1085
1423
  };
1086
1424
  }
1087
1425
  export async function handlePreEvaluateCheck(v) {
@@ -1164,7 +1502,7 @@ export async function handlePreEvaluateCheck(v) {
1164
1502
  });
1165
1503
  }
1166
1504
  if (project.perspective === "producer") {
1167
- const hasService = objects.some(o => o.objectType === "service");
1505
+ const hasService = objects.some(o => isObjectOfType(o.objectType, "service"));
1168
1506
  if (!hasService) {
1169
1507
  missing.push({
1170
1508
  id: "PE-06",
@@ -1271,8 +1609,12 @@ export async function handleVerifyDeployment(v) {
1271
1609
  const chainObjects = chainResult?.objects ?? [];
1272
1610
  const chainByAddress = new Map();
1273
1611
  for (const co of chainObjects) {
1274
- if (co && typeof co === "object" && "objectId" in co) {
1275
- chainByAddress.set(co.objectId, co);
1612
+ if (co && typeof co === "object") {
1613
+ const coRecord = co;
1614
+ const addr = coRecord.object ?? coRecord.objectId ?? coRecord.object_id;
1615
+ if (typeof addr === "string") {
1616
+ chainByAddress.set(addr, co);
1617
+ }
1276
1618
  }
1277
1619
  }
1278
1620
  const results = [];
@@ -1294,7 +1636,7 @@ export async function handleVerifyDeployment(v) {
1294
1636
  const sqliteFields = sqliteData?.data ?? {};
1295
1637
  const differences = [];
1296
1638
  let bindings;
1297
- if (obj.objectType === "service") {
1639
+ if (isObjectOfType(obj.objectType, "service")) {
1298
1640
  const fieldsToCompare = ["machine", "permission", "buy_guard", "arbitrations", "rewards", "repositories"];
1299
1641
  for (const f of fieldsToCompare) {
1300
1642
  const sqliteVal = sqliteFields[f];
@@ -1319,7 +1661,7 @@ export async function handleVerifyDeployment(v) {
1319
1661
  });
1320
1662
  }
1321
1663
  }
1322
- else if (obj.objectType === "machine") {
1664
+ else if (isObjectOfType(obj.objectType, "machine")) {
1323
1665
  if (sqliteFields.bPublished !== undefined && chainData.bPublished !== undefined
1324
1666
  && sqliteFields.bPublished !== chainData.bPublished) {
1325
1667
  differences.push({
@@ -9,7 +9,7 @@ function buildStage5ScoreCheck(input) {
9
9
  dimension: "risk",
10
10
  status: "FAIL",
11
11
  message: `Stage 3 evaluation score ${score} < ${STAGE5_RISK_SCORE_BLOCK} (block threshold). ` +
12
- `GLM6 衔接验证: deployment blocked — too many CRITICAL risks unresolved. ` +
12
+ `GLM6 handoff validation: deployment blocked — too many CRITICAL risks unresolved. ` +
13
13
  `Fix risks in Stage 3 (aggregate_risks) before deploying.`,
14
14
  };
15
15
  }
@@ -18,7 +18,7 @@ function buildStage5ScoreCheck(input) {
18
18
  dimension: "risk",
19
19
  status: "WARN",
20
20
  message: `Stage 3 evaluation score ${score} < ${STAGE5_RISK_SCORE_WARN} (warn threshold). ` +
21
- `GLM6 衔接验证: non-blocking — proceed at your own risk. ` +
21
+ `GLM6 handoff validation: non-blocking — proceed at your own risk. ` +
22
22
  `Recommend improving risk posture before deploying to mainnet.`,
23
23
  };
24
24
  }
@@ -42,7 +42,7 @@ function buildStage5DocCheck(input) {
42
42
  return {
43
43
  dimension: "semantic",
44
44
  status: "FAIL",
45
- message: "GLM6 衔接验证: Stage 4 deployment doc not generated. " +
45
+ message: "GLM6 handoff validation: Stage 4 deployment doc not generated. " +
46
46
  "Call generate_deployment_doc (Stage 4) before executing deployment (Stage 5).",
47
47
  };
48
48
  }
@@ -51,7 +51,7 @@ function buildStage5DocCheck(input) {
51
51
  return {
52
52
  dimension: "semantic",
53
53
  status: "FAIL",
54
- message: `GLM6 衔接验证: Stage 4 deployment doc has ${errorCount} D-error(s). ` +
54
+ message: `GLM6 handoff validation: Stage 4 deployment doc has ${errorCount} D-error(s). ` +
55
55
  `Fix all D-errors before executing deployment.`,
56
56
  };
57
57
  }
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { CoinParamSchema, CallEnvSchema, SubmissionCallSchema, TypeNamedObjectSchema } from "./base.js";
3
3
  import { AllocatorsSchema, PaymentInfoSchema } from "../query/index.js";
4
- import { NameOrAddressSchema, ReceivedBalanceOrRecentlySchema } from "../common/index.js";
4
+ import { NameOrAddressSchema, ReceivedBalanceOrRecentlySchema, RECEIVE_FORMAT_BLOCK_BALANCE } from "../common/index.js";
5
5
  export const CallAllocation_CreateSchema = z.object({
6
6
  object: TypeNamedObjectSchema.describe("REQUIRED for creating new object. Provide {name: 'yourName', type: 'Allocation'} to create and name the new Allocation object."),
7
7
  allocators: AllocatorsSchema,
@@ -10,7 +10,7 @@ export const CallAllocation_CreateSchema = z.object({
10
10
  }).strict().describe("Create a new Allocation object. Set 'object' field with {name: 'yourName', type: 'Allocation'} to name the new object. Notice:'name' goes INSIDE 'object', NOT at the data root level.");
11
11
  export const CallAllocation_OperateSchema = z.object({
12
12
  object: NameOrAddressSchema.describe("REQUIRED for operating existing object. Provide the Allocation object ID or existing name to reference the target object."),
13
- received_coins: ReceivedBalanceOrRecentlySchema.optional().describe("Unwrap the CoinWrapper objects received by the Allocation object and deposit them into the pending allocation balance"),
13
+ received_coins: ReceivedBalanceOrRecentlySchema.optional().describe("Unwrap the CoinWrapper objects received by the Allocation object and deposit them into the pending allocation balance." + RECEIVE_FORMAT_BLOCK_BALANCE),
14
14
  alloc_by_guard: NameOrAddressSchema.optional().describe("Verify the specified Guard and execute the corresponding fund allocation")
15
15
  }).strict().describe("Operate on an existing Allocation object. Set 'object' field with the object ID or existing name to specify the target.");
16
16
  export const CallAllocation_DataSchema = z.union([
@@ -1,21 +1,34 @@
1
1
  import { z } from "zod";
2
2
  import { TypedPermissionObjectSchema, CoinParamSchema, NamedObjectSchema, CallEnvSchema, SubmissionCallSchema } from "./base.js";
3
3
  import { VotingGuardSchema } from "../query/index.js";
4
- import { BalanceTypeSchema, DescriptionSchema, LongNameSchema, NameOrAddressSchema, NameSchema, ReceivedObjectsOrRecentlySchema } from "../common/index.js";
4
+ import { BalanceTypeSchema, DescriptionSchema, LongNameSchema, NameOrAddressSchema, NameSchema, ReceivedObjectsOrRecentlySchema, RECEIVE_FORMAT_BLOCK_OBJECTS } from "../common/index.js";
5
5
  export const DisputeSchema = z.object({
6
6
  order: NameOrAddressSchema.describe("Order ID or name."),
7
7
  description: DescriptionSchema.optional().describe("Dispute description."),
8
8
  proposition: z.array(LongNameSchema).describe("List of dispute propositions."),
9
- fee: CoinParamSchema.describe("Dispute processing fee."),
10
- namedArb: NamedObjectSchema.optional().describe("Name for the newly created arbitration object.")
9
+ fee: CoinParamSchema.describe("Dispute processing fee. FORMAT: {balance: <amount_in_smallest_unit>} — field name is 'balance' (NOT 'amount'). " +
10
+ "The token type and precision are determined by the Arbitration object's type_parameter (the generic type set when the Arbitration was created). " +
11
+ "For WOW (9 decimals): {balance: 50000000} = 0.05 WOW. For SUI (9 decimals): {balance: 50000000} = 0.05 SUI. " +
12
+ "For tokens with different decimals, adjust accordingly (e.g. USDC has 6 decimals, so {balance: 50000} = 0.05 USDC)."),
13
+ namedArb: NamedObjectSchema.optional().describe("RECOMMENDED: Set a local name for the newly created Arb (arbitration case) object. " +
14
+ "Without this, the Arb is only referenceable by its on-chain address. " +
15
+ "Example: {name: 'my_dispute_v1'} allows subsequent vote/feedback operations to use 'my_dispute_v1'.")
11
16
  }).strict();
12
17
  export const ConfirmSchema = z.object({
13
18
  arb: NameOrAddressSchema,
14
- voting_deadline: z.union([z.number().int().min(0), z.null()])
19
+ voting_deadline: z.union([z.number().int().min(0), z.null()]).describe("Voting deadline as Unix timestamp in MILLISECONDS (ms). " +
20
+ "MUST be in the future (recommended: now + at least 86400000 ms = 24 hours). " +
21
+ "Set to null to remove the deadline. " +
22
+ "COMMON MISTAKE: using seconds instead of milliseconds (multiply by 1000). " +
23
+ "Example: Date.now() + 259200000 for 3 days from now.")
15
24
  }).strict();
16
25
  export const VotingDeadlineChangeSchema = z.object({
17
26
  arb: NameOrAddressSchema,
18
- voting_deadline: z.union([z.number(), z.null()])
27
+ voting_deadline: z.union([z.number(), z.null()]).describe("New voting deadline as Unix timestamp in MILLISECONDS (ms). " +
28
+ "MUST be in the future (recommended: now + at least 86400000 ms = 24 hours). " +
29
+ "Set to null to remove the deadline. " +
30
+ "COMMON MISTAKE: using seconds instead of milliseconds (multiply by 1000). " +
31
+ "Example: Date.now() + 259200000 for 3 days from now.")
19
32
  }).strict();
20
33
  export const VoteSchema = z.object({
21
34
  arb: NameOrAddressSchema,
@@ -82,7 +95,7 @@ export const CallArbitration_DataSchema = z.object({
82
95
  fees_transfer: FeesTransferSchema.optional().describe("Distribute the withdrawn arbitration fees."),
83
96
  usage_guard: z.union([NameOrAddressSchema, z.null()]).optional().describe("Set Guard for verification when users apply for arbitration; if Guard verification fails, users will not be able to apply for arbitration."),
84
97
  voting_guard: VotingGuardActionSchema.optional().describe("Set Guard for verification during arbitration voting; if Guard verification fails, arbitration voting will fail."),
85
- owner_receive: ReceivedObjectsOrRecentlySchema.optional().describe("Unwrap CoinWrapper objects and other objects received by this object and send them to the owner of its Permission object."),
98
+ owner_receive: ReceivedObjectsOrRecentlySchema.optional().describe("Unwrap CoinWrapper objects and other objects received by this Arbitration object and send them to the owner of its Permission object." + RECEIVE_FORMAT_BLOCK_OBJECTS),
86
99
  um: z.union([NameOrAddressSchema, z.null()]).optional().describe("Contact object ID or name.")
87
100
  }).strict().describe("On-chain Arbitration operations. USAGE: (1) CREATE NEW: Set 'object' field with OBJECT format {name, type_parameter, permission, ...} to create an Arbitration. NOTE:'name' goes INSIDE 'object', NOT at the data root level. 'permission' can be a new Permission object or reference an existing one - check 'object' field description for details. (2) OPERATE EXISTING: Set 'object' field with STRING format (object ID or name). The 'object' field is CRITICAL and REQUIRED in both cases. STRING for existing, OBJECT for new creation.");
88
101
  export const CallArbitration_InputSchema = z.object({
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { WithPermissionObjectSchema, CallEnvSchema, SubmissionCallSchema } from "./base.js";
3
- import { NameOrAddressSchema, ReceivedObjectsOrRecentlySchema, DescriptionSchema, LongNameSchema, NameSchema } from "../common/index.js";
3
+ import { NameOrAddressSchema, ReceivedObjectsOrRecentlySchema, DescriptionSchema, LongNameSchema, NameSchema, RECEIVE_FORMAT_BLOCK_OBJECTS } from "../common/index.js";
4
4
  export const ImEntrySchema = z.object({
5
5
  at: NameOrAddressSchema.describe("Contact's account address or name for instant messaging"),
6
6
  description: LongNameSchema.optional().describe("Optional description or note about this contact"),
@@ -28,7 +28,7 @@ export const CallContact_DataSchema = z.object({
28
28
  description: DescriptionSchema.optional().describe("Contact object description or public information"),
29
29
  location: LongNameSchema.optional().describe("Physical or virtual location information for this contact"),
30
30
  ims: ImsOperationSchema.optional().describe("IM contact list operation: add, set, remove, or clear instant messaging contacts"),
31
- owner_receive: ReceivedObjectsOrRecentlySchema.optional().describe("Receive objects sent to this contact object and unwrap them to the permission owner"),
31
+ owner_receive: ReceivedObjectsOrRecentlySchema.optional().describe("Receive objects sent to this Contact object and unwrap them to the permission owner." + RECEIVE_FORMAT_BLOCK_OBJECTS),
32
32
  }).strict().describe("On-chain Contact operations. USAGE: (1) CREATE NEW: Set 'object' field with OBJECT format {name, permission, ...} to create a Contact. NOTE: 'name' goes INSIDE 'object', NOT at the data root level. 'permission' can be a new Permission object or reference an existing one - check 'object' field description for details. (2) OPERATE EXISTING: Set 'object' field with STRING format (object ID or name). The 'object' field is CRITICAL and REQUIRED in both cases. STRING for existing, OBJECT for new creation.");
33
33
  export const CallContact_InputSchema = z.object({
34
34
  data: CallContact_DataSchema.describe("Contact operation data containing object reference and operations to perform"),