@osfactory/har 0.12.1 → 0.13.1
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 +88 -66
- package/package.json +1 -1
- package/control/docker-compose.build.yml +0 -7
- package/control/docker-compose.yml +0 -31
package/dist/index.js
CHANGED
|
@@ -23367,7 +23367,7 @@ async function handleAgentSkills(options) {
|
|
|
23367
23367
|
const { repoPath, mode } = options;
|
|
23368
23368
|
if (options.enabled === false) return false;
|
|
23369
23369
|
let targets;
|
|
23370
|
-
if (options.agents
|
|
23370
|
+
if (typeof options.agents === "string") {
|
|
23371
23371
|
targets = parseAgentTargets(options.agents);
|
|
23372
23372
|
} else {
|
|
23373
23373
|
targets = detectAgentTargets(repoPath);
|
|
@@ -30532,54 +30532,88 @@ function shouldBuildControlLocally() {
|
|
|
30532
30532
|
}
|
|
30533
30533
|
|
|
30534
30534
|
// src/core/control-lifecycle.ts
|
|
30535
|
+
var CONTROL_CONTAINER_NAME = "har-control";
|
|
30536
|
+
var CONTROL_DATA_VOLUME = "har_control_data";
|
|
30537
|
+
var CONTROL_CONTAINER_PORT = 3847;
|
|
30538
|
+
var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
|
|
30535
30539
|
function resolveControlDir() {
|
|
30536
30540
|
return path38.resolve(__dirname, "..", "control");
|
|
30537
30541
|
}
|
|
30538
|
-
function
|
|
30539
|
-
|
|
30540
|
-
const files = [path38.join(controlDir, "docker-compose.yml")];
|
|
30541
|
-
if (options?.build ?? shouldBuildControlLocally()) {
|
|
30542
|
-
files.push(path38.join(controlDir, "docker-compose.build.yml"));
|
|
30543
|
-
}
|
|
30544
|
-
return files;
|
|
30542
|
+
function resolveControlBuildContext() {
|
|
30543
|
+
return path38.resolve(resolveControlDir(), "..");
|
|
30545
30544
|
}
|
|
30546
|
-
function
|
|
30547
|
-
|
|
30548
|
-
|
|
30549
|
-
|
|
30550
|
-
|
|
30551
|
-
|
|
30545
|
+
function buildDockerRunArgs(options) {
|
|
30546
|
+
const name = options.containerName ?? CONTROL_CONTAINER_NAME;
|
|
30547
|
+
const volume = options.volume ?? CONTROL_DATA_VOLUME;
|
|
30548
|
+
const args = ["run", "--name", name];
|
|
30549
|
+
if (options.detach) {
|
|
30550
|
+
args.push("-d", "--restart", "unless-stopped");
|
|
30551
|
+
} else {
|
|
30552
|
+
args.push("--rm");
|
|
30553
|
+
}
|
|
30554
|
+
args.push(
|
|
30555
|
+
"-p",
|
|
30556
|
+
`${options.hostPort}:${CONTROL_CONTAINER_PORT}`,
|
|
30557
|
+
"-v",
|
|
30558
|
+
`${volume}:/data`,
|
|
30559
|
+
"-e",
|
|
30560
|
+
`DATABASE_URL=${CONTROL_DATA_DB_URL}`,
|
|
30561
|
+
options.imageRef
|
|
30562
|
+
);
|
|
30563
|
+
return args;
|
|
30552
30564
|
}
|
|
30553
|
-
function
|
|
30554
|
-
const
|
|
30555
|
-
const composeFiles = resolveControlComposeFiles(options);
|
|
30556
|
-
const composeArgs = composeFiles.flatMap((file) => ["-f", file]);
|
|
30557
|
-
const result = (0, import_child_process8.spawnSync)("docker", ["compose", ...composeArgs, ...args], {
|
|
30558
|
-
cwd: controlDir,
|
|
30565
|
+
function runDocker(args) {
|
|
30566
|
+
const result = (0, import_child_process8.spawnSync)("docker", args, {
|
|
30559
30567
|
stdio: "inherit",
|
|
30560
|
-
env:
|
|
30568
|
+
env: process.env
|
|
30561
30569
|
});
|
|
30562
30570
|
if (result.error) {
|
|
30563
30571
|
throw result.error;
|
|
30564
30572
|
}
|
|
30565
30573
|
return result.status ?? 1;
|
|
30566
30574
|
}
|
|
30575
|
+
function controlContainerExists(name = CONTROL_CONTAINER_NAME) {
|
|
30576
|
+
const result = (0, import_child_process8.spawnSync)("docker", ["ps", "-aq", "-f", `name=^${name}$`], {
|
|
30577
|
+
encoding: "utf8",
|
|
30578
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
30579
|
+
});
|
|
30580
|
+
return (result.stdout ?? "").trim().length > 0;
|
|
30581
|
+
}
|
|
30582
|
+
function stopMissionControl() {
|
|
30583
|
+
if (!controlContainerExists()) {
|
|
30584
|
+
return 0;
|
|
30585
|
+
}
|
|
30586
|
+
return runDocker(["rm", "-f", CONTROL_CONTAINER_NAME]);
|
|
30587
|
+
}
|
|
30567
30588
|
async function startMissionControl(options) {
|
|
30568
30589
|
const build = options.build ?? shouldBuildControlLocally();
|
|
30569
30590
|
const imageRef = getControlImageRef();
|
|
30570
|
-
|
|
30571
|
-
|
|
30591
|
+
const apiUrl = getControlApiUrl();
|
|
30592
|
+
const hostPort = parseControlHostPort(apiUrl);
|
|
30593
|
+
if (build) {
|
|
30594
|
+
const buildCode = runDocker([
|
|
30595
|
+
"build",
|
|
30596
|
+
"-t",
|
|
30597
|
+
imageRef,
|
|
30598
|
+
"-f",
|
|
30599
|
+
path38.join(resolveControlDir(), "Dockerfile"),
|
|
30600
|
+
resolveControlBuildContext()
|
|
30601
|
+
]);
|
|
30602
|
+
if (buildCode !== 0) {
|
|
30603
|
+
return { code: buildCode, apiUrl, imageRef };
|
|
30604
|
+
}
|
|
30605
|
+
} else {
|
|
30606
|
+
const pullCode = runDocker(["pull", imageRef]);
|
|
30572
30607
|
if (pullCode !== 0) {
|
|
30573
|
-
return { code: pullCode, apiUrl
|
|
30608
|
+
return { code: pullCode, apiUrl, imageRef };
|
|
30574
30609
|
}
|
|
30575
30610
|
}
|
|
30576
|
-
|
|
30577
|
-
|
|
30578
|
-
if (build) {
|
|
30579
|
-
upArgs.push("--build");
|
|
30611
|
+
if (controlContainerExists()) {
|
|
30612
|
+
runDocker(["rm", "-f", CONTROL_CONTAINER_NAME]);
|
|
30580
30613
|
}
|
|
30581
|
-
const
|
|
30582
|
-
|
|
30614
|
+
const detach = options.detach !== false;
|
|
30615
|
+
const code = runDocker(buildDockerRunArgs({ imageRef, hostPort, detach }));
|
|
30616
|
+
return { code, apiUrl, imageRef };
|
|
30583
30617
|
}
|
|
30584
30618
|
async function syncReposAfterControlStart(cwd) {
|
|
30585
30619
|
if (!isControlEnabled()) {
|
|
@@ -31075,19 +31109,14 @@ var envCommand = {
|
|
|
31075
31109
|
describe: "Auto-apply AGENT.md proposal without prompting (--auto only)"
|
|
31076
31110
|
}).option("cursor-rule", {
|
|
31077
31111
|
type: "boolean",
|
|
31078
|
-
default: false
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
type: "boolean",
|
|
31082
|
-
default: false,
|
|
31083
|
-
describe: "Skip Cursor rule scaffolding"
|
|
31112
|
+
// No default: unset → prompt/auto-detect; --cursor-rule → true; --no-cursor-rule → false
|
|
31113
|
+
// (do not declare a separate --no-cursor-rule option — yargs negation owns that.)
|
|
31114
|
+
describe: "Create .cursor/rules/har-workflow.mdc without prompting (use --no-cursor-rule to skip)"
|
|
31084
31115
|
}).option("agents", {
|
|
31085
31116
|
type: "string",
|
|
31086
|
-
|
|
31087
|
-
|
|
31088
|
-
|
|
31089
|
-
default: false,
|
|
31090
|
-
describe: "Skip agent skills scaffolding"
|
|
31117
|
+
// --no-agents is yargs negation of this string option (sets agents=false). Do not
|
|
31118
|
+
// declare a separate --no-agents boolean — it collides and crashes parseAgentTargets.
|
|
31119
|
+
describe: "Scaffold agent skills for these targets (comma-separated: claude,cursor,codex); auto-detected when omitted; --no-agents to skip"
|
|
31091
31120
|
}),
|
|
31092
31121
|
handleInit
|
|
31093
31122
|
).command(
|
|
@@ -31106,19 +31135,11 @@ var envCommand = {
|
|
|
31106
31135
|
describe: "Adaptation summary to store in the manifest (--finalize only)"
|
|
31107
31136
|
}).option("cursor-rule", {
|
|
31108
31137
|
type: "boolean",
|
|
31109
|
-
default: false
|
|
31110
|
-
describe: "Create .cursor/rules/har-workflow.mdc without prompting"
|
|
31111
|
-
}).option("no-cursor-rule", {
|
|
31112
|
-
type: "boolean",
|
|
31113
|
-
default: false,
|
|
31114
|
-
describe: "Skip Cursor rule scaffolding"
|
|
31138
|
+
// No default: unset → prompt/auto-detect; --cursor-rule → true; --no-cursor-rule → false
|
|
31139
|
+
describe: "Create .cursor/rules/har-workflow.mdc without prompting (use --no-cursor-rule to skip)"
|
|
31115
31140
|
}).option("agents", {
|
|
31116
31141
|
type: "string",
|
|
31117
|
-
describe: "Scaffold agent skills for these targets (comma-separated: claude,cursor,codex); auto-detected when omitted"
|
|
31118
|
-
}).option("no-agents", {
|
|
31119
|
-
type: "boolean",
|
|
31120
|
-
default: false,
|
|
31121
|
-
describe: "Skip agent skills scaffolding"
|
|
31142
|
+
describe: "Scaffold agent skills for these targets (comma-separated: claude,cursor,codex); auto-detected when omitted; --no-agents to skip"
|
|
31122
31143
|
}),
|
|
31123
31144
|
handleMaintain
|
|
31124
31145
|
).command(
|
|
@@ -31294,14 +31315,13 @@ async function handleInit(argv) {
|
|
|
31294
31315
|
recordRepoForControlSync(repoPath);
|
|
31295
31316
|
await handleCursorRule({
|
|
31296
31317
|
repoPath,
|
|
31297
|
-
cursorRule: resolveCursorRuleFlag(argv.cursorRule
|
|
31318
|
+
cursorRule: resolveCursorRuleFlag(argv.cursorRule),
|
|
31298
31319
|
autoYes: argv.yes,
|
|
31299
31320
|
mode: "init"
|
|
31300
31321
|
});
|
|
31301
31322
|
await handleAgentSkills({
|
|
31302
31323
|
repoPath,
|
|
31303
|
-
|
|
31304
|
-
enabled: argv.noAgents ? false : void 0,
|
|
31324
|
+
...resolveAgentsScaffoldOptions(argv.agents),
|
|
31305
31325
|
autoYes: argv.yes,
|
|
31306
31326
|
force: argv.force,
|
|
31307
31327
|
mode: "init"
|
|
@@ -31367,14 +31387,13 @@ async function handleMaintain(argv) {
|
|
|
31367
31387
|
}
|
|
31368
31388
|
await handleCursorRule({
|
|
31369
31389
|
repoPath,
|
|
31370
|
-
cursorRule: resolveCursorRuleFlag(argv.cursorRule
|
|
31390
|
+
cursorRule: resolveCursorRuleFlag(argv.cursorRule),
|
|
31371
31391
|
autoYes: argv.yes,
|
|
31372
31392
|
mode: "maintain"
|
|
31373
31393
|
});
|
|
31374
31394
|
await handleAgentSkills({
|
|
31375
31395
|
repoPath,
|
|
31376
|
-
|
|
31377
|
-
enabled: argv.noAgents ? false : void 0,
|
|
31396
|
+
...resolveAgentsScaffoldOptions(argv.agents),
|
|
31378
31397
|
autoYes: argv.yes,
|
|
31379
31398
|
mode: "maintain"
|
|
31380
31399
|
});
|
|
@@ -31383,10 +31402,13 @@ async function handleMaintain(argv) {
|
|
|
31383
31402
|
process.exit(1);
|
|
31384
31403
|
}
|
|
31385
31404
|
}
|
|
31386
|
-
function resolveCursorRuleFlag(cursorRule
|
|
31387
|
-
|
|
31388
|
-
|
|
31389
|
-
|
|
31405
|
+
function resolveCursorRuleFlag(cursorRule) {
|
|
31406
|
+
return cursorRule;
|
|
31407
|
+
}
|
|
31408
|
+
function resolveAgentsScaffoldOptions(agents) {
|
|
31409
|
+
if (agents === false) return { enabled: false };
|
|
31410
|
+
if (typeof agents === "string") return { agents };
|
|
31411
|
+
return {};
|
|
31390
31412
|
}
|
|
31391
31413
|
function emitManualAdaptationPrompt(repoPath, mode, profile = "default", bundleReport) {
|
|
31392
31414
|
const prompt = mode === "init" ? buildInitAdaptationPrompt(repoPath, profile) : buildMaintainAdaptationPrompt(repoPath, bundleReport);
|
|
@@ -31750,7 +31772,7 @@ var controlCommand = {
|
|
|
31750
31772
|
describe: "Mission Control dashboard (local)",
|
|
31751
31773
|
builder: (yargs) => yargs.command(
|
|
31752
31774
|
"up",
|
|
31753
|
-
"Start Mission Control (Docker
|
|
31775
|
+
"Start Mission Control (single Docker container, SQLite)",
|
|
31754
31776
|
(y2) => y2.option("detach", { alias: "d", type: "boolean", default: true }).option("build", {
|
|
31755
31777
|
type: "boolean",
|
|
31756
31778
|
default: false,
|
|
@@ -31843,7 +31865,7 @@ async function handleUp(argv) {
|
|
|
31843
31865
|
}
|
|
31844
31866
|
async function handleDown() {
|
|
31845
31867
|
header("har control down");
|
|
31846
|
-
const code =
|
|
31868
|
+
const code = stopMissionControl();
|
|
31847
31869
|
process.exit(code);
|
|
31848
31870
|
}
|
|
31849
31871
|
async function handleRegister(argv) {
|
|
@@ -39867,10 +39889,10 @@ var HAR_MCP_TOOLS = [
|
|
|
39867
39889
|
},
|
|
39868
39890
|
{
|
|
39869
39891
|
name: "har_control_up",
|
|
39870
|
-
description: "Start local Mission Control (Docker
|
|
39892
|
+
description: "Start local Mission Control (a single self-contained Docker container backed by SQLite) and sync all harness repositories that were initialized with har env init.",
|
|
39871
39893
|
inputSchema: objectJsonSchema({
|
|
39872
39894
|
repo: repoJsonProperty,
|
|
39873
|
-
detach: { type: "boolean", description: "Run
|
|
39895
|
+
detach: { type: "boolean", description: "Run the container in detached mode (default true)" }
|
|
39874
39896
|
})
|
|
39875
39897
|
}
|
|
39876
39898
|
];
|
package/package.json
CHANGED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
services:
|
|
2
|
-
db:
|
|
3
|
-
image: postgres:16-alpine
|
|
4
|
-
environment:
|
|
5
|
-
POSTGRES_USER: har
|
|
6
|
-
POSTGRES_PASSWORD: har
|
|
7
|
-
POSTGRES_DB: har_control
|
|
8
|
-
ports:
|
|
9
|
-
- "5433:5432"
|
|
10
|
-
volumes:
|
|
11
|
-
- har_control_pg:/var/lib/postgresql/data
|
|
12
|
-
healthcheck:
|
|
13
|
-
test: ["CMD-SHELL", "pg_isready -U har -d har_control"]
|
|
14
|
-
interval: 5s
|
|
15
|
-
timeout: 5s
|
|
16
|
-
retries: 5
|
|
17
|
-
|
|
18
|
-
app:
|
|
19
|
-
image: ${HAR_CONTROL_IMAGE:-theosfactory/har-control}:${HAR_CONTROL_IMAGE_TAG}
|
|
20
|
-
pull_policy: always
|
|
21
|
-
ports:
|
|
22
|
-
- "3847:3847"
|
|
23
|
-
environment:
|
|
24
|
-
DATABASE_URL: postgresql://har:har@db:5432/har_control
|
|
25
|
-
NODE_ENV: production
|
|
26
|
-
depends_on:
|
|
27
|
-
db:
|
|
28
|
-
condition: service_healthy
|
|
29
|
-
|
|
30
|
-
volumes:
|
|
31
|
-
har_control_pg:
|