@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.
@@ -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
+ }
@@ -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 input mode */
27
- const teamMode = ref('chat');
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
- teamMode.value = 'chat';
138
+ viewMode.value = 'chat';
139
139
  historicalTeam.value = null;
140
140
  activeAgentView.value = null;
141
141
  }
142
142
 
143
143
  function newTeam() {
144
- teamMode.value = 'team';
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
- teamMode.value = 'team';
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
- teamMode.value = 'team';
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
- teamMode.value = 'team';
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, teamMode, activeAgentView, historicalTeam, teamsList,
374
+ teamState, viewMode, activeAgentView, historicalTeam, teamsList,
375
375
  agentMessages,
376
376
  // Computed
377
377
  isTeamActive, isTeamRunning, displayTeam,