@agent-link/server 0.1.157 → 0.1.159
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.
- package/package.json +1 -1
- package/web/app.js +655 -59
- package/web/landing.html +76 -20
- package/web/landing.zh.html +76 -20
- package/web/modules/backgroundRouting.js +2 -1
- package/web/modules/connection.js +22 -1
- package/web/modules/loop.js +337 -0
- package/web/modules/loopTemplates.js +110 -0
- package/web/modules/team.js +8 -8
- package/web/style.css +682 -13
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// ── Loop template definitions ─────────────────────────────────────────────────
|
|
2
|
+
// Predefined sample cases for the Loop creation panel ("Try it" cards).
|
|
3
|
+
// Each template pre-fills name, prompt, scheduleType, and scheduleConfig.
|
|
4
|
+
|
|
5
|
+
export const LOOP_TEMPLATES = {
|
|
6
|
+
'competitive-intel': {
|
|
7
|
+
label: 'Competitive Intel Monitor',
|
|
8
|
+
description: 'Track competitor products, pricing, and industry trends',
|
|
9
|
+
name: 'Competitive Intelligence Monitor',
|
|
10
|
+
prompt: `Monitor competitor and industry developments. Scan the working directory for any tracked competitor data, news feeds, or intelligence files.
|
|
11
|
+
|
|
12
|
+
1. Identify new product launches, feature updates, or pricing changes from competitors
|
|
13
|
+
2. Summarize key industry trends, regulatory changes, or market shifts
|
|
14
|
+
3. Highlight strategic threats (competitors gaining ground) and opportunities (gaps in market)
|
|
15
|
+
4. Compare against our current positioning where relevant
|
|
16
|
+
|
|
17
|
+
Provide a structured briefing with sections: Key Developments, Threats, Opportunities, Recommended Actions.`,
|
|
18
|
+
scheduleType: 'daily',
|
|
19
|
+
scheduleConfig: { hour: 8, minute: 0 },
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
'knowledge-base': {
|
|
23
|
+
label: 'Knowledge Base Maintenance',
|
|
24
|
+
description: 'Audit notes and docs for broken links, orphan files, and organization',
|
|
25
|
+
name: 'Knowledge Base Maintenance',
|
|
26
|
+
prompt: `Perform a maintenance audit on the knowledge base / notes in this directory.
|
|
27
|
+
|
|
28
|
+
1. Find broken internal links (references to files or headings that no longer exist)
|
|
29
|
+
2. Identify orphan files (documents with no inbound links from any other document)
|
|
30
|
+
3. Detect duplicate or near-duplicate content across files
|
|
31
|
+
4. Check for outdated information (files not modified in 90+ days that reference time-sensitive topics)
|
|
32
|
+
5. Suggest tag/folder reorganization for better discoverability
|
|
33
|
+
|
|
34
|
+
Provide a structured report with sections: Broken Links, Orphan Files, Duplicates, Stale Content, Reorganization Suggestions.`,
|
|
35
|
+
scheduleType: 'weekly',
|
|
36
|
+
scheduleConfig: { hour: 20, minute: 0, dayOfWeek: 5 }, // Friday 20:00
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
'daily-summary': {
|
|
40
|
+
label: '日报/周报生成',
|
|
41
|
+
description: '根据 git log 自动总结代码变更和工作进展',
|
|
42
|
+
name: '每日工作总结',
|
|
43
|
+
prompt: `根据当前工作目录的 git log 生成今日工作总结。
|
|
44
|
+
|
|
45
|
+
1. 列出今天所有 commit,按功能模块分组
|
|
46
|
+
2. 总结主要完成的功能、修复的 bug、重构的代码
|
|
47
|
+
3. 统计变更的文件数量和代码行数(新增/删除)
|
|
48
|
+
4. 标注仍在进行中的工作(未完成的分支、TODO 等)
|
|
49
|
+
5. 列出明日待办事项建议
|
|
50
|
+
|
|
51
|
+
输出格式:结构化的日报,包含:今日完成、进行中、明日计划。`,
|
|
52
|
+
scheduleType: 'daily',
|
|
53
|
+
scheduleConfig: { hour: 18, minute: 0 },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const LOOP_TEMPLATE_KEYS = ['competitive-intel', 'knowledge-base', 'daily-summary'];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Convert scheduleType + scheduleConfig into a cron expression string.
|
|
61
|
+
* @param {string} scheduleType - 'hourly' | 'daily' | 'weekly' | 'cron'
|
|
62
|
+
* @param {object} scheduleConfig - { hour?, minute?, dayOfWeek?, cronExpression? }
|
|
63
|
+
* @returns {string} cron expression
|
|
64
|
+
*/
|
|
65
|
+
export function buildCronExpression(scheduleType, scheduleConfig) {
|
|
66
|
+
const min = scheduleConfig.minute ?? 0;
|
|
67
|
+
const hr = scheduleConfig.hour ?? 9;
|
|
68
|
+
switch (scheduleType) {
|
|
69
|
+
case 'manual':
|
|
70
|
+
return '';
|
|
71
|
+
case 'hourly':
|
|
72
|
+
return `${min} * * * *`;
|
|
73
|
+
case 'daily':
|
|
74
|
+
return `${min} ${hr} * * *`;
|
|
75
|
+
case 'weekly':
|
|
76
|
+
return `${min} ${hr} * * ${scheduleConfig.dayOfWeek ?? 1}`;
|
|
77
|
+
case 'cron':
|
|
78
|
+
return scheduleConfig.cronExpression || `${min} ${hr} * * *`;
|
|
79
|
+
default:
|
|
80
|
+
return `${min} ${hr} * * *`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Format a cron expression into a human-readable description.
|
|
86
|
+
* @param {string} scheduleType - 'hourly' | 'daily' | 'weekly' | 'cron'
|
|
87
|
+
* @param {object} scheduleConfig - { hour?, minute?, dayOfWeek? }
|
|
88
|
+
* @param {string} cronExpr - raw cron expression (for 'cron' type)
|
|
89
|
+
* @returns {string}
|
|
90
|
+
*/
|
|
91
|
+
export function formatSchedule(scheduleType, scheduleConfig, cronExpr) {
|
|
92
|
+
const pad = n => String(n).padStart(2, '0');
|
|
93
|
+
const DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
94
|
+
switch (scheduleType) {
|
|
95
|
+
case 'manual':
|
|
96
|
+
return 'Manual only';
|
|
97
|
+
case 'hourly':
|
|
98
|
+
return 'Every hour';
|
|
99
|
+
case 'daily':
|
|
100
|
+
return `Every day at ${pad(scheduleConfig.hour ?? 9)}:${pad(scheduleConfig.minute ?? 0)}`;
|
|
101
|
+
case 'weekly': {
|
|
102
|
+
const day = DAYS[scheduleConfig.dayOfWeek ?? 1] || 'Monday';
|
|
103
|
+
return `Every ${day} at ${pad(scheduleConfig.hour ?? 9)}:${pad(scheduleConfig.minute ?? 0)}`;
|
|
104
|
+
}
|
|
105
|
+
case 'cron':
|
|
106
|
+
return cronExpr || 'Custom cron';
|
|
107
|
+
default:
|
|
108
|
+
return cronExpr || 'Unknown schedule';
|
|
109
|
+
}
|
|
110
|
+
}
|
package/web/modules/team.js
CHANGED
|
@@ -23,8 +23,8 @@ export function createTeam(deps) {
|
|
|
23
23
|
/** @type {import('vue').Ref<object|null>} Current team state (TeamStateSerialized or null) */
|
|
24
24
|
const teamState = ref(null);
|
|
25
25
|
|
|
26
|
-
/** @type {import('vue').Ref<string>} 'chat' | 'team' — current
|
|
27
|
-
const
|
|
26
|
+
/** @type {import('vue').Ref<string>} 'chat' | 'team' | 'loop' — current view mode */
|
|
27
|
+
const viewMode = ref('chat');
|
|
28
28
|
|
|
29
29
|
/** @type {import('vue').Ref<string|null>} Currently viewed agent ID, null = dashboard */
|
|
30
30
|
const activeAgentView = ref(null);
|
|
@@ -135,13 +135,13 @@ export function createTeam(deps) {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
function backToChat() {
|
|
138
|
-
|
|
138
|
+
viewMode.value = 'chat';
|
|
139
139
|
historicalTeam.value = null;
|
|
140
140
|
activeAgentView.value = null;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
function newTeam() {
|
|
144
|
-
|
|
144
|
+
viewMode.value = 'team';
|
|
145
145
|
historicalTeam.value = null;
|
|
146
146
|
activeAgentView.value = null;
|
|
147
147
|
// If completed team is still in teamState, clear it so create panel shows
|
|
@@ -161,7 +161,7 @@ export function createTeam(deps) {
|
|
|
161
161
|
switch (msg.type) {
|
|
162
162
|
case 'team_created':
|
|
163
163
|
teamState.value = msg.team;
|
|
164
|
-
|
|
164
|
+
viewMode.value = 'team';
|
|
165
165
|
historicalTeam.value = null;
|
|
166
166
|
activeAgentView.value = null;
|
|
167
167
|
agentMessages.value = {};
|
|
@@ -266,7 +266,7 @@ export function createTeam(deps) {
|
|
|
266
266
|
|
|
267
267
|
case 'team_detail':
|
|
268
268
|
historicalTeam.value = msg.team;
|
|
269
|
-
|
|
269
|
+
viewMode.value = 'team';
|
|
270
270
|
activeAgentView.value = null;
|
|
271
271
|
return true;
|
|
272
272
|
|
|
@@ -355,7 +355,7 @@ export function createTeam(deps) {
|
|
|
355
355
|
function handleActiveTeamRestore(activeTeam) {
|
|
356
356
|
if (!activeTeam) return;
|
|
357
357
|
teamState.value = activeTeam;
|
|
358
|
-
|
|
358
|
+
viewMode.value = 'team';
|
|
359
359
|
// Re-initialize agent message lists (messages lost on reconnect)
|
|
360
360
|
if (!agentMessages.value['lead']) {
|
|
361
361
|
agentMessages.value['lead'] = [];
|
|
@@ -371,7 +371,7 @@ export function createTeam(deps) {
|
|
|
371
371
|
|
|
372
372
|
return {
|
|
373
373
|
// State
|
|
374
|
-
teamState,
|
|
374
|
+
teamState, viewMode, activeAgentView, historicalTeam, teamsList,
|
|
375
375
|
agentMessages,
|
|
376
376
|
// Computed
|
|
377
377
|
isTeamActive, isTeamRunning, displayTeam,
|