@osfactory/har 1.16.2 → 1.18.0
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/index.js
CHANGED
|
@@ -36568,6 +36568,29 @@ var init_control_config = __esm({
|
|
|
36568
36568
|
}
|
|
36569
36569
|
});
|
|
36570
36570
|
|
|
36571
|
+
// src/core/portal-hosts.ts
|
|
36572
|
+
function kernoApiUrlFor(portalUrl) {
|
|
36573
|
+
const override = process.env.HAR_API_URL?.trim().replace(/\/+$/, "");
|
|
36574
|
+
if (override) return override;
|
|
36575
|
+
try {
|
|
36576
|
+
return KERNO_API_BY_PORTAL_HOST[new URL(portalUrl).hostname];
|
|
36577
|
+
} catch {
|
|
36578
|
+
return void 0;
|
|
36579
|
+
}
|
|
36580
|
+
}
|
|
36581
|
+
var KERNO_API_BY_PORTAL_HOST;
|
|
36582
|
+
var init_portal_hosts = __esm({
|
|
36583
|
+
"src/core/portal-hosts.ts"() {
|
|
36584
|
+
"use strict";
|
|
36585
|
+
KERNO_API_BY_PORTAL_HOST = {
|
|
36586
|
+
"portal.kerno.io": "https://api.kerno.io",
|
|
36587
|
+
"app.harhq.com": "https://api.kerno.io",
|
|
36588
|
+
"portal.dev.kerno.io": "https://api.dev.kerno.io",
|
|
36589
|
+
"app.dev.harhq.com": "https://api.dev.kerno.io"
|
|
36590
|
+
};
|
|
36591
|
+
}
|
|
36592
|
+
});
|
|
36593
|
+
|
|
36571
36594
|
// src/core/commit-bindings.ts
|
|
36572
36595
|
function bindingsDir(harnessRoot) {
|
|
36573
36596
|
return path11.join(harnessRoot, ".har", COMMIT_BINDINGS_DIR);
|
|
@@ -44307,7 +44330,8 @@ function rewindSince(since) {
|
|
|
44307
44330
|
return new Date(new Date(since).getTime() - overlap).toISOString();
|
|
44308
44331
|
}
|
|
44309
44332
|
function watermarkKeyForTarget(target) {
|
|
44310
|
-
|
|
44333
|
+
const apiUrl = kernoApiUrlFor(target.url);
|
|
44334
|
+
return apiUrl ? `${apiUrl}|${target.identityKey}` : target.identityKey;
|
|
44311
44335
|
}
|
|
44312
44336
|
function legacyWatermarkKeysForTarget(target) {
|
|
44313
44337
|
return target.url === target.identityKey ? [] : [target.url];
|
|
@@ -44397,9 +44421,14 @@ async function postJson(url, body, dryRun) {
|
|
|
44397
44421
|
}
|
|
44398
44422
|
return await response.json();
|
|
44399
44423
|
}
|
|
44424
|
+
function portalEndpointUrl(target, endpoint) {
|
|
44425
|
+
const apiUrl = kernoApiUrlFor(target.url);
|
|
44426
|
+
if (!apiUrl) return `${target.url}${endpoint}`;
|
|
44427
|
+
return `${apiUrl}${KERNO_INGEST_PREFIX}${endpoint.slice(PORTAL_API_PREFIX.length)}`;
|
|
44428
|
+
}
|
|
44400
44429
|
function postPortalOnce(target, endpoint, body) {
|
|
44401
44430
|
return postForResponse(
|
|
44402
|
-
|
|
44431
|
+
portalEndpointUrl(target, endpoint),
|
|
44403
44432
|
{
|
|
44404
44433
|
"Content-Type": "application/json",
|
|
44405
44434
|
Authorization: `Bearer ${target.token}`
|
|
@@ -44411,7 +44440,7 @@ async function refreshPortalToken(target) {
|
|
|
44411
44440
|
if (!target.refreshToken) return false;
|
|
44412
44441
|
let response;
|
|
44413
44442
|
try {
|
|
44414
|
-
response = await fetch(
|
|
44443
|
+
response = await fetch(portalEndpointUrl(target, "/api/cli/refresh"), {
|
|
44415
44444
|
method: "POST",
|
|
44416
44445
|
headers: { Authorization: `Bearer ${target.refreshToken}` }
|
|
44417
44446
|
});
|
|
@@ -45167,7 +45196,7 @@ async function syncRunWithControlAsync(repoPath, run2) {
|
|
|
45167
45196
|
if (!isRepoPortalSyncEnabled(canonical)) return;
|
|
45168
45197
|
for (const portal of resolved.targets) {
|
|
45169
45198
|
try {
|
|
45170
|
-
if (!await isControlApiReachable(portal.url)) continue;
|
|
45199
|
+
if (!kernoApiUrlFor(portal.url) && !await isControlApiReachable(portal.url)) continue;
|
|
45171
45200
|
await postPortal(portal, "/api/sync", { path: canonical, runs: [run2] });
|
|
45172
45201
|
} catch (err) {
|
|
45173
45202
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -45176,7 +45205,7 @@ async function syncRunWithControlAsync(repoPath, run2) {
|
|
|
45176
45205
|
}
|
|
45177
45206
|
}
|
|
45178
45207
|
}
|
|
45179
|
-
var path48, DEFAULT_MAX_BATCH_BYTES, DEFAULT_SYNC_OVERLAP_MS, MAX_FETCH_ATTEMPTS, SYNC_TIMEOUT_MS, EXPLICIT_SYNC_TIMEOUT_MS;
|
|
45208
|
+
var path48, DEFAULT_MAX_BATCH_BYTES, DEFAULT_SYNC_OVERLAP_MS, MAX_FETCH_ATTEMPTS, PORTAL_API_PREFIX, KERNO_INGEST_PREFIX, SYNC_TIMEOUT_MS, EXPLICIT_SYNC_TIMEOUT_MS;
|
|
45180
45209
|
var init_control_sync = __esm({
|
|
45181
45210
|
"src/core/control-sync.ts"() {
|
|
45182
45211
|
"use strict";
|
|
@@ -45185,6 +45214,7 @@ var init_control_sync = __esm({
|
|
|
45185
45214
|
init_stages();
|
|
45186
45215
|
init_schema2();
|
|
45187
45216
|
init_control_config();
|
|
45217
|
+
init_portal_hosts();
|
|
45188
45218
|
init_control_registry();
|
|
45189
45219
|
init_portal_credentials();
|
|
45190
45220
|
init_portal_targets();
|
|
@@ -45207,6 +45237,8 @@ var init_control_sync = __esm({
|
|
|
45207
45237
|
DEFAULT_MAX_BATCH_BYTES = 4 * 1024 * 1024;
|
|
45208
45238
|
DEFAULT_SYNC_OVERLAP_MS = 6e4;
|
|
45209
45239
|
MAX_FETCH_ATTEMPTS = 3;
|
|
45240
|
+
PORTAL_API_PREFIX = "/api";
|
|
45241
|
+
KERNO_INGEST_PREFIX = "/api/har/ingest";
|
|
45210
45242
|
SYNC_TIMEOUT_MS = 15e3;
|
|
45211
45243
|
EXPLICIT_SYNC_TIMEOUT_MS = 12e4;
|
|
45212
45244
|
}
|
|
@@ -17,10 +17,16 @@ harness or report it; do not fall back to ad-hoc commands.
|
|
|
17
17
|
`har env verify <id> --full`. Commit in the session worktree.
|
|
18
18
|
3. **Stop at handoff** — report summary, session branch and preview URLs, then
|
|
19
19
|
wait. Never autonomously `complete`, `teardown`, push, or open a PR.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
4. **All slots taken?** Occupied slots always block a launch, and you never free
|
|
21
|
+
one yourself. Run `har env status`, then show the user every slot — branch,
|
|
22
|
+
work unit, what it achieves, last verify, and whether its commits are merged,
|
|
23
|
+
pushed or unpushed — and recommend which to close: merged or abandoned work
|
|
24
|
+
with nothing left to do first; never one with unpushed commits. On approval:
|
|
25
|
+
`complete` / `teardown <id>`, then launch.
|
|
26
|
+
|
|
27
|
+
Customize the harness only through `harness.env`, `stages.json` + `.har/stages/`,
|
|
28
|
+
`.har/hooks/` and `.har/plugins/` — there is no generated `.har/*.sh` entry-point
|
|
29
|
+
surface.
|
|
24
30
|
|
|
25
31
|
Full detail — slot environment, readiness, definition of done, project commands,
|
|
26
32
|
commit gate: [`.har/README.md`](.har/README.md) and [`.har/stages.json`](.har/stages.json).
|
|
@@ -12,6 +12,7 @@ har env status # or ./.har/agent-cli.sh 1 status
|
|
|
12
12
|
|
|
13
13
|
- One slot ≈ one task. If slot 1 is occupied by unrelated work, use slot 2+ (limit: `agentSlots` in `.har/stages.json`).
|
|
14
14
|
- Occupied slots always block a new launch: run `har env teardown <id>` (or `complete <id>`) first, then launch again.
|
|
15
|
+
- All slots occupied? Never free one on your own. Show the user each slot (branch, work unit, what it achieves, last verify, merged / pushed / unpushed commits) and recommend which to close — merged or abandoned work with nothing left to do first, never one with unpushed commits. Free it only after approval.
|
|
15
16
|
|
|
16
17
|
## 2. Launch — BEFORE editing any file
|
|
17
18
|
|
|
@@ -11,6 +11,12 @@ never in the main checkout.
|
|
|
11
11
|
- Occupied slots always block a new launch: `har env complete <id>` (or `teardown <id>`),
|
|
12
12
|
then `har env launch <id>`. A new launch never chooses `main` for you — switch the
|
|
13
13
|
main checkout to your intended base first.
|
|
14
|
+
- When every slot is occupied, do not pick one to free on your own. Run
|
|
15
|
+
`har env status` and give the user a slot-by-slot summary: branch, bound work
|
|
16
|
+
unit, what the session achieves, last verify, and whether its commits are merged,
|
|
17
|
+
pushed, or unpushed (`git log <base>..<branch>`, PR state). Recommend which slot
|
|
18
|
+
to close — merged or abandoned work with nothing left to do first; never one with
|
|
19
|
+
unpushed commits — and free it with `complete` / `teardown` only after approval.
|
|
14
20
|
- `teardown` removes the worktree but **keeps the session branch** so you can push it
|
|
15
21
|
or open a PR (`--delete-branch` to drop it).
|
|
16
22
|
- If launch fails after creating a worktree/env file, the registry records `status: failed`.
|