@starlein/paperclip-plugin-company-wizard 0.4.5 → 0.4.6
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 +29 -0
- package/README.md +1 -1
- package/dist/manifest.js +4 -9
- package/dist/manifest.js.map +2 -2
- package/dist/ui/index.js +1 -2
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.js +239 -39
- package/dist/worker.js.map +2 -2
- package/package.json +1 -1
- package/templates/modules/auto-assign/README.md +9 -7
- package/templates/modules/auto-assign/agents/ceo/heartbeat-section.md +3 -1
- package/templates/modules/auto-assign/agents/ceo/skills/auto-assign.fallback.md +14 -8
- package/templates/modules/auto-assign/agents/product-owner/heartbeat-section.md +3 -1
- package/templates/modules/auto-assign/module.meta.json +3 -3
- package/templates/modules/auto-assign/skills/auto-assign.md +2 -2
- package/templates/modules/backlog/docs/backlog-process.md +7 -7
- package/templates/modules/backlog/docs/backlog-template.md +2 -1
- package/templates/modules/backlog/module.meta.json +2 -2
- package/templates/modules/backlog/skills/backlog-health.bar.md +1 -1
- package/templates/modules/backlog/skills/backlog-health.md +2 -2
- package/templates/modules/github-repo/README.md +3 -3
- package/templates/modules/github-repo/agents/engineer/skills/git-workflow.md +24 -8
- package/templates/modules/github-repo/docs/git-workflow.md +59 -2
- package/templates/modules/github-repo/module.meta.json +1 -1
- package/templates/roles/engineer/AGENTS.md +2 -0
- package/templates/roles/engineer/HEARTBEAT.md +1 -1
- package/templates/roles/product-owner/AGENTS.md +2 -1
- package/templates/roles/product-owner/HEARTBEAT.md +1 -1
package/dist/worker.js
CHANGED
|
@@ -9415,6 +9415,8 @@ async function assembleCompany({
|
|
|
9415
9415
|
presetLabels = [],
|
|
9416
9416
|
enableIsolatedWorktrees = false,
|
|
9417
9417
|
enableEnrichedPersonas = true,
|
|
9418
|
+
gitUserName,
|
|
9419
|
+
gitUserEmail,
|
|
9418
9420
|
outputDir,
|
|
9419
9421
|
templatesDir,
|
|
9420
9422
|
onProgress = () => {
|
|
@@ -10080,7 +10082,9 @@ Read: \`docs/${doc}\`
|
|
|
10080
10082
|
if (!workspace.cwd) workspace.cwd = localCwd;
|
|
10081
10083
|
const trimmedSetup = typeof workspace.setupCommand === "string" ? workspace.setupCommand.trim() : "";
|
|
10082
10084
|
if (!trimmedSetup || trimmedSetup === "git init -b main" || trimmedSetup === "git init") {
|
|
10083
|
-
|
|
10085
|
+
const gitName = gitUserName || "Paperclip Bootstrap";
|
|
10086
|
+
const gitEmail = gitUserEmail || "bootstrap@paperclip.local";
|
|
10087
|
+
workspace.setupCommand = `git init -b main && git -c user.email=${gitEmail} -c user.name='${gitName.replace(/'/g, "'\\''")}' commit --allow-empty -m 'chore: initialize repository'`;
|
|
10084
10088
|
}
|
|
10085
10089
|
}
|
|
10086
10090
|
return workspace;
|
|
@@ -10449,6 +10453,8 @@ var PaperclipClient = class {
|
|
|
10449
10453
|
this.credentials = credentials;
|
|
10450
10454
|
this.sessionCookie = null;
|
|
10451
10455
|
this.boardUserId = null;
|
|
10456
|
+
this.boardUserName = null;
|
|
10457
|
+
this.boardUserEmail = null;
|
|
10452
10458
|
}
|
|
10453
10459
|
async _fetch(path3, opts = {}) {
|
|
10454
10460
|
const url = `${this.baseUrl}${path3}`;
|
|
@@ -10490,6 +10496,8 @@ var PaperclipClient = class {
|
|
|
10490
10496
|
}
|
|
10491
10497
|
if (res.ok) {
|
|
10492
10498
|
this.boardUserId = "local-board";
|
|
10499
|
+
this.boardUserName = null;
|
|
10500
|
+
this.boardUserEmail = null;
|
|
10493
10501
|
return;
|
|
10494
10502
|
}
|
|
10495
10503
|
if (res.status === 401 || res.status === 403) {
|
|
@@ -10504,6 +10512,8 @@ var PaperclipClient = class {
|
|
|
10504
10512
|
try {
|
|
10505
10513
|
const session = await this._fetch("/api/auth/get-session");
|
|
10506
10514
|
this.boardUserId = session?.user?.id || null;
|
|
10515
|
+
this.boardUserName = session?.user?.name || null;
|
|
10516
|
+
this.boardUserEmail = session?.user?.email || null;
|
|
10507
10517
|
} catch {
|
|
10508
10518
|
}
|
|
10509
10519
|
return;
|
|
@@ -10772,6 +10782,23 @@ var PaperclipClient = class {
|
|
|
10772
10782
|
})
|
|
10773
10783
|
});
|
|
10774
10784
|
}
|
|
10785
|
+
async listRoutines(companyId, filters = {}) {
|
|
10786
|
+
const params = new URLSearchParams();
|
|
10787
|
+
if (filters.projectId) params.set("projectId", filters.projectId);
|
|
10788
|
+
const query = params.toString();
|
|
10789
|
+
return this._fetch(`/api/companies/${companyId}/routines${query ? `?${query}` : ""}`, {
|
|
10790
|
+
method: "GET"
|
|
10791
|
+
});
|
|
10792
|
+
}
|
|
10793
|
+
async getRoutine(routineId) {
|
|
10794
|
+
return this._fetch(`/api/routines/${routineId}`, { method: "GET" });
|
|
10795
|
+
}
|
|
10796
|
+
async updateRoutine(routineId, updates = {}) {
|
|
10797
|
+
return this._fetch(`/api/routines/${routineId}`, {
|
|
10798
|
+
method: "PATCH",
|
|
10799
|
+
body: JSON.stringify(updates || {})
|
|
10800
|
+
});
|
|
10801
|
+
}
|
|
10775
10802
|
async createRoutineTrigger(routineId, { kind, cronExpression, timezone }) {
|
|
10776
10803
|
return this._fetch(`/api/routines/${routineId}/triggers`, {
|
|
10777
10804
|
method: "POST",
|
|
@@ -10782,6 +10809,12 @@ var PaperclipClient = class {
|
|
|
10782
10809
|
})
|
|
10783
10810
|
});
|
|
10784
10811
|
}
|
|
10812
|
+
async updateRoutineTrigger(triggerId, updates = {}) {
|
|
10813
|
+
return this._fetch(`/api/routine-triggers/${triggerId}`, {
|
|
10814
|
+
method: "PATCH",
|
|
10815
|
+
body: JSON.stringify(updates || {})
|
|
10816
|
+
});
|
|
10817
|
+
}
|
|
10785
10818
|
async triggerHeartbeat(agentId, { issueId } = {}) {
|
|
10786
10819
|
return this._fetch(`/api/agents/${agentId}/wakeup`, {
|
|
10787
10820
|
method: "POST",
|
|
@@ -10969,7 +11002,7 @@ var __dirname = path2.dirname(fileURLToPath2(import.meta.url));
|
|
|
10969
11002
|
var DEFAULT_TEMPLATES_REPO_URL = "https://github.com/starlein/paperclip-plugin-company-wizard/tree/main/templates";
|
|
10970
11003
|
var BUNDLED_TEMPLATES_DIR = path2.resolve(__dirname, "..", "templates");
|
|
10971
11004
|
var PLUGIN_PACKAGE_NAME = "@starlein/paperclip-plugin-company-wizard";
|
|
10972
|
-
var CURRENT_PLUGIN_VERSION = "0.4.
|
|
11005
|
+
var CURRENT_PLUGIN_VERSION = "0.4.6";
|
|
10973
11006
|
var NPM_LATEST_URL = "https://registry.npmjs.org/@starlein%2Fpaperclip-plugin-company-wizard/latest";
|
|
10974
11007
|
function copyDirSync(src, dest) {
|
|
10975
11008
|
fs2.mkdirSync(dest, { recursive: true });
|
|
@@ -11017,6 +11050,9 @@ function downloadTemplatesFromGithub(destDir, githubUrl) {
|
|
|
11017
11050
|
}
|
|
11018
11051
|
}
|
|
11019
11052
|
}
|
|
11053
|
+
function isDockerLayout() {
|
|
11054
|
+
return fs2.existsSync(path2.join(os.homedir(), "instances"));
|
|
11055
|
+
}
|
|
11020
11056
|
async function ensureTemplatesDir(cfg) {
|
|
11021
11057
|
const repoUrl = cfg.templatesRepoUrl || DEFAULT_TEMPLATES_REPO_URL;
|
|
11022
11058
|
if (cfg.templatesPath) {
|
|
@@ -11024,6 +11060,15 @@ async function ensureTemplatesDir(cfg) {
|
|
|
11024
11060
|
downloadTemplatesFromGithub(cfg.templatesPath, repoUrl);
|
|
11025
11061
|
return cfg.templatesPath;
|
|
11026
11062
|
}
|
|
11063
|
+
if (isDockerLayout()) {
|
|
11064
|
+
const dockerTemplatesDir = path2.join(os.homedir(), "plugin-templates");
|
|
11065
|
+
if (fs2.existsSync(dockerTemplatesDir)) return dockerTemplatesDir;
|
|
11066
|
+
try {
|
|
11067
|
+
downloadTemplatesFromGithub(dockerTemplatesDir, repoUrl);
|
|
11068
|
+
return dockerTemplatesDir;
|
|
11069
|
+
} catch {
|
|
11070
|
+
}
|
|
11071
|
+
}
|
|
11027
11072
|
const defaultDir = path2.join(os.homedir(), ".paperclip", "plugin-templates");
|
|
11028
11073
|
if (fs2.existsSync(defaultDir)) return defaultDir;
|
|
11029
11074
|
try {
|
|
@@ -11136,10 +11181,6 @@ function loadTemplates(templatesDir) {
|
|
|
11136
11181
|
loadErrors: [...presetLoad.errors, ...moduleLoad.errors, ...roleLoad.errors]
|
|
11137
11182
|
};
|
|
11138
11183
|
}
|
|
11139
|
-
function cfgBool(cfg, key) {
|
|
11140
|
-
const raw = cfg[key];
|
|
11141
|
-
return raw === true || typeof raw === "string" && raw.toLowerCase() === "true";
|
|
11142
|
-
}
|
|
11143
11184
|
async function resolveEnableIsolatedWorkspacesFromInstance(cfg, log) {
|
|
11144
11185
|
const paperclipUrl = cfg.paperclipUrl || process.env.PAPERCLIP_PUBLIC_URL || "http://localhost:3100";
|
|
11145
11186
|
const paperclipEmail = cfg.paperclipEmail || "";
|
|
@@ -11184,11 +11225,12 @@ function resolveWritableCompaniesDir(cfg, log) {
|
|
|
11184
11225
|
);
|
|
11185
11226
|
}
|
|
11186
11227
|
}
|
|
11187
|
-
const candidates = [
|
|
11188
|
-
|
|
11189
|
-
path2.join(
|
|
11190
|
-
|
|
11191
|
-
|
|
11228
|
+
const candidates = [];
|
|
11229
|
+
if (isDockerLayout()) {
|
|
11230
|
+
candidates.push(path2.join(os.homedir(), "instances", "default", "companies"));
|
|
11231
|
+
}
|
|
11232
|
+
candidates.push(resolveCompaniesDir(cfg));
|
|
11233
|
+
candidates.push(path2.join(os.tmpdir(), "paperclip-companies"));
|
|
11192
11234
|
const attempted = /* @__PURE__ */ new Set();
|
|
11193
11235
|
let lastError = "";
|
|
11194
11236
|
for (const candidate of candidates) {
|
|
@@ -11207,6 +11249,51 @@ function resolveWritableCompaniesDir(cfg, log) {
|
|
|
11207
11249
|
`Unable to prepare a writable companies directory. Last attempt failed at ${lastError}`
|
|
11208
11250
|
);
|
|
11209
11251
|
}
|
|
11252
|
+
function isPathInside(parent, child) {
|
|
11253
|
+
const relative = path2.relative(parent, child);
|
|
11254
|
+
return relative === "" || !!relative && !relative.startsWith("..") && !path2.isAbsolute(relative);
|
|
11255
|
+
}
|
|
11256
|
+
function normalizeGitBranch(value) {
|
|
11257
|
+
const branch = typeof value === "string" && value.trim() ? value.trim() : "main";
|
|
11258
|
+
return /^[A-Za-z0-9._/-]+$/.test(branch) ? branch.replace(/^origin\//, "") : "main";
|
|
11259
|
+
}
|
|
11260
|
+
function prepareLocalProjectWorkspace(mainProject, companyDir, log, gitIdentity) {
|
|
11261
|
+
const workspace = mainProject?.workspace;
|
|
11262
|
+
if (!workspace || workspace.sourceType !== "local_path") return;
|
|
11263
|
+
const cwd = typeof workspace.cwd === "string" ? workspace.cwd.trim() : "";
|
|
11264
|
+
if (!cwd) return;
|
|
11265
|
+
const resolvedCompanyDir = path2.resolve(companyDir);
|
|
11266
|
+
const resolvedCwd = path2.resolve(cwd);
|
|
11267
|
+
if (!isPathInside(resolvedCompanyDir, resolvedCwd)) {
|
|
11268
|
+
log?.(`\u26A0 Skipped project workspace preparation outside company dir: ${resolvedCwd}`);
|
|
11269
|
+
return;
|
|
11270
|
+
}
|
|
11271
|
+
fs2.mkdirSync(resolvedCwd, { recursive: true });
|
|
11272
|
+
const gitDir = path2.join(resolvedCwd, ".git");
|
|
11273
|
+
if (fs2.existsSync(gitDir)) {
|
|
11274
|
+
log?.(`\u2713 Project workspace ready: ${resolvedCwd}`);
|
|
11275
|
+
return;
|
|
11276
|
+
}
|
|
11277
|
+
const branch = normalizeGitBranch(workspace.defaultRef);
|
|
11278
|
+
const gitUserName = gitIdentity?.name || "Paperclip Bootstrap";
|
|
11279
|
+
const gitUserEmail = gitIdentity?.email || "bootstrap@paperclip.local";
|
|
11280
|
+
execFileSync("git", ["init", "-b", branch], { cwd: resolvedCwd, stdio: "pipe" });
|
|
11281
|
+
execFileSync(
|
|
11282
|
+
"git",
|
|
11283
|
+
[
|
|
11284
|
+
"-c",
|
|
11285
|
+
`user.email=${gitUserEmail}`,
|
|
11286
|
+
"-c",
|
|
11287
|
+
`user.name=${gitUserName}`,
|
|
11288
|
+
"commit",
|
|
11289
|
+
"--allow-empty",
|
|
11290
|
+
"-m",
|
|
11291
|
+
"chore: initialize repository"
|
|
11292
|
+
],
|
|
11293
|
+
{ cwd: resolvedCwd, stdio: "pipe" }
|
|
11294
|
+
);
|
|
11295
|
+
log?.(`\u2713 Project workspace initialized: ${resolvedCwd}`);
|
|
11296
|
+
}
|
|
11210
11297
|
function formatRoleName(role) {
|
|
11211
11298
|
return role.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
11212
11299
|
}
|
|
@@ -11264,6 +11351,110 @@ async function syncAgentInstructionsIntoManagedBundle({
|
|
|
11264
11351
|
);
|
|
11265
11352
|
}
|
|
11266
11353
|
}
|
|
11354
|
+
function routineTemplateTitle(routine) {
|
|
11355
|
+
if (typeof routine?.title === "string" && routine.title.trim()) return routine.title.trim();
|
|
11356
|
+
if (typeof routine?.name === "string" && routine.name.trim()) return routine.name.trim();
|
|
11357
|
+
return "";
|
|
11358
|
+
}
|
|
11359
|
+
async function syncRoutineTrigger({
|
|
11360
|
+
client,
|
|
11361
|
+
routineId,
|
|
11362
|
+
schedule,
|
|
11363
|
+
log
|
|
11364
|
+
}) {
|
|
11365
|
+
if (!schedule) return;
|
|
11366
|
+
try {
|
|
11367
|
+
const detail = await client.getRoutine(routineId);
|
|
11368
|
+
const triggers = Array.isArray(detail?.triggers) ? detail.triggers : [];
|
|
11369
|
+
const scheduleTrigger = triggers.find((trigger) => trigger?.kind === "schedule");
|
|
11370
|
+
if (scheduleTrigger?.id) {
|
|
11371
|
+
await client.updateRoutineTrigger(scheduleTrigger.id, {
|
|
11372
|
+
enabled: true,
|
|
11373
|
+
cronExpression: schedule,
|
|
11374
|
+
timezone: scheduleTrigger.timezone || "UTC"
|
|
11375
|
+
});
|
|
11376
|
+
return;
|
|
11377
|
+
}
|
|
11378
|
+
await client.createRoutineTrigger(routineId, {
|
|
11379
|
+
kind: "schedule",
|
|
11380
|
+
cronExpression: schedule,
|
|
11381
|
+
timezone: "UTC"
|
|
11382
|
+
});
|
|
11383
|
+
} catch (err) {
|
|
11384
|
+
log(
|
|
11385
|
+
`\u26A0 Could not sync trigger for routine "${routineId}": ${err instanceof Error ? err.message : String(err)}`
|
|
11386
|
+
);
|
|
11387
|
+
}
|
|
11388
|
+
}
|
|
11389
|
+
async function syncExistingCompanyRoutines({
|
|
11390
|
+
client,
|
|
11391
|
+
companyId,
|
|
11392
|
+
routines,
|
|
11393
|
+
ceoAgentId,
|
|
11394
|
+
teamAgentIds,
|
|
11395
|
+
log
|
|
11396
|
+
}) {
|
|
11397
|
+
if (!Array.isArray(routines) || routines.length === 0) return;
|
|
11398
|
+
let existingRoutines = [];
|
|
11399
|
+
try {
|
|
11400
|
+
existingRoutines = await client.listRoutines(companyId);
|
|
11401
|
+
} catch (err) {
|
|
11402
|
+
log(
|
|
11403
|
+
`\u26A0 Could not list existing routines for template sync: ${err instanceof Error ? err.message : String(err)}`
|
|
11404
|
+
);
|
|
11405
|
+
return;
|
|
11406
|
+
}
|
|
11407
|
+
const byTitle = /* @__PURE__ */ new Map();
|
|
11408
|
+
for (const existing of existingRoutines) {
|
|
11409
|
+
if (typeof existing?.title === "string" && existing.title.trim()) {
|
|
11410
|
+
byTitle.set(existing.title.trim().toLowerCase(), existing);
|
|
11411
|
+
}
|
|
11412
|
+
}
|
|
11413
|
+
for (const routine of routines) {
|
|
11414
|
+
const title = routineTemplateTitle(routine);
|
|
11415
|
+
if (!title) continue;
|
|
11416
|
+
const role = routine.assignTo;
|
|
11417
|
+
const assigneeAgentId = !role || role === "ceo" ? ceoAgentId : teamAgentIds[role] ?? ceoAgentId;
|
|
11418
|
+
const payload = {
|
|
11419
|
+
title,
|
|
11420
|
+
description: routine.description || null,
|
|
11421
|
+
assigneeAgentId,
|
|
11422
|
+
priority: routine.priority || "medium",
|
|
11423
|
+
status: routine.status || "active",
|
|
11424
|
+
concurrencyPolicy: routine.concurrencyPolicy || "skip_if_active",
|
|
11425
|
+
catchUpPolicy: routine.catchUpPolicy || "skip_missed"
|
|
11426
|
+
};
|
|
11427
|
+
const existing = byTitle.get(title.toLowerCase());
|
|
11428
|
+
try {
|
|
11429
|
+
if (existing?.id) {
|
|
11430
|
+
await client.updateRoutine(existing.id, payload);
|
|
11431
|
+
await syncRoutineTrigger({
|
|
11432
|
+
client,
|
|
11433
|
+
routineId: existing.id,
|
|
11434
|
+
schedule: routine.schedule,
|
|
11435
|
+
log
|
|
11436
|
+
});
|
|
11437
|
+
log(`\u2713 Synced existing routine "${title}"`);
|
|
11438
|
+
} else {
|
|
11439
|
+
const created = await client.createRoutine(companyId, payload);
|
|
11440
|
+
if (routine.schedule && created?.id) {
|
|
11441
|
+
await client.createRoutineTrigger(created.id, {
|
|
11442
|
+
kind: "schedule",
|
|
11443
|
+
cronExpression: routine.schedule,
|
|
11444
|
+
timezone: "UTC"
|
|
11445
|
+
});
|
|
11446
|
+
}
|
|
11447
|
+
log(
|
|
11448
|
+
`\u2713 Created missing routine "${title}"${routine.schedule ? ` (${routine.schedule})` : ""}`
|
|
11449
|
+
);
|
|
11450
|
+
}
|
|
11451
|
+
} catch (err) {
|
|
11452
|
+
log(
|
|
11453
|
+
`\u26A0 Could not sync routine "${title}": ${err instanceof Error ? err.message : String(err)}`
|
|
11454
|
+
);
|
|
11455
|
+
}
|
|
11456
|
+
}
|
|
11457
|
+
}
|
|
11267
11458
|
function buildDecisionLogBody({
|
|
11268
11459
|
companyName,
|
|
11269
11460
|
companyDescription,
|
|
@@ -11547,10 +11738,6 @@ var plugin = definePlugin({
|
|
|
11547
11738
|
const paperclipUrl = cfg.paperclipUrl || process.env.PAPERCLIP_PUBLIC_URL || "http://localhost:3100";
|
|
11548
11739
|
const paperclipEmail = cfg.paperclipEmail || "";
|
|
11549
11740
|
const paperclipPassword = cfg.paperclipPassword || "";
|
|
11550
|
-
const disableBoardApprovalOnNewCompanies = cfgBool(
|
|
11551
|
-
cfg,
|
|
11552
|
-
"disableBoardApprovalOnNewCompanies"
|
|
11553
|
-
);
|
|
11554
11741
|
const enableIsolatedWorktrees = await resolveEnableIsolatedWorkspacesFromInstance(cfg, log);
|
|
11555
11742
|
const enableEnrichedPersonas = true;
|
|
11556
11743
|
const companyName = typeof params.companyName === "string" ? params.companyName.trim() : "";
|
|
@@ -11573,6 +11760,17 @@ var plugin = definePlugin({
|
|
|
11573
11760
|
);
|
|
11574
11761
|
const goals = collectGoals(selectedPreset, allModules, new Set(effectiveModules));
|
|
11575
11762
|
const presetBootstrapData = collectPresetBootstrapData(selectedPreset);
|
|
11763
|
+
log("Connecting to Paperclip API...");
|
|
11764
|
+
const client = new PaperclipClient(paperclipUrl, {
|
|
11765
|
+
email: paperclipEmail,
|
|
11766
|
+
password: paperclipPassword
|
|
11767
|
+
});
|
|
11768
|
+
await client.connect();
|
|
11769
|
+
log("Connected.");
|
|
11770
|
+
const gitIdentity = {
|
|
11771
|
+
name: client.boardUserName || null,
|
|
11772
|
+
email: client.boardUserEmail || paperclipEmail || null
|
|
11773
|
+
};
|
|
11576
11774
|
const outputDir = resolveWritableCompaniesDir(cfg, log);
|
|
11577
11775
|
log("Assembling company workspace...");
|
|
11578
11776
|
const companyDescription = typeof params.companyDescription === "string" ? params.companyDescription.trim() : "";
|
|
@@ -11593,6 +11791,8 @@ var plugin = definePlugin({
|
|
|
11593
11791
|
presetLabels: presetBootstrapData.labels,
|
|
11594
11792
|
enableIsolatedWorktrees,
|
|
11595
11793
|
enableEnrichedPersonas,
|
|
11794
|
+
gitUserName: gitIdentity.name || void 0,
|
|
11795
|
+
gitUserEmail: gitIdentity.email || void 0,
|
|
11596
11796
|
outputDir,
|
|
11597
11797
|
templatesDir,
|
|
11598
11798
|
onProgress: log
|
|
@@ -11610,20 +11810,13 @@ var plugin = definePlugin({
|
|
|
11610
11810
|
log(`\u270E Override: ${relPath}`);
|
|
11611
11811
|
}
|
|
11612
11812
|
}
|
|
11813
|
+
prepareLocalProjectWorkspace(assembleResult.mainProject, companyDir, log, gitIdentity);
|
|
11613
11814
|
const ceoInstructionsDir = path2.join(companyDir, "agents", "ceo");
|
|
11614
11815
|
const ceoEntryFile = "AGENTS.md";
|
|
11615
11816
|
const ceoEntryPath = path2.join(ceoInstructionsDir, ceoEntryFile);
|
|
11616
11817
|
const ceoPromptTemplate = fs2.existsSync(ceoEntryPath) ? fs2.readFileSync(ceoEntryPath, "utf-8") : "";
|
|
11617
11818
|
log("");
|
|
11618
11819
|
log(`\u2713 Generated files: ${companyDir}`);
|
|
11619
|
-
log("Connecting to Paperclip API...");
|
|
11620
|
-
const client = new PaperclipClient(paperclipUrl, {
|
|
11621
|
-
email: paperclipEmail,
|
|
11622
|
-
password: paperclipPassword
|
|
11623
|
-
});
|
|
11624
|
-
await client.connect();
|
|
11625
|
-
log("Connected.");
|
|
11626
|
-
log("");
|
|
11627
11820
|
let company;
|
|
11628
11821
|
let companyId;
|
|
11629
11822
|
let createdCompany = false;
|
|
@@ -11642,19 +11835,7 @@ var plugin = definePlugin({
|
|
|
11642
11835
|
companyId = company.id;
|
|
11643
11836
|
createdCompany = true;
|
|
11644
11837
|
log(`\u2713 Company "${companyName}" created`);
|
|
11645
|
-
|
|
11646
|
-
try {
|
|
11647
|
-
await client.updateCompany(companyId, { requireBoardApprovalForNewAgents: false });
|
|
11648
|
-
log("\u2713 Disabled board-approval hiring policy for this new company");
|
|
11649
|
-
} catch (err) {
|
|
11650
|
-
log(
|
|
11651
|
-
`\u26A0 Could not disable board-approval hiring for new agents: ${err instanceof Error ? err.message : String(err)}`
|
|
11652
|
-
);
|
|
11653
|
-
log(" Continuing \u2014 agent creation will use an approval-aware fallback if required.");
|
|
11654
|
-
}
|
|
11655
|
-
} else {
|
|
11656
|
-
log("Keeping company hire policy as configured (board approvals may be required).");
|
|
11657
|
-
}
|
|
11838
|
+
log("Keeping company hire policy as configured (board approvals may be required).");
|
|
11658
11839
|
}
|
|
11659
11840
|
let ceoAgentId;
|
|
11660
11841
|
const teamAgentIds = {};
|
|
@@ -11666,7 +11847,7 @@ var plugin = definePlugin({
|
|
|
11666
11847
|
const repositoryMode = userProjects.some(
|
|
11667
11848
|
(project) => project?.repoUrl || project?.workspace?.sourceType === "git_repo"
|
|
11668
11849
|
) ? "existing git repository" : "fresh local repository";
|
|
11669
|
-
const approvalMode =
|
|
11850
|
+
const approvalMode = "board approval preserved; /agent-hires may create pending approvals";
|
|
11670
11851
|
log("Creating board operations and hiring plan records...");
|
|
11671
11852
|
const createdBoardOperationsIssue = await client.createIssue(companyId, {
|
|
11672
11853
|
title: "Board Operations",
|
|
@@ -11882,6 +12063,14 @@ var plugin = definePlugin({
|
|
|
11882
12063
|
);
|
|
11883
12064
|
}
|
|
11884
12065
|
teamAgentIds[roleName] = existingAgent.id;
|
|
12066
|
+
await syncAgentInstructionsIntoManagedBundle({
|
|
12067
|
+
client,
|
|
12068
|
+
agentId: existingAgent.id,
|
|
12069
|
+
sourceDir: roleInstructionsDir,
|
|
12070
|
+
entryFile: "AGENTS.md",
|
|
12071
|
+
log
|
|
12072
|
+
});
|
|
12073
|
+
log(`\u2713 Synced ${roleTitle} instructions from latest templates`);
|
|
11885
12074
|
continue;
|
|
11886
12075
|
}
|
|
11887
12076
|
const roleAgent = await client.createAgent(companyId, {
|
|
@@ -11905,8 +12094,8 @@ var plugin = definePlugin({
|
|
|
11905
12094
|
);
|
|
11906
12095
|
}
|
|
11907
12096
|
}
|
|
12097
|
+
const routines = Array.isArray(assembleResult.initialRoutines) ? assembleResult.initialRoutines : [];
|
|
11908
12098
|
if (!existingCompanyId) {
|
|
11909
|
-
const routines = Array.isArray(assembleResult.initialRoutines) ? assembleResult.initialRoutines : [];
|
|
11910
12099
|
let mainProjectId;
|
|
11911
12100
|
const mainProject = assembleResult.mainProject;
|
|
11912
12101
|
if (routines.length > 0 && mainProject?.name) {
|
|
@@ -11939,7 +12128,8 @@ var plugin = definePlugin({
|
|
|
11939
12128
|
assigneeAgentId,
|
|
11940
12129
|
projectId: mainProjectId,
|
|
11941
12130
|
priority: routine.priority || "medium",
|
|
11942
|
-
concurrencyPolicy: routine.concurrencyPolicy || "skip_if_active"
|
|
12131
|
+
concurrencyPolicy: routine.concurrencyPolicy || "skip_if_active",
|
|
12132
|
+
catchUpPolicy: routine.catchUpPolicy || "skip_missed"
|
|
11943
12133
|
});
|
|
11944
12134
|
if (routine.schedule && createdRoutine?.id) {
|
|
11945
12135
|
await client.createRoutineTrigger(createdRoutine.id, {
|
|
@@ -11957,6 +12147,15 @@ var plugin = definePlugin({
|
|
|
11957
12147
|
);
|
|
11958
12148
|
}
|
|
11959
12149
|
}
|
|
12150
|
+
} else {
|
|
12151
|
+
await syncExistingCompanyRoutines({
|
|
12152
|
+
client,
|
|
12153
|
+
companyId,
|
|
12154
|
+
routines,
|
|
12155
|
+
ceoAgentId,
|
|
12156
|
+
teamAgentIds,
|
|
12157
|
+
log
|
|
12158
|
+
});
|
|
11960
12159
|
}
|
|
11961
12160
|
const bootstrapDescription = fs2.readFileSync(
|
|
11962
12161
|
path2.join(companyDir, "BOOTSTRAP.md"),
|
|
@@ -12039,6 +12238,7 @@ var worker_default = plugin;
|
|
|
12039
12238
|
runWorker(plugin, import.meta.url);
|
|
12040
12239
|
export {
|
|
12041
12240
|
worker_default as default,
|
|
12241
|
+
prepareLocalProjectWorkspace,
|
|
12042
12242
|
resolveWritableCompaniesDir
|
|
12043
12243
|
};
|
|
12044
12244
|
//# sourceMappingURL=worker.js.map
|