@mistralys/persona-builder 2.4.0 → 2.5.0

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 CHANGED
@@ -73,6 +73,7 @@ See the [CLI docs](docs/cli.md) for config file format and all flags.
73
73
  | [Getting Started](docs/getting-started.md) | Step-by-step tutorial — build your first persona from scratch |
74
74
  | [Directory Convention](docs/directory-convention.md) | Expected source layout (`meta/`, `content/`, `partials/`) |
75
75
  | [Template Syntax](docs/template-syntax.md) | Variables, partials, conditionals, and built-in context variables |
76
+ | [Target Differences](docs/target-differences.md) | VS Code vs Claude Code — tool notation, frontmatter, filename conventions, and common mistakes |
76
77
  | [Custom Variables & Dynamic Partials](docs/dynamic-partials.md) | Inject build-time variables and partial content at global, suite, or per-persona level |
77
78
  | [Plugins](docs/plugins.md) | `PersonaBuildPlugin` interface and examples |
78
79
 
package/dist/cli.cjs CHANGED
@@ -103,6 +103,10 @@ function serializeTools(tools) {
103
103
  function serializeToolsList(tools) {
104
104
  return tools.map((t) => `'${t}'`).join(", ");
105
105
  }
106
+ function serializeToolsBlock(tools) {
107
+ if (tools.length === 0) return " []";
108
+ return "\n" + tools.map((t) => ` - ${t}`).join("\n");
109
+ }
106
110
  async function loadPartials(dir) {
107
111
  const entries = await promises.readdir(dir, { withFileTypes: true });
108
112
  const mdFiles = entries.filter(
@@ -185,10 +189,10 @@ tools: [{{tools_list}}]
185
189
  ---`;
186
190
  var DEFAULT_FRONTMATTER_CLAUDE_CODE = `---
187
191
  name: {{cc_file_name_stem}}
188
- permissionMode: {{cc_permission_mode}}
192
+ description: {{description}}
189
193
  model: {{cc_model}}
190
194
  memory: {{cc_memory}}
191
- allowedTools: [{{cc_tools_list}}]
195
+ tools:{{cc_tools_block}}
192
196
  ---`;
193
197
  var DEFAULT_FRONTMATTER_DEEP_AGENTS = `---
194
198
  name: {{name}}
@@ -417,6 +421,12 @@ function buildContext(options) {
417
421
  if (!("cc_tools_json" in merged)) {
418
422
  merged["cc_tools_json"] = serializeTools(ccTools);
419
423
  }
424
+ if (!("tools_block" in merged)) {
425
+ merged["tools_block"] = serializeToolsBlock(tools);
426
+ }
427
+ if (!("cc_tools_block" in merged)) {
428
+ merged["cc_tools_block"] = serializeToolsBlock(ccTools);
429
+ }
420
430
  if (!("cc_file_name_stem" in merged) && typeof merged["cc_file_name"] === "string") {
421
431
  const ccFileName = merged["cc_file_name"];
422
432
  merged["cc_file_name_stem"] = ccFileName.replace(/\.md$/, "");
@@ -433,6 +443,9 @@ function buildContext(options) {
433
443
  if (!("da_tools_json" in merged)) {
434
444
  merged["da_tools_json"] = serializeTools(daTools);
435
445
  }
446
+ if (!("da_tools_block" in merged)) {
447
+ merged["da_tools_block"] = serializeToolsBlock(daTools);
448
+ }
436
449
  }
437
450
  for (const [key, value] of Object.entries(agentMap)) {
438
451
  if (!(key in merged)) {
@@ -451,6 +464,21 @@ function buildContext(options) {
451
464
  }
452
465
  return merged;
453
466
  }
467
+ function validateSubagentRefs(persona, agentMap) {
468
+ const subagents = persona.subagents;
469
+ if (!Array.isArray(subagents) || subagents.length === 0) return [];
470
+ const results = [];
471
+ for (const slug of subagents) {
472
+ const key = `agent_slug_${slug.replace(/-/g, "_")}`;
473
+ if (!(key in agentMap)) {
474
+ results.push({
475
+ severity: "error",
476
+ message: `Persona '${persona.name}' declares subagent '${slug}' but no persona with that slug exists in any configured suite.`
477
+ });
478
+ }
479
+ }
480
+ return results;
481
+ }
454
482
  async function buildPersona(personaYamlPath, suiteName, suiteConfig, sharedMeta, partialsMap, config, plugins, target, agentMap = {}, registry = defaultRegistry) {
455
483
  const personaMeta = await loadPersonaYaml(personaYamlPath);
456
484
  let context = buildContext({
@@ -489,7 +517,10 @@ async function buildPersona(personaYamlPath, suiteName, suiteConfig, sharedMeta,
489
517
  ${body}
490
518
  `);
491
519
  output = runPostRender(plugins, output, personaMetaTyped, target);
492
- const validationResults = runValidate(plugins, personaMetaTyped, suiteConfig, target);
520
+ const validationResults = [
521
+ ...runValidate(plugins, personaMetaTyped, suiteConfig, target),
522
+ ...validateSubagentRefs(personaMetaTyped, agentMap)
523
+ ];
493
524
  const def = registry.has(target) ? registry.get(target) : void 0;
494
525
  const outputDir = resolveOutputDir(target, suiteConfig, def);
495
526
  const fnKey = def?.filenameContextKey;