@native-marketing/sdk 0.3.5 → 0.3.7
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/http.js +270 -25
- package/dist/index.js +909 -57
- package/package.json +11 -1
- package/release.json +3 -3
- package/types/contracts/client-lifecycle.d.ts +55 -0
- package/types/contracts/client-update-policy.d.ts +84 -0
- package/types/contracts/generated/client-release.d.ts +14 -0
- package/types/contracts/human-knowledge.d.ts +2 -0
- package/types/contracts/index.d.ts +3 -0
- package/types/contracts/knowledge-discovery.d.ts +11 -1
- package/types/contracts/knowledge-reference-repair.d.ts +108 -0
- package/types/http/client-version.d.ts +35 -0
- package/types/http/client.d.ts +1 -0
- package/types/http/generated/schema.d.ts +643 -0
- package/types/http/index.d.ts +2 -0
- package/types/sdk/capability-definition.d.ts +1 -0
- package/types/sdk/cli/run.d.ts +1 -0
- package/types/sdk/client.d.ts +5 -0
- package/types/sdk/index.d.ts +3 -0
- package/types/sdk/transport.d.ts +6 -1
- package/types/sdk/updates/commands.d.ts +11 -0
- package/types/sdk/updates/install.d.ts +20 -0
- package/types/sdk/updates/registry.d.ts +26 -0
- package/types/sdk/updates/store.d.ts +14 -0
- package/types/sdk/updates/version.d.ts +93 -0
package/dist/index.js
CHANGED
|
@@ -5922,7 +5922,8 @@ var knowledgeDiscoveryDescriptionSchema = z79.object({
|
|
|
5922
5922
|
checkedAt: z79.string().datetime()
|
|
5923
5923
|
}).strict();
|
|
5924
5924
|
var knowledgeAdoptionCommandSchema = knowledgeDiscoveryReadQuerySchema.required().extend({
|
|
5925
|
-
requestId: z79.string().min(1).max(128)
|
|
5925
|
+
requestId: z79.string().min(1).max(128),
|
|
5926
|
+
ref: knowledgeRemoteRefSchema.max(2048)
|
|
5926
5927
|
}).strict();
|
|
5927
5928
|
var knowledgeAdoptionResultSchema = z79.object({ result: sourceRefSchema, replayed: z79.boolean() }).strict();
|
|
5928
5929
|
var knowledgeAdoptionReceiptQuerySchema = z79.object({ requestId: z79.string().min(1).max(128) }).strict();
|
|
@@ -5938,6 +5939,15 @@ var adoptedKnowledgeResourceSchema = z79.object({
|
|
|
5938
5939
|
ref: knowledgeRemoteRefSchema,
|
|
5939
5940
|
identityHash: z79.string().regex(/^sha256:[a-f0-9]{64}$/)
|
|
5940
5941
|
}).strict();
|
|
5942
|
+
var knowledgeResourceDescriptorSchema = knowledgeDiscoveryItemSchema.pick({
|
|
5943
|
+
ref: true,
|
|
5944
|
+
identityHash: true,
|
|
5945
|
+
ownerTenantId: true,
|
|
5946
|
+
resourceType: true,
|
|
5947
|
+
kind: true,
|
|
5948
|
+
classification: true,
|
|
5949
|
+
title: true
|
|
5950
|
+
}).extend({ schemaVersion: z79.literal(1) }).strict();
|
|
5941
5951
|
|
|
5942
5952
|
// packages/contracts/src/material-verification.ts
|
|
5943
5953
|
import { z as z80 } from "zod";
|
|
@@ -6924,7 +6934,21 @@ var surveyRejections = [
|
|
|
6924
6934
|
"PERSONAL_SURVEY_DRAFT_TRANSITION_IMMUTABLE"
|
|
6925
6935
|
];
|
|
6926
6936
|
function isKnownCapabilityRejection(code2, name) {
|
|
6927
|
-
return capabilityRejectedErrorCodes.includes(code2) || name === "
|
|
6937
|
+
return capabilityRejectedErrorCodes.includes(code2) || name === "cf_repair_knowledge_reference" && [
|
|
6938
|
+
"KNOWLEDGE_REFERENCE_REPAIR_CONFLICT",
|
|
6939
|
+
"KNOWLEDGE_REFERENCE_REPAIR_NOT_SUPPORTED",
|
|
6940
|
+
"KNOWLEDGE_REFERENCE_REPAIR_IDENTITY_MISMATCH",
|
|
6941
|
+
"KNOWLEDGE_DISCOVERY_IDENTITY_CHANGED",
|
|
6942
|
+
"KNOWLEDGE_DISCOVERY_FORBIDDEN",
|
|
6943
|
+
"KNOWLEDGE_DISCOVERY_UNAVAILABLE",
|
|
6944
|
+
"KNOWLEDGE_CATALOG_UNAVAILABLE",
|
|
6945
|
+
"KNOWLEDGE_TENANT_IDENTITY_CHANGED",
|
|
6946
|
+
"KNOWLEDGE_CATALOG_SCOPE_NOT_CONFIGURED",
|
|
6947
|
+
"KNOWLEDGE_PROVIDER_AUTH_REQUIRED",
|
|
6948
|
+
"KNOWLEDGE_ARTIFACT_ACCESS_DENIED",
|
|
6949
|
+
"KNOWLEDGE_ARTIFACT_TOO_LARGE",
|
|
6950
|
+
"KNOWLEDGE_ARTIFACT_DOWNLOAD_BUSY"
|
|
6951
|
+
].includes(code2) || name === "cf_adopt_discovered_knowledge" && [
|
|
6928
6952
|
"KNOWLEDGE_DISCOVERY_IDENTITY_CHANGED",
|
|
6929
6953
|
"KNOWLEDGE_DISCOVERY_FORBIDDEN",
|
|
6930
6954
|
"KNOWLEDGE_DISCOVERY_TEXT_TOO_LARGE",
|
|
@@ -7261,6 +7285,26 @@ var eventExchangePageSchema = z101.object({
|
|
|
7261
7285
|
nextAfter: z101.string().max(256).nullable()
|
|
7262
7286
|
}).strict();
|
|
7263
7287
|
|
|
7288
|
+
// packages/contracts/src/knowledge-reference-repair.ts
|
|
7289
|
+
import { z as z102 } from "zod";
|
|
7290
|
+
var knowledgeReferenceRepairQuerySchema = z102.object({
|
|
7291
|
+
sourceRef: stableRefSchema.refine((value) => value.startsWith("cf://source/"))
|
|
7292
|
+
}).strict();
|
|
7293
|
+
var knowledgeReferenceRepairPreviewSchema = z102.object({
|
|
7294
|
+
sourceRef: knowledgeReferenceRepairQuerySchema.shape.sourceRef,
|
|
7295
|
+
remoteRef: z102.string().min(1).max(2048),
|
|
7296
|
+
basisHash: z102.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
7297
|
+
sourceTenantId: z102.string().min(1).max(256),
|
|
7298
|
+
item: knowledgeDiscoveryItemSchema,
|
|
7299
|
+
byteLength: z102.number().int().nonnegative().safe(),
|
|
7300
|
+
verified: z102.literal(true)
|
|
7301
|
+
}).strict();
|
|
7302
|
+
var knowledgeReferenceRepairCommandSchema = knowledgeReferenceRepairQuerySchema.extend({
|
|
7303
|
+
requestId: z102.string().min(1).max(128),
|
|
7304
|
+
expectedBasisHash: knowledgeReferenceRepairPreviewSchema.shape.basisHash
|
|
7305
|
+
}).strict();
|
|
7306
|
+
var knowledgeReferenceRepairReceiptQuerySchema = knowledgeAdoptionReceiptQuerySchema;
|
|
7307
|
+
|
|
7264
7308
|
// packages/contracts/src/agent/capability-receipts.ts
|
|
7265
7309
|
var rule = (capability, schema2, operation, keys = [], field) => ({ capability, schema: schema2, operation, keys, field });
|
|
7266
7310
|
var foundation = (operation, field) => rule(
|
|
@@ -7282,6 +7326,10 @@ var execution = (family, operation) => ({
|
|
|
7282
7326
|
});
|
|
7283
7327
|
var learning = (op) => rule("cf_get_learning_command_receipt", learningReceiptSchema, op);
|
|
7284
7328
|
var rules = {
|
|
7329
|
+
cf_repair_knowledge_reference: rule(
|
|
7330
|
+
"cf_get_knowledge_reference_repair_receipt",
|
|
7331
|
+
knowledgeReferenceRepairReceiptQuerySchema
|
|
7332
|
+
),
|
|
7285
7333
|
cf_configure_event_exchange: rule(
|
|
7286
7334
|
"cf_get_event_exchange_receipt",
|
|
7287
7335
|
eventExchangeReceiptQuerySchema
|
|
@@ -7505,7 +7553,7 @@ function capabilityReceiptRead(name, input) {
|
|
|
7505
7553
|
}
|
|
7506
7554
|
|
|
7507
7555
|
// packages/contracts/src/agent/capability-status.ts
|
|
7508
|
-
import { z as
|
|
7556
|
+
import { z as z103 } from "zod";
|
|
7509
7557
|
var verification = {
|
|
7510
7558
|
capability: "cf_material_verification_status",
|
|
7511
7559
|
schema: materialVerificationIdSchema,
|
|
@@ -7523,7 +7571,7 @@ var rules2 = {
|
|
|
7523
7571
|
},
|
|
7524
7572
|
cf_tenant_material_scan_advance: {
|
|
7525
7573
|
capability: "cf_tenant_material_scan_status",
|
|
7526
|
-
schema:
|
|
7574
|
+
schema: z103.object({}).strict()
|
|
7527
7575
|
},
|
|
7528
7576
|
cf_sync_materials: {
|
|
7529
7577
|
capability: "cf_reconcile_materials",
|
|
@@ -7550,6 +7598,176 @@ function capabilityStatusRead(name, input) {
|
|
|
7550
7598
|
};
|
|
7551
7599
|
}
|
|
7552
7600
|
|
|
7601
|
+
// packages/contracts/src/client-lifecycle.ts
|
|
7602
|
+
import { z as z104 } from "zod";
|
|
7603
|
+
|
|
7604
|
+
// packages/contracts/src/generated/client-release.ts
|
|
7605
|
+
var nativeClientRelease = {
|
|
7606
|
+
schemaVersion: 1,
|
|
7607
|
+
product: "native-marketing",
|
|
7608
|
+
version: "0.3.7",
|
|
7609
|
+
packages: {
|
|
7610
|
+
sdk: "@native-marketing/sdk",
|
|
7611
|
+
cli: "@native-marketing/cli"
|
|
7612
|
+
},
|
|
7613
|
+
contractVersion: 1,
|
|
7614
|
+
minimumClientVersion: "0.3.6",
|
|
7615
|
+
apiMajor: 1,
|
|
7616
|
+
nodeMajor: 24,
|
|
7617
|
+
changes: [
|
|
7618
|
+
"Unified SDK, CLI and MCP release discovery and compatibility checks.",
|
|
7619
|
+
"Configurable CLI update notifications, pins and compatible automatic updates.",
|
|
7620
|
+
"Upgrade verification and explicit continuation without replaying business commands."
|
|
7621
|
+
]
|
|
7622
|
+
};
|
|
7623
|
+
|
|
7624
|
+
// packages/contracts/src/client-lifecycle.ts
|
|
7625
|
+
var nativeReleaseCapability = "com.native-marketing/client-release";
|
|
7626
|
+
var releaseVersionSchema = z104.string().max(128).regex(
|
|
7627
|
+
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/
|
|
7628
|
+
);
|
|
7629
|
+
var clientIdentitySchema = z104.object({
|
|
7630
|
+
version: releaseVersionSchema,
|
|
7631
|
+
contractVersion: z104.number().int().positive(),
|
|
7632
|
+
apiMajor: z104.number().int().positive()
|
|
7633
|
+
});
|
|
7634
|
+
var clientReleaseSchema = z104.object({
|
|
7635
|
+
schemaVersion: z104.literal(1),
|
|
7636
|
+
product: z104.literal("native-marketing"),
|
|
7637
|
+
version: releaseVersionSchema,
|
|
7638
|
+
packages: z104.object({
|
|
7639
|
+
sdk: z104.literal("@native-marketing/sdk"),
|
|
7640
|
+
cli: z104.literal("@native-marketing/cli")
|
|
7641
|
+
}),
|
|
7642
|
+
contractVersion: z104.number().int().positive(),
|
|
7643
|
+
minimumClientVersion: releaseVersionSchema,
|
|
7644
|
+
apiMajor: z104.number().int().positive(),
|
|
7645
|
+
nodeMajor: z104.number().int().positive(),
|
|
7646
|
+
changes: z104.array(z104.string().min(1).max(240)).max(8).default([])
|
|
7647
|
+
});
|
|
7648
|
+
var updatePolicySchema = z104.object({
|
|
7649
|
+
mode: z104.enum(["off", "notify", "auto"]).default("notify"),
|
|
7650
|
+
channel: z104.enum(["latest", "next", "beta"]).default("latest"),
|
|
7651
|
+
pin: releaseVersionSchema.nullable().default(null),
|
|
7652
|
+
intervalHours: z104.number().int().min(1).max(168).default(24)
|
|
7653
|
+
}).strict();
|
|
7654
|
+
var defaultUpdatePolicy = updatePolicySchema.parse({});
|
|
7655
|
+
function compareReleaseVersions(left, right) {
|
|
7656
|
+
const parse = (raw) => releaseVersionSchema.parse(raw).split("+")[0].split(/-(.*)/s);
|
|
7657
|
+
const a = parse(left), b = parse(right);
|
|
7658
|
+
const numbers = (x, y) => BigInt(x) < BigInt(y) ? -1 : BigInt(x) > BigInt(y) ? 1 : 0;
|
|
7659
|
+
const ac = a[0].split("."), bc = b[0].split(".");
|
|
7660
|
+
for (let i = 0; i < 3; i++) {
|
|
7661
|
+
const order = numbers(ac[i], bc[i]);
|
|
7662
|
+
if (order) return order;
|
|
7663
|
+
}
|
|
7664
|
+
if (a[1] === b[1]) return 0;
|
|
7665
|
+
if (!a[1] || !b[1]) return a[1] ? -1 : 1;
|
|
7666
|
+
const ap = a[1].split("."), bp = b[1].split(".");
|
|
7667
|
+
for (let i = 0; i < Math.max(ap.length, bp.length); i++) {
|
|
7668
|
+
const x = ap[i], y = bp[i];
|
|
7669
|
+
if (x === void 0 || y === void 0) return x === void 0 ? -1 : 1;
|
|
7670
|
+
if (x === y) continue;
|
|
7671
|
+
const xn = /^\d+$/.test(x), yn = /^\d+$/.test(y);
|
|
7672
|
+
return xn && yn ? numbers(x, y) : xn !== yn ? xn ? -1 : 1 : x < y ? -1 : 1;
|
|
7673
|
+
}
|
|
7674
|
+
return 0;
|
|
7675
|
+
}
|
|
7676
|
+
function assessNativeCompatibility(client, server) {
|
|
7677
|
+
client = clientIdentitySchema.parse(client);
|
|
7678
|
+
const result2 = (status, reason) => ({ status, reason, client, server: server ?? null });
|
|
7679
|
+
if (!server) return result2("UNKNOWN", "SERVER_METADATA_UNAVAILABLE");
|
|
7680
|
+
server = clientReleaseSchema.parse(server);
|
|
7681
|
+
if (client.contractVersion !== server.contractVersion)
|
|
7682
|
+
return result2("INCOMPATIBLE", "CONTRACT_MISMATCH");
|
|
7683
|
+
if (client.apiMajor !== server.apiMajor) return result2("INCOMPATIBLE", "API_MISMATCH");
|
|
7684
|
+
if (compareReleaseVersions(client.version, server.minimumClientVersion) < 0)
|
|
7685
|
+
return result2("INCOMPATIBLE", "CLIENT_TOO_OLD");
|
|
7686
|
+
return compareReleaseVersions(client.version, server.version) < 0 ? result2("UPGRADE_RECOMMENDED", "NEWER_CLIENT_AVAILABLE") : result2("COMPATIBLE", "CURRENT");
|
|
7687
|
+
}
|
|
7688
|
+
|
|
7689
|
+
// packages/contracts/src/client-update-policy.ts
|
|
7690
|
+
import { z as z105 } from "zod";
|
|
7691
|
+
var registryReleaseSchema = z105.object({
|
|
7692
|
+
name: z105.enum(["@native-marketing/sdk", "@native-marketing/cli"]),
|
|
7693
|
+
version: releaseVersionSchema,
|
|
7694
|
+
deprecated: z105.string().optional(),
|
|
7695
|
+
nativeMarketing: z105.object({
|
|
7696
|
+
contractVersion: z105.number().int().positive(),
|
|
7697
|
+
apiMajor: z105.number().int().positive(),
|
|
7698
|
+
nodeMajor: z105.number().int().positive(),
|
|
7699
|
+
changes: z105.array(z105.string().min(1).max(240)).max(8).optional()
|
|
7700
|
+
}).optional(),
|
|
7701
|
+
dist: z105.object({
|
|
7702
|
+
integrity: z105.string().max(512).regex(/^sha512-[A-Za-z0-9+/]{86}==$/)
|
|
7703
|
+
})
|
|
7704
|
+
});
|
|
7705
|
+
var clientUpdateStateSchema = z105.object({
|
|
7706
|
+
schemaVersion: z105.literal(1),
|
|
7707
|
+
policy: updatePolicySchema,
|
|
7708
|
+
lastCheck: z105.object({
|
|
7709
|
+
at: z105.number().int().nonnegative(),
|
|
7710
|
+
selector: z105.string().max(160),
|
|
7711
|
+
target: registryReleaseSchema
|
|
7712
|
+
}).strict().optional(),
|
|
7713
|
+
lastAttempt: z105.object({ at: z105.number().int().nonnegative(), selector: z105.string().max(160) }).strict().optional()
|
|
7714
|
+
}).strict();
|
|
7715
|
+
function planNativeUpdate(input) {
|
|
7716
|
+
const target = registryReleaseSchema.parse(input.target);
|
|
7717
|
+
const current = releaseVersionSchema.parse(input.currentVersion ?? nativeClientRelease.version);
|
|
7718
|
+
const policy = updatePolicySchema.parse(input.policy ?? {});
|
|
7719
|
+
const spec = `${target.name}@${target.version}`;
|
|
7720
|
+
const cli = target.name === nativeClientRelease.packages.cli;
|
|
7721
|
+
const result2 = (status, reason, eligible = false) => ({
|
|
7722
|
+
package: target.name,
|
|
7723
|
+
currentVersion: current,
|
|
7724
|
+
targetVersion: target.version,
|
|
7725
|
+
status,
|
|
7726
|
+
reason,
|
|
7727
|
+
eligibleForAutoUpdate: eligible,
|
|
7728
|
+
policy,
|
|
7729
|
+
commands: {
|
|
7730
|
+
npm: [
|
|
7731
|
+
"npm",
|
|
7732
|
+
"install",
|
|
7733
|
+
...cli ? ["--global"] : ["--save-exact"],
|
|
7734
|
+
spec,
|
|
7735
|
+
"--ignore-scripts",
|
|
7736
|
+
"--registry=https://registry.npmjs.org/",
|
|
7737
|
+
"--@native-marketing:registry=https://registry.npmjs.org/"
|
|
7738
|
+
],
|
|
7739
|
+
pnpm: ["pnpm", "add", ...cli ? ["--global"] : ["--save-exact"], spec, "--ignore-scripts"],
|
|
7740
|
+
yarn: cli ? null : ["yarn", "add", "--exact", spec]
|
|
7741
|
+
}
|
|
7742
|
+
});
|
|
7743
|
+
if (policy.pin && policy.pin !== target.version) return result2("BLOCKED", "PIN_MISMATCH");
|
|
7744
|
+
if (!policy.pin && policy.channel === "latest" && target.version.split("+")[0].includes("-"))
|
|
7745
|
+
return result2("BLOCKED", "CHANNEL_MISMATCH");
|
|
7746
|
+
const order = compareReleaseVersions(target.version, current);
|
|
7747
|
+
if (order < 0) return result2("BLOCKED", "DOWNGRADE_FORBIDDEN");
|
|
7748
|
+
if (target.deprecated !== void 0) return result2("BLOCKED", "DEPRECATED");
|
|
7749
|
+
if (!target.nativeMarketing) return result2("BLOCKED", "METADATA_UNAVAILABLE");
|
|
7750
|
+
const metadata = target.nativeMarketing;
|
|
7751
|
+
if (metadata.nodeMajor !== (input.nodeMajor ?? nativeClientRelease.nodeMajor))
|
|
7752
|
+
return result2("BLOCKED", "NODE_MISMATCH");
|
|
7753
|
+
if (metadata.contractVersion !== nativeClientRelease.contractVersion || metadata.apiMajor !== nativeClientRelease.apiMajor)
|
|
7754
|
+
return result2("BLOCKED", "CONTRACT_MISMATCH");
|
|
7755
|
+
if (input.server && assessNativeCompatibility(
|
|
7756
|
+
{
|
|
7757
|
+
version: target.version,
|
|
7758
|
+
contractVersion: metadata.contractVersion,
|
|
7759
|
+
apiMajor: metadata.apiMajor
|
|
7760
|
+
},
|
|
7761
|
+
input.server
|
|
7762
|
+
).status === "INCOMPATIBLE")
|
|
7763
|
+
return result2("BLOCKED", "SERVER_INCOMPATIBLE");
|
|
7764
|
+
if (order === 0) return result2("CURRENT", "CURRENT");
|
|
7765
|
+
const from = current.split(/[.+-]/), to = target.version.split(/[.+-]/);
|
|
7766
|
+
const compatibleLine = from[0] === to[0] && (from[0] !== "0" || from[1] === to[1]);
|
|
7767
|
+
const stable = !current.split("+")[0].includes("-") && !target.version.split("+")[0].includes("-");
|
|
7768
|
+
return compatibleLine && stable ? result2("UPDATE_AVAILABLE", "COMPATIBLE_UPDATE", true) : result2("UPDATE_AVAILABLE", "REVIEW_REQUIRED");
|
|
7769
|
+
}
|
|
7770
|
+
|
|
7553
7771
|
// packages/cli-client/src/errors.ts
|
|
7554
7772
|
var CliError = class extends Error {
|
|
7555
7773
|
constructor(code2, message, outcome = "NOT_SENT", details) {
|
|
@@ -7602,6 +7820,9 @@ function verifyCapabilityDefinition(raw, name, expectedHash) {
|
|
|
7602
7820
|
}
|
|
7603
7821
|
var CapabilityDefinitionCache = class {
|
|
7604
7822
|
values = /* @__PURE__ */ new Map();
|
|
7823
|
+
clear() {
|
|
7824
|
+
this.values.clear();
|
|
7825
|
+
}
|
|
7605
7826
|
remember(value) {
|
|
7606
7827
|
const verified = verifyCapabilityDefinition(value, value.definition.name);
|
|
7607
7828
|
const key2 = `${verified.definition.name}:AGENT_V3:${verified.schemaSha256}`;
|
|
@@ -7940,13 +8161,105 @@ function object2(value) {
|
|
|
7940
8161
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
7941
8162
|
}
|
|
7942
8163
|
|
|
8164
|
+
// packages/cli-client/src/updates/version.ts
|
|
8165
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
8166
|
+
import { dirname, join as join2 } from "node:path";
|
|
8167
|
+
function getNativeClientVersion() {
|
|
8168
|
+
return clientReleaseSchema.parse(nativeClientRelease);
|
|
8169
|
+
}
|
|
8170
|
+
async function getNativeCliVersion(executablePath) {
|
|
8171
|
+
const identity = { ...getNativeClientVersion(), sdkVersion: nativeClientRelease.version };
|
|
8172
|
+
if (!executablePath) return identity;
|
|
8173
|
+
try {
|
|
8174
|
+
const root = dirname(dirname(await realpath(executablePath)));
|
|
8175
|
+
const manifest = JSON.parse(await readFile(join2(root, "package.json"), "utf8"));
|
|
8176
|
+
if (manifest.name === nativeClientRelease.packages.cli)
|
|
8177
|
+
return { ...identity, version: releaseVersionSchema.parse(manifest.version) };
|
|
8178
|
+
} catch {
|
|
8179
|
+
}
|
|
8180
|
+
return identity;
|
|
8181
|
+
}
|
|
8182
|
+
function readNativeServerVersion(client) {
|
|
8183
|
+
const raw = client.getServerCapabilities()?.experimental?.[nativeReleaseCapability];
|
|
8184
|
+
let server;
|
|
8185
|
+
if (raw !== void 0) {
|
|
8186
|
+
const parsed = clientReleaseSchema.safeParse(raw);
|
|
8187
|
+
if (!parsed.success)
|
|
8188
|
+
throw new CliError(
|
|
8189
|
+
"INVALID_SERVER_RELEASE",
|
|
8190
|
+
"The advertised Native Marketing release contract is invalid."
|
|
8191
|
+
);
|
|
8192
|
+
server = parsed.data;
|
|
8193
|
+
}
|
|
8194
|
+
return {
|
|
8195
|
+
client: getNativeClientVersion(),
|
|
8196
|
+
serverInfo: client.getServerVersion() ?? null,
|
|
8197
|
+
mcpProtocolVersion: client.getNegotiatedProtocolVersion() ?? null,
|
|
8198
|
+
compatibility: assessNativeCompatibility(nativeClientRelease, server)
|
|
8199
|
+
};
|
|
8200
|
+
}
|
|
8201
|
+
function assertNativeCompatibility(result2, required = false) {
|
|
8202
|
+
if (result2.compatibility.status === "INCOMPATIBLE" || required && result2.compatibility.status === "UNKNOWN")
|
|
8203
|
+
throw new CliError(
|
|
8204
|
+
"CLIENT_INCOMPATIBLE",
|
|
8205
|
+
"Check version --server and update the client or connect to a compatible service. No business operation was sent.",
|
|
8206
|
+
"NOT_SENT",
|
|
8207
|
+
{ compatibility: result2.compatibility }
|
|
8208
|
+
);
|
|
8209
|
+
}
|
|
8210
|
+
async function refreshNativeServerVersion(client, timeout) {
|
|
8211
|
+
const reply = await client.callTool(
|
|
8212
|
+
{ name: "cf_get_client_release", arguments: {} },
|
|
8213
|
+
{
|
|
8214
|
+
timeout,
|
|
8215
|
+
allowInputRequired: true,
|
|
8216
|
+
toolDefinition: {
|
|
8217
|
+
name: "cf_get_client_release",
|
|
8218
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
8219
|
+
annotations: { readOnlyHint: true }
|
|
8220
|
+
}
|
|
8221
|
+
}
|
|
8222
|
+
).catch(() => {
|
|
8223
|
+
throw new CliError(
|
|
8224
|
+
"VERSION_CHECK_UNAVAILABLE",
|
|
8225
|
+
"Cannot refresh the service release. Reconnect or refresh again before continuing."
|
|
8226
|
+
);
|
|
8227
|
+
});
|
|
8228
|
+
const text3 = reply.content?.find((item) => item.type === "text");
|
|
8229
|
+
let server;
|
|
8230
|
+
try {
|
|
8231
|
+
if (reply.isError) throw new Error();
|
|
8232
|
+
server = clientReleaseSchema.parse(
|
|
8233
|
+
reply.structuredContent ?? (text3?.type === "text" ? JSON.parse(text3.text) : null)
|
|
8234
|
+
);
|
|
8235
|
+
} catch {
|
|
8236
|
+
throw new CliError("INVALID_SERVER_RELEASE", "Cannot verify the current server release.");
|
|
8237
|
+
}
|
|
8238
|
+
const result2 = {
|
|
8239
|
+
...readNativeServerVersion(client),
|
|
8240
|
+
compatibility: assessNativeCompatibility(nativeClientRelease, server)
|
|
8241
|
+
};
|
|
8242
|
+
return result2;
|
|
8243
|
+
}
|
|
8244
|
+
|
|
7943
8245
|
// packages/cli-client/src/transport.ts
|
|
7944
|
-
async function withClient(profile, timeout, operation) {
|
|
8246
|
+
async function withClient(profile, timeout, operation, options = {}) {
|
|
7945
8247
|
const resource = resourceUrl(profile.resource);
|
|
7946
8248
|
const accessToken = tokenText(profile.accessToken);
|
|
7947
8249
|
const client = new Client(
|
|
7948
|
-
{ name: "
|
|
7949
|
-
{
|
|
8250
|
+
{ name: "@native-marketing/sdk", version: nativeClientRelease.version },
|
|
8251
|
+
{
|
|
8252
|
+
inputRequired: { autoFulfill: false },
|
|
8253
|
+
capabilities: {
|
|
8254
|
+
experimental: {
|
|
8255
|
+
[nativeReleaseCapability]: {
|
|
8256
|
+
version: nativeClientRelease.version,
|
|
8257
|
+
contractVersion: nativeClientRelease.contractVersion,
|
|
8258
|
+
apiMajor: nativeClientRelease.apiMajor
|
|
8259
|
+
}
|
|
8260
|
+
}
|
|
8261
|
+
}
|
|
8262
|
+
}
|
|
7950
8263
|
);
|
|
7951
8264
|
const transport = new StreamableHTTPClientTransport(resource, {
|
|
7952
8265
|
authProvider: { token: async () => accessToken },
|
|
@@ -7967,6 +8280,10 @@ async function withClient(profile, timeout, operation) {
|
|
|
7967
8280
|
"Cannot authenticate/connect to the configured CF resource. No business operation was sent."
|
|
7968
8281
|
);
|
|
7969
8282
|
}
|
|
8283
|
+
const version = readNativeServerVersion(client);
|
|
8284
|
+
if (!options.allowIncompatible)
|
|
8285
|
+
assertNativeCompatibility(version, options.requireCompatibility);
|
|
8286
|
+
options.onVersion?.(version);
|
|
7970
8287
|
return await operation(client);
|
|
7971
8288
|
} finally {
|
|
7972
8289
|
await client.close().catch(() => void 0);
|
|
@@ -8834,43 +9151,97 @@ async function withNativeAgentClient(connection, action, options = {}) {
|
|
|
8834
9151
|
return withClient(
|
|
8835
9152
|
connection,
|
|
8836
9153
|
timeout,
|
|
8837
|
-
(client) =>
|
|
8838
|
-
|
|
8839
|
-
|
|
8840
|
-
|
|
8841
|
-
|
|
8842
|
-
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
9154
|
+
(client) => {
|
|
9155
|
+
let version = readNativeServerVersion(client);
|
|
9156
|
+
let versionUnverified = false;
|
|
9157
|
+
client.setNotificationHandler("notifications/tools/list_changed", () => {
|
|
9158
|
+
definitions.clear();
|
|
9159
|
+
});
|
|
9160
|
+
return action(
|
|
9161
|
+
new Proxy(
|
|
9162
|
+
{
|
|
9163
|
+
getVersion: () => structuredClone(version),
|
|
9164
|
+
refreshVersion: async () => {
|
|
9165
|
+
definitions.clear();
|
|
9166
|
+
try {
|
|
9167
|
+
version = await refreshNativeServerVersion(client, timeout);
|
|
9168
|
+
versionUnverified = false;
|
|
9169
|
+
} catch (error) {
|
|
9170
|
+
version = { ...version, compatibility: assessNativeCompatibility(version.client) };
|
|
9171
|
+
versionUnverified = true;
|
|
9172
|
+
throw error;
|
|
9173
|
+
}
|
|
9174
|
+
assertNativeCompatibility(version, options.requireCompatibility);
|
|
9175
|
+
options.onVersion?.(version);
|
|
9176
|
+
return structuredClone(version);
|
|
9177
|
+
},
|
|
9178
|
+
readPackageFile: (input) => readNativePackageFile(connection, input, timeout),
|
|
9179
|
+
readProjectMediaFile: (input) => readNativeProjectMediaFile(connection, input, timeout),
|
|
9180
|
+
uploadProjectMedia: (file) => uploadNativeProjectMedia(connection, file, timeout),
|
|
9181
|
+
uploadMaterial: (file) => uploadNativeMaterial(connection, file, timeout),
|
|
9182
|
+
inspectTool: (name) => inspectNativeTool(client, name, timeout, definitions),
|
|
9183
|
+
callTool: (name, input = {}, options2) => callNativeTool(
|
|
9184
|
+
client,
|
|
9185
|
+
name,
|
|
9186
|
+
input,
|
|
9187
|
+
connection.resource,
|
|
9188
|
+
options2,
|
|
9189
|
+
timeout,
|
|
9190
|
+
definitions
|
|
9191
|
+
),
|
|
9192
|
+
listToolsPage: (input = {}) => listNativeToolsPage(client, input, timeout),
|
|
9193
|
+
readCapabilitySchemaPage: (input) => readNativeCapabilitySchemaPage(client, input, timeout),
|
|
9194
|
+
readDocumentPage: (input) => readNativeDocumentPage(client, input, timeout),
|
|
9195
|
+
getBusinessSummary: (input) => getNativeBusinessSummary(client, input, timeout),
|
|
9196
|
+
callCapability: (input) => callNativeCapability(client, input, timeout),
|
|
9197
|
+
readCapability: (input) => readNativeCapability(client, input, timeout),
|
|
9198
|
+
writeCapability: (input) => writeNativeCapability(client, input, timeout),
|
|
9199
|
+
describeCapabilitySummary: (name) => readNativeCapabilityDescriptor(client, name, timeout),
|
|
9200
|
+
searchBusiness: (input) => searchNativeBusiness(client, input, timeout),
|
|
9201
|
+
readBusinessPage: (input) => readNativeBusinessPage(client, input, timeout),
|
|
9202
|
+
findCapabilities: (input) => findNativeCapabilities(client, input, timeout),
|
|
9203
|
+
discoverCapabilities: async (input) => {
|
|
9204
|
+
const page2 = await findAgentCapabilities(client, input, timeout);
|
|
9205
|
+
for (const item of page2.items)
|
|
9206
|
+
if (item.definition) definitions.remember(item.definition);
|
|
9207
|
+
return page2;
|
|
9208
|
+
},
|
|
9209
|
+
describeCapability: async (name, expectedHash) => {
|
|
9210
|
+
const cached = expectedHash ? definitions.get(name, expectedHash) : void 0;
|
|
9211
|
+
if (cached) return cached;
|
|
9212
|
+
const definition = await describeNativeCapability(client, name, timeout);
|
|
9213
|
+
if (expectedHash && definition.schemaSha256 !== expectedHash)
|
|
9214
|
+
throw new CliError(
|
|
9215
|
+
"CAPABILITY_SCHEMA_CHANGED",
|
|
9216
|
+
"Discover the current definition again.",
|
|
9217
|
+
"REJECTED"
|
|
9218
|
+
);
|
|
9219
|
+
definitions.remember(definition);
|
|
9220
|
+
return definition;
|
|
9221
|
+
}
|
|
9222
|
+
},
|
|
9223
|
+
{
|
|
9224
|
+
get(target, name, receiver) {
|
|
9225
|
+
const method = Reflect.get(target, name, receiver);
|
|
9226
|
+
if (typeof method !== "function" || name === "getVersion" || name === "refreshVersion")
|
|
9227
|
+
return method;
|
|
9228
|
+
return async (...args) => {
|
|
9229
|
+
if (versionUnverified)
|
|
9230
|
+
throw new CliError(
|
|
9231
|
+
"CLIENT_VERSION_UNVERIFIED",
|
|
9232
|
+
"Verify the service release again or reconnect before continuing. No business operation was sent.",
|
|
9233
|
+
"NOT_SENT",
|
|
9234
|
+
{ compatibility: version.compatibility }
|
|
9235
|
+
);
|
|
9236
|
+
assertNativeCompatibility(version, options.requireCompatibility);
|
|
9237
|
+
return Reflect.apply(method, target, args);
|
|
9238
|
+
};
|
|
9239
|
+
}
|
|
9240
|
+
}
|
|
9241
|
+
)
|
|
9242
|
+
);
|
|
9243
|
+
},
|
|
9244
|
+
options
|
|
8874
9245
|
);
|
|
8875
9246
|
}
|
|
8876
9247
|
function checkTimeout4(timeout) {
|
|
@@ -9025,9 +9396,22 @@ var values = /* @__PURE__ */ new Set([
|
|
|
9025
9396
|
"scope",
|
|
9026
9397
|
"job",
|
|
9027
9398
|
"view",
|
|
9028
|
-
"schema-hash"
|
|
9399
|
+
"schema-hash",
|
|
9400
|
+
"mode",
|
|
9401
|
+
"channel",
|
|
9402
|
+
"pin",
|
|
9403
|
+
"interval-hours"
|
|
9404
|
+
]);
|
|
9405
|
+
var flags = /* @__PURE__ */ new Set([
|
|
9406
|
+
"json",
|
|
9407
|
+
"stdin",
|
|
9408
|
+
"help",
|
|
9409
|
+
"version",
|
|
9410
|
+
"server",
|
|
9411
|
+
"strict",
|
|
9412
|
+
"allow-breaking",
|
|
9413
|
+
"dry-run"
|
|
9029
9414
|
]);
|
|
9030
|
-
var flags = /* @__PURE__ */ new Set(["json", "stdin", "help"]);
|
|
9031
9415
|
function parseArgs(args) {
|
|
9032
9416
|
const options = {};
|
|
9033
9417
|
const words = [];
|
|
@@ -9106,8 +9490,8 @@ async function login(store, rawResource, scope2, timeout, notify) {
|
|
|
9106
9490
|
const state = randomBytes(32).toString("base64url");
|
|
9107
9491
|
let resolveCode;
|
|
9108
9492
|
let rejectCode;
|
|
9109
|
-
const codePromise = new Promise((
|
|
9110
|
-
resolveCode =
|
|
9493
|
+
const codePromise = new Promise((resolve2, reject) => {
|
|
9494
|
+
resolveCode = resolve2;
|
|
9111
9495
|
rejectCode = reject;
|
|
9112
9496
|
});
|
|
9113
9497
|
void codePromise.catch(() => void 0);
|
|
@@ -9138,9 +9522,9 @@ async function login(store, rawResource, scope2, timeout, notify) {
|
|
|
9138
9522
|
});
|
|
9139
9523
|
let timer;
|
|
9140
9524
|
try {
|
|
9141
|
-
await new Promise((
|
|
9525
|
+
await new Promise((resolve2, reject) => {
|
|
9142
9526
|
server.once("error", reject);
|
|
9143
|
-
server.listen(0, "127.0.0.1",
|
|
9527
|
+
server.listen(0, "127.0.0.1", resolve2);
|
|
9144
9528
|
});
|
|
9145
9529
|
const address = server.address();
|
|
9146
9530
|
if (!address || typeof address === "string")
|
|
@@ -9210,7 +9594,7 @@ Waiting up to 5 minutes. For remote/headless Agents, use auth import with a prov
|
|
|
9210
9594
|
} finally {
|
|
9211
9595
|
if (timer) clearTimeout(timer);
|
|
9212
9596
|
server.closeAllConnections();
|
|
9213
|
-
await new Promise((
|
|
9597
|
+
await new Promise((resolve2) => server.close(() => resolve2()));
|
|
9214
9598
|
}
|
|
9215
9599
|
});
|
|
9216
9600
|
}
|
|
@@ -9254,6 +9638,9 @@ var commandTools = {
|
|
|
9254
9638
|
"knowledge discover": "cf_discover_knowledge",
|
|
9255
9639
|
"knowledge adopt": "cf_adopt_discovered_knowledge",
|
|
9256
9640
|
"knowledge adoption-receipt": "cf_get_knowledge_adoption_receipt",
|
|
9641
|
+
"knowledge repair-preview": "cf_preview_knowledge_reference_repair",
|
|
9642
|
+
"knowledge repair-reference": "cf_repair_knowledge_reference",
|
|
9643
|
+
"knowledge repair-receipt": "cf_get_knowledge_reference_repair_receipt",
|
|
9257
9644
|
"knowledge read-discovered": "cf_read_discovered_knowledge",
|
|
9258
9645
|
"knowledge describe-discovered": "cf_describe_discovered_knowledge",
|
|
9259
9646
|
"knowledge materials": "cf_list_materials",
|
|
@@ -9282,6 +9669,10 @@ var fullHelp = {
|
|
|
9282
9669
|
executable: "cf-agent",
|
|
9283
9670
|
transport: "OAuth-authenticated HTTPS MCP; no local database",
|
|
9284
9671
|
commands: [
|
|
9672
|
+
"version [--server [--strict] [--profile <name>]]",
|
|
9673
|
+
"update check [--channel latest|next|beta] [--pin <exact-version>|none]",
|
|
9674
|
+
"update apply [--dry-run] [--allow-breaking] [--channel latest|next|beta] [--pin <exact-version>|none]",
|
|
9675
|
+
"update policy [--mode off|notify|auto] [--channel latest|next|beta] [--pin <exact-version>|none] [--interval-hours <1..168>]",
|
|
9285
9676
|
"auth login --resource <url> [--scope <scopes>] [--profile <name>]",
|
|
9286
9677
|
"auth import --resource <url> --token-file <private-file> [--profile <name>]",
|
|
9287
9678
|
"auth status|refresh|logout [--profile <name>]",
|
|
@@ -9325,6 +9716,8 @@ var help = {
|
|
|
9325
9716
|
executable: "cf-agent",
|
|
9326
9717
|
transport: "OAuth-authenticated MCP; no local database",
|
|
9327
9718
|
commands: [
|
|
9719
|
+
"version [--server [--strict]]",
|
|
9720
|
+
"update check|apply|policy (help update for channels, pins and automatic updates)",
|
|
9328
9721
|
"auth login --resource <url> [--scope <scopes>]",
|
|
9329
9722
|
"search [<text>] [--input-file <query.json>|--stdin]",
|
|
9330
9723
|
"business read (--input-file <ref-and-page.json>|--stdin)",
|
|
@@ -9469,6 +9862,21 @@ function resolveBaseCommand(parsed) {
|
|
|
9469
9862
|
throw new CliError("INVALID_COMMAND", "Run help for supported commands.");
|
|
9470
9863
|
}
|
|
9471
9864
|
function resolveCommand(parsed) {
|
|
9865
|
+
if ([
|
|
9866
|
+
"mode",
|
|
9867
|
+
"channel",
|
|
9868
|
+
"pin",
|
|
9869
|
+
"interval-hours",
|
|
9870
|
+
"version",
|
|
9871
|
+
"server",
|
|
9872
|
+
"strict",
|
|
9873
|
+
"allow-breaking",
|
|
9874
|
+
"dry-run"
|
|
9875
|
+
].some((key2) => parsed.options[key2]))
|
|
9876
|
+
throw new CliError(
|
|
9877
|
+
"INVALID_OPTION",
|
|
9878
|
+
"Version/update options apply only to version/update commands."
|
|
9879
|
+
);
|
|
9472
9880
|
const removed = {
|
|
9473
9881
|
doctor: "context",
|
|
9474
9882
|
"knowledge sync-all": "knowledge discover",
|
|
@@ -9603,14 +10011,430 @@ function validateCommandInput(parsed, input) {
|
|
|
9603
10011
|
throw new CliError("INVALID_PAGINATION", "Supply only an optional nonempty cursor.");
|
|
9604
10012
|
}
|
|
9605
10013
|
|
|
10014
|
+
// packages/cli-client/src/updates/registry.ts
|
|
10015
|
+
async function checkNativeUpdates(options = {}) {
|
|
10016
|
+
const policy = updatePolicySchema.parse(options.policy ?? {});
|
|
10017
|
+
const current = releaseVersionSchema.safeParse(
|
|
10018
|
+
options.currentVersion ?? nativeClientRelease.version
|
|
10019
|
+
);
|
|
10020
|
+
if (!current.success)
|
|
10021
|
+
throw new CliError(
|
|
10022
|
+
"INVALID_UPDATE_VERSION",
|
|
10023
|
+
"The installed version must be an exact semantic version."
|
|
10024
|
+
);
|
|
10025
|
+
const timeout = options.timeoutMs ?? 5e3;
|
|
10026
|
+
if (!Number.isInteger(timeout) || timeout < 100 || timeout > 12e4)
|
|
10027
|
+
throw new CliError("INVALID_TIMEOUT", "Timeout must be 100\u2013120000 milliseconds.");
|
|
10028
|
+
const name = nativeClientRelease.packages[options.package ?? "sdk"];
|
|
10029
|
+
if (!name) throw new CliError("INVALID_UPDATE_PACKAGE", "Choose sdk or cli.");
|
|
10030
|
+
const selector = policy.pin ?? policy.channel;
|
|
10031
|
+
const url = `https://registry.npmjs.org/${encodeURIComponent(name)}/${encodeURIComponent(selector)}`;
|
|
10032
|
+
let target;
|
|
10033
|
+
try {
|
|
10034
|
+
const response = await (options.fetch ?? fetch)(url, {
|
|
10035
|
+
redirect: "error",
|
|
10036
|
+
credentials: "omit",
|
|
10037
|
+
signal: AbortSignal.timeout(timeout),
|
|
10038
|
+
headers: { accept: "application/json" }
|
|
10039
|
+
});
|
|
10040
|
+
if (!response.ok || !response.body) throw new Error();
|
|
10041
|
+
const reader = response.body.getReader();
|
|
10042
|
+
const chunks = [];
|
|
10043
|
+
let size = 0;
|
|
10044
|
+
try {
|
|
10045
|
+
for (; ; ) {
|
|
10046
|
+
const { done, value } = await reader.read();
|
|
10047
|
+
if (done) break;
|
|
10048
|
+
size += value.byteLength;
|
|
10049
|
+
if (size > 128 * 1024) throw new Error();
|
|
10050
|
+
chunks.push(value);
|
|
10051
|
+
}
|
|
10052
|
+
} finally {
|
|
10053
|
+
await reader.cancel().catch(() => void 0);
|
|
10054
|
+
reader.releaseLock();
|
|
10055
|
+
}
|
|
10056
|
+
target = registryReleaseSchema.parse(JSON.parse(Buffer.concat(chunks).toString("utf8")));
|
|
10057
|
+
if (target.name !== name || policy.pin && target.version !== policy.pin) throw new Error();
|
|
10058
|
+
} catch {
|
|
10059
|
+
throw new CliError(
|
|
10060
|
+
"UPDATE_CHECK_UNAVAILABLE",
|
|
10061
|
+
"Cannot verify release metadata from the public npm registry. Existing software and credentials are unchanged."
|
|
10062
|
+
);
|
|
10063
|
+
}
|
|
10064
|
+
return {
|
|
10065
|
+
checkedAt: Date.now(),
|
|
10066
|
+
target,
|
|
10067
|
+
plan: planNativeUpdate({
|
|
10068
|
+
target,
|
|
10069
|
+
policy,
|
|
10070
|
+
nodeMajor: Number(process.versions.node.split(".")[0]),
|
|
10071
|
+
currentVersion: current.data,
|
|
10072
|
+
...options.server ? { server: options.server } : {}
|
|
10073
|
+
})
|
|
10074
|
+
};
|
|
10075
|
+
}
|
|
10076
|
+
|
|
10077
|
+
// packages/cli-client/src/updates/store.ts
|
|
10078
|
+
import { lstat as lstat2, open as open6, rename as rename2, unlink as unlink2 } from "node:fs/promises";
|
|
10079
|
+
import { join as join3 } from "node:path";
|
|
10080
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
10081
|
+
var UpdateStore = class {
|
|
10082
|
+
files;
|
|
10083
|
+
constructor(env) {
|
|
10084
|
+
const base2 = new ProfileStore(env).directory;
|
|
10085
|
+
this.files = new ProfileStore({ CF_AGENT_CONFIG_DIR: join3(base2, "client-lifecycle") }, "state");
|
|
10086
|
+
}
|
|
10087
|
+
async read() {
|
|
10088
|
+
try {
|
|
10089
|
+
await lstat2(this.files.path);
|
|
10090
|
+
} catch (error) {
|
|
10091
|
+
if (error.code === "ENOENT")
|
|
10092
|
+
return { schemaVersion: 1, policy: updatePolicySchema.parse({}) };
|
|
10093
|
+
throw error;
|
|
10094
|
+
}
|
|
10095
|
+
let raw;
|
|
10096
|
+
try {
|
|
10097
|
+
raw = JSON.parse(await readFileBounded(this.files.path, true));
|
|
10098
|
+
} catch {
|
|
10099
|
+
throw new CliError(
|
|
10100
|
+
"INVALID_UPDATE_CONFIGURATION",
|
|
10101
|
+
"Update state is unreadable. Inspect the client-lifecycle configuration."
|
|
10102
|
+
);
|
|
10103
|
+
}
|
|
10104
|
+
const parsed = clientUpdateStateSchema.safeParse(raw);
|
|
10105
|
+
if (!parsed.success)
|
|
10106
|
+
throw new CliError(
|
|
10107
|
+
"INVALID_UPDATE_CONFIGURATION",
|
|
10108
|
+
"Update state is invalid. Inspect the client-lifecycle configuration."
|
|
10109
|
+
);
|
|
10110
|
+
return parsed.data;
|
|
10111
|
+
}
|
|
10112
|
+
locked(action) {
|
|
10113
|
+
return this.files.locked(action);
|
|
10114
|
+
}
|
|
10115
|
+
async change(action) {
|
|
10116
|
+
return this.locked(async () => {
|
|
10117
|
+
const state = clientUpdateStateSchema.parse(action(await this.read()));
|
|
10118
|
+
const temporary = `${this.files.path}.${randomUUID3()}.tmp`;
|
|
10119
|
+
const file = await open6(temporary, "wx", 384);
|
|
10120
|
+
try {
|
|
10121
|
+
try {
|
|
10122
|
+
await file.writeFile(JSON.stringify(state) + "\n");
|
|
10123
|
+
await file.sync();
|
|
10124
|
+
} finally {
|
|
10125
|
+
await file.close();
|
|
10126
|
+
}
|
|
10127
|
+
await rename2(temporary, this.files.path);
|
|
10128
|
+
} finally {
|
|
10129
|
+
await unlink2(temporary).catch(() => void 0);
|
|
10130
|
+
}
|
|
10131
|
+
return state;
|
|
10132
|
+
});
|
|
10133
|
+
}
|
|
10134
|
+
};
|
|
10135
|
+
function effectiveUpdatePolicy(policy, env) {
|
|
10136
|
+
const parsed = updatePolicySchema.safeParse({
|
|
10137
|
+
...policy,
|
|
10138
|
+
...env.CF_AGENT_UPDATE_MODE ? { mode: env.CF_AGENT_UPDATE_MODE } : {},
|
|
10139
|
+
...env.CF_AGENT_UPDATE_CHANNEL ? { channel: env.CF_AGENT_UPDATE_CHANNEL } : {},
|
|
10140
|
+
...env.CF_AGENT_UPDATE_PIN ? { pin: env.CF_AGENT_UPDATE_PIN === "none" ? null : env.CF_AGENT_UPDATE_PIN } : {}
|
|
10141
|
+
});
|
|
10142
|
+
if (!parsed.success)
|
|
10143
|
+
throw new CliError("INVALID_UPDATE_CONFIGURATION", "Invalid update environment policy.");
|
|
10144
|
+
return parsed.data;
|
|
10145
|
+
}
|
|
10146
|
+
|
|
10147
|
+
// packages/cli-client/src/updates/install.ts
|
|
10148
|
+
import { execFile } from "node:child_process";
|
|
10149
|
+
import { promisify } from "node:util";
|
|
10150
|
+
import { readFile as readFile2, realpath as realpath2 } from "node:fs/promises";
|
|
10151
|
+
import { dirname as dirname2, join as join4, resolve } from "node:path";
|
|
10152
|
+
var execute = promisify(execFile);
|
|
10153
|
+
async function installCliUpdate(input) {
|
|
10154
|
+
const plan = planNativeUpdate({
|
|
10155
|
+
target: input.target,
|
|
10156
|
+
...input.currentVersion ? { currentVersion: input.currentVersion } : {},
|
|
10157
|
+
policy: input.policy,
|
|
10158
|
+
nodeMajor: Number(process.versions.node.split(".")[0])
|
|
10159
|
+
});
|
|
10160
|
+
if (plan.package !== nativeClientRelease.packages.cli || plan.status !== "UPDATE_AVAILABLE" || !plan.eligibleForAutoUpdate && !input.allowBreaking)
|
|
10161
|
+
throw new CliError(
|
|
10162
|
+
"UPDATE_POLICY_BLOCKED",
|
|
10163
|
+
"This release cannot be installed under the selected policy.",
|
|
10164
|
+
"NOT_SENT",
|
|
10165
|
+
{ plan }
|
|
10166
|
+
);
|
|
10167
|
+
if (!input.executablePath || process.platform === "win32")
|
|
10168
|
+
throw new CliError(
|
|
10169
|
+
"MANAGED_UPDATE_UNAVAILABLE",
|
|
10170
|
+
"Use the package manager that owns this installation.",
|
|
10171
|
+
"NOT_SENT",
|
|
10172
|
+
{ plan }
|
|
10173
|
+
);
|
|
10174
|
+
const environment = Object.fromEntries(
|
|
10175
|
+
Object.entries(input.env).filter(
|
|
10176
|
+
([key2, value]) => value !== void 0 && !/^(?:CF_AGENT_|CONTENT_FACTORY_)/i.test(key2)
|
|
10177
|
+
)
|
|
10178
|
+
);
|
|
10179
|
+
environment.CF_AGENT_UPDATE_MODE = "off";
|
|
10180
|
+
environment.NODE_OPTIONS = "--max-old-space-size=384";
|
|
10181
|
+
const options = { env: environment, timeout: input.timeoutMs, maxBuffer: 128 * 1024 };
|
|
10182
|
+
let packageRoot, prefix;
|
|
10183
|
+
try {
|
|
10184
|
+
packageRoot = dirname2(dirname2(await realpath2(input.executablePath)));
|
|
10185
|
+
const manifest = JSON.parse(await readFile2(join4(packageRoot, "package.json"), "utf8"));
|
|
10186
|
+
const root = await realpath2(
|
|
10187
|
+
(await execute("npm", ["root", "--global"], options)).stdout.trim()
|
|
10188
|
+
);
|
|
10189
|
+
prefix = await realpath2((await execute("npm", ["prefix", "--global"], options)).stdout.trim());
|
|
10190
|
+
if (manifest.name !== nativeClientRelease.packages.cli || manifest.version !== plan.currentVersion || packageRoot !== await realpath2(join4(root, "@native-marketing/cli")) || packageRoot !== resolve(prefix, "lib/node_modules/@native-marketing/cli"))
|
|
10191
|
+
throw new Error();
|
|
10192
|
+
} catch {
|
|
10193
|
+
throw new CliError(
|
|
10194
|
+
"MANAGED_UPDATE_UNAVAILABLE",
|
|
10195
|
+
"Automatic installation supports the active npm global installation. Use the owning project/package manager for other installs.",
|
|
10196
|
+
"NOT_SENT",
|
|
10197
|
+
{ plan }
|
|
10198
|
+
);
|
|
10199
|
+
}
|
|
10200
|
+
const args = [
|
|
10201
|
+
"install",
|
|
10202
|
+
"--global",
|
|
10203
|
+
"--prefix",
|
|
10204
|
+
prefix,
|
|
10205
|
+
`${plan.package}@${plan.targetVersion}`,
|
|
10206
|
+
"--registry=https://registry.npmjs.org/",
|
|
10207
|
+
"--@native-marketing:registry=https://registry.npmjs.org/",
|
|
10208
|
+
"--ignore-scripts",
|
|
10209
|
+
"--no-audit",
|
|
10210
|
+
"--no-fund"
|
|
10211
|
+
];
|
|
10212
|
+
const recovery = [
|
|
10213
|
+
"npm",
|
|
10214
|
+
"install",
|
|
10215
|
+
"--global",
|
|
10216
|
+
"--prefix",
|
|
10217
|
+
prefix,
|
|
10218
|
+
`${plan.package}@${plan.currentVersion}`,
|
|
10219
|
+
"--ignore-scripts",
|
|
10220
|
+
"--registry=https://registry.npmjs.org/",
|
|
10221
|
+
"--@native-marketing:registry=https://registry.npmjs.org/"
|
|
10222
|
+
];
|
|
10223
|
+
const store = new UpdateStore(input.env);
|
|
10224
|
+
return store.locked(async () => {
|
|
10225
|
+
if (input.automatic) {
|
|
10226
|
+
const latest = effectiveUpdatePolicy((await store.read()).policy, input.env);
|
|
10227
|
+
if (latest.mode !== "auto" || (latest.pin ?? latest.channel) !== (input.policy.pin ?? input.policy.channel) || !planNativeUpdate({
|
|
10228
|
+
target: input.target,
|
|
10229
|
+
currentVersion: plan.currentVersion,
|
|
10230
|
+
policy: latest,
|
|
10231
|
+
nodeMajor: Number(process.versions.node.split(".")[0])
|
|
10232
|
+
}).eligibleForAutoUpdate)
|
|
10233
|
+
throw new CliError(
|
|
10234
|
+
"UPDATE_POLICY_CHANGED",
|
|
10235
|
+
"Automatic update policy changed. No installation or business operation was sent."
|
|
10236
|
+
);
|
|
10237
|
+
}
|
|
10238
|
+
const before = JSON.parse(await readFile2(join4(packageRoot, "package.json"), "utf8"));
|
|
10239
|
+
if (before.name !== plan.package || before.version !== plan.currentVersion)
|
|
10240
|
+
throw new CliError(
|
|
10241
|
+
"UPDATE_INSTALLATION_CHANGED",
|
|
10242
|
+
"The installed version changed. Check version before updating again."
|
|
10243
|
+
);
|
|
10244
|
+
try {
|
|
10245
|
+
await execute("npm", args, { ...options, cwd: prefix });
|
|
10246
|
+
const installed = JSON.parse(await readFile2(join4(packageRoot, "package.json"), "utf8"));
|
|
10247
|
+
if (installed.name !== plan.package || releaseVersionSchema.parse(installed.version) !== plan.targetVersion)
|
|
10248
|
+
throw new Error();
|
|
10249
|
+
const verified = await execute(
|
|
10250
|
+
process.execPath,
|
|
10251
|
+
[join4(packageRoot, "dist/cf.js"), "version", "--json"],
|
|
10252
|
+
options
|
|
10253
|
+
);
|
|
10254
|
+
const result2 = JSON.parse(verified.stdout);
|
|
10255
|
+
if (!result2.ok || result2.data?.version !== plan.targetVersion || result2.data?.sdkVersion !== plan.targetVersion)
|
|
10256
|
+
throw new Error();
|
|
10257
|
+
return {
|
|
10258
|
+
state: "UPDATED",
|
|
10259
|
+
package: plan.package,
|
|
10260
|
+
previousVersion: plan.currentVersion,
|
|
10261
|
+
installedVersion: plan.targetVersion,
|
|
10262
|
+
restartRequired: true,
|
|
10263
|
+
originalCommandExecuted: false,
|
|
10264
|
+
recovery
|
|
10265
|
+
};
|
|
10266
|
+
} catch {
|
|
10267
|
+
throw new CliError(
|
|
10268
|
+
"UPDATE_OUTCOME_UNKNOWN",
|
|
10269
|
+
"The installation may have changed. Inspect version before another update; use the recovery command if needed. The original business command was not sent.",
|
|
10270
|
+
"UNKNOWN",
|
|
10271
|
+
{ expectedVersion: plan.targetVersion, recovery, originalCommandExecuted: false }
|
|
10272
|
+
);
|
|
10273
|
+
}
|
|
10274
|
+
});
|
|
10275
|
+
}
|
|
10276
|
+
|
|
10277
|
+
// packages/cli-client/src/updates/commands.ts
|
|
10278
|
+
function validateOptions(parsed, names) {
|
|
10279
|
+
if (Object.keys(parsed.options).some((name) => !["json", "timeout-ms", ...names].includes(name)))
|
|
10280
|
+
throw new CliError("INVALID_OPTION", "Unsupported version/update option. Use help update.");
|
|
10281
|
+
}
|
|
10282
|
+
function selectedPolicy(saved, parsed) {
|
|
10283
|
+
const options = parsed.options;
|
|
10284
|
+
const result2 = updatePolicySchema.safeParse({
|
|
10285
|
+
...saved,
|
|
10286
|
+
...options.mode ? { mode: options.mode } : {},
|
|
10287
|
+
...options.channel ? { channel: options.channel } : {},
|
|
10288
|
+
...options.pin ? { pin: options.pin === "none" ? null : options.pin } : {},
|
|
10289
|
+
...options["interval-hours"] ? { intervalHours: Number(options["interval-hours"]) } : {}
|
|
10290
|
+
});
|
|
10291
|
+
if (!result2.success)
|
|
10292
|
+
throw new CliError(
|
|
10293
|
+
"INVALID_UPDATE_POLICY",
|
|
10294
|
+
"Use mode off/notify/auto, channel latest/next/beta, an exact pin or none, and interval-hours 1\u2013168."
|
|
10295
|
+
);
|
|
10296
|
+
return result2.data;
|
|
10297
|
+
}
|
|
10298
|
+
async function runLifecycleCommand(parsed, env, executablePath) {
|
|
10299
|
+
const { words, options, timeout } = parsed;
|
|
10300
|
+
if (options.version || words[0] === "version") {
|
|
10301
|
+
if (options.version && words.length !== 0 || !options.version && words.length !== 1)
|
|
10302
|
+
throw new CliError("INVALID_COMMAND", "Use version or --version.");
|
|
10303
|
+
validateOptions(parsed, ["version", "server", "strict", "profile"]);
|
|
10304
|
+
if (options.strict && !options.server)
|
|
10305
|
+
throw new CliError("INVALID_OPTION", "--strict requires version --server.");
|
|
10306
|
+
if (options.profile && !options.server)
|
|
10307
|
+
throw new CliError("INVALID_OPTION", "--profile requires version --server.");
|
|
10308
|
+
return options.server ? null : { command: "version", data: await getNativeCliVersion(executablePath) };
|
|
10309
|
+
}
|
|
10310
|
+
if (words[0] !== "update") return null;
|
|
10311
|
+
if (words.length !== 2 || !["check", "apply", "policy"].includes(words[1]))
|
|
10312
|
+
throw new CliError("INVALID_COMMAND", "Use update check/apply/policy.");
|
|
10313
|
+
const policyCommand = words[1] === "policy";
|
|
10314
|
+
validateOptions(
|
|
10315
|
+
parsed,
|
|
10316
|
+
policyCommand ? ["mode", "channel", "pin", "interval-hours"] : ["channel", "pin", ...words[1] === "apply" ? ["allow-breaking", "dry-run"] : []]
|
|
10317
|
+
);
|
|
10318
|
+
const store = new UpdateStore(env);
|
|
10319
|
+
const state = await store.read();
|
|
10320
|
+
if (policyCommand) {
|
|
10321
|
+
const changes = Object.keys(options).some(
|
|
10322
|
+
(name) => ["mode", "channel", "pin", "interval-hours"].includes(name)
|
|
10323
|
+
);
|
|
10324
|
+
const saved = changes ? await store.change((current) => ({
|
|
10325
|
+
...current,
|
|
10326
|
+
policy: selectedPolicy(current.policy, parsed)
|
|
10327
|
+
})) : state;
|
|
10328
|
+
return {
|
|
10329
|
+
command: "update policy",
|
|
10330
|
+
data: {
|
|
10331
|
+
saved: saved.policy,
|
|
10332
|
+
effective: effectiveUpdatePolicy(saved.policy, env),
|
|
10333
|
+
lastCheckedAt: saved.lastCheck?.at ?? null
|
|
10334
|
+
}
|
|
10335
|
+
};
|
|
10336
|
+
}
|
|
10337
|
+
const policy = selectedPolicy(effectiveUpdatePolicy(state.policy, env), parsed);
|
|
10338
|
+
const currentVersion = (await getNativeCliVersion(executablePath)).version;
|
|
10339
|
+
const checked = await checkNativeUpdates({
|
|
10340
|
+
package: "cli",
|
|
10341
|
+
currentVersion,
|
|
10342
|
+
policy,
|
|
10343
|
+
timeoutMs: timeout
|
|
10344
|
+
});
|
|
10345
|
+
await store.change((current) => ({
|
|
10346
|
+
...current,
|
|
10347
|
+
lastAttempt: { at: checked.checkedAt, selector: policy.pin ?? policy.channel },
|
|
10348
|
+
lastCheck: {
|
|
10349
|
+
at: checked.checkedAt,
|
|
10350
|
+
selector: policy.pin ?? policy.channel,
|
|
10351
|
+
target: checked.target
|
|
10352
|
+
}
|
|
10353
|
+
}));
|
|
10354
|
+
if (words[1] === "check" || options["dry-run"] || checked.plan.status === "CURRENT")
|
|
10355
|
+
return { command: words.join(" "), data: checked };
|
|
10356
|
+
const data = await installCliUpdate({
|
|
10357
|
+
target: checked.target,
|
|
10358
|
+
currentVersion,
|
|
10359
|
+
policy,
|
|
10360
|
+
timeoutMs: timeout,
|
|
10361
|
+
env,
|
|
10362
|
+
allowBreaking: Boolean(options["allow-breaking"]),
|
|
10363
|
+
...executablePath ? { executablePath } : {}
|
|
10364
|
+
});
|
|
10365
|
+
return { command: "update apply", data };
|
|
10366
|
+
}
|
|
10367
|
+
async function maybeAutoUpdate(env, io, timeout) {
|
|
10368
|
+
if (!io.executablePath || env.CF_AGENT_UPDATE_MODE === "off" || env.CI && !env.CF_AGENT_UPDATE_MODE)
|
|
10369
|
+
return null;
|
|
10370
|
+
const notify = io.notify ?? ((message) => process.stderr.write(message + "\n"));
|
|
10371
|
+
try {
|
|
10372
|
+
const store = new UpdateStore(env);
|
|
10373
|
+
const state = await store.read();
|
|
10374
|
+
const policy = effectiveUpdatePolicy(state.policy, env);
|
|
10375
|
+
if (policy.mode === "off") return null;
|
|
10376
|
+
const now = Date.now(), selector = policy.pin ?? policy.channel;
|
|
10377
|
+
const age = state.lastAttempt ? now - state.lastAttempt.at : Infinity;
|
|
10378
|
+
if (state.lastAttempt?.selector === selector && age >= 0 && age < policy.intervalHours * 36e5)
|
|
10379
|
+
return null;
|
|
10380
|
+
let claimed = false;
|
|
10381
|
+
await store.change((current) => {
|
|
10382
|
+
const age2 = current.lastAttempt ? now - current.lastAttempt.at : Infinity;
|
|
10383
|
+
if (current.lastAttempt?.selector === selector && age2 >= 0 && age2 < policy.intervalHours * 36e5)
|
|
10384
|
+
return current;
|
|
10385
|
+
claimed = true;
|
|
10386
|
+
return { ...current, lastAttempt: { at: now, selector } };
|
|
10387
|
+
});
|
|
10388
|
+
if (!claimed) return null;
|
|
10389
|
+
const currentVersion = (await getNativeCliVersion(io.executablePath)).version;
|
|
10390
|
+
const checked = await checkNativeUpdates({
|
|
10391
|
+
package: "cli",
|
|
10392
|
+
currentVersion,
|
|
10393
|
+
policy,
|
|
10394
|
+
timeoutMs: Math.min(timeout, 2e3)
|
|
10395
|
+
});
|
|
10396
|
+
await store.change((current) => ({
|
|
10397
|
+
...current,
|
|
10398
|
+
lastCheck: { at: checked.checkedAt, selector, target: checked.target }
|
|
10399
|
+
}));
|
|
10400
|
+
if (checked.plan.status === "CURRENT" || checked.plan.reason === "DOWNGRADE_FORBIDDEN" && !policy.pin)
|
|
10401
|
+
return null;
|
|
10402
|
+
if (policy.mode === "auto" && checked.plan.eligibleForAutoUpdate) {
|
|
10403
|
+
const data = await installCliUpdate({
|
|
10404
|
+
target: checked.target,
|
|
10405
|
+
currentVersion,
|
|
10406
|
+
automatic: true,
|
|
10407
|
+
policy,
|
|
10408
|
+
executablePath: io.executablePath,
|
|
10409
|
+
env,
|
|
10410
|
+
timeoutMs: timeout
|
|
10411
|
+
});
|
|
10412
|
+
notify(
|
|
10413
|
+
`Native Marketing updated to ${checked.plan.targetVersion}. Run the original command again.`
|
|
10414
|
+
);
|
|
10415
|
+
return { command: "update auto", data };
|
|
10416
|
+
}
|
|
10417
|
+
notify(
|
|
10418
|
+
`Native Marketing ${nativeClientRelease.version}: update ${checked.plan.targetVersion} (${checked.plan.reason}). Use update check or update apply.`
|
|
10419
|
+
);
|
|
10420
|
+
} catch (error) {
|
|
10421
|
+
if (error instanceof CliError && error.code === "UPDATE_OUTCOME_UNKNOWN") throw error;
|
|
10422
|
+
notify("Native Marketing update check/install is unavailable; use update check for details.");
|
|
10423
|
+
}
|
|
10424
|
+
return null;
|
|
10425
|
+
}
|
|
10426
|
+
|
|
9606
10427
|
// packages/cli-client/src/cli/run.ts
|
|
9607
10428
|
async function runNetworkCli(args, env = process.env, io = {}, executable = "cf") {
|
|
9608
10429
|
let command5 = executable;
|
|
9609
10430
|
try {
|
|
9610
10431
|
const parsed = parseArgs(args);
|
|
9611
10432
|
const { words, options, timeout } = parsed;
|
|
9612
|
-
if (!words.length || words[0] === "help" || options.help)
|
|
10433
|
+
if ((!words.length || words[0] === "help" || options.help) && !options.version)
|
|
9613
10434
|
return success("help", { ...commandHelp(words), executable });
|
|
10435
|
+
const local = await runLifecycleCommand(parsed, env, io.executablePath);
|
|
10436
|
+
if (local) return success(local.command, local.data);
|
|
10437
|
+
const remoteVersion = (words.join(" ") === "version" || options.version && !words.length) && options.server;
|
|
9614
10438
|
const store = new ProfileStore(env, String(options.profile ?? "default"));
|
|
9615
10439
|
if (words[0] === "auth") {
|
|
9616
10440
|
if (words.length !== 2)
|
|
@@ -9682,10 +10506,14 @@ async function runNetworkCli(args, env = process.env, io = {}, executable = "cf"
|
|
|
9682
10506
|
"AUTH_OPTION_MISUSE",
|
|
9683
10507
|
"Resource/token/scope options belong to auth commands. Business commands use the bound profile or CF_AGENT_RESOURCE and CF_AGENT_ACCESS_TOKEN together."
|
|
9684
10508
|
);
|
|
9685
|
-
resolveCommand(parsed);
|
|
9686
|
-
command5 = words[0] === "search" ? "search" : words[0] === "capabilities" ? words.slice(0, 2).join(" ") : words.join(" ");
|
|
10509
|
+
if (!remoteVersion) resolveCommand(parsed);
|
|
10510
|
+
command5 = remoteVersion ? "version" : words[0] === "search" ? "search" : words[0] === "capabilities" ? words.slice(0, 2).join(" ") : words.join(" ");
|
|
10511
|
+
if (!remoteVersion) {
|
|
10512
|
+
const automatic = await maybeAutoUpdate(env, io, timeout);
|
|
10513
|
+
if (automatic) return success(automatic.command, automatic.data);
|
|
10514
|
+
}
|
|
9687
10515
|
const input = options.stdin ? objectJson(await readStream(io.stdin ?? process.stdin)) : typeof options["input-file"] === "string" ? objectJson(await readFileBounded(options["input-file"])) : {};
|
|
9688
|
-
validateCommandInput(parsed, input);
|
|
10516
|
+
if (!remoteVersion) validateCommandInput(parsed, input);
|
|
9689
10517
|
let profile;
|
|
9690
10518
|
if (env.CF_AGENT_ACCESS_TOKEN || env.CF_AGENT_RESOURCE) {
|
|
9691
10519
|
if (options.profile || !env.CF_AGENT_ACCESS_TOKEN || !env.CF_AGENT_RESOURCE)
|
|
@@ -9698,7 +10526,18 @@ async function runNetworkCli(args, env = process.env, io = {}, executable = "cf"
|
|
|
9698
10526
|
accessToken: tokenText(env.CF_AGENT_ACCESS_TOKEN)
|
|
9699
10527
|
};
|
|
9700
10528
|
} else profile = await refreshProfile(store, timeout);
|
|
9701
|
-
const data =
|
|
10529
|
+
const data = remoteVersion ? await withClient(
|
|
10530
|
+
profile,
|
|
10531
|
+
timeout,
|
|
10532
|
+
async (client) => ({
|
|
10533
|
+
...readNativeServerVersion(client),
|
|
10534
|
+
cli: await getNativeCliVersion(io.executablePath)
|
|
10535
|
+
}),
|
|
10536
|
+
{
|
|
10537
|
+
allowIncompatible: !options.strict,
|
|
10538
|
+
requireCompatibility: Boolean(options.strict)
|
|
10539
|
+
}
|
|
10540
|
+
) : resolveCommand(parsed).mode === "package-file" ? await downloadPackageFile(profile, input, String(options["output-file"]), timeout) : resolveCommand(parsed).mode === "media-file" ? await downloadProjectMedia(profile, input, String(options["output-file"]), timeout) : resolveCommand(parsed).mode === "upload" ? await uploadLocalMaterial(
|
|
9702
10541
|
profile,
|
|
9703
10542
|
String(options.file),
|
|
9704
10543
|
String(options["request-id"]),
|
|
@@ -9707,7 +10546,15 @@ async function runNetworkCli(args, env = process.env, io = {}, executable = "cf"
|
|
|
9707
10546
|
) : await withClient(
|
|
9708
10547
|
profile,
|
|
9709
10548
|
timeout,
|
|
9710
|
-
(client) => businessCommand(client, parsed, input, profile.resource)
|
|
10549
|
+
(client) => businessCommand(client, parsed, input, profile.resource),
|
|
10550
|
+
{
|
|
10551
|
+
onVersion: (version) => {
|
|
10552
|
+
if (version.compatibility.status === "UPGRADE_RECOMMENDED")
|
|
10553
|
+
(io.notify ?? ((message) => process.stderr.write(message + "\n")))(
|
|
10554
|
+
`The service recommends Native Marketing ${version.compatibility.server.version}. Use update check.`
|
|
10555
|
+
);
|
|
10556
|
+
}
|
|
10557
|
+
}
|
|
9711
10558
|
);
|
|
9712
10559
|
return success(command5, data);
|
|
9713
10560
|
} catch (error) {
|
|
@@ -9719,14 +10566,19 @@ function success(command5, data) {
|
|
|
9719
10566
|
}
|
|
9720
10567
|
export {
|
|
9721
10568
|
CliError as NativeAgentClientError,
|
|
10569
|
+
assessNativeCompatibility,
|
|
9722
10570
|
callNativeCapability,
|
|
9723
10571
|
callNativeTool,
|
|
10572
|
+
checkNativeUpdates,
|
|
10573
|
+
defaultUpdatePolicy,
|
|
9724
10574
|
describeNativeCapability,
|
|
9725
10575
|
findAgentCapabilities,
|
|
9726
10576
|
findNativeCapabilities,
|
|
9727
10577
|
getNativeBusinessSummary,
|
|
10578
|
+
getNativeClientVersion,
|
|
9728
10579
|
inspectNativeTool,
|
|
9729
10580
|
listNativeToolsPage,
|
|
10581
|
+
planNativeUpdate,
|
|
9730
10582
|
projectMediaFileQuerySchema,
|
|
9731
10583
|
readNativeBusinessPage,
|
|
9732
10584
|
readNativeCapability,
|