@rubytech/create-maxy-code 0.1.4 → 0.1.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.
@@ -2483,7 +2483,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
2483
2483
  });
2484
2484
  if (!chunk) {
2485
2485
  if (i === 1) {
2486
- await new Promise((resolve4) => setTimeout(resolve4));
2486
+ await new Promise((resolve6) => setTimeout(resolve6));
2487
2487
  maxReadCount = 3;
2488
2488
  continue;
2489
2489
  }
@@ -2762,10 +2762,10 @@ var SCRYPT_R = 8;
2762
2762
  var SCRYPT_P = 1;
2763
2763
  var SCRYPT_KEYLEN = 64;
2764
2764
  function scryptAsync(password, salt) {
2765
- return new Promise((resolve4, reject) => {
2765
+ return new Promise((resolve6, reject) => {
2766
2766
  scrypt(password, salt, SCRYPT_KEYLEN, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (err, key) => {
2767
2767
  if (err) reject(err);
2768
- else resolve4(key);
2768
+ else resolve6(key);
2769
2769
  });
2770
2770
  });
2771
2771
  }
@@ -3412,45 +3412,551 @@ function parseCookieValue(cookieHeader, name) {
3412
3412
  }
3413
3413
  }
3414
3414
 
3415
+ // app/lib/claude-agent/account.ts
3416
+ import { resolve as resolve3 } from "path";
3417
+ import { readFileSync as readFileSync4, readdirSync, existsSync as existsSync4, statSync } from "fs";
3418
+
3419
+ // ../lib/brand-templating/src/index.ts
3420
+ import { join as join2 } from "path";
3421
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
3422
+ var PLACEHOLDER = "{{productName}}";
3423
+ var cachedProductName = null;
3424
+ function brandJsonPath() {
3425
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
3426
+ if (!platformRoot2) {
3427
+ throw new Error(
3428
+ "[skill-loader] MAXY_PLATFORM_ROOT not set \u2014 cannot resolve brand.json"
3429
+ );
3430
+ }
3431
+ return join2(platformRoot2, "config", "brand.json");
3432
+ }
3433
+ function getBrandProductName() {
3434
+ if (cachedProductName !== null) return cachedProductName;
3435
+ const path = brandJsonPath();
3436
+ if (!existsSync3(path)) {
3437
+ throw new Error(`[skill-loader] brand.json missing at ${path}`);
3438
+ }
3439
+ let parsed;
3440
+ try {
3441
+ parsed = JSON.parse(readFileSync3(path, "utf-8"));
3442
+ } catch (err) {
3443
+ throw new Error(
3444
+ `[skill-loader] brand.json unreadable at ${path}: ${err instanceof Error ? err.message : String(err)}`
3445
+ );
3446
+ }
3447
+ const value = parsed.productName;
3448
+ if (typeof value !== "string" || value.trim() === "") {
3449
+ throw new Error(
3450
+ `[skill-loader] brand.json at ${path} has missing or empty productName`
3451
+ );
3452
+ }
3453
+ cachedProductName = value;
3454
+ return value;
3455
+ }
3456
+ function substituteBrandPlaceholders(content, sourcePath) {
3457
+ if (!content.includes(PLACEHOLDER)) return content;
3458
+ let productName;
3459
+ try {
3460
+ productName = getBrandProductName();
3461
+ } catch (err) {
3462
+ console.error(
3463
+ `[skill-loader] ERROR: brand.json missing \u2014 cannot resolve productName for skill ${sourcePath}`
3464
+ );
3465
+ throw err;
3466
+ }
3467
+ const occurrences = content.split(PLACEHOLDER).length - 1;
3468
+ const substituted = content.split(PLACEHOLDER).join(productName);
3469
+ console.log(
3470
+ `[skill-loader] brand-substituted productName=${productName} skill=${sourcePath} occurrences=${occurrences}`
3471
+ );
3472
+ return substituted;
3473
+ }
3474
+
3475
+ // app/lib/claude-agent/account.ts
3476
+ var PLATFORM_ROOT2 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "..");
3477
+ var ACCOUNTS_DIR = resolve3(PLATFORM_ROOT2, "..", "data/accounts");
3478
+ if (!existsSync4(PLATFORM_ROOT2)) {
3479
+ throw new Error(
3480
+ `PLATFORM_ROOT does not exist: ${PLATFORM_ROOT2}
3481
+ Set the MAXY_PLATFORM_ROOT environment variable to the absolute path of the platform directory.`
3482
+ );
3483
+ }
3484
+ function resolveAccount() {
3485
+ if (!existsSync4(ACCOUNTS_DIR)) return null;
3486
+ let usersJsonUserId = null;
3487
+ if (existsSync4(USERS_FILE)) {
3488
+ try {
3489
+ const raw2 = readFileSync4(USERS_FILE, "utf-8").trim();
3490
+ if (raw2) {
3491
+ const users = JSON.parse(raw2);
3492
+ if (users.length > 0) {
3493
+ usersJsonUserId = users[0].userId;
3494
+ }
3495
+ }
3496
+ } catch {
3497
+ }
3498
+ }
3499
+ const entries = readdirSync(ACCOUNTS_DIR, { withFileTypes: true });
3500
+ let fallback = null;
3501
+ for (const entry of entries) {
3502
+ if (!entry.isDirectory()) continue;
3503
+ const configPath = resolve3(ACCOUNTS_DIR, entry.name, "account.json");
3504
+ if (!existsSync4(configPath)) continue;
3505
+ const raw2 = readFileSync4(configPath, "utf-8");
3506
+ let config;
3507
+ try {
3508
+ config = JSON.parse(raw2);
3509
+ } catch {
3510
+ console.error(`[maxy] account.json is corrupt at ${configPath} \u2014 skipping`);
3511
+ continue;
3512
+ }
3513
+ if (!config.adminModel || !config.publicModel) {
3514
+ throw new Error(
3515
+ `[maxy] account.json at ${configPath} is missing required model fields (adminModel / publicModel). Update account.json with valid model identifiers.`
3516
+ );
3517
+ }
3518
+ const result = {
3519
+ accountId: config.accountId,
3520
+ accountDir: resolve3(ACCOUNTS_DIR, entry.name),
3521
+ config
3522
+ };
3523
+ if (usersJsonUserId && config.admins?.some((a) => a.userId === usersJsonUserId)) {
3524
+ return result;
3525
+ }
3526
+ if (!fallback) {
3527
+ fallback = result;
3528
+ }
3529
+ }
3530
+ if (usersJsonUserId && fallback) {
3531
+ console.warn(
3532
+ `[maxy] resolveAccount: no account matches users.json userId ${usersJsonUserId} \u2014 falling back to ${fallback.accountId}`
3533
+ );
3534
+ }
3535
+ return fallback;
3536
+ }
3537
+ function readAgentFile(accountDir, agentName, filename) {
3538
+ const filePath = resolve3(accountDir, "agents", agentName, filename);
3539
+ if (!existsSync4(filePath)) return null;
3540
+ const raw2 = readFileSync4(filePath, "utf-8");
3541
+ if (filename.endsWith(".md")) {
3542
+ return substituteBrandPlaceholders(raw2, filePath);
3543
+ }
3544
+ return raw2;
3545
+ }
3546
+ var RESERVED_SLUGS = /* @__PURE__ */ new Set(["admin", "api", "assets", "brand", "bot", "privacy"]);
3547
+ var SLUG_PATTERN = /^[a-z][a-z0-9-]{2,49}$/;
3548
+ function validateAgentSlug(slug) {
3549
+ if (!SLUG_PATTERN.test(slug)) return false;
3550
+ if (RESERVED_SLUGS.has(slug)) return false;
3551
+ return true;
3552
+ }
3553
+ function resolveDefaultAgentSlug(accountDir) {
3554
+ const configPath = resolve3(accountDir, "account.json");
3555
+ if (!existsSync4(configPath)) {
3556
+ console.error("[agent-resolve] account.json not found \u2014 cannot resolve defaultAgent");
3557
+ return null;
3558
+ }
3559
+ let config;
3560
+ try {
3561
+ config = JSON.parse(readFileSync4(configPath, "utf-8"));
3562
+ } catch (err) {
3563
+ console.error("[agent-resolve] failed to read account.json:", err);
3564
+ return null;
3565
+ }
3566
+ if (!config.defaultAgent) {
3567
+ console.error("[agent-resolve] defaultAgent not configured in account.json \u2014 set it via the connect-whatsapp skill");
3568
+ return null;
3569
+ }
3570
+ const agentConfigPath = resolve3(accountDir, "agents", config.defaultAgent, "config.json");
3571
+ if (!existsSync4(agentConfigPath)) {
3572
+ console.error(`[agent-resolve] defaultAgent="${config.defaultAgent}" has no config.json at ${agentConfigPath}`);
3573
+ return null;
3574
+ }
3575
+ return config.defaultAgent;
3576
+ }
3577
+ function estimateTokens(text) {
3578
+ return Math.ceil(text.length / 4);
3579
+ }
3580
+ function resolveAgentConfig(accountDir, agentName) {
3581
+ let model = null;
3582
+ let plugins = null;
3583
+ let status = null;
3584
+ let displayName = null;
3585
+ let image = null;
3586
+ let imageShape = null;
3587
+ let showAgentName = false;
3588
+ let liveMemory = false;
3589
+ let knowledgeKeywords = null;
3590
+ let accessMode = "open";
3591
+ const MAX_KNOWLEDGE_KEYWORDS = 5;
3592
+ const configRaw = readAgentFile(accountDir, agentName, "config.json");
3593
+ if (configRaw) {
3594
+ let parsed;
3595
+ try {
3596
+ parsed = JSON.parse(configRaw);
3597
+ } catch {
3598
+ console.warn(`[agent-config] ${agentName}/config.json: invalid JSON \u2014 using defaults`);
3599
+ parsed = {};
3600
+ }
3601
+ model = typeof parsed.model === "string" ? parsed.model : null;
3602
+ plugins = Array.isArray(parsed.plugins) ? parsed.plugins : null;
3603
+ status = typeof parsed.status === "string" ? parsed.status : null;
3604
+ displayName = typeof parsed.displayName === "string" ? parsed.displayName : null;
3605
+ image = typeof parsed.image === "string" ? parsed.image : null;
3606
+ if (typeof parsed.imageShape === "string" && ["circle", "rounded"].includes(parsed.imageShape)) {
3607
+ imageShape = parsed.imageShape;
3608
+ }
3609
+ if (parsed.showAgentName === true) {
3610
+ showAgentName = true;
3611
+ } else if (parsed.showAgentName === "none") {
3612
+ showAgentName = "none";
3613
+ }
3614
+ if (image || imageShape || showAgentName) {
3615
+ console.log(`[agent-config] ${agentName}: image=${image || "(none)"} imageShape=${imageShape || "(none)"} showAgentName=${showAgentName}`);
3616
+ }
3617
+ if (typeof parsed.accessMode === "string" && ["gated", "paid"].includes(parsed.accessMode)) {
3618
+ accessMode = parsed.accessMode;
3619
+ }
3620
+ if (typeof parsed.liveMemory === "boolean") {
3621
+ liveMemory = parsed.liveMemory;
3622
+ } else if (typeof parsed.liveMemory === "string") {
3623
+ const lower = parsed.liveMemory.toLowerCase();
3624
+ if (lower === "true") {
3625
+ liveMemory = true;
3626
+ console.warn(`[agent-config] ${agentName}: liveMemory is string "true" \u2014 coercing to boolean. Fix the config to use a boolean value.`);
3627
+ } else if (lower === "false") {
3628
+ liveMemory = false;
3629
+ console.warn(`[agent-config] ${agentName}: liveMemory is string "false" \u2014 coercing to boolean. Fix the config to use a boolean value.`);
3630
+ } else {
3631
+ throw new Error(`[agent-config] ${agentName}: liveMemory has invalid string value "${parsed.liveMemory}" \u2014 expected boolean or "true"/"false"`);
3632
+ }
3633
+ } else if (parsed.liveMemory !== void 0 && parsed.liveMemory !== null) {
3634
+ throw new Error(`[agent-config] ${agentName}: liveMemory has invalid type ${typeof parsed.liveMemory} \u2014 expected boolean or "true"/"false"`);
3635
+ }
3636
+ if (Array.isArray(parsed.knowledgeKeywords) && parsed.knowledgeKeywords.length > 0) {
3637
+ const filtered = parsed.knowledgeKeywords.filter((k) => typeof k === "string" && k.trim()).map((k) => k.replace(/,/g, "").trim().toLowerCase()).filter(Boolean);
3638
+ if (filtered.length > MAX_KNOWLEDGE_KEYWORDS) {
3639
+ console.warn(`[agent-config] ${agentName}: knowledgeKeywords has ${filtered.length} entries \u2014 capping at ${MAX_KNOWLEDGE_KEYWORDS}`);
3640
+ }
3641
+ knowledgeKeywords = filtered.length > 0 ? filtered.slice(0, MAX_KNOWLEDGE_KEYWORDS) : null;
3642
+ }
3643
+ }
3644
+ let knowledge = null;
3645
+ let knowledgeBaked = false;
3646
+ const agentDir = resolve3(accountDir, "agents", agentName);
3647
+ const knowledgePath = resolve3(agentDir, "KNOWLEDGE.md");
3648
+ const summaryPath = resolve3(agentDir, "KNOWLEDGE-SUMMARY.md");
3649
+ const hasKnowledge = existsSync4(knowledgePath);
3650
+ const hasSummary = existsSync4(summaryPath);
3651
+ if (hasKnowledge && hasSummary) {
3652
+ const knowledgeMtime = statSync(knowledgePath).mtimeMs;
3653
+ const summaryMtime = statSync(summaryPath).mtimeMs;
3654
+ if (summaryMtime >= knowledgeMtime) {
3655
+ knowledge = readFileSync4(summaryPath, "utf-8");
3656
+ } else {
3657
+ console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
3658
+ knowledge = readFileSync4(knowledgePath, "utf-8");
3659
+ }
3660
+ knowledgeBaked = true;
3661
+ } else if (hasKnowledge) {
3662
+ knowledge = readFileSync4(knowledgePath, "utf-8");
3663
+ knowledgeBaked = true;
3664
+ }
3665
+ let budget = null;
3666
+ const identityRaw = readAgentFile(accountDir, agentName, "IDENTITY.md");
3667
+ const soulRaw = readAgentFile(accountDir, agentName, "SOUL.md");
3668
+ if (identityRaw || soulRaw || knowledge) {
3669
+ const identityTokens = identityRaw ? estimateTokens(identityRaw) : 0;
3670
+ const soulTokens = soulRaw ? estimateTokens(soulRaw) : 0;
3671
+ const knowledgeTokens = knowledge ? estimateTokens(knowledge) : 0;
3672
+ budget = {
3673
+ identity: identityTokens,
3674
+ soul: soulTokens,
3675
+ knowledge: knowledgeTokens,
3676
+ plugins: 0,
3677
+ total: identityTokens + soulTokens + knowledgeTokens
3678
+ };
3679
+ }
3680
+ return { model, plugins, status, displayName, image, imageShape, showAgentName, knowledge, knowledgeBaked, liveMemory, knowledgeKeywords, budget, accessMode };
3681
+ }
3682
+ function getDefaultAccountId() {
3683
+ return resolveAccount()?.accountId ?? null;
3684
+ }
3685
+ function resolveUserAccounts(userId) {
3686
+ if (!existsSync4(ACCOUNTS_DIR)) return [];
3687
+ const results = [];
3688
+ const entries = readdirSync(ACCOUNTS_DIR, { withFileTypes: true });
3689
+ for (const entry of entries) {
3690
+ if (!entry.isDirectory()) continue;
3691
+ const configPath = resolve3(ACCOUNTS_DIR, entry.name, "account.json");
3692
+ if (!existsSync4(configPath)) continue;
3693
+ let config;
3694
+ try {
3695
+ config = JSON.parse(readFileSync4(configPath, "utf-8"));
3696
+ } catch {
3697
+ console.error(`[session] account.json corrupt at ${configPath} \u2014 skipping`);
3698
+ continue;
3699
+ }
3700
+ const adminEntry = config.admins?.find((a) => a.userId === userId);
3701
+ if (adminEntry) {
3702
+ results.push({
3703
+ accountId: config.accountId,
3704
+ accountDir: resolve3(ACCOUNTS_DIR, entry.name),
3705
+ config,
3706
+ role: adminEntry.role
3707
+ });
3708
+ }
3709
+ }
3710
+ return results;
3711
+ }
3712
+
3713
+ // app/lib/claude-agent/session-store.ts
3714
+ import { createHash } from "crypto";
3715
+ var SESSION_TTL_MS2 = 24 * 60 * 60 * 1e3;
3716
+ var sessionStore = /* @__PURE__ */ new Map();
3717
+ function fingerprintSessionKey(raw2) {
3718
+ if (typeof raw2 !== "string" || !raw2) return raw2;
3719
+ if (/^sk_[a-f0-9]{16}$/.test(raw2)) return raw2;
3720
+ if (!raw2.startsWith("v1.")) return raw2;
3721
+ return `sk_${createHash("sha256").update(raw2).digest("hex").slice(0, 16)}`;
3722
+ }
3723
+ function registerSession(cacheKey2, agentType, accountId, _unused, userId, userName, role) {
3724
+ const existing = sessionStore.get(cacheKey2);
3725
+ if (existing) {
3726
+ existing.agentType = agentType;
3727
+ existing.accountId = accountId;
3728
+ existing.userId = userId ?? existing.userId;
3729
+ existing.userName = userName ?? existing.userName;
3730
+ existing.role = role ?? existing.role;
3731
+ return;
3732
+ }
3733
+ sessionStore.set(cacheKey2, { agentType, createdAt: Date.now(), accountId, userId, userName, role });
3734
+ }
3735
+ function validateSession(cacheKey2, agentType, _signedSessionToken) {
3736
+ const session = sessionStore.get(cacheKey2);
3737
+ if (!session) return { ok: false, reason: "session-not-registered" };
3738
+ if (session.agentType !== agentType) return { ok: false, reason: "agent-type-mismatch" };
3739
+ if (Date.now() - session.createdAt > SESSION_TTL_MS2) {
3740
+ sessionStore.delete(cacheKey2);
3741
+ return { ok: false, reason: "session-expired-age" };
3742
+ }
3743
+ return { ok: true };
3744
+ }
3745
+ function getAccountIdForSession(cacheKey2) {
3746
+ return sessionStore.get(cacheKey2)?.accountId;
3747
+ }
3748
+ function getUserIdForSession(cacheKey2) {
3749
+ return sessionStore.get(cacheKey2)?.userId;
3750
+ }
3751
+ function getUserNameForSession(cacheKey2) {
3752
+ return sessionStore.get(cacheKey2)?.userName;
3753
+ }
3754
+ function getRoleForSession(cacheKey2) {
3755
+ return sessionStore.get(cacheKey2)?.role;
3756
+ }
3757
+ function getConversationIdForSession(cacheKey2) {
3758
+ return sessionStore.get(cacheKey2)?.conversationId;
3759
+ }
3760
+ function setConversationIdForSession(cacheKey2, conversationId) {
3761
+ const session = sessionStore.get(cacheKey2);
3762
+ if (!session) return false;
3763
+ session.conversationId = conversationId;
3764
+ return true;
3765
+ }
3766
+ function setWantsPriorConversation(cacheKey2) {
3767
+ const session = sessionStore.get(cacheKey2);
3768
+ if (session) session.wantsPriorConversation = true;
3769
+ }
3770
+ function unregisterSession(cacheKey2) {
3771
+ return sessionStore.delete(cacheKey2);
3772
+ }
3773
+ function getSessionKeyByConversationId(_conversationId) {
3774
+ return void 0;
3775
+ }
3776
+
3777
+ // app/lib/claude-agent/plugin-manifest.ts
3778
+ import { resolve as resolve4, join as join3 } from "path";
3779
+ import {
3780
+ readFileSync as readFileSync5,
3781
+ writeFileSync as writeFileSync2,
3782
+ readdirSync as readdirSync2,
3783
+ existsSync as existsSync5,
3784
+ statSync as statSync2,
3785
+ cpSync
3786
+ } from "fs";
3787
+ function isMissingPluginDir(pluginDir) {
3788
+ const pluginRoot = resolve4(PLATFORM_ROOT2, "plugins", pluginDir);
3789
+ if (existsSync5(resolve4(pluginRoot, "PLUGIN.md"))) return false;
3790
+ if (existsSync5(resolve4(pluginRoot, "mcp/dist/index.js"))) return false;
3791
+ return true;
3792
+ }
3793
+ function findMissingPlugins(enabledPlugins) {
3794
+ if (!Array.isArray(enabledPlugins) || enabledPlugins.length === 0) return [];
3795
+ return enabledPlugins.filter(isMissingPluginDir);
3796
+ }
3797
+ function readBundleSubPlugins(bundlePath) {
3798
+ if (!existsSync5(bundlePath)) return [];
3799
+ let raw2;
3800
+ try {
3801
+ raw2 = readFileSync5(bundlePath, "utf-8");
3802
+ } catch {
3803
+ return [];
3804
+ }
3805
+ const fm = raw2.match(/^---\n([\s\S]*?)\n---/);
3806
+ if (!fm) return [];
3807
+ const subs = [];
3808
+ let inPlugins = false;
3809
+ for (const line of fm[1].split("\n")) {
3810
+ if (/^plugins:/.test(line)) {
3811
+ inPlugins = true;
3812
+ continue;
3813
+ }
3814
+ if (inPlugins) {
3815
+ const m = line.match(/^\s+- (.+)/);
3816
+ if (m) subs.push(m[1].trim());
3817
+ else break;
3818
+ }
3819
+ }
3820
+ return subs;
3821
+ }
3822
+ function walkPremiumBundles() {
3823
+ if (BRAND_NAME === "maxy") return [];
3824
+ const stagingRoot = resolve4(PLATFORM_ROOT2, "../premium-plugins");
3825
+ if (!existsSync5(stagingRoot)) return [];
3826
+ let entries;
3827
+ try {
3828
+ entries = readdirSync2(stagingRoot);
3829
+ } catch {
3830
+ return [];
3831
+ }
3832
+ const result = [];
3833
+ for (const bundle of entries) {
3834
+ const bundleDir = resolve4(stagingRoot, bundle);
3835
+ try {
3836
+ if (!statSync2(bundleDir).isDirectory()) continue;
3837
+ } catch {
3838
+ continue;
3839
+ }
3840
+ const declared = readBundleSubPlugins(join3(bundleDir, "BUNDLE.md"));
3841
+ result.push({ bundle, subs: declared.length > 0 ? declared : [bundle] });
3842
+ }
3843
+ return result;
3844
+ }
3845
+ function autoDeliverPremiumPlugins() {
3846
+ const TAG = "[premium-auto-deliver]";
3847
+ const bundles = walkPremiumBundles();
3848
+ if (bundles.length === 0) return;
3849
+ const stagingRoot = resolve4(PLATFORM_ROOT2, "../premium-plugins");
3850
+ const pluginsDir = resolve4(PLATFORM_ROOT2, "plugins");
3851
+ for (const { bundle, subs } of bundles) {
3852
+ const stagingDir = resolve4(stagingRoot, bundle);
3853
+ const bundlePath = join3(stagingDir, "BUNDLE.md");
3854
+ const isBundle = existsSync5(bundlePath);
3855
+ if (isBundle) {
3856
+ let delivered = 0;
3857
+ let skipped = 0;
3858
+ for (const sub of subs) {
3859
+ const target = resolve4(pluginsDir, sub);
3860
+ if (existsSync5(resolve4(target, "PLUGIN.md"))) {
3861
+ skipped++;
3862
+ continue;
3863
+ }
3864
+ const source = resolve4(stagingDir, "plugins", sub);
3865
+ if (!existsSync5(source)) {
3866
+ console.log(`${TAG} ${bundle}/${sub}: source missing in staging, skipping`);
3867
+ continue;
3868
+ }
3869
+ try {
3870
+ cpSync(source, target, { recursive: true });
3871
+ delivered++;
3872
+ } catch (err) {
3873
+ console.log(`${TAG} ${bundle}/${sub}: copy failed: ${err instanceof Error ? err.message : String(err)}`);
3874
+ }
3875
+ }
3876
+ console.log(`${TAG} ${bundle} (bundle): ${delivered} delivered, ${skipped} already present`);
3877
+ } else {
3878
+ const target = resolve4(pluginsDir, bundle);
3879
+ if (existsSync5(resolve4(target, "PLUGIN.md"))) {
3880
+ console.log(`${TAG} ${bundle}: already present, skipping`);
3881
+ } else {
3882
+ try {
3883
+ cpSync(stagingDir, target, { recursive: true });
3884
+ console.log(`${TAG} ${bundle} (standalone): delivered`);
3885
+ } catch (err) {
3886
+ console.log(`${TAG} ${bundle}: copy failed: ${err instanceof Error ? err.message : String(err)}`);
3887
+ }
3888
+ }
3889
+ }
3890
+ }
3891
+ }
3892
+ function reconcileEnabledPlugins(accountDir, config) {
3893
+ const TAG = "[premium-auto-deliver]";
3894
+ if (!accountDir || !config) return;
3895
+ const bundles = walkPremiumBundles();
3896
+ const pluginsDir = resolve4(PLATFORM_ROOT2, "plugins");
3897
+ const bundleNames = [];
3898
+ const allSubs = [];
3899
+ for (const { bundle, subs } of bundles) {
3900
+ bundleNames.push(bundle);
3901
+ for (const sub of subs) {
3902
+ if (!existsSync5(resolve4(pluginsDir, sub, "PLUGIN.md"))) continue;
3903
+ allSubs.push(sub);
3904
+ }
3905
+ }
3906
+ const current = Array.isArray(config.enabledPlugins) ? config.enabledPlugins : [];
3907
+ const currentSet = new Set(current);
3908
+ const added = [];
3909
+ for (const sub of allSubs) {
3910
+ if (currentSet.has(sub)) continue;
3911
+ currentSet.add(sub);
3912
+ added.push(sub);
3913
+ }
3914
+ console.log(`${TAG} brand=${BRAND_NAME} bundles=[${bundleNames.join(",")}] subs=[${allSubs.join(",")}] stamped=${added.length}`);
3915
+ if (added.length === 0) return;
3916
+ const merged = [...currentSet];
3917
+ const configPath = resolve4(accountDir, "account.json");
3918
+ try {
3919
+ const raw2 = readFileSync5(configPath, "utf-8");
3920
+ const parsed = JSON.parse(raw2);
3921
+ parsed.enabledPlugins = merged;
3922
+ writeFileSync2(configPath, JSON.stringify(parsed, null, 2) + "\n");
3923
+ config.enabledPlugins = merged;
3924
+ } catch (err) {
3925
+ console.error(`${TAG} enabled-stamp write failed: ${err instanceof Error ? err.message : String(err)}`);
3926
+ }
3927
+ }
3928
+
3929
+ // app/lib/claude-agent/logging.ts
3930
+ var emitMissingOnResolve = (..._args) => null;
3931
+
3932
+ // app/lib/claude-agent/spawn-env.ts
3933
+ var getBundleMtimeIso = (..._args) => null;
3934
+
3935
+ // app/lib/claude-agent/stream-log-writer.ts
3936
+ var appendStreamLogLine = (..._args) => null;
3937
+
3938
+ // app/lib/claude-agent/summary-helpers.ts
3939
+ var stripAttachmentMetaSuffix = (..._args) => null;
3940
+
3415
3941
  // app/lib/claude-agent.ts
3416
3942
  var agentLogStream = (..._args) => null;
3417
3943
  var clearSessionHistory = (..._args) => null;
3418
3944
  var compactSession = (..._args) => null;
3419
3945
  var completeGrantSetup = (..._args) => null;
3420
- var findMissingPlugins = (..._args) => null;
3421
- var fingerprintSessionKey = (..._args) => null;
3422
- var getAccountIdForSession = (..._args) => null;
3423
3946
  var getAgentNameForSession = (..._args) => null;
3424
- var getConversationIdForSession = (..._args) => null;
3425
- var getDefaultAccountId = (..._args) => null;
3426
3947
  var getGrantForSession = (..._args) => null;
3427
3948
  var getGroupSlugForSession = (..._args) => null;
3428
- var getRoleForSession = (..._args) => null;
3429
- var getSessionMessages = (..._args) => null;
3430
3949
  var getStreamLogHandle = (..._args) => null;
3431
- var getUserIdForSession = (..._args) => null;
3432
- var getUserNameForSession = (..._args) => null;
3433
3950
  var getVisitorIdForSession = (..._args) => null;
3434
- var hasStubAccountDir = (..._args) => null;
3435
3951
  var invokeAgent = (..._args) => null;
3436
- var listAdminSessionsInProgress = (..._args) => null;
3437
- var mintAdminSessionToken = (..._args) => null;
3952
+ var listAdminSessionsInProgress = (..._args) => [];
3438
3953
  var registerGrantSession = (..._args) => null;
3439
3954
  var registerResumedSession = (..._args) => null;
3440
- var registerSession = (..._args) => null;
3441
- var resolveAccount = (..._args) => null;
3442
- var resolveAgentConfig = (..._args) => null;
3443
- var resolveDefaultAgentSlug = (..._args) => null;
3444
- var resolveUserAccounts = (..._args) => null;
3445
3955
  var setAgentSessionId = (..._args) => null;
3446
- var setConversationIdForSession = (..._args) => null;
3447
3956
  var setGroupContextForSession = (..._args) => null;
3448
- var setWantsPriorConversation = (..._args) => null;
3957
+ var getSessionMessages = (..._args) => [];
3449
3958
  var sigtermFlushStreamLogs = (..._args) => null;
3450
3959
  var streamLogPathFor = (..._args) => null;
3451
- var unregisterSession = (..._args) => null;
3452
- var validateAgentSlug = (..._args) => null;
3453
- var validateSession = (..._args) => null;
3454
3960
 
3455
3961
  // server/routes/_helpers.ts
3456
3962
  async function safeJson(c) {
@@ -3577,16 +4083,16 @@ var clientIpMiddleware = async (c, next) => {
3577
4083
 
3578
4084
  // server/lib/action-runner.ts
3579
4085
  import { spawn } from "child_process";
3580
- import { createReadStream, existsSync as existsSync3, mkdirSync as mkdirSync3, readdirSync, statSync, unlinkSync, watch } from "fs";
4086
+ import { createReadStream, existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync as readdirSync3, statSync as statSync3, unlinkSync, watch } from "fs";
3581
4087
  import { homedir as homedir2 } from "os";
3582
- import { join as join2, resolve as resolve3 } from "path";
3583
- import { readFileSync as readFileSync3 } from "fs";
4088
+ import { join as join4, resolve as resolve5 } from "path";
4089
+ import { readFileSync as readFileSync6 } from "fs";
3584
4090
  import { setTimeout as delay } from "timers/promises";
3585
4091
  function loadBrandInfo() {
3586
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "..");
3587
- const brandPath = resolve3(platformRoot2, "config", "brand.json");
4092
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve5(process.cwd(), "..");
4093
+ const brandPath = resolve5(platformRoot2, "config", "brand.json");
3588
4094
  try {
3589
- const parsed = JSON.parse(readFileSync3(brandPath, "utf-8"));
4095
+ const parsed = JSON.parse(readFileSync6(brandPath, "utf-8"));
3590
4096
  const hostname = typeof parsed.hostname === "string" && parsed.hostname ? parsed.hostname : "maxy";
3591
4097
  const configDir = typeof parsed.configDir === "string" && parsed.configDir ? parsed.configDir : ".maxy";
3592
4098
  return { hostname, configDir };
@@ -3596,10 +4102,10 @@ function loadBrandInfo() {
3596
4102
  }
3597
4103
  function actionLogDir() {
3598
4104
  const { configDir } = loadBrandInfo();
3599
- return join2(homedir2(), configDir, "logs", "actions");
4105
+ return join4(homedir2(), configDir, "logs", "actions");
3600
4106
  }
3601
4107
  function actionLogPath(actionId) {
3602
- return join2(actionLogDir(), `${actionId}.log`);
4108
+ return join4(actionLogDir(), `${actionId}.log`);
3603
4109
  }
3604
4110
  var WHITELIST = {
3605
4111
  upgrade: {
@@ -3637,13 +4143,13 @@ var WHITELIST = {
3637
4143
  if (!idSet && !nameSet) {
3638
4144
  throw new Error("cloudflare-setup: requires tunnelId (operator-selected) OR tunnelName (operator-created)");
3639
4145
  }
3640
- const scriptPath = join2(homedir2(), "setup-tunnel.sh");
3641
- if (!existsSync3(scriptPath)) {
4146
+ const scriptPath = join4(homedir2(), "setup-tunnel.sh");
4147
+ if (!existsSync6(scriptPath)) {
3642
4148
  throw new Error(
3643
4149
  `cloudflare-setup: ~/setup-tunnel.sh not found. Re-run the installer to repair the symlink.`
3644
4150
  );
3645
4151
  }
3646
- const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "..");
4152
+ const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve5(process.cwd(), "..");
3647
4153
  return {
3648
4154
  argv: [scriptPath, ...positional],
3649
4155
  env: {
@@ -3691,12 +4197,12 @@ function actionNameFromId(actionId) {
3691
4197
  }
3692
4198
  function cleanupStaleLogs() {
3693
4199
  const dir = actionLogDir();
3694
- if (!existsSync3(dir)) return;
4200
+ if (!existsSync6(dir)) return;
3695
4201
  const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
3696
- for (const entry of readdirSync(dir)) {
3697
- const full = join2(dir, entry);
4202
+ for (const entry of readdirSync3(dir)) {
4203
+ const full = join4(dir, entry);
3698
4204
  try {
3699
- const st = statSync(full);
4205
+ const st = statSync3(full);
3700
4206
  if (st.isFile() && st.mtimeMs < cutoff) unlinkSync(full);
3701
4207
  } catch {
3702
4208
  }
@@ -3812,10 +4318,10 @@ function extractPhase(text) {
3812
4318
  return null;
3813
4319
  }
3814
4320
  function readLogTailLines(path, tailLines) {
3815
- if (!existsSync3(path)) return [];
4321
+ if (!existsSync6(path)) return [];
3816
4322
  let raw2;
3817
4323
  try {
3818
- raw2 = readFileSync3(path, "utf-8");
4324
+ raw2 = readFileSync6(path, "utf-8");
3819
4325
  } catch {
3820
4326
  return [];
3821
4327
  }
@@ -3832,8 +4338,8 @@ async function* streamActionEvents(opts) {
3832
4338
  let byteOffset = opts.fromByteOffset ?? 0;
3833
4339
  const actionName = actionNameFromId(actionId);
3834
4340
  const reconcileFromLog = isKnownAction(actionName) ? WHITELIST[actionName].reconcileFromLog : void 0;
3835
- if (existsSync3(logPath)) {
3836
- const snapshot = statSync(logPath).size;
4341
+ if (existsSync6(logPath)) {
4342
+ const snapshot = statSync3(logPath).size;
3837
4343
  if (byteOffset < snapshot) {
3838
4344
  for await (const ev of readLogLines(logPath, byteOffset, snapshot)) {
3839
4345
  const phase = extractPhase(ev.text);
@@ -3860,10 +4366,10 @@ async function* streamActionEvents(opts) {
3860
4366
  r();
3861
4367
  }
3862
4368
  }
3863
- const watcher = existsSync3(logPath) ? watch(logPath, async () => {
4369
+ const watcher = existsSync6(logPath) ? watch(logPath, async () => {
3864
4370
  if (!watching) return;
3865
4371
  try {
3866
- const size = statSync(logPath).size;
4372
+ const size = statSync3(logPath).size;
3867
4373
  if (size <= byteOffset) return;
3868
4374
  for await (const ev of readLogLines(logPath, byteOffset, size)) {
3869
4375
  const phase = extractPhase(ev.text);
@@ -4095,44 +4601,52 @@ export {
4095
4601
  renderLoginPage,
4096
4602
  canAccessAdmin,
4097
4603
  parseCookieValue,
4604
+ PLATFORM_ROOT2 as PLATFORM_ROOT,
4605
+ ACCOUNTS_DIR,
4606
+ resolveAccount,
4607
+ validateAgentSlug,
4608
+ resolveDefaultAgentSlug,
4609
+ resolveAgentConfig,
4610
+ getDefaultAccountId,
4611
+ resolveUserAccounts,
4612
+ fingerprintSessionKey,
4613
+ registerSession,
4614
+ validateSession,
4615
+ getAccountIdForSession,
4616
+ getUserIdForSession,
4617
+ getUserNameForSession,
4618
+ getRoleForSession,
4619
+ getConversationIdForSession,
4620
+ setConversationIdForSession,
4621
+ setWantsPriorConversation,
4622
+ unregisterSession,
4623
+ getSessionKeyByConversationId,
4624
+ findMissingPlugins,
4625
+ walkPremiumBundles,
4626
+ autoDeliverPremiumPlugins,
4627
+ reconcileEnabledPlugins,
4628
+ emitMissingOnResolve,
4629
+ getBundleMtimeIso,
4630
+ appendStreamLogLine,
4631
+ stripAttachmentMetaSuffix,
4098
4632
  agentLogStream,
4099
4633
  clearSessionHistory,
4100
4634
  compactSession,
4101
4635
  completeGrantSetup,
4102
- findMissingPlugins,
4103
- fingerprintSessionKey,
4104
- getAccountIdForSession,
4105
4636
  getAgentNameForSession,
4106
- getConversationIdForSession,
4107
- getDefaultAccountId,
4108
4637
  getGrantForSession,
4109
4638
  getGroupSlugForSession,
4110
- getRoleForSession,
4111
- getSessionMessages,
4112
4639
  getStreamLogHandle,
4113
- getUserIdForSession,
4114
- getUserNameForSession,
4115
4640
  getVisitorIdForSession,
4116
- hasStubAccountDir,
4117
4641
  invokeAgent,
4118
4642
  listAdminSessionsInProgress,
4119
- mintAdminSessionToken,
4120
4643
  registerGrantSession,
4121
4644
  registerResumedSession,
4122
- registerSession,
4123
- resolveAccount,
4124
- resolveAgentConfig,
4125
- resolveDefaultAgentSlug,
4126
- resolveUserAccounts,
4127
4645
  setAgentSessionId,
4128
- setConversationIdForSession,
4129
4646
  setGroupContextForSession,
4130
- setWantsPriorConversation,
4647
+ getSessionMessages,
4131
4648
  sigtermFlushStreamLogs,
4132
4649
  streamLogPathFor,
4133
- unregisterSession,
4134
- validateAgentSlug,
4135
- validateSession,
4136
4650
  safeJson,
4137
4651
  requireAdminSession,
4138
4652
  tryCookieBridgeForConversation,