agim-cli 1.1.2 → 1.1.4
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/CHANGELOG.md +104 -0
- package/README.md +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/core/a2a.d.ts +19 -0
- package/dist/core/a2a.d.ts.map +1 -1
- package/dist/core/a2a.js +55 -4
- package/dist/core/a2a.js.map +1 -1
- package/dist/core/approval-bus.d.ts.map +1 -1
- package/dist/core/approval-bus.js +19 -0
- package/dist/core/approval-bus.js.map +1 -1
- package/dist/core/artifacts.d.ts +86 -0
- package/dist/core/artifacts.d.ts.map +1 -0
- package/dist/core/artifacts.js +306 -0
- package/dist/core/artifacts.js.map +1 -0
- package/dist/core/commands/a2a.d.ts.map +1 -1
- package/dist/core/commands/a2a.js +19 -5
- package/dist/core/commands/a2a.js.map +1 -1
- package/dist/core/job-board.d.ts +5 -0
- package/dist/core/job-board.d.ts.map +1 -1
- package/dist/core/job-board.js +32 -0
- package/dist/core/job-board.js.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +27 -2
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -1
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +58 -6
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -1
- package/dist/web/public/memos.html +71 -15
- package/dist/web/public/reminders.html +89 -15
- package/dist/web/public/tasks.html +555 -8
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +275 -4
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,38 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Agim — Reminders</title>
|
|
7
7
|
<script src="/_app.js"></script>
|
|
8
|
+
<script>
|
|
9
|
+
// i18n bootstrap — mirrors tasks.html. _app.js reads window.__lang.
|
|
10
|
+
(function () {
|
|
11
|
+
const LANGS = { en: 'en', zh: 'zh' };
|
|
12
|
+
const savedLang = localStorage.getItem('im-hub-lang');
|
|
13
|
+
const browserLang = navigator.language.startsWith('zh') ? 'zh' : 'en';
|
|
14
|
+
window.__lang = savedLang && LANGS[savedLang] ? savedLang : browserLang;
|
|
15
|
+
document.documentElement.lang = window.__lang === 'zh' ? 'zh-CN' : 'en';
|
|
16
|
+
const T = {
|
|
17
|
+
en: {
|
|
18
|
+
title: 'Agim — Reminders', h1: 'Reminders',
|
|
19
|
+
backToChat: 'Chat', toTasks: 'Tasks', toMemos: 'Memos', toSettings: 'Settings',
|
|
20
|
+
statusPending: 'Pending', statusFired: 'Fired', statusCancelled: 'Cancelled', statusFailed: 'Failed',
|
|
21
|
+
empty: 'No reminders matching this filter.',
|
|
22
|
+
searchPlaceholder: 'search…',
|
|
23
|
+
cancel: 'Cancel', snooze: 'Snooze', delete: 'Delete',
|
|
24
|
+
fireAt: 'Fires at', recur: 'Repeat',
|
|
25
|
+
},
|
|
26
|
+
zh: {
|
|
27
|
+
title: 'Agim — 提醒', h1: '提醒',
|
|
28
|
+
backToChat: '对话', toTasks: '任务', toMemos: '备忘', toSettings: '设置',
|
|
29
|
+
statusPending: '待发', statusFired: '已发', statusCancelled: '已取消', statusFailed: '失败',
|
|
30
|
+
empty: '当前过滤下暂无提醒。',
|
|
31
|
+
searchPlaceholder: '搜索…',
|
|
32
|
+
cancel: '取消', snooze: '推迟', delete: '删除',
|
|
33
|
+
fireAt: '触发时间', recur: '重复',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
window.__t = T[window.__lang];
|
|
37
|
+
document.title = T[window.__lang].title;
|
|
38
|
+
})();
|
|
39
|
+
</script>
|
|
8
40
|
<style>
|
|
9
41
|
:root {
|
|
10
42
|
--bg: #fafafa; --fg: #222; --muted: #666; --border: #e5e7eb;
|
|
@@ -86,20 +118,25 @@
|
|
|
86
118
|
</head>
|
|
87
119
|
<body>
|
|
88
120
|
<header>
|
|
89
|
-
<h1>🔔
|
|
121
|
+
<h1>🔔 <span id="page-title"></span></h1>
|
|
122
|
+
<button id="theme-toggle" type="button" aria-label="Toggle color theme"></button>
|
|
123
|
+
<select id="langSelect" title="Language / 语言" style="margin-right:8px">
|
|
124
|
+
<option value="en">EN</option>
|
|
125
|
+
<option value="zh">中文</option>
|
|
126
|
+
</select>
|
|
90
127
|
<nav>
|
|
91
|
-
<a href="/"
|
|
92
|
-
<a href="/tasks"
|
|
93
|
-
<a href="/memos"
|
|
94
|
-
<a href="/settings"
|
|
128
|
+
<a href="/" id="lnk-chat"></a>
|
|
129
|
+
<a href="/tasks" id="lnk-tasks"></a>
|
|
130
|
+
<a href="/memos" id="lnk-memos"></a>
|
|
131
|
+
<a href="/settings" id="lnk-settings"></a>
|
|
95
132
|
</nav>
|
|
96
133
|
</header>
|
|
97
134
|
<main>
|
|
98
135
|
<div class="filters" id="filters">
|
|
99
|
-
<button type="button" class="filter-btn active" data-status="pending"
|
|
100
|
-
<button type="button" class="filter-btn" data-status="fired"
|
|
101
|
-
<button type="button" class="filter-btn" data-status="cancelled"
|
|
102
|
-
<button type="button" class="filter-btn" data-status="failed"
|
|
136
|
+
<button type="button" class="filter-btn active" data-status="pending" id="btn-status-pending"></button>
|
|
137
|
+
<button type="button" class="filter-btn" data-status="fired" id="btn-status-fired"></button>
|
|
138
|
+
<button type="button" class="filter-btn" data-status="cancelled" id="btn-status-cancelled"></button>
|
|
139
|
+
<button type="button" class="filter-btn" data-status="failed" id="btn-status-failed"></button>
|
|
103
140
|
</div>
|
|
104
141
|
<div id="list"></div>
|
|
105
142
|
</main>
|
|
@@ -107,11 +144,34 @@
|
|
|
107
144
|
|
|
108
145
|
<script>
|
|
109
146
|
(() => {
|
|
147
|
+
const T = window.__t;
|
|
110
148
|
const $list = document.getElementById('list')
|
|
111
149
|
const $toast = document.getElementById('toast')
|
|
112
150
|
const $filters = document.getElementById('filters')
|
|
113
151
|
let currentStatus = 'pending'
|
|
114
152
|
|
|
153
|
+
// i18n bind — header labels, status filter labels, lang switcher.
|
|
154
|
+
document.getElementById('page-title').textContent = T.h1;
|
|
155
|
+
document.getElementById('lnk-chat').textContent = T.backToChat;
|
|
156
|
+
document.getElementById('lnk-tasks').textContent = T.toTasks;
|
|
157
|
+
document.getElementById('lnk-memos').textContent = T.toMemos;
|
|
158
|
+
document.getElementById('lnk-settings').textContent = T.toSettings;
|
|
159
|
+
document.getElementById('btn-status-pending').textContent = T.statusPending;
|
|
160
|
+
document.getElementById('btn-status-fired').textContent = T.statusFired;
|
|
161
|
+
document.getElementById('btn-status-cancelled').textContent = T.statusCancelled;
|
|
162
|
+
document.getElementById('btn-status-failed').textContent = T.statusFailed;
|
|
163
|
+
if (window.imhub) imhub.theme.bindToggle(document.getElementById('theme-toggle'));
|
|
164
|
+
(function setupLangSwitcher() {
|
|
165
|
+
const sel = document.getElementById('langSelect');
|
|
166
|
+
if (!sel) return;
|
|
167
|
+
sel.value = window.__lang;
|
|
168
|
+
sel.addEventListener('change', () => {
|
|
169
|
+
if (sel.value === window.__lang) return;
|
|
170
|
+
localStorage.setItem('im-hub-lang', sel.value);
|
|
171
|
+
window.location.reload();
|
|
172
|
+
});
|
|
173
|
+
})();
|
|
174
|
+
|
|
115
175
|
function toast(msg, isErr = false) {
|
|
116
176
|
$toast.textContent = msg
|
|
117
177
|
$toast.className = `toast${isErr ? ' error' : ''}`
|
|
@@ -119,17 +179,31 @@
|
|
|
119
179
|
setTimeout(() => { $toast.style.display = 'none' }, 2500)
|
|
120
180
|
}
|
|
121
181
|
|
|
122
|
-
function fmtTime(
|
|
182
|
+
function fmtTime(s) {
|
|
183
|
+
if (!s) return '-'
|
|
184
|
+
// Normalize SQLite "YYYY-MM-DD HH:MM:SS" to RFC3339 — Safari/WebView
|
|
185
|
+
// reject the space-separated form (Invalid Date).
|
|
186
|
+
let iso = String(s).trim()
|
|
187
|
+
if (iso && !iso.includes('T')) iso = iso.replace(' ', 'T')
|
|
188
|
+
if (iso && !/[Z+]/.test(iso.slice(-6))) iso = iso + 'Z'
|
|
123
189
|
const d = new Date(iso)
|
|
124
|
-
if (Number.isNaN(d.getTime())) return
|
|
190
|
+
if (Number.isNaN(d.getTime())) return s
|
|
191
|
+
const isZh = window.__lang === 'zh'
|
|
125
192
|
const now = new Date()
|
|
126
193
|
const diffMs = d.getTime() - now.getTime()
|
|
127
194
|
const absMin = Math.abs(Math.round(diffMs / 60000))
|
|
195
|
+
const past = diffMs <= 0
|
|
128
196
|
let rel = ''
|
|
129
|
-
if (Math.abs(diffMs) < 60_000) rel = '刚才'
|
|
130
|
-
else if (absMin < 60) rel =
|
|
131
|
-
|
|
132
|
-
|
|
197
|
+
if (Math.abs(diffMs) < 60_000) rel = isZh ? '刚才' : 'just now'
|
|
198
|
+
else if (absMin < 60) rel = isZh
|
|
199
|
+
? `${past ? '已过 ' : ''}${absMin} 分钟${past ? '' : '后'}`
|
|
200
|
+
: `${absMin} min ${past ? 'ago' : 'from now'}`
|
|
201
|
+
else if (absMin < 1440) rel = isZh
|
|
202
|
+
? `${past ? '已过 ' : ''}${(absMin / 60).toFixed(1)} 小时${past ? '' : '后'}`
|
|
203
|
+
: `${(absMin / 60).toFixed(1)} h ${past ? 'ago' : 'from now'}`
|
|
204
|
+
else rel = isZh
|
|
205
|
+
? `${past ? '已过 ' : ''}${(absMin / 1440).toFixed(1)} 天${past ? '' : '后'}`
|
|
206
|
+
: `${(absMin / 1440).toFixed(1)} d ${past ? 'ago' : 'from now'}`
|
|
133
207
|
return `${d.toLocaleString()} · ${rel}`
|
|
134
208
|
}
|
|
135
209
|
|