@almightygpt/core 0.7.1 → 0.7.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/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  * - review/ ✅ task #11 diff review pipeline (with #12/#13/#14 wiring)
13
13
  * - budget/ ✅ task #14 BudgetTracker + BudgetExceededError
14
14
  */
15
- export declare const VERSION = "0.7.1";
15
+ export declare const VERSION = "0.7.2";
16
16
  export { checkGitStatus, assertSafeToWrite, GitStatusDirtyError, type GitStatusCheck, } from "./git/status.js";
17
17
  export { installTemplate, hasExistingConfig, type InstallOptions, type InstallResult, } from "./templates/install.js";
18
18
  export { loadConfig, ConfigError } from "./config/load.js";
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * - review/ ✅ task #11 diff review pipeline (with #12/#13/#14 wiring)
13
13
  * - budget/ ✅ task #14 BudgetTracker + BudgetExceededError
14
14
  */
15
- export const VERSION = "0.7.1";
15
+ export const VERSION = "0.7.2";
16
16
  // Git safety primitives
17
17
  export { checkGitStatus, assertSafeToWrite, GitStatusDirtyError, } from "./git/status.js";
18
18
  // Template installer
@@ -41,6 +41,16 @@ export interface InstallResult {
41
41
  from: string;
42
42
  to: string;
43
43
  }[];
44
+ /**
45
+ * Entries appended to the target repo's `.gitignore`. Empty if everything
46
+ * was already covered (e.g. user had `.almightygpt/` blanket-ignored, or
47
+ * had previously run init).
48
+ */
49
+ gitignoreAppended: string[];
50
+ /** Entries that were already present in `.gitignore` and didn't need adding. */
51
+ gitignoreAlreadyPresent: string[];
52
+ /** True if init created the `.gitignore` file (didn't exist). */
53
+ gitignoreCreated: boolean;
44
54
  }
45
55
  export declare function installTemplate(options: InstallOptions): Promise<InstallResult>;
46
56
  export declare function relativeFromCwd(targetDir: string, absPath: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/templates/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,0DAA0D;IAC1D,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC1C;AA0CD,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CA4ExB;AAmBD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED,2EAA2E;AAC3E,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3E"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/templates/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,0DAA0D;IAC1D,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzC;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,gFAAgF;IAChF,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,iEAAiE;IACjE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAwDD,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAqFxB;AAsFD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED,2EAA2E;AAC3E,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3E"}
@@ -18,6 +18,18 @@ import { dirname, join, relative } from "node:path";
18
18
  import { existsSync } from "node:fs";
19
19
  import { fileURLToPath } from "node:url";
20
20
  import { assertSafeToWrite } from "../git/status.js";
21
+ /**
22
+ * Entries appended to the host repo's `.gitignore`. The product's machine
23
+ * metadata (per-run outputs) must never land in git — but `.almightygpt/
24
+ * config.yaml` and `.almightygpt/rules.md` MUST. So we ignore the runs
25
+ * subfolder, not the whole `.almightygpt/` directory.
26
+ */
27
+ const GITIGNORE_HEADER = "# AlmightyGPT — machine-only run metadata (do not commit)";
28
+ const GITIGNORE_ENTRIES = [
29
+ ".almightygpt/runs/",
30
+ ".almightygpt/credentials.yaml",
31
+ ".almightygpt/credentials.json",
32
+ ];
21
33
  const __filename = fileURLToPath(import.meta.url);
22
34
  // In dev (ts-node-esm) and in built form, the templates package lives at the
23
35
  // same monorepo root. Find it by walking up until we hit packages/templates.
@@ -120,7 +132,78 @@ export async function installTemplate(options) {
120
132
  await writeFile(destAbs, content);
121
133
  written.push(destRel);
122
134
  }
123
- return { written, skipped, backedUp };
135
+ const gitignoreResult = await ensureGitignoreCovers(targetDir, dryRun);
136
+ return {
137
+ written,
138
+ skipped,
139
+ backedUp,
140
+ gitignoreAppended: gitignoreResult.added,
141
+ gitignoreAlreadyPresent: gitignoreResult.alreadyPresent,
142
+ gitignoreCreated: gitignoreResult.created,
143
+ };
144
+ }
145
+ /**
146
+ * Ensure the host repo's `.gitignore` covers `.almightygpt/runs/` and
147
+ * credential files. Creates `.gitignore` if it doesn't exist. Appends only
148
+ * the missing entries (idempotent — safe to call on every `init`).
149
+ *
150
+ * Returns a report so the CLI can show the user what changed.
151
+ */
152
+ async function ensureGitignoreCovers(targetDir, dryRun) {
153
+ const gitignorePath = join(targetDir, ".gitignore");
154
+ let existing = "";
155
+ let created = false;
156
+ try {
157
+ existing = await readFile(gitignorePath, "utf-8");
158
+ }
159
+ catch {
160
+ // File doesn't exist — we'll create it.
161
+ created = true;
162
+ }
163
+ const lines = new Set(existing
164
+ .split(/\r?\n/)
165
+ .map((l) => l.trim())
166
+ .filter(Boolean));
167
+ // An entry is already covered if (a) it's literally there, (b) its
168
+ // no-trailing-slash form is there, or (c) the user has `.almightygpt/`
169
+ // or `.almightygpt` ignoring the whole folder.
170
+ const alreadyCovers = (entry) => {
171
+ if (lines.has(entry))
172
+ return true;
173
+ if (lines.has(entry.replace(/\/$/, "")))
174
+ return true;
175
+ if (lines.has(".almightygpt/"))
176
+ return true;
177
+ if (lines.has(".almightygpt"))
178
+ return true;
179
+ return false;
180
+ };
181
+ const toAdd = [];
182
+ const alreadyPresent = [];
183
+ for (const entry of GITIGNORE_ENTRIES) {
184
+ if (alreadyCovers(entry))
185
+ alreadyPresent.push(entry);
186
+ else
187
+ toAdd.push(entry);
188
+ }
189
+ if (toAdd.length === 0 || dryRun) {
190
+ return { added: toAdd, alreadyPresent, created: created && !dryRun };
191
+ }
192
+ const hasHeader = existing.includes(GITIGNORE_HEADER);
193
+ const headerLine = hasHeader ? "" : `${GITIGNORE_HEADER}\n`;
194
+ const block = headerLine + toAdd.join("\n") + "\n";
195
+ let newContent;
196
+ if (!existing) {
197
+ newContent = block;
198
+ }
199
+ else if (existing.endsWith("\n")) {
200
+ newContent = existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
201
+ }
202
+ else {
203
+ newContent = existing + "\n\n" + block;
204
+ }
205
+ await writeFile(gitignorePath, newContent);
206
+ return { added: toAdd, alreadyPresent, created };
124
207
  }
125
208
  /**
126
209
  * Find a free `<file>.almighty-bak[.N]` slot for an existing file.
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/templates/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/templates/install.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almightygpt/core",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Core orchestrator, adapters, config, runs, and review logic for AlmightyGPT",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/index.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * - budget/ ✅ task #14 BudgetTracker + BudgetExceededError
14
14
  */
15
15
 
16
- export const VERSION = "0.7.1";
16
+ export const VERSION = "0.7.2";
17
17
 
18
18
  // Git safety primitives
19
19
  export {
@@ -43,8 +43,32 @@ export interface InstallResult {
43
43
  skipped: { path: string; reason: string }[];
44
44
  /** Files that were backed up before being overwritten. */
45
45
  backedUp: { from: string; to: string }[];
46
+ /**
47
+ * Entries appended to the target repo's `.gitignore`. Empty if everything
48
+ * was already covered (e.g. user had `.almightygpt/` blanket-ignored, or
49
+ * had previously run init).
50
+ */
51
+ gitignoreAppended: string[];
52
+ /** Entries that were already present in `.gitignore` and didn't need adding. */
53
+ gitignoreAlreadyPresent: string[];
54
+ /** True if init created the `.gitignore` file (didn't exist). */
55
+ gitignoreCreated: boolean;
46
56
  }
47
57
 
58
+ /**
59
+ * Entries appended to the host repo's `.gitignore`. The product's machine
60
+ * metadata (per-run outputs) must never land in git — but `.almightygpt/
61
+ * config.yaml` and `.almightygpt/rules.md` MUST. So we ignore the runs
62
+ * subfolder, not the whole `.almightygpt/` directory.
63
+ */
64
+ const GITIGNORE_HEADER =
65
+ "# AlmightyGPT — machine-only run metadata (do not commit)";
66
+ const GITIGNORE_ENTRIES = [
67
+ ".almightygpt/runs/",
68
+ ".almightygpt/credentials.yaml",
69
+ ".almightygpt/credentials.json",
70
+ ];
71
+
48
72
  const __filename = fileURLToPath(import.meta.url);
49
73
  // In dev (ts-node-esm) and in built form, the templates package lives at the
50
74
  // same monorepo root. Find it by walking up until we hit packages/templates.
@@ -162,7 +186,83 @@ export async function installTemplate(
162
186
  written.push(destRel);
163
187
  }
164
188
 
165
- return { written, skipped, backedUp };
189
+ const gitignoreResult = await ensureGitignoreCovers(targetDir, dryRun);
190
+
191
+ return {
192
+ written,
193
+ skipped,
194
+ backedUp,
195
+ gitignoreAppended: gitignoreResult.added,
196
+ gitignoreAlreadyPresent: gitignoreResult.alreadyPresent,
197
+ gitignoreCreated: gitignoreResult.created,
198
+ };
199
+ }
200
+
201
+ /**
202
+ * Ensure the host repo's `.gitignore` covers `.almightygpt/runs/` and
203
+ * credential files. Creates `.gitignore` if it doesn't exist. Appends only
204
+ * the missing entries (idempotent — safe to call on every `init`).
205
+ *
206
+ * Returns a report so the CLI can show the user what changed.
207
+ */
208
+ async function ensureGitignoreCovers(
209
+ targetDir: string,
210
+ dryRun: boolean,
211
+ ): Promise<{ added: string[]; alreadyPresent: string[]; created: boolean }> {
212
+ const gitignorePath = join(targetDir, ".gitignore");
213
+ let existing = "";
214
+ let created = false;
215
+ try {
216
+ existing = await readFile(gitignorePath, "utf-8");
217
+ } catch {
218
+ // File doesn't exist — we'll create it.
219
+ created = true;
220
+ }
221
+
222
+ const lines = new Set(
223
+ existing
224
+ .split(/\r?\n/)
225
+ .map((l) => l.trim())
226
+ .filter(Boolean),
227
+ );
228
+
229
+ // An entry is already covered if (a) it's literally there, (b) its
230
+ // no-trailing-slash form is there, or (c) the user has `.almightygpt/`
231
+ // or `.almightygpt` ignoring the whole folder.
232
+ const alreadyCovers = (entry: string): boolean => {
233
+ if (lines.has(entry)) return true;
234
+ if (lines.has(entry.replace(/\/$/, ""))) return true;
235
+ if (lines.has(".almightygpt/")) return true;
236
+ if (lines.has(".almightygpt")) return true;
237
+ return false;
238
+ };
239
+
240
+ const toAdd: string[] = [];
241
+ const alreadyPresent: string[] = [];
242
+ for (const entry of GITIGNORE_ENTRIES) {
243
+ if (alreadyCovers(entry)) alreadyPresent.push(entry);
244
+ else toAdd.push(entry);
245
+ }
246
+
247
+ if (toAdd.length === 0 || dryRun) {
248
+ return { added: toAdd, alreadyPresent, created: created && !dryRun };
249
+ }
250
+
251
+ const hasHeader = existing.includes(GITIGNORE_HEADER);
252
+ const headerLine = hasHeader ? "" : `${GITIGNORE_HEADER}\n`;
253
+ const block = headerLine + toAdd.join("\n") + "\n";
254
+
255
+ let newContent: string;
256
+ if (!existing) {
257
+ newContent = block;
258
+ } else if (existing.endsWith("\n")) {
259
+ newContent = existing + (existing.endsWith("\n\n") ? "" : "\n") + block;
260
+ } else {
261
+ newContent = existing + "\n\n" + block;
262
+ }
263
+
264
+ await writeFile(gitignorePath, newContent);
265
+ return { added: toAdd, alreadyPresent, created };
166
266
  }
167
267
 
168
268
  /**