@blogic-cz/agent-tools 0.2.0 → 0.2.2
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 +14 -1
- package/src/az-tool/index.ts +2 -2
- package/src/az-tool/service.ts +2 -2
- package/src/config/loader.ts +3 -0
- package/src/credential-guard/index.ts +2 -1
- package/src/db-tool/config-service.ts +2 -2
- package/src/db-tool/index.ts +2 -2
- package/src/db-tool/types.ts +1 -1
- package/src/gh-tool/index.ts +1 -1
- package/src/gh-tool/issue.ts +1 -1
- package/src/gh-tool/pr/commands.ts +3 -3
- package/src/gh-tool/pr/core.ts +11 -7
- package/src/gh-tool/pr/helpers.ts +1 -1
- package/src/gh-tool/pr/review.ts +10 -6
- package/src/gh-tool/repo.ts +1 -1
- package/src/gh-tool/workflow.ts +1 -1
- package/src/k8s-tool/index.ts +9 -9
- package/src/k8s-tool/service.ts +2 -2
- package/src/logs-tool/index.ts +2 -2
- package/src/logs-tool/service.ts +4 -4
- package/src/logs-tool/types.ts +1 -1
- package/src/session-tool/config.ts +1 -1
- package/src/session-tool/index.ts +1 -1
- package/src/session-tool/service.ts +16 -3
- package/src/session-tool/types.ts +1 -1
- package/src/shared/bun.ts +1 -1
- package/src/shared/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blogic-cz/agent-tools",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "CLI tools for AI coding agent workflows — GitHub, database, Kubernetes, Azure DevOps, logs, and sessions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -33,6 +33,19 @@
|
|
|
33
33
|
"LICENSE"
|
|
34
34
|
],
|
|
35
35
|
"type": "module",
|
|
36
|
+
"imports": {
|
|
37
|
+
"#shared": "./src/shared/index.ts",
|
|
38
|
+
"#shared/*": "./src/shared/*.ts",
|
|
39
|
+
"#config": "./src/config/index.ts",
|
|
40
|
+
"#config/*": "./src/config/*.ts",
|
|
41
|
+
"#gh/*": "./src/gh-tool/*.ts",
|
|
42
|
+
"#k8s/*": "./src/k8s-tool/*.ts",
|
|
43
|
+
"#db/*": "./src/db-tool/*.ts",
|
|
44
|
+
"#logs/*": "./src/logs-tool/*.ts",
|
|
45
|
+
"#az/*": "./src/az-tool/*.ts",
|
|
46
|
+
"#guard": "./src/credential-guard/index.ts",
|
|
47
|
+
"#session/*": "./src/session-tool/*.ts"
|
|
48
|
+
},
|
|
36
49
|
"exports": {
|
|
37
50
|
".": "./src/index.ts",
|
|
38
51
|
"./credential-guard": "./src/credential-guard/index.ts",
|
package/src/az-tool/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Command, Flag } from "effect/unstable/cli";
|
|
|
3
3
|
import { BunRuntime, BunServices } from "@effect/platform-bun";
|
|
4
4
|
import { Console, Effect, Layer, Option } from "effect";
|
|
5
5
|
|
|
6
|
-
import { formatAny, formatOption, formatOutput, renderCauseToStderr, VERSION } from "
|
|
6
|
+
import { formatAny, formatOption, formatOutput, renderCauseToStderr, VERSION } from "#shared";
|
|
7
7
|
import {
|
|
8
8
|
findFailedJobs,
|
|
9
9
|
getBuildJobSummary,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
getBuildTimeline,
|
|
13
13
|
} from "./build";
|
|
14
14
|
import { AzService, AzServiceLayer } from "./service";
|
|
15
|
-
import { ConfigServiceLayer } from "
|
|
15
|
+
import { ConfigServiceLayer } from "#config";
|
|
16
16
|
|
|
17
17
|
// ---------------------------------------------------------------------------
|
|
18
18
|
// Common flags shared across build subcommands
|
package/src/az-tool/service.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
|
2
2
|
import { Effect, Layer, ServiceMap, Stream, Option } from "effect";
|
|
3
3
|
|
|
4
4
|
import type { InvokeParams } from "./types";
|
|
5
|
-
import type { AzureConfig } from "
|
|
5
|
+
import type { AzureConfig } from "#config/types";
|
|
6
6
|
|
|
7
7
|
import { DIRECT_AZ_COMMANDS, STANDALONE_AZ_COMMANDS } from "./config";
|
|
8
8
|
import { AzSecurityError, AzCommandError, AzTimeoutError, AzParseError } from "./errors";
|
|
9
9
|
import { isCommandAllowed, isInvokeAllowed } from "./security";
|
|
10
|
-
import { ConfigService, getToolConfig } from "
|
|
10
|
+
import { ConfigService, getToolConfig } from "#config";
|
|
11
11
|
|
|
12
12
|
export class AzService extends ServiceMap.Service<
|
|
13
13
|
AzService,
|
package/src/config/loader.ts
CHANGED
|
@@ -73,11 +73,13 @@ async function findConfigFile(startDirectory: string = process.cwd()): Promise<s
|
|
|
73
73
|
|
|
74
74
|
while (true) {
|
|
75
75
|
const json5Path = `${currentDirectory}/agent-tools.json5`;
|
|
76
|
+
// eslint-disable-next-line eslint/no-await-in-loop -- sequential directory walk, each iteration may short-circuit
|
|
76
77
|
if (await Bun.file(json5Path).exists()) {
|
|
77
78
|
return json5Path;
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
const jsonPath = `${currentDirectory}/agent-tools.json`;
|
|
82
|
+
// eslint-disable-next-line eslint/no-await-in-loop -- sequential directory walk, each iteration may short-circuit
|
|
81
83
|
if (await Bun.file(jsonPath).exists()) {
|
|
82
84
|
return jsonPath;
|
|
83
85
|
}
|
|
@@ -107,6 +109,7 @@ export async function loadConfig(): Promise<AgentToolsConfig | undefined> {
|
|
|
107
109
|
`Invalid agent-tools config at ${configPath}: ${
|
|
108
110
|
error instanceof Error ? error.message : String(error)
|
|
109
111
|
}`,
|
|
112
|
+
{ cause: error },
|
|
110
113
|
);
|
|
111
114
|
}
|
|
112
115
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* at infrastructure level (K8s RBAC, file permissions, etc.)
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import type { CliToolOverride, CredentialGuardConfig } from "
|
|
17
|
+
import type { CliToolOverride, CredentialGuardConfig } from "#config/types.ts";
|
|
18
18
|
|
|
19
19
|
// ============================================================================
|
|
20
20
|
// TYPES
|
|
@@ -108,6 +108,7 @@ const SECRET_PATTERNS = [
|
|
|
108
108
|
/(?:secret|token|password|passwd|pwd)[" \t:=]+["']?(?!\$\{|process\.env|z\.|generate|create|read|get|fetch|import|export|const|function|return|Schema)[^\s"']{32,}["']?/i,
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
|
+
// eslint-disable-next-line eslint/no-useless-concat -- intentionally split to avoid credential guard self-detection
|
|
111
112
|
name: "Priv" + "ate Key",
|
|
112
113
|
pattern: new RegExp("-----BEGIN.*PRIVATE KEY-----"),
|
|
113
114
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect, Layer, ServiceMap } from "effect";
|
|
2
2
|
|
|
3
|
-
import { ConfigService, getToolConfig } from "
|
|
4
|
-
import type { DatabaseConfig } from "
|
|
3
|
+
import { ConfigService, getToolConfig } from "#config";
|
|
4
|
+
import type { DatabaseConfig } from "#config";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* DbConfigService wraps the resolved DatabaseConfig for the selected profile.
|
package/src/db-tool/index.ts
CHANGED
|
@@ -5,8 +5,8 @@ import { Console, Effect, Layer, Option } from "effect";
|
|
|
5
5
|
|
|
6
6
|
import type { SchemaMode } from "./types";
|
|
7
7
|
|
|
8
|
-
import { formatOption, formatOutput, renderCauseToStderr, VERSION } from "
|
|
9
|
-
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment } from "
|
|
8
|
+
import { formatOption, formatOutput, renderCauseToStderr, VERSION } from "#shared";
|
|
9
|
+
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment } from "#config";
|
|
10
10
|
import { makeDbConfigLayer } from "./config-service";
|
|
11
11
|
import { DbConnectionError } from "./errors";
|
|
12
12
|
import { DbService } from "./service";
|
package/src/db-tool/types.ts
CHANGED
package/src/gh-tool/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Command } from "effect/unstable/cli";
|
|
|
3
3
|
import { BunRuntime, BunServices } from "@effect/platform-bun";
|
|
4
4
|
import { Effect, Layer } from "effect";
|
|
5
5
|
|
|
6
|
-
import { renderCauseToStderr, VERSION } from "
|
|
6
|
+
import { renderCauseToStderr, VERSION } from "#shared";
|
|
7
7
|
import {
|
|
8
8
|
issueListCommand,
|
|
9
9
|
issueViewCommand,
|
package/src/gh-tool/issue.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, Flag } from "effect/unstable/cli";
|
|
2
2
|
import { Effect, Option } from "effect";
|
|
3
3
|
|
|
4
|
-
import { formatOption, logFormatted } from "
|
|
4
|
+
import { formatOption, logFormatted } from "#shared";
|
|
5
5
|
import { GitHubCommandError } from "./errors";
|
|
6
6
|
import { GitHubService } from "./service";
|
|
7
7
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Command, Flag } from "effect/unstable/cli";
|
|
2
2
|
import { Effect, Option } from "effect";
|
|
3
3
|
|
|
4
|
-
import type { PRStatusResult } from "
|
|
4
|
+
import type { PRStatusResult } from "#gh/types";
|
|
5
5
|
|
|
6
|
-
import { formatOption, logFormatted } from "
|
|
6
|
+
import { formatOption, logFormatted } from "#shared";
|
|
7
7
|
import {
|
|
8
8
|
CI_CHECK_WATCH_TIMEOUT_MS,
|
|
9
9
|
DEFAULT_DELETE_BRANCH,
|
|
10
10
|
DEFAULT_MERGE_STRATEGY,
|
|
11
11
|
MERGE_STRATEGIES,
|
|
12
|
-
} from "
|
|
12
|
+
} from "#gh/config";
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
15
|
createPR,
|
package/src/gh-tool/pr/core.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Console, Effect, Option } from "effect";
|
|
2
2
|
|
|
3
|
-
import type { BranchPRDetail, CheckResult, MergeResult, MergeStrategy, PRInfo } from "
|
|
3
|
+
import type { BranchPRDetail, CheckResult, MergeResult, MergeStrategy, PRInfo } from "#gh/types";
|
|
4
4
|
|
|
5
|
-
import { GitHubCommandError, GitHubMergeError, GitHubTimeoutError } from "
|
|
6
|
-
import { GitHubService } from "
|
|
5
|
+
import { GitHubCommandError, GitHubMergeError, GitHubTimeoutError } from "#gh/errors";
|
|
6
|
+
import { GitHubService } from "#gh/service";
|
|
7
7
|
|
|
8
8
|
import type { ButStatusJson, PRViewJsonResult } from "./helpers";
|
|
9
9
|
import { runLocalCommand } from "./helpers";
|
|
@@ -155,7 +155,7 @@ export const detectPRStatus = Effect.fn("pr.detectPRStatus")(function* () {
|
|
|
155
155
|
{ concurrency: "unbounded" },
|
|
156
156
|
);
|
|
157
157
|
|
|
158
|
-
const foundPrs = branchResults.
|
|
158
|
+
const foundPrs = branchResults.flatMap((r) => (r.openPr === null ? [] : [r.openPr]));
|
|
159
159
|
|
|
160
160
|
if (foundPrs.length === 0) {
|
|
161
161
|
const branchDetails: BranchPRDetail[] = branchResults.map((r) => ({
|
|
@@ -172,7 +172,7 @@ export const detectPRStatus = Effect.fn("pr.detectPRStatus")(function* () {
|
|
|
172
172
|
if (foundPrs.length === 1) {
|
|
173
173
|
return {
|
|
174
174
|
mode: "single" as const,
|
|
175
|
-
pr: foundPrs[0]
|
|
175
|
+
pr: foundPrs[0] as PRInfo,
|
|
176
176
|
};
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -205,7 +205,11 @@ export const createPR = Effect.fn("pr.createPR")(function* (opts: {
|
|
|
205
205
|
"--limit",
|
|
206
206
|
"1",
|
|
207
207
|
])
|
|
208
|
-
.pipe(
|
|
208
|
+
.pipe(
|
|
209
|
+
Effect.map((prs) =>
|
|
210
|
+
prs.length > 0 ? Option.some(prs[0] as PRInfo) : Option.none<PRInfo>(),
|
|
211
|
+
),
|
|
212
|
+
)
|
|
209
213
|
: gh
|
|
210
214
|
.runGhJson<{ number: number; url: string }>(["pr", "view", "--json", "number,url"])
|
|
211
215
|
.pipe(Effect.option);
|
|
@@ -258,7 +262,7 @@ export const createPR = Effect.fn("pr.createPR")(function* (opts: {
|
|
|
258
262
|
"1",
|
|
259
263
|
]);
|
|
260
264
|
if (prs.length > 0) {
|
|
261
|
-
return prs[0]
|
|
265
|
+
return prs[0] as PRInfo;
|
|
262
266
|
}
|
|
263
267
|
|
|
264
268
|
return yield* Effect.fail(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
2
2
|
import { Effect, Stream } from "effect";
|
|
3
3
|
|
|
4
|
-
import { GitHubCommandError } from "
|
|
4
|
+
import { GitHubCommandError } from "#gh/errors";
|
|
5
5
|
|
|
6
6
|
export type LocalCommandResult = {
|
|
7
7
|
stdout: string;
|
package/src/gh-tool/pr/review.ts
CHANGED
|
@@ -7,10 +7,10 @@ import type {
|
|
|
7
7
|
IsoTimestamp,
|
|
8
8
|
ReviewComment,
|
|
9
9
|
ReviewThread,
|
|
10
|
-
} from "
|
|
10
|
+
} from "#gh/types";
|
|
11
11
|
|
|
12
|
-
import { GitHubCommandError } from "
|
|
13
|
-
import { GitHubService } from "
|
|
12
|
+
import { GitHubCommandError } from "#gh/errors";
|
|
13
|
+
import { GitHubService } from "#gh/service";
|
|
14
14
|
|
|
15
15
|
import { viewPR } from "./core";
|
|
16
16
|
|
|
@@ -190,9 +190,12 @@ export const fetchThreads = Effect.fn("pr.fetchThreads")(function* (
|
|
|
190
190
|
const threads = response.repository.pullRequest.reviewThreads.nodes;
|
|
191
191
|
|
|
192
192
|
const mapped: ReviewThread[] = threads
|
|
193
|
-
.filter((node) => node.comments.nodes.length > 0)
|
|
194
193
|
.map((node) => {
|
|
195
|
-
const comment = node.comments.nodes[0]
|
|
194
|
+
const comment = node.comments.nodes[0];
|
|
195
|
+
if (!comment) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
196
199
|
return {
|
|
197
200
|
threadId: node.id,
|
|
198
201
|
commentId: comment.databaseId,
|
|
@@ -201,7 +204,8 @@ export const fetchThreads = Effect.fn("pr.fetchThreads")(function* (
|
|
|
201
204
|
body: comment.body,
|
|
202
205
|
isResolved: node.isResolved,
|
|
203
206
|
};
|
|
204
|
-
})
|
|
207
|
+
})
|
|
208
|
+
.filter((thread): thread is ReviewThread => thread !== null);
|
|
205
209
|
|
|
206
210
|
return unresolvedOnly ? mapped.filter((t) => !t.isResolved) : mapped;
|
|
207
211
|
});
|
package/src/gh-tool/repo.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, Flag } from "effect/unstable/cli";
|
|
2
2
|
import { Effect, Option } from "effect";
|
|
3
3
|
|
|
4
|
-
import { formatOption, logFormatted } from "
|
|
4
|
+
import { formatOption, logFormatted } from "#shared";
|
|
5
5
|
import { GitHubCommandError } from "./errors";
|
|
6
6
|
import { GitHubService } from "./service";
|
|
7
7
|
|
package/src/gh-tool/workflow.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command, Flag } from "effect/unstable/cli";
|
|
2
2
|
import { Console, Effect, Option } from "effect";
|
|
3
3
|
|
|
4
|
-
import { formatOption, logFormatted } from "
|
|
4
|
+
import { formatOption, logFormatted } from "#shared";
|
|
5
5
|
import { GitHubCommandError, GitHubNotFoundError } from "./errors";
|
|
6
6
|
import { GitHubService } from "./service";
|
|
7
7
|
|
package/src/k8s-tool/index.ts
CHANGED
|
@@ -5,10 +5,10 @@ import { Console, Effect, Layer, Option } from "effect";
|
|
|
5
5
|
|
|
6
6
|
import type { CommandResult } from "./types";
|
|
7
7
|
|
|
8
|
-
import { formatOption, formatOutput, renderCauseToStderr, VERSION } from "
|
|
8
|
+
import { formatOption, formatOutput, renderCauseToStderr, VERSION } from "#shared";
|
|
9
9
|
import { K8sService, K8sServiceLayer } from "./service";
|
|
10
|
-
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment, getToolConfig } from "
|
|
11
|
-
import type { K8sConfig } from "
|
|
10
|
+
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment, getToolConfig } from "#config";
|
|
11
|
+
import type { K8sConfig } from "#config";
|
|
12
12
|
import { K8sContextError } from "./errors";
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -78,17 +78,17 @@ const runK8sCommand = (command: string, options: CommonK8sCommandOptions) =>
|
|
|
78
78
|
const result = yield* k8sService.runKubectl(command, options.dryRun).pipe(
|
|
79
79
|
Effect.catchTags({
|
|
80
80
|
K8sContextError: (error) => {
|
|
81
|
-
const
|
|
81
|
+
const errorResult: CommandResult = {
|
|
82
82
|
success: false,
|
|
83
83
|
error: error.message,
|
|
84
84
|
hint: `Verify cluster ID "${k8sConfig.clusterId}" matches a context in kubectl config. Run: kubectl config get-contexts`,
|
|
85
85
|
nextCommand: "kubectl config get-contexts",
|
|
86
86
|
executionTimeMs: 0,
|
|
87
87
|
};
|
|
88
|
-
return Effect.succeed(
|
|
88
|
+
return Effect.succeed(errorResult);
|
|
89
89
|
},
|
|
90
90
|
K8sCommandError: (error) => {
|
|
91
|
-
const
|
|
91
|
+
const errorResult: CommandResult = {
|
|
92
92
|
success: false,
|
|
93
93
|
error: error.message,
|
|
94
94
|
command: error.command,
|
|
@@ -96,10 +96,10 @@ const runK8sCommand = (command: string, options: CommonK8sCommandOptions) =>
|
|
|
96
96
|
error.hint ?? "Check command syntax and ensure the target namespace/resource exists.",
|
|
97
97
|
executionTimeMs: 0,
|
|
98
98
|
};
|
|
99
|
-
return Effect.succeed(
|
|
99
|
+
return Effect.succeed(errorResult);
|
|
100
100
|
},
|
|
101
101
|
K8sTimeoutError: (error) => {
|
|
102
|
-
const
|
|
102
|
+
const errorResult: CommandResult = {
|
|
103
103
|
success: false,
|
|
104
104
|
error: error.message,
|
|
105
105
|
command: error.command,
|
|
@@ -108,7 +108,7 @@ const runK8sCommand = (command: string, options: CommonK8sCommandOptions) =>
|
|
|
108
108
|
`Command timed out after ${error.timeoutMs}ms. Consider increasing timeoutMs in config or narrowing the query.`,
|
|
109
109
|
executionTimeMs: error.timeoutMs,
|
|
110
110
|
};
|
|
111
|
-
return Effect.succeed(
|
|
111
|
+
return Effect.succeed(errorResult);
|
|
112
112
|
},
|
|
113
113
|
}),
|
|
114
114
|
);
|
package/src/k8s-tool/service.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { Effect, Layer, Option, Ref, ServiceMap, Stream } from "effect";
|
|
|
4
4
|
import type { CommandResult, Environment } from "./types";
|
|
5
5
|
|
|
6
6
|
import { K8sCommandError, K8sContextError, K8sTimeoutError } from "./errors";
|
|
7
|
-
import { ConfigService, getToolConfig } from "
|
|
8
|
-
import type { K8sConfig } from "
|
|
7
|
+
import { ConfigService, getToolConfig } from "#config";
|
|
8
|
+
import type { K8sConfig } from "#config";
|
|
9
9
|
|
|
10
10
|
export class K8sService extends ServiceMap.Service<
|
|
11
11
|
K8sService,
|
package/src/logs-tool/index.ts
CHANGED
|
@@ -20,8 +20,8 @@ import { Console, Effect, Layer, Option, Result } from "effect";
|
|
|
20
20
|
|
|
21
21
|
import type { Environment, LogResult, ReadOptions } from "./types";
|
|
22
22
|
|
|
23
|
-
import { formatOption, formatOutput, renderCauseToStderr, VERSION } from "
|
|
24
|
-
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment } from "
|
|
23
|
+
import { formatOption, formatOutput, renderCauseToStderr, VERSION } from "#shared";
|
|
24
|
+
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment } from "#config";
|
|
25
25
|
import { LogsConfigError, LogsNotFoundError, LogsReadError, LogsTimeoutError } from "./errors";
|
|
26
26
|
import { LogsService, LogsServiceLayer } from "./service";
|
|
27
27
|
|
package/src/logs-tool/service.ts
CHANGED
|
@@ -3,10 +3,10 @@ import { Effect, Layer, Result, ServiceMap, Stream } from "effect";
|
|
|
3
3
|
|
|
4
4
|
import type { Environment, LogFile, ReadOptions } from "./types";
|
|
5
5
|
|
|
6
|
-
import { K8sCommandError } from "
|
|
7
|
-
import { K8sService, K8sServiceLayer } from "
|
|
8
|
-
import { ConfigService, ConfigServiceLayer, getToolConfig } from "
|
|
9
|
-
import type { LogsConfig } from "
|
|
6
|
+
import { K8sCommandError } from "#k8s/errors";
|
|
7
|
+
import { K8sService, K8sServiceLayer } from "#k8s/service";
|
|
8
|
+
import { ConfigService, ConfigServiceLayer, getToolConfig } from "#config/loader";
|
|
9
|
+
import type { LogsConfig } from "#config/types";
|
|
10
10
|
import { LogsNotFoundError, LogsReadError, type LogsError } from "./errors";
|
|
11
11
|
|
|
12
12
|
export const parseLogFiles = (output: string): LogFile[] => {
|
package/src/logs-tool/types.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Effect, Layer, ServiceMap } from "effect";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
|
|
5
|
-
import { loadConfig } from "
|
|
5
|
+
import { loadConfig } from "#config/loader";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Resolves the OpenCode storage base path from config or default.
|
|
@@ -13,7 +13,7 @@ import { Console, Effect, Layer, Result } from "effect";
|
|
|
13
13
|
|
|
14
14
|
import type { MessageSummary, SessionResult } from "./types";
|
|
15
15
|
|
|
16
|
-
import { formatOption, formatOutput, VERSION } from "
|
|
16
|
+
import { formatOption, formatOutput, VERSION } from "#shared";
|
|
17
17
|
import { ResolvedPaths, ResolvedPathsLayer } from "./config";
|
|
18
18
|
import { SessionStorageNotFoundError } from "./errors";
|
|
19
19
|
import { formatDate, SessionService, SessionServiceLayer, truncate } from "./service";
|
|
@@ -51,8 +51,10 @@ const readJsonFilesInTree = (parentDir: string): Effect.Effect<FileEntry[], Sess
|
|
|
51
51
|
const subPath = `${parentDir}/${subDir}`;
|
|
52
52
|
let files: string[];
|
|
53
53
|
try {
|
|
54
|
+
// eslint-disable-next-line eslint/no-await-in-loop -- sequential directory walk, each iteration may short-circuit
|
|
54
55
|
files = await readdir(subPath);
|
|
55
56
|
} catch {
|
|
57
|
+
/* ignore unreadable files */
|
|
56
58
|
continue;
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -63,8 +65,11 @@ const readJsonFilesInTree = (parentDir: string): Effect.Effect<FileEntry[], Sess
|
|
|
63
65
|
try {
|
|
64
66
|
const content = await Bun.file(filePath).text();
|
|
65
67
|
results.push({ filePath, content });
|
|
66
|
-
} catch {
|
|
68
|
+
} catch {
|
|
69
|
+
/* ignore unreadable files */
|
|
70
|
+
}
|
|
67
71
|
});
|
|
72
|
+
// eslint-disable-next-line eslint/no-await-in-loop -- sequential directory walk, each iteration may short-circuit
|
|
68
73
|
await Promise.all(reads);
|
|
69
74
|
}
|
|
70
75
|
|
|
@@ -90,7 +95,9 @@ const readJsonFilesFlat = (dir: string): Effect.Effect<FileEntry[], SessionError
|
|
|
90
95
|
try {
|
|
91
96
|
const content = await Bun.file(filePath).text();
|
|
92
97
|
results.push({ filePath, content });
|
|
93
|
-
} catch {
|
|
98
|
+
} catch {
|
|
99
|
+
/* ignore unreadable files */
|
|
100
|
+
}
|
|
94
101
|
});
|
|
95
102
|
await Promise.all(reads);
|
|
96
103
|
|
|
@@ -191,7 +198,13 @@ export class SessionService extends ServiceMap.Service<
|
|
|
191
198
|
}
|
|
192
199
|
}
|
|
193
200
|
|
|
194
|
-
return
|
|
201
|
+
return (
|
|
202
|
+
summaries as MessageSummary[] & {
|
|
203
|
+
toSorted(
|
|
204
|
+
compareFn: (left: MessageSummary, right: MessageSummary) => number,
|
|
205
|
+
): MessageSummary[];
|
|
206
|
+
}
|
|
207
|
+
).toSorted((left, right) => right.created - left.created);
|
|
195
208
|
}),
|
|
196
209
|
|
|
197
210
|
searchSummaries: (summaries: MessageSummary[], query: string): MessageSummary[] => {
|
package/src/shared/bun.ts
CHANGED
package/src/shared/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { commonArgOptions, parseCommonArgs } from "./cli";
|
|
|
8
8
|
|
|
9
9
|
export { renderCauseToStderr } from "./error-renderer";
|
|
10
10
|
|
|
11
|
+
// eslint-disable-next-line import/no-relative-parent-imports -- package.json lives at project root, outside src/
|
|
11
12
|
import pkg from "../../package.json" with { type: "json" };
|
|
12
13
|
export const VERSION = pkg.version;
|
|
13
14
|
|