@starlein/paperclip-plugin-company-wizard 0.6.2 → 0.6.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/CHANGELOG.md +21 -0
- package/README.md +8 -4
- package/dist/manifest.js +3 -3
- package/dist/manifest.js.map +1 -1
- package/dist/ui/index.js +16 -1
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.js +46 -22
- package/dist/worker.js.map +2 -2
- package/docs/PAPERCLIP-COMPATIBILITY.md +3 -1
- package/package.json +1 -1
package/dist/worker.js
CHANGED
|
@@ -29352,7 +29352,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
|
29352
29352
|
var manifest = {
|
|
29353
29353
|
id: "starlein.paperclip-plugin-company-wizard",
|
|
29354
29354
|
apiVersion: 1,
|
|
29355
|
-
version: "0.6.
|
|
29355
|
+
version: "0.6.3",
|
|
29356
29356
|
displayName: "Company Wizard",
|
|
29357
29357
|
description: "AI-powered wizard to bootstrap agent companies from composable templates",
|
|
29358
29358
|
author: "Sascha Pietrowski <sp@speednetwork.de>",
|
|
@@ -29388,7 +29388,7 @@ var manifest = {
|
|
|
29388
29388
|
},
|
|
29389
29389
|
templatesPath: {
|
|
29390
29390
|
type: "string",
|
|
29391
|
-
description: "Optional
|
|
29391
|
+
description: "Optional existing template root containing roles/, modules/, and presets/. Overrides the GitHub URL. Leave empty to use bundled release templates or a custom GitHub source. Refresh never populates or overwrites this directory."
|
|
29392
29392
|
},
|
|
29393
29393
|
templatesRepoUrl: {
|
|
29394
29394
|
type: "string",
|
|
@@ -29399,7 +29399,7 @@ var manifest = {
|
|
|
29399
29399
|
type: "string",
|
|
29400
29400
|
enum: ["anthropic", "openai"],
|
|
29401
29401
|
default: "anthropic",
|
|
29402
|
-
description: "AI provider used for company generation. Anthropic uses Claude Opus 5 at max effort; OpenAI uses GPT-
|
|
29402
|
+
description: "AI provider used for company generation. Anthropic uses Claude Opus 5 at max effort; OpenAI uses GPT-6-Astra at high reasoning effort."
|
|
29403
29403
|
},
|
|
29404
29404
|
anthropicApiKey: {
|
|
29405
29405
|
// Paperclip's secret picker submits an EnvSecretRefBinding object,
|
|
@@ -31673,17 +31673,13 @@ function isDockerLayout() {
|
|
|
31673
31673
|
async function ensureTemplatesDir(cfg) {
|
|
31674
31674
|
const repoUrl = cfg.templatesRepoUrl || DEFAULT_TEMPLATES_REPO_URL;
|
|
31675
31675
|
if (cfg.templatesPath) {
|
|
31676
|
-
|
|
31677
|
-
throw new Error(`Configured templatesPath does not exist: ${cfg.templatesPath}`);
|
|
31676
|
+
return validateTemplatesDir(cfg.templatesPath, "Configured templatesPath");
|
|
31678
31677
|
}
|
|
31679
31678
|
if (!cfg.templatesRepoUrl || cfg.templatesRepoUrl === DEFAULT_TEMPLATES_REPO_URL) {
|
|
31680
|
-
|
|
31681
|
-
throw new Error(
|
|
31682
|
-
"Bundled templates are missing. Reinstall Company Wizard or configure templatesPath."
|
|
31683
|
-
);
|
|
31679
|
+
return validateTemplatesDir(BUNDLED_TEMPLATES_DIR, "Bundled templates");
|
|
31684
31680
|
}
|
|
31685
31681
|
const cacheDir = resolveTemplatesCacheDir(cfg);
|
|
31686
|
-
if (fs2.existsSync(cacheDir)) return cacheDir;
|
|
31682
|
+
if (fs2.existsSync(cacheDir)) return validateTemplatesDir(cacheDir, "Cached templates");
|
|
31687
31683
|
return refreshTemplatesCache(cfg);
|
|
31688
31684
|
}
|
|
31689
31685
|
function resolveTemplatesCacheDir(cfg) {
|
|
@@ -31695,14 +31691,12 @@ function resolveTemplatesCacheDir(cfg) {
|
|
|
31695
31691
|
}
|
|
31696
31692
|
function refreshTemplatesCache(cfg, log) {
|
|
31697
31693
|
if (cfg.templatesPath) {
|
|
31698
|
-
|
|
31699
|
-
throw new Error(`Configured templatesPath does not exist: ${cfg.templatesPath}`);
|
|
31694
|
+
validateTemplatesDir(cfg.templatesPath, "Configured templatesPath");
|
|
31700
31695
|
log?.("Using operator-managed templatesPath; no files overwritten.");
|
|
31701
31696
|
return cfg.templatesPath;
|
|
31702
31697
|
}
|
|
31703
31698
|
if (!cfg.templatesRepoUrl || cfg.templatesRepoUrl === DEFAULT_TEMPLATES_REPO_URL) {
|
|
31704
|
-
|
|
31705
|
-
throw new Error("Bundled templates are missing. Reinstall Company Wizard.");
|
|
31699
|
+
validateTemplatesDir(BUNDLED_TEMPLATES_DIR, "Bundled templates");
|
|
31706
31700
|
log?.(`Using bundled Company Wizard ${CURRENT_PLUGIN_VERSION} templates.`);
|
|
31707
31701
|
return BUNDLED_TEMPLATES_DIR;
|
|
31708
31702
|
}
|
|
@@ -31713,6 +31707,9 @@ function refreshTemplatesCache(cfg, log) {
|
|
|
31713
31707
|
const backupDir = `${stagingDir}-previous`;
|
|
31714
31708
|
try {
|
|
31715
31709
|
downloadTemplatesFromGithub(stagingDir, repoUrl);
|
|
31710
|
+
validateTemplatesDir(stagingDir, "Downloaded templates");
|
|
31711
|
+
const { loadErrors } = loadTemplates(stagingDir);
|
|
31712
|
+
if (loadErrors.length > 0) throw new Error(loadErrors.join("\n"));
|
|
31716
31713
|
if (fs2.existsSync(targetDir)) fs2.renameSync(targetDir, backupDir);
|
|
31717
31714
|
try {
|
|
31718
31715
|
fs2.renameSync(stagingDir, targetDir);
|
|
@@ -31728,7 +31725,7 @@ function refreshTemplatesCache(cfg, log) {
|
|
|
31728
31725
|
return targetDir;
|
|
31729
31726
|
}
|
|
31730
31727
|
var ANTHROPIC_AI_MODEL = "claude-opus-5";
|
|
31731
|
-
var OPENAI_AI_MODEL = "gpt-
|
|
31728
|
+
var OPENAI_AI_MODEL = "gpt-6-astra";
|
|
31732
31729
|
function isLikelyAnthropicApiKey(value) {
|
|
31733
31730
|
return value.startsWith("sk-ant-");
|
|
31734
31731
|
}
|
|
@@ -31878,7 +31875,11 @@ function loadJsonFiles(dir, filename) {
|
|
|
31878
31875
|
const fp = path2.join(fullDir, filename);
|
|
31879
31876
|
if (!fs2.existsSync(fp)) continue;
|
|
31880
31877
|
try {
|
|
31881
|
-
|
|
31878
|
+
const item = JSON.parse(fs2.readFileSync(fp, "utf-8"));
|
|
31879
|
+
if (!item || typeof item !== "object" || Array.isArray(item) || typeof item.name !== "string" || !item.name.trim()) {
|
|
31880
|
+
throw new Error("Template metadata must be an object with a non-empty name");
|
|
31881
|
+
}
|
|
31882
|
+
items.push(item);
|
|
31882
31883
|
} catch (err) {
|
|
31883
31884
|
errors.push(`Failed to parse ${fp}: ${err instanceof Error ? err.message : String(err)}`);
|
|
31884
31885
|
}
|
|
@@ -31909,6 +31910,23 @@ function loadTemplates(templatesDir) {
|
|
|
31909
31910
|
loadErrors: [...presetLoad.errors, ...moduleLoad.errors, ...roleLoad.errors]
|
|
31910
31911
|
};
|
|
31911
31912
|
}
|
|
31913
|
+
function validateTemplatesDir(dir, source) {
|
|
31914
|
+
try {
|
|
31915
|
+
if (!fs2.existsSync(dir)) throw new Error("directory does not exist");
|
|
31916
|
+
if (!fs2.statSync(dir).isDirectory()) throw new Error("path is not a directory");
|
|
31917
|
+
const templates = loadTemplates(dir);
|
|
31918
|
+
if (!templates.roles.some((role) => role.name === "ceo" && role._base)) {
|
|
31919
|
+
throw new Error(
|
|
31920
|
+
'No base CEO template found. Expected roles/ceo/role.meta.json with name "ceo" and base: true.' + (templates.loadErrors.length ? ` ${templates.loadErrors.join(" ")}` : "")
|
|
31921
|
+
);
|
|
31922
|
+
}
|
|
31923
|
+
return dir;
|
|
31924
|
+
} catch (err) {
|
|
31925
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
31926
|
+
const guidance = source === "Configured templatesPath" ? "Point templatesPath to the template root (containing roles/, modules/, presets/), or clear templatesPath to use bundled templates / the configured GitHub source. templatesPath overrides templatesRepoUrl; refresh never populates or overwrites local files." : "Reinstall Company Wizard for bundled templates, or refresh the configured custom GitHub source.";
|
|
31927
|
+
throw new Error(`${source} "${dir}": ${detail} ${guidance}`);
|
|
31928
|
+
}
|
|
31929
|
+
}
|
|
31912
31930
|
function resolvePaperclipCredentials(cfg) {
|
|
31913
31931
|
return {
|
|
31914
31932
|
url: cfg.paperclipUrl || process.env.PAPERCLIP_PUBLIC_URL || "http://localhost:3100",
|
|
@@ -32369,14 +32387,18 @@ ${moduleNames.length > 0 ? moduleNames.map((mod) => `- ${mod}`).join("\n") : "-
|
|
|
32369
32387
|
var plugin = definePlugin({
|
|
32370
32388
|
async setup(ctx) {
|
|
32371
32389
|
ctx.data.register("templates", async () => {
|
|
32372
|
-
|
|
32373
|
-
|
|
32374
|
-
|
|
32375
|
-
for (const
|
|
32376
|
-
ctx.logger.info(`\u26A0 Template load warning: ${
|
|
32390
|
+
try {
|
|
32391
|
+
const cfg = await ctx.config.get() ?? {};
|
|
32392
|
+
const templates = loadTemplates(await ensureTemplatesDir(cfg));
|
|
32393
|
+
for (const warning of templates.loadErrors) {
|
|
32394
|
+
ctx.logger.info(`\u26A0 Template load warning: ${warning}`);
|
|
32377
32395
|
}
|
|
32396
|
+
return templates;
|
|
32397
|
+
} catch (err) {
|
|
32398
|
+
const error61 = err instanceof Error ? err.message : String(err);
|
|
32399
|
+
ctx.logger.info(`Template load failed: ${error61}`);
|
|
32400
|
+
return { presets: [], modules: [], roles: [], loadErrors: [error61], error: error61 };
|
|
32378
32401
|
}
|
|
32379
|
-
return templates;
|
|
32380
32402
|
});
|
|
32381
32403
|
ctx.actions.register("refresh-templates", async () => {
|
|
32382
32404
|
try {
|
|
@@ -33551,6 +33573,8 @@ var plugin = definePlugin({
|
|
|
33551
33573
|
async onValidateConfig(config2) {
|
|
33552
33574
|
const paperclipUrl = config2.paperclipUrl || process.env.PAPERCLIP_PUBLIC_URL || "http://localhost:3100";
|
|
33553
33575
|
try {
|
|
33576
|
+
const templates = loadTemplates(await ensureTemplatesDir(config2));
|
|
33577
|
+
if (templates.loadErrors.length > 0) return { ok: false, errors: templates.loadErrors };
|
|
33554
33578
|
const client = new PaperclipClient(paperclipUrl, {
|
|
33555
33579
|
email: config2.paperclipEmail || "",
|
|
33556
33580
|
password: config2.paperclipPassword || ""
|