@jwilger/pi-development-system 0.8.8 → 0.8.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jwilger/pi-development-system",
3
- "version": "0.8.8",
3
+ "version": "0.8.9",
4
4
  "description": "A pi extension package representing a seasoned approach to software development using a full AI SDLC.",
5
5
  "keywords": [
6
6
  "pi-package"
@@ -18,6 +18,8 @@ type Options = {
18
18
  trailers: string[];
19
19
  file: string | undefined;
20
20
  opaque: boolean;
21
+ /** Heredoc markers found inside opaque `-m` values (`$(cat <<EOF …)`). */
22
+ markers: number[];
21
23
  };
22
24
 
23
25
  type Parsed = {
@@ -68,12 +70,21 @@ const OPAQUE_VALUE = /^\s*(?:\$\(|`)|^\$\{?\w+\}?$/;
68
70
  function record(options: Options, parsed: Parsed): void {
69
71
  if (parsed.kind === "file") options.file = parsed.value;
70
72
  else if (parsed.kind === "trailer") options.trailers.push(parsed.value ?? "");
71
- else if (parsed.value === undefined || OPAQUE_VALUE.test(parsed.value)) options.opaque = true;
72
- else options.messages.push(parsed.value);
73
+ else if (parsed.value === undefined || OPAQUE_VALUE.test(parsed.value)) {
74
+ options.opaque = true;
75
+ for (const hit of (parsed.value ?? "").matchAll(/#HD(\d+)/g))
76
+ options.markers.push(Number(hit[1]));
77
+ } else options.messages.push(parsed.value);
73
78
  }
74
79
 
75
80
  function readOptions(args: readonly string[]): Options {
76
- const options: Options = { messages: [], trailers: [], file: undefined, opaque: false };
81
+ const options: Options = {
82
+ messages: [],
83
+ trailers: [],
84
+ file: undefined,
85
+ opaque: false,
86
+ markers: [],
87
+ };
77
88
  for (let i = 0; i < args.length; ) {
78
89
  const parsed = parseArg(args, i);
79
90
  if (parsed !== undefined) record(options, parsed);
@@ -100,7 +111,11 @@ const heredocFrom = (lines: readonly string[], line: number, bodies: readonly st
100
111
  return undefined;
101
112
  };
102
113
 
103
- function extractOne(args: readonly string[], heredoc: string | undefined): CommitExtraction {
114
+ function extractOne(
115
+ args: readonly string[],
116
+ heredoc: string | undefined,
117
+ bodies: readonly string[],
118
+ ): CommitExtraction {
104
119
  const options = readOptions(args);
105
120
  if (options.file !== undefined && STDIN_PATHS.has(options.file)) {
106
121
  return heredoc === undefined
@@ -110,8 +125,12 @@ function extractOne(args: readonly string[], heredoc: string | undefined): Commi
110
125
  if (options.file !== undefined) return { kind: "file", path: options.file };
111
126
  const parts = [...options.messages];
112
127
  if (options.opaque) {
113
- if (heredoc === undefined) return unknown(options.trailers, true);
114
- parts.push(heredoc);
128
+ // The value's own heredoc, not whichever heredoc opens first on a shared line.
129
+ const own = options.markers.flatMap((i) => bodies[i] ?? []);
130
+ const fallback = heredoc === undefined ? [] : [heredoc];
131
+ const bodiesOfValue = own.length > 0 ? own : fallback;
132
+ if (bodiesOfValue.length === 0) return unknown(options.trailers, true);
133
+ parts.push(...bodiesOfValue);
115
134
  }
116
135
  if (parts.length === 0) return unknown(options.trailers);
117
136
  const trailers = options.trailers.length === 0 ? "" : `\n\n${options.trailers.join("\n")}`;
@@ -124,7 +143,7 @@ export function extractCommits(command: string): CommitExtraction[] {
124
143
  const resolution = resolveGit(rest);
125
144
  const lines = splitLines(rest);
126
145
  const found = resolution.invocations.flatMap((g) =>
127
- g.sub === "commit" ? [extractOne(g.args, heredocFrom(lines, g.line, bodies))] : [],
146
+ g.sub === "commit" ? [extractOne(g.args, heredocFrom(lines, g.line, bodies), bodies)] : [],
128
147
  );
129
148
  const hidden = opaqueMentions(resolution, "commit");
130
149
  return hidden ? [...found, unknown()] : found;