@pleri/olam-cli 0.1.68 → 0.1.70
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/dist/__tests__/audit-publish-deps-contract.test.d.ts +26 -0
- package/dist/__tests__/audit-publish-deps-contract.test.d.ts.map +1 -0
- package/dist/__tests__/audit-publish-deps-contract.test.js +86 -0
- package/dist/__tests__/audit-publish-deps-contract.test.js.map +1 -0
- package/dist/__tests__/host-cp-gh-token.test.js +18 -8
- package/dist/__tests__/host-cp-gh-token.test.js.map +1 -1
- package/dist/__tests__/host-cp.test.js +13 -5
- package/dist/__tests__/host-cp.test.js.map +1 -1
- package/dist/cli-version.d.ts +16 -0
- package/dist/cli-version.d.ts.map +1 -0
- package/dist/cli-version.js +39 -0
- package/dist/cli-version.js.map +1 -0
- package/dist/commands/host-cp.d.ts.map +1 -1
- package/dist/commands/host-cp.js +10 -0
- package/dist/commands/host-cp.js.map +1 -1
- package/dist/image-digests.json +5 -5
- package/dist/index.js +609 -596
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +301 -164
- package/host-cp/compose.yaml +6 -0
- package/host-cp/src/listening-server-poller.mjs +141 -0
- package/host-cp/src/port-bridge-manager.mjs +290 -0
- package/host-cp/src/server.mjs +48 -94
- package/host-cp/src/version-status.mjs +36 -0
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -15,6 +15,33 @@ var __export = (target, all) => {
|
|
|
15
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
// src/cli-version.ts
|
|
19
|
+
import * as fs from "node:fs";
|
|
20
|
+
import * as path from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
function readCliVersion() {
|
|
23
|
+
try {
|
|
24
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
for (const candidate of [
|
|
26
|
+
path.join(here, "package.json"),
|
|
27
|
+
path.join(here, "..", "package.json"),
|
|
28
|
+
path.join(here, "..", "..", "package.json")
|
|
29
|
+
]) {
|
|
30
|
+
if (fs.existsSync(candidate)) {
|
|
31
|
+
const pkg = JSON.parse(fs.readFileSync(candidate, "utf-8"));
|
|
32
|
+
if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
return "0.0.0-unknown";
|
|
38
|
+
}
|
|
39
|
+
var init_cli_version = __esm({
|
|
40
|
+
"src/cli-version.ts"() {
|
|
41
|
+
"use strict";
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
18
45
|
// src/output.ts
|
|
19
46
|
import pc from "picocolors";
|
|
20
47
|
function printError(message) {
|
|
@@ -4248,8 +4275,8 @@ var init_version2 = __esm({
|
|
|
4248
4275
|
});
|
|
4249
4276
|
|
|
4250
4277
|
// ../core/dist/world/repo-manifest.js
|
|
4251
|
-
import { existsSync, lstatSync, readFileSync } from "node:fs";
|
|
4252
|
-
import { join } from "node:path";
|
|
4278
|
+
import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2 } from "node:fs";
|
|
4279
|
+
import { join as join2 } from "node:path";
|
|
4253
4280
|
import YAML from "yaml";
|
|
4254
4281
|
function bootstrapStepCmd(entry) {
|
|
4255
4282
|
return typeof entry === "string" ? entry : entry.cmd;
|
|
@@ -4296,14 +4323,14 @@ function unknownTopLevelKeys(parsed) {
|
|
|
4296
4323
|
return Object.keys(parsed).filter((k) => !KNOWN_TOP_LEVEL_KEYS.has(k));
|
|
4297
4324
|
}
|
|
4298
4325
|
function loadRepoManifest(repoDir) {
|
|
4299
|
-
const olamPath =
|
|
4300
|
-
const adbPath =
|
|
4326
|
+
const olamPath = join2(repoDir, ".olam.yaml");
|
|
4327
|
+
const adbPath = join2(repoDir, ".adb.yaml");
|
|
4301
4328
|
let manifestPath2;
|
|
4302
4329
|
let source;
|
|
4303
|
-
if (
|
|
4330
|
+
if (existsSync2(olamPath)) {
|
|
4304
4331
|
manifestPath2 = olamPath;
|
|
4305
4332
|
source = "olam";
|
|
4306
|
-
} else if (
|
|
4333
|
+
} else if (existsSync2(adbPath)) {
|
|
4307
4334
|
manifestPath2 = adbPath;
|
|
4308
4335
|
source = "adb";
|
|
4309
4336
|
} else {
|
|
@@ -4313,10 +4340,10 @@ function loadRepoManifest(repoDir) {
|
|
|
4313
4340
|
if (stat.isSymbolicLink()) {
|
|
4314
4341
|
throw new Error(`[manifest] ${manifestPath2}: symbolic links are not permitted`);
|
|
4315
4342
|
}
|
|
4316
|
-
const raw =
|
|
4343
|
+
const raw = readFileSync2(manifestPath2, "utf-8");
|
|
4317
4344
|
const parsed = YAML.parse(raw, { maxAliasCount: 100 });
|
|
4318
4345
|
if (parsed === null || parsed === void 0) {
|
|
4319
|
-
if (source === "olam" &&
|
|
4346
|
+
if (source === "olam" && existsSync2(adbPath)) {
|
|
4320
4347
|
console.warn(`[manifest] ${manifestPath2}: file is empty; .adb.yaml is NOT consulted (delete .olam.yaml to fall back)`);
|
|
4321
4348
|
}
|
|
4322
4349
|
return null;
|
|
@@ -4421,12 +4448,12 @@ var init_repo_manifest = __esm({
|
|
|
4421
4448
|
|
|
4422
4449
|
// ../core/dist/util/path.js
|
|
4423
4450
|
import * as os from "node:os";
|
|
4424
|
-
import * as
|
|
4451
|
+
import * as path2 from "node:path";
|
|
4425
4452
|
function resolveTildePath(p) {
|
|
4426
4453
|
if (p === "~")
|
|
4427
4454
|
return os.homedir();
|
|
4428
4455
|
if (p.startsWith("~/"))
|
|
4429
|
-
return
|
|
4456
|
+
return path2.join(os.homedir(), p.slice(2));
|
|
4430
4457
|
if (p.startsWith("~")) {
|
|
4431
4458
|
throw new Error(`[path] POSIX "~user" syntax is not supported (got "${p}"). Use "~/..." for the operator's home or an absolute path.`);
|
|
4432
4459
|
}
|
|
@@ -4441,15 +4468,15 @@ var init_path = __esm({
|
|
|
4441
4468
|
});
|
|
4442
4469
|
|
|
4443
4470
|
// ../core/dist/workspace/store.js
|
|
4444
|
-
import * as
|
|
4471
|
+
import * as fs2 from "node:fs";
|
|
4445
4472
|
import * as os2 from "node:os";
|
|
4446
|
-
import * as
|
|
4473
|
+
import * as path3 from "node:path";
|
|
4447
4474
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
4448
4475
|
function workspacesDir() {
|
|
4449
4476
|
const override = process.env["OLAM_WORKSPACES_DIR"];
|
|
4450
4477
|
if (override && override.length > 0)
|
|
4451
4478
|
return override;
|
|
4452
|
-
return
|
|
4479
|
+
return path3.join(os2.homedir(), ".olam", "workspaces");
|
|
4453
4480
|
}
|
|
4454
4481
|
function validateName(name) {
|
|
4455
4482
|
if (!WORKSPACE_NAME_PATTERN.test(name)) {
|
|
@@ -4457,17 +4484,17 @@ function validateName(name) {
|
|
|
4457
4484
|
}
|
|
4458
4485
|
}
|
|
4459
4486
|
function filePathFor(name) {
|
|
4460
|
-
return
|
|
4487
|
+
return path3.join(workspacesDir(), `${name}.yaml`);
|
|
4461
4488
|
}
|
|
4462
4489
|
function listWorkspaces() {
|
|
4463
4490
|
const dir = workspacesDir();
|
|
4464
|
-
if (!
|
|
4491
|
+
if (!fs2.existsSync(dir))
|
|
4465
4492
|
return [];
|
|
4466
|
-
const entries =
|
|
4493
|
+
const entries = fs2.readdirSync(dir).filter((f) => f.endsWith(".yaml"));
|
|
4467
4494
|
const result = [];
|
|
4468
4495
|
for (const entry of entries) {
|
|
4469
4496
|
try {
|
|
4470
|
-
const raw =
|
|
4497
|
+
const raw = fs2.readFileSync(path3.join(dir, entry), "utf-8");
|
|
4471
4498
|
const parsed = parseYaml(raw);
|
|
4472
4499
|
const ws = WorkspaceSchema.parse(parsed);
|
|
4473
4500
|
result.push(ws);
|
|
@@ -4483,30 +4510,30 @@ function listWorkspaces() {
|
|
|
4483
4510
|
function readWorkspace(name) {
|
|
4484
4511
|
validateName(name);
|
|
4485
4512
|
const file = filePathFor(name);
|
|
4486
|
-
if (!
|
|
4513
|
+
if (!fs2.existsSync(file))
|
|
4487
4514
|
return null;
|
|
4488
|
-
const raw =
|
|
4515
|
+
const raw = fs2.readFileSync(file, "utf-8");
|
|
4489
4516
|
return WorkspaceSchema.parse(parseYaml(raw));
|
|
4490
4517
|
}
|
|
4491
4518
|
function writeWorkspace(ws, options = {}) {
|
|
4492
4519
|
validateName(ws.name);
|
|
4493
4520
|
const parsed = WorkspaceSchema.parse(ws);
|
|
4494
4521
|
const dir = workspacesDir();
|
|
4495
|
-
|
|
4522
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
4496
4523
|
const final = filePathFor(parsed.name);
|
|
4497
|
-
if (
|
|
4524
|
+
if (fs2.existsSync(final) && options.force !== true) {
|
|
4498
4525
|
throw new WorkspaceExistsError(parsed.name);
|
|
4499
4526
|
}
|
|
4500
4527
|
const tmp = `${final}.tmp-${process.pid}`;
|
|
4501
|
-
|
|
4502
|
-
|
|
4528
|
+
fs2.writeFileSync(tmp, stringifyYaml(parsed), { mode: 420 });
|
|
4529
|
+
fs2.renameSync(tmp, final);
|
|
4503
4530
|
}
|
|
4504
4531
|
function removeWorkspace(name) {
|
|
4505
4532
|
validateName(name);
|
|
4506
4533
|
const file = filePathFor(name);
|
|
4507
|
-
if (!
|
|
4534
|
+
if (!fs2.existsSync(file))
|
|
4508
4535
|
return false;
|
|
4509
|
-
|
|
4536
|
+
fs2.unlinkSync(file);
|
|
4510
4537
|
return true;
|
|
4511
4538
|
}
|
|
4512
4539
|
function workspaceToRepoConfigs(ws) {
|
|
@@ -4996,11 +5023,11 @@ var init_substitute = __esm({
|
|
|
4996
5023
|
});
|
|
4997
5024
|
|
|
4998
5025
|
// ../core/dist/config/dotenv.js
|
|
4999
|
-
import * as
|
|
5026
|
+
import * as fs3 from "node:fs";
|
|
5000
5027
|
function loadDotEnv(envPath) {
|
|
5001
|
-
if (!
|
|
5028
|
+
if (!fs3.existsSync(envPath))
|
|
5002
5029
|
return;
|
|
5003
|
-
const content =
|
|
5030
|
+
const content = fs3.readFileSync(envPath, "utf-8");
|
|
5004
5031
|
for (const line of content.split("\n")) {
|
|
5005
5032
|
const trimmed = line.trim();
|
|
5006
5033
|
if (!trimmed || trimmed.startsWith("#"))
|
|
@@ -5026,23 +5053,23 @@ var loader_exports = {};
|
|
|
5026
5053
|
__export(loader_exports, {
|
|
5027
5054
|
loadConfig: () => loadConfig
|
|
5028
5055
|
});
|
|
5029
|
-
import * as
|
|
5030
|
-
import * as
|
|
5056
|
+
import * as fs4 from "node:fs";
|
|
5057
|
+
import * as path4 from "node:path";
|
|
5031
5058
|
import { parse as parseYaml2 } from "yaml";
|
|
5032
5059
|
function findConfigFile(startDir) {
|
|
5033
5060
|
const searched = [];
|
|
5034
|
-
let current =
|
|
5061
|
+
let current = path4.resolve(startDir);
|
|
5035
5062
|
while (true) {
|
|
5036
|
-
const newLayout =
|
|
5037
|
-
const legacyLayout =
|
|
5063
|
+
const newLayout = path4.join(current, CONFIG_DIR_NAME, CONFIG_FILENAME);
|
|
5064
|
+
const legacyLayout = path4.join(current, LEGACY_CONFIG_FILENAME);
|
|
5038
5065
|
searched.push(newLayout, legacyLayout);
|
|
5039
|
-
if (
|
|
5066
|
+
if (fs4.existsSync(newLayout)) {
|
|
5040
5067
|
return { path: newLayout, isLegacy: false };
|
|
5041
5068
|
}
|
|
5042
|
-
if (
|
|
5069
|
+
if (fs4.existsSync(legacyLayout)) {
|
|
5043
5070
|
return { path: legacyLayout, isLegacy: true };
|
|
5044
5071
|
}
|
|
5045
|
-
const parent =
|
|
5072
|
+
const parent = path4.dirname(current);
|
|
5046
5073
|
if (parent === current)
|
|
5047
5074
|
break;
|
|
5048
5075
|
current = parent;
|
|
@@ -5057,12 +5084,12 @@ function loadConfig(startDir) {
|
|
|
5057
5084
|
Run /olam:init to migrate to .olam/config.yaml
|
|
5058
5085
|
`);
|
|
5059
5086
|
} else {
|
|
5060
|
-
const envPath =
|
|
5087
|
+
const envPath = path4.join(path4.dirname(found.path), ".env");
|
|
5061
5088
|
loadDotEnv(envPath);
|
|
5062
5089
|
}
|
|
5063
5090
|
let rawContent;
|
|
5064
5091
|
try {
|
|
5065
|
-
rawContent =
|
|
5092
|
+
rawContent = fs4.readFileSync(found.path, "utf-8");
|
|
5066
5093
|
} catch (err) {
|
|
5067
5094
|
throw new Error(`Failed to read ${found.path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
5068
5095
|
}
|
|
@@ -5104,27 +5131,27 @@ var init_loader = __esm({
|
|
|
5104
5131
|
|
|
5105
5132
|
// ../core/dist/auth/secret.js
|
|
5106
5133
|
import * as crypto from "node:crypto";
|
|
5107
|
-
import * as
|
|
5134
|
+
import * as fs8 from "node:fs";
|
|
5108
5135
|
import * as os4 from "node:os";
|
|
5109
|
-
import * as
|
|
5136
|
+
import * as path8 from "node:path";
|
|
5110
5137
|
function getSecretFilePath() {
|
|
5111
|
-
return
|
|
5138
|
+
return path8.join(os4.homedir(), ".olam", SECRET_FILENAME);
|
|
5112
5139
|
}
|
|
5113
5140
|
function getOrCreateSecret() {
|
|
5114
5141
|
const fromEnv = process.env[SECRET_ENV_VAR];
|
|
5115
5142
|
if (fromEnv && fromEnv.length > 0)
|
|
5116
5143
|
return fromEnv;
|
|
5117
5144
|
const file = getSecretFilePath();
|
|
5118
|
-
if (
|
|
5119
|
-
const value =
|
|
5145
|
+
if (fs8.existsSync(file)) {
|
|
5146
|
+
const value = fs8.readFileSync(file, "utf-8").trim();
|
|
5120
5147
|
if (value.length > 0)
|
|
5121
5148
|
return value;
|
|
5122
5149
|
}
|
|
5123
5150
|
const generated = crypto.randomBytes(SECRET_BYTES).toString("base64url");
|
|
5124
|
-
|
|
5125
|
-
|
|
5151
|
+
fs8.mkdirSync(path8.dirname(file), { recursive: true });
|
|
5152
|
+
fs8.writeFileSync(file, generated, { mode: 384 });
|
|
5126
5153
|
try {
|
|
5127
|
-
|
|
5154
|
+
fs8.chmodSync(file, 384);
|
|
5128
5155
|
} catch {
|
|
5129
5156
|
}
|
|
5130
5157
|
return generated;
|
|
@@ -5134,9 +5161,9 @@ function readSecretIfExists() {
|
|
|
5134
5161
|
if (fromEnv && fromEnv.length > 0)
|
|
5135
5162
|
return fromEnv;
|
|
5136
5163
|
const file = getSecretFilePath();
|
|
5137
|
-
if (!
|
|
5164
|
+
if (!fs8.existsSync(file))
|
|
5138
5165
|
return null;
|
|
5139
|
-
const value =
|
|
5166
|
+
const value = fs8.readFileSync(file, "utf-8").trim();
|
|
5140
5167
|
return value.length > 0 ? value : null;
|
|
5141
5168
|
}
|
|
5142
5169
|
var SECRET_ENV_VAR, SECRET_FILENAME, SECRET_BYTES;
|
|
@@ -5312,13 +5339,13 @@ var init_client = __esm({
|
|
|
5312
5339
|
|
|
5313
5340
|
// ../core/dist/auth/container.js
|
|
5314
5341
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
5315
|
-
import { existsSync as
|
|
5316
|
-
import * as
|
|
5317
|
-
import { fileURLToPath } from "node:url";
|
|
5342
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
5343
|
+
import * as path9 from "node:path";
|
|
5344
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5318
5345
|
function resolveAuthServicePath() {
|
|
5319
|
-
const here =
|
|
5320
|
-
const pkgsDir =
|
|
5321
|
-
return
|
|
5346
|
+
const here = fileURLToPath2(import.meta.url);
|
|
5347
|
+
const pkgsDir = path9.resolve(path9.dirname(here), "..", "..", "..");
|
|
5348
|
+
return path9.join(pkgsDir, "auth-service");
|
|
5322
5349
|
}
|
|
5323
5350
|
function sleep2(ms) {
|
|
5324
5351
|
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
@@ -5394,7 +5421,7 @@ var init_container = __esm({
|
|
|
5394
5421
|
*/
|
|
5395
5422
|
buildImage() {
|
|
5396
5423
|
const dockerfileDir = resolveAuthServicePath();
|
|
5397
|
-
if (!
|
|
5424
|
+
if (!existsSync9(path9.join(dockerfileDir, "Dockerfile"))) {
|
|
5398
5425
|
throw new Error(`auth image '${this.imageTag}' is not present locally and no Dockerfile is available at ${dockerfileDir} to build from. Run \`olam bootstrap\` to pull the published image, or check out the olam source tree.`);
|
|
5399
5426
|
}
|
|
5400
5427
|
execFileSync("docker", ["build", "--tag", this.imageTag, dockerfileDir], { stdio: "inherit" });
|
|
@@ -5627,16 +5654,16 @@ var init_volume = __esm({
|
|
|
5627
5654
|
});
|
|
5628
5655
|
|
|
5629
5656
|
// ../adapters/dist/docker/container.js
|
|
5630
|
-
import * as
|
|
5657
|
+
import * as fs10 from "node:fs";
|
|
5631
5658
|
import * as os6 from "node:os";
|
|
5632
|
-
import * as
|
|
5659
|
+
import * as path11 from "node:path";
|
|
5633
5660
|
function readAuthSecret() {
|
|
5634
5661
|
const fromEnv = process.env["OLAM_AUTH_SECRET"];
|
|
5635
5662
|
if (fromEnv && fromEnv.length > 0)
|
|
5636
5663
|
return fromEnv;
|
|
5637
|
-
const file =
|
|
5664
|
+
const file = path11.join(os6.homedir(), ".olam", "auth-secret");
|
|
5638
5665
|
try {
|
|
5639
|
-
return
|
|
5666
|
+
return fs10.readFileSync(file, "utf-8").trim();
|
|
5640
5667
|
} catch {
|
|
5641
5668
|
return "";
|
|
5642
5669
|
}
|
|
@@ -5645,9 +5672,9 @@ function readHostCpToken() {
|
|
|
5645
5672
|
const fromEnv = process.env["OLAM_HOST_CP_TOKEN"];
|
|
5646
5673
|
if (fromEnv && fromEnv.length > 0)
|
|
5647
5674
|
return fromEnv;
|
|
5648
|
-
const file =
|
|
5675
|
+
const file = path11.join(os6.homedir(), ".olam", "host-cp.token");
|
|
5649
5676
|
try {
|
|
5650
|
-
return
|
|
5677
|
+
return fs10.readFileSync(file, "utf-8").trim();
|
|
5651
5678
|
} catch {
|
|
5652
5679
|
return "";
|
|
5653
5680
|
}
|
|
@@ -5658,11 +5685,11 @@ function sanitizeContainerName(name) {
|
|
|
5658
5685
|
function buildPackageManagerCacheBinds(homeDir) {
|
|
5659
5686
|
const result = [];
|
|
5660
5687
|
for (const entry of PACKAGE_MANAGER_CACHE_DIRS) {
|
|
5661
|
-
const hostPath =
|
|
5688
|
+
const hostPath = path11.join(homeDir, entry.hostSubpath);
|
|
5662
5689
|
try {
|
|
5663
|
-
|
|
5690
|
+
fs10.mkdirSync(hostPath, { recursive: true, mode: 448 });
|
|
5664
5691
|
try {
|
|
5665
|
-
|
|
5692
|
+
fs10.chmodSync(hostPath, 448);
|
|
5666
5693
|
} catch {
|
|
5667
5694
|
}
|
|
5668
5695
|
result.push(`${hostPath}:${entry.containerPath}:rw`);
|
|
@@ -5814,12 +5841,12 @@ var init_container2 = __esm({
|
|
|
5814
5841
|
if (workspacePath) {
|
|
5815
5842
|
binds.push(`${workspacePath}:/home/olam/workspace:rw`);
|
|
5816
5843
|
}
|
|
5817
|
-
const r2CredHostPath =
|
|
5818
|
-
if (
|
|
5844
|
+
const r2CredHostPath = path11.join(olamHomeDir, ".olam", "r2-credentials.json");
|
|
5845
|
+
if (fs10.existsSync(r2CredHostPath)) {
|
|
5819
5846
|
binds.push(`${r2CredHostPath}:/etc/olam/r2-credentials.json:ro`);
|
|
5820
5847
|
}
|
|
5821
|
-
const gcloudCredsDir =
|
|
5822
|
-
if (
|
|
5848
|
+
const gcloudCredsDir = path11.join(olamHomeDir, ".config", "gcloud");
|
|
5849
|
+
if (fs10.existsSync(gcloudCredsDir)) {
|
|
5823
5850
|
binds.push(`${gcloudCredsDir}:/home/olam/.config/gcloud:ro`);
|
|
5824
5851
|
}
|
|
5825
5852
|
const hostControlPlanePort = HOST_CONTROL_PLANE_BASE + (portOffset ?? 0);
|
|
@@ -6254,7 +6281,7 @@ var init_cleanup = __esm({
|
|
|
6254
6281
|
|
|
6255
6282
|
// ../adapters/dist/ssh/connection.js
|
|
6256
6283
|
import { Client as SSHClient } from "ssh2";
|
|
6257
|
-
import { readFileSync as
|
|
6284
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
6258
6285
|
var SSHConnectionPool;
|
|
6259
6286
|
var init_connection = __esm({
|
|
6260
6287
|
"../adapters/dist/ssh/connection.js"() {
|
|
@@ -6349,7 +6376,7 @@ var init_connection = __esm({
|
|
|
6349
6376
|
host: config.host,
|
|
6350
6377
|
port: config.port ?? 22,
|
|
6351
6378
|
username: config.user,
|
|
6352
|
-
...config.key ? { privateKey:
|
|
6379
|
+
...config.key ? { privateKey: readFileSync10(config.key) } : {},
|
|
6353
6380
|
...config.password ? { password: config.password } : {}
|
|
6354
6381
|
});
|
|
6355
6382
|
});
|
|
@@ -7058,8 +7085,8 @@ __export(registry_exports, {
|
|
|
7058
7085
|
import { createRequire } from "node:module";
|
|
7059
7086
|
import * as net from "node:net";
|
|
7060
7087
|
import * as os7 from "node:os";
|
|
7061
|
-
import * as
|
|
7062
|
-
import * as
|
|
7088
|
+
import * as path12 from "node:path";
|
|
7089
|
+
import * as fs11 from "node:fs";
|
|
7063
7090
|
function getDatabase() {
|
|
7064
7091
|
if (_Database === null) {
|
|
7065
7092
|
_Database = _require("better-sqlite3");
|
|
@@ -7165,9 +7192,9 @@ CREATE TABLE IF NOT EXISTS meta (
|
|
|
7165
7192
|
WorldRegistry = class {
|
|
7166
7193
|
db;
|
|
7167
7194
|
constructor(dbPath) {
|
|
7168
|
-
const resolvedPath = dbPath ??
|
|
7195
|
+
const resolvedPath = dbPath ?? path12.join(os7.homedir(), ".olam", "worlds.db");
|
|
7169
7196
|
if (resolvedPath !== ":memory:") {
|
|
7170
|
-
|
|
7197
|
+
fs11.mkdirSync(path12.dirname(resolvedPath), { recursive: true });
|
|
7171
7198
|
}
|
|
7172
7199
|
const Database = getDatabase();
|
|
7173
7200
|
this.db = new Database(resolvedPath);
|
|
@@ -7354,8 +7381,8 @@ var init_devbox_image = __esm({
|
|
|
7354
7381
|
|
|
7355
7382
|
// ../core/dist/world/worktree.js
|
|
7356
7383
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
7357
|
-
import * as
|
|
7358
|
-
import * as
|
|
7384
|
+
import * as fs12 from "node:fs";
|
|
7385
|
+
import * as path13 from "node:path";
|
|
7359
7386
|
function resolveGitDir(repo) {
|
|
7360
7387
|
if (repo.path) {
|
|
7361
7388
|
return repo.path;
|
|
@@ -7365,11 +7392,11 @@ function resolveGitDir(repo) {
|
|
|
7365
7392
|
async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
7366
7393
|
const created = [];
|
|
7367
7394
|
for (const repo of repos) {
|
|
7368
|
-
const worktreePath =
|
|
7395
|
+
const worktreePath = path13.join(workspacePath, repo.name);
|
|
7369
7396
|
const gitDir = resolveGitDir(repo);
|
|
7370
7397
|
const branchName = branch || `olam/${worldId}`;
|
|
7371
7398
|
try {
|
|
7372
|
-
|
|
7399
|
+
fs12.mkdirSync(path13.dirname(worktreePath), { recursive: true });
|
|
7373
7400
|
execFileSync2("git", ["worktree", "add", worktreePath, "-b", branchName], {
|
|
7374
7401
|
cwd: gitDir,
|
|
7375
7402
|
stdio: "pipe"
|
|
@@ -7402,7 +7429,7 @@ async function createWorktrees(repos, worldId, workspacePath, branch) {
|
|
|
7402
7429
|
}
|
|
7403
7430
|
async function removeWorktrees(repos, workspacePath) {
|
|
7404
7431
|
for (const repo of repos) {
|
|
7405
|
-
const worktreePath =
|
|
7432
|
+
const worktreePath = path13.join(workspacePath, repo.name);
|
|
7406
7433
|
let gitDir;
|
|
7407
7434
|
try {
|
|
7408
7435
|
gitDir = resolveGitDir(repo);
|
|
@@ -7571,85 +7598,85 @@ var init_hooks_config = __esm({
|
|
|
7571
7598
|
|
|
7572
7599
|
// ../core/dist/world/env-setup.js
|
|
7573
7600
|
import * as crypto2 from "node:crypto";
|
|
7574
|
-
import * as
|
|
7601
|
+
import * as fs13 from "node:fs";
|
|
7575
7602
|
import * as os8 from "node:os";
|
|
7576
|
-
import * as
|
|
7603
|
+
import * as path14 from "node:path";
|
|
7577
7604
|
import { globSync } from "node:fs";
|
|
7578
7605
|
function copyClaudeConfig(workspacePath, homeDir, configCtx) {
|
|
7579
|
-
const sourceClaudeDir =
|
|
7580
|
-
const destClaudeDir =
|
|
7606
|
+
const sourceClaudeDir = path14.join(homeDir ?? os8.homedir(), ".claude");
|
|
7607
|
+
const destClaudeDir = path14.join(workspacePath, ".claude-host-config");
|
|
7581
7608
|
void configCtx;
|
|
7582
|
-
if (!
|
|
7609
|
+
if (!fs13.existsSync(sourceClaudeDir))
|
|
7583
7610
|
return;
|
|
7584
|
-
|
|
7585
|
-
const settingsPath =
|
|
7611
|
+
fs13.mkdirSync(destClaudeDir, { recursive: true });
|
|
7612
|
+
const settingsPath = path14.join(sourceClaudeDir, "settings.json");
|
|
7586
7613
|
let settings = {};
|
|
7587
|
-
if (
|
|
7614
|
+
if (fs13.existsSync(settingsPath)) {
|
|
7588
7615
|
try {
|
|
7589
|
-
settings = JSON.parse(
|
|
7616
|
+
settings = JSON.parse(fs13.readFileSync(settingsPath, "utf-8"));
|
|
7590
7617
|
delete settings["hooks"];
|
|
7591
7618
|
} catch {
|
|
7592
7619
|
}
|
|
7593
7620
|
}
|
|
7594
7621
|
const hooksConfig = generateHooksConfig(DEFAULT_HOOK_SERVER_URL);
|
|
7595
7622
|
settings["hooks"] = hooksConfig["hooks"];
|
|
7596
|
-
|
|
7597
|
-
const claudeMdPath =
|
|
7598
|
-
if (
|
|
7599
|
-
|
|
7623
|
+
fs13.writeFileSync(path14.join(destClaudeDir, "settings.json"), JSON.stringify(settings, null, 2));
|
|
7624
|
+
const claudeMdPath = path14.join(sourceClaudeDir, "CLAUDE.md");
|
|
7625
|
+
if (fs13.existsSync(claudeMdPath)) {
|
|
7626
|
+
fs13.copyFileSync(claudeMdPath, path14.join(destClaudeDir, "CLAUDE.md"));
|
|
7600
7627
|
}
|
|
7601
|
-
const rulesDir =
|
|
7602
|
-
if (
|
|
7603
|
-
copyDirRecursive(rulesDir,
|
|
7628
|
+
const rulesDir = path14.join(sourceClaudeDir, "rules");
|
|
7629
|
+
if (fs13.existsSync(rulesDir)) {
|
|
7630
|
+
copyDirRecursive(rulesDir, path14.join(destClaudeDir, "rules"));
|
|
7604
7631
|
}
|
|
7605
|
-
const agentsDir =
|
|
7606
|
-
if (
|
|
7607
|
-
copyDirRecursive(agentsDir,
|
|
7632
|
+
const agentsDir = path14.join(sourceClaudeDir, "agents");
|
|
7633
|
+
if (fs13.existsSync(agentsDir)) {
|
|
7634
|
+
copyDirRecursive(agentsDir, path14.join(destClaudeDir, "agents"));
|
|
7608
7635
|
}
|
|
7609
|
-
const pluginsDir =
|
|
7610
|
-
if (
|
|
7611
|
-
copyDirRecursive(pluginsDir,
|
|
7636
|
+
const pluginsDir = path14.join(sourceClaudeDir, "plugins");
|
|
7637
|
+
if (fs13.existsSync(pluginsDir)) {
|
|
7638
|
+
copyDirRecursive(pluginsDir, path14.join(destClaudeDir, "plugins"), 0, SKIP_FILES);
|
|
7612
7639
|
}
|
|
7613
|
-
const skillsDir =
|
|
7614
|
-
if (
|
|
7615
|
-
copyDirRecursive(skillsDir,
|
|
7640
|
+
const skillsDir = path14.join(sourceClaudeDir, "skills");
|
|
7641
|
+
if (fs13.existsSync(skillsDir)) {
|
|
7642
|
+
copyDirRecursive(skillsDir, path14.join(destClaudeDir, "skills"));
|
|
7616
7643
|
}
|
|
7617
|
-
const scriptsDir =
|
|
7618
|
-
if (
|
|
7619
|
-
copyDirRecursive(scriptsDir,
|
|
7644
|
+
const scriptsDir = path14.join(sourceClaudeDir, "scripts");
|
|
7645
|
+
if (fs13.existsSync(scriptsDir)) {
|
|
7646
|
+
copyDirRecursive(scriptsDir, path14.join(destClaudeDir, "scripts"));
|
|
7620
7647
|
}
|
|
7621
7648
|
applyProjectClaudeOverlay(workspacePath, destClaudeDir);
|
|
7622
7649
|
writeStrippedMcpServersSnapshot(homeDir ?? os8.homedir(), workspacePath, destClaudeDir);
|
|
7623
7650
|
}
|
|
7624
7651
|
function applyProjectClaudeOverlay(workspacePath, destClaudeDir) {
|
|
7625
|
-
const projectClaudeDir =
|
|
7626
|
-
if (!
|
|
7652
|
+
const projectClaudeDir = path14.join(workspacePath, ".claude");
|
|
7653
|
+
if (!fs13.existsSync(projectClaudeDir))
|
|
7627
7654
|
return;
|
|
7628
|
-
const projectSettingsPath =
|
|
7629
|
-
const destSettingsPath =
|
|
7630
|
-
if (
|
|
7655
|
+
const projectSettingsPath = path14.join(projectClaudeDir, "settings.json");
|
|
7656
|
+
const destSettingsPath = path14.join(destClaudeDir, "settings.json");
|
|
7657
|
+
if (fs13.existsSync(projectSettingsPath)) {
|
|
7631
7658
|
try {
|
|
7632
|
-
const projectSettings = JSON.parse(
|
|
7659
|
+
const projectSettings = JSON.parse(fs13.readFileSync(projectSettingsPath, "utf-8"));
|
|
7633
7660
|
delete projectSettings["hooks"];
|
|
7634
|
-
const existing =
|
|
7661
|
+
const existing = fs13.existsSync(destSettingsPath) ? JSON.parse(fs13.readFileSync(destSettingsPath, "utf-8")) : {};
|
|
7635
7662
|
const merged = { ...existing, ...projectSettings, hooks: existing["hooks"] };
|
|
7636
|
-
|
|
7663
|
+
fs13.writeFileSync(destSettingsPath, JSON.stringify(merged, null, 2));
|
|
7637
7664
|
} catch {
|
|
7638
7665
|
}
|
|
7639
7666
|
}
|
|
7640
|
-
const projectClaudeMd =
|
|
7641
|
-
if (
|
|
7642
|
-
|
|
7667
|
+
const projectClaudeMd = path14.join(projectClaudeDir, "CLAUDE.md");
|
|
7668
|
+
if (fs13.existsSync(projectClaudeMd)) {
|
|
7669
|
+
fs13.copyFileSync(projectClaudeMd, path14.join(destClaudeDir, "CLAUDE.md"));
|
|
7643
7670
|
}
|
|
7644
|
-
const projectAgentsMd =
|
|
7645
|
-
if (
|
|
7646
|
-
|
|
7671
|
+
const projectAgentsMd = path14.join(projectClaudeDir, "AGENTS.md");
|
|
7672
|
+
if (fs13.existsSync(projectAgentsMd)) {
|
|
7673
|
+
fs13.copyFileSync(projectAgentsMd, path14.join(destClaudeDir, "AGENTS.md"));
|
|
7647
7674
|
}
|
|
7648
7675
|
for (const subdir of ["rules", "agents", "plugins", "skills", "scripts"]) {
|
|
7649
|
-
const projectSubdir =
|
|
7650
|
-
if (
|
|
7676
|
+
const projectSubdir = path14.join(projectClaudeDir, subdir);
|
|
7677
|
+
if (fs13.existsSync(projectSubdir)) {
|
|
7651
7678
|
const skip = subdir === "plugins" ? SKIP_FILES : /* @__PURE__ */ new Set();
|
|
7652
|
-
copyDirRecursive(projectSubdir,
|
|
7679
|
+
copyDirRecursive(projectSubdir, path14.join(destClaudeDir, subdir), 0, skip);
|
|
7653
7680
|
}
|
|
7654
7681
|
}
|
|
7655
7682
|
}
|
|
@@ -7679,8 +7706,8 @@ function stripMcpServers(mcpServers) {
|
|
|
7679
7706
|
return out;
|
|
7680
7707
|
}
|
|
7681
7708
|
function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir) {
|
|
7682
|
-
const hostMcpServers = readMcpServersFromFile(
|
|
7683
|
-
const projectMcpServers = readMcpServersFromFile(
|
|
7709
|
+
const hostMcpServers = readMcpServersFromFile(path14.join(homeDir, ".claude.json"));
|
|
7710
|
+
const projectMcpServers = readMcpServersFromFile(path14.join(workspacePath, ".mcp.json"));
|
|
7684
7711
|
if (Object.keys(hostMcpServers).length === 0 && Object.keys(projectMcpServers).length === 0) {
|
|
7685
7712
|
return;
|
|
7686
7713
|
}
|
|
@@ -7689,11 +7716,11 @@ function writeStrippedMcpServersSnapshot(homeDir, workspacePath, destClaudeDir)
|
|
|
7689
7716
|
...stripMcpServers(projectMcpServers)
|
|
7690
7717
|
};
|
|
7691
7718
|
const output = { mcpServers: stripped };
|
|
7692
|
-
|
|
7719
|
+
fs13.writeFileSync(path14.join(destClaudeDir, ".claude.json"), JSON.stringify(output, null, 2), { mode: 384 });
|
|
7693
7720
|
}
|
|
7694
7721
|
function writeWorldEntitlementsJson(workspacePath, configCtx) {
|
|
7695
|
-
const olamDir =
|
|
7696
|
-
|
|
7722
|
+
const olamDir = path14.join(workspacePath, ".olam");
|
|
7723
|
+
fs13.mkdirSync(olamDir, { recursive: true });
|
|
7697
7724
|
const resolvedRepos = configCtx.repos.map((repo) => {
|
|
7698
7725
|
const repoEntitlement = repo;
|
|
7699
7726
|
return {
|
|
@@ -7707,14 +7734,14 @@ function writeWorldEntitlementsJson(workspacePath, configCtx) {
|
|
|
7707
7734
|
worlds_default: configCtx.worlds_default,
|
|
7708
7735
|
repos: resolvedRepos
|
|
7709
7736
|
};
|
|
7710
|
-
const filePath =
|
|
7711
|
-
|
|
7737
|
+
const filePath = path14.join(olamDir, "world-entitlements.json");
|
|
7738
|
+
fs13.writeFileSync(filePath, JSON.stringify(resolved, null, 2), { mode: 420 });
|
|
7712
7739
|
}
|
|
7713
7740
|
function readMcpServersFromFile(filePath) {
|
|
7714
|
-
if (!
|
|
7741
|
+
if (!fs13.existsSync(filePath))
|
|
7715
7742
|
return {};
|
|
7716
7743
|
try {
|
|
7717
|
-
const raw =
|
|
7744
|
+
const raw = fs13.readFileSync(filePath, "utf-8");
|
|
7718
7745
|
if (!raw.trim())
|
|
7719
7746
|
return {};
|
|
7720
7747
|
const parsed = JSON.parse(raw);
|
|
@@ -7729,8 +7756,8 @@ function readMcpServersFromFile(filePath) {
|
|
|
7729
7756
|
function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new Set()) {
|
|
7730
7757
|
if (depth > 10)
|
|
7731
7758
|
return;
|
|
7732
|
-
|
|
7733
|
-
for (const entry of
|
|
7759
|
+
fs13.mkdirSync(dest, { recursive: true });
|
|
7760
|
+
for (const entry of fs13.readdirSync(src, { withFileTypes: true })) {
|
|
7734
7761
|
const { name } = entry;
|
|
7735
7762
|
if (skipFiles.has(name))
|
|
7736
7763
|
continue;
|
|
@@ -7740,12 +7767,12 @@ function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new
|
|
|
7740
7767
|
continue;
|
|
7741
7768
|
if (entry.isDirectory() && SKIP_DIRS_ANYWHERE.has(name))
|
|
7742
7769
|
continue;
|
|
7743
|
-
const srcPath =
|
|
7744
|
-
const destPath =
|
|
7770
|
+
const srcPath = path14.join(src, name);
|
|
7771
|
+
const destPath = path14.join(dest, name);
|
|
7745
7772
|
if (entry.isSymbolicLink()) {
|
|
7746
7773
|
let stat;
|
|
7747
7774
|
try {
|
|
7748
|
-
stat =
|
|
7775
|
+
stat = fs13.statSync(srcPath);
|
|
7749
7776
|
} catch {
|
|
7750
7777
|
continue;
|
|
7751
7778
|
}
|
|
@@ -7754,12 +7781,12 @@ function copyDirRecursive(src, dest, depth = 0, skipFiles = /* @__PURE__ */ new
|
|
|
7754
7781
|
continue;
|
|
7755
7782
|
copyDirRecursive(srcPath, destPath, depth + 1, skipFiles);
|
|
7756
7783
|
} else if (stat.isFile()) {
|
|
7757
|
-
|
|
7784
|
+
fs13.copyFileSync(srcPath, destPath);
|
|
7758
7785
|
}
|
|
7759
7786
|
} else if (entry.isDirectory()) {
|
|
7760
7787
|
copyDirRecursive(srcPath, destPath, depth + 1, skipFiles);
|
|
7761
7788
|
} else {
|
|
7762
|
-
|
|
7789
|
+
fs13.copyFileSync(srcPath, destPath);
|
|
7763
7790
|
}
|
|
7764
7791
|
}
|
|
7765
7792
|
}
|
|
@@ -7897,9 +7924,9 @@ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, conf
|
|
|
7897
7924
|
}
|
|
7898
7925
|
}
|
|
7899
7926
|
for (const repo of repos) {
|
|
7900
|
-
const worktreePath =
|
|
7927
|
+
const worktreePath = path14.join(workspacePath, repo.name);
|
|
7901
7928
|
const sourcePath = repo.path;
|
|
7902
|
-
if (!sourcePath || !
|
|
7929
|
+
if (!sourcePath || !fs13.existsSync(worktreePath))
|
|
7903
7930
|
continue;
|
|
7904
7931
|
const envSetup = repo.env_setup;
|
|
7905
7932
|
if (!envSetup)
|
|
@@ -7918,23 +7945,23 @@ function setupWorldEnv(repos, workspacePath, serviceEnv, crossRepoEnv = {}, conf
|
|
|
7918
7945
|
}
|
|
7919
7946
|
}
|
|
7920
7947
|
function copyMatchingFiles(sourcePath, destPath, pattern) {
|
|
7921
|
-
const fullPattern =
|
|
7948
|
+
const fullPattern = path14.join(sourcePath, pattern);
|
|
7922
7949
|
if (!pattern.includes("*")) {
|
|
7923
|
-
const sourceFile =
|
|
7924
|
-
const destFile =
|
|
7925
|
-
if (
|
|
7926
|
-
|
|
7927
|
-
|
|
7950
|
+
const sourceFile = path14.join(sourcePath, pattern);
|
|
7951
|
+
const destFile = path14.join(destPath, pattern);
|
|
7952
|
+
if (fs13.existsSync(sourceFile)) {
|
|
7953
|
+
fs13.mkdirSync(path14.dirname(destFile), { recursive: true });
|
|
7954
|
+
fs13.copyFileSync(sourceFile, destFile);
|
|
7928
7955
|
}
|
|
7929
7956
|
return;
|
|
7930
7957
|
}
|
|
7931
7958
|
try {
|
|
7932
7959
|
const matches2 = globSync(fullPattern);
|
|
7933
7960
|
for (const match2 of matches2) {
|
|
7934
|
-
const relative2 =
|
|
7935
|
-
const dest =
|
|
7936
|
-
|
|
7937
|
-
|
|
7961
|
+
const relative2 = path14.relative(sourcePath, match2);
|
|
7962
|
+
const dest = path14.join(destPath, relative2);
|
|
7963
|
+
fs13.mkdirSync(path14.dirname(dest), { recursive: true });
|
|
7964
|
+
fs13.copyFileSync(match2, dest);
|
|
7938
7965
|
}
|
|
7939
7966
|
} catch {
|
|
7940
7967
|
}
|
|
@@ -7942,14 +7969,14 @@ function copyMatchingFiles(sourcePath, destPath, pattern) {
|
|
|
7942
7969
|
function generateEnvFromExample(repoPath, overrides) {
|
|
7943
7970
|
const exampleFiles = [".env.example", ".env.sample", ".env.local.example"];
|
|
7944
7971
|
for (const exampleName of exampleFiles) {
|
|
7945
|
-
const examplePath =
|
|
7946
|
-
if (!
|
|
7972
|
+
const examplePath = path14.join(repoPath, exampleName);
|
|
7973
|
+
if (!fs13.existsSync(examplePath))
|
|
7947
7974
|
continue;
|
|
7948
7975
|
const targetName = exampleName.replace(".example", "").replace(".sample", "");
|
|
7949
|
-
const targetPath =
|
|
7950
|
-
if (
|
|
7976
|
+
const targetPath = path14.join(repoPath, targetName);
|
|
7977
|
+
if (fs13.existsSync(targetPath))
|
|
7951
7978
|
continue;
|
|
7952
|
-
const template =
|
|
7979
|
+
const template = fs13.readFileSync(examplePath, "utf-8");
|
|
7953
7980
|
const generated = template.split("\n").map((line) => {
|
|
7954
7981
|
const match2 = /^([A-Z_][A-Z0-9_]*)=(.*)$/.exec(line);
|
|
7955
7982
|
if (match2) {
|
|
@@ -7960,13 +7987,13 @@ function generateEnvFromExample(repoPath, overrides) {
|
|
|
7960
7987
|
}
|
|
7961
7988
|
return line;
|
|
7962
7989
|
}).join("\n");
|
|
7963
|
-
|
|
7990
|
+
fs13.writeFileSync(targetPath, generated);
|
|
7964
7991
|
}
|
|
7965
7992
|
}
|
|
7966
7993
|
function applyEnvOverrides(repoPath, overrides) {
|
|
7967
|
-
const envPath =
|
|
7968
|
-
if (
|
|
7969
|
-
const existing =
|
|
7994
|
+
const envPath = path14.join(repoPath, ".env");
|
|
7995
|
+
if (fs13.existsSync(envPath)) {
|
|
7996
|
+
const existing = fs13.readFileSync(envPath, "utf-8");
|
|
7970
7997
|
const existingKeys = new Set(existing.split("\n").map((l) => l.split("=")[0]?.trim()).filter(Boolean));
|
|
7971
7998
|
const additions = [];
|
|
7972
7999
|
for (const [key, value] of Object.entries(overrides)) {
|
|
@@ -7975,7 +8002,7 @@ function applyEnvOverrides(repoPath, overrides) {
|
|
|
7975
8002
|
}
|
|
7976
8003
|
}
|
|
7977
8004
|
if (additions.length > 0) {
|
|
7978
|
-
|
|
8005
|
+
fs13.appendFileSync(envPath, "\n# Olam injected\n" + additions.join("\n") + "\n");
|
|
7979
8006
|
}
|
|
7980
8007
|
}
|
|
7981
8008
|
}
|
|
@@ -8053,9 +8080,9 @@ var init_env_setup = __esm({
|
|
|
8053
8080
|
|
|
8054
8081
|
// ../core/dist/world/baseline-diff.js
|
|
8055
8082
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
8056
|
-
import * as
|
|
8083
|
+
import * as fs14 from "node:fs";
|
|
8057
8084
|
import * as os9 from "node:os";
|
|
8058
|
-
import * as
|
|
8085
|
+
import * as path15 from "node:path";
|
|
8059
8086
|
function expandHome(p, homedir24) {
|
|
8060
8087
|
return p.replace(/^~(?=$|\/|\\)/, homedir24());
|
|
8061
8088
|
}
|
|
@@ -8081,9 +8108,9 @@ ${stderr}`;
|
|
|
8081
8108
|
function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
8082
8109
|
const exec = deps.exec ?? ((cmd, args, opts) => execFileSync3(cmd, args, opts));
|
|
8083
8110
|
const homedir24 = deps.homedir ?? (() => os9.homedir());
|
|
8084
|
-
const baselineDir =
|
|
8111
|
+
const baselineDir = path15.join(workspacePath, ".olam", "baseline");
|
|
8085
8112
|
try {
|
|
8086
|
-
|
|
8113
|
+
fs14.mkdirSync(baselineDir, { recursive: true });
|
|
8087
8114
|
} catch (err) {
|
|
8088
8115
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8089
8116
|
console.warn(`[baseline-diff] mkdir ${baselineDir} failed: ${msg}; reaper will see no baseline at all`);
|
|
@@ -8095,9 +8122,9 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
8095
8122
|
if (!repo.path)
|
|
8096
8123
|
continue;
|
|
8097
8124
|
const filename = `${sanitizeRepoFilename(repo.name)}.diff`;
|
|
8098
|
-
const outPath =
|
|
8125
|
+
const outPath = path15.join(baselineDir, filename);
|
|
8099
8126
|
const repoPath = expandHome(repo.path, homedir24);
|
|
8100
|
-
if (!
|
|
8127
|
+
if (!fs14.existsSync(repoPath)) {
|
|
8101
8128
|
writeBaselineFile(outPath, `# repo: ${repo.name}
|
|
8102
8129
|
# (skipped: path ${repoPath} does not exist)
|
|
8103
8130
|
`);
|
|
@@ -8164,7 +8191,7 @@ function snapshotBaselineDiff(repos, workspacePath, deps = {}) {
|
|
|
8164
8191
|
}
|
|
8165
8192
|
function writeBaselineFile(outPath, content) {
|
|
8166
8193
|
try {
|
|
8167
|
-
|
|
8194
|
+
fs14.writeFileSync(outPath, content);
|
|
8168
8195
|
} catch (err) {
|
|
8169
8196
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8170
8197
|
console.warn(`[baseline-diff] write to ${outPath} failed: ${msg}`);
|
|
@@ -8172,8 +8199,8 @@ function writeBaselineFile(outPath, content) {
|
|
|
8172
8199
|
}
|
|
8173
8200
|
function stripWorktreeEdits(repos, workspacePath) {
|
|
8174
8201
|
for (const repo of repos) {
|
|
8175
|
-
const worktreePath =
|
|
8176
|
-
if (!
|
|
8202
|
+
const worktreePath = path15.join(workspacePath, repo.name);
|
|
8203
|
+
if (!fs14.existsSync(worktreePath))
|
|
8177
8204
|
continue;
|
|
8178
8205
|
try {
|
|
8179
8206
|
execFileSync3("git", ["checkout", "--", "."], {
|
|
@@ -8210,12 +8237,12 @@ var init_baseline_diff = __esm({
|
|
|
8210
8237
|
});
|
|
8211
8238
|
|
|
8212
8239
|
// ../core/dist/world/context-injection.js
|
|
8213
|
-
import * as
|
|
8214
|
-
import * as
|
|
8240
|
+
import * as fs15 from "node:fs";
|
|
8241
|
+
import * as path16 from "node:path";
|
|
8215
8242
|
function injectWorldContext(opts) {
|
|
8216
8243
|
const { world, task, linearTicketId, claudeMdExtra, taskContext, services, pleriPlaneUrl } = opts;
|
|
8217
|
-
const claudeDir =
|
|
8218
|
-
|
|
8244
|
+
const claudeDir = path16.join(world.workspacePath, ".claude");
|
|
8245
|
+
fs15.mkdirSync(claudeDir, { recursive: true });
|
|
8219
8246
|
const sections = [];
|
|
8220
8247
|
sections.push(`# Olam World: ${world.name}`);
|
|
8221
8248
|
sections.push("");
|
|
@@ -8376,7 +8403,7 @@ function injectWorldContext(opts) {
|
|
|
8376
8403
|
sections.push("");
|
|
8377
8404
|
}
|
|
8378
8405
|
const content = sections.join("\n");
|
|
8379
|
-
|
|
8406
|
+
fs15.writeFileSync(path16.join(claudeDir, "CLAUDE.md"), content);
|
|
8380
8407
|
}
|
|
8381
8408
|
function formatTaskSource(ctx) {
|
|
8382
8409
|
if (ctx.source === "linear" && ctx.ticketId) {
|
|
@@ -8390,9 +8417,9 @@ function formatTaskSource(ctx) {
|
|
|
8390
8417
|
function hasPlanFile(world) {
|
|
8391
8418
|
if (world.repos.length === 0)
|
|
8392
8419
|
return false;
|
|
8393
|
-
const plansDir =
|
|
8420
|
+
const plansDir = path16.join(world.workspacePath, world.repos[0], "docs", "plans");
|
|
8394
8421
|
try {
|
|
8395
|
-
return
|
|
8422
|
+
return fs15.existsSync(plansDir) && fs15.readdirSync(plansDir).length > 0;
|
|
8396
8423
|
} catch {
|
|
8397
8424
|
return false;
|
|
8398
8425
|
}
|
|
@@ -9096,14 +9123,14 @@ var init_secrets_fetcher = __esm({
|
|
|
9096
9123
|
});
|
|
9097
9124
|
|
|
9098
9125
|
// ../core/dist/world/olam-yaml.js
|
|
9099
|
-
import * as
|
|
9126
|
+
import * as path17 from "node:path";
|
|
9100
9127
|
import YAML2 from "yaml";
|
|
9101
9128
|
function enrichReposWithManifests(repos, workspacePath) {
|
|
9102
9129
|
return repos.map((repo) => {
|
|
9103
9130
|
if (repo.manifest !== void 0 && repo.manifest !== null) {
|
|
9104
9131
|
return repo;
|
|
9105
9132
|
}
|
|
9106
|
-
const repoDir =
|
|
9133
|
+
const repoDir = path17.join(workspacePath, repo.name);
|
|
9107
9134
|
let manifest = null;
|
|
9108
9135
|
try {
|
|
9109
9136
|
manifest = loadRepoManifest(repoDir);
|
|
@@ -9124,8 +9151,8 @@ var init_olam_yaml = __esm({
|
|
|
9124
9151
|
});
|
|
9125
9152
|
|
|
9126
9153
|
// ../core/dist/policies/loader.js
|
|
9127
|
-
import * as
|
|
9128
|
-
import * as
|
|
9154
|
+
import * as fs16 from "node:fs";
|
|
9155
|
+
import * as path18 from "node:path";
|
|
9129
9156
|
import { parse as parseYaml3 } from "yaml";
|
|
9130
9157
|
function parseFrontmatter(content) {
|
|
9131
9158
|
const match2 = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/m.exec(content);
|
|
@@ -9145,20 +9172,20 @@ function toStringArray(v) {
|
|
|
9145
9172
|
return v.filter((x) => typeof x === "string");
|
|
9146
9173
|
}
|
|
9147
9174
|
function loadPolicies(workspaceRoot) {
|
|
9148
|
-
const policiesDir =
|
|
9149
|
-
if (!
|
|
9175
|
+
const policiesDir = path18.join(workspaceRoot, ".olam", "policies");
|
|
9176
|
+
if (!fs16.existsSync(policiesDir))
|
|
9150
9177
|
return [];
|
|
9151
9178
|
let files;
|
|
9152
9179
|
try {
|
|
9153
|
-
files =
|
|
9180
|
+
files = fs16.readdirSync(policiesDir).filter((f) => f.endsWith(".md")).sort();
|
|
9154
9181
|
} catch {
|
|
9155
9182
|
return [];
|
|
9156
9183
|
}
|
|
9157
9184
|
const policies = [];
|
|
9158
9185
|
for (const file of files) {
|
|
9159
|
-
const filePath =
|
|
9186
|
+
const filePath = path18.join(policiesDir, file);
|
|
9160
9187
|
try {
|
|
9161
|
-
const content =
|
|
9188
|
+
const content = fs16.readFileSync(filePath, "utf8");
|
|
9162
9189
|
const parsed = parseFrontmatter(content);
|
|
9163
9190
|
if (!parsed) {
|
|
9164
9191
|
console.warn(`[policies] skipping ${file}: no valid frontmatter block`);
|
|
@@ -9332,9 +9359,9 @@ __export(manager_exports, {
|
|
|
9332
9359
|
});
|
|
9333
9360
|
import * as crypto4 from "node:crypto";
|
|
9334
9361
|
import { execSync as execSync4 } from "node:child_process";
|
|
9335
|
-
import * as
|
|
9362
|
+
import * as fs17 from "node:fs";
|
|
9336
9363
|
import * as os10 from "node:os";
|
|
9337
|
-
import * as
|
|
9364
|
+
import * as path19 from "node:path";
|
|
9338
9365
|
import YAML3 from "yaml";
|
|
9339
9366
|
function getTokenScopes(ghToken, _exec = execSync4) {
|
|
9340
9367
|
try {
|
|
@@ -9749,7 +9776,7 @@ var init_manager = __esm({
|
|
|
9749
9776
|
}
|
|
9750
9777
|
}
|
|
9751
9778
|
const worldId = generateWorldId();
|
|
9752
|
-
const workspacePath =
|
|
9779
|
+
const workspacePath = path19.join(os10.homedir(), ".olam", "worlds", worldId);
|
|
9753
9780
|
const portOffset = this.registry.getNextPortOffset();
|
|
9754
9781
|
const branch = opts.branchName ?? `olam/${worldId}`;
|
|
9755
9782
|
const repos = this.resolveReposWithWorkspace(opts);
|
|
@@ -9806,37 +9833,37 @@ var init_manager = __esm({
|
|
|
9806
9833
|
if (!repo.path)
|
|
9807
9834
|
continue;
|
|
9808
9835
|
const sourceRoot = repo.path.replace(/^~/, os10.homedir());
|
|
9809
|
-
const worktreeRoot =
|
|
9810
|
-
if (!
|
|
9836
|
+
const worktreeRoot = path19.join(workspacePath, repo.name);
|
|
9837
|
+
if (!fs17.existsSync(sourceRoot) || !fs17.existsSync(worktreeRoot))
|
|
9811
9838
|
continue;
|
|
9812
9839
|
let copied = 0;
|
|
9813
9840
|
for (const pattern of RUNTIME_FILE_PATTERNS) {
|
|
9814
9841
|
const matches2 = [];
|
|
9815
9842
|
if (pattern.includes("*")) {
|
|
9816
|
-
const [dir, glob] = [
|
|
9817
|
-
const sourceDir =
|
|
9818
|
-
if (
|
|
9843
|
+
const [dir, glob] = [path19.dirname(pattern), path19.basename(pattern)];
|
|
9844
|
+
const sourceDir = path19.join(sourceRoot, dir);
|
|
9845
|
+
if (fs17.existsSync(sourceDir)) {
|
|
9819
9846
|
const ext2 = glob.replace(/^\*+/, "");
|
|
9820
9847
|
try {
|
|
9821
|
-
for (const entry of
|
|
9848
|
+
for (const entry of fs17.readdirSync(sourceDir)) {
|
|
9822
9849
|
if (ext2 === "" || entry.endsWith(ext2))
|
|
9823
|
-
matches2.push(
|
|
9850
|
+
matches2.push(path19.join(dir, entry));
|
|
9824
9851
|
}
|
|
9825
9852
|
} catch {
|
|
9826
9853
|
}
|
|
9827
9854
|
}
|
|
9828
|
-
} else if (
|
|
9855
|
+
} else if (fs17.existsSync(path19.join(sourceRoot, pattern))) {
|
|
9829
9856
|
matches2.push(pattern);
|
|
9830
9857
|
}
|
|
9831
9858
|
for (const rel of matches2) {
|
|
9832
|
-
const src =
|
|
9833
|
-
const dst =
|
|
9859
|
+
const src = path19.join(sourceRoot, rel);
|
|
9860
|
+
const dst = path19.join(worktreeRoot, rel);
|
|
9834
9861
|
try {
|
|
9835
|
-
const st =
|
|
9862
|
+
const st = fs17.statSync(src);
|
|
9836
9863
|
if (!st.isFile())
|
|
9837
9864
|
continue;
|
|
9838
|
-
|
|
9839
|
-
|
|
9865
|
+
fs17.mkdirSync(path19.dirname(dst), { recursive: true });
|
|
9866
|
+
fs17.copyFileSync(src, dst);
|
|
9840
9867
|
copied++;
|
|
9841
9868
|
} catch {
|
|
9842
9869
|
}
|
|
@@ -9936,7 +9963,7 @@ var init_manager = __esm({
|
|
|
9936
9963
|
try {
|
|
9937
9964
|
const hostExec = makeHostExecFn();
|
|
9938
9965
|
for (const repo of repos) {
|
|
9939
|
-
const repoDir =
|
|
9966
|
+
const repoDir = path19.join(workspacePath, repo.name);
|
|
9940
9967
|
if (repo.stack && Object.keys(repo.stack).length > 0) {
|
|
9941
9968
|
preDetectedStacks.set(repo.name, { repoName: repo.name, versions: repo.stack });
|
|
9942
9969
|
} else {
|
|
@@ -9993,10 +10020,10 @@ var init_manager = __esm({
|
|
|
9993
10020
|
const worldEnv = {};
|
|
9994
10021
|
if (opts.task)
|
|
9995
10022
|
worldEnv.OLAM_TASK = opts.task;
|
|
9996
|
-
const r2CredsPath =
|
|
9997
|
-
if (
|
|
10023
|
+
const r2CredsPath = path19.join(os10.homedir(), ".olam", "r2-credentials.json");
|
|
10024
|
+
if (fs17.existsSync(r2CredsPath)) {
|
|
9998
10025
|
try {
|
|
9999
|
-
const r2Raw =
|
|
10026
|
+
const r2Raw = fs17.readFileSync(r2CredsPath, "utf-8").trim();
|
|
10000
10027
|
if (r2Raw.length > 0) {
|
|
10001
10028
|
const r2 = JSON.parse(r2Raw);
|
|
10002
10029
|
if (typeof r2.account_id === "string")
|
|
@@ -10013,10 +10040,10 @@ var init_manager = __esm({
|
|
|
10013
10040
|
} catch {
|
|
10014
10041
|
}
|
|
10015
10042
|
}
|
|
10016
|
-
const keysYamlPath =
|
|
10017
|
-
if (
|
|
10043
|
+
const keysYamlPath = path19.join(os10.homedir(), ".olam", "keys.yaml");
|
|
10044
|
+
if (fs17.existsSync(keysYamlPath)) {
|
|
10018
10045
|
try {
|
|
10019
|
-
const keysRaw =
|
|
10046
|
+
const keysRaw = fs17.readFileSync(keysYamlPath, "utf-8").trim();
|
|
10020
10047
|
if (keysRaw.length > 0) {
|
|
10021
10048
|
const parsed = YAML3.parse(keysRaw);
|
|
10022
10049
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
@@ -10063,10 +10090,10 @@ var init_manager = __esm({
|
|
|
10063
10090
|
worldEnv[k] = v;
|
|
10064
10091
|
}
|
|
10065
10092
|
for (const { repoName, relativePath, content } of fileWrites) {
|
|
10066
|
-
const absPath =
|
|
10093
|
+
const absPath = path19.join(workspacePath, repoName, relativePath);
|
|
10067
10094
|
try {
|
|
10068
|
-
|
|
10069
|
-
|
|
10095
|
+
fs17.mkdirSync(path19.dirname(absPath), { recursive: true });
|
|
10096
|
+
fs17.writeFileSync(absPath, content.endsWith("\n") ? content : content + "\n", {
|
|
10070
10097
|
mode: 384
|
|
10071
10098
|
});
|
|
10072
10099
|
console.log(`[secrets] ${repoName}: materialised ${relativePath} (${content.length} chars, mode 0600)`);
|
|
@@ -10218,7 +10245,7 @@ var init_manager = __esm({
|
|
|
10218
10245
|
let taskWithPolicies = opts.task;
|
|
10219
10246
|
try {
|
|
10220
10247
|
const allPolicies = repos.flatMap((repo) => {
|
|
10221
|
-
const repoWorktree =
|
|
10248
|
+
const repoWorktree = path19.join(workspacePath, repo.name);
|
|
10222
10249
|
return loadPolicies(repoWorktree);
|
|
10223
10250
|
});
|
|
10224
10251
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -10234,8 +10261,8 @@ var init_manager = __esm({
|
|
|
10234
10261
|
${opts.task}`;
|
|
10235
10262
|
execSync4(`docker exec ${containerName} mkdir -p /home/olam/.olam/policies`, { stdio: "pipe", timeout: 1e4 });
|
|
10236
10263
|
for (const repo of repos) {
|
|
10237
|
-
const policiesDir =
|
|
10238
|
-
if (
|
|
10264
|
+
const policiesDir = path19.join(workspacePath, repo.name, ".olam", "policies");
|
|
10265
|
+
if (fs17.existsSync(policiesDir)) {
|
|
10239
10266
|
execSync4(`docker cp "${policiesDir}/." "${containerName}:/home/olam/.olam/policies/"`, { stdio: "pipe", timeout: 15e3 });
|
|
10240
10267
|
}
|
|
10241
10268
|
}
|
|
@@ -10314,8 +10341,8 @@ ${opts.task}`;
|
|
|
10314
10341
|
} catch {
|
|
10315
10342
|
}
|
|
10316
10343
|
try {
|
|
10317
|
-
|
|
10318
|
-
if (
|
|
10344
|
+
fs17.rmSync(world.workspacePath, { recursive: true, force: true });
|
|
10345
|
+
if (fs17.existsSync(world.workspacePath)) {
|
|
10319
10346
|
console.warn(`[WorldManager] destroyWorld(${worldId}): workspace dir ${world.workspacePath} still exists after rmSync. Run \`olam clean --apply\` to reap.`);
|
|
10320
10347
|
}
|
|
10321
10348
|
} catch (err) {
|
|
@@ -10400,14 +10427,14 @@ ${opts.task}`;
|
|
|
10400
10427
|
return names.map((name) => this.config.repos.find((r) => r.name === name)).filter((r) => r !== void 0);
|
|
10401
10428
|
}
|
|
10402
10429
|
transportPlanFile(planFilePath, workspacePath, repoNames) {
|
|
10403
|
-
const planContent =
|
|
10404
|
-
const planFileName =
|
|
10430
|
+
const planContent = fs17.readFileSync(planFilePath, "utf-8");
|
|
10431
|
+
const planFileName = path19.basename(planFilePath);
|
|
10405
10432
|
const targetRepo = repoNames[0];
|
|
10406
10433
|
if (!targetRepo)
|
|
10407
10434
|
return;
|
|
10408
|
-
const plansDir =
|
|
10409
|
-
|
|
10410
|
-
|
|
10435
|
+
const plansDir = path19.join(workspacePath, targetRepo, "docs", "plans");
|
|
10436
|
+
fs17.mkdirSync(plansDir, { recursive: true });
|
|
10437
|
+
fs17.writeFileSync(path19.join(plansDir, planFileName), planContent);
|
|
10411
10438
|
}
|
|
10412
10439
|
resolveServices(repos) {
|
|
10413
10440
|
const services = [];
|
|
@@ -10500,9 +10527,9 @@ var init_tracker = __esm({
|
|
|
10500
10527
|
});
|
|
10501
10528
|
|
|
10502
10529
|
// ../core/dist/world-paths.js
|
|
10503
|
-
import * as
|
|
10530
|
+
import * as path20 from "node:path";
|
|
10504
10531
|
function getWorldDbPath(workspacePath) {
|
|
10505
|
-
return
|
|
10532
|
+
return path20.join(workspacePath, WORLD_DB_FILENAME);
|
|
10506
10533
|
}
|
|
10507
10534
|
var WORLD_DB_FILENAME;
|
|
10508
10535
|
var init_world_paths = __esm({
|
|
@@ -11120,9 +11147,9 @@ var init_session_aggregator = __esm({
|
|
|
11120
11147
|
|
|
11121
11148
|
// ../core/dist/dashboard/server.js
|
|
11122
11149
|
import * as http from "node:http";
|
|
11123
|
-
import * as
|
|
11124
|
-
import * as
|
|
11125
|
-
import { fileURLToPath as
|
|
11150
|
+
import * as fs18 from "node:fs";
|
|
11151
|
+
import * as path21 from "node:path";
|
|
11152
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
11126
11153
|
function jsonResponse(res, data, status = 200) {
|
|
11127
11154
|
res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
|
|
11128
11155
|
res.end(JSON.stringify(data));
|
|
@@ -11132,7 +11159,7 @@ function notFound(res) {
|
|
|
11132
11159
|
}
|
|
11133
11160
|
function openThoughtStore(workspacePath) {
|
|
11134
11161
|
const dbPath = getWorldDbPath(workspacePath);
|
|
11135
|
-
if (!
|
|
11162
|
+
if (!fs18.existsSync(dbPath))
|
|
11136
11163
|
return null;
|
|
11137
11164
|
return new ThoughtLocalStore(dbPath);
|
|
11138
11165
|
}
|
|
@@ -11303,13 +11330,13 @@ function findSessionInWorld(registry, sessionId) {
|
|
|
11303
11330
|
}
|
|
11304
11331
|
function createDashboardServer(opts) {
|
|
11305
11332
|
const { port, registry } = opts;
|
|
11306
|
-
const thisDir =
|
|
11307
|
-
const defaultPublicDir =
|
|
11333
|
+
const thisDir = path21.dirname(fileURLToPath3(import.meta.url));
|
|
11334
|
+
const defaultPublicDir = path21.resolve(thisDir, "../../../control-plane/public");
|
|
11308
11335
|
const publicDir = opts.publicDir ?? defaultPublicDir;
|
|
11309
|
-
let hasPublicDir =
|
|
11336
|
+
let hasPublicDir = fs18.existsSync(publicDir);
|
|
11310
11337
|
const server = http.createServer((req, res) => {
|
|
11311
11338
|
if (!hasPublicDir) {
|
|
11312
|
-
hasPublicDir =
|
|
11339
|
+
hasPublicDir = fs18.existsSync(publicDir);
|
|
11313
11340
|
}
|
|
11314
11341
|
const host = req.headers.host ?? `localhost:${port}`;
|
|
11315
11342
|
const url = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -11583,22 +11610,22 @@ function createDashboardServer(opts) {
|
|
|
11583
11610
|
res.end(`<html><body style="font-family:system-ui;padding:2rem"><h1>Olam Dashboard</h1><p>The React app has not been built yet.</p><p>Run <code>npm run build:app</code> in <code>packages/control-plane</code> to build it.</p><p>API routes are available at <code>/api/*</code>.</p></body></html>`);
|
|
11584
11611
|
return;
|
|
11585
11612
|
}
|
|
11586
|
-
let filePath =
|
|
11613
|
+
let filePath = path21.join(publicDir, pathname === "/" ? "index.html" : pathname);
|
|
11587
11614
|
if (!filePath.startsWith(publicDir)) {
|
|
11588
11615
|
notFound(res);
|
|
11589
11616
|
return;
|
|
11590
11617
|
}
|
|
11591
|
-
if (
|
|
11592
|
-
const ext2 =
|
|
11618
|
+
if (fs18.existsSync(filePath) && fs18.statSync(filePath).isFile()) {
|
|
11619
|
+
const ext2 = path21.extname(filePath);
|
|
11593
11620
|
const contentType = MIME[ext2] ?? "application/octet-stream";
|
|
11594
11621
|
res.writeHead(200, { "Content-Type": contentType });
|
|
11595
|
-
|
|
11622
|
+
fs18.createReadStream(filePath).pipe(res);
|
|
11596
11623
|
return;
|
|
11597
11624
|
}
|
|
11598
|
-
filePath =
|
|
11599
|
-
if (
|
|
11625
|
+
filePath = path21.join(publicDir, "index.html");
|
|
11626
|
+
if (fs18.existsSync(filePath)) {
|
|
11600
11627
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
11601
|
-
|
|
11628
|
+
fs18.createReadStream(filePath).pipe(res);
|
|
11602
11629
|
return;
|
|
11603
11630
|
}
|
|
11604
11631
|
notFound(res);
|
|
@@ -11629,16 +11656,16 @@ var init_server = __esm({
|
|
|
11629
11656
|
});
|
|
11630
11657
|
|
|
11631
11658
|
// ../core/dist/dashboard/state.js
|
|
11632
|
-
import * as
|
|
11659
|
+
import * as fs19 from "node:fs";
|
|
11633
11660
|
import * as os11 from "node:os";
|
|
11634
|
-
import * as
|
|
11661
|
+
import * as path22 from "node:path";
|
|
11635
11662
|
function saveDashboardState(state) {
|
|
11636
|
-
|
|
11637
|
-
|
|
11663
|
+
fs19.mkdirSync(path22.dirname(STATE_PATH), { recursive: true });
|
|
11664
|
+
fs19.writeFileSync(STATE_PATH, JSON.stringify(state, null, 2));
|
|
11638
11665
|
}
|
|
11639
11666
|
function loadDashboardState() {
|
|
11640
11667
|
try {
|
|
11641
|
-
const raw =
|
|
11668
|
+
const raw = fs19.readFileSync(STATE_PATH, "utf-8");
|
|
11642
11669
|
return JSON.parse(raw);
|
|
11643
11670
|
} catch {
|
|
11644
11671
|
return null;
|
|
@@ -11646,7 +11673,7 @@ function loadDashboardState() {
|
|
|
11646
11673
|
}
|
|
11647
11674
|
function clearDashboardState() {
|
|
11648
11675
|
try {
|
|
11649
|
-
|
|
11676
|
+
fs19.unlinkSync(STATE_PATH);
|
|
11650
11677
|
} catch {
|
|
11651
11678
|
}
|
|
11652
11679
|
}
|
|
@@ -11666,7 +11693,7 @@ var STATE_PATH;
|
|
|
11666
11693
|
var init_state2 = __esm({
|
|
11667
11694
|
"../core/dist/dashboard/state.js"() {
|
|
11668
11695
|
"use strict";
|
|
11669
|
-
STATE_PATH =
|
|
11696
|
+
STATE_PATH = path22.join(os11.homedir(), ".olam", "dashboard.json");
|
|
11670
11697
|
}
|
|
11671
11698
|
});
|
|
11672
11699
|
|
|
@@ -12061,50 +12088,50 @@ __export(host_cp_exports, {
|
|
|
12061
12088
|
writeToken: () => writeToken
|
|
12062
12089
|
});
|
|
12063
12090
|
import * as crypto5 from "node:crypto";
|
|
12064
|
-
import * as
|
|
12091
|
+
import * as fs20 from "node:fs";
|
|
12065
12092
|
import * as os12 from "node:os";
|
|
12066
|
-
import * as
|
|
12093
|
+
import * as path23 from "node:path";
|
|
12067
12094
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
12068
12095
|
import Dockerode2 from "dockerode";
|
|
12069
12096
|
function findComposeFile() {
|
|
12070
12097
|
const candidates = [
|
|
12071
12098
|
// Bundled path: dist/index.js lives at <pkg>/dist/; host-cp/ is a sibling of dist/
|
|
12072
|
-
|
|
12099
|
+
path23.resolve(path23.dirname(new URL(import.meta.url).pathname), "../host-cp/compose.yaml"),
|
|
12073
12100
|
// Source-mode: cwd is monorepo root
|
|
12074
|
-
|
|
12101
|
+
path23.resolve(process.cwd(), "packages/host-cp/compose.yaml"),
|
|
12075
12102
|
// Source-mode: cwd is one level inside the monorepo
|
|
12076
|
-
|
|
12103
|
+
path23.resolve(process.cwd(), "../packages/host-cp/compose.yaml")
|
|
12077
12104
|
];
|
|
12078
12105
|
for (const c of candidates) {
|
|
12079
|
-
if (
|
|
12106
|
+
if (fs20.existsSync(c)) return c;
|
|
12080
12107
|
}
|
|
12081
|
-
return
|
|
12108
|
+
return path23.resolve(process.cwd(), "packages/host-cp/compose.yaml");
|
|
12082
12109
|
}
|
|
12083
12110
|
function olamHome() {
|
|
12084
|
-
return process.env.OLAM_HOME ??
|
|
12111
|
+
return process.env.OLAM_HOME ?? path23.join(os12.homedir(), ".olam");
|
|
12085
12112
|
}
|
|
12086
12113
|
function tokenPath() {
|
|
12087
|
-
return
|
|
12114
|
+
return path23.join(olamHome(), "host-cp.token");
|
|
12088
12115
|
}
|
|
12089
12116
|
function pidPath() {
|
|
12090
|
-
return
|
|
12117
|
+
return path23.join(olamHome(), "host-cp.pid");
|
|
12091
12118
|
}
|
|
12092
12119
|
function authSecretPath() {
|
|
12093
|
-
return
|
|
12120
|
+
return path23.join(olamHome(), "auth-secret");
|
|
12094
12121
|
}
|
|
12095
12122
|
function readAuthSecret2() {
|
|
12096
12123
|
const filePath = authSecretPath();
|
|
12097
|
-
if (!
|
|
12098
|
-
const raw =
|
|
12124
|
+
if (!fs20.existsSync(filePath)) return null;
|
|
12125
|
+
const raw = fs20.readFileSync(filePath, "utf-8").trim();
|
|
12099
12126
|
return raw.length > 0 ? raw : null;
|
|
12100
12127
|
}
|
|
12101
12128
|
function r2CredentialsPath() {
|
|
12102
|
-
return
|
|
12129
|
+
return path23.join(olamHome(), "r2-credentials.json");
|
|
12103
12130
|
}
|
|
12104
12131
|
function readR2Credentials() {
|
|
12105
12132
|
const filePath = r2CredentialsPath();
|
|
12106
|
-
if (!
|
|
12107
|
-
const raw =
|
|
12133
|
+
if (!fs20.existsSync(filePath)) return null;
|
|
12134
|
+
const raw = fs20.readFileSync(filePath, "utf-8").trim();
|
|
12108
12135
|
if (raw.length === 0) return null;
|
|
12109
12136
|
try {
|
|
12110
12137
|
const parsed = JSON.parse(raw);
|
|
@@ -12127,37 +12154,37 @@ function readR2Credentials() {
|
|
|
12127
12154
|
function writeToken() {
|
|
12128
12155
|
const token = crypto5.randomBytes(32).toString("hex");
|
|
12129
12156
|
const filePath = tokenPath();
|
|
12130
|
-
|
|
12131
|
-
|
|
12157
|
+
fs20.mkdirSync(path23.dirname(filePath), { recursive: true });
|
|
12158
|
+
fs20.writeFileSync(filePath, token, { mode: 384 });
|
|
12132
12159
|
return token;
|
|
12133
12160
|
}
|
|
12134
12161
|
function readToken() {
|
|
12135
12162
|
const filePath = tokenPath();
|
|
12136
|
-
if (!
|
|
12137
|
-
return
|
|
12163
|
+
if (!fs20.existsSync(filePath)) return null;
|
|
12164
|
+
return fs20.readFileSync(filePath, "utf-8").trim();
|
|
12138
12165
|
}
|
|
12139
12166
|
function removeToken() {
|
|
12140
12167
|
const filePath = tokenPath();
|
|
12141
|
-
if (!
|
|
12142
|
-
|
|
12168
|
+
if (!fs20.existsSync(filePath)) return false;
|
|
12169
|
+
fs20.unlinkSync(filePath);
|
|
12143
12170
|
return true;
|
|
12144
12171
|
}
|
|
12145
12172
|
function writePid(pid) {
|
|
12146
12173
|
const filePath = pidPath();
|
|
12147
|
-
|
|
12148
|
-
|
|
12174
|
+
fs20.mkdirSync(path23.dirname(filePath), { recursive: true });
|
|
12175
|
+
fs20.writeFileSync(filePath, String(pid), { mode: 420 });
|
|
12149
12176
|
}
|
|
12150
12177
|
function readPid() {
|
|
12151
12178
|
const filePath = pidPath();
|
|
12152
|
-
if (!
|
|
12153
|
-
const raw =
|
|
12179
|
+
if (!fs20.existsSync(filePath)) return null;
|
|
12180
|
+
const raw = fs20.readFileSync(filePath, "utf-8").trim();
|
|
12154
12181
|
const n = parseInt(raw, 10);
|
|
12155
12182
|
return Number.isFinite(n) ? n : null;
|
|
12156
12183
|
}
|
|
12157
12184
|
function removePid() {
|
|
12158
12185
|
const filePath = pidPath();
|
|
12159
|
-
if (!
|
|
12160
|
-
|
|
12186
|
+
if (!fs20.existsSync(filePath)) return false;
|
|
12187
|
+
fs20.unlinkSync(filePath);
|
|
12161
12188
|
return true;
|
|
12162
12189
|
}
|
|
12163
12190
|
async function findHostCpContainer() {
|
|
@@ -12269,6 +12296,10 @@ function buildComposeEnv(authSecret, ghToken) {
|
|
|
12269
12296
|
if (ghToken != null && ghToken.length > 0) {
|
|
12270
12297
|
env.GH_TOKEN = ghToken;
|
|
12271
12298
|
}
|
|
12299
|
+
const cliVersion = readCliVersion();
|
|
12300
|
+
if (cliVersion && cliVersion !== "0.0.0-unknown") {
|
|
12301
|
+
env.OLAM_CLI_VERSION = cliVersion;
|
|
12302
|
+
}
|
|
12272
12303
|
return env;
|
|
12273
12304
|
}
|
|
12274
12305
|
function captureGhToken() {
|
|
@@ -12316,7 +12347,7 @@ async function handleStart(opts) {
|
|
|
12316
12347
|
}
|
|
12317
12348
|
const token = writeToken();
|
|
12318
12349
|
const composeFile = findComposeFile();
|
|
12319
|
-
if (!
|
|
12350
|
+
if (!fs20.existsSync(composeFile)) {
|
|
12320
12351
|
printError(`compose.yaml not found at ${composeFile}. Run from the olam project root.`);
|
|
12321
12352
|
removeToken();
|
|
12322
12353
|
process.exitCode = 1;
|
|
@@ -12398,7 +12429,7 @@ async function stopHostCp() {
|
|
|
12398
12429
|
}
|
|
12399
12430
|
async function handleStop() {
|
|
12400
12431
|
const composeFile = findComposeFile();
|
|
12401
|
-
if (!
|
|
12432
|
+
if (!fs20.existsSync(composeFile)) {
|
|
12402
12433
|
printWarning(`compose.yaml not found at ${composeFile}. Cleaning up token + PID anyway.`);
|
|
12403
12434
|
removeToken();
|
|
12404
12435
|
removePid();
|
|
@@ -12426,13 +12457,13 @@ async function buildStatusReport() {
|
|
|
12426
12457
|
const container = await findHostCpContainer();
|
|
12427
12458
|
const health = await probeHealth();
|
|
12428
12459
|
const tokenFile = tokenPath();
|
|
12429
|
-
const tokenPresent =
|
|
12460
|
+
const tokenPresent = fs20.existsSync(tokenFile);
|
|
12430
12461
|
let tokenModeOk = false;
|
|
12431
12462
|
if (tokenPresent) {
|
|
12432
|
-
const mode =
|
|
12463
|
+
const mode = fs20.statSync(tokenFile).mode & 511;
|
|
12433
12464
|
tokenModeOk = mode === 384;
|
|
12434
12465
|
}
|
|
12435
|
-
const pidPresent =
|
|
12466
|
+
const pidPresent = fs20.existsSync(pidPath());
|
|
12436
12467
|
let stack;
|
|
12437
12468
|
if (!container) {
|
|
12438
12469
|
stack = "not_started";
|
|
@@ -12520,8 +12551,8 @@ async function discoverWorldPort(worldId) {
|
|
|
12520
12551
|
}
|
|
12521
12552
|
async function readHostCpToken2() {
|
|
12522
12553
|
const tp = tokenPath();
|
|
12523
|
-
if (!
|
|
12524
|
-
return
|
|
12554
|
+
if (!fs20.existsSync(tp)) return null;
|
|
12555
|
+
return fs20.readFileSync(tp, "utf-8").trim();
|
|
12525
12556
|
}
|
|
12526
12557
|
async function callHostCpProxy(method, worldId, path46, body) {
|
|
12527
12558
|
const token = await readHostCpToken2();
|
|
@@ -12637,6 +12668,7 @@ var init_host_cp = __esm({
|
|
|
12637
12668
|
init_dist();
|
|
12638
12669
|
init_output();
|
|
12639
12670
|
init_docker_host();
|
|
12671
|
+
init_cli_version();
|
|
12640
12672
|
init_open_url();
|
|
12641
12673
|
HOST_CP_PORT = 19e3;
|
|
12642
12674
|
SIDECAR_PULL_SERVICE = "docker-socket-proxy";
|
|
@@ -12651,17 +12683,17 @@ __export(install_root_exports, {
|
|
|
12651
12683
|
isDevMode: () => isDevMode,
|
|
12652
12684
|
resolveBuildScript: () => resolveBuildScript
|
|
12653
12685
|
});
|
|
12654
|
-
import { existsSync as
|
|
12655
|
-
import { dirname as
|
|
12656
|
-
import { fileURLToPath as
|
|
12686
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
12687
|
+
import { dirname as dirname14, join as join25, resolve as resolve6 } from "node:path";
|
|
12688
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
12657
12689
|
function installRoot(metaUrl = import.meta.url) {
|
|
12658
|
-
const here =
|
|
12659
|
-
return resolve6(
|
|
12690
|
+
const here = fileURLToPath4(metaUrl);
|
|
12691
|
+
return resolve6(dirname14(here), "..");
|
|
12660
12692
|
}
|
|
12661
12693
|
function isDevMode(env = process.env, installRootDir = installRoot()) {
|
|
12662
12694
|
if (env.OLAM_DEV !== "1") return false;
|
|
12663
12695
|
const repoRoot = resolve6(installRootDir, "..", "..");
|
|
12664
|
-
return
|
|
12696
|
+
return existsSync19(join25(repoRoot, "packages")) && existsSync19(join25(repoRoot, "package.json"));
|
|
12665
12697
|
}
|
|
12666
12698
|
function resolveBuildScript(input) {
|
|
12667
12699
|
const { scriptRelPath, env = process.env, installRootDir = installRoot() } = input;
|
|
@@ -12669,7 +12701,7 @@ function resolveBuildScript(input) {
|
|
|
12669
12701
|
throw new MissingBuildScriptError(scriptRelPath);
|
|
12670
12702
|
}
|
|
12671
12703
|
const repoRoot = resolve6(installRootDir, "..", "..");
|
|
12672
|
-
return
|
|
12704
|
+
return join25(repoRoot, scriptRelPath);
|
|
12673
12705
|
}
|
|
12674
12706
|
var MissingBuildScriptError;
|
|
12675
12707
|
var init_install_root = __esm({
|
|
@@ -12840,20 +12872,20 @@ var init_registry_allowlist = __esm({
|
|
|
12840
12872
|
});
|
|
12841
12873
|
|
|
12842
12874
|
// ../core/dist/world/world-yaml.js
|
|
12843
|
-
import * as
|
|
12844
|
-
import * as
|
|
12875
|
+
import * as fs22 from "node:fs";
|
|
12876
|
+
import * as path25 from "node:path";
|
|
12845
12877
|
import { parse as parseYaml4, stringify as stringifyYaml4 } from "yaml";
|
|
12846
12878
|
function writeWorldYaml(worldPath, data) {
|
|
12847
|
-
const olamDir =
|
|
12848
|
-
|
|
12849
|
-
|
|
12879
|
+
const olamDir = path25.join(worldPath, ".olam");
|
|
12880
|
+
fs22.mkdirSync(olamDir, { recursive: true });
|
|
12881
|
+
fs22.writeFileSync(path25.join(olamDir, "world.yaml"), stringifyYaml4(data), "utf-8");
|
|
12850
12882
|
}
|
|
12851
12883
|
function readWorldYaml(worldPath) {
|
|
12852
|
-
const yamlPath =
|
|
12853
|
-
if (!
|
|
12884
|
+
const yamlPath = path25.join(worldPath, ".olam", "world.yaml");
|
|
12885
|
+
if (!fs22.existsSync(yamlPath))
|
|
12854
12886
|
return null;
|
|
12855
12887
|
try {
|
|
12856
|
-
const raw =
|
|
12888
|
+
const raw = fs22.readFileSync(yamlPath, "utf-8");
|
|
12857
12889
|
const parsed = parseYaml4(raw);
|
|
12858
12890
|
return WorldYamlSchema.parse(parsed);
|
|
12859
12891
|
} catch {
|
|
@@ -12984,16 +13016,16 @@ __export(machine_schema_exports, {
|
|
|
12984
13016
|
readMachineConfig: () => readMachineConfig,
|
|
12985
13017
|
writeMachineConfig: () => writeMachineConfig
|
|
12986
13018
|
});
|
|
12987
|
-
import * as
|
|
12988
|
-
import * as
|
|
13019
|
+
import * as fs36 from "node:fs";
|
|
13020
|
+
import * as path40 from "node:path";
|
|
12989
13021
|
import * as os21 from "node:os";
|
|
12990
13022
|
import { parse as parseYaml5, stringify as stringifyYaml5 } from "yaml";
|
|
12991
13023
|
function readMachineConfig(configPath) {
|
|
12992
13024
|
const p = configPath ?? DEFAULT_CONFIG_PATH;
|
|
12993
|
-
if (!
|
|
13025
|
+
if (!fs36.existsSync(p))
|
|
12994
13026
|
return null;
|
|
12995
13027
|
try {
|
|
12996
|
-
const raw =
|
|
13028
|
+
const raw = fs36.readFileSync(p, "utf-8");
|
|
12997
13029
|
const parsed = parseYaml5(raw);
|
|
12998
13030
|
return MachineConfigSchema.parse(parsed);
|
|
12999
13031
|
} catch {
|
|
@@ -13002,8 +13034,8 @@ function readMachineConfig(configPath) {
|
|
|
13002
13034
|
}
|
|
13003
13035
|
function writeMachineConfig(config, configPath) {
|
|
13004
13036
|
const p = configPath ?? DEFAULT_CONFIG_PATH;
|
|
13005
|
-
|
|
13006
|
-
|
|
13037
|
+
fs36.mkdirSync(path40.dirname(p), { recursive: true });
|
|
13038
|
+
fs36.writeFileSync(p, stringifyYaml5({ ...config }), { mode: 420 });
|
|
13007
13039
|
}
|
|
13008
13040
|
function initMachineConfig(opts = {}) {
|
|
13009
13041
|
const configPath = opts.configPath ?? DEFAULT_CONFIG_PATH;
|
|
@@ -13026,22 +13058,20 @@ var init_machine_schema = __esm({
|
|
|
13026
13058
|
channel: external_exports.enum(["stable", "beta", "edge"]).default("stable"),
|
|
13027
13059
|
auto_update: external_exports.boolean().default(true),
|
|
13028
13060
|
telemetry: external_exports.boolean().default(true),
|
|
13029
|
-
worlds_dir: external_exports.string().default(() =>
|
|
13061
|
+
worlds_dir: external_exports.string().default(() => path40.join(os21.homedir(), ".olam", "worlds"))
|
|
13030
13062
|
});
|
|
13031
|
-
DEFAULT_CONFIG_PATH =
|
|
13063
|
+
DEFAULT_CONFIG_PATH = path40.join(os21.homedir(), ".olam", "config.yaml");
|
|
13032
13064
|
}
|
|
13033
13065
|
});
|
|
13034
13066
|
|
|
13035
13067
|
// src/index.ts
|
|
13068
|
+
init_cli_version();
|
|
13036
13069
|
import { Command } from "commander";
|
|
13037
|
-
import * as fs42 from "node:fs";
|
|
13038
|
-
import * as path45 from "node:path";
|
|
13039
|
-
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
13040
13070
|
|
|
13041
13071
|
// src/commands/init.ts
|
|
13042
13072
|
init_output();
|
|
13043
|
-
import * as
|
|
13044
|
-
import * as
|
|
13073
|
+
import * as fs6 from "node:fs";
|
|
13074
|
+
import * as path6 from "node:path";
|
|
13045
13075
|
import { execSync } from "node:child_process";
|
|
13046
13076
|
import pc3 from "picocolors";
|
|
13047
13077
|
|
|
@@ -13049,8 +13079,8 @@ import pc3 from "picocolors";
|
|
|
13049
13079
|
init_workspace();
|
|
13050
13080
|
init_loader();
|
|
13051
13081
|
init_output();
|
|
13052
|
-
import * as
|
|
13053
|
-
import * as
|
|
13082
|
+
import * as fs5 from "node:fs";
|
|
13083
|
+
import * as path5 from "node:path";
|
|
13054
13084
|
import pc2 from "picocolors";
|
|
13055
13085
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
13056
13086
|
function printWorkspaceNotFound(name) {
|
|
@@ -13144,7 +13174,7 @@ function registerWorkspace(program2) {
|
|
|
13144
13174
|
updatedAt: Date.now()
|
|
13145
13175
|
};
|
|
13146
13176
|
writeWorkspace(ws, { force: opts.force });
|
|
13147
|
-
const file =
|
|
13177
|
+
const file = path5.join(workspacesDir(), `${name}.yaml`);
|
|
13148
13178
|
printSuccess(`Created workspace "${name}" (${repos.length} repo${repos.length === 1 ? "" : "s"})`);
|
|
13149
13179
|
printInfo("File", file);
|
|
13150
13180
|
printInfo("Next", `olam create --name <world> --workspace ${name} --task "..."`);
|
|
@@ -13168,7 +13198,7 @@ function ensureProjectWorkspaceFromConfig(projectRoot, workspaceName) {
|
|
|
13168
13198
|
}
|
|
13169
13199
|
})();
|
|
13170
13200
|
if (existing) {
|
|
13171
|
-
return { created: false, file:
|
|
13201
|
+
return { created: false, file: path5.join(workspacesDir(), `${workspaceName}.yaml`) };
|
|
13172
13202
|
}
|
|
13173
13203
|
const cfg = loadConfig(projectRoot);
|
|
13174
13204
|
const repos = cfg.repos.map((r) => ({
|
|
@@ -13182,15 +13212,15 @@ function ensureProjectWorkspaceFromConfig(projectRoot, workspaceName) {
|
|
|
13182
13212
|
updatedAt: Date.now()
|
|
13183
13213
|
};
|
|
13184
13214
|
writeWorkspace(ws);
|
|
13185
|
-
const file =
|
|
13215
|
+
const file = path5.join(workspacesDir(), `${workspaceName}.yaml`);
|
|
13186
13216
|
return { created: true, file };
|
|
13187
13217
|
}
|
|
13188
13218
|
|
|
13189
13219
|
// src/commands/init.ts
|
|
13190
13220
|
function detectProjectType(root) {
|
|
13191
|
-
if (
|
|
13192
|
-
if (
|
|
13193
|
-
if (
|
|
13221
|
+
if (fs6.existsSync(path6.join(root, "Gemfile")) || fs6.existsSync(path6.join(root, "config", "routes.rb"))) return "rails";
|
|
13222
|
+
if (fs6.existsSync(path6.join(root, "package.json"))) return "node";
|
|
13223
|
+
if (fs6.existsSync(path6.join(root, "pyproject.toml")) || fs6.existsSync(path6.join(root, "requirements.txt"))) return "python";
|
|
13194
13224
|
return "generic";
|
|
13195
13225
|
}
|
|
13196
13226
|
function getRepoName(root) {
|
|
@@ -13203,13 +13233,13 @@ function getRepoName(root) {
|
|
|
13203
13233
|
if (match2) return match2[1];
|
|
13204
13234
|
} catch {
|
|
13205
13235
|
}
|
|
13206
|
-
return
|
|
13236
|
+
return path6.basename(root);
|
|
13207
13237
|
}
|
|
13208
13238
|
function findProjectRoot(startDir) {
|
|
13209
|
-
let current =
|
|
13239
|
+
let current = path6.resolve(startDir);
|
|
13210
13240
|
while (true) {
|
|
13211
|
-
if (
|
|
13212
|
-
const parent =
|
|
13241
|
+
if (fs6.existsSync(path6.join(current, ".git"))) return current;
|
|
13242
|
+
const parent = path6.dirname(current);
|
|
13213
13243
|
if (parent === current) return startDir;
|
|
13214
13244
|
current = parent;
|
|
13215
13245
|
}
|
|
@@ -13218,8 +13248,8 @@ function registerInit(program2) {
|
|
|
13218
13248
|
program2.command("init").description("Initialize olam in the current project").option("--path <path>", "Project root path", process.cwd()).option("--skip-pleri", "Skip Pleri setup").action(async (opts) => {
|
|
13219
13249
|
try {
|
|
13220
13250
|
const projectRoot = findProjectRoot(opts.path);
|
|
13221
|
-
const olamDir =
|
|
13222
|
-
if (
|
|
13251
|
+
const olamDir = path6.join(projectRoot, ".olam");
|
|
13252
|
+
if (fs6.existsSync(path6.join(olamDir, "config.yaml"))) {
|
|
13223
13253
|
printError(`Already initialized at ${olamDir}/config.yaml`);
|
|
13224
13254
|
process.exitCode = 1;
|
|
13225
13255
|
return;
|
|
@@ -13235,8 +13265,8 @@ function registerInit(program2) {
|
|
|
13235
13265
|
} catch {
|
|
13236
13266
|
remoteUrl = `git@github.com:your-org/${repoName}.git`;
|
|
13237
13267
|
}
|
|
13238
|
-
|
|
13239
|
-
|
|
13268
|
+
fs6.mkdirSync(path6.join(olamDir, "state"), { recursive: true });
|
|
13269
|
+
fs6.mkdirSync(path6.join(olamDir, "thoughts"), { recursive: true });
|
|
13240
13270
|
const pleriSection = opts.skipPleri ? "# pleri:\n# base_url: ${PLERI_BASE_URL}\n# plane_id: ${PLERI_PLANE_ID}\n# api_key: ${PLERI_API_KEY}\n" : "pleri:\n base_url: ${PLERI_BASE_URL}\n plane_id: ${PLERI_PLANE_ID}\n api_key: ${PLERI_API_KEY}\n";
|
|
13241
13271
|
const config = [
|
|
13242
13272
|
"version: 2",
|
|
@@ -13264,7 +13294,7 @@ function registerInit(program2) {
|
|
|
13264
13294
|
" mode: oauth",
|
|
13265
13295
|
""
|
|
13266
13296
|
].join("\n");
|
|
13267
|
-
|
|
13297
|
+
fs6.writeFileSync(path6.join(olamDir, "config.yaml"), config);
|
|
13268
13298
|
const envExample = [
|
|
13269
13299
|
"# Pleri credentials",
|
|
13270
13300
|
"PLERI_BASE_URL=https://pleri.dev/api",
|
|
@@ -13272,7 +13302,7 @@ function registerInit(program2) {
|
|
|
13272
13302
|
"PLERI_API_KEY=",
|
|
13273
13303
|
""
|
|
13274
13304
|
].join("\n");
|
|
13275
|
-
|
|
13305
|
+
fs6.writeFileSync(path6.join(olamDir, ".env.example"), envExample);
|
|
13276
13306
|
printHeader("Olam initialized");
|
|
13277
13307
|
printInfo("Config", `${olamDir}/config.yaml`);
|
|
13278
13308
|
printInfo("Project", `${projectType} (detected)`);
|
|
@@ -13297,9 +13327,9 @@ ${pc3.dim(`Next: olam create --name my-world --workspace ${repoName} --task "...
|
|
|
13297
13327
|
}
|
|
13298
13328
|
|
|
13299
13329
|
// src/commands/install.ts
|
|
13300
|
-
import * as
|
|
13330
|
+
import * as fs7 from "node:fs";
|
|
13301
13331
|
import * as os3 from "node:os";
|
|
13302
|
-
import * as
|
|
13332
|
+
import * as path7 from "node:path";
|
|
13303
13333
|
import pc4 from "picocolors";
|
|
13304
13334
|
import { stringify as stringifyYaml3 } from "yaml";
|
|
13305
13335
|
|
|
@@ -13442,11 +13472,11 @@ function walk(name, acc, stack) {
|
|
|
13442
13472
|
|
|
13443
13473
|
// src/commands/install.ts
|
|
13444
13474
|
init_output();
|
|
13445
|
-
var ROLE_FILE_PATH =
|
|
13475
|
+
var ROLE_FILE_PATH = path7.join(os3.homedir(), ".olam", "role.yaml");
|
|
13446
13476
|
function readRoleFile() {
|
|
13447
|
-
if (!
|
|
13477
|
+
if (!fs7.existsSync(ROLE_FILE_PATH)) return null;
|
|
13448
13478
|
try {
|
|
13449
|
-
const raw =
|
|
13479
|
+
const raw = fs7.readFileSync(ROLE_FILE_PATH, "utf-8");
|
|
13450
13480
|
const m = /archetype:\s*(\S+)/.exec(raw);
|
|
13451
13481
|
if (!m) return null;
|
|
13452
13482
|
const archetype = m[1];
|
|
@@ -13466,13 +13496,13 @@ function readRoleFile() {
|
|
|
13466
13496
|
}
|
|
13467
13497
|
}
|
|
13468
13498
|
function writeRoleFile(role) {
|
|
13469
|
-
|
|
13499
|
+
fs7.mkdirSync(path7.dirname(ROLE_FILE_PATH), { recursive: true });
|
|
13470
13500
|
const yaml = stringifyYaml3({
|
|
13471
13501
|
archetype: role.archetype,
|
|
13472
13502
|
customCapabilities: [...role.customCapabilities],
|
|
13473
13503
|
installedAt: role.installedAt
|
|
13474
13504
|
});
|
|
13475
|
-
|
|
13505
|
+
fs7.writeFileSync(ROLE_FILE_PATH, yaml, { mode: 420 });
|
|
13476
13506
|
}
|
|
13477
13507
|
function nextStepsFor(archetype) {
|
|
13478
13508
|
switch (archetype) {
|
|
@@ -13613,21 +13643,21 @@ import * as readline from "node:readline/promises";
|
|
|
13613
13643
|
import { spawn as spawn3 } from "node:child_process";
|
|
13614
13644
|
|
|
13615
13645
|
// src/commands/auth-status.ts
|
|
13616
|
-
import * as
|
|
13646
|
+
import * as fs9 from "node:fs";
|
|
13617
13647
|
import * as os5 from "node:os";
|
|
13618
|
-
import * as
|
|
13648
|
+
import * as path10 from "node:path";
|
|
13619
13649
|
import pc5 from "picocolors";
|
|
13620
13650
|
init_auth();
|
|
13621
13651
|
init_output();
|
|
13622
13652
|
init_exit_codes();
|
|
13623
|
-
var LOCAL_DATA_DIR =
|
|
13653
|
+
var LOCAL_DATA_DIR = path10.join(os5.homedir(), ".olam", "auth-data");
|
|
13624
13654
|
|
|
13625
13655
|
// src/commands/auth-upgrade.ts
|
|
13626
13656
|
init_output();
|
|
13627
13657
|
init_host_cp();
|
|
13628
13658
|
init_auth();
|
|
13629
|
-
import * as
|
|
13630
|
-
import * as
|
|
13659
|
+
import * as fs21 from "node:fs";
|
|
13660
|
+
import * as path24 from "node:path";
|
|
13631
13661
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
13632
13662
|
import ora2 from "ora";
|
|
13633
13663
|
import pc7 from "picocolors";
|
|
@@ -13638,20 +13668,20 @@ init_exit_codes();
|
|
|
13638
13668
|
init_protocol_version();
|
|
13639
13669
|
init_output();
|
|
13640
13670
|
import { spawn as spawn2, spawnSync as spawnSync6 } from "node:child_process";
|
|
13641
|
-
import { existsSync as
|
|
13642
|
-
import { join as
|
|
13671
|
+
import { existsSync as existsSync20, readFileSync as readFileSync16 } from "node:fs";
|
|
13672
|
+
import { join as join26 } from "node:path";
|
|
13643
13673
|
import ora from "ora";
|
|
13644
13674
|
import pc6 from "picocolors";
|
|
13645
13675
|
function loadImageDigests(installRootDir = installRoot()) {
|
|
13646
|
-
const digestsPath =
|
|
13647
|
-
if (!
|
|
13676
|
+
const digestsPath = join26(installRootDir, "dist", "image-digests.json");
|
|
13677
|
+
if (!existsSync20(digestsPath)) {
|
|
13648
13678
|
throw new Error(
|
|
13649
13679
|
`image-digests.json missing at ${digestsPath}. Re-run \`npm install -g @pleri/olam-cli@<version>\` to refresh the tarball.`
|
|
13650
13680
|
);
|
|
13651
13681
|
}
|
|
13652
13682
|
let parsed;
|
|
13653
13683
|
try {
|
|
13654
|
-
parsed = JSON.parse(
|
|
13684
|
+
parsed = JSON.parse(readFileSync16(digestsPath, "utf8"));
|
|
13655
13685
|
} catch (err) {
|
|
13656
13686
|
throw new Error(`image-digests.json is not valid JSON: ${err.message}`);
|
|
13657
13687
|
}
|
|
@@ -13968,8 +13998,8 @@ function parseAuthUpgradeOpts(raw) {
|
|
|
13968
13998
|
};
|
|
13969
13999
|
}
|
|
13970
14000
|
function validateAuthRepoRoot(cwd) {
|
|
13971
|
-
const marker =
|
|
13972
|
-
if (!
|
|
14001
|
+
const marker = path24.join(cwd, "packages/auth-service/Dockerfile");
|
|
14002
|
+
if (!fs21.existsSync(marker)) {
|
|
13973
14003
|
return {
|
|
13974
14004
|
ok: false,
|
|
13975
14005
|
error: `Not an olam repo root (expected ${marker}).
|
|
@@ -14703,15 +14733,15 @@ ${pc9.dim("Next: olam create --name my-world")}`);
|
|
|
14703
14733
|
// src/commands/create.ts
|
|
14704
14734
|
init_manager();
|
|
14705
14735
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
14706
|
-
import { existsSync as
|
|
14707
|
-
import { dirname as
|
|
14736
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
14737
|
+
import { dirname as dirname15, resolve as resolve7 } from "node:path";
|
|
14708
14738
|
import ora3 from "ora";
|
|
14709
14739
|
import pc10 from "picocolors";
|
|
14710
14740
|
|
|
14711
14741
|
// ../core/dist/world/devbox-freshness.js
|
|
14712
14742
|
import { execSync as execSync6 } from "node:child_process";
|
|
14713
|
-
import { existsSync as
|
|
14714
|
-
import { join as
|
|
14743
|
+
import { existsSync as existsSync22, statSync as statSync5 } from "node:fs";
|
|
14744
|
+
import { join as join28 } from "node:path";
|
|
14715
14745
|
var DEFAULT_DEVBOX_IMAGE = "olam-devbox:latest";
|
|
14716
14746
|
var DEVBOX_BAKED_SOURCES = [
|
|
14717
14747
|
"packages/adapters/src/docker/devbox.Dockerfile",
|
|
@@ -14747,7 +14777,7 @@ function getDevboxFreshness(deps) {
|
|
|
14747
14777
|
}
|
|
14748
14778
|
const newerSources = [];
|
|
14749
14779
|
for (const relPath of DEVBOX_BAKED_SOURCES) {
|
|
14750
|
-
const absPath =
|
|
14780
|
+
const absPath = join28(deps.repoRoot, relPath);
|
|
14751
14781
|
const mtimeMs = statMtime(absPath);
|
|
14752
14782
|
if (mtimeMs === null)
|
|
14753
14783
|
continue;
|
|
@@ -14800,7 +14830,7 @@ function defaultDockerInspect(image) {
|
|
|
14800
14830
|
}
|
|
14801
14831
|
function defaultStatMtime(absPath) {
|
|
14802
14832
|
try {
|
|
14803
|
-
if (!
|
|
14833
|
+
if (!existsSync22(absPath))
|
|
14804
14834
|
return null;
|
|
14805
14835
|
return statSync5(absPath).mtimeMs;
|
|
14806
14836
|
} catch {
|
|
@@ -15296,10 +15326,10 @@ ${pc10.cyan("Host CP UI:")} ${worldUrl}`);
|
|
|
15296
15326
|
function resolveRepoRoot(start) {
|
|
15297
15327
|
let cur = start;
|
|
15298
15328
|
while (true) {
|
|
15299
|
-
if (
|
|
15329
|
+
if (existsSync23(resolve7(cur, "packages")) && existsSync23(resolve7(cur, "package.json"))) {
|
|
15300
15330
|
return cur;
|
|
15301
15331
|
}
|
|
15302
|
-
const parent =
|
|
15332
|
+
const parent = dirname15(cur);
|
|
15303
15333
|
if (parent === cur) return start;
|
|
15304
15334
|
cur = parent;
|
|
15305
15335
|
}
|
|
@@ -15527,9 +15557,9 @@ function registerList(program2) {
|
|
|
15527
15557
|
|
|
15528
15558
|
// src/commands/status.ts
|
|
15529
15559
|
init_output();
|
|
15530
|
-
import * as
|
|
15560
|
+
import * as fs23 from "node:fs";
|
|
15531
15561
|
import * as os13 from "node:os";
|
|
15532
|
-
import * as
|
|
15562
|
+
import * as path26 from "node:path";
|
|
15533
15563
|
var CLI_VERSION2 = process.env["OLAM_CLI_VERSION"] ?? "0.0.0";
|
|
15534
15564
|
var HOST_CP_PORT2 = 19e3;
|
|
15535
15565
|
async function getMachineStatus(_probe, _loadCtx, _readToken) {
|
|
@@ -15559,14 +15589,14 @@ async function getMachineStatus(_probe, _loadCtx, _readToken) {
|
|
|
15559
15589
|
}
|
|
15560
15590
|
} catch {
|
|
15561
15591
|
}
|
|
15562
|
-
const manifestPath2 =
|
|
15592
|
+
const manifestPath2 = path26.join(os13.homedir(), ".olam", "cache", "manifest.json");
|
|
15563
15593
|
let updateAvailable = null;
|
|
15564
15594
|
let lastUpdateCheck = null;
|
|
15565
|
-
if (
|
|
15566
|
-
const mtime =
|
|
15595
|
+
if (fs23.existsSync(manifestPath2)) {
|
|
15596
|
+
const mtime = fs23.statSync(manifestPath2).mtime;
|
|
15567
15597
|
lastUpdateCheck = mtime.toISOString();
|
|
15568
15598
|
try {
|
|
15569
|
-
const manifest = JSON.parse(
|
|
15599
|
+
const manifest = JSON.parse(fs23.readFileSync(manifestPath2, "utf-8"));
|
|
15570
15600
|
const latest = manifest["version"];
|
|
15571
15601
|
updateAvailable = latest !== void 0 && latest !== CLI_VERSION2;
|
|
15572
15602
|
} catch {
|
|
@@ -15689,9 +15719,9 @@ function registerDestroy(program2) {
|
|
|
15689
15719
|
// src/commands/clean.ts
|
|
15690
15720
|
init_context();
|
|
15691
15721
|
init_output();
|
|
15692
|
-
import
|
|
15722
|
+
import fs24 from "node:fs";
|
|
15693
15723
|
import os14 from "node:os";
|
|
15694
|
-
import
|
|
15724
|
+
import path27 from "node:path";
|
|
15695
15725
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
15696
15726
|
function registerClean(program2) {
|
|
15697
15727
|
program2.command("clean").description("Reap orphan world filesystem state under ~/.olam/worlds/").option("--apply", "Actually delete the orphans (default is dry-run)", false).option(
|
|
@@ -15715,8 +15745,8 @@ async function runClean(opts) {
|
|
|
15715
15745
|
printError(error?.message ?? "Olam is not configured. Run `olam init` first.");
|
|
15716
15746
|
return 1;
|
|
15717
15747
|
}
|
|
15718
|
-
const worldsDir =
|
|
15719
|
-
if (!
|
|
15748
|
+
const worldsDir = path27.join(os14.homedir(), ".olam", "worlds");
|
|
15749
|
+
if (!fs24.existsSync(worldsDir)) {
|
|
15720
15750
|
if (opts.json) {
|
|
15721
15751
|
process.stdout.write(`${JSON.stringify({ worldsDir, entries: [] })}
|
|
15722
15752
|
`);
|
|
@@ -15731,8 +15761,8 @@ async function runClean(opts) {
|
|
|
15731
15761
|
}
|
|
15732
15762
|
const worktreeMap = collectWorktrees(worldsDir);
|
|
15733
15763
|
const entries = [];
|
|
15734
|
-
for (const id of
|
|
15735
|
-
const fullPath =
|
|
15764
|
+
for (const id of fs24.readdirSync(worldsDir).sort()) {
|
|
15765
|
+
const fullPath = path27.join(worldsDir, id);
|
|
15736
15766
|
const stat = safeStat(fullPath);
|
|
15737
15767
|
if (!stat || !stat.isDirectory()) continue;
|
|
15738
15768
|
entries.push(classifyWorld({ id, fullPath, liveIds, worktreeMap }));
|
|
@@ -15798,7 +15828,7 @@ function classifyWorld(args) {
|
|
|
15798
15828
|
if (liveIds.has(id)) {
|
|
15799
15829
|
return { id, path: fullPath, bytes, category: "active", note: "in registry" };
|
|
15800
15830
|
}
|
|
15801
|
-
const worktreeChild =
|
|
15831
|
+
const worktreeChild = path27.join(fullPath, "olam");
|
|
15802
15832
|
const worktreeInfo = worktreeMap.get(worktreeChild);
|
|
15803
15833
|
if (worktreeInfo) {
|
|
15804
15834
|
if (worktreeInfo.dirty > 0 || worktreeInfo.unpushed > 0) {
|
|
@@ -15844,20 +15874,20 @@ function reapEntry(entry) {
|
|
|
15844
15874
|
}
|
|
15845
15875
|
}
|
|
15846
15876
|
try {
|
|
15847
|
-
|
|
15877
|
+
fs24.rmSync(entry.path, { recursive: true, force: true });
|
|
15848
15878
|
} catch (err) {
|
|
15849
15879
|
process.stderr.write(` ! rm ${entry.path}: ${err instanceof Error ? err.message : String(err)}
|
|
15850
15880
|
`);
|
|
15851
15881
|
return false;
|
|
15852
15882
|
}
|
|
15853
|
-
return !
|
|
15883
|
+
return !fs24.existsSync(entry.path);
|
|
15854
15884
|
}
|
|
15855
15885
|
function collectWorktrees(worldsDir) {
|
|
15856
15886
|
const out = /* @__PURE__ */ new Map();
|
|
15857
|
-
for (const id of
|
|
15858
|
-
const child =
|
|
15859
|
-
const gitMarker =
|
|
15860
|
-
if (!
|
|
15887
|
+
for (const id of fs24.readdirSync(worldsDir)) {
|
|
15888
|
+
const child = path27.join(worldsDir, id, "olam");
|
|
15889
|
+
const gitMarker = path27.join(child, ".git");
|
|
15890
|
+
if (!fs24.existsSync(gitMarker)) continue;
|
|
15861
15891
|
const gitDir = resolveGitDirForWorktree(child);
|
|
15862
15892
|
if (!gitDir) continue;
|
|
15863
15893
|
const branch = readBranch(child);
|
|
@@ -15868,7 +15898,7 @@ function collectWorktrees(worldsDir) {
|
|
|
15868
15898
|
return out;
|
|
15869
15899
|
}
|
|
15870
15900
|
function resolveGitDirForWorktree(worktreePath) {
|
|
15871
|
-
const gitMarker =
|
|
15901
|
+
const gitMarker = path27.join(worktreePath, ".git");
|
|
15872
15902
|
try {
|
|
15873
15903
|
const top = execFileSync5("git", ["rev-parse", "--show-toplevel"], {
|
|
15874
15904
|
cwd: worktreePath,
|
|
@@ -15882,7 +15912,7 @@ function resolveGitDirForWorktree(worktreePath) {
|
|
|
15882
15912
|
stdio: "pipe"
|
|
15883
15913
|
}).trim();
|
|
15884
15914
|
if (!common) return top;
|
|
15885
|
-
return
|
|
15915
|
+
return path27.dirname(path27.resolve(worktreePath, common));
|
|
15886
15916
|
} catch {
|
|
15887
15917
|
return null;
|
|
15888
15918
|
}
|
|
@@ -15925,7 +15955,7 @@ function countUnpushed(worktreePath) {
|
|
|
15925
15955
|
}
|
|
15926
15956
|
function safeStat(p) {
|
|
15927
15957
|
try {
|
|
15928
|
-
return
|
|
15958
|
+
return fs24.statSync(p);
|
|
15929
15959
|
} catch {
|
|
15930
15960
|
return null;
|
|
15931
15961
|
}
|
|
@@ -15937,7 +15967,7 @@ function computeBytes(p) {
|
|
|
15937
15967
|
const cur = stack.pop();
|
|
15938
15968
|
let st;
|
|
15939
15969
|
try {
|
|
15940
|
-
st =
|
|
15970
|
+
st = fs24.lstatSync(cur);
|
|
15941
15971
|
} catch {
|
|
15942
15972
|
continue;
|
|
15943
15973
|
}
|
|
@@ -15945,11 +15975,11 @@ function computeBytes(p) {
|
|
|
15945
15975
|
if (st.isDirectory()) {
|
|
15946
15976
|
let entries;
|
|
15947
15977
|
try {
|
|
15948
|
-
entries =
|
|
15978
|
+
entries = fs24.readdirSync(cur);
|
|
15949
15979
|
} catch {
|
|
15950
15980
|
continue;
|
|
15951
15981
|
}
|
|
15952
|
-
for (const name of entries) stack.push(
|
|
15982
|
+
for (const name of entries) stack.push(path27.join(cur, name));
|
|
15953
15983
|
} else {
|
|
15954
15984
|
total += st.size;
|
|
15955
15985
|
}
|
|
@@ -16157,7 +16187,7 @@ init_context();
|
|
|
16157
16187
|
init_output();
|
|
16158
16188
|
init_exit_codes();
|
|
16159
16189
|
init_world_paths();
|
|
16160
|
-
import * as
|
|
16190
|
+
import * as fs25 from "node:fs";
|
|
16161
16191
|
import "node:path";
|
|
16162
16192
|
import ora6 from "ora";
|
|
16163
16193
|
function registerCrystallize(program2, options = {}) {
|
|
@@ -16189,7 +16219,7 @@ function registerCrystallize(program2, options = {}) {
|
|
|
16189
16219
|
return;
|
|
16190
16220
|
}
|
|
16191
16221
|
const thoughtDbPath = getWorldDbPath(world.workspacePath);
|
|
16192
|
-
if (!
|
|
16222
|
+
if (!fs25.existsSync(thoughtDbPath)) {
|
|
16193
16223
|
printError(`No thoughts captured yet for "${worldId}". Run a dispatch first.`);
|
|
16194
16224
|
process.exitCode = EXIT_GENERIC_ERROR;
|
|
16195
16225
|
return;
|
|
@@ -17563,11 +17593,11 @@ var qmarksTestNoExtDot = ([$0]) => {
|
|
|
17563
17593
|
return (f) => f.length === len && f !== "." && f !== "..";
|
|
17564
17594
|
};
|
|
17565
17595
|
var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
|
|
17566
|
-
var
|
|
17596
|
+
var path29 = {
|
|
17567
17597
|
win32: { sep: "\\" },
|
|
17568
17598
|
posix: { sep: "/" }
|
|
17569
17599
|
};
|
|
17570
|
-
var sep = defaultPlatform === "win32" ?
|
|
17600
|
+
var sep = defaultPlatform === "win32" ? path29.win32.sep : path29.posix.sep;
|
|
17571
17601
|
minimatch.sep = sep;
|
|
17572
17602
|
var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
|
|
17573
17603
|
minimatch.GLOBSTAR = GLOBSTAR;
|
|
@@ -18395,23 +18425,23 @@ function registerPolicyCheck(program2) {
|
|
|
18395
18425
|
// src/commands/upgrade.ts
|
|
18396
18426
|
init_output();
|
|
18397
18427
|
init_host_cp();
|
|
18398
|
-
import * as
|
|
18399
|
-
import * as
|
|
18428
|
+
import * as fs28 from "node:fs";
|
|
18429
|
+
import * as path32 from "node:path";
|
|
18400
18430
|
import { spawnSync as spawnSync11 } from "node:child_process";
|
|
18401
18431
|
import ora7 from "ora";
|
|
18402
18432
|
import pc17 from "picocolors";
|
|
18403
18433
|
|
|
18404
18434
|
// src/commands/upgrade-lock.ts
|
|
18405
|
-
import * as
|
|
18435
|
+
import * as fs26 from "node:fs";
|
|
18406
18436
|
import * as os15 from "node:os";
|
|
18407
|
-
import * as
|
|
18437
|
+
import * as path30 from "node:path";
|
|
18408
18438
|
import { spawnSync as spawnSync10 } from "node:child_process";
|
|
18409
|
-
var LOCK_FILE_PATH =
|
|
18439
|
+
var LOCK_FILE_PATH = path30.join(os15.homedir(), ".olam", ".upgrade.lock");
|
|
18410
18440
|
var STALE_LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
18411
18441
|
function readLockFile(lockPath) {
|
|
18412
18442
|
try {
|
|
18413
|
-
if (!
|
|
18414
|
-
const raw =
|
|
18443
|
+
if (!fs26.existsSync(lockPath)) return null;
|
|
18444
|
+
const raw = fs26.readFileSync(lockPath, "utf-8").trim();
|
|
18415
18445
|
if (raw.length === 0) return null;
|
|
18416
18446
|
const parsed = JSON.parse(raw);
|
|
18417
18447
|
if (typeof parsed.pid !== "number" || typeof parsed.startTs !== "number") return null;
|
|
@@ -18456,16 +18486,16 @@ function isStaleLock(content, nowMs = Date.now()) {
|
|
|
18456
18486
|
return false;
|
|
18457
18487
|
}
|
|
18458
18488
|
function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
|
|
18459
|
-
const dir =
|
|
18460
|
-
|
|
18489
|
+
const dir = path30.dirname(lockPath);
|
|
18490
|
+
fs26.mkdirSync(dir, { recursive: true });
|
|
18461
18491
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
18462
18492
|
try {
|
|
18463
|
-
const fd =
|
|
18493
|
+
const fd = fs26.openSync(lockPath, "wx", 420);
|
|
18464
18494
|
try {
|
|
18465
18495
|
const content = { pid: process.pid, startTs: nowMs };
|
|
18466
|
-
|
|
18496
|
+
fs26.writeSync(fd, JSON.stringify(content));
|
|
18467
18497
|
} finally {
|
|
18468
|
-
|
|
18498
|
+
fs26.closeSync(fd);
|
|
18469
18499
|
}
|
|
18470
18500
|
return { acquired: true, lockPath };
|
|
18471
18501
|
} catch (err) {
|
|
@@ -18474,7 +18504,7 @@ function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
|
|
|
18474
18504
|
const existing2 = readLockFile(lockPath);
|
|
18475
18505
|
if (isStaleLock(existing2, nowMs)) {
|
|
18476
18506
|
try {
|
|
18477
|
-
|
|
18507
|
+
fs26.unlinkSync(lockPath);
|
|
18478
18508
|
} catch (unlinkErr) {
|
|
18479
18509
|
const ucode = unlinkErr.code;
|
|
18480
18510
|
if (ucode !== "ENOENT") throw unlinkErr;
|
|
@@ -18499,7 +18529,7 @@ function acquireLock(lockPath = LOCK_FILE_PATH, nowMs = Date.now()) {
|
|
|
18499
18529
|
}
|
|
18500
18530
|
function releaseLock(lockPath = LOCK_FILE_PATH) {
|
|
18501
18531
|
try {
|
|
18502
|
-
|
|
18532
|
+
fs26.unlinkSync(lockPath);
|
|
18503
18533
|
} catch (err) {
|
|
18504
18534
|
const code = err.code;
|
|
18505
18535
|
if (code !== "ENOENT") throw err;
|
|
@@ -18517,19 +18547,19 @@ function formatRefusalMessage(result, lockPath = LOCK_FILE_PATH) {
|
|
|
18517
18547
|
}
|
|
18518
18548
|
|
|
18519
18549
|
// src/commands/upgrade-log.ts
|
|
18520
|
-
import * as
|
|
18550
|
+
import * as fs27 from "node:fs";
|
|
18521
18551
|
import * as os16 from "node:os";
|
|
18522
|
-
import * as
|
|
18552
|
+
import * as path31 from "node:path";
|
|
18523
18553
|
function getUpgradeLogPath() {
|
|
18524
18554
|
const home = process.env["HOME"] ?? os16.homedir();
|
|
18525
|
-
return
|
|
18555
|
+
return path31.join(home, ".olam", "upgrade.log");
|
|
18526
18556
|
}
|
|
18527
18557
|
var UPGRADE_LOG_PATH = getUpgradeLogPath();
|
|
18528
18558
|
function appendUpgradeLog(row, logPath = getUpgradeLogPath()) {
|
|
18529
18559
|
try {
|
|
18530
|
-
|
|
18560
|
+
fs27.mkdirSync(path31.dirname(logPath), { recursive: true });
|
|
18531
18561
|
const line = JSON.stringify(row) + "\n";
|
|
18532
|
-
|
|
18562
|
+
fs27.appendFileSync(logPath, line, { mode: 420 });
|
|
18533
18563
|
} catch (err) {
|
|
18534
18564
|
process.stderr.write(
|
|
18535
18565
|
`[upgrade-log] failed to append: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -18538,10 +18568,10 @@ function appendUpgradeLog(row, logPath = getUpgradeLogPath()) {
|
|
|
18538
18568
|
}
|
|
18539
18569
|
}
|
|
18540
18570
|
function readUpgradeLog(limit = 10, logPath = getUpgradeLogPath()) {
|
|
18541
|
-
if (!
|
|
18571
|
+
if (!fs27.existsSync(logPath)) return [];
|
|
18542
18572
|
let raw;
|
|
18543
18573
|
try {
|
|
18544
|
-
raw =
|
|
18574
|
+
raw = fs27.readFileSync(logPath, "utf-8");
|
|
18545
18575
|
} catch (err) {
|
|
18546
18576
|
process.stderr.write(
|
|
18547
18577
|
`[upgrade-log] failed to read: ${err instanceof Error ? err.message : String(err)}
|
|
@@ -18634,12 +18664,12 @@ init_protocol_version();
|
|
|
18634
18664
|
init_install_root();
|
|
18635
18665
|
var AUTH_HEALTH_URL2 = "http://127.0.0.1:9999/health";
|
|
18636
18666
|
function isNodeModulesInSync(cwd) {
|
|
18637
|
-
const lockPath =
|
|
18638
|
-
const markerPath =
|
|
18639
|
-
if (!
|
|
18667
|
+
const lockPath = path32.join(cwd, "package-lock.json");
|
|
18668
|
+
const markerPath = path32.join(cwd, "node_modules", ".package-lock.json");
|
|
18669
|
+
if (!fs28.existsSync(lockPath) || !fs28.existsSync(markerPath)) return false;
|
|
18640
18670
|
try {
|
|
18641
|
-
const lockStat =
|
|
18642
|
-
const markerStat =
|
|
18671
|
+
const lockStat = fs28.statSync(lockPath);
|
|
18672
|
+
const markerStat = fs28.statSync(markerPath);
|
|
18643
18673
|
return markerStat.mtimeMs >= lockStat.mtimeMs;
|
|
18644
18674
|
} catch {
|
|
18645
18675
|
return false;
|
|
@@ -18655,8 +18685,8 @@ function shouldSkipInstall(opts, cwd) {
|
|
|
18655
18685
|
return { skip: false };
|
|
18656
18686
|
}
|
|
18657
18687
|
function validateRepoRoot(cwd) {
|
|
18658
|
-
const marker =
|
|
18659
|
-
if (!
|
|
18688
|
+
const marker = path32.join(cwd, "packages/host-cp/compose.yaml");
|
|
18689
|
+
if (!fs28.existsSync(marker)) {
|
|
18660
18690
|
return {
|
|
18661
18691
|
ok: false,
|
|
18662
18692
|
error: `Not an olam repo root (expected ${marker}).
|
|
@@ -19012,9 +19042,9 @@ async function recreateAuthService() {
|
|
|
19012
19042
|
}
|
|
19013
19043
|
}
|
|
19014
19044
|
function readBundleHash(cwd) {
|
|
19015
|
-
const indexPath =
|
|
19016
|
-
if (!
|
|
19017
|
-
return extractBundleHash(
|
|
19045
|
+
const indexPath = path32.join(cwd, "packages/control-plane/public/index.html");
|
|
19046
|
+
if (!fs28.existsSync(indexPath)) return null;
|
|
19047
|
+
return extractBundleHash(fs28.readFileSync(indexPath, "utf-8"));
|
|
19018
19048
|
}
|
|
19019
19049
|
async function runUpgradePullByDigest(deps = {}) {
|
|
19020
19050
|
const docker2 = deps.docker ?? realDocker;
|
|
@@ -19514,7 +19544,7 @@ ${buildResult.stderr}`);
|
|
|
19514
19544
|
return;
|
|
19515
19545
|
}
|
|
19516
19546
|
const authSecret = readAuthSecret2();
|
|
19517
|
-
const spaDir =
|
|
19547
|
+
const spaDir = path32.join(cwd, "packages/control-plane/app");
|
|
19518
19548
|
const spaResult = runStep2(
|
|
19519
19549
|
"vite build (SPA)",
|
|
19520
19550
|
"npx",
|
|
@@ -20048,20 +20078,20 @@ ${pc19.dim(`world: ${worldId} sort: ${sortKey} refresh: 5s Ctrl-C to exit`)}
|
|
|
20048
20078
|
|
|
20049
20079
|
// src/commands/keys.ts
|
|
20050
20080
|
init_output();
|
|
20051
|
-
import * as
|
|
20081
|
+
import * as fs29 from "node:fs";
|
|
20052
20082
|
import * as os17 from "node:os";
|
|
20053
|
-
import * as
|
|
20083
|
+
import * as path33 from "node:path";
|
|
20054
20084
|
import YAML4 from "yaml";
|
|
20055
20085
|
function olamHome2() {
|
|
20056
|
-
return process.env.OLAM_HOME ??
|
|
20086
|
+
return process.env.OLAM_HOME ?? path33.join(os17.homedir(), ".olam");
|
|
20057
20087
|
}
|
|
20058
20088
|
function keysFilePath() {
|
|
20059
|
-
return
|
|
20089
|
+
return path33.join(olamHome2(), "keys.yaml");
|
|
20060
20090
|
}
|
|
20061
20091
|
function readKeysFile() {
|
|
20062
20092
|
const filePath = keysFilePath();
|
|
20063
|
-
if (!
|
|
20064
|
-
const raw =
|
|
20093
|
+
if (!fs29.existsSync(filePath)) return null;
|
|
20094
|
+
const raw = fs29.readFileSync(filePath, "utf-8").trim();
|
|
20065
20095
|
if (raw.length === 0) return null;
|
|
20066
20096
|
try {
|
|
20067
20097
|
const parsed = YAML4.parse(raw);
|
|
@@ -20077,13 +20107,13 @@ function readKeysFile() {
|
|
|
20077
20107
|
}
|
|
20078
20108
|
function writeKeysFile(keys) {
|
|
20079
20109
|
const dir = olamHome2();
|
|
20080
|
-
if (!
|
|
20081
|
-
|
|
20110
|
+
if (!fs29.existsSync(dir)) {
|
|
20111
|
+
fs29.mkdirSync(dir, { recursive: true });
|
|
20082
20112
|
}
|
|
20083
20113
|
const filePath = keysFilePath();
|
|
20084
20114
|
const content = YAML4.stringify(keys);
|
|
20085
|
-
|
|
20086
|
-
|
|
20115
|
+
fs29.writeFileSync(filePath, content, { encoding: "utf-8", mode: 384 });
|
|
20116
|
+
fs29.chmodSync(filePath, 384);
|
|
20087
20117
|
}
|
|
20088
20118
|
function redact(value) {
|
|
20089
20119
|
if (value.length <= 8) return value + "...";
|
|
@@ -20126,7 +20156,7 @@ function registerKeys(program2) {
|
|
|
20126
20156
|
}
|
|
20127
20157
|
const { [key]: _removed, ...rest } = existing;
|
|
20128
20158
|
if (Object.keys(rest).length === 0) {
|
|
20129
|
-
|
|
20159
|
+
fs29.unlinkSync(keysFilePath());
|
|
20130
20160
|
} else {
|
|
20131
20161
|
writeKeysFile(rest);
|
|
20132
20162
|
}
|
|
@@ -20149,26 +20179,26 @@ function registerKeys(program2) {
|
|
|
20149
20179
|
}
|
|
20150
20180
|
|
|
20151
20181
|
// src/commands/world-snapshot.ts
|
|
20152
|
-
import * as
|
|
20153
|
-
import * as
|
|
20182
|
+
import * as fs31 from "node:fs";
|
|
20183
|
+
import * as path35 from "node:path";
|
|
20154
20184
|
import { execSync as execSync9 } from "node:child_process";
|
|
20155
20185
|
import pc20 from "picocolors";
|
|
20156
20186
|
|
|
20157
20187
|
// ../core/dist/world/snapshot.js
|
|
20158
20188
|
import * as crypto6 from "node:crypto";
|
|
20159
|
-
import * as
|
|
20189
|
+
import * as fs30 from "node:fs";
|
|
20160
20190
|
import * as os18 from "node:os";
|
|
20161
|
-
import * as
|
|
20191
|
+
import * as path34 from "node:path";
|
|
20162
20192
|
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
20163
20193
|
function snapshotsDir() {
|
|
20164
|
-
return process.env["OLAM_SNAPSHOTS_DIR"] ??
|
|
20194
|
+
return process.env["OLAM_SNAPSHOTS_DIR"] ?? path34.join(os18.homedir(), ".olam", "snapshots");
|
|
20165
20195
|
}
|
|
20166
20196
|
function snapshotKindDir(worldId, kind) {
|
|
20167
|
-
return
|
|
20197
|
+
return path34.join(snapshotsDir(), worldId, kind);
|
|
20168
20198
|
}
|
|
20169
20199
|
function snapshotTarPath(worldId, kind, repoName, hash) {
|
|
20170
20200
|
const base = repoName ? `${repoName}-${hash}` : hash;
|
|
20171
|
-
return
|
|
20201
|
+
return path34.join(snapshotKindDir(worldId, kind), `${base}.tar.gz`);
|
|
20172
20202
|
}
|
|
20173
20203
|
function manifestPath(tarPath) {
|
|
20174
20204
|
return tarPath.replace(/\.tar\.gz$/, ".manifest.json");
|
|
@@ -20185,17 +20215,17 @@ function hashBuffers(entries) {
|
|
|
20185
20215
|
return hash.digest("hex").slice(0, 12);
|
|
20186
20216
|
}
|
|
20187
20217
|
function computeGemsFingerprint(repoDir) {
|
|
20188
|
-
const lockfile =
|
|
20189
|
-
if (!
|
|
20218
|
+
const lockfile = path34.join(repoDir, "Gemfile.lock");
|
|
20219
|
+
if (!fs30.existsSync(lockfile))
|
|
20190
20220
|
return null;
|
|
20191
|
-
return hashBuffers([{ path: "Gemfile.lock", content:
|
|
20221
|
+
return hashBuffers([{ path: "Gemfile.lock", content: fs30.readFileSync(lockfile) }]);
|
|
20192
20222
|
}
|
|
20193
20223
|
function computeNodeFingerprint(repoDir) {
|
|
20194
20224
|
const candidates = ["yarn.lock", "pnpm-lock.yaml", "package-lock.json"];
|
|
20195
20225
|
for (const name of candidates) {
|
|
20196
|
-
const lockfile =
|
|
20197
|
-
if (
|
|
20198
|
-
return hashBuffers([{ path: name, content:
|
|
20226
|
+
const lockfile = path34.join(repoDir, name);
|
|
20227
|
+
if (fs30.existsSync(lockfile)) {
|
|
20228
|
+
return hashBuffers([{ path: name, content: fs30.readFileSync(lockfile) }]);
|
|
20199
20229
|
}
|
|
20200
20230
|
}
|
|
20201
20231
|
return null;
|
|
@@ -20205,16 +20235,16 @@ function computePgFingerprint(repoDirs) {
|
|
|
20205
20235
|
const entries = [];
|
|
20206
20236
|
for (const repoDir of repoDirs) {
|
|
20207
20237
|
for (const pattern of patterns) {
|
|
20208
|
-
const filePath =
|
|
20209
|
-
if (
|
|
20210
|
-
entries.push({ path: filePath, content:
|
|
20238
|
+
const filePath = path34.join(repoDir, pattern);
|
|
20239
|
+
if (fs30.existsSync(filePath)) {
|
|
20240
|
+
entries.push({ path: filePath, content: fs30.readFileSync(filePath) });
|
|
20211
20241
|
}
|
|
20212
20242
|
}
|
|
20213
20243
|
}
|
|
20214
20244
|
return entries.length > 0 ? hashBuffers(entries) : null;
|
|
20215
20245
|
}
|
|
20216
20246
|
function packTarball(srcDir, destPath, opts = {}) {
|
|
20217
|
-
|
|
20247
|
+
fs30.mkdirSync(path34.dirname(destPath), { recursive: true });
|
|
20218
20248
|
const tmp = `${destPath}.tmp`;
|
|
20219
20249
|
const args = [];
|
|
20220
20250
|
if (opts.followSymlinks)
|
|
@@ -20222,47 +20252,47 @@ function packTarball(srcDir, destPath, opts = {}) {
|
|
|
20222
20252
|
args.push("-czf", tmp, "-C", srcDir, ".");
|
|
20223
20253
|
try {
|
|
20224
20254
|
execFileSync6("tar", args, { stdio: "pipe" });
|
|
20225
|
-
|
|
20255
|
+
fs30.renameSync(tmp, destPath);
|
|
20226
20256
|
} catch (err) {
|
|
20227
20257
|
try {
|
|
20228
|
-
|
|
20258
|
+
fs30.rmSync(tmp, { force: true });
|
|
20229
20259
|
} catch {
|
|
20230
20260
|
}
|
|
20231
20261
|
throw err;
|
|
20232
20262
|
}
|
|
20233
20263
|
}
|
|
20234
20264
|
function writeManifest(manifest, tarPath) {
|
|
20235
|
-
|
|
20265
|
+
fs30.writeFileSync(manifestPath(tarPath), JSON.stringify(manifest, null, 2), "utf-8");
|
|
20236
20266
|
}
|
|
20237
20267
|
function readManifest(tarPath) {
|
|
20238
20268
|
const mPath = manifestPath(tarPath);
|
|
20239
|
-
if (!
|
|
20269
|
+
if (!fs30.existsSync(mPath))
|
|
20240
20270
|
return null;
|
|
20241
20271
|
try {
|
|
20242
|
-
return JSON.parse(
|
|
20272
|
+
return JSON.parse(fs30.readFileSync(mPath, "utf-8"));
|
|
20243
20273
|
} catch {
|
|
20244
20274
|
return null;
|
|
20245
20275
|
}
|
|
20246
20276
|
}
|
|
20247
20277
|
function listSnapshots(worldIdFilter) {
|
|
20248
20278
|
const root = snapshotsDir();
|
|
20249
|
-
if (!
|
|
20279
|
+
if (!fs30.existsSync(root))
|
|
20250
20280
|
return [];
|
|
20251
20281
|
const now = Date.now();
|
|
20252
20282
|
const results = [];
|
|
20253
|
-
const worlds = worldIdFilter ? [worldIdFilter] :
|
|
20283
|
+
const worlds = worldIdFilter ? [worldIdFilter] : fs30.readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
20254
20284
|
for (const worldId of worlds) {
|
|
20255
|
-
const worldDir =
|
|
20256
|
-
if (!
|
|
20285
|
+
const worldDir = path34.join(root, worldId);
|
|
20286
|
+
if (!fs30.existsSync(worldDir) || !fs30.statSync(worldDir).isDirectory())
|
|
20257
20287
|
continue;
|
|
20258
20288
|
for (const kind of ["gems", "node", "pg"]) {
|
|
20259
|
-
const kindDir =
|
|
20260
|
-
if (!
|
|
20289
|
+
const kindDir = path34.join(worldDir, kind);
|
|
20290
|
+
if (!fs30.existsSync(kindDir))
|
|
20261
20291
|
continue;
|
|
20262
|
-
const tarballs =
|
|
20292
|
+
const tarballs = fs30.readdirSync(kindDir).filter((f) => f.endsWith(".tar.gz"));
|
|
20263
20293
|
for (const tarFile of tarballs) {
|
|
20264
|
-
const tarPath =
|
|
20265
|
-
const stat =
|
|
20294
|
+
const tarPath = path34.join(kindDir, tarFile);
|
|
20295
|
+
const stat = fs30.statSync(tarPath);
|
|
20266
20296
|
const manifest = readManifest(tarPath);
|
|
20267
20297
|
if (!manifest)
|
|
20268
20298
|
continue;
|
|
@@ -20352,17 +20382,17 @@ function resolveKinds(arg) {
|
|
|
20352
20382
|
return [];
|
|
20353
20383
|
}
|
|
20354
20384
|
async function captureGems(worldId, workspacePath, repo) {
|
|
20355
|
-
const repoDir =
|
|
20385
|
+
const repoDir = path35.join(workspacePath, repo);
|
|
20356
20386
|
const fingerprint = computeGemsFingerprint(repoDir);
|
|
20357
20387
|
if (!fingerprint) {
|
|
20358
20388
|
return { ok: false, tarPath: "", msg: "no Gemfile.lock \u2014 layer does not apply" };
|
|
20359
20389
|
}
|
|
20360
20390
|
const tarPath = snapshotTarPath(worldId, "gems", repo, fingerprint);
|
|
20361
|
-
const vendorBundle =
|
|
20362
|
-
if (
|
|
20391
|
+
const vendorBundle = path35.join(repoDir, "vendor", "bundle");
|
|
20392
|
+
if (fs31.existsSync(vendorBundle)) {
|
|
20363
20393
|
try {
|
|
20364
20394
|
packTarball(vendorBundle, tarPath);
|
|
20365
|
-
const stat =
|
|
20395
|
+
const stat = fs31.statSync(tarPath);
|
|
20366
20396
|
const manifest = {
|
|
20367
20397
|
kind: "gems",
|
|
20368
20398
|
worldId,
|
|
@@ -20395,10 +20425,10 @@ async function captureGems(worldId, workspacePath, repo) {
|
|
|
20395
20425
|
`docker exec ${containerName} sh -c 'mkdir -p "$(dirname ${tmpTar})" && tar -czf ${tmpTar}.tmp -C ${bundlePath} . && mv ${tmpTar}.tmp ${tmpTar}'`,
|
|
20396
20426
|
{ stdio: "pipe", timeout: 12e4 }
|
|
20397
20427
|
);
|
|
20398
|
-
|
|
20428
|
+
fs31.mkdirSync(path35.dirname(tarPath), { recursive: true });
|
|
20399
20429
|
execSync9(`docker cp ${containerName}:${tmpTar} "${tarPath}"`, { stdio: "pipe", timeout: 12e4 });
|
|
20400
20430
|
execSync9(`docker exec ${containerName} rm -f ${tmpTar}`, { stdio: "pipe" });
|
|
20401
|
-
const stat =
|
|
20431
|
+
const stat = fs31.statSync(tarPath);
|
|
20402
20432
|
const manifest = {
|
|
20403
20433
|
kind: "gems",
|
|
20404
20434
|
worldId,
|
|
@@ -20415,19 +20445,19 @@ async function captureGems(worldId, workspacePath, repo) {
|
|
|
20415
20445
|
}
|
|
20416
20446
|
}
|
|
20417
20447
|
async function captureNode(worldId, workspacePath, repo) {
|
|
20418
|
-
const repoDir =
|
|
20448
|
+
const repoDir = path35.join(workspacePath, repo);
|
|
20419
20449
|
const fingerprint = computeNodeFingerprint(repoDir);
|
|
20420
20450
|
if (!fingerprint) {
|
|
20421
20451
|
return { ok: false, tarPath: "", msg: "no lockfile \u2014 layer does not apply" };
|
|
20422
20452
|
}
|
|
20423
|
-
const nodeModules =
|
|
20424
|
-
if (!
|
|
20453
|
+
const nodeModules = path35.join(repoDir, "node_modules");
|
|
20454
|
+
if (!fs31.existsSync(nodeModules)) {
|
|
20425
20455
|
return { ok: false, tarPath: "", msg: "node_modules not installed yet" };
|
|
20426
20456
|
}
|
|
20427
20457
|
const tarPath = snapshotTarPath(worldId, "node", repo, fingerprint);
|
|
20428
20458
|
try {
|
|
20429
20459
|
packTarball(nodeModules, tarPath);
|
|
20430
|
-
const stat =
|
|
20460
|
+
const stat = fs31.statSync(tarPath);
|
|
20431
20461
|
const manifest = {
|
|
20432
20462
|
kind: "node",
|
|
20433
20463
|
worldId,
|
|
@@ -20444,7 +20474,7 @@ async function captureNode(worldId, workspacePath, repo) {
|
|
|
20444
20474
|
}
|
|
20445
20475
|
}
|
|
20446
20476
|
async function capturePg(worldId, workspacePath, repoNames) {
|
|
20447
|
-
const repoDirs = repoNames.map((r) =>
|
|
20477
|
+
const repoDirs = repoNames.map((r) => path35.join(workspacePath, r));
|
|
20448
20478
|
const fingerprint = computePgFingerprint(repoDirs);
|
|
20449
20479
|
if (!fingerprint) {
|
|
20450
20480
|
return { ok: false, tarPath: "", msg: "no Gemfile.lock / schema.rb \u2014 layer does not apply" };
|
|
@@ -20459,13 +20489,13 @@ async function capturePg(worldId, workspacePath, repoNames) {
|
|
|
20459
20489
|
}
|
|
20460
20490
|
try {
|
|
20461
20491
|
execSync9(`docker stop ${containerName}`, { stdio: "pipe", timeout: 3e4 });
|
|
20462
|
-
|
|
20492
|
+
fs31.mkdirSync(path35.dirname(tarPath), { recursive: true });
|
|
20463
20493
|
execSync9(
|
|
20464
|
-
`docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${
|
|
20494
|
+
`docker run --rm -v "${volumeName2}:/pgdata:ro" -v "${path35.dirname(tarPath)}:/dest" alpine sh -c 'tar -czf /dest/${path35.basename(tarPath)}.tmp -C /pgdata . && mv /dest/${path35.basename(tarPath)}.tmp /dest/${path35.basename(tarPath)}'`,
|
|
20465
20495
|
{ stdio: "pipe", timeout: 18e4 }
|
|
20466
20496
|
);
|
|
20467
20497
|
execSync9(`docker start ${containerName}`, { stdio: "pipe", timeout: 3e4 });
|
|
20468
|
-
const stat =
|
|
20498
|
+
const stat = fs31.statSync(tarPath);
|
|
20469
20499
|
const manifest = {
|
|
20470
20500
|
kind: "pg",
|
|
20471
20501
|
worldId,
|
|
@@ -20540,35 +20570,35 @@ function formatAge2(ms) {
|
|
|
20540
20570
|
// src/commands/refresh.ts
|
|
20541
20571
|
init_context();
|
|
20542
20572
|
init_output();
|
|
20543
|
-
import * as
|
|
20573
|
+
import * as fs33 from "node:fs";
|
|
20544
20574
|
import * as os19 from "node:os";
|
|
20545
|
-
import * as
|
|
20575
|
+
import * as path37 from "node:path";
|
|
20546
20576
|
import { spawnSync as spawnSync13 } from "node:child_process";
|
|
20547
20577
|
import ora8 from "ora";
|
|
20548
20578
|
|
|
20549
20579
|
// src/commands/refresh-helpers.ts
|
|
20550
|
-
import * as
|
|
20551
|
-
import * as
|
|
20580
|
+
import * as fs32 from "node:fs";
|
|
20581
|
+
import * as path36 from "node:path";
|
|
20552
20582
|
function collectCpSourceFiles(standaloneDir) {
|
|
20553
|
-
if (!
|
|
20583
|
+
if (!fs32.existsSync(standaloneDir)) {
|
|
20554
20584
|
throw new Error(`CP standalone dir not found: ${standaloneDir}`);
|
|
20555
20585
|
}
|
|
20556
20586
|
const entries = [];
|
|
20557
|
-
const topLevel =
|
|
20558
|
-
const stat =
|
|
20587
|
+
const topLevel = fs32.readdirSync(standaloneDir).filter((f) => {
|
|
20588
|
+
const stat = fs32.statSync(path36.join(standaloneDir, f));
|
|
20559
20589
|
return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
|
|
20560
20590
|
}).sort();
|
|
20561
20591
|
for (const f of topLevel) {
|
|
20562
|
-
entries.push({ srcPath:
|
|
20592
|
+
entries.push({ srcPath: path36.join(standaloneDir, f), destRelPath: f });
|
|
20563
20593
|
}
|
|
20564
|
-
const libDir =
|
|
20565
|
-
if (
|
|
20566
|
-
const libFiles =
|
|
20567
|
-
const stat =
|
|
20594
|
+
const libDir = path36.join(standaloneDir, "lib");
|
|
20595
|
+
if (fs32.existsSync(libDir) && fs32.statSync(libDir).isDirectory()) {
|
|
20596
|
+
const libFiles = fs32.readdirSync(libDir).filter((f) => {
|
|
20597
|
+
const stat = fs32.statSync(path36.join(libDir, f));
|
|
20568
20598
|
return stat.isFile() && f.endsWith(".mjs") && !f.endsWith(".test.mjs");
|
|
20569
20599
|
}).sort();
|
|
20570
20600
|
for (const f of libFiles) {
|
|
20571
|
-
entries.push({ srcPath:
|
|
20601
|
+
entries.push({ srcPath: path36.join(libDir, f), destRelPath: `lib/${f}` });
|
|
20572
20602
|
}
|
|
20573
20603
|
}
|
|
20574
20604
|
return entries;
|
|
@@ -20626,16 +20656,16 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
|
|
|
20626
20656
|
error: err instanceof Error ? err.message : String(err)
|
|
20627
20657
|
};
|
|
20628
20658
|
}
|
|
20629
|
-
const stagingDir =
|
|
20630
|
-
|
|
20659
|
+
const stagingDir = fs33.mkdtempSync(
|
|
20660
|
+
path37.join(os19.tmpdir(), `olam-refresh-${worldId}-`)
|
|
20631
20661
|
);
|
|
20632
20662
|
try {
|
|
20633
20663
|
const hasLib = entries.some((e) => e.destRelPath.startsWith("lib/"));
|
|
20634
20664
|
if (hasLib) {
|
|
20635
|
-
|
|
20665
|
+
fs33.mkdirSync(path37.join(stagingDir, "lib"), { recursive: true });
|
|
20636
20666
|
}
|
|
20637
20667
|
for (const { srcPath, destRelPath } of entries) {
|
|
20638
|
-
|
|
20668
|
+
fs33.copyFileSync(srcPath, path37.join(stagingDir, destRelPath));
|
|
20639
20669
|
}
|
|
20640
20670
|
const cpResult = docker([
|
|
20641
20671
|
"cp",
|
|
@@ -20650,7 +20680,7 @@ async function refreshWorld(worldId, portOffset, standaloneDir, opts) {
|
|
|
20650
20680
|
};
|
|
20651
20681
|
}
|
|
20652
20682
|
} finally {
|
|
20653
|
-
|
|
20683
|
+
fs33.rmSync(stagingDir, { recursive: true, force: true });
|
|
20654
20684
|
}
|
|
20655
20685
|
if (opts.restart) {
|
|
20656
20686
|
const restartResult = docker([
|
|
@@ -20687,11 +20717,11 @@ function registerRefresh(program2) {
|
|
|
20687
20717
|
process.exitCode = 1;
|
|
20688
20718
|
return;
|
|
20689
20719
|
}
|
|
20690
|
-
const standaloneDir =
|
|
20720
|
+
const standaloneDir = path37.join(
|
|
20691
20721
|
process.cwd(),
|
|
20692
20722
|
"packages/control-plane/standalone"
|
|
20693
20723
|
);
|
|
20694
|
-
if (!
|
|
20724
|
+
if (!fs33.existsSync(standaloneDir)) {
|
|
20695
20725
|
printError(
|
|
20696
20726
|
`CP standalone source not found at ${standaloneDir}.
|
|
20697
20727
|
Run \`olam refresh\` from the olam repo root.`
|
|
@@ -20770,9 +20800,9 @@ Run \`olam refresh\` from the olam repo root.`
|
|
|
20770
20800
|
}
|
|
20771
20801
|
|
|
20772
20802
|
// src/commands/diagnose.ts
|
|
20773
|
-
import * as
|
|
20803
|
+
import * as fs34 from "node:fs";
|
|
20774
20804
|
import * as os20 from "node:os";
|
|
20775
|
-
import * as
|
|
20805
|
+
import * as path38 from "node:path";
|
|
20776
20806
|
import { execFileSync as execFileSync7, execSync as execSync10 } from "node:child_process";
|
|
20777
20807
|
import pc21 from "picocolors";
|
|
20778
20808
|
|
|
@@ -20807,9 +20837,9 @@ function stripSecrets(input) {
|
|
|
20807
20837
|
}
|
|
20808
20838
|
|
|
20809
20839
|
// src/commands/diagnose.ts
|
|
20810
|
-
var DIAGNOSTICS_DIR =
|
|
20811
|
-
var LOG_DIR =
|
|
20812
|
-
var CACHE_DIR =
|
|
20840
|
+
var DIAGNOSTICS_DIR = path38.join(os20.homedir(), ".olam", "diagnostics");
|
|
20841
|
+
var LOG_DIR = path38.join(os20.homedir(), ".olam", "log");
|
|
20842
|
+
var CACHE_DIR = path38.join(os20.homedir(), ".olam", "cache");
|
|
20813
20843
|
var LOG_TAIL_LINES = 200;
|
|
20814
20844
|
function safeExec(cmd) {
|
|
20815
20845
|
try {
|
|
@@ -20823,10 +20853,10 @@ function defaultZip(zipPath, files) {
|
|
|
20823
20853
|
}
|
|
20824
20854
|
async function buildDiagnosticsZip(_exec = (cmd) => safeExec(cmd), _outDir = DIAGNOSTICS_DIR, _logDir = LOG_DIR, _zip = defaultZip) {
|
|
20825
20855
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 23);
|
|
20826
|
-
const zipPath =
|
|
20827
|
-
const tmpDir =
|
|
20856
|
+
const zipPath = path38.join(_outDir, `olam-diag-${ts}.zip`);
|
|
20857
|
+
const tmpDir = fs34.mkdtempSync(path38.join(os20.tmpdir(), "olam-diag-"));
|
|
20828
20858
|
try {
|
|
20829
|
-
|
|
20859
|
+
fs34.mkdirSync(_outDir, { recursive: true });
|
|
20830
20860
|
const entries = [];
|
|
20831
20861
|
const version = process.env["OLAM_CLI_VERSION"] ?? "unknown";
|
|
20832
20862
|
const nodeVersion = process.version;
|
|
@@ -20842,14 +20872,14 @@ platform: ${platform}
|
|
|
20842
20872
|
`uptime: ${os20.uptime()}s`
|
|
20843
20873
|
].join("\n") + "\n";
|
|
20844
20874
|
_writeEntry(tmpDir, "os-info.txt", stripSecrets(osContent), entries);
|
|
20845
|
-
const depsFile =
|
|
20846
|
-
if (
|
|
20847
|
-
const deps =
|
|
20875
|
+
const depsFile = path38.join(CACHE_DIR, "deps.json");
|
|
20876
|
+
if (fs34.existsSync(depsFile)) {
|
|
20877
|
+
const deps = fs34.readFileSync(depsFile, "utf-8");
|
|
20848
20878
|
_writeEntry(tmpDir, "deps.json", stripSecrets(deps), entries);
|
|
20849
20879
|
}
|
|
20850
20880
|
const latestLog = _latestLog(_logDir);
|
|
20851
20881
|
if (latestLog) {
|
|
20852
|
-
const lines =
|
|
20882
|
+
const lines = fs34.readFileSync(latestLog, "utf-8").split("\n");
|
|
20853
20883
|
const tail = lines.slice(-LOG_TAIL_LINES).join("\n");
|
|
20854
20884
|
_writeEntry(tmpDir, "log-tail.txt", stripSecrets(tail), entries);
|
|
20855
20885
|
}
|
|
@@ -20861,38 +20891,38 @@ platform: ${platform}
|
|
|
20861
20891
|
if (authAudit) {
|
|
20862
20892
|
_writeEntry(tmpDir, "audit-auth-callers.txt", stripSecrets(authAudit), entries);
|
|
20863
20893
|
}
|
|
20864
|
-
const fileArgs = entries.map((e) =>
|
|
20894
|
+
const fileArgs = entries.map((e) => path38.join(tmpDir, e));
|
|
20865
20895
|
try {
|
|
20866
20896
|
_zip(zipPath, fileArgs);
|
|
20867
20897
|
} catch (err) {
|
|
20868
20898
|
throw new Error(`zip command produced no output file. zip stderr: ${err.message}`);
|
|
20869
20899
|
}
|
|
20870
|
-
if (!
|
|
20900
|
+
if (!fs34.existsSync(zipPath)) {
|
|
20871
20901
|
throw new Error("zip command produced no output file.");
|
|
20872
20902
|
}
|
|
20873
20903
|
return { zipPath, entries };
|
|
20874
20904
|
} finally {
|
|
20875
20905
|
try {
|
|
20876
|
-
|
|
20906
|
+
fs34.rmSync(tmpDir, { recursive: true, force: true });
|
|
20877
20907
|
} catch {
|
|
20878
20908
|
}
|
|
20879
20909
|
}
|
|
20880
20910
|
}
|
|
20881
20911
|
function _writeEntry(dir, name, content, entries) {
|
|
20882
|
-
|
|
20912
|
+
fs34.writeFileSync(path38.join(dir, name), content, { mode: 420 });
|
|
20883
20913
|
entries.push(name);
|
|
20884
20914
|
}
|
|
20885
20915
|
function _latestLog(logDir) {
|
|
20886
|
-
if (!
|
|
20887
|
-
const files =
|
|
20888
|
-
return files.length > 0 ?
|
|
20916
|
+
if (!fs34.existsSync(logDir)) return null;
|
|
20917
|
+
const files = fs34.readdirSync(logDir).filter((f) => f.startsWith("host-")).sort().reverse();
|
|
20918
|
+
return files.length > 0 ? path38.join(logDir, files[0]) : null;
|
|
20889
20919
|
}
|
|
20890
20920
|
async function buildTelemetryPayload() {
|
|
20891
20921
|
const channel = "stable";
|
|
20892
|
-
const manifestFile =
|
|
20922
|
+
const manifestFile = path38.join(CACHE_DIR, "manifest.json");
|
|
20893
20923
|
let manifestAgeHours = null;
|
|
20894
|
-
if (
|
|
20895
|
-
const mtime =
|
|
20924
|
+
if (fs34.existsSync(manifestFile)) {
|
|
20925
|
+
const mtime = fs34.statSync(manifestFile).mtime.getTime();
|
|
20896
20926
|
manifestAgeHours = Math.round((Date.now() - mtime) / 36e5);
|
|
20897
20927
|
}
|
|
20898
20928
|
return {
|
|
@@ -20935,24 +20965,24 @@ function registerDiagnose(program2) {
|
|
|
20935
20965
|
}
|
|
20936
20966
|
|
|
20937
20967
|
// src/commands/update.ts
|
|
20938
|
-
import * as
|
|
20968
|
+
import * as fs37 from "node:fs";
|
|
20939
20969
|
import * as os22 from "node:os";
|
|
20940
|
-
import * as
|
|
20970
|
+
import * as path41 from "node:path";
|
|
20941
20971
|
import { execSync as execSync11 } from "node:child_process";
|
|
20942
20972
|
import pc22 from "picocolors";
|
|
20943
20973
|
|
|
20944
20974
|
// src/lib/symlink-reconcile.ts
|
|
20945
|
-
import * as
|
|
20946
|
-
import * as
|
|
20975
|
+
import * as fs35 from "node:fs";
|
|
20976
|
+
import * as path39 from "node:path";
|
|
20947
20977
|
var realFs = {
|
|
20948
|
-
readdirSync: (p) =>
|
|
20949
|
-
existsSync: (p) =>
|
|
20950
|
-
lstatSync: (p) =>
|
|
20951
|
-
readlinkSync: (p) =>
|
|
20952
|
-
symlinkSync: (t, l) =>
|
|
20953
|
-
unlinkSync: (p) =>
|
|
20978
|
+
readdirSync: (p) => fs35.readdirSync(p),
|
|
20979
|
+
existsSync: (p) => fs35.existsSync(p),
|
|
20980
|
+
lstatSync: (p) => fs35.lstatSync(p),
|
|
20981
|
+
readlinkSync: (p) => fs35.readlinkSync(p),
|
|
20982
|
+
symlinkSync: (t, l) => fs35.symlinkSync(t, l),
|
|
20983
|
+
unlinkSync: (p) => fs35.unlinkSync(p),
|
|
20954
20984
|
mkdirSync: (p, o) => {
|
|
20955
|
-
|
|
20985
|
+
fs35.mkdirSync(p, o);
|
|
20956
20986
|
}
|
|
20957
20987
|
};
|
|
20958
20988
|
function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
@@ -20962,8 +20992,8 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
|
20962
20992
|
_fs.mkdirSync(claudeSkillsDir, { recursive: true });
|
|
20963
20993
|
const sourceSkills = _fs.existsSync(npmSkillsDir) ? _fs.readdirSync(npmSkillsDir).filter((d) => d.startsWith("olam-")) : [];
|
|
20964
20994
|
for (const skill of sourceSkills) {
|
|
20965
|
-
const linkPath =
|
|
20966
|
-
const target =
|
|
20995
|
+
const linkPath = path39.join(claudeSkillsDir, skill);
|
|
20996
|
+
const target = path39.join(npmSkillsDir, skill);
|
|
20967
20997
|
if (!_fs.existsSync(linkPath)) {
|
|
20968
20998
|
try {
|
|
20969
20999
|
_fs.symlinkSync(target, linkPath);
|
|
@@ -20976,7 +21006,7 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
|
20976
21006
|
}
|
|
20977
21007
|
const deployedEntries = _fs.existsSync(claudeSkillsDir) ? _fs.readdirSync(claudeSkillsDir).filter((d) => d.startsWith("olam-")) : [];
|
|
20978
21008
|
for (const entry of deployedEntries) {
|
|
20979
|
-
const linkPath =
|
|
21009
|
+
const linkPath = path39.join(claudeSkillsDir, entry);
|
|
20980
21010
|
let isSymlink = false;
|
|
20981
21011
|
try {
|
|
20982
21012
|
isSymlink = _fs.lstatSync(linkPath).isSymbolicLink();
|
|
@@ -21001,9 +21031,9 @@ function reconcileSkillSymlinks(npmSkillsDir, claudeSkillsDir, _fs = realFs) {
|
|
|
21001
21031
|
|
|
21002
21032
|
// src/commands/update.ts
|
|
21003
21033
|
var PACKAGE_NAME = "@pleri/olam-cli";
|
|
21004
|
-
var CACHE_DIR2 =
|
|
21005
|
-
var LOG_DIR2 =
|
|
21006
|
-
var LAST_STABLE_FILE =
|
|
21034
|
+
var CACHE_DIR2 = path41.join(os22.homedir(), ".olam", "cache");
|
|
21035
|
+
var LOG_DIR2 = path41.join(os22.homedir(), ".olam", "log");
|
|
21036
|
+
var LAST_STABLE_FILE = path41.join(CACHE_DIR2, "last-stable.txt");
|
|
21007
21037
|
function defaultExec(cmd) {
|
|
21008
21038
|
try {
|
|
21009
21039
|
const stdout = execSync11(cmd, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
@@ -21025,22 +21055,22 @@ function getCurrentVersion(_exec = defaultExec) {
|
|
|
21025
21055
|
}
|
|
21026
21056
|
function readLastStable(file = LAST_STABLE_FILE) {
|
|
21027
21057
|
try {
|
|
21028
|
-
const v =
|
|
21058
|
+
const v = fs37.readFileSync(file, "utf-8").trim();
|
|
21029
21059
|
return v || null;
|
|
21030
21060
|
} catch {
|
|
21031
21061
|
return null;
|
|
21032
21062
|
}
|
|
21033
21063
|
}
|
|
21034
21064
|
function writeLastStable(version, file = LAST_STABLE_FILE) {
|
|
21035
|
-
|
|
21036
|
-
|
|
21065
|
+
fs37.mkdirSync(path41.dirname(file), { recursive: true });
|
|
21066
|
+
fs37.writeFileSync(file, version, { mode: 420 });
|
|
21037
21067
|
}
|
|
21038
21068
|
function logUpdateFailure(stderr) {
|
|
21039
21069
|
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
21040
|
-
const logFile =
|
|
21070
|
+
const logFile = path41.join(LOG_DIR2, `update-${ts}.log`);
|
|
21041
21071
|
try {
|
|
21042
|
-
|
|
21043
|
-
|
|
21072
|
+
fs37.mkdirSync(LOG_DIR2, { recursive: true });
|
|
21073
|
+
fs37.appendFileSync(logFile, `[update-failure ${(/* @__PURE__ */ new Date()).toISOString()}]
|
|
21044
21074
|
${stderr}
|
|
21045
21075
|
`, "utf-8");
|
|
21046
21076
|
} catch {
|
|
@@ -21127,8 +21157,8 @@ async function doUpdate(opts, _exec = defaultExec, _reconcile = reconcileSkillSy
|
|
|
21127
21157
|
let symlinkResult = { added: [], removed: [] };
|
|
21128
21158
|
if (npmRootResult.exitCode === 0) {
|
|
21129
21159
|
const npmRoot = npmRootResult.stdout.trim();
|
|
21130
|
-
const npmSkillsDir =
|
|
21131
|
-
const claudeSkillsDir =
|
|
21160
|
+
const npmSkillsDir = path41.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills");
|
|
21161
|
+
const claudeSkillsDir = path41.join(os22.homedir(), ".claude", "skills");
|
|
21132
21162
|
const rec = _reconcile(npmSkillsDir, claudeSkillsDir);
|
|
21133
21163
|
symlinkResult = { added: rec.added, removed: rec.removed };
|
|
21134
21164
|
if (!quiet && (rec.added.length > 0 || rec.removed.length > 0)) {
|
|
@@ -21174,8 +21204,8 @@ async function doRollback(_exec = defaultExec, _reconcile = reconcileSkillSymlin
|
|
|
21174
21204
|
if (npmRootResult.exitCode === 0) {
|
|
21175
21205
|
const npmRoot = npmRootResult.stdout.trim();
|
|
21176
21206
|
_reconcile(
|
|
21177
|
-
|
|
21178
|
-
|
|
21207
|
+
path41.join(npmRoot, "@pleri", "olam-cli", "plugin", "skills"),
|
|
21208
|
+
path41.join(os22.homedir(), ".claude", "skills")
|
|
21179
21209
|
);
|
|
21180
21210
|
}
|
|
21181
21211
|
return { action: "rolled-back", restoredVersion: prev, exitCode: 0 };
|
|
@@ -21256,7 +21286,7 @@ function registerBegin(program2) {
|
|
|
21256
21286
|
}
|
|
21257
21287
|
|
|
21258
21288
|
// src/commands/config.ts
|
|
21259
|
-
import * as
|
|
21289
|
+
import * as fs40 from "node:fs";
|
|
21260
21290
|
import { createRequire as createRequire3 } from "node:module";
|
|
21261
21291
|
|
|
21262
21292
|
// ../core/dist/global-config/schema.js
|
|
@@ -21333,9 +21363,9 @@ var DEFAULT_GLOBAL_CONFIG = {
|
|
|
21333
21363
|
};
|
|
21334
21364
|
|
|
21335
21365
|
// ../core/dist/global-config/store.js
|
|
21336
|
-
import * as
|
|
21366
|
+
import * as fs38 from "node:fs";
|
|
21337
21367
|
import * as os23 from "node:os";
|
|
21338
|
-
import * as
|
|
21368
|
+
import * as path42 from "node:path";
|
|
21339
21369
|
var GlobalConfigReadError = class extends Error {
|
|
21340
21370
|
constructor(configPath, cause) {
|
|
21341
21371
|
const msg = cause instanceof Error ? cause.message : String(cause);
|
|
@@ -21348,16 +21378,16 @@ function globalConfigPath() {
|
|
|
21348
21378
|
const override = process.env["OLAM_GLOBAL_CONFIG_PATH"];
|
|
21349
21379
|
if (override && override.length > 0)
|
|
21350
21380
|
return override;
|
|
21351
|
-
return
|
|
21381
|
+
return path42.join(os23.homedir(), ".olam", "config.json");
|
|
21352
21382
|
}
|
|
21353
21383
|
function readGlobalConfig() {
|
|
21354
21384
|
const configPath = globalConfigPath();
|
|
21355
|
-
if (!
|
|
21385
|
+
if (!fs38.existsSync(configPath)) {
|
|
21356
21386
|
return { ...DEFAULT_GLOBAL_CONFIG };
|
|
21357
21387
|
}
|
|
21358
21388
|
let raw;
|
|
21359
21389
|
try {
|
|
21360
|
-
raw =
|
|
21390
|
+
raw = fs38.readFileSync(configPath, "utf-8");
|
|
21361
21391
|
} catch (err) {
|
|
21362
21392
|
throw new GlobalConfigReadError(configPath, err);
|
|
21363
21393
|
}
|
|
@@ -21376,20 +21406,20 @@ function readGlobalConfig() {
|
|
|
21376
21406
|
function writeGlobalConfig(config) {
|
|
21377
21407
|
const configPath = globalConfigPath();
|
|
21378
21408
|
const validated = GlobalConfigSchema.parse(config);
|
|
21379
|
-
const dir =
|
|
21380
|
-
|
|
21409
|
+
const dir = path42.dirname(configPath);
|
|
21410
|
+
fs38.mkdirSync(dir, { recursive: true });
|
|
21381
21411
|
const tmp = `${configPath}.tmp-${process.pid}`;
|
|
21382
|
-
|
|
21383
|
-
|
|
21412
|
+
fs38.writeFileSync(tmp, JSON.stringify(validated, null, 2) + "\n", { mode: 420 });
|
|
21413
|
+
fs38.renameSync(tmp, configPath);
|
|
21384
21414
|
}
|
|
21385
21415
|
|
|
21386
21416
|
// ../core/dist/global-config/repos.js
|
|
21387
|
-
import * as
|
|
21417
|
+
import * as fs39 from "node:fs";
|
|
21388
21418
|
import * as os24 from "node:os";
|
|
21389
|
-
import * as
|
|
21419
|
+
import * as path43 from "node:path";
|
|
21390
21420
|
function expandPath(p) {
|
|
21391
21421
|
if (p === "~" || p.startsWith("~/")) {
|
|
21392
|
-
return
|
|
21422
|
+
return path43.join(os24.homedir(), p.slice(1));
|
|
21393
21423
|
}
|
|
21394
21424
|
return p;
|
|
21395
21425
|
}
|
|
@@ -21402,7 +21432,7 @@ function addRepo(entry) {
|
|
|
21402
21432
|
throw new Error(`repo "${entry.name}" already registered. Use "olam repos update" to change its path.`);
|
|
21403
21433
|
}
|
|
21404
21434
|
const resolvedPath = expandPath(entry.path);
|
|
21405
|
-
if (!
|
|
21435
|
+
if (!fs39.existsSync(resolvedPath)) {
|
|
21406
21436
|
throw new Error(`path "${entry.path}" does not exist. Verify the path is correct.`);
|
|
21407
21437
|
}
|
|
21408
21438
|
const now = Date.now();
|
|
@@ -21431,7 +21461,7 @@ function updateRepo(name, updates) {
|
|
|
21431
21461
|
throw new Error(`repo "${name}" is not registered. Run "olam repos list" to see registered repos.`);
|
|
21432
21462
|
}
|
|
21433
21463
|
const resolvedUpdatePath = updates.path !== void 0 ? expandPath(updates.path) : void 0;
|
|
21434
|
-
if (resolvedUpdatePath !== void 0 && !
|
|
21464
|
+
if (resolvedUpdatePath !== void 0 && !fs39.existsSync(resolvedUpdatePath)) {
|
|
21435
21465
|
throw new Error(`path "${updates.path}" does not exist. Verify the path is correct.`);
|
|
21436
21466
|
}
|
|
21437
21467
|
const existing = config.repos[idx];
|
|
@@ -21455,14 +21485,14 @@ function registerConfig(program2) {
|
|
|
21455
21485
|
const config = program2.command("config").description("Manage global olam configuration");
|
|
21456
21486
|
config.command("validate [path]").description("Validate ~/.olam/config.json (or a custom path) against the schema").action((filePath) => {
|
|
21457
21487
|
const resolvedPath = filePath ?? globalConfigPath();
|
|
21458
|
-
if (!
|
|
21488
|
+
if (!fs40.existsSync(resolvedPath)) {
|
|
21459
21489
|
process.stderr.write(`config file not found: ${resolvedPath}
|
|
21460
21490
|
`);
|
|
21461
21491
|
process.exit(1);
|
|
21462
21492
|
}
|
|
21463
21493
|
let raw;
|
|
21464
21494
|
try {
|
|
21465
|
-
raw =
|
|
21495
|
+
raw = fs40.readFileSync(resolvedPath, "utf-8");
|
|
21466
21496
|
} catch (err) {
|
|
21467
21497
|
const msg = err instanceof Error ? err.message : String(err);
|
|
21468
21498
|
process.stderr.write(`cannot read ${resolvedPath}: ${msg}
|
|
@@ -21899,12 +21929,12 @@ import * as readline3 from "node:readline";
|
|
|
21899
21929
|
import pc27 from "picocolors";
|
|
21900
21930
|
|
|
21901
21931
|
// src/commands/mcp/import-discovery.ts
|
|
21902
|
-
import * as
|
|
21932
|
+
import * as fs41 from "node:fs";
|
|
21903
21933
|
import * as os25 from "node:os";
|
|
21904
|
-
import * as
|
|
21934
|
+
import * as path44 from "node:path";
|
|
21905
21935
|
function readJsonFile(filePath) {
|
|
21906
21936
|
try {
|
|
21907
|
-
const raw =
|
|
21937
|
+
const raw = fs41.readFileSync(filePath, "utf-8");
|
|
21908
21938
|
return JSON.parse(raw);
|
|
21909
21939
|
} catch {
|
|
21910
21940
|
return null;
|
|
@@ -21933,24 +21963,24 @@ function extractMcpServers(obj, source, sourceLabel) {
|
|
|
21933
21963
|
}
|
|
21934
21964
|
function getClaudeDesktopPath() {
|
|
21935
21965
|
if (process.platform === "darwin") {
|
|
21936
|
-
return
|
|
21966
|
+
return path44.join(os25.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
21937
21967
|
}
|
|
21938
21968
|
if (process.platform === "win32") {
|
|
21939
|
-
const appData = process.env["APPDATA"] ??
|
|
21940
|
-
return
|
|
21969
|
+
const appData = process.env["APPDATA"] ?? path44.join(os25.homedir(), "AppData", "Roaming");
|
|
21970
|
+
return path44.join(appData, "Claude", "claude_desktop_config.json");
|
|
21941
21971
|
}
|
|
21942
|
-
return
|
|
21972
|
+
return path44.join(os25.homedir(), ".config", "Claude", "claude_desktop_config.json");
|
|
21943
21973
|
}
|
|
21944
21974
|
function getOlamRepoPaths() {
|
|
21945
21975
|
const configPaths = [
|
|
21946
|
-
|
|
21947
|
-
|
|
21976
|
+
path44.join(os25.homedir(), ".olam", "config.yaml"),
|
|
21977
|
+
path44.join(process.cwd(), ".olam", "config.yaml")
|
|
21948
21978
|
];
|
|
21949
21979
|
const paths = [];
|
|
21950
21980
|
for (const configPath of configPaths) {
|
|
21951
|
-
if (!
|
|
21981
|
+
if (!fs41.existsSync(configPath)) continue;
|
|
21952
21982
|
try {
|
|
21953
|
-
const raw =
|
|
21983
|
+
const raw = fs41.readFileSync(configPath, "utf-8");
|
|
21954
21984
|
const repoMatches = [...raw.matchAll(/path:\s*["']?([^\s"'\n]+)/g)];
|
|
21955
21985
|
for (const m of repoMatches) {
|
|
21956
21986
|
if (m[1]) paths.push(m[1]);
|
|
@@ -21966,7 +21996,7 @@ async function discoverMcpSources(repoPaths) {
|
|
|
21966
21996
|
const sources = [];
|
|
21967
21997
|
const sourceDefs = [
|
|
21968
21998
|
{
|
|
21969
|
-
path:
|
|
21999
|
+
path: path44.join(os25.homedir(), ".claude.json"),
|
|
21970
22000
|
label: "Claude Code (~/.claude.json)"
|
|
21971
22001
|
},
|
|
21972
22002
|
{
|
|
@@ -21974,19 +22004,19 @@ async function discoverMcpSources(repoPaths) {
|
|
|
21974
22004
|
label: "Claude Desktop"
|
|
21975
22005
|
},
|
|
21976
22006
|
{
|
|
21977
|
-
path:
|
|
22007
|
+
path: path44.join(os25.homedir(), ".cursor", "mcp.json"),
|
|
21978
22008
|
label: "Cursor (~/.cursor/mcp.json)"
|
|
21979
22009
|
},
|
|
21980
22010
|
{
|
|
21981
|
-
path:
|
|
22011
|
+
path: path44.join(os25.homedir(), ".codeium", "windsurf", "mcp_config.json"),
|
|
21982
22012
|
label: "Windsurf (~/.codeium/windsurf/mcp_config.json)"
|
|
21983
22013
|
}
|
|
21984
22014
|
];
|
|
21985
22015
|
const resolvedRepoPaths = repoPaths ?? getOlamRepoPaths();
|
|
21986
22016
|
for (const repoPath of resolvedRepoPaths) {
|
|
21987
22017
|
sourceDefs.push({
|
|
21988
|
-
path:
|
|
21989
|
-
label: `.mcp.json (${
|
|
22018
|
+
path: path44.join(repoPath, ".mcp.json"),
|
|
22019
|
+
label: `.mcp.json (${path44.basename(repoPath)})`
|
|
21990
22020
|
});
|
|
21991
22021
|
}
|
|
21992
22022
|
const reads = await Promise.all(
|
|
@@ -22216,18 +22246,18 @@ function registerMcp(program2) {
|
|
|
22216
22246
|
}
|
|
22217
22247
|
|
|
22218
22248
|
// src/pleri-config.ts
|
|
22219
|
-
import * as
|
|
22220
|
-
import * as
|
|
22249
|
+
import * as fs42 from "node:fs";
|
|
22250
|
+
import * as path45 from "node:path";
|
|
22221
22251
|
function isPleriConfigured(configDir = process.env.OLAM_CONFIG_DIR ?? ".olam") {
|
|
22222
22252
|
if (process.env.PLERI_BASE_URL) {
|
|
22223
22253
|
return true;
|
|
22224
22254
|
}
|
|
22225
|
-
const configPath =
|
|
22226
|
-
if (!
|
|
22255
|
+
const configPath = path45.join(configDir, "config.yaml");
|
|
22256
|
+
if (!fs42.existsSync(configPath)) {
|
|
22227
22257
|
return false;
|
|
22228
22258
|
}
|
|
22229
22259
|
try {
|
|
22230
|
-
const contents =
|
|
22260
|
+
const contents = fs42.readFileSync(configPath, "utf8");
|
|
22231
22261
|
return /^[^#\n]*\bpleri:/m.test(contents);
|
|
22232
22262
|
} catch {
|
|
22233
22263
|
return false;
|
|
@@ -22236,23 +22266,6 @@ function isPleriConfigured(configDir = process.env.OLAM_CONFIG_DIR ?? ".olam") {
|
|
|
22236
22266
|
|
|
22237
22267
|
// src/index.ts
|
|
22238
22268
|
var program = new Command();
|
|
22239
|
-
function readCliVersion() {
|
|
22240
|
-
try {
|
|
22241
|
-
const here = path45.dirname(fileURLToPath4(import.meta.url));
|
|
22242
|
-
for (const candidate of [
|
|
22243
|
-
path45.join(here, "package.json"),
|
|
22244
|
-
path45.join(here, "..", "package.json"),
|
|
22245
|
-
path45.join(here, "..", "..", "package.json")
|
|
22246
|
-
]) {
|
|
22247
|
-
if (fs42.existsSync(candidate)) {
|
|
22248
|
-
const pkg = JSON.parse(fs42.readFileSync(candidate, "utf-8"));
|
|
22249
|
-
if (typeof pkg.version === "string" && pkg.version.length > 0) return pkg.version;
|
|
22250
|
-
}
|
|
22251
|
-
}
|
|
22252
|
-
} catch {
|
|
22253
|
-
}
|
|
22254
|
-
return "0.0.0-unknown";
|
|
22255
|
-
}
|
|
22256
22269
|
program.name("olam").description("Olam \u2014 isolated development worlds with thought graph capture").version(readCliVersion());
|
|
22257
22270
|
registerInit(program);
|
|
22258
22271
|
registerInstall(program);
|