overlane 0.1.153 → 0.1.155
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/overlane-full.mjs +445 -406
- package/dist/overlane.mjs +25373 -361
- package/package.json +1 -1
- package/plugins/.claude-plugin/marketplace.json +2 -1
- package/plugins/claude/.claude-plugin/marketplace.json +2 -1
- package/plugins/claude/plugins/overlane/.claude-plugin/plugin.json +3 -2
- package/plugins/claude/plugins/overlane/scripts/harness-codemap.mjs +20 -18
- package/plugins/claude/plugins/overlane/scripts/harness-context.mjs +23 -21
- package/plugins/claude/plugins/overlane/scripts/harness-guard.mjs +14 -14
- package/plugins/claude/plugins/overlane/scripts/harness-intake.mjs +24 -22
- package/plugins/claude/plugins/overlane/scripts/harness-overlay.mjs +19 -17
- package/plugins/claude/plugins/overlane/scripts/harness-quota.mjs +17 -17
- package/plugins/claude/plugins/overlane/scripts/harness-statusline.mjs +11 -11
- package/plugins/claude/plugins/overlane/scripts/harness-stop.mjs +22 -20
- package/plugins/claude/plugins/overlane/skills/run-step/SKILL.md +4 -4
- package/plugins/codex/plugins/overlane/.codex-plugin/plugin.json +4 -3
- package/plugins/codex/plugins/overlane/scripts/harness-codemap.mjs +20 -18
- package/plugins/codex/plugins/overlane/scripts/harness-context.mjs +23 -21
- package/plugins/codex/plugins/overlane/scripts/harness-guard.mjs +14 -14
- package/plugins/codex/plugins/overlane/scripts/harness-intake.mjs +24 -22
- package/plugins/codex/plugins/overlane/scripts/harness-overlay.mjs +19 -17
- package/plugins/codex/plugins/overlane/scripts/harness-quota.mjs +17 -17
- package/plugins/codex/plugins/overlane/scripts/harness-statusline.mjs +11 -11
- package/plugins/codex/plugins/overlane/scripts/harness-stop.mjs +22 -20
- package/plugins/codex/plugins/overlane/skills/run-step/SKILL.md +4 -4
- package/plugins/release-manifest.json +35 -36
package/dist/overlane-full.mjs
CHANGED
|
@@ -20650,11 +20650,11 @@ var init_clients = __esm({
|
|
|
20650
20650
|
// ../contracts/src/code-map.ts
|
|
20651
20651
|
function codeMapDefault(setting, results = GATE_07_LATEST) {
|
|
20652
20652
|
const result = results[setting];
|
|
20653
|
-
if (result.verdict === "failed") return { setting, on: false, basis: "gate-07-failed", reason: `off: ${result.summary}
|
|
20654
|
-
if (result.verdict === "passed") return { setting, on: true, basis: "gate-07-passed", reason: `on: ${result.summary}
|
|
20653
|
+
if (result.verdict === "failed") return { setting, on: false, basis: "gate-07-failed", reason: `off: ${result.summary}`, gate07: "failed" };
|
|
20654
|
+
if (result.verdict === "passed") return { setting, on: true, basis: "gate-07-passed", reason: `on: ${result.summary}`, gate07: "passed" };
|
|
20655
20655
|
const on = SPEC_DEFAULT[setting];
|
|
20656
20656
|
if (result.verdict === "pending") {
|
|
20657
|
-
return { setting, on, basis: "spec-default-provisional", reason: `${on ? "on" : "off"} by the spec default, provisional: ${result.summary}
|
|
20657
|
+
return { setting, on, basis: "spec-default-provisional", reason: `${on ? "on" : "off"} by the spec default, provisional: ${result.summary}`, gate07: "pending" };
|
|
20658
20658
|
}
|
|
20659
20659
|
return { setting, on, basis: "spec-default", reason: `${on ? "on" : "off"} by the spec default: ${result.summary}`, gate07: "not-applicable" };
|
|
20660
20660
|
}
|
|
@@ -20672,22 +20672,19 @@ var init_code_map = __esm({
|
|
|
20672
20672
|
GATE_07_LATEST = {
|
|
20673
20673
|
"local-agent-with-grep": {
|
|
20674
20674
|
verdict: "failed",
|
|
20675
|
-
summary: "
|
|
20676
|
-
evidence: "ADR 0018, docs/findings/gate-07-preliminary.md, docs/findings/gate-07-realism-afltables.md"
|
|
20675
|
+
summary: "measured with a local checkout and grep, the code tools cost more tokens (109% to 115%) than the agent's own search"
|
|
20677
20676
|
},
|
|
20678
20677
|
"cloud-session": {
|
|
20679
20678
|
verdict: "pending",
|
|
20680
|
-
summary: "re-run for agents without a checkout: the mechanical leg is recorded, the agent leg waits on a model"
|
|
20681
|
-
evidence: "docs/findings/MS-A5-results.md (MS-A5.6)"
|
|
20679
|
+
summary: "re-run for agents without a checkout: the mechanical leg is recorded, the agent leg waits on a model"
|
|
20682
20680
|
},
|
|
20683
20681
|
bot: {
|
|
20684
20682
|
verdict: "pending",
|
|
20685
|
-
summary: "re-run for agents without a checkout: the mechanical leg is recorded, the agent leg waits on a model"
|
|
20686
|
-
evidence: "docs/findings/MS-A5-results.md (MS-A5.6)"
|
|
20683
|
+
summary: "re-run for agents without a checkout: the mechanical leg is recorded, the agent leg waits on a model"
|
|
20687
20684
|
},
|
|
20688
|
-
"review-service": { verdict: "not-applicable", summary: "the review service has no grep to compare with; it uses the map as context"
|
|
20689
|
-
"cross-repo": { verdict: "not-applicable", summary: "cross-repository questions have no single checkout to search"
|
|
20690
|
-
wiki: { verdict: "not-applicable", summary: "the generated wiki is built from the map"
|
|
20685
|
+
"review-service": { verdict: "not-applicable", summary: "the review service has no grep to compare with; it uses the map as context" },
|
|
20686
|
+
"cross-repo": { verdict: "not-applicable", summary: "cross-repository questions have no single checkout to search" },
|
|
20687
|
+
wiki: { verdict: "not-applicable", summary: "the generated wiki is built from the map" }
|
|
20691
20688
|
};
|
|
20692
20689
|
SPEC_DEFAULT = {
|
|
20693
20690
|
"local-agent-with-grep": false,
|
|
@@ -23755,7 +23752,7 @@ var init_wording = __esm({
|
|
|
23755
23752
|
});
|
|
23756
23753
|
|
|
23757
23754
|
// ../contracts/src/code-map-context.ts
|
|
23758
|
-
var CodeMapDigest
|
|
23755
|
+
var CodeMapDigest;
|
|
23759
23756
|
var init_code_map_context = __esm({
|
|
23760
23757
|
"../contracts/src/code-map-context.ts"() {
|
|
23761
23758
|
"use strict";
|
|
@@ -23772,8 +23769,6 @@ var init_code_map_context = __esm({
|
|
|
23772
23769
|
/** Qualified names of the symbols the ranking put first. */
|
|
23773
23770
|
seeds: external_exports.array(external_exports.string())
|
|
23774
23771
|
}).strict();
|
|
23775
|
-
CODE_MAP_DIGEST_PATH = ".harness/code-map.json";
|
|
23776
|
-
CODE_INDEX_PATH = ".harness/code-index.json";
|
|
23777
23772
|
}
|
|
23778
23773
|
});
|
|
23779
23774
|
|
|
@@ -27285,6 +27280,38 @@ var init_observability = __esm({
|
|
|
27285
27280
|
}
|
|
27286
27281
|
});
|
|
27287
27282
|
|
|
27283
|
+
// ../contracts/src/overlane-paths.ts
|
|
27284
|
+
function isStatePath(path) {
|
|
27285
|
+
const p2 = path.replace(/\\/g, "/");
|
|
27286
|
+
return p2 === STATE_DIR || p2.startsWith(`${STATE_DIR}/`);
|
|
27287
|
+
}
|
|
27288
|
+
var OVERLANE_DIR, STATE_DIR, PLAN_DIR, STATE_GITIGNORE, STATE_FILES;
|
|
27289
|
+
var init_overlane_paths = __esm({
|
|
27290
|
+
"../contracts/src/overlane-paths.ts"() {
|
|
27291
|
+
"use strict";
|
|
27292
|
+
OVERLANE_DIR = ".overlane";
|
|
27293
|
+
STATE_DIR = ".overlane/state";
|
|
27294
|
+
PLAN_DIR = ".overlane/plan";
|
|
27295
|
+
STATE_GITIGNORE = "# Written by overlane (ADR 0067): this folder is local state and is never committed.\n*\n";
|
|
27296
|
+
STATE_FILES = {
|
|
27297
|
+
binding: "project.json",
|
|
27298
|
+
owned: "owned.json",
|
|
27299
|
+
task: "task.json",
|
|
27300
|
+
taskPolicy: "task-policy.json",
|
|
27301
|
+
run: "run.json",
|
|
27302
|
+
release: "release.json",
|
|
27303
|
+
codeMap: "code-map.json",
|
|
27304
|
+
codeIndex: "code-index.json",
|
|
27305
|
+
codeMapSetting: "code-map-setting.json",
|
|
27306
|
+
codemapSessions: "codemap-sessions",
|
|
27307
|
+
overlay: "overlay",
|
|
27308
|
+
misses: "misses.log",
|
|
27309
|
+
ledger: "token-ledger.jsonl",
|
|
27310
|
+
logs: "logs"
|
|
27311
|
+
};
|
|
27312
|
+
}
|
|
27313
|
+
});
|
|
27314
|
+
|
|
27288
27315
|
// ../contracts/src/index.ts
|
|
27289
27316
|
var init_src = __esm({
|
|
27290
27317
|
"../contracts/src/index.ts"() {
|
|
@@ -27338,6 +27365,36 @@ var init_src = __esm({
|
|
|
27338
27365
|
init_enterprise();
|
|
27339
27366
|
init_observability();
|
|
27340
27367
|
init_code_nav();
|
|
27368
|
+
init_overlane_paths();
|
|
27369
|
+
}
|
|
27370
|
+
});
|
|
27371
|
+
|
|
27372
|
+
// ../contracts/src/overlane-paths-node.ts
|
|
27373
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
27374
|
+
import { join } from "node:path";
|
|
27375
|
+
function stateDir(root) {
|
|
27376
|
+
return join(root, STATE_DIR);
|
|
27377
|
+
}
|
|
27378
|
+
function statePath(root, file2, ...rest) {
|
|
27379
|
+
return join(root, STATE_DIR, STATE_FILES[file2], ...rest);
|
|
27380
|
+
}
|
|
27381
|
+
function ensureStateDir(root) {
|
|
27382
|
+
const dir = stateDir(root);
|
|
27383
|
+
mkdirSync2(dir, { recursive: true });
|
|
27384
|
+
const path = join(dir, ".gitignore");
|
|
27385
|
+
let current2;
|
|
27386
|
+
try {
|
|
27387
|
+
current2 = readFileSync2(path, "utf8");
|
|
27388
|
+
} catch {
|
|
27389
|
+
current2 = null;
|
|
27390
|
+
}
|
|
27391
|
+
if (current2 !== STATE_GITIGNORE) writeFileSync2(path, STATE_GITIGNORE);
|
|
27392
|
+
return dir;
|
|
27393
|
+
}
|
|
27394
|
+
var init_overlane_paths_node = __esm({
|
|
27395
|
+
"../contracts/src/overlane-paths-node.ts"() {
|
|
27396
|
+
"use strict";
|
|
27397
|
+
init_overlane_paths();
|
|
27341
27398
|
}
|
|
27342
27399
|
});
|
|
27343
27400
|
|
|
@@ -34672,7 +34729,7 @@ var require_dist = __commonJS({
|
|
|
34672
34729
|
});
|
|
34673
34730
|
|
|
34674
34731
|
// src/assets.ts
|
|
34675
|
-
import { basename as basename5, join as
|
|
34732
|
+
import { basename as basename5, join as join28, resolve as resolve17 } from "node:path";
|
|
34676
34733
|
import { fileURLToPath } from "node:url";
|
|
34677
34734
|
function packageRoot(env = process.env) {
|
|
34678
34735
|
const override = env["OVERLANE_PACKAGE_ROOT"];
|
|
@@ -34681,16 +34738,16 @@ function packageRoot(env = process.env) {
|
|
|
34681
34738
|
}
|
|
34682
34739
|
function assetDir(env = process.env) {
|
|
34683
34740
|
const override = env["OVERLANE_ASSET_DIR"];
|
|
34684
|
-
return override !== void 0 && override !== "" ? override :
|
|
34741
|
+
return override !== void 0 && override !== "" ? override : join28(packageRoot(env), "assets");
|
|
34685
34742
|
}
|
|
34686
34743
|
function assetFile(name2) {
|
|
34687
|
-
return
|
|
34744
|
+
return join28(assetDir(), basename5(name2));
|
|
34688
34745
|
}
|
|
34689
34746
|
var VERSION;
|
|
34690
34747
|
var init_assets = __esm({
|
|
34691
34748
|
"src/assets.ts"() {
|
|
34692
34749
|
"use strict";
|
|
34693
|
-
VERSION = true ? "0.1.
|
|
34750
|
+
VERSION = true ? "0.1.155" : "0.0.0-dev";
|
|
34694
34751
|
}
|
|
34695
34752
|
});
|
|
34696
34753
|
|
|
@@ -42634,7 +42691,7 @@ var init_treesitter = __esm({
|
|
|
42634
42691
|
import { execFile as execFile2 } from "node:child_process";
|
|
42635
42692
|
import { createHash as createHash6 } from "node:crypto";
|
|
42636
42693
|
import { lstat, readFile as readFile4 } from "node:fs/promises";
|
|
42637
|
-
import { join as
|
|
42694
|
+
import { join as join29 } from "node:path";
|
|
42638
42695
|
import { promisify } from "node:util";
|
|
42639
42696
|
function shardKeyOf(shard) {
|
|
42640
42697
|
return `sha256:${sha256Hex2(Buffer.from(`${shard.path}\0${shard.contentHash}\0${shard.precision}`, "utf8"))}`;
|
|
@@ -42661,7 +42718,7 @@ async function mapLimit(items, limit, task) {
|
|
|
42661
42718
|
return results;
|
|
42662
42719
|
}
|
|
42663
42720
|
async function hashRegularFile(repoRoot, path) {
|
|
42664
|
-
const absolute =
|
|
42721
|
+
const absolute = join29(repoRoot, path);
|
|
42665
42722
|
try {
|
|
42666
42723
|
const stats = await lstat(absolute);
|
|
42667
42724
|
if (!stats.isFile()) return null;
|
|
@@ -42699,7 +42756,7 @@ async function buildSnapshot(options) {
|
|
|
42699
42756
|
const needParse = [...hashes.keys()].filter((path) => !byPath.has(path));
|
|
42700
42757
|
const parsed = await mapLimit(needParse, 8, async (path) => {
|
|
42701
42758
|
if (languageForPath(path) === null) return { path, shard: null };
|
|
42702
|
-
const bytes = await readFile4(
|
|
42759
|
+
const bytes = await readFile4(join29(options.repoRoot, path));
|
|
42703
42760
|
if (bytes.byteLength > MAX_PARSE_BYTES) return { path, shard: null };
|
|
42704
42761
|
const hash2 = `sha256:${sha256Hex2(bytes)}`;
|
|
42705
42762
|
if (hash2 !== hashes.get(path)) throw new Error(`${path} changed while the snapshot was being built`);
|
|
@@ -43255,7 +43312,7 @@ var init_context_map = __esm({
|
|
|
43255
43312
|
// ../index-builder/src/context-map-build.ts
|
|
43256
43313
|
import { execFile as execFile3 } from "node:child_process";
|
|
43257
43314
|
import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile3 } from "node:fs/promises";
|
|
43258
|
-
import { dirname as
|
|
43315
|
+
import { dirname as dirname8, join as join30 } from "node:path";
|
|
43259
43316
|
import { promisify as promisify2 } from "node:util";
|
|
43260
43317
|
async function git5(root, args2) {
|
|
43261
43318
|
const { stdout } = await execFileAsync2("git", args2, { cwd: root, encoding: "utf8", maxBuffer: 256 * 1024 * 1024 });
|
|
@@ -43268,7 +43325,7 @@ async function buildArtifactsForCheckout(options) {
|
|
|
43268
43325
|
for (const path of tracked) {
|
|
43269
43326
|
if (languageForPath(path) === null) continue;
|
|
43270
43327
|
try {
|
|
43271
|
-
const bytes = await readFile5(
|
|
43328
|
+
const bytes = await readFile5(join30(options.root, path));
|
|
43272
43329
|
if (bytes.byteLength > MAX_PARSE_BYTES) {
|
|
43273
43330
|
uncovered += 1;
|
|
43274
43331
|
continue;
|
|
@@ -43292,15 +43349,16 @@ async function buildArtifactsForCheckout(options) {
|
|
|
43292
43349
|
return { digest, indexFile };
|
|
43293
43350
|
}
|
|
43294
43351
|
async function writeIndexFile(root, indexFile) {
|
|
43295
|
-
|
|
43296
|
-
|
|
43352
|
+
ensureStateDir(root);
|
|
43353
|
+
const path = statePath(root, "codeIndex");
|
|
43297
43354
|
await writeFile3(path, `${JSON.stringify(indexFile)}
|
|
43298
43355
|
`);
|
|
43299
43356
|
return path;
|
|
43300
43357
|
}
|
|
43301
43358
|
async function writeDigest(root, digest, out2) {
|
|
43302
|
-
|
|
43303
|
-
|
|
43359
|
+
if (out2 === void 0) ensureStateDir(root);
|
|
43360
|
+
const path = out2 ?? statePath(root, "codeMap");
|
|
43361
|
+
await mkdir3(dirname8(path), { recursive: true });
|
|
43304
43362
|
await writeFile3(path, `${JSON.stringify(digest)}
|
|
43305
43363
|
`);
|
|
43306
43364
|
return path;
|
|
@@ -43310,6 +43368,7 @@ var init_context_map_build = __esm({
|
|
|
43310
43368
|
"../index-builder/src/context-map-build.ts"() {
|
|
43311
43369
|
"use strict";
|
|
43312
43370
|
init_src();
|
|
43371
|
+
init_overlane_paths_node();
|
|
43313
43372
|
init_context_map();
|
|
43314
43373
|
init_languages();
|
|
43315
43374
|
init_snapshot();
|
|
@@ -43320,7 +43379,7 @@ var init_context_map_build = __esm({
|
|
|
43320
43379
|
// ../index-builder/src/run.ts
|
|
43321
43380
|
import { execFile as execFile4 } from "node:child_process";
|
|
43322
43381
|
import { mkdir as mkdir4, readdir as readdir4, rm as rm2, writeFile as writeFile4 } from "node:fs/promises";
|
|
43323
|
-
import { join as
|
|
43382
|
+
import { join as join31, resolve as resolve18 } from "node:path";
|
|
43324
43383
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
43325
43384
|
import { promisify as promisify3 } from "node:util";
|
|
43326
43385
|
function originOf(url2) {
|
|
@@ -43411,13 +43470,13 @@ ${USAGE}`);
|
|
|
43411
43470
|
}
|
|
43412
43471
|
}
|
|
43413
43472
|
async function writeSnapshot(dir, built) {
|
|
43414
|
-
await mkdir4(
|
|
43415
|
-
for (const name2 of await readdir4(
|
|
43416
|
-
await writeFile4(
|
|
43417
|
-
await writeFile4(
|
|
43473
|
+
await mkdir4(join31(dir, "shards"), { recursive: true });
|
|
43474
|
+
for (const name2 of await readdir4(join31(dir, "shards"))) await rm2(join31(dir, "shards", name2));
|
|
43475
|
+
await writeFile4(join31(dir, "manifest.json"), JSON.stringify(built.manifest, null, 2));
|
|
43476
|
+
await writeFile4(join31(dir, "uncovered.json"), JSON.stringify(built.uncovered, null, 2));
|
|
43418
43477
|
for (const shard of built.shards) {
|
|
43419
43478
|
const name2 = shardKeyOf(shard).slice("sha256:".length);
|
|
43420
|
-
await writeFile4(
|
|
43479
|
+
await writeFile4(join31(dir, "shards", `${name2}.json`), JSON.stringify(shard));
|
|
43421
43480
|
}
|
|
43422
43481
|
}
|
|
43423
43482
|
var execFileAsync3, USAGE, UsageError2, OPTIONS;
|
|
@@ -43435,7 +43494,7 @@ var init_run = __esm({
|
|
|
43435
43494
|
overlane-index map [--root DIR] [--out FILE] [--task TEXT]
|
|
43436
43495
|
overlane-index upload --service URL --tenant ID (--project ID | --repo owner/name) --commit SHA [--branch B] [--scip FILE ...] [--root DIR] [--audience URL]
|
|
43437
43496
|
|
|
43438
|
-
map writes the ranked code map digest (default .
|
|
43497
|
+
map writes the ranked code map digest (default .overlane/state/code-map.json in the root) that the session-start hook delivers as context (ADR 0055). No model; --task ranks by the words of a task.
|
|
43439
43498
|
--project indexes an Overlane project (no GitHub repository needed) and uploads with OVERLANE_TOKEN.
|
|
43440
43499
|
--repo names a GitHub repository; in GitHub Actions the OIDC token is used when ACTIONS_ID_TOKEN_REQUEST_URL is set.
|
|
43441
43500
|
Authentication for upload: OVERLANE_TOKEN (always for --project), or the GitHub Actions OIDC token for --repo.
|
|
@@ -58263,8 +58322,8 @@ var init_cloud = __esm({
|
|
|
58263
58322
|
|
|
58264
58323
|
// ../code-shim/src/git.ts
|
|
58265
58324
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
58266
|
-
import { existsSync as
|
|
58267
|
-
import { join as
|
|
58325
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
58326
|
+
import { join as join35 } from "node:path";
|
|
58268
58327
|
function git7(root, args2) {
|
|
58269
58328
|
try {
|
|
58270
58329
|
return execFileSync2("git", args2, { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], maxBuffer: 64 * 1024 * 1024, timeout: 1e4 });
|
|
@@ -58326,7 +58385,7 @@ function readWorkingCopyState(root) {
|
|
|
58326
58385
|
const head = headCommit2(root);
|
|
58327
58386
|
const raw = git7(root, ["status", "--porcelain=v2", "-z", "--untracked-files=all"]);
|
|
58328
58387
|
if (raw === null) return { head, dirty: /* @__PURE__ */ new Set(), deleted: /* @__PURE__ */ new Set(), renamed: /* @__PURE__ */ new Map() };
|
|
58329
|
-
return { head, ...parseStatus(raw, (path) =>
|
|
58388
|
+
return { head, ...parseStatus(raw, (path) => existsSync15(join35(root, path))) };
|
|
58330
58389
|
}
|
|
58331
58390
|
var init_git2 = __esm({
|
|
58332
58391
|
"../code-shim/src/git.ts"() {
|
|
@@ -58335,18 +58394,18 @@ var init_git2 = __esm({
|
|
|
58335
58394
|
});
|
|
58336
58395
|
|
|
58337
58396
|
// ../code-shim/src/config.ts
|
|
58338
|
-
import { readFileSync as
|
|
58397
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
58339
58398
|
import { homedir as homedir3 } from "node:os";
|
|
58340
|
-
import { join as
|
|
58399
|
+
import { join as join36 } from "node:path";
|
|
58341
58400
|
function configDir2(env) {
|
|
58342
|
-
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ??
|
|
58343
|
-
return
|
|
58401
|
+
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ?? join36(homedir3(), ".config");
|
|
58402
|
+
return join36(base5, "overlane");
|
|
58344
58403
|
}
|
|
58345
58404
|
function findToken2(env, serviceUrl, now) {
|
|
58346
58405
|
const fromEnv = env["OVERLANE_TOKEN"];
|
|
58347
58406
|
if (fromEnv !== void 0 && fromEnv.length > 0) return fromEnv;
|
|
58348
58407
|
try {
|
|
58349
|
-
const file2 = JSON.parse(
|
|
58408
|
+
const file2 = JSON.parse(readFileSync23(join36(configDir2(env), "credentials.json"), "utf8"));
|
|
58350
58409
|
const stored = file2[serviceUrl];
|
|
58351
58410
|
if (stored === void 0 || typeof stored.accessToken !== "string" || stored.accessToken.length === 0) return null;
|
|
58352
58411
|
if (typeof stored.expiresAt === "number" && stored.expiresAt <= now) return null;
|
|
@@ -58358,7 +58417,7 @@ function findToken2(env, serviceUrl, now) {
|
|
|
58358
58417
|
function resolveCloudConfig(root, env, now) {
|
|
58359
58418
|
let binding;
|
|
58360
58419
|
try {
|
|
58361
|
-
const parsed = ProjectBinding.safeParse(JSON.parse(
|
|
58420
|
+
const parsed = ProjectBinding.safeParse(JSON.parse(readFileSync23(statePath(root, "binding"), "utf8")));
|
|
58362
58421
|
if (!parsed.success) return null;
|
|
58363
58422
|
binding = parsed.data;
|
|
58364
58423
|
} catch {
|
|
@@ -58376,11 +58435,12 @@ var init_config = __esm({
|
|
|
58376
58435
|
"use strict";
|
|
58377
58436
|
init_src();
|
|
58378
58437
|
init_git2();
|
|
58438
|
+
init_overlane_paths_node();
|
|
58379
58439
|
}
|
|
58380
58440
|
});
|
|
58381
58441
|
|
|
58382
58442
|
// ../code-shim/src/local.ts
|
|
58383
|
-
import { readFileSync as
|
|
58443
|
+
import { readFileSync as readFileSync24, statSync as statSync4 } from "node:fs";
|
|
58384
58444
|
import { isAbsolute as isAbsolute2, relative as relative5, resolve as resolve19, sep as sep2 } from "node:path";
|
|
58385
58445
|
function resolveInside(root, path) {
|
|
58386
58446
|
const absolute = resolve19(root, path);
|
|
@@ -58500,7 +58560,7 @@ var init_local = __esm({
|
|
|
58500
58560
|
let shard;
|
|
58501
58561
|
try {
|
|
58502
58562
|
this.parses += 1;
|
|
58503
|
-
shard = await this.parse(path,
|
|
58563
|
+
shard = await this.parse(path, readFileSync24(absolute, "utf8"));
|
|
58504
58564
|
} catch {
|
|
58505
58565
|
shard = null;
|
|
58506
58566
|
}
|
|
@@ -58512,7 +58572,7 @@ var init_local = __esm({
|
|
|
58512
58572
|
const absolute = resolveInside(this.root, path);
|
|
58513
58573
|
if (absolute === null) return null;
|
|
58514
58574
|
try {
|
|
58515
|
-
return
|
|
58575
|
+
return readFileSync24(absolute, "utf8");
|
|
58516
58576
|
} catch {
|
|
58517
58577
|
return null;
|
|
58518
58578
|
}
|
|
@@ -58522,7 +58582,7 @@ var init_local = __esm({
|
|
|
58522
58582
|
const absolute = resolveInside(this.root, path);
|
|
58523
58583
|
if (absolute === null) return void 0;
|
|
58524
58584
|
try {
|
|
58525
|
-
const lines =
|
|
58585
|
+
const lines = readFileSync24(absolute, "utf8").split("\n");
|
|
58526
58586
|
const start2 = range[0];
|
|
58527
58587
|
if (start2 >= lines.length) return void 0;
|
|
58528
58588
|
const end = Math.min(Math.max(range[2], start2), start2 + maxLines - 1, lines.length - 1);
|
|
@@ -58749,7 +58809,7 @@ var init_nav = __esm({
|
|
|
58749
58809
|
|
|
58750
58810
|
// ../code-shim/src/edit.ts
|
|
58751
58811
|
import { createHash as createHash8 } from "node:crypto";
|
|
58752
|
-
import { readFileSync as
|
|
58812
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync12 } from "node:fs";
|
|
58753
58813
|
function lineStarts(text2) {
|
|
58754
58814
|
const starts = [0];
|
|
58755
58815
|
for (let i2 = 0; i2 < text2.length; i2 += 1) if (text2[i2] === "\n") starts.push(i2 + 1);
|
|
@@ -58790,7 +58850,7 @@ async function editSymbol(index, args2) {
|
|
|
58790
58850
|
if (!found.ok) return found;
|
|
58791
58851
|
const absolute = resolveInside(index.root, args2.path);
|
|
58792
58852
|
if (absolute === null) return { ok: false, reason: `path ${args2.path} is outside the repository` };
|
|
58793
|
-
const original =
|
|
58853
|
+
const original = readFileSync25(absolute, "utf8");
|
|
58794
58854
|
const starts = lineStarts(original);
|
|
58795
58855
|
const range = found.symbol.enclosingRange ?? found.symbol.range;
|
|
58796
58856
|
const from = offsetOf(starts, original, range[0], range[1]);
|
|
@@ -58818,7 +58878,7 @@ ${args2.content.replace(/\n+$/, "")}`;
|
|
|
58818
58878
|
const before = positionAt(next, changedStart);
|
|
58819
58879
|
const after = positionAt(next, insertAt + inserted.length);
|
|
58820
58880
|
const bytes = Buffer.from(next, "utf8");
|
|
58821
|
-
|
|
58881
|
+
writeFileSync12(absolute, bytes);
|
|
58822
58882
|
return {
|
|
58823
58883
|
ok: true,
|
|
58824
58884
|
path: args2.path,
|
|
@@ -58857,7 +58917,7 @@ async function renameSymbol(deps, args2) {
|
|
|
58857
58917
|
if (absolute === null) return { ok: false, reason: `reference path ${path} is outside the repository` };
|
|
58858
58918
|
let text2;
|
|
58859
58919
|
try {
|
|
58860
|
-
text2 =
|
|
58920
|
+
text2 = readFileSync25(absolute, "utf8");
|
|
58861
58921
|
} catch {
|
|
58862
58922
|
return { ok: false, reason: `cannot read ${path}` };
|
|
58863
58923
|
}
|
|
@@ -58879,7 +58939,7 @@ async function renameSymbol(deps, args2) {
|
|
|
58879
58939
|
let next = item.text;
|
|
58880
58940
|
for (const offset of offsets) next = next.slice(0, offset) + args2.new_name + next.slice(offset + oldName.length);
|
|
58881
58941
|
const bytes = Buffer.from(next, "utf8");
|
|
58882
|
-
|
|
58942
|
+
writeFileSync12(item.absolute, bytes);
|
|
58883
58943
|
filesChanged.push({ path: item.path, edits: offsets.length, sha256: sha2563(bytes) });
|
|
58884
58944
|
edits += offsets.length;
|
|
58885
58945
|
}
|
|
@@ -59165,7 +59225,6 @@ init_zod();
|
|
|
59165
59225
|
|
|
59166
59226
|
// ../cli/src/binding.ts
|
|
59167
59227
|
init_src();
|
|
59168
|
-
import { join as join2 } from "node:path";
|
|
59169
59228
|
|
|
59170
59229
|
// ../cli/src/files.ts
|
|
59171
59230
|
import { chmodSync, mkdirSync, readFileSync, rmdirSync, rmSync, writeFileSync } from "node:fs";
|
|
@@ -59211,52 +59270,10 @@ function jsonText(value) {
|
|
|
59211
59270
|
`;
|
|
59212
59271
|
}
|
|
59213
59272
|
|
|
59214
|
-
// ../cli/src/owned.ts
|
|
59215
|
-
init_zod();
|
|
59216
|
-
import { join } from "node:path";
|
|
59217
|
-
var BINDING_FILE = join(".harness", "project.json");
|
|
59218
|
-
var OWNED_FILE = join(".harness", "owned.json");
|
|
59219
|
-
var CODEX_CONFIG_FILE = join(".codex", "config.toml");
|
|
59220
|
-
var OwnedAgent = external_exports.object({ marketplace: external_exports.boolean(), plugin: external_exports.boolean() }).strict();
|
|
59221
|
-
var OwnedConfigLines = external_exports.object({ text: external_exports.string().min(1), createdFile: external_exports.boolean() }).strict();
|
|
59222
|
-
var Owned = external_exports.object({
|
|
59223
|
-
version: external_exports.literal(1),
|
|
59224
|
-
serviceUrl: external_exports.string().min(1),
|
|
59225
|
-
marketplaceRoot: external_exports.string().min(1),
|
|
59226
|
-
claude: OwnedAgent.optional(),
|
|
59227
|
-
codex: OwnedAgent.extend({ configLines: OwnedConfigLines.optional() }).strict().optional(),
|
|
59228
|
-
binding: external_exports.boolean(),
|
|
59229
|
-
excludeLine: external_exports.boolean()
|
|
59230
|
-
}).strict();
|
|
59231
|
-
function readOwned(root) {
|
|
59232
|
-
const parsed = Owned.safeParse(readJson(join(root, OWNED_FILE)));
|
|
59233
|
-
return parsed.success ? parsed.data : null;
|
|
59234
|
-
}
|
|
59235
|
-
function writeOwned(root, owned) {
|
|
59236
|
-
const ordered = {
|
|
59237
|
-
version: owned.version,
|
|
59238
|
-
serviceUrl: owned.serviceUrl,
|
|
59239
|
-
marketplaceRoot: owned.marketplaceRoot,
|
|
59240
|
-
...owned.claude === void 0 ? {} : { claude: { marketplace: owned.claude.marketplace, plugin: owned.claude.plugin } },
|
|
59241
|
-
...owned.codex === void 0 ? {} : {
|
|
59242
|
-
codex: {
|
|
59243
|
-
marketplace: owned.codex.marketplace,
|
|
59244
|
-
plugin: owned.codex.plugin,
|
|
59245
|
-
...owned.codex.configLines === void 0 ? {} : { configLines: owned.codex.configLines }
|
|
59246
|
-
}
|
|
59247
|
-
},
|
|
59248
|
-
binding: owned.binding,
|
|
59249
|
-
excludeLine: owned.excludeLine
|
|
59250
|
-
};
|
|
59251
|
-
return writeIfDifferent(join(root, OWNED_FILE), jsonText(ordered));
|
|
59252
|
-
}
|
|
59253
|
-
function removeOwned(root) {
|
|
59254
|
-
removeFile(join(root, OWNED_FILE));
|
|
59255
|
-
}
|
|
59256
|
-
|
|
59257
59273
|
// ../cli/src/binding.ts
|
|
59274
|
+
init_overlane_paths_node();
|
|
59258
59275
|
function readBindingFile(root) {
|
|
59259
|
-
const text2 = readText(
|
|
59276
|
+
const text2 = readText(statePath(root, "binding"));
|
|
59260
59277
|
if (text2 === null) return { kind: "missing" };
|
|
59261
59278
|
let raw;
|
|
59262
59279
|
try {
|
|
@@ -59276,6 +59293,8 @@ function bindingText(binding) {
|
|
|
59276
59293
|
|
|
59277
59294
|
// ../cli/src/connect.ts
|
|
59278
59295
|
init_src();
|
|
59296
|
+
init_src();
|
|
59297
|
+
init_overlane_paths_node();
|
|
59279
59298
|
import { existsSync as existsSync2 } from "node:fs";
|
|
59280
59299
|
import { join as join6, resolve } from "node:path";
|
|
59281
59300
|
|
|
@@ -59537,7 +59556,7 @@ async function detectAgents(deps, agents, cwd) {
|
|
|
59537
59556
|
|
|
59538
59557
|
// ../cli/src/credentials.ts
|
|
59539
59558
|
init_zod();
|
|
59540
|
-
import { join as
|
|
59559
|
+
import { join as join2 } from "node:path";
|
|
59541
59560
|
var KEYCHAIN_SERVICE = "overlane";
|
|
59542
59561
|
var StoredTokens = external_exports.object({ accessToken: external_exports.string().min(1), refreshToken: external_exports.string().min(1).optional(), expiresAt: external_exports.number().optional() }).strict();
|
|
59543
59562
|
var ClientCache = external_exports.object({ clientId: external_exports.string().min(1), port: external_exports.number().int().min(1).max(65535) }).strict();
|
|
@@ -59547,10 +59566,10 @@ var AuthState = external_exports.object({
|
|
|
59547
59566
|
}).strict();
|
|
59548
59567
|
var CredentialFile = external_exports.record(external_exports.string(), StoredTokens);
|
|
59549
59568
|
function authStatePath(deps) {
|
|
59550
|
-
return
|
|
59569
|
+
return join2(deps.paths.configDir, "auth.json");
|
|
59551
59570
|
}
|
|
59552
59571
|
function credentialsPath(deps) {
|
|
59553
|
-
return
|
|
59572
|
+
return join2(deps.paths.configDir, "credentials.json");
|
|
59554
59573
|
}
|
|
59555
59574
|
function readAuthState(deps) {
|
|
59556
59575
|
const parsed = AuthState.safeParse(readJson(authStatePath(deps)));
|
|
@@ -59675,6 +59694,49 @@ init_zod();
|
|
|
59675
59694
|
import { existsSync } from "node:fs";
|
|
59676
59695
|
import { join as join4 } from "node:path";
|
|
59677
59696
|
|
|
59697
|
+
// ../cli/src/owned.ts
|
|
59698
|
+
init_zod();
|
|
59699
|
+
import { join as join3 } from "node:path";
|
|
59700
|
+
init_overlane_paths_node();
|
|
59701
|
+
var BINDING_FILE = ".overlane/state/project.json";
|
|
59702
|
+
var OWNED_FILE = ".overlane/state/owned.json";
|
|
59703
|
+
var CODEX_CONFIG_FILE = join3(".codex", "config.toml");
|
|
59704
|
+
var OwnedAgent = external_exports.object({ marketplace: external_exports.boolean(), plugin: external_exports.boolean() }).strict();
|
|
59705
|
+
var OwnedConfigLines = external_exports.object({ text: external_exports.string().min(1), createdFile: external_exports.boolean() }).strict();
|
|
59706
|
+
var Owned = external_exports.object({
|
|
59707
|
+
version: external_exports.literal(1),
|
|
59708
|
+
serviceUrl: external_exports.string().min(1),
|
|
59709
|
+
marketplaceRoot: external_exports.string().min(1),
|
|
59710
|
+
claude: OwnedAgent.optional(),
|
|
59711
|
+
codex: OwnedAgent.extend({ configLines: OwnedConfigLines.optional() }).strict().optional(),
|
|
59712
|
+
binding: external_exports.boolean()
|
|
59713
|
+
}).strict();
|
|
59714
|
+
function readOwned(root) {
|
|
59715
|
+
const parsed = Owned.safeParse(readJson(statePath(root, "owned")));
|
|
59716
|
+
return parsed.success ? parsed.data : null;
|
|
59717
|
+
}
|
|
59718
|
+
function writeOwned(root, owned) {
|
|
59719
|
+
const ordered = {
|
|
59720
|
+
version: owned.version,
|
|
59721
|
+
serviceUrl: owned.serviceUrl,
|
|
59722
|
+
marketplaceRoot: owned.marketplaceRoot,
|
|
59723
|
+
...owned.claude === void 0 ? {} : { claude: { marketplace: owned.claude.marketplace, plugin: owned.claude.plugin } },
|
|
59724
|
+
...owned.codex === void 0 ? {} : {
|
|
59725
|
+
codex: {
|
|
59726
|
+
marketplace: owned.codex.marketplace,
|
|
59727
|
+
plugin: owned.codex.plugin,
|
|
59728
|
+
...owned.codex.configLines === void 0 ? {} : { configLines: owned.codex.configLines }
|
|
59729
|
+
}
|
|
59730
|
+
},
|
|
59731
|
+
binding: owned.binding
|
|
59732
|
+
};
|
|
59733
|
+
ensureStateDir(root);
|
|
59734
|
+
return writeIfDifferent(statePath(root, "owned"), jsonText(ordered));
|
|
59735
|
+
}
|
|
59736
|
+
function removeOwned(root) {
|
|
59737
|
+
removeFile(statePath(root, "owned"));
|
|
59738
|
+
}
|
|
59739
|
+
|
|
59678
59740
|
// ../cli/src/toml.ts
|
|
59679
59741
|
function parseKeyPath(source) {
|
|
59680
59742
|
const parts2 = [];
|
|
@@ -60101,7 +60163,7 @@ async function requireToken(deps, serviceUrl) {
|
|
|
60101
60163
|
|
|
60102
60164
|
// ../cli/src/project.ts
|
|
60103
60165
|
init_src();
|
|
60104
|
-
import { basename
|
|
60166
|
+
import { basename } from "node:path";
|
|
60105
60167
|
var REMOTE_PATTERNS = [
|
|
60106
60168
|
/^(?:https?|git|ssh):\/\/(?:[^@/]+@)?github\.com(?::\d+)?\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i,
|
|
60107
60169
|
/^(?:[^@/]+@)?github\.com:([^/]+)\/([^/]+?)(?:\.git)?\/?$/i
|
|
@@ -60165,37 +60227,6 @@ async function headCommit(deps, root) {
|
|
|
60165
60227
|
const sha = head.stdout.trim();
|
|
60166
60228
|
return head.code === 0 && sha.length > 0 ? sha : null;
|
|
60167
60229
|
}
|
|
60168
|
-
var EXCLUDE_LINE = ".harness/";
|
|
60169
|
-
async function excludePath(deps, root) {
|
|
60170
|
-
const result = await deps.exec("git", ["rev-parse", "--path-format=absolute", "--git-path", "info/exclude"], { cwd: root });
|
|
60171
|
-
if (result.code !== 0 || result.stdout.trim().length === 0) {
|
|
60172
|
-
return join5(root, ".git", "info", "exclude");
|
|
60173
|
-
}
|
|
60174
|
-
return result.stdout.trim();
|
|
60175
|
-
}
|
|
60176
|
-
async function isHarnessIgnored(deps, root) {
|
|
60177
|
-
const result = await deps.exec("git", ["check-ignore", "-q", ".harness/project.json"], { cwd: root });
|
|
60178
|
-
return result.code === 0;
|
|
60179
|
-
}
|
|
60180
|
-
async function addExclude(deps, root) {
|
|
60181
|
-
const path = await excludePath(deps, root);
|
|
60182
|
-
const text2 = readText(path) ?? "";
|
|
60183
|
-
if (text2.split("\n").includes(EXCLUDE_LINE)) return false;
|
|
60184
|
-
const prefix = text2.length === 0 || text2.endsWith("\n") ? "" : "\n";
|
|
60185
|
-
writeIfDifferent(path, `${text2}${prefix}${EXCLUDE_LINE}
|
|
60186
|
-
`);
|
|
60187
|
-
return true;
|
|
60188
|
-
}
|
|
60189
|
-
async function removeExclude(deps, root) {
|
|
60190
|
-
const path = await excludePath(deps, root);
|
|
60191
|
-
const text2 = readText(path);
|
|
60192
|
-
if (text2 === null) return;
|
|
60193
|
-
const lines = text2.split("\n");
|
|
60194
|
-
const index = lines.indexOf(EXCLUDE_LINE);
|
|
60195
|
-
if (index === -1) return;
|
|
60196
|
-
lines.splice(index, 1);
|
|
60197
|
-
writeIfDifferent(path, lines.join("\n"));
|
|
60198
|
-
}
|
|
60199
60230
|
|
|
60200
60231
|
// ../cli/src/readiness.ts
|
|
60201
60232
|
function report(agent, state, detail, action) {
|
|
@@ -60219,7 +60250,7 @@ async function assessAgent(deps, input2) {
|
|
|
60219
60250
|
return report(agent, "incompatible", input2.info.detail, `install ${label2} (\`${agent}\`) and run \`overlane doctor\` again`);
|
|
60220
60251
|
}
|
|
60221
60252
|
if (input2.binding.kind !== "ok") {
|
|
60222
|
-
const why = input2.binding.kind === "missing" ? "no .
|
|
60253
|
+
const why = input2.binding.kind === "missing" ? "no .overlane/state/project.json" : `invalid .overlane/state/project.json (${input2.binding.detail})`;
|
|
60223
60254
|
return report(agent, "blocked", why, "run `overlane connect`");
|
|
60224
60255
|
}
|
|
60225
60256
|
if (!input2.hasToken) return report(agent, "blocked", "no stored token for the service", "run `overlane connect` to sign in");
|
|
@@ -60436,7 +60467,7 @@ function normaliseServiceUrl(value) {
|
|
|
60436
60467
|
return url2.toString().replace(/\/+$/, "");
|
|
60437
60468
|
}
|
|
60438
60469
|
function emptyOwned(serviceUrl, marketplaceRoot2) {
|
|
60439
|
-
return { version: 1, serviceUrl, marketplaceRoot: marketplaceRoot2, binding: false
|
|
60470
|
+
return { version: 1, serviceUrl, marketplaceRoot: marketplaceRoot2, binding: false };
|
|
60440
60471
|
}
|
|
60441
60472
|
async function connect(deps, options) {
|
|
60442
60473
|
const infos = await detectAgents(deps, options.agents, deps.paths.cwd);
|
|
@@ -60490,7 +60521,7 @@ async function connect(deps, options) {
|
|
|
60490
60521
|
}
|
|
60491
60522
|
}
|
|
60492
60523
|
}
|
|
60493
|
-
const
|
|
60524
|
+
const gitignoreNeeded = !existsSync2(join6(root, STATE_DIR, ".gitignore"));
|
|
60494
60525
|
const bindingMissing = existing.kind !== "ok";
|
|
60495
60526
|
const existingToken = await findToken(deps, serviceUrl);
|
|
60496
60527
|
say(deps);
|
|
@@ -60506,21 +60537,21 @@ async function connect(deps, options) {
|
|
|
60506
60537
|
}
|
|
60507
60538
|
for (const line3 of present) say(deps, ` skip: ${line3}`);
|
|
60508
60539
|
say(deps, ` write ${BINDING_FILE}: project ID, tenant ID, service URL, release digest and the release-signing public key from the service`);
|
|
60509
|
-
say(deps,
|
|
60510
|
-
if (
|
|
60540
|
+
say(deps, ` write ${OWNED_FILE}: the entries overlane added, so \`overlane disconnect\` removes only those`);
|
|
60541
|
+
if (gitignoreNeeded) say(deps, ` write ${STATE_DIR}/.gitignore (\`*\`): local state is never committed`);
|
|
60511
60542
|
for (const info2 of active) {
|
|
60512
60543
|
say(deps, ` hook (${info2.agent}, SessionStart): node ${hookScript(marketplaceRoot2, info2.agent)}`);
|
|
60513
60544
|
}
|
|
60514
|
-
say(deps, " It runs at session start and reads .
|
|
60545
|
+
say(deps, " It runs at session start and reads .overlane/state/project.json and git. When a harness token is available (OVERLANE_TOKEN, the OS");
|
|
60515
60546
|
say(deps, ` keychain or the 0600 file) it calls ${serviceUrl}/v1/tenants/<tenant>/projects/<project>/context?commit=<sha>`);
|
|
60516
60547
|
say(deps, " with the token as a Bearer header, sending only the tenant, project and commit SHA. It never sends source code.");
|
|
60517
60548
|
say(deps);
|
|
60518
60549
|
if (options.dryRun) {
|
|
60519
60550
|
say(deps, "Dry run: no command was run and no file was written.");
|
|
60520
60551
|
const writes = [{ path: BINDING_FILE, action: "write", description: "project ID, tenant ID, service URL, release digest and the release-signing public key" }];
|
|
60521
|
-
writes.push({ path:
|
|
60552
|
+
writes.push({ path: OWNED_FILE, action: "write", description: "the entries overlane added, so `overlane disconnect` removes only those" });
|
|
60522
60553
|
if (codexEdit !== null) writes.push({ path: CODEX_CONFIG_FILE, action: "append", description: `enable the plugin for this project (${codexEdit.block.trim().split("\n").join("; ")})` });
|
|
60523
|
-
if (
|
|
60554
|
+
if (gitignoreNeeded) writes.push({ path: `${STATE_DIR}/.gitignore`, action: "write", description: "`*`: the state folder ignores itself (ADR 0067)" });
|
|
60524
60555
|
const plan3 = dryRunPlan({
|
|
60525
60556
|
service: serviceUrl,
|
|
60526
60557
|
requests: [
|
|
@@ -60537,7 +60568,7 @@ async function connect(deps, options) {
|
|
|
60537
60568
|
});
|
|
60538
60569
|
return { data: plan3 };
|
|
60539
60570
|
}
|
|
60540
|
-
const pending = steps.length > 0 || codexEdit !== null ||
|
|
60571
|
+
const pending = steps.length > 0 || codexEdit !== null || gitignoreNeeded || bindingMissing;
|
|
60541
60572
|
if (pending && !options.yes) {
|
|
60542
60573
|
if (!deps.isTTY) {
|
|
60543
60574
|
const hint = `overlane connect${options.service === void 0 ? "" : ` --service ${options.service}`}${options.agents.length === AGENT_NAMES.length ? "" : ` --agents ${options.agents.join(",")}`}${options.marketplaceRoot === void 0 ? "" : ` --marketplace-root ${options.marketplaceRoot}`} --yes`;
|
|
@@ -60564,6 +60595,7 @@ async function connect(deps, options) {
|
|
|
60564
60595
|
releaseDigest: record3.releaseDigest,
|
|
60565
60596
|
...servicePublicKey === null ? {} : { servicePublicKey }
|
|
60566
60597
|
});
|
|
60598
|
+
ensureStateDir(root);
|
|
60567
60599
|
const previousOwned = readOwned(root);
|
|
60568
60600
|
const owned = previousOwned === null ? emptyOwned(serviceUrl, marketplaceRoot2) : { ...previousOwned, serviceUrl, marketplaceRoot: marketplaceRoot2 };
|
|
60569
60601
|
try {
|
|
@@ -60585,13 +60617,12 @@ async function connect(deps, options) {
|
|
|
60585
60617
|
verify(deps, root, active);
|
|
60586
60618
|
say(deps, `[agents] ${CONNECT_STEPS.agents}: done`);
|
|
60587
60619
|
await reportStep(deps, serviceUrl, token.token, me.tenantId, "agents", { agents: active.map((info2) => info2.agent === "claude" ? "claude-code" : info2.agent) });
|
|
60588
|
-
if (writeIfDifferent(
|
|
60620
|
+
if (writeIfDifferent(statePath(root, "binding"), bindingText(binding))) {
|
|
60589
60621
|
say(deps, `Wrote ${BINDING_FILE}`);
|
|
60590
60622
|
wrote.push(BINDING_FILE);
|
|
60591
60623
|
}
|
|
60592
60624
|
if (codexEdit !== null) wrote.push(CODEX_CONFIG_FILE);
|
|
60593
60625
|
owned.binding = true;
|
|
60594
|
-
if (excludeNeeded && await addExclude(deps, root)) owned.excludeLine = true;
|
|
60595
60626
|
say(deps, `[repo] ${CONNECT_STEPS.repo}: done`);
|
|
60596
60627
|
const next = await reportStep(deps, serviceUrl, token.token, me.tenantId, "repo", { repo: repoChoice(project) });
|
|
60597
60628
|
if (next !== null) say(deps, `Next in onboarding: ${next === "repo" ? "first-task" : next} (${CONNECT_STEPS[next === "repo" ? "first-task" : next]})`);
|
|
@@ -60791,7 +60822,7 @@ var authStatusCommand = defineCommand({
|
|
|
60791
60822
|
});
|
|
60792
60823
|
|
|
60793
60824
|
// ../cli/src/commands/client.ts
|
|
60794
|
-
import { readFileSync as
|
|
60825
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
60795
60826
|
import { join as join8, resolve as resolve3 } from "node:path";
|
|
60796
60827
|
|
|
60797
60828
|
// ../plugin-builder/src/adapters/plan.ts
|
|
@@ -60808,7 +60839,7 @@ function contextInstructions(client) {
|
|
|
60808
60839
|
return [
|
|
60809
60840
|
"## Overlane",
|
|
60810
60841
|
"",
|
|
60811
|
-
`This project shares context between coding agents through Overlane (${CLIENT_LABELS[client]} is one of them). Project and team IDs are in \`.
|
|
60842
|
+
`This project shares context between coding agents through Overlane (${CLIENT_LABELS[client]} is one of them). Project and team IDs are in \`.overlane/state/project.json\`.`,
|
|
60812
60843
|
"",
|
|
60813
60844
|
"- At the start of every task, call the `harness_context` tool of the `overlane` MCP server (or run `overlane context`).",
|
|
60814
60845
|
"- Claim work with `harness_task` before you change files, checkpoint before you stop or hand over, and submit with evidence. A task is done only when `harness_task get` shows it `verified`; saying so in chat is not enough.",
|
|
@@ -60873,7 +60904,7 @@ function planAdapter(client, surface, options = {}) {
|
|
|
60873
60904
|
}
|
|
60874
60905
|
|
|
60875
60906
|
// ../plugin-builder/src/adapters/install.ts
|
|
60876
|
-
import { chmodSync as chmodSync2, existsSync as existsSync3, mkdirSync as
|
|
60907
|
+
import { chmodSync as chmodSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
60877
60908
|
import { dirname as dirname2, isAbsolute, join as join7, relative, resolve as resolve2 } from "node:path";
|
|
60878
60909
|
function safePath(root, path) {
|
|
60879
60910
|
const full = resolve2(root, path);
|
|
@@ -60944,7 +60975,7 @@ function applyPlan(root, ops, options = {}) {
|
|
|
60944
60975
|
const applied = [];
|
|
60945
60976
|
for (const op of ops) {
|
|
60946
60977
|
const full = safePath(root, op.path);
|
|
60947
|
-
const existing = existsSync3(full) ?
|
|
60978
|
+
const existing = existsSync3(full) ? readFileSync3(full, "utf8") : null;
|
|
60948
60979
|
let next;
|
|
60949
60980
|
try {
|
|
60950
60981
|
next = render(op, existing);
|
|
@@ -60954,8 +60985,8 @@ function applyPlan(root, ops, options = {}) {
|
|
|
60954
60985
|
}
|
|
60955
60986
|
const action = existing === null ? "created" : existing === next ? "unchanged" : "updated";
|
|
60956
60987
|
if (action !== "unchanged" && options.dryRun !== true) {
|
|
60957
|
-
|
|
60958
|
-
|
|
60988
|
+
mkdirSync3(dirname2(full), { recursive: true });
|
|
60989
|
+
writeFileSync3(full, next);
|
|
60959
60990
|
if (op.kind === "write" && op.executable === true) chmodSync2(full, 493);
|
|
60960
60991
|
}
|
|
60961
60992
|
applied.push({ path: join7(op.path), action });
|
|
@@ -60964,7 +60995,7 @@ function applyPlan(root, ops, options = {}) {
|
|
|
60964
60995
|
}
|
|
60965
60996
|
|
|
60966
60997
|
// ../plugin-builder/src/adapters/cloud.ts
|
|
60967
|
-
var FALLBACK_DIR = ".
|
|
60998
|
+
var FALLBACK_DIR = ".overlane/hooks";
|
|
60968
60999
|
var CLAUDE_PLUGIN_SCRIPTS = ["claude", "plugins", "overlane", "scripts"];
|
|
60969
61000
|
var FALLBACK_SCRIPTS = ["harness-context.mjs", "harness-stop.mjs"];
|
|
60970
61001
|
function claudeFallbackSettings() {
|
|
@@ -61000,7 +61031,7 @@ function planCloudRecipe(client, options = {}) {
|
|
|
61000
61031
|
"3. `overlane task submit <id>` with evidence when done. The completion gate is advisory on this path: the server still refuses to mark an unverified task verified."
|
|
61001
61032
|
].join("\n")
|
|
61002
61033
|
},
|
|
61003
|
-
{ kind: "write", path:
|
|
61034
|
+
{ kind: "write", path: `${FALLBACK_DIR}/codex-cloud-setup.sh`, content: CODEX_SETUP_SCRIPT, executable: true }
|
|
61004
61035
|
];
|
|
61005
61036
|
}
|
|
61006
61037
|
const ops = [];
|
|
@@ -61039,8 +61070,8 @@ var NEXT = {
|
|
|
61039
61070
|
grok: ["Start Grok Build in this project; run `grok inspect` to see the overlane MCP server, then approve its sign-in."],
|
|
61040
61071
|
cursor: ["Open the project in Cursor, enable the overlane server under Settings > MCP, and sign in when asked."],
|
|
61041
61072
|
gemini: ["Run `gemini` in this project; the workspace extension `overlane` loads on start. Sign in when the MCP server asks."],
|
|
61042
|
-
claude: ["Commit .claude/settings.json, .
|
|
61043
|
-
codex: ["Commit AGENTS.md and .
|
|
61073
|
+
claude: ["Commit .claude/settings.json, .overlane/hooks and CLAUDE.md. In the Claude Code on the web environment, add the secret OVERLANE_TOKEN (an agent token from `overlane token create`)."],
|
|
61074
|
+
codex: ["Commit AGENTS.md and .overlane/hooks/codex-cloud-setup.sh. In the Codex cloud environment, run the setup script and add the secret OVERLANE_TOKEN (an agent token from `overlane token create`). Completion gating is advisory on Codex cloud."]
|
|
61044
61075
|
};
|
|
61045
61076
|
var clientInstallCommand = defineCommand({
|
|
61046
61077
|
path: ["client", "install"],
|
|
@@ -61074,7 +61105,7 @@ var clientInstallCommand = defineCommand({
|
|
|
61074
61105
|
const scripts = {};
|
|
61075
61106
|
for (const script of FALLBACK_SCRIPTS) {
|
|
61076
61107
|
try {
|
|
61077
|
-
scripts[script] =
|
|
61108
|
+
scripts[script] = readFileSync4(join8(root, ...CLAUDE_PLUGIN_SCRIPTS, script), "utf8");
|
|
61078
61109
|
} catch {
|
|
61079
61110
|
throw new UsageError(`the built Claude plugin was not found under ${root}`, { hint: "build it with the plugin builder or pass --marketplace-root" });
|
|
61080
61111
|
}
|
|
@@ -61102,8 +61133,8 @@ init_zod();
|
|
|
61102
61133
|
|
|
61103
61134
|
// ../cli/src/release/installed.ts
|
|
61104
61135
|
init_src();
|
|
61105
|
-
import {
|
|
61106
|
-
import {
|
|
61136
|
+
import { readFileSync as readFileSync5, renameSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
61137
|
+
import { join as join9 } from "node:path";
|
|
61107
61138
|
|
|
61108
61139
|
// ../cli/src/release/verify.ts
|
|
61109
61140
|
init_src();
|
|
@@ -61160,21 +61191,22 @@ function diffDigestOf(diff) {
|
|
|
61160
61191
|
}
|
|
61161
61192
|
|
|
61162
61193
|
// ../cli/src/release/installed.ts
|
|
61163
|
-
|
|
61194
|
+
init_overlane_paths_node();
|
|
61195
|
+
var RELEASE_FILE = ".overlane/state/release.json";
|
|
61164
61196
|
function readInstalled(root) {
|
|
61165
|
-
const parsed = ReleaseManifest.safeParse(readJson(
|
|
61197
|
+
const parsed = ReleaseManifest.safeParse(readJson(statePath(root, "release")));
|
|
61166
61198
|
return parsed.success ? parsed.data : null;
|
|
61167
61199
|
}
|
|
61168
61200
|
function writeInstalled(root, manifest) {
|
|
61169
|
-
|
|
61170
|
-
|
|
61201
|
+
ensureStateDir(root);
|
|
61202
|
+
const path = statePath(root, "release");
|
|
61171
61203
|
const temp = `${path}.${process.pid}.tmp`;
|
|
61172
|
-
|
|
61204
|
+
writeFileSync4(temp, jsonText(manifest));
|
|
61173
61205
|
renameSync(temp, path);
|
|
61174
61206
|
}
|
|
61175
61207
|
function diskDigest(marketplaceRoot2, file2) {
|
|
61176
61208
|
try {
|
|
61177
|
-
return sha256Of(
|
|
61209
|
+
return sha256Of(readFileSync5(join9(marketplaceRoot2, file2.path)));
|
|
61178
61210
|
} catch {
|
|
61179
61211
|
return null;
|
|
61180
61212
|
}
|
|
@@ -61199,14 +61231,13 @@ function mismatchedFiles(marketplaceRoot2, target2) {
|
|
|
61199
61231
|
|
|
61200
61232
|
// ../cli/src/release/update.ts
|
|
61201
61233
|
init_src();
|
|
61202
|
-
import { join as
|
|
61234
|
+
import { join as join12, resolve as resolve4 } from "node:path";
|
|
61203
61235
|
|
|
61204
61236
|
// ../cli/src/task/state.ts
|
|
61205
61237
|
init_src();
|
|
61238
|
+
import { renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
61206
61239
|
init_zod();
|
|
61207
|
-
|
|
61208
|
-
import { dirname as dirname4, join as join10 } from "node:path";
|
|
61209
|
-
var TASK_STATE_PATH = join10(".harness", "task.json");
|
|
61240
|
+
init_overlane_paths_node();
|
|
61210
61241
|
var LocalTaskState = external_exports.object({
|
|
61211
61242
|
taskId: TaskId,
|
|
61212
61243
|
fencingToken: external_exports.number().int().nonnegative(),
|
|
@@ -61218,7 +61249,7 @@ var LocalTaskState = external_exports.object({
|
|
|
61218
61249
|
}).strict();
|
|
61219
61250
|
function readTaskState(root) {
|
|
61220
61251
|
try {
|
|
61221
|
-
const text2 = readText(
|
|
61252
|
+
const text2 = readText(statePath(root, "task"));
|
|
61222
61253
|
if (text2 === null) return null;
|
|
61223
61254
|
const parsed = LocalTaskState.safeParse(JSON.parse(text2));
|
|
61224
61255
|
return parsed.success ? parsed.data : null;
|
|
@@ -61227,27 +61258,27 @@ function readTaskState(root) {
|
|
|
61227
61258
|
}
|
|
61228
61259
|
}
|
|
61229
61260
|
function writeTaskState(root, state) {
|
|
61230
|
-
|
|
61231
|
-
|
|
61261
|
+
ensureStateDir(root);
|
|
61262
|
+
const path = statePath(root, "task");
|
|
61232
61263
|
const temp = `${path}.${process.pid}.tmp`;
|
|
61233
|
-
|
|
61264
|
+
writeFileSync5(temp, `${JSON.stringify(state, null, 2)}
|
|
61234
61265
|
`);
|
|
61235
61266
|
renameSync2(temp, path);
|
|
61236
61267
|
}
|
|
61237
61268
|
function removeTaskState(root) {
|
|
61238
|
-
rmSync2(
|
|
61269
|
+
rmSync2(statePath(root, "task"), { force: true });
|
|
61239
61270
|
}
|
|
61240
61271
|
|
|
61241
61272
|
// ../cli/src/release/approvals.ts
|
|
61242
61273
|
init_src();
|
|
61243
61274
|
init_zod();
|
|
61244
|
-
import { chmodSync as chmodSync3, mkdirSync as
|
|
61275
|
+
import { chmodSync as chmodSync3, mkdirSync as mkdirSync6, renameSync as renameSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
61245
61276
|
import { hostname as hostname3 } from "node:os";
|
|
61246
|
-
import { dirname as
|
|
61277
|
+
import { dirname as dirname4, join as join10 } from "node:path";
|
|
61247
61278
|
var APPROVALS_FILE = "approvals.json";
|
|
61248
61279
|
var Approvals = external_exports.array(ReleaseApproval);
|
|
61249
61280
|
function approvalsPath(deps) {
|
|
61250
|
-
return
|
|
61281
|
+
return join10(deps.paths.configDir, APPROVALS_FILE);
|
|
61251
61282
|
}
|
|
61252
61283
|
function readApprovals(deps) {
|
|
61253
61284
|
const parsed = Approvals.safeParse(readJson(approvalsPath(deps)));
|
|
@@ -61260,29 +61291,29 @@ function recordApproval(deps, approval) {
|
|
|
61260
61291
|
const full = ReleaseApproval.parse({ ...approval, machine: hostname3() || "unknown", approvedAt: new Date(deps.now()).toISOString() });
|
|
61261
61292
|
const path = approvalsPath(deps);
|
|
61262
61293
|
const all = [...readApprovals(deps).filter((existing) => existing.digest !== full.digest), full];
|
|
61263
|
-
|
|
61294
|
+
mkdirSync6(dirname4(path), { recursive: true });
|
|
61264
61295
|
const temp = `${path}.${process.pid}.tmp`;
|
|
61265
|
-
|
|
61296
|
+
writeFileSync6(temp, jsonText(all), { mode: 384 });
|
|
61266
61297
|
chmodSync3(temp, 384);
|
|
61267
61298
|
renameSync3(temp, path);
|
|
61268
61299
|
return full;
|
|
61269
61300
|
}
|
|
61270
61301
|
|
|
61271
61302
|
// ../cli/src/release/source.ts
|
|
61272
|
-
import { mkdirSync as
|
|
61273
|
-
import { join as
|
|
61303
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync6 } from "node:fs";
|
|
61304
|
+
import { join as join11 } from "node:path";
|
|
61274
61305
|
var SIDECAR_DIR = ".release";
|
|
61275
61306
|
function sourceUrl(deps, source) {
|
|
61276
61307
|
const override = deps.env["OVERLANE_RELEASE_SOURCE_URL"];
|
|
61277
61308
|
return override !== void 0 && override.length > 0 ? override : `https://github.com/${source.repository}.git`;
|
|
61278
61309
|
}
|
|
61279
61310
|
async function git(deps, root, args2, quiet = false) {
|
|
61280
|
-
const result = await deps.exec("git", [`--git-dir=${
|
|
61311
|
+
const result = await deps.exec("git", [`--git-dir=${join11(root, ".git")}`, `--work-tree=${root}`, "-c", "advice.detachedHead=false", ...args2], { cwd: root });
|
|
61281
61312
|
if (result.code !== 0 && !quiet) throw new CliError(`\`git ${args2.join(" ")}\` failed (exit ${result.code}): ${(result.stderr || result.stdout).trim().slice(0, 400)}`);
|
|
61282
61313
|
return { code: result.code, text: result.stdout.trim() };
|
|
61283
61314
|
}
|
|
61284
61315
|
async function fetchReleaseSource(deps, marketplaceRoot2, source) {
|
|
61285
|
-
|
|
61316
|
+
mkdirSync7(marketplaceRoot2, { recursive: true });
|
|
61286
61317
|
const url2 = sourceUrl(deps, source);
|
|
61287
61318
|
if ((await git(deps, marketplaceRoot2, ["rev-parse", "--git-dir"], true)).code !== 0) await git(deps, marketplaceRoot2, ["init", "-q"]);
|
|
61288
61319
|
say(deps, `Fetching ${source.repository}@${source.commit.slice(0, 12)} (${source.ref})`);
|
|
@@ -61302,7 +61333,7 @@ async function verifySourceTree(deps, marketplaceRoot2, files, digest) {
|
|
|
61302
61333
|
for (const file2 of files) {
|
|
61303
61334
|
let actual = null;
|
|
61304
61335
|
try {
|
|
61305
|
-
actual = sha256Of(
|
|
61336
|
+
actual = sha256Of(readFileSync6(join11(marketplaceRoot2, file2.path)));
|
|
61306
61337
|
} catch {
|
|
61307
61338
|
}
|
|
61308
61339
|
if (actual === null) problems.push(`${file2.path} is missing`);
|
|
@@ -61462,7 +61493,7 @@ async function installRelease(deps, ctx, targetDigest, options, isPin) {
|
|
|
61462
61493
|
}
|
|
61463
61494
|
function syncBinding(root, binding, digest) {
|
|
61464
61495
|
if (binding.releaseDigest === digest) return;
|
|
61465
|
-
writeIfDifferent(
|
|
61496
|
+
writeIfDifferent(join12(root, BINDING_FILE), bindingText({ ...binding, releaseDigest: digest }));
|
|
61466
61497
|
}
|
|
61467
61498
|
|
|
61468
61499
|
// ../cli/src/kit/api.ts
|
|
@@ -61556,10 +61587,9 @@ function kitClient(deps, serviceUrl, binding, token) {
|
|
|
61556
61587
|
|
|
61557
61588
|
// ../cli/src/kit/run-state.ts
|
|
61558
61589
|
init_src();
|
|
61590
|
+
import { renameSync as renameSync4, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
61559
61591
|
init_zod();
|
|
61560
|
-
|
|
61561
|
-
import { dirname as dirname6, join as join14 } from "node:path";
|
|
61562
|
-
var RUN_STATE_PATH = join14(".harness", "run.json");
|
|
61592
|
+
init_overlane_paths_node();
|
|
61563
61593
|
var LocalRunState = external_exports.object({
|
|
61564
61594
|
runId: external_exports.string().min(1),
|
|
61565
61595
|
executor: external_exports.enum(["claude-code", "codex"]),
|
|
@@ -61570,7 +61600,7 @@ var LocalRunState = external_exports.object({
|
|
|
61570
61600
|
}).strict();
|
|
61571
61601
|
function readRunState(root) {
|
|
61572
61602
|
try {
|
|
61573
|
-
const text2 = readText(
|
|
61603
|
+
const text2 = readText(statePath(root, "run"));
|
|
61574
61604
|
if (text2 === null) return null;
|
|
61575
61605
|
const parsed = LocalRunState.safeParse(JSON.parse(text2));
|
|
61576
61606
|
return parsed.success ? parsed.data : null;
|
|
@@ -61579,15 +61609,15 @@ function readRunState(root) {
|
|
|
61579
61609
|
}
|
|
61580
61610
|
}
|
|
61581
61611
|
function writeRunState(root, state) {
|
|
61582
|
-
|
|
61583
|
-
|
|
61612
|
+
ensureStateDir(root);
|
|
61613
|
+
const path = statePath(root, "run");
|
|
61584
61614
|
const temp = `${path}.${process.pid}.tmp`;
|
|
61585
|
-
|
|
61615
|
+
writeFileSync7(temp, `${JSON.stringify(state, null, 2)}
|
|
61586
61616
|
`);
|
|
61587
61617
|
renameSync4(temp, path);
|
|
61588
61618
|
}
|
|
61589
61619
|
function removeRunState(root) {
|
|
61590
|
-
rmSync3(
|
|
61620
|
+
rmSync3(statePath(root, "run"), { force: true });
|
|
61591
61621
|
}
|
|
61592
61622
|
|
|
61593
61623
|
// ../cli/src/kit/run.ts
|
|
@@ -61608,7 +61638,7 @@ ${issues.map((issue2) => ` - ${issue2}`).join("\n")}` : message);
|
|
|
61608
61638
|
// ../kit/src/plan-files.ts
|
|
61609
61639
|
init_src();
|
|
61610
61640
|
import { mkdir, readdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
61611
|
-
import { join as
|
|
61641
|
+
import { join as join13 } from "node:path";
|
|
61612
61642
|
|
|
61613
61643
|
// ../kit/src/text.ts
|
|
61614
61644
|
var import_yaml = __toESM(require_dist(), 1);
|
|
@@ -61687,10 +61717,10 @@ function slugify2(value) {
|
|
|
61687
61717
|
}
|
|
61688
61718
|
|
|
61689
61719
|
// ../kit/src/plan-files.ts
|
|
61690
|
-
var
|
|
61720
|
+
var PLAN_DIR2 = PLAN_DIR;
|
|
61691
61721
|
var planPaths = (repoDir) => {
|
|
61692
|
-
const root =
|
|
61693
|
-
return { root, project:
|
|
61722
|
+
const root = join13(repoDir, PLAN_DIR2);
|
|
61723
|
+
return { root, project: join13(root, "project.md"), milestones: join13(root, "milestones.md"), tasks: join13(root, "tasks"), task: (id2) => join13(root, "tasks", `${id2}.md`) };
|
|
61694
61724
|
};
|
|
61695
61725
|
function parsePlan(input2, where2) {
|
|
61696
61726
|
const result = Plan.safeParse(input2);
|
|
@@ -61749,11 +61779,11 @@ async function writePlan(repoDir, plan3) {
|
|
|
61749
61779
|
]);
|
|
61750
61780
|
await mkdir(paths.tasks, { recursive: true });
|
|
61751
61781
|
const keep = new Set(canonical.tasks.map((task) => `${task.id}.md`));
|
|
61752
|
-
for (const entry of await readdir(paths.tasks)) if (entry.endsWith(".md") && !keep.has(entry)) await rm(
|
|
61782
|
+
for (const entry of await readdir(paths.tasks)) if (entry.endsWith(".md") && !keep.has(entry)) await rm(join13(paths.tasks, entry));
|
|
61753
61783
|
for (const [file2, text2] of files) await writeFile(file2, text2, "utf8");
|
|
61754
61784
|
return [...files.keys()].map((file2) => file2.slice(repoDir.length).replace(/^\/+/, ""));
|
|
61755
61785
|
}
|
|
61756
|
-
async function
|
|
61786
|
+
async function readText3(file2) {
|
|
61757
61787
|
try {
|
|
61758
61788
|
return await readFile(file2, "utf8");
|
|
61759
61789
|
} catch (error62) {
|
|
@@ -61815,8 +61845,8 @@ function parseTask(text2, where2) {
|
|
|
61815
61845
|
}
|
|
61816
61846
|
async function readPlan(repoDir) {
|
|
61817
61847
|
const paths = planPaths(repoDir);
|
|
61818
|
-
const { schemaVersion, project } = parseProject(await
|
|
61819
|
-
const milestones = parseMilestones(await
|
|
61848
|
+
const { schemaVersion, project } = parseProject(await readText3(paths.project), paths.project);
|
|
61849
|
+
const milestones = parseMilestones(await readText3(paths.milestones), paths.milestones);
|
|
61820
61850
|
let entries;
|
|
61821
61851
|
try {
|
|
61822
61852
|
entries = (await readdir(paths.tasks)).filter((entry) => entry.endsWith(".md"));
|
|
@@ -61825,8 +61855,8 @@ async function readPlan(repoDir) {
|
|
|
61825
61855
|
}
|
|
61826
61856
|
const tasks = [];
|
|
61827
61857
|
for (const entry of entries.sort(naturalCompare)) {
|
|
61828
|
-
const file2 =
|
|
61829
|
-
const task = parseTask(await
|
|
61858
|
+
const file2 = join13(paths.tasks, entry);
|
|
61859
|
+
const task = parseTask(await readText3(file2), file2);
|
|
61830
61860
|
if (`${task.id}.md` !== entry) throw new KitError(`${file2}: file name must be ${task.id}.md`);
|
|
61831
61861
|
tasks.push(task);
|
|
61832
61862
|
}
|
|
@@ -61837,13 +61867,13 @@ async function readPlan(repoDir) {
|
|
|
61837
61867
|
init_src();
|
|
61838
61868
|
init_zod();
|
|
61839
61869
|
import { mkdir as mkdir2, readdir as readdir3, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
61840
|
-
import { basename as basename3, dirname as
|
|
61870
|
+
import { basename as basename3, dirname as dirname5, join as join15, resolve as resolve6 } from "node:path";
|
|
61841
61871
|
|
|
61842
61872
|
// ../kit/src/detect.ts
|
|
61843
61873
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
61844
61874
|
init_src();
|
|
61845
61875
|
import { readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
|
|
61846
|
-
import { basename as basename2, join as
|
|
61876
|
+
import { basename as basename2, join as join14, resolve as resolve5 } from "node:path";
|
|
61847
61877
|
var KINDS = ["typecheck", "lint", "build", "test"];
|
|
61848
61878
|
async function readOptional(file2) {
|
|
61849
61879
|
try {
|
|
@@ -61888,7 +61918,7 @@ async function detectCommands(repoDir) {
|
|
|
61888
61918
|
if (!sources.includes(source)) sources.push(source);
|
|
61889
61919
|
};
|
|
61890
61920
|
const scriptBodies = /* @__PURE__ */ new Map();
|
|
61891
|
-
const packageText = await readOptional(
|
|
61921
|
+
const packageText = await readOptional(join14(root, "package.json"));
|
|
61892
61922
|
if (packageText !== void 0) {
|
|
61893
61923
|
let pkg;
|
|
61894
61924
|
try {
|
|
@@ -61910,13 +61940,13 @@ async function detectCommands(repoDir) {
|
|
|
61910
61940
|
install = pm === "npm" ? lock ? "npm ci" : "npm install" : `${pm} install`;
|
|
61911
61941
|
if (!sources.includes("package.json")) sources.push("package.json");
|
|
61912
61942
|
}
|
|
61913
|
-
const makefile = await readOptional(
|
|
61943
|
+
const makefile = await readOptional(join14(root, "Makefile")) ?? await readOptional(join14(root, "makefile"));
|
|
61914
61944
|
if (makefile !== void 0) {
|
|
61915
61945
|
const targets = new Set([...makefile.matchAll(/^([A-Za-z0-9_.-]+)\s*:(?!=)/gm)].map((m) => m[1] ?? ""));
|
|
61916
61946
|
const names = { typecheck: ["typecheck"], lint: ["lint"], build: ["build"], test: ["test", "tests"] };
|
|
61917
61947
|
for (const kind of KINDS) for (const name2 of names[kind]) if (targets.has(name2)) add(kind, `make ${name2}`, "Makefile");
|
|
61918
61948
|
}
|
|
61919
|
-
const pyproject = await readOptional(
|
|
61949
|
+
const pyproject = await readOptional(join14(root, "pyproject.toml"));
|
|
61920
61950
|
if (pyproject !== void 0) {
|
|
61921
61951
|
const files = await readdir2(root).catch(() => []);
|
|
61922
61952
|
const runner = files.includes("uv.lock") ? "uv run " : files.includes("poetry.lock") || /\[tool\.poetry\]/.test(pyproject) ? "poetry run " : "";
|
|
@@ -61928,13 +61958,13 @@ async function detectCommands(repoDir) {
|
|
|
61928
61958
|
else if (/^\[project\]/m.test(pyproject)) install = "pip install -e .";
|
|
61929
61959
|
}
|
|
61930
61960
|
}
|
|
61931
|
-
const workflowDir =
|
|
61961
|
+
const workflowDir = join14(root, ".github", "workflows");
|
|
61932
61962
|
const workflows = (await readdir2(workflowDir).catch(() => [])).filter((f) => /\.ya?ml$/.test(f)).sort();
|
|
61933
61963
|
for (const file2 of workflows) {
|
|
61934
61964
|
const source = `.github/workflows/${file2}`;
|
|
61935
61965
|
let doc;
|
|
61936
61966
|
try {
|
|
61937
|
-
doc = (0, import_yaml2.parse)(await readOptional(
|
|
61967
|
+
doc = (0, import_yaml2.parse)(await readOptional(join14(workflowDir, file2)) ?? "");
|
|
61938
61968
|
} catch {
|
|
61939
61969
|
continue;
|
|
61940
61970
|
}
|
|
@@ -61979,7 +62009,7 @@ async function draftPlanForExisting(repoDir, opts = {}) {
|
|
|
61979
62009
|
const detected = await detectCommands(root);
|
|
61980
62010
|
let pkgName;
|
|
61981
62011
|
let pkgDescription;
|
|
61982
|
-
const packageText = await readOptional(
|
|
62012
|
+
const packageText = await readOptional(join14(root, "package.json"));
|
|
61983
62013
|
if (packageText !== void 0) {
|
|
61984
62014
|
try {
|
|
61985
62015
|
const pkg = JSON.parse(packageText);
|
|
@@ -62139,13 +62169,13 @@ function parseConstitution(text2) {
|
|
|
62139
62169
|
}
|
|
62140
62170
|
async function findConstitution(repoDir) {
|
|
62141
62171
|
for (const rel of CONSTITUTION_PATHS) {
|
|
62142
|
-
const text2 = await readOptional2(
|
|
62172
|
+
const text2 = await readOptional2(join15(repoDir, rel));
|
|
62143
62173
|
if (text2 !== void 0) return { file: rel, text: text2 };
|
|
62144
62174
|
}
|
|
62145
62175
|
return void 0;
|
|
62146
62176
|
}
|
|
62147
62177
|
async function discoverFeatures(repoDir) {
|
|
62148
|
-
const specsDir =
|
|
62178
|
+
const specsDir = join15(repoDir, "specs");
|
|
62149
62179
|
let dirs;
|
|
62150
62180
|
try {
|
|
62151
62181
|
dirs = (await readdir3(specsDir, { withFileTypes: true })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
@@ -62154,10 +62184,10 @@ async function discoverFeatures(repoDir) {
|
|
|
62154
62184
|
}
|
|
62155
62185
|
const features = [];
|
|
62156
62186
|
for (const dir of dirs.sort(naturalCompare)) {
|
|
62157
|
-
const tasksText = await readOptional2(
|
|
62187
|
+
const tasksText = await readOptional2(join15(specsDir, dir, "tasks.md"));
|
|
62158
62188
|
if (tasksText === void 0) continue;
|
|
62159
|
-
const { phases, block: block2 } = parseTasksFile(tasksText,
|
|
62160
|
-
const specText = await readOptional2(
|
|
62189
|
+
const { phases, block: block2 } = parseTasksFile(tasksText, join15("specs", dir, "tasks.md"));
|
|
62190
|
+
const specText = await readOptional2(join15(specsDir, dir, "spec.md")) ?? "";
|
|
62161
62191
|
const number4 = /^(\d+)(?:-|$)/.exec(dir)?.[1];
|
|
62162
62192
|
features.push({ dir, key: number4 ?? slugify2(dir).replace(/-/g, ""), phases, block: block2, stories: parseStories(specText), specText });
|
|
62163
62193
|
}
|
|
@@ -62267,7 +62297,7 @@ async function gitRoot(deps, label2) {
|
|
|
62267
62297
|
function boundProject(deps, root) {
|
|
62268
62298
|
const bound = readBindingFile(root);
|
|
62269
62299
|
if (bound.kind !== "ok") {
|
|
62270
|
-
throw new CliError(bound.kind === "missing" ? "this project is not connected; run `overlane connect` first" : `.
|
|
62300
|
+
throw new CliError(bound.kind === "missing" ? "this project is not connected; run `overlane connect` first" : `.overlane/state/project.json is invalid (${bound.detail}); run \`overlane connect\``, {
|
|
62271
62301
|
code: "not_connected",
|
|
62272
62302
|
exit: EXIT.conflict,
|
|
62273
62303
|
hint: "overlane connect"
|
|
@@ -62304,7 +62334,7 @@ function otherAgent(name2) {
|
|
|
62304
62334
|
}
|
|
62305
62335
|
|
|
62306
62336
|
// ../cli/src/task/usage.ts
|
|
62307
|
-
import { join as
|
|
62337
|
+
import { join as join16 } from "node:path";
|
|
62308
62338
|
var FIVE_HOUR_WARN_PERCENT = 85;
|
|
62309
62339
|
var WEEKLY_WARN_PERCENT = 90;
|
|
62310
62340
|
var UNDATED_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
@@ -62316,7 +62346,7 @@ function window2(value) {
|
|
|
62316
62346
|
}
|
|
62317
62347
|
function readUsage(deps) {
|
|
62318
62348
|
try {
|
|
62319
|
-
const text2 = readText(
|
|
62349
|
+
const text2 = readText(join16(deps.paths.configDir, "usage.json"));
|
|
62320
62350
|
if (text2 === null) return null;
|
|
62321
62351
|
const raw = JSON.parse(text2);
|
|
62322
62352
|
if (typeof raw.updatedAt !== "number") return null;
|
|
@@ -62412,17 +62442,18 @@ function summarizeTask(view) {
|
|
|
62412
62442
|
}
|
|
62413
62443
|
|
|
62414
62444
|
// ../cli/src/task/workcopy.ts
|
|
62445
|
+
init_src();
|
|
62415
62446
|
import { createHash as createHash3 } from "node:crypto";
|
|
62416
|
-
import { lstatSync, readFileSync as
|
|
62417
|
-
import { join as
|
|
62418
|
-
var isHarnessPath = (path) => path
|
|
62447
|
+
import { lstatSync, readFileSync as readFileSync7, readlinkSync } from "node:fs";
|
|
62448
|
+
import { join as join17 } from "node:path";
|
|
62449
|
+
var isHarnessPath = (path) => isStatePath(path);
|
|
62419
62450
|
var CONTENT_LIMIT = 16 * 1024 * 1024;
|
|
62420
62451
|
function untrackedLine(root, path) {
|
|
62421
62452
|
try {
|
|
62422
|
-
const info2 = lstatSync(
|
|
62423
|
-
if (info2.isSymbolicLink()) return `${path}\0l:${readlinkSync(
|
|
62453
|
+
const info2 = lstatSync(join17(root, path));
|
|
62454
|
+
if (info2.isSymbolicLink()) return `${path}\0l:${readlinkSync(join17(root, path))}`;
|
|
62424
62455
|
if (info2.isFile()) {
|
|
62425
|
-
return info2.size <= CONTENT_LIMIT ? `${path}\0f:${createHash3("sha256").update(
|
|
62456
|
+
return info2.size <= CONTENT_LIMIT ? `${path}\0f:${createHash3("sha256").update(readFileSync7(join17(root, path))).digest("hex")}` : `${path}\0s:${info2.size}`;
|
|
62426
62457
|
}
|
|
62427
62458
|
} catch {
|
|
62428
62459
|
}
|
|
@@ -62521,7 +62552,7 @@ async function heldTask(ctx) {
|
|
|
62521
62552
|
const lease = view.contract.lease;
|
|
62522
62553
|
if (view.state === "paused" || lease === void 0 || lease.fencingToken !== state.fencingToken) {
|
|
62523
62554
|
removeTaskState(ctx.root);
|
|
62524
|
-
throw new CliError(`task ${state.taskId} is ${view.state} and this working copy no longer holds its lease; cleared .
|
|
62555
|
+
throw new CliError(`task ${state.taskId} is ${view.state} and this working copy no longer holds its lease; cleared .overlane/state/task.json`, {
|
|
62525
62556
|
code: "lease_lost",
|
|
62526
62557
|
exit: EXIT.conflict,
|
|
62527
62558
|
hint: `overlane task resume ${state.taskId}`
|
|
@@ -62617,7 +62648,7 @@ async function startTask(deps, input2) {
|
|
|
62617
62648
|
body: { requestId: "cli-<uuid>", expectedVersion: "<version from the first response>", holder: holderFor(executorName), executor, ttlSeconds: LEASE_TTL_SECONDS }
|
|
62618
62649
|
}
|
|
62619
62650
|
],
|
|
62620
|
-
writes: [{ path: ".
|
|
62651
|
+
writes: [{ path: ".overlane/state/task.json", action: "write", description: "the lease and fencing token of the claimed task (never committed)" }]
|
|
62621
62652
|
})
|
|
62622
62653
|
);
|
|
62623
62654
|
}
|
|
@@ -62656,7 +62687,7 @@ async function taskStatus(deps) {
|
|
|
62656
62687
|
const lease = view.contract.lease;
|
|
62657
62688
|
const leaseHeld = lease !== void 0 && lease.fencingToken === state.fencingToken;
|
|
62658
62689
|
if (!leaseHeld) {
|
|
62659
|
-
say(deps, "This working copy no longer holds the lease; `.
|
|
62690
|
+
say(deps, "This working copy no longer holds the lease; `.overlane/state/task.json` is stale. Use `overlane task resume` to claim the task again.");
|
|
62660
62691
|
} else {
|
|
62661
62692
|
writeTaskState(ctx.root, { ...state, expectedVersion: view.version });
|
|
62662
62693
|
}
|
|
@@ -62699,7 +62730,7 @@ async function writeCheckpoint(deps, input2) {
|
|
|
62699
62730
|
dryRunPlan({
|
|
62700
62731
|
service: project.serviceUrl,
|
|
62701
62732
|
requests: [{ method: "POST", path: taskPaths.operation(tenantId, projectId, state2.taskId, "checkpoint"), body: request2, note: "expectedVersion is read from the service when this runs for real" }],
|
|
62702
|
-
writes: input2.pause === void 0 ? [] : [{ path: ".
|
|
62733
|
+
writes: input2.pause === void 0 ? [] : [{ path: ".overlane/state/task.json", action: "delete", description: "the lease ends when the task is paused" }]
|
|
62703
62734
|
})
|
|
62704
62735
|
);
|
|
62705
62736
|
return { kind: "planned", outcome };
|
|
@@ -62763,7 +62794,7 @@ async function resumeTask(deps, input2) {
|
|
|
62763
62794
|
note: "sent only if the working copy matches the latest checkpoint's recovery route"
|
|
62764
62795
|
}
|
|
62765
62796
|
],
|
|
62766
|
-
writes: [{ path: ".
|
|
62797
|
+
writes: [{ path: ".overlane/state/task.json", action: "write", description: "the lease and fencing token of the claimed task (never committed)" }]
|
|
62767
62798
|
})
|
|
62768
62799
|
);
|
|
62769
62800
|
}
|
|
@@ -62821,7 +62852,7 @@ async function submitTask(deps, input2) {
|
|
|
62821
62852
|
dryRunPlan({
|
|
62822
62853
|
service: project.serviceUrl,
|
|
62823
62854
|
requests: [{ method: "POST", path: taskPaths.operation(tenantId, projectId, state2.taskId, "submit"), body: request2, note: "expectedVersion is read from the service when this runs for real" }],
|
|
62824
|
-
writes: [{ path: ".
|
|
62855
|
+
writes: [{ path: ".overlane/state/task.json", action: "write", description: "the new task version" }]
|
|
62825
62856
|
})
|
|
62826
62857
|
);
|
|
62827
62858
|
}
|
|
@@ -62892,7 +62923,7 @@ async function recordEvidence(deps, input2) {
|
|
|
62892
62923
|
const checkId = checkIdFor(command);
|
|
62893
62924
|
if (!view.contract.requiredChecks.some((check2) => check2.id === checkId)) {
|
|
62894
62925
|
throw new CliError(
|
|
62895
|
-
`no required check of task ${taskId} matches this command (check ${checkId}); pass the verification command exactly as written in .
|
|
62926
|
+
`no required check of task ${taskId} matches this command (check ${checkId}); pass the verification command exactly as written in .overlane/plan/tasks/${taskId}.md. Required checks: ${view.contract.requiredChecks.map((check2) => check2.id).join(", ") || "none"}`,
|
|
62896
62927
|
{ code: "no_matching_check", exit: EXIT.notFound, hint: `overlane task status` }
|
|
62897
62928
|
);
|
|
62898
62929
|
}
|
|
@@ -63075,7 +63106,7 @@ async function startRun(deps, input2) {
|
|
|
63075
63106
|
{ method: "GET", path: kitPaths.policy(tenantId, projectId), note: "a paused policy or an executor outside executorsAllowed stops here with exit 6" },
|
|
63076
63107
|
{ method: "POST", path: kitPaths.runs(tenantId, projectId), body: StartRunRequest.parse({ requestId: requestId2(), executor: executorFor(executor2 === "codex" ? "codex" : "claude-code"), trigger }) }
|
|
63077
63108
|
],
|
|
63078
|
-
writes: [{ path: ".
|
|
63109
|
+
writes: [{ path: ".overlane/state/run.json", action: "write", description: "the run id, start time and policy snapshot (never committed)" }]
|
|
63079
63110
|
})
|
|
63080
63111
|
);
|
|
63081
63112
|
}
|
|
@@ -63167,8 +63198,8 @@ async function claimTask(deps, input2) {
|
|
|
63167
63198
|
}
|
|
63168
63199
|
],
|
|
63169
63200
|
writes: [
|
|
63170
|
-
{ path: ".
|
|
63171
|
-
{ path: ".
|
|
63201
|
+
{ path: ".overlane/state/task.json", action: "write", description: "the lease and fencing token of the claimed task" },
|
|
63202
|
+
{ path: ".overlane/state/run.json", action: "write", description: "adds the task to the run's claimed list" }
|
|
63172
63203
|
]
|
|
63173
63204
|
})
|
|
63174
63205
|
);
|
|
@@ -63211,9 +63242,9 @@ async function claimTask(deps, input2) {
|
|
|
63211
63242
|
for (const criterion of contract.acceptanceCriteria) say(deps, ` - ${criterion}`);
|
|
63212
63243
|
const commands = await verificationCommands(ctx.root, taskId);
|
|
63213
63244
|
if (commands === null) {
|
|
63214
|
-
say(deps, `Verification commands: see .
|
|
63245
|
+
say(deps, `Verification commands: see .overlane/plan/tasks/${taskId}.md`);
|
|
63215
63246
|
} else {
|
|
63216
|
-
say(deps, `Verification commands (from .
|
|
63247
|
+
say(deps, `Verification commands (from .overlane/plan/tasks/${taskId}.md; pass each one exactly as written to \`overlane task evidence\`):`);
|
|
63217
63248
|
for (const command of commands) say(deps, ` $ ${command}`);
|
|
63218
63249
|
}
|
|
63219
63250
|
return {
|
|
@@ -63224,7 +63255,7 @@ async function claimTask(deps, input2) {
|
|
|
63224
63255
|
allowedPaths: [...contract.scope.allowedPaths],
|
|
63225
63256
|
acceptanceCriteria: [...contract.acceptanceCriteria],
|
|
63226
63257
|
verificationCommands: commands === null ? null : [...commands],
|
|
63227
|
-
planFile: `.
|
|
63258
|
+
planFile: `.overlane/plan/tasks/${taskId}.md`
|
|
63228
63259
|
}
|
|
63229
63260
|
};
|
|
63230
63261
|
} catch (error62) {
|
|
@@ -63271,7 +63302,7 @@ async function endRun(deps, input2) {
|
|
|
63271
63302
|
dryRunPlan({
|
|
63272
63303
|
service: project.serviceUrl,
|
|
63273
63304
|
requests: [{ method: "POST", path: kitPaths.endRun(project.binding.tenantId, project.binding.projectId, run4.runId), body: EndRunRequest.parse({ requestId: requestId2(), stopReason: reason }) }],
|
|
63274
|
-
writes: [{ path: ".
|
|
63305
|
+
writes: [{ path: ".overlane/state/run.json", action: "delete", description: "the run ends" }]
|
|
63275
63306
|
})
|
|
63276
63307
|
);
|
|
63277
63308
|
}
|
|
@@ -63283,7 +63314,7 @@ async function endRun(deps, input2) {
|
|
|
63283
63314
|
} catch (error62) {
|
|
63284
63315
|
if (error62 instanceof ServiceError && error62.code === "run_not_found") {
|
|
63285
63316
|
removeRunState(ctx.root);
|
|
63286
|
-
throw new CliError(`${error62.message}; removed the stale .
|
|
63317
|
+
throw new CliError(`${error62.message}; removed the stale .overlane/state/run.json`, { code: "run_not_found", exit: EXIT.notFound, hint: "overlane run start" });
|
|
63287
63318
|
}
|
|
63288
63319
|
throw error62;
|
|
63289
63320
|
}
|
|
@@ -63566,7 +63597,7 @@ var contextCommand = defineCommand({
|
|
|
63566
63597
|
// ../cli/src/commands/lib.ts
|
|
63567
63598
|
init_src();
|
|
63568
63599
|
init_zod();
|
|
63569
|
-
import { existsSync as existsSync4, readFileSync as
|
|
63600
|
+
import { existsSync as existsSync4, readFileSync as readFileSync8 } from "node:fs";
|
|
63570
63601
|
import { basename as basename4, resolve as resolve7 } from "node:path";
|
|
63571
63602
|
var SERVICE_FLAG = { name: "service", type: "string", value: "URL", description: "The service address (default: OVERLANE_SERVICE_URL, then the project's binding, then the hosted service)" };
|
|
63572
63603
|
var TEAM_FLAG = { name: "team", type: "string", value: "TENANT_ID", description: "The team (tenant) to act on (default: the one your token belongs to)" };
|
|
@@ -63682,7 +63713,7 @@ function readLockfiles(paths) {
|
|
|
63682
63713
|
const kind = LOCKFILES.find(([pattern]) => pattern.test(basename4(file2)))?.[1];
|
|
63683
63714
|
if (kind === void 0) throw new UsageError(`${file2} is not a lockfile this command reads`, { hint: "supported: package-lock.json, pnpm-lock.yaml, yarn.lock, requirements.txt, uv.lock, Cargo.lock, go.sum" });
|
|
63684
63715
|
try {
|
|
63685
|
-
return { kind, content:
|
|
63716
|
+
return { kind, content: readFileSync8(resolve7(file2), "utf8") };
|
|
63686
63717
|
} catch {
|
|
63687
63718
|
throw new UsageError(`cannot read ${file2}`);
|
|
63688
63719
|
}
|
|
@@ -63775,7 +63806,7 @@ var libAddCommand = defineCommand({
|
|
|
63775
63806
|
if (version2 === void 0 || files.length === 0) throw new UsageError("add needs --version and at least one --file", { hint: "overlane lib add <library> --version 1.0.0 --file README.md" });
|
|
63776
63807
|
const pages = files.map((file2) => {
|
|
63777
63808
|
try {
|
|
63778
|
-
return { title: basename4(file2), text:
|
|
63809
|
+
return { title: basename4(file2), text: readFileSync8(resolve7(file2), "utf8") };
|
|
63779
63810
|
} catch {
|
|
63780
63811
|
throw new UsageError(`cannot read ${file2}`);
|
|
63781
63812
|
}
|
|
@@ -64478,7 +64509,7 @@ var billingCommands = [
|
|
|
64478
64509
|
init_src();
|
|
64479
64510
|
init_zod();
|
|
64480
64511
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
64481
|
-
import { readFileSync as
|
|
64512
|
+
import { readFileSync as readFileSync9, statSync } from "node:fs";
|
|
64482
64513
|
import { resolve as resolve8 } from "node:path";
|
|
64483
64514
|
var common3 = { needsAuth: true, needsNetwork: true };
|
|
64484
64515
|
var requestId4 = () => `cli-${randomUUID4()}`;
|
|
@@ -64691,7 +64722,7 @@ function readPushFiles(inv) {
|
|
|
64691
64722
|
let content;
|
|
64692
64723
|
try {
|
|
64693
64724
|
if (statSync(absolute).size > 5e6) throw new UsageError(`${path} is larger than 5 MB; push it with git and a token instead`, { hint: `overlane repo token <repo> --scope write` });
|
|
64694
|
-
content =
|
|
64725
|
+
content = readFileSync9(absolute, "utf8");
|
|
64695
64726
|
} catch (error62) {
|
|
64696
64727
|
if (error62 instanceof UsageError) throw error62;
|
|
64697
64728
|
throw new UsageError(`could not read ${path}`);
|
|
@@ -65075,7 +65106,7 @@ var repoCommands = [
|
|
|
65075
65106
|
// ../cli/src/commands/ci.ts
|
|
65076
65107
|
init_src();
|
|
65077
65108
|
init_zod();
|
|
65078
|
-
import { readFileSync as
|
|
65109
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
65079
65110
|
import { resolve as resolve9 } from "node:path";
|
|
65080
65111
|
var RUN_ARG = { name: "run", required: true, description: "The run ID" };
|
|
65081
65112
|
function arg2(inv, index, what, hint) {
|
|
@@ -65104,7 +65135,7 @@ var ciValidateCommand = defineCommand({
|
|
|
65104
65135
|
const file2 = textFlag(inv, "file") ?? PIPELINE_CONFIG_PATH;
|
|
65105
65136
|
let text2;
|
|
65106
65137
|
try {
|
|
65107
|
-
text2 =
|
|
65138
|
+
text2 = readFileSync10(resolve9(inv.deps.paths.cwd, file2), "utf8");
|
|
65108
65139
|
} catch {
|
|
65109
65140
|
throw new UsageError(`could not read ${file2}`, { hint: "overlane ci validate --file <path>" });
|
|
65110
65141
|
}
|
|
@@ -65608,7 +65639,7 @@ var deployCommands = [deployTargetsCommand, deployTargetAddCommand, deployEnvCre
|
|
|
65608
65639
|
init_src();
|
|
65609
65640
|
init_zod();
|
|
65610
65641
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
65611
|
-
import { readFileSync as
|
|
65642
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
65612
65643
|
import { resolve as resolve10 } from "node:path";
|
|
65613
65644
|
var common4 = { needsAuth: true, needsNetwork: true };
|
|
65614
65645
|
var requestId5 = () => `cli-${randomUUID5()}`;
|
|
@@ -65620,9 +65651,9 @@ async function planned3(inv, method, path, body2, note) {
|
|
|
65620
65651
|
const project = await offlineProject(inv.deps, "guard");
|
|
65621
65652
|
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
65622
65653
|
}
|
|
65623
|
-
function
|
|
65654
|
+
function readText4(inv, path) {
|
|
65624
65655
|
try {
|
|
65625
|
-
return
|
|
65656
|
+
return readFileSync11(resolve10(inv.deps.paths.cwd, path), "utf8");
|
|
65626
65657
|
} catch {
|
|
65627
65658
|
throw new UsageError(`could not read ${path}`, { hint: "overlane guard rules test --file rules.json --tool git.push" });
|
|
65628
65659
|
}
|
|
@@ -65697,7 +65728,7 @@ var guardRulesTestCommand = defineCommand({
|
|
|
65697
65728
|
if (file2 === void 0) throw new UsageError("rules test needs --file", { hint: "overlane guard rules test --file rules.json --tool git.push" });
|
|
65698
65729
|
let json2;
|
|
65699
65730
|
try {
|
|
65700
|
-
json2 = JSON.parse(
|
|
65731
|
+
json2 = JSON.parse(readText4(inv, file2));
|
|
65701
65732
|
} catch (error62) {
|
|
65702
65733
|
if (error62 instanceof UsageError) throw error62;
|
|
65703
65734
|
throw new UsageError(`${file2} is not valid JSON`);
|
|
@@ -65753,7 +65784,7 @@ var guardRulesPutCommand = defineCommand({
|
|
|
65753
65784
|
const offline = await offlineProject(inv.deps, "guard");
|
|
65754
65785
|
return planOutcome(inv.deps, dryRunPlan({ service: offline.serviceUrl, requests: [{ method: "PUT", path: guardPaths.rules(offline.binding.tenantId), body: { requestId: "<generated>", layer, ...layer === "project" ? { projectId: offline.binding.projectId } : {}, content: `<contents of ${file2}>`, ...reason === void 0 ? {} : { reason } }, note: "the file is validated and scanned for credentials on the server" }] }));
|
|
65755
65786
|
}
|
|
65756
|
-
const content =
|
|
65787
|
+
const content = readText4(inv, file2);
|
|
65757
65788
|
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
65758
65789
|
return { data: await call2(GuardRuleFileRecord, "PUT", guardPaths.rules(tenantId), { requestId: requestId5(), layer, ...layer === "project" ? { projectId } : {}, content, ...reason === void 0 ? {} : { reason } }) };
|
|
65759
65790
|
}
|
|
@@ -65765,7 +65796,7 @@ async function evaluate(inv, dryRun) {
|
|
|
65765
65796
|
...actionOf(inv),
|
|
65766
65797
|
...textFlag(inv, "task") === void 0 ? {} : { taskHeld: textFlag(inv, "task") === "held" },
|
|
65767
65798
|
...textFlag(inv, "summary") === void 0 ? {} : { summary: textFlag(inv, "summary") },
|
|
65768
|
-
...contentFile === void 0 ? {} : { content:
|
|
65799
|
+
...contentFile === void 0 ? {} : { content: readText4(inv, contentFile) },
|
|
65769
65800
|
...dryRun ? { dryRun: true } : {}
|
|
65770
65801
|
};
|
|
65771
65802
|
const approval = textFlag(inv, "approval");
|
|
@@ -65826,7 +65857,7 @@ var guardScanCommand = defineCommand({
|
|
|
65826
65857
|
const path = textFlag(inv, "path");
|
|
65827
65858
|
if (path === void 0) throw new UsageError("scan needs --path", { hint: "overlane guard scan --path src/config.ts" });
|
|
65828
65859
|
const { call: call2, tenantId } = await connected3(inv);
|
|
65829
|
-
const result = await call2(SecretScanResult, "POST", guardPaths.scan(tenantId), { source: textFlag(inv, "source") ?? "push", content:
|
|
65860
|
+
const result = await call2(SecretScanResult, "POST", guardPaths.scan(tenantId), { source: textFlag(inv, "source") ?? "push", content: readText4(inv, path), path });
|
|
65830
65861
|
return result.blocked ? { data: result, exit: EXIT.blocked, error: new CliError("a credential was found; nothing should be pushed until it is removed and rotated", { code: "secret_detected", exit: EXIT.blocked, hint: "overlane guard scan --path <file>" }) } : { data: result };
|
|
65831
65862
|
}
|
|
65832
65863
|
});
|
|
@@ -66147,7 +66178,7 @@ var memoryCommands = [memorySearchCommand, memoryAddCommand, memoryConfirmComman
|
|
|
66147
66178
|
init_src();
|
|
66148
66179
|
init_zod();
|
|
66149
66180
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
66150
|
-
import { readFileSync as
|
|
66181
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
66151
66182
|
var common6 = { needsAuth: true, needsNetwork: true };
|
|
66152
66183
|
var requestId7 = () => `cli-${randomUUID7()}`;
|
|
66153
66184
|
var PRIORITIES = ["P0", "P1", "P2", "P3"];
|
|
@@ -66341,7 +66372,7 @@ var issueImportCommand = defineCommand({
|
|
|
66341
66372
|
if (file2 === void 0) throw new UsageError("import needs the path of the export file");
|
|
66342
66373
|
let data;
|
|
66343
66374
|
try {
|
|
66344
|
-
data = JSON.parse(
|
|
66375
|
+
data = JSON.parse(readFileSync12(file2, "utf8"));
|
|
66345
66376
|
} catch {
|
|
66346
66377
|
throw new UsageError(`${file2} is not a readable JSON file`);
|
|
66347
66378
|
}
|
|
@@ -67220,8 +67251,11 @@ var ConnectKitResult = external_exports.union([
|
|
|
67220
67251
|
var ConnectAny = external_exports.union([ConnectResult, DryRunResult]);
|
|
67221
67252
|
|
|
67222
67253
|
// ../cli/src/disconnect.ts
|
|
67223
|
-
import { join as
|
|
67254
|
+
import { join as join18 } from "node:path";
|
|
67224
67255
|
init_zod();
|
|
67256
|
+
init_src();
|
|
67257
|
+
init_overlane_paths_node();
|
|
67258
|
+
import { existsSync as existsSync5, readdirSync } from "node:fs";
|
|
67225
67259
|
var DisconnectResult = withDryRun(
|
|
67226
67260
|
external_exports.object({
|
|
67227
67261
|
/** False when the project had nothing overlane added. */
|
|
@@ -67240,14 +67274,14 @@ async function disconnect(deps, options) {
|
|
|
67240
67274
|
const owned = readOwned(root);
|
|
67241
67275
|
const binding = readBindingFile(root);
|
|
67242
67276
|
if (owned === null) {
|
|
67243
|
-
say(deps, "Nothing to disconnect: this project has no .
|
|
67244
|
-
return { data: { disconnected: false, commands: [], removed: [], tokenDeleted: false, note: "this project has no .
|
|
67277
|
+
say(deps, "Nothing to disconnect: this project has no .overlane/state/owned.json, so overlane added nothing here.");
|
|
67278
|
+
return { data: { disconnected: false, commands: [], removed: [], tokenDeleted: false, note: "this project has no .overlane/state/owned.json, so overlane added nothing here" } };
|
|
67245
67279
|
}
|
|
67246
67280
|
const steps = [];
|
|
67247
67281
|
if (owned.claude !== void 0) steps.push(...claudeRemoveSteps(readClaudeState(root), owned.claude));
|
|
67248
67282
|
const codexState = readCodexState(deps, root);
|
|
67249
67283
|
if (owned.codex !== void 0) steps.push(...codexRemoveSteps(codexState, owned.codex));
|
|
67250
|
-
const configPath =
|
|
67284
|
+
const configPath = join18(root, CODEX_CONFIG_FILE);
|
|
67251
67285
|
const lines = owned.codex?.configLines;
|
|
67252
67286
|
const configText = readText(configPath);
|
|
67253
67287
|
const configRemovable = lines !== void 0 && configText !== null && configText.includes(lines.text);
|
|
@@ -67256,14 +67290,12 @@ async function disconnect(deps, options) {
|
|
|
67256
67290
|
$ ${formatCommand(step2)}`);
|
|
67257
67291
|
if (configRemovable) say(deps, ` remove the lines overlane added to ${CODEX_CONFIG_FILE}`);
|
|
67258
67292
|
say(deps, ` delete ${BINDING_FILE} and ${OWNED_FILE}`);
|
|
67259
|
-
if (owned.excludeLine) say(deps, ` remove ${EXCLUDE_LINE} from ${await excludePath(deps, root)}`);
|
|
67260
67293
|
say(deps, ` delete the stored token for ${owned.serviceUrl}`);
|
|
67261
67294
|
if (options.dryRun) {
|
|
67262
67295
|
say(deps, "Dry run: no command was run and no file was changed.");
|
|
67263
67296
|
const writes = [];
|
|
67264
67297
|
if (configRemovable) writes.push({ path: CODEX_CONFIG_FILE, action: "write", description: "remove the lines overlane added" });
|
|
67265
67298
|
writes.push({ path: BINDING_FILE, action: "delete", description: "the project binding" }, { path: OWNED_FILE, action: "delete", description: "the record of what connect added" });
|
|
67266
|
-
if (owned.excludeLine) writes.push({ path: await excludePath(deps, root), action: "write", description: `remove ${EXCLUDE_LINE}` });
|
|
67267
67299
|
return {
|
|
67268
67300
|
data: dryRunPlan({
|
|
67269
67301
|
commands: steps.map((step2) => formatCommand(step2)),
|
|
@@ -67292,7 +67324,7 @@ async function disconnect(deps, options) {
|
|
|
67292
67324
|
const without = configText.replace(lines.text, "");
|
|
67293
67325
|
if (without.length === 0 && lines.createdFile) {
|
|
67294
67326
|
removeFile(configPath);
|
|
67295
|
-
removeDirIfEmpty(
|
|
67327
|
+
removeDirIfEmpty(join18(root, ".codex"));
|
|
67296
67328
|
} else {
|
|
67297
67329
|
writeIfDifferent(configPath, without);
|
|
67298
67330
|
}
|
|
@@ -67302,17 +67334,21 @@ async function disconnect(deps, options) {
|
|
|
67302
67334
|
if (failures.length > 0) {
|
|
67303
67335
|
writeOwned(root, remaining);
|
|
67304
67336
|
for (const failure4 of failures) warn(deps, failure4);
|
|
67305
|
-
throw new CliError("some native commands failed; the connection is only partly removed, and
|
|
67337
|
+
throw new CliError("some native commands failed; the connection is only partly removed, and owned.json in the state folder keeps what is left. Fix the cause and run `overlane disconnect` again", {
|
|
67306
67338
|
code: "partial_disconnect",
|
|
67307
67339
|
hint: "overlane disconnect --force"
|
|
67308
67340
|
});
|
|
67309
67341
|
}
|
|
67310
|
-
|
|
67311
|
-
removeFile(join20(root, BINDING_FILE));
|
|
67342
|
+
removeFile(statePath(root, "binding"));
|
|
67312
67343
|
removed.push(BINDING_FILE, OWNED_FILE);
|
|
67313
67344
|
removeOwned(root);
|
|
67314
|
-
removeFile(
|
|
67315
|
-
|
|
67345
|
+
removeFile(statePath(root, "misses"));
|
|
67346
|
+
const state = join18(root, STATE_DIR);
|
|
67347
|
+
if (existsSync5(state) && readdirSync(state).every((name2) => name2 === ".gitignore")) {
|
|
67348
|
+
removeFile(join18(state, ".gitignore"));
|
|
67349
|
+
removeDirIfEmpty(state);
|
|
67350
|
+
}
|
|
67351
|
+
removeDirIfEmpty(join18(root, OVERLANE_DIR));
|
|
67316
67352
|
const serviceUrl = binding.kind === "ok" ? binding.binding.serviceUrl : owned.serviceUrl;
|
|
67317
67353
|
await deleteTokens(deps, serviceUrl);
|
|
67318
67354
|
if (await loadTokens(deps, serviceUrl) !== null) {
|
|
@@ -67331,17 +67367,17 @@ init_zod();
|
|
|
67331
67367
|
|
|
67332
67368
|
// ../cli/src/rules.ts
|
|
67333
67369
|
init_src();
|
|
67334
|
-
import { existsSync as
|
|
67335
|
-
import { dirname as
|
|
67370
|
+
import { existsSync as existsSync6, lstatSync as lstatSync2, mkdirSync as mkdirSync9, readFileSync as readFileSync13, renameSync as renameSync5, writeFileSync as writeFileSync8 } from "node:fs";
|
|
67371
|
+
import { dirname as dirname6, join as join19 } from "node:path";
|
|
67336
67372
|
function readIfRegular(root, relative6, unsafe) {
|
|
67337
|
-
const full =
|
|
67338
|
-
if (!
|
|
67373
|
+
const full = join19(root, relative6);
|
|
67374
|
+
if (!existsSync6(full) && !isLink(full)) return null;
|
|
67339
67375
|
const stat = lstatSync2(full);
|
|
67340
67376
|
if (stat.isSymbolicLink() || !stat.isFile()) {
|
|
67341
67377
|
unsafe.push(relative6);
|
|
67342
67378
|
return null;
|
|
67343
67379
|
}
|
|
67344
|
-
return
|
|
67380
|
+
return readFileSync13(full, "utf8");
|
|
67345
67381
|
}
|
|
67346
67382
|
function isLink(path) {
|
|
67347
67383
|
try {
|
|
@@ -67380,10 +67416,10 @@ function applyPlan2(root, plan3) {
|
|
|
67380
67416
|
const written = [];
|
|
67381
67417
|
for (const step2 of plan3.steps) {
|
|
67382
67418
|
if (step2.next === null) continue;
|
|
67383
|
-
const full =
|
|
67384
|
-
|
|
67419
|
+
const full = join19(root, step2.path);
|
|
67420
|
+
mkdirSync9(dirname6(full), { recursive: true });
|
|
67385
67421
|
const temp = `${full}.overlane-tmp`;
|
|
67386
|
-
|
|
67422
|
+
writeFileSync8(temp, step2.next, { encoding: "utf8", mode: 420 });
|
|
67387
67423
|
renameSync5(temp, full);
|
|
67388
67424
|
written.push(step2.path);
|
|
67389
67425
|
}
|
|
@@ -67482,22 +67518,22 @@ async function doctor(deps, options) {
|
|
|
67482
67518
|
// ../cli/src/kit/setup.ts
|
|
67483
67519
|
init_src();
|
|
67484
67520
|
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
67485
|
-
import { existsSync as
|
|
67486
|
-
import { join as
|
|
67521
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3 } from "node:fs";
|
|
67522
|
+
import { join as join21 } from "node:path";
|
|
67487
67523
|
|
|
67488
67524
|
// ../cli/src/kit/ci.ts
|
|
67489
|
-
import { existsSync as
|
|
67490
|
-
import { join as
|
|
67525
|
+
import { existsSync as existsSync7, readdirSync as readdirSync2 } from "node:fs";
|
|
67526
|
+
import { join as join20 } from "node:path";
|
|
67491
67527
|
var ACTION_PINS = {
|
|
67492
67528
|
checkout: "actions/checkout@v7.0.1",
|
|
67493
67529
|
setupNode: "actions/setup-node@v7.0.0",
|
|
67494
67530
|
pnpm: "pnpm/action-setup@v6.1.0",
|
|
67495
67531
|
setupPython: "actions/setup-python@v7.0.0"
|
|
67496
67532
|
};
|
|
67497
|
-
var CI_FILE =
|
|
67533
|
+
var CI_FILE = join20(".github", "workflows", "ci.yml");
|
|
67498
67534
|
function hasCi(root) {
|
|
67499
67535
|
try {
|
|
67500
|
-
return
|
|
67536
|
+
return readdirSync2(join20(root, ".github", "workflows")).some((name2) => /\.ya?ml$/.test(name2));
|
|
67501
67537
|
} catch {
|
|
67502
67538
|
return false;
|
|
67503
67539
|
}
|
|
@@ -67509,12 +67545,12 @@ function ciWorkflow(root, detected) {
|
|
|
67509
67545
|
for (const run3 of detected.typecheck ?? []) commands.push({ name: "Typecheck", run: run3 });
|
|
67510
67546
|
for (const run3 of detected.test) commands.push({ name: "Test", run: run3 });
|
|
67511
67547
|
if (!commands.some((command) => command.name !== "Install")) return null;
|
|
67512
|
-
const node2 =
|
|
67513
|
-
const python =
|
|
67548
|
+
const node2 = existsSync7(join20(root, "package.json"));
|
|
67549
|
+
const python = existsSync7(join20(root, "pyproject.toml"));
|
|
67514
67550
|
const steps = [` - uses: ${ACTION_PINS.checkout}`];
|
|
67515
67551
|
if (node2) {
|
|
67516
67552
|
if (detected.install?.startsWith("pnpm")) steps.push(` - uses: ${ACTION_PINS.pnpm}`);
|
|
67517
|
-
const version2 =
|
|
67553
|
+
const version2 = existsSync7(join20(root, ".nvmrc")) ? "node-version-file: .nvmrc" : "node-version: 22";
|
|
67518
67554
|
steps.push(` - uses: ${ACTION_PINS.setupNode}`, " with:", ` ${version2}`);
|
|
67519
67555
|
}
|
|
67520
67556
|
if (python) {
|
|
@@ -67532,7 +67568,7 @@ var BLOCK_END = "<!-- overlane-kit:run-step:end -->";
|
|
|
67532
67568
|
var BLOCK_BODY = [
|
|
67533
67569
|
"## Autonomous runs",
|
|
67534
67570
|
"",
|
|
67535
|
-
"The plan is in `.
|
|
67571
|
+
"The plan is in `.overlane/plan/`. To work on it, use the run-step skill: one bounded run, one task at a time, within the task's allowed paths.",
|
|
67536
67572
|
AGENTS_LINE,
|
|
67537
67573
|
"Decide questions yourself and record the decision with `overlane run decide`; do not wait for an answer."
|
|
67538
67574
|
].join("\n");
|
|
@@ -67556,7 +67592,7 @@ var INSTRUCTION_FILES = ["CLAUDE.md", "AGENTS.md"];
|
|
|
67556
67592
|
var runPrompt = (projectId) => `Run one bounded step with the run-step skill for project ${projectId}.`;
|
|
67557
67593
|
function hasSpecKit(root) {
|
|
67558
67594
|
try {
|
|
67559
|
-
return
|
|
67595
|
+
return readdirSync3(join21(root, "specs"), { withFileTypes: true }).some((entry) => entry.isDirectory() && existsSync8(join21(root, "specs", entry.name, "tasks.md")));
|
|
67560
67596
|
} catch {
|
|
67561
67597
|
return false;
|
|
67562
67598
|
}
|
|
@@ -67613,15 +67649,15 @@ async function connectKit(deps, options) {
|
|
|
67613
67649
|
const project = await detectProject(deps, { name: options.name, provider: options.provider });
|
|
67614
67650
|
const { root } = project;
|
|
67615
67651
|
if (await headCommit(deps, root) === null) throw new CliError("the repository has no commit yet; make an initial commit first");
|
|
67616
|
-
const planDir =
|
|
67617
|
-
const planExists =
|
|
67652
|
+
const planDir = join21(root, PLAN_DIR2);
|
|
67653
|
+
const planExists = existsSync8(join21(planDir, "project.md"));
|
|
67618
67654
|
const ciExists = hasCi(root);
|
|
67619
67655
|
let plan3;
|
|
67620
67656
|
let planSource;
|
|
67621
67657
|
try {
|
|
67622
67658
|
if (planExists) {
|
|
67623
67659
|
plan3 = await readPlan(root);
|
|
67624
|
-
planSource = `${
|
|
67660
|
+
planSource = `${PLAN_DIR2}/ already exists; kept as it is`;
|
|
67625
67661
|
} else if (options.mode === "new") {
|
|
67626
67662
|
plan3 = newPlan(project.name, options.goal ?? "", !ciExists);
|
|
67627
67663
|
planSource = "minimal plan from --goal";
|
|
@@ -67638,7 +67674,7 @@ async function connectKit(deps, options) {
|
|
|
67638
67674
|
}
|
|
67639
67675
|
const detected = await detectCommands(root);
|
|
67640
67676
|
const workflow = ciExists ? null : ciWorkflow(root, detected);
|
|
67641
|
-
const blocks = INSTRUCTION_FILES.map((file2) => ({ file: file2, before: readText(
|
|
67677
|
+
const blocks = INSTRUCTION_FILES.map((file2) => ({ file: file2, before: readText(join21(root, file2)) })).map((entry) => ({ ...entry, after: withBlock2(entry.before) }));
|
|
67642
67678
|
const blockChanges = blocks.filter((entry) => entry.after !== entry.before);
|
|
67643
67679
|
const firstMilestone = plan3.milestones[0]?.id ?? DEFAULT_RUN_POLICY.buildAheadLimit;
|
|
67644
67680
|
const branchExists = (await gitOut(deps, root, "rev-parse", "--verify", "--quiet", `refs/heads/${KIT_BRANCH}`)).code === 0;
|
|
@@ -67648,10 +67684,10 @@ async function connectKit(deps, options) {
|
|
|
67648
67684
|
if (unsaved.length > 0 && !options.dryRun) throw new CliError(`uncommitted changes in ${unsaved.join(", ")}; commit or stash them so the kit commit holds only its own lines`);
|
|
67649
67685
|
say(deps, `Kit setup (${options.mode}) for ${projectLabel(project)}`);
|
|
67650
67686
|
say(deps, ` branch: create ${KIT_BRANCH}`);
|
|
67651
|
-
say(deps, ` plan: ${planSource} (${plan3.milestones.length} milestone(s), ${plan3.tasks.length} task(s))${planExists ? "" : `, written to ${
|
|
67687
|
+
say(deps, ` plan: ${planSource} (${plan3.milestones.length} milestone(s), ${plan3.tasks.length} task(s))${planExists ? "" : `, written to ${PLAN_DIR2}/`}`);
|
|
67652
67688
|
say(deps, ciExists ? " ci: a workflow already exists; left alone" : workflow === null ? " ci: no install, typecheck or test command detected, so no workflow is written (the plan task adds it)" : ` ci: write ${CI_FILE} (pinned actions; runs ${[detected.install, ...detected.typecheck ?? [], ...detected.test].filter((c2) => c2 !== void 0).join("; ")})`);
|
|
67653
67689
|
for (const entry of blocks) say(deps, ` ${entry.file}: ${entry.after === entry.before ? "block already present" : entry.before === null ? "create with the run-step block" : "append the run-step block (your text is untouched)"}`);
|
|
67654
|
-
say(deps, " binding: the normal connect flow (plugins, .
|
|
67690
|
+
say(deps, " binding: the normal connect flow (plugins, .overlane/state/project.json)");
|
|
67655
67691
|
say(deps, ` policy: default run policy, build-ahead limit ${firstMilestone}`);
|
|
67656
67692
|
say(deps, " sync: send the plan to the service");
|
|
67657
67693
|
say(deps, " review: commit on the branch and open one pull request (or print the exact commands)");
|
|
@@ -67664,7 +67700,7 @@ async function connectKit(deps, options) {
|
|
|
67664
67700
|
say(deps, "Dry run: no file was written and no branch, commit or service change was made.");
|
|
67665
67701
|
const base5 = inner.data !== void 0 && "dryRun" in inner.data ? inner.data : dryRunPlan({});
|
|
67666
67702
|
const writes = [
|
|
67667
|
-
...planExists ? [] : [{ path: `${
|
|
67703
|
+
...planExists ? [] : [{ path: `${PLAN_DIR2}/`, action: "write", description: planSource }],
|
|
67668
67704
|
...workflow === null ? [] : [{ path: CI_FILE, action: "write", description: "CI workflow with pinned actions" }],
|
|
67669
67705
|
...blockChanges.map((entry) => ({ path: entry.file, action: entry.before === null ? "write" : "append", description: "the run-step block" })),
|
|
67670
67706
|
...base5.writes
|
|
@@ -67693,22 +67729,22 @@ async function connectKit(deps, options) {
|
|
|
67693
67729
|
await gitOk(deps, root, "switch", "-c", KIT_BRANCH);
|
|
67694
67730
|
if (!planExists) await writePlan(root, plan3);
|
|
67695
67731
|
const written = [];
|
|
67696
|
-
if (workflow !== null && writeIfDifferent(
|
|
67697
|
-
for (const entry of blockChanges) if (writeIfDifferent(
|
|
67698
|
-
const agentConfig = [
|
|
67732
|
+
if (workflow !== null && writeIfDifferent(join21(root, CI_FILE), workflow)) written.push(CI_FILE);
|
|
67733
|
+
for (const entry of blockChanges) if (writeIfDifferent(join21(root, entry.file), entry.after)) written.push(entry.file);
|
|
67734
|
+
const agentConfig = [join21(".claude", "settings.json"), join21(".codex", "config.toml")];
|
|
67699
67735
|
const preDirty = new Set(await dirty(deps, root, agentConfig));
|
|
67700
|
-
const preExisting = new Set(agentConfig.filter((file2) =>
|
|
67736
|
+
const preExisting = new Set(agentConfig.filter((file2) => existsSync8(join21(root, file2))));
|
|
67701
67737
|
const connected11 = await connect(deps, { ...options, yes: true });
|
|
67702
67738
|
if (connected11.error !== void 0 || readBindingFile(root).kind !== "ok") {
|
|
67703
67739
|
throw new CliError(`connect did not finish; the kit files are on ${KIT_BRANCH}, uncommitted. Fix the cause and run \`overlane connect\`, then commit`, { code: "connect_incomplete", hint: "overlane connect --yes" });
|
|
67704
67740
|
}
|
|
67705
67741
|
const connectData = connected11.data !== void 0 && !("dryRun" in connected11.data) ? connected11.data : void 0;
|
|
67706
67742
|
for (const file2 of agentConfig) {
|
|
67707
|
-
if (!
|
|
67743
|
+
if (!existsSync8(join21(root, file2)) || preDirty.has(file2) || preExisting.has(file2) && (await dirty(deps, root, [file2])).length === 0) continue;
|
|
67708
67744
|
if ((await gitOut(deps, root, "check-ignore", "-q", "--", file2)).code === 0) continue;
|
|
67709
67745
|
written.push(file2);
|
|
67710
67746
|
}
|
|
67711
|
-
await gitOk(deps, root, "add", "-f", "--",
|
|
67747
|
+
await gitOk(deps, root, "add", "-f", "--", PLAN_DIR2);
|
|
67712
67748
|
if (written.length > 0) await gitOk(deps, root, "add", "--", ...written);
|
|
67713
67749
|
await gitOk(deps, root, "commit", "-m", "Set up the project kit", "-m", `Plan files, ${workflow === null ? "no new CI" : "CI"} and the run-step block. Review, merge, then the scheduler runs bounded steps.`);
|
|
67714
67750
|
const sha = (await gitOk(deps, root, "rev-parse", "HEAD")).trim();
|
|
@@ -67770,7 +67806,7 @@ var ROOT_FLAG = { name: "marketplace-root", type: "string", value: "DIR", descri
|
|
|
67770
67806
|
var connectCommand = defineCommand({
|
|
67771
67807
|
path: ["connect"],
|
|
67772
67808
|
summary: "Connect this project (native Overlane, or your GitHub repository): sign in, bind it, register the plugin; --kit also sets up a plan",
|
|
67773
|
-
description: "Works in any git project, with no GitHub account: without a GitHub origin the project is a native Overlane project named after the folder (--name renames it). With a github.com origin it binds that repository instead (--provider overlane keeps it native). Detects the installed agents, previews the plan, then (with --yes) signs in through the browser, creates or looks up the project on the service, runs the agents' native plugin commands, writes .
|
|
67809
|
+
description: "Works in any git project, with no GitHub account: without a GitHub origin the project is a native Overlane project named after the folder (--name renames it). With a github.com origin it binds that repository instead (--provider overlane keeps it native). Detects the installed agents, previews the plan, then (with --yes) signs in through the browser, creates or looks up the project on the service, runs the agents' native plugin commands, writes .overlane/state/project.json and records what it added in .overlane/state/owned.json so `overlane disconnect` removes only that. With --kit existing|new it also drafts the plan files, CI and a pull request. Without a terminal it never prompts: pass --yes, or --dry-run to preview.",
|
|
67774
67810
|
flags: [
|
|
67775
67811
|
{ name: "service", type: "string", value: "URL", description: "Service address (https); default is the hosted service or OVERLANE_SERVICE_URL" },
|
|
67776
67812
|
ROOT_FLAG,
|
|
@@ -67822,7 +67858,7 @@ var doctorCommand = defineCommand({
|
|
|
67822
67858
|
var disconnectCommand = defineCommand({
|
|
67823
67859
|
path: ["disconnect"],
|
|
67824
67860
|
summary: "Remove what connect added to this project and delete the stored token",
|
|
67825
|
-
description: "Removes only what .
|
|
67861
|
+
description: "Removes only what .overlane/state/owned.json records: the native plugin entries, the Codex config lines connect appended, the binding, and the stored token. Hosted history is untouched. Destructive: without a terminal it needs --force.",
|
|
67826
67862
|
examples: ["overlane disconnect --dry-run", "overlane disconnect --force"],
|
|
67827
67863
|
effect: "destructive",
|
|
67828
67864
|
keywords: ["remove", "uninstall", "unlink", "detach", "undo connect", "leave", "delete binding", "forget", "sign out", "logout", "clean up"],
|
|
@@ -67925,7 +67961,7 @@ async function updateRelease(deps, input2) {
|
|
|
67925
67961
|
{ method: "GET", path: input2.to === void 0 ? releasePaths.one(tenantId, "<pinned digest>") : releasePaths.one(tenantId, input2.to) }
|
|
67926
67962
|
],
|
|
67927
67963
|
commands: [...updateSteps("claude"), ...updateSteps("codex")].map((step2) => `${step2.command} ${step2.args.join(" ")}`),
|
|
67928
|
-
writes: [{ path: ".
|
|
67964
|
+
writes: [{ path: ".overlane/state/release.json", action: "write", description: "the installed release record, written only after the commands succeed" }],
|
|
67929
67965
|
notes: ["No credentials were found, so the release was not read and no diff is shown."]
|
|
67930
67966
|
})
|
|
67931
67967
|
);
|
|
@@ -67945,7 +67981,7 @@ async function rollbackRelease(deps, input2) {
|
|
|
67945
67981
|
service: project.serviceUrl,
|
|
67946
67982
|
requests: [{ method: "POST", path: releasePaths.rollback(project.binding.tenantId, project.binding.projectId), body: {}, note: "moves the project's pin back to the previous release" }],
|
|
67947
67983
|
commands: [...updateSteps("claude"), ...updateSteps("codex")].map((step2) => `${step2.command} ${step2.args.join(" ")}`),
|
|
67948
|
-
writes: [{ path: ".
|
|
67984
|
+
writes: [{ path: ".overlane/state/release.json", action: "write", description: "the installed release record, written only after the commands succeed" }],
|
|
67949
67985
|
notes: ["After the pin moves, the previous release is installed the way `overlane release update` installs it."]
|
|
67950
67986
|
})
|
|
67951
67987
|
);
|
|
@@ -68025,7 +68061,7 @@ var releaseListCommand = defineCommand({
|
|
|
68025
68061
|
var releaseStatusCommand = defineCommand({
|
|
68026
68062
|
path: ["release", "status"],
|
|
68027
68063
|
summary: "Show the installed release against the project's pin",
|
|
68028
|
-
description: `Compares the installed release (.
|
|
68064
|
+
description: `Compares the installed release (.overlane/state/release.json) with the project binding and the service's pin, and lists approvals recorded on this machine. Works when the service is down (the pin then reads "unreachable").`,
|
|
68029
68065
|
examples: ["overlane release status"],
|
|
68030
68066
|
effect: "read",
|
|
68031
68067
|
...common9,
|
|
@@ -68124,7 +68160,7 @@ var EXECUTOR = { name: "executor", type: "string", enum: ["claude-code", "codex"
|
|
|
68124
68160
|
var STOP_NOTE = "A stop (policy paused, a budget spent, nothing runnable) exits 6 with the reason in the error code and the exact `overlane run end --reason ...` as the hint.";
|
|
68125
68161
|
var runStartCommand = defineCommand({
|
|
68126
68162
|
path: ["run", "start"],
|
|
68127
|
-
summary: "Start a bounded run and record it in .
|
|
68163
|
+
summary: "Start a bounded run and record it in .overlane/state/run.json",
|
|
68128
68164
|
description: `Starts one bounded run for this working copy after checking the run policy. ${STOP_NOTE}`,
|
|
68129
68165
|
flags: [{ name: "trigger", type: "string", enum: ["schedule", "interactive", "event"], default: "interactive", description: "What started the run" }, EXECUTOR],
|
|
68130
68166
|
examples: ["overlane run start --trigger schedule", "overlane run start --dry-run"],
|
|
@@ -68178,7 +68214,7 @@ var runDecideCommand = defineCommand({
|
|
|
68178
68214
|
var runEndCommand = defineCommand({
|
|
68179
68215
|
path: ["run", "end"],
|
|
68180
68216
|
summary: "End the active run and release its leases",
|
|
68181
|
-
description: "Ends the run with a stop reason, removes .
|
|
68217
|
+
description: "Ends the run with a stop reason, removes .overlane/state/run.json and reports how many tasks were claimed and verified. Run it even when stopping early. Exit 1 when the service reports leases that were not released.",
|
|
68182
68218
|
flags: [{ name: "reason", type: "string", required: true, enum: RUN_STOP_REASONS, description: "Why the run ended" }],
|
|
68183
68219
|
examples: ["overlane run end --reason nothing_runnable", "overlane run end --reason error"],
|
|
68184
68220
|
effect: "write",
|
|
@@ -68224,17 +68260,17 @@ var runResumeCommand = defineCommand({
|
|
|
68224
68260
|
var runCommands = [runStartCommand, runNextCommand, runClaimCommand, runDecideCommand, runEndCommand, runStatusCommand, runPauseCommand, runResumeCommand];
|
|
68225
68261
|
|
|
68226
68262
|
// ../cli/src/task/queue.ts
|
|
68263
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
68264
|
+
import { renameSync as renameSync6, writeFileSync as writeFileSync9 } from "node:fs";
|
|
68227
68265
|
init_src();
|
|
68228
68266
|
init_zod();
|
|
68229
|
-
|
|
68230
|
-
|
|
68231
|
-
import { dirname as dirname9, join as join24 } from "node:path";
|
|
68232
|
-
var TASK_POLICY_PATH = join24(".harness", "task-policy.json");
|
|
68267
|
+
init_overlane_paths_node();
|
|
68268
|
+
var TASK_POLICY_PATH = ".overlane/state/task-policy.json";
|
|
68233
68269
|
function writePolicyFile(root, policy, nowMs) {
|
|
68234
|
-
|
|
68235
|
-
|
|
68270
|
+
ensureStateDir(root);
|
|
68271
|
+
const path = statePath(root, "taskPolicy");
|
|
68236
68272
|
const temp = `${path}.${process.pid}.tmp`;
|
|
68237
|
-
|
|
68273
|
+
writeFileSync9(temp, `${JSON.stringify({ enforcement: policy.enforcement, ...policy.reason === void 0 ? {} : { reason: policy.reason }, checkedAt: new Date(nowMs).toISOString() }, null, 2)}
|
|
68238
68274
|
`);
|
|
68239
68275
|
renameSync6(temp, path);
|
|
68240
68276
|
}
|
|
@@ -68433,7 +68469,7 @@ var taskPrioritiseCommand = defineCommand({
|
|
|
68433
68469
|
var taskPolicyCommand = defineCommand({
|
|
68434
68470
|
path: ["task", "policy"],
|
|
68435
68471
|
summary: "Show whether changes need an active task, and refresh this working copy's copy",
|
|
68436
|
-
description: "Reads the project's task requirement (default `required`: edits and mutating shell commands are refused without an active task) and writes it to .
|
|
68472
|
+
description: "Reads the project's task requirement (default `required`: edits and mutating shell commands are refused without an active task) and writes it to .overlane/state/task-policy.json for the hooks.",
|
|
68437
68473
|
examples: ["overlane task policy"],
|
|
68438
68474
|
effect: "read",
|
|
68439
68475
|
...common11,
|
|
@@ -68823,7 +68859,7 @@ var TaskStartResult = withDryRun(
|
|
|
68823
68859
|
external_exports.object({ taskId: external_exports.string(), version: external_exports.number(), state: external_exports.string(), holder: external_exports.string(), leaseExpiresAt: external_exports.string().optional(), next: external_exports.string() })
|
|
68824
68860
|
);
|
|
68825
68861
|
var TaskStatusResult = external_exports.object({
|
|
68826
|
-
/** This working copy holds a task (`.
|
|
68862
|
+
/** This working copy holds a task (`.overlane/state/task.json`). */
|
|
68827
68863
|
held: external_exports.boolean(),
|
|
68828
68864
|
/** The held task still has this working copy's lease. */
|
|
68829
68865
|
leaseHeld: external_exports.boolean().optional(),
|
|
@@ -68869,7 +68905,7 @@ var taskListCommand = defineCommand({
|
|
|
68869
68905
|
var taskStartCommand = defineCommand({
|
|
68870
68906
|
path: ["task", "start"],
|
|
68871
68907
|
summary: "Claim an existing task, or create one with a contract and claim it",
|
|
68872
|
-
description: "With a TASK_ID, claims that ready or paused task for this working copy (same checks as `task resume`). Without one, creates a task (outcome, acceptance criteria, required checks, allowed paths) at the current commit and claims it, writing the lease to .
|
|
68908
|
+
description: "With a TASK_ID, claims that ready or paused task for this working copy (same checks as `task resume`). Without one, creates a task (outcome, acceptance criteria, required checks, allowed paths) at the current commit and claims it, writing the lease to .overlane/state/task.json. Fails with exit 5 if this working copy already holds a task.",
|
|
68873
68909
|
args: [{ name: "task-id", required: false, description: "An existing task to claim; omit to create one from the flags" }],
|
|
68874
68910
|
flags: [
|
|
68875
68911
|
{ name: "outcome", type: "string", value: "TEXT", description: "What the task must achieve (up to 500 characters)" },
|
|
@@ -69351,7 +69387,7 @@ var developerCommands = [
|
|
|
69351
69387
|
// ../cli/src/commands/connector.ts
|
|
69352
69388
|
init_src();
|
|
69353
69389
|
init_zod();
|
|
69354
|
-
import { readFileSync as
|
|
69390
|
+
import { readFileSync as readFileSync14 } from "node:fs";
|
|
69355
69391
|
var Summary = external_exports.object({ provider: external_exports.string(), name: external_exports.string(), domain: external_exports.string(), auth: external_exports.string(), actions: external_exports.number(), nativeAlternative: external_exports.string() });
|
|
69356
69392
|
var summary = (c2) => ({ provider: c2.provider, name: c2.displayName, domain: c2.domain, auth: c2.auth.type === "oauth" ? `OAuth (${c2.auth.scopes.join(" ")})` : `key (${c2.auth.keyLabel})`, actions: c2.actions.length, nativeAlternative: c2.nativeAlternative });
|
|
69357
69393
|
var Action2 = external_exports.object({ name: external_exports.string(), summary: external_exports.string(), kind: external_exports.enum(["read", "write", "destructive"]), gateClass: external_exports.string().nullable() });
|
|
@@ -69546,7 +69582,7 @@ function inputOf(inv) {
|
|
|
69546
69582
|
const inline = textFlag(inv, "input");
|
|
69547
69583
|
const file2 = textFlag(inv, "input-file");
|
|
69548
69584
|
if (inline !== void 0 && file2 !== void 0) throw new UsageError("give --input or --input-file, not both", { hint: "overlane schema connector run" });
|
|
69549
|
-
const text2 = inline ?? (file2 === void 0 ? "{}" :
|
|
69585
|
+
const text2 = inline ?? (file2 === void 0 ? "{}" : readFileSync14(file2, "utf8"));
|
|
69550
69586
|
try {
|
|
69551
69587
|
const parsed = JSON.parse(text2);
|
|
69552
69588
|
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("not an object");
|
|
@@ -70651,7 +70687,7 @@ var egressCommands = [egressPolicyShowCommand, egressPolicySetCommand, egressChe
|
|
|
70651
70687
|
// ../cli/src/commands/enterprise.ts
|
|
70652
70688
|
init_src();
|
|
70653
70689
|
init_zod();
|
|
70654
|
-
import { readFileSync as
|
|
70690
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "node:fs";
|
|
70655
70691
|
import { resolve as resolve13 } from "node:path";
|
|
70656
70692
|
var common20 = { needsAuth: true, needsNetwork: true };
|
|
70657
70693
|
async function connected9(inv) {
|
|
@@ -70742,8 +70778,8 @@ var enterpriseAuditExportCommand = defineCommand({
|
|
|
70742
70778
|
const exported = await call2(AuditExport, "POST", enterprisePaths.auditExports(tenantId), {});
|
|
70743
70779
|
const file2 = resolve13(inv.deps.paths.cwd, textFlag(inv, "out") ?? "audit.csv");
|
|
70744
70780
|
const manifestFile = `${file2}.manifest.json`;
|
|
70745
|
-
|
|
70746
|
-
|
|
70781
|
+
writeFileSync10(file2, exported.csv);
|
|
70782
|
+
writeFileSync10(manifestFile, `${JSON.stringify(exported.manifest, null, 2)}
|
|
70747
70783
|
`);
|
|
70748
70784
|
return { data: { file: file2, manifestFile, manifest: exported.manifest } };
|
|
70749
70785
|
}
|
|
@@ -70770,8 +70806,8 @@ var enterpriseAuditVerifyCommand = defineCommand({
|
|
|
70770
70806
|
let manifest;
|
|
70771
70807
|
let csv;
|
|
70772
70808
|
try {
|
|
70773
|
-
csv =
|
|
70774
|
-
manifest = AuditExportManifest.parse(JSON.parse(
|
|
70809
|
+
csv = readFileSync15(path, "utf8");
|
|
70810
|
+
manifest = AuditExportManifest.parse(JSON.parse(readFileSync15(manifestPath, "utf8")));
|
|
70775
70811
|
} catch {
|
|
70776
70812
|
throw new UsageError(`could not read ${file2} and its manifest`, { hint: "overlane enterprise audit export --out audit.csv" });
|
|
70777
70813
|
}
|
|
@@ -71038,7 +71074,7 @@ var enterpriseDataExportCommand = defineCommand({
|
|
|
71038
71074
|
const { call: call2, tenantId } = await connected9(inv);
|
|
71039
71075
|
const report2 = await call2(DataExportReport, "POST", enterprisePaths.dataExport(tenantId), body2);
|
|
71040
71076
|
const file2 = resolve13(inv.deps.paths.cwd, textFlag(inv, "out") ?? "export.ndjson");
|
|
71041
|
-
|
|
71077
|
+
writeFileSync10(file2, report2.ndjson);
|
|
71042
71078
|
return { data: { file: file2, totalRows: report2.totalRows, stores: report2.stores } };
|
|
71043
71079
|
}
|
|
71044
71080
|
});
|
|
@@ -71655,13 +71691,13 @@ init_src();
|
|
|
71655
71691
|
init_zod();
|
|
71656
71692
|
|
|
71657
71693
|
// ../cli/src/token/brief.ts
|
|
71658
|
-
import { existsSync as
|
|
71659
|
-
import { join as
|
|
71694
|
+
import { existsSync as existsSync10, readFileSync as readFileSync16 } from "node:fs";
|
|
71695
|
+
import { join as join23 } from "node:path";
|
|
71660
71696
|
|
|
71661
71697
|
// ../cli/src/token/ctx.ts
|
|
71662
71698
|
import { execFile } from "node:child_process";
|
|
71663
|
-
import { existsSync as
|
|
71664
|
-
import { dirname as
|
|
71699
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
71700
|
+
import { dirname as dirname7, join as join22, relative as relative2, resolve as resolve14 } from "node:path";
|
|
71665
71701
|
var CoreError = class extends Error {
|
|
71666
71702
|
exit;
|
|
71667
71703
|
hint;
|
|
@@ -71689,8 +71725,8 @@ function nodeCtx(cwd, env = process.env, now = Date.now) {
|
|
|
71689
71725
|
function findRoot(cwd) {
|
|
71690
71726
|
let dir = resolve14(cwd);
|
|
71691
71727
|
for (; ; ) {
|
|
71692
|
-
if (
|
|
71693
|
-
const up =
|
|
71728
|
+
if (existsSync9(join22(dir, ".git")) || existsSync9(join22(dir, ".overlane"))) return dir;
|
|
71729
|
+
const up = dirname7(dir);
|
|
71694
71730
|
if (up === dir) return resolve14(cwd);
|
|
71695
71731
|
dir = up;
|
|
71696
71732
|
}
|
|
@@ -71746,9 +71782,9 @@ async function brief(ctx, input2) {
|
|
|
71746
71782
|
lines.push(parsed === null ? "not a git repository" : formatGitBrief(parsed));
|
|
71747
71783
|
}
|
|
71748
71784
|
if (mode === "tasks" || mode === "all") {
|
|
71749
|
-
const file2 =
|
|
71750
|
-
if (
|
|
71751
|
-
const open2 = openP0Lines(
|
|
71785
|
+
const file2 = join23(root, "TASKS.md");
|
|
71786
|
+
if (existsSync10(file2)) {
|
|
71787
|
+
const open2 = openP0Lines(readFileSync16(file2, "utf8"));
|
|
71752
71788
|
data.tasks = { source: "TASKS.md", open: open2.slice(0, MAX_TASKS), more: Math.max(0, open2.length - MAX_TASKS) };
|
|
71753
71789
|
lines.push(...open2.length === 0 ? ["no open P0 lines in TASKS.md"] : [`${open2.length} open P0:`, ...data.tasks.open], ...data.tasks.more > 0 ? [`+${data.tasks.more} more in TASKS.md`] : []);
|
|
71754
71790
|
} else {
|
|
@@ -71760,13 +71796,13 @@ async function brief(ctx, input2) {
|
|
|
71760
71796
|
}
|
|
71761
71797
|
|
|
71762
71798
|
// ../cli/src/token/code.ts
|
|
71763
|
-
import { existsSync as
|
|
71764
|
-
import { join as
|
|
71799
|
+
import { existsSync as existsSync12, readFileSync as readFileSync18, statSync as statSync2 } from "node:fs";
|
|
71800
|
+
import { join as join24, relative as relative3, resolve as resolve15 } from "node:path";
|
|
71765
71801
|
|
|
71766
71802
|
// ../cli/src/token/index-file.ts
|
|
71767
|
-
import { existsSync as
|
|
71768
|
-
|
|
71769
|
-
|
|
71803
|
+
import { existsSync as existsSync11, readFileSync as readFileSync17 } from "node:fs";
|
|
71804
|
+
init_overlane_paths_node();
|
|
71805
|
+
init_src();
|
|
71770
71806
|
var BUILD_INDEX_COMMAND = "node packages/index-builder/dist/overlane-index.mjs map --root .";
|
|
71771
71807
|
var LoadedIndex = class {
|
|
71772
71808
|
constructor(sha, fileCount, uncovered, builtAt, rows, edges) {
|
|
@@ -71865,11 +71901,11 @@ function loadFreshIndex(ctx, root) {
|
|
|
71865
71901
|
return pending;
|
|
71866
71902
|
}
|
|
71867
71903
|
async function loadFreshIndexUncached(ctx, root) {
|
|
71868
|
-
const file2 =
|
|
71869
|
-
if (!
|
|
71904
|
+
const file2 = statePath(root, "codeIndex");
|
|
71905
|
+
if (!existsSync11(file2)) return { state: "missing" };
|
|
71870
71906
|
let text2;
|
|
71871
71907
|
try {
|
|
71872
|
-
text2 =
|
|
71908
|
+
text2 = readFileSync17(file2, "utf8");
|
|
71873
71909
|
} catch {
|
|
71874
71910
|
return { state: "missing" };
|
|
71875
71911
|
}
|
|
@@ -71882,7 +71918,7 @@ async function loadFreshIndexUncached(ctx, root) {
|
|
|
71882
71918
|
ctx.git(["rev-list", "--count", `${index.sha}..HEAD`], root)
|
|
71883
71919
|
]);
|
|
71884
71920
|
if (diff.code !== 0) return { state: "unusable", reason: `the index was built at ${index.sha.slice(0, 7)}, which this checkout does not have` };
|
|
71885
|
-
const changed = new Set([...diff.stdout.split("\n"), ...untracked.code === 0 ? untracked.stdout.split("\n") : []].filter((p2) => p2 !== "" && !p2
|
|
71921
|
+
const changed = new Set([...diff.stdout.split("\n"), ...untracked.code === 0 ? untracked.stdout.split("\n") : []].filter((p2) => p2 !== "" && !isStatePath(p2)));
|
|
71886
71922
|
return { state: "ready", index, headSha: head.code === 0 ? head.stdout.trim() : "", behind: count.code === 0 ? Number.parseInt(count.stdout.trim(), 10) || 0 : 0, changed };
|
|
71887
71923
|
}
|
|
71888
71924
|
|
|
@@ -71998,9 +72034,9 @@ var escapeRegex2 = (text2) => text2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
|
71998
72034
|
var isTestPath = (path) => /(?:^|\/)(?:tests?|__tests__|fixtures)\/|\.(?:test|spec)\.[a-z]+$/.test(path);
|
|
71999
72035
|
function readLines(root, path) {
|
|
72000
72036
|
try {
|
|
72001
|
-
const file2 =
|
|
72037
|
+
const file2 = join24(root, path);
|
|
72002
72038
|
if (statSync2(file2).size > 4 * 1024 * 1024) return null;
|
|
72003
|
-
return
|
|
72039
|
+
return readFileSync18(file2, "utf8").split("\n");
|
|
72004
72040
|
} catch {
|
|
72005
72041
|
return null;
|
|
72006
72042
|
}
|
|
@@ -72049,7 +72085,7 @@ function scanForDefinitions(root, files, name2) {
|
|
|
72049
72085
|
return hits;
|
|
72050
72086
|
}
|
|
72051
72087
|
function indexProblem(fresh) {
|
|
72052
|
-
if (fresh.state === "missing") return `no code index at .
|
|
72088
|
+
if (fresh.state === "missing") return `no code index at .overlane/state/code-index.json; build it with: ${BUILD_INDEX_COMMAND}`;
|
|
72053
72089
|
if (fresh.state === "unusable") return `code index unusable (${fresh.reason}); rebuild with: ${BUILD_INDEX_COMMAND}`;
|
|
72054
72090
|
return "";
|
|
72055
72091
|
}
|
|
@@ -72112,7 +72148,7 @@ function numbered(lines, from, to) {
|
|
|
72112
72148
|
function resolveFile(ctx, root, path) {
|
|
72113
72149
|
for (const base5 of [root, ctx.cwd]) {
|
|
72114
72150
|
const full = resolve15(base5, path);
|
|
72115
|
-
if (
|
|
72151
|
+
if (existsSync12(full) && statSync2(full).isFile()) return relative3(root, full);
|
|
72116
72152
|
}
|
|
72117
72153
|
return null;
|
|
72118
72154
|
}
|
|
@@ -72306,19 +72342,19 @@ async function refsCore(ctx, input2) {
|
|
|
72306
72342
|
}
|
|
72307
72343
|
|
|
72308
72344
|
// ../cli/src/token/cloud.ts
|
|
72345
|
+
init_overlane_paths_node();
|
|
72309
72346
|
import { execFileSync } from "node:child_process";
|
|
72310
|
-
import { readFileSync as
|
|
72347
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
72311
72348
|
import { homedir } from "node:os";
|
|
72312
|
-
import { join as
|
|
72349
|
+
import { join as join25 } from "node:path";
|
|
72313
72350
|
var CLOUD_TIMEOUT_MS = 4e3;
|
|
72314
|
-
var BINDING_FILE2 = join29(".harness", "project.json");
|
|
72315
72351
|
var KEYCHAIN_SERVICE2 = "overlane";
|
|
72316
72352
|
var CloudUnavailable = class extends Error {
|
|
72317
72353
|
};
|
|
72318
72354
|
var text = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
72319
72355
|
function readCloudBinding(root) {
|
|
72320
72356
|
try {
|
|
72321
|
-
const raw = JSON.parse(
|
|
72357
|
+
const raw = JSON.parse(readFileSync19(statePath(root, "binding"), "utf8"));
|
|
72322
72358
|
const serviceUrl = text(raw["serviceUrl"]);
|
|
72323
72359
|
const tenantId = text(raw["tenantId"]);
|
|
72324
72360
|
const projectId = text(raw["projectId"]);
|
|
@@ -72329,8 +72365,8 @@ function readCloudBinding(root) {
|
|
|
72329
72365
|
}
|
|
72330
72366
|
}
|
|
72331
72367
|
function configDir(env) {
|
|
72332
|
-
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ??
|
|
72333
|
-
return
|
|
72368
|
+
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ?? join25(homedir(), ".config");
|
|
72369
|
+
return join25(base5, "overlane");
|
|
72334
72370
|
}
|
|
72335
72371
|
function readKeychain(serviceUrl) {
|
|
72336
72372
|
const commands = {
|
|
@@ -72365,7 +72401,7 @@ function findCloudToken(ctx, serviceUrl) {
|
|
|
72365
72401
|
}
|
|
72366
72402
|
}
|
|
72367
72403
|
try {
|
|
72368
|
-
const file2 = JSON.parse(
|
|
72404
|
+
const file2 = JSON.parse(readFileSync19(join25(configDir(ctx.env), "credentials.json"), "utf8"));
|
|
72369
72405
|
return usable(file2[serviceUrl], ctx.now());
|
|
72370
72406
|
} catch {
|
|
72371
72407
|
return null;
|
|
@@ -72373,7 +72409,7 @@ function findCloudToken(ctx, serviceUrl) {
|
|
|
72373
72409
|
}
|
|
72374
72410
|
function readOverlaySession(root) {
|
|
72375
72411
|
try {
|
|
72376
|
-
const id2 =
|
|
72412
|
+
const id2 = readFileSync19(statePath(root, "overlay", "session"), "utf8").trim();
|
|
72377
72413
|
return /^[A-Za-z0-9._-]{1,64}$/.test(id2) ? id2 : void 0;
|
|
72378
72414
|
} catch {
|
|
72379
72415
|
return void 0;
|
|
@@ -72576,8 +72612,8 @@ var codeShow = (ctx, input2) => cloudFirst(
|
|
|
72576
72612
|
|
|
72577
72613
|
// ../cli/src/token/exec.ts
|
|
72578
72614
|
import { spawn } from "node:child_process";
|
|
72579
|
-
import { createWriteStream, mkdirSync as
|
|
72580
|
-
import { join as
|
|
72615
|
+
import { createWriteStream, mkdirSync as mkdirSync11 } from "node:fs";
|
|
72616
|
+
import { join as join26 } from "node:path";
|
|
72581
72617
|
|
|
72582
72618
|
// ../cli/src/token/parsers.ts
|
|
72583
72619
|
var ANSI = /\u001b\[[0-9;?]*[A-Za-z]/g;
|
|
@@ -72918,6 +72954,7 @@ function summarise(command, output2, exit) {
|
|
|
72918
72954
|
}
|
|
72919
72955
|
|
|
72920
72956
|
// ../cli/src/token/exec.ts
|
|
72957
|
+
init_overlane_paths_node();
|
|
72921
72958
|
var MAX_CAPTURE = 64 * 1024 * 1024;
|
|
72922
72959
|
var SAFE_TOKEN = /^[A-Za-z0-9_@%+=:,./~-]+$/;
|
|
72923
72960
|
var quote2 = (token) => SAFE_TOKEN.test(token) ? token : `'${token.replaceAll("'", "'\\''")}'`;
|
|
@@ -72940,10 +72977,11 @@ async function execCommand(ctx, input2) {
|
|
|
72940
72977
|
}
|
|
72941
72978
|
const command = commandLine(input2.tokens);
|
|
72942
72979
|
const root = findRoot(ctx.cwd);
|
|
72943
|
-
|
|
72944
|
-
|
|
72980
|
+
ensureStateDir(root);
|
|
72981
|
+
const dir = statePath(root, "logs");
|
|
72982
|
+
mkdirSync11(dir, { recursive: true });
|
|
72945
72983
|
const started = ctx.now();
|
|
72946
|
-
const logFile =
|
|
72984
|
+
const logFile = join26(dir, `${utcStamp(started)}-${slugOf(input2.name, command)}.log`);
|
|
72947
72985
|
const stream = createWriteStream(logFile);
|
|
72948
72986
|
const chunks = [];
|
|
72949
72987
|
let captured = 0;
|
|
@@ -72982,9 +73020,10 @@ function signalNumber(signal) {
|
|
|
72982
73020
|
}
|
|
72983
73021
|
|
|
72984
73022
|
// ../cli/src/token/ledger.ts
|
|
72985
|
-
import { existsSync as
|
|
72986
|
-
import {
|
|
72987
|
-
|
|
73023
|
+
import { existsSync as existsSync13, readFileSync as readFileSync20 } from "node:fs";
|
|
73024
|
+
import { resolve as resolve16 } from "node:path";
|
|
73025
|
+
init_overlane_paths_node();
|
|
73026
|
+
var LEDGER_PATH = ".overlane/state/token-ledger.jsonl";
|
|
72988
73027
|
var CATEGORY_RULES = [
|
|
72989
73028
|
["wrangler", /\bwrangler\b/],
|
|
72990
73029
|
["typecheck", /\btsc\b|\btypecheck\b/],
|
|
@@ -73116,16 +73155,16 @@ async function tokensReport(ctx, input2) {
|
|
|
73116
73155
|
let read;
|
|
73117
73156
|
if (input2.transcript !== void 0) {
|
|
73118
73157
|
const file2 = resolve16(ctx.cwd, input2.transcript);
|
|
73119
|
-
if (!
|
|
73158
|
+
if (!existsSync13(file2)) return { data: { source: input2.transcript, since: input2.since ?? null, calls: 0, tokens: 0, skipped: 0, rows: [] }, lines: [`none: no transcript at ${input2.transcript}`], exit: 4 };
|
|
73120
73159
|
source = input2.transcript;
|
|
73121
|
-
read = readTranscript(
|
|
73160
|
+
read = readTranscript(readFileSync20(file2, "utf8"));
|
|
73122
73161
|
} else {
|
|
73123
|
-
const file2 =
|
|
73124
|
-
if (!
|
|
73162
|
+
const file2 = statePath(root, "ledger");
|
|
73163
|
+
if (!existsSync13(file2)) {
|
|
73125
73164
|
return { data: { source: LEDGER_PATH, since: input2.since ?? null, calls: 0, tokens: 0, skipped: 0, rows: [] }, lines: [`none: no ledger at ${LEDGER_PATH}; the tool-call hook writes it, or pass --transcript <path.jsonl>`], exit: 4 };
|
|
73126
73165
|
}
|
|
73127
73166
|
source = LEDGER_PATH;
|
|
73128
|
-
read = readLedger(
|
|
73167
|
+
read = readLedger(readFileSync20(file2, "utf8"));
|
|
73129
73168
|
}
|
|
73130
73169
|
const calls = cutoff === null ? read.calls : read.calls.filter((c2) => c2.ts >= cutoff);
|
|
73131
73170
|
const report2 = buildReport(calls, top, source, input2.since ?? null, read.skipped);
|
|
@@ -73147,7 +73186,7 @@ var TOKEN_COMMANDS = [
|
|
|
73147
73186
|
{
|
|
73148
73187
|
path: ["code", "find"],
|
|
73149
73188
|
summary: "Find where a symbol is defined: one line each, kind, qualified name, path:line",
|
|
73150
|
-
description: `Looks the name up in the local code index (.
|
|
73189
|
+
description: `Looks the name up in the local code index (.overlane/state/code-index.json) and prints "kind qualified path:line", best match first, at most --limit lines (default 20). Entries in files that changed since the index was built are replaced by a pattern scan, and the output says so. With no index, or one this checkout does not have, it prints one line saying so and falls back to a bounded literal search (git grep -n -w, at most 20 lines). ${NOTE} Use this in place of grep for "where is X defined".`,
|
|
73151
73190
|
args: [{ name: "name", required: true, description: "Symbol name, or a qualified name such as Class.method" }],
|
|
73152
73191
|
flags: [
|
|
73153
73192
|
{ name: "kind", type: "string", value: "KIND", description: "Only this kind: function, class, interface, type, constant, method, variable, property, namespace" },
|
|
@@ -73195,7 +73234,7 @@ var TOKEN_COMMANDS = [
|
|
|
73195
73234
|
{
|
|
73196
73235
|
path: ["exec"],
|
|
73197
73236
|
summary: "Run a command; keep the full output in a log and print a short status and parsed summary",
|
|
73198
|
-
description: `Runs the command after -- through the shell, streams nothing, saves stdout and stderr to .
|
|
73237
|
+
description: `Runs the command after -- through the shell, streams nothing, saves stdout and stderr to .overlane/state/logs/TIMESTAMP-NAME.log, and prints one line "ok|FAIL exit=N 12.3s log=PATH" followed by a summary parsed from the output: vitest (files and tests per package, each failing test with the first lines of its assertion), tsc (error count and the first 10 errors), esbuild and astro build errors, wrangler deploy (version id, routes, errors), wrangler d1 (bookmark, applied migrations), git push (ref updates or the rejection). A command it does not know prints nothing more on success and its last 20 lines on failure. The exit code is the command's. A failure always shows its cause; the full text is in the log.`,
|
|
73199
73238
|
args: [{ name: "command", required: true, variadic: true, description: "The command and its arguments, after --" }],
|
|
73200
73239
|
flags: [{ name: "name", type: "string", value: "NAME", description: "Label used in the log file name" }],
|
|
73201
73240
|
examples: ["overlane exec -- pnpm -r test", "overlane exec --name typecheck -- pnpm -r typecheck", "overlane exec -- 'git push -u origin wip/unit'"],
|
|
@@ -73219,7 +73258,7 @@ var TOKEN_COMMANDS = [
|
|
|
73219
73258
|
{
|
|
73220
73259
|
path: ["tokens", "report"],
|
|
73221
73260
|
summary: "Where tool-call tokens went, by category, with the terse command that replaces each",
|
|
73222
|
-
description: `Reads .
|
|
73261
|
+
description: `Reads .overlane/state/token-ledger.jsonl (one JSON object per tool call: ts, tool, category, inChars, outChars, command) or, with --transcript, a Claude Code transcript (tool_use and tool_result pairs, Bash calls categorised by command: test, typecheck, wrangler, build, git, grep/sed/cat, curl, other). Prints the top categories by estimated tokens (characters / 4) with calls, average and the suggested replacement: grep, cat and sed to overlane code find, show, outline and refs; test, typecheck, build and wrangler to overlane exec; git status and log to overlane brief git. ${NOTE}`,
|
|
73223
73262
|
args: [],
|
|
73224
73263
|
flags: [
|
|
73225
73264
|
{ name: "since", type: "string", value: "WINDOW", description: "Only calls in this window: 7d, 12h, 30m, 2w or a date" },
|
|
@@ -73253,7 +73292,7 @@ function tokenCommand(path, result, effect = "read") {
|
|
|
73253
73292
|
handler: async (inv) => {
|
|
73254
73293
|
if (inv.dryRun) {
|
|
73255
73294
|
const line3 = inv.positionals.join(" ");
|
|
73256
|
-
return planOutcome(inv.deps, dryRunPlan({ commands: [line3], writes: [{ path: ".
|
|
73295
|
+
return planOutcome(inv.deps, dryRunPlan({ commands: [line3], writes: [{ path: ".overlane/state/logs", action: "write", description: "the full output of the command, in a new log file" }] }));
|
|
73257
73296
|
}
|
|
73258
73297
|
const ctx = nodeCtx(inv.deps.paths.cwd, inv.deps.env, inv.deps.now);
|
|
73259
73298
|
try {
|
|
@@ -73563,38 +73602,38 @@ init_src2();
|
|
|
73563
73602
|
|
|
73564
73603
|
// src/data-dir.ts
|
|
73565
73604
|
import { homedir as homedir2 } from "node:os";
|
|
73566
|
-
import { join as
|
|
73605
|
+
import { join as join32 } from "node:path";
|
|
73567
73606
|
function dataDir(env = process.env, home = homedir2()) {
|
|
73568
73607
|
const override = env["OVERLANE_DATA_DIR"];
|
|
73569
73608
|
if (override !== void 0 && override !== "") return override;
|
|
73570
|
-
const base5 = env["XDG_DATA_HOME"] ?? (process.platform === "win32" ? env["LOCALAPPDATA"] : void 0) ?? (process.platform === "darwin" ?
|
|
73571
|
-
return
|
|
73609
|
+
const base5 = env["XDG_DATA_HOME"] ?? (process.platform === "win32" ? env["LOCALAPPDATA"] : void 0) ?? (process.platform === "darwin" ? join32(home, "Library", "Application Support") : join32(home, ".local", "share"));
|
|
73610
|
+
return join32(base5, "overlane");
|
|
73572
73611
|
}
|
|
73573
73612
|
function marketplaceRoot(env = process.env, home = homedir2()) {
|
|
73574
|
-
return
|
|
73613
|
+
return join32(dataDir(env, home), "marketplace");
|
|
73575
73614
|
}
|
|
73576
73615
|
|
|
73577
73616
|
// src/plugin.ts
|
|
73578
|
-
import { readFileSync as
|
|
73579
|
-
import { join as
|
|
73617
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
73618
|
+
import { join as join34 } from "node:path";
|
|
73580
73619
|
import { parseArgs as parseArgs3 } from "node:util";
|
|
73581
73620
|
|
|
73582
73621
|
// src/marketplace.ts
|
|
73583
73622
|
init_src();
|
|
73584
73623
|
import { createHash as createHash7 } from "node:crypto";
|
|
73585
|
-
import { cpSync, existsSync as
|
|
73586
|
-
import { dirname as
|
|
73624
|
+
import { cpSync, existsSync as existsSync14, mkdirSync as mkdirSync12, readdirSync as readdirSync4, readFileSync as readFileSync21, renameSync as renameSync7, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync11 } from "node:fs";
|
|
73625
|
+
import { dirname as dirname9, join as join33, relative as relative4, sep } from "node:path";
|
|
73587
73626
|
var CLIENT_DIRS = ["claude", "codex"];
|
|
73588
73627
|
var TREE_DIRS = [...CLIENT_DIRS, ".claude-plugin", ".agents"];
|
|
73589
73628
|
var EMBEDDED_MANIFEST = "release-manifest.json";
|
|
73590
|
-
var INSTALLED_MANIFEST =
|
|
73629
|
+
var INSTALLED_MANIFEST = join33(".release", "manifest.json");
|
|
73591
73630
|
var MarketplaceError = class extends Error {
|
|
73592
73631
|
};
|
|
73593
73632
|
function loadEmbedded(packageRoot2) {
|
|
73594
|
-
const dir =
|
|
73595
|
-
const path =
|
|
73596
|
-
if (!
|
|
73597
|
-
const parsed = ReleaseManifest.safeParse(JSON.parse(
|
|
73633
|
+
const dir = join33(packageRoot2, "plugins");
|
|
73634
|
+
const path = join33(dir, EMBEDDED_MANIFEST);
|
|
73635
|
+
if (!existsSync14(path)) throw new MarketplaceError(`this package has no embedded plugin release (${path} is missing)`);
|
|
73636
|
+
const parsed = ReleaseManifest.safeParse(JSON.parse(readFileSync21(path, "utf8")));
|
|
73598
73637
|
if (!parsed.success) throw new MarketplaceError(`the embedded release manifest is invalid: ${parsed.error.message}`);
|
|
73599
73638
|
return { dir, manifest: parsed.data };
|
|
73600
73639
|
}
|
|
@@ -73602,10 +73641,10 @@ function sha2562(data) {
|
|
|
73602
73641
|
return `sha256:${createHash7("sha256").update(data).digest("hex")}`;
|
|
73603
73642
|
}
|
|
73604
73643
|
function listFiles(root, dir = root) {
|
|
73605
|
-
if (!
|
|
73644
|
+
if (!existsSync14(dir)) return [];
|
|
73606
73645
|
const out2 = [];
|
|
73607
|
-
for (const entry of
|
|
73608
|
-
const full =
|
|
73646
|
+
for (const entry of readdirSync4(dir, { withFileTypes: true })) {
|
|
73647
|
+
const full = join33(dir, entry.name);
|
|
73609
73648
|
if (entry.isDirectory()) out2.push(...listFiles(root, full));
|
|
73610
73649
|
else out2.push(relative4(root, full).split(sep).join("/"));
|
|
73611
73650
|
}
|
|
@@ -73617,15 +73656,15 @@ async function verifyTree(treeRoot, manifest) {
|
|
|
73617
73656
|
if (recomputed !== manifest.digest) problems.push(`manifest digest ${manifest.digest} does not match its file list (${recomputed})`);
|
|
73618
73657
|
const listed = new Set(manifest.files.map((file2) => file2.path));
|
|
73619
73658
|
for (const file2 of manifest.files) {
|
|
73620
|
-
const path =
|
|
73621
|
-
if (!
|
|
73659
|
+
const path = join33(treeRoot, file2.path);
|
|
73660
|
+
if (!existsSync14(path)) {
|
|
73622
73661
|
problems.push(`missing: ${file2.path}`);
|
|
73623
73662
|
continue;
|
|
73624
73663
|
}
|
|
73625
|
-
if (sha2562(
|
|
73664
|
+
if (sha2562(readFileSync21(path)) !== file2.digest) problems.push(`modified: ${file2.path}`);
|
|
73626
73665
|
}
|
|
73627
73666
|
for (const client of TREE_DIRS) {
|
|
73628
|
-
for (const found of listFiles(
|
|
73667
|
+
for (const found of listFiles(join33(treeRoot, client))) {
|
|
73629
73668
|
if (!listed.has(`${client}/${found}`)) problems.push(`unlisted: ${client}/${found}`);
|
|
73630
73669
|
}
|
|
73631
73670
|
}
|
|
@@ -73633,7 +73672,7 @@ async function verifyTree(treeRoot, manifest) {
|
|
|
73633
73672
|
}
|
|
73634
73673
|
function readInstalledManifest(target2) {
|
|
73635
73674
|
try {
|
|
73636
|
-
const parsed = ReleaseManifest.safeParse(JSON.parse(
|
|
73675
|
+
const parsed = ReleaseManifest.safeParse(JSON.parse(readFileSync21(join33(target2, INSTALLED_MANIFEST), "utf8")));
|
|
73637
73676
|
return parsed.success ? parsed.data : null;
|
|
73638
73677
|
} catch {
|
|
73639
73678
|
return null;
|
|
@@ -73658,23 +73697,23 @@ async function syncMarketplace(embedded, target2) {
|
|
|
73658
73697
|
const staging = `${target2}.new-${process.pid}`;
|
|
73659
73698
|
const previous = `${target2}.old-${process.pid}`;
|
|
73660
73699
|
rmSync4(staging, { recursive: true, force: true });
|
|
73661
|
-
|
|
73700
|
+
mkdirSync12(staging, { recursive: true });
|
|
73662
73701
|
try {
|
|
73663
73702
|
for (const client of TREE_DIRS) {
|
|
73664
|
-
if (
|
|
73703
|
+
if (existsSync14(join33(embedded.dir, client))) cpSync(join33(embedded.dir, client), join33(staging, client), { recursive: true });
|
|
73665
73704
|
}
|
|
73666
|
-
|
|
73667
|
-
|
|
73705
|
+
mkdirSync12(join33(staging, ".release"), { recursive: true });
|
|
73706
|
+
writeFileSync11(join33(staging, INSTALLED_MANIFEST), `${JSON.stringify(embedded.manifest, null, 2)}
|
|
73668
73707
|
`);
|
|
73669
73708
|
const after = await verifyTree(staging, embedded.manifest);
|
|
73670
73709
|
if (after.length > 0) throw new MarketplaceError(`the copied plugin files do not match the release manifest:
|
|
73671
73710
|
${after.join("\n ")}`);
|
|
73672
|
-
|
|
73673
|
-
if (
|
|
73711
|
+
mkdirSync12(dirname9(target2), { recursive: true });
|
|
73712
|
+
if (existsSync14(target2)) renameSync7(target2, previous);
|
|
73674
73713
|
try {
|
|
73675
73714
|
renameSync7(staging, target2);
|
|
73676
73715
|
} catch (error62) {
|
|
73677
|
-
if (
|
|
73716
|
+
if (existsSync14(previous)) renameSync7(previous, target2);
|
|
73678
73717
|
throw error62;
|
|
73679
73718
|
}
|
|
73680
73719
|
rmSync4(previous, { recursive: true, force: true });
|
|
@@ -73684,7 +73723,7 @@ async function syncMarketplace(embedded, target2) {
|
|
|
73684
73723
|
}
|
|
73685
73724
|
async function ensureMarketplace(embedded, target2) {
|
|
73686
73725
|
const installed = readInstalledManifest(target2);
|
|
73687
|
-
const present =
|
|
73726
|
+
const present = existsSync14(target2) && statSync3(target2).isDirectory();
|
|
73688
73727
|
if (installed !== null && present && !isNewer(embedded.manifest.version, installed.version)) return false;
|
|
73689
73728
|
await syncMarketplace(embedded, target2);
|
|
73690
73729
|
return true;
|
|
@@ -73696,8 +73735,8 @@ var PLUGIN_USAGE = ` overlane plugin install [--scope project|user] [--client c
|
|
|
73696
73735
|
var PluginUsageError = class extends Error {
|
|
73697
73736
|
};
|
|
73698
73737
|
function readNames(treeRoot, client) {
|
|
73699
|
-
const file2 = client === "claude" ?
|
|
73700
|
-
const parsed = JSON.parse(
|
|
73738
|
+
const file2 = client === "claude" ? join34(treeRoot, "claude", ".claude-plugin", "marketplace.json") : join34(treeRoot, "codex", ".agents", "plugins", "marketplace.json");
|
|
73739
|
+
const parsed = JSON.parse(readFileSync22(file2, "utf8"));
|
|
73701
73740
|
const record3 = parsed;
|
|
73702
73741
|
const plugin = record3.plugins?.[0]?.name;
|
|
73703
73742
|
if (typeof record3.name !== "string" || typeof plugin !== "string") throw new MarketplaceError(`${file2} names no marketplace or plugin`);
|
|
@@ -73743,7 +73782,7 @@ ${PLUGIN_USAGE}`);
|
|
|
73743
73782
|
const key = `${names.plugin}@${names.marketplace}`;
|
|
73744
73783
|
if (!await available(deps, client)) {
|
|
73745
73784
|
if (explicit !== void 0) {
|
|
73746
|
-
deps.stderr(`overlane: \`${client}\` was not found on PATH; the marketplace is at ${
|
|
73785
|
+
deps.stderr(`overlane: \`${client}\` was not found on PATH; the marketplace is at ${join34(root, client)}
|
|
73747
73786
|
`);
|
|
73748
73787
|
failed = true;
|
|
73749
73788
|
} else {
|
|
@@ -73755,7 +73794,7 @@ ${PLUGIN_USAGE}`);
|
|
|
73755
73794
|
ranAny = true;
|
|
73756
73795
|
deps.stdout(`${client}:
|
|
73757
73796
|
`);
|
|
73758
|
-
const dir =
|
|
73797
|
+
const dir = join34(root, client);
|
|
73759
73798
|
const steps = client === "claude" ? [
|
|
73760
73799
|
["claude", ["plugin", "marketplace", "add", dir, "--scope", scope]],
|
|
73761
73800
|
["claude", ["plugin", "marketplace", "update", names.marketplace]],
|
|
@@ -73923,7 +73962,7 @@ var packageCommands = [indexBuildCommand, indexUploadCommand, shimCommand, plugi
|
|
|
73923
73962
|
// src/deps.ts
|
|
73924
73963
|
import { execFile as execFile5, spawn as spawn2 } from "node:child_process";
|
|
73925
73964
|
import { homedir as homedir4 } from "node:os";
|
|
73926
|
-
import { join as
|
|
73965
|
+
import { join as join37 } from "node:path";
|
|
73927
73966
|
import { createInterface } from "node:readline/promises";
|
|
73928
73967
|
function exec(command, args2, options) {
|
|
73929
73968
|
return new Promise((resolveResult) => {
|
|
@@ -73969,8 +74008,8 @@ async function confirm(question) {
|
|
|
73969
74008
|
}
|
|
73970
74009
|
}
|
|
73971
74010
|
function configDir3(env) {
|
|
73972
|
-
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ??
|
|
73973
|
-
return
|
|
74011
|
+
const base5 = env["XDG_CONFIG_HOME"] ?? (process.platform === "win32" ? env["APPDATA"] : void 0) ?? join37(homedir4(), ".config");
|
|
74012
|
+
return join37(base5, "overlane");
|
|
73974
74013
|
}
|
|
73975
74014
|
function createDeps2(env = process.env) {
|
|
73976
74015
|
return {
|