@blogic-cz/agent-tools 0.15.12 → 0.15.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blogic-cz/agent-tools",
3
- "version": "0.15.12",
3
+ "version": "0.15.13",
4
4
  "description": "CLI tools for AI coding agent workflows — GitHub, database, Kubernetes, Azure DevOps, logs, sessions, and audit",
5
5
  "keywords": [
6
6
  "agent",
@@ -0,0 +1,27 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ // Homebrew keeps libpq keg-only, so psql is routinely installed yet absent from PATH.
5
+ const KEG_ONLY_PSQL_DIRECTORIES = ["/opt/homebrew/opt/libpq/bin", "/usr/local/opt/libpq/bin"];
6
+
7
+ export const PSQL_MISSING_HINT =
8
+ "psql was not found on PATH. On macOS install it with `brew install libpq`; libpq is keg-only, so also add /opt/homebrew/opt/libpq/bin (Apple silicon) or /usr/local/opt/libpq/bin (Intel) to PATH.";
9
+
10
+ export const resolvePsqlSearchPath = (
11
+ pathEnv: string | undefined,
12
+ fileExists: (candidate: string) => boolean = existsSync,
13
+ ): string | undefined => {
14
+ const directories = (pathEnv ?? "").split(":").filter((directory) => directory.length > 0);
15
+ if (directories.some((directory) => fileExists(join(directory, "psql")))) {
16
+ return pathEnv;
17
+ }
18
+
19
+ const kegOnly = KEG_ONLY_PSQL_DIRECTORIES.find((directory) =>
20
+ fileExists(join(directory, "psql")),
21
+ );
22
+ if (kegOnly === undefined) {
23
+ return pathEnv;
24
+ }
25
+
26
+ return directories.length > 0 ? [...directories, kegOnly].join(":") : kegOnly;
27
+ };
@@ -10,6 +10,7 @@ import { resolveEnvironmentScopedPrerequisites } from "#shared/prerequisites/con
10
10
  import { runWithProfilePrerequisites } from "#shared/prerequisites/runtime";
11
11
  import { buildApiProbeArgs } from "#shared/k8s-probe";
12
12
  import { DbConfigService, TUNNEL_CHECK_INTERVAL_MS } from "./config-service";
13
+ import { PSQL_MISSING_HINT, resolvePsqlSearchPath } from "./psql";
13
14
  import {
14
15
  DbConnectionError,
15
16
  DbMutationBlockedError,
@@ -235,7 +236,8 @@ export class DbService extends Context.Service<
235
236
  new DbQueryError({
236
237
  message: `Command execution failed: ${String(platformError)}`,
237
238
  sql: "shell command",
238
- stderr: undefined,
239
+ stderr: String(platformError),
240
+ ...(String(platformError).includes("psql") ? { hint: PSQL_MISSING_HINT } : {}),
239
241
  }),
240
242
  ),
241
243
  );
@@ -402,6 +404,7 @@ export class DbService extends Context.Service<
402
404
  stderr: "pipe",
403
405
  env: {
404
406
  ...process.env,
407
+ PATH: resolvePsqlSearchPath(process.env.PATH),
405
408
  ...(password ? { PGPASSWORD: password } : {}),
406
409
  ...(isFullyReadOnly(config)
407
410
  ? { PGOPTIONS: "-c default_transaction_read_only=on" }
@@ -141,7 +141,7 @@ export class K8sService extends Context.Service<
141
141
  message: `Command execution failed: ${String(platformError)}`,
142
142
  command: commandStr,
143
143
  exitCode: -1,
144
- stderr: undefined,
144
+ stderr: String(platformError),
145
145
  }),
146
146
  ),
147
147
  );
@@ -320,7 +320,7 @@ export class K8sService extends Context.Service<
320
320
  message: `Command execution failed: ${String(platformError)}`,
321
321
  command: fullCommand,
322
322
  exitCode: -1,
323
- stderr: undefined,
323
+ stderr: String(platformError),
324
324
  }),
325
325
  ),
326
326
  );