@blogic-cz/agent-tools 1.5.11 → 1.6.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/README.md +4 -0
- package/dist/credential-guard/index.d.ts.map +1 -1
- package/dist/gh-tool/pr/commands.d.ts +5 -0
- package/dist/gh-tool/pr/commands.d.ts.map +1 -1
- package/dist/gh-tool/pr/core.d.ts +23 -0
- package/dist/gh-tool/pr/core.d.ts.map +1 -1
- package/dist/gh-tool/pr/index.d.ts +1 -1
- package/dist/gh-tool/pr/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/credential-guard/index.ts +196 -7
- package/src/gh-tool/main.ts +2 -0
- package/src/gh-tool/pr/commands.ts +21 -0
- package/src/gh-tool/pr/core.ts +15 -0
- package/src/gh-tool/pr/index.ts +1 -0
package/README.md
CHANGED
|
@@ -648,6 +648,8 @@ That's it. The hook reads tool input from stdin, runs the guard, and exits with
|
|
|
648
648
|
|
|
649
649
|
The guard permits static `printenv` reads and simple `echo`/`printf` expansions only for exact names in `credentialGuard.allowedEnvironmentVariables`. The default list is empty. Multiple names are allowed only when each name is approved. Approved environment values may be displayed, but redirecting their pipeline or passing them to an executor stays blocked.
|
|
650
650
|
|
|
651
|
+
Python inline programs and quoted stdin heredocs can also display approved values through `os.getenv("NAME")`, `os.environ.get("NAME", "default")`, or `os.environ["NAME"]`. The complete program must be `import os` followed by `print(...)` statements using these reads and plain string labels or defaults. Dynamic names, aliases, escaped or interpolated strings, additional statements, and whole-environment output remain unsupported. The same redirection and pipeline restrictions apply.
|
|
652
|
+
|
|
651
653
|
Literal assignments such as `F=README.md; cat "$F"` work in supported static commands. Bounded proofs also support a literal `for` loop over a fixed list, the adjacent `cd PATH && T=LITERAL && git add -- "$T/file"` form, and `rg -n PATTERN src/{a,b}` with a single literal path-brace component. Loop binders are a single lowercase letter or `T`, and their uses must occupy supported data operands. Every body command and expanded path is checked; unsupported control flow, mutations such as `printf -v`, and unknown command roles cannot establish the proof. Other variable assignments and brace expansions retain conservative refusal. Fully quoted literal braces remain usable in static searches.
|
|
652
654
|
|
|
653
655
|
Ordinary navigation operands such as `cd "$HOME"` and `git -C "$WORKTREE_ROOT" status --short` do not need display permission. This does not authorize printing those values, using them as code/options, or reading unknown file paths. In `printf`, approved values belong in data arguments after a fixed nonmutating format, for example `printf -- '%s' "$WORKSPACE_LABEL"`.
|
|
@@ -656,6 +658,8 @@ The guard recognizes `rtk`, `rtk proxy`, `command`, and supported `env` prefixes
|
|
|
656
658
|
|
|
657
659
|
Paths are checked against sensitive filename patterns and configured path rules. Supported proofs apply those checks to their expanded operands. Ordinary parent-directory and absolute paths may be allowed; the guard does not resolve filesystem paths or symlinks, or enforce repository confinement.
|
|
658
660
|
|
|
661
|
+
Recognized Linux process-environment paths such as `/proc/self/environ`, `/proc/thread-self/environ`, and PID/task variants are blocked before configured path exceptions.
|
|
662
|
+
|
|
659
663
|
Single literal `echo`/`printf` writes with output redirection and single `cat`/`tee` heredoc writes are allowed. Heredoc braces are data. Use a quoted delimiter for literal code; unquoted heredocs containing `$`, backticks, or backslashes do not receive the literal-write exception. The exception permits only supported combinations with navigation or selected inspections; unsupported following commands remain outside it. Supported complete Python stdin heredocs are checked as inline programs, with the normal runtime-argument, path, execution, and environment checks.
|
|
660
664
|
|
|
661
665
|
Python JSON parsing, dictionary iteration, and printing are not themselves evidence of credential access. They follow the same access and execution rules as other supported inline programs. This intentionally permits ordinary JSON output that older versions refused. Unknown secrets in ordinary files can therefore reach arbitrary shell output; wrapper content checks do not protect that output. A refusal caused by unsupported syntax means the guard could not establish its policy conditions, not that it observed a secret being read.
|
|
@@ -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;
|
|
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;AAimEF,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,CA4TrF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UAv8ED,SAAS,UAAU,UAAU,KAAK,IAu8EM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YAz8EC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAy8EjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aA38EE,MAAM,KAAK,OA28EgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aA78EE,MAAM,KAAK,OA68EgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YA/8EC,MAAM,KAAK,OA+8E0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YAj9EC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAi9Ef,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YAn9EC,MAAM,KAAK,OAm9EsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YAr9EC,MAAM,KAAK,MAAM,GAAG,IAq9Ea,CAAC"}
|
|
@@ -228,6 +228,11 @@ export declare const prReadyCommand: Command.Command<"ready", {
|
|
|
228
228
|
readonly pr: Option.Option<number>;
|
|
229
229
|
readonly repo: Option.Option<string>;
|
|
230
230
|
}, {}, import("#gh/service").GhError, GitHubService>;
|
|
231
|
+
export declare const prDraftCommand: Command.Command<"draft", {
|
|
232
|
+
readonly format: "json" | "toon";
|
|
233
|
+
readonly pr: Option.Option<number>;
|
|
234
|
+
readonly repo: Option.Option<string>;
|
|
235
|
+
}, {}, import("#gh/service").GhError, GitHubService>;
|
|
231
236
|
export declare const prChecksCommand: Command.Command<"checks", {
|
|
232
237
|
readonly failFast: boolean;
|
|
233
238
|
readonly format: "json" | "toon";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAW,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,WAAW,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -149,6 +149,29 @@ export declare const readyPR: (opts: {
|
|
|
149
149
|
baseSha: string | null;
|
|
150
150
|
wasAlreadyReady: boolean;
|
|
151
151
|
}, import("#gh/service").GhError, GitHubService>;
|
|
152
|
+
export declare const draftPR: (opts: {
|
|
153
|
+
pr: number | null;
|
|
154
|
+
}) => Effect.Effect<{
|
|
155
|
+
number: number;
|
|
156
|
+
url: string;
|
|
157
|
+
title: string;
|
|
158
|
+
headRefName: string;
|
|
159
|
+
baseRefName: string;
|
|
160
|
+
state: string;
|
|
161
|
+
isDraft: boolean;
|
|
162
|
+
mergeable: "MERGEABLE" | "CONFLICTING" | "UNKNOWN";
|
|
163
|
+
body: string;
|
|
164
|
+
author: {
|
|
165
|
+
login: string;
|
|
166
|
+
is_bot: boolean;
|
|
167
|
+
};
|
|
168
|
+
reviewDecision: "APPROVED" | "CHANGES_REQUESTED" | "REVIEW_REQUIRED" | "";
|
|
169
|
+
reviewRequests: import("#gh/types").ReviewRequest[];
|
|
170
|
+
headRefOid?: string;
|
|
171
|
+
headSha: string | null;
|
|
172
|
+
baseSha: string | null;
|
|
173
|
+
wasAlreadyDraft: boolean;
|
|
174
|
+
}, import("#gh/service").GhError, GitHubService>;
|
|
152
175
|
export declare const editPR: (opts: {
|
|
153
176
|
pr: number;
|
|
154
177
|
title: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAE1E,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,iBAAiB,EAEjB,WAAW,EACX,aAAa,EACb,MAAM,EAGN,iBAAiB,EAIlB,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA4O5C,eAAO,MAAM,qBAAqB,QAAwB,CAAC;AAS3D,eAAO,MAAM,iBAAiB,gIAiB5B,CAAC;AA8IH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;iBAYuC,MAAM;;;gDAMnE,CAAC;AAEH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;iBAR4C,MAAM;;;gDAuBnE,CAAC;AAEH,eAAO,MAAM,cAAc;UAiBf,MAAM;cACI,cAAc,EAAE;;;;;UAkI1B,QAAQ;QACK,MAAM;;;;;UAKrB,UAAU;;kGAGlB,CAAC;AAEH,eAAO,MAAM,OAAO;WACX,MAAM;WACN,MAAM;YACL,MAAM,GAAG,IAAI;UACf,MAAM,GAAG,IAAI;UACb,MAAM,GAAG,IAAI;YACX,MAAM,GAAG,IAAI;2EAkBrB,CAAC;AAMH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;iBAtNkC,MAAM;;;gDAqPnE,CAAC;AAEH,eAAO,MAAM,QAAQ;UACb,MAAM,GAAG,IAAI;WACZ,MAAM;UACP,MAAM;WACL,OAAO;UACR,MAAM,GAAG,IAAI;yEA8FnB,CAAC;AAkFH,eAAO,MAAM,OAAO;QACd,MAAM;cACA,aAAa;kBACT,OAAO;aACZ,OAAO;iGAyThB,CAAC;AAEH,eAAO,MAAM,OAAO;QACd,MAAM;aACD,MAAM,GAAG,IAAI;kBACR,OAAO;;;;;;;;;;;;;;;;;iBA9uBwC,MAAM;;;gDA+vBnE,CAAC;AAEH,eAAO,MAAM,OAAO;QAAkD,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;iBAjwBpB,MAAM;;;;gDAgxBnE,CAAC;AAEH,eAAO,MAAM,MAAM;QACb,MAAM;WACH,MAAM,GAAG,IAAI;UACd,MAAM,GAAG,IAAI;UACb,MAAM,GAAG,IAAI;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/gh-tool/pr/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { prChecksCommand, prChecksFailedCommand, prCloseCommand, prCommentCommand, prCommentsCommand, prCreateCommand, prDiscussionSummaryCommand, 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, 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,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,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"}
|
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import type { CliToolOverride, CredentialGuardConfig } from "#config/types";
|
|
18
18
|
import { redactSensitiveText } from "#shared/content-security";
|
|
19
19
|
import { SECRET_PATTERNS } from "#shared/credential-patterns";
|
|
20
|
+
import { posix } from "node:path";
|
|
20
21
|
|
|
21
22
|
export { findSecretMatches } from "#shared/credential-patterns";
|
|
22
23
|
export { redactSensitiveText } from "#shared/content-security";
|
|
@@ -89,6 +90,9 @@ const DEFAULT_ALLOWED_PATH_PATTERNS: RegExp[] = [
|
|
|
89
90
|
/\.env\.sample$/,
|
|
90
91
|
];
|
|
91
92
|
|
|
93
|
+
const PROCESS_ENVIRONMENT_PATH =
|
|
94
|
+
/^(?:\/|(?:\.\.\/)*)proc\/(?:self|thread-self|[0-9]+|\$\$|\$\{\$\})(?:\/task\/(?:[0-9]+|\$\$|\$\{\$\}))?\/environ$/;
|
|
95
|
+
|
|
92
96
|
/**
|
|
93
97
|
* CLI tools that must use wrapper tools for security and audit.
|
|
94
98
|
*/
|
|
@@ -1263,12 +1267,144 @@ function unwrapStaticCommand(words: string[]): string[] {
|
|
|
1263
1267
|
}
|
|
1264
1268
|
|
|
1265
1269
|
function isAllowedEnvironmentRead(argv: string[], allowedNames: Set<string>): boolean {
|
|
1270
|
+
if (isAllowedPythonEnvironmentRead(argv, allowedNames)) return true;
|
|
1266
1271
|
if (argv[0]?.split("/").at(-1) !== "printenv") return false;
|
|
1267
1272
|
const args = argv.slice(1);
|
|
1268
1273
|
if (args[0] === "--") args.shift();
|
|
1269
1274
|
return args.length > 0 && args.every((name) => allowedNames.has(name));
|
|
1270
1275
|
}
|
|
1271
1276
|
|
|
1277
|
+
/** Prove the complete, print-only Python program before treating its reads as approved. */
|
|
1278
|
+
function isAllowedPythonEnvironmentRead(argv: string[], allowedNames: Set<string>): boolean {
|
|
1279
|
+
const index = inlineProgramIndex(argv);
|
|
1280
|
+
if (inlineRuntimeKind(argv[0]) !== "python" || index === undefined || argv.length !== index + 1)
|
|
1281
|
+
return false;
|
|
1282
|
+
|
|
1283
|
+
const program = argv[index] ?? "";
|
|
1284
|
+
let position = 0;
|
|
1285
|
+
let foundRead = false;
|
|
1286
|
+
const skipInlineWhitespace = () => {
|
|
1287
|
+
while (/[\t ]/.test(program[position] ?? "")) position++;
|
|
1288
|
+
};
|
|
1289
|
+
const take = (value: string): boolean => {
|
|
1290
|
+
if (!program.startsWith(value, position)) return false;
|
|
1291
|
+
position += value.length;
|
|
1292
|
+
return true;
|
|
1293
|
+
};
|
|
1294
|
+
const takeIdentifier = (value: string): boolean => {
|
|
1295
|
+
if (!take(value) || /[A-Za-z0-9_]/.test(program[position] ?? "")) return false;
|
|
1296
|
+
return true;
|
|
1297
|
+
};
|
|
1298
|
+
const takeString = (): string | undefined => {
|
|
1299
|
+
skipInlineWhitespace();
|
|
1300
|
+
const quote = program[position];
|
|
1301
|
+
if ((quote !== "'" && quote !== '"') || program.startsWith(quote.repeat(3), position))
|
|
1302
|
+
return undefined;
|
|
1303
|
+
position++;
|
|
1304
|
+
const start = position;
|
|
1305
|
+
while (position < program.length && program[position] !== quote) {
|
|
1306
|
+
if (/[\\\r\n]/.test(program[position] ?? "")) return undefined;
|
|
1307
|
+
position++;
|
|
1308
|
+
}
|
|
1309
|
+
if (program[position] !== quote) return undefined;
|
|
1310
|
+
const value = program.slice(start, position);
|
|
1311
|
+
position++;
|
|
1312
|
+
return value;
|
|
1313
|
+
};
|
|
1314
|
+
const takeEnvironmentRead = (): boolean => {
|
|
1315
|
+
skipInlineWhitespace();
|
|
1316
|
+
const start = position;
|
|
1317
|
+
if (!takeIdentifier("os")) return false;
|
|
1318
|
+
if (!take(".")) {
|
|
1319
|
+
position = start;
|
|
1320
|
+
return false;
|
|
1321
|
+
}
|
|
1322
|
+
if (takeIdentifier("getenv")) {
|
|
1323
|
+
if (!take("(")) return false;
|
|
1324
|
+
const name = takeString();
|
|
1325
|
+
if (name === undefined || !allowedNames.has(name)) return false;
|
|
1326
|
+
skipInlineWhitespace();
|
|
1327
|
+
if (take(",")) {
|
|
1328
|
+
if (takeString() === undefined) return false;
|
|
1329
|
+
skipInlineWhitespace();
|
|
1330
|
+
}
|
|
1331
|
+
if (!take(")")) return false;
|
|
1332
|
+
foundRead = true;
|
|
1333
|
+
return true;
|
|
1334
|
+
}
|
|
1335
|
+
if (!takeIdentifier("environ")) return false;
|
|
1336
|
+
if (take(".")) {
|
|
1337
|
+
if (!takeIdentifier("get") || !take("(")) return false;
|
|
1338
|
+
const name = takeString();
|
|
1339
|
+
if (name === undefined || !allowedNames.has(name)) return false;
|
|
1340
|
+
skipInlineWhitespace();
|
|
1341
|
+
if (take(",")) {
|
|
1342
|
+
if (takeString() === undefined) return false;
|
|
1343
|
+
skipInlineWhitespace();
|
|
1344
|
+
}
|
|
1345
|
+
if (!take(")")) return false;
|
|
1346
|
+
foundRead = true;
|
|
1347
|
+
return true;
|
|
1348
|
+
}
|
|
1349
|
+
if (!take("[")) return false;
|
|
1350
|
+
const name = takeString();
|
|
1351
|
+
if (name === undefined || !allowedNames.has(name)) return false;
|
|
1352
|
+
skipInlineWhitespace();
|
|
1353
|
+
if (!take("]")) return false;
|
|
1354
|
+
foundRead = true;
|
|
1355
|
+
return true;
|
|
1356
|
+
};
|
|
1357
|
+
const takeExpression = (): boolean => {
|
|
1358
|
+
const takeTerm = (): boolean => takeString() !== undefined || takeEnvironmentRead();
|
|
1359
|
+
if (!takeTerm()) return false;
|
|
1360
|
+
skipInlineWhitespace();
|
|
1361
|
+
while (take("+")) {
|
|
1362
|
+
if (!takeTerm()) return false;
|
|
1363
|
+
skipInlineWhitespace();
|
|
1364
|
+
}
|
|
1365
|
+
return true;
|
|
1366
|
+
};
|
|
1367
|
+
const takePrint = (): boolean => {
|
|
1368
|
+
skipInlineWhitespace();
|
|
1369
|
+
if (!takeIdentifier("print")) return false;
|
|
1370
|
+
skipInlineWhitespace();
|
|
1371
|
+
if (!take("(")) return false;
|
|
1372
|
+
skipInlineWhitespace();
|
|
1373
|
+
if (take(")")) return true;
|
|
1374
|
+
while (true) {
|
|
1375
|
+
if (!takeExpression()) return false;
|
|
1376
|
+
skipInlineWhitespace();
|
|
1377
|
+
if (take(")")) return true;
|
|
1378
|
+
if (!take(",")) return false;
|
|
1379
|
+
skipInlineWhitespace();
|
|
1380
|
+
if (take(")")) return true;
|
|
1381
|
+
}
|
|
1382
|
+
};
|
|
1383
|
+
const skipSeparators = (): void => {
|
|
1384
|
+
while (true) {
|
|
1385
|
+
skipInlineWhitespace();
|
|
1386
|
+
if (take(";") || take("\n") || take("\r\n")) continue;
|
|
1387
|
+
break;
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
|
|
1391
|
+
skipInlineWhitespace();
|
|
1392
|
+
if (!takeIdentifier("import")) return false;
|
|
1393
|
+
skipInlineWhitespace();
|
|
1394
|
+
if (!takeIdentifier("os")) return false;
|
|
1395
|
+
skipInlineWhitespace();
|
|
1396
|
+
if (!(take(";") || take("\n") || take("\r\n"))) return false;
|
|
1397
|
+
skipSeparators();
|
|
1398
|
+
while (position < program.length) {
|
|
1399
|
+
if (!takePrint()) return false;
|
|
1400
|
+
skipInlineWhitespace();
|
|
1401
|
+
if (position === program.length) break;
|
|
1402
|
+
if (!(take(";") || take("\n") || take("\r\n"))) return false;
|
|
1403
|
+
skipSeparators();
|
|
1404
|
+
}
|
|
1405
|
+
return foundRead;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1272
1408
|
function hasExecutionOption(args: string[], longOptions: string[], shortOption?: string): boolean {
|
|
1273
1409
|
return args.some((arg) => {
|
|
1274
1410
|
const flag = arg.split("=", 1)[0] ?? "";
|
|
@@ -1431,13 +1567,13 @@ function hasEnvironmentRead(
|
|
|
1431
1567
|
const pipelines = parsed.pipelines.map((commands) => commands.map(unwrapStaticCommand));
|
|
1432
1568
|
const unwrapped = pipelines.flat();
|
|
1433
1569
|
if (
|
|
1434
|
-
|
|
1570
|
+
parsed.redirects.length > 0 &&
|
|
1435
1571
|
unwrapped.some((argv) => isAllowedEnvironmentRead(argv, allowedNames))
|
|
1436
1572
|
) {
|
|
1437
1573
|
return true;
|
|
1438
1574
|
}
|
|
1439
1575
|
if (
|
|
1440
|
-
|
|
1576
|
+
parsed.redirects.length > 0 &&
|
|
1441
1577
|
pipelines.some((pipeline) =>
|
|
1442
1578
|
pipeline.some(
|
|
1443
1579
|
(argv) => isLiteralTextProducer(argv) && mentionsEnvironmentRead(argv.join(" ")),
|
|
@@ -1963,6 +2099,28 @@ function isLiteralInlineWriter(argv: string[]): boolean {
|
|
|
1963
2099
|
return take(/^\s*\)\s*;?\s*$/) && position === program.length;
|
|
1964
2100
|
}
|
|
1965
2101
|
|
|
2102
|
+
/** Literal inline output can accompany a proved environment display; file writers cannot. */
|
|
2103
|
+
function isLiteralInlineDisplay(argv: string[]): boolean {
|
|
2104
|
+
const index = inlineProgramIndex(argv);
|
|
2105
|
+
if (index === undefined || !isLiteralInlineWriter(argv)) return false;
|
|
2106
|
+
const kind = inlineRuntimeKind(argv[0]);
|
|
2107
|
+
const program = argv[index] ?? "";
|
|
2108
|
+
return (
|
|
2109
|
+
(kind === "python" && /^\s*print\s*\(/.test(program)) ||
|
|
2110
|
+
(kind === "node" && /^\s*console\s*\.\s*log\s*\(/.test(program))
|
|
2111
|
+
);
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
/** Parse approved Python readers from the original shell shape, including quoted stdin heredocs. */
|
|
2115
|
+
function hasApprovedPythonEnvironmentRead(command: string, allowedNames: Set<string>): boolean {
|
|
2116
|
+
const normalized = normalizeProgramHeredocs(command);
|
|
2117
|
+
const parsed = parseStaticShellCommands(normalized);
|
|
2118
|
+
if (!parsed || typeof parsed === "string") return false;
|
|
2119
|
+
return parsed.pipelines
|
|
2120
|
+
.flat()
|
|
2121
|
+
.some((words) => isAllowedPythonEnvironmentRead(unwrapStaticCommand(words), allowedNames));
|
|
2122
|
+
}
|
|
2123
|
+
|
|
1966
2124
|
/** Inert command identity is unproved after an explicit environment mutation. */
|
|
1967
2125
|
function hasEnvironmentMutationPrefix(command: string): boolean {
|
|
1968
2126
|
const heredoc = boundedHeredoc(command);
|
|
@@ -1991,10 +2149,27 @@ function hasEnvironmentMutationPrefix(command: string): boolean {
|
|
|
1991
2149
|
});
|
|
1992
2150
|
}
|
|
1993
2151
|
|
|
1994
|
-
function hasEnvironmentSourceAccess(
|
|
2152
|
+
function hasEnvironmentSourceAccess(
|
|
2153
|
+
command: string,
|
|
2154
|
+
rawTrigger: boolean,
|
|
2155
|
+
allowedNames: Set<string>,
|
|
2156
|
+
): boolean {
|
|
1995
2157
|
if (rawTrigger && hasEnvironmentMutationPrefix(command)) return true;
|
|
1996
|
-
if (isLiteralTextWrite(command) || isStaticHerdrPrompt(command)) return false;
|
|
1997
2158
|
const parsed = parseStaticShellCommands(command);
|
|
2159
|
+
if (parsed && typeof parsed !== "string") {
|
|
2160
|
+
const commands = parsed.pipelines.flat().map(unwrapStaticCommand);
|
|
2161
|
+
if (commands.some((argv) => isAllowedPythonEnvironmentRead(argv, allowedNames))) {
|
|
2162
|
+
if (hasEnvironmentMutationPrefix(command)) return true;
|
|
2163
|
+
return !commands.every(
|
|
2164
|
+
(argv) =>
|
|
2165
|
+
argv[0]?.split("/").at(-1) === "cat" ||
|
|
2166
|
+
isPassiveTextCommand(argv) ||
|
|
2167
|
+
isAllowedPythonEnvironmentRead(argv, allowedNames) ||
|
|
2168
|
+
isLiteralInlineDisplay(argv),
|
|
2169
|
+
);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
if (isLiteralTextWrite(command) || isStaticHerdrPrompt(command)) return false;
|
|
1998
2173
|
if (!parsed || typeof parsed === "string") return rawTrigger;
|
|
1999
2174
|
const commands = parsed.pipelines.flat().map(unwrapStaticCommand);
|
|
2000
2175
|
if (rawTrigger) {
|
|
@@ -2007,12 +2182,15 @@ function hasEnvironmentSourceAccess(command: string, rawTrigger: boolean): boole
|
|
|
2007
2182
|
);
|
|
2008
2183
|
}
|
|
2009
2184
|
return commands.some((argv) => {
|
|
2185
|
+
if (isAllowedPythonEnvironmentRead(argv, allowedNames)) return false;
|
|
2010
2186
|
const index = inlineProgramIndex(argv);
|
|
2011
2187
|
if (index === undefined) return false;
|
|
2012
|
-
const
|
|
2188
|
+
const python = inlineRuntimeKind(argv[0]) === "python";
|
|
2189
|
+
const parts = programParts(argv[index] ?? "", python);
|
|
2013
2190
|
if (!parts) return true;
|
|
2014
2191
|
return (
|
|
2015
2192
|
mentionsEnvironmentSource(parts.code) ||
|
|
2193
|
+
(python && /\b(?:environ|getenv)\b/.test(parts.code)) ||
|
|
2016
2194
|
(/\b(?:os|process)\s*\[/.test(parts.code) &&
|
|
2017
2195
|
parts.literals.some((value) => /^(?:env|environ|getenv)$/.test(value)))
|
|
2018
2196
|
);
|
|
@@ -2085,12 +2263,17 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
|
|
|
2085
2263
|
|
|
2086
2264
|
function isPathAllowed(filePath: string): boolean {
|
|
2087
2265
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
2088
|
-
return
|
|
2266
|
+
return (
|
|
2267
|
+
!PROCESS_ENVIRONMENT_PATH.test(posix.normalize(normalizedPath)) &&
|
|
2268
|
+
allowedPathPatterns.some((pattern) => pattern.test(normalizedPath))
|
|
2269
|
+
);
|
|
2089
2270
|
}
|
|
2090
2271
|
|
|
2091
2272
|
function isPathBlocked(filePath: string): boolean {
|
|
2092
2273
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
2093
2274
|
|
|
2275
|
+
if (PROCESS_ENVIRONMENT_PATH.test(posix.normalize(normalizedPath))) return true;
|
|
2276
|
+
|
|
2094
2277
|
for (const pattern of allowedPathPatterns) {
|
|
2095
2278
|
if (pattern.test(normalizedPath)) {
|
|
2096
2279
|
return false;
|
|
@@ -2126,6 +2309,12 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
|
|
|
2126
2309
|
const allowPackageInventory = hasProvedPackageInventoryInvocation(originalCommand);
|
|
2127
2310
|
const rawEnvironmentSource =
|
|
2128
2311
|
mentionsEnvironmentSource(command) && mentionsInlineRuntime(command);
|
|
2312
|
+
if (
|
|
2313
|
+
hasApprovedPythonEnvironmentRead(originalCommand, allowedEnvironmentVariables) &&
|
|
2314
|
+
hasEnvironmentMutationPrefix(normalizeProgramHeredocs(originalCommand))
|
|
2315
|
+
) {
|
|
2316
|
+
return "blocked by the environment/execution policy after an unproved environment mutation";
|
|
2317
|
+
}
|
|
2129
2318
|
if (rawEnvironmentSource && hasEnvironmentMutationPrefix(originalCommand))
|
|
2130
2319
|
return "blocked by the environment/execution policy after an unproved environment mutation";
|
|
2131
2320
|
command = normalizeProgramHeredocs(command);
|
|
@@ -2157,7 +2346,7 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
|
|
|
2157
2346
|
return "expands an unapproved or executable environment variable value";
|
|
2158
2347
|
}
|
|
2159
2348
|
if (
|
|
2160
|
-
hasEnvironmentSourceAccess(command, rawEnvironmentSource) ||
|
|
2349
|
+
hasEnvironmentSourceAccess(command, rawEnvironmentSource, allowedEnvironmentVariables) ||
|
|
2161
2350
|
hasEnvironmentRead(command, allowedEnvironmentVariables, allowPackageInventory)
|
|
2162
2351
|
) {
|
|
2163
2352
|
return "blocked by the environment/execution policy; permitted access or non-execution could not be established for this command form";
|
package/src/gh-tool/main.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
prEditCommand,
|
|
29
29
|
prMergeCommand,
|
|
30
30
|
prReadyCommand,
|
|
31
|
+
prDraftCommand,
|
|
31
32
|
prStackCommand,
|
|
32
33
|
prRequestReviewCommand,
|
|
33
34
|
prThreadsCommand,
|
|
@@ -95,6 +96,7 @@ const prCommand = Command.make("pr", {}).pipe(
|
|
|
95
96
|
prEditCommand,
|
|
96
97
|
prMergeCommand,
|
|
97
98
|
prReadyCommand,
|
|
99
|
+
prDraftCommand,
|
|
98
100
|
prStackCommand,
|
|
99
101
|
prRequestReviewCommand,
|
|
100
102
|
prWaitMergeableCommand,
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
closePR,
|
|
35
35
|
collectWithStableState,
|
|
36
36
|
createPR,
|
|
37
|
+
draftPR,
|
|
37
38
|
detectPRStatus,
|
|
38
39
|
editPR,
|
|
39
40
|
fetchPRView,
|
|
@@ -784,6 +785,26 @@ export const prReadyCommand = Command.make(
|
|
|
784
785
|
),
|
|
785
786
|
);
|
|
786
787
|
|
|
788
|
+
export const prDraftCommand = Command.make(
|
|
789
|
+
"draft",
|
|
790
|
+
{
|
|
791
|
+
format: formatOption,
|
|
792
|
+
pr: Flag.Int("pr").pipe(
|
|
793
|
+
Flag.withDescription("PR number (default: current branch PR)"),
|
|
794
|
+
Flag.optional,
|
|
795
|
+
),
|
|
796
|
+
repo: repoOption,
|
|
797
|
+
},
|
|
798
|
+
({ format, pr, repo }) =>
|
|
799
|
+
withRepo(
|
|
800
|
+
repo,
|
|
801
|
+
Effect.gen(function* () {
|
|
802
|
+
const result = yield* draftPR({ pr: Option.getOrNull(pr) });
|
|
803
|
+
yield* logFormatted(result, format);
|
|
804
|
+
}),
|
|
805
|
+
),
|
|
806
|
+
).pipe(Command.withDescription("Convert an open PR to draft (no-op if it's already a draft)"));
|
|
807
|
+
|
|
787
808
|
export const prChecksCommand = Command.make(
|
|
788
809
|
"checks",
|
|
789
810
|
{
|
package/src/gh-tool/pr/core.ts
CHANGED
|
@@ -1220,6 +1220,21 @@ export const readyPR = Effect.fn("pr.readyPR")(function* (opts: { pr: number | n
|
|
|
1220
1220
|
return { ...updated, wasAlreadyReady: false };
|
|
1221
1221
|
});
|
|
1222
1222
|
|
|
1223
|
+
export const draftPR = Effect.fn("pr.draftPR")(function* (opts: { pr: number | null }) {
|
|
1224
|
+
const gh = yield* GitHubService;
|
|
1225
|
+
|
|
1226
|
+
const info = yield* viewPR(opts.pr);
|
|
1227
|
+
|
|
1228
|
+
if (info.isDraft) {
|
|
1229
|
+
return { ...info, wasAlreadyDraft: true };
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
yield* gh.runGh(["pr", "ready", String(info.number), "--undo"]);
|
|
1233
|
+
|
|
1234
|
+
const updated = yield* viewPR(info.number);
|
|
1235
|
+
return { ...updated, wasAlreadyDraft: false };
|
|
1236
|
+
});
|
|
1237
|
+
|
|
1223
1238
|
export const editPR = Effect.fn("pr.editPR")(function* (opts: {
|
|
1224
1239
|
pr: number;
|
|
1225
1240
|
title: string | null;
|