@chatcode/cco-market 1.45.1
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 +146 -0
- package/README.zh.md +143 -0
- package/UPDATE-API-V1.md +132 -0
- package/client/client.js +11534 -0
- package/cordis.patch.yml +5 -0
- package/lib/accelerate.js +184 -0
- package/lib/agents.js +36 -0
- package/lib/backup.js +572 -0
- package/lib/catalog-local-match.js +126 -0
- package/lib/catalog-npm.js +111 -0
- package/lib/changelog.js +242 -0
- package/lib/channels.js +64 -0
- package/lib/check.js +1067 -0
- package/lib/compatibility.js +198 -0
- package/lib/diagnostics.js +49 -0
- package/lib/discovery-compatibility.js +260 -0
- package/lib/dsh-cli.js +949 -0
- package/lib/dsh-install.js +108 -0
- package/lib/gist.js +352 -0
- package/lib/groups.js +97 -0
- package/lib/home-paths.js +42 -0
- package/lib/hot.js +519 -0
- package/lib/http.js +39 -0
- package/lib/index.js +97 -0
- package/lib/install.js +387 -0
- package/lib/log.js +197 -0
- package/lib/ndjson.js +154 -0
- package/lib/net.js +98 -0
- package/lib/order.js +284 -0
- package/lib/patch.js +521 -0
- package/lib/pnpm-compat.js +490 -0
- package/lib/presets.js +278 -0
- package/lib/profile.js +911 -0
- package/lib/region-probe.js +93 -0
- package/lib/regions.js +253 -0
- package/lib/registry.js +204 -0
- package/lib/restart.js +373 -0
- package/lib/routes.js +4372 -0
- package/lib/settings.js +109 -0
- package/lib/skill-market/api.js +119 -0
- package/lib/skill-market/config.js +29 -0
- package/lib/skill-market/installer.js +352 -0
- package/lib/skill-market/runtime.js +13 -0
- package/lib/skill-market/tui.js +119 -0
- package/lib/skill-market/types.js +1 -0
- package/lib/skill-market/web-routes.js +123 -0
- package/lib/snapshot.js +500 -0
- package/lib/source-migration.js +54 -0
- package/lib/sources.js +596 -0
- package/lib/store.js +91 -0
- package/lib/themes.js +102 -0
- package/lib/trial.js +116 -0
- package/lib/types/accelerate.d.ts +85 -0
- package/lib/types/agents.d.ts +22 -0
- package/lib/types/backup.d.ts +131 -0
- package/lib/types/catalog-local-match.d.ts +50 -0
- package/lib/types/catalog-npm.d.ts +47 -0
- package/lib/types/changelog.d.ts +102 -0
- package/lib/types/channels.d.ts +56 -0
- package/lib/types/check.d.ts +266 -0
- package/lib/types/compatibility.d.ts +64 -0
- package/lib/types/diagnostics.d.ts +29 -0
- package/lib/types/discovery-compatibility.d.ts +80 -0
- package/lib/types/dsh-cli.d.ts +324 -0
- package/lib/types/dsh-install.d.ts +46 -0
- package/lib/types/gist.d.ts +53 -0
- package/lib/types/groups.d.ts +34 -0
- package/lib/types/home-paths.d.ts +16 -0
- package/lib/types/hot.d.ts +221 -0
- package/lib/types/http.d.ts +12 -0
- package/lib/types/index.d.ts +14 -0
- package/lib/types/install.d.ts +172 -0
- package/lib/types/log.d.ts +43 -0
- package/lib/types/ndjson.d.ts +52 -0
- package/lib/types/net.d.ts +58 -0
- package/lib/types/order.d.ts +100 -0
- package/lib/types/patch.d.ts +129 -0
- package/lib/types/pnpm-compat.d.ts +93 -0
- package/lib/types/presets.d.ts +90 -0
- package/lib/types/profile.d.ts +253 -0
- package/lib/types/region-probe.d.ts +50 -0
- package/lib/types/regions.d.ts +122 -0
- package/lib/types/registry.d.ts +86 -0
- package/lib/types/restart.d.ts +194 -0
- package/lib/types/routes.d.ts +67 -0
- package/lib/types/settings.d.ts +78 -0
- package/lib/types/skill-market/api.d.ts +10 -0
- package/lib/types/skill-market/config.d.ts +3 -0
- package/lib/types/skill-market/installer.d.ts +23 -0
- package/lib/types/skill-market/runtime.d.ts +10 -0
- package/lib/types/skill-market/tui.d.ts +4 -0
- package/lib/types/skill-market/types.d.ts +71 -0
- package/lib/types/skill-market/web-routes.d.ts +19 -0
- package/lib/types/snapshot.d.ts +93 -0
- package/lib/types/source-migration.d.ts +11 -0
- package/lib/types/sources.d.ts +216 -0
- package/lib/types/store.d.ts +30 -0
- package/lib/types/themes.d.ts +40 -0
- package/lib/types/trial.d.ts +61 -0
- package/lib/types/update-api-v1.d.ts +66 -0
- package/lib/types/updates.d.ts +123 -0
- package/lib/types/verify.d.ts +139 -0
- package/lib/update-api-v1.js +215 -0
- package/lib/updates.js +361 -0
- package/lib/verify.js +453 -0
- package/package.json +121 -0
- package/src/accelerate.ts +213 -0
- package/src/agents.ts +43 -0
- package/src/backup.ts +583 -0
- package/src/catalog-local-match.ts +144 -0
- package/src/catalog-npm.ts +120 -0
- package/src/changelog.ts +282 -0
- package/src/channels.ts +70 -0
- package/src/check.ts +1239 -0
- package/src/client/CommentsModal.tsx +119 -0
- package/src/client/Diagnostics.tsx +907 -0
- package/src/client/ErrorBoundary.tsx +111 -0
- package/src/client/InstallToast.tsx +31 -0
- package/src/client/Market.module.css +830 -0
- package/src/client/MarketSection.tsx +5301 -0
- package/src/client/OperationsPanel.tsx +365 -0
- package/src/client/SettingsCard.tsx +621 -0
- package/src/client/SkillMarket.module.css +21 -0
- package/src/client/SkillMarketSection.tsx +162 -0
- package/src/client/comments.ts +54 -0
- package/src/client/globals.d.ts +13 -0
- package/src/client/index.ts +180 -0
- package/src/client/locales.ts +1112 -0
- package/src/client/market-data.ts +1321 -0
- package/src/client/operations.ts +201 -0
- package/src/client/preset-panel.tsx +263 -0
- package/src/client/primitives.d.ts +140 -0
- package/src/client/self-check.ts +147 -0
- package/src/client/snapshot-panel.tsx +244 -0
- package/src/compatibility.ts +237 -0
- package/src/diagnostics.ts +84 -0
- package/src/discovery-compatibility.ts +315 -0
- package/src/dsh-cli.ts +1126 -0
- package/src/dsh-install.ts +118 -0
- package/src/gist.ts +362 -0
- package/src/groups.ts +111 -0
- package/src/home-paths.ts +53 -0
- package/src/hot.ts +628 -0
- package/src/http.ts +41 -0
- package/src/index.ts +128 -0
- package/src/install.ts +420 -0
- package/src/log.ts +206 -0
- package/src/ndjson.ts +185 -0
- package/src/net.ts +106 -0
- package/src/order.ts +303 -0
- package/src/patch.ts +522 -0
- package/src/pnpm-compat.ts +527 -0
- package/src/presets.ts +344 -0
- package/src/profile.ts +940 -0
- package/src/region-probe.ts +97 -0
- package/src/regions.ts +310 -0
- package/src/registry.ts +250 -0
- package/src/restart.ts +396 -0
- package/src/routes.ts +4506 -0
- package/src/settings.ts +141 -0
- package/src/skill-market/api.ts +130 -0
- package/src/skill-market/config.ts +32 -0
- package/src/skill-market/installer.ts +337 -0
- package/src/skill-market/runtime.ts +14 -0
- package/src/skill-market/tui.ts +157 -0
- package/src/skill-market/types.ts +80 -0
- package/src/skill-market/web-routes.ts +132 -0
- package/src/snapshot.ts +532 -0
- package/src/source-migration.ts +61 -0
- package/src/sources.ts +565 -0
- package/src/store.ts +89 -0
- package/src/themes.ts +125 -0
- package/src/trial.ts +156 -0
- package/src/update-api-v1.ts +277 -0
- package/src/updates.ts +400 -0
- package/src/verify.ts +492 -0
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolving a GitHub install through a region's proxy without proxying the
|
|
3
|
+
* tarball pnpm records.
|
|
4
|
+
*
|
|
5
|
+
* pnpm does not fetch `github:owner/repo` with `git clone`; it resolves the
|
|
6
|
+
* shortcut and downloads a tarball from codeload.github.com. That rules out
|
|
7
|
+
* the usual `git config insteadOf` trick — there is no git command to
|
|
8
|
+
* redirect.
|
|
9
|
+
*
|
|
10
|
+
* Prefix-proxying that tarball used to save substantial time, but pnpm 11's
|
|
11
|
+
* fail-closed lockfile checks changed the safety boundary. A URL shaped like
|
|
12
|
+
* `https://proxy/https://codeload.github.com/.../<commit>` no longer has the
|
|
13
|
+
* codeload hostname, so pnpm treats it as an ordinary remote tarball and
|
|
14
|
+
* requires an integrity hash that its GitHub resolver does not write. The
|
|
15
|
+
* result is ERR_PNPM_MISSING_TARBALL_INTEGRITY on the install itself (#385).
|
|
16
|
+
* Disabling that check or minting a checksum from whatever the proxy served
|
|
17
|
+
* would weaken pnpm's supply-chain protection, so neither is acceptable.
|
|
18
|
+
*
|
|
19
|
+
* The safe middle ground is to resolve HEAD through the regional proxy, then
|
|
20
|
+
* hand pnpm a commit-pinned `github:owner/repo#<sha>` target. The ref lookup
|
|
21
|
+
* still avoids a slow or unreachable GitHub metadata request; pnpm itself
|
|
22
|
+
* fetches the canonical codeload URL, records it as `gitHosted: true`, and
|
|
23
|
+
* keeps its integrity policy intact.
|
|
24
|
+
*
|
|
25
|
+
* - **The commit has to be pinned.** The profile reads each plugin's
|
|
26
|
+
* installed commit back out of the lockfile by matching a codeload URL
|
|
27
|
+
* ending in a 40-character SHA (src/profile.ts). A `HEAD` tarball installs
|
|
28
|
+
* perfectly and then reports no version forever. So this resolves the SHA
|
|
29
|
+
* first, and a rewrite that cannot get one does not happen.
|
|
30
|
+
* - **Build-script approval has to keep matching.** `gitAllowBuildsKey`
|
|
31
|
+
* (src/sources.ts) derives its stable key from the repo, and the pinned
|
|
32
|
+
* GitHub form preserves that identity.
|
|
33
|
+
*
|
|
34
|
+
* Catalog subpath entries are left alone: `#path:` identifies a different
|
|
35
|
+
* package inside the repo, so the acceleration step never rewrites that
|
|
36
|
+
* fragment. Collection roots discovered after install preserve the resolved
|
|
37
|
+
* commit and add their subpath as pnpm's second `&path:` selector.
|
|
38
|
+
*
|
|
39
|
+
* Every SHA-lookup failure falls back to the original target. Acceleration
|
|
40
|
+
* is an optimisation, and an optimisation that can fail an install is a bug.
|
|
41
|
+
*/
|
|
42
|
+
import { logEvent } from './log.js';
|
|
43
|
+
import { marketFetch } from './net.js';
|
|
44
|
+
import { githubRoutesFor, rememberGithubRoute, routesFor, throughProxy, } from './regions.js';
|
|
45
|
+
/** A bare repo shortcut whose HEAD can be replaced by one immutable ref. */
|
|
46
|
+
const BARE_GITHUB_RE = /^github:([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)$/;
|
|
47
|
+
/**
|
|
48
|
+
* How long to wait for the SHA before giving up and installing directly.
|
|
49
|
+
*
|
|
50
|
+
* Short on purpose: this is spent BEFORE the download starts, and the whole
|
|
51
|
+
* point is to avoid a slow or unreachable direct metadata lookup. A proxy
|
|
52
|
+
* that cannot answer promptly should not delay pnpm's ordinary direct path.
|
|
53
|
+
*/
|
|
54
|
+
const RESOLVE_TIMEOUT_MS = 6000;
|
|
55
|
+
/**
|
|
56
|
+
* The commit `HEAD` points at, from git's own ref advertisement.
|
|
57
|
+
*
|
|
58
|
+
* This is the endpoint `git clone` reads before it fetches anything, and it
|
|
59
|
+
* is the right one here for two measured reasons. It is not the REST API, so
|
|
60
|
+
* it does not consume the 60-requests-per-hour unauthenticated quota that a
|
|
61
|
+
* user installing a handful of plugins could plausibly exhaust. And it
|
|
62
|
+
* survives the proxy: over five consecutive tries from an unproxied mainland
|
|
63
|
+
* connection it answered 200 in ~1.2s every time, while the REST API through
|
|
64
|
+
* the same proxy returned 200, 200, then 403 — a proxy that rate-limits the
|
|
65
|
+
* API path would silently drop every install back to the slow route.
|
|
66
|
+
*
|
|
67
|
+
* The response is git's pkt-line format, whose first ref line carries
|
|
68
|
+
* `<sha> HEAD\0<capabilities>`. Read with a pattern rather than a parser:
|
|
69
|
+
* one 40-character hex string followed by `HEAD` is unambiguous in this
|
|
70
|
+
* payload, and a length-prefix reader would be more code to get wrong.
|
|
71
|
+
*
|
|
72
|
+
* The same advertisement lists every branch and tag, which is what `ref`
|
|
73
|
+
* uses. A plugin installed from `github:owner/repo#publish` is not asking
|
|
74
|
+
* about the default branch at all, and answering with it made the market
|
|
75
|
+
* report an update forever (#446) — the two SHAs simply never match. Both
|
|
76
|
+
* namespaces are searched because pnpm accepts a tag there too, branches
|
|
77
|
+
* first since that is what the reports are about.
|
|
78
|
+
* @param ref - branch or tag to resolve, or undefined for the default branch.
|
|
79
|
+
*/
|
|
80
|
+
export async function headCommit(repo, proxy, signal, ref) {
|
|
81
|
+
const result = await tryHeadCommit(repo, proxy, signal, ref);
|
|
82
|
+
return result.kind === 'valid' ? result.sha : null;
|
|
83
|
+
}
|
|
84
|
+
/** One route attempt, preserving valid "ref is absent" from invalid payloads. */
|
|
85
|
+
async function tryHeadCommit(repo, proxy, signal, ref) {
|
|
86
|
+
const base = `https://github.com/${repo}/info/refs?service=git-upload-pack`;
|
|
87
|
+
try {
|
|
88
|
+
const res = await marketFetch(throughProxy(proxy, base), {
|
|
89
|
+
signal,
|
|
90
|
+
headers: { 'user-agent': 'git/2.40.0' },
|
|
91
|
+
});
|
|
92
|
+
if (!res.ok)
|
|
93
|
+
return { kind: 'failed' };
|
|
94
|
+
const body = await res.text();
|
|
95
|
+
const contentType = res
|
|
96
|
+
.headers?.get?.('content-type')?.toLowerCase() ?? '';
|
|
97
|
+
// Public mirrors often answer a failed upstream request with their own
|
|
98
|
+
// branded HTML and status 200. A git advertisement has both its service
|
|
99
|
+
// prelude and at least one advertised ref; accepting anything else would
|
|
100
|
+
// cache a route that never returned Git data in the first place.
|
|
101
|
+
if (contentType.includes('text/html')
|
|
102
|
+
|| !body.includes('# service=git-upload-pack')
|
|
103
|
+
|| !/[0-9a-f]{40} (?:HEAD|refs\/(?:heads|tags)\/)/u.test(body)) {
|
|
104
|
+
return { kind: 'failed' };
|
|
105
|
+
}
|
|
106
|
+
if (ref === undefined) {
|
|
107
|
+
const found = /([0-9a-f]{40}) HEAD/.exec(body);
|
|
108
|
+
return { kind: 'valid', sha: found === null ? null : found[1] };
|
|
109
|
+
}
|
|
110
|
+
// Anchored to the ref's full name so `publish` cannot match a branch
|
|
111
|
+
// called `publish-old`, and escaped because a ref may contain regex
|
|
112
|
+
// metacharacters (`.` is legal in a branch name).
|
|
113
|
+
const quoted = ref.replace(/[.*+?^${}()|[\]\\]/gu, String.raw `\$&`);
|
|
114
|
+
for (const namespace of ['heads', 'tags']) {
|
|
115
|
+
const found = new RegExp(String.raw `([0-9a-f]{40}) refs/${namespace}/${quoted}(?![^\s])`, 'u').exec(body);
|
|
116
|
+
if (found !== null)
|
|
117
|
+
return { kind: 'valid', sha: found[1] };
|
|
118
|
+
}
|
|
119
|
+
// The advertisement is authoritative for this repository. Asking another
|
|
120
|
+
// mirror cannot make a branch that is absent here appear.
|
|
121
|
+
return { kind: 'valid', sha: null };
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return { kind: 'failed' };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Run one candidate under its own budget, optionally linked to a caller signal. */
|
|
128
|
+
async function timedHeadCommit(repo, route, ref, signal) {
|
|
129
|
+
const controller = new AbortController();
|
|
130
|
+
const abort = () => { controller.abort(); };
|
|
131
|
+
if (signal?.aborted === true)
|
|
132
|
+
controller.abort();
|
|
133
|
+
else
|
|
134
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
135
|
+
const timer = setTimeout(abort, RESOLVE_TIMEOUT_MS);
|
|
136
|
+
try {
|
|
137
|
+
return await tryHeadCommit(repo, route, controller.signal, ref);
|
|
138
|
+
}
|
|
139
|
+
finally {
|
|
140
|
+
clearTimeout(timer);
|
|
141
|
+
signal?.removeEventListener('abort', abort);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The current `HEAD` commit for a repo, on whichever route the region uses.
|
|
146
|
+
*
|
|
147
|
+
* Wraps the timeout so callers outside the install path — the build-script
|
|
148
|
+
* approval below, which needs a commit-pinned key — do not each reinvent it.
|
|
149
|
+
*/
|
|
150
|
+
export async function resolveHeadCommit(repo, region, env = process.env, ref) {
|
|
151
|
+
for (const route of githubRoutesFor('git', region, env)) {
|
|
152
|
+
const result = await timedHeadCommit(repo, route, ref);
|
|
153
|
+
if (result.kind === 'failed')
|
|
154
|
+
continue;
|
|
155
|
+
rememberGithubRoute('git', route);
|
|
156
|
+
return result.sha;
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The install target to actually hand pnpm, given the region in force.
|
|
162
|
+
*
|
|
163
|
+
* @param target - what `installTargetFor` produced.
|
|
164
|
+
* @param region - the download region.
|
|
165
|
+
* @param env - environment, for the proxy override.
|
|
166
|
+
* @returns a commit-pinned GitHub shortcut when one route resolves HEAD,
|
|
167
|
+
* otherwise `target` unchanged.
|
|
168
|
+
*/
|
|
169
|
+
export async function acceleratedTarget(target, region, env = process.env) {
|
|
170
|
+
// A plain global install lets pnpm do its ordinary GitHub resolution. A
|
|
171
|
+
// custom prefix makes even that region an accelerated one.
|
|
172
|
+
if (routesFor(region, env).githubProxy === null)
|
|
173
|
+
return target;
|
|
174
|
+
const bare = BARE_GITHUB_RE.exec(target);
|
|
175
|
+
if (bare === null)
|
|
176
|
+
return target;
|
|
177
|
+
const repo = bare[1];
|
|
178
|
+
const sha = await resolveHeadCommit(repo, region, env);
|
|
179
|
+
if (sha === null) {
|
|
180
|
+
logEvent('info', 'region', `${repo}: could not resolve a commit through the available routes; installing directly`);
|
|
181
|
+
return target;
|
|
182
|
+
}
|
|
183
|
+
return `github:${repo}#${sha}`;
|
|
184
|
+
}
|
package/lib/agents.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional host-provided agent inventory: lets the market refuse plugin
|
|
3
|
+
* mutations while a live agent is mid-turn. Mutating `node_modules` under a
|
|
4
|
+
* running agent replaces files the running plugin modules may still read or
|
|
5
|
+
* lazily import — the update "succeeds" while old code and new files mix.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Ids of the host's currently running agents, or [] when the host has no
|
|
9
|
+
* agents service. Only a positive `status === 'running'` blocks an update —
|
|
10
|
+
* unknown statuses are treated as not running, so a future agent
|
|
11
|
+
* implementation with different wording fails open (the market stays
|
|
12
|
+
* usable) instead of wedging the plugin page.
|
|
13
|
+
*/
|
|
14
|
+
export function runningAgentIds(agents) {
|
|
15
|
+
if (agents === undefined)
|
|
16
|
+
return [];
|
|
17
|
+
let listed;
|
|
18
|
+
try {
|
|
19
|
+
listed = agents.list();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// A half-disposed registry must never take the market's routes down.
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
if (!Array.isArray(listed))
|
|
26
|
+
return [];
|
|
27
|
+
const ids = [];
|
|
28
|
+
for (const agent of listed) {
|
|
29
|
+
if (agent === null || typeof agent !== 'object' || agent.status !== 'running')
|
|
30
|
+
continue;
|
|
31
|
+
const id = typeof agent.id === 'string' && agent.id !== '' ? agent.id : 'agent';
|
|
32
|
+
if (!ids.includes(id))
|
|
33
|
+
ids.push(id);
|
|
34
|
+
}
|
|
35
|
+
return ids;
|
|
36
|
+
}
|