@useorgx/openclaw-plugin 0.4.5 → 0.4.8

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 (60) hide show
  1. package/README.md +333 -26
  2. package/dashboard/dist/assets/B3ziCA02.js +8 -0
  3. package/dashboard/dist/assets/BNeJ0kpF.js +1 -0
  4. package/dashboard/dist/assets/BzkiMPmM.js +215 -0
  5. package/dashboard/dist/assets/CUV9IHHi.js +1 -0
  6. package/dashboard/dist/assets/CpJsfbXo.js +9 -0
  7. package/dashboard/dist/assets/Ie7d9Iq2.css +1 -0
  8. package/dashboard/dist/assets/sAhvFnpk.js +4 -0
  9. package/dashboard/dist/index.html +5 -5
  10. package/dist/activity-actor-fields.d.ts +3 -0
  11. package/dist/activity-actor-fields.js +128 -0
  12. package/dist/activity-store.d.ts +28 -0
  13. package/dist/activity-store.js +257 -0
  14. package/dist/agent-context-store.d.ts +19 -0
  15. package/dist/agent-context-store.js +60 -3
  16. package/dist/agent-suite.d.ts +83 -0
  17. package/dist/agent-suite.js +615 -0
  18. package/dist/artifacts/register-artifact.d.ts +47 -0
  19. package/dist/artifacts/register-artifact.js +271 -0
  20. package/dist/auth-store.js +8 -13
  21. package/dist/contracts/client.d.ts +23 -1
  22. package/dist/contracts/client.js +127 -8
  23. package/dist/contracts/types.d.ts +194 -1
  24. package/dist/entity-comment-store.d.ts +29 -0
  25. package/dist/entity-comment-store.js +190 -0
  26. package/dist/hooks/post-reporting-event.mjs +326 -0
  27. package/dist/http-handler.d.ts +7 -1
  28. package/dist/http-handler.js +4500 -534
  29. package/dist/index.js +1078 -68
  30. package/dist/local-openclaw.js +8 -0
  31. package/dist/mcp-client-setup.js +145 -28
  32. package/dist/mcp-http-handler.d.ts +17 -0
  33. package/dist/mcp-http-handler.js +144 -3
  34. package/dist/next-up-queue-store.d.ts +31 -0
  35. package/dist/next-up-queue-store.js +169 -0
  36. package/dist/openclaw.plugin.json +1 -1
  37. package/dist/outbox.d.ts +1 -1
  38. package/dist/runtime-instance-store.d.ts +1 -1
  39. package/dist/runtime-instance-store.js +19 -2
  40. package/dist/skill-pack-state.d.ts +69 -0
  41. package/dist/skill-pack-state.js +232 -0
  42. package/dist/worker-supervisor.d.ts +25 -0
  43. package/dist/worker-supervisor.js +77 -0
  44. package/openclaw.plugin.json +1 -1
  45. package/package.json +15 -1
  46. package/skills/orgx-design-agent/SKILL.md +38 -0
  47. package/skills/orgx-engineering-agent/SKILL.md +55 -0
  48. package/skills/orgx-marketing-agent/SKILL.md +40 -0
  49. package/skills/orgx-operations-agent/SKILL.md +40 -0
  50. package/skills/orgx-orchestrator-agent/SKILL.md +45 -0
  51. package/skills/orgx-product-agent/SKILL.md +39 -0
  52. package/skills/orgx-sales-agent/SKILL.md +40 -0
  53. package/skills/ship/SKILL.md +63 -0
  54. package/dashboard/dist/assets/B68j2crt.js +0 -1
  55. package/dashboard/dist/assets/BZZ-fiJx.js +0 -32
  56. package/dashboard/dist/assets/BoXlCHKa.js +0 -9
  57. package/dashboard/dist/assets/Bq9x_Xyh.css +0 -1
  58. package/dashboard/dist/assets/DBhrRVdp.js +0 -1
  59. package/dashboard/dist/assets/DD1jv1Hd.js +0 -8
  60. package/dashboard/dist/assets/DNjbmawF.js +0 -214
@@ -15,6 +15,14 @@ export interface OrgXConfig {
15
15
  syncIntervalMs: number;
16
16
  /** Plugin enabled */
17
17
  enabled: boolean;
18
+ /**
19
+ * When true (default), provision/update the OrgX agent suite automatically
20
+ * after a successful connection/sync.
21
+ *
22
+ * Safe by default: provisioning uses managed/local overlays and skips files
23
+ * that appear to have out-of-band edits ("conflict").
24
+ */
25
+ autoInstallAgentSuiteOnConnect?: boolean;
18
26
  }
19
27
  export type OnboardingStatus = 'idle' | 'starting' | 'awaiting_browser_auth' | 'pairing' | 'connected' | 'error' | 'manual_key';
20
28
  export type OnboardingNextAction = 'connect' | 'wait_for_browser' | 'open_dashboard' | 'enter_manual_key' | 'retry' | 'reconnect';
@@ -45,6 +53,119 @@ export interface OrgSnapshot {
45
53
  /** Last sync timestamp */
46
54
  syncedAt: string;
47
55
  }
56
+ export type KickoffContextScope = {
57
+ initiative_id?: string | null;
58
+ workstream_id?: string | null;
59
+ task_id?: string | null;
60
+ };
61
+ export type KickoffContextEntityRef = {
62
+ id: string;
63
+ title: string;
64
+ status?: string | null;
65
+ summary?: string | null;
66
+ url?: string | null;
67
+ metadata?: Record<string, unknown> | null;
68
+ };
69
+ export type KickoffContextToolScope = {
70
+ allow?: string[];
71
+ deny?: string[];
72
+ notes?: string | null;
73
+ };
74
+ export interface KickoffContext {
75
+ /** Deterministic hash of the payload used to render a kickoff message. */
76
+ context_hash: string;
77
+ /** Optional schema version for forward/back compat. */
78
+ schema_version?: string | null;
79
+ /** Human-friendly overview sentence(s). */
80
+ overview?: string | null;
81
+ initiative?: KickoffContextEntityRef | null;
82
+ workstream?: KickoffContextEntityRef | null;
83
+ task?: (KickoffContextEntityRef & {
84
+ description?: string | null;
85
+ checklist?: string[] | null;
86
+ }) | null;
87
+ acceptance_criteria?: string[] | null;
88
+ constraints?: string[] | null;
89
+ risks?: string[] | null;
90
+ decisions?: KickoffContextEntityRef[] | null;
91
+ artifacts?: KickoffContextEntityRef[] | null;
92
+ tool_scope?: KickoffContextToolScope | null;
93
+ reporting_expectations?: string[] | null;
94
+ /** Server-provided hints for agent tone/behavior; optional. */
95
+ persona?: {
96
+ voice?: string | null;
97
+ collaboration_style?: string | null;
98
+ defaults?: string[] | null;
99
+ } | null;
100
+ }
101
+ export type KickoffContextRequest = KickoffContextScope & {
102
+ agent_id?: string | null;
103
+ domain?: string | null;
104
+ required_skills?: string[] | null;
105
+ message?: string | null;
106
+ };
107
+ export type KickoffContextResponse = {
108
+ ok: true;
109
+ data: KickoffContext;
110
+ } | {
111
+ ok: false;
112
+ error: string;
113
+ };
114
+ export type OrgxAgentDomain = "engineering" | "product" | "design" | "marketing" | "sales" | "operations" | "orchestration";
115
+ /**
116
+ * AgentProfile describes the stable agent identity + workspace configuration
117
+ * needed to instantiate OrgX agents in OpenClaw.
118
+ *
119
+ * Note: this is a provisioning contract (what to install/configure), not an
120
+ * execution record (runs/sessions).
121
+ */
122
+ export type OrgxAgentProfile = {
123
+ id: string;
124
+ name: string;
125
+ domain: OrgxAgentDomain;
126
+ workspace: string;
127
+ required_skills?: string[] | null;
128
+ tool_scope?: KickoffContextToolScope | null;
129
+ persona?: KickoffContext["persona"] | null;
130
+ };
131
+ export type OrgxAgentPack = {
132
+ pack_id: string;
133
+ pack_version: string;
134
+ schema_version?: string | null;
135
+ skill_pack?: {
136
+ name: string;
137
+ version: string;
138
+ checksum: string;
139
+ } | null;
140
+ agents: OrgxAgentProfile[];
141
+ managed_files: string[];
142
+ };
143
+ export type SkillPack = {
144
+ name: string;
145
+ version: string;
146
+ checksum: string;
147
+ status?: "draft" | "pending_review" | "approved" | "rejected" | string;
148
+ manifest: Record<string, unknown>;
149
+ required_scopes?: string[] | null;
150
+ required_tools?: string[] | null;
151
+ updated_at?: string | null;
152
+ };
153
+ /**
154
+ * Canonical manifest shape expected by the OpenClaw plugin.
155
+ *
156
+ * Stored in `skill_packs.manifest` on the OrgX server.
157
+ */
158
+ export type OpenClawSkillPackManifestV1 = {
159
+ schema_version: string;
160
+ openclaw_skills: Partial<Record<OrgxAgentDomain, string>>;
161
+ };
162
+ export type SkillPackResponse = {
163
+ ok: true;
164
+ data: SkillPack;
165
+ } | {
166
+ ok: false;
167
+ error: string;
168
+ };
48
169
  export interface Initiative {
49
170
  id: string;
50
171
  title: string;
@@ -349,13 +470,81 @@ export interface ApplyChangesetResponse {
349
470
  event_id: string | null;
350
471
  auth_mode?: 'service' | 'api_key';
351
472
  }
473
+ export interface RecordRunOutcomeRequest {
474
+ initiative_id: string;
475
+ execution_id: string;
476
+ execution_type: string;
477
+ agent_id: string;
478
+ task_type?: string;
479
+ domain?: string;
480
+ started_at?: string;
481
+ completed_at?: string;
482
+ inputs?: Record<string, unknown>;
483
+ outputs?: Record<string, unknown>;
484
+ steps?: Array<Record<string, unknown>>;
485
+ success: boolean;
486
+ quality_score?: number;
487
+ duration_vs_estimate?: number;
488
+ cost_vs_budget?: number;
489
+ human_interventions?: number;
490
+ user_satisfaction?: number;
491
+ errors?: string[];
492
+ metadata?: Record<string, unknown>;
493
+ run_id?: string;
494
+ correlation_id?: string;
495
+ source_client?: ReportingSourceClient;
496
+ }
497
+ export interface RecordRunOutcomeResponse {
498
+ ok: true;
499
+ run_id: string;
500
+ reused_run: boolean;
501
+ execution_id: string;
502
+ event_id: string | null;
503
+ auth_mode?: 'service' | 'api_key';
504
+ }
505
+ export type RetroFollowUpPriority = 'p0' | 'p1' | 'p2';
506
+ export interface RetroJson {
507
+ summary: string;
508
+ what_went_well?: string[];
509
+ what_went_wrong?: string[];
510
+ decisions?: string[];
511
+ follow_ups?: Array<{
512
+ title: string;
513
+ priority?: RetroFollowUpPriority;
514
+ reason?: string;
515
+ }>;
516
+ signals?: Record<string, unknown>;
517
+ }
518
+ export type RetroEntityType = 'initiative' | 'workstream' | 'milestone' | 'task';
519
+ export interface RecordRunRetroRequest {
520
+ initiative_id: string;
521
+ entity_type?: RetroEntityType;
522
+ entity_id?: string;
523
+ title?: string;
524
+ idempotency_key?: string;
525
+ retro: RetroJson;
526
+ markdown?: string;
527
+ run_id?: string;
528
+ correlation_id?: string;
529
+ source_client?: ReportingSourceClient;
530
+ }
531
+ export interface RecordRunRetroResponse {
532
+ ok: true;
533
+ run_id: string;
534
+ reused_run: boolean;
535
+ work_artifact_id: string | null;
536
+ run_step_id: string | null;
537
+ run_artifact_id: string | null;
538
+ event_id: string | null;
539
+ auth_mode?: 'service' | 'api_key';
540
+ }
352
541
  export type LiveActivityType = 'run_started' | 'run_completed' | 'run_failed' | 'artifact_created' | 'decision_requested' | 'decision_resolved' | 'handoff_requested' | 'handoff_claimed' | 'handoff_fulfilled' | 'blocker_created' | 'milestone_completed' | 'delegation';
353
542
  export type RuntimeInstanceState = 'active' | 'stale' | 'stopped' | 'error';
354
543
  export interface RuntimeInstance {
355
544
  id: string;
356
545
  sourceClient: RuntimeSourceClient;
357
546
  displayName: string;
358
- providerLogo: 'openai' | 'anthropic' | 'openclaw' | 'orgx' | 'unknown';
547
+ providerLogo: 'codex' | 'openai' | 'anthropic' | 'openclaw' | 'orgx' | 'unknown';
359
548
  state: RuntimeInstanceState;
360
549
  runId: string | null;
361
550
  correlationId: string | null;
@@ -379,6 +568,10 @@ export interface LiveActivityItem {
379
568
  description: string | null;
380
569
  agentId: string | null;
381
570
  agentName: string | null;
571
+ requesterAgentId: string | null;
572
+ requesterAgentName: string | null;
573
+ executorAgentId: string | null;
574
+ executorAgentName: string | null;
382
575
  runId: string | null;
383
576
  initiativeId: string | null;
384
577
  timestamp: string;
@@ -0,0 +1,29 @@
1
+ export type EntityCommentAuthorType = "human" | "agent" | "system";
2
+ export type EntityCommentRecord = {
3
+ id: string;
4
+ parent_comment_id: string | null;
5
+ author_type: EntityCommentAuthorType;
6
+ author_id: string;
7
+ author_name: string | null;
8
+ body: string;
9
+ comment_type: string;
10
+ severity: string;
11
+ tags: string[] | null;
12
+ created_at: string;
13
+ };
14
+ export declare function listEntityComments(entityType: string, entityId: string): EntityCommentRecord[];
15
+ export declare function appendEntityComment(input: {
16
+ entityType: string;
17
+ entityId: string;
18
+ body: string;
19
+ commentType?: string | null;
20
+ severity?: string | null;
21
+ tags?: unknown;
22
+ author?: {
23
+ author_type?: EntityCommentAuthorType;
24
+ author_id?: string;
25
+ author_name?: string | null;
26
+ };
27
+ }): EntityCommentRecord;
28
+ export declare function mergeEntityComments(remote: unknown, local: EntityCommentRecord[]): EntityCommentRecord[];
29
+ export declare function clearEntityCommentsStore(): void;
@@ -0,0 +1,190 @@
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, } from "node:fs";
2
+ import { randomUUID } from "node:crypto";
3
+ import { getOrgxPluginConfigDir, getOrgxPluginConfigPath } from "./paths.js";
4
+ import { backupCorruptFileSync, writeJsonFileAtomicSync } from "./fs-utils.js";
5
+ const MAX_COMMENTS_PER_ENTITY = 240;
6
+ const MAX_TOTAL_COMMENTS = 1_500;
7
+ function commentsDir() {
8
+ return getOrgxPluginConfigDir();
9
+ }
10
+ function commentsFile() {
11
+ return getOrgxPluginConfigPath("entity-comments.json");
12
+ }
13
+ function ensureDir() {
14
+ const dir = commentsDir();
15
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
16
+ try {
17
+ chmodSync(dir, 0o700);
18
+ }
19
+ catch {
20
+ // best effort
21
+ }
22
+ }
23
+ function parseJson(value) {
24
+ try {
25
+ return JSON.parse(value);
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ function entityKey(entityType, entityId) {
32
+ return `${entityType.trim().toLowerCase()}:${entityId.trim()}`;
33
+ }
34
+ function normalizeTags(value) {
35
+ if (!Array.isArray(value))
36
+ return null;
37
+ const tags = value
38
+ .map((item) => (typeof item === "string" ? item.trim() : ""))
39
+ .filter((item) => item.length > 0);
40
+ return tags.length > 0 ? tags.slice(0, 16) : [];
41
+ }
42
+ function normalizeComment(input) {
43
+ const createdAt = typeof input.created_at === "string" ? input.created_at : new Date().toISOString();
44
+ return {
45
+ id: typeof input.id === "string" && input.id.trim().length > 0 ? input.id.trim() : `local_${randomUUID()}`,
46
+ parent_comment_id: typeof input.parent_comment_id === "string" && input.parent_comment_id.trim().length > 0
47
+ ? input.parent_comment_id.trim()
48
+ : null,
49
+ author_type: input.author_type === "agent" || input.author_type === "system" ? input.author_type : "human",
50
+ author_id: typeof input.author_id === "string" && input.author_id.trim().length > 0 ? input.author_id.trim() : "local_user",
51
+ author_name: typeof input.author_name === "string" && input.author_name.trim().length > 0 ? input.author_name.trim() : null,
52
+ body: typeof input.body === "string" ? input.body : "",
53
+ comment_type: typeof input.comment_type === "string" && input.comment_type.trim().length > 0 ? input.comment_type.trim() : "note",
54
+ severity: typeof input.severity === "string" && input.severity.trim().length > 0 ? input.severity.trim() : "info",
55
+ tags: normalizeTags(input.tags) ?? [],
56
+ created_at: createdAt,
57
+ };
58
+ }
59
+ function readStore() {
60
+ const file = commentsFile();
61
+ try {
62
+ if (!existsSync(file)) {
63
+ return { updatedAt: new Date().toISOString(), commentsByEntity: {} };
64
+ }
65
+ const raw = readFileSync(file, "utf8");
66
+ const parsed = parseJson(raw);
67
+ if (!parsed || typeof parsed !== "object") {
68
+ backupCorruptFileSync(file);
69
+ return { updatedAt: new Date().toISOString(), commentsByEntity: {} };
70
+ }
71
+ const commentsByEntity = parsed.commentsByEntity && typeof parsed.commentsByEntity === "object"
72
+ ? parsed.commentsByEntity
73
+ : {};
74
+ return {
75
+ updatedAt: typeof parsed.updatedAt === "string" ? parsed.updatedAt : new Date().toISOString(),
76
+ commentsByEntity,
77
+ };
78
+ }
79
+ catch {
80
+ return { updatedAt: new Date().toISOString(), commentsByEntity: {} };
81
+ }
82
+ }
83
+ function writeStore(store) {
84
+ ensureDir();
85
+ const file = commentsFile();
86
+ writeJsonFileAtomicSync(file, store, 0o600);
87
+ }
88
+ function trimStore(store) {
89
+ const next = {
90
+ updatedAt: store.updatedAt,
91
+ commentsByEntity: { ...store.commentsByEntity },
92
+ };
93
+ for (const [key, comments] of Object.entries(next.commentsByEntity)) {
94
+ if (!Array.isArray(comments) || comments.length === 0) {
95
+ delete next.commentsByEntity[key];
96
+ continue;
97
+ }
98
+ const normalized = comments.map((c) => normalizeComment(c));
99
+ normalized.sort((a, b) => Date.parse(a.created_at) - Date.parse(b.created_at));
100
+ next.commentsByEntity[key] = normalized.slice(-MAX_COMMENTS_PER_ENTITY);
101
+ }
102
+ const all = [];
103
+ for (const [key, comments] of Object.entries(next.commentsByEntity)) {
104
+ for (const comment of comments)
105
+ all.push({ key, comment });
106
+ }
107
+ if (all.length <= MAX_TOTAL_COMMENTS)
108
+ return next;
109
+ all.sort((a, b) => Date.parse(b.comment.created_at) - Date.parse(a.comment.created_at));
110
+ const keep = all.slice(0, MAX_TOTAL_COMMENTS);
111
+ const keepByEntity = new Map();
112
+ for (const item of keep) {
113
+ const list = keepByEntity.get(item.key) ?? [];
114
+ list.push(item.comment);
115
+ keepByEntity.set(item.key, list);
116
+ }
117
+ const rebuilt = {};
118
+ for (const [key, list] of keepByEntity.entries()) {
119
+ list.sort((a, b) => Date.parse(a.created_at) - Date.parse(b.created_at));
120
+ rebuilt[key] = list;
121
+ }
122
+ next.commentsByEntity = rebuilt;
123
+ return next;
124
+ }
125
+ export function listEntityComments(entityType, entityId) {
126
+ const key = entityKey(entityType, entityId);
127
+ const store = readStore();
128
+ const list = store.commentsByEntity[key];
129
+ if (!Array.isArray(list) || list.length === 0)
130
+ return [];
131
+ return list.map((c) => normalizeComment(c));
132
+ }
133
+ export function appendEntityComment(input) {
134
+ const body = input.body.trim();
135
+ if (!body) {
136
+ throw new Error("comment body is required");
137
+ }
138
+ const key = entityKey(input.entityType, input.entityId);
139
+ const now = new Date().toISOString();
140
+ const record = normalizeComment({
141
+ id: `local_${randomUUID()}`,
142
+ parent_comment_id: null,
143
+ author_type: input.author?.author_type ?? "human",
144
+ author_id: input.author?.author_id ?? "local_user",
145
+ author_name: input.author?.author_name ?? null,
146
+ body,
147
+ comment_type: (input.commentType ?? "note") || "note",
148
+ severity: (input.severity ?? "info") || "info",
149
+ tags: normalizeTags(input.tags) ?? [],
150
+ created_at: now,
151
+ });
152
+ const store = readStore();
153
+ const existing = Array.isArray(store.commentsByEntity[key]) ? store.commentsByEntity[key] : [];
154
+ const next = {
155
+ updatedAt: now,
156
+ commentsByEntity: {
157
+ ...store.commentsByEntity,
158
+ [key]: [...existing, record],
159
+ },
160
+ };
161
+ const trimmed = trimStore(next);
162
+ writeStore(trimmed);
163
+ return record;
164
+ }
165
+ export function mergeEntityComments(remote, local) {
166
+ const remoteList = Array.isArray(remote) ? remote : [];
167
+ const merged = new Map();
168
+ for (const comment of remoteList) {
169
+ if (!comment || typeof comment !== "object")
170
+ continue;
171
+ const record = normalizeComment(comment);
172
+ merged.set(record.id, record);
173
+ }
174
+ for (const comment of local) {
175
+ const record = normalizeComment(comment);
176
+ merged.set(record.id, record);
177
+ }
178
+ const list = Array.from(merged.values());
179
+ list.sort((a, b) => Date.parse(a.created_at) - Date.parse(b.created_at));
180
+ return list;
181
+ }
182
+ export function clearEntityCommentsStore() {
183
+ const file = commentsFile();
184
+ try {
185
+ rmSync(file, { force: true });
186
+ }
187
+ catch {
188
+ // best effort
189
+ }
190
+ }