@blogic-cz/agent-tools 1.6.12 → 1.6.14

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/README.md CHANGED
@@ -355,6 +355,8 @@ bun gh-tool pr checks-failed --pr 123 --with-logs --format json # includes diagn
355
355
  bun gh-tool pr rerun-checks --pr 123 --failed-only --watch --timeout 600
356
356
  bun gh-tool pr trigger-checks --pr 123 --workflow dotnet-pull-request.yml # only when zero checks reported
357
357
  bun gh-tool pr watch --prs 123,124 --format jsonl --timeout 600
358
+ bun gh-tool pr edit-comment --comment-id 456 --body-file correction.md # Edit your own review comment
359
+ bun gh-tool pr edit-comment --comment-id 789 --kind issue --pr 123 --body "Corrected detail"
358
360
  bun gh-tool pr reply-and-resolve --comment-id 456 --body "Done" # infers PR and thread
359
361
  bun gh-tool pr request-review --repo be --pr 123 --reviewers alice,bob
360
362
  bun gh-tool pr review --pr 123 --event comment --body "Notes, no verdict"
@@ -365,6 +367,10 @@ bun gh-tool pr review --pr 123 --event approve --confirm
365
367
  # Optional --pr/--thread-id retain legacy flow and are validated before either mutation.
366
368
  ```
367
369
 
370
+ `pr edit-comment` defaults to inline review comments; pass `--kind issue` for PR discussion
371
+ comments. It checks the authenticated GitHub user owns the comment before editing, and `--pr`
372
+ also verifies the comment belongs to that pull request.
373
+
368
374
  `pr review` creates and submits a review in one call, for a verdict reached from a diff with no pending review to submit. `pr submit-review` takes the same `--event` for a review that is already pending. `--event approve` and `--event request-changes` change whether the PR can merge, so both require `--confirm`, the same gate `pr merge` uses; `--event comment` carries no verdict and needs none. `--event comment` and `--event request-changes` require a non-empty body — GitHub rejects a bodyless one. GitHub also refuses a verdict on your own PR; that failure returns a hint pointing at `--event comment` instead of the raw API error.
369
375
 
370
376
  Reruns preflight every target before mutation and fail closed with `evidence_unavailable` when attempt jobs or logs cannot be read. Failed jobs use one `gh run rerun RUN --failed` mutation per workflow run. Without `--watch`, output returns current attempt metadata immediately; with `--watch`, discovery and watching share one absolute `--timeout` deadline and report `discovery_timeout` or `watch_timeout` with latest attempt state. Repeated matching pre-test infrastructure failures return `escalation_required` without mutation. See [`skills/gh-tool/SKILL.md`](skills/gh-tool/SKILL.md) for operating guidance; this section is canonical for added output fields.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credential-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAK5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAM/D,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAQF,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,CAAC;AAg4FF,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAErE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe,CAoWrF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UA9wGD,SAAS,UAAU,UAAU,KAAK,IA8wGM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YAhxGC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAgxGjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aAlxGE,MAAM,KAAK,OAkxGgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aApxGE,MAAM,KAAK,OAoxGgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YAtxGC,MAAM,KAAK,OAsxG0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YAxxGC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAwxGf,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YA1xGC,MAAM,KAAK,OA0xGsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YA5xGC,MAAM,KAAK,MAAM,GAAG,IA4xGa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/credential-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAmB,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAK5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAM/D,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,CAAC;AAQF,+CAA+C;AAC/C,MAAM,MAAM,eAAe,GAAG;IAC5B,uBAAuB,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3E,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,sBAAsB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjF,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,CAAC;AA66FF,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAErE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAED,2CAA2C;AAC3C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAEpE;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,qBAAqB,GAAG,eAAe,CA+XrF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UAt1GD,SAAS,UAAU,UAAU,KAAK,IAs1GM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YAx1GC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAw1GjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aA11GE,MAAM,KAAK,OA01GgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aA51GE,MAAM,KAAK,OA41GgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YA91GC,MAAM,KAAK,OA81G0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YAh2GC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAg2Gf,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YAl2GC,MAAM,KAAK,OAk2GsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YAp2GC,MAAM,KAAK,MAAM,GAAG,IAo2Ga,CAAC"}
@@ -328,6 +328,15 @@ export declare const prCommentCommand: Command.Command<"comment", {
328
328
  readonly pr: Option.Option<number>;
329
329
  readonly repo: Option.Option<string>;
330
330
  }, {}, import("#gh/service").GhError, GitHubService>;
331
+ export declare const prEditCommentCommand: Command.Command<"edit-comment", {
332
+ readonly body: Option.Option<string>;
333
+ readonly bodyFile: Option.Option<string>;
334
+ readonly commentId: number;
335
+ readonly format: "json" | "toon";
336
+ readonly kind: "issue" | "review";
337
+ readonly pr: Option.Option<number>;
338
+ readonly repo: Option.Option<string>;
339
+ }, {}, import("#gh/service").GhError, GitHubService>;
331
340
  export declare const prDiscussionSummaryCommand: Command.Command<"discussion-summary", {
332
341
  readonly format: "json" | "toon";
333
342
  readonly pr: Option.Option<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/commands.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export { prChecksCommand, prChecksFailedCommand, prCloseCommand, prCommentCommand, prCommentsCommand, prCreateCommand, prDiscussionSummaryCommand, prDraftCommand, prEditCommand, prFeedbackCommand, prIssueCommentsCommand, prIssueCommentsLatestCommand, prLastHumanReviewerCommand, prListCommand, prMergeCommand, prReadyCommand, prStackCommand, prRequestReviewCommand, prReplyCommand, prRerunChecksCommand, prReplyAndResolveCommand, prResolveCommand, prReviewCommand, prReviewsCommand, prStatusCommand, prSubmitReviewCommand, prThreadsCommand, prTriggerChecksCommand, prWaitMergeableCommand, prReviewTriageCommand, prReviewTriageBatchCommand, prViewCommand, prWatchCommand, } from "./commands";
1
+ export { prChecksCommand, prChecksFailedCommand, prCloseCommand, prCommentCommand, prEditCommentCommand, prCommentsCommand, prCreateCommand, prDiscussionSummaryCommand, prDraftCommand, prEditCommand, prFeedbackCommand, prIssueCommentsCommand, prIssueCommentsLatestCommand, prLastHumanReviewerCommand, prListCommand, prMergeCommand, prReadyCommand, prStackCommand, prRequestReviewCommand, prReplyCommand, prRerunChecksCommand, prReplyAndResolveCommand, prResolveCommand, prReviewCommand, prReviewsCommand, prStatusCommand, prSubmitReviewCommand, prThreadsCommand, prTriggerChecksCommand, prWaitMergeableCommand, prReviewTriageCommand, prReviewTriageBatchCommand, prViewCommand, prWatchCommand, } from "./commands";
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,4BAA4B,EAC5B,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,4BAA4B,EAC5B,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,wBAAwB,EACxB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,aAAa,EACb,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -48,6 +48,13 @@ export declare const fetchDiscussionSummary: (pr: number | null) => Effect.Effec
48
48
  unresolvedReviewThreadsCount: number;
49
49
  unresolvedUnrepliedReviewThreadsCount: number;
50
50
  }, import("#gh/service").GhError, GitHubService>;
51
+ export declare const editComment: (commentId: number, body: string, kind: "issue" | "review", pr: number | null) => Effect.Effect<{
52
+ commentId: number;
53
+ url: string;
54
+ updatedAt: string;
55
+ hint: string;
56
+ nextCommand: string;
57
+ }, import("#gh/service").GhError, GitHubService>;
51
58
  /**
52
59
  * Reply to an inline review comment via REST API.
53
60
  */
@@ -1 +1 @@
1
- {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/review.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAEV,YAAY,EAGZ,iBAAiB,EACjB,aAAa,EACb,YAAY,EAEb,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAye5C;;;GAGG;AACH,eAAO,MAAM,YAAY,gMAcvB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa,uKAoCxB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,8KAmC7B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY,+NA+CvB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;gDAaxB,CAAC;AAEH,eAAO,MAAM,uBAAuB,6JAgBlC,CAAC;AAEH,eAAO,MAAM,gBAAgB,gHA0C3B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;gDA4CjC,CAAC;AAeH;;GAEG;AACH,eAAO,MAAM,cAAc;;;gDA4FzB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;gDA0FjC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa;;;gDAWxB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAgCzD;;;GAGG;AACH,eAAO,MAAM,YAAY;QACnB,MAAM,GAAG,IAAI;WACV,WAAW;UACZ,MAAM;aACH,OAAO;;;;;;;gDAmDhB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;gDAyM9B,CAAC;AAeH,eAAO,MAAM,sBAAsB;;;;gDA8CjC,CAAC"}
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/review.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAEV,YAAY,EAGZ,iBAAiB,EACjB,aAAa,EACb,YAAY,EAEb,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAkf5C;;;GAGG;AACH,eAAO,MAAM,YAAY,gMAcvB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,aAAa,uKAoCxB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,8KAmC7B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY,+NA+CvB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;gDAaxB,CAAC;AAEH,eAAO,MAAM,uBAAuB,6JAgBlC,CAAC;AAEH,eAAO,MAAM,gBAAgB,gHA0C3B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;gDA4CjC,CAAC;AAeH,eAAO,MAAM,WAAW;;;;;;gDAmGtB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc;;;gDA4FzB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;gDA0FjC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa;;;gDAWxB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAgCzD;;;GAGG;AACH,eAAO,MAAM,YAAY;QACnB,MAAM,GAAG,IAAI;WACV,WAAW;UACZ,MAAM;aACH,OAAO;;;;;;;gDAmDhB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;gDAyM9B,CAAC;AAeH,eAAO,MAAM,sBAAsB;;;;gDA8CjC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blogic-cz/agent-tools",
3
- "version": "1.6.12",
3
+ "version": "1.6.14",
4
4
  "description": "CLI tools for AI coding agent workflows — GitHub, database, Kubernetes, Azure platform, Azure DevOps, logs, sessions, and audit",
5
5
  "keywords": [
6
6
  "agent",
@@ -422,6 +422,7 @@ function literalBindingText(
422
422
  command: string,
423
423
  name: string,
424
424
  value: string,
425
+ allowBrackets = false,
425
426
  ): { text: string; syntax: string } | undefined {
426
427
  let text = "";
427
428
  let syntax = "";
@@ -453,7 +454,11 @@ function literalBindingText(
453
454
  syntax += quote ? " ".repeat(value.length) : value;
454
455
  i += match[0].length - 1;
455
456
  } else {
456
- if (char === "`" || (!quote && /[(){}*?[\]#]/.test(char))) return undefined;
457
+ if (
458
+ char === "`" ||
459
+ (!quote && (/[(){}*?#]/.test(char) || (!allowBrackets && (char === "[" || char === "]"))))
460
+ )
461
+ return undefined;
457
462
  text += char;
458
463
  syntax += quote ? " " : char;
459
464
  }
@@ -608,24 +613,45 @@ function literalShellBodies(command: string): string[] | undefined {
608
613
  return bodies;
609
614
  }
610
615
 
611
- function isProvedLiteralShellBody(body: string): boolean {
616
+ function isProvedLiteralShellBody(
617
+ body: string,
618
+ allowedNames: Set<string>,
619
+ isPathBlocked: (path: string) => boolean,
620
+ onProvedPredicate: () => void,
621
+ ): boolean {
612
622
  if (!body.trim()) return true;
613
623
  const materialized = materializeLiteralShell(body)?.command ?? body;
614
624
  const parsed = parseStaticShellCommands(materialized);
615
- if (!parsed || typeof parsed === "string" || !hasProvedNavigationSequence(materialized))
616
- return false;
625
+ if (!parsed || typeof parsed === "string") {
626
+ let proved = false;
627
+ if (
628
+ hasEnvironmentVariableExpansionRead(body, allowedNames, isPathBlocked, undefined, () => {
629
+ proved = true;
630
+ }) ||
631
+ !proved
632
+ )
633
+ return false;
634
+ onProvedPredicate();
635
+ return true;
636
+ }
637
+ if (!hasProvedNavigationSequence(materialized)) return false;
617
638
  if (isStaticHerdrPrompt(materialized)) return true;
618
639
  return parsed.pipelines.flat().every((words) => {
619
640
  const argv = unwrapProofCommand(words, "\0");
620
641
  if (!argv) return false;
621
642
  if (argv[0]?.split("/").at(-1) === "env") return false;
622
643
  const name = unwrapStaticCommand(argv)[0]?.split("/").at(-1) ?? "";
623
- if (isShellWord(name))
644
+ if (isShellWord(name)) {
645
+ const nested = literalShellBodies(
646
+ words.map((word) => "'" + word.replaceAll("'", "'\"'\"'") + "'").join(" "),
647
+ );
624
648
  return (
625
- literalShellBodies(
626
- words.map((word) => "'" + word.replaceAll("'", "'\"'\"'") + "'").join(" "),
627
- ) !== undefined
649
+ nested !== undefined &&
650
+ nested.every((inner) =>
651
+ isProvedLiteralShellBody(inner, allowedNames, isPathBlocked, onProvedPredicate),
652
+ )
628
653
  );
654
+ }
629
655
  return (
630
656
  isProvedCwdSubprocessRole(unwrapStaticCommand(argv)) ||
631
657
  (name === "bun" && isSafeLocalAssignmentCommand(argv) && !isUnsupportedInlineRuntime(argv)) ||
@@ -2535,7 +2561,9 @@ function hasEnvironmentVariableExpansionRead(
2535
2561
  allowedNames: Set<string>,
2536
2562
  isPathBlocked: (path: string) => boolean,
2537
2563
  onProvedStatus?: (command: string) => void,
2564
+ onProvedPredicate?: () => void,
2538
2565
  ): boolean {
2566
+ const originalCommand = command;
2539
2567
  let heredoc = boundedHeredoc(command);
2540
2568
  while (heredoc) {
2541
2569
  // In an unquoted heredoc, # and quote characters are data, not shell syntax.
@@ -2544,6 +2572,7 @@ function hasEnvironmentVariableExpansionRead(
2544
2572
  heredoc = boundedHeredoc(command);
2545
2573
  }
2546
2574
  if (!command.includes("$") && !command.includes("`")) return false;
2575
+ let predicateSyntaxIntact = command === originalCommand;
2547
2576
  let invalidExpansion = false;
2548
2577
  const assignments = getLeadingLiteralAssignments(command);
2549
2578
  let localIndex = 0;
@@ -2562,6 +2591,7 @@ function hasEnvironmentVariableExpansionRead(
2562
2591
  for (let i = 0; i < command.length; i++) {
2563
2592
  const char = command[i] ?? "";
2564
2593
  if (!quote && char === "#" && !wordStarted) {
2594
+ predicateSyntaxIntact = false;
2565
2595
  while (i + 1 < command.length && command[i + 1] !== "\n") i++;
2566
2596
  continue;
2567
2597
  }
@@ -2810,6 +2840,21 @@ function hasEnvironmentVariableExpansionRead(
2810
2840
  const materialized = normalized.replaceAll("ENVVALUE", "SAFEENVVALUE");
2811
2841
  const blocked = hasSensitiveFileRead(materialized, isPathBlocked);
2812
2842
  if (!blocked && statusCaptures.size) onProvedStatus?.(materialized);
2843
+ // This is a complete command proof, not merely a recursively safe shell body.
2844
+ if (
2845
+ !blocked &&
2846
+ parsed.pipelines.length === 1 &&
2847
+ parsed.pipelines[0]?.length === 1 &&
2848
+ !parsed.redirects.length
2849
+ ) {
2850
+ const argv = unwrapProofCommand(parsed.pipelines[0]?.[0] ?? [], "ENVVALUE");
2851
+ if (argv && isApprovedEnvironmentPredicate(argv) && predicateSyntaxIntact) {
2852
+ // Roles alone cannot prove original shell boundaries or discarded controls.
2853
+ // Brackets are enabled only for the completely proved bracket builtin.
2854
+ const binding = literalBindingText(normalized, "", "", argv[0] === "[");
2855
+ if (binding && !/[;&|<>\r\n]/.test(binding.syntax.trim())) onProvedPredicate?.();
2856
+ }
2857
+ }
2813
2858
  return blocked;
2814
2859
  }
2815
2860
 
@@ -3120,11 +3165,37 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
3120
3165
  const shellBodies = literalShellBodies(command);
3121
3166
  if (!shellBodies || (shellBodies.length && shellDepth >= 8))
3122
3167
  return "cannot prove a bounded literal shell invocation";
3168
+ const provedPredicateShellBodies: string[] = [];
3123
3169
  for (const body of shellBodies) {
3124
3170
  const reason = getDangerousBashReason(body, shellDepth + 1);
3125
3171
  if (reason || getBlockedCliTool(body, true, shellDepth + 1))
3126
3172
  return reason ?? "invokes a blocked CLI from a shell body";
3127
- if (!isProvedLiteralShellBody(body)) return "cannot prove a closed literal shell body";
3173
+ if (
3174
+ !isProvedLiteralShellBody(body, allowedEnvironmentVariables, isPathBlocked, () => {
3175
+ provedPredicateShellBodies.push(body);
3176
+ })
3177
+ )
3178
+ return "cannot prove a closed literal shell body";
3179
+ }
3180
+ if (provedPredicateShellBodies.length) {
3181
+ const context = parseStaticShellCommands(command);
3182
+ const binding = literalBindingText(command, "", "");
3183
+ const argv =
3184
+ context && typeof context !== "string"
3185
+ ? unwrapProofCommand(context.pipelines[0]?.[0] ?? [], "\0")
3186
+ : undefined;
3187
+ if (
3188
+ !context ||
3189
+ typeof context === "string" ||
3190
+ context.pipelines.length !== 1 ||
3191
+ context.pipelines[0]?.length !== 1 ||
3192
+ context.redirects.length !== 0 ||
3193
+ !binding ||
3194
+ /[;&|<>\r\n]/.test(binding.syntax.trim()) ||
3195
+ !argv ||
3196
+ !SHELL_IDENTITIES.has(argv[0] ?? "")
3197
+ )
3198
+ return "cannot prove a single literal shell predicate invocation";
3128
3199
  }
3129
3200
  const proof = materializeLiteralShell(command);
3130
3201
  if (!proof && /^\s*for\b/.test(command)) return "cannot prove a bounded literal shell loop";
@@ -3169,6 +3240,7 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
3169
3240
  allowedEnvironmentVariables,
3170
3241
  allowPackageInventory,
3171
3242
  shellBodies.filter((body) => {
3243
+ if (provedPredicateShellBodies.includes(body)) return true;
3172
3244
  const parsed = parseStaticShellCommands(body);
3173
3245
  return (
3174
3246
  parsed &&
@@ -36,6 +36,7 @@ import {
36
36
  prIssueCommentsCommand,
37
37
  prIssueCommentsLatestCommand,
38
38
  prCommentCommand,
39
+ prEditCommentCommand,
39
40
  prDiscussionSummaryCommand,
40
41
  prFeedbackCommand,
41
42
  prReplyCommand,
@@ -108,6 +109,7 @@ const prCommand = Command.make("pr", {}).pipe(
108
109
  prIssueCommentsCommand,
109
110
  prIssueCommentsLatestCommand,
110
111
  prCommentCommand,
112
+ prEditCommentCommand,
111
113
  prDiscussionSummaryCommand,
112
114
  prReplyCommand,
113
115
  prResolveCommand,
@@ -206,7 +208,7 @@ WORKFLOW FOR AI AGENTS:
206
208
  1. Use 'pr view' to inspect current PR
207
209
  2. Use 'pr discussion-summary' for overview (counts + latest discussion comment)
208
210
  3. Use 'pr threads' and 'pr issue-comments-latest --author <username> --body-contains "Review"' for review context
209
- 4. Use 'pr reply', 'pr comment' and 'pr resolve' to handle feedback
211
+ 4. Use 'pr reply', 'pr comment', 'pr edit-comment' and 'pr resolve' to handle feedback
210
212
  4b. Use 'pr review --event request-changes|approve|comment --confirm' to post a verdict, or 'pr submit-review' for a pending one
211
213
  5. Use 'pr checks' to monitor CI status; 'pr trigger-checks --workflow <file.yml>' when zero checks were reported
212
214
  6. Use 'pr merge' to merge (dry-run by default)
@@ -52,6 +52,7 @@ import {
52
52
  } from "./core";
53
53
  import {
54
54
  createReview,
55
+ editComment,
55
56
  fetchComments,
56
57
  fetchDiscussionSummary,
57
58
  fetchFeedback,
@@ -1306,6 +1307,47 @@ export const prCommentCommand = Command.make(
1306
1307
  ),
1307
1308
  ).pipe(Command.withDescription("Post a general PR discussion comment"));
1308
1309
 
1310
+ export const prEditCommentCommand = Command.make(
1311
+ "edit-comment",
1312
+ {
1313
+ body: Flag.String("body").pipe(
1314
+ Flag.withDescription("Updated comment body text"),
1315
+ Flag.optional,
1316
+ ),
1317
+ bodyFile: Flag.String("body-file").pipe(
1318
+ Flag.withDescription("Read updated comment body from a file path or '-' for stdin"),
1319
+ Flag.optional,
1320
+ ),
1321
+ commentId: Flag.Int("comment-id").pipe(Flag.withDescription("ID of the comment to edit")),
1322
+ format: formatOption,
1323
+ kind: Flag.Literals("kind", ["review", "issue"]).pipe(
1324
+ Flag.withDescription("Comment type: inline review comment or PR discussion comment"),
1325
+ Flag.withDefault("review"),
1326
+ ),
1327
+ pr: Flag.Int("pr").pipe(
1328
+ Flag.withDescription("Require the comment to belong to this PR"),
1329
+ Flag.optional,
1330
+ ),
1331
+ repo: repoOption,
1332
+ },
1333
+ ({ body, bodyFile, commentId, format, kind, pr, repo }) =>
1334
+ withRepo(
1335
+ repo,
1336
+ Effect.gen(function* () {
1337
+ const resolvedBody = yield* resolveRequiredTextInput({
1338
+ command: "gh-tool pr edit-comment",
1339
+ value: Option.getOrNull(body),
1340
+ fileValue: Option.getOrNull(bodyFile),
1341
+ valueFlag: "--body",
1342
+ fileFlag: "--body-file",
1343
+ label: "body",
1344
+ });
1345
+ const result = yield* editComment(commentId, resolvedBody, kind, Option.getOrNull(pr));
1346
+ yield* logFormatted(result, format);
1347
+ }),
1348
+ ),
1349
+ ).pipe(Command.withDescription("Edit your own inline review or PR discussion comment"));
1350
+
1309
1351
  export const prDiscussionSummaryCommand = Command.make(
1310
1352
  "discussion-summary",
1311
1353
  {
@@ -3,6 +3,7 @@ export {
3
3
  prChecksFailedCommand,
4
4
  prCloseCommand,
5
5
  prCommentCommand,
6
+ prEditCommentCommand,
6
7
  prCommentsCommand,
7
8
  prCreateCommand,
8
9
  prDiscussionSummaryCommand,
@@ -299,6 +299,15 @@ type ReviewCommentById = {
299
299
  pull_request_url: string;
300
300
  };
301
301
 
302
+ type EditableComment = {
303
+ id: number;
304
+ user: { login: string };
305
+ html_url: string;
306
+ updated_at: string;
307
+ pull_request_url?: string;
308
+ issue_url?: string;
309
+ };
310
+
302
311
  const REST_PAGE_SIZE = 100;
303
312
 
304
313
  const feedbackOrigin = (commitSha: string | null, currentHeadSha: string | null): FeedbackOrigin =>
@@ -801,6 +810,107 @@ const fetchReviewCommentById = Effect.fn("pr.fetchReviewCommentById")(function*
801
810
  return comment;
802
811
  });
803
812
 
813
+ export const editComment = Effect.fn("pr.editComment")(function* (
814
+ commentId: number,
815
+ body: string,
816
+ kind: "review" | "issue",
817
+ pr: number | null,
818
+ ) {
819
+ const service = yield* GitHubService;
820
+ const repoInfo = yield* service.getRepoInfo();
821
+ const command = "gh-tool pr edit-comment";
822
+ if (
823
+ !Number.isInteger(commentId) ||
824
+ commentId <= 0 ||
825
+ (pr !== null && (!Number.isInteger(pr) || pr <= 0))
826
+ ) {
827
+ return yield* Effect.fail(
828
+ new GitHubCommandError({
829
+ command,
830
+ exitCode: 1,
831
+ stderr: "--comment-id and --pr must be positive integers",
832
+ message: "--comment-id and --pr must be positive integers",
833
+ hint: "Pass a positive comment ID and, when supplied, a positive PR number.",
834
+ }),
835
+ );
836
+ }
837
+ if (body.trim().length === 0) {
838
+ return yield* Effect.fail(
839
+ new GitHubCommandError({
840
+ command,
841
+ exitCode: 1,
842
+ stderr: "Comment body cannot be empty",
843
+ message: "Comment body cannot be empty",
844
+ hint: "Pass non-empty comment text with --body or --body-file.",
845
+ }),
846
+ );
847
+ }
848
+
849
+ const endpoint = `repos/${repoInfo.owner}/${repoInfo.name}/${kind === "review" ? "pulls" : "issues"}/comments/${commentId}`;
850
+ const target = yield* service.runGhJson<EditableComment>(["api", endpoint]);
851
+ const viewer = yield* service.runGhJson<{ login: string }>(["api", "user"]);
852
+ if (target.user.login.toLowerCase() !== viewer.login.toLowerCase()) {
853
+ return yield* Effect.fail(
854
+ new GitHubCommandError({
855
+ command,
856
+ exitCode: 1,
857
+ stderr: `Comment ${commentId} was written by ${target.user.login}; only your own comments can be edited`,
858
+ message: `Comment ${commentId} was written by ${target.user.login}; only your own comments can be edited`,
859
+ hint: "Edit only comments authored by the authenticated GitHub user.",
860
+ }),
861
+ );
862
+ }
863
+
864
+ const commentPrUrl = kind === "review" ? target.pull_request_url : target.issue_url;
865
+ if (pr !== null && !commentPrUrl?.endsWith(`/${kind === "review" ? "pulls" : "issues"}/${pr}`)) {
866
+ return yield* Effect.fail(
867
+ new GitHubCommandError({
868
+ command,
869
+ exitCode: 1,
870
+ stderr: `Comment ${commentId} does not belong to PR #${pr}`,
871
+ message: `Comment ${commentId} does not belong to PR #${pr}`,
872
+ hint: "Pass the PR that owns this comment, or omit --pr to edit by comment ID.",
873
+ }),
874
+ );
875
+ }
876
+ if (kind === "issue" && pr !== null) {
877
+ const pullRequest = yield* service.runGhJson<{ number: number }>([
878
+ "api",
879
+ `repos/${repoInfo.owner}/${repoInfo.name}/pulls/${pr}`,
880
+ ]);
881
+ if (pullRequest.number !== pr) {
882
+ return yield* Effect.fail(
883
+ new GitHubCommandError({
884
+ command,
885
+ exitCode: 1,
886
+ stderr: `Comment ${commentId} does not belong to PR #${pr}`,
887
+ message: `Comment ${commentId} does not belong to PR #${pr}`,
888
+ hint: "Pass the PR that owns this comment, or omit --pr to edit by comment ID.",
889
+ }),
890
+ );
891
+ }
892
+ }
893
+
894
+ const updated = yield* service.runGhJson<EditableComment>([
895
+ "api",
896
+ "-X",
897
+ "PATCH",
898
+ endpoint,
899
+ "-f",
900
+ `body=${body}`,
901
+ ]);
902
+ return {
903
+ commentId: updated.id,
904
+ url: updated.html_url,
905
+ updatedAt: updated.updated_at,
906
+ hint: "The comment was updated.",
907
+ nextCommand:
908
+ kind === "review"
909
+ ? "gh-tool pr comments --pr <number>"
910
+ : "gh-tool pr issue-comments --pr <number>",
911
+ };
912
+ });
913
+
804
914
  /**
805
915
  * Reply to an inline review comment via REST API.
806
916
  */