@blogic-cz/agent-tools 1.5.9 → 1.5.10

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
@@ -612,6 +612,10 @@ The guard blocks agents from accessing sensitive files, leaking secrets, and run
612
612
 
613
613
  GitHub text and file publication, database queries, Azure and Kubernetes command arguments, and observability requests are checked before execution. GitHub file uploads use snapshots of the inspected bytes. Generated release notes and existing pending reviews or draft releases are inspected before publication. Authentication headers and connection credentials remain inside the tools.
614
614
 
615
+ GitHub API requests validate the serialized body that will be sent, including JSON keys and decoded string values. Serialization happens once, before authentication lookup or network access. File publication checks both the supplied path and its resolved target against known credential locations before reading content. This includes SSH, AWS, Kubernetes, Azure, and common CLI credential stores. An unknown filename can still contain credentials, so content checks also apply.
616
+
617
+ The two direct GitHub CLI launch paths receive an explicit environment containing supported GitHub authentication, host/configuration, proxy/CA, and platform variables. Unrelated parent variables and runtime loader settings are not inherited. Other tools retain their own environment contracts; this does not isolate the parent agent or prevent GitHub CLI access to its configured credential files.
618
+
615
619
  Results retain their JSON or TOON structure, with detected credentials replaced by `[REDACTED]`. Audit records are sanitized before storage; reading older records also sanitizes the returned content but does not rewrite the database.
616
620
 
617
621
  These checks apply to these wrappers. They do not intercept arbitrary shell programs or other agent tools. GitHub does not offer an atomic content-version condition for submitting pending reviews or publishing existing drafts, so a concurrent remote edit between inspection and publication remains possible.
@@ -654,6 +658,8 @@ Paths are checked against sensitive filename patterns and configured path rules.
654
658
 
655
659
  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.
656
660
 
661
+ 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.
662
+
657
663
  A separate bounded Node proof supports literal `package.json` inventory loops that print `bin` metadata or use the supported scripts filter. The complete invocation must preserve loader identity through known passive commands, closed literal writers, or proved inventories. Startup/environment mutations, unknown commands, loader changes, and other dynamic loading remain unproved and are refused.
658
664
 
659
665
  ### Setup for OpenCode
@@ -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;AAI5E,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;AA07DF,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,CAiTrF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UArxED,SAAS,UAAU,UAAU,KAAK,IAqxEM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YAvxEC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAuxEjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aAzxEE,MAAM,KAAK,OAyxEgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aA3xEE,MAAM,KAAK,OA2xEgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YA7xEC,MAAM,KAAK,OA6xE0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YA/xEC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IA+xEf,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YAjyEC,MAAM,KAAK,OAiyEsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YAnyEC,MAAM,KAAK,MAAM,GAAG,IAmyEa,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;AAI5E,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;AA66DF,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,CAiTrF;AAQD,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,UAxwED,SAAS,UAAU,UAAU,KAAK,IAwwEM,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,aAAa,YA1wEC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IA0wEjB,CAAC;AAExD,yEAAyE;AACzE,eAAO,MAAM,aAAa,aA5wEE,MAAM,KAAK,OA4wEgB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,aAAa,aA9wEE,MAAM,KAAK,OA8wEgB,CAAC;AAExD,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,YAhxEC,MAAM,KAAK,OAgxE0B,CAAC;AAE1E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,YAlxEC,MAAM,KAAK;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAkxEf,CAAC;AAEhE,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,YApxEC,MAAM,KAAK,OAoxEsB,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,YAtxEC,MAAM,KAAK,MAAM,GAAG,IAsxEa,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/gh-tool/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,eAAe,EAA2C,MAAM,UAAU,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAU/C,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAYF,eAAO,MAAM,kBAAkB,qDA4B7B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AA4FF,eAAO,MAAM,SAAS,GAAI,CAAC,QACnB,gBAAgB,KACrB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,cAAc,CAQjD,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/gh-tool/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,EAAE,eAAe,EAA2C,MAAM,UAAU,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAW/C,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAYF,eAAO,MAAM,kBAAkB,qDA6B7B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAuFF,eAAO,MAAM,SAAS,GAAI,CAAC,QACnB,gBAAgB,KACrB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,cAAc,CAqCjD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const ghEnvironment: (environment?: Record<string, string | undefined>) => Record<string, string>;
2
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/gh-tool/environment.ts"],"names":[],"mappings":"AAyCA,eAAO,MAAM,aAAa,iBACX,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,KAC9C,MAAM,CAAC,MAAM,EAAE,MAAM,CAMrB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/gh-tool/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AAExD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,aAAa,EAA4C,MAAM,SAAS,CAAC;AA4DlF,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,kBAAkB,GAAG,eAAe,GAAG,mBAAmB,CAAC;;oBAK7D,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC;wBAChD,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC;yBAC/C,CACnB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,KAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;yBACf,CAAC,CAAC,EACrB,IAAI,EAAE,gBAAgB,KACnB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;4BACzB,MAAM,MAAM,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,EAAE,KAAK,CAAC;0BAC1D,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC;6BACnC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,CAAC;;AAjBpD,qBAAa,aAAc,SAAQ,kBAmBF;IAC/B,MAAM,CAAC,QAAQ,CAAC,KAAK,6FAyRnB;CACH"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/gh-tool/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AAExD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAIxC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,aAAa,EAA4C,MAAM,SAAS,CAAC;AA4DlF,MAAM,MAAM,QAAQ,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG,kBAAkB,GAAG,eAAe,GAAG,mBAAmB,CAAC;;oBAK7D,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC;wBAChD,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC;yBAC/C,CACnB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,KAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;yBACf,CAAC,CAAC,EACrB,IAAI,EAAE,gBAAgB,KACnB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;4BACzB,MAAM,MAAM,CAAC,MAAM,CAAC,gBAAgB,GAAG,SAAS,EAAE,KAAK,CAAC;0BAC1D,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC;6BACnC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,kBAAkB,EAAE,CAAC,CAAC;;AAjBpD,qBAAa,aAAc,SAAQ,kBAmBF;IAC/B,MAAM,CAAC,QAAQ,CAAC,KAAK,6FA0RnB;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"text-input.d.ts","sourceRoot":"","sources":["../../src/gh-tool/text-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AASpE,QAAA,MAAM,WAAW,wDAAgD,CAAC;AAIlE,eAAO,MAAM,eAAe,aAAc,MAAM,YACmB,CAAC;AAEpE,eAAO,MAAM,oBAAoB,SAAU,MAAM,WAAW,MAAM,0FAYjE,CAAC;AAEF,eAAO,MAAM,yBAAyB,aAAc,MAAM,WAAW,MAAM;;;6BAUH,CAAC;AAEzE,eAAO,MAAM,oBAAoB,aAAc,MAAM,WAAW,MAAM,mDACJ,CAAC;AAuBnE,KAAK,uBAAuB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAwFF,eAAO,MAAM,wBAAwB,YAC1B,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,cAAc,CAAC,KACrE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAIuD,CAAC;AAEnG,eAAO,MAAM,wBAAwB,YAC1B,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,cAAc,CAAC,KACrE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,kBAAkB,CAI9C,CAAC;AAEL,eAAO,MAAM,uBAAuB,YACzB,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,cAAc,CAAC,GAAG;IACvE,YAAY,EAAE,MAAM,CAAC;CACtB,KACA,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAKsD,CAAC"}
1
+ {"version":3,"file":"text-input.d.ts","sourceRoot":"","sources":["../../src/gh-tool/text-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAepE,QAAA,MAAM,WAAW,wDAAgD,CAAC;AAIlE,eAAO,MAAM,eAAe,aAAc,MAAM,YACyC,CAAC;AAE1F,eAAO,MAAM,oBAAoB,SAAU,MAAM,WAAW,MAAM,0FAYjE,CAAC;AAEF,eAAO,MAAM,yBAAyB,aAAc,MAAM,WAAW,MAAM;;;6BAUH,CAAC;AAEzE,eAAO,MAAM,oBAAoB,aAAc,MAAM,WAAW,MAAM,mDACJ,CAAC;AAuBnE,KAAK,uBAAuB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAwFF,eAAO,MAAM,wBAAwB,YAC1B,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,cAAc,CAAC,KACrE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAIuD,CAAC;AAEnG,eAAO,MAAM,wBAAwB,YAC1B,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,cAAc,CAAC,KACrE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,kBAAkB,CAI9C,CAAC;AAEL,eAAO,MAAM,uBAAuB,YACzB,IAAI,CAAC,uBAAuB,EAAE,aAAa,GAAG,cAAc,CAAC,GAAG;IACvE,YAAY,EAAE,MAAM,CAAC;CACtB,KACA,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAKsD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blogic-cz/agent-tools",
3
- "version": "1.5.9",
3
+ "version": "1.5.10",
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",
@@ -997,18 +997,6 @@ function inlinePackageCommands(command: string, allowInventory: boolean): string
997
997
  });
998
998
  }
999
999
 
1000
- /** JSON values selected by arbitrary keys or printed wholesale have no metadata proof. */
1001
- function hasUnverifiedJsonValueOutput(code: string): boolean {
1002
- if (!/\bjson\.loads?\s*\(/.test(code) || !/\bprint\s*\(/.test(code)) return false;
1003
- if (/\.items\s*\(/.test(code) || /\bprint\s*\(\s*json\.loads?\s*\(/.test(code)) return true;
1004
- const names = [...code.matchAll(/\b([A-Za-z_]\w*)\s*=\s*json\.loads?\s*\(/g)].map(
1005
- (match) => match[1] ?? "",
1006
- );
1007
- return names.some((name) =>
1008
- new RegExp(`\\bprint\\s*\\(\\s*(?:json\\.dumps\\s*\\(\\s*)?${name}\\s*[,)]`).test(code),
1009
- );
1010
- }
1011
-
1012
1000
  function hasInlineProgramExecution(
1013
1001
  program: string,
1014
1002
  python: boolean,
@@ -1016,7 +1004,6 @@ function hasInlineProgramExecution(
1016
1004
  ): boolean {
1017
1005
  const parts = programParts(program, python);
1018
1006
  if (!parts) return true;
1019
- if (python && hasUnverifiedJsonValueOutput(parts.code)) return true;
1020
1007
  if (parts.loadedModules.some((name) => /^(?:node:)?vm$/.test(name))) return true;
1021
1008
  // Dynamic loading and reflective access cannot establish a non-executing code operand.
1022
1009
  if (
@@ -2137,7 +2124,7 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
2137
2124
  const rawEnvironmentSource =
2138
2125
  mentionsEnvironmentSource(command) && mentionsInlineRuntime(command);
2139
2126
  if (rawEnvironmentSource && hasEnvironmentMutationPrefix(originalCommand))
2140
- return "reads process environment after an unproved environment mutation";
2127
+ return "blocked by the environment/execution policy after an unproved environment mutation";
2141
2128
  command = normalizeProgramHeredocs(command);
2142
2129
  const proof = materializeLiteralShell(command);
2143
2130
  if (!proof && /^\s*for\b/.test(command)) return "cannot prove a bounded literal shell loop";
@@ -2158,19 +2145,19 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
2158
2145
  if (
2159
2146
  hasSensitiveFileRead(command, isPathBlocked) ||
2160
2147
  hasSensitivePathRedirect(command, isPathBlocked)
2161
- ) {
2162
- return "accesses a sensitive file path";
2163
- }
2148
+ )
2149
+ return "blocked by the file-access policy; a sensitive path matched or this command form could not be verified";
2164
2150
  if (
2165
2151
  !isLiteralTextWrite(command) &&
2166
2152
  hasEnvironmentVariableExpansionRead(command, allowedEnvironmentVariables, isPathBlocked)
2167
2153
  ) {
2168
2154
  return "expands an unapproved or executable environment variable value";
2169
2155
  }
2170
- if (hasEnvironmentSourceAccess(command, rawEnvironmentSource))
2171
- return "reads process environment from a script";
2172
- if (hasEnvironmentRead(command, allowedEnvironmentVariables, allowPackageInventory)) {
2173
- return "reads environment variables or passes them to an executor";
2156
+ if (
2157
+ hasEnvironmentSourceAccess(command, rawEnvironmentSource) ||
2158
+ hasEnvironmentRead(command, allowedEnvironmentVariables, allowPackageInventory)
2159
+ ) {
2160
+ return "blocked by the environment/execution policy; permitted access or non-execution could not be established for this command form";
2174
2161
  }
2175
2162
  if (
2176
2163
  dangerousBashPatterns.some(
@@ -2319,7 +2306,7 @@ export function createCredentialGuard(config?: CredentialGuardConfig): Credentia
2319
2306
  throw new Error(
2320
2307
  `\u{1F6AB} Command blocked: ${dangerousReason}; this command might expose secrets.\n\n` +
2321
2308
  `Command: ${command}\n\n` +
2322
- `If you need environment info, ask the user directly.\n\n` +
2309
+ `Use a supported command form or the appropriate wrapper tool.\n\n` +
2323
2310
  `Think this is wrong? Review the project repository, adjust the patterns, and submit a PR.`,
2324
2311
  );
2325
2312
  }
@@ -4,6 +4,7 @@ import { retryTransient } from "#shared/retry-transient";
4
4
 
5
5
  import { GitHubAuthError, GitHubCommandError, GitHubNotFoundError } from "./errors";
6
6
  import type { GitHubApiError } from "./errors";
7
+ import { ghEnvironment } from "./environment";
7
8
  import { validateOutboundText } from "./text-input";
8
9
 
9
10
  // Direct HTTP, not `gh api`: the CLI collapses every failure into a non-zero exit and
@@ -44,6 +45,7 @@ export const resolveGitHubToken = Effect.fn("gh.resolveGitHubToken")(function* (
44
45
  const proc = Bun.spawn(["gh", "auth", "token", "--hostname", "github.com"], {
45
46
  stdout: "pipe",
46
47
  stderr: "ignore",
48
+ env: ghEnvironment(),
47
49
  });
48
50
  const stdout = await new Response(proc.stdout).text();
49
51
  const exitCode = await proc.exited;
@@ -67,27 +69,22 @@ export type GitHubApiRequest = {
67
69
 
68
70
  const MAX_API_RETRIES = 2;
69
71
 
70
- const outboundBodyText = (value: unknown): string => {
72
+ // Traverse only parsed JSON, never the caller's getters or toJSON hooks.
73
+ const decodedBodyText = (value: unknown): string => {
71
74
  if (typeof value === "string") return value;
72
- if (Array.isArray(value)) return value.map(outboundBodyText).join("\n");
75
+ if (Array.isArray(value)) return value.map(decodedBodyText).join("\n");
73
76
  if (value !== null && typeof value === "object")
74
- return Object.values(value).map(outboundBodyText).join("\n");
77
+ return Object.entries(value)
78
+ .map(([key, item]) => `${key}\n${decodedBodyText(item)}`)
79
+ .join("\n");
75
80
  return "";
76
81
  };
77
82
 
78
- const githubApiAttempt = Effect.fn("gh.githubApiAttempt")(function* <T>(opts: GitHubApiRequest) {
83
+ const githubApiAttempt = Effect.fn("gh.githubApiAttempt")(function* <T>(
84
+ opts: GitHubApiRequest,
85
+ serializedBody: string | undefined,
86
+ ) {
79
87
  const method = opts.method ?? "GET";
80
- const bodyText = yield* Effect.try({
81
- try: () => outboundBodyText(opts.body),
82
- catch: () =>
83
- new GitHubCommandError({
84
- command: `gh-tool ${method} ${opts.path}`,
85
- exitCode: 1,
86
- stderr: "Refusing to publish an invalid request body",
87
- message: "Refusing to publish an invalid request body",
88
- }),
89
- });
90
- yield* validateOutboundText(`${opts.path}\n${bodyText}`, `gh-tool ${method} ${opts.path}`);
91
88
  const token = yield* resolveGitHubToken();
92
89
  const url = `${GITHUB_API_ROOT}/${opts.path.replace(/^\//, "")}`;
93
90
 
@@ -99,9 +96,9 @@ const githubApiAttempt = Effect.fn("gh.githubApiAttempt")(function* <T>(opts: Gi
99
96
  Accept: GITHUB_ACCEPT,
100
97
  Authorization: `Bearer ${token}`,
101
98
  "X-GitHub-Api-Version": GITHUB_API_VERSION,
102
- ...(opts.body === undefined ? {} : { "Content-Type": "application/json" }),
99
+ ...(serializedBody === undefined ? {} : { "Content-Type": "application/json" }),
103
100
  },
104
- ...(opts.body === undefined ? {} : { body: JSON.stringify(opts.body) }),
101
+ ...(serializedBody === undefined ? {} : { body: serializedBody }),
105
102
  }),
106
103
  catch: (cause) =>
107
104
  new GitHubCommandError({
@@ -158,13 +155,42 @@ const githubApiAttempt = Effect.fn("gh.githubApiAttempt")(function* <T>(opts: Gi
158
155
  export const githubApi = <T>(
159
156
  opts: GitHubApiRequest,
160
157
  ): Effect.Effect<GitHubApiResponse<T>, GitHubApiError> =>
161
- retryTransient({
162
- attempt: () => githubApiAttempt<T>(opts),
163
- isTransient: (error) =>
164
- error._tag === "GitHubCommandError" &&
165
- error.retryable === true &&
166
- (opts.method ?? "GET") === "GET",
167
- maxRetries: MAX_API_RETRIES,
158
+ Effect.gen(function* () {
159
+ const snapshot = yield* Effect.try({
160
+ try: () => {
161
+ const path = opts.path;
162
+ const method = opts.method ?? "GET";
163
+ const alsoAcceptStatus = opts.alsoAcceptStatus;
164
+ const request = {
165
+ path,
166
+ method,
167
+ ...(alsoAcceptStatus === undefined ? {} : { alsoAcceptStatus: [...alsoAcceptStatus] }),
168
+ };
169
+ const body = opts.body;
170
+ if (body === undefined) return { request, serialized: undefined, decoded: "" };
171
+ const serialized = JSON.stringify(body);
172
+ if (serialized === undefined) throw new Error("Body is not JSON serializable");
173
+ return { request, serialized, decoded: decodedBodyText(JSON.parse(serialized)) };
174
+ },
175
+ catch: () =>
176
+ new GitHubCommandError({
177
+ command: "gh-tool API",
178
+ exitCode: 1,
179
+ stderr: "Refusing to publish an invalid request body",
180
+ message: "Refusing to publish an invalid request body",
181
+ }),
182
+ });
183
+ const { request } = snapshot;
184
+ yield* validateOutboundText(
185
+ `${request.path}\n${snapshot.serialized ?? ""}\n${snapshot.decoded}`,
186
+ `gh-tool ${request.method} ${request.path}`,
187
+ );
188
+ return yield* retryTransient({
189
+ attempt: () => githubApiAttempt<T>(request, snapshot.serialized),
190
+ isTransient: (error) =>
191
+ error._tag === "GitHubCommandError" && error.retryable === true && request.method === "GET",
192
+ maxRetries: MAX_API_RETRIES,
193
+ });
168
194
  });
169
195
 
170
196
  const safeJsonParse = (text: string): unknown => {
@@ -0,0 +1,50 @@
1
+ // Exact names only: GH children need their own auth/config, not unrelated credentials
2
+ // or executable-loader, editor, and pager settings from the parent process.
3
+ const GH_ENVIRONMENT_NAMES = [
4
+ "PATH",
5
+ "HOME",
6
+ "USERPROFILE",
7
+ "APPDATA",
8
+ "AppData",
9
+ "HOMEDRIVE",
10
+ "HOMEPATH",
11
+ "SYSTEMROOT",
12
+ "SystemRoot",
13
+ "WINDIR",
14
+ "TMPDIR",
15
+ "TMP",
16
+ "TEMP",
17
+ "LANG",
18
+ "LC_ALL",
19
+ "LC_CTYPE",
20
+ "TERM",
21
+ "XDG_CONFIG_HOME",
22
+ "DBUS_SESSION_BUS_ADDRESS",
23
+ "GH_CONFIG_DIR",
24
+ "GH_HOST",
25
+ "GH_REPO",
26
+ "GH_TOKEN",
27
+ "GITHUB_TOKEN",
28
+ "GH_ENTERPRISE_TOKEN",
29
+ "GITHUB_ENTERPRISE_TOKEN",
30
+ "HTTP_PROXY",
31
+ "http_proxy",
32
+ "HTTPS_PROXY",
33
+ "https_proxy",
34
+ "ALL_PROXY",
35
+ "all_proxy",
36
+ "NO_PROXY",
37
+ "no_proxy",
38
+ "SSL_CERT_FILE",
39
+ "SSL_CERT_DIR",
40
+ ] as const;
41
+
42
+ export const ghEnvironment = (
43
+ environment: Record<string, string | undefined> = process.env,
44
+ ): Record<string, string> =>
45
+ Object.fromEntries(
46
+ GH_ENVIRONMENT_NAMES.flatMap((name) => {
47
+ const value = environment[name];
48
+ return value === undefined ? [] : [[name, value]];
49
+ }),
50
+ );
@@ -5,6 +5,7 @@ import type { GitHubRepoConfig } from "#config";
5
5
  import type { RepoInfo } from "./types";
6
6
 
7
7
  import { GH_BINARY } from "./config";
8
+ import { ghEnvironment } from "./environment";
8
9
  import { GitHubAuthError, GitHubCommandError, GitHubNotFoundError } from "./errors";
9
10
  import { retryTransient } from "#shared/retry-transient";
10
11
  import { githubApi } from "./api";
@@ -165,7 +166,8 @@ export class GitHubService extends Context.Service<
165
166
  const command = ChildProcess.make(GH_BINARY, args, {
166
167
  stdout: "pipe",
167
168
  stderr: "pipe",
168
- ...(ghRepo ? { env: { GH_REPO: ghRepo }, extendEnv: true } : {}),
169
+ env: { ...ghEnvironment(), ...(ghRepo ? { GH_REPO: ghRepo } : {}) },
170
+ extendEnv: false,
169
171
  });
170
172
 
171
173
  const proc = yield* executor.spawn(command);
@@ -12,13 +12,19 @@ const SENSITIVE_PATH_PATTERNS = [
12
12
  /\.envrc$/,
13
13
  /\.(pem|key|p12|pfx|cer|crt)$/i,
14
14
  /(?:^|[\\/])(credentials?|passwd|shadow)$/i,
15
+ /(?:^|\/)(?:\.ssh|\.aws|\.kube|\.azure|secrets?|credentials?)(?:\/|$)/i,
16
+ /(?:^|\/)(?:\.npmrc|\.netrc|\.git-credentials|\.sentryclirc|\.pypirc|\.pgpass)$/i,
17
+ /(?:^|\/)\.docker\/config\.json$/i,
18
+ /(?:^|\/)\.config\/gh\/hosts\.yml$/i,
19
+ /(?:^|\/)GitHub CLI\/hosts\.yml$/i,
20
+ /(?:^|\/)(?:kubeconfig(?:[.-].+)?|[^/]+\.kubeconfig)$/i,
15
21
  ];
16
22
  const MissingMode = Schema.Literals(["error", "null", "default"]);
17
23
 
18
24
  const readTextFromStdin = () => Bun.stdin.text();
19
25
 
20
26
  export const isSensitivePath = (filePath: string) =>
21
- SENSITIVE_PATH_PATTERNS.some((pattern) => pattern.test(filePath));
27
+ SENSITIVE_PATH_PATTERNS.some((pattern) => pattern.test(filePath.replaceAll("\\", "/")));
22
28
 
23
29
  export const validateOutboundText = (text: string, command: string) => {
24
30
  const reason = unsafeOutboundTextReason(text);