@zhijiewang/openharness 2.20.0 → 2.22.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/README.md +21 -1
- package/README.zh-CN.md +21 -1
- package/dist/commands/ai.js +10 -0
- package/dist/commands/session.d.ts +18 -1
- package/dist/commands/session.js +82 -2
- package/dist/commands/settings.d.ts +1 -1
- package/dist/commands/settings.js +71 -1
- package/dist/harness/api-key-helper.d.ts +32 -0
- package/dist/harness/api-key-helper.js +70 -0
- package/dist/harness/config.d.ts +38 -0
- package/dist/harness/credentials.d.ts +6 -4
- package/dist/harness/credentials.js +15 -4
- package/dist/harness/hooks.d.ts +22 -1
- package/dist/harness/hooks.js +37 -0
- package/dist/main.js +361 -108
- package/dist/mcp/elicitation.d.ts +66 -0
- package/dist/mcp/elicitation.js +88 -0
- package/dist/mcp/loader.d.ts +29 -2
- package/dist/mcp/loader.js +59 -3
- package/dist/mcp/roots.d.ts +36 -0
- package/dist/mcp/roots.js +56 -0
- package/dist/mcp/transport.js +45 -3
- package/dist/providers/index.d.ts +25 -1
- package/dist/providers/index.js +27 -2
- package/dist/query/index.js +1 -1
- package/dist/query/tools.d.ts +2 -2
- package/dist/query/tools.js +68 -4
- package/dist/query/types.d.ts +10 -0
- package/dist/tools/EnterWorktreeTool/index.js +4 -0
- package/dist/tools/ExitWorktreeTool/index.js +7 -0
- package/dist/utils/debug.d.ts +63 -0
- package/dist/utils/debug.js +122 -0
- package/dist/utils/install-method.d.ts +42 -0
- package/dist/utils/install-method.js +110 -0
- package/package.json +1 -1
package/dist/harness/hooks.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* - prompt: LLM yes/no check via provider.complete()
|
|
11
11
|
*/
|
|
12
12
|
import { spawn, spawnSync } from "node:child_process";
|
|
13
|
+
import { debug } from "../utils/debug.js";
|
|
13
14
|
import { readOhConfig } from "./config.js";
|
|
14
15
|
let cachedHooks;
|
|
15
16
|
export function getHooks() {
|
|
@@ -22,6 +23,18 @@ export function getHooks() {
|
|
|
22
23
|
/** Clear hook cache (call after config changes) */
|
|
23
24
|
export function invalidateHookCache() {
|
|
24
25
|
cachedHooks = undefined;
|
|
26
|
+
cachedDisableAllHooks = undefined;
|
|
27
|
+
}
|
|
28
|
+
let cachedDisableAllHooks;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the configured `disableAllHooks` kill switch is set.
|
|
31
|
+
* Cached so the per-emit cost is a single boolean read.
|
|
32
|
+
*/
|
|
33
|
+
export function areHooksEnabled() {
|
|
34
|
+
if (cachedDisableAllHooks === undefined) {
|
|
35
|
+
cachedDisableAllHooks = readOhConfig()?.disableAllHooks === true;
|
|
36
|
+
}
|
|
37
|
+
return !cachedDisableAllHooks;
|
|
25
38
|
}
|
|
26
39
|
function buildEnv(event, ctx) {
|
|
27
40
|
const env = {
|
|
@@ -71,6 +84,22 @@ function buildEnv(event, ctx) {
|
|
|
71
84
|
env.OH_TURN_NUMBER = ctx.turnNumber;
|
|
72
85
|
if (ctx.turnReason !== undefined)
|
|
73
86
|
env.OH_TURN_REASON = ctx.turnReason;
|
|
87
|
+
if (ctx.worktreePath !== undefined)
|
|
88
|
+
env.OH_WORKTREE_PATH = ctx.worktreePath;
|
|
89
|
+
if (ctx.worktreeParent !== undefined)
|
|
90
|
+
env.OH_WORKTREE_PARENT = ctx.worktreeParent;
|
|
91
|
+
if (ctx.worktreeForced !== undefined)
|
|
92
|
+
env.OH_WORKTREE_FORCED = ctx.worktreeForced;
|
|
93
|
+
if (ctx.elicitationServer !== undefined)
|
|
94
|
+
env.OH_ELICITATION_SERVER = ctx.elicitationServer;
|
|
95
|
+
if (ctx.elicitationMessage !== undefined)
|
|
96
|
+
env.OH_ELICITATION_MESSAGE = ctx.elicitationMessage;
|
|
97
|
+
if (ctx.elicitationSchema !== undefined)
|
|
98
|
+
env.OH_ELICITATION_SCHEMA = ctx.elicitationSchema;
|
|
99
|
+
if (ctx.elicitationAction !== undefined)
|
|
100
|
+
env.OH_ELICITATION_ACTION = ctx.elicitationAction;
|
|
101
|
+
if (ctx.elicitationContent !== undefined)
|
|
102
|
+
env.OH_ELICITATION_CONTENT = ctx.elicitationContent;
|
|
74
103
|
return env;
|
|
75
104
|
}
|
|
76
105
|
/**
|
|
@@ -400,10 +429,14 @@ async function executeHookDef(def, event, ctx) {
|
|
|
400
429
|
* All other hooks run asynchronously to avoid blocking the event loop.
|
|
401
430
|
*/
|
|
402
431
|
export function emitHook(event, ctx = {}) {
|
|
432
|
+
if (!areHooksEnabled())
|
|
433
|
+
return true;
|
|
403
434
|
const hooks = getHooks();
|
|
404
435
|
if (!hooks)
|
|
405
436
|
return true;
|
|
406
437
|
const defs = hooks[event] ?? [];
|
|
438
|
+
if (defs.length > 0)
|
|
439
|
+
debug("hooks", "fire", { event, count: defs.length, tool: ctx.toolName });
|
|
407
440
|
const env = buildEnv(event, ctx);
|
|
408
441
|
if (event === "preToolUse") {
|
|
409
442
|
// preToolUse command hooks must be synchronous — they gate tool execution
|
|
@@ -456,6 +489,8 @@ export function emitHook(event, ctx = {}) {
|
|
|
456
489
|
* Supports all hook types (command, HTTP, prompt).
|
|
457
490
|
*/
|
|
458
491
|
export async function emitHookAsync(event, ctx = {}) {
|
|
492
|
+
if (!areHooksEnabled())
|
|
493
|
+
return true;
|
|
459
494
|
const hooks = getHooks();
|
|
460
495
|
if (!hooks)
|
|
461
496
|
return true;
|
|
@@ -570,6 +605,8 @@ async function runHookForOutcome(def, event, ctx) {
|
|
|
570
605
|
* from hooks is ignored — outcome.allowed is always true. additionalContext is still collected.
|
|
571
606
|
*/
|
|
572
607
|
export async function emitHookWithOutcome(event, ctx = {}) {
|
|
608
|
+
if (!areHooksEnabled())
|
|
609
|
+
return { allowed: true };
|
|
573
610
|
const hooks = getHooks();
|
|
574
611
|
const list = hooks?.[event];
|
|
575
612
|
if (!list || list.length === 0)
|