@useorgx/openclaw-plugin 0.4.5 → 0.4.6
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/README.md +24 -3
- package/dashboard/dist/assets/0tOC3wSN.js +214 -0
- package/dashboard/dist/assets/B3ziCA02.js +8 -0
- package/dashboard/dist/assets/Bm8QnMJ_.js +1 -0
- package/dashboard/dist/assets/CpJsfbXo.js +9 -0
- package/dashboard/dist/assets/CyxZio4Y.js +1 -0
- package/dashboard/dist/assets/DaAIOik3.css +1 -0
- package/dashboard/dist/assets/sAhvFnpk.js +4 -0
- package/dashboard/dist/index.html +5 -5
- package/dist/activity-store.d.ts +28 -0
- package/dist/activity-store.js +250 -0
- package/dist/agent-context-store.d.ts +19 -0
- package/dist/agent-context-store.js +60 -3
- package/dist/agent-suite.d.ts +83 -0
- package/dist/agent-suite.js +615 -0
- package/dist/contracts/client.d.ts +22 -1
- package/dist/contracts/client.js +120 -3
- package/dist/contracts/types.d.ts +190 -1
- package/dist/entity-comment-store.d.ts +29 -0
- package/dist/entity-comment-store.js +190 -0
- package/dist/hooks/post-reporting-event.mjs +326 -0
- package/dist/http-handler.d.ts +7 -1
- package/dist/http-handler.js +3603 -578
- package/dist/index.js +936 -62
- package/dist/mcp-client-setup.js +156 -24
- package/dist/mcp-http-handler.d.ts +17 -0
- package/dist/mcp-http-handler.js +144 -3
- package/dist/next-up-queue-store.d.ts +31 -0
- package/dist/next-up-queue-store.js +169 -0
- package/dist/openclaw.plugin.json +1 -1
- package/dist/outbox.d.ts +1 -1
- package/dist/runtime-instance-store.d.ts +1 -1
- package/dist/runtime-instance-store.js +20 -3
- package/dist/skill-pack-state.d.ts +69 -0
- package/dist/skill-pack-state.js +232 -0
- package/dist/worker-supervisor.d.ts +25 -0
- package/dist/worker-supervisor.js +62 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +10 -1
- package/skills/orgx-design-agent/SKILL.md +38 -0
- package/skills/orgx-engineering-agent/SKILL.md +55 -0
- package/skills/orgx-marketing-agent/SKILL.md +40 -0
- package/skills/orgx-operations-agent/SKILL.md +40 -0
- package/skills/orgx-orchestrator-agent/SKILL.md +45 -0
- package/skills/orgx-product-agent/SKILL.md +39 -0
- package/skills/orgx-sales-agent/SKILL.md +40 -0
- package/skills/ship/SKILL.md +63 -0
- package/dashboard/dist/assets/B68j2crt.js +0 -1
- package/dashboard/dist/assets/BZZ-fiJx.js +0 -32
- package/dashboard/dist/assets/BoXlCHKa.js +0 -9
- package/dashboard/dist/assets/Bq9x_Xyh.css +0 -1
- package/dashboard/dist/assets/DBhrRVdp.js +0 -1
- package/dashboard/dist/assets/DD1jv1Hd.js +0 -8
- package/dashboard/dist/assets/DNjbmawF.js +0 -214
package/dist/outbox.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import type { LiveActivityItem } from "./types.js";
|
|
7
7
|
export interface OutboxEvent {
|
|
8
8
|
id: string;
|
|
9
|
-
type: "progress" | "decision" | "artifact" | "changeset";
|
|
9
|
+
type: "progress" | "decision" | "artifact" | "changeset" | "retro" | "outcome";
|
|
10
10
|
timestamp: string;
|
|
11
11
|
payload: Record<string, unknown>;
|
|
12
12
|
/** Converted to a LiveActivityItem for dashboard display. */
|
|
@@ -21,7 +21,7 @@ export type RuntimeInstanceRecord = {
|
|
|
21
21
|
id: string;
|
|
22
22
|
sourceClient: RuntimeSourceClient;
|
|
23
23
|
displayName: string;
|
|
24
|
-
providerLogo: "openai" | "anthropic" | "openclaw" | "orgx" | "unknown";
|
|
24
|
+
providerLogo: "codex" | "openai" | "anthropic" | "openclaw" | "orgx" | "unknown";
|
|
25
25
|
state: RuntimeInstanceState;
|
|
26
26
|
event: RuntimeHookEvent;
|
|
27
27
|
runId: string | null;
|
|
@@ -85,7 +85,7 @@ function normalizeHookEvent(value) {
|
|
|
85
85
|
}
|
|
86
86
|
function toProviderLogo(sourceClient) {
|
|
87
87
|
if (sourceClient === "codex")
|
|
88
|
-
return "
|
|
88
|
+
return "codex";
|
|
89
89
|
if (sourceClient === "claude-code")
|
|
90
90
|
return "anthropic";
|
|
91
91
|
if (sourceClient === "openclaw")
|
|
@@ -94,6 +94,22 @@ function toProviderLogo(sourceClient) {
|
|
|
94
94
|
return "orgx";
|
|
95
95
|
return "unknown";
|
|
96
96
|
}
|
|
97
|
+
function normalizeProviderLogo(value, sourceClient) {
|
|
98
|
+
const normalized = normalizeNullableString(value)?.toLowerCase();
|
|
99
|
+
if (normalized === "codex")
|
|
100
|
+
return "codex";
|
|
101
|
+
if (normalized === "openai")
|
|
102
|
+
return sourceClient === "codex" ? "codex" : "openai";
|
|
103
|
+
if (normalized === "anthropic")
|
|
104
|
+
return "anthropic";
|
|
105
|
+
if (normalized === "openclaw")
|
|
106
|
+
return "openclaw";
|
|
107
|
+
if (normalized === "orgx")
|
|
108
|
+
return "orgx";
|
|
109
|
+
if (normalized === "unknown")
|
|
110
|
+
return "unknown";
|
|
111
|
+
return toProviderLogo(sourceClient);
|
|
112
|
+
}
|
|
97
113
|
function toDisplayName(sourceClient) {
|
|
98
114
|
if (sourceClient === "codex")
|
|
99
115
|
return "Codex";
|
|
@@ -152,11 +168,12 @@ function normalizeProgress(value) {
|
|
|
152
168
|
return Math.max(0, Math.min(100, Math.round(value)));
|
|
153
169
|
}
|
|
154
170
|
function normalizeRecord(input) {
|
|
171
|
+
const sourceClient = normalizeSourceClient(input.sourceClient);
|
|
155
172
|
return {
|
|
156
173
|
id: normalizeNullableString(input.id) ?? input.id,
|
|
157
|
-
sourceClient
|
|
174
|
+
sourceClient,
|
|
158
175
|
displayName: normalizeNullableString(input.displayName) ?? "Runtime",
|
|
159
|
-
providerLogo: input.providerLogo,
|
|
176
|
+
providerLogo: normalizeProviderLogo(input.providerLogo, sourceClient),
|
|
160
177
|
state: normalizeState(input.state),
|
|
161
178
|
event: normalizeHookEvent(input.event),
|
|
162
179
|
runId: normalizeNullableString(input.runId),
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { SkillPack } from "./contracts/types.js";
|
|
2
|
+
import type { OrgxSkillPackOverrides } from "./agent-suite.js";
|
|
3
|
+
export type SkillPackState = {
|
|
4
|
+
version: 1;
|
|
5
|
+
updatedAt: string;
|
|
6
|
+
lastCheckedAt: string | null;
|
|
7
|
+
lastError: string | null;
|
|
8
|
+
etag: string | null;
|
|
9
|
+
policy: {
|
|
10
|
+
frozen: boolean;
|
|
11
|
+
pinnedChecksum: string | null;
|
|
12
|
+
};
|
|
13
|
+
pack: {
|
|
14
|
+
name: string;
|
|
15
|
+
version: string;
|
|
16
|
+
checksum: string;
|
|
17
|
+
updated_at: string | null;
|
|
18
|
+
} | null;
|
|
19
|
+
remote: {
|
|
20
|
+
name: string;
|
|
21
|
+
version: string;
|
|
22
|
+
checksum: string;
|
|
23
|
+
updated_at: string | null;
|
|
24
|
+
} | null;
|
|
25
|
+
overrides: OrgxSkillPackOverrides | null;
|
|
26
|
+
};
|
|
27
|
+
export declare function readSkillPackState(input?: {
|
|
28
|
+
openclawDir?: string;
|
|
29
|
+
}): SkillPackState;
|
|
30
|
+
export declare function writeSkillPackState(state: SkillPackState, input?: {
|
|
31
|
+
openclawDir?: string;
|
|
32
|
+
}): void;
|
|
33
|
+
export declare function updateSkillPackPolicy(input: {
|
|
34
|
+
openclawDir?: string;
|
|
35
|
+
frozen?: boolean;
|
|
36
|
+
pinnedChecksum?: string | null;
|
|
37
|
+
pinToCurrent?: boolean;
|
|
38
|
+
clearPin?: boolean;
|
|
39
|
+
}): SkillPackState;
|
|
40
|
+
export declare function toOrgxSkillPackOverrides(input: {
|
|
41
|
+
pack: SkillPack;
|
|
42
|
+
etag: string | null;
|
|
43
|
+
}): OrgxSkillPackOverrides;
|
|
44
|
+
export declare function refreshSkillPackState(input: {
|
|
45
|
+
getSkillPack: (args: {
|
|
46
|
+
name?: string;
|
|
47
|
+
ifNoneMatch?: string | null;
|
|
48
|
+
}) => Promise<{
|
|
49
|
+
ok: true;
|
|
50
|
+
notModified: true;
|
|
51
|
+
etag: string | null;
|
|
52
|
+
pack: null;
|
|
53
|
+
} | {
|
|
54
|
+
ok: true;
|
|
55
|
+
notModified: false;
|
|
56
|
+
etag: string | null;
|
|
57
|
+
pack: SkillPack;
|
|
58
|
+
} | {
|
|
59
|
+
ok: false;
|
|
60
|
+
status: number;
|
|
61
|
+
error: string;
|
|
62
|
+
}>;
|
|
63
|
+
packName?: string;
|
|
64
|
+
openclawDir?: string;
|
|
65
|
+
force?: boolean;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
state: SkillPackState;
|
|
68
|
+
changed: boolean;
|
|
69
|
+
}>;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { writeFileAtomicSync } from "./fs-utils.js";
|
|
4
|
+
import { getOpenClawDir } from "./paths.js";
|
|
5
|
+
const STORE_VERSION = 1;
|
|
6
|
+
const STATE_FILENAME = "orgx-skill-pack-state.json";
|
|
7
|
+
function nowIso() {
|
|
8
|
+
return new Date().toISOString();
|
|
9
|
+
}
|
|
10
|
+
function isRecord(value) {
|
|
11
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
12
|
+
}
|
|
13
|
+
function coerceString(value) {
|
|
14
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
15
|
+
}
|
|
16
|
+
function statePath(openclawDir) {
|
|
17
|
+
return join(openclawDir, STATE_FILENAME);
|
|
18
|
+
}
|
|
19
|
+
export function readSkillPackState(input) {
|
|
20
|
+
const openclawDir = input?.openclawDir ?? getOpenClawDir();
|
|
21
|
+
const path = statePath(openclawDir);
|
|
22
|
+
const empty = {
|
|
23
|
+
version: STORE_VERSION,
|
|
24
|
+
updatedAt: nowIso(),
|
|
25
|
+
lastCheckedAt: null,
|
|
26
|
+
lastError: null,
|
|
27
|
+
etag: null,
|
|
28
|
+
policy: { frozen: false, pinnedChecksum: null },
|
|
29
|
+
pack: null,
|
|
30
|
+
remote: null,
|
|
31
|
+
overrides: null,
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
if (!existsSync(path))
|
|
35
|
+
return empty;
|
|
36
|
+
const raw = readFileSync(path, "utf8");
|
|
37
|
+
const parsed = JSON.parse(raw);
|
|
38
|
+
if (!isRecord(parsed))
|
|
39
|
+
return empty;
|
|
40
|
+
if (parsed.version !== STORE_VERSION)
|
|
41
|
+
return empty;
|
|
42
|
+
const policy = isRecord(parsed.policy) ? parsed.policy : null;
|
|
43
|
+
const pack = isRecord(parsed.pack) ? parsed.pack : null;
|
|
44
|
+
const remote = isRecord(parsed.remote) ? parsed.remote : null;
|
|
45
|
+
const overrides = isRecord(parsed.overrides) ? parsed.overrides : null;
|
|
46
|
+
return {
|
|
47
|
+
version: STORE_VERSION,
|
|
48
|
+
updatedAt: coerceString(parsed.updatedAt) ?? nowIso(),
|
|
49
|
+
lastCheckedAt: coerceString(parsed.lastCheckedAt),
|
|
50
|
+
lastError: coerceString(parsed.lastError),
|
|
51
|
+
etag: coerceString(parsed.etag),
|
|
52
|
+
policy: {
|
|
53
|
+
frozen: Boolean(policy?.frozen),
|
|
54
|
+
pinnedChecksum: coerceString(policy?.pinnedChecksum),
|
|
55
|
+
},
|
|
56
|
+
pack: pack
|
|
57
|
+
? {
|
|
58
|
+
name: coerceString(pack.name) ?? "",
|
|
59
|
+
version: coerceString(pack.version) ?? "",
|
|
60
|
+
checksum: coerceString(pack.checksum) ?? "",
|
|
61
|
+
updated_at: coerceString(pack.updated_at),
|
|
62
|
+
}
|
|
63
|
+
: null,
|
|
64
|
+
remote: remote
|
|
65
|
+
? {
|
|
66
|
+
name: coerceString(remote.name) ?? "",
|
|
67
|
+
version: coerceString(remote.version) ?? "",
|
|
68
|
+
checksum: coerceString(remote.checksum) ?? "",
|
|
69
|
+
updated_at: coerceString(remote.updated_at),
|
|
70
|
+
}
|
|
71
|
+
: null,
|
|
72
|
+
overrides: overrides
|
|
73
|
+
? overrides
|
|
74
|
+
: null,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return empty;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function writeSkillPackState(state, input) {
|
|
82
|
+
const openclawDir = input?.openclawDir ?? getOpenClawDir();
|
|
83
|
+
const path = statePath(openclawDir);
|
|
84
|
+
writeFileAtomicSync(path, `${JSON.stringify(state, null, 2)}\n`, {
|
|
85
|
+
mode: 0o600,
|
|
86
|
+
encoding: "utf8",
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export function updateSkillPackPolicy(input) {
|
|
90
|
+
const prev = readSkillPackState({ openclawDir: input.openclawDir });
|
|
91
|
+
const nextPolicy = { ...prev.policy };
|
|
92
|
+
if (typeof input.frozen === "boolean") {
|
|
93
|
+
nextPolicy.frozen = input.frozen;
|
|
94
|
+
}
|
|
95
|
+
if (input.clearPin) {
|
|
96
|
+
nextPolicy.pinnedChecksum = null;
|
|
97
|
+
}
|
|
98
|
+
else if (input.pinToCurrent) {
|
|
99
|
+
nextPolicy.pinnedChecksum = prev.pack?.checksum ?? prev.remote?.checksum ?? null;
|
|
100
|
+
}
|
|
101
|
+
else if (typeof input.pinnedChecksum === "string") {
|
|
102
|
+
nextPolicy.pinnedChecksum = input.pinnedChecksum.trim() || null;
|
|
103
|
+
}
|
|
104
|
+
else if (input.pinnedChecksum === null) {
|
|
105
|
+
nextPolicy.pinnedChecksum = null;
|
|
106
|
+
}
|
|
107
|
+
const next = {
|
|
108
|
+
...prev,
|
|
109
|
+
updatedAt: nowIso(),
|
|
110
|
+
policy: nextPolicy,
|
|
111
|
+
};
|
|
112
|
+
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
113
|
+
return next;
|
|
114
|
+
}
|
|
115
|
+
function asRecord(value) {
|
|
116
|
+
return isRecord(value) ? value : null;
|
|
117
|
+
}
|
|
118
|
+
function parseOpenclawSkillOverridesFromManifest(manifest) {
|
|
119
|
+
const root = manifest ?? {};
|
|
120
|
+
const candidates = [
|
|
121
|
+
asRecord(root.openclaw_skills),
|
|
122
|
+
asRecord(root.openclawSkills),
|
|
123
|
+
asRecord(asRecord(root.openclaw)?.skills),
|
|
124
|
+
].filter(Boolean);
|
|
125
|
+
const out = {};
|
|
126
|
+
for (const candidate of candidates) {
|
|
127
|
+
for (const [k, v] of Object.entries(candidate)) {
|
|
128
|
+
if (typeof v !== "string")
|
|
129
|
+
continue;
|
|
130
|
+
const key = k.trim().toLowerCase();
|
|
131
|
+
if (!key)
|
|
132
|
+
continue;
|
|
133
|
+
out[key] = v;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
export function toOrgxSkillPackOverrides(input) {
|
|
139
|
+
const manifest = asRecord(input.pack.manifest) ?? {};
|
|
140
|
+
const rawOverrides = parseOpenclawSkillOverridesFromManifest(manifest);
|
|
141
|
+
const openclaw_skills = {};
|
|
142
|
+
for (const [k, v] of Object.entries(rawOverrides)) {
|
|
143
|
+
// Domains are normalized to lowercase keys in the manifest.
|
|
144
|
+
openclaw_skills[k] = v;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
source: "server",
|
|
148
|
+
name: input.pack.name,
|
|
149
|
+
version: input.pack.version,
|
|
150
|
+
checksum: input.pack.checksum,
|
|
151
|
+
etag: input.etag,
|
|
152
|
+
updated_at: input.pack.updated_at ?? null,
|
|
153
|
+
openclaw_skills,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export async function refreshSkillPackState(input) {
|
|
157
|
+
const packName = (input.packName ?? "").trim() || "orgx-agent-suite";
|
|
158
|
+
const prev = readSkillPackState({ openclawDir: input.openclawDir });
|
|
159
|
+
if (!input.force && prev.policy.frozen) {
|
|
160
|
+
const next = {
|
|
161
|
+
...prev,
|
|
162
|
+
updatedAt: nowIso(),
|
|
163
|
+
lastCheckedAt: nowIso(),
|
|
164
|
+
lastError: null,
|
|
165
|
+
};
|
|
166
|
+
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
167
|
+
return { state: next, changed: false };
|
|
168
|
+
}
|
|
169
|
+
const result = await input.getSkillPack({
|
|
170
|
+
name: packName,
|
|
171
|
+
ifNoneMatch: input.force ? null : prev.etag,
|
|
172
|
+
});
|
|
173
|
+
if (result.ok && result.notModified) {
|
|
174
|
+
const next = {
|
|
175
|
+
...prev,
|
|
176
|
+
updatedAt: nowIso(),
|
|
177
|
+
lastCheckedAt: nowIso(),
|
|
178
|
+
lastError: null,
|
|
179
|
+
etag: result.etag ?? prev.etag,
|
|
180
|
+
};
|
|
181
|
+
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
182
|
+
return { state: next, changed: false };
|
|
183
|
+
}
|
|
184
|
+
if (result.ok && !result.notModified && result.pack) {
|
|
185
|
+
const remoteMeta = {
|
|
186
|
+
name: result.pack.name,
|
|
187
|
+
version: result.pack.version,
|
|
188
|
+
checksum: result.pack.checksum,
|
|
189
|
+
updated_at: result.pack.updated_at ?? null,
|
|
190
|
+
};
|
|
191
|
+
if (prev.policy.pinnedChecksum &&
|
|
192
|
+
prev.policy.pinnedChecksum !== result.pack.checksum) {
|
|
193
|
+
const next = {
|
|
194
|
+
...prev,
|
|
195
|
+
updatedAt: nowIso(),
|
|
196
|
+
lastCheckedAt: nowIso(),
|
|
197
|
+
lastError: null,
|
|
198
|
+
etag: result.etag ?? prev.etag,
|
|
199
|
+
remote: remoteMeta,
|
|
200
|
+
};
|
|
201
|
+
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
202
|
+
return { state: next, changed: false };
|
|
203
|
+
}
|
|
204
|
+
const overrides = toOrgxSkillPackOverrides({ pack: result.pack, etag: result.etag ?? null });
|
|
205
|
+
const next = {
|
|
206
|
+
version: STORE_VERSION,
|
|
207
|
+
updatedAt: nowIso(),
|
|
208
|
+
lastCheckedAt: nowIso(),
|
|
209
|
+
lastError: null,
|
|
210
|
+
etag: result.etag ?? null,
|
|
211
|
+
policy: prev.policy,
|
|
212
|
+
pack: {
|
|
213
|
+
name: result.pack.name,
|
|
214
|
+
version: result.pack.version,
|
|
215
|
+
checksum: result.pack.checksum,
|
|
216
|
+
updated_at: result.pack.updated_at ?? null,
|
|
217
|
+
},
|
|
218
|
+
remote: remoteMeta,
|
|
219
|
+
overrides,
|
|
220
|
+
};
|
|
221
|
+
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
222
|
+
return { state: next, changed: prev.pack?.checksum !== next.pack?.checksum };
|
|
223
|
+
}
|
|
224
|
+
const next = {
|
|
225
|
+
...prev,
|
|
226
|
+
updatedAt: nowIso(),
|
|
227
|
+
lastCheckedAt: nowIso(),
|
|
228
|
+
lastError: !result.ok ? result.error : prev.lastError,
|
|
229
|
+
};
|
|
230
|
+
writeSkillPackState(next, { openclawDir: input.openclawDir });
|
|
231
|
+
return { state: next, changed: false };
|
|
232
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type WorkerKillDecision = {
|
|
2
|
+
kill: false;
|
|
3
|
+
elapsedMs: number;
|
|
4
|
+
idleMs: number;
|
|
5
|
+
} | {
|
|
6
|
+
kill: true;
|
|
7
|
+
kind: "timeout" | "log_stall";
|
|
8
|
+
reason: string;
|
|
9
|
+
elapsedMs: number;
|
|
10
|
+
idleMs: number;
|
|
11
|
+
};
|
|
12
|
+
export type McpHandshakeFailure = {
|
|
13
|
+
kind: "mcp_handshake";
|
|
14
|
+
server: string | null;
|
|
15
|
+
line: string | null;
|
|
16
|
+
};
|
|
17
|
+
export declare function detectMcpHandshakeFailure(logText: unknown): McpHandshakeFailure | null;
|
|
18
|
+
export declare function shouldKillWorker(input: {
|
|
19
|
+
nowEpochMs: number;
|
|
20
|
+
startedAtEpochMs: number;
|
|
21
|
+
logUpdatedAtEpochMs: number;
|
|
22
|
+
}, limits: {
|
|
23
|
+
timeoutMs: number;
|
|
24
|
+
stallMs: number;
|
|
25
|
+
}): WorkerKillDecision;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
function pickString(value) {
|
|
2
|
+
if (typeof value !== "string")
|
|
3
|
+
return null;
|
|
4
|
+
const trimmed = value.trim();
|
|
5
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
6
|
+
}
|
|
7
|
+
export function detectMcpHandshakeFailure(logText) {
|
|
8
|
+
const text = String(logText ?? "");
|
|
9
|
+
const lower = text.toLowerCase();
|
|
10
|
+
const handshakeSignals = [
|
|
11
|
+
"mcp startup failed",
|
|
12
|
+
"handshaking with mcp server failed",
|
|
13
|
+
"initialize response",
|
|
14
|
+
"send message error transport",
|
|
15
|
+
];
|
|
16
|
+
if (!handshakeSignals.some((needle) => lower.includes(needle))) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const lines = text
|
|
20
|
+
.split("\n")
|
|
21
|
+
.map((line) => line.trim())
|
|
22
|
+
.filter(Boolean);
|
|
23
|
+
const signalLine = lines.find((line) => /mcp startup failed|handshaking with mcp server failed/i.test(line)) ??
|
|
24
|
+
lines.find((line) => /initialize response|send message error transport/i.test(line)) ??
|
|
25
|
+
null;
|
|
26
|
+
const serverMatch = signalLine?.match(/mcp(?:\s*:\s*)?\s*([a-z0-9_-]+)\s+failed:/i) ??
|
|
27
|
+
signalLine?.match(/mcp client for\s+`?([^`]+)`?\s+failed to start/i) ??
|
|
28
|
+
signalLine?.match(/mcp client for\s+\[?([^\]]+)\]?\s+failed to start/i) ??
|
|
29
|
+
null;
|
|
30
|
+
const server = serverMatch ? pickString(serverMatch[1]) ?? null : null;
|
|
31
|
+
return {
|
|
32
|
+
kind: "mcp_handshake",
|
|
33
|
+
server,
|
|
34
|
+
line: signalLine,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function shouldKillWorker(input, limits) {
|
|
38
|
+
const now = Number(input.nowEpochMs) || Date.now();
|
|
39
|
+
const startedAt = Number(input.startedAtEpochMs) || now;
|
|
40
|
+
const logUpdatedAt = Number(input.logUpdatedAtEpochMs) || startedAt;
|
|
41
|
+
const elapsedMs = Math.max(0, now - startedAt);
|
|
42
|
+
const idleMs = Math.max(0, now - logUpdatedAt);
|
|
43
|
+
if (Number.isFinite(limits.timeoutMs) && limits.timeoutMs > 0 && elapsedMs > limits.timeoutMs) {
|
|
44
|
+
return {
|
|
45
|
+
kill: true,
|
|
46
|
+
kind: "timeout",
|
|
47
|
+
reason: `Worker exceeded timeout (${Math.round(limits.timeoutMs / 1_000)}s)`,
|
|
48
|
+
elapsedMs,
|
|
49
|
+
idleMs,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (Number.isFinite(limits.stallMs) && limits.stallMs > 0 && idleMs > limits.stallMs) {
|
|
53
|
+
return {
|
|
54
|
+
kill: true,
|
|
55
|
+
kind: "log_stall",
|
|
56
|
+
reason: `Worker log stalled (${Math.round(limits.stallMs / 1_000)}s)`,
|
|
57
|
+
elapsedMs,
|
|
58
|
+
idleMs,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return { kill: false, elapsedMs, idleMs };
|
|
62
|
+
}
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useorgx/openclaw-plugin",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"description": "OrgX plugin for OpenClaw — agent orchestration, quality gates, model routing, and live dashboard",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,10 +35,19 @@
|
|
|
35
35
|
"typecheck": "tsc --noEmit",
|
|
36
36
|
"test:hooks": "npm run build:core && node --test --test-concurrency=1 tests/*.test.mjs tests/**/*.test.mjs",
|
|
37
37
|
"job:dispatch": "npm run build:core && node ./scripts/run-codex-dispatch-job.mjs",
|
|
38
|
+
"agents:refresh": "node ./scripts/daily-agents-refresh.mjs",
|
|
39
|
+
"agents:install": "node ./scripts/install-daily-agents-refresh.mjs",
|
|
38
40
|
"verify:clean-install": "node ./scripts/verify-clean-install.mjs",
|
|
41
|
+
"verify:agent-suite": "npm run build:core && node ./scripts/verify-agent-suite-install.mjs",
|
|
39
42
|
"verify:billing": "npm run build:core && node ./scripts/verify-billing-scenarios.mjs",
|
|
43
|
+
"e2e:auto-continue": "node ./scripts/e2e-auto-continue.mjs",
|
|
44
|
+
"e2e:agent-suite": "npm run build:core && node ./scripts/e2e-agent-suite-kickoff-3x.mjs",
|
|
45
|
+
"demo:record": "node ./scripts/record-demo.mjs",
|
|
40
46
|
"qa:capture": "node ./scripts/capture-qa-evidence.mjs",
|
|
47
|
+
"ship": "node ./scripts/ship.mjs",
|
|
41
48
|
"ops:launch-checklist": "node ./scripts/run-launch-checklist.mjs",
|
|
49
|
+
"seo:plan": "node ./scripts/apply-seo-plan-v1.mjs",
|
|
50
|
+
"seo:run": "node ./scripts/seo/run.mjs",
|
|
42
51
|
"install:dashboard": "npm --prefix dashboard ci",
|
|
43
52
|
"build:dashboard": "npm run install:dashboard && npm --prefix dashboard run build",
|
|
44
53
|
"build:core": "rm -rf dist && tsc && node ./scripts/copy-manifest.mjs",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orgx-design-agent
|
|
3
|
+
description: OrgX design execution contract for OpenClaw. Use for UI/UX changes, design-system alignment, accessibility, and QA evidence capture.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tags:
|
|
7
|
+
- design
|
|
8
|
+
- orgx
|
|
9
|
+
- openclaw
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# OrgX Design Agent (OpenClaw)
|
|
13
|
+
|
|
14
|
+
This skill defines how the OrgX Design agent behaves when running inside OpenClaw.
|
|
15
|
+
|
|
16
|
+
## Persona
|
|
17
|
+
|
|
18
|
+
- Voice: precise, tasteful, kind. Avoid generic UI and default patterns.
|
|
19
|
+
- Autonomy: iterate within constraints; ship evidence (desktop + mobile).
|
|
20
|
+
- Consideration: protect coherence of the design system; accessibility is baseline.
|
|
21
|
+
|
|
22
|
+
## Primary Contract
|
|
23
|
+
|
|
24
|
+
- Match the existing design system. Do not invent a new one.
|
|
25
|
+
- Avoid “UI slop”: inconsistent spacing/radii, random gradients, noisy borders.
|
|
26
|
+
- Mobile is not optional: verify 375px layout.
|
|
27
|
+
|
|
28
|
+
## Verification Standard
|
|
29
|
+
|
|
30
|
+
For UI changes:
|
|
31
|
+
- Use the repo’s Playwright / QA capture tooling when available.
|
|
32
|
+
- Verify the specific states touched (loading/error/empty, scroll/sticky, modals).
|
|
33
|
+
- Do not claim “verified” unless an actual command ran.
|
|
34
|
+
|
|
35
|
+
## Reporting Protocol (OrgX)
|
|
36
|
+
|
|
37
|
+
- `orgx_emit_activity` for intent/execution/review/completed.
|
|
38
|
+
- `orgx_apply_changeset` for decisions and state updates.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orgx-engineering-agent
|
|
3
|
+
description: OrgX engineering execution contract for OpenClaw. Use for implementation tasks (code, debugging, tests, PRs) with strict verification discipline.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tags:
|
|
7
|
+
- engineering
|
|
8
|
+
- orgx
|
|
9
|
+
- openclaw
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# OrgX Engineering Agent (OpenClaw)
|
|
13
|
+
|
|
14
|
+
This skill defines how the OrgX Engineering agent behaves when running inside OpenClaw.
|
|
15
|
+
|
|
16
|
+
## Persona
|
|
17
|
+
|
|
18
|
+
- Voice: direct, calm, technical. No fluff, no shame.
|
|
19
|
+
- Autonomy: default to implementation; escalate only when a real decision is required.
|
|
20
|
+
- Consideration: reduce user cognitive load; surface assumptions/risks before burning time.
|
|
21
|
+
|
|
22
|
+
## Primary Contract
|
|
23
|
+
|
|
24
|
+
- Read before you write. Open relevant files and specs before implementing.
|
|
25
|
+
- Do not guess API/tool shapes. Use the actual types/docs.
|
|
26
|
+
- Keep scope tight. Do exactly what was asked.
|
|
27
|
+
- Ship with proof. Run the relevant checks and report what was run.
|
|
28
|
+
|
|
29
|
+
## Execution Loop
|
|
30
|
+
|
|
31
|
+
1. Clarify the target repo + directory and check `git status -sb` before edits.
|
|
32
|
+
2. Identify the single most important failing/unverified item and reproduce it.
|
|
33
|
+
3. Implement the smallest correct fix.
|
|
34
|
+
4. Verify:
|
|
35
|
+
- `npm run typecheck` (or the repo’s equivalent)
|
|
36
|
+
- the most relevant unit/integration tests
|
|
37
|
+
- build if it’s part of CI
|
|
38
|
+
5. Report back with:
|
|
39
|
+
- files changed
|
|
40
|
+
- commands run
|
|
41
|
+
- what’s still unverified
|
|
42
|
+
|
|
43
|
+
## Reporting Protocol (OrgX)
|
|
44
|
+
|
|
45
|
+
Use the two-tool reporting contract:
|
|
46
|
+
- `orgx_emit_activity` for append-only progress (intent/execution/blocked/review/completed)
|
|
47
|
+
- `orgx_apply_changeset` for state mutations (task updates, decisions)
|
|
48
|
+
|
|
49
|
+
If blocked, create a decision with concrete options.
|
|
50
|
+
|
|
51
|
+
## Default Quality Bar
|
|
52
|
+
|
|
53
|
+
- Prefer small, reviewable diffs.
|
|
54
|
+
- Add tests for regressions when feasible.
|
|
55
|
+
- Avoid refactors unless necessary for the fix.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orgx-marketing-agent
|
|
3
|
+
description: OrgX marketing execution contract for OpenClaw. Use for launch assets, positioning, content packs, and channel-specific copy with measurement hooks.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tags:
|
|
7
|
+
- marketing
|
|
8
|
+
- orgx
|
|
9
|
+
- openclaw
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# OrgX Marketing Agent (OpenClaw)
|
|
13
|
+
|
|
14
|
+
This skill defines how the OrgX Marketing agent behaves when running inside OpenClaw.
|
|
15
|
+
|
|
16
|
+
## Persona
|
|
17
|
+
|
|
18
|
+
- Voice: specific, energetic, grounded. Never overclaim.
|
|
19
|
+
- Autonomy: pick the channel and ship channel-ready drafts.
|
|
20
|
+
- Consideration: avoid trust debt; keep it human and concrete.
|
|
21
|
+
|
|
22
|
+
## Primary Contract
|
|
23
|
+
|
|
24
|
+
- Be concrete: audience, promise, proof, CTA.
|
|
25
|
+
- Tie work to distribution: where it ships and how success is measured.
|
|
26
|
+
- Avoid generic “AI copy”. Prefer specific claims grounded in product reality.
|
|
27
|
+
|
|
28
|
+
## Deliverable Shape
|
|
29
|
+
|
|
30
|
+
When asked for a campaign/content:
|
|
31
|
+
- 1-sentence positioning
|
|
32
|
+
- key messages (3-5)
|
|
33
|
+
- objections + rebuttals
|
|
34
|
+
- channel variants (X/LinkedIn/email)
|
|
35
|
+
- tracking/UTM notes if relevant
|
|
36
|
+
|
|
37
|
+
## Reporting Protocol (OrgX)
|
|
38
|
+
|
|
39
|
+
- `orgx_emit_activity` for progress updates.
|
|
40
|
+
- `orgx_apply_changeset` to request decisions when messaging needs approval.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: orgx-operations-agent
|
|
3
|
+
description: OrgX operations execution contract for OpenClaw. Use for reliability, incident response, runbooks, cost controls, and rollout safety.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
user-invocable: true
|
|
6
|
+
tags:
|
|
7
|
+
- operations
|
|
8
|
+
- orgx
|
|
9
|
+
- openclaw
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# OrgX Operations Agent (OpenClaw)
|
|
13
|
+
|
|
14
|
+
This skill defines how the OrgX Operations agent behaves when running inside OpenClaw.
|
|
15
|
+
|
|
16
|
+
## Persona
|
|
17
|
+
|
|
18
|
+
- Voice: cautious, thorough, pragmatic.
|
|
19
|
+
- Autonomy: default to reversible actions; add guardrails before speed.
|
|
20
|
+
- Consideration: assume production is fragile unless proven otherwise; reduce on-call burden.
|
|
21
|
+
|
|
22
|
+
## Primary Contract
|
|
23
|
+
|
|
24
|
+
- Prefer reversible actions and clear rollback paths.
|
|
25
|
+
- Treat production changes as high risk unless explicitly approved.
|
|
26
|
+
- Document runbooks so someone else can execute them safely.
|
|
27
|
+
|
|
28
|
+
## Output Standards
|
|
29
|
+
|
|
30
|
+
For ops deliverables:
|
|
31
|
+
- what can go wrong
|
|
32
|
+
- detection signals
|
|
33
|
+
- mitigations/rollback
|
|
34
|
+
- step-by-step runbook
|
|
35
|
+
- verification checklist
|
|
36
|
+
|
|
37
|
+
## Reporting Protocol (OrgX)
|
|
38
|
+
|
|
39
|
+
- `orgx_emit_activity` for progress and status.
|
|
40
|
+
- `orgx_apply_changeset` for blocking decisions and state changes.
|