@craftsamo/whatsapp-tools 0.1.0 → 0.1.2
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/.antigravity-plugin/plugin.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -1
- package/README.md +58 -12
- package/dist/cli.js +212 -146
- package/dist/mcp.js +206 -107
- package/dist/opencode.js +192 -105
- package/package.json +1 -1
- package/plugin.yaml +1 -1
- package/src/hermes/whatsapp_tools_hermes/approval.py +1 -6
- package/src/hermes/whatsapp_tools_hermes/plugin.py +2 -2
- package/src/hermes/whatsapp_tools_hermes/project.py +4 -4
- package/src/hermes/whatsapp_tools_hermes/settings.py +15 -69
package/dist/mcp.js
CHANGED
|
@@ -2984,7 +2984,7 @@ var require_compile = __commonJS({
|
|
|
2984
2984
|
const schOrFunc = root.refs[ref];
|
|
2985
2985
|
if (schOrFunc)
|
|
2986
2986
|
return schOrFunc;
|
|
2987
|
-
let _sch =
|
|
2987
|
+
let _sch = resolve5.call(this, root, ref);
|
|
2988
2988
|
if (_sch === void 0) {
|
|
2989
2989
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
2990
2990
|
const { schemaId } = this.opts;
|
|
@@ -3011,7 +3011,7 @@ var require_compile = __commonJS({
|
|
|
3011
3011
|
function sameSchemaEnv(s1, s2) {
|
|
3012
3012
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3013
3013
|
}
|
|
3014
|
-
function
|
|
3014
|
+
function resolve5(root, ref) {
|
|
3015
3015
|
let sch;
|
|
3016
3016
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
3017
3017
|
ref = sch;
|
|
@@ -3875,7 +3875,7 @@ var require_fast_uri = __commonJS({
|
|
|
3875
3875
|
}
|
|
3876
3876
|
return uri;
|
|
3877
3877
|
}
|
|
3878
|
-
function
|
|
3878
|
+
function resolve5(baseURI, relativeURI, options) {
|
|
3879
3879
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3880
3880
|
const {
|
|
3881
3881
|
parsed: baseParsed,
|
|
@@ -4266,7 +4266,7 @@ var require_fast_uri = __commonJS({
|
|
|
4266
4266
|
var fastUri = {
|
|
4267
4267
|
SCHEMES,
|
|
4268
4268
|
normalize,
|
|
4269
|
-
resolve:
|
|
4269
|
+
resolve: resolve5,
|
|
4270
4270
|
resolveComponent,
|
|
4271
4271
|
equal,
|
|
4272
4272
|
serialize,
|
|
@@ -12325,7 +12325,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
|
|
|
12325
12325
|
var NONE = 0;
|
|
12326
12326
|
var ASSUMED = 1;
|
|
12327
12327
|
var PROVEN = 2;
|
|
12328
|
-
function isRecursive(inst, stack,
|
|
12328
|
+
function isRecursive(inst, stack, resolve5) {
|
|
12329
12329
|
const cached2 = recursive.get(inst);
|
|
12330
12330
|
if (cached2 !== void 0)
|
|
12331
12331
|
return cached2 ? PROVEN : NONE;
|
|
@@ -12335,7 +12335,7 @@ function isRecursive(inst, stack, resolve7) {
|
|
|
12335
12335
|
let result = NONE;
|
|
12336
12336
|
const check2 = (child) => {
|
|
12337
12337
|
if (result !== PROVEN && child?._zod) {
|
|
12338
|
-
const answer = isRecursive(child, stack,
|
|
12338
|
+
const answer = isRecursive(child, stack, resolve5);
|
|
12339
12339
|
if (answer > result)
|
|
12340
12340
|
result = answer;
|
|
12341
12341
|
}
|
|
@@ -12346,7 +12346,7 @@ function isRecursive(inst, stack, resolve7) {
|
|
|
12346
12346
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
12347
12347
|
if (spread && !desc.enumerable)
|
|
12348
12348
|
continue;
|
|
12349
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
12349
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve5) : NONE;
|
|
12350
12350
|
if (child > answer)
|
|
12351
12351
|
answer = child;
|
|
12352
12352
|
}
|
|
@@ -12410,7 +12410,7 @@ function isRecursive(inst, stack, resolve7) {
|
|
|
12410
12410
|
break;
|
|
12411
12411
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
12412
12412
|
case "lazy": {
|
|
12413
|
-
const inner = def._cachedInner ?? (
|
|
12413
|
+
const inner = def._cachedInner ?? (resolve5 ? inst._zod.innerType : void 0);
|
|
12414
12414
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
12415
12415
|
break;
|
|
12416
12416
|
}
|
|
@@ -28587,12 +28587,12 @@ var StdioServerTransport = class {
|
|
|
28587
28587
|
this.onclose?.();
|
|
28588
28588
|
}
|
|
28589
28589
|
send(message) {
|
|
28590
|
-
return new Promise((
|
|
28590
|
+
return new Promise((resolve5) => {
|
|
28591
28591
|
const json2 = serializeMessage(message);
|
|
28592
28592
|
if (this._stdout.write(json2)) {
|
|
28593
|
-
|
|
28593
|
+
resolve5();
|
|
28594
28594
|
} else {
|
|
28595
|
-
this._stdout.once("drain",
|
|
28595
|
+
this._stdout.once("drain", resolve5);
|
|
28596
28596
|
}
|
|
28597
28597
|
});
|
|
28598
28598
|
}
|
|
@@ -28639,7 +28639,7 @@ function abortError(signal) {
|
|
|
28639
28639
|
}
|
|
28640
28640
|
function exec(argv, options) {
|
|
28641
28641
|
const { signal } = options;
|
|
28642
|
-
return new Promise((
|
|
28642
|
+
return new Promise((resolve5, reject) => {
|
|
28643
28643
|
if (signal?.aborted) {
|
|
28644
28644
|
reject(abortError(signal));
|
|
28645
28645
|
return;
|
|
@@ -28698,7 +28698,7 @@ function exec(argv, options) {
|
|
|
28698
28698
|
}
|
|
28699
28699
|
const finish = () => settle2(() => {
|
|
28700
28700
|
const { code, killedBy } = exitedWith ?? { code: null, killedBy: null };
|
|
28701
|
-
|
|
28701
|
+
resolve5({
|
|
28702
28702
|
code: code ?? -1,
|
|
28703
28703
|
stdout,
|
|
28704
28704
|
stderr,
|
|
@@ -28882,6 +28882,10 @@ function packageRoot(bundleUrl) {
|
|
|
28882
28882
|
return dirname(dirname(fileURLToPath(bundleUrl)));
|
|
28883
28883
|
}
|
|
28884
28884
|
|
|
28885
|
+
// src/entry/settings.ts
|
|
28886
|
+
import { homedir as homedir2 } from "node:os";
|
|
28887
|
+
import { isAbsolute as isAbsolute3, join, resolve as resolvePath, sep as sep2 } from "node:path";
|
|
28888
|
+
|
|
28885
28889
|
// src/project.ts
|
|
28886
28890
|
var PROJECT = {
|
|
28887
28891
|
/** The plugin, MCP server and program name. */
|
|
@@ -28896,70 +28900,53 @@ var PROJECT = {
|
|
|
28896
28900
|
toolsets: ["account", "chats", "contacts", "history", "files", "sends", "actions"],
|
|
28897
28901
|
/** The toolsets on when a setting names none. */
|
|
28898
28902
|
defaultToolsets: ["account", "chats", "contacts", "history", "sends"],
|
|
28903
|
+
/** The package's own settings, which the tools themselves read: each snake_case name and its type, with bounds when it needs them. */
|
|
28904
|
+
options: {
|
|
28905
|
+
state_dir: "path",
|
|
28906
|
+
download_dir: "path",
|
|
28907
|
+
send_dirs: "paths"
|
|
28908
|
+
},
|
|
28899
28909
|
/** The environment variables the tools read besides the settings, which Codex forwards to the server after them. */
|
|
28900
28910
|
toolVariables: []
|
|
28901
28911
|
};
|
|
28902
28912
|
|
|
28903
28913
|
// src/entry/directory.ts
|
|
28904
28914
|
import { homedir } from "node:os";
|
|
28905
|
-
import { isAbsolute as isAbsolute2,
|
|
28915
|
+
import { isAbsolute as isAbsolute2, resolve } from "node:path";
|
|
28916
|
+
var DOWNLOADS_DIR = "Downloads";
|
|
28906
28917
|
function homeDir(env7) {
|
|
28907
28918
|
const envHome = env7.HOME;
|
|
28908
28919
|
if (envHome && isAbsolute2(envHome)) return envHome;
|
|
28909
28920
|
return homedir();
|
|
28910
28921
|
}
|
|
28911
|
-
function
|
|
28912
|
-
|
|
28913
|
-
if (text2.startsWith("~/") || text2.startsWith(`~${sep2}`)) {
|
|
28914
|
-
return join(home, text2.slice(2));
|
|
28915
|
-
}
|
|
28916
|
-
return text2;
|
|
28922
|
+
function pathOf(value) {
|
|
28923
|
+
return typeof value === "string" ? value : void 0;
|
|
28917
28924
|
}
|
|
28918
|
-
function
|
|
28919
|
-
|
|
28920
|
-
|
|
28921
|
-
|
|
28922
|
-
|
|
28923
|
-
|
|
28924
|
-
|
|
28925
|
+
function pathsOf(value) {
|
|
28926
|
+
return typeof value === "object" ? value : [];
|
|
28927
|
+
}
|
|
28928
|
+
function directorySettings(options, env7, profile) {
|
|
28929
|
+
const home = homeDir(env7);
|
|
28930
|
+
const xdg = env7.XDG_STATE_HOME;
|
|
28931
|
+
const stateHome = xdg && isAbsolute2(xdg) ? xdg : resolve(home, ".local", "state");
|
|
28932
|
+
return {
|
|
28933
|
+
state_dir: pathOf(options.state_dir) ?? resolve(stateHome, profile.name),
|
|
28934
|
+
download_dir: pathOf(options.download_dir) ?? resolve(home, DOWNLOADS_DIR, profile.name),
|
|
28935
|
+
send_dirs: [...new Set(pathsOf(options.send_dirs))]
|
|
28936
|
+
};
|
|
28925
28937
|
}
|
|
28926
28938
|
function toolDirectories(settings) {
|
|
28927
28939
|
return { stateDir: settings.state_dir, downloadDir: settings.download_dir, sendDirs: settings.send_dirs };
|
|
28928
28940
|
}
|
|
28929
28941
|
|
|
28930
|
-
// src/entry/download-dir.ts
|
|
28931
|
-
import { resolve as resolve2 } from "node:path";
|
|
28932
|
-
var DOWNLOADS_DIR = "Downloads";
|
|
28933
|
-
function resolveDownloadDir(given, env7, profile) {
|
|
28934
|
-
const home = homeDir(env7);
|
|
28935
|
-
return given !== void 0 ? resolveGivenDirectory(given, home) : resolve2(home, DOWNLOADS_DIR, profile.name);
|
|
28936
|
-
}
|
|
28937
|
-
|
|
28938
28942
|
// src/entry/profile.ts
|
|
28939
28943
|
var PROJECT_PROFILE = {
|
|
28940
28944
|
name: PROJECT.name,
|
|
28941
28945
|
envPrefix: PROJECT.envPrefix,
|
|
28942
|
-
toolsets: { names: PROJECT.toolsets, defaults: PROJECT.defaultToolsets }
|
|
28946
|
+
toolsets: { names: PROJECT.toolsets, defaults: PROJECT.defaultToolsets },
|
|
28947
|
+
options: PROJECT.options
|
|
28943
28948
|
};
|
|
28944
28949
|
|
|
28945
|
-
// src/entry/send-dirs.ts
|
|
28946
|
-
function resolveSendDirs(given, env7) {
|
|
28947
|
-
const home = homeDir(env7);
|
|
28948
|
-
return [...new Set(given.map((directory) => resolveGivenDirectory(directory, home)))];
|
|
28949
|
-
}
|
|
28950
|
-
|
|
28951
|
-
// src/entry/state-dir.ts
|
|
28952
|
-
import { isAbsolute as isAbsolute3, resolve as resolve3 } from "node:path";
|
|
28953
|
-
function resolveStateDir(given, env7, profile) {
|
|
28954
|
-
const home = homeDir(env7);
|
|
28955
|
-
if (given !== void 0) return resolveGivenDirectory(given, home);
|
|
28956
|
-
const xdg = env7.XDG_STATE_HOME;
|
|
28957
|
-
if (xdg && isAbsolute3(xdg)) {
|
|
28958
|
-
return resolve3(xdg, profile.name);
|
|
28959
|
-
}
|
|
28960
|
-
return resolve3(home, ".local", "state", profile.name);
|
|
28961
|
-
}
|
|
28962
|
-
|
|
28963
28950
|
// src/entry/settings.ts
|
|
28964
28951
|
var CONFIRM_MODES = ["harness", "elicitation"];
|
|
28965
28952
|
var ALL_TOOLSETS = "all";
|
|
@@ -28970,17 +28957,28 @@ var OPTIONS = {
|
|
|
28970
28957
|
read_only: { flag: "--read-only", envSuffix: "READ_ONLY", boolean: true },
|
|
28971
28958
|
tools: { flag: "--tools", envSuffix: "TOOLS" },
|
|
28972
28959
|
exclude_tools: { flag: "--exclude-tools", envSuffix: "EXCLUDE_TOOLS" },
|
|
28973
|
-
confirm: { flag: "--confirm", envSuffix: "CONFIRM" }
|
|
28974
|
-
state_dir: { flag: "--state-dir", envSuffix: "STATE_DIR" },
|
|
28975
|
-
download_dir: { flag: "--download-dir", envSuffix: "DOWNLOAD_DIR" },
|
|
28976
|
-
send_dirs: { flag: "--send-dirs", envSuffix: "SEND_DIRS" }
|
|
28960
|
+
confirm: { flag: "--confirm", envSuffix: "CONFIRM" }
|
|
28977
28961
|
};
|
|
28962
|
+
function profileOptions(profile) {
|
|
28963
|
+
return profile.options ?? {};
|
|
28964
|
+
}
|
|
28965
|
+
function settingOptions(profile) {
|
|
28966
|
+
const toolOptions = Object.entries(profileOptions(profile)).map(([name, spec]) => [
|
|
28967
|
+
name,
|
|
28968
|
+
{
|
|
28969
|
+
flag: `--${name.replace(/_/g, "-")}`,
|
|
28970
|
+
envSuffix: name.toUpperCase(),
|
|
28971
|
+
...optionType(spec) === "boolean" && { boolean: true }
|
|
28972
|
+
}
|
|
28973
|
+
]);
|
|
28974
|
+
return { ...OPTIONS, ...Object.fromEntries(toolOptions) };
|
|
28975
|
+
}
|
|
28978
28976
|
function envName(name, profile) {
|
|
28979
|
-
return `${profile.envPrefix}_${
|
|
28977
|
+
return `${profile.envPrefix}_${settingOptions(profile)[name].envSuffix}`;
|
|
28980
28978
|
}
|
|
28981
|
-
function readFlags(argv) {
|
|
28979
|
+
function readFlags(argv, profile) {
|
|
28982
28980
|
const byFlag = new Map(
|
|
28983
|
-
Object.
|
|
28981
|
+
Object.entries(settingOptions(profile)).map(([name, option]) => [option.flag, { name, ...option }])
|
|
28984
28982
|
);
|
|
28985
28983
|
const given = {};
|
|
28986
28984
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -29005,9 +29003,6 @@ function readFlags(argv) {
|
|
|
29005
29003
|
function splitList(value) {
|
|
29006
29004
|
return value.split(",").map((item) => item.trim()).filter((item) => item !== "");
|
|
29007
29005
|
}
|
|
29008
|
-
function listedDirectories(given) {
|
|
29009
|
-
return given === void 0 ? [] : splitList(given.text).map((text2) => ({ text: text2, source: given.source }));
|
|
29010
|
-
}
|
|
29011
29006
|
function checkToolsets(names, source, toolsets) {
|
|
29012
29007
|
if (names.includes(ALL_TOOLSETS)) return ALL_TOOLSETS;
|
|
29013
29008
|
const unknown2 = names.find((name) => !toolsets.names.includes(name));
|
|
@@ -29036,20 +29031,99 @@ function parseConfirm(value, source) {
|
|
|
29036
29031
|
}
|
|
29037
29032
|
return mode;
|
|
29038
29033
|
}
|
|
29034
|
+
function parseNumber(value, source) {
|
|
29035
|
+
const trimmed = value.trim();
|
|
29036
|
+
const parsed = trimmed === "" ? Number.NaN : Number(trimmed);
|
|
29037
|
+
if (!Number.isFinite(parsed)) {
|
|
29038
|
+
throw new ToolError("invalid_argument", `Unknown number "${value}" in ${source}; use a finite number.`);
|
|
29039
|
+
}
|
|
29040
|
+
return parsed;
|
|
29041
|
+
}
|
|
29042
|
+
function absolutePath(text2, source, env7) {
|
|
29043
|
+
const home = env7.HOME !== void 0 && isAbsolute3(env7.HOME) ? env7.HOME : homedir2();
|
|
29044
|
+
const expanded = text2 === "~" || text2.startsWith("~/") || text2.startsWith(`~${sep2}`) ? join(home, text2.slice(1)) : text2;
|
|
29045
|
+
if (!isAbsolute3(expanded)) throw new ToolError("invalid_argument", `${source} must be an absolute path.`);
|
|
29046
|
+
return resolvePath(expanded);
|
|
29047
|
+
}
|
|
29048
|
+
function absolutePaths(items, source, env7) {
|
|
29049
|
+
return items.length > 0 ? items.map((item) => absolutePath(item, source, env7)) : void 0;
|
|
29050
|
+
}
|
|
29039
29051
|
function envText(name, env7, profile) {
|
|
29040
29052
|
const variable = envName(name, profile);
|
|
29041
29053
|
const text2 = env7[variable];
|
|
29042
29054
|
return text2 === void 0 || text2.trim() === "" ? void 0 : { text: text2, source: variable };
|
|
29043
29055
|
}
|
|
29056
|
+
function optionType(spec) {
|
|
29057
|
+
return typeof spec === "string" ? spec : spec.type;
|
|
29058
|
+
}
|
|
29059
|
+
function itemCount(count) {
|
|
29060
|
+
return count === 1 ? "1 item" : `${count} items`;
|
|
29061
|
+
}
|
|
29062
|
+
function numberBoundsError({ integer: integer2, min, max }, source) {
|
|
29063
|
+
const range = min !== void 0 && max !== void 0 ? ` from ${min} to ${max}` : min !== void 0 ? ` of at least ${min}` : max !== void 0 ? ` of at most ${max}` : "";
|
|
29064
|
+
return new ToolError("invalid_argument", `${source} must be ${integer2 ? "a whole number" : "a number"}${range}.`);
|
|
29065
|
+
}
|
|
29066
|
+
function countBoundsError({ min, max }, source) {
|
|
29067
|
+
const range = min !== void 0 && max !== void 0 ? `from ${min} to ${max} items` : min !== void 0 ? `at least ${itemCount(min)}` : `at most ${itemCount(max)}`;
|
|
29068
|
+
return new ToolError("invalid_argument", `${source} must list ${range}.`);
|
|
29069
|
+
}
|
|
29070
|
+
function withinBounds(spec, value, source) {
|
|
29071
|
+
if (value === void 0 || typeof spec === "string") return value;
|
|
29072
|
+
const bounds = spec;
|
|
29073
|
+
const { integer: integer2, min, max } = bounds;
|
|
29074
|
+
if (typeof value === "number") {
|
|
29075
|
+
if (integer2 && !Number.isInteger(value) || min !== void 0 && value < min || max !== void 0 && value > max) {
|
|
29076
|
+
throw numberBoundsError(bounds, source);
|
|
29077
|
+
}
|
|
29078
|
+
} else if (typeof value === "object" && (min !== void 0 && value.length < min || max !== void 0 && value.length > max)) {
|
|
29079
|
+
throw countBoundsError(bounds, source);
|
|
29080
|
+
}
|
|
29081
|
+
return value;
|
|
29082
|
+
}
|
|
29083
|
+
function parseOptionText(spec, given, env7) {
|
|
29084
|
+
return withinBounds(spec, parseTypedText(optionType(spec), given, env7), given.source);
|
|
29085
|
+
}
|
|
29086
|
+
function parseTypedText(kind, given, env7) {
|
|
29087
|
+
switch (kind) {
|
|
29088
|
+
case "text":
|
|
29089
|
+
return nonBlank(given.text);
|
|
29090
|
+
case "boolean":
|
|
29091
|
+
return parseBoolean(given.text, given.source);
|
|
29092
|
+
case "number":
|
|
29093
|
+
return parseNumber(given.text, given.source);
|
|
29094
|
+
case "list": {
|
|
29095
|
+
const items = splitList(given.text);
|
|
29096
|
+
return items.length > 0 ? items : void 0;
|
|
29097
|
+
}
|
|
29098
|
+
case "path": {
|
|
29099
|
+
const text2 = nonBlank(given.text);
|
|
29100
|
+
return text2 === void 0 ? void 0 : absolutePath(text2, given.source, env7);
|
|
29101
|
+
}
|
|
29102
|
+
case "paths":
|
|
29103
|
+
return absolutePaths(splitList(given.text), given.source, env7);
|
|
29104
|
+
}
|
|
29105
|
+
}
|
|
29106
|
+
function optionsFrom(flags, env7, profile) {
|
|
29107
|
+
const options = {};
|
|
29108
|
+
for (const [name, spec] of Object.entries(profileOptions(profile))) {
|
|
29109
|
+
if (flags[name] !== void 0) {
|
|
29110
|
+
const parsed = parseOptionText(spec, { text: flags[name], source: settingOptions(profile)[name].flag }, env7);
|
|
29111
|
+
if (parsed !== void 0) options[name] = parsed;
|
|
29112
|
+
continue;
|
|
29113
|
+
}
|
|
29114
|
+
const fromEnv = envText(name, env7, profile);
|
|
29115
|
+
if (fromEnv !== void 0) {
|
|
29116
|
+
const parsed = parseOptionText(spec, fromEnv, env7);
|
|
29117
|
+
if (parsed !== void 0) options[name] = parsed;
|
|
29118
|
+
}
|
|
29119
|
+
}
|
|
29120
|
+
return options;
|
|
29121
|
+
}
|
|
29044
29122
|
function parseSettings(argv, env7, profile = PROJECT_PROFILE) {
|
|
29045
|
-
const flags = readFlags(argv);
|
|
29123
|
+
const flags = readFlags(argv, profile);
|
|
29046
29124
|
const value = (name) => flags[name] !== void 0 ? { text: flags[name], source: OPTIONS[name].flag } : envText(name, env7, profile);
|
|
29047
|
-
const
|
|
29048
|
-
|
|
29049
|
-
state_dir: resolveStateDir(value("state_dir"), env7, profile),
|
|
29050
|
-
download_dir: resolveDownloadDir(value("download_dir"), env7, profile),
|
|
29051
|
-
send_dirs: resolveSendDirs(listedDirectories(value("send_dirs")), env7)
|
|
29052
|
-
};
|
|
29125
|
+
const options = optionsFrom(flags, env7, profile);
|
|
29126
|
+
const settings = { confirm: "harness", ...directorySettings(options, env7, profile), options };
|
|
29053
29127
|
const toolsets = value("toolsets");
|
|
29054
29128
|
if (toolsets) settings.toolsets = checkToolsets(splitList(toolsets.text), toolsets.source, profile.toolsets);
|
|
29055
29129
|
const readOnly = value("read_only");
|
|
@@ -29062,17 +29136,10 @@ function parseSettings(argv, env7, profile = PROJECT_PROFILE) {
|
|
|
29062
29136
|
if (confirm) settings.confirm = parseConfirm(confirm.text.trim(), confirm.source);
|
|
29063
29137
|
return settings;
|
|
29064
29138
|
}
|
|
29065
|
-
|
|
29066
|
-
|
|
29067
|
-
"
|
|
29068
|
-
|
|
29069
|
-
"exclude_tools",
|
|
29070
|
-
"state_dir",
|
|
29071
|
-
"download_dir",
|
|
29072
|
-
"send_dirs"
|
|
29073
|
-
];
|
|
29074
|
-
var LANGUAGE_OPTION = "language";
|
|
29075
|
-
var PLUGIN_OPTION_NAMES = [...TOOL_OPTION_NAMES, LANGUAGE_OPTION];
|
|
29139
|
+
function nonBlank(text2) {
|
|
29140
|
+
const trimmed = text2?.trim();
|
|
29141
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
29142
|
+
}
|
|
29076
29143
|
|
|
29077
29144
|
// src/core/account/read.ts
|
|
29078
29145
|
import { env as env2 } from "node:process";
|
|
@@ -30815,7 +30882,7 @@ var deleteResult = external_exports.object({
|
|
|
30815
30882
|
var deleteAnswer = deleteResult.extend({ service_running: external_exports.boolean() });
|
|
30816
30883
|
|
|
30817
30884
|
// src/core/whatsapp/file-send.ts
|
|
30818
|
-
import { isAbsolute as isAbsolute5, resolve as
|
|
30885
|
+
import { isAbsolute as isAbsolute5, resolve as resolve2 } from "node:path";
|
|
30819
30886
|
var FILE_SEND_OP = "file_send";
|
|
30820
30887
|
var SEND_AS = ["image", "video", "audio", "document"];
|
|
30821
30888
|
var FILE_CAPTION_MAX_CHARACTERS = 1024;
|
|
@@ -30954,7 +31021,7 @@ function callService(paths, op, args, { mode, signal, timeoutMs: requestedMs = D
|
|
|
30954
31021
|
if (signal?.aborted) return Promise.reject(abortError(signal));
|
|
30955
31022
|
const timeoutMs = Number.isNaN(requestedMs) ? DEFAULT_TIMEOUT_MS2 : Math.min(Math.max(Math.ceil(requestedMs), 1), MAX_DEADLINE_MS);
|
|
30956
31023
|
const request = encodeLine({ op, args, deadline_ms: timeoutMs });
|
|
30957
|
-
return new Promise((
|
|
31024
|
+
return new Promise((resolve5, reject) => {
|
|
30958
31025
|
const socket = createConnection(paths.socket);
|
|
30959
31026
|
socket.setEncoding("utf8");
|
|
30960
31027
|
let sent = false;
|
|
@@ -30999,7 +31066,7 @@ function callService(paths, op, args, { mode, signal, timeoutMs: requestedMs = D
|
|
|
30999
31066
|
if (end === -1) return;
|
|
31000
31067
|
const response = parseResponse(received.slice(0, end));
|
|
31001
31068
|
if (!response) return unknownOutcome2("The sync service's answer could not be read");
|
|
31002
|
-
if (response.ok) return finish(() =>
|
|
31069
|
+
if (response.ok) return finish(() => resolve5(response.data));
|
|
31003
31070
|
fail(new ToolError(response.error.code, response.error.message));
|
|
31004
31071
|
});
|
|
31005
31072
|
socket.on("error", (error62) => {
|
|
@@ -32421,7 +32488,7 @@ function parseOctal(field) {
|
|
|
32421
32488
|
}
|
|
32422
32489
|
return digits > 0 ? value : void 0;
|
|
32423
32490
|
}
|
|
32424
|
-
function
|
|
32491
|
+
function parseNumber2(field) {
|
|
32425
32492
|
const first = field[0];
|
|
32426
32493
|
if (first === void 0 || (first & BASE256_FLAG) === 0) return parseOctal(field);
|
|
32427
32494
|
if (first === BASE256_NEGATIVE) return void 0;
|
|
@@ -32460,7 +32527,7 @@ function parseHeader(block) {
|
|
|
32460
32527
|
path[prefix.length] = "/".charCodeAt(0);
|
|
32461
32528
|
path.set(name, prefix.length + 1);
|
|
32462
32529
|
}
|
|
32463
|
-
return { path, size:
|
|
32530
|
+
return { path, size: parseNumber2(block.subarray(SIZE_START, SIZE_END)), type: block[TYPE_OFFSET] };
|
|
32464
32531
|
}
|
|
32465
32532
|
function parseDecimal(text2) {
|
|
32466
32533
|
if (!/^[0-9]{1,15}$/.test(text2)) return void 0;
|
|
@@ -34086,7 +34153,7 @@ var whatsappFileSave = createFileSave();
|
|
|
34086
34153
|
|
|
34087
34154
|
// src/core/file/send/tool.ts
|
|
34088
34155
|
import { realpath as realpath5 } from "node:fs/promises";
|
|
34089
|
-
import { resolve as
|
|
34156
|
+
import { resolve as resolve4 } from "node:path";
|
|
34090
34157
|
|
|
34091
34158
|
// src/core/outgoing/limits.ts
|
|
34092
34159
|
var MAX_FILES = 10;
|
|
@@ -34317,7 +34384,7 @@ function kindOf(name, head, { asDocument = false } = {}) {
|
|
|
34317
34384
|
}
|
|
34318
34385
|
|
|
34319
34386
|
// src/core/file/send/resolve-files.ts
|
|
34320
|
-
import { homedir as
|
|
34387
|
+
import { homedir as homedir3 } from "node:os";
|
|
34321
34388
|
|
|
34322
34389
|
// src/core/outgoing/roots.ts
|
|
34323
34390
|
import { realpath as realpath3 } from "node:fs/promises";
|
|
@@ -34355,7 +34422,7 @@ async function allowedRoots({ cwd, sendDirs, home, forbidden }) {
|
|
|
34355
34422
|
|
|
34356
34423
|
// src/core/outgoing/resolve.ts
|
|
34357
34424
|
import { lstat as lstat5, realpath as realpath4 } from "node:fs/promises";
|
|
34358
|
-
import { basename as basename2, resolve as
|
|
34425
|
+
import { basename as basename2, resolve as resolve3, sep as sep4 } from "node:path";
|
|
34359
34426
|
|
|
34360
34427
|
// src/core/outgoing/deny-lists.ts
|
|
34361
34428
|
import { sep as sep3 } from "node:path";
|
|
@@ -34441,7 +34508,7 @@ async function realPathOf(path, shown) {
|
|
|
34441
34508
|
}
|
|
34442
34509
|
async function resolveOutgoing(path, { cwd, roots, forbidden, home }) {
|
|
34443
34510
|
const shown = JSON.stringify(path);
|
|
34444
|
-
const real = await realPathOf(
|
|
34511
|
+
const real = await realPathOf(resolve3(cwd, path), shown);
|
|
34445
34512
|
const stats = await lstat5(real, { bigint: true });
|
|
34446
34513
|
if (!stats.isFile()) throw new ToolError("invalid_argument", `${shown} is not a regular file.`);
|
|
34447
34514
|
if (stats.nlink > 1n) throw hardLinked(shown);
|
|
@@ -34472,7 +34539,7 @@ async function resolveOutgoing(path, { cwd, roots, forbidden, home }) {
|
|
|
34472
34539
|
// src/core/file/send/resolve-files.ts
|
|
34473
34540
|
async function resolveFiles(files, ctx) {
|
|
34474
34541
|
const forbidden = [ctx.stateDir, ctx.ownDir].filter((directory) => directory !== void 0);
|
|
34475
|
-
const home =
|
|
34542
|
+
const home = homedir3();
|
|
34476
34543
|
const roots = await allowedRoots({ cwd: ctx.cwd, sendDirs: ctx.sendDirs ?? [], home, forbidden });
|
|
34477
34544
|
const seen = /* @__PURE__ */ new Set();
|
|
34478
34545
|
const resolvedFiles = [];
|
|
@@ -34953,7 +35020,7 @@ var CAPTION_RULES = {
|
|
|
34953
35020
|
};
|
|
34954
35021
|
var CAPTION_ON_AUDIO = "A caption on an audio file is dropped by WhatsApp without a word, so it is refused. Send the audio without text, send it as a document with as_document, or put the text in a message of its own with whatsapp_message_send if the user wants that. Nothing was sent.";
|
|
34955
35022
|
async function fileTarget(path, cwd) {
|
|
34956
|
-
const absolute =
|
|
35023
|
+
const absolute = resolve4(cwd, path);
|
|
34957
35024
|
return realpath5(absolute).catch(() => absolute);
|
|
34958
35025
|
}
|
|
34959
35026
|
async function sendTargets(args, ctx) {
|
|
@@ -36367,7 +36434,7 @@ var Protocol = class {
|
|
|
36367
36434
|
return;
|
|
36368
36435
|
}
|
|
36369
36436
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
36370
|
-
await new Promise((
|
|
36437
|
+
await new Promise((resolve5) => setTimeout(resolve5, pollInterval));
|
|
36371
36438
|
options?.signal?.throwIfAborted();
|
|
36372
36439
|
}
|
|
36373
36440
|
} catch (error62) {
|
|
@@ -36384,7 +36451,7 @@ var Protocol = class {
|
|
|
36384
36451
|
*/
|
|
36385
36452
|
request(request, resultSchema, options) {
|
|
36386
36453
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
36387
|
-
return new Promise((
|
|
36454
|
+
return new Promise((resolve5, reject) => {
|
|
36388
36455
|
const earlyReject = (error62) => {
|
|
36389
36456
|
reject(error62);
|
|
36390
36457
|
};
|
|
@@ -36462,7 +36529,7 @@ var Protocol = class {
|
|
|
36462
36529
|
if (!parseResult.success) {
|
|
36463
36530
|
reject(parseResult.error);
|
|
36464
36531
|
} else {
|
|
36465
|
-
|
|
36532
|
+
resolve5(parseResult.data);
|
|
36466
36533
|
}
|
|
36467
36534
|
} catch (error62) {
|
|
36468
36535
|
reject(error62);
|
|
@@ -36724,12 +36791,12 @@ var Protocol = class {
|
|
|
36724
36791
|
}
|
|
36725
36792
|
} catch {
|
|
36726
36793
|
}
|
|
36727
|
-
return new Promise((
|
|
36794
|
+
return new Promise((resolve5, reject) => {
|
|
36728
36795
|
if (signal.aborted) {
|
|
36729
36796
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
36730
36797
|
return;
|
|
36731
36798
|
}
|
|
36732
|
-
const timeoutId = setTimeout(
|
|
36799
|
+
const timeoutId = setTimeout(resolve5, interval);
|
|
36733
36800
|
signal.addEventListener("abort", () => {
|
|
36734
36801
|
clearTimeout(timeoutId);
|
|
36735
36802
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -37545,23 +37612,52 @@ function elicitationConfirm(server, signal) {
|
|
|
37545
37612
|
|
|
37546
37613
|
// src/mcp/roots.ts
|
|
37547
37614
|
import { statSync } from "node:fs";
|
|
37615
|
+
import { isAbsolute as isAbsolute7 } from "node:path";
|
|
37548
37616
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
37549
37617
|
var FILE_URI_PROTOCOL = "file:";
|
|
37618
|
+
var SANDBOX_STATE_META = "codex/sandbox-state-meta";
|
|
37619
|
+
var TURN_METADATA = "x-codex-turn-metadata";
|
|
37620
|
+
function existingDirectory(dir) {
|
|
37621
|
+
try {
|
|
37622
|
+
return statSync(dir, { throwIfNoEntry: false })?.isDirectory() ? dir : void 0;
|
|
37623
|
+
} catch {
|
|
37624
|
+
return void 0;
|
|
37625
|
+
}
|
|
37626
|
+
}
|
|
37550
37627
|
function localDirectory(uri) {
|
|
37551
37628
|
try {
|
|
37552
37629
|
const url2 = new URL(uri);
|
|
37553
|
-
|
|
37554
|
-
const dir = fileURLToPath2(url2);
|
|
37555
|
-
return statSync(dir, { throwIfNoEntry: false })?.isDirectory() ? dir : void 0;
|
|
37630
|
+
return url2.protocol === FILE_URI_PROTOCOL ? existingDirectory(fileURLToPath2(url2)) : void 0;
|
|
37556
37631
|
} catch {
|
|
37557
37632
|
return void 0;
|
|
37558
37633
|
}
|
|
37559
37634
|
}
|
|
37635
|
+
function isRecord2(value) {
|
|
37636
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37637
|
+
}
|
|
37638
|
+
async function usableDirectory(candidate, ownDir, allowPath = false) {
|
|
37639
|
+
if (typeof candidate !== "string") return void 0;
|
|
37640
|
+
const dir = allowPath && isAbsolute7(candidate) ? existingDirectory(candidate) : localDirectory(candidate);
|
|
37641
|
+
if (dir === void 0 || ownDir !== void 0 && await isWithin(dir, ownDir)) return void 0;
|
|
37642
|
+
return dir;
|
|
37643
|
+
}
|
|
37644
|
+
async function callDirectory(meta3, ownDir) {
|
|
37645
|
+
if (!isRecord2(meta3)) return void 0;
|
|
37646
|
+
const sandbox = meta3[SANDBOX_STATE_META];
|
|
37647
|
+
if (isRecord2(sandbox)) {
|
|
37648
|
+
const dir = await usableDirectory(sandbox.sandboxCwd, ownDir, true);
|
|
37649
|
+
if (dir !== void 0) return dir;
|
|
37650
|
+
}
|
|
37651
|
+
const turn = meta3[TURN_METADATA];
|
|
37652
|
+
if (!isRecord2(turn) || !isRecord2(turn.workspaces)) return void 0;
|
|
37653
|
+
const workspaces = Object.keys(turn.workspaces);
|
|
37654
|
+
return workspaces.length === 1 ? usableDirectory(workspaces[0], ownDir, true) : void 0;
|
|
37655
|
+
}
|
|
37560
37656
|
async function firstUsableRoot(server, ownDir, signal) {
|
|
37561
37657
|
const { roots } = await server.listRoots(void 0, { signal });
|
|
37562
37658
|
for (const root of roots) {
|
|
37563
|
-
const dir =
|
|
37564
|
-
if (dir !== void 0
|
|
37659
|
+
const dir = await usableDirectory(root.uri, ownDir);
|
|
37660
|
+
if (dir !== void 0) return dir;
|
|
37565
37661
|
}
|
|
37566
37662
|
return void 0;
|
|
37567
37663
|
}
|
|
@@ -37572,7 +37668,9 @@ function createWorkingDirResolver(server, fallback, ownDir) {
|
|
|
37572
37668
|
cached2 = void 0;
|
|
37573
37669
|
generation++;
|
|
37574
37670
|
});
|
|
37575
|
-
return async (signal) => {
|
|
37671
|
+
return async (signal, meta3) => {
|
|
37672
|
+
const callDir = await callDirectory(meta3, ownDir);
|
|
37673
|
+
if (callDir !== void 0) return callDir;
|
|
37576
37674
|
if (!server.getClientCapabilities()?.roots) return fallback();
|
|
37577
37675
|
if (cached2 !== void 0) return cached2;
|
|
37578
37676
|
const started = generation;
|
|
@@ -37613,7 +37711,7 @@ function createServer(specs, settings, options = {}) {
|
|
|
37613
37711
|
`));
|
|
37614
37712
|
const server = new Server(
|
|
37615
37713
|
{ name: PROJECT.name, version: options.version ?? DEFAULT_VERSION },
|
|
37616
|
-
{ capabilities: { tools: {} } }
|
|
37714
|
+
{ capabilities: { tools: {}, experimental: { [SANDBOX_STATE_META]: {} } } }
|
|
37617
37715
|
);
|
|
37618
37716
|
const workingDir = createWorkingDirResolver(server, options.cwd ?? (() => process.cwd()), options.ownDir);
|
|
37619
37717
|
const toolsets = options.toolsets ?? PROJECT_PROFILE.toolsets;
|
|
@@ -37626,10 +37724,11 @@ function createServer(specs, settings, options = {}) {
|
|
|
37626
37724
|
try {
|
|
37627
37725
|
const confirm = settings.confirm === "elicitation" ? elicitationConfirm(server, extra.signal) : void 0;
|
|
37628
37726
|
const ctx = {
|
|
37629
|
-
cwd: await workingDir(extra.signal),
|
|
37727
|
+
cwd: await workingDir(extra.signal, request.params._meta),
|
|
37630
37728
|
ownDir: options.ownDir,
|
|
37631
37729
|
...toolDirectories(settings),
|
|
37632
37730
|
programName: PROJECT.name,
|
|
37731
|
+
options: settings.options,
|
|
37633
37732
|
signal: extra.signal,
|
|
37634
37733
|
...confirm && { confirm }
|
|
37635
37734
|
};
|
|
@@ -37655,7 +37754,7 @@ async function main() {
|
|
|
37655
37754
|
const settings = parseSettings(process.argv.slice(2), process.env);
|
|
37656
37755
|
server = createServer(ALL_TOOLS, settings, {
|
|
37657
37756
|
ownDir: packageRoot(import.meta.url),
|
|
37658
|
-
version: true ? "0.
|
|
37757
|
+
version: true ? "0.1.2" : void 0
|
|
37659
37758
|
});
|
|
37660
37759
|
} catch (error62) {
|
|
37661
37760
|
if (!isToolError(error62)) throw error62;
|