Skip to content

Commit 660d3f0

Browse files
xesrevinuGit Agent
andcommitted
refactor(shared): align types and imports across modules
- Add optional cause to ConfigError and other error schemas - Comment out ApiError formatting path in error formatter - Adjust imports and TS path suffixes to .ts extensions - Refactor process result types and error handling with Effect - Stabilize progress config typings and label keys to match new enums refactor that updates shared module typings and imports, and improves error handling paths and process typings. the changes align extensions and optional fields to support more robust error information. Co-Authored-By: Git Agent <noreply@git-agent.dev>
1 parent 664a26d commit 660d3f0

6 files changed

Lines changed: 111 additions & 105 deletions

File tree

src/shared/errors.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export class CliUsageError extends Schema.TaggedErrorClass<CliUsageError>()("Cli
88

99
export class ConfigError extends Schema.TaggedErrorClass<ConfigError>()("ConfigError", {
1010
message: Schema.String,
11+
cause: Schema.optional(Schema.Unknown),
1112
}) {
1213
static is = Schema.is(this);
1314
}
@@ -28,6 +29,7 @@ export class ApiError extends Schema.TaggedErrorClass<ApiError>()("ApiError", {
2829
message: Schema.String,
2930
status: Schema.optional(Schema.Number),
3031
body: Schema.optional(Schema.String),
32+
cause: Schema.optional(Schema.Unknown),
3133
}) {
3234
static is = Schema.is(this);
3335
}
@@ -65,16 +67,16 @@ export const renderError = (error: unknown): string => {
6567
if (ConfigError.is(error)) {
6668
return error.message;
6769
}
68-
if (ApiError.is(error)) {
69-
const parts = [error.message];
70-
if (typeof error.status === "number") {
71-
parts.push(`status: ${error.status}`);
72-
}
73-
if (typeof error.body === "string" && error.body.trim().length > 0) {
74-
parts.push(error.body.trim());
75-
}
76-
return parts.join("\n");
77-
}
70+
// if (ApiError.is(error)) {
71+
// const parts = [error.message];
72+
// if (typeof error.status === "number") {
73+
// parts.push(`status: ${error.status}`);
74+
// }
75+
// if (typeof error.body === "string" && error.body.trim().length > 0) {
76+
// parts.push(error.body.trim());
77+
// }
78+
// return parts.join("\n");
79+
// }
7880
if (ProcessExecutionError.is(error)) {
7981
const details = error.stderr.trim().length > 0 ? error.stderr.trim() : error.stdout.trim();
8082
return `${error.command} exited with code ${error.exitCode}${details.length > 0 ? `\n${details}` : ""}`;

src/shared/output.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Console, Effect } from "effect";
2-
import type { SingleCommitResult } from "../domain/commit";
2+
import type { SingleCommitResult } from "../domain/commit.ts";
33

44
const indent = (value: string, prefix = " "): string =>
55
value

src/shared/process.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
import { Effect, Stream } from "effect";
1+
import { Effect, Schema, Stream } from "effect";
22
import { ChildProcess } from "effect/unstable/process";
3-
import { ProcessExecutionError } from "./errors";
3+
import { ProcessExecutionError } from "./errors.ts";
44

5-
export interface ProcessResult {
6-
readonly stdout: string;
7-
readonly stderr: string;
8-
readonly exitCode: number;
9-
}
5+
export const ProcessResult = Schema.Struct({
6+
stdout: Schema.String,
7+
stderr: Schema.String,
8+
exitCode: Schema.Number,
9+
});
10+
11+
export type ProcessResult = typeof ProcessResult.Type;
1012

1113
export interface RunProcessOptions {
1214
readonly command: string;
13-
readonly args?: ReadonlyArray<string>;
14-
readonly cwd?: string;
15-
readonly env?: Record<string, string | undefined>;
16-
readonly stdin?: string;
17-
readonly allowFailure?: boolean;
15+
readonly args?: ReadonlyArray<string> | undefined;
16+
readonly cwd?: string | undefined;
17+
readonly env?: Record<string, string | undefined> | undefined;
18+
readonly stdin?: string | undefined;
19+
readonly allowFailure?: boolean | undefined;
1820
}
1921

2022
const encoder = new TextEncoder();
@@ -70,8 +72,8 @@ export const runProcess = ({
7072
}).pipe(
7173
Effect.catch((cause) =>
7274
ProcessExecutionError.is(cause)
73-
? Effect.failSync(() => cause)
74-
: Effect.failSync(() => toProcessExecutionError(command, args, cause)),
75+
? Effect.fail(cause)
76+
: Effect.fail(toProcessExecutionError(command, args, cause)),
7577
),
7678
),
7779
);

src/shared/progress-config.ts

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ProgressAttributeDescriptor, ProgressRenderConfig } from "./tracing";
1+
import type { ProgressAttributeDescriptor, ProgressRenderConfig } from "./tracing.ts";
22

33
const hiddenAttributePrefixes = ["http.request.header.", "http.response.header."];
44

@@ -18,7 +18,6 @@ const hiddenAttributeKeys = new Set([
1818

1919
const orderedInteractiveAttributeKeys = [
2020
"vcs",
21-
"requested_vcs",
2221
"dry_run",
2322
"no_stage",
2423
"amend",
@@ -57,32 +56,21 @@ const interactiveLabelByKey: Record<string, string> = {
5756
};
5857

5958
const friendlySpanNames: Record<string, string> = {
60-
"commit.prepare-request": "Prepare commit",
61-
"commit.run": "Run commit",
62-
"commit.resolve-provider": "Resolve provider",
63-
"commit.load-project-config": "Load project config",
64-
"commit.scan-changes": "Scan changes",
65-
"commit.plan-groups": "Plan commits",
66-
"commit.resolve-message": "Resolve commit message",
67-
"commit.refresh-scopes": "Refresh scopes",
68-
"commit.replan-groups": "Replan commits",
69-
"commit.generate-message": "Generate commit message",
70-
"commit.run-hooks": "Run commit hooks",
71-
"commit.create": "Create commit",
72-
"commit.load-previous": "Load previous commit",
73-
"commit.generate-amend-message": "Generate amended message",
74-
"commit.amend": "Amend commit",
75-
"init.run": "Run init",
76-
"init.resolve-provider": "Resolve provider",
77-
"init.initialize-repository": "Initialize repository",
78-
"init.generate-gitignore": "Generate .gitignore",
79-
"init.generate-scopes": "Generate scopes",
80-
"init.write-default-hook": "Write default hook",
81-
"init.write-hook": "Write hook config",
82-
"init.write-project-config": "Write project config",
83-
"config.resolve-provider": "Resolve provider config",
84-
"config.resolve-field": "Resolve config value",
85-
"hooks.execute": "Run hook",
59+
"Commit.ScanChanges": "Scan changes",
60+
"Commit.PlanGroups": "Plan commits",
61+
"Commit.ResolveMessage": "Resolve commit message",
62+
"Commit.ReplanGroups": "Replan commits",
63+
"Commit.Create": "Create commit",
64+
"Commit.create": "Create commit",
65+
"Commit.LoadPrevious": "Load previous commit",
66+
"Commit.Amend": "Amend commit",
67+
"Config.GenerateGitignore": "Generate .gitignore",
68+
"Config.GenerateScopes": "Generate scopes",
69+
"Config.ResolveProvider": "Resolve provider",
70+
"Init.WriteDefaultHook": "Write default hook",
71+
"Init.WriteHook": "Write hook config",
72+
"LLM.GenerateMessage": "Generate commit message",
73+
"LLM.PlanCommits": "Plan commits",
8674
"LanguageModel.generateText": "Call model",
8775
};
8876

@@ -141,7 +129,7 @@ const toDescriptors = (
141129
key: string,
142130
value: unknown,
143131
label = simplifyInteractiveLabel(key),
144-
dedupeKey?: string,
132+
dedupeKey?: string | undefined,
145133
) => {
146134
if (value === undefined || value === null) {
147135
return;

src/shared/text.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Trailer } from "../domain/commit";
1+
import type { Trailer } from "../domain/commit.ts";
22

33
export const countLines = (content: string): number => {
44
if (content.length === 0) {

src/shared/tracing.ts

Lines changed: 64 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { clearScreenDown, cursorTo, moveCursor } from "node:readline";
2-
import { Cause, Duration, Effect, Exit, Layer, ServiceMap, Tracer } from "effect";
3-
import { renderError } from "./errors";
2+
import { Cause, Duration, Effect, Exit, Layer, Schema, ServiceMap, Tracer } from "effect";
3+
import { renderError } from "./errors.ts";
44

55
type ProgressStatus = "running" | "done" | "failed" | "interrupted";
66

@@ -34,59 +34,73 @@ interface CompactAttributeToken {
3434

3535
export type ProgressRenderMode = "interactive" | "raw";
3636

37-
export interface ProgressAttributeDescriptor {
38-
readonly key: string;
39-
readonly label?: string;
40-
readonly value: unknown;
41-
readonly dedupeKey?: string;
42-
}
37+
export const ProgressAttributeDescriptor = Schema.Struct({
38+
key: Schema.String,
39+
label: Schema.optionalKey(Schema.String),
40+
value: Schema.Unknown,
41+
dedupeKey: Schema.optionalKey(Schema.String),
42+
});
4343

44-
export interface ProgressAttributeFormatInput {
45-
readonly key: string;
46-
readonly value: unknown;
47-
readonly defaultLabel: string;
48-
}
44+
export type ProgressAttributeDescriptor = typeof ProgressAttributeDescriptor.Type;
4945

50-
export interface ProgressAttributeFormatOutput {
51-
readonly label?: string;
52-
readonly value?: unknown;
53-
readonly dedupeKey?: string;
54-
}
46+
export const ProgressAttributeFormatInput = Schema.Struct({
47+
key: Schema.String,
48+
value: Schema.Unknown,
49+
defaultLabel: Schema.String,
50+
});
5551

56-
export interface ProgressStatusSymbols {
57-
readonly runningParent: string;
58-
readonly success: string;
59-
readonly failed: string;
60-
readonly interrupted: string;
61-
}
52+
export type ProgressAttributeFormatInput = typeof ProgressAttributeFormatInput.Type;
53+
54+
export const ProgressAttributeFormatOutput = Schema.Struct({
55+
label: Schema.optionalKey(Schema.String),
56+
value: Schema.optionalKey(Schema.Unknown),
57+
dedupeKey: Schema.optionalKey(Schema.String),
58+
});
59+
60+
export type ProgressAttributeFormatOutput = typeof ProgressAttributeFormatOutput.Type;
61+
62+
export const ProgressStatusSymbols = Schema.Struct({
63+
runningParent: Schema.String,
64+
success: Schema.String,
65+
failed: Schema.String,
66+
interrupted: Schema.String,
67+
});
68+
69+
export type ProgressStatusSymbols = typeof ProgressStatusSymbols.Type;
6270

6371
export interface ProgressRenderConfig {
64-
readonly headerLabel?: string;
65-
readonly spinnerFrames?: ReadonlyArray<string>;
66-
readonly symbols?: Partial<ProgressStatusSymbols>;
67-
readonly formatSpanName?: (
68-
name: string,
69-
options: {
70-
readonly mode: ProgressRenderMode;
71-
readonly span: Tracer.Span;
72-
},
73-
) => string;
74-
readonly formatAttributes?: (
75-
input: {
76-
readonly attributes: ReadonlyMap<string, unknown>;
77-
},
78-
options: {
79-
readonly mode: ProgressRenderMode;
80-
readonly span: Tracer.Span;
81-
},
82-
) => ReadonlyArray<ProgressAttributeDescriptor> | undefined;
83-
readonly formatAttribute?: (
84-
attribute: ProgressAttributeFormatInput,
85-
options: {
86-
readonly mode: ProgressRenderMode;
87-
readonly span: Tracer.Span;
88-
},
89-
) => ProgressAttributeFormatOutput | undefined;
72+
readonly headerLabel?: string | undefined;
73+
readonly spinnerFrames?: ReadonlyArray<string> | undefined;
74+
readonly symbols?: Partial<ProgressStatusSymbols> | undefined;
75+
readonly formatSpanName?:
76+
| ((
77+
name: string,
78+
options: {
79+
readonly mode: ProgressRenderMode;
80+
readonly span: Tracer.Span;
81+
},
82+
) => string)
83+
| undefined;
84+
readonly formatAttributes?:
85+
| ((
86+
input: {
87+
readonly attributes: ReadonlyMap<string, unknown>;
88+
},
89+
options: {
90+
readonly mode: ProgressRenderMode;
91+
readonly span: Tracer.Span;
92+
},
93+
) => ReadonlyArray<ProgressAttributeDescriptor> | undefined)
94+
| undefined;
95+
readonly formatAttribute?:
96+
| ((
97+
attribute: ProgressAttributeFormatInput,
98+
options: {
99+
readonly mode: ProgressRenderMode;
100+
readonly span: Tracer.Span;
101+
},
102+
) => ProgressAttributeFormatOutput | undefined)
103+
| undefined;
90104
}
91105

92106
const defaultHeaderLabel = "progress";

0 commit comments

Comments
 (0)