add template
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function readStdin() {
|
||||
return fs.readFileSync(0, 'utf8');
|
||||
}
|
||||
|
||||
function isInside(parent, target) {
|
||||
const relative = path.relative(parent, target);
|
||||
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
||||
}
|
||||
|
||||
function collectPathStrings(value, key = '', output = []) {
|
||||
if (value == null) {
|
||||
return output;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
if (/path|file/i.test(key)) {
|
||||
output.push(value);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((item) => collectPathStrings(item, key, output));
|
||||
return output;
|
||||
}
|
||||
|
||||
if (typeof value === 'object') {
|
||||
Object.entries(value).forEach(([childKey, childValue]) => {
|
||||
collectPathStrings(childValue, childKey, output);
|
||||
});
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function resolveCandidate(candidate, rootDir) {
|
||||
const cleaned = String(candidate).trim().replace(/^["']|["']$/g, '');
|
||||
if (!cleaned) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return path.isAbsolute(cleaned)
|
||||
? path.resolve(cleaned)
|
||||
: path.resolve(rootDir, cleaned);
|
||||
}
|
||||
|
||||
try {
|
||||
const input = JSON.parse(readStdin() || '{}');
|
||||
if (input.tool_response && input.tool_response.error) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const projectDir = process.env.GEMINI_PROJECT_DIR || input.cwd || process.cwd();
|
||||
const wikiDir = path.resolve(projectDir, 'wiki');
|
||||
const outputDir = path.resolve(projectDir, 'output');
|
||||
const indexPath = path.resolve(wikiDir, 'index.md');
|
||||
const logPath = path.resolve(wikiDir, 'log.md');
|
||||
const candidates = collectPathStrings(input.tool_input || {});
|
||||
const targets = candidates
|
||||
.map((candidate) => resolveCandidate(candidate, projectDir))
|
||||
.filter(Boolean);
|
||||
|
||||
const wikiTargets = targets.filter((target) => isInside(wikiDir, target));
|
||||
const outputTargets = targets.filter((target) => isInside(outputDir, target));
|
||||
|
||||
if (wikiTargets.some((target) => target !== indexPath && target !== logPath)) {
|
||||
process.stdout.write(JSON.stringify({
|
||||
suppressOutput: true,
|
||||
hookSpecificOutput: {
|
||||
additionalContext:
|
||||
'wiki/ 페이지를 수정했다. 이 턴이 끝나기 전에 YAML frontmatter(title, tags, sources, created, updated), [[wikilink]], wiki/index.md 한 줄 항목, wiki/log.md 변경 기록이 모두 반영되었는지 확인하라.'
|
||||
}
|
||||
}));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (outputTargets.length > 0) {
|
||||
process.stdout.write(JSON.stringify({
|
||||
suppressOutput: true,
|
||||
hookSpecificOutput: {
|
||||
additionalContext:
|
||||
'output/ 결과물은 wiki/ 페이지에 근거해야 한다. 가능하면 사용한 핵심 wiki 페이지를 본문 또는 말미에 남기고, raw/ 직접 해석에 의존하지 마라.'
|
||||
}
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
process.stderr.write(String(error));
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user