@nextclaw/x-harness 0.1.0 → 0.1.1

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 (94) hide show
  1. package/README.md +2 -2
  2. package/cli/main.js +23 -11
  3. package/dist/api.js +53 -1
  4. package/dist/browser-dom-capabilities.d.ts +4 -0
  5. package/dist/browser-dom-capabilities.js +110 -0
  6. package/dist/browser-dom-dependencies.d.ts +16 -0
  7. package/dist/browser-dom-editing.d.ts +148 -0
  8. package/dist/browser-dom-editing.js +386 -0
  9. package/dist/browser-dom-navigation.d.ts +9 -0
  10. package/dist/browser-dom-navigation.js +165 -0
  11. package/dist/browser-dom-network.d.ts +1 -0
  12. package/dist/browser-dom-network.js +128 -0
  13. package/dist/browser-dom-submission.d.ts +2 -0
  14. package/dist/browser-dom-submission.js +82 -0
  15. package/dist/browser-dom.d.ts +1 -1
  16. package/dist/browser-dom.js +51 -802
  17. package/dist/browser-native.js +32 -28
  18. package/dist/browser.js +6 -2
  19. package/dist/creator.js +1 -1
  20. package/dist/growth-batch.d.ts +5 -0
  21. package/dist/growth-batch.js +168 -0
  22. package/dist/growth-constants.d.ts +5 -0
  23. package/dist/growth-constants.js +13 -0
  24. package/dist/growth-dependencies.d.ts +33 -0
  25. package/dist/growth-execution.d.ts +11 -0
  26. package/dist/growth-execution.js +315 -0
  27. package/dist/growth-parallel.d.ts +4 -0
  28. package/dist/growth-parallel.js +301 -0
  29. package/dist/growth-plan.d.ts +4 -0
  30. package/dist/growth-plan.js +207 -0
  31. package/dist/growth-policy.d.ts +9 -0
  32. package/dist/growth-policy.js +181 -0
  33. package/dist/growth-publishing.d.ts +5 -0
  34. package/dist/growth-publishing.js +240 -0
  35. package/dist/growth-reading.d.ts +4 -0
  36. package/dist/growth-reading.js +135 -0
  37. package/dist/growth-recovery.d.ts +6 -0
  38. package/dist/growth-recovery.js +158 -0
  39. package/dist/growth-state.d.ts +8 -0
  40. package/dist/growth-state.js +183 -0
  41. package/dist/growth-tasks.d.ts +17 -0
  42. package/dist/growth-tasks.js +101 -0
  43. package/dist/growth.d.ts +1 -0
  44. package/dist/growth.js +122 -1902
  45. package/dist/platform-capabilities.d.ts +4 -0
  46. package/dist/platform-capabilities.js +19 -0
  47. package/dist/platform-collections.d.ts +7 -0
  48. package/dist/platform-collections.js +223 -0
  49. package/dist/platform-dependencies.d.ts +43 -0
  50. package/dist/platform-diagnostics.d.ts +9 -0
  51. package/dist/platform-diagnostics.js +51 -0
  52. package/dist/platform-observation.d.ts +8 -0
  53. package/dist/platform-observation.js +75 -0
  54. package/dist/platform-rules.d.ts +17 -0
  55. package/dist/platform-rules.js +41 -0
  56. package/dist/platform-targets.d.ts +7 -0
  57. package/dist/platform-targets.js +129 -0
  58. package/dist/platform-writing.d.ts +8 -0
  59. package/dist/platform-writing.js +171 -0
  60. package/dist/platform.d.ts +1 -1
  61. package/dist/platform.js +56 -677
  62. package/dist/readers-actions.d.ts +2 -0
  63. package/dist/readers-actions.js +66 -0
  64. package/dist/readers-ax-host.d.ts +2 -0
  65. package/dist/readers-ax-host.js +125 -0
  66. package/dist/readers-ax-parser.d.ts +1 -0
  67. package/dist/readers-ax-parser.js +69 -0
  68. package/dist/readers-ax-program.d.ts +1 -0
  69. package/dist/readers-ax-tree.d.ts +19 -0
  70. package/dist/readers-ax-tree.js +110 -0
  71. package/dist/readers-ax-views.d.ts +87 -0
  72. package/dist/readers-ax-views.js +247 -0
  73. package/dist/readers-cli.d.ts +6 -0
  74. package/dist/readers-composer.d.ts +2 -0
  75. package/dist/readers-composer.js +131 -0
  76. package/dist/readers-navigation.d.ts +2 -0
  77. package/dist/readers-navigation.js +66 -0
  78. package/dist/readers-posts.d.ts +2 -0
  79. package/dist/readers-posts.js +141 -0
  80. package/dist/readers-profile.d.ts +3 -0
  81. package/dist/readers-profile.js +157 -0
  82. package/dist/readers.d.ts +9 -20
  83. package/dist/results.js +1 -1
  84. package/dist/round-state.js +2 -2
  85. package/dist/types.d.ts +10 -0
  86. package/generated/observation.mjs +2 -1
  87. package/package.json +1 -1
  88. package/skill/SKILL.md +17 -36
  89. package/skill/references/api.md +7 -34
  90. package/skill/references/reads.md +23 -0
  91. package/skill/references/recovery.md +25 -0
  92. package/skill/references/setup.md +23 -0
  93. package/skill/references/writes.md +51 -0
  94. package/dist/readers.js +0 -1045
package/README.md CHANGED
@@ -13,7 +13,7 @@ npx @nextclaw/x-harness@latest update --target codex
13
13
 
14
14
  Requires Node.js 22+ and a compatible browser-enabled AI host. Codex desktop with CUA is the validated host. `--target claude` installs Skill text into Claude's Skill directory; the Claude host must separately provide compatible CUA tab/app methods. Installing text alone does not add browser control.
15
15
 
16
- The runtime lives in `~/.x-harness/runtime`; the Skill is managed in the selected host's Skill directory. Updates preserve your independent workspaces, back up the previous runtime and Skill, and refuse to overwrite unrecognized directories. Restart the task's module binding after updating.
16
+ The runtime lives in `~/.x-harness/runtime`; the Skill is managed in the selected host's Skill directory. Updates preserve your independent workspaces, back up the previous runtime and Skill, and refuse to overwrite unrecognized directories. Bind the new moduleURL reported by update; its versioned path refreshes the complete module graph, including in a persistent REPL. The stable CLI entry remains usable.
17
17
 
18
18
  Initialize your own workspace (use the stable CLI path reported by setup):
19
19
 
@@ -37,6 +37,6 @@ Read APIs: `readCreator`, `readBookmarks`, `searchSources`, `readPost`, `readPer
37
37
  Write APIs: `publishPost`, `replyToPost`, `followOne`, `followBatch`, `runGrowthRound`.
38
38
  Recovery: `verifySubmission`, `verifyPublishedPost`, `verifyFollow`.
39
39
 
40
- Writing requires the user's explicit task authorization, reviewed prepared actions and their own ledger plan. Initialization enables no planned writes. Current writing window: 07:00–22:00 Asia/Shanghai; follow quality gates currently require reviewed Chinese-language, blue-check candidates. Read tasks do not require that candidate policy. Missing browser capability, login or decision evidence is returned explicitly. Unknown submissions are verified before any further submission.
40
+ Writing requires the user's explicit task authorization, reviewed prepared actions and their own ledger plan. Initialization enables no planned writes. Current runtime windows (Asia/Shanghai): originals/follows 07:00–22:00; replies 07:00–24:00. Follow any stricter original project contract; follow quality gates currently require reviewed Chinese-language, blue-check candidates. Read tasks do not require that candidate policy. Missing browser capability, login or decision evidence is returned explicitly. Unknown submissions are verified before any further submission.
41
41
 
42
42
  Free to use under the included proprietary license. The distributed JavaScript is readable; the private TypeScript repository is not published. This is not an official X product. See `LICENSE` for permitted use.
package/cli/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync, renameSync, rmSync, cpSync, mkdtempSync, openSync, closeSync, unlinkSync, readdirSync, } from "node:fs";
3
- import { join, resolve, dirname } from "node:path";
3
+ import { join, resolve, dirname, relative } from "node:path";
4
4
  import { homedir } from "node:os";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
6
6
  import { randomUUID } from "node:crypto";
@@ -44,6 +44,24 @@ function location() {
44
44
  home,
45
45
  };
46
46
  }
47
+ function stageRuntime(stage, runtime) {
48
+ const stagedRuntime = join(stage, "runtime");
49
+ const suffix = join("versions", release.version, "node_modules", ...release.name.split("/"));
50
+ const installedRoot = join(stagedRuntime, suffix);
51
+ cpSync(packageRoot, installedRoot, { recursive: true });
52
+ if (readJSON(join(installedRoot, "package.json")).version !== release.version)
53
+ throw Error("Installed version mismatch");
54
+ const finalRoot = join(runtime, suffix);
55
+ const stableRoot = join(stagedRuntime, "node_modules", ...release.name.split("/"));
56
+ const stableCLI = join(runtime, "node_modules", ...release.name.split("/"), "cli", "main.js");
57
+ mkdirSync(join(stableRoot, "cli"), { recursive: true });
58
+ writeFileSync(join(stableRoot, "package.json"), JSON.stringify({ type: "module" }));
59
+ const entry = relative(dirname(stableCLI), join(finalRoot, "cli", "main.js"))
60
+ .split("\\")
61
+ .join("/");
62
+ writeFileSync(join(stableRoot, "cli", "main.js"), `#!/usr/bin/env node\nawait import(new URL(${JSON.stringify(entry)}, import.meta.url));\n`);
63
+ return { stagedRuntime, installedRoot, finalRoot, stableCLI };
64
+ }
47
65
  function setup() {
48
66
  const target = flags.get("--target") ?? "codex";
49
67
  const stateFile = join(home, "installation.json");
@@ -66,23 +84,17 @@ function setup() {
66
84
  const changes = [];
67
85
  let completed = false;
68
86
  try {
69
- const stagedRuntime = join(stage, "runtime");
70
- mkdirSync(stagedRuntime);
71
- const installedRoot = join(stagedRuntime, "node_modules", ...release.name.split("/"));
72
- // npx has already fetched this release. Persist its dependency-free runtime once.
73
- cpSync(packageRoot, installedRoot, { recursive: true });
74
- if (readJSON(join(installedRoot, "package.json")).version !== release.version)
75
- throw Error("Installed version mismatch");
87
+ // Persist npx's already fetched runtime once; versioned URLs invalidate the whole module graph.
88
+ const { stagedRuntime, installedRoot, finalRoot, stableCLI } = stageRuntime(stage, runtime);
76
89
  const metadata = { managedBy: release.name, version: release.version };
77
90
  writeFileSync(join(stagedRuntime, ".x-harness-managed.json"), JSON.stringify(metadata));
78
- const finalRoot = join(runtime, "node_modules", ...release.name.split("/"));
79
91
  const installs = [{ src: stagedRuntime, dest: runtime, key: "runtime" }];
80
92
  for (const t of targets) {
81
93
  const stagedSkill = join(stage, `skill-${t}`);
82
94
  cpSync(join(installedRoot, "skill"), stagedSkill, { recursive: true });
83
95
  const content = readFileSync(join(stagedSkill, "SKILL.md"), "utf8")
84
96
  .replaceAll("{{MODULE_URL}}", pathToFileURL(join(finalRoot, "dist", "index.js")).href)
85
- .replaceAll("{{CLI_PATH}}", join(finalRoot, "cli", "main.js"));
97
+ .replaceAll("{{CLI_PATH}}", stableCLI);
86
98
  writeFileSync(join(stagedSkill, "SKILL.md"), content);
87
99
  writeFileSync(join(stagedSkill, ".x-harness-managed.json"), JSON.stringify(metadata));
88
100
  installs.push({
@@ -111,7 +123,7 @@ function setup() {
111
123
  status: "installed",
112
124
  ...state,
113
125
  moduleURL: pathToFileURL(join(finalRoot, "dist", "index.js")).href,
114
- cliPath: join(finalRoot, "cli", "main.js"),
126
+ cliPath: stableCLI,
115
127
  skillPaths: targets.map(skillPath),
116
128
  backup: changes.some((c) => c.hadOld) ? backup : null,
117
129
  next: "Start a fresh module binding using the installed x-harness Skill.",
package/dist/api.js CHANGED
@@ -7,7 +7,44 @@ export function createBusinessHarness(dependencies) {
7
7
  // All public operations share the same error boundary. Full errors remain local proof.
8
8
  async function invoke(operation, args) {
9
9
  try {
10
- return await core[operation](args);
10
+ const raw = await core[operation](args);
11
+ // Legacy core decisions can contain a human error without a diagnostic proof.
12
+ // Expose a bounded recovery route; consumers never need implementation source.
13
+ const errors = [
14
+ raw.reason,
15
+ ...(raw.decision ?? []).flatMap((d) => [
16
+ d.reason,
17
+ d.error,
18
+ ]),
19
+ ].filter((reason) => typeof reason === "string" && stableReason(reason) !== reason);
20
+ if (errors.length) {
21
+ const evidenceRef = await store.recordProof({
22
+ operation,
23
+ error: errors[0],
24
+ ...(errors.length > 1 ? { errors } : {}),
25
+ });
26
+ return {
27
+ ...raw,
28
+ ...(raw.reason ? { reason: stableReason(raw.reason) } : {}),
29
+ evidenceRef,
30
+ ...(raw.decision
31
+ ? {
32
+ decision: raw.decision.map((d) => ({
33
+ ...d,
34
+ reason: stableReason(d.reason),
35
+ })),
36
+ }
37
+ : {}),
38
+ diagnostic: {
39
+ operation,
40
+ category: "boundary",
41
+ code: "harness-boundary-error",
42
+ next: "inspect-local-proof",
43
+ evidenceRef,
44
+ },
45
+ };
46
+ }
47
+ return raw;
11
48
  }
12
49
  catch (error) {
13
50
  const message = error instanceof Error ? error.message : String(error);
@@ -29,6 +66,15 @@ export function createBusinessHarness(dependencies) {
29
66
  ...(evidenceRef
30
67
  ? { evidenceRef }
31
68
  : { missing: ["local-proof-unavailable"] }),
69
+ diagnostic: {
70
+ operation,
71
+ category: "boundary",
72
+ code: evidenceRef
73
+ ? "harness-boundary-error"
74
+ : "evidence-store-unavailable",
75
+ next: evidenceRef ? "inspect-local-proof" : "restore-proof-store",
76
+ ...(evidenceRef ? { evidenceRef } : {}),
77
+ },
32
78
  };
33
79
  }
34
80
  }
@@ -112,6 +158,9 @@ export function createBusinessHarness(dependencies) {
112
158
  out.decision = issues;
113
159
  if (raw.evidenceRef)
114
160
  out.evidenceRef = raw.evidenceRef;
161
+ const d = diagnostic(raw.diagnostic);
162
+ if (d)
163
+ out.diagnostic = d;
115
164
  if (Array.isArray(raw.settlementErrors))
116
165
  out.settlementErrors = raw.settlementErrors
117
166
  .map(stableReason)
@@ -231,6 +280,9 @@ export function createBusinessHarness(dependencies) {
231
280
  output.batchId = raw.batchId;
232
281
  if (raw.evidenceRef)
233
282
  output.evidenceRef = raw.evidenceRef;
283
+ const d = diagnostic(raw.diagnostic);
284
+ if (d)
285
+ output.diagnostic = d;
234
286
  const issues = decisions(raw.decision);
235
287
  if (raw.reason)
236
288
  issues.push({ reason: raw.reason, status: "needsDecision" });
@@ -0,0 +1,4 @@
1
+ import type { DOMDependencies } from "./browser-dom-dependencies.js";
2
+ export declare function createDOMCapabilities(dependencies: Pick<DOMDependencies, "tab" | "nativeSubmit">): {
3
+ capabilities(operation: any): any;
4
+ };
@@ -0,0 +1,110 @@
1
+ import { missingMethods } from "./browser-common.js";
2
+ export function createDOMCapabilities(dependencies) {
3
+ const { tab, nativeSubmit } = dependencies;
4
+ return {
5
+ capabilities(operation) {
6
+ const base = missingMethods(tab?.playwright, ["evaluate"]);
7
+ if (operation === "readCreator") {
8
+ base.push(...missingMethods(tab, [
9
+ "url",
10
+ "goto",
11
+ "reload",
12
+ "getAXState",
13
+ "scroll",
14
+ ]));
15
+ base.push(...missingMethods(tab.playwright, ["locator"]));
16
+ if (typeof tab.playwright?.locator === "function") {
17
+ const article = tab.playwright.locator("article");
18
+ base.push(...missingMethods(article, ["first", "getByRole"]));
19
+ if (typeof article.first === "function")
20
+ base.push(...missingMethods(article.first(), ["waitFor"]));
21
+ if (typeof article.getByRole === "function")
22
+ base.push(...missingMethods(article.getByRole("button", { name: "显示更多", exact: true }), ["all"]));
23
+ }
24
+ return base;
25
+ }
26
+ if (["readBookmarks", "searchSources", "readFeedback"].includes(operation)) {
27
+ base.push(...missingMethods(tab, ["goto"]));
28
+ base.push(...missingMethods(tab?.playwright, ["getByRole", "waitForURL"]));
29
+ if (typeof tab?.playwright?.getByRole === "function")
30
+ base.push(...missingMethods(tab.playwright.getByRole("article"), [
31
+ "first",
32
+ "waitFor",
33
+ ]));
34
+ if (operation !== "readFeedback") {
35
+ base.push(...missingMethods(tab?.playwright, [
36
+ "getByRole",
37
+ "getByText",
38
+ "locator",
39
+ "waitForURL",
40
+ ]));
41
+ if (typeof tab?.playwright?.getByRole === "function")
42
+ base.push(...missingMethods(tab.playwright.getByRole("main"), [
43
+ "count",
44
+ "click",
45
+ "first",
46
+ "waitFor",
47
+ ]));
48
+ if (typeof tab?.playwright?.locator === "function")
49
+ base.push(...missingMethods(tab.playwright.locator("a"), [
50
+ "count",
51
+ "filter",
52
+ "press",
53
+ ]));
54
+ if (typeof tab?.playwright?.getByText === "function")
55
+ base.push(...missingMethods(tab.playwright.getByText(""), ["waitFor"]));
56
+ }
57
+ return base;
58
+ }
59
+ if (operation !== "read")
60
+ base.push(...missingMethods(tab?.playwright, ["getByRole"]), ...missingMethods(tab, ["goto"]));
61
+ if (operation !== "read" &&
62
+ typeof tab?.playwright?.getByRole === "function") {
63
+ base.push(...missingMethods(tab.playwright.getByRole("button"), [
64
+ "count",
65
+ "click",
66
+ ]));
67
+ if (operation !== "submitFollow")
68
+ base.push(...missingMethods(tab.playwright.getByRole("textbox"), [
69
+ "count",
70
+ "fill",
71
+ ]));
72
+ if (["submitPost", "submitReply"].includes(operation)) {
73
+ base.push(...missingMethods(tab.playwright, ["locator", "waitForLoadState"]));
74
+ base.push(...missingMethods(tab.playwright.getByRole("button"), [
75
+ "and",
76
+ "waitFor",
77
+ ]));
78
+ }
79
+ }
80
+ if (operation === "refreshPerson" || operation === "refreshPosts") {
81
+ base.push(...missingMethods(tab, ["reload"]));
82
+ base.push(...missingMethods(tab?.playwright, ["waitForLoadState"]));
83
+ if (typeof tab?.playwright?.getByRole === "function")
84
+ base.push(...missingMethods(tab.playwright.getByRole("button"), ["waitFor"]));
85
+ }
86
+ if (operation === "openOwnPostMenu") {
87
+ base.push(...missingMethods(tab?.playwright, ["locator"]));
88
+ if (typeof tab?.playwright?.getByRole === "function")
89
+ base.push(...missingMethods(tab.playwright.getByRole("article"), [
90
+ "filter",
91
+ "getByRole",
92
+ ]));
93
+ }
94
+ if (operation === "submitEditedPost") {
95
+ base.push(...missingMethods(tab?.playwright, ["waitForLoadState"]));
96
+ if (typeof tab?.playwright?.getByRole === "function")
97
+ base.push(...missingMethods(tab.playwright.getByRole("button"), ["press"]));
98
+ }
99
+ if (operation === "attachAssets")
100
+ base.push(...missingMethods(tab?.playwright, [
101
+ "waitForEvent",
102
+ "getByLabel",
103
+ "getByPlaceholder",
104
+ ]));
105
+ if (nativeSubmit && ["submitPost", "submitReply"].includes(operation))
106
+ base.push(...missingMethods(tab, ["getAXState", "click"]));
107
+ return base;
108
+ },
109
+ };
110
+ }
@@ -0,0 +1,16 @@
1
+ export interface DOMSession {
2
+ current?: any;
3
+ replyBinding?: any;
4
+ refreshNotice?: any;
5
+ editBinding?: any;
6
+ }
7
+ export interface DOMDependencies {
8
+ tab: any;
9
+ nativeSubmit: boolean;
10
+ readDOM: any;
11
+ session: DOMSession;
12
+ submitAX: any;
13
+ observe: (query: any) => Promise<any>;
14
+ locator: (role: any, name?: any) => any;
15
+ unique: (loc: any) => Promise<any>;
16
+ }
@@ -0,0 +1,148 @@
1
+ import type { DOMDependencies } from "./browser-dom-dependencies.js";
2
+ export declare function createDOMEditing(dependencies: Pick<DOMDependencies, "session" | "unique" | "locator" | "tab" | "observe">): {
3
+ dismissMenu: (command: any) => Promise<{
4
+ completed: boolean;
5
+ loc?: undefined;
6
+ submittedEditor?: undefined;
7
+ } | {
8
+ completed: boolean;
9
+ loc: any;
10
+ submittedEditor: any;
11
+ }>;
12
+ openControl: (command: any) => Promise<{
13
+ completed: boolean;
14
+ loc?: undefined;
15
+ submittedEditor?: undefined;
16
+ } | {
17
+ completed: boolean;
18
+ loc: any;
19
+ submittedEditor: any;
20
+ }>;
21
+ openOwnPostMenu: (command: any) => Promise<{
22
+ completed: boolean;
23
+ loc?: undefined;
24
+ submittedEditor?: undefined;
25
+ } | {
26
+ completed: boolean;
27
+ loc: any;
28
+ submittedEditor: any;
29
+ }>;
30
+ submitEditedPost: (command: any) => Promise<{
31
+ completed: boolean;
32
+ loc?: undefined;
33
+ submittedEditor?: undefined;
34
+ } | {
35
+ completed: boolean;
36
+ loc: any;
37
+ submittedEditor: any;
38
+ }>;
39
+ expandPost: (command: any) => Promise<{
40
+ completed: boolean;
41
+ loc?: undefined;
42
+ submittedEditor?: undefined;
43
+ } | {
44
+ completed: boolean;
45
+ loc: any;
46
+ submittedEditor: any;
47
+ }>;
48
+ nextPosts: (command: any) => Promise<{
49
+ completed: boolean;
50
+ loc?: undefined;
51
+ submittedEditor?: undefined;
52
+ } | {
53
+ completed: boolean;
54
+ loc: any;
55
+ submittedEditor: any;
56
+ }>;
57
+ clearPreparedText: (command: any) => Promise<{
58
+ completed: boolean;
59
+ value: Promise<any>;
60
+ loc?: undefined;
61
+ submittedEditor?: undefined;
62
+ } | {
63
+ completed: boolean;
64
+ loc: any;
65
+ submittedEditor: any;
66
+ value?: undefined;
67
+ }>;
68
+ closePreparedReply: (command: any) => Promise<{
69
+ completed: boolean;
70
+ value: Promise<any>;
71
+ loc?: undefined;
72
+ submittedEditor?: undefined;
73
+ } | {
74
+ completed: boolean;
75
+ loc: any;
76
+ submittedEditor: any;
77
+ value?: undefined;
78
+ }>;
79
+ closePreparedMedia: (command: any) => Promise<{
80
+ completed: boolean;
81
+ value: Promise<any>;
82
+ loc?: undefined;
83
+ submittedEditor?: undefined;
84
+ } | {
85
+ completed: boolean;
86
+ loc: any;
87
+ submittedEditor: any;
88
+ value?: undefined;
89
+ }>;
90
+ removePreparedMedia: (command: any) => Promise<{
91
+ completed: boolean;
92
+ value: Promise<any>;
93
+ loc?: undefined;
94
+ submittedEditor?: undefined;
95
+ } | {
96
+ completed: boolean;
97
+ loc: any;
98
+ submittedEditor: any;
99
+ value?: undefined;
100
+ }>;
101
+ attachAssets: (command: any) => Promise<{
102
+ completed: boolean;
103
+ value: {
104
+ assets: {
105
+ path: any;
106
+ alt: any;
107
+ }[];
108
+ mediaEvidence: any;
109
+ composer: any;
110
+ };
111
+ loc?: undefined;
112
+ submittedEditor?: undefined;
113
+ } | {
114
+ completed: boolean;
115
+ loc: any;
116
+ submittedEditor: any;
117
+ value?: undefined;
118
+ }>;
119
+ follow: (command: any) => Promise<{
120
+ completed: boolean;
121
+ loc: any;
122
+ submittedEditor: any;
123
+ }>;
124
+ openReply: (command: any) => Promise<{
125
+ completed: boolean;
126
+ loc: any;
127
+ submittedEditor: any;
128
+ }>;
129
+ fillComposer: (command: any) => Promise<{
130
+ completed: boolean;
131
+ loc?: undefined;
132
+ submittedEditor?: undefined;
133
+ } | {
134
+ completed: boolean;
135
+ loc: any;
136
+ submittedEditor: any;
137
+ }>;
138
+ submitPost: (command: any) => Promise<{
139
+ completed: boolean;
140
+ loc: any;
141
+ submittedEditor: any;
142
+ }>;
143
+ submitReply: (command: any) => Promise<{
144
+ completed: boolean;
145
+ loc: any;
146
+ submittedEditor: any;
147
+ }>;
148
+ };