@lovrozagar/grunt 0.2.0 → 0.3.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/.agents/agents/grunt.md +4 -2
- package/.agents/agents/orchestrator.md +2 -2
- package/.agents/hooks.json +12 -1
- package/.agents/skills/commit/SKILL.md +21 -0
- package/.agents/skills/commit-and-push/SKILL.md +15 -0
- package/.agents/skills/explain/SKILL.md +14 -0
- package/.agents/skills/handoff/SKILL.md +84 -0
- package/.agents/skills/parent/SKILL.md +11 -0
- package/.agents/skills/solo/SKILL.md +21 -0
- package/.claude/agents/grunt.md +2 -0
- package/.claude/agents/orchestrator.md +3 -3
- package/.claude/settings.json +34 -1
- package/.claude/skills/commit/SKILL.md +21 -0
- package/.claude/skills/commit-and-push/SKILL.md +15 -0
- package/.claude/skills/explain/SKILL.md +14 -0
- package/.claude/skills/handoff/SKILL.md +84 -0
- package/.claude/skills/parent/SKILL.md +11 -0
- package/.claude/skills/solo/SKILL.md +21 -0
- package/.codex/agents/grunt.toml +4 -2
- package/.codex/agents/orchestrator.toml +2 -2
- package/.codex/hooks.json +34 -1
- package/.grok/agents/grunt.md +4 -2
- package/.grok/agents/orchestrator.md +2 -2
- package/.grok/hooks/orchestrate-parent.js +263 -29
- package/.grok/skills/commit/SKILL.md +21 -0
- package/.grok/skills/commit-and-push/SKILL.md +15 -0
- package/.grok/skills/handoff/SKILL.md +84 -0
- package/.grok/skills/solo/SKILL.md +21 -0
- package/.rulesync/hooks.jsonc +11 -3
- package/.rulesync/reference/cascade.md +4 -3
- package/.rulesync/reference/hooks.md +5 -1
- package/.rulesync/reference/map.md +18 -3
- package/.rulesync/rules/CLAUDE.md +2 -1
- package/.rulesync/rules/overview.md +2 -1
- package/.rulesync/skills/commit/SKILL.md +22 -0
- package/.rulesync/skills/commit-and-push/SKILL.md +16 -0
- package/.rulesync/skills/handoff/SKILL.md +84 -0
- package/.rulesync/skills/solo/SKILL.md +21 -0
- package/.rulesync/subagents/grunt.md +6 -2
- package/.rulesync/subagents/implementer.md +2 -0
- package/.rulesync/subagents/orchestrator.md +4 -2
- package/.rulesync/subagents/thinker.md +2 -0
- package/AGENTS.md +2 -1
- package/CLAUDE.md +2 -1
- package/README.md +2 -2
- package/cli/init.mjs +105 -6
- package/cli/init.test.ts +303 -6
- package/package.json +12 -6
- package/scripts/emit-agent-shell-tools.mjs +118 -0
- package/scripts/emit-gemini.mjs +219 -0
- package/scripts/emit-mcp-policy.mjs +23 -0
- package/scripts/gate-fat-tools.mjs +64 -0
- package/scripts/hooks-union.mjs +391 -0
- package/scripts/persist-handoff.mjs +231 -0
- package/scripts/scrub-spawn-prompt.mjs +37 -17
|
@@ -4,9 +4,10 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
import { scrubText } from "./scrub-text-lib.mjs";
|
|
7
|
+
import { denyResponse } from "./gate-fat-tools.mjs";
|
|
7
8
|
|
|
8
9
|
const ALLOWED_TYPES = new Set(["grunt", "implementer", "thinker"]);
|
|
9
|
-
export const MAX_PROMPT_CHARS =
|
|
10
|
+
export const MAX_PROMPT_CHARS = 100000;
|
|
10
11
|
export const TRUNCATE_SUFFIX = "…[truncated]";
|
|
11
12
|
/** `router` is a legacy transcript prefix; keep matching it to strip old pastes. */
|
|
12
13
|
const TRANSCRIPT_PREFIX =
|
|
@@ -72,14 +73,25 @@ export function extractVerdictBlocks(text) {
|
|
|
72
73
|
return { body: body.join("\n"), blocks };
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
export function truncatePrompt(text,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
export function truncatePrompt(text, _max = MAX_PROMPT_CHARS) {
|
|
77
|
+
return String(text);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function workspaceRootOf(data) {
|
|
81
|
+
return (
|
|
82
|
+
process.env.GROK_WORKSPACE_ROOT ||
|
|
83
|
+
(data && (data.workspaceRoot || data.workspace_root || data.cwd)) ||
|
|
84
|
+
process.env.CLAUDE_PROJECT_DIR ||
|
|
85
|
+
process.cwd() ||
|
|
86
|
+
""
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function spawnCapReason(workspaceRoot) {
|
|
91
|
+
const root = workspaceRoot || process.cwd() || "";
|
|
92
|
+
return (
|
|
93
|
+
`spawn prompt exceeds ${MAX_PROMPT_CHARS} chars after scrub; write it under ${root}/.tmp/plans/ and re-spawn with that abs path`
|
|
94
|
+
);
|
|
83
95
|
}
|
|
84
96
|
|
|
85
97
|
const INLINE_TRANSCRIPT =
|
|
@@ -108,13 +120,7 @@ export function capSpawnPrompt(prompt) {
|
|
|
108
120
|
const again = extractVerdictBlocks(s);
|
|
109
121
|
const blocks = extracted.blocks.concat(again.blocks);
|
|
110
122
|
const verdictPart = blocks.length ? "\n" + blocks.join("\n") : "";
|
|
111
|
-
|
|
112
|
-
let core = again.body;
|
|
113
|
-
if (core.length > maxCore) {
|
|
114
|
-
const cut = Math.max(0, maxCore - TRUNCATE_SUFFIX.length);
|
|
115
|
-
core = core.slice(0, cut) + TRUNCATE_SUFFIX;
|
|
116
|
-
}
|
|
117
|
-
return (core + verdictPart).trim();
|
|
123
|
+
return (again.body + verdictPart).trim();
|
|
118
124
|
}
|
|
119
125
|
|
|
120
126
|
export function rewriteSpawnToolInput(toolInput, { defaultGrunt = false } = {}) {
|
|
@@ -160,9 +166,19 @@ export function processHookPayload(data) {
|
|
|
160
166
|
if (!data || typeof data !== "object" || Array.isArray(data)) return null;
|
|
161
167
|
let toolInput = data.toolInput;
|
|
162
168
|
if (toolInput == null) toolInput = data.tool_input;
|
|
163
|
-
|
|
169
|
+
const updated = rewriteSpawnToolInput(toolInput, {
|
|
164
170
|
defaultGrunt: grokDefaultGrunt(),
|
|
165
171
|
});
|
|
172
|
+
const prompt =
|
|
173
|
+
updated && typeof updated.prompt === "string"
|
|
174
|
+
? updated.prompt
|
|
175
|
+
: toolInput && typeof toolInput.prompt === "string"
|
|
176
|
+
? toolInput.prompt
|
|
177
|
+
: "";
|
|
178
|
+
if (prompt.length > MAX_PROMPT_CHARS) {
|
|
179
|
+
return denyResponse(spawnCapReason(workspaceRootOf(data)));
|
|
180
|
+
}
|
|
181
|
+
return updated;
|
|
166
182
|
}
|
|
167
183
|
|
|
168
184
|
export function hookResponse(updated) {
|
|
@@ -179,6 +195,10 @@ function main() {
|
|
|
179
195
|
const data = readJsonValue();
|
|
180
196
|
const updated = processHookPayload(data);
|
|
181
197
|
if (!updated) return 0;
|
|
198
|
+
if (updated.decision === "deny") {
|
|
199
|
+
process.stdout.write(JSON.stringify(updated));
|
|
200
|
+
return 0;
|
|
201
|
+
}
|
|
182
202
|
process.stdout.write(JSON.stringify(hookResponse(updated)));
|
|
183
203
|
return 0;
|
|
184
204
|
} catch {
|