@intentic/registry-scan 1.176.3
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/LICENSE +21 -0
- package/README.md +63 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +21 -0
- package/dist/cli.js.map +1 -0
- package/dist/github.d.ts +16 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +75 -0
- package/dist/github.js.map +1 -0
- package/dist/outputs.d.ts +5 -0
- package/dist/outputs.d.ts.map +1 -0
- package/dist/outputs.js +50 -0
- package/dist/outputs.js.map +1 -0
- package/dist/scan.d.ts +26 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +82 -0
- package/dist/scan.js.map +1 -0
- package/package.json +42 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Artur Kurowski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# @intentic/registry-scan
|
|
2
|
+
|
|
3
|
+
The nightly job behind the [extension registry](seed/README.md). Published to npm because it runs from a
|
|
4
|
+
GitHub Action inside a public repository this monorepo does not contain — `npx --yes @intentic/registry-scan`
|
|
5
|
+
is the whole install step there.
|
|
6
|
+
|
|
7
|
+
The file format it reads and writes lives in [`@intentic/registry`](../../_sandbox/registry), which the daemon
|
|
8
|
+
and the site's gallery use too, so all three agree by construction rather than by three copies of a zod
|
|
9
|
+
schema staying in step.
|
|
10
|
+
|
|
11
|
+
## What it does, and what it refuses to do
|
|
12
|
+
|
|
13
|
+
Scanning GitHub for a topic is **discovery**. Merging a pull request is the **decision**. Keeping those apart
|
|
14
|
+
is the entire design: a topic is a public namespace anybody can join, so a job that listed what it found
|
|
15
|
+
would publish the first malicious repository to tag itself — and the alternative, a submission form on the
|
|
16
|
+
site, is a login, a spam queue and an admin panel standing in for a git commit.
|
|
17
|
+
|
|
18
|
+
So each run:
|
|
19
|
+
|
|
20
|
+
1. Searches `topic:intentic-extension`.
|
|
21
|
+
2. Refreshes stars and last-push for **already-listed** entries into `registry.generated.json`, including the
|
|
22
|
+
listings the topic search never returned (a listing that arrived by pull request has no obligation to
|
|
23
|
+
carry the topic, and dropping its stars for that would rank it below newcomers for no reason).
|
|
24
|
+
3. For each **unlisted** repo whose `intentic-extension.json` parses, materialises a proposal: a complete
|
|
25
|
+
candidate `marketplace.json` with one entry added, plus the pull request's title and body.
|
|
26
|
+
4. Emits warnings for everything it skipped, into the job summary.
|
|
27
|
+
|
|
28
|
+
It never lists, delists, or changes a trust level. A repository that went briefly private should come back to
|
|
29
|
+
its listing, not to a deletion.
|
|
30
|
+
|
|
31
|
+
The one rule it enforces by itself is identity. The listing key is `publisher.name` read from the manifest —
|
|
32
|
+
[`extensionIdOf`](../../_sandbox/extension-api/src/manifest.ts) — so a repository that copies somebody else's
|
|
33
|
+
manifest collides with their existing listing and is refused here rather than arriving as a pull request that
|
|
34
|
+
looks legitimate.
|
|
35
|
+
|
|
36
|
+
## Layout
|
|
37
|
+
|
|
38
|
+
| Path | What it is |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| [src/scan.ts](src/scan.ts) | The decision logic, pure and fully unit-tested against a fake reader. |
|
|
41
|
+
| [src/github.ts](src/github.ts) | The four REST reads, behind an interface so the above needs no network. |
|
|
42
|
+
| [src/cli.ts](src/cli.ts) | The IO: read the checkout, write the facts file and the proposal directories. |
|
|
43
|
+
| [seed/](seed) | What the registry repository itself contains — the curated file, the author-facing README, and the workflow that calls this. |
|
|
44
|
+
|
|
45
|
+
`seed/` is a starting point, not a synced copy: push it once to create the registry repository, then it lives
|
|
46
|
+
its own life over there. The one coupling that matters is the workflow's `npx` line, which is why this
|
|
47
|
+
package is published.
|
|
48
|
+
|
|
49
|
+
## Running it against a checkout
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
GITHUB_TOKEN=… REGISTRY_DIR=/path/to/registry-checkout node dist/cli.js
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`SCANNED_AT` overrides the timestamp so a re-run against a fixed input produces a fixed output. A token is
|
|
56
|
+
required — the search and contents endpoints are rate-limited to approximately nothing without one.
|
|
57
|
+
|
|
58
|
+
## Key files
|
|
59
|
+
|
|
60
|
+
- [src/scan.ts](src/scan.ts) — finding extensions and resolving each to a sha.
|
|
61
|
+
- [src/github.ts](src/github.ts) — the API half.
|
|
62
|
+
- [src/outputs.ts](src/outputs.ts) — what the job writes.
|
|
63
|
+
- [src/cli.ts](src/cli.ts) — the entry point the nightly job runs.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { REGISTRY_FILE, RegistryFileSchema } from "@intentic/registry";
|
|
5
|
+
import { githubReader } from "./github.js";
|
|
6
|
+
import { scanSummary, writeScanOutputs } from "./outputs.js";
|
|
7
|
+
import { scanRegistry } from "./scan.js";
|
|
8
|
+
const main = async () => {
|
|
9
|
+
const token = process.env[`GITHUB_TOKEN`];
|
|
10
|
+
if (token === undefined || token === ``) {
|
|
11
|
+
throw new Error(`GITHUB_TOKEN is required — the search and contents endpoints are rate-limited to nothing without it`);
|
|
12
|
+
}
|
|
13
|
+
const scannedAt = process.env[`SCANNED_AT`] ?? new Date().toISOString();
|
|
14
|
+
const root = process.env[`REGISTRY_DIR`] ?? process.cwd();
|
|
15
|
+
const file = RegistryFileSchema.parse(JSON.parse(await readFile(join(root, REGISTRY_FILE), "utf8")));
|
|
16
|
+
const result = await scanRegistry(file, githubReader(token), scannedAt);
|
|
17
|
+
await writeScanOutputs(root, file, result);
|
|
18
|
+
process.stdout.write(`${scanSummary(result)}\n`);
|
|
19
|
+
};
|
|
20
|
+
await main();
|
|
21
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAKzC,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,qGAAqG,CAAC,CAAC;IAC3H,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1D,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACrG,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IAExE,MAAM,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,IAAI,EAAE,CAAC"}
|
package/dist/github.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface GithubRepo {
|
|
2
|
+
fullName: string;
|
|
3
|
+
stars: number;
|
|
4
|
+
pushedAt: string;
|
|
5
|
+
defaultBranch: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
archived: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface GithubReader {
|
|
10
|
+
searchByTopic(topic: string): Promise<GithubRepo[]>;
|
|
11
|
+
getRepo(fullName: string): Promise<GithubRepo | undefined>;
|
|
12
|
+
headSha(fullName: string, ref: string): Promise<string | undefined>;
|
|
13
|
+
readFile(fullName: string, ref: string, path: string): Promise<string | undefined>;
|
|
14
|
+
}
|
|
15
|
+
export declare const githubReader: (token: string, fetchImpl?: typeof fetch) => GithubReader;
|
|
16
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IAEvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IAEd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IACzB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEpD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAC3D,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACtF;AA0CD,eAAO,MAAM,YAAY,UAAW,MAAM,cAAa,OAAO,KAAK,KAAW,YAoD7E,CAAC"}
|
package/dist/github.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const RepoSchema = z.object({
|
|
3
|
+
full_name: z.string(),
|
|
4
|
+
stargazers_count: z.number(),
|
|
5
|
+
pushed_at: z.string(),
|
|
6
|
+
default_branch: z.string(),
|
|
7
|
+
description: z.string().nullable(),
|
|
8
|
+
archived: z.boolean(),
|
|
9
|
+
});
|
|
10
|
+
const SearchSchema = z.object({ total_count: z.number(), incomplete_results: z.boolean(), items: z.array(RepoSchema) });
|
|
11
|
+
const RefSchema = z.object({ object: z.object({ sha: z.string() }) });
|
|
12
|
+
const toRepo = (raw) => ({
|
|
13
|
+
fullName: raw.full_name,
|
|
14
|
+
stars: raw.stargazers_count,
|
|
15
|
+
pushedAt: raw.pushed_at,
|
|
16
|
+
defaultBranch: raw.default_branch,
|
|
17
|
+
archived: raw.archived,
|
|
18
|
+
...(raw.description !== null ? { description: raw.description } : {}),
|
|
19
|
+
});
|
|
20
|
+
const PER_PAGE = 100;
|
|
21
|
+
const MAX_PAGES = 10;
|
|
22
|
+
const optional = async (response, what) => {
|
|
23
|
+
if (response.status === 404) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
throw new Error(`GitHub ${response.status} reading ${what}: ${await response.text()}`);
|
|
28
|
+
}
|
|
29
|
+
return response;
|
|
30
|
+
};
|
|
31
|
+
export const githubReader = (token, fetchImpl = fetch) => {
|
|
32
|
+
const call = async (path) => fetchImpl(`https://api.github.com${path}`, {
|
|
33
|
+
headers: {
|
|
34
|
+
accept: "application/vnd.github+json",
|
|
35
|
+
authorization: `Bearer ${token}`,
|
|
36
|
+
"x-github-api-version": "2022-11-28",
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
async searchByTopic(topic) {
|
|
41
|
+
const repos = [];
|
|
42
|
+
for (let page = 1; page <= MAX_PAGES; page++) {
|
|
43
|
+
const response = await call(`/search/repositories?q=${encodeURIComponent(`topic:${topic}`)}&per_page=${PER_PAGE}&page=${page}`);
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`GitHub ${response.status} searching topic:${topic}: ${await response.text()}`);
|
|
46
|
+
}
|
|
47
|
+
const { items } = SearchSchema.parse(await response.json());
|
|
48
|
+
repos.push(...items.map(toRepo));
|
|
49
|
+
if (items.length < PER_PAGE) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return repos;
|
|
54
|
+
},
|
|
55
|
+
async getRepo(fullName) {
|
|
56
|
+
const response = await optional(await call(`/repos/${fullName}`), fullName);
|
|
57
|
+
return response === undefined ? undefined : toRepo(RepoSchema.parse(await response.json()));
|
|
58
|
+
},
|
|
59
|
+
async headSha(fullName, ref) {
|
|
60
|
+
const response = await optional(await call(`/repos/${fullName}/git/ref/heads/${ref}`), `${fullName}@${ref}`);
|
|
61
|
+
return response === undefined ? undefined : RefSchema.parse(await response.json()).object.sha;
|
|
62
|
+
},
|
|
63
|
+
async readFile(fullName, ref, path) {
|
|
64
|
+
const response = await optional(await fetchImpl(`https://api.github.com/repos/${fullName}/contents/${path}?ref=${encodeURIComponent(ref)}`, {
|
|
65
|
+
headers: {
|
|
66
|
+
accept: "application/vnd.github.raw+json",
|
|
67
|
+
authorization: `Bearer ${token}`,
|
|
68
|
+
"x-github-api-version": "2022-11-28",
|
|
69
|
+
},
|
|
70
|
+
}), `${fullName}:${path}@${ref}`);
|
|
71
|
+
return response === undefined ? undefined : response.text();
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type RegistryFile } from "@intentic/registry";
|
|
2
|
+
import type { ScanResult } from "./scan.js";
|
|
3
|
+
export declare const scanSummary: ({ facts, proposals, warnings }: ScanResult) => string;
|
|
4
|
+
export declare const writeScanOutputs: (root: string, file: RegistryFile, result: ScanResult) => Promise<void>;
|
|
5
|
+
//# sourceMappingURL=outputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputs.d.ts","sourceRoot":"","sources":["../src/outputs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAmB,UAAU,EAAE,MAAM,WAAW,CAAC;AAsC7D,eAAO,MAAM,WAAW,mCAAoC,UAAU,KAAG,MAQzD,CAAC;AAEjB,eAAO,MAAM,gBAAgB,SAAgB,MAAM,QAAQ,YAAY,UAAU,UAAU,KAAG,OAAO,CAAC,IAAI,CAiBzG,CAAC"}
|
package/dist/outputs.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { REGISTRY_FACTS_FILE } from "@intentic/registry";
|
|
4
|
+
const OUT_DIR = ".scan";
|
|
5
|
+
const INDENT = 4;
|
|
6
|
+
const writeJson = async (path, value) => {
|
|
7
|
+
await mkdir(dirname(path), { recursive: true });
|
|
8
|
+
await writeFile(path, `${JSON.stringify(value, null, INDENT)}\n`, "utf8");
|
|
9
|
+
};
|
|
10
|
+
const prBody = (proposal) => [
|
|
11
|
+
`Found by the nightly scan: [\`${proposal.repo}\`](https://github.com/${proposal.repo}) carries the \`intentic-extension\` topic and a manifest that parses.`,
|
|
12
|
+
``,
|
|
13
|
+
`| | |`,
|
|
14
|
+
`| --- | --- |`,
|
|
15
|
+
`| Extension id | \`${proposal.entry.name}\` |`,
|
|
16
|
+
`| Version | \`${proposal.entry.version}\` |`,
|
|
17
|
+
`| Pinned commit | \`${proposal.entry.source.sha}\` |`,
|
|
18
|
+
``,
|
|
19
|
+
`**What to check before merging.** The manifest parses and the publisher does not collide with an`,
|
|
20
|
+
`existing listing — the scan verified both, and nothing else. Review checks the pointer, not the code:`,
|
|
21
|
+
``,
|
|
22
|
+
`- [ ] The commit resolves and the entry bundle exists at it.`,
|
|
23
|
+
`- [ ] The description matches what the manifest actually contributes.`,
|
|
24
|
+
`- [ ] The publisher slug belongs to whoever owns this repository.`,
|
|
25
|
+
``,
|
|
26
|
+
`Merging lists it as \`trust: "listed"\` — the pointer resolves, and that is the whole claim. Promoting`,
|
|
27
|
+
`to \`verified\` is a separate edit by somebody who has read the source at this sha.`,
|
|
28
|
+
].join("\n");
|
|
29
|
+
export const scanSummary = ({ facts, proposals, warnings }) => [
|
|
30
|
+
`# Registry scan`,
|
|
31
|
+
``,
|
|
32
|
+
`- Facts refreshed for **${facts.entries.length}** listed ${facts.entries.length === 1 ? "entry" : "entries"}`,
|
|
33
|
+
`- **${proposals.length}** new ${proposals.length === 1 ? "listing" : "listings"} proposed`,
|
|
34
|
+
...(proposals.length > 0 ? [``, ...proposals.map((proposal) => ` - \`${proposal.entry.name}\` from ${proposal.repo}`)] : []),
|
|
35
|
+
...(warnings.length > 0 ? [``, `## Skipped and needing a look`, ``, ...warnings.map((warning) => `- ${warning}`)] : []),
|
|
36
|
+
].join("\n");
|
|
37
|
+
export const writeScanOutputs = async (root, file, result) => {
|
|
38
|
+
await writeJson(join(root, REGISTRY_FACTS_FILE), result.facts);
|
|
39
|
+
const out = join(root, OUT_DIR);
|
|
40
|
+
await rm(out, { recursive: true, force: true });
|
|
41
|
+
await mkdir(out, { recursive: true });
|
|
42
|
+
for (const proposal of result.proposals) {
|
|
43
|
+
const dir = join(out, "proposals", proposal.entry.name);
|
|
44
|
+
await writeJson(join(dir, "marketplace.json"), { ...file, plugins: [...file.plugins, proposal.entry] });
|
|
45
|
+
await writeFile(join(dir, "title.txt"), `Add ${proposal.entry.name} (${proposal.repo})\n`, "utf8");
|
|
46
|
+
await writeFile(join(dir, "body.md"), `${prBody(proposal)}\n`, "utf8");
|
|
47
|
+
}
|
|
48
|
+
await writeFile(join(out, "summary.md"), `${scanSummary(result)}\n`, "utf8");
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=outputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputs.js","sourceRoot":"","sources":["../src/outputs.ts"],"names":[],"mappings":"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"}
|
package/dist/scan.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type RegistryFacts, type RegistryFile } from "@intentic/registry";
|
|
2
|
+
import type { GithubReader } from "./github.js";
|
|
3
|
+
export interface ListingProposal {
|
|
4
|
+
repo: string;
|
|
5
|
+
entry: {
|
|
6
|
+
name: string;
|
|
7
|
+
kind: "extension";
|
|
8
|
+
trust: "listed";
|
|
9
|
+
description?: string;
|
|
10
|
+
version: string;
|
|
11
|
+
logo?: string;
|
|
12
|
+
icon?: string;
|
|
13
|
+
source: {
|
|
14
|
+
source: "github";
|
|
15
|
+
repo: string;
|
|
16
|
+
sha: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface ScanResult {
|
|
21
|
+
facts: RegistryFacts;
|
|
22
|
+
proposals: ListingProposal[];
|
|
23
|
+
warnings: string[];
|
|
24
|
+
}
|
|
25
|
+
export declare const scanRegistry: (file: RegistryFile, github: GithubReader, scannedAt: string) => Promise<ScanResult>;
|
|
26
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAiC,MAAM,oBAAoB,CAAC;AACxH,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,aAAa,CAAC;AAsB5D,MAAM,WAAW,eAAe;IAE5B,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE;QACH,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,WAAW,CAAC;QAClB,KAAK,EAAE,QAAQ,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,EAAE;YAAE,MAAM,EAAE,QAAQ,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3D,CAAC;CACL;AAED,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACtB;AA8DD,eAAO,MAAM,YAAY,SAAgB,YAAY,UAAU,YAAY,aAAa,MAAM,KAAG,OAAO,CAAC,UAAU,CA0ClH,CAAC"}
|
package/dist/scan.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ExtensionManifestSchema, extensionIdOf } from "@intentic/extension-api";
|
|
2
|
+
import { githubRepoOf, REGISTRY_TOPIC, resolveSource } from "@intentic/registry";
|
|
3
|
+
const MANIFEST_PATH = "intentic-extension.json";
|
|
4
|
+
const listedRepos = (file) => {
|
|
5
|
+
const byRepo = new Map();
|
|
6
|
+
for (const plugin of file.plugins) {
|
|
7
|
+
const repo = githubRepoOf(resolveSource(plugin.source, "", file.metadata?.pluginRoot));
|
|
8
|
+
if (repo !== undefined) {
|
|
9
|
+
byRepo.set(repo.toLowerCase(), plugin.name);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return byRepo;
|
|
13
|
+
};
|
|
14
|
+
const propose = async (repo, github, listed) => {
|
|
15
|
+
if (repo.archived) {
|
|
16
|
+
return `${repo.fullName}: archived`;
|
|
17
|
+
}
|
|
18
|
+
const raw = await github.readFile(repo.fullName, repo.defaultBranch, MANIFEST_PATH);
|
|
19
|
+
if (raw === undefined) {
|
|
20
|
+
return `${repo.fullName}: topic is set but there is no ${MANIFEST_PATH} at the root of ${repo.defaultBranch}`;
|
|
21
|
+
}
|
|
22
|
+
const parsed = ExtensionManifestSchema.safeParse(JSON.parse(raw));
|
|
23
|
+
if (!parsed.success) {
|
|
24
|
+
return `${repo.fullName}: ${MANIFEST_PATH} does not parse — ${parsed.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join("; ")}`;
|
|
25
|
+
}
|
|
26
|
+
const id = extensionIdOf(parsed.data);
|
|
27
|
+
const claimedBy = [...listed.entries()].find(([, name]) => name === id);
|
|
28
|
+
if (claimedBy !== undefined) {
|
|
29
|
+
return `${repo.fullName}: claims ${id}, which is already listed from ${claimedBy[0]}`;
|
|
30
|
+
}
|
|
31
|
+
const sha = await github.headSha(repo.fullName, repo.defaultBranch);
|
|
32
|
+
if (sha === undefined) {
|
|
33
|
+
return `${repo.fullName}: no commit found on ${repo.defaultBranch}`;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
repo: repo.fullName,
|
|
37
|
+
entry: {
|
|
38
|
+
name: id,
|
|
39
|
+
kind: "extension",
|
|
40
|
+
trust: "listed",
|
|
41
|
+
...(repo.description !== undefined ? { description: repo.description } : {}),
|
|
42
|
+
version: parsed.data.version,
|
|
43
|
+
...(parsed.data.logo !== undefined ? { logo: parsed.data.logo } : {}),
|
|
44
|
+
...(parsed.data.icon !== undefined ? { icon: parsed.data.icon } : {}),
|
|
45
|
+
source: { source: "github", repo: repo.fullName, sha },
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export const scanRegistry = async (file, github, scannedAt) => {
|
|
50
|
+
const listed = listedRepos(file);
|
|
51
|
+
const warnings = [];
|
|
52
|
+
const found = await github.searchByTopic(REGISTRY_TOPIC);
|
|
53
|
+
const foundByRepo = new Map(found.map((repo) => [repo.fullName.toLowerCase(), repo]));
|
|
54
|
+
const entries = [];
|
|
55
|
+
for (const [repoName, entryName] of listed) {
|
|
56
|
+
const repo = foundByRepo.get(repoName) ?? (await github.getRepo(repoName));
|
|
57
|
+
if (repo === undefined) {
|
|
58
|
+
warnings.push(`${entryName}: source repo ${repoName} is gone or no longer readable — listing may need review`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (repo.archived) {
|
|
62
|
+
warnings.push(`${entryName}: source repo ${repoName} is archived`);
|
|
63
|
+
}
|
|
64
|
+
entries.push({ name: entryName, stars: repo.stars, pushedAt: repo.pushedAt });
|
|
65
|
+
}
|
|
66
|
+
const proposals = [];
|
|
67
|
+
for (const repo of found) {
|
|
68
|
+
if (listed.has(repo.fullName.toLowerCase())) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const outcome = await propose(repo, github, listed);
|
|
72
|
+
if (typeof outcome === "string") {
|
|
73
|
+
warnings.push(outcome);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
proposals.push(outcome);
|
|
77
|
+
}
|
|
78
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
79
|
+
proposals.sort((a, b) => a.entry.name.localeCompare(b.entry.name));
|
|
80
|
+
return { facts: { scannedAt, entries }, proposals, warnings };
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=scan.js.map
|
package/dist/scan.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@intentic/registry-scan",
|
|
3
|
+
"version": "1.176.3",
|
|
4
|
+
"description": "The nightly scan behind the extension registry — finds topic-tagged repos, refreshes upstream facts, and proposes listings as pull requests",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/intentic/intentic.git",
|
|
10
|
+
"directory": "_tools/registry-scan"
|
|
11
|
+
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"intentic-registry-scan": "./dist/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public",
|
|
20
|
+
"registry": "https://registry.npmjs.org/"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"zod": "4.4.3",
|
|
24
|
+
"@intentic/extension-api": "1.176.3",
|
|
25
|
+
"@intentic/registry": "1.176.3"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "24.13.2",
|
|
29
|
+
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
30
|
+
"vitest": "4.1.10",
|
|
31
|
+
"@intentic/testing": "0.0.0",
|
|
32
|
+
"@intentic/tsconfig": "0.0.0"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsgo",
|
|
36
|
+
"typecheck": "tsgo --noEmit -p tsconfig.test.json",
|
|
37
|
+
"watch": "tsgo --build --watch",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"test:watch": "vitest",
|
|
40
|
+
"scan": "node dist/cli.js"
|
|
41
|
+
}
|
|
42
|
+
}
|