@335g/pi-git 0.0.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 (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +121 -0
  3. package/README.md +121 -0
  4. package/dist/commands/agg-commit.d.ts +9 -0
  5. package/dist/commands/agg-commit.d.ts.map +1 -0
  6. package/dist/commands/agg-commit.js +144 -0
  7. package/dist/commands/agg-commit.js.map +1 -0
  8. package/dist/commands/auto-agg-commit.d.ts +9 -0
  9. package/dist/commands/auto-agg-commit.d.ts.map +1 -0
  10. package/dist/commands/auto-agg-commit.js +113 -0
  11. package/dist/commands/auto-agg-commit.js.map +1 -0
  12. package/dist/commands/branch.d.ts +8 -0
  13. package/dist/commands/branch.d.ts.map +1 -0
  14. package/dist/commands/branch.js +197 -0
  15. package/dist/commands/branch.js.map +1 -0
  16. package/dist/commands/config.d.ts +10 -0
  17. package/dist/commands/config.d.ts.map +1 -0
  18. package/dist/commands/config.js +234 -0
  19. package/dist/commands/config.js.map +1 -0
  20. package/dist/commands/git-diff.d.ts +10 -0
  21. package/dist/commands/git-diff.d.ts.map +1 -0
  22. package/dist/commands/git-diff.js +228 -0
  23. package/dist/commands/git-diff.js.map +1 -0
  24. package/dist/commands/git-log.d.ts +8 -0
  25. package/dist/commands/git-log.d.ts.map +1 -0
  26. package/dist/commands/git-log.js +100 -0
  27. package/dist/commands/git-log.js.map +1 -0
  28. package/dist/core/auto-commit-message.d.ts +15 -0
  29. package/dist/core/auto-commit-message.d.ts.map +1 -0
  30. package/dist/core/auto-commit-message.js +121 -0
  31. package/dist/core/auto-commit-message.js.map +1 -0
  32. package/dist/core/auto-commit.d.ts +12 -0
  33. package/dist/core/auto-commit.d.ts.map +1 -0
  34. package/dist/core/auto-commit.js +67 -0
  35. package/dist/core/auto-commit.js.map +1 -0
  36. package/dist/core/commit-message.d.ts +25 -0
  37. package/dist/core/commit-message.d.ts.map +1 -0
  38. package/dist/core/commit-message.js +127 -0
  39. package/dist/core/commit-message.js.map +1 -0
  40. package/dist/core/diff-analyzer.d.ts +23 -0
  41. package/dist/core/diff-analyzer.d.ts.map +1 -0
  42. package/dist/core/diff-analyzer.js +245 -0
  43. package/dist/core/diff-analyzer.js.map +1 -0
  44. package/dist/core/git.d.ts +50 -0
  45. package/dist/core/git.d.ts.map +1 -0
  46. package/dist/core/git.js +152 -0
  47. package/dist/core/git.js.map +1 -0
  48. package/dist/core/resolve-model.d.ts +18 -0
  49. package/dist/core/resolve-model.d.ts.map +1 -0
  50. package/dist/core/resolve-model.js +33 -0
  51. package/dist/core/resolve-model.js.map +1 -0
  52. package/dist/index.d.ts +8 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +61 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/tui/hunk-review.d.ts +49 -0
  57. package/dist/tui/hunk-review.d.ts.map +1 -0
  58. package/dist/tui/hunk-review.js +300 -0
  59. package/dist/tui/hunk-review.js.map +1 -0
  60. package/dist/types.d.ts +23 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/types.js +5 -0
  63. package/dist/types.js.map +1 -0
  64. package/dist/utils/footer-manager.d.ts +68 -0
  65. package/dist/utils/footer-manager.d.ts.map +1 -0
  66. package/dist/utils/footer-manager.js +138 -0
  67. package/dist/utils/footer-manager.js.map +1 -0
  68. package/dist/utils/lang.d.ts +12 -0
  69. package/dist/utils/lang.d.ts.map +1 -0
  70. package/dist/utils/lang.js +16 -0
  71. package/dist/utils/lang.js.map +1 -0
  72. package/dist/utils/settings.d.ts +47 -0
  73. package/dist/utils/settings.d.ts.map +1 -0
  74. package/dist/utils/settings.js +151 -0
  75. package/dist/utils/settings.js.map +1 -0
  76. package/package.json +60 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Model resolution helper for pi-git commands.
3
+ *
4
+ * Resolves the AI model to use based on configuration or session context.
5
+ */
6
+ import { getAnalysisModel } from "../utils/settings.js";
7
+ /**
8
+ * Resolve the model to use for AI operations.
9
+ *
10
+ * Priority:
11
+ * 1. Configured `analysis_model` in settings (format: "provider/model-id")
12
+ * 2. Current session model (`ctx.model`)
13
+ *
14
+ * @returns The resolved model, or undefined if no model is available
15
+ */
16
+ export function resolveModel(ctx) {
17
+ // Try configured model first
18
+ const configuredModel = getAnalysisModel(ctx.cwd);
19
+ if (configuredModel) {
20
+ const slashIndex = configuredModel.indexOf("/");
21
+ if (slashIndex > 0) {
22
+ const provider = configuredModel.substring(0, slashIndex);
23
+ const modelId = configuredModel.substring(slashIndex + 1);
24
+ const found = ctx.modelRegistry.find(provider, modelId);
25
+ if (found) {
26
+ return found;
27
+ }
28
+ }
29
+ }
30
+ // Fall back to session model
31
+ return ctx.model;
32
+ }
33
+ //# sourceMappingURL=resolve-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-model.js","sourceRoot":"","sources":["../../src/core/resolve-model.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,GAAqB;IAChD,6BAA6B;IAC7B,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,eAAe,CAAC,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YAC1D,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACxD,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,OAAO,GAAG,CAAC,KAAK,CAAC;AACnB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * pi-git extension entry point
3
+ *
4
+ * Provides slash commands for git operations.
5
+ */
6
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
7
+ export default function (pi: ExtensionAPI): void;
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAWpE,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,QAuDxC"}
package/dist/index.js ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * pi-git extension entry point
3
+ *
4
+ * Provides slash commands for git operations.
5
+ */
6
+ import { handleAggCommit } from "./commands/agg-commit.js";
7
+ import { handleAutoAggCommit } from "./commands/auto-agg-commit.js";
8
+ import { handleBranch } from "./commands/branch.js";
9
+ import { handleConfig } from "./commands/config.js";
10
+ import { handleGitDiff } from "./commands/git-diff.js";
11
+ import { handleGitLog } from "./commands/git-log.js";
12
+ import { handleAutoCommit } from "./core/auto-commit.js";
13
+ import { footerManager } from "./utils/footer-manager.js";
14
+ export default function (pi) {
15
+ pi.on("session_start", async (_event, ctx) => {
16
+ if (ctx.hasUI) {
17
+ footerManager.initialize(pi, ctx.ui, ctx.cwd);
18
+ await footerManager.refresh();
19
+ }
20
+ });
21
+ pi.registerCommand("git-agg-commit", {
22
+ description: "Auto stage and commit changes with AI-generated Conventional Commits messages",
23
+ handler: async (args, ctx) => {
24
+ await handleAggCommit(pi, ctx, args);
25
+ },
26
+ });
27
+ pi.registerCommand("git-config", {
28
+ description: "Get, set, or list pi-git configuration values",
29
+ handler: async (args, ctx) => {
30
+ await handleConfig(pi, ctx, args);
31
+ },
32
+ });
33
+ pi.registerCommand("git-auto-agg-commit", {
34
+ description: "Toggle automatic git-agg-commit after assistant responses",
35
+ handler: async (args, ctx) => {
36
+ await handleAutoAggCommit(pi, ctx, args);
37
+ },
38
+ });
39
+ pi.registerCommand("git-branch", {
40
+ description: "Manage git branches: list, switch, create, and delete",
41
+ handler: async (args, ctx) => {
42
+ await handleBranch(pi, ctx, args);
43
+ },
44
+ });
45
+ pi.registerCommand("git-diff", {
46
+ description: "Interactively review AI-generated hunks and commit approved ones",
47
+ handler: async (args, ctx) => {
48
+ await handleGitDiff(pi, ctx, args);
49
+ },
50
+ });
51
+ pi.registerCommand("git-log", {
52
+ description: "Display git log in oneline format",
53
+ handler: async (args, ctx) => {
54
+ await handleGitLog(pi, ctx, args);
55
+ },
56
+ });
57
+ pi.on("agent_end", async (event, ctx) => {
58
+ await handleAutoCommit(pi, ctx, event);
59
+ });
60
+ }
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,CAAC,OAAO,WAAW,EAAgB;IACvC,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC3C,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,aAAa,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9C,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC;QAChC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,gBAAgB,EAAE;QACnC,WAAW,EACT,+EAA+E;QACjF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACvC,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,YAAY,EAAE;QAC/B,WAAW,EAAE,+CAA+C;QAC5D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,qBAAqB,EAAE;QACxC,WAAW,EAAE,2DAA2D;QACxE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,mBAAmB,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,YAAY,EAAE;QAC/B,WAAW,EAAE,uDAAuD;QACpE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,UAAU,EAAE;QAC7B,WAAW,EACT,kEAAkE;QACpE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE;QAC5B,WAAW,EAAE,mCAAmC;QAChD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACtC,MAAM,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAsB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Hunk review TUI component
3
+ *
4
+ * Displays a hunk with its files and commit message, allowing the user to:
5
+ * - Navigate through files
6
+ * - View diff for each file
7
+ * - Approve, skip, or exclude files
8
+ * - Edit the commit message
9
+ */
10
+ import type { Component } from "@earendil-works/pi-tui";
11
+ import type { FileStats, Hunk } from "../types.js";
12
+ export type HunkReviewAction = {
13
+ type: "approve";
14
+ message: string;
15
+ excludedFiles: string[];
16
+ } | {
17
+ type: "edit_message";
18
+ currentMessage: string;
19
+ excludedFiles: string[];
20
+ } | {
21
+ type: "skip";
22
+ excludedFiles: string[];
23
+ } | {
24
+ type: "quit";
25
+ };
26
+ export declare class HunkReviewComponent implements Component {
27
+ private hunk;
28
+ private hunkIndex;
29
+ private totalHunks;
30
+ private fileStats;
31
+ private fileDiffs;
32
+ private tui;
33
+ private theme;
34
+ private onComplete;
35
+ private container;
36
+ private selectedIndex;
37
+ private excludedFiles;
38
+ private mode;
39
+ private diffScrollOffset;
40
+ constructor(hunk: Hunk, hunkIndex: number, totalHunks: number, fileStats: Map<string, FileStats>, fileDiffs: Map<string, string[]>, tui: any, theme: any, onComplete: (action: HunkReviewAction) => void);
41
+ private renderList;
42
+ private renderDiff;
43
+ render(width: number): string[];
44
+ handleInput(data: string): void;
45
+ private handleListInput;
46
+ private handleDiffInput;
47
+ invalidate(): void;
48
+ }
49
+ //# sourceMappingURL=hunk-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hunk-review.d.ts","sourceRoot":"","sources":["../../src/tui/hunk-review.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AASxD,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,qBAAa,mBAAoB,YAAW,SAAS;IAQjD,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,UAAU;IAdpB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,gBAAgB,CAAK;gBAGnB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EACjC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAChC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,GAAG,EACV,UAAU,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI;IAMxD,OAAO,CAAC,UAAU;IAoElB,OAAO,CAAC,UAAU;IA0ElB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAM/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ/B,OAAO,CAAC,eAAe;IA2EvB,OAAO,CAAC,eAAe;IA+DvB,UAAU,IAAI,IAAI;CAGnB"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Hunk review TUI component
3
+ *
4
+ * Displays a hunk with its files and commit message, allowing the user to:
5
+ * - Navigate through files
6
+ * - View diff for each file
7
+ * - Approve, skip, or exclude files
8
+ * - Edit the commit message
9
+ */
10
+ import { Container, Text, matchesKey, Key, truncateToWidth, } from "@earendil-works/pi-tui";
11
+ import { DynamicBorder } from "@earendil-works/pi-coding-agent";
12
+ export class HunkReviewComponent {
13
+ hunk;
14
+ hunkIndex;
15
+ totalHunks;
16
+ fileStats;
17
+ fileDiffs;
18
+ tui;
19
+ theme;
20
+ onComplete;
21
+ container;
22
+ selectedIndex = 0;
23
+ excludedFiles = new Set();
24
+ mode = "list";
25
+ diffScrollOffset = 0;
26
+ constructor(hunk, hunkIndex, totalHunks, fileStats, fileDiffs, tui, theme, onComplete) {
27
+ this.hunk = hunk;
28
+ this.hunkIndex = hunkIndex;
29
+ this.totalHunks = totalHunks;
30
+ this.fileStats = fileStats;
31
+ this.fileDiffs = fileDiffs;
32
+ this.tui = tui;
33
+ this.theme = theme;
34
+ this.onComplete = onComplete;
35
+ this.container = new Container();
36
+ this.renderList();
37
+ }
38
+ renderList() {
39
+ this.container.clear();
40
+ const border = new DynamicBorder((s) => this.theme.fg("border", s));
41
+ this.container.addChild(border);
42
+ // Header
43
+ const header = this.theme.fg("accent", this.theme.bold(`Hunk ${this.hunkIndex + 1}/${this.totalHunks}`));
44
+ this.container.addChild(new Text(header, 1, 0));
45
+ // Commit message
46
+ const messageLabel = this.theme.fg("muted", "Message: ");
47
+ const messageText = this.theme.fg("text", this.hunk.message);
48
+ this.container.addChild(new Text(messageLabel + messageText, 1, 0));
49
+ // Empty line
50
+ this.container.addChild(new Text("", 0, 0));
51
+ // File list
52
+ const files = this.hunk.files.filter((f) => !this.excludedFiles.has(f));
53
+ for (let i = 0; i < files.length; i++) {
54
+ const file = files[i];
55
+ const stats = this.fileStats.get(file);
56
+ const isSelected = i === this.selectedIndex;
57
+ let line = "";
58
+ if (isSelected) {
59
+ line += this.theme.fg("accent", "● ");
60
+ }
61
+ else {
62
+ line += " ";
63
+ }
64
+ line += this.theme.fg("text", file);
65
+ if (stats) {
66
+ const statsText = ` +${stats.additions} -${stats.deletions}`;
67
+ line += this.theme.fg("muted", statsText);
68
+ }
69
+ this.container.addChild(new Text(line, 1, 0));
70
+ }
71
+ // Empty line
72
+ this.container.addChild(new Text("", 0, 0));
73
+ // Help text - keybindings
74
+ const helpLines = [
75
+ this.theme.fg("muted", "Navigation:"),
76
+ this.theme.fg("text", " ↑↓ ") + this.theme.fg("muted", "Navigate files"),
77
+ this.theme.fg("text", " Enter ") + this.theme.fg("muted", "View diff"),
78
+ this.theme.fg("muted", "Actions:"),
79
+ this.theme.fg("text", " a ") + this.theme.fg("muted", "Approve & commit"),
80
+ this.theme.fg("text", " e ") + this.theme.fg("muted", "Edit message"),
81
+ this.theme.fg("text", " x ") + this.theme.fg("muted", "Exclude file"),
82
+ this.theme.fg("text", " s ") + this.theme.fg("muted", "Skip hunk"),
83
+ this.theme.fg("text", " q ") + this.theme.fg("muted", "Quit"),
84
+ ];
85
+ for (const line of helpLines) {
86
+ this.container.addChild(new Text(line, 1, 0));
87
+ }
88
+ this.container.addChild(border);
89
+ }
90
+ renderDiff() {
91
+ this.container.clear();
92
+ const files = this.hunk.files.filter((f) => !this.excludedFiles.has(f));
93
+ const file = files[this.selectedIndex];
94
+ if (!file) {
95
+ this.mode = "list";
96
+ this.renderList();
97
+ return;
98
+ }
99
+ const diffLines = this.fileDiffs.get(file) || [];
100
+ const border = new DynamicBorder((s) => this.theme.fg("border", s));
101
+ this.container.addChild(border);
102
+ // Header
103
+ const header = this.theme.fg("accent", this.theme.bold(`Diff: ${file}`));
104
+ this.container.addChild(new Text(header, 1, 0));
105
+ // Empty line
106
+ this.container.addChild(new Text("", 0, 0));
107
+ // Diff content (with scrolling)
108
+ const visibleLines = 20; // TODO: calculate from terminal height
109
+ const start = this.diffScrollOffset;
110
+ const end = Math.min(start + visibleLines, diffLines.length);
111
+ for (let i = start; i < end; i++) {
112
+ const line = diffLines[i];
113
+ let colored = line;
114
+ if (line.startsWith("+")) {
115
+ colored = this.theme.fg("toolDiffAdded", line);
116
+ }
117
+ else if (line.startsWith("-")) {
118
+ colored = this.theme.fg("toolDiffRemoved", line);
119
+ }
120
+ else {
121
+ colored = this.theme.fg("toolDiffContext", line);
122
+ }
123
+ this.container.addChild(new Text(colored, 1, 0));
124
+ }
125
+ // Scroll indicator
126
+ if (diffLines.length > visibleLines) {
127
+ const scrollInfo = this.theme.fg("muted", `Lines ${start + 1}-${end} of ${diffLines.length}`);
128
+ this.container.addChild(new Text(scrollInfo, 1, 0));
129
+ }
130
+ // Empty line
131
+ this.container.addChild(new Text("", 0, 0));
132
+ // Help text - keybindings
133
+ const helpLines = [
134
+ this.theme.fg("muted", "Navigation:"),
135
+ this.theme.fg("text", " ↑↓ ") + this.theme.fg("muted", "Scroll line by line"),
136
+ this.theme.fg("text", " Shift+↑↓ ") + this.theme.fg("muted", "Scroll ¾ page"),
137
+ this.theme.fg("text", " Home/End ") + this.theme.fg("muted", "Jump to top/bottom"),
138
+ this.theme.fg("text", " Esc ") + this.theme.fg("muted", "Back to file list"),
139
+ ];
140
+ for (const line of helpLines) {
141
+ this.container.addChild(new Text(line, 1, 0));
142
+ }
143
+ this.container.addChild(border);
144
+ }
145
+ render(width) {
146
+ return this.container
147
+ .render(width)
148
+ .map((line) => truncateToWidth(line, width));
149
+ }
150
+ handleInput(data) {
151
+ if (this.mode === "list") {
152
+ this.handleListInput(data);
153
+ }
154
+ else {
155
+ this.handleDiffInput(data);
156
+ }
157
+ }
158
+ handleListInput(data) {
159
+ const files = this.hunk.files.filter((f) => !this.excludedFiles.has(f));
160
+ if (matchesKey(data, Key.up)) {
161
+ if (this.selectedIndex > 0) {
162
+ this.selectedIndex--;
163
+ this.renderList();
164
+ this.tui.requestRender();
165
+ }
166
+ }
167
+ else if (matchesKey(data, Key.down)) {
168
+ if (this.selectedIndex < files.length - 1) {
169
+ this.selectedIndex++;
170
+ this.renderList();
171
+ this.tui.requestRender();
172
+ }
173
+ }
174
+ else if (matchesKey(data, Key.enter)) {
175
+ // Switch to diff view
176
+ if (files.length > 0) {
177
+ this.mode = "diff";
178
+ this.diffScrollOffset = 0;
179
+ this.renderDiff();
180
+ this.tui.requestRender();
181
+ }
182
+ }
183
+ else if (data === "a") {
184
+ // Approve
185
+ this.onComplete({
186
+ type: "approve",
187
+ message: this.hunk.message,
188
+ excludedFiles: Array.from(this.excludedFiles),
189
+ });
190
+ }
191
+ else if (data === "e") {
192
+ // Edit message
193
+ this.onComplete({
194
+ type: "edit_message",
195
+ currentMessage: this.hunk.message,
196
+ excludedFiles: Array.from(this.excludedFiles),
197
+ });
198
+ }
199
+ else if (data === "s") {
200
+ // Skip
201
+ this.onComplete({
202
+ type: "skip",
203
+ excludedFiles: Array.from(this.excludedFiles),
204
+ });
205
+ }
206
+ else if (data === "x") {
207
+ // Exclude selected file
208
+ if (files.length > 0) {
209
+ const file = files[this.selectedIndex];
210
+ this.excludedFiles.add(file);
211
+ // Adjust selection if needed
212
+ const newFiles = this.hunk.files.filter((f) => !this.excludedFiles.has(f));
213
+ if (this.selectedIndex >= newFiles.length && this.selectedIndex > 0) {
214
+ this.selectedIndex--;
215
+ }
216
+ // If all files excluded, auto-skip
217
+ if (newFiles.length === 0) {
218
+ this.onComplete({
219
+ type: "skip",
220
+ excludedFiles: Array.from(this.excludedFiles),
221
+ });
222
+ return;
223
+ }
224
+ this.renderList();
225
+ this.tui.requestRender();
226
+ }
227
+ }
228
+ else if (data === "q") {
229
+ // Quit
230
+ this.onComplete({ type: "quit" });
231
+ }
232
+ }
233
+ handleDiffInput(data) {
234
+ const files = this.hunk.files.filter((f) => !this.excludedFiles.has(f));
235
+ const file = files[this.selectedIndex];
236
+ if (!file) {
237
+ this.mode = "list";
238
+ this.renderList();
239
+ this.tui.requestRender();
240
+ return;
241
+ }
242
+ const diffLines = this.fileDiffs.get(file) || [];
243
+ const visibleLines = 20;
244
+ if (matchesKey(data, Key.up)) {
245
+ if (this.diffScrollOffset > 0) {
246
+ this.diffScrollOffset--;
247
+ this.renderDiff();
248
+ this.tui.requestRender();
249
+ }
250
+ }
251
+ else if (matchesKey(data, Key.down)) {
252
+ if (this.diffScrollOffset < diffLines.length - visibleLines) {
253
+ this.diffScrollOffset++;
254
+ this.renderDiff();
255
+ this.tui.requestRender();
256
+ }
257
+ }
258
+ else if (matchesKey(data, Key.shift("up"))) {
259
+ if (this.diffScrollOffset > 0) {
260
+ const jump = Math.floor(visibleLines * 3 / 4);
261
+ this.diffScrollOffset = Math.max(0, this.diffScrollOffset - jump);
262
+ this.renderDiff();
263
+ this.tui.requestRender();
264
+ }
265
+ }
266
+ else if (matchesKey(data, Key.shift("down"))) {
267
+ if (this.diffScrollOffset < diffLines.length - visibleLines) {
268
+ const jump = Math.floor(visibleLines * 3 / 4);
269
+ this.diffScrollOffset = Math.min(diffLines.length - visibleLines, this.diffScrollOffset + jump);
270
+ this.renderDiff();
271
+ this.tui.requestRender();
272
+ }
273
+ }
274
+ else if (matchesKey(data, Key.home)) {
275
+ if (this.diffScrollOffset > 0) {
276
+ this.diffScrollOffset = 0;
277
+ this.renderDiff();
278
+ this.tui.requestRender();
279
+ }
280
+ }
281
+ else if (matchesKey(data, Key.end)) {
282
+ const maxOffset = Math.max(0, diffLines.length - visibleLines);
283
+ if (this.diffScrollOffset < maxOffset) {
284
+ this.diffScrollOffset = maxOffset;
285
+ this.renderDiff();
286
+ this.tui.requestRender();
287
+ }
288
+ }
289
+ else if (matchesKey(data, Key.escape)) {
290
+ // Back to list
291
+ this.mode = "list";
292
+ this.renderList();
293
+ this.tui.requestRender();
294
+ }
295
+ }
296
+ invalidate() {
297
+ this.container.invalidate();
298
+ }
299
+ }
300
+ //# sourceMappingURL=hunk-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hunk-review.js","sourceRoot":"","sources":["../../src/tui/hunk-review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Types for pi-git extension
3
+ */
4
+ export interface Hunk {
5
+ /** Files included in this hunk */
6
+ files: string[];
7
+ /** Conventional Commit message for this hunk */
8
+ message: string;
9
+ /** Optional description of changes for message generation context */
10
+ description?: string;
11
+ }
12
+ export interface FileStats {
13
+ path: string;
14
+ additions: number;
15
+ deletions: number;
16
+ }
17
+ export interface AgentEndEvent {
18
+ messages?: Array<{
19
+ role: string;
20
+ content: unknown;
21
+ }>;
22
+ }
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,IAAI;IACnB,kCAAkC;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAAC;CACJ"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Types for pi-git extension
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Footer status manager for pi-git extension
3
+ *
4
+ * Manages footer display in a unified way:
5
+ * - Base display: auto-commit on/off + clean/changed state
6
+ * - Running display: command execution phase
7
+ *
8
+ * Singleton instance is exported as `footerManager`.
9
+ */
10
+ import type { ExtensionAPI, ExtensionUIContext } from "@earendil-works/pi-coding-agent";
11
+ type Phase = "prepare" | "collectDiff" | "analyze" | "generateMessage" | "commit";
12
+ /**
13
+ * Singleton class that manages footer status display.
14
+ *
15
+ * When `ui` is null (hasUI = false), all methods become no-op.
16
+ */
17
+ declare class FooterManager {
18
+ private pi;
19
+ private ui;
20
+ private cwd;
21
+ private running;
22
+ /**
23
+ * Initialize the manager with pi API, UI context, and working directory.
24
+ * Call this once at session_start.
25
+ *
26
+ * @param pi - Extension API for executing git commands
27
+ * @param ui - UI context (null if hasUI is false)
28
+ * @param cwd - Working directory
29
+ */
30
+ initialize(pi: ExtensionAPI, ui: ExtensionUIContext | null, cwd?: string): void;
31
+ /**
32
+ * Check if a command is currently running.
33
+ */
34
+ isRunning(): boolean;
35
+ /**
36
+ * Refresh the base display (auto-commit on/off + clean/changed).
37
+ * Does nothing if a command is running or if UI is not available.
38
+ */
39
+ refresh(): Promise<void>;
40
+ /**
41
+ * Start running display. Sets the running flag and shows phase text.
42
+ *
43
+ * @param command - Command name ("agg-commit" or "auto-commit")
44
+ * @param phase - Initial phase
45
+ * @param lang - Optional language override (for --lang flag)
46
+ */
47
+ setRunning(command: string, phase: Phase, lang?: string): Promise<void>;
48
+ /**
49
+ * Update the phase of the currently running command.
50
+ * Does nothing if no command is running.
51
+ *
52
+ * @param phase - New phase
53
+ * @param lang - Optional language override (for --lang flag)
54
+ */
55
+ setPhase(phase: Phase, lang?: string): Promise<void>;
56
+ /**
57
+ * End the running display. Clears the running flag and refreshes base display.
58
+ */
59
+ clearRunning(): Promise<void>;
60
+ /**
61
+ * Render the current phase text to the footer.
62
+ */
63
+ private renderPhase;
64
+ }
65
+ /** Singleton instance */
66
+ export declare const footerManager: FooterManager;
67
+ export {};
68
+ //# sourceMappingURL=footer-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"footer-manager.d.ts","sourceRoot":"","sources":["../../src/utils/footer-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EACnB,MAAM,iCAAiC,CAAC;AAMzC,KAAK,KAAK,GACN,SAAS,GACT,aAAa,GACb,SAAS,GACT,iBAAiB,GACjB,QAAQ,CAAC;AAEb;;;;GAIG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,EAAE,CAA6B;IACvC,OAAO,CAAC,EAAE,CAAmC;IAC7C,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,OAAO,CACR;IAEP;;;;;;;OAOG;IACH,UAAU,CACR,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,kBAAkB,GAAG,IAAI,EAC7B,GAAG,CAAC,EAAE,MAAM,GACX,IAAI;IAMP;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAwB9B;;;;;;OAMG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAMhB;;;;;;OAMG;IACG,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS1D;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAKnC;;OAEG;IACH,OAAO,CAAC,WAAW;CASpB;AA4BD,yBAAyB;AACzB,eAAO,MAAM,aAAa,eAAsB,CAAC"}