@tangle-network/agent-app 0.49.33 → 0.49.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/bin/tangle-agent/home-maintenance.py +280 -0
  2. package/bin/tangle-agent/home.mjs +166 -0
  3. package/bin/tangle-agent/provision.mjs +168 -0
  4. package/bin/tangle-agent/runtime.mjs +151 -0
  5. package/bin/tangle-agent.mjs +26 -0
  6. package/dist/VaultPane-2SJSP6TS.js +7 -0
  7. package/dist/app-auth/index.d.ts +14 -2
  8. package/dist/app-auth/index.js +3 -3
  9. package/dist/app-auth/index.js.map +1 -1
  10. package/dist/assistant/index.js +7 -7
  11. package/dist/chat-react/index.js +1 -1
  12. package/dist/chat-routes/index.js +4 -4
  13. package/dist/chat-store/index.js +2 -2
  14. package/dist/{chunk-FCUWRMAF.js → chunk-56SVXAIK.js} +14 -9
  15. package/dist/chunk-56SVXAIK.js.map +1 -0
  16. package/dist/chunk-6CV66YOB.js +99 -0
  17. package/dist/chunk-6CV66YOB.js.map +1 -0
  18. package/dist/{chunk-V4YGTOCS.js → chunk-MIFVOYZ7.js} +5 -5
  19. package/dist/{chunk-FXWNNHPC.js → chunk-MVIIH2EQ.js} +165 -72
  20. package/dist/chunk-MVIIH2EQ.js.map +1 -0
  21. package/dist/{chunk-TNWQA5XJ.js → chunk-NLNM5PP6.js} +5 -4
  22. package/dist/chunk-NLNM5PP6.js.map +1 -0
  23. package/dist/{chunk-4PZE7XAM.js → chunk-S3344RBY.js} +4 -4
  24. package/dist/{chunk-4S36HWE4.js → chunk-WAMJSZYB.js} +1 -1
  25. package/dist/{chunk-VIL6MHHQ.js → chunk-XTLYE2VO.js} +6 -6
  26. package/dist/design-canvas-react/index.js +1 -1
  27. package/dist/design-canvas-react/lazy.js +1 -1
  28. package/dist/hosted-agent/general-skill.d.ts +2 -0
  29. package/dist/hosted-agent/general.d.ts +53 -0
  30. package/dist/hosted-agent/index.d.ts +9 -1
  31. package/dist/hosted-agent/index.js +294 -7
  32. package/dist/hosted-agent/index.js.map +1 -1
  33. package/dist/hosted-agent/react/LineBilling.d.ts +3 -0
  34. package/dist/hosted-agent/react/LineMembers.d.ts +3 -0
  35. package/dist/hosted-agent/react/LineSetup.d.ts +3 -0
  36. package/dist/hosted-agent/react/contracts.d.ts +136 -0
  37. package/dist/hosted-agent/react/index.d.ts +5 -0
  38. package/dist/hosted-agent/react/index.js +573 -0
  39. package/dist/hosted-agent/react/index.js.map +1 -0
  40. package/dist/hosted-agent/react/lines.css +110 -0
  41. package/dist/hosted-agent/react/styles.d.ts +2 -0
  42. package/dist/hosted-agent/react/styles.js +1 -0
  43. package/dist/hosted-agent/react/styles.js.map +1 -0
  44. package/dist/hosted-agent/workflows.d.ts +17 -0
  45. package/dist/{mention-editor-4PYZJM5A.js → mention-editor-ELAINF6H.js} +3 -2
  46. package/dist/mention-editor-ELAINF6H.js.map +1 -0
  47. package/dist/platform/index.js +1 -1
  48. package/dist/platform/sso.d.ts +74 -7
  49. package/dist/profile/home.d.ts +23 -0
  50. package/dist/profile/index.d.ts +1 -0
  51. package/dist/profile/index.js +9 -1
  52. package/dist/profile/index.js.map +1 -1
  53. package/dist/public-consultation/index.js +4 -4
  54. package/dist/stories/hosted-agent/fixtures.d.ts +34 -0
  55. package/dist/teams/index.js +5 -5
  56. package/dist/teams/invitations-api.js +4 -4
  57. package/dist/theme/tokens.css +20 -3
  58. package/dist/vault/ConfirmDialog.d.ts +1 -1
  59. package/dist/vault/VaultPane.d.ts +2 -2
  60. package/dist/vault/contracts.d.ts +8 -0
  61. package/dist/vault/index.js +1 -1
  62. package/dist/vault/lazy.d.ts +3 -3
  63. package/dist/vault/lazy.js +1 -1
  64. package/dist/vault/lazy.js.map +1 -1
  65. package/dist/web-react/index.js +23 -23
  66. package/package.json +47 -14
  67. package/dist/VaultPane-32HVWZ6A.js +0 -7
  68. package/dist/chunk-FCUWRMAF.js.map +0 -1
  69. package/dist/chunk-FXWNNHPC.js.map +0 -1
  70. package/dist/chunk-TNWQA5XJ.js.map +0 -1
  71. package/dist/mention-editor-4PYZJM5A.js.map +0 -1
  72. /package/dist/{VaultPane-32HVWZ6A.js.map → VaultPane-2SJSP6TS.js.map} +0 -0
  73. /package/dist/{chunk-V4YGTOCS.js.map → chunk-MIFVOYZ7.js.map} +0 -0
  74. /package/dist/{chunk-4PZE7XAM.js.map → chunk-S3344RBY.js.map} +0 -0
  75. /package/dist/{chunk-4S36HWE4.js.map → chunk-WAMJSZYB.js.map} +0 -0
  76. /package/dist/{chunk-VIL6MHHQ.js.map → chunk-XTLYE2VO.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/profile/index.ts"],"sourcesContent":["/**\n * Profile composer + evolvable-section seam for agent products.\n *\n * The standard \"load a deployable AgentProfile, including skills, plus the\n * skills the end user added to their own instance\" entry point. A product holds\n * a canonical base `AgentProfile` (role/environment/tool-conventions rendered\n * into `prompt.systemPrompt`, baseline skills, baseline MCP). At deploy/turn\n * time it layers four file-mount channels onto `resources.files` —\n *\n * 1. skills — the always-mounted product skill corpus\n * 2. knowledge — a second always-mounted corpus (domain knowledge pack)\n * 3. registry — the tier-gated installable registry (free -> boot-mounted)\n * 4. userSkills — per-user / per-workspace skills the END USER adds to their\n * own instance, mounted at `~/.claude/skills/<id>/SKILL.md`\n * exactly like the registry's free tier\n *\n * plus an optional MCP overlay (delegation + per-turn app-tool side channel), a\n * per-turn `systemPrompt` override, and a `name` override. The canonical\n * `mergeAgentProfiles` contract makes `mcp` last-wins per key (base -> overlay),\n * concatenates `resources` arrays (base ++ overlay), and shallow-merges `prompt`\n * so an overlay carrying only `systemPrompt` overrides it while keeping base\n * instructions. The compose algebra is DATA — the product injects the base\n * profile, the channel mounts (built with the `skills` subpath primitives), the\n * delegation/app-tool MCP map, and the override strings; nothing here reaches\n * for env, a glob, or a specific product's profile.\n *\n * The evolvable-section seam is the loader closure. A product's single\n * self-improvable domain section (the one `applyDomainPatch` targets) loads its\n * body from a deployed markdown override, falling back to an in-tree baseline.\n * The `import.meta.glob('<lit>', ...)` literal must stay at the CONSUMER call\n * site (Vite static-analyzes it), so `makeEvolvableSection` takes the loader as\n * a closure and a REQUIRED `baseline` — it never constructs a glob and never\n * defaults the baseline, so a product can't render an empty learned-guidance\n * section. `stripComments` is the shared \"is this addendum really empty?\" test.\n */\n\nimport type {\n AgentProfile,\n AgentProfileFileMount,\n AgentProfileMcpServer,\n AgentProfileResourceRef,\n} from '@tangle-network/agent-interface'\nimport { mergeAgentProfiles } from '@tangle-network/agent-interface'\nimport { profile } from '@tangle-network/agent-eval'\nimport {\n composeShellResources,\n registrySkills,\n skillMountPath,\n type ComposeShellResourcesInput,\n type SkillEntry,\n} from '../skills/index'\nimport { assertSystemPromptWithinBudget, type ComposeProfileBudget } from './budget'\n\n/** The prompt byte budget lives in `./budget` (import-free) so `/sandbox` can\n * run the same gate without pulling agent-eval through this module. Re-exported\n * here so the published `/profile` surface is unchanged. */\nexport {\n assertProfilePromptWithinBudget,\n assertSystemPromptWithinBudget,\n DEFAULT_MAX_SYSTEM_PROMPT_BYTES,\n largestPromptSections,\n type ComposeProfileBudget,\n} from './budget'\n\n/** Re-expose the agent-eval section/render substrate so a product wires the\n * evolvable surface through ONE subpath: `makeEvolvableSection` builds the\n * section, `profile.renderProfile` renders it, `profile.applyDomainPatch` lets\n * the loop patch it by id. The rendering/patching engine stays in agent-eval;\n * reach it through this namespace (re-exporting the bare fns would leak\n * agent-eval's un-nameable AgentProfile type into our generated d.ts). */\nexport { profile }\n\n/** The file-mount channels layered onto `resources.files`. The first three\n * mirror {@link ComposeShellResourcesInput}; `userSkills` is the per-user /\n * per-workspace channel — skills the END USER added to their own instance,\n * mounted at the harness skill-discovery path like the registry's free tier. */\nexport interface ProfileChannels {\n /** Always-mounted skill corpus (pass `corpusSkills(...)`). */\n skills?: AgentProfileFileMount[]\n /** Always-mounted knowledge corpus (pass `corpusSkills(...)` for the pack). */\n knowledge?: AgentProfileFileMount[]\n /** Single-file evolvable / learned-guidance corpora, if mounted as files. */\n evolvable?: AgentProfileFileMount[]\n /** Tier-gated installable registry (pass the registry array; free tier is\n * mounted, paid is install-on-demand). Gated through {@link registrySkills}. */\n registry?: SkillEntry[]\n /** Per-user / per-workspace skills the end user adds to their own instance.\n * Mounted at `~/.claude/skills/<id>/SKILL.md`, the same harness path the\n * registry uses, so a user skill and a registry skill with the same id\n * collide deterministically (the user skill, appended last, wins). */\n userSkills?: UserSkill[]\n /** Final skip filter applied to the composed mount list by mount `path`. */\n filesPredicate?: (mount: AgentProfileFileMount) => boolean\n /** Typed `resources.skills` channel — refs the platform materializer places\n * at the harness-native skill dir (see {@link skillRefs} and\n * `@tangle-network/agent-app/skills-placement`'s `composeSkillsForHarness`).\n * The successor to path-baked mounts: `registry`/`userSkills` above mount\n * files at the hardcoded claude-code path via {@link skillMountPath};\n * `skillRefs` instead rides the provider-neutral `resources.skills` field\n * the platform resolves per harness. */\n skillRefs?: AgentProfileResourceRef[]\n /** Tier passed to {@link registrySkills} for the `registry` channel.\n * Previously hardcoded `'free'`; default unchanged. */\n registryTier?: string\n}\n\n/** A per-user / per-workspace skill: an id and an inline `SKILL.md` body. The\n * user-facing analogue of a registry {@link SkillEntry} with no tier gate —\n * every user skill is mounted (the user opted in by adding it). */\nexport interface UserSkill {\n id: string\n /** Inline `SKILL.md` body mounted at {@link skillMountPath}. */\n skillMd: string\n}\n\n/** Overlay overrides applied on top of the channel mounts. */\nexport interface ProfileOverlay {\n /** Extra MCP servers merged into the profile `mcp` map (last-wins per key over\n * the base servers). The product builds this from its delegation MCP entry\n * and any per-turn app-tool side-channel servers. An absent/`undefined` entry\n * is dropped — pass only the servers that resolved (fail-closed at the seam,\n * not here). */\n mcp?: Record<string, AgentProfileMcpServer>\n /** Per-turn system-prompt override. When set, replaces the base\n * `prompt.systemPrompt` while keeping base `prompt.instructions`. When unset,\n * the base prompt passes through unchanged. */\n systemPrompt?: string\n /** Extra instruction lines merged onto the active prompt (e.g. a per-turn\n * domain/integration directive). Appended to base `prompt.instructions` by\n * the SDK merge. */\n instructions?: string[]\n /** Profile `name` override. When unset, the base name is kept. */\n name?: string\n}\n\n/** Project per-user skills onto SDK file mounts at the harness skill-discovery\n * path. No tier gate — a user skill is mounted because the user added it.\n * Sorted by path for determinism (matches {@link registrySkills}). */\nexport function userSkillMounts(userSkills: UserSkill[]): AgentProfileFileMount[] {\n return userSkills\n .map(\n (s) =>\n ({\n path: skillMountPath(s.id),\n resource: { kind: 'inline', name: s.id, content: s.skillMd },\n }) satisfies AgentProfileFileMount,\n )\n .sort((a, b) => a.path.localeCompare(b.path))\n}\n\n/**\n * Compose a deployable `AgentProfile` from a canonical base plus the four\n * file-mount channels and the overlay overrides.\n *\n * Files: base `resources.files` come first; the four channels follow in\n * `skills -> knowledge -> evolvable -> registry -> userSkills` order (so a\n * userSkill that mounts at the same path as a registry skill is the last write\n * and wins). MCP: base servers first, the overlay `mcp` last (last-wins per\n * key). Prompt: the overlay `systemPrompt`, when set, replaces the base one;\n * base instructions are preserved. Name: the overlay `name`, when set, wins.\n *\n * The merge delegates to the SDK `mergeAgentProfiles` (overlay-wins on records,\n * arrays concatenated) — the deterministic algebra is the overlay we hand it,\n * not a hand-rolled spread. `mergeAgentProfiles(base, overlay)` returns\n * `undefined` only when BOTH are `undefined`; `base` is always defined here, so\n * the result is non-`undefined` by construction and we assert that to the caller.\n *\n * The composed `prompt.systemPrompt` is byte-budgeted here — the single point\n * where the FINAL prompt exists ({@link assertSystemPromptWithinBudget};\n * default {@link DEFAULT_MAX_SYSTEM_PROMPT_BYTES}, `warnOnly` escape hatch).\n */\nexport function composeAgentProfile(\n base: AgentProfile,\n channels: ProfileChannels = {},\n overlay: ProfileOverlay = {},\n budget: ComposeProfileBudget = {},\n): AgentProfile {\n const shellInput: ComposeShellResourcesInput = {\n skills: channels.skills,\n knowledge: channels.knowledge,\n evolvable: channels.evolvable,\n registry: channels.registry\n ? registrySkills(channels.registry, channels.registryTier ?? 'free')\n : undefined,\n predicate: channels.filesPredicate,\n }\n const channelFiles = composeShellResources(shellInput)\n const userFiles = channels.userSkills ? userSkillMounts(channels.userSkills) : []\n const overlayFiles = channels.filesPredicate\n ? userFiles.filter(channels.filesPredicate)\n : userFiles\n const files = [...channelFiles, ...overlayFiles]\n\n const promptOverlay: { systemPrompt?: string; instructions?: string[] } = {}\n if (overlay.systemPrompt) promptOverlay.systemPrompt = overlay.systemPrompt\n if (overlay.instructions && overlay.instructions.length > 0) promptOverlay.instructions = overlay.instructions\n\n const overlayProfile: AgentProfile = {\n ...(overlay.name ? { name: overlay.name } : {}),\n ...(Object.keys(promptOverlay).length > 0 ? { prompt: promptOverlay } : {}),\n ...(overlay.mcp ? { mcp: overlay.mcp } : {}),\n resources: {\n files,\n ...(channels.skillRefs && channels.skillRefs.length > 0 ? { skills: channels.skillRefs } : {}),\n },\n }\n\n const merged = mergeAgentProfiles(base, overlayProfile)\n if (!merged)\n throw new Error('composeAgentProfile: mergeAgentProfiles returned undefined for a defined base')\n // Byte-budget gate on the FINAL composed systemPrompt — this is the single\n // point where every channel and overlay has been merged in.\n const systemPrompt = merged.prompt?.systemPrompt\n if (typeof systemPrompt === 'string') assertSystemPromptWithinBudget(systemPrompt, budget)\n return pruneEmptyResourceChannels(merged)\n}\n\n/** Drop absent and empty resource channels the canonical merge normalizes in,\n * so the composed profile's wire payload carries\n * only the channels that actually have content — one canonical shape every app\n * emits, instead of a sidecar payload full of empty arrays. */\nfunction pruneEmptyResourceChannels(profile: AgentProfile): AgentProfile {\n if (!profile.resources) return profile\n const kept = Object.fromEntries(\n Object.entries(profile.resources).filter(([, value]) =>\n value !== undefined && !(Array.isArray(value) && value.length === 0),\n ),\n ) as AgentProfile['resources']\n const out: AgentProfile = { ...profile, resources: kept }\n if (kept && Object.keys(kept).length === 0) delete out.resources\n return out\n}\n\n/** True body of an addendum file with HTML comments stripped — an all-comment\n * placeholder counts as empty, so the loader falls back to the baseline. */\nexport function stripComments(raw: string): string {\n return raw.replace(/<!--[\\s\\S]*?-->/g, '').trim()\n}\n\n/** Inputs to {@link makeEvolvableSection}. */\nexport interface EvolvableSectionInput {\n /** Section id the self-improvement loop targets with `applyDomainPatch`. */\n id: string\n /** Section title rendered as `### <title>`. */\n title: string\n /**\n * Load the deployed section body. The CONSUMER supplies this closure and runs\n * its own `import.meta.glob('<lit>', { eager: true, query: '?raw', import:\n * 'default' })` inside it — the literal must stay at the call site so Vite can\n * static-analyze it; a glob constructed here would not resolve the product's\n * files. Return the raw markdown (comments and all); `makeEvolvableSection`\n * applies {@link stripComments} to decide whether it is really populated.\n */\n load: () => string\n /**\n * The in-tree fallback body, used when `load()` returns an\n * all-comments/empty placeholder. REQUIRED — no internal default — so a\n * product can never accidentally render an empty evolvable section.\n */\n baseline: string\n}\n\n/**\n * Build the one evolvable (`evolvable: true`) domain section whose body comes\n * from the product's loader, falling back to the required baseline when the\n * loaded body is empty after stripping comments. Returns the agent-eval\n * `AgentProfileSection` shape — drop it straight into `prodProfile`'s shipped\n * sections. The loader is the only seam; the empty-vs-populated rule and the\n * baseline fallback are the lifted algebra.\n */\nexport function makeEvolvableSection(input: EvolvableSectionInput): profile.AgentProfileSection {\n const loaded = input.load()\n const body = stripComments(loaded) ? loaded.trim() : input.baseline\n return { id: input.id, title: input.title, body, evolvable: true }\n}\n\nexport {\n assertSkillDeliveryDisjoint,\n composeShellResources,\n composeSkills,\n corpusSkills,\n loadMarkdownCorpus,\n mergeComposedSkills,\n parseCorpusSkills,\n parseSkillFrontmatter,\n registrySkills,\n renderInlineSkills,\n renderSkillIndex,\n skillEntryFromMarkdown,\n skillMountPath,\n skillRefs,\n} from '../skills/index'\nexport type {\n ComposedSkills,\n ComposeShellResourcesInput,\n CorpusEntry,\n CorpusLoadResult,\n GlobModules,\n LoadCorpusOptions,\n ParsedSkill,\n SkillDeliveryMode,\n SkillEntry,\n SkillFrontmatter,\n} from '../skills/index'\nexport {\n diffProfileFingerprints,\n fingerprintAgentProfile,\n formatProfileDrift,\n} from './fingerprint'\nexport type {\n ProfileDrift,\n ProfileDriftEntry,\n ProfileFingerprint,\n ProfileFingerprintContext,\n} from './fingerprint'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAS,0BAA0B;AACnC,SAAS,eAAe;AA+FjB,SAAS,gBAAgB,YAAkD;AAChF,SAAO,WACJ;AAAA,IACC,CAAC,OACE;AAAA,MACC,MAAM,eAAe,EAAE,EAAE;AAAA,MACzB,UAAU,EAAE,MAAM,UAAU,MAAM,EAAE,IAAI,SAAS,EAAE,QAAQ;AAAA,IAC7D;AAAA,EACJ,EACC,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAChD;AAuBO,SAAS,oBACd,MACA,WAA4B,CAAC,GAC7B,UAA0B,CAAC,GAC3B,SAA+B,CAAC,GAClB;AACd,QAAM,aAAyC;AAAA,IAC7C,QAAQ,SAAS;AAAA,IACjB,WAAW,SAAS;AAAA,IACpB,WAAW,SAAS;AAAA,IACpB,UAAU,SAAS,WACf,eAAe,SAAS,UAAU,SAAS,gBAAgB,MAAM,IACjE;AAAA,IACJ,WAAW,SAAS;AAAA,EACtB;AACA,QAAM,eAAe,sBAAsB,UAAU;AACrD,QAAM,YAAY,SAAS,aAAa,gBAAgB,SAAS,UAAU,IAAI,CAAC;AAChF,QAAM,eAAe,SAAS,iBAC1B,UAAU,OAAO,SAAS,cAAc,IACxC;AACJ,QAAM,QAAQ,CAAC,GAAG,cAAc,GAAG,YAAY;AAE/C,QAAM,gBAAoE,CAAC;AAC3E,MAAI,QAAQ,aAAc,eAAc,eAAe,QAAQ;AAC/D,MAAI,QAAQ,gBAAgB,QAAQ,aAAa,SAAS,EAAG,eAAc,eAAe,QAAQ;AAElG,QAAM,iBAA+B;AAAA,IACnC,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,IAC7C,GAAI,OAAO,KAAK,aAAa,EAAE,SAAS,IAAI,EAAE,QAAQ,cAAc,IAAI,CAAC;AAAA,IACzE,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC1C,WAAW;AAAA,MACT;AAAA,MACA,GAAI,SAAS,aAAa,SAAS,UAAU,SAAS,IAAI,EAAE,QAAQ,SAAS,UAAU,IAAI,CAAC;AAAA,IAC9F;AAAA,EACF;AAEA,QAAM,SAAS,mBAAmB,MAAM,cAAc;AACtD,MAAI,CAAC;AACH,UAAM,IAAI,MAAM,+EAA+E;AAGjG,QAAM,eAAe,OAAO,QAAQ;AACpC,MAAI,OAAO,iBAAiB,SAAU,gCAA+B,cAAc,MAAM;AACzF,SAAO,2BAA2B,MAAM;AAC1C;AAMA,SAAS,2BAA2BA,UAAqC;AACvE,MAAI,CAACA,SAAQ,UAAW,QAAOA;AAC/B,QAAM,OAAO,OAAO;AAAA,IAClB,OAAO,QAAQA,SAAQ,SAAS,EAAE;AAAA,MAAO,CAAC,CAAC,EAAE,KAAK,MAChD,UAAU,UAAa,EAAE,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;AAAA,IACpE;AAAA,EACF;AACA,QAAM,MAAoB,EAAE,GAAGA,UAAS,WAAW,KAAK;AACxD,MAAI,QAAQ,OAAO,KAAK,IAAI,EAAE,WAAW,EAAG,QAAO,IAAI;AACvD,SAAO;AACT;AAIO,SAAS,cAAc,KAAqB;AACjD,SAAO,IAAI,QAAQ,oBAAoB,EAAE,EAAE,KAAK;AAClD;AAiCO,SAAS,qBAAqB,OAA2D;AAC9F,QAAM,SAAS,MAAM,KAAK;AAC1B,QAAM,OAAO,cAAc,MAAM,IAAI,OAAO,KAAK,IAAI,MAAM;AAC3D,SAAO,EAAE,IAAI,MAAM,IAAI,OAAO,MAAM,OAAO,MAAM,WAAW,KAAK;AACnE;","names":["profile"]}
1
+ {"version":3,"sources":["../../src/profile/index.ts"],"sourcesContent":["/**\n * Profile composer + evolvable-section seam for agent products.\n *\n * The standard \"load a deployable AgentProfile, including skills, plus the\n * skills the end user added to their own instance\" entry point. A product holds\n * a canonical base `AgentProfile` (role/environment/tool-conventions rendered\n * into `prompt.systemPrompt`, baseline skills, baseline MCP). At deploy/turn\n * time it layers four file-mount channels onto `resources.files` —\n *\n * 1. skills — the always-mounted product skill corpus\n * 2. knowledge — a second always-mounted corpus (domain knowledge pack)\n * 3. registry — the tier-gated installable registry (free -> boot-mounted)\n * 4. userSkills — per-user / per-workspace skills the END USER adds to their\n * own instance, mounted at `~/.claude/skills/<id>/SKILL.md`\n * exactly like the registry's free tier\n *\n * plus an optional MCP overlay (delegation + per-turn app-tool side channel), a\n * per-turn `systemPrompt` override, and a `name` override. The canonical\n * `mergeAgentProfiles` contract makes `mcp` last-wins per key (base -> overlay),\n * concatenates `resources` arrays (base ++ overlay), and shallow-merges `prompt`\n * so an overlay carrying only `systemPrompt` overrides it while keeping base\n * instructions. The compose algebra is DATA — the product injects the base\n * profile, the channel mounts (built with the `skills` subpath primitives), the\n * delegation/app-tool MCP map, and the override strings; nothing here reaches\n * for env, a glob, or a specific product's profile.\n *\n * The evolvable-section seam is the loader closure. A product's single\n * self-improvable domain section (the one `applyDomainPatch` targets) loads its\n * body from a deployed markdown override, falling back to an in-tree baseline.\n * The `import.meta.glob('<lit>', ...)` literal must stay at the CONSUMER call\n * site (Vite static-analyzes it), so `makeEvolvableSection` takes the loader as\n * a closure and a REQUIRED `baseline` — it never constructs a glob and never\n * defaults the baseline, so a product can't render an empty learned-guidance\n * section. `stripComments` is the shared \"is this addendum really empty?\" test.\n */\n\nimport type {\n AgentProfile,\n AgentProfileFileMount,\n AgentProfileMcpServer,\n AgentProfileResourceRef,\n} from '@tangle-network/agent-interface'\nimport { mergeAgentProfiles } from '@tangle-network/agent-interface'\nimport { profile } from '@tangle-network/agent-eval'\nimport {\n composeShellResources,\n registrySkills,\n skillMountPath,\n type ComposeShellResourcesInput,\n type SkillEntry,\n} from '../skills/index'\nimport { assertSystemPromptWithinBudget, type ComposeProfileBudget } from './budget'\n\n/** The prompt byte budget lives in `./budget` (import-free) so `/sandbox` can\n * run the same gate without pulling agent-eval through this module. Re-exported\n * here so the published `/profile` surface is unchanged. */\nexport {\n assertProfilePromptWithinBudget,\n assertSystemPromptWithinBudget,\n DEFAULT_MAX_SYSTEM_PROMPT_BYTES,\n largestPromptSections,\n type ComposeProfileBudget,\n} from './budget'\n\n/** Re-expose the agent-eval section/render substrate so a product wires the\n * evolvable surface through ONE subpath: `makeEvolvableSection` builds the\n * section, `profile.renderProfile` renders it, `profile.applyDomainPatch` lets\n * the loop patch it by id. The rendering/patching engine stays in agent-eval;\n * reach it through this namespace (re-exporting the bare fns would leak\n * agent-eval's un-nameable AgentProfile type into our generated d.ts). */\nexport { profile }\n\n/** The file-mount channels layered onto `resources.files`. The first three\n * mirror {@link ComposeShellResourcesInput}; `userSkills` is the per-user /\n * per-workspace channel — skills the END USER added to their own instance,\n * mounted at the harness skill-discovery path like the registry's free tier. */\nexport interface ProfileChannels {\n /** Always-mounted skill corpus (pass `corpusSkills(...)`). */\n skills?: AgentProfileFileMount[]\n /** Always-mounted knowledge corpus (pass `corpusSkills(...)` for the pack). */\n knowledge?: AgentProfileFileMount[]\n /** Single-file evolvable / learned-guidance corpora, if mounted as files. */\n evolvable?: AgentProfileFileMount[]\n /** Tier-gated installable registry (pass the registry array; free tier is\n * mounted, paid is install-on-demand). Gated through {@link registrySkills}. */\n registry?: SkillEntry[]\n /** Per-user / per-workspace skills the end user adds to their own instance.\n * Mounted at `~/.claude/skills/<id>/SKILL.md`, the same harness path the\n * registry uses, so a user skill and a registry skill with the same id\n * collide deterministically (the user skill, appended last, wins). */\n userSkills?: UserSkill[]\n /** Final skip filter applied to the composed mount list by mount `path`. */\n filesPredicate?: (mount: AgentProfileFileMount) => boolean\n /** Typed `resources.skills` channel — refs the platform materializer places\n * at the harness-native skill dir (see {@link skillRefs} and\n * `@tangle-network/agent-app/skills-placement`'s `composeSkillsForHarness`).\n * The successor to path-baked mounts: `registry`/`userSkills` above mount\n * files at the hardcoded claude-code path via {@link skillMountPath};\n * `skillRefs` instead rides the provider-neutral `resources.skills` field\n * the platform resolves per harness. */\n skillRefs?: AgentProfileResourceRef[]\n /** Tier passed to {@link registrySkills} for the `registry` channel.\n * Previously hardcoded `'free'`; default unchanged. */\n registryTier?: string\n}\n\n/** A per-user / per-workspace skill: an id and an inline `SKILL.md` body. The\n * user-facing analogue of a registry {@link SkillEntry} with no tier gate —\n * every user skill is mounted (the user opted in by adding it). */\nexport interface UserSkill {\n id: string\n /** Inline `SKILL.md` body mounted at {@link skillMountPath}. */\n skillMd: string\n}\n\n/** Overlay overrides applied on top of the channel mounts. */\nexport interface ProfileOverlay {\n /** Extra MCP servers merged into the profile `mcp` map (last-wins per key over\n * the base servers). The product builds this from its delegation MCP entry\n * and any per-turn app-tool side-channel servers. An absent/`undefined` entry\n * is dropped — pass only the servers that resolved (fail-closed at the seam,\n * not here). */\n mcp?: Record<string, AgentProfileMcpServer>\n /** Per-turn system-prompt override. When set, replaces the base\n * `prompt.systemPrompt` while keeping base `prompt.instructions`. When unset,\n * the base prompt passes through unchanged. */\n systemPrompt?: string\n /** Extra instruction lines merged onto the active prompt (e.g. a per-turn\n * domain/integration directive). Appended to base `prompt.instructions` by\n * the SDK merge. */\n instructions?: string[]\n /** Profile `name` override. When unset, the base name is kept. */\n name?: string\n}\n\n/** Project per-user skills onto SDK file mounts at the harness skill-discovery\n * path. No tier gate — a user skill is mounted because the user added it.\n * Sorted by path for determinism (matches {@link registrySkills}). */\nexport function userSkillMounts(userSkills: UserSkill[]): AgentProfileFileMount[] {\n return userSkills\n .map(\n (s) =>\n ({\n path: skillMountPath(s.id),\n resource: { kind: 'inline', name: s.id, content: s.skillMd },\n }) satisfies AgentProfileFileMount,\n )\n .sort((a, b) => a.path.localeCompare(b.path))\n}\n\n/**\n * Compose a deployable `AgentProfile` from a canonical base plus the four\n * file-mount channels and the overlay overrides.\n *\n * Files: base `resources.files` come first; the four channels follow in\n * `skills -> knowledge -> evolvable -> registry -> userSkills` order (so a\n * userSkill that mounts at the same path as a registry skill is the last write\n * and wins). MCP: base servers first, the overlay `mcp` last (last-wins per\n * key). Prompt: the overlay `systemPrompt`, when set, replaces the base one;\n * base instructions are preserved. Name: the overlay `name`, when set, wins.\n *\n * The merge delegates to the SDK `mergeAgentProfiles` (overlay-wins on records,\n * arrays concatenated) — the deterministic algebra is the overlay we hand it,\n * not a hand-rolled spread. `mergeAgentProfiles(base, overlay)` returns\n * `undefined` only when BOTH are `undefined`; `base` is always defined here, so\n * the result is non-`undefined` by construction and we assert that to the caller.\n *\n * The composed `prompt.systemPrompt` is byte-budgeted here — the single point\n * where the FINAL prompt exists ({@link assertSystemPromptWithinBudget};\n * default {@link DEFAULT_MAX_SYSTEM_PROMPT_BYTES}, `warnOnly` escape hatch).\n */\nexport function composeAgentProfile(\n base: AgentProfile,\n channels: ProfileChannels = {},\n overlay: ProfileOverlay = {},\n budget: ComposeProfileBudget = {},\n): AgentProfile {\n const shellInput: ComposeShellResourcesInput = {\n skills: channels.skills,\n knowledge: channels.knowledge,\n evolvable: channels.evolvable,\n registry: channels.registry\n ? registrySkills(channels.registry, channels.registryTier ?? 'free')\n : undefined,\n predicate: channels.filesPredicate,\n }\n const channelFiles = composeShellResources(shellInput)\n const userFiles = channels.userSkills ? userSkillMounts(channels.userSkills) : []\n const overlayFiles = channels.filesPredicate\n ? userFiles.filter(channels.filesPredicate)\n : userFiles\n const files = [...channelFiles, ...overlayFiles]\n\n const promptOverlay: { systemPrompt?: string; instructions?: string[] } = {}\n if (overlay.systemPrompt) promptOverlay.systemPrompt = overlay.systemPrompt\n if (overlay.instructions && overlay.instructions.length > 0) promptOverlay.instructions = overlay.instructions\n\n const overlayProfile: AgentProfile = {\n ...(overlay.name ? { name: overlay.name } : {}),\n ...(Object.keys(promptOverlay).length > 0 ? { prompt: promptOverlay } : {}),\n ...(overlay.mcp ? { mcp: overlay.mcp } : {}),\n resources: {\n files,\n ...(channels.skillRefs && channels.skillRefs.length > 0 ? { skills: channels.skillRefs } : {}),\n },\n }\n\n const merged = mergeAgentProfiles(base, overlayProfile)\n if (!merged)\n throw new Error('composeAgentProfile: mergeAgentProfiles returned undefined for a defined base')\n // Byte-budget gate on the FINAL composed systemPrompt — this is the single\n // point where every channel and overlay has been merged in.\n const systemPrompt = merged.prompt?.systemPrompt\n if (typeof systemPrompt === 'string') assertSystemPromptWithinBudget(systemPrompt, budget)\n return pruneEmptyResourceChannels(merged)\n}\n\n/** Drop absent and empty resource channels the canonical merge normalizes in,\n * so the composed profile's wire payload carries\n * only the channels that actually have content — one canonical shape every app\n * emits, instead of a sidecar payload full of empty arrays. */\nfunction pruneEmptyResourceChannels(profile: AgentProfile): AgentProfile {\n if (!profile.resources) return profile\n const kept = Object.fromEntries(\n Object.entries(profile.resources).filter(([, value]) =>\n value !== undefined && !(Array.isArray(value) && value.length === 0),\n ),\n ) as AgentProfile['resources']\n const out: AgentProfile = { ...profile, resources: kept }\n if (kept && Object.keys(kept).length === 0) delete out.resources\n return out\n}\n\n/** True body of an addendum file with HTML comments stripped — an all-comment\n * placeholder counts as empty, so the loader falls back to the baseline. */\nexport function stripComments(raw: string): string {\n return raw.replace(/<!--[\\s\\S]*?-->/g, '').trim()\n}\n\n/** Inputs to {@link makeEvolvableSection}. */\nexport interface EvolvableSectionInput {\n /** Section id the self-improvement loop targets with `applyDomainPatch`. */\n id: string\n /** Section title rendered as `### <title>`. */\n title: string\n /**\n * Load the deployed section body. The CONSUMER supplies this closure and runs\n * its own `import.meta.glob('<lit>', { eager: true, query: '?raw', import:\n * 'default' })` inside it — the literal must stay at the call site so Vite can\n * static-analyze it; a glob constructed here would not resolve the product's\n * files. Return the raw markdown (comments and all); `makeEvolvableSection`\n * applies {@link stripComments} to decide whether it is really populated.\n */\n load: () => string\n /**\n * The in-tree fallback body, used when `load()` returns an\n * all-comments/empty placeholder. REQUIRED — no internal default — so a\n * product can never accidentally render an empty evolvable section.\n */\n baseline: string\n}\n\n/**\n * Build the one evolvable (`evolvable: true`) domain section whose body comes\n * from the product's loader, falling back to the required baseline when the\n * loaded body is empty after stripping comments. Returns the agent-eval\n * `AgentProfileSection` shape — drop it straight into `prodProfile`'s shipped\n * sections. The loader is the only seam; the empty-vs-populated rule and the\n * baseline fallback are the lifted algebra.\n */\nexport function makeEvolvableSection(input: EvolvableSectionInput): profile.AgentProfileSection {\n const loaded = input.load()\n const body = stripComments(loaded) ? loaded.trim() : input.baseline\n return { id: input.id, title: input.title, body, evolvable: true }\n}\n\nexport {\n assertSkillDeliveryDisjoint,\n composeShellResources,\n composeSkills,\n corpusSkills,\n loadMarkdownCorpus,\n mergeComposedSkills,\n parseCorpusSkills,\n parseSkillFrontmatter,\n registrySkills,\n renderInlineSkills,\n renderSkillIndex,\n skillEntryFromMarkdown,\n skillMountPath,\n skillRefs,\n} from '../skills/index'\nexport type {\n ComposedSkills,\n ComposeShellResourcesInput,\n CorpusEntry,\n CorpusLoadResult,\n GlobModules,\n LoadCorpusOptions,\n ParsedSkill,\n SkillDeliveryMode,\n SkillEntry,\n SkillFrontmatter,\n} from '../skills/index'\nexport {\n diffProfileFingerprints,\n fingerprintAgentProfile,\n formatProfileDrift,\n} from './fingerprint'\nexport type {\n ProfileDrift,\n ProfileDriftEntry,\n ProfileFingerprint,\n ProfileFingerprintContext,\n} from './fingerprint'\n\nexport { DEFAULT_HOME_LIMITS, defaultHomeFiles, withDefaultAgentHome } from './home'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,SAAS,0BAA0B;AACnC,SAAS,eAAe;AA+FjB,SAAS,gBAAgB,YAAkD;AAChF,SAAO,WACJ;AAAA,IACC,CAAC,OACE;AAAA,MACC,MAAM,eAAe,EAAE,EAAE;AAAA,MACzB,UAAU,EAAE,MAAM,UAAU,MAAM,EAAE,IAAI,SAAS,EAAE,QAAQ;AAAA,IAC7D;AAAA,EACJ,EACC,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAChD;AAuBO,SAAS,oBACd,MACA,WAA4B,CAAC,GAC7B,UAA0B,CAAC,GAC3B,SAA+B,CAAC,GAClB;AACd,QAAM,aAAyC;AAAA,IAC7C,QAAQ,SAAS;AAAA,IACjB,WAAW,SAAS;AAAA,IACpB,WAAW,SAAS;AAAA,IACpB,UAAU,SAAS,WACf,eAAe,SAAS,UAAU,SAAS,gBAAgB,MAAM,IACjE;AAAA,IACJ,WAAW,SAAS;AAAA,EACtB;AACA,QAAM,eAAe,sBAAsB,UAAU;AACrD,QAAM,YAAY,SAAS,aAAa,gBAAgB,SAAS,UAAU,IAAI,CAAC;AAChF,QAAM,eAAe,SAAS,iBAC1B,UAAU,OAAO,SAAS,cAAc,IACxC;AACJ,QAAM,QAAQ,CAAC,GAAG,cAAc,GAAG,YAAY;AAE/C,QAAM,gBAAoE,CAAC;AAC3E,MAAI,QAAQ,aAAc,eAAc,eAAe,QAAQ;AAC/D,MAAI,QAAQ,gBAAgB,QAAQ,aAAa,SAAS,EAAG,eAAc,eAAe,QAAQ;AAElG,QAAM,iBAA+B;AAAA,IACnC,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,IAC7C,GAAI,OAAO,KAAK,aAAa,EAAE,SAAS,IAAI,EAAE,QAAQ,cAAc,IAAI,CAAC;AAAA,IACzE,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,IAC1C,WAAW;AAAA,MACT;AAAA,MACA,GAAI,SAAS,aAAa,SAAS,UAAU,SAAS,IAAI,EAAE,QAAQ,SAAS,UAAU,IAAI,CAAC;AAAA,IAC9F;AAAA,EACF;AAEA,QAAM,SAAS,mBAAmB,MAAM,cAAc;AACtD,MAAI,CAAC;AACH,UAAM,IAAI,MAAM,+EAA+E;AAGjG,QAAM,eAAe,OAAO,QAAQ;AACpC,MAAI,OAAO,iBAAiB,SAAU,gCAA+B,cAAc,MAAM;AACzF,SAAO,2BAA2B,MAAM;AAC1C;AAMA,SAAS,2BAA2BA,UAAqC;AACvE,MAAI,CAACA,SAAQ,UAAW,QAAOA;AAC/B,QAAM,OAAO,OAAO;AAAA,IAClB,OAAO,QAAQA,SAAQ,SAAS,EAAE;AAAA,MAAO,CAAC,CAAC,EAAE,KAAK,MAChD,UAAU,UAAa,EAAE,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW;AAAA,IACpE;AAAA,EACF;AACA,QAAM,MAAoB,EAAE,GAAGA,UAAS,WAAW,KAAK;AACxD,MAAI,QAAQ,OAAO,KAAK,IAAI,EAAE,WAAW,EAAG,QAAO,IAAI;AACvD,SAAO;AACT;AAIO,SAAS,cAAc,KAAqB;AACjD,SAAO,IAAI,QAAQ,oBAAoB,EAAE,EAAE,KAAK;AAClD;AAiCO,SAAS,qBAAqB,OAA2D;AAC9F,QAAM,SAAS,MAAM,KAAK;AAC1B,QAAM,OAAO,cAAc,MAAM,IAAI,OAAO,KAAK,IAAI,MAAM;AAC3D,SAAO,EAAE,IAAI,MAAM,IAAI,OAAO,MAAM,OAAO,MAAM,WAAW,KAAK;AACnE;","names":["profile"]}
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createChatTurnRoutes,
3
3
  streamChatRouteAsSandboxEvents
4
- } from "../chunk-V4YGTOCS.js";
5
- import "../chunk-ZSSCVT6H.js";
4
+ } from "../chunk-MIFVOYZ7.js";
6
5
  import "../chunk-EA4UVS4T.js";
7
- import "../chunk-4PZE7XAM.js";
8
- import "../chunk-ZVEEWGDK.js";
6
+ import "../chunk-ZSSCVT6H.js";
7
+ import "../chunk-S3344RBY.js";
9
8
  import "../chunk-X47R2IVO.js";
10
9
  import "../chunk-TXD5HXLE.js";
10
+ import "../chunk-ZVEEWGDK.js";
11
11
  import "../chunk-3NM4GCAY.js";
12
12
  import "../chunk-ZMMIQOFI.js";
13
13
  import "../chunk-M3K2HVQD.js";
@@ -0,0 +1,34 @@
1
+ import type { LineMember } from '@tangle-network/sandbox';
2
+ import type { LineBillingView, LineMembersClient, LineSetupClient, LineSetupSnapshot } from '../../hosted-agent/react';
3
+ export declare const workspaceName = "Example workspace";
4
+ export declare const setupEmpty: LineSetupSnapshot;
5
+ export declare const setupConnected: LineSetupSnapshot;
6
+ export declare const setupDisconnected: LineSetupSnapshot;
7
+ export declare const setupMultiNumberDisconnected: LineSetupSnapshot;
8
+ export declare const setupManualNumberReconnect: LineSetupSnapshot;
9
+ export declare function createSetupClient(initial: LineSetupSnapshot): LineSetupClient;
10
+ /** Let a mutation succeed, fail its next read once, then allow Retry to recover. */
11
+ export declare function createSetupRefreshFailureClient(initial: LineSetupSnapshot): LineSetupClient;
12
+ export declare const memberRoles: readonly [{
13
+ readonly value: 'owner';
14
+ readonly label: 'Owner';
15
+ readonly tools: 'act';
16
+ }, {
17
+ readonly value: 'manager';
18
+ readonly label: 'Manager';
19
+ readonly tools: 'act';
20
+ }, {
21
+ readonly value: 'member';
22
+ readonly label: 'Member';
23
+ readonly tools: 'act';
24
+ }, {
25
+ readonly value: 'chat-only';
26
+ readonly label: 'Guest';
27
+ readonly tools: 'chat';
28
+ }];
29
+ export declare const members: LineMember[];
30
+ export declare function createMembersClient(initial: LineMember[]): LineMembersClient;
31
+ /** Retain the successful write while the next member list read fails once. */
32
+ export declare function createMembersRefreshFailureClient(initial: LineMember[]): LineMembersClient;
33
+ export declare const billingUnverified: LineBillingView;
34
+ export declare const billingVerified: LineBillingView;
@@ -1,8 +1,3 @@
1
- import {
2
- generateInviteToken,
3
- isInviteTokenShape,
4
- validateInviteToken
5
- } from "../chunk-DJ4VJIH5.js";
6
1
  import {
7
2
  INVITATION_EXPIRY_DAYS,
8
3
  generateInvitationToken,
@@ -12,6 +7,11 @@ import {
12
7
  parseInvitationPermission,
13
8
  renderInvitationEmail
14
9
  } from "../chunk-2DRYTJHI.js";
10
+ import {
11
+ generateInviteToken,
12
+ isInviteTokenShape,
13
+ validateInviteToken
14
+ } from "../chunk-DJ4VJIH5.js";
15
15
  import {
16
16
  ASSIGNABLE_WORKSPACE_ROLES,
17
17
  ORGANIZATION_ROLES,
@@ -1,7 +1,3 @@
1
- import {
2
- SeatLimitError
3
- } from "../chunk-MEUNTJL5.js";
4
- import "../chunk-DJ4VJIH5.js";
5
1
  import {
6
2
  generateInvitationToken,
7
3
  getInvitationExpiresAt,
@@ -9,6 +5,10 @@ import {
9
5
  normalizeInvitationEmail,
10
6
  parseInvitationPermission
11
7
  } from "../chunk-2DRYTJHI.js";
8
+ import {
9
+ SeatLimitError
10
+ } from "../chunk-MEUNTJL5.js";
11
+ import "../chunk-DJ4VJIH5.js";
12
12
  import {
13
13
  hasWorkspaceRole
14
14
  } from "../chunk-6XIAPIW6.js";
@@ -371,10 +371,27 @@
371
371
  * An outline, not a `ring-*` box-shadow, because an outline is not painted by
372
372
  * the element's own background/shadow stack — it cannot be covered by a sibling
373
373
  * and it needs no `ring-offset-color` matched to whatever surface it sits on.
374
+ *
375
+ * The rule lives in `@layer base` for the same contract. Tailwind v4 hosts put
376
+ * every utility in `@layer utilities`, and an UNLAYERED rule beats ANY layered
377
+ * one regardless of specificity — measured in the playground, where the bare
378
+ * floor out-painted even `.focus\:outline-none:focus` and painted a second
379
+ * strong outline inside the composer card's own ring. In v4's declared order
380
+ * (`theme, base, components, utilities`) base sits under utilities, and in
381
+ * unlayered v3 hosts an unlayered utility beats a layered floor, so the
382
+ * opt-out above wins in both and the specificity ladder in this comment is
383
+ * no longer hostage to stylesheet import order.
374
384
  */
375
- :focus-visible {
376
- outline: var(--focus-ring-width) solid var(--focus-ring-color);
377
- outline-offset: var(--focus-ring-offset);
385
+ @layer base {
386
+ :focus-visible {
387
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
388
+ outline-offset: var(--focus-ring-offset);
389
+ }
390
+
391
+ /* The composer card owns keyboard feedback through its themeable ring. */
392
+ [data-composer-input]:focus-visible {
393
+ outline: none;
394
+ }
378
395
  }
379
396
 
380
397
  [data-theme='dark'],
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Self-contained confirm dialog — no dialog library. A focus-trapped modal with
3
- * Esc-to-cancel and Enter-to-confirm, used for create / delete / discard-unsaved
3
+ * Escape-to-cancel and Enter from text inputs, used for create / delete / discard-unsaved
4
4
  * flows so the pane carries zero UI-kit dependency.
5
5
  */
6
6
  import { type ReactNode } from 'react';
@@ -11,10 +11,10 @@
11
11
  * optional `codec` seam supplies rich/source parsing (identity passthrough by
12
12
  * default). Chrome uses the shared theme tokens (bg-card, border-border, …).
13
13
  */
14
- import type { VaultPaneProps } from './contracts';
14
+ import type { VaultPaneHandle, VaultPaneProps } from './contracts';
15
15
  /**
16
16
  * Browse and edit files in the available pane width.
17
17
  * Below 45rem, Files and the selected document share one pane.
18
18
  * Switching panes keeps the editor mounted and preserves unsaved changes.
19
19
  */
20
- export declare function VaultPane(props: VaultPaneProps): import("react").JSX.Element;
20
+ export declare const VaultPane: import("react").ForwardRefExoticComponent<VaultPaneProps & import("react").RefAttributes<VaultPaneHandle>>;
@@ -92,6 +92,14 @@ export interface VaultMarkdownCodec {
92
92
  parse(raw: string): VaultRichParts;
93
93
  serialize(parts: VaultRichParts): string;
94
94
  }
95
+ /** File navigation requested by controls outside the pane. */
96
+ export interface VaultPaneHandle {
97
+ /**
98
+ * Request a file, confirming unsaved edits before changing selection.
99
+ * The path need not appear in the current tree; the data port validates and reads it.
100
+ */
101
+ openFile: (path: string) => void;
102
+ }
95
103
  /** Props the pane passes to the product's tree renderer (e.g. RichFileTree). */
96
104
  export interface VaultTreeRenderProps {
97
105
  root: VaultTreeNode;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ConfirmDialog,
3
3
  VaultPane
4
- } from "../chunk-FCUWRMAF.js";
4
+ } from "../chunk-56SVXAIK.js";
5
5
  export {
6
6
  ConfirmDialog,
7
7
  VaultPane
@@ -4,7 +4,7 @@
4
4
  * component directly, so the pane chunk loads on first render. Mount inside a
5
5
  * `<Suspense>` boundary; the product provides the fallback.
6
6
  */
7
- import type { VaultPaneProps } from './contracts';
8
- export type { VaultPaneProps };
7
+ import type { VaultPaneHandle, VaultPaneProps } from './contracts';
8
+ export type { VaultPaneHandle, VaultPaneProps };
9
9
  /** Resolve VaultPane component lazily to optimize loading and improve performance */
10
- export declare const VaultPaneLazy: import("react").LazyExoticComponent<typeof import("./VaultPane").VaultPane>;
10
+ export declare const VaultPaneLazy: import("react").LazyExoticComponent<import("react").ForwardRefExoticComponent<VaultPaneProps & import("react").RefAttributes<VaultPaneHandle>>>;
@@ -1,7 +1,7 @@
1
1
  // src/vault/lazy.tsx
2
2
  import { lazy } from "react";
3
3
  var VaultPaneLazy = lazy(
4
- () => import("../VaultPane-32HVWZ6A.js").then((m) => ({ default: m.VaultPane }))
4
+ () => import("../VaultPane-2SJSP6TS.js").then((m) => ({ default: m.VaultPane }))
5
5
  );
6
6
  export {
7
7
  VaultPaneLazy
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/vault/lazy.tsx"],"sourcesContent":["/**\n * Code-split entry for the vault surface. Products that don't need the vault on\n * initial load import `VaultPaneLazy` (a `React.lazy` handle) instead of the\n * component directly, so the pane chunk loads on first render. Mount inside a\n * `<Suspense>` boundary; the product provides the fallback.\n */\n\nimport { lazy } from 'react'\nimport type { VaultPaneProps } from './contracts'\n\nexport type { VaultPaneProps }\n\n/** Resolve VaultPane component lazily to optimize loading and improve performance */\nexport const VaultPaneLazy = lazy(\n () => import('./VaultPane').then((m) => ({ default: m.VaultPane })),\n)\n"],"mappings":";AAOA,SAAS,YAAY;AAMd,IAAM,gBAAgB;AAAA,EAC3B,MAAM,OAAO,0BAAa,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE;AACpE;","names":[]}
1
+ {"version":3,"sources":["../../src/vault/lazy.tsx"],"sourcesContent":["/**\n * Code-split entry for the vault surface. Products that don't need the vault on\n * initial load import `VaultPaneLazy` (a `React.lazy` handle) instead of the\n * component directly, so the pane chunk loads on first render. Mount inside a\n * `<Suspense>` boundary; the product provides the fallback.\n */\n\nimport { lazy } from 'react'\nimport type { VaultPaneHandle, VaultPaneProps } from './contracts'\n\nexport type { VaultPaneHandle, VaultPaneProps }\n\n/** Resolve VaultPane component lazily to optimize loading and improve performance */\nexport const VaultPaneLazy = lazy(\n () => import('./VaultPane').then((m) => ({ default: m.VaultPane })),\n)\n"],"mappings":";AAOA,SAAS,YAAY;AAMd,IAAM,gBAAgB;AAAA,EAC3B,MAAM,OAAO,0BAAa,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE;AACpE;","names":[]}
@@ -128,7 +128,7 @@ import {
128
128
  withoutRecordGridCreated,
129
129
  withoutRecordGridRemoved,
130
130
  withoutRecordGridUpdate
131
- } from "../chunk-VIL6MHHQ.js";
131
+ } from "../chunk-XTLYE2VO.js";
132
132
  import {
133
133
  SessionHistoryPanel,
134
134
  formatSessionTimestamp,
@@ -139,26 +139,7 @@ import {
139
139
  import {
140
140
  MENTION_PILL_CLASS
141
141
  } from "../chunk-3HUFJ5LO.js";
142
- import {
143
- tabTerminalConnectionId,
144
- useSandboxTerminalConnection
145
- } from "../chunk-BATKJP3P.js";
146
142
  import "../chunk-FBVLEGEG.js";
147
- import {
148
- EvidenceLineageTable,
149
- ExceptionList,
150
- ProvenanceStamp,
151
- QualityCheckList,
152
- ReviewQueuePanel,
153
- WorkProductCard,
154
- mergeReviewQueuePages,
155
- reviewQueueStateLabel,
156
- workProductPartsFromMessageParts,
157
- workProductStatusLabel
158
- } from "../chunk-ENLRJYVW.js";
159
- import {
160
- parseReviewQueueItem
161
- } from "../chunk-GEYACSFW.js";
162
143
  import {
163
144
  AgentSessionControls,
164
145
  ChatComposer,
@@ -174,7 +155,7 @@ import {
174
155
  renamePastedImages,
175
156
  useComposerAttachments,
176
157
  useDictation
177
- } from "../chunk-TNWQA5XJ.js";
158
+ } from "../chunk-NLNM5PP6.js";
178
159
  import "../chunk-L7MB2LLM.js";
179
160
  import {
180
161
  DEFAULT_EFFORT_LEVELS,
@@ -193,7 +174,26 @@ import {
193
174
  usePending,
194
175
  usePopover
195
176
  } from "../chunk-4I76LTZS.js";
177
+ import {
178
+ tabTerminalConnectionId,
179
+ useSandboxTerminalConnection
180
+ } from "../chunk-BATKJP3P.js";
196
181
  import "../chunk-SJWIZT7B.js";
182
+ import {
183
+ EvidenceLineageTable,
184
+ ExceptionList,
185
+ ProvenanceStamp,
186
+ QualityCheckList,
187
+ ReviewQueuePanel,
188
+ WorkProductCard,
189
+ mergeReviewQueuePages,
190
+ reviewQueueStateLabel,
191
+ workProductPartsFromMessageParts,
192
+ workProductStatusLabel
193
+ } from "../chunk-ENLRJYVW.js";
194
+ import {
195
+ parseReviewQueueItem
196
+ } from "../chunk-GEYACSFW.js";
197
197
  import "../chunk-3UBAO3N5.js";
198
198
  import "../chunk-FQYAJYPW.js";
199
199
  import {
@@ -208,8 +208,7 @@ import {
208
208
  isChatAttachmentPart,
209
209
  mentionInputToPart,
210
210
  mentionPartsFromMessageParts
211
- } from "../chunk-4PZE7XAM.js";
212
- import "../chunk-ZVEEWGDK.js";
211
+ } from "../chunk-S3344RBY.js";
213
212
  import {
214
213
  DISPATCH_MAX_MEDIA_PARTS,
215
214
  DISPATCH_MAX_PARTS,
@@ -223,6 +222,7 @@ import {
223
222
  mentionKindForPath
224
223
  } from "../chunk-X47R2IVO.js";
225
224
  import "../chunk-TXD5HXLE.js";
225
+ import "../chunk-ZVEEWGDK.js";
226
226
  import {
227
227
  attachmentPartKey
228
228
  } from "../chunk-ZMMIQOFI.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-app",
3
- "version": "0.49.33",
3
+ "version": "0.49.35",
4
4
  "packageManager": "pnpm@11.24.0",
5
5
  "description": "Build agent applications with typed chat, tools, sandboxes, integrations, billing, and evaluation.",
6
6
  "keywords": [
@@ -38,7 +38,8 @@
38
38
  "agent-app-peer-check": "./dist/peer-floors/cli.js",
39
39
  "agent-app-spend-check": "./dist/spend/cli.js",
40
40
  "agent-app-signoff": "./dist/signoff/cli.js",
41
- "agent-app-verify-proof": "./dist/signoff/proof-cli.js"
41
+ "agent-app-verify-proof": "./dist/signoff/proof-cli.js",
42
+ "tangle-agent": "bin/tangle-agent.mjs"
42
43
  },
43
44
  "exports": {
44
45
  "./package.json": "./package.json",
@@ -222,6 +223,15 @@
222
223
  "import": "./dist/hosted-agent/index.js",
223
224
  "default": "./dist/hosted-agent/index.js"
224
225
  },
226
+ "./hosted-agent/react": {
227
+ "types": "./dist/hosted-agent/react/index.d.ts",
228
+ "import": "./dist/hosted-agent/react/index.js",
229
+ "default": "./dist/hosted-agent/react/index.js"
230
+ },
231
+ "./hosted-agent/react/styles": {
232
+ "types": "./dist/hosted-agent/react/styles.d.ts",
233
+ "default": "./dist/hosted-agent/react/lines.css"
234
+ },
225
235
  "./interactions": {
226
236
  "types": "./dist/interactions/index.d.ts",
227
237
  "import": "./dist/interactions/index.js",
@@ -545,16 +555,16 @@
545
555
  "@storybook/react-vite": "^10.5.10",
546
556
  "@tailwindcss/postcss": "^4.3.3",
547
557
  "@tangle-network/agent-docs": "0.2.1",
548
- "@tangle-network/agent-eval": "0.193.2",
558
+ "@tangle-network/agent-eval": "0.199.1",
549
559
  "@tangle-network/agent-gateway": "0.11.4",
550
- "@tangle-network/agent-integrations": "0.55.0",
560
+ "@tangle-network/agent-integrations": "0.57.0",
551
561
  "@tangle-network/agent-interface": "2.13.0",
552
- "@tangle-network/agent-knowledge": "17.1.8",
562
+ "@tangle-network/agent-knowledge": "17.1.10",
553
563
  "@tangle-network/agent-profile-materialize": "0.20.1",
554
- "@tangle-network/agent-runtime": "0.277.0",
564
+ "@tangle-network/agent-runtime": "0.282.2",
555
565
  "@tangle-network/brand": "1.5.0",
556
566
  "@tangle-network/hub-sdk": "0.19.3",
557
- "@tangle-network/sandbox": "0.53.0",
567
+ "@tangle-network/sandbox": "0.55.2",
558
568
  "@tangle-network/sandbox-ui": "0.113.3",
559
569
  "@tangle-network/ui": "11.9.0",
560
570
  "@testing-library/dom": "^10.4.1",
@@ -602,20 +612,27 @@
602
612
  "viem": "^2.56.0",
603
613
  "vitest": "^4.1.11",
604
614
  "y-protocols": "^1.0.7",
605
- "yjs": "^13.6.32"
615
+ "yjs": "^13.6.32",
616
+ "@modelcontextprotocol/sdk": "^1.30.0",
617
+ "@tangle-network/browser-agent-driver": "^0.36.1",
618
+ "@tangle-network/tcloud": "^0.5.2",
619
+ "playwright": "^1.63.0",
620
+ "@ai-sdk/google": "^3.0.33",
621
+ "@ai-sdk/anthropic": "^3.0.49",
622
+ "@anthropic-ai/sdk": "^0.93.0"
606
623
  },
607
624
  "peerDependencies": {
608
625
  "@firecrawl/pdf-inspector-wasm": ">=0.1.3",
609
626
  "@huggingface/transformers": ">=3",
610
- "@tangle-network/agent-eval": ">=0.185.0 <0.198.0",
611
- "@tangle-network/agent-integrations": ">=0.54.2 <0.56.0",
612
- "@tangle-network/agent-interface": "^2.11.0",
627
+ "@tangle-network/agent-eval": ">=0.199.0 <0.200.0",
628
+ "@tangle-network/agent-integrations": ">=0.54.2 <0.58.0",
629
+ "@tangle-network/agent-interface": "^2.13.0",
613
630
  "@tangle-network/agent-knowledge": "^17.1.2",
614
631
  "@tangle-network/agent-profile-materialize": ">=0.20.1 <0.21.0",
615
- "@tangle-network/agent-runtime": ">=0.262.0 <0.278.0",
632
+ "@tangle-network/agent-runtime": ">=0.282.2 <0.283.0",
616
633
  "@tangle-network/brand": ">=1.5.0",
617
634
  "@tangle-network/hub-sdk": ">=0.19.3 <0.20.0",
618
- "@tangle-network/sandbox": ">=0.45.0 <0.48.0 || ^0.49.0 || ^0.50.0 || ^0.51.0 || ^0.52.0 || ^0.53.0",
635
+ "@tangle-network/sandbox": ">=0.45.0 <0.48.0 || ^0.49.0 || ^0.50.0 || ^0.51.0 || ^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0",
619
636
  "@tangle-network/sandbox-ui": ">=0.113.3 <0.114.0",
620
637
  "@tangle-network/ui": ">=11.6.0 <12.0.0",
621
638
  "@tiptap/core": ">=3.28.0 <4.0.0",
@@ -634,7 +651,11 @@
634
651
  "react-dom": ">=18",
635
652
  "react-konva": ">=18",
636
653
  "react-router": ">=8.3.0",
637
- "resend": ">=6"
654
+ "resend": ">=6",
655
+ "@modelcontextprotocol/sdk": "^1.30.0",
656
+ "@tangle-network/browser-agent-driver": "^0.36.1",
657
+ "@tangle-network/tcloud": "^0.5.2",
658
+ "playwright": "^1.63.0"
638
659
  },
639
660
  "peerDependenciesMeta": {
640
661
  "@firecrawl/pdf-inspector-wasm": {
@@ -717,6 +738,18 @@
717
738
  },
718
739
  "@tangle-network/hub-sdk": {
719
740
  "optional": true
741
+ },
742
+ "@modelcontextprotocol/sdk": {
743
+ "optional": true
744
+ },
745
+ "@tangle-network/browser-agent-driver": {
746
+ "optional": true
747
+ },
748
+ "@tangle-network/tcloud": {
749
+ "optional": true
750
+ },
751
+ "playwright": {
752
+ "optional": true
720
753
  }
721
754
  },
722
755
  "dependencies": {
@@ -1,7 +0,0 @@
1
- import {
2
- VaultPane
3
- } from "./chunk-FCUWRMAF.js";
4
- export {
5
- VaultPane
6
- };
7
- //# sourceMappingURL=VaultPane-32HVWZ6A.js.map