{"version":3,"file":"policies-command.mjs","names":[],"sources":["../../../src/commands/policies-command.ts"],"sourcesContent":["/**\n * /policies — User-facing command for viewing and managing spending policies.\n *\n * Subcommands:\n *   /policies              — list all policies with their rules\n *   /policies <name>       — view a specific policy\n *   /policies enable <name>\n *   /policies disable <name>\n *   /policies delete <name>\n *\n * Policy CREATION is handled conversationally via the policy_manage tool.\n * Users just say what they want in plain English; the agent interprets.\n */\n\nimport { getPolicyStore } from '../services/policy-store.js';\nimport { getPolicyMode, isDelegationMode, describeRule } from '../services/policy-types.js';\nimport type { Policy } from '../services/policy-types.js';\nimport { buildPolicyDisplay, renderPolicyDisplay } from '../services/policy-evaluator.js';\nimport { formatDelegationStatus, canRedeem } from '../services/delegation-service.js';\nimport { CHAIN_NAMES } from '../services/delegation-types.js';\nimport { recordCommand } from '../services/command-history.js';\nimport { getWalletState } from '../services/walletconnect-service.js';\nimport { hasAgentAccount } from '../services/agent-keystore.js';\n\n/** Determine actual enforcement based on wallet mode + delegation setup. */\nfunction getEnforcementInfo(): { method: string; explanation: string } {\n  const wallet = getWalletState();\n  const hasAgent = hasAgentAccount();\n\n  if (wallet.mode === 'bankr') {\n    return {\n      method: 'AI-enforced (Bankr wallet)',\n      explanation: hasAgent\n        ? 'Your Bankr wallet sends transactions through its own API. Policies are enforced by the AI before execution — not on-chain. To use on-chain enforcement, send from your delegator account instead.'\n        : 'Your Bankr wallet sends transactions through its own API. Policies are enforced by the AI before execution — not on-chain. Run /delegator create to set up on-chain enforcement with a separate smart account.',\n    };\n  }\n\n  if (hasAgent) {\n    return {\n      method: 'On-chain (delegator smart account)',\n      explanation: 'Transactions from the delegator account are enforced on-chain by smart contract caveats. The agent cannot bypass these limits.',\n    };\n  }\n\n  return {\n    method: 'AI-enforced (no delegator set up)',\n    explanation: 'Policies are enforced by the AI before execution. Run /delegator create for tamper-proof on-chain enforcement.',\n  };\n}\n\nexport const policiesCommand = {\n  name: 'policies',\n  description: 'View and manage spending policies: /policies [enable|disable|delete] [name]',\n  acceptsArgs: true,\n  requireAuth: true,\n\n  handler: async (ctx?: any) => {\n    const args = (ctx?.args ?? '').trim();\n    const store = getPolicyStore();\n    const { extractPolicyUserId } = await import('../services/policy-evaluator.js');\n    let userId = extractPolicyUserId(ctx);\n    const ownerCount = store.listPolicies(userId).length;\n    if (ownerCount === 0) {\n      const found = store.findFirstUserWithPolicies();\n      if (found) {\n        const foundCount = store.listPolicies(found).length;\n        console.info(`[policies] userId=${userId} has 0 policies, found=${found} has ${foundCount}`);\n        if (foundCount > 0) userId = found;\n      } else {\n        console.info(`[policies] userId=${userId} has 0 policies, no alternative found`);\n      }\n    }\n\n    let result: { text: string };\n    if (!args) {\n      result = listAll(userId);\n    } else {\n      const parts = args.split(/\\s+/);\n      const sub = parts[0]!.toLowerCase();\n      const name = parts.slice(1).join(' ');\n\n      switch (sub) {\n        case 'create':  result = createQuick(userId, name); break;\n        case 'enable':  result = setStatus(userId, name, 'active'); break;\n        case 'disable': result = setStatus(userId, name, 'disabled'); break;\n        case 'delete':  result = deletePol(userId, name); break;\n        case 'overview': result = showOverview(userId); break;\n        default:        result = viewPolicy(userId, args); break;\n      }\n    }\n\n    // Record for LLM context injection\n    recordCommand(userId, `/policies ${args}`.trim(), result.text.slice(0, 150));\n    return result;\n  },\n};\n\n// ─── Quick Create ───────────────────────────────────────────────────────\n// /policies create <name> <amount>\n// Creates a max_amount policy directly without LLM.\n// Example: /policies create test-live 5\n\nfunction createQuick(userId: string, nameAndAmount: string) {\n  const parts = nameAndAmount.trim().split(/\\s+/);\n  const name = parts[0];\n  const amountStr = parts[1];\n\n  if (!name || !amountStr) {\n    return { text: [\n      'Usage: /policies create <name> <max-usd>',\n      '',\n      'Example:',\n      '  /policies create test-live 5',\n      '  (blocks any tx over $5)',\n      '',\n      '  /policies create daily-cap 100',\n      '  (blocks any tx over $100)',\n    ].join('\\n') };\n  }\n\n  const maxUsd = parseFloat(amountStr);\n  if (isNaN(maxUsd) || maxUsd <= 0) {\n    return { text: `Invalid amount: ${amountStr}. Use a positive number (USD).` };\n  }\n\n  const store = getPolicyStore();\n  const existing = store.getPolicyByName(userId, name);\n  if (existing) {\n    return { text: `Policy \"${name}\" already exists. Use /policies delete ${name} first.` };\n  }\n\n  const { randomUUID } = require('node:crypto');\n  const policy: Policy = {\n    id: randomUUID(),\n    name,\n    description: `Max $${maxUsd} per transaction`,\n    rules: [{ type: 'max_amount' as const, maxAmountUsd: maxUsd }],\n    scope: { type: 'all_write' as const },\n    status: 'active',\n    confirmedAt: Date.now(),\n    createdAt: Date.now(),\n    updatedAt: Date.now(),\n    userId,\n  };\n\n  store.savePolicy(policy);\n\n  return { text: [\n    `**Policy \"${name}\" created and active.**`,\n    '',\n    `  Rule: block any tx over $${maxUsd}`,\n    '  Scope: all write operations',\n    '',\n    'Next: /delegate create ' + name,\n  ].join('\\n') };\n}\n\nfunction listAll(userId: string) {\n  const store = getPolicyStore();\n  const policies = store.listPolicies(userId);\n\n  if (policies.length === 0) {\n    return {\n      text: [\n        '**No policies set.**',\n        '',\n        'To create a policy, just describe what you want in plain English:',\n        '  \"Don\\'t let me spend more than $500 a day on DeFi\"',\n        '  \"Block all interactions with SHIB\"',\n        '  \"Require my confirmation for anything over $100\"',\n        '',\n        'The agent will interpret your request, show you exactly what will be enforced, and ask for confirmation before activating.',\n      ].join('\\n'),\n    };\n  }\n\n  const mode = getPolicyMode();\n  const modeLabel = mode === 'delegation' ? 'delegation (on-chain)' : 'simple (app-layer)';\n  const lines: string[] = [\n    `**${policies.length} polic${policies.length === 1 ? 'y' : 'ies'}** — mode: ${modeLabel}`,\n    '',\n  ];\n\n  for (const p of policies) {\n    const display = buildPolicyDisplay(p, userId);\n    lines.push(renderPolicyDisplay(display));\n    if (p.delegation && isDelegationMode()) {\n      lines.push('');\n      lines.push('**On-chain delegation:**');\n      lines.push(formatDelegationStatus(p.delegation));\n    }\n    lines.push('');\n    lines.push('---');\n    lines.push('');\n  }\n\n  lines.push('Commands: `/policies enable <name>`, `/policies disable <name>`, `/policies delete <name>`');\n\n  return { text: lines.join('\\n') };\n}\n\nfunction viewPolicy(userId: string, nameOrId: string) {\n  const store = getPolicyStore();\n  let policy = store.getPolicyByName(userId, nameOrId);\n  if (!policy) policy = store.getPolicy(userId, nameOrId);\n  if (!policy) {\n    return { text: `Policy \"${nameOrId}\" not found. Use \\`/policies\\` to list all.` };\n  }\n\n  const display = buildPolicyDisplay(policy, userId);\n  const lines: string[] = [renderPolicyDisplay(display)];\n\n  // Include delegation info (same as list view)\n  if (isDelegationMode() && policy.delegation) {\n    lines.push('');\n    lines.push('**On-chain delegation:**');\n    lines.push(formatDelegationStatus(policy.delegation));\n\n    // Show expiry if set\n    if (policy.delegation.expiresAt) {\n      const exp = new Date(policy.delegation.expiresAt);\n      const remaining = exp.getTime() - Date.now();\n      if (remaining > 0) {\n        const hours = Math.floor(remaining / 3_600_000);\n        const days = Math.floor(hours / 24);\n        lines.push(`  Expires: ${exp.toISOString()} (${days > 0 ? `${days}d ` : ''}${hours % 24}h remaining)`);\n      } else {\n        lines.push('  Expires: **EXPIRED**');\n      }\n    }\n  }\n\n  return { text: lines.join('\\n') };\n}\n\n// ─── Overview ───────────────────────────────────────────────────────────\n\nfunction showOverview(userId: string) {\n  const store = getPolicyStore();\n  const policies = store.listPolicies(userId);\n  const mode = getPolicyMode();\n  const delegation = isDelegationMode();\n\n  const lines: string[] = [];\n  lines.push('**Policy Overview**');\n  lines.push('');\n\n  // Enforcement — what's actually happening\n  const enforcement = getEnforcementInfo();\n  lines.push(`Enforced by: **${enforcement.method}**`);\n  lines.push(enforcement.explanation);\n  lines.push('');\n\n  // Counts\n  const active = policies.filter(p => p.status === 'active');\n  const withDelegation = active.filter(p => p.delegation?.status === 'signed' || p.delegation?.status === 'active');\n  lines.push(`Policies: ${active.length} active${withDelegation.length > 0 ? `, ${withDelegation.length} with on-chain delegation` : ''}`);\n  lines.push('');\n\n  if (active.length === 0) {\n    lines.push('No active policies. Describe a policy in plain English and the agent will create it.');\n    return { text: lines.join('\\n') };\n  }\n\n  // Per-policy summary (compact table-like format)\n  for (const p of active) {\n    const rules = p.rules.map(r => describeRule(r));\n    const scopeLabel = p.scope.type === 'all_write' ? 'all write tools'\n      : p.scope.type === 'tools' ? (p.scope as any).tools?.join(', ')\n      : p.scope.type === 'categories' ? (p.scope as any).categories?.join(', ')\n      : p.scope.type;\n\n    lines.push(`**${p.name}**`);\n    lines.push(`  Scope: ${scopeLabel}`);\n    for (const r of rules) {\n      lines.push(`  Rule: ${r}`);\n    }\n\n    // Budget usage\n    const usage = store.getUsage?.(userId, p.id);\n    if (usage) {\n      for (const u of Array.isArray(usage) ? usage : []) {\n        if (u.spentUsd !== undefined && u.limitUsd !== undefined) {\n          const pct = Math.round((u.spentUsd / u.limitUsd) * 100);\n          const remaining = Math.max(0, u.limitUsd - u.spentUsd);\n          lines.push(`  Budget: $${u.spentUsd.toFixed(2)} / $${u.limitUsd} used (${pct}%, $${remaining.toFixed(2)} remaining)`);\n        }\n      }\n    }\n\n    // Delegation status (compact)\n    if (delegation && p.delegation) {\n      const d = p.delegation;\n      const chain = CHAIN_NAMES[d.chainId] ?? d.chainId;\n      const readiness = canRedeem(p.id);\n      const statusTag = readiness.ready ? 'READY' : 'NOT READY';\n\n      let expiryTag = '';\n      if (d.expiresAt) {\n        const remaining = new Date(d.expiresAt).getTime() - Date.now();\n        if (remaining <= 0) expiryTag = ' | EXPIRED';\n        else {\n          const h = Math.floor(remaining / 3_600_000);\n          expiryTag = h >= 24 ? ` | ${Math.floor(h / 24)}d remaining` : ` | ${h}h remaining`;\n        }\n      }\n\n      lines.push(`  Delegation: [${d.status.toUpperCase()}] on ${chain} | ${statusTag}${expiryTag}`);\n    } else if (delegation) {\n      lines.push('  Delegation: none (use `/delegate create ${p.name}`)');\n    }\n\n    lines.push('');\n  }\n\n  // Footer\n  lines.push('---');\n  lines.push('`/policies <name>` for details | `/delegate status` for on-chain state');\n\n  return { text: lines.join('\\n') };\n}\n\nfunction setStatus(userId: string, name: string, status: 'active' | 'disabled') {\n  if (!name) return { text: `Usage: \\`/policies ${status === 'active' ? 'enable' : 'disable'} <name>\\`` };\n\n  const store = getPolicyStore();\n  let policy = store.getPolicyByName(userId, name);\n  if (!policy) policy = store.getPolicy(userId, name);\n  if (!policy) return { text: `Policy \"${name}\" not found.` };\n\n  // Policies can be enabled regardless of confirmedAt — they may have been\n  // created via /policies create or via the LLM tool without the confirm step.\n\n  policy.status = status;\n  policy.updatedAt = Date.now();\n  store.savePolicy(policy);\n\n  const label = status === 'active' ? 'enabled (active)' : 'disabled';\n  return { text: `Policy **${policy.name}** is now ${label}.` };\n}\n\nfunction deletePol(userId: string, name: string) {\n  if (!name) return { text: 'Usage: `/policies delete <name>`' };\n\n  const store = getPolicyStore();\n  let policy = store.getPolicyByName(userId, name);\n  if (!policy) policy = store.getPolicy(userId, name);\n  if (!policy) return { text: `Policy \"${name}\" not found.` };\n\n  store.deletePolicy(userId, policy.id);\n  return { text: `Policy **${policy.name}** has been deleted.` };\n}\n"],"mappings":"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"}