@blogic-cz/agent-tools 0.2.0 → 0.2.1
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 +4 -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 +17 -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 +14 -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.1",
|
|
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,9 @@
|
|
|
33
33
|
"LICENSE"
|
|
34
34
|
],
|
|
35
35
|
"type": "module",
|
|
36
|
+
"imports": {
|
|
37
|
+
"#src/*": "./src/*"
|
|
38
|
+
},
|
|
36
39
|
"exports": {
|
|
37
40
|
".": "./src/index.ts",
|
|
38
41
|
"./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 "#src/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 "#src/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 "#src/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 "#src/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 "#src/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 "#src/config";
|
|
4
|
+
import type { DatabaseConfig } from "#src/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 "#src/shared";
|
|
9
|
+
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment } from "#src/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 "#src/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 "#src/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 "#src/gh-tool/types";
|
|
5
5
|
|
|
6
|
-
import { formatOption, logFormatted } from "
|
|
6
|
+
import { formatOption, logFormatted } from "#src/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 "#src/gh-tool/config";
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
15
|
createPR,
|
package/src/gh-tool/pr/core.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { Console, Effect, Option } from "effect";
|
|
2
2
|
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
BranchPRDetail,
|
|
5
|
+
CheckResult,
|
|
6
|
+
MergeResult,
|
|
7
|
+
MergeStrategy,
|
|
8
|
+
PRInfo,
|
|
9
|
+
} from "#src/gh-tool/types";
|
|
4
10
|
|
|
5
|
-
import { GitHubCommandError, GitHubMergeError, GitHubTimeoutError } from "
|
|
6
|
-
import { GitHubService } from "
|
|
11
|
+
import { GitHubCommandError, GitHubMergeError, GitHubTimeoutError } from "#src/gh-tool/errors";
|
|
12
|
+
import { GitHubService } from "#src/gh-tool/service";
|
|
7
13
|
|
|
8
14
|
import type { ButStatusJson, PRViewJsonResult } from "./helpers";
|
|
9
15
|
import { runLocalCommand } from "./helpers";
|
|
@@ -155,7 +161,7 @@ export const detectPRStatus = Effect.fn("pr.detectPRStatus")(function* () {
|
|
|
155
161
|
{ concurrency: "unbounded" },
|
|
156
162
|
);
|
|
157
163
|
|
|
158
|
-
const foundPrs = branchResults.
|
|
164
|
+
const foundPrs = branchResults.flatMap((r) => (r.openPr === null ? [] : [r.openPr]));
|
|
159
165
|
|
|
160
166
|
if (foundPrs.length === 0) {
|
|
161
167
|
const branchDetails: BranchPRDetail[] = branchResults.map((r) => ({
|
|
@@ -172,7 +178,7 @@ export const detectPRStatus = Effect.fn("pr.detectPRStatus")(function* () {
|
|
|
172
178
|
if (foundPrs.length === 1) {
|
|
173
179
|
return {
|
|
174
180
|
mode: "single" as const,
|
|
175
|
-
pr: foundPrs[0]
|
|
181
|
+
pr: foundPrs[0] as PRInfo,
|
|
176
182
|
};
|
|
177
183
|
}
|
|
178
184
|
|
|
@@ -205,7 +211,11 @@ export const createPR = Effect.fn("pr.createPR")(function* (opts: {
|
|
|
205
211
|
"--limit",
|
|
206
212
|
"1",
|
|
207
213
|
])
|
|
208
|
-
.pipe(
|
|
214
|
+
.pipe(
|
|
215
|
+
Effect.map((prs) =>
|
|
216
|
+
prs.length > 0 ? Option.some(prs[0] as PRInfo) : Option.none<PRInfo>(),
|
|
217
|
+
),
|
|
218
|
+
)
|
|
209
219
|
: gh
|
|
210
220
|
.runGhJson<{ number: number; url: string }>(["pr", "view", "--json", "number,url"])
|
|
211
221
|
.pipe(Effect.option);
|
|
@@ -258,7 +268,7 @@ export const createPR = Effect.fn("pr.createPR")(function* (opts: {
|
|
|
258
268
|
"1",
|
|
259
269
|
]);
|
|
260
270
|
if (prs.length > 0) {
|
|
261
|
-
return prs[0]
|
|
271
|
+
return prs[0] as PRInfo;
|
|
262
272
|
}
|
|
263
273
|
|
|
264
274
|
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 "#src/gh-tool/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 "#src/gh-tool/types";
|
|
11
11
|
|
|
12
|
-
import { GitHubCommandError } from "
|
|
13
|
-
import { GitHubService } from "
|
|
12
|
+
import { GitHubCommandError } from "#src/gh-tool/errors";
|
|
13
|
+
import { GitHubService } from "#src/gh-tool/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 "#src/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 "#src/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,15 @@ 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 "#src/shared";
|
|
9
9
|
import { K8sService, K8sServiceLayer } from "./service";
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
ConfigService,
|
|
12
|
+
ConfigServiceLayer,
|
|
13
|
+
getDefaultEnvironment,
|
|
14
|
+
getToolConfig,
|
|
15
|
+
} from "#src/config";
|
|
16
|
+
import type { K8sConfig } from "#src/config";
|
|
12
17
|
import { K8sContextError } from "./errors";
|
|
13
18
|
|
|
14
19
|
/**
|
|
@@ -78,17 +83,17 @@ const runK8sCommand = (command: string, options: CommonK8sCommandOptions) =>
|
|
|
78
83
|
const result = yield* k8sService.runKubectl(command, options.dryRun).pipe(
|
|
79
84
|
Effect.catchTags({
|
|
80
85
|
K8sContextError: (error) => {
|
|
81
|
-
const
|
|
86
|
+
const errorResult: CommandResult = {
|
|
82
87
|
success: false,
|
|
83
88
|
error: error.message,
|
|
84
89
|
hint: `Verify cluster ID "${k8sConfig.clusterId}" matches a context in kubectl config. Run: kubectl config get-contexts`,
|
|
85
90
|
nextCommand: "kubectl config get-contexts",
|
|
86
91
|
executionTimeMs: 0,
|
|
87
92
|
};
|
|
88
|
-
return Effect.succeed(
|
|
93
|
+
return Effect.succeed(errorResult);
|
|
89
94
|
},
|
|
90
95
|
K8sCommandError: (error) => {
|
|
91
|
-
const
|
|
96
|
+
const errorResult: CommandResult = {
|
|
92
97
|
success: false,
|
|
93
98
|
error: error.message,
|
|
94
99
|
command: error.command,
|
|
@@ -96,10 +101,10 @@ const runK8sCommand = (command: string, options: CommonK8sCommandOptions) =>
|
|
|
96
101
|
error.hint ?? "Check command syntax and ensure the target namespace/resource exists.",
|
|
97
102
|
executionTimeMs: 0,
|
|
98
103
|
};
|
|
99
|
-
return Effect.succeed(
|
|
104
|
+
return Effect.succeed(errorResult);
|
|
100
105
|
},
|
|
101
106
|
K8sTimeoutError: (error) => {
|
|
102
|
-
const
|
|
107
|
+
const errorResult: CommandResult = {
|
|
103
108
|
success: false,
|
|
104
109
|
error: error.message,
|
|
105
110
|
command: error.command,
|
|
@@ -108,7 +113,7 @@ const runK8sCommand = (command: string, options: CommonK8sCommandOptions) =>
|
|
|
108
113
|
`Command timed out after ${error.timeoutMs}ms. Consider increasing timeoutMs in config or narrowing the query.`,
|
|
109
114
|
executionTimeMs: error.timeoutMs,
|
|
110
115
|
};
|
|
111
|
-
return Effect.succeed(
|
|
116
|
+
return Effect.succeed(errorResult);
|
|
112
117
|
},
|
|
113
118
|
}),
|
|
114
119
|
);
|
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 "#src/config";
|
|
8
|
+
import type { K8sConfig } from "#src/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 "#src/shared";
|
|
24
|
+
import { ConfigService, ConfigServiceLayer, getDefaultEnvironment } from "#src/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 "#src/k8s-tool/errors";
|
|
7
|
+
import { K8sService, K8sServiceLayer } from "#src/k8s-tool/service";
|
|
8
|
+
import { ConfigService, ConfigServiceLayer, getToolConfig } from "#src/config/loader";
|
|
9
|
+
import type { LogsConfig } from "#src/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 "#src/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 "#src/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
|
|