@pleri/olam-cli 0.1.45 → 0.1.47

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "auth": "sha256:4e2ea22c5ef026ecf7b10892fbe381384b32e83636962d86d9ab1fc572972f8e",
3
- "devbox": "sha256:9363a1979d7df0ed2b2c964c183ba3e739383c146416f27b1ceb976f64648fd9",
3
+ "devbox": "sha256:4148e0bc06774b3970a12f2257d8ebb381bb51b898f61351c1a6d19ee4b948c9",
4
4
  "host-cp": "sha256:29d2e544db7fabae259a0311a76ff367ee5e2ca5f48e9640ebefaf3c5997bda3",
5
5
  "$schema_version": 1,
6
- "$published_version": "0.1.45",
6
+ "$published_version": "0.1.47",
7
7
  "$registry": "ghcr.io/pleri"
8
8
  }
package/dist/index.js CHANGED
@@ -7508,9 +7508,10 @@ import * as fs12 from "node:fs";
7508
7508
  import * as os8 from "node:os";
7509
7509
  import * as path13 from "node:path";
7510
7510
  import { globSync } from "node:fs";
7511
- function copyClaudeConfig(workspacePath, homeDir) {
7511
+ function copyClaudeConfig(workspacePath, homeDir, configCtx) {
7512
7512
  const sourceClaudeDir = path13.join(homeDir ?? os8.homedir(), ".claude");
7513
7513
  const destClaudeDir = path13.join(workspacePath, ".claude-host-config");
7514
+ void configCtx;
7514
7515
  if (!fs12.existsSync(sourceClaudeDir))
7515
7516
  return;
7516
7517
  fs12.mkdirSync(destClaudeDir, { recursive: true });
@@ -7550,6 +7551,113 @@ function copyClaudeConfig(workspacePath, homeDir) {
7550
7551
  if (fs12.existsSync(scriptsDir)) {
7551
7552
  copyDirRecursive(scriptsDir, path13.join(destClaudeDir, "scripts"));
7552
7553
  }
7554
+ applyProjectClaudeOverlay(workspacePath, destClaudeDir);
7555
+ writeStrippedMcpServersSnapshot(homeDir ?? os8.homedir(), workspacePath, destClaudeDir);
7556
+ }
7557
+ function applyProjectClaudeOverlay(workspacePath, destClaudeDir) {
7558
+ const projectClaudeDir = path13.join(workspacePath, ".claude");
7559
+ if (!fs12.existsSync(projectClaudeDir))
7560
+ return;
7561
+ const projectSettingsPath = path13.join(projectClaudeDir, "settings.json");
7562
+ const destSettingsPath = path13.join(destClaudeDir, "settings.json");
7563
+ if (fs12.existsSync(projectSettingsPath)) {
7564
+ try {
7565
+ const projectSettings = JSON.parse(fs12.readFileSync(projectSettingsPath, "utf-8"));
7566
+ delete projectSettings["hooks"];
7567
+ const existing = fs12.existsSync(destSettingsPath) ? JSON.parse(fs12.readFileSync(destSettingsPath, "utf-8")) : {};
7568
+ const merged = { ...existing, ...projectSettings, hooks: existing["hooks"] };
7569
+ fs12.writeFileSync(destSettingsPath, JSON.stringify(merged, null, 2));
7570
+ } catch {
7571
+ }
7572
+ }
7573
+ const projectClaudeMd = path13.join(projectClaudeDir, "CLAUDE.md");
7574
+ if (fs12.existsSync(projectClaudeMd)) {
7575
+ fs12.copyFileSync(projectClaudeMd, path13.join(destClaudeDir, "CLAUDE.md"));
7576
+ }
7577
+ const projectAgentsMd = path13.join(projectClaudeDir, "AGENTS.md");
7578
+ if (fs12.existsSync(projectAgentsMd)) {
7579
+ fs12.copyFileSync(projectAgentsMd, path13.join(destClaudeDir, "AGENTS.md"));
7580
+ }
7581
+ for (const subdir of ["rules", "agents", "plugins", "skills", "scripts"]) {
7582
+ const projectSubdir = path13.join(projectClaudeDir, subdir);
7583
+ if (fs12.existsSync(projectSubdir)) {
7584
+ const skip = subdir === "plugins" ? SKIP_FILES : /* @__PURE__ */ new Set();
7585
+ copyDirRecursive(projectSubdir, path13.join(destClaudeDir, subdir), 0, skip);
7586
+ }
7587
+ }
7588
+ }
7589
+ function stripMcpServers(mcpServers) {
7590
+ const out = {};
7591
+ for (const [svc, entry] of Object.entries(mcpServers)) {
7592
+ if (!entry || typeof entry !== "object")
7593
+ continue;
7594
+ const stripped = {};
7595
+ for (const [key, value] of Object.entries(entry)) {
7596
+ if (!MCP_SERVER_ALLOWLIST.has(key))
7597
+ continue;
7598
+ if (key === "args") {
7599
+ if (Array.isArray(value)) {
7600
+ stripped.args = value.filter((v) => typeof v === "string");
7601
+ }
7602
+ } else if (key === "command" && typeof value === "string") {
7603
+ stripped.command = value;
7604
+ } else if (key === "type" && typeof value === "string") {
7605
+ stripped.type = value;
7606
+ } else if (key === "url" && typeof value === "string") {
7607
+ stripped.url = value;
7608
+ }
7609
+ }
7610
+ out[svc] = stripped;
7611
+ }
7612
+ return out;
7613
+ }
7614
+ function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir) {
7615
+ const hostMcpServers = readMcpServersFromFile(path13.join(homeDir, ".claude.json"));
7616
+ const projectMcpServers = readMcpServersFromFile(path13.join(workspacePath, ".mcp.json"));
7617
+ if (Object.keys(hostMcpServers).length === 0 && Object.keys(projectMcpServers).length === 0) {
7618
+ return;
7619
+ }
7620
+ const stripped = {
7621
+ ...stripMcpServers(hostMcpServers),
7622
+ ...stripMcpServers(projectMcpServers)
7623
+ };
7624
+ const output = { mcpServers: stripped };
7625
+ fs12.writeFileSync(path13.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
7626
+ }
7627
+ function writeWorldEntitlementsJson(workspacePath, configCtx) {
7628
+ const olamDir = path13.join(workspacePath, ".olam");
7629
+ fs12.mkdirSync(olamDir, { recursive: true });
7630
+ const resolvedRepos = configCtx.repos.map((repo) => {
7631
+ const repoEntitlement = repo;
7632
+ return {
7633
+ name: repo.name,
7634
+ entitled_mcps: repoEntitlement.entitled_mcps !== void 0 ? repoEntitlement.entitled_mcps : configCtx.worlds_default.entitled_mcps,
7635
+ agent_teams_enabled: repoEntitlement.agent_teams_enabled !== void 0 ? repoEntitlement.agent_teams_enabled : configCtx.worlds_default.agent_teams_enabled
7636
+ };
7637
+ });
7638
+ const resolved = {
7639
+ multi_tenant: configCtx.multi_tenant,
7640
+ worlds_default: configCtx.worlds_default,
7641
+ repos: resolvedRepos
7642
+ };
7643
+ const filePath = path13.join(olamDir, "world-entitlements.json");
7644
+ fs12.writeFileSync(filePath, JSON.stringify(resolved, null, 2), { mode: 420 });
7645
+ }
7646
+ function readMcpServersFromFile(filePath) {
7647
+ if (!fs12.existsSync(filePath))
7648
+ return {};
7649
+ try {
7650
+ const raw = fs12.readFileSync(filePath, "utf-8");
7651
+ if (!raw.trim())
7652
+ return {};
7653
+ const parsed = JSON.parse(raw);
7654
+ const mcpServers = parsed["mcpServers"];
7655
+ if (!mcpServers || typeof mcpServers !== "object")
7656
+ return {};
7657
+ return mcpServers;
7658
+ } catch {
7659
+ return {};
7660
+ }
7553
7661
  }
7554
7662
  function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new Set()) {
7555
7663
  if (depth > 10)
@@ -7710,11 +7818,17 @@ function buildRepoEnvBundle(repoName, serviceEnv, crossRepoEnv, envOverrides) {
7710
7818
  const merged = { ...serviceEnv, ...injectables };
7711
7819
  return { merged, injectables };
7712
7820
  }
7713
- function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}) {
7821
+ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, configCtx) {
7714
7822
  try {
7715
- copyClaudeConfig(workspacePath);
7823
+ copyClaudeConfig(workspacePath, void 0, configCtx);
7716
7824
  } catch {
7717
7825
  }
7826
+ if (configCtx) {
7827
+ try {
7828
+ writeWorldEntitlementsJson(workspacePath, configCtx);
7829
+ } catch {
7830
+ }
7831
+ }
7718
7832
  for (const repo of repos) {
7719
7833
  const worktreePath = path13.join(workspacePath, repo.name);
7720
7834
  const sourcePath = repo.path;
@@ -7798,11 +7912,17 @@ function applyEnvOverrides(repoPath, overrides) {
7798
7912
  }
7799
7913
  }
7800
7914
  }
7801
- var SKIP_FILES, DENY_PATTERNS, SKIP_DIRS, PROTECTED_ENV_KEYS, PROTECTED_ENV_KEY_SET, ENV_KEY_PATTERN, ENV_VALUE_FORBIDDEN;
7915
+ var MCP_SERVER_ALLOWLIST, SKIP_FILES, DENY_PATTERNS, SKIP_DIRS, PROTECTED_ENV_KEYS, PROTECTED_ENV_KEY_SET, ENV_KEY_PATTERN, ENV_VALUE_FORBIDDEN;
7802
7916
  var init_env_setup = __esm({
7803
7917
  "../core/dist/world/env-setup.js"() {
7804
7918
  "use strict";
7805
7919
  init_hooks_config();
7920
+ MCP_SERVER_ALLOWLIST = /* @__PURE__ */ new Set([
7921
+ "command",
7922
+ "args",
7923
+ "type",
7924
+ "url"
7925
+ ]);
7806
7926
  SKIP_FILES = /* @__PURE__ */ new Set([
7807
7927
  ".credentials.json",
7808
7928
  "credentials.json",
@@ -7820,7 +7940,9 @@ var init_env_setup = __esm({
7820
7940
  "sessions",
7821
7941
  "projects",
7822
7942
  "cache",
7823
- "backups"
7943
+ "backups",
7944
+ "teams",
7945
+ "tasks"
7824
7946
  ]);
7825
7947
  PROTECTED_ENV_KEYS = [
7826
7948
  // Discrete host vars
@@ -9653,7 +9775,12 @@ var init_manager = __esm({
9653
9775
  }
9654
9776
  }
9655
9777
  try {
9656
- setupWorldEnv(enrichedRepos, workspacePath, serviceEnv, crossRepoEnv);
9778
+ const configCtx = {
9779
+ multi_tenant: this.config.multi_tenant,
9780
+ worlds_default: this.config.worlds_default,
9781
+ repos: enrichedRepos
9782
+ };
9783
+ setupWorldEnv(enrichedRepos, workspacePath, serviceEnv, crossRepoEnv, configCtx);
9657
9784
  } catch (err) {
9658
9785
  const msg = err instanceof Error ? err.message : String(err);
9659
9786
  console.warn(`[WorldManager] env setup failed: ${msg}`);
@@ -25062,9 +25062,10 @@ function generateHooksConfig(hookServerUrl = DEFAULT_HOOK_SERVER_URL) {
25062
25062
  }
25063
25063
 
25064
25064
  // ../core/dist/world/env-setup.js
25065
- function copyClaudeConfig(workspacePath, homeDir) {
25065
+ function copyClaudeConfig(workspacePath, homeDir, configCtx) {
25066
25066
  const sourceClaudeDir = path9.join(homeDir ?? os6.homedir(), ".claude");
25067
25067
  const destClaudeDir = path9.join(workspacePath, ".claude-host-config");
25068
+ void configCtx;
25068
25069
  if (!fs6.existsSync(sourceClaudeDir))
25069
25070
  return;
25070
25071
  fs6.mkdirSync(destClaudeDir, { recursive: true });
@@ -25104,6 +25105,119 @@ function copyClaudeConfig(workspacePath, homeDir) {
25104
25105
  if (fs6.existsSync(scriptsDir)) {
25105
25106
  copyDirRecursive(scriptsDir, path9.join(destClaudeDir, "scripts"));
25106
25107
  }
25108
+ applyProjectClaudeOverlay(workspacePath, destClaudeDir);
25109
+ writeStrippedMcpServersSnapshot(homeDir ?? os6.homedir(), workspacePath, destClaudeDir);
25110
+ }
25111
+ function applyProjectClaudeOverlay(workspacePath, destClaudeDir) {
25112
+ const projectClaudeDir = path9.join(workspacePath, ".claude");
25113
+ if (!fs6.existsSync(projectClaudeDir))
25114
+ return;
25115
+ const projectSettingsPath = path9.join(projectClaudeDir, "settings.json");
25116
+ const destSettingsPath = path9.join(destClaudeDir, "settings.json");
25117
+ if (fs6.existsSync(projectSettingsPath)) {
25118
+ try {
25119
+ const projectSettings = JSON.parse(fs6.readFileSync(projectSettingsPath, "utf-8"));
25120
+ delete projectSettings["hooks"];
25121
+ const existing = fs6.existsSync(destSettingsPath) ? JSON.parse(fs6.readFileSync(destSettingsPath, "utf-8")) : {};
25122
+ const merged = { ...existing, ...projectSettings, hooks: existing["hooks"] };
25123
+ fs6.writeFileSync(destSettingsPath, JSON.stringify(merged, null, 2));
25124
+ } catch {
25125
+ }
25126
+ }
25127
+ const projectClaudeMd = path9.join(projectClaudeDir, "CLAUDE.md");
25128
+ if (fs6.existsSync(projectClaudeMd)) {
25129
+ fs6.copyFileSync(projectClaudeMd, path9.join(destClaudeDir, "CLAUDE.md"));
25130
+ }
25131
+ const projectAgentsMd = path9.join(projectClaudeDir, "AGENTS.md");
25132
+ if (fs6.existsSync(projectAgentsMd)) {
25133
+ fs6.copyFileSync(projectAgentsMd, path9.join(destClaudeDir, "AGENTS.md"));
25134
+ }
25135
+ for (const subdir of ["rules", "agents", "plugins", "skills", "scripts"]) {
25136
+ const projectSubdir = path9.join(projectClaudeDir, subdir);
25137
+ if (fs6.existsSync(projectSubdir)) {
25138
+ const skip = subdir === "plugins" ? SKIP_FILES : /* @__PURE__ */ new Set();
25139
+ copyDirRecursive(projectSubdir, path9.join(destClaudeDir, subdir), 0, skip);
25140
+ }
25141
+ }
25142
+ }
25143
+ var MCP_SERVER_ALLOWLIST = /* @__PURE__ */ new Set([
25144
+ "command",
25145
+ "args",
25146
+ "type",
25147
+ "url"
25148
+ ]);
25149
+ function stripMcpServers(mcpServers) {
25150
+ const out = {};
25151
+ for (const [svc, entry] of Object.entries(mcpServers)) {
25152
+ if (!entry || typeof entry !== "object")
25153
+ continue;
25154
+ const stripped = {};
25155
+ for (const [key, value] of Object.entries(entry)) {
25156
+ if (!MCP_SERVER_ALLOWLIST.has(key))
25157
+ continue;
25158
+ if (key === "args") {
25159
+ if (Array.isArray(value)) {
25160
+ stripped.args = value.filter((v) => typeof v === "string");
25161
+ }
25162
+ } else if (key === "command" && typeof value === "string") {
25163
+ stripped.command = value;
25164
+ } else if (key === "type" && typeof value === "string") {
25165
+ stripped.type = value;
25166
+ } else if (key === "url" && typeof value === "string") {
25167
+ stripped.url = value;
25168
+ }
25169
+ }
25170
+ out[svc] = stripped;
25171
+ }
25172
+ return out;
25173
+ }
25174
+ function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir) {
25175
+ const hostMcpServers = readMcpServersFromFile(path9.join(homeDir, ".claude.json"));
25176
+ const projectMcpServers = readMcpServersFromFile(path9.join(workspacePath, ".mcp.json"));
25177
+ if (Object.keys(hostMcpServers).length === 0 && Object.keys(projectMcpServers).length === 0) {
25178
+ return;
25179
+ }
25180
+ const stripped = {
25181
+ ...stripMcpServers(hostMcpServers),
25182
+ ...stripMcpServers(projectMcpServers)
25183
+ };
25184
+ const output = { mcpServers: stripped };
25185
+ fs6.writeFileSync(path9.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
25186
+ }
25187
+ function writeWorldEntitlementsJson(workspacePath, configCtx) {
25188
+ const olamDir = path9.join(workspacePath, ".olam");
25189
+ fs6.mkdirSync(olamDir, { recursive: true });
25190
+ const resolvedRepos = configCtx.repos.map((repo) => {
25191
+ const repoEntitlement = repo;
25192
+ return {
25193
+ name: repo.name,
25194
+ entitled_mcps: repoEntitlement.entitled_mcps !== void 0 ? repoEntitlement.entitled_mcps : configCtx.worlds_default.entitled_mcps,
25195
+ agent_teams_enabled: repoEntitlement.agent_teams_enabled !== void 0 ? repoEntitlement.agent_teams_enabled : configCtx.worlds_default.agent_teams_enabled
25196
+ };
25197
+ });
25198
+ const resolved = {
25199
+ multi_tenant: configCtx.multi_tenant,
25200
+ worlds_default: configCtx.worlds_default,
25201
+ repos: resolvedRepos
25202
+ };
25203
+ const filePath = path9.join(olamDir, "world-entitlements.json");
25204
+ fs6.writeFileSync(filePath, JSON.stringify(resolved, null, 2), { mode: 420 });
25205
+ }
25206
+ function readMcpServersFromFile(filePath) {
25207
+ if (!fs6.existsSync(filePath))
25208
+ return {};
25209
+ try {
25210
+ const raw = fs6.readFileSync(filePath, "utf-8");
25211
+ if (!raw.trim())
25212
+ return {};
25213
+ const parsed = JSON.parse(raw);
25214
+ const mcpServers = parsed["mcpServers"];
25215
+ if (!mcpServers || typeof mcpServers !== "object")
25216
+ return {};
25217
+ return mcpServers;
25218
+ } catch {
25219
+ return {};
25220
+ }
25107
25221
  }
25108
25222
  var SKIP_FILES = /* @__PURE__ */ new Set([
25109
25223
  ".credentials.json",
@@ -25122,7 +25236,9 @@ var SKIP_DIRS = /* @__PURE__ */ new Set([
25122
25236
  "sessions",
25123
25237
  "projects",
25124
25238
  "cache",
25125
- "backups"
25239
+ "backups",
25240
+ "teams",
25241
+ "tasks"
25126
25242
  ]);
25127
25243
  function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new Set()) {
25128
25244
  if (depth > 10)
@@ -25314,11 +25430,17 @@ function buildRepoEnvBundle(repoName, serviceEnv, crossRepoEnv, envOverrides) {
25314
25430
  const merged = { ...serviceEnv, ...injectables };
25315
25431
  return { merged, injectables };
25316
25432
  }
25317
- function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}) {
25433
+ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, configCtx) {
25318
25434
  try {
25319
- copyClaudeConfig(workspacePath);
25435
+ copyClaudeConfig(workspacePath, void 0, configCtx);
25320
25436
  } catch {
25321
25437
  }
25438
+ if (configCtx) {
25439
+ try {
25440
+ writeWorldEntitlementsJson(workspacePath, configCtx);
25441
+ } catch {
25442
+ }
25443
+ }
25322
25444
  for (const repo of repos) {
25323
25445
  const worktreePath = path9.join(workspacePath, repo.name);
25324
25446
  const sourcePath = repo.path;
@@ -30387,7 +30509,12 @@ var WorldManager = class {
30387
30509
  }
30388
30510
  }
30389
30511
  try {
30390
- setupWorldEnv(enrichedRepos, workspacePath, serviceEnv, crossRepoEnv);
30512
+ const configCtx = {
30513
+ multi_tenant: this.config.multi_tenant,
30514
+ worlds_default: this.config.worlds_default,
30515
+ repos: enrichedRepos
30516
+ };
30517
+ setupWorldEnv(enrichedRepos, workspacePath, serviceEnv, crossRepoEnv, configCtx);
30391
30518
  } catch (err) {
30392
30519
  const msg = err instanceof Error ? err.message : String(err);
30393
30520
  console.warn(`[WorldManager] env setup failed: ${msg}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pleri/olam-cli",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "olam": "./bin/olam.cjs"