{
  "version": 3,
  "sources": ["../../../node_modules/yaml/dist/nodes/identity.js", "../../../node_modules/yaml/dist/visit.js", "../../../node_modules/yaml/dist/doc/directives.js", "../../../node_modules/yaml/dist/doc/anchors.js", "../../../node_modules/yaml/dist/doc/applyReviver.js", "../../../node_modules/yaml/dist/nodes/toJS.js", "../../../node_modules/yaml/dist/nodes/Node.js", "../../../node_modules/yaml/dist/nodes/Alias.js", "../../../node_modules/yaml/dist/nodes/Scalar.js", "../../../node_modules/yaml/dist/doc/createNode.js", "../../../node_modules/yaml/dist/nodes/Collection.js", "../../../node_modules/yaml/dist/stringify/stringifyComment.js", "../../../node_modules/yaml/dist/stringify/foldFlowLines.js", "../../../node_modules/yaml/dist/stringify/stringifyString.js", "../../../node_modules/yaml/dist/stringify/stringify.js", "../../../node_modules/yaml/dist/stringify/stringifyPair.js", "../../../node_modules/yaml/dist/log.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/merge.js", "../../../node_modules/yaml/dist/nodes/addPairToJSMap.js", "../../../node_modules/yaml/dist/nodes/Pair.js", "../../../node_modules/yaml/dist/stringify/stringifyCollection.js", "../../../node_modules/yaml/dist/nodes/YAMLMap.js", "../../../node_modules/yaml/dist/schema/common/map.js", "../../../node_modules/yaml/dist/nodes/YAMLSeq.js", "../../../node_modules/yaml/dist/schema/common/seq.js", "../../../node_modules/yaml/dist/schema/common/string.js", "../../../node_modules/yaml/dist/schema/common/null.js", "../../../node_modules/yaml/dist/schema/core/bool.js", "../../../node_modules/yaml/dist/stringify/stringifyNumber.js", "../../../node_modules/yaml/dist/schema/core/float.js", "../../../node_modules/yaml/dist/schema/core/int.js", "../../../node_modules/yaml/dist/schema/core/schema.js", "../../../node_modules/yaml/dist/schema/json/schema.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/binary.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/pairs.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/omap.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/bool.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/float.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/int.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/set.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/timestamp.js", "../../../node_modules/yaml/dist/schema/yaml-1.1/schema.js", "../../../node_modules/yaml/dist/schema/tags.js", "../../../node_modules/yaml/dist/schema/Schema.js", "../../../node_modules/yaml/dist/stringify/stringifyDocument.js", "../../../node_modules/yaml/dist/doc/Document.js", "../../../node_modules/yaml/dist/errors.js", "../../../node_modules/yaml/dist/compose/resolve-props.js", "../../../node_modules/yaml/dist/compose/util-contains-newline.js", "../../../node_modules/yaml/dist/compose/util-flow-indent-check.js", "../../../node_modules/yaml/dist/compose/util-map-includes.js", "../../../node_modules/yaml/dist/compose/resolve-block-map.js", "../../../node_modules/yaml/dist/compose/resolve-block-seq.js", "../../../node_modules/yaml/dist/compose/resolve-end.js", "../../../node_modules/yaml/dist/compose/resolve-flow-collection.js", "../../../node_modules/yaml/dist/compose/compose-collection.js", "../../../node_modules/yaml/dist/compose/resolve-block-scalar.js", "../../../node_modules/yaml/dist/compose/resolve-flow-scalar.js", "../../../node_modules/yaml/dist/compose/compose-scalar.js", "../../../node_modules/yaml/dist/compose/util-empty-scalar-position.js", "../../../node_modules/yaml/dist/compose/compose-node.js", "../../../node_modules/yaml/dist/compose/compose-doc.js", "../../../node_modules/yaml/dist/compose/composer.js", "../../../node_modules/yaml/dist/parse/cst-scalar.js", "../../../node_modules/yaml/dist/parse/cst-stringify.js", "../../../node_modules/yaml/dist/parse/cst-visit.js", "../../../node_modules/yaml/dist/parse/cst.js", "../../../node_modules/yaml/dist/parse/lexer.js", "../../../node_modules/yaml/dist/parse/line-counter.js", "../../../node_modules/yaml/dist/parse/parser.js", "../../../node_modules/yaml/dist/public-api.js", "../../../node_modules/yaml/dist/index.js", "../../../src/workers/config.ts", "../../../src/daemon/config.ts", "../../../src/notifications/types.ts", "../../../src/tasks/types.ts", "../../../src/runtime-paths.ts", "../../../src/config/pai-home.ts", "../../../src/config/main-config.ts", "../../../src/config/json-store.ts", "../../../src/config/yaml-store.ts", "../../../src/workers/workers-config.ts", "../../../src/workers/paths.ts", "../../../src/workers/pending.ts", "../../../src/workers/status.ts", "../../../src/workers/worktree.ts", "../../../src/hooks/ts/lib/worker-session.ts", "../../../src/hooks/ts/session-start/load-project-context.ts", "../../../src/memory/wakeup.ts", "../../../src/session/checkpoint-block.ts", "../../../src/hooks/ts/lib/handover-budget.ts", "../../../src/hooks/ts/lib/pai-paths.ts", "../../../src/hooks/ts/lib/project-utils/paths.ts", "../../../src/hooks/ts/lib/project-utils/notify.ts", "../../../src/hooks/ts/lib/project-utils/session-notes.ts"],
  "sourcesContent": ["'use strict';\n\nconst ALIAS = Symbol.for('yaml.alias');\nconst DOC = Symbol.for('yaml.document');\nconst MAP = Symbol.for('yaml.map');\nconst PAIR = Symbol.for('yaml.pair');\nconst SCALAR = Symbol.for('yaml.scalar');\nconst SEQ = Symbol.for('yaml.seq');\nconst NODE_TYPE = Symbol.for('yaml.node.type');\nconst isAlias = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === ALIAS;\nconst isDocument = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === DOC;\nconst isMap = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === MAP;\nconst isPair = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === PAIR;\nconst isScalar = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === SCALAR;\nconst isSeq = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === SEQ;\nfunction isCollection(node) {\n    if (node && typeof node === 'object')\n        switch (node[NODE_TYPE]) {\n            case MAP:\n            case SEQ:\n                return true;\n        }\n    return false;\n}\nfunction isNode(node) {\n    if (node && typeof node === 'object')\n        switch (node[NODE_TYPE]) {\n            case ALIAS:\n            case MAP:\n            case SCALAR:\n            case SEQ:\n                return true;\n        }\n    return false;\n}\nconst hasAnchor = (node) => (isScalar(node) || isCollection(node)) && !!node.anchor;\n\nexports.ALIAS = ALIAS;\nexports.DOC = DOC;\nexports.MAP = MAP;\nexports.NODE_TYPE = NODE_TYPE;\nexports.PAIR = PAIR;\nexports.SCALAR = SCALAR;\nexports.SEQ = SEQ;\nexports.hasAnchor = hasAnchor;\nexports.isAlias = isAlias;\nexports.isCollection = isCollection;\nexports.isDocument = isDocument;\nexports.isMap = isMap;\nexports.isNode = isNode;\nexports.isPair = isPair;\nexports.isScalar = isScalar;\nexports.isSeq = isSeq;\n", "'use strict';\n\nvar identity = require('./nodes/identity.js');\n\nconst BREAK = Symbol('break visit');\nconst SKIP = Symbol('skip children');\nconst REMOVE = Symbol('remove node');\n/**\n * Apply a visitor to an AST node or document.\n *\n * Walks through the tree (depth-first) starting from `node`, calling a\n * `visitor` function with three arguments:\n *   - `key`: For sequence values and map `Pair`, the node's index in the\n *     collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.\n *     `null` for the root node.\n *   - `node`: The current node.\n *   - `path`: The ancestry of the current node.\n *\n * The return value of the visitor may be used to control the traversal:\n *   - `undefined` (default): Do nothing and continue\n *   - `visit.SKIP`: Do not visit the children of this node, continue with next\n *     sibling\n *   - `visit.BREAK`: Terminate traversal completely\n *   - `visit.REMOVE`: Remove the current node, then continue with the next one\n *   - `Node`: Replace the current node, then continue by visiting it\n *   - `number`: While iterating the items of a sequence or map, set the index\n *     of the next step. This is useful especially if the index of the current\n *     node has changed.\n *\n * If `visitor` is a single function, it will be called with all values\n * encountered in the tree, including e.g. `null` values. Alternatively,\n * separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,\n * `Alias` and `Scalar` node. To define the same visitor function for more than\n * one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)\n * and `Node` (alias, map, seq & scalar) targets. Of all these, only the most\n * specific defined one will be used for each node.\n */\nfunction visit(node, visitor) {\n    const visitor_ = initVisitor(visitor);\n    if (identity.isDocument(node)) {\n        const cd = visit_(null, node.contents, visitor_, Object.freeze([node]));\n        if (cd === REMOVE)\n            node.contents = null;\n    }\n    else\n        visit_(null, node, visitor_, Object.freeze([]));\n}\n// Without the `as symbol` casts, TS declares these in the `visit`\n// namespace using `var`, but then complains about that because\n// `unique symbol` must be `const`.\n/** Terminate visit traversal completely */\nvisit.BREAK = BREAK;\n/** Do not visit the children of the current node */\nvisit.SKIP = SKIP;\n/** Remove the current node */\nvisit.REMOVE = REMOVE;\nfunction visit_(key, node, visitor, path) {\n    const ctrl = callVisitor(key, node, visitor, path);\n    if (identity.isNode(ctrl) || identity.isPair(ctrl)) {\n        replaceNode(key, path, ctrl);\n        return visit_(key, ctrl, visitor, path);\n    }\n    if (typeof ctrl !== 'symbol') {\n        if (identity.isCollection(node)) {\n            path = Object.freeze(path.concat(node));\n            for (let i = 0; i < node.items.length; ++i) {\n                const ci = visit_(i, node.items[i], visitor, path);\n                if (typeof ci === 'number')\n                    i = ci - 1;\n                else if (ci === BREAK)\n                    return BREAK;\n                else if (ci === REMOVE) {\n                    node.items.splice(i, 1);\n                    i -= 1;\n                }\n            }\n        }\n        else if (identity.isPair(node)) {\n            path = Object.freeze(path.concat(node));\n            const ck = visit_('key', node.key, visitor, path);\n            if (ck === BREAK)\n                return BREAK;\n            else if (ck === REMOVE)\n                node.key = null;\n            const cv = visit_('value', node.value, visitor, path);\n            if (cv === BREAK)\n                return BREAK;\n            else if (cv === REMOVE)\n                node.value = null;\n        }\n    }\n    return ctrl;\n}\n/**\n * Apply an async visitor to an AST node or document.\n *\n * Walks through the tree (depth-first) starting from `node`, calling a\n * `visitor` function with three arguments:\n *   - `key`: For sequence values and map `Pair`, the node's index in the\n *     collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.\n *     `null` for the root node.\n *   - `node`: The current node.\n *   - `path`: The ancestry of the current node.\n *\n * The return value of the visitor may be used to control the traversal:\n *   - `Promise`: Must resolve to one of the following values\n *   - `undefined` (default): Do nothing and continue\n *   - `visit.SKIP`: Do not visit the children of this node, continue with next\n *     sibling\n *   - `visit.BREAK`: Terminate traversal completely\n *   - `visit.REMOVE`: Remove the current node, then continue with the next one\n *   - `Node`: Replace the current node, then continue by visiting it\n *   - `number`: While iterating the items of a sequence or map, set the index\n *     of the next step. This is useful especially if the index of the current\n *     node has changed.\n *\n * If `visitor` is a single function, it will be called with all values\n * encountered in the tree, including e.g. `null` values. Alternatively,\n * separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,\n * `Alias` and `Scalar` node. To define the same visitor function for more than\n * one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)\n * and `Node` (alias, map, seq & scalar) targets. Of all these, only the most\n * specific defined one will be used for each node.\n */\nasync function visitAsync(node, visitor) {\n    const visitor_ = initVisitor(visitor);\n    if (identity.isDocument(node)) {\n        const cd = await visitAsync_(null, node.contents, visitor_, Object.freeze([node]));\n        if (cd === REMOVE)\n            node.contents = null;\n    }\n    else\n        await visitAsync_(null, node, visitor_, Object.freeze([]));\n}\n// Without the `as symbol` casts, TS declares these in the `visit`\n// namespace using `var`, but then complains about that because\n// `unique symbol` must be `const`.\n/** Terminate visit traversal completely */\nvisitAsync.BREAK = BREAK;\n/** Do not visit the children of the current node */\nvisitAsync.SKIP = SKIP;\n/** Remove the current node */\nvisitAsync.REMOVE = REMOVE;\nasync function visitAsync_(key, node, visitor, path) {\n    const ctrl = await callVisitor(key, node, visitor, path);\n    if (identity.isNode(ctrl) || identity.isPair(ctrl)) {\n        replaceNode(key, path, ctrl);\n        return visitAsync_(key, ctrl, visitor, path);\n    }\n    if (typeof ctrl !== 'symbol') {\n        if (identity.isCollection(node)) {\n            path = Object.freeze(path.concat(node));\n            for (let i = 0; i < node.items.length; ++i) {\n                const ci = await visitAsync_(i, node.items[i], visitor, path);\n                if (typeof ci === 'number')\n                    i = ci - 1;\n                else if (ci === BREAK)\n                    return BREAK;\n                else if (ci === REMOVE) {\n                    node.items.splice(i, 1);\n                    i -= 1;\n                }\n            }\n        }\n        else if (identity.isPair(node)) {\n            path = Object.freeze(path.concat(node));\n            const ck = await visitAsync_('key', node.key, visitor, path);\n            if (ck === BREAK)\n                return BREAK;\n            else if (ck === REMOVE)\n                node.key = null;\n            const cv = await visitAsync_('value', node.value, visitor, path);\n            if (cv === BREAK)\n                return BREAK;\n            else if (cv === REMOVE)\n                node.value = null;\n        }\n    }\n    return ctrl;\n}\nfunction initVisitor(visitor) {\n    if (typeof visitor === 'object' &&\n        (visitor.Collection || visitor.Node || visitor.Value)) {\n        return Object.assign({\n            Alias: visitor.Node,\n            Map: visitor.Node,\n            Scalar: visitor.Node,\n            Seq: visitor.Node\n        }, visitor.Value && {\n            Map: visitor.Value,\n            Scalar: visitor.Value,\n            Seq: visitor.Value\n        }, visitor.Collection && {\n            Map: visitor.Collection,\n            Seq: visitor.Collection\n        }, visitor);\n    }\n    return visitor;\n}\nfunction callVisitor(key, node, visitor, path) {\n    if (typeof visitor === 'function')\n        return visitor(key, node, path);\n    if (identity.isMap(node))\n        return visitor.Map?.(key, node, path);\n    if (identity.isSeq(node))\n        return visitor.Seq?.(key, node, path);\n    if (identity.isPair(node))\n        return visitor.Pair?.(key, node, path);\n    if (identity.isScalar(node))\n        return visitor.Scalar?.(key, node, path);\n    if (identity.isAlias(node))\n        return visitor.Alias?.(key, node, path);\n    return undefined;\n}\nfunction replaceNode(key, path, node) {\n    const parent = path[path.length - 1];\n    if (identity.isCollection(parent)) {\n        parent.items[key] = node;\n    }\n    else if (identity.isPair(parent)) {\n        if (key === 'key')\n            parent.key = node;\n        else\n            parent.value = node;\n    }\n    else if (identity.isDocument(parent)) {\n        parent.contents = node;\n    }\n    else {\n        const pt = identity.isAlias(parent) ? 'alias' : 'scalar';\n        throw new Error(`Cannot replace node with ${pt} parent`);\n    }\n}\n\nexports.visit = visit;\nexports.visitAsync = visitAsync;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar visit = require('../visit.js');\n\nconst escapeChars = {\n    '!': '%21',\n    ',': '%2C',\n    '[': '%5B',\n    ']': '%5D',\n    '{': '%7B',\n    '}': '%7D'\n};\nconst escapeTagName = (tn) => tn.replace(/[!,[\\]{}]/g, ch => escapeChars[ch]);\nclass Directives {\n    constructor(yaml, tags) {\n        /**\n         * The directives-end/doc-start marker `---`. If `null`, a marker may still be\n         * included in the document's stringified representation.\n         */\n        this.docStart = null;\n        /** The doc-end marker `...`.  */\n        this.docEnd = false;\n        this.yaml = Object.assign({}, Directives.defaultYaml, yaml);\n        this.tags = Object.assign({}, Directives.defaultTags, tags);\n    }\n    clone() {\n        const copy = new Directives(this.yaml, this.tags);\n        copy.docStart = this.docStart;\n        return copy;\n    }\n    /**\n     * During parsing, get a Directives instance for the current document and\n     * update the stream state according to the current version's spec.\n     */\n    atDocument() {\n        const res = new Directives(this.yaml, this.tags);\n        switch (this.yaml.version) {\n            case '1.1':\n                this.atNextDocument = true;\n                break;\n            case '1.2':\n                this.atNextDocument = false;\n                this.yaml = {\n                    explicit: Directives.defaultYaml.explicit,\n                    version: '1.2'\n                };\n                this.tags = Object.assign({}, Directives.defaultTags);\n                break;\n        }\n        return res;\n    }\n    /**\n     * @param onError - May be called even if the action was successful\n     * @returns `true` on success\n     */\n    add(line, onError) {\n        if (this.atNextDocument) {\n            this.yaml = { explicit: Directives.defaultYaml.explicit, version: '1.1' };\n            this.tags = Object.assign({}, Directives.defaultTags);\n            this.atNextDocument = false;\n        }\n        const parts = line.trim().split(/[ \\t]+/);\n        const name = parts.shift();\n        switch (name) {\n            case '%TAG': {\n                if (parts.length !== 2) {\n                    onError(0, '%TAG directive should contain exactly two parts');\n                    if (parts.length < 2)\n                        return false;\n                }\n                const [handle, prefix] = parts;\n                this.tags[handle] = prefix;\n                return true;\n            }\n            case '%YAML': {\n                this.yaml.explicit = true;\n                if (parts.length !== 1) {\n                    onError(0, '%YAML directive should contain exactly one part');\n                    return false;\n                }\n                const [version] = parts;\n                if (version === '1.1' || version === '1.2') {\n                    this.yaml.version = version;\n                    return true;\n                }\n                else {\n                    const isValid = /^\\d+\\.\\d+$/.test(version);\n                    onError(6, `Unsupported YAML version ${version}`, isValid);\n                    return false;\n                }\n            }\n            default:\n                onError(0, `Unknown directive ${name}`, true);\n                return false;\n        }\n    }\n    /**\n     * Resolves a tag, matching handles to those defined in %TAG directives.\n     *\n     * @returns Resolved tag, which may also be the non-specific tag `'!'` or a\n     *   `'!local'` tag, or `null` if unresolvable.\n     */\n    tagName(source, onError) {\n        if (source === '!')\n            return '!'; // non-specific tag\n        if (source[0] !== '!') {\n            onError(`Not a valid tag: ${source}`);\n            return null;\n        }\n        if (source[1] === '<') {\n            const verbatim = source.slice(2, -1);\n            if (verbatim === '!' || verbatim === '!!') {\n                onError(`Verbatim tags aren't resolved, so ${source} is invalid.`);\n                return null;\n            }\n            if (source[source.length - 1] !== '>')\n                onError('Verbatim tags must end with a >');\n            return verbatim;\n        }\n        const [, handle, suffix] = source.match(/^(.*!)([^!]*)$/s);\n        if (!suffix)\n            onError(`The ${source} tag has no suffix`);\n        const prefix = this.tags[handle];\n        if (prefix) {\n            try {\n                return prefix + decodeURIComponent(suffix);\n            }\n            catch (error) {\n                onError(String(error));\n                return null;\n            }\n        }\n        if (handle === '!')\n            return source; // local tag\n        onError(`Could not resolve tag: ${source}`);\n        return null;\n    }\n    /**\n     * Given a fully resolved tag, returns its printable string form,\n     * taking into account current tag prefixes and defaults.\n     */\n    tagString(tag) {\n        for (const [handle, prefix] of Object.entries(this.tags)) {\n            if (tag.startsWith(prefix))\n                return handle + escapeTagName(tag.substring(prefix.length));\n        }\n        return tag[0] === '!' ? tag : `!<${tag}>`;\n    }\n    toString(doc) {\n        const lines = this.yaml.explicit\n            ? [`%YAML ${this.yaml.version || '1.2'}`]\n            : [];\n        const tagEntries = Object.entries(this.tags);\n        let tagNames;\n        if (doc && tagEntries.length > 0 && identity.isNode(doc.contents)) {\n            const tags = {};\n            visit.visit(doc.contents, (_key, node) => {\n                if (identity.isNode(node) && node.tag)\n                    tags[node.tag] = true;\n            });\n            tagNames = Object.keys(tags);\n        }\n        else\n            tagNames = [];\n        for (const [handle, prefix] of tagEntries) {\n            if (handle === '!!' && prefix === 'tag:yaml.org,2002:')\n                continue;\n            if (!doc || tagNames.some(tn => tn.startsWith(prefix)))\n                lines.push(`%TAG ${handle} ${prefix}`);\n        }\n        return lines.join('\\n');\n    }\n}\nDirectives.defaultYaml = { explicit: false, version: '1.2' };\nDirectives.defaultTags = { '!!': 'tag:yaml.org,2002:' };\n\nexports.Directives = Directives;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar visit = require('../visit.js');\n\n/**\n * Verify that the input string is a valid anchor.\n *\n * Will throw on errors.\n */\nfunction anchorIsValid(anchor) {\n    if (/[\\x00-\\x19\\s,[\\]{}]/.test(anchor)) {\n        const sa = JSON.stringify(anchor);\n        const msg = `Anchor must not contain whitespace or control characters: ${sa}`;\n        throw new Error(msg);\n    }\n    return true;\n}\nfunction anchorNames(root) {\n    const anchors = new Set();\n    visit.visit(root, {\n        Value(_key, node) {\n            if (node.anchor)\n                anchors.add(node.anchor);\n        }\n    });\n    return anchors;\n}\n/** Find a new anchor name with the given `prefix` and a one-indexed suffix. */\nfunction findNewAnchor(prefix, exclude) {\n    for (let i = 1; true; ++i) {\n        const name = `${prefix}${i}`;\n        if (!exclude.has(name))\n            return name;\n    }\n}\nfunction createNodeAnchors(doc, prefix) {\n    const aliasObjects = [];\n    const sourceObjects = new Map();\n    let prevAnchors = null;\n    return {\n        onAnchor: (source) => {\n            aliasObjects.push(source);\n            prevAnchors ?? (prevAnchors = anchorNames(doc));\n            const anchor = findNewAnchor(prefix, prevAnchors);\n            prevAnchors.add(anchor);\n            return anchor;\n        },\n        /**\n         * With circular references, the source node is only resolved after all\n         * of its child nodes are. This is why anchors are set only after all of\n         * the nodes have been created.\n         */\n        setAnchors: () => {\n            for (const source of aliasObjects) {\n                const ref = sourceObjects.get(source);\n                if (typeof ref === 'object' &&\n                    ref.anchor &&\n                    (identity.isScalar(ref.node) || identity.isCollection(ref.node))) {\n                    ref.node.anchor = ref.anchor;\n                }\n                else {\n                    const error = new Error('Failed to resolve repeated object (this should not happen)');\n                    error.source = source;\n                    throw error;\n                }\n            }\n        },\n        sourceObjects\n    };\n}\n\nexports.anchorIsValid = anchorIsValid;\nexports.anchorNames = anchorNames;\nexports.createNodeAnchors = createNodeAnchors;\nexports.findNewAnchor = findNewAnchor;\n", "'use strict';\n\n/**\n * Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec,\n * in section 24.5.1.1 \"Runtime Semantics: InternalizeJSONProperty\" of the\n * 2021 edition: https://tc39.es/ecma262/#sec-json.parse\n *\n * Includes extensions for handling Map and Set objects.\n */\nfunction applyReviver(reviver, obj, key, val) {\n    if (val && typeof val === 'object') {\n        if (Array.isArray(val)) {\n            for (let i = 0, len = val.length; i < len; ++i) {\n                const v0 = val[i];\n                const v1 = applyReviver(reviver, val, String(i), v0);\n                // eslint-disable-next-line @typescript-eslint/no-array-delete\n                if (v1 === undefined)\n                    delete val[i];\n                else if (v1 !== v0)\n                    val[i] = v1;\n            }\n        }\n        else if (val instanceof Map) {\n            for (const k of Array.from(val.keys())) {\n                const v0 = val.get(k);\n                const v1 = applyReviver(reviver, val, k, v0);\n                if (v1 === undefined)\n                    val.delete(k);\n                else if (v1 !== v0)\n                    val.set(k, v1);\n            }\n        }\n        else if (val instanceof Set) {\n            for (const v0 of Array.from(val)) {\n                const v1 = applyReviver(reviver, val, v0, v0);\n                if (v1 === undefined)\n                    val.delete(v0);\n                else if (v1 !== v0) {\n                    val.delete(v0);\n                    val.add(v1);\n                }\n            }\n        }\n        else {\n            for (const [k, v0] of Object.entries(val)) {\n                const v1 = applyReviver(reviver, val, k, v0);\n                if (v1 === undefined)\n                    delete val[k];\n                else if (v1 !== v0)\n                    val[k] = v1;\n            }\n        }\n    }\n    return reviver.call(obj, key, val);\n}\n\nexports.applyReviver = applyReviver;\n", "'use strict';\n\nvar identity = require('./identity.js');\n\n/**\n * Recursively convert any node or its contents to native JavaScript\n *\n * @param value - The input value\n * @param arg - If `value` defines a `toJSON()` method, use this\n *   as its first argument\n * @param ctx - Conversion context, originally set in Document#toJS(). If\n *   `{ keep: true }` is not set, output should be suitable for JSON\n *   stringification.\n */\nfunction toJS(value, arg, ctx) {\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n    if (Array.isArray(value))\n        return value.map((v, i) => toJS(v, String(i), ctx));\n    if (value && typeof value.toJSON === 'function') {\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n        if (!ctx || !identity.hasAnchor(value))\n            return value.toJSON(arg, ctx);\n        const data = { aliasCount: 0, count: 1, res: undefined };\n        ctx.anchors.set(value, data);\n        ctx.onCreate = res => {\n            data.res = res;\n            delete ctx.onCreate;\n        };\n        const res = value.toJSON(arg, ctx);\n        if (ctx.onCreate)\n            ctx.onCreate(res);\n        return res;\n    }\n    if (typeof value === 'bigint' && !ctx?.keep)\n        return Number(value);\n    return value;\n}\n\nexports.toJS = toJS;\n", "'use strict';\n\nvar applyReviver = require('../doc/applyReviver.js');\nvar identity = require('./identity.js');\nvar toJS = require('./toJS.js');\n\nclass NodeBase {\n    constructor(type) {\n        Object.defineProperty(this, identity.NODE_TYPE, { value: type });\n    }\n    /** Create a copy of this node.  */\n    clone() {\n        const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));\n        if (this.range)\n            copy.range = this.range.slice();\n        return copy;\n    }\n    /** A plain JavaScript representation of this node. */\n    toJS(doc, { mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {\n        if (!identity.isDocument(doc))\n            throw new TypeError('A document argument is required');\n        const ctx = {\n            anchors: new Map(),\n            doc,\n            keep: true,\n            mapAsMap: mapAsMap === true,\n            mapKeyWarned: false,\n            maxAliasCount: typeof maxAliasCount === 'number' ? maxAliasCount : 100\n        };\n        const res = toJS.toJS(this, '', ctx);\n        if (typeof onAnchor === 'function')\n            for (const { count, res } of ctx.anchors.values())\n                onAnchor(res, count);\n        return typeof reviver === 'function'\n            ? applyReviver.applyReviver(reviver, { '': res }, '', res)\n            : res;\n    }\n}\n\nexports.NodeBase = NodeBase;\n", "'use strict';\n\nvar anchors = require('../doc/anchors.js');\nvar visit = require('../visit.js');\nvar identity = require('./identity.js');\nvar Node = require('./Node.js');\nvar toJS = require('./toJS.js');\n\nclass Alias extends Node.NodeBase {\n    constructor(source) {\n        super(identity.ALIAS);\n        this.source = source;\n        Object.defineProperty(this, 'tag', {\n            set() {\n                throw new Error('Alias nodes cannot have tags');\n            }\n        });\n    }\n    /**\n     * Resolve the value of this alias within `doc`, finding the last\n     * instance of the `source` anchor before this node.\n     */\n    resolve(doc, ctx) {\n        if (ctx?.maxAliasCount === 0)\n            throw new ReferenceError('Alias resolution is disabled');\n        let nodes;\n        if (ctx?.aliasResolveCache) {\n            nodes = ctx.aliasResolveCache;\n        }\n        else {\n            nodes = [];\n            visit.visit(doc, {\n                Node: (_key, node) => {\n                    if (identity.isAlias(node) || identity.hasAnchor(node))\n                        nodes.push(node);\n                }\n            });\n            if (ctx)\n                ctx.aliasResolveCache = nodes;\n        }\n        let found = undefined;\n        for (const node of nodes) {\n            if (node === this)\n                break;\n            if (node.anchor === this.source)\n                found = node;\n        }\n        if (found && ctx) {\n            const { anchors, doc, maxAliasCount } = ctx;\n            let data = anchors.get(found);\n            if (!data) {\n                // Resolve anchors for Node.prototype.toJS()\n                toJS.toJS(found, null, ctx);\n                data = anchors.get(found);\n            }\n            /* istanbul ignore if */\n            if (data?.res === undefined) {\n                const msg = 'This should not happen: Alias anchor was not resolved?';\n                throw new ReferenceError(msg);\n            }\n            if (maxAliasCount >= 0) {\n                data.count += 1;\n                if (data.aliasCount === 0)\n                    data.aliasCount = getAliasCount(doc, found, anchors);\n                if (data.count * data.aliasCount > maxAliasCount) {\n                    const msg = 'Excessive alias count indicates a resource exhaustion attack';\n                    throw new ReferenceError(msg);\n                }\n            }\n        }\n        return found;\n    }\n    toJSON(_arg, ctx) {\n        if (!ctx)\n            return { source: this.source };\n        const source = this.resolve(ctx.doc, ctx);\n        if (!source) {\n            const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;\n            throw new ReferenceError(msg);\n        }\n        return ctx.anchors.get(source).res;\n    }\n    toString(ctx, _onComment, _onChompKeep) {\n        const src = `*${this.source}`;\n        if (ctx) {\n            anchors.anchorIsValid(this.source);\n            if (ctx.options.verifyAliasOrder && !ctx.anchors.has(this.source)) {\n                const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;\n                throw new Error(msg);\n            }\n            if (ctx.implicitKey)\n                return `${src} `;\n        }\n        return src;\n    }\n}\nfunction getAliasCount(doc, node, anchors) {\n    if (identity.isAlias(node)) {\n        const source = node.resolve(doc);\n        const anchor = anchors && source && anchors.get(source);\n        return anchor ? anchor.count * anchor.aliasCount : 0;\n    }\n    else if (identity.isCollection(node)) {\n        let count = 0;\n        for (const item of node.items) {\n            const c = getAliasCount(doc, item, anchors);\n            if (c > count)\n                count = c;\n        }\n        return count;\n    }\n    else if (identity.isPair(node)) {\n        const kc = getAliasCount(doc, node.key, anchors);\n        const vc = getAliasCount(doc, node.value, anchors);\n        return Math.max(kc, vc);\n    }\n    return 1;\n}\n\nexports.Alias = Alias;\n", "'use strict';\n\nvar identity = require('./identity.js');\nvar Node = require('./Node.js');\nvar toJS = require('./toJS.js');\n\nconst isScalarValue = (value) => !value || (typeof value !== 'function' && typeof value !== 'object');\nclass Scalar extends Node.NodeBase {\n    constructor(value) {\n        super(identity.SCALAR);\n        this.value = value;\n    }\n    toJSON(arg, ctx) {\n        return ctx?.keep ? this.value : toJS.toJS(this.value, arg, ctx);\n    }\n    toString() {\n        return String(this.value);\n    }\n}\nScalar.BLOCK_FOLDED = 'BLOCK_FOLDED';\nScalar.BLOCK_LITERAL = 'BLOCK_LITERAL';\nScalar.PLAIN = 'PLAIN';\nScalar.QUOTE_DOUBLE = 'QUOTE_DOUBLE';\nScalar.QUOTE_SINGLE = 'QUOTE_SINGLE';\n\nexports.Scalar = Scalar;\nexports.isScalarValue = isScalarValue;\n", "'use strict';\n\nvar Alias = require('../nodes/Alias.js');\nvar identity = require('../nodes/identity.js');\nvar Scalar = require('../nodes/Scalar.js');\n\nconst defaultTagPrefix = 'tag:yaml.org,2002:';\nfunction findTagObject(value, tagName, tags) {\n    if (tagName) {\n        const match = tags.filter(t => t.tag === tagName);\n        const tagObj = match.find(t => !t.format) ?? match[0];\n        if (!tagObj)\n            throw new Error(`Tag ${tagName} not found`);\n        return tagObj;\n    }\n    return tags.find(t => t.identify?.(value) && !t.format);\n}\nfunction createNode(value, tagName, ctx) {\n    if (identity.isDocument(value))\n        value = value.contents;\n    if (identity.isNode(value))\n        return value;\n    if (identity.isPair(value)) {\n        const map = ctx.schema[identity.MAP].createNode?.(ctx.schema, null, ctx);\n        map.items.push(value);\n        return map;\n    }\n    if (value instanceof String ||\n        value instanceof Number ||\n        value instanceof Boolean ||\n        (typeof BigInt !== 'undefined' && value instanceof BigInt) // not supported everywhere\n    ) {\n        // https://tc39.es/ecma262/#sec-serializejsonproperty\n        value = value.valueOf();\n    }\n    const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;\n    // Detect duplicate references to the same object & use Alias nodes for all\n    // after first. The `ref` wrapper allows for circular references to resolve.\n    let ref = undefined;\n    if (aliasDuplicateObjects && value && typeof value === 'object') {\n        ref = sourceObjects.get(value);\n        if (ref) {\n            ref.anchor ?? (ref.anchor = onAnchor(value));\n            return new Alias.Alias(ref.anchor);\n        }\n        else {\n            ref = { anchor: null, node: null };\n            sourceObjects.set(value, ref);\n        }\n    }\n    if (tagName?.startsWith('!!'))\n        tagName = defaultTagPrefix + tagName.slice(2);\n    let tagObj = findTagObject(value, tagName, schema.tags);\n    if (!tagObj) {\n        if (value && typeof value.toJSON === 'function') {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n            value = value.toJSON();\n        }\n        if (!value || typeof value !== 'object') {\n            const node = new Scalar.Scalar(value);\n            if (ref)\n                ref.node = node;\n            return node;\n        }\n        tagObj =\n            value instanceof Map\n                ? schema[identity.MAP]\n                : Symbol.iterator in Object(value)\n                    ? schema[identity.SEQ]\n                    : schema[identity.MAP];\n    }\n    if (onTagObj) {\n        onTagObj(tagObj);\n        delete ctx.onTagObj;\n    }\n    const node = tagObj?.createNode\n        ? tagObj.createNode(ctx.schema, value, ctx)\n        : typeof tagObj?.nodeClass?.from === 'function'\n            ? tagObj.nodeClass.from(ctx.schema, value, ctx)\n            : new Scalar.Scalar(value);\n    if (tagName)\n        node.tag = tagName;\n    else if (!tagObj.default)\n        node.tag = tagObj.tag;\n    if (ref)\n        ref.node = node;\n    return node;\n}\n\nexports.createNode = createNode;\n", "'use strict';\n\nvar createNode = require('../doc/createNode.js');\nvar identity = require('./identity.js');\nvar Node = require('./Node.js');\n\nfunction collectionFromPath(schema, path, value) {\n    let v = value;\n    for (let i = path.length - 1; i >= 0; --i) {\n        const k = path[i];\n        if (typeof k === 'number' && Number.isInteger(k) && k >= 0) {\n            const a = [];\n            a[k] = v;\n            v = a;\n        }\n        else {\n            v = new Map([[k, v]]);\n        }\n    }\n    return createNode.createNode(v, undefined, {\n        aliasDuplicateObjects: false,\n        keepUndefined: false,\n        onAnchor: () => {\n            throw new Error('This should not happen, please report a bug.');\n        },\n        schema,\n        sourceObjects: new Map()\n    });\n}\n// Type guard is intentionally a little wrong so as to be more useful,\n// as it does not cover untypable empty non-string iterables (e.g. []).\nconst isEmptyPath = (path) => path == null ||\n    (typeof path === 'object' && !!path[Symbol.iterator]().next().done);\nclass Collection extends Node.NodeBase {\n    constructor(type, schema) {\n        super(type);\n        Object.defineProperty(this, 'schema', {\n            value: schema,\n            configurable: true,\n            enumerable: false,\n            writable: true\n        });\n    }\n    /**\n     * Create a copy of this collection.\n     *\n     * @param schema - If defined, overwrites the original's schema\n     */\n    clone(schema) {\n        const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));\n        if (schema)\n            copy.schema = schema;\n        copy.items = copy.items.map(it => identity.isNode(it) || identity.isPair(it) ? it.clone(schema) : it);\n        if (this.range)\n            copy.range = this.range.slice();\n        return copy;\n    }\n    /**\n     * Adds a value to the collection. For `!!map` and `!!omap` the value must\n     * be a Pair instance or a `{ key, value }` object, which may not have a key\n     * that already exists in the map.\n     */\n    addIn(path, value) {\n        if (isEmptyPath(path))\n            this.add(value);\n        else {\n            const [key, ...rest] = path;\n            const node = this.get(key, true);\n            if (identity.isCollection(node))\n                node.addIn(rest, value);\n            else if (node === undefined && this.schema)\n                this.set(key, collectionFromPath(this.schema, rest, value));\n            else\n                throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);\n        }\n    }\n    /**\n     * Removes a value from the collection.\n     * @returns `true` if the item was found and removed.\n     */\n    deleteIn(path) {\n        const [key, ...rest] = path;\n        if (rest.length === 0)\n            return this.delete(key);\n        const node = this.get(key, true);\n        if (identity.isCollection(node))\n            return node.deleteIn(rest);\n        else\n            throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);\n    }\n    /**\n     * Returns item at `key`, or `undefined` if not found. By default unwraps\n     * scalar values from their surrounding node; to disable set `keepScalar` to\n     * `true` (collections are always returned intact).\n     */\n    getIn(path, keepScalar) {\n        const [key, ...rest] = path;\n        const node = this.get(key, true);\n        if (rest.length === 0)\n            return !keepScalar && identity.isScalar(node) ? node.value : node;\n        else\n            return identity.isCollection(node) ? node.getIn(rest, keepScalar) : undefined;\n    }\n    hasAllNullValues(allowScalar) {\n        return this.items.every(node => {\n            if (!identity.isPair(node))\n                return false;\n            const n = node.value;\n            return (n == null ||\n                (allowScalar &&\n                    identity.isScalar(n) &&\n                    n.value == null &&\n                    !n.commentBefore &&\n                    !n.comment &&\n                    !n.tag));\n        });\n    }\n    /**\n     * Checks if the collection includes a value with the key `key`.\n     */\n    hasIn(path) {\n        const [key, ...rest] = path;\n        if (rest.length === 0)\n            return this.has(key);\n        const node = this.get(key, true);\n        return identity.isCollection(node) ? node.hasIn(rest) : false;\n    }\n    /**\n     * Sets a value in this collection. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     */\n    setIn(path, value) {\n        const [key, ...rest] = path;\n        if (rest.length === 0) {\n            this.set(key, value);\n        }\n        else {\n            const node = this.get(key, true);\n            if (identity.isCollection(node))\n                node.setIn(rest, value);\n            else if (node === undefined && this.schema)\n                this.set(key, collectionFromPath(this.schema, rest, value));\n            else\n                throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);\n        }\n    }\n}\n\nexports.Collection = Collection;\nexports.collectionFromPath = collectionFromPath;\nexports.isEmptyPath = isEmptyPath;\n", "'use strict';\n\n/**\n * Stringifies a comment.\n *\n * Empty comment lines are left empty,\n * lines consisting of a single space are replaced by `#`,\n * and all other lines are prefixed with a `#`.\n */\nconst stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, '#');\nfunction indentComment(comment, indent) {\n    if (/^\\n+$/.test(comment))\n        return comment.substring(1);\n    return indent ? comment.replace(/^(?! *$)/gm, indent) : comment;\n}\nconst lineComment = (str, indent, comment) => str.endsWith('\\n')\n    ? indentComment(comment, indent)\n    : comment.includes('\\n')\n        ? '\\n' + indentComment(comment, indent)\n        : (str.endsWith(' ') ? '' : ' ') + comment;\n\nexports.indentComment = indentComment;\nexports.lineComment = lineComment;\nexports.stringifyComment = stringifyComment;\n", "'use strict';\n\nconst FOLD_FLOW = 'flow';\nconst FOLD_BLOCK = 'block';\nconst FOLD_QUOTED = 'quoted';\n/**\n * Tries to keep input at up to `lineWidth` characters, splitting only on spaces\n * not followed by newlines or spaces unless `mode` is `'quoted'`. Lines are\n * terminated with `\\n` and started with `indent`.\n */\nfunction foldFlowLines(text, indent, mode = 'flow', { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {\n    if (!lineWidth || lineWidth < 0)\n        return text;\n    if (lineWidth < minContentWidth)\n        minContentWidth = 0;\n    const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);\n    if (text.length <= endStep)\n        return text;\n    const folds = [];\n    const escapedFolds = {};\n    let end = lineWidth - indent.length;\n    if (typeof indentAtStart === 'number') {\n        if (indentAtStart > lineWidth - Math.max(2, minContentWidth))\n            folds.push(0);\n        else\n            end = lineWidth - indentAtStart;\n    }\n    let split = undefined;\n    let prev = undefined;\n    let overflow = false;\n    let i = -1;\n    let escStart = -1;\n    let escEnd = -1;\n    if (mode === FOLD_BLOCK) {\n        i = consumeMoreIndentedLines(text, i, indent.length);\n        if (i !== -1)\n            end = i + endStep;\n    }\n    for (let ch; (ch = text[(i += 1)]);) {\n        if (mode === FOLD_QUOTED && ch === '\\\\') {\n            escStart = i;\n            switch (text[i + 1]) {\n                case 'x':\n                    i += 3;\n                    break;\n                case 'u':\n                    i += 5;\n                    break;\n                case 'U':\n                    i += 9;\n                    break;\n                default:\n                    i += 1;\n            }\n            escEnd = i;\n        }\n        if (ch === '\\n') {\n            if (mode === FOLD_BLOCK)\n                i = consumeMoreIndentedLines(text, i, indent.length);\n            end = i + indent.length + endStep;\n            split = undefined;\n        }\n        else {\n            if (ch === ' ' &&\n                prev &&\n                prev !== ' ' &&\n                prev !== '\\n' &&\n                prev !== '\\t') {\n                // space surrounded by non-space can be replaced with newline + indent\n                const next = text[i + 1];\n                if (next && next !== ' ' && next !== '\\n' && next !== '\\t')\n                    split = i;\n            }\n            if (i >= end) {\n                if (split) {\n                    folds.push(split);\n                    end = split + endStep;\n                    split = undefined;\n                }\n                else if (mode === FOLD_QUOTED) {\n                    // white-space collected at end may stretch past lineWidth\n                    while (prev === ' ' || prev === '\\t') {\n                        prev = ch;\n                        ch = text[(i += 1)];\n                        overflow = true;\n                    }\n                    // Account for newline escape, but don't break preceding escape\n                    const j = i > escEnd + 1 ? i - 2 : escStart - 1;\n                    // Bail out if lineWidth & minContentWidth are shorter than an escape string\n                    if (escapedFolds[j])\n                        return text;\n                    folds.push(j);\n                    escapedFolds[j] = true;\n                    end = j + endStep;\n                    split = undefined;\n                }\n                else {\n                    overflow = true;\n                }\n            }\n        }\n        prev = ch;\n    }\n    if (overflow && onOverflow)\n        onOverflow();\n    if (folds.length === 0)\n        return text;\n    if (onFold)\n        onFold();\n    let res = text.slice(0, folds[0]);\n    for (let i = 0; i < folds.length; ++i) {\n        const fold = folds[i];\n        const end = folds[i + 1] || text.length;\n        if (fold === 0)\n            res = `\\n${indent}${text.slice(0, end)}`;\n        else {\n            if (mode === FOLD_QUOTED && escapedFolds[fold])\n                res += `${text[fold]}\\\\`;\n            res += `\\n${indent}${text.slice(fold + 1, end)}`;\n        }\n    }\n    return res;\n}\n/**\n * Presumes `i + 1` is at the start of a line\n * @returns index of last newline in more-indented block\n */\nfunction consumeMoreIndentedLines(text, i, indent) {\n    let end = i;\n    let start = i + 1;\n    let ch = text[start];\n    while (ch === ' ' || ch === '\\t') {\n        if (i < start + indent) {\n            ch = text[++i];\n        }\n        else {\n            do {\n                ch = text[++i];\n            } while (ch && ch !== '\\n');\n            end = i;\n            start = i + 1;\n            ch = text[start];\n        }\n    }\n    return end;\n}\n\nexports.FOLD_BLOCK = FOLD_BLOCK;\nexports.FOLD_FLOW = FOLD_FLOW;\nexports.FOLD_QUOTED = FOLD_QUOTED;\nexports.foldFlowLines = foldFlowLines;\n", "'use strict';\n\nvar Scalar = require('../nodes/Scalar.js');\nvar foldFlowLines = require('./foldFlowLines.js');\n\nconst getFoldOptions = (ctx, isBlock) => ({\n    indentAtStart: isBlock ? ctx.indent.length : ctx.indentAtStart,\n    lineWidth: ctx.options.lineWidth,\n    minContentWidth: ctx.options.minContentWidth\n});\n// Also checks for lines starting with %, as parsing the output as YAML 1.1 will\n// presume that's starting a new document.\nconst containsDocumentMarker = (str) => /^(%|---|\\.\\.\\.)/m.test(str);\nfunction lineLengthOverLimit(str, lineWidth, indentLength) {\n    if (!lineWidth || lineWidth < 0)\n        return false;\n    const limit = lineWidth - indentLength;\n    const strLen = str.length;\n    if (strLen <= limit)\n        return false;\n    for (let i = 0, start = 0; i < strLen; ++i) {\n        if (str[i] === '\\n') {\n            if (i - start > limit)\n                return true;\n            start = i + 1;\n            if (strLen - start <= limit)\n                return false;\n        }\n    }\n    return true;\n}\nfunction doubleQuotedString(value, ctx) {\n    const json = JSON.stringify(value);\n    if (ctx.options.doubleQuotedAsJSON)\n        return json;\n    const { implicitKey } = ctx;\n    const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;\n    const indent = ctx.indent || (containsDocumentMarker(value) ? '  ' : '');\n    let str = '';\n    let start = 0;\n    for (let i = 0, ch = json[i]; ch; ch = json[++i]) {\n        if (ch === ' ' && json[i + 1] === '\\\\' && json[i + 2] === 'n') {\n            // space before newline needs to be escaped to not be folded\n            str += json.slice(start, i) + '\\\\ ';\n            i += 1;\n            start = i;\n            ch = '\\\\';\n        }\n        if (ch === '\\\\')\n            switch (json[i + 1]) {\n                case 'u':\n                    {\n                        str += json.slice(start, i);\n                        const code = json.substr(i + 2, 4);\n                        switch (code) {\n                            case '0000':\n                                str += '\\\\0';\n                                break;\n                            case '0007':\n                                str += '\\\\a';\n                                break;\n                            case '000b':\n                                str += '\\\\v';\n                                break;\n                            case '001b':\n                                str += '\\\\e';\n                                break;\n                            case '0085':\n                                str += '\\\\N';\n                                break;\n                            case '00a0':\n                                str += '\\\\_';\n                                break;\n                            case '2028':\n                                str += '\\\\L';\n                                break;\n                            case '2029':\n                                str += '\\\\P';\n                                break;\n                            default:\n                                if (code.substr(0, 2) === '00')\n                                    str += '\\\\x' + code.substr(2);\n                                else\n                                    str += json.substr(i, 6);\n                        }\n                        i += 5;\n                        start = i + 1;\n                    }\n                    break;\n                case 'n':\n                    if (implicitKey ||\n                        json[i + 2] === '\"' ||\n                        json.length < minMultiLineLength) {\n                        i += 1;\n                    }\n                    else {\n                        // folding will eat first newline\n                        str += json.slice(start, i) + '\\n\\n';\n                        while (json[i + 2] === '\\\\' &&\n                            json[i + 3] === 'n' &&\n                            json[i + 4] !== '\"') {\n                            str += '\\n';\n                            i += 2;\n                        }\n                        str += indent;\n                        // space after newline needs to be escaped to not be folded\n                        if (json[i + 2] === ' ')\n                            str += '\\\\';\n                        i += 1;\n                        start = i + 1;\n                    }\n                    break;\n                default:\n                    i += 1;\n            }\n    }\n    str = start ? str + json.slice(start) : json;\n    return implicitKey\n        ? str\n        : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));\n}\nfunction singleQuotedString(value, ctx) {\n    if (ctx.options.singleQuote === false ||\n        (ctx.implicitKey && value.includes('\\n')) ||\n        /[ \\t]\\n|\\n[ \\t]/.test(value) // single quoted string can't have leading or trailing whitespace around newline\n    )\n        return doubleQuotedString(value, ctx);\n    const indent = ctx.indent || (containsDocumentMarker(value) ? '  ' : '');\n    const res = \"'\" + value.replace(/'/g, \"''\").replace(/\\n+/g, `$&\\n${indent}`) + \"'\";\n    return ctx.implicitKey\n        ? res\n        : foldFlowLines.foldFlowLines(res, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));\n}\nfunction quotedString(value, ctx) {\n    const { singleQuote } = ctx.options;\n    let qs;\n    if (singleQuote === false)\n        qs = doubleQuotedString;\n    else {\n        const hasDouble = value.includes('\"');\n        const hasSingle = value.includes(\"'\");\n        if (hasDouble && !hasSingle)\n            qs = singleQuotedString;\n        else if (hasSingle && !hasDouble)\n            qs = doubleQuotedString;\n        else\n            qs = singleQuote ? singleQuotedString : doubleQuotedString;\n    }\n    return qs(value, ctx);\n}\n// The negative lookbehind avoids a polynomial search,\n// but isn't supported yet on Safari: https://caniuse.com/js-regexp-lookbehind\nlet blockEndNewlines;\ntry {\n    blockEndNewlines = new RegExp('(^|(?<!\\n))\\n+(?!\\n|$)', 'g');\n}\ncatch {\n    blockEndNewlines = /\\n+(?!\\n|$)/g;\n}\nfunction blockString({ comment, type, value }, ctx, onComment, onChompKeep) {\n    const { blockQuote, commentString, lineWidth } = ctx.options;\n    // 1. Block can't end in whitespace unless the last line is non-empty.\n    // 2. Strings consisting of only whitespace are best rendered explicitly.\n    if (!blockQuote || /\\n[\\t ]+$/.test(value)) {\n        return quotedString(value, ctx);\n    }\n    const indent = ctx.indent ||\n        (ctx.forceBlockIndent || containsDocumentMarker(value) ? '  ' : '');\n    const literal = blockQuote === 'literal'\n        ? true\n        : blockQuote === 'folded' || type === Scalar.Scalar.BLOCK_FOLDED\n            ? false\n            : type === Scalar.Scalar.BLOCK_LITERAL\n                ? true\n                : !lineLengthOverLimit(value, lineWidth, indent.length);\n    if (!value)\n        return literal ? '|\\n' : '>\\n';\n    // determine chomping from whitespace at value end\n    let chomp;\n    let endStart;\n    for (endStart = value.length; endStart > 0; --endStart) {\n        const ch = value[endStart - 1];\n        if (ch !== '\\n' && ch !== '\\t' && ch !== ' ')\n            break;\n    }\n    let end = value.substring(endStart);\n    const endNlPos = end.indexOf('\\n');\n    if (endNlPos === -1) {\n        chomp = '-'; // strip\n    }\n    else if (value === end || endNlPos !== end.length - 1) {\n        chomp = '+'; // keep\n        if (onChompKeep)\n            onChompKeep();\n    }\n    else {\n        chomp = ''; // clip\n    }\n    if (end) {\n        value = value.slice(0, -end.length);\n        if (end[end.length - 1] === '\\n')\n            end = end.slice(0, -1);\n        end = end.replace(blockEndNewlines, `$&${indent}`);\n    }\n    // determine indent indicator from whitespace at value start\n    let startWithSpace = false;\n    let startEnd;\n    let startNlPos = -1;\n    for (startEnd = 0; startEnd < value.length; ++startEnd) {\n        const ch = value[startEnd];\n        if (ch === ' ')\n            startWithSpace = true;\n        else if (ch === '\\n')\n            startNlPos = startEnd;\n        else\n            break;\n    }\n    let start = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);\n    if (start) {\n        value = value.substring(start.length);\n        start = start.replace(/\\n+/g, `$&${indent}`);\n    }\n    const indentSize = indent ? '2' : '1'; // root is at -1\n    // Leading | or > is added later\n    let header = (startWithSpace ? indentSize : '') + chomp;\n    if (comment) {\n        header += ' ' + commentString(comment.replace(/ ?[\\r\\n]+/g, ' '));\n        if (onComment)\n            onComment();\n    }\n    if (!literal) {\n        const foldedValue = value\n            .replace(/\\n+/g, '\\n$&')\n            .replace(/(?:^|\\n)([\\t ].*)(?:([\\n\\t ]*)\\n(?![\\n\\t ]))?/g, '$1$2') // more-indented lines aren't folded\n            //                ^ more-ind. ^ empty     ^ capture next empty lines only at end of indent\n            .replace(/\\n+/g, `$&${indent}`);\n        let literalFallback = false;\n        const foldOptions = getFoldOptions(ctx, true);\n        if (blockQuote !== 'folded' && type !== Scalar.Scalar.BLOCK_FOLDED) {\n            foldOptions.onOverflow = () => {\n                literalFallback = true;\n            };\n        }\n        const body = foldFlowLines.foldFlowLines(`${start}${foldedValue}${end}`, indent, foldFlowLines.FOLD_BLOCK, foldOptions);\n        if (!literalFallback)\n            return `>${header}\\n${indent}${body}`;\n    }\n    value = value.replace(/\\n+/g, `$&${indent}`);\n    return `|${header}\\n${indent}${start}${value}${end}`;\n}\nfunction plainString(item, ctx, onComment, onChompKeep) {\n    const { type, value } = item;\n    const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;\n    if ((implicitKey && value.includes('\\n')) ||\n        (inFlow && /[[\\]{},]/.test(value))) {\n        return quotedString(value, ctx);\n    }\n    if (/^[\\n\\t ,[\\]{}#&*!|>'\"%@`]|^[?-]$|^[?-][ \\t]|[\\n:][ \\t]|[ \\t]\\n|[\\n\\t ]#|[\\n\\t :]$/.test(value)) {\n        // not allowed:\n        // - '-' or '?'\n        // - start with an indicator character (except [?:-]) or /[?-] /\n        // - '\\n ', ': ' or ' \\n' anywhere\n        // - '#' not preceded by a non-space char\n        // - end with ' ' or ':'\n        return implicitKey || inFlow || !value.includes('\\n')\n            ? quotedString(value, ctx)\n            : blockString(item, ctx, onComment, onChompKeep);\n    }\n    if (!implicitKey &&\n        !inFlow &&\n        type !== Scalar.Scalar.PLAIN &&\n        value.includes('\\n')) {\n        // Where allowed & type not set explicitly, prefer block style for multiline strings\n        return blockString(item, ctx, onComment, onChompKeep);\n    }\n    if (containsDocumentMarker(value)) {\n        if (indent === '') {\n            ctx.forceBlockIndent = true;\n            return blockString(item, ctx, onComment, onChompKeep);\n        }\n        else if (implicitKey && indent === indentStep) {\n            return quotedString(value, ctx);\n        }\n    }\n    const str = value.replace(/\\n+/g, `$&\\n${indent}`);\n    // Verify that output will be parsed as a string, as e.g. plain numbers and\n    // booleans get parsed with those types in v1.2 (e.g. '42', 'true' & '0.9e-3'),\n    // and others in v1.1.\n    if (actualString) {\n        const test = (tag) => tag.default && tag.tag !== 'tag:yaml.org,2002:str' && tag.test?.test(str);\n        const { compat, tags } = ctx.doc.schema;\n        if (tags.some(test) || compat?.some(test))\n            return quotedString(value, ctx);\n    }\n    return implicitKey\n        ? str\n        : foldFlowLines.foldFlowLines(str, indent, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));\n}\nfunction stringifyString(item, ctx, onComment, onChompKeep) {\n    const { implicitKey, inFlow } = ctx;\n    const ss = typeof item.value === 'string'\n        ? item\n        : Object.assign({}, item, { value: String(item.value) });\n    let { type } = item;\n    if (type !== Scalar.Scalar.QUOTE_DOUBLE) {\n        // force double quotes on control characters & unpaired surrogates\n        if (/[\\x00-\\x08\\x0b-\\x1f\\x7f-\\x9f\\u{D800}-\\u{DFFF}]/u.test(ss.value))\n            type = Scalar.Scalar.QUOTE_DOUBLE;\n    }\n    const _stringify = (_type) => {\n        switch (_type) {\n            case Scalar.Scalar.BLOCK_FOLDED:\n            case Scalar.Scalar.BLOCK_LITERAL:\n                return implicitKey || inFlow\n                    ? quotedString(ss.value, ctx) // blocks are not valid inside flow containers\n                    : blockString(ss, ctx, onComment, onChompKeep);\n            case Scalar.Scalar.QUOTE_DOUBLE:\n                return doubleQuotedString(ss.value, ctx);\n            case Scalar.Scalar.QUOTE_SINGLE:\n                return singleQuotedString(ss.value, ctx);\n            case Scalar.Scalar.PLAIN:\n                return plainString(ss, ctx, onComment, onChompKeep);\n            default:\n                return null;\n        }\n    };\n    let res = _stringify(type);\n    if (res === null) {\n        const { defaultKeyType, defaultStringType } = ctx.options;\n        const t = (implicitKey && defaultKeyType) || defaultStringType;\n        res = _stringify(t);\n        if (res === null)\n            throw new Error(`Unsupported default string type ${t}`);\n    }\n    return res;\n}\n\nexports.stringifyString = stringifyString;\n", "'use strict';\n\nvar anchors = require('../doc/anchors.js');\nvar identity = require('../nodes/identity.js');\nvar stringifyComment = require('./stringifyComment.js');\nvar stringifyString = require('./stringifyString.js');\n\nfunction createStringifyContext(doc, options) {\n    const opt = Object.assign({\n        blockQuote: true,\n        commentString: stringifyComment.stringifyComment,\n        defaultKeyType: null,\n        defaultStringType: 'PLAIN',\n        directives: null,\n        doubleQuotedAsJSON: false,\n        doubleQuotedMinMultiLineLength: 40,\n        falseStr: 'false',\n        flowCollectionPadding: true,\n        indentSeq: true,\n        lineWidth: 80,\n        minContentWidth: 20,\n        nullStr: 'null',\n        simpleKeys: false,\n        singleQuote: null,\n        trailingComma: false,\n        trueStr: 'true',\n        verifyAliasOrder: true\n    }, doc.schema.toStringOptions, options);\n    let inFlow;\n    switch (opt.collectionStyle) {\n        case 'block':\n            inFlow = false;\n            break;\n        case 'flow':\n            inFlow = true;\n            break;\n        default:\n            inFlow = null;\n    }\n    return {\n        anchors: new Set(),\n        doc,\n        flowCollectionPadding: opt.flowCollectionPadding ? ' ' : '',\n        indent: '',\n        indentStep: typeof opt.indent === 'number' ? ' '.repeat(opt.indent) : '  ',\n        inFlow,\n        options: opt\n    };\n}\nfunction getTagObject(tags, item) {\n    if (item.tag) {\n        const match = tags.filter(t => t.tag === item.tag);\n        if (match.length > 0)\n            return match.find(t => t.format === item.format) ?? match[0];\n    }\n    let tagObj = undefined;\n    let obj;\n    if (identity.isScalar(item)) {\n        obj = item.value;\n        let match = tags.filter(t => t.identify?.(obj));\n        if (match.length > 1) {\n            const testMatch = match.filter(t => t.test);\n            if (testMatch.length > 0)\n                match = testMatch;\n        }\n        tagObj =\n            match.find(t => t.format === item.format) ?? match.find(t => !t.format);\n    }\n    else {\n        obj = item;\n        tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass);\n    }\n    if (!tagObj) {\n        const name = obj?.constructor?.name ?? (obj === null ? 'null' : typeof obj);\n        throw new Error(`Tag not resolved for ${name} value`);\n    }\n    return tagObj;\n}\n// needs to be called before value stringifier to allow for circular anchor refs\nfunction stringifyProps(node, tagObj, { anchors: anchors$1, doc }) {\n    if (!doc.directives)\n        return '';\n    const props = [];\n    const anchor = (identity.isScalar(node) || identity.isCollection(node)) && node.anchor;\n    if (anchor && anchors.anchorIsValid(anchor)) {\n        anchors$1.add(anchor);\n        props.push(`&${anchor}`);\n    }\n    const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);\n    if (tag)\n        props.push(doc.directives.tagString(tag));\n    return props.join(' ');\n}\nfunction stringify(item, ctx, onComment, onChompKeep) {\n    if (identity.isPair(item))\n        return item.toString(ctx, onComment, onChompKeep);\n    if (identity.isAlias(item)) {\n        if (ctx.doc.directives)\n            return item.toString(ctx);\n        if (ctx.resolvedAliases?.has(item)) {\n            throw new TypeError(`Cannot stringify circular structure without alias nodes`);\n        }\n        else {\n            if (ctx.resolvedAliases)\n                ctx.resolvedAliases.add(item);\n            else\n                ctx.resolvedAliases = new Set([item]);\n            item = item.resolve(ctx.doc);\n        }\n    }\n    let tagObj = undefined;\n    const node = identity.isNode(item)\n        ? item\n        : ctx.doc.createNode(item, { onTagObj: o => (tagObj = o) });\n    tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));\n    const props = stringifyProps(node, tagObj, ctx);\n    if (props.length > 0)\n        ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;\n    const str = typeof tagObj.stringify === 'function'\n        ? tagObj.stringify(node, ctx, onComment, onChompKeep)\n        : identity.isScalar(node)\n            ? stringifyString.stringifyString(node, ctx, onComment, onChompKeep)\n            : node.toString(ctx, onComment, onChompKeep);\n    if (!props)\n        return str;\n    return identity.isScalar(node) || str[0] === '{' || str[0] === '['\n        ? `${props} ${str}`\n        : `${props}\\n${ctx.indent}${str}`;\n}\n\nexports.createStringifyContext = createStringifyContext;\nexports.stringify = stringify;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar Scalar = require('../nodes/Scalar.js');\nvar stringify = require('./stringify.js');\nvar stringifyComment = require('./stringifyComment.js');\n\nfunction stringifyPair({ key, value }, ctx, onComment, onChompKeep) {\n    const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;\n    let keyComment = (identity.isNode(key) && key.comment) || null;\n    if (simpleKeys) {\n        if (keyComment) {\n            throw new Error('With simple keys, key nodes cannot have comments');\n        }\n        if (identity.isCollection(key) || (!identity.isNode(key) && typeof key === 'object')) {\n            const msg = 'With simple keys, collection cannot be used as a key value';\n            throw new Error(msg);\n        }\n    }\n    let explicitKey = !simpleKeys &&\n        (!key ||\n            (keyComment && value == null && !ctx.inFlow) ||\n            identity.isCollection(key) ||\n            (identity.isScalar(key)\n                ? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL\n                : typeof key === 'object'));\n    ctx = Object.assign({}, ctx, {\n        allNullValues: false,\n        implicitKey: !explicitKey && (simpleKeys || !allNullValues),\n        indent: indent + indentStep\n    });\n    let keyCommentDone = false;\n    let chompKeep = false;\n    let str = stringify.stringify(key, ctx, () => (keyCommentDone = true), () => (chompKeep = true));\n    if (!explicitKey && !ctx.inFlow && str.length > 1024) {\n        if (simpleKeys)\n            throw new Error('With simple keys, single line scalar must not span more than 1024 characters');\n        explicitKey = true;\n    }\n    if (ctx.inFlow) {\n        if (allNullValues || value == null) {\n            if (keyCommentDone && onComment)\n                onComment();\n            return str === '' ? '?' : explicitKey ? `? ${str}` : str;\n        }\n    }\n    else if ((allNullValues && !simpleKeys) || (value == null && explicitKey)) {\n        str = `? ${str}`;\n        if (keyComment && !keyCommentDone) {\n            str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));\n        }\n        else if (chompKeep && onChompKeep)\n            onChompKeep();\n        return str;\n    }\n    if (keyCommentDone)\n        keyComment = null;\n    if (explicitKey) {\n        if (keyComment)\n            str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));\n        str = `? ${str}\\n${indent}:`;\n    }\n    else {\n        str = `${str}:`;\n        if (keyComment)\n            str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));\n    }\n    let vsb, vcb, valueComment;\n    if (identity.isNode(value)) {\n        vsb = !!value.spaceBefore;\n        vcb = value.commentBefore;\n        valueComment = value.comment;\n    }\n    else {\n        vsb = false;\n        vcb = null;\n        valueComment = null;\n        if (value && typeof value === 'object')\n            value = doc.createNode(value);\n    }\n    ctx.implicitKey = false;\n    if (!explicitKey && !keyComment && identity.isScalar(value))\n        ctx.indentAtStart = str.length + 1;\n    chompKeep = false;\n    if (!indentSeq &&\n        indentStep.length >= 2 &&\n        !ctx.inFlow &&\n        !explicitKey &&\n        identity.isSeq(value) &&\n        !value.flow &&\n        !value.tag &&\n        !value.anchor) {\n        // If indentSeq === false, consider '- ' as part of indentation where possible\n        ctx.indent = ctx.indent.substring(2);\n    }\n    let valueCommentDone = false;\n    const valueStr = stringify.stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));\n    let ws = ' ';\n    if (keyComment || vsb || vcb) {\n        ws = vsb ? '\\n' : '';\n        if (vcb) {\n            const cs = commentString(vcb);\n            ws += `\\n${stringifyComment.indentComment(cs, ctx.indent)}`;\n        }\n        if (valueStr === '' && !ctx.inFlow) {\n            if (ws === '\\n' && valueComment)\n                ws = '\\n\\n';\n        }\n        else {\n            ws += `\\n${ctx.indent}`;\n        }\n    }\n    else if (!explicitKey && identity.isCollection(value)) {\n        const vs0 = valueStr[0];\n        const nl0 = valueStr.indexOf('\\n');\n        const hasNewline = nl0 !== -1;\n        const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;\n        if (hasNewline || !flow) {\n            let hasPropsLine = false;\n            if (hasNewline && (vs0 === '&' || vs0 === '!')) {\n                let sp0 = valueStr.indexOf(' ');\n                if (vs0 === '&' &&\n                    sp0 !== -1 &&\n                    sp0 < nl0 &&\n                    valueStr[sp0 + 1] === '!') {\n                    sp0 = valueStr.indexOf(' ', sp0 + 1);\n                }\n                if (sp0 === -1 || nl0 < sp0)\n                    hasPropsLine = true;\n            }\n            if (!hasPropsLine)\n                ws = `\\n${ctx.indent}`;\n        }\n    }\n    else if (valueStr === '' || valueStr[0] === '\\n') {\n        ws = '';\n    }\n    str += ws + valueStr;\n    if (ctx.inFlow) {\n        if (valueCommentDone && onComment)\n            onComment();\n    }\n    else if (valueComment && !valueCommentDone) {\n        str += stringifyComment.lineComment(str, ctx.indent, commentString(valueComment));\n    }\n    else if (chompKeep && onChompKeep) {\n        onChompKeep();\n    }\n    return str;\n}\n\nexports.stringifyPair = stringifyPair;\n", "'use strict';\n\nvar node_process = require('process');\n\nfunction debug(logLevel, ...messages) {\n    if (logLevel === 'debug')\n        console.log(...messages);\n}\nfunction warn(logLevel, warning) {\n    if (logLevel === 'debug' || logLevel === 'warn') {\n        if (typeof node_process.emitWarning === 'function')\n            node_process.emitWarning(warning);\n        else\n            console.warn(warning);\n    }\n}\n\nexports.debug = debug;\nexports.warn = warn;\n", "'use strict';\n\nvar identity = require('../../nodes/identity.js');\nvar Scalar = require('../../nodes/Scalar.js');\n\n// If the value associated with a merge key is a single mapping node, each of\n// its key/value pairs is inserted into the current mapping, unless the key\n// already exists in it. If the value associated with the merge key is a\n// sequence, then this sequence is expected to contain mapping nodes and each\n// of these nodes is merged in turn according to its order in the sequence.\n// Keys in mapping nodes earlier in the sequence override keys specified in\n// later mapping nodes. -- http://yaml.org/type/merge.html\nconst MERGE_KEY = '<<';\nconst merge = {\n    identify: value => value === MERGE_KEY ||\n        (typeof value === 'symbol' && value.description === MERGE_KEY),\n    default: 'key',\n    tag: 'tag:yaml.org,2002:merge',\n    test: /^<<$/,\n    resolve: () => Object.assign(new Scalar.Scalar(Symbol(MERGE_KEY)), {\n        addToJSMap: addMergeToJSMap\n    }),\n    stringify: () => MERGE_KEY\n};\nconst isMergeKey = (ctx, key) => (merge.identify(key) ||\n    (identity.isScalar(key) &&\n        (!key.type || key.type === Scalar.Scalar.PLAIN) &&\n        merge.identify(key.value))) &&\n    ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default);\nfunction addMergeToJSMap(ctx, map, value) {\n    const source = resolveAliasValue(ctx, value);\n    if (identity.isSeq(source))\n        for (const it of source.items)\n            mergeValue(ctx, map, it);\n    else if (Array.isArray(source))\n        for (const it of source)\n            mergeValue(ctx, map, it);\n    else\n        mergeValue(ctx, map, source);\n}\nfunction mergeValue(ctx, map, value) {\n    const source = resolveAliasValue(ctx, value);\n    if (!identity.isMap(source))\n        throw new Error('Merge sources must be maps or map aliases');\n    const srcMap = source.toJSON(null, ctx, Map);\n    for (const [key, value] of srcMap) {\n        if (map instanceof Map) {\n            if (!map.has(key))\n                map.set(key, value);\n        }\n        else if (map instanceof Set) {\n            map.add(key);\n        }\n        else if (!Object.prototype.hasOwnProperty.call(map, key)) {\n            Object.defineProperty(map, key, {\n                value,\n                writable: true,\n                enumerable: true,\n                configurable: true\n            });\n        }\n    }\n    return map;\n}\nfunction resolveAliasValue(ctx, value) {\n    return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;\n}\n\nexports.addMergeToJSMap = addMergeToJSMap;\nexports.isMergeKey = isMergeKey;\nexports.merge = merge;\n", "'use strict';\n\nvar log = require('../log.js');\nvar merge = require('../schema/yaml-1.1/merge.js');\nvar stringify = require('../stringify/stringify.js');\nvar identity = require('./identity.js');\nvar toJS = require('./toJS.js');\n\nfunction addPairToJSMap(ctx, map, { key, value }) {\n    if (identity.isNode(key) && key.addToJSMap)\n        key.addToJSMap(ctx, map, value);\n    // TODO: Should drop this special case for bare << handling\n    else if (merge.isMergeKey(ctx, key))\n        merge.addMergeToJSMap(ctx, map, value);\n    else {\n        const jsKey = toJS.toJS(key, '', ctx);\n        if (map instanceof Map) {\n            map.set(jsKey, toJS.toJS(value, jsKey, ctx));\n        }\n        else if (map instanceof Set) {\n            map.add(jsKey);\n        }\n        else {\n            const stringKey = stringifyKey(key, jsKey, ctx);\n            const jsValue = toJS.toJS(value, stringKey, ctx);\n            if (stringKey in map)\n                Object.defineProperty(map, stringKey, {\n                    value: jsValue,\n                    writable: true,\n                    enumerable: true,\n                    configurable: true\n                });\n            else\n                map[stringKey] = jsValue;\n        }\n    }\n    return map;\n}\nfunction stringifyKey(key, jsKey, ctx) {\n    if (jsKey === null)\n        return '';\n    // eslint-disable-next-line @typescript-eslint/no-base-to-string\n    if (typeof jsKey !== 'object')\n        return String(jsKey);\n    if (identity.isNode(key) && ctx?.doc) {\n        const strCtx = stringify.createStringifyContext(ctx.doc, {});\n        strCtx.anchors = new Set();\n        for (const node of ctx.anchors.keys())\n            strCtx.anchors.add(node.anchor);\n        strCtx.inFlow = true;\n        strCtx.inStringifyKey = true;\n        const strKey = key.toString(strCtx);\n        if (!ctx.mapKeyWarned) {\n            let jsonStr = JSON.stringify(strKey);\n            if (jsonStr.length > 40)\n                jsonStr = jsonStr.substring(0, 36) + '...\"';\n            log.warn(ctx.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${jsonStr}. Set mapAsMap: true to use object keys.`);\n            ctx.mapKeyWarned = true;\n        }\n        return strKey;\n    }\n    return JSON.stringify(jsKey);\n}\n\nexports.addPairToJSMap = addPairToJSMap;\n", "'use strict';\n\nvar createNode = require('../doc/createNode.js');\nvar stringifyPair = require('../stringify/stringifyPair.js');\nvar addPairToJSMap = require('./addPairToJSMap.js');\nvar identity = require('./identity.js');\n\nfunction createPair(key, value, ctx) {\n    const k = createNode.createNode(key, undefined, ctx);\n    const v = createNode.createNode(value, undefined, ctx);\n    return new Pair(k, v);\n}\nclass Pair {\n    constructor(key, value = null) {\n        Object.defineProperty(this, identity.NODE_TYPE, { value: identity.PAIR });\n        this.key = key;\n        this.value = value;\n    }\n    clone(schema) {\n        let { key, value } = this;\n        if (identity.isNode(key))\n            key = key.clone(schema);\n        if (identity.isNode(value))\n            value = value.clone(schema);\n        return new Pair(key, value);\n    }\n    toJSON(_, ctx) {\n        const pair = ctx?.mapAsMap ? new Map() : {};\n        return addPairToJSMap.addPairToJSMap(ctx, pair, this);\n    }\n    toString(ctx, onComment, onChompKeep) {\n        return ctx?.doc\n            ? stringifyPair.stringifyPair(this, ctx, onComment, onChompKeep)\n            : JSON.stringify(this);\n    }\n}\n\nexports.Pair = Pair;\nexports.createPair = createPair;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar stringify = require('./stringify.js');\nvar stringifyComment = require('./stringifyComment.js');\n\nfunction stringifyCollection(collection, ctx, options) {\n    const flow = ctx.inFlow ?? collection.flow;\n    const stringify = flow ? stringifyFlowCollection : stringifyBlockCollection;\n    return stringify(collection, ctx, options);\n}\nfunction stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {\n    const { indent, options: { commentString } } = ctx;\n    const itemCtx = Object.assign({}, ctx, { indent: itemIndent, type: null });\n    let chompKeep = false; // flag for the preceding node's status\n    const lines = [];\n    for (let i = 0; i < items.length; ++i) {\n        const item = items[i];\n        let comment = null;\n        if (identity.isNode(item)) {\n            if (!chompKeep && item.spaceBefore)\n                lines.push('');\n            addCommentBefore(ctx, lines, item.commentBefore, chompKeep);\n            if (item.comment)\n                comment = item.comment;\n        }\n        else if (identity.isPair(item)) {\n            const ik = identity.isNode(item.key) ? item.key : null;\n            if (ik) {\n                if (!chompKeep && ik.spaceBefore)\n                    lines.push('');\n                addCommentBefore(ctx, lines, ik.commentBefore, chompKeep);\n            }\n        }\n        chompKeep = false;\n        let str = stringify.stringify(item, itemCtx, () => (comment = null), () => (chompKeep = true));\n        if (comment)\n            str += stringifyComment.lineComment(str, itemIndent, commentString(comment));\n        if (chompKeep && comment)\n            chompKeep = false;\n        lines.push(blockItemPrefix + str);\n    }\n    let str;\n    if (lines.length === 0) {\n        str = flowChars.start + flowChars.end;\n    }\n    else {\n        str = lines[0];\n        for (let i = 1; i < lines.length; ++i) {\n            const line = lines[i];\n            str += line ? `\\n${indent}${line}` : '\\n';\n        }\n    }\n    if (comment) {\n        str += '\\n' + stringifyComment.indentComment(commentString(comment), indent);\n        if (onComment)\n            onComment();\n    }\n    else if (chompKeep && onChompKeep)\n        onChompKeep();\n    return str;\n}\nfunction stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {\n    const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;\n    itemIndent += indentStep;\n    const itemCtx = Object.assign({}, ctx, {\n        indent: itemIndent,\n        inFlow: true,\n        type: null\n    });\n    let reqNewline = false;\n    let linesAtValue = 0;\n    const lines = [];\n    for (let i = 0; i < items.length; ++i) {\n        const item = items[i];\n        let comment = null;\n        if (identity.isNode(item)) {\n            if (item.spaceBefore)\n                lines.push('');\n            addCommentBefore(ctx, lines, item.commentBefore, false);\n            if (item.comment)\n                comment = item.comment;\n        }\n        else if (identity.isPair(item)) {\n            const ik = identity.isNode(item.key) ? item.key : null;\n            if (ik) {\n                if (ik.spaceBefore)\n                    lines.push('');\n                addCommentBefore(ctx, lines, ik.commentBefore, false);\n                if (ik.comment)\n                    reqNewline = true;\n            }\n            const iv = identity.isNode(item.value) ? item.value : null;\n            if (iv) {\n                if (iv.comment)\n                    comment = iv.comment;\n                if (iv.commentBefore)\n                    reqNewline = true;\n            }\n            else if (item.value == null && ik?.comment) {\n                comment = ik.comment;\n            }\n        }\n        if (comment)\n            reqNewline = true;\n        let str = stringify.stringify(item, itemCtx, () => (comment = null));\n        reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\\n'));\n        if (i < items.length - 1) {\n            str += ',';\n        }\n        else if (ctx.options.trailingComma) {\n            if (ctx.options.lineWidth > 0) {\n                reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +\n                    (str.length + 2) >\n                    ctx.options.lineWidth);\n            }\n            if (reqNewline) {\n                str += ',';\n            }\n        }\n        if (comment)\n            str += stringifyComment.lineComment(str, itemIndent, commentString(comment));\n        lines.push(str);\n        linesAtValue = lines.length;\n    }\n    const { start, end } = flowChars;\n    if (lines.length === 0) {\n        return start + end;\n    }\n    else {\n        if (!reqNewline) {\n            const len = lines.reduce((sum, line) => sum + line.length + 2, 2);\n            reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;\n        }\n        if (reqNewline) {\n            let str = start;\n            for (const line of lines)\n                str += line ? `\\n${indentStep}${indent}${line}` : '\\n';\n            return `${str}\\n${indent}${end}`;\n        }\n        else {\n            return `${start}${fcPadding}${lines.join(' ')}${fcPadding}${end}`;\n        }\n    }\n}\nfunction addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) {\n    if (comment && chompKeep)\n        comment = comment.replace(/^\\n+/, '');\n    if (comment) {\n        const ic = stringifyComment.indentComment(commentString(comment), indent);\n        lines.push(ic.trimStart()); // Avoid double indent on first line\n    }\n}\n\nexports.stringifyCollection = stringifyCollection;\n", "'use strict';\n\nvar stringifyCollection = require('../stringify/stringifyCollection.js');\nvar addPairToJSMap = require('./addPairToJSMap.js');\nvar Collection = require('./Collection.js');\nvar identity = require('./identity.js');\nvar Pair = require('./Pair.js');\nvar Scalar = require('./Scalar.js');\n\nfunction findPair(items, key) {\n    const k = identity.isScalar(key) ? key.value : key;\n    for (const it of items) {\n        if (identity.isPair(it)) {\n            if (it.key === key || it.key === k)\n                return it;\n            if (identity.isScalar(it.key) && it.key.value === k)\n                return it;\n        }\n    }\n    return undefined;\n}\nclass YAMLMap extends Collection.Collection {\n    static get tagName() {\n        return 'tag:yaml.org,2002:map';\n    }\n    constructor(schema) {\n        super(identity.MAP, schema);\n        this.items = [];\n    }\n    /**\n     * A generic collection parsing method that can be extended\n     * to other node classes that inherit from YAMLMap\n     */\n    static from(schema, obj, ctx) {\n        const { keepUndefined, replacer } = ctx;\n        const map = new this(schema);\n        const add = (key, value) => {\n            if (typeof replacer === 'function')\n                value = replacer.call(obj, key, value);\n            else if (Array.isArray(replacer) && !replacer.includes(key))\n                return;\n            if (value !== undefined || keepUndefined)\n                map.items.push(Pair.createPair(key, value, ctx));\n        };\n        if (obj instanceof Map) {\n            for (const [key, value] of obj)\n                add(key, value);\n        }\n        else if (obj && typeof obj === 'object') {\n            for (const key of Object.keys(obj))\n                add(key, obj[key]);\n        }\n        if (typeof schema.sortMapEntries === 'function') {\n            map.items.sort(schema.sortMapEntries);\n        }\n        return map;\n    }\n    /**\n     * Adds a value to the collection.\n     *\n     * @param overwrite - If not set `true`, using a key that is already in the\n     *   collection will throw. Otherwise, overwrites the previous value.\n     */\n    add(pair, overwrite) {\n        let _pair;\n        if (identity.isPair(pair))\n            _pair = pair;\n        else if (!pair || typeof pair !== 'object' || !('key' in pair)) {\n            // In TypeScript, this never happens.\n            _pair = new Pair.Pair(pair, pair?.value);\n        }\n        else\n            _pair = new Pair.Pair(pair.key, pair.value);\n        const prev = findPair(this.items, _pair.key);\n        const sortEntries = this.schema?.sortMapEntries;\n        if (prev) {\n            if (!overwrite)\n                throw new Error(`Key ${_pair.key} already set`);\n            // For scalars, keep the old node & its comments and anchors\n            if (identity.isScalar(prev.value) && Scalar.isScalarValue(_pair.value))\n                prev.value.value = _pair.value;\n            else\n                prev.value = _pair.value;\n        }\n        else if (sortEntries) {\n            const i = this.items.findIndex(item => sortEntries(_pair, item) < 0);\n            if (i === -1)\n                this.items.push(_pair);\n            else\n                this.items.splice(i, 0, _pair);\n        }\n        else {\n            this.items.push(_pair);\n        }\n    }\n    delete(key) {\n        const it = findPair(this.items, key);\n        if (!it)\n            return false;\n        const del = this.items.splice(this.items.indexOf(it), 1);\n        return del.length > 0;\n    }\n    get(key, keepScalar) {\n        const it = findPair(this.items, key);\n        const node = it?.value;\n        return (!keepScalar && identity.isScalar(node) ? node.value : node) ?? undefined;\n    }\n    has(key) {\n        return !!findPair(this.items, key);\n    }\n    set(key, value) {\n        this.add(new Pair.Pair(key, value), true);\n    }\n    /**\n     * @param ctx - Conversion context, originally set in Document#toJS()\n     * @param {Class} Type - If set, forces the returned collection type\n     * @returns Instance of Type, Map, or Object\n     */\n    toJSON(_, ctx, Type) {\n        const map = Type ? new Type() : ctx?.mapAsMap ? new Map() : {};\n        if (ctx?.onCreate)\n            ctx.onCreate(map);\n        for (const item of this.items)\n            addPairToJSMap.addPairToJSMap(ctx, map, item);\n        return map;\n    }\n    toString(ctx, onComment, onChompKeep) {\n        if (!ctx)\n            return JSON.stringify(this);\n        for (const item of this.items) {\n            if (!identity.isPair(item))\n                throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);\n        }\n        if (!ctx.allNullValues && this.hasAllNullValues(false))\n            ctx = Object.assign({}, ctx, { allNullValues: true });\n        return stringifyCollection.stringifyCollection(this, ctx, {\n            blockItemPrefix: '',\n            flowChars: { start: '{', end: '}' },\n            itemIndent: ctx.indent || '',\n            onChompKeep,\n            onComment\n        });\n    }\n}\n\nexports.YAMLMap = YAMLMap;\nexports.findPair = findPair;\n", "'use strict';\n\nvar identity = require('../../nodes/identity.js');\nvar YAMLMap = require('../../nodes/YAMLMap.js');\n\nconst map = {\n    collection: 'map',\n    default: true,\n    nodeClass: YAMLMap.YAMLMap,\n    tag: 'tag:yaml.org,2002:map',\n    resolve(map, onError) {\n        if (!identity.isMap(map))\n            onError('Expected a mapping for this tag');\n        return map;\n    },\n    createNode: (schema, obj, ctx) => YAMLMap.YAMLMap.from(schema, obj, ctx)\n};\n\nexports.map = map;\n", "'use strict';\n\nvar createNode = require('../doc/createNode.js');\nvar stringifyCollection = require('../stringify/stringifyCollection.js');\nvar Collection = require('./Collection.js');\nvar identity = require('./identity.js');\nvar Scalar = require('./Scalar.js');\nvar toJS = require('./toJS.js');\n\nclass YAMLSeq extends Collection.Collection {\n    static get tagName() {\n        return 'tag:yaml.org,2002:seq';\n    }\n    constructor(schema) {\n        super(identity.SEQ, schema);\n        this.items = [];\n    }\n    add(value) {\n        this.items.push(value);\n    }\n    /**\n     * Removes a value from the collection.\n     *\n     * `key` must contain a representation of an integer for this to succeed.\n     * It may be wrapped in a `Scalar`.\n     *\n     * @returns `true` if the item was found and removed.\n     */\n    delete(key) {\n        const idx = asItemIndex(key);\n        if (typeof idx !== 'number')\n            return false;\n        const del = this.items.splice(idx, 1);\n        return del.length > 0;\n    }\n    get(key, keepScalar) {\n        const idx = asItemIndex(key);\n        if (typeof idx !== 'number')\n            return undefined;\n        const it = this.items[idx];\n        return !keepScalar && identity.isScalar(it) ? it.value : it;\n    }\n    /**\n     * Checks if the collection includes a value with the key `key`.\n     *\n     * `key` must contain a representation of an integer for this to succeed.\n     * It may be wrapped in a `Scalar`.\n     */\n    has(key) {\n        const idx = asItemIndex(key);\n        return typeof idx === 'number' && idx < this.items.length;\n    }\n    /**\n     * Sets a value in this collection. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     *\n     * If `key` does not contain a representation of an integer, this will throw.\n     * It may be wrapped in a `Scalar`.\n     */\n    set(key, value) {\n        const idx = asItemIndex(key);\n        if (typeof idx !== 'number')\n            throw new Error(`Expected a valid index, not ${key}.`);\n        const prev = this.items[idx];\n        if (identity.isScalar(prev) && Scalar.isScalarValue(value))\n            prev.value = value;\n        else\n            this.items[idx] = value;\n    }\n    toJSON(_, ctx) {\n        const seq = [];\n        if (ctx?.onCreate)\n            ctx.onCreate(seq);\n        let i = 0;\n        for (const item of this.items)\n            seq.push(toJS.toJS(item, String(i++), ctx));\n        return seq;\n    }\n    toString(ctx, onComment, onChompKeep) {\n        if (!ctx)\n            return JSON.stringify(this);\n        return stringifyCollection.stringifyCollection(this, ctx, {\n            blockItemPrefix: '- ',\n            flowChars: { start: '[', end: ']' },\n            itemIndent: (ctx.indent || '') + '  ',\n            onChompKeep,\n            onComment\n        });\n    }\n    static from(schema, obj, ctx) {\n        const { replacer } = ctx;\n        const seq = new this(schema);\n        if (obj && Symbol.iterator in Object(obj)) {\n            let i = 0;\n            for (let it of obj) {\n                if (typeof replacer === 'function') {\n                    const key = obj instanceof Set ? it : String(i++);\n                    it = replacer.call(obj, key, it);\n                }\n                seq.items.push(createNode.createNode(it, undefined, ctx));\n            }\n        }\n        return seq;\n    }\n}\nfunction asItemIndex(key) {\n    let idx = identity.isScalar(key) ? key.value : key;\n    if (idx && typeof idx === 'string')\n        idx = Number(idx);\n    return typeof idx === 'number' && Number.isInteger(idx) && idx >= 0\n        ? idx\n        : null;\n}\n\nexports.YAMLSeq = YAMLSeq;\n", "'use strict';\n\nvar identity = require('../../nodes/identity.js');\nvar YAMLSeq = require('../../nodes/YAMLSeq.js');\n\nconst seq = {\n    collection: 'seq',\n    default: true,\n    nodeClass: YAMLSeq.YAMLSeq,\n    tag: 'tag:yaml.org,2002:seq',\n    resolve(seq, onError) {\n        if (!identity.isSeq(seq))\n            onError('Expected a sequence for this tag');\n        return seq;\n    },\n    createNode: (schema, obj, ctx) => YAMLSeq.YAMLSeq.from(schema, obj, ctx)\n};\n\nexports.seq = seq;\n", "'use strict';\n\nvar stringifyString = require('../../stringify/stringifyString.js');\n\nconst string = {\n    identify: value => typeof value === 'string',\n    default: true,\n    tag: 'tag:yaml.org,2002:str',\n    resolve: str => str,\n    stringify(item, ctx, onComment, onChompKeep) {\n        ctx = Object.assign({ actualString: true }, ctx);\n        return stringifyString.stringifyString(item, ctx, onComment, onChompKeep);\n    }\n};\n\nexports.string = string;\n", "'use strict';\n\nvar Scalar = require('../../nodes/Scalar.js');\n\nconst nullTag = {\n    identify: value => value == null,\n    createNode: () => new Scalar.Scalar(null),\n    default: true,\n    tag: 'tag:yaml.org,2002:null',\n    test: /^(?:~|[Nn]ull|NULL)?$/,\n    resolve: () => new Scalar.Scalar(null),\n    stringify: ({ source }, ctx) => typeof source === 'string' && nullTag.test.test(source)\n        ? source\n        : ctx.options.nullStr\n};\n\nexports.nullTag = nullTag;\n", "'use strict';\n\nvar Scalar = require('../../nodes/Scalar.js');\n\nconst boolTag = {\n    identify: value => typeof value === 'boolean',\n    default: true,\n    tag: 'tag:yaml.org,2002:bool',\n    test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,\n    resolve: str => new Scalar.Scalar(str[0] === 't' || str[0] === 'T'),\n    stringify({ source, value }, ctx) {\n        if (source && boolTag.test.test(source)) {\n            const sv = source[0] === 't' || source[0] === 'T';\n            if (value === sv)\n                return source;\n        }\n        return value ? ctx.options.trueStr : ctx.options.falseStr;\n    }\n};\n\nexports.boolTag = boolTag;\n", "'use strict';\n\nfunction stringifyNumber({ format, minFractionDigits, tag, value }) {\n    if (typeof value === 'bigint')\n        return String(value);\n    const num = typeof value === 'number' ? value : Number(value);\n    if (!isFinite(num))\n        return isNaN(num) ? '.nan' : num < 0 ? '-.inf' : '.inf';\n    let n = Object.is(value, -0) ? '-0' : JSON.stringify(value);\n    if (!format &&\n        minFractionDigits &&\n        (!tag || tag === 'tag:yaml.org,2002:float') &&\n        /^-?\\d/.test(n) &&\n        !n.includes('e')) {\n        let i = n.indexOf('.');\n        if (i < 0) {\n            i = n.length;\n            n += '.';\n        }\n        let d = minFractionDigits - (n.length - i - 1);\n        while (d-- > 0)\n            n += '0';\n    }\n    return n;\n}\n\nexports.stringifyNumber = stringifyNumber;\n", "'use strict';\n\nvar Scalar = require('../../nodes/Scalar.js');\nvar stringifyNumber = require('../../stringify/stringifyNumber.js');\n\nconst floatNaN = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^(?:[-+]?\\.(?:inf|Inf|INF)|\\.nan|\\.NaN|\\.NAN)$/,\n    resolve: str => str.slice(-3).toLowerCase() === 'nan'\n        ? NaN\n        : str[0] === '-'\n            ? Number.NEGATIVE_INFINITY\n            : Number.POSITIVE_INFINITY,\n    stringify: stringifyNumber.stringifyNumber\n};\nconst floatExp = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    format: 'EXP',\n    test: /^[-+]?(?:\\.[0-9]+|[0-9]+(?:\\.[0-9]*)?)[eE][-+]?[0-9]+$/,\n    resolve: str => parseFloat(str),\n    stringify(node) {\n        const num = Number(node.value);\n        return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);\n    }\n};\nconst float = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^[-+]?(?:\\.[0-9]+|[0-9]+\\.[0-9]*)$/,\n    resolve(str) {\n        const node = new Scalar.Scalar(parseFloat(str));\n        const dot = str.indexOf('.');\n        if (dot !== -1 && str[str.length - 1] === '0')\n            node.minFractionDigits = str.length - dot - 1;\n        return node;\n    },\n    stringify: stringifyNumber.stringifyNumber\n};\n\nexports.float = float;\nexports.floatExp = floatExp;\nexports.floatNaN = floatNaN;\n", "'use strict';\n\nvar stringifyNumber = require('../../stringify/stringifyNumber.js');\n\nconst intIdentify = (value) => typeof value === 'bigint' || Number.isInteger(value);\nconst intResolve = (str, offset, radix, { intAsBigInt }) => (intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix));\nfunction intStringify(node, radix, prefix) {\n    const { value } = node;\n    if (intIdentify(value) && value >= 0)\n        return prefix + value.toString(radix);\n    return stringifyNumber.stringifyNumber(node);\n}\nconst intOct = {\n    identify: value => intIdentify(value) && value >= 0,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'OCT',\n    test: /^0o[0-7]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt),\n    stringify: node => intStringify(node, 8, '0o')\n};\nconst int = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    test: /^[-+]?[0-9]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),\n    stringify: stringifyNumber.stringifyNumber\n};\nconst intHex = {\n    identify: value => intIdentify(value) && value >= 0,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'HEX',\n    test: /^0x[0-9a-fA-F]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),\n    stringify: node => intStringify(node, 16, '0x')\n};\n\nexports.int = int;\nexports.intHex = intHex;\nexports.intOct = intOct;\n", "'use strict';\n\nvar map = require('../common/map.js');\nvar _null = require('../common/null.js');\nvar seq = require('../common/seq.js');\nvar string = require('../common/string.js');\nvar bool = require('./bool.js');\nvar float = require('./float.js');\nvar int = require('./int.js');\n\nconst schema = [\n    map.map,\n    seq.seq,\n    string.string,\n    _null.nullTag,\n    bool.boolTag,\n    int.intOct,\n    int.int,\n    int.intHex,\n    float.floatNaN,\n    float.floatExp,\n    float.float\n];\n\nexports.schema = schema;\n", "'use strict';\n\nvar Scalar = require('../../nodes/Scalar.js');\nvar map = require('../common/map.js');\nvar seq = require('../common/seq.js');\n\nfunction intIdentify(value) {\n    return typeof value === 'bigint' || Number.isInteger(value);\n}\nconst stringifyJSON = ({ value }) => JSON.stringify(value);\nconst jsonScalars = [\n    {\n        identify: value => typeof value === 'string',\n        default: true,\n        tag: 'tag:yaml.org,2002:str',\n        resolve: str => str,\n        stringify: stringifyJSON\n    },\n    {\n        identify: value => value == null,\n        createNode: () => new Scalar.Scalar(null),\n        default: true,\n        tag: 'tag:yaml.org,2002:null',\n        test: /^null$/,\n        resolve: () => null,\n        stringify: stringifyJSON\n    },\n    {\n        identify: value => typeof value === 'boolean',\n        default: true,\n        tag: 'tag:yaml.org,2002:bool',\n        test: /^true$|^false$/,\n        resolve: str => str === 'true',\n        stringify: stringifyJSON\n    },\n    {\n        identify: intIdentify,\n        default: true,\n        tag: 'tag:yaml.org,2002:int',\n        test: /^-?(?:0|[1-9][0-9]*)$/,\n        resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),\n        stringify: ({ value }) => intIdentify(value) ? value.toString() : JSON.stringify(value)\n    },\n    {\n        identify: value => typeof value === 'number',\n        default: true,\n        tag: 'tag:yaml.org,2002:float',\n        test: /^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,\n        resolve: str => parseFloat(str),\n        stringify: stringifyJSON\n    }\n];\nconst jsonError = {\n    default: true,\n    tag: '',\n    test: /^/,\n    resolve(str, onError) {\n        onError(`Unresolved plain scalar ${JSON.stringify(str)}`);\n        return str;\n    }\n};\nconst schema = [map.map, seq.seq].concat(jsonScalars, jsonError);\n\nexports.schema = schema;\n", "'use strict';\n\nvar node_buffer = require('buffer');\nvar Scalar = require('../../nodes/Scalar.js');\nvar stringifyString = require('../../stringify/stringifyString.js');\n\nconst binary = {\n    identify: value => value instanceof Uint8Array, // Buffer inherits from Uint8Array\n    default: false,\n    tag: 'tag:yaml.org,2002:binary',\n    /**\n     * Returns a Buffer in node and an Uint8Array in browsers\n     *\n     * To use the resulting buffer as an image, you'll want to do something like:\n     *\n     *   const blob = new Blob([buffer], { type: 'image/jpeg' })\n     *   document.querySelector('#photo').src = URL.createObjectURL(blob)\n     */\n    resolve(src, onError) {\n        if (typeof node_buffer.Buffer === 'function') {\n            return node_buffer.Buffer.from(src, 'base64');\n        }\n        else if (typeof atob === 'function') {\n            // On IE 11, atob() can't handle newlines\n            const str = atob(src.replace(/[\\n\\r]/g, ''));\n            const buffer = new Uint8Array(str.length);\n            for (let i = 0; i < str.length; ++i)\n                buffer[i] = str.charCodeAt(i);\n            return buffer;\n        }\n        else {\n            onError('This environment does not support reading binary tags; either Buffer or atob is required');\n            return src;\n        }\n    },\n    stringify({ comment, type, value }, ctx, onComment, onChompKeep) {\n        if (!value)\n            return '';\n        const buf = value; // checked earlier by binary.identify()\n        let str;\n        if (typeof node_buffer.Buffer === 'function') {\n            str =\n                buf instanceof node_buffer.Buffer\n                    ? buf.toString('base64')\n                    : node_buffer.Buffer.from(buf.buffer).toString('base64');\n        }\n        else if (typeof btoa === 'function') {\n            let s = '';\n            for (let i = 0; i < buf.length; ++i)\n                s += String.fromCharCode(buf[i]);\n            str = btoa(s);\n        }\n        else {\n            throw new Error('This environment does not support writing binary tags; either Buffer or btoa is required');\n        }\n        type ?? (type = Scalar.Scalar.BLOCK_LITERAL);\n        if (type !== Scalar.Scalar.QUOTE_DOUBLE) {\n            const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);\n            const n = Math.ceil(str.length / lineWidth);\n            const lines = new Array(n);\n            for (let i = 0, o = 0; i < n; ++i, o += lineWidth) {\n                lines[i] = str.substr(o, lineWidth);\n            }\n            str = lines.join(type === Scalar.Scalar.BLOCK_LITERAL ? '\\n' : ' ');\n        }\n        return stringifyString.stringifyString({ comment, type, value: str }, ctx, onComment, onChompKeep);\n    }\n};\n\nexports.binary = binary;\n", "'use strict';\n\nvar identity = require('../../nodes/identity.js');\nvar Pair = require('../../nodes/Pair.js');\nvar Scalar = require('../../nodes/Scalar.js');\nvar YAMLSeq = require('../../nodes/YAMLSeq.js');\n\nfunction resolvePairs(seq, onError) {\n    if (identity.isSeq(seq)) {\n        for (let i = 0; i < seq.items.length; ++i) {\n            let item = seq.items[i];\n            if (identity.isPair(item))\n                continue;\n            else if (identity.isMap(item)) {\n                if (item.items.length > 1)\n                    onError('Each pair must have its own sequence indicator');\n                const pair = item.items[0] || new Pair.Pair(new Scalar.Scalar(null));\n                if (item.commentBefore)\n                    pair.key.commentBefore = pair.key.commentBefore\n                        ? `${item.commentBefore}\\n${pair.key.commentBefore}`\n                        : item.commentBefore;\n                if (item.comment) {\n                    const cn = pair.value ?? pair.key;\n                    cn.comment = cn.comment\n                        ? `${item.comment}\\n${cn.comment}`\n                        : item.comment;\n                }\n                item = pair;\n            }\n            seq.items[i] = identity.isPair(item) ? item : new Pair.Pair(item);\n        }\n    }\n    else\n        onError('Expected a sequence for this tag');\n    return seq;\n}\nfunction createPairs(schema, iterable, ctx) {\n    const { replacer } = ctx;\n    const pairs = new YAMLSeq.YAMLSeq(schema);\n    pairs.tag = 'tag:yaml.org,2002:pairs';\n    let i = 0;\n    if (iterable && Symbol.iterator in Object(iterable))\n        for (let it of iterable) {\n            if (typeof replacer === 'function')\n                it = replacer.call(iterable, String(i++), it);\n            let key, value;\n            if (Array.isArray(it)) {\n                if (it.length === 2) {\n                    key = it[0];\n                    value = it[1];\n                }\n                else\n                    throw new TypeError(`Expected [key, value] tuple: ${it}`);\n            }\n            else if (it && it instanceof Object) {\n                const keys = Object.keys(it);\n                if (keys.length === 1) {\n                    key = keys[0];\n                    value = it[key];\n                }\n                else {\n                    throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`);\n                }\n            }\n            else {\n                key = it;\n            }\n            pairs.items.push(Pair.createPair(key, value, ctx));\n        }\n    return pairs;\n}\nconst pairs = {\n    collection: 'seq',\n    default: false,\n    tag: 'tag:yaml.org,2002:pairs',\n    resolve: resolvePairs,\n    createNode: createPairs\n};\n\nexports.createPairs = createPairs;\nexports.pairs = pairs;\nexports.resolvePairs = resolvePairs;\n", "'use strict';\n\nvar identity = require('../../nodes/identity.js');\nvar toJS = require('../../nodes/toJS.js');\nvar YAMLMap = require('../../nodes/YAMLMap.js');\nvar YAMLSeq = require('../../nodes/YAMLSeq.js');\nvar pairs = require('./pairs.js');\n\nclass YAMLOMap extends YAMLSeq.YAMLSeq {\n    constructor() {\n        super();\n        this.add = YAMLMap.YAMLMap.prototype.add.bind(this);\n        this.delete = YAMLMap.YAMLMap.prototype.delete.bind(this);\n        this.get = YAMLMap.YAMLMap.prototype.get.bind(this);\n        this.has = YAMLMap.YAMLMap.prototype.has.bind(this);\n        this.set = YAMLMap.YAMLMap.prototype.set.bind(this);\n        this.tag = YAMLOMap.tag;\n    }\n    /**\n     * If `ctx` is given, the return type is actually `Map<unknown, unknown>`,\n     * but TypeScript won't allow widening the signature of a child method.\n     */\n    toJSON(_, ctx) {\n        if (!ctx)\n            return super.toJSON(_);\n        const map = new Map();\n        if (ctx?.onCreate)\n            ctx.onCreate(map);\n        for (const pair of this.items) {\n            let key, value;\n            if (identity.isPair(pair)) {\n                key = toJS.toJS(pair.key, '', ctx);\n                value = toJS.toJS(pair.value, key, ctx);\n            }\n            else {\n                key = toJS.toJS(pair, '', ctx);\n            }\n            if (map.has(key))\n                throw new Error('Ordered maps must not include duplicate keys');\n            map.set(key, value);\n        }\n        return map;\n    }\n    static from(schema, iterable, ctx) {\n        const pairs$1 = pairs.createPairs(schema, iterable, ctx);\n        const omap = new this();\n        omap.items = pairs$1.items;\n        return omap;\n    }\n}\nYAMLOMap.tag = 'tag:yaml.org,2002:omap';\nconst omap = {\n    collection: 'seq',\n    identify: value => value instanceof Map,\n    nodeClass: YAMLOMap,\n    default: false,\n    tag: 'tag:yaml.org,2002:omap',\n    resolve(seq, onError) {\n        const pairs$1 = pairs.resolvePairs(seq, onError);\n        const seenKeys = [];\n        for (const { key } of pairs$1.items) {\n            if (identity.isScalar(key)) {\n                if (seenKeys.includes(key.value)) {\n                    onError(`Ordered maps must not include duplicate keys: ${key.value}`);\n                }\n                else {\n                    seenKeys.push(key.value);\n                }\n            }\n        }\n        return Object.assign(new YAMLOMap(), pairs$1);\n    },\n    createNode: (schema, iterable, ctx) => YAMLOMap.from(schema, iterable, ctx)\n};\n\nexports.YAMLOMap = YAMLOMap;\nexports.omap = omap;\n", "'use strict';\n\nvar Scalar = require('../../nodes/Scalar.js');\n\nfunction boolStringify({ value, source }, ctx) {\n    const boolObj = value ? trueTag : falseTag;\n    if (source && boolObj.test.test(source))\n        return source;\n    return value ? ctx.options.trueStr : ctx.options.falseStr;\n}\nconst trueTag = {\n    identify: value => value === true,\n    default: true,\n    tag: 'tag:yaml.org,2002:bool',\n    test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,\n    resolve: () => new Scalar.Scalar(true),\n    stringify: boolStringify\n};\nconst falseTag = {\n    identify: value => value === false,\n    default: true,\n    tag: 'tag:yaml.org,2002:bool',\n    test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,\n    resolve: () => new Scalar.Scalar(false),\n    stringify: boolStringify\n};\n\nexports.falseTag = falseTag;\nexports.trueTag = trueTag;\n", "'use strict';\n\nvar Scalar = require('../../nodes/Scalar.js');\nvar stringifyNumber = require('../../stringify/stringifyNumber.js');\n\nconst floatNaN = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^(?:[-+]?\\.(?:inf|Inf|INF)|\\.nan|\\.NaN|\\.NAN)$/,\n    resolve: (str) => str.slice(-3).toLowerCase() === 'nan'\n        ? NaN\n        : str[0] === '-'\n            ? Number.NEGATIVE_INFINITY\n            : Number.POSITIVE_INFINITY,\n    stringify: stringifyNumber.stringifyNumber\n};\nconst floatExp = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    format: 'EXP',\n    test: /^[-+]?(?:[0-9][0-9_]*)?(?:\\.[0-9_]*)?[eE][-+]?[0-9]+$/,\n    resolve: (str) => parseFloat(str.replace(/_/g, '')),\n    stringify(node) {\n        const num = Number(node.value);\n        return isFinite(num) ? num.toExponential() : stringifyNumber.stringifyNumber(node);\n    }\n};\nconst float = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^[-+]?(?:[0-9][0-9_]*)?\\.[0-9_]*$/,\n    resolve(str) {\n        const node = new Scalar.Scalar(parseFloat(str.replace(/_/g, '')));\n        const dot = str.indexOf('.');\n        if (dot !== -1) {\n            const f = str.substring(dot + 1).replace(/_/g, '');\n            if (f[f.length - 1] === '0')\n                node.minFractionDigits = f.length;\n        }\n        return node;\n    },\n    stringify: stringifyNumber.stringifyNumber\n};\n\nexports.float = float;\nexports.floatExp = floatExp;\nexports.floatNaN = floatNaN;\n", "'use strict';\n\nvar stringifyNumber = require('../../stringify/stringifyNumber.js');\n\nconst intIdentify = (value) => typeof value === 'bigint' || Number.isInteger(value);\nfunction intResolve(str, offset, radix, { intAsBigInt }) {\n    const sign = str[0];\n    if (sign === '-' || sign === '+')\n        offset += 1;\n    str = str.substring(offset).replace(/_/g, '');\n    if (intAsBigInt) {\n        switch (radix) {\n            case 2:\n                str = `0b${str}`;\n                break;\n            case 8:\n                str = `0o${str}`;\n                break;\n            case 16:\n                str = `0x${str}`;\n                break;\n        }\n        const n = BigInt(str);\n        return sign === '-' ? BigInt(-1) * n : n;\n    }\n    const n = parseInt(str, radix);\n    return sign === '-' ? -1 * n : n;\n}\nfunction intStringify(node, radix, prefix) {\n    const { value } = node;\n    if (intIdentify(value)) {\n        const str = value.toString(radix);\n        return value < 0 ? '-' + prefix + str.substr(1) : prefix + str;\n    }\n    return stringifyNumber.stringifyNumber(node);\n}\nconst intBin = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'BIN',\n    test: /^[-+]?0b[0-1_]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),\n    stringify: node => intStringify(node, 2, '0b')\n};\nconst intOct = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'OCT',\n    test: /^[-+]?0[0-7_]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),\n    stringify: node => intStringify(node, 8, '0')\n};\nconst int = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    test: /^[-+]?[0-9][0-9_]*$/,\n    resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),\n    stringify: stringifyNumber.stringifyNumber\n};\nconst intHex = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'HEX',\n    test: /^[-+]?0x[0-9a-fA-F_]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),\n    stringify: node => intStringify(node, 16, '0x')\n};\n\nexports.int = int;\nexports.intBin = intBin;\nexports.intHex = intHex;\nexports.intOct = intOct;\n", "'use strict';\n\nvar identity = require('../../nodes/identity.js');\nvar Pair = require('../../nodes/Pair.js');\nvar YAMLMap = require('../../nodes/YAMLMap.js');\n\nclass YAMLSet extends YAMLMap.YAMLMap {\n    constructor(schema) {\n        super(schema);\n        this.tag = YAMLSet.tag;\n    }\n    add(key) {\n        let pair;\n        if (identity.isPair(key))\n            pair = key;\n        else if (key &&\n            typeof key === 'object' &&\n            'key' in key &&\n            'value' in key &&\n            key.value === null)\n            pair = new Pair.Pair(key.key, null);\n        else\n            pair = new Pair.Pair(key, null);\n        const prev = YAMLMap.findPair(this.items, pair.key);\n        if (!prev)\n            this.items.push(pair);\n    }\n    /**\n     * If `keepPair` is `true`, returns the Pair matching `key`.\n     * Otherwise, returns the value of that Pair's key.\n     */\n    get(key, keepPair) {\n        const pair = YAMLMap.findPair(this.items, key);\n        return !keepPair && identity.isPair(pair)\n            ? identity.isScalar(pair.key)\n                ? pair.key.value\n                : pair.key\n            : pair;\n    }\n    set(key, value) {\n        if (typeof value !== 'boolean')\n            throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`);\n        const prev = YAMLMap.findPair(this.items, key);\n        if (prev && !value) {\n            this.items.splice(this.items.indexOf(prev), 1);\n        }\n        else if (!prev && value) {\n            this.items.push(new Pair.Pair(key));\n        }\n    }\n    toJSON(_, ctx) {\n        return super.toJSON(_, ctx, Set);\n    }\n    toString(ctx, onComment, onChompKeep) {\n        if (!ctx)\n            return JSON.stringify(this);\n        if (this.hasAllNullValues(true))\n            return super.toString(Object.assign({}, ctx, { allNullValues: true }), onComment, onChompKeep);\n        else\n            throw new Error('Set items must all have null values');\n    }\n    static from(schema, iterable, ctx) {\n        const { replacer } = ctx;\n        const set = new this(schema);\n        if (iterable && Symbol.iterator in Object(iterable))\n            for (let value of iterable) {\n                if (typeof replacer === 'function')\n                    value = replacer.call(iterable, value, value);\n                set.items.push(Pair.createPair(value, null, ctx));\n            }\n        return set;\n    }\n}\nYAMLSet.tag = 'tag:yaml.org,2002:set';\nconst set = {\n    collection: 'map',\n    identify: value => value instanceof Set,\n    nodeClass: YAMLSet,\n    default: false,\n    tag: 'tag:yaml.org,2002:set',\n    createNode: (schema, iterable, ctx) => YAMLSet.from(schema, iterable, ctx),\n    resolve(map, onError) {\n        if (identity.isMap(map)) {\n            if (map.hasAllNullValues(true))\n                return Object.assign(new YAMLSet(), map);\n            else\n                onError('Set items must all have null values');\n        }\n        else\n            onError('Expected a mapping for this tag');\n        return map;\n    }\n};\n\nexports.YAMLSet = YAMLSet;\nexports.set = set;\n", "'use strict';\n\nvar stringifyNumber = require('../../stringify/stringifyNumber.js');\n\n/** Internal types handle bigint as number, because TS can't figure it out. */\nfunction parseSexagesimal(str, asBigInt) {\n    const sign = str[0];\n    const parts = sign === '-' || sign === '+' ? str.substring(1) : str;\n    const num = (n) => asBigInt ? BigInt(n) : Number(n);\n    const res = parts\n        .replace(/_/g, '')\n        .split(':')\n        .reduce((res, p) => res * num(60) + num(p), num(0));\n    return (sign === '-' ? num(-1) * res : res);\n}\n/**\n * hhhh:mm:ss.sss\n *\n * Internal types handle bigint as number, because TS can't figure it out.\n */\nfunction stringifySexagesimal(node) {\n    let { value } = node;\n    let num = (n) => n;\n    if (typeof value === 'bigint')\n        num = n => BigInt(n);\n    else if (isNaN(value) || !isFinite(value))\n        return stringifyNumber.stringifyNumber(node);\n    let sign = '';\n    if (value < 0) {\n        sign = '-';\n        value *= num(-1);\n    }\n    const _60 = num(60);\n    const parts = [value % _60]; // seconds, including ms\n    if (value < 60) {\n        parts.unshift(0); // at least one : is required\n    }\n    else {\n        value = (value - parts[0]) / _60;\n        parts.unshift(value % _60); // minutes\n        if (value >= 60) {\n            value = (value - parts[0]) / _60;\n            parts.unshift(value); // hours\n        }\n    }\n    return (sign +\n        parts\n            .map(n => String(n).padStart(2, '0'))\n            .join(':')\n            .replace(/000000\\d*$/, '') // % 60 may introduce error\n    );\n}\nconst intTime = {\n    identify: value => typeof value === 'bigint' || Number.isInteger(value),\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'TIME',\n    test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,\n    resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt),\n    stringify: stringifySexagesimal\n};\nconst floatTime = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    format: 'TIME',\n    test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*$/,\n    resolve: str => parseSexagesimal(str, false),\n    stringify: stringifySexagesimal\n};\nconst timestamp = {\n    identify: value => value instanceof Date,\n    default: true,\n    tag: 'tag:yaml.org,2002:timestamp',\n    // If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part\n    // may be omitted altogether, resulting in a date format. In such a case, the time part is\n    // assumed to be 00:00:00Z (start of day, UTC).\n    test: RegExp('^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})' + // YYYY-Mm-Dd\n        '(?:' + // time is optional\n        '(?:t|T|[ \\\\t]+)' + // t | T | whitespace\n        '([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\\\.[0-9]+)?)' + // Hh:Mm:Ss(.ss)?\n        '(?:[ \\\\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?' + // Z | +5 | -03:30\n        ')?$'),\n    resolve(str) {\n        const match = str.match(timestamp.test);\n        if (!match)\n            throw new Error('!!timestamp expects a date, starting with yyyy-mm-dd');\n        const [, year, month, day, hour, minute, second] = match.map(Number);\n        const millisec = match[7] ? Number((match[7] + '00').substr(1, 3)) : 0;\n        let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);\n        const tz = match[8];\n        if (tz && tz !== 'Z') {\n            let d = parseSexagesimal(tz, false);\n            if (Math.abs(d) < 30)\n                d *= 60;\n            date -= 60000 * d;\n        }\n        return new Date(date);\n    },\n    stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\\.000Z$/, '') ?? ''\n};\n\nexports.floatTime = floatTime;\nexports.intTime = intTime;\nexports.timestamp = timestamp;\n", "'use strict';\n\nvar map = require('../common/map.js');\nvar _null = require('../common/null.js');\nvar seq = require('../common/seq.js');\nvar string = require('../common/string.js');\nvar binary = require('./binary.js');\nvar bool = require('./bool.js');\nvar float = require('./float.js');\nvar int = require('./int.js');\nvar merge = require('./merge.js');\nvar omap = require('./omap.js');\nvar pairs = require('./pairs.js');\nvar set = require('./set.js');\nvar timestamp = require('./timestamp.js');\n\nconst schema = [\n    map.map,\n    seq.seq,\n    string.string,\n    _null.nullTag,\n    bool.trueTag,\n    bool.falseTag,\n    int.intBin,\n    int.intOct,\n    int.int,\n    int.intHex,\n    float.floatNaN,\n    float.floatExp,\n    float.float,\n    binary.binary,\n    merge.merge,\n    omap.omap,\n    pairs.pairs,\n    set.set,\n    timestamp.intTime,\n    timestamp.floatTime,\n    timestamp.timestamp\n];\n\nexports.schema = schema;\n", "'use strict';\n\nvar map = require('./common/map.js');\nvar _null = require('./common/null.js');\nvar seq = require('./common/seq.js');\nvar string = require('./common/string.js');\nvar bool = require('./core/bool.js');\nvar float = require('./core/float.js');\nvar int = require('./core/int.js');\nvar schema = require('./core/schema.js');\nvar schema$1 = require('./json/schema.js');\nvar binary = require('./yaml-1.1/binary.js');\nvar merge = require('./yaml-1.1/merge.js');\nvar omap = require('./yaml-1.1/omap.js');\nvar pairs = require('./yaml-1.1/pairs.js');\nvar schema$2 = require('./yaml-1.1/schema.js');\nvar set = require('./yaml-1.1/set.js');\nvar timestamp = require('./yaml-1.1/timestamp.js');\n\nconst schemas = new Map([\n    ['core', schema.schema],\n    ['failsafe', [map.map, seq.seq, string.string]],\n    ['json', schema$1.schema],\n    ['yaml11', schema$2.schema],\n    ['yaml-1.1', schema$2.schema]\n]);\nconst tagsByName = {\n    binary: binary.binary,\n    bool: bool.boolTag,\n    float: float.float,\n    floatExp: float.floatExp,\n    floatNaN: float.floatNaN,\n    floatTime: timestamp.floatTime,\n    int: int.int,\n    intHex: int.intHex,\n    intOct: int.intOct,\n    intTime: timestamp.intTime,\n    map: map.map,\n    merge: merge.merge,\n    null: _null.nullTag,\n    omap: omap.omap,\n    pairs: pairs.pairs,\n    seq: seq.seq,\n    set: set.set,\n    timestamp: timestamp.timestamp\n};\nconst coreKnownTags = {\n    'tag:yaml.org,2002:binary': binary.binary,\n    'tag:yaml.org,2002:merge': merge.merge,\n    'tag:yaml.org,2002:omap': omap.omap,\n    'tag:yaml.org,2002:pairs': pairs.pairs,\n    'tag:yaml.org,2002:set': set.set,\n    'tag:yaml.org,2002:timestamp': timestamp.timestamp\n};\nfunction getTags(customTags, schemaName, addMergeTag) {\n    const schemaTags = schemas.get(schemaName);\n    if (schemaTags && !customTags) {\n        return addMergeTag && !schemaTags.includes(merge.merge)\n            ? schemaTags.concat(merge.merge)\n            : schemaTags.slice();\n    }\n    let tags = schemaTags;\n    if (!tags) {\n        if (Array.isArray(customTags))\n            tags = [];\n        else {\n            const keys = Array.from(schemas.keys())\n                .filter(key => key !== 'yaml11')\n                .map(key => JSON.stringify(key))\n                .join(', ');\n            throw new Error(`Unknown schema \"${schemaName}\"; use one of ${keys} or define customTags array`);\n        }\n    }\n    if (Array.isArray(customTags)) {\n        for (const tag of customTags)\n            tags = tags.concat(tag);\n    }\n    else if (typeof customTags === 'function') {\n        tags = customTags(tags.slice());\n    }\n    if (addMergeTag)\n        tags = tags.concat(merge.merge);\n    return tags.reduce((tags, tag) => {\n        const tagObj = typeof tag === 'string' ? tagsByName[tag] : tag;\n        if (!tagObj) {\n            const tagName = JSON.stringify(tag);\n            const keys = Object.keys(tagsByName)\n                .map(key => JSON.stringify(key))\n                .join(', ');\n            throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);\n        }\n        if (!tags.includes(tagObj))\n            tags.push(tagObj);\n        return tags;\n    }, []);\n}\n\nexports.coreKnownTags = coreKnownTags;\nexports.getTags = getTags;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar map = require('./common/map.js');\nvar seq = require('./common/seq.js');\nvar string = require('./common/string.js');\nvar tags = require('./tags.js');\n\nconst sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;\nclass Schema {\n    constructor({ compat, customTags, merge, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) {\n        this.compat = Array.isArray(compat)\n            ? tags.getTags(compat, 'compat')\n            : compat\n                ? tags.getTags(null, compat)\n                : null;\n        this.name = (typeof schema === 'string' && schema) || 'core';\n        this.knownTags = resolveKnownTags ? tags.coreKnownTags : {};\n        this.tags = tags.getTags(customTags, this.name, merge);\n        this.toStringOptions = toStringDefaults ?? null;\n        Object.defineProperty(this, identity.MAP, { value: map.map });\n        Object.defineProperty(this, identity.SCALAR, { value: string.string });\n        Object.defineProperty(this, identity.SEQ, { value: seq.seq });\n        // Used by createMap()\n        this.sortMapEntries =\n            typeof sortMapEntries === 'function'\n                ? sortMapEntries\n                : sortMapEntries === true\n                    ? sortMapEntriesByKey\n                    : null;\n    }\n    clone() {\n        const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));\n        copy.tags = this.tags.slice();\n        return copy;\n    }\n}\n\nexports.Schema = Schema;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar stringify = require('./stringify.js');\nvar stringifyComment = require('./stringifyComment.js');\n\nfunction stringifyDocument(doc, options) {\n    const lines = [];\n    let hasDirectives = options.directives === true;\n    if (options.directives !== false && doc.directives) {\n        const dir = doc.directives.toString(doc);\n        if (dir) {\n            lines.push(dir);\n            hasDirectives = true;\n        }\n        else if (doc.directives.docStart)\n            hasDirectives = true;\n    }\n    if (hasDirectives)\n        lines.push('---');\n    const ctx = stringify.createStringifyContext(doc, options);\n    const { commentString } = ctx.options;\n    if (doc.commentBefore) {\n        if (lines.length !== 1)\n            lines.unshift('');\n        const cs = commentString(doc.commentBefore);\n        lines.unshift(stringifyComment.indentComment(cs, ''));\n    }\n    let chompKeep = false;\n    let contentComment = null;\n    if (doc.contents) {\n        if (identity.isNode(doc.contents)) {\n            if (doc.contents.spaceBefore && hasDirectives)\n                lines.push('');\n            if (doc.contents.commentBefore) {\n                const cs = commentString(doc.contents.commentBefore);\n                lines.push(stringifyComment.indentComment(cs, ''));\n            }\n            // top-level block scalars need to be indented if followed by a comment\n            ctx.forceBlockIndent = !!doc.comment;\n            contentComment = doc.contents.comment;\n        }\n        const onChompKeep = contentComment ? undefined : () => (chompKeep = true);\n        let body = stringify.stringify(doc.contents, ctx, () => (contentComment = null), onChompKeep);\n        if (contentComment)\n            body += stringifyComment.lineComment(body, '', commentString(contentComment));\n        if ((body[0] === '|' || body[0] === '>') &&\n            lines[lines.length - 1] === '---') {\n            // Top-level block scalars with a preceding doc marker ought to use the\n            // same line for their header.\n            lines[lines.length - 1] = `--- ${body}`;\n        }\n        else\n            lines.push(body);\n    }\n    else {\n        lines.push(stringify.stringify(doc.contents, ctx));\n    }\n    if (doc.directives?.docEnd) {\n        if (doc.comment) {\n            const cs = commentString(doc.comment);\n            if (cs.includes('\\n')) {\n                lines.push('...');\n                lines.push(stringifyComment.indentComment(cs, ''));\n            }\n            else {\n                lines.push(`... ${cs}`);\n            }\n        }\n        else {\n            lines.push('...');\n        }\n    }\n    else {\n        let dc = doc.comment;\n        if (dc && chompKeep)\n            dc = dc.replace(/^\\n+/, '');\n        if (dc) {\n            if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')\n                lines.push('');\n            lines.push(stringifyComment.indentComment(commentString(dc), ''));\n        }\n    }\n    return lines.join('\\n') + '\\n';\n}\n\nexports.stringifyDocument = stringifyDocument;\n", "'use strict';\n\nvar Alias = require('../nodes/Alias.js');\nvar Collection = require('../nodes/Collection.js');\nvar identity = require('../nodes/identity.js');\nvar Pair = require('../nodes/Pair.js');\nvar toJS = require('../nodes/toJS.js');\nvar Schema = require('../schema/Schema.js');\nvar stringifyDocument = require('../stringify/stringifyDocument.js');\nvar anchors = require('./anchors.js');\nvar applyReviver = require('./applyReviver.js');\nvar createNode = require('./createNode.js');\nvar directives = require('./directives.js');\n\nclass Document {\n    constructor(value, replacer, options) {\n        /** A comment before this Document */\n        this.commentBefore = null;\n        /** A comment immediately after this Document */\n        this.comment = null;\n        /** Errors encountered during parsing. */\n        this.errors = [];\n        /** Warnings encountered during parsing. */\n        this.warnings = [];\n        Object.defineProperty(this, identity.NODE_TYPE, { value: identity.DOC });\n        let _replacer = null;\n        if (typeof replacer === 'function' || Array.isArray(replacer)) {\n            _replacer = replacer;\n        }\n        else if (options === undefined && replacer) {\n            options = replacer;\n            replacer = undefined;\n        }\n        const opt = Object.assign({\n            intAsBigInt: false,\n            keepSourceTokens: false,\n            logLevel: 'warn',\n            prettyErrors: true,\n            strict: true,\n            stringKeys: false,\n            uniqueKeys: true,\n            version: '1.2'\n        }, options);\n        this.options = opt;\n        let { version } = opt;\n        if (options?._directives) {\n            this.directives = options._directives.atDocument();\n            if (this.directives.yaml.explicit)\n                version = this.directives.yaml.version;\n        }\n        else\n            this.directives = new directives.Directives({ version });\n        this.setSchema(version, options);\n        // @ts-expect-error We can't really know that this matches Contents.\n        this.contents =\n            value === undefined ? null : this.createNode(value, _replacer, options);\n    }\n    /**\n     * Create a deep copy of this Document and its contents.\n     *\n     * Custom Node values that inherit from `Object` still refer to their original instances.\n     */\n    clone() {\n        const copy = Object.create(Document.prototype, {\n            [identity.NODE_TYPE]: { value: identity.DOC }\n        });\n        copy.commentBefore = this.commentBefore;\n        copy.comment = this.comment;\n        copy.errors = this.errors.slice();\n        copy.warnings = this.warnings.slice();\n        copy.options = Object.assign({}, this.options);\n        if (this.directives)\n            copy.directives = this.directives.clone();\n        copy.schema = this.schema.clone();\n        // @ts-expect-error We can't really know that this matches Contents.\n        copy.contents = identity.isNode(this.contents)\n            ? this.contents.clone(copy.schema)\n            : this.contents;\n        if (this.range)\n            copy.range = this.range.slice();\n        return copy;\n    }\n    /** Adds a value to the document. */\n    add(value) {\n        if (assertCollection(this.contents))\n            this.contents.add(value);\n    }\n    /** Adds a value to the document. */\n    addIn(path, value) {\n        if (assertCollection(this.contents))\n            this.contents.addIn(path, value);\n    }\n    /**\n     * Create a new `Alias` node, ensuring that the target `node` has the required anchor.\n     *\n     * If `node` already has an anchor, `name` is ignored.\n     * Otherwise, the `node.anchor` value will be set to `name`,\n     * or if an anchor with that name is already present in the document,\n     * `name` will be used as a prefix for a new unique anchor.\n     * If `name` is undefined, the generated anchor will use 'a' as a prefix.\n     */\n    createAlias(node, name) {\n        if (!node.anchor) {\n            const prev = anchors.anchorNames(this);\n            node.anchor =\n                // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n                !name || prev.has(name) ? anchors.findNewAnchor(name || 'a', prev) : name;\n        }\n        return new Alias.Alias(node.anchor);\n    }\n    createNode(value, replacer, options) {\n        let _replacer = undefined;\n        if (typeof replacer === 'function') {\n            value = replacer.call({ '': value }, '', value);\n            _replacer = replacer;\n        }\n        else if (Array.isArray(replacer)) {\n            const keyToStr = (v) => typeof v === 'number' || v instanceof String || v instanceof Number;\n            const asStr = replacer.filter(keyToStr).map(String);\n            if (asStr.length > 0)\n                replacer = replacer.concat(asStr);\n            _replacer = replacer;\n        }\n        else if (options === undefined && replacer) {\n            options = replacer;\n            replacer = undefined;\n        }\n        const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {};\n        const { onAnchor, setAnchors, sourceObjects } = anchors.createNodeAnchors(this, \n        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n        anchorPrefix || 'a');\n        const ctx = {\n            aliasDuplicateObjects: aliasDuplicateObjects ?? true,\n            keepUndefined: keepUndefined ?? false,\n            onAnchor,\n            onTagObj,\n            replacer: _replacer,\n            schema: this.schema,\n            sourceObjects\n        };\n        const node = createNode.createNode(value, tag, ctx);\n        if (flow && identity.isCollection(node))\n            node.flow = true;\n        setAnchors();\n        return node;\n    }\n    /**\n     * Convert a key and a value into a `Pair` using the current schema,\n     * recursively wrapping all values as `Scalar` or `Collection` nodes.\n     */\n    createPair(key, value, options = {}) {\n        const k = this.createNode(key, null, options);\n        const v = this.createNode(value, null, options);\n        return new Pair.Pair(k, v);\n    }\n    /**\n     * Removes a value from the document.\n     * @returns `true` if the item was found and removed.\n     */\n    delete(key) {\n        return assertCollection(this.contents) ? this.contents.delete(key) : false;\n    }\n    /**\n     * Removes a value from the document.\n     * @returns `true` if the item was found and removed.\n     */\n    deleteIn(path) {\n        if (Collection.isEmptyPath(path)) {\n            if (this.contents == null)\n                return false;\n            // @ts-expect-error Presumed impossible if Strict extends false\n            this.contents = null;\n            return true;\n        }\n        return assertCollection(this.contents)\n            ? this.contents.deleteIn(path)\n            : false;\n    }\n    /**\n     * Returns item at `key`, or `undefined` if not found. By default unwraps\n     * scalar values from their surrounding node; to disable set `keepScalar` to\n     * `true` (collections are always returned intact).\n     */\n    get(key, keepScalar) {\n        return identity.isCollection(this.contents)\n            ? this.contents.get(key, keepScalar)\n            : undefined;\n    }\n    /**\n     * Returns item at `path`, or `undefined` if not found. By default unwraps\n     * scalar values from their surrounding node; to disable set `keepScalar` to\n     * `true` (collections are always returned intact).\n     */\n    getIn(path, keepScalar) {\n        if (Collection.isEmptyPath(path))\n            return !keepScalar && identity.isScalar(this.contents)\n                ? this.contents.value\n                : this.contents;\n        return identity.isCollection(this.contents)\n            ? this.contents.getIn(path, keepScalar)\n            : undefined;\n    }\n    /**\n     * Checks if the document includes a value with the key `key`.\n     */\n    has(key) {\n        return identity.isCollection(this.contents) ? this.contents.has(key) : false;\n    }\n    /**\n     * Checks if the document includes a value at `path`.\n     */\n    hasIn(path) {\n        if (Collection.isEmptyPath(path))\n            return this.contents !== undefined;\n        return identity.isCollection(this.contents) ? this.contents.hasIn(path) : false;\n    }\n    /**\n     * Sets a value in this document. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     */\n    set(key, value) {\n        if (this.contents == null) {\n            // @ts-expect-error We can't really know that this matches Contents.\n            this.contents = Collection.collectionFromPath(this.schema, [key], value);\n        }\n        else if (assertCollection(this.contents)) {\n            this.contents.set(key, value);\n        }\n    }\n    /**\n     * Sets a value in this document. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     */\n    setIn(path, value) {\n        if (Collection.isEmptyPath(path)) {\n            // @ts-expect-error We can't really know that this matches Contents.\n            this.contents = value;\n        }\n        else if (this.contents == null) {\n            // @ts-expect-error We can't really know that this matches Contents.\n            this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);\n        }\n        else if (assertCollection(this.contents)) {\n            this.contents.setIn(path, value);\n        }\n    }\n    /**\n     * Change the YAML version and schema used by the document.\n     * A `null` version disables support for directives, explicit tags, anchors, and aliases.\n     * It also requires the `schema` option to be given as a `Schema` instance value.\n     *\n     * Overrides all previously set schema options.\n     */\n    setSchema(version, options = {}) {\n        if (typeof version === 'number')\n            version = String(version);\n        let opt;\n        switch (version) {\n            case '1.1':\n                if (this.directives)\n                    this.directives.yaml.version = '1.1';\n                else\n                    this.directives = new directives.Directives({ version: '1.1' });\n                opt = { resolveKnownTags: false, schema: 'yaml-1.1' };\n                break;\n            case '1.2':\n            case 'next':\n                if (this.directives)\n                    this.directives.yaml.version = version;\n                else\n                    this.directives = new directives.Directives({ version });\n                opt = { resolveKnownTags: true, schema: 'core' };\n                break;\n            case null:\n                if (this.directives)\n                    delete this.directives;\n                opt = null;\n                break;\n            default: {\n                const sv = JSON.stringify(version);\n                throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);\n            }\n        }\n        // Not using `instanceof Schema` to allow for duck typing\n        if (options.schema instanceof Object)\n            this.schema = options.schema;\n        else if (opt)\n            this.schema = new Schema.Schema(Object.assign(opt, options));\n        else\n            throw new Error(`With a null YAML version, the { schema: Schema } option is required`);\n    }\n    // json & jsonArg are only used from toJSON()\n    toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {\n        const ctx = {\n            anchors: new Map(),\n            doc: this,\n            keep: !json,\n            mapAsMap: mapAsMap === true,\n            mapKeyWarned: false,\n            maxAliasCount: typeof maxAliasCount === 'number' ? maxAliasCount : 100\n        };\n        const res = toJS.toJS(this.contents, jsonArg ?? '', ctx);\n        if (typeof onAnchor === 'function')\n            for (const { count, res } of ctx.anchors.values())\n                onAnchor(res, count);\n        return typeof reviver === 'function'\n            ? applyReviver.applyReviver(reviver, { '': res }, '', res)\n            : res;\n    }\n    /**\n     * A JSON representation of the document `contents`.\n     *\n     * @param jsonArg Used by `JSON.stringify` to indicate the array index or\n     *   property name.\n     */\n    toJSON(jsonArg, onAnchor) {\n        return this.toJS({ json: true, jsonArg, mapAsMap: false, onAnchor });\n    }\n    /** A YAML representation of the document. */\n    toString(options = {}) {\n        if (this.errors.length > 0)\n            throw new Error('Document with errors cannot be stringified');\n        if ('indent' in options &&\n            (!Number.isInteger(options.indent) || Number(options.indent) <= 0)) {\n            const s = JSON.stringify(options.indent);\n            throw new Error(`\"indent\" option must be a positive integer, not ${s}`);\n        }\n        return stringifyDocument.stringifyDocument(this, options);\n    }\n}\nfunction assertCollection(contents) {\n    if (identity.isCollection(contents))\n        return true;\n    throw new Error('Expected a YAML collection as document contents');\n}\n\nexports.Document = Document;\n", "'use strict';\n\nclass YAMLError extends Error {\n    constructor(name, pos, code, message) {\n        super();\n        this.name = name;\n        this.code = code;\n        this.message = message;\n        this.pos = pos;\n    }\n}\nclass YAMLParseError extends YAMLError {\n    constructor(pos, code, message) {\n        super('YAMLParseError', pos, code, message);\n    }\n}\nclass YAMLWarning extends YAMLError {\n    constructor(pos, code, message) {\n        super('YAMLWarning', pos, code, message);\n    }\n}\nconst prettifyError = (src, lc) => (error) => {\n    if (error.pos[0] === -1)\n        return;\n    error.linePos = error.pos.map(pos => lc.linePos(pos));\n    const { line, col } = error.linePos[0];\n    error.message += ` at line ${line}, column ${col}`;\n    let ci = col - 1;\n    let lineStr = src\n        .substring(lc.lineStarts[line - 1], lc.lineStarts[line])\n        .replace(/[\\n\\r]+$/, '');\n    // Trim to max 80 chars, keeping col position near the middle\n    if (ci >= 60 && lineStr.length > 80) {\n        const trimStart = Math.min(ci - 39, lineStr.length - 79);\n        lineStr = '\u2026' + lineStr.substring(trimStart);\n        ci -= trimStart - 1;\n    }\n    if (lineStr.length > 80)\n        lineStr = lineStr.substring(0, 79) + '\u2026';\n    // Include previous line in context if pointing at line start\n    if (line > 1 && /^ *$/.test(lineStr.substring(0, ci))) {\n        // Regexp won't match if start is trimmed\n        let prev = src.substring(lc.lineStarts[line - 2], lc.lineStarts[line - 1]);\n        if (prev.length > 80)\n            prev = prev.substring(0, 79) + '\u2026\\n';\n        lineStr = prev + lineStr;\n    }\n    if (/[^ ]/.test(lineStr)) {\n        let count = 1;\n        const end = error.linePos[1];\n        if (end?.line === line && end.col > col) {\n            count = Math.max(1, Math.min(end.col - col, 80 - ci));\n        }\n        const pointer = ' '.repeat(ci) + '^'.repeat(count);\n        error.message += `:\\n\\n${lineStr}\\n${pointer}\\n`;\n    }\n};\n\nexports.YAMLError = YAMLError;\nexports.YAMLParseError = YAMLParseError;\nexports.YAMLWarning = YAMLWarning;\nexports.prettifyError = prettifyError;\n", "'use strict';\n\nfunction resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {\n    let spaceBefore = false;\n    let atNewline = startOnNewline;\n    let hasSpace = startOnNewline;\n    let comment = '';\n    let commentSep = '';\n    let hasNewline = false;\n    let reqSpace = false;\n    let tab = null;\n    let anchor = null;\n    let tag = null;\n    let newlineAfterProp = null;\n    let comma = null;\n    let found = null;\n    let start = null;\n    for (const token of tokens) {\n        if (reqSpace) {\n            if (token.type !== 'space' &&\n                token.type !== 'newline' &&\n                token.type !== 'comma')\n                onError(token.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');\n            reqSpace = false;\n        }\n        if (tab) {\n            if (atNewline && token.type !== 'comment' && token.type !== 'newline') {\n                onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');\n            }\n            tab = null;\n        }\n        switch (token.type) {\n            case 'space':\n                // At the doc level, tabs at line start may be parsed\n                // as leading white space rather than indentation.\n                // In a flow collection, only the parser handles indent.\n                if (!flow &&\n                    (indicator !== 'doc-start' || next?.type !== 'flow-collection') &&\n                    token.source.includes('\\t')) {\n                    tab = token;\n                }\n                hasSpace = true;\n                break;\n            case 'comment': {\n                if (!hasSpace)\n                    onError(token, 'MISSING_CHAR', 'Comments must be separated from other tokens by white space characters');\n                const cb = token.source.substring(1) || ' ';\n                if (!comment)\n                    comment = cb;\n                else\n                    comment += commentSep + cb;\n                commentSep = '';\n                atNewline = false;\n                break;\n            }\n            case 'newline':\n                if (atNewline) {\n                    if (comment)\n                        comment += token.source;\n                    else if (!found || indicator !== 'seq-item-ind')\n                        spaceBefore = true;\n                }\n                else\n                    commentSep += token.source;\n                atNewline = true;\n                hasNewline = true;\n                if (anchor || tag)\n                    newlineAfterProp = token;\n                hasSpace = true;\n                break;\n            case 'anchor':\n                if (anchor)\n                    onError(token, 'MULTIPLE_ANCHORS', 'A node can have at most one anchor');\n                if (token.source.endsWith(':'))\n                    onError(token.offset + token.source.length - 1, 'BAD_ALIAS', 'Anchor ending in : is ambiguous', true);\n                anchor = token;\n                start ?? (start = token.offset);\n                atNewline = false;\n                hasSpace = false;\n                reqSpace = true;\n                break;\n            case 'tag': {\n                if (tag)\n                    onError(token, 'MULTIPLE_TAGS', 'A node can have at most one tag');\n                tag = token;\n                start ?? (start = token.offset);\n                atNewline = false;\n                hasSpace = false;\n                reqSpace = true;\n                break;\n            }\n            case indicator:\n                // Could here handle preceding comments differently\n                if (anchor || tag)\n                    onError(token, 'BAD_PROP_ORDER', `Anchors and tags must be after the ${token.source} indicator`);\n                if (found)\n                    onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${token.source} in ${flow ?? 'collection'}`);\n                found = token;\n                atNewline =\n                    indicator === 'seq-item-ind' || indicator === 'explicit-key-ind';\n                hasSpace = false;\n                break;\n            case 'comma':\n                if (flow) {\n                    if (comma)\n                        onError(token, 'UNEXPECTED_TOKEN', `Unexpected , in ${flow}`);\n                    comma = token;\n                    atNewline = false;\n                    hasSpace = false;\n                    break;\n                }\n            // else fallthrough\n            default:\n                onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${token.type} token`);\n                atNewline = false;\n                hasSpace = false;\n        }\n    }\n    const last = tokens[tokens.length - 1];\n    const end = last ? last.offset + last.source.length : offset;\n    if (reqSpace &&\n        next &&\n        next.type !== 'space' &&\n        next.type !== 'newline' &&\n        next.type !== 'comma' &&\n        (next.type !== 'scalar' || next.source !== '')) {\n        onError(next.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');\n    }\n    if (tab &&\n        ((atNewline && tab.indent <= parentIndent) ||\n            next?.type === 'block-map' ||\n            next?.type === 'block-seq'))\n        onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');\n    return {\n        comma,\n        found,\n        spaceBefore,\n        comment,\n        hasNewline,\n        anchor,\n        tag,\n        newlineAfterProp,\n        end,\n        start: start ?? end\n    };\n}\n\nexports.resolveProps = resolveProps;\n", "'use strict';\n\nfunction containsNewline(key) {\n    if (!key)\n        return null;\n    switch (key.type) {\n        case 'alias':\n        case 'scalar':\n        case 'double-quoted-scalar':\n        case 'single-quoted-scalar':\n            if (key.source.includes('\\n'))\n                return true;\n            if (key.end)\n                for (const st of key.end)\n                    if (st.type === 'newline')\n                        return true;\n            return false;\n        case 'flow-collection':\n            for (const it of key.items) {\n                for (const st of it.start)\n                    if (st.type === 'newline')\n                        return true;\n                if (it.sep)\n                    for (const st of it.sep)\n                        if (st.type === 'newline')\n                            return true;\n                if (containsNewline(it.key) || containsNewline(it.value))\n                    return true;\n            }\n            return false;\n        default:\n            return true;\n    }\n}\n\nexports.containsNewline = containsNewline;\n", "'use strict';\n\nvar utilContainsNewline = require('./util-contains-newline.js');\n\nfunction flowIndentCheck(indent, fc, onError) {\n    if (fc?.type === 'flow-collection') {\n        const end = fc.end[0];\n        if (end.indent === indent &&\n            (end.source === ']' || end.source === '}') &&\n            utilContainsNewline.containsNewline(fc)) {\n            const msg = 'Flow end indicator should be more indented than parent';\n            onError(end, 'BAD_INDENT', msg, true);\n        }\n    }\n}\n\nexports.flowIndentCheck = flowIndentCheck;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\n\nfunction mapIncludes(ctx, items, search) {\n    const { uniqueKeys } = ctx.options;\n    if (uniqueKeys === false)\n        return false;\n    const isEqual = typeof uniqueKeys === 'function'\n        ? uniqueKeys\n        : (a, b) => a === b || (identity.isScalar(a) && identity.isScalar(b) && a.value === b.value);\n    return items.some(pair => isEqual(pair.key, search));\n}\n\nexports.mapIncludes = mapIncludes;\n", "'use strict';\n\nvar Pair = require('../nodes/Pair.js');\nvar YAMLMap = require('../nodes/YAMLMap.js');\nvar resolveProps = require('./resolve-props.js');\nvar utilContainsNewline = require('./util-contains-newline.js');\nvar utilFlowIndentCheck = require('./util-flow-indent-check.js');\nvar utilMapIncludes = require('./util-map-includes.js');\n\nconst startColMsg = 'All mapping items must start at the same column';\nfunction resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, tag) {\n    const NodeClass = tag?.nodeClass ?? YAMLMap.YAMLMap;\n    const map = new NodeClass(ctx.schema);\n    if (ctx.atRoot)\n        ctx.atRoot = false;\n    let offset = bm.offset;\n    let commentEnd = null;\n    for (const collItem of bm.items) {\n        const { start, key, sep, value } = collItem;\n        // key properties\n        const keyProps = resolveProps.resolveProps(start, {\n            indicator: 'explicit-key-ind',\n            next: key ?? sep?.[0],\n            offset,\n            onError,\n            parentIndent: bm.indent,\n            startOnNewline: true\n        });\n        const implicitKey = !keyProps.found;\n        if (implicitKey) {\n            if (key) {\n                if (key.type === 'block-seq')\n                    onError(offset, 'BLOCK_AS_IMPLICIT_KEY', 'A block sequence may not be used as an implicit map key');\n                else if ('indent' in key && key.indent !== bm.indent)\n                    onError(offset, 'BAD_INDENT', startColMsg);\n            }\n            if (!keyProps.anchor && !keyProps.tag && !sep) {\n                commentEnd = keyProps.end;\n                if (keyProps.comment) {\n                    if (map.comment)\n                        map.comment += '\\n' + keyProps.comment;\n                    else\n                        map.comment = keyProps.comment;\n                }\n                continue;\n            }\n            if (keyProps.newlineAfterProp || utilContainsNewline.containsNewline(key)) {\n                onError(key ?? start[start.length - 1], 'MULTILINE_IMPLICIT_KEY', 'Implicit keys need to be on a single line');\n            }\n        }\n        else if (keyProps.found?.indent !== bm.indent) {\n            onError(offset, 'BAD_INDENT', startColMsg);\n        }\n        // key value\n        ctx.atKey = true;\n        const keyStart = keyProps.end;\n        const keyNode = key\n            ? composeNode(ctx, key, keyProps, onError)\n            : composeEmptyNode(ctx, keyStart, start, null, keyProps, onError);\n        if (ctx.schema.compat)\n            utilFlowIndentCheck.flowIndentCheck(bm.indent, key, onError);\n        ctx.atKey = false;\n        if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))\n            onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique');\n        // value properties\n        const valueProps = resolveProps.resolveProps(sep ?? [], {\n            indicator: 'map-value-ind',\n            next: value,\n            offset: keyNode.range[2],\n            onError,\n            parentIndent: bm.indent,\n            startOnNewline: !key || key.type === 'block-scalar'\n        });\n        offset = valueProps.end;\n        if (valueProps.found) {\n            if (implicitKey) {\n                if (value?.type === 'block-map' && !valueProps.hasNewline)\n                    onError(offset, 'BLOCK_AS_IMPLICIT_KEY', 'Nested mappings are not allowed in compact mappings');\n                if (ctx.options.strict &&\n                    keyProps.start < valueProps.found.offset - 1024)\n                    onError(keyNode.range, 'KEY_OVER_1024_CHARS', 'The : indicator must be at most 1024 chars after the start of an implicit block mapping key');\n            }\n            // value value\n            const valueNode = value\n                ? composeNode(ctx, value, valueProps, onError)\n                : composeEmptyNode(ctx, offset, sep, null, valueProps, onError);\n            if (ctx.schema.compat)\n                utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);\n            offset = valueNode.range[2];\n            const pair = new Pair.Pair(keyNode, valueNode);\n            if (ctx.options.keepSourceTokens)\n                pair.srcToken = collItem;\n            map.items.push(pair);\n        }\n        else {\n            // key with no value\n            if (implicitKey)\n                onError(keyNode.range, 'MISSING_CHAR', 'Implicit map keys need to be followed by map values');\n            if (valueProps.comment) {\n                if (keyNode.comment)\n                    keyNode.comment += '\\n' + valueProps.comment;\n                else\n                    keyNode.comment = valueProps.comment;\n            }\n            const pair = new Pair.Pair(keyNode);\n            if (ctx.options.keepSourceTokens)\n                pair.srcToken = collItem;\n            map.items.push(pair);\n        }\n    }\n    if (commentEnd && commentEnd < offset)\n        onError(commentEnd, 'IMPOSSIBLE', 'Map comment with trailing content');\n    map.range = [bm.offset, offset, commentEnd ?? offset];\n    return map;\n}\n\nexports.resolveBlockMap = resolveBlockMap;\n", "'use strict';\n\nvar YAMLSeq = require('../nodes/YAMLSeq.js');\nvar resolveProps = require('./resolve-props.js');\nvar utilFlowIndentCheck = require('./util-flow-indent-check.js');\n\nfunction resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, tag) {\n    const NodeClass = tag?.nodeClass ?? YAMLSeq.YAMLSeq;\n    const seq = new NodeClass(ctx.schema);\n    if (ctx.atRoot)\n        ctx.atRoot = false;\n    if (ctx.atKey)\n        ctx.atKey = false;\n    let offset = bs.offset;\n    let commentEnd = null;\n    for (const { start, value } of bs.items) {\n        const props = resolveProps.resolveProps(start, {\n            indicator: 'seq-item-ind',\n            next: value,\n            offset,\n            onError,\n            parentIndent: bs.indent,\n            startOnNewline: true\n        });\n        if (!props.found) {\n            if (props.anchor || props.tag || value) {\n                if (value?.type === 'block-seq')\n                    onError(props.end, 'BAD_INDENT', 'All sequence items must start at the same column');\n                else\n                    onError(offset, 'MISSING_CHAR', 'Sequence item without - indicator');\n            }\n            else {\n                commentEnd = props.end;\n                if (props.comment)\n                    seq.comment = props.comment;\n                continue;\n            }\n        }\n        const node = value\n            ? composeNode(ctx, value, props, onError)\n            : composeEmptyNode(ctx, props.end, start, null, props, onError);\n        if (ctx.schema.compat)\n            utilFlowIndentCheck.flowIndentCheck(bs.indent, value, onError);\n        offset = node.range[2];\n        seq.items.push(node);\n    }\n    seq.range = [bs.offset, offset, commentEnd ?? offset];\n    return seq;\n}\n\nexports.resolveBlockSeq = resolveBlockSeq;\n", "'use strict';\n\nfunction resolveEnd(end, offset, reqSpace, onError) {\n    let comment = '';\n    if (end) {\n        let hasSpace = false;\n        let sep = '';\n        for (const token of end) {\n            const { source, type } = token;\n            switch (type) {\n                case 'space':\n                    hasSpace = true;\n                    break;\n                case 'comment': {\n                    if (reqSpace && !hasSpace)\n                        onError(token, 'MISSING_CHAR', 'Comments must be separated from other tokens by white space characters');\n                    const cb = source.substring(1) || ' ';\n                    if (!comment)\n                        comment = cb;\n                    else\n                        comment += sep + cb;\n                    sep = '';\n                    break;\n                }\n                case 'newline':\n                    if (comment)\n                        sep += source;\n                    hasSpace = true;\n                    break;\n                default:\n                    onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${type} at node end`);\n            }\n            offset += source.length;\n        }\n    }\n    return { comment, offset };\n}\n\nexports.resolveEnd = resolveEnd;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar Pair = require('../nodes/Pair.js');\nvar YAMLMap = require('../nodes/YAMLMap.js');\nvar YAMLSeq = require('../nodes/YAMLSeq.js');\nvar resolveEnd = require('./resolve-end.js');\nvar resolveProps = require('./resolve-props.js');\nvar utilContainsNewline = require('./util-contains-newline.js');\nvar utilMapIncludes = require('./util-map-includes.js');\n\nconst blockMsg = 'Block collections are not allowed within flow collections';\nconst isBlock = (token) => token && (token.type === 'block-map' || token.type === 'block-seq');\nfunction resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onError, tag) {\n    const isMap = fc.start.source === '{';\n    const fcName = isMap ? 'flow map' : 'flow sequence';\n    const NodeClass = (tag?.nodeClass ?? (isMap ? YAMLMap.YAMLMap : YAMLSeq.YAMLSeq));\n    const coll = new NodeClass(ctx.schema);\n    coll.flow = true;\n    const atRoot = ctx.atRoot;\n    if (atRoot)\n        ctx.atRoot = false;\n    if (ctx.atKey)\n        ctx.atKey = false;\n    let offset = fc.offset + fc.start.source.length;\n    for (let i = 0; i < fc.items.length; ++i) {\n        const collItem = fc.items[i];\n        const { start, key, sep, value } = collItem;\n        const props = resolveProps.resolveProps(start, {\n            flow: fcName,\n            indicator: 'explicit-key-ind',\n            next: key ?? sep?.[0],\n            offset,\n            onError,\n            parentIndent: fc.indent,\n            startOnNewline: false\n        });\n        if (!props.found) {\n            if (!props.anchor && !props.tag && !sep && !value) {\n                if (i === 0 && props.comma)\n                    onError(props.comma, 'UNEXPECTED_TOKEN', `Unexpected , in ${fcName}`);\n                else if (i < fc.items.length - 1)\n                    onError(props.start, 'UNEXPECTED_TOKEN', `Unexpected empty item in ${fcName}`);\n                if (props.comment) {\n                    if (coll.comment)\n                        coll.comment += '\\n' + props.comment;\n                    else\n                        coll.comment = props.comment;\n                }\n                offset = props.end;\n                continue;\n            }\n            if (!isMap && ctx.options.strict && utilContainsNewline.containsNewline(key))\n                onError(key, // checked by containsNewline()\n                'MULTILINE_IMPLICIT_KEY', 'Implicit keys of flow sequence pairs need to be on a single line');\n        }\n        if (i === 0) {\n            if (props.comma)\n                onError(props.comma, 'UNEXPECTED_TOKEN', `Unexpected , in ${fcName}`);\n        }\n        else {\n            if (!props.comma)\n                onError(props.start, 'MISSING_CHAR', `Missing , between ${fcName} items`);\n            if (props.comment) {\n                let prevItemComment = '';\n                loop: for (const st of start) {\n                    switch (st.type) {\n                        case 'comma':\n                        case 'space':\n                            break;\n                        case 'comment':\n                            prevItemComment = st.source.substring(1);\n                            break loop;\n                        default:\n                            break loop;\n                    }\n                }\n                if (prevItemComment) {\n                    let prev = coll.items[coll.items.length - 1];\n                    if (identity.isPair(prev))\n                        prev = prev.value ?? prev.key;\n                    if (prev.comment)\n                        prev.comment += '\\n' + prevItemComment;\n                    else\n                        prev.comment = prevItemComment;\n                    props.comment = props.comment.substring(prevItemComment.length + 1);\n                }\n            }\n        }\n        if (!isMap && !sep && !props.found) {\n            // item is a value in a seq\n            // \u2192 key & sep are empty, start does not include ? or :\n            const valueNode = value\n                ? composeNode(ctx, value, props, onError)\n                : composeEmptyNode(ctx, props.end, sep, null, props, onError);\n            coll.items.push(valueNode);\n            offset = valueNode.range[2];\n            if (isBlock(value))\n                onError(valueNode.range, 'BLOCK_IN_FLOW', blockMsg);\n        }\n        else {\n            // item is a key+value pair\n            // key value\n            ctx.atKey = true;\n            const keyStart = props.end;\n            const keyNode = key\n                ? composeNode(ctx, key, props, onError)\n                : composeEmptyNode(ctx, keyStart, start, null, props, onError);\n            if (isBlock(key))\n                onError(keyNode.range, 'BLOCK_IN_FLOW', blockMsg);\n            ctx.atKey = false;\n            // value properties\n            const valueProps = resolveProps.resolveProps(sep ?? [], {\n                flow: fcName,\n                indicator: 'map-value-ind',\n                next: value,\n                offset: keyNode.range[2],\n                onError,\n                parentIndent: fc.indent,\n                startOnNewline: false\n            });\n            if (valueProps.found) {\n                if (!isMap && !props.found && ctx.options.strict) {\n                    if (sep)\n                        for (const st of sep) {\n                            if (st === valueProps.found)\n                                break;\n                            if (st.type === 'newline') {\n                                onError(st, 'MULTILINE_IMPLICIT_KEY', 'Implicit keys of flow sequence pairs need to be on a single line');\n                                break;\n                            }\n                        }\n                    if (props.start < valueProps.found.offset - 1024)\n                        onError(valueProps.found, 'KEY_OVER_1024_CHARS', 'The : indicator must be at most 1024 chars after the start of an implicit flow sequence key');\n                }\n            }\n            else if (value) {\n                if ('source' in value && value.source?.[0] === ':')\n                    onError(value, 'MISSING_CHAR', `Missing space after : in ${fcName}`);\n                else\n                    onError(valueProps.start, 'MISSING_CHAR', `Missing , or : between ${fcName} items`);\n            }\n            // value value\n            const valueNode = value\n                ? composeNode(ctx, value, valueProps, onError)\n                : valueProps.found\n                    ? composeEmptyNode(ctx, valueProps.end, sep, null, valueProps, onError)\n                    : null;\n            if (valueNode) {\n                if (isBlock(value))\n                    onError(valueNode.range, 'BLOCK_IN_FLOW', blockMsg);\n            }\n            else if (valueProps.comment) {\n                if (keyNode.comment)\n                    keyNode.comment += '\\n' + valueProps.comment;\n                else\n                    keyNode.comment = valueProps.comment;\n            }\n            const pair = new Pair.Pair(keyNode, valueNode);\n            if (ctx.options.keepSourceTokens)\n                pair.srcToken = collItem;\n            if (isMap) {\n                const map = coll;\n                if (utilMapIncludes.mapIncludes(ctx, map.items, keyNode))\n                    onError(keyStart, 'DUPLICATE_KEY', 'Map keys must be unique');\n                map.items.push(pair);\n            }\n            else {\n                const map = new YAMLMap.YAMLMap(ctx.schema);\n                map.flow = true;\n                map.items.push(pair);\n                const endRange = (valueNode ?? keyNode).range;\n                map.range = [keyNode.range[0], endRange[1], endRange[2]];\n                coll.items.push(map);\n            }\n            offset = valueNode ? valueNode.range[2] : valueProps.end;\n        }\n    }\n    const expectedEnd = isMap ? '}' : ']';\n    const [ce, ...ee] = fc.end;\n    let cePos = offset;\n    if (ce?.source === expectedEnd)\n        cePos = ce.offset + ce.source.length;\n    else {\n        const name = fcName[0].toUpperCase() + fcName.substring(1);\n        const msg = atRoot\n            ? `${name} must end with a ${expectedEnd}`\n            : `${name} in block collection must be sufficiently indented and end with a ${expectedEnd}`;\n        onError(offset, atRoot ? 'MISSING_CHAR' : 'BAD_INDENT', msg);\n        if (ce && ce.source.length !== 1)\n            ee.unshift(ce);\n    }\n    if (ee.length > 0) {\n        const end = resolveEnd.resolveEnd(ee, cePos, ctx.options.strict, onError);\n        if (end.comment) {\n            if (coll.comment)\n                coll.comment += '\\n' + end.comment;\n            else\n                coll.comment = end.comment;\n        }\n        coll.range = [fc.offset, cePos, end.offset];\n    }\n    else {\n        coll.range = [fc.offset, cePos, cePos];\n    }\n    return coll;\n}\n\nexports.resolveFlowCollection = resolveFlowCollection;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar Scalar = require('../nodes/Scalar.js');\nvar YAMLMap = require('../nodes/YAMLMap.js');\nvar YAMLSeq = require('../nodes/YAMLSeq.js');\nvar resolveBlockMap = require('./resolve-block-map.js');\nvar resolveBlockSeq = require('./resolve-block-seq.js');\nvar resolveFlowCollection = require('./resolve-flow-collection.js');\n\nfunction resolveCollection(CN, ctx, token, onError, tagName, tag) {\n    const coll = token.type === 'block-map'\n        ? resolveBlockMap.resolveBlockMap(CN, ctx, token, onError, tag)\n        : token.type === 'block-seq'\n            ? resolveBlockSeq.resolveBlockSeq(CN, ctx, token, onError, tag)\n            : resolveFlowCollection.resolveFlowCollection(CN, ctx, token, onError, tag);\n    const Coll = coll.constructor;\n    // If we got a tagName matching the class, or the tag name is '!',\n    // then use the tagName from the node class used to create it.\n    if (tagName === '!' || tagName === Coll.tagName) {\n        coll.tag = Coll.tagName;\n        return coll;\n    }\n    if (tagName)\n        coll.tag = tagName;\n    return coll;\n}\nfunction composeCollection(CN, ctx, token, props, onError) {\n    const tagToken = props.tag;\n    const tagName = !tagToken\n        ? null\n        : ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg));\n    if (token.type === 'block-seq') {\n        const { anchor, newlineAfterProp: nl } = props;\n        const lastProp = anchor && tagToken\n            ? anchor.offset > tagToken.offset\n                ? anchor\n                : tagToken\n            : (anchor ?? tagToken);\n        if (lastProp && (!nl || nl.offset < lastProp.offset)) {\n            const message = 'Missing newline after block sequence props';\n            onError(lastProp, 'MISSING_CHAR', message);\n        }\n    }\n    const expType = token.type === 'block-map'\n        ? 'map'\n        : token.type === 'block-seq'\n            ? 'seq'\n            : token.start.source === '{'\n                ? 'map'\n                : 'seq';\n    // shortcut: check if it's a generic YAMLMap or YAMLSeq\n    // before jumping into the custom tag logic.\n    if (!tagToken ||\n        !tagName ||\n        tagName === '!' ||\n        (tagName === YAMLMap.YAMLMap.tagName && expType === 'map') ||\n        (tagName === YAMLSeq.YAMLSeq.tagName && expType === 'seq')) {\n        return resolveCollection(CN, ctx, token, onError, tagName);\n    }\n    let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);\n    if (!tag) {\n        const kt = ctx.schema.knownTags[tagName];\n        if (kt?.collection === expType) {\n            ctx.schema.tags.push(Object.assign({}, kt, { default: false }));\n            tag = kt;\n        }\n        else {\n            if (kt) {\n                onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? 'scalar'}`, true);\n            }\n            else {\n                onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);\n            }\n            return resolveCollection(CN, ctx, token, onError, tagName);\n        }\n    }\n    const coll = resolveCollection(CN, ctx, token, onError, tagName, tag);\n    const res = tag.resolve?.(coll, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg), ctx.options) ?? coll;\n    const node = identity.isNode(res)\n        ? res\n        : new Scalar.Scalar(res);\n    node.range = coll.range;\n    node.tag = tagName;\n    if (tag?.format)\n        node.format = tag.format;\n    return node;\n}\n\nexports.composeCollection = composeCollection;\n", "'use strict';\n\nvar Scalar = require('../nodes/Scalar.js');\n\nfunction resolveBlockScalar(ctx, scalar, onError) {\n    const start = scalar.offset;\n    const header = parseBlockScalarHeader(scalar, ctx.options.strict, onError);\n    if (!header)\n        return { value: '', type: null, comment: '', range: [start, start, start] };\n    const type = header.mode === '>' ? Scalar.Scalar.BLOCK_FOLDED : Scalar.Scalar.BLOCK_LITERAL;\n    const lines = scalar.source ? splitLines(scalar.source) : [];\n    // determine the end of content & start of chomping\n    let chompStart = lines.length;\n    for (let i = lines.length - 1; i >= 0; --i) {\n        const content = lines[i][1];\n        if (content === '' || content === '\\r')\n            chompStart = i;\n        else\n            break;\n    }\n    // shortcut for empty contents\n    if (chompStart === 0) {\n        const value = header.chomp === '+' && lines.length > 0\n            ? '\\n'.repeat(Math.max(1, lines.length - 1))\n            : '';\n        let end = start + header.length;\n        if (scalar.source)\n            end += scalar.source.length;\n        return { value, type, comment: header.comment, range: [start, end, end] };\n    }\n    // find the indentation level to trim from start\n    let trimIndent = scalar.indent + header.indent;\n    let offset = scalar.offset + header.length;\n    let contentStart = 0;\n    for (let i = 0; i < chompStart; ++i) {\n        const [indent, content] = lines[i];\n        if (content === '' || content === '\\r') {\n            if (header.indent === 0 && indent.length > trimIndent)\n                trimIndent = indent.length;\n        }\n        else {\n            if (indent.length < trimIndent) {\n                const message = 'Block scalars with more-indented leading empty lines must use an explicit indentation indicator';\n                onError(offset + indent.length, 'MISSING_CHAR', message);\n            }\n            if (header.indent === 0)\n                trimIndent = indent.length;\n            contentStart = i;\n            if (trimIndent === 0 && !ctx.atRoot) {\n                const message = 'Block scalar values in collections must be indented';\n                onError(offset, 'BAD_INDENT', message);\n            }\n            break;\n        }\n        offset += indent.length + content.length + 1;\n    }\n    // include trailing more-indented empty lines in content\n    for (let i = lines.length - 1; i >= chompStart; --i) {\n        if (lines[i][0].length > trimIndent)\n            chompStart = i + 1;\n    }\n    let value = '';\n    let sep = '';\n    let prevMoreIndented = false;\n    // leading whitespace is kept intact\n    for (let i = 0; i < contentStart; ++i)\n        value += lines[i][0].slice(trimIndent) + '\\n';\n    for (let i = contentStart; i < chompStart; ++i) {\n        let [indent, content] = lines[i];\n        offset += indent.length + content.length + 1;\n        const crlf = content[content.length - 1] === '\\r';\n        if (crlf)\n            content = content.slice(0, -1);\n        /* istanbul ignore if already caught in lexer */\n        if (content && indent.length < trimIndent) {\n            const src = header.indent\n                ? 'explicit indentation indicator'\n                : 'first line';\n            const message = `Block scalar lines must not be less indented than their ${src}`;\n            onError(offset - content.length - (crlf ? 2 : 1), 'BAD_INDENT', message);\n            indent = '';\n        }\n        if (type === Scalar.Scalar.BLOCK_LITERAL) {\n            value += sep + indent.slice(trimIndent) + content;\n            sep = '\\n';\n        }\n        else if (indent.length > trimIndent || content[0] === '\\t') {\n            // more-indented content within a folded block\n            if (sep === ' ')\n                sep = '\\n';\n            else if (!prevMoreIndented && sep === '\\n')\n                sep = '\\n\\n';\n            value += sep + indent.slice(trimIndent) + content;\n            sep = '\\n';\n            prevMoreIndented = true;\n        }\n        else if (content === '') {\n            // empty line\n            if (sep === '\\n')\n                value += '\\n';\n            else\n                sep = '\\n';\n        }\n        else {\n            value += sep + content;\n            sep = ' ';\n            prevMoreIndented = false;\n        }\n    }\n    switch (header.chomp) {\n        case '-':\n            break;\n        case '+':\n            for (let i = chompStart; i < lines.length; ++i)\n                value += '\\n' + lines[i][0].slice(trimIndent);\n            if (value[value.length - 1] !== '\\n')\n                value += '\\n';\n            break;\n        default:\n            value += '\\n';\n    }\n    const end = start + header.length + scalar.source.length;\n    return { value, type, comment: header.comment, range: [start, end, end] };\n}\nfunction parseBlockScalarHeader({ offset, props }, strict, onError) {\n    /* istanbul ignore if should not happen */\n    if (props[0].type !== 'block-scalar-header') {\n        onError(props[0], 'IMPOSSIBLE', 'Block scalar header not found');\n        return null;\n    }\n    const { source } = props[0];\n    const mode = source[0];\n    let indent = 0;\n    let chomp = '';\n    let error = -1;\n    for (let i = 1; i < source.length; ++i) {\n        const ch = source[i];\n        if (!chomp && (ch === '-' || ch === '+'))\n            chomp = ch;\n        else {\n            const n = Number(ch);\n            if (!indent && n)\n                indent = n;\n            else if (error === -1)\n                error = offset + i;\n        }\n    }\n    if (error !== -1)\n        onError(error, 'UNEXPECTED_TOKEN', `Block scalar header includes extra characters: ${source}`);\n    let hasSpace = false;\n    let comment = '';\n    let length = source.length;\n    for (let i = 1; i < props.length; ++i) {\n        const token = props[i];\n        switch (token.type) {\n            case 'space':\n                hasSpace = true;\n            // fallthrough\n            case 'newline':\n                length += token.source.length;\n                break;\n            case 'comment':\n                if (strict && !hasSpace) {\n                    const message = 'Comments must be separated from other tokens by white space characters';\n                    onError(token, 'MISSING_CHAR', message);\n                }\n                length += token.source.length;\n                comment = token.source.substring(1);\n                break;\n            case 'error':\n                onError(token, 'UNEXPECTED_TOKEN', token.message);\n                length += token.source.length;\n                break;\n            /* istanbul ignore next should not happen */\n            default: {\n                const message = `Unexpected token in block scalar header: ${token.type}`;\n                onError(token, 'UNEXPECTED_TOKEN', message);\n                const ts = token.source;\n                if (ts && typeof ts === 'string')\n                    length += ts.length;\n            }\n        }\n    }\n    return { mode, indent, chomp, comment, length };\n}\n/** @returns Array of lines split up as `[indent, content]` */\nfunction splitLines(source) {\n    const split = source.split(/\\n( *)/);\n    const first = split[0];\n    const m = first.match(/^( *)/);\n    const line0 = m?.[1]\n        ? [m[1], first.slice(m[1].length)]\n        : ['', first];\n    const lines = [line0];\n    for (let i = 1; i < split.length; i += 2)\n        lines.push([split[i], split[i + 1]]);\n    return lines;\n}\n\nexports.resolveBlockScalar = resolveBlockScalar;\n", "'use strict';\n\nvar Scalar = require('../nodes/Scalar.js');\nvar resolveEnd = require('./resolve-end.js');\n\nfunction resolveFlowScalar(scalar, strict, onError) {\n    const { offset, type, source, end } = scalar;\n    let _type;\n    let value;\n    const _onError = (rel, code, msg) => onError(offset + rel, code, msg);\n    switch (type) {\n        case 'scalar':\n            _type = Scalar.Scalar.PLAIN;\n            value = plainValue(source, _onError);\n            break;\n        case 'single-quoted-scalar':\n            _type = Scalar.Scalar.QUOTE_SINGLE;\n            value = singleQuotedValue(source, _onError);\n            break;\n        case 'double-quoted-scalar':\n            _type = Scalar.Scalar.QUOTE_DOUBLE;\n            value = doubleQuotedValue(source, _onError);\n            break;\n        /* istanbul ignore next should not happen */\n        default:\n            onError(scalar, 'UNEXPECTED_TOKEN', `Expected a flow scalar value, but found: ${type}`);\n            return {\n                value: '',\n                type: null,\n                comment: '',\n                range: [offset, offset + source.length, offset + source.length]\n            };\n    }\n    const valueEnd = offset + source.length;\n    const re = resolveEnd.resolveEnd(end, valueEnd, strict, onError);\n    return {\n        value,\n        type: _type,\n        comment: re.comment,\n        range: [offset, valueEnd, re.offset]\n    };\n}\nfunction plainValue(source, onError) {\n    let badChar = '';\n    switch (source[0]) {\n        /* istanbul ignore next should not happen */\n        case '\\t':\n            badChar = 'a tab character';\n            break;\n        case ',':\n            badChar = 'flow indicator character ,';\n            break;\n        case '%':\n            badChar = 'directive indicator character %';\n            break;\n        case '|':\n        case '>': {\n            badChar = `block scalar indicator ${source[0]}`;\n            break;\n        }\n        case '@':\n        case '`': {\n            badChar = `reserved character ${source[0]}`;\n            break;\n        }\n    }\n    if (badChar)\n        onError(0, 'BAD_SCALAR_START', `Plain value cannot start with ${badChar}`);\n    return unfoldLines(source);\n}\nfunction singleQuotedValue(source, onError) {\n    if (source[source.length - 1] !== \"'\" || source.length === 1)\n        onError(source.length, 'MISSING_CHAR', \"Missing closing 'quote\");\n    return unfoldLines(source.slice(1, -1)).replace(/''/g, \"'\");\n}\nfunction unfoldLines(source) {\n    const line = /(.*?)\\r?\\n/sy;\n    let match = line.exec(source);\n    if (!match)\n        return source;\n    /**\n     * The negative lookbehinds in these RegExps are to\n     * prevent causing a polynomial search time in certain cases.\n     *\n     * The try-catch is for Safari < 16.4 and other old browsers:\n     * https://caniuse.com/js-regexp-lookbehind\n     */\n    let trimEnd, trimBoth;\n    try {\n        trimEnd = new RegExp('(?<![ \\t])[ \\t]+$');\n        trimBoth = new RegExp('^[ \\t]+|(?<![ \\t])[ \\t]+$', 'g');\n    }\n    catch {\n        trimEnd = /[ \\t]+$/;\n        trimBoth = /^[ \\t]+|[ \\t]+$/g;\n    }\n    let res = match[1].replace(trimEnd, '');\n    let sep = ' ';\n    let pos = line.lastIndex;\n    while ((match = line.exec(source))) {\n        const lm = match[1].replace(trimBoth, '');\n        if (lm === '') {\n            if (sep === '\\n')\n                res += sep;\n            else\n                sep = '\\n';\n        }\n        else {\n            res += sep + lm;\n            sep = ' ';\n        }\n        pos = line.lastIndex;\n    }\n    const last = /[ \\t]*(.*)/sy;\n    last.lastIndex = pos;\n    match = last.exec(source);\n    return res + sep + (match?.[1] ?? '');\n}\nfunction doubleQuotedValue(source, onError) {\n    let res = '';\n    for (let i = 1; i < source.length - 1; ++i) {\n        const ch = source[i];\n        if (ch === '\\r' && source[i + 1] === '\\n')\n            continue;\n        if (ch === '\\n') {\n            const { fold, offset } = foldNewline(source, i);\n            res += fold;\n            i = offset;\n        }\n        else if (ch === '\\\\') {\n            let next = source[++i];\n            const cc = escapeCodes[next];\n            if (cc)\n                res += cc;\n            else if (next === '\\n') {\n                // skip escaped newlines, but still trim the following line\n                next = source[i + 1];\n                while (next === ' ' || next === '\\t')\n                    next = source[++i + 1];\n            }\n            else if (next === '\\r' && source[i + 1] === '\\n') {\n                // skip escaped CRLF newlines, but still trim the following line\n                next = source[++i + 1];\n                while (next === ' ' || next === '\\t')\n                    next = source[++i + 1];\n            }\n            else if (next === 'x' || next === 'u' || next === 'U') {\n                const length = next === 'x' ? 2 : next === 'u' ? 4 : 8;\n                res += parseCharCode(source, i + 1, length, onError);\n                i += length;\n            }\n            else {\n                const raw = source.substr(i - 1, 2);\n                onError(i - 1, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);\n                res += raw;\n            }\n        }\n        else if (ch === ' ' || ch === '\\t') {\n            // trim trailing whitespace\n            const wsStart = i;\n            let next = source[i + 1];\n            while (next === ' ' || next === '\\t')\n                next = source[++i + 1];\n            if (next !== '\\n' && !(next === '\\r' && source[i + 2] === '\\n'))\n                res += i > wsStart ? source.slice(wsStart, i + 1) : ch;\n        }\n        else {\n            res += ch;\n        }\n    }\n    if (source[source.length - 1] !== '\"' || source.length === 1)\n        onError(source.length, 'MISSING_CHAR', 'Missing closing \"quote');\n    return res;\n}\n/**\n * Fold a single newline into a space, multiple newlines to N - 1 newlines.\n * Presumes `source[offset] === '\\n'`\n */\nfunction foldNewline(source, offset) {\n    let fold = '';\n    let ch = source[offset + 1];\n    while (ch === ' ' || ch === '\\t' || ch === '\\n' || ch === '\\r') {\n        if (ch === '\\r' && source[offset + 2] !== '\\n')\n            break;\n        if (ch === '\\n')\n            fold += '\\n';\n        offset += 1;\n        ch = source[offset + 1];\n    }\n    if (!fold)\n        fold = ' ';\n    return { fold, offset };\n}\nconst escapeCodes = {\n    '0': '\\0', // null character\n    a: '\\x07', // bell character\n    b: '\\b', // backspace\n    e: '\\x1b', // escape character\n    f: '\\f', // form feed\n    n: '\\n', // line feed\n    r: '\\r', // carriage return\n    t: '\\t', // horizontal tab\n    v: '\\v', // vertical tab\n    N: '\\u0085', // Unicode next line\n    _: '\\u00a0', // Unicode non-breaking space\n    L: '\\u2028', // Unicode line separator\n    P: '\\u2029', // Unicode paragraph separator\n    ' ': ' ',\n    '\"': '\"',\n    '/': '/',\n    '\\\\': '\\\\',\n    '\\t': '\\t'\n};\nfunction parseCharCode(source, offset, length, onError) {\n    const cc = source.substr(offset, length);\n    const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);\n    const code = ok ? parseInt(cc, 16) : NaN;\n    try {\n        return String.fromCodePoint(code);\n    }\n    catch {\n        const raw = source.substr(offset - 2, length + 2);\n        onError(offset - 2, 'BAD_DQ_ESCAPE', `Invalid escape sequence ${raw}`);\n        return raw;\n    }\n}\n\nexports.resolveFlowScalar = resolveFlowScalar;\n", "'use strict';\n\nvar identity = require('../nodes/identity.js');\nvar Scalar = require('../nodes/Scalar.js');\nvar resolveBlockScalar = require('./resolve-block-scalar.js');\nvar resolveFlowScalar = require('./resolve-flow-scalar.js');\n\nfunction composeScalar(ctx, token, tagToken, onError) {\n    const { value, type, comment, range } = token.type === 'block-scalar'\n        ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError)\n        : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);\n    const tagName = tagToken\n        ? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg))\n        : null;\n    let tag;\n    if (ctx.options.stringKeys && ctx.atKey) {\n        tag = ctx.schema[identity.SCALAR];\n    }\n    else if (tagName)\n        tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);\n    else if (token.type === 'scalar')\n        tag = findScalarTagByTest(ctx, value, token, onError);\n    else\n        tag = ctx.schema[identity.SCALAR];\n    let scalar;\n    try {\n        const res = tag.resolve(value, msg => onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg), ctx.options);\n        scalar = identity.isScalar(res) ? res : new Scalar.Scalar(res);\n    }\n    catch (error) {\n        const msg = error instanceof Error ? error.message : String(error);\n        onError(tagToken ?? token, 'TAG_RESOLVE_FAILED', msg);\n        scalar = new Scalar.Scalar(value);\n    }\n    scalar.range = range;\n    scalar.source = value;\n    if (type)\n        scalar.type = type;\n    if (tagName)\n        scalar.tag = tagName;\n    if (tag.format)\n        scalar.format = tag.format;\n    if (comment)\n        scalar.comment = comment;\n    return scalar;\n}\nfunction findScalarTagByName(schema, value, tagName, tagToken, onError) {\n    if (tagName === '!')\n        return schema[identity.SCALAR]; // non-specific tag\n    const matchWithTest = [];\n    for (const tag of schema.tags) {\n        if (!tag.collection && tag.tag === tagName) {\n            if (tag.default && tag.test)\n                matchWithTest.push(tag);\n            else\n                return tag;\n        }\n    }\n    for (const tag of matchWithTest)\n        if (tag.test?.test(value))\n            return tag;\n    const kt = schema.knownTags[tagName];\n    if (kt && !kt.collection) {\n        // Ensure that the known tag is available for stringifying,\n        // but does not get used by default.\n        schema.tags.push(Object.assign({}, kt, { default: false, test: undefined }));\n        return kt;\n    }\n    onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, tagName !== 'tag:yaml.org,2002:str');\n    return schema[identity.SCALAR];\n}\nfunction findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {\n    const tag = schema.tags.find(tag => (tag.default === true || (atKey && tag.default === 'key')) &&\n        tag.test?.test(value)) || schema[identity.SCALAR];\n    if (schema.compat) {\n        const compat = schema.compat.find(tag => tag.default && tag.test?.test(value)) ??\n            schema[identity.SCALAR];\n        if (tag.tag !== compat.tag) {\n            const ts = directives.tagString(tag.tag);\n            const cs = directives.tagString(compat.tag);\n            const msg = `Value may be parsed as either ${ts} or ${cs}`;\n            onError(token, 'TAG_RESOLVE_FAILED', msg, true);\n        }\n    }\n    return tag;\n}\n\nexports.composeScalar = composeScalar;\n", "'use strict';\n\nfunction emptyScalarPosition(offset, before, pos) {\n    if (before) {\n        pos ?? (pos = before.length);\n        for (let i = pos - 1; i >= 0; --i) {\n            let st = before[i];\n            switch (st.type) {\n                case 'space':\n                case 'comment':\n                case 'newline':\n                    offset -= st.source.length;\n                    continue;\n            }\n            // Technically, an empty scalar is immediately after the last non-empty\n            // node, but it's more useful to place it after any whitespace.\n            st = before[++i];\n            while (st?.type === 'space') {\n                offset += st.source.length;\n                st = before[++i];\n            }\n            break;\n        }\n    }\n    return offset;\n}\n\nexports.emptyScalarPosition = emptyScalarPosition;\n", "'use strict';\n\nvar Alias = require('../nodes/Alias.js');\nvar identity = require('../nodes/identity.js');\nvar composeCollection = require('./compose-collection.js');\nvar composeScalar = require('./compose-scalar.js');\nvar resolveEnd = require('./resolve-end.js');\nvar utilEmptyScalarPosition = require('./util-empty-scalar-position.js');\n\nconst CN = { composeNode, composeEmptyNode };\nfunction composeNode(ctx, token, props, onError) {\n    const atKey = ctx.atKey;\n    const { spaceBefore, comment, anchor, tag } = props;\n    let node;\n    let isSrcToken = true;\n    switch (token.type) {\n        case 'alias':\n            node = composeAlias(ctx, token, onError);\n            if (anchor || tag)\n                onError(token, 'ALIAS_PROPS', 'An alias node must not specify any properties');\n            break;\n        case 'scalar':\n        case 'single-quoted-scalar':\n        case 'double-quoted-scalar':\n        case 'block-scalar':\n            node = composeScalar.composeScalar(ctx, token, tag, onError);\n            if (anchor)\n                node.anchor = anchor.source.substring(1);\n            break;\n        case 'block-map':\n        case 'block-seq':\n        case 'flow-collection':\n            try {\n                node = composeCollection.composeCollection(CN, ctx, token, props, onError);\n                if (anchor)\n                    node.anchor = anchor.source.substring(1);\n            }\n            catch (error) {\n                // Almost certainly here due to a stack overflow\n                const message = error instanceof Error ? error.message : String(error);\n                onError(token, 'RESOURCE_EXHAUSTION', message);\n            }\n            break;\n        default: {\n            const message = token.type === 'error'\n                ? token.message\n                : `Unsupported token (type: ${token.type})`;\n            onError(token, 'UNEXPECTED_TOKEN', message);\n            isSrcToken = false;\n        }\n    }\n    node ?? (node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError));\n    if (anchor && node.anchor === '')\n        onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');\n    if (atKey &&\n        ctx.options.stringKeys &&\n        (!identity.isScalar(node) ||\n            typeof node.value !== 'string' ||\n            (node.tag && node.tag !== 'tag:yaml.org,2002:str'))) {\n        const msg = 'With stringKeys, all keys must be strings';\n        onError(tag ?? token, 'NON_STRING_KEY', msg);\n    }\n    if (spaceBefore)\n        node.spaceBefore = true;\n    if (comment) {\n        if (token.type === 'scalar' && token.source === '')\n            node.comment = comment;\n        else\n            node.commentBefore = comment;\n    }\n    // @ts-expect-error Type checking misses meaning of isSrcToken\n    if (ctx.options.keepSourceTokens && isSrcToken)\n        node.srcToken = token;\n    return node;\n}\nfunction composeEmptyNode(ctx, offset, before, pos, { spaceBefore, comment, anchor, tag, end }, onError) {\n    const token = {\n        type: 'scalar',\n        offset: utilEmptyScalarPosition.emptyScalarPosition(offset, before, pos),\n        indent: -1,\n        source: ''\n    };\n    const node = composeScalar.composeScalar(ctx, token, tag, onError);\n    if (anchor) {\n        node.anchor = anchor.source.substring(1);\n        if (node.anchor === '')\n            onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');\n    }\n    if (spaceBefore)\n        node.spaceBefore = true;\n    if (comment) {\n        node.comment = comment;\n        node.range[2] = end;\n    }\n    return node;\n}\nfunction composeAlias({ options }, { offset, source, end }, onError) {\n    const alias = new Alias.Alias(source.substring(1));\n    if (alias.source === '')\n        onError(offset, 'BAD_ALIAS', 'Alias cannot be an empty string');\n    if (alias.source.endsWith(':'))\n        onError(offset + source.length - 1, 'BAD_ALIAS', 'Alias ending in : is ambiguous', true);\n    const valueEnd = offset + source.length;\n    const re = resolveEnd.resolveEnd(end, valueEnd, options.strict, onError);\n    alias.range = [offset, valueEnd, re.offset];\n    if (re.comment)\n        alias.comment = re.comment;\n    return alias;\n}\n\nexports.composeEmptyNode = composeEmptyNode;\nexports.composeNode = composeNode;\n", "'use strict';\n\nvar Document = require('../doc/Document.js');\nvar composeNode = require('./compose-node.js');\nvar resolveEnd = require('./resolve-end.js');\nvar resolveProps = require('./resolve-props.js');\n\nfunction composeDoc(options, directives, { offset, start, value, end }, onError) {\n    const opts = Object.assign({ _directives: directives }, options);\n    const doc = new Document.Document(undefined, opts);\n    const ctx = {\n        atKey: false,\n        atRoot: true,\n        directives: doc.directives,\n        options: doc.options,\n        schema: doc.schema\n    };\n    const props = resolveProps.resolveProps(start, {\n        indicator: 'doc-start',\n        next: value ?? end?.[0],\n        offset,\n        onError,\n        parentIndent: 0,\n        startOnNewline: true\n    });\n    if (props.found) {\n        doc.directives.docStart = true;\n        if (value &&\n            (value.type === 'block-map' || value.type === 'block-seq') &&\n            !props.hasNewline)\n            onError(props.end, 'MISSING_CHAR', 'Block collection cannot start on same line with directives-end marker');\n    }\n    // @ts-expect-error If Contents is set, let's trust the user\n    doc.contents = value\n        ? composeNode.composeNode(ctx, value, props, onError)\n        : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);\n    const contentEnd = doc.contents.range[2];\n    const re = resolveEnd.resolveEnd(end, contentEnd, false, onError);\n    if (re.comment)\n        doc.comment = re.comment;\n    doc.range = [offset, contentEnd, re.offset];\n    return doc;\n}\n\nexports.composeDoc = composeDoc;\n", "'use strict';\n\nvar node_process = require('process');\nvar directives = require('../doc/directives.js');\nvar Document = require('../doc/Document.js');\nvar errors = require('../errors.js');\nvar identity = require('../nodes/identity.js');\nvar composeDoc = require('./compose-doc.js');\nvar resolveEnd = require('./resolve-end.js');\n\nfunction getErrorPos(src) {\n    if (typeof src === 'number')\n        return [src, src + 1];\n    if (Array.isArray(src))\n        return src.length === 2 ? src : [src[0], src[1]];\n    const { offset, source } = src;\n    return [offset, offset + (typeof source === 'string' ? source.length : 1)];\n}\nfunction parsePrelude(prelude) {\n    let comment = '';\n    let atComment = false;\n    let afterEmptyLine = false;\n    for (let i = 0; i < prelude.length; ++i) {\n        const source = prelude[i];\n        switch (source[0]) {\n            case '#':\n                comment +=\n                    (comment === '' ? '' : afterEmptyLine ? '\\n\\n' : '\\n') +\n                        (source.substring(1) || ' ');\n                atComment = true;\n                afterEmptyLine = false;\n                break;\n            case '%':\n                if (prelude[i + 1]?.[0] !== '#')\n                    i += 1;\n                atComment = false;\n                break;\n            default:\n                // This may be wrong after doc-end, but in that case it doesn't matter\n                if (!atComment)\n                    afterEmptyLine = true;\n                atComment = false;\n        }\n    }\n    return { comment, afterEmptyLine };\n}\n/**\n * Compose a stream of CST nodes into a stream of YAML Documents.\n *\n * ```ts\n * import { Composer, Parser } from 'yaml'\n *\n * const src: string = ...\n * const tokens = new Parser().parse(src)\n * const docs = new Composer().compose(tokens)\n * ```\n */\nclass Composer {\n    constructor(options = {}) {\n        this.doc = null;\n        this.atDirectives = false;\n        this.prelude = [];\n        this.errors = [];\n        this.warnings = [];\n        this.onError = (source, code, message, warning) => {\n            const pos = getErrorPos(source);\n            if (warning)\n                this.warnings.push(new errors.YAMLWarning(pos, code, message));\n            else\n                this.errors.push(new errors.YAMLParseError(pos, code, message));\n        };\n        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n        this.directives = new directives.Directives({ version: options.version || '1.2' });\n        this.options = options;\n    }\n    decorate(doc, afterDoc) {\n        const { comment, afterEmptyLine } = parsePrelude(this.prelude);\n        //console.log({ dc: doc.comment, prelude, comment })\n        if (comment) {\n            const dc = doc.contents;\n            if (afterDoc) {\n                doc.comment = doc.comment ? `${doc.comment}\\n${comment}` : comment;\n            }\n            else if (afterEmptyLine || doc.directives.docStart || !dc) {\n                doc.commentBefore = comment;\n            }\n            else if (identity.isCollection(dc) && !dc.flow && dc.items.length > 0) {\n                let it = dc.items[0];\n                if (identity.isPair(it))\n                    it = it.key;\n                const cb = it.commentBefore;\n                it.commentBefore = cb ? `${comment}\\n${cb}` : comment;\n            }\n            else {\n                const cb = dc.commentBefore;\n                dc.commentBefore = cb ? `${comment}\\n${cb}` : comment;\n            }\n        }\n        if (afterDoc) {\n            for (let i = 0; i < this.errors.length; ++i)\n                doc.errors.push(this.errors[i]);\n            for (let i = 0; i < this.warnings.length; ++i)\n                doc.warnings.push(this.warnings[i]);\n        }\n        else {\n            doc.errors = this.errors;\n            doc.warnings = this.warnings;\n        }\n        this.prelude = [];\n        this.errors = [];\n        this.warnings = [];\n    }\n    /**\n     * Current stream status information.\n     *\n     * Mostly useful at the end of input for an empty stream.\n     */\n    streamInfo() {\n        return {\n            comment: parsePrelude(this.prelude).comment,\n            directives: this.directives,\n            errors: this.errors,\n            warnings: this.warnings\n        };\n    }\n    /**\n     * Compose tokens into documents.\n     *\n     * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.\n     * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.\n     */\n    *compose(tokens, forceDoc = false, endOffset = -1) {\n        for (const token of tokens)\n            yield* this.next(token);\n        yield* this.end(forceDoc, endOffset);\n    }\n    /** Advance the composer by one CST token. */\n    *next(token) {\n        if (node_process.env.LOG_STREAM)\n            console.dir(token, { depth: null });\n        switch (token.type) {\n            case 'directive':\n                this.directives.add(token.source, (offset, message, warning) => {\n                    const pos = getErrorPos(token);\n                    pos[0] += offset;\n                    this.onError(pos, 'BAD_DIRECTIVE', message, warning);\n                });\n                this.prelude.push(token.source);\n                this.atDirectives = true;\n                break;\n            case 'document': {\n                const doc = composeDoc.composeDoc(this.options, this.directives, token, this.onError);\n                if (this.atDirectives && !doc.directives.docStart)\n                    this.onError(token, 'MISSING_CHAR', 'Missing directives-end/doc-start indicator line');\n                this.decorate(doc, false);\n                if (this.doc)\n                    yield this.doc;\n                this.doc = doc;\n                this.atDirectives = false;\n                break;\n            }\n            case 'byte-order-mark':\n            case 'space':\n                break;\n            case 'comment':\n            case 'newline':\n                this.prelude.push(token.source);\n                break;\n            case 'error': {\n                const msg = token.source\n                    ? `${token.message}: ${JSON.stringify(token.source)}`\n                    : token.message;\n                const error = new errors.YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', msg);\n                if (this.atDirectives || !this.doc)\n                    this.errors.push(error);\n                else\n                    this.doc.errors.push(error);\n                break;\n            }\n            case 'doc-end': {\n                if (!this.doc) {\n                    const msg = 'Unexpected doc-end without preceding document';\n                    this.errors.push(new errors.YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', msg));\n                    break;\n                }\n                this.doc.directives.docEnd = true;\n                const end = resolveEnd.resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError);\n                this.decorate(this.doc, true);\n                if (end.comment) {\n                    const dc = this.doc.comment;\n                    this.doc.comment = dc ? `${dc}\\n${end.comment}` : end.comment;\n                }\n                this.doc.range[2] = end.offset;\n                break;\n            }\n            default:\n                this.errors.push(new errors.YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', `Unsupported token ${token.type}`));\n        }\n    }\n    /**\n     * Call at end of input to yield any remaining document.\n     *\n     * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.\n     * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.\n     */\n    *end(forceDoc = false, endOffset = -1) {\n        if (this.doc) {\n            this.decorate(this.doc, true);\n            yield this.doc;\n            this.doc = null;\n        }\n        else if (forceDoc) {\n            const opts = Object.assign({ _directives: this.directives }, this.options);\n            const doc = new Document.Document(undefined, opts);\n            if (this.atDirectives)\n                this.onError(endOffset, 'MISSING_CHAR', 'Missing directives-end indicator line');\n            doc.range = [0, endOffset, endOffset];\n            this.decorate(doc, false);\n            yield doc;\n        }\n    }\n}\n\nexports.Composer = Composer;\n", "'use strict';\n\nvar resolveBlockScalar = require('../compose/resolve-block-scalar.js');\nvar resolveFlowScalar = require('../compose/resolve-flow-scalar.js');\nvar errors = require('../errors.js');\nvar stringifyString = require('../stringify/stringifyString.js');\n\nfunction resolveAsScalar(token, strict = true, onError) {\n    if (token) {\n        const _onError = (pos, code, message) => {\n            const offset = typeof pos === 'number' ? pos : Array.isArray(pos) ? pos[0] : pos.offset;\n            if (onError)\n                onError(offset, code, message);\n            else\n                throw new errors.YAMLParseError([offset, offset + 1], code, message);\n        };\n        switch (token.type) {\n            case 'scalar':\n            case 'single-quoted-scalar':\n            case 'double-quoted-scalar':\n                return resolveFlowScalar.resolveFlowScalar(token, strict, _onError);\n            case 'block-scalar':\n                return resolveBlockScalar.resolveBlockScalar({ options: { strict } }, token, _onError);\n        }\n    }\n    return null;\n}\n/**\n * Create a new scalar token with `value`\n *\n * Values that represent an actual string but may be parsed as a different type should use a `type` other than `'PLAIN'`,\n * as this function does not support any schema operations and won't check for such conflicts.\n *\n * @param value The string representation of the value, which will have its content properly indented.\n * @param context.end Comments and whitespace after the end of the value, or after the block scalar header. If undefined, a newline will be added.\n * @param context.implicitKey Being within an implicit key may affect the resolved type of the token's value.\n * @param context.indent The indent level of the token.\n * @param context.inFlow Is this scalar within a flow collection? This may affect the resolved type of the token's value.\n * @param context.offset The offset position of the token.\n * @param context.type The preferred type of the scalar token. If undefined, the previous type of the `token` will be used, defaulting to `'PLAIN'`.\n */\nfunction createScalarToken(value, context) {\n    const { implicitKey = false, indent, inFlow = false, offset = -1, type = 'PLAIN' } = context;\n    const source = stringifyString.stringifyString({ type, value }, {\n        implicitKey,\n        indent: indent > 0 ? ' '.repeat(indent) : '',\n        inFlow,\n        options: { blockQuote: true, lineWidth: -1 }\n    });\n    const end = context.end ?? [\n        { type: 'newline', offset: -1, indent, source: '\\n' }\n    ];\n    switch (source[0]) {\n        case '|':\n        case '>': {\n            const he = source.indexOf('\\n');\n            const head = source.substring(0, he);\n            const body = source.substring(he + 1) + '\\n';\n            const props = [\n                { type: 'block-scalar-header', offset, indent, source: head }\n            ];\n            if (!addEndtoBlockProps(props, end))\n                props.push({ type: 'newline', offset: -1, indent, source: '\\n' });\n            return { type: 'block-scalar', offset, indent, props, source: body };\n        }\n        case '\"':\n            return { type: 'double-quoted-scalar', offset, indent, source, end };\n        case \"'\":\n            return { type: 'single-quoted-scalar', offset, indent, source, end };\n        default:\n            return { type: 'scalar', offset, indent, source, end };\n    }\n}\n/**\n * Set the value of `token` to the given string `value`, overwriting any previous contents and type that it may have.\n *\n * Best efforts are made to retain any comments previously associated with the `token`,\n * though all contents within a collection's `items` will be overwritten.\n *\n * Values that represent an actual string but may be parsed as a different type should use a `type` other than `'PLAIN'`,\n * as this function does not support any schema operations and won't check for such conflicts.\n *\n * @param token Any token. If it does not include an `indent` value, the value will be stringified as if it were an implicit key.\n * @param value The string representation of the value, which will have its content properly indented.\n * @param context.afterKey In most cases, values after a key should have an additional level of indentation.\n * @param context.implicitKey Being within an implicit key may affect the resolved type of the token's value.\n * @param context.inFlow Being within a flow collection may affect the resolved type of the token's value.\n * @param context.type The preferred type of the scalar token. If undefined, the previous type of the `token` will be used, defaulting to `'PLAIN'`.\n */\nfunction setScalarValue(token, value, context = {}) {\n    let { afterKey = false, implicitKey = false, inFlow = false, type } = context;\n    let indent = 'indent' in token ? token.indent : null;\n    if (afterKey && typeof indent === 'number')\n        indent += 2;\n    if (!type)\n        switch (token.type) {\n            case 'single-quoted-scalar':\n                type = 'QUOTE_SINGLE';\n                break;\n            case 'double-quoted-scalar':\n                type = 'QUOTE_DOUBLE';\n                break;\n            case 'block-scalar': {\n                const header = token.props[0];\n                if (header.type !== 'block-scalar-header')\n                    throw new Error('Invalid block scalar header');\n                type = header.source[0] === '>' ? 'BLOCK_FOLDED' : 'BLOCK_LITERAL';\n                break;\n            }\n            default:\n                type = 'PLAIN';\n        }\n    const source = stringifyString.stringifyString({ type, value }, {\n        implicitKey: implicitKey || indent === null,\n        indent: indent !== null && indent > 0 ? ' '.repeat(indent) : '',\n        inFlow,\n        options: { blockQuote: true, lineWidth: -1 }\n    });\n    switch (source[0]) {\n        case '|':\n        case '>':\n            setBlockScalarValue(token, source);\n            break;\n        case '\"':\n            setFlowScalarValue(token, source, 'double-quoted-scalar');\n            break;\n        case \"'\":\n            setFlowScalarValue(token, source, 'single-quoted-scalar');\n            break;\n        default:\n            setFlowScalarValue(token, source, 'scalar');\n    }\n}\nfunction setBlockScalarValue(token, source) {\n    const he = source.indexOf('\\n');\n    const head = source.substring(0, he);\n    const body = source.substring(he + 1) + '\\n';\n    if (token.type === 'block-scalar') {\n        const header = token.props[0];\n        if (header.type !== 'block-scalar-header')\n            throw new Error('Invalid block scalar header');\n        header.source = head;\n        token.source = body;\n    }\n    else {\n        const { offset } = token;\n        const indent = 'indent' in token ? token.indent : -1;\n        const props = [\n            { type: 'block-scalar-header', offset, indent, source: head }\n        ];\n        if (!addEndtoBlockProps(props, 'end' in token ? token.end : undefined))\n            props.push({ type: 'newline', offset: -1, indent, source: '\\n' });\n        for (const key of Object.keys(token))\n            if (key !== 'type' && key !== 'offset')\n                delete token[key];\n        Object.assign(token, { type: 'block-scalar', indent, props, source: body });\n    }\n}\n/** @returns `true` if last token is a newline */\nfunction addEndtoBlockProps(props, end) {\n    if (end)\n        for (const st of end)\n            switch (st.type) {\n                case 'space':\n                case 'comment':\n                    props.push(st);\n                    break;\n                case 'newline':\n                    props.push(st);\n                    return true;\n            }\n    return false;\n}\nfunction setFlowScalarValue(token, source, type) {\n    switch (token.type) {\n        case 'scalar':\n        case 'double-quoted-scalar':\n        case 'single-quoted-scalar':\n            token.type = type;\n            token.source = source;\n            break;\n        case 'block-scalar': {\n            const end = token.props.slice(1);\n            let oa = source.length;\n            if (token.props[0].type === 'block-scalar-header')\n                oa -= token.props[0].source.length;\n            for (const tok of end)\n                tok.offset += oa;\n            delete token.props;\n            Object.assign(token, { type, source, end });\n            break;\n        }\n        case 'block-map':\n        case 'block-seq': {\n            const offset = token.offset + source.length;\n            const nl = { type: 'newline', offset, indent: token.indent, source: '\\n' };\n            delete token.items;\n            Object.assign(token, { type, source, end: [nl] });\n            break;\n        }\n        default: {\n            const indent = 'indent' in token ? token.indent : -1;\n            const end = 'end' in token && Array.isArray(token.end)\n                ? token.end.filter(st => st.type === 'space' ||\n                    st.type === 'comment' ||\n                    st.type === 'newline')\n                : [];\n            for (const key of Object.keys(token))\n                if (key !== 'type' && key !== 'offset')\n                    delete token[key];\n            Object.assign(token, { type, indent, source, end });\n        }\n    }\n}\n\nexports.createScalarToken = createScalarToken;\nexports.resolveAsScalar = resolveAsScalar;\nexports.setScalarValue = setScalarValue;\n", "'use strict';\n\n/**\n * Stringify a CST document, token, or collection item\n *\n * Fair warning: This applies no validation whatsoever, and\n * simply concatenates the sources in their logical order.\n */\nconst stringify = (cst) => 'type' in cst ? stringifyToken(cst) : stringifyItem(cst);\nfunction stringifyToken(token) {\n    switch (token.type) {\n        case 'block-scalar': {\n            let res = '';\n            for (const tok of token.props)\n                res += stringifyToken(tok);\n            return res + token.source;\n        }\n        case 'block-map':\n        case 'block-seq': {\n            let res = '';\n            for (const item of token.items)\n                res += stringifyItem(item);\n            return res;\n        }\n        case 'flow-collection': {\n            let res = token.start.source;\n            for (const item of token.items)\n                res += stringifyItem(item);\n            for (const st of token.end)\n                res += st.source;\n            return res;\n        }\n        case 'document': {\n            let res = stringifyItem(token);\n            if (token.end)\n                for (const st of token.end)\n                    res += st.source;\n            return res;\n        }\n        default: {\n            let res = token.source;\n            if ('end' in token && token.end)\n                for (const st of token.end)\n                    res += st.source;\n            return res;\n        }\n    }\n}\nfunction stringifyItem({ start, key, sep, value }) {\n    let res = '';\n    for (const st of start)\n        res += st.source;\n    if (key)\n        res += stringifyToken(key);\n    if (sep)\n        for (const st of sep)\n            res += st.source;\n    if (value)\n        res += stringifyToken(value);\n    return res;\n}\n\nexports.stringify = stringify;\n", "'use strict';\n\nconst BREAK = Symbol('break visit');\nconst SKIP = Symbol('skip children');\nconst REMOVE = Symbol('remove item');\n/**\n * Apply a visitor to a CST document or item.\n *\n * Walks through the tree (depth-first) starting from the root, calling a\n * `visitor` function with two arguments when entering each item:\n *   - `item`: The current item, which included the following members:\n *     - `start: SourceToken[]` \u2013 Source tokens before the key or value,\n *       possibly including its anchor or tag.\n *     - `key?: Token | null` \u2013 Set for pair values. May then be `null`, if\n *       the key before the `:` separator is empty.\n *     - `sep?: SourceToken[]` \u2013 Source tokens between the key and the value,\n *       which should include the `:` map value indicator if `value` is set.\n *     - `value?: Token` \u2013 The value of a sequence item, or of a map pair.\n *   - `path`: The steps from the root to the current node, as an array of\n *     `['key' | 'value', number]` tuples.\n *\n * The return value of the visitor may be used to control the traversal:\n *   - `undefined` (default): Do nothing and continue\n *   - `visit.SKIP`: Do not visit the children of this token, continue with\n *      next sibling\n *   - `visit.BREAK`: Terminate traversal completely\n *   - `visit.REMOVE`: Remove the current item, then continue with the next one\n *   - `number`: Set the index of the next step. This is useful especially if\n *     the index of the current token has changed.\n *   - `function`: Define the next visitor for this item. After the original\n *     visitor is called on item entry, next visitors are called after handling\n *     a non-empty `key` and when exiting the item.\n */\nfunction visit(cst, visitor) {\n    if ('type' in cst && cst.type === 'document')\n        cst = { start: cst.start, value: cst.value };\n    _visit(Object.freeze([]), cst, visitor);\n}\n// Without the `as symbol` casts, TS declares these in the `visit`\n// namespace using `var`, but then complains about that because\n// `unique symbol` must be `const`.\n/** Terminate visit traversal completely */\nvisit.BREAK = BREAK;\n/** Do not visit the children of the current item */\nvisit.SKIP = SKIP;\n/** Remove the current item */\nvisit.REMOVE = REMOVE;\n/** Find the item at `path` from `cst` as the root */\nvisit.itemAtPath = (cst, path) => {\n    let item = cst;\n    for (const [field, index] of path) {\n        const tok = item?.[field];\n        if (tok && 'items' in tok) {\n            item = tok.items[index];\n        }\n        else\n            return undefined;\n    }\n    return item;\n};\n/**\n * Get the immediate parent collection of the item at `path` from `cst` as the root.\n *\n * Throws an error if the collection is not found, which should never happen if the item itself exists.\n */\nvisit.parentCollection = (cst, path) => {\n    const parent = visit.itemAtPath(cst, path.slice(0, -1));\n    const field = path[path.length - 1][0];\n    const coll = parent?.[field];\n    if (coll && 'items' in coll)\n        return coll;\n    throw new Error('Parent collection not found');\n};\nfunction _visit(path, item, visitor) {\n    let ctrl = visitor(item, path);\n    if (typeof ctrl === 'symbol')\n        return ctrl;\n    for (const field of ['key', 'value']) {\n        const token = item[field];\n        if (token && 'items' in token) {\n            for (let i = 0; i < token.items.length; ++i) {\n                const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);\n                if (typeof ci === 'number')\n                    i = ci - 1;\n                else if (ci === BREAK)\n                    return BREAK;\n                else if (ci === REMOVE) {\n                    token.items.splice(i, 1);\n                    i -= 1;\n                }\n            }\n            if (typeof ctrl === 'function' && field === 'key')\n                ctrl = ctrl(item, path);\n        }\n    }\n    return typeof ctrl === 'function' ? ctrl(item, path) : ctrl;\n}\n\nexports.visit = visit;\n", "'use strict';\n\nvar cstScalar = require('./cst-scalar.js');\nvar cstStringify = require('./cst-stringify.js');\nvar cstVisit = require('./cst-visit.js');\n\n/** The byte order mark */\nconst BOM = '\\u{FEFF}';\n/** Start of doc-mode */\nconst DOCUMENT = '\\x02'; // C0: Start of Text\n/** Unexpected end of flow-mode */\nconst FLOW_END = '\\x18'; // C0: Cancel\n/** Next token is a scalar value */\nconst SCALAR = '\\x1f'; // C0: Unit Separator\n/** @returns `true` if `token` is a flow or block collection */\nconst isCollection = (token) => !!token && 'items' in token;\n/** @returns `true` if `token` is a flow or block scalar; not an alias */\nconst isScalar = (token) => !!token &&\n    (token.type === 'scalar' ||\n        token.type === 'single-quoted-scalar' ||\n        token.type === 'double-quoted-scalar' ||\n        token.type === 'block-scalar');\n/* istanbul ignore next */\n/** Get a printable representation of a lexer token */\nfunction prettyToken(token) {\n    switch (token) {\n        case BOM:\n            return '<BOM>';\n        case DOCUMENT:\n            return '<DOC>';\n        case FLOW_END:\n            return '<FLOW_END>';\n        case SCALAR:\n            return '<SCALAR>';\n        default:\n            return JSON.stringify(token);\n    }\n}\n/** Identify the type of a lexer token. May return `null` for unknown tokens. */\nfunction tokenType(source) {\n    switch (source) {\n        case BOM:\n            return 'byte-order-mark';\n        case DOCUMENT:\n            return 'doc-mode';\n        case FLOW_END:\n            return 'flow-error-end';\n        case SCALAR:\n            return 'scalar';\n        case '---':\n            return 'doc-start';\n        case '...':\n            return 'doc-end';\n        case '':\n        case '\\n':\n        case '\\r\\n':\n            return 'newline';\n        case '-':\n            return 'seq-item-ind';\n        case '?':\n            return 'explicit-key-ind';\n        case ':':\n            return 'map-value-ind';\n        case '{':\n            return 'flow-map-start';\n        case '}':\n            return 'flow-map-end';\n        case '[':\n            return 'flow-seq-start';\n        case ']':\n            return 'flow-seq-end';\n        case ',':\n            return 'comma';\n    }\n    switch (source[0]) {\n        case ' ':\n        case '\\t':\n            return 'space';\n        case '#':\n            return 'comment';\n        case '%':\n            return 'directive-line';\n        case '*':\n            return 'alias';\n        case '&':\n            return 'anchor';\n        case '!':\n            return 'tag';\n        case \"'\":\n            return 'single-quoted-scalar';\n        case '\"':\n            return 'double-quoted-scalar';\n        case '|':\n        case '>':\n            return 'block-scalar-header';\n    }\n    return null;\n}\n\nexports.createScalarToken = cstScalar.createScalarToken;\nexports.resolveAsScalar = cstScalar.resolveAsScalar;\nexports.setScalarValue = cstScalar.setScalarValue;\nexports.stringify = cstStringify.stringify;\nexports.visit = cstVisit.visit;\nexports.BOM = BOM;\nexports.DOCUMENT = DOCUMENT;\nexports.FLOW_END = FLOW_END;\nexports.SCALAR = SCALAR;\nexports.isCollection = isCollection;\nexports.isScalar = isScalar;\nexports.prettyToken = prettyToken;\nexports.tokenType = tokenType;\n", "'use strict';\n\nvar cst = require('./cst.js');\n\n/*\nSTART -> stream\n\nstream\n  directive -> line-end -> stream\n  indent + line-end -> stream\n  [else] -> line-start\n\nline-end\n  comment -> line-end\n  newline -> .\n  input-end -> END\n\nline-start\n  doc-start -> doc\n  doc-end -> stream\n  [else] -> indent -> block-start\n\nblock-start\n  seq-item-start -> block-start\n  explicit-key-start -> block-start\n  map-value-start -> block-start\n  [else] -> doc\n\ndoc\n  line-end -> line-start\n  spaces -> doc\n  anchor -> doc\n  tag -> doc\n  flow-start -> flow -> doc\n  flow-end -> error -> doc\n  seq-item-start -> error -> doc\n  explicit-key-start -> error -> doc\n  map-value-start -> doc\n  alias -> doc\n  quote-start -> quoted-scalar -> doc\n  block-scalar-header -> line-end -> block-scalar(min) -> line-start\n  [else] -> plain-scalar(false, min) -> doc\n\nflow\n  line-end -> flow\n  spaces -> flow\n  anchor -> flow\n  tag -> flow\n  flow-start -> flow -> flow\n  flow-end -> .\n  seq-item-start -> error -> flow\n  explicit-key-start -> flow\n  map-value-start -> flow\n  alias -> flow\n  quote-start -> quoted-scalar -> flow\n  comma -> flow\n  [else] -> plain-scalar(true, 0) -> flow\n\nquoted-scalar\n  quote-end -> .\n  [else] -> quoted-scalar\n\nblock-scalar(min)\n  newline + peek(indent < min) -> .\n  [else] -> block-scalar(min)\n\nplain-scalar(is-flow, min)\n  scalar-end(is-flow) -> .\n  peek(newline + (indent < min)) -> .\n  [else] -> plain-scalar(min)\n*/\nfunction isEmpty(ch) {\n    switch (ch) {\n        case undefined:\n        case ' ':\n        case '\\n':\n        case '\\r':\n        case '\\t':\n            return true;\n        default:\n            return false;\n    }\n}\nconst hexDigits = new Set('0123456789ABCDEFabcdef');\nconst tagChars = new Set(\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()\");\nconst flowIndicatorChars = new Set(',[]{}');\nconst invalidAnchorChars = new Set(' ,[]{}\\n\\r\\t');\nconst isNotAnchorChar = (ch) => !ch || invalidAnchorChars.has(ch);\n/**\n * Splits an input string into lexical tokens, i.e. smaller strings that are\n * easily identifiable by `tokens.tokenType()`.\n *\n * Lexing starts always in a \"stream\" context. Incomplete input may be buffered\n * until a complete token can be emitted.\n *\n * In addition to slices of the original input, the following control characters\n * may also be emitted:\n *\n * - `\\x02` (Start of Text): A document starts with the next token\n * - `\\x18` (Cancel): Unexpected end of flow-mode (indicates an error)\n * - `\\x1f` (Unit Separator): Next token is a scalar value\n * - `\\u{FEFF}` (Byte order mark): Emitted separately outside documents\n */\nclass Lexer {\n    constructor() {\n        /**\n         * Flag indicating whether the end of the current buffer marks the end of\n         * all input\n         */\n        this.atEnd = false;\n        /**\n         * Explicit indent set in block scalar header, as an offset from the current\n         * minimum indent, so e.g. set to 1 from a header `|2+`. Set to -1 if not\n         * explicitly set.\n         */\n        this.blockScalarIndent = -1;\n        /**\n         * Block scalars that include a + (keep) chomping indicator in their header\n         * include trailing empty lines, which are otherwise excluded from the\n         * scalar's contents.\n         */\n        this.blockScalarKeep = false;\n        /** Current input */\n        this.buffer = '';\n        /**\n         * Flag noting whether the map value indicator : can immediately follow this\n         * node within a flow context.\n         */\n        this.flowKey = false;\n        /** Count of surrounding flow collection levels. */\n        this.flowLevel = 0;\n        /**\n         * Minimum level of indentation required for next lines to be parsed as a\n         * part of the current scalar value.\n         */\n        this.indentNext = 0;\n        /** Indentation level of the current line. */\n        this.indentValue = 0;\n        /** Position of the next \\n character. */\n        this.lineEndPos = null;\n        /** Stores the state of the lexer if reaching the end of incpomplete input */\n        this.next = null;\n        /** A pointer to `buffer`; the current position of the lexer. */\n        this.pos = 0;\n    }\n    /**\n     * Generate YAML tokens from the `source` string. If `incomplete`,\n     * a part of the last line may be left as a buffer for the next call.\n     *\n     * @returns A generator of lexical tokens\n     */\n    *lex(source, incomplete = false) {\n        if (source) {\n            if (typeof source !== 'string')\n                throw TypeError('source is not a string');\n            this.buffer = this.buffer ? this.buffer + source : source;\n            this.lineEndPos = null;\n        }\n        this.atEnd = !incomplete;\n        let next = this.next ?? 'stream';\n        while (next && (incomplete || this.hasChars(1)))\n            next = yield* this.parseNext(next);\n    }\n    atLineEnd() {\n        let i = this.pos;\n        let ch = this.buffer[i];\n        while (ch === ' ' || ch === '\\t')\n            ch = this.buffer[++i];\n        if (!ch || ch === '#' || ch === '\\n')\n            return true;\n        if (ch === '\\r')\n            return this.buffer[i + 1] === '\\n';\n        return false;\n    }\n    charAt(n) {\n        return this.buffer[this.pos + n];\n    }\n    continueScalar(offset) {\n        let ch = this.buffer[offset];\n        if (this.indentNext > 0) {\n            let indent = 0;\n            while (ch === ' ')\n                ch = this.buffer[++indent + offset];\n            if (ch === '\\r') {\n                const next = this.buffer[indent + offset + 1];\n                if (next === '\\n' || (!next && !this.atEnd))\n                    return offset + indent + 1;\n            }\n            return ch === '\\n' || indent >= this.indentNext || (!ch && !this.atEnd)\n                ? offset + indent\n                : -1;\n        }\n        if (ch === '-' || ch === '.') {\n            const dt = this.buffer.substr(offset, 3);\n            if ((dt === '---' || dt === '...') && isEmpty(this.buffer[offset + 3]))\n                return -1;\n        }\n        return offset;\n    }\n    getLine() {\n        let end = this.lineEndPos;\n        if (typeof end !== 'number' || (end !== -1 && end < this.pos)) {\n            end = this.buffer.indexOf('\\n', this.pos);\n            this.lineEndPos = end;\n        }\n        if (end === -1)\n            return this.atEnd ? this.buffer.substring(this.pos) : null;\n        if (this.buffer[end - 1] === '\\r')\n            end -= 1;\n        return this.buffer.substring(this.pos, end);\n    }\n    hasChars(n) {\n        return this.pos + n <= this.buffer.length;\n    }\n    setNext(state) {\n        this.buffer = this.buffer.substring(this.pos);\n        this.pos = 0;\n        this.lineEndPos = null;\n        this.next = state;\n        return null;\n    }\n    peek(n) {\n        return this.buffer.substr(this.pos, n);\n    }\n    *parseNext(next) {\n        switch (next) {\n            case 'stream':\n                return yield* this.parseStream();\n            case 'line-start':\n                return yield* this.parseLineStart();\n            case 'block-start':\n                return yield* this.parseBlockStart();\n            case 'doc':\n                return yield* this.parseDocument();\n            case 'flow':\n                return yield* this.parseFlowCollection();\n            case 'quoted-scalar':\n                return yield* this.parseQuotedScalar();\n            case 'block-scalar':\n                return yield* this.parseBlockScalar();\n            case 'plain-scalar':\n                return yield* this.parsePlainScalar();\n        }\n    }\n    *parseStream() {\n        let line = this.getLine();\n        if (line === null)\n            return this.setNext('stream');\n        if (line[0] === cst.BOM) {\n            yield* this.pushCount(1);\n            line = line.substring(1);\n        }\n        if (line[0] === '%') {\n            let dirEnd = line.length;\n            let cs = line.indexOf('#');\n            while (cs !== -1) {\n                const ch = line[cs - 1];\n                if (ch === ' ' || ch === '\\t') {\n                    dirEnd = cs - 1;\n                    break;\n                }\n                else {\n                    cs = line.indexOf('#', cs + 1);\n                }\n            }\n            while (true) {\n                const ch = line[dirEnd - 1];\n                if (ch === ' ' || ch === '\\t')\n                    dirEnd -= 1;\n                else\n                    break;\n            }\n            const n = (yield* this.pushCount(dirEnd)) + (yield* this.pushSpaces(true));\n            yield* this.pushCount(line.length - n); // possible comment\n            this.pushNewline();\n            return 'stream';\n        }\n        if (this.atLineEnd()) {\n            const sp = yield* this.pushSpaces(true);\n            yield* this.pushCount(line.length - sp);\n            yield* this.pushNewline();\n            return 'stream';\n        }\n        yield cst.DOCUMENT;\n        return yield* this.parseLineStart();\n    }\n    *parseLineStart() {\n        const ch = this.charAt(0);\n        if (!ch && !this.atEnd)\n            return this.setNext('line-start');\n        if (ch === '-' || ch === '.') {\n            if (!this.atEnd && !this.hasChars(4))\n                return this.setNext('line-start');\n            const s = this.peek(3);\n            if ((s === '---' || s === '...') && isEmpty(this.charAt(3))) {\n                yield* this.pushCount(3);\n                this.indentValue = 0;\n                this.indentNext = 0;\n                return s === '---' ? 'doc' : 'stream';\n            }\n        }\n        this.indentValue = yield* this.pushSpaces(false);\n        if (this.indentNext > this.indentValue && !isEmpty(this.charAt(1)))\n            this.indentNext = this.indentValue;\n        return yield* this.parseBlockStart();\n    }\n    *parseBlockStart() {\n        const [ch0, ch1] = this.peek(2);\n        if (!ch1 && !this.atEnd)\n            return this.setNext('block-start');\n        if ((ch0 === '-' || ch0 === '?' || ch0 === ':') && isEmpty(ch1)) {\n            const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));\n            this.indentNext = this.indentValue + 1;\n            this.indentValue += n;\n            return 'block-start';\n        }\n        return 'doc';\n    }\n    *parseDocument() {\n        yield* this.pushSpaces(true);\n        const line = this.getLine();\n        if (line === null)\n            return this.setNext('doc');\n        let n = yield* this.pushIndicators();\n        switch (line[n]) {\n            case '#':\n                yield* this.pushCount(line.length - n);\n            // fallthrough\n            case undefined:\n                yield* this.pushNewline();\n                return yield* this.parseLineStart();\n            case '{':\n            case '[':\n                yield* this.pushCount(1);\n                this.flowKey = false;\n                this.flowLevel = 1;\n                return 'flow';\n            case '}':\n            case ']':\n                // this is an error\n                yield* this.pushCount(1);\n                return 'doc';\n            case '*':\n                yield* this.pushUntil(isNotAnchorChar);\n                return 'doc';\n            case '\"':\n            case \"'\":\n                return yield* this.parseQuotedScalar();\n            case '|':\n            case '>':\n                n += yield* this.parseBlockScalarHeader();\n                n += yield* this.pushSpaces(true);\n                yield* this.pushCount(line.length - n);\n                yield* this.pushNewline();\n                return yield* this.parseBlockScalar();\n            default:\n                return yield* this.parsePlainScalar();\n        }\n    }\n    *parseFlowCollection() {\n        let nl, sp;\n        let indent = -1;\n        do {\n            nl = yield* this.pushNewline();\n            if (nl > 0) {\n                sp = yield* this.pushSpaces(false);\n                this.indentValue = indent = sp;\n            }\n            else {\n                sp = 0;\n            }\n            sp += yield* this.pushSpaces(true);\n        } while (nl + sp > 0);\n        const line = this.getLine();\n        if (line === null)\n            return this.setNext('flow');\n        if ((indent !== -1 && indent < this.indentNext && line[0] !== '#') ||\n            (indent === 0 &&\n                (line.startsWith('---') || line.startsWith('...')) &&\n                isEmpty(line[3]))) {\n            // Allowing for the terminal ] or } at the same (rather than greater)\n            // indent level as the initial [ or { is technically invalid, but\n            // failing here would be surprising to users.\n            const atFlowEndMarker = indent === this.indentNext - 1 &&\n                this.flowLevel === 1 &&\n                (line[0] === ']' || line[0] === '}');\n            if (!atFlowEndMarker) {\n                // this is an error\n                this.flowLevel = 0;\n                yield cst.FLOW_END;\n                return yield* this.parseLineStart();\n            }\n        }\n        let n = 0;\n        while (line[n] === ',') {\n            n += yield* this.pushCount(1);\n            n += yield* this.pushSpaces(true);\n            this.flowKey = false;\n        }\n        n += yield* this.pushIndicators();\n        switch (line[n]) {\n            case undefined:\n                return 'flow';\n            case '#':\n                yield* this.pushCount(line.length - n);\n                return 'flow';\n            case '{':\n            case '[':\n                yield* this.pushCount(1);\n                this.flowKey = false;\n                this.flowLevel += 1;\n                return 'flow';\n            case '}':\n            case ']':\n                yield* this.pushCount(1);\n                this.flowKey = true;\n                this.flowLevel -= 1;\n                return this.flowLevel ? 'flow' : 'doc';\n            case '*':\n                yield* this.pushUntil(isNotAnchorChar);\n                return 'flow';\n            case '\"':\n            case \"'\":\n                this.flowKey = true;\n                return yield* this.parseQuotedScalar();\n            case ':': {\n                const next = this.charAt(1);\n                if (this.flowKey || isEmpty(next) || next === ',') {\n                    this.flowKey = false;\n                    yield* this.pushCount(1);\n                    yield* this.pushSpaces(true);\n                    return 'flow';\n                }\n            }\n            // fallthrough\n            default:\n                this.flowKey = false;\n                return yield* this.parsePlainScalar();\n        }\n    }\n    *parseQuotedScalar() {\n        const quote = this.charAt(0);\n        let end = this.buffer.indexOf(quote, this.pos + 1);\n        if (quote === \"'\") {\n            while (end !== -1 && this.buffer[end + 1] === \"'\")\n                end = this.buffer.indexOf(\"'\", end + 2);\n        }\n        else {\n            // double-quote\n            while (end !== -1) {\n                let n = 0;\n                while (this.buffer[end - 1 - n] === '\\\\')\n                    n += 1;\n                if (n % 2 === 0)\n                    break;\n                end = this.buffer.indexOf('\"', end + 1);\n            }\n        }\n        // Only looking for newlines within the quotes\n        const qb = this.buffer.substring(0, end);\n        let nl = qb.indexOf('\\n', this.pos);\n        if (nl !== -1) {\n            while (nl !== -1) {\n                const cs = this.continueScalar(nl + 1);\n                if (cs === -1)\n                    break;\n                nl = qb.indexOf('\\n', cs);\n            }\n            if (nl !== -1) {\n                // this is an error caused by an unexpected unindent\n                end = nl - (qb[nl - 1] === '\\r' ? 2 : 1);\n            }\n        }\n        if (end === -1) {\n            if (!this.atEnd)\n                return this.setNext('quoted-scalar');\n            end = this.buffer.length;\n        }\n        yield* this.pushToIndex(end + 1, false);\n        return this.flowLevel ? 'flow' : 'doc';\n    }\n    *parseBlockScalarHeader() {\n        this.blockScalarIndent = -1;\n        this.blockScalarKeep = false;\n        let i = this.pos;\n        while (true) {\n            const ch = this.buffer[++i];\n            if (ch === '+')\n                this.blockScalarKeep = true;\n            else if (ch > '0' && ch <= '9')\n                this.blockScalarIndent = Number(ch) - 1;\n            else if (ch !== '-')\n                break;\n        }\n        return yield* this.pushUntil(ch => isEmpty(ch) || ch === '#');\n    }\n    *parseBlockScalar() {\n        let nl = this.pos - 1; // may be -1 if this.pos === 0\n        let indent = 0;\n        let ch;\n        loop: for (let i = this.pos; (ch = this.buffer[i]); ++i) {\n            switch (ch) {\n                case ' ':\n                    indent += 1;\n                    break;\n                case '\\n':\n                    nl = i;\n                    indent = 0;\n                    break;\n                case '\\r': {\n                    const next = this.buffer[i + 1];\n                    if (!next && !this.atEnd)\n                        return this.setNext('block-scalar');\n                    if (next === '\\n')\n                        break;\n                } // fallthrough\n                default:\n                    break loop;\n            }\n        }\n        if (!ch && !this.atEnd)\n            return this.setNext('block-scalar');\n        if (indent >= this.indentNext) {\n            if (this.blockScalarIndent === -1)\n                this.indentNext = indent;\n            else {\n                this.indentNext =\n                    this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);\n            }\n            do {\n                const cs = this.continueScalar(nl + 1);\n                if (cs === -1)\n                    break;\n                nl = this.buffer.indexOf('\\n', cs);\n            } while (nl !== -1);\n            if (nl === -1) {\n                if (!this.atEnd)\n                    return this.setNext('block-scalar');\n                nl = this.buffer.length;\n            }\n        }\n        // Trailing insufficiently indented tabs are invalid.\n        // To catch that during parsing, we include them in the block scalar value.\n        let i = nl + 1;\n        ch = this.buffer[i];\n        while (ch === ' ')\n            ch = this.buffer[++i];\n        if (ch === '\\t') {\n            while (ch === '\\t' || ch === ' ' || ch === '\\r' || ch === '\\n')\n                ch = this.buffer[++i];\n            nl = i - 1;\n        }\n        else if (!this.blockScalarKeep) {\n            do {\n                let i = nl - 1;\n                let ch = this.buffer[i];\n                if (ch === '\\r')\n                    ch = this.buffer[--i];\n                const lastChar = i; // Drop the line if last char not more indented\n                while (ch === ' ')\n                    ch = this.buffer[--i];\n                if (ch === '\\n' && i >= this.pos && i + 1 + indent > lastChar)\n                    nl = i;\n                else\n                    break;\n            } while (true);\n        }\n        yield cst.SCALAR;\n        yield* this.pushToIndex(nl + 1, true);\n        return yield* this.parseLineStart();\n    }\n    *parsePlainScalar() {\n        const inFlow = this.flowLevel > 0;\n        let end = this.pos - 1;\n        let i = this.pos - 1;\n        let ch;\n        while ((ch = this.buffer[++i])) {\n            if (ch === ':') {\n                const next = this.buffer[i + 1];\n                if (isEmpty(next) || (inFlow && flowIndicatorChars.has(next)))\n                    break;\n                end = i;\n            }\n            else if (isEmpty(ch)) {\n                let next = this.buffer[i + 1];\n                if (ch === '\\r') {\n                    if (next === '\\n') {\n                        i += 1;\n                        ch = '\\n';\n                        next = this.buffer[i + 1];\n                    }\n                    else\n                        end = i;\n                }\n                if (next === '#' || (inFlow && flowIndicatorChars.has(next)))\n                    break;\n                if (ch === '\\n') {\n                    const cs = this.continueScalar(i + 1);\n                    if (cs === -1)\n                        break;\n                    i = Math.max(i, cs - 2); // to advance, but still account for ' #'\n                }\n            }\n            else {\n                if (inFlow && flowIndicatorChars.has(ch))\n                    break;\n                end = i;\n            }\n        }\n        if (!ch && !this.atEnd)\n            return this.setNext('plain-scalar');\n        yield cst.SCALAR;\n        yield* this.pushToIndex(end + 1, true);\n        return inFlow ? 'flow' : 'doc';\n    }\n    *pushCount(n) {\n        if (n > 0) {\n            yield this.buffer.substr(this.pos, n);\n            this.pos += n;\n            return n;\n        }\n        return 0;\n    }\n    *pushToIndex(i, allowEmpty) {\n        const s = this.buffer.slice(this.pos, i);\n        if (s) {\n            yield s;\n            this.pos += s.length;\n            return s.length;\n        }\n        else if (allowEmpty)\n            yield '';\n        return 0;\n    }\n    *pushIndicators() {\n        let n = 0;\n        loop: while (true) {\n            switch (this.charAt(0)) {\n                case '!':\n                    n += yield* this.pushTag();\n                    n += yield* this.pushSpaces(true);\n                    continue loop;\n                case '&':\n                    n += yield* this.pushUntil(isNotAnchorChar);\n                    n += yield* this.pushSpaces(true);\n                    continue loop;\n                case '-': // this is an error\n                case '?': // this is an error outside flow collections\n                case ':': {\n                    const inFlow = this.flowLevel > 0;\n                    const ch1 = this.charAt(1);\n                    if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {\n                        if (!inFlow)\n                            this.indentNext = this.indentValue + 1;\n                        else if (this.flowKey)\n                            this.flowKey = false;\n                        n += yield* this.pushCount(1);\n                        n += yield* this.pushSpaces(true);\n                        continue loop;\n                    }\n                }\n            }\n            break loop;\n        }\n        return n;\n    }\n    *pushTag() {\n        if (this.charAt(1) === '<') {\n            let i = this.pos + 2;\n            let ch = this.buffer[i];\n            while (!isEmpty(ch) && ch !== '>')\n                ch = this.buffer[++i];\n            return yield* this.pushToIndex(ch === '>' ? i + 1 : i, false);\n        }\n        else {\n            let i = this.pos + 1;\n            let ch = this.buffer[i];\n            while (ch) {\n                if (tagChars.has(ch))\n                    ch = this.buffer[++i];\n                else if (ch === '%' &&\n                    hexDigits.has(this.buffer[i + 1]) &&\n                    hexDigits.has(this.buffer[i + 2])) {\n                    ch = this.buffer[(i += 3)];\n                }\n                else\n                    break;\n            }\n            return yield* this.pushToIndex(i, false);\n        }\n    }\n    *pushNewline() {\n        const ch = this.buffer[this.pos];\n        if (ch === '\\n')\n            return yield* this.pushCount(1);\n        else if (ch === '\\r' && this.charAt(1) === '\\n')\n            return yield* this.pushCount(2);\n        else\n            return 0;\n    }\n    *pushSpaces(allowTabs) {\n        let i = this.pos - 1;\n        let ch;\n        do {\n            ch = this.buffer[++i];\n        } while (ch === ' ' || (allowTabs && ch === '\\t'));\n        const n = i - this.pos;\n        if (n > 0) {\n            yield this.buffer.substr(this.pos, n);\n            this.pos = i;\n        }\n        return n;\n    }\n    *pushUntil(test) {\n        let i = this.pos;\n        let ch = this.buffer[i];\n        while (!test(ch))\n            ch = this.buffer[++i];\n        return yield* this.pushToIndex(i, false);\n    }\n}\n\nexports.Lexer = Lexer;\n", "'use strict';\n\n/**\n * Tracks newlines during parsing in order to provide an efficient API for\n * determining the one-indexed `{ line, col }` position for any offset\n * within the input.\n */\nclass LineCounter {\n    constructor() {\n        this.lineStarts = [];\n        /**\n         * Should be called in ascending order. Otherwise, call\n         * `lineCounter.lineStarts.sort()` before calling `linePos()`.\n         */\n        this.addNewLine = (offset) => this.lineStarts.push(offset);\n        /**\n         * Performs a binary search and returns the 1-indexed { line, col }\n         * position of `offset`. If `line === 0`, `addNewLine` has never been\n         * called or `offset` is before the first known newline.\n         */\n        this.linePos = (offset) => {\n            let low = 0;\n            let high = this.lineStarts.length;\n            while (low < high) {\n                const mid = (low + high) >> 1; // Math.floor((low + high) / 2)\n                if (this.lineStarts[mid] < offset)\n                    low = mid + 1;\n                else\n                    high = mid;\n            }\n            if (this.lineStarts[low] === offset)\n                return { line: low + 1, col: 1 };\n            if (low === 0)\n                return { line: 0, col: offset };\n            const start = this.lineStarts[low - 1];\n            return { line: low, col: offset - start + 1 };\n        };\n    }\n}\n\nexports.LineCounter = LineCounter;\n", "'use strict';\n\nvar node_process = require('process');\nvar cst = require('./cst.js');\nvar lexer = require('./lexer.js');\n\nfunction includesToken(list, type) {\n    for (let i = 0; i < list.length; ++i)\n        if (list[i].type === type)\n            return true;\n    return false;\n}\nfunction findNonEmptyIndex(list) {\n    for (let i = 0; i < list.length; ++i) {\n        switch (list[i].type) {\n            case 'space':\n            case 'comment':\n            case 'newline':\n                break;\n            default:\n                return i;\n        }\n    }\n    return -1;\n}\nfunction isFlowToken(token) {\n    switch (token?.type) {\n        case 'alias':\n        case 'scalar':\n        case 'single-quoted-scalar':\n        case 'double-quoted-scalar':\n        case 'flow-collection':\n            return true;\n        default:\n            return false;\n    }\n}\nfunction getPrevProps(parent) {\n    switch (parent.type) {\n        case 'document':\n            return parent.start;\n        case 'block-map': {\n            const it = parent.items[parent.items.length - 1];\n            return it.sep ?? it.start;\n        }\n        case 'block-seq':\n            return parent.items[parent.items.length - 1].start;\n        /* istanbul ignore next should not happen */\n        default:\n            return [];\n    }\n}\n/** Note: May modify input array */\nfunction getFirstKeyStartProps(prev) {\n    if (prev.length === 0)\n        return [];\n    let i = prev.length;\n    loop: while (--i >= 0) {\n        switch (prev[i].type) {\n            case 'doc-start':\n            case 'explicit-key-ind':\n            case 'map-value-ind':\n            case 'seq-item-ind':\n            case 'newline':\n                break loop;\n        }\n    }\n    while (prev[++i]?.type === 'space') {\n        /* loop */\n    }\n    return prev.splice(i, prev.length);\n}\nfunction arrayPushArray(target, source) {\n    // May exhaust call stack with large `source` array\n    if (source.length < 1e5)\n        Array.prototype.push.apply(target, source);\n    else\n        for (let i = 0; i < source.length; ++i)\n            target.push(source[i]);\n}\nfunction fixFlowSeqItems(fc) {\n    if (fc.start.type === 'flow-seq-start') {\n        for (const it of fc.items) {\n            if (it.sep &&\n                !it.value &&\n                !includesToken(it.start, 'explicit-key-ind') &&\n                !includesToken(it.sep, 'map-value-ind')) {\n                if (it.key)\n                    it.value = it.key;\n                delete it.key;\n                if (isFlowToken(it.value)) {\n                    if (it.value.end)\n                        arrayPushArray(it.value.end, it.sep);\n                    else\n                        it.value.end = it.sep;\n                }\n                else\n                    arrayPushArray(it.start, it.sep);\n                delete it.sep;\n            }\n        }\n    }\n}\n/**\n * A YAML concrete syntax tree (CST) parser\n *\n * ```ts\n * const src: string = ...\n * for (const token of new Parser().parse(src)) {\n *   // token: Token\n * }\n * ```\n *\n * To use the parser with a user-provided lexer:\n *\n * ```ts\n * function* parse(source: string, lexer: Lexer) {\n *   const parser = new Parser()\n *   for (const lexeme of lexer.lex(source))\n *     yield* parser.next(lexeme)\n *   yield* parser.end()\n * }\n *\n * const src: string = ...\n * const lexer = new Lexer()\n * for (const token of parse(src, lexer)) {\n *   // token: Token\n * }\n * ```\n */\nclass Parser {\n    /**\n     * @param onNewLine - If defined, called separately with the start position of\n     *   each new line (in `parse()`, including the start of input).\n     */\n    constructor(onNewLine) {\n        /** If true, space and sequence indicators count as indentation */\n        this.atNewLine = true;\n        /** If true, next token is a scalar value */\n        this.atScalar = false;\n        /** Current indentation level */\n        this.indent = 0;\n        /** Current offset since the start of parsing */\n        this.offset = 0;\n        /** On the same line with a block map key */\n        this.onKeyLine = false;\n        /** Top indicates the node that's currently being built */\n        this.stack = [];\n        /** The source of the current token, set in parse() */\n        this.source = '';\n        /** The type of the current token, set in parse() */\n        this.type = '';\n        // Must be defined after `next()`\n        this.lexer = new lexer.Lexer();\n        this.onNewLine = onNewLine;\n    }\n    /**\n     * Parse `source` as a YAML stream.\n     * If `incomplete`, a part of the last line may be left as a buffer for the next call.\n     *\n     * Errors are not thrown, but yielded as `{ type: 'error', message }` tokens.\n     *\n     * @returns A generator of tokens representing each directive, document, and other structure.\n     */\n    *parse(source, incomplete = false) {\n        if (this.onNewLine && this.offset === 0)\n            this.onNewLine(0);\n        for (const lexeme of this.lexer.lex(source, incomplete))\n            yield* this.next(lexeme);\n        if (!incomplete)\n            yield* this.end();\n    }\n    /**\n     * Advance the parser by the `source` of one lexical token.\n     */\n    *next(source) {\n        this.source = source;\n        if (node_process.env.LOG_TOKENS)\n            console.log('|', cst.prettyToken(source));\n        if (this.atScalar) {\n            this.atScalar = false;\n            yield* this.step();\n            this.offset += source.length;\n            return;\n        }\n        const type = cst.tokenType(source);\n        if (!type) {\n            const message = `Not a YAML token: ${source}`;\n            yield* this.pop({ type: 'error', offset: this.offset, message, source });\n            this.offset += source.length;\n        }\n        else if (type === 'scalar') {\n            this.atNewLine = false;\n            this.atScalar = true;\n            this.type = 'scalar';\n        }\n        else {\n            this.type = type;\n            yield* this.step();\n            switch (type) {\n                case 'newline':\n                    this.atNewLine = true;\n                    this.indent = 0;\n                    if (this.onNewLine)\n                        this.onNewLine(this.offset + source.length);\n                    break;\n                case 'space':\n                    if (this.atNewLine && source[0] === ' ')\n                        this.indent += source.length;\n                    break;\n                case 'explicit-key-ind':\n                case 'map-value-ind':\n                case 'seq-item-ind':\n                    if (this.atNewLine)\n                        this.indent += source.length;\n                    break;\n                case 'doc-mode':\n                case 'flow-error-end':\n                    return;\n                default:\n                    this.atNewLine = false;\n            }\n            this.offset += source.length;\n        }\n    }\n    /** Call at end of input to push out any remaining constructions */\n    *end() {\n        while (this.stack.length > 0)\n            yield* this.pop();\n    }\n    get sourceToken() {\n        const st = {\n            type: this.type,\n            offset: this.offset,\n            indent: this.indent,\n            source: this.source\n        };\n        return st;\n    }\n    *step() {\n        const top = this.peek(1);\n        if (this.type === 'doc-end' && top?.type !== 'doc-end') {\n            while (this.stack.length > 0)\n                yield* this.pop();\n            this.stack.push({\n                type: 'doc-end',\n                offset: this.offset,\n                source: this.source\n            });\n            return;\n        }\n        if (!top)\n            return yield* this.stream();\n        switch (top.type) {\n            case 'document':\n                return yield* this.document(top);\n            case 'alias':\n            case 'scalar':\n            case 'single-quoted-scalar':\n            case 'double-quoted-scalar':\n                return yield* this.scalar(top);\n            case 'block-scalar':\n                return yield* this.blockScalar(top);\n            case 'block-map':\n                return yield* this.blockMap(top);\n            case 'block-seq':\n                return yield* this.blockSequence(top);\n            case 'flow-collection':\n                return yield* this.flowCollection(top);\n            case 'doc-end':\n                return yield* this.documentEnd(top);\n        }\n        /* istanbul ignore next should not happen */\n        yield* this.pop();\n    }\n    peek(n) {\n        return this.stack[this.stack.length - n];\n    }\n    *pop(error) {\n        const token = error ?? this.stack.pop();\n        /* istanbul ignore if should not happen */\n        if (!token) {\n            const message = 'Tried to pop an empty stack';\n            yield { type: 'error', offset: this.offset, source: '', message };\n        }\n        else if (this.stack.length === 0) {\n            yield token;\n        }\n        else {\n            const top = this.peek(1);\n            if (token.type === 'block-scalar') {\n                // Block scalars use their parent rather than header indent\n                token.indent = 'indent' in top ? top.indent : 0;\n            }\n            else if (token.type === 'flow-collection' && top.type === 'document') {\n                // Ignore all indent for top-level flow collections\n                token.indent = 0;\n            }\n            if (token.type === 'flow-collection')\n                fixFlowSeqItems(token);\n            switch (top.type) {\n                case 'document':\n                    top.value = token;\n                    break;\n                case 'block-scalar':\n                    top.props.push(token); // error\n                    break;\n                case 'block-map': {\n                    const it = top.items[top.items.length - 1];\n                    if (it.value) {\n                        top.items.push({ start: [], key: token, sep: [] });\n                        this.onKeyLine = true;\n                        return;\n                    }\n                    else if (it.sep) {\n                        it.value = token;\n                    }\n                    else {\n                        Object.assign(it, { key: token, sep: [] });\n                        this.onKeyLine = !it.explicitKey;\n                        return;\n                    }\n                    break;\n                }\n                case 'block-seq': {\n                    const it = top.items[top.items.length - 1];\n                    if (it.value)\n                        top.items.push({ start: [], value: token });\n                    else\n                        it.value = token;\n                    break;\n                }\n                case 'flow-collection': {\n                    const it = top.items[top.items.length - 1];\n                    if (!it || it.value)\n                        top.items.push({ start: [], key: token, sep: [] });\n                    else if (it.sep)\n                        it.value = token;\n                    else\n                        Object.assign(it, { key: token, sep: [] });\n                    return;\n                }\n                /* istanbul ignore next should not happen */\n                default:\n                    yield* this.pop();\n                    yield* this.pop(token);\n            }\n            if ((top.type === 'document' ||\n                top.type === 'block-map' ||\n                top.type === 'block-seq') &&\n                (token.type === 'block-map' || token.type === 'block-seq')) {\n                const last = token.items[token.items.length - 1];\n                if (last &&\n                    !last.sep &&\n                    !last.value &&\n                    last.start.length > 0 &&\n                    findNonEmptyIndex(last.start) === -1 &&\n                    (token.indent === 0 ||\n                        last.start.every(st => st.type !== 'comment' || st.indent < token.indent))) {\n                    if (top.type === 'document')\n                        top.end = last.start;\n                    else\n                        top.items.push({ start: last.start });\n                    token.items.splice(-1, 1);\n                }\n            }\n        }\n    }\n    *stream() {\n        switch (this.type) {\n            case 'directive-line':\n                yield { type: 'directive', offset: this.offset, source: this.source };\n                return;\n            case 'byte-order-mark':\n            case 'space':\n            case 'comment':\n            case 'newline':\n                yield this.sourceToken;\n                return;\n            case 'doc-mode':\n            case 'doc-start': {\n                const doc = {\n                    type: 'document',\n                    offset: this.offset,\n                    start: []\n                };\n                if (this.type === 'doc-start')\n                    doc.start.push(this.sourceToken);\n                this.stack.push(doc);\n                return;\n            }\n        }\n        yield {\n            type: 'error',\n            offset: this.offset,\n            message: `Unexpected ${this.type} token in YAML stream`,\n            source: this.source\n        };\n    }\n    *document(doc) {\n        if (doc.value)\n            return yield* this.lineEnd(doc);\n        switch (this.type) {\n            case 'doc-start': {\n                if (findNonEmptyIndex(doc.start) !== -1) {\n                    yield* this.pop();\n                    yield* this.step();\n                }\n                else\n                    doc.start.push(this.sourceToken);\n                return;\n            }\n            case 'anchor':\n            case 'tag':\n            case 'space':\n            case 'comment':\n            case 'newline':\n                doc.start.push(this.sourceToken);\n                return;\n        }\n        const bv = this.startBlockValue(doc);\n        if (bv)\n            this.stack.push(bv);\n        else {\n            yield {\n                type: 'error',\n                offset: this.offset,\n                message: `Unexpected ${this.type} token in YAML document`,\n                source: this.source\n            };\n        }\n    }\n    *scalar(scalar) {\n        if (this.type === 'map-value-ind') {\n            const prev = getPrevProps(this.peek(2));\n            const start = getFirstKeyStartProps(prev);\n            let sep;\n            if (scalar.end) {\n                sep = scalar.end;\n                sep.push(this.sourceToken);\n                delete scalar.end;\n            }\n            else\n                sep = [this.sourceToken];\n            const map = {\n                type: 'block-map',\n                offset: scalar.offset,\n                indent: scalar.indent,\n                items: [{ start, key: scalar, sep }]\n            };\n            this.onKeyLine = true;\n            this.stack[this.stack.length - 1] = map;\n        }\n        else\n            yield* this.lineEnd(scalar);\n    }\n    *blockScalar(scalar) {\n        switch (this.type) {\n            case 'space':\n            case 'comment':\n            case 'newline':\n                scalar.props.push(this.sourceToken);\n                return;\n            case 'scalar':\n                scalar.source = this.source;\n                // block-scalar source includes trailing newline\n                this.atNewLine = true;\n                this.indent = 0;\n                if (this.onNewLine) {\n                    let nl = this.source.indexOf('\\n') + 1;\n                    while (nl !== 0) {\n                        this.onNewLine(this.offset + nl);\n                        nl = this.source.indexOf('\\n', nl) + 1;\n                    }\n                }\n                yield* this.pop();\n                break;\n            /* istanbul ignore next should not happen */\n            default:\n                yield* this.pop();\n                yield* this.step();\n        }\n    }\n    *blockMap(map) {\n        const it = map.items[map.items.length - 1];\n        // it.sep is true-ish if pair already has key or : separator\n        switch (this.type) {\n            case 'newline':\n                this.onKeyLine = false;\n                if (it.value) {\n                    const end = 'end' in it.value ? it.value.end : undefined;\n                    const last = Array.isArray(end) ? end[end.length - 1] : undefined;\n                    if (last?.type === 'comment')\n                        end?.push(this.sourceToken);\n                    else\n                        map.items.push({ start: [this.sourceToken] });\n                }\n                else if (it.sep) {\n                    it.sep.push(this.sourceToken);\n                }\n                else {\n                    it.start.push(this.sourceToken);\n                }\n                return;\n            case 'space':\n            case 'comment':\n                if (it.value) {\n                    map.items.push({ start: [this.sourceToken] });\n                }\n                else if (it.sep) {\n                    it.sep.push(this.sourceToken);\n                }\n                else {\n                    if (this.atIndentedComment(it.start, map.indent)) {\n                        const prev = map.items[map.items.length - 2];\n                        const end = prev?.value?.end;\n                        if (Array.isArray(end)) {\n                            arrayPushArray(end, it.start);\n                            end.push(this.sourceToken);\n                            map.items.pop();\n                            return;\n                        }\n                    }\n                    it.start.push(this.sourceToken);\n                }\n                return;\n        }\n        if (this.indent >= map.indent) {\n            const atMapIndent = !this.onKeyLine && this.indent === map.indent;\n            const atNextItem = atMapIndent &&\n                (it.sep || it.explicitKey) &&\n                this.type !== 'seq-item-ind';\n            // For empty nodes, assign newline-separated not indented empty tokens to following node\n            let start = [];\n            if (atNextItem && it.sep && !it.value) {\n                const nl = [];\n                for (let i = 0; i < it.sep.length; ++i) {\n                    const st = it.sep[i];\n                    switch (st.type) {\n                        case 'newline':\n                            nl.push(i);\n                            break;\n                        case 'space':\n                            break;\n                        case 'comment':\n                            if (st.indent > map.indent)\n                                nl.length = 0;\n                            break;\n                        default:\n                            nl.length = 0;\n                    }\n                }\n                if (nl.length >= 2)\n                    start = it.sep.splice(nl[1]);\n            }\n            switch (this.type) {\n                case 'anchor':\n                case 'tag':\n                    if (atNextItem || it.value) {\n                        start.push(this.sourceToken);\n                        map.items.push({ start });\n                        this.onKeyLine = true;\n                    }\n                    else if (it.sep) {\n                        it.sep.push(this.sourceToken);\n                    }\n                    else {\n                        it.start.push(this.sourceToken);\n                    }\n                    return;\n                case 'explicit-key-ind':\n                    if (!it.sep && !it.explicitKey) {\n                        it.start.push(this.sourceToken);\n                        it.explicitKey = true;\n                    }\n                    else if (atNextItem || it.value) {\n                        start.push(this.sourceToken);\n                        map.items.push({ start, explicitKey: true });\n                    }\n                    else {\n                        this.stack.push({\n                            type: 'block-map',\n                            offset: this.offset,\n                            indent: this.indent,\n                            items: [{ start: [this.sourceToken], explicitKey: true }]\n                        });\n                    }\n                    this.onKeyLine = true;\n                    return;\n                case 'map-value-ind':\n                    if (it.explicitKey) {\n                        if (!it.sep) {\n                            if (includesToken(it.start, 'newline')) {\n                                Object.assign(it, { key: null, sep: [this.sourceToken] });\n                            }\n                            else {\n                                const start = getFirstKeyStartProps(it.start);\n                                this.stack.push({\n                                    type: 'block-map',\n                                    offset: this.offset,\n                                    indent: this.indent,\n                                    items: [{ start, key: null, sep: [this.sourceToken] }]\n                                });\n                            }\n                        }\n                        else if (it.value) {\n                            map.items.push({ start: [], key: null, sep: [this.sourceToken] });\n                        }\n                        else if (includesToken(it.sep, 'map-value-ind')) {\n                            this.stack.push({\n                                type: 'block-map',\n                                offset: this.offset,\n                                indent: this.indent,\n                                items: [{ start, key: null, sep: [this.sourceToken] }]\n                            });\n                        }\n                        else if (isFlowToken(it.key) &&\n                            !includesToken(it.sep, 'newline')) {\n                            const start = getFirstKeyStartProps(it.start);\n                            const key = it.key;\n                            const sep = it.sep;\n                            sep.push(this.sourceToken);\n                            // @ts-expect-error type guard is wrong here\n                            delete it.key;\n                            // @ts-expect-error type guard is wrong here\n                            delete it.sep;\n                            this.stack.push({\n                                type: 'block-map',\n                                offset: this.offset,\n                                indent: this.indent,\n                                items: [{ start, key, sep }]\n                            });\n                        }\n                        else if (start.length > 0) {\n                            // Not actually at next item\n                            it.sep = it.sep.concat(start, this.sourceToken);\n                        }\n                        else {\n                            it.sep.push(this.sourceToken);\n                        }\n                    }\n                    else {\n                        if (!it.sep) {\n                            Object.assign(it, { key: null, sep: [this.sourceToken] });\n                        }\n                        else if (it.value || atNextItem) {\n                            map.items.push({ start, key: null, sep: [this.sourceToken] });\n                        }\n                        else if (includesToken(it.sep, 'map-value-ind')) {\n                            this.stack.push({\n                                type: 'block-map',\n                                offset: this.offset,\n                                indent: this.indent,\n                                items: [{ start: [], key: null, sep: [this.sourceToken] }]\n                            });\n                        }\n                        else {\n                            it.sep.push(this.sourceToken);\n                        }\n                    }\n                    this.onKeyLine = true;\n                    return;\n                case 'alias':\n                case 'scalar':\n                case 'single-quoted-scalar':\n                case 'double-quoted-scalar': {\n                    const fs = this.flowScalar(this.type);\n                    if (atNextItem || it.value) {\n                        map.items.push({ start, key: fs, sep: [] });\n                        this.onKeyLine = true;\n                    }\n                    else if (it.sep) {\n                        this.stack.push(fs);\n                    }\n                    else {\n                        Object.assign(it, { key: fs, sep: [] });\n                        this.onKeyLine = true;\n                    }\n                    return;\n                }\n                default: {\n                    const bv = this.startBlockValue(map);\n                    if (bv) {\n                        if (bv.type === 'block-seq') {\n                            if (!it.explicitKey &&\n                                it.sep &&\n                                !includesToken(it.sep, 'newline')) {\n                                yield* this.pop({\n                                    type: 'error',\n                                    offset: this.offset,\n                                    message: 'Unexpected block-seq-ind on same line with key',\n                                    source: this.source\n                                });\n                                return;\n                            }\n                        }\n                        else if (atMapIndent) {\n                            map.items.push({ start });\n                        }\n                        this.stack.push(bv);\n                        return;\n                    }\n                }\n            }\n        }\n        yield* this.pop();\n        yield* this.step();\n    }\n    *blockSequence(seq) {\n        const it = seq.items[seq.items.length - 1];\n        switch (this.type) {\n            case 'newline':\n                if (it.value) {\n                    const end = 'end' in it.value ? it.value.end : undefined;\n                    const last = Array.isArray(end) ? end[end.length - 1] : undefined;\n                    if (last?.type === 'comment')\n                        end?.push(this.sourceToken);\n                    else\n                        seq.items.push({ start: [this.sourceToken] });\n                }\n                else\n                    it.start.push(this.sourceToken);\n                return;\n            case 'space':\n            case 'comment':\n                if (it.value)\n                    seq.items.push({ start: [this.sourceToken] });\n                else {\n                    if (this.atIndentedComment(it.start, seq.indent)) {\n                        const prev = seq.items[seq.items.length - 2];\n                        const end = prev?.value?.end;\n                        if (Array.isArray(end)) {\n                            arrayPushArray(end, it.start);\n                            end.push(this.sourceToken);\n                            seq.items.pop();\n                            return;\n                        }\n                    }\n                    it.start.push(this.sourceToken);\n                }\n                return;\n            case 'anchor':\n            case 'tag':\n                if (it.value || this.indent <= seq.indent)\n                    break;\n                it.start.push(this.sourceToken);\n                return;\n            case 'seq-item-ind':\n                if (this.indent !== seq.indent)\n                    break;\n                if (it.value || includesToken(it.start, 'seq-item-ind'))\n                    seq.items.push({ start: [this.sourceToken] });\n                else\n                    it.start.push(this.sourceToken);\n                return;\n        }\n        if (this.indent > seq.indent) {\n            const bv = this.startBlockValue(seq);\n            if (bv) {\n                this.stack.push(bv);\n                return;\n            }\n        }\n        yield* this.pop();\n        yield* this.step();\n    }\n    *flowCollection(fc) {\n        const it = fc.items[fc.items.length - 1];\n        if (this.type === 'flow-error-end') {\n            let top;\n            do {\n                yield* this.pop();\n                top = this.peek(1);\n            } while (top?.type === 'flow-collection');\n        }\n        else if (fc.end.length === 0) {\n            switch (this.type) {\n                case 'comma':\n                case 'explicit-key-ind':\n                    if (!it || it.sep)\n                        fc.items.push({ start: [this.sourceToken] });\n                    else\n                        it.start.push(this.sourceToken);\n                    return;\n                case 'map-value-ind':\n                    if (!it || it.value)\n                        fc.items.push({ start: [], key: null, sep: [this.sourceToken] });\n                    else if (it.sep)\n                        it.sep.push(this.sourceToken);\n                    else\n                        Object.assign(it, { key: null, sep: [this.sourceToken] });\n                    return;\n                case 'space':\n                case 'comment':\n                case 'newline':\n                case 'anchor':\n                case 'tag':\n                    if (!it || it.value)\n                        fc.items.push({ start: [this.sourceToken] });\n                    else if (it.sep)\n                        it.sep.push(this.sourceToken);\n                    else\n                        it.start.push(this.sourceToken);\n                    return;\n                case 'alias':\n                case 'scalar':\n                case 'single-quoted-scalar':\n                case 'double-quoted-scalar': {\n                    const fs = this.flowScalar(this.type);\n                    if (!it || it.value)\n                        fc.items.push({ start: [], key: fs, sep: [] });\n                    else if (it.sep)\n                        this.stack.push(fs);\n                    else\n                        Object.assign(it, { key: fs, sep: [] });\n                    return;\n                }\n                case 'flow-map-end':\n                case 'flow-seq-end':\n                    fc.end.push(this.sourceToken);\n                    return;\n            }\n            const bv = this.startBlockValue(fc);\n            /* istanbul ignore else should not happen */\n            if (bv)\n                this.stack.push(bv);\n            else {\n                yield* this.pop();\n                yield* this.step();\n            }\n        }\n        else {\n            const parent = this.peek(2);\n            if (parent.type === 'block-map' &&\n                ((this.type === 'map-value-ind' && parent.indent === fc.indent) ||\n                    (this.type === 'newline' &&\n                        !parent.items[parent.items.length - 1].sep))) {\n                yield* this.pop();\n                yield* this.step();\n            }\n            else if (this.type === 'map-value-ind' &&\n                parent.type !== 'flow-collection') {\n                const prev = getPrevProps(parent);\n                const start = getFirstKeyStartProps(prev);\n                fixFlowSeqItems(fc);\n                const sep = fc.end.splice(1, fc.end.length);\n                sep.push(this.sourceToken);\n                const map = {\n                    type: 'block-map',\n                    offset: fc.offset,\n                    indent: fc.indent,\n                    items: [{ start, key: fc, sep }]\n                };\n                this.onKeyLine = true;\n                this.stack[this.stack.length - 1] = map;\n            }\n            else {\n                yield* this.lineEnd(fc);\n            }\n        }\n    }\n    flowScalar(type) {\n        if (this.onNewLine) {\n            let nl = this.source.indexOf('\\n') + 1;\n            while (nl !== 0) {\n                this.onNewLine(this.offset + nl);\n                nl = this.source.indexOf('\\n', nl) + 1;\n            }\n        }\n        return {\n            type,\n            offset: this.offset,\n            indent: this.indent,\n            source: this.source\n        };\n    }\n    startBlockValue(parent) {\n        switch (this.type) {\n            case 'alias':\n            case 'scalar':\n            case 'single-quoted-scalar':\n            case 'double-quoted-scalar':\n                return this.flowScalar(this.type);\n            case 'block-scalar-header':\n                return {\n                    type: 'block-scalar',\n                    offset: this.offset,\n                    indent: this.indent,\n                    props: [this.sourceToken],\n                    source: ''\n                };\n            case 'flow-map-start':\n            case 'flow-seq-start':\n                return {\n                    type: 'flow-collection',\n                    offset: this.offset,\n                    indent: this.indent,\n                    start: this.sourceToken,\n                    items: [],\n                    end: []\n                };\n            case 'seq-item-ind':\n                return {\n                    type: 'block-seq',\n                    offset: this.offset,\n                    indent: this.indent,\n                    items: [{ start: [this.sourceToken] }]\n                };\n            case 'explicit-key-ind': {\n                this.onKeyLine = true;\n                const prev = getPrevProps(parent);\n                const start = getFirstKeyStartProps(prev);\n                start.push(this.sourceToken);\n                return {\n                    type: 'block-map',\n                    offset: this.offset,\n                    indent: this.indent,\n                    items: [{ start, explicitKey: true }]\n                };\n            }\n            case 'map-value-ind': {\n                this.onKeyLine = true;\n                const prev = getPrevProps(parent);\n                const start = getFirstKeyStartProps(prev);\n                return {\n                    type: 'block-map',\n                    offset: this.offset,\n                    indent: this.indent,\n                    items: [{ start, key: null, sep: [this.sourceToken] }]\n                };\n            }\n        }\n        return null;\n    }\n    atIndentedComment(start, indent) {\n        if (this.type !== 'comment')\n            return false;\n        if (this.indent <= indent)\n            return false;\n        return start.every(st => st.type === 'newline' || st.type === 'space');\n    }\n    *documentEnd(docEnd) {\n        if (this.type !== 'doc-mode') {\n            if (docEnd.end)\n                docEnd.end.push(this.sourceToken);\n            else\n                docEnd.end = [this.sourceToken];\n            if (this.type === 'newline')\n                yield* this.pop();\n        }\n    }\n    *lineEnd(token) {\n        switch (this.type) {\n            case 'comma':\n            case 'doc-start':\n            case 'doc-end':\n            case 'flow-seq-end':\n            case 'flow-map-end':\n            case 'map-value-ind':\n                yield* this.pop();\n                yield* this.step();\n                break;\n            case 'newline':\n                this.onKeyLine = false;\n            // fallthrough\n            case 'space':\n            case 'comment':\n            default:\n                // all other values are errors\n                if (token.end)\n                    token.end.push(this.sourceToken);\n                else\n                    token.end = [this.sourceToken];\n                if (this.type === 'newline')\n                    yield* this.pop();\n        }\n    }\n}\n\nexports.Parser = Parser;\n", "'use strict';\n\nvar composer = require('./compose/composer.js');\nvar Document = require('./doc/Document.js');\nvar errors = require('./errors.js');\nvar log = require('./log.js');\nvar identity = require('./nodes/identity.js');\nvar lineCounter = require('./parse/line-counter.js');\nvar parser = require('./parse/parser.js');\n\nfunction parseOptions(options) {\n    const prettyErrors = options.prettyErrors !== false;\n    const lineCounter$1 = options.lineCounter || (prettyErrors && new lineCounter.LineCounter()) || null;\n    return { lineCounter: lineCounter$1, prettyErrors };\n}\n/**\n * Parse the input as a stream of YAML documents.\n *\n * Documents should be separated from each other by `...` or `---` marker lines.\n *\n * @returns If an empty `docs` array is returned, it will be of type\n *   EmptyStream and contain additional stream information. In\n *   TypeScript, you should use `'empty' in docs` as a type guard for it.\n */\nfunction parseAllDocuments(source, options = {}) {\n    const { lineCounter, prettyErrors } = parseOptions(options);\n    const parser$1 = new parser.Parser(lineCounter?.addNewLine);\n    const composer$1 = new composer.Composer(options);\n    const docs = Array.from(composer$1.compose(parser$1.parse(source)));\n    if (prettyErrors && lineCounter)\n        for (const doc of docs) {\n            doc.errors.forEach(errors.prettifyError(source, lineCounter));\n            doc.warnings.forEach(errors.prettifyError(source, lineCounter));\n        }\n    if (docs.length > 0)\n        return docs;\n    return Object.assign([], { empty: true }, composer$1.streamInfo());\n}\n/** Parse an input string into a single YAML.Document */\nfunction parseDocument(source, options = {}) {\n    const { lineCounter, prettyErrors } = parseOptions(options);\n    const parser$1 = new parser.Parser(lineCounter?.addNewLine);\n    const composer$1 = new composer.Composer(options);\n    // `doc` is always set by compose.end(true) at the very latest\n    let doc = null;\n    for (const _doc of composer$1.compose(parser$1.parse(source), true, source.length)) {\n        if (!doc)\n            doc = _doc;\n        else if (doc.options.logLevel !== 'silent') {\n            doc.errors.push(new errors.YAMLParseError(_doc.range.slice(0, 2), 'MULTIPLE_DOCS', 'Source contains multiple documents; please use YAML.parseAllDocuments()'));\n            break;\n        }\n    }\n    if (prettyErrors && lineCounter) {\n        doc.errors.forEach(errors.prettifyError(source, lineCounter));\n        doc.warnings.forEach(errors.prettifyError(source, lineCounter));\n    }\n    return doc;\n}\nfunction parse(src, reviver, options) {\n    let _reviver = undefined;\n    if (typeof reviver === 'function') {\n        _reviver = reviver;\n    }\n    else if (options === undefined && reviver && typeof reviver === 'object') {\n        options = reviver;\n    }\n    const doc = parseDocument(src, options);\n    if (!doc)\n        return null;\n    doc.warnings.forEach(warning => log.warn(doc.options.logLevel, warning));\n    if (doc.errors.length > 0) {\n        if (doc.options.logLevel !== 'silent')\n            throw doc.errors[0];\n        else\n            doc.errors = [];\n    }\n    return doc.toJS(Object.assign({ reviver: _reviver }, options));\n}\nfunction stringify(value, replacer, options) {\n    let _replacer = null;\n    if (typeof replacer === 'function' || Array.isArray(replacer)) {\n        _replacer = replacer;\n    }\n    else if (options === undefined && replacer) {\n        options = replacer;\n    }\n    if (typeof options === 'string')\n        options = options.length;\n    if (typeof options === 'number') {\n        const indent = Math.round(options);\n        options = indent < 1 ? undefined : indent > 8 ? { indent: 8 } : { indent };\n    }\n    if (value === undefined) {\n        const { keepUndefined } = options ?? replacer ?? {};\n        if (!keepUndefined)\n            return undefined;\n    }\n    if (identity.isDocument(value) && !_replacer)\n        return value.toString(options);\n    return new Document.Document(value, _replacer, options).toString(options);\n}\n\nexports.parse = parse;\nexports.parseAllDocuments = parseAllDocuments;\nexports.parseDocument = parseDocument;\nexports.stringify = stringify;\n", "'use strict';\n\nvar composer = require('./compose/composer.js');\nvar Document = require('./doc/Document.js');\nvar Schema = require('./schema/Schema.js');\nvar errors = require('./errors.js');\nvar Alias = require('./nodes/Alias.js');\nvar identity = require('./nodes/identity.js');\nvar Pair = require('./nodes/Pair.js');\nvar Scalar = require('./nodes/Scalar.js');\nvar YAMLMap = require('./nodes/YAMLMap.js');\nvar YAMLSeq = require('./nodes/YAMLSeq.js');\nvar cst = require('./parse/cst.js');\nvar lexer = require('./parse/lexer.js');\nvar lineCounter = require('./parse/line-counter.js');\nvar parser = require('./parse/parser.js');\nvar publicApi = require('./public-api.js');\nvar visit = require('./visit.js');\n\n\n\nexports.Composer = composer.Composer;\nexports.Document = Document.Document;\nexports.Schema = Schema.Schema;\nexports.YAMLError = errors.YAMLError;\nexports.YAMLParseError = errors.YAMLParseError;\nexports.YAMLWarning = errors.YAMLWarning;\nexports.Alias = Alias.Alias;\nexports.isAlias = identity.isAlias;\nexports.isCollection = identity.isCollection;\nexports.isDocument = identity.isDocument;\nexports.isMap = identity.isMap;\nexports.isNode = identity.isNode;\nexports.isPair = identity.isPair;\nexports.isScalar = identity.isScalar;\nexports.isSeq = identity.isSeq;\nexports.Pair = Pair.Pair;\nexports.Scalar = Scalar.Scalar;\nexports.YAMLMap = YAMLMap.YAMLMap;\nexports.YAMLSeq = YAMLSeq.YAMLSeq;\nexports.CST = cst;\nexports.Lexer = lexer.Lexer;\nexports.LineCounter = lineCounter.LineCounter;\nexports.Parser = parser.Parser;\nexports.parse = publicApi.parse;\nexports.parseAllDocuments = publicApi.parseAllDocuments;\nexports.parseDocument = publicApi.parseDocument;\nexports.stringify = publicApi.stringify;\nexports.visit = visit.visit;\nexports.visitAsync = visit.visitAsync;\n", "/**\n * config.ts \u2014 the `workers` section of the PAI config file (CONFIG_FILE,\n * see src/daemon/config.ts's paiConfigFilePath \u2014 ~/.claude/pai/config.yaml\n * today, config.json until `pai config yaml` runs).\n *\n * Everything that knows about worker providers reads this module: the CLI\n * (`pai worker \u2026`), the MCP tools (worker_*), and the Agent-routing hook.\n * Keep it free of commander/MCP imports so all three layers stay thin over it.\n *\n * Keys are never stored here \u2014 only paths to 0600 files. A provider without a\n * keyFile is a local server and gets the placeholder token \"local\".\n *\n * `protocol: \"openai\"` providers run through the PAI proxy (src/workers/proxy):\n * `upstreamUrl` is their Chat Completions base, and `run` points\n * ANTHROPIC_BASE_URL at the local proxy with the provider name in the path.\n * `engine: \"codex\"` providers run through the Codex CLI instead of Claude\n * Code.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { CONFIG_FILE, readMainConfigRaw, writeMainConfigRaw } from \"../daemon/config.js\";\nimport { paiHomePath } from \"../config/pai-home.js\";\nimport { contextWindowFromModelId, DEFAULT_CONTEXT_WINDOW } from \"../utils/model-window.js\";\nimport { readWorkersYaml, workersYamlPath, writeWorkersYaml, type WorkersYamlData } from \"./workers-config.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Wire protocol a provider speaks: \"anthropic\" natively, \"openai\" through the\n * PAI proxy (which translates the Anthropic Messages API to Chat Completions).\n */\nexport type WorkerProtocol = \"anthropic\" | \"openai\";\n\n/**\n * Runner executable behind a provider: Claude Code, the Codex CLI, or the\n * \"image\" engine (src/workers/engines/image.ts \u2014 an OpenAI-compatible\n * images API, not a claude/codex spawn).\n */\nexport type WorkerEngine = \"claude\" | \"codex\" | \"image\";\n\n/** One quota window the statusline renders for a provider (e.g. \"5h\", \"7d\"). */\nexport interface UsageWindow {\n  /** Window label shown in the statusline, e.g. \"5h\". */\n  name: string;\n  /** jq expression against the usage response yielding a percent 0\u2013100. */\n  percent: string;\n  /** jq expression against the usage response yielding the reset time. */\n  resetAt?: string;\n  /** How resetAt is interpreted: epoch ms (default), epoch s, or ISO string. */\n  resetUnit?: \"ms\" | \"s\" | \"iso\";\n}\n\n/**\n * How the statusline fetches and renders a provider's plan quota. The block\n * names a JSON GET endpoint plus per-window jq expressions, so a new provider\n * is config, not code in statusline-command.sh.\n */\nexport interface ProviderUsage {\n  /** GET endpoint returning the usage JSON. */\n  url: string;\n  /**\n   * Auth header template, default \"Authorization: Bearer\"; the key from\n   * keyFile is appended after a space. A value without a space (e.g.\n   * \"x-api-key\") is sent as \"<authHeader>: <key>\".\n   */\n  authHeader?: string;\n  /** Display label for the usage segments, default = provider name. */\n  label?: string;\n  windows: UsageWindow[];\n  /** Statusline cache TTL in seconds, default 60. */\n  ttlSeconds?: number;\n}\n\nexport interface WorkerProvider {\n  enabled: boolean;\n  /** Wire protocol the baseUrl speaks. */\n  protocol: WorkerProtocol;\n  /** Anthropic-compatible Messages API base. */\n  baseUrl: string;\n  /** 0600 file holding the auth token; null for local servers (\"local\"). */\n  keyFile: string | null;\n  /**\n   * The auth token itself, inline in workers.yaml. Wins over keyFile when\n   * both are set (`pai worker config check` notices this). Keeping the key\n   * out of a separate file is the operator's explicit call \u2014 the file this\n   * lives in must be 0600 (writeWorkersYamlText enforces that) and is never\n   * committed. See resolveProviderKey for the one place this is read.\n   */\n  key?: string;\n  /** Model id per capability; see MODEL_CAPABILITIES. Only default is required. */\n  models: { default: string } & Partial<Record<ModelCapability, string>>;\n  /**\n   * Model id \u2192 tier alias, overriding the built-in mapping (models.fast \u2192\n   * haiku tier, models.default \u2192 sonnet tier). Lets a provider pin an extra\n   * model id to a tier, e.g. a heavyweight default to the opus tier.\n   */\n  modelTiers?: Record<string, ModelTier>;\n  /** Extra environment variables for runs through this provider (string values). */\n  env: Record<string, string>;\n  note?: string;\n  /**\n   * OpenAI Chat Completions base (e.g. \"https://api.openai.com/v1\"). Required\n   * for protocol \"openai\"; read by the PAI proxy, never by the runner.\n   */\n  upstreamUrl?: string;\n  /** Runner for this provider; \"codex\" goes through the Codex CLI. */\n  engine?: WorkerEngine;\n  /** Optional shell command printing 0\u2013100 (percent of quota used). */\n  quotaProbe?: string;\n  /** Auto-routing skips the provider at or above this percentage. Default 95. */\n  quotaSkipAt?: number;\n  /**\n   * Context window of the provider's model, for the context meter. No\n   * default: the meter only shows a window the init event announced (or\n   * this explicit value, for engines without one, e.g. codex).\n   */\n  contextWindow?: number;\n  /** Cost tier 1 (cheapest) \u2026 5 (most expensive); classes cap it via maxCostTier. */\n  costTier?: number;\n  /** Capability tags; classes filter auto-routing via requireTags. */\n  tags?: ProviderTag[];\n  /** Statusline plan-quota block; see ProviderUsage. Absent = \"usage n/a\". */\n  usage?: ProviderUsage;\n  /**\n   * True only for the synthetic built-in \"anthropic\" provider (see\n   * ANTHROPIC_NATIVE): plain Claude Code, on its own OAuth/Max-plan login \u2014\n   * no baseUrl, no key file, no config entry. Never set by parseProvider.\n   */\n  native?: boolean;\n}\n\n/**\n * Reserved provider name for plain Anthropic: Claude Code's own OAuth/Max-plan\n * login, no base URL override and no API key. It never needs (or accepts) a\n * `providers.anthropic` config entry \u2014 resolveTarget/mustExist synthesize it\n * on demand via `nativeAnthropicProvider()`.\n */\nexport const ANTHROPIC_NATIVE = \"anthropic\";\n\n/**\n * Models the built-in provider runs on. This is the only place a model id is\n * named for it: run.ts resolves the class capability against this table like\n * it does for any configured provider and passes `--model` explicitly.\n *\n * Workers exist to parallelise and to save cost, so they must never inherit\n * the orchestrator's model. A bare headless `claude` takes the interactive\n * session default, and one probe came up on the most expensive tier because\n * the chat session had been switched to it. Sonnet is the working tier;\n * haiku serves the fast classes (spotcheck, simple). These are the Claude\n * Code CLI's own tier aliases, not pinned ids: the CLI resolves each to its\n * newest model on every run, so the tier tracks a release without a code\n * change here (adoptInitModel in run.ts swaps the alias for the init event's\n * resolved id once the run announces one).\n */\nexport const NATIVE_ANTHROPIC_MODELS: WorkerProvider[\"models\"] = {\n  default: \"sonnet\",\n  fast: \"haiku\",\n};\n\n/**\n * The synthetic provider object for ANTHROPIC_NATIVE. `baseUrl` is empty and\n * there is no key file, so buildRunEnv strips every provider env override;\n * the models come from NATIVE_ANTHROPIC_MODELS so a run always names its\n * model on the command line.\n */\nexport function nativeAnthropicProvider(\n  models: WorkerProvider[\"models\"] = NATIVE_ANTHROPIC_MODELS\n): WorkerProvider {\n  return {\n    enabled: true,\n    protocol: \"anthropic\",\n    baseUrl: \"\",\n    keyFile: null,\n    models: { ...models },\n    env: {},\n    native: true,\n  };\n}\n\n/**\n * Provider by name, synthesizing ANTHROPIC_NATIVE when it is asked for. Reads\n * `config.nativeModels` (workers.yaml's documented `providers.anthropic.models`\n * override, if any) so a config that pins a different default/fast id for the\n * built-in provider is honored everywhere a provider is resolved.\n */\nexport function getProviderOrNative(\n  config: { providers: Record<string, WorkerProvider>; nativeModels?: WorkerProvider[\"models\"] },\n  name: string\n): WorkerProvider | undefined {\n  if (name === ANTHROPIC_NATIVE) return nativeAnthropicProvider(config.nativeModels);\n  return config.providers[name];\n}\n\nexport interface WorkersPaneConfig {\n  enabled: boolean;\n  /** Font size (points) of the follow-pane profile's font. */\n  fontSize: number;\n  /** Seconds a pane lingers after its worker goes quiet. */\n  autoExitSecs: number;\n}\n\nexport interface WorkersRoutingConfig {\n  /** Provider names in preference order; first usable one wins. */\n  order: string[];\n  /** Minutes a provider sits in cooldown after a quota/rate failure. */\n  cooldownMinutes: number;\n  /** Reroute a failed-before-first-tool run to the next provider. */\n  retryOnQuota: boolean;\n}\n\n/** Sub-worker caps: how deep the worker tree may grow, how wide per parent. */\nexport interface WorkersTreeConfig {\n  /** Maximum nesting depth of sub-workers (top-level = 0). */\n  maxDepth: number;\n  /** Maximum concurrently running children per parent. */\n  maxChildren: number;\n}\n\n/** Cost/quality tier of a provider's model, 1 (cheapest) \u2026 5 (most expensive). */\nexport type CostTier = 1 | 2 | 3 | 4 | 5;\n\n/** The tier aliases the CLI and daemon tables understand \u2014 class proxies, not\n *  Anthropic model names: any provider's model maps onto one of these. */\nexport type ModelTier = \"haiku\" | \"sonnet\" | \"opus\";\n\nconst MODEL_TIERS: readonly ModelTier[] = [\"haiku\", \"sonnet\", \"opus\"];\n\nexport const DEFAULT_COST_TIER = 3;\n\n/** Tags a provider may carry; classes filter auto-routing on them. */\nexport const PROVIDER_TAGS = [\n  \"code\",\n  \"vision\",\n  \"image-gen\",\n  \"long-context\",\n  \"fast\",\n  \"reasoning\",\n] as const;\n\nexport type ProviderTag = (typeof PROVIDER_TAGS)[number];\n\n/** The standard task classes; `workers.classes` maps each to a target. */\nexport const WORKER_CLASSES = [\n  \"draft\",\n  \"plan\",\n  \"implement\",\n  \"review\",\n  \"research\",\n  \"spotcheck\",\n  \"simple\",\n  \"complex\",\n  \"image\",\n] as const;\n\nexport type WorkerClassName = (typeof WORKER_CLASSES)[number];\n\n/**\n * The well-known model capabilities \u2014 documented, and what the starter\n * workers.yaml and `pai worker model`'s listing show by name. The set is\n * open, though: a provider's `models` block may carry any capability name\n * matching CAPABILITY_NAME_RE (see isModelCapability), e.g. \"vision\" or\n * \"longcontext\" for a provider that serves them. \"default\" is the required\n * catch-all; the others name what a model is *for* \u2014 \"fast\" the cheap tier\n * (spotcheck, haiku-tier spawns), \"image\" the image class/capability.\n * Everything resolves through resolveModelCapability, falling back to\n * default; cross-provider preference for a capability is `capabilities:` in\n * workers.yaml (see resolveCapability).\n */\nexport const MODEL_CAPABILITIES = [\"default\", \"fast\", \"image\"] as const;\n\nexport type ModelCapability = string;\n\nexport const CAPABILITY_NAME_RE = /^[a-z][a-z0-9-]*$/;\n\n/** Is this string a syntactically valid capability name (open set)? */\nexport function isModelCapability(v: string): v is ModelCapability {\n  return CAPABILITY_NAME_RE.test(v);\n}\n\n/**\n * Which model capability a class runs on when its target names no alias: the\n * image class uses the image model, the cheap classes (spotcheck, simple) the\n * fast model, every other class the provider default. A provider without a\n * fast model falls back to its default (resolveModelCapability).\n */\nconst CLASS_MODEL_CAPABILITY: Record<WorkerClassName, ModelCapability> = {\n  draft: \"default\",\n  plan: \"default\",\n  implement: \"default\",\n  review: \"default\",\n  research: \"default\",\n  spotcheck: \"fast\",\n  simple: \"fast\",\n  complex: \"default\",\n  image: \"image\",\n};\n\n/** Capability for a run's class (default when unset or not a standard class). */\nexport function classModelCapability(className?: string): ModelCapability {\n  return (className && CLASS_MODEL_CAPABILITY[className as WorkerClassName]) || \"default\";\n}\n\n/**\n * A class target: \"<provider>\", \"<provider>/<modelAlias>\", or an object. The\n * object either pins a `provider` (plus optional `mcp` allowlist) or only\n * constrains auto-routing (`maxCostTier`, `requireTags`, per-class `order`).\n */\nexport type ClassTarget =\n  | string\n  | {\n      provider?: string;\n      mcp?: string[];\n      /** Auto-routing may only use providers at or below this cost tier. */\n      maxCostTier?: number;\n      /** Auto-routing may only use providers carrying all these tags. */\n      requireTags?: string[];\n      /** Provider order for this class; defaults to routing.order. */\n      order?: string[];\n    };\n\n/**\n * State of the machine-wide Claude Code fallback (`pai worker fallback on`):\n * every new Claude Code process runs on `provider` until `fallback off`.\n * `saved` holds what ~/.claude/settings.json carried before the switch so\n * `off` can restore it exactly.\n */\nexport interface WorkersFallback {\n  /** Provider every new Claude Code process is pointed at. */\n  provider: string;\n  /**\n   * settings.json before the switch. `env` records the previous value of\n   * every env key fallback touched (null = the key was absent), `model` the\n   * previous top-level model pin (null = none), `envExisted` whether an env\n   * block existed at all.\n   */\n  saved: {\n    env: Record<string, string | null>;\n    model: string | null;\n    envExisted: boolean;\n  };\n  /** ISO stamp of the switch (shown by `fallback status`). */\n  on: string;\n}\n\nexport interface WorkersConfig {\n  enabled: boolean;\n  /** Provider name, or \"auto\" for routing.order resolution. */\n  active: string | null;\n  providers: Record<string, WorkerProvider>;\n  /** Class \u2192 target; see ClassTarget. (Reads the legacy `roles` key.) */\n  classes: Record<string, ClassTarget>;\n  /** MCP set name \u2192 server names; `--mcp <set>` and class `mcp` expand these. */\n  mcpSets: Record<string, string[]>;\n  /**\n   * Capability \u2192 provider names in preference order (workers.yaml\n   * `capabilities:`), e.g. `{ image: [\"pictures\", \"glm\"] }`. Cross-provider,\n   * unlike a provider's own `models` table: this is what lets `--capability\n   * image` find the one provider configured to serve it. See resolveCapability.\n   */\n  capabilities: Record<string, string[]>;\n  pane: WorkersPaneConfig;\n  logDir: string;\n  routing: WorkersRoutingConfig;\n  /** Sub-worker caps (workers.tree). */\n  tree: WorkersTreeConfig;\n  /**\n   * Daemon cache-keepalive cadence in seconds: how often a trivial\n   * single-turn heartbeat worker re-arms the provider prompt cache\n   * (src/workers/keepalive.ts). 0 = off.\n   */\n  cacheKeepaliveSecs: number;\n  /** Default time limit of every run in minutes (workers.defaultMaxMinutes); 0 = none. */\n  defaultMaxMinutes: number;\n  /** Runs strip browser tools unless --browser is passed (workers.noBrowserByDefault). */\n  noBrowserByDefault: boolean;\n  /**\n   * Run native-Anthropic workers through `caveman claude` (workers.caveman).\n   * Off pins them to api.anthropic.com even when the user settings route\n   * every claude through a proxy; see claudeCommand in run-env.ts.\n   */\n  caveman: boolean;\n  /** Machine-wide Claude Code fallback; null = off. */\n  fallback: WorkersFallback | null;\n  /**\n   * Model ids for the built-in `anthropic` provider, when workers.yaml\n   * documents an override under `providers.anthropic.models`. Defaults to\n   * NATIVE_ANTHROPIC_MODELS.\n   */\n  nativeModels: WorkerProvider[\"models\"];\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_LOG_DIR = \"~/.claude/logs/workers\";\n\nexport const DEFAULT_PANE: WorkersPaneConfig = {\n  enabled: true,\n  fontSize: 13,\n  autoExitSecs: 60,\n};\n\nexport const DEFAULT_ROUTING: WorkersRoutingConfig = {\n  order: [],\n  cooldownMinutes: 30,\n  retryOnQuota: true,\n};\n\nexport const DEFAULT_TREE: WorkersTreeConfig = {\n  maxDepth: 2,\n  maxChildren: 4,\n};\n\n/**\n * Cache-keepalive cadence when the config names none. Measured 2026-09-18\n * (pair probes through the real worker spawn path, numbers in\n * docs/cache-keepalive.md): the implicit provider cache only serves a fresh\n * worker warm within roughly the first minute (positive back-to-back, gone\n * at 2 min), and it covers only ~2.6k of the ~18k-token prefix. Holding it\n * needs a beat every <2 min \u2014 a continuous bill for a small saving \u2014 so the\n * default is OFF and arming it is the operator's explicit call (set e.g.\n * \"cacheKeepaliveSecs\": 60).\n */\nexport const DEFAULT_CACHE_KEEPALIVE_SECS = 0;\nexport const DEFAULT_MAX_MINUTES = 60;\n\n/**\n * The default MCP sets every config starts from. `desktop` names the clickr\n * server so `--mcp desktop` hands a worker the machine controls (read-only\n * tools always; actuating ones after the operator hands the controls over,\n * see `pai worker controls`). A user's mcpSets section is merged over this,\n * so `desktop: []` removes the set deliberately.\n */\nexport const DEFAULT_MCP_SETS: Record<string, string[]> = {\n  desktop: [\"clickr\"],\n};\n\nexport function defaultWorkersConfig(): WorkersConfig {\n  return {\n    enabled: false,\n    active: null,\n    providers: {},\n    classes: {},\n    mcpSets: { ...DEFAULT_MCP_SETS },\n    capabilities: {},\n    pane: { ...DEFAULT_PANE },\n    logDir: DEFAULT_LOG_DIR,\n    routing: { ...DEFAULT_ROUTING, order: [] },\n    tree: { ...DEFAULT_TREE },\n    cacheKeepaliveSecs: DEFAULT_CACHE_KEEPALIVE_SECS,\n    defaultMaxMinutes: DEFAULT_MAX_MINUTES,\n    noBrowserByDefault: false,\n    caveman: false,\n    fallback: null,\n    nativeModels: { ...NATIVE_ANTHROPIC_MODELS },\n  };\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport class WorkersConfigError extends Error {}\n\nfunction bad(path: string, why: string): never {\n  throw new WorkersConfigError(`workers${path}: ${why}`);\n}\n\nfunction str(v: unknown): string {\n  return typeof v === \"string\" ? v : \"\";\n}\n\n/**\n * Parse a `models` block (capability \u2192 model id, \"default\" required). Shared\n * by parseProvider and the YAML loader's builtin-anthropic override, which\n * has no other provider fields to validate.\n */\nexport function parseModelsBlock(pathPrefix: string, modelsRaw: unknown): WorkerProvider[\"models\"] {\n  const raw = modelsRaw === undefined ? {} : modelsRaw;\n  if (typeof raw !== \"object\" || raw === null) bad(pathPrefix, \"must be an object\");\n  const m = raw as Record<string, unknown>;\n  const defaultModel = str(m.default);\n  if (!defaultModel) bad(`${pathPrefix}.default`, \"is required\");\n  const models: WorkerProvider[\"models\"] = { default: defaultModel };\n  for (const key of Object.keys(m)) {\n    if (key === \"default\") continue;\n    if (!isModelCapability(key)) {\n      bad(\n        `${pathPrefix}.${key}`,\n        `\"${key}\" is not a valid capability name (must match ^[a-z][a-z0-9-]*$; well-known: ${MODEL_CAPABILITIES.join(\", \")}, but any name in that shape is accepted)`\n      );\n    }\n    const id = str(m[key]);\n    if (!id) bad(`${pathPrefix}.${key}`, \"must be a non-empty model id\");\n    models[key] = id;\n  }\n  return models;\n}\n\n/** Parse and validate one provider entry (shared by JSON and YAML loading). */\nexport function parseProvider(name: string, raw: unknown): WorkerProvider {\n  if (name === ANTHROPIC_NATIVE) {\n    bad(\n      `.providers.${name}`,\n      `\"${ANTHROPIC_NATIVE}\" is reserved for plain Anthropic (Claude Code's own OAuth/Max-plan login) and cannot be configured here \u2014 remove this entry; use --provider ${ANTHROPIC_NATIVE} or \"pai worker providers use ${ANTHROPIC_NATIVE}\" instead`\n    );\n  }\n  if (typeof raw !== \"object\" || raw === null) bad(`.providers.${name}`, \"must be an object\");\n  const p = raw as Record<string, unknown>;\n\n  const protocol = p.protocol === undefined ? \"anthropic\" : str(p.protocol);\n  if (protocol !== \"anthropic\" && protocol !== \"openai\") {\n    bad(`.providers.${name}.protocol`, `\"${str(p.protocol)}\" is neither \"anthropic\" nor \"openai\"`);\n  }\n  const engine = p.engine === undefined ? \"claude\" : str(p.engine);\n  if (engine !== \"claude\" && engine !== \"codex\" && engine !== \"image\") {\n    bad(`.providers.${name}.engine`, `\"${str(p.engine)}\" is none of \"claude\", \"codex\", \"image\"`);\n  }\n\n  const baseUrl = str(p.baseUrl);\n  // openai providers reach the model through the PAI proxy; their baseUrl is\n  // the proxy URL, filled in by the runner \u2014 only anthropic needs one here.\n  if (!baseUrl && protocol !== \"openai\") bad(`.providers.${name}.baseUrl`, \"is required\");\n\n  const keyFile =\n    p.keyFile === undefined || p.keyFile === null || str(p.keyFile) === \"\"\n      ? null\n      : str(p.keyFile);\n  const key = str(p.key) || undefined;\n\n  const models = parseModelsBlock(`.providers.${name}.models`, p.models);\n\n  let modelTiers: Record<string, ModelTier> | undefined;\n  if (p.modelTiers !== undefined) {\n    if (typeof p.modelTiers !== \"object\" || p.modelTiers === null || Array.isArray(p.modelTiers)) {\n      bad(`.providers.${name}.modelTiers`, \"must be an object of model id \u2192 haiku | sonnet | opus\");\n    }\n    modelTiers = {};\n    for (const [id, tier] of Object.entries(p.modelTiers as Record<string, unknown>)) {\n      if (typeof tier !== \"string\" || !MODEL_TIERS.includes(tier as ModelTier)) {\n        bad(\n          `.providers.${name}.modelTiers.${id}`,\n          `must be \"haiku\", \"sonnet\" or \"opus\" (got ${JSON.stringify(tier)})`\n        );\n      }\n      modelTiers[id] = tier as ModelTier;\n    }\n  }\n\n  const env: Record<string, string> = {};\n  if (p.env !== undefined) {\n    if (typeof p.env !== \"object\" || p.env === null || Array.isArray(p.env)) {\n      bad(`.providers.${name}.env`, \"must be an object of string values\");\n    }\n    for (const [k, v] of Object.entries(p.env as Record<string, unknown>)) {\n      if (typeof v !== \"string\") bad(`.providers.${name}.env.${k}`, \"must be a string\");\n      env[k] = v;\n    }\n  }\n\n  const quotaSkipAt = p.quotaSkipAt === undefined ? undefined : p.quotaSkipAt;\n  if (quotaSkipAt !== undefined) {\n    if (typeof quotaSkipAt !== \"number\" || quotaSkipAt < 0 || quotaSkipAt > 100) {\n      bad(`.providers.${name}.quotaSkipAt`, \"must be a number between 0 and 100\");\n    }\n  }\n\n  const contextWindow = p.contextWindow === undefined ? undefined : p.contextWindow;\n  if (contextWindow !== undefined) {\n    if (typeof contextWindow !== \"number\" || contextWindow <= 0) {\n      bad(`.providers.${name}.contextWindow`, \"must be a positive number of tokens\");\n    }\n  }\n\n  const upstreamUrl = str(p.upstreamUrl);\n  if (protocol === \"openai\" && !upstreamUrl) {\n    bad(`.providers.${name}.upstreamUrl`, `is required for protocol \"openai\" (the Chat Completions base, e.g. \"https://api.openai.com/v1\")`);\n  }\n\n  const costTier = p.costTier === undefined ? undefined : p.costTier;\n  if (costTier !== undefined) {\n    if (typeof costTier !== \"number\" || !Number.isInteger(costTier) || costTier < 1 || costTier > 5) {\n      bad(`.providers.${name}.costTier`, \"must be an integer 1 (cheapest) \u2026 5 (most expensive)\");\n    }\n  }\n\n  let tags: ProviderTag[] | undefined;\n  if (p.tags !== undefined) {\n    if (!Array.isArray(p.tags) || p.tags.some((x) => typeof x !== \"string\")) {\n      bad(`.providers.${name}.tags`, `must be an array of tags from: ${PROVIDER_TAGS.join(\", \")}`);\n    }\n    for (const t of p.tags as string[]) {\n      if (!(PROVIDER_TAGS as readonly string[]).includes(t)) {\n        bad(`.providers.${name}.tags`, `\"${t}\" is not a tag (from: ${PROVIDER_TAGS.join(\", \")})`);\n      }\n    }\n    tags = p.tags as ProviderTag[];\n  }\n\n  let usage: ProviderUsage | undefined;\n  if (p.usage !== undefined) {\n    if (typeof p.usage !== \"object\" || p.usage === null || Array.isArray(p.usage)) {\n      bad(`.providers.${name}.usage`, \"must be an object\");\n    }\n    const u = p.usage as Record<string, unknown>;\n    const usageUrl = str(u.url);\n    if (!usageUrl) bad(`.providers.${name}.usage.url`, \"is required\");\n    if (!Array.isArray(u.windows) || u.windows.length === 0) {\n      bad(`.providers.${name}.usage.windows`, \"must be a non-empty array\");\n    }\n    const windows: UsageWindow[] = [];\n    for (const [i, wRaw] of (u.windows as unknown[]).entries()) {\n      const wpath = `.providers.${name}.usage.windows[${i}]`;\n      if (typeof wRaw !== \"object\" || wRaw === null || Array.isArray(wRaw)) {\n        bad(wpath, \"must be an object\");\n      }\n      const w = wRaw as Record<string, unknown>;\n      const wname = str(w.name);\n      if (!wname) bad(`${wpath}.name`, \"is required\");\n      const percent = str(w.percent);\n      if (!percent) bad(`${wpath}.percent`, \"is required (a jq expression yielding 0\u2013100)\");\n      const resetUnit = w.resetUnit === undefined ? undefined : str(w.resetUnit);\n      if (resetUnit !== undefined && resetUnit !== \"ms\" && resetUnit !== \"s\" && resetUnit !== \"iso\") {\n        bad(`${wpath}.resetUnit`, `must be \"ms\", \"s\" or \"iso\"`);\n      }\n      windows.push({\n        name: wname,\n        percent,\n        ...(str(w.resetAt) ? { resetAt: str(w.resetAt) } : {}),\n        ...(resetUnit ? { resetUnit } : {}),\n      });\n    }\n    const ttlSeconds = u.ttlSeconds === undefined ? undefined : u.ttlSeconds;\n    if (ttlSeconds !== undefined && (typeof ttlSeconds !== \"number\" || ttlSeconds <= 0)) {\n      bad(`.providers.${name}.usage.ttlSeconds`, \"must be a positive number of seconds\");\n    }\n    usage = {\n      url: usageUrl,\n      ...(str(u.authHeader) ? { authHeader: str(u.authHeader) } : {}),\n      ...(str(u.label) ? { label: str(u.label) } : {}),\n      windows,\n      ...(ttlSeconds !== undefined ? { ttlSeconds } : {}),\n    };\n  }\n\n  return {\n    enabled: p.enabled === undefined ? true : p.enabled === true,\n    protocol,\n    baseUrl,\n    keyFile,\n    ...(key ? { key } : {}),\n    models,\n    ...(modelTiers ? { modelTiers } : {}),\n    env,\n    ...(str(p.note) ? { note: str(p.note) } : {}),\n    ...(upstreamUrl ? { upstreamUrl } : {}),\n    ...(engine !== \"claude\" ? { engine } : {}),\n    ...(str(p.quotaProbe) ? { quotaProbe: str(p.quotaProbe) } : {}),\n    ...(quotaSkipAt !== undefined ? { quotaSkipAt } : {}),\n    ...(contextWindow !== undefined ? { contextWindow } : {}),\n    ...(costTier !== undefined ? { costTier } : {}),\n    ...(tags ? { tags } : {}),\n    ...(usage ? { usage } : {}),\n  };\n}\n\n/**\n * Parse a `classes` (or legacy `roles`) value shared by JSON and YAML\n * loading. `badPathPrefix` names the field in error messages, e.g. \".classes\".\n */\nexport function parseClassesValue(\n  classesRaw: unknown,\n  badPathPrefix: string\n): Record<string, ClassTarget> {\n  const classes: Record<string, ClassTarget> = {};\n  if (classesRaw === undefined) return classes;\n  if (typeof classesRaw !== \"object\" || classesRaw === null || Array.isArray(classesRaw)) {\n    bad(badPathPrefix, \"must be an object of class \u2192 provider[/alias] or {provider, mcp, maxCostTier, requireTags, order}\");\n  }\n  for (const [cls, target] of Object.entries(classesRaw as Record<string, unknown>)) {\n    if (typeof target === \"object\" && target !== null && !Array.isArray(target)) {\n      const o = target as Record<string, unknown>;\n      const provider = str(o.provider);\n      if (o.provider !== undefined && (!provider || provider.includes(\" \"))) {\n        bad(`${badPathPrefix}.${cls}.provider`, `invalid provider \"${provider}\"`);\n      }\n      let mcp: string[] | undefined;\n      if (o.mcp !== undefined) {\n        if (!Array.isArray(o.mcp) || o.mcp.some((x) => typeof x !== \"string\")) {\n          bad(`${badPathPrefix}.${cls}.mcp`, \"must be an array of MCP server or set names\");\n        }\n        mcp = o.mcp as string[];\n      }\n      let maxCostTier: number | undefined;\n      if (o.maxCostTier !== undefined) {\n        if (\n          typeof o.maxCostTier !== \"number\" ||\n          !Number.isInteger(o.maxCostTier) ||\n          o.maxCostTier < 1 ||\n          o.maxCostTier > 5\n        ) {\n          bad(`${badPathPrefix}.${cls}.maxCostTier`, \"must be an integer 1 \u2026 5\");\n        }\n        maxCostTier = o.maxCostTier;\n      }\n      let requireTags: string[] | undefined;\n      if (o.requireTags !== undefined) {\n        if (!Array.isArray(o.requireTags) || o.requireTags.some((x) => typeof x !== \"string\")) {\n          bad(`${badPathPrefix}.${cls}.requireTags`, `must be an array of tags from: ${PROVIDER_TAGS.join(\", \")}`);\n        }\n        for (const t of o.requireTags as string[]) {\n          if (!(PROVIDER_TAGS as readonly string[]).includes(t)) {\n            bad(`${badPathPrefix}.${cls}.requireTags`, `\"${t}\" is not a tag (from: ${PROVIDER_TAGS.join(\", \")})`);\n          }\n        }\n        requireTags = o.requireTags as string[];\n      }\n      let order: string[] | undefined;\n      if (o.order !== undefined) {\n        if (!Array.isArray(o.order) || o.order.some((x) => typeof x !== \"string\")) {\n          bad(`${badPathPrefix}.${cls}.order`, \"must be an array of provider names\");\n        }\n        order = o.order as string[];\n      }\n      const obj: ClassTarget = {\n        ...(provider ? { provider } : {}),\n        ...(mcp ? { mcp } : {}),\n        ...(maxCostTier !== undefined ? { maxCostTier } : {}),\n        ...(requireTags ? { requireTags } : {}),\n        ...(order ? { order } : {}),\n      };\n      classes[cls] = Object.keys(obj).length ? obj : {};\n    } else {\n      const t = str(target);\n      if (!t || t.includes(\" \")) bad(`${badPathPrefix}.${cls}`, `invalid target \"${t}\"`);\n      classes[cls] = t;\n    }\n  }\n  return classes;\n}\n\n/**\n * Parse an `mcpSets` (or `mcp_sets`) value shared by JSON and YAML loading.\n * Always merged over DEFAULT_MCP_SETS, so an omitted `desktop` key keeps the\n * built-in clickr set (see DEFAULT_MCP_SETS).\n */\nexport function parseMcpSetsValue(raw: unknown, badPathPrefix: string): Record<string, string[]> {\n  const mcpSets: Record<string, string[]> = { ...DEFAULT_MCP_SETS };\n  if (raw === undefined) return mcpSets;\n  if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n    bad(badPathPrefix, \"must be an object of set name \u2192 [server names]\");\n  }\n  for (const [setName, servers] of Object.entries(raw as Record<string, unknown>)) {\n    if (!Array.isArray(servers) || servers.some((x) => typeof x !== \"string\")) {\n      bad(`${badPathPrefix}.${setName}`, \"must be an array of MCP server names\");\n    }\n    mcpSets[setName] = servers as string[];\n  }\n  return mcpSets;\n}\n\n/**\n * Parse a `capabilities` value shared by JSON and YAML loading: capability\n * name (open set, see isModelCapability) \u2192 provider names in preference\n * order. Provider names are not cross-checked here \u2014 a name that stops\n * existing is simply skipped by resolveCapability at resolve time, the same\n * way routing.order tolerates a removed provider.\n */\nexport function parseCapabilitiesValue(raw: unknown, badPathPrefix: string): Record<string, string[]> {\n  const capabilities: Record<string, string[]> = {};\n  if (raw === undefined) return capabilities;\n  if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n    bad(badPathPrefix, \"must be an object of capability name \u2192 [provider names]\");\n  }\n  for (const [name, order] of Object.entries(raw as Record<string, unknown>)) {\n    if (!isModelCapability(name)) {\n      bad(`${badPathPrefix}.${name}`, `\"${name}\" is not a valid capability name (must match ^[a-z][a-z0-9-]*$)`);\n    }\n    if (!Array.isArray(order) || order.length === 0 || order.some((x) => typeof x !== \"string\" || !x)) {\n      bad(`${badPathPrefix}.${name}`, \"must be a non-empty array of provider names\");\n    }\n    capabilities[name] = order as string[];\n  }\n  return capabilities;\n}\n\n/**\n * Parse and validate a raw `workers` value. Missing section \u2192 defaults.\n * Unknown-but-typed garbage \u2192 WorkersConfigError naming the offending field.\n */\nexport function parseWorkersConfig(raw: unknown): WorkersConfig {\n  const d = defaultWorkersConfig();\n  if (raw === undefined || raw === null) return d;\n  if (typeof raw !== \"object\" || Array.isArray(raw)) {\n    bad(\"\", \"section must be an object\");\n  }\n  const w = raw as Record<string, unknown>;\n\n  const providers: Record<string, WorkerProvider> = {};\n  if (w.providers !== undefined) {\n    if (typeof w.providers !== \"object\" || w.providers === null || Array.isArray(w.providers)) {\n      bad(\".providers\", \"must be an object keyed by provider name\");\n    }\n    for (const [name, p] of Object.entries(w.providers)) {\n      providers[name] = parseProvider(name, p);\n    }\n  }\n\n  // classes is canonical; a config that still carries the pre-classes `roles`\n  // key is migrated by reading it here \u2014 the next write stores only `classes`.\n  const classesRaw = w.classes !== undefined ? w.classes : w.roles;\n  const classes = parseClassesValue(classesRaw, w.classes !== undefined ? \".classes\" : \".roles\");\n\n  const mcpSets = parseMcpSetsValue(w.mcpSets, \".mcpSets\");\n  const capabilities = parseCapabilitiesValue(w.capabilities, \".capabilities\");\n\n  let pane = { ...DEFAULT_PANE };\n  if (w.pane !== undefined) {\n    if (typeof w.pane !== \"object\" || w.pane === null) bad(\".pane\", \"must be an object\");\n    const pc = w.pane as Record<string, unknown>;\n    if (pc.enabled !== undefined && typeof pc.enabled !== \"boolean\") bad(\".pane.enabled\", \"must be boolean\");\n    if (pc.fontSize !== undefined && (typeof pc.fontSize !== \"number\" || pc.fontSize <= 0)) {\n      bad(\".pane.fontSize\", \"must be a positive number of points\");\n    }\n    if (pc.autoExitSecs !== undefined && typeof pc.autoExitSecs !== \"number\") {\n      bad(\".pane.autoExitSecs\", \"must be a number\");\n    }\n    // legacy fontScale (a relative scale, superseded by fontSize) is tolerated and ignored\n    pane = {\n      enabled: pc.enabled === undefined ? DEFAULT_PANE.enabled : pc.enabled === true,\n      fontSize: pc.fontSize === undefined ? DEFAULT_PANE.fontSize : pc.fontSize,\n      autoExitSecs: pc.autoExitSecs === undefined ? DEFAULT_PANE.autoExitSecs : pc.autoExitSecs,\n    };\n  }\n\n  let routing = { ...DEFAULT_ROUTING, order: [] as string[] };\n  if (w.routing !== undefined) {\n    if (typeof w.routing !== \"object\" || w.routing === null) bad(\".routing\", \"must be an object\");\n    const r = w.routing as Record<string, unknown>;\n    if (r.order !== undefined) {\n      if (!Array.isArray(r.order) || r.order.some((x) => typeof x !== \"string\")) {\n        bad(\".routing.order\", \"must be an array of provider names\");\n      }\n      routing.order = r.order as string[];\n    }\n    if (r.cooldownMinutes !== undefined && typeof r.cooldownMinutes !== \"number\") {\n      bad(\".routing.cooldownMinutes\", \"must be a number\");\n    }\n    if (r.retryOnQuota !== undefined && typeof r.retryOnQuota !== \"boolean\") {\n      bad(\".routing.retryOnQuota\", \"must be boolean\");\n    }\n    routing = {\n      order: routing.order,\n      cooldownMinutes: r.cooldownMinutes === undefined ? DEFAULT_ROUTING.cooldownMinutes : r.cooldownMinutes,\n      retryOnQuota: r.retryOnQuota === undefined ? DEFAULT_ROUTING.retryOnQuota : r.retryOnQuota === true,\n    };\n  }\n\n  let tree = { ...DEFAULT_TREE };\n  if (w.tree !== undefined) {\n    if (typeof w.tree !== \"object\" || w.tree === null || Array.isArray(w.tree)) {\n      bad(\".tree\", \"must be an object\");\n    }\n    const t = w.tree as Record<string, unknown>;\n    if (t.maxDepth !== undefined) {\n      if (typeof t.maxDepth !== \"number\" || !Number.isInteger(t.maxDepth) || t.maxDepth < 0) {\n        bad(\".tree.maxDepth\", \"must be a non-negative integer\");\n      }\n    }\n    if (t.maxChildren !== undefined) {\n      if (typeof t.maxChildren !== \"number\" || !Number.isInteger(t.maxChildren) || t.maxChildren < 1) {\n        bad(\".tree.maxChildren\", \"must be a positive integer\");\n      }\n    }\n    tree = {\n      maxDepth: t.maxDepth === undefined ? DEFAULT_TREE.maxDepth : t.maxDepth,\n      maxChildren: t.maxChildren === undefined ? DEFAULT_TREE.maxChildren : t.maxChildren,\n    };\n  }\n\n  let cacheKeepaliveSecs = DEFAULT_CACHE_KEEPALIVE_SECS;\n  if (w.cacheKeepaliveSecs !== undefined) {\n    if (\n      typeof w.cacheKeepaliveSecs !== \"number\" ||\n      !Number.isInteger(w.cacheKeepaliveSecs) ||\n      w.cacheKeepaliveSecs < 0\n    ) {\n      bad(\".cacheKeepaliveSecs\", \"must be a non-negative integer (seconds, 0 = off)\");\n    }\n    cacheKeepaliveSecs = w.cacheKeepaliveSecs;\n  }\n\n  let defaultMaxMinutes = DEFAULT_MAX_MINUTES;\n  if (w.defaultMaxMinutes !== undefined) {\n    if (typeof w.defaultMaxMinutes !== \"number\" || !Number.isInteger(w.defaultMaxMinutes) || w.defaultMaxMinutes < 0) {\n      bad(\".defaultMaxMinutes\", \"must be a non-negative integer (minutes, 0 = no limit)\");\n    }\n    defaultMaxMinutes = w.defaultMaxMinutes;\n  }\n  if (w.noBrowserByDefault !== undefined && typeof w.noBrowserByDefault !== \"boolean\") {\n    bad(\".noBrowserByDefault\", \"must be true or false\");\n  }\n  const noBrowserByDefault = w.noBrowserByDefault === true;\n\n  if (w.caveman !== undefined && typeof w.caveman !== \"boolean\") {\n    bad(\".caveman\", \"must be true or false\");\n  }\n  const caveman = w.caveman === true;\n\n  const active = w.active === undefined || w.active === null ? null : str(w.active);\n  if (active !== null && active !== \"auto\" && !(active in providers)) {\n    // Tolerated at parse time (a provider may have been removed while active\n    // still names it) but every consumer resolves it to a clear error.\n  }\n\n  let fallback: WorkersFallback | null = null;\n  if (w.fallback !== undefined && w.fallback !== null) {\n    if (typeof w.fallback !== \"object\" || Array.isArray(w.fallback)) {\n      bad(\".fallback\", \"must be an object (written by `pai worker fallback on`)\");\n    }\n    const f = w.fallback as Record<string, unknown>;\n    const provider = str(f.provider);\n    if (!provider) bad(\".fallback.provider\", \"is required\");\n    const savedRaw = f.saved;\n    if (typeof savedRaw !== \"object\" || savedRaw === null || Array.isArray(savedRaw)) {\n      bad(\".fallback.saved\", \"must be an object\");\n    }\n    const s = savedRaw as Record<string, unknown>;\n    if (typeof s.env !== \"object\" || s.env === null || Array.isArray(s.env)) {\n      bad(\".fallback.saved.env\", \"must be an object of env key \u2192 previous value or null\");\n    }\n    const env: Record<string, string | null> = {};\n    for (const [k, v] of Object.entries(s.env as Record<string, unknown>)) {\n      env[k] = v === null || typeof v === \"string\" ? (v as string | null) : null;\n    }\n    if (s.model !== null && s.model !== undefined && typeof s.model !== \"string\") {\n      bad(\".fallback.saved.model\", \"must be a string or null\");\n    }\n    fallback = {\n      provider,\n      saved: {\n        env,\n        model: typeof s.model === \"string\" ? s.model : null,\n        envExisted: s.envExisted === true,\n      },\n      on: str(f.on) || new Date(0).toISOString(),\n    };\n  }\n\n  return {\n    enabled: w.enabled === undefined ? d.enabled : w.enabled === true,\n    active,\n    providers,\n    classes,\n    mcpSets,\n    capabilities,\n    pane,\n    logDir: str(w.logDir) || d.logDir,\n    routing,\n    tree,\n    cacheKeepaliveSecs,\n    defaultMaxMinutes,\n    noBrowserByDefault,\n    caveman,\n    fallback,\n    nativeModels: { ...NATIVE_ANTHROPIC_MODELS },\n  };\n}\n\n// ---------------------------------------------------------------------------\n// Read / write\n// ---------------------------------------------------------------------------\n\nfunction workersYamlDataOf(workers: WorkersConfig): WorkersYamlData {\n  return {\n    active: workers.active,\n    providers: workers.providers,\n    classes: workers.classes,\n    mcpSets: workers.mcpSets,\n    capabilities: workers.capabilities,\n    nativeModels: workers.nativeModels,\n  };\n}\n\n/**\n * Read the whole config file and return (raw, workers) \u2014 the raw record so\n * callers can rewrite it preserving every other section, the parsed+validated\n * workers section. Unreadable config throws, missing is fine. `path`\n * overrides the config location (tests, CLAUDE_SETTINGS_PATH-style dry runs);\n * default CONFIG_FILE (see paiConfigFilePath). Reads via readMainConfigRaw,\n * so a config.yaml next to `path` is preferred over JSON, same as every\n * other main-config reader.\n *\n * Providers, classes, mcpSets and active load from workers.yaml (next to\n * `path`) when it exists; otherwise they fall back to the JSON `workers`\n * section, and then to built-in defaults \u2014 nothing breaks before migration\n * (`pai worker config migrate`). Everything else (pane, routing, tree,\n * cacheKeepaliveSecs, fallback, enabled, logDir) always comes from the main\n * config (JSON or YAML).\n */\nexport function readWorkersSection(path: string = CONFIG_FILE): {\n  raw: Record<string, unknown>;\n  workers: WorkersConfig;\n} {\n  const raw = readMainConfigRaw(path);\n  const workers = parseWorkersConfig(raw.workers);\n  const yaml = readWorkersYaml(workersYamlPath());\n  if (yaml) {\n    workers.active = yaml.data.active;\n    workers.providers = yaml.data.providers;\n    workers.classes = yaml.data.classes;\n    workers.mcpSets = yaml.data.mcpSets;\n    workers.capabilities = yaml.data.capabilities;\n    workers.nativeModels = yaml.data.nativeModels;\n  }\n  return { raw, workers };\n}\n\n/**\n * Write the workers section back, atomically. When workers.yaml exists, its\n * providers/classes/mcpSets/active are synced there (comment-preserving,\n * only the entries that changed are touched) and stripped from the JSON\n * `workers` section; everything else still writes to JSON as before.\n */\nexport function writeWorkersSection(\n  raw: Record<string, unknown>,\n  workers: WorkersConfig,\n  path: string = CONFIG_FILE\n): void {\n  const yamlPath = workersYamlPath();\n  const usingYaml = existsSync(yamlPath);\n  if (usingYaml) {\n    writeWorkersYaml(yamlPath, workersYamlDataOf(workers));\n  }\n  const jsonWorkers = usingYaml\n    ? {\n        enabled: workers.enabled,\n        pane: workers.pane,\n        logDir: workers.logDir,\n        routing: workers.routing,\n        tree: workers.tree,\n        cacheKeepaliveSecs: workers.cacheKeepaliveSecs,\n        defaultMaxMinutes: workers.defaultMaxMinutes,\n        noBrowserByDefault: workers.noBrowserByDefault,\n        caveman: workers.caveman,\n        ...(workers.fallback ? { fallback: workers.fallback } : {}),\n      }\n    : workers.fallback\n      ? workers\n      : { ...workers, fallback: undefined };\n  raw.workers = jsonWorkers;\n  writeMainConfigRaw(raw, path);\n}\n\n/** Expand a leading ~ (config values are written with `~` to stay portable). */\nexport function expandHome(p: string): string {\n  if (p === \"~\" || p.startsWith(\"~/\")) return join(homedir(), p.slice(1));\n  return p;\n}\n\n// ---------------------------------------------------------------------------\n// Runnability checks (proxy / codex providers included)\n// ---------------------------------------------------------------------------\n\nexport function assertProviderRunnable(name: string, p: WorkerProvider): void {\n  if (p.protocol === \"openai\" && !p.upstreamUrl) {\n    throw new WorkersConfigError(\n      `provider \"${name}\" uses protocol \"openai\" but has no upstreamUrl \u2014 ` +\n        `set its Chat Completions base (e.g. \"https://api.openai.com/v1\") ` +\n        `so the PAI proxy knows where to translate to.`\n    );\n  }\n}\n\n/** Where a provider's key file lives, or null. Shared by run + test + add. */\nexport function providerKeyPath(p: WorkerProvider): string | null {\n  return p.keyFile ? expandHome(p.keyFile) : null;\n}\n\n/**\n * The provider's auth token: inline `key` wins when set, else `key_file`\n * read and trimmed, else null (native/local providers use the \"local\"\n * placeholder). The one place a provider's key value is resolved \u2014 every\n * spawn path (buildRunEnv, the codex runner, the openai proxy, the\n * machine-wide fallback) reads through this instead of its own\n * readFileSync, so inline keys work everywhere a key file already did.\n */\nexport function resolveProviderKey(p: WorkerProvider): string | null {\n  if (p.key) return p.key;\n  const keyPath = providerKeyPath(p);\n  if (!keyPath) return null;\n  let content: string;\n  try {\n    content = readFileSync(keyPath, \"utf8\");\n  } catch {\n    throw new WorkersConfigError(`key file not readable: ${keyPath}`);\n  }\n  const token = content.trim();\n  if (!token) throw new WorkersConfigError(`key file is empty: ${keyPath}`);\n  return token;\n}\n\n/** `key: ****` + last 4 chars \u2014 never the full value. Used everywhere a\n *  provider's key would otherwise be echoed (`providers`, `config check`). */\nexport function maskKey(key: string): string {\n  return `****${key.slice(-4)}`;\n}\n\nexport { DEFAULT_CONTEXT_WINDOW } from \"../utils/model-window.js\";\n\n/** Cost tier of a provider for class filtering (unset = 3, the middle). */\nexport function providerCostTier(p: WorkerProvider): number {\n  return p.costTier ?? DEFAULT_COST_TIER;\n}\n\n/**\n * The model id for a capability: the provider's preference for it, else its\n * default model \u2014 the one resolution rule every consumer (image class, fast\n * tier spawns, env pins) goes through.\n */\nexport function resolveModelCapability(p: WorkerProvider, capability: ModelCapability): string {\n  return p.models[capability] ?? p.models.default;\n}\n\n/** Runner behind a provider, defaulting to the Claude Code harness. */\nfunction providerEngine(p: WorkerProvider): WorkerEngine {\n  return p.engine ?? \"claude\";\n}\n\n/** Does this provider name a model for the capability (\"default\" always counts)? */\nfunction providerDeclaresCapability(p: WorkerProvider, capability: string): boolean {\n  return capability === \"default\" || p.models[capability] !== undefined;\n}\n\n/** A provider usable for this capability: declares it, enabled, and passes assertProviderRunnable. */\nfunction providerUsableForCapability(p: WorkerProvider | undefined, capability: string): p is WorkerProvider {\n  if (!p || !p.enabled || !providerDeclaresCapability(p, capability)) return false;\n  try {\n    assertProviderRunnable(\"\", p);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nexport interface ResolvedCapability {\n  /** Provider name the capability resolved to (\"anthropic\" for the built-in). */\n  provider: string;\n  model: string;\n  engine: WorkerEngine;\n  /**\n   * True when nothing declared this capability anywhere and the result is\n   * just the active provider's default model \u2014 a caller should treat this as\n   * \"no real image/vision/\u2026 provider is configured\", not a genuine match.\n   */\n  fellBack: boolean;\n}\n\n/**\n * Cross-provider capability resolution (`workers.yaml`'s `capabilities:`\n * map): which provider+model serves a named capability (e.g. \"image\"),\n * independent of any one provider's own `models` table.\n *\n * Resolution order:\n *   1. `capabilities.<name>` (explicit preference list) \u2014 first provider\n *      that declares the capability, is enabled, and passes\n *      assertProviderRunnable.\n *   2. No preference list: the active provider, if it declares the\n *      capability.\n *   3. Still nothing: any enabled provider that declares the capability\n *      (stable order \u2014 provider names sorted, \"anthropic\" included).\n *   4. Nothing anywhere: the active provider's default model, `fellBack: true`.\n */\nexport function resolveCapability(\n  workers: Pick<WorkersConfig, \"providers\" | \"active\" | \"capabilities\" | \"nativeModels\">,\n  capability: string\n): ResolvedCapability {\n  const order = workers.capabilities[capability];\n  if (order?.length) {\n    for (const name of order) {\n      const p = getProviderOrNative(workers, name);\n      if (providerUsableForCapability(p, capability)) {\n        return { provider: name, model: resolveModelCapability(p, capability), engine: providerEngine(p), fellBack: false };\n      }\n    }\n    throw new WorkersConfigError(\n      `no configured provider for capability \"${capability}\" is usable right now ` +\n        `(checked, in order: ${order.join(\", \")}) \u2014 set one with: pai worker capability ${capability} <provider>`\n    );\n  }\n\n  const activeName = workers.active && workers.active !== \"auto\" ? workers.active : null;\n  if (activeName) {\n    const p = getProviderOrNative(workers, activeName);\n    if (providerUsableForCapability(p, capability)) {\n      return { provider: activeName, model: resolveModelCapability(p, capability), engine: providerEngine(p), fellBack: false };\n    }\n  }\n\n  const candidates: Record<string, WorkerProvider> = {\n    [ANTHROPIC_NATIVE]: nativeAnthropicProvider(workers.nativeModels),\n    ...workers.providers,\n  };\n  for (const name of Object.keys(candidates).sort()) {\n    const p = candidates[name];\n    if (providerUsableForCapability(p, capability)) {\n      return { provider: name, model: resolveModelCapability(p, capability), engine: providerEngine(p), fellBack: false };\n    }\n  }\n\n  const fallbackName = activeName ?? ANTHROPIC_NATIVE;\n  const fallback = getProviderOrNative(workers, fallbackName) ?? nativeAnthropicProvider(workers.nativeModels);\n  return {\n    provider: fallbackName,\n    model: fallback.models.default,\n    engine: providerEngine(fallback),\n    fellBack: true,\n  };\n}\n\n/**\n * Context window used by the meter when the run reports none: an explicit\n * `contextWindow` first, then whatever the default model's id declares\n * (\"[1m]\" \u2192 1,000,000), then the last-resort default.\n */\nexport function providerContextWindow(p: WorkerProvider): number {\n  return (\n    p.contextWindow ??\n    contextWindowFromModelId(p.models.default) ??\n    DEFAULT_CONTEXT_WINDOW\n  );\n}\n\n/** Directory under which inline keys (MCP `key` field) are stored, 0600. */\nexport function keysDir(): string {\n  return paiHomePath(\"keys\");\n}\n", "/**\n * config.ts \u2014 Configuration loader for PAI Daemon\n *\n * Loads config from ~/.claude/pai/config.json (the pre-2026-09-19 location\n * was ~/.config/pai/config.json, briefly ~/.claude/pai.json in between \u2014\n * see paiConfigFilePath/migrateConfigFile).\n * Deep-merges with defaults so partial configs work fine.\n * Expands ~ in path values at runtime.\n */\n\nimport { existsSync, mkdirSync, writeFileSync, chmodSync, readdirSync } from \"node:fs\";\nimport { homedir, userInfo } from \"node:os\";\nimport { join, dirname, basename } from \"node:path\";\nimport type { NotificationConfig } from \"../notifications/types.js\";\nimport { DEFAULT_NOTIFICATION_CONFIG } from \"../notifications/types.js\";\nimport type { TaskConfig } from \"../tasks/types.js\";\nimport { DEFAULT_TASK_CONFIG } from \"../tasks/types.js\";\nimport { paiSocketPath } from \"../runtime-paths.js\";\nimport {\n  paiHomePath,\n  resolvePaiFile,\n  migratePaiFile,\n  PaiFileMigrationError,\n  type MigrateFileResult,\n} from \"../config/pai-home.js\";\nimport {\n  yamlSiblingPath,\n  readDualFormatConfigRaw,\n  writeDualFormatConfigRaw,\n  MainConfigError,\n} from \"../config/main-config.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SearchConfig {\n  /** Default search mode: 'keyword', 'semantic', or 'hybrid'. Default: 'keyword'. */\n  mode: \"keyword\" | \"semantic\" | \"hybrid\";\n  /** Enable cross-encoder reranking by default. Default: true. */\n  rerank: boolean;\n  /** Recency boost half-life in days. 0 = off. Default: 90. */\n  recencyBoostDays: number;\n  /** Default max results. Default: 10. */\n  defaultLimit: number;\n  /** Default snippet length for MCP results. Default: 200. */\n  snippetLength: number;\n}\n\nexport interface PostgresConfig {\n  /** Connection string \u2014 if set, overrides individual host/port/etc. fields */\n  connectionString?: string;\n  /** Postgres host (default: \"localhost\") */\n  host?: string;\n  /** Postgres port (default: 5432) */\n  port?: number;\n  /** Postgres database name (default: \"pai\") */\n  database?: string;\n  /** Postgres user (default: \"pai\") */\n  user?: string;\n  /** Postgres password (default: \"pai\") */\n  password?: string;\n  /** Maximum pool connections (default: 5) */\n  maxConnections?: number;\n  /** Connection timeout in ms (default: 5000) */\n  connectionTimeoutMs?: number;\n}\n\n/**\n * Idle-triggered prompt-cache keepalive for interactive Claude Code sessions\n * (see docs/cache-keepalive.md, \"Interactive sessions\"). Distinct from\n * `workers.cacheKeepaliveSecs` (src/workers/config.ts), which re-arms a\n * *worker provider's* cache via trivial worker spawns on a fixed timer: this\n * beats a live interactive session only when it has actually gone idle long\n * enough to risk its 1h ephemeral cache expiring, and only within working\n * hours \u2014 a fixed timer would beat while the user is active (no-op, wasted\n * quota) or overnight (never pays back before the next real prompt anyway).\n */\nexport interface SessionsCacheKeepaliveConfig {\n  /** Off by default \u2014 arming it is the operator's explicit call. */\n  enabled: boolean;\n  /** Beat a session once it has been idle at least this long. Must be < the\n   *  provider's cache TTL (60 for the 1h ephemeral cache) or the beat is too\n   *  late to matter. */\n  idleMinutes: number;\n  /** Cap on consecutive beats per idle stretch; resets when the user prompts\n   *  the session again for real (not with the keepalive word itself). */\n  maxBeats: number;\n  /** Local time window \"HH:MM-HH:MM\" outside which no beats are sent. */\n  activeHours: string;\n  /** Skip sessions whose context is too small to be worth a beat. */\n  minContextTokens: number;\n  /** The exact word typed into the session; kept to one word so the\n   *  UserPromptSubmit hook can recognise it and answer minimally. */\n  prompt: string;\n}\n\nexport interface SessionsConfig {\n  cacheKeepalive: SessionsCacheKeepaliveConfig;\n}\n\nexport interface PaiDaemonConfig {\n  /** Unix Domain Socket path for IPC */\n  socketPath: string;\n\n  /** Index schedule interval in seconds (default: 300 = 5 minutes) */\n  indexIntervalSecs: number;\n\n  /** Embedding schedule interval in seconds (default: 600 = 10 minutes) */\n  embedIntervalSecs: number;\n  /** Run an embed pass 60s after daemon start. Off by default: with a large\n   *  backlog it makes every restart a CPU storm, and it ignores the interval. */\n  embedOnStartup: boolean;\n\n  /** Local hour (0-23) to anchor the recurring index/embed cycle to. When unset,\n   *  the cycle is anchored to daemon start, so a daytime restart pins every\n   *  later pass to daytime too \u2014 a 24h interval does not by itself mean \"at\n   *  night\". Set this to run maintenance in a fixed window regardless of when\n   *  the machine last booted. */\n  maintenanceHour?: number;\n\n  /** Storage backend: \"sqlite\" (default) or \"postgres\" */\n  storageBackend: \"sqlite\" | \"postgres\";\n\n  /** PostgreSQL connection config (used when storageBackend = \"postgres\") */\n  postgres?: PostgresConfig;\n\n  /** Embedding model name (used for semantic/hybrid search) */\n  embeddingModel: string;\n\n  /** Log level */\n  logLevel: \"debug\" | \"info\" | \"warn\" | \"error\";\n\n  /** Obsidian vault root path for zettelkasten indexing. If set, vault indexing runs alongside project indexing. */\n  vaultPath?: string;\n\n  /** Registry project_id to use for vault chunks in memory_chunks. Default: auto-detected. */\n  vaultProjectId?: number;\n\n  /** Notification subsystem configuration */\n  notifications: NotificationConfig;\n\n  /** Search defaults \u2014 applied when MCP tool or CLI doesn't specify a value */\n  search: SearchConfig;\n\n  /** Task bus \u2014 optional external tracker for cross-session work */\n  tasks: TaskConfig;\n\n  /** Who \"me\" is \u2014 addresses that count as the user's own. */\n  identity: IdentityConfig;\n\n  /** Interactive-session settings (currently just the cache keepalive). */\n  sessions: SessionsConfig;\n}\n\n/**\n * The user's own identity, for anything that delivers back to them.\n *\n * This exists so \"my own address\" is a fact the system can check rather than\n * something a model infers from context. An assistant deciding on the spot\n * whether an address looks like the user's is exactly the judgement that should\n * not be re-made per message.\n *\n * Empty by default and never guessed at install time: an empty `selfEmails`\n * means nothing is self-addressed, so anything reading this fails closed.\n */\nexport interface IdentityConfig {\n  /**\n   * Where digests and \"mail me X\" requests are delivered.\n   *\n   * Must be a mailbox separate from the account doing the sending. Gmail files\n   * a message sent from an account to itself \u2014 or to one of its own domain\n   * aliases \u2014 under Sent only, and it never reaches the inbox. The send reports\n   * success, so this fails silently and looks exactly like delivery. Observed\n   * 2026-08-01: owner@example.ch \u2192 owner@example.de, sent fine, invisible.\n   *\n   * Where a separate mailbox is not available, deliver by writing the message\n   * and adding the INBOX label to it rather than relying on the send path.\n   */\n  deliverTo?: string;\n\n  /**\n   * Every address that counts as the user's own.\n   *\n   * Used as an allowlist by anything that may act without review \u2014 outbound\n   * mail being the case that motivated it. Membership is the whole test: an\n   * address that is not listed is not the user's, however similar it looks.\n   * Plus-aliases and domain aliases must be listed explicitly rather than\n   * pattern-matched, because the patterns that would match them also match\n   * addresses belonging to other people.\n   */\n  selfEmails: string[];\n\n  /** The account used to send on the user's behalf, when one is configured. */\n  sendingAccount?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Per-user Postgres isolation\n// ---------------------------------------------------------------------------\n\n/** Derive a per-user Postgres database name: pai_<username> */\nfunction perUserDbName(): string {\n  const username = userInfo().username;\n  // Sanitize: only allow alphanumeric and underscore for Postgres identifiers\n  const safe = username.replace(/[^a-zA-Z0-9_]/g, \"_\").toLowerCase();\n  return `pai_${safe}`;\n}\n\n/** Derive the per-user connection string */\nfunction perUserConnectionString(): string {\n  const db = perUserDbName();\n  return `postgresql://pai:pai@localhost:5432/${db}`;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\n/**\n * idleMinutes=50 sits under the 60-minute ephemeral-1h TTL with margin for\n * scheduler jitter; maxBeats=6 (~5h of coverage at one beat per idle stretch)\n * and activeHours 08:00-22:00 keep an unattended overnight machine from\n * beating all night for a session nobody will return to before the cache\n * would have expired anyway.\n */\nexport const DEFAULT_SESSIONS_CACHE_KEEPALIVE: SessionsCacheKeepaliveConfig = {\n  enabled: false,\n  idleMinutes: 50,\n  maxBeats: 6,\n  activeHours: \"08:00-22:00\",\n  minContextTokens: 20_000,\n  prompt: \"keepalive\",\n};\n\nexport const DEFAULTS: PaiDaemonConfig = {\n  socketPath: paiSocketPath(),\n  indexIntervalSecs: 300,\n  embedIntervalSecs: 600,\n  embedOnStartup: false,\n  storageBackend: \"sqlite\",\n  postgres: {\n    connectionString: perUserConnectionString(),\n    maxConnections: 5,\n    connectionTimeoutMs: 5000,\n  },\n  embeddingModel: \"Snowflake/snowflake-arctic-embed-m-v1.5\",\n  logLevel: \"info\",\n  notifications: DEFAULT_NOTIFICATION_CONFIG,\n  tasks: DEFAULT_TASK_CONFIG,\n  // Deliberately empty. An install must not guess who the user is: a wrong\n  // guess here is an address that can be mailed without review.\n  identity: { selfEmails: [] },\n  sessions: { cacheKeepalive: { ...DEFAULT_SESSIONS_CACHE_KEEPALIVE } },\n  search: {\n    mode: \"keyword\",\n    rerank: true,\n    recencyBoostDays: 90,\n    defaultLimit: 10,\n    snippetLength: 200,\n  },\n};\n\n/** Config template \u2014 generated at runtime so the DB name is per-user */\nfunction configTemplate(): string {\n  return `{\n  \"socketPath\": \"/tmp/pai.sock\",\n  \"indexIntervalSecs\": 300,\n  \"embedIntervalSecs\": 600,\n  \"storageBackend\": \"sqlite\",\n  \"postgres\": {\n    \"connectionString\": \"${perUserConnectionString()}\",\n    \"maxConnections\": 5,\n    \"connectionTimeoutMs\": 5000\n  },\n  \"embeddingModel\": \"Snowflake/snowflake-arctic-embed-m-v1.5\",\n  \"logLevel\": \"info\",\n  \"vaultPath\": \"\",\n  \"vaultProjectId\": 0,\n  \"search\": {\n    \"mode\": \"keyword\",\n    \"rerank\": true,\n    \"recencyBoostDays\": 90,\n    \"defaultLimit\": 10,\n    \"snippetLength\": 200\n  }\n}\n`;\n}\n\n// ---------------------------------------------------------------------------\n// Path helpers\n// ---------------------------------------------------------------------------\n\n/** Expand a leading ~ to the real home directory */\nexport function expandHome(p: string): string {\n  if (p === \"~\" || p.startsWith(\"~/\") || p.startsWith(\"~\\\\\")) {\n    return join(homedir(), p.slice(1));\n  }\n  return p;\n}\n\n/** Canonical location since 2026-09-19: under the PAI_HOME namespace dir,\n *  so nothing PAI writes can collide with a file Claude Code itself owns. */\nconst NEW_CONFIG_FILE = paiHomePath(\"config.json\");\n\n/** Briefly the canonical location between 2026-09-19's two migrations \u2014\n *  read during the transition, never written to again. */\nconst OLD_CONFIG_FILE = join(homedir(), \".claude\", \"pai.json\");\n\n/** Where the config lived before 2026-09-19 \u2014 read during the transition,\n *  never written to once NEW_CONFIG_FILE exists (see `pai config migrate`). */\nconst LEGACY_CONFIG_FILE = join(homedir(), \".config\", \"pai\", \"config.json\");\n\n/**\n * The path any read/write of the PAI config actually uses: PAI_CONFIG_FILE\n * (tests, power users) first, else the new PAI_HOME location if it exists,\n * else the most recent old location that is actually on disk (printing a\n * one-time notice), else the new location (the target a first write creates).\n */\nexport function paiConfigFilePath(): string {\n  const override = process.env.PAI_CONFIG_FILE;\n  if (override) return override;\n  return resolvePaiFile(NEW_CONFIG_FILE, [OLD_CONFIG_FILE, LEGACY_CONFIG_FILE], \"pai config migrate\");\n}\n\nexport const CONFIG_FILE = paiConfigFilePath();\nexport const CONFIG_DIR = dirname(CONFIG_FILE);\n\n/** config.yaml \u2014 the canonical main config once `pai config yaml` has run,\n *  read/written by readMainConfigRaw/writeMainConfigRaw instead of\n *  CONFIG_FILE whenever it exists (see src/config/main-config.ts). */\nexport function paiConfigYamlFilePath(): string {\n  return yamlSiblingPath(CONFIG_FILE);\n}\n\n/**\n * Read the raw main config object exactly as every non-typed writer\n * (identity, notifications, obsidian, setup, workers, memory settings) needs\n * it: config.yaml when it exists, else CONFIG_FILE. `path` overrides the\n * JSON location (tests, or workers/config.ts's parametrized CONFIG_FILE) \u2014\n * its YAML sibling (same dir, `config.yaml`) is what gets preferred.\n */\nexport function readMainConfigRaw(path: string = CONFIG_FILE): Record<string, unknown> {\n  try {\n    return readDualFormatConfigRaw(path);\n  } catch (e) {\n    throw e instanceof MainConfigError ? new Error(e.message) : e;\n  }\n}\n\n/**\n * Write the raw main config object back through the same seam: a\n * comment-preserving sync into config.yaml when it exists, else a plain\n * writeJsonAtomic to `path`. Every writer of the main config must call this\n * instead of touching CONFIG_FILE directly, so a config.yaml on disk is\n * honored no matter which of them made the change.\n */\nexport function writeMainConfigRaw(raw: Record<string, unknown>, path: string = CONFIG_FILE): void {\n  try {\n    writeDualFormatConfigRaw(path, raw);\n  } catch (e) {\n    throw e instanceof MainConfigError ? new Error(e.message) : e;\n  }\n}\n\nexport const ConfigMigrationError = PaiFileMigrationError;\nexport type ConfigMigrateResult = MigrateFileResult;\n\n/**\n * `pai config migrate`: move config.json (from ~/.claude/pai.json or\n * ~/.config/pai/config.json, whichever is found) to ~/.claude/pai/config.json\n * byte-for-byte, verify the copy, then rename the old file aside as\n * config.json.migrated-<YYYYMMDD> (never deleted).\n */\nexport function migrateConfigFile(opts: { dryRun?: boolean } = {}): ConfigMigrateResult {\n  const result = migratePaiFile(NEW_CONFIG_FILE, [OLD_CONFIG_FILE, LEGACY_CONFIG_FILE], opts);\n  if (!result.dryRun && result.fromPath) {\n    // config.json can hold secrets (e.g. the Postgres password) \u2014 lock down\n    // both the new location and the `.migrated-<stamp>` copy left behind.\n    if (existsSync(result.toPath)) chmodSync(result.toPath, 0o600);\n    const oldDir = dirname(result.fromPath);\n    const oldName = basename(result.fromPath);\n    for (const entry of readdirSync(oldDir)) {\n      if (entry.startsWith(`${oldName}.migrated-`)) chmodSync(join(oldDir, entry), 0o600);\n    }\n  }\n  return result;\n}\n\n// ---------------------------------------------------------------------------\n// Deep merge (handles nested objects, not arrays)\n// ---------------------------------------------------------------------------\n\nfunction deepMerge<T extends object>(\n  target: T,\n  source: Record<string, unknown>\n): T {\n  const result = { ...target };\n  for (const key of Object.keys(source)) {\n    const srcVal = source[key];\n    if (srcVal === undefined || srcVal === null) continue;\n    const tgtVal = (target as Record<string, unknown>)[key];\n    if (\n      typeof srcVal === \"object\" &&\n      !Array.isArray(srcVal) &&\n      typeof tgtVal === \"object\" &&\n      tgtVal !== null &&\n      !Array.isArray(tgtVal)\n    ) {\n      (result as Record<string, unknown>)[key] = deepMerge(\n        tgtVal as object,\n        srcVal as Record<string, unknown>\n      );\n    } else {\n      (result as Record<string, unknown>)[key] = srcVal;\n    }\n  }\n  return result;\n}\n\n// ---------------------------------------------------------------------------\n// Config loader\n// ---------------------------------------------------------------------------\n\n/**\n * Load configuration: config.yaml (see paiConfigYamlFilePath) if it exists,\n * else CONFIG_FILE (see paiConfigFilePath), else defaults. Returns defaults\n * deep-merged with any values found in the file.\n */\nexport function loadConfig(): PaiDaemonConfig {\n  if (!existsSync(CONFIG_FILE) && !existsSync(paiConfigYamlFilePath())) {\n    return { ...DEFAULTS };\n  }\n\n  let parsed: Record<string, unknown>;\n  try {\n    parsed = readMainConfigRaw();\n  } catch (e) {\n    process.stderr.write(\n      `[pai-daemon] Could not read config: ${e instanceof Error ? e.message : String(e)}\\n`\n    );\n    return { ...DEFAULTS };\n  }\n\n  // Compat: config.json may use \"obsidianVaultPath\" (legacy key) instead of \"vaultPath\".\n  // Map it across so the daemon picks it up correctly.\n  if (parsed.obsidianVaultPath && !parsed.vaultPath) {\n    parsed.vaultPath = parsed.obsidianVaultPath;\n    process.stderr.write(\n      `[pai-daemon] Config: mapped obsidianVaultPath \u2192 vaultPath (${parsed.vaultPath})\\n`\n    );\n  }\n\n  return deepMerge(DEFAULTS, parsed);\n}\n\n/**\n * Ensure CONFIG_DIR exists and write a default config template to CONFIG_FILE\n * if none exists yet. Call this only from the `serve` command.\n */\nexport function ensureConfigDir(): void {\n  if (!existsSync(CONFIG_DIR)) {\n    mkdirSync(CONFIG_DIR, { recursive: true });\n    process.stderr.write(\n      `[pai-daemon] Created config directory: ${CONFIG_DIR}\\n`\n    );\n  }\n\n  if (!existsSync(CONFIG_FILE) && !existsSync(paiConfigYamlFilePath())) {\n    try {\n      writeFileSync(CONFIG_FILE, configTemplate(), \"utf-8\");\n      process.stderr.write(\n        `[pai-daemon] Wrote default config to: ${CONFIG_FILE}\\n`\n      );\n    } catch (e) {\n      process.stderr.write(\n        `[pai-daemon] Could not write default config: ${e}\\n`\n      );\n    }\n  }\n}\n", "/**\n * types.ts \u2014 Unified Notification Framework type definitions\n *\n * Defines the channel registry, event routing, and configuration schema\n * for PAI's notification subsystem.\n */\n\n// ---------------------------------------------------------------------------\n// Channel identifiers\n// ---------------------------------------------------------------------------\n\nexport type ChannelId = \"ntfy\" | \"whatsapp\" | \"macos\" | \"voice\" | \"cli\";\n\n// ---------------------------------------------------------------------------\n// Notification event types\n// ---------------------------------------------------------------------------\n\n/**\n * The semantic type of a notification event.\n * Used to route events to the appropriate channels.\n */\nexport type NotificationEvent =\n  | \"error\"\n  | \"progress\"\n  | \"completion\"\n  | \"info\"\n  | \"debug\";\n\n// ---------------------------------------------------------------------------\n// Notification mode\n// ---------------------------------------------------------------------------\n\n/**\n * The current notification mode.\n *\n * - \"auto\"      \u2014 Use the per-event routing table (default)\n * - \"voice\"     \u2014 All events go to voice (WhatsApp TTS)\n * - \"whatsapp\"  \u2014 All events go to WhatsApp text\n * - \"ntfy\"      \u2014 All events go to ntfy.sh\n * - \"macos\"     \u2014 All events go to macOS notifications\n * - \"cli\"       \u2014 All events go to CLI stdout only\n * - \"off\"       \u2014 Suppress all notifications\n */\nexport type NotificationMode =\n  | \"auto\"\n  | \"voice\"\n  | \"whatsapp\"\n  | \"ntfy\"\n  | \"macos\"\n  | \"cli\"\n  | \"off\";\n\n// ---------------------------------------------------------------------------\n// Per-channel configuration\n// ---------------------------------------------------------------------------\n\nexport interface NtfyChannelConfig {\n  enabled: boolean;\n  /** ntfy.sh topic URL, e.g. \"https://ntfy.sh/my-topic\" */\n  url?: string;\n  /** ntfy priority: min | low | default | high | urgent */\n  priority?: \"min\" | \"low\" | \"default\" | \"high\" | \"urgent\";\n}\n\nexport interface WhatsAppChannelConfig {\n  enabled: boolean;\n  /** Optional recipient (phone, JID, or contact name). Omit for self-chat. */\n  recipient?: string;\n}\n\nexport interface MacOsChannelConfig {\n  enabled: boolean;\n}\n\nexport interface VoiceChannelConfig {\n  enabled: boolean;\n  /** Kokoro voice name, e.g. \"bm_george\", \"af_bella\". Default: \"bm_george\" */\n  voiceName?: string;\n}\n\nexport interface CliChannelConfig {\n  enabled: boolean;\n}\n\nexport interface ChannelConfigs {\n  ntfy: NtfyChannelConfig;\n  whatsapp: WhatsAppChannelConfig;\n  macos: MacOsChannelConfig;\n  voice: VoiceChannelConfig;\n  cli: CliChannelConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Routing table\n// ---------------------------------------------------------------------------\n\n/**\n * Maps each event type to the ordered list of channels that should receive it.\n * Only channels that are enabled in `channels` and present in this list are used.\n */\nexport type RoutingTable = {\n  [K in NotificationEvent]: ChannelId[];\n};\n\nexport const DEFAULT_ROUTING: RoutingTable = {\n  error:      [\"whatsapp\", \"macos\", \"ntfy\", \"cli\"],\n  completion: [\"whatsapp\", \"macos\", \"ntfy\", \"cli\"],\n  info:       [\"cli\"],\n  progress:   [\"cli\"],\n  debug:      [],\n};\n\n// ---------------------------------------------------------------------------\n// Top-level notification config (embedded in PaiDaemonConfig)\n// ---------------------------------------------------------------------------\n\nexport interface NotificationConfig {\n  /** Current routing mode. Default: \"auto\" */\n  mode: NotificationMode;\n  /** Per-channel configuration */\n  channels: ChannelConfigs;\n  /** Event \u2192 channel routing (used in \"auto\" mode) */\n  routing: RoutingTable;\n}\n\nexport const DEFAULT_CHANNELS: ChannelConfigs = {\n  ntfy: {\n    enabled: false,\n    url: undefined,\n    priority: \"default\",\n  },\n  whatsapp: {\n    enabled: true,\n    recipient: undefined,\n  },\n  macos: {\n    enabled: true,\n  },\n  voice: {\n    enabled: false,\n    voiceName: \"bm_george\",\n  },\n  cli: {\n    enabled: true,\n  },\n};\n\nexport const DEFAULT_NOTIFICATION_CONFIG: NotificationConfig = {\n  mode: \"auto\",\n  channels: DEFAULT_CHANNELS,\n  routing: DEFAULT_ROUTING,\n};\n\n// ---------------------------------------------------------------------------\n// Notification payload\n// ---------------------------------------------------------------------------\n\nexport interface NotificationPayload {\n  /** Semantic event type \u2014 used for routing */\n  event: NotificationEvent;\n  /** The notification message body */\n  message: string;\n  /** Optional title (used by macOS, ntfy) */\n  title?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Provider interface\n// ---------------------------------------------------------------------------\n\nexport interface NotificationProvider {\n  readonly channelId: ChannelId;\n  /**\n   * Send a notification.\n   * Returns true on success, false on failure (failure is non-fatal).\n   */\n  send(payload: NotificationPayload, config: NotificationConfig): Promise<boolean>;\n}\n\n// ---------------------------------------------------------------------------\n// Send result\n// ---------------------------------------------------------------------------\n\nexport interface SendResult {\n  channelsAttempted: ChannelId[];\n  channelsSucceeded: ChannelId[];\n  channelsFailed: ChannelId[];\n  mode: NotificationMode;\n}\n", "/**\n * types.ts \u2014 Task Bus type definitions\n *\n * Defines the provider registry, ownership resolution, and configuration schema\n * for PAI's cross-session task subsystem.\n *\n * The task bus routes work between PAI sessions through an external tracker.\n * A session files a task; a routine reads it later and dispatches it to the\n * session that owns it \u2014 spawning one if none is running.\n *\n * See docs/task-bus.md for the architecture and its constraints.\n */\n\n// ---------------------------------------------------------------------------\n// Provider identifiers\n// ---------------------------------------------------------------------------\n\nexport type ProviderId = \"todoist\";\n\n// ---------------------------------------------------------------------------\n// Ownership\n// ---------------------------------------------------------------------------\n\n/**\n * Prefix marking a tracker label as a PAI ownership assertion.\n * A task labelled `pai:acme-api` is owned by the `acme-api` project.\n */\nexport const OWNER_LABEL_PREFIX = \"pai:\";\n\n/**\n * How a task's owner was determined. Recorded so the routine can explain\n * itself, and so a mis-resolution is diagnosable rather than silent.\n *\n * - \"label\"     \u2014 an explicit `pai:<project>` label (authoritative)\n * - \"container\" \u2014 the enclosing sub-project name matched a PAI alias (fallback)\n * - \"none\"      \u2014 unresolved; the task stays in the findings inbox\n */\nexport type OwnerSource = \"label\" | \"container\" | \"none\";\n\nexport interface TaskOwner {\n  /** Resolved PAI project short name, e.g. \"acme-api\". Null when UNROUTED. */\n  project: string | null;\n  /** Absolute path to the project root. Null when UNROUTED. */\n  rootPath: string | null;\n  source: OwnerSource;\n  /**\n   * The raw string that resolution was attempted against, kept for diagnostics\n   * when `source` is \"none\" \u2014 e.g. a \"Reading List \uD83D\uDCDA\" container matches no\n   * PAI project, which is expected rather than a fault.\n   */\n  rawHint?: string;\n}\n\n/** An unresolved owner. UNROUTED is a normal state, not an error. */\nexport const UNROUTED: TaskOwner = {\n  project: null,\n  rootPath: null,\n  source: \"none\",\n};\n\n// ---------------------------------------------------------------------------\n// Tasks\n// ---------------------------------------------------------------------------\n\nexport type TaskPriority = \"p1\" | \"p2\" | \"p3\" | \"p4\";\n\nexport interface Task {\n  /** Provider-native task ID. Opaque; never parsed. */\n  id: string;\n  title: string;\n  /**\n   * Full procedure AND reasoning \u2014 enough that the task is actionable months\n   * later, or by the user alone, without re-deriving anything. Enforced at\n   * filing time rather than left to discipline.\n   */\n  body: string;\n  owner: TaskOwner;\n  /** ISO 8601 date or datetime. Null when the task has no due date. */\n  due: string | null;\n  /**\n   * The tracker's own recurrence text, e.g. \"every day at 08:00\". Null for a\n   * one-off.\n   *\n   * Kept verbatim rather than parsed into a rule because it is also the only\n   * way to write a recurrence back: Todoist re-parses this string, and it is\n   * what lets a due date be restored without destroying the recurrence.\n   */\n  recurrence?: string | null;\n  priority: TaskPriority;\n  labels: string[];\n  /**\n   * Stable reference to the artifact this task is about. Prefer a `hook://`\n   * URL over a filesystem path \u2014 it survives renames and moves, and opens in\n   * DEVONthink To Go on iOS.\n   */\n  sourceUrl?: string;\n  /** True for organizational headers that cannot be completed. */\n  isHeader?: boolean;\n}\n\n/** A task being filed. `owner` is a project short name, resolved on write. */\nexport interface NewTask {\n  title: string;\n  body: string;\n  owner?: string | null;\n  due?: string;\n  priority?: TaskPriority;\n  labels?: string[];\n  sourceUrl?: string;\n  /**\n   * Sub-project to file into, created if absent.\n   *\n   * The convention is one sub-project per PAI project under the bus root. It\n   * previously existed only in the shape of the data, so every session had to\n   * re-derive it \u2014 and a session that inferred cautiously filed flat instead,\n   * which is exactly the pile the convention prevents.\n   */\n  into?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Provider interface\n// ---------------------------------------------------------------------------\n\nexport interface ListOptions {\n  /** Only tasks due on or before this ISO date. Omit for all open tasks. */\n  dueBefore?: string;\n  /** Restrict to one resolved owner. Omit for every owner. */\n  owner?: string;\n  /** Include tasks that resolved to UNROUTED. Default: true. */\n  includeUnrouted?: boolean;\n  limit?: number;\n}\n\nexport interface TaskProvider {\n  readonly providerId: ProviderId;\n\n  /**\n   * False when no credential is configured. The bus degrades to a no-op\n   * rather than failing \u2014 a user without a tracker still gets working PAI.\n   */\n  isConfigured(): boolean;\n\n  listOpen(opts: ListOptions): Promise<Task[]>;\n  add(task: NewTask): Promise<Task>;\n  complete(id: string): Promise<void>;\n\n  /**\n   * Rewrite a task's due date through the tracker's natural-language field.\n   *\n   * Optional, and deliberately expressed as a string rather than a date: a\n   * recurring task's schedule and its next occurrence are the same field, so\n   * moving the date without the rule silently downgrades a routine to a one-off.\n   * A provider that cannot express both at once should not offer this.\n   */\n  setDue?(id: string, dueString: string): Promise<void>;\n\n  /**\n   * Sub-projects under the bus root \u2014 the set of addresses a task can be filed\n   * against, one per session.\n   *\n   * Optional because it is not universal: a tracker may address work by tag or\n   * list rather than by nested project, and forcing a nesting concept onto one\n   * that has none would mean faking it. A provider without these simply does\n   * not offer session-scoped inboxes, and callers say so rather than failing.\n   */\n  listSubProjects?(): Promise<Array<{ id: string; name: string }>>;\n  findOrCreateSubProject?(name: string): Promise<{ id: string; created: boolean }>;\n\n  /**\n   * The comment thread on a task, oldest first.\n   *\n   * Optional because not every tracker has threaded comments. Where it exists,\n   * the thread is usually where the reasoning lives \u2014 the question, the answer,\n   * the correction \u2014 and completing the task takes it out of view. That is what\n   * the archive exists to keep.\n   */\n  listComments?(taskId: string): Promise<Array<{ id: string; content: string; postedAt?: string }>>;\n\n  /**\n   * One task by id, whether open or completed.\n   *\n   * Needed because archiving runs at or after completion, and a completed task\n   * is gone from `listOpen` \u2014 which is exactly the moment its discussion stops\n   * being visible and most needs keeping.\n   */\n  getTask?(id: string): Promise<Task | null>;\n}\n\n// ---------------------------------------------------------------------------\n// Configuration\n// ---------------------------------------------------------------------------\n\nexport interface TodoistProviderConfig {\n  enabled: boolean;\n  /**\n   * API token. Resolution order is apiKey \u2192 TODOIST_API_KEY env \u2192 unconfigured.\n   *\n   * Never read this from another tool's config file. PAI ships as a product;\n   * scraping ~/.claude.json for a key belonging to the Todoist MCP is not\n   * acceptable even though the key is sitting there.\n   */\n  apiKey?: string;\n  /**\n   * Tracker project ID that roots the bus (the \"Claude \uD83E\uDD16\" project).\n   *\n   * Stored as an ID, never a name. Todoist's project search silently returns\n   * zero results for names containing emoji \u2014 resolving by name would report\n   * \"no tasks\" instead of failing, which is the exact class of silent failure\n   * this subsystem exists to surface.\n   */\n  rootProjectId?: string;\n  /** Section ID for the findings inbox. Tasks land here when UNROUTED. */\n  findingsSectionId?: string;\n}\n\nexport interface TaskConfig {\n  /** Master switch. When false the bus is inert. */\n  enabled: boolean;\n  providers: {\n    todoist: TodoistProviderConfig;\n  };\n  /**\n   * Dispatch work to the owning session automatically, spawning one if absent.\n   * Requires AIBroker. When false \u2014 or when AIBroker is unavailable \u2014 PAI\n   * reports which project owns each task and leaves acting to the user.\n   */\n  autoDispatch: boolean;\n\n  /**\n   * Seconds AIBroker may spend on a single dispatch, spawn included.\n   *\n   * Passed down to the transport so both sides share one deadline. Raise it on\n   * a loaded machine where sessions are slow to start accepting input.\n   */\n  dispatchTimeoutSecs?: number;\n\n  /**\n   * Project a task goes to when it carries the bare `pai` marker and its\n   * location says nothing \u2014 an Inbox capture, typically.\n   *\n   * This is the one thing a task's location cannot express: \"an AI should take\n   * this, and I do not know which one yet\". Everything else is answered by the\n   * project the task sits in.\n   *\n   * Unset means such a task stays UNROUTED, which is a legitimate choice: it\n   * then surfaces in the findings inbox for triage rather than being guessed at.\n   */\n  defaultOwner?: string;\n}\n\nexport const DEFAULT_TASK_CONFIG: TaskConfig = {\n  enabled: false,\n  providers: {\n    todoist: {\n      enabled: false,\n    },\n  },\n  autoDispatch: false,\n};\n\n// ---------------------------------------------------------------------------\n// Dispatch results\n// ---------------------------------------------------------------------------\n\n/**\n * What happened to one task during a dispatch run.\n *\n * - \"delivered\"    \u2014 sent to an already-running session, and confirmed submitted\n * - \"queued\"       \u2014 typed into a live session that was mid-turn, so submission\n *                    could not be confirmed inside the window. This is delivery:\n *                    Claude Code holds typed input until the current turn ends.\n *                    Never retried \u2014 the text is already in the input box, so a\n *                    second attempt is a second copy, not a retry. One trigger\n *                    arrived three times on 2026-08-01 for exactly that reason.\n * - \"spawned\"      \u2014 none running; one was launched, came up, and received it\n * - \"unrouted\"     \u2014 no owner resolved; left in the findings inbox\n * - \"unlaunchable\" \u2014 an owner resolved but no PAI alias exists to launch it\n * - \"unreachable\"  \u2014 a session was launched but never became ready to accept input\n * - \"skipped\"      \u2014 autoDispatch is off, or no transport; reported only\n *\n * `unlaunchable` and `unreachable` are distinct because the fixes differ:\n * the first is a setup gap (register an alias), the second is a runtime\n * failure (find out why the session did not come up). Collapsing them would\n * send users looking in the wrong place.\n *\n * None of these are errors. A task that could not be delivered is a routing\n * result to report, not an exception to throw.\n */\nexport type DispatchOutcome =\n  | \"delivered\"\n  | \"queued\"\n  | \"spawned\"\n  | \"unrouted\"\n  | \"unlaunchable\"\n  | \"unreachable\"\n  | \"skipped\";\n\nexport interface DispatchResult {\n  task: Task;\n  outcome: DispatchOutcome;\n  /** Session the task reached, when it reached one. */\n  session?: string;\n  /** Why the task did not reach a session. Present on failure outcomes. */\n  reason?: string;\n}\n", "/**\n * runtime-paths.ts \u2014 the shared files PAI talks to the running daemon through.\n *\n * Sockets, logs and pidfiles live at fixed absolute paths under /tmp, and every\n * one of them is shared with a *live* daemon. That makes them the same hazard\n * as any other piece of real user state a test can reach: writing one from a\n * test does not fail, it corrupts something already running, silently.\n *\n * The home guard in test/setup-home-guard.ts does not cover them. It works by\n * redirecting HOME, so it protects paths *derived* from the home directory and\n * nothing else \u2014 a hardcoded \"/tmp/pai.sock\" walks straight past it. Verified\n * on 2026-08-01 by snapshotting all five and running the suite: nothing writes\n * to them today. But \"no test does this yet\" is not a property, and the next\n * daemon test to be written would clobber the live socket with nothing to stop\n * it.\n *\n * So each path is read from an environment variable with the historical /tmp\n * value as its default. Behaviour is unchanged for every real invocation; the\n * test setup overrides the variables and the whole class becomes unreachable\n * rather than merely absent, the same way the home guard works.\n *\n * Read at call time, not at module load: the test setup file runs before any\n * module is imported, but resolving these eagerly would still bake in whatever\n * the environment held at import and make the override order matter.\n */\n\n/** IPC socket for the PAI daemon. */\nexport function paiSocketPath(): string {\n  return process.env.PAI_SOCKET_PATH ?? \"/tmp/pai.sock\";\n}\n\n/** IPC socket for the AIBroker daemon \u2014 read by PAI, owned by AIBroker. */\nexport function aibrokerSocketPath(): string {\n  return process.env.PAI_AIBROKER_SOCKET_PATH ?? \"/tmp/aibroker.sock\";\n}\n\n/** Where the daemon's stdout and stderr are collected. */\nexport function daemonLogPath(): string {\n  return process.env.PAI_DAEMON_LOG_PATH ?? \"/tmp/pai-daemon.log\";\n}\n\n/** Pidfile for the running daemon. */\nexport function daemonPidPath(): string {\n  return process.env.PAI_DAEMON_PID_PATH ?? \"/tmp/pai-daemon.pid\";\n}\n\n/** Where the launchd scheduler tick writes its output. */\nexport function schedulerLogPath(): string {\n  return process.env.PAI_SCHEDULER_LOG_PATH ?? \"/tmp/pai-scheduler.log\";\n}\n\n/**\n * Where the status line caches what it may reuse between renders: the\n * per-provider plan-usage snapshots and the Claude Code version. Shared with\n * every live session's status line, so a test writing here would be feeding\n * fixtures to the real thing. Read by statusline-command.sh as PAI_CACHE_DIR.\n */\nexport function paiCacheDir(): string {\n  return process.env.PAI_CACHE_DIR ?? \"/tmp/claude\";\n}\n\n/**\n * Every runtime path, for the test guard to redirect in one place.\n *\n * Listed here rather than in the guard so that adding a path and forgetting to\n * protect it is not possible: the guard iterates this.\n */\nexport const RUNTIME_PATH_ENV_VARS = [\n  \"PAI_SOCKET_PATH\",\n  \"PAI_AIBROKER_SOCKET_PATH\",\n  \"PAI_DAEMON_LOG_PATH\",\n  \"PAI_DAEMON_PID_PATH\",\n  \"PAI_SCHEDULER_LOG_PATH\",\n  \"PAI_CACHE_DIR\",\n] as const;\n", "/**\n * pai-home.ts \u2014 the PAI_HOME namespace directory and generic per-user file\n * migration into it.\n *\n * Every PAI-owned per-user file (workers.yaml, config.json, whisper-rules.md,\n * advisor-mode.json, ...) lives under PAI_HOME (~/.claude/pai by default) so\n * nothing PAI writes can ever collide with a file Claude Code itself\n * introduces under ~/.claude. Decided 2026-09-19 \u2014 see docs/workers-config.md.\n */\n\nimport { existsSync, mkdirSync, readFileSync, copyFileSync, renameSync, readdirSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, dirname } from \"node:path\";\nimport { execFileSync } from \"node:child_process\";\n\n/**\n * Byte-identical check that works for files of any size. `cmp` compares by\n * streaming rather than loading either file into memory, unlike a\n * readFileSync + Buffer.compare \u2014 which throws (\"File size is greater than\n * 2 GiB\") on anything past Node's 2GiB single-read ceiling, a real limit hit\n * migrating a multi-gigabyte legacy federation database file.\n */\nfunction filesByteIdentical(a: string, b: string): boolean {\n  try {\n    execFileSync(\"cmp\", [\"-s\", a, b], { stdio: \"pipe\" });\n    return true;\n  } catch (e) {\n    if (e && typeof e === \"object\" && \"status\" in e && (e as { status: number }).status === 1) return false;\n    // cmp missing or errored for an unrelated reason \u2014 fall back to an\n    // in-memory compare (fine for the small files this path normally sees).\n    return Buffer.compare(readFileSync(a), readFileSync(b)) === 0;\n  }\n}\n\n/** PAI_HOME (test isolation, power users) overrides the default namespace dir. */\nexport function paiHomeDir(): string {\n  return process.env.PAI_HOME || join(homedir(), \".claude\", \"pai\");\n}\n\n/** A path under PAI_HOME, e.g. `paiHomePath(\"config.json\")`. */\nexport function paiHomePath(...segments: string[]): string {\n  return join(paiHomeDir(), ...segments);\n}\n\nconst noticesPrinted = new Set<string>();\n\n/**\n * Resolve a per-user PAI file: the new PAI_HOME path if it exists, else the\n * first existing entry in `oldCandidates` (checked in order \u2014 most recent\n * old location first), else the new path (the target a first write\n * creates). Prints one stderr notice per process per new-path when a\n * fallback location is actually used.\n */\nexport function resolvePaiFile(newPath: string, oldCandidates: string[], migrateHint: string): string {\n  if (existsSync(newPath)) return newPath;\n  for (const old of oldCandidates) {\n    if (existsSync(old)) {\n      if (!noticesPrinted.has(newPath)) {\n        noticesPrinted.add(newPath);\n        process.stderr.write(\n          `pai: ${old} is at an old location \u2014 run \\`${migrateHint}\\` to move it to ${newPath}\\n`\n        );\n      }\n      return old;\n    }\n  }\n  return newPath;\n}\n\nexport class PaiFileMigrationError extends Error {}\n\nexport interface MigrateFileResult {\n  fromPath: string | null;\n  toPath: string;\n  dryRun: boolean;\n  note?: string;\n}\n\n/**\n * Move a per-user PAI file to its new PAI_HOME location: copy, verify\n * byte-identical, then rename the source to `<name>.migrated-<YYYYMMDD>`\n * (never deleted). Idempotent: if the new path already holds bytes\n * identical to the found source, the source is just renamed aside; if it\n * differs, this refuses rather than overwrite silently.\n */\nexport function migratePaiFile(\n  newPath: string,\n  oldCandidates: string[],\n  opts: { dryRun?: boolean } = {}\n): MigrateFileResult {\n  const fromPath = oldCandidates.find((p) => existsSync(p)) ?? null;\n  if (!fromPath) {\n    const note = existsSync(newPath) ? \"already at new location\" : \"nothing to migrate \u2014 file does not exist yet\";\n    return { fromPath: null, toPath: newPath, dryRun: !!opts.dryRun, note };\n  }\n  if (opts.dryRun) return { fromPath, toPath: newPath, dryRun: true };\n\n  const stamp = new Date().toISOString().slice(0, 10).replace(/-/g, \"\");\n\n  if (existsSync(newPath)) {\n    if (filesByteIdentical(fromPath, newPath)) {\n      renameSync(fromPath, `${fromPath}.migrated-${stamp}`);\n      return { fromPath, toPath: newPath, dryRun: false, note: \"identical \u2014 old file renamed aside\" };\n    }\n    throw new PaiFileMigrationError(\n      `${newPath} already exists and differs from ${fromPath} \u2014 resolve manually, nothing changed`\n    );\n  }\n\n  const dir = dirname(newPath);\n  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n  copyFileSync(fromPath, newPath);\n\n  if (!filesByteIdentical(fromPath, newPath)) {\n    throw new PaiFileMigrationError(\n      `${newPath}: copy did not match ${fromPath} byte-for-byte \u2014 aborting, old file left in place`\n    );\n  }\n\n  renameSync(fromPath, `${fromPath}.migrated-${stamp}`);\n  return { fromPath, toPath: newPath, dryRun: false };\n}\n\nexport interface MigrateDirResult {\n  fromDir: string | null;\n  toDir: string;\n  dryRun: boolean;\n  movedCount?: number;\n  note?: string;\n}\n\n/**\n * Move a per-user PAI directory (queries/, session-state/, ...) into\n * PAI_HOME: move every entry from the first found old candidate into the\n * new dir (never overwriting an existing entry there), then rename the now-\n * empty old dir aside to `<name>.migrated-<YYYYMMDD>` (never deleted).\n * Idempotent \u2014 an already-migrated dir has nothing left to find.\n */\nexport function migratePaiDir(\n  newDir: string,\n  oldCandidates: string[],\n  opts: { dryRun?: boolean } = {}\n): MigrateDirResult {\n  const fromDir = oldCandidates.find((p) => existsSync(p) && statSync(p).isDirectory()) ?? null;\n  if (!fromDir) {\n    const note = existsSync(newDir) ? \"already at new location\" : \"nothing to migrate \u2014 directory does not exist yet\";\n    return { fromDir: null, toDir: newDir, dryRun: !!opts.dryRun, note };\n  }\n\n  const entries = readdirSync(fromDir);\n  if (opts.dryRun) return { fromDir, toDir: newDir, dryRun: true, movedCount: entries.length };\n\n  if (!existsSync(newDir)) mkdirSync(newDir, { recursive: true });\n\n  let moved = 0;\n  const collided: string[] = [];\n  for (const entry of entries) {\n    const src = join(fromDir, entry);\n    const dst = join(newDir, entry);\n    if (existsSync(dst)) {\n      collided.push(entry);\n      continue;\n    }\n    renameSync(src, dst);\n    moved++;\n  }\n\n  const stamp = new Date().toISOString().slice(0, 10).replace(/-/g, \"\");\n  const remaining = readdirSync(fromDir);\n  const note = collided.length\n    ? `${collided.length} entrie(s) left in ${fromDir} \u2014 name already existed in ${newDir}`\n    : undefined;\n\n  if (remaining.length === 0) {\n    renameSync(fromDir, `${fromDir}.migrated-${stamp}`);\n  }\n\n  return { fromDir, toDir: newDir, dryRun: false, movedCount: moved, note };\n}\n", "/**\n * main-config.ts \u2014 the dual-format (config.yaml / config.json) engine behind\n * the main PAI config file. Deliberately has NO dependency on\n * src/daemon/config.ts (which owns path resolution, PaiDaemonConfig and\n * DEFAULTS) so that module can import this one for loadConfig() without a\n * cycle; every path this module touches is passed in explicitly.\n *\n * Precedence, same shape as workers.yaml/workers/config.ts: config.yaml wins\n * when it exists, config.json otherwise. `pai config yaml` (see\n * src/cli/commands/config.ts) performs the one-time JSON\u2192YAML conversion;\n * every writer that goes through readMainConfigRaw/writeMainConfigRaw (see\n * src/daemon/config.ts) keeps working unmodified either way.\n */\n\nimport { existsSync, readFileSync, renameSync, chmodSync } from \"node:fs\";\nimport { dirname, join, basename } from \"node:path\";\nimport { Document, parseDocument } from \"yaml\";\nimport { readJsonStrict, writeJsonAtomic } from \"./json-store.js\";\nimport { writeYamlFileAtomic, syncPlainObjectIntoYamlDoc, deepEqualJson, setYamlKeyComment } from \"./yaml-store.js\";\n\nexport class MainConfigError extends Error {}\n\n/** The config.yaml sibling of a given config.json path (same directory). */\nexport function yamlSiblingPath(jsonPath: string): string {\n  return join(dirname(jsonPath), \"config.yaml\");\n}\n\n/** The path a user should be pointed at: config.yaml when it exists (same\n *  precedence as readDualFormatConfigRaw), else config.json. */\nexport function resolvedMainConfigPath(jsonPath: string, yamlPath: string = yamlSiblingPath(jsonPath)): string {\n  return existsSync(yamlPath) ? yamlPath : jsonPath;\n}\n\n/**\n * Read the raw main config: config.yaml if it exists, else config.json\n * (readJsonStrict \u2014 missing is `{}`, damaged throws), matching\n * readWorkersSection's precedence for workers.yaml/JSON.\n */\nexport function readDualFormatConfigRaw(jsonPath: string, yamlPath: string = yamlSiblingPath(jsonPath)): Record<string, unknown> {\n  if (existsSync(yamlPath)) {\n    let text: string;\n    try {\n      text = readFileSync(yamlPath, \"utf8\");\n    } catch (e) {\n      throw new MainConfigError(`Could not read ${yamlPath}: ${e instanceof Error ? e.message : String(e)}`);\n    }\n    const doc = parseDocument(text);\n    if (doc.errors.length) {\n      throw new MainConfigError(`${yamlPath}: ${doc.errors[0].message}`);\n    }\n    const parsed = doc.toJS();\n    if (parsed === null || parsed === undefined) return {};\n    if (typeof parsed !== \"object\" || Array.isArray(parsed)) {\n      throw new MainConfigError(`${yamlPath}: top level must be a mapping`);\n    }\n    return parsed as Record<string, unknown>;\n  }\n  return readJsonStrict(jsonPath, jsonPath);\n}\n\n/**\n * Write the raw main config back: comment-preserving diff-sync into\n * config.yaml when it exists, else plain writeJsonAtomic to config.json \u2014\n * this is the one seam every writer of the main config (CLI commands,\n * identity, notifications, setup, workers) routes through, so a config.yaml\n * on disk is honored no matter which of them made the change.\n */\nexport function writeDualFormatConfigRaw(\n  jsonPath: string,\n  raw: Record<string, unknown>,\n  yamlPath: string = yamlSiblingPath(jsonPath)\n): void {\n  if (existsSync(yamlPath)) {\n    let text: string;\n    try {\n      text = readFileSync(yamlPath, \"utf8\");\n    } catch (e) {\n      throw new MainConfigError(`Could not read ${yamlPath}: ${e instanceof Error ? e.message : String(e)}`);\n    }\n    const doc = parseDocument(text);\n    if (doc.errors.length) {\n      throw new MainConfigError(`${yamlPath}: ${doc.errors[0].message}`);\n    }\n    const before = (doc.toJS() ?? {}) as Record<string, unknown>;\n    syncPlainObjectIntoYamlDoc(doc, before, raw);\n    try {\n      writeYamlFileAtomic(yamlPath, String(doc), { label: yamlPath });\n    } catch (e) {\n      throw new MainConfigError(e instanceof Error ? e.message : String(e));\n    }\n    return;\n  }\n  writeJsonAtomic(jsonPath, raw, { label: jsonPath });\n}\n\n// ---------------------------------------------------------------------------\n// JSON \u2192 YAML migration (\"pai config yaml\")\n// ---------------------------------------------------------------------------\n\n/**\n * Short annotation for every top-level PaiDaemonConfig field, shown as a `#`\n * comment above the field in the generated config.yaml. Mirrors (and must be\n * kept in sync with) the doc comments on PaiDaemonConfig in\n * src/daemon/config.ts \u2014 kept as a separate short-form table rather than\n * parsed from the TS source at runtime.\n */\nexport const MAIN_CONFIG_SECTION_COMMENTS: Record<string, string> = {\n  socketPath: \"Unix Domain Socket path for daemon IPC.\",\n  indexIntervalSecs: \"How often the daemon re-indexes changed files, in seconds.\",\n  embedIntervalSecs: \"How often the daemon runs the embedding pass, in seconds.\",\n  embedOnStartup:\n    \"Run an embed pass 60s after daemon start. Off by default: with a large backlog it makes every restart a CPU storm.\",\n  maintenanceHour: \"Local hour (0-23) to anchor the recurring index/embed cycle to, so maintenance runs in a fixed window.\",\n  storageBackend: 'Storage backend: \"sqlite\" (default) or \"postgres\".',\n  postgres: 'PostgreSQL connection settings, used when storageBackend is \"postgres\".',\n  embeddingModel: \"Embedding model name, used for semantic/hybrid search.\",\n  logLevel: \"Daemon log level: debug, info, warn, or error.\",\n  vaultPath: \"Obsidian vault root path for zettelkasten indexing, if any.\",\n  vaultProjectId: \"Registry project_id used for vault chunks in memory_chunks. Default: auto-detected.\",\n  notifications: \"Notification subsystem configuration.\",\n  search: \"Search defaults, applied when an MCP tool or CLI call doesn't specify one.\",\n  tasks: \"Task bus \u2014 optional external tracker for cross-session work.\",\n  identity:\n    'Who \"me\" is \u2014 addresses that count as the user\\'s own. Empty by default and never guessed: nothing is self-addressed until this is set.',\n  workers:\n    \"Non-provider worker settings (pane, routing, tree, cache keepalive, fallback). Providers/classes/mcp_sets live in workers.yaml, not here.\",\n};\n\n/** Keys whose leading-underscore string value is a JSON stand-in for a\n *  comment (e.g. `\"_comment\": \"...\"`, `\"_deliverToNote\": \"...\"`). Stripped\n *  from the generated YAML and re-attached as a real `#` comment above the\n *  nearest remaining sibling key in the same object. */\nfunction isCommentKey(key: string): boolean {\n  return key.startsWith(\"_\");\n}\n\ninterface CollectedComment {\n  path: (string | number)[];\n  text: string;\n}\n\n/** Recursively strip `_`-prefixed comment keys out of a plain JSON value,\n *  returning the cleaned value plus where each stripped comment belongs. */\nfunction stripUnderscoreComments(value: unknown, path: (string | number)[] = []): { cleaned: unknown; comments: CollectedComment[] } {\n  if (Array.isArray(value)) {\n    const comments: CollectedComment[] = [];\n    const cleaned = value.map((v, i) => {\n      const r = stripUnderscoreComments(v, [...path, i]);\n      comments.push(...r.comments);\n      return r.cleaned;\n    });\n    return { cleaned, comments };\n  }\n  if (typeof value === \"object\" && value !== null) {\n    const obj = value as Record<string, unknown>;\n    const cleaned: Record<string, unknown> = {};\n    const comments: CollectedComment[] = [];\n    const localComments: string[] = [];\n    for (const [k, v] of Object.entries(obj)) {\n      if (isCommentKey(k)) {\n        if (typeof v === \"string\" && v.trim()) localComments.push(v.trim());\n        continue;\n      }\n      const r = stripUnderscoreComments(v, [...path, k]);\n      cleaned[k] = r.cleaned;\n      comments.push(...r.comments);\n    }\n    // Attach every local comment above the first remaining key in this\n    // object (in source order) \u2014 good enough for the JSON-workaround shape\n    // this exists to convert (a `_comment` sibling explaining the object).\n    const firstKey = Object.keys(cleaned)[0];\n    if (localComments.length && firstKey !== undefined) {\n      comments.unshift({ path: [...path, firstKey], text: localComments.join(\" \") });\n    }\n    return { cleaned, comments };\n  }\n  return { cleaned: value, comments: [] };\n}\n\nexport interface MainConfigMigrateResult {\n  yamlPath: string;\n  yamlText: string;\n  /** Path the pre-migration JSON was renamed to; null on a dry run. */\n  backupPath: string | null;\n  dryRun: boolean;\n}\n\n/**\n * `pai config yaml`: convert config.json to config.yaml. Strips `_`-prefixed\n * JSON-comment-workaround keys into real `#` comments, adds a short\n * annotation above every top-level section (MAIN_CONFIG_SECTION_COMMENTS),\n * verifies the generated YAML re-parses to the exact same data before\n * writing anything, then renames the JSON aside to\n * `config.json.migrated-<YYYY-MM-DD>` (never deleted). Refuses when\n * config.yaml already exists unless `force`. `dryRun` computes and returns\n * the would-be YAML text without touching either file.\n */\nexport function migrateMainConfigToYaml(\n  jsonPath: string,\n  opts: { dryRun?: boolean; force?: boolean; yamlPath?: string; sectionComments?: Record<string, string> } = {}\n): MainConfigMigrateResult {\n  const yamlPath = opts.yamlPath ?? yamlSiblingPath(jsonPath);\n  if (existsSync(yamlPath) && !opts.force) {\n    throw new MainConfigError(`${yamlPath} already exists \u2014 edit it directly, or pass --force to regenerate it from ${jsonPath}`);\n  }\n  if (!existsSync(jsonPath)) {\n    throw new MainConfigError(`${jsonPath} does not exist \u2014 nothing to migrate`);\n  }\n\n  const raw = readJsonStrict(jsonPath, jsonPath);\n  const { cleaned, comments } = stripUnderscoreComments(raw);\n  const cleanedObj = cleaned as Record<string, unknown>;\n\n  const doc = new Document(cleanedObj);\n  const sectionComments = opts.sectionComments ?? MAIN_CONFIG_SECTION_COMMENTS;\n  for (const [key, text] of Object.entries(sectionComments)) {\n    if (key in cleanedObj) setYamlKeyComment(doc, [key], text);\n  }\n  for (const c of comments) {\n    setYamlKeyComment(doc, c.path, c.text);\n  }\n  const yamlText = String(doc);\n\n  // Round-trip check: the generated YAML must re-parse to exactly the data\n  // it was built from before anything is written or renamed.\n  const reparsed = parseDocument(yamlText).toJS();\n  if (!deepEqualJson(reparsed, cleanedObj)) {\n    throw new MainConfigError(\n      `${yamlPath}: generated YAML does not re-parse to the same data as ${jsonPath} \u2014 aborting, nothing written`\n    );\n  }\n\n  if (opts.dryRun) {\n    return { yamlPath, yamlText, backupPath: null, dryRun: true };\n  }\n\n  writeYamlFileAtomic(yamlPath, yamlText, { label: yamlPath });\n\n  const stamp = new Date().toISOString().slice(0, 10);\n  const backupPath = join(dirname(jsonPath), `${basename(jsonPath)}.migrated-${stamp}`);\n  renameSync(jsonPath, backupPath);\n  chmodSync(backupPath, 0o600);\n\n  return { yamlPath, yamlText, backupPath, dryRun: false };\n}\n", "/**\n * json-store.ts \u2014 read/write JSON config files without destroying them\n *\n * The failure this exists to prevent:\n *\n *     try { return JSON.parse(read(path)); } catch { return {}; }\n *     ... later ...\n *     write(path, JSON.stringify(ourData));\n *\n * An unreadable file becomes an empty object, and the next write makes that\n * permanent. Silently, exit code 0. This shape appeared three times in this\n * repo against three different files, and twice in AIBroker.\n *\n * The distinction that matters is between *missing* and *unreadable*:\n *\n *   missing     \u2014 legitimate first run. Start fresh; writing is safe.\n *   unreadable  \u2014 the file exists and we could not parse it. Those bytes are\n *                 the only copy of something. Never overwrite them.\n *\n * Collapsing the second into the first is the bug.\n *\n * NOT everything deserves this guard. For a transient buffer \u2014 an undelivered\n * message queue, a cache \u2014 starting fresh IS the correct recovery, and\n * refusing to write would disable the feature permanently. Use `writeJsonAtomic`\n * alone there: it still prevents a crash from truncating a good file, without\n * blocking recovery. Reserve `readJsonStrict` for data a user cannot rebuild.\n */\n\nimport {\n  existsSync,\n  readFileSync,\n  writeFileSync,\n  copyFileSync,\n  renameSync,\n  unlinkSync,\n  mkdirSync,\n  chmodSync,\n} from \"node:fs\";\nimport { dirname } from \"node:path\";\n\n/**\n * Read a JSON file, distinguishing \"absent\" from \"damaged\".\n *\n * @param path   file to read\n * @param label  how to name it to the user, e.g. \"~/.claude.json\"\n * @throws if the file exists but cannot be read or parsed\n */\nexport function readJsonStrict(path: string, label = path): Record<string, unknown> {\n  if (!existsSync(path)) return {};\n\n  let raw: string;\n  try {\n    raw = readFileSync(path, \"utf8\");\n  } catch (e) {\n    throw new Error(\n      `Could not read ${label}: ${e instanceof Error ? e.message : String(e)}\\n` +\n      `Refusing to continue \u2014 writing now would replace its contents with ours alone.`\n    );\n  }\n\n  try {\n    return JSON.parse(raw) as Record<string, unknown>;\n  } catch (e) {\n    throw new Error(\n      `${label} exists but is not valid JSON: ${e instanceof Error ? e.message : String(e)}\\n` +\n      `Refusing to continue \u2014 overwriting it would destroy whatever it holds.\\n` +\n      `Repair the file, or move it aside and re-run this command.`\n    );\n  }\n}\n\n/**\n * Leaf values that mean \"type word\", not data.\n *\n * A config whose top-level keys map to bare type words is a serialized schema,\n * not a configuration \u2014 the exact shape found over the live config on\n * 2026-09-18 (399 bytes: `socketPath: string`, `indexIntervalSecs: int`, \u2026).\n * No real config carries three of these at its top level; a dump carries\n * nothing else.\n */\nconst SCHEMA_TYPE_WORDS = new Set([\n  \"string\", \"int\", \"integer\", \"number\", \"bool\", \"boolean\",\n  \"float\", \"double\", \"object\", \"array\", \"any\", \"unknown\",\n]);\n\nfunction schemaDumpHits(data: Record<string, unknown>): number {\n  let hits = 0;\n  for (const v of Object.values(data)) {\n    if (typeof v === \"string\" && SCHEMA_TYPE_WORDS.has(v.trim())) hits += 1;\n  }\n  return hits;\n}\n\n/**\n * Write JSON without risking the existing file.\n *\n * Keeps a `.bak-pai` copy of the previous contents, then writes to a temp file\n * and renames. Rename is atomic within a filesystem, so a crash mid-write\n * leaves the original intact rather than truncated \u2014 which is how these files\n * become corrupt in the first place.\n */\nexport function writeJsonAtomic(\n  path: string,\n  data: Record<string, unknown>,\n  opts: { backup?: boolean; label?: string } = {}\n): void {\n  const { backup = true, label = path } = opts;\n  if (schemaDumpHits(data) >= 3) {\n    throw new Error(\n      `${label}: refusing to write \u2014 the object looks like a type schema, not values ` +\n        `(several top-level keys map to bare type words). That is the corruption ` +\n        `signature of 2026-09-18: the caller serialized the schema instead of the ` +\n        `config. Nothing was written.`\n    );\n  }\n  const serialized = JSON.stringify(data, null, 2) + \"\\n\";\n\n  const dir = dirname(path);\n  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n\n  if (backup && existsSync(path)) {\n    try {\n      copyFileSync(path, `${path}.bak-pai`);\n      chmodSync(`${path}.bak-pai`, 0o600);\n    } catch (e) {\n      throw new Error(\n        `Could not back up ${label}: ${e instanceof Error ? e.message : String(e)}\\n` +\n        `Refusing to write without a backup.`\n      );\n    }\n  }\n\n  const tmp = `${path}.tmp-pai-${process.pid}`;\n  try {\n    writeFileSync(tmp, serialized, { encoding: \"utf8\", mode: 0o600 });\n    renameSync(tmp, path);\n    chmodSync(path, 0o600);\n  } catch (e) {\n    try { if (existsSync(tmp)) unlinkSync(tmp); } catch { /* best effort */ }\n    throw new Error(\n      `Failed to write ${label}: ${e instanceof Error ? e.message : String(e)}\\n` +\n      `The original is unchanged.`\n    );\n  }\n}\n", "/**\n * yaml-store.ts \u2014 generic, comment-preserving YAML file helpers shared by\n * every PAI config file that has a YAML form (config.yaml, voices.yaml;\n * workers.yaml keeps its own writer in workers-config.ts because it needs\n * provider-specific key-quoting, but its atomic-write tail is this module's\n * writeYamlFileAtomic).\n */\n\nimport {\n  existsSync,\n  readFileSync,\n  writeFileSync,\n  copyFileSync,\n  renameSync,\n  unlinkSync,\n  mkdirSync,\n  chmodSync,\n} from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { Document, YAMLMap, parseDocument, type Node, type Pair, type Scalar } from \"yaml\";\n\nexport class YamlStoreError extends Error {}\n\n/**\n * Validate `text` parses as YAML, back up any existing file to `.bak-pai`,\n * then write via temp file + rename (atomic within a filesystem) at mode\n * 0600 \u2014 every PAI-owned YAML file can carry secrets, key or no key.\n */\nexport function writeYamlFileAtomic(path: string, text: string, opts: { label?: string } = {}): void {\n  const label = opts.label ?? path;\n  const parsed = parseDocument(text);\n  if (parsed.errors.length) {\n    throw new YamlStoreError(`refusing to write ${label}: ${parsed.errors[0].message} (previous file left unchanged)`);\n  }\n\n  const dir = dirname(path);\n  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n  if (existsSync(path)) {\n    try {\n      copyFileSync(path, `${path}.bak-pai`);\n    } catch (e) {\n      throw new YamlStoreError(\n        `Could not back up ${label}: ${e instanceof Error ? e.message : String(e)}\\nRefusing to write without a backup.`\n      );\n    }\n  }\n  const tmp = `${path}.tmp-pai-${process.pid}`;\n  try {\n    writeFileSync(tmp, text, { encoding: \"utf8\", mode: 0o600 });\n    renameSync(tmp, path);\n    chmodSync(path, 0o600);\n  } catch (e) {\n    try {\n      if (existsSync(tmp)) unlinkSync(tmp);\n    } catch {\n      /* best effort */\n    }\n    throw new YamlStoreError(`Failed to write ${label}: ${e instanceof Error ? e.message : String(e)}`);\n  }\n}\n\n/** Deep-equal for plain JSON-shaped values (objects/arrays/scalars). */\nexport function deepEqualJson(a: unknown, b: unknown): boolean {\n  return JSON.stringify(a) === JSON.stringify(b);\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/**\n * Apply the diff between `before` and `after` (arbitrary nested plain JSON\n * objects) onto a YAML Document, touching only the leaves/keys that actually\n * changed \u2014 this is what lets hand-written comments elsewhere in the file\n * survive a `set`/`unset`. Arrays and non-object values are replaced\n * wholesale when they differ; only plain objects are diffed key by key.\n */\nexport function syncPlainObjectIntoYamlDoc(\n  doc: Document,\n  before: unknown,\n  after: unknown,\n  path: (string | number)[] = []\n): void {\n  if (isPlainObject(after) && isPlainObject(before)) {\n    for (const key of Object.keys(after)) {\n      syncPlainObjectIntoYamlDoc(doc, before[key], after[key], [...path, key]);\n    }\n    for (const key of Object.keys(before)) {\n      if (!(key in after)) doc.deleteIn([...path, key]);\n    }\n    return;\n  }\n  if (after === undefined) {\n    if (before !== undefined) doc.deleteIn(path);\n    return;\n  }\n  if (!deepEqualJson(before, after)) {\n    doc.setIn(path, after);\n  }\n}\n\n/**\n * Attach a `# text` comment directly above the key at `path` inside a YAML\n * Document \u2014 used for the annotated section headers `pai config yaml`\n * writes. No-op if the path does not resolve to a mapping entry (e.g. the\n * key was omitted from the document).\n */\nexport function setYamlKeyComment(doc: Document, path: (string | number)[], text: string): void {\n  const parentPath = path.slice(0, -1);\n  const lastKey = path[path.length - 1];\n  const parent = parentPath.length ? doc.getIn(parentPath, true) : doc.contents;\n  if (!(parent instanceof YAMLMap)) return;\n  const pair = (parent.items as Pair[]).find((p) => (p.key as Scalar)?.value === lastKey);\n  if (pair) {\n    (pair.key as Node & { commentBefore?: string }).commentBefore = ` ${text}`;\n  }\n}\n", "/**\n * workers-config.ts \u2014 workers.yaml: providers, model roles, class routing,\n * mcp_sets.\n *\n * config.ts's readWorkersSection/writeWorkersSection are the only callers \u2014\n * every other module keeps talking to the WorkersConfig shape from config.ts\n * and never touches this file. That is deliberate: adding a provider used to\n * mean editing JSON inside an unrelated config blob; this module makes\n * providers/classes/mcp_sets/active a single human-editable file, documented\n * in docs/workers-config.md, while everything downstream is unchanged.\n *\n * Writes go through the `yaml` package's Document API and only touch the\n * entries that actually changed, so hand-written comments elsewhere in the\n * file \u2014 including a comment directly above an untouched provider \u2014 survive\n * byte-for-byte across `add`, `use`, `disable`, and every other mutation.\n */\n\nimport { existsSync, readFileSync, writeFileSync, chmodSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { Document, Scalar, parseDocument, type Node } from \"yaml\";\nimport { readJsonStrict, writeJsonAtomic } from \"../config/json-store.js\";\nimport { writeYamlFileAtomic, YamlStoreError } from \"../config/yaml-store.js\";\nimport { paiHomePath, resolvePaiFile, migratePaiFile, type MigrateFileResult } from \"../config/pai-home.js\";\nimport {\n  ANTHROPIC_NATIVE,\n  NATIVE_ANTHROPIC_MODELS,\n  WorkersConfigError,\n  expandHome,\n  isModelCapability,\n  parseCapabilitiesValue,\n  parseClassesValue,\n  parseMcpSetsValue,\n  parseModelsBlock,\n  parseProvider,\n  parseWorkersConfig,\n  type ClassTarget,\n  type WorkerProvider,\n} from \"./config.js\";\n\nexport const WORKERS_YAML_FILENAME = \"workers.yaml\";\n\n/**\n * Where workers.yaml lives since 2026-09-19: under the PAI_HOME namespace\n * dir (~/.claude/pai by default) \u2014 this file is per-user state that can\n * carry API keys and must never be committed, same as the rest of PAI_HOME.\n */\nfunction defaultWorkersYamlPath(): string {\n  return paiHomePath(WORKERS_YAML_FILENAME);\n}\n\n/** Briefly the canonical location between 2026-09-19's two migrations \u2014\n *  read during the transition, never written to again. */\nfunction oldWorkersYamlPath(): string {\n  return join(homedir(), \".claude\", WORKERS_YAML_FILENAME);\n}\n\n/** Where workers.yaml lived before 2026-09-19 \u2014 read during the transition,\n *  never written to (see `pai worker config migrate`). */\nfunction legacyWorkersYamlPath(): string {\n  return join(homedir(), \".config\", \"pai\", WORKERS_YAML_FILENAME);\n}\n\n/**\n * The path any read/write of workers.yaml actually uses: PAI_WORKERS_YAML\n * (tests, power users) first, else the new PAI_HOME location if it exists,\n * else the most recent old location that is actually on disk (printing a\n * one-time notice), else the new location (the target a first write creates).\n */\nexport function workersYamlPath(): string {\n  const override = process.env.PAI_WORKERS_YAML;\n  if (override) return override;\n  return resolvePaiFile(\n    defaultWorkersYamlPath(),\n    [oldWorkersYamlPath(), legacyWorkersYamlPath()],\n    \"pai worker config migrate\"\n  );\n}\n\n/** Where a fresh write (init, migrate, relocate's destination) always\n *  targets \u2014 the new location, or PAI_WORKERS_YAML for test isolation.\n *  Never an old path: nothing is ever written there again. */\nfunction writeTargetWorkersYamlPath(): string {\n  return process.env.PAI_WORKERS_YAML ?? defaultWorkersYamlPath();\n}\n\n/**\n * One-line notice for `pai worker config check` and `pai worker providers`\n * when workers.yaml is still sitting at an old location. Null once it has\n * moved (or PAI_WORKERS_YAML is set \u2014 that always wins, nothing to migrate).\n */\nexport function workersYamlLegacyNotice(): string | null {\n  if (process.env.PAI_WORKERS_YAML) return null;\n  if (existsSync(defaultWorkersYamlPath())) return null;\n  const found = [oldWorkersYamlPath(), legacyWorkersYamlPath()].find((p) => existsSync(p));\n  if (!found) return null;\n  return `workers.yaml is still at the old location (${found}) \u2014 run \\`pai worker config migrate\\` to move it to ${defaultWorkersYamlPath()}`;\n}\n\nexport interface WorkersYamlData {\n  active: string | null;\n  providers: Record<string, WorkerProvider>;\n  classes: Record<string, ClassTarget>;\n  capabilities: Record<string, string[]>;\n  mcpSets: Record<string, string[]>;\n  nativeModels: WorkerProvider[\"models\"];\n}\n\n// ---------------------------------------------------------------------------\n// Friendly (on-disk) provider shape \u2194 internal WorkerProvider\n// ---------------------------------------------------------------------------\n\n/** snake_case on-disk keys \u2192 the camelCase raw shape parseProvider expects. */\nfunction yamlProviderToRaw(y: Record<string, unknown>): Record<string, unknown> {\n  const raw: Record<string, unknown> = {};\n  if (y.enabled !== undefined) raw.enabled = y.enabled;\n  if (y.url !== undefined) raw.baseUrl = y.url;\n  if (y.key_file !== undefined) raw.keyFile = y.key_file;\n  if (y.key !== undefined) raw.key = y.key;\n  if (y.tier !== undefined) raw.costTier = y.tier;\n  if (y.models !== undefined) raw.models = y.models;\n  if (y.protocol !== undefined) raw.protocol = y.protocol;\n  if (y.engine !== undefined) raw.engine = y.engine;\n  if (y.upstream_url !== undefined) raw.upstreamUrl = y.upstream_url;\n  if (y.env !== undefined) raw.env = y.env;\n  if (y.note !== undefined) raw.note = y.note;\n  if (y.quota_probe !== undefined) raw.quotaProbe = y.quota_probe;\n  if (y.quota_skip_at !== undefined) raw.quotaSkipAt = y.quota_skip_at;\n  if (y.context_window !== undefined) raw.contextWindow = y.context_window;\n  if (y.tags !== undefined) raw.tags = y.tags;\n  if (y.usage !== undefined) raw.usage = y.usage;\n  if (y.model_tiers !== undefined) raw.modelTiers = y.model_tiers;\n  return raw;\n}\n\n/** Internal WorkerProvider \u2192 the friendly on-disk plain object for writing. */\nfunction providerToYamlPlain(p: WorkerProvider): Record<string, unknown> {\n  const y: Record<string, unknown> = {};\n  if (!p.enabled) y.enabled = false;\n  if (p.baseUrl) y.url = p.baseUrl;\n  if (p.keyFile) y.key_file = p.keyFile;\n  if (p.key) y.key = p.key;\n  if (p.costTier !== undefined) y.tier = p.costTier;\n  y.models = { ...p.models };\n  if (p.protocol && p.protocol !== \"anthropic\") y.protocol = p.protocol;\n  if (p.engine && p.engine !== \"claude\") y.engine = p.engine;\n  if (p.upstreamUrl) y.upstream_url = p.upstreamUrl;\n  if (p.env && Object.keys(p.env).length) y.env = { ...p.env };\n  if (p.note) y.note = p.note;\n  if (p.quotaProbe) y.quota_probe = p.quotaProbe;\n  if (p.quotaSkipAt !== undefined) y.quota_skip_at = p.quotaSkipAt;\n  if (p.contextWindow !== undefined) y.context_window = p.contextWindow;\n  if (p.tags?.length) y.tags = [...p.tags];\n  if (p.usage) y.usage = p.usage;\n  if (p.modelTiers) y.model_tiers = { ...p.modelTiers };\n  return y;\n}\n\n/** The builtin `anthropic` block only ever carries `builtin: true` + `models`. */\nfunction parseBuiltinAnthropic(raw: unknown, pathPrefix: string): WorkerProvider[\"models\"] {\n  if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n    throw new WorkersConfigError(`${pathPrefix}: must be an object`);\n  }\n  const p = raw as Record<string, unknown>;\n  if (p.builtin !== true) {\n    throw new WorkersConfigError(\n      `${pathPrefix}: \"${ANTHROPIC_NATIVE}\" is reserved for the built-in Claude Code login \u2014 ` +\n        `set \"builtin: true\" (optionally with a \"models\" override) or rename this provider`\n    );\n  }\n  const disallowed = [\"url\", \"key_file\", \"key\", \"engine\", \"protocol\", \"upstream_url\"].filter(\n    (k) => p[k] !== undefined\n  );\n  if (disallowed.length) {\n    throw new WorkersConfigError(\n      `${pathPrefix}: a builtin provider cannot set ${disallowed.join(\", \")} \u2014 it runs on Claude Code's own login`\n    );\n  }\n  if (p.models === undefined) return { ...NATIVE_ANTHROPIC_MODELS };\n  return { ...NATIVE_ANTHROPIC_MODELS, ...parseModelsBlock(`${pathPrefix}.models`, p.models) };\n}\n\n// ---------------------------------------------------------------------------\n// Line-numbered errors\n// ---------------------------------------------------------------------------\n\nfunction lineOf(doc: Document, path: (string | number)[]): number | null {\n  try {\n    const node = doc.getIn(path, true) as Node | undefined;\n    const range = node && typeof node === \"object\" && \"range\" in node ? node.range : undefined;\n    if (!range) return null;\n    const text = String(doc);\n    return text.slice(0, range[0]).split(\"\\n\").length;\n  } catch {\n    return null;\n  }\n}\n\nfunction withLine(doc: Document, path: (string | number)[], yamlPath: string, e: unknown): never {\n  const msg = e instanceof Error ? e.message : String(e);\n  const line = lineOf(doc, path);\n  throw new WorkersConfigError(line ? `${yamlPath}:${line}: ${msg}` : `${yamlPath}: ${msg}`);\n}\n\n// ---------------------------------------------------------------------------\n// Load + validate\n// ---------------------------------------------------------------------------\n\n/**\n * Parse and fully validate a workers.yaml Document. Throws WorkersConfigError\n * naming `<path>:<line>` for anything wrong \u2014 an unknown provider referenced\n * by a class is a load error here, not a spawn-time surprise.\n */\nexport function parseWorkersYamlDocument(doc: Document, yamlPath: string): WorkersYamlData {\n  const root = doc.toJS() ?? {};\n  if (typeof root !== \"object\" || Array.isArray(root)) {\n    throw new WorkersConfigError(`${yamlPath}: top level must be a mapping`);\n  }\n  const r = root as Record<string, unknown>;\n\n  const providers: Record<string, WorkerProvider> = {};\n  let nativeModels: WorkerProvider[\"models\"] = { ...NATIVE_ANTHROPIC_MODELS };\n  const providersRaw = r.providers;\n  if (providersRaw !== undefined) {\n    if (typeof providersRaw !== \"object\" || providersRaw === null || Array.isArray(providersRaw)) {\n      withLine(doc, [\"providers\"], yamlPath, new WorkersConfigError(\"providers: must be a mapping of name \u2192 provider\"));\n    }\n    for (const [name, raw] of Object.entries(providersRaw as Record<string, unknown>)) {\n      try {\n        if (name === ANTHROPIC_NATIVE) {\n          nativeModels = parseBuiltinAnthropic(raw, `providers.${name}`);\n        } else {\n          providers[name] = parseProvider(name, yamlProviderToRaw(raw as Record<string, unknown>));\n        }\n      } catch (e) {\n        withLine(doc, [\"providers\", name], yamlPath, e);\n      }\n    }\n  }\n\n  let classes: Record<string, ClassTarget> = {};\n  if (r.classes !== undefined) {\n    try {\n      classes = parseClassesValue(r.classes, \"classes\");\n    } catch (e) {\n      withLine(doc, [\"classes\"], yamlPath, e);\n    }\n    // Cross-validate: every class must name a known provider (or \"anthropic\")\n    // and, if it names a role, a capability that provider actually declares.\n    // Unlike the JSON path (where a provider can be removed out from under a\n    // class and the error surfaces at spawn time), workers.yaml catches this\n    // at load time.\n    for (const [cls, target] of Object.entries(classes)) {\n      const provider = typeof target === \"string\" ? target.split(\"/\")[0] : target.provider;\n      const alias = typeof target === \"string\" ? target.split(\"/\")[1] : undefined;\n      if (provider !== undefined) {\n        const native = provider === ANTHROPIC_NATIVE;\n        if (!native && !providers[provider]) {\n          withLine(\n            doc,\n            [\"classes\", cls],\n            yamlPath,\n            new WorkersConfigError(\n              `classes.${cls}: no provider named \"${provider}\" (configured: ${Object.keys(providers).join(\", \") || \"(none)\"})`\n            )\n          );\n        }\n        if (alias !== undefined) {\n          if (!isModelCapability(alias)) {\n            withLine(\n              doc,\n              [\"classes\", cls],\n              yamlPath,\n              new WorkersConfigError(\n                `classes.${cls}: \"${alias}\" is not a valid capability name (must match ^[a-z][a-z0-9-]*$)`\n              )\n            );\n          } else if (!native && providers[provider] && alias !== \"default\" && !providers[provider].models[alias]) {\n            // the native provider has no configurable model slots \u2014 any\n            // alias resolves through resolveModelCapability's own fallback\n            withLine(\n              doc,\n              [\"classes\", cls],\n              yamlPath,\n              new WorkersConfigError(`classes.${cls}: provider \"${provider}\" has no \"${alias}\" model configured`)\n            );\n          }\n        }\n      }\n    }\n  }\n\n  let capabilities: Record<string, string[]> = {};\n  if (r.capabilities !== undefined) {\n    try {\n      capabilities = parseCapabilitiesValue(r.capabilities, \"capabilities\");\n    } catch (e) {\n      withLine(doc, [\"capabilities\"], yamlPath, e);\n    }\n  }\n\n  let mcpSets: Record<string, string[]> = {};\n  if (r.mcp_sets !== undefined) {\n    try {\n      mcpSets = parseMcpSetsValue(r.mcp_sets, \"mcp_sets\");\n    } catch (e) {\n      withLine(doc, [\"mcp_sets\"], yamlPath, e);\n    }\n  } else {\n    mcpSets = parseMcpSetsValue(undefined, \"mcp_sets\");\n  }\n\n  const active = r.active === undefined || r.active === null ? null : String(r.active);\n  if (active !== null && active !== ANTHROPIC_NATIVE && active !== \"auto\" && !providers[active]) {\n    withLine(\n      doc,\n      [\"active\"],\n      yamlPath,\n      new WorkersConfigError(\n        `active: no provider named \"${active}\" (configured: ${Object.keys(providers).join(\", \") || \"(none)\"})`\n      )\n    );\n  }\n\n  return { active, providers, classes, capabilities, mcpSets, nativeModels };\n}\n\n/** Read + parse workers.yaml. Returns null if the file does not exist. */\nexport function readWorkersYaml(yamlPath: string): { doc: Document; data: WorkersYamlData } | null {\n  if (!existsSync(yamlPath)) return null;\n  let text: string;\n  try {\n    text = readFileSync(yamlPath, \"utf8\");\n  } catch (e) {\n    throw new WorkersConfigError(\n      `Could not read ${yamlPath}: ${e instanceof Error ? e.message : String(e)}`\n    );\n  }\n  const doc = parseDocument(text);\n  if (doc.errors.length) {\n    throw new WorkersConfigError(`${yamlPath}: ${doc.errors[0].message}`);\n  }\n  const data = parseWorkersYamlDocument(doc, yamlPath);\n  return { doc, data };\n}\n\n// ---------------------------------------------------------------------------\n// Write (diff-based, comment-preserving)\n// ---------------------------------------------------------------------------\n\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n  return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/**\n * A `key:` value as an explicit double-quoted YAML scalar. A key is an\n * opaque token, not YAML-authored text \u2014 plain-scalar auto-styling could\n * read one back as a number or boolean (an all-digit token, \"true\", \"no\", \u2026)\n * if it were ever left unquoted, so every write forces the quoted form\n * regardless of what the plain style would otherwise pick.\n */\nfunction quotedKeyNode(value: string): Scalar {\n  const s = new Scalar(value);\n  s.type = Scalar.QUOTE_DOUBLE;\n  return s;\n}\n\n/**\n * Apply the changes between `before` and `after` onto `doc`, touching only\n * the providers/classes/mcp_sets/active entries that actually differ. This is\n * what makes comment preservation possible: an untouched provider's node\n * (and any comment above it) is never revisited.\n */\nfunction syncWorkersYamlDocument(doc: Document, before: WorkersYamlData, after: WorkersYamlData): void {\n  // providers: add/update changed, remove gone (never touch the builtin anthropic block)\n  for (const [name, p] of Object.entries(after.providers)) {\n    const beforeP = before.providers[name];\n    const changed = !beforeP || !shallowEqual(providerToYamlPlain(beforeP), providerToYamlPlain(p));\n    if (changed) {\n      // a fresh (or wholesale-replaced) provider entry is set in one shot as\n      // a plain object \u2014 the yaml lib only turns it into real Map/Scalar\n      // nodes lazily at stringify time, so a follow-up setIn/deleteIn into\n      // the same not-yet-a-collection value would fail. Embedding the `key`\n      // as an actual Scalar node here rides along: stringify leaves already-\n      // Node values alone (see stringifyPair.js), quoting only that field.\n      const y: Record<string, unknown> = providerToYamlPlain(p);\n      if (typeof y.key === \"string\") y.key = quotedKeyNode(y.key);\n      doc.setIn([\"providers\", name], y);\n    }\n  }\n  for (const name of Object.keys(before.providers)) {\n    if (!(name in after.providers)) doc.deleteIn([\"providers\", name]);\n  }\n\n  // builtin anthropic models: only the capabilities that changed; the entry\n  // is created (with `builtin: true`) when the file has none yet\n  if (!shallowEqual(before.nativeModels, after.nativeModels)) {\n    if (!doc.hasIn([\"providers\", ANTHROPIC_NATIVE])) {\n      doc.setIn([\"providers\", ANTHROPIC_NATIVE], { builtin: true, models: { ...after.nativeModels } });\n    } else {\n      for (const [cap, id] of Object.entries(after.nativeModels)) {\n        if (before.nativeModels[cap] !== id) doc.setIn([\"providers\", ANTHROPIC_NATIVE, \"models\", cap], id);\n      }\n    }\n  }\n\n  // classes: same add/update/remove diff\n  for (const [cls, target] of Object.entries(after.classes)) {\n    if (!shallowEqual(before.classes[cls], target)) {\n      doc.setIn([\"classes\", cls], target);\n    }\n  }\n  for (const cls of Object.keys(before.classes)) {\n    if (!(cls in after.classes)) doc.deleteIn([\"classes\", cls]);\n  }\n\n  // capabilities: same add/update/remove diff\n  for (const [cap, prefs] of Object.entries(after.capabilities)) {\n    if (!shallowEqual(before.capabilities[cap], prefs)) {\n      doc.setIn([\"capabilities\", cap], [...prefs]);\n    }\n  }\n  for (const cap of Object.keys(before.capabilities)) {\n    if (!(cap in after.capabilities)) doc.deleteIn([\"capabilities\", cap]);\n  }\n\n  // mcp_sets: same add/update/remove diff\n  for (const [set, servers] of Object.entries(after.mcpSets)) {\n    if (!shallowEqual(before.mcpSets[set], servers)) {\n      doc.setIn([\"mcp_sets\", set], [...servers]);\n    }\n  }\n  for (const set of Object.keys(before.mcpSets)) {\n    if (!(set in after.mcpSets)) doc.deleteIn([\"mcp_sets\", set]);\n  }\n\n  // active\n  if (before.active !== after.active) {\n    if (after.active === null) doc.deleteIn([\"active\"]);\n    else doc.setIn([\"active\"], after.active);\n  }\n}\n\n/**\n * Write `after` into workers.yaml, preserving comments on everything that did\n * not change. Re-reads the file fresh (so the diff is against what is really\n * on disk, not a stale in-memory copy) and re-validates the result before\n * committing; on failure the previous bytes are left untouched.\n */\nexport function writeWorkersYaml(yamlPath: string, after: WorkersYamlData): void {\n  const existing = readWorkersYaml(yamlPath);\n  const doc = existing ? existing.doc : new Document({});\n  const before: WorkersYamlData = existing\n    ? existing.data\n    : {\n        active: null,\n        providers: {},\n        classes: {},\n        capabilities: {},\n        mcpSets: {},\n        nativeModels: { ...NATIVE_ANTHROPIC_MODELS },\n      };\n  syncWorkersYamlDocument(doc, before, after);\n  writeWorkersYamlText(yamlPath, String(doc));\n}\n\n/** Atomic write with a .bak-pai backup and a re-validate-or-restore guard.\n *  The file-I/O tail (backup, temp write at 0600, rename, chmod) is shared\n *  with every other PAI YAML file via writeYamlFileAtomic; only the\n *  workers.yaml-specific validation (parseWorkersYamlDocument) lives here. */\nexport function writeWorkersYamlText(yamlPath: string, text: string): void {\n  // Validate before committing anything to disk.\n  const probe = parseDocument(text);\n  if (probe.errors.length) {\n    throw new WorkersConfigError(`refusing to write ${yamlPath}: ${probe.errors[0].message} (previous file left unchanged)`);\n  }\n  try {\n    parseWorkersYamlDocument(probe, yamlPath);\n  } catch (e) {\n    const msg = e instanceof Error ? e.message : String(e);\n    throw new WorkersConfigError(`refusing to write ${yamlPath}: ${msg} (previous file left unchanged)`);\n  }\n\n  try {\n    writeYamlFileAtomic(yamlPath, text, { label: yamlPath });\n  } catch (e) {\n    throw new WorkersConfigError(e instanceof YamlStoreError ? e.message : String(e instanceof Error ? e.message : e));\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Starter template, init, migrate\n// ---------------------------------------------------------------------------\n\n/** The exact commented starter shipped as examples/workers.yaml and by `init`. */\nexport function starterWorkersYamlText(): string {\n  return `# PAI worker configuration.\n# Providers PAI can run workers on, the model each role uses, and which\n# provider every --class goes to. Edit by hand; \\`pai worker providers\\` shows\n# the effective result. Comments are preserved when PAI writes this file.\n#\n# Per-user state, kept 0600: this file can hold API keys (\\`key:\\`, below).\n# Never commit it or share it. \\`key_file: <path>\\` keeps a secret in its own\n# 0600 file instead, if you'd rather not put it here.\n\nactive: anthropic          # provider for \\`pai worker run\\` without --provider or --class\n\nproviders:\n  anthropic:\n    builtin: true          # Claude Code's own login: no url, no key file\n    models:\n      default: ${NATIVE_ANTHROPIC_MODELS.default}\n      fast: ${NATIVE_ANTHROPIC_MODELS.fast}\n  glm:\n    url: https://api.z.ai/api/anthropic\n    key: \"<your-api-key>\"   # or key_file: <path to a 0600 file>\n    tier: 3\n    models:\n      default: glm-5.3[1m]\n      fast: glm-5.3-flash\n      image: example-paint\n  kimi:\n    url: https://api.kimi.ai/coding/\n    key: \"<your-api-key>\"   # or key_file: <path to a 0600 file>\n    tier: 3\n    models:\n      default: k3[1m]\n      fast: kimi-for-coding[1m]\n\n# An \\`engine: image\\` provider does not spawn Claude \u2014 \\`pai worker run\n# --capability image\\` POSTs straight to its OpenAI-compatible images API and\n# writes the PNG it gets back. Uncomment and point it at a real provider\n# (still nested under providers:, above) to enable \\`--capability image\\`:\n#   pictures:\n#     engine: image\n#     url: https://api.example.com/v1\n#     key: \"<your-api-key>\"\n#     models:\n#       default: example-image-model\n#       image: example-image-model\n\n# A class names a provider, or provider/role to pick a non-default model.\n# Workers exist to parallelise and to save cost: the default is Sonnet,\n# Haiku for the mechanical classes, and nothing here inherits the\n# orchestrating session's model.\nclasses:\n  implement: anthropic\n  draft: anthropic\n  research: anthropic\n  complex: anthropic\n  plan: anthropic\n  review: anthropic\n  spotcheck: anthropic/fast\n  simple: anthropic/fast\n  image: glm/image\n\n# Cross-provider capability preference: which provider serves a --capability\n# request, in order, when more than one declares it. Unlisted capabilities\n# fall back to the active provider, then any provider that declares them.\n# capabilities:\n#   image: [pictures, glm]\n#   fast: [anthropic]\n\nmcp_sets:\n  desktop: [clickr]\n`;\n}\n\n/**\n * Build a workers.yaml document from real (migrated) data, keeping the same\n * header/section comments as the starter. Used by `pai worker config\n * migrate` \u2014 `init` writes the literal starter instead, since it has no data\n * to carry over.\n */\nexport function buildWorkersYamlText(data: WorkersYamlData): string {\n  const lines: string[] = [];\n  lines.push(\"# PAI worker configuration.\");\n  lines.push(\"# Providers PAI can run workers on, the model each role uses, and which\");\n  lines.push(\"# provider every --class goes to. Edit by hand; `pai worker providers` shows\");\n  lines.push(\"# the effective result. Comments are preserved when PAI writes this file.\");\n  lines.push(\"\");\n  lines.push(\n    `active: ${data.active ?? \"null\"}` +\n      \"          # provider for `pai worker run` without --provider or --class\"\n  );\n  lines.push(\"\");\n  lines.push(\"providers:\");\n  lines.push(\"  anthropic:\");\n  lines.push(\"    builtin: true          # Claude Code's own login: no url, no key file\");\n  lines.push(\"    models:\");\n  lines.push(`      default: ${data.nativeModels.default}`);\n  if (data.nativeModels.fast) lines.push(`      fast: ${data.nativeModels.fast}`);\n  if (data.nativeModels.image) lines.push(`      image: ${data.nativeModels.image}`);\n  for (const [name, p] of Object.entries(data.providers)) {\n    const y = providerToYamlPlain(p);\n    lines.push(`  ${name}:`);\n    for (const [k, v] of Object.entries(y)) {\n      if (k === \"models\") continue;\n      // a key is an opaque token, not YAML-authored text \u2014 always quoted so\n      // it never round-trips as a number or boolean (see quotedKeyNode).\n      lines.push(k === \"key\" ? `    key: ${JSON.stringify(String(v))}` : `    ${k}: ${yamlScalar(v)}`);\n    }\n    lines.push(\"    models:\");\n    for (const [k, v] of Object.entries(p.models)) lines.push(`      ${k}: ${yamlScalar(v)}`);\n  }\n  lines.push(\"\");\n  lines.push(\"# A class names a provider, or provider/role to pick a non-default model.\");\n  lines.push(\"# Workers exist to parallelise and to save cost: the default is Sonnet,\");\n  lines.push(\"# Haiku for the mechanical classes, and nothing here inherits the\");\n  lines.push(\"# orchestrating session's model.\");\n  const classEntries = Object.entries(data.classes);\n  lines.push(classEntries.length ? \"classes:\" : \"classes: {}\");\n  for (const [cls, target] of classEntries) {\n    lines.push(`  ${cls}: ${typeof target === \"string\" ? target : yamlScalar(target)}`);\n  }\n  lines.push(\"\");\n  const capEntries = Object.entries(data.capabilities);\n  if (capEntries.length) {\n    lines.push(\"capabilities:\");\n    for (const [cap, prefs] of capEntries) lines.push(`  ${cap}: [${prefs.join(\", \")}]`);\n    lines.push(\"\");\n  }\n  const mcpEntries = Object.entries(data.mcpSets);\n  lines.push(mcpEntries.length ? \"mcp_sets:\" : \"mcp_sets: {}\");\n  for (const [set, servers] of mcpEntries) {\n    lines.push(`  ${set}: [${servers.join(\", \")}]`);\n  }\n  lines.push(\"\");\n  return lines.join(\"\\n\");\n}\n\n/** Minimal scalar formatter for buildWorkersYamlText's flat key: value lines. */\nfunction yamlScalar(v: unknown): string {\n  if (typeof v === \"string\") {\n    // quote only when the plain form would be ambiguous YAML\n    return /^[\\w./~\\[\\]-]+$/.test(v) ? v : JSON.stringify(v);\n  }\n  if (Array.isArray(v)) return `[${v.map(yamlScalar).join(\", \")}]`;\n  if (v && typeof v === \"object\") return JSON.stringify(v);\n  return String(v);\n}\n\n// ---------------------------------------------------------------------------\n// Migration from the JSON `workers` section\n// ---------------------------------------------------------------------------\n\nexport interface MigrateResult {\n  yamlPath: string;\n  yamlText: string;\n  /** Path the pre-migration JSON `workers` section was backed up to; null on a dry run. */\n  backupPath: string | null;\n  dryRun: boolean;\n}\n\n/**\n * `pai worker config migrate`: reads the JSON `workers` section, writes\n * workers.yaml with the starter's comments, backs the JSON section up to\n * `workers.json.migrated-<date>` next to it, and strips providers/classes\n * (and the legacy `roles`)/mcpSets/active from the JSON. Idempotent: refuses\n * when workers.yaml already exists unless `force`. `dryRun` computes and\n * returns the would-be YAML text without touching either file.\n */\nexport function migrateWorkersToYaml(\n  jsonPath: string,\n  opts: { force?: boolean; dryRun?: boolean } = {}\n): MigrateResult {\n  const existing = workersYamlPath();\n  if (existsSync(existing) && !opts.force) {\n    throw new WorkersConfigError(\n      `${existing} already exists \u2014 refusing to overwrite without --force`\n    );\n  }\n  const yamlPath = writeTargetWorkersYamlPath();\n  const raw = readJsonStrict(jsonPath, jsonPath);\n  const workers = parseWorkersConfig(raw.workers);\n  const data: WorkersYamlData = {\n    active: workers.active,\n    providers: workers.providers,\n    classes: workers.classes,\n    capabilities: workers.capabilities,\n    mcpSets: workers.mcpSets,\n    nativeModels: workers.nativeModels,\n  };\n  const yamlText = buildWorkersYamlText(data);\n\n  if (opts.dryRun) {\n    return { yamlPath, yamlText, backupPath: null, dryRun: true };\n  }\n\n  writeWorkersYamlText(yamlPath, yamlText);\n\n  const stamp = new Date().toISOString().slice(0, 10);\n  const backupPath = join(dirname(jsonPath), `workers.json.migrated-${stamp}`);\n  writeFileSync(backupPath, JSON.stringify(raw.workers ?? {}, null, 2) + \"\\n\", \"utf8\");\n\n  const priorWorkers = (raw.workers as Record<string, unknown>) ?? {};\n  const { providers: _p, classes: _c, roles: _r, mcpSets: _m, active: _a, ...rest } = priorWorkers;\n  raw.workers = rest;\n  writeJsonAtomic(jsonPath, raw, { label: jsonPath });\n\n  return { yamlPath, yamlText, backupPath, dryRun: false };\n}\n\n/**\n * `pai worker config init`: write the literal commented starter (no data to\n * carry over \u2014 that is what `migrate` is for). Refuses if workers.yaml\n * already exists.\n */\nexport function initWorkersYaml(): string {\n  const existing = workersYamlPath();\n  if (existsSync(existing)) {\n    throw new WorkersConfigError(\n      `${existing} already exists \u2014 edit it directly, or run \\`pai worker config migrate --force\\` to regenerate it from the JSON config`\n    );\n  }\n  const yamlPath = writeTargetWorkersYamlPath();\n  writeWorkersYamlText(yamlPath, starterWorkersYamlText());\n  return yamlPath;\n}\n\n// ---------------------------------------------------------------------------\n// Relocating from an old location\n// ---------------------------------------------------------------------------\n\nexport type RelocateResult = MigrateFileResult;\n\n/** True when an old-location workers.yaml exists and nothing is at the new one yet. */\nexport function needsWorkersYamlRelocation(): boolean {\n  return (\n    !process.env.PAI_WORKERS_YAML &&\n    !existsSync(defaultWorkersYamlPath()) &&\n    [oldWorkersYamlPath(), legacyWorkersYamlPath()].some((p) => existsSync(p))\n  );\n}\n\n/**\n * `pai worker config migrate` when workers.yaml is still at an old location\n * (~/.claude/workers.yaml or, older still, ~/.config/pai/workers.yaml): a\n * byte-for-byte copy to the new path (comments, keys, everything \u2014 this only\n * changes where the file lives), verified, then the old file is renamed\n * aside as workers.yaml.migrated-<YYYYMMDD> (never deleted). No JSON\n * involved, and no secrets are read or transformed beyond copying bytes.\n */\nexport function relocateWorkersYaml(opts: { force?: boolean; dryRun?: boolean } = {}): RelocateResult {\n  const toPath = writeTargetWorkersYamlPath();\n  const result = migratePaiFile(toPath, [oldWorkersYamlPath(), legacyWorkersYamlPath()], opts);\n  if (!result.dryRun && result.fromPath) chmodSync(toPath, 0o600);\n  return result;\n}\n\n// ---------------------------------------------------------------------------\n// Inlining key_file contents as `key:`\n// ---------------------------------------------------------------------------\n\nexport interface InlineKeysResult {\n  yamlPath: string;\n  inlined: { provider: string; keyFilePath: string }[];\n  dryRun: boolean;\n}\n\n/**\n * `pai worker config inline-keys`: for every provider with a `key_file` and\n * no `key`, read the file, write its trimmed contents as a quoted `key:`,\n * and remove `key_file`. The key file itself is left on disk \u2014 this only\n * changes what workers.yaml reads from, never deletes a credential the\n * operator might still want. `dryRun` computes the plan (provider names and\n * key file paths only \u2014 never the key values) without writing anything.\n */\nexport function inlineWorkersYamlKeys(opts: { dryRun?: boolean } = {}): InlineKeysResult {\n  const yamlPath = workersYamlPath();\n  const existing = readWorkersYaml(yamlPath);\n  if (!existing) {\n    throw new WorkersConfigError(`${yamlPath} does not exist \u2014 run \\`pai worker config init\\` first`);\n  }\n  const { doc, data } = existing;\n  const inlined: { provider: string; keyFilePath: string }[] = [];\n  for (const [name, p] of Object.entries(data.providers)) {\n    if (p.key || !p.keyFile) continue;\n    const keyPath = expandHome(p.keyFile);\n    let content: string;\n    try {\n      content = readFileSync(keyPath, \"utf8\");\n    } catch (e) {\n      throw new WorkersConfigError(\n        `providers.${name}.key_file: could not read ${keyPath}: ${e instanceof Error ? e.message : String(e)}`\n      );\n    }\n    const token = content.trim();\n    if (!token) throw new WorkersConfigError(`providers.${name}.key_file: ${keyPath} is empty`);\n    inlined.push({ provider: name, keyFilePath: p.keyFile });\n    if (!opts.dryRun) {\n      doc.setIn([\"providers\", name, \"key\"], quotedKeyNode(token));\n      doc.deleteIn([\"providers\", name, \"key_file\"]);\n    }\n  }\n  if (!opts.dryRun && inlined.length) {\n    writeWorkersYamlText(yamlPath, String(doc));\n  }\n  return { yamlPath, inlined, dryRun: !!opts.dryRun };\n}\n", "/**\n * paths.ts \u2014 where worker run artefacts live.\n *\n * Everything a run writes (event mirror, status file, pane registry, routing\n * state, the empty MCP config) sits under one logDir so the whole tree is\n * disposable and configurable: `workers.logDir`, default ~/.claude/logs/workers.\n */\n\nimport { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { expandHome, DEFAULT_LOG_DIR, type WorkersConfig } from \"./config.js\";\nimport { paiHomePath, resolvePaiFile } from \"../config/pai-home.js\";\n\n/**\n * Absolute logDir for the given config. An explicit `logDir` in workers.yaml\n * is honored verbatim (the user chose it). Otherwise this resolves like every\n * other PAI_HOME file: PAI_HOME/logs/workers if it exists, else the old\n * ~/.claude/logs/workers (with a one-time notice), else the new path.\n */\nexport function workersLogDir(config: WorkersConfig): string {\n  const expanded = expandHome(config.logDir);\n  if (config.logDir !== DEFAULT_LOG_DIR) return expanded;\n  return resolvePaiFile(paiHomePath(\"logs\", \"workers\"), [expanded], \"pai config migrate --logs\");\n}\n\n/** The strict empty MCP config for headless runs, written on demand. */\nexport function ensureNoMcpConfig(logDir: string): string {\n  const path = noMcpConfigPath(logDir);\n  if (!existsSync(path)) {\n    mkdirSync(logDir, { recursive: true });\n    writeFileSync(path, '{ \"mcpServers\": {} }\\n', \"utf8\");\n  }\n  return path;\n}\n\nexport function statusPath(logDir: string, id: string): string {\n  return join(logDir, `${id}.status`);\n}\n\nexport function eventsPath(logDir: string, id: string): string {\n  return join(logDir, `${id}.jsonl`);\n}\n\nexport function ledgerPath(logDir: string): string {\n  return join(logDir, \"ledger.log\");\n}\n\nexport function routingStatePath(logDir: string): string {\n  return join(logDir, \"routing-state.json\");\n}\n\nexport function panesDir(logDir: string): string {\n  return join(logDir, \"panes\");\n}\n\n/**\n * The strict empty MCP config handed to headless workers. Written into the\n * logDir on demand (never into the user's vendor config directory \u2014 this is\n * PAI state, not vendor state).\n */\nexport function noMcpConfigPath(logDir: string): string {\n  return join(logDir, \"no-mcp.json\");\n}\n", "/**\n * Pending worker results: finished workers whose worktree branch still holds\n * work that never reached the repo (commits not in HEAD, or uncommitted\n * files). Surfaced by `pai worker ps/pending`, the SessionStart hook, the\n * status line and the prepublish gate so an unmerged fix cannot be forgotten.\n */\n\nimport { existsSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isLive, loadStatuses } from \"./status.js\";\nimport { statusPath } from \"./paths.js\";\nimport { git, uncommittedPaths } from \"./worktree.js\";\n\nexport interface PendingResult {\n  id: string;\n  label: string;\n  repo: string;\n  /** ms since the worker's status file last changed (its end). */\n  ageMs: number;\n  age: string;\n  /** commits on the branch not in the repo's HEAD (patch-id aware). */\n  commits: number;\n  /** uncommitted paths in the worktree, node_modules excluded. */\n  dirty: number;\n}\n\n/** Stale after this long: `pai worker gc` (archive) instead of merge. */\nexport const STALE_HOURS = 24;\n\nfunction toplevel(dir: string): string | null {\n  try {\n    return git(dir, [\"rev-parse\", \"--show-toplevel\"]);\n  } catch {\n    return null;\n  }\n}\n\nfunction fmtAge(ms: number): string {\n  const h = Math.floor(ms / 3_600_000);\n  return h >= 48 ? `${Math.floor(h / 24)}d` : h >= 1 ? `${h}h` : `${Math.floor(ms / 60_000)}m`;\n}\n\n/** Finished workers with unmerged work; `repoRoot` limits to one repo, else every repo. */\nexport function pendingResults(logDir: string, repoRoot?: string, now = Date.now()): PendingResult[] {\n  const want = repoRoot ? toplevel(repoRoot) : null;\n  if (repoRoot && !want) return [];\n  const out: PendingResult[] = [];\n  for (const st of loadStatuses(logDir)) {\n    if (st.archived || st.merged || isLive(st)) continue;\n    if (!st.worktreeDir || !existsSync(st.worktreeDir)) continue;\n    const repo = toplevel(st.cwd);\n    if (!repo || (want && repo !== want)) continue;\n    let commits = 0;\n    let dirty = 0;\n    try {\n      if (st.branch) {\n        commits = git(repo, [\"cherry\", \"HEAD\", `refs/heads/${st.branch}`])\n          .split(\"\\n\")\n          .filter((l) => l.startsWith(\"+\")).length;\n      }\n      dirty = uncommittedPaths(st.worktreeDir).filter((p) => !/(^|\\/)node_modules(\\/|$)/.test(p)).length;\n    } catch {\n      continue; // branch or worktree unreadable: nothing verifiable to report\n    }\n    if (!commits && !dirty) continue;\n    let ageMs = 0;\n    try {\n      ageMs = Math.max(0, now - statSync(statusPath(logDir, st.id)).mtimeMs);\n    } catch {\n      // status vanished mid-scan: age unknown, keep the entry\n    }\n    out.push({ id: st.id, label: st.label, repo, ageMs, age: fmtAge(ageMs), commits, dirty });\n  }\n  return out;\n}\n\n/** One human line per result, with the exact next command. */\nexport function formatPending(results: PendingResult[], showRepo = false): string {\n  return results\n    .map((r) => {\n      const next = r.ageMs > STALE_HOURS * 3_600_000 ? \"pai worker gc\" : `pai worker merge ${r.id}`;\n      const repo = showRepo ? `  ${r.repo}` : \"\";\n      return `${r.id}  ${r.age}  ${r.commits} commit(s), ${r.dirty} dirty  ${r.label}${repo}  -> ${next}`;\n    })\n    .join(\"\\n\");\n}\n\n/**\n * Release gate: exit code and message for `pai worker pending --gate`.\n * PAI_ALLOW_PENDING=1 overrides.\n */\nexport function pendingGate(\n  results: PendingResult[],\n  env: NodeJS.ProcessEnv = process.env\n): { code: number; message: string } {\n  if (!results.length || env.PAI_ALLOW_PENDING === \"1\") return { code: 0, message: \"\" };\n  return {\n    code: 1,\n    message:\n      `${results.length} unmerged worker result(s) in this repo \u2014 merge or discard before publishing:\\n` +\n      `${formatPending(results)}\\n` +\n      \"Override deliberately with PAI_ALLOW_PENDING=1.\",\n  };\n}\n\n/** Cached count of pending results for `cwd`'s repo (statusline/hook: cheap on repeat). */\nexport function pendingCountCached(logDir: string, cwd: string, ttlMs = 60_000, now = Date.now()): number {\n  const file = join(logDir, \"pending-cache.json\");\n  let cache: Record<string, { at: number; n: number }> = {};\n  try {\n    cache = JSON.parse(readFileSync(file, \"utf8\"));\n  } catch {\n    // no cache yet\n  }\n  const hit = cache[cwd];\n  if (hit && now - hit.at < ttlMs) return hit.n;\n  const n = pendingResults(logDir, cwd, now).length;\n  try {\n    writeFileSync(file, JSON.stringify({ ...cache, [cwd]: { at: now, n } }));\n  } catch {\n    // read-only log dir: recompute next time\n  }\n  return n;\n}\n", "/**\n * status.ts \u2014 the live per-worker status file.\n *\n * One JSON file per run, rewritten atomically on every turn, read by `ps`,\n * `follow`, the status line and the pane logic. Same field set the Python\n * runner wrote, plus `provider` (routing is multi-provider now) and `session`\n * (the AIBroker identity of the launching session, see scope.ts).\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport {\n  existsSync,\n  mkdirSync,\n  readFileSync,\n  readdirSync,\n  renameSync,\n  rmSync,\n  writeFileSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { shortText } from \"./args.js\";\nimport { statusPath } from \"./paths.js\";\n\nexport interface WorkerSessionRef {\n  /** AIBroker/iTerm session id (the iTerm UUID). */\n  id: string;\n  /** AIBroker name of that session, when it has one. */\n  name: string;\n}\n\nexport interface WorkerStatus {\n  id: string;\n  pid: number;\n  label: string;\n  cwd: string;\n  /** iTerm session id of the launching terminal (\"\" outside iTerm). */\n  term: string;\n  provider: string;\n  model: string;\n  state: \"running\" | \"done\" | \"failed\" | \"killed\" | \"lost\";\n  started: string;\n  updated: string;\n  turns: number;\n  tools: number;\n  last: string;\n  rc: number | null;\n  secs: number | null;\n  /** Launching session resolved through AIBroker, when it was. */\n  session?: WorkerSessionRef | null;\n  /** Claude Code session id (system/init) \u2014 what `resume` continues. */\n  claudeSession?: string | null;\n  /**\n   * Claude Code session id of the orchestrator whose Bash launched this run,\n   * when the status line's session map knew it (see scope.ts). Distinct from\n   * claudeSession, which is the run's own session.\n   */\n  spawnerSession?: string | null;\n  /** Context meter: tokens of the last assistant turn (input+cache+output). */\n  contextTokens?: number | null;\n  /** Context meter: window size (init model info or provider default). */\n  contextWindow?: number | null;\n  /** Path the prompt was read from via --spec (\"-\" for stdin), when it was. */\n  spec?: string | null;\n  /**\n   * Caller's --output-format, when the run was headless. A json/stream-json\n   * caller reads its own result and is notified on process exit by the\n   * harness \u2014 supervision.ts uses this to skip the duplicate relay send.\n   */\n  outputFormat?: \"text\" | \"json\" | \"stream-json\";\n  /** Chain this stage belongs to (the chain id), when it is a chain stage. */\n  parent?: string;\n  /** Class name of the chain stage (\"draft\", \"implement\", \u2026). */\n  stage?: string;\n  /** Worktree this run executed in, when it got one (see worktree.ts). */\n  worktreeDir?: string | null;\n  /** Branch the worker committed on (worker/<id>), set on worktree runs. */\n  branch?: string | null;\n  /** Commit the branch started from (worktree base) for the commits count. */\n  worktreeBase?: string | null;\n  /** Whether `worktreeBase` is a snapshot of uncommitted checkout state, not HEAD. */\n  worktreeSnapshot?: boolean | null;\n  /** Commits the worker made on its branch; set with `branch` on success. */\n  commits?: number | null;\n  /** Set by `pai worker merge` once the branch landed in the original checkout. */\n  merged?: boolean;\n  /** Set by `pai worker gc`: the hidden ref (refs/pai-archive/<id>) holding the leftover worktree's state. */\n  archived?: string | null;\n  /**\n   * How the run came to be: \"spawn\" (a `pai worker run` subagent) or \"chat\"\n   * (the terminal's interactive pane itself, tracked like a worker). Absent\n   * on statuses written before the flag existed \u2014 read as a spawn.\n   */\n  origin?: \"spawn\" | \"chat\";\n  /** Which contract/parser this run used for its final report (see report.ts). */\n  reportFormat?: \"json\" | \"ag2\";\n  /** Whether the final AG2 report passed `aibroker agentish check`; unset for json reports or when no validator ran. */\n  reportValid?: boolean;\n  /** Validation error messages, when reportValid is false. */\n  reportErrors?: string[];\n  /** Whether the headless prompt got the end-of-turn \"final message must be\u2026\" trailer line. */\n  promptTrailer?: boolean;\n  /** Whether an invalid AG2 final message triggered the one bounded re-ask (see run.ts). */\n  reportRetried?: boolean;\n  /**\n   * Consecutive failed tool executions in this run, maintained by the runner's\n   * stream loop (0 after any success). Absent on old status files \u2014 every\n   * reader must treat that as \"no signal\".\n   */\n  consecFails?: number | null;\n  /**\n   * Seconds of the most recent single long sleep observed in a Bash tool_use\n   * (see parseSleepSecs), cleared when the command completes. Absent on old\n   * status files.\n   */\n  sleepSec?: number | null;\n  /** Epoch ms the run is stopped at (deadline.ts); absent = no limit. */\n  deadlineAt?: number | null;\n  /** Limit in minutes the deadline was derived from. */\n  maxMinutes?: number | null;\n  /** The deadline stopped this run (state failed, `last` says why). */\n  timedOut?: boolean;\n  /** Launching process (the parent of `pai worker run`) at start, and its command name. */\n  parentPid?: number;\n  parentComm?: string;\n  parentBackground?: boolean;\n  /** Why the run ended (endreason.ts): exit, deadline, pai-worker-kill, parent-gone, external-signal. */\n  endReason?: string;\n  /** Who asked for the stop, when known (kill caller, daemon:<reason>). */\n  endBy?: string;\n  /** Detail for the reason (signal, sender note). */\n  endNote?: string;\n  /** Ever granted clickr desktop controls (see controls.ts) \u2014 the runner returns them best-effort on exit. */\n  controlsHeld?: boolean;\n}\n\n/** Label a worker gets when launched with neither --label nor a prompt. */\nexport const UNLABELED = \"unlabeled\";\n\n/**\n * Whether a status is the terminal's interactive chat pane, not a spawned\n * task worker. `origin` is the real discriminator; the fallback catches\n * running entries from before the flag existed (unlabeled, no turns yet).\n * Removable once every pane runs code that writes `origin`.\n */\nexport function isChatPane(s: Pick<WorkerStatus, \"origin\" | \"label\" | \"turns\">): boolean {\n  return (\n    s.origin === \"chat\" ||\n    (!s.origin && (s.label === UNLABELED || s.label === \"(no prompt)\") && s.turns === 0)\n  );\n}\n\n/** Context-meter percentage 0\u2013100, null when the numbers are missing. */\nexport function contextPercent(s: Pick<WorkerStatus, \"contextTokens\" | \"contextWindow\">): number | null {\n  if (!s.contextTokens || !s.contextWindow) return null;\n  return Math.round((s.contextTokens / s.contextWindow) * 100);\n}\n\n/** Compact token count: 84k, 200k, 900. */\nexport function fmtContextK(n: number): string {\n  return n >= 1000 ? `${Math.round(n / 1000)}k` : String(n);\n}\n\n/**\n * The one context-meter label, shared by every renderer so identical\n * numbers always render identically: `ctx 84k/200k (42%)` \u2014 used-style\n * percent. Empty when the numbers are missing (callers drop the part).\n */\nexport function contextLabel(\n  s: Pick<WorkerStatus, \"contextTokens\" | \"contextWindow\">\n): string {\n  const pct = contextPercent(s);\n  if (pct === null) return \"\";\n  return `ctx ${fmtContextK(s.contextTokens ?? 0)}/${fmtContextK(s.contextWindow ?? 0)} (${pct}%)`;\n}\n\n/** Timestamp format shared by status files and the ledger. */\nexport function nowStamp(d: Date = new Date()): string {\n  const p = (n: number) => String(n).padStart(2, \"0\");\n  return (\n    `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ` +\n    `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`\n  );\n}\n\n// second-resolution ids repeat when two workers/chains start together in one\n// process; a repeat gets a monotonic suffix so files never collide\nlet lastId = \"\";\nlet idSeq = 0;\n\nexport function newWorkerId(d: Date = new Date(), pid = process.pid): string {\n  const p = (n: number) => String(n).padStart(2, \"0\");\n  const base = `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}-${pid}`;\n  if (base === lastId) {\n    idSeq += 1;\n    return `${base}-${String(idSeq).padStart(2, \"0\")}`;\n  }\n  lastId = base;\n  idSeq = 0;\n  return base;\n}\n\n// Temp names must be unique per writer, not just per worker: two processes\n// legitimately write the same id at the same moment (`pai worker kill` marking\n// a run killed while the run's own SIGTERM handler writes its terminal state).\n// With one shared `<id>.status.tmp` they clobber each other's temp file and the\n// loser's rename fails with ENOENT \u2014 observed live on 2026-09-19.\nlet tmpSeq = 0;\n\n/** A temp path only this call owns \u2014 never the same string twice. */\nexport function statusTmpPath(logDir: string, id: string): string {\n  return `${statusPath(logDir, id)}.${process.pid}.${tmpSeq++}.tmp`;\n}\n\n// The label this process first wrote for a given worker id: run.ts holds one\n// unchanging label in memory for the whole run and passes it to every\n// periodic saveStatus call, so a later call whose label still equals this\n// baseline is that unmodified write, never an intentional change \u2014 on-disk\n// then wins, so an external `pai worker goal` relabel between two of a\n// worker's own writes survives instead of being reverted by the next one. A\n// call whose label differs from the baseline (or the first call for an id in\n// this process, which has no baseline yet) IS the intentional change and\n// always wins \u2014 exactly the one-shot `pai worker goal` process itself.\nconst firstWrittenLabel = new Map<string, string>();\n\n/** Write status atomically (temp + rename) and stamp `updated`. */\nexport function saveStatus(logDir: string, status: WorkerStatus, d: Date = new Date()): void {\n  status.updated = nowStamp(d);\n  const path = statusPath(logDir, status.id);\n  const baseline = firstWrittenLabel.get(status.id);\n  if (baseline === undefined) {\n    firstWrittenLabel.set(status.id, status.label);\n  }\n  const onDisk = baseline === undefined ? undefined : loadStatus(logDir, status.id);\n  if (onDisk) {\n    if (status.label === baseline && onDisk.label !== status.label) status.label = onDisk.label;\n    // Set by another process (`pai worker controls`); a true flag is never dropped by a stale in-memory copy.\n    if (onDisk.controlsHeld) status.controlsHeld = true;\n  }\n  const tmp = statusTmpPath(logDir, status.id);\n  if (!existsSync(logDir)) mkdirSync(logDir, { recursive: true });\n  try {\n    writeFileSync(tmp, JSON.stringify(status), \"utf8\");\n    renameSync(tmp, path);\n  } catch (e) {\n    try {\n      rmSync(tmp, { force: true });\n    } catch {\n      // nothing to clean up\n    }\n    throw e;\n  }\n}\n\n/**\n * Set a worker's goal (the operator's `--label`), atomically, through the\n * same saveStatus path everything else writes with. Used by `pai worker\n * goal` and the `--goal` option of `say`: a fresh call in a fresh process, so\n * it always carries no baseline yet and always wins over the worker's own\n * next periodic write (see saveStatus above).\n */\nexport function setWorkerLabel(logDir: string, id: string, label: string): WorkerStatus {\n  const status = loadStatus(logDir, id);\n  if (!status) throw new Error(`no worker named \"${id}\"`);\n  status.label = label;\n  saveStatus(logDir, status);\n  return status;\n}\n\n/** Load every status file in the logDir, oldest id first, skipping damage. */\nexport function loadStatuses(logDir: string): WorkerStatus[] {\n  if (!existsSync(logDir)) return [];\n  const out: WorkerStatus[] = [];\n  for (const name of readdirSync(logDir).sort()) {\n    if (!name.endsWith(\".status\")) continue;\n    try {\n      out.push(JSON.parse(readFileSync(join(logDir, name), \"utf8\")) as WorkerStatus);\n    } catch {\n      // a half-written or damaged status file is not worth a crash\n    }\n  }\n  return out;\n}\n\nexport function loadStatus(logDir: string, id: string): WorkerStatus | null {\n  const path = statusPath(logDir, id);\n  if (!existsSync(path)) return null;\n  try {\n    return JSON.parse(readFileSync(path, \"utf8\")) as WorkerStatus;\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Wait for a worker to record its own terminal state (the run's signal\n * handler writes killed/rc/secs). Returns that status, or null when it is\n * still \"running\" after `timeoutMs` \u2014 the caller then writes the state itself.\n */\nexport async function waitForTerminalStatus(\n  logDir: string,\n  id: string,\n  timeoutMs = 2000,\n  stepMs = 50\n): Promise<WorkerStatus | null> {\n  const deadline = Date.now() + timeoutMs;\n  for (;;) {\n    const s = loadStatus(logDir, id);\n    if (s && s.state !== \"running\") return s;\n    if (Date.now() >= deadline) return null;\n    await new Promise((r) => setTimeout(r, stepMs));\n  }\n}\n\nexport function alive(pid: number | null | undefined): boolean {\n  if (!pid || pid <= 0) return false;\n  try {\n    process.kill(pid, 0);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Whether `status.pid` still names the process that was started as this\n * worker, not a later, unrelated process the OS handed the same pid to after\n * the worker exited. `alive()` alone can't tell these apart \u2014 a pid observed\n * live on 2026-09-19 (worker 20260919-083549-90913) had been reused, and\n * `pai worker kill` signalled the wrong, unrelated process. `ps -o lstart=`\n * reads the running process's actual start time and compares it against the\n * status file's own `started` stamp; a reused pid almost never starts within\n * 120s of the original, so a wider drift means \"different process\".\n */\nexport function ownsPid(status: Pick<WorkerStatus, \"pid\" | \"started\">): boolean {\n  if (status.pid <= 0 || !alive(status.pid)) return false;\n  try {\n    const out = execFileSync(\"ps\", [\"-o\", \"lstart=\", \"-p\", String(status.pid)], {\n      encoding: \"utf8\",\n      env: { ...process.env, LC_ALL: \"C\" },\n    }).trim();\n    const psStart = Date.parse(out);\n    const started = Date.parse(status.started.replace(\" \", \"T\"));\n    if (Number.isNaN(psStart) || Number.isNaN(started)) return alive(status.pid);\n    return Math.abs(psStart - started) <= 120_000;\n  } catch {\n    // pid exited between the alive() check and the ps call, or ps failed for\n    // another reason \u2014 the pid-existence check is still better than nothing.\n    return alive(status.pid);\n  }\n}\n\n/** Whether a status is both marked \"running\" and still owns its recorded pid. */\nexport function isLive(status: Pick<WorkerStatus, \"pid\" | \"started\" | \"state\">): boolean {\n  return status.state === \"running\" && ownsPid(status);\n}\n\n/** \"42s\" under 90s, \"7m\" above \u2014 the coarse age the table and bar show. */\nexport function ageOf(ts: string, now: Date = new Date()): string {\n  const t = Date.parse(ts.replace(\" \", \"T\"));\n  if (Number.isNaN(t)) return \"?\";\n  const s = Math.max(0, Math.floor((now.getTime() - t) / 1000));\n  return s < 90 ? `${s}s` : `${Math.floor(s / 60)}m`;\n}\n\n/** Precise elapsed time: \"45s\", \"1m 23s\", \"12m 05s\", \"1h 02m 05s\" \u2014 seconds zero-padded after a larger unit. */\nexport function elapsedOf(ts: string, now: Date = new Date()): string {\n  const t = Date.parse(ts.replace(\" \", \"T\"));\n  if (Number.isNaN(t)) return \"?\";\n  const secs = Math.max(0, Math.floor((now.getTime() - t) / 1000));\n  const hours = Math.floor(secs / 3600);\n  const mins = Math.floor((secs % 3600) / 60);\n  const sec = secs % 60;\n  if (hours > 0) return `${hours}h ${String(mins).padStart(2, \"0\")}m ${String(sec).padStart(2, \"0\")}s`;\n  if (mins > 0) return `${mins}m ${String(sec).padStart(2, \"0\")}s`;\n  return `${sec}s`;\n}\n\n/** Shorter sleeps are legitimate polling \u2014 not worth a supervision event. */\nexport const SLEEP_FLOOR_SECS = 60;\n\nconst SLEEP_RE = /^\\s*sleep\\s+([0-9]+(?:\\.[0-9]+)?)([smhd]?)\\s*(?:$|[;&|])/;\n\n/** s/m/h/d suffix to seconds multiplier, shared by every `sleep N<unit>` parse below. */\nfunction sleepUnitMultiplier(unit: string): number {\n  return unit === \"m\" ? 60 : unit === \"h\" ? 3600 : unit === \"d\" ? 86_400 : 1;\n}\n\n/**\n * Seconds of a `sleep N` (N plain or with an s/m/h/d suffix) that stands alone\n * or leads a compound command (`sleep 150; cat f`, `sleep 2m && tail f`,\n * `sleep 90 || true`, `sleep 60 &`), or null when no long sleep leads: anchored\n * to the start of the command, so a filename containing \"sleep\" or an\n * `echo sleep 500` never trips it, and floored at SLEEP_FLOOR_SECS so ordinary\n * polling stays invisible.\n */\nexport function parseSleepSecs(command: string): number | null {\n  const m = command.match(SLEEP_RE);\n  if (!m) return null;\n  const secs = Number(m[1]) * sleepUnitMultiplier(m[2]);\n  return Number.isFinite(secs) && secs >= SLEEP_FLOOR_SECS ? secs : null;\n}\n\n/**\n * Every command-segment boundary a shell recognises before a new simple\n * command can start: the very start of the string, `;`, `&`/`&&`, `|`/`||`,\n * a newline, an opening `(` or `{` (also covers `$(...)`, which ends in `(`),\n * or the keywords `do`/`then`. Segment end is the mirror image plus a closing\n * `)`, so `sleep 90` inside `$(sleep 90)` or `(sleep 90)` still counts.\n */\n// The terminator is a lookahead, not a consumed match: two sleeps sharing one\n// separator (`sleep 65; sleep 590`) both need that `;` available as their own\n// boundary \u2014 matchAll never revisits a character a previous match consumed.\nconst SLEEP_SEGMENT_RE =\n  /(?:^|[;&|\\n(){]|\\bdo\\b|\\bthen\\b)\\s*sleep\\s+([0-9]+(?:\\.[0-9]+)?)([smhd]?)(?=\\s*(?:$|[;&|)\\n]))/g;\n\n/**\n * The longest `sleep N` found as its OWN command segment anywhere in\n * `command` \u2014 not just leading it, unlike {@link parseSleepSecs} \u2014 or null\n * when none reaches SLEEP_FLOOR_SECS. Used by the PreToolUse Bash gate\n * (block-sleep-poll.ts), which must catch a sleep buried after `&&`, inside a\n * `do ... done` loop, or in a subshell, not only one that leads the command.\n */\nexport function longestSleepSecs(command: string): number | null {\n  let longest: number | null = null;\n  for (const m of command.matchAll(SLEEP_SEGMENT_RE)) {\n    const secs = Number(m[1]) * sleepUnitMultiplier(m[2]);\n    if (!Number.isFinite(secs) || secs < SLEEP_FLOOR_SECS) continue;\n    if (longest === null || secs > longest) longest = secs;\n  }\n  return longest;\n}\n\nconst LOOP_RE = /\\b(for|while|until)\\b([^;\\n]*)[;\\n]\\s*do\\b([\\s\\S]*?)\\bdone\\b/g;\n\nfunction sleepSum(text: string): number {\n  let sum = 0;\n  for (const m of text.matchAll(SLEEP_SEGMENT_RE)) {\n    const secs = Number(m[1]) * sleepUnitMultiplier(m[2]);\n    if (Number.isFinite(secs)) sum += secs;\n  }\n  return sum;\n}\n\n/** Iterations of a `for x in <words>` header, or null when not provably small. */\nfunction forIterations(header: string): number | null {\n  const words = header.replace(/^\\s*\\w+\\s+in\\s+/, \"\").trim();\n  if (words === header.trim() || /[$`*?]/.test(words)) return null;\n  const range = /^\\{(-?\\d+)\\.\\.(-?\\d+)\\}$/.exec(words);\n  if (range) return Math.abs(Number(range[2]) - Number(range[1])) + 1;\n  return words ? words.split(/\\s+/).length : 0;\n}\n\n/**\n * Total sleep of one Bash command: every `sleep N` segment counted once, plus\n * loop repetition \u2014 `for x in a b c` multiplies its body by the word count;\n * `while`/`until` and any unbounded `for` count as at least SLEEP_FLOOR_SECS,\n * except a `kill -0` job-wait (the sanctioned wait-for-a-job loop). Used by\n * the PreToolUse gate so `sleep 58; sleep 58` is caught as the 116 s it is.\n */\n// ponytail: loops are not nested-aware (body ends at the first `done`); upgrade to a real shell parse if that bites.\nexport function totalSleepSecs(command: string): number {\n  let total = sleepSum(command);\n  for (const m of command.matchAll(LOOP_RE)) {\n    const body = sleepSum(m[3]);\n    if (body === 0) continue;\n    if (m[1] === \"for\") {\n      const n = forIterations(m[2]);\n      total += n === null ? Math.max(SLEEP_FLOOR_SECS, body) : body * (n - 1);\n    } else if (!/\\bkill\\s+-0\\b/.test(m[2])) {\n      total += SLEEP_FLOOR_SECS;\n    }\n  }\n  return total;\n}\n\n/** One-line description of a tool call, e.g. \"Bash: npm test\". */\nexport function describeTool(name: string, inp: unknown): string {\n  if (typeof inp !== \"object\" || inp === null) return name;\n  const i = inp as Record<string, unknown>;\n  const get = (k: string) => (typeof i[k] === \"string\" ? (i[k] as string) : \"\");\n  if (name === \"Bash\") return `Bash: ${shortText(get(\"command\"), 70)}`;\n  if (name === \"Read\" || name === \"Edit\" || name === \"Write\" || name === \"MultiEdit\") {\n    const file = get(\"file_path\").split(\"/\").pop() ?? \"\";\n    return `${name}: ${file}`;\n  }\n  if (name === \"Grep\" || name === \"Glob\") return `${name}: ${shortText(get(\"pattern\"), 50)}`;\n  if (name === \"WebSearch\") return `${name}: ${shortText(get(\"query\"), 50)}`;\n  if (name === \"WebFetch\") return `${name}: ${shortText(get(\"url\"), 60)}`;\n  return name;\n}\n", "/**\n * worktree.ts \u2014 one git worktree per writing worker.\n *\n * A run whose class edits files (implement, complex, plan) and whose cwd is a\n * git repository gets its own worktree by default: `git worktree add\n * <logDir>/worktrees/<id> -b worker/<id>` from the current HEAD. The worker\n * commits its own work on that branch \u2014 the no-commit rule applies to the\n * main branch only \u2014 and the parent (or the operator) merges the result back:\n *\n *   pai worker merge <id>     git merge --no-ff worker/<id> + remove worktree + delete branch\n *   pai worker discard <id>   remove worktree and branch, keep nothing\n *\n * `ps` marks a worker with an unmerged branch `\u2387`. Draft and review run in\n * place; `--no-worktree` opts out, `--worktree` forces one on.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { existsSync, lstatSync, mkdirSync, readFileSync, mkdtempSync, writeFileSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve, sep } from \"node:path\";\nimport { tmpdir, platform } from \"node:os\";\nimport { isLive, loadStatus, loadStatuses, saveStatus, UNLABELED, type WorkerStatus } from \"./status.js\";\nimport { appendLedger } from \"./ledger.js\";\nimport { ledgerPath, statusPath } from \"./paths.js\";\n\nexport function worktreesDir(logDir: string): string {\n  return join(logDir, \"worktrees\");\n}\n\nexport function worktreeBranch(id: string): string {\n  return `worker/${id}`;\n}\n\nexport function worktreePath(logDir: string, id: string): string {\n  return join(worktreesDir(logDir), id);\n}\n\n/** Run git in `cwd` with an optional env override, trimmed stdout, stderr on failure. */\nfunction runGit(cwd: string, args: string[], env?: NodeJS.ProcessEnv, timeout = 30_000): string {\n  try {\n    return execFileSync(\"git\", [\"-C\", cwd, ...args], {\n      encoding: \"utf8\",\n      timeout,\n      stdio: [\"ignore\", \"pipe\", \"pipe\"],\n      ...(env ? { env } : {}),\n    }).trim();\n  } catch (e) {\n    const err = e as { stderr?: Buffer | string; message?: string };\n    const why =\n      (typeof err.stderr === \"string\" ? err.stderr : err.stderr?.toString(\"utf8\")) ||\n      err.message ||\n      String(e);\n    throw new Error(`git ${args.join(\" \")} in ${cwd}: ${why.trim()}`);\n  }\n}\n\n/** Run git in `cwd`, returning trimmed stdout; throws with stderr on failure. */\nexport function git(cwd: string, args: string[], timeoutMs?: number): string {\n  return runGit(cwd, args, undefined, timeoutMs);\n}\n\n/** Is `cwd` inside a git repository (a .git dir \u2014 worktrees: a .git file)? */\nexport function isGitRepo(cwd: string): boolean {\n  try {\n    return git(cwd, [\"rev-parse\", \"--git-dir\"]) !== \"\";\n  } catch {\n    return false;\n  }\n}\n\n/** Tools that can write to the checkout (Bash can, via the shell). */\nconst WRITING_TOOLS = [\"Edit\", \"Write\", \"MultiEdit\", \"NotebookEdit\", \"Bash\"];\n\n/** Can a run with these --allowedTools write? No restriction at all means yes. */\nexport function toolsCanWrite(allowedTools: string[]): boolean {\n  const names = allowedTools.flatMap((e) => e.split(\",\")).map((s) => s.trim().replace(/\\(.*$/, \"\")).filter(Boolean);\n  return !names.length || names.some((n) => WRITING_TOOLS.includes(n));\n}\n\n/** How the run flags decide the worktree question; undefined = decide by default. */\nexport type WorktreeFlag = boolean | undefined;\n\n/** Should this run get a worktree? Explicit flag first, then: can it write? */\nexport function worktreeWanted(flag: WorktreeFlag, opts: { cwd: string; allowedTools: string[] }): boolean {\n  if (flag !== undefined) return flag;\n  return toolsCanWrite(opts.allowedTools) && isGitRepo(opts.cwd);\n}\n\nexport interface WorktreeInfo {\n  dir: string;\n  branch: string;\n  base: string;\n  /** `base` is a snapshot commit of uncommitted checkout state, not HEAD itself. */\n  snapshot: boolean;\n}\n\n/**\n * Commit `cwd`'s current index + working tree (including untracked files) as\n * a floating commit on top of HEAD, without touching the real index, working\n * tree or HEAD: a temporary `GIT_INDEX_FILE` collects the snapshot, `git\n * commit-tree` writes the commit object directly (it updates no ref). The\n * caller then branches a worktree from that commit, so the worktree sees\n * exactly what was on disk, uncommitted or not.\n */\nfunction snapshotUncommitted(cwd: string, id: string, head: string): string {\n  const idxDir = mkdtempSync(join(tmpdir(), \"pai-worktree-idx-\"));\n  const idx = join(idxDir, \"index\");\n  try {\n    const env = { ...process.env, GIT_INDEX_FILE: idx };\n    runGit(cwd, [\"read-tree\", head], env);\n    runGit(cwd, [\"add\", \"-A\"], env);\n    const tree = runGit(cwd, [\"write-tree\"], env);\n    return runGit(cwd, [\n      \"commit-tree\",\n      tree,\n      \"-p\",\n      head,\n      \"-m\",\n      `worker ${id}: snapshot of uncommitted checkout`,\n    ]);\n  } finally {\n    rmSync(idxDir, { recursive: true, force: true });\n  }\n}\n\n/**\n * Create the worktree and branch for `id` from `cwd`'s HEAD \u2014 or, when the\n * checkout has uncommitted changes, from a snapshot commit of that dirty\n * state (see `snapshotUncommitted`), so a worktree worker sees the same\n * files the operator sees, not just what was last committed. Throws when git\n * refuses (no commits yet, branch exists, \u2026) \u2014 the caller decides whether to\n * degrade to an in-place run.\n */\nexport function addWorktree(logDir: string, id: string, cwd: string): WorktreeInfo {\n  const dir = worktreePath(logDir, id);\n  const branch = worktreeBranch(id);\n  const head = git(cwd, [\"rev-parse\", \"HEAD\"]);\n  const dirty = dirtyPaths(cwd).length > 0;\n  const base = dirty ? snapshotUncommitted(cwd, id, head) : head;\n  git(cwd, [\"worktree\", \"add\", dir, \"-b\", branch, base]);\n  provisionDeps(logDir, id, cwd, dir);\n  return { dir, branch, base, snapshot: dirty };\n}\n\n/**\n * Give the worktree its own dependencies so the worker never has to improvise\n * (symlinking node_modules to the main checkout, building in a /tmp copy).\n * A real node_modules directory in the main checkout is APFS-cloned\n * (`cp -c`, copy-on-write, near instant); elsewhere the lockfile installs it.\n * Never a symlink. Time-boxed and best effort: a failure is logged, the run\n * goes on.\n */\nexport function provisionDeps(logDir: string, id: string, cwd: string, wtDir: string): void {\n  const note = (n: string) => appendLedger(ledgerPath(logDir), \"WORKER-NOTE\", { id, note: n });\n  try {\n    const root = git(cwd, [\"rev-parse\", \"--show-toplevel\"]);\n    const main = join(root, \"node_modules\");\n    const dest = join(wtDir, \"node_modules\");\n    if (!existsSync(main) || lstatSync(main).isSymbolicLink() || existsSync(dest)) return;\n    try {\n      // an unignored node_modules would be committed by salvage\n      git(wtDir, [\"check-ignore\", \"-q\", \"node_modules\"]);\n    } catch {\n      return;\n    }\n    const t0 = Date.now();\n    const opts = { cwd: wtDir, stdio: \"ignore\" as const, timeout: 180_000 };\n    if (platform() === \"darwin\") {\n      try {\n        execFileSync(\"cp\", [\"-cR\", main, dest], opts);\n        note(`node_modules cloned (apfs) in ${Date.now() - t0}ms`);\n        return;\n      } catch {\n        rmSync(dest, { recursive: true, force: true }); // half-copied\n      }\n    }\n    if (existsSync(join(wtDir, \"bun.lock\"))) execFileSync(\"bun\", [\"install\", \"--frozen-lockfile\"], opts);\n    else if (existsSync(join(wtDir, \"package-lock.json\"))) execFileSync(\"npm\", [\"ci\"], opts);\n    else return;\n    note(`node_modules installed from lockfile in ${Date.now() - t0}ms`);\n  } catch (e) {\n    try {\n      note(`node_modules provisioning failed: ${(e as Error).message}`);\n    } catch {\n      /* ledger is best effort too */\n    }\n  }\n}\n\n/** Commits the branch collected on top of its base. */\nexport function commitsSince(dir: string, base: string): number {\n  try {\n    return parseInt(git(dir, [\"rev-list\", \"--count\", `${base}..HEAD`]), 10) || 0;\n  } catch {\n    return 0;\n  }\n}\n\n/**\n * Record the worktree result in the status file: branch and commit count on\n * success, the worktree cleaned up on failure. Returns the updated status.\n */\nexport function recordWorktree(\n  logDir: string,\n  status: WorkerStatus,\n  info: WorktreeInfo,\n  ok: boolean\n): WorkerStatus {\n  const s = { ...status };\n  if (ok) {\n    s.branch = info.branch;\n    s.commits = commitsSince(info.dir, info.base);\n    s.worktreeDir = info.dir;\n    s.worktreeBase = info.base;\n    s.worktreeSnapshot = info.snapshot;\n  } else if (safeCommitsSince(info.dir, info.base) > 0) {\n    // a failed or killed run that committed (or was salvaged) keeps its work:\n    // branch and worktree stay for `pai worker merge` / `discard`\n    s.branch = info.branch;\n    s.commits = commitsSince(info.dir, info.base);\n    s.worktreeDir = info.dir;\n    s.worktreeBase = info.base;\n    s.worktreeSnapshot = info.snapshot;\n  } else {\n    // a failed run with no commits leaves nothing to merge; the branch dies with the worktree\n    removeWorktree(s.cwd, info.dir, true);\n    try {\n      git(s.cwd, [\"branch\", \"-D\", info.branch]);\n    } catch {\n      // already gone or never created\n    }\n    s.branch = null;\n    s.worktreeDir = null;\n    s.worktreeBase = null;\n    s.commits = null;\n    s.worktreeSnapshot = null;\n  }\n  saveStatus(logDir, s);\n  return s;\n}\n\nfunction safeCommitsSince(dir: string, base: string): number {\n  try {\n    return commitsSince(dir, base);\n  } catch {\n    return 0;\n  }\n}\n\n/**\n * Salvage for an exit path (run finaliser, kill signal): commit whatever the\n * worker left uncommitted, log WORKER-SALVAGE, never throw. Bounded by\n * `timeoutMs` per git call. Returns the committed paths.\n */\nexport function salvageOnExit(\n  ledger: string,\n  id: string,\n  label: string,\n  wtDir: string,\n  timeoutMs?: number\n): string[] {\n  try {\n    const { committed, skipped } = salvageUncommitted(wtDir, label, timeoutMs);\n    if (committed.length) appendLedger(ledger, \"WORKER-SALVAGE\", { id, paths: committed.join(\",\"), skipped: skipped.length });\n    if (skipped.length) appendLedger(ledger, \"WORKER-NOTE\", { id, note: `salvage skipped: ${skipped.join(\"; \")}` });\n    return committed;\n  } catch (e) {\n    try {\n      appendLedger(ledger, \"WORKER-NOTE\", { id, note: `salvage failed: ${(e as Error).message}` });\n    } catch {\n      /* best effort */\n    }\n    return [];\n  }\n}\n\n/** Remove a worktree directory from git's books and the filesystem. */\nfunction removeWorktree(cwd: string, dir: string, force: boolean): void {\n  try {\n    git(cwd, [\"worktree\", \"remove\", ...(force ? [\"--force\"] : []), dir]);\n    return;\n  } catch {\n    // fall through to the manual cleanup\n  }\n  if (existsSync(dir)) {\n    try {\n      rmSync(dir, { recursive: true, force: true });\n      git(cwd, [\"worktree\", \"prune\"]);\n    } catch {\n      // best effort: a leftover directory is visible in the logDir\n    }\n  }\n}\n\n/**\n * Tracked changes (staged or not) plus untracked files \u2014 everything a\n * `git add -A` in `wtDir` would commit. The same two calls the old patch\n * carry used; name-only, not porcelain: a worktree-only change renders as\n * \" M path\" and the shared git() helper trims that leading space away.\n */\nexport function uncommittedPaths(wtDir: string, timeoutMs?: number): string[] {\n  const tracked = git(wtDir, [\"diff\", \"--name-only\", \"HEAD\"], timeoutMs).split(\"\\n\").filter(Boolean);\n  const untracked = git(wtDir, [\"ls-files\", \"--others\", \"--exclude-standard\"], timeoutMs)\n    .split(\"\\n\")\n    .filter(Boolean);\n  return [...tracked, ...untracked];\n}\n\n/**\n * True when `wtDir`/`relPath` is a symlink whose target resolves outside\n * `wtDir` \u2014 e.g. a worker's `node_modules -> <main checkout>/node_modules`\n * convenience link. A `.gitignore` using `dir/` (directories only) does not\n * ignore such a link, so it turns up as untracked; staging and merging it\n * lets git replace the real directory on the other side with a symlink to\n * itself. Never a candidate for salvage.\n */\nfunction symlinkEscapesWorktree(wtDir: string, relPath: string): boolean {\n  const full = join(wtDir, relPath);\n  let stat;\n  try {\n    stat = lstatSync(full);\n  } catch {\n    return false; // vanished; nothing to skip\n  }\n  if (!stat.isSymbolicLink()) return false;\n  const target = readlinkSync(full);\n  const resolvedTarget = isAbsolute(target) ? target : resolve(dirname(full), target);\n  const realTarget = existsSync(resolvedTarget) ? realpathSync(resolvedTarget) : resolvedTarget;\n  const realWtDir = realpathSync(wtDir);\n  return realTarget !== realWtDir && !realTarget.startsWith(realWtDir + sep);\n}\n\nexport interface SalvageResult {\n  /** Paths committed onto the branch. */\n  committed: string[];\n  /** Human-readable notes for paths left on disk, uncommitted, and why. */\n  skipped: string[];\n}\n\n/**\n * Commit a worktree's uncommitted changes to its branch so the merge carries\n * them. `git merge` only moves committed work, so a worker that stopped\n * without committing would lose its edits to `worktree remove` \u2014 exactly\n * what happened live on 2026-09-17. Returns the salvaged paths, empty when\n * the worktree is clean. A symlink pointing outside the worktree (see\n * `symlinkEscapesWorktree`) is never staged; it is left on disk and reported\n * as skipped instead. A failed commit throws with the worktree untouched:\n * its edits are still on disk, so nothing is lost.\n */\nexport function salvageUncommitted(wtDir: string, label: string, timeoutMs?: number): SalvageResult {\n  const paths = uncommittedPaths(wtDir, timeoutMs);\n  if (!paths.length) return { committed: [], skipped: [] };\n  const skipped: string[] = [];\n  // tracked files gone from disk but not staged for removal: the worker never\n  // ran `git rm`, so the absence is not its decision (see MAX_SALVAGE_DELETES)\n  const missing = new Set(git(wtDir, [\"ls-files\", \"--deleted\"], timeoutMs).split(\"\\n\").filter(Boolean));\n  const toStage: string[] = [];\n  for (const p of paths) {\n    if (missing.has(p)) {\n      skipped.push(`${p} (missing, not committed)`);\n    } else if (symlinkEscapesWorktree(wtDir, p)) {\n      skipped.push(`symlink ${p} -> ${readlinkSync(join(wtDir, p))} (points outside the worktree)`);\n    } else {\n      toStage.push(p);\n    }\n  }\n  if (!toStage.length) return { committed: [], skipped };\n  try {\n    // --ignore-removal: additions and modifications only. Deletions the worker\n    // staged itself (git rm) are already in the index and ride along.\n    const excludes = paths.filter((p) => !toStage.includes(p)).map((p) => `:(exclude,literal)${p}`);\n    git(wtDir, [\"add\", \"--ignore-removal\", \"--\", \".\", ...excludes], timeoutMs);\n    const deleted = git(wtDir, [\"diff\", \"--cached\", \"--diff-filter=D\", \"--name-only\"], timeoutMs).split(\"\\n\").filter(Boolean);\n    if (deleted.length > MAX_SALVAGE_DELETES) {\n      git(wtDir, [\"reset\", \"-q\"], timeoutMs);\n      throw new Error(`salvage would delete ${deleted.length} tracked files (${deleted.slice(0, 5).join(\", \")}, ...), refused`);\n    }\n    git(wtDir, [\"commit\", \"-m\", `salvaged: ${label}`], timeoutMs);\n  } catch (e) {\n    throw new Error(\n      `cannot salvage the uncommitted changes in ${wtDir} \u2014 ${(e as Error).message}; ` +\n        `nothing was lost: commit them there by hand, then re-run merge`\n    );\n  }\n  return { committed: toStage, skipped };\n}\n\n/** A salvage commit that deletes more tracked files than this is refused. */\nconst MAX_SALVAGE_DELETES = 5;\n\n/**\n * The dirty paths of a checkout, parsed from `git status --porcelain -z`:\n * NUL-separated (a path with a newline in it cannot corrupt the parse),\n * rename entries contribute both sides, and any quoting is stripped.\n */\nfunction dirtyPaths(cwd: string): string[] {\n  // raw execFileSync, not the shared git(): it trims stdout, which eats the\n  // leading space of a worktree-only \" M path\" record and breaks the parse\n  const raw = execFileSync(\"git\", [\"-C\", cwd, \"status\", \"--porcelain\", \"-z\"], {\n    encoding: \"utf8\",\n    timeout: 30_000,\n    stdio: [\"ignore\", \"pipe\", \"pipe\"],\n  });\n  const fields = raw.split(\"\\0\");\n  const strip = (p: string) => (p.startsWith('\"') && p.endsWith('\"') ? p.slice(1, -1) : p);\n  const out: string[] = [];\n  for (let i = 0; i < fields.length; i++) {\n    const f = fields[i];\n    if (!f || f.length < 4 || f.charAt(2) !== \" \") continue; // not an \"XY path\" record\n    out.push(strip(f.slice(3)));\n    const xy = f.slice(0, 2);\n    if (xy.includes(\"R\") || xy.includes(\"C\")) {\n      const orig = fields[i + 1]; // rename/copy records carry the source path next\n      if (orig && orig.charAt(2) !== \" \") {\n        out.push(strip(orig));\n        i += 1;\n      }\n    }\n  }\n  return out;\n}\n\n/**\n * Refuse the merge when the original checkout is dirty in paths the branch\n * touches: the merge would overwrite those edits or fail on them, either way\n * leaving a half-state. No merge is made, the worktree stays.\n */\nfunction assertNoDirtyOverlap(\n  cwd: string,\n  incoming: string[],\n  id: string,\n  branch: string\n): void {\n  const dirty = new Set(dirtyPaths(cwd));\n  const overlap = [...new Set(incoming)].filter((p) => dirty.has(p)).sort();\n  if (!overlap.length) return;\n  throw new Error(\n    `worker ${id}: the checkout ${cwd} has uncommitted changes in paths ${branch} touches: ` +\n      `${overlap.join(\", \")}. Commit or stash them in the checkout, then re-run: pai worker merge ${id}. ` +\n      `No merge was made; the worktree was kept.`\n  );\n}\n\n/**\n * Never remove a worktree that still holds uncommitted changes \u2014 except a\n * symlink escaping the worktree (see `symlinkEscapesWorktree`): it was\n * deliberately left uncommitted by `salvageUncommitted`, and deleting the\n * link itself touches nothing outside the worktree.\n */\nexport function assertWorktreeClean(wtDir: string, id: string): void {\n  const leftover = uncommittedPaths(wtDir).filter((p) => !symlinkEscapesWorktree(wtDir, p));\n  if (leftover.length) {\n    throw new Error(\n      `worker ${id}: the worktree ${wtDir} still holds uncommitted changes ` +\n        `(${leftover.join(\", \")}) \u2014 it was NOT removed; commit or copy them by hand, then re-run merge`\n    );\n  }\n}\n\n/** Blob sha of `path` at `rev` in `cwd`, or null when it does not exist there. */\nfunction blobAt(cwd: string, rev: string, path: string): string | null {\n  try {\n    return git(cwd, [\"rev-parse\", \"--verify\", \"-q\", `${rev}:${path}`]);\n  } catch {\n    return null;\n  }\n}\n\n/** Blob sha of `path` as it sits on disk in `cwd`, or null when it is absent. */\nfunction workingBlob(cwd: string, path: string): string | null {\n  if (!existsSync(join(cwd, path))) return null;\n  try {\n    return git(cwd, [\"hash-object\", \"--\", path]);\n  } catch {\n    return null;\n  }\n}\n\n/**\n * Refuse a snapshot merge when the checkout differs from the snapshot the\n * worker branched from, for any path the branch touched: the operator edited\n * it, or it was created/deleted since \u2014 applying the branch's diff on top\n * would silently discard that. Absent-in-both counts as equal.\n */\nfunction assertNoSnapshotDrift(cwd: string, snapshot: string, paths: string[], id: string): void {\n  const drifted = paths\n    .filter((p) => blobAt(cwd, snapshot, p) !== workingBlob(cwd, p))\n    .sort();\n  if (!drifted.length) return;\n  throw new Error(\n    `worker ${id}: the checkout ${cwd} has changed since the worktree's snapshot in paths the branch touches: ` +\n      `${drifted.join(\", \")}. Resolve by hand, then re-run: pai worker merge ${id}. ` +\n      `No merge was made; the worktree was kept.`\n  );\n}\n\n/**\n * `pai worker merge <id>` for a snapshot-based worktree (see `addWorktree`):\n * git's own merge only moves committed history, and the snapshot commit was\n * never on any branch reachable from `cwd`'s HEAD, so there is nothing to\n * `git merge` here. Instead the worker's own changes \u2014 `git diff --binary\n * <snapshot> <branch>` \u2014 are applied straight onto the checkout's working\n * tree as uncommitted edits, exactly like the uncommitted state the worker\n * started from. Works even if `cwd`'s HEAD moved since the snapshot: the\n * diff is applied to files, not merged into a tree.\n */\nfunction mergeSnapshotWorker(\n  logDir: string,\n  id: string,\n  st: WorkerStatus & Required<Pick<WorkerStatus, \"branch\" | \"worktreeDir\">>,\n  noCommit = false\n): string {\n  const snapshot = st.worktreeBase!;\n  const branch = st.branch!;\n  const worktreeDir = st.worktreeDir!;\n  const salvage = existsSync(worktreeDir)\n    ? salvageUncommitted(worktreeDir, st.label || UNLABELED)\n    : { committed: [], skipped: [] };\n  const incoming = parseInt(git(st.cwd, [\"rev-list\", \"--count\", `${snapshot}..${branch}`]), 10) || 0;\n  if (incoming <= 0) {\n    throw new Error(\n      `worker ${id}: branch ${branch} has no commits beyond its snapshot to merge. ` +\n        `The worktree ${worktreeDir} was NOT removed \u2014 uncommitted work there would be destroyed. ` +\n        `Commit it yourself, or drop everything with: pai worker discard ${id}`\n    );\n  }\n  const changedPaths = git(st.cwd, [\"diff\", \"--name-only\", snapshot, branch]).split(\"\\n\").filter(Boolean);\n  assertNoSnapshotDrift(st.cwd, snapshot, changedPaths, id);\n  const diff = execFileSync(\"git\", [\"-C\", st.cwd, \"diff\", \"--binary\", snapshot, branch], {\n    encoding: \"utf8\",\n    timeout: 30_000,\n    maxBuffer: 64 * 1024 * 1024,\n  });\n  if (diff.trim()) {\n    try {\n      execFileSync(\"git\", [\"-C\", st.cwd, \"apply\", \"--binary\"], {\n        input: diff,\n        encoding: \"utf8\",\n        timeout: 30_000,\n        stdio: [\"pipe\", \"pipe\", \"pipe\"],\n      });\n    } catch (e) {\n      const err = e as { stderr?: Buffer | string; message?: string };\n      const why =\n        (typeof err.stderr === \"string\" ? err.stderr : err.stderr?.toString(\"utf8\")) ||\n        err.message ||\n        String(e);\n      throw new Error(\n        `worker ${id}: git refused to apply ${branch}'s changes to ${st.cwd} \u2014 ${why.trim()}. ` +\n          `The worktree ${worktreeDir} was kept: resolve by hand, then re-run merge`\n      );\n    }\n  }\n  if (noCommit) return noCommitNextSteps(id, branch, worktreeDir, changedPaths);\n  removeWorktree(st.cwd, worktreeDir, true);\n  try {\n    git(st.cwd, [\"branch\", \"-D\", branch]); // never merged by git \u2014 nothing for -d to see\n  } catch {\n    // already gone\n  }\n  const s = { ...st, merged: true };\n  saveStatus(logDir, s);\n  const base =\n    `applied worker ${id}'s changes (branch ${branch}) to ${st.cwd} as uncommitted changes: ` +\n    `${changedPaths.join(\", \")} (worktree removed, branch deleted)`;\n  const notes: string[] = [];\n  if (salvage.committed.length) {\n    notes.push(\n      `salvaged ${salvage.committed.length} uncommitted change(s) onto the branch first: ${salvage.committed.join(\", \")}`\n    );\n  }\n  if (salvage.skipped.length) {\n    notes.push(`skipped ${salvage.skipped.join(\", \")}`);\n  }\n  return notes.length ? `${base}; ${notes.join(\"; \")}` : base;\n}\n\nfunction noCommitNextSteps(id: string, branch: string, worktreeDir: string, paths: string[]): string {\n  return (\n    `applied worker ${id}'s changes (branch ${branch}) to the checkout as uncommitted changes: ${paths.join(\", \")}. ` +\n    `Branch and worktree ${worktreeDir} were kept. Next: review (git diff), commit, then run: pai worker gc`\n  );\n}\n\n/**\n * `merge --no-commit`: apply base..branch to the checkout with a 3-way\n * `git apply`, leaving the result uncommitted. On conflict the tree is left\n * as is (markers + unmerged index entries) and the conflicted paths are listed.\n */\nfunction applyNoCommit(cwd: string, id: string, branch: string, worktreeDir: string, base: string, paths: string[]): string {\n  const diff = execFileSync(\"git\", [\"-C\", cwd, \"diff\", \"--binary\", `${base}..${branch}`], {\n    encoding: \"buffer\",\n    timeout: 30_000,\n    maxBuffer: 64 * 1024 * 1024,\n    env: { ...process.env, LC_ALL: \"C\" },\n  });\n  try {\n    execFileSync(\"git\", [\"-C\", cwd, \"apply\", \"--3way\", \"--binary\"], {\n      input: diff,\n      timeout: 30_000,\n      stdio: [\"pipe\", \"pipe\", \"pipe\"],\n      env: { ...process.env, LC_ALL: \"C\" },\n    });\n  } catch (e) {\n    const conflicted = git(cwd, [\"diff\", \"--name-only\", \"--diff-filter=U\"]).split(\"\\n\").filter(Boolean);\n    const err = e as { stderr?: Buffer | string; message?: string };\n    const why = ((typeof err.stderr === \"string\" ? err.stderr : err.stderr?.toString(\"utf8\")) || err.message || \"\").trim();\n    throw new Error(\n      conflicted.length\n        ? `worker ${id}: applying ${branch} conflicted in ${conflicted.join(\", \")}. The tree was left for you: ` +\n            `resolve those paths, review, commit; branch and worktree ${worktreeDir} were kept`\n        : `worker ${id}: git refused to apply ${branch} to ${cwd} \u2014 ${why}. Nothing was changed; branch and worktree were kept`\n    );\n  }\n  return noCommitNextSteps(id, branch, worktreeDir, paths);\n}\n\nexport type VerifyState = \"identical\" | \"differs\" | \"missing\" | \"deleted\";\nexport interface VerifyResult {\n  id: string;\n  ref: string;\n  base: string;\n  against: string;\n  files: { path: string; state: VerifyState }[];\n  ok: boolean;\n}\n\n/**\n * `pai worker verify <id>`: for every file the worker's branch (or its\n * refs/pai-archive/<id> archive once the branch is gone) changed since its\n * base, compare bytes with the working tree or `--against <ref>`.\n * identical = the target already holds the worker's version (a worker delete\n * counts as identical when the target lacks the file too); differs = other\n * bytes; missing = the worker's file is absent in the target; deleted = the\n * worker deleted it but the target still has it. ok = every file identical.\n */\nexport function verifyWorker(logDir: string, id: string, opts: { against?: string } = {}): VerifyResult {\n  const st = loadStatus(logDir, id);\n  if (!st) throw new Error(`no worker named \"${id}\"`);\n  const env = { ...process.env, LC_ALL: \"C\" };\n  const bytes = (args: string[]): Buffer | null => {\n    try {\n      return execFileSync(\"git\", [\"-C\", st.cwd, ...args], {\n        env,\n        timeout: 30_000,\n        maxBuffer: 256 * 1024 * 1024,\n        stdio: [\"ignore\", \"pipe\", \"pipe\"],\n      });\n    } catch {\n      return null;\n    }\n  };\n  const has = (ref: string): boolean => bytes([\"rev-parse\", \"--verify\", \"-q\", `${ref}^{commit}`]) !== null;\n  const ref = [`refs/heads/${worktreeBranch(id)}`, `refs/pai-archive/${id}`].find(has);\n  if (!ref) throw new Error(`worker ${id}: neither ${worktreeBranch(id)} nor refs/pai-archive/${id} exists in ${st.cwd}`);\n  const base = st.worktreeSnapshot && st.worktreeBase ? st.worktreeBase : git(st.cwd, [\"merge-base\", \"HEAD\", ref]);\n  const list = (bytes([\"diff\", \"--name-status\", \"--no-renames\", \"-z\", `${base}..${ref}`]) ?? Buffer.alloc(0))\n    .toString(\"utf8\")\n    .split(\"\\0\")\n    .filter(Boolean);\n  const files: VerifyResult[\"files\"] = [];\n  for (let i = 0; i + 1 < list.length; i += 2) {\n    const path = list[i + 1];\n    const deleted = list[i] === \"D\";\n    const target = opts.against\n      ? bytes([\"show\", `${opts.against}:${path}`])\n      : existsSync(join(st.cwd, path))\n        ? readFileSync(join(st.cwd, path))\n        : null;\n    let state: VerifyState;\n    if (deleted) state = target ? \"deleted\" : \"identical\";\n    else {\n      const mine = bytes([\"show\", `${ref}:${path}`]);\n      state = !target ? \"missing\" : mine && mine.equals(target) ? \"identical\" : \"differs\";\n    }\n    files.push({ path, state });\n  }\n  return { id, ref, base, against: opts.against ?? \"working tree\", files, ok: files.every((f) => f.state === \"identical\") };\n}\n\n/**\n * `pai worker merge <id>`: salvage whatever the worker left uncommitted onto\n * its branch, refuse when the original checkout is dirty in paths the branch\n * touches, merge with --no-ff (the merge commit names the worker), then\n * remove the worktree and delete the branch; the status gains `merged: true`.\n * A branch with nothing to merge is refused loudly \u2014 after salvage that\n * genuinely means it holds nothing, and reporting success there would\n * destroy the worktree for no gain.\n */\nexport function mergeWorker(logDir: string, id: string, opts: { noCommit?: boolean } = {}): string {\n  const st = mustHaveBranch(logDir, id);\n  if (st.merged) return `worker ${id}: branch ${st.branch} already merged`;\n  if (st.worktreeSnapshot) return mergeSnapshotWorker(logDir, id, st, opts.noCommit);\n  // salvage first: only a commit can carry uncommitted work through the merge\n  const salvage = existsSync(st.worktreeDir!)\n    ? salvageUncommitted(st.worktreeDir!, st.label || UNLABELED)\n    : { committed: [], skipped: [] };\n  const incoming = parseInt(git(st.cwd, [\"rev-list\", \"--count\", `HEAD..${st.branch}`]), 10) || 0;\n  if (incoming <= 0) {\n    throw new Error(\n      `worker ${id}: branch ${st.branch} has no commits to merge. ` +\n        `The worktree ${st.worktreeDir} was NOT removed \u2014 uncommitted work there would be destroyed. ` +\n        `Commit it yourself, or drop everything with: pai worker discard ${id}`\n    );\n  }\n  const mergeBase = git(st.cwd, [\"merge-base\", \"HEAD\", st.branch!]);\n  const incomingPaths = git(st.cwd, [\"diff\", \"--name-only\", mergeBase, st.branch!])\n    .split(\"\\n\")\n    .filter(Boolean);\n  assertNoDirtyOverlap(st.cwd, incomingPaths, id, st.branch!);\n  if (opts.noCommit) return applyNoCommit(st.cwd, id, st.branch!, st.worktreeDir!, mergeBase, incomingPaths);\n  try {\n    git(st.cwd, [\"merge\", \"--no-ff\", st.branch!, \"-m\", `merge worker ${id} (${st.label})`]);\n  } catch (e) {\n    throw new Error(\n      `worker ${id}: git refused the merge of ${st.branch} \u2014 ${(e as Error).message}. ` +\n        `The worktree ${st.worktreeDir} was kept: resolve the conflict, then re-run merge`\n    );\n  }\n  if (existsSync(st.worktreeDir!)) assertWorktreeClean(st.worktreeDir!, id);\n  // force: assertWorktreeClean already confirmed nothing but a skipped\n  // outside-pointing symlink (if anything) remains uncommitted\n  removeWorktree(st.cwd, st.worktreeDir!, true);\n  let branchGone = true;\n  try {\n    git(st.cwd, [\"branch\", \"-d\", st.branch!]);\n  } catch {\n    branchGone = false; // -d refuses anything not fully merged; keep the branch, say so\n  }\n  const s = { ...st, merged: true };\n  saveStatus(logDir, s);\n  const base = `merged ${st.branch} into ${st.cwd} (worktree removed${branchGone ? \", branch deleted\" : \"; branch kept: git refused -d\"})`;\n  const notes: string[] = [];\n  if (salvage.committed.length) {\n    notes.push(`salvaged ${salvage.committed.length} uncommitted change(s): ${salvage.committed.join(\", \")}`);\n  }\n  if (salvage.skipped.length) {\n    notes.push(`skipped ${salvage.skipped.join(\", \")}`);\n  }\n  return notes.length ? `${base}; ${notes.join(\"; \")}` : base;\n}\n\n/** `pai worker discard <id>`: drop worktree and branch, keep nothing. */\nexport function discardWorker(logDir: string, id: string): string {\n  const st = mustHaveBranch(logDir, id);\n  removeWorktree(st.cwd, st.worktreeDir!, true);\n  let branchGone = false;\n  try {\n    git(st.cwd, [\"branch\", \"-D\", st.branch!]);\n    branchGone = true;\n  } catch {\n    branchGone = false;\n  }\n  const s = {\n    ...st,\n    branch: null,\n    worktreeDir: null,\n    worktreeBase: null,\n    worktreeSnapshot: null,\n    commits: null,\n    merged: false,\n  };\n  saveStatus(logDir, s);\n  return `discarded worker ${id}: worktree removed${branchGone ? `, branch ${st.branch} deleted` : \"\"}`;\n}\n\nfunction mustHaveBranch(logDir: string, id: string): WorkerStatus & Required<Pick<WorkerStatus, \"branch\" | \"worktreeDir\">> {\n  const st = loadStatus(logDir, id);\n  if (!st) throw new Error(`no worker named \"${id}\"`);\n  if (!st.branch || !st.worktreeDir) {\n    throw new Error(\n      `worker ${id} has no worktree branch to ${st.branch ? \"clean up\" : \"merge\"} \u2014 ` +\n        `it ran in place or its branch was already handled`\n    );\n  }\n  return st as WorkerStatus & Required<Pick<WorkerStatus, \"branch\" | \"worktreeDir\">>;\n}\n\n/**\n * The paragraph a worktree run's system prompt gains: it may commit on its\n * own branch (the no-commit rule holds for the main branch only), it must not\n * merge or push itself, and the parent or operator merges.\n */\nexport function worktreeSystemPrompt(id: string, branch: string, dir: string, snapshot = false): string {\n  return [\n    \"You are running in your own git worktree:\",\n    `  ${dir} on branch ${branch} (worker id ${id}).`,\n    \"Commit your work on that branch as you go (git add / git commit) \u2014 committing here is expected;\",\n    \"the no-commit rule applies to the main branch only, and this is not it.\",\n    \"Do not merge, rebase or push; the operator merges your branch back with `pai worker merge`.\",\n    \"Use ONLY relative paths inside the worktree, never absolute worktree paths \u2014 absolute paths break after merge and leak machine layout.\",\n    ...(snapshot\n      ? [\n          \"This worktree was branched from a snapshot that includes files the parent checkout had uncommitted at spawn time \u2014 not just its last commit.\",\n        ]\n      : []),\n  ].join(\"\\n\");\n}\n\n/**\n * For headless runs WITHOUT a worktree: the worker shares the operator's\n * checkout with other in-flight workers, so a hook blocks git stash (except\n * list/show), reset, clean, checkout/restore of paths, switch, rebase and\n * merge \u2014 take baselines from measurements before editing, not from stash.\n */\nexport function inPlaceSystemPrompt(): string {\n  return [\n    \"You are running in the operator's shared git checkout, alongside other workers editing it at the same time.\",\n    \"A hook blocks git stash (except list/show), reset, clean, checkout/restore of files, switch, rebase and merge \u2014 take baselines from measurements taken before you edit, not from stashing.\",\n    \"Read-only git (status, diff, log, show, stash list) is fine.\",\n  ].join(\"\\n\");\n}\n\nexport interface GcEntry {\n  id: string;\n  /** archive ref, or the reason the worktree was skipped. */\n  archive?: string;\n  skipped?: string;\n}\n\nconst GC_STAMP = \"gc-last\";\n\n/**\n * Archive worktrees of finished workers older than `olderThanHours` and\n * status-less orphan directories: uncommitted state is salvaged onto the\n * branch, the branch is x, the worktree is\n * removed. Nothing is deleted without a salvage first; a failed salvage skips\n * that worktree. Running workers are never touched. `dryRun` reports only.\n */\nexport function gcWorktrees(\n  logDir: string,\n  olderThanHours = 24,\n  dryRun = false,\n  now = Date.now()\n): GcEntry[] {\n  const cutoff = now - olderThanHours * 3_600_000;\n  const out: GcEntry[] = [];\n  const root = worktreesDir(logDir);\n  const known = new Set<string>();\n  const archive = (id: string, dir: string, st: WorkerStatus | null): void => {\n    const target = `refs/pai-archive/${id}`;\n    if (dryRun) return void out.push({ id, archive: target });\n    try {\n      // The shared object store and refs live in the main repo; the recorded cwd\n      // may be another worker's worktree that gc already removed.\n      let repo: string;\n      try {\n        const raw = git(dir, [\"rev-parse\", \"--git-common-dir\"]);\n        repo = isAbsolute(raw) ? raw : resolve(dir, raw);\n      } catch {\n        throw new Error(\"not a git worktree\");\n      }\n      const label = `archive: leftover state of worker ${id}`;\n      if (uncommittedPaths(dir).length) {\n        // salvageUncommitted labels \"salvaged: <label>\"; keep the requested subject\n        const res = salvageUncommitted(dir, label);\n        if (res.committed.length) git(dir, [\"commit\", \"--amend\", \"-q\", \"-m\", label]);\n        if (res.skipped.length && uncommittedPaths(dir).some((p) => !symlinkEscapesWorktree(dir, p))) {\n          throw new Error(\"uncommitted paths remain\");\n        }\n      }\n      const src = worktreeBranch(id);\n      let hasBranch = true;\n      try {\n        git(repo, [\"rev-parse\", \"--verify\", \"-q\", `refs/heads/${src}`]);\n      } catch {\n        hasBranch = false;\n      }\n      const tip = git(dir, [\"rev-parse\", \"HEAD\"]);\n      // never drop a branch whose tip the archive ref would not keep reachable\n      if (hasBranch) git(repo, [\"merge-base\", \"--is-ancestor\", `refs/heads/${src}`, tip]);\n      git(repo, [\"update-ref\", target, tip]);\n      git(repo, [\"worktree\", \"remove\", \"--force\", dir]);\n      if (hasBranch) git(repo, [\"branch\", \"-D\", src]);\n      if (st) saveStatus(logDir, { ...st, branch: null, worktreeDir: null, archived: target });\n      appendLedger(ledgerPath(logDir), \"WORKER-GC\", { id, archive: target });\n      out.push({ id, archive: target });\n    } catch (e) {\n      out.push({ id, skipped: (e as Error).message.split(\"\\n\")[0] });\n    }\n  };\n\n  for (const st of loadStatuses(logDir)) {\n    known.add(st.id);\n    if (!st.worktreeDir || !existsSync(st.worktreeDir) || isLive(st)) continue;\n    let end = 0;\n    try {\n      end = statSync(statusPath(logDir, st.id)).mtimeMs;\n    } catch {\n      continue;\n    }\n    if (end > cutoff) continue;\n    archive(st.id, st.worktreeDir, st);\n  }\n\n  if (existsSync(root)) {\n    for (const ent of readdirSync(root, { withFileTypes: true })) {\n      if (!ent.isDirectory() || known.has(ent.name) || existsSync(statusPath(logDir, ent.name))) continue;\n      const dir = join(root, ent.name);\n      try {\n        if (statSync(dir).mtimeMs > cutoff) continue;\n      } catch {\n        continue;\n      }\n      archive(ent.name, dir, null);\n    }\n  }\n  if (!dryRun) {\n    for (const repo of new Set(loadStatuses(logDir).map((s) => s.cwd))) {\n      try {\n        git(repo, [\"worktree\", \"prune\"]);\n      } catch {\n        // repo gone\n      }\n    }\n  }\n  return out;\n}\n\n/** Run `gcWorktrees` at most once per `everyMin` minutes (stamp file in the logDir). */\nexport function gcWorktreesThrottled(logDir: string, everyMin = 60, now = Date.now()): GcEntry[] | null {\n  const stamp = join(logDir, GC_STAMP);\n  try {\n    if (now - statSync(stamp).mtimeMs < everyMin * 60_000) return null;\n  } catch {\n    // never ran\n  }\n  mkdirSync(logDir, { recursive: true });\n  writeFileSync(stamp, String(now), \"utf8\");\n  return gcWorktrees(logDir, 24, false, now);\n}\n", "/**\n * Worker-session detection.\n *\n * A disposable headless worker (a `claude -p` run started by an orchestrating\n * session, possibly against a different model provider with a different\n * context window) shares the project directory and the hook configuration\n * with the real session that spawned it. Left alone, the hooks treat it as a\n * session in its own right: they inject project context into it, create and\n * rename a numbered session note for it, autosave it, and enqueue a\n * model-written handover for it. Its compactions also land in the project's\n * transcript folder, where they are indistinguishable from a real session's\n * and drag the measured compaction trigger down (observed 2026-09-17: two\n * workers compacting at ~151k tokens pulled a project's trigger from ~784k\n * to ~151k, and the real session's handover fired at ~50k tokens).\n *\n * The launcher marks such sessions with `PAI_WORKER=1`. Every hook that does\n * per-session bookkeeping returns immediately when this predicate is true.\n * Deliberately NOT guarded: the security validator (a worker's shell\n * commands must still be checked) and observability capture.\n */\nexport function isWorkerSession(env: NodeJS.ProcessEnv = process.env): boolean {\n  return env.PAI_WORKER === \"1\";\n}\n", "#!/usr/bin/env node\n\n/**\n * load-project-context.ts\n *\n * SessionStart hook that sets up project context:\n * - Checks for CLAUDE.md in various locations (Claude Code handles loading)\n * - Sets up Notes/ directory in ~/.claude/projects/{encoded-path}/\n * - Ensures TODO.md exists\n * - Sends ntfy.sh notification (mandatory)\n * - Displays session continuity info (like session-init.sh)\n *\n * This hook complements Claude Code's native CLAUDE.md loading by:\n * - Setting up the Notes infrastructure\n * - Showing the latest session note for continuity\n * - Sending ntfy.sh notifications\n */\n\nimport { readWorkersSection } from '../../../workers/config.js';\nimport { workersLogDir } from '../../../workers/paths.js';\nimport { pendingResults } from '../../../workers/pending.js';\nimport { isWorkerSession } from \"../lib/worker-session.js\";\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join, basename, dirname, resolve } from 'path';\nimport { homedir } from 'os';\nimport { execSync } from 'child_process';\nimport { buildWakeupContext } from '../../../memory/wakeup.js';\nimport { readContinueCheckpoint } from '../../../session/checkpoint-block.js';\nimport { applyHandoverBudget } from '../lib/handover-budget.js';\nimport { sessionRoutingPath } from '../lib/pai-paths.js';\nimport {\n  findNotesDir,\n  getProjectDir,\n  getCurrentNotePath,\n  createSessionNote,\n  findTodoPath,\n  findAllClaudeMdPaths,\n  sendNtfyNotification,\n  isProbeSession,\n  archiveSessionFilesToSessionsDir\n} from '../lib/project-utils.js';\n\n/**\n * Find the pai CLI binary path dynamically.\n * Tries `which pai` first, then common fallback locations.\n */\nfunction findPaiBinary(): string {\n  try {\n    return execSync('which pai', { encoding: 'utf-8' }).trim();\n  } catch {\n    // Fallback locations in order of preference\n    const fallbacks = [\n      '/usr/local/bin/pai',\n      '/opt/homebrew/bin/pai',\n      `${process.env.HOME}/.local/bin/pai`,\n    ];\n    for (const p of fallbacks) {\n      if (existsSync(p)) return p;\n    }\n  }\n  return 'pai'; // Last resort: rely on PATH at runtime\n}\n\n/**\n * Check session-routing.json for an active route.\n * Returns the routed Notes path if set, or null to use default behavior.\n */\nfunction getRoutedNotesPath(): string | null {\n  const routingFile = sessionRoutingPath();\n  if (!existsSync(routingFile)) return null;\n\n  try {\n    const routing = JSON.parse(readFileSync(routingFile, 'utf-8'));\n    const active = routing?.active_session;\n    if (active?.notes_path) {\n      return active.notes_path;\n    }\n  } catch {\n    // Ignore parse errors\n  }\n  return null;\n}\n\n/**\n * Project signals that indicate a directory is a real project root.\n */\nconst PROJECT_SIGNALS = [\n  '.git',\n  'package.json',\n  'pubspec.yaml',\n  'Cargo.toml',\n  'go.mod',\n  'pyproject.toml',\n  'setup.py',\n  'build.gradle',\n  'pom.xml',\n  'composer.json',\n  'Gemfile',\n  'Makefile',\n  'CMakeLists.txt',\n  'tsconfig.json',\n  'CLAUDE.md',\n  join('Notes', 'PAI.md'),\n];\n\n/**\n * Returns true if the given directory looks like a project root.\n * Checks for the presence of well-known project signal files/dirs.\n */\nfunction hasProjectSignals(dir: string): boolean {\n  for (const signal of PROJECT_SIGNALS) {\n    if (existsSync(join(dir, signal))) return true;\n  }\n  return false;\n}\n\n/**\n * Returns true if the directory should NOT be auto-registered.\n * Guards: home directory, shallow paths, temp directories.\n */\nfunction isGuardedPath(dir: string): boolean {\n  const home = homedir();\n  const resolved = resolve(dir);\n\n  // Never register the home directory itself\n  if (resolved === home) return true;\n\n  // Depth guard: require at least 3 path segments beyond root\n  // e.g. /Users/owner/foo is depth 3 on macOS \u2014 reject it\n  const parts = resolved.split('/').filter(Boolean);\n  if (parts.length < 3) return true;\n\n  // Temp/system directories\n  const forbidden = ['/tmp', '/var', '/private/tmp', '/private/var/folders'];\n  for (const prefix of forbidden) {\n    if (resolved === prefix || resolved.startsWith(prefix + '/')) return true;\n  }\n\n  return false;\n}\n\ninterface HookInput {\n  session_id: string;\n  cwd: string;\n  hook_event_name: string;\n}\n\nasync function main() {\n  if (isWorkerSession()) return; // disposable worker: no per-session bookkeeping\n  console.error('\\nload-project-context.ts starting...');\n\n  // Skip probe/health-check sessions (e.g. CodexBar ClaudeProbe)\n  if (isProbeSession()) {\n    console.error('Probe session detected - skipping project context loading');\n    process.exit(0);\n  }\n\n  // Read hook input from stdin\n  let hookInput: HookInput | null = null;\n  try {\n    const chunks: Buffer[] = [];\n    for await (const chunk of process.stdin) {\n      chunks.push(chunk);\n    }\n    const input = Buffer.concat(chunks).toString('utf-8');\n    if (input.trim()) {\n      hookInput = JSON.parse(input);\n    }\n  } catch (error) {\n    console.error('Could not parse hook input, using process.cwd()');\n  }\n\n  // Get current working directory\n  const cwd = hookInput?.cwd || process.cwd();\n\n  // Determine meaningful project name\n  // If cwd is a Notes directory, use parent directory name instead\n  let projectName = basename(cwd);\n  if (projectName.toLowerCase() === 'notes') {\n    projectName = basename(dirname(cwd));\n  }\n\n  console.error(`Working directory: ${cwd}`);\n  console.error(`Project: ${projectName}`);\n\n  // Check if this is a subagent session - skip for subagents\n  const isSubagent = process.env.CLAUDE_AGENT_TYPE !== undefined ||\n                     (process.env.CLAUDE_PROJECT_DIR || '').includes('/.claude/agents/');\n\n  if (isSubagent) {\n    console.error('Subagent session - skipping project context setup');\n    process.exit(0);\n  }\n\n  // 1. Find and READ all CLAUDE.md files - inject them into context\n  // This ensures Claude actually processes the instructions, not just sees them in headers\n  const claudeMdPaths = findAllClaudeMdPaths(cwd);\n  const claudeMdContents: { path: string; content: string }[] = [];\n\n  if (claudeMdPaths.length > 0) {\n    console.error(`Found ${claudeMdPaths.length} CLAUDE.md file(s):`);\n    for (const path of claudeMdPaths) {\n      console.error(`   - ${path}`);\n      try {\n        const content = readFileSync(path, 'utf-8');\n        claudeMdContents.push({ path, content });\n        console.error(`     Read ${content.length} chars`);\n      } catch (error) {\n        console.error(`     Could not read: ${error}`);\n      }\n    }\n  } else {\n    console.error('No CLAUDE.md found in project');\n    console.error('   Consider creating one at ./CLAUDE.md or ./.claude/CLAUDE.md');\n  }\n\n  // 2. Find or create Notes directory\n  // Priority:\n  //   1. Active session routing (pai route <project>) \u2192 routed Obsidian path\n  //   2. Local Notes/ in cwd \u2192 use it (git-trackable, e.g. symlink to Obsidian)\n  //   3. Central ~/.claude/projects/.../Notes/ \u2192 fallback\n  const routedPath = getRoutedNotesPath();\n  let notesDir: string;\n\n  if (routedPath) {\n    // Routing is active - use the configured Obsidian Notes path\n    const { mkdirSync } = await import('fs');\n    if (!existsSync(routedPath)) {\n      mkdirSync(routedPath, { recursive: true });\n      console.error(`Created routed Notes: ${routedPath}`);\n    } else {\n      console.error(`Notes directory: ${routedPath} (routed via pai route)`);\n    }\n    notesDir = routedPath;\n  } else {\n    const notesInfo = findNotesDir(cwd);\n\n    if (notesInfo.isLocal) {\n      notesDir = notesInfo.path;\n      console.error(`Notes directory: ${notesDir} (local)`);\n    } else {\n      // Create central Notes directory\n      if (!existsSync(notesInfo.path)) {\n        const { mkdirSync } = await import('fs');\n        mkdirSync(notesInfo.path, { recursive: true });\n        console.error(`Created central Notes: ${notesInfo.path}`);\n      } else {\n        console.error(`Notes directory: ${notesInfo.path} (central)`);\n      }\n      notesDir = notesInfo.path;\n    }\n  }\n\n  // 3. Archive the project's transcripts into sessions/ \u2014 by LINKING, never moving.\n  //\n  // This used to renameSync every .jsonl except the newest out of the project\n  // root. `claude --resume <uuid>` reads ~/.claude/projects/<encoded>/<uuid>.jsonl\n  // and only that path, so moving the file is what makes a session unresumable \u2014\n  // and because this is a SessionStart hook, the act of STARTING a session in a\n  // project destroyed the resumability of every earlier session in it. The old\n  // comment (\"keep the newest one for potential resume\") shows the dependency was\n  // known; keeping one file was not enough.\n  //\n  // Measured 2026-08-04: this repo had 1 transcript at the top level and 52 under\n  // sessions/, every one of the 52 unresumable. Among them was the id PAI prints\n  // in its own archived handovers as `claude --resume <uuid>`, so the instruction\n  // we ship in every checkpoint could not work.\n  //\n  // It also completes the incident of that morning: `pai Northwind` failed to\n  // resume b3462801 because of a probe bug, started a fresh session instead, and\n  // THIS hook then moved b3462801 \u2014 867 KB of real work \u2014 out of reach. The\n  // failed resume destroyed what it had failed to open.\n  //\n  // A hard link keeps both truths: the archive under sessions/ is populated for\n  // everything that reads it, and the file Claude Code owns stays where Claude\n  // Code put it. Same inode, so it costs nothing.\n  // This was the fourth mover, with its own inline loop. It now calls the one\n  // shared archiver instead: a second implementation is exactly how the earlier\n  // probeResume fix came to land in one of three copies and leave `pai <Name>`\n  // broken for a day.\n  const projectDir = getProjectDir(cwd);\n  if (existsSync(projectDir)) {\n    try {\n      // Exclude this session's own transcript: it is being written right now,\n      // and the archive is meant to hold finished sessions.\n      const own = hookInput?.session_id ? `${hookInput.session_id}.jsonl` : undefined;\n      archiveSessionFilesToSessionsDir(projectDir, own, true);\n    } catch (error) {\n      console.error(`Could not archive session transcripts: ${error}`);\n    }\n  }\n\n  // 4. Find or create TODO.md\n  const todoPath = findTodoPath(cwd);\n  const hasTodo = existsSync(todoPath);\n  if (hasTodo) {\n    console.error(`TODO.md: ${todoPath}`);\n  } else {\n    // Create TODO.md in the Notes directory\n    const newTodoPath = join(notesDir, 'TODO.md');\n    const { writeFileSync } = await import('fs');\n    writeFileSync(newTodoPath, `# TODO\\n\\n## Offen\\n\\n- [ ] \\n\\n---\\n\\n*Created: ${new Date().toISOString()}*\\n`);\n    console.error(`Created TODO.md: ${newTodoPath}`);\n  }\n\n  // 5. Check for existing note or create new one\n  let activeNotePath: string | null = null;\n\n  if (notesDir) {  // notesDir is always set now (local or central)\n    const currentNotePath = getCurrentNotePath(notesDir);\n\n    // Only create a new note if there is truly no note at all.\n    // A completed note is still used \u2014 it will be updated or continued.\n    // This prevents duplicate notes at month boundaries and on every compaction.\n    if (!currentNotePath) {\n      // Defensive: ensure projectName is a usable string\n      const safeProjectName = (typeof projectName === 'string' && projectName.trim().length > 0)\n        ? projectName.trim()\n        : 'Untitled Session';\n      console.error('\\nNo previous session notes found - creating new one');\n      activeNotePath = createSessionNote(notesDir, String(safeProjectName));\n      console.error(`Created: ${basename(activeNotePath)}`);\n    } else {\n      activeNotePath = currentNotePath!;\n      console.error(`\\nUsing existing session note: ${basename(activeNotePath)}`);\n      // Show preview of current note\n      try {\n        const content = readFileSync(activeNotePath, 'utf-8');\n        const lines = content.split('\\n').slice(0, 12);\n        console.error('--- Current Note Preview ---');\n        for (const line of lines) {\n          console.error(line);\n        }\n        console.error('--- End Preview ---\\n');\n      } catch {\n        // Ignore read errors\n      }\n    }\n  }\n\n  // 6. Show TODO.md preview\n  if (existsSync(todoPath)) {\n    try {\n      const todoContent = readFileSync(todoPath, 'utf-8');\n      const todoLines = todoContent.split('\\n').filter(l => l.includes('[ ]')).slice(0, 5);\n      if (todoLines.length > 0) {\n        console.error('\\nOpen TODOs:');\n        for (const line of todoLines) {\n          console.error(`   ${line.trim()}`);\n        }\n      }\n    } catch {\n      // Ignore read errors\n    }\n  }\n\n  // 7. Send ntfy.sh notification (MANDATORY)\n  await sendNtfyNotification(`Session started in ${projectName}`);\n\n  // 7.5. Run pai project detect to identify the registered PAI project\n  const paiBin = findPaiBinary();\n  let paiProjectBlock = '';\n  try {\n    const { execFileSync } = await import('child_process');\n    const raw = execFileSync(paiBin, ['project', 'detect', '--json', cwd], {\n      encoding: 'utf-8',\n      env: process.env,\n    }).trim();\n\n    if (raw) {\n      const detected = JSON.parse(raw) as {\n        slug?: string;\n        display_name?: string;\n        root_path?: string;\n        match_type?: string;\n        relative_path?: string | null;\n        session_count?: number;\n        status?: string;\n        error?: string;\n        cwd?: string;\n      };\n\n      /**\n       * Attempt to auto-register the CWD as a new PAI project.\n       * Calls `pai project add <cwd>`, then re-detects to confirm registration.\n       * Returns true if registration succeeded (or was attempted and project add ran),\n       * and sets paiProjectBlock as a side effect on success.\n       */\n      const tryAutoRegister = async (): Promise<boolean> => {\n        if (isGuardedPath(cwd) || !hasProjectSignals(cwd)) return false;\n\n        try {\n          execFileSync(paiBin, ['project', 'add', cwd], {\n            encoding: 'utf-8',\n            env: process.env,\n          });\n          console.error(`PAI auto-registered project at: ${cwd}`);\n\n          // Re-run detect to confirm registration\n          try {\n            const raw2 = execFileSync(paiBin, ['project', 'detect', '--json', cwd], {\n              encoding: 'utf-8',\n              env: process.env,\n            }).trim();\n\n            if (raw2) {\n              const detected2 = JSON.parse(raw2) as typeof detected;\n              if (detected2.slug) {\n                const name2 = detected2.display_name || detected2.slug;\n                console.error(`PAI auto-registered: \"${detected2.slug}\" (${detected2.match_type})`);\n                paiProjectBlock = `PAI Project Registry: ${name2} (slug: ${detected2.slug}) [AUTO-REGISTERED]\nMatch: ${detected2.match_type ?? 'exact'} | Sessions: 0`;\n                return true;\n              }\n            }\n          } catch (detectErr) {\n            console.error('PAI auto-registration: project added but re-detect failed:', detectErr);\n            return true; // project IS registered, just can't load context\n          }\n        } catch (addErr) {\n          console.error('PAI auto-registration failed (project add):', addErr);\n        }\n        return false;\n      };\n\n      if (detected.error === 'no_match') {\n        // Attempt auto-registration if the directory looks like a real project\n        const autoRegistered = await tryAutoRegister();\n\n        if (!autoRegistered) {\n          paiProjectBlock = `PAI Project Registry: No registered project matches this directory.\nRun \"pai project add .\" to register this project, or use /route to tag the session.`;\n          console.error('PAI detect: no match for', cwd);\n        }\n      } else if (\n        detected.match_type === 'parent' &&\n        detected.relative_path &&\n        !isGuardedPath(cwd) &&\n        hasProjectSignals(cwd)\n      ) {\n        // The CWD is inside a broader registered parent (e.g. \"owner\" or \"apps\"),\n        // but it has its own project signals \u2014 register it as a distinct project.\n        console.error(\n          `PAI detect: parent match to \"${detected.slug}\" via relative path \"${detected.relative_path}\" \u2014 CWD looks like its own project, attempting auto-registration`\n        );\n        const autoRegistered = await tryAutoRegister();\n\n        if (!autoRegistered) {\n          // Fall through: show the parent match as normal\n          const name = detected.display_name || detected.slug;\n          const nameSlug = ` (slug: ${detected.slug})`;\n          const matchDesc = `parent (+${detected.relative_path ?? ''})`;\n          const statusFlag = detected.status && detected.status !== 'active'\n            ? ` [${detected.status.toUpperCase()}]`\n            : '';\n          paiProjectBlock = `PAI Project Registry: ${name}${statusFlag}${nameSlug}\nMatch: ${matchDesc} | Sessions: ${detected.session_count ?? 0}${detected.status && detected.status !== 'active' ? `\\nWARNING: Project status is \"${detected.status}\". Run: pai project health --fix` : ''}`;\n          console.error(`PAI detect: kept parent match \"${detected.slug}\" (auto-register not applicable)`);\n        }\n      } else if (detected.slug) {\n        const name = detected.display_name || detected.slug;\n        const nameSlug = ` (slug: ${detected.slug})`;\n        const matchDesc = detected.match_type === 'exact'\n          ? 'exact'\n          : `parent (+${detected.relative_path ?? ''})`;\n        const statusFlag = detected.status && detected.status !== 'active'\n          ? ` [${detected.status.toUpperCase()}]`\n          : '';\n        paiProjectBlock = `PAI Project Registry: ${name}${statusFlag}${nameSlug}\nMatch: ${matchDesc} | Sessions: ${detected.session_count ?? 0}${detected.status && detected.status !== 'active' ? `\\nWARNING: Project status is \"${detected.status}\". Run: pai project health --fix` : ''}`;\n        console.error(`PAI detect: matched \"${detected.slug}\" (${detected.match_type})`);\n      }\n    }\n  } catch (e) {\n    // Non-fatal \u2014 don't break session start if pai is unavailable\n    console.error('pai project detect failed:', e);\n  }\n\n  // 8. Output system reminder with session info\n  const reminder = `\n<system-reminder>\nPROJECT CONTEXT LOADED\n\nProject: ${projectName}\nWorking Directory: ${cwd}\n${notesDir ? `Notes Directory: ${notesDir}${routedPath ? ' (routed via pai route)' : ''}` : 'Notes: disabled (no local Notes/ directory)'}\n${hasTodo ? `TODO: ${todoPath}` : 'TODO: not found'}\n${claudeMdPaths.length > 0 ? `CLAUDE.md: ${claudeMdPaths.join(', ')}` : 'No CLAUDE.md found'}\n${activeNotePath ? `Active Note: ${basename(activeNotePath)}` : ''}\n${routedPath ? `\\nNote Routing: ACTIVE (pai route is set - notes go to Obsidian vault)` : ''}\n${paiProjectBlock ? `\\n${paiProjectBlock}` : ''}\n</system-reminder>\n`;\n\n  // Output to stdout for Claude to receive\n  console.log(reminder);\n\n  // Unmerged finished worker results in this repo: one line, none when zero\n  try {\n    const { workers } = readWorkersSection();\n    const pending = pendingResults(workersLogDir(workers), cwd);\n    if (pending.length) {\n      console.log(`${pending.length} finished worker result(s) not merged in this repo: ${pending.map((r) => r.id).join(', ')} \u2014 run \\`pai worker pending\\``);\n    }\n  } catch {\n    // no workers config or not a git repo: stay silent\n  }\n\n  // An MCP/tools pin silently drops servers; say so. Nothing printed when unpinned.\n  try {\n    const { execFileSync: run } = await import('child_process');\n    const pins = run(paiBin, ['project', 'pins'], { encoding: 'utf-8', cwd }).trim();\n    if (pins) console.log(pins);\n  } catch {\n    // pai unavailable: stay silent\n  }\n\n  // 8.5. INJECT THE PAUSE CHECKPOINT\n  //\n  // `pai pause` writes the handover to TODO.md under `## Continue`. Until now\n  // nothing read it back: CORE SKILL.md only told the model to look there *if\n  // the user typed \"go\"*, so a resumed session started blind unless the user\n  // knew the magic word. Writing a handover nobody delivers is not a\n  // handover. Inject it, and say plainly that it is the previous session's\n  // state rather than an instruction to act on.\n  let handoverInjected = false;\n  if (existsSync(todoPath)) {\n    try {\n      const checkpoint = readContinueCheckpoint(readFileSync(todoPath, 'utf-8'));\n      if (checkpoint) {\n        handoverInjected = true;\n        const from = checkpoint.meta?.session\n          ? `\\nFrom session: ${checkpoint.meta.session}`\n          : '';\n        const when = checkpoint.meta?.ts ? `\\nPaused at: ${checkpoint.meta.ts}` : '';\n        const resume = checkpoint.meta?.sessionId\n          ? `\\nResume that session with: claude --resume ${checkpoint.meta.sessionId}`\n          : '';\n        const budgeted = applyHandoverBudget(checkpoint.body, todoPath);\n\n        console.log(`\n<system-reminder>\nHANDOVER FROM THE PREVIOUS SESSION\n\nSource: ${todoPath} (## Continue)${from}${when}${resume}\n\n${budgeted.body}\n\n---\nThis is recorded state, not a new instruction. Do not start acting on it\nunprompted. If the user says \"go\", \"continue\", or \"weiter\", resume from here.\n</system-reminder>\n`);\n        const budgetNote = budgeted.truncated\n          ? ', truncated'\n          : budgeted.elided.length > 0\n            ? `, elided: ${budgeted.elided.join(',')}`\n            : '';\n        console.error(`Injected pause checkpoint (${checkpoint.body.length} chars${budgetNote})`);\n      } else {\n        console.error('No pause checkpoint body in TODO.md \u2014 nothing to hand over');\n      }\n    } catch (error) {\n      // Non-fatal \u2014 a malformed TODO.md must never block session start.\n      console.error('Checkpoint injection failed:', error);\n    }\n  }\n\n  // 9. INJECT CLAUDE.md contents as system-reminders\n  // This ensures Claude actually reads and processes the instructions\n  for (const { path, content } of claudeMdContents) {\n    const claudeMdReminder = `\n<system-reminder>\nLOCAL CLAUDE.md LOADED (MANDATORY - READ AND FOLLOW)\n\nSource: ${path}\n\n${content}\n\n---\nTHE ABOVE INSTRUCTIONS ARE MANDATORY. Follow them exactly.\n</system-reminder>\n`;\n    console.log(claudeMdReminder);\n    console.error(`Injected CLAUDE.md content from: ${path}`);\n  }\n\n  // 10. Inject wake-up context (L0 identity + L1 essential story) if available\n  // The detected PAI project root_path is used for L1 note lookup.\n  // We derive it from the `paiProjectBlock` detection result by re-running a\n  // lightweight registry lookup, or by falling back to cwd for local-notes projects.\n  try {\n    // Attempt to find the project root path from the registry via `pai project detect --json`\n    let wakeupRootPath: string | undefined;\n    try {\n      const { execFileSync: efs } = await import('child_process');\n      const raw2 = efs(paiBin, ['project', 'detect', '--json', cwd], {\n        encoding: 'utf-8',\n        env: process.env,\n      }).trim();\n      if (raw2) {\n        const det = JSON.parse(raw2) as { root_path?: string; slug?: string };\n        if (det.root_path) wakeupRootPath = det.root_path;\n      }\n    } catch {\n      // Non-fatal \u2014 fall back to cwd\n      wakeupRootPath = cwd;\n    }\n\n    // Handover supersedes the L1 story: both summarise the same recent note,\n    // and the handover is a curated message while the story is auto-extracted.\n    const wakeupBlock = buildWakeupContext(wakeupRootPath, undefined, { skipStory: handoverInjected });\n    if (wakeupBlock) {\n      const wakeupReminder = `\\n<system-reminder>\\nWAKEUP CONTEXT\\n\\n${wakeupBlock}\\n</system-reminder>\\n`;\n      console.log(wakeupReminder);\n      console.error('Injected wake-up context (L0+L1)');\n    } else {\n      console.error('No wake-up context to inject (no identity file or session notes)');\n    }\n  } catch (wakeupError) {\n    // Non-fatal \u2014 don't block session start\n    console.error('Wake-up context injection failed:', wakeupError);\n  }\n\n  console.error('\\nProject context setup complete\\n');\n  process.exit(0);\n}\n\nmain().catch(error => {\n  console.error('load-project-context.ts error:', error);\n  process.exit(0); // Don't block session start\n});\n", "/**\n * Wake-up context system \u2014 progressive context loading inspired by mempalace.\n *\n * Layers:\n *   L0 Identity     (~100 tokens)   \u2014 user identity from ~/.pai/identity.txt. Always loaded.\n *   L1 Essential Story (~500-800t)  \u2014 top session notes for the project, key lines extracted.\n *   L2 On-Demand                    \u2014 triggered by topic queries (handled by memory_search).\n *   L3 Deep Search                  \u2014 unlimited federated memory search (memory_search tool).\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { join, basename } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { paiHomePath, migratePaiFile, type MigrateFileResult } from \"../config/pai-home.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum tokens for the L1 essential story block. Approx 4 chars/token.\n * Measured 2026-09-20: 800 tokens was mostly stale bullets. Reduced to 300.\n */\nconst L1_TOKEN_BUDGET = 300;\nconst L1_CHAR_BUDGET = L1_TOKEN_BUDGET * 4; // ~1600 chars\n\n/** Maximum session notes to scan when building L1. Reduced from 10 to 3 (2026-09-20). */\nconst L1_MAX_NOTES = 3;\n\n/** Sections to extract from session notes (in priority order). */\nconst EXTRACT_SECTIONS = [\n  \"Work Done\",\n  \"Key Decisions\",\n  \"Next Steps\",\n  \"Checkpoint\",\n];\n\n/** Identity file location. */\nconst IDENTITY_FILE = join(homedir(), \".pai\", \"identity.txt\");\n\n// ---------------------------------------------------------------------------\n// L0: Identity\n// ---------------------------------------------------------------------------\n\n/**\n * Load L0 identity. Prefers the PAI_HOME location (identity.txt migrated by\n * `pai config migrate`), falling back to the legacy ~/.pai/identity.txt so a\n * not-yet-migrated file keeps working. Returns \"\" if neither exists. Never\n * throws.\n */\nexport function loadL0Identity(\n  opts: { newPath?: string; legacyPath?: string } = {}\n): string {\n  const newPath = opts.newPath ?? paiHomePath(\"identity.txt\");\n  const legacyPath = opts.legacyPath ?? IDENTITY_FILE;\n  const path = existsSync(newPath) ? newPath : legacyPath;\n  if (!existsSync(path)) return \"\";\n  try {\n    return readFileSync(path, \"utf-8\").trim();\n  } catch {\n    return \"\";\n  }\n}\n\n/**\n * Move ~/.pai/identity.txt into PAI_HOME, following the same copy /\n * verify-byte-identical / rename-aside semantics as every other per-user\n * file (see migratePaiFile). `from`/`to` are overridable for tests.\n */\nexport function migrateIdentityFile(\n  opts: { dryRun?: boolean; from?: string; to?: string } = {}\n): MigrateFileResult {\n  const toPath = opts.to ?? paiHomePath(\"identity.txt\");\n  const fromPath = opts.from ?? IDENTITY_FILE;\n  return migratePaiFile(toPath, [fromPath], { dryRun: opts.dryRun });\n}\n\n// ---------------------------------------------------------------------------\n// L1: Essential Story\n// ---------------------------------------------------------------------------\n\n/**\n * Find the Notes directory for a project given its root_path from the registry.\n * Checks local Notes/ first, then central ~/.claude/projects/... path.\n */\nfunction findNotesDirForProject(rootPath: string): string | null {\n  // Check local Notes directories first\n  const localCandidates = [\n    join(rootPath, \"Notes\"),\n    join(rootPath, \"notes\"),\n    join(rootPath, \".claude\", \"Notes\"),\n  ];\n  for (const p of localCandidates) {\n    if (existsSync(p)) return p;\n  }\n\n  // Fall back to central ~/.claude/projects/{encoded}/Notes\n  const encoded = rootPath\n    .replace(/\\//g, \"-\")\n    .replace(/\\./g, \"-\")\n    .replace(/ /g, \"-\");\n  const centralNotes = join(\n    homedir(),\n    \".claude\",\n    \"projects\",\n    encoded,\n    \"Notes\"\n  );\n  if (existsSync(centralNotes)) return centralNotes;\n\n  return null;\n}\n\n/**\n * Recursively find all .md session note files in a Notes directory.\n * Handles both flat layout (Notes/*.md) and month-subdirectory layout\n * (Notes/YYYY/MM/*.md). Returns files sorted newest-first by filename\n * (note numbers are monotonically increasing, so lexicographic = newest-last,\n * so we reverse).\n */\nfunction findSessionNotes(notesDir: string): string[] {\n  const result: string[] = [];\n\n  const scanDir = (dir: string) => {\n    if (!existsSync(dir)) return;\n    let entries: Array<{ name: string; isDir: boolean }>;\n    try {\n      entries = readdirSync(dir, { withFileTypes: true })\n        .map((e) => ({ name: e.name, isDir: e.isDirectory() }));\n    } catch {\n      return;\n    }\n\n    for (const entry of entries) {\n      const fullPath = join(dir, entry.name);\n      if (entry.isDir) {\n        // Recurse into YYYY/MM subdirectories\n        scanDir(fullPath);\n      } else if (entry.name.match(/^\\d{3,4}[\\s_-].*\\.md$/)) {\n        result.push(fullPath);\n      }\n    }\n  };\n\n  scanDir(notesDir);\n\n  // Sort newest-first by the DATE in the filename, not the note number.\n  //\n  // The note number is only monotonic within one uninterrupted numbering run.\n  // It restarts \u2014 per month directory, and after a registry merge renumbers a\n  // project \u2014 so \"highest number\" and \"most recent\" diverge. Observed live:\n  // `0184 - 2026-02-22` outranked `0008 - 2026-08-01`, and the wake-up context\n  // handed a resumed session five-month-old material as its recent history.\n  //\n  // `NNNN - YYYY-MM-DD - Title.md` is the enforced layout, so the date is the\n  // reliable key. Number breaks ties within a day; mtime is the last resort\n  // for notes that predate the naming convention.\n  const dateOf = (p: string): string =>\n    basename(p).match(/(\\d{4}-\\d{2}-\\d{2})/)?.[1] ?? \"\";\n  const numberOf = (p: string): number =>\n    parseInt(basename(p).match(/^(\\d+)/)?.[1] ?? \"0\", 10);\n  const mtimeOf = (p: string): number => {\n    try {\n      return statSync(p).mtimeMs;\n    } catch {\n      return 0;\n    }\n  };\n\n  result.sort((a, b) => {\n    const dateA = dateOf(a);\n    const dateB = dateOf(b);\n    // Undated notes sort last rather than winning on an empty string.\n    if (dateA !== dateB) {\n      if (!dateA) return 1;\n      if (!dateB) return -1;\n      return dateB.localeCompare(dateA);\n    }\n    const byNumber = numberOf(b) - numberOf(a);\n    if (byNumber !== 0) return byNumber;\n    return mtimeOf(b) - mtimeOf(a);\n  });\n\n  return result;\n}\n\n/**\n * Extract the most important lines from a session note.\n * Prioritises: Work Done items, Key Decisions, Next Steps, Checkpoint headings.\n * Returns a condensed string under maxChars.\n */\nfunction normalizeLine(line: string): string {\n  return line\n    .replace(/^(- \\[[ x]\\] |- |\\* |\\d+\\.\\s)/, \"\")\n    .trim()\n    .replace(/\\s+/g, \" \");\n}\n\nfunction extractKeyLines(\n  content: string,\n  maxChars: number,\n  seen: Set<string> = new Set(),\n  seenLabels: Set<string> = new Set()\n): string {\n  const lines = content.split(\"\\n\");\n  const selected: string[] = [];\n  let inTargetSection = false;\n  let currentSection = \"\";\n  let charCount = 0;\n  // Heading text seen since the last line was emitted. Buffered rather than\n  // pushed immediately: a heading with no surviving lines under it (every\n  // line deduped against an earlier note) must not appear at all.\n  let pendingLabel: string | null = null;\n\n  // First pass: collect lines from priority sections\n  for (const line of lines) {\n    // Detect section headers\n    const h2Match = line.match(/^## (.+)$/);\n    const h3Match = line.match(/^### (.+)$/);\n    if (h2Match) {\n      currentSection = h2Match[1];\n      inTargetSection = EXTRACT_SECTIONS.some((s) =>\n        currentSection.toLowerCase().includes(s.toLowerCase())\n      );\n      pendingLabel = null;\n      continue;\n    }\n    if (h3Match) {\n      // Checkpoints / sub-sections \u2014 buffer as a candidate label.\n      if (inTargetSection) {\n        pendingLabel = h3Match[1];\n      }\n      continue;\n    }\n\n    if (!inTargetSection) continue;\n\n    // Skip blank lines and HTML comments\n    const trimmed = line.trim();\n    if (!trimmed || trimmed.startsWith(\"<!--\") || trimmed === \"---\") continue;\n\n    // Include checkbox items, bold text, and plain text lines\n    if (\n      trimmed.startsWith(\"- \") ||\n      trimmed.startsWith(\"* \") ||\n      trimmed.match(/^\\d+\\./) ||\n      trimmed.startsWith(\"**\")\n    ) {\n      const normalized = normalizeLine(trimmed);\n      if (seen.has(normalized)) continue;\n\n      let labelText = \"\";\n      let labelKey = \"\";\n      if (pendingLabel !== null) {\n        labelKey = pendingLabel.toLowerCase().trim();\n        if (!seenLabels.has(labelKey)) {\n          labelText = `[${pendingLabel}]`;\n        }\n      }\n\n      if (charCount + labelText.length + trimmed.length + 2 > maxChars) break;\n\n      if (labelText) {\n        selected.push(labelText);\n        seenLabels.add(labelKey);\n        charCount += labelText.length + 1;\n      }\n      pendingLabel = null;\n\n      seen.add(normalized);\n      selected.push(trimmed);\n      charCount += trimmed.length + 1;\n    }\n  }\n\n  return selected.join(\"\\n\");\n}\n\n/**\n * Build the L1 essential story block.\n *\n * Reads the most recent session notes for the project and extracts the key\n * lines (Work Done, Key Decisions, Next Steps) within the token budget.\n *\n * @param rootPath   The project root path (from the registry).\n * @param tokenBudget  Max tokens to consume. Default 800 (~3200 chars).\n * @returns Formatted L1 block, or empty string if no notes found.\n */\nexport function buildL1EssentialStory(\n  rootPath: string,\n  tokenBudget = L1_TOKEN_BUDGET\n): string {\n  const charBudget = tokenBudget * 4;\n  const notesDir = findNotesDirForProject(rootPath);\n  if (!notesDir) return \"\";\n\n  const noteFiles = findSessionNotes(notesDir).slice(0, L1_MAX_NOTES);\n  if (noteFiles.length === 0) return \"\";\n\n  const sections: string[] = [];\n  const seen = new Set<string>();\n  const seenLabels = new Set<string>();\n  let remaining = charBudget;\n\n  for (const noteFile of noteFiles) {\n    if (remaining <= 50) break;\n\n    let content: string;\n    try {\n      content = readFileSync(noteFile, \"utf-8\");\n    } catch {\n      continue;\n    }\n\n    // Extract the note date and title from the filename\n    const name = basename(noteFile);\n    const titleMatch = name.match(/^\\d+ - (\\d{4}-\\d{2}-\\d{2}) - (.+)\\.md$/);\n    const dateLabel = titleMatch ? titleMatch[1] : \"\";\n    const titleLabel = titleMatch\n      ? titleMatch[2]\n      : name.replace(/^\\d+ - /, \"\").replace(/\\.md$/, \"\");\n\n    // Skip if nothing useful extracted from this note\n    const perNoteChars = Math.min(remaining, Math.floor(charBudget / noteFiles.length) + 200);\n    const extracted = extractKeyLines(content, perNoteChars, seen, seenLabels);\n    // A note whose every extracted line survived only as a label (all its\n    // real lines deduped against an earlier, newer note) contributes nothing\n    // \u2014 including its title.\n    const hasContentLine = extracted\n      .split(\"\\n\")\n      .some((l) => !/^\\[.*\\]$/.test(l));\n    if (!extracted || !hasContentLine) continue;\n\n    const noteBlock = `[${dateLabel} - ${titleLabel}]\\n${extracted}`;\n    sections.push(noteBlock);\n    remaining -= noteBlock.length + 1;\n  }\n\n  if (sections.length === 0) return \"\";\n\n  return sections.join(\"\\n\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Combined: buildWakeupContext\n// ---------------------------------------------------------------------------\n\n/**\n * Build the combined wake-up context block (L0 + L1).\n *\n * Returns a formatted string suitable for injection as a system-reminder,\n * or an empty string if both layers are empty.\n *\n * @param rootPath   Project root path for L1 note lookup. Optional.\n * @param tokenBudget  L1 token budget. Default 800.\n * @param opts.skipStory  Skip the L1 essential story. Set when a handover\n *   checkpoint was already injected \u2014 the story re-summarises the same note\n *   the handover came from, at lower quality.\n */\nexport function buildWakeupContext(\n  rootPath?: string,\n  tokenBudget = L1_TOKEN_BUDGET,\n  opts: { skipStory?: boolean } = {}\n): string {\n  const identity = loadL0Identity();\n  const essentialStory = rootPath && !opts.skipStory\n    ? buildL1EssentialStory(rootPath, tokenBudget)\n    : \"\";\n\n  if (!identity && !essentialStory) return \"\";\n\n  const parts: string[] = [];\n\n  if (identity) {\n    parts.push(`## L0 Identity\\n\\n${identity}`);\n  }\n\n  if (essentialStory) {\n    parts.push(`## L1 Essential Story\\n\\n${essentialStory}`);\n  }\n\n  return parts.join(\"\\n\\n\");\n}\n", "/**\n * Shared \"## Continue\" checkpoint logic for a project's TODO.md.\n *\n * WHY THIS MODULE EXISTS\n * ----------------------\n * Before this, `pause.ts` and `handover.ts` each carried their own copy of\n * findProjectTodo / stripContinueSection / block-builder. Both wrote the same\n * fixed four-line block, and both stripped any existing ## Continue section\n * unconditionally. The consequence was that a rich, model-authored checkpoint\n * could never survive:\n *\n *   1. `pai pause` had no way to accept a body, so the model printed its\n *      checkpoint to the terminal and it was lost.\n *   2. Even if a body had been written by hand, the session-stop hook runs\n *      `pai session handover` on every clean exit, which regenerated the\n *      generic block and erased it.\n *\n * So there are two jobs here:\n *\n *   - AUTHORED writes (`pai pause --body-file`) carry the model's markdown\n *     verbatim, wrapped in explicit start/end markers.\n *   - AUTO writes (hooks) must never destroy an authored checkpoint belonging\n *     to the *same* session. They may replace a stale one left by an earlier\n *     session, otherwise TODO.md would show a checkpoint that no longer\n *     describes where the work stands.\n *\n * PARSING\n * -------\n * A rich body can legitimately contain `---` rules and `##` headings, which the\n * old heuristic scanner treated as section terminators. Authored blocks are\n * therefore delimited by an explicit HTML-comment pair; the legacy heuristic is\n * kept only as a fallback for blocks written before this change.\n */\n\nimport {\n  existsSync,\n  readFileSync,\n  writeFileSync,\n  readdirSync,\n  renameSync,\n  mkdirSync,\n  realpathSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Locations searched for a project TODO.md, in priority order. */\nexport const TODO_LOCATIONS = [\n  \"Notes/TODO.md\",\n  \".claude/Notes/TODO.md\",\n  \"tasks/todo.md\",\n  \"TODO.md\",\n];\n\nexport const MARKER_OPEN = \"<!-- pai:checkpoint\";\nexport const MARKER_CLOSE = \"<!-- /pai:checkpoint -->\";\n\n/**\n * Markers for a handover that has been superseded but not thrown away.\n *\n * Deliberately NOT `pai:checkpoint`: `locateContinue` scans for that marker and\n * for the `## Continue` heading, so an archived block written verbatim would be\n * found as the live section and rewritten in place of it. Archived entries are\n * inert by construction \u2014 different marker, no heading.\n */\nexport const ARCHIVE_OPEN = \"<!-- pai:archived-handover\";\nexport const ARCHIVE_CLOSE = \"<!-- /pai:archived-handover -->\";\nexport const ARCHIVE_HEADING = \"## Previous handovers\";\n\n/**\n * How many superseded handovers TODO.md keeps.\n *\n * Enough that a handover survives a run of sessions that each end without\n * pausing, which is the sequence that destroyed one on 2026-08-04. Not\n * unbounded: TODO.md is read by a human at the top of every session, and a file\n * that grows without limit stops being read, which is its own kind of loss.\n */\nexport const ARCHIVE_LIMIT = 5;\n\nexport const CONTINUE_HEADING = \"## Continue\";\n\n/** Who wrote the checkpoint currently in TODO.md. */\nexport type Authorship = \"model\" | \"auto\";\n\n/** Result of applying a checkpoint. */\nexport type ApplyAction = \"written\" | \"preserved\" | \"failed\";\n\n// ---------------------------------------------------------------------------\n// TODO.md discovery\n// ---------------------------------------------------------------------------\n\nexport function findProjectTodo(\n  rootPath: string\n): { path: string; content: string } | null {\n  for (const rel of TODO_LOCATIONS) {\n    const full = join(rootPath, rel);\n    if (existsSync(full)) {\n      try {\n        return { path: full, content: readFileSync(full, \"utf8\") };\n      } catch {\n        // unreadable \u2014 try next\n      }\n    }\n  }\n  return null;\n}\n\n/**\n * Resolve the TODO.md to write to, creating Notes/ if nothing exists yet.\n * Returns null only when the directory could not be created.\n */\nexport function resolveTodoTarget(\n  rootPath: string,\n  opts: { create?: boolean } = {}\n): { path: string; content: string } | null {\n  const found = findProjectTodo(rootPath);\n  if (found) return found;\n\n  const notesDir = join(rootPath, \"Notes\");\n  if (opts.create !== false) {\n    try {\n      if (!existsSync(notesDir)) mkdirSync(notesDir, { recursive: true });\n    } catch {\n      return null;\n    }\n  }\n  return { path: join(notesDir, \"TODO.md\"), content: \"\" };\n}\n\n// ---------------------------------------------------------------------------\n// Marker parsing\n// ---------------------------------------------------------------------------\n\nexport interface CheckpointMeta {\n  authored: Authorship;\n  /** Session line the checkpoint describes, e.g. \"0003 - 2026-08-01 - Title\". */\n  session?: string;\n  /** Claude Code session UUID, when known. */\n  sessionId?: string;\n  ts?: string;\n}\n\n/**\n * Parse a `<!-- pai:checkpoint key=\"value\" ... -->` marker line.\n * Returns null when the line is not a marker.\n */\nexport function parseMarker(line: string): CheckpointMeta | null {\n  const trimmed = line.trim();\n  if (!trimmed.startsWith(MARKER_OPEN)) return null;\n\n  const attrs: Record<string, string> = {};\n  for (const m of trimmed.matchAll(/([a-zA-Z][\\w-]*)=\"([^\"]*)\"/g)) {\n    attrs[m[1]] = m[2];\n  }\n\n  return {\n    authored: attrs.authored === \"model\" ? \"model\" : \"auto\",\n    session: attrs.session || undefined,\n    sessionId: attrs[\"session-id\"] || undefined,\n    ts: attrs.ts || undefined,\n  };\n}\n\nexport interface LocatedContinue {\n  /** Index of the \"## Continue\" heading line. */\n  startIdx: number;\n  /** Exclusive end index, past any trailing `---` separator. */\n  endIdx: number;\n  meta: CheckpointMeta | null;\n  /** Raw lines of the section, heading included. */\n  lines: string[];\n}\n\n/**\n * Lines an auto-generated block is made of. Anything else in a section is\n * content somebody put there deliberately.\n *\n * The blockquote marker is optional on every pattern. These lines appear\n * quoted when the block builder emits them as its header, and unquoted when a\n * caller passes the same text as a BODY \u2014 which the session-stop hook does: it\n * builds `Working directory: ${cwd}` and hands it over as state. Matching only\n * the quoted form made such a body read as content, which is how a session\n * that did no work at all overwrote a real handover on 2026-08-04. A line that\n * merely restates the generated header is boilerplate wherever it sits.\n */\nconst BOILERPLATE_PATTERNS = [\n  /^##\\s+Continue$/,\n  /^<!--\\s*\\/?pai:checkpoint/,\n  /^>?\\s*\\*\\*Last session:\\*\\*/,\n  /^>?\\s*\\*\\*Paused at:\\*\\*/,\n  /^>?\\s*Working directory:/,\n  /^>?\\s*Resume with:/,\n  /^>?\\s*_No checkpoint body was recorded/,\n  /^-{3,}$/,\n];\n\n/** A blank line, with or without a blockquote marker. */\nconst BLANK_LINE = /^>?\\s*$/;\n\n/**\n * True when a section contains nothing but generated header lines.\n *\n * This is the guard that stops an auto write from destroying content it did\n * not author. A session that hit the old clobbering bug may have worked around\n * it by hand \u2014 writing its state into a subsection underneath the generated\n * header lines, in an unmarked block. Those blocks predate the marker, so\n * authorship cannot be read off them; the only safe signal is whether anything\n * beyond boilerplate is present.\n */\nexport function isBoilerplateOnly(lines: string[]): boolean {\n  return lines.every((line) => {\n    const t = line.trim();\n    return BLANK_LINE.test(t) || BOILERPLATE_PATTERNS.some((re) => re.test(t));\n  });\n}\n\n/**\n * True when a checkpoint body says something the generated header does not.\n *\n * \"Has a body\" and \"has something to say\" are not the same question, and the\n * preservation rules care only about the second. An unattended writer that\n * emits a single line restating the working directory has produced a body by\n * any string test and a handover by none.\n */\nexport function hasSubstance(body: string | null | undefined): boolean {\n  const text = (body ?? \"\").trim();\n  if (!text) return false;\n  return !isBoilerplateOnly(text.split(\"\\n\"));\n}\n\n/**\n * Extract the non-boilerplate content of a section, or \"\" if there is none.\n *\n * Interior blank lines are kept. They are not decoration \u2014 in Markdown they\n * are what separates a paragraph from the table or list that follows, so\n * dropping them (as this did while it treated every blank line as boilerplate)\n * silently welds a checkpoint body into one unreadable run.\n */\nexport function extractSectionContent(lines: string[]): string {\n  const kept: string[] = [];\n  for (const line of lines) {\n    const t = line.trim();\n    if (BOILERPLATE_PATTERNS.some((re) => re.test(t))) continue;\n    kept.push(line);\n  }\n  return trimBlankEdges(collapseBlankRuns(kept)).join(\"\\n\");\n}\n\n/** Drop leading and trailing blank lines, leaving interior spacing alone. */\nfunction trimBlankEdges(lines: string[]): string[] {\n  let start = 0;\n  let end = lines.length;\n  while (start < end && BLANK_LINE.test(lines[start].trim())) start += 1;\n  while (end > start && BLANK_LINE.test(lines[end - 1].trim())) end -= 1;\n  return lines.slice(start, end);\n}\n\n/**\n * Collapse runs of blank lines to a single blank.\n *\n * Removing a boilerplate line leaves the blank that surrounded it behind, so\n * stripping the header can open a three-line gap in the middle of the body.\n * One blank line is all Markdown needs.\n */\nfunction collapseBlankRuns(lines: string[]): string[] {\n  const out: string[] = [];\n  let lastWasBlank = false;\n  for (const line of lines) {\n    const isBlank = BLANK_LINE.test(line.trim());\n    if (isBlank && lastWasBlank) continue;\n    out.push(line);\n    lastWasBlank = isBlank;\n  }\n  return out;\n}\n\n/**\n * Locate the existing ## Continue section.\n *\n * When the section carries an explicit marker pair, the close marker defines\n * the end \u2014 this is what lets a rich body contain `---` and `##` safely.\n * Otherwise the legacy heuristic applies: stop at the first `---` or the next\n * `##` heading.\n */\nexport function locateContinue(content: string): LocatedContinue | null {\n  const lines = content.split(\"\\n\");\n  const startIdx = lines.findIndex((l) => l.trim() === CONTINUE_HEADING);\n  if (startIdx === -1) return null;\n\n  // Look for an open marker in the first few lines of the section.\n  let meta: CheckpointMeta | null = null;\n  let markerIdx = -1;\n  for (let i = startIdx + 1; i < Math.min(startIdx + 6, lines.length); i++) {\n    const parsed = parseMarker(lines[i]);\n    if (parsed) {\n      meta = parsed;\n      markerIdx = i;\n      break;\n    }\n    // A non-blank, non-marker line means there is no marker for this section.\n    if (lines[i].trim() !== \"\") break;\n  }\n\n  let endIdx = lines.length;\n\n  if (markerIdx !== -1) {\n    const closeIdx = lines.findIndex(\n      (l, i) => i > markerIdx && l.trim() === MARKER_CLOSE\n    );\n    if (closeIdx !== -1) {\n      endIdx = closeIdx + 1;\n    } else {\n      // Malformed (open without close) \u2014 fall back to the heuristic so we do\n      // not swallow the rest of the file.\n      endIdx = heuristicEnd(lines, startIdx);\n    }\n  } else {\n    endIdx = heuristicEnd(lines, startIdx);\n  }\n\n  // Consume one trailing `---` separator and the blank lines around it.\n  let trailingEnd = endIdx;\n  while (trailingEnd < lines.length && lines[trailingEnd].trim() === \"\") {\n    trailingEnd += 1;\n  }\n  if (trailingEnd < lines.length && lines[trailingEnd].trim() === \"---\") {\n    trailingEnd += 1;\n  } else {\n    trailingEnd = endIdx;\n  }\n\n  return {\n    startIdx,\n    endIdx: trailingEnd,\n    meta,\n    lines: lines.slice(startIdx, trailingEnd),\n  };\n}\n\n/**\n * Legacy scanner for blocks written before checkpoint markers existed.\n *\n * Terminates on a horizontal rule or the next level-1 or level-2 heading. Note\n * the `(?!#)` \u2014 `###` is a *subsection* of `## Continue`, not a terminator. The\n * original scanner stopped at any run of `#`, which meant a `### Restored\n * state` subsection fell outside the section entirely and could not be seen,\n * let alone carried forward.\n *\n * `#{1,2}` rather than `##`, because matching only `##` did not stop at an H1\n * and therefore ATE IT. A TODO.md whose `## Continue` block precedes its\n * `# TODO` title had the title absorbed into the section and destroyed on the\n * next regenerate \u2014 reported independently by three sessions on 2026-08-03,\n * one of which lost it three times and recovered from git each time.\n *\n * An H1 is a document-level heading. It can never be part of a `## Continue`\n * section, so treating it as a terminator is not a heuristic improvement but a\n * structural fact.\n */\nfunction heuristicEnd(lines: string[], startIdx: number): number {\n  for (let i = startIdx + 1; i < lines.length; i++) {\n    const trimmed = lines[i].trim();\n    if (\n      trimmed === \"---\" ||\n      (/^#{1,2}(?!#)/.test(trimmed) && trimmed !== CONTINUE_HEADING)\n    ) {\n      return i;\n    }\n  }\n  return lines.length;\n}\n\n/** Remove the ## Continue section, returning the remainder of the document. */\nexport function stripContinue(content: string): string {\n  const found = locateContinue(content);\n  if (!found) return content;\n\n  const lines = content.split(\"\\n\");\n  const before = lines.slice(0, found.startIdx);\n  const after = lines.slice(found.endIdx);\n  while (after.length > 0 && after[0].trim() === \"\") after.shift();\n\n  return [...before, ...after].join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Reading a checkpoint back\n// ---------------------------------------------------------------------------\n\nexport interface ContinueCheckpoint {\n  meta: CheckpointMeta | null;\n  /** The authored body \u2014 the section with generated header lines removed. */\n  body: string;\n  /** The full section, heading included. */\n  raw: string;\n}\n\n/**\n * Read the `## Continue` checkpoint out of a TODO.md.\n *\n * Writing a checkpoint is only half of a handover; something has to deliver it\n * to the next session. This is the read side, used by the SessionStart hook.\n *\n * Returns null when there is no section, or when the section holds nothing but\n * generated header lines \u2014 a bodyless block carries no information a new\n * session does not already have, and injecting it would only add noise.\n */\nexport function readContinueCheckpoint(\n  content: string\n): ContinueCheckpoint | null {\n  const found = locateContinue(content);\n  if (!found) return null;\n\n  const body = found.meta\n    ? extractMarkedBody(found.lines)\n    : extractSectionContent(found.lines);\n  if (!body) return null;\n\n  return { meta: found.meta, body, raw: found.lines.join(\"\\n\") };\n}\n\n/**\n * Extract the body of a marker-delimited block by position rather than by\n * pattern.\n *\n * The layout is fixed: open marker, a contiguous run of `>` header lines, the\n * body, then the close marker. Because the boundaries are known exactly, the\n * body comes back byte-for-byte \u2014 including any `---` rules or `##` headings\n * of its own, which a pattern-based filter would mistake for boilerplate and\n * delete. Falls back to the pattern filter if the shape is not as expected.\n */\nfunction extractMarkedBody(lines: string[]): string {\n  const markerIdx = lines.findIndex((l) => parseMarker(l) !== null);\n  if (markerIdx === -1) return extractSectionContent(lines);\n\n  const closeIdx = lines.findIndex(\n    (l, i) => i > markerIdx && l.trim() === MARKER_CLOSE\n  );\n  if (closeIdx === -1) return extractSectionContent(lines);\n\n  // Skip the blank lines and the `>` header run that follow the open marker.\n  let bodyStart = markerIdx + 1;\n  while (bodyStart < closeIdx) {\n    const t = lines[bodyStart].trim();\n    if (BLANK_LINE.test(t) || t.startsWith(\">\")) {\n      bodyStart += 1;\n      continue;\n    }\n    break;\n  }\n\n  return trimBlankEdges(lines.slice(bodyStart, closeIdx)).join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Block construction\n// ---------------------------------------------------------------------------\n\nexport interface BuildOptions {\n  authored: Authorship;\n  /** Human-readable session line, or \"Unknown session\". */\n  sessionLine: string;\n  /** Claude Code session UUID \u2014 the `claude --resume` handle. */\n  sessionId?: string;\n  cwd: string;\n  /** Model-authored markdown. Omitted for auto blocks. */\n  body?: string;\n  /** Overridable for deterministic tests. */\n  timestamp?: string;\n}\n\nfunction escapeAttr(value: string): string {\n  return value.replace(/\"/g, \"'\");\n}\n\nexport function buildContinueBlock(opts: BuildOptions): string {\n  const ts = opts.timestamp ?? new Date().toISOString();\n\n  const attrs = [\n    `authored=\"${opts.authored}\"`,\n    `session=\"${escapeAttr(opts.sessionLine)}\"`,\n    opts.sessionId ? `session-id=\"${escapeAttr(opts.sessionId)}\"` : null,\n    `ts=\"${ts}\"`,\n  ]\n    .filter(Boolean)\n    .join(\" \");\n\n  const header = [\n    `> **Last session:** ${opts.sessionLine}`,\n    `> **Paused at:** ${ts}`,\n    \">\",\n    `> Working directory: ${opts.cwd}`,\n  ];\n\n  if (opts.sessionId) {\n    header.push(\">\", `> Resume with: \\`claude --resume ${opts.sessionId}\\``);\n  }\n\n  const body = (opts.body ?? \"\").trim();\n\n  const parts = [\n    CONTINUE_HEADING,\n    \"\",\n    `${MARKER_OPEN} ${attrs} -->`,\n    \"\",\n    ...header,\n  ];\n\n  if (body) {\n    parts.push(\"\", body);\n  } else {\n    parts.push(\n      \">\",\n      \"> _No checkpoint body was recorded \u2014 see the latest session note._\"\n    );\n  }\n\n  parts.push(\"\", MARKER_CLOSE, \"\", \"---\", \"\");\n\n  return parts.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Apply\n// ---------------------------------------------------------------------------\n\nexport interface ApplyOptions extends BuildOptions {\n  /** Project root; TODO.md is resolved beneath it. */\n  rootPath: string;\n  /** Preview only \u2014 nothing is written. */\n  dryRun?: boolean;\n}\n\nexport interface ApplyResult {\n  action: ApplyAction;\n  path: string | null;\n  block: string;\n  /** Set when action === \"preserved\". */\n  preservedMeta?: CheckpointMeta;\n  /** Set when unattributed content was carried forward into the new block. */\n  carriedForward?: boolean;\n  /** Set when a superseded model-authored handover was moved to the archive. */\n  archived?: boolean;\n  error?: string;\n}\n\n/**\n * Write the ## Continue block, honouring the preservation rules.\n *\n * An AUTO write is unattended \u2014 it fires from the session-stop and pre-compact\n * hooks \u2014 so it operates under one governing rule: **never destroy content it\n * did not author.** Three cases follow from that:\n *\n *   1. An authored checkpoint for the SAME session is left untouched. The hooks\n *      fire after the model has already recorded the real state; overwriting it\n *      with metadata is the bug this module exists to fix.\n *\n *      \"Same session\" is decided by the Claude session UUID whenever both sides\n *      know it, and only falls back to the human-readable session line when one\n *      of them does not. The line is derived from the session note filename,\n *      and `session-stop.sh` *renames and renumbers that file* \u2014 via `session\n *      slug --apply` and `session cleanup --execute` \u2014 before it reaches the\n *      handover step. So the key the hook computes at exit is not the key the\n *      model wrote seconds earlier, and a filename-keyed comparison mismatches\n *      by construction. Observed live on 2026-08-01: notes renumbered twice\n *      within a single session. The UUID is the only identifier that holds\n *      still.\n *   2. An authored checkpoint from an EARLIER session is stale \u2014 TODO.md would\n *      otherwise keep pointing at the wrong session \u2014 so it is replaced. Its\n *      content is not lost: `pai pause` mirrors every authored body into the\n *      session note.\n *   3. An UNMARKED block predates the marker, so authorship cannot be read off\n *      it. If it is nothing but generated header lines it is replaced. If it\n *      carries anything else, that content was put there deliberately \u2014 quite\n *      possibly as a hand-rolled workaround for the very clobbering this fixes \u2014\n *      and is carried forward into the new block rather than dropped.\n *\n * A MODEL write always replaces: the model is authoring the checkpoint, and a\n * newer one supersedes an older one.\n */\n/**\n * Do an existing checkpoint and an incoming write describe the same session?\n *\n * The UUID is authoritative when both sides carry one: it is assigned by Claude\n * Code and never changes for the life of the session. The session line is a\n * derived, mutable label and is only consulted when there is no UUID to compare\n * \u2014 a checkpoint written before `--session-id` was threaded through, or an auto\n * write from a caller that was not given one.\n */\nfunction isSameSession(\n  meta: CheckpointMeta,\n  opts: Pick<ApplyOptions, \"sessionId\" | \"sessionLine\">\n): boolean {\n  if (meta.sessionId && opts.sessionId) {\n    return meta.sessionId === opts.sessionId;\n  }\n  return meta.session === opts.sessionLine;\n}\n\n/**\n * How long a model-authored checkpoint is protected from automated overwriting.\n *\n * Sized for the race, not for the session: the gap between a model writing its\n * checkpoint and a hook firing is seconds to minutes, and an hour covers even a\n * slow checkpoint on a loaded machine. Anything genuinely from an earlier\n * session is hours or days old and still falls through to case 2, which is what\n * keeps TODO.md from freezing on a checkpoint nobody will ever replace.\n */\nconst AUTHORED_GRACE_MS = 60 * 60 * 1000;\n\n/** Was this checkpoint written recently enough to still belong to the run in progress? */\nfunction isRecent(meta: CheckpointMeta, now?: string): boolean {\n  if (!meta.ts) return false; // no stamp, no claim \u2014 case 2 decides as before\n  const then = Date.parse(meta.ts);\n  if (Number.isNaN(then)) return false;\n  const nowMs = now ? Date.parse(now) : Date.now();\n  if (Number.isNaN(nowMs)) return false;\n  // Guard the future too: a clock skew that puts the stamp ahead of now must\n  // not read as \"very old\" and license an overwrite.\n  return nowMs - then < AUTHORED_GRACE_MS;\n}\n\n/**\n * Turn a live checkpoint block into an inert archive entry.\n *\n * Two things have to go: the `## Continue` heading and the `pai:checkpoint`\n * marker. Both are what `locateContinue` looks for, so leaving either in place\n * would let a later write treat the archive as the live section \u2014 and the next\n * one after that would then archive the archive. Everything else is kept\n * verbatim, because the body is the whole reason this exists.\n */\nfunction toArchiveEntry(lines: string[], meta: CheckpointMeta | null): string[] {\n  const out: string[] = [];\n  const label = meta?.session ?? \"Unknown session\";\n  const stamp = meta?.ts ? ` \u2014 checkpointed ${meta.ts}` : \"\";\n  out.push(`${ARCHIVE_OPEN} session=\"${label}\"${meta?.ts ? ` ts=\"${meta.ts}\"` : \"\"} -->`);\n  out.push(\"\");\n  out.push(`### ${label}${stamp}`);\n  out.push(\"\");\n  for (const line of lines) {\n    if (line.trim() === CONTINUE_HEADING) continue;\n    if (line.trim().startsWith(MARKER_OPEN)) continue;\n    if (line.trim() === MARKER_CLOSE) continue;\n    if (line.trim() === \"---\") continue;\n    out.push(line);\n  }\n  while (out.length > 0 && out[out.length - 1].trim() === \"\") out.pop();\n  out.push(\"\");\n  out.push(ARCHIVE_CLOSE);\n  return out;\n}\n\n/**\n * Put a superseded handover into the archive section, newest first.\n *\n * `rest` is the document with the Continue section already stripped. The\n * archive lives immediately below it so a reader meets the current handover\n * first and the previous ones directly after, rather than hunting for them at\n * the bottom of a file that also holds the project's open work.\n */\nfunction archiveInto(rest: string, entry: string[]): string {\n  const lines = rest.split(\"\\n\");\n  const headingIdx = lines.findIndex((l) => l.trim() === ARCHIVE_HEADING);\n\n  if (headingIdx === -1) {\n    return [ARCHIVE_HEADING, \"\", ...entry, \"\", \"---\", \"\", rest.trimStart()].join(\"\\n\");\n  }\n\n  // Insert directly under the heading, then drop whatever falls past the cap.\n  const before = lines.slice(0, headingIdx + 1);\n  const after = lines.slice(headingIdx + 1);\n  while (after.length > 0 && after[0].trim() === \"\") after.shift();\n\n  const merged = [...entry, \"\", ...after];\n  const kept: string[] = [];\n  let seen = 0;\n  for (let i = 0; i < merged.length; i++) {\n    if (merged[i].trim().startsWith(ARCHIVE_OPEN)) {\n      seen += 1;\n      if (seen > ARCHIVE_LIMIT) {\n        // Everything from here to the end of THIS entry goes; keep scanning so\n        // anything after the archive section (other headings, open work) stays.\n        while (i < merged.length && merged[i].trim() !== ARCHIVE_CLOSE) i++;\n        continue; // skips the close marker too\n      }\n    }\n    kept.push(merged[i]);\n  }\n  return [...before, \"\", ...kept].join(\"\\n\");\n}\n\nexport function applyContinue(opts: ApplyOptions): ApplyResult {\n  const target = resolveTodoTarget(opts.rootPath, { create: !opts.dryRun });\n  if (!target) {\n    return {\n      action: \"failed\",\n      path: null,\n      block: buildContinueBlock(opts),\n      error: \"Could not resolve or create a TODO.md target\",\n    };\n  }\n\n  const existing = locateContinue(target.content);\n  let carriedForward = false;\n  let effectiveBody = opts.body;\n  let archiveEntry: string[] | null = null;\n\n  if (opts.authored === \"auto\" && existing) {\n    // Case 1 \u2014 authored, same session: hands off.\n    if (existing.meta?.authored === \"model\" && isSameSession(existing.meta, opts)) {\n      return {\n        action: \"preserved\",\n        path: target.path,\n        block: buildContinueBlock(opts),\n        preservedMeta: existing.meta,\n      };\n    }\n\n    // Case 1b \u2014 the incoming write has nothing to say, and what is already\n    // there does. A metadata-only block says \"see the latest session note\", so\n    // replacing a real handover with one trades content for a pointer \u2014 and the\n    // pointer is not always good: observed live on 2026-08-01 in the AIBroker\n    // project, where the stop hook's bodyless handover overwrote the autosave's\n    // body and named a session note that had never been created, leaving the\n    // next session nothing to resume from.\n    //\n    // Deferring to the session note is only safe when the note demonstrably has\n    // the content. This code cannot see that, so it does the one thing that is\n    // never wrong: a write with nothing to say does not get to destroy\n    // something that does. A stale-but-real handover beats a fresh dead link.\n    // Scoped to blocks we marked. An unmarked block falls through to case 3,\n    // which salvages its content into the new block rather than freezing the\n    // old one \u2014 better, because an unmarked block has no session metadata worth\n    // preserving and may predate this scheme entirely.\n    //\n    // The test is SUBSTANCE, not emptiness. It was emptiness until 2026-08-04,\n    // when a session that was opened and immediately exited destroyed the\n    // previous day's handover for every project it touched. Its stop hook found\n    // no work items and no completion message, so it sent the one line it\n    // always builds unconditionally \u2014 `Working directory: \u2026`, a verbatim copy\n    // of a line the header already generates. Non-empty by a string test, so\n    // this guard stood down; worthless by any other reading. `hasSubstance`\n    // asks the question the comment above always claimed to be asking.\n    if (\n      existing.meta &&\n      !hasSubstance(opts.body) &&\n      !isBoilerplateOnly(existing.lines)\n    ) {\n      return {\n        action: \"preserved\",\n        path: target.path,\n        block: buildContinueBlock(opts),\n        preservedMeta: existing.meta ?? undefined,\n      };\n    }\n\n    // Case 2b \u2014 a model checkpoint written moments ago is THIS session's,\n    // whatever the identity comparison says.\n    //\n    // Case 2 deliberately lets an auto write replace an authored checkpoint\n    // from an EARLIER session, and that policy is right: TODO.md would freeze\n    // otherwise, and `pai pause` mirrors authored bodies into the session note.\n    // The bug is not the policy, it is that identity DEGRADES and healthy\n    // sessions fall into it.\n    //\n    // `sessionId` is optional on `pai pause`. Without it isSameSession compares\n    // a display line containing the note TITLE \u2014 and pausing renames the note.\n    // So a session writes a checkpoint, its note is renamed, the hook fires\n    // seconds later, no longer recognises its own work, and classifies it as a\n    // stale earlier session. Three sessions reported exactly this on\n    // 2026-08-03 from one `pai pause all`; one lost its checkpoint three times\n    // and recovered from git each time. Sessions without a clean repo would\n    // never have known it happened.\n    //\n    // Recency is the tiebreaker that identity cannot supply. A model checkpoint\n    // minutes old is not a stale predecessor by any reading, so an automated\n    // digest does not get to overwrite it. Older ones still fall through to\n    // case 2 and are replaced as before, which is what stops TODO.md freezing\n    // and keeps this from nesting carried-forward blocks without end.\n    if (\n      existing.meta?.authored === \"model\" &&\n      isRecent(existing.meta, opts.timestamp) &&\n      !isBoilerplateOnly(existing.lines)\n    ) {\n      return {\n        action: \"preserved\",\n        path: target.path,\n        block: buildContinueBlock(opts),\n        preservedMeta: existing.meta,\n      };\n    }\n\n    // Case 2c \u2014 an authored handover from an EARLIER session, past the grace\n    // window. Case 2 deleted it, on the reasoning that TODO.md must not freeze\n    // and that `pai pause` mirrors authored bodies into the session note.\n    //\n    // The first half is right. The second is an assumption, and on 2026-08-04\n    // it was false in the plainest way available: this project keeps no session\n    // notes at all (`Notes/*` is gitignored and none exist on disk), so the\n    // checkpoint WAS the only copy. It went at 08:36:29Z, to the autosave of a\n    // session that had been open for sixteen minutes and had typed one line \u2014\n    // destroying, as its first act, the handover it had been started to read.\n    //\n    // This is also the escape the v0.27.2 guard could not close: that one asks\n    // whether the block is RECENT, and a handover written the night before is\n    // not. Age was never the question. Nothing here needs the old block gone;\n    // it only needs the slot. So the block moves down the file instead, and the\n    // freeze argument and the loss argument stop being in tension.\n    //\n    // Only for `model` blocks with something in them. An auto block is a\n    // transcript scrape that regenerates on the next tick, and archiving those\n    // would bury the real handovers under mechanical noise.\n    if (\n      existing.meta?.authored === \"model\" &&\n      !isBoilerplateOnly(existing.lines) &&\n      !isSameSession(existing.meta, opts)\n    ) {\n      archiveEntry = toArchiveEntry(existing.lines, existing.meta);\n    }\n\n    // Case 3 \u2014 unmarked block holding content nobody can attribute to us.\n    if (!existing.meta && !isBoilerplateOnly(existing.lines)) {\n      const salvaged = extractSectionContent(existing.lines);\n      if (salvaged) {\n        effectiveBody = [\n          \"_Carried forward from the previous checkpoint (author unknown \u2014 this\",\n          \"block predates checkpoint authorship markers):_\",\n          \"\",\n          salvaged,\n        ].join(\"\\n\");\n        carriedForward = true;\n      }\n    }\n  }\n\n  const block = buildContinueBlock({ ...opts, body: effectiveBody });\n\n  if (opts.dryRun) {\n    return { action: \"written\", path: target.path, block, carriedForward, archived: !!archiveEntry };\n  }\n\n  const rest = stripContinue(target.content).trimStart();\n  const newContent = block + (archiveEntry ? archiveInto(rest, archiveEntry) : rest);\n  const tmpPath = `${target.path}.continue.tmp`;\n\n  try {\n    writeFileSync(tmpPath, newContent, \"utf8\");\n    renameSync(tmpPath, target.path);\n  } catch (err) {\n    try {\n      if (existsSync(tmpPath)) renameSync(tmpPath, `${tmpPath}.dead`);\n    } catch {\n      /* ignore */\n    }\n    return {\n      action: \"failed\",\n      path: target.path,\n      block,\n      error: String(err),\n    };\n  }\n\n  return { action: \"written\", path: target.path, block, carriedForward, archived: !!archiveEntry };\n}\n\n// ---------------------------------------------------------------------------\n// Session-note discovery\n//\n// Lifted verbatim from end.ts so pause, end and any future caller share one\n// implementation. end.ts now imports these rather than carrying its own copy.\n// ---------------------------------------------------------------------------\n\n/** ADAPTER_DIR (harness adapter root) \u2014 mirrors pai-paths.ts's resolveAdapterDir(),\n *  kept self-contained here to avoid importing pai-paths.ts's process.exit(1)\n *  validation side effect. PAI_DIR is the deprecated alias, same as there. */\nfunction getPaiDir(): string {\n  const envDir = process.env.ADAPTER_DIR || process.env.PAI_DIR;\n  if (envDir) {\n    try {\n      return realpathSync(envDir);\n    } catch {\n      return envDir;\n    }\n  }\n  return join(homedir(), \".claude\");\n}\n\n/**\n * Find the notes directory for a project \u2014 local first, then the central\n * ~/.claude/projects/<encoded>/Notes fallback. Never creates.\n */\nexport function findNotesDir(\n  rootPath: string,\n  encodedDir: string\n): string | null {\n  for (const rel of [\"Notes\", \"notes\", \".claude/Notes\"]) {\n    const p = join(rootPath, rel);\n    if (existsSync(p)) return p;\n  }\n  const central = join(getPaiDir(), \"projects\", encodedDir, \"Notes\");\n  if (existsSync(central)) return central;\n  return null;\n}\n\n/**\n * Find the current (highest-numbered) session note: current month, then the\n * previous month, then a flat notesDir as legacy fallback.\n */\nexport function findLatestNote(notesDir: string): string | null {\n  const findIn = (dir: string): string | null => {\n    if (!existsSync(dir)) return null;\n    let files: string[];\n    try {\n      files = readdirSync(dir);\n    } catch {\n      return null;\n    }\n    const notes = files\n      .filter((f) => /^\\d{3,4}[\\s_-].*\\.md$/.test(f))\n      .sort((a, b) => {\n        const na = parseInt(a.match(/^(\\d+)/)?.[1] ?? \"0\", 10);\n        const nb = parseInt(b.match(/^(\\d+)/)?.[1] ?? \"0\", 10);\n        return na - nb;\n      });\n    return notes.length > 0 ? join(dir, notes[notes.length - 1]) : null;\n  };\n\n  const now = new Date();\n  const year = String(now.getFullYear());\n  const month = String(now.getMonth() + 1).padStart(2, \"0\");\n\n  const current = findIn(join(notesDir, year, month));\n  if (current) return current;\n\n  const prev = new Date(now.getFullYear(), now.getMonth() - 1, 1);\n  const py = String(prev.getFullYear());\n  const pm = String(prev.getMonth() + 1).padStart(2, \"0\");\n  const prevFound = findIn(join(notesDir, py, pm));\n  if (prevFound) return prevFound;\n\n  return findIn(notesDir);\n}\n\n// ---------------------------------------------------------------------------\n// Session-note append\n// ---------------------------------------------------------------------------\n\n/**\n * Append the checkpoint body to a session note.\n *\n * TODO.md's ## Continue is a single slot that every later checkpoint\n * overwrites. The session note is the durable record, so the body goes to both.\n * Idempotent per timestamp: re-running with the same stamp will not duplicate.\n */\nexport function appendCheckpointToNote(\n  notePath: string,\n  body: string,\n  timestamp?: string\n): { appended: boolean; error?: string } {\n  const ts = timestamp ?? new Date().toISOString();\n  const heading = `## Pause Checkpoint \u2014 ${ts}`;\n\n  let existing: string;\n  try {\n    existing = readFileSync(notePath, \"utf8\");\n  } catch (err) {\n    return { appended: false, error: String(err) };\n  }\n\n  if (existing.includes(heading)) return { appended: false };\n\n  const block = `\\n\\n---\\n\\n${heading}\\n\\n${body.trim()}\\n`;\n  const tmpPath = `${notePath}.checkpoint.tmp`;\n\n  try {\n    writeFileSync(tmpPath, existing.trimEnd() + block, \"utf8\");\n    renameSync(tmpPath, notePath);\n  } catch (err) {\n    try {\n      if (existsSync(tmpPath)) renameSync(tmpPath, `${tmpPath}.dead`);\n    } catch {\n      /* ignore */\n    }\n    return { appended: false, error: String(err) };\n  }\n\n  return { appended: true };\n}\n\n// ---------------------------------------------------------------------------\n// Body loading\n// ---------------------------------------------------------------------------\n\n/** Read a checkpoint body from a file, or from stdin when path is \"-\". */\nexport function readBodyFile(path: string): string {\n  if (path === \"-\") {\n    return readFileSync(0, \"utf8\");\n  }\n  return readFileSync(path, \"utf8\");\n}\n", "/**\n * handover-budget.ts \u2014 cap the `## Continue` handover body injected at\n * SessionStart.\n *\n * Text tokenises at ~2.6 chars per token; a 1,600-char budget is ~620 tokens.\n * Together with the hook's 117-token fixed part, this stays under the 1,000-token\n * SessionStart limit, eliding retrospective `d=` (done) and `t=` (tests) fields\n * while preserving `g=` (goal), `@n` file pointers, and `z=` (state).\n */\n\nexport const HANDOVER_CHAR_BUDGET = 1600;\n\nexport interface BudgetResult {\n  body: string;\n  elided: string[];\n  truncated: boolean;\n}\n\ninterface Field {\n  key: string;\n  lines: string[];\n}\n\nconst FIELD_START = /^([a-zA-Z@][a-zA-Z0-9]*)=/;\n\nfunction splitFields(body: string): { preamble: string[]; fields: Field[] } {\n  const lines = body.split(\"\\n\");\n  const preamble: string[] = [];\n  const fields: Field[] = [];\n  let current: Field | null = null;\n  for (const line of lines) {\n    const m = line.match(FIELD_START);\n    if (m) {\n      current = { key: m[1], lines: [line] };\n      fields.push(current);\n    } else if (current) {\n      current.lines.push(line);\n    } else {\n      preamble.push(line);\n    }\n  }\n  return { preamble, fields };\n}\n\nfunction elisionLine(key: string, charCount: number, sourcePath: string): string {\n  return `${key}= elided, ${charCount} chars; full text in ${sourcePath} (## Continue)`;\n}\n\nfunction render(preamble: string[], fields: Field[]): string {\n  const parts = [...preamble];\n  for (const f of fields) parts.push(...f.lines);\n  return parts.join(\"\\n\");\n}\n\n/**\n * Elide the `d=` and `t=` fields (in that order, only while still over\n * budget) before falling back to a hard truncation \u2014 those two fields are\n * retrospective, everything else (`g=`, `@n` pointers, `z=`) is what a\n * resumer actually needs.\n */\nexport function applyHandoverBudget(\n  body: string,\n  sourcePath: string,\n  budget: number = HANDOVER_CHAR_BUDGET\n): BudgetResult {\n  if (body.length <= budget) {\n    return { body, elided: [], truncated: false };\n  }\n\n  const { preamble, fields } = splitFields(body);\n  const elided: string[] = [];\n\n  if (fields.length > 0) {\n    for (const key of [\"d\", \"t\"]) {\n      if (render(preamble, fields).length <= budget) break;\n      const field = fields.find((f) => f.key === key);\n      if (!field) continue;\n      const charCount = field.lines.join(\"\\n\").length;\n      field.lines = [elisionLine(key, charCount, sourcePath)];\n      elided.push(key);\n    }\n  }\n\n  const result = render(preamble, fields);\n  if (fields.length === 0 || result.length > budget) {\n    const source = fields.length === 0 ? body : result;\n    const truncated =\n      source.slice(0, budget) +\n      `\\n[handover truncated at ${budget} chars; full text in ${sourcePath} (## Continue)]`;\n    return { body: truncated, elided, truncated: true };\n  }\n\n  return { body: result, elided, truncated: false };\n}\n", "/**\n * PAI Path Resolution - Single Source of Truth\n *\n * This module provides consistent path resolution across all PAI hooks.\n *\n * Two different things live here, and they must not be confused:\n *\n * - ADAPTER_DIR (~/.claude by default) is the Claude Code harness adapter \u2014\n *   fixed, hardcoded paths the harness itself loads from (Hooks/, skills/,\n *   agents/, commands/, settings.json, statusline-command.sh,\n *   tab-color-command.sh). It is harness-specific: a future harness would\n *   need its own adapter directory with its own conventions.\n * - PAI_HOME (~/.claude/pai by default \u2014 see ../../../config/pai-home.ts) is\n *   where PAI's own state lives: everything hooks WRITE (History/,\n *   agent-sessions.json, session-routing.json, ...) resolves there, with a\n *   fallback to the pre-2026-09-19 ADAPTER_DIR location and a one-time\n *   stderr notice, exactly like every other PAI_HOME file.\n *\n * ALSO loads .env file from ADAPTER_DIR so all hooks get environment\n * variables without relying on Claude Code's settings.json injection.\n *\n * Usage in hooks:\n *   import { ADAPTER_DIR, HOOKS_DIR, SKILLS_DIR, historyDir } from './lib/pai-paths';\n */\n\nimport { homedir } from 'os';\nimport { resolve, join } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport {\n  paiHomePath,\n  resolvePaiFile,\n  migratePaiFile,\n  migratePaiDir,\n  type MigrateFileResult,\n  type MigrateDirResult,\n} from '../../../config/pai-home.js';\n\n/**\n * Load .env file and inject into process.env\n * Must run BEFORE ADAPTER_DIR resolution so .env can set ADAPTER_DIR/PAI_DIR if needed\n */\nfunction loadEnvFile(): void {\n  // Check common locations for .env\n  const possiblePaths = [\n    resolve(process.env.ADAPTER_DIR || process.env.PAI_DIR || '', '.env'),\n    resolve(homedir(), '.claude', '.env'),\n  ];\n\n  for (const envPath of possiblePaths) {\n    if (existsSync(envPath)) {\n      try {\n        const content = readFileSync(envPath, 'utf-8');\n        for (const line of content.split('\\n')) {\n          const trimmed = line.trim();\n          // Skip comments and empty lines\n          if (!trimmed || trimmed.startsWith('#')) continue;\n\n          const eqIndex = trimmed.indexOf('=');\n          if (eqIndex > 0) {\n            const key = trimmed.substring(0, eqIndex).trim();\n            let value = trimmed.substring(eqIndex + 1).trim();\n\n            // Remove surrounding quotes if present\n            if ((value.startsWith('\"') && value.endsWith('\"')) ||\n                (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n              value = value.slice(1, -1);\n            }\n\n            // Expand $HOME and ~ in values\n            value = value.replace(/\\$HOME/g, homedir());\n            value = value.replace(/^~(?=\\/|$)/, homedir());\n\n            // Only set if not already defined (env vars take precedence)\n            if (process.env[key] === undefined) {\n              process.env[key] = value;\n            }\n          }\n        }\n        // Found and loaded, don't check other paths\n        break;\n      } catch {\n        // Silently continue if .env can't be read\n      }\n    }\n  }\n}\n\n// Load .env FIRST, before any other initialization\nloadEnvFile();\n\nfunction defaultAdapterDir(): string {\n  return resolve(homedir(), '.claude');\n}\n\n/**\n * Never print when stdout/stderr is a data channel, not a human: hook\n * bundles and worker-status-line.mjs set PAI_QUIET_NOTICES=1 via their\n * esbuild banner (scripts/build-hooks.mjs), and a `pai worker run\n * --output-format json` invocation is detected directly off argv since its\n * env can't be set before this module's static imports resolve.\n */\nfunction suppressDeprecationNotices(): boolean {\n  if (process.env.PAI_QUIET_NOTICES === '1') return true;\n  const idx = process.argv.indexOf('--output-format');\n  return idx !== -1 && process.argv[idx + 1] === 'json';\n}\n\n/**\n * At most once per process \u2014 a `globalThis` flag rather than a module-level\n * `let` because hooks and the CLI can end up with more than one instance of\n * this module loaded into the same process (separate bundles), each with its\n * own module scope; only a property on the shared global survives that.\n */\nfunction warnPaiDirDeprecatedOnce(message: string): void {\n  const g = globalThis as typeof globalThis & { __paiDirNoticePrinted?: boolean };\n  if (g.__paiDirNoticePrinted || suppressDeprecationNotices()) return;\n  g.__paiDirNoticePrinted = true;\n  process.stderr.write(`pai: ${message}\\n`);\n}\n\n/**\n * Smart ADAPTER_DIR detection with fallback\n * Priority:\n * 1. ADAPTER_DIR environment variable (if set) \u2014 warns once if PAI_DIR is\n *    ALSO set and resolves to a different path (naming both).\n * 2. PAI_DIR environment variable (deprecated alias, one release) \u2014 warns\n *    once only when it differs from the default adapter root; PAI_DIR set to\n *    the same value as the default is the operator's current, correct\n *    setting and stays silent.\n * 3. ~/.claude (standard location)\n */\nfunction resolveAdapterDir(): string {\n  if (process.env.ADAPTER_DIR) {\n    const adapterDir = resolve(process.env.ADAPTER_DIR);\n    if (process.env.PAI_DIR) {\n      const paiDir = resolve(process.env.PAI_DIR);\n      if (paiDir !== adapterDir) {\n        warnPaiDirDeprecatedOnce(\n          `ADAPTER_DIR (${adapterDir}) and PAI_DIR (${paiDir}) are both set and differ \u2014 ADAPTER_DIR wins. PAI_DIR still works for one release.`\n        );\n      }\n    }\n    return adapterDir;\n  }\n  if (process.env.PAI_DIR) {\n    const paiDir = resolve(process.env.PAI_DIR);\n    if (paiDir !== defaultAdapterDir()) {\n      warnPaiDirDeprecatedOnce(\n        'PAI_DIR is deprecated \u2014 use ADAPTER_DIR for the harness adapter root (~/.claude). PAI_DIR still works for one release.'\n      );\n    }\n    return paiDir;\n  }\n  return defaultAdapterDir();\n}\n\n/** The Claude Code harness adapter root \u2014 NOT PAI's state home. See module doc above. */\nexport const ADAPTER_DIR = resolveAdapterDir();\n\n/** @deprecated alias for ADAPTER_DIR, kept for one release. Prefer ADAPTER_DIR. */\nexport const PAI_DIR = ADAPTER_DIR;\n\n/**\n * Adapter directories \u2014 fixed paths the Claude Code harness itself loads\n * from. These stay under ADAPTER_DIR; they are not PAI state.\n */\nexport const HOOKS_DIR = join(ADAPTER_DIR, 'Hooks');\nexport const SKILLS_DIR = join(ADAPTER_DIR, 'skills');\nexport const AGENTS_DIR = join(ADAPTER_DIR, 'agents');\nexport const COMMANDS_DIR = join(ADAPTER_DIR, 'commands');\n\n// ---------------------------------------------------------------------------\n// PAI state written by hooks \u2014 resolves under PAI_HOME, falling back to the\n// pre-2026-09-19 ADAPTER_DIR location (one-time stderr notice) until\n// `pai config migrate --history` moves it. Actively written on every hook\n// event across every session, so unlike most PAI_HOME files the live move is\n// deliberately NOT automatic \u2014 see `pai config migrate --history`.\n// ---------------------------------------------------------------------------\n\nfunction oldHistoryDir(): string {\n  return join(ADAPTER_DIR, 'History');\n}\n\n/** Read/write location for hook-captured history: PAI_HOME/History if\n *  present, else the old ADAPTER_DIR/History (one-time stderr notice). */\nexport function historyDir(): string {\n  return resolvePaiFile(paiHomePath('History'), [oldHistoryDir()], 'pai config migrate --history');\n}\n\nexport function migrateHistoryDir(opts: { dryRun?: boolean } = {}): MigrateDirResult {\n  return migratePaiDir(paiHomePath('History'), [oldHistoryDir()], opts);\n}\n\nfunction oldAgentSessionsPath(): string {\n  return join(ADAPTER_DIR, 'agent-sessions.json');\n}\n\nexport function agentSessionsPath(): string {\n  return resolvePaiFile(paiHomePath('agent-sessions.json'), [oldAgentSessionsPath()], 'pai config migrate --history');\n}\n\nexport function migrateAgentSessions(opts: { dryRun?: boolean } = {}): MigrateFileResult {\n  return migratePaiFile(paiHomePath('agent-sessions.json'), [oldAgentSessionsPath()], opts);\n}\n\nfunction oldSecurityEventsPath(): string {\n  return join(ADAPTER_DIR, 'history', 'security', 'security-events.jsonl');\n}\n\nexport function securityEventsPath(): string {\n  return resolvePaiFile(\n    paiHomePath('History', 'security', 'security-events.jsonl'),\n    [oldSecurityEventsPath()],\n    'pai config migrate --history'\n  );\n}\n\nexport function migrateSecurityEvents(opts: { dryRun?: boolean } = {}): MigrateFileResult {\n  return migratePaiFile(paiHomePath('History', 'security', 'security-events.jsonl'), [oldSecurityEventsPath()], opts);\n}\n\nfunction oldSessionRoutingPath(): string {\n  return join(ADAPTER_DIR, 'session-routing.json');\n}\n\nexport function sessionRoutingPath(): string {\n  return resolvePaiFile(paiHomePath('session-routing.json'), [oldSessionRoutingPath()], 'pai config migrate --history');\n}\n\nexport function migrateSessionRouting(opts: { dryRun?: boolean } = {}): MigrateFileResult {\n  return migratePaiFile(paiHomePath('session-routing.json'), [oldSessionRoutingPath()], opts);\n}\n\n/**\n * Helper to get history file path with date-based organization\n */\nexport function getHistoryFilePath(subdir: string, filename: string): string {\n  const now = new Date();\n  const tz = process.env.TIME_ZONE || Intl.DateTimeFormat().resolvedOptions().timeZone;\n  const localDate = new Date(now.toLocaleString('en-US', { timeZone: tz }));\n  const year = localDate.getFullYear();\n  const month = String(localDate.getMonth() + 1).padStart(2, '0');\n\n  return join(historyDir(), subdir, `${year}-${month}`, filename);\n}\n", "/**\n * Path utilities \u2014 encoding, Notes/Sessions directory discovery and creation.\n */\n\nimport { existsSync, mkdirSync, readdirSync, linkSync, copyFileSync } from 'fs';\nimport { join, basename } from 'path';\nimport { ADAPTER_DIR, PAI_DIR } from '../pai-paths.js';\n\n// Re-export for consumers. PROJECTS_DIR is a harness-adjacent data dir, not\n// PAI_HOME state \u2014 out of scope for the PAI_DIR\u2192PAI_HOME fold (see pai-paths.ts).\nexport { ADAPTER_DIR, PAI_DIR };\nexport const PROJECTS_DIR = join(ADAPTER_DIR, 'projects');\n\n/**\n * Directories known to be automated health-check / probe sessions.\n * Hooks should exit early for these to avoid registry clutter and wasted work.\n */\nconst PROBE_CWD_PATTERNS = [\n  '/CodexBar/ClaudeProbe',\n  '/ClaudeProbe',\n];\n\n/**\n * Check if the current working directory belongs to a probe/health-check session.\n * Returns true if hooks should skip this session entirely.\n */\nexport function isProbeSession(cwd?: string): boolean {\n  const dir = cwd || process.cwd();\n  return PROBE_CWD_PATTERNS.some(pattern => dir.includes(pattern));\n}\n\n/**\n * Encode a path the same way Claude Code does:\n * - Replace / with -\n * - Replace . with -\n * - Replace space with -\n */\nexport function encodePath(path: string): string {\n  return path\n    .replace(/\\//g, '-')\n    .replace(/\\./g, '-')\n    .replace(/ /g, '-');\n}\n\n/** Get the project directory for a given working directory. */\nexport function getProjectDir(cwd: string): string {\n  const encoded = encodePath(cwd);\n  return join(PROJECTS_DIR, encoded);\n}\n\n/** Get the Notes directory for a project (central location). */\nexport function getNotesDir(cwd: string): string {\n  return join(getProjectDir(cwd), 'Notes');\n}\n\n/**\n * Find Notes directory \u2014 checks local first, falls back to central.\n * Does NOT create the directory.\n */\nexport function findNotesDir(cwd: string): { path: string; isLocal: boolean } {\n  const cwdBasename = basename(cwd).toLowerCase();\n  if (cwdBasename === 'notes' && existsSync(cwd)) {\n    return { path: cwd, isLocal: true };\n  }\n\n  const localPaths = [\n    join(cwd, 'Notes'),\n    join(cwd, 'notes'),\n    join(cwd, '.claude', 'Notes'),\n  ];\n\n  for (const path of localPaths) {\n    if (existsSync(path)) {\n      return { path, isLocal: true };\n    }\n  }\n\n  return { path: getNotesDir(cwd), isLocal: false };\n}\n\n/** Get the sessions/ directory for a project (stores .jsonl transcripts). */\nexport function getSessionsDir(cwd: string): string {\n  return join(getProjectDir(cwd), 'sessions');\n}\n\n/** Get the sessions/ directory from a project directory path. */\nexport function getSessionsDirFromProjectDir(projectDir: string): string {\n  return join(projectDir, 'sessions');\n}\n\n// ---------------------------------------------------------------------------\n// Directory creation helpers\n// ---------------------------------------------------------------------------\n\n/** Ensure the Notes directory exists for a project. @deprecated Use ensureNotesDirSmart() */\nexport function ensureNotesDir(cwd: string): string {\n  const notesDir = getNotesDir(cwd);\n  if (!existsSync(notesDir)) {\n    mkdirSync(notesDir, { recursive: true });\n    console.error(`Created Notes directory: ${notesDir}`);\n  }\n  return notesDir;\n}\n\n/**\n * Smart Notes directory handling:\n * - If local Notes/ exists \u2192 use it (don't create anything new)\n * - If no local Notes/ \u2192 ensure central exists and use that\n */\nexport function ensureNotesDirSmart(cwd: string): { path: string; isLocal: boolean } {\n  const found = findNotesDir(cwd);\n  if (found.isLocal) return found;\n  if (!existsSync(found.path)) {\n    mkdirSync(found.path, { recursive: true });\n    console.error(`Created central Notes directory: ${found.path}`);\n  }\n  return found;\n}\n\n/** Ensure the sessions/ directory exists for a project. */\nexport function ensureSessionsDir(cwd: string): string {\n  const sessionsDir = getSessionsDir(cwd);\n  if (!existsSync(sessionsDir)) {\n    mkdirSync(sessionsDir, { recursive: true });\n    console.error(`Created sessions directory: ${sessionsDir}`);\n  }\n  return sessionsDir;\n}\n\n/** Ensure the sessions/ directory exists (from project dir path). */\nexport function ensureSessionsDirFromProjectDir(projectDir: string): string {\n  const sessionsDir = getSessionsDirFromProjectDir(projectDir);\n  if (!existsSync(sessionsDir)) {\n    mkdirSync(sessionsDir, { recursive: true });\n    console.error(`Created sessions directory: ${sessionsDir}`);\n  }\n  return sessionsDir;\n}\n\n/**\n * Publish every project-root .jsonl into sessions/ as well, WITHOUT removing it.\n *\n * This used to renameSync, and that is how PAI destroyed its users' sessions.\n *\n * `claude --resume <uuid>` finds a transcript only at the project root. Move it\n * into sessions/ and the session becomes permanently unresumable \u2014 measured\n * 2026-08-04: `claude --resume b3462801` (867 KB of real work, sessions/ only)\n * answers \"No conversation found with session ID\", while a top-level id is found\n * fine. Nothing warned; the id still looked valid everywhere PAI displayed it.\n *\n * The damage was not occasional. This ran from a UserPromptSubmit hook excluding\n * only the CURRENT session, so every prompt anyone typed unresumed every other\n * session in the project. One PAI project measured 1 transcript at top level\n * against 52 underneath. Among the casualties was 046bb712 \u2014 the exact id PAI's\n * own handover tells the user to resume.\n *\n * A hardlink satisfies both sides, which is why this is a two-line fix rather\n * than a redesign: the archive genuinely has consumers that read sessions/\n * (session-summary-worker, registry/moved, session/autosave), and `--resume`\n * needs the root path. One inode, two names, no copy, no window where the file\n * is missing from either place.\n *\n * Never unlink the source. Tidying up another tool's store was the whole\n * mistake; a stale duplicate is free, a lost session is not. Every caller of\n * `transcriptFiles()` was checked before choosing this \u2014 they all test emptiness\n * (`.length > 0`), never count, so the duplicate cannot skew a project's stats.\n *\n * `excludeFile` keeps a hook from archiving the transcript it is itself watching\n * being written. It is not a \"finished sessions only\" guard and must not be read\n * as one: it excludes exactly one file, the caller's own, so with two sessions\n * live in one project each still archives the other mid-turn. A consumer that\n * needs \"finished only\" has to enforce that itself \u2014 this function cannot know\n * what is live.\n *\n * Returns the number of files newly archived.\n */\nexport function archiveSessionFilesToSessionsDir(\n  projectDir: string,\n  excludeFile?: string,\n  silent = false\n): number {\n  const sessionsDir = ensureSessionsDirFromProjectDir(projectDir);\n\n  if (!existsSync(projectDir)) return 0;\n\n  const files = readdirSync(projectDir);\n  let archivedCount = 0;\n\n  for (const file of files) {\n    if (!file.endsWith('.jsonl') || file === excludeFile) continue;\n\n    const sourcePath = join(projectDir, file);\n    const destPath = join(sessionsDir, file);\n\n    // Already archived \u2014 including by an earlier rename, before this was a\n    // hardlink. Those are the sessions that need restoring to the root, which is\n    // a separate repair and not this function's job.\n    if (existsSync(destPath)) continue;\n\n    try {\n      linkSync(sourcePath, destPath);\n      if (!silent) console.error(`Archived ${file} \u2192 sessions/ (still resumable)`);\n      archivedCount++;\n    } catch (error) {\n      // Cross-device (EXDEV) is the realistic failure: sessions/ on another\n      // volume. Copy instead, and still leave the original alone.\n      try {\n        copyFileSync(sourcePath, destPath);\n        if (!silent) console.error(`Copied ${file} \u2192 sessions/ (hardlink unavailable)`);\n        archivedCount++;\n      } catch {\n        if (!silent) console.error(`Could not archive ${file}: ${error}`);\n      }\n    }\n  }\n\n  return archivedCount;\n}\n\n/**\n * @deprecated Renamed to `archiveSessionFilesToSessionsDir`, which is what it\n * now does. Kept so an out-of-tree caller fails loudly at the type level rather\n * than silently keeping the old destructive name for a non-destructive action.\n */\nexport const moveSessionFilesToSessionsDir = archiveSessionFilesToSessionsDir;\n\n// ---------------------------------------------------------------------------\n// CLAUDE.md / TODO.md discovery\n// ---------------------------------------------------------------------------\n\n/** Find TODO.md \u2014 check local first, fallback to central. */\nexport function findTodoPath(cwd: string): string {\n  const localPaths = [\n    join(cwd, 'TODO.md'),\n    join(cwd, 'notes', 'TODO.md'),\n    join(cwd, 'Notes', 'TODO.md'),\n    join(cwd, '.claude', 'TODO.md'),\n  ];\n\n  for (const path of localPaths) {\n    if (existsSync(path)) return path;\n  }\n\n  return join(getNotesDir(cwd), 'TODO.md');\n}\n\n/** Find CLAUDE.md \u2014 returns the FIRST found path. */\nexport function findClaudeMdPath(cwd: string): string | null {\n  const paths = findAllClaudeMdPaths(cwd);\n  return paths.length > 0 ? paths[0] : null;\n}\n\n/**\n * Find ALL CLAUDE.md files in local locations in priority order.\n */\nexport function findAllClaudeMdPaths(cwd: string): string[] {\n  const foundPaths: string[] = [];\n\n  const localPaths = [\n    join(cwd, '.claude', 'CLAUDE.md'),\n    join(cwd, 'CLAUDE.md'),\n    join(cwd, 'Notes', 'CLAUDE.md'),\n    join(cwd, 'notes', 'CLAUDE.md'),\n    join(cwd, 'Prompts', 'CLAUDE.md'),\n    join(cwd, 'prompts', 'CLAUDE.md'),\n  ];\n\n  for (const path of localPaths) {\n    if (existsSync(path)) foundPaths.push(path);\n  }\n\n  return foundPaths;\n}\n", "/**\n * Push notification helpers \u2014 WhatsApp-aware with ntfy.sh fallback.\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\n/**\n * Check if a messaging MCP server (AIBroker, Whazaa, or Telex) is configured.\n * When any messaging server is active, the AI handles notifications via MCP\n * and ntfy is skipped to avoid duplicates.\n */\nexport function isWhatsAppEnabled(): boolean {\n  try {\n    const settingsPath = join(homedir(), '.claude', 'settings.json');\n    if (!existsSync(settingsPath)) return false;\n\n    const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));\n    const enabled: string[] = settings.enabledMcpjsonServers || [];\n    return enabled.includes('aibroker') || enabled.includes('whazaa') || enabled.includes('telex');\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Send push notification \u2014 WhatsApp-aware with ntfy fallback.\n *\n * When WhatsApp (Whazaa) is enabled in MCP config, ntfy is SKIPPED\n * because the AI sends WhatsApp messages directly via MCP.\n * When WhatsApp is NOT configured, ntfy fires as the fallback channel.\n */\nexport async function sendNtfyNotification(message: string, retries = 2): Promise<boolean> {\n  if (isWhatsAppEnabled()) {\n    console.error(`WhatsApp (Whazaa) enabled in MCP config \u2014 skipping ntfy`);\n    return true;\n  }\n\n  const topic = process.env.NTFY_TOPIC;\n\n  if (!topic) {\n    console.error('NTFY_TOPIC not set and WhatsApp not active \u2014 notifications disabled');\n    return false;\n  }\n\n  for (let attempt = 0; attempt <= retries; attempt++) {\n    try {\n      const response = await fetch(`https://ntfy.sh/${topic}`, {\n        method: 'POST',\n        body: message,\n        headers: {\n          'Title': 'Claude Code',\n          'Priority': 'default',\n        },\n      });\n\n      if (response.ok) {\n        console.error(`ntfy.sh notification sent (WhatsApp inactive): \"${message}\"`);\n        return true;\n      } else {\n        console.error(`ntfy.sh attempt ${attempt + 1} failed: ${response.status}`);\n      }\n    } catch (error) {\n      console.error(`ntfy.sh attempt ${attempt + 1} error: ${error}`);\n    }\n\n    if (attempt < retries) {\n      await new Promise(resolve => setTimeout(resolve, 1000));\n    }\n  }\n\n  console.error('ntfy.sh notification failed after all retries');\n  return false;\n}\n", "/**\n * Session note creation, editing, checkpointing, renaming, and finalization.\n */\n\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, renameSync } from 'fs';\nimport { join, basename } from 'path';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Get or create the YYYY/MM subdirectory for the current month inside notesDir. */\nfunction getMonthDir(notesDir: string): string {\n  const now = new Date();\n  const year = String(now.getFullYear());\n  const month = String(now.getMonth() + 1).padStart(2, '0');\n  const monthDir = join(notesDir, year, month);\n  if (!existsSync(monthDir)) {\n    mkdirSync(monthDir, { recursive: true });\n  }\n  return monthDir;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Get the next note number (4-digit format: 0001, 0002, etc.).\n * Numbers are scoped per YYYY/MM directory.\n */\nexport function getNextNoteNumber(notesDir: string): string {\n  const monthDir = getMonthDir(notesDir);\n\n  const files = readdirSync(monthDir)\n    .filter(f => f.match(/^\\d{3,4}[\\s_-]/))\n    .sort();\n\n  if (files.length === 0) return '0001';\n\n  let maxNumber = 0;\n  for (const file of files) {\n    const digitMatch = file.match(/^(\\d+)/);\n    if (digitMatch) {\n      const num = parseInt(digitMatch[1], 10);\n      if (num > maxNumber) maxNumber = num;\n    }\n  }\n\n  return String(maxNumber + 1).padStart(4, '0');\n}\n\n/**\n * Get the current (latest) note file path, or null if none exists.\n * Searches current month \u2192 previous month \u2192 flat notesDir (legacy).\n */\nexport function getCurrentNotePath(notesDir: string): string | null {\n  if (!existsSync(notesDir)) return null;\n\n  const findLatestIn = (dir: string): string | null => {\n    if (!existsSync(dir)) return null;\n    const files = readdirSync(dir)\n      .filter(f => f.match(/^\\d{3,4}[\\s_-].*\\.md$/))\n      .sort((a, b) => {\n        const numA = parseInt(a.match(/^(\\d+)/)?.[1] || '0', 10);\n        const numB = parseInt(b.match(/^(\\d+)/)?.[1] || '0', 10);\n        return numA - numB;\n      });\n    if (files.length === 0) return null;\n    return join(dir, files[files.length - 1]);\n  };\n\n  const now = new Date();\n  const year = String(now.getFullYear());\n  const month = String(now.getMonth() + 1).padStart(2, '0');\n  const currentMonthDir = join(notesDir, year, month);\n  const found = findLatestIn(currentMonthDir);\n  if (found) return found;\n\n  const prevDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);\n  const prevYear = String(prevDate.getFullYear());\n  const prevMonth = String(prevDate.getMonth() + 1).padStart(2, '0');\n  const prevMonthDir = join(notesDir, prevYear, prevMonth);\n  const prevFound = findLatestIn(prevMonthDir);\n  if (prevFound) return prevFound;\n\n  return findLatestIn(notesDir);\n}\n\n/**\n * Create a new session note.\n * Format: \"NNNN - YYYY-MM-DD - New Session.md\" filed into YYYY/MM subdirectory.\n * Claude MUST rename at session end with a meaningful description.\n */\nexport function createSessionNote(notesDir: string, description: string): string {\n  const noteNumber = getNextNoteNumber(notesDir);\n  const date = new Date().toISOString().split('T')[0];\n  const monthDir = getMonthDir(notesDir);\n  const filename = `${noteNumber} - ${date} - New Session.md`;\n  const filepath = join(monthDir, filename);\n\n  const content = `# Session ${noteNumber}: ${description}\n\n**Date:** ${date}\n**Status:** In Progress\n\n---\n\n## Work Done\n\n<!-- PAI will add completed work here during session -->\n\n---\n\n## Next Steps\n\n<!-- To be filled at session end -->\n\n---\n\n**Tags:** #Session\n`;\n\n  writeFileSync(filepath, content);\n  console.error(`Created session note: ${filename}`);\n\n  return filepath;\n}\n\n/** Append a checkpoint to the current session note. */\nexport function appendCheckpoint(notePath: string, checkpoint: string): void {\n  if (!existsSync(notePath)) {\n    console.error(`Note file not found, recreating: ${notePath}`);\n    try {\n      const parentDir = join(notePath, '..');\n      if (!existsSync(parentDir)) mkdirSync(parentDir, { recursive: true });\n      const noteFilename = basename(notePath);\n      const numberMatch = noteFilename.match(/^(\\d+)/);\n      const noteNumber = numberMatch ? numberMatch[1] : '0000';\n      const date = new Date().toISOString().split('T')[0];\n      const content = `# Session ${noteNumber}: Recovered\\n\\n**Date:** ${date}\\n**Status:** In Progress\\n\\n---\\n\\n## Work Done\\n\\n<!-- PAI will add completed work here during session -->\\n\\n---\\n\\n## Next Steps\\n\\n<!-- To be filled at session end -->\\n\\n---\\n\\n**Tags:** #Session\\n`;\n      writeFileSync(notePath, content);\n      console.error(`Recreated session note: ${noteFilename}`);\n    } catch (err) {\n      console.error(`Failed to recreate note: ${err}`);\n      return;\n    }\n  }\n\n  const content = readFileSync(notePath, 'utf-8');\n  const timestamp = new Date().toISOString();\n  const checkpointText = `\\n### Checkpoint ${timestamp}\\n\\n${checkpoint}\\n`;\n\n  const nextStepsIndex = content.indexOf('## Next Steps');\n  const newContent = nextStepsIndex !== -1\n    ? content.substring(0, nextStepsIndex) + checkpointText + content.substring(nextStepsIndex)\n    : content + checkpointText;\n\n  writeFileSync(notePath, newContent);\n  console.error(`Checkpoint added to: ${basename(notePath)}`);\n}\n\n/** Work item for session notes. */\nexport interface WorkItem {\n  title: string;\n  details?: string[];\n  completed?: boolean;\n}\n\n/** Add work items to the \"Work Done\" section of a session note. */\nexport function addWorkToSessionNote(notePath: string, workItems: WorkItem[], sectionTitle?: string): void {\n  if (!existsSync(notePath)) {\n    console.error(`Note file not found: ${notePath}`);\n    return;\n  }\n\n  let content = readFileSync(notePath, 'utf-8');\n\n  let workText = '';\n  if (sectionTitle) workText += `\\n### ${sectionTitle}\\n\\n`;\n\n  for (const item of workItems) {\n    const checkbox = item.completed !== false ? '[x]' : '[ ]';\n    workText += `- ${checkbox} **${item.title}**\\n`;\n    if (item.details && item.details.length > 0) {\n      for (const detail of item.details) {\n        workText += `  - ${detail}\\n`;\n      }\n    }\n  }\n\n  const workDoneMatch = content.match(/## Work Done\\n\\n(<!-- .*? -->)?/);\n  if (workDoneMatch) {\n    const insertPoint = content.indexOf(workDoneMatch[0]) + workDoneMatch[0].length;\n    content = content.substring(0, insertPoint) + workText + content.substring(insertPoint);\n  } else {\n    const nextStepsIndex = content.indexOf('## Next Steps');\n    if (nextStepsIndex !== -1) {\n      content = content.substring(0, nextStepsIndex) + workText + '\\n' + content.substring(nextStepsIndex);\n    }\n  }\n\n  writeFileSync(notePath, content);\n  console.error(`Added ${workItems.length} work item(s) to: ${basename(notePath)}`);\n}\n\n/**\n * Check if a candidate title is meaningless / garbage.\n * Public wrapper around the internal filter for use by other hooks.\n */\nexport function isMeaningfulTitle(text: string): boolean {\n  return !isMeaninglessCandidate(text);\n}\n\n/** Sanitize a string for use in a filename. */\nexport function sanitizeForFilename(str: string): string {\n  return str\n    .toLowerCase()\n    .replace(/[^a-z0-9\\s-]/g, '')\n    .replace(/\\s+/g, '-')\n    .replace(/-+/g, '-')\n    .replace(/^-|-$/g, '')\n    .substring(0, 50);\n}\n\n/**\n * Return true if the candidate string should be rejected as a meaningful name.\n * Rejects file paths, shebangs, timestamps, system noise, XML tags, hashes, etc.\n */\nfunction isMeaninglessCandidate(text: string): boolean {\n  const t = text.trim();\n  if (!t) return true;\n  if (t.length < 5) return true;                              // too short to be meaningful\n  if (t.startsWith('/') || t.startsWith('~')) return true;    // file path\n  if (t.startsWith('#!')) return true;                         // shebang\n  if (t.includes('[object Object]')) return true;              // serialization artifact\n  if (/^\\d{4}-\\d{2}-\\d{2}(T[\\d:.Z+-]+)?$/.test(t)) return true; // ISO timestamp\n  if (/^\\d{1,2}:\\d{2}(:\\d{2})?(\\s*(AM|PM))?$/i.test(t)) return true; // time-only\n  if (/^<[a-z-]+[\\s/>]/i.test(t)) return true;               // XML/HTML tags (<task-notification>, etc.)\n  if (/^[0-9a-f]{10,}$/i.test(t)) return true;               // hex hash strings\n  if (/^Exit code \\d+/i.test(t)) return true;                 // exit code messages\n  if (/^Error:/i.test(t)) return true;                        // error messages\n  if (/^This session is being continued/i.test(t)) return true; // continuation boilerplate\n  if (/^\\(Bash completed/i.test(t)) return true;              // bash output noise\n  if (/^Task Notification$/i.test(t)) return true;            // literal \"Task Notification\"\n  if (/^New Session$/i.test(t)) return true;                  // placeholder title\n  if (/^Recovered Session$/i.test(t)) return true;            // placeholder title\n  if (/^Continued Session$/i.test(t)) return true;            // placeholder title\n  if (/^Untitled Session$/i.test(t)) return true;             // placeholder title\n  if (/^Context Compression$/i.test(t)) return true;          // compression artifact\n  if (/^[A-Fa-f0-9]{8,}\\s+Output$/i.test(t)) return true;   // hash + \"Output\" pattern\n  return false;\n}\n\n/**\n * Extract a meaningful name from session note content and summary.\n * Looks at Work Done section headers, bold text, and summary.\n */\nexport function extractMeaningfulName(noteContent: string, summary: string): string {\n  const workDoneMatch = noteContent.match(/## Work Done\\n\\n([\\s\\S]*?)(?=\\n---|\\n## Next)/);\n\n  if (workDoneMatch) {\n    const workDoneSection = workDoneMatch[1];\n\n    const subheadings = workDoneSection.match(/### ([^\\n]+)/g);\n    if (subheadings && subheadings.length > 0) {\n      const firstHeading = subheadings[0].replace('### ', '').trim();\n      if (!isMeaninglessCandidate(firstHeading) && firstHeading.length > 5 && firstHeading.length < 60) {\n        return sanitizeForFilename(firstHeading);\n      }\n    }\n\n    const boldMatches = workDoneSection.match(/\\*\\*([^*]+)\\*\\*/g);\n    if (boldMatches && boldMatches.length > 0) {\n      const firstBold = boldMatches[0].replace(/\\*\\*/g, '').trim();\n      if (!isMeaninglessCandidate(firstBold) && firstBold.length > 3 && firstBold.length < 50) {\n        return sanitizeForFilename(firstBold);\n      }\n    }\n\n    const numberedItems = workDoneSection.match(/^\\d+\\.\\s+\\*\\*([^*]+)\\*\\*/m);\n    if (numberedItems && !isMeaninglessCandidate(numberedItems[1])) {\n      return sanitizeForFilename(numberedItems[1]);\n    }\n  }\n\n  if (summary && summary.length > 5 && summary !== 'Session completed.' && !isMeaninglessCandidate(summary)) {\n    const cleanSummary = summary\n      .replace(/[^\\w\\s-]/g, ' ')\n      .trim()\n      .split(/\\s+/)\n      .slice(0, 5)\n      .join(' ');\n    if (cleanSummary.length > 3 && !isMeaninglessCandidate(cleanSummary)) {\n      return sanitizeForFilename(cleanSummary);\n    }\n  }\n\n  return '';\n}\n\n/**\n * Rename a session note with a meaningful name.\n * Always uses \"NNNN - YYYY-MM-DD - Description.md\" format.\n * Returns the new path, or original path if rename fails.\n */\nexport function renameSessionNote(notePath: string, meaningfulName: string): string {\n  if (!meaningfulName || !existsSync(notePath)) return notePath;\n\n  const dir = join(notePath, '..');\n  const oldFilename = basename(notePath);\n\n  const correctMatch = oldFilename.match(/^(\\d{3,4}) - (\\d{4}-\\d{2}-\\d{2}) - .*\\.md$/);\n  const legacyMatch = oldFilename.match(/^(\\d{3,4})_(\\d{4}-\\d{2}-\\d{2})_.*\\.md$/);\n  const match = correctMatch || legacyMatch;\n  if (!match) return notePath;\n\n  const [, noteNumber, date] = match;\n\n  const titleCaseName = meaningfulName\n    .split(/[\\s_-]+/)\n    .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n    .join(' ')\n    .trim();\n\n  const paddedNumber = noteNumber.padStart(4, '0');\n  const newFilename = `${paddedNumber} - ${date} - ${titleCaseName}.md`;\n  const newPath = join(dir, newFilename);\n\n  if (newFilename === oldFilename) return notePath;\n\n  try {\n    renameSync(notePath, newPath);\n    console.error(`Renamed note: ${oldFilename} \u2192 ${newFilename}`);\n    return newPath;\n  } catch (error) {\n    console.error(`Could not rename note: ${error}`);\n    return notePath;\n  }\n}\n\n/** Update the session note's H1 title and rename the file. */\nexport function updateSessionNoteTitle(notePath: string, newTitle: string): void {\n  if (!existsSync(notePath)) {\n    console.error(`Note file not found: ${notePath}`);\n    return;\n  }\n\n  let content = readFileSync(notePath, 'utf-8');\n  content = content.replace(/^# Session \\d+:.*$/m, (match) => {\n    const sessionNum = match.match(/Session (\\d+)/)?.[1] || '';\n    return `# Session ${sessionNum}: ${newTitle}`;\n  });\n  writeFileSync(notePath, content);\n  renameSessionNote(notePath, sanitizeForFilename(newTitle));\n}\n\n/**\n * Finalize session note \u2014 mark as complete, add summary, rename with meaningful name.\n * IDEMPOTENT: subsequent calls are no-ops if already finalized.\n * Returns the final path (may be renamed).\n */\nexport function finalizeSessionNote(notePath: string, summary: string): string {\n  if (!existsSync(notePath)) {\n    console.error(`Note file not found: ${notePath}`);\n    return notePath;\n  }\n\n  let content = readFileSync(notePath, 'utf-8');\n\n  if (content.includes('**Status:** Completed')) {\n    console.error(`Note already finalized: ${basename(notePath)}`);\n    return notePath;\n  }\n\n  content = content.replace('**Status:** In Progress', '**Status:** Completed');\n\n  if (!content.includes('**Completed:**')) {\n    const completionTime = new Date().toISOString();\n    content = content.replace(\n      '---\\n\\n## Work Done',\n      `**Completed:** ${completionTime}\\n\\n---\\n\\n## Work Done`\n    );\n  }\n\n  const nextStepsMatch = content.match(/## Next Steps\\n\\n(<!-- .*? -->)/);\n  if (nextStepsMatch) {\n    content = content.replace(\n      nextStepsMatch[0],\n      `## Next Steps\\n\\n${summary || 'Session completed.'}`\n    );\n  }\n\n  writeFileSync(notePath, content);\n  console.error(`Session note finalized: ${basename(notePath)}`);\n\n  const meaningfulName = extractMeaningfulName(content, summary);\n  if (meaningfulName) {\n    return renameSessionNote(notePath, meaningfulName);\n  }\n\n  return notePath;\n}\n"],
  "mappings": "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",
  "names": ["res", "res", "anchors", "doc", "Scalar", "Scalar", "node", "str", "i", "end", "Scalar", "str", "str", "Scalar", "str", "Scalar", "value", "stringify", "comment", "str", "Scalar", "YAMLMap", "YAMLMap", "map", "Scalar", "seq", "str", "Scalar", "Scalar", "str", "Scalar", "str", "str", "require_schema", "Scalar", "str", "Scalar", "str", "Scalar", "pairs", "YAMLMap", "omap", "require_bool", "Scalar", "require_float", "Scalar", "str", "require_int", "str", "n", "YAMLMap", "set", "str", "res", "require_schema", "tags", "Document", "res", "YAMLMap", "YAMLMap", "Scalar", "YAMLMap", "Scalar", "value", "end", "Scalar", "Scalar", "tag", "Document", "Document", "i", "ch", "start", "Document", "lineCounter", "parseDocument", "Document", "Scalar", "YAMLMap", "homedir", "join", "homedir", "join", "dirname", "basename", "import_yaml", "existsSync", "readFileSync", "renameSync", "chmodSync", "dirname", "join", "existsSync", "readFileSync", "copyFileSync", "renameSync", "mkdirSync", "existsSync", "readFileSync", "join", "dirname", "existsSync", "readFileSync", "join", "homedir", "dirname", "import_yaml", "existsSync", "readFileSync", "writeFileSync", "chmodSync", "homedir", "dirname", "join", "join", "homedir", "existsSync", "readFileSync", "DEFAULT_ROUTING", "join", "homedir", "join", "join", "existsSync", "readFileSync", "statSync", "writeFileSync", "existsSync", "mkdirSync", "readFileSync", "readdirSync", "renameSync", "writeFileSync", "join", "existsSync", "readdirSync", "readFileSync", "join", "execFileSync", "execFileSync", "existsSync", "statSync", "existsSync", "readFileSync", "join", "basename", "dirname", "resolve", "homedir", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "basename", "homedir", "join", "homedir", "existsSync", "readFileSync", "join", "existsSync", "homedir", "readdirSync", "basename", "statSync", "readFileSync", "homedir", "join", "existsSync", "readFileSync", "homedir", "existsSync", "readFileSync", "join", "join", "existsSync", "mkdirSync", "readdirSync", "copyFileSync", "join", "basename", "join", "basename", "existsSync", "join", "existsSync", "mkdirSync", "readdirSync", "join", "copyFileSync", "join", "existsSync", "join", "existsSync", "existsSync", "readFileSync", "join", "homedir", "resolve", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "renameSync", "join", "basename", "existsSync", "readFileSync", "join", "homedir", "resolve", "basename", "dirname", "mkdirSync", "writeFileSync", "execFileSync"]
}
