pi-graphite 0.2.0 → 0.2.2

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/README.md CHANGED
@@ -59,18 +59,6 @@ pi -e /path/to/pi-graphite
59
59
  - Stderr is parsed into structured `hints` (e.g. `notInitialized`, `conflictHalted`,
60
60
  `checkedOutElsewhere`, `restackNeeded`, `trunkOutOfSync`).
61
61
 
62
- ## Intentional non-goals (in Layer A)
63
-
64
- - No `graphite_raw` passthrough. Use bash for arbitrary `gt` flags.
65
- - No workflow orchestration (plan → apply across multiple commands).
66
- - No wrapping of `gt add/cherry-pick/rebase/reset/restore` passthroughs.
67
- - No wrapping of browser/help commands (`dash`, `docs`, `guide`, `changelog`,
68
- `feedback`, `demo`, `completion`, `fish`).
69
- - `gt reorder` (editor-only) and `gt split --by-commit / --by-hunk`
70
- (interactive-only) are intentionally not exposed.
71
-
72
- Layer B (workflow tools) and Layer C (raw escape hatch) are planned, not built.
73
-
74
62
  ## License
75
63
 
76
64
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-graphite",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Structured pi tools for the Graphite (gt) CLI.",
5
5
  "keywords": [
6
6
  "pi",
package/src/lib/exec.ts CHANGED
@@ -28,6 +28,14 @@ export function stripAnsi(s: string): string {
28
28
  return s.replace(ANSI, "");
29
29
  }
30
30
 
31
+ /**
32
+ * Replace Graphite's internal product name "Charcoal" with "Graphite" so
33
+ * users and the LLM see a consistent product name. Casing is preserved.
34
+ */
35
+ export function sanitizeBranding(s: string): string {
36
+ return s.replace(/charcoal/gi, (m) => (m[0] === m[0].toUpperCase() ? "Graphite" : "graphite"));
37
+ }
38
+
31
39
  export function truncateOutput(s: string): string {
32
40
  if (s.length <= MAX_BYTES) {
33
41
  const lines = s.split("\n");
@@ -109,8 +117,8 @@ export async function runGt(
109
117
  args,
110
118
  cwd,
111
119
  exitCode: -1,
112
- stdout: stripAnsi(stdout),
113
- stderr: stripAnsi(stderr),
120
+ stdout: sanitizeBranding(stripAnsi(stdout)),
121
+ stderr: sanitizeBranding(stripAnsi(stderr)),
114
122
  timedOut: false,
115
123
  spawnError: err.message,
116
124
  });
@@ -123,8 +131,8 @@ export async function runGt(
123
131
  args,
124
132
  cwd,
125
133
  exitCode: code ?? -1,
126
- stdout: truncateOutput(stripAnsi(stdout)),
127
- stderr: truncateOutput(stripAnsi(stderr)),
134
+ stdout: truncateOutput(sanitizeBranding(stripAnsi(stdout))),
135
+ stderr: truncateOutput(sanitizeBranding(stripAnsi(stderr))),
128
136
  timedOut: killed,
129
137
  });
130
138
  });
package/src/lib/result.ts CHANGED
@@ -28,7 +28,10 @@ const PATTERNS: Array<[Exclude<keyof GtHints, "checkedOutElsewhere" | "invalidAr
28
28
  ],
29
29
  [
30
30
  "notInitialized",
31
- /Charcoal has not been initialized|graphite is not (?:yet )?initialized|run\s+`?gt\s+init`?/i,
31
+ // Output is sanitized before hint parsing, so Charcoal is replaced with
32
+ // Graphite. We still allow the original spelling defensively in case the
33
+ // sanitizer is bypassed.
34
+ /Graphite has not been initialized|Charcoal has not been initialized|graphite is not (?:yet )?initialized|run\s+`?gt\s+init`?/i,
32
35
  ],
33
36
  [
34
37
  "notAuthenticated",
@@ -159,11 +162,15 @@ async function detectCurrentBranch(cwd: string): Promise<string | undefined> {
159
162
  async function detectTrunk(cwd: string): Promise<string | undefined> {
160
163
  const out = await execText("gt", ["--cwd", cwd, "--no-interactive", "trunk"], cwd);
161
164
  // gt trunk prints the trunk name on its own line. Take last non-empty line.
162
- const line = out
165
+ const cleaned = out
163
166
  .replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "")
167
+ .replace(/charcoal/gi, (m) => (m[0] === m[0].toUpperCase() ? "Graphite" : "graphite"));
168
+ const line = cleaned
164
169
  .split("\n")
165
170
  .map((s) => s.trim())
166
171
  .filter(Boolean)
172
+ // Skip Graphite banner / init lines so we keep the actual trunk name.
173
+ .filter((s) => !/Graphite|Welcome/i.test(s) && !/initialized/i.test(s))
167
174
  .pop();
168
175
  return line || undefined;
169
176
  }