@clawcipes/recipes 0.1.2 → 0.1.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.
- package/index.ts +43 -15
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -262,16 +262,23 @@ async function applyAgentSnippetsToOpenClawConfig(api: OpenClawPluginApi, snippe
|
|
|
262
262
|
return { updatedAgents: snippets.map((s) => s.id) };
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
async function scaffoldAgentFromRecipe(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
265
|
+
async function scaffoldAgentFromRecipe(
|
|
266
|
+
api: OpenClawPluginApi,
|
|
267
|
+
recipe: RecipeFrontmatter,
|
|
268
|
+
opts: {
|
|
269
|
+
agentId: string;
|
|
270
|
+
agentName?: string;
|
|
271
|
+
update?: boolean;
|
|
272
|
+
vars?: Record<string, string>;
|
|
273
|
+
|
|
274
|
+
// Where to write the scaffolded files (may be a shared team workspace role folder)
|
|
275
|
+
filesRootDir: string;
|
|
276
|
+
|
|
277
|
+
// What to set in agents.list[].workspace (may be shared team workspace root)
|
|
278
|
+
workspaceRootDir: string;
|
|
279
|
+
},
|
|
280
|
+
) {
|
|
281
|
+
await ensureDir(opts.filesRootDir);
|
|
275
282
|
|
|
276
283
|
const templates = recipe.templates ?? {};
|
|
277
284
|
const files = recipe.files ?? [];
|
|
@@ -282,7 +289,7 @@ async function scaffoldAgentFromRecipe(api: OpenClawPluginApi, recipe: RecipeFro
|
|
|
282
289
|
const raw = templates[f.template];
|
|
283
290
|
if (typeof raw !== "string") throw new Error(`Missing template: ${f.template}`);
|
|
284
291
|
const rendered = renderTemplate(raw, vars);
|
|
285
|
-
const target = path.join(
|
|
292
|
+
const target = path.join(opts.filesRootDir, f.path);
|
|
286
293
|
const mode = opts.update ? (f.mode ?? "overwrite") : (f.mode ?? "createOnly");
|
|
287
294
|
const r = await writeFileSafely(target, rendered, mode);
|
|
288
295
|
fileResults.push({ path: target, wrote: r.wrote, reason: r.reason });
|
|
@@ -290,13 +297,14 @@ async function scaffoldAgentFromRecipe(api: OpenClawPluginApi, recipe: RecipeFro
|
|
|
290
297
|
|
|
291
298
|
const configSnippet: AgentConfigSnippet = {
|
|
292
299
|
id: opts.agentId,
|
|
293
|
-
workspace:
|
|
300
|
+
workspace: opts.workspaceRootDir,
|
|
294
301
|
identity: { name: opts.agentName ?? recipe.name ?? opts.agentId },
|
|
295
302
|
tools: recipe.tools ?? {},
|
|
296
303
|
};
|
|
297
304
|
|
|
298
305
|
return {
|
|
299
|
-
|
|
306
|
+
filesRootDir: opts.filesRootDir,
|
|
307
|
+
workspaceRootDir: opts.workspaceRootDir,
|
|
300
308
|
fileResults,
|
|
301
309
|
next: {
|
|
302
310
|
configSnippet,
|
|
@@ -509,7 +517,8 @@ const recipesPlugin = {
|
|
|
509
517
|
if (!workspaceRoot) throw new Error("agents.defaults.workspace is not set in config");
|
|
510
518
|
|
|
511
519
|
const teamId = String(options.teamId);
|
|
512
|
-
|
|
520
|
+
// Team workspace root (shared by all role agents): ~/.openclaw/workspace-<teamId>
|
|
521
|
+
const teamDir = path.resolve(workspaceRoot, "..", `workspace-${teamId}`);
|
|
513
522
|
|
|
514
523
|
const inboxDir = path.join(teamDir, "inbox");
|
|
515
524
|
const backlogDir = path.join(teamDir, "work", "backlog");
|
|
@@ -658,10 +667,16 @@ const recipesPlugin = {
|
|
|
658
667
|
return;
|
|
659
668
|
}
|
|
660
669
|
|
|
670
|
+
const baseWorkspace = api.config.agents?.defaults?.workspace ?? "~/.openclaw/workspace";
|
|
671
|
+
// Put standalone agent workspaces alongside the default workspace (same parent dir).
|
|
672
|
+
const resolvedWorkspaceRoot = path.resolve(baseWorkspace, "..", `workspace-${options.agentId}`);
|
|
673
|
+
|
|
661
674
|
const result = await scaffoldAgentFromRecipe(api, recipe, {
|
|
662
675
|
agentId: options.agentId,
|
|
663
676
|
agentName: options.name,
|
|
664
677
|
update: !!options.overwrite,
|
|
678
|
+
filesRootDir: resolvedWorkspaceRoot,
|
|
679
|
+
workspaceRootDir: resolvedWorkspaceRoot,
|
|
665
680
|
vars: {
|
|
666
681
|
agentId: options.agentId,
|
|
667
682
|
agentName: options.name ?? recipe.name ?? options.agentId,
|
|
@@ -702,8 +717,15 @@ const recipesPlugin = {
|
|
|
702
717
|
return;
|
|
703
718
|
}
|
|
704
719
|
|
|
705
|
-
const
|
|
720
|
+
const baseWorkspace = api.config.agents?.defaults?.workspace;
|
|
721
|
+
if (!baseWorkspace) throw new Error("agents.defaults.workspace is not set in config");
|
|
722
|
+
|
|
723
|
+
// Team workspace root (shared by all role agents): ~/.openclaw/workspace-<teamId>
|
|
724
|
+
const teamDir = path.resolve(baseWorkspace, "..", `workspace-${teamId}`);
|
|
706
725
|
await ensureDir(teamDir);
|
|
726
|
+
|
|
727
|
+
const rolesDir = path.join(teamDir, "roles");
|
|
728
|
+
await ensureDir(rolesDir);
|
|
707
729
|
const notesDir = path.join(teamDir, "notes");
|
|
708
730
|
const workDir = path.join(teamDir, "work");
|
|
709
731
|
const backlogDir = path.join(workDir, "backlog");
|
|
@@ -761,16 +783,22 @@ const recipesPlugin = {
|
|
|
761
783
|
tools: a.tools ?? recipe.tools,
|
|
762
784
|
};
|
|
763
785
|
|
|
786
|
+
const roleDir = path.join(rolesDir, role);
|
|
764
787
|
const r = await scaffoldAgentFromRecipe(api, scopedRecipe, {
|
|
765
788
|
agentId,
|
|
766
789
|
agentName,
|
|
767
790
|
update: !!options.overwrite,
|
|
791
|
+
// Write role-specific files under roles/<role>/
|
|
792
|
+
filesRootDir: roleDir,
|
|
793
|
+
// But set the agent workspace root to the shared team workspace
|
|
794
|
+
workspaceRootDir: teamDir,
|
|
768
795
|
vars: {
|
|
769
796
|
teamId,
|
|
770
797
|
teamDir,
|
|
771
798
|
role,
|
|
772
799
|
agentId,
|
|
773
800
|
agentName,
|
|
801
|
+
roleDir,
|
|
774
802
|
},
|
|
775
803
|
});
|
|
776
804
|
results.push({ role, agentId, ...r });
|