@aligndottech/cli 0.31.1 → 0.32.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.
- package/README.md +1 -0
- package/dist/commands/decisions/index.d.ts.map +1 -1
- package/dist/commands/decisions/index.js +10 -0
- package/dist/commands/decisions/index.js.map +1 -1
- package/dist/commands/import/docs.d.ts +3 -0
- package/dist/commands/import/docs.d.ts.map +1 -0
- package/dist/commands/import/docs.js +36 -0
- package/dist/commands/import/docs.js.map +1 -0
- package/dist/commands/import/git.d.ts.map +1 -1
- package/dist/commands/import/git.js +12 -3
- package/dist/commands/import/git.js.map +1 -1
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +2 -0
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/local.d.ts.map +1 -1
- package/dist/commands/local.js +29 -2
- package/dist/commands/local.js.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +12 -2
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +255 -53
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +7 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/why.d.ts.map +1 -1
- package/dist/commands/why.js +52 -4
- package/dist/commands/why.js.map +1 -1
- package/dist/lib/commit-cite.d.ts +3 -2
- package/dist/lib/commit-cite.d.ts.map +1 -1
- package/dist/lib/commit-cite.js +18 -3
- package/dist/lib/commit-cite.js.map +1 -1
- package/dist/lib/config.d.ts +22 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +69 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/connect-prompt.d.ts +53 -0
- package/dist/lib/connect-prompt.d.ts.map +1 -0
- package/dist/lib/connect-prompt.js +102 -0
- package/dist/lib/connect-prompt.js.map +1 -0
- package/dist/lib/decision-refs.d.ts +18 -1
- package/dist/lib/decision-refs.d.ts.map +1 -1
- package/dist/lib/decision-refs.js +60 -1
- package/dist/lib/decision-refs.js.map +1 -1
- package/dist/lib/fetchers/docs.d.ts +6 -0
- package/dist/lib/fetchers/docs.d.ts.map +1 -0
- package/dist/lib/fetchers/docs.js +180 -0
- package/dist/lib/fetchers/docs.js.map +1 -0
- package/dist/lib/found-summary.d.ts +34 -0
- package/dist/lib/found-summary.d.ts.map +1 -0
- package/dist/lib/found-summary.js +63 -0
- package/dist/lib/found-summary.js.map +1 -0
- package/dist/lib/gateway-client.d.ts +15 -1
- package/dist/lib/gateway-client.d.ts.map +1 -1
- package/dist/lib/gateway-client.js +7 -1
- package/dist/lib/gateway-client.js.map +1 -1
- package/dist/lib/git.d.ts +57 -5
- package/dist/lib/git.d.ts.map +1 -1
- package/dist/lib/git.js +114 -17
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/local-db.d.ts +81 -3
- package/dist/lib/local-db.d.ts.map +1 -1
- package/dist/lib/local-db.js +163 -14
- package/dist/lib/local-db.js.map +1 -1
- package/dist/lib/local-gateway-client.d.ts +9 -2
- package/dist/lib/local-gateway-client.d.ts.map +1 -1
- package/dist/lib/local-gateway-client.js +91 -10
- package/dist/lib/local-gateway-client.js.map +1 -1
- package/dist/lib/repo-identity.d.ts +47 -0
- package/dist/lib/repo-identity.d.ts.map +1 -0
- package/dist/lib/repo-identity.js +110 -0
- package/dist/lib/repo-identity.js.map +1 -0
- package/dist/lib/setup-ux.d.ts +12 -0
- package/dist/lib/setup-ux.d.ts.map +1 -1
- package/dist/lib/setup-ux.js +18 -0
- package/dist/lib/setup-ux.js.map +1 -1
- package/dist/lib/value-rollup.d.ts +19 -1
- package/dist/lib/value-rollup.d.ts.map +1 -1
- package/dist/lib/value-rollup.js +39 -11
- package/dist/lib/value-rollup.js.map +1 -1
- package/package.json +1 -1
package/dist/lib/git.d.ts
CHANGED
|
@@ -6,7 +6,27 @@ export interface GitCommit {
|
|
|
6
6
|
date: string;
|
|
7
7
|
filesChanged: string[];
|
|
8
8
|
}
|
|
9
|
-
export
|
|
9
|
+
export interface CommitHistoryResult {
|
|
10
|
+
commits: GitCommit[];
|
|
11
|
+
/** Every commit `git log` returned, before either promotion filter ran - i.e. what
|
|
12
|
+
* `commits.length` is a fraction OF. Needed to report "fewer, better rows" honestly
|
|
13
|
+
* (ALI-804): `commits.length` alone reads as "this is everything", not as a kept count. */
|
|
14
|
+
scanned: number;
|
|
15
|
+
/** Commits whose subject passed isDecisionCommit's shape check but whose body stated
|
|
16
|
+
* no reason (ALI-804's rationale gate) - the "what changed, not why" case. Kept
|
|
17
|
+
* separate from `scanned - commits.length`, which also includes the PRE-EXISTING
|
|
18
|
+
* subject-shape rejections (chore/wip/merge/too-short) - folding those into "no
|
|
19
|
+
* stated reason" overstates what THIS gate did (Copilot review, PR #223). */
|
|
20
|
+
rejectedByRationale: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Same as {@link getCommitHistory}, plus the raw scanned count. A separate export
|
|
24
|
+
* because {@link getCommitHistory}'s `Promise<GitCommit[]>` signature is the
|
|
25
|
+
* `GitCommitSource` contract connector-core's `GitFetcher` is typed against
|
|
26
|
+
* (`node_modules/@aligndottech/connector-core`) - changing its return shape would
|
|
27
|
+
* break that interface for no gain, since the SDK fetcher never needs the scanned count.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getCommitHistoryDetailed(opts: {
|
|
10
30
|
limit?: number;
|
|
11
31
|
from?: string;
|
|
12
32
|
to?: string;
|
|
@@ -14,10 +34,38 @@ export declare function getCommitHistory(opts: {
|
|
|
14
34
|
/** Run git in this directory instead of the process cwd. Lets tests point at a
|
|
15
35
|
* fixture repo without process.chdir, which leaks across concurrent workers. */
|
|
16
36
|
cwd?: string;
|
|
17
|
-
}): Promise<
|
|
37
|
+
}): Promise<CommitHistoryResult>;
|
|
38
|
+
export declare function getCommitHistory(opts: Parameters<typeof getCommitHistoryDetailed>[0]): Promise<GitCommit[]>;
|
|
18
39
|
export declare function isDecisionCommit(subject: string): boolean;
|
|
19
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Does this commit's body actually state a reason, once the noise is stripped? Measured
|
|
42
|
+
* while filtering ALI-804's git-only import: a body-shaped string is not automatically a
|
|
43
|
+
* WHY - a git trailer inflates "has a body" with no rationale in it, and a squash-merge
|
|
44
|
+
* bullet that just repeats the subject ("* fix: same as the subject") reads as prose
|
|
45
|
+
* while adding none. This is the same "prose in body, non-mechanical subject" proxy the
|
|
46
|
+
* ALI-804 measurement itself used to produce its headline numbers, made executable.
|
|
47
|
+
*/
|
|
48
|
+
export declare function hasStatedRationale(subject: string, body: string): boolean;
|
|
49
|
+
export declare function getRemoteUrl(opts?: {
|
|
50
|
+
cwd?: string;
|
|
51
|
+
}): Promise<string | null>;
|
|
52
|
+
/**
|
|
53
|
+
* The absolute repo root, for the ALI-798 fallback identity when a repo has no
|
|
54
|
+
* remote (or one `repoFromRemoteUrl` does not recognise): a self-hosted GHES, or a
|
|
55
|
+
* repo that has never been pushed. `--show-toplevel` always returns an absolute
|
|
56
|
+
* path, so this can never collide with the `host/owner/repo` identity shape.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getRepoRoot(opts?: {
|
|
59
|
+
cwd?: string;
|
|
60
|
+
}): Promise<string | null>;
|
|
20
61
|
export declare function buildCommitUrl(remoteUrl: string | null, sha: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* Web link to a file at a specific branch (an ADR, a CLAUDE.md section) - the blob-URL
|
|
64
|
+
* sibling of buildCommitUrl, same fallback convention: with no known remote this returns
|
|
65
|
+
* a stable, non-network `git://` identifier rather than a clickable link. It is used as a
|
|
66
|
+
* dedup key (source_url) as much as a link, so "not clickable" must never mean "not stable".
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildBlobUrl(remoteUrl: string | null, branch: string, relPath: string): string;
|
|
21
69
|
export declare function formatCommitAsText(commit: GitCommit, commitUrl?: string): string;
|
|
22
70
|
export declare function getStagedDiff(): Promise<string>;
|
|
23
71
|
export declare function getHeadDiff(): Promise<string>;
|
|
@@ -34,6 +82,10 @@ export declare function getHeadDiff(): Promise<string>;
|
|
|
34
82
|
* conflict this branch did not cause fail it.
|
|
35
83
|
*/
|
|
36
84
|
export declare function getBaseDiff(baseRef: string): Promise<string>;
|
|
37
|
-
export declare function getCurrentBranch(
|
|
38
|
-
|
|
85
|
+
export declare function getCurrentBranch(opts?: {
|
|
86
|
+
cwd?: string;
|
|
87
|
+
}): Promise<string>;
|
|
88
|
+
export declare function isGitRepo(opts?: {
|
|
89
|
+
cwd?: string;
|
|
90
|
+
}): Promise<boolean>;
|
|
39
91
|
//# sourceMappingURL=git.d.ts.map
|
package/dist/lib/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAsB,
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB;;gGAE4F;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB;;;;kFAI8E;IAC9E,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;qFACiF;IACjF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA0H/B;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAEjH;AAqBD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGzD;AAkBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAUzE;AAED,wBAAsB,YAAY,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOtF;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOrF;AAiBD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAM9F;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAUhF;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAGrD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAGnD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGlE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/E;AAED,wBAAsB,SAAS,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7E"}
|
package/dist/lib/git.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { execa } from 'execa';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Same as {@link getCommitHistory}, plus the raw scanned count. A separate export
|
|
4
|
+
* because {@link getCommitHistory}'s `Promise<GitCommit[]>` signature is the
|
|
5
|
+
* `GitCommitSource` contract connector-core's `GitFetcher` is typed against
|
|
6
|
+
* (`node_modules/@aligndottech/connector-core`) - changing its return shape would
|
|
7
|
+
* break that interface for no gain, since the SDK fetcher never needs the scanned count.
|
|
8
|
+
*/
|
|
9
|
+
export async function getCommitHistoryDetailed(opts) {
|
|
3
10
|
const SEP = '\x1f';
|
|
4
11
|
const MARKER = `COMMIT${SEP}`;
|
|
5
12
|
const BODY_END = `${SEP}END`;
|
|
@@ -42,11 +49,13 @@ export async function getCommitHistory(opts) {
|
|
|
42
49
|
// Other git failures (e.g. a bad --branch) still surface.
|
|
43
50
|
const e = err;
|
|
44
51
|
if (e.exitCode === 128 && /does not have any commits|bad default revision/i.test(e.stderr ?? '')) {
|
|
45
|
-
return [];
|
|
52
|
+
return { commits: [], scanned: 0, rejectedByRationale: 0 };
|
|
46
53
|
}
|
|
47
54
|
throw err;
|
|
48
55
|
}
|
|
49
56
|
const commits = [];
|
|
57
|
+
let scanned = 0;
|
|
58
|
+
let rejectedByRationale = 0;
|
|
50
59
|
let sha = '', subject = '', author = '', date = '';
|
|
51
60
|
let bodyLines = [];
|
|
52
61
|
let files = [];
|
|
@@ -54,10 +63,22 @@ export async function getCommitHistory(opts) {
|
|
|
54
63
|
const flush = () => {
|
|
55
64
|
if (mode === 'idle' || !sha)
|
|
56
65
|
return;
|
|
66
|
+
scanned++;
|
|
57
67
|
const shaped = resolveCommitShape(subject, bodyLines.join('\n').trimEnd());
|
|
58
|
-
if (isDecisionCommit(shaped.subject))
|
|
59
|
-
|
|
68
|
+
if (!isDecisionCommit(shaped.subject))
|
|
69
|
+
return;
|
|
70
|
+
// A promoted merge (ALI-792) already cleared an extra bar: its subject came from the
|
|
71
|
+
// body's own first line via isDecisionCommit, and its body always retains the original
|
|
72
|
+
// "Merge pull request #N from x/y" line for the PR ref - so it never needs to ALSO
|
|
73
|
+
// clear the rationale bar below. A plain commit gets no such head start: its subject
|
|
74
|
+
// is unvetted prose, so the body has to state why, or it is pure "what changed"
|
|
75
|
+
// (ALI-804 - the whole complaint this filter exists to answer).
|
|
76
|
+
const wasPromotedMerge = shaped.subject !== subject;
|
|
77
|
+
if (!wasPromotedMerge && !hasStatedRationale(shaped.subject, shaped.body)) {
|
|
78
|
+
rejectedByRationale++;
|
|
79
|
+
return;
|
|
60
80
|
}
|
|
81
|
+
commits.push({ sha, subject: shaped.subject, body: shaped.body, author, date, filesChanged: files.slice(0, 10) });
|
|
61
82
|
};
|
|
62
83
|
// A header line must carry a full 40-hex sha in the second field. Without the check,
|
|
63
84
|
// a commit BODY containing a line that starts with "COMMIT\x1f" (git preserves \x1f
|
|
@@ -111,7 +132,10 @@ export async function getCommitHistory(opts) {
|
|
|
111
132
|
}
|
|
112
133
|
}
|
|
113
134
|
flush();
|
|
114
|
-
return commits;
|
|
135
|
+
return { commits, scanned, rejectedByRationale };
|
|
136
|
+
}
|
|
137
|
+
export async function getCommitHistory(opts) {
|
|
138
|
+
return (await getCommitHistoryDetailed(opts)).commits;
|
|
115
139
|
}
|
|
116
140
|
/**
|
|
117
141
|
* A merge commit's boilerplate subject hides the decision its body carries: on GitHub's
|
|
@@ -138,28 +162,101 @@ export function isDecisionCommit(subject) {
|
|
|
138
162
|
return false;
|
|
139
163
|
return !/^(chore|wip|merge|revert|bump|update deps|release|typo)/i.test(subject.trim());
|
|
140
164
|
}
|
|
141
|
-
|
|
165
|
+
// A line that IS a git trailer (key: value at the start of the line), not merely a
|
|
166
|
+
// sentence that happens to mention one of these words mid-line - "Refs ALI-123 and
|
|
167
|
+
// closes #45." inside a real paragraph must NOT be stripped, only a line that is
|
|
168
|
+
// nothing but the trailer.
|
|
169
|
+
const TRAILER_LINE_RE = /^(co-authored-by|signed-off-by|reviewed-by|acked-by|helped-by|cc|refs?|closes?|fixes?|resolves?)\s*:\s*\S/i;
|
|
170
|
+
// Attribution lines an agent appends (e.g. "🤖 Generated with [Claude Code](...)")
|
|
171
|
+
// carry no rationale either - it's who/what wrote the commit, not why. Anchored to the
|
|
172
|
+
// START of the line (past an optional bot emoji): unanchored, this also matched mid-
|
|
173
|
+
// sentence, so a real reason like "Regenerated with a fresh script..." was wrongly
|
|
174
|
+
// stripped as if it were an attribution line (Copilot review, PR #223).
|
|
175
|
+
const GENERATED_WITH_RE = /^(?:🤖\s*)?generated (with|by)\b/i;
|
|
176
|
+
function normalizeForEcho(s) {
|
|
177
|
+
return s.toLowerCase().replace(/^[*\-•]\s*/, '').replace(/[^a-z0-9]+/g, ' ').trim();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Does this commit's body actually state a reason, once the noise is stripped? Measured
|
|
181
|
+
* while filtering ALI-804's git-only import: a body-shaped string is not automatically a
|
|
182
|
+
* WHY - a git trailer inflates "has a body" with no rationale in it, and a squash-merge
|
|
183
|
+
* bullet that just repeats the subject ("* fix: same as the subject") reads as prose
|
|
184
|
+
* while adding none. This is the same "prose in body, non-mechanical subject" proxy the
|
|
185
|
+
* ALI-804 measurement itself used to produce its headline numbers, made executable.
|
|
186
|
+
*/
|
|
187
|
+
export function hasStatedRationale(subject, body) {
|
|
188
|
+
if (!body.trim())
|
|
189
|
+
return false;
|
|
190
|
+
const subjectNorm = normalizeForEcho(subject);
|
|
191
|
+
const remaining = body
|
|
192
|
+
.split('\n')
|
|
193
|
+
.map(l => l.trim())
|
|
194
|
+
.filter(Boolean)
|
|
195
|
+
.filter(l => !TRAILER_LINE_RE.test(l) && !GENERATED_WITH_RE.test(l))
|
|
196
|
+
.filter(l => normalizeForEcho(l) !== subjectNorm);
|
|
197
|
+
return remaining.length > 0;
|
|
198
|
+
}
|
|
199
|
+
export async function getRemoteUrl(opts = {}) {
|
|
142
200
|
try {
|
|
143
|
-
const { stdout } = await execa('git', ['remote', 'get-url', 'origin']);
|
|
201
|
+
const { stdout } = await execa('git', ['remote', 'get-url', 'origin'], opts.cwd ? { cwd: opts.cwd } : {});
|
|
144
202
|
return stdout.trim() || null;
|
|
145
203
|
}
|
|
146
204
|
catch {
|
|
147
205
|
return null;
|
|
148
206
|
}
|
|
149
207
|
}
|
|
150
|
-
|
|
208
|
+
/**
|
|
209
|
+
* The absolute repo root, for the ALI-798 fallback identity when a repo has no
|
|
210
|
+
* remote (or one `repoFromRemoteUrl` does not recognise): a self-hosted GHES, or a
|
|
211
|
+
* repo that has never been pushed. `--show-toplevel` always returns an absolute
|
|
212
|
+
* path, so this can never collide with the `host/owner/repo` identity shape.
|
|
213
|
+
*/
|
|
214
|
+
export async function getRepoRoot(opts = {}) {
|
|
215
|
+
try {
|
|
216
|
+
const { stdout } = await execa('git', ['rev-parse', '--show-toplevel'], opts.cwd ? { cwd: opts.cwd } : {});
|
|
217
|
+
return stdout.trim() || null;
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** GitHub/GitLab web base parsed from a remote, or null for anything else (bitbucket,
|
|
224
|
+
* self-hosted, no remote). Shared by buildCommitUrl and buildBlobUrl so the two web
|
|
225
|
+
* link builders can't drift on what counts as "a known host" (code-style.md, two
|
|
226
|
+
* writers of one fact). */
|
|
227
|
+
function repoWebBase(remoteUrl) {
|
|
151
228
|
if (!remoteUrl)
|
|
152
|
-
return
|
|
229
|
+
return null;
|
|
153
230
|
const sshGh = remoteUrl.match(/git@github\.com[:/](.+?)(?:\.git)?$/);
|
|
154
231
|
if (sshGh)
|
|
155
|
-
return `https://github.com/${sshGh[1]}
|
|
232
|
+
return { kind: 'github', base: `https://github.com/${sshGh[1]}` };
|
|
156
233
|
const httpsGh = remoteUrl.match(/github\.com[:/](.+?)(?:\.git)?$/);
|
|
157
234
|
if (httpsGh)
|
|
158
|
-
return `https://github.com/${httpsGh[1]}
|
|
235
|
+
return { kind: 'github', base: `https://github.com/${httpsGh[1]}` };
|
|
159
236
|
const gl = remoteUrl.match(/gitlab\.com[:/](.+?)(?:\.git)?$/);
|
|
160
237
|
if (gl)
|
|
161
|
-
return `https://gitlab.com/${gl[1]}
|
|
162
|
-
return
|
|
238
|
+
return { kind: 'gitlab', base: `https://gitlab.com/${gl[1]}` };
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
export function buildCommitUrl(remoteUrl, sha) {
|
|
242
|
+
const web = repoWebBase(remoteUrl);
|
|
243
|
+
if (!web)
|
|
244
|
+
return `git://commit/${sha}`;
|
|
245
|
+
return web.kind === 'gitlab' ? `${web.base}/-/commit/${sha}` : `${web.base}/commit/${sha}`;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Web link to a file at a specific branch (an ADR, a CLAUDE.md section) - the blob-URL
|
|
249
|
+
* sibling of buildCommitUrl, same fallback convention: with no known remote this returns
|
|
250
|
+
* a stable, non-network `git://` identifier rather than a clickable link. It is used as a
|
|
251
|
+
* dedup key (source_url) as much as a link, so "not clickable" must never mean "not stable".
|
|
252
|
+
*/
|
|
253
|
+
export function buildBlobUrl(remoteUrl, branch, relPath) {
|
|
254
|
+
const web = repoWebBase(remoteUrl);
|
|
255
|
+
if (!web)
|
|
256
|
+
return `git://blob/${branch}/${relPath}`;
|
|
257
|
+
return web.kind === 'gitlab'
|
|
258
|
+
? `${web.base}/-/blob/${branch}/${relPath}`
|
|
259
|
+
: `${web.base}/blob/${branch}/${relPath}`;
|
|
163
260
|
}
|
|
164
261
|
export function formatCommitAsText(commit, commitUrl) {
|
|
165
262
|
const parts = [commit.subject];
|
|
@@ -198,13 +295,13 @@ export async function getBaseDiff(baseRef) {
|
|
|
198
295
|
const result = await execa('git', ['diff', `${baseRef}...HEAD`]);
|
|
199
296
|
return result.stdout;
|
|
200
297
|
}
|
|
201
|
-
export async function getCurrentBranch() {
|
|
202
|
-
const result = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD']);
|
|
298
|
+
export async function getCurrentBranch(opts) {
|
|
299
|
+
const result = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], opts?.cwd ? { cwd: opts.cwd } : {});
|
|
203
300
|
return result.stdout.trim();
|
|
204
301
|
}
|
|
205
|
-
export async function isGitRepo() {
|
|
302
|
+
export async function isGitRepo(opts = {}) {
|
|
206
303
|
try {
|
|
207
|
-
await execa('git', ['rev-parse', '--git-dir']);
|
|
304
|
+
await execa('git', ['rev-parse', '--git-dir'], opts.cwd ? { cwd: opts.cwd } : {});
|
|
208
305
|
return true;
|
|
209
306
|
}
|
|
210
307
|
catch {
|
package/dist/lib/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/local-db.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export interface DecisionRow {
|
|
|
5
5
|
sourceUrl: string | null;
|
|
6
6
|
platform: string;
|
|
7
7
|
createdAt: string;
|
|
8
|
+
/** ALI-798: which repo this decision came from (host/owner/repo, or a repo root
|
|
9
|
+
* path for a remoteless git repo) - null for anything that is not code, or code
|
|
10
|
+
* whose repo could not be identified. */
|
|
11
|
+
repo: string | null;
|
|
8
12
|
}
|
|
9
13
|
export interface LinkRow {
|
|
10
14
|
id: string;
|
|
@@ -26,7 +30,7 @@ export interface DbStats {
|
|
|
26
30
|
* `migrate` from the source and compares it here, because forgetting the bump leaves the new
|
|
27
31
|
* branch running destructively on every open with nothing to stop it.
|
|
28
32
|
*/
|
|
29
|
-
export declare const SCHEMA_VERSION =
|
|
33
|
+
export declare const SCHEMA_VERSION = 3;
|
|
30
34
|
/**
|
|
31
35
|
* A `source_url` is only an identity if it points at ONE thing. Some fetchers substitute a
|
|
32
36
|
* constant when the per-item link is missing, and connector-core ships one:
|
|
@@ -62,11 +66,24 @@ export declare function createLocalDb(dbPath: string): {
|
|
|
62
66
|
* distinct - so `align capture` with no URL keeps inserting, by construction rather than by
|
|
63
67
|
* a special case here.
|
|
64
68
|
*/
|
|
69
|
+
/**
|
|
70
|
+
* `repo` (ALI-798): the identity of the checkout this decision came from, or null for
|
|
71
|
+
* anything that is not code (Jira, Slack, a bare capture). Optional so every existing
|
|
72
|
+
* caller keeps compiling unchanged - omitting it inserts NULL, same as it always did.
|
|
73
|
+
*
|
|
74
|
+
* On a re-import upsert, COALESCE keeps whichever value is non-null: a new repo can fill
|
|
75
|
+
* in an attribution the row did not have, but an already-attributed row is never
|
|
76
|
+
* overwritten back to unattributed by a re-import that (for whatever reason) resolved no
|
|
77
|
+
* repo this time. Re-attributing a row that ALREADY has a (different) repo is not a case
|
|
78
|
+
* this upsert needs to handle - `source_url` identifies the row, and a URL does not
|
|
79
|
+
* change which repo it points at between imports.
|
|
80
|
+
*/
|
|
65
81
|
insertDecision(row: {
|
|
66
82
|
title: string;
|
|
67
83
|
summary: string;
|
|
68
84
|
sourceUrl: string | null;
|
|
69
85
|
platform: string;
|
|
86
|
+
repo?: string | null;
|
|
70
87
|
}): string;
|
|
71
88
|
/**
|
|
72
89
|
* The id this graph already holds for `(source_url, title)`, or null.
|
|
@@ -93,11 +110,37 @@ export declare function createLocalDb(dbPath: string): {
|
|
|
93
110
|
* distinct, so those rows never conflict and every one of them really is new.
|
|
94
111
|
*/
|
|
95
112
|
findIdBySource(sourceUrl: string | null, title: string): string | null;
|
|
96
|
-
|
|
113
|
+
/**
|
|
114
|
+
* `filter.repo` scopes to one repo's rows. `includeUnattributed` (ALI-798's own rule:
|
|
115
|
+
* "repo = ? OR repo IS NULL") also returns rows with no repo at all - a Jira ticket, a
|
|
116
|
+
* Slack thread, anything not code - because a strict `repo = ?` would make 36% of a
|
|
117
|
+
* measured real graph (every non-code decision) invisible from inside any one repo,
|
|
118
|
+
* which is a worse regression than the bug this filter exists to fix. Left false by
|
|
119
|
+
* callers that want an exact match (repo resolution, tests) rather than the retrieval
|
|
120
|
+
* default.
|
|
121
|
+
*/
|
|
122
|
+
listDecisions(filter?: {
|
|
123
|
+
repo?: string;
|
|
124
|
+
includeUnattributed?: boolean;
|
|
125
|
+
}): DecisionRow[];
|
|
97
126
|
getDecisionById(id: string): DecisionRow | null;
|
|
127
|
+
/** Distinct repo identities known to this graph, for resolving a `--repo <name>` argument
|
|
128
|
+
* against what actually exists rather than guessing at a spelling. */
|
|
129
|
+
listRepos(): string[];
|
|
98
130
|
setEmbedding(decisionId: string, embedding: Float32Array): void;
|
|
99
131
|
getEmbedding(decisionId: string): Float32Array | null;
|
|
100
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Unscoped by default: relationship linking (ingestOne, in local-gateway-client.ts) wants
|
|
134
|
+
* candidates across EVERY repo - cross-repo memory is the product this ticket protects,
|
|
135
|
+
* not just the thing it stops blending on retrieval. A `filter.repo` is for the retrieval
|
|
136
|
+
* paths (search, ask) that DO want to stay in-scope, filtered here rather than after
|
|
137
|
+
* ranking - filtering post-rank would silently return fewer than `topK` results whenever
|
|
138
|
+
* some of the best global matches fall outside the scope.
|
|
139
|
+
*/
|
|
140
|
+
getAllEmbeddings(filter?: {
|
|
141
|
+
repo?: string;
|
|
142
|
+
includeUnattributed?: boolean;
|
|
143
|
+
}): Array<{
|
|
101
144
|
decisionId: string;
|
|
102
145
|
embedding: Float32Array;
|
|
103
146
|
}>;
|
|
@@ -132,6 +175,41 @@ export declare function createLocalDb(dbPath: string): {
|
|
|
132
175
|
ref: string;
|
|
133
176
|
platform: string;
|
|
134
177
|
}>;
|
|
178
|
+
/**
|
|
179
|
+
* Every ref across every decision, for the gap resolver (ALI-796): it needs to
|
|
180
|
+
* count DISTINCT decisions per platform graph-wide, which a per-decision
|
|
181
|
+
* `getRefs` cannot do without one round trip per decision.
|
|
182
|
+
*/
|
|
183
|
+
getAllRefs(): Array<{
|
|
184
|
+
decisionId: string;
|
|
185
|
+
ref: string;
|
|
186
|
+
platform: string;
|
|
187
|
+
}>;
|
|
188
|
+
/**
|
|
189
|
+
* ALI-796's payoff: a newly-ingested decision may be the exact thing an EARLIER
|
|
190
|
+
* decision's text already cited (a git commit citing "ALI-123", now that the Jira
|
|
191
|
+
* issue for it has been imported). `candidates` is that new decision's own
|
|
192
|
+
* identity (decision-refs.ts's `refIdentityFor`) - every shape another decision
|
|
193
|
+
* could have recorded it as. For each one that some existing ref already names,
|
|
194
|
+
* link the citer to this decision.
|
|
195
|
+
*
|
|
196
|
+
* Deliberately one-directional: it resolves refs that were ALREADY WAITING when
|
|
197
|
+
* this decision arrives. It does not also re-scan this decision's own text for refs
|
|
198
|
+
* pointing at decisions already in the graph - the realistic setup flow imports git
|
|
199
|
+
* (which writes the citing refs) before a connector is added later to fill them in,
|
|
200
|
+
* so the citer is always the one already present. A source imported before the
|
|
201
|
+
* repo it is later linked from is the case this does not cover.
|
|
202
|
+
*
|
|
203
|
+
* `relation: 'relates'` at confidence 1.0 - not a guess like the cosine-similarity
|
|
204
|
+
* `relates` edges elsewhere (ALI-503): this one is a deterministic exact-key match,
|
|
205
|
+
* and 1.0 says so. `insertLinkRow`'s unique index on (source, target, relation)
|
|
206
|
+
* makes re-resolving the same pair on a later import a no-op rather than a
|
|
207
|
+
* duplicate edge.
|
|
208
|
+
*/
|
|
209
|
+
resolveRefs(newDecisionId: string, candidates: Array<{
|
|
210
|
+
ref: string;
|
|
211
|
+
platform: string;
|
|
212
|
+
}>): void;
|
|
135
213
|
listLinks(filter?: {
|
|
136
214
|
relation?: string;
|
|
137
215
|
decisionId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-db.d.ts","sourceRoot":"","sources":["../../src/lib/local-db.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"local-db.d.ts","sourceRoot":"","sources":["../../src/lib/local-db.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB;;8CAE0C;IAC1C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmCD;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAetE;AA0KD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM;IAyBxC;;;;;;;;;;;OAWG;IACH;;;;;;;;;;;OAWG;wBACiB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,MAAM;IAkBjI;;;;;;;;;;;;;;;;;;;;;;;OAuBG;8BACuB,MAAM,GAAG,IAAI,SAAS,MAAM,GAAG,MAAM,GAAG,IAAI;IAStE;;;;;;;;OAQG;2BACmB;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAQ,WAAW,EAAE;wBAWvE,MAAM,GAAG,WAAW,GAAG,IAAI;IAM/C;2EACuE;iBAC1D,MAAM,EAAE;6BAKI,MAAM,aAAa,YAAY,GAAG,IAAI;6BAMtC,MAAM,GAAG,YAAY,GAAG,IAAI;IAQrD;;;;;;;OAOG;8BACsB;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAQ,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,YAAY,CAAA;KAAE,CAAC;IAevI;;;;;;;;;OASG;qBACc;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIpG;;;;;;OAMG;4BACqB,MAAM,QAAQ,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;wBAmBjE,MAAM,GAAG,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAMrE;;;;OAIG;kBACW,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAM1E;;;;;;;;;;;;;;;;;;;;OAoBG;+BACwB,MAAM,cAAc,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;uBAa3E;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,EAAE;gBAQ7D,OAAO;eAQR,IAAI;aAON,IAAI;EAIhB;AAED,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC"}
|