Files
2026-04-17 10:35:09 +09:00

95 lines
2.8 KiB
JavaScript

#!/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);
}