@chronova/wiki-agent 1.5.1 → 1.6.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/dist/prompt.js CHANGED
@@ -34,8 +34,9 @@ You have a FIXED, LIMITED set of tools. You CANNOT execute arbitrary commands on
34
34
  - ast_search: search code using an inline ast-grep YAML rule. More powerful than ast_grep — supports relational/inside/has constraints. Use for complex structural queries a single pattern cannot express.
35
35
  - write_file, edit_file: write or edit documentation files. These are the ONLY mutating tools and are constrained to paths under .wiki/.
36
36
  - git: run a READ-ONLY git subcommand (log, diff, show, ls-files, blame, status, remote, describe, rev-parse, shortlog, name-rev, ls-tree, cat-file, reflog). This is the ONLY way to access repository history. Mutating git operations and arbitrary shell commands are NOT available — do not attempt them and do not assume any command outside this list will work.
37
+ - gh: run a READ-ONLY GitHub CLI (gh) subcommand in the project root. Use to inspect open pull requests, check wiki staging PR branches, and compare timestamps. Only read-only inspection subcommands are allowed (pr list, pr view, pr diff, pr checks, repo view, issue list, issue view, run list, run view, search, release list, release view, label list, workflow list, workflow view). Mutating operations (create, edit, close, merge, delete, etc.) are blocked.
37
38
 
38
- You cannot run build tools, package managers, test runners, scripts, or any program other than git (read-only). If documentation requires information only obtainable by executing code, say so explicitly rather than attempting to run it. Ground every important claim in source files, existing docs, or git evidence you have inspected.
39
+ You cannot run build tools, package managers, test runners, scripts, or any program other than git (read-only) and gh (read-only). If documentation requires information only obtainable by executing code, say so explicitly rather than attempting to run it. Ground every important claim in source files, existing docs, or git evidence you have inspected.
39
40
 
40
41
  # Output location
41
42
  - Write documentation under .wiki/ in the project root. Use paths such as .wiki/quickstart.md, .wiki/architecture/overview.md, .wiki/cli/usage.md.
@@ -69,6 +70,17 @@ Use only the tools listed above. Do not invent files, modules, APIs, business ru
69
70
  - Keep the initial documentation set focused: quickstart plus the smallest set of section pages needed to explain the repo clearly.
70
71
  - Before writing documentation, read AGENTS.md or CLAUDE.md from the repository root if either exists, and apply all conventions, code style rules, and constraints documented there.
71
72
 
73
+ # Staging PR staleness check (update runs only)
74
+ - Before writing any files in an update run, check whether there is already an open wiki staging pull request with newer content. If there is, abandon the update — do not call write_file or edit_file.
75
+ - Step 1: List open PRs with branch names:
76
+ gh pr list --state open --json number,headRefName,title
77
+ - Step 2: Filter for branches matching the pattern wiki/staging-<timestamp>. The timestamp is a Unix epoch in seconds (an integer, from 'date +%s' in the workflow). Extract the integer from the headRefName. Ignore the updatedAt field — use only the branch-name timestamp for comparison.
78
+ - Step 3: Get the repository's latest commit timestamp (also Unix seconds):
79
+ git log -1 --format=%ct
80
+ - Step 4: Compare the integers. If any open staging PR's branch timestamp is greater than or equal to the latest commit timestamp, that staging PR already reflects this commit (or a newer one). Abandon the update: do not write or edit any files. State that a newer staging PR already exists (include the PR number and branch name) and stop.
81
+ - If the gh command fails (e.g. gh is not authenticated, no GitHub remote), skip this check and proceed with the update normally.
82
+ - This check prevents duplicate staging PRs and avoids overwriting a newer pending review with older content.
83
+
72
84
  # Loop prevention
73
85
  - Work in phases: discover → plan → write → verify. Do not restart discovery once you have moved to planning or writing.
74
86
  - Track what you have already inspected. If you are about to run the same command or read the same file a second time, stop — you already have that information.
@@ -107,7 +119,7 @@ Update the existing wiki documentation for this repository.
107
119
 
108
120
  Inspect .wiki/, identify recent source changes or newly relevant evidence, and refresh only the documentation pages directly affected by those changes. Use the git evidence below when available. Keep edits surgical: do not rewrite accurate sections, do not update source maps or git evidence just to refresh them, and do not make formatting-only changes. If the wiki is already current, do not edit files.
109
121
 
110
- Make one focused discovery pass to identify what changed, then proceed to surgical edits. Do not loop on repeated exploration steps.
122
+ Make one focused discovery pass to identify what changed, then proceed to surgical edits. Do not loop on repeated exploration steps. Before writing any files, perform the staging PR staleness check described in the system prompt — if a newer open staging PR exists, abandon the update.
111
123
 
112
124
  Git change summary:
113
125
  ${gitSummary ?? "(not available)"}
package/dist/tools.js CHANGED
@@ -439,6 +439,74 @@ export function createTools(projectRoot) {
439
439
  }
440
440
  },
441
441
  };
442
+ const ghTool = {
443
+ definition: {
444
+ type: "function",
445
+ function: {
446
+ name: "gh",
447
+ description: "Run a read-only GitHub CLI (gh) subcommand in the project root. Use to inspect open pull requests, check wiki staging PR branches, and compare timestamps. Only read-only inspection subcommands are permitted — no mutating operations (create, edit, close, merge, delete, etc.).",
448
+ parameters: {
449
+ type: "object",
450
+ properties: {
451
+ args: {
452
+ type: "string",
453
+ description: "gh subcommand and arguments, without the leading 'gh'. Example: 'pr list --state open --head wiki/staging-* --json headRefName,updatedAt,number,title', 'pr view <number> --json updatedAt,headRefName,body', 'pr view <number> --json files'.",
454
+ },
455
+ },
456
+ required: ["args"],
457
+ },
458
+ },
459
+ },
460
+ handler: async (args) => {
461
+ const argString = args.args ?? "";
462
+ // Only read-only / inspection subcommands are permitted. The agent
463
+ // cannot mutate GitHub state through this tool.
464
+ const ALLOWED_GH_SUBCOMMANDS = {
465
+ pr: true, issue: true, repo: true, run: true, api: true,
466
+ "search": true, release: true, label: true, workflow: true,
467
+ };
468
+ // Mutating subcommand prefixes that must never run, even under an
469
+ // allowed top-level command (e.g. `gh pr create`, `gh pr merge`).
470
+ const BLOCKED_ACTIONS = {
471
+ create: true, edit: true, close: true, reopen: true, merge: true,
472
+ delete: true, ready: true, review: true, comment: true,
473
+ lock: true, unlock: true, assign: true, unassign: true,
474
+ label: true, unlabel: true, transfer: true, archive: true,
475
+ unarchive: true, deploy: true, rerun: true, cancel: true,
476
+ publish: true, set: true, add: true, remove: true,
477
+ };
478
+ const tokens = argString.trim().split(/\s+/);
479
+ const subcommand = tokens[0] ?? "";
480
+ if (!ALLOWED_GH_SUBCOMMANDS[subcommand]) {
481
+ return `Error: gh subcommand '${subcommand}' is not permitted. Only read-only inspection subcommands are allowed (pr, issue, repo, run, api, search, release, label, workflow).`;
482
+ }
483
+ // For `gh pr` and similar, check the action token (second token)
484
+ // against the blocklist. `gh pr list`, `gh pr view`, `gh pr diff`,
485
+ // `gh pr checks` are read-only and allowed.
486
+ const action = tokens[1] ?? "";
487
+ if (BLOCKED_ACTIONS[action]) {
488
+ return `Error: gh ${subcommand} ${action} is a mutating operation. Only read-only inspection is allowed (list, view, diff, checks, status).`;
489
+ }
490
+ // Reject shell metacharacters that could chain commands or inject
491
+ // flags, same guard as the git tool.
492
+ if (/[;&|`$()<>]/.test(argString)) {
493
+ return "Error: shell metacharacters are not permitted in gh arguments.";
494
+ }
495
+ try {
496
+ const { stdout, stderr } = await execAsync(`gh ${argString}`, {
497
+ cwd: projectRoot,
498
+ maxBuffer: 1024 * 1024,
499
+ timeout: 30_000,
500
+ });
501
+ const result = stdout + (stderr ? `\n${stderr}` : "");
502
+ return truncateResult(result || "(no output)");
503
+ }
504
+ catch (error) {
505
+ const message = error instanceof Error ? error.message : String(error);
506
+ return truncateResult(`Error: ${message}`);
507
+ }
508
+ },
509
+ };
442
510
  return [
443
511
  readFileTool,
444
512
  writeFileTool,
@@ -449,6 +517,7 @@ export function createTools(projectRoot) {
449
517
  gitTool,
450
518
  astGrepTool,
451
519
  astSearchTool,
520
+ ghTool,
452
521
  ];
453
522
  }
454
523
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chronova/wiki-agent",
3
- "version": "1.5.1",
3
+ "version": "1.6.1",
4
4
  "description": "Standalone Ollama-only documentation agent",
5
5
  "type": "module",
6
6
  "bin": {