@hung319/opencode-hive 1.3.9 → 1.4.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/dist/index.js +1148 -117
- package/dist/tools/memory.d.ts +35 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -232,7 +232,7 @@ var init_context_compression = __esm(() => {
|
|
|
232
232
|
|
|
233
233
|
// src/index.ts
|
|
234
234
|
import * as path8 from "path";
|
|
235
|
-
import * as
|
|
235
|
+
import * as os2 from "os";
|
|
236
236
|
|
|
237
237
|
// ../../node_modules/.bun/zod@4.1.8/node_modules/zod/v4/classic/external.js
|
|
238
238
|
var exports_external = {};
|
|
@@ -15845,6 +15845,428 @@ mcp:
|
|
|
15845
15845
|
}
|
|
15846
15846
|
});
|
|
15847
15847
|
|
|
15848
|
+
// src/tools/memory.ts
|
|
15849
|
+
import * as fs2 from "fs";
|
|
15850
|
+
import * as path2 from "path";
|
|
15851
|
+
import * as os from "os";
|
|
15852
|
+
function getGlobalMemoryDir() {
|
|
15853
|
+
return path2.join(os.homedir(), ".config", "opencode", "hive", "memory", "global");
|
|
15854
|
+
}
|
|
15855
|
+
function getProjectMemoryDir(projectRoot) {
|
|
15856
|
+
return path2.join(projectRoot, ".hive", "memory", "project");
|
|
15857
|
+
}
|
|
15858
|
+
function getJournalDir() {
|
|
15859
|
+
return path2.join(os.homedir(), ".config", "opencode", "hive", "journal");
|
|
15860
|
+
}
|
|
15861
|
+
function parseFrontmatter2(content) {
|
|
15862
|
+
if (!content.startsWith(`---
|
|
15863
|
+
`)) {
|
|
15864
|
+
return { frontmatter: {}, body: content };
|
|
15865
|
+
}
|
|
15866
|
+
const endIndex = content.indexOf(`
|
|
15867
|
+
---
|
|
15868
|
+
`, 4);
|
|
15869
|
+
if (endIndex === -1) {
|
|
15870
|
+
return { frontmatter: {}, body: content };
|
|
15871
|
+
}
|
|
15872
|
+
const fmText = content.slice(4, endIndex);
|
|
15873
|
+
const body = content.slice(endIndex + 5);
|
|
15874
|
+
const frontmatter = {};
|
|
15875
|
+
for (const line of fmText.split(`
|
|
15876
|
+
`)) {
|
|
15877
|
+
const colonIdx = line.indexOf(":");
|
|
15878
|
+
if (colonIdx > 0) {
|
|
15879
|
+
const key = line.slice(0, colonIdx).trim();
|
|
15880
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
15881
|
+
if (value === "true")
|
|
15882
|
+
frontmatter[key] = true;
|
|
15883
|
+
else if (value === "false")
|
|
15884
|
+
frontmatter[key] = false;
|
|
15885
|
+
else if (!isNaN(Number(value)))
|
|
15886
|
+
frontmatter[key] = Number(value);
|
|
15887
|
+
else
|
|
15888
|
+
frontmatter[key] = value;
|
|
15889
|
+
}
|
|
15890
|
+
}
|
|
15891
|
+
return { frontmatter, body };
|
|
15892
|
+
}
|
|
15893
|
+
function buildFrontmatter(frontmatter) {
|
|
15894
|
+
const lines = [];
|
|
15895
|
+
for (const [key, value] of Object.entries(frontmatter)) {
|
|
15896
|
+
if (typeof value === "boolean" || typeof value === "number") {
|
|
15897
|
+
lines.push(`${key}: ${value}`);
|
|
15898
|
+
} else if (Array.isArray(value)) {
|
|
15899
|
+
lines.push(`${key}:`);
|
|
15900
|
+
for (const item of value) {
|
|
15901
|
+
lines.push(` - ${item}`);
|
|
15902
|
+
}
|
|
15903
|
+
} else {
|
|
15904
|
+
lines.push(`${key}: ${value}`);
|
|
15905
|
+
}
|
|
15906
|
+
}
|
|
15907
|
+
return lines.length > 0 ? `---
|
|
15908
|
+
${lines.join(`
|
|
15909
|
+
`)}
|
|
15910
|
+
---
|
|
15911
|
+
` : "";
|
|
15912
|
+
}
|
|
15913
|
+
function readMemoryBlock(filePath, scope) {
|
|
15914
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
15915
|
+
const { frontmatter, body } = parseFrontmatter2(content);
|
|
15916
|
+
const label = frontmatter.label || path2.basename(filePath, path2.extname(filePath));
|
|
15917
|
+
const description = frontmatter.description || "Memory block";
|
|
15918
|
+
const limit = frontmatter.limit || 5000;
|
|
15919
|
+
const readOnly = frontmatter.read_only === true;
|
|
15920
|
+
const stats = fs2.statSync(filePath);
|
|
15921
|
+
return {
|
|
15922
|
+
scope,
|
|
15923
|
+
label,
|
|
15924
|
+
description,
|
|
15925
|
+
limit,
|
|
15926
|
+
readOnly,
|
|
15927
|
+
value: body.trim(),
|
|
15928
|
+
filePath,
|
|
15929
|
+
lastModified: stats.mtime.toISOString(),
|
|
15930
|
+
charsCurrent: body.trim().length
|
|
15931
|
+
};
|
|
15932
|
+
}
|
|
15933
|
+
function listMemoryBlocks(scope, projectRoot) {
|
|
15934
|
+
const dir = scope === "global" ? getGlobalMemoryDir() : getProjectMemoryDir(projectRoot);
|
|
15935
|
+
if (!fs2.existsSync(dir)) {
|
|
15936
|
+
return [];
|
|
15937
|
+
}
|
|
15938
|
+
const blocks = [];
|
|
15939
|
+
for (const file2 of fs2.readdirSync(dir)) {
|
|
15940
|
+
if (file2.endsWith(".md")) {
|
|
15941
|
+
const filePath = path2.join(dir, file2);
|
|
15942
|
+
try {
|
|
15943
|
+
blocks.push(readMemoryBlock(filePath, scope));
|
|
15944
|
+
} catch {}
|
|
15945
|
+
}
|
|
15946
|
+
}
|
|
15947
|
+
return blocks.sort((a, b) => {
|
|
15948
|
+
const priority = { persona: 0, human: 1, project: 2 };
|
|
15949
|
+
const pa = priority[a.label] ?? 10;
|
|
15950
|
+
const pb = priority[b.label] ?? 10;
|
|
15951
|
+
if (pa !== pb)
|
|
15952
|
+
return pa - pb;
|
|
15953
|
+
return a.label.localeCompare(b.label);
|
|
15954
|
+
});
|
|
15955
|
+
}
|
|
15956
|
+
var SEED_BLOCKS = [
|
|
15957
|
+
{ scope: "global", label: "persona", description: "How the agent should behave and respond. Personality, communication style, constraints." },
|
|
15958
|
+
{ scope: "global", label: "human", description: "Key details about the user: preferences, habits, constraints, working style." },
|
|
15959
|
+
{ scope: "project", label: "project", description: "Project-specific knowledge: commands, architecture, conventions, gotchas." }
|
|
15960
|
+
];
|
|
15961
|
+
async function ensureMemorySeeded(projectRoot) {
|
|
15962
|
+
for (const seed of SEED_BLOCKS) {
|
|
15963
|
+
const dir = seed.scope === "global" ? getGlobalMemoryDir() : getProjectMemoryDir(projectRoot);
|
|
15964
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
15965
|
+
const filePath = path2.join(dir, `${seed.label}.md`);
|
|
15966
|
+
if (!fs2.existsSync(filePath)) {
|
|
15967
|
+
const content = buildFrontmatter({
|
|
15968
|
+
label: seed.label,
|
|
15969
|
+
description: seed.description,
|
|
15970
|
+
limit: 5000,
|
|
15971
|
+
read_only: false
|
|
15972
|
+
});
|
|
15973
|
+
fs2.writeFileSync(filePath, content + `
|
|
15974
|
+
`, "utf-8");
|
|
15975
|
+
}
|
|
15976
|
+
}
|
|
15977
|
+
}
|
|
15978
|
+
function writeJournalEntry(title, body, project, tags = []) {
|
|
15979
|
+
const journalDir = getJournalDir();
|
|
15980
|
+
fs2.mkdirSync(journalDir, { recursive: true });
|
|
15981
|
+
const now = new Date;
|
|
15982
|
+
const id2 = `${now.getUTCFullYear()}${String(now.getUTCMonth() + 1).padStart(2, "0")}${String(now.getUTCDate()).padStart(2, "0")}-${String(now.getUTCHours()).padStart(2, "0")}${String(now.getUTCMinutes()).padStart(2, "0")}${String(now.getUTCSeconds()).padStart(2, "0")}-${String(now.getUTCMilliseconds()).padStart(3, "0")}`;
|
|
15983
|
+
const filePath = path2.join(journalDir, `${id2}.md`);
|
|
15984
|
+
const frontmatter = buildFrontmatter({
|
|
15985
|
+
title,
|
|
15986
|
+
project: project || "",
|
|
15987
|
+
tags,
|
|
15988
|
+
created: now.toISOString()
|
|
15989
|
+
});
|
|
15990
|
+
fs2.writeFileSync(filePath, frontmatter + body + `
|
|
15991
|
+
`, "utf-8");
|
|
15992
|
+
return {
|
|
15993
|
+
id: id2,
|
|
15994
|
+
title,
|
|
15995
|
+
body,
|
|
15996
|
+
project,
|
|
15997
|
+
tags,
|
|
15998
|
+
created: now.toISOString(),
|
|
15999
|
+
filePath
|
|
16000
|
+
};
|
|
16001
|
+
}
|
|
16002
|
+
function searchJournalEntries(query, project, limit = 20) {
|
|
16003
|
+
const journalDir = getJournalDir();
|
|
16004
|
+
if (!fs2.existsSync(journalDir)) {
|
|
16005
|
+
return { entries: [], total: 0 };
|
|
16006
|
+
}
|
|
16007
|
+
const entries = [];
|
|
16008
|
+
const files = fs2.readdirSync(journalDir).filter((f) => f.endsWith(".md")).sort().reverse();
|
|
16009
|
+
for (const file2 of files) {
|
|
16010
|
+
const filePath = path2.join(journalDir, file2);
|
|
16011
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
16012
|
+
const { frontmatter, body } = parseFrontmatter2(content);
|
|
16013
|
+
const entry = {
|
|
16014
|
+
id: file2.replace(".md", ""),
|
|
16015
|
+
title: frontmatter.title || "Untitled",
|
|
16016
|
+
body: body.trim(),
|
|
16017
|
+
project: frontmatter.project,
|
|
16018
|
+
tags: frontmatter.tags || [],
|
|
16019
|
+
created: frontmatter.created || "",
|
|
16020
|
+
filePath
|
|
16021
|
+
};
|
|
16022
|
+
if (project && entry.project !== project)
|
|
16023
|
+
continue;
|
|
16024
|
+
if (query) {
|
|
16025
|
+
const searchText = `${entry.title} ${entry.body}`.toLowerCase();
|
|
16026
|
+
if (!searchText.includes(query.toLowerCase()))
|
|
16027
|
+
continue;
|
|
16028
|
+
}
|
|
16029
|
+
entries.push(entry);
|
|
16030
|
+
if (entries.length >= limit)
|
|
16031
|
+
break;
|
|
16032
|
+
}
|
|
16033
|
+
return { entries, total: files.length };
|
|
16034
|
+
}
|
|
16035
|
+
var hiveMemoryListTool = tool({
|
|
16036
|
+
description: "List all memory blocks. Shows global (cross-project) and project-scoped blocks with descriptions and sizes.",
|
|
16037
|
+
args: {
|
|
16038
|
+
scope: tool.schema.enum(["global", "project", "all"]).optional().describe("Scope to list: global, project, or all (default: all)")
|
|
16039
|
+
},
|
|
16040
|
+
async execute({ scope = "all" }) {
|
|
16041
|
+
const projectRoot = process.cwd();
|
|
16042
|
+
const blocks = [];
|
|
16043
|
+
if (scope === "global" || scope === "all") {
|
|
16044
|
+
blocks.push(...listMemoryBlocks("global", projectRoot));
|
|
16045
|
+
}
|
|
16046
|
+
if (scope === "project" || scope === "all") {
|
|
16047
|
+
blocks.push(...listMemoryBlocks("project", projectRoot));
|
|
16048
|
+
}
|
|
16049
|
+
if (blocks.length === 0) {
|
|
16050
|
+
return JSON.stringify({
|
|
16051
|
+
message: "No memory blocks found. Use hive_memory_set to create one.",
|
|
16052
|
+
global: [],
|
|
16053
|
+
project: []
|
|
16054
|
+
}, null, 2);
|
|
16055
|
+
}
|
|
16056
|
+
const grouped = {
|
|
16057
|
+
global: blocks.filter((b) => b.scope === "global"),
|
|
16058
|
+
project: blocks.filter((b) => b.scope === "project")
|
|
16059
|
+
};
|
|
16060
|
+
return JSON.stringify({
|
|
16061
|
+
total: blocks.length,
|
|
16062
|
+
global: grouped.global.map((b) => ({
|
|
16063
|
+
label: b.label,
|
|
16064
|
+
description: b.description,
|
|
16065
|
+
charsCurrent: b.charsCurrent,
|
|
16066
|
+
charsLimit: b.limit,
|
|
16067
|
+
readOnly: b.readOnly,
|
|
16068
|
+
lastModified: b.lastModified
|
|
16069
|
+
})),
|
|
16070
|
+
project: grouped.project.map((b) => ({
|
|
16071
|
+
label: b.label,
|
|
16072
|
+
description: b.description,
|
|
16073
|
+
charsCurrent: b.charsCurrent,
|
|
16074
|
+
charsLimit: b.limit,
|
|
16075
|
+
readOnly: b.readOnly,
|
|
16076
|
+
lastModified: b.lastModified
|
|
16077
|
+
}))
|
|
16078
|
+
}, null, 2);
|
|
16079
|
+
}
|
|
16080
|
+
});
|
|
16081
|
+
var hiveMemorySetTool = tool({
|
|
16082
|
+
description: "Create or overwrite a memory block. Use for full updates.",
|
|
16083
|
+
args: {
|
|
16084
|
+
scope: tool.schema.enum(["global", "project"]).describe("Scope: global (cross-project) or project (project-scoped)"),
|
|
16085
|
+
label: tool.schema.string().describe("Label for the memory block (e.g., persona, human, project, conventions)"),
|
|
16086
|
+
value: tool.schema.string().describe("Content to store in the memory block"),
|
|
16087
|
+
description: tool.schema.string().optional().describe("Description of how this block should be used"),
|
|
16088
|
+
limit: tool.schema.number().optional().describe("Maximum characters allowed (default: 5000)"),
|
|
16089
|
+
readOnly: tool.schema.boolean().optional().describe("Make block read-only (default: false)")
|
|
16090
|
+
},
|
|
16091
|
+
async execute({ scope, label, value, description, limit = 5000, readOnly = false }) {
|
|
16092
|
+
const projectRoot = process.cwd();
|
|
16093
|
+
if (!/^[a-z0-9][a-z0-9-_]{1,60}$/i.test(label)) {
|
|
16094
|
+
return JSON.stringify({
|
|
16095
|
+
success: false,
|
|
16096
|
+
error: `Invalid label "${label}". Use letters/numbers/dash/underscore (2-61 chars).`
|
|
16097
|
+
}, null, 2);
|
|
16098
|
+
}
|
|
16099
|
+
if (value.length > limit) {
|
|
16100
|
+
return JSON.stringify({
|
|
16101
|
+
success: false,
|
|
16102
|
+
error: `Value too large (${value.length} chars, limit: ${limit})`,
|
|
16103
|
+
hint: "Use hive_memory_replace for surgical edits, or increase the limit."
|
|
16104
|
+
}, null, 2);
|
|
16105
|
+
}
|
|
16106
|
+
const dir = scope === "global" ? getGlobalMemoryDir() : getProjectMemoryDir(projectRoot);
|
|
16107
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
16108
|
+
const filePath = path2.join(dir, `${label}.md`);
|
|
16109
|
+
if (fs2.existsSync(filePath)) {
|
|
16110
|
+
const existing = readMemoryBlock(filePath, scope);
|
|
16111
|
+
if (existing.readOnly) {
|
|
16112
|
+
return JSON.stringify({
|
|
16113
|
+
success: false,
|
|
16114
|
+
error: `Memory block "${scope}:${label}" is read-only`
|
|
16115
|
+
}, null, 2);
|
|
16116
|
+
}
|
|
16117
|
+
}
|
|
16118
|
+
const content = buildFrontmatter({
|
|
16119
|
+
label,
|
|
16120
|
+
description: description || `Memory block: ${label}`,
|
|
16121
|
+
limit,
|
|
16122
|
+
read_only: readOnly
|
|
16123
|
+
});
|
|
16124
|
+
fs2.writeFileSync(filePath, content + value + `
|
|
16125
|
+
`, "utf-8");
|
|
16126
|
+
return JSON.stringify({
|
|
16127
|
+
success: true,
|
|
16128
|
+
scope,
|
|
16129
|
+
label,
|
|
16130
|
+
charsWritten: value.length,
|
|
16131
|
+
charsLimit: limit
|
|
16132
|
+
}, null, 2);
|
|
16133
|
+
}
|
|
16134
|
+
});
|
|
16135
|
+
var hiveMemoryReplaceTool = tool({
|
|
16136
|
+
description: "Replace a substring within a memory block. Use for surgical edits.",
|
|
16137
|
+
args: {
|
|
16138
|
+
scope: tool.schema.enum(["global", "project"]).describe("Scope of the memory block"),
|
|
16139
|
+
label: tool.schema.string().describe("Label of the memory block"),
|
|
16140
|
+
oldText: tool.schema.string().describe("Text to find and replace"),
|
|
16141
|
+
newText: tool.schema.string().describe("Replacement text")
|
|
16142
|
+
},
|
|
16143
|
+
async execute({ scope, label, oldText, newText }) {
|
|
16144
|
+
const projectRoot = process.cwd();
|
|
16145
|
+
const dir = scope === "global" ? getGlobalMemoryDir() : getProjectMemoryDir(projectRoot);
|
|
16146
|
+
const filePath = path2.join(dir, `${label}.md`);
|
|
16147
|
+
if (!fs2.existsSync(filePath)) {
|
|
16148
|
+
return JSON.stringify({
|
|
16149
|
+
success: false,
|
|
16150
|
+
error: `Memory block not found: ${scope}:${label}`
|
|
16151
|
+
}, null, 2);
|
|
16152
|
+
}
|
|
16153
|
+
const block = readMemoryBlock(filePath, scope);
|
|
16154
|
+
if (block.readOnly) {
|
|
16155
|
+
return JSON.stringify({
|
|
16156
|
+
success: false,
|
|
16157
|
+
error: `Memory block "${scope}:${label}" is read-only`
|
|
16158
|
+
}, null, 2);
|
|
16159
|
+
}
|
|
16160
|
+
if (!block.value.includes(oldText)) {
|
|
16161
|
+
return JSON.stringify({
|
|
16162
|
+
success: false,
|
|
16163
|
+
error: `Text not found in "${scope}:${label}"`,
|
|
16164
|
+
hint: "The oldText must match exactly. Try copying from hive_memory_list output."
|
|
16165
|
+
}, null, 2);
|
|
16166
|
+
}
|
|
16167
|
+
const newValue = block.value.replace(oldText, newText);
|
|
16168
|
+
if (newValue.length > block.limit) {
|
|
16169
|
+
return JSON.stringify({
|
|
16170
|
+
success: false,
|
|
16171
|
+
error: `Replacement would exceed limit (${newValue.length} > ${block.limit})`
|
|
16172
|
+
}, null, 2);
|
|
16173
|
+
}
|
|
16174
|
+
const content = buildFrontmatter({
|
|
16175
|
+
label: block.label,
|
|
16176
|
+
description: block.description,
|
|
16177
|
+
limit: block.limit,
|
|
16178
|
+
read_only: block.readOnly
|
|
16179
|
+
});
|
|
16180
|
+
fs2.writeFileSync(filePath, content + newValue + `
|
|
16181
|
+
`, "utf-8");
|
|
16182
|
+
return JSON.stringify({
|
|
16183
|
+
success: true,
|
|
16184
|
+
scope,
|
|
16185
|
+
label,
|
|
16186
|
+
charsReplaced: newValue.length
|
|
16187
|
+
}, null, 2);
|
|
16188
|
+
}
|
|
16189
|
+
});
|
|
16190
|
+
var hiveJournalWriteTool = tool({
|
|
16191
|
+
description: "Write a journal entry. Journal is append-only for capturing insights, decisions, and discoveries.",
|
|
16192
|
+
args: {
|
|
16193
|
+
title: tool.schema.string().describe("Title of the journal entry"),
|
|
16194
|
+
body: tool.schema.string().describe("Content of the journal entry"),
|
|
16195
|
+
tags: tool.schema.array(tool.schema.string()).optional().describe("Tags to categorize the entry")
|
|
16196
|
+
},
|
|
16197
|
+
async execute({ title, body, tags = [] }) {
|
|
16198
|
+
const projectRoot = process.cwd();
|
|
16199
|
+
const entry = writeJournalEntry(title, body, projectRoot, tags);
|
|
16200
|
+
return JSON.stringify({
|
|
16201
|
+
success: true,
|
|
16202
|
+
id: entry.id,
|
|
16203
|
+
title: entry.title,
|
|
16204
|
+
created: entry.created,
|
|
16205
|
+
message: "Journal entry written successfully"
|
|
16206
|
+
}, null, 2);
|
|
16207
|
+
}
|
|
16208
|
+
});
|
|
16209
|
+
var hiveJournalSearchTool = tool({
|
|
16210
|
+
description: "Search journal entries. Filter by text query, project, or tags.",
|
|
16211
|
+
args: {
|
|
16212
|
+
query: tool.schema.string().optional().describe("Text to search for in title and body"),
|
|
16213
|
+
project: tool.schema.string().optional().describe("Filter by project path"),
|
|
16214
|
+
tags: tool.schema.array(tool.schema.string()).optional().describe("Filter by tags"),
|
|
16215
|
+
limit: tool.schema.number().optional().describe("Maximum entries to return (default: 20)")
|
|
16216
|
+
},
|
|
16217
|
+
async execute({ query, project, tags, limit = 20 }) {
|
|
16218
|
+
const result = searchJournalEntries(query, project, limit);
|
|
16219
|
+
return JSON.stringify({
|
|
16220
|
+
total: result.total,
|
|
16221
|
+
returned: result.entries.length,
|
|
16222
|
+
entries: result.entries.map((e) => ({
|
|
16223
|
+
id: e.id,
|
|
16224
|
+
title: e.title,
|
|
16225
|
+
project: e.project,
|
|
16226
|
+
tags: e.tags,
|
|
16227
|
+
created: e.created,
|
|
16228
|
+
preview: e.body.slice(0, 200) + (e.body.length > 200 ? "..." : "")
|
|
16229
|
+
}))
|
|
16230
|
+
}, null, 2);
|
|
16231
|
+
}
|
|
16232
|
+
});
|
|
16233
|
+
async function buildMemoryInjection(projectRoot) {
|
|
16234
|
+
await ensureMemorySeeded(projectRoot);
|
|
16235
|
+
const globalBlocks = listMemoryBlocks("global", projectRoot);
|
|
16236
|
+
const projectBlocks = listMemoryBlocks("project", projectRoot);
|
|
16237
|
+
if (globalBlocks.length === 0 && projectBlocks.length === 0) {
|
|
16238
|
+
return "";
|
|
16239
|
+
}
|
|
16240
|
+
const sections = [];
|
|
16241
|
+
sections.push("<memory_instructions>");
|
|
16242
|
+
sections.push("You have access to persistent memory blocks that survive across sessions.");
|
|
16243
|
+
sections.push(`Use memory tools to store important information, decisions, and preferences.
|
|
16244
|
+
`);
|
|
16245
|
+
if (globalBlocks.length > 0) {
|
|
16246
|
+
sections.push("## Global Memory (cross-project)");
|
|
16247
|
+
for (const block of globalBlocks) {
|
|
16248
|
+
sections.push(`
|
|
16249
|
+
### ${block.label} (${block.charsCurrent}/${block.limit} chars)`);
|
|
16250
|
+
sections.push(`_${block.description}_`);
|
|
16251
|
+
sections.push(block.value || "(empty)");
|
|
16252
|
+
}
|
|
16253
|
+
}
|
|
16254
|
+
if (projectBlocks.length > 0) {
|
|
16255
|
+
sections.push(`
|
|
16256
|
+
## Project Memory`);
|
|
16257
|
+
for (const block of projectBlocks) {
|
|
16258
|
+
sections.push(`
|
|
16259
|
+
### ${block.label} (${block.charsCurrent}/${block.limit} chars)`);
|
|
16260
|
+
sections.push(`_${block.description}_`);
|
|
16261
|
+
sections.push(block.value || "(empty)");
|
|
16262
|
+
}
|
|
16263
|
+
}
|
|
16264
|
+
sections.push(`
|
|
16265
|
+
</memory_instructions>`);
|
|
16266
|
+
return sections.join(`
|
|
16267
|
+
`);
|
|
16268
|
+
}
|
|
16269
|
+
|
|
15848
16270
|
// src/agents/hive.ts
|
|
15849
16271
|
var QUEEN_BEE_PROMPT = `# Zetta (Hybrid)
|
|
15850
16272
|
|
|
@@ -16700,6 +17122,426 @@ Before verdict, mentally execute 2-3 tasks:
|
|
|
16700
17122
|
- Focus on worker success, not perfection
|
|
16701
17123
|
`;
|
|
16702
17124
|
|
|
17125
|
+
// src/agents/code-reviewer.ts
|
|
17126
|
+
var CODE_REVIEWER_PROMPT = `# Code Review Agent
|
|
17127
|
+
|
|
17128
|
+
You are in code review mode. Your role is strictly analytical, perform a code review on the provided diff.
|
|
17129
|
+
|
|
17130
|
+
## Guidelines
|
|
17131
|
+
|
|
17132
|
+
- **Pragmatic over pedantic**: Flag real problems, not style preferences
|
|
17133
|
+
- **Evidence-based**: Every issue must be traceable to specific diff lines
|
|
17134
|
+
- **Actionable**: Every issue must have a clear path to resolution
|
|
17135
|
+
- **Production-minded**: Assume this code ships to users
|
|
17136
|
+
|
|
17137
|
+
## Scope
|
|
17138
|
+
|
|
17139
|
+
### CRITICAL FOCUS AREAS:
|
|
17140
|
+
1. **Discipline:** Only review code that is part of the diff. Do not flag pre-existing issues in unchanged code.
|
|
17141
|
+
2. **Logic & Stability:** Edge cases (nulls, empty collections), race conditions, and incorrect state transitions.
|
|
17142
|
+
3. **Security:** Injection risks, improper validation, sensitive data exposure in logs/errors.
|
|
17143
|
+
4. **Performance:** Resource leaks, O(n^2) operations on large datasets, unnecessary network/DB calls.
|
|
17144
|
+
5. **Maintainability:** Clear violations of SOLID principles or excessive complexity.
|
|
17145
|
+
6. **Convention:** AGENTS.md violation (only if AGENTS.md content is available)
|
|
17146
|
+
|
|
17147
|
+
### SIMPLIFICATION FOCUS:
|
|
17148
|
+
Identify opportunities to simplify while preserving exact functionality:
|
|
17149
|
+
- Reduce unnecessary complexity and nesting
|
|
17150
|
+
- Remove redundant code/abstractions introduced by the change
|
|
17151
|
+
- Improve naming only when it prevents misunderstanding (not for preference)
|
|
17152
|
+
- Consolidate related logic when it increases readability
|
|
17153
|
+
- Avoid nested ternary operators; prefer if/else or switch
|
|
17154
|
+
- Remove comments that restate obvious code
|
|
17155
|
+
- Prefer explicit code over dense one-liners
|
|
17156
|
+
|
|
17157
|
+
### OPERATIONAL RULES:
|
|
17158
|
+
- **No scope creep:** Do not propose refactors outside the diff unless required to fix a blocking issue.
|
|
17159
|
+
- **Evidence-Based Only:** Never flag "potential" issues without explaining *why* they would occur based on the code provided.
|
|
17160
|
+
- **AGENTS.md Protocol:** If \`AGENTS.md\` exists in the repo, check it for project-specific rules. If not found, ignore all AGENTS.md instructions.
|
|
17161
|
+
- **Zero-Noise Policy:** Do not comment on stylistic preferences (naming, formatting) unless they explicitly violate a rule in \`AGENTS.md\`.
|
|
17162
|
+
- **Safety First:** Every suggestion must be provably behavior-preserving. When in doubt, omit it.
|
|
17163
|
+
- **Non-stylistic simplification:** Simplification candidates must be justified by reduced complexity/duplication/nesting in the diff, not stylistic preference.
|
|
17164
|
+
|
|
17165
|
+
## Output Format
|
|
17166
|
+
|
|
17167
|
+
## Code review
|
|
17168
|
+
|
|
17169
|
+
### Issues
|
|
17170
|
+
- A numbered list of blocking issues
|
|
17171
|
+
- Each issue MUST include:
|
|
17172
|
+
- reason: "bug" | "security" | "correctness" | "AGENTS.md adherence"
|
|
17173
|
+
- location: \`<path>::<symbol>\` or \`<path>::<global>\` + \`<lines>\` if available
|
|
17174
|
+
- evidence: quote the exact diff hunk lines
|
|
17175
|
+
- fix:
|
|
17176
|
+
- either a committable patch (max 5 lines per file)
|
|
17177
|
+
- or a concise, explicit instruction if a patch would exceed this limit
|
|
17178
|
+
|
|
17179
|
+
If no blocking issues are found, explicitly state:
|
|
17180
|
+
- "No blocking issues found."
|
|
17181
|
+
|
|
17182
|
+
### Simplification candidates (optional)
|
|
17183
|
+
Include this section only if there are meaningful refactors that are clearly behavior-preserving.
|
|
17184
|
+
- A numbered list of candidates.
|
|
17185
|
+
- Each candidate MUST include:
|
|
17186
|
+
- goal: what clarity/maintainability improves
|
|
17187
|
+
- constraints: "no behavior change", and any diff-specific invariants (e.g., "preserve error messages", "keep API shape")
|
|
17188
|
+
- evidence: quote the exact diff hunk lines
|
|
17189
|
+
- location: \`<path>::<symbol>\` or \`<path>::<global>\` + \`<lines>\` if available
|
|
17190
|
+
- suggested change:
|
|
17191
|
+
- either a committable patch (max 5 lines per file)
|
|
17192
|
+
- or a concise refactor plan (if patch would exceed this limit)
|
|
17193
|
+
`;
|
|
17194
|
+
|
|
17195
|
+
// src/agents/code-simplifier.ts
|
|
17196
|
+
var CODE_SIMPLIFIER_PROMPT = `# Code Simplifier Agent
|
|
17197
|
+
|
|
17198
|
+
You are a code simplification agent. Your role is to **refine recently written or modified code** to improve clarity, consistency, and maintainability **without changing behavior**.
|
|
17199
|
+
|
|
17200
|
+
This agent is intended to be triggered automatically **after a logical chunk of code has been written or modified** (feature implementation, bug fix, refactor, optimization).
|
|
17201
|
+
|
|
17202
|
+
You do not introduce new features, fix bugs, or change logic. You only improve how the code is expressed.
|
|
17203
|
+
|
|
17204
|
+
## Core principles
|
|
17205
|
+
|
|
17206
|
+
### 1. Behavior preservation (absolute rule)
|
|
17207
|
+
- Do **not** change observable behavior.
|
|
17208
|
+
- Do **not** change public APIs, function signatures, return values, error messages, or execution order.
|
|
17209
|
+
- Do **not** alter async behavior, side effects, or performance characteristics unless explicitly instructed.
|
|
17210
|
+
- If behavior preservation cannot be proven, **do not apply the change**.
|
|
17211
|
+
|
|
17212
|
+
### 2. Scope discipline
|
|
17213
|
+
- Only simplify code that was **modified or introduced in the current session**.
|
|
17214
|
+
- This includes **untracked files** (new files not yet committed) listed in the working tree.
|
|
17215
|
+
- Do not refactor adjacent or pre-existing code unless strictly required to simplify the modified section.
|
|
17216
|
+
- No cross-file refactors unless the change itself spans multiple files.
|
|
17217
|
+
|
|
17218
|
+
### 3. Clarity over cleverness
|
|
17219
|
+
Favor explicit, readable code over compact or "clever" solutions.
|
|
17220
|
+
- Prefer simple control flow over dense expressions.
|
|
17221
|
+
- Prefer explicit variable names over implicit meaning.
|
|
17222
|
+
- Prefer straightforward logic over abstractions introduced solely to reduce line count.
|
|
17223
|
+
|
|
17224
|
+
## Simplification focus
|
|
17225
|
+
|
|
17226
|
+
Apply simplifications only when they clearly improve readability or maintainability:
|
|
17227
|
+
|
|
17228
|
+
- Reduce unnecessary nesting and branching.
|
|
17229
|
+
- Remove redundant checks, conversions, or temporary variables introduced by the change.
|
|
17230
|
+
- Consolidate closely related logic when it improves readability **without merging concerns**.
|
|
17231
|
+
- Avoid nested ternary operators; use \`if/else\` or \`switch\` for multi-branch logic.
|
|
17232
|
+
- Remove comments that restate obvious code; keep comments that explain intent or non-obvious decisions.
|
|
17233
|
+
- Improve naming **only** when current names cause ambiguity or misunderstanding (not for preference).
|
|
17234
|
+
|
|
17235
|
+
## Project standards
|
|
17236
|
+
|
|
17237
|
+
- If a project standards file exists (e.g. \`CLAUDE.md\`, \`AGENTS.md\`), follow it.
|
|
17238
|
+
- If standards are not accessible, do **not** enforce stylistic conventions as rules.
|
|
17239
|
+
- Standards may guide simplification only when they clearly improve maintainability of the modified code.
|
|
17240
|
+
|
|
17241
|
+
## Non-goals (do NOT do these)
|
|
17242
|
+
- Do not optimize performance unless simplification naturally preserves it.
|
|
17243
|
+
- Do not introduce new abstractions unless they clearly reduce complexity.
|
|
17244
|
+
- Do not refactor for consistency across the whole codebase.
|
|
17245
|
+
- Do not reformat code purely for style or aesthetics.
|
|
17246
|
+
- Do not rewrite working code "because it could be nicer".
|
|
17247
|
+
|
|
17248
|
+
## Execution process
|
|
17249
|
+
|
|
17250
|
+
1. Identify code that was added or modified in the current session, **including untracked files listed in the diff**.
|
|
17251
|
+
2. **Read the content of untracked files** using the Read tool before analyzing them.
|
|
17252
|
+
3. Analyze the code for unnecessary complexity, redundancy, or unclear structure.
|
|
17253
|
+
4. Apply minimal, behavior-preserving refinements.
|
|
17254
|
+
5. Re-check that functionality, outputs, and side effects are unchanged.
|
|
17255
|
+
6. Produce the simplified code.
|
|
17256
|
+
|
|
17257
|
+
## Output requirements
|
|
17258
|
+
|
|
17259
|
+
- Apply changes directly to the code.
|
|
17260
|
+
- Keep changes minimal and localized.
|
|
17261
|
+
- If no meaningful simplification is possible, make no changes.
|
|
17262
|
+
- If a change could be controversial or borderline, prefer omission.
|
|
17263
|
+
|
|
17264
|
+
Your goal is not to "clean everything", but to ensure that **newly written code enters the codebase at a high standard of clarity and maintainability**, without risk.
|
|
17265
|
+
`;
|
|
17266
|
+
|
|
17267
|
+
// src/agents/codebase-locator.ts
|
|
17268
|
+
var CODEBASE_LOCATOR_PROMPT = `# Codebase Locator Agent
|
|
17269
|
+
|
|
17270
|
+
You are a SUBAGENT for finding file locations in the codebase.
|
|
17271
|
+
|
|
17272
|
+
## Purpose
|
|
17273
|
+
Find WHERE files live. No content analysis, no suggestions, no opinions, just locations.
|
|
17274
|
+
|
|
17275
|
+
## Rules
|
|
17276
|
+
|
|
17277
|
+
- Return file paths only
|
|
17278
|
+
- Organize results by logical category
|
|
17279
|
+
- Be exhaustive - find ALL relevant files
|
|
17280
|
+
- Include test files when relevant
|
|
17281
|
+
- Include config files when relevant
|
|
17282
|
+
|
|
17283
|
+
## Search Strategies
|
|
17284
|
+
|
|
17285
|
+
- **by-name**: Glob for file names
|
|
17286
|
+
- **by-content**: Grep for specific terms, imports, usage
|
|
17287
|
+
- **by-convention**: Check standard locations (src/, lib/, tests/, config/)
|
|
17288
|
+
- **by-extension**: Filter by file type
|
|
17289
|
+
- **by-import**: Find files that import/export a symbol
|
|
17290
|
+
|
|
17291
|
+
## Categories
|
|
17292
|
+
|
|
17293
|
+
- Source files
|
|
17294
|
+
- Test files
|
|
17295
|
+
- Type definitions
|
|
17296
|
+
- Configuration
|
|
17297
|
+
- Documentation
|
|
17298
|
+
- Scripts
|
|
17299
|
+
|
|
17300
|
+
## Output Format
|
|
17301
|
+
|
|
17302
|
+
## Source Files
|
|
17303
|
+
- path/to/file.ts
|
|
17304
|
+
- path/to/another.ts
|
|
17305
|
+
|
|
17306
|
+
## Tests
|
|
17307
|
+
- path/to/file.test.ts
|
|
17308
|
+
- path/to/another.spec.ts
|
|
17309
|
+
|
|
17310
|
+
## Config
|
|
17311
|
+
- path/to/config.json
|
|
17312
|
+
- path/to/tsconfig.json
|
|
17313
|
+
`;
|
|
17314
|
+
|
|
17315
|
+
// src/agents/codebase-analyzer.ts
|
|
17316
|
+
var CODEBASE_ANALYZER_PROMPT = `# Codebase Analyzer Agent
|
|
17317
|
+
|
|
17318
|
+
You are a SUBAGENT for analyzing and explaining code behavior.
|
|
17319
|
+
|
|
17320
|
+
## Purpose
|
|
17321
|
+
Explain HOW code works. Document what IS, not what SHOULD BE.
|
|
17322
|
+
|
|
17323
|
+
## Rules
|
|
17324
|
+
|
|
17325
|
+
- Always include file:line references
|
|
17326
|
+
- Read files COMPLETELY - never use limit/offset
|
|
17327
|
+
- Describe behavior, not quality
|
|
17328
|
+
- No suggestions, no improvements, no opinions
|
|
17329
|
+
- Trace actual execution paths, not assumptions
|
|
17330
|
+
- Include error handling paths
|
|
17331
|
+
- Document side effects explicitly
|
|
17332
|
+
- Note any external dependencies called
|
|
17333
|
+
|
|
17334
|
+
## Process
|
|
17335
|
+
|
|
17336
|
+
1. Identify entry points
|
|
17337
|
+
2. Read all relevant files completely
|
|
17338
|
+
3. Trace data flow step by step
|
|
17339
|
+
4. Trace control flow (conditionals, loops, early returns)
|
|
17340
|
+
5. Document function calls with their locations
|
|
17341
|
+
6. Note state mutations and side effects
|
|
17342
|
+
7. Map error propagation paths
|
|
17343
|
+
|
|
17344
|
+
## Output Format
|
|
17345
|
+
|
|
17346
|
+
## [Component/Feature]
|
|
17347
|
+
|
|
17348
|
+
**Purpose**: [One sentence]
|
|
17349
|
+
|
|
17350
|
+
**Entry point**: \`file:line\`
|
|
17351
|
+
|
|
17352
|
+
**Data flow**:
|
|
17353
|
+
1. \`file:line\` - [what happens]
|
|
17354
|
+
2. \`file:line\` - [next step]
|
|
17355
|
+
3. \`file:line\` - [continues...]
|
|
17356
|
+
|
|
17357
|
+
**Key functions**:
|
|
17358
|
+
- \`functionName\` at \`file:line\` - [what it does]
|
|
17359
|
+
- \`anotherFn\` at \`file:line\` - [what it does]
|
|
17360
|
+
|
|
17361
|
+
**State mutations**:
|
|
17362
|
+
- \`file:line\` - [what changes]
|
|
17363
|
+
|
|
17364
|
+
**Error paths**:
|
|
17365
|
+
- \`file:line\` - [error condition] → [handling]
|
|
17366
|
+
|
|
17367
|
+
**External calls**:
|
|
17368
|
+
- \`file:line\` - calls [external service/API]
|
|
17369
|
+
|
|
17370
|
+
## Tracing Rules
|
|
17371
|
+
|
|
17372
|
+
- Follow imports to their source
|
|
17373
|
+
- Expand function calls inline when relevant
|
|
17374
|
+
- Note async boundaries explicitly
|
|
17375
|
+
- Track data transformations step by step
|
|
17376
|
+
- Document callback and event flows
|
|
17377
|
+
- Include middleware/interceptor chains
|
|
17378
|
+
`;
|
|
17379
|
+
|
|
17380
|
+
// src/agents/pattern-finder.ts
|
|
17381
|
+
var PATTERN_FINDER_PROMPT = `# Pattern Finder Agent
|
|
17382
|
+
|
|
17383
|
+
You are a SUBAGENT for finding coding patterns and conventions.
|
|
17384
|
+
|
|
17385
|
+
## Purpose
|
|
17386
|
+
Find existing patterns in the codebase to model after. Show, don't tell.
|
|
17387
|
+
|
|
17388
|
+
## Rules
|
|
17389
|
+
|
|
17390
|
+
- Provide concrete code examples, not abstract descriptions
|
|
17391
|
+
- Always include file:line references
|
|
17392
|
+
- Show 2-3 best examples, not exhaustive lists
|
|
17393
|
+
- Include enough context to understand usage
|
|
17394
|
+
- Prioritize recent/maintained code over legacy
|
|
17395
|
+
- Include test examples when available
|
|
17396
|
+
- Note any variations of the pattern
|
|
17397
|
+
|
|
17398
|
+
## What to Find
|
|
17399
|
+
|
|
17400
|
+
- How similar features are implemented
|
|
17401
|
+
- Naming conventions used
|
|
17402
|
+
- Error handling patterns
|
|
17403
|
+
- Testing patterns
|
|
17404
|
+
- File organization patterns
|
|
17405
|
+
- Import/export patterns
|
|
17406
|
+
- Configuration patterns
|
|
17407
|
+
- API patterns (routes, handlers, responses)
|
|
17408
|
+
|
|
17409
|
+
## Search Process
|
|
17410
|
+
|
|
17411
|
+
1. Grep for similar implementations
|
|
17412
|
+
2. Check test files for usage examples
|
|
17413
|
+
3. Look for documentation or comments
|
|
17414
|
+
4. Find the most representative example
|
|
17415
|
+
5. Find variations if they exist
|
|
17416
|
+
|
|
17417
|
+
## Output Format
|
|
17418
|
+
|
|
17419
|
+
## Pattern: [Name]
|
|
17420
|
+
|
|
17421
|
+
**Best example**: \`file:line-line\`
|
|
17422
|
+
\`\`\`language
|
|
17423
|
+
[code snippet]
|
|
17424
|
+
\`\`\`
|
|
17425
|
+
|
|
17426
|
+
**Also see**:
|
|
17427
|
+
- \`file:line\` - [variation/alternative]
|
|
17428
|
+
|
|
17429
|
+
**Usage notes**: [when/how to apply]
|
|
17430
|
+
|
|
17431
|
+
## Quality Criteria
|
|
17432
|
+
|
|
17433
|
+
- Prefer patterns with tests
|
|
17434
|
+
- Prefer patterns that are widely used
|
|
17435
|
+
- Prefer recent over old
|
|
17436
|
+
- Prefer simple over complex
|
|
17437
|
+
- Note if pattern seems inconsistent across codebase
|
|
17438
|
+
`;
|
|
17439
|
+
|
|
17440
|
+
// src/agents/project-initializer.ts
|
|
17441
|
+
var PROJECT_INITIALIZER_PROMPT = `# Project Initializer Agent
|
|
17442
|
+
|
|
17443
|
+
You are a SUBAGENT - use task tool to spawn other subagents for parallel execution.
|
|
17444
|
+
|
|
17445
|
+
## Purpose
|
|
17446
|
+
Rapidly analyze any project and generate ARCHITECTURE.md and CODE_STYLE.md
|
|
17447
|
+
|
|
17448
|
+
## Critical Rule
|
|
17449
|
+
MAXIMIZE PARALLELISM. Speed is critical.
|
|
17450
|
+
- Call multiple task tools in ONE message for parallel execution
|
|
17451
|
+
- Never wait for one thing when you can do many
|
|
17452
|
+
|
|
17453
|
+
## Task
|
|
17454
|
+
Generate two documentation files that help AI agents understand this codebase:
|
|
17455
|
+
- ARCHITECTURE.md - Project structure, components, and data flow
|
|
17456
|
+
- CODE_STYLE.md - Coding conventions, patterns, and guidelines
|
|
17457
|
+
|
|
17458
|
+
## Parallel Execution Strategy
|
|
17459
|
+
|
|
17460
|
+
### Phase 1: Discovery
|
|
17461
|
+
Launch ALL discovery in ONE message:
|
|
17462
|
+
- Glob for entry points, configs, main modules
|
|
17463
|
+
- Glob for test files and test patterns
|
|
17464
|
+
- Glob for linter, formatter, CI configs
|
|
17465
|
+
- Use grep to find key patterns
|
|
17466
|
+
|
|
17467
|
+
### Phase 2: Deep Analysis
|
|
17468
|
+
Based on discovery:
|
|
17469
|
+
- Read 5 core source files simultaneously
|
|
17470
|
+
- Read 3 test files simultaneously
|
|
17471
|
+
- Read config files simultaneously
|
|
17472
|
+
|
|
17473
|
+
### Phase 3: Write Output Files
|
|
17474
|
+
- Write ARCHITECTURE.md
|
|
17475
|
+
- Write CODE_STYLE.md
|
|
17476
|
+
|
|
17477
|
+
## Available Subagents
|
|
17478
|
+
|
|
17479
|
+
Use task tool to spawn subagents:
|
|
17480
|
+
- **codebase-locator**: Fast file/pattern finder
|
|
17481
|
+
- **codebase-analyzer**: Deep module analyzer
|
|
17482
|
+
- **pattern-finder**: Pattern extractor
|
|
17483
|
+
|
|
17484
|
+
## Language Detection
|
|
17485
|
+
|
|
17486
|
+
Identify language(s) by examining file extensions and config files:
|
|
17487
|
+
- Python: pyproject.toml, setup.py, requirements.txt, *.py
|
|
17488
|
+
- JavaScript/TypeScript: package.json, tsconfig.json, *.js, *.ts, *.tsx
|
|
17489
|
+
- Go: go.mod, go.sum, *.go
|
|
17490
|
+
- Rust: Cargo.toml, *.rs
|
|
17491
|
+
- Java: pom.xml, build.gradle, *.java
|
|
17492
|
+
|
|
17493
|
+
## Architecture Analysis
|
|
17494
|
+
|
|
17495
|
+
Answer these questions:
|
|
17496
|
+
- What does this project do? (purpose)
|
|
17497
|
+
- What are the main entry points?
|
|
17498
|
+
- How is the code organized? (modules, packages, layers)
|
|
17499
|
+
- What are the core abstractions?
|
|
17500
|
+
- How does data flow through the system?
|
|
17501
|
+
- What external services does it integrate with?
|
|
17502
|
+
- How is configuration managed?
|
|
17503
|
+
- What's the deployment model?
|
|
17504
|
+
|
|
17505
|
+
## Code Style Analysis
|
|
17506
|
+
|
|
17507
|
+
Answer these questions:
|
|
17508
|
+
- How are files and directories named?
|
|
17509
|
+
- How are functions, classes, variables named?
|
|
17510
|
+
- What patterns are used consistently?
|
|
17511
|
+
- How are errors handled?
|
|
17512
|
+
- How is logging done?
|
|
17513
|
+
- What testing patterns are used?
|
|
17514
|
+
- Are there linter/formatter configs to reference?
|
|
17515
|
+
|
|
17516
|
+
## Output Requirements
|
|
17517
|
+
|
|
17518
|
+
- ARCHITECTURE.md should let someone understand the system in 5 minutes
|
|
17519
|
+
- CODE_STYLE.md should let someone write conforming code immediately
|
|
17520
|
+
- Keep total size under 500 lines per file
|
|
17521
|
+
- Use bullet points and tables over prose
|
|
17522
|
+
- Include file paths for everything you reference
|
|
17523
|
+
|
|
17524
|
+
## Execution Steps
|
|
17525
|
+
|
|
17526
|
+
1. **Discovery** (parallel):
|
|
17527
|
+
- Glob for package.json, pyproject.toml, go.mod, Cargo.toml
|
|
17528
|
+
- Glob for *.config.*, .eslintrc*, .prettierrc*
|
|
17529
|
+
- Glob for README*, CONTRIBUTING*
|
|
17530
|
+
- Read root directory listing
|
|
17531
|
+
- Use task to spawn codebase-locator for entry points
|
|
17532
|
+
- Use task to spawn codebase-locator for test files
|
|
17533
|
+
- Use task to spawn codebase-locator for config files
|
|
17534
|
+
|
|
17535
|
+
2. **Deep Analysis** (parallel):
|
|
17536
|
+
- Read multiple source files
|
|
17537
|
+
- Use task to spawn codebase-analyzer for core modules
|
|
17538
|
+
- Use task to spawn pattern-finder for conventions
|
|
17539
|
+
|
|
17540
|
+
3. **Write output files**:
|
|
17541
|
+
- Write ARCHITECTURE.md
|
|
17542
|
+
- Write CODE_STYLE.md
|
|
17543
|
+
`;
|
|
17544
|
+
|
|
16703
17545
|
// src/agents/custom-agents.ts
|
|
16704
17546
|
function buildCustomSubagents({
|
|
16705
17547
|
customAgents,
|
|
@@ -16772,15 +17614,15 @@ var createBuiltinMcps = (disabledMcps = []) => {
|
|
|
16772
17614
|
|
|
16773
17615
|
// ../hive-core/dist/index.js
|
|
16774
17616
|
import { createRequire as createRequire2 } from "node:module";
|
|
16775
|
-
import * as
|
|
16776
|
-
import * as
|
|
17617
|
+
import * as path3 from "path";
|
|
17618
|
+
import * as fs3 from "fs";
|
|
16777
17619
|
import * as path22 from "path";
|
|
16778
17620
|
import * as fs22 from "fs";
|
|
16779
|
-
import * as
|
|
17621
|
+
import * as fs32 from "fs";
|
|
16780
17622
|
import * as fs4 from "fs";
|
|
16781
17623
|
import * as fs5 from "fs";
|
|
16782
17624
|
import * as fs7 from "fs/promises";
|
|
16783
|
-
import * as
|
|
17625
|
+
import * as path32 from "path";
|
|
16784
17626
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
16785
17627
|
import { spawn } from "child_process";
|
|
16786
17628
|
import { normalize } from "node:path";
|
|
@@ -16792,7 +17634,7 @@ import * as path6 from "path";
|
|
|
16792
17634
|
import * as fs11 from "fs";
|
|
16793
17635
|
import * as path7 from "path";
|
|
16794
17636
|
import { existsSync as existsSync5 } from "fs";
|
|
16795
|
-
import { join as
|
|
17637
|
+
import { join as join82, sep } from "path";
|
|
16796
17638
|
import { execSync } from "child_process";
|
|
16797
17639
|
var __create = Object.create;
|
|
16798
17640
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -17451,10 +18293,10 @@ var require_src2 = __commonJS((exports) => {
|
|
|
17451
18293
|
var fs_1 = __require2("fs");
|
|
17452
18294
|
var debug_1 = __importDefault(require_src());
|
|
17453
18295
|
var log = debug_1.default("@kwsites/file-exists");
|
|
17454
|
-
function check2(
|
|
17455
|
-
log(`checking %s`,
|
|
18296
|
+
function check2(path33, isFile, isDirectory) {
|
|
18297
|
+
log(`checking %s`, path33);
|
|
17456
18298
|
try {
|
|
17457
|
-
const stat2 = fs_1.statSync(
|
|
18299
|
+
const stat2 = fs_1.statSync(path33);
|
|
17458
18300
|
if (stat2.isFile() && isFile) {
|
|
17459
18301
|
log(`[OK] path represents a file`);
|
|
17460
18302
|
return true;
|
|
@@ -17474,8 +18316,8 @@ var require_src2 = __commonJS((exports) => {
|
|
|
17474
18316
|
throw e;
|
|
17475
18317
|
}
|
|
17476
18318
|
}
|
|
17477
|
-
function exists(
|
|
17478
|
-
return check2(
|
|
18319
|
+
function exists(path33, type = exports.READABLE) {
|
|
18320
|
+
return check2(path33, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
17479
18321
|
}
|
|
17480
18322
|
exports.exists = exists;
|
|
17481
18323
|
exports.FILE = 1;
|
|
@@ -17616,6 +18458,19 @@ var DEFAULT_HIVE_CONFIG = {
|
|
|
17616
18458
|
skills: [],
|
|
17617
18459
|
autoLoadSkills: []
|
|
17618
18460
|
}
|
|
18461
|
+
},
|
|
18462
|
+
tokenTruncation: {
|
|
18463
|
+
enabled: true,
|
|
18464
|
+
maxChars: 30000,
|
|
18465
|
+
keepFirstPercent: 40,
|
|
18466
|
+
keepLastPercent: 40
|
|
18467
|
+
},
|
|
18468
|
+
sessionSnapshot: {
|
|
18469
|
+
enabled: true,
|
|
18470
|
+
maxSnapshotChars: 2048,
|
|
18471
|
+
includeActiveFeature: true,
|
|
18472
|
+
includePendingTasks: true,
|
|
18473
|
+
includeModifiedFiles: false
|
|
17619
18474
|
}
|
|
17620
18475
|
};
|
|
17621
18476
|
var HIVE_DIR = ".hive";
|
|
@@ -17632,78 +18487,78 @@ function normalizePath(filePath) {
|
|
|
17632
18487
|
return filePath.replace(/\\/g, "/");
|
|
17633
18488
|
}
|
|
17634
18489
|
function getHivePath(projectRoot) {
|
|
17635
|
-
return
|
|
18490
|
+
return path3.join(projectRoot, HIVE_DIR);
|
|
17636
18491
|
}
|
|
17637
18492
|
function getFeaturesPath(projectRoot) {
|
|
17638
|
-
return
|
|
18493
|
+
return path3.join(getHivePath(projectRoot), FEATURES_DIR);
|
|
17639
18494
|
}
|
|
17640
18495
|
function getFeaturePath(projectRoot, featureName) {
|
|
17641
|
-
return
|
|
18496
|
+
return path3.join(getFeaturesPath(projectRoot), featureName);
|
|
17642
18497
|
}
|
|
17643
18498
|
function getPlanPath(projectRoot, featureName) {
|
|
17644
|
-
return
|
|
18499
|
+
return path3.join(getFeaturePath(projectRoot, featureName), PLAN_FILE);
|
|
17645
18500
|
}
|
|
17646
18501
|
function getCommentsPath(projectRoot, featureName) {
|
|
17647
|
-
return
|
|
18502
|
+
return path3.join(getFeaturePath(projectRoot, featureName), COMMENTS_FILE);
|
|
17648
18503
|
}
|
|
17649
18504
|
function getFeatureJsonPath(projectRoot, featureName) {
|
|
17650
|
-
return
|
|
18505
|
+
return path3.join(getFeaturePath(projectRoot, featureName), FEATURE_FILE);
|
|
17651
18506
|
}
|
|
17652
18507
|
function getContextPath(projectRoot, featureName) {
|
|
17653
|
-
return
|
|
18508
|
+
return path3.join(getFeaturePath(projectRoot, featureName), CONTEXT_DIR);
|
|
17654
18509
|
}
|
|
17655
18510
|
function getTasksPath(projectRoot, featureName) {
|
|
17656
|
-
return
|
|
18511
|
+
return path3.join(getFeaturePath(projectRoot, featureName), TASKS_DIR);
|
|
17657
18512
|
}
|
|
17658
18513
|
function getTaskPath(projectRoot, featureName, taskFolder) {
|
|
17659
|
-
return
|
|
18514
|
+
return path3.join(getTasksPath(projectRoot, featureName), taskFolder);
|
|
17660
18515
|
}
|
|
17661
18516
|
function getTaskStatusPath(projectRoot, featureName, taskFolder) {
|
|
17662
|
-
return
|
|
18517
|
+
return path3.join(getTaskPath(projectRoot, featureName, taskFolder), STATUS_FILE);
|
|
17663
18518
|
}
|
|
17664
18519
|
function getTaskReportPath(projectRoot, featureName, taskFolder) {
|
|
17665
|
-
return
|
|
18520
|
+
return path3.join(getTaskPath(projectRoot, featureName, taskFolder), REPORT_FILE);
|
|
17666
18521
|
}
|
|
17667
18522
|
function getTaskSpecPath(projectRoot, featureName, taskFolder) {
|
|
17668
|
-
return
|
|
18523
|
+
return path3.join(getTaskPath(projectRoot, featureName, taskFolder), "spec.md");
|
|
17669
18524
|
}
|
|
17670
18525
|
function getApprovedPath(projectRoot, featureName) {
|
|
17671
|
-
return
|
|
18526
|
+
return path3.join(getFeaturePath(projectRoot, featureName), APPROVED_FILE);
|
|
17672
18527
|
}
|
|
17673
18528
|
var SUBTASKS_DIR = "subtasks";
|
|
17674
18529
|
var SPEC_FILE = "spec.md";
|
|
17675
18530
|
function getSubtasksPath(projectRoot, featureName, taskFolder) {
|
|
17676
|
-
return
|
|
18531
|
+
return path3.join(getTaskPath(projectRoot, featureName, taskFolder), SUBTASKS_DIR);
|
|
17677
18532
|
}
|
|
17678
18533
|
function getSubtaskPath(projectRoot, featureName, taskFolder, subtaskFolder) {
|
|
17679
|
-
return
|
|
18534
|
+
return path3.join(getSubtasksPath(projectRoot, featureName, taskFolder), subtaskFolder);
|
|
17680
18535
|
}
|
|
17681
18536
|
function getSubtaskStatusPath(projectRoot, featureName, taskFolder, subtaskFolder) {
|
|
17682
|
-
return
|
|
18537
|
+
return path3.join(getSubtaskPath(projectRoot, featureName, taskFolder, subtaskFolder), STATUS_FILE);
|
|
17683
18538
|
}
|
|
17684
18539
|
function getSubtaskSpecPath(projectRoot, featureName, taskFolder, subtaskFolder) {
|
|
17685
|
-
return
|
|
18540
|
+
return path3.join(getSubtaskPath(projectRoot, featureName, taskFolder, subtaskFolder), SPEC_FILE);
|
|
17686
18541
|
}
|
|
17687
18542
|
function getSubtaskReportPath(projectRoot, featureName, taskFolder, subtaskFolder) {
|
|
17688
|
-
return
|
|
18543
|
+
return path3.join(getSubtaskPath(projectRoot, featureName, taskFolder, subtaskFolder), REPORT_FILE);
|
|
17689
18544
|
}
|
|
17690
18545
|
function ensureDir(dirPath) {
|
|
17691
|
-
if (!
|
|
17692
|
-
|
|
18546
|
+
if (!fs3.existsSync(dirPath)) {
|
|
18547
|
+
fs3.mkdirSync(dirPath, { recursive: true });
|
|
17693
18548
|
}
|
|
17694
18549
|
}
|
|
17695
18550
|
function fileExists(filePath) {
|
|
17696
|
-
return
|
|
18551
|
+
return fs3.existsSync(filePath);
|
|
17697
18552
|
}
|
|
17698
18553
|
function readJson(filePath) {
|
|
17699
|
-
if (!
|
|
18554
|
+
if (!fs3.existsSync(filePath))
|
|
17700
18555
|
return null;
|
|
17701
|
-
const content =
|
|
18556
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
17702
18557
|
return JSON.parse(content);
|
|
17703
18558
|
}
|
|
17704
18559
|
function writeJson(filePath, data) {
|
|
17705
|
-
ensureDir(
|
|
17706
|
-
|
|
18560
|
+
ensureDir(path3.dirname(filePath));
|
|
18561
|
+
fs3.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
17707
18562
|
}
|
|
17708
18563
|
var DEFAULT_LOCK_OPTIONS = {
|
|
17709
18564
|
timeout: 5000,
|
|
@@ -17715,7 +18570,7 @@ function getLockPath(filePath) {
|
|
|
17715
18570
|
}
|
|
17716
18571
|
function isLockStale(lockPath, staleTTL) {
|
|
17717
18572
|
try {
|
|
17718
|
-
const stat2 =
|
|
18573
|
+
const stat2 = fs3.statSync(lockPath);
|
|
17719
18574
|
const age = Date.now() - stat2.mtimeMs;
|
|
17720
18575
|
return age > staleTTL;
|
|
17721
18576
|
} catch {
|
|
@@ -17725,7 +18580,7 @@ function isLockStale(lockPath, staleTTL) {
|
|
|
17725
18580
|
function acquireLockSync(filePath, options = {}) {
|
|
17726
18581
|
const opts = { ...DEFAULT_LOCK_OPTIONS, ...options };
|
|
17727
18582
|
const lockPath = getLockPath(filePath);
|
|
17728
|
-
const lockDir =
|
|
18583
|
+
const lockDir = path3.dirname(lockPath);
|
|
17729
18584
|
const startTime = Date.now();
|
|
17730
18585
|
const lockContent = JSON.stringify({
|
|
17731
18586
|
pid: process.pid,
|
|
@@ -17735,12 +18590,12 @@ function acquireLockSync(filePath, options = {}) {
|
|
|
17735
18590
|
ensureDir(lockDir);
|
|
17736
18591
|
while (true) {
|
|
17737
18592
|
try {
|
|
17738
|
-
const fd =
|
|
17739
|
-
|
|
17740
|
-
|
|
18593
|
+
const fd = fs3.openSync(lockPath, fs3.constants.O_CREAT | fs3.constants.O_EXCL | fs3.constants.O_WRONLY);
|
|
18594
|
+
fs3.writeSync(fd, lockContent);
|
|
18595
|
+
fs3.closeSync(fd);
|
|
17741
18596
|
return () => {
|
|
17742
18597
|
try {
|
|
17743
|
-
|
|
18598
|
+
fs3.unlinkSync(lockPath);
|
|
17744
18599
|
} catch {}
|
|
17745
18600
|
};
|
|
17746
18601
|
} catch (err) {
|
|
@@ -17750,7 +18605,7 @@ function acquireLockSync(filePath, options = {}) {
|
|
|
17750
18605
|
} else if (error45.code === "EEXIST") {
|
|
17751
18606
|
if (isLockStale(lockPath, opts.staleLockTTL)) {
|
|
17752
18607
|
try {
|
|
17753
|
-
|
|
18608
|
+
fs3.unlinkSync(lockPath);
|
|
17754
18609
|
continue;
|
|
17755
18610
|
} catch {}
|
|
17756
18611
|
}
|
|
@@ -17766,14 +18621,14 @@ function acquireLockSync(filePath, options = {}) {
|
|
|
17766
18621
|
}
|
|
17767
18622
|
}
|
|
17768
18623
|
function writeAtomic(filePath, content) {
|
|
17769
|
-
ensureDir(
|
|
18624
|
+
ensureDir(path3.dirname(filePath));
|
|
17770
18625
|
const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
17771
18626
|
try {
|
|
17772
|
-
|
|
17773
|
-
|
|
18627
|
+
fs3.writeFileSync(tempPath, content);
|
|
18628
|
+
fs3.renameSync(tempPath, filePath);
|
|
17774
18629
|
} catch (error45) {
|
|
17775
18630
|
try {
|
|
17776
|
-
|
|
18631
|
+
fs3.unlinkSync(tempPath);
|
|
17777
18632
|
} catch {}
|
|
17778
18633
|
throw error45;
|
|
17779
18634
|
}
|
|
@@ -17808,13 +18663,13 @@ function patchJsonLockedSync(filePath, patch, options = {}) {
|
|
|
17808
18663
|
}
|
|
17809
18664
|
}
|
|
17810
18665
|
function readText(filePath) {
|
|
17811
|
-
if (!
|
|
18666
|
+
if (!fs3.existsSync(filePath))
|
|
17812
18667
|
return null;
|
|
17813
|
-
return
|
|
18668
|
+
return fs3.readFileSync(filePath, "utf-8");
|
|
17814
18669
|
}
|
|
17815
18670
|
function writeText(filePath, content) {
|
|
17816
|
-
ensureDir(
|
|
17817
|
-
|
|
18671
|
+
ensureDir(path3.dirname(filePath));
|
|
18672
|
+
fs3.writeFileSync(filePath, content);
|
|
17818
18673
|
}
|
|
17819
18674
|
function detectContext(cwd) {
|
|
17820
18675
|
const result = {
|
|
@@ -17896,7 +18751,7 @@ class FeatureService {
|
|
|
17896
18751
|
const featuresPath = getFeaturesPath(this.projectRoot);
|
|
17897
18752
|
if (!fileExists(featuresPath))
|
|
17898
18753
|
return [];
|
|
17899
|
-
return
|
|
18754
|
+
return fs32.readdirSync(featuresPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
17900
18755
|
}
|
|
17901
18756
|
getActive() {
|
|
17902
18757
|
const features = this.list();
|
|
@@ -17942,7 +18797,7 @@ class FeatureService {
|
|
|
17942
18797
|
const tasksPath = getTasksPath(this.projectRoot, featureName);
|
|
17943
18798
|
if (!fileExists(tasksPath))
|
|
17944
18799
|
return [];
|
|
17945
|
-
const folders =
|
|
18800
|
+
const folders = fs32.readdirSync(tasksPath, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort();
|
|
17946
18801
|
return folders.map((folder) => {
|
|
17947
18802
|
const statusPath = `${tasksPath}/${folder}/status.json`;
|
|
17948
18803
|
const status = readJson(statusPath);
|
|
@@ -18272,20 +19127,20 @@ ${f.content}`).join(`
|
|
|
18272
19127
|
return [task.order - 1];
|
|
18273
19128
|
};
|
|
18274
19129
|
const visited = new Map;
|
|
18275
|
-
const
|
|
19130
|
+
const path33 = [];
|
|
18276
19131
|
const dfs = (taskOrder) => {
|
|
18277
19132
|
const state = visited.get(taskOrder);
|
|
18278
19133
|
if (state === 2) {
|
|
18279
19134
|
return;
|
|
18280
19135
|
}
|
|
18281
19136
|
if (state === 1) {
|
|
18282
|
-
const cycleStart =
|
|
18283
|
-
const cyclePath = [...
|
|
19137
|
+
const cycleStart = path33.indexOf(taskOrder);
|
|
19138
|
+
const cyclePath = [...path33.slice(cycleStart), taskOrder];
|
|
18284
19139
|
const cycleDesc = cyclePath.join(" -> ");
|
|
18285
19140
|
throw new Error(`Invalid dependency graph in plan.md: Cycle detected in task dependencies: ${cycleDesc}. ` + `Tasks cannot have circular dependencies. Please fix the "Depends on:" lines in plan.md.`);
|
|
18286
19141
|
}
|
|
18287
19142
|
visited.set(taskOrder, 1);
|
|
18288
|
-
|
|
19143
|
+
path33.push(taskOrder);
|
|
18289
19144
|
const task = taskByOrder.get(taskOrder);
|
|
18290
19145
|
if (task) {
|
|
18291
19146
|
const deps = getDependencies(task);
|
|
@@ -18293,7 +19148,7 @@ ${f.content}`).join(`
|
|
|
18293
19148
|
dfs(depOrder);
|
|
18294
19149
|
}
|
|
18295
19150
|
}
|
|
18296
|
-
|
|
19151
|
+
path33.pop();
|
|
18297
19152
|
visited.set(taskOrder, 2);
|
|
18298
19153
|
};
|
|
18299
19154
|
for (const task of tasks) {
|
|
@@ -18639,8 +19494,8 @@ function pathspec(...paths) {
|
|
|
18639
19494
|
cache.set(key, paths);
|
|
18640
19495
|
return key;
|
|
18641
19496
|
}
|
|
18642
|
-
function isPathSpec(
|
|
18643
|
-
return
|
|
19497
|
+
function isPathSpec(path33) {
|
|
19498
|
+
return path33 instanceof String && cache.has(path33);
|
|
18644
19499
|
}
|
|
18645
19500
|
function toPaths(pathSpec) {
|
|
18646
19501
|
return cache.get(pathSpec) || [];
|
|
@@ -18726,8 +19581,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = `
|
|
|
18726
19581
|
function forEachLineWithContent(input, callback) {
|
|
18727
19582
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
18728
19583
|
}
|
|
18729
|
-
function folderExists(
|
|
18730
|
-
return import_file_exists.exists(
|
|
19584
|
+
function folderExists(path33) {
|
|
19585
|
+
return import_file_exists.exists(path33, import_file_exists.FOLDER);
|
|
18731
19586
|
}
|
|
18732
19587
|
function append(target, item) {
|
|
18733
19588
|
if (Array.isArray(target)) {
|
|
@@ -19118,8 +19973,8 @@ function checkIsRepoRootTask() {
|
|
|
19118
19973
|
commands,
|
|
19119
19974
|
format: "utf-8",
|
|
19120
19975
|
onError,
|
|
19121
|
-
parser(
|
|
19122
|
-
return /^\.(git)?$/.test(
|
|
19976
|
+
parser(path33) {
|
|
19977
|
+
return /^\.(git)?$/.test(path33.trim());
|
|
19123
19978
|
}
|
|
19124
19979
|
};
|
|
19125
19980
|
}
|
|
@@ -19530,11 +20385,11 @@ function parseGrep(grep) {
|
|
|
19530
20385
|
const paths = /* @__PURE__ */ new Set;
|
|
19531
20386
|
const results = {};
|
|
19532
20387
|
forEachLineWithContent(grep, (input) => {
|
|
19533
|
-
const [
|
|
19534
|
-
paths.add(
|
|
19535
|
-
(results[
|
|
20388
|
+
const [path33, line, preview] = input.split(NULL);
|
|
20389
|
+
paths.add(path33);
|
|
20390
|
+
(results[path33] = results[path33] || []).push({
|
|
19536
20391
|
line: asNumber(line),
|
|
19537
|
-
path:
|
|
20392
|
+
path: path33,
|
|
19538
20393
|
preview
|
|
19539
20394
|
});
|
|
19540
20395
|
});
|
|
@@ -20200,14 +21055,14 @@ var init_hash_object = __esm2({
|
|
|
20200
21055
|
init_task();
|
|
20201
21056
|
}
|
|
20202
21057
|
});
|
|
20203
|
-
function parseInit(bare,
|
|
21058
|
+
function parseInit(bare, path33, text) {
|
|
20204
21059
|
const response = String(text).trim();
|
|
20205
21060
|
let result;
|
|
20206
21061
|
if (result = initResponseRegex.exec(response)) {
|
|
20207
|
-
return new InitSummary(bare,
|
|
21062
|
+
return new InitSummary(bare, path33, false, result[1]);
|
|
20208
21063
|
}
|
|
20209
21064
|
if (result = reInitResponseRegex.exec(response)) {
|
|
20210
|
-
return new InitSummary(bare,
|
|
21065
|
+
return new InitSummary(bare, path33, true, result[1]);
|
|
20211
21066
|
}
|
|
20212
21067
|
let gitDir = "";
|
|
20213
21068
|
const tokens = response.split(" ");
|
|
@@ -20218,7 +21073,7 @@ function parseInit(bare, path32, text) {
|
|
|
20218
21073
|
break;
|
|
20219
21074
|
}
|
|
20220
21075
|
}
|
|
20221
|
-
return new InitSummary(bare,
|
|
21076
|
+
return new InitSummary(bare, path33, /^re/i.test(response), gitDir);
|
|
20222
21077
|
}
|
|
20223
21078
|
var InitSummary;
|
|
20224
21079
|
var initResponseRegex;
|
|
@@ -20226,9 +21081,9 @@ var reInitResponseRegex;
|
|
|
20226
21081
|
var init_InitSummary = __esm2({
|
|
20227
21082
|
"src/lib/responses/InitSummary.ts"() {
|
|
20228
21083
|
InitSummary = class {
|
|
20229
|
-
constructor(bare,
|
|
21084
|
+
constructor(bare, path33, existing, gitDir) {
|
|
20230
21085
|
this.bare = bare;
|
|
20231
|
-
this.path =
|
|
21086
|
+
this.path = path33;
|
|
20232
21087
|
this.existing = existing;
|
|
20233
21088
|
this.gitDir = gitDir;
|
|
20234
21089
|
}
|
|
@@ -20240,7 +21095,7 @@ var init_InitSummary = __esm2({
|
|
|
20240
21095
|
function hasBareCommand(command) {
|
|
20241
21096
|
return command.includes(bareCommand);
|
|
20242
21097
|
}
|
|
20243
|
-
function initTask(bare = false,
|
|
21098
|
+
function initTask(bare = false, path33, customArgs) {
|
|
20244
21099
|
const commands = ["init", ...customArgs];
|
|
20245
21100
|
if (bare && !hasBareCommand(commands)) {
|
|
20246
21101
|
commands.splice(1, 0, bareCommand);
|
|
@@ -20249,7 +21104,7 @@ function initTask(bare = false, path32, customArgs) {
|
|
|
20249
21104
|
commands,
|
|
20250
21105
|
format: "utf-8",
|
|
20251
21106
|
parser(text) {
|
|
20252
|
-
return parseInit(commands.includes("--bare"),
|
|
21107
|
+
return parseInit(commands.includes("--bare"), path33, text);
|
|
20253
21108
|
}
|
|
20254
21109
|
};
|
|
20255
21110
|
}
|
|
@@ -20964,12 +21819,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
20964
21819
|
"src/lib/responses/FileStatusSummary.ts"() {
|
|
20965
21820
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
20966
21821
|
FileStatusSummary = class {
|
|
20967
|
-
constructor(
|
|
20968
|
-
this.path =
|
|
21822
|
+
constructor(path33, index, working_dir) {
|
|
21823
|
+
this.path = path33;
|
|
20969
21824
|
this.index = index;
|
|
20970
21825
|
this.working_dir = working_dir;
|
|
20971
21826
|
if (index === "R" || working_dir === "R") {
|
|
20972
|
-
const detail = fromPathRegex.exec(
|
|
21827
|
+
const detail = fromPathRegex.exec(path33) || [null, path33, path33];
|
|
20973
21828
|
this.from = detail[2] || "";
|
|
20974
21829
|
this.path = detail[1] || "";
|
|
20975
21830
|
}
|
|
@@ -21000,14 +21855,14 @@ function splitLine(result, lineStr) {
|
|
|
21000
21855
|
default:
|
|
21001
21856
|
return;
|
|
21002
21857
|
}
|
|
21003
|
-
function data(index, workingDir,
|
|
21858
|
+
function data(index, workingDir, path33) {
|
|
21004
21859
|
const raw = `${index}${workingDir}`;
|
|
21005
21860
|
const handler = parsers6.get(raw);
|
|
21006
21861
|
if (handler) {
|
|
21007
|
-
handler(result,
|
|
21862
|
+
handler(result, path33);
|
|
21008
21863
|
}
|
|
21009
21864
|
if (raw !== "##" && raw !== "!!") {
|
|
21010
|
-
result.files.push(new FileStatusSummary(
|
|
21865
|
+
result.files.push(new FileStatusSummary(path33, index, workingDir));
|
|
21011
21866
|
}
|
|
21012
21867
|
}
|
|
21013
21868
|
}
|
|
@@ -21291,8 +22146,8 @@ var init_simple_git_api = __esm2({
|
|
|
21291
22146
|
}
|
|
21292
22147
|
return this._runTask(configurationErrorTask("Git.cwd: workingDirectory must be supplied as a string"), next);
|
|
21293
22148
|
}
|
|
21294
|
-
hashObject(
|
|
21295
|
-
return this._runTask(hashObjectTask(
|
|
22149
|
+
hashObject(path33, write) {
|
|
22150
|
+
return this._runTask(hashObjectTask(path33, write === true), trailingFunctionArgument(arguments));
|
|
21296
22151
|
}
|
|
21297
22152
|
init(bare) {
|
|
21298
22153
|
return this._runTask(initTask(bare === true, this._executor.cwd, getTrailingOptions(arguments)), trailingFunctionArgument(arguments));
|
|
@@ -21585,8 +22440,8 @@ var init_branch = __esm2({
|
|
|
21585
22440
|
}
|
|
21586
22441
|
});
|
|
21587
22442
|
function toPath(input) {
|
|
21588
|
-
const
|
|
21589
|
-
return
|
|
22443
|
+
const path33 = input.trim().replace(/^["']|["']$/g, "");
|
|
22444
|
+
return path33 && normalize(path33);
|
|
21590
22445
|
}
|
|
21591
22446
|
var parseCheckIgnore;
|
|
21592
22447
|
var init_CheckIgnore = __esm2({
|
|
@@ -21851,8 +22706,8 @@ __export2(sub_module_exports, {
|
|
|
21851
22706
|
subModuleTask: () => subModuleTask,
|
|
21852
22707
|
updateSubModuleTask: () => updateSubModuleTask
|
|
21853
22708
|
});
|
|
21854
|
-
function addSubModuleTask(repo,
|
|
21855
|
-
return subModuleTask(["add", repo,
|
|
22709
|
+
function addSubModuleTask(repo, path33) {
|
|
22710
|
+
return subModuleTask(["add", repo, path33]);
|
|
21856
22711
|
}
|
|
21857
22712
|
function initSubModuleTask(customArgs) {
|
|
21858
22713
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -22106,8 +22961,8 @@ var require_git = __commonJS2({
|
|
|
22106
22961
|
}
|
|
22107
22962
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
22108
22963
|
};
|
|
22109
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
22110
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
22964
|
+
Git2.prototype.submoduleAdd = function(repo, path33, then) {
|
|
22965
|
+
return this._runTask(addSubModuleTask2(repo, path33), trailingFunctionArgument2(arguments));
|
|
22111
22966
|
};
|
|
22112
22967
|
Git2.prototype.submoduleUpdate = function(args2, then) {
|
|
22113
22968
|
return this._runTask(updateSubModuleTask2(getTrailingOptions2(arguments, true)), trailingFunctionArgument2(arguments));
|
|
@@ -22640,19 +23495,19 @@ class WorktreeService {
|
|
|
22640
23495
|
return esm_default(cwd || this.config.baseDir);
|
|
22641
23496
|
}
|
|
22642
23497
|
getWorktreesDir() {
|
|
22643
|
-
return
|
|
23498
|
+
return path32.join(this.config.hiveDir, ".worktrees");
|
|
22644
23499
|
}
|
|
22645
23500
|
getWorktreePath(feature, step) {
|
|
22646
|
-
return
|
|
23501
|
+
return path32.join(this.getWorktreesDir(), feature, step);
|
|
22647
23502
|
}
|
|
22648
23503
|
async getStepStatusPath(feature, step) {
|
|
22649
|
-
const featurePath =
|
|
22650
|
-
const tasksPath =
|
|
23504
|
+
const featurePath = path32.join(this.config.hiveDir, "features", feature);
|
|
23505
|
+
const tasksPath = path32.join(featurePath, "tasks", step, "status.json");
|
|
22651
23506
|
try {
|
|
22652
23507
|
await fs7.access(tasksPath);
|
|
22653
23508
|
return tasksPath;
|
|
22654
23509
|
} catch {}
|
|
22655
|
-
return
|
|
23510
|
+
return path32.join(featurePath, "execution", step, "status.json");
|
|
22656
23511
|
}
|
|
22657
23512
|
getBranchName(feature, step) {
|
|
22658
23513
|
return `hive/${feature}/${step}`;
|
|
@@ -22661,7 +23516,7 @@ class WorktreeService {
|
|
|
22661
23516
|
const worktreePath = this.getWorktreePath(feature, step);
|
|
22662
23517
|
const branchName = this.getBranchName(feature, step);
|
|
22663
23518
|
const git = this.getGit();
|
|
22664
|
-
await fs7.mkdir(
|
|
23519
|
+
await fs7.mkdir(path32.dirname(worktreePath), { recursive: true });
|
|
22665
23520
|
const base = baseBranch || (await git.revparse(["HEAD"])).trim();
|
|
22666
23521
|
const existing = await this.get(feature, step);
|
|
22667
23522
|
if (existing) {
|
|
@@ -22756,7 +23611,7 @@ class WorktreeService {
|
|
|
22756
23611
|
}
|
|
22757
23612
|
async exportPatch(feature, step, baseBranch) {
|
|
22758
23613
|
const worktreePath = this.getWorktreePath(feature, step);
|
|
22759
|
-
const patchPath =
|
|
23614
|
+
const patchPath = path32.join(worktreePath, "..", `${step}.patch`);
|
|
22760
23615
|
const base = baseBranch || "HEAD~1";
|
|
22761
23616
|
const worktreeGit = this.getGit(worktreePath);
|
|
22762
23617
|
const diff = await worktreeGit.diff([`${base}...HEAD`]);
|
|
@@ -22768,7 +23623,7 @@ class WorktreeService {
|
|
|
22768
23623
|
if (!hasDiff) {
|
|
22769
23624
|
return { success: true, filesAffected: [] };
|
|
22770
23625
|
}
|
|
22771
|
-
const patchPath =
|
|
23626
|
+
const patchPath = path32.join(this.config.hiveDir, ".worktrees", feature, `${step}.patch`);
|
|
22772
23627
|
try {
|
|
22773
23628
|
await fs7.writeFile(patchPath, diffContent);
|
|
22774
23629
|
const git = this.getGit();
|
|
@@ -22790,7 +23645,7 @@ class WorktreeService {
|
|
|
22790
23645
|
if (!hasDiff) {
|
|
22791
23646
|
return { success: true, filesAffected: [] };
|
|
22792
23647
|
}
|
|
22793
|
-
const patchPath =
|
|
23648
|
+
const patchPath = path32.join(this.config.hiveDir, ".worktrees", feature, `${step}.patch`);
|
|
22794
23649
|
try {
|
|
22795
23650
|
await fs7.writeFile(patchPath, diffContent);
|
|
22796
23651
|
const git = this.getGit();
|
|
@@ -22859,7 +23714,7 @@ class WorktreeService {
|
|
|
22859
23714
|
try {
|
|
22860
23715
|
const features = feature ? [feature] : await fs7.readdir(worktreesDir);
|
|
22861
23716
|
for (const feat of features) {
|
|
22862
|
-
const featurePath =
|
|
23717
|
+
const featurePath = path32.join(worktreesDir, feat);
|
|
22863
23718
|
const stat2 = await fs7.stat(featurePath).catch(() => null);
|
|
22864
23719
|
if (!stat2?.isDirectory())
|
|
22865
23720
|
continue;
|
|
@@ -22883,13 +23738,13 @@ class WorktreeService {
|
|
|
22883
23738
|
const worktreesDir = this.getWorktreesDir();
|
|
22884
23739
|
const features = feature ? [feature] : await fs7.readdir(worktreesDir).catch(() => []);
|
|
22885
23740
|
for (const feat of features) {
|
|
22886
|
-
const featurePath =
|
|
23741
|
+
const featurePath = path32.join(worktreesDir, feat);
|
|
22887
23742
|
const stat2 = await fs7.stat(featurePath).catch(() => null);
|
|
22888
23743
|
if (!stat2?.isDirectory())
|
|
22889
23744
|
continue;
|
|
22890
23745
|
const steps = await fs7.readdir(featurePath).catch(() => []);
|
|
22891
23746
|
for (const step of steps) {
|
|
22892
|
-
const worktreePath =
|
|
23747
|
+
const worktreePath = path32.join(featurePath, step);
|
|
22893
23748
|
const stepStat = await fs7.stat(worktreePath).catch(() => null);
|
|
22894
23749
|
if (!stepStat?.isDirectory())
|
|
22895
23750
|
continue;
|
|
@@ -22909,7 +23764,7 @@ class WorktreeService {
|
|
|
22909
23764
|
if (!hasDiff) {
|
|
22910
23765
|
return [];
|
|
22911
23766
|
}
|
|
22912
|
-
const patchPath =
|
|
23767
|
+
const patchPath = path32.join(this.config.hiveDir, ".worktrees", feature, `${step}-check.patch`);
|
|
22913
23768
|
try {
|
|
22914
23769
|
await fs7.writeFile(patchPath, diffContent);
|
|
22915
23770
|
const git = this.getGit();
|
|
@@ -23592,19 +24447,19 @@ class AgentsMdService {
|
|
|
23592
24447
|
|
|
23593
24448
|
class DockerSandboxService {
|
|
23594
24449
|
static detectImage(worktreePath) {
|
|
23595
|
-
if (existsSync5(
|
|
24450
|
+
if (existsSync5(join82(worktreePath, "Dockerfile"))) {
|
|
23596
24451
|
return null;
|
|
23597
24452
|
}
|
|
23598
|
-
if (existsSync5(
|
|
24453
|
+
if (existsSync5(join82(worktreePath, "package.json"))) {
|
|
23599
24454
|
return "node:22-slim";
|
|
23600
24455
|
}
|
|
23601
|
-
if (existsSync5(
|
|
24456
|
+
if (existsSync5(join82(worktreePath, "requirements.txt")) || existsSync5(join82(worktreePath, "pyproject.toml"))) {
|
|
23602
24457
|
return "python:3.12-slim";
|
|
23603
24458
|
}
|
|
23604
|
-
if (existsSync5(
|
|
24459
|
+
if (existsSync5(join82(worktreePath, "go.mod"))) {
|
|
23605
24460
|
return "golang:1.22-slim";
|
|
23606
24461
|
}
|
|
23607
|
-
if (existsSync5(
|
|
24462
|
+
if (existsSync5(join82(worktreePath, "Cargo.toml"))) {
|
|
23608
24463
|
return "rust:1.77-slim";
|
|
23609
24464
|
}
|
|
23610
24465
|
return "ubuntu:24.04";
|
|
@@ -24251,7 +25106,7 @@ async function buildAutoLoadedSkillsContent(agentName, configService, projectRoo
|
|
|
24251
25106
|
if (autoLoadSkills.length === 0) {
|
|
24252
25107
|
return "";
|
|
24253
25108
|
}
|
|
24254
|
-
const homeDir = process.env.HOME ||
|
|
25109
|
+
const homeDir = process.env.HOME || os2.homedir();
|
|
24255
25110
|
const skillTemplates = [];
|
|
24256
25111
|
for (const skillId of autoLoadSkills) {
|
|
24257
25112
|
const builtinSkill = BUILTIN_SKILLS.find((entry) => entry.name === skillId);
|
|
@@ -24794,6 +25649,10 @@ Use the \`@path\` attachment syntax in the prompt to reference the file. Do not
|
|
|
24794
25649
|
return;
|
|
24795
25650
|
}
|
|
24796
25651
|
output.system.push(HIVE_SYSTEM_PROMPT);
|
|
25652
|
+
const memoryInjection = await buildMemoryInjection(directory);
|
|
25653
|
+
if (memoryInjection) {
|
|
25654
|
+
output.system.push(memoryInjection);
|
|
25655
|
+
}
|
|
24797
25656
|
const activeFeature = resolveFeature();
|
|
24798
25657
|
if (activeFeature) {
|
|
24799
25658
|
const info = featureService.getInfo(activeFeature);
|
|
@@ -24814,16 +25673,64 @@ Use the \`@path\` attachment syntax in the prompt to reference the file. Do not
|
|
|
24814
25673
|
}
|
|
24815
25674
|
},
|
|
24816
25675
|
"experimental.session.compacting": async (input, output) => {
|
|
25676
|
+
const snapshotConfig = configService.get().sessionSnapshot;
|
|
25677
|
+
const compressionConfig = configService.get().contextCompression;
|
|
25678
|
+
if (snapshotConfig?.enabled !== false) {
|
|
25679
|
+
const snapshotParts = [];
|
|
25680
|
+
const maxChars = snapshotConfig?.maxSnapshotChars ?? 2048;
|
|
25681
|
+
if (snapshotConfig?.includeActiveFeature !== false) {
|
|
25682
|
+
try {
|
|
25683
|
+
const active = featureService.getActive();
|
|
25684
|
+
if (active) {
|
|
25685
|
+
snapshotParts.push(`## Active Feature: ${active.name}`);
|
|
25686
|
+
snapshotParts.push(`Status: ${active.status}`);
|
|
25687
|
+
}
|
|
25688
|
+
} catch {}
|
|
25689
|
+
}
|
|
25690
|
+
if (snapshotConfig?.includePendingTasks !== false) {
|
|
25691
|
+
try {
|
|
25692
|
+
const featureNames = featureService.list();
|
|
25693
|
+
const pendingTasks = [];
|
|
25694
|
+
for (const name of featureNames) {
|
|
25695
|
+
const info = featureService.getInfo(name);
|
|
25696
|
+
if (info && info.status !== "completed") {
|
|
25697
|
+
const pending = info.tasks.filter((t) => t.status === "pending" || t.status === "in_progress");
|
|
25698
|
+
for (const task of pending) {
|
|
25699
|
+
pendingTasks.push(`- [${task.status}] ${task.name}`);
|
|
25700
|
+
}
|
|
25701
|
+
}
|
|
25702
|
+
}
|
|
25703
|
+
if (pendingTasks.length > 0) {
|
|
25704
|
+
snapshotParts.push(`
|
|
25705
|
+
## Pending Tasks (${pendingTasks.length})`);
|
|
25706
|
+
snapshotParts.push(...pendingTasks.slice(0, 20));
|
|
25707
|
+
}
|
|
25708
|
+
} catch {}
|
|
25709
|
+
}
|
|
25710
|
+
if (snapshotParts.length > 0) {
|
|
25711
|
+
const snapshot = snapshotParts.join(`
|
|
25712
|
+
`).slice(0, maxChars);
|
|
25713
|
+
output.context.push(`
|
|
25714
|
+
## Session Snapshot (before compaction)
|
|
25715
|
+
|
|
25716
|
+
${snapshot}
|
|
25717
|
+
|
|
25718
|
+
**Important:** After compaction, resume from where you left off. Check the pending tasks above and continue working.
|
|
25719
|
+
`);
|
|
25720
|
+
}
|
|
25721
|
+
}
|
|
24817
25722
|
const contextLimit = input.contextLimit || 200000;
|
|
24818
25723
|
const messages = input.messages || [];
|
|
24819
25724
|
if (messages.length > 0) {
|
|
24820
|
-
const {
|
|
24821
|
-
|
|
24822
|
-
|
|
24823
|
-
|
|
24824
|
-
|
|
24825
|
-
|
|
24826
|
-
|
|
25725
|
+
const { needsCompression: needsCompression2, compressContext: compressContext2, buildCompressionHint: buildCompressionHint2 } = await Promise.resolve().then(() => (init_context_compression(), exports_context_compression));
|
|
25726
|
+
const threshold = compressionConfig?.threshold ?? 0.5;
|
|
25727
|
+
const enabled = compressionConfig?.enabled ?? true;
|
|
25728
|
+
if (needsCompression2(messages, contextLimit, { threshold, enabled })) {
|
|
25729
|
+
const { stats } = compressContext2(messages, {
|
|
25730
|
+
threshold,
|
|
25731
|
+
enabled,
|
|
25732
|
+
maxToolCalls: compressionConfig?.maxToolCalls ?? 50,
|
|
25733
|
+
protectedTools: compressionConfig?.protectedTools ?? [
|
|
24827
25734
|
"hive_feature_create",
|
|
24828
25735
|
"hive_plan_write",
|
|
24829
25736
|
"hive_worktree_commit",
|
|
@@ -24868,6 +25775,27 @@ Use the \`@path\` attachment syntax in the prompt to reference the file. Do not
|
|
|
24868
25775
|
output.args.command = wrapped;
|
|
24869
25776
|
output.args.workdir = undefined;
|
|
24870
25777
|
},
|
|
25778
|
+
"tool.execute.after": async (input, output) => {
|
|
25779
|
+
const truncationConfig = configService.get().tokenTruncation;
|
|
25780
|
+
if (!truncationConfig?.enabled)
|
|
25781
|
+
return;
|
|
25782
|
+
const result = output.output;
|
|
25783
|
+
if (!result)
|
|
25784
|
+
return;
|
|
25785
|
+
const maxChars = truncationConfig.maxChars ?? 30000;
|
|
25786
|
+
if (result.length <= maxChars)
|
|
25787
|
+
return;
|
|
25788
|
+
const keepFirst = truncationConfig.keepFirstPercent ?? 40;
|
|
25789
|
+
const keepLast = truncationConfig.keepLastPercent ?? 40;
|
|
25790
|
+
const firstChars = Math.floor(result.length * keepFirst / 100);
|
|
25791
|
+
const lastChars = Math.floor(result.length * keepLast / 100);
|
|
25792
|
+
const truncated = result.slice(0, firstChars) + `
|
|
25793
|
+
|
|
25794
|
+
[... ${result.length - firstChars - lastChars} characters truncated ...]
|
|
25795
|
+
|
|
25796
|
+
` + result.slice(-lastChars);
|
|
25797
|
+
output.output = truncated;
|
|
25798
|
+
},
|
|
24871
25799
|
mcp: builtinMcps,
|
|
24872
25800
|
tool: {
|
|
24873
25801
|
gitingest: gitingestTool,
|
|
@@ -24887,6 +25815,11 @@ Use the \`@path\` attachment syntax in the prompt to reference the file. Do not
|
|
|
24887
25815
|
lsp_code_actions: lspCodeActionsTool,
|
|
24888
25816
|
skill_mcp: skillMcpTool,
|
|
24889
25817
|
list_skill_mcps: listSkillMcpsTool,
|
|
25818
|
+
hive_memory_list: hiveMemoryListTool,
|
|
25819
|
+
hive_memory_set: hiveMemorySetTool,
|
|
25820
|
+
hive_memory_replace: hiveMemoryReplaceTool,
|
|
25821
|
+
hive_journal_write: hiveJournalWriteTool,
|
|
25822
|
+
hive_journal_search: hiveJournalSearchTool,
|
|
24890
25823
|
hive_skill: createHiveSkillTool(filteredSkills),
|
|
24891
25824
|
hive_feature_create: tool({
|
|
24892
25825
|
description: "Create a new feature and set it as active",
|
|
@@ -25661,13 +26594,111 @@ ${Object.entries(customAgentConfigs).sort(([left], [right]) => left.localeCompar
|
|
|
25661
26594
|
skill: "allow"
|
|
25662
26595
|
}
|
|
25663
26596
|
};
|
|
26597
|
+
const micodeUserConfig = configService.getAgentConfig("codebase-locator");
|
|
26598
|
+
const codebaseLocatorConfig = {
|
|
26599
|
+
model: micodeUserConfig.model,
|
|
26600
|
+
variant: micodeUserConfig.variant,
|
|
26601
|
+
temperature: micodeUserConfig.temperature ?? 0.3,
|
|
26602
|
+
mode: "subagent",
|
|
26603
|
+
description: "Codebase Locator - Finds WHERE files live in the codebase. No analysis, just locations.",
|
|
26604
|
+
prompt: CODEBASE_LOCATOR_PROMPT,
|
|
26605
|
+
tools: agentTools(["hive_plan_read", "hive_skill"]),
|
|
26606
|
+
permission: {
|
|
26607
|
+
edit: "deny",
|
|
26608
|
+
task: "deny",
|
|
26609
|
+
delegate: "deny",
|
|
26610
|
+
skill: "allow"
|
|
26611
|
+
}
|
|
26612
|
+
};
|
|
26613
|
+
const codebaseAnalyzerConfig = {
|
|
26614
|
+
model: micodeUserConfig.model,
|
|
26615
|
+
variant: micodeUserConfig.variant,
|
|
26616
|
+
temperature: micodeUserConfig.temperature ?? 0.3,
|
|
26617
|
+
mode: "subagent",
|
|
26618
|
+
description: "Codebase Analyzer - Explains HOW code works. Deep module analysis.",
|
|
26619
|
+
prompt: CODEBASE_ANALYZER_PROMPT,
|
|
26620
|
+
tools: agentTools(["hive_plan_read", "hive_skill"]),
|
|
26621
|
+
permission: {
|
|
26622
|
+
edit: "deny",
|
|
26623
|
+
task: "deny",
|
|
26624
|
+
delegate: "deny",
|
|
26625
|
+
skill: "allow"
|
|
26626
|
+
}
|
|
26627
|
+
};
|
|
26628
|
+
const patternFinderConfig = {
|
|
26629
|
+
model: micodeUserConfig.model,
|
|
26630
|
+
variant: micodeUserConfig.variant,
|
|
26631
|
+
temperature: micodeUserConfig.temperature ?? 0.3,
|
|
26632
|
+
mode: "subagent",
|
|
26633
|
+
description: "Pattern Finder - Finds patterns to model after. Extracts conventions.",
|
|
26634
|
+
prompt: PATTERN_FINDER_PROMPT,
|
|
26635
|
+
tools: agentTools(["hive_plan_read", "hive_skill"]),
|
|
26636
|
+
permission: {
|
|
26637
|
+
edit: "deny",
|
|
26638
|
+
task: "deny",
|
|
26639
|
+
delegate: "deny",
|
|
26640
|
+
skill: "allow"
|
|
26641
|
+
}
|
|
26642
|
+
};
|
|
26643
|
+
const projectInitializerConfig = {
|
|
26644
|
+
model: micodeUserConfig.model,
|
|
26645
|
+
variant: micodeUserConfig.variant,
|
|
26646
|
+
temperature: micodeUserConfig.temperature ?? 0.5,
|
|
26647
|
+
mode: "subagent",
|
|
26648
|
+
description: "Project Initializer - Generates project documentation from codebase analysis.",
|
|
26649
|
+
prompt: PROJECT_INITIALIZER_PROMPT,
|
|
26650
|
+
tools: agentTools(["hive_plan_read", "hive_context_write", "hive_skill"]),
|
|
26651
|
+
permission: {
|
|
26652
|
+
edit: "deny",
|
|
26653
|
+
task: "deny",
|
|
26654
|
+
delegate: "deny",
|
|
26655
|
+
skill: "allow"
|
|
26656
|
+
}
|
|
26657
|
+
};
|
|
26658
|
+
const froggyUserConfig = configService.getAgentConfig("code-reviewer");
|
|
26659
|
+
const codeReviewerConfig = {
|
|
26660
|
+
model: froggyUserConfig.model,
|
|
26661
|
+
variant: froggyUserConfig.variant,
|
|
26662
|
+
temperature: froggyUserConfig.temperature ?? 0.3,
|
|
26663
|
+
mode: "subagent",
|
|
26664
|
+
description: "Code Reviewer - Reviews code for quality, correctness, security, and maintainability.",
|
|
26665
|
+
prompt: CODE_REVIEWER_PROMPT,
|
|
26666
|
+
tools: agentTools(["hive_plan_read", "hive_skill"]),
|
|
26667
|
+
permission: {
|
|
26668
|
+
edit: "deny",
|
|
26669
|
+
task: "deny",
|
|
26670
|
+
delegate: "deny",
|
|
26671
|
+
skill: "allow"
|
|
26672
|
+
}
|
|
26673
|
+
};
|
|
26674
|
+
const codeSimplifierConfig = {
|
|
26675
|
+
model: froggyUserConfig.model,
|
|
26676
|
+
variant: froggyUserConfig.variant,
|
|
26677
|
+
temperature: froggyUserConfig.temperature ?? 0.3,
|
|
26678
|
+
mode: "subagent",
|
|
26679
|
+
description: "Code Simplifier - Simplifies recently modified code for clarity while preserving behavior.",
|
|
26680
|
+
prompt: CODE_SIMPLIFIER_PROMPT,
|
|
26681
|
+
tools: agentTools(["hive_plan_read", "hive_skill"]),
|
|
26682
|
+
permission: {
|
|
26683
|
+
edit: "deny",
|
|
26684
|
+
task: "deny",
|
|
26685
|
+
delegate: "deny",
|
|
26686
|
+
skill: "allow"
|
|
26687
|
+
}
|
|
26688
|
+
};
|
|
25664
26689
|
const builtInAgentConfigs = {
|
|
25665
26690
|
zetta: zettaConfig,
|
|
25666
26691
|
"architect-planner": architectConfig,
|
|
25667
26692
|
"swarm-orchestrator": swarmConfig,
|
|
25668
26693
|
"scout-researcher": scoutConfig,
|
|
25669
26694
|
"forager-worker": foragerConfig,
|
|
25670
|
-
"hygienic-reviewer": hygienicConfig
|
|
26695
|
+
"hygienic-reviewer": hygienicConfig,
|
|
26696
|
+
"code-reviewer": codeReviewerConfig,
|
|
26697
|
+
"code-simplifier": codeSimplifierConfig,
|
|
26698
|
+
"codebase-locator": codebaseLocatorConfig,
|
|
26699
|
+
"codebase-analyzer": codebaseAnalyzerConfig,
|
|
26700
|
+
"pattern-finder": patternFinderConfig,
|
|
26701
|
+
"project-initializer": projectInitializerConfig
|
|
25671
26702
|
};
|
|
25672
26703
|
const customAutoLoadedSkills = Object.fromEntries(await Promise.all(Object.entries(customAgentConfigs).map(async ([customAgentName, customAgentConfig]) => {
|
|
25673
26704
|
const inheritedBaseSkills = customAgentConfig.baseAgent === "forager-worker" ? foragerUserConfig.autoLoadSkills ?? [] : hygienicUserConfig.autoLoadSkills ?? [];
|