@inerrata-corporation/errata 2.0.7-dev.2782 → 2.0.7-dev.2821
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/errata.mjs +131 -23
- package/package.json +1 -1
package/errata.mjs
CHANGED
|
@@ -25433,8 +25433,17 @@ var init_client = __esm({
|
|
|
25433
25433
|
}
|
|
25434
25434
|
/** Resolve-or-create the org's project for a repo locator (ambient link,
|
|
25435
25435
|
* PJ-entity). Requires user identity on the JWT — login-gated like actAs. */
|
|
25436
|
-
async resolveProject(locator, name2) {
|
|
25437
|
-
return this.json("POST", "/api/gate/projects/resolve",
|
|
25436
|
+
async resolveProject(locator, name2, rootCommitSha) {
|
|
25437
|
+
return this.json("POST", "/api/gate/projects/resolve", {
|
|
25438
|
+
locator,
|
|
25439
|
+
...name2 ? { name: name2 } : {},
|
|
25440
|
+
...rootCommitSha ? { rootCommitSha } : {}
|
|
25441
|
+
});
|
|
25442
|
+
}
|
|
25443
|
+
/** PJ-claim-fingerprint: tell an already-linked project its repo's root commit.
|
|
25444
|
+
* Org-scoped and record-if-absent server-side; never creates a project. */
|
|
25445
|
+
async recordProjectRootCommit(projectId, rootCommitSha) {
|
|
25446
|
+
return this.json("POST", "/api/gate/projects/fingerprint", { projectId, rootCommitSha });
|
|
25438
25447
|
}
|
|
25439
25448
|
/** PJ-ingest-history: report the history stage so the console mirrors it;
|
|
25440
25449
|
* the answer carries the console's standing Stop. Org-scoped; foreign ids 404. */
|
|
@@ -62967,7 +62976,7 @@ var require_mock_interceptor = __commonJS({
|
|
|
62967
62976
|
var require_mock_client = __commonJS({
|
|
62968
62977
|
"../../node_modules/.pnpm/undici@6.24.1/node_modules/undici/lib/mock/mock-client.js"(exports, module2) {
|
|
62969
62978
|
"use strict";
|
|
62970
|
-
var { promisify:
|
|
62979
|
+
var { promisify: promisify3 } = __require("node:util");
|
|
62971
62980
|
var Client = require_client();
|
|
62972
62981
|
var { buildMockDispatch } = require_mock_utils();
|
|
62973
62982
|
var {
|
|
@@ -63007,7 +63016,7 @@ var require_mock_client = __commonJS({
|
|
|
63007
63016
|
return new MockInterceptor(opts, this[kDispatches]);
|
|
63008
63017
|
}
|
|
63009
63018
|
async [kClose]() {
|
|
63010
|
-
await
|
|
63019
|
+
await promisify3(this[kOriginalClose])();
|
|
63011
63020
|
this[kConnected] = 0;
|
|
63012
63021
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
63013
63022
|
}
|
|
@@ -63020,7 +63029,7 @@ var require_mock_client = __commonJS({
|
|
|
63020
63029
|
var require_mock_pool = __commonJS({
|
|
63021
63030
|
"../../node_modules/.pnpm/undici@6.24.1/node_modules/undici/lib/mock/mock-pool.js"(exports, module2) {
|
|
63022
63031
|
"use strict";
|
|
63023
|
-
var { promisify:
|
|
63032
|
+
var { promisify: promisify3 } = __require("node:util");
|
|
63024
63033
|
var Pool = require_pool();
|
|
63025
63034
|
var { buildMockDispatch } = require_mock_utils();
|
|
63026
63035
|
var {
|
|
@@ -63060,7 +63069,7 @@ var require_mock_pool = __commonJS({
|
|
|
63060
63069
|
return new MockInterceptor(opts, this[kDispatches]);
|
|
63061
63070
|
}
|
|
63062
63071
|
async [kClose]() {
|
|
63063
|
-
await
|
|
63072
|
+
await promisify3(this[kOriginalClose])();
|
|
63064
63073
|
this[kConnected] = 0;
|
|
63065
63074
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
63066
63075
|
}
|
|
@@ -79922,7 +79931,7 @@ function createWatchBreaker(deps) {
|
|
|
79922
79931
|
}
|
|
79923
79932
|
|
|
79924
79933
|
// src/engine.ts
|
|
79925
|
-
var DAEMON_VERSION = true ? "2.0.7-dev.
|
|
79934
|
+
var DAEMON_VERSION = true ? "2.0.7-dev.2821" : "2.0.0-alpha.0";
|
|
79926
79935
|
var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
|
|
79927
79936
|
var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
|
|
79928
79937
|
var GIT_OP_MUTE_MS = 4e3;
|
|
@@ -83703,17 +83712,47 @@ init_identity2();
|
|
|
83703
83712
|
|
|
83704
83713
|
// src/project-link.ts
|
|
83705
83714
|
init_profile2();
|
|
83706
|
-
|
|
83715
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
83716
|
+
import { promisify } from "node:util";
|
|
83717
|
+
var execFileAsync = promisify(execFile3);
|
|
83718
|
+
async function readRootCommit(root) {
|
|
83719
|
+
try {
|
|
83720
|
+
const { stdout } = await execFileAsync("git", ["rev-list", "--max-parents=0", "HEAD"], {
|
|
83721
|
+
cwd: root,
|
|
83722
|
+
encoding: "utf8",
|
|
83723
|
+
timeout: 15e3,
|
|
83724
|
+
windowsHide: true
|
|
83725
|
+
});
|
|
83726
|
+
const sha2 = stdout.split(/\s+/).filter(Boolean).pop();
|
|
83727
|
+
return sha2 && /^[0-9a-f]{40,64}$/i.test(sha2) ? sha2.toLowerCase() : null;
|
|
83728
|
+
} catch {
|
|
83729
|
+
return null;
|
|
83730
|
+
}
|
|
83731
|
+
}
|
|
83732
|
+
async function ensureProjectLink(root, profile, client, rootCommit = readRootCommit) {
|
|
83707
83733
|
if (profile.projectLinkDisabled) return { linked: false, reason: "disabled" };
|
|
83708
83734
|
const locator = profile.repoLocator;
|
|
83709
83735
|
if (!locator) return { linked: false, reason: "no-locator" };
|
|
83710
83736
|
if (profile.projectId && profile.projectLocator === locator) {
|
|
83737
|
+
if (profile.rootCommitReportedFor !== profile.projectId && client.recordProjectRootCommit) {
|
|
83738
|
+
const sha2 = await rootCommit(root);
|
|
83739
|
+
if (sha2) {
|
|
83740
|
+
try {
|
|
83741
|
+
await client.recordProjectRootCommit(profile.projectId, sha2);
|
|
83742
|
+
profile.rootCommitReportedFor = profile.projectId;
|
|
83743
|
+
saveProfile(root, profile);
|
|
83744
|
+
} catch {
|
|
83745
|
+
}
|
|
83746
|
+
}
|
|
83747
|
+
}
|
|
83711
83748
|
return { linked: false, reason: "already-linked" };
|
|
83712
83749
|
}
|
|
83713
83750
|
try {
|
|
83714
|
-
const
|
|
83751
|
+
const sha2 = await rootCommit(root);
|
|
83752
|
+
const res = await client.resolveProject(locator, profile.name, sha2 ?? void 0);
|
|
83715
83753
|
profile.projectId = res.project.id;
|
|
83716
83754
|
profile.projectLocator = locator;
|
|
83755
|
+
if (sha2) profile.rootCommitReportedFor = res.project.id;
|
|
83717
83756
|
saveProfile(root, profile);
|
|
83718
83757
|
return { linked: true, projectId: res.project.id, created: res.created };
|
|
83719
83758
|
} catch (err2) {
|
|
@@ -84065,10 +84104,10 @@ async function hydrateProject(opts) {
|
|
|
84065
84104
|
// src/project-history.ts
|
|
84066
84105
|
init_src7();
|
|
84067
84106
|
init_src();
|
|
84068
|
-
import { execFile as
|
|
84107
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
84069
84108
|
import { readFileSync as readFileSync32 } from "node:fs";
|
|
84070
84109
|
import { join as join36 } from "node:path";
|
|
84071
|
-
import { promisify } from "node:util";
|
|
84110
|
+
import { promisify as promisify2 } from "node:util";
|
|
84072
84111
|
|
|
84073
84112
|
// src/history-walk.ts
|
|
84074
84113
|
var LOCKFILE_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -84442,14 +84481,14 @@ var GitBlobReader = class {
|
|
|
84442
84481
|
|
|
84443
84482
|
// src/project-history.ts
|
|
84444
84483
|
init_profile2();
|
|
84445
|
-
var
|
|
84484
|
+
var execFileAsync2 = promisify2(execFile4);
|
|
84446
84485
|
var HISTORY_EXTRACTOR_VERSION = "history-2";
|
|
84447
84486
|
var LEASE_POLL_MS = 2e4;
|
|
84448
84487
|
var RECOVERY_DEADLINE_MS = 15 * 6e4;
|
|
84449
84488
|
var MAX_ANCHORS_PER_TOKEN = 20;
|
|
84450
84489
|
var DEFAULT_LOOKAHEAD = 2;
|
|
84451
84490
|
async function defaultGit(root, args2) {
|
|
84452
|
-
const { stdout } = await
|
|
84491
|
+
const { stdout } = await execFileAsync2("git", ["-C", root, ...args2], { maxBuffer: 64 * 1024 * 1024, windowsHide: true });
|
|
84453
84492
|
return stdout;
|
|
84454
84493
|
}
|
|
84455
84494
|
function readIgnoreLines(root, profile) {
|
|
@@ -84995,16 +85034,28 @@ async function loginOAuthDevice(opts) {
|
|
|
84995
85034
|
if (approvedInstallation !== opts.installationId) {
|
|
84996
85035
|
throw new Error("approved installation does not match the terminal request");
|
|
84997
85036
|
}
|
|
84998
|
-
|
|
85037
|
+
return exchangeDeviceSession({
|
|
85038
|
+
fetchFn,
|
|
85039
|
+
resourceUrl: device.resource,
|
|
85040
|
+
deviceSession,
|
|
85041
|
+
installationId: approvedInstallation,
|
|
85042
|
+
clientId,
|
|
85043
|
+
scope
|
|
85044
|
+
});
|
|
85045
|
+
}
|
|
85046
|
+
async function exchangeDeviceSession(opts) {
|
|
85047
|
+
const fetchFn = opts.fetchFn ?? fetch;
|
|
85048
|
+
const scope = opts.scope ?? DEFAULT_OAUTH_SCOPE;
|
|
85049
|
+
const resourceResponse = await fetchFn(opts.resourceUrl, {
|
|
84999
85050
|
method: "POST",
|
|
85000
85051
|
headers: {
|
|
85001
|
-
authorization: `Bearer ${deviceSession}`,
|
|
85052
|
+
authorization: `Bearer ${opts.deviceSession}`,
|
|
85002
85053
|
"content-type": "application/json",
|
|
85003
85054
|
accept: "application/json"
|
|
85004
85055
|
},
|
|
85005
85056
|
body: JSON.stringify({
|
|
85006
|
-
installationId:
|
|
85007
|
-
clientId,
|
|
85057
|
+
installationId: opts.installationId,
|
|
85058
|
+
clientId: opts.clientId,
|
|
85008
85059
|
scopes: scope.split(/\s+/).filter((value) => !["openid", "profile", "email", "offline_access"].includes(value))
|
|
85009
85060
|
})
|
|
85010
85061
|
});
|
|
@@ -85013,12 +85064,12 @@ async function loginOAuthDevice(opts) {
|
|
|
85013
85064
|
throw new Error(`device resource exchange failed: HTTP ${resourceResponse.status}`);
|
|
85014
85065
|
}
|
|
85015
85066
|
return {
|
|
85016
|
-
installationId:
|
|
85017
|
-
clientId,
|
|
85018
|
-
tokenEndpoint:
|
|
85067
|
+
installationId: opts.installationId,
|
|
85068
|
+
clientId: opts.clientId,
|
|
85069
|
+
tokenEndpoint: opts.resourceUrl,
|
|
85019
85070
|
tokens: {
|
|
85020
85071
|
accessToken: resource["access_token"],
|
|
85021
|
-
refreshToken: deviceSession,
|
|
85072
|
+
refreshToken: opts.deviceSession,
|
|
85022
85073
|
...typeof resource["expires_in"] === "number" ? { expiresInSec: resource["expires_in"] } : {}
|
|
85023
85074
|
}
|
|
85024
85075
|
};
|
|
@@ -85232,7 +85283,10 @@ async function linkThroughConsole(opts) {
|
|
|
85232
85283
|
return {
|
|
85233
85284
|
status: "approved",
|
|
85234
85285
|
decision,
|
|
85235
|
-
installationId: typeof payload?.["installation_id"] === "string" ? payload["installation_id"] : null
|
|
85286
|
+
installationId: typeof payload?.["installation_id"] === "string" ? payload["installation_id"] : null,
|
|
85287
|
+
deviceSession: typeof payload?.["access_token"] === "string" ? payload["access_token"] : null,
|
|
85288
|
+
resourceUrl: device.resource,
|
|
85289
|
+
clientId
|
|
85236
85290
|
};
|
|
85237
85291
|
}
|
|
85238
85292
|
return { status: "expired" };
|
|
@@ -89222,6 +89276,50 @@ async function linkRegisteredWorkspaces(cfg) {
|
|
|
89222
89276
|
}
|
|
89223
89277
|
}
|
|
89224
89278
|
}
|
|
89279
|
+
async function bindWorkspaceToLinkInstallation(cfg, out2, orgId) {
|
|
89280
|
+
const installationId = out2.installationId;
|
|
89281
|
+
if (!out2.deviceSession) {
|
|
89282
|
+
console.warn(
|
|
89283
|
+
` note: the project is in another org; run \`errata login --device --installation ${installationId} --profile <name>\` then \`errata workspace bind . --profile <name>\``
|
|
89284
|
+
);
|
|
89285
|
+
return null;
|
|
89286
|
+
}
|
|
89287
|
+
try {
|
|
89288
|
+
const minted = await exchangeDeviceSession({
|
|
89289
|
+
resourceUrl: out2.resourceUrl,
|
|
89290
|
+
deviceSession: out2.deviceSession,
|
|
89291
|
+
installationId,
|
|
89292
|
+
clientId: out2.clientId
|
|
89293
|
+
});
|
|
89294
|
+
const existing = Object.entries(cfg.installationProfiles).find(([, p]) => p.installationId === installationId)?.[0];
|
|
89295
|
+
let profileName = existing ?? `link-${orgId.slice(0, 8)}`;
|
|
89296
|
+
for (let i2 = 2; !existing && cfg.installationProfiles[profileName]; i2++) profileName = `link-${orgId.slice(0, 8)}-${i2}`;
|
|
89297
|
+
const next = {
|
|
89298
|
+
...cfg,
|
|
89299
|
+
installationProfiles: {
|
|
89300
|
+
...cfg.installationProfiles,
|
|
89301
|
+
[profileName]: {
|
|
89302
|
+
installationId,
|
|
89303
|
+
cloudUrl: cfg.cloudUrl,
|
|
89304
|
+
apiKey: null,
|
|
89305
|
+
accessToken: minted.tokens.accessToken,
|
|
89306
|
+
refreshToken: minted.tokens.refreshToken ?? null,
|
|
89307
|
+
tokenEndpoint: minted.tokenEndpoint,
|
|
89308
|
+
oauthClientId: minted.clientId,
|
|
89309
|
+
activeAgent: null
|
|
89310
|
+
}
|
|
89311
|
+
}
|
|
89312
|
+
};
|
|
89313
|
+
saveConfig(next);
|
|
89314
|
+
setWorkspaceBinding(workspaceEntryForPath(ROOT)?.id ?? ROOT, profileName);
|
|
89315
|
+
return { config: next, profileName };
|
|
89316
|
+
} catch (err2) {
|
|
89317
|
+
console.warn(
|
|
89318
|
+
` note: the project is linked, but this workspace could not take the other org's credential (${err2 instanceof Error ? err2.message : String(err2)}); run \`errata login --device --installation ${installationId} --profile <name>\` then \`errata workspace bind . --profile <name>\``
|
|
89319
|
+
);
|
|
89320
|
+
return null;
|
|
89321
|
+
}
|
|
89322
|
+
}
|
|
89225
89323
|
async function cmdLink(args2) {
|
|
89226
89324
|
const flag = (name2) => {
|
|
89227
89325
|
const i2 = args2.indexOf(name2);
|
|
@@ -89301,12 +89399,22 @@ async function cmdLink(args2) {
|
|
|
89301
89399
|
);
|
|
89302
89400
|
await refreshLinkedCodexHooks(args2);
|
|
89303
89401
|
if (applied.wroteIgnore) console.log("wrote .errataignore (starter) \u2014 edit it; it is your hard control");
|
|
89402
|
+
let reportClient = authedCloudClient(applied.config);
|
|
89403
|
+
if (out3.installationId && out3.installationId !== activeProfile?.installationId) {
|
|
89404
|
+
const bound = await bindWorkspaceToLinkInstallation(applied.config, out3, d.orgId);
|
|
89405
|
+
if (bound) {
|
|
89406
|
+
reportClient = authedCloudClientForProfile(bound.config, bound.profileName);
|
|
89407
|
+
console.log(
|
|
89408
|
+
`this workspace now uses installation ${out3.installationId.slice(0, 8)} (profile ${bound.profileName}) in org ${d.orgId.slice(0, 8)}; your machine default is unchanged`
|
|
89409
|
+
);
|
|
89410
|
+
}
|
|
89411
|
+
}
|
|
89304
89412
|
if (!hasCloudCredential(cfg)) {
|
|
89305
89413
|
console.log(" note: run `errata login` so this daemon can sync under the link and report the history stage.");
|
|
89306
89414
|
return;
|
|
89307
89415
|
}
|
|
89308
89416
|
const consents = historyConsents(applied.profile);
|
|
89309
|
-
const reported = await reportHistoryStage(
|
|
89417
|
+
const reported = await reportHistoryStage(reportClient, applied.profile, (line) => console.warn(line));
|
|
89310
89418
|
if (reported?.consents) {
|
|
89311
89419
|
const synced = applyConsents(applied.profile, applied.config, reported.consents, (/* @__PURE__ */ new Date()).toISOString());
|
|
89312
89420
|
if (synced.changed) {
|