@decionis/mcp 0.3.0 → 0.4.0
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/.claude-plugin/plugin.json +1 -1
- package/README.md +9 -3
- package/dist/AgentHookCli.js +2 -2
- package/dist/ManagedAgentHookCli.js +1623 -913
- package/dist/agent/AgentIndex.js +2 -2
- package/dist/{chunk-LIVLO4MV.js → chunk-5Q6BCK32.js} +983 -273
- package/dist/chunk-5Q6BCK32.js.map +1 -0
- package/dist/{chunk-ABHNQFWI.js → chunk-GCE6PUYD.js} +2 -2
- package/dist/index.js +165 -106
- package/dist/index.js.map +1 -1
- package/package.json +22 -22
- package/dist/chunk-LIVLO4MV.js.map +0 -1
- /package/dist/{chunk-ABHNQFWI.js.map → chunk-GCE6PUYD.js.map} +0 -0
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
LocalDecionisGateway,
|
|
4
4
|
PolicyFileRepository,
|
|
5
5
|
normalizeVerdict
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5Q6BCK32.js";
|
|
7
7
|
|
|
8
8
|
// src/agent/AgentContracts.ts
|
|
9
9
|
var AgentHookInputError = class extends Error {
|
|
@@ -498,4 +498,4 @@ export {
|
|
|
498
498
|
AgentHostRegistry,
|
|
499
499
|
AgentHookCommand
|
|
500
500
|
};
|
|
501
|
-
//# sourceMappingURL=chunk-
|
|
501
|
+
//# sourceMappingURL=chunk-GCE6PUYD.js.map
|
package/dist/index.js
CHANGED
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
external_exports,
|
|
6
6
|
normalizeVerdict,
|
|
7
7
|
sha256Hex
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5Q6BCK32.js";
|
|
9
9
|
|
|
10
10
|
// src/Server.ts
|
|
11
11
|
import { createInterface } from "readline";
|
|
12
12
|
var SUPPORTED_PROTOCOL_VERSIONS = ["2025-11-25", "2025-06-18", "2025-03-26", "2024-11-05"];
|
|
13
|
-
var MCP_SERVER_VERSION = "0.
|
|
13
|
+
var MCP_SERVER_VERSION = "0.4.0";
|
|
14
14
|
var DEFAULT_PROTOCOL_VERSION = "2025-11-25";
|
|
15
15
|
var isPlainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
16
16
|
function rpcResult(id, result) {
|
|
@@ -606,7 +606,7 @@ function createDecionisTools(gateway2, additionalTools = [], options = {}) {
|
|
|
606
606
|
// src/kubernetes/KubernetesActionPlanner.ts
|
|
607
607
|
import { randomUUID } from "crypto";
|
|
608
608
|
|
|
609
|
-
//
|
|
609
|
+
// ../../../Decionis/packages/sdk-node/dist/index.js
|
|
610
610
|
import { createHash as createHash2 } from "crypto";
|
|
611
611
|
import { createHash as createHash3 } from "crypto";
|
|
612
612
|
var DEFAULT_SKEW_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -733,16 +733,10 @@ var authorityVerificationRequirementsSchema = external_exports.object({
|
|
|
733
733
|
});
|
|
734
734
|
}
|
|
735
735
|
});
|
|
736
|
-
var authorityApprovalTierSchema = external_exports.object({
|
|
737
|
-
priority: external_exports.number().int().min(1).max(5),
|
|
738
|
-
principal_ids: external_exports.array(external_exports.string().min(1).max(200)).min(1).max(10)
|
|
739
|
-
}).strict();
|
|
740
736
|
var authorityResolutionPolicySchema = external_exports.object({
|
|
741
737
|
quorum: external_exports.literal(1),
|
|
742
738
|
delegation: external_exports.enum(["DISALLOWED", "REQUIREMENT_REFRESH"]),
|
|
743
|
-
fallback_role_ids: external_exports.array(external_exports.string().regex(/^[A-Z][A-Z0-9_]{1,63}$/)).max(10).default([])
|
|
744
|
-
/** An approval chain: one valid proof from every tier satisfies the requirement. */
|
|
745
|
-
tiers: external_exports.array(authorityApprovalTierSchema).min(1).max(5).optional()
|
|
739
|
+
fallback_role_ids: external_exports.array(external_exports.string().regex(/^[A-Z][A-Z0-9_]{1,63}$/)).max(10).default([])
|
|
746
740
|
}).strict().superRefine((policy, context) => {
|
|
747
741
|
if (new Set(policy.fallback_role_ids).size !== policy.fallback_role_ids.length) {
|
|
748
742
|
context.addIssue({
|
|
@@ -751,24 +745,6 @@ var authorityResolutionPolicySchema = external_exports.object({
|
|
|
751
745
|
message: "fallback role ids must be unique"
|
|
752
746
|
});
|
|
753
747
|
}
|
|
754
|
-
if (policy.tiers) {
|
|
755
|
-
const priorities = policy.tiers.map((tier) => tier.priority);
|
|
756
|
-
if (priorities.some((priority, index) => index > 0 && priority <= priorities[index - 1])) {
|
|
757
|
-
context.addIssue({
|
|
758
|
-
code: external_exports.ZodIssueCode.custom,
|
|
759
|
-
path: ["tiers"],
|
|
760
|
-
message: "tier priorities must be unique and ascending"
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
const principals = policy.tiers.flatMap((tier) => tier.principal_ids);
|
|
764
|
-
if (new Set(principals).size !== principals.length) {
|
|
765
|
-
context.addIssue({
|
|
766
|
-
code: external_exports.ZodIssueCode.custom,
|
|
767
|
-
path: ["tiers"],
|
|
768
|
-
message: "a principal belongs to one tier only"
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
748
|
});
|
|
773
749
|
var originatorSchema = external_exports.object({
|
|
774
750
|
organization_id: external_exports.string().min(1).max(200),
|
|
@@ -834,13 +810,6 @@ var decionisAuthorityRequirementSchema = external_exports.object({
|
|
|
834
810
|
message: "fallback roles must not repeat the primary role"
|
|
835
811
|
});
|
|
836
812
|
}
|
|
837
|
-
if (requirement.resolution.tiers && requirement.selector.kind !== "ROLE") {
|
|
838
|
-
context.addIssue({
|
|
839
|
-
code: external_exports.ZodIssueCode.custom,
|
|
840
|
-
path: ["resolution", "tiers"],
|
|
841
|
-
message: "an approval chain names its members' trusted role through a ROLE selector"
|
|
842
|
-
});
|
|
843
|
-
}
|
|
844
813
|
if (requirement.orchestration?.mode === "MANAGED" && requirement.selector.kind === "PRINCIPAL" && requirement.selector.role_id === void 0) {
|
|
845
814
|
context.addIssue({
|
|
846
815
|
code: external_exports.ZodIssueCode.custom,
|
|
@@ -1023,25 +992,13 @@ function expectedManagedEscalationOutcome(status) {
|
|
|
1023
992
|
if (["EXPIRED", "REJECTED", "BLOCKED", "CANCELLED"].includes(status)) return "BLOCK";
|
|
1024
993
|
return "ESCALATE_PENDING";
|
|
1025
994
|
}
|
|
1026
|
-
var managedApprovalTierSchema = external_exports.object({
|
|
1027
|
-
tier: external_exports.number().int().min(1).max(5),
|
|
1028
|
-
tier_count: external_exports.number().int().min(1).max(5),
|
|
1029
|
-
principal_id: external_exports.string().min(1).max(200)
|
|
1030
|
-
}).strict();
|
|
1031
|
-
var managedApprovalChainSchema = external_exports.object({
|
|
1032
|
-
chain_id: external_exports.string().max(200),
|
|
1033
|
-
tier_count: external_exports.number().int().min(1).max(5),
|
|
1034
|
-
tiers_approved: external_exports.number().int().min(0).max(5)
|
|
1035
|
-
}).strict();
|
|
1036
995
|
var managedEscalationReferenceSchema = external_exports.object({
|
|
1037
996
|
outcome: managedEscalationOutcomeSchema,
|
|
1038
997
|
escalation_id: external_exports.string().min(8).max(200),
|
|
1039
998
|
intent_id: external_exports.string().min(1).max(200),
|
|
1040
999
|
status: managedEscalationStatusSchema,
|
|
1041
1000
|
expires_at: external_exports.string().datetime(),
|
|
1042
|
-
reason_codes: external_exports.array(external_exports.string().min(1).max(200)).max(50)
|
|
1043
|
-
approval_tier: managedApprovalTierSchema.nullable().optional().default(null),
|
|
1044
|
-
approval_chain: managedApprovalChainSchema.nullable().optional().default(null)
|
|
1001
|
+
reason_codes: external_exports.array(external_exports.string().min(1).max(200)).max(50)
|
|
1045
1002
|
}).strict().superRefine((reference, context) => {
|
|
1046
1003
|
if (reference.outcome !== expectedManagedEscalationOutcome(reference.status)) {
|
|
1047
1004
|
context.addIssue({
|
|
@@ -1092,8 +1049,6 @@ var managedEscalationViewSchema = external_exports.object({
|
|
|
1092
1049
|
outcome: managedEscalationOutcomeSchema,
|
|
1093
1050
|
expires_at: external_exports.string().datetime(),
|
|
1094
1051
|
reason_codes: external_exports.array(external_exports.string().min(1).max(200)).max(50),
|
|
1095
|
-
approval_tier: managedApprovalTierSchema.nullable().optional().default(null),
|
|
1096
|
-
approval_chain: managedApprovalChainSchema.nullable().optional().default(null),
|
|
1097
1052
|
decision: authorityDecisionSchema.nullable()
|
|
1098
1053
|
}).strict().superRefine((view, context) => {
|
|
1099
1054
|
if (view.outcome !== expectedManagedEscalationOutcome(view.status)) {
|
|
@@ -1379,7 +1334,6 @@ var DecionisExecutionClient = class {
|
|
|
1379
1334
|
claim_token: claimToken,
|
|
1380
1335
|
claim_validated_at: claimValidatedAt,
|
|
1381
1336
|
claim_lease_expires_at: claimLeaseExpiresAt,
|
|
1382
|
-
...typeof body.claim_attestation === "string" && body.claim_attestation.length > 0 ? { claim_attestation: body.claim_attestation } : {},
|
|
1383
1337
|
...body.evidence && typeof body.evidence === "object" ? { evidence: body.evidence } : {}
|
|
1384
1338
|
};
|
|
1385
1339
|
if (executionAuthorityProtocolSemantics(redemption) === "UNSUPPORTED") {
|
|
@@ -2356,7 +2310,7 @@ var KubectlCommandRunner = class {
|
|
|
2356
2310
|
// src/kubernetes/KubernetesOperations.ts
|
|
2357
2311
|
import { createHash as createHash4 } from "crypto";
|
|
2358
2312
|
|
|
2359
|
-
//
|
|
2313
|
+
// ../../../Decionis/packages/dossier-verify/dist/chunk-WNX2CYWD.js
|
|
2360
2314
|
import { createHash, createPublicKey, verify as verifyEd25519 } from "crypto";
|
|
2361
2315
|
import { lookup } from "dns/promises";
|
|
2362
2316
|
import { request as httpsRequest } from "https";
|
|
@@ -8465,16 +8419,90 @@ var networkRead = {
|
|
|
8465
8419
|
function createShieldPairTool(options = {}) {
|
|
8466
8420
|
const store = options.store ?? new ShieldCredentialStore();
|
|
8467
8421
|
const fetchImpl = options.fetch ?? fetch;
|
|
8468
|
-
const baseUrl = () => (options.baseUrl?.() ?? process.env.DECIONIS_SHIELD_API_URL?.trim() ?? "").replace(
|
|
8422
|
+
const baseUrl = () => (options.baseUrl?.() ?? process.env.DECIONIS_SHIELD_API_URL?.trim() ?? "").replace(
|
|
8423
|
+
/\/+$/,
|
|
8424
|
+
""
|
|
8425
|
+
) || "https://api.shield.decionis.com";
|
|
8426
|
+
const pendingEmail = /* @__PURE__ */ new Map();
|
|
8427
|
+
const post = async (path, body) => fetchImpl(`${baseUrl()}${path}`, {
|
|
8428
|
+
method: "POST",
|
|
8429
|
+
headers: {
|
|
8430
|
+
accept: "application/json",
|
|
8431
|
+
"content-type": "application/json",
|
|
8432
|
+
"x-shield-surface": "mcp"
|
|
8433
|
+
},
|
|
8434
|
+
body: JSON.stringify(body)
|
|
8435
|
+
});
|
|
8436
|
+
const unreachable = (error) => ({
|
|
8437
|
+
content: text4({
|
|
8438
|
+
error: "SHIELD_PAIRING_UNREACHABLE",
|
|
8439
|
+
message: `Could not reach Shield: ${error instanceof Error ? error.message : String(error)}. Nothing was paired.`
|
|
8440
|
+
}),
|
|
8441
|
+
isError: true
|
|
8442
|
+
});
|
|
8443
|
+
const keep = async (response, displayName, agentId, hints) => {
|
|
8444
|
+
const payload = await response.json().catch(() => null);
|
|
8445
|
+
if (response.ok && payload?.upgrade_required === true) {
|
|
8446
|
+
return {
|
|
8447
|
+
content: text4({
|
|
8448
|
+
error: "SHIELD_SOURCE_LIMIT",
|
|
8449
|
+
message: "The user's free Shield already covers its limit of spending sources. They can remove one in the Shield app or upgrade; nothing was paired."
|
|
8450
|
+
}),
|
|
8451
|
+
isError: true
|
|
8452
|
+
};
|
|
8453
|
+
}
|
|
8454
|
+
if (!response.ok || !payload || typeof payload.api_key !== "string" || typeof payload.app_id !== "string") {
|
|
8455
|
+
const code_ = payload && typeof payload.error === "string" ? payload.error : `HTTP ${response.status}`;
|
|
8456
|
+
return {
|
|
8457
|
+
content: text4({ error: code_, message: hints[code_] ?? "Nothing was paired." }),
|
|
8458
|
+
isError: true
|
|
8459
|
+
};
|
|
8460
|
+
}
|
|
8461
|
+
const integration = payload.integration ?? {};
|
|
8462
|
+
const credential = {
|
|
8463
|
+
apiKey: payload.api_key,
|
|
8464
|
+
appId: payload.app_id,
|
|
8465
|
+
baseUrl: baseUrl(),
|
|
8466
|
+
integrationId: typeof integration.integrationId === "string" ? integration.integrationId : void 0,
|
|
8467
|
+
displayName,
|
|
8468
|
+
agentId,
|
|
8469
|
+
pairedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8470
|
+
};
|
|
8471
|
+
store.write(credential);
|
|
8472
|
+
const limit = typeof payload.weekly_limit === "number" ? payload.weekly_limit : null;
|
|
8473
|
+
return {
|
|
8474
|
+
content: text4({
|
|
8475
|
+
paired: true,
|
|
8476
|
+
rotated: payload.rotated === true,
|
|
8477
|
+
displayName,
|
|
8478
|
+
weeklyLimit: limit,
|
|
8479
|
+
storedAt: store.location(),
|
|
8480
|
+
next: "The shield.* tools now ask this user's own Shield. Before any purchase, call shield.request_purchase; execute only on ALLOW."
|
|
8481
|
+
})
|
|
8482
|
+
};
|
|
8483
|
+
};
|
|
8469
8484
|
return {
|
|
8470
8485
|
name: "shield.pair",
|
|
8471
8486
|
title: "Pair with the user's Shield",
|
|
8472
|
-
description: "Bind this assistant to the user's Decionis Shield
|
|
8487
|
+
description: "Bind this assistant to the user's Decionis Shield, one of two ways. (1) The six-character pairing code shown in the Shield app (AI spending allowance \u2192 Bind your own agent): pass it as code. (2) The user's email: pass email, and Shield emails them a 6-digit code; ask the user for it, then call again with email and emailCode. Ask the user; never guess a code. After pairing, shield.request_purchase and the other shield.* tools ask the user's own spending rules.",
|
|
8473
8488
|
inputSchema: {
|
|
8474
8489
|
type: "object",
|
|
8475
|
-
required: ["code"],
|
|
8476
8490
|
properties: {
|
|
8477
|
-
code: {
|
|
8491
|
+
code: {
|
|
8492
|
+
type: "string",
|
|
8493
|
+
pattern: "^[A-Za-z0-9]{6,8}$",
|
|
8494
|
+
description: "The pairing code from the Shield app."
|
|
8495
|
+
},
|
|
8496
|
+
email: {
|
|
8497
|
+
type: "string",
|
|
8498
|
+
maxLength: 254,
|
|
8499
|
+
description: "The user's Shield email, to be sent a sign-in code."
|
|
8500
|
+
},
|
|
8501
|
+
emailCode: {
|
|
8502
|
+
type: "string",
|
|
8503
|
+
pattern: "^[0-9]{6}$",
|
|
8504
|
+
description: "The 6-digit code Shield emailed to the user."
|
|
8505
|
+
},
|
|
8478
8506
|
displayName: {
|
|
8479
8507
|
type: "string",
|
|
8480
8508
|
maxLength: 120,
|
|
@@ -8485,63 +8513,94 @@ function createShieldPairTool(options = {}) {
|
|
|
8485
8513
|
},
|
|
8486
8514
|
annotations: networkMutation,
|
|
8487
8515
|
handler: async (args) => {
|
|
8488
|
-
const code = typeof args.code === "string" ? args.code.trim().toUpperCase() : "";
|
|
8489
|
-
if (!/^[A-Z0-9]{6,8}$/.test(code)) {
|
|
8490
|
-
return { content: text4("A pairing code is 6 to 8 letters and digits. Ask the user for the code shown in the Shield app."), isError: true };
|
|
8491
|
-
}
|
|
8492
8516
|
const displayName = typeof args.displayName === "string" && args.displayName.trim() ? args.displayName.trim().slice(0, 120) : defaultAgentDisplayName(options.clientName?.());
|
|
8493
|
-
const
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
8506
|
-
|
|
8517
|
+
const agent = {
|
|
8518
|
+
app_id: SHIELD_MCP_APP_ID,
|
|
8519
|
+
agent_id: store.agentId(),
|
|
8520
|
+
display_name: displayName
|
|
8521
|
+
};
|
|
8522
|
+
const email = typeof args.email === "string" ? args.email.trim().toLowerCase() : "";
|
|
8523
|
+
const emailCode = typeof args.emailCode === "string" ? args.emailCode.trim() : "";
|
|
8524
|
+
if (email) {
|
|
8525
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
8526
|
+
return {
|
|
8527
|
+
content: text4(
|
|
8528
|
+
"That is not an email address. Ask the user for the email they use with Shield."
|
|
8529
|
+
),
|
|
8530
|
+
isError: true
|
|
8531
|
+
};
|
|
8532
|
+
}
|
|
8533
|
+
if (!emailCode) {
|
|
8534
|
+
let response3;
|
|
8535
|
+
try {
|
|
8536
|
+
response3 = await post("/v1/consumer/auth/start", { email, scope: "agent" });
|
|
8537
|
+
} catch (error) {
|
|
8538
|
+
return unreachable(error);
|
|
8539
|
+
}
|
|
8540
|
+
const payload = await response3.json().catch(() => null);
|
|
8541
|
+
if (!response3.ok || !payload || typeof payload.challenge_id !== "string") {
|
|
8542
|
+
return {
|
|
8543
|
+
content: text4({
|
|
8544
|
+
error: response3.status === 429 ? "SHIELD_TOO_MANY_CODES" : `HTTP ${response3.status}`,
|
|
8545
|
+
message: response3.status === 429 ? "Shield has sent several codes already. Wait a minute, then try again." : "Shield could not send a code right now. Nothing was paired."
|
|
8546
|
+
}),
|
|
8547
|
+
isError: true
|
|
8548
|
+
};
|
|
8549
|
+
}
|
|
8550
|
+
pendingEmail.set(email, payload.challenge_id);
|
|
8551
|
+
return {
|
|
8552
|
+
content: text4({
|
|
8553
|
+
emailed: true,
|
|
8554
|
+
email,
|
|
8555
|
+
next: `Ask the user for the 6-digit code Shield just emailed to ${email}, then call shield.pair again with email and emailCode.`
|
|
8556
|
+
})
|
|
8557
|
+
};
|
|
8558
|
+
}
|
|
8559
|
+
if (!/^[0-9]{6}$/.test(emailCode)) {
|
|
8560
|
+
return {
|
|
8561
|
+
content: text4(
|
|
8562
|
+
"The emailed code is 6 digits. Ask the user to read it from the Shield email."
|
|
8563
|
+
),
|
|
8564
|
+
isError: true
|
|
8565
|
+
};
|
|
8566
|
+
}
|
|
8567
|
+
let response2;
|
|
8568
|
+
try {
|
|
8569
|
+
response2 = await post("/v1/consumer/auth/verify", {
|
|
8570
|
+
email,
|
|
8571
|
+
code: emailCode,
|
|
8572
|
+
...pendingEmail.has(email) ? { challenge_id: pendingEmail.get(email) } : {},
|
|
8573
|
+
scope: "agent",
|
|
8574
|
+
agent
|
|
8575
|
+
});
|
|
8576
|
+
} catch (error) {
|
|
8577
|
+
return unreachable(error);
|
|
8578
|
+
}
|
|
8579
|
+
if (response2.ok) pendingEmail.delete(email);
|
|
8580
|
+
return keep(response2, displayName, agent.agent_id, {
|
|
8581
|
+
INVALID_CODE: "The code is wrong or has expired (five minutes). Ask the user for the newest code, or call shield.pair with email again to send a fresh one.",
|
|
8582
|
+
OTP_TOO_MANY_ATTEMPTS: "Too many wrong codes for that email. Call shield.pair with email again to send a fresh one.",
|
|
8583
|
+
CHALLENGE_NOT_FOUND: "No code is waiting for that email. Call shield.pair with email first."
|
|
8507
8584
|
});
|
|
8508
|
-
}
|
|
8585
|
+
}
|
|
8586
|
+
const code = typeof args.code === "string" ? args.code.trim().toUpperCase() : "";
|
|
8587
|
+
if (!/^[A-Z0-9]{6,8}$/.test(code)) {
|
|
8509
8588
|
return {
|
|
8510
|
-
content: text4(
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
}),
|
|
8589
|
+
content: text4(
|
|
8590
|
+
"Give either the pairing code shown in the Shield app (6 to 8 letters and digits) or the user's email. Ask the user; never guess."
|
|
8591
|
+
),
|
|
8514
8592
|
isError: true
|
|
8515
8593
|
};
|
|
8516
8594
|
}
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
return
|
|
8595
|
+
let response;
|
|
8596
|
+
try {
|
|
8597
|
+
response = await post("/v1/consumer/pairing/claim", { code, agent });
|
|
8598
|
+
} catch (error) {
|
|
8599
|
+
return unreachable(error);
|
|
8522
8600
|
}
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
appId: payload.app_id,
|
|
8527
|
-
baseUrl: baseUrl(),
|
|
8528
|
-
integrationId: typeof integration.integrationId === "string" ? integration.integrationId : void 0,
|
|
8529
|
-
displayName,
|
|
8530
|
-
agentId,
|
|
8531
|
-
pairedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8532
|
-
};
|
|
8533
|
-
store.write(credential);
|
|
8534
|
-
const limit = typeof payload.weekly_limit === "number" ? payload.weekly_limit : null;
|
|
8535
|
-
return {
|
|
8536
|
-
content: text4({
|
|
8537
|
-
paired: true,
|
|
8538
|
-
rotated: payload.rotated === true,
|
|
8539
|
-
displayName,
|
|
8540
|
-
weeklyLimit: limit,
|
|
8541
|
-
storedAt: store.location(),
|
|
8542
|
-
next: "The shield.* tools now ask this user's own Shield. Before any purchase, call shield.request_purchase; execute only on ALLOW."
|
|
8543
|
-
})
|
|
8544
|
-
};
|
|
8601
|
+
return keep(response, displayName, agent.agent_id, {
|
|
8602
|
+
PAIRING_CODE_INVALID: "The code is wrong, expired (ten minutes) or already used. Ask the user for a fresh one from the Shield app."
|
|
8603
|
+
});
|
|
8545
8604
|
}
|
|
8546
8605
|
};
|
|
8547
8606
|
}
|