overlane 0.1.124 → 0.1.126
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 +585 -182
- 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 +35 -34
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-guard.mjs +34 -33
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-intake.mjs +38 -37
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-quota.mjs +36 -35
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-statusline.mjs +32 -31
- package/plugins/claude/plugins/mvrx-harness/scripts/harness-stop.mjs +39 -38
- package/plugins/codex/plugins/mvrx-harness/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-context.mjs +35 -34
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-guard.mjs +34 -33
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-intake.mjs +38 -37
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-quota.mjs +36 -35
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-statusline.mjs +32 -31
- package/plugins/codex/plugins/mvrx-harness/scripts/harness-stop.mjs +39 -38
- 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(),
|
|
@@ -22286,6 +22378,208 @@ var init_onboarding = __esm({
|
|
|
22286
22378
|
}
|
|
22287
22379
|
});
|
|
22288
22380
|
|
|
22381
|
+
// ../contracts/src/audit.ts
|
|
22382
|
+
function canonicalJson(value) {
|
|
22383
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "null";
|
|
22384
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
22385
|
+
const entries = Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
22386
|
+
return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v)}`).join(",")}}`;
|
|
22387
|
+
}
|
|
22388
|
+
function sha256Hex(text) {
|
|
22389
|
+
const data = new TextEncoder().encode(text);
|
|
22390
|
+
const bitLength = data.length * 8;
|
|
22391
|
+
const padded = new Uint8Array(Math.ceil((data.length + 9) / 64) * 64);
|
|
22392
|
+
padded.set(data);
|
|
22393
|
+
padded[data.length] = 128;
|
|
22394
|
+
const view = new DataView(padded.buffer);
|
|
22395
|
+
view.setUint32(padded.length - 8, Math.floor(bitLength / 2 ** 32));
|
|
22396
|
+
view.setUint32(padded.length - 4, bitLength >>> 0);
|
|
22397
|
+
const h = new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]);
|
|
22398
|
+
const w = new Uint32Array(64);
|
|
22399
|
+
const rotr = (x, n) => x >>> n | x << 32 - n;
|
|
22400
|
+
for (let offset = 0; offset < padded.length; offset += 64) {
|
|
22401
|
+
for (let i2 = 0; i2 < 16; i2 += 1) w[i2] = view.getUint32(offset + i2 * 4);
|
|
22402
|
+
for (let i2 = 16; i2 < 64; i2 += 1) {
|
|
22403
|
+
const a2 = w[i2 - 15];
|
|
22404
|
+
const b2 = w[i2 - 2];
|
|
22405
|
+
const s0 = rotr(a2, 7) ^ rotr(a2, 18) ^ a2 >>> 3;
|
|
22406
|
+
const s1 = rotr(b2, 17) ^ rotr(b2, 19) ^ b2 >>> 10;
|
|
22407
|
+
w[i2] = w[i2 - 16] + s0 + w[i2 - 7] + s1 >>> 0;
|
|
22408
|
+
}
|
|
22409
|
+
let [a, b, c, d, e, f, g, hh] = h;
|
|
22410
|
+
for (let i2 = 0; i2 < 64; i2 += 1) {
|
|
22411
|
+
const t1 = hh + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + (e & f ^ ~e & g) + K[i2] + w[i2] >>> 0;
|
|
22412
|
+
const t2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
|
|
22413
|
+
hh = g;
|
|
22414
|
+
g = f;
|
|
22415
|
+
f = e;
|
|
22416
|
+
e = d + t1 >>> 0;
|
|
22417
|
+
d = c;
|
|
22418
|
+
c = b;
|
|
22419
|
+
b = a;
|
|
22420
|
+
a = t1 + t2 >>> 0;
|
|
22421
|
+
}
|
|
22422
|
+
const sums = [a, b, c, d, e, f, g, hh];
|
|
22423
|
+
for (let i2 = 0; i2 < 8; i2 += 1) h[i2] = h[i2] + sums[i2] >>> 0;
|
|
22424
|
+
}
|
|
22425
|
+
return [...h].map((n) => n.toString(16).padStart(8, "0")).join("");
|
|
22426
|
+
}
|
|
22427
|
+
function auditHash(prevHash, body2) {
|
|
22428
|
+
return sha256Hex(`${prevHash}
|
|
22429
|
+
${canonicalJson(AuditEventBody.parse(body2))}`);
|
|
22430
|
+
}
|
|
22431
|
+
function chainAuditEvent(prevHash, body2) {
|
|
22432
|
+
const previous = prevHash ?? AUDIT_GENESIS_HASH;
|
|
22433
|
+
return AuditEvent.parse({ ...body2, prevHash: previous, hash: auditHash(previous, body2) });
|
|
22434
|
+
}
|
|
22435
|
+
var AUDIT_CATEGORIES, AuditCategory, AUDIT_ACTIONS, AUDIT_ACTION_NAMES, AuditActionName, AUDIT_RESULTS, AuditResult, AuditPrincipalType, AuditTarget, Hash, AUDIT_GENESIS_HASH, AuditEventBody, AuditEvent, AuditList, AuditVerification, K, FIXTURE_AT, fixtureBodies, AUDIT_FIXTURE;
|
|
22436
|
+
var init_audit = __esm({
|
|
22437
|
+
"../contracts/src/audit.ts"() {
|
|
22438
|
+
"use strict";
|
|
22439
|
+
init_zod();
|
|
22440
|
+
init_common();
|
|
22441
|
+
AUDIT_CATEGORIES = ["admin", "policy", "token"];
|
|
22442
|
+
AuditCategory = external_exports.enum(AUDIT_CATEGORIES);
|
|
22443
|
+
AUDIT_ACTIONS = {
|
|
22444
|
+
"member.removed": "admin",
|
|
22445
|
+
"member.role_changed": "admin",
|
|
22446
|
+
"invitation.created": "admin",
|
|
22447
|
+
"invitation.revoked": "admin",
|
|
22448
|
+
"run_policy.updated": "policy",
|
|
22449
|
+
"project.updated": "policy",
|
|
22450
|
+
"release.published": "policy",
|
|
22451
|
+
"release.promoted": "policy",
|
|
22452
|
+
"release.withdrawn": "policy",
|
|
22453
|
+
"release.pinned": "policy",
|
|
22454
|
+
"release.rolled_back": "policy",
|
|
22455
|
+
"memory_settings.updated": "policy",
|
|
22456
|
+
"issue_sync.updated": "policy",
|
|
22457
|
+
"loop.created": "policy",
|
|
22458
|
+
"loop.updated": "policy",
|
|
22459
|
+
"loop.deleted": "policy",
|
|
22460
|
+
"bot.registered": "policy",
|
|
22461
|
+
"bot.revoked": "policy",
|
|
22462
|
+
"bot.key_rotated": "policy",
|
|
22463
|
+
"token.created": "token",
|
|
22464
|
+
"token.revoked": "token"
|
|
22465
|
+
};
|
|
22466
|
+
AUDIT_ACTION_NAMES = Object.keys(AUDIT_ACTIONS);
|
|
22467
|
+
AuditActionName = external_exports.enum(Object.keys(AUDIT_ACTIONS));
|
|
22468
|
+
AUDIT_RESULTS = ["success", "denied", "failure"];
|
|
22469
|
+
AuditResult = external_exports.enum(AUDIT_RESULTS);
|
|
22470
|
+
AuditPrincipalType = external_exports.enum(["user", "agent", "system"]);
|
|
22471
|
+
AuditTarget = external_exports.object({ type: external_exports.string().min(1).max(40), id: external_exports.string().max(200) }).strict();
|
|
22472
|
+
Hash = external_exports.string().regex(/^[0-9a-f]{64}$/, "must be 64 lowercase hex characters");
|
|
22473
|
+
AUDIT_GENESIS_HASH = "0".repeat(64);
|
|
22474
|
+
AuditEventBody = external_exports.object({
|
|
22475
|
+
tenantId: TenantId,
|
|
22476
|
+
/** 1, 2, 3 ... per tenant, with no gaps. */
|
|
22477
|
+
seq: external_exports.number().int().positive(),
|
|
22478
|
+
eventId: external_exports.string().min(1).max(64),
|
|
22479
|
+
at: Timestamp,
|
|
22480
|
+
/** User ID, agent token ID or `system`. */
|
|
22481
|
+
actor: external_exports.string().min(1).max(200),
|
|
22482
|
+
principalType: AuditPrincipalType,
|
|
22483
|
+
role: external_exports.string().min(1).max(40).nullable(),
|
|
22484
|
+
action: AuditActionName,
|
|
22485
|
+
category: AuditCategory,
|
|
22486
|
+
target: AuditTarget,
|
|
22487
|
+
result: AuditResult
|
|
22488
|
+
}).strict();
|
|
22489
|
+
AuditEvent = AuditEventBody.extend({ prevHash: Hash, hash: Hash }).strict().refine((event) => AUDIT_ACTIONS[event.action] === event.category, { message: "category does not match the action", path: ["category"] });
|
|
22490
|
+
AuditList = external_exports.object({
|
|
22491
|
+
tenantId: TenantId,
|
|
22492
|
+
events: external_exports.array(AuditEvent),
|
|
22493
|
+
/** Pass as `after` to read the next page; null when this is the last page. */
|
|
22494
|
+
nextAfter: external_exports.number().int().nonnegative().nullable(),
|
|
22495
|
+
/** Hash of the newest row of the tenant's chain (null for an empty log). */
|
|
22496
|
+
head: Hash.nullable()
|
|
22497
|
+
}).strict();
|
|
22498
|
+
AuditVerification = external_exports.object({
|
|
22499
|
+
tenantId: TenantId,
|
|
22500
|
+
ok: external_exports.boolean(),
|
|
22501
|
+
checked: external_exports.number().int().nonnegative(),
|
|
22502
|
+
head: Hash.nullable(),
|
|
22503
|
+
/** The first row that fails (its seq) and why. */
|
|
22504
|
+
brokenAt: external_exports.number().int().positive().optional(),
|
|
22505
|
+
reason: external_exports.enum(["bad_hash", "bad_link", "bad_sequence", "wrong_tenant", "bad_category"]).optional()
|
|
22506
|
+
}).strict();
|
|
22507
|
+
K = new Uint32Array([
|
|
22508
|
+
1116352408,
|
|
22509
|
+
1899447441,
|
|
22510
|
+
3049323471,
|
|
22511
|
+
3921009573,
|
|
22512
|
+
961987163,
|
|
22513
|
+
1508970993,
|
|
22514
|
+
2453635748,
|
|
22515
|
+
2870763221,
|
|
22516
|
+
3624381080,
|
|
22517
|
+
310598401,
|
|
22518
|
+
607225278,
|
|
22519
|
+
1426881987,
|
|
22520
|
+
1925078388,
|
|
22521
|
+
2162078206,
|
|
22522
|
+
2614888103,
|
|
22523
|
+
3248222580,
|
|
22524
|
+
3835390401,
|
|
22525
|
+
4022224774,
|
|
22526
|
+
264347078,
|
|
22527
|
+
604807628,
|
|
22528
|
+
770255983,
|
|
22529
|
+
1249150122,
|
|
22530
|
+
1555081692,
|
|
22531
|
+
1996064986,
|
|
22532
|
+
2554220882,
|
|
22533
|
+
2821834349,
|
|
22534
|
+
2952996808,
|
|
22535
|
+
3210313671,
|
|
22536
|
+
3336571891,
|
|
22537
|
+
3584528711,
|
|
22538
|
+
113926993,
|
|
22539
|
+
338241895,
|
|
22540
|
+
666307205,
|
|
22541
|
+
773529912,
|
|
22542
|
+
1294757372,
|
|
22543
|
+
1396182291,
|
|
22544
|
+
1695183700,
|
|
22545
|
+
1986661051,
|
|
22546
|
+
2177026350,
|
|
22547
|
+
2456956037,
|
|
22548
|
+
2730485921,
|
|
22549
|
+
2820302411,
|
|
22550
|
+
3259730800,
|
|
22551
|
+
3345764771,
|
|
22552
|
+
3516065817,
|
|
22553
|
+
3600352804,
|
|
22554
|
+
4094571909,
|
|
22555
|
+
275423344,
|
|
22556
|
+
430227734,
|
|
22557
|
+
506948616,
|
|
22558
|
+
659060556,
|
|
22559
|
+
883997877,
|
|
22560
|
+
958139571,
|
|
22561
|
+
1322822218,
|
|
22562
|
+
1537002063,
|
|
22563
|
+
1747873779,
|
|
22564
|
+
1955562222,
|
|
22565
|
+
2024104815,
|
|
22566
|
+
2227730452,
|
|
22567
|
+
2361852424,
|
|
22568
|
+
2428436474,
|
|
22569
|
+
2756734187,
|
|
22570
|
+
3204031479,
|
|
22571
|
+
3329325298
|
|
22572
|
+
]);
|
|
22573
|
+
FIXTURE_AT = "2026-10-09T00:00:00.000Z";
|
|
22574
|
+
fixtureBodies = [
|
|
22575
|
+
{ tenantId: "tm-1", seq: 1, eventId: "aud_1", at: FIXTURE_AT, actor: "u-owner", principalType: "user", role: "owner", action: "invitation.created", category: "admin", target: { type: "invitation", id: "inv_1" }, result: "success" },
|
|
22576
|
+
{ tenantId: "tm-1", seq: 2, eventId: "aud_2", at: "2026-10-09T00:05:00.000Z", actor: "u-admin", principalType: "user", role: "admin", action: "run_policy.updated", category: "policy", target: { type: "project", id: "prj-demo" }, result: "success" },
|
|
22577
|
+
{ tenantId: "tm-1", seq: 3, eventId: "aud_3", at: "2026-10-09T00:10:00.000Z", actor: "u-viewer", principalType: "user", role: "viewer", action: "token.created", category: "token", target: { type: "token", id: "" }, result: "denied" }
|
|
22578
|
+
];
|
|
22579
|
+
AUDIT_FIXTURE = fixtureBodies.reduce((rows, body2) => [...rows, chainAuditEvent(rows.at(-1)?.hash ?? null, body2)], []);
|
|
22580
|
+
}
|
|
22581
|
+
});
|
|
22582
|
+
|
|
22289
22583
|
// ../contracts/src/docs-service.ts
|
|
22290
22584
|
function scoped(shape2) {
|
|
22291
22585
|
return external_exports.discriminatedUnion("visibility", [external_exports.object({ ...shape2, ...PublicScope }).strict(), external_exports.object({ ...shape2, ...PrivateScope }).strict()]);
|
|
@@ -22505,7 +22799,7 @@ var init_docs_service = __esm({
|
|
|
22505
22799
|
function base3(tenantId, projectId) {
|
|
22506
22800
|
return `/v1/tenants/${encodeURIComponent(tenantId)}/projects/${encodeURIComponent(projectId)}/review`;
|
|
22507
22801
|
}
|
|
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;
|
|
22802
|
+
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
22803
|
var init_review = __esm({
|
|
22510
22804
|
"../contracts/src/review.ts"() {
|
|
22511
22805
|
"use strict";
|
|
@@ -22520,6 +22814,9 @@ var init_review = __esm({
|
|
|
22520
22814
|
tenantId: TenantId,
|
|
22521
22815
|
id: external_exports.string().min(1),
|
|
22522
22816
|
projectId: ProjectId,
|
|
22817
|
+
/** Where the change lives. A record from before ADR 0050 has none: read it with `reviewProvider`, which gives `github`. */
|
|
22818
|
+
provider: Provider.optional(),
|
|
22819
|
+
/** The repository key: `owner/name` for a connection, `overlane/<projectId>` or `patch/<projectId>` for native reviews. */
|
|
22523
22820
|
repository: external_exports.string().min(1),
|
|
22524
22821
|
pullNumber: external_exports.number().int().positive(),
|
|
22525
22822
|
path: external_exports.string().min(1),
|
|
@@ -22573,6 +22870,7 @@ var init_review = __esm({
|
|
|
22573
22870
|
tenantId: TenantId,
|
|
22574
22871
|
id: external_exports.string().min(1),
|
|
22575
22872
|
projectId: ProjectId,
|
|
22873
|
+
provider: Provider.optional(),
|
|
22576
22874
|
repository: external_exports.string().min(1),
|
|
22577
22875
|
pullNumber: external_exports.number().int().positive(),
|
|
22578
22876
|
headSha: CommitSha,
|
|
@@ -22613,6 +22911,7 @@ var init_review = __esm({
|
|
|
22613
22911
|
patch: external_exports.string().max(4e5).optional()
|
|
22614
22912
|
}).strict();
|
|
22615
22913
|
PullRequestSnapshot = external_exports.object({
|
|
22914
|
+
provider: Provider.optional(),
|
|
22616
22915
|
repository: external_exports.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/),
|
|
22617
22916
|
number: external_exports.number().int().positive(),
|
|
22618
22917
|
headSha: CommitSha,
|
|
@@ -22623,10 +22922,20 @@ var init_review = __esm({
|
|
|
22623
22922
|
fork: external_exports.boolean().default(false),
|
|
22624
22923
|
files: external_exports.array(PullFile).max(3e3)
|
|
22625
22924
|
}).strict();
|
|
22925
|
+
MAX_PATCH_BYTES = 2e6;
|
|
22626
22926
|
ReviewRunRequest = external_exports.object({
|
|
22627
22927
|
requestId: external_exports.string().min(1).max(128),
|
|
22628
22928
|
trigger: external_exports.enum(REVIEW_TRIGGERS).default("manual"),
|
|
22629
22929
|
source: external_exports.discriminatedUnion("kind", [
|
|
22930
|
+
external_exports.object({
|
|
22931
|
+
kind: external_exports.literal("patch"),
|
|
22932
|
+
diff: external_exports.string().min(1).max(MAX_PATCH_BYTES),
|
|
22933
|
+
title: external_exports.string().max(500).optional(),
|
|
22934
|
+
/** Names this change so a re-review of the same change merges its findings; defaults to `patch`. */
|
|
22935
|
+
label: external_exports.string().regex(/^[A-Za-z0-9._-]{1,64}$/).optional(),
|
|
22936
|
+
author: external_exports.string().min(1).max(100).optional()
|
|
22937
|
+
}).strict(),
|
|
22938
|
+
external_exports.object({ kind: external_exports.literal("overlane"), number: external_exports.number().int().positive(), repository: external_exports.string().min(1).optional() }).strict(),
|
|
22630
22939
|
external_exports.object({ kind: external_exports.literal("github"), repository: external_exports.string().min(1), number: external_exports.number().int().positive() }).strict(),
|
|
22631
22940
|
external_exports.object({ kind: external_exports.literal("inline"), pull: PullRequestSnapshot }).strict()
|
|
22632
22941
|
])
|
|
@@ -23444,6 +23753,7 @@ var init_src = __esm({
|
|
|
23444
23753
|
init_memory();
|
|
23445
23754
|
init_issues();
|
|
23446
23755
|
init_onboarding();
|
|
23756
|
+
init_audit();
|
|
23447
23757
|
init_docs_service();
|
|
23448
23758
|
init_review();
|
|
23449
23759
|
init_guardrails();
|
|
@@ -30784,25 +31094,25 @@ var require_dist = __commonJS({
|
|
|
30784
31094
|
});
|
|
30785
31095
|
|
|
30786
31096
|
// src/assets.ts
|
|
30787
|
-
import { basename as
|
|
31097
|
+
import { basename as basename5, join as join24, resolve as resolve11 } from "node:path";
|
|
30788
31098
|
import { fileURLToPath } from "node:url";
|
|
30789
31099
|
function packageRoot(env = process.env) {
|
|
30790
31100
|
const override = env["MVRX_PACKAGE_ROOT"];
|
|
30791
31101
|
if (override !== void 0 && override !== "") return override;
|
|
30792
|
-
return
|
|
31102
|
+
return resolve11(fileURLToPath(new URL(".", import.meta.url)), "..");
|
|
30793
31103
|
}
|
|
30794
31104
|
function assetDir(env = process.env) {
|
|
30795
31105
|
const override = env["MVRX_ASSET_DIR"];
|
|
30796
31106
|
return override !== void 0 && override !== "" ? override : join24(packageRoot(env), "assets");
|
|
30797
31107
|
}
|
|
30798
31108
|
function assetFile(name2) {
|
|
30799
|
-
return join24(assetDir(),
|
|
31109
|
+
return join24(assetDir(), basename5(name2));
|
|
30800
31110
|
}
|
|
30801
31111
|
var VERSION;
|
|
30802
31112
|
var init_assets = __esm({
|
|
30803
31113
|
"src/assets.ts"() {
|
|
30804
31114
|
"use strict";
|
|
30805
|
-
VERSION = true ? "0.1.
|
|
31115
|
+
VERSION = true ? "0.1.126" : "0.0.0-dev";
|
|
30806
31116
|
}
|
|
30807
31117
|
});
|
|
30808
31118
|
|
|
@@ -32220,7 +32530,7 @@ function createFileRegistry(...args2) {
|
|
|
32220
32530
|
if (seen.has(protoFileName)) {
|
|
32221
32531
|
continue;
|
|
32222
32532
|
}
|
|
32223
|
-
const dep =
|
|
32533
|
+
const dep = resolve14(protoFileName);
|
|
32224
32534
|
if (!dep) {
|
|
32225
32535
|
throw new Error(`Unable to resolve ${protoFileName}, imported by ${file2.name}`);
|
|
32226
32536
|
}
|
|
@@ -32234,7 +32544,7 @@ function createFileRegistry(...args2) {
|
|
|
32234
32544
|
return deps.concat(...deps.map(recurseDeps));
|
|
32235
32545
|
};
|
|
32236
32546
|
const input2 = args2[0];
|
|
32237
|
-
const
|
|
32547
|
+
const resolve14 = args2[1];
|
|
32238
32548
|
const seen = /* @__PURE__ */ new Set();
|
|
32239
32549
|
for (const file2 of [input2, ...recurseDeps(input2)].reverse()) {
|
|
32240
32550
|
addFile(file2, registry2);
|
|
@@ -34647,13 +34957,13 @@ async function Module2(moduleArg = {}) {
|
|
|
34647
34957
|
}
|
|
34648
34958
|
readAsync = /* @__PURE__ */ __name(async (url2) => {
|
|
34649
34959
|
if (isFileURI(url2)) {
|
|
34650
|
-
return new Promise((
|
|
34960
|
+
return new Promise((resolve14, reject) => {
|
|
34651
34961
|
var xhr = new XMLHttpRequest();
|
|
34652
34962
|
xhr.open("GET", url2, true);
|
|
34653
34963
|
xhr.responseType = "arraybuffer";
|
|
34654
34964
|
xhr.onload = () => {
|
|
34655
34965
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
34656
|
-
|
|
34966
|
+
resolve14(xhr.response);
|
|
34657
34967
|
return;
|
|
34658
34968
|
}
|
|
34659
34969
|
reject(xhr.status);
|
|
@@ -34849,9 +35159,9 @@ async function Module2(moduleArg = {}) {
|
|
|
34849
35159
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
34850
35160
|
var info2 = getWasmImports();
|
|
34851
35161
|
if (Module["instantiateWasm"]) {
|
|
34852
|
-
return new Promise((
|
|
35162
|
+
return new Promise((resolve14, reject) => {
|
|
34853
35163
|
Module["instantiateWasm"](info2, (mod, inst) => {
|
|
34854
|
-
|
|
35164
|
+
resolve14(receiveInstance(mod, inst));
|
|
34855
35165
|
});
|
|
34856
35166
|
});
|
|
34857
35167
|
}
|
|
@@ -36184,8 +36494,8 @@ async function Module2(moduleArg = {}) {
|
|
|
36184
36494
|
if (runtimeInitialized) {
|
|
36185
36495
|
moduleRtn = Module;
|
|
36186
36496
|
} else {
|
|
36187
|
-
moduleRtn = new Promise((
|
|
36188
|
-
readyPromiseResolve =
|
|
36497
|
+
moduleRtn = new Promise((resolve14, reject) => {
|
|
36498
|
+
readyPromiseResolve = resolve14;
|
|
36189
36499
|
readyPromiseReject = reject;
|
|
36190
36500
|
});
|
|
36191
36501
|
}
|
|
@@ -38734,9 +39044,9 @@ import { lstat, readFile as readFile4 } from "node:fs/promises";
|
|
|
38734
39044
|
import { join as join25 } from "node:path";
|
|
38735
39045
|
import { promisify } from "node:util";
|
|
38736
39046
|
function shardKeyOf(shard) {
|
|
38737
|
-
return `sha256:${
|
|
39047
|
+
return `sha256:${sha256Hex2(Buffer.from(`${shard.path}\0${shard.contentHash}\0${shard.precision}`, "utf8"))}`;
|
|
38738
39048
|
}
|
|
38739
|
-
function
|
|
39049
|
+
function sha256Hex2(bytes) {
|
|
38740
39050
|
return createHash6("sha256").update(bytes).digest("hex");
|
|
38741
39051
|
}
|
|
38742
39052
|
async function listTrackedFiles(repoRoot) {
|
|
@@ -38762,7 +39072,7 @@ async function hashRegularFile(repoRoot, path) {
|
|
|
38762
39072
|
try {
|
|
38763
39073
|
const stats = await lstat(absolute);
|
|
38764
39074
|
if (!stats.isFile()) return null;
|
|
38765
|
-
return `sha256:${
|
|
39075
|
+
return `sha256:${sha256Hex2(await readFile4(absolute))}`;
|
|
38766
39076
|
} catch (error62) {
|
|
38767
39077
|
if (error62 instanceof Error && "code" in error62 && error62.code === "ENOENT") return null;
|
|
38768
39078
|
throw error62;
|
|
@@ -38798,7 +39108,7 @@ async function buildSnapshot(options) {
|
|
|
38798
39108
|
if (languageForPath(path) === null) return { path, shard: null };
|
|
38799
39109
|
const bytes = await readFile4(join25(options.repoRoot, path));
|
|
38800
39110
|
if (bytes.byteLength > MAX_PARSE_BYTES) return { path, shard: null };
|
|
38801
|
-
const hash2 = `sha256:${
|
|
39111
|
+
const hash2 = `sha256:${sha256Hex2(bytes)}`;
|
|
38802
39112
|
if (hash2 !== hashes.get(path)) throw new Error(`${path} changed while the snapshot was being built`);
|
|
38803
39113
|
const shard = await parseDeclarations(path, bytes.toString("utf8"));
|
|
38804
39114
|
return { path, shard: shard ? { ...shard, contentHash: hash2 } : null };
|
|
@@ -38812,7 +39122,8 @@ async function buildSnapshot(options) {
|
|
|
38812
39122
|
const manifest = SnapshotManifest.parse({
|
|
38813
39123
|
schemaVersion: "1",
|
|
38814
39124
|
tenantId: options.tenantId,
|
|
38815
|
-
repository: options.repository,
|
|
39125
|
+
...options.repository !== void 0 ? { repository: options.repository } : {},
|
|
39126
|
+
...options.projectId !== void 0 ? { projectId: options.projectId } : {},
|
|
38816
39127
|
commitSha: options.commitSha,
|
|
38817
39128
|
...options.branch !== void 0 ? { branch: options.branch } : {},
|
|
38818
39129
|
indexers: [...indexers.values()].sort((a, b) => compareStrings(a.name, b.name) || compareStrings(a.version, b.version)),
|
|
@@ -38843,7 +39154,9 @@ async function uploadSnapshot(options) {
|
|
|
38843
39154
|
const doFetch = options.fetch ?? fetch;
|
|
38844
39155
|
const base4 = options.serviceUrl.replace(/\/+$/, "");
|
|
38845
39156
|
const manifest = SnapshotManifest.parse(options.manifest);
|
|
38846
|
-
const { tenantId, repository, commitSha } = manifest;
|
|
39157
|
+
const { tenantId, repository, projectId, commitSha } = manifest;
|
|
39158
|
+
const byProject = projectId !== void 0 && (repository === void 0 || options.byProject === true);
|
|
39159
|
+
if (!byProject && repository === void 0) throw new Error("the manifest names neither a repository nor a project");
|
|
38847
39160
|
const headers = { authorization: `Bearer ${options.token}`, "content-type": "application/json" };
|
|
38848
39161
|
const send2 = async (path, body2) => {
|
|
38849
39162
|
for (let attempt2 = 1; ; attempt2 += 1) {
|
|
@@ -38861,16 +39174,17 @@ async function uploadSnapshot(options) {
|
|
|
38861
39174
|
failure4 = error62 instanceof Error ? error62.message : String(error62);
|
|
38862
39175
|
if (attempt2 >= ATTEMPTS) throw new Error(`POST ${path} failed: ${failure4}`);
|
|
38863
39176
|
}
|
|
38864
|
-
await new Promise((
|
|
39177
|
+
await new Promise((resolve14) => setTimeout(resolve14, (options.retryDelayMs ?? 500) * attempt2));
|
|
38865
39178
|
}
|
|
38866
39179
|
};
|
|
38867
|
-
const
|
|
39180
|
+
const manifestPath = byProject ? codePaths.projectUploadManifest(tenantId, projectId ?? "") : codePaths.uploadManifest(tenantId, repository?.owner ?? "", repository?.name ?? "");
|
|
39181
|
+
const manifestResponse = await send2(manifestPath, JSON.stringify(manifest));
|
|
38868
39182
|
const { missing } = ManifestUploadResponse.parse(await manifestResponse.json());
|
|
38869
39183
|
const wanted = new Set(missing);
|
|
38870
39184
|
for (const hash2 of options.existing ?? []) wanted.delete(hash2);
|
|
38871
39185
|
const maxShards = options.maxBatchShards ?? MAX_BATCH_SHARDS;
|
|
38872
39186
|
const maxBytes = options.maxBatchBytes ?? MAX_BATCH_BYTES;
|
|
38873
|
-
const shardsPath = codePaths.uploadShards(tenantId, repository
|
|
39187
|
+
const shardsPath = byProject ? codePaths.projectUploadShards(tenantId, projectId ?? "", commitSha) : codePaths.uploadShards(tenantId, repository?.owner ?? "", repository?.name ?? "", commitSha);
|
|
38874
39188
|
let batch = [];
|
|
38875
39189
|
let batchBytes = 0;
|
|
38876
39190
|
let uploadedShards = 0;
|
|
@@ -38894,7 +39208,7 @@ async function uploadSnapshot(options) {
|
|
|
38894
39208
|
batchBytes += size;
|
|
38895
39209
|
}
|
|
38896
39210
|
await flush();
|
|
38897
|
-
await send2(codePaths.publish(tenantId, repository
|
|
39211
|
+
await send2(byProject ? codePaths.projectPublish(tenantId, projectId ?? "", commitSha) : codePaths.publish(tenantId, repository?.owner ?? "", repository?.name ?? "", commitSha), "{}");
|
|
38898
39212
|
return { missing: missing.length, uploadedShards, batches };
|
|
38899
39213
|
}
|
|
38900
39214
|
var MAX_BATCH_SHARDS, MAX_BATCH_BYTES, ATTEMPTS, HttpError;
|
|
@@ -38939,7 +39253,7 @@ var init_oidc = __esm({
|
|
|
38939
39253
|
// ../index-builder/src/run.ts
|
|
38940
39254
|
import { execFile as execFile2 } from "node:child_process";
|
|
38941
39255
|
import { mkdir as mkdir3, readdir as readdir4, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
38942
|
-
import { join as join26, resolve as
|
|
39256
|
+
import { join as join26, resolve as resolve12 } from "node:path";
|
|
38943
39257
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
38944
39258
|
import { promisify as promisify2 } from "node:util";
|
|
38945
39259
|
async function git3(root, args2) {
|
|
@@ -38960,9 +39274,11 @@ async function repositoryFromRemote(root) {
|
|
|
38960
39274
|
}
|
|
38961
39275
|
}
|
|
38962
39276
|
async function snapshotFromArgs(values, env) {
|
|
38963
|
-
const root =
|
|
38964
|
-
const
|
|
38965
|
-
if (!
|
|
39277
|
+
const root = resolve12(typeof values["root"] === "string" ? values["root"] : process.cwd());
|
|
39278
|
+
const projectId = typeof values["project"] === "string" ? values["project"] : void 0;
|
|
39279
|
+
if (projectId !== void 0 && !ProjectId.safeParse(projectId).success) throw new UsageError2(`--project must be a project identifier, got "${projectId}"`);
|
|
39280
|
+
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);
|
|
39281
|
+
if (!repoText && projectId === void 0) throw new UsageError2("cannot determine the repository; pass --project ID, or --repo owner/name");
|
|
38966
39282
|
const commit = (typeof values["commit"] === "string" ? values["commit"] : void 0) ?? env["GITHUB_SHA"] ?? await git3(root, ["rev-parse", "HEAD"]);
|
|
38967
39283
|
const branch = typeof values["branch"] === "string" ? values["branch"] : void 0;
|
|
38968
39284
|
const tenant = (typeof values["tenant"] === "string" ? values["tenant"] : void 0) ?? env["HARNESS_TENANT"];
|
|
@@ -38970,9 +39286,10 @@ async function snapshotFromArgs(values, env) {
|
|
|
38970
39286
|
const scip = Array.isArray(values["scip"]) ? values["scip"] : [];
|
|
38971
39287
|
return buildSnapshot({
|
|
38972
39288
|
repoRoot: root,
|
|
38973
|
-
scipFiles: scip.map((file2) =>
|
|
39289
|
+
scipFiles: scip.map((file2) => resolve12(file2)),
|
|
38974
39290
|
tenantId: tenant,
|
|
38975
|
-
repository: parseRepository(repoText),
|
|
39291
|
+
...repoText ? { repository: parseRepository(repoText) } : {},
|
|
39292
|
+
...projectId !== void 0 ? { projectId } : {},
|
|
38976
39293
|
commitSha: commit,
|
|
38977
39294
|
...branch !== void 0 ? { branch } : {}
|
|
38978
39295
|
});
|
|
@@ -38985,17 +39302,18 @@ async function runCli2(argv, env, out2 = console.log, err2 = console.error) {
|
|
|
38985
39302
|
const outDir = values.out;
|
|
38986
39303
|
if (!outDir) throw new UsageError2("build needs --out DIR");
|
|
38987
39304
|
const built = await snapshotFromArgs({ ...values, tenant: values.tenant ?? env["HARNESS_TENANT"] ?? "local" }, env);
|
|
38988
|
-
await writeSnapshot(
|
|
38989
|
-
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${
|
|
39305
|
+
await writeSnapshot(resolve12(outDir), built);
|
|
39306
|
+
out2(`built ${built.shards.length} shards (${built.uncovered.length} files uncovered) into ${resolve12(outDir)}`);
|
|
38990
39307
|
return 0;
|
|
38991
39308
|
}
|
|
38992
39309
|
if (command === "upload") {
|
|
38993
39310
|
const service = values.service;
|
|
38994
39311
|
if (!service) throw new UsageError2("upload needs --service URL");
|
|
38995
39312
|
const built = await snapshotFromArgs(values, env);
|
|
38996
|
-
const
|
|
38997
|
-
|
|
38998
|
-
|
|
39313
|
+
const byProject = values.project !== void 0;
|
|
39314
|
+
const token = !byProject && env["ACTIONS_ID_TOKEN_REQUEST_URL"] ? await getOidcToken(values.audience ?? service, env) : env["HARNESS_TOKEN"];
|
|
39315
|
+
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");
|
|
39316
|
+
const result = await uploadSnapshot({ serviceUrl: service, token, manifest: built.manifest, shards: built.shards, ...byProject ? { byProject: true } : {} });
|
|
38999
39317
|
out2(`published ${built.manifest.commitSha}: ${built.shards.length} shards, ${result.missing} new, ${result.batches} batches`);
|
|
39000
39318
|
return 0;
|
|
39001
39319
|
}
|
|
@@ -39030,10 +39348,12 @@ var init_run = __esm({
|
|
|
39030
39348
|
init_upload();
|
|
39031
39349
|
execFileAsync2 = promisify2(execFile2);
|
|
39032
39350
|
USAGE = `usage:
|
|
39033
|
-
mvrx-index build --scip FILE [--scip FILE ...] --out DIR [--repo owner/name] [--tenant ID] [--commit SHA] [--branch B] [--root DIR]
|
|
39034
|
-
mvrx-index upload --service URL --tenant ID --repo owner/name --commit SHA [--branch B] [--scip FILE ...] [--root DIR] [--audience URL]
|
|
39351
|
+
mvrx-index build --scip FILE [--scip FILE ...] --out DIR [--project ID | --repo owner/name] [--tenant ID] [--commit SHA] [--branch B] [--root DIR]
|
|
39352
|
+
mvrx-index upload --service URL --tenant ID (--project ID | --repo owner/name) --commit SHA [--branch B] [--scip FILE ...] [--root DIR] [--audience URL]
|
|
39035
39353
|
|
|
39036
|
-
|
|
39354
|
+
--project indexes an Overlane project (no GitHub repository needed) and uploads with HARNESS_TOKEN.
|
|
39355
|
+
--repo names a GitHub repository; in GitHub Actions the OIDC token is used when ACTIONS_ID_TOKEN_REQUEST_URL is set.
|
|
39356
|
+
Authentication for upload: HARNESS_TOKEN (always for --project), or the GitHub Actions OIDC token for --repo.
|
|
39037
39357
|
`;
|
|
39038
39358
|
UsageError2 = class extends Error {
|
|
39039
39359
|
};
|
|
@@ -39043,6 +39363,7 @@ Authentication for upload: the GitHub Actions OIDC token when ACTIONS_ID_TOKEN_R
|
|
|
39043
39363
|
service: { type: "string" },
|
|
39044
39364
|
tenant: { type: "string" },
|
|
39045
39365
|
repo: { type: "string" },
|
|
39366
|
+
project: { type: "string" },
|
|
39046
39367
|
commit: { type: "string" },
|
|
39047
39368
|
branch: { type: "string" },
|
|
39048
39369
|
root: { type: "string" },
|
|
@@ -42614,14 +42935,14 @@ function inputRequiredRoundsExceededMessage(method, maxRounds) {
|
|
|
42614
42935
|
return `Multi-round-trip request '${method}' still required input after ${maxRounds} rounds (inputRequired.maxRounds)`;
|
|
42615
42936
|
}
|
|
42616
42937
|
function sleep2(ms, signal) {
|
|
42617
|
-
return new Promise((
|
|
42938
|
+
return new Promise((resolve14, reject) => {
|
|
42618
42939
|
if (signal?.aborted) {
|
|
42619
42940
|
reject(signal.reason instanceof SdkError ? signal.reason : new SdkError(SdkErrorCode.RequestTimeout, String(signal.reason)));
|
|
42620
42941
|
return;
|
|
42621
42942
|
}
|
|
42622
42943
|
const timer = setTimeout(() => {
|
|
42623
42944
|
signal?.removeEventListener("abort", onAbort);
|
|
42624
|
-
|
|
42945
|
+
resolve14();
|
|
42625
42946
|
}, ms);
|
|
42626
42947
|
const onAbort = () => {
|
|
42627
42948
|
clearTimeout(timer);
|
|
@@ -44417,7 +44738,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
44417
44738
|
const flowStartedAt = Date.now();
|
|
44418
44739
|
let onAbort;
|
|
44419
44740
|
let cleanupMessageId;
|
|
44420
|
-
return new Promise((
|
|
44741
|
+
return new Promise((resolve14, reject) => {
|
|
44421
44742
|
const earlyReject = (error62) => {
|
|
44422
44743
|
reject(error62);
|
|
44423
44744
|
};
|
|
@@ -44485,7 +44806,7 @@ var init_src_CX2iR2pK = __esm({
|
|
|
44485
44806
|
}
|
|
44486
44807
|
if (decoded.kind === "invalid") return reject(decoded.error);
|
|
44487
44808
|
if (decoded.kind === "input_required") {
|
|
44488
|
-
if (options?.allowInputRequired === true) return
|
|
44809
|
+
if (options?.allowInputRequired === true) return resolve14(manualInputRequiredValue(decoded));
|
|
44489
44810
|
const flow = {
|
|
44490
44811
|
codec: codec2,
|
|
44491
44812
|
request,
|
|
@@ -44497,11 +44818,11 @@ var init_src_CX2iR2pK = __esm({
|
|
|
44497
44818
|
params
|
|
44498
44819
|
}, resultSchema2, legOptions)
|
|
44499
44820
|
};
|
|
44500
|
-
return
|
|
44821
|
+
return resolve14(this._resolveNonCompleteResult(decoded, flow));
|
|
44501
44822
|
}
|
|
44502
44823
|
const result = decoded.result;
|
|
44503
44824
|
validateStandardSchema(resultSchema2, result).then((parseResult) => {
|
|
44504
|
-
if (parseResult.success)
|
|
44825
|
+
if (parseResult.success) resolve14(parseResult.data);
|
|
44505
44826
|
else reject(new SdkError(SdkErrorCode.InvalidResult, `Invalid result for ${request.method}: ${parseResult.error}`));
|
|
44506
44827
|
}, reject);
|
|
44507
44828
|
});
|
|
@@ -47317,7 +47638,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47317
47638
|
ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
|
|
47318
47639
|
const schOrFunc = root.refs[ref];
|
|
47319
47640
|
if (schOrFunc) return schOrFunc;
|
|
47320
|
-
let _sch =
|
|
47641
|
+
let _sch = resolve14.call(this, root, ref);
|
|
47321
47642
|
if (_sch === void 0) {
|
|
47322
47643
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
47323
47644
|
const { schemaId } = this.opts;
|
|
@@ -47343,7 +47664,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47343
47664
|
function sameSchemaEnv(s1, s2) {
|
|
47344
47665
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
47345
47666
|
}
|
|
47346
|
-
function
|
|
47667
|
+
function resolve14(root, ref) {
|
|
47347
47668
|
let sch;
|
|
47348
47669
|
while (typeof (sch = this.refs[ref]) == "string") ref = sch;
|
|
47349
47670
|
return sch || this.schemas[ref] || resolveSchema.call(this, root, ref);
|
|
@@ -47793,7 +48114,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47793
48114
|
else if (typeof uri === "object") uri = parse5(serialize(uri, options), options);
|
|
47794
48115
|
return uri;
|
|
47795
48116
|
}
|
|
47796
|
-
function
|
|
48117
|
+
function resolve14(baseURI, relativeURI, options) {
|
|
47797
48118
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
47798
48119
|
const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
47799
48120
|
schemelessOptions.skipEscape = true;
|
|
@@ -47967,7 +48288,7 @@ var init_ajvProvider_CEoC_sr = __esm({
|
|
|
47967
48288
|
const fastUri = {
|
|
47968
48289
|
SCHEMES,
|
|
47969
48290
|
normalize,
|
|
47970
|
-
resolve:
|
|
48291
|
+
resolve: resolve14,
|
|
47971
48292
|
resolveComponent,
|
|
47972
48293
|
equal,
|
|
47973
48294
|
serialize,
|
|
@@ -53664,7 +53985,7 @@ var init_stdio = __esm({
|
|
|
53664
53985
|
}
|
|
53665
53986
|
send(message) {
|
|
53666
53987
|
if (this._closed) return Promise.reject(/* @__PURE__ */ new Error("StdioServerTransport is closed"));
|
|
53667
|
-
return new Promise((
|
|
53988
|
+
return new Promise((resolve14, reject) => {
|
|
53668
53989
|
const json2 = serializeMessage(message);
|
|
53669
53990
|
let settled = false;
|
|
53670
53991
|
const onError = (error62) => {
|
|
@@ -53679,14 +54000,14 @@ var init_stdio = __esm({
|
|
|
53679
54000
|
settled = true;
|
|
53680
54001
|
this._stdout.off("error", onError);
|
|
53681
54002
|
this._stdout.off("drain", onDrain);
|
|
53682
|
-
|
|
54003
|
+
resolve14();
|
|
53683
54004
|
};
|
|
53684
54005
|
this._stdout.once("error", onError);
|
|
53685
54006
|
if (this._stdout.write(json2)) {
|
|
53686
54007
|
if (settled) return;
|
|
53687
54008
|
settled = true;
|
|
53688
54009
|
this._stdout.off("error", onError);
|
|
53689
|
-
|
|
54010
|
+
resolve14();
|
|
53690
54011
|
} else if (!settled) this._stdout.once("drain", onDrain);
|
|
53691
54012
|
});
|
|
53692
54013
|
}
|
|
@@ -53740,14 +54061,14 @@ var init_stdio = __esm({
|
|
|
53740
54061
|
*/
|
|
53741
54062
|
async whenRequestsAnswered(timeoutMs) {
|
|
53742
54063
|
if (this._closed || this._pendingRequests.size === 0) return true;
|
|
53743
|
-
return await new Promise((
|
|
54064
|
+
return await new Promise((resolve14) => {
|
|
53744
54065
|
const waiter = () => {
|
|
53745
54066
|
clearTimeout(timer);
|
|
53746
|
-
|
|
54067
|
+
resolve14(true);
|
|
53747
54068
|
};
|
|
53748
54069
|
const timer = setTimeout(() => {
|
|
53749
54070
|
this._drainWaiters = this._drainWaiters.filter((pending) => pending !== waiter);
|
|
53750
|
-
|
|
54071
|
+
resolve14(false);
|
|
53751
54072
|
}, timeoutMs);
|
|
53752
54073
|
this._drainWaiters.push(waiter);
|
|
53753
54074
|
});
|
|
@@ -53972,9 +54293,9 @@ var init_config = __esm({
|
|
|
53972
54293
|
|
|
53973
54294
|
// ../code-shim/src/local.ts
|
|
53974
54295
|
import { readFileSync as readFileSync13, statSync as statSync2 } from "node:fs";
|
|
53975
|
-
import { isAbsolute as isAbsolute2, relative as relative3, resolve as
|
|
54296
|
+
import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolve13, sep as sep2 } from "node:path";
|
|
53976
54297
|
function resolveInside(root, path) {
|
|
53977
|
-
const absolute =
|
|
54298
|
+
const absolute = resolve13(root, path);
|
|
53978
54299
|
const rel = relative3(root, absolute);
|
|
53979
54300
|
if (rel.length === 0 || rel.startsWith("..") || isAbsolute2(rel)) return null;
|
|
53980
54301
|
return absolute;
|
|
@@ -55448,19 +55769,19 @@ function pkcePair() {
|
|
|
55448
55769
|
return { verifier, challenge: base64url3(createHash("sha256").update(verifier).digest()) };
|
|
55449
55770
|
}
|
|
55450
55771
|
function listen(server, port) {
|
|
55451
|
-
return new Promise((
|
|
55772
|
+
return new Promise((resolve14, reject) => {
|
|
55452
55773
|
const onError = (error62) => reject(error62);
|
|
55453
55774
|
server.once("error", onError);
|
|
55454
55775
|
server.listen(port, "127.0.0.1", () => {
|
|
55455
55776
|
server.off("error", onError);
|
|
55456
|
-
|
|
55777
|
+
resolve14();
|
|
55457
55778
|
});
|
|
55458
55779
|
});
|
|
55459
55780
|
}
|
|
55460
55781
|
async function startLoopback(preferredPort, state) {
|
|
55461
55782
|
let settle2;
|
|
55462
|
-
const code2 = new Promise((
|
|
55463
|
-
settle2 = { resolve:
|
|
55783
|
+
const code2 = new Promise((resolve14, reject) => {
|
|
55784
|
+
settle2 = { resolve: resolve14, reject };
|
|
55464
55785
|
});
|
|
55465
55786
|
code2.catch(() => void 0);
|
|
55466
55787
|
const server = createServer((request, response) => {
|
|
@@ -55648,7 +55969,7 @@ async function requireToken(deps, serviceUrl) {
|
|
|
55648
55969
|
|
|
55649
55970
|
// ../cli/src/project.ts
|
|
55650
55971
|
init_src();
|
|
55651
|
-
import { join as join5 } from "node:path";
|
|
55972
|
+
import { basename, join as join5 } from "node:path";
|
|
55652
55973
|
var REMOTE_PATTERNS = [
|
|
55653
55974
|
/^(?:https?|git|ssh):\/\/(?:[^@/]+@)?github\.com(?::\d+)?\/([^/]+)\/([^/]+?)(?:\.git)?\/?$/i,
|
|
55654
55975
|
/^(?:[^@/]+@)?github\.com:([^/]+)\/([^/]+?)(?:\.git)?\/?$/i
|
|
@@ -55663,21 +55984,49 @@ function parseGitHubRemote(url2) {
|
|
|
55663
55984
|
}
|
|
55664
55985
|
return null;
|
|
55665
55986
|
}
|
|
55666
|
-
|
|
55987
|
+
function parseProvider(value) {
|
|
55988
|
+
if (value === void 0) return void 0;
|
|
55989
|
+
if (PROVIDERS.includes(value)) return value;
|
|
55990
|
+
throw new UsageError(`--provider must be one of ${PROVIDERS.join(", ")}`, { hint: "overlane connect --provider overlane" });
|
|
55991
|
+
}
|
|
55992
|
+
function safeName(text) {
|
|
55993
|
+
const cleaned = text.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^[-.]+|-+$/g, "");
|
|
55994
|
+
return cleaned.slice(0, 100) === "" ? "project" : cleaned.slice(0, 100);
|
|
55995
|
+
}
|
|
55996
|
+
function projectLabel(project) {
|
|
55997
|
+
return project.repository === void 0 ? project.name : `${project.repository.owner}/${project.repository.name}`;
|
|
55998
|
+
}
|
|
55999
|
+
function projectSummary(project) {
|
|
56000
|
+
return { provider: project.provider, ...project.repository === void 0 ? {} : { owner: project.repository.owner }, name: project.repository?.name ?? project.name, root: project.root };
|
|
56001
|
+
}
|
|
56002
|
+
function projectRequest(project) {
|
|
56003
|
+
if (project.provider === "github" && project.repository !== void 0) {
|
|
56004
|
+
return { provider: "github", repository: project.repository, name: project.name };
|
|
56005
|
+
}
|
|
56006
|
+
return { provider: "overlane", name: project.name };
|
|
56007
|
+
}
|
|
56008
|
+
async function detectProject(deps, choice = {}) {
|
|
55667
56009
|
const top = await deps.exec("git", ["rev-parse", "--show-toplevel"], { cwd: deps.paths.cwd });
|
|
55668
56010
|
if (top.code !== 0 || top.stdout.trim().length === 0) {
|
|
55669
|
-
throw new UsageError("not inside a git repository (or git is not installed); run overlane from
|
|
56011
|
+
throw new UsageError("not inside a git repository (or git is not installed); run overlane from your project folder (`git init` makes one)");
|
|
55670
56012
|
}
|
|
55671
56013
|
const root = top.stdout.trim();
|
|
56014
|
+
if (choice.name !== void 0 && (choice.name.trim().length === 0 || choice.name.length > 100)) throw new UsageError("--name must be 1 to 100 characters");
|
|
55672
56015
|
const remote = await deps.exec("git", ["remote", "get-url", "origin"], { cwd: root });
|
|
55673
|
-
|
|
55674
|
-
|
|
56016
|
+
const originUrl = remote.code === 0 ? remote.stdout.trim() : "";
|
|
56017
|
+
const github = originUrl.length === 0 ? null : parseGitHubRemote(originUrl);
|
|
56018
|
+
const wanted = choice.provider;
|
|
56019
|
+
if (wanted === "gitlab") {
|
|
56020
|
+
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" });
|
|
55675
56021
|
}
|
|
55676
|
-
|
|
55677
|
-
|
|
55678
|
-
throw new UsageError(
|
|
56022
|
+
if (wanted === "github" && github === null) {
|
|
56023
|
+
const why = originUrl.length === 0 ? "this repository has no `origin` remote" : `origin is ${originUrl}, which is not a github.com repository`;
|
|
56024
|
+
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" });
|
|
55679
56025
|
}
|
|
55680
|
-
|
|
56026
|
+
if (github !== null && wanted !== "overlane") {
|
|
56027
|
+
return { root, provider: "github", name: choice.name ?? github.name, repository: github };
|
|
56028
|
+
}
|
|
56029
|
+
return { root, provider: "overlane", name: choice.name ?? (basename(root).slice(0, 100) || "project") };
|
|
55681
56030
|
}
|
|
55682
56031
|
async function headCommit(deps, root) {
|
|
55683
56032
|
const head = await deps.exec("git", ["rev-parse", "HEAD"], { cwd: root });
|
|
@@ -55917,7 +56266,7 @@ var DEFAULT_SERVICE_URL = "https://api.overlane.dev";
|
|
|
55917
56266
|
var CONNECT_STEPS = {
|
|
55918
56267
|
"sign-up": "sign in through the browser (OAuth with PKCE), or use HARNESS_TOKEN",
|
|
55919
56268
|
agents: "register the plugin with each agent's own commands (no vendor token is asked for)",
|
|
55920
|
-
repo: "bind this
|
|
56269
|
+
repo: "bind this project to the service: a native Overlane project by default, or your GitHub repository",
|
|
55921
56270
|
"first-task": 'start your first task with `overlane task new "<title>"`',
|
|
55922
56271
|
"first-review": "read the first review in the web app",
|
|
55923
56272
|
invite: "invite teammates from the web app (optional, never blocks)"
|
|
@@ -55966,10 +56315,9 @@ async function connect(deps, options) {
|
|
|
55966
56315
|
if (active.length === 0) {
|
|
55967
56316
|
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" });
|
|
55968
56317
|
}
|
|
55969
|
-
const project = await detectProject(deps);
|
|
56318
|
+
const project = await detectProject(deps, { name: options.name, provider: options.provider });
|
|
55970
56319
|
const root = project.root;
|
|
55971
|
-
|
|
55972
|
-
say(deps, `Project: ${repository.owner}/${repository.name} at ${root}`);
|
|
56320
|
+
say(deps, `Project: ${projectLabel(project)}${project.provider === "overlane" ? " (native Overlane project; no GitHub account needed)" : " (GitHub)"} at ${root}`);
|
|
55973
56321
|
const existing = readBindingFile(root);
|
|
55974
56322
|
const serviceInput = options.service ?? deps.env["HARNESS_SERVICE_URL"] ?? (existing.kind === "ok" ? existing.binding.serviceUrl : DEFAULT_SERVICE_URL);
|
|
55975
56323
|
if (serviceInput === void 0 || serviceInput.length === 0) {
|
|
@@ -56017,7 +56365,7 @@ async function connect(deps, options) {
|
|
|
56017
56365
|
say(deps, `Steps (the same names as the web onboarding): ${STEP_NAMES.join(", ")}`);
|
|
56018
56366
|
say(deps, "Plan");
|
|
56019
56367
|
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)}`}`);
|
|
56020
|
-
say(deps, ` service: GET ${serviceUrl}/v1/me, then create or look up the project
|
|
56368
|
+
say(deps, ` service: GET ${serviceUrl}/v1/me, then create or look up the project ${projectLabel(project)}`);
|
|
56021
56369
|
for (const step2 of steps) say(deps, ` ${step2.agent}: ${step2.summary}
|
|
56022
56370
|
$ ${formatCommand(step2)}`);
|
|
56023
56371
|
if (codexEdit !== null) {
|
|
@@ -56045,7 +56393,7 @@ async function connect(deps, options) {
|
|
|
56045
56393
|
service: serviceUrl,
|
|
56046
56394
|
requests: [
|
|
56047
56395
|
{ method: "GET", path: apiPaths.whoami, note: existingToken === null ? "after browser sign-in" : "with the stored token" },
|
|
56048
|
-
{ method: "POST", path: apiPaths.projects("<tenantId from /v1/me>"), body:
|
|
56396
|
+
{ method: "POST", path: apiPaths.projects("<tenantId from /v1/me>"), body: projectRequest(project), note: "creates the project or returns the existing one" },
|
|
56049
56397
|
{ method: "GET", path: releasePaths.publicKey(), note: "the release-signing key; a failure here does not fail connect" }
|
|
56050
56398
|
],
|
|
56051
56399
|
commands: steps.map((step2) => formatCommand(step2)),
|
|
@@ -56065,7 +56413,7 @@ async function connect(deps, options) {
|
|
|
56065
56413
|
}
|
|
56066
56414
|
if (!await deps.confirm("Apply this plan?")) {
|
|
56067
56415
|
say(deps, "Cancelled; nothing changed.");
|
|
56068
|
-
return { data: emptyResult(
|
|
56416
|
+
return { data: emptyResult(project, serviceUrl, infos, true) };
|
|
56069
56417
|
}
|
|
56070
56418
|
}
|
|
56071
56419
|
const token = await ensureToken(deps, serviceUrl);
|
|
@@ -56074,8 +56422,7 @@ async function connect(deps, options) {
|
|
|
56074
56422
|
const wrote = [];
|
|
56075
56423
|
const applied = [];
|
|
56076
56424
|
const me = await whoAmI(deps, serviceUrl, token.token);
|
|
56077
|
-
const
|
|
56078
|
-
const record3 = await createProject(deps, serviceUrl, me.tenantId, token.token, request);
|
|
56425
|
+
const record3 = await createProject(deps, serviceUrl, me.tenantId, token.token, projectRequest(project));
|
|
56079
56426
|
if (record3.tenantId !== me.tenantId) throw new CliError("the service returned a project for another tenant");
|
|
56080
56427
|
const servicePublicKey = await fetchServicePublicKey(deps, serviceUrl, token.token) ?? (existing.kind === "ok" ? existing.binding.servicePublicKey ?? null : null);
|
|
56081
56428
|
const binding = ProjectBinding.parse({
|
|
@@ -56114,7 +56461,7 @@ async function connect(deps, options) {
|
|
|
56114
56461
|
owned.binding = true;
|
|
56115
56462
|
if (excludeNeeded && await addExclude(deps, root)) owned.excludeLine = true;
|
|
56116
56463
|
say(deps, `[repo] ${CONNECT_STEPS.repo}: done`);
|
|
56117
|
-
const next = await reportStep(deps, serviceUrl, token.token, me.tenantId, "repo", { repo:
|
|
56464
|
+
const next = await reportStep(deps, serviceUrl, token.token, me.tenantId, "repo", { repo: repoChoice(project) });
|
|
56118
56465
|
if (next !== null) say(deps, `Next in onboarding: ${next === "repo" ? "first-task" : next} (${CONNECT_STEPS[next === "repo" ? "first-task" : next]})`);
|
|
56119
56466
|
} finally {
|
|
56120
56467
|
if (previousOwned !== null || owned.binding || owned.claude !== void 0 || owned.codex !== void 0) writeOwned(root, owned);
|
|
@@ -56128,7 +56475,7 @@ async function connect(deps, options) {
|
|
|
56128
56475
|
for (const line2 of renderReports(reports)) say(deps, ` ${line2}`);
|
|
56129
56476
|
return {
|
|
56130
56477
|
data: {
|
|
56131
|
-
project:
|
|
56478
|
+
project: projectSummary(project),
|
|
56132
56479
|
serviceUrl,
|
|
56133
56480
|
tenantId: binding.tenantId,
|
|
56134
56481
|
projectId: binding.projectId,
|
|
@@ -56142,9 +56489,13 @@ async function connect(deps, options) {
|
|
|
56142
56489
|
}
|
|
56143
56490
|
};
|
|
56144
56491
|
}
|
|
56145
|
-
function
|
|
56492
|
+
function repoChoice(project) {
|
|
56493
|
+
if (project.provider === "github" && project.repository !== void 0) return { provider: "github", owner: project.repository.owner, name: project.repository.name };
|
|
56494
|
+
return { provider: "overlane", owner: "native", name: safeName(project.name) };
|
|
56495
|
+
}
|
|
56496
|
+
function emptyResult(project, serviceUrl, infos, cancelled) {
|
|
56146
56497
|
return {
|
|
56147
|
-
project:
|
|
56498
|
+
project: projectSummary(project),
|
|
56148
56499
|
serviceUrl,
|
|
56149
56500
|
credentials: "unchanged",
|
|
56150
56501
|
agents: infos.map((info2) => ({ agent: info2.agent, installed: info2.installed, detail: info2.detail })),
|
|
@@ -56207,8 +56558,8 @@ function withTimeout(deps, ms) {
|
|
|
56207
56558
|
}
|
|
56208
56559
|
async function attempt(deps, ms, work) {
|
|
56209
56560
|
let timer;
|
|
56210
|
-
const deadline = new Promise((
|
|
56211
|
-
timer = setTimeout(() =>
|
|
56561
|
+
const deadline = new Promise((resolve14) => {
|
|
56562
|
+
timer = setTimeout(() => resolve14("unreachable"), ms);
|
|
56212
56563
|
});
|
|
56213
56564
|
try {
|
|
56214
56565
|
return await Promise.race([work(withTimeout(deps, ms)).catch((error62) => error62 instanceof ServiceError && error62.exit === EXIT.auth ? "unauthenticated" : "unreachable"), deadline]);
|
|
@@ -57347,13 +57698,13 @@ async function readPlan(repoDir) {
|
|
|
57347
57698
|
init_src();
|
|
57348
57699
|
init_zod();
|
|
57349
57700
|
import { mkdir as mkdir2, readdir as readdir3, readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
57350
|
-
import { basename as
|
|
57701
|
+
import { basename as basename3, dirname as dirname7, join as join17, resolve as resolve6 } from "node:path";
|
|
57351
57702
|
|
|
57352
57703
|
// ../kit/src/detect.ts
|
|
57353
57704
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
57354
57705
|
init_src();
|
|
57355
57706
|
import { readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
|
|
57356
|
-
import { basename, join as join16, resolve as resolve5 } from "node:path";
|
|
57707
|
+
import { basename as basename2, join as join16, resolve as resolve5 } from "node:path";
|
|
57357
57708
|
var KINDS = ["typecheck", "lint", "build", "test"];
|
|
57358
57709
|
async function readOptional(file2) {
|
|
57359
57710
|
try {
|
|
@@ -57498,7 +57849,7 @@ async function draftPlanForExisting(repoDir, opts = {}) {
|
|
|
57498
57849
|
} catch {
|
|
57499
57850
|
}
|
|
57500
57851
|
}
|
|
57501
|
-
const name2 = (opts.name ?? pkgName ??
|
|
57852
|
+
const name2 = (opts.name ?? pkgName ?? basename2(root)).slice(0, 100);
|
|
57502
57853
|
const milestone = opts.milestoneId ?? "M1";
|
|
57503
57854
|
const allowedPaths = opts.allowedPaths ?? ["."];
|
|
57504
57855
|
const tasks = [];
|
|
@@ -57696,7 +58047,7 @@ async function importSpecKit(repoDir) {
|
|
|
57696
58047
|
const constitution = await findConstitution(root);
|
|
57697
58048
|
const parsedConstitution = constitution ? parseConstitution(constitution.text) : void 0;
|
|
57698
58049
|
const firstInput = /\*\*Input\*\*:\s*User description:\s*"(.*)"/.exec(features[0]?.specText ?? "")?.[1];
|
|
57699
|
-
const name2 = (parsedConstitution?.name ??
|
|
58050
|
+
const name2 = (parsedConstitution?.name ?? basename3(root)).slice(0, 100);
|
|
57700
58051
|
const goal = (parsedConstitution?.goal ?? firstInput ?? `Deliver ${name2}.`).slice(0, 2e3);
|
|
57701
58052
|
const multi = features.length > 1;
|
|
57702
58053
|
const counts2 = /* @__PURE__ */ new Map();
|
|
@@ -59069,7 +59420,7 @@ var contextCommand = defineCommand({
|
|
|
59069
59420
|
init_src();
|
|
59070
59421
|
init_zod();
|
|
59071
59422
|
import { existsSync as existsSync4, readFileSync as readFileSync7 } from "node:fs";
|
|
59072
|
-
import { basename as
|
|
59423
|
+
import { basename as basename4, resolve as resolve7 } from "node:path";
|
|
59073
59424
|
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)" };
|
|
59074
59425
|
var TEAM_FLAG = { name: "team", type: "string", value: "TENANT_ID", description: "The team (tenant) to act on (default: the one your token belongs to)" };
|
|
59075
59426
|
var ECOSYSTEM_FLAG = { name: "ecosystem", type: "string", enum: DOCS_ECOSYSTEMS, default: "npm", description: "Where the library is published" };
|
|
@@ -59181,7 +59532,7 @@ function readLockfiles(paths) {
|
|
|
59181
59532
|
const files = paths.length > 0 ? paths : DEFAULT_LOCKFILES.filter((name2) => existsSync4(resolve7(name2)));
|
|
59182
59533
|
if (files.length === 0) throw new UsageError("no lockfile found in this directory", { hint: "overlane lib pins --project <id> --lockfile pnpm-lock.yaml" });
|
|
59183
59534
|
return files.map((file2) => {
|
|
59184
|
-
const kind = LOCKFILES.find(([pattern]) => pattern.test(
|
|
59535
|
+
const kind = LOCKFILES.find(([pattern]) => pattern.test(basename4(file2)))?.[1];
|
|
59185
59536
|
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" });
|
|
59186
59537
|
try {
|
|
59187
59538
|
return { kind, content: readFileSync7(resolve7(file2), "utf8") };
|
|
@@ -59277,7 +59628,7 @@ var libAddCommand = defineCommand({
|
|
|
59277
59628
|
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" });
|
|
59278
59629
|
const pages = files.map((file2) => {
|
|
59279
59630
|
try {
|
|
59280
|
-
return { title:
|
|
59631
|
+
return { title: basename4(file2), text: readFileSync7(resolve7(file2), "utf8") };
|
|
59281
59632
|
} catch {
|
|
59282
59633
|
throw new UsageError(`cannot read ${file2}`);
|
|
59283
59634
|
}
|
|
@@ -59353,7 +59704,7 @@ async function post(deps, base4, path, body2) {
|
|
|
59353
59704
|
return { status: response.status, json: json2 };
|
|
59354
59705
|
}
|
|
59355
59706
|
function sleep(ms) {
|
|
59356
|
-
return new Promise((
|
|
59707
|
+
return new Promise((resolve14) => setTimeout(resolve14, ms));
|
|
59357
59708
|
}
|
|
59358
59709
|
async function deviceLogin(deps, service, options) {
|
|
59359
59710
|
const started = await post(deps, service, "/auth/device", {});
|
|
@@ -60951,6 +61302,7 @@ var loopCommands = [loopListCommand, loopNewCommand, loopSetCommand, loopFireCom
|
|
|
60951
61302
|
// ../cli/src/commands/review.ts
|
|
60952
61303
|
init_src();
|
|
60953
61304
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
61305
|
+
import { resolve as resolve9 } from "node:path";
|
|
60954
61306
|
var common7 = { needsAuth: true, needsNetwork: true };
|
|
60955
61307
|
var requestId7 = () => `cli-${randomUUID7()}`;
|
|
60956
61308
|
async function connected3(inv) {
|
|
@@ -60969,9 +61321,38 @@ async function repositoryOf(inv) {
|
|
|
60969
61321
|
}
|
|
60970
61322
|
const remote = await inv.deps.exec("git", ["remote", "get-url", "origin"], { cwd: inv.deps.paths.cwd });
|
|
60971
61323
|
const match = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?\s*$/.exec(remote.stdout.trim());
|
|
60972
|
-
if (remote.code !== 0 || match === null) throw new UsageError("could not read
|
|
61324
|
+
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" });
|
|
60973
61325
|
return `${match[1]}/${match[2]}`;
|
|
60974
61326
|
}
|
|
61327
|
+
async function diffOf(inv) {
|
|
61328
|
+
const flag = textFlag(inv, "diff");
|
|
61329
|
+
const pull = inv.positionals[0];
|
|
61330
|
+
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" });
|
|
61331
|
+
let from;
|
|
61332
|
+
let text;
|
|
61333
|
+
if (flag !== void 0) {
|
|
61334
|
+
if (flag === "-") {
|
|
61335
|
+
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" });
|
|
61336
|
+
from = "standard input";
|
|
61337
|
+
text = await inv.deps.stdin.read();
|
|
61338
|
+
} else {
|
|
61339
|
+
from = flag;
|
|
61340
|
+
text = readText(resolve9(inv.deps.paths.cwd, flag));
|
|
61341
|
+
if (text === null) throw new UsageError(`could not read the diff file ${flag}`, { hint: "git diff > change.patch && overlane review run --diff change.patch" });
|
|
61342
|
+
}
|
|
61343
|
+
} else if (pull === void 0) {
|
|
61344
|
+
if (inv.deps.stdin === void 0 || inv.deps.stdin.isTTY) {
|
|
61345
|
+
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" });
|
|
61346
|
+
}
|
|
61347
|
+
from = "standard input";
|
|
61348
|
+
text = await inv.deps.stdin.read();
|
|
61349
|
+
} else {
|
|
61350
|
+
return void 0;
|
|
61351
|
+
}
|
|
61352
|
+
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" });
|
|
61353
|
+
if (text.length > MAX_PATCH_BYTES) throw new UsageError(`the diff is larger than ${MAX_PATCH_BYTES} characters; review it in parts`);
|
|
61354
|
+
return { text, from };
|
|
61355
|
+
}
|
|
60975
61356
|
function id(inv, what) {
|
|
60976
61357
|
const value = inv.positionals[0];
|
|
60977
61358
|
if (value === void 0) throw new UsageError(`${what} needs a finding ID`, { hint: "overlane review findings" });
|
|
@@ -60980,22 +61361,39 @@ function id(inv, what) {
|
|
|
60980
61361
|
var FINDING_LINE = (finding) => `${finding.status.padEnd(9)} ${finding.severity.padEnd(8)} ${finding.path}:${finding.line} ${finding.rule ?? "see reason"} ${finding.id}`;
|
|
60981
61362
|
var reviewRunCommand = defineCommand({
|
|
60982
61363
|
path: ["review", "run"],
|
|
60983
|
-
summary: "Review a
|
|
60984
|
-
description: "Runs the review service
|
|
60985
|
-
args: [{ name: "pull", required:
|
|
60986
|
-
flags: [
|
|
60987
|
-
|
|
61364
|
+
summary: "Review a diff (no repository needed) or a pull request now and report the findings",
|
|
61365
|
+
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.",
|
|
61366
|
+
args: [{ name: "pull", required: false, description: "A pull request number (omit it to review a diff)" }],
|
|
61367
|
+
flags: [
|
|
61368
|
+
{ name: "diff", type: "string", value: "FILE", description: "Review this unified diff (a file, or - for standard input); needs no repository" },
|
|
61369
|
+
{ name: "title", type: "string", value: "TEXT", description: "A title for the diff, shown in the summary" },
|
|
61370
|
+
{ name: "label", type: "string", value: "NAME", description: "Names the diff so a re-review of the same change merges its findings (default: patch)" },
|
|
61371
|
+
{ name: "repo", type: "string", value: "OWNER/NAME", description: "For a pull request number: the GitHub repository (default: the origin remote); not used with --diff" }
|
|
61372
|
+
],
|
|
61373
|
+
examples: ["overlane review run --diff change.patch", "overlane review run --diff -", "overlane review run 7 --repo acme/app --dry-run"],
|
|
60988
61374
|
effect: "write",
|
|
60989
61375
|
...common7,
|
|
60990
|
-
keywords: ["code review", "review
|
|
61376
|
+
keywords: ["code review", "review diff", "review patch", "review pull request", "review pr", "check my pr", "findings"],
|
|
60991
61377
|
result: withDryRun(ReviewRunResponse),
|
|
60992
61378
|
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)] : [],
|
|
60993
61379
|
handler: async (inv) => {
|
|
61380
|
+
const diff = await diffOf(inv);
|
|
61381
|
+
if (diff !== void 0) {
|
|
61382
|
+
const title = textFlag(inv, "title");
|
|
61383
|
+
const label = textFlag(inv, "label");
|
|
61384
|
+
const source = { kind: "patch", diff: diff.text, ...title === void 0 ? {} : { title }, ...label === void 0 ? {} : { label } };
|
|
61385
|
+
const patchBody = { requestId: requestId7(), trigger: "manual", source };
|
|
61386
|
+
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");
|
|
61387
|
+
const sent = await connected3(inv);
|
|
61388
|
+
const patched = await sent.call(ReviewRunResponse, "POST", reviewPaths.runs(sent.tenantId, sent.projectId), patchBody);
|
|
61389
|
+
if (patched.run.status === "partial") say(inv.deps, "Partial review: the token cap was reached. The summary lists what was not covered.");
|
|
61390
|
+
return { data: patched };
|
|
61391
|
+
}
|
|
60994
61392
|
const number4 = Number(inv.positionals[0]);
|
|
60995
|
-
if (!Number.isInteger(number4) || number4 < 1) throw new UsageError("run needs a pull request number", { hint: "overlane review run
|
|
61393
|
+
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" });
|
|
60996
61394
|
const repository = await repositoryOf(inv);
|
|
60997
61395
|
const body2 = { requestId: requestId7(), trigger: "manual", source: { kind: "github", repository, number: number4 } };
|
|
60998
|
-
if (inv.dryRun) return planned3(inv, "POST", reviewPaths.runs, body2, "reads the pull request through the GitHub
|
|
61396
|
+
if (inv.dryRun) return planned3(inv, "POST", reviewPaths.runs, body2, "reads the pull request through the GitHub connection and runs the review");
|
|
60999
61397
|
const { call: call2, tenantId, projectId } = await connected3(inv);
|
|
61000
61398
|
const result = await call2(ReviewRunResponse, "POST", reviewPaths.runs(tenantId, projectId), body2);
|
|
61001
61399
|
if (result.run.status === "partial") say(inv.deps, "Partial review: the token cap was reached. The summary lists what was not covered.");
|
|
@@ -61106,7 +61504,7 @@ var reviewSettingsCommand = defineCommand({
|
|
|
61106
61504
|
var reviewSettingsSetCommand = defineCommand({
|
|
61107
61505
|
path: ["review", "settings", "set"],
|
|
61108
61506
|
summary: "Change the review mode, token cap or skip patterns",
|
|
61109
|
-
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.",
|
|
61507
|
+
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.",
|
|
61110
61508
|
flags: [
|
|
61111
61509
|
{ name: "mode", type: "string", enum: ["log_only", "comments"], description: "log_only records findings only; comments posts them" },
|
|
61112
61510
|
{ name: "token-cap", type: "string", value: "N", description: "Most tokens one pull request may use (1,000 to 2,000,000)" },
|
|
@@ -61192,7 +61590,7 @@ function rootHelp(specs, version2) {
|
|
|
61192
61590
|
const lines = [
|
|
61193
61591
|
ROOT_FIRST_LINE,
|
|
61194
61592
|
"",
|
|
61195
|
-
`overlane${version2 === "" ? "" : ` ${version2}`} - connect a
|
|
61593
|
+
`overlane${version2 === "" ? "" : ` ${version2}`} - connect a project to Overlane (no GitHub account needed), and run its tasks`,
|
|
61196
61594
|
"",
|
|
61197
61595
|
"Usage: overlane <command> [flags] overlane <command> --help overlane schema <command>",
|
|
61198
61596
|
"",
|
|
@@ -61503,7 +61901,7 @@ init_zod();
|
|
|
61503
61901
|
// ../cli/src/connect-result.ts
|
|
61504
61902
|
init_zod();
|
|
61505
61903
|
var ConnectResult = external_exports.object({
|
|
61506
|
-
project: external_exports.object({ owner: external_exports.string(), name: external_exports.string(), root: external_exports.string() }),
|
|
61904
|
+
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() }),
|
|
61507
61905
|
serviceUrl: external_exports.string(),
|
|
61508
61906
|
tenantId: external_exports.string().optional(),
|
|
61509
61907
|
projectId: external_exports.string().optional(),
|
|
@@ -61648,10 +62046,10 @@ async function disconnect(deps, options) {
|
|
|
61648
62046
|
}
|
|
61649
62047
|
|
|
61650
62048
|
// ../cli/src/doctor.ts
|
|
61651
|
-
import { resolve as
|
|
62049
|
+
import { resolve as resolve10 } from "node:path";
|
|
61652
62050
|
init_zod();
|
|
61653
62051
|
var DoctorResult = external_exports.object({
|
|
61654
|
-
project: external_exports.object({ owner: external_exports.string(), name: external_exports.string(), root: external_exports.string() }),
|
|
62052
|
+
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() }),
|
|
61655
62053
|
binding: external_exports.enum(["ok", "missing", "invalid"]),
|
|
61656
62054
|
service: external_exports.string().optional(),
|
|
61657
62055
|
credentials: external_exports.string().optional(),
|
|
@@ -61668,13 +62066,13 @@ async function doctor(deps, options) {
|
|
|
61668
62066
|
const root = project.root;
|
|
61669
62067
|
const binding = readBindingFile(root);
|
|
61670
62068
|
const owned = readOwned(root);
|
|
61671
|
-
const marketplaceRoot2 =
|
|
62069
|
+
const marketplaceRoot2 = resolve10(options.marketplaceRoot ?? owned?.marketplaceRoot ?? deps.paths.defaultMarketplaceRoot);
|
|
61672
62070
|
const infos = await detectAgents(deps, options.agents, root);
|
|
61673
62071
|
let service = "reachable";
|
|
61674
62072
|
let hasToken = false;
|
|
61675
62073
|
let credentials;
|
|
61676
62074
|
let checked2 = false;
|
|
61677
|
-
say(deps, `Project: ${project
|
|
62075
|
+
say(deps, `Project: ${projectLabel(project)} at ${root}`);
|
|
61678
62076
|
if (binding.kind === "ok") {
|
|
61679
62077
|
const { serviceUrl } = binding.binding;
|
|
61680
62078
|
const token = await findToken(deps, serviceUrl);
|
|
@@ -61698,7 +62096,7 @@ async function doctor(deps, options) {
|
|
|
61698
62096
|
const installedStates = reports.filter((report2, index) => infos[index]?.installed === true).map((report2) => report2.state);
|
|
61699
62097
|
const ready = installedStates.length > 0 && installedStates.every((state) => state === "ready");
|
|
61700
62098
|
const data = {
|
|
61701
|
-
project:
|
|
62099
|
+
project: projectSummary(project),
|
|
61702
62100
|
binding: binding.kind,
|
|
61703
62101
|
...binding.kind === "ok" ? { service: binding.binding.serviceUrl } : {},
|
|
61704
62102
|
...credentials === void 0 ? {} : { credentials },
|
|
@@ -61818,7 +62216,7 @@ function newPlan(name2, goal, withCiTask) {
|
|
|
61818
62216
|
id: "T001",
|
|
61819
62217
|
title: "Add CI",
|
|
61820
62218
|
milestone: "M1",
|
|
61821
|
-
outcome: "A GitHub Actions
|
|
62219
|
+
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.",
|
|
61822
62220
|
allowedPaths: [".github/**"],
|
|
61823
62221
|
acceptance: ["A workflow in .github/workflows runs on push and pull_request"],
|
|
61824
62222
|
verification: ['test -n "$(ls .github/workflows/*.yml .github/workflows/*.yaml 2>/dev/null)"'],
|
|
@@ -61857,7 +62255,8 @@ function schedulerSetup(projectId) {
|
|
|
61857
62255
|
}
|
|
61858
62256
|
async function connectKit(deps, options) {
|
|
61859
62257
|
if (options.mode === "new" && (options.goal === void 0 || options.goal.trim().length === 0)) throw new UsageError("--kit new needs --goal TEXT");
|
|
61860
|
-
const
|
|
62258
|
+
const project = await detectProject(deps, { name: options.name, provider: options.provider });
|
|
62259
|
+
const { root } = project;
|
|
61861
62260
|
if (await headCommit(deps, root) === null) throw new CliError("the repository has no commit yet; make an initial commit first");
|
|
61862
62261
|
const planDir = join22(root, PLAN_DIR);
|
|
61863
62262
|
const planExists = existsSync6(join22(planDir, "project.md"));
|
|
@@ -61869,7 +62268,7 @@ async function connectKit(deps, options) {
|
|
|
61869
62268
|
plan3 = await readPlan(root);
|
|
61870
62269
|
planSource = `${PLAN_DIR}/ already exists; kept as it is`;
|
|
61871
62270
|
} else if (options.mode === "new") {
|
|
61872
|
-
plan3 = newPlan(
|
|
62271
|
+
plan3 = newPlan(project.name, options.goal ?? "", !ciExists);
|
|
61873
62272
|
planSource = "minimal plan from --goal";
|
|
61874
62273
|
} else if (hasSpecKit(root)) {
|
|
61875
62274
|
plan3 = await importSpecKit(root);
|
|
@@ -61892,7 +62291,7 @@ async function connectKit(deps, options) {
|
|
|
61892
62291
|
const touched = [...INSTRUCTION_FILES, CI_FILE];
|
|
61893
62292
|
const unsaved = await dirty(deps, root, touched);
|
|
61894
62293
|
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`);
|
|
61895
|
-
say(deps, `Kit setup (${options.mode}) for ${
|
|
62294
|
+
say(deps, `Kit setup (${options.mode}) for ${projectLabel(project)}`);
|
|
61896
62295
|
say(deps, ` branch: create ${KIT_BRANCH}`);
|
|
61897
62296
|
say(deps, ` plan: ${planSource} (${plan3.milestones.length} milestone(s), ${plan3.tasks.length} task(s))${planExists ? "" : `, written to ${PLAN_DIR}/`}`);
|
|
61898
62297
|
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("; ")})`);
|
|
@@ -61969,7 +62368,7 @@ async function connectKit(deps, options) {
|
|
|
61969
62368
|
say(deps, `Run policy set (build-ahead limit ${firstMilestone}).`);
|
|
61970
62369
|
const synced = await kit.syncPlan(PlanSyncRequest.parse({ requestId: `cli-${randomUUID8()}`, sourceCommit: sha, plan: await readPlan(root) }));
|
|
61971
62370
|
say(deps, `Plan synced: ${synced.created.length} created, ${synced.updated.length} updated, ${synced.unchanged.length} unchanged, ${synced.deferred.length} deferred.`);
|
|
61972
|
-
const pr = await openPullRequest(deps, root,
|
|
62371
|
+
const pr = await openPullRequest(deps, root, project.name);
|
|
61973
62372
|
say(deps);
|
|
61974
62373
|
for (const line2 of schedulerSetup(binding.binding.projectId)) say(deps, line2);
|
|
61975
62374
|
return {
|
|
@@ -62015,18 +62414,20 @@ var AGENTS_FLAG = { name: "agents", type: "string", value: "claude,codex", descr
|
|
|
62015
62414
|
var ROOT_FLAG = { name: "marketplace-root", type: "string", value: "DIR", description: "Folder holding the built claude/ and codex/ plugin marketplaces" };
|
|
62016
62415
|
var connectCommand = defineCommand({
|
|
62017
62416
|
path: ["connect"],
|
|
62018
|
-
summary: "Connect this GitHub
|
|
62019
|
-
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.",
|
|
62417
|
+
summary: "Connect this project (native Overlane, or your GitHub repository): sign in, bind it, register the plugin; --kit also sets up a plan",
|
|
62418
|
+
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.",
|
|
62020
62419
|
flags: [
|
|
62021
62420
|
{ name: "service", type: "string", value: "URL", description: "Service address (https); default is the hosted service or HARNESS_SERVICE_URL" },
|
|
62022
62421
|
ROOT_FLAG,
|
|
62023
62422
|
AGENTS_FLAG,
|
|
62024
62423
|
{ 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." },
|
|
62025
62424
|
{ name: "yes", type: "boolean", description: "Apply the plan without asking (required when there is no terminal)" },
|
|
62425
|
+
{ name: "name", type: "string", value: "NAME", description: "The project name (default: the GitHub repository name, else this folder's name)" },
|
|
62426
|
+
{ 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)" },
|
|
62026
62427
|
{ name: "kit", type: "string", enum: ["existing", "new"], description: "Also set up the project kit: plan files, CI, instruction blocks and one pull request" },
|
|
62027
62428
|
{ name: "goal", type: "string", value: "TEXT", description: "The project's goal; required with --kit new" }
|
|
62028
62429
|
],
|
|
62029
|
-
examples: ["overlane connect --dry-run", "overlane connect --yes", 'overlane connect --kit new --goal "A rundown service" --yes', "overlane connect --kit existing --yes"],
|
|
62430
|
+
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"],
|
|
62030
62431
|
effect: "write",
|
|
62031
62432
|
needsNetwork: true,
|
|
62032
62433
|
keywords: ["setup", "install", "bind", "link", "onboard", "register plugin", "bootstrap", "autonomous", "plan", "kit", "get started", "initialise", "enable harness", "ci workflow", "pull request"],
|
|
@@ -62037,7 +62438,9 @@ var connectCommand = defineCommand({
|
|
|
62037
62438
|
marketplaceRoot: textFlag(inv, "marketplace-root"),
|
|
62038
62439
|
agents: parseAgentList(textFlag(inv, "agents")),
|
|
62039
62440
|
dryRun: inv.dryRun,
|
|
62040
|
-
yes: boolFlag(inv, "yes")
|
|
62441
|
+
yes: boolFlag(inv, "yes"),
|
|
62442
|
+
name: textFlag(inv, "name"),
|
|
62443
|
+
provider: parseProvider(textFlag(inv, "provider"))
|
|
62041
62444
|
};
|
|
62042
62445
|
const kit = textFlag(inv, "kit");
|
|
62043
62446
|
const goal = textFlag(inv, "goal");
|