niahere 0.3.4 → 0.3.5
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/package.json +1 -1
- package/src/chat/engine.ts +2 -0
- package/src/core/runner.ts +2 -0
- package/src/core/sdk-hooks.ts +43 -0
package/package.json
CHANGED
package/src/chat/engine.ts
CHANGED
|
@@ -27,6 +27,7 @@ import { isRetryableApiError, sleep } from "../utils/retry";
|
|
|
27
27
|
import { registerActiveHandle, unregisterActiveHandle } from "../core/active-handles";
|
|
28
28
|
import { resolveJobPrompt } from "../core/job-prompt";
|
|
29
29
|
import { getSdkSkillsSetting } from "../core/skills";
|
|
30
|
+
import { getSdkHooks } from "../core/sdk-hooks";
|
|
30
31
|
|
|
31
32
|
const IDLE_TIMEOUT = 10 * 60 * 1000; // 10 minutes
|
|
32
33
|
const LONG_RUNNING_WARN = 30 * 60 * 1000; // 30 minutes
|
|
@@ -332,6 +333,7 @@ export async function createChatEngine(opts: EngineOptions): Promise<ChatEngine>
|
|
|
332
333
|
includePartialMessages: true,
|
|
333
334
|
settingSources: ["project", "user"],
|
|
334
335
|
skills: getSdkSkillsSetting(),
|
|
336
|
+
hooks: getSdkHooks(),
|
|
335
337
|
};
|
|
336
338
|
const model = resolveSdkModel(contextModel);
|
|
337
339
|
if (model) {
|
package/src/core/runner.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { log } from "../utils/log";
|
|
|
18
18
|
import { isRetryableApiError, sleep } from "../utils/retry";
|
|
19
19
|
import { registerActiveHandle, unregisterActiveHandle } from "./active-handles";
|
|
20
20
|
import { getSdkSkillsSetting } from "./skills";
|
|
21
|
+
import { getSdkHooks } from "./sdk-hooks";
|
|
21
22
|
|
|
22
23
|
export { buildWorkingMemory } from "./job-prompt";
|
|
23
24
|
|
|
@@ -121,6 +122,7 @@ export async function runJobWithClaude(
|
|
|
121
122
|
permissionMode: "bypassPermissions",
|
|
122
123
|
sessionId,
|
|
123
124
|
skills: getSdkSkillsSetting(),
|
|
125
|
+
hooks: getSdkHooks(),
|
|
124
126
|
};
|
|
125
127
|
|
|
126
128
|
if (model && model !== "default") {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HookCallbackMatcher,
|
|
3
|
+
HookEvent,
|
|
4
|
+
HookJSONOutput,
|
|
5
|
+
PreToolUseHookInput,
|
|
6
|
+
} from "@anthropic-ai/claude-agent-sdk";
|
|
7
|
+
|
|
8
|
+
const GH_MERGE_PATTERN = /(?:^|[\s;&|(])gh\s+pr\s+merge(?:\s|$)/;
|
|
9
|
+
|
|
10
|
+
const STAMP_WARNING_CONTEXT = [
|
|
11
|
+
"PreToolUse warning: this Bash command merges a GitHub PR.",
|
|
12
|
+
"If the user only wants to APPROVE the PR (LGTM), use the gh-stamp skill",
|
|
13
|
+
'(`gh pr comment <pr> --body "LGTM, Stamped ✅"`) instead of merging.',
|
|
14
|
+
"Confirm intent before proceeding.",
|
|
15
|
+
].join(" ");
|
|
16
|
+
|
|
17
|
+
const STAMP_WARNING_MESSAGE =
|
|
18
|
+
"Heads up: about to run `gh pr merge`. Did you mean to STAMP (LGTM approval) instead? See the gh-stamp skill.";
|
|
19
|
+
|
|
20
|
+
const warnOnGhMerge: HookCallbackMatcher = {
|
|
21
|
+
matcher: "Bash",
|
|
22
|
+
hooks: [
|
|
23
|
+
async (input): Promise<HookJSONOutput> => {
|
|
24
|
+
if (input.hook_event_name !== "PreToolUse") return {};
|
|
25
|
+
const command = (input as PreToolUseHookInput).tool_input as { command?: unknown } | undefined;
|
|
26
|
+
const cmd = command?.command;
|
|
27
|
+
if (typeof cmd !== "string" || !GH_MERGE_PATTERN.test(cmd)) return {};
|
|
28
|
+
return {
|
|
29
|
+
systemMessage: STAMP_WARNING_MESSAGE,
|
|
30
|
+
hookSpecificOutput: {
|
|
31
|
+
hookEventName: "PreToolUse",
|
|
32
|
+
additionalContext: STAMP_WARNING_CONTEXT,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function getSdkHooks(): Partial<Record<HookEvent, HookCallbackMatcher[]>> {
|
|
40
|
+
return {
|
|
41
|
+
PreToolUse: [warnOnGhMerge],
|
|
42
|
+
};
|
|
43
|
+
}
|