@osfactory/har 1.3.0 → 1.5.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 +124 -37
- package/dist/templates/agent-skills/har-wt.md +2 -1
- package/dist/templates/profiles/cli/docs/readme/definition-of-done.md +1 -1
- package/dist/templates/profiles/default/docs/readme/definition-of-done.md +1 -1
- package/dist/templates/profiles/ios/docs/readme/definition-of-done.md +1 -1
- package/dist/templates/shared-docs/readme/session-lifecycle.md +3 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4796,7 +4796,9 @@ var init_schema = __esm({
|
|
|
4796
4796
|
toolCallId: external_exports.string().optional(),
|
|
4797
4797
|
correlationId: external_exports.string().optional(),
|
|
4798
4798
|
workUnitId: WorkUnitIdSchema.optional(),
|
|
4799
|
-
attemptId: WorkAttemptIdSchema.optional()
|
|
4799
|
+
attemptId: WorkAttemptIdSchema.optional(),
|
|
4800
|
+
/** One occupancy of a slot (#316) — records are scoped to it, not to slot id. */
|
|
4801
|
+
occupancyKey: external_exports.string().min(1).optional()
|
|
4800
4802
|
}).passthrough();
|
|
4801
4803
|
AgentTrajectoryRecordSchema = AgentTrajectoryRecordV1Schema;
|
|
4802
4804
|
USAGE_HARVEST_VERSION = 2;
|
|
@@ -4811,6 +4813,8 @@ var init_schema = __esm({
|
|
|
4811
4813
|
suffix: external_exports.string().optional(),
|
|
4812
4814
|
workUnitId: WorkUnitIdSchema.optional(),
|
|
4813
4815
|
attemptId: WorkAttemptIdSchema.optional(),
|
|
4816
|
+
/** One occupancy of a slot (#316) — usage is scoped to it, not to slot id. */
|
|
4817
|
+
occupancyKey: external_exports.string().min(1).optional(),
|
|
4814
4818
|
tokensInput: external_exports.number().nonnegative().default(0),
|
|
4815
4819
|
tokensOutput: external_exports.number().nonnegative().default(0),
|
|
4816
4820
|
tokensCacheRead: external_exports.number().nonnegative().default(0),
|
|
@@ -32752,6 +32756,13 @@ function findValidation(checkoutDir, treeHash) {
|
|
|
32752
32756
|
return void 0;
|
|
32753
32757
|
}
|
|
32754
32758
|
}
|
|
32759
|
+
function findPassingFullValidation(input) {
|
|
32760
|
+
if (!isCheckoutRoot(input.checkoutDir)) return void 0;
|
|
32761
|
+
const { treeHash } = computeWorktreeSnapshot(input.checkoutDir);
|
|
32762
|
+
const record2 = findValidation(input.checkoutDir, treeHash) ?? (input.harnessRoot ? findValidation(input.harnessRoot, treeHash) : void 0);
|
|
32763
|
+
if (record2?.status === "pass" && record2.full) return record2;
|
|
32764
|
+
return void 0;
|
|
32765
|
+
}
|
|
32755
32766
|
function attachCommit(checkoutDir, treeHash, commitSha) {
|
|
32756
32767
|
const record2 = findValidation(checkoutDir, treeHash);
|
|
32757
32768
|
if (!record2) return void 0;
|
|
@@ -59038,10 +59049,12 @@ var require_run_async = __commonJS({
|
|
|
59038
59049
|
// src/core/otel-hooks.ts
|
|
59039
59050
|
var otel_hooks_exports = {};
|
|
59040
59051
|
__export(otel_hooks_exports, {
|
|
59052
|
+
HOOK_TIMEOUT_SECONDS: () => HOOK_TIMEOUT_SECONDS,
|
|
59041
59053
|
LEGACY_CURSOR_ONLY_HOOK_EVENTS: () => LEGACY_CURSOR_ONLY_HOOK_EVENTS,
|
|
59042
59054
|
OTEL_HOOKS_AGENTS: () => OTEL_HOOKS_AGENTS,
|
|
59043
59055
|
OTEL_HOOKS_PACKAGE: () => OTEL_HOOKS_PACKAGE,
|
|
59044
59056
|
OTEL_HOOKS_PROVIDERS: () => OTEL_HOOKS_PROVIDERS,
|
|
59057
|
+
buildOtelHookSetupArgs: () => buildOtelHookSetupArgs,
|
|
59045
59058
|
buildOtelHooksConfig: () => buildOtelHooksConfig,
|
|
59046
59059
|
disableOtelHooksExport: () => disableOtelHooksExport,
|
|
59047
59060
|
ensureOtelHooks: () => ensureOtelHooks,
|
|
@@ -59147,11 +59160,22 @@ function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome())
|
|
|
59147
59160
|
const stateDir = getOtelHooksStateDir(hooksHome);
|
|
59148
59161
|
const script = `#!/usr/bin/env bash
|
|
59149
59162
|
# Managed by har telemetry \u2014 invokes @osfactory/otel-hook with HAR config.
|
|
59150
|
-
|
|
59151
|
-
|
|
59163
|
+
#
|
|
59164
|
+
# Two rules for this wrapper (#328):
|
|
59165
|
+
# 1. Bounded. Export and flush budgets keep it well inside the per-hook
|
|
59166
|
+
# timeout the agent enforces, so an unreachable Mission Control costs
|
|
59167
|
+
# milliseconds instead of stalling the session.
|
|
59168
|
+
# 2. Silent about its own failures. Dropped telemetry must never fail an
|
|
59169
|
+
# agent turn, so the exit status is always 0 \u2014 a non-zero hook exit can
|
|
59170
|
+
# block a tool call.
|
|
59171
|
+
set -uo pipefail
|
|
59172
|
+
"${otelHookCommand}" run \\
|
|
59152
59173
|
--config-file "${configPath}" \\
|
|
59153
59174
|
--state-dir "${stateDir}" \\
|
|
59154
|
-
|
|
59175
|
+
--timeout-ms ${HOOK_EXPORT_TIMEOUT_MS} \\
|
|
59176
|
+
--flush-timeout-ms ${HOOK_FLUSH_TIMEOUT_MS} \\
|
|
59177
|
+
"$@" || true
|
|
59178
|
+
exit 0
|
|
59155
59179
|
`;
|
|
59156
59180
|
fs68.writeFileSync(wrapperPath, script, { mode: 493 });
|
|
59157
59181
|
try {
|
|
@@ -59244,23 +59268,30 @@ function isOtelHookCommand(command2, wrapperPath) {
|
|
|
59244
59268
|
function normalizeLegacyProviderFlagsInCommand(command2) {
|
|
59245
59269
|
return command2.replace(/(^|\s)--cursor(?=\s|$)/g, "$1--provider cursor").replace(/(^|\s)--claude(?=\s|$)/g, "$1--provider claude-code").replace(/(^|\s)--codex(?=\s|$)/g, "$1--provider codex");
|
|
59246
59270
|
}
|
|
59271
|
+
function buildOtelHookSetupArgs(providerId, hookCommand) {
|
|
59272
|
+
return [
|
|
59273
|
+
"setup",
|
|
59274
|
+
"--provider",
|
|
59275
|
+
providerId,
|
|
59276
|
+
"--scope",
|
|
59277
|
+
"global",
|
|
59278
|
+
"--hook-command",
|
|
59279
|
+
hookCommand,
|
|
59280
|
+
"--managed-marker",
|
|
59281
|
+
"otel-hook",
|
|
59282
|
+
// Written into each generated hook entry so the agent bounds it (#328).
|
|
59283
|
+
// Without this the agent falls back to its own default and an unreachable
|
|
59284
|
+
// collector stalls the session before its first model request.
|
|
59285
|
+
"--timeout-seconds",
|
|
59286
|
+
String(HOOK_TIMEOUT_SECONDS)
|
|
59287
|
+
];
|
|
59288
|
+
}
|
|
59247
59289
|
function runSetupProvider(providerId, otelHookCommand, wrapperPath) {
|
|
59248
59290
|
const hookCommand = `${wrapperPath} --provider ${providerId}`;
|
|
59249
|
-
const result = (0, import_child_process19.spawnSync)(
|
|
59250
|
-
|
|
59251
|
-
|
|
59252
|
-
|
|
59253
|
-
"--provider",
|
|
59254
|
-
providerId,
|
|
59255
|
-
"--scope",
|
|
59256
|
-
"global",
|
|
59257
|
-
"--hook-command",
|
|
59258
|
-
hookCommand,
|
|
59259
|
-
"--managed-marker",
|
|
59260
|
-
"otel-hook"
|
|
59261
|
-
],
|
|
59262
|
-
{ encoding: "utf8", timeout: 6e4 }
|
|
59263
|
-
);
|
|
59291
|
+
const result = (0, import_child_process19.spawnSync)(otelHookCommand, buildOtelHookSetupArgs(providerId, hookCommand), {
|
|
59292
|
+
encoding: "utf8",
|
|
59293
|
+
timeout: 6e4
|
|
59294
|
+
});
|
|
59264
59295
|
if (result.status === 0) {
|
|
59265
59296
|
return { ok: true, detail: `setup --provider ${providerId}` };
|
|
59266
59297
|
}
|
|
@@ -59487,7 +59518,7 @@ function ensureOtelHooks(options) {
|
|
|
59487
59518
|
function disableOtelHooksExport() {
|
|
59488
59519
|
return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
|
|
59489
59520
|
}
|
|
59490
|
-
var import_child_process19, fs68, os22, path76, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
|
|
59521
|
+
var import_child_process19, fs68, os22, path76, OTEL_HOOKS_PACKAGE, HOOK_TIMEOUT_SECONDS, HOOK_EXPORT_TIMEOUT_MS, HOOK_FLUSH_TIMEOUT_MS, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
|
|
59491
59522
|
var init_otel_hooks = __esm({
|
|
59492
59523
|
"src/core/otel-hooks.ts"() {
|
|
59493
59524
|
"use strict";
|
|
@@ -59498,6 +59529,9 @@ var init_otel_hooks = __esm({
|
|
|
59498
59529
|
init_control_config();
|
|
59499
59530
|
init_telemetry_config();
|
|
59500
59531
|
OTEL_HOOKS_PACKAGE = "@osfactory/otel-hook@0.2.0";
|
|
59532
|
+
HOOK_TIMEOUT_SECONDS = 10;
|
|
59533
|
+
HOOK_EXPORT_TIMEOUT_MS = 1500;
|
|
59534
|
+
HOOK_FLUSH_TIMEOUT_MS = 500;
|
|
59501
59535
|
OTEL_HOOKS_PROVIDERS = [
|
|
59502
59536
|
{ id: "cursor", label: "cursor" },
|
|
59503
59537
|
{ id: "claude-code", label: "claude" },
|
|
@@ -79330,9 +79364,9 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
79330
79364
|
return envResult;
|
|
79331
79365
|
}
|
|
79332
79366
|
/**
|
|
79333
|
-
* Finish a session:
|
|
79334
|
-
*
|
|
79335
|
-
* can push it and open a PR.
|
|
79367
|
+
* Finish a session: reuse the last matching passing full validation (or
|
|
79368
|
+
* re-run verify when asked), then teardown. The session branch is kept so
|
|
79369
|
+
* the user can push it and open a PR.
|
|
79336
79370
|
*/
|
|
79337
79371
|
async completeEnvironment(options) {
|
|
79338
79372
|
const harnessRoot = resolveHarnessRoot(options.repoPath);
|
|
@@ -79344,9 +79378,11 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
79344
79378
|
stderr: `No active session for agent ${options.agentId}. Run launch first.`
|
|
79345
79379
|
};
|
|
79346
79380
|
}
|
|
79381
|
+
const runVerify = shouldReverifyOnComplete(options);
|
|
79347
79382
|
let verification;
|
|
79348
79383
|
let validation2;
|
|
79349
|
-
|
|
79384
|
+
let reusedValidation = false;
|
|
79385
|
+
if (runVerify) {
|
|
79350
79386
|
const verify = await this.runVerification({
|
|
79351
79387
|
repoPath: options.repoPath,
|
|
79352
79388
|
agentId: options.agentId,
|
|
@@ -79359,11 +79395,27 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
79359
79395
|
if (verify.code !== 0 || verification?.status !== "pass") {
|
|
79360
79396
|
return {
|
|
79361
79397
|
...verify,
|
|
79362
|
-
stderr: verify.stderr + "\nVerification failed \u2014 session NOT completed. Fix the failures and rerun
|
|
79398
|
+
stderr: verify.stderr + "\nVerification failed \u2014 session NOT completed. Fix the failures and rerun `complete --verify`, or use teardown to free the slot without claiming completion."
|
|
79363
79399
|
};
|
|
79364
79400
|
}
|
|
79401
|
+
} else {
|
|
79402
|
+
const checkoutDir = resolveValidationCheckoutDir({
|
|
79403
|
+
worktreePath: session.worktreePath,
|
|
79404
|
+
workDir: session.workDir,
|
|
79405
|
+
harnessRoot
|
|
79406
|
+
});
|
|
79407
|
+
validation2 = findPassingFullValidation({ checkoutDir, harnessRoot });
|
|
79408
|
+
if (!validation2) {
|
|
79409
|
+
return {
|
|
79410
|
+
code: 1,
|
|
79411
|
+
stdout: "",
|
|
79412
|
+
stderr: `No passing full validation matches the current worktree. The tree may have changed since the last \`har env verify --full\`. Re-run verification with: har env complete ${options.agentId} --verify
|
|
79413
|
+
Or free the slot without claiming completion: har env teardown ${options.agentId}`
|
|
79414
|
+
};
|
|
79415
|
+
}
|
|
79416
|
+
reusedValidation = true;
|
|
79365
79417
|
}
|
|
79366
|
-
if (session.workUnitId && session.attemptId &&
|
|
79418
|
+
if (session.workUnitId && session.attemptId && runVerify && !validation2) {
|
|
79367
79419
|
return {
|
|
79368
79420
|
code: 1,
|
|
79369
79421
|
stdout: "",
|
|
@@ -79387,11 +79439,13 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
79387
79439
|
trigger: options.trigger
|
|
79388
79440
|
});
|
|
79389
79441
|
if (teardown.code !== 0) return { ...teardown, verification };
|
|
79442
|
+
const reusedNote = reusedValidation && validation2 ? `Reused passing full validation ${validation2.validationId} for tree ${validation2.treeHash}.
|
|
79443
|
+
` : "";
|
|
79390
79444
|
const branchNote = session.branch ? `Branch kept: ${session.branch} \u2014 push it with: git push -u origin ${session.branch}
|
|
79391
79445
|
` : "";
|
|
79392
79446
|
return {
|
|
79393
79447
|
...teardown,
|
|
79394
|
-
stdout: teardown.stdout + branchNote,
|
|
79448
|
+
stdout: teardown.stdout + reusedNote + branchNote,
|
|
79395
79449
|
branch: session.branch,
|
|
79396
79450
|
workDir: session.workDir,
|
|
79397
79451
|
worktreePath: session.worktreePath,
|
|
@@ -79430,6 +79484,10 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
|
|
|
79430
79484
|
return toEnvironmentRunResult(result);
|
|
79431
79485
|
}
|
|
79432
79486
|
};
|
|
79487
|
+
function shouldReverifyOnComplete(options) {
|
|
79488
|
+
if (options.verify === true) return true;
|
|
79489
|
+
return options.skipVerify === false;
|
|
79490
|
+
}
|
|
79433
79491
|
var defaultRunService = new RunService();
|
|
79434
79492
|
function createRunService(executor = localScriptExecutor) {
|
|
79435
79493
|
return new RunService(executor);
|
|
@@ -79919,12 +79977,12 @@ Typical agent workflow:
|
|
|
79919
79977
|
har env launch <id> # new session from the main checkout's HEAD
|
|
79920
79978
|
# \u2026edit only under the printed work dir\u2026
|
|
79921
79979
|
har env verify <id> --full
|
|
79922
|
-
har env complete <id> # done:
|
|
79980
|
+
har env complete <id> # done: reuse last full validation + free the slot (branch kept for PR)
|
|
79923
79981
|
|
|
79924
79982
|
Slot lifecycle (do not confuse these):
|
|
79925
79983
|
launch start a NEW session (worktree from $REPO_ROOT HEAD)
|
|
79926
79984
|
recover resume a failed/partial launch (keeps the existing worktree)
|
|
79927
|
-
complete finish successfully: full
|
|
79985
|
+
complete finish successfully: reuse last matching full validation, then teardown (frees the slot)
|
|
79928
79986
|
teardown abandon / free the slot without a completion validation
|
|
79929
79987
|
|
|
79930
79988
|
Occupied slots always block a new launch:
|
|
@@ -79940,7 +79998,7 @@ var HAR_ENV_EPILOG = `Environment lifecycle:
|
|
|
79940
79998
|
launch <id> fresh session worktree from the main checkout's current HEAD
|
|
79941
79999
|
recover <id> alias for launch --resume (failed/starting only)
|
|
79942
80000
|
verify <id> run checks (--full before declaring done)
|
|
79943
|
-
complete <id> full
|
|
80001
|
+
complete <id> reuse last full validation + teardown; --verify to re-run; keeps branch (frees slot)
|
|
79944
80002
|
teardown <id> free the slot without recording a completion validation
|
|
79945
80003
|
|
|
79946
80004
|
Occupied slots:
|
|
@@ -80168,11 +80226,15 @@ var envCommand = {
|
|
|
80168
80226
|
handleTeardown
|
|
80169
80227
|
).command(
|
|
80170
80228
|
"complete <id>",
|
|
80171
|
-
"Finish a session:
|
|
80172
|
-
(y) => y.positional("id", { type: "number", describe: "Agent slot id (see .har/stages.json agentSlots)" }).option("repo", { type: "string", default: "." }).option("
|
|
80229
|
+
"Finish a session: reuse the last matching full validation, teardown, keep the branch for a PR",
|
|
80230
|
+
(y) => y.positional("id", { type: "number", describe: "Agent slot id (see .har/stages.json agentSlots)" }).option("repo", { type: "string", default: "." }).option("verify", {
|
|
80173
80231
|
type: "boolean",
|
|
80174
80232
|
default: false,
|
|
80175
|
-
describe: "
|
|
80233
|
+
describe: "Re-run full verification before teardown (use when the tree may have changed since the last passing --full)"
|
|
80234
|
+
}).option("skip-verify", {
|
|
80235
|
+
type: "boolean",
|
|
80236
|
+
hidden: true,
|
|
80237
|
+
describe: "Deprecated no-op: complete already skips re-verification by default"
|
|
80176
80238
|
}),
|
|
80177
80239
|
handleComplete
|
|
80178
80240
|
).command(
|
|
@@ -80694,6 +80756,7 @@ async function handleComplete(argv) {
|
|
|
80694
80756
|
const result = await completeEnvironment({
|
|
80695
80757
|
repoPath: repo,
|
|
80696
80758
|
agentId,
|
|
80759
|
+
verify: argv.verify,
|
|
80697
80760
|
skipVerify: argv.skipVerify,
|
|
80698
80761
|
capture: false
|
|
80699
80762
|
});
|
|
@@ -90261,6 +90324,14 @@ async function runLineGate(options) {
|
|
|
90261
90324
|
}
|
|
90262
90325
|
const registry2 = readStageRegistry(repoPath);
|
|
90263
90326
|
const registeredIds = new Set(registry2.stages.map((s) => s.id));
|
|
90327
|
+
if (options.agentId === void 0) {
|
|
90328
|
+
const needSlot = required2.filter((stage) => registry2.stages.find((s) => s.id === stage.id)?.requiresAgentId).map((stage) => stage.id);
|
|
90329
|
+
if (needSlot.length > 0) {
|
|
90330
|
+
throw new Error(
|
|
90331
|
+
`Gate stage(s) ${needSlot.join(", ")} run in an agent slot \u2014 pass --agent <id> (har line gate ${options.station} --line ${lineId} --agent 1).`
|
|
90332
|
+
);
|
|
90333
|
+
}
|
|
90334
|
+
}
|
|
90264
90335
|
const results = [];
|
|
90265
90336
|
let pass = true;
|
|
90266
90337
|
for (const stage of required2) {
|
|
@@ -90431,7 +90502,12 @@ var PreflightEnvironmentOutputSchema = ShellRunOutputSchema.extend({
|
|
|
90431
90502
|
var CompleteEnvironmentInputSchema = external_exports.object({
|
|
90432
90503
|
repo: external_exports.string().default("."),
|
|
90433
90504
|
agentId: agentIdSchema,
|
|
90434
|
-
|
|
90505
|
+
verify: external_exports.boolean().optional().describe(
|
|
90506
|
+
"Re-run full verification before teardown when the tree may have changed since the last passing --full"
|
|
90507
|
+
),
|
|
90508
|
+
skipVerify: external_exports.boolean().optional().describe(
|
|
90509
|
+
"Deprecated. Complete already skips re-verification by default. Pass verify=true to re-run; skipVerify=false still forces a re-run."
|
|
90510
|
+
)
|
|
90435
90511
|
});
|
|
90436
90512
|
var CompleteEnvironmentOutputSchema = ShellRunOutputSchema.extend({
|
|
90437
90513
|
branch: external_exports.string().optional().describe("Session branch kept for the user to push / open a PR"),
|
|
@@ -90739,14 +90815,18 @@ var HAR_MCP_TOOLS = [
|
|
|
90739
90815
|
},
|
|
90740
90816
|
{
|
|
90741
90817
|
name: "har_complete_environment",
|
|
90742
|
-
description: "Finish a session when the work is done:
|
|
90818
|
+
description: "Finish a session when the work is done: reuses the last passing full validation for the current worktree (or re-runs verify when verify=true), tears the slot down, and KEEPS the session branch so the user can push it and open a PR.",
|
|
90743
90819
|
inputSchema: objectJsonSchema(
|
|
90744
90820
|
{
|
|
90745
90821
|
repo: repoJsonProperty,
|
|
90746
90822
|
agentId: agentIdJsonProperty,
|
|
90823
|
+
verify: {
|
|
90824
|
+
type: "boolean",
|
|
90825
|
+
description: "Re-run full verification before teardown when the tree may have changed since the last passing --full"
|
|
90826
|
+
},
|
|
90747
90827
|
skipVerify: {
|
|
90748
90828
|
type: "boolean",
|
|
90749
|
-
description: "
|
|
90829
|
+
description: "Deprecated. Complete already skips re-verification by default. Pass verify=true to re-run."
|
|
90750
90830
|
}
|
|
90751
90831
|
},
|
|
90752
90832
|
["agentId"]
|
|
@@ -91083,6 +91163,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
|
|
|
91083
91163
|
const result = await completeEnvironment({
|
|
91084
91164
|
repoPath: repo,
|
|
91085
91165
|
agentId,
|
|
91166
|
+
verify: input.verify,
|
|
91086
91167
|
skipVerify: input.skipVerify,
|
|
91087
91168
|
capture: true,
|
|
91088
91169
|
trigger: "mcp"
|
|
@@ -91277,7 +91358,7 @@ var ONBOARDING_GUIDE_STEPS = [
|
|
|
91277
91358
|
body: [
|
|
91278
91359
|
"Quick: har env verify <id>",
|
|
91279
91360
|
"Done: har env verify <id> --full then har env complete <id>",
|
|
91280
|
-
"`complete`
|
|
91361
|
+
"`complete` reuses the last matching full validation, frees the slot, and keeps the session branch for a PR. Pass --verify if the tree changed."
|
|
91281
91362
|
].join("\n")
|
|
91282
91363
|
},
|
|
91283
91364
|
{
|
|
@@ -92459,6 +92540,12 @@ async function handleStatus3(argv) {
|
|
|
92459
92540
|
info(`Mission Control: ${apiUrl} (${reachable ? "reachable" : "not reachable"})`);
|
|
92460
92541
|
info(`OTLP endpoint: ${payload.otelEndpoint}`);
|
|
92461
92542
|
info(`Hooks home: ${payload.otelHooksHome}`);
|
|
92543
|
+
if (enabled && !reachable) {
|
|
92544
|
+
warn(
|
|
92545
|
+
"Agent hooks are installed but Mission Control is not reachable \u2014 each turn pays the export timeout for telemetry nobody receives."
|
|
92546
|
+
);
|
|
92547
|
+
info("Start it with: har control up \u2022 or stop exporting: har telemetry off");
|
|
92548
|
+
}
|
|
92462
92549
|
printSignals();
|
|
92463
92550
|
}
|
|
92464
92551
|
async function handleOn(argv) {
|
|
@@ -57,7 +57,8 @@ Do not substitute ad-hoc test commands for harness verification. Any edit after
|
|
|
57
57
|
## 5. Finish
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
har env complete <id> #
|
|
60
|
+
har env complete <id> # reuse last passing full validation + teardown, keeps the session branch
|
|
61
|
+
har env complete <id> --verify # re-run full verify first if the tree may have changed
|
|
61
62
|
```
|
|
62
63
|
|
|
63
64
|
Report to the user: verification result, the session branch name (so they can push / open a PR), and the slot preview URLs if the app is running.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
- [ ] New behavior has automated test coverage
|
|
7
7
|
- [ ] Changes committed **in the session worktree** with a clear message
|
|
8
8
|
- [ ] Present session handoff (summary, branch, preview URLs) and **wait for user** before `complete`, push, or PR
|
|
9
|
-
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete <id>` (or MCP `har_complete_environment`) —
|
|
9
|
+
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete <id>` (or MCP `har_complete_environment`) — reuse last passing full validation + teardown, branch kept. Pass `--verify` / `verify: true` if the tree may have changed.
|
|
10
10
|
|
|
11
11
|
### Session handoff
|
|
12
12
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- [ ] Changes committed **in the session worktree** with a clear message
|
|
8
8
|
- [ ] The user got the preview URLs to test the app themselves
|
|
9
9
|
- [ ] Present session handoff (summary, branch, preview URLs) and **wait for user** before `complete`, push, or PR
|
|
10
|
-
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete <id>` (or MCP `har_complete_environment`) —
|
|
10
|
+
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete <id>` (or MCP `har_complete_environment`) — reuse last passing full validation + teardown, branch kept. Pass `--verify` / `verify: true` if the tree may have changed.
|
|
11
11
|
|
|
12
12
|
### Session handoff
|
|
13
13
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
- [ ] New behavior has automated test coverage (unit tests via XCTest)
|
|
7
7
|
- [ ] Changes committed **in the session worktree** with a clear message
|
|
8
8
|
- [ ] Present session handoff (summary, branch, preview URLs) and **wait for user** before `complete`, push, or PR
|
|
9
|
-
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete <id>` (or MCP `har_complete_environment`) —
|
|
9
|
+
- [ ] On user approval of the default: push + open PR (when `gh`/GitHub MCP available), then `har env complete <id>` (or MCP `har_complete_environment`) — reuse last passing full validation + teardown, branch kept. Pass `--verify` / `verify: true` if the tree may have changed.
|
|
10
10
|
|
|
11
11
|
### Session handoff
|
|
12
12
|
|
|
@@ -15,6 +15,7 @@ never in the main checkout.
|
|
|
15
15
|
or open a PR (`--delete-branch` to drop it).
|
|
16
16
|
- If launch fails after creating a worktree/env file, the registry records `status: failed`.
|
|
17
17
|
Resume it instead of starting fresh: `har env launch <id> --resume` or `har env recover <id>`.
|
|
18
|
-
- `har env complete <id>` finishes a session:
|
|
19
|
-
then teardown — branch kept.
|
|
18
|
+
- `har env complete <id>` finishes a session: reuses the last matching passing
|
|
19
|
+
full validation, then teardown — branch kept. Pass `--verify` to re-run full
|
|
20
|
+
verify if the tree may have changed.
|
|
20
21
|
- `--no-worktree` runs the slot from the repo root instead (single-agent mode).
|