@cmmd-center/forge 0.9.16 → 0.9.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +175 -33
- package/dist/bin.mjs +199 -57
- package/dist/client/assets/{CanvasPanel-Dc8j2ouo.js → CanvasPanel-D9sKevpO.js} +2 -2
- package/dist/client/assets/{CompositeItem-Cn5DdObI.js → CompositeItem-Bsi2e5qV.js} +2 -2
- package/dist/client/assets/{DiffPanel-CRdkVPEz.js → DiffPanel-ClMWe6-c.js} +2 -2
- package/dist/client/assets/{DiffPanel.logic-BIPcNz_o.js → DiffPanel.logic-o7tDdTzf.js} +2 -2
- package/dist/client/assets/{DiffPanelShell-tIdXu7mn.js → DiffPanelShell-R1Q66jTc.js} +2 -2
- package/dist/client/assets/{DiffWorkerPoolProvider-tFSGuVfC.js → DiffWorkerPoolProvider-lEFZi8QR.js} +2 -2
- package/dist/client/assets/{PullRequestCodePanel-inwJYfZC.js → PullRequestCodePanel-BpbniIb5.js} +2 -2
- package/dist/client/assets/{Virtualizer-DeKxnAeU.js → Virtualizer-B5NXbN5f.js} +2 -2
- package/dist/client/assets/{canvasStateStore-Dlm4tanv.js → canvasStateStore-qioLqOoT.js} +2 -2
- package/dist/client/assets/{cmmdAuthRedirect-C1FjO86g.js → cmmdAuthRedirect-lmPzseq5.js} +2 -2
- package/dist/client/assets/{index-BvXPD-Rk.js → index-D0769c3n.js} +18 -18
- package/dist/client/assets/{src-DljvAdHI.js → src-BL6J64vk.js} +3 -3
- package/dist/client/assets/{toggle-It2CvaLA.js → toggle-CW3yNjj1.js} +2 -2
- package/dist/client/assets/{useTriggerFocusGuards-DfUh9uvu.js → useTriggerFocusGuards-mvO6ygs-.js} +2 -2
- package/dist/client/index.html +10 -10
- package/dist/{open-D8mGyWmt.mjs → open-FIgTDosf.mjs} +3 -3
- package/package.json +1 -1
package/dist/bin.mjs
CHANGED
|
@@ -22,7 +22,7 @@ import { createCipheriv, createDecipheriv, createHash, createHmac, createPublicK
|
|
|
22
22
|
import * as FS$1 from "node:fs";
|
|
23
23
|
import fs, { accessSync, chmodSync, constants, createReadStream, existsSync, mkdirSync, mkdtempSync, promises, readFile, readFileSync, readdir, readdirSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
24
24
|
import * as NodeOS from "node:os";
|
|
25
|
-
import
|
|
25
|
+
import os, { homedir, networkInterfaces, tmpdir } from "node:os";
|
|
26
26
|
import * as Path$1 from "node:path";
|
|
27
27
|
import path, { basename, delimiter, dirname, extname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
28
28
|
import { pathToFileURL } from "node:url";
|
|
@@ -22164,6 +22164,40 @@ const ServerProviderAuth = Struct({
|
|
|
22164
22164
|
accountEmail: optional$4(TrimmedNonEmptyString),
|
|
22165
22165
|
provenance: optional$4(ProviderAuthProvenance)
|
|
22166
22166
|
});
|
|
22167
|
+
/**
|
|
22168
|
+
* Whether this Environment will let a person select the provider.
|
|
22169
|
+
*
|
|
22170
|
+
* Published for every provider the build knows about. A provider is never
|
|
22171
|
+
* dropped from the list: absence is not a state, and four different reasons
|
|
22172
|
+
* once collapsed into one "Coming soon." string because the Shell had to infer
|
|
22173
|
+
* meaning from what was missing. See
|
|
22174
|
+
* `docs/adr/withheld-providers-carry-their-reason.md`.
|
|
22175
|
+
*/
|
|
22176
|
+
const ProviderAvailability = Literals(["available", "unavailable"]);
|
|
22177
|
+
/**
|
|
22178
|
+
* Why a Withheld Provider is withheld. The four members are the glossary's,
|
|
22179
|
+
* in `CONTEXT.md` section "Provider availability": Unbuilt, Not Offered, Not
|
|
22180
|
+
* Usable, Not on this Environment. Only Unbuilt may read "Coming soon."
|
|
22181
|
+
*
|
|
22182
|
+
* An Environment can only ever report Unbuilt, Not Usable, or Not on this
|
|
22183
|
+
* Environment. Not Offered is a CMMD fact about the organization's Provider
|
|
22184
|
+
* Offer, which the Shell adds when it joins.
|
|
22185
|
+
*/
|
|
22186
|
+
const ProviderUnavailableReason = Literals([
|
|
22187
|
+
"unbuilt",
|
|
22188
|
+
"not-offered",
|
|
22189
|
+
"not-usable",
|
|
22190
|
+
"not-on-this-environment"
|
|
22191
|
+
]);
|
|
22192
|
+
/**
|
|
22193
|
+
* The Not Usable sub-case. It picks a second line of copy, not a fifth state,
|
|
22194
|
+
* which is why it is a separate field rather than three more reasons.
|
|
22195
|
+
*/
|
|
22196
|
+
const ProviderUnavailableDetail = Literals([
|
|
22197
|
+
"no-connection",
|
|
22198
|
+
"delivery-pending",
|
|
22199
|
+
"reconnect-required"
|
|
22200
|
+
]);
|
|
22167
22201
|
const ServerProviderModel = Struct({
|
|
22168
22202
|
slug: TrimmedNonEmptyString,
|
|
22169
22203
|
name: TrimmedNonEmptyString,
|
|
@@ -22195,6 +22229,9 @@ const ServerProvider = Struct({
|
|
|
22195
22229
|
checkedAt: IsoDateTime,
|
|
22196
22230
|
message: optional$4(TrimmedNonEmptyString),
|
|
22197
22231
|
models: ArraySchema(ServerProviderModel),
|
|
22232
|
+
availability: optional$4(ProviderAvailability),
|
|
22233
|
+
unavailableReason: optional$4(ProviderUnavailableReason),
|
|
22234
|
+
unavailableDetail: optional$4(ProviderUnavailableDetail),
|
|
22198
22235
|
slashCommands: ArraySchema(ServerProviderSlashCommand).pipe(withDecodingDefault(succeed([]))),
|
|
22199
22236
|
skills: ArraySchema(ServerProviderSkill).pipe(withDecodingDefault(succeed([])))
|
|
22200
22237
|
});
|
|
@@ -49482,7 +49519,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
|
49482
49519
|
const min = forceColor || 0;
|
|
49483
49520
|
if (env.TERM === "dumb") return min;
|
|
49484
49521
|
if (process$1.platform === "win32") {
|
|
49485
|
-
const osRelease =
|
|
49522
|
+
const osRelease = os.release().split(".");
|
|
49486
49523
|
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
49487
49524
|
return 1;
|
|
49488
49525
|
}
|
|
@@ -51925,7 +51962,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
51925
51962
|
exports.processDetector = void 0;
|
|
51926
51963
|
const api_1 = (init_esm$1(), __toCommonJS(esm_exports$1));
|
|
51927
51964
|
const semconv_1 = require_semconv$1();
|
|
51928
|
-
const os$
|
|
51965
|
+
const os$4 = __require("os");
|
|
51929
51966
|
/**
|
|
51930
51967
|
* ProcessDetector will be used to detect the resources related current process running
|
|
51931
51968
|
* and being instrumented from the NodeJS Process module.
|
|
@@ -51947,7 +51984,7 @@ var require_ProcessDetector = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
51947
51984
|
};
|
|
51948
51985
|
if (process.argv.length > 1) attributes[semconv_1.ATTR_PROCESS_COMMAND] = process.argv[1];
|
|
51949
51986
|
try {
|
|
51950
|
-
const userInfo = os$
|
|
51987
|
+
const userInfo = os$4.userInfo();
|
|
51951
51988
|
attributes[semconv_1.ATTR_PROCESS_OWNER] = userInfo.username;
|
|
51952
51989
|
} catch (e) {
|
|
51953
51990
|
api_1.diag.debug(`error obtaining process owner: ${e}`);
|
|
@@ -64870,7 +64907,7 @@ function normalizeNumberish(value) {
|
|
|
64870
64907
|
}
|
|
64871
64908
|
//#endregion
|
|
64872
64909
|
//#region package.json
|
|
64873
|
-
var version$1 = "0.9.
|
|
64910
|
+
var version$1 = "0.9.17";
|
|
64874
64911
|
//#endregion
|
|
64875
64912
|
//#region src/sentry.ts
|
|
64876
64913
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -73500,7 +73537,7 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
|
|
|
73500
73537
|
var fs$6 = __require("fs");
|
|
73501
73538
|
var path$5 = __require("path");
|
|
73502
73539
|
var url$1 = __require("url");
|
|
73503
|
-
var os$
|
|
73540
|
+
var os$3 = __require("os");
|
|
73504
73541
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
73505
73542
|
var vars = process.config && process.config.variables || {};
|
|
73506
73543
|
var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
|
|
@@ -73508,8 +73545,8 @@ var require_node_gyp_build = /* @__PURE__ */ __commonJSMin(((exports, module) =>
|
|
|
73508
73545
|
var abi = versions.modules;
|
|
73509
73546
|
if (versions.deno || process.isBun) abi = "unsupported";
|
|
73510
73547
|
var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
|
|
73511
|
-
var arch = process.env.npm_config_arch || os$
|
|
73512
|
-
var platform = process.env.npm_config_platform || os$
|
|
73548
|
+
var arch = process.env.npm_config_arch || os$3.arch();
|
|
73549
|
+
var platform = process.env.npm_config_platform || os$3.platform();
|
|
73513
73550
|
var libc = process.env.LIBC || (isMusl(platform) ? "musl" : "glibc");
|
|
73514
73551
|
var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
|
|
73515
73552
|
var uv = (versions.uv || "").split(".")[0];
|
|
@@ -91167,7 +91204,7 @@ const launchDetached = (launch) => gen(function* () {
|
|
|
91167
91204
|
});
|
|
91168
91205
|
const OpenLive = effect(Open, gen(function* () {
|
|
91169
91206
|
const open = yield* tryPromise({
|
|
91170
|
-
try: () => import("./open-
|
|
91207
|
+
try: () => import("./open-FIgTDosf.mjs"),
|
|
91171
91208
|
catch: (cause) => new OpenError$1({
|
|
91172
91209
|
message: "failed to load browser opener",
|
|
91173
91210
|
cause
|
|
@@ -184380,7 +184417,7 @@ var Vce = {
|
|
|
184380
184417
|
function Ve() {
|
|
184381
184418
|
return Vce;
|
|
184382
184419
|
}
|
|
184383
|
-
var Us =
|
|
184420
|
+
var Us = os.homedir(), lk = os.tmpdir(), { env: Vc } = process$1, Yce = (e) => {
|
|
184384
184421
|
let t = path.join(Us, "Library");
|
|
184385
184422
|
return {
|
|
184386
184423
|
data: path.join(t, "Application Support", e),
|
|
@@ -194580,12 +194617,12 @@ function qZ(e, t) {
|
|
|
194580
194617
|
}
|
|
194581
194618
|
return n;
|
|
194582
194619
|
}
|
|
194583
|
-
var os$
|
|
194620
|
+
var os$2 = "https://code.claude.com/docs/en", kKe = [
|
|
194584
194621
|
{
|
|
194585
194622
|
matches: (e) => e.path === "permissions.defaultMode" && e.code === "invalid_value",
|
|
194586
194623
|
tip: {
|
|
194587
194624
|
suggestion: "Valid modes: \"acceptEdits\" (ask before file changes), \"plan\" (analysis only), \"bypassPermissions\" (auto-accept all), or \"default\" (standard behavior)",
|
|
194588
|
-
docLink: `${os$
|
|
194625
|
+
docLink: `${os$2}/iam#permission-modes`
|
|
194589
194626
|
}
|
|
194590
194627
|
},
|
|
194591
194628
|
{
|
|
@@ -194600,7 +194637,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
194600
194637
|
matches: (e) => e.path.startsWith("env.") && e.code === "invalid_type",
|
|
194601
194638
|
tip: {
|
|
194602
194639
|
suggestion: "Environment variables must be strings. Wrap numbers and booleans in quotes. Example: \"DEBUG\": \"true\", \"PORT\": \"3000\"",
|
|
194603
|
-
docLink: `${os$
|
|
194640
|
+
docLink: `${os$2}/settings#environment-variables`
|
|
194604
194641
|
}
|
|
194605
194642
|
},
|
|
194606
194643
|
{
|
|
@@ -194611,14 +194648,14 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
194611
194648
|
matches: (e) => e.path.startsWith("hooks.") && e.code === "invalid_key",
|
|
194612
194649
|
tip: {
|
|
194613
194650
|
suggestion: "Not a recognized hook event. Common events: PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, Stop. Check spelling and capitalization.",
|
|
194614
|
-
docLink: `${os$
|
|
194651
|
+
docLink: `${os$2}/hooks`
|
|
194615
194652
|
}
|
|
194616
194653
|
},
|
|
194617
194654
|
{
|
|
194618
194655
|
matches: (e) => /\.hooks\.\d+\.command$/.test(e.path) && e.code === "invalid_type" && e.received === "undefined",
|
|
194619
194656
|
tip: {
|
|
194620
194657
|
suggestion: "Command hooks require `command`. For exec form (no shell), set `command` to the executable and `args` to its arguments: {\"type\": \"command\", \"command\": \"echo\", \"args\": [\"hi\"]}. For shell form, set `command` to the full shell string: {\"type\": \"command\", \"command\": \"echo hi\"}.",
|
|
194621
|
-
docLink: `${os$
|
|
194658
|
+
docLink: `${os$2}/hooks#exec-form-and-shell-form`
|
|
194622
194659
|
}
|
|
194623
194660
|
},
|
|
194624
194661
|
{
|
|
@@ -194633,7 +194670,7 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
194633
194670
|
matches: (e) => e.code === "unrecognized_keys",
|
|
194634
194671
|
tip: {
|
|
194635
194672
|
suggestion: "Check for typos or refer to the documentation for valid fields",
|
|
194636
|
-
docLink: `${os$
|
|
194673
|
+
docLink: `${os$2}/settings`
|
|
194637
194674
|
}
|
|
194638
194675
|
},
|
|
194639
194676
|
{
|
|
@@ -194648,13 +194685,13 @@ var os$1 = "https://code.claude.com/docs/en", kKe = [
|
|
|
194648
194685
|
matches: (e) => e.path === "permissions.additionalDirectories" && e.code === "invalid_type",
|
|
194649
194686
|
tip: {
|
|
194650
194687
|
suggestion: "Must be an array of directory paths. Example: [\"~/projects\", \"/tmp/workspace\"]. You can also use --add-dir flag or /add-dir command",
|
|
194651
|
-
docLink: `${os$
|
|
194688
|
+
docLink: `${os$2}/iam#working-directories`
|
|
194652
194689
|
}
|
|
194653
194690
|
}
|
|
194654
194691
|
], AKe = {
|
|
194655
|
-
permissions: `${os$
|
|
194656
|
-
env: `${os$
|
|
194657
|
-
hooks: `${os$
|
|
194692
|
+
permissions: `${os$2}/iam#configuring-permissions`,
|
|
194693
|
+
env: `${os$2}/settings#environment-variables`,
|
|
194694
|
+
hooks: `${os$2}/hooks`
|
|
194658
194695
|
};
|
|
194659
194696
|
function GZ(e) {
|
|
194660
194697
|
let t = kKe.find((r) => r.matches(e));
|
|
@@ -258907,7 +258944,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
|
|
|
258907
258944
|
var dgram = __require("dgram");
|
|
258908
258945
|
var thunky = require_thunky();
|
|
258909
258946
|
var events = __require("events");
|
|
258910
|
-
var os = __require("os");
|
|
258947
|
+
var os$1 = __require("os");
|
|
258911
258948
|
var noop = function() {};
|
|
258912
258949
|
module.exports = function(opts) {
|
|
258913
258950
|
if (!opts) opts = {};
|
|
@@ -259038,14 +259075,14 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
|
|
|
259038
259075
|
return that;
|
|
259039
259076
|
};
|
|
259040
259077
|
function defaultInterface() {
|
|
259041
|
-
var networks = os.networkInterfaces();
|
|
259078
|
+
var networks = os$1.networkInterfaces();
|
|
259042
259079
|
var names = Object.keys(networks);
|
|
259043
259080
|
for (var i = 0; i < names.length; i++) {
|
|
259044
259081
|
var net = networks[names[i]];
|
|
259045
259082
|
for (var j = 0; j < net.length; j++) {
|
|
259046
259083
|
var iface = net[j];
|
|
259047
259084
|
if (isIPv4(iface.family) && !iface.internal) {
|
|
259048
|
-
if (os.platform() === "darwin" && names[i] === "en0") return iface.address;
|
|
259085
|
+
if (os$1.platform() === "darwin" && names[i] === "en0") return iface.address;
|
|
259049
259086
|
return "0.0.0.0";
|
|
259050
259087
|
}
|
|
259051
259088
|
}
|
|
@@ -259053,7 +259090,7 @@ var import_multicast_dns = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMi
|
|
|
259053
259090
|
return "127.0.0.1";
|
|
259054
259091
|
}
|
|
259055
259092
|
function allInterfaces() {
|
|
259056
|
-
var networks = os.networkInterfaces();
|
|
259093
|
+
var networks = os$1.networkInterfaces();
|
|
259057
259094
|
var names = Object.keys(networks);
|
|
259058
259095
|
var res = [];
|
|
259059
259096
|
for (var i = 0; i < names.length; i++) {
|
|
@@ -284577,14 +284614,87 @@ const writeProviderStatusCache = (input) => {
|
|
|
284577
284614
|
})));
|
|
284578
284615
|
};
|
|
284579
284616
|
//#endregion
|
|
284580
|
-
//#region
|
|
284617
|
+
//#region ../../packages/shared/src/providerExecution.ts
|
|
284618
|
+
/**
|
|
284619
|
+
* Canonical provider-readiness gate for starting work.
|
|
284620
|
+
*
|
|
284621
|
+
* Cloud user VMs can execute through Forge's scoped provider proxy without a
|
|
284622
|
+
* provider-local login. In that case the provider reports unauthenticated but
|
|
284623
|
+
* its credential provenance is explicitly `proxied`.
|
|
284624
|
+
*/
|
|
284625
|
+
function isServerProviderExecutable(provider) {
|
|
284626
|
+
const hasExecutionAuthority = provider.auth.status !== "unauthenticated" || provider.auth.provenance?.credentialScope === "proxied";
|
|
284627
|
+
return provider.enabled && provider.installed && provider.status === "ready" && hasExecutionAuthority && provider.models.length > 0;
|
|
284628
|
+
}
|
|
284629
|
+
//#endregion
|
|
284630
|
+
//#region src/provider/providerAvailability.ts
|
|
284581
284631
|
/**
|
|
284582
|
-
*
|
|
284583
|
-
*
|
|
284584
|
-
*
|
|
284585
|
-
*
|
|
284632
|
+
* Derive what this Environment knows about a provider's availability.
|
|
284633
|
+
*
|
|
284634
|
+
* WHY THIS EXISTS
|
|
284635
|
+
*
|
|
284636
|
+
* Four different states (Unbuilt, Not Offered, Not Usable, Not on this
|
|
284637
|
+
* Environment) used to render as one "Coming soon." string, because consumers
|
|
284638
|
+
* were handed a filtered list and had to infer meaning from what was missing.
|
|
284639
|
+
* Every provider is now published with an explicit availability and, when
|
|
284640
|
+
* withheld, its reason. See `docs/adr/withheld-providers-carry-their-reason.md`
|
|
284641
|
+
* and the glossary in `CONTEXT.md` section "Provider availability".
|
|
284642
|
+
*
|
|
284643
|
+
* WHAT AN ENVIRONMENT MAY SAY
|
|
284644
|
+
*
|
|
284645
|
+
* Three of the four reasons only. Not Offered is a fact about the CMMD
|
|
284646
|
+
* organization's Provider Offer, and delivery-pending is a fact about a
|
|
284647
|
+
* credential in flight; neither is visible from inside an Environment, so the
|
|
284648
|
+
* Shell adds them when it joins. Nothing here may invent them.
|
|
284649
|
+
*
|
|
284650
|
+
* This reads the snapshot a provider Layer already produced. It runs no probe
|
|
284651
|
+
* and changes no probe: `isServerProviderExecutable` stays the single gate on
|
|
284652
|
+
* whether a turn can be dispatched, and this restates its answer in the
|
|
284653
|
+
* vocabulary a person sees.
|
|
284586
284654
|
*/
|
|
284587
|
-
|
|
284655
|
+
/**
|
|
284656
|
+
* Providers Forge ships in the UI but cannot execute, published as Unbuilt.
|
|
284657
|
+
*
|
|
284658
|
+
* Empty in this build: codex, claudeAgent, ollama, cmmd, apex, cursor and
|
|
284659
|
+
* opencode all have a real detection Layer and a registered adapter. The list
|
|
284660
|
+
* stays as the one place a provider that ships ahead of its server-side
|
|
284661
|
+
* implementation is named, so "Coming soon." is a deliberate entry rather than
|
|
284662
|
+
* a fallback something fell into.
|
|
284663
|
+
*/
|
|
284664
|
+
const UNBUILT_PROVIDERS = [];
|
|
284665
|
+
function deriveProviderAvailability(provider, unbuiltProviders = UNBUILT_PROVIDERS) {
|
|
284666
|
+
if (unbuiltProviders.includes(provider.provider)) return {
|
|
284667
|
+
availability: "unavailable",
|
|
284668
|
+
unavailableReason: "unbuilt"
|
|
284669
|
+
};
|
|
284670
|
+
if (isServerProviderExecutable(provider)) return { availability: "available" };
|
|
284671
|
+
const hasProxiedCredential = provider.auth.provenance?.credentialScope === "proxied";
|
|
284672
|
+
if (provider.installed && provider.auth.status === "unauthenticated" && !hasProxiedCredential) return {
|
|
284673
|
+
availability: "unavailable",
|
|
284674
|
+
unavailableReason: "not-usable",
|
|
284675
|
+
unavailableDetail: "no-connection"
|
|
284676
|
+
};
|
|
284677
|
+
return {
|
|
284678
|
+
availability: "unavailable",
|
|
284679
|
+
unavailableReason: "not-on-this-environment"
|
|
284680
|
+
};
|
|
284681
|
+
}
|
|
284682
|
+
/**
|
|
284683
|
+
* Stamp a snapshot with its derived availability.
|
|
284684
|
+
*
|
|
284685
|
+
* The previous fields are dropped before the new ones are applied. Merging
|
|
284686
|
+
* would leave a provider that just connected reporting `available` while still
|
|
284687
|
+
* carrying the reason it was withheld for.
|
|
284688
|
+
*/
|
|
284689
|
+
function withProviderAvailability(provider, unbuiltProviders = UNBUILT_PROVIDERS) {
|
|
284690
|
+
const { availability: _availability, unavailableReason: _unavailableReason, unavailableDetail: _unavailableDetail, ...rest } = provider;
|
|
284691
|
+
return {
|
|
284692
|
+
...rest,
|
|
284693
|
+
...deriveProviderAvailability(provider, unbuiltProviders)
|
|
284694
|
+
};
|
|
284695
|
+
}
|
|
284696
|
+
//#endregion
|
|
284697
|
+
//#region src/provider/Layers/ProviderRegistry.ts
|
|
284588
284698
|
const loadProviders = (codexProvider, claudeProvider, ollamaProvider, cmmdProvider, apexProvider, cursorProvider, opencodeProvider) => all([
|
|
284589
284699
|
codexProvider.getSnapshot,
|
|
284590
284700
|
claudeProvider.getSnapshot,
|
|
@@ -284621,9 +284731,9 @@ const ProviderRegistryLive = effect(ProviderRegistry, gen(function* () {
|
|
|
284621
284731
|
cachedProvider,
|
|
284622
284732
|
fallbackProvider
|
|
284623
284733
|
});
|
|
284624
|
-
return
|
|
284734
|
+
return UNBUILT_PROVIDERS.includes(provider) ? fallbackProvider : void 0;
|
|
284625
284735
|
}));
|
|
284626
|
-
}, { concurrency: "unbounded" }).pipe(map$3((providers) => orderProviderSnapshots(providers.filter((provider) => provider !== void 0)))));
|
|
284736
|
+
}, { concurrency: "unbounded" }).pipe(map$3((providers) => orderProviderSnapshots(providers.filter((provider) => provider !== void 0).map((provider) => withProviderAvailability(provider))))));
|
|
284627
284737
|
const persistProvider = (provider) => writeProviderStatusCache({
|
|
284628
284738
|
filePath: cachePathByProvider.get(provider.provider),
|
|
284629
284739
|
provider
|
|
@@ -284631,7 +284741,8 @@ const ProviderRegistryLive = effect(ProviderRegistry, gen(function* () {
|
|
|
284631
284741
|
provider: provider.provider,
|
|
284632
284742
|
error
|
|
284633
284743
|
})), ignore);
|
|
284634
|
-
const upsertProviders = fn$1("upsertProviders")(function* (
|
|
284744
|
+
const upsertProviders = fn$1("upsertProviders")(function* (incomingProviders, options) {
|
|
284745
|
+
const nextProviders = incomingProviders.map((provider) => withProviderAvailability(provider));
|
|
284635
284746
|
const [previousProviders, providers] = yield* modify$3(providersRef, (previousProviders) => {
|
|
284636
284747
|
const mergedProviders = new Map(previousProviders.map((provider) => [provider.provider, provider]));
|
|
284637
284748
|
for (const provider of nextProviders) mergedProviders.set(provider.provider, provider);
|
|
@@ -287392,7 +287503,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
287392
287503
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
287393
287504
|
*/
|
|
287394
287505
|
function readBakedBuildCommit() {
|
|
287395
|
-
return "
|
|
287506
|
+
return "86c71b55bb7a5dfbbad063d6e4c082570759f006";
|
|
287396
287507
|
}
|
|
287397
287508
|
async function resolveServerBuildCommit(input) {
|
|
287398
287509
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -300054,21 +300165,24 @@ function processRuntimeReplicationOutboxItem(item, dependencies) {
|
|
|
300054
300165
|
//#endregion
|
|
300055
300166
|
//#region src/runtimeReplication/Services/ActiveHourMeter.ts
|
|
300056
300167
|
var ActiveHourMeter = class extends Service$1()("forge/runtimeReplication/Services/ActiveHourMeter") {};
|
|
300057
|
-
|
|
300058
|
-
|
|
300168
|
+
/** `slug` and `name` are `.min(1).max(512)` on the receiving schema. */
|
|
300169
|
+
const FIELD_MAX_LENGTH = 512;
|
|
300170
|
+
/** `version` is `.max(128)` on the receiving schema, with no length floor. */
|
|
300171
|
+
const VERSION_MAX_LENGTH = 128;
|
|
300172
|
+
/** `binaryPath` is `.max(2048)` on the receiving schema, with no length floor. */
|
|
300173
|
+
const BINARY_PATH_MAX_LENGTH = 2048;
|
|
300059
300174
|
/**
|
|
300060
|
-
*
|
|
300175
|
+
* Trim to the receiving schema's maximum, or null.
|
|
300061
300176
|
*
|
|
300062
|
-
*
|
|
300063
|
-
*
|
|
300064
|
-
*
|
|
300177
|
+
* Neither field has a length floor, so an empty string would be legal — but it
|
|
300178
|
+
* is not an answer. A version nobody resolved and a binary nobody found are
|
|
300179
|
+
* both null, which is what the control plane stores and what a reader can tell
|
|
300180
|
+
* apart from a real value.
|
|
300065
300181
|
*/
|
|
300066
|
-
function
|
|
300067
|
-
const
|
|
300068
|
-
return
|
|
300182
|
+
function cappedText(value, max) {
|
|
300183
|
+
const normalized = value?.trim().slice(0, max);
|
|
300184
|
+
return normalized ? normalized : null;
|
|
300069
300185
|
}
|
|
300070
|
-
/** `slug` and `name` are `.min(1).max(512)` on the receiving schema. */
|
|
300071
|
-
const FIELD_MAX_LENGTH = 512;
|
|
300072
300186
|
function serializeModel(model) {
|
|
300073
300187
|
const slug = model.slug.trim().slice(0, FIELD_MAX_LENGTH);
|
|
300074
300188
|
const name = model.name.trim().slice(0, FIELD_MAX_LENGTH);
|
|
@@ -300082,20 +300196,48 @@ function serializeModel(model) {
|
|
|
300082
300196
|
name
|
|
300083
300197
|
};
|
|
300084
300198
|
}
|
|
300199
|
+
/**
|
|
300200
|
+
* The availability to publish for one provider.
|
|
300201
|
+
*
|
|
300202
|
+
* The registry stamps every snapshot before it leaves, so this normally copies.
|
|
300203
|
+
* Deriving over a stamped snapshot would lose the one fact only the registry
|
|
300204
|
+
* holds — which providers this build cannot run at all — and republish every
|
|
300205
|
+
* Unbuilt provider as Not on this Environment. The fallback covers a snapshot
|
|
300206
|
+
* that reached the outbox from some other path.
|
|
300207
|
+
*
|
|
300208
|
+
* Built by spread so a key with no value is ABSENT rather than `undefined`: the
|
|
300209
|
+
* receiving object is `.strict()`, `undefined` is not a legal enum member, and
|
|
300210
|
+
* the outbox retries the resulting 400 forever.
|
|
300211
|
+
*/
|
|
300212
|
+
function publishedAvailability(provider) {
|
|
300213
|
+
if (provider.availability === void 0) return deriveProviderAvailability(provider);
|
|
300214
|
+
const reason = provider.unavailableReason;
|
|
300215
|
+
const detail = provider.unavailableDetail;
|
|
300216
|
+
return {
|
|
300217
|
+
availability: provider.availability,
|
|
300218
|
+
...reason === void 0 ? {} : { unavailableReason: reason },
|
|
300219
|
+
...detail === void 0 ? {} : { unavailableDetail: detail }
|
|
300220
|
+
};
|
|
300221
|
+
}
|
|
300222
|
+
function serializeProvider(provider) {
|
|
300223
|
+
const models = [];
|
|
300224
|
+
for (const model of provider.models) {
|
|
300225
|
+
if (models.length >= 256) break;
|
|
300226
|
+
const serialized = serializeModel(model);
|
|
300227
|
+
if (serialized) models.push(serialized);
|
|
300228
|
+
}
|
|
300229
|
+
return {
|
|
300230
|
+
provider: provider.provider,
|
|
300231
|
+
models,
|
|
300232
|
+
...publishedAvailability(provider),
|
|
300233
|
+
version: cappedText(provider.version, VERSION_MAX_LENGTH),
|
|
300234
|
+
binaryPath: cappedText(provider.auth.provenance?.binaryPath, BINARY_PATH_MAX_LENGTH)
|
|
300235
|
+
};
|
|
300236
|
+
}
|
|
300085
300237
|
function serializeProviderCatalog(providers) {
|
|
300086
300238
|
const catalog = [];
|
|
300087
300239
|
for (const provider of providers) {
|
|
300088
|
-
|
|
300089
|
-
const models = [];
|
|
300090
|
-
for (const model of provider.models) {
|
|
300091
|
-
if (models.length >= 256) break;
|
|
300092
|
-
const serialized = serializeModel(model);
|
|
300093
|
-
if (serialized) models.push(serialized);
|
|
300094
|
-
}
|
|
300095
|
-
catalog.push({
|
|
300096
|
-
provider: provider.provider,
|
|
300097
|
-
models
|
|
300098
|
-
});
|
|
300240
|
+
catalog.push(serializeProvider(provider));
|
|
300099
300241
|
if (catalog.length >= 16) break;
|
|
300100
300242
|
}
|
|
300101
300243
|
return catalog;
|
|
@@ -310543,7 +310685,7 @@ const connectLoginCommand = make$32("login", {
|
|
|
310543
310685
|
})).json();
|
|
310544
310686
|
},
|
|
310545
310687
|
openBrowser: async (url) => {
|
|
310546
|
-
const open = (await import("./open-
|
|
310688
|
+
const open = (await import("./open-FIgTDosf.mjs")).default;
|
|
310547
310689
|
await open(url);
|
|
310548
310690
|
return true;
|
|
310549
310691
|
},
|