@blogic-cz/agent-tools 0.8.15 → 0.8.17
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 -10
- package/src/az-tool/service.ts +2 -2
- package/src/config/loader.ts +4 -5
- package/src/db-tool/config-service.ts +4 -5
- package/src/db-tool/service.ts +2 -2
- package/src/gh-tool/pr/commands.ts +2 -1
- package/src/gh-tool/pr/core.ts +219 -9
- package/src/gh-tool/service.ts +2 -2
- package/src/gh-tool/types.ts +56 -0
- package/src/k8s-tool/service.ts +2 -2
- package/src/logs-tool/service.ts +2 -2
- package/src/session-tool/config.ts +2 -2
- package/src/session-tool/service.ts +2 -2
- package/src/shared/audit.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blogic-cz/agent-tools",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.17",
|
|
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",
|
|
@@ -116,22 +116,26 @@
|
|
|
116
116
|
"lint": "oxlint -c ./.oxlintrc.json --deny-warnings",
|
|
117
117
|
"lint:fix": "oxlint -c ./.oxlintrc.json --fix",
|
|
118
118
|
"session-tool": "bun src/session-tool/index.ts",
|
|
119
|
+
"update:packages": "bun update -i -r",
|
|
119
120
|
"update:skills": "bun run .agents/skills/update-packages/references/skills-update-local.ts",
|
|
120
121
|
"test": "vitest run"
|
|
121
122
|
},
|
|
122
123
|
"dependencies": {
|
|
123
|
-
"@effect/platform-bun": "4.0.0-beta.
|
|
124
|
+
"@effect/platform-bun": "4.0.0-beta.48",
|
|
124
125
|
"@toon-format/toon": "2.1.0",
|
|
125
|
-
"effect": "4.0.0-beta.
|
|
126
|
+
"effect": "4.0.0-beta.48"
|
|
126
127
|
},
|
|
127
128
|
"devDependencies": {
|
|
128
|
-
"@effect/language-service": "0.
|
|
129
|
-
"@effect/vitest": "4.0.0-beta.
|
|
130
|
-
"@types/bun": "1.3.
|
|
131
|
-
"oxfmt": "0.
|
|
132
|
-
"oxlint": "1.
|
|
133
|
-
"typescript": "
|
|
134
|
-
"vitest": "^4.
|
|
129
|
+
"@effect/language-service": "0.85.1",
|
|
130
|
+
"@effect/vitest": "4.0.0-beta.48",
|
|
131
|
+
"@types/bun": "1.3.12",
|
|
132
|
+
"oxfmt": "0.44.0",
|
|
133
|
+
"oxlint": "1.59.0",
|
|
134
|
+
"typescript": "6.0.2",
|
|
135
|
+
"vitest": "^4.1.4"
|
|
136
|
+
},
|
|
137
|
+
"overrides": {
|
|
138
|
+
"@effect/platform-node-shared": "4.0.0-beta.48"
|
|
135
139
|
},
|
|
136
140
|
"engines": {
|
|
137
141
|
"bun": ">=1.0.0"
|
package/src/az-tool/service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
2
|
-
import { Effect, Layer,
|
|
2
|
+
import { Context, Effect, Layer, Option, Stream } from "effect";
|
|
3
3
|
|
|
4
4
|
import type { InvokeParams } from "./types";
|
|
5
5
|
import type { AzureConfig } from "#config/types";
|
|
@@ -10,7 +10,7 @@ import { isCommandAllowed, isInvokeAllowed } from "./security";
|
|
|
10
10
|
import { transformCmdOutput } from "./transformers";
|
|
11
11
|
import { ConfigService, getToolConfig } from "#config";
|
|
12
12
|
|
|
13
|
-
export class AzService extends
|
|
13
|
+
export class AzService extends Context.Service<
|
|
14
14
|
AzService,
|
|
15
15
|
{
|
|
16
16
|
readonly runCommand: (
|
package/src/config/loader.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { dirname } from "node:path";
|
|
2
2
|
|
|
3
|
-
import { Data, Effect, Layer, Schema
|
|
3
|
+
import { Context, Data, Effect, Layer, Schema } from "effect";
|
|
4
4
|
|
|
5
5
|
import type { AgentToolsConfig, GitHubRepoConfig } from "./types";
|
|
6
6
|
|
|
@@ -159,10 +159,9 @@ export async function loadConfig(): Promise<AgentToolsConfig | undefined> {
|
|
|
159
159
|
return decodeConfig(parsed, configPath);
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
export class ConfigService extends
|
|
163
|
-
ConfigService,
|
|
164
|
-
|
|
165
|
-
>()("@agent-tools/ConfigService") {}
|
|
162
|
+
export class ConfigService extends Context.Service<ConfigService, AgentToolsConfig | undefined>()(
|
|
163
|
+
"@agent-tools/ConfigService",
|
|
164
|
+
) {}
|
|
166
165
|
|
|
167
166
|
export class ConfigLoadError extends Data.TaggedError("ConfigLoadError")<{
|
|
168
167
|
readonly cause: unknown;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Layer
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
2
|
|
|
3
3
|
import { ConfigService, getToolConfig } from "#config";
|
|
4
4
|
import type { DatabaseConfig } from "#config";
|
|
@@ -12,10 +12,9 @@ import type { DatabaseConfig } from "#config";
|
|
|
12
12
|
* const dbConfig = yield* DbConfigService;
|
|
13
13
|
* if (!dbConfig) { // no config }
|
|
14
14
|
*/
|
|
15
|
-
export class DbConfigService extends
|
|
16
|
-
DbConfigService,
|
|
17
|
-
|
|
18
|
-
>()("@agent-tools/DbConfigService") {}
|
|
15
|
+
export class DbConfigService extends Context.Service<DbConfigService, DatabaseConfig | undefined>()(
|
|
16
|
+
"@agent-tools/DbConfigService",
|
|
17
|
+
) {}
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
20
|
* Creates a DbConfigService layer that resolves the database config
|
package/src/db-tool/service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
2
|
-
import { Clock, Duration, Effect, Layer, Ref,
|
|
2
|
+
import { Clock, Context, Duration, Effect, Layer, Ref, Stream } from "effect";
|
|
3
3
|
|
|
4
4
|
import type { DbConfig, QueryResult, SchemaMode } from "./types";
|
|
5
5
|
|
|
@@ -33,7 +33,7 @@ export function resolveDbAccessMode(
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export class DbService extends
|
|
36
|
+
export class DbService extends Context.Service<
|
|
37
37
|
DbService,
|
|
38
38
|
{
|
|
39
39
|
readonly executeQuery: (env: string, sql: string) => Effect.Effect<QueryResult, DbError>;
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
detectPRStatus,
|
|
22
22
|
editPR,
|
|
23
23
|
fetchChecks,
|
|
24
|
+
fetchChecksForCommand,
|
|
24
25
|
fetchFailedChecks,
|
|
25
26
|
mergePR,
|
|
26
27
|
rerunChecks,
|
|
@@ -200,7 +201,7 @@ export const prChecksCommand = Command.make(
|
|
|
200
201
|
({ failFast, format, pr, timeout, watch }) =>
|
|
201
202
|
Effect.gen(function* () {
|
|
202
203
|
const prNumber = Option.getOrNull(pr);
|
|
203
|
-
const checks = yield*
|
|
204
|
+
const checks = yield* fetchChecksForCommand(prNumber, watch, failFast, timeout);
|
|
204
205
|
yield* logFormatted(checks, format);
|
|
205
206
|
}),
|
|
206
207
|
).pipe(Command.withDescription("Fetch CI check status for a PR (optionally watch with timeout)"));
|
package/src/gh-tool/pr/core.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import { Console, Effect, Option } from "effect";
|
|
2
|
-
|
|
3
|
-
import type {
|
|
1
|
+
import { Console, Effect, Option, Result } from "effect";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
BranchPRDetail,
|
|
5
|
+
CheckResult,
|
|
6
|
+
FailedCheckDetail,
|
|
7
|
+
FailedCheckRunContext,
|
|
8
|
+
MergeResult,
|
|
9
|
+
MergeStrategy,
|
|
10
|
+
PRInfo,
|
|
11
|
+
WorkflowRunDetail,
|
|
12
|
+
} from "#gh/types";
|
|
4
13
|
|
|
5
14
|
import { GitHubCommandError, GitHubMergeError, GitHubTimeoutError } from "#gh/errors";
|
|
6
15
|
import { GitHubService } from "#gh/service";
|
|
@@ -8,6 +17,174 @@ import { GitHubService } from "#gh/service";
|
|
|
8
17
|
import type { ButStatusJson, PRViewJsonResult } from "./helpers";
|
|
9
18
|
import { runLocalCommand } from "./helpers";
|
|
10
19
|
|
|
20
|
+
const CHECK_JSON_FIELDS = "name,state,bucket,link";
|
|
21
|
+
const GITHUB_ACTIONS_RUN_ID_RE = /github\.com\/[^/]+\/[^/]+\/actions\/runs\/(\d+)/;
|
|
22
|
+
|
|
23
|
+
const buildChecksCommand = (pr: number | null, includeWatch: boolean): string =>
|
|
24
|
+
`bun agent-tools-gh pr checks${pr !== null ? ` --pr ${pr}` : ""}${includeWatch ? " --watch" : ""}`;
|
|
25
|
+
|
|
26
|
+
const buildChecksFailedCommand = (pr: number | null): string =>
|
|
27
|
+
`bun agent-tools-gh pr checks-failed${pr !== null ? ` --pr ${pr}` : ""}`;
|
|
28
|
+
|
|
29
|
+
const extractRunIdFromCheckLink = (link: string): number | null => {
|
|
30
|
+
const match = link.match(GITHUB_ACTIONS_RUN_ID_RE);
|
|
31
|
+
if (!match?.[1]) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const runId = Number(match[1]);
|
|
36
|
+
return Number.isFinite(runId) ? runId : null;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const fetchWorkflowRunFailureContext = Effect.fn("pr.fetchWorkflowRunFailureContext")(function* (
|
|
40
|
+
runId: number,
|
|
41
|
+
) {
|
|
42
|
+
const gh = yield* GitHubService;
|
|
43
|
+
|
|
44
|
+
const run = yield* gh
|
|
45
|
+
.runGhJson<WorkflowRunDetail>([
|
|
46
|
+
"run",
|
|
47
|
+
"view",
|
|
48
|
+
String(runId),
|
|
49
|
+
"--json",
|
|
50
|
+
"databaseId,url,workflowName,status,conclusion,jobs",
|
|
51
|
+
])
|
|
52
|
+
.pipe(Effect.catchTag("GitHubCommandError", () => Effect.succeed(null)));
|
|
53
|
+
|
|
54
|
+
if (run === null) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const failedJobs = run.jobs
|
|
59
|
+
.filter((job) => job.conclusion === "failure" || job.status === "failure")
|
|
60
|
+
.map((job) => ({
|
|
61
|
+
name: job.name,
|
|
62
|
+
status: job.status,
|
|
63
|
+
conclusion: job.conclusion,
|
|
64
|
+
url: job.url,
|
|
65
|
+
failedSteps: job.steps
|
|
66
|
+
.filter((step) => step.conclusion === "failure" || step.status === "failure")
|
|
67
|
+
.map((step) => step.name),
|
|
68
|
+
}));
|
|
69
|
+
|
|
70
|
+
const context: FailedCheckRunContext = {
|
|
71
|
+
runId: run.databaseId,
|
|
72
|
+
url: run.url,
|
|
73
|
+
workflowName: run.workflowName,
|
|
74
|
+
status: run.status,
|
|
75
|
+
conclusion: run.conclusion,
|
|
76
|
+
failedJobs,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return context;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const fetchCheckResults = Effect.fn("pr.fetchCheckResults")(function* (pr: number | null) {
|
|
83
|
+
const gh = yield* GitHubService;
|
|
84
|
+
|
|
85
|
+
const args = ["pr", "checks"];
|
|
86
|
+
if (pr !== null) {
|
|
87
|
+
args.push(String(pr));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return yield* gh.runGhJson<CheckResult[]>([...args, "--json", CHECK_JSON_FIELDS]);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const buildFailedChecksReport = Effect.fn("pr.buildFailedChecksReport")(function* (
|
|
94
|
+
pr: number | null,
|
|
95
|
+
checks: CheckResult[],
|
|
96
|
+
) {
|
|
97
|
+
const failedChecks = checks.filter((check) => check.bucket === "fail");
|
|
98
|
+
const pendingChecks = checks.filter((check) => check.bucket === "pending");
|
|
99
|
+
const passedChecks = checks.filter((check) => check.bucket === "pass");
|
|
100
|
+
|
|
101
|
+
const runIds = [
|
|
102
|
+
...new Set(
|
|
103
|
+
failedChecks
|
|
104
|
+
.map((check) => extractRunIdFromCheckLink(check.link))
|
|
105
|
+
.filter((id) => id !== null),
|
|
106
|
+
),
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
const runContexts = new Map<number, FailedCheckRunContext | null>();
|
|
110
|
+
const contexts = yield* Effect.forEach(
|
|
111
|
+
runIds,
|
|
112
|
+
(runId) =>
|
|
113
|
+
fetchWorkflowRunFailureContext(runId).pipe(
|
|
114
|
+
Effect.map((context) => [runId, context] as const),
|
|
115
|
+
),
|
|
116
|
+
{ concurrency: "unbounded" },
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
for (const [runId, context] of contexts) {
|
|
120
|
+
runContexts.set(runId, context);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const enrichedFailedChecks: FailedCheckDetail[] = failedChecks.map((check) => {
|
|
124
|
+
const runId = extractRunIdFromCheckLink(check.link);
|
|
125
|
+
return {
|
|
126
|
+
...check,
|
|
127
|
+
runId,
|
|
128
|
+
run: runId === null ? null : (runContexts.get(runId) ?? null),
|
|
129
|
+
};
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const nextCommands = [
|
|
133
|
+
buildChecksFailedCommand(pr),
|
|
134
|
+
...new Set(
|
|
135
|
+
enrichedFailedChecks.flatMap((check) => {
|
|
136
|
+
if (check.runId === null) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const commands = [`bun agent-tools-gh workflow view --run ${check.runId}`];
|
|
141
|
+
const firstFailedJob = check.run?.failedJobs[0];
|
|
142
|
+
if (firstFailedJob) {
|
|
143
|
+
commands.push(
|
|
144
|
+
`bun agent-tools-gh workflow job-logs --run ${check.runId} --job ${JSON.stringify(firstFailedJob.name)} --failed-steps-only`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return commands;
|
|
149
|
+
}),
|
|
150
|
+
),
|
|
151
|
+
...(pendingChecks.length > 0 ? [buildChecksCommand(pr, true)] : []),
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
const message =
|
|
155
|
+
failedChecks.length === 0
|
|
156
|
+
? pendingChecks.length > 0
|
|
157
|
+
? `No failed checks yet; ${pendingChecks.length} check(s) are still running.`
|
|
158
|
+
: "No failed checks detected."
|
|
159
|
+
: pendingChecks.length > 0
|
|
160
|
+
? `Detected ${failedChecks.length} failed check(s) while ${pendingChecks.length} check(s) are still running.`
|
|
161
|
+
: `Detected ${failedChecks.length} failed check(s).`;
|
|
162
|
+
|
|
163
|
+
const hint =
|
|
164
|
+
failedChecks.length === 0
|
|
165
|
+
? pendingChecks.length > 0
|
|
166
|
+
? "Wait for the remaining checks to finish, or use --watch to block until CI settles."
|
|
167
|
+
: "All current checks are green."
|
|
168
|
+
: pendingChecks.length > 0
|
|
169
|
+
? "Inspect the failed workflow run first. Other checks are still running and may change overall merge readiness."
|
|
170
|
+
: "Inspect the failed workflow run and failed job logs to get the first concrete error, then rerun only if the failure is understood.";
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
status: failedChecks.length > 0 ? "failed" : "no_failures",
|
|
174
|
+
message,
|
|
175
|
+
summary: {
|
|
176
|
+
total: checks.length,
|
|
177
|
+
failed: failedChecks.length,
|
|
178
|
+
pending: pendingChecks.length,
|
|
179
|
+
passed: passedChecks.length,
|
|
180
|
+
},
|
|
181
|
+
failedChecks: enrichedFailedChecks,
|
|
182
|
+
pendingChecks,
|
|
183
|
+
hint,
|
|
184
|
+
nextCommands,
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
|
|
11
188
|
export const viewPR = Effect.fn("pr.viewPR")(function* (prNumber: number | null) {
|
|
12
189
|
const gh = yield* GitHubService;
|
|
13
190
|
|
|
@@ -433,7 +610,7 @@ export const fetchChecks = Effect.fn("pr.fetchChecks")(function* (
|
|
|
433
610
|
yield* gh.runGh(watchArgs).pipe(
|
|
434
611
|
Effect.timeoutOrElse({
|
|
435
612
|
duration: timeoutMs,
|
|
436
|
-
|
|
613
|
+
orElse: () =>
|
|
437
614
|
Effect.fail(
|
|
438
615
|
new GitHubTimeoutError({
|
|
439
616
|
message: `CI check monitoring timed out after ${timeoutSeconds}s`,
|
|
@@ -446,22 +623,55 @@ export const fetchChecks = Effect.fn("pr.fetchChecks")(function* (
|
|
|
446
623
|
}),
|
|
447
624
|
);
|
|
448
625
|
|
|
449
|
-
return yield*
|
|
626
|
+
return yield* fetchCheckResults(pr);
|
|
450
627
|
}
|
|
451
628
|
|
|
452
|
-
const results = yield*
|
|
629
|
+
const results = yield* fetchCheckResults(pr);
|
|
453
630
|
if (results.some((c) => c.bucket === "pending")) {
|
|
454
631
|
yield* Console.warn(
|
|
455
632
|
`ℹ️ Some checks are still running. Prefer --watch to block until completion instead of polling:\n` +
|
|
456
|
-
`
|
|
633
|
+
` ${buildChecksCommand(pr, true)}`,
|
|
457
634
|
);
|
|
458
635
|
}
|
|
459
636
|
return results;
|
|
460
637
|
});
|
|
461
638
|
|
|
462
639
|
export const fetchFailedChecks = Effect.fn("pr.fetchFailedChecks")(function* (pr: number | null) {
|
|
463
|
-
const checks = yield*
|
|
464
|
-
return
|
|
640
|
+
const checks = yield* fetchCheckResults(pr);
|
|
641
|
+
return yield* buildFailedChecksReport(pr, checks);
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
export const fetchChecksForCommand = Effect.fn("pr.fetchChecksForCommand")(function* (
|
|
645
|
+
pr: number | null,
|
|
646
|
+
watch: boolean,
|
|
647
|
+
failFast: boolean,
|
|
648
|
+
timeoutSeconds: number,
|
|
649
|
+
) {
|
|
650
|
+
if (!watch) {
|
|
651
|
+
return yield* fetchChecks(pr, false, failFast, timeoutSeconds);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
const watchedChecks = yield* fetchChecks(pr, true, failFast, timeoutSeconds).pipe(
|
|
655
|
+
Effect.result,
|
|
656
|
+
Effect.flatMap((result) => {
|
|
657
|
+
if (Result.isFailure(result) && result.failure._tag !== "GitHubCommandError") {
|
|
658
|
+
return Effect.fail(result.failure);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
return Effect.succeed(result);
|
|
662
|
+
}),
|
|
663
|
+
);
|
|
664
|
+
|
|
665
|
+
if (Result.isSuccess(watchedChecks)) {
|
|
666
|
+
return watchedChecks.success;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
const finalChecks = yield* fetchCheckResults(pr);
|
|
670
|
+
if (finalChecks.some((check) => check.bucket === "fail")) {
|
|
671
|
+
return yield* buildFailedChecksReport(pr, finalChecks);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return yield* Effect.fail(watchedChecks.failure);
|
|
465
675
|
});
|
|
466
676
|
|
|
467
677
|
export const rerunChecks = Effect.fn("pr.rerunChecks")(function* (
|
package/src/gh-tool/service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
2
|
-
import { Effect, Layer,
|
|
2
|
+
import { Context, Effect, Layer, Stream } from "effect";
|
|
3
3
|
|
|
4
4
|
import type { RepoInfo } from "./types";
|
|
5
5
|
|
|
@@ -15,7 +15,7 @@ type GhResult = {
|
|
|
15
15
|
|
|
16
16
|
type GhError = GitHubCommandError | GitHubAuthError | GitHubNotFoundError;
|
|
17
17
|
|
|
18
|
-
export class GitHubService extends
|
|
18
|
+
export class GitHubService extends Context.Service<
|
|
19
19
|
GitHubService,
|
|
20
20
|
{
|
|
21
21
|
readonly runGh: (args: string[]) => Effect.Effect<GhResult, GhError>;
|
package/src/gh-tool/types.ts
CHANGED
|
@@ -62,6 +62,62 @@ export type CheckResult = {
|
|
|
62
62
|
link: string;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
+
export type FailedCheckJob = {
|
|
66
|
+
name: string;
|
|
67
|
+
status: string;
|
|
68
|
+
conclusion: string | null;
|
|
69
|
+
url: string;
|
|
70
|
+
failedSteps: string[];
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type FailedCheckRunContext = {
|
|
74
|
+
runId: number;
|
|
75
|
+
url: string | null;
|
|
76
|
+
workflowName: string | null;
|
|
77
|
+
status: string;
|
|
78
|
+
conclusion: string | null;
|
|
79
|
+
failedJobs: FailedCheckJob[];
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type FailedCheckDetail = CheckResult & {
|
|
83
|
+
runId: number | null;
|
|
84
|
+
run: FailedCheckRunContext | null;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export type FailedChecksReport = {
|
|
88
|
+
status: "failed" | "no_failures";
|
|
89
|
+
message: string;
|
|
90
|
+
summary: {
|
|
91
|
+
total: number;
|
|
92
|
+
failed: number;
|
|
93
|
+
pending: number;
|
|
94
|
+
passed: number;
|
|
95
|
+
};
|
|
96
|
+
failedChecks: FailedCheckDetail[];
|
|
97
|
+
pendingChecks: CheckResult[];
|
|
98
|
+
hint: string;
|
|
99
|
+
nextCommands: string[];
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export type WorkflowRunDetail = {
|
|
103
|
+
databaseId: number;
|
|
104
|
+
url: string;
|
|
105
|
+
workflowName: string | null;
|
|
106
|
+
status: string;
|
|
107
|
+
conclusion: string | null;
|
|
108
|
+
jobs: Array<{
|
|
109
|
+
name: string;
|
|
110
|
+
status: string;
|
|
111
|
+
conclusion: string | null;
|
|
112
|
+
url: string;
|
|
113
|
+
steps: Array<{
|
|
114
|
+
name: string;
|
|
115
|
+
status: string;
|
|
116
|
+
conclusion: string | null;
|
|
117
|
+
}>;
|
|
118
|
+
}>;
|
|
119
|
+
};
|
|
120
|
+
|
|
65
121
|
export type MergeResult = {
|
|
66
122
|
merged: boolean;
|
|
67
123
|
strategy: MergeStrategy;
|
package/src/k8s-tool/service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
2
|
-
import { Effect, Layer, Option, Ref,
|
|
2
|
+
import { Context, Effect, Layer, Option, Ref, Stream } from "effect";
|
|
3
3
|
|
|
4
4
|
import type { CommandResult, Environment } from "./types";
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@ import { ConfigService, getToolConfig } from "#config";
|
|
|
13
13
|
import type { K8sConfig } from "#config";
|
|
14
14
|
import { isKubectlCommandAllowed } from "./security";
|
|
15
15
|
|
|
16
|
-
export class K8sService extends
|
|
16
|
+
export class K8sService extends Context.Service<
|
|
17
17
|
K8sService,
|
|
18
18
|
{
|
|
19
19
|
readonly runCommand: (
|
package/src/logs-tool/service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
|
|
2
|
-
import { Effect, Layer, Result,
|
|
2
|
+
import { Context, Effect, Layer, Result, Stream } from "effect";
|
|
3
3
|
|
|
4
4
|
import type { Environment, LogFile, ReadOptions } from "./types";
|
|
5
5
|
|
|
@@ -47,7 +47,7 @@ export const sanitizeShellArg = (input: string): string => `'${input.replace(/'/
|
|
|
47
47
|
|
|
48
48
|
const readCommandOutput = (output: unknown): string => (typeof output === "string" ? output : "");
|
|
49
49
|
|
|
50
|
-
export class LogsService extends
|
|
50
|
+
export class LogsService extends Context.Service<
|
|
51
51
|
LogsService,
|
|
52
52
|
{
|
|
53
53
|
readonly listLogs: (env: Environment, profile?: string) => Effect.Effect<LogFile[], LogsError>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Layer
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -38,7 +38,7 @@ export const resolveSessionsPath = Effect.gen(function* () {
|
|
|
38
38
|
/**
|
|
39
39
|
* Context tag for resolved paths (cached during effect execution).
|
|
40
40
|
*/
|
|
41
|
-
export class ResolvedPaths extends
|
|
41
|
+
export class ResolvedPaths extends Context.Service<
|
|
42
42
|
ResolvedPaths,
|
|
43
43
|
{
|
|
44
44
|
readonly messagesPath: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Layer
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
2
|
import { readdir } from "node:fs/promises";
|
|
3
3
|
|
|
4
4
|
import type { MessageSummary, SessionInfo } from "./types";
|
|
@@ -142,7 +142,7 @@ const readJsonFilesFlat = (dir: string): Effect.Effect<FileEntry[], SessionError
|
|
|
142
142
|
}),
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
-
export class SessionService extends
|
|
145
|
+
export class SessionService extends Context.Service<
|
|
146
146
|
SessionService,
|
|
147
147
|
{
|
|
148
148
|
readonly getSessionsForProject: (
|
package/src/shared/audit.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { mkdirSync } from "node:fs";
|
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { basename, dirname, join } from "node:path";
|
|
5
5
|
|
|
6
|
-
import { Cause, Effect, Layer
|
|
6
|
+
import { Cause, Context, Effect, Layer } from "effect";
|
|
7
7
|
|
|
8
8
|
import { loadConfig } from "#config";
|
|
9
9
|
|
|
@@ -65,7 +65,7 @@ type TableInfoRow = {
|
|
|
65
65
|
name: string;
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
-
export class AuditService extends
|
|
68
|
+
export class AuditService extends Context.Service<AuditService, AuditServiceShape>()(
|
|
69
69
|
"@agent-tools/AuditService",
|
|
70
70
|
) {}
|
|
71
71
|
|