ghagga 3.1.0 → 3.2.0

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 (54) hide show
  1. package/dist/commands/memory/backfill.d.ts +13 -0
  2. package/dist/commands/memory/backfill.d.ts.map +1 -0
  3. package/dist/commands/memory/backfill.js +47 -0
  4. package/dist/commands/memory/backfill.js.map +1 -0
  5. package/dist/commands/memory/backfill.test.d.ts +11 -0
  6. package/dist/commands/memory/backfill.test.d.ts.map +1 -0
  7. package/dist/commands/memory/backfill.test.js +127 -0
  8. package/dist/commands/memory/backfill.test.js.map +1 -0
  9. package/dist/commands/memory/clear.test.js +9 -0
  10. package/dist/commands/memory/clear.test.js.map +1 -1
  11. package/dist/commands/memory/delete.test.js +9 -0
  12. package/dist/commands/memory/delete.test.js.map +1 -1
  13. package/dist/commands/memory/index.d.ts +3 -3
  14. package/dist/commands/memory/index.d.ts.map +1 -1
  15. package/dist/commands/memory/index.js +5 -3
  16. package/dist/commands/memory/index.js.map +1 -1
  17. package/dist/commands/memory/list.test.js +9 -0
  18. package/dist/commands/memory/list.test.js.map +1 -1
  19. package/dist/commands/memory/search.test.js +9 -0
  20. package/dist/commands/memory/search.test.js.map +1 -1
  21. package/dist/commands/memory/show.test.js +9 -0
  22. package/dist/commands/memory/show.test.js.map +1 -1
  23. package/dist/commands/memory/stats.test.js +9 -0
  24. package/dist/commands/memory/stats.test.js.map +1 -1
  25. package/dist/commands/memory/utils.d.ts.map +1 -1
  26. package/dist/commands/memory/utils.js +14 -1
  27. package/dist/commands/memory/utils.js.map +1 -1
  28. package/dist/commands/review-output.test.js +9 -0
  29. package/dist/commands/review-output.test.js.map +1 -1
  30. package/dist/commands/review.d.ts.map +1 -1
  31. package/dist/commands/review.js +14 -2
  32. package/dist/commands/review.js.map +1 -1
  33. package/dist/commands/review.test.js +9 -0
  34. package/dist/commands/review.test.js.map +1 -1
  35. package/dist/lib/cli-gitlab-client-port.test.js +38 -24
  36. package/dist/lib/cli-gitlab-client-port.test.js.map +1 -1
  37. package/dist/lib/config.d.ts +11 -0
  38. package/dist/lib/config.d.ts.map +1 -1
  39. package/dist/lib/config.js.map +1 -1
  40. package/dist/lib/embedding.d.ts +23 -0
  41. package/dist/lib/embedding.d.ts.map +1 -0
  42. package/dist/lib/embedding.js +39 -0
  43. package/dist/lib/embedding.js.map +1 -0
  44. package/dist/lib/embedding.test.d.ts +8 -0
  45. package/dist/lib/embedding.test.d.ts.map +1 -0
  46. package/dist/lib/embedding.test.js +101 -0
  47. package/dist/lib/embedding.test.js.map +1 -0
  48. package/dist/lib/gitlab-e2e.manual.test.d.ts +38 -5
  49. package/dist/lib/gitlab-e2e.manual.test.d.ts.map +1 -1
  50. package/dist/lib/gitlab-e2e.manual.test.js +93 -15
  51. package/dist/lib/gitlab-e2e.manual.test.js.map +1 -1
  52. package/dist/lib/pr-postback.test.js +40 -24
  53. package/dist/lib/pr-postback.test.js.map +1 -1
  54. package/package.json +7 -7
@@ -19,6 +19,17 @@ export interface GhaggaCliConfig {
19
19
  defaultProvider?: string;
20
20
  /** Default model for the provider */
21
21
  defaultModel?: string;
22
+ /**
23
+ * Embedding provider config overrides (design D2). Config-file keys take
24
+ * precedence over the matching `EMBEDDING_*` env vars — see
25
+ * `resolveCliEmbeddingConfig` in `./embedding.js`.
26
+ */
27
+ embeddingProvider?: string;
28
+ embeddingModel?: string;
29
+ embeddingBaseUrl?: string;
30
+ embeddingApiKey?: string;
31
+ embeddingDimension?: number;
32
+ embeddingCandidateK?: number;
22
33
  }
23
34
  export declare function getConfigDir(): string;
24
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2BAA2B;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,wBAAgB,YAAY,IAAI,MAAM,CAIrC;AAQD;;GAEG;AACH,wBAAgB,UAAU,IAAI,eAAe,CAa5C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAYxD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAGpC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAG9C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAGpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2BAA2B;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAID,wBAAgB,YAAY,IAAI,MAAM,CAIrC;AAQD;;GAEG;AACH,wBAAgB,UAAU,IAAI,eAAe,CAa5C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAYxD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAGpC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAG9C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAGpD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAyBjC,mEAAmE;AAEnE,MAAM,UAAU,YAAY;IAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9C,MAAM,IAAI,GAAG,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,mEAAmE;AAEnE;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAuB;IAChD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,aAAa,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QAChE,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,UAAU,CAAC,EAAE,CAAC,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,aAAa,EAAE,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAqCjC,mEAAmE;AAEnE,MAAM,UAAU,YAAY;IAC1B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9C,MAAM,IAAI,GAAG,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACrD,OAAO,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,mEAAmE;AAEnE;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAuB;IAChD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,aAAa,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QAChE,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,UAAU,CAAC,EAAE,CAAC,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,aAAa,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * CLI embedding provider resolution (design D2, task 5.2).
3
+ *
4
+ * Merges the `EMBEDDING_*` keys stored in `~/.config/ghagga/config.json`
5
+ * over `process.env` before delegating to `resolveEmbeddingConfig` /
6
+ * `createEmbeddingProvider` from `ghagga-core` — the same resolver every
7
+ * construction site (server, CLI, Action) shares. Config-file values win
8
+ * over env so `ghagga login`-style persisted preferences aren't shadowed
9
+ * by ambient env vars.
10
+ */
11
+ import type { EmbeddingConfig, EmbeddingProvider } from 'ghagga-core';
12
+ /** Resolve the merged embedding config (config-file over env, design D2). */
13
+ export declare function resolveCliEmbeddingConfig(): EmbeddingConfig;
14
+ /**
15
+ * Resolve the merged config AND build the concrete provider in one call —
16
+ * the common case for every SqliteMemoryStorage construction site.
17
+ * Returns `provider: undefined` when unconfigured (`none`-default parity).
18
+ */
19
+ export declare function resolveCliEmbeddingProvider(): {
20
+ config: EmbeddingConfig;
21
+ provider: EmbeddingProvider | undefined;
22
+ };
23
+ //# sourceMappingURL=embedding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.d.ts","sourceRoot":"","sources":["../../src/lib/embedding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAItE,6EAA6E;AAC7E,wBAAgB,yBAAyB,IAAI,eAAe,CAmB3D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,IAAI;IAC7C,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;CACzC,CAGA"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * CLI embedding provider resolution (design D2, task 5.2).
3
+ *
4
+ * Merges the `EMBEDDING_*` keys stored in `~/.config/ghagga/config.json`
5
+ * over `process.env` before delegating to `resolveEmbeddingConfig` /
6
+ * `createEmbeddingProvider` from `ghagga-core` — the same resolver every
7
+ * construction site (server, CLI, Action) shares. Config-file values win
8
+ * over env so `ghagga login`-style persisted preferences aren't shadowed
9
+ * by ambient env vars.
10
+ */
11
+ import { createEmbeddingProvider, resolveEmbeddingConfig } from 'ghagga-core';
12
+ import { loadConfig } from './config.js';
13
+ /** Resolve the merged embedding config (config-file over env, design D2). */
14
+ export function resolveCliEmbeddingConfig() {
15
+ const fileConfig = loadConfig();
16
+ const merged = {
17
+ EMBEDDING_PROVIDER: fileConfig.embeddingProvider ?? process.env.EMBEDDING_PROVIDER,
18
+ EMBEDDING_MODEL: fileConfig.embeddingModel ?? process.env.EMBEDDING_MODEL,
19
+ EMBEDDING_BASE_URL: fileConfig.embeddingBaseUrl ?? process.env.EMBEDDING_BASE_URL,
20
+ EMBEDDING_API_KEY: fileConfig.embeddingApiKey ?? process.env.EMBEDDING_API_KEY,
21
+ EMBEDDING_DIMENSION: fileConfig.embeddingDimension !== undefined
22
+ ? String(fileConfig.embeddingDimension)
23
+ : process.env.EMBEDDING_DIMENSION,
24
+ EMBEDDING_CANDIDATE_K: fileConfig.embeddingCandidateK !== undefined
25
+ ? String(fileConfig.embeddingCandidateK)
26
+ : process.env.EMBEDDING_CANDIDATE_K,
27
+ };
28
+ return resolveEmbeddingConfig(merged);
29
+ }
30
+ /**
31
+ * Resolve the merged config AND build the concrete provider in one call —
32
+ * the common case for every SqliteMemoryStorage construction site.
33
+ * Returns `provider: undefined` when unconfigured (`none`-default parity).
34
+ */
35
+ export function resolveCliEmbeddingProvider() {
36
+ const config = resolveCliEmbeddingConfig();
37
+ return { config, provider: createEmbeddingProvider(config) ?? undefined };
38
+ }
39
+ //# sourceMappingURL=embedding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.js","sourceRoot":"","sources":["../../src/lib/embedding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,6EAA6E;AAC7E,MAAM,UAAU,yBAAyB;IACvC,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;IAEhC,MAAM,MAAM,GAAuC;QACjD,kBAAkB,EAAE,UAAU,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAClF,eAAe,EAAE,UAAU,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;QACzE,kBAAkB,EAAE,UAAU,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;QACjF,iBAAiB,EAAE,UAAU,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC9E,mBAAmB,EACjB,UAAU,CAAC,kBAAkB,KAAK,SAAS;YACzC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC;YACvC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB;QACrC,qBAAqB,EACnB,UAAU,CAAC,mBAAmB,KAAK,SAAS;YAC1C,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC;YACxC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB;KACxC,CAAC;IAEF,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B;IAIzC,MAAM,MAAM,GAAG,yBAAyB,EAAE,CAAC;IAC3C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,uBAAuB,CAAC,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tests for CLI embedding provider resolution (design D2, task 5.2/5.4).
3
+ *
4
+ * Mocks `./config.js` (loadConfig) to isolate the merge-precedence logic:
5
+ * config-file keys override the matching `EMBEDDING_*` env vars.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=embedding.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.test.d.ts","sourceRoot":"","sources":["../../src/lib/embedding.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Tests for CLI embedding provider resolution (design D2, task 5.2/5.4).
3
+ *
4
+ * Mocks `./config.js` (loadConfig) to isolate the merge-precedence logic:
5
+ * config-file keys override the matching `EMBEDDING_*` env vars.
6
+ */
7
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8
+ const { mockLoadConfig } = vi.hoisted(() => ({
9
+ mockLoadConfig: vi.fn(),
10
+ }));
11
+ vi.mock('./config.js', () => ({
12
+ loadConfig: () => mockLoadConfig(),
13
+ }));
14
+ import { resolveCliEmbeddingConfig, resolveCliEmbeddingProvider } from './embedding.js';
15
+ const ENV_KEYS = [
16
+ 'EMBEDDING_PROVIDER',
17
+ 'EMBEDDING_MODEL',
18
+ 'EMBEDDING_BASE_URL',
19
+ 'EMBEDDING_API_KEY',
20
+ 'EMBEDDING_DIMENSION',
21
+ 'EMBEDDING_CANDIDATE_K',
22
+ ];
23
+ let originalEnv;
24
+ beforeEach(() => {
25
+ vi.clearAllMocks();
26
+ mockLoadConfig.mockReturnValue({});
27
+ originalEnv = {};
28
+ for (const key of ENV_KEYS) {
29
+ originalEnv[key] = process.env[key];
30
+ delete process.env[key];
31
+ }
32
+ });
33
+ afterEach(() => {
34
+ for (const key of ENV_KEYS) {
35
+ if (originalEnv[key] === undefined) {
36
+ delete process.env[key];
37
+ }
38
+ else {
39
+ process.env[key] = originalEnv[key];
40
+ }
41
+ }
42
+ });
43
+ describe('resolveCliEmbeddingConfig', () => {
44
+ it('resolves to "none" when neither config file nor env is set', () => {
45
+ const config = resolveCliEmbeddingConfig();
46
+ expect(config.provider).toBe('none');
47
+ expect(config.candidateK).toBe(200);
48
+ expect(config.model).toBeUndefined();
49
+ });
50
+ it('falls back to env when the config file has no embedding keys', () => {
51
+ process.env.EMBEDDING_PROVIDER = 'openai-compatible';
52
+ process.env.EMBEDDING_MODEL = 'text-embedding-3-small';
53
+ process.env.EMBEDDING_BASE_URL = 'https://api.openai.com/v1';
54
+ process.env.EMBEDDING_DIMENSION = '1536';
55
+ const config = resolveCliEmbeddingConfig();
56
+ expect(config.provider).toBe('openai-compatible');
57
+ expect(config.model).toBe('text-embedding-3-small');
58
+ expect(config.dimension).toBe(1536);
59
+ });
60
+ it('prefers config-file values over env (design D2 precedence)', () => {
61
+ process.env.EMBEDDING_PROVIDER = 'openai-compatible';
62
+ process.env.EMBEDDING_MODEL = 'env-model';
63
+ mockLoadConfig.mockReturnValue({
64
+ embeddingProvider: 'openai-compatible',
65
+ embeddingModel: 'config-file-model',
66
+ embeddingBaseUrl: 'https://api.example.com/v1',
67
+ embeddingDimension: 768,
68
+ embeddingCandidateK: 42,
69
+ });
70
+ const config = resolveCliEmbeddingConfig();
71
+ expect(config.model).toBe('config-file-model');
72
+ expect(config.baseUrl).toBe('https://api.example.com/v1');
73
+ expect(config.dimension).toBe(768);
74
+ expect(config.candidateK).toBe(42);
75
+ });
76
+ });
77
+ describe('resolveCliEmbeddingProvider', () => {
78
+ it('returns provider: undefined when unconfigured (none-default parity)', () => {
79
+ const { provider, config } = resolveCliEmbeddingProvider();
80
+ expect(provider).toBeUndefined();
81
+ expect(config.provider).toBe('none');
82
+ });
83
+ it('returns a concrete provider when fully configured', () => {
84
+ mockLoadConfig.mockReturnValue({
85
+ embeddingProvider: 'openai-compatible',
86
+ embeddingModel: 'text-embedding-3-small',
87
+ embeddingBaseUrl: 'https://api.openai.com/v1',
88
+ embeddingDimension: 1536,
89
+ });
90
+ const { provider, config } = resolveCliEmbeddingProvider();
91
+ expect(provider).toBeDefined();
92
+ expect(provider?.dimension).toBe(1536);
93
+ expect(config.model).toBe('text-embedding-3-small');
94
+ });
95
+ it('an unknown provider id falls back to undefined (never throws)', () => {
96
+ mockLoadConfig.mockReturnValue({ embeddingProvider: 'totally-unknown' });
97
+ const { provider } = resolveCliEmbeddingProvider();
98
+ expect(provider).toBeUndefined();
99
+ });
100
+ });
101
+ //# sourceMappingURL=embedding.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.test.js","sourceRoot":"","sources":["../../src/lib/embedding.test.ts"],"names":[],"mappings":"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"}
@@ -5,20 +5,53 @@
5
5
  * coverage of the GitLab REST surface lives in `cli-gitlab-client-port.test.ts`
6
6
  * (fetch-mocked). This file is the real-instance sign-off the spec mandates.
7
7
  *
8
+ * ENVIRONMENT VARIABLES
9
+ * ---------------------
10
+ * REQUIRED:
11
+ * GITLAB_PAT a Personal Access Token with the `api` scope.
12
+ * GITLAB_E2E_PROJECT the `group/project` path (nested groups OK,
13
+ * e.g. `group/subgroup/project`).
14
+ * GITLAB_E2E_MR the iid of an OPEN, throwaway MR in that project. The
15
+ * test posts and sweeps notes on it, so it MUST be a
16
+ * disposable MR you control — never a real review.
17
+ * OPTIONAL (self-hosted GitLab — gitlab.com is the default):
18
+ * GITLAB_HOST a host-only override (e.g. `gitlab.example.com`) when the
19
+ * API host differs from gitlab.com.
20
+ * GITLAB_API_BASE a FULL `.../api/v4` base override, required for a
21
+ * self-managed GitLab served under a subpath
22
+ * (e.g. `https://example.com/gitlab/api/v4`). Wins over
23
+ * GITLAB_HOST. Both are resolved through the SAME
24
+ * production helper (`resolveGitLabApiBase`) the `--mr`
25
+ * command path uses, so this test exercises the real
26
+ * self-hosted resolution — not a test-only shortcut.
27
+ *
8
28
  * HOW TO RUN IT MANUALLY
9
29
  * ----------------------
10
- * Against a throwaway GitLab project + open MR you control:
30
+ * Against a throwaway GitLab project + OPEN, disposable MR you control:
11
31
  *
12
32
  * export GITLAB_PAT=glpat-xxxxxxxxxxxxxxxxxxxx # PAT with `api` scope
13
33
  * export GITLAB_E2E_PROJECT=group/your-project # group/project path
14
- * export GITLAB_E2E_MR=1 # an OPEN MR iid in it
34
+ * export GITLAB_E2E_MR=1 # an OPEN, throwaway MR iid
35
+ * # optional self-hosted: export GITLAB_HOST=gitlab.example.com
15
36
  * pnpm --filter ghagga exec vitest run src/lib/gitlab-e2e.manual.test.ts
16
37
  *
17
38
  * It will: resolve the numeric project id from the path, post (idempotently
18
39
  * upsert) a marker-tagged summary note to the MR, assert the returned id is a
19
- * positive number, then run a SECOND upsert and assert the first note was swept
20
- * (deletedNativeIds non-empty) proving the find→delete→repost idempotency
21
- * against the live API. Inspect the MR afterwards: exactly ONE GHAGGA note.
40
+ * positive number AND that the SPECIFIC note production just created
41
+ * (first.createdNativeId) is live on the MR carrying MARKER.html, then run a
42
+ * SECOND upsert and assert (a) the first note's id is in deletedNativeIds and
43
+ * (b) against the real MR state exactly ONE marker note remains and it is the
44
+ * second note — proving the find→delete→repost idempotency FOLD against the
45
+ * live API. An `afterAll` ATTEMPTS to leave zero leftover notes (best-effort; a
46
+ * transient GitLab failure may leave one, which the next run's sweep removes).
47
+ *
48
+ * MARKER OWNERSHIP NOTE: the marker is OWNED BY THE CALLER, not the adapter —
49
+ * the test renders it into `body` (see where `body` is built below). Production
50
+ * never injects it; `upsertSummaryComment` only USES `marker.html` to FILTER
51
+ * which notes to sweep (gitlab-forge-adapter.ts:182). So the anchored assertion
52
+ * below simply verifies that the note production created persists with the
53
+ * marker on live GitLab; the "exactly one marker note after the repost" check
54
+ * is what actually proves the idempotency fold against real MR state.
22
55
  */
23
56
  export {};
24
57
  //# sourceMappingURL=gitlab-e2e.manual.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gitlab-e2e.manual.test.d.ts","sourceRoot":"","sources":["../../src/lib/gitlab-e2e.manual.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
1
+ {"version":3,"file":"gitlab-e2e.manual.test.d.ts","sourceRoot":"","sources":["../../src/lib/gitlab-e2e.manual.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG"}
@@ -5,41 +5,100 @@
5
5
  * coverage of the GitLab REST surface lives in `cli-gitlab-client-port.test.ts`
6
6
  * (fetch-mocked). This file is the real-instance sign-off the spec mandates.
7
7
  *
8
+ * ENVIRONMENT VARIABLES
9
+ * ---------------------
10
+ * REQUIRED:
11
+ * GITLAB_PAT a Personal Access Token with the `api` scope.
12
+ * GITLAB_E2E_PROJECT the `group/project` path (nested groups OK,
13
+ * e.g. `group/subgroup/project`).
14
+ * GITLAB_E2E_MR the iid of an OPEN, throwaway MR in that project. The
15
+ * test posts and sweeps notes on it, so it MUST be a
16
+ * disposable MR you control — never a real review.
17
+ * OPTIONAL (self-hosted GitLab — gitlab.com is the default):
18
+ * GITLAB_HOST a host-only override (e.g. `gitlab.example.com`) when the
19
+ * API host differs from gitlab.com.
20
+ * GITLAB_API_BASE a FULL `.../api/v4` base override, required for a
21
+ * self-managed GitLab served under a subpath
22
+ * (e.g. `https://example.com/gitlab/api/v4`). Wins over
23
+ * GITLAB_HOST. Both are resolved through the SAME
24
+ * production helper (`resolveGitLabApiBase`) the `--mr`
25
+ * command path uses, so this test exercises the real
26
+ * self-hosted resolution — not a test-only shortcut.
27
+ *
8
28
  * HOW TO RUN IT MANUALLY
9
29
  * ----------------------
10
- * Against a throwaway GitLab project + open MR you control:
30
+ * Against a throwaway GitLab project + OPEN, disposable MR you control:
11
31
  *
12
32
  * export GITLAB_PAT=glpat-xxxxxxxxxxxxxxxxxxxx # PAT with `api` scope
13
33
  * export GITLAB_E2E_PROJECT=group/your-project # group/project path
14
- * export GITLAB_E2E_MR=1 # an OPEN MR iid in it
34
+ * export GITLAB_E2E_MR=1 # an OPEN, throwaway MR iid
35
+ * # optional self-hosted: export GITLAB_HOST=gitlab.example.com
15
36
  * pnpm --filter ghagga exec vitest run src/lib/gitlab-e2e.manual.test.ts
16
37
  *
17
38
  * It will: resolve the numeric project id from the path, post (idempotently
18
39
  * upsert) a marker-tagged summary note to the MR, assert the returned id is a
19
- * positive number, then run a SECOND upsert and assert the first note was swept
20
- * (deletedNativeIds non-empty) proving the find→delete→repost idempotency
21
- * against the live API. Inspect the MR afterwards: exactly ONE GHAGGA note.
40
+ * positive number AND that the SPECIFIC note production just created
41
+ * (first.createdNativeId) is live on the MR carrying MARKER.html, then run a
42
+ * SECOND upsert and assert (a) the first note's id is in deletedNativeIds and
43
+ * (b) against the real MR state exactly ONE marker note remains and it is the
44
+ * second note — proving the find→delete→repost idempotency FOLD against the
45
+ * live API. An `afterAll` ATTEMPTS to leave zero leftover notes (best-effort; a
46
+ * transient GitLab failure may leave one, which the next run's sweep removes).
47
+ *
48
+ * MARKER OWNERSHIP NOTE: the marker is OWNED BY THE CALLER, not the adapter —
49
+ * the test renders it into `body` (see where `body` is built below). Production
50
+ * never injects it; `upsertSummaryComment` only USES `marker.html` to FILTER
51
+ * which notes to sweep (gitlab-forge-adapter.ts:182). So the anchored assertion
52
+ * below simply verifies that the note production created persists with the
53
+ * marker on live GitLab; the "exactly one marker note after the repost" check
54
+ * is what actually proves the idempotency fold against real MR state.
22
55
  */
23
56
  import { GitLabForgeAdapter } from 'ghagga-forge';
24
- import { describe, expect, it } from 'vitest';
25
- import { createCliGitLabClientPort, resolveGitLabProjectId } from './cli-gitlab-client-port.js';
57
+ import { afterAll, describe, expect, it } from 'vitest';
58
+ import { createCliGitLabClientPort, resolveGitLabApiBase, resolveGitLabProjectId, } from './cli-gitlab-client-port.js';
26
59
  import { postSummaryComment } from './pr-postback.js';
27
60
  const PAT = process.env.GITLAB_PAT;
28
61
  const PROJECT_PATH = process.env.GITLAB_E2E_PROJECT ?? '';
29
62
  const MR_IID = Number.parseInt(process.env.GITLAB_E2E_MR ?? '', 10);
30
63
  const MARKER = { html: '<!-- ghagga-review -->' };
64
+ /**
65
+ * Resolve the API base the SAME way the production `--mr` command path does:
66
+ * feed gitlab.com as the remote-derived host and let GITLAB_HOST / GITLAB_API_BASE
67
+ * override it (resolveGitLabApiBase precedence). With no override this is exactly
68
+ * the gitlab.com default the back-compat callers use.
69
+ */
70
+ const API_BASE = resolveGitLabApiBase('gitlab.com');
31
71
  describe('GitLab MR summary post-back — LIVE E2E (manual gate, R-GITLAB)', () => {
32
- it.skipIf(!PAT)('resolves numeric project id + posts a summary note + sweeps the stale one on re-run', async () => {
72
+ // Note ids created during the test, swept best-effort in afterAll so the
73
+ // throwaway MR is left clean. Only populated when the test actually runs
74
+ // (it is empty when skipped without a PAT, so afterAll is a no-op).
75
+ const createdNoteIds = [];
76
+ let client;
77
+ let projectId;
78
+ const token = PAT;
79
+ afterAll(async () => {
80
+ // Best-effort cleanup: tolerate a per-note failure (404 / already gone /
81
+ // transient) so a delete error never fails the suite. Skipped entirely when
82
+ // the test did not run (no client / projectId resolved → nothing created).
83
+ if (!PAT || client == null || projectId == null)
84
+ return;
85
+ for (const noteId of createdNoteIds) {
86
+ try {
87
+ await client.deleteMrNote(projectId, MR_IID, noteId, token);
88
+ }
89
+ catch {
90
+ // Tolerate: leaving a stray note is better than failing the suite on
91
+ // cleanup. The next manual run's sweep removes it anyway.
92
+ }
93
+ }
94
+ });
95
+ it.skipIf(!PAT)('resolves numeric project id + posts a marker-tagged note + sweeps the stale one on re-run', async () => {
33
96
  expect(PROJECT_PATH, 'set GITLAB_E2E_PROJECT=group/project').not.toBe('');
34
97
  expect(Number.isInteger(MR_IID) && MR_IID > 0, 'set GITLAB_E2E_MR=<open MR iid>').toBe(true);
35
- const token = PAT;
36
- const projectId = await resolveGitLabProjectId(PROJECT_PATH, token);
98
+ projectId = await resolveGitLabProjectId(PROJECT_PATH, token, API_BASE);
37
99
  expect(projectId).toMatch(/^\d+$/); // numeric project id (R-GITLAB nativeId)
38
- const adapter = new GitLabForgeAdapter({
39
- client: createCliGitLabClientPort(),
40
- token,
41
- projectId,
42
- });
100
+ client = createCliGitLabClientPort(API_BASE);
101
+ const adapter = new GitLabForgeAdapter({ client, token, projectId });
43
102
  const ref = {
44
103
  repo: { kind: 'gitlab', nativeId: projectId, path: PROJECT_PATH },
45
104
  iid: MR_IID,
@@ -48,10 +107,29 @@ describe('GitLab MR summary post-back — LIVE E2E (manual gate, R-GITLAB)', ()
48
107
  // First upsert: posts a fresh note.
49
108
  const first = await postSummaryComment(adapter, ref, body, MARKER);
50
109
  expect(first.createdNativeId).toBeGreaterThan(0);
110
+ createdNoteIds.push(first.createdNativeId);
111
+ // Marker persistence: anchor the assertion to the note PRODUCTION created
112
+ // (first.createdNativeId === GitLabNote.id), not to "any note that happens
113
+ // to carry the marker". This proves the specific note the upsert posted is
114
+ // live on the MR AND still carries the marker the adapter's sweep filters
115
+ // on (gitlab-forge-adapter.ts:182).
116
+ const afterFirst = await client.listMrNotes(projectId, MR_IID, token);
117
+ const createdNote = afterFirst.find((n) => n.id === first.createdNativeId);
118
+ expect(createdNote, 'the note created by upsert must appear in the live listing').toBeDefined();
119
+ expect(createdNote?.body.includes(MARKER.html), 'the created note must carry the marker the sweep filters on').toBe(true);
51
120
  // Second upsert: must SWEEP the first (idempotency) and repost.
52
121
  const second = await postSummaryComment(adapter, ref, body, MARKER);
53
122
  expect(second.createdNativeId).toBeGreaterThan(0);
123
+ createdNoteIds.push(second.createdNativeId);
54
124
  expect(second.deletedNativeIds).toContain(first.createdNativeId);
125
+ // Idempotency FOLD against the REAL MR state (not just the return value):
126
+ // after the repost exactly ONE marker note must remain, and it must be the
127
+ // note the SECOND upsert created. This is the invariant the sweep exists to
128
+ // hold — complements the `deletedNativeIds toContain first` return-value check.
129
+ const afterSecond = await client.listMrNotes(projectId, MR_IID, token);
130
+ const markerNotes = afterSecond.filter((n) => n.body.includes(MARKER.html));
131
+ expect(markerNotes.length, 'the sweep must leave exactly one note carrying the marker').toBe(1);
132
+ expect(markerNotes[0]?.id).toBe(second.createdNativeId);
55
133
  }, 30_000);
56
134
  });
57
135
  //# sourceMappingURL=gitlab-e2e.manual.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gitlab-e2e.manual.test.js","sourceRoot":"","sources":["../../src/lib/gitlab-e2e.manual.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AACnC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC;AAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;AACpE,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;AAElD,QAAQ,CAAC,gEAAgE,EAAE,GAAG,EAAE;IAC9E,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CACb,qFAAqF,EACrF,KAAK,IAAI,EAAE;QACT,MAAM,CAAC,YAAY,EAAE,sCAAsC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,iCAAiC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE7F,MAAM,KAAK,GAAG,GAAa,CAAC;QAC5B,MAAM,SAAS,GAAG,MAAM,sBAAsB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACpE,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,yCAAyC;QAE7E,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC;YACrC,MAAM,EAAE,yBAAyB,EAAE;YACnC,KAAK;YACL,SAAS;SACV,CAAC,CAAC;QACH,MAAM,GAAG,GAAG;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE;YAC1E,GAAG,EAAE,MAAM;SACZ,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,IAAI,8BAA8B,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAEpF,oCAAoC;QACpC,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACnE,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAEjD,gEAAgE;QAChE,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACnE,CAAC,EACD,MAAM,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"gitlab-e2e.manual.test.js","sourceRoot":"","sources":["../../src/lib/gitlab-e2e.manual.test.ts"],"names":[],"mappings":"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"}
@@ -55,31 +55,43 @@ describe('postSummaryComment via CLI port + GitHubForgeAdapter', () => {
55
55
  expect(postInit.method).toBe('POST');
56
56
  expect(JSON.parse(postInit.body)).toEqual({ body });
57
57
  });
58
- it('finds stale → deletes ALLreposts fresh (idempotent upsert + marker)', async () => {
58
+ it('finds stale → updates latest IN PLACE prunes only stale duplicates (idempotent upsert + marker)', async () => {
59
59
  // list returns two GHAGGA comments (with marker) + one foreign comment
60
60
  mockFetch.mockResolvedValueOnce(jsonResponse(200, [
61
61
  { id: 100, body: `old ${REVIEW_COMMENT_MARKER}` },
62
62
  { id: 200, body: 'someone else' },
63
63
  { id: 300, body: `newer ${REVIEW_COMMENT_MARKER}` },
64
64
  ]));
65
- // deleteComment(latest=300), deleteComment(stale=100)
65
+ // FORGE-UPSERT-005: updateComment(latest=300) IN PLACE first...
66
+ mockFetch.mockResolvedValueOnce(jsonResponse(200, { id: 300 }));
67
+ // ...then deleteComment(stale=100) only after the update confirms success.
66
68
  mockFetch.mockResolvedValueOnce(jsonResponse(204, {}));
67
- mockFetch.mockResolvedValueOnce(jsonResponse(204, {}));
68
- // postComment fresh
69
- mockFetch.mockResolvedValueOnce(jsonResponse(201, { id: 400 }));
70
69
  const adapter = buildAdapter();
71
70
  const result = await postSummaryComment(adapter, REF, 'body', MARKER);
72
- expect(result.createdNativeId).toBe(400);
73
- // delete order: latest first, then stale.
74
- expect(result.deletedNativeIds).toEqual([300, 100]);
75
- const delCall1 = mockFetch.mock.calls[1];
76
- const delCall2 = mockFetch.mock.calls[2];
77
- expect(delCall1[0]).toContain('/issues/comments/300');
78
- expect(delCall1[1].method).toBe('DELETE');
79
- expect(delCall2[0]).toContain('/issues/comments/100');
80
- // foreign comment (200) is never deleted.
71
+ // "created" now carries the id of the comment currently holding the review
72
+ // body the updated latest (300), NOT a freshly posted comment.
73
+ expect(result.createdNativeId).toBe(300);
74
+ // The latest (300) is updated, never deleted; only the stale duplicate (100) is pruned.
75
+ expect(result.deletedNativeIds).toEqual([100]);
76
+ // Update happens in place (PATCH) on the latest, before any delete.
77
+ const updateCall = mockFetch.mock.calls[1];
78
+ expect(updateCall[0]).toContain('/issues/comments/300');
79
+ expect(updateCall[1].method).toBe('PATCH');
80
+ expect(JSON.parse(updateCall[1].body)).toEqual({ body: 'body' });
81
+ const delCall = mockFetch.mock.calls[2];
82
+ expect(delCall[0]).toContain('/issues/comments/100');
83
+ expect(delCall[1].method).toBe('DELETE');
84
+ // The latest (300) is updated, never the target of a DELETE.
85
+ const deleteUrls = mockFetch.mock.calls
86
+ .filter((c) => c[1].method === 'DELETE')
87
+ .map((c) => c[0]);
88
+ expect(deleteUrls.some((u) => u.includes('/issues/comments/300'))).toBe(false);
89
+ // foreign comment (200) is never touched.
81
90
  const allUrls = mockFetch.mock.calls.map((c) => c[0]).join('\n');
82
91
  expect(allUrls).not.toContain('/issues/comments/200');
92
+ // No fresh POST on the replace path — the update carried the body.
93
+ const methods = mockFetch.mock.calls.map((c) => c[1].method);
94
+ expect(methods).not.toContain('POST');
83
95
  });
84
96
  it('a 401 with the static token is fatal (no invalidate-retry)', async () => {
85
97
  // findExistingComment → 401
@@ -127,22 +139,26 @@ describe('CLI GitHub port — findExistingComment pagination (backlog #6)', () =
127
139
  expect(mockFetch).toHaveBeenCalledTimes(1);
128
140
  expect(mockFetch.mock.calls[0][0]).toContain('page=1');
129
141
  });
130
- it('multi-page → full page 1 forces page 2 fetch; stale-on-page-2 found + deleted (no duplicate)', async () => {
131
- // page 1: 100 comments, NO marker → must fetch page 2; page 2 carries the stale marker.
142
+ it('multi-page → full page 1 forces page 2 fetch; stale-on-page-2 found + updated in place (no duplicate)', async () => {
143
+ // page 1: 100 comments, NO marker → must fetch page 2; page 2 carries the sole marker.
132
144
  mockFetch.mockResolvedValueOnce(jsonResponse(200, makeComments(100, 0)));
133
145
  mockFetch.mockResolvedValueOnce(jsonResponse(200, makeComments(15, 100, 5))); // marker id 105
134
- // adapter deletes the found stale (105) then reposts fresh.
135
- mockFetch.mockResolvedValueOnce(jsonResponse(204, {})); // delete 105
136
- mockFetch.mockResolvedValueOnce(jsonResponse(201, { id: 777 })); // repost
146
+ // FORGE-UPSERT-005: single GHAGGA comment update it in place, nothing to prune.
147
+ mockFetch.mockResolvedValueOnce(jsonResponse(200, { id: 105 })); // update 105
137
148
  const adapter = buildAdapter();
138
149
  const result = await postSummaryComment(adapter, REF, 'body', MARKER);
139
- expect(result.deletedNativeIds).toEqual([105]);
140
- expect(result.createdNativeId).toBe(777);
150
+ // Sole comment (105) is updated in place: it carries the body, nothing is deleted.
151
+ expect(result.deletedNativeIds).toEqual([]);
152
+ expect(result.createdNativeId).toBe(105);
141
153
  expect(mockFetch.mock.calls[0][0]).toContain('page=1');
142
154
  expect(mockFetch.mock.calls[1][0]).toContain('page=2');
143
- const delCall = mockFetch.mock.calls[2];
144
- expect(delCall[0]).toContain('/issues/comments/105');
145
- expect(delCall[1].method).toBe('DELETE');
155
+ const updateCall = mockFetch.mock.calls[2];
156
+ expect(updateCall[0]).toContain('/issues/comments/105');
157
+ expect(updateCall[1].method).toBe('PATCH');
158
+ // No DELETE and no POST — the sole comment is updated, not replaced.
159
+ const methods = mockFetch.mock.calls.map((c) => c[1].method);
160
+ expect(methods).not.toContain('DELETE');
161
+ expect(methods).not.toContain('POST');
146
162
  });
147
163
  it('safety bound → stops at MAX_PAGES (50) and warns instead of looping forever', async () => {
148
164
  for (let page = 0; page < 50; page++) {
@@ -1 +1 @@
1
- {"version":3,"file":"pr-postback.test.js","sourceRoot":"","sources":["../../src/lib/pr-postback.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pr-postback.test.js","sourceRoot":"","sources":["../../src/lib/pr-postback.test.ts"],"names":[],"mappings":"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"}