jinzd-ai-cli 0.4.206 → 0.4.208
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/dist/{batch-6PORMJWT.js → batch-3T44NFLG.js} +2 -2
- package/dist/{chunk-QQYSZMET.js → chunk-2OVMMSGQ.js} +3 -3
- package/dist/{chunk-2WV6AGHM.js → chunk-J22B3OSQ.js} +1 -1
- package/dist/{chunk-QNUVZO5X.js → chunk-KV4GYNEA.js} +1 -1
- package/dist/{chunk-KJHMRAJU.js → chunk-P7JY3SWA.js} +1 -1
- package/dist/{chunk-BQIV4ZQT.js → chunk-QDY72ABW.js} +1 -1
- package/dist/{chunk-KOU4KX7J.js → chunk-TD7JEHCR.js} +2 -2
- package/dist/{chunk-TW47X5AO.js → chunk-TM4MS63K.js} +1 -1
- package/dist/{chunk-SFCNFX42.js → chunk-VWYUB22Y.js} +1 -1
- package/dist/{ci-AYMV66P3.js → ci-6QWBVRJX.js} +2 -2
- package/dist/{constants-NHGTSHKT.js → constants-SZTQNN7K.js} +1 -1
- package/dist/{doctor-cli-WKH7T4AW.js → doctor-cli-I2Y2YR4V.js} +4 -4
- package/dist/electron-server.js +5 -8
- package/dist/{hub-6R3M3NTC.js → hub-XVPFBODB.js} +1 -1
- package/dist/index.js +90 -88
- package/dist/{run-tests-5F2OBWIK.js → run-tests-D5SNUBYX.js} +2 -2
- package/dist/{run-tests-NBCA4KEG.js → run-tests-HZ2CRCTZ.js} +1 -1
- package/dist/{server-LDPQ3DLK.js → server-4EFTRFTN.js} +10 -13
- package/dist/{server-37EXC4EB.js → server-PVKLPRUP.js} +4 -4
- package/dist/{task-orchestrator-2DTDVCMR.js → task-orchestrator-2A5VCFLS.js} +4 -4
- package/dist/{usage-SZWZFX3T.js → usage-Q24E5636.js} +2 -2
- package/dist/web/client/actions.js +84 -0
- package/dist/web/client/app.js +20 -202
- package/dist/web/client/index.html +26 -41
- package/dist/web/client/sw.js +1 -1
- package/dist/web/client/templates.js +188 -0
- package/package.json +1 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt template modal and import/export helpers.
|
|
3
|
+
* Loaded after app.js so it can use shared UI helpers.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const TEMPLATES_KEY = 'aicli-templates';
|
|
7
|
+
|
|
8
|
+
function loadTemplates() {
|
|
9
|
+
try {
|
|
10
|
+
return JSON.parse(localStorage.getItem(TEMPLATES_KEY) || '[]');
|
|
11
|
+
} catch {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function saveTemplatesToStorage(templates) {
|
|
17
|
+
localStorage.setItem(TEMPLATES_KEY, JSON.stringify(templates));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function openTemplatesModal() {
|
|
21
|
+
const modal = document.getElementById('templates-modal');
|
|
22
|
+
if (!modal) return;
|
|
23
|
+
cancelTemplateForm();
|
|
24
|
+
renderTemplateList();
|
|
25
|
+
document.getElementById('template-search').value = '';
|
|
26
|
+
modal.showModal();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function renderTemplateList(filter) {
|
|
30
|
+
const listEl = document.getElementById('template-list');
|
|
31
|
+
if (!listEl) return;
|
|
32
|
+
const templates = loadTemplates();
|
|
33
|
+
const q = (filter || '').toLowerCase();
|
|
34
|
+
const filtered = q
|
|
35
|
+
? templates.filter(t => t.name.toLowerCase().includes(q) || (t.tags || []).some(tag => tag.toLowerCase().includes(q)) || t.content.toLowerCase().includes(q))
|
|
36
|
+
: templates;
|
|
37
|
+
|
|
38
|
+
if (filtered.length === 0) {
|
|
39
|
+
listEl.innerHTML = `<div class="template-empty">${q ? 'No matching templates' : 'No templates yet. Click + New to create one.'}</div>`;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
listEl.innerHTML = filtered.map(t => {
|
|
44
|
+
const preview = t.content.length > 80 ? t.content.slice(0, 80) + '...' : t.content;
|
|
45
|
+
const tagsHtml = (t.tags || []).map(tag => `<span class="template-item-tag">${escapeHtml(tag)}</span>`).join('');
|
|
46
|
+
return `
|
|
47
|
+
<div class="template-item" data-tpl-id="${t.id}" data-action="use-template">
|
|
48
|
+
<div class="template-item-body">
|
|
49
|
+
<div class="template-item-name">${escapeHtml(t.name)}</div>
|
|
50
|
+
<div class="template-item-preview">${escapeHtml(preview)}</div>
|
|
51
|
+
${tagsHtml ? `<div class="template-item-tags">${tagsHtml}</div>` : ''}
|
|
52
|
+
</div>
|
|
53
|
+
<div class="template-item-actions">
|
|
54
|
+
<button class="btn btn-xs btn-ghost" data-action="edit-template" title="Edit">Edit</button>
|
|
55
|
+
<button class="btn btn-xs btn-ghost" data-action="delete-template" title="Delete">Delete</button>
|
|
56
|
+
</div>
|
|
57
|
+
</div>`;
|
|
58
|
+
}).join('');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function useTemplate(id) {
|
|
62
|
+
const templates = loadTemplates();
|
|
63
|
+
const tpl = templates.find(t => t.id === id);
|
|
64
|
+
if (!tpl) return;
|
|
65
|
+
const input = document.getElementById('user-input');
|
|
66
|
+
if (!input) return;
|
|
67
|
+
input.value = tpl.content;
|
|
68
|
+
input.focus();
|
|
69
|
+
input.style.height = 'auto';
|
|
70
|
+
input.style.height = Math.min(input.scrollHeight, 200) + 'px';
|
|
71
|
+
document.getElementById('templates-modal')?.close();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function showAddTemplate() {
|
|
75
|
+
const form = document.getElementById('template-form');
|
|
76
|
+
form.classList.remove('hidden');
|
|
77
|
+
document.getElementById('tpl-edit-id').value = '';
|
|
78
|
+
document.getElementById('tpl-name').value = '';
|
|
79
|
+
document.getElementById('tpl-content').value = '';
|
|
80
|
+
document.getElementById('tpl-tags').value = '';
|
|
81
|
+
document.getElementById('tpl-name').focus();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function editTemplate(id) {
|
|
85
|
+
const templates = loadTemplates();
|
|
86
|
+
const tpl = templates.find(t => t.id === id);
|
|
87
|
+
if (!tpl) return;
|
|
88
|
+
const form = document.getElementById('template-form');
|
|
89
|
+
form.classList.remove('hidden');
|
|
90
|
+
document.getElementById('tpl-edit-id').value = tpl.id;
|
|
91
|
+
document.getElementById('tpl-name').value = tpl.name;
|
|
92
|
+
document.getElementById('tpl-content').value = tpl.content;
|
|
93
|
+
document.getElementById('tpl-tags').value = (tpl.tags || []).join(', ');
|
|
94
|
+
document.getElementById('tpl-name').focus();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function cancelTemplateForm() {
|
|
98
|
+
document.getElementById('template-form')?.classList.add('hidden');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function saveTemplateForm() {
|
|
102
|
+
const name = document.getElementById('tpl-name').value.trim();
|
|
103
|
+
const content = document.getElementById('tpl-content').value.trim();
|
|
104
|
+
const tagsRaw = document.getElementById('tpl-tags').value.trim();
|
|
105
|
+
const editId = document.getElementById('tpl-edit-id').value;
|
|
106
|
+
|
|
107
|
+
if (!name || !content) return;
|
|
108
|
+
|
|
109
|
+
const tags = tagsRaw ? tagsRaw.split(',').map(s => s.trim()).filter(Boolean) : [];
|
|
110
|
+
const templates = loadTemplates();
|
|
111
|
+
|
|
112
|
+
if (editId) {
|
|
113
|
+
const idx = templates.findIndex(t => t.id === editId);
|
|
114
|
+
if (idx >= 0) {
|
|
115
|
+
templates[idx].name = name;
|
|
116
|
+
templates[idx].content = content;
|
|
117
|
+
templates[idx].tags = tags;
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
templates.unshift({
|
|
121
|
+
id: 'tpl-' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6),
|
|
122
|
+
name,
|
|
123
|
+
content,
|
|
124
|
+
tags,
|
|
125
|
+
createdAt: new Date().toISOString(),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
saveTemplatesToStorage(templates);
|
|
130
|
+
cancelTemplateForm();
|
|
131
|
+
renderTemplateList();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function deleteTemplate(id) {
|
|
135
|
+
const templates = loadTemplates().filter(t => t.id !== id);
|
|
136
|
+
saveTemplatesToStorage(templates);
|
|
137
|
+
renderTemplateList(document.getElementById('template-search')?.value);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function exportTemplates() {
|
|
141
|
+
const templates = loadTemplates();
|
|
142
|
+
if (templates.length === 0) return;
|
|
143
|
+
const blob = new Blob([JSON.stringify(templates, null, 2)], { type: 'application/json' });
|
|
144
|
+
const url = URL.createObjectURL(blob);
|
|
145
|
+
const a = document.createElement('a');
|
|
146
|
+
a.href = url;
|
|
147
|
+
a.download = `aicli-templates-${new Date().toISOString().slice(0, 10)}.json`;
|
|
148
|
+
a.click();
|
|
149
|
+
URL.revokeObjectURL(url);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function importTemplates() {
|
|
153
|
+
const input = document.createElement('input');
|
|
154
|
+
input.type = 'file';
|
|
155
|
+
input.accept = '.json';
|
|
156
|
+
input.addEventListener('change', () => {
|
|
157
|
+
const file = input.files[0];
|
|
158
|
+
if (!file) return;
|
|
159
|
+
const reader = new FileReader();
|
|
160
|
+
reader.addEventListener('load', () => {
|
|
161
|
+
try {
|
|
162
|
+
const imported = JSON.parse(reader.result);
|
|
163
|
+
if (!Array.isArray(imported)) throw new Error('Not an array');
|
|
164
|
+
const existing = loadTemplates();
|
|
165
|
+
const existingIds = new Set(existing.map(t => t.id));
|
|
166
|
+
let added = 0;
|
|
167
|
+
for (const t of imported) {
|
|
168
|
+
if (t.id && t.name && t.content && !existingIds.has(t.id)) {
|
|
169
|
+
existing.push(t);
|
|
170
|
+
added++;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
saveTemplatesToStorage(existing);
|
|
174
|
+
renderTemplateList();
|
|
175
|
+
addInfoMessage(`Imported ${added} template(s).`);
|
|
176
|
+
} catch {
|
|
177
|
+
addErrorMessage('Failed to import templates: invalid JSON format.');
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
reader.readAsText(file);
|
|
181
|
+
});
|
|
182
|
+
input.click();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
document.getElementById('btn-templates')?.addEventListener('click', openTemplatesModal);
|
|
186
|
+
document.getElementById('template-search')?.addEventListener('input', (e) => {
|
|
187
|
+
renderTemplateList(e.target.value);
|
|
188
|
+
});
|