@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.
Files changed (2) hide show
  1. package/index.ts +43 -15
  2. 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(api: OpenClawPluginApi, recipe: RecipeFrontmatter, opts: {
266
- agentId: string;
267
- agentName?: string;
268
- update?: boolean;
269
- vars?: Record<string, string>;
270
- }) {
271
- const cfg = getCfg(api);
272
-
273
- const agentDir = workspacePath(api, cfg.workspaceAgentsDir, opts.agentId);
274
- await ensureDir(agentDir);
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(agentDir, f.path);
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: agentDir,
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
- agentDir,
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
- const teamDir = workspacePath(api, cfg.workspaceTeamsDir, teamId);
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 teamDir = workspacePath(api, cfg.workspaceTeamsDir, teamId);
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 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawcipes/recipes",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Clawcipes recipes plugin for OpenClaw (markdown recipes -> scaffold agents/teams)",
5
5
  "main": "index.ts",
6
6
  "type": "commonjs",