@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
- return target.identityKey;
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
- `${target.url}${endpoint}`,
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(`${target.url}/api/cli/refresh`, {
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
- Occupied slots always block: `complete` / `teardown`, then launch. Customize the
22
- harness only through `harness.env`, `stages.json` + `.har/stages/`, `.har/hooks/`
23
- and `.har/plugins/` — there is no generated `.har/*.sh` entry-point surface.
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`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osfactory/har",
3
- "version": "1.16.2",
3
+ "version": "1.18.0",
4
4
  "description": "HAR: open agent harness CLI and MCP server for coding agents, isolated worktrees, and software-factory workflows",
5
5
  "keywords": [
6
6
  "har",