overlane 0.1.123 → 0.1.125
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.mjs +1150 -310
- package/package.json +1 -1
- package/plugins/claude/plugins/mvrx-harness/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-context.mjs +33 -33
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-guard.mjs +24 -24
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-intake.mjs +36 -36
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-quota.mjs +34 -34
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-statusline.mjs +25 -25
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-stop.mjs +29 -29
- package/plugins/codex/plugins/mvrx-harness/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-context.mjs +33 -33
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-guard.mjs +24 -24
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-intake.mjs +36 -36
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-quota.mjs +34 -34
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-statusline.mjs +25 -25
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-stop.mjs +29 -29
- package/plugins/release-manifest.json +20 -20
package/dist/overlane.mjs
CHANGED
|
@@ -4545,7 +4545,7 @@ function isRef(value) {
|
|
|
4545
4545
|
function cloneIssues(issues) {
|
|
4546
4546
|
return issues.map((iss) => iss.path ? { ...iss, path: iss.path.slice() } : { ...iss });
|
|
4547
4547
|
}
|
|
4548
|
-
function isRecursive(inst, stack,
|
|
4548
|
+
function isRecursive(inst, stack, resolve14) {
|
|
4549
4549
|
const cached2 = recursive.get(inst);
|
|
4550
4550
|
if (cached2 !== void 0)
|
|
4551
4551
|
return cached2 ? PROVEN : NONE;
|
|
@@ -4555,7 +4555,7 @@ function isRecursive(inst, stack, resolve13) {
|
|
|
4555
4555
|
let result = NONE;
|
|
4556
4556
|
const check2 = (child) => {
|
|
4557
4557
|
if (result !== PROVEN && child?._zod) {
|
|
4558
|
-
const answer = isRecursive(child, stack,
|
|
4558
|
+
const answer = isRecursive(child, stack, resolve14);
|
|
4559
4559
|
if (answer > result)
|
|
4560
4560
|
result = answer;
|
|
4561
4561
|
}
|
|
@@ -4566,7 +4566,7 @@ function isRecursive(inst, stack, resolve13) {
|
|
|
4566
4566
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
4567
4567
|
if (spread && !desc.enumerable)
|
|
4568
4568
|
continue;
|
|
4569
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
4569
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve14) : NONE;
|
|
4570
4570
|
if (child > answer)
|
|
4571
4571
|
answer = child;
|
|
4572
4572
|
}
|
|
@@ -4630,7 +4630,7 @@ function isRecursive(inst, stack, resolve13) {
|
|
|
4630
4630
|
break;
|
|
4631
4631
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
4632
4632
|
case "lazy": {
|
|
4633
|
-
const inner = def._cachedInner ?? (
|
|
4633
|
+
const inner = def._cachedInner ?? (resolve14 ? inst._zod.innerType : void 0);
|
|
4634
4634
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
4635
4635
|
break;
|
|
4636
4636
|
}
|
|
@@ -20409,7 +20409,14 @@ var init_zod = __esm({
|
|
|
20409
20409
|
});
|
|
20410
20410
|
|
|
20411
20411
|
// ../contracts/src/common.ts
|
|
20412
|
-
|
|
20412
|
+
function withCompat(fill, schema) {
|
|
20413
|
+
return external_exports.preprocess((raw) => typeof raw === "object" && raw !== null && !Array.isArray(raw) ? fill(raw) : raw, schema);
|
|
20414
|
+
}
|
|
20415
|
+
function resolveProvider(record3) {
|
|
20416
|
+
if (record3.provider !== void 0) return record3.provider;
|
|
20417
|
+
return record3.repository !== void 0 && record3.repository !== null ? "github" : DEFAULT_PROVIDER;
|
|
20418
|
+
}
|
|
20419
|
+
var identifier, TenantId, ProjectId, TaskId, CommitSha, Sha256Digest, Timestamp, SemVer, SchemaVersion, PROVIDERS, Provider, DEFAULT_PROVIDER;
|
|
20413
20420
|
var init_common = __esm({
|
|
20414
20421
|
"../contracts/src/common.ts"() {
|
|
20415
20422
|
"use strict";
|
|
@@ -20423,6 +20430,9 @@ var init_common = __esm({
|
|
|
20423
20430
|
Timestamp = external_exports.iso.datetime({ offset: true });
|
|
20424
20431
|
SemVer = external_exports.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/, "must be a semantic version");
|
|
20425
20432
|
SchemaVersion = external_exports.literal("1");
|
|
20433
|
+
PROVIDERS = ["overlane", "github", "gitlab"];
|
|
20434
|
+
Provider = external_exports.enum(PROVIDERS);
|
|
20435
|
+
DEFAULT_PROVIDER = "overlane";
|
|
20426
20436
|
}
|
|
20427
20437
|
});
|
|
20428
20438
|
|
|
@@ -20448,7 +20458,7 @@ var init_executor = __esm({
|
|
|
20448
20458
|
});
|
|
20449
20459
|
|
|
20450
20460
|
// ../contracts/src/evidence.ts
|
|
20451
|
-
var EvidenceLevel, EvidenceSubject, InputDigests, recordBase, MachineEvidence, HumanEvidence, EvidenceRecord;
|
|
20461
|
+
var EvidenceLevel, EvidenceSubject, InputDigests, recordBase, MachineRunner, MachineEvidence, HumanEvidence, EvidenceRecord;
|
|
20452
20462
|
var init_evidence = __esm({
|
|
20453
20463
|
"../contracts/src/evidence.ts"() {
|
|
20454
20464
|
"use strict";
|
|
@@ -20477,15 +20487,20 @@ var init_evidence = __esm({
|
|
|
20477
20487
|
recordedAt: Timestamp,
|
|
20478
20488
|
executor: Executor
|
|
20479
20489
|
};
|
|
20490
|
+
MachineRunner = withCompat(
|
|
20491
|
+
(runner) => runner["provider"] === void 0 ? { ...runner, provider: runner["environment"] === "github-checks" ? "github" : "overlane" } : runner,
|
|
20492
|
+
external_exports.object({
|
|
20493
|
+
provider: Provider,
|
|
20494
|
+
identity: external_exports.string().min(1),
|
|
20495
|
+
environment: external_exports.string().min(1)
|
|
20496
|
+
}).strict()
|
|
20497
|
+
);
|
|
20480
20498
|
MachineEvidence = external_exports.object({
|
|
20481
20499
|
...recordBase,
|
|
20482
20500
|
level: external_exports.enum(["L0", "L1", "L2", "L3"]),
|
|
20483
20501
|
checkId: external_exports.string().min(1),
|
|
20484
20502
|
checkDefinitionDigest: Sha256Digest,
|
|
20485
|
-
runner:
|
|
20486
|
-
identity: external_exports.string().min(1),
|
|
20487
|
-
environment: external_exports.string().min(1)
|
|
20488
|
-
}).strict(),
|
|
20503
|
+
runner: MachineRunner,
|
|
20489
20504
|
startedAt: Timestamp,
|
|
20490
20505
|
finishedAt: Timestamp,
|
|
20491
20506
|
exitStatus: external_exports.number().int(),
|
|
@@ -20700,7 +20715,21 @@ var init_domain_event = __esm({
|
|
|
20700
20715
|
});
|
|
20701
20716
|
|
|
20702
20717
|
// ../contracts/src/api.ts
|
|
20703
|
-
|
|
20718
|
+
function checkProviderShape(value, ctx) {
|
|
20719
|
+
const provider = resolveProvider(value);
|
|
20720
|
+
const nested = value.repository?.provider;
|
|
20721
|
+
if (nested !== void 0 && nested !== provider) {
|
|
20722
|
+
ctx.addIssue({ code: "custom", path: ["repository", "provider"], message: "repository.provider must match provider" });
|
|
20723
|
+
}
|
|
20724
|
+
if (provider !== "overlane" && value.repository === void 0) {
|
|
20725
|
+
ctx.addIssue({ code: "custom", path: ["repository"], message: `a ${provider} project needs a repository` });
|
|
20726
|
+
}
|
|
20727
|
+
const host = value.repository?.host;
|
|
20728
|
+
if (host !== void 0 && host !== HOSTS[provider]) {
|
|
20729
|
+
ctx.addIssue({ code: "custom", path: ["repository", "host"], message: `host must be ${HOSTS[provider]} for provider ${provider}; name the provider for a repository that is not on github.com` });
|
|
20730
|
+
}
|
|
20731
|
+
}
|
|
20732
|
+
var apiPaths, HARNESS_SCOPES, HarnessScope, RepositoryRef, ProjectConnection, HOSTS, ProjectRepository, fillProvider, CreateProjectRequest, UpdateProjectRequest, ProjectRecord, WhoAmI, ApiError;
|
|
20704
20733
|
var init_api2 = __esm({
|
|
20705
20734
|
"../contracts/src/api.ts"() {
|
|
20706
20735
|
"use strict";
|
|
@@ -20720,24 +20749,58 @@ var init_api2 = __esm({
|
|
|
20720
20749
|
owner: external_exports.string().regex(/^[A-Za-z0-9-]{1,39}$/),
|
|
20721
20750
|
name: external_exports.string().regex(/^[A-Za-z0-9._-]{1,100}$/)
|
|
20722
20751
|
}).strict();
|
|
20723
|
-
|
|
20724
|
-
|
|
20725
|
-
|
|
20726
|
-
|
|
20727
|
-
|
|
20752
|
+
ProjectConnection = external_exports.object({
|
|
20753
|
+
provider: Provider,
|
|
20754
|
+
/** The GitHub App installation number; GitHub only. */
|
|
20755
|
+
installationId: external_exports.number().int().positive().optional(),
|
|
20756
|
+
/** The provider's own identifier for the repository or project. */
|
|
20757
|
+
externalId: external_exports.string().min(1).max(200).optional()
|
|
20728
20758
|
}).strict();
|
|
20759
|
+
HOSTS = { overlane: "overlane", github: "github.com", gitlab: "gitlab.com" };
|
|
20760
|
+
ProjectRepository = external_exports.object({
|
|
20761
|
+
provider: Provider.optional(),
|
|
20762
|
+
host: external_exports.enum(["github.com", "gitlab.com", "overlane"]).optional(),
|
|
20763
|
+
owner: external_exports.string().min(1).max(200),
|
|
20764
|
+
name: external_exports.string().regex(/^[A-Za-z0-9._-]{1,100}$/)
|
|
20765
|
+
}).strict().superRefine((repository, ctx) => {
|
|
20766
|
+
const provider = repository.provider ?? (repository.host === "gitlab.com" ? "gitlab" : repository.host === "overlane" ? "overlane" : "github");
|
|
20767
|
+
if (repository.host !== void 0 && repository.host !== HOSTS[provider]) {
|
|
20768
|
+
ctx.addIssue({ code: "custom", path: ["host"], message: `host must be ${HOSTS[provider]} for provider ${provider}` });
|
|
20769
|
+
}
|
|
20770
|
+
const pattern = provider === "gitlab" ? /^[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)*$/ : /^[A-Za-z0-9-]{1,39}$/;
|
|
20771
|
+
if (!pattern.test(repository.owner)) ctx.addIssue({ code: "custom", path: ["owner"], message: "owner is not valid for this provider" });
|
|
20772
|
+
});
|
|
20773
|
+
fillProvider = (record3) => record3["provider"] === void 0 ? { ...record3, provider: resolveProvider({ repository: record3["repository"] }) } : record3;
|
|
20774
|
+
CreateProjectRequest = withCompat(
|
|
20775
|
+
fillProvider,
|
|
20776
|
+
external_exports.object({
|
|
20777
|
+
provider: Provider,
|
|
20778
|
+
repository: ProjectRepository.optional(),
|
|
20779
|
+
connection: ProjectConnection.optional(),
|
|
20780
|
+
name: external_exports.string().min(1).max(100),
|
|
20781
|
+
/** ADR 0018: the hosted code layer is off unless a project turns it on. Missing means false. */
|
|
20782
|
+
codeLayer: external_exports.boolean().optional()
|
|
20783
|
+
}).strict().superRefine(checkProviderShape)
|
|
20784
|
+
);
|
|
20729
20785
|
UpdateProjectRequest = external_exports.object({ codeLayer: external_exports.boolean() }).strict();
|
|
20730
|
-
ProjectRecord =
|
|
20731
|
-
|
|
20732
|
-
|
|
20733
|
-
|
|
20734
|
-
|
|
20735
|
-
|
|
20736
|
-
|
|
20737
|
-
|
|
20738
|
-
|
|
20739
|
-
|
|
20740
|
-
|
|
20786
|
+
ProjectRecord = withCompat(
|
|
20787
|
+
fillProvider,
|
|
20788
|
+
external_exports.object({
|
|
20789
|
+
tenantId: TenantId,
|
|
20790
|
+
projectId: ProjectId,
|
|
20791
|
+
name: external_exports.string().min(1).max(100),
|
|
20792
|
+
/** Missing in records from before ADR 0050: reads as `github` with a repository, else `overlane`. */
|
|
20793
|
+
provider: Provider,
|
|
20794
|
+
/** Absent for a native project that has no repository yet. */
|
|
20795
|
+
repository: ProjectRepository.optional(),
|
|
20796
|
+
connection: ProjectConnection.optional(),
|
|
20797
|
+
releaseVersion: external_exports.string().min(1),
|
|
20798
|
+
releaseDigest: Sha256Digest,
|
|
20799
|
+
createdAt: Timestamp,
|
|
20800
|
+
/** ADR 0018: registers the MCP `code` tool and opens the code routes. Missing in older records means false. */
|
|
20801
|
+
codeLayer: external_exports.boolean().default(false)
|
|
20802
|
+
}).strict().superRefine(checkProviderShape)
|
|
20803
|
+
);
|
|
20741
20804
|
WhoAmI = external_exports.object({
|
|
20742
20805
|
tenantId: TenantId,
|
|
20743
20806
|
userId: external_exports.string().min(1),
|
|
@@ -20813,7 +20876,7 @@ var init_task_api = __esm({
|
|
|
20813
20876
|
});
|
|
20814
20877
|
|
|
20815
20878
|
// ../contracts/src/code-index.ts
|
|
20816
|
-
var SourceRange, PRECISION, Precision, SYMBOL_KINDS, SymbolKind, IndexedSymbol, Occurrence, FileShard, ManifestEntry, ManifestUploadResponse, ShardUploadRequest, SnapshotManifest, AnswerProvenance, SymbolHit, ReferenceHit, codePaths;
|
|
20879
|
+
var SourceRange, PRECISION, Precision, SYMBOL_KINDS, SymbolKind, IndexedSymbol, Occurrence, FileShard, ManifestEntry, ManifestUploadResponse, ShardUploadRequest, SnapshotManifest, AnswerProvenance, SymbolHit, ReferenceHit, projectBase, codePaths;
|
|
20817
20880
|
var init_code_index = __esm({
|
|
20818
20881
|
"../contracts/src/code-index.ts"() {
|
|
20819
20882
|
"use strict";
|
|
@@ -20856,13 +20919,14 @@ var init_code_index = __esm({
|
|
|
20856
20919
|
SnapshotManifest = external_exports.object({
|
|
20857
20920
|
schemaVersion: external_exports.literal("1"),
|
|
20858
20921
|
tenantId: TenantId,
|
|
20859
|
-
repository: RepositoryRef,
|
|
20922
|
+
repository: RepositoryRef.optional(),
|
|
20923
|
+
projectId: ProjectId.optional(),
|
|
20860
20924
|
commitSha: CommitSha,
|
|
20861
20925
|
branch: external_exports.string().min(1).optional(),
|
|
20862
20926
|
indexers: external_exports.array(external_exports.object({ name: external_exports.string().min(1), version: external_exports.string().min(1) }).strict()).min(1),
|
|
20863
20927
|
files: external_exports.array(ManifestEntry),
|
|
20864
20928
|
createdAt: Timestamp
|
|
20865
|
-
}).strict();
|
|
20929
|
+
}).strict().refine((manifest) => manifest.repository !== void 0 || manifest.projectId !== void 0, { message: "a manifest names a repository or a projectId" });
|
|
20866
20930
|
AnswerProvenance = external_exports.object({
|
|
20867
20931
|
requestedCommit: CommitSha.nullable(),
|
|
20868
20932
|
indexedCommit: CommitSha.nullable(),
|
|
@@ -20874,7 +20938,12 @@ var init_code_index = __esm({
|
|
|
20874
20938
|
}).strict();
|
|
20875
20939
|
SymbolHit = external_exports.object({ path: external_exports.string().min(1), symbol: external_exports.string().min(1), name: external_exports.string().min(1), kind: SymbolKind, range: SourceRange, precision: Precision, source: external_exports.enum(["cloud", "local"]) }).strict();
|
|
20876
20940
|
ReferenceHit = external_exports.object({ path: external_exports.string().min(1), symbol: external_exports.string().min(1), range: SourceRange, enclosingSymbol: external_exports.string().optional(), source: external_exports.enum(["cloud", "local"]) }).strict();
|
|
20941
|
+
projectBase = (tenantId, projectId) => `/v1/tenants/${encodeURIComponent(tenantId)}/projects/${encodeURIComponent(projectId)}`;
|
|
20877
20942
|
codePaths = {
|
|
20943
|
+
projectUploadManifest: (tenantId, projectId) => `${projectBase(tenantId, projectId)}/snapshots`,
|
|
20944
|
+
projectUploadShards: (tenantId, projectId, commit) => `${projectBase(tenantId, projectId)}/snapshots/${commit}/shards`,
|
|
20945
|
+
projectPublish: (tenantId, projectId, commit) => `${projectBase(tenantId, projectId)}/snapshots/${commit}/publish`,
|
|
20946
|
+
projectQuery: (tenantId, projectId, tool) => `${projectBase(tenantId, projectId)}/code/${tool}`,
|
|
20878
20947
|
uploadManifest: (tenantId, owner, repo) => `/v1/tenants/${encodeURIComponent(tenantId)}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/snapshots`,
|
|
20879
20948
|
uploadShards: (tenantId, owner, repo, commit) => `/v1/tenants/${encodeURIComponent(tenantId)}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/snapshots/${commit}/shards`,
|
|
20880
20949
|
publish: (tenantId, owner, repo, commit) => `/v1/tenants/${encodeURIComponent(tenantId)}/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/snapshots/${commit}/publish`,
|
|
@@ -21938,7 +22007,7 @@ function forAgent(issue2) {
|
|
|
21938
22007
|
const source = issue2.external?.source ?? "overlane";
|
|
21939
22008
|
return AgentIssueView.parse({ ...issue2, title: { trust: "untrusted_data", source, text: issue2.title }, description: { trust: "untrusted_data", source, text: issue2.description }, notice: UNTRUSTED_NOTICE });
|
|
21940
22009
|
}
|
|
21941
|
-
var prefixed, IssueId, WorkProjectId, CycleId, LabelId, ViewId, LoopId, RequestId3, Title, Description, Name, ISSUE_STATUSES, IssueStatus, SettableIssueStatus, ASSIGNEE_TYPES, AssigneeType, Assignee, ACTOR_TYPES, ActorType, Actor, TASK_LINK_STATES, IssueTaskLink, IssueTaskLinks, IssueLinks, ISSUE_SOURCES, IssueSource, ExternalRef, record2, Label, WorkProject, Cycle, Issue, UNTRUSTED_NOTICE, UntrustedText, AgentIssueView, ISSUE_FIELDS, IssueField, FieldChangeEvent, VIEW_FIELDS, ViewField, ViewCondition, ViewDefinition, SavedView, ViewGroup, ViewResult, SyncFields, SyncEnvelope, SYNC_MODES, SyncMode, SyncConfig, SetSyncConfigRequest, SyncOutcome, SyncResult, LoopTrigger, LoopDefinition, LOOP_STOP_REASONS, LoopStopReason, LoopRun, IMPORT_SOURCES, ImportSource, ImportRequest, ImportReport, CreateIssueRequest, UpdateIssueRequest, AssignIssueRequest, AssignResult, CreateLabelRequest, CreateWorkProjectRequest, UpdateWorkProjectRequest, CreateCycleRequest, CreateViewRequest, CreateLoopRequest, UpdateLoopRequest, FireLoopRequest, IssueList, LabelList, WorkProjectList, CycleList, ViewList, LoopList, IssueEventList, base2, issuePaths;
|
|
22010
|
+
var prefixed, IssueId, WorkProjectId, CycleId, LabelId, ViewId, LoopId, RequestId3, Title, Description, Name, ISSUE_STATUSES, IssueStatus, SettableIssueStatus, ASSIGNEE_TYPES, AssigneeType, Assignee, ACTOR_TYPES, ActorType, Actor, TASK_LINK_STATES, IssueTaskLink, IssueTaskLinks, IssueLinks, ISSUE_SOURCES, IssueSource, ExternalRef, record2, Label, WorkProject, Cycle, Issue, UNTRUSTED_NOTICE, UntrustedText, AgentIssueView, ISSUE_FIELDS, IssueField, FieldChangeEvent, VIEW_FIELDS, ViewField, ViewCondition, ViewDefinition, SavedView, ViewGroup, ViewResult, SyncFields, SYNC_PROVIDERS, SyncProvider, SyncEnvelope, SYNC_MODES, SyncMode, SyncConfig, SetSyncConfigRequest, SyncOutcome, SyncResult, LoopTrigger, LoopDefinition, LOOP_STOP_REASONS, LoopStopReason, LoopRun, IMPORT_SOURCES, ImportSource, ImportRequest, ImportReport, CreateIssueRequest, UpdateIssueRequest, AssignIssueRequest, AssignResult, CreateLabelRequest, CreateWorkProjectRequest, UpdateWorkProjectRequest, CreateCycleRequest, CreateViewRequest, CreateLoopRequest, UpdateLoopRequest, FireLoopRequest, IssueList, LabelList, WorkProjectList, CycleList, ViewList, LoopList, IssueEventList, base2, issuePaths;
|
|
21942
22011
|
var init_issues = __esm({
|
|
21943
22012
|
"../contracts/src/issues.ts"() {
|
|
21944
22013
|
"use strict";
|
|
@@ -22050,35 +22119,47 @@ var init_issues = __esm({
|
|
|
22050
22119
|
ViewGroup = external_exports.object({ key: external_exports.string(), issues: external_exports.array(Issue) }).strict();
|
|
22051
22120
|
ViewResult = external_exports.object({ tenantId: TenantId, viewId: ViewId.nullable(), total: external_exports.number().int().nonnegative(), groups: external_exports.array(ViewGroup) }).strict();
|
|
22052
22121
|
SyncFields = external_exports.object({ title: Title.optional(), description: Description.optional(), status: SettableIssueStatus.optional(), labels: external_exports.array(external_exports.string().min(1).max(100)).optional(), assigneeLogin: external_exports.string().max(100).nullable().optional() }).strict();
|
|
22053
|
-
|
|
22054
|
-
|
|
22055
|
-
|
|
22056
|
-
|
|
22057
|
-
|
|
22058
|
-
|
|
22059
|
-
|
|
22060
|
-
|
|
22061
|
-
|
|
22062
|
-
|
|
22063
|
-
|
|
22064
|
-
|
|
22065
|
-
|
|
22066
|
-
|
|
22067
|
-
|
|
22068
|
-
|
|
22069
|
-
|
|
22070
|
-
|
|
22122
|
+
SYNC_PROVIDERS = [...PROVIDERS, "linear", "jira"];
|
|
22123
|
+
SyncProvider = external_exports.enum(SYNC_PROVIDERS);
|
|
22124
|
+
SyncEnvelope = withCompat(
|
|
22125
|
+
(envelope) => envelope["provider"] === void 0 ? { ...envelope, provider: envelope["source"] } : envelope,
|
|
22126
|
+
external_exports.object({
|
|
22127
|
+
tenantId: TenantId,
|
|
22128
|
+
projectId: ProjectId,
|
|
22129
|
+
/** Unique per delivery or change; a second arrival does nothing. */
|
|
22130
|
+
idempotencyKey: external_exports.string().min(8).max(200),
|
|
22131
|
+
/** Per issue, from the source. A change at or below the highest applied sequence is late. */
|
|
22132
|
+
sequence: external_exports.number().int().nonnegative(),
|
|
22133
|
+
source: external_exports.enum(["github", "overlane"]),
|
|
22134
|
+
/** The system on the other side of the sync. Missing reads as `source` (github or overlane); linear, jira and gitlab name themselves here. */
|
|
22135
|
+
provider: SyncProvider,
|
|
22136
|
+
/** The source's own clock; resolves a conflict inside the sync window with the server receive time. */
|
|
22137
|
+
sourceTimestamp: Timestamp,
|
|
22138
|
+
issue: external_exports.object({ externalId: external_exports.string().min(1).max(200), url: external_exports.string().url().max(500).optional() }).strict(),
|
|
22139
|
+
change: external_exports.discriminatedUnion("kind", [
|
|
22140
|
+
external_exports.object({ kind: external_exports.literal("upsert"), fields: SyncFields }).strict(),
|
|
22141
|
+
/** A close carries the issue's other fields too: deliveries are snapshots, so a late earlier edit loses nothing. */
|
|
22142
|
+
external_exports.object({ kind: external_exports.literal("external_close"), fields: SyncFields.optional() }).strict(),
|
|
22143
|
+
external_exports.object({ kind: external_exports.literal("external_reopen"), fields: SyncFields.optional() }).strict()
|
|
22144
|
+
])
|
|
22145
|
+
}).strict()
|
|
22146
|
+
);
|
|
22071
22147
|
SYNC_MODES = ["off", "read_only", "write_back"];
|
|
22072
22148
|
SyncMode = external_exports.enum(SYNC_MODES);
|
|
22073
|
-
SyncConfig =
|
|
22074
|
-
|
|
22075
|
-
|
|
22076
|
-
|
|
22077
|
-
|
|
22078
|
-
|
|
22079
|
-
|
|
22080
|
-
|
|
22081
|
-
|
|
22149
|
+
SyncConfig = withCompat(
|
|
22150
|
+
(config2) => config2["provider"] === void 0 ? { ...config2, provider: config2["repository"] === null || config2["repository"] === void 0 ? "overlane" : "github" } : config2,
|
|
22151
|
+
external_exports.object({
|
|
22152
|
+
tenantId: TenantId,
|
|
22153
|
+
projectId: ProjectId,
|
|
22154
|
+
/** Missing reads as `github` when a repository is set, otherwise `overlane` (ADR 0050). */
|
|
22155
|
+
provider: SyncProvider,
|
|
22156
|
+
repository: external_exports.string().regex(/^[\w.-]+\/[\w.-]+$/).nullable(),
|
|
22157
|
+
mode: SyncMode,
|
|
22158
|
+
updatedBy: external_exports.string().nullable(),
|
|
22159
|
+
updatedAt: Timestamp.nullable()
|
|
22160
|
+
}).strict()
|
|
22161
|
+
);
|
|
22162
|
+
SetSyncConfigRequest = external_exports.object({ requestId: RequestId3, provider: SyncProvider.optional(), repository: external_exports.string().regex(/^[\w.-]+\/[\w.-]+$/), mode: SyncMode }).strict();
|
|
22082
22163
|
SyncOutcome = external_exports.enum(["applied", "replayed", "late", "ignored_off", "conflict_resolved", "external_close_recorded"]);
|
|
22083
22164
|
SyncResult = external_exports.object({ tenantId: TenantId, outcome: SyncOutcome, issueId: IssueId.nullable(), idempotencyKey: external_exports.string() }).strict();
|
|
22084
22165
|
LoopTrigger = external_exports.discriminatedUnion("kind", [
|
|
@@ -22192,13 +22273,23 @@ var init_issues = __esm({
|
|
|
22192
22273
|
});
|
|
22193
22274
|
|
|
22194
22275
|
// ../contracts/src/onboarding.ts
|
|
22276
|
+
function readLegacyRepoChoice(raw) {
|
|
22277
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return raw;
|
|
22278
|
+
const { kind, installationId, ...rest } = raw;
|
|
22279
|
+
if (kind === void 0 && installationId === void 0) return raw;
|
|
22280
|
+
const out2 = { ...rest };
|
|
22281
|
+
if (out2["provider"] === void 0 && kind !== void 0) out2["provider"] = kind === "native" ? "overlane" : kind;
|
|
22282
|
+
if (out2["provider"] === void 0 && installationId !== void 0) out2["provider"] = "github";
|
|
22283
|
+
if (installationId !== void 0 && out2["connection"] === void 0) out2["connection"] = { installationId };
|
|
22284
|
+
return out2;
|
|
22285
|
+
}
|
|
22195
22286
|
function initialSteps() {
|
|
22196
22287
|
return STEP_NAMES.map((step2, i2) => ({ step: step2, status: i2 === 0 ? "done" : i2 === 1 ? "active" : "pending" }));
|
|
22197
22288
|
}
|
|
22198
22289
|
function newProgress(tenantId, userId, at) {
|
|
22199
22290
|
return { tenantId, userId, step: "agents", steps: initialSteps(), data: {}, version: 0, complete: false, updatedAt: at };
|
|
22200
22291
|
}
|
|
22201
|
-
var STEP_NAMES, StepName, StepStatus, RepairAction, FAILURE_REPAIRS, FAILURE_CODES, FailureCodeSchema, StepState, Slug, RepoChoice, OnboardingData, OnboardingProgress, AdvanceRequest, AdvanceResponse, OnboardingEvent, FirstReview, onboardingPaths, PROGRESS_FIXTURE;
|
|
22292
|
+
var STEP_NAMES, StepName, StepStatus, RepairAction, FAILURE_REPAIRS, FAILURE_CODES, FailureCodeSchema, StepState, Slug, RepoChoiceShape, RepoChoice, OnboardingData, OnboardingProgress, AdvanceRequest, AdvanceResponse, OnboardingEvent, FirstReview, onboardingPaths, PROGRESS_FIXTURE;
|
|
22202
22293
|
var init_onboarding = __esm({
|
|
22203
22294
|
"../contracts/src/onboarding.ts"() {
|
|
22204
22295
|
"use strict";
|
|
@@ -22212,8 +22303,8 @@ var init_onboarding = __esm({
|
|
|
22212
22303
|
"sign-in-cancelled": { id: "retry-sign-in", text: "Sign-in was cancelled. Try again, or use the email link." },
|
|
22213
22304
|
"agent-not-connected": { id: "retry-connect", text: "The agent has not connected yet. Run the plugin command shown, then check again." },
|
|
22214
22305
|
"agent-oauth-denied": { id: "reauthorise", text: "Access was denied in the agent's own sign-in. Approve it there, then check again." },
|
|
22215
|
-
"install-cancelled": { id: "retry-install", text: "The GitHub App install was cancelled. Retry the install, or
|
|
22216
|
-
"repo-unreachable": { id: "pick-another-repo", text: "That repository could not be read. Pick another, or re-run the
|
|
22306
|
+
"install-cancelled": { id: "retry-install", text: "The GitHub App install was cancelled. Retry the install, or continue with a native Overlane project (no GitHub account needed)." },
|
|
22307
|
+
"repo-unreachable": { id: "pick-another-repo", text: "That repository could not be read. Pick another, continue with a native Overlane project, or re-run the connection to grant access." },
|
|
22217
22308
|
"task-failed": { id: "retry-task", text: "The first task did not finish. Retry it, or pick a smaller template." },
|
|
22218
22309
|
"review-unavailable": { id: "reload-review", text: "The review is not ready. Reload it, or open the task to see its evidence." },
|
|
22219
22310
|
"invite-failed": { id: "retry-invite", text: "An invitation could not be sent. Check the address and try again, or skip this step." }
|
|
@@ -22227,13 +22318,14 @@ var init_onboarding = __esm({
|
|
|
22227
22318
|
repair: RepairAction.optional()
|
|
22228
22319
|
}).strict().refine((s) => s.status === "failed" === (s.repair !== void 0 && s.failure !== void 0), { message: "a failed step carries a failure code and a repair action, and no other step does" });
|
|
22229
22320
|
Slug = external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,39}$/);
|
|
22230
|
-
|
|
22231
|
-
|
|
22321
|
+
RepoChoiceShape = external_exports.object({
|
|
22322
|
+
provider: Provider.default("overlane"),
|
|
22232
22323
|
owner: external_exports.string().regex(/^[A-Za-z0-9-]{1,39}$/),
|
|
22233
22324
|
name: external_exports.string().regex(/^[A-Za-z0-9._-]{1,100}$/),
|
|
22234
|
-
/**
|
|
22235
|
-
installationId: external_exports.number().int().positive().optional()
|
|
22325
|
+
/** Absent for a native repository. */
|
|
22326
|
+
connection: external_exports.object({ installationId: external_exports.number().int().positive().optional(), externalId: external_exports.string().min(1).max(200).optional() }).strict().optional()
|
|
22236
22327
|
}).strict();
|
|
22328
|
+
RepoChoice = external_exports.preprocess(readLegacyRepoChoice, RepoChoiceShape);
|
|
22237
22329
|
OnboardingData = external_exports.object({
|
|
22238
22330
|
agents: external_exports.array(Slug).max(20).optional(),
|
|
22239
22331
|
bots: external_exports.array(Slug).max(20).optional(),
|
|
@@ -22505,7 +22597,7 @@ var init_docs_service = __esm({
|
|
|
22505
22597
|
function base3(tenantId, projectId) {
|
|
22506
22598
|
return `/v1/tenants/${encodeURIComponent(tenantId)}/projects/${encodeURIComponent(projectId)}/review`;
|
|
22507
22599
|
}
|
|
22508
|
-
var SEVERITIES, Severity, FINDING_STATUSES, FindingStatus, counts, Finding, REVIEW_SKIP_REASONS, SkipEntry, SkipList, TokenCapNotice, REVIEW_MODES, ReviewMode, REVIEW_TRIGGERS, REVIEW_STATUSES, ReviewSummary, ReviewRun, REVIEW_PRIVACY_TEXT, ReviewSettings, UpdateReviewSettingsRequest, PullFile, PullRequestSnapshot, ReviewRunRequest, ReviewRunResponse, ReviewStatusResponse, ReviewFindingsResponse, FEEDBACK_KINDS, FeedbackRequest, LearnedRule, FeedbackResponse, AutofixRequest, AutofixResponse, RawFinding, reviewPaths;
|
|
22600
|
+
var SEVERITIES, Severity, FINDING_STATUSES, FindingStatus, counts, Finding, REVIEW_SKIP_REASONS, SkipEntry, SkipList, TokenCapNotice, REVIEW_MODES, ReviewMode, REVIEW_TRIGGERS, REVIEW_STATUSES, ReviewSummary, ReviewRun, REVIEW_PRIVACY_TEXT, ReviewSettings, UpdateReviewSettingsRequest, PullFile, PullRequestSnapshot, MAX_PATCH_BYTES, ReviewRunRequest, ReviewRunResponse, ReviewStatusResponse, ReviewFindingsResponse, FEEDBACK_KINDS, FeedbackRequest, LearnedRule, FeedbackResponse, AutofixRequest, AutofixResponse, RawFinding, reviewPaths;
|
|
22509
22601
|
var init_review = __esm({
|
|
22510
22602
|
"../contracts/src/review.ts"() {
|
|
22511
22603
|
"use strict";
|
|
@@ -22520,6 +22612,9 @@ var init_review = __esm({
|
|
|
22520
22612
|
tenantId: TenantId,
|
|
22521
22613
|
id: external_exports.string().min(1),
|
|
22522
22614
|
projectId: ProjectId,
|
|
22615
|
+
/** Where the change lives. A record from before ADR 0050 has none: read it with `reviewProvider`, which gives `github`. */
|
|
22616
|
+
provider: Provider.optional(),
|
|
22617
|
+
/** The repository key: `owner/name` for a connection, `overlane/<projectId>` or `patch/<projectId>` for native reviews. */
|
|
22523
22618
|
repository: external_exports.string().min(1),
|
|
22524
22619
|
pullNumber: external_exports.number().int().positive(),
|
|
22525
22620
|
path: external_exports.string().min(1),
|
|
@@ -22573,6 +22668,7 @@ var init_review = __esm({
|
|
|
22573
22668
|
tenantId: TenantId,
|
|
22574
22669
|
id: external_exports.string().min(1),
|
|
22575
22670
|
projectId: ProjectId,
|
|
22671
|
+
provider: Provider.optional(),
|
|
22576
22672
|
repository: external_exports.string().min(1),
|
|
22577
22673
|
pullNumber: external_exports.number().int().positive(),
|
|
22578
22674
|
headSha: CommitSha,
|
|
@@ -22613,6 +22709,7 @@ var init_review = __esm({
|
|
|
22613
22709
|
patch: external_exports.string().max(4e5).optional()
|
|
22614
22710
|
}).strict();
|
|
22615
22711
|
PullRequestSnapshot = external_exports.object({
|
|
22712
|
+
provider: Provider.optional(),
|
|
22616
22713
|
repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/),
|
|
22617
22714
|
number: external_exports.number().int().positive(),
|
|
22618
22715
|
headSha: CommitSha,
|
|
@@ -22623,10 +22720,20 @@ var init_review = __esm({
|
|
|
22623
22720
|
fork: external_exports.boolean().default(false),
|
|
22624
22721
|
files: external_exports.array(PullFile).max(3e3)
|
|
22625
22722
|
}).strict();
|
|
22723
|
+
MAX_PATCH_BYTES = 2e6;
|
|
22626
22724
|
ReviewRunRequest = external_exports.object({
|
|
22627
22725
|
requestId: external_exports.string().min(1).max(128),
|
|
22628
22726
|
trigger: external_exports.enum(REVIEW_TRIGGERS).default("manual"),
|
|
22629
22727
|
source: external_exports.discriminatedUnion("kind", [
|
|
22728
|
+
external_exports.object({
|
|
22729
|
+
kind: external_exports.literal("patch"),
|
|
22730
|
+
diff: external_exports.string().min(1).max(MAX_PATCH_BYTES),
|
|
22731
|
+
title: external_exports.string().max(500).optional(),
|
|
22732
|
+
/** Names this change so a re-review of the same change merges its findings; defaults to `patch`. */
|
|
22733
|
+
label: external_exports.string().regex(/^[A-Za-z0-9._-]{1,64}$/).optional(),
|
|
22734
|
+
author: external_exports.string().min(1).max(100).optional()
|
|
22735
|
+
}).strict(),
|
|
22736
|
+
external_exports.object({ kind: external_exports.literal("overlane"), number: external_exports.number().int().positive(), repository: external_exports.string().min(1).optional() }).strict(),
|
|
22630
22737
|
external_exports.object({ kind: external_exports.literal("github"), repository: external_exports.string().min(1), number: external_exports.number().int().positive() }).strict(),
|
|
22631
22738
|
external_exports.object({ kind: external_exports.literal("inline"), pull: PullRequestSnapshot }).strict()
|
|
22632
22739
|
])
|
|
@@ -23049,6 +23156,375 @@ var init_code_map = __esm({
|
|
|
23049
23156
|
}
|
|
23050
23157
|
});
|
|
23051
23158
|
|
|
23159
|
+
// ../contracts/src/plans.ts
|
|
23160
|
+
var PLAN_IDS, BillingPlanId, CHECKOUT_PLANS, CheckoutPlanId, METERS, Meter, AllowanceValue, PlanAllowances, PlanData, OverageRates, FreeTierControls, PlanCatalog, TenantPlanLimits;
|
|
23161
|
+
var init_plans = __esm({
|
|
23162
|
+
"../contracts/src/plans.ts"() {
|
|
23163
|
+
"use strict";
|
|
23164
|
+
init_zod();
|
|
23165
|
+
PLAN_IDS = ["free", "pro", "team", "business", "enterprise"];
|
|
23166
|
+
BillingPlanId = external_exports.enum(PLAN_IDS);
|
|
23167
|
+
CHECKOUT_PLANS = ["pro", "team", "business"];
|
|
23168
|
+
CheckoutPlanId = external_exports.enum(CHECKOUT_PLANS);
|
|
23169
|
+
METERS = ["reviews", "ciMinutes", "docsCalls", "hostedInference"];
|
|
23170
|
+
Meter = external_exports.enum(METERS);
|
|
23171
|
+
AllowanceValue = external_exports.union([external_exports.number().int().nonnegative(), external_exports.literal("unlimited"), external_exports.null()]);
|
|
23172
|
+
PlanAllowances = external_exports.object({
|
|
23173
|
+
privateProjects: AllowanceValue,
|
|
23174
|
+
tasks: AllowanceValue,
|
|
23175
|
+
reviews: AllowanceValue,
|
|
23176
|
+
docsCalls: AllowanceValue,
|
|
23177
|
+
ciMinutes: AllowanceValue
|
|
23178
|
+
}).strict();
|
|
23179
|
+
PlanData = external_exports.object({
|
|
23180
|
+
id: BillingPlanId,
|
|
23181
|
+
name: external_exports.string().min(1),
|
|
23182
|
+
audience: external_exports.string().min(1),
|
|
23183
|
+
/** Per month (per seat for per-seat plans), billed monthly. Null for Free and Enterprise. */
|
|
23184
|
+
monthlyCents: external_exports.number().int().positive().nullable(),
|
|
23185
|
+
/** Per month (per seat for per-seat plans), billed annually. */
|
|
23186
|
+
annualMonthlyCents: external_exports.number().int().positive().nullable(),
|
|
23187
|
+
unit: external_exports.enum(["free", "month", "seat / month", "custom"]),
|
|
23188
|
+
perSeat: external_exports.boolean(),
|
|
23189
|
+
/** Seat allowances are pooled across the workspace (Team) rather than held per person (REQ-BIL-07). */
|
|
23190
|
+
pooled: external_exports.boolean(),
|
|
23191
|
+
minimumSeats: external_exports.number().int().positive().optional(),
|
|
23192
|
+
maximumSeats: external_exports.number().int().positive().optional(),
|
|
23193
|
+
/** An allowance on a per-seat plan is per seat; on a workspace plan (Free) it is for the whole workspace. */
|
|
23194
|
+
allowances: PlanAllowances,
|
|
23195
|
+
/** Observability retention in days; null when the plan states none. */
|
|
23196
|
+
retentionDays: external_exports.number().int().positive().nullable(),
|
|
23197
|
+
/** Memory levels, as shown on the pricing page. */
|
|
23198
|
+
memory: external_exports.string().nullable(),
|
|
23199
|
+
/** Whether usage beyond an allowance is billed. Free has no card on file, so it stops instead (REQ-BIL-11). */
|
|
23200
|
+
overage: external_exports.boolean()
|
|
23201
|
+
}).strict();
|
|
23202
|
+
OverageRates = external_exports.object({
|
|
23203
|
+
/** Micro-dollars per review beyond the allowance ($0.10). */
|
|
23204
|
+
reviewMicros: external_exports.number().int().positive(),
|
|
23205
|
+
/** Micro-dollars per CI minute beyond the allowance ($0.006). */
|
|
23206
|
+
ciMinuteMicros: external_exports.number().int().positive(),
|
|
23207
|
+
/** Markup on hosted inference and compute at provider cost, in basis points (10% = 1000). BYOK is free. */
|
|
23208
|
+
hostedMarkupBps: external_exports.number().int().nonnegative()
|
|
23209
|
+
}).strict();
|
|
23210
|
+
FreeTierControls = external_exports.object({
|
|
23211
|
+
/** CPU seconds one CI job may use on a plan with no card on file. */
|
|
23212
|
+
ciJobCpuSeconds: external_exports.number().int().positive(),
|
|
23213
|
+
/** Requests per minute per tenant on Free, and on a paid plan. */
|
|
23214
|
+
requestsPerMinute: external_exports.number().int().positive(),
|
|
23215
|
+
paidRequestsPerMinute: external_exports.number().int().positive(),
|
|
23216
|
+
/** Only when the person has chosen to connect an account on another service (GitHub, GitLab, ...): how old it must be. No account is ever required (ADR 0050). */
|
|
23217
|
+
minimumConnectedAccountAgeDays: external_exports.number().int().nonnegative(),
|
|
23218
|
+
/** CI beyond the free allowance needs a card, which means a paid plan. */
|
|
23219
|
+
cardRequiredForCiBeyondAllowance: external_exports.literal(true)
|
|
23220
|
+
}).strict();
|
|
23221
|
+
PlanCatalog = external_exports.object({
|
|
23222
|
+
version: external_exports.literal("1"),
|
|
23223
|
+
currency: external_exports.literal("USD"),
|
|
23224
|
+
/** Every plan, in order. */
|
|
23225
|
+
plans: external_exports.array(PlanData).length(PLAN_IDS.length),
|
|
23226
|
+
overage: OverageRates,
|
|
23227
|
+
/** Length of the failed-payment grace period, in days, before any restriction (REQ-BIL-09). */
|
|
23228
|
+
graceDays: external_exports.number().int().positive(),
|
|
23229
|
+
/** Days before the end of grace that a reminder notice is sent. */
|
|
23230
|
+
graceReminderDays: external_exports.array(external_exports.number().int().positive()),
|
|
23231
|
+
freeTier: FreeTierControls
|
|
23232
|
+
}).strict().superRefine((catalog, ctx) => {
|
|
23233
|
+
catalog.plans.forEach((plan3, index) => {
|
|
23234
|
+
if (plan3.id !== PLAN_IDS[index]) ctx.addIssue({ code: "custom", path: ["plans", index, "id"], message: `plans are listed in order: expected ${PLAN_IDS[index]}` });
|
|
23235
|
+
if (plan3.monthlyCents === null !== (plan3.annualMonthlyCents === null)) ctx.addIssue({ code: "custom", path: ["plans", index], message: "monthly and annual prices are both set or both null" });
|
|
23236
|
+
if (plan3.monthlyCents !== null && plan3.annualMonthlyCents !== null && plan3.annualMonthlyCents >= plan3.monthlyCents) {
|
|
23237
|
+
ctx.addIssue({ code: "custom", path: ["plans", index, "annualMonthlyCents"], message: "annual billing is cheaper per month" });
|
|
23238
|
+
}
|
|
23239
|
+
});
|
|
23240
|
+
});
|
|
23241
|
+
TenantPlanLimits = external_exports.object({
|
|
23242
|
+
tenantId: external_exports.string().min(1),
|
|
23243
|
+
plan: BillingPlanId,
|
|
23244
|
+
seats: external_exports.number().int().positive(),
|
|
23245
|
+
/** Total for the workspace this period: per-seat allowance times seats on a per-seat plan. */
|
|
23246
|
+
allowances: PlanAllowances,
|
|
23247
|
+
retentionDays: external_exports.number().int().positive().nullable(),
|
|
23248
|
+
/** True once the tenant is past a downgrade or grace restriction: reads work, writes do not (REQ-BIL-06, REQ-BIL-09). */
|
|
23249
|
+
readOnly: external_exports.boolean(),
|
|
23250
|
+
/** Whether usage beyond an allowance is billed (true) or refused (false). */
|
|
23251
|
+
overage: external_exports.boolean(),
|
|
23252
|
+
periodStart: external_exports.iso.datetime({ offset: true }),
|
|
23253
|
+
periodEnd: external_exports.iso.datetime({ offset: true })
|
|
23254
|
+
}).strict();
|
|
23255
|
+
}
|
|
23256
|
+
});
|
|
23257
|
+
|
|
23258
|
+
// ../contracts/src/billing.ts
|
|
23259
|
+
var BillingInterval, SUBSCRIPTION_STATUSES, SubscriptionStatus, Subscription, Seat, UsageEventInput, UsageEvent, RecordUsageResponse, INVOICE_STATUSES, InvoiceStatus, InvoiceLine, Invoice, GRACE_STATES, GraceState, GraceNotice, Grace, CAP_SCOPES, CapScope, Cap, PutCapRequest, DeleteCapRequest, MeterUsage, UsageSummary, CheckoutRequest, CheckoutResponse, ChangePlanRequest, OverLimit, ChangePlanResponse, SeatChangeRequest, SeatChangeResponse, CancelRequest, PortalResponse, BillingStatus, UsageDecision, STRIPE_EVENT_TYPES, StripeEventType, epochSeconds, StripeSubscriptionObject, StripeInvoiceObject, StripeCheckoutObject, StripeEvent, WEBHOOK_OUTCOMES, WebhookOutcome, WebhookResult, billingPaths;
|
|
23260
|
+
var init_billing = __esm({
|
|
23261
|
+
"../contracts/src/billing.ts"() {
|
|
23262
|
+
"use strict";
|
|
23263
|
+
init_zod();
|
|
23264
|
+
init_common();
|
|
23265
|
+
init_plans();
|
|
23266
|
+
BillingInterval = external_exports.enum(["month", "year"]);
|
|
23267
|
+
SUBSCRIPTION_STATUSES = ["active", "past_due", "canceled", "incomplete"];
|
|
23268
|
+
SubscriptionStatus = external_exports.enum(SUBSCRIPTION_STATUSES);
|
|
23269
|
+
Subscription = external_exports.object({
|
|
23270
|
+
tenantId: TenantId,
|
|
23271
|
+
plan: BillingPlanId,
|
|
23272
|
+
interval: BillingInterval,
|
|
23273
|
+
seats: external_exports.number().int().positive(),
|
|
23274
|
+
status: SubscriptionStatus,
|
|
23275
|
+
stripeCustomerId: external_exports.string().min(1).optional(),
|
|
23276
|
+
stripeSubscriptionId: external_exports.string().min(1).optional(),
|
|
23277
|
+
currentPeriodStart: Timestamp,
|
|
23278
|
+
currentPeriodEnd: Timestamp,
|
|
23279
|
+
cancelAtPeriodEnd: external_exports.boolean(),
|
|
23280
|
+
/** Set by a downgrade over the new limits or by the end of a failed-payment grace period. Reads work; writes are refused; nothing is deleted (REQ-BIL-06). */
|
|
23281
|
+
readOnly: external_exports.boolean(),
|
|
23282
|
+
readOnlyReason: external_exports.enum(["downgrade_over_limit", "payment_failed"]).optional(),
|
|
23283
|
+
updatedAt: Timestamp
|
|
23284
|
+
}).strict();
|
|
23285
|
+
Seat = external_exports.object({
|
|
23286
|
+
tenantId: TenantId,
|
|
23287
|
+
purchased: external_exports.number().int().positive(),
|
|
23288
|
+
minimum: external_exports.number().int().positive(),
|
|
23289
|
+
maximum: external_exports.number().int().positive().nullable(),
|
|
23290
|
+
assigned: external_exports.number().int().nonnegative()
|
|
23291
|
+
}).strict();
|
|
23292
|
+
UsageEventInput = external_exports.object({
|
|
23293
|
+
meter: Meter,
|
|
23294
|
+
quantity: external_exports.number().int().positive().max(1e9),
|
|
23295
|
+
idempotencyKey: external_exports.string().min(1).max(200),
|
|
23296
|
+
/** When the usage happened (not when it arrived). */
|
|
23297
|
+
at: Timestamp,
|
|
23298
|
+
feature: external_exports.string().min(1).max(64).optional(),
|
|
23299
|
+
projectId: external_exports.string().min(1).max(128).optional(),
|
|
23300
|
+
agentId: external_exports.string().min(1).max(128).optional(),
|
|
23301
|
+
/** Provider cost in micro-dollars, for hosted inference. The platform adds the markup. */
|
|
23302
|
+
costMicros: external_exports.number().int().nonnegative().optional()
|
|
23303
|
+
}).strict();
|
|
23304
|
+
UsageEvent = UsageEventInput.extend({
|
|
23305
|
+
tenantId: TenantId,
|
|
23306
|
+
/** Monotonic per tenant, assigned when first recorded; a replay returns the first one. */
|
|
23307
|
+
sequence: external_exports.number().int().positive(),
|
|
23308
|
+
/** Start of the billing period whose invoice carries this usage. Late usage after an invoice closed lands on the next one (REQ-BIL-08). */
|
|
23309
|
+
periodStart: Timestamp,
|
|
23310
|
+
receivedAt: Timestamp,
|
|
23311
|
+
/** True when the event arrived after its own period's invoice closed. */
|
|
23312
|
+
late: external_exports.boolean()
|
|
23313
|
+
}).strict();
|
|
23314
|
+
RecordUsageResponse = external_exports.object({ event: UsageEvent, duplicate: external_exports.boolean() }).strict();
|
|
23315
|
+
INVOICE_STATUSES = ["draft", "open", "paid", "void", "uncollectible"];
|
|
23316
|
+
InvoiceStatus = external_exports.enum(INVOICE_STATUSES);
|
|
23317
|
+
InvoiceLine = external_exports.object({
|
|
23318
|
+
kind: external_exports.enum(["subscription", "proration", "usage"]),
|
|
23319
|
+
meter: Meter.optional(),
|
|
23320
|
+
description: external_exports.string().min(1).max(200),
|
|
23321
|
+
quantity: external_exports.number().int().nonnegative(),
|
|
23322
|
+
unitMicros: external_exports.number().int().nonnegative().optional(),
|
|
23323
|
+
amountCents: external_exports.number().int()
|
|
23324
|
+
}).strict();
|
|
23325
|
+
Invoice = external_exports.object({
|
|
23326
|
+
tenantId: TenantId,
|
|
23327
|
+
invoiceId: external_exports.string().min(1),
|
|
23328
|
+
status: InvoiceStatus,
|
|
23329
|
+
periodStart: Timestamp,
|
|
23330
|
+
periodEnd: Timestamp,
|
|
23331
|
+
lines: external_exports.array(InvoiceLine),
|
|
23332
|
+
totalCents: external_exports.number().int(),
|
|
23333
|
+
/** The invoice stopped taking new usage at this time. Usage that arrives later goes on the next invoice. */
|
|
23334
|
+
closedAt: Timestamp.optional(),
|
|
23335
|
+
paidAt: Timestamp.optional(),
|
|
23336
|
+
failedAttempts: external_exports.number().int().nonnegative()
|
|
23337
|
+
}).strict();
|
|
23338
|
+
GRACE_STATES = ["none", "grace", "restricted"];
|
|
23339
|
+
GraceState = external_exports.enum(GRACE_STATES);
|
|
23340
|
+
GraceNotice = external_exports.object({
|
|
23341
|
+
id: external_exports.string().min(1),
|
|
23342
|
+
kind: external_exports.enum(["payment_failed", "reminder", "restricted", "recovered"]),
|
|
23343
|
+
at: Timestamp,
|
|
23344
|
+
message: external_exports.string().min(1)
|
|
23345
|
+
}).strict();
|
|
23346
|
+
Grace = external_exports.object({
|
|
23347
|
+
tenantId: TenantId,
|
|
23348
|
+
state: GraceState,
|
|
23349
|
+
invoiceId: external_exports.string().min(1).optional(),
|
|
23350
|
+
startedAt: Timestamp.optional(),
|
|
23351
|
+
endsAt: Timestamp.optional(),
|
|
23352
|
+
notices: external_exports.array(GraceNotice)
|
|
23353
|
+
}).strict();
|
|
23354
|
+
CAP_SCOPES = ["team", "project", "agent"];
|
|
23355
|
+
CapScope = external_exports.enum(CAP_SCOPES);
|
|
23356
|
+
Cap = external_exports.object({
|
|
23357
|
+
tenantId: TenantId,
|
|
23358
|
+
scope: CapScope,
|
|
23359
|
+
/** Project ID or agent token ID; absent for the whole team. */
|
|
23360
|
+
scopeId: external_exports.string().min(1).max(128).optional(),
|
|
23361
|
+
/** Per billing period, in cents of metered spend (overage plus hosted inference with markup). */
|
|
23362
|
+
limitCents: external_exports.number().int().positive().max(1e8),
|
|
23363
|
+
updatedBy: external_exports.string().min(1),
|
|
23364
|
+
updatedAt: Timestamp
|
|
23365
|
+
}).strict().superRefine((cap, ctx) => {
|
|
23366
|
+
if (cap.scope === "team" && cap.scopeId !== void 0) ctx.addIssue({ code: "custom", path: ["scopeId"], message: "a team cap has no scope ID" });
|
|
23367
|
+
if (cap.scope !== "team" && cap.scopeId === void 0) ctx.addIssue({ code: "custom", path: ["scopeId"], message: "a project or agent cap names its project or agent" });
|
|
23368
|
+
});
|
|
23369
|
+
PutCapRequest = external_exports.object({
|
|
23370
|
+
requestId: external_exports.string().min(1).max(128),
|
|
23371
|
+
scope: CapScope,
|
|
23372
|
+
scopeId: external_exports.string().min(1).max(128).optional(),
|
|
23373
|
+
limitCents: external_exports.number().int().positive().max(1e8)
|
|
23374
|
+
}).strict();
|
|
23375
|
+
DeleteCapRequest = external_exports.object({ requestId: external_exports.string().min(1).max(128), scope: CapScope, scopeId: external_exports.string().min(1).max(128).optional() }).strict();
|
|
23376
|
+
MeterUsage = external_exports.object({
|
|
23377
|
+
meter: Meter,
|
|
23378
|
+
used: external_exports.number().int().nonnegative(),
|
|
23379
|
+
/** Total allowance for the workspace this period (per-seat allowance times seats). Null when the plan states none. */
|
|
23380
|
+
allowance: AllowanceValue,
|
|
23381
|
+
overUnits: external_exports.number().int().nonnegative(),
|
|
23382
|
+
/** Price of one unit beyond the allowance, in micro-dollars; null for hosted inference (provider cost plus markup) and unmetered-for-billing meters. */
|
|
23383
|
+
rateMicros: external_exports.number().int().nonnegative().nullable(),
|
|
23384
|
+
overageMicros: external_exports.number().int().nonnegative()
|
|
23385
|
+
}).strict();
|
|
23386
|
+
UsageSummary = external_exports.object({
|
|
23387
|
+
tenantId: TenantId,
|
|
23388
|
+
plan: BillingPlanId,
|
|
23389
|
+
periodStart: Timestamp,
|
|
23390
|
+
periodEnd: Timestamp,
|
|
23391
|
+
meters: external_exports.array(MeterUsage),
|
|
23392
|
+
/** Metered spend this period: overage plus hosted inference with markup, in micro-dollars. */
|
|
23393
|
+
spendMicros: external_exports.number().int().nonnegative(),
|
|
23394
|
+
/** Plain-language messages: an allowance reached, overage starting, a cap near. */
|
|
23395
|
+
notices: external_exports.array(external_exports.string().min(1))
|
|
23396
|
+
}).strict();
|
|
23397
|
+
CheckoutRequest = external_exports.object({
|
|
23398
|
+
requestId: external_exports.string().min(1).max(128),
|
|
23399
|
+
plan: CheckoutPlanId,
|
|
23400
|
+
interval: BillingInterval.default("month"),
|
|
23401
|
+
seats: external_exports.number().int().positive().max(1e4).default(1)
|
|
23402
|
+
}).strict();
|
|
23403
|
+
CheckoutResponse = external_exports.object({
|
|
23404
|
+
tenantId: TenantId,
|
|
23405
|
+
sessionId: external_exports.string().min(1),
|
|
23406
|
+
/** A Stripe-hosted page. Card details are entered there and never reach Overlane (REQ-BIL-13). */
|
|
23407
|
+
url: external_exports.string().url(),
|
|
23408
|
+
plan: CheckoutPlanId,
|
|
23409
|
+
interval: BillingInterval,
|
|
23410
|
+
seats: external_exports.number().int().positive(),
|
|
23411
|
+
/** What the first period costs before tax, in cents. Stripe Tax adds tax at checkout. */
|
|
23412
|
+
firstPeriodCents: external_exports.number().int().nonnegative()
|
|
23413
|
+
}).strict();
|
|
23414
|
+
ChangePlanRequest = external_exports.object({
|
|
23415
|
+
requestId: external_exports.string().min(1).max(128),
|
|
23416
|
+
plan: BillingPlanId.exclude(["enterprise"]),
|
|
23417
|
+
interval: BillingInterval.optional(),
|
|
23418
|
+
seats: external_exports.number().int().positive().max(1e4).optional()
|
|
23419
|
+
}).strict();
|
|
23420
|
+
OverLimit = external_exports.object({ what: external_exports.string().min(1), used: external_exports.number().int().nonnegative(), limit: external_exports.number().int().nonnegative() }).strict();
|
|
23421
|
+
ChangePlanResponse = external_exports.object({
|
|
23422
|
+
subscription: Subscription,
|
|
23423
|
+
/** Charge (positive) or credit (negative) for the rest of the period, in cents. */
|
|
23424
|
+
prorationCents: external_exports.number().int(),
|
|
23425
|
+
/** What the new plan's limits are exceeded by. When non-empty the workspace is read-only; nothing is deleted. */
|
|
23426
|
+
overLimit: external_exports.array(OverLimit),
|
|
23427
|
+
deleted: external_exports.literal(0)
|
|
23428
|
+
}).strict();
|
|
23429
|
+
SeatChangeRequest = external_exports.object({ requestId: external_exports.string().min(1).max(128), seats: external_exports.number().int().positive().max(1e4) }).strict();
|
|
23430
|
+
SeatChangeResponse = external_exports.object({
|
|
23431
|
+
subscription: Subscription,
|
|
23432
|
+
seat: Seat,
|
|
23433
|
+
/** Prorated charge (positive) or credit (negative) for the remainder of the period, in cents (REQ-BIL-05). */
|
|
23434
|
+
prorationCents: external_exports.number().int()
|
|
23435
|
+
}).strict();
|
|
23436
|
+
CancelRequest = external_exports.object({ requestId: external_exports.string().min(1).max(128), atPeriodEnd: external_exports.boolean().default(true) }).strict();
|
|
23437
|
+
PortalResponse = external_exports.object({ tenantId: TenantId, url: external_exports.string().url() }).strict();
|
|
23438
|
+
BillingStatus = external_exports.object({
|
|
23439
|
+
tenantId: TenantId,
|
|
23440
|
+
subscription: Subscription,
|
|
23441
|
+
seat: Seat,
|
|
23442
|
+
grace: Grace,
|
|
23443
|
+
limits: TenantPlanLimits,
|
|
23444
|
+
usage: UsageSummary,
|
|
23445
|
+
caps: external_exports.array(Cap),
|
|
23446
|
+
invoices: external_exports.array(Invoice),
|
|
23447
|
+
/** True when Stripe is configured; false while the live leg is pending and the in-process fake serves. */
|
|
23448
|
+
live: external_exports.boolean()
|
|
23449
|
+
}).strict();
|
|
23450
|
+
UsageDecision = external_exports.object({
|
|
23451
|
+
tenantId: TenantId,
|
|
23452
|
+
meter: Meter,
|
|
23453
|
+
outcome: external_exports.enum(["within_allowance", "overage", "refused", "cap_reached", "read_only"]),
|
|
23454
|
+
allowed: external_exports.boolean(),
|
|
23455
|
+
/** Micro-dollars this unit costs; zero within the allowance. */
|
|
23456
|
+
chargeMicros: external_exports.number().int().nonnegative(),
|
|
23457
|
+
message: external_exports.string().min(1),
|
|
23458
|
+
nextCommand: external_exports.string().nullable(),
|
|
23459
|
+
exitCode: external_exports.union([external_exports.literal(0), external_exports.literal(6)])
|
|
23460
|
+
}).strict();
|
|
23461
|
+
STRIPE_EVENT_TYPES = [
|
|
23462
|
+
"checkout.session.completed",
|
|
23463
|
+
"customer.subscription.created",
|
|
23464
|
+
"customer.subscription.updated",
|
|
23465
|
+
"customer.subscription.deleted",
|
|
23466
|
+
"invoice.created",
|
|
23467
|
+
"invoice.finalized",
|
|
23468
|
+
"invoice.paid",
|
|
23469
|
+
"invoice.payment_failed"
|
|
23470
|
+
];
|
|
23471
|
+
StripeEventType = external_exports.enum(STRIPE_EVENT_TYPES);
|
|
23472
|
+
epochSeconds = external_exports.number().int().nonnegative();
|
|
23473
|
+
StripeSubscriptionObject = external_exports.object({
|
|
23474
|
+
id: external_exports.string().min(1),
|
|
23475
|
+
customer: external_exports.string().min(1),
|
|
23476
|
+
status: external_exports.enum(["active", "past_due", "canceled", "incomplete", "unpaid", "trialing", "incomplete_expired"]),
|
|
23477
|
+
cancel_at_period_end: external_exports.boolean(),
|
|
23478
|
+
current_period_start: epochSeconds,
|
|
23479
|
+
current_period_end: epochSeconds,
|
|
23480
|
+
quantity: external_exports.number().int().positive(),
|
|
23481
|
+
metadata: external_exports.object({ tenantId: TenantId, plan: CheckoutPlanId, interval: BillingInterval }).passthrough()
|
|
23482
|
+
}).passthrough();
|
|
23483
|
+
StripeInvoiceObject = external_exports.object({
|
|
23484
|
+
id: external_exports.string().min(1),
|
|
23485
|
+
customer: external_exports.string().min(1),
|
|
23486
|
+
subscription: external_exports.string().min(1).nullable(),
|
|
23487
|
+
status: external_exports.enum(["draft", "open", "paid", "void", "uncollectible"]),
|
|
23488
|
+
amount_due: external_exports.number().int().nonnegative(),
|
|
23489
|
+
amount_paid: external_exports.number().int().nonnegative(),
|
|
23490
|
+
period_start: epochSeconds,
|
|
23491
|
+
period_end: epochSeconds,
|
|
23492
|
+
attempt_count: external_exports.number().int().nonnegative().default(0),
|
|
23493
|
+
metadata: external_exports.object({ tenantId: TenantId.optional() }).passthrough().default({})
|
|
23494
|
+
}).passthrough();
|
|
23495
|
+
StripeCheckoutObject = external_exports.object({
|
|
23496
|
+
id: external_exports.string().min(1),
|
|
23497
|
+
customer: external_exports.string().min(1),
|
|
23498
|
+
subscription: external_exports.string().min(1).nullable(),
|
|
23499
|
+
metadata: external_exports.object({ tenantId: TenantId }).passthrough()
|
|
23500
|
+
}).passthrough();
|
|
23501
|
+
StripeEvent = external_exports.object({
|
|
23502
|
+
id: external_exports.string().min(1),
|
|
23503
|
+
type: external_exports.string().min(1),
|
|
23504
|
+
created: epochSeconds,
|
|
23505
|
+
data: external_exports.object({ object: external_exports.record(external_exports.string(), external_exports.unknown()) })
|
|
23506
|
+
}).passthrough();
|
|
23507
|
+
WEBHOOK_OUTCOMES = ["applied", "replayed", "stale", "ignored"];
|
|
23508
|
+
WebhookOutcome = external_exports.enum(WEBHOOK_OUTCOMES);
|
|
23509
|
+
WebhookResult = external_exports.object({ ok: external_exports.literal(true), outcome: WebhookOutcome, eventId: external_exports.string().min(1) }).strict();
|
|
23510
|
+
billingPaths = {
|
|
23511
|
+
status: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing`,
|
|
23512
|
+
checkout: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/checkout`,
|
|
23513
|
+
plan: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/plan`,
|
|
23514
|
+
seats: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/seats`,
|
|
23515
|
+
cancel: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/cancel`,
|
|
23516
|
+
portal: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/portal`,
|
|
23517
|
+
usage: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/usage`,
|
|
23518
|
+
decision: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/usage/decision`,
|
|
23519
|
+
caps: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/caps`,
|
|
23520
|
+
invoices: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/invoices`,
|
|
23521
|
+
limits: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/billing/limits`,
|
|
23522
|
+
stripeWebhook: "/webhooks/billing/stripe",
|
|
23523
|
+
workosWebhook: "/webhooks/billing/workos"
|
|
23524
|
+
};
|
|
23525
|
+
}
|
|
23526
|
+
});
|
|
23527
|
+
|
|
23052
23528
|
// ../contracts/src/index.ts
|
|
23053
23529
|
var init_src = __esm({
|
|
23054
23530
|
"../contracts/src/index.ts"() {
|
|
@@ -23079,6 +23555,8 @@ var init_src = __esm({
|
|
|
23079
23555
|
init_review();
|
|
23080
23556
|
init_guardrails();
|
|
23081
23557
|
init_code_map();
|
|
23558
|
+
init_plans();
|
|
23559
|
+
init_billing();
|
|
23082
23560
|
}
|
|
23083
23561
|
});
|
|
23084
23562
|
|
|
@@ -30413,25 +30891,25 @@ var require_dist = __commonJS({
|
|
|
30413
30891
|
});
|
|
30414
30892
|
|
|
30415
30893
|
// src/assets.ts
|
|
30416
|
-
import { basename as
|
|
30894
|
+
import { basename as basename5, join as join24, resolve as resolve11 } from "node:path";
|
|
30417
30895
|
import { fileURLToPath } from "node:url";
|
|
30418
30896
|
function packageRoot(env = process.env) {
|
|
30419
30897
|
const override = env["MVRX_PACKAGE_ROOT"];
|
|
30420
30898
|
if (override !== void 0 && override !== "") return override;
|
|
30421
|
-
return
|
|
30899
|
+
return resolve11(fileURLToPath(new URL(".", import.meta.url)), "..");
|
|
30422
30900
|
}
|
|
30423
30901
|
function assetDir(env = process.env) {
|
|
30424
30902
|
const override = env["MVRX_ASSET_DIR"];
|
|
30425
30903
|
return override !== void 0 && override !== "" ? override : join24(packageRoot(env), "assets");
|
|
30426
30904
|
}
|
|
30427
30905
|
function assetFile(name2) {
|
|
30428
|
-
return join24(assetDir(),
|
|
30906
|
+
return join24(assetDir(), basename5(name2));
|
|
30429
30907
|
}
|
|
30430
30908
|
var VERSION;
|
|
30431
30909
|
var init_assets = __esm({
|
|
30432
30910
|
"src/assets.ts"() {
|
|
30433
30911
|
"use strict";
|
|
30434
|
-
VERSION = true ? "0.1.
|
|
30912
|
+
VERSION = true ? "0.1.125" : "0.0.0-dev";
|
|
30435
30913
|
}
|
|
30436
30914
|
});
|
|
30437
30915
|
|
|
@@ -31849,7 +32327,7 @@ function createFileRegistry(...args2) {
|
|
|
31849
32327
|
if (seen.has(protoFileName)) {
|
|
31850
32328
|
continue;
|
|
31851
32329
|
}
|
|
31852
|
-
const dep =
|
|
32330
|
+
const dep = resolve14(protoFileName);
|
|
31853
32331
|
if (!dep) {
|
|
31854
32332
|
throw new Error(`Unable to resolve ${protoFileName}, imported by ${file2.name}`);
|
|
31855
32333
|
}
|
|
@@ -31863,7 +32341,7 @@ function createFileRegistry(...args2) {
|
|
|
31863
32341
|
return deps.concat(...deps.map(recurseDeps));
|
|
31864
32342
|
};
|
|
31865
32343
|
const input2 = args2[0];
|
|
31866
|
-
const
|
|
32344
|
+
const resolve14 = args2[1];
|
|
31867
32345
|
const seen = /* @__PURE__ */ new Set();
|
|
31868
32346
|
for (const file2 of [input2, ...recurseDeps(input2)].reverse()) {
|
|
31869
32347
|
addFile(file2, registry2);
|
|
@@ -34276,13 +34754,13 @@ async function Module2(moduleArg = {}) {
|
|
|
34276
34754
|
}
|
|
34277
34755
|
readAsync = /* @__PURE__ */ __name(async (url2) => {
|
|
34278
34756
|
if (isFileURI(url2)) {
|
|
34279
|
-
return new Promise((
|
|
34757
|
+
return new Promise((resolve14, reject) => {
|
|
34280
34758
|
var xhr = new XMLHttpRequest();
|
|
34281
34759
|
xhr.open("GET", url2, true);
|
|
34282
34760
|
xhr.responseType = "arraybuffer";
|
|
34283
34761
|
xhr.onload = () => {
|
|
34284
34762
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
34285
|
-
|
|
34763
|
+
resolve14(xhr.response);
|
|
34286
34764
|
return;
|
|
34287
34765
|
}
|
|
34288
34766
|
reject(xhr.status);
|
|
@@ -34478,9 +34956,9 @@ async function Module2(moduleArg = {}) {
|
|
|
34478
34956
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
34479
34957
|
var info2 = getWasmImports();
|
|
34480
34958
|
if (Module["instantiateWasm"]) {
|
|
34481
|
-
return new Promise((
|
|
34959
|
+
return new Promise((resolve14, reject) => {
|
|
34482
34960
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
34483
|
-
|
|
34961
|
+
resolve14(receiveInstance(mod, inst));
|
|
34484
34962
|
});
|
|
34485
34963
|
});
|
|
34486
34964
|
}
|
|
@@ -35813,8 +36291,8 @@ async function Module2(moduleArg = {}) {
|
|
|
35813
36291
|
if (runtimeInitialized) {
|
|
35814
36292
|
moduleRtn = Module;
|
|
35815
36293
|
} else {
|
|
35816
|
-
moduleRtn = new Promise((
|
|
35817
|
-
readyPromiseResolve =
|
|
36294
|
+
moduleRtn = new Promise((resolve14, reject) => {
|
|
36295
|
+
readyPromiseResolve = resolve14;
|
|
35818
36296
|
readyPromiseReject = reject;
|
|
35819
36297
|
});
|
|
35820
36298
|
}
|
|
@@ -38441,7 +38919,8 @@ async function buildSnapshot(options) {
|
|
|
38441
38919
|
const manifest = SnapshotManifest.parse({
|
|
38442
38920
|
schemaVersion: "1",
|
|
38443
38921
|
tenantId: options.tenantId,
|
|
38444
|
-
repository: options.repository,
|
|
38922
|
+
...options.repository !== void 0 ? { repository: options.repository } : {},
|
|
38923
|
+
...options.projectId !== void 0 ? { projectId: options.projectId } : {},
|
|
38445
38924
|
commitSha: options.commitSha,
|
|
38446
38925
|
...options.branch !== void 0 ? { branch: options.branch } : {},
|
|
38447
38926
|
indexers: [...indexers.values()].sort((a, b) => compareStrings(a.name, b.name) || compareStrings(a.version, b.version)),
|
|
@@ -38472,7 +38951,9 @@ async function uploadSnapshot(options) {
|
|
|
38472
38951
|
const doFetch = options.fetch ?? fetch;
|
|
38473
38952
|
const base4 = options.serviceUrl.replace(/\/+$/, "");
|
|
38474
38953
|
const manifest = SnapshotManifest.parse(options.manifest);
|
|
38475
|
-
const { tenantId, repository, commitSha } = manifest;
|
|
38954
|
+
const { tenantId, repository, projectId, commitSha } = manifest;
|
|
38955
|
+
const byProject = projectId !== void 0 && (repository === void 0 || options.byProject === true);
|
|
38956
|
+
if (!byProject && repository === void 0) throw new Error("the manifest names neither a repository nor a project");
|
|
38476
38957
|
const headers = { authorization: `Bearer ${options.token}`, "content-type": "application/json" };
|
|
38477
38958
|
const send2 = async (path, body2) => {
|
|
38478
38959
|
for (let attempt2 = 1; ; attempt2 += 1) {
|
|
@@ -38490,16 +38971,17 @@ async function uploadSnapshot(options) {
|
|
|
38490
38971
|
failure4 = error62 instanceof Error ? error62.message : String(error62);
|
|
38491
38972
|
if (attempt2 >= ATTEMPTS) throw new Error(`POST ${path} failed: ${failure4}`);
|
|
38492
38973
|
}
|
|
38493
|
-
await new Promise((
|
|
38974
|
+
await new Promise((resolve14) => setTimeout(resolve14, (options.retryDelayMs ?? 500) * attempt2));
|
|
38494
38975
|
}
|
|
38495
38976
|
};
|
|
38496
|
-
const
|
|
38977
|
+
const manifestPath = byProject ? codePaths.projectUploadManifest(tenantId, projectId ?? "") : codePaths.uploadManifest(tenantId, repository?.owner ?? "", repository?.name ?? "");
|
|
38978
|
+
const manifestResponse = await send2(manifestPath, JSON.stringify(manifest));
|
|
38497
38979
|
const { missing } = ManifestUploadResponse.parse(await manifestResponse.json());
|
|
38498
38980
|
const wanted = new Set(missing);
|
|
38499
38981
|
for (const hash2 of options.existing ?? []) wanted.delete(hash2);
|
|
38500
38982
|
const maxShards = options.maxBatchShards ?? MAX_BATCH_SHARDS;
|
|
38501
38983
|
const maxBytes = options.maxBatchBytes ?? MAX_BATCH_BYTES;
|
|
38502
|
-
const shardsPath = codePaths.uploadShards(tenantId, repository
|
|
38984
|
+
const shardsPath = byProject ? codePaths.projectUploadShards(tenantId, projectId ?? "", commitSha) : codePaths.uploadShards(tenantId, repository?.owner ?? "", repository?.name ?? "", commitSha);
|
|
38503
38985
|
let batch = [];
|
|
38504
38986
|
let batchBytes = 0;
|
|
38505
38987
|
let uploadedShards = 0;
|
|
@@ -38523,7 +39005,7 @@ async function uploadSnapshot(options) {
|
|
|
38523
39005
|
batchBytes += size;
|
|
38524
39006
|
}
|
|
38525
39007
|
await flush();
|
|
38526
|
-
await send2(codePaths.publish(tenantId, repository
|
|
39008
|
+
await send2(byProject ? codePaths.projectPublish(tenantId, projectId ?? "", commitSha) : codePaths.publish(tenantId, repository?.owner ?? "", repository?.name ?? "", commitSha), "{}");
|
|
38527
39009
|
return { missing: missing.length, uploadedShards, batches };
|
|
38528
39010
|
}
|
|
38529
39011
|
var MAX_BATCH_SHARDS, MAX_BATCH_BYTES, ATTEMPTS, HttpError;
|
|
@@ -38568,7 +39050,7 @@ var init_oidc = __esm({
|
|
|
38568
39050
|
// ../index-builder/src/run.ts
|
|
38569
39051
|
import { execFile as execFile2 } from "node:child_process";
|
|
38570
39052
|
import { mkdir as mkdir3, readdir as readdir4, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
38571
|
-
import { join as join26, resolve as
|
|
39053
|
+
import { join as join26, resolve as resolve12 } from "node:path";
|
|
38572
39054
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
38573
39055
|
import { promisify as promisify2 } from "node:util";
|
|
38574
39056
|
async function git3(root, args2) {
|
|
@@ -38589,9 +39071,11 @@ async function repositoryFromRemote(root) {
|
|
|
38589
39071
|
}
|
|
38590
39072
|
}
|
|
38591
39073
|
async function snapshotFromArgs(values, env) {
|
|
38592
|
-
const root =
|
|
38593
|
-
const
|
|
38594
|
-
if (!
|
|
39074
|
+
const root = resolve12(typeof values["root"] === "string" ? values["root"] : process.cwd());
|
|
39075
|
+
const projectId = typeof values["project"] === "string" ? values["project"] : void 0;
|
|
39076
|
+
if (projectId !== void 0 && !ProjectId.safeParse(projectId).success) throw new UsageError2(`--project must be a project identifier, got "${projectId}"`);
|
|
39077
|
+
const repoText = projectId !== void 0 ? typeof values["repo"] === "string" ? values["repo"] : void 0 : (typeof values["repo"] === "string" ? values["repo"] : void 0) ?? env["GITHUB_REPOSITORY"] ?? await repositoryFromRemote(root);
|
|
39078
|
+
if (!repoText && projectId === void 0) throw new UsageError2("cannot determine the repository; pass --project ID, or --repo owner/name");
|
|
38595
39079
|
const commit = (typeof values["commit"] === "string" ? values["commit"] : void 0) ?? env["GITHUB_SHA"] ?? await git3(root, ["rev-parse", "HEAD"]);
|
|
38596
39080
|
const branch = typeof values["branch"] === "string" ? values["branch"] : void 0;
|
|
38597
39081
|
const tenant = (typeof values["tenant"] === "string" ? values["tenant"] : void 0) ?? env["HARNESS_TENANT"];
|
|
@@ -38599,9 +39083,10 @@ async function snapshotFromArgs(values, env) {
|
|
|
38599
39083
|
const scip = Array.isArray(values["scip"]) ? values["scip"] : [];
|
|
38600
39084
|
return buildSnapshot({
|
|
38601
39085
|
repoRoot: root,
|
|
38602
|
-
scipFiles: scip.map((file2) =>
|
|
39086
|
+
scipFiles: scip.map((file2) => resolve12(file2)),
|
|
38603
39087
|
tenantId: tenant,
|
|
38604
|
-
repository: parseRepository(repoText),
|
|
39088
|
+
...repoText ? { repository: parseRepository(repoText) } : {},
|
|
39089
|
+
...projectId !== void 0 ? { projectId } : {},
|
|
38605
39090
|
commitSha: commit,
|
|
38606
39091
|
...branch !== void 0 ? { branch } : {}
|
|
38607
39092
|
});
|
|
@@ -38614,17 +39099,18 @@ async function runCli2(argv, env, out2 = console.log, err2 = console.error) {
|
|
|
38614
39099
|
const outDir = values.out;
|
|
38615
39100
|
if (!outDir) throw new UsageError2("build needs --out DIR");
|
|
38616
39101
|
const built = await snapshotFromArgs({ ...values, tenant: values.tenant ?? env["HARNESS_TENANT"] ?? "local" }, env);
|
|
38617
|
-
await writeSnapshot(
|
|
38618
|
-
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${
|
|
39102
|
+
await writeSnapshot(resolve12(outDir), built);
|
|
39103
|
+
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${resolve12(outDir)}`);
|
|
38619
39104
|
return 0;
|
|
38620
39105
|
}
|
|
38621
39106
|
if (command === "upload") {
|
|
38622
39107
|
const service = values.service;
|
|
38623
39108
|
if (!service) throw new UsageError2("upload needs --service URL");
|
|
38624
39109
|
const built = await snapshotFromArgs(values, env);
|
|
38625
|
-
const
|
|
38626
|
-
|
|
38627
|
-
|
|
39110
|
+
const byProject = values.project !== void 0;
|
|
39111
|
+
const token = !byProject && env["ACTIONS_ID_TOKEN_REQUEST_URL"] ? await getOidcToken(values.audience ?? service, env) : env["HARNESS_TOKEN"];
|
|
39112
|
+
if (!token) throw new UsageError2(byProject ? "no credentials: set HARNESS_TOKEN" : "no credentials: run in GitHub Actions with id-token: write, or set HARNESS_TOKEN");
|
|
39113
|
+
const result = await uploadSnapshot({ serviceUrl: service, token, manifest: built.manifest, shards: built.shards, ...byProject ? { byProject: true } : {} });
|
|
38628
39114
|
out2(`published ${built.manifest.commitSha}: ${built.shards.length} shards, ${result.missing} new, ${result.batches} batches`);
|
|
38629
39115
|
return 0;
|
|
38630
39116
|
}
|
|
@@ -38659,10 +39145,12 @@ var init_run = __esm({
|
|
|
38659
39145
|
init_upload();
|
|
38660
39146
|
execFileAsync2 = promisify2(execFile2);
|
|
38661
39147
|
USAGE = `usage:
|
|
38662
|
-
mvrx-index build --scip FILE [--scip FILE ...] --out DIR [--repo owner/name] [--tenant ID] [--commit SHA] [--branch B] [--root DIR]
|
|
38663
|
-
mvrx-index upload --service URL --tenant ID --repo owner/name --commit SHA [--branch B] [--scip FILE ...] [--root DIR] [--audience URL]
|
|
39148
|
+
mvrx-index build --scip FILE [--scip FILE ...] --out DIR [--project ID | --repo owner/name] [--tenant ID] [--commit SHA] [--branch B] [--root DIR]
|
|
39149
|
+
mvrx-index upload --service URL --tenant ID (--project ID | --repo owner/name) --commit SHA [--branch B] [--scip FILE ...] [--root DIR] [--audience URL]
|
|
38664
39150
|
|
|
38665
|
-
|
|
39151
|
+
--project indexes an Overlane project (no GitHub repository needed) and uploads with HARNESS_TOKEN.
|
|
39152
|
+
--repo names a GitHub repository; in GitHub Actions the OIDC token is used when ACTIONS_ID_TOKEN_REQUEST_URL is set.
|
|
39153
|
+
Authentication for upload: HARNESS_TOKEN (always for --project), or the GitHub Actions OIDC token for --repo.
|
|
38666
39154
|
`;
|
|
38667
39155
|
UsageError2 = class extends Error {
|
|
38668
39156
|
};
|
|
@@ -38672,6 +39160,7 @@ Authentication for upload: the GitHub Actions OIDC token when ACTIONS_ID_TOKEN_R
|
|
|
38672
39160
|
service: { type: "string" },
|
|
38673
39161
|
tenant: { type: "string" },
|
|
38674
39162
|
repo: { type: "string" },
|
|
39163
|
+
project: { type: "string" },
|
|
38675
39164
|
commit: { type: "string" },
|
|
38676
39165
|
branch: { type: "string" },
|
|
38677
39166
|
root: { type: "string" },
|
|
@@ -42243,14 +42732,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
42243
42732
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
42244
42733
|
}
|
|
42245
42734
|
function sleep2(ms, signal) {
|
|
42246
|
-
return new Promise((
|
|
42735
|
+
return new Promise((resolve14, reject) => {
|
|
42247
42736
|
if (signal?.aborted) {
|
|
42248
42737
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
42249
42738
|
return;
|
|
42250
42739
|
}
|
|
42251
42740
|
const timer = setTimeout(() => {
|
|
42252
42741
|
signal?.removeEventListener("abort", onAbort);
|
|
42253
|
-
|
|
42742
|
+
resolve14();
|
|
42254
42743
|
}, ms);
|
|
42255
42744
|
const onAbort = () => {
|
|
42256
42745
|
clearTimeout(timer);
|
|
@@ -44046,7 +44535,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
44046
44535
|
const flowStartedAt = Date.now();
|
|
44047
44536
|
let onAbort;
|
|
44048
44537
|
let cleanupMessageId;
|
|
44049
|
-
return new Promise((
|
|
44538
|
+
return new Promise((resolve14, reject) => {
|
|
44050
44539
|
const earlyReject = (error62) => {
|
|
44051
44540
|
reject(error62);
|
|
44052
44541
|
};
|
|
@@ -44114,7 +44603,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
44114
44603
|
}
|
|
44115
44604
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
44116
44605
|
if (decoded.kind === "input_required") {
|
|
44117
|
-
if (options?.allowInputRequired === true) return
|
|
44606
|
+
if (options?.allowInputRequired === true) return resolve14(manualInputRequiredValue(decoded));
|
|
44118
44607
|
const flow = {
|
|
44119
44608
|
codec: codec2,
|
|
44120
44609
|
request,
|
|
@@ -44126,11 +44615,11 @@ var init_src_CX2iR2pK = __esm({
|
|
|
44126
44615
|
params
|
|
44127
44616
|
}, resultSchema2, legOptions)
|
|
44128
44617
|
};
|
|
44129
|
-
return
|
|
44618
|
+
return resolve14(this._resolveNonCompleteResult(decoded, flow));
|
|
44130
44619
|
}
|
|
44131
44620
|
const result = decoded.result;
|
|
44132
44621
|
validateStandardSchema(resultSchema2, result).then((parseResult) => {
|
|
44133
|
-
if (parseResult.success)
|
|
44622
|
+
if (parseResult.success) resolve14(parseResult.data);
|
|
44134
44623
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
44135
44624
|
}, reject);
|
|
44136
44625
|
});
|
|
@@ -46946,7 +47435,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46946
47435
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
46947
47436
|
const schOrFunc = root.refs[ref];
|
|
46948
47437
|
if (schOrFunc) return schOrFunc;
|
|
46949
|
-
let _sch =
|
|
47438
|
+
let _sch = resolve14.call(this, root, ref);
|
|
46950
47439
|
if (_sch === void 0) {
|
|
46951
47440
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
46952
47441
|
const { schemaId } = this.opts;
|
|
@@ -46972,7 +47461,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
46972
47461
|
function sameSchemaEnv(s1, s2) {
|
|
46973
47462
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
46974
47463
|
}
|
|
46975
|
-
function
|
|
47464
|
+
function resolve14(root, ref) {
|
|
46976
47465
|
let sch;
|
|
46977
47466
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
46978
47467
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -47422,7 +47911,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47422
47911
|
else if (typeof uri === "object") uri = parse5(serialize(uri, options), options);
|
|
47423
47912
|
return uri;
|
|
47424
47913
|
}
|
|
47425
|
-
function
|
|
47914
|
+
function resolve14(baseURI, relativeURI, options) {
|
|
47426
47915
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
47427
47916
|
const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
47428
47917
|
schemelessOptions.skipEscape = true;
|
|
@@ -47596,7 +48085,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47596
48085
|
const fastUri = {
|
|
47597
48086
|
SCHEMES,
|
|
47598
48087
|
normalize,
|
|
47599
|
-
resolve:
|
|
48088
|
+
resolve: resolve14,
|
|
47600
48089
|
resolveComponent,
|
|
47601
48090
|
equal,
|
|
47602
48091
|
serialize,
|
|
@@ -53293,7 +53782,7 @@ var init_stdio = __esm({
|
|
|
53293
53782
|
}
|
|
53294
53783
|
send(message) {
|
|
53295
53784
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
53296
|
-
return new Promise((
|
|
53785
|
+
return new Promise((resolve14, reject) => {
|
|
53297
53786
|
const json2 = serializeMessage(message);
|
|
53298
53787
|
let settled = false;
|
|
53299
53788
|
const onError = (error62) => {
|
|
@@ -53308,14 +53797,14 @@ var init_stdio = __esm({
|
|
|
53308
53797
|
settled = true;
|
|
53309
53798
|
this._stdout.off("error", onError);
|
|
53310
53799
|
this._stdout.off("drain", onDrain);
|
|
53311
|
-
|
|
53800
|
+
resolve14();
|
|
53312
53801
|
};
|
|
53313
53802
|
this._stdout.once("error", onError);
|
|
53314
53803
|
if (this._stdout.write(json2)) {
|
|
53315
53804
|
if (settled) return;
|
|
53316
53805
|
settled = true;
|
|
53317
53806
|
this._stdout.off("error", onError);
|
|
53318
|
-
|
|
53807
|
+
resolve14();
|
|
53319
53808
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
53320
53809
|
});
|
|
53321
53810
|
}
|
|
@@ -53369,14 +53858,14 @@ var init_stdio = __esm({
|
|
|
53369
53858
|
*/
|
|
53370
53859
|
async whenRequestsAnswered(timeoutMs) {
|
|
53371
53860
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
53372
|
-
return await new Promise((
|
|
53861
|
+
return await new Promise((resolve14) => {
|
|
53373
53862
|
const waiter = () => {
|
|
53374
53863
|
clearTimeout(timer);
|
|
53375
|
-
|
|
53864
|
+
resolve14(true);
|
|
53376
53865
|
};
|
|
53377
53866
|
const timer = setTimeout(() => {
|
|
53378
53867
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
53379
|
-
|
|
53868
|
+
resolve14(false);
|
|
53380
53869
|
}, timeoutMs);
|
|
53381
53870
|
this._drainWaiters.push(waiter);
|
|
53382
53871
|
});
|
|
@@ -53601,9 +54090,9 @@ var init_config = __esm({
|
|
|
53601
54090
|
|
|
53602
54091
|
// ../code-shim/src/local.ts
|
|
53603
54092
|
import { readFileSync as readFileSync13, statSync as statSync2 } from "node:fs";
|
|
53604
|
-
import { isAbsolute as isAbsolute2, relative as relative3, resolve as
|
|
54093
|
+
import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolve13, sep as sep2 } from "node:path";
|
|
53605
54094
|
function resolveInside(root, path) {
|
|
53606
|
-
const absolute =
|
|
54095
|
+
const absolute = resolve13(root, path);
|
|
53607
54096
|
const rel = relative3(root, absolute);
|
|
53608
54097
|
if (rel.length === 0 || rel.startsWith("..") || isAbsolute2(rel)) return null;
|
|
53609
54098
|
return absolute;
|
|
@@ -55077,19 +55566,19 @@ function pkcePair() {
|
|
|
55077
55566
|
return { verifier, challenge: base64url3(createHash("sha256").update(verifier).digest()) };
|
|
55078
55567
|
}
|
|
55079
55568
|
function listen(server, port) {
|
|
55080
|
-
return new Promise((
|
|
55569
|
+
return new Promise((resolve14, reject) => {
|
|
55081
55570
|
const onError = (error62) => reject(error62);
|
|
55082
55571
|
server.once("error", onError);
|
|
55083
55572
|
server.listen(port, "127.0.0.1", () => {
|
|
55084
55573
|
server.off("error", onError);
|
|
55085
|
-
|
|
55574
|
+
resolve14();
|
|
55086
55575
|
});
|
|
55087
55576
|
});
|
|
55088
55577
|
}
|
|
55089
55578
|
async function startLoopback(preferredPort, state) {
|
|
55090
55579
|
let settle2;
|
|
55091
|
-
const code2 = new Promise((
|
|
55092
|
-
settle2 = { resolve:
|
|
55580
|
+
const code2 = new Promise((resolve14, reject) => {
|
|
55581
|
+
settle2 = { resolve: resolve14, reject };
|
|
55093
55582
|
});
|
|
55094
55583
|
code2.catch(() => void 0);
|
|
55095
55584
|
const server = createServer((request, response) => {
|
|
@@ -55277,7 +55766,7 @@ async function requireToken(deps, serviceUrl) {
|
|
|
55277
55766
|
|
|
55278
55767
|
// ../cli/src/project.ts
|
|
55279
55768
|
init_src();
|
|
55280
|
-
import { join as join5 } from "node:path";
|
|
55769
|
+
import { basename, join as join5 } from "node:path";
|
|
55281
55770
|
var REMOTE_PATTERNS = [
|
|
55282
55771
|
/^(?:https?|git|ssh):\/\/(?:[^@/]+@)?github\.com(?::\d+)?\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i,
|
|
55283
55772
|
/^(?:[^@/]+@)?github\.com:([^/]+)\/([^/]+?)(?:\.git)?\/?$/i
|
|
@@ -55292,21 +55781,49 @@ function parseGitHubRemote(url2) {
|
|
|
55292
55781
|
}
|
|
55293
55782
|
return null;
|
|
55294
55783
|
}
|
|
55295
|
-
|
|
55784
|
+
function parseProvider(value) {
|
|
55785
|
+
if (value === void 0) return void 0;
|
|
55786
|
+
if (PROVIDERS.includes(value)) return value;
|
|
55787
|
+
throw new UsageError(`--provider must be one of ${PROVIDERS.join(", ")}`, { hint: "overlane connect --provider overlane" });
|
|
55788
|
+
}
|
|
55789
|
+
function safeName(text) {
|
|
55790
|
+
const cleaned = text.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[-.]+|-+$/g, "");
|
|
55791
|
+
return cleaned.slice(0, 100) === "" ? "project" : cleaned.slice(0, 100);
|
|
55792
|
+
}
|
|
55793
|
+
function projectLabel(project) {
|
|
55794
|
+
return project.repository === void 0 ? project.name : `${project.repository.owner}/${project.repository.name}`;
|
|
55795
|
+
}
|
|
55796
|
+
function projectSummary(project) {
|
|
55797
|
+
return { provider: project.provider, ...project.repository === void 0 ? {} : { owner: project.repository.owner }, name: project.repository?.name ?? project.name, root: project.root };
|
|
55798
|
+
}
|
|
55799
|
+
function projectRequest(project) {
|
|
55800
|
+
if (project.provider === "github" && project.repository !== void 0) {
|
|
55801
|
+
return { provider: "github", repository: project.repository, name: project.name };
|
|
55802
|
+
}
|
|
55803
|
+
return { provider: "overlane", name: project.name };
|
|
55804
|
+
}
|
|
55805
|
+
async function detectProject(deps, choice = {}) {
|
|
55296
55806
|
const top = await deps.exec("git", ["rev-parse", "--show-toplevel"], { cwd: deps.paths.cwd });
|
|
55297
55807
|
if (top.code !== 0 || top.stdout.trim().length === 0) {
|
|
55298
|
-
throw new UsageError("not inside a git repository (or git is not installed); run overlane from
|
|
55808
|
+
throw new UsageError("not inside a git repository (or git is not installed); run overlane from your project folder (`git init` makes one)");
|
|
55299
55809
|
}
|
|
55300
55810
|
const root = top.stdout.trim();
|
|
55811
|
+
if (choice.name !== void 0 && (choice.name.trim().length === 0 || choice.name.length > 100)) throw new UsageError("--name must be 1 to 100 characters");
|
|
55301
55812
|
const remote = await deps.exec("git", ["remote", "get-url", "origin"], { cwd: root });
|
|
55302
|
-
|
|
55303
|
-
|
|
55813
|
+
const originUrl = remote.code === 0 ? remote.stdout.trim() : "";
|
|
55814
|
+
const github = originUrl.length === 0 ? null : parseGitHubRemote(originUrl);
|
|
55815
|
+
const wanted = choice.provider;
|
|
55816
|
+
if (wanted === "gitlab") {
|
|
55817
|
+
throw new UsageError("--provider gitlab is not available from the CLI yet; use --provider overlane (the default) and connect GitLab from the web app", { hint: "overlane connect --provider overlane" });
|
|
55818
|
+
}
|
|
55819
|
+
if (wanted === "github" && github === null) {
|
|
55820
|
+
const why = originUrl.length === 0 ? "this repository has no `origin` remote" : `origin is ${originUrl}, which is not a github.com repository`;
|
|
55821
|
+
throw new UsageError(`--provider github needs a github.com origin, and ${why}. Leave --provider off to make a native Overlane project, or add the GitHub remote first`, { hint: "overlane connect --provider overlane" });
|
|
55304
55822
|
}
|
|
55305
|
-
|
|
55306
|
-
|
|
55307
|
-
throw new UsageError(`origin is ${remote.stdout.trim()}, which is not a github.com repository; only GitHub projects are supported`);
|
|
55823
|
+
if (github !== null && wanted !== "overlane") {
|
|
55824
|
+
return { root, provider: "github", name: choice.name ?? github.name, repository: github };
|
|
55308
55825
|
}
|
|
55309
|
-
return { root,
|
|
55826
|
+
return { root, provider: "overlane", name: choice.name ?? (basename(root).slice(0, 100) || "project") };
|
|
55310
55827
|
}
|
|
55311
55828
|
async function headCommit(deps, root) {
|
|
55312
55829
|
const head = await deps.exec("git", ["rev-parse", "HEAD"], { cwd: root });
|
|
@@ -55546,7 +56063,7 @@ var DEFAULT_SERVICE_URL = "https://api.overlane.dev";
|
|
|
55546
56063
|
var CONNECT_STEPS = {
|
|
55547
56064
|
"sign-up": "sign in through the browser (OAuth with PKCE), or use HARNESS_TOKEN",
|
|
55548
56065
|
agents: "register the plugin with each agent's own commands (no vendor token is asked for)",
|
|
55549
|
-
repo: "bind this
|
|
56066
|
+
repo: "bind this project to the service: a native Overlane project by default, or your GitHub repository",
|
|
55550
56067
|
"first-task": 'start your first task with `overlane task new "<title>"`',
|
|
55551
56068
|
"first-review": "read the first review in the web app",
|
|
55552
56069
|
invite: "invite teammates from the web app (optional, never blocks)"
|
|
@@ -55595,10 +56112,9 @@ async function connect(deps, options) {
|
|
|
55595
56112
|
if (active.length === 0) {
|
|
55596
56113
|
throw new CliError("none of the selected agents is installed, so there is nothing to connect", { code: "no_agent", exit: EXIT.conflict, hint: "overlane doctor" });
|
|
55597
56114
|
}
|
|
55598
|
-
const project = await detectProject(deps);
|
|
56115
|
+
const project = await detectProject(deps, { name: options.name, provider: options.provider });
|
|
55599
56116
|
const root = project.root;
|
|
55600
|
-
|
|
55601
|
-
say(deps, `Project: ${repository.owner}/${repository.name} at ${root}`);
|
|
56117
|
+
say(deps, `Project: ${projectLabel(project)}${project.provider === "overlane" ? " (native Overlane project; no GitHub account needed)" : " (GitHub)"} at ${root}`);
|
|
55602
56118
|
const existing = readBindingFile(root);
|
|
55603
56119
|
const serviceInput = options.service ?? deps.env["HARNESS_SERVICE_URL"] ?? (existing.kind === "ok" ? existing.binding.serviceUrl : DEFAULT_SERVICE_URL);
|
|
55604
56120
|
if (serviceInput === void 0 || serviceInput.length === 0) {
|
|
@@ -55646,7 +56162,7 @@ async function connect(deps, options) {
|
|
|
55646
56162
|
say(deps, `Steps (the same names as the web onboarding): ${STEP_NAMES.join(", ")}`);
|
|
55647
56163
|
say(deps, "Plan");
|
|
55648
56164
|
say(deps, ` sign-in: ${existingToken === null ? `browser sign-in to ${serviceUrl} (OAuth with PKCE), token kept in the OS keychain or a 0600 file in your user config directory` : `${describeStore(deps, existingToken.source)}`}`);
|
|
55649
|
-
say(deps, ` service: GET ${serviceUrl}/v1/me, then create or look up the project
|
|
56165
|
+
say(deps, ` service: GET ${serviceUrl}/v1/me, then create or look up the project ${projectLabel(project)}`);
|
|
55650
56166
|
for (const step2 of steps) say(deps, ` ${step2.agent}: ${step2.summary}
|
|
55651
56167
|
$ ${formatCommand(step2)}`);
|
|
55652
56168
|
if (codexEdit !== null) {
|
|
@@ -55674,7 +56190,7 @@ async function connect(deps, options) {
|
|
|
55674
56190
|
service: serviceUrl,
|
|
55675
56191
|
requests: [
|
|
55676
56192
|
{ method: "GET", path: apiPaths.whoami, note: existingToken === null ? "after browser sign-in" : "with the stored token" },
|
|
55677
|
-
{ method: "POST", path: apiPaths.projects("<tenantId from /v1/me>"), body:
|
|
56193
|
+
{ method: "POST", path: apiPaths.projects("<tenantId from /v1/me>"), body: projectRequest(project), note: "creates the project or returns the existing one" },
|
|
55678
56194
|
{ method: "GET", path: releasePaths.publicKey(), note: "the release-signing key; a failure here does not fail connect" }
|
|
55679
56195
|
],
|
|
55680
56196
|
commands: steps.map((step2) => formatCommand(step2)),
|
|
@@ -55694,7 +56210,7 @@ async function connect(deps, options) {
|
|
|
55694
56210
|
}
|
|
55695
56211
|
if (!await deps.confirm("Apply this plan?")) {
|
|
55696
56212
|
say(deps, "Cancelled; nothing changed.");
|
|
55697
|
-
return { data: emptyResult(
|
|
56213
|
+
return { data: emptyResult(project, serviceUrl, infos, true) };
|
|
55698
56214
|
}
|
|
55699
56215
|
}
|
|
55700
56216
|
const token = await ensureToken(deps, serviceUrl);
|
|
@@ -55703,8 +56219,7 @@ async function connect(deps, options) {
|
|
|
55703
56219
|
const wrote = [];
|
|
55704
56220
|
const applied = [];
|
|
55705
56221
|
const me = await whoAmI(deps, serviceUrl, token.token);
|
|
55706
|
-
const
|
|
55707
|
-
const record3 = await createProject(deps, serviceUrl, me.tenantId, token.token, request);
|
|
56222
|
+
const record3 = await createProject(deps, serviceUrl, me.tenantId, token.token, projectRequest(project));
|
|
55708
56223
|
if (record3.tenantId !== me.tenantId) throw new CliError("the service returned a project for another tenant");
|
|
55709
56224
|
const servicePublicKey = await fetchServicePublicKey(deps, serviceUrl, token.token) ?? (existing.kind === "ok" ? existing.binding.servicePublicKey ?? null : null);
|
|
55710
56225
|
const binding = ProjectBinding.parse({
|
|
@@ -55743,7 +56258,7 @@ async function connect(deps, options) {
|
|
|
55743
56258
|
owned.binding = true;
|
|
55744
56259
|
if (excludeNeeded && await addExclude(deps, root)) owned.excludeLine = true;
|
|
55745
56260
|
say(deps, `[repo] ${CONNECT_STEPS.repo}: done`);
|
|
55746
|
-
const next = await reportStep(deps, serviceUrl, token.token, me.tenantId, "repo", { repo:
|
|
56261
|
+
const next = await reportStep(deps, serviceUrl, token.token, me.tenantId, "repo", { repo: repoChoice(project) });
|
|
55747
56262
|
if (next !== null) say(deps, `Next in onboarding: ${next === "repo" ? "first-task" : next} (${CONNECT_STEPS[next === "repo" ? "first-task" : next]})`);
|
|
55748
56263
|
} finally {
|
|
55749
56264
|
if (previousOwned !== null || owned.binding || owned.claude !== void 0 || owned.codex !== void 0) writeOwned(root, owned);
|
|
@@ -55757,7 +56272,7 @@ async function connect(deps, options) {
|
|
|
55757
56272
|
for (const line2 of renderReports(reports)) say(deps, ` ${line2}`);
|
|
55758
56273
|
return {
|
|
55759
56274
|
data: {
|
|
55760
|
-
project:
|
|
56275
|
+
project: projectSummary(project),
|
|
55761
56276
|
serviceUrl,
|
|
55762
56277
|
tenantId: binding.tenantId,
|
|
55763
56278
|
projectId: binding.projectId,
|
|
@@ -55771,9 +56286,13 @@ async function connect(deps, options) {
|
|
|
55771
56286
|
}
|
|
55772
56287
|
};
|
|
55773
56288
|
}
|
|
55774
|
-
function
|
|
56289
|
+
function repoChoice(project) {
|
|
56290
|
+
if (project.provider === "github" && project.repository !== void 0) return { provider: "github", owner: project.repository.owner, name: project.repository.name };
|
|
56291
|
+
return { provider: "overlane", owner: "native", name: safeName(project.name) };
|
|
56292
|
+
}
|
|
56293
|
+
function emptyResult(project, serviceUrl, infos, cancelled) {
|
|
55775
56294
|
return {
|
|
55776
|
-
project:
|
|
56295
|
+
project: projectSummary(project),
|
|
55777
56296
|
serviceUrl,
|
|
55778
56297
|
credentials: "unchanged",
|
|
55779
56298
|
agents: infos.map((info2) => ({ agent: info2.agent, installed: info2.installed, detail: info2.detail })),
|
|
@@ -55836,8 +56355,8 @@ function withTimeout(deps, ms) {
|
|
|
55836
56355
|
}
|
|
55837
56356
|
async function attempt(deps, ms, work) {
|
|
55838
56357
|
let timer;
|
|
55839
|
-
const deadline = new Promise((
|
|
55840
|
-
timer = setTimeout(() =>
|
|
56358
|
+
const deadline = new Promise((resolve14) => {
|
|
56359
|
+
timer = setTimeout(() => resolve14("unreachable"), ms);
|
|
55841
56360
|
});
|
|
55842
56361
|
try {
|
|
55843
56362
|
return await Promise.race([work(withTimeout(deps, ms)).catch((error62) => error62 instanceof ServiceError && error62.exit === EXIT.auth ? "unauthenticated" : "unreachable"), deadline]);
|
|
@@ -56976,13 +57495,13 @@ async function readPlan(repoDir) {
|
|
|
56976
57495
|
init_src();
|
|
56977
57496
|
init_zod();
|
|
56978
57497
|
import { mkdir as mkdir2, readdir as readdir3, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
56979
|
-
import { basename as
|
|
57498
|
+
import { basename as basename3, dirname as dirname7, join as join17, resolve as resolve6 } from "node:path";
|
|
56980
57499
|
|
|
56981
57500
|
// ../kit/src/detect.ts
|
|
56982
57501
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
56983
57502
|
init_src();
|
|
56984
57503
|
import { readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
|
|
56985
|
-
import { basename, join as join16, resolve as resolve5 } from "node:path";
|
|
57504
|
+
import { basename as basename2, join as join16, resolve as resolve5 } from "node:path";
|
|
56986
57505
|
var KINDS = ["typecheck", "lint", "build", "test"];
|
|
56987
57506
|
async function readOptional(file2) {
|
|
56988
57507
|
try {
|
|
@@ -57127,7 +57646,7 @@ async function draftPlanForExisting(repoDir, opts = {}) {
|
|
|
57127
57646
|
} catch {
|
|
57128
57647
|
}
|
|
57129
57648
|
}
|
|
57130
|
-
const name2 = (opts.name ?? pkgName ??
|
|
57649
|
+
const name2 = (opts.name ?? pkgName ?? basename2(root)).slice(0, 100);
|
|
57131
57650
|
const milestone = opts.milestoneId ?? "M1";
|
|
57132
57651
|
const allowedPaths = opts.allowedPaths ?? ["."];
|
|
57133
57652
|
const tasks = [];
|
|
@@ -57325,7 +57844,7 @@ async function importSpecKit(repoDir) {
|
|
|
57325
57844
|
const constitution = await findConstitution(root);
|
|
57326
57845
|
const parsedConstitution = constitution ? parseConstitution(constitution.text) : void 0;
|
|
57327
57846
|
const firstInput = /\*\*Input\*\*:\s*User description:\s*"(.*)"/.exec(features[0]?.specText ?? "")?.[1];
|
|
57328
|
-
const name2 = (parsedConstitution?.name ??
|
|
57847
|
+
const name2 = (parsedConstitution?.name ?? basename3(root)).slice(0, 100);
|
|
57329
57848
|
const goal = (parsedConstitution?.goal ?? firstInput ?? `Deliver ${name2}.`).slice(0, 2e3);
|
|
57330
57849
|
const multi = features.length > 1;
|
|
57331
57850
|
const counts2 = /* @__PURE__ */ new Map();
|
|
@@ -58698,7 +59217,7 @@ var contextCommand = defineCommand({
|
|
|
58698
59217
|
init_src();
|
|
58699
59218
|
init_zod();
|
|
58700
59219
|
import { existsSync as existsSync4, readFileSync as readFileSync7 } from "node:fs";
|
|
58701
|
-
import { basename as
|
|
59220
|
+
import { basename as basename4, resolve as resolve7 } from "node:path";
|
|
58702
59221
|
var SERVICE_FLAG = { name: "service", type: "string", value: "URL", description: "The service address (default: HARNESS_SERVICE_URL, then the project's binding, then the hosted service)" };
|
|
58703
59222
|
var TEAM_FLAG = { name: "team", type: "string", value: "TENANT_ID", description: "The team (tenant) to act on (default: the one your token belongs to)" };
|
|
58704
59223
|
var ECOSYSTEM_FLAG = { name: "ecosystem", type: "string", enum: DOCS_ECOSYSTEMS, default: "npm", description: "Where the library is published" };
|
|
@@ -58810,7 +59329,7 @@ function readLockfiles(paths) {
|
|
|
58810
59329
|
const files = paths.length > 0 ? paths : DEFAULT_LOCKFILES.filter((name2) => existsSync4(resolve7(name2)));
|
|
58811
59330
|
if (files.length === 0) throw new UsageError("no lockfile found in this directory", { hint: "overlane lib pins --project <id> --lockfile pnpm-lock.yaml" });
|
|
58812
59331
|
return files.map((file2) => {
|
|
58813
|
-
const kind = LOCKFILES.find(([pattern]) => pattern.test(
|
|
59332
|
+
const kind = LOCKFILES.find(([pattern]) => pattern.test(basename4(file2)))?.[1];
|
|
58814
59333
|
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" });
|
|
58815
59334
|
try {
|
|
58816
59335
|
return { kind, content: readFileSync7(resolve7(file2), "utf8") };
|
|
@@ -58906,7 +59425,7 @@ var libAddCommand = defineCommand({
|
|
|
58906
59425
|
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" });
|
|
58907
59426
|
const pages = files.map((file2) => {
|
|
58908
59427
|
try {
|
|
58909
|
-
return { title:
|
|
59428
|
+
return { title: basename4(file2), text: readFileSync7(resolve7(file2), "utf8") };
|
|
58910
59429
|
} catch {
|
|
58911
59430
|
throw new UsageError(`cannot read ${file2}`);
|
|
58912
59431
|
}
|
|
@@ -58982,7 +59501,7 @@ async function post(deps, base4, path, body2) {
|
|
|
58982
59501
|
return { status: response.status, json: json2 };
|
|
58983
59502
|
}
|
|
58984
59503
|
function sleep(ms) {
|
|
58985
|
-
return new Promise((
|
|
59504
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
58986
59505
|
}
|
|
58987
59506
|
async function deviceLogin(deps, service, options) {
|
|
58988
59507
|
const started = await post(deps, service, "/auth/device", {});
|
|
@@ -59337,19 +59856,287 @@ var tokenRevokeCommand = defineCommand({
|
|
|
59337
59856
|
});
|
|
59338
59857
|
var identityCommands = [authLoginCommand, authLogoutCommand, authTokenCommand, teamListCommand, teamInviteCommand, tokenCreateCommand, tokenListCommand, tokenRevokeCommand];
|
|
59339
59858
|
|
|
59340
|
-
// ../cli/src/commands/
|
|
59859
|
+
// ../cli/src/commands/billing.ts
|
|
59341
59860
|
init_src();
|
|
59342
59861
|
init_zod();
|
|
59343
59862
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
59344
|
-
import { readFileSync as readFileSync8 } from "node:fs";
|
|
59345
|
-
import { resolve as resolve8 } from "node:path";
|
|
59346
59863
|
var common2 = { needsAuth: true, needsNetwork: true };
|
|
59347
59864
|
var requestId3 = () => `cli-${randomUUID3()}`;
|
|
59348
59865
|
async function connected(inv) {
|
|
59866
|
+
const project = await connectedProject(inv.deps, "billing");
|
|
59867
|
+
return { call: serviceCall(inv.deps, project.serviceUrl, project.token), tenantId: project.binding.tenantId };
|
|
59868
|
+
}
|
|
59869
|
+
async function planned(inv, method, path, body2, note) {
|
|
59870
|
+
const project = await offlineProject(inv.deps, "billing");
|
|
59871
|
+
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
59872
|
+
}
|
|
59873
|
+
var usd = (cents) => `$${Math.trunc(cents / 100)}.${String(cents % 100).padStart(2, "0")}`;
|
|
59874
|
+
var micros = (value) => value % 1e4 === 0 ? usd(value / 1e4) : `$${(value / 1e6).toFixed(3)}`;
|
|
59875
|
+
function parseUsdToCents(text) {
|
|
59876
|
+
const match = /^(\d{1,7})(?:\.(\d{1,2}))?$/.exec(text.trim());
|
|
59877
|
+
if (match === null) throw new UsageError("--usd must be an amount like 50 or 12.50", { hint: "overlane billing caps set --scope team --usd 50" });
|
|
59878
|
+
return Number(match[1]) * 100 + Number((match[2] ?? "").padEnd(2, "0") || "0");
|
|
59879
|
+
}
|
|
59880
|
+
function positiveInt(text, flag) {
|
|
59881
|
+
if (text === void 0) return void 0;
|
|
59882
|
+
if (!/^\d+$/.test(text) || Number(text) < 1) throw new UsageError(`--${flag} must be a whole number of at least 1`);
|
|
59883
|
+
return Number(text);
|
|
59884
|
+
}
|
|
59885
|
+
var PLAN_FLAG = (plans, required2) => ({ name: "plan", type: "string", required: required2, enum: plans, value: "PLAN", description: "The plan" });
|
|
59886
|
+
var INTERVAL_FLAG = { name: "interval", type: "string", enum: ["month", "year"], value: "month|year", description: "Billing period; annual billing is cheaper per month" };
|
|
59887
|
+
var SEATS_FLAG = { name: "seats", type: "string", value: "N", description: "Seats (Business needs at least 10; Pro is one person)" };
|
|
59888
|
+
var billingStatusCommand = defineCommand({
|
|
59889
|
+
path: ["billing", "status"],
|
|
59890
|
+
summary: "Show the plan, seats, usage against allowances, caps, grace period and invoices",
|
|
59891
|
+
description: "Shows what this workspace is on, what the plan allows (from the one plan data file the pricing page also reads), what is used this period, any spending caps, and whether a failed payment has started a grace period. Read-only for every role, agents included.",
|
|
59892
|
+
examples: ["overlane billing status", "overlane billing status --json"],
|
|
59893
|
+
effect: "read",
|
|
59894
|
+
...common2,
|
|
59895
|
+
keywords: ["billing", "plan", "subscription", "invoice", "what plan am i on", "seats", "grace period", "read-only"],
|
|
59896
|
+
result: BillingStatus,
|
|
59897
|
+
text: (d) => [
|
|
59898
|
+
`plan: ${d.subscription.plan} (${d.subscription.status}), ${d.subscription.seats} seat${d.subscription.seats === 1 ? "" : "s"}, ${d.subscription.interval}ly${d.subscription.cancelAtPeriodEnd ? ", ends at the period end" : ""}`,
|
|
59899
|
+
...d.limits.readOnly ? ["this workspace is READ-ONLY: nothing was deleted; reading works"] : [],
|
|
59900
|
+
...d.grace.state === "none" ? [] : [`payment: ${d.grace.state}${d.grace.endsAt === void 0 ? "" : ` until ${d.grace.endsAt.slice(0, 10)}`}`],
|
|
59901
|
+
...d.usage.meters.map((m) => `${m.meter}: ${m.used}${typeof m.allowance === "number" ? ` of ${m.allowance}` : m.allowance === "unlimited" ? " (unlimited)" : ""}${m.overageMicros > 0 ? `, overage ${micros(m.overageMicros)}` : ""}`),
|
|
59902
|
+
`metered spend this period: ${micros(d.usage.spendMicros)}`,
|
|
59903
|
+
...d.caps.map((c) => `cap ${c.scope}${c.scopeId === void 0 ? "" : ` ${c.scopeId}`}: ${usd(c.limitCents)}`),
|
|
59904
|
+
...d.usage.notices,
|
|
59905
|
+
...d.grace.notices.slice(-1).map((n) => n.message),
|
|
59906
|
+
...d.live ? [] : ["payments: not connected to Stripe in this deployment (live leg pending)"]
|
|
59907
|
+
],
|
|
59908
|
+
handler: async (inv) => {
|
|
59909
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59910
|
+
return { data: await call2(BillingStatus, "GET", billingPaths.status(tenantId)) };
|
|
59911
|
+
}
|
|
59912
|
+
});
|
|
59913
|
+
var billingUsageCommand = defineCommand({
|
|
59914
|
+
path: ["billing", "usage"],
|
|
59915
|
+
summary: "Show usage this period against each allowance, with the overage price from the plan data file",
|
|
59916
|
+
description: "Lists reviews, CI minutes, docs calls and hosted inference used this period, the allowance each plan gives, units beyond it and what they cost. Beyond an allowance nothing stops unless a spending cap is set.",
|
|
59917
|
+
examples: ["overlane billing usage", "overlane billing usage --json"],
|
|
59918
|
+
effect: "read",
|
|
59919
|
+
...common2,
|
|
59920
|
+
keywords: ["usage", "allowance", "overage", "reviews used", "ci minutes", "how much have i used"],
|
|
59921
|
+
result: UsageSummary,
|
|
59922
|
+
text: (d) => [`period: ${d.periodStart.slice(0, 10)} to ${d.periodEnd.slice(0, 10)}`, ...d.meters.map((m) => `${m.meter}: ${m.used}${typeof m.allowance === "number" ? ` / ${m.allowance}` : ""}${m.rateMicros === null ? "" : ` (${micros(m.rateMicros)} each beyond)`}${m.overageMicros > 0 ? ` overage ${micros(m.overageMicros)}` : ""}`), `metered spend: ${micros(d.spendMicros)}`, ...d.notices],
|
|
59923
|
+
handler: async (inv) => {
|
|
59924
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59925
|
+
return { data: await call2(UsageSummary, "GET", billingPaths.usage(tenantId)) };
|
|
59926
|
+
}
|
|
59927
|
+
});
|
|
59928
|
+
var billingCheckCommand = defineCommand({
|
|
59929
|
+
path: ["billing", "check"],
|
|
59930
|
+
summary: "Ask whether a spend is allowed now; exits 6 when a limit or cap refuses it",
|
|
59931
|
+
description: "Asks the billing service before a review, CI run or hosted inference call: within the allowance, over it and billed (with a notice), or refused (a plan with no overage path, a reached spending cap, a read-only workspace). A refusal exits 6 and names the next command.",
|
|
59932
|
+
flags: [
|
|
59933
|
+
{ name: "meter", type: "string", required: true, enum: METERS, value: "METER", description: "What is being spent" },
|
|
59934
|
+
{ name: "quantity", type: "string", value: "N", description: "Units, default 1" },
|
|
59935
|
+
{ name: "cost-micros", type: "string", value: "N", description: "Provider cost of a hosted inference call, in millionths of a dollar" },
|
|
59936
|
+
{ name: "project", type: "string", value: "ID", description: "The project, for a project cap" },
|
|
59937
|
+
{ name: "agent", type: "string", value: "ID", description: "The agent token, for an agent cap" },
|
|
59938
|
+
{ name: "byok", type: "boolean", description: "The call runs on your own key: no platform charge" }
|
|
59939
|
+
],
|
|
59940
|
+
examples: ["overlane billing check --meter reviews", "overlane billing check --meter hostedInference --cost-micros 2000 --agent tok_1"],
|
|
59941
|
+
effect: "read",
|
|
59942
|
+
...common2,
|
|
59943
|
+
keywords: ["can i spend", "spending cap reached", "limit check", "exit 6", "budget gate"],
|
|
59944
|
+
result: UsageDecision,
|
|
59945
|
+
text: (d) => [`${d.allowed ? "ALLOWED" : "REFUSED"} (${d.outcome}) ${d.message}`, ...d.nextCommand === null ? [] : [`next: ${d.nextCommand}`]],
|
|
59946
|
+
handler: async (inv) => {
|
|
59947
|
+
const meter = textFlag(inv, "meter");
|
|
59948
|
+
if (meter === void 0) throw new UsageError("check needs --meter", { hint: "overlane billing check --meter reviews" });
|
|
59949
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59950
|
+
const quantity = positiveInt(textFlag(inv, "quantity"), "quantity");
|
|
59951
|
+
const cost = textFlag(inv, "cost-micros");
|
|
59952
|
+
const body2 = { meter, ...quantity === void 0 ? {} : { quantity }, ...cost === void 0 ? {} : { costMicros: Number(cost) }, ...textFlag(inv, "project") === void 0 ? {} : { projectId: textFlag(inv, "project") }, ...textFlag(inv, "agent") === void 0 ? {} : { agentId: textFlag(inv, "agent") }, ...boolFlag(inv, "byok") ? { byok: true } : {} };
|
|
59953
|
+
const decision = await call2(UsageDecision, "POST", billingPaths.decision(tenantId), body2);
|
|
59954
|
+
return decision.allowed ? { data: decision } : { data: decision, exit: EXIT.blocked, error: new CliError(decision.message, { code: decision.outcome, exit: EXIT.blocked, ...decision.nextCommand === null ? {} : { hint: decision.nextCommand } }) };
|
|
59955
|
+
}
|
|
59956
|
+
});
|
|
59957
|
+
var billingCheckoutCommand = defineCommand({
|
|
59958
|
+
path: ["billing", "checkout"],
|
|
59959
|
+
summary: "Start buying a plan: prints a Stripe-hosted checkout link (a person pays; agents cannot)",
|
|
59960
|
+
description: "Opens a checkout for Pro, Team or Business. Business needs at least 10 seats. The link is a Stripe-hosted page where the card is entered; Overlane never sees it. The plan is active when the payment webhook arrives. Enterprise is contract-only.",
|
|
59961
|
+
flags: [PLAN_FLAG(["pro", "team", "business"], true), INTERVAL_FLAG, SEATS_FLAG],
|
|
59962
|
+
examples: ["overlane billing checkout --plan team --seats 5", "overlane billing checkout --plan business --seats 10 --interval year --dry-run"],
|
|
59963
|
+
effect: "write",
|
|
59964
|
+
...common2,
|
|
59965
|
+
keywords: ["upgrade", "buy", "subscribe", "pay", "checkout", "choose plan"],
|
|
59966
|
+
result: withDryRun(CheckoutResponse),
|
|
59967
|
+
text: (d) => "url" in d ? [`${d.plan} x ${d.seats} (${d.interval}ly): first period ${usd(d.firstPeriodCents)} before tax`, `open: ${d.url}`] : [],
|
|
59968
|
+
handler: async (inv) => {
|
|
59969
|
+
const body2 = { requestId: requestId3(), plan: textFlag(inv, "plan"), interval: textFlag(inv, "interval") ?? "month", ...textFlag(inv, "seats") === void 0 ? {} : { seats: positiveInt(textFlag(inv, "seats"), "seats") } };
|
|
59970
|
+
if (inv.dryRun) return planned(inv, "POST", billingPaths.checkout, body2, "opens a Stripe-hosted checkout; nothing is charged");
|
|
59971
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59972
|
+
return { data: await call2(CheckoutResponse, "POST", billingPaths.checkout(tenantId), body2) };
|
|
59973
|
+
}
|
|
59974
|
+
});
|
|
59975
|
+
var billingPlanCommand = defineCommand({
|
|
59976
|
+
path: ["billing", "plan"],
|
|
59977
|
+
summary: "Upgrade or downgrade the plan; a downgrade over the new limits makes the workspace read-only and deletes nothing",
|
|
59978
|
+
description: "Changes a paid plan with proration for the rest of the period. `--plan free` ends the paid plan at the end of the period already paid for. If data is over the new plan's limits the workspace becomes read-only (reads keep working) and nothing is ever deleted; upgrading restores it.",
|
|
59979
|
+
flags: [PLAN_FLAG(["free", "pro", "team", "business"], true), INTERVAL_FLAG, SEATS_FLAG],
|
|
59980
|
+
examples: ["overlane billing plan --plan team --seats 4", "overlane billing plan --plan free --dry-run"],
|
|
59981
|
+
effect: "write",
|
|
59982
|
+
...common2,
|
|
59983
|
+
keywords: ["downgrade", "upgrade", "change plan", "switch plan", "go back to free"],
|
|
59984
|
+
result: withDryRun(ChangePlanResponse),
|
|
59985
|
+
text: (d) => "subscription" in d ? [`plan: ${d.subscription.plan}, ${d.subscription.seats} seats`, `proration: ${d.prorationCents >= 0 ? "charge" : "credit"} ${usd(Math.abs(d.prorationCents))}`, ...d.overLimit.map((o) => `over the limit: ${o.what} ${o.used} of ${o.limit}; the workspace is read-only, nothing is deleted`)] : [],
|
|
59986
|
+
handler: async (inv) => {
|
|
59987
|
+
const body2 = { requestId: requestId3(), plan: textFlag(inv, "plan"), ...textFlag(inv, "interval") === void 0 ? {} : { interval: textFlag(inv, "interval") }, ...textFlag(inv, "seats") === void 0 ? {} : { seats: positiveInt(textFlag(inv, "seats"), "seats") } };
|
|
59988
|
+
if (inv.dryRun) return planned(inv, "POST", billingPaths.plan, body2, "prorates the rest of the period");
|
|
59989
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
59990
|
+
return { data: await call2(ChangePlanResponse, "POST", billingPaths.plan(tenantId), body2) };
|
|
59991
|
+
}
|
|
59992
|
+
});
|
|
59993
|
+
var billingSeatsCommand = defineCommand({
|
|
59994
|
+
path: ["billing", "seats"],
|
|
59995
|
+
summary: "Change the number of seats mid-cycle; the change prorates",
|
|
59996
|
+
description: "Sets the seat count on a per-seat plan. The charge or credit for the rest of the period is prorated by the second. Business never goes below 10 seats, and seats cannot drop below the people who hold one.",
|
|
59997
|
+
flags: [{ ...SEATS_FLAG, required: true }],
|
|
59998
|
+
examples: ["overlane billing seats --seats 8", "overlane billing seats --seats 12 --dry-run"],
|
|
59999
|
+
effect: "write",
|
|
60000
|
+
...common2,
|
|
60001
|
+
keywords: ["add seats", "remove seats", "more people", "proration", "seat count"],
|
|
60002
|
+
result: withDryRun(SeatChangeResponse),
|
|
60003
|
+
text: (d) => "seat" in d ? [`seats: ${d.seat.purchased} (${d.seat.assigned} in use)`, `proration: ${d.prorationCents >= 0 ? "charge" : "credit"} ${usd(Math.abs(d.prorationCents))}`] : [],
|
|
60004
|
+
handler: async (inv) => {
|
|
60005
|
+
const body2 = { requestId: requestId3(), seats: positiveInt(textFlag(inv, "seats"), "seats") };
|
|
60006
|
+
if (inv.dryRun) return planned(inv, "POST", billingPaths.seats, body2, "prorates the rest of the period");
|
|
60007
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
60008
|
+
return { data: await call2(SeatChangeResponse, "POST", billingPaths.seats(tenantId), body2) };
|
|
60009
|
+
}
|
|
60010
|
+
});
|
|
60011
|
+
var billingCancelCommand = defineCommand({
|
|
60012
|
+
path: ["billing", "cancel"],
|
|
60013
|
+
summary: "Cancel the paid plan at the end of the period already paid for",
|
|
60014
|
+
description: "Cancels at the period end by default, so everything keeps working until then. With --now the plan ends immediately. Data over the Free limits becomes read-only; nothing is deleted.",
|
|
60015
|
+
flags: [{ name: "now", type: "boolean", description: "End the plan immediately instead of at the period end" }],
|
|
60016
|
+
examples: ["overlane billing cancel", "overlane billing cancel --dry-run"],
|
|
60017
|
+
effect: "destructive",
|
|
60018
|
+
...common2,
|
|
60019
|
+
keywords: ["cancel subscription", "stop paying", "end plan"],
|
|
60020
|
+
result: withDryRun(Subscription),
|
|
60021
|
+
text: (d) => "plan" in d ? [`plan: ${d.plan}${d.cancelAtPeriodEnd ? `, ends ${d.currentPeriodEnd.slice(0, 10)}` : ""}`] : [],
|
|
60022
|
+
handler: async (inv) => {
|
|
60023
|
+
const body2 = { requestId: requestId3(), atPeriodEnd: !boolFlag(inv, "now") };
|
|
60024
|
+
if (inv.dryRun) return planned(inv, "POST", billingPaths.cancel, body2);
|
|
60025
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
60026
|
+
return { data: await call2(Subscription, "POST", billingPaths.cancel(tenantId), body2) };
|
|
60027
|
+
}
|
|
60028
|
+
});
|
|
60029
|
+
var billingPortalCommand = defineCommand({
|
|
60030
|
+
path: ["billing", "portal"],
|
|
60031
|
+
summary: "Print a link to Stripe's billing portal: card, invoices and tax details",
|
|
60032
|
+
description: "Opens a Stripe-hosted portal where a person updates the card, downloads invoices and edits tax details. Overlane never stores card data.",
|
|
60033
|
+
examples: ["overlane billing portal"],
|
|
60034
|
+
effect: "write",
|
|
60035
|
+
...common2,
|
|
60036
|
+
keywords: ["update card", "invoices", "tax id", "payment method", "billing portal"],
|
|
60037
|
+
result: withDryRun(PortalResponse),
|
|
60038
|
+
text: (d) => "url" in d ? [`open: ${d.url}`] : [],
|
|
60039
|
+
handler: async (inv) => {
|
|
60040
|
+
if (inv.dryRun) return planned(inv, "POST", billingPaths.portal, {});
|
|
60041
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
60042
|
+
return { data: await call2(PortalResponse, "POST", billingPaths.portal(tenantId), {}) };
|
|
60043
|
+
}
|
|
60044
|
+
});
|
|
60045
|
+
var CapList = external_exports.object({ tenantId: external_exports.string(), caps: external_exports.array(Cap) }).strict();
|
|
60046
|
+
var CapRemoved = external_exports.object({ tenantId: external_exports.string(), removed: external_exports.literal(true) }).strict();
|
|
60047
|
+
var CAP_FLAGS = [
|
|
60048
|
+
{ name: "scope", type: "string", required: true, enum: CAP_SCOPES, value: "SCOPE", description: "team, project or agent" },
|
|
60049
|
+
{ name: "id", type: "string", value: "ID", description: "The project or agent token the cap applies to (not for team)" }
|
|
60050
|
+
];
|
|
60051
|
+
function capTarget(inv) {
|
|
60052
|
+
const scope = textFlag(inv, "scope");
|
|
60053
|
+
const id2 = textFlag(inv, "id");
|
|
60054
|
+
if (scope === void 0) throw new UsageError("this command needs --scope", { hint: "overlane billing caps set --scope team --usd 50" });
|
|
60055
|
+
if (scope === "team" && id2 !== void 0) throw new UsageError("a team cap has no --id");
|
|
60056
|
+
if (scope !== "team" && id2 === void 0) throw new UsageError(`a ${scope} cap needs --id`, { hint: `overlane billing caps set --scope ${scope} --id <${scope} id> --usd 50` });
|
|
60057
|
+
return { scope, ...id2 === void 0 ? {} : { scopeId: id2 } };
|
|
60058
|
+
}
|
|
60059
|
+
var billingCapsListCommand = defineCommand({
|
|
60060
|
+
path: ["billing", "caps", "list"],
|
|
60061
|
+
summary: "List spending caps per team, project and agent",
|
|
60062
|
+
description: "Shows each cap in dollars per billing period. With a cap set, reviews, CI and hosted inference stop at it (exit 6); with none, usage beyond an allowance is billed.",
|
|
60063
|
+
examples: ["overlane billing caps list", "overlane billing caps list --json"],
|
|
60064
|
+
effect: "read",
|
|
60065
|
+
...common2,
|
|
60066
|
+
keywords: ["spending cap", "budget", "limit spend", "caps"],
|
|
60067
|
+
result: CapList,
|
|
60068
|
+
text: (d) => d.caps.length === 0 ? ["No spending caps: usage beyond an allowance is billed, nothing stops."] : d.caps.map((c) => `${c.scope}${c.scopeId === void 0 ? "" : ` ${c.scopeId}`}: ${usd(c.limitCents)} per period`),
|
|
60069
|
+
handler: async (inv) => {
|
|
60070
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
60071
|
+
return { data: await call2(CapList, "GET", billingPaths.caps(tenantId)) };
|
|
60072
|
+
}
|
|
60073
|
+
});
|
|
60074
|
+
var billingCapsSetCommand = defineCommand({
|
|
60075
|
+
path: ["billing", "caps", "set"],
|
|
60076
|
+
summary: "Set a spending cap per period for the team, a project or an agent",
|
|
60077
|
+
description: "Sets the most metered spend (overage plus hosted inference with markup) allowed per billing period. At the cap, hosted inference, AI reviews and CI stop with exit code 6 and a visible message until the next period or until the cap is raised. Only a signed-in owner can set one.",
|
|
60078
|
+
flags: [...CAP_FLAGS, { name: "usd", type: "string", required: true, value: "AMOUNT", description: "Dollars per period, for example 50 or 12.50" }],
|
|
60079
|
+
examples: ["overlane billing caps set --scope team --usd 50", "overlane billing caps set --scope agent --id tok_1 --usd 5 --dry-run"],
|
|
60080
|
+
effect: "write",
|
|
60081
|
+
...common2,
|
|
60082
|
+
keywords: ["set cap", "limit spending", "budget", "stop at"],
|
|
60083
|
+
result: withDryRun(Cap),
|
|
60084
|
+
text: (d) => "limitCents" in d ? [`cap ${d.scope}${d.scopeId === void 0 ? "" : ` ${d.scopeId}`}: ${usd(d.limitCents)} per period`] : [],
|
|
60085
|
+
handler: async (inv) => {
|
|
60086
|
+
const target = capTarget(inv);
|
|
60087
|
+
const usdText = textFlag(inv, "usd");
|
|
60088
|
+
if (usdText === void 0) throw new UsageError("set needs --usd", { hint: "overlane billing caps set --scope team --usd 50" });
|
|
60089
|
+
const body2 = { requestId: requestId3(), ...target, limitCents: parseUsdToCents(usdText) };
|
|
60090
|
+
if (inv.dryRun) return planned(inv, "PUT", billingPaths.caps, body2);
|
|
60091
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
60092
|
+
return { data: await call2(Cap, "PUT", billingPaths.caps(tenantId), body2) };
|
|
60093
|
+
}
|
|
60094
|
+
});
|
|
60095
|
+
var billingCapsRemoveCommand = defineCommand({
|
|
60096
|
+
path: ["billing", "caps", "remove"],
|
|
60097
|
+
summary: "Remove a spending cap",
|
|
60098
|
+
description: "Removes a cap. Without a team cap, usage beyond an allowance is billed and nothing stops.",
|
|
60099
|
+
flags: CAP_FLAGS,
|
|
60100
|
+
examples: ["overlane billing caps remove --scope team", "overlane billing caps remove --scope project --id prj_1 --dry-run"],
|
|
60101
|
+
effect: "write",
|
|
60102
|
+
...common2,
|
|
60103
|
+
keywords: ["remove cap", "no limit", "delete cap"],
|
|
60104
|
+
result: withDryRun(CapRemoved),
|
|
60105
|
+
text: (d) => "removed" in d ? ["Cap removed."] : [],
|
|
60106
|
+
handler: async (inv) => {
|
|
60107
|
+
const body2 = { requestId: requestId3(), ...capTarget(inv) };
|
|
60108
|
+
if (inv.dryRun) return planned(inv, "DELETE", billingPaths.caps, body2);
|
|
60109
|
+
const { call: call2, tenantId } = await connected(inv);
|
|
60110
|
+
return { data: await call2(CapRemoved, "DELETE", billingPaths.caps(tenantId), body2) };
|
|
60111
|
+
}
|
|
60112
|
+
});
|
|
60113
|
+
var billingCommands = [
|
|
60114
|
+
billingStatusCommand,
|
|
60115
|
+
billingUsageCommand,
|
|
60116
|
+
billingCheckCommand,
|
|
60117
|
+
billingCheckoutCommand,
|
|
60118
|
+
billingPlanCommand,
|
|
60119
|
+
billingSeatsCommand,
|
|
60120
|
+
billingCancelCommand,
|
|
60121
|
+
billingPortalCommand,
|
|
60122
|
+
billingCapsListCommand,
|
|
60123
|
+
billingCapsSetCommand,
|
|
60124
|
+
billingCapsRemoveCommand
|
|
60125
|
+
];
|
|
60126
|
+
|
|
60127
|
+
// ../cli/src/commands/guard.ts
|
|
60128
|
+
init_src();
|
|
60129
|
+
init_zod();
|
|
60130
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
60131
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
60132
|
+
import { resolve as resolve8 } from "node:path";
|
|
60133
|
+
var common3 = { needsAuth: true, needsNetwork: true };
|
|
60134
|
+
var requestId4 = () => `cli-${randomUUID4()}`;
|
|
60135
|
+
async function connected2(inv) {
|
|
59349
60136
|
const project = await connectedProject(inv.deps, "guard");
|
|
59350
60137
|
return { project, call: serviceCall(inv.deps, project.serviceUrl, project.token), tenantId: project.binding.tenantId, projectId: project.binding.projectId };
|
|
59351
60138
|
}
|
|
59352
|
-
async function
|
|
60139
|
+
async function planned2(inv, method, path, body2, note) {
|
|
59353
60140
|
const project = await offlineProject(inv.deps, "guard");
|
|
59354
60141
|
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
59355
60142
|
}
|
|
@@ -59398,12 +60185,12 @@ var guardRulesListCommand = defineCommand({
|
|
|
59398
60185
|
description: "Lists the platform rules (always in force), then the team and project rule files and their rules. A rule change is an audit event; every file version is listed with its digest and author.",
|
|
59399
60186
|
examples: ["overlane guard rules list", "overlane guard rules list --json"],
|
|
59400
60187
|
effect: "read",
|
|
59401
|
-
...
|
|
60188
|
+
...common3,
|
|
59402
60189
|
keywords: ["guardrails", "policy as code", "rules in force", "protected branches", "what is blocked", "rule files"],
|
|
59403
60190
|
result: GuardRulesResponse,
|
|
59404
60191
|
text: (d) => [...d.rules.map((rule) => `${rule.layer.padEnd(8)} ${rule.effect.padEnd(16)} ${rule.id}${rule.dryRun ? " [dry-run]" : ""} ${rule.description}`), ...d.files.map((file2) => `file ${file2.layer} v${file2.version} ${file2.digest.slice(0, 19)} by ${file2.author}`)],
|
|
59405
60192
|
handler: async (inv) => {
|
|
59406
|
-
const { call: call2, tenantId, projectId } = await
|
|
60193
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59407
60194
|
return { data: await call2(GuardRulesResponse, "GET", `${guardPaths.rules(tenantId)}?projectId=${encodeURIComponent(projectId)}`) };
|
|
59408
60195
|
}
|
|
59409
60196
|
});
|
|
@@ -59473,7 +60260,7 @@ var guardRulesPutCommand = defineCommand({
|
|
|
59473
60260
|
],
|
|
59474
60261
|
examples: ['overlane guard rules put --file rules.json --reason "freeze deploys on Fridays"', "overlane guard rules put --file rules.json --layer project --dry-run"],
|
|
59475
60262
|
effect: "write",
|
|
59476
|
-
...
|
|
60263
|
+
...common3,
|
|
59477
60264
|
keywords: ["publish rules", "update guardrails", "change policy", "upload rule file", "freeze deploys"],
|
|
59478
60265
|
result: withDryRun(GuardRuleFileRecord),
|
|
59479
60266
|
text: (d) => "version" in d ? [`Published ${d.layer} rule file v${d.version} (${d.ruleCount} rules, ${d.digest.slice(0, 19)}).`] : [],
|
|
@@ -59487,12 +60274,12 @@ var guardRulesPutCommand = defineCommand({
|
|
|
59487
60274
|
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" }] }));
|
|
59488
60275
|
}
|
|
59489
60276
|
const content = readText3(inv, file2);
|
|
59490
|
-
const { call: call2, tenantId, projectId } = await
|
|
59491
|
-
return { data: await call2(GuardRuleFileRecord, "PUT", guardPaths.rules(tenantId), { requestId:
|
|
60277
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
60278
|
+
return { data: await call2(GuardRuleFileRecord, "PUT", guardPaths.rules(tenantId), { requestId: requestId4(), layer, ...layer === "project" ? { projectId } : {}, content, ...reason === void 0 ? {} : { reason } }) };
|
|
59492
60279
|
}
|
|
59493
60280
|
});
|
|
59494
60281
|
async function evaluate(inv, dryRun) {
|
|
59495
|
-
const { call: call2, tenantId, projectId } = await
|
|
60282
|
+
const { call: call2, tenantId, projectId } = await connected2(inv);
|
|
59496
60283
|
const contentFile = textFlag(inv, "content-file");
|
|
59497
60284
|
const body2 = {
|
|
59498
60285
|
...actionOf(inv),
|
|
@@ -59518,12 +60305,12 @@ var guardCheckCommand = defineCommand({
|
|
|
59518
60305
|
flags: [...DECISION_FLAGS, { name: "approval", type: "string", value: "ID", description: "An approval that covers exactly this action" }],
|
|
59519
60306
|
examples: ["overlane guard check --tool git.push --branch main --task held", 'overlane guard check --tool deploy.run --environment production --summary "Deploy build 42" --dry-run'],
|
|
59520
60307
|
effect: "write",
|
|
59521
|
-
...
|
|
60308
|
+
...common3,
|
|
59522
60309
|
keywords: ["check action", "pre push check", "ci gate", "is this allowed", "approval required", "blocked by policy"],
|
|
59523
60310
|
result: withDryRun(GuardEvaluateResponse),
|
|
59524
60311
|
text: (d) => "decision" in d ? describeDecision(d.decision) : [],
|
|
59525
60312
|
handler: async (inv) => {
|
|
59526
|
-
if (inv.dryRun) return
|
|
60313
|
+
if (inv.dryRun) return planned2(inv, "POST", guardPaths.evaluate, { ...actionOf(inv) }, "the decision is recorded; a rule that needs approval opens one");
|
|
59527
60314
|
const reply = await evaluate(inv, false);
|
|
59528
60315
|
return reply.decision.allowed ? { data: reply } : refusalOutcome(reply, reply.decision);
|
|
59529
60316
|
}
|
|
@@ -59535,7 +60322,7 @@ var guardDryRunCommand = defineCommand({
|
|
|
59535
60322
|
flags: DECISION_FLAGS,
|
|
59536
60323
|
examples: ["overlane guard dry-run --tool git.push --branch main --task held", "overlane guard dry-run --tool egress.fetch --host registry.example.com --json"],
|
|
59537
60324
|
effect: "read",
|
|
59538
|
-
...
|
|
60325
|
+
...common3,
|
|
59539
60326
|
keywords: ["dry run rules", "what would block", "test policy", "simulate", "would be refused"],
|
|
59540
60327
|
result: GuardEvaluateResponse,
|
|
59541
60328
|
text: (d) => describeDecision(d.decision),
|
|
@@ -59551,14 +60338,14 @@ var guardScanCommand = defineCommand({
|
|
|
59551
60338
|
],
|
|
59552
60339
|
examples: ["overlane guard scan --path src/config.ts", "overlane guard scan --path ci.log --source log --json"],
|
|
59553
60340
|
effect: "read",
|
|
59554
|
-
...
|
|
60341
|
+
...common3,
|
|
59555
60342
|
keywords: ["secret scan", "find credentials", "leaked key", "push protection", "scan file"],
|
|
59556
60343
|
result: SecretScanResult,
|
|
59557
60344
|
text: (d) => d.findings.length === 0 ? ["No credentials found."] : d.findings.map((finding) => `${finding.disposition.padEnd(8)} ${finding.rule}${finding.path === void 0 ? "" : ` ${finding.path}`}${finding.line === void 0 ? "" : `:${finding.line}`}`),
|
|
59558
60345
|
handler: async (inv) => {
|
|
59559
60346
|
const path = textFlag(inv, "path");
|
|
59560
60347
|
if (path === void 0) throw new UsageError("scan needs --path", { hint: "overlane guard scan --path src/config.ts" });
|
|
59561
|
-
const { call: call2, tenantId } = await
|
|
60348
|
+
const { call: call2, tenantId } = await connected2(inv);
|
|
59562
60349
|
const result = await call2(SecretScanResult, "POST", guardPaths.scan(tenantId), { source: textFlag(inv, "source") ?? "push", content: readText3(inv, path), path });
|
|
59563
60350
|
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 };
|
|
59564
60351
|
}
|
|
@@ -59571,12 +60358,12 @@ var guardApprovalsListCommand = defineCommand({
|
|
|
59571
60358
|
flags: [{ name: "status", type: "string", enum: ["pending", "approved", "denied"], description: "Only approvals with this status" }],
|
|
59572
60359
|
examples: ["overlane guard approvals list", "overlane guard approvals list --status pending --json"],
|
|
59573
60360
|
effect: "read",
|
|
59574
|
-
...
|
|
60361
|
+
...common3,
|
|
59575
60362
|
keywords: ["pending approvals", "approve before write", "who needs to approve", "approval queue"],
|
|
59576
60363
|
result: ApprovalList2,
|
|
59577
60364
|
text: (d) => d.approvals.length === 0 ? ["No approvals."] : d.approvals.flatMap((a) => [`${a.status.padEnd(9)} ${a.id} ${a.tool} by ${a.requestedBy} (rule ${a.ruleId})`, ` ${a.summary}`]),
|
|
59578
60365
|
handler: async (inv) => {
|
|
59579
|
-
const { call: call2, tenantId } = await
|
|
60366
|
+
const { call: call2, tenantId } = await connected2(inv);
|
|
59580
60367
|
const status = textFlag(inv, "status");
|
|
59581
60368
|
return { data: await call2(ApprovalList2, "GET", `${guardPaths.approvals(tenantId)}${status === void 0 ? "" : `?status=${status}`}`) };
|
|
59582
60369
|
}
|
|
@@ -59593,7 +60380,7 @@ var guardApprovalsAnswerCommand = defineCommand({
|
|
|
59593
60380
|
],
|
|
59594
60381
|
examples: ["overlane guard approvals answer apr_1 --decision approve", 'overlane guard approvals answer apr_1 --decision approve --evidence "diff reviewed" --reason "matches the task" --dry-run'],
|
|
59595
60382
|
effect: "write",
|
|
59596
|
-
...
|
|
60383
|
+
...common3,
|
|
59597
60384
|
keywords: ["approve action", "deny action", "answer approval", "allow push", "sign off"],
|
|
59598
60385
|
result: withDryRun(GuardApproval),
|
|
59599
60386
|
text: (d) => "status" in d ? [`${d.id} is ${d.status}.`] : [],
|
|
@@ -59604,8 +60391,8 @@ var guardApprovalsAnswerCommand = defineCommand({
|
|
|
59604
60391
|
const evidence = listFlag(inv, "evidence");
|
|
59605
60392
|
const parsed = AnswerGuardApprovalRequest.safeParse({ decision: textFlag(inv, "decision"), ...reason === void 0 ? {} : { reason }, ...evidence.length === 0 ? {} : { evidence } });
|
|
59606
60393
|
if (!parsed.success) throw new UsageError("--decision must be approve or deny", { hint: `overlane guard approvals answer ${approvalId} --decision approve` });
|
|
59607
|
-
if (inv.dryRun) return
|
|
59608
|
-
const { call: call2, tenantId } = await
|
|
60394
|
+
if (inv.dryRun) return planned2(inv, "POST", (tenantId2) => guardPaths.answer(tenantId2, approvalId), parsed.data);
|
|
60395
|
+
const { call: call2, tenantId } = await connected2(inv);
|
|
59609
60396
|
return { data: await call2(GuardApproval, "POST", guardPaths.answer(tenantId, approvalId), parsed.data) };
|
|
59610
60397
|
}
|
|
59611
60398
|
});
|
|
@@ -59614,10 +60401,10 @@ var guardCommands = [guardRulesListCommand, guardRulesTestCommand, guardRulesPut
|
|
|
59614
60401
|
// ../cli/src/commands/memory.ts
|
|
59615
60402
|
init_src();
|
|
59616
60403
|
init_zod();
|
|
59617
|
-
import { randomUUID as
|
|
60404
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
59618
60405
|
var SERVICE_FLAG3 = { name: "service", type: "string", value: "URL", description: "The service address (default: HARNESS_SERVICE_URL, then the project's binding, then the hosted service)" };
|
|
59619
60406
|
var TEAM_FLAG3 = { name: "team", type: "string", value: "TENANT_ID", description: "The team (tenant) to act on (default: the one your token belongs to)" };
|
|
59620
|
-
var
|
|
60407
|
+
var common4 = { needsAuth: true, needsNetwork: true };
|
|
59621
60408
|
async function authed3(inv) {
|
|
59622
60409
|
const target = await resolveTarget(inv.deps, textFlag(inv, "service"));
|
|
59623
60410
|
const token = await requireToken(inv.deps, target.storeKey);
|
|
@@ -59636,7 +60423,7 @@ async function plan2(inv, method, path, body2, note) {
|
|
|
59636
60423
|
const tenant = textFlag(inv, "team") ?? ":your-team";
|
|
59637
60424
|
return planOutcome(inv.deps, dryRunPlan({ service: target.service, requests: [{ method, path: path(tenant), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
59638
60425
|
}
|
|
59639
|
-
var
|
|
60426
|
+
var requestId5 = () => `cli-${randomUUID5()}`;
|
|
59640
60427
|
var memorySearchCommand = defineCommand({
|
|
59641
60428
|
path: ["memory", "search"],
|
|
59642
60429
|
summary: "Search memory across project, team, user and global scopes",
|
|
@@ -59651,7 +60438,7 @@ var memorySearchCommand = defineCommand({
|
|
|
59651
60438
|
],
|
|
59652
60439
|
examples: ['overlane memory search "how do we deploy"', 'overlane memory search "indentation" --scope team --json'],
|
|
59653
60440
|
effect: "read",
|
|
59654
|
-
...
|
|
60441
|
+
...common4,
|
|
59655
60442
|
keywords: ["recall", "remember", "what do we know", "find memory", "lookup", "notes", "conventions", "decisions"],
|
|
59656
60443
|
result: MemorySearchResponse,
|
|
59657
60444
|
text: (d) => d.items.length === 0 ? ["No memories match."] : d.items.map((i2) => `${i2.scope.padEnd(7)} ${i2.status.padEnd(9)} ${i2.id} ${i2.title}${i2.stale ? " [stale]" : ""}${i2.overriddenBy === null ? "" : ` [overridden by ${i2.overriddenBy}]`}`),
|
|
@@ -59685,7 +60472,7 @@ var memoryAddCommand = defineCommand({
|
|
|
59685
60472
|
],
|
|
59686
60473
|
examples: ['overlane memory add --title "Deploy day" "Deploys go out on Tuesdays" --project prj_1', 'overlane memory add --title "Editor" --scope user "I prefer a dark theme" --dry-run'],
|
|
59687
60474
|
effect: "write",
|
|
59688
|
-
...
|
|
60475
|
+
...common4,
|
|
59689
60476
|
keywords: ["remember this", "save a note", "record a decision", "store convention", "candidate"],
|
|
59690
60477
|
result: AddResult,
|
|
59691
60478
|
handler: async (inv) => {
|
|
@@ -59693,7 +60480,7 @@ var memoryAddCommand = defineCommand({
|
|
|
59693
60480
|
if (title === void 0) throw new UsageError("add needs --title", { hint: 'overlane memory add --title "..." "<text>"' });
|
|
59694
60481
|
const project = textFlag(inv, "project");
|
|
59695
60482
|
const parsed = MemoryCandidate.safeParse({
|
|
59696
|
-
requestId:
|
|
60483
|
+
requestId: requestId5(),
|
|
59697
60484
|
scope: textFlag(inv, "scope") ?? "project",
|
|
59698
60485
|
...project === void 0 ? {} : { projectId: project },
|
|
59699
60486
|
category: textFlag(inv, "category") ?? "fact",
|
|
@@ -59724,7 +60511,7 @@ var memoryConfirmCommand = defineCommand({
|
|
|
59724
60511
|
],
|
|
59725
60512
|
examples: ["overlane memory confirm mem_ab12", "overlane memory confirm mem_ab12 --basis ci_evidence --evidence 0123abc:unit_tests --dry-run"],
|
|
59726
60513
|
effect: "write",
|
|
59727
|
-
...
|
|
60514
|
+
...common4,
|
|
59728
60515
|
keywords: ["approve memory", "verify", "promote candidate", "second observer", "ci evidence"],
|
|
59729
60516
|
result: ConfirmResult,
|
|
59730
60517
|
handler: async (inv) => {
|
|
@@ -59748,7 +60535,7 @@ var memoryPromoteCommand = defineCommand({
|
|
|
59748
60535
|
flags: [SERVICE_FLAG3, TEAM_FLAG3, { name: "to", type: "string", enum: ["team", "global"], default: "team", description: "Where to promote it" }],
|
|
59749
60536
|
examples: ["overlane memory promote mem_ab12 --to team", "overlane memory promote mem_cd34 --to global --dry-run"],
|
|
59750
60537
|
effect: "write",
|
|
59751
|
-
...
|
|
60538
|
+
...common4,
|
|
59752
60539
|
keywords: ["share with team", "contribute", "global memory", "make team wide"],
|
|
59753
60540
|
result: withDryRun(MemoryPromoteResponse),
|
|
59754
60541
|
handler: async (inv) => {
|
|
@@ -59776,7 +60563,7 @@ var memoryExportCommand = defineCommand({
|
|
|
59776
60563
|
],
|
|
59777
60564
|
examples: ["overlane memory export --json", "overlane memory export --scope user --user usr_1 --json"],
|
|
59778
60565
|
effect: "read",
|
|
59779
|
-
...
|
|
60566
|
+
...common4,
|
|
59780
60567
|
keywords: ["download memory", "backup", "data portability", "gdpr", "subject access"],
|
|
59781
60568
|
result: MemoryExportRecord,
|
|
59782
60569
|
text: (d) => [`${d.items.length} memories exported at ${d.exportedAt}. Use --json for the full content.`],
|
|
@@ -59800,7 +60587,7 @@ var memoryDeleteCommand = defineCommand({
|
|
|
59800
60587
|
flags: [SERVICE_FLAG3, TEAM_FLAG3],
|
|
59801
60588
|
examples: ["overlane memory delete mem_ab12 --force", "overlane memory delete mem_ab12 --dry-run"],
|
|
59802
60589
|
effect: "destructive",
|
|
59803
|
-
...
|
|
60590
|
+
...common4,
|
|
59804
60591
|
keywords: ["remove memory", "forget", "erase", "wrong memory", "gdpr deletion"],
|
|
59805
60592
|
result: withDryRun(MemoryDeleteResponse),
|
|
59806
60593
|
handler: async (inv) => {
|
|
@@ -59821,7 +60608,7 @@ var memoryUnlearnCommand = defineCommand({
|
|
|
59821
60608
|
flags: [SERVICE_FLAG3, TEAM_FLAG3],
|
|
59822
60609
|
examples: ["overlane memory unlearn mem_ab12 --force", "overlane memory unlearn mem_ab12 --dry-run"],
|
|
59823
60610
|
effect: "destructive",
|
|
59824
|
-
...
|
|
60611
|
+
...common4,
|
|
59825
60612
|
keywords: ["unlearn", "forget everything derived", "retract", "poisoned memory", "bad memory"],
|
|
59826
60613
|
result: withDryRun(MemoryUnlearnRecord),
|
|
59827
60614
|
handler: async (inv) => {
|
|
@@ -59841,7 +60628,7 @@ var memoryStatusCommand = defineCommand({
|
|
|
59841
60628
|
flags: [SERVICE_FLAG3, TEAM_FLAG3],
|
|
59842
60629
|
examples: ["overlane memory status", "overlane memory status --json"],
|
|
59843
60630
|
effect: "read",
|
|
59844
|
-
...
|
|
60631
|
+
...common4,
|
|
59845
60632
|
keywords: ["memory health", "stale memory", "how many memories", "contribution", "opt in"],
|
|
59846
60633
|
result: MemoryStatusResponse,
|
|
59847
60634
|
text: (d) => [...Object.entries(d.counts).map(([key, n]) => `${key}: ${n}`), `stale: ${d.stale}`, `global contribution: ${d.settings.globalContribution ? "on" : "off"}`, `pending jobs: ${d.pendingJobs}`],
|
|
@@ -59859,7 +60646,7 @@ var memoryContributionCommand = defineCommand({
|
|
|
59859
60646
|
flags: [SERVICE_FLAG3, TEAM_FLAG3],
|
|
59860
60647
|
examples: ["overlane memory contribution on", "overlane memory contribution off --dry-run"],
|
|
59861
60648
|
effect: "write",
|
|
59862
|
-
...
|
|
60649
|
+
...common4,
|
|
59863
60650
|
keywords: ["opt in", "opt out", "share patterns", "global pool", "contribute"],
|
|
59864
60651
|
result: withDryRun(MemorySettings),
|
|
59865
60652
|
handler: async (inv) => {
|
|
@@ -59879,10 +60666,10 @@ var memoryCommands = [memorySearchCommand, memoryAddCommand, memoryConfirmComman
|
|
|
59879
60666
|
// ../cli/src/commands/issue.ts
|
|
59880
60667
|
init_src();
|
|
59881
60668
|
init_zod();
|
|
59882
|
-
import { randomUUID as
|
|
60669
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
59883
60670
|
import { readFileSync as readFileSync9 } from "node:fs";
|
|
59884
|
-
var
|
|
59885
|
-
var
|
|
60671
|
+
var common5 = { needsAuth: true, needsNetwork: true };
|
|
60672
|
+
var requestId6 = () => `cli-${randomUUID6()}`;
|
|
59886
60673
|
var PRIORITIES = ["P0", "P1", "P2", "P3"];
|
|
59887
60674
|
var STATUSES = ["backlog", "todo", "in_progress", "in_review", "cancelled"];
|
|
59888
60675
|
async function send(deps, label, schema, method, path, body2, dryRun) {
|
|
@@ -59919,7 +60706,7 @@ var issueListCommand = defineCommand({
|
|
|
59919
60706
|
flags: [{ name: "status", type: "string", enum: ["backlog", "todo", "in_progress", "in_review", "done", "cancelled"], description: "Only issues in this status" }],
|
|
59920
60707
|
examples: ["overlane issue list", "overlane issue list --status todo --json"],
|
|
59921
60708
|
effect: "read",
|
|
59922
|
-
...
|
|
60709
|
+
...common5,
|
|
59923
60710
|
keywords: ["issues", "backlog", "tickets", "work items", "what is open", "list issues"],
|
|
59924
60711
|
result: external_exports.object({ issues: external_exports.array(IssueShown) }),
|
|
59925
60712
|
handler: async (inv) => {
|
|
@@ -59940,7 +60727,7 @@ var issueShowCommand = defineCommand({
|
|
|
59940
60727
|
args: [{ name: "issue-id", required: true, description: "The issue ID, for example iss_ab12cd34ef56gh78" }],
|
|
59941
60728
|
examples: ["overlane issue show iss_ab12cd34ef56gh78"],
|
|
59942
60729
|
effect: "read",
|
|
59943
|
-
...
|
|
60730
|
+
...common5,
|
|
59944
60731
|
keywords: ["issue details", "ticket", "view issue", "who is working on"],
|
|
59945
60732
|
result: IssueShown,
|
|
59946
60733
|
handler: async (inv) => {
|
|
@@ -59963,7 +60750,7 @@ var issueEventsCommand = defineCommand({
|
|
|
59963
60750
|
args: [{ name: "issue-id", required: true, description: "The issue ID" }],
|
|
59964
60751
|
examples: ["overlane issue events iss_ab12cd34ef56gh78"],
|
|
59965
60752
|
effect: "read",
|
|
59966
|
-
...
|
|
60753
|
+
...common5,
|
|
59967
60754
|
keywords: ["audit", "history", "who changed", "field changes", "issue log"],
|
|
59968
60755
|
result: IssueEventList,
|
|
59969
60756
|
handler: async (inv) => {
|
|
@@ -59988,12 +60775,12 @@ var issueNewCommand = defineCommand({
|
|
|
59988
60775
|
],
|
|
59989
60776
|
examples: ['overlane issue new "Back-time drifts by a second"', 'overlane issue new "Fix export" --priority P0 --description "Fails on empty notes"'],
|
|
59990
60777
|
effect: "write",
|
|
59991
|
-
...
|
|
60778
|
+
...common5,
|
|
59992
60779
|
keywords: ["create issue", "new issue", "file a ticket", "add work item", "report bug"],
|
|
59993
60780
|
result: withDryRun(Issue),
|
|
59994
60781
|
handler: async (inv) => {
|
|
59995
60782
|
const estimate = textFlag(inv, "estimate");
|
|
59996
|
-
const body2 = { requestId:
|
|
60783
|
+
const body2 = { requestId: requestId6(), title: inv.positionals.join(" "), description: textFlag(inv, "description") ?? "", priority: priorityFlag(inv) ?? "P1", status: textFlag(inv, "status") ?? "backlog", ...estimate === void 0 ? {} : { estimate: Number(estimate) } };
|
|
59997
60784
|
const result = await send(inv.deps, "issue", Issue, "POST", issuePaths.issues, body2, inv.dryRun);
|
|
59998
60785
|
if (result.value !== void 0) say(inv.deps, `Created #${result.value.number} ${result.value.issueId}`);
|
|
59999
60786
|
return result;
|
|
@@ -60013,7 +60800,7 @@ var issueUpdateCommand = defineCommand({
|
|
|
60013
60800
|
],
|
|
60014
60801
|
examples: ["overlane issue update iss_ab12cd34ef56gh78 --priority P0", 'overlane issue update iss_ab12cd34ef56gh78 --status in_progress --title "New title"'],
|
|
60015
60802
|
effect: "write",
|
|
60016
|
-
...
|
|
60803
|
+
...common5,
|
|
60017
60804
|
keywords: ["edit issue", "change status", "change priority", "rename issue", "update ticket"],
|
|
60018
60805
|
result: withDryRun(Issue),
|
|
60019
60806
|
handler: async (inv) => {
|
|
@@ -60021,7 +60808,7 @@ var issueUpdateCommand = defineCommand({
|
|
|
60021
60808
|
if (id2 === void 0) throw new UsageError("update needs an ISSUE_ID");
|
|
60022
60809
|
const estimate = textFlag(inv, "estimate");
|
|
60023
60810
|
const body2 = {
|
|
60024
|
-
requestId:
|
|
60811
|
+
requestId: requestId6(),
|
|
60025
60812
|
...textFlag(inv, "title") === void 0 ? {} : { title: textFlag(inv, "title") },
|
|
60026
60813
|
...textFlag(inv, "description") === void 0 ? {} : { description: textFlag(inv, "description") },
|
|
60027
60814
|
...textFlag(inv, "status") === void 0 ? {} : { status: textFlag(inv, "status") },
|
|
@@ -60042,14 +60829,14 @@ var issueAssignCommand = defineCommand({
|
|
|
60042
60829
|
],
|
|
60043
60830
|
examples: ["overlane issue assign iss_ab12cd34ef56gh78 agent:claude-code", "overlane issue assign iss_ab12cd34ef56gh78 none"],
|
|
60044
60831
|
effect: "write",
|
|
60045
|
-
...
|
|
60832
|
+
...common5,
|
|
60046
60833
|
keywords: ["assign", "give to agent", "hand to bot", "delegate", "who works on this", "unassign"],
|
|
60047
60834
|
result: withDryRun(AssignResult),
|
|
60048
60835
|
handler: async (inv) => {
|
|
60049
60836
|
const id2 = inv.positionals[0];
|
|
60050
60837
|
if (id2 === void 0) throw new UsageError("assign needs an ISSUE_ID and an assignee");
|
|
60051
60838
|
const assignee = parseAssignee(inv.positionals[1]);
|
|
60052
|
-
const result = await send(inv.deps, "issue", AssignResult, "POST", (t, p) => issuePaths.assign(t, p, id2), { requestId:
|
|
60839
|
+
const result = await send(inv.deps, "issue", AssignResult, "POST", (t, p) => issuePaths.assign(t, p, id2), { requestId: requestId6(), assignee }, inv.dryRun);
|
|
60053
60840
|
if (result.value !== void 0) say(inv.deps, result.value.taskId === null ? "Assigned." : `Assigned. Task: ${result.value.taskId}${result.value.createdTask ? " (new)" : ""}`);
|
|
60054
60841
|
return result;
|
|
60055
60842
|
}
|
|
@@ -60065,7 +60852,7 @@ var issueImportCommand = defineCommand({
|
|
|
60065
60852
|
flags: [{ name: "preview", type: "boolean", description: "Report what the import would create or update, and write nothing" }],
|
|
60066
60853
|
examples: ["overlane issue import linear ./linear-export.json --preview", "overlane issue import jira ./jira-search.json"],
|
|
60067
60854
|
effect: "write",
|
|
60068
|
-
...
|
|
60855
|
+
...common5,
|
|
60069
60856
|
keywords: ["import", "migrate from linear", "migrate from jira", "github projects import", "bring issues in"],
|
|
60070
60857
|
result: withDryRun(ImportReport),
|
|
60071
60858
|
handler: async (inv) => {
|
|
@@ -60078,7 +60865,7 @@ var issueImportCommand = defineCommand({
|
|
|
60078
60865
|
} catch {
|
|
60079
60866
|
throw new UsageError(`${file2} is not a readable JSON file`);
|
|
60080
60867
|
}
|
|
60081
|
-
const result = await send(inv.deps, "issue", ImportReport, "POST", issuePaths.import, { requestId:
|
|
60868
|
+
const result = await send(inv.deps, "issue", ImportReport, "POST", issuePaths.import, { requestId: requestId6(), source, dryRun: boolFlag(inv, "preview"), data }, inv.dryRun);
|
|
60082
60869
|
if (result.value !== void 0) {
|
|
60083
60870
|
const r = result.value;
|
|
60084
60871
|
say(inv.deps, `${r.dryRun ? "Would import" : "Imported"} from ${r.source}: ${r.created} new, ${r.updated} updated, ${r.unchanged} unchanged, ${r.skipped.length} skipped.`);
|
|
@@ -60092,7 +60879,7 @@ var issueSyncCommand = defineCommand({
|
|
|
60092
60879
|
description: "Overlane issues work with no sync; syncing with GitHub is optional. Shows the repository and mode: off (default), read_only (GitHub changes flow in, nothing is written to GitHub) or write_back (an owner or admin opted in).",
|
|
60093
60880
|
examples: ["overlane issue sync"],
|
|
60094
60881
|
effect: "read",
|
|
60095
|
-
...
|
|
60882
|
+
...common5,
|
|
60096
60883
|
keywords: ["github sync", "sync status", "two-way sync", "write back"],
|
|
60097
60884
|
result: SyncConfig,
|
|
60098
60885
|
handler: async (inv) => {
|
|
@@ -60112,13 +60899,13 @@ var issueSyncSetCommand = defineCommand({
|
|
|
60112
60899
|
],
|
|
60113
60900
|
examples: ["overlane issue sync set acme/app read_only", "overlane issue sync set acme/app off"],
|
|
60114
60901
|
effect: "write",
|
|
60115
|
-
...
|
|
60902
|
+
...common5,
|
|
60116
60903
|
keywords: ["enable github sync", "write back", "turn off sync", "read only sync"],
|
|
60117
60904
|
result: withDryRun(SyncConfig),
|
|
60118
60905
|
handler: async (inv) => {
|
|
60119
60906
|
const [repository, mode] = inv.positionals;
|
|
60120
60907
|
if (repository === void 0 || mode === void 0) throw new UsageError("sync set needs REPOSITORY and MODE");
|
|
60121
|
-
return send(inv.deps, "issue", SyncConfig, "PUT", issuePaths.sync, { requestId:
|
|
60908
|
+
return send(inv.deps, "issue", SyncConfig, "PUT", issuePaths.sync, { requestId: requestId6(), repository, mode }, inv.dryRun);
|
|
60122
60909
|
}
|
|
60123
60910
|
});
|
|
60124
60911
|
var issueCommands = [issueListCommand, issueShowCommand, issueEventsCommand, issueNewCommand, issueUpdateCommand, issueAssignCommand, issueImportCommand, issueSyncCommand, issueSyncSetCommand];
|
|
@@ -60126,7 +60913,7 @@ var issueCommands = [issueListCommand, issueShowCommand, issueEventsCommand, iss
|
|
|
60126
60913
|
// ../cli/src/commands/issue-views.ts
|
|
60127
60914
|
init_src();
|
|
60128
60915
|
init_zod();
|
|
60129
|
-
var
|
|
60916
|
+
var common6 = { needsAuth: true, needsNetwork: true };
|
|
60130
60917
|
var Deleted = external_exports.object({ deleted: external_exports.literal(true) });
|
|
60131
60918
|
var FIELDS = ["status", "priority", "assigneeType", "assignee", "labelId", "workProjectId", "cycleId", "estimate", "source", "title", "number", "createdAt", "updatedAt"];
|
|
60132
60919
|
function parseCondition(text) {
|
|
@@ -60142,7 +60929,7 @@ var viewListCommand = defineCommand({
|
|
|
60142
60929
|
description: "Lists saved views: a filter plus a group-by and sort over any issue field.",
|
|
60143
60930
|
examples: ["overlane view list"],
|
|
60144
60931
|
effect: "read",
|
|
60145
|
-
...
|
|
60932
|
+
...common6,
|
|
60146
60933
|
keywords: ["saved views", "filters", "board", "group by"],
|
|
60147
60934
|
result: ViewList,
|
|
60148
60935
|
handler: async (inv) => {
|
|
@@ -60160,7 +60947,7 @@ var viewRunCommand = defineCommand({
|
|
|
60160
60947
|
args: [{ name: "view-id", required: true, description: "The saved view ID" }],
|
|
60161
60948
|
examples: ["overlane view run viw_ab12cd34ef56gh78"],
|
|
60162
60949
|
effect: "read",
|
|
60163
|
-
...
|
|
60950
|
+
...common6,
|
|
60164
60951
|
keywords: ["run view", "show board", "group issues"],
|
|
60165
60952
|
result: ViewResult,
|
|
60166
60953
|
handler: async (inv) => {
|
|
@@ -60188,12 +60975,12 @@ var viewNewCommand = defineCommand({
|
|
|
60188
60975
|
],
|
|
60189
60976
|
examples: ["overlane view new Urgent --filter priority=P0 --group-by status", 'overlane view new "Agent work" --filter assigneeType=agent --group-by status'],
|
|
60190
60977
|
effect: "write",
|
|
60191
|
-
...
|
|
60978
|
+
...common6,
|
|
60192
60979
|
keywords: ["create view", "save filter", "board", "group by status"],
|
|
60193
60980
|
result: withDryRun(SavedView),
|
|
60194
60981
|
handler: async (inv) => {
|
|
60195
60982
|
const definition = { filter: listFlag(inv, "filter").map(parseCondition), groupBy: textFlag(inv, "group-by") ?? null, sortBy: textFlag(inv, "sort-by") ?? "number", sortDirection: boolFlag(inv, "desc") ? "desc" : "asc" };
|
|
60196
|
-
return send(inv.deps, "view", SavedView, "POST", issuePaths.views, { requestId:
|
|
60983
|
+
return send(inv.deps, "view", SavedView, "POST", issuePaths.views, { requestId: requestId6(), name: inv.positionals.join(" "), definition }, inv.dryRun);
|
|
60197
60984
|
}
|
|
60198
60985
|
});
|
|
60199
60986
|
var viewDeleteCommand = defineCommand({
|
|
@@ -60203,7 +60990,7 @@ var viewDeleteCommand = defineCommand({
|
|
|
60203
60990
|
args: [{ name: "view-id", required: false, description: "The saved view ID (required; checked after the --force confirmation)" }],
|
|
60204
60991
|
examples: ["overlane view delete viw_ab12cd34ef56gh78 --force"],
|
|
60205
60992
|
effect: "destructive",
|
|
60206
|
-
...
|
|
60993
|
+
...common6,
|
|
60207
60994
|
keywords: ["remove view", "delete filter"],
|
|
60208
60995
|
result: withDryRun(Deleted),
|
|
60209
60996
|
handler: async (inv) => {
|
|
@@ -60218,7 +61005,7 @@ var loopListCommand = defineCommand({
|
|
|
60218
61005
|
description: "Lists loops: a trigger (schedule or event), a filter over issues and the executor they dispatch.",
|
|
60219
61006
|
examples: ["overlane loop list"],
|
|
60220
61007
|
effect: "read",
|
|
60221
|
-
...
|
|
61008
|
+
...common6,
|
|
60222
61009
|
keywords: ["loops", "scheduled work", "recurring", "automation"],
|
|
60223
61010
|
result: LoopList,
|
|
60224
61011
|
handler: async (inv) => {
|
|
@@ -60242,7 +61029,7 @@ var loopNewCommand = defineCommand({
|
|
|
60242
61029
|
],
|
|
60243
61030
|
examples: ["overlane loop new Nightly --every 1440 --filter priority=P0", "overlane loop new OnAssign --on issue.assigned"],
|
|
60244
61031
|
effect: "write",
|
|
60245
|
-
...
|
|
61032
|
+
...common6,
|
|
60246
61033
|
keywords: ["schedule agent", "recurring work", "event trigger", "automation", "nightly"],
|
|
60247
61034
|
result: withDryRun(LoopDefinition),
|
|
60248
61035
|
handler: async (inv) => {
|
|
@@ -60250,7 +61037,7 @@ var loopNewCommand = defineCommand({
|
|
|
60250
61037
|
const on = textFlag(inv, "on");
|
|
60251
61038
|
if (every === void 0 === (on === void 0)) throw new UsageError("pass exactly one of --every MINUTES or --on EVENT");
|
|
60252
61039
|
const trigger = every !== void 0 ? { kind: "schedule", everyMinutes: Number(every) } : { kind: "event", on };
|
|
60253
|
-
return send(inv.deps, "loop", LoopDefinition, "POST", issuePaths.loops, { requestId:
|
|
61040
|
+
return send(inv.deps, "loop", LoopDefinition, "POST", issuePaths.loops, { requestId: requestId6(), name: inv.positionals.join(" "), trigger, filter: listFlag(inv, "filter").map(parseCondition), executor: textFlag(inv, "executor") ?? "claude-code" }, inv.dryRun);
|
|
60254
61041
|
}
|
|
60255
61042
|
});
|
|
60256
61043
|
var loopSetCommand = defineCommand({
|
|
@@ -60263,13 +61050,13 @@ var loopSetCommand = defineCommand({
|
|
|
60263
61050
|
],
|
|
60264
61051
|
examples: ["overlane loop set lop_ab12cd34ef56gh78 off"],
|
|
60265
61052
|
effect: "write",
|
|
60266
|
-
...
|
|
61053
|
+
...common6,
|
|
60267
61054
|
keywords: ["disable loop", "enable loop", "stop schedule"],
|
|
60268
61055
|
result: withDryRun(LoopDefinition),
|
|
60269
61056
|
handler: async (inv) => {
|
|
60270
61057
|
const [id2, state] = inv.positionals;
|
|
60271
61058
|
if (id2 === void 0 || state !== "on" && state !== "off") throw new UsageError("set needs a LOOP_ID and on or off");
|
|
60272
|
-
return send(inv.deps, "loop", LoopDefinition, "PATCH", (t, p) => issuePaths.loop(t, p, id2), { requestId:
|
|
61059
|
+
return send(inv.deps, "loop", LoopDefinition, "PATCH", (t, p) => issuePaths.loop(t, p, id2), { requestId: requestId6(), enabled: state === "on" }, inv.dryRun);
|
|
60273
61060
|
}
|
|
60274
61061
|
});
|
|
60275
61062
|
var loopFireCommand = defineCommand({
|
|
@@ -60279,13 +61066,13 @@ var loopFireCommand = defineCommand({
|
|
|
60279
61066
|
args: [{ name: "loop-id", required: true, description: "The loop ID" }],
|
|
60280
61067
|
examples: ["overlane loop fire lop_ab12cd34ef56gh78"],
|
|
60281
61068
|
effect: "write",
|
|
60282
|
-
...
|
|
61069
|
+
...common6,
|
|
60283
61070
|
keywords: ["run loop", "trigger loop", "dispatch agent"],
|
|
60284
61071
|
result: withDryRun(LoopRun),
|
|
60285
61072
|
handler: async (inv) => {
|
|
60286
61073
|
const id2 = inv.positionals[0];
|
|
60287
61074
|
if (id2 === void 0) throw new UsageError("fire needs a LOOP_ID");
|
|
60288
|
-
const result = await send(inv.deps, "loop", LoopRun, "POST", (t, p) => issuePaths.loopFire(t, p, id2), { requestId:
|
|
61075
|
+
const result = await send(inv.deps, "loop", LoopRun, "POST", (t, p) => issuePaths.loopFire(t, p, id2), { requestId: requestId6(), trigger: "schedule" }, inv.dryRun);
|
|
60289
61076
|
if (result.value !== void 0) say(inv.deps, `Loop run ${result.value.runId ?? "(none)"}: ${result.value.claimed.length} claimed, stopped: ${result.value.stopReason}.`);
|
|
60290
61077
|
return result;
|
|
60291
61078
|
}
|
|
@@ -60297,7 +61084,7 @@ var loopDeleteCommand = defineCommand({
|
|
|
60297
61084
|
args: [{ name: "loop-id", required: false, description: "The loop ID (required; checked after the --force confirmation)" }],
|
|
60298
61085
|
examples: ["overlane loop delete lop_ab12cd34ef56gh78 --force"],
|
|
60299
61086
|
effect: "destructive",
|
|
60300
|
-
...
|
|
61087
|
+
...common6,
|
|
60301
61088
|
keywords: ["remove loop", "delete schedule"],
|
|
60302
61089
|
result: withDryRun(Deleted),
|
|
60303
61090
|
handler: async (inv) => {
|
|
@@ -60311,14 +61098,15 @@ var loopCommands = [loopListCommand, loopNewCommand, loopSetCommand, loopFireCom
|
|
|
60311
61098
|
|
|
60312
61099
|
// ../cli/src/commands/review.ts
|
|
60313
61100
|
init_src();
|
|
60314
|
-
import { randomUUID as
|
|
60315
|
-
|
|
60316
|
-
var
|
|
60317
|
-
|
|
61101
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
61102
|
+
import { resolve as resolve9 } from "node:path";
|
|
61103
|
+
var common7 = { needsAuth: true, needsNetwork: true };
|
|
61104
|
+
var requestId7 = () => `cli-${randomUUID7()}`;
|
|
61105
|
+
async function connected3(inv) {
|
|
60318
61106
|
const project = await connectedProject(inv.deps, "review");
|
|
60319
61107
|
return { project, call: serviceCall(inv.deps, project.serviceUrl, project.token), tenantId: project.binding.tenantId, projectId: project.binding.projectId };
|
|
60320
61108
|
}
|
|
60321
|
-
async function
|
|
61109
|
+
async function planned3(inv, method, path, body2, note) {
|
|
60322
61110
|
const project = await offlineProject(inv.deps, "review");
|
|
60323
61111
|
return planOutcome(inv.deps, dryRunPlan({ service: project.serviceUrl, requests: [{ method, path: path(project.binding.tenantId, project.binding.projectId), ...body2 === void 0 ? {} : { body: body2 }, ...note === void 0 ? {} : { note } }] }));
|
|
60324
61112
|
}
|
|
@@ -60330,9 +61118,38 @@ async function repositoryOf(inv) {
|
|
|
60330
61118
|
}
|
|
60331
61119
|
const remote = await inv.deps.exec("git", ["remote", "get-url", "origin"], { cwd: inv.deps.paths.cwd });
|
|
60332
61120
|
const match = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?\s*$/.exec(remote.stdout.trim());
|
|
60333
|
-
if (remote.code !== 0 || match === null) throw new UsageError("could not read
|
|
61121
|
+
if (remote.code !== 0 || match === null) throw new UsageError("could not read a GitHub repository from the origin remote; to review a change without one, give the diff", { hint: "overlane review run --diff change.patch" });
|
|
60334
61122
|
return `${match[1]}/${match[2]}`;
|
|
60335
61123
|
}
|
|
61124
|
+
async function diffOf(inv) {
|
|
61125
|
+
const flag = textFlag(inv, "diff");
|
|
61126
|
+
const pull = inv.positionals[0];
|
|
61127
|
+
if (flag !== void 0 && pull !== void 0) throw new UsageError("give a pull request number or --diff, not both", { hint: "overlane review run --diff change.patch" });
|
|
61128
|
+
let from;
|
|
61129
|
+
let text;
|
|
61130
|
+
if (flag !== void 0) {
|
|
61131
|
+
if (flag === "-") {
|
|
61132
|
+
if (inv.deps.stdin === void 0) throw new UsageError("--diff - reads standard input, which is not available here", { hint: "overlane review run --diff change.patch" });
|
|
61133
|
+
from = "standard input";
|
|
61134
|
+
text = await inv.deps.stdin.read();
|
|
61135
|
+
} else {
|
|
61136
|
+
from = flag;
|
|
61137
|
+
text = readText(resolve9(inv.deps.paths.cwd, flag));
|
|
61138
|
+
if (text === null) throw new UsageError(`could not read the diff file ${flag}`, { hint: "git diff > change.patch && overlane review run --diff change.patch" });
|
|
61139
|
+
}
|
|
61140
|
+
} else if (pull === void 0) {
|
|
61141
|
+
if (inv.deps.stdin === void 0 || inv.deps.stdin.isTTY) {
|
|
61142
|
+
throw new UsageError("nothing to review: give a diff (--diff change.patch, or pipe one in) or a pull request number", { hint: "overlane review run --diff change.patch" });
|
|
61143
|
+
}
|
|
61144
|
+
from = "standard input";
|
|
61145
|
+
text = await inv.deps.stdin.read();
|
|
61146
|
+
} else {
|
|
61147
|
+
return void 0;
|
|
61148
|
+
}
|
|
61149
|
+
if (text.trim().length === 0) throw new UsageError(`the diff from ${from} is empty: there is nothing to review`, { hint: "git diff > change.patch && overlane review run --diff change.patch" });
|
|
61150
|
+
if (text.length > MAX_PATCH_BYTES) throw new UsageError(`the diff is larger than ${MAX_PATCH_BYTES} characters; review it in parts`);
|
|
61151
|
+
return { text, from };
|
|
61152
|
+
}
|
|
60336
61153
|
function id(inv, what) {
|
|
60337
61154
|
const value = inv.positionals[0];
|
|
60338
61155
|
if (value === void 0) throw new UsageError(`${what} needs a finding ID`, { hint: "overlane review findings" });
|
|
@@ -60341,23 +61158,40 @@ function id(inv, what) {
|
|
|
60341
61158
|
var FINDING_LINE = (finding) => `${finding.status.padEnd(9)} ${finding.severity.padEnd(8)} ${finding.path}:${finding.line} ${finding.rule ?? "see reason"} ${finding.id}`;
|
|
60342
61159
|
var reviewRunCommand = defineCommand({
|
|
60343
61160
|
path: ["review", "run"],
|
|
60344
|
-
summary: "Review a
|
|
60345
|
-
description: "Runs the review service
|
|
60346
|
-
args: [{ name: "pull", required:
|
|
60347
|
-
flags: [
|
|
60348
|
-
|
|
61161
|
+
summary: "Review a diff (no repository needed) or a pull request now and report the findings",
|
|
61162
|
+
description: "Runs the review service. The native way is a diff: `--diff change.patch`, or `--diff -` (or a pipe) to read it from standard input; it needs no repository and no GitHub account, and it is log-only. A pull request number reviews a pull request instead (native pull requests arrive with Overlane git; a GitHub one needs the GitHub connection and the App's pull-request access, otherwise the command says the live leg is pending). Deterministic checks (secret scan, static rules, diff validation) run first and alone when no model is available; a model pass is an optional second pass under the per-PR token cap. Until the project owner enables comments (`overlane review settings set --mode comments`) a pull request run is log-only and posts nothing. Diff text and code are data, never instructions.",
|
|
61163
|
+
args: [{ name: "pull", required: false, description: "A pull request number (omit it to review a diff)" }],
|
|
61164
|
+
flags: [
|
|
61165
|
+
{ name: "diff", type: "string", value: "FILE", description: "Review this unified diff (a file, or - for standard input); needs no repository" },
|
|
61166
|
+
{ name: "title", type: "string", value: "TEXT", description: "A title for the diff, shown in the summary" },
|
|
61167
|
+
{ name: "label", type: "string", value: "NAME", description: "Names the diff so a re-review of the same change merges its findings (default: patch)" },
|
|
61168
|
+
{ name: "repo", type: "string", value: "OWNER/NAME", description: "For a pull request number: the GitHub repository (default: the origin remote); not used with --diff" }
|
|
61169
|
+
],
|
|
61170
|
+
examples: ["overlane review run --diff change.patch", "overlane review run --diff -", "overlane review run 7 --repo acme/app --dry-run"],
|
|
60349
61171
|
effect: "write",
|
|
60350
|
-
...
|
|
60351
|
-
keywords: ["code review", "review
|
|
61172
|
+
...common7,
|
|
61173
|
+
keywords: ["code review", "review diff", "review patch", "review pull request", "review pr", "check my pr", "findings"],
|
|
60352
61174
|
result: withDryRun(ReviewRunResponse),
|
|
60353
61175
|
text: (d) => "run" in d ? [`${d.run.status} review of ${d.run.repository}#${d.run.pullNumber} (${d.run.mode}${d.run.posted ? ", posted" : ", nothing posted"}): ${d.run.findings.open} open, ${d.run.findings.fixed} fixed, ${d.run.findings.dismissed} dismissed.`, ...d.findings.filter((finding) => finding.status === "open").map(FINDING_LINE)] : [],
|
|
60354
61176
|
handler: async (inv) => {
|
|
61177
|
+
const diff = await diffOf(inv);
|
|
61178
|
+
if (diff !== void 0) {
|
|
61179
|
+
const title = textFlag(inv, "title");
|
|
61180
|
+
const label = textFlag(inv, "label");
|
|
61181
|
+
const source = { kind: "patch", diff: diff.text, ...title === void 0 ? {} : { title }, ...label === void 0 ? {} : { label } };
|
|
61182
|
+
const patchBody = { requestId: requestId7(), trigger: "manual", source };
|
|
61183
|
+
if (inv.dryRun) return planned3(inv, "POST", reviewPaths.runs, { ...patchBody, source: { ...source, diff: `<${diff.text.length} characters from ${diff.from}>` } }, "runs the deterministic checks on the diff, then an optional model pass; nothing is posted");
|
|
61184
|
+
const sent = await connected3(inv);
|
|
61185
|
+
const patched = await sent.call(ReviewRunResponse, "POST", reviewPaths.runs(sent.tenantId, sent.projectId), patchBody);
|
|
61186
|
+
if (patched.run.status === "partial") say(inv.deps, "Partial review: the token cap was reached. The summary lists what was not covered.");
|
|
61187
|
+
return { data: patched };
|
|
61188
|
+
}
|
|
60355
61189
|
const number4 = Number(inv.positionals[0]);
|
|
60356
|
-
if (!Number.isInteger(number4) || number4 < 1) throw new UsageError("run needs a pull request number", { hint: "overlane review run
|
|
61190
|
+
if (!Number.isInteger(number4) || number4 < 1) throw new UsageError("run needs a pull request number, or a diff with --diff", { hint: "overlane review run --diff change.patch" });
|
|
60357
61191
|
const repository = await repositoryOf(inv);
|
|
60358
|
-
const body2 = { requestId:
|
|
60359
|
-
if (inv.dryRun) return
|
|
60360
|
-
const { call: call2, tenantId, projectId } = await
|
|
61192
|
+
const body2 = { requestId: requestId7(), trigger: "manual", source: { kind: "github", repository, number: number4 } };
|
|
61193
|
+
if (inv.dryRun) return planned3(inv, "POST", reviewPaths.runs, body2, "reads the pull request through the GitHub connection and runs the review");
|
|
61194
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60361
61195
|
const result = await call2(ReviewRunResponse, "POST", reviewPaths.runs(tenantId, projectId), body2);
|
|
60362
61196
|
if (result.run.status === "partial") say(inv.deps, "Partial review: the token cap was reached. The summary lists what was not covered.");
|
|
60363
61197
|
return { data: result };
|
|
@@ -60369,12 +61203,12 @@ var reviewStatusCommand = defineCommand({
|
|
|
60369
61203
|
description: "Shows whether review posts comments or is log-only, the token cap, the latest runs and the number of open findings. States the data-use terms: diffs go to model providers only under terms that exclude training.",
|
|
60370
61204
|
examples: ["overlane review status", "overlane review status --json"],
|
|
60371
61205
|
effect: "read",
|
|
60372
|
-
...
|
|
61206
|
+
...common7,
|
|
60373
61207
|
keywords: ["review mode", "log only", "review settings", "recent reviews", "how is review doing"],
|
|
60374
61208
|
result: ReviewStatusResponse,
|
|
60375
61209
|
text: (d) => [`Review mode: ${d.settings.mode}. Token cap per pull request: ${d.settings.tokenCap}. Open findings: ${d.openFindings}.`, d.settings.privacy, ...d.runs.slice(0, 5).map((run3) => `${run3.startedAt} ${run3.repository}#${run3.pullNumber} ${run3.status} ${run3.tokensUsed} tokens ${run3.model}`)],
|
|
60376
61210
|
handler: async (inv) => {
|
|
60377
|
-
const { call: call2, tenantId, projectId } = await
|
|
61211
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60378
61212
|
return { data: await call2(ReviewStatusResponse, "GET", reviewPaths.status(tenantId, projectId)) };
|
|
60379
61213
|
}
|
|
60380
61214
|
});
|
|
@@ -60389,12 +61223,12 @@ var reviewFindingsCommand = defineCommand({
|
|
|
60389
61223
|
],
|
|
60390
61224
|
examples: ["overlane review findings --status open", "overlane review findings --pull 7 --json"],
|
|
60391
61225
|
effect: "read",
|
|
60392
|
-
...
|
|
61226
|
+
...common7,
|
|
60393
61227
|
keywords: ["list findings", "open comments", "review comments", "what did review find", "defects"],
|
|
60394
61228
|
result: ReviewFindingsResponse,
|
|
60395
61229
|
text: (d) => d.findings.length === 0 ? ["No findings."] : d.findings.map(FINDING_LINE),
|
|
60396
61230
|
handler: async (inv) => {
|
|
60397
|
-
const { call: call2, tenantId, projectId } = await
|
|
61231
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60398
61232
|
const params = new URLSearchParams();
|
|
60399
61233
|
for (const name2 of ["pull", "repo", "status"]) {
|
|
60400
61234
|
const value = textFlag(inv, name2);
|
|
@@ -60415,16 +61249,16 @@ var reviewDismissCommand = defineCommand({
|
|
|
60415
61249
|
],
|
|
60416
61250
|
examples: ['overlane review dismiss fnd_1 --note "intended"', "overlane review dismiss fnd_2 --accept"],
|
|
60417
61251
|
effect: "write",
|
|
60418
|
-
...
|
|
61252
|
+
...common7,
|
|
60419
61253
|
keywords: ["dismiss finding", "ignore comment", "false positive", "accept finding", "teach reviewer", "feedback"],
|
|
60420
61254
|
result: withDryRun(FeedbackResponse),
|
|
60421
61255
|
text: (d) => "finding" in d ? [`${d.finding.id} is ${d.finding.status}.${d.learned === null ? "" : ` Learned: ${d.learned.direction} ${d.learned.rule} (${d.learned.evidence} reviews).`}`] : [],
|
|
60422
61256
|
handler: async (inv) => {
|
|
60423
61257
|
const findingId = id(inv, "dismiss");
|
|
60424
61258
|
const note = textFlag(inv, "note");
|
|
60425
|
-
const body2 = { kind: inv.values["accept"] === true ? "accept" : "dismiss", ...note === void 0 ? {} : { note }, requestId:
|
|
60426
|
-
if (inv.dryRun) return
|
|
60427
|
-
const { call: call2, tenantId, projectId } = await
|
|
61259
|
+
const body2 = { kind: inv.values["accept"] === true ? "accept" : "dismiss", ...note === void 0 ? {} : { note }, requestId: requestId7() };
|
|
61260
|
+
if (inv.dryRun) return planned3(inv, "POST", (tenantId2, projectId2) => reviewPaths.feedback(tenantId2, projectId2, findingId), body2);
|
|
61261
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60428
61262
|
return { data: await call2(FeedbackResponse, "POST", reviewPaths.feedback(tenantId, projectId, findingId), body2) };
|
|
60429
61263
|
}
|
|
60430
61264
|
});
|
|
@@ -60436,16 +61270,16 @@ var reviewAutofixCommand = defineCommand({
|
|
|
60436
61270
|
flags: [{ name: "assign", type: "string", value: "AGENT", description: "The agent or bot to assign, for example agent:fixer" }],
|
|
60437
61271
|
examples: ["overlane review autofix fnd_1", "overlane review autofix fnd_1 --assign agent:fixer --dry-run"],
|
|
60438
61272
|
effect: "write",
|
|
60439
|
-
...
|
|
61273
|
+
...common7,
|
|
60440
61274
|
keywords: ["auto fix", "autofix", "fix finding", "create task from finding", "assign to agent"],
|
|
60441
61275
|
result: withDryRun(AutofixResponse),
|
|
60442
61276
|
text: (d) => "taskId" in d ? [`Task ${d.taskId} created${d.assignee === null ? "" : ` for ${d.assignee}`}. Start it with: overlane task start ${d.taskId}`] : [],
|
|
60443
61277
|
handler: async (inv) => {
|
|
60444
61278
|
const findingId = id(inv, "autofix");
|
|
60445
61279
|
const assignee = textFlag(inv, "assign");
|
|
60446
|
-
const body2 = { requestId:
|
|
60447
|
-
if (inv.dryRun) return
|
|
60448
|
-
const { call: call2, tenantId, projectId } = await
|
|
61280
|
+
const body2 = { requestId: requestId7(), ...assignee === void 0 ? {} : { assignee } };
|
|
61281
|
+
if (inv.dryRun) return planned3(inv, "POST", (tenantId2, projectId2) => reviewPaths.autofix(tenantId2, projectId2, findingId), body2);
|
|
61282
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60449
61283
|
return { data: await call2(AutofixResponse, "POST", reviewPaths.autofix(tenantId, projectId, findingId), body2) };
|
|
60450
61284
|
}
|
|
60451
61285
|
});
|
|
@@ -60455,19 +61289,19 @@ var reviewSettingsCommand = defineCommand({
|
|
|
60455
61289
|
description: "Shows the mode (log-only until comments are enabled), the per-PR token cap, extra skip patterns and the statement that diffs go to model providers only under terms that exclude training.",
|
|
60456
61290
|
examples: ["overlane review settings"],
|
|
60457
61291
|
effect: "read",
|
|
60458
|
-
...
|
|
61292
|
+
...common7,
|
|
60459
61293
|
keywords: ["review configuration", "token cap", "skip patterns", "privacy", "no training", "data use"],
|
|
60460
61294
|
result: ReviewSettings,
|
|
60461
61295
|
text: (d) => [`Mode: ${d.mode}. Token cap: ${d.tokenCap}. Extra skip patterns: ${d.skipPatterns.length === 0 ? "none" : d.skipPatterns.join(", ")}.`, d.privacy],
|
|
60462
61296
|
handler: async (inv) => {
|
|
60463
|
-
const { call: call2, tenantId, projectId } = await
|
|
61297
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60464
61298
|
return { data: await call2(ReviewSettings, "GET", reviewPaths.settings(tenantId, projectId)) };
|
|
60465
61299
|
}
|
|
60466
61300
|
});
|
|
60467
61301
|
var reviewSettingsSetCommand = defineCommand({
|
|
60468
61302
|
path: ["review", "settings", "set"],
|
|
60469
61303
|
summary: "Change the review mode, token cap or skip patterns",
|
|
60470
|
-
description: "Sets how review behaves for the project. Enabling comments (`--mode comments`) lets review post inline comments and the summary on GitHub; it is log-only until then. An agent or a person can change them; a read-only viewer cannot.",
|
|
61304
|
+
description: "Sets how review behaves for the project. Enabling comments (`--mode comments`) lets review post inline comments and the summary on the pull request (GitHub today; native pull requests with Overlane git); it is log-only until then. A diff review never posts. An agent or a person can change them; a read-only viewer cannot.",
|
|
60471
61305
|
flags: [
|
|
60472
61306
|
{ name: "mode", type: "string", enum: ["log_only", "comments"], description: "log_only records findings only; comments posts them" },
|
|
60473
61307
|
{ name: "token-cap", type: "string", value: "N", description: "Most tokens one pull request may use (1,000 to 2,000,000)" },
|
|
@@ -60475,7 +61309,7 @@ var reviewSettingsSetCommand = defineCommand({
|
|
|
60475
61309
|
],
|
|
60476
61310
|
examples: ["overlane review settings set --mode comments", "overlane review settings set --token-cap 40000 --skip 'docs/**' --dry-run"],
|
|
60477
61311
|
effect: "write",
|
|
60478
|
-
...
|
|
61312
|
+
...common7,
|
|
60479
61313
|
keywords: ["enable review comments", "turn on review", "log only", "set token cap", "skip files"],
|
|
60480
61314
|
result: withDryRun(ReviewSettings),
|
|
60481
61315
|
text: (d) => "mode" in d ? [`Review is ${d.mode}. Token cap ${d.tokenCap}.`] : [],
|
|
@@ -60489,8 +61323,8 @@ var reviewSettingsSetCommand = defineCommand({
|
|
|
60489
61323
|
});
|
|
60490
61324
|
if (!parsed.success) throw new UsageError(parsed.error.issues.map((issue2) => issue2.message).join("; "), { hint: "overlane review settings set --mode comments" });
|
|
60491
61325
|
if (Object.keys(parsed.data).length === 0) throw new UsageError("nothing to change", { hint: "overlane review settings set --mode comments" });
|
|
60492
|
-
if (inv.dryRun) return
|
|
60493
|
-
const { call: call2, tenantId, projectId } = await
|
|
61326
|
+
if (inv.dryRun) return planned3(inv, "PUT", reviewPaths.settings, parsed.data);
|
|
61327
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60494
61328
|
return { data: await call2(ReviewSettings, "PUT", reviewPaths.settings(tenantId, projectId), parsed.data) };
|
|
60495
61329
|
}
|
|
60496
61330
|
});
|
|
@@ -60500,12 +61334,12 @@ var codeMapStatusCommand = defineCommand({
|
|
|
60500
61334
|
description: "Lists every supported client in its local and cloud setting, and the bots, review service, cross-repository questions and wiki, with whether the code map is on and the reason. The default for a setting follows the latest GATE-07 result for that setting: off for a local agent with grep (the local run failed, ADR 0018), on where there is no checkout until a re-run says otherwise.",
|
|
60501
61335
|
examples: ["overlane code-map status", "overlane code-map status --json"],
|
|
60502
61336
|
effect: "read",
|
|
60503
|
-
...
|
|
61337
|
+
...common7,
|
|
60504
61338
|
keywords: ["code map", "code tools", "is the code map on", "gate-07", "code layer", "per client"],
|
|
60505
61339
|
result: CodeMapStatus,
|
|
60506
61340
|
text: (d) => d.clients.map((row) => `${row.on ? "on " : "off"} ${row.subject}: ${row.reason}`),
|
|
60507
61341
|
handler: async (inv) => {
|
|
60508
|
-
const { call: call2, tenantId, projectId } = await
|
|
61342
|
+
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
60509
61343
|
return { data: await call2(CodeMapStatus, "GET", codeMapPaths.status(tenantId, projectId)) };
|
|
60510
61344
|
}
|
|
60511
61345
|
});
|
|
@@ -60553,7 +61387,7 @@ function rootHelp(specs, version2) {
|
|
|
60553
61387
|
const lines = [
|
|
60554
61388
|
ROOT_FIRST_LINE,
|
|
60555
61389
|
"",
|
|
60556
|
-
`overlane${version2 === "" ? "" : ` ${version2}`} - connect a
|
|
61390
|
+
`overlane${version2 === "" ? "" : ` ${version2}`} - connect a project to Overlane (no GitHub account needed), and run its tasks`,
|
|
60557
61391
|
"",
|
|
60558
61392
|
"Usage: overlane <command> [flags] overlane <command> --help overlane schema <command>",
|
|
60559
61393
|
"",
|
|
@@ -60864,7 +61698,7 @@ init_zod();
|
|
|
60864
61698
|
// ../cli/src/connect-result.ts
|
|
60865
61699
|
init_zod();
|
|
60866
61700
|
var ConnectResult = external_exports.object({
|
|
60867
|
-
project: external_exports.object({ owner: external_exports.string(), name: external_exports.string(), root: external_exports.string() }),
|
|
61701
|
+
project: external_exports.object({ provider: external_exports.enum(["overlane", "github", "gitlab"]).optional(), owner: external_exports.string().optional(), name: external_exports.string(), root: external_exports.string() }),
|
|
60868
61702
|
serviceUrl: external_exports.string(),
|
|
60869
61703
|
tenantId: external_exports.string().optional(),
|
|
60870
61704
|
projectId: external_exports.string().optional(),
|
|
@@ -61009,10 +61843,10 @@ async function disconnect(deps, options) {
|
|
|
61009
61843
|
}
|
|
61010
61844
|
|
|
61011
61845
|
// ../cli/src/doctor.ts
|
|
61012
|
-
import { resolve as
|
|
61846
|
+
import { resolve as resolve10 } from "node:path";
|
|
61013
61847
|
init_zod();
|
|
61014
61848
|
var DoctorResult = external_exports.object({
|
|
61015
|
-
project: external_exports.object({ owner: external_exports.string(), name: external_exports.string(), root: external_exports.string() }),
|
|
61849
|
+
project: external_exports.object({ provider: external_exports.enum(["overlane", "github", "gitlab"]).optional(), owner: external_exports.string().optional(), name: external_exports.string(), root: external_exports.string() }),
|
|
61016
61850
|
binding: external_exports.enum(["ok", "missing", "invalid"]),
|
|
61017
61851
|
service: external_exports.string().optional(),
|
|
61018
61852
|
credentials: external_exports.string().optional(),
|
|
@@ -61029,13 +61863,13 @@ async function doctor(deps, options) {
|
|
|
61029
61863
|
const root = project.root;
|
|
61030
61864
|
const binding = readBindingFile(root);
|
|
61031
61865
|
const owned = readOwned(root);
|
|
61032
|
-
const marketplaceRoot2 =
|
|
61866
|
+
const marketplaceRoot2 = resolve10(options.marketplaceRoot ?? owned?.marketplaceRoot ?? deps.paths.defaultMarketplaceRoot);
|
|
61033
61867
|
const infos = await detectAgents(deps, options.agents, root);
|
|
61034
61868
|
let service = "reachable";
|
|
61035
61869
|
let hasToken = false;
|
|
61036
61870
|
let credentials;
|
|
61037
61871
|
let checked2 = false;
|
|
61038
|
-
say(deps, `Project: ${project
|
|
61872
|
+
say(deps, `Project: ${projectLabel(project)} at ${root}`);
|
|
61039
61873
|
if (binding.kind === "ok") {
|
|
61040
61874
|
const { serviceUrl } = binding.binding;
|
|
61041
61875
|
const token = await findToken(deps, serviceUrl);
|
|
@@ -61059,7 +61893,7 @@ async function doctor(deps, options) {
|
|
|
61059
61893
|
const installedStates = reports.filter((report2, index) => infos[index]?.installed === true).map((report2) => report2.state);
|
|
61060
61894
|
const ready = installedStates.length > 0 && installedStates.every((state) => state === "ready");
|
|
61061
61895
|
const data = {
|
|
61062
|
-
project:
|
|
61896
|
+
project: projectSummary(project),
|
|
61063
61897
|
binding: binding.kind,
|
|
61064
61898
|
...binding.kind === "ok" ? { service: binding.binding.serviceUrl } : {},
|
|
61065
61899
|
...credentials === void 0 ? {} : { credentials },
|
|
@@ -61089,7 +61923,7 @@ async function doctor(deps, options) {
|
|
|
61089
61923
|
|
|
61090
61924
|
// ../cli/src/kit/setup.ts
|
|
61091
61925
|
init_src();
|
|
61092
|
-
import { randomUUID as
|
|
61926
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
61093
61927
|
import { existsSync as existsSync6, readdirSync as readdirSync2 } from "node:fs";
|
|
61094
61928
|
import { join as join22 } from "node:path";
|
|
61095
61929
|
|
|
@@ -61179,7 +62013,7 @@ function newPlan(name2, goal, withCiTask) {
|
|
|
61179
62013
|
id: "T001",
|
|
61180
62014
|
title: "Add CI",
|
|
61181
62015
|
milestone: "M1",
|
|
61182
|
-
outcome: "A GitHub Actions
|
|
62016
|
+
outcome: "A CI workflow (GitHub Actions today; Overlane CI once native CI is available) runs the project's install, typecheck and test commands on every push and pull request.",
|
|
61183
62017
|
allowedPaths: [".github/**"],
|
|
61184
62018
|
acceptance: ["A workflow in .github/workflows runs on push and pull_request"],
|
|
61185
62019
|
verification: ['test -n "$(ls .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null)"'],
|
|
@@ -61218,7 +62052,8 @@ function schedulerSetup(projectId) {
|
|
|
61218
62052
|
}
|
|
61219
62053
|
async function connectKit(deps, options) {
|
|
61220
62054
|
if (options.mode === "new" && (options.goal === void 0 || options.goal.trim().length === 0)) throw new UsageError("--kit new needs --goal TEXT");
|
|
61221
|
-
const
|
|
62055
|
+
const project = await detectProject(deps, { name: options.name, provider: options.provider });
|
|
62056
|
+
const { root } = project;
|
|
61222
62057
|
if (await headCommit(deps, root) === null) throw new CliError("the repository has no commit yet; make an initial commit first");
|
|
61223
62058
|
const planDir = join22(root, PLAN_DIR);
|
|
61224
62059
|
const planExists = existsSync6(join22(planDir, "project.md"));
|
|
@@ -61230,7 +62065,7 @@ async function connectKit(deps, options) {
|
|
|
61230
62065
|
plan3 = await readPlan(root);
|
|
61231
62066
|
planSource = `${PLAN_DIR}/ already exists; kept as it is`;
|
|
61232
62067
|
} else if (options.mode === "new") {
|
|
61233
|
-
plan3 = newPlan(
|
|
62068
|
+
plan3 = newPlan(project.name, options.goal ?? "", !ciExists);
|
|
61234
62069
|
planSource = "minimal plan from --goal";
|
|
61235
62070
|
} else if (hasSpecKit(root)) {
|
|
61236
62071
|
plan3 = await importSpecKit(root);
|
|
@@ -61253,7 +62088,7 @@ async function connectKit(deps, options) {
|
|
|
61253
62088
|
const touched = [...INSTRUCTION_FILES, CI_FILE];
|
|
61254
62089
|
const unsaved = await dirty(deps, root, touched);
|
|
61255
62090
|
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`);
|
|
61256
|
-
say(deps, `Kit setup (${options.mode}) for ${
|
|
62091
|
+
say(deps, `Kit setup (${options.mode}) for ${projectLabel(project)}`);
|
|
61257
62092
|
say(deps, ` branch: create ${KIT_BRANCH}`);
|
|
61258
62093
|
say(deps, ` plan: ${planSource} (${plan3.milestones.length} milestone(s), ${plan3.tasks.length} task(s))${planExists ? "" : `, written to ${PLAN_DIR}/`}`);
|
|
61259
62094
|
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((c) => c !== void 0).join("; ")})`);
|
|
@@ -61305,11 +62140,11 @@ async function connectKit(deps, options) {
|
|
|
61305
62140
|
const agentConfig = [join22(".claude", "settings.json"), join22(".codex", "config.toml")];
|
|
61306
62141
|
const preDirty = new Set(await dirty(deps, root, agentConfig));
|
|
61307
62142
|
const preExisting = new Set(agentConfig.filter((file2) => existsSync6(join22(root, file2))));
|
|
61308
|
-
const
|
|
61309
|
-
if (
|
|
62143
|
+
const connected4 = await connect(deps, { ...options, yes: true });
|
|
62144
|
+
if (connected4.error !== void 0 || readBindingFile(root).kind !== "ok") {
|
|
61310
62145
|
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" });
|
|
61311
62146
|
}
|
|
61312
|
-
const connectData =
|
|
62147
|
+
const connectData = connected4.data !== void 0 && !("dryRun" in connected4.data) ? connected4.data : void 0;
|
|
61313
62148
|
for (const file2 of agentConfig) {
|
|
61314
62149
|
if (!existsSync6(join22(root, file2)) || preDirty.has(file2) || preExisting.has(file2) && (await dirty(deps, root, [file2])).length === 0) continue;
|
|
61315
62150
|
if ((await gitOut(deps, root, "check-ignore", "-q", "--", file2)).code === 0) continue;
|
|
@@ -61328,9 +62163,9 @@ async function connectKit(deps, options) {
|
|
|
61328
62163
|
const kit = kitClient(deps, serviceUrl, binding.binding, token.token);
|
|
61329
62164
|
await kit.putPolicy({ ...DEFAULT_RUN_POLICY, buildAheadLimit: firstMilestone });
|
|
61330
62165
|
say(deps, `Run policy set (build-ahead limit ${firstMilestone}).`);
|
|
61331
|
-
const synced = await kit.syncPlan(PlanSyncRequest.parse({ requestId: `cli-${
|
|
62166
|
+
const synced = await kit.syncPlan(PlanSyncRequest.parse({ requestId: `cli-${randomUUID8()}`, sourceCommit: sha, plan: await readPlan(root) }));
|
|
61332
62167
|
say(deps, `Plan synced: ${synced.created.length} created, ${synced.updated.length} updated, ${synced.unchanged.length} unchanged, ${synced.deferred.length} deferred.`);
|
|
61333
|
-
const pr = await openPullRequest(deps, root,
|
|
62168
|
+
const pr = await openPullRequest(deps, root, project.name);
|
|
61334
62169
|
say(deps);
|
|
61335
62170
|
for (const line2 of schedulerSetup(binding.binding.projectId)) say(deps, line2);
|
|
61336
62171
|
return {
|
|
@@ -61376,18 +62211,20 @@ var AGENTS_FLAG = { name: "agents", type: "string", value: "claude,codex", descr
|
|
|
61376
62211
|
var ROOT_FLAG = { name: "marketplace-root", type: "string", value: "DIR", description: "Folder holding the built claude/ and codex/ plugin marketplaces" };
|
|
61377
62212
|
var connectCommand = defineCommand({
|
|
61378
62213
|
path: ["connect"],
|
|
61379
|
-
summary: "Connect this GitHub
|
|
61380
|
-
description: "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 .harness/project.json and records what it added in .harness/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.",
|
|
62214
|
+
summary: "Connect this project (native Overlane, or your GitHub repository): sign in, bind it, register the plugin; --kit also sets up a plan",
|
|
62215
|
+
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 .harness/project.json and records what it added in .harness/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.",
|
|
61381
62216
|
flags: [
|
|
61382
62217
|
{ name: "service", type: "string", value: "URL", description: "Service address (https); default is the hosted service or HARNESS_SERVICE_URL" },
|
|
61383
62218
|
ROOT_FLAG,
|
|
61384
62219
|
AGENTS_FLAG,
|
|
61385
62220
|
{ name: "dry-run", type: "boolean", description: "Print the plan, the requests it would send and the files it would write; change nothing. Needs no credentials." },
|
|
61386
62221
|
{ name: "yes", type: "boolean", description: "Apply the plan without asking (required when there is no terminal)" },
|
|
62222
|
+
{ name: "name", type: "string", value: "NAME", description: "The project name (default: the GitHub repository name, else this folder's name)" },
|
|
62223
|
+
{ name: "provider", type: "string", enum: ["overlane", "github"], description: "Where the project lives: overlane (native, the default without a GitHub origin) or github (needs a github.com origin)" },
|
|
61387
62224
|
{ name: "kit", type: "string", enum: ["existing", "new"], description: "Also set up the project kit: plan files, CI, instruction blocks and one pull request" },
|
|
61388
62225
|
{ name: "goal", type: "string", value: "TEXT", description: "The project's goal; required with --kit new" }
|
|
61389
62226
|
],
|
|
61390
|
-
examples: ["overlane connect --dry-run", "overlane connect --yes", 'overlane connect --kit new --goal "A rundown service" --yes', "overlane connect --kit existing --yes"],
|
|
62227
|
+
examples: ["overlane connect --dry-run", "overlane connect --yes", "overlane connect --name my-app --yes", "overlane connect --provider github --yes", 'overlane connect --kit new --goal "A rundown service" --yes', "overlane connect --kit existing --yes"],
|
|
61391
62228
|
effect: "write",
|
|
61392
62229
|
needsNetwork: true,
|
|
61393
62230
|
keywords: ["setup", "install", "bind", "link", "onboard", "register plugin", "bootstrap", "autonomous", "plan", "kit", "get started", "initialise", "enable harness", "ci workflow", "pull request"],
|
|
@@ -61398,7 +62235,9 @@ var connectCommand = defineCommand({
|
|
|
61398
62235
|
marketplaceRoot: textFlag(inv, "marketplace-root"),
|
|
61399
62236
|
agents: parseAgentList(textFlag(inv, "agents")),
|
|
61400
62237
|
dryRun: inv.dryRun,
|
|
61401
|
-
yes: boolFlag(inv, "yes")
|
|
62238
|
+
yes: boolFlag(inv, "yes"),
|
|
62239
|
+
name: textFlag(inv, "name"),
|
|
62240
|
+
provider: parseProvider(textFlag(inv, "provider"))
|
|
61402
62241
|
};
|
|
61403
62242
|
const kit = textFlag(inv, "kit");
|
|
61404
62243
|
const goal = textFlag(inv, "goal");
|
|
@@ -61612,7 +62451,7 @@ var ReleaseRollbackResult = external_exports.union([
|
|
|
61612
62451
|
]);
|
|
61613
62452
|
|
|
61614
62453
|
// ../cli/src/commands/release.ts
|
|
61615
|
-
var
|
|
62454
|
+
var common8 = { needsAuth: true, needsNetwork: true };
|
|
61616
62455
|
var APPROVE = { name: "approve", type: "string", value: "DIGEST", description: "Approve this exact release digest when it changes executable files or policy" };
|
|
61617
62456
|
var releaseListCommand = defineCommand({
|
|
61618
62457
|
path: ["release", "list"],
|
|
@@ -61620,7 +62459,7 @@ var releaseListCommand = defineCommand({
|
|
|
61620
62459
|
description: "Lists releases with version, short digest, channel, change kinds, restart rule, compatibility and which projects pin them.",
|
|
61621
62460
|
examples: ["overlane release list"],
|
|
61622
62461
|
effect: "read",
|
|
61623
|
-
...
|
|
62462
|
+
...common8,
|
|
61624
62463
|
keywords: ["releases", "versions", "available", "published", "what versions", "all releases"],
|
|
61625
62464
|
result: ReleaseListResult,
|
|
61626
62465
|
handler: async (inv) => listReleases(inv.deps)
|
|
@@ -61631,7 +62470,7 @@ var releaseStatusCommand = defineCommand({
|
|
|
61631
62470
|
description: `Compares the installed release (.harness/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").`,
|
|
61632
62471
|
examples: ["overlane release status"],
|
|
61633
62472
|
effect: "read",
|
|
61634
|
-
...
|
|
62473
|
+
...common8,
|
|
61635
62474
|
keywords: ["installed", "version", "in sync", "update available", "which release", "pinned", "am i up to date", "current release"],
|
|
61636
62475
|
result: ReleaseStatusResult,
|
|
61637
62476
|
handler: async (inv) => releaseStatus(inv.deps)
|
|
@@ -61643,7 +62482,7 @@ var releaseUpdateCommand = defineCommand({
|
|
|
61643
62482
|
flags: [{ name: "to", type: "string", value: "DIGEST", description: "Install this release instead of the project's pin" }, APPROVE],
|
|
61644
62483
|
examples: ["overlane release update --dry-run", "overlane release update", "overlane release update --approve sha256:..."],
|
|
61645
62484
|
effect: "write",
|
|
61646
|
-
...
|
|
62485
|
+
...common8,
|
|
61647
62486
|
keywords: ["upgrade", "install release", "new version", "pull latest", "plugin update", "approve", "update plugin", "get newest"],
|
|
61648
62487
|
result: ReleaseUpdateResult,
|
|
61649
62488
|
handler: async (inv) => updateRelease(inv.deps, { to: textFlag(inv, "to"), approve: textFlag(inv, "approve"), dryRun: inv.dryRun })
|
|
@@ -61655,7 +62494,7 @@ var releaseRollbackCommand = defineCommand({
|
|
|
61655
62494
|
flags: [APPROVE],
|
|
61656
62495
|
examples: ["overlane release rollback --dry-run", "overlane release rollback --force"],
|
|
61657
62496
|
effect: "destructive",
|
|
61658
|
-
...
|
|
62497
|
+
...common8,
|
|
61659
62498
|
keywords: ["roll back", "revert", "undo update", "previous version", "downgrade", "go back", "restore", "undo release", "bad release"],
|
|
61660
62499
|
result: ReleaseRollbackResult,
|
|
61661
62500
|
handler: async (inv) => rollbackRelease(inv.deps, { approve: textFlag(inv, "approve"), dryRun: inv.dryRun })
|
|
@@ -61722,7 +62561,7 @@ var RunStatusResult = external_exports.object({
|
|
|
61722
62561
|
var RunPolicyChangeResult = withDryRun(external_exports.object({ changed: external_exports.boolean(), policy: PolicyShape }));
|
|
61723
62562
|
|
|
61724
62563
|
// ../cli/src/commands/run.ts
|
|
61725
|
-
var
|
|
62564
|
+
var common9 = { needsAuth: true, needsNetwork: true };
|
|
61726
62565
|
var EXECUTOR = { name: "executor", type: "string", enum: ["claude-code", "codex"], description: "Which agent this is (default: detected from the environment)" };
|
|
61727
62566
|
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.";
|
|
61728
62567
|
var runStartCommand = defineCommand({
|
|
@@ -61732,7 +62571,7 @@ var runStartCommand = defineCommand({
|
|
|
61732
62571
|
flags: [{ name: "trigger", type: "string", enum: ["schedule", "interactive", "event"], default: "interactive", description: "What started the run" }, EXECUTOR],
|
|
61733
62572
|
examples: ["overlane run start --trigger schedule", "overlane run start --dry-run"],
|
|
61734
62573
|
effect: "write",
|
|
61735
|
-
...
|
|
62574
|
+
...common9,
|
|
61736
62575
|
keywords: ["begin run", "bounded step", "autonomous", "start working", "new run", "schedule", "kick off"],
|
|
61737
62576
|
result: RunStartResult,
|
|
61738
62577
|
handler: async (inv) => startRun(inv.deps, { trigger: textFlag(inv, "trigger"), executor: textFlag(inv, "executor"), dryRun: inv.dryRun })
|
|
@@ -61744,7 +62583,7 @@ var runNextCommand = defineCommand({
|
|
|
61744
62583
|
flags: [EXECUTOR],
|
|
61745
62584
|
examples: ["overlane run next"],
|
|
61746
62585
|
effect: "read",
|
|
61747
|
-
...
|
|
62586
|
+
...common9,
|
|
61748
62587
|
keywords: ["what should I work on next", "next task", "runnable", "what to do", "pick a task", "which task", "what's next", "work on", "what is next", "todo"],
|
|
61749
62588
|
result: RunNextResult,
|
|
61750
62589
|
handler: async (inv) => nextTask(inv.deps, { executor: textFlag(inv, "executor") })
|
|
@@ -61756,7 +62595,7 @@ var runClaimCommand = defineCommand({
|
|
|
61756
62595
|
args: [{ name: "task-id", required: false, description: "The task to claim (default: the next runnable one)" }],
|
|
61757
62596
|
examples: ["overlane run claim", "overlane run claim T003"],
|
|
61758
62597
|
effect: "write",
|
|
61759
|
-
...
|
|
62598
|
+
...common9,
|
|
61760
62599
|
keywords: ["take task", "lease task", "grab", "assign", "pick up task", "get a task"],
|
|
61761
62600
|
result: RunClaimResult,
|
|
61762
62601
|
handler: async (inv) => claimTask(inv.deps, { positionals: inv.positionals, dryRun: inv.dryRun })
|
|
@@ -61773,7 +62612,7 @@ var runDecideCommand = defineCommand({
|
|
|
61773
62612
|
],
|
|
61774
62613
|
examples: ['overlane run decide --question "Which date library?" --decision "Use the built-in Intl" --evidence "package.json has no date library"'],
|
|
61775
62614
|
effect: "write",
|
|
61776
|
-
...
|
|
62615
|
+
...common9,
|
|
61777
62616
|
keywords: ["record decision", "question", "unblocked", "owner override", "judgement call", "log choice", "do not ask", "decide"],
|
|
61778
62617
|
result: RunDecideResult,
|
|
61779
62618
|
handler: async (inv) => decide(inv.deps, { question: textFlag(inv, "question"), decision: textFlag(inv, "decision"), evidence: listFlag(inv, "evidence"), task: textFlag(inv, "task"), dryRun: inv.dryRun })
|
|
@@ -61785,7 +62624,7 @@ var runEndCommand = defineCommand({
|
|
|
61785
62624
|
flags: [{ name: "reason", type: "string", required: true, enum: RUN_STOP_REASONS, description: "Why the run ended" }],
|
|
61786
62625
|
examples: ["overlane run end --reason nothing_runnable", "overlane run end --reason error"],
|
|
61787
62626
|
effect: "write",
|
|
61788
|
-
...
|
|
62627
|
+
...common9,
|
|
61789
62628
|
keywords: ["finish run", "stop", "wrap up", "close run", "release leases", "done with run", "end the run"],
|
|
61790
62629
|
result: RunEndResult,
|
|
61791
62630
|
handler: async (inv) => endRun(inv.deps, { reason: textFlag(inv, "reason"), dryRun: inv.dryRun })
|
|
@@ -61797,7 +62636,7 @@ var runStatusCommand = defineCommand({
|
|
|
61797
62636
|
flags: [EXECUTOR],
|
|
61798
62637
|
examples: ["overlane run status"],
|
|
61799
62638
|
effect: "read",
|
|
61800
|
-
...
|
|
62639
|
+
...common9,
|
|
61801
62640
|
keywords: ["policy", "budget", "limits", "how much left", "remaining", "state of run", "is it paused", "run policy"],
|
|
61802
62641
|
result: RunStatusResult,
|
|
61803
62642
|
handler: async (inv) => runStatus(inv.deps, { executor: textFlag(inv, "executor") })
|
|
@@ -61808,7 +62647,7 @@ var runPauseCommand = defineCommand({
|
|
|
61808
62647
|
description: "Sets the project's run policy to paused. Every run then stops at its next check (`STOP paused`). Undo with `overlane run resume`. Safe to repeat.",
|
|
61809
62648
|
examples: ["overlane run pause", "overlane run pause --dry-run"],
|
|
61810
62649
|
effect: "write",
|
|
61811
|
-
...
|
|
62650
|
+
...common9,
|
|
61812
62651
|
keywords: ["pause", "halt", "freeze", "stop all", "emergency brake", "disable autonomous runs", "policy", "no new runs", "stop agents", "turn off", "suspend"],
|
|
61813
62652
|
result: RunPolicyChangeResult,
|
|
61814
62653
|
handler: async (inv) => setPolicyStatus(inv.deps, "paused", inv.dryRun)
|
|
@@ -61819,7 +62658,7 @@ var runResumeCommand = defineCommand({
|
|
|
61819
62658
|
description: "Sets the project's run policy back to active so runs can start and tasks can be claimed again. Safe to repeat.",
|
|
61820
62659
|
examples: ["overlane run resume", "overlane run resume --dry-run"],
|
|
61821
62660
|
effect: "write",
|
|
61822
|
-
...
|
|
62661
|
+
...common9,
|
|
61823
62662
|
keywords: ["unpause", "re-enable", "continue autonomous", "reactivate", "policy active", "turn on", "restart runs", "lift the pause"],
|
|
61824
62663
|
result: RunPolicyChangeResult,
|
|
61825
62664
|
handler: async (inv) => setPolicyStatus(inv.deps, "active", inv.dryRun)
|
|
@@ -61829,7 +62668,7 @@ var runCommands = [runStartCommand, runNextCommand, runClaimCommand, runDecideCo
|
|
|
61829
62668
|
// ../cli/src/task/queue.ts
|
|
61830
62669
|
init_src();
|
|
61831
62670
|
init_zod();
|
|
61832
|
-
import { randomUUID as
|
|
62671
|
+
import { randomUUID as randomUUID9 } from "node:crypto";
|
|
61833
62672
|
import { mkdirSync as mkdirSync8, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "node:fs";
|
|
61834
62673
|
import { dirname as dirname8, join as join23 } from "node:path";
|
|
61835
62674
|
var TASK_POLICY_PATH = join23(".harness", "task-policy.json");
|
|
@@ -61849,7 +62688,7 @@ var TaskQueueResult = TaskQueue;
|
|
|
61849
62688
|
var TaskPrioritiseResult = withDryRun(external_exports.object({ ...PrioritiseResult.shape, next: external_exports.string() }));
|
|
61850
62689
|
var TaskPolicyResult = external_exports.object({ enforcement: TaskEnforcement, reason: external_exports.string().optional(), changedBy: external_exports.string().optional(), updatedAt: external_exports.string().optional(), localFile: external_exports.string() });
|
|
61851
62690
|
var TaskPolicySetResult = withDryRun(TaskPolicyResult);
|
|
61852
|
-
var
|
|
62691
|
+
var requestId8 = () => `cli-${randomUUID9()}`;
|
|
61853
62692
|
function priorityOf(value, fallback) {
|
|
61854
62693
|
const parsed = TaskPriority.safeParse(value ?? fallback);
|
|
61855
62694
|
if (!parsed.success) throw new UsageError(`--priority must be one of ${TASK_PRIORITIES.join(", ")}`);
|
|
@@ -61888,7 +62727,7 @@ async function prioritiseTask(deps, input2) {
|
|
|
61888
62727
|
const name2 = detectExecutorName(deps.env);
|
|
61889
62728
|
let request;
|
|
61890
62729
|
try {
|
|
61891
|
-
request = PrioritiseRequest.parse({ requestId:
|
|
62730
|
+
request = PrioritiseRequest.parse({ requestId: requestId8(), priority, top: input2.top, origin: name2 === "terminal" ? "user" : "agent", ...input2.reason === void 0 ? {} : { reason: input2.reason }, executor: executorFor(name2) });
|
|
61892
62731
|
} catch (error62) {
|
|
61893
62732
|
throw new UsageError(String(error62));
|
|
61894
62733
|
}
|
|
@@ -61917,7 +62756,7 @@ async function newTask(deps, input2) {
|
|
|
61917
62756
|
const begun = data;
|
|
61918
62757
|
const project = await connectedProject(deps, "task");
|
|
61919
62758
|
const name2 = detectExecutorName(deps.env);
|
|
61920
|
-
const request = PrioritiseRequest.parse({ requestId:
|
|
62759
|
+
const request = PrioritiseRequest.parse({ requestId: requestId8(), priority, top: input2.top, origin: name2 === "terminal" ? "user" : "agent", executor: executorFor(name2) });
|
|
61921
62760
|
try {
|
|
61922
62761
|
const ranked = await serviceCall(deps, project.serviceUrl, project.token)(PrioritiseResult, "POST", taskQueuePaths.prioritise(project.binding.tenantId, project.binding.projectId, begun.taskId), request);
|
|
61923
62762
|
say(deps, `Ranked ${begun.taskId} ${ranked.priority}${input2.top ? " (first)" : ""}.`);
|
|
@@ -61938,7 +62777,7 @@ async function setPolicy(deps, input2) {
|
|
|
61938
62777
|
const enforcement = TaskEnforcement.safeParse(input2.enforcement);
|
|
61939
62778
|
if (!enforcement.success) throw new UsageError(`set needs ${TASK_ENFORCEMENT.join(" or ")}`);
|
|
61940
62779
|
const name2 = detectExecutorName(deps.env);
|
|
61941
|
-
const parsed = SetTaskPolicyRequest.safeParse({ requestId:
|
|
62780
|
+
const parsed = SetTaskPolicyRequest.safeParse({ requestId: requestId8(), enforcement: enforcement.data, ...input2.reason === void 0 ? {} : { reason: input2.reason }, executor: executorFor(name2) });
|
|
61942
62781
|
if (!parsed.success) throw new UsageError(parsed.error.issues.map((issue2) => issue2.message).join("; "));
|
|
61943
62782
|
if (input2.dryRun) {
|
|
61944
62783
|
const project2 = await offlineProject(deps, "task");
|
|
@@ -61965,7 +62804,7 @@ async function startExisting(deps, taskId, dryRun) {
|
|
|
61965
62804
|
}
|
|
61966
62805
|
|
|
61967
62806
|
// ../cli/src/commands/queue.ts
|
|
61968
|
-
var
|
|
62807
|
+
var common10 = { needsAuth: true, needsNetwork: true };
|
|
61969
62808
|
var PRIORITIES2 = ["P0", "P1", "P2", "P3"];
|
|
61970
62809
|
var taskNewCommand = defineCommand({
|
|
61971
62810
|
path: ["task", "new"],
|
|
@@ -61981,7 +62820,7 @@ var taskNewCommand = defineCommand({
|
|
|
61981
62820
|
],
|
|
61982
62821
|
examples: ['overlane task new "Fix login redirect"', 'overlane task new "Hotfix the build" --priority P0 --top'],
|
|
61983
62822
|
effect: "write",
|
|
61984
|
-
...
|
|
62823
|
+
...common10,
|
|
61985
62824
|
keywords: ["new task", "create task", "no active task", "blocked no task", "start work", "need a task", "begin", "quick task"],
|
|
61986
62825
|
result: TaskNewResult,
|
|
61987
62826
|
handler: async (inv) => newTask(inv.deps, {
|
|
@@ -62000,7 +62839,7 @@ var taskNextCommand = defineCommand({
|
|
|
62000
62839
|
description: "Picks the best ready or paused task: P0 before P3, then rank, then milestone and dependency order. When this working copy holds a task and the next one outranks it, says so (preempt) and prints the commands to checkpoint and switch; the preempted task comes back through this command afterwards.",
|
|
62001
62840
|
examples: ["overlane task next"],
|
|
62002
62841
|
effect: "read",
|
|
62003
|
-
...
|
|
62842
|
+
...common10,
|
|
62004
62843
|
keywords: ["what next", "next task", "priority", "what should i work on", "pick work", "resume after", "queue"],
|
|
62005
62844
|
result: TaskNextResult,
|
|
62006
62845
|
handler: async (inv) => taskNext(inv.deps)
|
|
@@ -62011,7 +62850,7 @@ var taskQueueCommand = defineCommand({
|
|
|
62011
62850
|
description: "Lists ready, running, paused and blocked tasks by priority, then rank, then plan order, with each task's priority.",
|
|
62012
62851
|
examples: ["overlane task queue"],
|
|
62013
62852
|
effect: "read",
|
|
62014
|
-
...
|
|
62853
|
+
...common10,
|
|
62015
62854
|
keywords: ["priority list", "ranking", "order", "backlog", "what is queued", "p0"],
|
|
62016
62855
|
result: TaskQueueResult,
|
|
62017
62856
|
handler: async (inv) => taskQueue(inv.deps)
|
|
@@ -62028,7 +62867,7 @@ var taskPrioritiseCommand = defineCommand({
|
|
|
62028
62867
|
],
|
|
62029
62868
|
examples: ["overlane task prioritise task-7 --priority P0 --top", 'overlane task prioritise task-9 --priority P2 --reason "user said later"'],
|
|
62030
62869
|
effect: "write",
|
|
62031
|
-
...
|
|
62870
|
+
...common10,
|
|
62032
62871
|
keywords: ["reprioritize", "reprioritise", "bump", "urgent", "move to top", "rank", "lower priority", "p0", "p1", "p2", "p3"],
|
|
62033
62872
|
result: TaskPrioritiseResult,
|
|
62034
62873
|
handler: async (inv) => prioritiseTask(inv.deps, { taskId: inv.positionals[0], priority: textFlag(inv, "priority"), top: boolFlag(inv, "top"), reason: textFlag(inv, "reason"), dryRun: inv.dryRun })
|
|
@@ -62039,7 +62878,7 @@ var taskPolicyCommand = defineCommand({
|
|
|
62039
62878
|
description: "Reads the project's task requirement (default `required`: edits and mutating shell commands are refused without an active task) and writes it to .harness/task-policy.json for the hooks.",
|
|
62040
62879
|
examples: ["overlane task policy"],
|
|
62041
62880
|
effect: "read",
|
|
62042
|
-
...
|
|
62881
|
+
...common10,
|
|
62043
62882
|
keywords: ["enforcement", "require task", "task gate", "relax", "blocked", "policy"],
|
|
62044
62883
|
result: TaskPolicyResult,
|
|
62045
62884
|
handler: async (inv) => showPolicy2(inv.deps)
|
|
@@ -62052,7 +62891,7 @@ var taskPolicySetCommand = defineCommand({
|
|
|
62052
62891
|
flags: [{ name: "reason", type: "string", value: "TEXT", description: "Why the rule is relaxed (required for relaxed)" }],
|
|
62053
62892
|
examples: ["overlane task policy set required", 'overlane task policy set relaxed --reason "docs-only repository"'],
|
|
62054
62893
|
effect: "write",
|
|
62055
|
-
...
|
|
62894
|
+
...common10,
|
|
62056
62895
|
keywords: ["relax", "turn off task requirement", "require tasks", "allow edits without task", "enforcement"],
|
|
62057
62896
|
result: TaskPolicySetResult,
|
|
62058
62897
|
handler: async (inv) => setPolicy(inv.deps, { enforcement: inv.positionals[0], reason: textFlag(inv, "reason"), dryRun: inv.dryRun })
|
|
@@ -62097,14 +62936,14 @@ var TaskHandoffResult = withDryRun(
|
|
|
62097
62936
|
);
|
|
62098
62937
|
|
|
62099
62938
|
// ../cli/src/commands/task.ts
|
|
62100
|
-
var
|
|
62939
|
+
var common11 = { needsAuth: true, needsNetwork: true };
|
|
62101
62940
|
var taskListCommand = defineCommand({
|
|
62102
62941
|
path: ["task", "list"],
|
|
62103
62942
|
summary: "List the project's tasks and their states",
|
|
62104
62943
|
description: "Lists every task of the connected project with its state, pause reason, version, lease holder, checks and latest checkpoint.",
|
|
62105
62944
|
examples: ["overlane task list"],
|
|
62106
62945
|
effect: "read",
|
|
62107
|
-
...
|
|
62946
|
+
...common11,
|
|
62108
62947
|
keywords: ["tasks", "show all tasks", "see tasks", "backlog", "what tasks exist", "work items"],
|
|
62109
62948
|
result: TaskListResult,
|
|
62110
62949
|
handler: async (inv) => listTasks(inv.deps)
|
|
@@ -62122,7 +62961,7 @@ var taskStartCommand = defineCommand({
|
|
|
62122
62961
|
],
|
|
62123
62962
|
examples: ["overlane task start task-7", 'overlane task start --outcome "Add CSV export" --criterion "export works" --check unit_tests:L2 --path "src/**"', 'overlane task start --outcome "Fix login" --criterion "login passes" --path "src/auth/**" --dry-run'],
|
|
62124
62963
|
effect: "write",
|
|
62125
|
-
...
|
|
62964
|
+
...common11,
|
|
62126
62965
|
keywords: ["begin", "create task", "new task", "open", "claim new", "work item", "contract", "acceptance criteria", "start working"],
|
|
62127
62966
|
result: TaskStartResult,
|
|
62128
62967
|
handler: async (inv) => inv.positionals[0] !== void 0 ? startExisting(inv.deps, inv.positionals[0], inv.dryRun) : startTask(inv.deps, { outcome: textFlag(inv, "outcome"), criteria: listFlag(inv, "criterion"), paths: listFlag(inv, "path"), checks: listFlag(inv, "check"), dryRun: inv.dryRun })
|
|
@@ -62133,7 +62972,7 @@ var taskStatusCommand = defineCommand({
|
|
|
62133
62972
|
description: "Shows the held task from the service: state, lease, acceptance criteria, checks, evidence count and the latest checkpoint. Says so when nothing is held or the lease was lost.",
|
|
62134
62973
|
examples: ["overlane task status"],
|
|
62135
62974
|
effect: "read",
|
|
62136
|
-
...
|
|
62975
|
+
...common11,
|
|
62137
62976
|
keywords: ["current task", "what am i working on", "lease", "active task", "progress", "held task"],
|
|
62138
62977
|
result: TaskStatusResult,
|
|
62139
62978
|
handler: async (inv) => taskStatus(inv.deps)
|
|
@@ -62149,7 +62988,7 @@ var taskCheckpointCommand = defineCommand({
|
|
|
62149
62988
|
],
|
|
62150
62989
|
examples: ['overlane task checkpoint --summary "Parser done" --next "Write the tests"', 'overlane task checkpoint --summary "Out of budget" --next "Resume" --pause quota'],
|
|
62151
62990
|
effect: "write",
|
|
62152
|
-
...
|
|
62991
|
+
...common11,
|
|
62153
62992
|
keywords: ["save", "progress", "pause", "stop work", "park", "quota", "limit reached", "remember place", "snapshot", "save state", "out of budget"],
|
|
62154
62993
|
result: TaskCheckpointResult,
|
|
62155
62994
|
handler: async (inv) => checkpointTask(inv.deps, { summary: textFlag(inv, "summary"), next: textFlag(inv, "next"), pause: textFlag(inv, "pause"), dryRun: inv.dryRun })
|
|
@@ -62161,7 +63000,7 @@ var taskResumeCommand = defineCommand({
|
|
|
62161
63000
|
args: [{ name: "task-id", required: true, description: "The task to resume" }],
|
|
62162
63001
|
examples: ["overlane task resume task-1"],
|
|
62163
63002
|
effect: "write",
|
|
62164
|
-
...
|
|
63003
|
+
...common11,
|
|
62165
63004
|
keywords: ["continue", "pick up", "restart", "reclaim", "after pause", "take over", "carry on"],
|
|
62166
63005
|
result: TaskResumeResult,
|
|
62167
63006
|
handler: async (inv) => resumeTask(inv.deps, { taskId: inv.positionals[0], dryRun: inv.dryRun })
|
|
@@ -62172,7 +63011,7 @@ var taskSubmitCommand = defineCommand({
|
|
|
62172
63011
|
description: "Asks for verification at HEAD. The task is verified only when evidence at or above each required check's level exists for that commit: L2 comes from CI on the pushed commit, L1 from `overlane task evidence`.",
|
|
62173
63012
|
examples: ["overlane task submit", "overlane task submit --dry-run"],
|
|
62174
63013
|
effect: "write",
|
|
62175
|
-
...
|
|
63014
|
+
...common11,
|
|
62176
63015
|
keywords: ["finish", "done", "complete", "verify", "ready for review", "request verification", "hand in", "turn in"],
|
|
62177
63016
|
result: TaskSubmitResult,
|
|
62178
63017
|
handler: async (inv) => submitTask(inv.deps, { dryRun: inv.dryRun })
|
|
@@ -62188,7 +63027,7 @@ var taskEvidenceCommand = defineCommand({
|
|
|
62188
63027
|
],
|
|
62189
63028
|
examples: ["overlane task evidence --level L1 -- pnpm test"],
|
|
62190
63029
|
effect: "write",
|
|
62191
|
-
...
|
|
63030
|
+
...common11,
|
|
62192
63031
|
keywords: ["tests", "prove", "record test result", "verification", "run checks", "L1", "attest", "run the tests and record"],
|
|
62193
63032
|
result: TaskEvidenceResult,
|
|
62194
63033
|
handler: async (inv) => recordEvidence(inv.deps, { level: textFlag(inv, "level"), task: textFlag(inv, "task"), words: inv.positionals, dryRun: inv.dryRun })
|
|
@@ -62204,7 +63043,7 @@ var taskHandoffCommand = defineCommand({
|
|
|
62204
63043
|
],
|
|
62205
63044
|
examples: ["overlane task handoff --to codex", 'overlane task handoff --to claude --summary "API done" --next "Add tests"'],
|
|
62206
63045
|
effect: "write",
|
|
62207
|
-
...
|
|
63046
|
+
...common11,
|
|
62208
63047
|
keywords: ["hand off", "transfer", "give to", "switch agent", "other agent", "codex", "claude", "pass the task", "delegate", "move work", "swap agents"],
|
|
62209
63048
|
result: TaskHandoffResult,
|
|
62210
63049
|
handler: async (inv) => handoffTask(inv.deps, { summary: textFlag(inv, "summary"), next: textFlag(inv, "next"), to: textFlag(inv, "to"), dryRun: inv.dryRun })
|
|
@@ -62235,7 +63074,8 @@ function coreCommands() {
|
|
|
62235
63074
|
...memoryCommands,
|
|
62236
63075
|
...libCommands,
|
|
62237
63076
|
...reviewCommands,
|
|
62238
|
-
...guardCommands
|
|
63077
|
+
...guardCommands,
|
|
63078
|
+
...billingCommands
|
|
62239
63079
|
];
|
|
62240
63080
|
}
|
|
62241
63081
|
function createRegistry(extra = []) {
|