@integrity-labs/agt-cli 0.28.650 → 0.28.652
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/agt.js +5 -5
- package/dist/{chunk-5DXWVKCZ.js → chunk-6PR2K3XB.js} +4 -4
- package/dist/{chunk-CSLG2XMX.js → chunk-E26EKDFP.js} +2 -2
- package/dist/{chunk-ZAZKEL4Y.js → chunk-HRMF6VUK.js} +48 -16
- package/dist/chunk-HRMF6VUK.js.map +1 -0
- package/dist/{claude-pair-runtime-ENRW5IDG.js → claude-pair-runtime-E6BFNZUV.js} +2 -2
- package/dist/lib/manager-worker.js +13 -13
- package/dist/mcp/direct-chat-channel.js +47 -15
- package/dist/mcp/index.js +47 -15
- package/dist/mcp/origami.js +47 -15
- package/dist/mcp/slack-channel.js +47 -15
- package/dist/mcp/telegram-channel.js +47 -15
- package/dist/{persistent-session-2JT7HIFF.js → persistent-session-XXP4NGEP.js} +3 -3
- package/dist/{responsiveness-probe-5TOZHK3H.js → responsiveness-probe-QSJ263ZW.js} +3 -3
- package/dist/{session-auth-dead-PFCVB7MZ.js → session-auth-dead-HHZT5KIM.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-ZAZKEL4Y.js.map +0 -1
- /package/dist/{chunk-5DXWVKCZ.js.map → chunk-6PR2K3XB.js.map} +0 -0
- /package/dist/{chunk-CSLG2XMX.js.map → chunk-E26EKDFP.js.map} +0 -0
- /package/dist/{claude-pair-runtime-ENRW5IDG.js.map → claude-pair-runtime-E6BFNZUV.js.map} +0 -0
- /package/dist/{persistent-session-2JT7HIFF.js.map → persistent-session-XXP4NGEP.js.map} +0 -0
- /package/dist/{responsiveness-probe-5TOZHK3H.js.map → responsiveness-probe-QSJ263ZW.js.map} +0 -0
- /package/dist/{session-auth-dead-PFCVB7MZ.js.map → session-auth-dead-HHZT5KIM.js.map} +0 -0
|
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
|
|
|
100
100
|
return { ok: true };
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
103
|
+
const { resolveClaudeBinary } = await import("./persistent-session-XXP4NGEP.js");
|
|
104
104
|
const claudeBin = resolveClaudeBinary();
|
|
105
105
|
const pairEnv = {
|
|
106
106
|
...process.env,
|
|
@@ -373,4 +373,4 @@ export {
|
|
|
373
373
|
startClaudePair,
|
|
374
374
|
submitClaudePairCode
|
|
375
375
|
};
|
|
376
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
376
|
+
//# sourceMappingURL=claude-pair-runtime-E6BFNZUV.js.map
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
safeWriteJsonAtomic,
|
|
56
56
|
setConfigHash,
|
|
57
57
|
tripClass
|
|
58
|
-
} from "../chunk-
|
|
58
|
+
} from "../chunk-6PR2K3XB.js";
|
|
59
59
|
import {
|
|
60
60
|
getProjectDir as getProjectDir2,
|
|
61
61
|
getReadyTasks,
|
|
@@ -111,7 +111,7 @@ import {
|
|
|
111
111
|
takeZombieDetection,
|
|
112
112
|
toOpencodeModel,
|
|
113
113
|
writeEgressAllowlist
|
|
114
|
-
} from "../chunk-
|
|
114
|
+
} from "../chunk-E26EKDFP.js";
|
|
115
115
|
import {
|
|
116
116
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
117
117
|
AnchorSessionClient,
|
|
@@ -192,7 +192,7 @@ import {
|
|
|
192
192
|
subagentActivityAgeSeconds,
|
|
193
193
|
sumTranscriptUsageInWindow,
|
|
194
194
|
transcriptActivityAgeSeconds
|
|
195
|
-
} from "../chunk-
|
|
195
|
+
} from "../chunk-HRMF6VUK.js";
|
|
196
196
|
import {
|
|
197
197
|
reapOrphanChannelMcps
|
|
198
198
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -11609,7 +11609,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
11609
11609
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
11610
11610
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
11611
11611
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
11612
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
11612
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-QSJ263ZW.js");
|
|
11613
11613
|
const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
|
|
11614
11614
|
if (newest === null) return null;
|
|
11615
11615
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -12252,7 +12252,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
12252
12252
|
var lastVersionCheckAt = 0;
|
|
12253
12253
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
12254
12254
|
var lastResponsivenessProbeAt = 0;
|
|
12255
|
-
var agtCliVersion = true ? "0.28.
|
|
12255
|
+
var agtCliVersion = true ? "0.28.652" : "dev";
|
|
12256
12256
|
function resolveBrewPath(execFileSync3) {
|
|
12257
12257
|
try {
|
|
12258
12258
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -13560,7 +13560,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
13560
13560
|
if (codeNames.length === 0) return;
|
|
13561
13561
|
void (async () => {
|
|
13562
13562
|
try {
|
|
13563
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13563
|
+
const { collectDiagnostics } = await import("../persistent-session-XXP4NGEP.js");
|
|
13564
13564
|
await api.post("/host/heartbeat", {
|
|
13565
13565
|
host_id: hostId,
|
|
13566
13566
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -13676,7 +13676,7 @@ async function pollCycleInner() {
|
|
|
13676
13676
|
}
|
|
13677
13677
|
try {
|
|
13678
13678
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
13679
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13679
|
+
const { collectDiagnostics } = await import("../persistent-session-XXP4NGEP.js");
|
|
13680
13680
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
13681
13681
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor) : void 0;
|
|
13682
13682
|
let tailscaleHostname;
|
|
@@ -13799,7 +13799,7 @@ async function pollCycleInner() {
|
|
|
13799
13799
|
collectPanelessActivityProbes,
|
|
13800
13800
|
getResponsivenessIntervalMs,
|
|
13801
13801
|
occupancyQualificationClassifications
|
|
13802
|
-
} = await import("../responsiveness-probe-
|
|
13802
|
+
} = await import("../responsiveness-probe-QSJ263ZW.js");
|
|
13803
13803
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
13804
13804
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
13805
13805
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -13909,7 +13909,7 @@ async function pollCycleInner() {
|
|
|
13909
13909
|
collectResponsivenessProbes,
|
|
13910
13910
|
livePendingInboundOldestAgeSeconds,
|
|
13911
13911
|
parkPendingInbound
|
|
13912
|
-
} = await import("../responsiveness-probe-
|
|
13912
|
+
} = await import("../responsiveness-probe-QSJ263ZW.js");
|
|
13913
13913
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
13914
13914
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
13915
13915
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -14065,7 +14065,7 @@ async function pollCycleInner() {
|
|
|
14065
14065
|
}
|
|
14066
14066
|
try {
|
|
14067
14067
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
|
|
14068
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
14068
|
+
const { probeSessionAuth } = await import("../session-auth-dead-HHZT5KIM.js");
|
|
14069
14069
|
const observations = [];
|
|
14070
14070
|
const pendingCacheCommits = [];
|
|
14071
14071
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -17698,7 +17698,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
17698
17698
|
void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
|
|
17699
17699
|
void (async () => {
|
|
17700
17700
|
try {
|
|
17701
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
17701
|
+
const { collectDiagnostics } = await import("../persistent-session-XXP4NGEP.js");
|
|
17702
17702
|
await api.post("/host/heartbeat", {
|
|
17703
17703
|
host_id: hostId,
|
|
17704
17704
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -17749,7 +17749,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
17749
17749
|
}
|
|
17750
17750
|
try {
|
|
17751
17751
|
const hostId = await getHostId();
|
|
17752
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
17752
|
+
const { collectDiagnostics } = await import("../persistent-session-XXP4NGEP.js");
|
|
17753
17753
|
await api.post("/host/heartbeat", {
|
|
17754
17754
|
host_id: hostId,
|
|
17755
17755
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
|
|
@@ -18346,7 +18346,7 @@ async function processClaudePairSessions(agents) {
|
|
|
18346
18346
|
killPairSession,
|
|
18347
18347
|
pairTmuxSession,
|
|
18348
18348
|
finalizeClaudePairOnboarding
|
|
18349
|
-
} = await import("../claude-pair-runtime-
|
|
18349
|
+
} = await import("../claude-pair-runtime-E6BFNZUV.js");
|
|
18350
18350
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
18351
18351
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
18352
18352
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -32209,6 +32209,9 @@ var TIER_PATTERNS = [
|
|
|
32209
32209
|
}
|
|
32210
32210
|
];
|
|
32211
32211
|
|
|
32212
|
+
// ../core/dist/integrations/pending-approval.js
|
|
32213
|
+
var PENDING_APPROVAL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
32214
|
+
|
|
32212
32215
|
// ../core/dist/integrations/augmented-live/markup.js
|
|
32213
32216
|
var MARKUP_MARKER = "__augmentedLiveMarkup";
|
|
32214
32217
|
var MARKUP_CONTROL_MARKER = "__augmentedLiveMarkupControl";
|
|
@@ -33674,7 +33677,7 @@ var INTEGRATION_REGISTRY = [
|
|
|
33674
33677
|
id: "firecrawl",
|
|
33675
33678
|
name: "Firecrawl",
|
|
33676
33679
|
category: "knowledge",
|
|
33677
|
-
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account
|
|
33680
|
+
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account.",
|
|
33678
33681
|
// ENG-7217: Firecrawl migrates from a customer-API-key stdio MCP
|
|
33679
33682
|
// (`npx firecrawl-mcp`, FIRECRAWL_API_KEY) to a PREMIUM, platform-managed
|
|
33680
33683
|
// integration on the Deck / ElevenLabs model (ADR-0031, epic ENG-6920):
|
|
@@ -33685,16 +33688,30 @@ var INTEGRATION_REGISTRY = [
|
|
|
33685
33688
|
// is metered at the one control-plane chokepoint and gated on a per-org opt-in
|
|
33686
33689
|
// + monthly USD cap.
|
|
33687
33690
|
//
|
|
33688
|
-
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
33689
|
-
//
|
|
33691
|
+
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
33692
|
+
// was also offered so a customer could bring their OWN Firecrawl key. A BYO
|
|
33690
33693
|
// install (`credential_source='byo'`) authenticates with the customer's key
|
|
33691
33694
|
// (stored encrypted on the install) and is NOT metered — its upstream cost is
|
|
33692
|
-
// on the customer's own Firecrawl bill.
|
|
33693
|
-
//
|
|
33694
|
-
// `api_key` is
|
|
33695
|
-
// `
|
|
33696
|
-
//
|
|
33697
|
-
|
|
33695
|
+
// on the customer's own Firecrawl bill.
|
|
33696
|
+
//
|
|
33697
|
+
// ENG-9235: `api_key` is PARKED, not abandoned. BYO is gated on the plan-tier
|
|
33698
|
+
// `byo_credentials` entitlement, which only `enterprise` has (the column is
|
|
33699
|
+
// NOT NULL DEFAULT false, and ENG-9143 explicitly set it false for Team). The
|
|
33700
|
+
// connect wizard never reads that flag, so offering `api_key` here sent every
|
|
33701
|
+
// Team/Business customer to firecrawl.dev for a key we would then reject with
|
|
33702
|
+
// a 403 `byo_not_entitled_by_plan` — after they had signed up for it.
|
|
33703
|
+
//
|
|
33704
|
+
// Removing it is also what removes that screen: the wizard's picker only
|
|
33705
|
+
// renders for 2+ selectable auth types (`selectableWizardAuthMethods`), so a
|
|
33706
|
+
// single `['none']` restores the friction-free managed install with no UI
|
|
33707
|
+
// change. Restore `api_key` only together with an entitlement-aware wizard —
|
|
33708
|
+
// see ENG-9236 for the proper fix.
|
|
33709
|
+
//
|
|
33710
|
+
// KEEP IN LOCKSTEP with the `firecrawl` row in
|
|
33711
|
+
// packages/supabase/seeds/toolkit-definitions.json: that seed carries its own
|
|
33712
|
+
// `auth_types` and is what `db:catalog:seed` upserts on every prod deploy, so
|
|
33713
|
+
// editing this array alone changes nothing a customer can see.
|
|
33714
|
+
supported_auth_types: ["none"],
|
|
33698
33715
|
capabilities: [
|
|
33699
33716
|
{ id: "firecrawl:scrape", name: "Scrape Pages", description: "Fetch a single URL as clean markdown / structured data (firecrawl_scrape).", access: "write" },
|
|
33700
33717
|
{ id: "firecrawl:search", name: "Web Search", description: "Search the web and return ranked results, optionally scraped (firecrawl_search).", access: "write" },
|
|
@@ -36354,18 +36371,33 @@ var FLAG_REGISTRY = [
|
|
|
36354
36371
|
},
|
|
36355
36372
|
{
|
|
36356
36373
|
key: "ninjafy-brand",
|
|
36357
|
-
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is USER-FACING BRAND
|
|
36374
|
+
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is the USER-FACING BRAND PRESENTATION \u2014 text AND VISUAL THEME. ENG-8858 widened this from text alone: the Ninjafy palette is gated here too, because a colour theme is not text. It stays ONE key rather than gaining a `ninjafy-theme` sibling, so a half-branded state \u2014 ninjafy wordmark over Augmented green \u2014 is unreachable and the rebrand keeps a single kill switch. It must never gate a code identifier, package name, env var or CLI name. EXISTING identifiers stay `Augmented`/`agt` per the CLAUDE.md naming contract, which protects them from premature renaming \u2014 the deep rename is workstream C of docs/runbooks/rebrand-ninjafy-migration.md and is out of scope here. That contract does NOT require NEW code to carry the old brand: artefacts created specifically for the rebrand take Ninjafy naming (ENG-8078 decision 9; see the CLAUDE.md rebrand carve-out). Either way it is a naming rule, not a flag concern \u2014 this key gates presentation, never an identifier. Set the stage-wide default to flip a whole environment, or add a feature_flag_overrides row to pilot a subset while everyone else still sees Augmented. Overrides resolve at FOUR grains, most specific first \u2014 agent, team, host, then org-wide (evaluate.ts:79-81); organization_id is always required, so there is no global override. Org and team are the useful pilot grains for THIS flag: there is now exactly ONE consumer \u2014 (dashboard)/layout.tsx via getPublicBooleanFlagServer \u2014 evaluating in the active-org cookie scope, so a host- or agent-scoped row is accepted by the table but never reached by the console. It resolves the key ONCE per request and passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop. Resolution is SERVER-side deliberately: the client hook starts at its default and updates after an async GET /flags, so anything gated on it paints Augmented and then repaints. ENG-8858 moved the PALETTE for that reason (a full-page colour flash); ENG-9227 moved the WORDMARK, which had been the last surface still swapping after hydration. A consequence worth knowing: /login and the marketing routes stay on the Augmented palette whatever an org sets, because getPublicBooleanFlagServer returns the default without a verified session and a pre-auth page has neither a session nor an active org \u2014 a PER-ORG flag structurally cannot brand one. Those surfaces follow only when the stage-wide default flips. Ships dark.',
|
|
36358
36375
|
flagType: "boolean",
|
|
36359
36376
|
// Declared safe value is `false`: the pre-rebrand brand. `false` is also the
|
|
36360
36377
|
// fail-closed direction — if the flag DB is unreachable we must show the brand
|
|
36361
36378
|
// that is currently live and contractually correct, never leak an unannounced
|
|
36362
36379
|
// rebrand to every customer at once.
|
|
36363
36380
|
defaultValue: false,
|
|
36364
|
-
//
|
|
36365
|
-
//
|
|
36366
|
-
//
|
|
36367
|
-
//
|
|
36368
|
-
//
|
|
36381
|
+
// ENG-9227: there are NO client readers of this key left. (dashboard)/
|
|
36382
|
+
// layout.tsx resolves it ONCE server-side via getPublicBooleanFlagServer and
|
|
36383
|
+
// passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop.
|
|
36384
|
+
// ENG-8858 did that for the THEME; ENG-9227 finished the job for the
|
|
36385
|
+
// WORDMARK, which had kept usePublicBooleanFlag and so kept swapping
|
|
36386
|
+
// "augmented.team" to "ninjafy" after hydration.
|
|
36387
|
+
//
|
|
36388
|
+
// `public` MUST STAY ANYWAY, and this is the trap. It is tempting to read
|
|
36389
|
+
// "no client readers" as "no longer needs to be public" — but
|
|
36390
|
+
// getPublicBooleanFlagServer resolves against the very same `GET /flags`
|
|
36391
|
+
// endpoint the browser uses, and that route filters to listPublicFlagKeys()
|
|
36392
|
+
// (routes/flags.ts:72-75). A non-public key is simply absent from the map,
|
|
36393
|
+
// so the server helper would fall through to its default and return `false`
|
|
36394
|
+
// FOREVER — the brand quietly reverting to Augmented for every org, with no
|
|
36395
|
+
// error anywhere. `public` here means "readable through the public map",
|
|
36396
|
+
// not "read by a browser".
|
|
36397
|
+
//
|
|
36398
|
+
// Unlike onboarding-msteams-channel above there is no wrong-org hazard — the
|
|
36399
|
+
// single reader evaluates inside the active-org cookie's scope, which is
|
|
36400
|
+
// exactly the org whose brand should be shown.
|
|
36369
36401
|
public: true
|
|
36370
36402
|
},
|
|
36371
36403
|
{
|
package/dist/mcp/index.js
CHANGED
|
@@ -39548,6 +39548,9 @@ var TIER_PATTERNS = [
|
|
|
39548
39548
|
}
|
|
39549
39549
|
];
|
|
39550
39550
|
|
|
39551
|
+
// ../core/dist/integrations/pending-approval.js
|
|
39552
|
+
var PENDING_APPROVAL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
39553
|
+
|
|
39551
39554
|
// ../core/dist/integrations/augmented-live/markup.js
|
|
39552
39555
|
var MARKUP_MARKER = "__augmentedLiveMarkup";
|
|
39553
39556
|
var MARKUP_CONTROL_MARKER = "__augmentedLiveMarkupControl";
|
|
@@ -41013,7 +41016,7 @@ var INTEGRATION_REGISTRY = [
|
|
|
41013
41016
|
id: "firecrawl",
|
|
41014
41017
|
name: "Firecrawl",
|
|
41015
41018
|
category: "knowledge",
|
|
41016
|
-
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account
|
|
41019
|
+
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account.",
|
|
41017
41020
|
// ENG-7217: Firecrawl migrates from a customer-API-key stdio MCP
|
|
41018
41021
|
// (`npx firecrawl-mcp`, FIRECRAWL_API_KEY) to a PREMIUM, platform-managed
|
|
41019
41022
|
// integration on the Deck / ElevenLabs model (ADR-0031, epic ENG-6920):
|
|
@@ -41024,16 +41027,30 @@ var INTEGRATION_REGISTRY = [
|
|
|
41024
41027
|
// is metered at the one control-plane chokepoint and gated on a per-org opt-in
|
|
41025
41028
|
// + monthly USD cap.
|
|
41026
41029
|
//
|
|
41027
|
-
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
41028
|
-
//
|
|
41030
|
+
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
41031
|
+
// was also offered so a customer could bring their OWN Firecrawl key. A BYO
|
|
41029
41032
|
// install (`credential_source='byo'`) authenticates with the customer's key
|
|
41030
41033
|
// (stored encrypted on the install) and is NOT metered — its upstream cost is
|
|
41031
|
-
// on the customer's own Firecrawl bill.
|
|
41032
|
-
//
|
|
41033
|
-
// `api_key` is
|
|
41034
|
-
// `
|
|
41035
|
-
//
|
|
41036
|
-
|
|
41034
|
+
// on the customer's own Firecrawl bill.
|
|
41035
|
+
//
|
|
41036
|
+
// ENG-9235: `api_key` is PARKED, not abandoned. BYO is gated on the plan-tier
|
|
41037
|
+
// `byo_credentials` entitlement, which only `enterprise` has (the column is
|
|
41038
|
+
// NOT NULL DEFAULT false, and ENG-9143 explicitly set it false for Team). The
|
|
41039
|
+
// connect wizard never reads that flag, so offering `api_key` here sent every
|
|
41040
|
+
// Team/Business customer to firecrawl.dev for a key we would then reject with
|
|
41041
|
+
// a 403 `byo_not_entitled_by_plan` — after they had signed up for it.
|
|
41042
|
+
//
|
|
41043
|
+
// Removing it is also what removes that screen: the wizard's picker only
|
|
41044
|
+
// renders for 2+ selectable auth types (`selectableWizardAuthMethods`), so a
|
|
41045
|
+
// single `['none']` restores the friction-free managed install with no UI
|
|
41046
|
+
// change. Restore `api_key` only together with an entitlement-aware wizard —
|
|
41047
|
+
// see ENG-9236 for the proper fix.
|
|
41048
|
+
//
|
|
41049
|
+
// KEEP IN LOCKSTEP with the `firecrawl` row in
|
|
41050
|
+
// packages/supabase/seeds/toolkit-definitions.json: that seed carries its own
|
|
41051
|
+
// `auth_types` and is what `db:catalog:seed` upserts on every prod deploy, so
|
|
41052
|
+
// editing this array alone changes nothing a customer can see.
|
|
41053
|
+
supported_auth_types: ["none"],
|
|
41037
41054
|
capabilities: [
|
|
41038
41055
|
{ id: "firecrawl:scrape", name: "Scrape Pages", description: "Fetch a single URL as clean markdown / structured data (firecrawl_scrape).", access: "write" },
|
|
41039
41056
|
{ id: "firecrawl:search", name: "Web Search", description: "Search the web and return ranked results, optionally scraped (firecrawl_search).", access: "write" },
|
|
@@ -43244,18 +43261,33 @@ var FLAG_REGISTRY = [
|
|
|
43244
43261
|
},
|
|
43245
43262
|
{
|
|
43246
43263
|
key: "ninjafy-brand",
|
|
43247
|
-
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is USER-FACING BRAND
|
|
43264
|
+
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is the USER-FACING BRAND PRESENTATION \u2014 text AND VISUAL THEME. ENG-8858 widened this from text alone: the Ninjafy palette is gated here too, because a colour theme is not text. It stays ONE key rather than gaining a `ninjafy-theme` sibling, so a half-branded state \u2014 ninjafy wordmark over Augmented green \u2014 is unreachable and the rebrand keeps a single kill switch. It must never gate a code identifier, package name, env var or CLI name. EXISTING identifiers stay `Augmented`/`agt` per the CLAUDE.md naming contract, which protects them from premature renaming \u2014 the deep rename is workstream C of docs/runbooks/rebrand-ninjafy-migration.md and is out of scope here. That contract does NOT require NEW code to carry the old brand: artefacts created specifically for the rebrand take Ninjafy naming (ENG-8078 decision 9; see the CLAUDE.md rebrand carve-out). Either way it is a naming rule, not a flag concern \u2014 this key gates presentation, never an identifier. Set the stage-wide default to flip a whole environment, or add a feature_flag_overrides row to pilot a subset while everyone else still sees Augmented. Overrides resolve at FOUR grains, most specific first \u2014 agent, team, host, then org-wide (evaluate.ts:79-81); organization_id is always required, so there is no global override. Org and team are the useful pilot grains for THIS flag: there is now exactly ONE consumer \u2014 (dashboard)/layout.tsx via getPublicBooleanFlagServer \u2014 evaluating in the active-org cookie scope, so a host- or agent-scoped row is accepted by the table but never reached by the console. It resolves the key ONCE per request and passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop. Resolution is SERVER-side deliberately: the client hook starts at its default and updates after an async GET /flags, so anything gated on it paints Augmented and then repaints. ENG-8858 moved the PALETTE for that reason (a full-page colour flash); ENG-9227 moved the WORDMARK, which had been the last surface still swapping after hydration. A consequence worth knowing: /login and the marketing routes stay on the Augmented palette whatever an org sets, because getPublicBooleanFlagServer returns the default without a verified session and a pre-auth page has neither a session nor an active org \u2014 a PER-ORG flag structurally cannot brand one. Those surfaces follow only when the stage-wide default flips. Ships dark.',
|
|
43248
43265
|
flagType: "boolean",
|
|
43249
43266
|
// Declared safe value is `false`: the pre-rebrand brand. `false` is also the
|
|
43250
43267
|
// fail-closed direction — if the flag DB is unreachable we must show the brand
|
|
43251
43268
|
// that is currently live and contractually correct, never leak an unannounced
|
|
43252
43269
|
// rebrand to every customer at once.
|
|
43253
43270
|
defaultValue: false,
|
|
43254
|
-
//
|
|
43255
|
-
//
|
|
43256
|
-
//
|
|
43257
|
-
//
|
|
43258
|
-
//
|
|
43271
|
+
// ENG-9227: there are NO client readers of this key left. (dashboard)/
|
|
43272
|
+
// layout.tsx resolves it ONCE server-side via getPublicBooleanFlagServer and
|
|
43273
|
+
// passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop.
|
|
43274
|
+
// ENG-8858 did that for the THEME; ENG-9227 finished the job for the
|
|
43275
|
+
// WORDMARK, which had kept usePublicBooleanFlag and so kept swapping
|
|
43276
|
+
// "augmented.team" to "ninjafy" after hydration.
|
|
43277
|
+
//
|
|
43278
|
+
// `public` MUST STAY ANYWAY, and this is the trap. It is tempting to read
|
|
43279
|
+
// "no client readers" as "no longer needs to be public" — but
|
|
43280
|
+
// getPublicBooleanFlagServer resolves against the very same `GET /flags`
|
|
43281
|
+
// endpoint the browser uses, and that route filters to listPublicFlagKeys()
|
|
43282
|
+
// (routes/flags.ts:72-75). A non-public key is simply absent from the map,
|
|
43283
|
+
// so the server helper would fall through to its default and return `false`
|
|
43284
|
+
// FOREVER — the brand quietly reverting to Augmented for every org, with no
|
|
43285
|
+
// error anywhere. `public` here means "readable through the public map",
|
|
43286
|
+
// not "read by a browser".
|
|
43287
|
+
//
|
|
43288
|
+
// Unlike onboarding-msteams-channel above there is no wrong-org hazard — the
|
|
43289
|
+
// single reader evaluates inside the active-org cookie's scope, which is
|
|
43290
|
+
// exactly the org whose brand should be shown.
|
|
43259
43291
|
public: true
|
|
43260
43292
|
},
|
|
43261
43293
|
{
|
package/dist/mcp/origami.js
CHANGED
|
@@ -38429,6 +38429,9 @@ var TIER_PATTERNS = [
|
|
|
38429
38429
|
}
|
|
38430
38430
|
];
|
|
38431
38431
|
|
|
38432
|
+
// ../core/dist/integrations/pending-approval.js
|
|
38433
|
+
var PENDING_APPROVAL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
38434
|
+
|
|
38432
38435
|
// ../core/dist/integrations/augmented-live/markup.js
|
|
38433
38436
|
var MARKUP_MARKER = "__augmentedLiveMarkup";
|
|
38434
38437
|
var MARKUP_CONTROL_MARKER = "__augmentedLiveMarkupControl";
|
|
@@ -39894,7 +39897,7 @@ var INTEGRATION_REGISTRY = [
|
|
|
39894
39897
|
id: "firecrawl",
|
|
39895
39898
|
name: "Firecrawl",
|
|
39896
39899
|
category: "knowledge",
|
|
39897
|
-
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account
|
|
39900
|
+
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account.",
|
|
39898
39901
|
// ENG-7217: Firecrawl migrates from a customer-API-key stdio MCP
|
|
39899
39902
|
// (`npx firecrawl-mcp`, FIRECRAWL_API_KEY) to a PREMIUM, platform-managed
|
|
39900
39903
|
// integration on the Deck / ElevenLabs model (ADR-0031, epic ENG-6920):
|
|
@@ -39905,16 +39908,30 @@ var INTEGRATION_REGISTRY = [
|
|
|
39905
39908
|
// is metered at the one control-plane chokepoint and gated on a per-org opt-in
|
|
39906
39909
|
// + monthly USD cap.
|
|
39907
39910
|
//
|
|
39908
|
-
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
39909
|
-
//
|
|
39911
|
+
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
39912
|
+
// was also offered so a customer could bring their OWN Firecrawl key. A BYO
|
|
39910
39913
|
// install (`credential_source='byo'`) authenticates with the customer's key
|
|
39911
39914
|
// (stored encrypted on the install) and is NOT metered — its upstream cost is
|
|
39912
|
-
// on the customer's own Firecrawl bill.
|
|
39913
|
-
//
|
|
39914
|
-
// `api_key` is
|
|
39915
|
-
// `
|
|
39916
|
-
//
|
|
39917
|
-
|
|
39915
|
+
// on the customer's own Firecrawl bill.
|
|
39916
|
+
//
|
|
39917
|
+
// ENG-9235: `api_key` is PARKED, not abandoned. BYO is gated on the plan-tier
|
|
39918
|
+
// `byo_credentials` entitlement, which only `enterprise` has (the column is
|
|
39919
|
+
// NOT NULL DEFAULT false, and ENG-9143 explicitly set it false for Team). The
|
|
39920
|
+
// connect wizard never reads that flag, so offering `api_key` here sent every
|
|
39921
|
+
// Team/Business customer to firecrawl.dev for a key we would then reject with
|
|
39922
|
+
// a 403 `byo_not_entitled_by_plan` — after they had signed up for it.
|
|
39923
|
+
//
|
|
39924
|
+
// Removing it is also what removes that screen: the wizard's picker only
|
|
39925
|
+
// renders for 2+ selectable auth types (`selectableWizardAuthMethods`), so a
|
|
39926
|
+
// single `['none']` restores the friction-free managed install with no UI
|
|
39927
|
+
// change. Restore `api_key` only together with an entitlement-aware wizard —
|
|
39928
|
+
// see ENG-9236 for the proper fix.
|
|
39929
|
+
//
|
|
39930
|
+
// KEEP IN LOCKSTEP with the `firecrawl` row in
|
|
39931
|
+
// packages/supabase/seeds/toolkit-definitions.json: that seed carries its own
|
|
39932
|
+
// `auth_types` and is what `db:catalog:seed` upserts on every prod deploy, so
|
|
39933
|
+
// editing this array alone changes nothing a customer can see.
|
|
39934
|
+
supported_auth_types: ["none"],
|
|
39918
39935
|
capabilities: [
|
|
39919
39936
|
{ id: "firecrawl:scrape", name: "Scrape Pages", description: "Fetch a single URL as clean markdown / structured data (firecrawl_scrape).", access: "write" },
|
|
39920
39937
|
{ id: "firecrawl:search", name: "Web Search", description: "Search the web and return ranked results, optionally scraped (firecrawl_search).", access: "write" },
|
|
@@ -42104,18 +42121,33 @@ var FLAG_REGISTRY = [
|
|
|
42104
42121
|
},
|
|
42105
42122
|
{
|
|
42106
42123
|
key: "ninjafy-brand",
|
|
42107
|
-
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is USER-FACING BRAND
|
|
42124
|
+
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is the USER-FACING BRAND PRESENTATION \u2014 text AND VISUAL THEME. ENG-8858 widened this from text alone: the Ninjafy palette is gated here too, because a colour theme is not text. It stays ONE key rather than gaining a `ninjafy-theme` sibling, so a half-branded state \u2014 ninjafy wordmark over Augmented green \u2014 is unreachable and the rebrand keeps a single kill switch. It must never gate a code identifier, package name, env var or CLI name. EXISTING identifiers stay `Augmented`/`agt` per the CLAUDE.md naming contract, which protects them from premature renaming \u2014 the deep rename is workstream C of docs/runbooks/rebrand-ninjafy-migration.md and is out of scope here. That contract does NOT require NEW code to carry the old brand: artefacts created specifically for the rebrand take Ninjafy naming (ENG-8078 decision 9; see the CLAUDE.md rebrand carve-out). Either way it is a naming rule, not a flag concern \u2014 this key gates presentation, never an identifier. Set the stage-wide default to flip a whole environment, or add a feature_flag_overrides row to pilot a subset while everyone else still sees Augmented. Overrides resolve at FOUR grains, most specific first \u2014 agent, team, host, then org-wide (evaluate.ts:79-81); organization_id is always required, so there is no global override. Org and team are the useful pilot grains for THIS flag: there is now exactly ONE consumer \u2014 (dashboard)/layout.tsx via getPublicBooleanFlagServer \u2014 evaluating in the active-org cookie scope, so a host- or agent-scoped row is accepted by the table but never reached by the console. It resolves the key ONCE per request and passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop. Resolution is SERVER-side deliberately: the client hook starts at its default and updates after an async GET /flags, so anything gated on it paints Augmented and then repaints. ENG-8858 moved the PALETTE for that reason (a full-page colour flash); ENG-9227 moved the WORDMARK, which had been the last surface still swapping after hydration. A consequence worth knowing: /login and the marketing routes stay on the Augmented palette whatever an org sets, because getPublicBooleanFlagServer returns the default without a verified session and a pre-auth page has neither a session nor an active org \u2014 a PER-ORG flag structurally cannot brand one. Those surfaces follow only when the stage-wide default flips. Ships dark.',
|
|
42108
42125
|
flagType: "boolean",
|
|
42109
42126
|
// Declared safe value is `false`: the pre-rebrand brand. `false` is also the
|
|
42110
42127
|
// fail-closed direction — if the flag DB is unreachable we must show the brand
|
|
42111
42128
|
// that is currently live and contractually correct, never leak an unannounced
|
|
42112
42129
|
// rebrand to every customer at once.
|
|
42113
42130
|
defaultValue: false,
|
|
42114
|
-
//
|
|
42115
|
-
//
|
|
42116
|
-
//
|
|
42117
|
-
//
|
|
42118
|
-
//
|
|
42131
|
+
// ENG-9227: there are NO client readers of this key left. (dashboard)/
|
|
42132
|
+
// layout.tsx resolves it ONCE server-side via getPublicBooleanFlagServer and
|
|
42133
|
+
// passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop.
|
|
42134
|
+
// ENG-8858 did that for the THEME; ENG-9227 finished the job for the
|
|
42135
|
+
// WORDMARK, which had kept usePublicBooleanFlag and so kept swapping
|
|
42136
|
+
// "augmented.team" to "ninjafy" after hydration.
|
|
42137
|
+
//
|
|
42138
|
+
// `public` MUST STAY ANYWAY, and this is the trap. It is tempting to read
|
|
42139
|
+
// "no client readers" as "no longer needs to be public" — but
|
|
42140
|
+
// getPublicBooleanFlagServer resolves against the very same `GET /flags`
|
|
42141
|
+
// endpoint the browser uses, and that route filters to listPublicFlagKeys()
|
|
42142
|
+
// (routes/flags.ts:72-75). A non-public key is simply absent from the map,
|
|
42143
|
+
// so the server helper would fall through to its default and return `false`
|
|
42144
|
+
// FOREVER — the brand quietly reverting to Augmented for every org, with no
|
|
42145
|
+
// error anywhere. `public` here means "readable through the public map",
|
|
42146
|
+
// not "read by a browser".
|
|
42147
|
+
//
|
|
42148
|
+
// Unlike onboarding-msteams-channel above there is no wrong-org hazard — the
|
|
42149
|
+
// single reader evaluates inside the active-org cookie's scope, which is
|
|
42150
|
+
// exactly the org whose brand should be shown.
|
|
42119
42151
|
public: true
|
|
42120
42152
|
},
|
|
42121
42153
|
{
|
|
@@ -32489,6 +32489,9 @@ var TIER_PATTERNS = [
|
|
|
32489
32489
|
}
|
|
32490
32490
|
];
|
|
32491
32491
|
|
|
32492
|
+
// ../core/dist/integrations/pending-approval.js
|
|
32493
|
+
var PENDING_APPROVAL_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
32494
|
+
|
|
32492
32495
|
// ../core/dist/integrations/augmented-live/markup.js
|
|
32493
32496
|
var MARKUP_MARKER = "__augmentedLiveMarkup";
|
|
32494
32497
|
var MARKUP_CONTROL_MARKER = "__augmentedLiveMarkupControl";
|
|
@@ -33960,7 +33963,7 @@ var INTEGRATION_REGISTRY = [
|
|
|
33960
33963
|
id: "firecrawl",
|
|
33961
33964
|
name: "Firecrawl",
|
|
33962
33965
|
category: "knowledge",
|
|
33963
|
-
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account
|
|
33966
|
+
description: "Web data for agents: scrape, map, crawl and search any website for clean structured data, plus scheduled change-detection monitors whose updates arrive in the agent's direct-chat. Connect via the platform-managed account.",
|
|
33964
33967
|
// ENG-7217: Firecrawl migrates from a customer-API-key stdio MCP
|
|
33965
33968
|
// (`npx firecrawl-mcp`, FIRECRAWL_API_KEY) to a PREMIUM, platform-managed
|
|
33966
33969
|
// integration on the Deck / ElevenLabs model (ADR-0031, epic ENG-6920):
|
|
@@ -33971,16 +33974,30 @@ var INTEGRATION_REGISTRY = [
|
|
|
33971
33974
|
// is metered at the one control-plane chokepoint and gated on a per-org opt-in
|
|
33972
33975
|
// + monthly USD cap.
|
|
33973
33976
|
//
|
|
33974
|
-
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
33975
|
-
//
|
|
33977
|
+
// ENG-8304 / ADR-0055 (Phase 1b — Firecrawl is the BYO exemplar): `api_key`
|
|
33978
|
+
// was also offered so a customer could bring their OWN Firecrawl key. A BYO
|
|
33976
33979
|
// install (`credential_source='byo'`) authenticates with the customer's key
|
|
33977
33980
|
// (stored encrypted on the install) and is NOT metered — its upstream cost is
|
|
33978
|
-
// on the customer's own Firecrawl bill.
|
|
33979
|
-
//
|
|
33980
|
-
// `api_key` is
|
|
33981
|
-
// `
|
|
33982
|
-
//
|
|
33983
|
-
|
|
33981
|
+
// on the customer's own Firecrawl bill.
|
|
33982
|
+
//
|
|
33983
|
+
// ENG-9235: `api_key` is PARKED, not abandoned. BYO is gated on the plan-tier
|
|
33984
|
+
// `byo_credentials` entitlement, which only `enterprise` has (the column is
|
|
33985
|
+
// NOT NULL DEFAULT false, and ENG-9143 explicitly set it false for Team). The
|
|
33986
|
+
// connect wizard never reads that flag, so offering `api_key` here sent every
|
|
33987
|
+
// Team/Business customer to firecrawl.dev for a key we would then reject with
|
|
33988
|
+
// a 403 `byo_not_entitled_by_plan` — after they had signed up for it.
|
|
33989
|
+
//
|
|
33990
|
+
// Removing it is also what removes that screen: the wizard's picker only
|
|
33991
|
+
// renders for 2+ selectable auth types (`selectableWizardAuthMethods`), so a
|
|
33992
|
+
// single `['none']` restores the friction-free managed install with no UI
|
|
33993
|
+
// change. Restore `api_key` only together with an entitlement-aware wizard —
|
|
33994
|
+
// see ENG-9236 for the proper fix.
|
|
33995
|
+
//
|
|
33996
|
+
// KEEP IN LOCKSTEP with the `firecrawl` row in
|
|
33997
|
+
// packages/supabase/seeds/toolkit-definitions.json: that seed carries its own
|
|
33998
|
+
// `auth_types` and is what `db:catalog:seed` upserts on every prod deploy, so
|
|
33999
|
+
// editing this array alone changes nothing a customer can see.
|
|
34000
|
+
supported_auth_types: ["none"],
|
|
33984
34001
|
capabilities: [
|
|
33985
34002
|
{ id: "firecrawl:scrape", name: "Scrape Pages", description: "Fetch a single URL as clean markdown / structured data (firecrawl_scrape).", access: "write" },
|
|
33986
34003
|
{ id: "firecrawl:search", name: "Web Search", description: "Search the web and return ranked results, optionally scraped (firecrawl_search).", access: "write" },
|
|
@@ -36587,18 +36604,33 @@ var FLAG_REGISTRY = [
|
|
|
36587
36604
|
},
|
|
36588
36605
|
{
|
|
36589
36606
|
key: "ninjafy-brand",
|
|
36590
|
-
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is USER-FACING BRAND
|
|
36607
|
+
description: 'Present the product under the Ninjafy brand instead of Augmented Team (ENG-8250). This is the UMBRELLA brand gate, not a one-off nav toggle: every subsequent rebrand surface (page titles, email templates, marketing-facing copy) reads THIS key rather than adding its own flag, so the whole rebrand keeps a single kill switch. First surface is the left-hand nav wordmark \u2014 ON replaces the human+robot mark and the "augmented.team" text with italic lowercase "ninjafy"; OFF renders exactly what shipped before. Scope is the USER-FACING BRAND PRESENTATION \u2014 text AND VISUAL THEME. ENG-8858 widened this from text alone: the Ninjafy palette is gated here too, because a colour theme is not text. It stays ONE key rather than gaining a `ninjafy-theme` sibling, so a half-branded state \u2014 ninjafy wordmark over Augmented green \u2014 is unreachable and the rebrand keeps a single kill switch. It must never gate a code identifier, package name, env var or CLI name. EXISTING identifiers stay `Augmented`/`agt` per the CLAUDE.md naming contract, which protects them from premature renaming \u2014 the deep rename is workstream C of docs/runbooks/rebrand-ninjafy-migration.md and is out of scope here. That contract does NOT require NEW code to carry the old brand: artefacts created specifically for the rebrand take Ninjafy naming (ENG-8078 decision 9; see the CLAUDE.md rebrand carve-out). Either way it is a naming rule, not a flag concern \u2014 this key gates presentation, never an identifier. Set the stage-wide default to flip a whole environment, or add a feature_flag_overrides row to pilot a subset while everyone else still sees Augmented. Overrides resolve at FOUR grains, most specific first \u2014 agent, team, host, then org-wide (evaluate.ts:79-81); organization_id is always required, so there is no global override. Org and team are the useful pilot grains for THIS flag: there is now exactly ONE consumer \u2014 (dashboard)/layout.tsx via getPublicBooleanFlagServer \u2014 evaluating in the active-org cookie scope, so a host- or agent-scoped row is accepted by the table but never reached by the console. It resolves the key ONCE per request and passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop. Resolution is SERVER-side deliberately: the client hook starts at its default and updates after an async GET /flags, so anything gated on it paints Augmented and then repaints. ENG-8858 moved the PALETTE for that reason (a full-page colour flash); ENG-9227 moved the WORDMARK, which had been the last surface still swapping after hydration. A consequence worth knowing: /login and the marketing routes stay on the Augmented palette whatever an org sets, because getPublicBooleanFlagServer returns the default without a verified session and a pre-auth page has neither a session nor an active org \u2014 a PER-ORG flag structurally cannot brand one. Those surfaces follow only when the stage-wide default flips. Ships dark.',
|
|
36591
36608
|
flagType: "boolean",
|
|
36592
36609
|
// Declared safe value is `false`: the pre-rebrand brand. `false` is also the
|
|
36593
36610
|
// fail-closed direction — if the flag DB is unreachable we must show the brand
|
|
36594
36611
|
// that is currently live and contractually correct, never leak an unannounced
|
|
36595
36612
|
// rebrand to every customer at once.
|
|
36596
36613
|
defaultValue: false,
|
|
36597
|
-
//
|
|
36598
|
-
//
|
|
36599
|
-
//
|
|
36600
|
-
//
|
|
36601
|
-
//
|
|
36614
|
+
// ENG-9227: there are NO client readers of this key left. (dashboard)/
|
|
36615
|
+
// layout.tsx resolves it ONCE server-side via getPublicBooleanFlagServer and
|
|
36616
|
+
// passes the boolean down to sidebar.tsx and top-nav.tsx as a required prop.
|
|
36617
|
+
// ENG-8858 did that for the THEME; ENG-9227 finished the job for the
|
|
36618
|
+
// WORDMARK, which had kept usePublicBooleanFlag and so kept swapping
|
|
36619
|
+
// "augmented.team" to "ninjafy" after hydration.
|
|
36620
|
+
//
|
|
36621
|
+
// `public` MUST STAY ANYWAY, and this is the trap. It is tempting to read
|
|
36622
|
+
// "no client readers" as "no longer needs to be public" — but
|
|
36623
|
+
// getPublicBooleanFlagServer resolves against the very same `GET /flags`
|
|
36624
|
+
// endpoint the browser uses, and that route filters to listPublicFlagKeys()
|
|
36625
|
+
// (routes/flags.ts:72-75). A non-public key is simply absent from the map,
|
|
36626
|
+
// so the server helper would fall through to its default and return `false`
|
|
36627
|
+
// FOREVER — the brand quietly reverting to Augmented for every org, with no
|
|
36628
|
+
// error anywhere. `public` here means "readable through the public map",
|
|
36629
|
+
// not "read by a browser".
|
|
36630
|
+
//
|
|
36631
|
+
// Unlike onboarding-msteams-channel above there is no wrong-org hazard — the
|
|
36632
|
+
// single reader evaluates inside the active-org cookie's scope, which is
|
|
36633
|
+
// exactly the org whose brand should be shown.
|
|
36602
36634
|
public: true
|
|
36603
36635
|
},
|
|
36604
36636
|
{
|