@samaksh/git-worker 0.1.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.
Files changed (47) hide show
  1. package/dist/cli/index.js +1 -1
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.js +3 -0
  4. package/dist/services/git/reader.js +105 -34
  5. package/dist/services/workspace/manager.js +1 -1
  6. package/dist/stages/eligibility.js +38 -14
  7. package/dist/stages/select.js +46 -37
  8. package/package.json +11 -1
  9. package/GIT_WORKER_PROJECT_PLAN.md +0 -499
  10. package/demo/README.md +0 -58
  11. package/demo/index.ts +0 -526
  12. package/src/app.ts +0 -69
  13. package/src/cli/commands.ts +0 -142
  14. package/src/cli/index.ts +0 -123
  15. package/src/config/defaults.ts +0 -46
  16. package/src/config/load.ts +0 -70
  17. package/src/config/schema.ts +0 -48
  18. package/src/core/errors.ts +0 -45
  19. package/src/core/pipeline.ts +0 -17
  20. package/src/core/types.ts +0 -188
  21. package/src/services/editor/index.ts +0 -85
  22. package/src/services/git/ops.ts +0 -170
  23. package/src/services/git/reader.ts +0 -148
  24. package/src/services/report/index.ts +0 -104
  25. package/src/services/review/index.ts +0 -80
  26. package/src/services/state/index.ts +0 -77
  27. package/src/services/template/env.ts +0 -169
  28. package/src/services/template/interpolator.ts +0 -109
  29. package/src/services/template/transform.ts +0 -97
  30. package/src/services/template/validator.ts +0 -75
  31. package/src/services/workspace/cache.ts +0 -144
  32. package/src/services/workspace/manager.ts +0 -370
  33. package/src/stages/apply.ts +0 -194
  34. package/src/stages/edit-template.ts +0 -227
  35. package/src/stages/eligibility.ts +0 -67
  36. package/src/stages/load-template.ts +0 -188
  37. package/src/stages/plan.ts +0 -362
  38. package/src/stages/push.ts +0 -120
  39. package/src/stages/report.ts +0 -126
  40. package/src/stages/resolve-project.ts +0 -341
  41. package/src/stages/review.ts +0 -228
  42. package/src/stages/select.ts +0 -302
  43. package/src/stages/sync.ts +0 -63
  44. package/src/utils/hash.ts +0 -15
  45. package/src/utils/ui.ts +0 -137
  46. package/src/utils/which.ts +0 -18
  47. package/tsconfig.json +0 -18
@@ -1,142 +0,0 @@
1
- import chalk from "chalk";
2
- import { clack, sectionHeader, statusLine } from "../utils/ui.js";
3
- import {
4
- listCachedProjects,
5
- clearProjectCache,
6
- clearAllCache,
7
- } from "../services/workspace/cache.js";
8
- import { getWorkspaceRoot } from "../services/workspace/manager.js";
9
-
10
- export async function handleCacheList(): Promise<void> {
11
- const root = getWorkspaceRoot();
12
- sectionHeader("Cached Projects (~/.git-worker)");
13
-
14
- const projects = await listCachedProjects();
15
- if (projects.length === 0) {
16
- console.log("");
17
- clack.log.info(`No cached repositories found in ${root}/projects`);
18
- console.log("");
19
- return;
20
- }
21
-
22
- console.log("");
23
- console.log(
24
- chalk.bold(
25
- ` ${"Name".padEnd(20)} ${"Remote URL / Path".padEnd(46)} Cached Date`
26
- )
27
- );
28
- console.log(chalk.gray(" " + "─".repeat(80)));
29
-
30
- for (const p of projects) {
31
- const name = chalk.cyan(p.name.slice(0, 18).padEnd(20));
32
- const target = (p.remoteUrl || p.sourceRepoPath || "(unknown)").slice(0, 44).padEnd(46);
33
- const date = p.createdAt ? p.createdAt.slice(0, 10) : "unknown";
34
- console.log(` ${name} ${chalk.white(target)} ${chalk.gray(date)}`);
35
- }
36
-
37
- console.log(chalk.gray(" " + "─".repeat(80)));
38
- console.log(
39
- chalk.gray(
40
- ` Total: ${projects.length} repository/repositories cached in ${root}/projects`
41
- )
42
- );
43
- console.log("");
44
- }
45
-
46
- export async function handleCacheClean(
47
- target?: string,
48
- options?: { all?: boolean; yes?: boolean; force?: boolean }
49
- ): Promise<void> {
50
- const root = getWorkspaceRoot();
51
- const projects = await listCachedProjects();
52
-
53
- if (projects.length === 0) {
54
- clack.log.info(`No cached repositories found in ${root}/projects`);
55
- return;
56
- }
57
-
58
- const skipConfirm = options?.yes || options?.force || Boolean(process.env.CI);
59
-
60
- // 1. If explicit --all flag provided
61
- if (options?.all) {
62
- if (!skipConfirm) {
63
- const confirm = await clack.confirm({
64
- message: `Are you sure you want to remove ALL ${projects.length} cached project(s) from ${root}?`,
65
- initialValue: true,
66
- });
67
- if (clack.isCancel(confirm) || !confirm) {
68
- clack.log.warn("Cache clean cancelled.");
69
- return;
70
- }
71
- }
72
-
73
- const result = await clearAllCache();
74
- if (!result.ok) {
75
- clack.log.error(result.error.message);
76
- process.exit(1);
77
- }
78
- statusLine("ok", `Cleared all cached projects (${result.value.count} removed)`);
79
- return;
80
- }
81
-
82
- // 2. If a specific target ID / URL / path was passed as positional argument
83
- if (target) {
84
- const result = await clearProjectCache(target);
85
- if (!result.ok) {
86
- clack.log.error(result.error.message);
87
- process.exit(1);
88
- }
89
- statusLine("ok", `Removed cache for: ${result.value.removed}`);
90
- return;
91
- }
92
-
93
- // 3. Interactive prompt
94
- sectionHeader("Clean Cache");
95
-
96
- const choice = await clack.select<string>({
97
- message: "Select cache to remove:",
98
- options: [
99
- {
100
- value: "__ALL__",
101
- label: `Clear ALL cached projects (${projects.length} projects)`,
102
- hint: `removes all checkouts in ${root}/projects`,
103
- },
104
- ...projects.map((p) => ({
105
- value: p.id,
106
- label: `${p.name} (${p.remoteUrl || p.sourceRepoPath})`,
107
- hint: `ID: ${p.id} (${p.createdAt ? p.createdAt.slice(0, 10) : ""})`,
108
- })),
109
- ],
110
- });
111
-
112
- if (clack.isCancel(choice)) {
113
- clack.log.warn("Cancelled.");
114
- return;
115
- }
116
-
117
- if (choice === "__ALL__") {
118
- const confirm = await clack.confirm({
119
- message: `Are you sure you want to remove ALL ${projects.length} cached project(s)?`,
120
- initialValue: true,
121
- });
122
- if (clack.isCancel(confirm) || !confirm) {
123
- clack.log.warn("Cancelled.");
124
- return;
125
- }
126
- const result = await clearAllCache();
127
- if (!result.ok) {
128
- clack.log.error(result.error.message);
129
- process.exit(1);
130
- }
131
- statusLine("ok", `Cleared all cached projects (${result.value.count} removed)`);
132
- return;
133
- }
134
-
135
- // Specific selected project
136
- const result = await clearProjectCache(choice);
137
- if (!result.ok) {
138
- clack.log.error(result.error.message);
139
- process.exit(1);
140
- }
141
- statusLine("ok", `Removed cache for: ${result.value.removed}`);
142
- }
package/src/cli/index.ts DELETED
@@ -1,123 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from "commander";
3
- import { run } from "../app.js";
4
- import { handleCacheList, handleCacheClean } from "./commands.js";
5
- import chalk from "chalk";
6
-
7
- const program = new Command();
8
-
9
- program
10
- .name("git-worker")
11
- .description("Safe, composable CLI/TUI for applying reviewed file changes across many Git branches")
12
- .version("0.1.0")
13
- .option("-r, --repo <path>", "Repository path or remote URL (default: current directory)")
14
- .option("-c, --cached", "Select from previously cloned and cached repositories")
15
- .option("-b, --branch <pattern>", "Branch pattern — glob (uat/*) or regex (/uat.*/)")
16
- .option("-i, --invert-branch", "Invert the branch selection pattern")
17
- .option("-f, --file <path>", "Target file path inside the repository (e.g. .env)")
18
- .option("-e, --editor <name>", "Editor to use: code (VS Code) or vim")
19
- .option("-m, --commit-msg <message>", "Commit message")
20
- .option("-p, --push <policy>", "Push policy: prompt (default) | always | never")
21
- .option("--remote <name>", "Git remote name (default: origin)")
22
- .option("--auto-approve", "Auto-approve all changes (skip interactive review)")
23
- .option("--ci", "CI mode: non-interactive, fail on missing dynamic values")
24
- .action(async (opts) => {
25
- // Validate push policy
26
- if (opts.push && !["prompt", "always", "never"].includes(opts.push)) {
27
- console.error(chalk.red(` ✗ Invalid push policy '${opts.push}'. Must be: prompt | always | never`));
28
- process.exit(1);
29
- }
30
-
31
- // Validate incompatible combinations
32
- if (opts.ci && opts.push === "prompt") {
33
- console.error(chalk.yellow(` ⚠ Warning: --ci with --push prompt will not push (no interactive prompt in CI). Use --push always or --push never.`));
34
- }
35
-
36
- try {
37
- const result = await run({
38
- repo: opts.repo,
39
- cached: opts.cached ?? false,
40
- branch: opts.branch,
41
- invertBranch: opts.invertBranch ?? false,
42
- file: opts.file,
43
- editor: opts.editor,
44
- commitMsg: opts.commitMsg,
45
- push: opts.push as "prompt" | "always" | "never" | undefined,
46
- remote: opts.remote,
47
- autoApprove: opts.autoApprove ?? false,
48
- ci: opts.ci ?? false,
49
- });
50
-
51
- if (!result.ok) {
52
- const { error } = result;
53
- if (error.category === "INPUT_CANCELLED") {
54
- console.log(chalk.gray("\n Cancelled."));
55
- process.exit(0);
56
- }
57
- console.error(chalk.red(`\n ✗ [${error.category}] ${error.message}`));
58
- process.exit(1);
59
- }
60
-
61
- process.exit(0);
62
- } catch (e: any) {
63
- console.error(chalk.red(`\n ✗ Fatal: ${e.message}`));
64
- if (process.env.DEBUG) {
65
- console.error(e.stack);
66
- }
67
- process.exit(1);
68
- }
69
- });
70
-
71
- // ── Cache management subcommands ──────────────────────────────────────────
72
-
73
- const cacheCmd = program
74
- .command("cache")
75
- .description("Manage git-worker's cached workspaces and repositories (~/.git-worker)");
76
-
77
- cacheCmd
78
- .command("list")
79
- .alias("ls")
80
- .description("List all cached projects")
81
- .action(async () => {
82
- try {
83
- await handleCacheList();
84
- process.exit(0);
85
- } catch (e: any) {
86
- console.error(chalk.red(` ✗ Error: ${e.message}`));
87
- process.exit(1);
88
- }
89
- });
90
-
91
- cacheCmd
92
- .command("clean [target]")
93
- .alias("clear")
94
- .description("Clean workspace cache (all or a specific project)")
95
- .option("-a, --all", "Clean all cached projects")
96
- .option("-y, --yes", "Skip confirmation prompt")
97
- .action(async (target, opts) => {
98
- try {
99
- await handleCacheClean(target, opts);
100
- process.exit(0);
101
- } catch (e: any) {
102
- console.error(chalk.red(` ✗ Error: ${e.message}`));
103
- process.exit(1);
104
- }
105
- });
106
-
107
- // Convenient top-level alias: git-worker clean [target] [-a]
108
- program
109
- .command("clean [target]")
110
- .description("Shorthand to clean cached workspace(s)")
111
- .option("-a, --all", "Clean all cached projects")
112
- .option("-y, --yes", "Skip confirmation prompt")
113
- .action(async (target, opts) => {
114
- try {
115
- await handleCacheClean(target, opts);
116
- process.exit(0);
117
- } catch (e: any) {
118
- console.error(chalk.red(` ✗ Error: ${e.message}`));
119
- process.exit(1);
120
- }
121
- });
122
-
123
- program.parse();
@@ -1,46 +0,0 @@
1
- import { AppConfig } from "./schema.js";
2
-
3
- export const DEFAULT_CONFIG: AppConfig = {
4
- git: {
5
- remote: "origin",
6
- fetchPrune: true,
7
- cleanMode: "tracked-and-untracked",
8
- pushPolicy: "prompt",
9
- commitMessage: "chore: sync configuration",
10
- },
11
- workspace: {
12
- root: ".git-worker",
13
- lockTimeoutMs: 30000,
14
- },
15
- editor: {
16
- name: "code",
17
- editCommand: ["code", "--wait", "{file}"],
18
- diffCommand: ["code", "--diff", "{before}", "{after}"],
19
- },
20
- template: {
21
- placeholderOpen: "{",
22
- placeholderClose: "}",
23
- missingValuePolicy: "prompt-each-branch",
24
- emptyValueIsPresent: true,
25
- unmanagedKeyPolicy: "preserve",
26
- removedTemplateKeyPolicy: "preserve",
27
- },
28
- review: {
29
- autoApprove: false,
30
- readOnlySnapshots: true,
31
- },
32
- execution: {
33
- concurrency: 1,
34
- stopOnBranchError: false,
35
- },
36
- report: {
37
- writeJson: false,
38
- writeMarkdown: false,
39
- redactValues: true,
40
- warnOnSecrets: true,
41
- },
42
- safety: {
43
- rejectNoRemote: true,
44
- saveOnPartialSuccess: true,
45
- },
46
- };
@@ -1,70 +0,0 @@
1
- import { AppConfig, AppConfigSchema } from "./schema.js";
2
- import { DEFAULT_CONFIG } from "./defaults.js";
3
- import { CliInput } from "../core/types.js";
4
- import { existsSync, readFileSync } from "fs";
5
- import { join, resolve } from "path";
6
-
7
- function loadProjectConfig(repoPath: string): Partial<AppConfig> {
8
- const candidates = [
9
- join(resolve(repoPath), "git-worker.config.json"),
10
- join(resolve(repoPath), ".git-worker.config.json"),
11
- ];
12
- for (const candidate of candidates) {
13
- if (existsSync(candidate)) {
14
- try {
15
- const raw = readFileSync(candidate, "utf-8");
16
- return JSON.parse(raw) as Partial<AppConfig>;
17
- } catch {
18
- // ignore malformed
19
- }
20
- }
21
- }
22
- return {};
23
- }
24
-
25
- function deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T {
26
- const result = { ...base };
27
- for (const key of Object.keys(override) as (keyof T)[]) {
28
- const overrideVal = override[key];
29
- if (overrideVal === undefined) continue;
30
- if (
31
- typeof overrideVal === "object" &&
32
- overrideVal !== null &&
33
- !Array.isArray(overrideVal) &&
34
- typeof result[key] === "object" &&
35
- result[key] !== null
36
- ) {
37
- result[key] = deepMerge(result[key] as Record<string, unknown>, overrideVal as Record<string, unknown>) as T[keyof T];
38
- } else {
39
- result[key] = overrideVal as T[keyof T];
40
- }
41
- }
42
- return result;
43
- }
44
-
45
- export function loadConfig(cliInput: CliInput): AppConfig {
46
- // Load project config from repo directory
47
- const repoPath = cliInput.repo || process.cwd();
48
- const projectConfig = loadProjectConfig(repoPath);
49
-
50
- // Merge: defaults < project config < CLI overrides
51
- const cliOverrides: Partial<AppConfig> = {
52
- git: {
53
- ...DEFAULT_CONFIG.git,
54
- ...(cliInput.push ? { pushPolicy: cliInput.push } : {}),
55
- ...(cliInput.commitMsg ? { commitMessage: cliInput.commitMsg } : {}),
56
- ...(cliInput.remote ? { remote: cliInput.remote } : {}),
57
- },
58
- editor: {
59
- ...DEFAULT_CONFIG.editor,
60
- ...(cliInput.editor ? { name: cliInput.editor } : {}),
61
- },
62
- review: {
63
- ...DEFAULT_CONFIG.review,
64
- ...(cliInput.autoApprove !== undefined ? { autoApprove: cliInput.autoApprove } : {}),
65
- },
66
- };
67
-
68
- const merged = deepMerge(deepMerge(DEFAULT_CONFIG as Record<string, unknown>, projectConfig as Record<string, unknown>) as AppConfig, cliOverrides);
69
- return Object.freeze(AppConfigSchema.parse(merged)) as AppConfig;
70
- }
@@ -1,48 +0,0 @@
1
- import { z } from "zod";
2
-
3
- export const AppConfigSchema = z.object({
4
- git: z.object({
5
- remote: z.string().default("origin"),
6
- fetchPrune: z.boolean().default(true),
7
- cleanMode: z.enum(["tracked-and-untracked", "tracked-only"]).default("tracked-and-untracked"),
8
- pushPolicy: z.enum(["prompt", "always", "never"]).default("prompt"),
9
- commitMessage: z.string().default("chore: sync configuration"),
10
- }),
11
- workspace: z.object({
12
- root: z.string().default(".git-worker"),
13
- lockTimeoutMs: z.number().default(30000),
14
- }),
15
- editor: z.object({
16
- name: z.string().default("code"),
17
- editCommand: z.array(z.string()).default(["code", "--wait", "{file}"]),
18
- diffCommand: z.array(z.string()).default(["code", "--diff", "{before}", "{after}"]),
19
- }),
20
- template: z.object({
21
- placeholderOpen: z.string().default("{"),
22
- placeholderClose: z.string().default("}"),
23
- missingValuePolicy: z.enum(["prompt-each-branch"]).default("prompt-each-branch"),
24
- emptyValueIsPresent: z.boolean().default(true),
25
- unmanagedKeyPolicy: z.enum(["preserve"]).default("preserve"),
26
- removedTemplateKeyPolicy: z.enum(["preserve"]).default("preserve"),
27
- }),
28
- review: z.object({
29
- autoApprove: z.boolean().default(false),
30
- readOnlySnapshots: z.boolean().default(true),
31
- }),
32
- execution: z.object({
33
- concurrency: z.number().default(1),
34
- stopOnBranchError: z.boolean().default(false),
35
- }),
36
- report: z.object({
37
- writeJson: z.boolean().default(false),
38
- writeMarkdown: z.boolean().default(false),
39
- redactValues: z.boolean().default(true),
40
- warnOnSecrets: z.boolean().default(true),
41
- }),
42
- safety: z.object({
43
- rejectNoRemote: z.boolean().default(true),
44
- saveOnPartialSuccess: z.boolean().default(true),
45
- }),
46
- });
47
-
48
- export type AppConfig = z.infer<typeof AppConfigSchema>;
@@ -1,45 +0,0 @@
1
- import { AppError } from "./types.js";
2
-
3
- export function configError(msg: string, details?: unknown): AppError {
4
- return new AppError("CONFIG", msg, details);
5
- }
6
-
7
- export function gitError(msg: string, details?: unknown): AppError {
8
- return new AppError("GIT", msg, details);
9
- }
10
-
11
- export function editorError(msg: string, details?: unknown): AppError {
12
- return new AppError("EDITOR", msg, details);
13
- }
14
-
15
- export function templateError(msg: string, details?: unknown): AppError {
16
- return new AppError("TEMPLATE", msg, details);
17
- }
18
-
19
- export function eligibilityError(msg: string, details?: unknown): AppError {
20
- return new AppError("ELIGIBILITY", msg, details);
21
- }
22
-
23
- export function inputCancelledError(msg: string, details?: unknown): AppError {
24
- return new AppError("INPUT_CANCELLED", msg, details);
25
- }
26
-
27
- export function stalePlanError(msg: string, details?: unknown): AppError {
28
- return new AppError("STALE_PLAN", msg, details);
29
- }
30
-
31
- export function applyError(msg: string, details?: unknown): AppError {
32
- return new AppError("APPLY", msg, details);
33
- }
34
-
35
- export function pushError(msg: string, details?: unknown): AppError {
36
- return new AppError("PUSH", msg, details);
37
- }
38
-
39
- export function workspaceError(msg: string, details?: unknown): AppError {
40
- return new AppError("WORKSPACE", msg, details);
41
- }
42
-
43
- export function validationError(msg: string, details?: unknown): AppError {
44
- return new AppError("VALIDATION", msg, details);
45
- }
@@ -1,17 +0,0 @@
1
- import { Result, AppError, ok } from "./types.js";
2
-
3
- export type Stage<C, D> = (context: C, deps: D) => Promise<Result<C, AppError>>;
4
-
5
- export function pipeline<C, D>(...stages: Stage<C, D>[]): Stage<C, D> {
6
- return async (initial: C, deps: D): Promise<Result<C, AppError>> => {
7
- let current = initial;
8
- for (const stage of stages) {
9
- const result = await stage(current, deps);
10
- if (!result.ok) {
11
- return result;
12
- }
13
- current = result.value;
14
- }
15
- return ok(current);
16
- };
17
- }
package/src/core/types.ts DELETED
@@ -1,188 +0,0 @@
1
- export type Result<T, E = AppError> =
2
- | { ok: true; value: T }
3
- | { ok: false; error: E };
4
-
5
- export type AppErrorCategory =
6
- | "CONFIG"
7
- | "GIT"
8
- | "EDITOR"
9
- | "TEMPLATE"
10
- | "ELIGIBILITY"
11
- | "INPUT_CANCELLED"
12
- | "STALE_PLAN"
13
- | "APPLY"
14
- | "PUSH"
15
- | "WORKSPACE"
16
- | "VALIDATION";
17
-
18
- export class AppError extends Error {
19
- category: AppErrorCategory;
20
- details?: unknown;
21
-
22
- constructor(category: AppErrorCategory, message: string, details?: unknown) {
23
- super(message);
24
- this.name = "AppError";
25
- this.category = category;
26
- this.details = details;
27
- }
28
- }
29
-
30
- export function ok<T>(value: T): Result<T> {
31
- return { ok: true, value };
32
- }
33
-
34
- export function err<E extends AppError>(error: E): Result<never, E> {
35
- return { ok: false, error };
36
- }
37
-
38
- export type BranchRef = {
39
- name: string;
40
- remote?: string;
41
- sha: string;
42
- isRemote: boolean;
43
- };
44
-
45
- export type TargetFile = {
46
- path: string;
47
- };
48
-
49
- export type TemplateEngineType = "env-reconcile" | "source-of-truth";
50
-
51
- export type TargetTemplate = {
52
- path: string;
53
- engine: TemplateEngineType;
54
- raw: string;
55
- parsedEnv?: TemplateDocument;
56
- variables?: Array<{ name: string; fallback?: string; raw: string }>;
57
- isNewFile?: boolean;
58
- };
59
-
60
- export type ManagedProject = {
61
- id: string;
62
- sourceRepoPath: string;
63
- remoteUrl?: string;
64
- managedRepoPath: string;
65
- stagingDir: string;
66
- stateDir: string;
67
- reportsDir: string;
68
- markerPath: string;
69
- isCached?: boolean;
70
- };
71
-
72
- export type TemplateDocument = {
73
- raw: string;
74
- assignments: TemplateAssignment[];
75
- placeholders: string[];
76
- };
77
-
78
- export type TemplateAssignment = {
79
- key: string;
80
- value: string;
81
- isStatic: boolean;
82
- isPlaceholder: boolean;
83
- placeholderName?: string;
84
- originalLine: string;
85
- };
86
-
87
- export type EnvEntry = {
88
- key: string;
89
- value: string;
90
- lineIndex: number;
91
- originalLine: string;
92
- hasExport: boolean;
93
- };
94
-
95
- export type BranchContent = {
96
- branch: BranchRef;
97
- exists: boolean;
98
- content?: string;
99
- error?: string;
100
- };
101
-
102
- export type MissingValueRequest = {
103
- branch: BranchRef;
104
- key: string;
105
- };
106
-
107
- export type BranchPlan = {
108
- branch: BranchRef;
109
- baseCommitSha: string;
110
- path: string;
111
- beforeContent: string;
112
- beforeContentHash: string;
113
- afterContent: string;
114
- afterContentHash: string;
115
- diff: string;
116
- planHash: string;
117
- status: "changed" | "unchanged" | "error";
118
- reason?: string;
119
- addedKeys: string[];
120
- updatedKeys: string[];
121
- missingVars?: string[];
122
- isNewFile?: boolean;
123
- };
124
-
125
- export type Approval = {
126
- branchName: string;
127
- approved: boolean;
128
- planHash: string;
129
- };
130
-
131
- export type BranchResult = {
132
- branch: BranchRef;
133
- status: "skipped" | "rejected" | "unchanged" | "committed" | "failed";
134
- commitSha?: string;
135
- reason?: string;
136
- };
137
-
138
- export type PushResult = {
139
- branch: BranchRef;
140
- status: "pushed" | "skipped" | "failed";
141
- reason?: string;
142
- };
143
-
144
- export type CliInput = {
145
- repo?: string;
146
- cached?: boolean;
147
- branch?: string;
148
- invertBranch?: boolean;
149
- file?: string;
150
- editor?: string;
151
- commitMsg?: string;
152
- push?: "prompt" | "always" | "never";
153
- remote?: string;
154
- autoApprove?: boolean;
155
- ci?: boolean;
156
- };
157
-
158
- export type AppServices = {
159
- git: import("../services/git/reader.js").GitReader;
160
- gitOps: import("../services/git/ops.js").GitOps;
161
- workspace: import("../services/workspace/manager.js").WorkspaceManager;
162
- template: import("../services/template/transform.js").TemplateService;
163
- state: import("../services/state/index.js").StateService;
164
- editor: import("../services/editor/index.js").EditorService;
165
- review: import("../services/review/index.js").ReviewService;
166
- };
167
-
168
- export type AppDeps = {
169
- config: import("../config/schema.js").AppConfig;
170
- services: AppServices;
171
- };
172
-
173
- export type RunContext = {
174
- runId: string;
175
- input: CliInput;
176
- project?: ManagedProject;
177
- selectedBranches?: BranchRef[];
178
- target?: TargetFile;
179
- targets?: TargetFile[];
180
- eligible?: BranchRef[];
181
- template?: TemplateDocument;
182
- activeTemplate?: TargetTemplate;
183
- templates?: TargetTemplate[];
184
- plans?: BranchPlan[];
185
- approvals?: Approval[];
186
- results?: BranchResult[];
187
- pushResults?: PushResult[];
188
- };