ofiere-openclaw-plugin 4.3.1 → 4.4.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.
- package/package.json +1 -1
- package/src/tools.ts +96 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ofiere-openclaw-plugin",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw plugin for Ofiere PM - 10 meta-tools with 13-action workflow mastery covering tasks, agents, projects, scheduling, knowledge, workflows, notifications, memory, prompts, and constellation agent architecture",
|
|
6
6
|
"keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
|
package/src/tools.ts
CHANGED
|
@@ -2098,8 +2098,11 @@ function registerConstellationOps(
|
|
|
2098
2098
|
return path.join(OPENCLAW_ROOT, `workspace-${agentName.toLowerCase()}`);
|
|
2099
2099
|
}
|
|
2100
2100
|
|
|
2101
|
-
|
|
2102
|
-
|
|
2101
|
+
// System-generated .md files that OpenClaw creates automatically — not user-authored
|
|
2102
|
+
const SYSTEM_MD_FILES = new Set(["HEARTBEAT.md", "USER.md", "MEMORY.md"]);
|
|
2103
|
+
|
|
2104
|
+
function listWorkspaceAgents(): Array<{ name: string; codename: string; role: string; files: string[]; system_files: string[]; hasSkills: boolean }> {
|
|
2105
|
+
const result: Array<{ name: string; codename: string; role: string; files: string[]; system_files: string[]; hasSkills: boolean }> = [];
|
|
2103
2106
|
try {
|
|
2104
2107
|
const entries = fs.readdirSync(OPENCLAW_ROOT, { withFileTypes: true });
|
|
2105
2108
|
for (const entry of entries) {
|
|
@@ -2107,7 +2110,9 @@ function registerConstellationOps(
|
|
|
2107
2110
|
const agentName = entry.name.replace("workspace-", "");
|
|
2108
2111
|
if (agentName === "main" || agentName === "zero" || agentName === "echo") continue; // skip system agents
|
|
2109
2112
|
const wsPath = path.join(OPENCLAW_ROOT, entry.name);
|
|
2110
|
-
const
|
|
2113
|
+
const allMd = fs.readdirSync(wsPath).filter((f: string) => f.endsWith(".md"));
|
|
2114
|
+
const files = allMd.filter((f: string) => !SYSTEM_MD_FILES.has(f));
|
|
2115
|
+
const system_files = allMd.filter((f: string) => SYSTEM_MD_FILES.has(f));
|
|
2111
2116
|
// Try to extract codename and role from IDENTITY.md
|
|
2112
2117
|
let codename = agentName.toUpperCase();
|
|
2113
2118
|
let role = "Agent";
|
|
@@ -2119,7 +2124,7 @@ function registerConstellationOps(
|
|
|
2119
2124
|
if (roleMatch) role = roleMatch[1].trim();
|
|
2120
2125
|
} catch {}
|
|
2121
2126
|
const hasSkills = fs.existsSync(path.join(wsPath, "skills"));
|
|
2122
|
-
result.push({ name: agentName, codename, role, files, hasSkills });
|
|
2127
|
+
result.push({ name: agentName, codename, role, files, system_files, hasSkills });
|
|
2123
2128
|
}
|
|
2124
2129
|
} catch (e) {
|
|
2125
2130
|
api.logger?.warn?.(`[ofiere] Failed to list workspaces: ${e}`);
|
|
@@ -2158,6 +2163,7 @@ function registerConstellationOps(
|
|
|
2158
2163
|
if (p.emoji) lines.push(`**Emoji:** ${p.emoji}`);
|
|
2159
2164
|
lines.push(`**Role:** ${p.role || "Agent"}`);
|
|
2160
2165
|
lines.push(`**Codename:** ${p.codename}`);
|
|
2166
|
+
if (p.color_hex) lines.push(`**Color:** ${p.color_hex}`);
|
|
2161
2167
|
if (p.voice_sample) lines.push(`**Sample:** ${p.voice_sample}`);
|
|
2162
2168
|
lines.push("");
|
|
2163
2169
|
if (p.one_liner) {
|
|
@@ -2170,10 +2176,34 @@ function registerConstellationOps(
|
|
|
2170
2176
|
lines.push("");
|
|
2171
2177
|
lines.push(p.core_identity || `${p.agent_name} is an AI agent specializing in ${p.role || "general tasks"}.`);
|
|
2172
2178
|
lines.push("");
|
|
2179
|
+
if (p.personality) {
|
|
2180
|
+
lines.push("## Personality");
|
|
2181
|
+
lines.push("");
|
|
2182
|
+
lines.push(p.personality);
|
|
2183
|
+
lines.push("");
|
|
2184
|
+
}
|
|
2173
2185
|
lines.push("## Operating Style");
|
|
2174
2186
|
lines.push("");
|
|
2175
2187
|
lines.push(p.operating_style || "Focused, professional, detail-oriented.");
|
|
2176
2188
|
lines.push("");
|
|
2189
|
+
if (p.tone) {
|
|
2190
|
+
lines.push("## Tone");
|
|
2191
|
+
lines.push("");
|
|
2192
|
+
lines.push(p.tone);
|
|
2193
|
+
lines.push("");
|
|
2194
|
+
}
|
|
2195
|
+
if (p.worldview) {
|
|
2196
|
+
lines.push("## Worldview");
|
|
2197
|
+
lines.push("");
|
|
2198
|
+
lines.push(p.worldview);
|
|
2199
|
+
lines.push("");
|
|
2200
|
+
}
|
|
2201
|
+
if (p.pacing) {
|
|
2202
|
+
lines.push("## Pacing");
|
|
2203
|
+
lines.push("");
|
|
2204
|
+
lines.push(p.pacing);
|
|
2205
|
+
lines.push("");
|
|
2206
|
+
}
|
|
2177
2207
|
lines.push("## Relationship to Team");
|
|
2178
2208
|
lines.push("");
|
|
2179
2209
|
lines.push(p.team_relationship || "Collaborative team member within the agent constellation.");
|
|
@@ -2440,6 +2470,7 @@ function registerConstellationOps(
|
|
|
2440
2470
|
role: a.role,
|
|
2441
2471
|
file_count: a.files.length,
|
|
2442
2472
|
files: a.files,
|
|
2473
|
+
system_files: a.system_files,
|
|
2443
2474
|
has_skills: a.hasSkills,
|
|
2444
2475
|
})),
|
|
2445
2476
|
count: agents.length,
|
|
@@ -2452,8 +2483,10 @@ function registerConstellationOps(
|
|
|
2452
2483
|
const name = (params.agent_name as string).toLowerCase();
|
|
2453
2484
|
const wsPath = getWorkspacePath(name);
|
|
2454
2485
|
if (!fs.existsSync(wsPath)) return err(`Agent workspace not found: workspace-${name}`);
|
|
2455
|
-
const
|
|
2456
|
-
const
|
|
2486
|
+
const allMd = fs.readdirSync(wsPath).filter((f: string) => f.endsWith(".md"));
|
|
2487
|
+
const userMd = allMd.filter((f: string) => !SYSTEM_MD_FILES.has(f));
|
|
2488
|
+
const systemMd = allMd.filter((f: string) => SYSTEM_MD_FILES.has(f));
|
|
2489
|
+
const fileDetails = userMd.map((f: string) => {
|
|
2457
2490
|
const stat = fs.statSync(path.join(wsPath, f));
|
|
2458
2491
|
return { name: f, size_bytes: stat.size, modified: stat.mtime.toISOString() };
|
|
2459
2492
|
});
|
|
@@ -2471,7 +2504,7 @@ function registerConstellationOps(
|
|
|
2471
2504
|
if (emojiMatch) identity.emoji = emojiMatch[1].trim();
|
|
2472
2505
|
} catch {}
|
|
2473
2506
|
const hasSkills = fs.existsSync(path.join(wsPath, "skills"));
|
|
2474
|
-
return ok({ agent_name: name, identity, files: fileDetails, has_skills: hasSkills, workspace_path: wsPath });
|
|
2507
|
+
return ok({ agent_name: name, identity, files: fileDetails, system_files: systemMd, has_skills: hasSkills, workspace_path: wsPath });
|
|
2475
2508
|
}
|
|
2476
2509
|
|
|
2477
2510
|
// ── Read a file ──
|
|
@@ -2540,7 +2573,46 @@ function registerConstellationOps(
|
|
|
2540
2573
|
|
|
2541
2574
|
// Create doctrine file (codename.md) — empty scaffold
|
|
2542
2575
|
const doctrineName = `${(params.codename as string).toUpperCase()}.md`;
|
|
2543
|
-
const doctrineMd =
|
|
2576
|
+
const doctrineMd = [
|
|
2577
|
+
`# ${params.codename} Doctrine`,
|
|
2578
|
+
"",
|
|
2579
|
+
"## Mission",
|
|
2580
|
+
"",
|
|
2581
|
+
p.mission || "To be defined.",
|
|
2582
|
+
"",
|
|
2583
|
+
"## Scope of Responsibility",
|
|
2584
|
+
"",
|
|
2585
|
+
p.scope || `All tasks related to ${p.role || "the assigned domain"}.`,
|
|
2586
|
+
"",
|
|
2587
|
+
"## Decision Frameworks",
|
|
2588
|
+
"",
|
|
2589
|
+
"*To be defined by the operator.*",
|
|
2590
|
+
"",
|
|
2591
|
+
"## Non-Goals",
|
|
2592
|
+
"",
|
|
2593
|
+
"*To be defined by the operator.*",
|
|
2594
|
+
"",
|
|
2595
|
+
"## Evaluation Criteria",
|
|
2596
|
+
"",
|
|
2597
|
+
"*To be defined by the operator.*",
|
|
2598
|
+
"",
|
|
2599
|
+
"## Metrics",
|
|
2600
|
+
"",
|
|
2601
|
+
"*To be defined by the operator.*",
|
|
2602
|
+
"",
|
|
2603
|
+
"## Standard Deliverables",
|
|
2604
|
+
"",
|
|
2605
|
+
"*To be defined by the operator.*",
|
|
2606
|
+
"",
|
|
2607
|
+
"## Anti-Patterns",
|
|
2608
|
+
"",
|
|
2609
|
+
"*To be defined by the operator.*",
|
|
2610
|
+
"",
|
|
2611
|
+
"## Handoff Rules",
|
|
2612
|
+
"",
|
|
2613
|
+
"*To be defined by the operator.*",
|
|
2614
|
+
"",
|
|
2615
|
+
].join("\n");
|
|
2544
2616
|
writeAgentFile(agentName, doctrineName, doctrineMd);
|
|
2545
2617
|
filesWritten.push(doctrineName);
|
|
2546
2618
|
|
|
@@ -2618,12 +2690,13 @@ function registerConstellationOps(
|
|
|
2618
2690
|
const agentsContent = readAgentFile(agent.name, "AGENTS.md");
|
|
2619
2691
|
const owns: string[] = [];
|
|
2620
2692
|
if (agentsContent) {
|
|
2621
|
-
// Extract
|
|
2622
|
-
|
|
2693
|
+
// Extract Owns section — flexible heading match (##, ###, or ####)
|
|
2694
|
+
// Also try matching under a Boundaries parent section
|
|
2695
|
+
const ownsMatch = agentsContent.match(/#{2,4}\s+Owns\s*\n+([\s\S]*?)(?=\n#{2,4}\s|$)/i);
|
|
2623
2696
|
if (ownsMatch) {
|
|
2624
2697
|
const items = ownsMatch[1].split("\n")
|
|
2625
2698
|
.map((l: string) => l.replace(/^[\s-*]+/, "").trim())
|
|
2626
|
-
.filter((l: string) => l.length > 0);
|
|
2699
|
+
.filter((l: string) => l.length > 0 && !l.startsWith("#"));
|
|
2627
2700
|
owns.push(...items);
|
|
2628
2701
|
}
|
|
2629
2702
|
}
|
|
@@ -2640,17 +2713,18 @@ function registerConstellationOps(
|
|
|
2640
2713
|
|
|
2641
2714
|
// Safety gate: confirm must be explicitly true
|
|
2642
2715
|
if (params.confirm !== true) {
|
|
2643
|
-
// List
|
|
2644
|
-
let
|
|
2716
|
+
// List only user-visible files (exclude system md + internal dirs)
|
|
2717
|
+
let userFiles: string[] = [];
|
|
2645
2718
|
try {
|
|
2646
2719
|
if (fs.existsSync(wsPath)) {
|
|
2647
|
-
|
|
2720
|
+
userFiles = fs.readdirSync(wsPath)
|
|
2721
|
+
.filter((f: string) => (f.endsWith(".md") && !SYSTEM_MD_FILES.has(f)) || f === "skills");
|
|
2648
2722
|
}
|
|
2649
2723
|
} catch {}
|
|
2650
2724
|
return err(
|
|
2651
|
-
`⚠️ DESTRUCTIVE ACTION: This will permanently delete agent "${agentName}" and ALL files in workspace-${agentName}/ (${
|
|
2725
|
+
`⚠️ DESTRUCTIVE ACTION: This will permanently delete agent "${agentName}" and ALL files in workspace-${agentName}/ (${userFiles.length} user files). ` +
|
|
2652
2726
|
`This CANNOT be undone.\n\n` +
|
|
2653
|
-
`Files that will be deleted:\n${
|
|
2727
|
+
`Files that will be deleted:\n${userFiles.map((f: string) => ` - ${f}`).join("\n") || " (directory not found)"}\n\n` +
|
|
2654
2728
|
`To proceed, ask the user for explicit confirmation and then call this action again with confirm: true.`
|
|
2655
2729
|
);
|
|
2656
2730
|
}
|
|
@@ -2660,10 +2734,11 @@ function registerConstellationOps(
|
|
|
2660
2734
|
return err(`Agent workspace-${agentName} does not exist at ${wsPath}`);
|
|
2661
2735
|
}
|
|
2662
2736
|
|
|
2663
|
-
// Count files before deletion for the report
|
|
2664
|
-
let
|
|
2737
|
+
// Count user-visible files before deletion for the report
|
|
2738
|
+
let deletedUserFiles: string[] = [];
|
|
2665
2739
|
try {
|
|
2666
|
-
|
|
2740
|
+
deletedUserFiles = fs.readdirSync(wsPath)
|
|
2741
|
+
.filter((f: string) => (f.endsWith(".md") && !SYSTEM_MD_FILES.has(f)) || f === "skills");
|
|
2667
2742
|
} catch {}
|
|
2668
2743
|
|
|
2669
2744
|
// Remove the entire workspace directory
|
|
@@ -2690,13 +2765,13 @@ function registerConstellationOps(
|
|
|
2690
2765
|
unregResult = { success: false, message: `Unregistration may have failed: ${unregCombined.slice(0, 200)}` };
|
|
2691
2766
|
}
|
|
2692
2767
|
|
|
2693
|
-
api.logger?.info?.(`[ofiere] Deleted agent "${agentName}" — ${
|
|
2768
|
+
api.logger?.info?.(`[ofiere] Deleted agent "${agentName}" — ${deletedUserFiles.length} files removed`);
|
|
2694
2769
|
|
|
2695
2770
|
return ok({
|
|
2696
2771
|
message: `Agent "${agentName}" has been permanently deleted`,
|
|
2697
2772
|
agent_name: agentName,
|
|
2698
2773
|
workspace_deleted: wsPath,
|
|
2699
|
-
files_removed:
|
|
2774
|
+
files_removed: deletedUserFiles.length,
|
|
2700
2775
|
unregistration: unregResult,
|
|
2701
2776
|
});
|
|
2702
2777
|
}
|