@hmharness/agent 0.23.20 → 0.23.22

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.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- export { baseTools, readFileTool, writeFileTool, listDirTool, runCommandTool, rememberTool, seeImageTool } from './tools.js';
2
- export { manifestFor, capabilityReport, authorize, type CapabilityManifest, type CapabilityRisk, type PolicyMode } from './capability.js';
3
- export { checkpointProject, createProject, findProject, interruptProject, listProjects, loadProject, projectFor, releaseProject, restoreCheckpoint, resumeBundle, transitionProject, attachRun, newProjectId, type CheckpointRef, type DecisionEntry, type ProjectRecord, type ProjectState, } from './project.js';
4
- export { mechanicalGate, parseVerdict, runPipeline, type PipelineOptions, type PipelineReport, type StageRecord, type StageRole, } from './pipeline.js';
5
- export { buildSystemPrompt } from './prompt.js';
6
- export { strings, type Locale, type Strings } from './i18n.js';
7
- export { makeSpawnTool, MAX_SPAWN_DEPTH, type SpawnBase } from './spawn.js';
8
- export { withTopologyGovernance, mapRole, liveTopologySnapshot, teamLog } from './topology-live.js';
9
- export { buildRegistry, contextPack, makeApproval, liveYolo, nativeRegistry, runAgentTask, spawnBase, toServerConfig, type AgentTaskOptions, type RunnerEvents, } from './runner.js';
10
- export * from './skills-conformance.js';
11
- export * from './acp.js';
12
- export * from './topology.js';
13
- export * from './meta-harness.js';
1
+ export { baseTools, readFileTool, writeFileTool, listDirTool, runCommandTool, rememberTool, seeImageTool } from './tools.ts';
2
+ export { manifestFor, capabilityReport, authorize, type CapabilityManifest, type CapabilityRisk, type PolicyMode } from './capability.ts';
3
+ export { checkpointProject, createProject, findProject, interruptProject, listProjects, loadProject, projectFor, releaseProject, restoreCheckpoint, resumeBundle, transitionProject, attachRun, newProjectId, type CheckpointRef, type DecisionEntry, type ProjectRecord, type ProjectState, } from './project.ts';
4
+ export { mechanicalGate, parseVerdict, runPipeline, type PipelineOptions, type PipelineReport, type StageRecord, type StageRole, } from './pipeline.ts';
5
+ export { buildSystemPrompt } from './prompt.ts';
6
+ export { strings, type Locale, type Strings } from './i18n.ts';
7
+ export { makeSpawnTool, MAX_SPAWN_DEPTH, type SpawnBase } from './spawn.ts';
8
+ export { withTopologyGovernance, mapRole, liveTopologySnapshot, teamLog } from './topology-live.ts';
9
+ export { buildRegistry, contextPack, makeApproval, liveYolo, nativeRegistry, runAgentTask, spawnBase, toServerConfig, type AgentTaskOptions, type RunnerEvents, } from './runner.ts';
10
+ export * from './skills-conformance.ts';
11
+ export * from './acp.ts';
12
+ export * from './topology.ts';
13
+ export * from './meta-harness.ts';
package/dist/runner.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  import { Registry, type ChatMessage, type DeltaKind, type HmhConfig, type LoopApproval, type LoopResult, type McpClient, type McpServerConfig, type McpServerImport, type ToolContext } from '@hmharness/kernel';
9
9
  import { type EmbeddingProvider } from '@hmharness/evolution';
10
10
  import * as readline from 'node:readline/promises';
11
- import { type SpawnBase } from './spawn.js';
11
+ import { type SpawnBase } from './spawn.ts';
12
12
  /** Flatten the config.json shape into the runtime discriminated union. */
13
13
  export declare function toServerConfig(c: McpServerImport): McpServerConfig;
14
14
  /**
@@ -20,6 +20,7 @@ export declare const spawnBase: {
20
20
  };
21
21
  export declare function nativeRegistry(depth: number, opts?: {
22
22
  lsp?: boolean;
23
+ browser?: boolean;
23
24
  workspaceRoot?: string;
24
25
  }): Registry;
25
26
  export declare function buildRegistry(opts?: {
package/dist/runner.js CHANGED
@@ -16,6 +16,7 @@ import { appendMemory, listSkills, readInsights, readNotes, retrieveInsights, re
16
16
  import { harmonyTools } from '@hmharness/domain-harmony';
17
17
  import { opsTools } from '@hmharness/domain-ops';
18
18
  import { discoverServers, lspTools } from '@hmharness/lsp';
19
+ import { discoverBrowsers, browserTools } from '@hmharness/browser';
19
20
  import * as readline from 'node:readline/promises';
20
21
  import { stdin } from 'node:process';
21
22
  import { baseTools } from "./tools.js";
@@ -51,6 +52,19 @@ export function nativeRegistry(depth, opts = {}) {
51
52
  }
52
53
  catch { /* lsp optional: never block tool assembly */ }
53
54
  }
55
+ // BrowserOS browser_* family — same rule: only when a BrowserOS binary
56
+ // is discoverable + healthy. Trust is enforced at launch time (like lsp
57
+ // clientFor): an untrusted binary produces an actionable error, not a
58
+ // dead tool. The user's daily browser is never touched — tools drive a
59
+ // dedicated instance.
60
+ if (opts.browser !== false) {
61
+ try {
62
+ if (discoverBrowsers().some((b) => b.healthy)) {
63
+ reg.registerAll(browserTools({ workspaceRoot: opts.workspaceRoot ?? process.cwd(), home: homeDir() }));
64
+ }
65
+ }
66
+ catch { /* browser optional: never block tool assembly */ }
67
+ }
54
68
  if (depth < MAX_SPAWN_DEPTH) {
55
69
  // blueprint M10: every spawn_agent is governed by the live topology
56
70
  // (role contract + shared budget + immutable multi-agent.jsonl audit);
package/dist/tools.js CHANGED
@@ -493,7 +493,7 @@ export const desktopTypeTool = {
493
493
  */
494
494
  export const browserOpenTool = {
495
495
  name: 'browser_open',
496
- description: 'Open a URL in the user\'s default browser (visible). Then use desktop_screenshot + see_image to see the page, desktop_click/desktop_type to interact. Full workflow: browser_open → desktop_screenshot → see_image (find elements) → desktop_click (click) → desktop_screenshot (verify).',
496
+ description: 'Open a URL in the user\'s default browser (visible). Then use desktop_screenshot + see_image to see the page, desktop_click/desktop_type to interact. Full workflow: browser_open → desktop_screenshot → see_image (find elements) → desktop_click (click) → desktop_screenshot (verify). When running inside a host browser (BrowserOS ACP), this navigates the host\'s active tab instead of opening a new OS window — pair it with browser_snapshot/browser_read.',
497
497
  parameters: {
498
498
  type: 'object',
499
499
  properties: {
@@ -506,6 +506,26 @@ export const browserOpenTool = {
506
506
  const url = String(args.url ?? '').trim();
507
507
  if (!/^https?:\/\//i.test(url))
508
508
  return { output: 'only http(s) URLs', isError: true };
509
+ // Under a host browser (acp-serve/BrowserOS): opening the OS default
510
+ // browser pops a SECOND window per call — the exact bug users see as
511
+ // "a new browser window on every message". Navigate the host's active
512
+ // tab instead; the browser_* family reads/verifies from there.
513
+ const attachPort = Number(process.env.HMH_BROWSER_ATTACH ?? 0);
514
+ if (Number.isInteger(attachPort) && attachPort > 0) {
515
+ try {
516
+ const { CdpBrowser } = await import('@hmharness/browser');
517
+ const c = new CdpBrowser({ port: attachPort });
518
+ if (await c.up()) {
519
+ const tabs = (await c.tabs()).filter((t) => !t.url.startsWith('chrome-extension://'));
520
+ const page = tabs.find((t) => !t.url.startsWith('about:')) ?? tabs[0];
521
+ const tid = page?.targetId ?? (await c.openTab('about:blank'));
522
+ await c.navigate(tid, url);
523
+ const title = String(await c.evaluate(tid, 'document.title').catch(() => ''));
524
+ return { output: `navigated the host browser to ${url} (title: ${title || 'loading'}) — use browser_snapshot/browser_read to see the page` };
525
+ }
526
+ }
527
+ catch { /* fall through to the default-browser path if attach fails */ }
528
+ }
509
529
  try {
510
530
  if (process.platform === 'win32') {
511
531
  const { execFile } = await import('node:child_process');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hmharness/agent",
3
- "version": "0.23.20",
3
+ "version": "0.23.22",
4
4
  "description": "hmharness agent execution layer: base tools, system prompt, sub-agent spawn, and the shared task runner that frontends (cli, web) drive.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,14 +15,15 @@
15
15
  "build": "tsc -p tsconfig.build.json"
16
16
  },
17
17
  "dependencies": {
18
- "@hmharness/cognitive": "0.23.20",
19
- "@hmharness/domain-harmony": "0.23.20",
20
- "@hmharness/domain-ops": "0.23.20",
21
- "@hmharness/evolution": "0.23.20",
22
- "@hmharness/kernel": "0.23.20",
23
- "@hmharness/observability": "0.23.20",
24
- "@hmharness/sandbox": "0.23.20",
25
- "@hmharness/lsp": "0.23.20"
18
+ "@hmharness/cognitive": "0.23.22",
19
+ "@hmharness/domain-harmony": "0.23.22",
20
+ "@hmharness/domain-ops": "0.23.22",
21
+ "@hmharness/evolution": "0.23.22",
22
+ "@hmharness/kernel": "0.23.22",
23
+ "@hmharness/observability": "0.23.22",
24
+ "@hmharness/sandbox": "0.23.22",
25
+ "@hmharness/lsp": "0.23.22",
26
+ "@hmharness/browser": "0.23.22"
26
27
  },
27
28
  "files": [
28
29
  "dist"