agent-session-guide.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. const fs = require('fs');
  2. const path = require('path');
  3. const { latestPath } = require('./output-paths');
  4. const { buildClaudeSessionName } = require('./agent-runtime');
  5. const PACKAGE_ROOT = path.resolve(__dirname, '..', '..', '..');
  6. function sessionCommandPrefix() {
  7. const pluginsDir = path.dirname(PACKAGE_ROOT);
  8. const claudeDir = path.dirname(pluginsDir);
  9. if (path.basename(pluginsDir) === 'plugins' && path.basename(claudeDir) === '.claude') {
  10. return `npm --prefix ".claude/plugins/${path.basename(PACKAGE_ROOT)}" run`;
  11. }
  12. return 'npm run';
  13. }
  14. function safeCustomerArgument(value) {
  15. return String(value || '企微客户')
  16. .replace(/[^\p{L}\p{N} _.-]/gu, '')
  17. .trim()
  18. .slice(0, 60) || '企微客户';
  19. }
  20. function readSessionState(filePath = latestPath('messages', 'claude-code-sessions.json')) {
  21. try {
  22. const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
  23. parsed.sessions ||= {};
  24. parsed.project ||= {};
  25. return parsed;
  26. } catch {
  27. return { version: 1, project: {}, sessions: {} };
  28. }
  29. }
  30. function getCustomerSessionGuide(conversation = {}, options = {}) {
  31. const conversationId = String(conversation.id || conversation.conversationId || '');
  32. const customerName = String(conversation.contact_name || conversation.displayName || '企微客户').trim();
  33. const state = options.state || readSessionState(options.sessionFile);
  34. const session = state.sessions?.[conversationId] || null;
  35. const displayName = session?.displayName || buildClaudeSessionName({
  36. conversation: { contact_name: customerName },
  37. }, conversationId || customerName);
  38. const safeName = safeCustomerArgument(customerName);
  39. return {
  40. detected: Boolean(session),
  41. ready: Boolean(session?.initialized),
  42. status: !session ? 'not_created' : session.initialized ? 'ready' : 'waiting_first_run',
  43. customerName,
  44. displayName,
  45. openLocation: 'Fmode Studio → 当前企微项目 → 终端',
  46. openCommand: `${sessionCommandPrefix()} agent:session -- --customer "${safeName}"`,
  47. openMode: 'forked-review',
  48. productionSessionProtected: true,
  49. guidance: session?.initialized
  50. ? '已检测到客户专属 Claude Code Session。运行打开命令后会 fork 审阅副本,可查看完整历史、模型思考和工具记录。'
  51. : session
  52. ? '客户专属 Session 已分配,首次生成草稿后即可打开完整 Claude Code 对话。'
  53. : '该客户尚未创建 Claude Code Session;首次运行 Agent 后系统会自动创建并显示打开方式。',
  54. updatedAt: session?.updatedAt || session?.createdAt || null,
  55. };
  56. }
  57. module.exports = {
  58. safeCustomerArgument,
  59. sessionCommandPrefix,
  60. readSessionState,
  61. getCustomerSessionGuide,
  62. };