@zaly/agent 0.0.4 → 0.0.6
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/{agent-GDLdDc2w.mjs → agent-DirSoZjM.mjs} +8 -9
- package/dist/agent-DirSoZjM.mjs.map +1 -0
- package/dist/{bash-QNMTQ1PD.mjs → bash-COgq4W7U.mjs} +2 -2
- package/dist/{bash-QNMTQ1PD.mjs.map → bash-COgq4W7U.mjs.map} +1 -1
- package/dist/compactions-3AjPqjeZ.mjs.map +1 -1
- package/dist/{fetch-D8cmmA3E.mjs → fetch-DXuxAg_t.mjs} +3 -3
- package/dist/{fetch-D8cmmA3E.mjs.map → fetch-DXuxAg_t.mjs.map} +1 -1
- package/dist/{grep-B2Ax7ewy.mjs → grep-B4GF0svc.mjs} +2 -2
- package/dist/{grep-B2Ax7ewy.mjs.map → grep-B4GF0svc.mjs.map} +1 -1
- package/dist/index-node-esm-DAnl9SaE.mjs +2114 -0
- package/dist/index-node-esm-DAnl9SaE.mjs.map +1 -0
- package/dist/index.d.mts +47 -42
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +28 -22
- package/dist/index.mjs.map +1 -1
- package/dist/{jsonl-Dw_VBp46.mjs → jsonl-CvgEOakL.mjs} +2 -2
- package/dist/jsonl-CvgEOakL.mjs.map +1 -0
- package/dist/{manager-D-lWBTHG.mjs → manager-DHBfEtge.mjs} +12 -2
- package/dist/manager-DHBfEtge.mjs.map +1 -0
- package/dist/masker-Bv9KjkDF.mjs.map +1 -1
- package/dist/notify-DpG_m9iP.mjs.map +1 -1
- package/dist/{registry-CFmR5G3J.mjs → registry-Bao6L4Ue.mjs} +399 -73
- package/dist/registry-Bao6L4Ue.mjs.map +1 -0
- package/dist/session/claude.d.mts +2 -3
- package/dist/session/claude.d.mts.map +1 -1
- package/dist/session/claude.mjs +1 -1
- package/dist/{session-CUUdWFC5.mjs → session-B1lXSWhT.mjs} +4 -4
- package/dist/session-B1lXSWhT.mjs.map +1 -0
- package/dist/session.d.mts +8 -8
- package/dist/session.d.mts.map +1 -1
- package/dist/session.mjs +3 -3
- package/dist/{subagent-baqzjRMc.mjs → subagent-Zz-MQHk2.mjs} +3 -3
- package/dist/{subagent-baqzjRMc.mjs.map → subagent-Zz-MQHk2.mjs.map} +1 -1
- package/dist/swarm-BJ3gQA1Z.mjs.map +1 -1
- package/dist/{tasks-D8rARHZ1.mjs → tasks-BA-PCeGa.mjs} +4 -3
- package/dist/{tasks-D8rARHZ1.mjs.map → tasks-BA-PCeGa.mjs.map} +1 -1
- package/dist/{tasks-WmC270X2.mjs → tasks-WdRAHsOL.mjs} +5 -4
- package/dist/tasks-WdRAHsOL.mjs.map +1 -0
- package/dist/{tools-DW1dbcCz.mjs → tools-CZvBFp-v.mjs} +144 -38
- package/dist/tools-CZvBFp-v.mjs.map +1 -0
- package/dist/truncate-BSMXgiXj.mjs.map +1 -1
- package/dist/{uuid-ByXP5SO5.mjs → uuid-CAdJg4l8.mjs} +2 -2
- package/dist/{uuid-ByXP5SO5.mjs.map → uuid-CAdJg4l8.mjs.map} +1 -1
- package/package.json +12 -12
- package/dist/agent-GDLdDc2w.mjs.map +0 -1
- package/dist/index-node-esm-D6YQRKEz.mjs +0 -1537
- package/dist/index-node-esm-D6YQRKEz.mjs.map +0 -1
- package/dist/jsonl-Dw_VBp46.mjs.map +0 -1
- package/dist/manager-D-lWBTHG.mjs.map +0 -1
- package/dist/registry-CFmR5G3J.mjs.map +0 -1
- package/dist/session-CUUdWFC5.mjs.map +0 -1
- package/dist/tasks-WmC270X2.mjs.map +0 -1
- package/dist/tools-DW1dbcCz.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-node-esm-D6YQRKEz.mjs","names":[],"sources":["../../../node_modules/.bun/jsonpath-plus@10.4.0/node_modules/jsonpath-plus/dist/index-node-esm.js"],"sourcesContent":["import vm from 'vm';\n\n/**\n * @implements {IHooks}\n */\nclass Hooks {\n /**\n * @callback HookCallback\n * @this {*|Jsep} this\n * @param {Jsep} env\n * @returns: void\n */\n /**\n * Adds the given callback to the list of callbacks for the given hook.\n *\n * The callback will be invoked when the hook it is registered for is run.\n *\n * One callback function can be registered to multiple hooks and the same hook multiple times.\n *\n * @param {string|object} name The name of the hook, or an object of callbacks keyed by name\n * @param {HookCallback|boolean} callback The callback function which is given environment variables.\n * @param {?boolean} [first=false] Will add the hook to the top of the list (defaults to the bottom)\n * @public\n */\n add(name, callback, first) {\n if (typeof arguments[0] != 'string') {\n // Multiple hook callbacks, keyed by name\n for (let name in arguments[0]) {\n this.add(name, arguments[0][name], arguments[1]);\n }\n } else {\n (Array.isArray(name) ? name : [name]).forEach(function (name) {\n this[name] = this[name] || [];\n if (callback) {\n this[name][first ? 'unshift' : 'push'](callback);\n }\n }, this);\n }\n }\n\n /**\n * Runs a hook invoking all registered callbacks with the given environment variables.\n *\n * Callbacks will be invoked synchronously and in the order in which they were registered.\n *\n * @param {string} name The name of the hook.\n * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.\n * @public\n */\n run(name, env) {\n this[name] = this[name] || [];\n this[name].forEach(function (callback) {\n callback.call(env && env.context ? env.context : env, env);\n });\n }\n}\n\n/**\n * @implements {IPlugins}\n */\nclass Plugins {\n constructor(jsep) {\n this.jsep = jsep;\n this.registered = {};\n }\n\n /**\n * @callback PluginSetup\n * @this {Jsep} jsep\n * @returns: void\n */\n /**\n * Adds the given plugin(s) to the registry\n *\n * @param {object} plugins\n * @param {string} plugins.name The name of the plugin\n * @param {PluginSetup} plugins.init The init function\n * @public\n */\n register(...plugins) {\n plugins.forEach(plugin => {\n if (typeof plugin !== 'object' || !plugin.name || !plugin.init) {\n throw new Error('Invalid JSEP plugin format');\n }\n if (this.registered[plugin.name]) {\n // already registered. Ignore.\n return;\n }\n plugin.init(this.jsep);\n this.registered[plugin.name] = plugin;\n });\n }\n}\n\n// JavaScript Expression Parser (JSEP) 1.4.0\n\nclass Jsep {\n /**\n * @returns {string}\n */\n static get version() {\n // To be filled in by the template\n return '1.4.0';\n }\n\n /**\n * @returns {string}\n */\n static toString() {\n return 'JavaScript Expression Parser (JSEP) v' + Jsep.version;\n }\n // ==================== CONFIG ================================\n /**\n * @method addUnaryOp\n * @param {string} op_name The name of the unary op to add\n * @returns {Jsep}\n */\n static addUnaryOp(op_name) {\n Jsep.max_unop_len = Math.max(op_name.length, Jsep.max_unop_len);\n Jsep.unary_ops[op_name] = 1;\n return Jsep;\n }\n\n /**\n * @method jsep.addBinaryOp\n * @param {string} op_name The name of the binary op to add\n * @param {number} precedence The precedence of the binary op (can be a float). Higher number = higher precedence\n * @param {boolean} [isRightAssociative=false] whether operator is right-associative\n * @returns {Jsep}\n */\n static addBinaryOp(op_name, precedence, isRightAssociative) {\n Jsep.max_binop_len = Math.max(op_name.length, Jsep.max_binop_len);\n Jsep.binary_ops[op_name] = precedence;\n if (isRightAssociative) {\n Jsep.right_associative.add(op_name);\n } else {\n Jsep.right_associative.delete(op_name);\n }\n return Jsep;\n }\n\n /**\n * @method addIdentifierChar\n * @param {string} char The additional character to treat as a valid part of an identifier\n * @returns {Jsep}\n */\n static addIdentifierChar(char) {\n Jsep.additional_identifier_chars.add(char);\n return Jsep;\n }\n\n /**\n * @method addLiteral\n * @param {string} literal_name The name of the literal to add\n * @param {*} literal_value The value of the literal\n * @returns {Jsep}\n */\n static addLiteral(literal_name, literal_value) {\n Jsep.literals[literal_name] = literal_value;\n return Jsep;\n }\n\n /**\n * @method removeUnaryOp\n * @param {string} op_name The name of the unary op to remove\n * @returns {Jsep}\n */\n static removeUnaryOp(op_name) {\n delete Jsep.unary_ops[op_name];\n if (op_name.length === Jsep.max_unop_len) {\n Jsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);\n }\n return Jsep;\n }\n\n /**\n * @method removeAllUnaryOps\n * @returns {Jsep}\n */\n static removeAllUnaryOps() {\n Jsep.unary_ops = {};\n Jsep.max_unop_len = 0;\n return Jsep;\n }\n\n /**\n * @method removeIdentifierChar\n * @param {string} char The additional character to stop treating as a valid part of an identifier\n * @returns {Jsep}\n */\n static removeIdentifierChar(char) {\n Jsep.additional_identifier_chars.delete(char);\n return Jsep;\n }\n\n /**\n * @method removeBinaryOp\n * @param {string} op_name The name of the binary op to remove\n * @returns {Jsep}\n */\n static removeBinaryOp(op_name) {\n delete Jsep.binary_ops[op_name];\n if (op_name.length === Jsep.max_binop_len) {\n Jsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);\n }\n Jsep.right_associative.delete(op_name);\n return Jsep;\n }\n\n /**\n * @method removeAllBinaryOps\n * @returns {Jsep}\n */\n static removeAllBinaryOps() {\n Jsep.binary_ops = {};\n Jsep.max_binop_len = 0;\n return Jsep;\n }\n\n /**\n * @method removeLiteral\n * @param {string} literal_name The name of the literal to remove\n * @returns {Jsep}\n */\n static removeLiteral(literal_name) {\n delete Jsep.literals[literal_name];\n return Jsep;\n }\n\n /**\n * @method removeAllLiterals\n * @returns {Jsep}\n */\n static removeAllLiterals() {\n Jsep.literals = {};\n return Jsep;\n }\n // ==================== END CONFIG ============================\n\n /**\n * @returns {string}\n */\n get char() {\n return this.expr.charAt(this.index);\n }\n\n /**\n * @returns {number}\n */\n get code() {\n return this.expr.charCodeAt(this.index);\n }\n /**\n * @param {string} expr a string with the passed in express\n * @returns Jsep\n */\n constructor(expr) {\n // `index` stores the character number we are currently at\n // All of the gobbles below will modify `index` as we move along\n this.expr = expr;\n this.index = 0;\n }\n\n /**\n * static top-level parser\n * @returns {jsep.Expression}\n */\n static parse(expr) {\n return new Jsep(expr).parse();\n }\n\n /**\n * Get the longest key length of any object\n * @param {object} obj\n * @returns {number}\n */\n static getMaxKeyLen(obj) {\n return Math.max(0, ...Object.keys(obj).map(k => k.length));\n }\n\n /**\n * `ch` is a character code in the next three functions\n * @param {number} ch\n * @returns {boolean}\n */\n static isDecimalDigit(ch) {\n return ch >= 48 && ch <= 57; // 0...9\n }\n\n /**\n * Returns the precedence of a binary operator or `0` if it isn't a binary operator. Can be float.\n * @param {string} op_val\n * @returns {number}\n */\n static binaryPrecedence(op_val) {\n return Jsep.binary_ops[op_val] || 0;\n }\n\n /**\n * Looks for start of identifier\n * @param {number} ch\n * @returns {boolean}\n */\n static isIdentifierStart(ch) {\n return ch >= 65 && ch <= 90 ||\n // A...Z\n ch >= 97 && ch <= 122 ||\n // a...z\n ch >= 128 && !Jsep.binary_ops[String.fromCharCode(ch)] ||\n // any non-ASCII that is not an operator\n Jsep.additional_identifier_chars.has(String.fromCharCode(ch)); // additional characters\n }\n\n /**\n * @param {number} ch\n * @returns {boolean}\n */\n static isIdentifierPart(ch) {\n return Jsep.isIdentifierStart(ch) || Jsep.isDecimalDigit(ch);\n }\n\n /**\n * throw error at index of the expression\n * @param {string} message\n * @throws\n */\n throwError(message) {\n const error = new Error(message + ' at character ' + this.index);\n error.index = this.index;\n error.description = message;\n throw error;\n }\n\n /**\n * Run a given hook\n * @param {string} name\n * @param {jsep.Expression|false} [node]\n * @returns {?jsep.Expression}\n */\n runHook(name, node) {\n if (Jsep.hooks[name]) {\n const env = {\n context: this,\n node\n };\n Jsep.hooks.run(name, env);\n return env.node;\n }\n return node;\n }\n\n /**\n * Runs a given hook until one returns a node\n * @param {string} name\n * @returns {?jsep.Expression}\n */\n searchHook(name) {\n if (Jsep.hooks[name]) {\n const env = {\n context: this\n };\n Jsep.hooks[name].find(function (callback) {\n callback.call(env.context, env);\n return env.node;\n });\n return env.node;\n }\n }\n\n /**\n * Push `index` up to the next non-space character\n */\n gobbleSpaces() {\n let ch = this.code;\n // Whitespace\n while (ch === Jsep.SPACE_CODE || ch === Jsep.TAB_CODE || ch === Jsep.LF_CODE || ch === Jsep.CR_CODE) {\n ch = this.expr.charCodeAt(++this.index);\n }\n this.runHook('gobble-spaces');\n }\n\n /**\n * Top-level method to parse all expressions and returns compound or single node\n * @returns {jsep.Expression}\n */\n parse() {\n this.runHook('before-all');\n const nodes = this.gobbleExpressions();\n\n // If there's only one expression just try returning the expression\n const node = nodes.length === 1 ? nodes[0] : {\n type: Jsep.COMPOUND,\n body: nodes\n };\n return this.runHook('after-all', node);\n }\n\n /**\n * top-level parser (but can be reused within as well)\n * @param {number} [untilICode]\n * @returns {jsep.Expression[]}\n */\n gobbleExpressions(untilICode) {\n let nodes = [],\n ch_i,\n node;\n while (this.index < this.expr.length) {\n ch_i = this.code;\n\n // Expressions can be separated by semicolons, commas, or just inferred without any\n // separators\n if (ch_i === Jsep.SEMCOL_CODE || ch_i === Jsep.COMMA_CODE) {\n this.index++; // ignore separators\n } else {\n // Try to gobble each expression individually\n if (node = this.gobbleExpression()) {\n nodes.push(node);\n // If we weren't able to find a binary expression and are out of room, then\n // the expression passed in probably has too much\n } else if (this.index < this.expr.length) {\n if (ch_i === untilICode) {\n break;\n }\n this.throwError('Unexpected \"' + this.char + '\"');\n }\n }\n }\n return nodes;\n }\n\n /**\n * The main parsing function.\n * @returns {?jsep.Expression}\n */\n gobbleExpression() {\n const node = this.searchHook('gobble-expression') || this.gobbleBinaryExpression();\n this.gobbleSpaces();\n return this.runHook('after-expression', node);\n }\n\n /**\n * Search for the operation portion of the string (e.g. `+`, `===`)\n * Start by taking the longest possible binary operations (3 characters: `===`, `!==`, `>>>`)\n * and move down from 3 to 2 to 1 character until a matching binary operation is found\n * then, return that binary operation\n * @returns {string|boolean}\n */\n gobbleBinaryOp() {\n this.gobbleSpaces();\n let to_check = this.expr.substr(this.index, Jsep.max_binop_len);\n let tc_len = to_check.length;\n while (tc_len > 0) {\n // Don't accept a binary op when it is an identifier.\n // Binary ops that start with a identifier-valid character must be followed\n // by a non identifier-part valid character\n if (Jsep.binary_ops.hasOwnProperty(to_check) && (!Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) {\n this.index += tc_len;\n return to_check;\n }\n to_check = to_check.substr(0, --tc_len);\n }\n return false;\n }\n\n /**\n * This function is responsible for gobbling an individual expression,\n * e.g. `1`, `1+2`, `a+(b*2)-Math.sqrt(2)`\n * @returns {?jsep.BinaryExpression}\n */\n gobbleBinaryExpression() {\n let node, biop, prec, stack, biop_info, left, right, i, cur_biop;\n\n // First, try to get the leftmost thing\n // Then, check to see if there's a binary operator operating on that leftmost thing\n // Don't gobbleBinaryOp without a left-hand-side\n left = this.gobbleToken();\n if (!left) {\n return left;\n }\n biop = this.gobbleBinaryOp();\n\n // If there wasn't a binary operator, just return the leftmost node\n if (!biop) {\n return left;\n }\n\n // Otherwise, we need to start a stack to properly place the binary operations in their\n // precedence structure\n biop_info = {\n value: biop,\n prec: Jsep.binaryPrecedence(biop),\n right_a: Jsep.right_associative.has(biop)\n };\n right = this.gobbleToken();\n if (!right) {\n this.throwError(\"Expected expression after \" + biop);\n }\n stack = [left, biop_info, right];\n\n // Properly deal with precedence using [recursive descent](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm)\n while (biop = this.gobbleBinaryOp()) {\n prec = Jsep.binaryPrecedence(biop);\n if (prec === 0) {\n this.index -= biop.length;\n break;\n }\n biop_info = {\n value: biop,\n prec,\n right_a: Jsep.right_associative.has(biop)\n };\n cur_biop = biop;\n\n // Reduce: make a binary expression from the three topmost entries.\n const comparePrev = prev => biop_info.right_a && prev.right_a ? prec > prev.prec : prec <= prev.prec;\n while (stack.length > 2 && comparePrev(stack[stack.length - 2])) {\n right = stack.pop();\n biop = stack.pop().value;\n left = stack.pop();\n node = {\n type: Jsep.BINARY_EXP,\n operator: biop,\n left,\n right\n };\n stack.push(node);\n }\n node = this.gobbleToken();\n if (!node) {\n this.throwError(\"Expected expression after \" + cur_biop);\n }\n stack.push(biop_info, node);\n }\n i = stack.length - 1;\n node = stack[i];\n while (i > 1) {\n node = {\n type: Jsep.BINARY_EXP,\n operator: stack[i - 1].value,\n left: stack[i - 2],\n right: node\n };\n i -= 2;\n }\n return node;\n }\n\n /**\n * An individual part of a binary expression:\n * e.g. `foo.bar(baz)`, `1`, `\"abc\"`, `(a % 2)` (because it's in parenthesis)\n * @returns {boolean|jsep.Expression}\n */\n gobbleToken() {\n let ch, to_check, tc_len, node;\n this.gobbleSpaces();\n node = this.searchHook('gobble-token');\n if (node) {\n return this.runHook('after-token', node);\n }\n ch = this.code;\n if (Jsep.isDecimalDigit(ch) || ch === Jsep.PERIOD_CODE) {\n // Char code 46 is a dot `.` which can start off a numeric literal\n return this.gobbleNumericLiteral();\n }\n if (ch === Jsep.SQUOTE_CODE || ch === Jsep.DQUOTE_CODE) {\n // Single or double quotes\n node = this.gobbleStringLiteral();\n } else if (ch === Jsep.OBRACK_CODE) {\n node = this.gobbleArray();\n } else {\n to_check = this.expr.substr(this.index, Jsep.max_unop_len);\n tc_len = to_check.length;\n while (tc_len > 0) {\n // Don't accept an unary op when it is an identifier.\n // Unary ops that start with a identifier-valid character must be followed\n // by a non identifier-part valid character\n if (Jsep.unary_ops.hasOwnProperty(to_check) && (!Jsep.isIdentifierStart(this.code) || this.index + to_check.length < this.expr.length && !Jsep.isIdentifierPart(this.expr.charCodeAt(this.index + to_check.length)))) {\n this.index += tc_len;\n const argument = this.gobbleToken();\n if (!argument) {\n this.throwError('missing unaryOp argument');\n }\n return this.runHook('after-token', {\n type: Jsep.UNARY_EXP,\n operator: to_check,\n argument,\n prefix: true\n });\n }\n to_check = to_check.substr(0, --tc_len);\n }\n if (Jsep.isIdentifierStart(ch)) {\n node = this.gobbleIdentifier();\n if (Jsep.literals.hasOwnProperty(node.name)) {\n node = {\n type: Jsep.LITERAL,\n value: Jsep.literals[node.name],\n raw: node.name\n };\n } else if (node.name === Jsep.this_str) {\n node = {\n type: Jsep.THIS_EXP\n };\n }\n } else if (ch === Jsep.OPAREN_CODE) {\n // open parenthesis\n node = this.gobbleGroup();\n }\n }\n if (!node) {\n return this.runHook('after-token', false);\n }\n node = this.gobbleTokenProperty(node);\n return this.runHook('after-token', node);\n }\n\n /**\n * Gobble properties of of identifiers/strings/arrays/groups.\n * e.g. `foo`, `bar.baz`, `foo['bar'].baz`\n * It also gobbles function calls:\n * e.g. `Math.acos(obj.angle)`\n * @param {jsep.Expression} node\n * @returns {jsep.Expression}\n */\n gobbleTokenProperty(node) {\n this.gobbleSpaces();\n let ch = this.code;\n while (ch === Jsep.PERIOD_CODE || ch === Jsep.OBRACK_CODE || ch === Jsep.OPAREN_CODE || ch === Jsep.QUMARK_CODE) {\n let optional;\n if (ch === Jsep.QUMARK_CODE) {\n if (this.expr.charCodeAt(this.index + 1) !== Jsep.PERIOD_CODE) {\n break;\n }\n optional = true;\n this.index += 2;\n this.gobbleSpaces();\n ch = this.code;\n }\n this.index++;\n if (ch === Jsep.OBRACK_CODE) {\n node = {\n type: Jsep.MEMBER_EXP,\n computed: true,\n object: node,\n property: this.gobbleExpression()\n };\n if (!node.property) {\n this.throwError('Unexpected \"' + this.char + '\"');\n }\n this.gobbleSpaces();\n ch = this.code;\n if (ch !== Jsep.CBRACK_CODE) {\n this.throwError('Unclosed [');\n }\n this.index++;\n } else if (ch === Jsep.OPAREN_CODE) {\n // A function call is being made; gobble all the arguments\n node = {\n type: Jsep.CALL_EXP,\n 'arguments': this.gobbleArguments(Jsep.CPAREN_CODE),\n callee: node\n };\n } else if (ch === Jsep.PERIOD_CODE || optional) {\n if (optional) {\n this.index--;\n }\n this.gobbleSpaces();\n node = {\n type: Jsep.MEMBER_EXP,\n computed: false,\n object: node,\n property: this.gobbleIdentifier()\n };\n }\n if (optional) {\n node.optional = true;\n } // else leave undefined for compatibility with esprima\n\n this.gobbleSpaces();\n ch = this.code;\n }\n return node;\n }\n\n /**\n * Parse simple numeric literals: `12`, `3.4`, `.5`. Do this by using a string to\n * keep track of everything in the numeric literal and then calling `parseFloat` on that string\n * @returns {jsep.Literal}\n */\n gobbleNumericLiteral() {\n let number = '',\n ch,\n chCode;\n while (Jsep.isDecimalDigit(this.code)) {\n number += this.expr.charAt(this.index++);\n }\n if (this.code === Jsep.PERIOD_CODE) {\n // can start with a decimal marker\n number += this.expr.charAt(this.index++);\n while (Jsep.isDecimalDigit(this.code)) {\n number += this.expr.charAt(this.index++);\n }\n }\n ch = this.char;\n if (ch === 'e' || ch === 'E') {\n // exponent marker\n number += this.expr.charAt(this.index++);\n ch = this.char;\n if (ch === '+' || ch === '-') {\n // exponent sign\n number += this.expr.charAt(this.index++);\n }\n while (Jsep.isDecimalDigit(this.code)) {\n // exponent itself\n number += this.expr.charAt(this.index++);\n }\n if (!Jsep.isDecimalDigit(this.expr.charCodeAt(this.index - 1))) {\n this.throwError('Expected exponent (' + number + this.char + ')');\n }\n }\n chCode = this.code;\n\n // Check to make sure this isn't a variable name that start with a number (123abc)\n if (Jsep.isIdentifierStart(chCode)) {\n this.throwError('Variable names cannot start with a number (' + number + this.char + ')');\n } else if (chCode === Jsep.PERIOD_CODE || number.length === 1 && number.charCodeAt(0) === Jsep.PERIOD_CODE) {\n this.throwError('Unexpected period');\n }\n return {\n type: Jsep.LITERAL,\n value: parseFloat(number),\n raw: number\n };\n }\n\n /**\n * Parses a string literal, staring with single or double quotes with basic support for escape codes\n * e.g. `\"hello world\"`, `'this is\\nJSEP'`\n * @returns {jsep.Literal}\n */\n gobbleStringLiteral() {\n let str = '';\n const startIndex = this.index;\n const quote = this.expr.charAt(this.index++);\n let closed = false;\n while (this.index < this.expr.length) {\n let ch = this.expr.charAt(this.index++);\n if (ch === quote) {\n closed = true;\n break;\n } else if (ch === '\\\\') {\n // Check for all of the common escape codes\n ch = this.expr.charAt(this.index++);\n switch (ch) {\n case 'n':\n str += '\\n';\n break;\n case 'r':\n str += '\\r';\n break;\n case 't':\n str += '\\t';\n break;\n case 'b':\n str += '\\b';\n break;\n case 'f':\n str += '\\f';\n break;\n case 'v':\n str += '\\x0B';\n break;\n default:\n str += ch;\n }\n } else {\n str += ch;\n }\n }\n if (!closed) {\n this.throwError('Unclosed quote after \"' + str + '\"');\n }\n return {\n type: Jsep.LITERAL,\n value: str,\n raw: this.expr.substring(startIndex, this.index)\n };\n }\n\n /**\n * Gobbles only identifiers\n * e.g.: `foo`, `_value`, `$x1`\n * Also, this function checks if that identifier is a literal:\n * (e.g. `true`, `false`, `null`) or `this`\n * @returns {jsep.Identifier}\n */\n gobbleIdentifier() {\n let ch = this.code,\n start = this.index;\n if (Jsep.isIdentifierStart(ch)) {\n this.index++;\n } else {\n this.throwError('Unexpected ' + this.char);\n }\n while (this.index < this.expr.length) {\n ch = this.code;\n if (Jsep.isIdentifierPart(ch)) {\n this.index++;\n } else {\n break;\n }\n }\n return {\n type: Jsep.IDENTIFIER,\n name: this.expr.slice(start, this.index)\n };\n }\n\n /**\n * Gobbles a list of arguments within the context of a function call\n * or array literal. This function also assumes that the opening character\n * `(` or `[` has already been gobbled, and gobbles expressions and commas\n * until the terminator character `)` or `]` is encountered.\n * e.g. `foo(bar, baz)`, `my_func()`, or `[bar, baz]`\n * @param {number} termination\n * @returns {jsep.Expression[]}\n */\n gobbleArguments(termination) {\n const args = [];\n let closed = false;\n let separator_count = 0;\n while (this.index < this.expr.length) {\n this.gobbleSpaces();\n let ch_i = this.code;\n if (ch_i === termination) {\n // done parsing\n closed = true;\n this.index++;\n if (termination === Jsep.CPAREN_CODE && separator_count && separator_count >= args.length) {\n this.throwError('Unexpected token ' + String.fromCharCode(termination));\n }\n break;\n } else if (ch_i === Jsep.COMMA_CODE) {\n // between expressions\n this.index++;\n separator_count++;\n if (separator_count !== args.length) {\n // missing argument\n if (termination === Jsep.CPAREN_CODE) {\n this.throwError('Unexpected token ,');\n } else if (termination === Jsep.CBRACK_CODE) {\n for (let arg = args.length; arg < separator_count; arg++) {\n args.push(null);\n }\n }\n }\n } else if (args.length !== separator_count && separator_count !== 0) {\n // NOTE: `&& separator_count !== 0` allows for either all commas, or all spaces as arguments\n this.throwError('Expected comma');\n } else {\n const node = this.gobbleExpression();\n if (!node || node.type === Jsep.COMPOUND) {\n this.throwError('Expected comma');\n }\n args.push(node);\n }\n }\n if (!closed) {\n this.throwError('Expected ' + String.fromCharCode(termination));\n }\n return args;\n }\n\n /**\n * Responsible for parsing a group of things within parentheses `()`\n * that have no identifier in front (so not a function call)\n * This function assumes that it needs to gobble the opening parenthesis\n * and then tries to gobble everything within that parenthesis, assuming\n * that the next thing it should see is the close parenthesis. If not,\n * then the expression probably doesn't have a `)`\n * @returns {boolean|jsep.Expression}\n */\n gobbleGroup() {\n this.index++;\n let nodes = this.gobbleExpressions(Jsep.CPAREN_CODE);\n if (this.code === Jsep.CPAREN_CODE) {\n this.index++;\n if (nodes.length === 1) {\n return nodes[0];\n } else if (!nodes.length) {\n return false;\n } else {\n return {\n type: Jsep.SEQUENCE_EXP,\n expressions: nodes\n };\n }\n } else {\n this.throwError('Unclosed (');\n }\n }\n\n /**\n * Responsible for parsing Array literals `[1, 2, 3]`\n * This function assumes that it needs to gobble the opening bracket\n * and then tries to gobble the expressions as arguments.\n * @returns {jsep.ArrayExpression}\n */\n gobbleArray() {\n this.index++;\n return {\n type: Jsep.ARRAY_EXP,\n elements: this.gobbleArguments(Jsep.CBRACK_CODE)\n };\n }\n}\n\n// Static fields:\nconst hooks = new Hooks();\nObject.assign(Jsep, {\n hooks,\n plugins: new Plugins(Jsep),\n // Node Types\n // ----------\n // This is the full set of types that any JSEP node can be.\n // Store them here to save space when minified\n COMPOUND: 'Compound',\n SEQUENCE_EXP: 'SequenceExpression',\n IDENTIFIER: 'Identifier',\n MEMBER_EXP: 'MemberExpression',\n LITERAL: 'Literal',\n THIS_EXP: 'ThisExpression',\n CALL_EXP: 'CallExpression',\n UNARY_EXP: 'UnaryExpression',\n BINARY_EXP: 'BinaryExpression',\n ARRAY_EXP: 'ArrayExpression',\n TAB_CODE: 9,\n LF_CODE: 10,\n CR_CODE: 13,\n SPACE_CODE: 32,\n PERIOD_CODE: 46,\n // '.'\n COMMA_CODE: 44,\n // ','\n SQUOTE_CODE: 39,\n // single quote\n DQUOTE_CODE: 34,\n // double quotes\n OPAREN_CODE: 40,\n // (\n CPAREN_CODE: 41,\n // )\n OBRACK_CODE: 91,\n // [\n CBRACK_CODE: 93,\n // ]\n QUMARK_CODE: 63,\n // ?\n SEMCOL_CODE: 59,\n // ;\n COLON_CODE: 58,\n // :\n\n // Operations\n // ----------\n // Use a quickly-accessible map to store all of the unary operators\n // Values are set to `1` (it really doesn't matter)\n unary_ops: {\n '-': 1,\n '!': 1,\n '~': 1,\n '+': 1\n },\n // Also use a map for the binary operations but set their values to their\n // binary precedence for quick reference (higher number = higher precedence)\n // see [Order of operations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence)\n binary_ops: {\n '||': 1,\n '??': 1,\n '&&': 2,\n '|': 3,\n '^': 4,\n '&': 5,\n '==': 6,\n '!=': 6,\n '===': 6,\n '!==': 6,\n '<': 7,\n '>': 7,\n '<=': 7,\n '>=': 7,\n '<<': 8,\n '>>': 8,\n '>>>': 8,\n '+': 9,\n '-': 9,\n '*': 10,\n '/': 10,\n '%': 10,\n '**': 11\n },\n // sets specific binary_ops as right-associative\n right_associative: new Set(['**']),\n // Additional valid identifier chars, apart from a-z, A-Z and 0-9 (except on the starting char)\n additional_identifier_chars: new Set(['$', '_']),\n // Literals\n // ----------\n // Store the values to return for the various literals we may encounter\n literals: {\n 'true': true,\n 'false': false,\n 'null': null\n },\n // Except for `this`, which is special. This could be changed to something like `'self'` as well\n this_str: 'this'\n});\nJsep.max_unop_len = Jsep.getMaxKeyLen(Jsep.unary_ops);\nJsep.max_binop_len = Jsep.getMaxKeyLen(Jsep.binary_ops);\n\n// Backward Compatibility:\nconst jsep = expr => new Jsep(expr).parse();\nconst stdClassProps = Object.getOwnPropertyNames(class Test {});\nObject.getOwnPropertyNames(Jsep).filter(prop => !stdClassProps.includes(prop) && jsep[prop] === undefined).forEach(m => {\n jsep[m] = Jsep[m];\n});\njsep.Jsep = Jsep; // allows for const { Jsep } = require('jsep');\n\nconst CONDITIONAL_EXP = 'ConditionalExpression';\nvar ternary = {\n name: 'ternary',\n init(jsep) {\n // Ternary expression: test ? consequent : alternate\n jsep.hooks.add('after-expression', function gobbleTernary(env) {\n if (env.node && this.code === jsep.QUMARK_CODE) {\n this.index++;\n const test = env.node;\n const consequent = this.gobbleExpression();\n if (!consequent) {\n this.throwError('Expected expression');\n }\n this.gobbleSpaces();\n if (this.code === jsep.COLON_CODE) {\n this.index++;\n const alternate = this.gobbleExpression();\n if (!alternate) {\n this.throwError('Expected expression');\n }\n env.node = {\n type: CONDITIONAL_EXP,\n test,\n consequent,\n alternate\n };\n\n // check for operators of higher priority than ternary (i.e. assignment)\n // jsep sets || at 1, and assignment at 0.9, and conditional should be between them\n if (test.operator && jsep.binary_ops[test.operator] <= 0.9) {\n let newTest = test;\n while (newTest.right.operator && jsep.binary_ops[newTest.right.operator] <= 0.9) {\n newTest = newTest.right;\n }\n env.node.test = newTest.right;\n newTest.right = env.node;\n env.node = test;\n }\n } else {\n this.throwError('Expected :');\n }\n }\n });\n }\n};\n\n// Add default plugins:\n\njsep.plugins.register(ternary);\n\nconst FSLASH_CODE = 47; // '/'\nconst BSLASH_CODE = 92; // '\\\\'\n\nvar index = {\n name: 'regex',\n init(jsep) {\n // Regex literal: /abc123/ig\n jsep.hooks.add('gobble-token', function gobbleRegexLiteral(env) {\n if (this.code === FSLASH_CODE) {\n const patternIndex = ++this.index;\n let inCharSet = false;\n while (this.index < this.expr.length) {\n if (this.code === FSLASH_CODE && !inCharSet) {\n const pattern = this.expr.slice(patternIndex, this.index);\n let flags = '';\n while (++this.index < this.expr.length) {\n const code = this.code;\n if (code >= 97 && code <= 122 // a...z\n || code >= 65 && code <= 90 // A...Z\n || code >= 48 && code <= 57) {\n // 0-9\n flags += this.char;\n } else {\n break;\n }\n }\n let value;\n try {\n value = new RegExp(pattern, flags);\n } catch (e) {\n this.throwError(e.message);\n }\n env.node = {\n type: jsep.LITERAL,\n value,\n raw: this.expr.slice(patternIndex - 1, this.index)\n };\n\n // allow . [] and () after regex: /regex/.test(a)\n env.node = this.gobbleTokenProperty(env.node);\n return env.node;\n }\n if (this.code === jsep.OBRACK_CODE) {\n inCharSet = true;\n } else if (inCharSet && this.code === jsep.CBRACK_CODE) {\n inCharSet = false;\n }\n this.index += this.code === BSLASH_CODE ? 2 : 1;\n }\n this.throwError('Unclosed Regex');\n }\n });\n }\n};\n\nconst PLUS_CODE = 43; // +\nconst MINUS_CODE = 45; // -\n\nconst plugin = {\n name: 'assignment',\n assignmentOperators: new Set(['=', '*=', '**=', '/=', '%=', '+=', '-=', '<<=', '>>=', '>>>=', '&=', '^=', '|=', '||=', '&&=', '??=']),\n updateOperators: [PLUS_CODE, MINUS_CODE],\n assignmentPrecedence: 0.9,\n init(jsep) {\n const updateNodeTypes = [jsep.IDENTIFIER, jsep.MEMBER_EXP];\n plugin.assignmentOperators.forEach(op => jsep.addBinaryOp(op, plugin.assignmentPrecedence, true));\n jsep.hooks.add('gobble-token', function gobbleUpdatePrefix(env) {\n const code = this.code;\n if (plugin.updateOperators.some(c => c === code && c === this.expr.charCodeAt(this.index + 1))) {\n this.index += 2;\n env.node = {\n type: 'UpdateExpression',\n operator: code === PLUS_CODE ? '++' : '--',\n argument: this.gobbleTokenProperty(this.gobbleIdentifier()),\n prefix: true\n };\n if (!env.node.argument || !updateNodeTypes.includes(env.node.argument.type)) {\n this.throwError(`Unexpected ${env.node.operator}`);\n }\n }\n });\n jsep.hooks.add('after-token', function gobbleUpdatePostfix(env) {\n if (env.node) {\n const code = this.code;\n if (plugin.updateOperators.some(c => c === code && c === this.expr.charCodeAt(this.index + 1))) {\n if (!updateNodeTypes.includes(env.node.type)) {\n this.throwError(`Unexpected ${env.node.operator}`);\n }\n this.index += 2;\n env.node = {\n type: 'UpdateExpression',\n operator: code === PLUS_CODE ? '++' : '--',\n argument: env.node,\n prefix: false\n };\n }\n }\n });\n jsep.hooks.add('after-expression', function gobbleAssignment(env) {\n if (env.node) {\n // Note: Binaries can be chained in a single expression to respect\n // operator precedence (i.e. a = b = 1 + 2 + 3)\n // Update all binary assignment nodes in the tree\n updateBinariesToAssignments(env.node);\n }\n });\n function updateBinariesToAssignments(node) {\n if (plugin.assignmentOperators.has(node.operator)) {\n node.type = 'AssignmentExpression';\n updateBinariesToAssignments(node.left);\n updateBinariesToAssignments(node.right);\n } else if (!node.operator) {\n Object.values(node).forEach(val => {\n if (val && typeof val === 'object') {\n updateBinariesToAssignments(val);\n }\n });\n }\n }\n }\n};\n\n/* eslint-disable no-bitwise -- Convenient */\n\n// register plugins\njsep.plugins.register(index, plugin);\njsep.addUnaryOp('typeof');\njsep.addUnaryOp('void');\njsep.addLiteral('null', null);\njsep.addLiteral('undefined', undefined);\nconst BLOCKED_PROTO_PROPERTIES = new Set(['constructor', '__proto__', '__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__']);\nconst SafeEval = {\n /**\n * @param {jsep.Expression} ast\n * @param {Record<string, any>} subs\n */\n evalAst(ast, subs) {\n switch (ast.type) {\n case 'BinaryExpression':\n case 'LogicalExpression':\n return SafeEval.evalBinaryExpression(ast, subs);\n case 'Compound':\n return SafeEval.evalCompound(ast, subs);\n case 'ConditionalExpression':\n return SafeEval.evalConditionalExpression(ast, subs);\n case 'Identifier':\n return SafeEval.evalIdentifier(ast, subs);\n case 'Literal':\n return SafeEval.evalLiteral(ast, subs);\n case 'MemberExpression':\n return SafeEval.evalMemberExpression(ast, subs);\n case 'UnaryExpression':\n return SafeEval.evalUnaryExpression(ast, subs);\n case 'ArrayExpression':\n return SafeEval.evalArrayExpression(ast, subs);\n case 'CallExpression':\n return SafeEval.evalCallExpression(ast, subs);\n case 'AssignmentExpression':\n return SafeEval.evalAssignmentExpression(ast, subs);\n default:\n throw SyntaxError('Unexpected expression', ast);\n }\n },\n evalBinaryExpression(ast, subs) {\n const result = {\n '||': (a, b) => a || b(),\n '&&': (a, b) => a && b(),\n '|': (a, b) => a | b(),\n '^': (a, b) => a ^ b(),\n '&': (a, b) => a & b(),\n // eslint-disable-next-line eqeqeq -- API\n '==': (a, b) => a == b(),\n // eslint-disable-next-line eqeqeq -- API\n '!=': (a, b) => a != b(),\n '===': (a, b) => a === b(),\n '!==': (a, b) => a !== b(),\n '<': (a, b) => a < b(),\n '>': (a, b) => a > b(),\n '<=': (a, b) => a <= b(),\n '>=': (a, b) => a >= b(),\n '<<': (a, b) => a << b(),\n '>>': (a, b) => a >> b(),\n '>>>': (a, b) => a >>> b(),\n '+': (a, b) => a + b(),\n '-': (a, b) => a - b(),\n '*': (a, b) => a * b(),\n '/': (a, b) => a / b(),\n '%': (a, b) => a % b()\n }[ast.operator](SafeEval.evalAst(ast.left, subs), () => SafeEval.evalAst(ast.right, subs));\n return result;\n },\n evalCompound(ast, subs) {\n let last;\n for (let i = 0; i < ast.body.length; i++) {\n if (ast.body[i].type === 'Identifier' && ['var', 'let', 'const'].includes(ast.body[i].name) && ast.body[i + 1] && ast.body[i + 1].type === 'AssignmentExpression') {\n // var x=2; is detected as\n // [{Identifier var}, {AssignmentExpression x=2}]\n // eslint-disable-next-line @stylistic/max-len -- Long\n // eslint-disable-next-line sonarjs/updated-loop-counter -- Convenient\n i += 1;\n }\n const expr = ast.body[i];\n last = SafeEval.evalAst(expr, subs);\n }\n return last;\n },\n evalConditionalExpression(ast, subs) {\n if (SafeEval.evalAst(ast.test, subs)) {\n return SafeEval.evalAst(ast.consequent, subs);\n }\n return SafeEval.evalAst(ast.alternate, subs);\n },\n evalIdentifier(ast, subs) {\n if (Object.hasOwn(subs, ast.name)) {\n return subs[ast.name];\n }\n throw ReferenceError(`${ast.name} is not defined`);\n },\n evalLiteral(ast) {\n return ast.value;\n },\n evalMemberExpression(ast, subs) {\n const prop = String(\n // NOTE: `String(value)` throws error when\n // value has overwritten the toString method to return non-string\n // i.e. `value = {toString: () => []}`\n ast.computed ? SafeEval.evalAst(ast.property) // `object[property]`\n : ast.property.name // `object.property` property is Identifier\n );\n const obj = SafeEval.evalAst(ast.object, subs);\n if (obj === undefined || obj === null) {\n throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);\n }\n if (!Object.hasOwn(obj, prop) && BLOCKED_PROTO_PROPERTIES.has(prop)) {\n throw TypeError(`Cannot read properties of ${obj} (reading '${prop}')`);\n }\n const result = obj[prop];\n if (typeof result === 'function') {\n return result.bind(obj); // arrow functions aren't affected by bind.\n }\n return result;\n },\n evalUnaryExpression(ast, subs) {\n const result = {\n '-': a => -SafeEval.evalAst(a, subs),\n '!': a => !SafeEval.evalAst(a, subs),\n '~': a => ~SafeEval.evalAst(a, subs),\n // eslint-disable-next-line no-implicit-coercion -- API\n '+': a => +SafeEval.evalAst(a, subs),\n typeof: a => typeof SafeEval.evalAst(a, subs),\n // eslint-disable-next-line no-void, sonarjs/void-use -- feature\n void: a => void SafeEval.evalAst(a, subs)\n }[ast.operator](ast.argument);\n return result;\n },\n evalArrayExpression(ast, subs) {\n return ast.elements.map(el => SafeEval.evalAst(el, subs));\n },\n evalCallExpression(ast, subs) {\n const args = ast.arguments.map(arg => SafeEval.evalAst(arg, subs));\n const func = SafeEval.evalAst(ast.callee, subs);\n /* c8 ignore start */\n if (func === Function) {\n // unreachable since BLOCKED_PROTO_PROPERTIES includes 'constructor'\n throw new Error('Function constructor is disabled');\n }\n /* c8 ignore end */\n return func(...args);\n },\n evalAssignmentExpression(ast, subs) {\n if (ast.left.type !== 'Identifier') {\n throw SyntaxError('Invalid left-hand side in assignment');\n }\n const id = ast.left.name;\n const value = SafeEval.evalAst(ast.right, subs);\n subs[id] = value;\n return subs[id];\n }\n};\n\n/**\n * A replacement for NodeJS' VM.Script which is also {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | Content Security Policy} friendly.\n */\nclass SafeScript {\n /**\n * @param {string} expr Expression to evaluate\n */\n constructor(expr) {\n this.code = expr;\n this.ast = jsep(this.code);\n }\n\n /**\n * @param {object} context Object whose items will be added\n * to evaluation\n * @returns {EvaluatedResult} Result of evaluated code\n */\n runInNewContext(context) {\n // `Object.create(null)` creates a prototypeless object\n const keyMap = Object.assign(Object.create(null), context);\n return SafeEval.evalAst(this.ast, keyMap);\n }\n}\n\n/* eslint-disable camelcase -- Convenient for escaping */\n\n\n/**\n * @typedef {null|boolean|number|string|object|GenericArray} JSONObject\n */\n\n/**\n * @typedef {any} AnyItem\n */\n\n/**\n * @typedef {any} AnyResult\n */\n\n/**\n * Copies array and then pushes item into it.\n * @param {GenericArray} arr Array to copy and into which to push\n * @param {AnyItem} item Array item to add (to end)\n * @returns {GenericArray} Copy of the original array\n */\nfunction push(arr, item) {\n arr = arr.slice();\n arr.push(item);\n return arr;\n}\n/**\n * Copies array and then unshifts item into it.\n * @param {AnyItem} item Array item to add (to beginning)\n * @param {GenericArray} arr Array to copy and into which to unshift\n * @returns {GenericArray} Copy of the original array\n */\nfunction unshift(item, arr) {\n arr = arr.slice();\n arr.unshift(item);\n return arr;\n}\n\n/**\n * Caught when JSONPath is used without `new` but rethrown if with `new`\n * @extends Error\n */\nclass NewError extends Error {\n /**\n * @param {AnyResult} value The evaluated scalar value\n */\n constructor(value) {\n super('JSONPath should not be called with \"new\" (it prevents return ' + 'of (unwrapped) scalar values)');\n this.avoidNew = true;\n this.value = value;\n this.name = 'NewError';\n }\n}\n\n/**\n* @typedef {object} ReturnObject\n* @property {string} path\n* @property {JSONObject} value\n* @property {object|GenericArray} parent\n* @property {string} parentProperty\n*/\n\n/**\n* @callback JSONPathCallback\n* @param {string|object} preferredOutput\n* @param {\"value\"|\"property\"} type\n* @param {ReturnObject} fullRetObj\n* @returns {void}\n*/\n\n/**\n* @callback OtherTypeCallback\n* @param {JSONObject} val\n* @param {string} path\n* @param {object|GenericArray} parent\n* @param {string} parentPropName\n* @returns {boolean}\n*/\n\n/**\n * @typedef {any} ContextItem\n */\n\n/**\n * @typedef {any} EvaluatedResult\n */\n\n/**\n* @callback EvalCallback\n* @param {string} code\n* @param {ContextItem} context\n* @returns {EvaluatedResult}\n*/\n\n/**\n * @typedef {typeof SafeScript} EvalClass\n */\n\n/**\n * @typedef {object} JSONPathOptions\n * @property {JSON} json\n * @property {string|string[]} path\n * @property {\"value\"|\"path\"|\"pointer\"|\"parent\"|\"parentProperty\"|\n * \"all\"} [resultType=\"value\"]\n * @property {boolean} [flatten=false]\n * @property {boolean} [wrap=true]\n * @property {object} [sandbox={}]\n * @property {EvalCallback|EvalClass|'safe'|'native'|\n * boolean} [eval = 'safe']\n * @property {object|GenericArray|null} [parent=null]\n * @property {string|null} [parentProperty=null]\n * @property {JSONPathCallback} [callback]\n * @property {OtherTypeCallback} [otherTypeCallback] Defaults to\n * function which throws on encountering `@other`\n * @property {boolean} [autostart=true]\n */\n\n/**\n * @param {string|JSONPathOptions} opts If a string, will be treated as `expr`\n * @param {string} [expr] JSON path to evaluate\n * @param {JSON} [obj] JSON object to evaluate against\n * @param {JSONPathCallback} [callback] Passed 3 arguments: 1) desired payload\n * per `resultType`, 2) `\"value\"|\"property\"`, 3) Full returned object with\n * all payloads\n * @param {OtherTypeCallback} [otherTypeCallback] If `@other()` is at the end\n * of one's query, this will be invoked with the value of the item, its\n * path, its parent, and its parent's property name, and it should return\n * a boolean indicating whether the supplied value belongs to the \"other\"\n * type or not (or it may handle transformations and return `false`).\n * @returns {JSONPath}\n * @class\n */\nfunction JSONPath(opts, expr, obj, callback, otherTypeCallback) {\n // eslint-disable-next-line no-restricted-syntax -- Allow for pseudo-class\n if (!(this instanceof JSONPath)) {\n try {\n return new JSONPath(opts, expr, obj, callback, otherTypeCallback);\n } catch (e) {\n if (!e.avoidNew) {\n throw e;\n }\n return e.value;\n }\n }\n if (typeof opts === 'string') {\n otherTypeCallback = callback;\n callback = obj;\n obj = expr;\n expr = opts;\n opts = null;\n }\n const optObj = opts && typeof opts === 'object';\n opts = opts || {};\n this.json = opts.json || obj;\n this.path = opts.path || expr;\n this.resultType = opts.resultType || 'value';\n this.flatten = opts.flatten || false;\n this.wrap = Object.hasOwn(opts, 'wrap') ? opts.wrap : true;\n this.sandbox = opts.sandbox || {};\n this.eval = opts.eval === undefined ? 'safe' : opts.eval;\n this.ignoreEvalErrors = typeof opts.ignoreEvalErrors === 'undefined' ? false : opts.ignoreEvalErrors;\n this.parent = opts.parent || null;\n this.parentProperty = opts.parentProperty || null;\n this.callback = opts.callback || callback || null;\n this.otherTypeCallback = opts.otherTypeCallback || otherTypeCallback || function () {\n throw new TypeError('You must supply an otherTypeCallback callback option ' + 'with the @other() operator.');\n };\n if (opts.autostart !== false) {\n const args = {\n path: optObj ? opts.path : expr\n };\n if (!optObj) {\n args.json = obj;\n } else if ('json' in opts) {\n args.json = opts.json;\n }\n const ret = this.evaluate(args);\n if (!ret || typeof ret !== 'object') {\n throw new NewError(ret);\n }\n return ret;\n }\n}\n\n// PUBLIC METHODS\nJSONPath.prototype.evaluate = function (expr, json, callback, otherTypeCallback) {\n let currParent = this.parent,\n currParentProperty = this.parentProperty;\n let {\n flatten,\n wrap\n } = this;\n this.currResultType = this.resultType;\n this.currEval = this.eval;\n this.currSandbox = this.sandbox;\n callback = callback || this.callback;\n this.currOtherTypeCallback = otherTypeCallback || this.otherTypeCallback;\n json = json || this.json;\n expr = expr || this.path;\n if (expr && typeof expr === 'object' && !Array.isArray(expr)) {\n if (!expr.path && expr.path !== '') {\n throw new TypeError('You must supply a \"path\" property when providing an object ' + 'argument to JSONPath.evaluate().');\n }\n if (!Object.hasOwn(expr, 'json')) {\n throw new TypeError('You must supply a \"json\" property when providing an object ' + 'argument to JSONPath.evaluate().');\n }\n ({\n json\n } = expr);\n flatten = Object.hasOwn(expr, 'flatten') ? expr.flatten : flatten;\n this.currResultType = Object.hasOwn(expr, 'resultType') ? expr.resultType : this.currResultType;\n this.currSandbox = Object.hasOwn(expr, 'sandbox') ? expr.sandbox : this.currSandbox;\n wrap = Object.hasOwn(expr, 'wrap') ? expr.wrap : wrap;\n this.currEval = Object.hasOwn(expr, 'eval') ? expr.eval : this.currEval;\n callback = Object.hasOwn(expr, 'callback') ? expr.callback : callback;\n this.currOtherTypeCallback = Object.hasOwn(expr, 'otherTypeCallback') ? expr.otherTypeCallback : this.currOtherTypeCallback;\n currParent = Object.hasOwn(expr, 'parent') ? expr.parent : currParent;\n currParentProperty = Object.hasOwn(expr, 'parentProperty') ? expr.parentProperty : currParentProperty;\n expr = expr.path;\n }\n currParent = currParent || null;\n currParentProperty = currParentProperty || null;\n if (Array.isArray(expr)) {\n expr = JSONPath.toPathString(expr);\n }\n if (!expr && expr !== '' || !json) {\n return undefined;\n }\n const exprList = JSONPath.toPathArray(expr);\n if (exprList[0] === '$' && exprList.length > 1) {\n exprList.shift();\n }\n this._hasParentSelector = null;\n const result = this._trace(exprList, json, ['$'], currParent, currParentProperty, callback).filter(function (ea) {\n return ea && !ea.isParentSelector;\n });\n if (!result.length) {\n return wrap ? [] : undefined;\n }\n if (!wrap && result.length === 1 && !result[0].hasArrExpr) {\n return this._getPreferredOutput(result[0]);\n }\n return result.reduce((rslt, ea) => {\n const valOrPath = this._getPreferredOutput(ea);\n if (flatten && Array.isArray(valOrPath)) {\n rslt = rslt.concat(valOrPath);\n } else {\n rslt.push(valOrPath);\n }\n return rslt;\n }, []);\n};\n\n// PRIVATE METHODS\n\nJSONPath.prototype._getPreferredOutput = function (ea) {\n const resultType = this.currResultType;\n switch (resultType) {\n case 'all':\n {\n const path = Array.isArray(ea.path) ? ea.path : JSONPath.toPathArray(ea.path);\n ea.pointer = JSONPath.toPointer(path);\n ea.path = typeof ea.path === 'string' ? ea.path : JSONPath.toPathString(ea.path);\n return ea;\n }\n case 'value':\n case 'parent':\n case 'parentProperty':\n return ea[resultType];\n case 'path':\n return JSONPath.toPathString(ea[resultType]);\n case 'pointer':\n return JSONPath.toPointer(ea.path);\n default:\n throw new TypeError('Unknown result type');\n }\n};\nJSONPath.prototype._handleCallback = function (fullRetObj, callback, type) {\n if (callback) {\n const preferredOutput = this._getPreferredOutput(fullRetObj);\n fullRetObj.path = typeof fullRetObj.path === 'string' ? fullRetObj.path : JSONPath.toPathString(fullRetObj.path);\n // eslint-disable-next-line n/callback-return -- No need to return\n callback(preferredOutput, type, fullRetObj);\n }\n};\n\n/**\n *\n * @param {string} expr\n * @param {JSONObject} val\n * @param {string} path\n * @param {object|GenericArray} parent\n * @param {string} parentPropName\n * @param {JSONPathCallback} callback\n * @param {boolean} hasArrExpr\n * @param {boolean} literalPriority\n * @returns {ReturnObject|ReturnObject[]}\n */\nJSONPath.prototype._trace = function (expr, val, path, parent, parentPropName, callback, hasArrExpr, literalPriority) {\n // No expr to follow? return path and value as the result of\n // this trace branch\n let retObj;\n if (!expr.length) {\n retObj = {\n path,\n value: val,\n parent,\n parentProperty: parentPropName,\n hasArrExpr\n };\n this._handleCallback(retObj, callback, 'value');\n return retObj;\n }\n const loc = expr[0],\n x = expr.slice(1);\n\n // We need to gather the return value of recursive trace calls in order to\n // do the parent sel computation.\n const ret = [];\n /**\n *\n * @param {ReturnObject|ReturnObject[]} elems\n * @returns {void}\n */\n function addRet(elems) {\n if (Array.isArray(elems)) {\n // This was causing excessive stack size in Node (with or\n // without Babel) against our performance test:\n // `ret.push(...elems);`\n elems.forEach(t => {\n ret.push(t);\n });\n } else {\n ret.push(elems);\n }\n }\n if ((typeof loc !== 'string' || literalPriority) && val && Object.hasOwn(val, loc)) {\n // simple case--directly follow property\n addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr));\n // eslint-disable-next-line unicorn/prefer-switch -- Part of larger `if`\n } else if (loc === '*') {\n // all child properties\n this._walk(val, m => {\n addRet(this._trace(x, val[m], push(path, m), val, m, callback, true, true));\n });\n } else if (loc === '..') {\n // all descendent parent properties\n // Check remaining expression with val's immediate children\n addRet(this._trace(x, val, path, parent, parentPropName, callback, hasArrExpr));\n this._walk(val, m => {\n // We don't join m and x here because we only want parents,\n // not scalar values\n if (typeof val[m] === 'object') {\n // Keep going with recursive descent on val's\n // object children\n addRet(this._trace(expr.slice(), val[m], push(path, m), val, m, callback, true));\n }\n });\n // The parent sel computation is handled in the frame above using the\n // ancestor object of val\n } else if (loc === '^') {\n // This is not a final endpoint, so we do not invoke the callback here\n this._hasParentSelector = true;\n return {\n path: path.slice(0, -1),\n expr: x,\n isParentSelector: true\n };\n } else if (loc === '~') {\n // property name\n retObj = {\n path: push(path, loc),\n value: parentPropName,\n parent,\n parentProperty: null\n };\n this._handleCallback(retObj, callback, 'property');\n return retObj;\n } else if (loc === '$') {\n // root only\n addRet(this._trace(x, val, path, null, null, callback, hasArrExpr));\n } else if (/^(-?\\d*):(-?\\d*):?(\\d*)$/u.test(loc)) {\n // [start:end:step] Python slice syntax\n addRet(this._slice(loc, x, val, path, parent, parentPropName, callback));\n } else if (loc.indexOf('?(') === 0) {\n // [?(expr)] (filtering)\n if (this.currEval === false) {\n throw new Error('Eval [?(expr)] prevented in JSONPath expression.');\n }\n const safeLoc = loc.replace(/^\\?\\((.*?)\\)$/u, '$1');\n // check for a nested filter expression\n const nested = /@.?([^?]*)[['](\\??\\(.*?\\))(?!.\\)\\])[\\]']/gu.exec(safeLoc);\n if (nested) {\n // find if there are matches in the nested expression\n // add them to the result set if there is at least one match\n this._walk(val, m => {\n const npath = [nested[2]];\n const nvalue = nested[1] ? val[m][nested[1]] : val[m];\n const filterResults = this._trace(npath, nvalue, path, parent, parentPropName, callback, true);\n if (filterResults.length > 0) {\n addRet(this._trace(x, val[m], push(path, m), val, m, callback, true));\n }\n });\n } else {\n this._walk(val, m => {\n if (this._eval(safeLoc, val[m], m, path, parent, parentPropName)) {\n addRet(this._trace(x, val[m], push(path, m), val, m, callback, true));\n }\n });\n }\n } else if (loc[0] === '(') {\n // [(expr)] (dynamic property/index)\n if (this.currEval === false) {\n throw new Error('Eval [(expr)] prevented in JSONPath expression.');\n }\n // As this will resolve to a property name (but we don't know it\n // yet), property and parent information is relative to the\n // parent of the property to which this expression will resolve\n addRet(this._trace(unshift(this._eval(loc, val, path.at(-1), path.slice(0, -1), parent, parentPropName), x), val, path, parent, parentPropName, callback, hasArrExpr));\n } else if (loc[0] === '@') {\n // value type: @boolean(), etc.\n let addType = false;\n const valueType = loc.slice(1, -2);\n switch (valueType) {\n case 'scalar':\n if (!val || !['object', 'function'].includes(typeof val)) {\n addType = true;\n }\n break;\n case 'boolean':\n case 'string':\n case 'undefined':\n case 'function':\n if (typeof val === valueType) {\n addType = true;\n }\n break;\n case 'integer':\n if (Number.isFinite(val) && !(val % 1)) {\n addType = true;\n }\n break;\n case 'number':\n if (Number.isFinite(val)) {\n addType = true;\n }\n break;\n case 'nonFinite':\n if (typeof val === 'number' && !Number.isFinite(val)) {\n addType = true;\n }\n break;\n case 'object':\n if (val && typeof val === valueType) {\n addType = true;\n }\n break;\n case 'array':\n if (Array.isArray(val)) {\n addType = true;\n }\n break;\n case 'other':\n addType = this.currOtherTypeCallback(val, path, parent, parentPropName);\n break;\n case 'null':\n if (val === null) {\n addType = true;\n }\n break;\n /* c8 ignore next 2 */\n default:\n throw new TypeError('Unknown value type ' + valueType);\n }\n if (addType) {\n retObj = {\n path,\n value: val,\n parent,\n parentProperty: parentPropName\n };\n this._handleCallback(retObj, callback, 'value');\n return retObj;\n }\n // `-escaped property\n } else if (loc[0] === '`' && val && Object.hasOwn(val, loc.slice(1))) {\n const locProp = loc.slice(1);\n addRet(this._trace(x, val[locProp], push(path, locProp), val, locProp, callback, hasArrExpr, true));\n } else if (loc.includes(',')) {\n // [name1,name2,...]\n const parts = loc.split(',');\n for (const part of parts) {\n addRet(this._trace(unshift(part, x), val, path, parent, parentPropName, callback, true));\n }\n // simple case--directly follow property\n } else if (!literalPriority && val && Object.hasOwn(val, loc)) {\n addRet(this._trace(x, val[loc], push(path, loc), val, loc, callback, hasArrExpr, true));\n }\n\n // We check the resulting values for parent selections. For parent\n // selections we discard the value object and continue the trace with the\n // current val object\n if (this._hasParentSelector) {\n for (let t = 0; t < ret.length; t++) {\n const rett = ret[t];\n if (rett && rett.isParentSelector) {\n const tmp = this._trace(rett.expr, val, rett.path, parent, parentPropName, callback, hasArrExpr);\n if (Array.isArray(tmp)) {\n ret[t] = tmp[0];\n const tl = tmp.length;\n for (let tt = 1; tt < tl; tt++) {\n // eslint-disable-next-line @stylistic/max-len -- Long\n // eslint-disable-next-line sonarjs/updated-loop-counter -- Convenient\n t++;\n ret.splice(t, 0, tmp[tt]);\n }\n } else {\n ret[t] = tmp;\n }\n }\n }\n }\n return ret;\n};\nJSONPath.prototype._walk = function (val, f) {\n if (Array.isArray(val)) {\n const n = val.length;\n for (let i = 0; i < n; i++) {\n f(i);\n }\n } else if (val && typeof val === 'object') {\n Object.keys(val).forEach(m => {\n f(m);\n });\n }\n};\nJSONPath.prototype._slice = function (loc, expr, val, path, parent, parentPropName, callback) {\n if (!Array.isArray(val)) {\n return undefined;\n }\n const len = val.length,\n parts = loc.split(':'),\n step = parts[2] && Number.parseInt(parts[2]) || 1;\n let start = parts[0] && Number.parseInt(parts[0]) || 0,\n end = parts[1] && Number.parseInt(parts[1]) || len;\n start = start < 0 ? Math.max(0, start + len) : Math.min(len, start);\n end = end < 0 ? Math.max(0, end + len) : Math.min(len, end);\n const ret = [];\n for (let i = start; i < end; i += step) {\n const tmp = this._trace(unshift(i, expr), val, path, parent, parentPropName, callback, true);\n // Should only be possible to be an array here since first part of\n // ``unshift(i, expr)` passed in above would not be empty, nor `~`,\n // nor begin with `@` (as could return objects)\n // This was causing excessive stack size in Node (with or\n // without Babel) against our performance test: `ret.push(...tmp);`\n tmp.forEach(t => {\n ret.push(t);\n });\n }\n return ret;\n};\nJSONPath.prototype._eval = function (code, _v, _vname, path, parent, parentPropName) {\n this.currSandbox._$_parentProperty = parentPropName;\n this.currSandbox._$_parent = parent;\n this.currSandbox._$_property = _vname;\n this.currSandbox._$_root = this.json;\n this.currSandbox._$_v = _v;\n const containsPath = code.includes('@path');\n if (containsPath) {\n this.currSandbox._$_path = JSONPath.toPathString(path.concat([_vname]));\n }\n const scriptCacheKey = this.currEval + 'Script:' + code;\n if (!JSONPath.cache[scriptCacheKey]) {\n let script = code.replaceAll('@parentProperty', '_$_parentProperty').replaceAll('@parent', '_$_parent').replaceAll('@property', '_$_property').replaceAll('@root', '_$_root').replaceAll(/@([.\\s)[])/gu, '_$_v$1');\n if (containsPath) {\n script = script.replaceAll('@path', '_$_path');\n }\n if (this.currEval === 'safe' || this.currEval === true || this.currEval === undefined) {\n JSONPath.cache[scriptCacheKey] = new this.safeVm.Script(script);\n } else if (this.currEval === 'native') {\n JSONPath.cache[scriptCacheKey] = new this.vm.Script(script);\n } else if (typeof this.currEval === 'function' && this.currEval.prototype && Object.hasOwn(this.currEval.prototype, 'runInNewContext')) {\n const CurrEval = this.currEval;\n JSONPath.cache[scriptCacheKey] = new CurrEval(script);\n } else if (typeof this.currEval === 'function') {\n JSONPath.cache[scriptCacheKey] = {\n runInNewContext: context => this.currEval(script, context)\n };\n } else {\n throw new TypeError(`Unknown \"eval\" property \"${this.currEval}\"`);\n }\n }\n try {\n return JSONPath.cache[scriptCacheKey].runInNewContext(this.currSandbox);\n } catch (e) {\n if (this.ignoreEvalErrors) {\n return false;\n }\n throw new Error('jsonPath: ' + e.message + ': ' + code);\n }\n};\n\n// PUBLIC CLASS PROPERTIES AND METHODS\n\n// Could store the cache object itself\nJSONPath.cache = {};\n\n/**\n * @param {string[]} pathArr Array to convert\n * @returns {string} The path string\n */\nJSONPath.toPathString = function (pathArr) {\n const x = pathArr,\n n = x.length;\n let p = '$';\n for (let i = 1; i < n; i++) {\n if (!/^(~|\\^|@.*?\\(\\))$/u.test(x[i])) {\n p += /^[0-9*]+$/u.test(x[i]) ? '[' + x[i] + ']' : \"['\" + x[i] + \"']\";\n }\n }\n return p;\n};\n\n/**\n * @param {string} pointer JSON Path\n * @returns {string} JSON Pointer\n */\nJSONPath.toPointer = function (pointer) {\n const x = pointer,\n n = x.length;\n let p = '';\n for (let i = 1; i < n; i++) {\n if (!/^(~|\\^|@.*?\\(\\))$/u.test(x[i])) {\n p += '/' + x[i].toString().replaceAll('~', '~0').replaceAll('/', '~1');\n }\n }\n return p;\n};\n\n/**\n * @param {string} expr Expression to convert\n * @returns {string[]}\n */\nJSONPath.toPathArray = function (expr) {\n const {\n cache\n } = JSONPath;\n if (cache[expr]) {\n return cache[expr].concat();\n }\n const subx = [];\n const normalized = expr\n // Properties\n .replaceAll(/@(?:null|boolean|number|string|integer|undefined|nonFinite|scalar|array|object|function|other)\\(\\)/gu, ';$&;')\n // Parenthetical evaluations (filtering and otherwise), directly\n // within brackets or single quotes\n .replaceAll(/[['](\\??\\(.*?\\))[\\]'](?!.\\])/gu, function ($0, $1) {\n return '[#' + (subx.push($1) - 1) + ']';\n })\n // Escape periods and tildes within properties\n .replaceAll(/\\[['\"]([^'\\]]*)['\"]\\]/gu, function ($0, prop) {\n return \"['\" + prop.replaceAll('.', '%@%').replaceAll('~', '%%@@%%') + \"']\";\n })\n // Properties operator\n .replaceAll('~', ';~;')\n // Split by property boundaries\n .replaceAll(/['\"]?\\.['\"]?(?![^[]*\\])|\\[['\"]?/gu, ';')\n // Reinsert periods within properties\n .replaceAll('%@%', '.')\n // Reinsert tildes within properties\n .replaceAll('%%@@%%', '~')\n // Parent\n .replaceAll(/(?:;)?(\\^+)(?:;)?/gu, function ($0, ups) {\n return ';' + ups.split('').join(';') + ';';\n })\n // Descendents\n .replaceAll(/;;;|;;/gu, ';..;')\n // Remove trailing\n .replaceAll(/;$|'?\\]|'$/gu, '');\n const exprList = normalized.split(';').map(function (exp) {\n const match = exp.match(/#(\\d+)/u);\n return !match || !match[1] ? exp : subx[match[1]];\n });\n cache[expr] = exprList;\n return cache[expr].concat();\n};\nJSONPath.prototype.safeVm = {\n Script: SafeScript\n};\n\nJSONPath.prototype.vm = vm;\n\nexport { JSONPath };\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jsonl-Dw_VBp46.mjs","names":["#jsonl","#fetch","#nodes","#root","#path","#it","#count","#fd","#toJson"],"sources":["../src/session/jsonl.ts"],"sourcesContent":["import type { FileHandle } from \"node:fs/promises\"\nimport type { SessionStore } from \"./store.ts\"\nimport type { SessionNode } from \"./types.ts\"\n\nimport { normPath, safeStringify, withLock } from \"@zaly/shared\"\nimport { appendFile, open } from \"node:fs/promises\"\n\nconst CHUNK_SIZE = 4 * 1024 * 1024\n\n/**\n * JSONL-backed `SessionStore` — append-only file, one record per line.\n *\n * Current implementation reads the entire file on `load()` and keeps the\n * full DAG in memory. Future optimizations (lazy reads with offset\n * index, LRU cache for huge sessions) can land behind this same\n * interface without changing `Session`.\n *\n * Crash tolerance: a truncated last line (interrupted mid-write) is\n * silently dropped; any other JSON parse error mid-file throws so real\n * corruption surfaces loudly.\n */\nexport class JsonlStore implements SessionStore {\n readonly path: string\n #nodes = new Map<string, SessionNode>()\n #root?: SessionNode\n #jsonl: JsonlReader<SessionNode>\n\n constructor(path: string) {\n this.path = path\n this.#jsonl = new JsonlReader(path)\n }\n\n /** Load + open: hydrate the DAG from `path` (when the file exists),\n * then open the writer in append mode. New nodes land on disk as\n * they're committed. */\n static async load(path: string): Promise<JsonlStore> {\n path = normPath(path)\n const ret = new JsonlStore(path)\n await ret.#fetch({ limit: 1 })\n return ret\n }\n\n async #fetch(opts?: { id?: string; limit?: number }): Promise<SessionNode | undefined> {\n let count = 0\n let value: SessionNode | undefined\n // oxlint-disable-next-line no-await-in-loop\n while ((value = await this.#jsonl.next()) !== undefined) {\n this.#nodes.set(value.uuid, value)\n this.#root ??= value\n if (opts?.limit && count++ >= opts.limit) break // safe — doesn't call .return()\n if (opts?.id && value.uuid === opts.id) return value\n }\n }\n\n get root(): SessionNode | undefined {\n return this.#root\n }\n\n async get(id: string): Promise<SessionNode | undefined> {\n return this.#nodes.get(id) ?? (await this.#fetch({ id }))\n }\n\n async write(node: SessionNode): Promise<void> {\n const line = `${safeStringify(node)}\\n`\n await withLock(this.path, async () => {\n await appendFile(this.path, line, \"utf8\")\n })\n this.#nodes.set(node.uuid, node)\n this.#root = node\n }\n\n async close(): Promise<void> {\n await this.#jsonl.close()\n }\n\n async *all(): AsyncIterable<SessionNode> {\n await this.#fetch()\n yield* this.#nodes.values()\n }\n}\n\nexport class JsonlReader<T> {\n #fd?: FileHandle\n #path: string\n #it?: AsyncIterableIterator<T>\n #count = 0\n\n constructor(readonly path: string) {\n this.#path = path\n this.#it = this.generator()\n }\n\n #toJson(line: string): T | undefined {\n if (line.trim() === \"\") return\n try {\n const ret = JSON.parse(line) as T\n this.#count++\n return ret\n } catch (error) {\n // Tolerate a truncated last line (crash mid-write); anything\n // else is real corruption.\n if (this.#count === 0) return\n throw new Error(\n `JsonlStore.load: malformed JSON at line ${this.#count + 1} of \"${this.#path}\": ${(error as Error).message}`,\n { cause: error }\n )\n }\n }\n\n private async *generator(): AsyncIterableIterator<T> {\n try {\n this.#fd = await open(this.#path, \"r\")\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return\n throw error\n }\n let { size: position } = await this.#fd.stat()\n let leftover = \"\"\n try {\n while (position > 0) {\n const length = Math.min(position, CHUNK_SIZE)\n position -= length\n // oxlint-disable-next-line no-await-in-loop\n const { buffer } = await this.#fd.read(Buffer.alloc(length), 0, length, position)\n const lines = (buffer.toString(\"utf8\") + leftover).split(/\\r?\\n/)\n leftover = lines.shift() ?? \"\"\n for (let i = lines.length - 1; i >= 0; i--) {\n const v = this.#toJson(lines[i])\n if (v) yield v\n }\n }\n if (leftover.length) {\n const v = this.#toJson(leftover)\n if (v) yield v\n }\n } finally {\n await this.#fd.close()\n this.#it = undefined\n }\n }\n\n async next(): Promise<T | undefined> {\n if (!this.#it) return\n const { value, done } = await this.#it.next()\n return done ? undefined : value\n }\n\n async close() {\n if (this.#it) {\n await this.#it.return?.() // runs the generator's finally\n this.#it = undefined\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"manager-D-lWBTHG.mjs","names":["#rules","#workspaces"],"sources":["../src/permissions/presets.ts","../src/permissions/manager.ts"],"sourcesContent":["import type { Verdict } from \"./types.ts\"\n\n/**\n * Permission presets — verdict-keyed pattern lists in the same shape\n * `parseRules` accepts. The TUI exposes these as `--preset strict`,\n * `--preset readonly`, etc.; the manager resolves the chosen preset to\n * the structured `Rule<string>[]` at construction.\n *\n * Pattern grammar:\n * \"bash(ls:*)\" → bash command pattern\n * \"read(/src/**)\" → workspace-relative gitignore pattern\n * \"read(*)\" → matches every read in any workspace\n * \"bash\" → bare scope, equivalent to `bash(*)` (match any cmd)\n *\n * Scope names are exact matches against the tool name they gate\n * (snake_case). Underscored scopes work too (`task_stop`, `task_poll`).\n */\nexport type PermissionPresetName = \"strict\" | \"readonly\" | \"permissive\" | \"yolo\"\n\nexport interface PermissionPreset {\n description: string\n rules: Partial<Record<Verdict, string[]>>\n}\n\n// ── Pattern groups ─────────────────────────────────────────────────────────\n\n/** Native tools that only inspect session state or workspace files. */\nconst READONLY_TOOLS = [\n \"tool(read)\",\n \"tool(grep)\",\n \"tool(find)\",\n \"tool(task_list)\",\n \"tool(task_poll)\",\n]\n\n/** Read-only utilities the model can run without surprises: file\n * inspection, search, metadata. None of these modify state on their own.\n * (`sed`/`awk` writes still gated by Write rules via the bash handler's\n * composition with the file handler.) */\nconst READONLY_BASH = [\n \"bash(ls:*)\",\n \"bash(cat:*)\",\n \"bash(head:*)\",\n \"bash(tail:*)\",\n \"bash(wc:*)\",\n \"bash(find:*)\",\n \"bash(grep:*)\",\n \"bash(rg:*)\",\n \"bash(fd:*)\",\n \"bash(sort:*)\",\n \"bash(uniq:*)\",\n \"bash(cut:*)\",\n \"bash(diff:*)\",\n \"bash(stat:*)\",\n \"bash(file:*)\",\n \"bash(realpath:*)\",\n \"bash(readlink:*)\",\n \"bash(basename:*)\",\n \"bash(dirname:*)\",\n \"bash(echo:*)\",\n \"bash(printf:*)\",\n \"bash(sed:*)\",\n \"bash(awk:*)\",\n \"bash(xxd:*)\",\n \"bash(hexdump:*)\",\n \"bash(od:*)\",\n \"bash(tree:*)\",\n \"bash(pwd)\",\n \"bash(true)\",\n \"bash(false)\",\n \"bash(which:*)\",\n \"bash(type:*)\",\n \"bash(command:*)\",\n \"bash(test:*)\",\n \"bash(cd:*)\",\n]\n\n/** Read-only git + GitHub CLI subcommands. */\nconst READONLY_GIT = [\n \"bash(git status:*)\",\n \"bash(git log:*)\",\n \"bash(git diff:*)\",\n \"bash(git show:*)\",\n \"bash(git show-ref:*)\",\n \"bash(git branch:*)\",\n \"bash(git remote:*)\",\n \"bash(git rev-parse:*)\",\n \"bash(git config --get:*)\",\n \"bash(gh issue list:*)\",\n \"bash(gh issue view:*)\",\n \"bash(gh pr list:*)\",\n \"bash(gh pr view:*)\",\n \"bash(gh repo view:*)\",\n]\n\n/** Common dev-workflow commands — build, test, typecheck. Excludes\n * package management (`npm install`, `bun add`) which can drag arbitrary\n * code in over the network. */\nconst DEV_BASIC = [\n \"bash(bun test:*)\",\n \"bash(bun test:node:*)\",\n \"bash(bun test:bun:*)\",\n \"bash(bun check:*)\",\n \"bash(bun run:*)\",\n \"bash(bun build:*)\",\n \"bash(bunx tsc:*)\",\n \"bash(bun tsc:*)\",\n \"bash(bun x tsc:*)\",\n \"bash(bunx vitest:*)\",\n \"bash(bun x vitest:*)\",\n \"bash(bunx oxlint:*)\",\n \"bash(bun x oxlint:*)\",\n \"bash(oxlint:*)\",\n]\n\n/** Hard denies — never auto-allowed, regardless of preset. */\nconst HARD_DENIES = [\"bash(sudo:*)\"]\n\n/** Broader rules unlocked by the permissive preset. Trades some safety\n * for speed — appropriate for frontier models with strong instruction\n * following. Includes ad-hoc bun/node evals and git mutations. */\nconst PERMISSIVE_EXTRAS = [\n \"bash(bun -e:*)\",\n \"bash(bun:*)\",\n \"bash(node:*)\",\n \"bash(node -e:*)\",\n \"bash(make:*)\",\n \"bash(mkdir:*)\",\n \"bash(cp:*)\",\n \"bash(mv:*)\",\n \"bash(touch:*)\",\n \"bash(ln:*)\",\n \"bash(chmod:*)\",\n \"bash(git add:*)\",\n \"bash(git commit:*)\",\n \"bash(git checkout:*)\",\n \"bash(git restore:*)\",\n \"bash(git stash:*)\",\n \"bash(git fetch:*)\",\n \"bash(git pull:*)\",\n \"bash(curl:*)\",\n \"bash(jq:*)\",\n \"bash(perl -e:*)\",\n \"bash(timeout:*)\",\n \"bash(for:*)\",\n \"bash(while:*)\",\n]\n\n// ── Presets ────────────────────────────────────────────────────────────────\n\n// oxlint-disable sort-keys\nexport const permissionPresets = {\n strict: {\n description: \"Ask for everything. No commands or file ops auto-allowed.\",\n rules: {\n deny: HARD_DENIES,\n // Override the tool/file handlers' default allows.\n ask: [\"tool(*)\", \"read(*)\", \"write(*)\"],\n },\n },\n readonly: {\n description:\n \"Auto-allow read-only utilities, git read-only ops, and common build/test commands. \" +\n \"Reads inside the workspace are allowed (sensitive paths denied); writes always ask.\",\n rules: {\n deny: HARD_DENIES,\n allow: [...READONLY_TOOLS, ...READONLY_BASH, ...READONLY_GIT, ...DEV_BASIC],\n ask: [\"tool(*)\", \"write(*)\"],\n },\n },\n permissive: {\n description:\n \"Readonly preset plus broader dev commands (file moves, ad-hoc bun/node evals, \" +\n \"git mutations, network fetches) and writes inside the workspace.\",\n rules: {\n deny: HARD_DENIES,\n allow: [\n \"tool(*)\",\n ...READONLY_BASH,\n ...READONLY_GIT,\n ...DEV_BASIC,\n ...PERMISSIVE_EXTRAS,\n // Allow writes inside any workspace (sensitive paths still denied\n // by the file handler before rule resolution).\n \"write(*)\",\n ],\n },\n },\n yolo: {\n description: \"Allow everything. No prompts. Use only when you trust the model and the task.\",\n rules: {\n allow: [\"bash\", \"read(*)\", \"write(*)\", \"tool(*)\"],\n },\n },\n} as const satisfies Record<PermissionPresetName, PermissionPreset>\n","import type { PermissionPresetName } from \"./presets.ts\"\nimport type { CheckResult, Rule, Verdict } from \"./types.ts\"\n\nimport { normPath } from \"@zaly/shared\"\nimport { handlerRegistry } from \"./handlers/registry.ts\"\nimport { permissionPresets } from \"./presets.ts\"\n\nexport type PermissionOptions = {\n /** Session cwd — anchor for resolving relative paths and the default\n * spawn cwd for bash subprocesses. Pinned at construction; the agent\n * never mutates `process.cwd()`, and there's no `cd` tool. Defaults\n * to `process.cwd()`. */\n cwd?: string\n /** Named preset — supplies a baseline rule set. Explicit `rules` win\n * over preset rules on conflict (first-match-wins resolution; user\n * rules are listed before preset rules at construction). */\n preset?: PermissionPresetName\n rules?: Rule[] | Partial<Record<Verdict, string[] | undefined>>\n /** Initial workspace list. `cwd` is auto-added so the user doesn't\n * have to repeat it. Pass paths absolute (or relative — they'll be\n * resolved against `cwd`). */\n workspaces?: readonly string[]\n}\n\n/**\n * Owns per-session permission state and dispatches `validate(scope, input)`\n * to the registered handler for `scope`. Handlers receive rules\n * pre-filtered to their scope plus the shared workspace list.\n *\n * Mutators (`addWorkspace`, `addRule`, …) are how the prompt UI promotes\n * an `ask` verdict — once the user picks \"allow `Bash(git push:*)` for\n * this session\", the TUI calls `manager.addRule(...)` and subsequent\n * `validate()` calls pick it up via the filter.\n */\nexport class PermissionManager {\n readonly cwd: string\n #rules: Rule[] = []\n #workspaces: string[]\n\n constructor(opts?: PermissionOptions) {\n this.cwd = normPath(opts?.cwd)\n if (opts?.rules) {\n const more = Array.isArray(opts.rules) ? opts.rules : parseRules(opts.rules)\n this.#rules.push(...more)\n }\n if (opts?.preset) this.#rules.push(...parseRules(permissionPresets[opts.preset].rules))\n this.#workspaces = (opts?.workspaces ?? []).map((p) => normPath(this.cwd, p))\n // Auto-include cwd so users don't have to repeat it. Listed first so\n // longest-prefix lookup in handlers stays predictable.\n if (!this.#workspaces.includes(this.cwd)) this.#workspaces.unshift(this.cwd)\n }\n\n // ── Workspaces ──────────────────────────────────────────────────────\n\n get workspaces(): readonly string[] {\n return this.#workspaces\n }\n\n addWorkspace(path: string): void {\n const abs = normPath(this.cwd, path)\n if (!this.#workspaces.includes(abs)) this.#workspaces.push(abs)\n }\n\n removeWorkspace(path: string): void {\n const abs = normPath(this.cwd, path)\n const i = this.#workspaces.indexOf(abs)\n if (i !== -1) this.#workspaces.splice(i, 1)\n }\n\n // ── Rules ───────────────────────────────────────────────────────────\n\n get rules(): readonly Rule[] {\n return this.#rules\n }\n\n /** Rules whose scope has no registered handler — surfaces config\n * errors (typos, unknown scopes, malformed pattern strings). The TUI\n * can render these as a startup warning. */\n get invalidRules(): readonly Rule[] {\n return this.#rules.filter((r) => !handlerRegistry.has(r.scope))\n }\n\n addRule(rule: Rule): void {\n this.#rules.unshift(rule)\n }\n\n // ── Dispatch ────────────────────────────────────────────────────────\n\n validate(scope: string, input: string): CheckResult {\n if (!handlerRegistry.has(scope)) {\n throw new Error(`no permission handler registered for scope \"${scope}\"`)\n }\n const handler = handlerRegistry.load(scope)\n const rules = this.#rules.filter((r) => r.scope === scope)\n return handler.validate(input, {\n cwd: this.cwd,\n rules,\n scope,\n validate: this.validate.bind(this),\n workspaces: this.#workspaces,\n })\n }\n}\n\n/** Parse Claude-Code-style permission config (a verdict-keyed map of\n * pattern strings) into structured `Rule<string>[]`.\n *\n * Pattern shapes accepted:\n * \"Bash(ls:*)\" → { scope: \"bash\", pattern: \"ls:*\" }\n * \"WebSearch\" → { scope: \"websearch\", pattern: \"*\" } // bare name = scope-wide\n *\n * Scopes are normalized to lower-case so config can use either\n * TitleCase (\"Bash\") or lowercase (\"bash\") interchangeably.\n *\n * Malformed entries are pushed verbatim so `manager.invalidRules`\n * surfaces them — typos in the scope (\"Bahs(...)\") are caught the same\n * way (no handler registered → flagged invalid). */\nexport function parseRules(rules: Partial<Record<Verdict, string[] | undefined>>): Rule[] {\n const ret: Rule[] = []\n for (const policy of Object.keys(rules) as Verdict[]) {\n const patterns = rules[policy]\n if (!Array.isArray(patterns)) continue\n for (const raw of patterns) {\n const m = raw.match(/^(\\w+)(?:\\((.+)\\))?$/)\n if (m) {\n const [, scope, pat = \"*\"] = m\n ret.push({ pattern: pat, policy, scope: scope.toLowerCase() })\n } else {\n // Truly malformed — preserve verbatim so invalidRules surfaces it.\n ret.push({ pattern: raw, policy, scope: \"invalid\" })\n }\n }\n }\n return ret\n}\n"],"mappings":";;;;AA2BA,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;AACF;;;;;AAMA,MAAM,gBAAgB;CACpB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;AAKA,MAAM,YAAY;CAChB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,MAAM,cAAc,CAAC,cAAc;;;;AAKnC,MAAM,oBAAoB;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAKA,MAAa,oBAAoB;CAC/B,QAAQ;EACN,aAAa;EACb,OAAO;GACL,MAAM;GAEN,KAAK;IAAC;IAAW;IAAW;GAAU;EACxC;CACF;CACA,UAAU;EACR,aACE;EAEF,OAAO;GACL,MAAM;GACN,OAAO;IAAC,GAAG;IAAgB,GAAG;IAAe,GAAG;IAAc,GAAG;GAAS;GAC1E,KAAK,CAAC,WAAW,UAAU;EAC7B;CACF;CACA,YAAY;EACV,aACE;EAEF,OAAO;GACL,MAAM;GACN,OAAO;IACL;IACA,GAAG;IACH,GAAG;IACH,GAAG;IACH,GAAG;IAGH;GACF;EACF;CACF;CACA,MAAM;EACJ,aAAa;EACb,OAAO,EACL,OAAO;GAAC;GAAQ;GAAW;GAAY;EAAS,EAClD;CACF;AACF;;;;;;;;;;;;;AChKA,IAAa,oBAAb,MAA+B;CAC7B;CACA,SAAiB,CAAC;CAClB;CAEA,YAAY,MAA0B;EACpC,KAAK,MAAM,SAAS,MAAM,GAAG;EAC7B,IAAI,MAAM,OAAO;GACf,MAAM,OAAO,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,WAAW,KAAK,KAAK;GAC3E,KAAKA,OAAO,KAAK,GAAG,IAAI;EAC1B;EACA,IAAI,MAAM,QAAQ,KAAKA,OAAO,KAAK,GAAG,WAAW,kBAAkB,KAAK,OAAO,CAAC,KAAK,CAAC;EACtF,KAAKC,eAAe,MAAM,cAAc,CAAC,EAAA,CAAG,KAAK,MAAM,SAAS,KAAK,KAAK,CAAC,CAAC;EAG5E,IAAI,CAAC,KAAKA,YAAY,SAAS,KAAK,GAAG,GAAG,KAAKA,YAAY,QAAQ,KAAK,GAAG;CAC7E;CAIA,IAAI,aAAgC;EAClC,OAAO,KAAKA;CACd;CAEA,aAAa,MAAoB;EAC/B,MAAM,MAAM,SAAS,KAAK,KAAK,IAAI;EACnC,IAAI,CAAC,KAAKA,YAAY,SAAS,GAAG,GAAG,KAAKA,YAAY,KAAK,GAAG;CAChE;CAEA,gBAAgB,MAAoB;EAClC,MAAM,MAAM,SAAS,KAAK,KAAK,IAAI;EACnC,MAAM,IAAI,KAAKA,YAAY,QAAQ,GAAG;EACtC,IAAI,MAAM,IAAI,KAAKA,YAAY,OAAO,GAAG,CAAC;CAC5C;CAIA,IAAI,QAAyB;EAC3B,OAAO,KAAKD;CACd;;;;CAKA,IAAI,eAAgC;EAClC,OAAO,KAAKA,OAAO,QAAQ,MAAM,CAAC,gBAAgB,IAAI,EAAE,KAAK,CAAC;CAChE;CAEA,QAAQ,MAAkB;EACxB,KAAKA,OAAO,QAAQ,IAAI;CAC1B;CAIA,SAAS,OAAe,OAA4B;EAClD,IAAI,CAAC,gBAAgB,IAAI,KAAK,GAC5B,MAAM,IAAI,MAAM,+CAA+C,MAAM,EAAE;EAEzE,MAAM,UAAU,gBAAgB,KAAK,KAAK;EAC1C,MAAM,QAAQ,KAAKA,OAAO,QAAQ,MAAM,EAAE,UAAU,KAAK;EACzD,OAAO,QAAQ,SAAS,OAAO;GAC7B,KAAK,KAAK;GACV;GACA;GACA,UAAU,KAAK,SAAS,KAAK,IAAI;GACjC,YAAY,KAAKC;EACnB,CAAC;CACH;AACF;;;;;;;;;;;;;;AAeA,SAAgB,WAAW,OAA+D;CACxF,MAAM,MAAc,CAAC;CACrB,KAAK,MAAM,UAAU,OAAO,KAAK,KAAK,GAAgB;EACpD,MAAM,WAAW,MAAM;EACvB,IAAI,CAAC,MAAM,QAAQ,QAAQ,GAAG;EAC9B,KAAK,MAAM,OAAO,UAAU;GAC1B,MAAM,IAAI,IAAI,MAAM,sBAAsB;GAC1C,IAAI,GAAG;IACL,MAAM,GAAG,OAAO,MAAM,OAAO;IAC7B,IAAI,KAAK;KAAE,SAAS;KAAK;KAAQ,OAAO,MAAM,YAAY;IAAE,CAAC;GAC/D,OAEE,IAAI,KAAK;IAAE,SAAS;IAAK;IAAQ,OAAO;GAAU,CAAC;EAEvD;CACF;CACA,OAAO;AACT"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry-CFmR5G3J.mjs","names":["resolveRule"],"sources":["../src/permissions/handlers/bash.ts","../../../node_modules/.bun/ignore@7.0.5/node_modules/ignore/index.js","../src/permissions/handlers/files.ts","../src/permissions/handlers/tool.ts","../src/permissions/handlers/registry.ts"],"sourcesContent":["import type { Segment } from \"../../utils/bash/parser.ts\"\nimport type { CheckResult, PermissionHandler, Rule, Suggestion, Verdict } from \"../types.ts\"\n\nimport { parseBash } from \"../../utils/bash/parser.ts\"\nimport { TOOLS } from \"../../utils/bash/tools.ts\"\n\n/**\n * Handler for `Rule<\"bash\">` — evaluates a bash command line against\n * pattern rules, then delegates each segment's inferred and explicit\n * file paths to the file handler via `ctx.validate(\"read\"|\"write\", …)`.\n *\n * Composition keeps file-rule logic in one place: the bash handler\n * doesn't know about workspaces, sensitive files, or path-pattern\n * matching — it just asks the registered handler for those scopes.\n *\n * Sources of file paths per segment:\n * - `seg.reads` / `seg.writes` — explicit `<` / `>` / `>>` redirects\n * extracted by the parser.\n * - `TOOLS[cmd].reads/writes(args)` — inferred from built-in tool\n * specs (e.g. `cat foo.txt` reads `foo.txt`, `tee out` writes `out`).\n *\n * Suggestions and reasons from inner `validate` calls bubble up so the\n * prompt UI can offer \"allow `Bash(cat:*)`\" alongside \"add ~/Documents\n * as workspace\" in a single ask.\n */\nexport const bashHandler: PermissionHandler<\"bash\"> = {\n validate(input, ctx): CheckResult {\n const parsed = parseBash(input)\n if (!parsed.ok) {\n return {\n ask: `Allow this bash command? (${parsed.reason})`,\n reason: parsed.reason,\n verdict: \"ask\",\n }\n }\n\n let verdict: Verdict = \"allow\"\n let reason: string | undefined\n const suggestions: Suggestion[] = []\n\n for (const seg of parsed.segments) {\n // Bash rule match for the command itself. Resolve this before the\n // conservative safety checks so explicit allow-all presets like yolo can\n // mean exactly that instead of degrading to an unimplemented ask prompt.\n const cmdVerdict = resolveRules(ctx.rules, seg) ?? \"ask\"\n if (seg.hasCommandSubst && cmdVerdict !== \"allow\") {\n return {\n ask: `Allow command substitution in \\`${seg.cmd}\\`?`,\n reason: \"command substitution not allowed\",\n verdict: \"ask\",\n }\n }\n const spec = TOOLS[seg.cmd]\n if (spec?.unsafe?.(seg.args) && cmdVerdict !== \"allow\") {\n return {\n ask: `Allow invocation of \\`${seg.cmd}\\`? (unsafe)`,\n reason: `${seg.cmd}: invocation mode not safely modelled`,\n verdict: \"ask\",\n }\n }\n\n let segVerdict: Verdict = cmdVerdict\n let segReason: string | undefined =\n cmdVerdict === \"allow\" ? undefined : `segment \"${seg.cmd}\" → ${cmdVerdict}`\n if (cmdVerdict === \"ask\") {\n suggestions.push({\n kind: \"rule\",\n pattern: seg.args.length > 0 ? `${seg.cmd}:*` : seg.cmd,\n scope: \"bash\",\n })\n }\n\n // Delegate file paths to the file handler. Reads first, then\n // writes; both contribute to this segment's verdict via combine.\n const reads = [...(spec?.reads?.(seg.args) ?? []), ...seg.reads]\n const writes = [...(spec?.writes?.(seg.args) ?? []), ...seg.writes.map((w) => w.path)]\n\n for (const path of reads) {\n if (seg.dyn?.has(path)) {\n segVerdict = combine(segVerdict, \"ask\")\n segReason ??= `${seg.cmd}: read ${path}: dynamic path`\n suggestions.push({\n kind: \"rule\",\n pattern: `${seg.cmd}:*`,\n scope: \"bash\",\n })\n continue\n }\n const r = ctx.validate(\"read\", path)\n segVerdict = combine(segVerdict, r.verdict)\n if (r.verdict !== \"allow\") {\n segReason ??= `${seg.cmd}: read ${path}: ${r.reason}`\n if (r.suggestions) suggestions.push(...r.suggestions)\n }\n if (segVerdict === \"deny\") break\n }\n if (segVerdict !== \"deny\") {\n for (const path of writes) {\n if (seg.dyn?.has(path)) {\n segVerdict = combine(segVerdict, \"ask\")\n segReason ??= `${seg.cmd}: write ${path}: dynamic path`\n suggestions.push({\n kind: \"rule\",\n pattern: `${seg.cmd}:*`,\n scope: \"bash\",\n })\n continue\n }\n const w = ctx.validate(\"write\", path)\n segVerdict = combine(segVerdict, w.verdict)\n if (w.verdict !== \"allow\") {\n segReason ??= `${seg.cmd}: write ${path}: ${w.reason}`\n if (w.suggestions) suggestions.push(...w.suggestions)\n }\n if (segVerdict === \"deny\") break\n }\n }\n\n verdict = combine(verdict, segVerdict)\n if (verdict !== \"allow\" && reason === undefined) reason = segReason\n if (verdict === \"deny\") break\n }\n\n return verdict === \"allow\"\n ? { verdict: \"allow\" }\n : {\n ask: `Allow this bash command?`,\n reason: reason ?? \"no rule matched\",\n suggestions: suggestions.length > 0 ? suggestions : undefined,\n verdict,\n }\n },\n}\n\n// ── Pattern matching ─────────────────────────────────────────────────────\n\n/** A command-pattern rule.\n *\n * Pattern syntax:\n * \"cmd\" → cmd alone, no args\n * \"cmd:*\" → cmd with any args (trailing wildcard)\n * \"cmd a\" → cmd with arg \"a\", no other args\n * \"cmd a:*\" → cmd with arg \"a\" plus any others\n * \"cmd a b\" → cmd with exact args [a, b]\n * \"cmd --flag*\" → cmd with arg starting with \"--flag\" (per-arg prefix)\n * \"bun test:node:*\" → cmd \"bun\", arg \"test:node\", any others\n *\n * Whitespace separates the cmd from its args, and args from each\n * other. The `:` character is only meaningful as the trailing `:*`\n * wildcard suffix — anywhere else (including inside an arg like\n * `test:node`) it's a literal character. */\n\ninterface ParsedPattern {\n cmd: string\n /** Arg-position match tokens. Each may end with `*` for prefix match. */\n parts: string[]\n /** Set when the pattern ends with `:*`, allowing arbitrary further args. */\n trailingWildcard: boolean\n}\n\n/** Combine two verdicts: deny dominates, ask beats allow. */\nfunction combine(a: Verdict, b: Verdict): Verdict {\n if (a === \"deny\" || b === \"deny\") return \"deny\"\n if (a === \"ask\" || b === \"ask\") return \"ask\"\n return \"allow\"\n}\n\nconst patternCache = new Map<string, ParsedPattern>()\n\nfunction parsePattern(pattern: string): ParsedPattern {\n const cached = patternCache.get(pattern)\n if (cached) return cached\n\n let body = pattern.trim()\n let trailingWildcard = false\n if (body.endsWith(\":*\")) {\n trailingWildcard = true\n body = body.slice(0, -2)\n }\n\n const tokens = body.split(/\\s+/).filter((s) => s.length > 0)\n const cmd = tokens[0] ?? \"\"\n const result: ParsedPattern = {\n cmd,\n parts: tokens.slice(1),\n trailingWildcard,\n }\n patternCache.set(pattern, result)\n return result\n}\n\nfunction matchPart(part: string, value: string): boolean {\n if (part.endsWith(\"*\")) {\n return value.startsWith(part.slice(0, -1))\n }\n return part === value\n}\n\n/** Test whether a parsed segment matches a rule pattern. */\nexport function matchRule(rule: Rule, seg: Segment): boolean {\n const p = parsePattern(rule.pattern)\n // Bare `*` (e.g. from a `Bash` rule with no parens) matches any command.\n if (p.cmd === \"*\" && p.parts.length === 0) return true\n if (p.cmd !== seg.cmd) return false\n if (seg.args.length < p.parts.length) return false\n for (let i = 0; i < p.parts.length; i++) {\n if (!matchPart(p.parts[i], seg.args[i])) return false\n }\n if (p.trailingWildcard) return true\n return seg.args.length === p.parts.length\n}\n\n/** First-match-wins resolution. Returns `undefined` if no rule matches. */\nfunction resolveRules(rules: readonly Rule[], seg: Segment): Verdict | undefined {\n for (const r of rules) {\n if (matchRule(r, seg)) return r.policy\n }\n return undefined\n}\n","// A simple implementation of make-array\nfunction makeArray (subject) {\n return Array.isArray(subject)\n ? subject\n : [subject]\n}\n\nconst UNDEFINED = undefined\nconst EMPTY = ''\nconst SPACE = ' '\nconst ESCAPE = '\\\\'\nconst REGEX_TEST_BLANK_LINE = /^\\s+$/\nconst REGEX_INVALID_TRAILING_BACKSLASH = /(?:[^\\\\]|^)\\\\$/\nconst REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\\\!/\nconst REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\\\#/\nconst REGEX_SPLITALL_CRLF = /\\r?\\n/g\n\n// Invalid:\n// - /foo,\n// - ./foo,\n// - ../foo,\n// - .\n// - ..\n// Valid:\n// - .foo\nconst REGEX_TEST_INVALID_PATH = /^\\.{0,2}\\/|^\\.{1,2}$/\n\nconst REGEX_TEST_TRAILING_SLASH = /\\/$/\n\nconst SLASH = '/'\n\n// Do not use ternary expression here, since \"istanbul ignore next\" is buggy\nlet TMP_KEY_IGNORE = 'node-ignore'\n/* istanbul ignore else */\nif (typeof Symbol !== 'undefined') {\n TMP_KEY_IGNORE = Symbol.for('node-ignore')\n}\nconst KEY_IGNORE = TMP_KEY_IGNORE\n\nconst define = (object, key, value) => {\n Object.defineProperty(object, key, {value})\n return value\n}\n\nconst REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g\n\nconst RETURN_FALSE = () => false\n\n// Sanitize the range of a regular expression\n// The cases are complicated, see test cases for details\nconst sanitizeRange = range => range.replace(\n REGEX_REGEXP_RANGE,\n (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0)\n ? match\n // Invalid range (out of order) which is ok for gitignore rules but\n // fatal for JavaScript regular expression, so eliminate it.\n : EMPTY\n)\n\n// See fixtures #59\nconst cleanRangeBackSlash = slashes => {\n const {length} = slashes\n return slashes.slice(0, length - length % 2)\n}\n\n// > If the pattern ends with a slash,\n// > it is removed for the purpose of the following description,\n// > but it would only find a match with a directory.\n// > In other words, foo/ will match a directory foo and paths underneath it,\n// > but will not match a regular file or a symbolic link foo\n// > (this is consistent with the way how pathspec works in general in Git).\n// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`'\n// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call\n// you could use option `mark: true` with `glob`\n\n// '`foo/`' should not continue with the '`..`'\nconst REPLACERS = [\n\n [\n // Remove BOM\n // TODO:\n // Other similar zero-width characters?\n /^\\uFEFF/,\n () => EMPTY\n ],\n\n // > Trailing spaces are ignored unless they are quoted with backslash (\"\\\")\n [\n // (a\\ ) -> (a )\n // (a ) -> (a)\n // (a ) -> (a)\n // (a \\ ) -> (a )\n /((?:\\\\\\\\)*?)(\\\\?\\s+)$/,\n (_, m1, m2) => m1 + (\n m2.indexOf('\\\\') === 0\n ? SPACE\n : EMPTY\n )\n ],\n\n // Replace (\\ ) with ' '\n // (\\ ) -> ' '\n // (\\\\ ) -> '\\\\ '\n // (\\\\\\ ) -> '\\\\ '\n [\n /(\\\\+?)\\s/g,\n (_, m1) => {\n const {length} = m1\n return m1.slice(0, length - length % 2) + SPACE\n }\n ],\n\n // Escape metacharacters\n // which is written down by users but means special for regular expressions.\n\n // > There are 12 characters with special meanings:\n // > - the backslash \\,\n // > - the caret ^,\n // > - the dollar sign $,\n // > - the period or dot .,\n // > - the vertical bar or pipe symbol |,\n // > - the question mark ?,\n // > - the asterisk or star *,\n // > - the plus sign +,\n // > - the opening parenthesis (,\n // > - the closing parenthesis ),\n // > - and the opening square bracket [,\n // > - the opening curly brace {,\n // > These special characters are often called \"metacharacters\".\n [\n /[\\\\$.|*+(){^]/g,\n match => `\\\\${match}`\n ],\n\n [\n // > a question mark (?) matches a single character\n /(?!\\\\)\\?/g,\n () => '[^/]'\n ],\n\n // leading slash\n [\n\n // > A leading slash matches the beginning of the pathname.\n // > For example, \"/*.c\" matches \"cat-file.c\" but not \"mozilla-sha1/sha1.c\".\n // A leading slash matches the beginning of the pathname\n /^\\//,\n () => '^'\n ],\n\n // replace special metacharacter slash after the leading slash\n [\n /\\//g,\n () => '\\\\/'\n ],\n\n [\n // > A leading \"**\" followed by a slash means match in all directories.\n // > For example, \"**/foo\" matches file or directory \"foo\" anywhere,\n // > the same as pattern \"foo\".\n // > \"**/foo/bar\" matches file or directory \"bar\" anywhere that is directly\n // > under directory \"foo\".\n // Notice that the '*'s have been replaced as '\\\\*'\n /^\\^*\\\\\\*\\\\\\*\\\\\\//,\n\n // '**/foo' <-> 'foo'\n () => '^(?:.*\\\\/)?'\n ],\n\n // starting\n [\n // there will be no leading '/'\n // (which has been replaced by section \"leading slash\")\n // If starts with '**', adding a '^' to the regular expression also works\n /^(?=[^^])/,\n function startingReplacer () {\n // If has a slash `/` at the beginning or middle\n return !/\\/(?!$)/.test(this)\n // > Prior to 2.22.1\n // > If the pattern does not contain a slash /,\n // > Git treats it as a shell glob pattern\n // Actually, if there is only a trailing slash,\n // git also treats it as a shell glob pattern\n\n // After 2.22.1 (compatible but clearer)\n // > If there is a separator at the beginning or middle (or both)\n // > of the pattern, then the pattern is relative to the directory\n // > level of the particular .gitignore file itself.\n // > Otherwise the pattern may also match at any level below\n // > the .gitignore level.\n ? '(?:^|\\\\/)'\n\n // > Otherwise, Git treats the pattern as a shell glob suitable for\n // > consumption by fnmatch(3)\n : '^'\n }\n ],\n\n // two globstars\n [\n // Use lookahead assertions so that we could match more than one `'/**'`\n /\\\\\\/\\\\\\*\\\\\\*(?=\\\\\\/|$)/g,\n\n // Zero, one or several directories\n // should not use '*', or it will be replaced by the next replacer\n\n // Check if it is not the last `'/**'`\n (_, index, str) => index + 6 < str.length\n\n // case: /**/\n // > A slash followed by two consecutive asterisks then a slash matches\n // > zero or more directories.\n // > For example, \"a/**/b\" matches \"a/b\", \"a/x/b\", \"a/x/y/b\" and so on.\n // '/**/'\n ? '(?:\\\\/[^\\\\/]+)*'\n\n // case: /**\n // > A trailing `\"/**\"` matches everything inside.\n\n // #21: everything inside but it should not include the current folder\n : '\\\\/.+'\n ],\n\n // normal intermediate wildcards\n [\n // Never replace escaped '*'\n // ignore rule '\\*' will match the path '*'\n\n // 'abc.*/' -> go\n // 'abc.*' -> skip this rule,\n // coz trailing single wildcard will be handed by [trailing wildcard]\n /(^|[^\\\\]+)(\\\\\\*)+(?=.+)/g,\n\n // '*.js' matches '.js'\n // '*.js' doesn't match 'abc'\n (_, p1, p2) => {\n // 1.\n // > An asterisk \"*\" matches anything except a slash.\n // 2.\n // > Other consecutive asterisks are considered regular asterisks\n // > and will match according to the previous rules.\n const unescaped = p2.replace(/\\\\\\*/g, '[^\\\\/]*')\n return p1 + unescaped\n }\n ],\n\n [\n // unescape, revert step 3 except for back slash\n // For example, if a user escape a '\\\\*',\n // after step 3, the result will be '\\\\\\\\\\\\*'\n /\\\\\\\\\\\\(?=[$.|*+(){^])/g,\n () => ESCAPE\n ],\n\n [\n // '\\\\\\\\' -> '\\\\'\n /\\\\\\\\/g,\n () => ESCAPE\n ],\n\n [\n // > The range notation, e.g. [a-zA-Z],\n // > can be used to match one of the characters in a range.\n\n // `\\` is escaped by step 3\n /(\\\\)?\\[([^\\]/]*?)(\\\\*)($|\\])/g,\n (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE\n // '\\\\[bar]' -> '\\\\\\\\[bar\\\\]'\n ? `\\\\[${range}${cleanRangeBackSlash(endEscape)}${close}`\n : close === ']'\n ? endEscape.length % 2 === 0\n // A normal case, and it is a range notation\n // '[bar]'\n // '[bar\\\\\\\\]'\n ? `[${sanitizeRange(range)}${endEscape}]`\n // Invalid range notaton\n // '[bar\\\\]' -> '[bar\\\\\\\\]'\n : '[]'\n : '[]'\n ],\n\n // ending\n [\n // 'js' will not match 'js.'\n // 'ab' will not match 'abc'\n /(?:[^*])$/,\n\n // WTF!\n // https://git-scm.com/docs/gitignore\n // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1)\n // which re-fixes #24, #38\n\n // > If there is a separator at the end of the pattern then the pattern\n // > will only match directories, otherwise the pattern can match both\n // > files and directories.\n\n // 'js*' will not match 'a.js'\n // 'js/' will not match 'a.js'\n // 'js' will match 'a.js' and 'a.js/'\n match => /\\/$/.test(match)\n // foo/ will not match 'foo'\n ? `${match}$`\n // foo matches 'foo' and 'foo/'\n : `${match}(?=$|\\\\/$)`\n ]\n]\n\nconst REGEX_REPLACE_TRAILING_WILDCARD = /(^|\\\\\\/)?\\\\\\*$/\nconst MODE_IGNORE = 'regex'\nconst MODE_CHECK_IGNORE = 'checkRegex'\nconst UNDERSCORE = '_'\n\nconst TRAILING_WILD_CARD_REPLACERS = {\n [MODE_IGNORE] (_, p1) {\n const prefix = p1\n // '\\^':\n // '/*' does not match EMPTY\n // '/*' does not match everything\n\n // '\\\\\\/':\n // 'abc/*' does not match 'abc/'\n ? `${p1}[^/]+`\n\n // 'a*' matches 'a'\n // 'a*' matches 'aa'\n : '[^/]*'\n\n return `${prefix}(?=$|\\\\/$)`\n },\n\n [MODE_CHECK_IGNORE] (_, p1) {\n // When doing `git check-ignore`\n const prefix = p1\n // '\\\\\\/':\n // 'abc/*' DOES match 'abc/' !\n ? `${p1}[^/]*`\n\n // 'a*' matches 'a'\n // 'a*' matches 'aa'\n : '[^/]*'\n\n return `${prefix}(?=$|\\\\/$)`\n }\n}\n\n// @param {pattern}\nconst makeRegexPrefix = pattern => REPLACERS.reduce(\n (prev, [matcher, replacer]) =>\n prev.replace(matcher, replacer.bind(pattern)),\n pattern\n)\n\nconst isString = subject => typeof subject === 'string'\n\n// > A blank line matches no files, so it can serve as a separator for readability.\nconst checkPattern = pattern => pattern\n && isString(pattern)\n && !REGEX_TEST_BLANK_LINE.test(pattern)\n && !REGEX_INVALID_TRAILING_BACKSLASH.test(pattern)\n\n // > A line starting with # serves as a comment.\n && pattern.indexOf('#') !== 0\n\nconst splitPattern = pattern => pattern\n.split(REGEX_SPLITALL_CRLF)\n.filter(Boolean)\n\nclass IgnoreRule {\n constructor (\n pattern,\n mark,\n body,\n ignoreCase,\n negative,\n prefix\n ) {\n this.pattern = pattern\n this.mark = mark\n this.negative = negative\n\n define(this, 'body', body)\n define(this, 'ignoreCase', ignoreCase)\n define(this, 'regexPrefix', prefix)\n }\n\n get regex () {\n const key = UNDERSCORE + MODE_IGNORE\n\n if (this[key]) {\n return this[key]\n }\n\n return this._make(MODE_IGNORE, key)\n }\n\n get checkRegex () {\n const key = UNDERSCORE + MODE_CHECK_IGNORE\n\n if (this[key]) {\n return this[key]\n }\n\n return this._make(MODE_CHECK_IGNORE, key)\n }\n\n _make (mode, key) {\n const str = this.regexPrefix.replace(\n REGEX_REPLACE_TRAILING_WILDCARD,\n\n // It does not need to bind pattern\n TRAILING_WILD_CARD_REPLACERS[mode]\n )\n\n const regex = this.ignoreCase\n ? new RegExp(str, 'i')\n : new RegExp(str)\n\n return define(this, key, regex)\n }\n}\n\nconst createRule = ({\n pattern,\n mark\n}, ignoreCase) => {\n let negative = false\n let body = pattern\n\n // > An optional prefix \"!\" which negates the pattern;\n if (body.indexOf('!') === 0) {\n negative = true\n body = body.substr(1)\n }\n\n body = body\n // > Put a backslash (\"\\\") in front of the first \"!\" for patterns that\n // > begin with a literal \"!\", for example, `\"\\!important!.txt\"`.\n .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!')\n // > Put a backslash (\"\\\") in front of the first hash for patterns that\n // > begin with a hash.\n .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#')\n\n const regexPrefix = makeRegexPrefix(body)\n\n return new IgnoreRule(\n pattern,\n mark,\n body,\n ignoreCase,\n negative,\n regexPrefix\n )\n}\n\nclass RuleManager {\n constructor (ignoreCase) {\n this._ignoreCase = ignoreCase\n this._rules = []\n }\n\n _add (pattern) {\n // #32\n if (pattern && pattern[KEY_IGNORE]) {\n this._rules = this._rules.concat(pattern._rules._rules)\n this._added = true\n return\n }\n\n if (isString(pattern)) {\n pattern = {\n pattern\n }\n }\n\n if (checkPattern(pattern.pattern)) {\n const rule = createRule(pattern, this._ignoreCase)\n this._added = true\n this._rules.push(rule)\n }\n }\n\n // @param {Array<string> | string | Ignore} pattern\n add (pattern) {\n this._added = false\n\n makeArray(\n isString(pattern)\n ? splitPattern(pattern)\n : pattern\n ).forEach(this._add, this)\n\n return this._added\n }\n\n // Test one single path without recursively checking parent directories\n //\n // - checkUnignored `boolean` whether should check if the path is unignored,\n // setting `checkUnignored` to `false` could reduce additional\n // path matching.\n // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`\n\n // @returns {TestResult} true if a file is ignored\n test (path, checkUnignored, mode) {\n let ignored = false\n let unignored = false\n let matchedRule\n\n this._rules.forEach(rule => {\n const {negative} = rule\n\n // | ignored : unignored\n // -------- | ---------------------------------------\n // negative | 0:0 | 0:1 | 1:0 | 1:1\n // -------- | ------- | ------- | ------- | --------\n // 0 | TEST | TEST | SKIP | X\n // 1 | TESTIF | SKIP | TEST | X\n\n // - SKIP: always skip\n // - TEST: always test\n // - TESTIF: only test if checkUnignored\n // - X: that never happen\n if (\n unignored === negative && ignored !== unignored\n || negative && !ignored && !unignored && !checkUnignored\n ) {\n return\n }\n\n const matched = rule[mode].test(path)\n\n if (!matched) {\n return\n }\n\n ignored = !negative\n unignored = negative\n\n matchedRule = negative\n ? UNDEFINED\n : rule\n })\n\n const ret = {\n ignored,\n unignored\n }\n\n if (matchedRule) {\n ret.rule = matchedRule\n }\n\n return ret\n }\n}\n\nconst throwError = (message, Ctor) => {\n throw new Ctor(message)\n}\n\nconst checkPath = (path, originalPath, doThrow) => {\n if (!isString(path)) {\n return doThrow(\n `path must be a string, but got \\`${originalPath}\\``,\n TypeError\n )\n }\n\n // We don't know if we should ignore EMPTY, so throw\n if (!path) {\n return doThrow(`path must not be empty`, TypeError)\n }\n\n // Check if it is a relative path\n if (checkPath.isNotRelative(path)) {\n const r = '`path.relative()`d'\n return doThrow(\n `path should be a ${r} string, but got \"${originalPath}\"`,\n RangeError\n )\n }\n\n return true\n}\n\nconst isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path)\n\ncheckPath.isNotRelative = isNotRelative\n\n// On windows, the following function will be replaced\n/* istanbul ignore next */\ncheckPath.convert = p => p\n\n\nclass Ignore {\n constructor ({\n ignorecase = true,\n ignoreCase = ignorecase,\n allowRelativePaths = false\n } = {}) {\n define(this, KEY_IGNORE, true)\n\n this._rules = new RuleManager(ignoreCase)\n this._strictPathCheck = !allowRelativePaths\n this._initCache()\n }\n\n _initCache () {\n // A cache for the result of `.ignores()`\n this._ignoreCache = Object.create(null)\n\n // A cache for the result of `.test()`\n this._testCache = Object.create(null)\n }\n\n add (pattern) {\n if (this._rules.add(pattern)) {\n // Some rules have just added to the ignore,\n // making the behavior changed,\n // so we need to re-initialize the result cache\n this._initCache()\n }\n\n return this\n }\n\n // legacy\n addPattern (pattern) {\n return this.add(pattern)\n }\n\n // @returns {TestResult}\n _test (originalPath, cache, checkUnignored, slices) {\n const path = originalPath\n // Supports nullable path\n && checkPath.convert(originalPath)\n\n checkPath(\n path,\n originalPath,\n this._strictPathCheck\n ? throwError\n : RETURN_FALSE\n )\n\n return this._t(path, cache, checkUnignored, slices)\n }\n\n checkIgnore (path) {\n // If the path doest not end with a slash, `.ignores()` is much equivalent\n // to `git check-ignore`\n if (!REGEX_TEST_TRAILING_SLASH.test(path)) {\n return this.test(path)\n }\n\n const slices = path.split(SLASH).filter(Boolean)\n slices.pop()\n\n if (slices.length) {\n const parent = this._t(\n slices.join(SLASH) + SLASH,\n this._testCache,\n true,\n slices\n )\n\n if (parent.ignored) {\n return parent\n }\n }\n\n return this._rules.test(path, false, MODE_CHECK_IGNORE)\n }\n\n _t (\n // The path to be tested\n path,\n\n // The cache for the result of a certain checking\n cache,\n\n // Whether should check if the path is unignored\n checkUnignored,\n\n // The path slices\n slices\n ) {\n if (path in cache) {\n return cache[path]\n }\n\n if (!slices) {\n // path/to/a.js\n // ['path', 'to', 'a.js']\n slices = path.split(SLASH).filter(Boolean)\n }\n\n slices.pop()\n\n // If the path has no parent directory, just test it\n if (!slices.length) {\n return cache[path] = this._rules.test(path, checkUnignored, MODE_IGNORE)\n }\n\n const parent = this._t(\n slices.join(SLASH) + SLASH,\n cache,\n checkUnignored,\n slices\n )\n\n // If the path contains a parent directory, check the parent first\n return cache[path] = parent.ignored\n // > It is not possible to re-include a file if a parent directory of\n // > that file is excluded.\n ? parent\n : this._rules.test(path, checkUnignored, MODE_IGNORE)\n }\n\n ignores (path) {\n return this._test(path, this._ignoreCache, false).ignored\n }\n\n createFilter () {\n return path => !this.ignores(path)\n }\n\n filter (paths) {\n return makeArray(paths).filter(this.createFilter())\n }\n\n // @returns {TestResult}\n test (path) {\n return this._test(path, this._testCache, true)\n }\n}\n\nconst factory = options => new Ignore(options)\n\nconst isPathValid = path =>\n checkPath(path && checkPath.convert(path), path, RETURN_FALSE)\n\n/* istanbul ignore next */\nconst setupWindows = () => {\n /* eslint no-control-regex: \"off\" */\n const makePosix = str => /^\\\\\\\\\\?\\\\/.test(str)\n || /[\"<>|\\u0000-\\u001F]+/u.test(str)\n ? str\n : str.replace(/\\\\/g, '/')\n\n checkPath.convert = makePosix\n\n // 'C:\\\\foo' <- 'C:\\\\foo' has been converted to 'C:/'\n // 'd:\\\\foo'\n const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\\//i\n checkPath.isNotRelative = path =>\n REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path)\n || isNotRelative(path)\n}\n\n\n// Windows\n// --------------------------------------------------------------\n/* istanbul ignore next */\nif (\n // Detect `process` so that it can run in browsers.\n typeof process !== 'undefined'\n && process.platform === 'win32'\n) {\n setupWindows()\n}\n\n// COMMONJS_EXPORTS ////////////////////////////////////////////////////////////\n\nmodule.exports = factory\n\n// Although it is an anti-pattern,\n// it is still widely misused by a lot of libraries in github\n// Ref: https://github.com/search?q=ignore.default%28%29&type=code\nfactory.default = factory\n\nmodule.exports.isPathValid = isPathValid\n\n// For testing purposes\ndefine(module.exports, Symbol.for('setupWindows'), setupWindows)\n","import type { CheckResult, PermissionHandler, Rule } from \"../types.ts\"\n\nimport { normPath, prettyPath } from \"@zaly/shared\"\nimport ignore from \"ignore\"\nimport { dirname, isAbsolute, relative } from \"pathe\"\n\n/**\n * Handler for `Rule<\"read\" | \"write\">` — one impl serves both scopes\n * because they share the same matcher and the same workspace state.\n *\n * Algorithm:\n * 1. Normalize candidate to an absolute path.\n * 2. Sensitive-file check (env, ssh keys, credentials) → deny.\n * 3. Find the longest-prefix workspace containing the path. None →\n * ask, with a `kind: \"workspace\"` suggestion for the containing\n * directory.\n * 4. Inside a workspace: resolve the first matching rule against the\n * workspace-relative path. Earlier rules win.\n * 5. Default when no rule matches but the path is inside a workspace:\n * `allow` for reads (workspace = trust signal), `ask` for writes\n * (mutating ops escalate by default; users add `Write(...)` rules\n * to whitelist).\n *\n * Pattern grammar (per Claude-Code conventions):\n * //abs/path absolute filesystem path\n * ~/path path under home directory\n * /path or path workspace-relative (passed through to gitignore)\n */\nexport const fileHandler: PermissionHandler<\"read\" | \"write\"> = {\n validate(input, ctx): CheckResult {\n const abs = normPath(ctx.cwd, input)\n\n if (isSensitiveFile(abs)) {\n return { reason: `${abs}: sensitive file`, verdict: \"deny\" }\n }\n\n const ws = longestWorkspace(abs, ctx.workspaces)\n const inWorkspace = ws !== undefined\n\n // Inside-workspace + path === root: the workspace itself (e.g. `find .`\n // resolved to cwd). Workspace containment alone is enough to allow.\n if (inWorkspace && abs === ws) return { verdict: \"allow\" }\n\n // Outside any workspace, fall through to rule matching with `/` as\n // synthetic root. Lets blanket rules like `read(*)` (yolo preset)\n // override the default \"ask outside workspace\" verdict, while\n // narrower presets keep the safer default.\n const base = ws ?? \"/\"\n const rel = relative(base, abs)\n\n const verb = ctx.scope === \"read\" ? \"reading\" : \"writing\"\n\n const rule = resolveRule(base, rel, ctx.rules)\n if (rule?.policy === \"deny\") return { reason: `${abs}: denied by rule`, verdict: \"deny\" }\n if (rule?.policy === \"ask\") {\n return {\n ask: `Allow ${verb} ${prettyPath(abs)}?`,\n reason: `${abs}: rule requires confirmation`,\n suggestions: [{ kind: \"rule\", pattern: `/${rel}`, scope: ctx.scope }],\n verdict: \"ask\",\n }\n }\n if (rule?.policy === \"allow\") return { verdict: \"allow\" }\n\n // No rule matched. Defaults differ by location:\n // - Inside a workspace: reads ride on workspace trust → allow;\n // writes escalate → ask.\n // - Outside any workspace: always ask, and surface a\n // workspace-add suggestion so the user can promote the parent\n // dir without composing a rule by hand.\n if (!inWorkspace) {\n const parent = dirname(abs)\n return {\n ask: `Allow ${verb} ${prettyPath(abs)}? (not in any workspace)`,\n reason: `${abs}: outside any workspace`,\n suggestions: [\n { description: `add ${parent} as workspace`, kind: \"workspace\", path: parent },\n ],\n verdict: \"ask\",\n }\n }\n if (ctx.scope === \"read\") return { verdict: \"allow\" }\n return {\n ask: `Allow ${verb} ${prettyPath(abs)}?`,\n reason: `${abs}: write requires confirmation`,\n suggestions: [{ kind: \"rule\", pattern: `/${rel}`, scope: \"write\" }],\n verdict: \"ask\",\n }\n },\n}\n\n/** True if `path` looks like a credentials/keys file we shouldn't\n * expose to the model by default. Conservative — false positives are\n * fine here, and users can override via `allow` rules. */\nexport function isSensitiveFile(path: string): boolean {\n return SENSITIVE_PATTERNS.some((re) => re.test(path))\n}\n\n/** Common locations for credentials, keys, and other sensitive data.\n * Matched against the path string directly — covers both absolute and\n * relative inputs. Add to this list as new gotchas surface. */\nconst SENSITIVE_PATTERNS: RegExp[] = [\n /(?:^|\\/)\\.env(?:\\.|$)/, // .env, .env.local, .env.production, ...\n /(?:^|\\/)\\.git\\/(?!hooks\\/)/, // .git/* but not hooks (commonly inspected)\n /(?:^|\\/)\\.ssh\\//, // ssh keys + config\n /(?:^|\\/)\\.aws\\/credentials/,\n /(?:^|\\/)\\.netrc$/,\n /(?:^|\\/)id_(?:rsa|dsa|ed25519|ecdsa)(?:\\.pub)?$/,\n /(?:^|\\/)\\.npmrc$/, // can hold auth tokens\n /(?:^|\\/)\\.pypirc$/,\n /(?:^|\\/)secrets?\\//,\n /(?:^|\\/)credentials?(?:\\.|\\/)/,\n]\n\n/** Longest-prefix match against the workspace list — returns the\n * containing workspace's absolute path, or undefined if none contain\n * the candidate. Workspaces arrive pre-normalized from the manager. */\nfunction longestWorkspace(abs: string, workspaces: readonly string[]): string | undefined {\n let best: string | undefined\n for (const root of workspaces) {\n if (abs === root || abs.startsWith(root.endsWith(\"/\") ? root : `${root}/`)) {\n if (best === undefined || root.length > best.length) best = root\n }\n }\n return best\n}\n\n/** Resolve the first matching rule.\n * Patterns get normalized (`//abs`, `~/`, `/rel`, `rel`) into\n * workspace-rooted gitignore syntax; patterns that resolve outside the\n * candidate's workspace are dropped (they don't apply here). */\nfunction resolveRule(\n workspace: string,\n rel: string,\n rules: readonly Rule<\"read\" | \"write\">[]\n): Rule<\"read\" | \"write\"> | undefined {\n if (rel === \"\") return undefined\n for (const rule of rules) {\n const norm = normalizePattern(rule.pattern, workspace)\n if (norm === undefined) continue\n try {\n if (ignore().add(norm).ignores(rel)) return rule\n } catch {\n // Skip invalid rels.\n }\n }\n}\n\nfunction normalizePattern(pattern: string, workspace: string): string | undefined {\n if (pattern.startsWith(\"//\")) {\n return relativizeToWorkspace(pattern.slice(1), workspace)\n }\n if (pattern.startsWith(\"~/\")) {\n return relativizeToWorkspace(normPath(pattern), workspace)\n }\n // /pattern or pattern → already workspace-relative gitignore syntax.\n return pattern\n}\n\nfunction relativizeToWorkspace(absPattern: string, workspace: string): string | undefined {\n const rel = relative(workspace, absPattern)\n if (rel === \"\" || rel.startsWith(\"..\") || isAbsolute(rel)) return undefined\n return `/${rel}`\n}\n","import type { CheckResult, PermissionHandler, Rule } from \"../types.ts\"\n\nimport ignore from \"ignore\"\n\n/**\n * Generic tool-scope handler.\n *\n * Used by `Tasks` to gate every tool dispatch on the tool name, and\n * available to tools themselves for richer checks (e.g. fetch passing\n * `fetch:example.com` so users can ask-for-domain).\n *\n * Pattern grammar is gitignore-style — reuses the `ignore` package so\n * the syntax matches `read` / `write` patterns. Common shapes:\n *\n * \"tool\" → bare scope; matches every input (default-allow)\n * \"tool(bash)\" → exact match for `\"bash\"`\n * \"tool(fetch:*)\" → glob match `\"fetch:...\"`\n * \"tool(task_*)\" → glob match `\"task_...\"`\n *\n * Resolution is first-match-wins. Default verdict when no rule matches is\n * `allow` — an unconfigured `tool` scope should not surprise users by\n * gating ordinary tool calls.\n */\nexport const toolHandler: PermissionHandler<\"tool\"> = {\n validate(input, ctx): CheckResult {\n const rule = resolveRule(input, ctx.rules)\n if (rule?.policy === \"deny\") {\n return { reason: `tool ${input}: denied by rule`, verdict: \"deny\" }\n }\n if (rule?.policy === \"ask\") {\n return {\n ask: `Allow tool ${input}?`,\n reason: `tool ${input}: rule requires confirmation`,\n suggestions: [{ kind: \"rule\", pattern: input, scope: \"tool\" }],\n verdict: \"ask\",\n }\n }\n return { verdict: \"allow\" }\n },\n}\n\nfunction resolveRule(input: string, rules: readonly Rule<\"tool\">[]): Rule<\"tool\"> | undefined {\n for (const rule of rules) {\n if (ignore().add(rule.pattern).ignores(input)) return rule\n }\n}\n","import type { PermissionHandler } from \"../types.ts\"\n\nimport { createRegistry } from \"@zaly/shared/registry\"\nimport { bashHandler } from \"./bash.ts\"\nimport { fileHandler } from \"./files.ts\"\nimport { toolHandler } from \"./tool.ts\"\n\nexport type HandlerLoader = () => PermissionHandler<string>\n\nconst builtin = {\n bash: () => bashHandler,\n read: () => fileHandler,\n tool: () => toolHandler,\n write: () => fileHandler,\n} as const satisfies Record<string, HandlerLoader>\n\n/** Open registry of permission scopes — declaration-merge to add your\n * own. The keys give `ctx.need(\"…\", input)` typed autocomplete and\n * catch typos at compile time. The value carries the *input* type for\n * that scope (almost always `string` — files take paths, bash takes\n * commands, the generic `tool` scope takes the tool name).\n *\n * Built-ins:\n * - `bash` → command string\n * - `read` → absolute path\n * - `write` → absolute path\n * - `tool` → tool name (or richer `name:arg` shape per tool)\n *\n * Add your own scope:\n *\n * ```ts\n * declare module \"@zaly/agent\" {\n * interface PermissionScopes {\n * fetch: string // expects a domain (or \"*\" for any)\n * }\n * }\n * ```\n *\n * Then `ctx.need(\"fetch\", domain)` is typed end-to-end. You still need\n * to register a runtime handler via `handlerRegistry.register(\"fetch\", …)`\n * — this interface is only the type-side declaration.\n */\nexport interface PermissionScopes {\n bash: string\n read: string\n tool: string\n write: string\n}\n\nexport type BuiltinScope = keyof typeof builtin\nexport type PermissionScope = keyof PermissionScopes\nexport type AnyScope = PermissionScope | (string & {})\n\nexport const handlerRegistry = createRegistry<HandlerLoader>(\"scope\").from(builtin)\n"],"x_google_ignoreList":[1],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-CUUdWFC5.mjs","names":["#nodes","#root","#store","#opts","#path","#id","#dir","#rebuild","#chain","#view","#settings","#started","#commit","#autostart","#head","#closed","#emitChanges","#migrate"],"sources":["../src/session/memory.ts","../src/session/session.ts"],"sourcesContent":["import type { SessionStore } from \"./store.ts\"\nimport type { SessionNode } from \"./types.ts\"\n\n/**\n * In-memory `SessionStore` — a `Map<uuid, SessionNode>` plus a `root`\n * pointer. No persistence. Construction takes optional initial nodes\n * for tests, replay tools, and the Claude session importer.\n */\nexport class MemoryStore implements SessionStore {\n readonly #nodes: Map<string, SessionNode>\n #root?: SessionNode\n\n constructor(nodes?: Iterable<SessionNode>) {\n this.#nodes = new Map()\n if (nodes) {\n for (const node of nodes) {\n this.#nodes.set(node.uuid, node)\n this.#root = node\n }\n }\n }\n\n get root(): SessionNode | undefined {\n return this.#root\n }\n\n async get(id: string): Promise<SessionNode | undefined> {\n return this.#nodes.get(id)\n }\n\n async write(node: SessionNode): Promise<void> {\n this.#nodes.set(node.uuid, node)\n this.#root = node\n }\n\n *all(): Iterable<SessionNode> {\n yield* this.#nodes.values()\n }\n}\n","import type { Message } from \"@zaly/ai\"\nimport type { SessionStore } from \"./store.ts\"\nimport type {\n MaskCheckpoint,\n PartialNode,\n SessionEvents,\n SessionInit,\n SessionMessage,\n SessionNode,\n SessionNodeView,\n SessionOptions,\n SessionSettings,\n SessionUpdate,\n SessionView,\n} from \"./types.ts\"\n\nimport { Emitter, normPath } from \"@zaly/shared\"\nimport { zalyPaths } from \"@zaly/shared/paths\"\nimport { isDeepStrictEqual } from \"node:util\"\nimport { join } from \"pathe\"\nimport { uuidv7 } from \"../utils/uuid.ts\"\nimport { JsonlStore } from \"./jsonl.ts\"\nimport { MemoryStore } from \"./memory.ts\"\n\nconst VERSION = 2\n\n/**\n * Conversation primitive. Owns a DAG of message + compaction + meta\n * nodes via a `SessionStore` backend; the *active* message list is\n * whatever you get by walking `parentUuid` backwards from the store's\n * root until you hit a `compact` node (or the start).\n *\n * **Meta is snapshot-based.** `session-meta` nodes carry the full\n * cumulative meta as of their commit time. Other node types (start,\n * resume, message, compact) don't carry meta — `Session` reconstructs\n * the cumulative meta at any point by finding the most recent\n * `session-meta` ancestor in a forward pass over the chain. Public\n * APIs return `SessionNodeView` (raw node + decorated `meta`).\n *\n * Designed so the loop, the persistor, the TUI, and any replay tool\n * all read from one source of truth and never mutate the DAG behind\n * each other's backs:\n *\n * - **Run loop** (`Agent`) calls `add()` on each new message and\n * `compact()` on overflow.\n * - **TUI** subscribes to the `node` event for streaming render.\n * - **Persistor** is the `SessionStore` — `MemoryStore` for ephemeral\n * sessions, `JsonlStore` for file-backed.\n *\n * Construction:\n * - Use `await Session.load(opts)` for the recommended path — picks\n * the right store (Memory if no path, JSONL if path).\n * - For tests / direct embedding, `new Session({ store })` works with\n * any pre-built store.\n */\nexport class Session<T extends SessionStore = SessionStore> extends Emitter<SessionEvents> {\n readonly #store: T\n #opts: SessionInit<T>\n #id: string\n #dir: string\n #settings: SessionSettings = {}\n #view: SessionView = { messages: [], nodes: new Map() }\n #closed = false\n #started = false\n #path?: string\n #head?: string\n\n protected constructor(opts: SessionInit<T>) {\n super()\n this.#opts = opts\n this.#path = opts.path\n this.#store = opts.store\n this.#id = opts.defaults?.sessionId ?? uuidv7()\n this.#dir = normPath(opts.dir ?? join(zalyPaths.env.tmp, \"sessions\", this.#id))\n }\n\n /** Recommended one-step path: pick the right store backend, hydrate\n * if applicable, return a ready-to-use session.\n *\n * - `path` provided → `JsonlStore` (file-backed, hydrates from disk\n * if the file exists, opens for append either way).\n * - No `path` → `MemoryStore` (ephemeral, no persistence). */\n static async load<T extends SessionStore = SessionStore>(\n opts: SessionOptions<T> & { store: T }\n ): Promise<Session<T>>\n static async load(opts: SessionOptions & { path: string }): Promise<Session<JsonlStore>>\n static async load(opts?: SessionOptions & {}): Promise<Session<MemoryStore>>\n static async load(opts: SessionOptions = {}): Promise<Session> {\n const session = await Session.create(opts)\n await session.#rebuild()\n return session\n }\n\n private static async create(opts: SessionOptions = {}): Promise<Session> {\n const path = opts.path ? normPath(opts.path) : undefined\n const store: SessionStore =\n opts.store ?? (path ? await JsonlStore.load(path) : new MemoryStore())\n const init: SessionInit = { ...opts, path, store }\n return new Session(init)\n }\n\n /** Efficiently fetch the most recent user message by walking backward until we hit\n * a user message, without reconstructing the full chain. Useful for a session picker. */\n static async lastMessage(opts: SessionOptions = {}): Promise<Message<\"user\"> | undefined> {\n const session = await Session.create(opts)\n let ret: Message<\"user\"> | undefined\n await session.#chain({\n stop: (node) => {\n if (node.type === \"message\" && node.message.role === \"user\") {\n ret = node.message\n return true\n }\n return false\n },\n })\n void session.close()\n return ret\n }\n\n async #rebuild(): Promise<void> {\n const chain = await this.#chain()\n this.#view = chain\n this.#settings = chain.settings\n this.#id = chain.settings.sessionId ?? this.#id\n }\n\n // ── Read ──────────────────────────────────────────────────────────────\n\n /** Active conversation — chain from current head back to the most\n * recent compact (exclusive), in chronological order. This is what\n * the agent sees on the next request. */\n get messages(): readonly Message[] {\n return this.#view.messages\n }\n\n get maskCheckpoint(): MaskCheckpoint | undefined {\n return this.#view.maskCheckpoint\n }\n\n get id(): string {\n return this.#id\n }\n\n get dir(): string {\n return this.#dir\n }\n\n get path(): string | undefined {\n return this.#path\n }\n\n get started(): boolean {\n return this.#started\n }\n\n /** Current session settings, merged with defaults. */\n get settings(): SessionSettings {\n return { ...this.#opts.defaults, ...this.#settings }\n }\n\n async update(settings: SessionUpdate, opts?: { force?: boolean }): Promise<string> {\n return this.#commit({ settings, type: \"session-settings\" }, opts)\n }\n\n /** Lazily emits `session-start` on a fresh session or `session-resume`\n * on a hydrated one. Called from `#commit` before the first non-marker\n * node lands so the start/resume marker always heads the chain. */\n async #autostart(): Promise<void> {\n if (!this.#started) await this.start()\n }\n\n /** Explicitly mark the session as started — writes a `session-start`\n * marker on a fresh session, `session-resume` on a hydrated one.\n * Idempotent; subsequent calls are no-ops. Optional `meta` is\n * applied via `update()` after the marker lands. */\n async start(settings?: SessionUpdate): Promise<string | undefined> {\n if (this.#started) return settings ? this.update(settings) : this.#store.root?.uuid\n this.#started = true\n const type = this.messages.length > 0 ? (\"session-resume\" as const) : (\"session-start\" as const)\n await this.#commit({ type })\n void this.emit(type)\n await this.update(settings ?? {})\n return this.#store.root?.uuid\n }\n\n /** Look up the decorated view for a node id — raw node plus the\n * cumulative meta as of that node's position. Returns the\n * message-typed view, or `undefined` if the id doesn't refer to a\n * message in this session. */\n async node(id?: string | Message): Promise<(SessionNodeView & { type: \"message\" }) | undefined> {\n const m = typeof id === \"string\" ? { id } : id\n if (!m?.id) return undefined\n const ret = this.#view.nodes.get(m.id)\n return ret?.type === \"message\" ? ret : undefined\n }\n\n /** Current head uuid — the root of the store, which is the most\n * recently appended node. */\n get head(): string | undefined {\n return this.#head ?? this.#store.root?.uuid\n }\n\n /** Full DAG iterator — backed by `store.all()`. Yields raw nodes\n * (no meta decoration). */\n nodes(): Iterable<SessionNode> | AsyncIterable<SessionNode> {\n return this.#store.all?.() ?? []\n }\n\n get root(): SessionNode | undefined {\n return this.#store.root\n }\n\n // ── Mutate ────────────────────────────────────────────────────────────\n\n /** Append a message. The new node is parented to the current head,\n * head advances, and a `node` event fires. Optional `meta` carries\n * usage / model / finish info — populate it for assistant turns\n * the agent commits after a step. Returns the assigned uuid.\n *\n * If `message.id` / `message.ts` are set (e.g. round-tripped from a\n * prior load), they're used as the node's uuid / timestamp; otherwise\n * fresh values are generated. The committed message always carries\n * both — `m.id === node.uuid` and `m.ts === node.ts`. */\n async add(message: Message): Promise<string> {\n const uuid = message.id ?? uuidv7()\n const ts = message.ts ?? Date.now()\n const m = { ...message, id: uuid, ts }\n return this.#commit({ message: m, type: \"message\" })\n }\n\n /** Mark a compaction boundary. Subsequent `add()` calls land after\n * this node; their messages form the new active conversation. The\n * pre-compact chain stays in the store but is no longer part of\n * `messages`. Also commits a fresh `session-meta` snapshot right\n * after the compact so post-compact lazy walks always have a nearby\n * meta anchor. */\n async compact(opts: {\n trigger?: \"manual\" | \"auto\"\n preTokens?: number\n durationMs?: number\n tail: number\n summary: Message<\"system\">\n }): Promise<string> {\n const node: SessionNode = {\n durationMs: opts.durationMs,\n parentUuid: this.#store.root?.uuid,\n preTokens: opts.preTokens,\n summary: opts.summary,\n tail: opts.tail,\n trigger: opts.trigger ?? \"manual\",\n ts: Date.now(),\n type: \"compact\",\n uuid: uuidv7(),\n }\n const compactUuid = await this.#commit(node)\n await this.update({}, { force: true })\n await this.#rebuild()\n void this.emit(\"compact\", { node })\n return compactUuid\n }\n\n async addMaskCheckpoint(opts: MaskCheckpoint): Promise<string> {\n this.#view.maskCheckpoint = opts\n return this.#commit({ ...opts, type: \"mask-checkpoint\" })\n }\n\n async checkout(uuid: string): Promise<void> {\n if (this.#closed) throw new Error(\"Session is closed\")\n this.#head = uuid\n await this.#rebuild()\n }\n\n /** Pre-active history of the current chain — messages from before\n * the most recent compact (and earlier compacts), in chronological\n * order. Useful for TUI scrollback that wants to render context the\n * agent itself no longer sees.\n *\n * `limit` truncates from the front (oldest), so the most recent\n * history messages always make it through. */\n async history(limit?: number): Promise<readonly Message[]> {\n const chain = await this.#chain({ active: false, limit })\n return chain.messages\n }\n\n /** Flush + close the underlying store. Subsequent writes throw. */\n async close(): Promise<void> {\n if (this.#closed) return\n this.#closed = true\n await this.#store.close?.()\n }\n\n // ── Internals ────────────────────────────────────────────────────────\n\n /** Atomically commit a node: register it in the store, update active\n * messages, persist, and emit. Single chokepoint for all mutations. */\n async #commit(n: PartialNode, opts: { force?: boolean } = {}): Promise<string> {\n let node: SessionNode = {\n ...n,\n parentUuid: this.head,\n ts: Date.now(),\n uuid: uuidv7(),\n }\n\n if (!this.#started && node.type !== \"session-start\" && node.type !== \"session-resume\") {\n await this.#autostart()\n }\n if (this.#closed) throw new Error(\"Session is closed\")\n\n const next: SessionSettings = {\n ...this.#opts.defaults,\n ...this.#settings,\n ...(node.type === \"session-settings\" ? node.settings : {}),\n sessionId: this.#id,\n version: VERSION,\n }\n if (next.cwd) next.cwd = normPath(next.cwd)\n if (next.workspace) next.workspace = normPath(next.workspace)\n\n if (node.type === \"session-settings\") {\n if (!opts.force && isDeepStrictEqual(this.#settings, next)) return this.#store.root!.uuid\n node = { ...node, settings: next }\n }\n\n node = { ...node, parentUuid: this.head }\n await this.#store.write(node)\n this.#head = undefined // invalidate head cache so it reflects the store's root on next read\n\n // Decorate the new node with cumulative meta and append to the\n // active chain view\n this.#view.nodes.set(node.uuid, { ...node, settings: next })\n if (node.type === \"message\") this.#view.messages.push(node.message)\n\n // cwd / meta event signaling\n if (node.type === \"session-settings\") {\n const prev = this.#settings\n this.#settings = next\n this.#emitChanges(prev)\n }\n\n void this.emit(\"node\", { node })\n return node.uuid\n }\n\n #emitChanges(prev: SessionSettings): void {\n const next = this.#settings\n if (next.cwd && next.cwd !== prev.cwd) void this.emit(\"cwd\", { cwd: next.cwd, prev: prev.cwd })\n if (next.modelId && next.modelId !== prev.modelId)\n void this.emit(\"model\", { model: next.modelId, prev: prev.modelId })\n if (next.reasoning && next.reasoning !== prev.reasoning)\n void this.emit(\"reasoning\", { effort: next.reasoning, prev: prev.reasoning })\n }\n\n /** Walk `parentUuid` from the given node back toward the root,\n * returning the chain as decorated views (each with cumulative meta).\n * The `active` flag controls what counts:\n * - `true` — only the active chain (stops at first compact /\n * session-start, with the kept tail spliced in via\n * the compact's `tail` field, summary substituted\n * in place of the compact node).\n * - `false` — includes everything back to the root\n * Returns chronological order. */\n async #chain(\n opts: {\n active?: boolean\n limit?: number\n uuid?: string\n stop?: (node: SessionNode) => boolean\n } = {}\n ): Promise<SessionView & { settings: SessionSettings }> {\n // Backward pass: collect raw nodes (new to old)\n const reverse: SessionNode[] = []\n let cursor = opts.uuid ?? this.head\n let limit = opts.limit ?? Infinity\n let compact: SessionNode<\"compact\"> | undefined\n const messageNodes: SessionNode<\"message\">[] = []\n let maskCheckpoint: SessionNode<\"mask-checkpoint\"> | undefined\n\n // Walk backward from the head until we hit a compact or the start, collecting nodes.\n while (cursor) {\n // eslint-disable-next-line no-await-in-loop\n const node = await this.#store.get(cursor)\n if (!node || (node.type === \"message\" && messageNodes.length + 1 > limit)) break\n cursor = node.parentUuid\n reverse.push(node)\n // Keep track if the last mask-checkpoint, until we hit a compaction.\n if (node.type === \"mask-checkpoint\" && !compact && !maskCheckpoint) maskCheckpoint = node\n if (node.type === \"message\") messageNodes.push(node)\n if (node.type === \"compact\" && (opts.active ?? true)) {\n if (compact) break // stop at the first compact\n compact = node\n // update limit to the compact's tail\n limit = Math.min(limit, messageNodes.length + node.tail)\n }\n if (opts.stop?.(node)) break\n }\n\n // Forward pass: decorate with cumulative meta. session-meta nodes\n // redefine the meta; everything else inherits the running snapshot.\n const nodes = new Map<string, SessionNodeView>()\n let settings: SessionSettings = {}\n for (const n of reverse.toReversed()) {\n if (n.type === \"session-settings\") settings = n.settings\n nodes.set(n.uuid, { ...n, settings })\n }\n\n this.#migrate(nodes)\n\n const messages: SessionMessage[] = []\n for (const n of messageNodes) {\n // add `id`, `ts` and `modelId` (if assistant turn) to the message\n const m = { ...n.message, id: n.uuid, ts: n.ts }\n if (m.role === \"assistant\") {\n // Add missing modelId to assistant messages if not present\n const s = nodes.get(n.uuid)?.settings ?? {}\n m.meta = { ...m.meta, modelId: m.meta?.modelId ?? s.modelId }\n }\n n.message = m\n messages.push(m)\n }\n\n // Add compaction summary as the first message\n if (compact) {\n messages.push({ ...compact.summary, id: compact.uuid, ts: compact.ts })\n nodes.set(compact.uuid, {\n message: compact.summary,\n parentUuid: compact.parentUuid,\n settings: nodes.get(compact.uuid)?.settings ?? {},\n ts: compact.ts,\n type: \"message\",\n uuid: compact.uuid,\n })\n }\n\n return {\n compact,\n maskCheckpoint,\n messages: messages.toReversed(),\n nodes,\n settings,\n }\n }\n\n #migrate(nodes: Map<string, SessionNodeView>) {\n for (const n of nodes.values()) {\n const version = n.settings.version ?? 0\n if (version === VERSION) continue\n n.settings = { ...n.settings, version: VERSION }\n\n if (n.type === \"compact\") {\n n.summary.meta = { kind: \"compaction-summary\", ...n.summary.meta }\n continue\n }\n\n if (n.type !== \"message\") continue\n const m = n.message\n\n if (\n m.role === \"system\" &&\n Array.isArray(m.content) &&\n m.content[0].type === \"meta\" &&\n m.content[0].tag === \"task\"\n ) {\n // Missing task meta data kind\n m.meta = { kind: \"task\", ...m.meta }\n }\n\n n.message = m\n }\n }\n}\n"],"mappings":"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"}
|