ideaco 1.1.5

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 (159) hide show
  1. package/.dockerignore +33 -0
  2. package/.nvmrc +1 -0
  3. package/ARCHITECTURE.md +394 -0
  4. package/Dockerfile +50 -0
  5. package/LICENSE +29 -0
  6. package/README.md +206 -0
  7. package/bin/i18n.js +46 -0
  8. package/bin/ideaco.js +494 -0
  9. package/deploy.sh +15 -0
  10. package/docker-compose.yml +30 -0
  11. package/electron/main.cjs +986 -0
  12. package/electron/preload.cjs +14 -0
  13. package/electron/web-backends.cjs +854 -0
  14. package/jsconfig.json +8 -0
  15. package/next.config.mjs +34 -0
  16. package/package.json +134 -0
  17. package/postcss.config.mjs +6 -0
  18. package/public/demo/dashboard.png +0 -0
  19. package/public/demo/employee.png +0 -0
  20. package/public/demo/messages.png +0 -0
  21. package/public/demo/office.png +0 -0
  22. package/public/demo/requirement.png +0 -0
  23. package/public/logo.jpeg +0 -0
  24. package/public/logo.png +0 -0
  25. package/scripts/prepare-electron.js +67 -0
  26. package/scripts/release.js +76 -0
  27. package/src/app/api/agents/[agentId]/chat/route.js +70 -0
  28. package/src/app/api/agents/[agentId]/conversations/route.js +35 -0
  29. package/src/app/api/agents/[agentId]/route.js +106 -0
  30. package/src/app/api/avatar/route.js +104 -0
  31. package/src/app/api/browse-dir/route.js +44 -0
  32. package/src/app/api/chat/route.js +265 -0
  33. package/src/app/api/company/factory-reset/route.js +43 -0
  34. package/src/app/api/company/route.js +82 -0
  35. package/src/app/api/departments/[deptId]/agents/[agentId]/dismiss/route.js +19 -0
  36. package/src/app/api/departments/route.js +92 -0
  37. package/src/app/api/group-chat-loop/events/route.js +70 -0
  38. package/src/app/api/group-chat-loop/route.js +94 -0
  39. package/src/app/api/mailbox/route.js +100 -0
  40. package/src/app/api/messages/route.js +14 -0
  41. package/src/app/api/providers/[id]/configure/route.js +21 -0
  42. package/src/app/api/providers/[id]/refresh-cookie/route.js +38 -0
  43. package/src/app/api/providers/[id]/test-cookie/route.js +28 -0
  44. package/src/app/api/providers/route.js +11 -0
  45. package/src/app/api/requirements/route.js +242 -0
  46. package/src/app/api/secretary/route.js +65 -0
  47. package/src/app/api/system/cli-backends/route.js +91 -0
  48. package/src/app/api/system/cron/route.js +110 -0
  49. package/src/app/api/system/knowledge/route.js +104 -0
  50. package/src/app/api/system/plugins/route.js +40 -0
  51. package/src/app/api/system/skills/route.js +46 -0
  52. package/src/app/api/system/status/route.js +46 -0
  53. package/src/app/api/talent-market/[profileId]/recall/route.js +22 -0
  54. package/src/app/api/talent-market/[profileId]/route.js +17 -0
  55. package/src/app/api/talent-market/route.js +26 -0
  56. package/src/app/api/teams/route.js +773 -0
  57. package/src/app/api/ws-files/[departmentId]/file/route.js +27 -0
  58. package/src/app/api/ws-files/[departmentId]/files/route.js +22 -0
  59. package/src/app/globals.css +130 -0
  60. package/src/app/layout.jsx +40 -0
  61. package/src/app/page.jsx +97 -0
  62. package/src/components/AgentChatModal.jsx +164 -0
  63. package/src/components/AgentDetailModal.jsx +425 -0
  64. package/src/components/AgentSpyModal.jsx +481 -0
  65. package/src/components/AvatarGrid.jsx +29 -0
  66. package/src/components/BossProfileModal.jsx +162 -0
  67. package/src/components/CachedAvatar.jsx +77 -0
  68. package/src/components/ChatPanel.jsx +219 -0
  69. package/src/components/ChatShared.jsx +255 -0
  70. package/src/components/DepartmentDetail.jsx +842 -0
  71. package/src/components/DepartmentView.jsx +367 -0
  72. package/src/components/FileReference.jsx +260 -0
  73. package/src/components/FilesView.jsx +465 -0
  74. package/src/components/GroupChatView.jsx +799 -0
  75. package/src/components/Mailbox.jsx +926 -0
  76. package/src/components/MessagesView.jsx +112 -0
  77. package/src/components/OnboardingGuide.jsx +209 -0
  78. package/src/components/OrgTree.jsx +151 -0
  79. package/src/components/Overview.jsx +391 -0
  80. package/src/components/PixelOffice.jsx +2281 -0
  81. package/src/components/ProviderGrid.jsx +551 -0
  82. package/src/components/ProvidersBoard.jsx +16 -0
  83. package/src/components/RequirementDetail.jsx +1279 -0
  84. package/src/components/RequirementsBoard.jsx +187 -0
  85. package/src/components/SecretarySettings.jsx +295 -0
  86. package/src/components/SetupWizard.jsx +388 -0
  87. package/src/components/Sidebar.jsx +169 -0
  88. package/src/components/SystemMonitor.jsx +808 -0
  89. package/src/components/TalentMarket.jsx +183 -0
  90. package/src/components/TeamDetail.jsx +697 -0
  91. package/src/core/agent/base-agent.js +104 -0
  92. package/src/core/agent/chat-store.js +602 -0
  93. package/src/core/agent/cli-agent/backends/claude-code/README.md +52 -0
  94. package/src/core/agent/cli-agent/backends/claude-code/config.js +27 -0
  95. package/src/core/agent/cli-agent/backends/codebuddy/README.md +236 -0
  96. package/src/core/agent/cli-agent/backends/codebuddy/config.js +27 -0
  97. package/src/core/agent/cli-agent/backends/codex/README.md +51 -0
  98. package/src/core/agent/cli-agent/backends/codex/config.js +27 -0
  99. package/src/core/agent/cli-agent/backends/index.js +27 -0
  100. package/src/core/agent/cli-agent/backends/registry.js +580 -0
  101. package/src/core/agent/cli-agent/index.js +154 -0
  102. package/src/core/agent/index.js +60 -0
  103. package/src/core/agent/llm-agent/client.js +320 -0
  104. package/src/core/agent/llm-agent/index.js +97 -0
  105. package/src/core/agent/message-bus.js +211 -0
  106. package/src/core/agent/session.js +608 -0
  107. package/src/core/agent/tools.js +596 -0
  108. package/src/core/agent/web-agent/backends/base-backend.js +180 -0
  109. package/src/core/agent/web-agent/backends/chatgpt/client.js +146 -0
  110. package/src/core/agent/web-agent/backends/chatgpt/config.js +148 -0
  111. package/src/core/agent/web-agent/backends/chatgpt/dom-scripts.js +303 -0
  112. package/src/core/agent/web-agent/backends/index.js +91 -0
  113. package/src/core/agent/web-agent/index.js +278 -0
  114. package/src/core/agent/web-agent/web-client.js +407 -0
  115. package/src/core/employee/base-employee.js +1088 -0
  116. package/src/core/employee/index.js +35 -0
  117. package/src/core/employee/knowledge.js +327 -0
  118. package/src/core/employee/lifecycle.js +990 -0
  119. package/src/core/employee/memory/index.js +642 -0
  120. package/src/core/employee/memory/store.js +143 -0
  121. package/src/core/employee/performance.js +224 -0
  122. package/src/core/employee/secretary.js +625 -0
  123. package/src/core/employee/skills.js +398 -0
  124. package/src/core/index.js +38 -0
  125. package/src/core/organization/company.js +2600 -0
  126. package/src/core/organization/department.js +737 -0
  127. package/src/core/organization/group-chat-loop.js +264 -0
  128. package/src/core/organization/index.js +8 -0
  129. package/src/core/organization/persistence.js +111 -0
  130. package/src/core/organization/team.js +267 -0
  131. package/src/core/organization/workforce/hr.js +377 -0
  132. package/src/core/organization/workforce/providers.js +468 -0
  133. package/src/core/organization/workforce/role-archetypes.js +805 -0
  134. package/src/core/organization/workforce/talent-market.js +205 -0
  135. package/src/core/prompts.js +532 -0
  136. package/src/core/requirement.js +1789 -0
  137. package/src/core/system/audit.js +483 -0
  138. package/src/core/system/cron.js +449 -0
  139. package/src/core/system/index.js +7 -0
  140. package/src/core/system/plugin.js +2183 -0
  141. package/src/core/utils/json-parse.js +188 -0
  142. package/src/core/workspace.js +239 -0
  143. package/src/lib/api-i18n.js +211 -0
  144. package/src/lib/avatar.js +268 -0
  145. package/src/lib/client-store.js +1025 -0
  146. package/src/lib/config-validator.js +483 -0
  147. package/src/lib/format-time.js +22 -0
  148. package/src/lib/hooks.js +414 -0
  149. package/src/lib/i18n.js +134 -0
  150. package/src/lib/paths.js +23 -0
  151. package/src/lib/store.js +72 -0
  152. package/src/locales/de.js +393 -0
  153. package/src/locales/en.js +1054 -0
  154. package/src/locales/es.js +393 -0
  155. package/src/locales/fr.js +393 -0
  156. package/src/locales/ja.js +501 -0
  157. package/src/locales/ko.js +513 -0
  158. package/src/locales/zh.js +828 -0
  159. package/tailwind.config.mjs +11 -0
@@ -0,0 +1,183 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import { useStore } from '@/lib/client-store';
5
+ import { useI18n } from '@/lib/i18n';
6
+
7
+ export default function TalentMarket({ asModal = false, onClose = null }) {
8
+ const { t } = useI18n();
9
+ const { company, recallAgent, deleteTalent } = useStore();
10
+ const [recallTarget, setRecallTarget] = useState(null);
11
+ const [deleteTarget, setDeleteTarget] = useState(null);
12
+ const [targetDept, setTargetDept] = useState('');
13
+ const [deleting, setDeleting] = useState(false);
14
+
15
+ if (!company) return null;
16
+
17
+ const talents = company.talentMarket || [];
18
+ const departments = company.departments || [];
19
+
20
+ const handleRecall = async () => {
21
+ if (!recallTarget || !targetDept) return;
22
+ try {
23
+ await recallAgent(recallTarget.id, targetDept);
24
+ setRecallTarget(null);
25
+ setTargetDept('');
26
+ } catch (e) { /* handled */ }
27
+ };
28
+
29
+ const content = (
30
+ <div className={asModal ? 'space-y-4' : 'p-6 space-y-6 animate-fade-in'}>
31
+ {!asModal && (
32
+ <div>
33
+ <h1 className="text-2xl font-bold">{t('talent.title')}</h1>
34
+ <p className="text-sm text-[var(--muted)] mt-1">
35
+ {t('talent.subtitle')}
36
+ </p>
37
+ </div>
38
+ )}
39
+
40
+ {talents.length === 0 ? (
41
+ <div className="card text-center py-12 text-[var(--muted)]">
42
+ <div className="text-5xl mb-4">๐Ÿช</div>
43
+ <p className="text-lg">{t('talent.empty')}</p>
44
+ <p className="text-sm mt-1">{t('talent.emptyHint')}</p>
45
+ </div>
46
+ ) : (
47
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
48
+ {talents.map((talent) => (
49
+ <div key={talent.id} className="card relative">
50
+ {/* Top right action buttons */}
51
+ <div className="absolute top-2 right-2 flex items-center gap-1">
52
+ <button
53
+ className="text-xs bg-blue-900/20 text-blue-400 hover:bg-blue-900/40 px-2.5 py-1 rounded-lg transition-colors"
54
+ title={t('talent.recallBtn')}
55
+ onClick={() => setRecallTarget(talent)}
56
+ disabled={departments.length === 0}
57
+ >{t('talent.recallBtn')}</button>
58
+ <button
59
+ className="text-xs bg-red-900/20 text-red-400 hover:bg-red-900/40 px-2.5 py-1 rounded-lg transition-colors"
60
+ title={t('talent.deleteBtn')}
61
+ onClick={() => setDeleteTarget(talent)}
62
+ >
63
+ ๐Ÿ—‘
64
+ </button>
65
+ </div>
66
+
67
+ <div className="flex items-center justify-between mb-3 pr-16">
68
+ <div>
69
+ <h3 className="font-semibold">{talent.name}</h3>
70
+ <div className="text-xs text-[var(--muted)]">
71
+ {talent.gender === 'female' ? '๐Ÿ‘ฉ' : '๐Ÿ‘จ'}{talent.age ? ` ${t('display.ageYears', { n: talent.age })}` : ''} ยท {talent.role}
72
+ </div>
73
+ </div>
74
+ {talent.performanceScore && (
75
+ <span className={`text-sm font-bold ${
76
+ talent.performanceScore >= 80 ? 'text-green-400' :
77
+ talent.performanceScore >= 60 ? 'text-yellow-400' : 'text-red-400'
78
+ }`}>
79
+ {t('talent.score', { score: talent.performanceScore })}
80
+ </span>
81
+ )}
82
+ </div>
83
+
84
+ <div className="flex flex-wrap gap-1.5 mb-3">
85
+ {talent.skills.map((s, i) => (
86
+ <span key={i} className="text-[10px] bg-white/5 text-[var(--muted)] px-1.5 py-0.5 rounded">{s}</span>
87
+ ))}
88
+ </div>
89
+
90
+ <div className="text-xs text-[var(--muted)] space-y-1">
91
+ <div>{t('talent.dismissReason', { reason: talent.dismissalReason })}</div>
92
+ <div>{t('talent.memoryCount', { n: talent.memoryCount })}</div>
93
+ {talent.registeredAt && (
94
+ <div>{t('talent.registeredAt', { date: new Date(talent.registeredAt).toLocaleDateString() })}</div>
95
+ )}
96
+ </div>
97
+ </div>
98
+ ))}
99
+ </div>
100
+ )}
101
+
102
+ {/* Recall modal */}
103
+ {recallTarget && (
104
+ <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50 !m-0" onClick={() => setRecallTarget(null)}>
105
+ <div className="card max-w-sm w-full mx-4 space-y-4" onClick={e => e.stopPropagation()}>
106
+ <h3 className="text-lg font-semibold">{t('talent.recall.title', { name: recallTarget.name })}</h3>
107
+ <p className="text-sm text-[var(--muted)]">
108
+ {t('talent.recall.desc', { name: recallTarget.name })}
109
+ </p>
110
+ <div>
111
+ <label className="block text-sm mb-1 text-[var(--muted)]">{t('talent.recall.deptLabel')}</label>
112
+ <select
113
+ className="input w-full"
114
+ value={targetDept}
115
+ onChange={e => setTargetDept(e.target.value)}
116
+ >
117
+ <option value="">{t('talent.recall.deptPlaceholder')}</option>
118
+ {departments.map(d => (
119
+ <option key={d.id} value={d.id}>{d.name}</option>
120
+ ))}
121
+ </select>
122
+ </div>
123
+ <div className="flex gap-2">
124
+ <button className="btn-secondary flex-1" onClick={() => setRecallTarget(null)}>{t('common.cancel')}</button>
125
+ <button className="btn-primary flex-1" disabled={!targetDept} onClick={handleRecall}>{t('talent.recall.confirmBtn')}</button>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ )}
130
+ {/* Delete confirm modal */}
131
+ {deleteTarget && (
132
+ <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50 !m-0" onClick={() => setDeleteTarget(null)}>
133
+ <div className="card max-w-sm w-full mx-4 space-y-4" onClick={e => e.stopPropagation()}>
134
+ <h3 className="text-lg font-semibold text-red-400">{t('talent.deleteConfirm.title', { name: deleteTarget.name })}</h3>
135
+ <p className="text-sm text-[var(--muted)]">
136
+ {t('talent.deleteConfirm.desc', { name: deleteTarget.name })}
137
+ </p>
138
+ <div className="flex gap-2">
139
+ <button className="btn-secondary flex-1" onClick={() => setDeleteTarget(null)}>{t('common.cancel')}</button>
140
+ <button
141
+ className="flex-1 px-3 py-2 rounded-lg text-sm font-medium bg-red-500/20 text-red-400 hover:bg-red-500/30 transition-colors disabled:opacity-50"
142
+ disabled={deleting}
143
+ onClick={async () => {
144
+ setDeleting(true);
145
+ try {
146
+ await deleteTalent(deleteTarget.id);
147
+ setDeleteTarget(null);
148
+ } catch (e) { /* handled */ }
149
+ setDeleting(false);
150
+ }}
151
+ >
152
+ {deleting ? t('talent.deleteConfirm.deleting') : t('talent.deleteConfirm.confirmBtn')}
153
+ </button>
154
+ </div>
155
+ </div>
156
+ </div>
157
+ )}
158
+ </div>
159
+ );
160
+
161
+ if (asModal) {
162
+ return (
163
+ <div className="fixed inset-0 bg-black/60 flex items-center justify-center z-50 !m-0" onClick={onClose}>
164
+ <div className="bg-[var(--card)] border border-[var(--border)] rounded-xl max-w-3xl w-full mx-4 max-h-[80vh] overflow-hidden flex flex-col" onClick={e => e.stopPropagation()}>
165
+ {/* Modal header */}
166
+ <div className="flex items-center justify-between p-4 border-b border-[var(--border)]">
167
+ <div>
168
+ <h2 className="text-lg font-bold">{t('talent.title')}</h2>
169
+ <p className="text-xs text-[var(--muted)]">{t('talent.subtitle')}</p>
170
+ </div>
171
+ <button onClick={onClose} className="text-[var(--muted)] hover:text-white text-xl px-2">โœ•</button>
172
+ </div>
173
+ {/* Modal body */}
174
+ <div className="overflow-auto p-4">
175
+ {content}
176
+ </div>
177
+ </div>
178
+ </div>
179
+ );
180
+ }
181
+
182
+ return content;
183
+ }