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,91 @@
1
+ /**
2
+ * CLI Backends API - Manage CLI backends (detect, register, configure)
3
+ */
4
+ import { NextResponse } from 'next/server';
5
+ import { cliBackendRegistry } from '@/core/agent/cli-agent/backends/index.js';
6
+ import { getCompany } from '@/lib/store';
7
+ import { getApiT } from '@/lib/api-i18n';
8
+
9
+ /**
10
+ * GET /api/system/cli-backends
11
+ * Get all CLI backend statuses
12
+ */
13
+ export async function GET() {
14
+ try {
15
+ const backends = cliBackendRegistry.listAll();
16
+ return NextResponse.json({ data: backends });
17
+ } catch (error) {
18
+ return NextResponse.json({ error: error.message }, { status: 500 });
19
+ }
20
+ }
21
+
22
+ /**
23
+ * POST /api/system/cli-backends
24
+ * CLI backend management operations
25
+ *
26
+ * Actions:
27
+ * - detect: detect all CLIs
28
+ * - detectOne: detect a single CLI
29
+ * - register: register a custom CLI
30
+ * - unregister: remove a custom CLI
31
+ */
32
+ export async function POST(request) {
33
+ const t = getApiT(request);
34
+ try {
35
+ const body = await request.json();
36
+ const { action } = body;
37
+
38
+ switch (action) {
39
+ case 'detect': {
40
+ const results = await cliBackendRegistry.detectAll();
41
+ // Sync detected CLI backends into provider registry
42
+ const company = getCompany();
43
+ if (company) {
44
+ company.providerRegistry.syncCLIBackends(cliBackendRegistry);
45
+ }
46
+ return NextResponse.json({ data: results });
47
+ }
48
+
49
+ case 'detectOne': {
50
+ const { backendId } = body;
51
+ if (!backendId) {
52
+ return NextResponse.json({ error: t('api.missingBackendId') }, { status: 400 });
53
+ }
54
+ const result = await cliBackendRegistry.detect(backendId);
55
+ return NextResponse.json({ data: { id: backendId, ...result } });
56
+ }
57
+
58
+ case 'register': {
59
+ const { config } = body;
60
+ if (!config || !config.id || !config.execCommand) {
61
+ return NextResponse.json({ error: t('api.cliConfigRequired') }, { status: 400 });
62
+ }
63
+ const registered = cliBackendRegistry.register(config);
64
+ // Detect immediately after registration
65
+ await cliBackendRegistry.detect(registered.id);
66
+ // Sync to provider registry
67
+ const company2 = getCompany();
68
+ if (company2) {
69
+ company2.providerRegistry.syncCLIBackends(cliBackendRegistry);
70
+ }
71
+ const backends = cliBackendRegistry.listAll();
72
+ return NextResponse.json({ data: backends });
73
+ }
74
+
75
+ case 'unregister': {
76
+ const { backendId } = body;
77
+ if (!backendId) {
78
+ return NextResponse.json({ error: t('api.missingBackendId') }, { status: 400 });
79
+ }
80
+ cliBackendRegistry.unregister(backendId);
81
+ const backends = cliBackendRegistry.listAll();
82
+ return NextResponse.json({ data: backends });
83
+ }
84
+
85
+ default:
86
+ return NextResponse.json({ error: t('api.pluginUnknownAction', { action }) }, { status: 400 });
87
+ }
88
+ } catch (error) {
89
+ return NextResponse.json({ error: error.message }, { status: 500 });
90
+ }
91
+ }
@@ -0,0 +1,110 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getCompany } from '@/lib/store';
3
+ import { cronScheduler } from '@/core/system/cron.js';
4
+ import { getApiT } from '@/lib/api-i18n';
5
+
6
+ /**
7
+ * GET /api/system/cron - List all cron jobs
8
+ */
9
+ export async function GET() {
10
+ try {
11
+ return NextResponse.json({
12
+ data: {
13
+ summary: cronScheduler.getSummary(),
14
+ jobs: cronScheduler.listJobs(),
15
+ },
16
+ });
17
+ } catch (error) {
18
+ return NextResponse.json({ error: error.message }, { status: 500 });
19
+ }
20
+ }
21
+
22
+ /**
23
+ * POST /api/system/cron - Manage cron jobs
24
+ *
25
+ * Actions:
26
+ * - create: { name, cronExpression, agentId, taskPrompt, description? }
27
+ * - pause: { jobId }
28
+ * - resume: { jobId }
29
+ * - trigger: { jobId }
30
+ * - delete: { jobId }
31
+ */
32
+ export async function POST(request) {
33
+ const t = getApiT(request);
34
+ const company = getCompany();
35
+ if (!company) {
36
+ return NextResponse.json({ error: t('api.noCompany') }, { status: 400 });
37
+ }
38
+
39
+ try {
40
+ const body = await request.json();
41
+ const { action = 'create' } = body;
42
+
43
+ switch (action) {
44
+ case 'create': {
45
+ const { name, cronExpression, agentId, taskPrompt, description } = body;
46
+ if (!name || !cronExpression || !agentId || !taskPrompt) {
47
+ return NextResponse.json(
48
+ { error: t('api.cronMissingFields') },
49
+ { status: 400 }
50
+ );
51
+ }
52
+
53
+ // Verify agent exists
54
+ let agentFound = false;
55
+ for (const dept of company.departments.values()) {
56
+ if (dept.agents.has(agentId)) {
57
+ agentFound = true;
58
+ break;
59
+ }
60
+ }
61
+ if (!agentFound) {
62
+ return NextResponse.json({ error: t('api.agentNotFoundId', { id: agentId }) }, { status: 404 });
63
+ }
64
+
65
+ const job = cronScheduler.addJob({
66
+ name,
67
+ cronExpression,
68
+ agentId,
69
+ taskPrompt,
70
+ description: description || '',
71
+ });
72
+
73
+ return NextResponse.json({
74
+ data: {
75
+ id: job.id,
76
+ name: job.name,
77
+ cronExpression: job.cronExpression,
78
+ nextRun: job.nextRun?.toISOString(),
79
+ status: job.status,
80
+ },
81
+ });
82
+ }
83
+
84
+ case 'pause': {
85
+ cronScheduler.pauseJob(body.jobId);
86
+ return NextResponse.json({ data: { success: true } });
87
+ }
88
+
89
+ case 'resume': {
90
+ cronScheduler.resumeJob(body.jobId);
91
+ return NextResponse.json({ data: { success: true } });
92
+ }
93
+
94
+ case 'trigger': {
95
+ await cronScheduler.triggerJob(body.jobId);
96
+ return NextResponse.json({ data: { success: true } });
97
+ }
98
+
99
+ case 'delete': {
100
+ cronScheduler.removeJob(body.jobId);
101
+ return NextResponse.json({ data: { success: true } });
102
+ }
103
+
104
+ default:
105
+ return NextResponse.json({ error: t('api.pluginUnknownAction', { action }) }, { status: 400 });
106
+ }
107
+ } catch (error) {
108
+ return NextResponse.json({ error: error.message }, { status: 500 });
109
+ }
110
+ }
@@ -0,0 +1,104 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { knowledgeManager, KnowledgeType, EntryType } from '@/core/employee/knowledge.js';
3
+ import { getApiT } from '@/lib/api-i18n';
4
+
5
+ /**
6
+ * GET /api/system/knowledge - Get knowledge base list or search
7
+ */
8
+ export async function GET(request) {
9
+ const t = getApiT(request);
10
+ try {
11
+ const { searchParams } = new URL(request.url);
12
+ const query = searchParams.get('query');
13
+ const kbId = searchParams.get('kbId');
14
+
15
+ // Search
16
+ if (query) {
17
+ const results = knowledgeManager.search(query, { limit: 20 });
18
+ return NextResponse.json({ data: results });
19
+ }
20
+
21
+ // Get entries for a specific knowledge base
22
+ if (kbId) {
23
+ const kb = knowledgeManager.get(kbId);
24
+ if (!kb) return NextResponse.json({ error: t('api.kbNotFound') }, { status: 404 });
25
+ return NextResponse.json({
26
+ data: {
27
+ id: kb.id,
28
+ name: kb.name,
29
+ description: kb.description,
30
+ type: kb.type,
31
+ enabled: kb.enabled,
32
+ entries: kb.listEntries(),
33
+ stats: kb.getStats(),
34
+ },
35
+ });
36
+ }
37
+
38
+ // List all knowledge bases
39
+ return NextResponse.json({
40
+ data: {
41
+ bases: knowledgeManager.list(),
42
+ stats: knowledgeManager.getOverallStats(),
43
+ types: KnowledgeType,
44
+ entryTypes: EntryType,
45
+ },
46
+ });
47
+ } catch (error) {
48
+ return NextResponse.json({ error: error.message }, { status: 500 });
49
+ }
50
+ }
51
+
52
+ /**
53
+ * POST /api/system/knowledge - Knowledge base management operations
54
+ * Actions: create, addEntry, removeEntry, delete, toggle
55
+ */
56
+ export async function POST(request) {
57
+ const t = getApiT(request);
58
+ try {
59
+ const body = await request.json();
60
+ const { action } = body;
61
+
62
+ switch (action) {
63
+ case 'create': {
64
+ const kb = knowledgeManager.create({
65
+ name: body.name,
66
+ description: body.description,
67
+ type: body.type || KnowledgeType.GLOBAL,
68
+ ownerId: body.ownerId || null,
69
+ });
70
+ return NextResponse.json({ data: { id: kb.id, success: true } });
71
+ }
72
+ case 'addEntry': {
73
+ const entry = knowledgeManager.addEntry(body.kbId, {
74
+ title: body.title,
75
+ content: body.content,
76
+ type: body.entryType || EntryType.NOTE,
77
+ tags: body.tags || [],
78
+ importance: body.importance || 0.5,
79
+ source: body.source || null,
80
+ createdBy: body.createdBy || null,
81
+ });
82
+ return NextResponse.json({ data: { id: entry.id, success: true } });
83
+ }
84
+ case 'removeEntry': {
85
+ const result = knowledgeManager.removeEntry(body.kbId, body.entryId);
86
+ return NextResponse.json({ data: { success: result } });
87
+ }
88
+ case 'delete': {
89
+ const result = knowledgeManager.delete(body.kbId);
90
+ return NextResponse.json({ data: { success: result } });
91
+ }
92
+ case 'toggle': {
93
+ const kb = knowledgeManager.get(body.kbId);
94
+ if (!kb) return NextResponse.json({ error: t('api.kbNotFound') }, { status: 404 });
95
+ kb.enabled = !kb.enabled;
96
+ return NextResponse.json({ data: { success: true, enabled: kb.enabled } });
97
+ }
98
+ default:
99
+ return NextResponse.json({ error: t('api.kbUnknownAction', { action }) }, { status: 400 });
100
+ }
101
+ } catch (error) {
102
+ return NextResponse.json({ error: error.message }, { status: 500 });
103
+ }
104
+ }
@@ -0,0 +1,40 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { pluginRegistry } from '@/core/system/plugin.js';
3
+ import { getApiT } from '@/lib/api-i18n';
4
+
5
+ /**
6
+ * GET /api/system/plugins - List all plugins
7
+ */
8
+ export async function GET() {
9
+ try {
10
+ return NextResponse.json({ data: pluginRegistry.list() });
11
+ } catch (error) {
12
+ return NextResponse.json({ error: error.message }, { status: 500 });
13
+ }
14
+ }
15
+
16
+ /**
17
+ * POST /api/system/plugins - Manage plugins
18
+ * Actions: enable, disable
19
+ */
20
+ export async function POST(request) {
21
+ const t = getApiT(request);
22
+ try {
23
+ const { action, pluginId } = await request.json();
24
+ if (!pluginId) {
25
+ return NextResponse.json({ error: t('api.missingPluginId') }, { status: 400 });
26
+ }
27
+ switch (action) {
28
+ case 'enable':
29
+ pluginRegistry.enable(pluginId);
30
+ return NextResponse.json({ data: { success: true } });
31
+ case 'disable':
32
+ pluginRegistry.disable(pluginId);
33
+ return NextResponse.json({ data: { success: true } });
34
+ default:
35
+ return NextResponse.json({ error: t('api.pluginUnknownAction', { action }) }, { status: 400 });
36
+ }
37
+ } catch (error) {
38
+ return NextResponse.json({ error: error.message }, { status: 500 });
39
+ }
40
+ }
@@ -0,0 +1,46 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { skillRegistry } from '@/core/employee/skills.js';
3
+ import { getApiT } from '@/lib/api-i18n';
4
+
5
+ /**
6
+ * GET /api/system/skills - Get all skills
7
+ */
8
+ export async function GET() {
9
+ try {
10
+ return NextResponse.json({ data: skillRegistry.list() });
11
+ } catch (error) {
12
+ return NextResponse.json({ error: error.message }, { status: 500 });
13
+ }
14
+ }
15
+
16
+ /**
17
+ * POST /api/system/skills - Manage skills
18
+ * Actions: enable, disable, configure
19
+ */
20
+ export async function POST(request) {
21
+ const t = getApiT(request);
22
+ try {
23
+ const { action, skillId, config } = await request.json();
24
+ if (!skillId) {
25
+ return NextResponse.json({ error: t('api.missingSkillId') }, { status: 400 });
26
+ }
27
+ switch (action) {
28
+ case 'enable':
29
+ skillRegistry.enable(skillId);
30
+ return NextResponse.json({ data: { success: true } });
31
+ case 'disable':
32
+ skillRegistry.disable(skillId);
33
+ return NextResponse.json({ data: { success: true } });
34
+ case 'install':
35
+ skillRegistry.install(skillId, config || {});
36
+ return NextResponse.json({ data: { success: true } });
37
+ case 'configure':
38
+ skillRegistry.configure(skillId, config || {});
39
+ return NextResponse.json({ data: { success: true } });
40
+ default:
41
+ return NextResponse.json({ error: t('api.pluginUnknownAction', { action }) }, { status: 400 });
42
+ }
43
+ } catch (error) {
44
+ return NextResponse.json({ error: error.message }, { status: 500 });
45
+ }
46
+ }
@@ -0,0 +1,46 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { auditLogger, securityGuard } from '@/core/system/audit.js';
3
+ import { pluginRegistry } from '@/core/system/plugin.js';
4
+ import { cronScheduler } from '@/core/system/cron.js';
5
+ import { hookRegistry } from '@/lib/hooks.js';
6
+ import { sessionManager } from '@/core/agent/session.js';
7
+ import { configValidator } from '@/lib/config-validator.js';
8
+
9
+ /**
10
+ * GET /api/system/status - System status dashboard
11
+ * Returns health of all distilled systems: audit, routing, plugins, cron, hooks, sessions, config
12
+ */
13
+ export async function GET() {
14
+ try {
15
+ const status = {
16
+ // Audit system summary
17
+ audit: auditLogger.getSummary(),
18
+
19
+ // Plugin system status
20
+ plugins: pluginRegistry.list(),
21
+
22
+ // Cron scheduler status
23
+ cron: cronScheduler.getSummary(),
24
+ cronJobs: cronScheduler.listJobs(),
25
+
26
+ // Hook system status
27
+ hooks: hookRegistry.getSummary(),
28
+
29
+ // Session manager status
30
+ sessions: sessionManager.getSummary(),
31
+
32
+ // Config validator (validate current empty config as health check)
33
+ configHealth: {
34
+ schemaFields: Object.keys(configValidator.schema.properties || {}),
35
+ },
36
+
37
+ // Recent security events
38
+ recentAuditEvents: auditLogger.query({ limit: 20 }),
39
+ blockedActions: auditLogger.query({ blocked: true, limit: 10 }),
40
+ };
41
+
42
+ return NextResponse.json({ data: status });
43
+ } catch (error) {
44
+ return NextResponse.json({ error: error.message }, { status: 500 });
45
+ }
46
+ }
@@ -0,0 +1,22 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getCompany } from '@/lib/store';
3
+ import { getApiT } from '@/lib/api-i18n';
4
+
5
+ export async function POST(request, { params }) {
6
+ const t = getApiT(request);
7
+ const company = getCompany();
8
+ if (!company) return NextResponse.json({ error: t('api.noCompany') }, { status: 400 });
9
+
10
+ try {
11
+ const { profileId } = await params;
12
+ const { departmentId, newSkills } = await request.json();
13
+ if (!departmentId) {
14
+ return NextResponse.json({ error: t('api.targetDeptRequired') }, { status: 400 });
15
+ }
16
+ company.recallAgent(departmentId, profileId, newSkills || []);
17
+ company._log('Recall talent', `Recalled employee from talent market`);
18
+ return NextResponse.json({ success: true, data: company.getFullState() });
19
+ } catch (e) {
20
+ return NextResponse.json({ error: e.message }, { status: 400 });
21
+ }
22
+ }
@@ -0,0 +1,17 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getCompany } from '@/lib/store';
3
+ import { getApiT } from '@/lib/api-i18n';
4
+
5
+ export async function DELETE(request, { params }) {
6
+ const t = getApiT(request);
7
+ const company = getCompany();
8
+ if (!company) return NextResponse.json({ error: t('api.noCompany') }, { status: 400 });
9
+
10
+ try {
11
+ const { profileId } = await params;
12
+ company.deleteTalent(profileId);
13
+ return NextResponse.json({ success: true, data: company.getFullState() });
14
+ } catch (e) {
15
+ return NextResponse.json({ error: e.message }, { status: 400 });
16
+ }
17
+ }
@@ -0,0 +1,26 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getCompany } from '@/lib/store';
3
+ import { getApiT } from '@/lib/api-i18n';
4
+
5
+ export async function GET(request) {
6
+ const t = getApiT(request);
7
+ const company = getCompany();
8
+ if (!company) return NextResponse.json({ error: t('api.noCompany') }, { status: 400 });
9
+
10
+ const market = company.talentMarket.listAvailable().map(p => ({
11
+ id: p.id,
12
+ name: p.name,
13
+ role: p.role,
14
+ skills: [...p.skills, ...p.acquiredSkills],
15
+ acquiredSkills: p.acquiredSkills,
16
+ dismissalReason: p.dismissalReason,
17
+ performanceScore: p.performanceData?.averageScore,
18
+ registeredAt: p.registeredAt,
19
+ workHistory: p.workHistory,
20
+ memoryCount: p.memorySnapshot
21
+ ? (p.memorySnapshot.shortTerm?.length || 0) + (p.memorySnapshot.longTerm?.length || 0)
22
+ : 0,
23
+ }));
24
+
25
+ return NextResponse.json({ data: market });
26
+ }