@cmo-so/mcp 0.9.1 → 0.9.3
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/cmo-mcp.mjs +347 -194
- package/package.json +1 -1
package/dist/cmo-mcp.mjs
CHANGED
|
@@ -449,9 +449,9 @@ var require_codegen = __commonJS({
|
|
|
449
449
|
}
|
|
450
450
|
};
|
|
451
451
|
var Label = class extends Node {
|
|
452
|
-
constructor(
|
|
452
|
+
constructor(label2) {
|
|
453
453
|
super();
|
|
454
|
-
this.label =
|
|
454
|
+
this.label = label2;
|
|
455
455
|
this.names = {};
|
|
456
456
|
}
|
|
457
457
|
render({ _n }) {
|
|
@@ -459,14 +459,14 @@ var require_codegen = __commonJS({
|
|
|
459
459
|
}
|
|
460
460
|
};
|
|
461
461
|
var Break = class extends Node {
|
|
462
|
-
constructor(
|
|
462
|
+
constructor(label2) {
|
|
463
463
|
super();
|
|
464
|
-
this.label =
|
|
464
|
+
this.label = label2;
|
|
465
465
|
this.names = {};
|
|
466
466
|
}
|
|
467
467
|
render({ _n }) {
|
|
468
|
-
const
|
|
469
|
-
return `break${
|
|
468
|
+
const label2 = this.label ? ` ${this.label}` : "";
|
|
469
|
+
return `break${label2};` + _n;
|
|
470
470
|
}
|
|
471
471
|
};
|
|
472
472
|
var Throw = class extends Node {
|
|
@@ -506,17 +506,17 @@ var require_codegen = __commonJS({
|
|
|
506
506
|
this.nodes = nodes;
|
|
507
507
|
}
|
|
508
508
|
render(opts) {
|
|
509
|
-
return this.nodes.reduce((code,
|
|
509
|
+
return this.nodes.reduce((code, n2) => code + n2.render(opts), "");
|
|
510
510
|
}
|
|
511
511
|
optimizeNodes() {
|
|
512
512
|
const { nodes } = this;
|
|
513
513
|
let i = nodes.length;
|
|
514
514
|
while (i--) {
|
|
515
|
-
const
|
|
516
|
-
if (Array.isArray(
|
|
517
|
-
nodes.splice(i, 1, ...
|
|
518
|
-
else if (
|
|
519
|
-
nodes[i] =
|
|
515
|
+
const n2 = nodes[i].optimizeNodes();
|
|
516
|
+
if (Array.isArray(n2))
|
|
517
|
+
nodes.splice(i, 1, ...n2);
|
|
518
|
+
else if (n2)
|
|
519
|
+
nodes[i] = n2;
|
|
520
520
|
else
|
|
521
521
|
nodes.splice(i, 1);
|
|
522
522
|
}
|
|
@@ -526,16 +526,16 @@ var require_codegen = __commonJS({
|
|
|
526
526
|
const { nodes } = this;
|
|
527
527
|
let i = nodes.length;
|
|
528
528
|
while (i--) {
|
|
529
|
-
const
|
|
530
|
-
if (
|
|
529
|
+
const n2 = nodes[i];
|
|
530
|
+
if (n2.optimizeNames(names, constants))
|
|
531
531
|
continue;
|
|
532
|
-
subtractNames(names,
|
|
532
|
+
subtractNames(names, n2.names);
|
|
533
533
|
nodes.splice(i, 1);
|
|
534
534
|
}
|
|
535
535
|
return nodes.length > 0 ? this : void 0;
|
|
536
536
|
}
|
|
537
537
|
get names() {
|
|
538
|
-
return this.nodes.reduce((names,
|
|
538
|
+
return this.nodes.reduce((names, n2) => addNames(names, n2.names), {});
|
|
539
539
|
}
|
|
540
540
|
};
|
|
541
541
|
var BlockNode = class extends ParentNode {
|
|
@@ -878,12 +878,12 @@ var require_codegen = __commonJS({
|
|
|
878
878
|
return this._endBlockNode(For);
|
|
879
879
|
}
|
|
880
880
|
// `label` statement
|
|
881
|
-
label(
|
|
882
|
-
return this._leafNode(new Label(
|
|
881
|
+
label(label2) {
|
|
882
|
+
return this._leafNode(new Label(label2));
|
|
883
883
|
}
|
|
884
884
|
// `break` statement
|
|
885
|
-
break(
|
|
886
|
-
return this._leafNode(new Break(
|
|
885
|
+
break(label2) {
|
|
886
|
+
return this._leafNode(new Break(label2));
|
|
887
887
|
}
|
|
888
888
|
// `return` statement
|
|
889
889
|
return(value) {
|
|
@@ -946,8 +946,8 @@ var require_codegen = __commonJS({
|
|
|
946
946
|
endFunc() {
|
|
947
947
|
return this._endBlockNode(Func);
|
|
948
948
|
}
|
|
949
|
-
optimize(
|
|
950
|
-
while (
|
|
949
|
+
optimize(n2 = 1) {
|
|
950
|
+
while (n2-- > 0) {
|
|
951
951
|
this._root.optimizeNodes();
|
|
952
952
|
this._root.optimizeNames(this._root.names, this._constants);
|
|
953
953
|
}
|
|
@@ -961,19 +961,19 @@ var require_codegen = __commonJS({
|
|
|
961
961
|
this._nodes.push(node2);
|
|
962
962
|
}
|
|
963
963
|
_endBlockNode(N1, N2) {
|
|
964
|
-
const
|
|
965
|
-
if (
|
|
964
|
+
const n2 = this._currNode;
|
|
965
|
+
if (n2 instanceof N1 || N2 && n2 instanceof N2) {
|
|
966
966
|
this._nodes.pop();
|
|
967
967
|
return this;
|
|
968
968
|
}
|
|
969
969
|
throw new Error(`CodeGen: not in block "${N2 ? `${N1.kind}/${N2.kind}` : N1.kind}"`);
|
|
970
970
|
}
|
|
971
971
|
_elseNode(node2) {
|
|
972
|
-
const
|
|
973
|
-
if (!(
|
|
972
|
+
const n2 = this._currNode;
|
|
973
|
+
if (!(n2 instanceof If)) {
|
|
974
974
|
throw new Error('CodeGen: "else" without "if"');
|
|
975
975
|
}
|
|
976
|
-
this._currNode =
|
|
976
|
+
this._currNode = n2.else = node2;
|
|
977
977
|
return this;
|
|
978
978
|
}
|
|
979
979
|
get _root() {
|
|
@@ -990,8 +990,8 @@ var require_codegen = __commonJS({
|
|
|
990
990
|
};
|
|
991
991
|
exports.CodeGen = CodeGen;
|
|
992
992
|
function addNames(names, from) {
|
|
993
|
-
for (const
|
|
994
|
-
names[
|
|
993
|
+
for (const n2 in from)
|
|
994
|
+
names[n2] = (names[n2] || 0) + (from[n2] || 0);
|
|
995
995
|
return names;
|
|
996
996
|
}
|
|
997
997
|
function addExprNames(names, from) {
|
|
@@ -1002,20 +1002,20 @@ var require_codegen = __commonJS({
|
|
|
1002
1002
|
return replaceName(expr);
|
|
1003
1003
|
if (!canOptimize(expr))
|
|
1004
1004
|
return expr;
|
|
1005
|
-
return new code_1._Code(expr._items.reduce((
|
|
1005
|
+
return new code_1._Code(expr._items.reduce((items2, c) => {
|
|
1006
1006
|
if (c instanceof code_1.Name)
|
|
1007
1007
|
c = replaceName(c);
|
|
1008
1008
|
if (c instanceof code_1._Code)
|
|
1009
|
-
|
|
1009
|
+
items2.push(...c._items);
|
|
1010
1010
|
else
|
|
1011
|
-
|
|
1012
|
-
return
|
|
1011
|
+
items2.push(c);
|
|
1012
|
+
return items2;
|
|
1013
1013
|
}, []));
|
|
1014
|
-
function replaceName(
|
|
1015
|
-
const c = constants[
|
|
1016
|
-
if (c === void 0 || names[
|
|
1017
|
-
return
|
|
1018
|
-
delete names[
|
|
1014
|
+
function replaceName(n2) {
|
|
1015
|
+
const c = constants[n2.str];
|
|
1016
|
+
if (c === void 0 || names[n2.str] !== 1)
|
|
1017
|
+
return n2;
|
|
1018
|
+
delete names[n2.str];
|
|
1019
1019
|
return c;
|
|
1020
1020
|
}
|
|
1021
1021
|
function canOptimize(e) {
|
|
@@ -1023,8 +1023,8 @@ var require_codegen = __commonJS({
|
|
|
1023
1023
|
}
|
|
1024
1024
|
}
|
|
1025
1025
|
function subtractNames(names, from) {
|
|
1026
|
-
for (const
|
|
1027
|
-
names[
|
|
1026
|
+
for (const n2 in from)
|
|
1027
|
+
names[n2] = (names[n2] || 0) - (from[n2] || 0);
|
|
1028
1028
|
}
|
|
1029
1029
|
function not(x) {
|
|
1030
1030
|
return typeof x == "boolean" || typeof x == "number" || x === null ? !x : (0, code_1._)`!${par(x)}`;
|
|
@@ -1167,7 +1167,7 @@ var require_util = __commonJS({
|
|
|
1167
1167
|
mergeNames: (gen, from, to) => gen.if((0, codegen_1._)`${to} !== true && ${from} !== undefined`, () => gen.assign(to, (0, codegen_1._)`${from} === true ? true : ${to} > ${from} ? ${to} : ${from}`)),
|
|
1168
1168
|
mergeToName: (gen, from, to) => gen.if((0, codegen_1._)`${to} !== true`, () => gen.assign(to, from === true ? true : (0, codegen_1._)`${to} > ${from} ? ${to} : ${from}`)),
|
|
1169
1169
|
mergeValues: (from, to) => from === true ? true : Math.max(from, to),
|
|
1170
|
-
resultToName: (gen,
|
|
1170
|
+
resultToName: (gen, items2) => gen.var("items", items2)
|
|
1171
1171
|
})
|
|
1172
1172
|
};
|
|
1173
1173
|
function evaluatedPropsToName(gen, ps) {
|
|
@@ -1361,12 +1361,12 @@ var require_errors = __commonJS({
|
|
|
1361
1361
|
}
|
|
1362
1362
|
return [E.schemaPath, schPath];
|
|
1363
1363
|
}
|
|
1364
|
-
function extraErrorProps(cxt, { params, message }, keyValues) {
|
|
1364
|
+
function extraErrorProps(cxt, { params, message: message2 }, keyValues) {
|
|
1365
1365
|
const { keyword, data, schemaValue, it } = cxt;
|
|
1366
1366
|
const { opts, propertyName, topSchemaRef, schemaPath } = it;
|
|
1367
1367
|
keyValues.push([E.keyword, keyword], [E.params, typeof params == "function" ? params(cxt) : params || (0, codegen_1._)`{}`]);
|
|
1368
1368
|
if (opts.messages) {
|
|
1369
|
-
keyValues.push([E.message, typeof
|
|
1369
|
+
keyValues.push([E.message, typeof message2 == "function" ? message2(cxt) : message2]);
|
|
1370
1370
|
}
|
|
1371
1371
|
if (opts.verbose) {
|
|
1372
1372
|
keyValues.push([E.schema, schemaValue], [E.parentSchema, (0, codegen_1._)`${topSchemaRef}${schemaPath}`], [names_1.default.data, data]);
|
|
@@ -1675,13 +1675,13 @@ var require_defaults = __commonJS({
|
|
|
1675
1675
|
var codegen_1 = require_codegen();
|
|
1676
1676
|
var util_1 = require_util();
|
|
1677
1677
|
function assignDefaults(it, ty) {
|
|
1678
|
-
const { properties, items } = it.schema;
|
|
1678
|
+
const { properties, items: items2 } = it.schema;
|
|
1679
1679
|
if (ty === "object" && properties) {
|
|
1680
1680
|
for (const key in properties) {
|
|
1681
1681
|
assignDefault(it, key, properties[key].default);
|
|
1682
1682
|
}
|
|
1683
|
-
} else if (ty === "array" && Array.isArray(
|
|
1684
|
-
|
|
1683
|
+
} else if (ty === "array" && Array.isArray(items2)) {
|
|
1684
|
+
items2.forEach((sch, i) => assignDefault(it, i, sch.default));
|
|
1685
1685
|
}
|
|
1686
1686
|
}
|
|
1687
1687
|
exports.assignDefaults = assignDefaults;
|
|
@@ -2485,11 +2485,11 @@ var require_validate = __commonJS({
|
|
|
2485
2485
|
gen.return((0, codegen_1._)`${names_1.default.errors} === 0`);
|
|
2486
2486
|
}
|
|
2487
2487
|
}
|
|
2488
|
-
function assignEvaluated({ gen, evaluated, props, items }) {
|
|
2488
|
+
function assignEvaluated({ gen, evaluated, props, items: items2 }) {
|
|
2489
2489
|
if (props instanceof codegen_1.Name)
|
|
2490
2490
|
gen.assign((0, codegen_1._)`${evaluated}.props`, props);
|
|
2491
|
-
if (
|
|
2492
|
-
gen.assign((0, codegen_1._)`${evaluated}.items`,
|
|
2491
|
+
if (items2 instanceof codegen_1.Name)
|
|
2492
|
+
gen.assign((0, codegen_1._)`${evaluated}.items`, items2);
|
|
2493
2493
|
}
|
|
2494
2494
|
function schemaKeywords(it, types, typeErrors, errsCount) {
|
|
2495
2495
|
const { gen, schema, data, allErrors, opts, self } = it;
|
|
@@ -2952,12 +2952,12 @@ var require_compile = __commonJS({
|
|
|
2952
2952
|
validate2.source = { validateName, validateCode, scopeValues: gen._values };
|
|
2953
2953
|
}
|
|
2954
2954
|
if (this.opts.unevaluated) {
|
|
2955
|
-
const { props, items } = schemaCxt;
|
|
2955
|
+
const { props, items: items2 } = schemaCxt;
|
|
2956
2956
|
validate2.evaluated = {
|
|
2957
2957
|
props: props instanceof codegen_1.Name ? void 0 : props,
|
|
2958
|
-
items:
|
|
2958
|
+
items: items2 instanceof codegen_1.Name ? void 0 : items2,
|
|
2959
2959
|
dynamicProps: props instanceof codegen_1.Name,
|
|
2960
|
-
dynamicItems:
|
|
2960
|
+
dynamicItems: items2 instanceof codegen_1.Name
|
|
2961
2961
|
};
|
|
2962
2962
|
if (validate2.source)
|
|
2963
2963
|
validate2.source.evaluated = (0, codegen_1.stringify)(validate2.evaluated);
|
|
@@ -4496,11 +4496,11 @@ var require_core = __commonJS({
|
|
|
4496
4496
|
}
|
|
4497
4497
|
const valid = this.validate($schema, schema);
|
|
4498
4498
|
if (!valid && throwOrLogError) {
|
|
4499
|
-
const
|
|
4499
|
+
const message2 = "schema is invalid: " + this.errorsText();
|
|
4500
4500
|
if (this.opts.validateSchema === "log")
|
|
4501
|
-
this.logger.error(
|
|
4501
|
+
this.logger.error(message2);
|
|
4502
4502
|
else
|
|
4503
|
-
throw new Error(
|
|
4503
|
+
throw new Error(message2);
|
|
4504
4504
|
}
|
|
4505
4505
|
return valid;
|
|
4506
4506
|
}
|
|
@@ -4967,8 +4967,8 @@ var require_ref = __commonJS({
|
|
|
4967
4967
|
it.items = util_1.mergeEvaluated.items(gen, schEvaluated.items, it.items);
|
|
4968
4968
|
}
|
|
4969
4969
|
} else {
|
|
4970
|
-
const
|
|
4971
|
-
it.items = util_1.mergeEvaluated.items(gen,
|
|
4970
|
+
const items2 = gen.var("items", (0, codegen_1._)`${source}.evaluated.items`);
|
|
4971
|
+
it.items = util_1.mergeEvaluated.items(gen, items2, it.items, codegen_1.Name);
|
|
4972
4972
|
}
|
|
4973
4973
|
}
|
|
4974
4974
|
}
|
|
@@ -5508,28 +5508,28 @@ var require_additionalItems = __commonJS({
|
|
|
5508
5508
|
error: error2,
|
|
5509
5509
|
code(cxt) {
|
|
5510
5510
|
const { parentSchema, it } = cxt;
|
|
5511
|
-
const { items } = parentSchema;
|
|
5512
|
-
if (!Array.isArray(
|
|
5511
|
+
const { items: items2 } = parentSchema;
|
|
5512
|
+
if (!Array.isArray(items2)) {
|
|
5513
5513
|
(0, util_1.checkStrictMode)(it, '"additionalItems" is ignored when "items" is not an array of schemas');
|
|
5514
5514
|
return;
|
|
5515
5515
|
}
|
|
5516
|
-
validateAdditionalItems(cxt,
|
|
5516
|
+
validateAdditionalItems(cxt, items2);
|
|
5517
5517
|
}
|
|
5518
5518
|
};
|
|
5519
|
-
function validateAdditionalItems(cxt,
|
|
5519
|
+
function validateAdditionalItems(cxt, items2) {
|
|
5520
5520
|
const { gen, schema, data, keyword, it } = cxt;
|
|
5521
5521
|
it.items = true;
|
|
5522
5522
|
const len = gen.const("len", (0, codegen_1._)`${data}.length`);
|
|
5523
5523
|
if (schema === false) {
|
|
5524
|
-
cxt.setParams({ len:
|
|
5525
|
-
cxt.pass((0, codegen_1._)`${len} <= ${
|
|
5524
|
+
cxt.setParams({ len: items2.length });
|
|
5525
|
+
cxt.pass((0, codegen_1._)`${len} <= ${items2.length}`);
|
|
5526
5526
|
} else if (typeof schema == "object" && !(0, util_1.alwaysValidSchema)(it, schema)) {
|
|
5527
|
-
const valid = gen.var("valid", (0, codegen_1._)`${len} <= ${
|
|
5527
|
+
const valid = gen.var("valid", (0, codegen_1._)`${len} <= ${items2.length}`);
|
|
5528
5528
|
gen.if((0, codegen_1.not)(valid), () => validateItems(valid));
|
|
5529
5529
|
cxt.ok(valid);
|
|
5530
5530
|
}
|
|
5531
5531
|
function validateItems(valid) {
|
|
5532
|
-
gen.forRange("i",
|
|
5532
|
+
gen.forRange("i", items2.length, len, (i) => {
|
|
5533
5533
|
cxt.subschema({ keyword, dataProp: i, dataPropType: util_1.Type.Num }, valid);
|
|
5534
5534
|
if (!it.allErrors)
|
|
5535
5535
|
gen.if((0, codegen_1.not)(valid), () => gen.break());
|
|
@@ -7199,7 +7199,7 @@ var require_dist = __commonJS({
|
|
|
7199
7199
|
// package.json
|
|
7200
7200
|
var package_default = {
|
|
7201
7201
|
name: "@cmo-so/cli",
|
|
7202
|
-
version: "0.9.
|
|
7202
|
+
version: "0.9.3",
|
|
7203
7203
|
description: "CMO.so on the command line: your websites, ideas, blog posts, LinkedIn queue and results, plus a local MCP server for Claude Desktop, Cursor and other MCP clients.",
|
|
7204
7204
|
type: "module",
|
|
7205
7205
|
license: "MIT",
|
|
@@ -7271,14 +7271,14 @@ var OAuthError = class extends Error {
|
|
|
7271
7271
|
}
|
|
7272
7272
|
};
|
|
7273
7273
|
var SignInRequiredError = class extends Error {
|
|
7274
|
-
constructor(
|
|
7275
|
-
super(
|
|
7274
|
+
constructor(message2 = "Please sign in again.") {
|
|
7275
|
+
super(message2);
|
|
7276
7276
|
this.name = "SignInRequiredError";
|
|
7277
7277
|
}
|
|
7278
7278
|
};
|
|
7279
7279
|
var ApiError = class extends Error {
|
|
7280
|
-
constructor(status,
|
|
7281
|
-
super(
|
|
7280
|
+
constructor(status, message2, requestId, detail = null) {
|
|
7281
|
+
super(message2);
|
|
7282
7282
|
this.status = status;
|
|
7283
7283
|
this.requestId = requestId;
|
|
7284
7284
|
this.detail = detail;
|
|
@@ -7508,10 +7508,10 @@ function createApi({ baseUrl, session: session2, fetch: fetchImpl = globalThis.f
|
|
|
7508
7508
|
}),
|
|
7509
7509
|
models: () => request("/v1/maggie/bridge/models"),
|
|
7510
7510
|
/** Add a ChatGPT account to the bridge (then connect it). */
|
|
7511
|
-
addAccount: (
|
|
7511
|
+
addAccount: (label2) => request("/v1/maggie/bridge/accounts", {
|
|
7512
7512
|
method: "POST",
|
|
7513
7513
|
headers: { "Content-Type": "application/json" },
|
|
7514
|
-
body: JSON.stringify({ label:
|
|
7514
|
+
body: JSON.stringify({ label: label2 ?? null })
|
|
7515
7515
|
}),
|
|
7516
7516
|
/** Make one of the bridge's ChatGPT accounts the one that answers. */
|
|
7517
7517
|
chooseAccount: (id) => request(`/v1/maggie/bridge/accounts/${encodeURIComponent(id)}/use`, { method: "POST" }),
|
|
@@ -7530,8 +7530,8 @@ function createApi({ baseUrl, session: session2, fetch: fetchImpl = globalThis.f
|
|
|
7530
7530
|
/** The user has read the team's latest reply or status change. */
|
|
7531
7531
|
seen: (id) => request(`/v1/feedback/${encodeURIComponent(id)}/seen`, { method: "POST" }),
|
|
7532
7532
|
/** One of the user's feedback photos as a data: URL (an <Image> source on web and native). */
|
|
7533
|
-
photo: async (id,
|
|
7534
|
-
const { type, bytes } = await requestBytes(`/v1/feedback/${encodeURIComponent(id)}/photos/${
|
|
7533
|
+
photo: async (id, n2) => {
|
|
7534
|
+
const { type, bytes } = await requestBytes(`/v1/feedback/${encodeURIComponent(id)}/photos/${n2}`);
|
|
7535
7535
|
return dataUrl(type, bytes);
|
|
7536
7536
|
}
|
|
7537
7537
|
},
|
|
@@ -7581,8 +7581,8 @@ function errorMessage(data, status) {
|
|
|
7581
7581
|
const detail = data?.detail;
|
|
7582
7582
|
if (typeof detail === "string" && detail) return detail;
|
|
7583
7583
|
if (detail && typeof detail === "object" && !Array.isArray(detail)) {
|
|
7584
|
-
const
|
|
7585
|
-
if (typeof
|
|
7584
|
+
const message2 = detail.message;
|
|
7585
|
+
if (typeof message2 === "string" && message2) return message2;
|
|
7586
7586
|
}
|
|
7587
7587
|
if (Array.isArray(detail)) {
|
|
7588
7588
|
const first = detail[0];
|
|
@@ -7600,8 +7600,8 @@ function dataUrl(type, bytes) {
|
|
|
7600
7600
|
const parts = [];
|
|
7601
7601
|
let chunk = "";
|
|
7602
7602
|
for (let i = 0; i < b.length; i += 3) {
|
|
7603
|
-
const
|
|
7604
|
-
chunk += B64.charAt(
|
|
7603
|
+
const n2 = (b[i] ?? 0) << 16 | (b[i + 1] ?? 0) << 8 | (b[i + 2] ?? 0);
|
|
7604
|
+
chunk += B64.charAt(n2 >> 18 & 63) + B64.charAt(n2 >> 12 & 63) + (i + 1 < b.length ? B64.charAt(n2 >> 6 & 63) : "=") + (i + 2 < b.length ? B64.charAt(n2 & 63) : "=");
|
|
7605
7605
|
if (chunk.length >= 8192) {
|
|
7606
7606
|
parts.push(chunk);
|
|
7607
7607
|
chunk = "";
|
|
@@ -7784,8 +7784,14 @@ function domainApi(api2, domain) {
|
|
|
7784
7784
|
/** How a posted Instagram post is doing (read from Instagram, kept 15 minutes; `refresh` reads again). */
|
|
7785
7785
|
socialInsights: (id, refresh = false) => api2.request(`${base}/social/${id}/insights${refresh ? "?refresh=true" : ""}`),
|
|
7786
7786
|
deletePostedSocial: (id) => api2.request(`${base}/social/${id}/published`, { method: "DELETE" }),
|
|
7787
|
-
/**
|
|
7788
|
-
|
|
7787
|
+
/**
|
|
7788
|
+
* Change a posted post. LinkedIn changes its text in place (likes and comments stay); with `repost`, and on
|
|
7789
|
+
* the other channels, the old one comes down and the new text goes out now.
|
|
7790
|
+
*/
|
|
7791
|
+
republishSocial: (id, socialCopy, repost = false) => post(`${base}/social/${id}/republish`, {
|
|
7792
|
+
...socialCopy ? { social_copy: socialCopy } : {},
|
|
7793
|
+
...repost ? { repost: true } : {}
|
|
7794
|
+
}),
|
|
7789
7795
|
restoreSocial: (id) => post(`${base}/social/${id}/restore`),
|
|
7790
7796
|
pauseSocial: () => post(`${base}/social/pause`),
|
|
7791
7797
|
/**
|
|
@@ -8463,8 +8469,8 @@ function cleanSitemap(entry, domain) {
|
|
|
8463
8469
|
if (!url) return "The sitemap must be a web address starting with http:// or https://.";
|
|
8464
8470
|
let owner = SITEMAP_OWNERS.includes(entry.owner) ? entry.owner : "other";
|
|
8465
8471
|
if (owner === "own" && domain && !onWebsite(url, domain)) owner = "other";
|
|
8466
|
-
const
|
|
8467
|
-
const out = { ...entry, url, owner, label:
|
|
8472
|
+
const label2 = (entry.label ?? "").trim().slice(0, SITEMAP_LABEL_MAX);
|
|
8473
|
+
const out = { ...entry, url, owner, label: label2 || null, uses: sitemapUses(owner, entry.uses) };
|
|
8468
8474
|
if (!out.id) delete out.id;
|
|
8469
8475
|
return out;
|
|
8470
8476
|
}
|
|
@@ -8481,8 +8487,8 @@ function checkSitemaps(list2) {
|
|
|
8481
8487
|
function sitemapCheckLine(check) {
|
|
8482
8488
|
if (!check || check.status === "unchecked") return "Checked when you save";
|
|
8483
8489
|
if (check.status === "error") return check.error?.trim() || "Couldn't read this sitemap.";
|
|
8484
|
-
const
|
|
8485
|
-
const found =
|
|
8490
|
+
const n2 = check.url_count;
|
|
8491
|
+
const found = n2 == null ? "Read" : `Found ${n2.toLocaleString("en-GB")} ${n2 === 1 ? "page" : "pages"}`;
|
|
8486
8492
|
const at = check.checked_at ? new Date(check.checked_at) : null;
|
|
8487
8493
|
const when = at && !Number.isNaN(at.getTime()) ? at.toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" }) : null;
|
|
8488
8494
|
return when ? `${found} \xB7 checked ${when}` : found;
|
|
@@ -8510,13 +8516,13 @@ var named = (title, id) => {
|
|
|
8510
8516
|
const s = String(id ?? "").trim();
|
|
8511
8517
|
return s && s.length <= 8 ? ` #${s}` : "";
|
|
8512
8518
|
};
|
|
8513
|
-
var list = (xs,
|
|
8519
|
+
var list = (xs, n2 = 5) => {
|
|
8514
8520
|
const a = (Array.isArray(xs) ? xs : xs == null ? [] : [xs]).map(String);
|
|
8515
|
-
return a.length >
|
|
8521
|
+
return a.length > n2 ? `${a.slice(0, n2).join(", ")} +${a.length - n2}` : a.join(", ");
|
|
8516
8522
|
};
|
|
8517
|
-
var placeEn = (p,
|
|
8523
|
+
var placeEn = (p, items2 = "posts") => {
|
|
8518
8524
|
const t = String(p ?? "").trim().toLowerCase();
|
|
8519
|
-
if (t === "end") return `at the end of the queue, after the ${
|
|
8525
|
+
if (t === "end") return `at the end of the queue, after the ${items2} already waiting`;
|
|
8520
8526
|
if (t === "random") return "at a random place in the queue";
|
|
8521
8527
|
if (/^\d+$/.test(t)) return Number(t) === 0 ? null : `after the first ${t} in the queue`;
|
|
8522
8528
|
return null;
|
|
@@ -8607,13 +8613,13 @@ var confirmCopy = {
|
|
|
8607
8613
|
sitemap_upsert: {
|
|
8608
8614
|
en: (a) => {
|
|
8609
8615
|
const whose = { own: "your site's ", competitor: "a competitor's ", other: "another site's " }[a.owner];
|
|
8610
|
-
const
|
|
8611
|
-
return a.url ? `Save ${whose ?? "the "}sitemap ${a.url}${
|
|
8616
|
+
const label2 = a.label ? ` (${q(a.label)})` : "";
|
|
8617
|
+
return a.url ? `Save ${whose ?? "the "}sitemap ${a.url}${label2}.` : `Change the sitemap${label2}: ${keys(a).filter((k) => k !== "id").join(", ")}.`;
|
|
8612
8618
|
},
|
|
8613
8619
|
"zh-Hant": (a) => {
|
|
8614
8620
|
const whose = { own: "\u81EA\u5DF1\u7DB2\u7AD9\u7684", competitor: "\u7AF6\u722D\u5C0D\u624B\u7684", other: "\u5176\u4ED6\u7DB2\u7AD9\u7684" }[a.owner];
|
|
8615
|
-
const
|
|
8616
|
-
return a.url ? `\u5132\u5B58${whose ?? ""} sitemap ${a.url}${
|
|
8621
|
+
const label2 = a.label ? `\uFF08${q(a.label)}\uFF09` : "";
|
|
8622
|
+
return a.url ? `\u5132\u5B58${whose ?? ""} sitemap ${a.url}${label2}\u3002` : `\u4FEE\u6539 sitemap${label2}\uFF1A${keys(a).filter((k) => k !== "id").join("\u3001")}\u3002`;
|
|
8617
8623
|
}
|
|
8618
8624
|
},
|
|
8619
8625
|
sitemap_remove: {
|
|
@@ -8771,20 +8777,32 @@ var confirmCopy = {
|
|
|
8771
8777
|
},
|
|
8772
8778
|
social_approve: {
|
|
8773
8779
|
en: (a) => {
|
|
8774
|
-
const
|
|
8780
|
+
const n2 = ids(a);
|
|
8775
8781
|
const at = placeEn(a.position);
|
|
8776
8782
|
if (at)
|
|
8777
|
-
return `Approve ${
|
|
8778
|
-
return
|
|
8783
|
+
return `Approve ${n2.length > 1 ? `${n2.length} posts: ${n2.map((i) => `#${i}`).join(", ")}` : `post #${n2[0]}`}. ${n2.length > 1 ? "They are" : "It is"} queued ${at}, and go${n2.length > 1 ? "" : "es"} out where your network can see ${n2.length > 1 ? "them" : "it"}.`;
|
|
8784
|
+
return n2.length > 1 ? `Approve ${n2.length} posts: ${n2.map((i) => `#${i}`).join(", ")}. Each goes out at your next posting times, where your network can see it.` : `Approve post #${n2[0]}. It goes out at your next posting time, where your network can see it.`;
|
|
8779
8785
|
},
|
|
8780
8786
|
"zh-Hant": (a) => {
|
|
8781
|
-
const
|
|
8787
|
+
const n2 = ids(a);
|
|
8782
8788
|
const at = placeZh(a.position);
|
|
8783
8789
|
if (at)
|
|
8784
|
-
return `\u6279\u51C6${
|
|
8785
|
-
return
|
|
8790
|
+
return `\u6279\u51C6${n2.length > 1 ? ` ${n2.length} \u7BC7\u8CBC\u6587\uFF1A${n2.map((i) => `#${i}`).join("\u3001")}` : `\u8CBC\u6587 #${n2[0]}`}\u3002${at}\uFF0C\u767C\u51FA\u5F8C\u4F60\u7684\u4EBA\u8108\u90FD\u770B\u5F97\u5230\u3002`;
|
|
8791
|
+
return n2.length > 1 ? `\u6279\u51C6 ${n2.length} \u7BC7\u8CBC\u6587\uFF1A${n2.map((i) => `#${i}`).join("\u3001")}\u3002\u6BCF\u7BC7\u5728\u63A5\u4E0B\u4F86\u7684\u767C\u6587\u6642\u9593\u767C\u51FA\uFF0C\u4F60\u7684\u4EBA\u8108\u90FD\u770B\u5F97\u5230\u3002` : `\u6279\u51C6\u8CBC\u6587 #${n2[0]}\u3002\u5B83\u6703\u5728\u4E0B\u4E00\u500B\u767C\u6587\u6642\u9593\u767C\u51FA\uFF0C\u4F60\u7684\u4EBA\u8108\u90FD\u770B\u5F97\u5230\u3002`;
|
|
8786
8792
|
}
|
|
8787
8793
|
},
|
|
8794
|
+
social_publish_now: {
|
|
8795
|
+
en: (a) => `Post #${a.id} on its channel now, not at its posting time (even while posting is paused). Everyone who follows you can see it.`,
|
|
8796
|
+
"zh-Hant": (a) => `\u7ACB\u5373\u5728\u5B83\u7684\u983B\u9053\u767C\u51FA\u8CBC\u6587 #${a.id}\uFF0C\u4E0D\u7B49\u767C\u6587\u6642\u9593\uFF08\u66AB\u505C\u767C\u6587\u6642\u4E5F\u6703\u767C\uFF09\u3002\u767C\u51FA\u5F8C\u95DC\u6CE8\u4F60\u7684\u4EBA\u90FD\u770B\u5F97\u5230\u3002`
|
|
8797
|
+
},
|
|
8798
|
+
social_posted_update: {
|
|
8799
|
+
en: (a) => a.repost ? `Take post #${a.id} down (its likes and comments go) and put it up again${a.social_copy ? ` as ${q(a.social_copy)}` : ""}.` : `Change the text of the posted post #${a.id} to ${q(a.social_copy)}. On LinkedIn it stays up with its likes and comments; on other channels it comes down and goes out again.`,
|
|
8800
|
+
"zh-Hant": (a) => a.repost ? `\u64A4\u4E0B\u8CBC\u6587 #${a.id}\uFF08\u8B9A\u548C\u7559\u8A00\u6703\u6D88\u5931\uFF09\uFF0C\u518D\u91CD\u65B0\u767C\u51FA${a.social_copy ? `\uFF0C\u5167\u5BB9\u6539\u70BA ${q(a.social_copy)}` : ""}\u3002` : `\u628A\u5DF2\u767C\u51FA\u7684\u8CBC\u6587 #${a.id} \u6539\u70BA ${q(a.social_copy)}\u3002LinkedIn \u4E0A\u539F\u5730\u4FEE\u6539\uFF0C\u8B9A\u548C\u7559\u8A00\u4FDD\u7559\uFF1B\u5176\u4ED6\u983B\u9053\u6703\u64A4\u4E0B\u5F8C\u91CD\u767C\u3002`
|
|
8801
|
+
},
|
|
8802
|
+
social_posted_delete: {
|
|
8803
|
+
en: (a) => `Take post #${a.id} down from its channel, with its likes and comments. This can't be undone.`,
|
|
8804
|
+
"zh-Hant": (a) => `\u628A\u8CBC\u6587 #${a.id} \u5F9E\u5B83\u7684\u983B\u9053\u64A4\u4E0B\uFF0C\u8B9A\u548C\u7559\u8A00\u4E00\u8D77\u522A\u9664\uFF0C\u7121\u6CD5\u5FA9\u539F\u3002`
|
|
8805
|
+
},
|
|
8788
8806
|
social_skip: { en: (a) => `Skip post #${a.id}.`, "zh-Hant": (a) => `\u8DF3\u904E\u8CBC\u6587 #${a.id}\u3002` },
|
|
8789
8807
|
social_restore: {
|
|
8790
8808
|
en: (a) => `Bring back post #${a.id}.`,
|
|
@@ -8838,12 +8856,12 @@ var confirmCopy = {
|
|
|
8838
8856
|
},
|
|
8839
8857
|
social_pictures_attach: {
|
|
8840
8858
|
en: (a) => {
|
|
8841
|
-
const
|
|
8842
|
-
return `${a.append ? "Add" : "Put"} your ${
|
|
8859
|
+
const n2 = (Array.isArray(a.urls) ? a.urls.length : 0) + (Array.isArray(a.files) ? a.files.length : 0);
|
|
8860
|
+
return `${a.append ? "Add" : "Put"} your ${n2} picture${n2 === 1 ? "" : "s"} ${a.append ? "after the pictures on" : "on"} post #${a.id}${a.append ? "" : ", in place of its picture"} (free). On LinkedIn a set goes out as a swipeable PDF carousel.`;
|
|
8843
8861
|
},
|
|
8844
8862
|
"zh-Hant": (a) => {
|
|
8845
|
-
const
|
|
8846
|
-
return `${a.append ? `\u5728\u8CBC\u6587 #${a.id} \u73FE\u6709\u5716\u7247\u5F8C\u52A0\u4E0A` : `\u628A\u8CBC\u6587 #${a.id} \u7684\u5716\u7247\u63DB\u6210`}\u4F60\u7684 ${
|
|
8863
|
+
const n2 = (Array.isArray(a.urls) ? a.urls.length : 0) + (Array.isArray(a.files) ? a.files.length : 0);
|
|
8864
|
+
return `${a.append ? `\u5728\u8CBC\u6587 #${a.id} \u73FE\u6709\u5716\u7247\u5F8C\u52A0\u4E0A` : `\u628A\u8CBC\u6587 #${a.id} \u7684\u5716\u7247\u63DB\u6210`}\u4F60\u7684 ${n2} \u5F35\u5716\u7247\uFF08\u514D\u8CBB\uFF09\u3002\u5728 LinkedIn \u4E0A\uFF0C\u4E00\u7D44\u5716\u7247\u6703\u4EE5\u53EF\u6ED1\u52D5\u7684 PDF \u8F2A\u64AD\u767C\u51FA\u3002`;
|
|
8847
8865
|
}
|
|
8848
8866
|
},
|
|
8849
8867
|
social_carousel_pdf_attach: {
|
|
@@ -9072,35 +9090,104 @@ function confirmText(tool2, args, lang = "en") {
|
|
|
9072
9090
|
function costText(cost, lang = "en") {
|
|
9073
9091
|
const parts = [];
|
|
9074
9092
|
if (cost.aiGenerations) {
|
|
9075
|
-
const
|
|
9093
|
+
const n2 = cost.aiGenerations;
|
|
9076
9094
|
const left = cost.aiLeft;
|
|
9077
9095
|
parts.push(
|
|
9078
|
-
lang === "zh-Hant" ? `\u7528 ${
|
|
9096
|
+
lang === "zh-Hant" ? `\u7528 ${n2} \u6B21 AI \u751F\u6210${left == null ? "" : `\uFF08\u4ECA\u5929\u5269 ${left} \u6B21\uFF09`}\u3002` : `Uses ${n2} AI generation${n2 === 1 ? "" : "s"}${left == null ? "" : ` (${left} left today)`}.`
|
|
9079
9097
|
);
|
|
9080
9098
|
}
|
|
9081
9099
|
if (cost.credits) {
|
|
9082
|
-
const
|
|
9100
|
+
const n2 = cost.credits;
|
|
9083
9101
|
const left = cost.creditsLeft;
|
|
9084
9102
|
parts.push(
|
|
9085
|
-
lang === "zh-Hant" ? `\u6263 ${
|
|
9103
|
+
lang === "zh-Hant" ? `\u6263 ${n2} \u500B\u984D\u5EA6${left == null ? "" : `\uFF08\u5269 ${left}\uFF09`}\u3002` : `Uses ${n2} credit${n2 === 1 ? "" : "s"}${left == null ? "" : ` (${left} left)`}.`
|
|
9086
9104
|
);
|
|
9087
9105
|
}
|
|
9088
9106
|
return parts.join(" ");
|
|
9089
9107
|
}
|
|
9090
9108
|
|
|
9109
|
+
// ../../packages/mcp/src/messages.ts
|
|
9110
|
+
var UPPER = /* @__PURE__ */ new Set(["seo", "gsc", "gbp", "cta", "cmo", "dns", "ai", "api", "pdf", "url", "id"]);
|
|
9111
|
+
var n = (count, word, plural) => count === 1 ? `1 ${word}` : `${count ? count : "no"} ${plural ?? `${word}s`}`;
|
|
9112
|
+
function titleOf(name) {
|
|
9113
|
+
const words = name.split("_").map((w) => UPPER.has(w) ? w.toUpperCase() : w);
|
|
9114
|
+
const head = words[0] ?? "";
|
|
9115
|
+
return [head.charAt(0).toUpperCase() + head.slice(1), ...words.slice(1)].join(" ");
|
|
9116
|
+
}
|
|
9117
|
+
var LIST_KEYS = ["items", "results", "posts", "ideas", "workspaces", "rows"];
|
|
9118
|
+
function items(value) {
|
|
9119
|
+
if (Array.isArray(value)) return value;
|
|
9120
|
+
if (value && typeof value === "object") {
|
|
9121
|
+
for (const k of LIST_KEYS) {
|
|
9122
|
+
const v = value[k];
|
|
9123
|
+
if (Array.isArray(v)) return v;
|
|
9124
|
+
}
|
|
9125
|
+
}
|
|
9126
|
+
return null;
|
|
9127
|
+
}
|
|
9128
|
+
function label(x) {
|
|
9129
|
+
if (x && typeof x === "object") {
|
|
9130
|
+
const o = x;
|
|
9131
|
+
for (const k of ["title", "name", "domain", "label", "what", "text", "id"]) {
|
|
9132
|
+
if (o[k] !== void 0 && o[k] !== null && o[k] !== "") return String(o[k]);
|
|
9133
|
+
}
|
|
9134
|
+
return Object.entries(o).filter(([, v]) => typeof v !== "object").slice(0, 3).map(([k, v]) => `${k} ${v}`).join(", ");
|
|
9135
|
+
}
|
|
9136
|
+
return String(x);
|
|
9137
|
+
}
|
|
9138
|
+
function bodyLines(value) {
|
|
9139
|
+
const list2 = items(value);
|
|
9140
|
+
if (list2) {
|
|
9141
|
+
const out = list2.slice(0, 8).map((x) => `- ${label(x)}`.slice(0, 200));
|
|
9142
|
+
return list2.length > 8 ? [...out, `\u2026and ${list2.length - 8} more`] : out;
|
|
9143
|
+
}
|
|
9144
|
+
if (value && typeof value === "object") {
|
|
9145
|
+
return Object.entries(value).filter(([k, v]) => v !== null && v !== void 0 && v !== "" && typeof v !== "object" && k !== "next").slice(0, 8).map(([k, v]) => `${k.replace(/_/g, " ")}: ${v}`.slice(0, 200));
|
|
9146
|
+
}
|
|
9147
|
+
return value === null || value === void 0 || value === "" ? [] : [String(value).slice(0, 600)];
|
|
9148
|
+
}
|
|
9149
|
+
function said(name, value) {
|
|
9150
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
9151
|
+
for (const k of ["say", "headline", "summary", "message"]) {
|
|
9152
|
+
const v = value[k];
|
|
9153
|
+
if (typeof v === "string" && v.trim()) return (v.trim().split("\n")[0] ?? "").slice(0, 240);
|
|
9154
|
+
}
|
|
9155
|
+
}
|
|
9156
|
+
const list2 = items(value);
|
|
9157
|
+
if (list2) {
|
|
9158
|
+
let noun = name.endsWith("_list") ? name.slice(0, -5).split("_").pop() ?? "item" : "item";
|
|
9159
|
+
if (noun.endsWith("s")) noun = noun.slice(0, -1);
|
|
9160
|
+
return list2.length ? `I found ${n(list2.length, noun)}.` : "There's nothing there yet.";
|
|
9161
|
+
}
|
|
9162
|
+
if (typeof value === "string") return (value.trim().split("\n")[0] ?? "").slice(0, 240) || "Done.";
|
|
9163
|
+
return "Here it is.";
|
|
9164
|
+
}
|
|
9165
|
+
var lowerFirst = (s) => /^[A-Za-z][a-z]/.test(s) ? s.charAt(0).toLowerCase() + s.slice(1) : s;
|
|
9166
|
+
function message(name, value, opts = {}) {
|
|
9167
|
+
const title = titleOf(name);
|
|
9168
|
+
if (opts.error) return { say: `That didn't work: ${opts.error}`.slice(0, 300), title, lines: [] };
|
|
9169
|
+
if (opts.preview) return { say: "This needs your yes first; nothing has changed yet.", title, lines: [opts.preview] };
|
|
9170
|
+
if (opts.done) return { say: `Done: ${lowerFirst(opts.done)}`, title, lines: bodyLines(value) };
|
|
9171
|
+
return { say: said(name, value), title, lines: bodyLines(value) };
|
|
9172
|
+
}
|
|
9173
|
+
function messageText(m) {
|
|
9174
|
+
const body = [m.title ? `**${m.title}**` : "", ...m.lines].filter(Boolean).join("\n");
|
|
9175
|
+
return [m.say, body].filter(Boolean).join("\n\n").trim();
|
|
9176
|
+
}
|
|
9177
|
+
|
|
9091
9178
|
// ../../packages/tools/src/lib.ts
|
|
9092
9179
|
var none = { type: "object", properties: {} };
|
|
9093
9180
|
function ws(ctx) {
|
|
9094
9181
|
if (!ctx.domain) throw new Error("No website is selected yet. Add one first.");
|
|
9095
9182
|
return domainApi(ctx.api, ctx.domain);
|
|
9096
9183
|
}
|
|
9097
|
-
var clip = (text3,
|
|
9184
|
+
var clip = (text3, n2 = 280) => typeof text3 === "string" ? text3.length > n2 ? `${text3.slice(0, n2)}\u2026` : text3 : text3 ?? null;
|
|
9098
9185
|
var plain = (html) => String(html ?? "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
9099
9186
|
var untrusted = (value) => ({ untrusted: value });
|
|
9100
9187
|
function upsert(list2, item2, key) {
|
|
9101
9188
|
const k = (key(item2) ?? "").trim().toLowerCase();
|
|
9102
9189
|
const i = list2.findIndex((x) => (key(x) ?? "").trim().toLowerCase() === k);
|
|
9103
|
-
return i >= 0 ? list2.map((x,
|
|
9190
|
+
return i >= 0 ? list2.map((x, n2) => n2 === i ? { ...x, ...item2 } : x) : [...list2, item2];
|
|
9104
9191
|
}
|
|
9105
9192
|
function remove(list2, name, key) {
|
|
9106
9193
|
const k = name.trim().toLowerCase();
|
|
@@ -9109,8 +9196,8 @@ function remove(list2, name, key) {
|
|
|
9109
9196
|
return out;
|
|
9110
9197
|
}
|
|
9111
9198
|
var int = (v, min, max, fallback) => {
|
|
9112
|
-
const
|
|
9113
|
-
return Number.isFinite(
|
|
9199
|
+
const n2 = Math.trunc(Number(v));
|
|
9200
|
+
return Number.isFinite(n2) ? Math.min(max, Math.max(min, n2)) : fallback;
|
|
9114
9201
|
};
|
|
9115
9202
|
var positionParam = (what, fallback) => ({
|
|
9116
9203
|
type: "string",
|
|
@@ -9279,12 +9366,12 @@ var accountTools = [
|
|
|
9279
9366
|
risk: "R0",
|
|
9280
9367
|
run: async (ctx, { platform }) => {
|
|
9281
9368
|
const p = platform && CONNECT_FORMS.includes(platform) ? platform : "";
|
|
9282
|
-
const
|
|
9369
|
+
const label2 = p ? `Connect ${CONNECT_NAMES[p]}` : "Connect your website";
|
|
9283
9370
|
const link = `https://app.cmo.so/posts?connect=${p || "wordpress"}${ctx.domain ? `&site=${encodeURIComponent(ctx.domain)}` : ""}`;
|
|
9284
9371
|
if (ctx.client === "chat")
|
|
9285
9372
|
return {
|
|
9286
|
-
card: { type: "connect", platform: p || null, label },
|
|
9287
|
-
shown: `A "${
|
|
9373
|
+
card: { type: "connect", platform: p || null, label: label2 },
|
|
9374
|
+
shown: `A "${label2}" button now shows under your message. The user fills in the form there; say so in one line.`
|
|
9288
9375
|
};
|
|
9289
9376
|
return { link, shown: "Give the user this link: it opens the form in the cmo.so app (web or phone)." };
|
|
9290
9377
|
}
|
|
@@ -9987,10 +10074,10 @@ var brandTools = [
|
|
|
9987
10074
|
need: write2,
|
|
9988
10075
|
risk: "W1",
|
|
9989
10076
|
run: async (ctx, { count }) => {
|
|
9990
|
-
const
|
|
9991
|
-
if (!Number.isFinite(
|
|
9992
|
-
const out = await ws(ctx).updateBrand({ internal_links: { count:
|
|
9993
|
-
return { internal_links: out.internal_links ?? { count:
|
|
10077
|
+
const n2 = Math.round(Number(count));
|
|
10078
|
+
if (!Number.isFinite(n2) || n2 < 0 || n2 > 10) throw new Error("count must be 0 to 10.");
|
|
10079
|
+
const out = await ws(ctx).updateBrand({ internal_links: { count: n2 } });
|
|
10080
|
+
return { internal_links: out.internal_links ?? { count: n2 } };
|
|
9994
10081
|
}
|
|
9995
10082
|
}),
|
|
9996
10083
|
tool({
|
|
@@ -10011,8 +10098,8 @@ var brandTools = [
|
|
|
10011
10098
|
risk: "W1",
|
|
10012
10099
|
run: async (ctx, { use_in_posts, ...item2 }) => {
|
|
10013
10100
|
const t = (await ws(ctx).brand()).testimonials ?? { enabled: false, items: [] };
|
|
10014
|
-
const
|
|
10015
|
-
return (await ws(ctx).updateBrand({ testimonials: { enabled: use_in_posts ?? t.enabled, items } })).testimonials;
|
|
10101
|
+
const items2 = upsert(t.items, item2, (i) => i.name);
|
|
10102
|
+
return (await ws(ctx).updateBrand({ testimonials: { enabled: use_in_posts ?? t.enabled, items: items2 } })).testimonials;
|
|
10016
10103
|
}
|
|
10017
10104
|
}),
|
|
10018
10105
|
tool({
|
|
@@ -10030,8 +10117,8 @@ var brandTools = [
|
|
|
10030
10117
|
risk: "W1",
|
|
10031
10118
|
run: async (ctx, { name, use_in_posts }) => {
|
|
10032
10119
|
const t = (await ws(ctx).brand()).testimonials ?? { enabled: false, items: [] };
|
|
10033
|
-
const
|
|
10034
|
-
return (await ws(ctx).updateBrand({ testimonials: { enabled: use_in_posts ?? t.enabled, items } })).testimonials;
|
|
10120
|
+
const items2 = name ? remove(t.items, name, (i) => i.name) : t.items;
|
|
10121
|
+
return (await ws(ctx).updateBrand({ testimonials: { enabled: use_in_posts ?? t.enabled, items: items2 } })).testimonials;
|
|
10035
10122
|
}
|
|
10036
10123
|
}),
|
|
10037
10124
|
tool({
|
|
@@ -10233,7 +10320,7 @@ var brandTools = [
|
|
|
10233
10320
|
);
|
|
10234
10321
|
if (typeof entry === "string") throw new Error(entry);
|
|
10235
10322
|
if (old && sitemapUrl(old.url) !== entry.url) delete entry.check;
|
|
10236
|
-
const next = old ? list2.map((x,
|
|
10323
|
+
const next = old ? list2.map((x, n2) => n2 === i ? entry : x) : [...list2, entry];
|
|
10237
10324
|
const problem = checkSitemaps(next);
|
|
10238
10325
|
if (problem) throw new Error(problem);
|
|
10239
10326
|
const saved = (await ws(ctx).updateBrand({ sitemaps: next })).sitemaps ?? next;
|
|
@@ -10257,7 +10344,7 @@ var brandTools = [
|
|
|
10257
10344
|
const list2 = (await ws(ctx).brand()).sitemaps ?? [];
|
|
10258
10345
|
const i = findSitemap(list2, id, url);
|
|
10259
10346
|
if (i < 0) throw new Error(`No sitemap ${id ?? url} was found. Use sitemap_list.`);
|
|
10260
|
-
const saved = (await ws(ctx).updateBrand({ sitemaps: list2.filter((_,
|
|
10347
|
+
const saved = (await ws(ctx).updateBrand({ sitemaps: list2.filter((_, n2) => n2 !== i) })).sitemaps ?? [];
|
|
10261
10348
|
return { removed: list2[i]?.url, sitemaps: saved.map((s) => s.url) };
|
|
10262
10349
|
}
|
|
10263
10350
|
}),
|
|
@@ -10416,7 +10503,7 @@ function sitemapResult(s) {
|
|
|
10416
10503
|
// ../../packages/tools/src/feedback.ts
|
|
10417
10504
|
var account = { resource: "account", level: "read" };
|
|
10418
10505
|
var TYPES = ["bug", "quality", "idea", "praise", "other"];
|
|
10419
|
-
var text = (v,
|
|
10506
|
+
var text = (v, n2) => String(v ?? "").trim().slice(0, n2);
|
|
10420
10507
|
var feedbackTools = [
|
|
10421
10508
|
tool({
|
|
10422
10509
|
name: "feedback_send",
|
|
@@ -11736,17 +11823,70 @@ var socialTools = [
|
|
|
11736
11823
|
const at = positionOf(position);
|
|
11737
11824
|
const api2 = ws(ctx);
|
|
11738
11825
|
const results = [];
|
|
11739
|
-
for (const
|
|
11826
|
+
for (const n2 of list2) {
|
|
11740
11827
|
try {
|
|
11741
|
-
await api2.approveSocial(
|
|
11742
|
-
results.push({ id:
|
|
11828
|
+
await api2.approveSocial(n2, at);
|
|
11829
|
+
results.push({ id: n2, ok: true });
|
|
11743
11830
|
} catch (e) {
|
|
11744
|
-
results.push({ id:
|
|
11831
|
+
results.push({ id: n2, ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
11745
11832
|
}
|
|
11746
11833
|
}
|
|
11747
11834
|
return { approved: results.filter((r) => r.ok).length, results };
|
|
11748
11835
|
}
|
|
11749
11836
|
}),
|
|
11837
|
+
tool({
|
|
11838
|
+
name: "social_publish_now",
|
|
11839
|
+
description: "Post one social post on its channel now instead of at its posting time: a draft waiting for approval, a queued post, or one that didn't go out. It goes even while posting is paused. It goes out in the background: the answer says it is publishing; read social_post_get after a minute for its link (or why it couldn't go). Not while its picture is being made.",
|
|
11840
|
+
parameters: { type: "object", properties: { id: { type: "integer" } }, required: ["id"] },
|
|
11841
|
+
group: "social",
|
|
11842
|
+
need: write5,
|
|
11843
|
+
risk: "W3",
|
|
11844
|
+
gates: ["VER"],
|
|
11845
|
+
run: async (ctx, { id }) => {
|
|
11846
|
+
const n2 = Number(id);
|
|
11847
|
+
if (!Number.isInteger(n2) || n2 <= 0) throw new Error("Which post?");
|
|
11848
|
+
const post = await ws(ctx).publishSocialNow(n2, { background: true });
|
|
11849
|
+
return post.status === "published" ? post : { ...post, note: "Posting now. Check social_post_get in a minute for its link." };
|
|
11850
|
+
}
|
|
11851
|
+
}),
|
|
11852
|
+
tool({
|
|
11853
|
+
name: "social_posted_update",
|
|
11854
|
+
description: "Change a social post that has already gone out. On LinkedIn the new text replaces the old in place: the post keeps its likes and comments (its pictures can't change this way). With repost, and on Facebook, Instagram and Google, the old post comes down with its likes and comments and the new version goes out now. Without social_copy and with repost, it goes out again as it is (e.g. after new pictures).",
|
|
11855
|
+
parameters: {
|
|
11856
|
+
type: "object",
|
|
11857
|
+
properties: {
|
|
11858
|
+
id: { type: "integer" },
|
|
11859
|
+
social_copy: { type: "string", description: "The post's new text" },
|
|
11860
|
+
repost: { type: "boolean", description: "Take it down and put it up again instead of editing it" }
|
|
11861
|
+
},
|
|
11862
|
+
required: ["id"]
|
|
11863
|
+
},
|
|
11864
|
+
group: "social",
|
|
11865
|
+
need: write5,
|
|
11866
|
+
risk: "W3",
|
|
11867
|
+
gates: ["VER"],
|
|
11868
|
+
run: async (ctx, { id, social_copy, repost }) => {
|
|
11869
|
+
const n2 = Number(id);
|
|
11870
|
+
if (!Number.isInteger(n2) || n2 <= 0) throw new Error("Which post?");
|
|
11871
|
+
const copy = typeof social_copy === "string" ? social_copy.trim() : "";
|
|
11872
|
+
if (!copy && repost !== true) throw new Error("Give the new text (social_copy), or repost: true.");
|
|
11873
|
+
return ws(ctx).republishSocial(n2, copy || void 0, repost === true);
|
|
11874
|
+
}
|
|
11875
|
+
}),
|
|
11876
|
+
tool({
|
|
11877
|
+
name: "social_posted_delete",
|
|
11878
|
+
description: "Take a social post that has gone out down from its channel (LinkedIn, Facebook, Instagram, Google). Its likes and comments go with it; this can't be undone.",
|
|
11879
|
+
parameters: { type: "object", properties: { id: { type: "integer" } }, required: ["id"] },
|
|
11880
|
+
group: "social",
|
|
11881
|
+
need: write5,
|
|
11882
|
+
risk: "W3",
|
|
11883
|
+
gates: ["VER"],
|
|
11884
|
+
run: async (ctx, { id }) => {
|
|
11885
|
+
const n2 = Number(id);
|
|
11886
|
+
if (!Number.isInteger(n2) || n2 <= 0) throw new Error("Which post?");
|
|
11887
|
+
return ws(ctx).deletePostedSocial(n2);
|
|
11888
|
+
}
|
|
11889
|
+
}),
|
|
11750
11890
|
tool({
|
|
11751
11891
|
name: "social_skip",
|
|
11752
11892
|
description: "Skip a LinkedIn post (it won't be posted; it can be restored).",
|
|
@@ -13822,8 +13962,8 @@ function prefixIssues(path, issues) {
|
|
|
13822
13962
|
return iss;
|
|
13823
13963
|
});
|
|
13824
13964
|
}
|
|
13825
|
-
function unwrapMessage(
|
|
13826
|
-
return typeof
|
|
13965
|
+
function unwrapMessage(message2) {
|
|
13966
|
+
return typeof message2 === "string" ? message2 : message2?.message;
|
|
13827
13967
|
}
|
|
13828
13968
|
function sizeCaps(defChecks) {
|
|
13829
13969
|
const caps = [];
|
|
@@ -13853,7 +13993,7 @@ function finalizeIssue(iss, ctx, config2) {
|
|
|
13853
13993
|
iss.schema = iss.inst;
|
|
13854
13994
|
}
|
|
13855
13995
|
const schemaError = iss.schema !== iss.inst ? iss.schema?._zod.def?.error : void 0;
|
|
13856
|
-
const
|
|
13996
|
+
const message2 = iss.message ? iss.message : unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(schemaError?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config2.customError?.(iss)) ?? unwrapMessage(config2.localeError?.(iss)) ?? "Invalid input";
|
|
13857
13997
|
const full = {};
|
|
13858
13998
|
for (const k of Object.keys(iss)) {
|
|
13859
13999
|
if (k === "inst" || k === "schema" || k === "continue" || k === "input" || k === "__proto__")
|
|
@@ -13861,7 +14001,7 @@ function finalizeIssue(iss, ctx, config2) {
|
|
|
13861
14001
|
full[k] = iss[k];
|
|
13862
14002
|
}
|
|
13863
14003
|
full.path ?? (full.path = []);
|
|
13864
|
-
full.message =
|
|
14004
|
+
full.message = message2;
|
|
13865
14005
|
if (ctx?.reportInput) {
|
|
13866
14006
|
full.input = iss.input;
|
|
13867
14007
|
}
|
|
@@ -15477,10 +15617,10 @@ function capSize(inst, size) {
|
|
|
15477
15617
|
const cap = Math.min(...caps.map((c) => c[0]));
|
|
15478
15618
|
const parse3 = inst._zod.parse;
|
|
15479
15619
|
inst._zod.parse = (payload, ctx) => {
|
|
15480
|
-
const
|
|
15481
|
-
if (
|
|
15620
|
+
const n2 = size(payload.value);
|
|
15621
|
+
if (n2 > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
|
|
15482
15622
|
for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
|
|
15483
|
-
if (
|
|
15623
|
+
if (n2 > max && ch._zod.def.when(payload)) {
|
|
15484
15624
|
const start = payload.issues.length;
|
|
15485
15625
|
ch._zod.check(payload);
|
|
15486
15626
|
payload.issues[start].continue = false;
|
|
@@ -17576,12 +17716,12 @@ function initializeContext(params) {
|
|
|
17576
17716
|
external: params?.external ?? void 0
|
|
17577
17717
|
};
|
|
17578
17718
|
}
|
|
17579
|
-
function handleUnrepresentable(schema, ctx, json, params,
|
|
17580
|
-
const result = typeof ctx.unrepresentable === "function" ? ctx.unrepresentable({ zodSchema: schema, path: params.path, message }) : ctx.unrepresentable;
|
|
17719
|
+
function handleUnrepresentable(schema, ctx, json, params, message2) {
|
|
17720
|
+
const result = typeof ctx.unrepresentable === "function" ? ctx.unrepresentable({ zodSchema: schema, path: params.path, message: message2 }) : ctx.unrepresentable;
|
|
17581
17721
|
if (result === "any")
|
|
17582
17722
|
return false;
|
|
17583
17723
|
if (result === void 0 || result === "throw")
|
|
17584
|
-
throw new Error(
|
|
17724
|
+
throw new Error(message2);
|
|
17585
17725
|
Object.assign(json, result);
|
|
17586
17726
|
return true;
|
|
17587
17727
|
}
|
|
@@ -19274,17 +19414,17 @@ var ZodArray = /* @__PURE__ */ $constructor("ZodArray", (inst, def) => {
|
|
|
19274
19414
|
inst._zod.processJSONSchema = (ctx, json, params) => arrayProcessor(inst, ctx, json, params);
|
|
19275
19415
|
inst.element = def.element;
|
|
19276
19416
|
}, {
|
|
19277
|
-
min(
|
|
19278
|
-
return this.check(_minLength(
|
|
19417
|
+
min(n2, params) {
|
|
19418
|
+
return this.check(_minLength(n2, params));
|
|
19279
19419
|
},
|
|
19280
19420
|
nonempty(params) {
|
|
19281
19421
|
return this.check(_minLength(1, params));
|
|
19282
19422
|
},
|
|
19283
|
-
max(
|
|
19284
|
-
return this.check(_maxLength(
|
|
19423
|
+
max(n2, params) {
|
|
19424
|
+
return this.check(_maxLength(n2, params));
|
|
19285
19425
|
},
|
|
19286
|
-
length(
|
|
19287
|
-
return this.check(_length(
|
|
19426
|
+
length(n2, params) {
|
|
19427
|
+
return this.check(_length(n2, params));
|
|
19288
19428
|
},
|
|
19289
19429
|
unwrap() {
|
|
19290
19430
|
return this.element;
|
|
@@ -21188,8 +21328,8 @@ var ServerResultSchema = union([
|
|
|
21188
21328
|
CreateTaskResultSchema
|
|
21189
21329
|
]);
|
|
21190
21330
|
var McpError = class _McpError extends Error {
|
|
21191
|
-
constructor(code,
|
|
21192
|
-
super(`MCP error ${code}: ${
|
|
21331
|
+
constructor(code, message2, data) {
|
|
21332
|
+
super(`MCP error ${code}: ${message2}`);
|
|
21193
21333
|
this.code = code;
|
|
21194
21334
|
this.data = data;
|
|
21195
21335
|
this.name = "McpError";
|
|
@@ -21197,19 +21337,19 @@ var McpError = class _McpError extends Error {
|
|
|
21197
21337
|
/**
|
|
21198
21338
|
* Factory method to create the appropriate error type based on the error code and data
|
|
21199
21339
|
*/
|
|
21200
|
-
static fromError(code,
|
|
21340
|
+
static fromError(code, message2, data) {
|
|
21201
21341
|
if (code === ErrorCode.UrlElicitationRequired && data) {
|
|
21202
21342
|
const errorData = data;
|
|
21203
21343
|
if (errorData.elicitations) {
|
|
21204
|
-
return new UrlElicitationRequiredError(errorData.elicitations,
|
|
21344
|
+
return new UrlElicitationRequiredError(errorData.elicitations, message2);
|
|
21205
21345
|
}
|
|
21206
21346
|
}
|
|
21207
|
-
return new _McpError(code,
|
|
21347
|
+
return new _McpError(code, message2, data);
|
|
21208
21348
|
}
|
|
21209
21349
|
};
|
|
21210
21350
|
var UrlElicitationRequiredError = class extends McpError {
|
|
21211
|
-
constructor(elicitations,
|
|
21212
|
-
super(ErrorCode.UrlElicitationRequired,
|
|
21351
|
+
constructor(elicitations, message2 = `URL elicitation${elicitations.length > 1 ? "s" : ""} required`) {
|
|
21352
|
+
super(ErrorCode.UrlElicitationRequired, message2, {
|
|
21213
21353
|
elicitations
|
|
21214
21354
|
});
|
|
21215
21355
|
}
|
|
@@ -21295,15 +21435,15 @@ var Protocol = class {
|
|
|
21295
21435
|
let queuedMessage;
|
|
21296
21436
|
while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
|
|
21297
21437
|
if (queuedMessage.type === "response" || queuedMessage.type === "error") {
|
|
21298
|
-
const
|
|
21299
|
-
const requestId =
|
|
21438
|
+
const message2 = queuedMessage.message;
|
|
21439
|
+
const requestId = message2.id;
|
|
21300
21440
|
const resolver = this._requestResolvers.get(requestId);
|
|
21301
21441
|
if (resolver) {
|
|
21302
21442
|
this._requestResolvers.delete(requestId);
|
|
21303
21443
|
if (queuedMessage.type === "response") {
|
|
21304
|
-
resolver(
|
|
21444
|
+
resolver(message2);
|
|
21305
21445
|
} else {
|
|
21306
|
-
const errorMessage3 =
|
|
21446
|
+
const errorMessage3 = message2;
|
|
21307
21447
|
const error2 = new McpError(errorMessage3.error.code, errorMessage3.error.message, errorMessage3.error.data);
|
|
21308
21448
|
resolver(error2);
|
|
21309
21449
|
}
|
|
@@ -21442,16 +21582,16 @@ var Protocol = class {
|
|
|
21442
21582
|
this._onerror(error2);
|
|
21443
21583
|
};
|
|
21444
21584
|
const _onmessage = this._transport?.onmessage;
|
|
21445
|
-
this._transport.onmessage = (
|
|
21446
|
-
_onmessage?.(
|
|
21447
|
-
if (isJSONRPCResultResponse(
|
|
21448
|
-
this._onresponse(
|
|
21449
|
-
} else if (isJSONRPCRequest(
|
|
21450
|
-
this._onrequest(
|
|
21451
|
-
} else if (isJSONRPCNotification(
|
|
21452
|
-
this._onnotification(
|
|
21585
|
+
this._transport.onmessage = (message2, extra) => {
|
|
21586
|
+
_onmessage?.(message2, extra);
|
|
21587
|
+
if (isJSONRPCResultResponse(message2) || isJSONRPCErrorResponse(message2)) {
|
|
21588
|
+
this._onresponse(message2);
|
|
21589
|
+
} else if (isJSONRPCRequest(message2)) {
|
|
21590
|
+
this._onrequest(message2, extra);
|
|
21591
|
+
} else if (isJSONRPCNotification(message2)) {
|
|
21592
|
+
this._onnotification(message2);
|
|
21453
21593
|
} else {
|
|
21454
|
-
this._onerror(new Error(`Unknown message type: ${JSON.stringify(
|
|
21594
|
+
this._onerror(new Error(`Unknown message type: ${JSON.stringify(message2)}`));
|
|
21455
21595
|
}
|
|
21456
21596
|
};
|
|
21457
21597
|
await this._transport.start();
|
|
@@ -22061,12 +22201,12 @@ var Protocol = class {
|
|
|
22061
22201
|
* the error appropriately (e.g., by failing the task, logging, etc.). The Protocol layer
|
|
22062
22202
|
* simply propagates the error.
|
|
22063
22203
|
*/
|
|
22064
|
-
async _enqueueTaskMessage(taskId,
|
|
22204
|
+
async _enqueueTaskMessage(taskId, message2, sessionId) {
|
|
22065
22205
|
if (!this._taskStore || !this._taskMessageQueue) {
|
|
22066
22206
|
throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
|
|
22067
22207
|
}
|
|
22068
22208
|
const maxQueueSize = this._options?.maxTaskQueueSize;
|
|
22069
|
-
await this._taskMessageQueue.enqueue(taskId,
|
|
22209
|
+
await this._taskMessageQueue.enqueue(taskId, message2, sessionId, maxQueueSize);
|
|
22070
22210
|
}
|
|
22071
22211
|
/**
|
|
22072
22212
|
* Clears the message queue for a task and rejects any pending request resolvers.
|
|
@@ -22076,9 +22216,9 @@ var Protocol = class {
|
|
|
22076
22216
|
async _clearTaskQueue(taskId, sessionId) {
|
|
22077
22217
|
if (this._taskMessageQueue) {
|
|
22078
22218
|
const messages = await this._taskMessageQueue.dequeueAll(taskId, sessionId);
|
|
22079
|
-
for (const
|
|
22080
|
-
if (
|
|
22081
|
-
const requestId =
|
|
22219
|
+
for (const message2 of messages) {
|
|
22220
|
+
if (message2.type === "request" && isJSONRPCRequest(message2.message)) {
|
|
22221
|
+
const requestId = message2.message.id;
|
|
22082
22222
|
const resolver = this._requestResolvers.get(requestId);
|
|
22083
22223
|
if (resolver) {
|
|
22084
22224
|
resolver(new McpError(ErrorCode.InternalError, "Task cancelled or completed"));
|
|
@@ -23243,14 +23383,14 @@ function toolArgs(args) {
|
|
|
23243
23383
|
return out;
|
|
23244
23384
|
}
|
|
23245
23385
|
function withIdempotency(api2, approvalId) {
|
|
23246
|
-
let
|
|
23386
|
+
let n2 = 0;
|
|
23247
23387
|
return {
|
|
23248
23388
|
...api2,
|
|
23249
23389
|
request: (path, init = {}) => {
|
|
23250
23390
|
const method = (init.method ?? "GET").toUpperCase();
|
|
23251
23391
|
if (method === "GET" || method === "HEAD") return api2.request(path, init);
|
|
23252
23392
|
const headers = new Headers(init.headers);
|
|
23253
|
-
headers.set("Idempotency-Key", idempotencyKey(approvalId, 0,
|
|
23393
|
+
headers.set("Idempotency-Key", idempotencyKey(approvalId, 0, n2++));
|
|
23254
23394
|
return api2.request(path, { ...init, headers });
|
|
23255
23395
|
}
|
|
23256
23396
|
};
|
|
@@ -23258,13 +23398,18 @@ function withIdempotency(api2, approvalId) {
|
|
|
23258
23398
|
var text2 = (value) => [
|
|
23259
23399
|
{ type: "text", text: typeof value === "string" ? value : JSON.stringify(value) }
|
|
23260
23400
|
];
|
|
23261
|
-
function ok(result, extra) {
|
|
23401
|
+
function ok(result, extra, msg) {
|
|
23262
23402
|
const value = result ?? { ok: true };
|
|
23263
23403
|
const structured = value && typeof value === "object" && !Array.isArray(value) ? value : { items: value };
|
|
23264
|
-
return { content: text2(value), structuredContent: { ...structured, ...extra } };
|
|
23404
|
+
if (!msg) return { content: text2(value), structuredContent: { ...structured, ...extra } };
|
|
23405
|
+
return {
|
|
23406
|
+
content: [...text2(messageText(msg)), ...text2(value)],
|
|
23407
|
+
structuredContent: { ...structured, ...extra, message: msg }
|
|
23408
|
+
};
|
|
23265
23409
|
}
|
|
23266
|
-
function fail(
|
|
23267
|
-
return { content: text2({ error:
|
|
23410
|
+
function fail(error2, tool2) {
|
|
23411
|
+
if (!tool2) return { content: text2({ error: error2 }), isError: true };
|
|
23412
|
+
return { content: [...text2(messageText(message(tool2, void 0, { error: error2 }))), ...text2({ error: error2 })], isError: true };
|
|
23268
23413
|
}
|
|
23269
23414
|
function errorMessage2(e) {
|
|
23270
23415
|
if (e instanceof SignInRequiredError) return "The sign-in has expired. Reconnect CMO.so and try again.";
|
|
@@ -23404,7 +23549,10 @@ function createMcpServer(deps) {
|
|
|
23404
23549
|
);
|
|
23405
23550
|
const callArgs = approval ? withFreshFiles(t, approval.calls[0]?.args ?? {}, toolArgs(args)) : toolArgs(args);
|
|
23406
23551
|
const ctx = { api: api2, domain, client: "mcp" };
|
|
23407
|
-
if (!isWrite(t))
|
|
23552
|
+
if (!isWrite(t)) {
|
|
23553
|
+
const value = await t.run(ctx, callArgs);
|
|
23554
|
+
return ok(value, viewForTool(t.name) ? { workspace: domain } : void 0, message(t.name, value));
|
|
23555
|
+
}
|
|
23408
23556
|
let standing = null;
|
|
23409
23557
|
if (!approval && !deps.previewOnly && domain && isStanding(t.name)) {
|
|
23410
23558
|
const claim2 = await api2.account?.claimStanding({ website: domain, tool: t.name, units: standingUnits(t.name, callArgs) }).catch(() => null);
|
|
@@ -23426,14 +23574,19 @@ function createMcpServer(deps) {
|
|
|
23426
23574
|
const calls = [{ name: t.name, args: callArgs }];
|
|
23427
23575
|
const summary2 = t.confirm?.(callArgs, "en") ?? t.description;
|
|
23428
23576
|
const cost = await previewCost(api2, domain, t);
|
|
23429
|
-
|
|
23430
|
-
|
|
23431
|
-
|
|
23432
|
-
|
|
23433
|
-
|
|
23434
|
-
|
|
23435
|
-
|
|
23436
|
-
|
|
23577
|
+
const preview = cost ? `${summary2} ${cost}` : summary2;
|
|
23578
|
+
return ok(
|
|
23579
|
+
{
|
|
23580
|
+
status: "needs_confirmation",
|
|
23581
|
+
preview,
|
|
23582
|
+
risk: t.risk,
|
|
23583
|
+
workspace: domain,
|
|
23584
|
+
confirmation: signer.sign({ calls, principal, domain }),
|
|
23585
|
+
next: "Show the preview to the user. If they agree, call this tool again with confirm: true and this confirmation (it runs exactly what was previewed). Nothing has changed yet."
|
|
23586
|
+
},
|
|
23587
|
+
void 0,
|
|
23588
|
+
message(t.name, void 0, { preview })
|
|
23589
|
+
);
|
|
23437
23590
|
}
|
|
23438
23591
|
const summary = `${t.confirm?.(callArgs, "en") ?? t.description}${standing ? ` (standing permission #${standing})` : ""}`;
|
|
23439
23592
|
try {
|
|
@@ -23441,14 +23594,14 @@ function createMcpServer(deps) {
|
|
|
23441
23594
|
const added = t.name === "website_add" ? result?.domain : null;
|
|
23442
23595
|
const where = typeof added === "string" && added ? added : domain;
|
|
23443
23596
|
await deps.audit?.({ domain: where, actions: [{ tool: t.name, summary, ok: true, action_id: approval.id }] }).catch(() => void 0);
|
|
23444
|
-
return ok(result);
|
|
23597
|
+
return ok(result, void 0, message(t.name, result, { done: summary }));
|
|
23445
23598
|
} catch (e) {
|
|
23446
23599
|
const error2 = errorMessage2(e);
|
|
23447
23600
|
await deps.audit?.({ domain, actions: [{ tool: t.name, summary, ok: false, error: error2, action_id: approval.id }] }).catch(() => void 0);
|
|
23448
|
-
return fail(error2);
|
|
23601
|
+
return fail(error2, t.name);
|
|
23449
23602
|
}
|
|
23450
23603
|
} catch (e) {
|
|
23451
|
-
return fail(errorMessage2(e));
|
|
23604
|
+
return fail(errorMessage2(e), t.name);
|
|
23452
23605
|
}
|
|
23453
23606
|
});
|
|
23454
23607
|
server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({
|
|
@@ -23578,8 +23731,8 @@ var ReadBuffer = class {
|
|
|
23578
23731
|
function deserializeMessage(line) {
|
|
23579
23732
|
return JSONRPCMessageSchema.parse(JSON.parse(line));
|
|
23580
23733
|
}
|
|
23581
|
-
function serializeMessage(
|
|
23582
|
-
return JSON.stringify(
|
|
23734
|
+
function serializeMessage(message2) {
|
|
23735
|
+
return JSON.stringify(message2) + "\n";
|
|
23583
23736
|
}
|
|
23584
23737
|
|
|
23585
23738
|
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.30.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
@@ -23617,11 +23770,11 @@ var StdioServerTransport = class {
|
|
|
23617
23770
|
processReadBuffer() {
|
|
23618
23771
|
while (true) {
|
|
23619
23772
|
try {
|
|
23620
|
-
const
|
|
23621
|
-
if (
|
|
23773
|
+
const message2 = this._readBuffer.readMessage();
|
|
23774
|
+
if (message2 === null) {
|
|
23622
23775
|
break;
|
|
23623
23776
|
}
|
|
23624
|
-
this.onmessage?.(
|
|
23777
|
+
this.onmessage?.(message2);
|
|
23625
23778
|
} catch (error2) {
|
|
23626
23779
|
this.onerror?.(error2);
|
|
23627
23780
|
}
|
|
@@ -23637,9 +23790,9 @@ var StdioServerTransport = class {
|
|
|
23637
23790
|
this._readBuffer.clear();
|
|
23638
23791
|
this.onclose?.();
|
|
23639
23792
|
}
|
|
23640
|
-
send(
|
|
23793
|
+
send(message2) {
|
|
23641
23794
|
return new Promise((resolve) => {
|
|
23642
|
-
const json = serializeMessage(
|
|
23795
|
+
const json = serializeMessage(message2);
|
|
23643
23796
|
if (this._stdout.write(json)) {
|
|
23644
23797
|
resolve();
|
|
23645
23798
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmo-so/mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "CMO.so's MCP server for Claude Desktop, Cursor, VS Code and other MCP clients: manage your websites, blog posts, LinkedIn queue and results with Maggie.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|