@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.cjs
CHANGED
|
@@ -22345,6 +22345,40 @@ const ServerProviderAuth = require_Schema$1.Struct({
|
|
|
22345
22345
|
accountEmail: require_Schema$1.optional(TrimmedNonEmptyString),
|
|
22346
22346
|
provenance: require_Schema$1.optional(ProviderAuthProvenance)
|
|
22347
22347
|
});
|
|
22348
|
+
/**
|
|
22349
|
+
* Whether this Environment will let a person select the provider.
|
|
22350
|
+
*
|
|
22351
|
+
* Published for every provider the build knows about. A provider is never
|
|
22352
|
+
* dropped from the list: absence is not a state, and four different reasons
|
|
22353
|
+
* once collapsed into one "Coming soon." string because the Shell had to infer
|
|
22354
|
+
* meaning from what was missing. See
|
|
22355
|
+
* `docs/adr/withheld-providers-carry-their-reason.md`.
|
|
22356
|
+
*/
|
|
22357
|
+
const ProviderAvailability = require_Schema$1.Literals(["available", "unavailable"]);
|
|
22358
|
+
/**
|
|
22359
|
+
* Why a Withheld Provider is withheld. The four members are the glossary's,
|
|
22360
|
+
* in `CONTEXT.md` section "Provider availability": Unbuilt, Not Offered, Not
|
|
22361
|
+
* Usable, Not on this Environment. Only Unbuilt may read "Coming soon."
|
|
22362
|
+
*
|
|
22363
|
+
* An Environment can only ever report Unbuilt, Not Usable, or Not on this
|
|
22364
|
+
* Environment. Not Offered is a CMMD fact about the organization's Provider
|
|
22365
|
+
* Offer, which the Shell adds when it joins.
|
|
22366
|
+
*/
|
|
22367
|
+
const ProviderUnavailableReason = require_Schema$1.Literals([
|
|
22368
|
+
"unbuilt",
|
|
22369
|
+
"not-offered",
|
|
22370
|
+
"not-usable",
|
|
22371
|
+
"not-on-this-environment"
|
|
22372
|
+
]);
|
|
22373
|
+
/**
|
|
22374
|
+
* The Not Usable sub-case. It picks a second line of copy, not a fifth state,
|
|
22375
|
+
* which is why it is a separate field rather than three more reasons.
|
|
22376
|
+
*/
|
|
22377
|
+
const ProviderUnavailableDetail = require_Schema$1.Literals([
|
|
22378
|
+
"no-connection",
|
|
22379
|
+
"delivery-pending",
|
|
22380
|
+
"reconnect-required"
|
|
22381
|
+
]);
|
|
22348
22382
|
const ServerProviderModel = require_Schema$1.Struct({
|
|
22349
22383
|
slug: TrimmedNonEmptyString,
|
|
22350
22384
|
name: TrimmedNonEmptyString,
|
|
@@ -22376,6 +22410,9 @@ const ServerProvider = require_Schema$1.Struct({
|
|
|
22376
22410
|
checkedAt: IsoDateTime,
|
|
22377
22411
|
message: require_Schema$1.optional(TrimmedNonEmptyString),
|
|
22378
22412
|
models: require_Schema$1.ArraySchema(ServerProviderModel),
|
|
22413
|
+
availability: require_Schema$1.optional(ProviderAvailability),
|
|
22414
|
+
unavailableReason: require_Schema$1.optional(ProviderUnavailableReason),
|
|
22415
|
+
unavailableDetail: require_Schema$1.optional(ProviderUnavailableDetail),
|
|
22379
22416
|
slashCommands: require_Schema$1.ArraySchema(ServerProviderSlashCommand).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed([]))),
|
|
22380
22417
|
skills: require_Schema$1.ArraySchema(ServerProviderSkill).pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed([])))
|
|
22381
22418
|
});
|
|
@@ -65123,7 +65160,7 @@ function normalizeNumberish(value) {
|
|
|
65123
65160
|
}
|
|
65124
65161
|
//#endregion
|
|
65125
65162
|
//#region package.json
|
|
65126
|
-
var version$1 = "0.9.
|
|
65163
|
+
var version$1 = "0.9.17";
|
|
65127
65164
|
//#endregion
|
|
65128
65165
|
//#region src/sentry.ts
|
|
65129
65166
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -285043,14 +285080,87 @@ const writeProviderStatusCache = (input) => {
|
|
|
285043
285080
|
})));
|
|
285044
285081
|
};
|
|
285045
285082
|
//#endregion
|
|
285046
|
-
//#region
|
|
285083
|
+
//#region ../../packages/shared/src/providerExecution.ts
|
|
285084
|
+
/**
|
|
285085
|
+
* Canonical provider-readiness gate for starting work.
|
|
285086
|
+
*
|
|
285087
|
+
* Cloud user VMs can execute through Forge's scoped provider proxy without a
|
|
285088
|
+
* provider-local login. In that case the provider reports unauthenticated but
|
|
285089
|
+
* its credential provenance is explicitly `proxied`.
|
|
285090
|
+
*/
|
|
285091
|
+
function isServerProviderExecutable(provider) {
|
|
285092
|
+
const hasExecutionAuthority = provider.auth.status !== "unauthenticated" || provider.auth.provenance?.credentialScope === "proxied";
|
|
285093
|
+
return provider.enabled && provider.installed && provider.status === "ready" && hasExecutionAuthority && provider.models.length > 0;
|
|
285094
|
+
}
|
|
285095
|
+
//#endregion
|
|
285096
|
+
//#region src/provider/providerAvailability.ts
|
|
285047
285097
|
/**
|
|
285048
|
-
*
|
|
285049
|
-
*
|
|
285050
|
-
*
|
|
285051
|
-
*
|
|
285098
|
+
* Derive what this Environment knows about a provider's availability.
|
|
285099
|
+
*
|
|
285100
|
+
* WHY THIS EXISTS
|
|
285101
|
+
*
|
|
285102
|
+
* Four different states (Unbuilt, Not Offered, Not Usable, Not on this
|
|
285103
|
+
* Environment) used to render as one "Coming soon." string, because consumers
|
|
285104
|
+
* were handed a filtered list and had to infer meaning from what was missing.
|
|
285105
|
+
* Every provider is now published with an explicit availability and, when
|
|
285106
|
+
* withheld, its reason. See `docs/adr/withheld-providers-carry-their-reason.md`
|
|
285107
|
+
* and the glossary in `CONTEXT.md` section "Provider availability".
|
|
285108
|
+
*
|
|
285109
|
+
* WHAT AN ENVIRONMENT MAY SAY
|
|
285110
|
+
*
|
|
285111
|
+
* Three of the four reasons only. Not Offered is a fact about the CMMD
|
|
285112
|
+
* organization's Provider Offer, and delivery-pending is a fact about a
|
|
285113
|
+
* credential in flight; neither is visible from inside an Environment, so the
|
|
285114
|
+
* Shell adds them when it joins. Nothing here may invent them.
|
|
285115
|
+
*
|
|
285116
|
+
* This reads the snapshot a provider Layer already produced. It runs no probe
|
|
285117
|
+
* and changes no probe: `isServerProviderExecutable` stays the single gate on
|
|
285118
|
+
* whether a turn can be dispatched, and this restates its answer in the
|
|
285119
|
+
* vocabulary a person sees.
|
|
285052
285120
|
*/
|
|
285053
|
-
|
|
285121
|
+
/**
|
|
285122
|
+
* Providers Forge ships in the UI but cannot execute, published as Unbuilt.
|
|
285123
|
+
*
|
|
285124
|
+
* Empty in this build: codex, claudeAgent, ollama, cmmd, apex, cursor and
|
|
285125
|
+
* opencode all have a real detection Layer and a registered adapter. The list
|
|
285126
|
+
* stays as the one place a provider that ships ahead of its server-side
|
|
285127
|
+
* implementation is named, so "Coming soon." is a deliberate entry rather than
|
|
285128
|
+
* a fallback something fell into.
|
|
285129
|
+
*/
|
|
285130
|
+
const UNBUILT_PROVIDERS = [];
|
|
285131
|
+
function deriveProviderAvailability(provider, unbuiltProviders = UNBUILT_PROVIDERS) {
|
|
285132
|
+
if (unbuiltProviders.includes(provider.provider)) return {
|
|
285133
|
+
availability: "unavailable",
|
|
285134
|
+
unavailableReason: "unbuilt"
|
|
285135
|
+
};
|
|
285136
|
+
if (isServerProviderExecutable(provider)) return { availability: "available" };
|
|
285137
|
+
const hasProxiedCredential = provider.auth.provenance?.credentialScope === "proxied";
|
|
285138
|
+
if (provider.installed && provider.auth.status === "unauthenticated" && !hasProxiedCredential) return {
|
|
285139
|
+
availability: "unavailable",
|
|
285140
|
+
unavailableReason: "not-usable",
|
|
285141
|
+
unavailableDetail: "no-connection"
|
|
285142
|
+
};
|
|
285143
|
+
return {
|
|
285144
|
+
availability: "unavailable",
|
|
285145
|
+
unavailableReason: "not-on-this-environment"
|
|
285146
|
+
};
|
|
285147
|
+
}
|
|
285148
|
+
/**
|
|
285149
|
+
* Stamp a snapshot with its derived availability.
|
|
285150
|
+
*
|
|
285151
|
+
* The previous fields are dropped before the new ones are applied. Merging
|
|
285152
|
+
* would leave a provider that just connected reporting `available` while still
|
|
285153
|
+
* carrying the reason it was withheld for.
|
|
285154
|
+
*/
|
|
285155
|
+
function withProviderAvailability(provider, unbuiltProviders = UNBUILT_PROVIDERS) {
|
|
285156
|
+
const { availability: _availability, unavailableReason: _unavailableReason, unavailableDetail: _unavailableDetail, ...rest } = provider;
|
|
285157
|
+
return {
|
|
285158
|
+
...rest,
|
|
285159
|
+
...deriveProviderAvailability(provider, unbuiltProviders)
|
|
285160
|
+
};
|
|
285161
|
+
}
|
|
285162
|
+
//#endregion
|
|
285163
|
+
//#region src/provider/Layers/ProviderRegistry.ts
|
|
285054
285164
|
const loadProviders = (codexProvider, claudeProvider, ollamaProvider, cmmdProvider, apexProvider, cursorProvider, opencodeProvider) => require_Schema$1.all([
|
|
285055
285165
|
codexProvider.getSnapshot,
|
|
285056
285166
|
claudeProvider.getSnapshot,
|
|
@@ -285087,9 +285197,9 @@ const ProviderRegistryLive = require_Schema$1.effect(ProviderRegistry, require_S
|
|
|
285087
285197
|
cachedProvider,
|
|
285088
285198
|
fallbackProvider
|
|
285089
285199
|
});
|
|
285090
|
-
return
|
|
285200
|
+
return UNBUILT_PROVIDERS.includes(provider) ? fallbackProvider : void 0;
|
|
285091
285201
|
}));
|
|
285092
|
-
}, { concurrency: "unbounded" }).pipe(require_Schema$1.map((providers) => orderProviderSnapshots(providers.filter((provider) => provider !== void 0))));
|
|
285202
|
+
}, { concurrency: "unbounded" }).pipe(require_Schema$1.map((providers) => orderProviderSnapshots(providers.filter((provider) => provider !== void 0).map((provider) => withProviderAvailability(provider)))));
|
|
285093
285203
|
const providersRef = yield* require_HttpServer.make$3(cachedProviders);
|
|
285094
285204
|
const persistProvider = (provider) => writeProviderStatusCache({
|
|
285095
285205
|
filePath: cachePathByProvider.get(provider.provider),
|
|
@@ -285098,7 +285208,8 @@ const ProviderRegistryLive = require_Schema$1.effect(ProviderRegistry, require_S
|
|
|
285098
285208
|
provider: provider.provider,
|
|
285099
285209
|
error
|
|
285100
285210
|
})), require_Schema$1.ignore);
|
|
285101
|
-
const upsertProviders = require_Schema$1.fn("upsertProviders")(function* (
|
|
285211
|
+
const upsertProviders = require_Schema$1.fn("upsertProviders")(function* (incomingProviders, options) {
|
|
285212
|
+
const nextProviders = incomingProviders.map((provider) => withProviderAvailability(provider));
|
|
285102
285213
|
const [previousProviders, providers] = yield* require_HttpServer.modify(providersRef, (previousProviders) => {
|
|
285103
285214
|
const mergedProviders = new Map(previousProviders.map((provider) => [provider.provider, provider]));
|
|
285104
285215
|
for (const provider of nextProviders) mergedProviders.set(provider.provider, provider);
|
|
@@ -287887,7 +287998,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
287887
287998
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
287888
287999
|
*/
|
|
287889
288000
|
function readBakedBuildCommit() {
|
|
287890
|
-
return "
|
|
288001
|
+
return "86c71b55bb7a5dfbbad063d6e4c082570759f006";
|
|
287891
288002
|
}
|
|
287892
288003
|
async function resolveServerBuildCommit(input) {
|
|
287893
288004
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -300625,21 +300736,24 @@ function processRuntimeReplicationOutboxItem(item, dependencies) {
|
|
|
300625
300736
|
//#endregion
|
|
300626
300737
|
//#region src/runtimeReplication/Services/ActiveHourMeter.ts
|
|
300627
300738
|
var ActiveHourMeter = class extends require_Schema$1.Service()("forge/runtimeReplication/Services/ActiveHourMeter") {};
|
|
300628
|
-
|
|
300629
|
-
|
|
300739
|
+
/** `slug` and `name` are `.min(1).max(512)` on the receiving schema. */
|
|
300740
|
+
const FIELD_MAX_LENGTH = 512;
|
|
300741
|
+
/** `version` is `.max(128)` on the receiving schema, with no length floor. */
|
|
300742
|
+
const VERSION_MAX_LENGTH = 128;
|
|
300743
|
+
/** `binaryPath` is `.max(2048)` on the receiving schema, with no length floor. */
|
|
300744
|
+
const BINARY_PATH_MAX_LENGTH = 2048;
|
|
300630
300745
|
/**
|
|
300631
|
-
*
|
|
300746
|
+
* Trim to the receiving schema's maximum, or null.
|
|
300632
300747
|
*
|
|
300633
|
-
*
|
|
300634
|
-
*
|
|
300635
|
-
*
|
|
300748
|
+
* Neither field has a length floor, so an empty string would be legal — but it
|
|
300749
|
+
* is not an answer. A version nobody resolved and a binary nobody found are
|
|
300750
|
+
* both null, which is what the control plane stores and what a reader can tell
|
|
300751
|
+
* apart from a real value.
|
|
300636
300752
|
*/
|
|
300637
|
-
function
|
|
300638
|
-
const
|
|
300639
|
-
return
|
|
300753
|
+
function cappedText(value, max) {
|
|
300754
|
+
const normalized = value?.trim().slice(0, max);
|
|
300755
|
+
return normalized ? normalized : null;
|
|
300640
300756
|
}
|
|
300641
|
-
/** `slug` and `name` are `.min(1).max(512)` on the receiving schema. */
|
|
300642
|
-
const FIELD_MAX_LENGTH = 512;
|
|
300643
300757
|
function serializeModel(model) {
|
|
300644
300758
|
const slug = model.slug.trim().slice(0, FIELD_MAX_LENGTH);
|
|
300645
300759
|
const name = model.name.trim().slice(0, FIELD_MAX_LENGTH);
|
|
@@ -300653,20 +300767,48 @@ function serializeModel(model) {
|
|
|
300653
300767
|
name
|
|
300654
300768
|
};
|
|
300655
300769
|
}
|
|
300770
|
+
/**
|
|
300771
|
+
* The availability to publish for one provider.
|
|
300772
|
+
*
|
|
300773
|
+
* The registry stamps every snapshot before it leaves, so this normally copies.
|
|
300774
|
+
* Deriving over a stamped snapshot would lose the one fact only the registry
|
|
300775
|
+
* holds — which providers this build cannot run at all — and republish every
|
|
300776
|
+
* Unbuilt provider as Not on this Environment. The fallback covers a snapshot
|
|
300777
|
+
* that reached the outbox from some other path.
|
|
300778
|
+
*
|
|
300779
|
+
* Built by spread so a key with no value is ABSENT rather than `undefined`: the
|
|
300780
|
+
* receiving object is `.strict()`, `undefined` is not a legal enum member, and
|
|
300781
|
+
* the outbox retries the resulting 400 forever.
|
|
300782
|
+
*/
|
|
300783
|
+
function publishedAvailability(provider) {
|
|
300784
|
+
if (provider.availability === void 0) return deriveProviderAvailability(provider);
|
|
300785
|
+
const reason = provider.unavailableReason;
|
|
300786
|
+
const detail = provider.unavailableDetail;
|
|
300787
|
+
return {
|
|
300788
|
+
availability: provider.availability,
|
|
300789
|
+
...reason === void 0 ? {} : { unavailableReason: reason },
|
|
300790
|
+
...detail === void 0 ? {} : { unavailableDetail: detail }
|
|
300791
|
+
};
|
|
300792
|
+
}
|
|
300793
|
+
function serializeProvider(provider) {
|
|
300794
|
+
const models = [];
|
|
300795
|
+
for (const model of provider.models) {
|
|
300796
|
+
if (models.length >= 256) break;
|
|
300797
|
+
const serialized = serializeModel(model);
|
|
300798
|
+
if (serialized) models.push(serialized);
|
|
300799
|
+
}
|
|
300800
|
+
return {
|
|
300801
|
+
provider: provider.provider,
|
|
300802
|
+
models,
|
|
300803
|
+
...publishedAvailability(provider),
|
|
300804
|
+
version: cappedText(provider.version, VERSION_MAX_LENGTH),
|
|
300805
|
+
binaryPath: cappedText(provider.auth.provenance?.binaryPath, BINARY_PATH_MAX_LENGTH)
|
|
300806
|
+
};
|
|
300807
|
+
}
|
|
300656
300808
|
function serializeProviderCatalog(providers) {
|
|
300657
300809
|
const catalog = [];
|
|
300658
300810
|
for (const provider of providers) {
|
|
300659
|
-
|
|
300660
|
-
const models = [];
|
|
300661
|
-
for (const model of provider.models) {
|
|
300662
|
-
if (models.length >= 256) break;
|
|
300663
|
-
const serialized = serializeModel(model);
|
|
300664
|
-
if (serialized) models.push(serialized);
|
|
300665
|
-
}
|
|
300666
|
-
catalog.push({
|
|
300667
|
-
provider: provider.provider,
|
|
300668
|
-
models
|
|
300669
|
-
});
|
|
300811
|
+
catalog.push(serializeProvider(provider));
|
|
300670
300812
|
if (catalog.length >= 16) break;
|
|
300671
300813
|
}
|
|
300672
300814
|
return catalog;
|