codexmate 0.1.23 → 0.1.25
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/cli.js +4 -1
- package/package.json +1 -1
- package/plugins/prompt-templates/computed.mjs +1 -1
- package/plugins/prompt-templates/index.mjs +3 -3
- package/plugins/prompt-templates/manifest.mjs +5 -3
- package/plugins/prompt-templates/methods.mjs +9 -2
- package/plugins/registry.mjs +5 -2
- package/plugins/text-tools/computed.mjs +23 -0
- package/plugins/text-tools/index.mjs +14 -0
- package/plugins/text-tools/manifest.mjs +20 -0
- package/plugins/text-tools/methods.mjs +24 -0
- package/plugins/text-tools/overview.mjs +12 -0
- package/plugins/text-tools/ownership.mjs +7 -0
- package/web-ui/app.js +5 -2
- package/web-ui/index.html +0 -1
- package/web-ui/logic.markdown-editor.mjs +5 -57
- package/web-ui/logic.prompts-change-axis.mjs +3 -88
- package/web-ui/logic.prompts-path-reference.mjs +118 -0
- package/web-ui/modules/app.methods.agents.mjs +1 -0
- package/web-ui/modules/app.methods.index.mjs +1 -1
- package/web-ui/modules/app.methods.navigation.mjs +79 -3
- package/web-ui/modules/app.methods.prompts-editor.mjs +140 -145
- package/web-ui/modules/app.methods.web-ui-preferences.mjs +7 -1
- package/web-ui/modules/i18n/locales/en.mjs +22 -1
- package/web-ui/modules/i18n/locales/ja.mjs +22 -1
- package/web-ui/modules/i18n/locales/vi.mjs +22 -1
- package/web-ui/modules/i18n/locales/zh-tw.mjs +22 -1
- package/web-ui/modules/i18n/locales/zh.mjs +22 -1
- package/web-ui/modules/plugins.computed.mjs +8 -2
- package/web-ui/modules/plugins.methods.mjs +8 -2
- package/web-ui/partials/index/layout-header.html +19 -4
- package/web-ui/partials/index/panel-plugins.html +45 -5
- package/web-ui/partials/index/panel-prompts.html +24 -31
- package/web-ui/res/web-ui-render.precompiled.js +142 -130
- package/web-ui/session-helpers.mjs +0 -1
- package/web-ui/source-bundle.cjs +1 -0
- package/web-ui/styles/prompts-editor.css +20 -91
|
@@ -110,12 +110,17 @@
|
|
|
110
110
|
const settingsTab = typeof vm.settingsTab === 'string' ? vm.settingsTab.trim().toLowerCase() : 'general';
|
|
111
111
|
const skillsTargetApp = typeof vm.skillsTargetApp === 'string' && (vm.skillsTargetApp === 'codex' || vm.skillsTargetApp === 'claude' || vm.skillsTargetApp === 'pi') ? vm.skillsTargetApp : 'codex';
|
|
112
112
|
const promptTemplatesMode = typeof vm.promptTemplatesMode === 'string' && (vm.promptTemplatesMode === 'compose' || vm.promptTemplatesMode === 'manage') ? vm.promptTemplatesMode : 'compose';
|
|
113
|
+
const pluginsActiveIdSource = resolvedOverrides && typeof resolvedOverrides.pluginsActiveId === 'string'
|
|
114
|
+
? resolvedOverrides.pluginsActiveId
|
|
115
|
+
: vm.pluginsActiveId;
|
|
116
|
+
const pluginsActiveId = typeof pluginsActiveIdSource === 'string' ? pluginsActiveIdSource.trim() : '';
|
|
113
117
|
const snapshot = {
|
|
114
118
|
settingsTab: settingsTab === 'data' ? 'data' : 'general',
|
|
115
119
|
mainTab: resolveSelectableMainTab(mainTab),
|
|
116
120
|
configMode: configModeSet && configModeSet.has(configMode) ? configMode : 'codex',
|
|
117
121
|
skillsTargetApp,
|
|
118
|
-
promptTemplatesMode
|
|
122
|
+
promptTemplatesMode,
|
|
123
|
+
pluginsActiveId: pluginsActiveId || 'prompt-templates'
|
|
119
124
|
};
|
|
120
125
|
if (typeof vm.persistWebUiPreferences === 'function') {
|
|
121
126
|
vm.persistWebUiPreferences({ navigation: snapshot });
|
|
@@ -192,6 +197,7 @@
|
|
|
192
197
|
intent: '',
|
|
193
198
|
pendingTarget: '',
|
|
194
199
|
pendingConfigMode: '',
|
|
200
|
+
pendingPluginsId: '',
|
|
195
201
|
ticket: 0
|
|
196
202
|
};
|
|
197
203
|
return this.__mainTabSwitchState;
|
|
@@ -242,7 +248,7 @@
|
|
|
242
248
|
if (!normalizedKind || !normalizedValue) {
|
|
243
249
|
return;
|
|
244
250
|
}
|
|
245
|
-
const expectedIntent = normalizedKind === 'config'
|
|
251
|
+
const expectedIntent = normalizedKind === 'config' || normalizedKind === 'plugins' ? normalizedKind : normalizedValue;
|
|
246
252
|
this.cancelTouchNavIntentReset();
|
|
247
253
|
const token = (Number(this.__touchNavIntentResetToken) || 0) + 1;
|
|
248
254
|
this.__touchNavIntentResetToken = token;
|
|
@@ -259,21 +265,26 @@
|
|
|
259
265
|
this.clearMainTabSwitchIntent(expectedIntent);
|
|
260
266
|
}, 1000);
|
|
261
267
|
},
|
|
262
|
-
applyImmediateNavIntent(tab, configMode = '') {
|
|
268
|
+
applyImmediateNavIntent(tab, configMode = '', pluginsId = '') {
|
|
263
269
|
if (typeof document === 'undefined') return;
|
|
264
270
|
const normalizedTab = typeof tab === 'string' ? tab.trim().toLowerCase() : '';
|
|
265
271
|
if (!normalizedTab) return;
|
|
266
272
|
const normalizedMode = typeof configMode === 'string' ? configMode.trim().toLowerCase() : '';
|
|
273
|
+
const normalizedPluginId = typeof pluginsId === 'string' ? pluginsId.trim().toLowerCase() : '';
|
|
267
274
|
const domState = this.ensureImmediateNavDomState();
|
|
268
275
|
const nodes = Array.isArray(domState.navNodes) ? domState.navNodes : [];
|
|
269
276
|
for (const node of nodes) {
|
|
270
277
|
if (!node || !node.classList) continue;
|
|
271
278
|
const nodeTab = String(node.getAttribute('data-main-tab') || '').trim().toLowerCase();
|
|
272
279
|
const nodeMode = String(node.getAttribute('data-config-mode') || '').trim().toLowerCase();
|
|
280
|
+
const nodePluginId = String(node.getAttribute('data-plugins-id') || '').trim().toLowerCase();
|
|
273
281
|
let shouldActivate = nodeTab === normalizedTab;
|
|
274
282
|
if (shouldActivate && normalizedTab === 'config') {
|
|
275
283
|
shouldActivate = nodeMode ? nodeMode === normalizedMode : false;
|
|
276
284
|
}
|
|
285
|
+
if (shouldActivate && normalizedTab === 'plugins') {
|
|
286
|
+
shouldActivate = nodePluginId ? nodePluginId === normalizedPluginId : !normalizedPluginId;
|
|
287
|
+
}
|
|
277
288
|
node.classList.toggle('nav-intent-active', !!shouldActivate);
|
|
278
289
|
node.classList.toggle('nav-intent-inactive', !shouldActivate);
|
|
279
290
|
}
|
|
@@ -395,6 +406,67 @@
|
|
|
395
406
|
if (this.consumePointerNavCommit('config', normalizedMode)) return;
|
|
396
407
|
this.switchConfigMode(normalizedMode);
|
|
397
408
|
},
|
|
409
|
+
|
|
410
|
+
switchPluginsTab(pluginId) {
|
|
411
|
+
const normalizedId = typeof pluginId === 'string' ? pluginId.trim().toLowerCase() : '';
|
|
412
|
+
if (!normalizedId) return;
|
|
413
|
+
if (typeof this.selectPlugin === 'function') {
|
|
414
|
+
this.selectPlugin(normalizedId);
|
|
415
|
+
} else {
|
|
416
|
+
this.pluginsActiveId = normalizedId;
|
|
417
|
+
}
|
|
418
|
+
this.switchMainTab('plugins');
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
onPluginsTabPointerDown(pluginId) {
|
|
422
|
+
const event = arguments.length > 1 ? arguments[1] : null;
|
|
423
|
+
if (event && typeof event.button === 'number' && event.button !== 0) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
const normalizedId = typeof pluginId === 'string' ? pluginId.trim().toLowerCase() : '';
|
|
427
|
+
if (!normalizedId) return;
|
|
428
|
+
persistNavState(this, { mainTab: 'plugins', pluginsActiveId: normalizedId });
|
|
429
|
+
this.setMainTabSwitchIntent('plugins');
|
|
430
|
+
if (typeof this.ensureMainTabSwitchState === 'function') {
|
|
431
|
+
this.ensureMainTabSwitchState().pendingPluginsId = normalizedId;
|
|
432
|
+
}
|
|
433
|
+
this.applyImmediateNavIntent('plugins', '', normalizedId);
|
|
434
|
+
const shouldHideSessionPanel = this.mainTab === 'sessions';
|
|
435
|
+
this.setSessionPanelFastHidden(shouldHideSessionPanel);
|
|
436
|
+
const pointerType = event && typeof event.pointerType === 'string'
|
|
437
|
+
? event.pointerType.trim().toLowerCase()
|
|
438
|
+
: '';
|
|
439
|
+
if (pointerType === 'touch') {
|
|
440
|
+
this.scheduleTouchNavIntentReset('plugins', normalizedId);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
this.recordPointerNavCommit('plugins', normalizedId);
|
|
444
|
+
this.switchPluginsTab(normalizedId);
|
|
445
|
+
},
|
|
446
|
+
|
|
447
|
+
onPluginsTabClick(pluginId) {
|
|
448
|
+
const normalizedId = typeof pluginId === 'string' ? pluginId.trim().toLowerCase() : '';
|
|
449
|
+
if (!normalizedId) return;
|
|
450
|
+
if (this.consumePointerNavCommit('plugins', normalizedId)) return;
|
|
451
|
+
this.switchPluginsTab(normalizedId);
|
|
452
|
+
},
|
|
453
|
+
|
|
454
|
+
isPluginsIdNavActive(pluginId) {
|
|
455
|
+
const normalizedId = typeof pluginId === 'string' ? pluginId.trim().toLowerCase() : '';
|
|
456
|
+
if (!normalizedId) return false;
|
|
457
|
+
if (!this.isMainTabNavActive('plugins')) return false;
|
|
458
|
+
const state = this.ensureMainTabSwitchState();
|
|
459
|
+
const pendingId = typeof state.pendingPluginsId === 'string'
|
|
460
|
+
? state.pendingPluginsId.trim().toLowerCase()
|
|
461
|
+
: '';
|
|
462
|
+
if (state.intent === 'plugins' && pendingId) {
|
|
463
|
+
return pendingId === normalizedId;
|
|
464
|
+
}
|
|
465
|
+
const currentId = typeof this.pluginsActiveId === 'string'
|
|
466
|
+
? this.pluginsActiveId.trim().toLowerCase()
|
|
467
|
+
: '';
|
|
468
|
+
return currentId === normalizedId;
|
|
469
|
+
},
|
|
398
470
|
clearMainTabSwitchIntent(expectedTab = '') {
|
|
399
471
|
const state = this.ensureMainTabSwitchState();
|
|
400
472
|
if (expectedTab && state.intent && state.intent !== expectedTab) {
|
|
@@ -404,6 +476,7 @@
|
|
|
404
476
|
state.intent = '';
|
|
405
477
|
state.pendingTarget = '';
|
|
406
478
|
state.pendingConfigMode = '';
|
|
479
|
+
state.pendingPluginsId = '';
|
|
407
480
|
this.clearImmediateNavIntent();
|
|
408
481
|
this.setSessionPanelFastHidden(false);
|
|
409
482
|
},
|
|
@@ -463,6 +536,9 @@
|
|
|
463
536
|
if (targetTab !== 'config') {
|
|
464
537
|
switchState.pendingConfigMode = '';
|
|
465
538
|
}
|
|
539
|
+
if (targetTab !== 'plugins') {
|
|
540
|
+
switchState.pendingPluginsId = '';
|
|
541
|
+
}
|
|
466
542
|
if (targetTab === previousTab) {
|
|
467
543
|
switchState.ticket += 1;
|
|
468
544
|
switchState.pendingTarget = '';
|
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Prompts-panel Markdown editor methods:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* and the sysPromptContent editor.
|
|
2
|
+
* Prompts-panel Markdown editor methods: mobile view switching and the
|
|
3
|
+
* live split preview (marked + DOMPurify, debounced). One implementation
|
|
4
|
+
* is shared by the agentsContent editor and the sysPromptContent editor.
|
|
6
5
|
*
|
|
7
6
|
* State contract (declared in app.js data()):
|
|
8
7
|
* promptsPreviewEnabled, promptsPreviewCollapsed, promptsMobileView,
|
|
9
|
-
* promptsPreviewLibsMissing,
|
|
10
|
-
*
|
|
8
|
+
* promptsPreviewLibsMissing, agentsPreviewHtml, sysPromptPreviewHtml,
|
|
9
|
+
* agentsChangeAxis, sysChangeAxis,
|
|
10
|
+
* promptsPathReferencePaths, promptsPathReferenceLoading,
|
|
11
|
+
* promptsPathReferenceCacheKey (path-reference dropdown)
|
|
11
12
|
* Template contract:
|
|
12
13
|
* refs promptsAgentsTextarea / promptsSysTextarea on the two textareas,
|
|
13
|
-
* refs promptsAgentsHighlight / promptsSysHighlight on the backdrop <pre>,
|
|
14
14
|
* refs promptsAgentsDiffView / promptsSysDiffView on the two diff row containers.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { buildMarkdownPreviewHtml } from '../logic.markdown-editor.mjs';
|
|
17
18
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
buildPromptPathReferenceOptions as buildPromptPathReferenceOptionList,
|
|
20
|
+
buildPromptPathReferenceSentence,
|
|
21
|
+
insertPromptPathReferenceText
|
|
22
|
+
} from '../logic.prompts-path-reference.mjs';
|
|
21
23
|
import {
|
|
22
|
-
|
|
23
|
-
buildPromptsDiffAxis,
|
|
24
|
-
computePromptsAxisScrollTop
|
|
24
|
+
buildPromptsDiffAxis
|
|
25
25
|
} from '../logic.prompts-change-axis.mjs';
|
|
26
26
|
|
|
27
|
-
const PROMPTS_HIGHLIGHT_DEBOUNCE_MS = 150;
|
|
28
27
|
const PROMPTS_PREVIEW_DEBOUNCE_MS = 300;
|
|
29
28
|
const PROMPTS_AXIS_DEBOUNCE_MS = 300;
|
|
30
29
|
|
|
@@ -32,7 +31,6 @@ const PROMPTS_EDITOR_META = {
|
|
|
32
31
|
agents: {
|
|
33
32
|
contentField: 'agentsContent',
|
|
34
33
|
originalField: 'agentsOriginalContent',
|
|
35
|
-
highlightField: 'agentsHighlightHtml',
|
|
36
34
|
previewField: 'agentsPreviewHtml',
|
|
37
35
|
axisField: 'agentsChangeAxis',
|
|
38
36
|
diffLinesField: 'agentsDiffLines',
|
|
@@ -43,13 +41,11 @@ const PROMPTS_EDITOR_META = {
|
|
|
43
41
|
diffLoadingField: 'agentsDiffLoading',
|
|
44
42
|
prepareDiffMethod: 'prepareAgentsDiff',
|
|
45
43
|
textareaRef: 'promptsAgentsTextarea',
|
|
46
|
-
highlightRef: 'promptsAgentsHighlight',
|
|
47
44
|
diffViewRef: 'promptsAgentsDiffView'
|
|
48
45
|
},
|
|
49
46
|
sys: {
|
|
50
47
|
contentField: 'sysPromptContent',
|
|
51
48
|
originalField: 'sysPromptOriginalContent',
|
|
52
|
-
highlightField: 'sysPromptHighlightHtml',
|
|
53
49
|
previewField: 'sysPromptPreviewHtml',
|
|
54
50
|
axisField: 'sysChangeAxis',
|
|
55
51
|
diffLinesField: 'sysPromptDiffLines',
|
|
@@ -60,7 +56,6 @@ const PROMPTS_EDITOR_META = {
|
|
|
60
56
|
diffLoadingField: 'sysPromptDiffLoading',
|
|
61
57
|
prepareDiffMethod: 'prepareSysPromptDiff',
|
|
62
58
|
textareaRef: 'promptsSysTextarea',
|
|
63
|
-
highlightRef: 'promptsSysHighlight',
|
|
64
59
|
diffViewRef: 'promptsSysDiffView'
|
|
65
60
|
}
|
|
66
61
|
};
|
|
@@ -69,13 +64,6 @@ function emptyPromptsChangeAxis() {
|
|
|
69
64
|
return { mode: 'edit', ticks: [], truncated: false, totalLines: 0, added: 0, removed: 0 };
|
|
70
65
|
}
|
|
71
66
|
|
|
72
|
-
function resolvePromptsHljs() {
|
|
73
|
-
if (typeof window !== 'undefined' && window.hljs) {
|
|
74
|
-
return window.hljs;
|
|
75
|
-
}
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
67
|
function resolvePromptsPreviewLibs() {
|
|
80
68
|
if (typeof window === 'undefined') {
|
|
81
69
|
return { marked: null, purify: null };
|
|
@@ -83,53 +71,15 @@ function resolvePromptsPreviewLibs() {
|
|
|
83
71
|
return { marked: window.marked || null, purify: window.DOMPurify || null };
|
|
84
72
|
}
|
|
85
73
|
|
|
86
|
-
export function createPromptsEditorMethods() {
|
|
74
|
+
export function createPromptsEditorMethods(options = {}) {
|
|
75
|
+
const { api } = options;
|
|
76
|
+
|
|
87
77
|
return {
|
|
88
78
|
promptsEditorMeta(key) {
|
|
89
79
|
return PROMPTS_EDITOR_META[key] || null;
|
|
90
80
|
},
|
|
91
81
|
|
|
92
82
|
|
|
93
|
-
refreshPromptsHighlight(key) {
|
|
94
|
-
const meta = this.promptsEditorMeta(key);
|
|
95
|
-
if (!meta) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
this[meta.highlightField] = highlightMarkdownText(this[meta.contentField], resolvePromptsHljs());
|
|
99
|
-
this.syncPromptsOverlayScroll(key);
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
schedulePromptsHighlight(key) {
|
|
103
|
-
const meta = this.promptsEditorMeta(key);
|
|
104
|
-
if (!meta) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
if (!this._promptsHighlightTimers) {
|
|
108
|
-
this._promptsHighlightTimers = {};
|
|
109
|
-
}
|
|
110
|
-
if (this._promptsHighlightTimers[key]) {
|
|
111
|
-
clearTimeout(this._promptsHighlightTimers[key]);
|
|
112
|
-
}
|
|
113
|
-
this._promptsHighlightTimers[key] = setTimeout(() => {
|
|
114
|
-
this._promptsHighlightTimers[key] = null;
|
|
115
|
-
this.refreshPromptsHighlight(key);
|
|
116
|
-
}, PROMPTS_HIGHLIGHT_DEBOUNCE_MS);
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
syncPromptsOverlayScroll(key) {
|
|
120
|
-
const meta = this.promptsEditorMeta(key);
|
|
121
|
-
if (!meta || typeof this.$refs !== 'object' || !this.$refs) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
const textarea = this.$refs[meta.textareaRef];
|
|
125
|
-
const backdrop = this.$refs[meta.highlightRef];
|
|
126
|
-
if (!textarea || !backdrop) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
backdrop.scrollTop = textarea.scrollTop;
|
|
130
|
-
backdrop.scrollLeft = textarea.scrollLeft;
|
|
131
|
-
},
|
|
132
|
-
|
|
133
83
|
refreshPromptsPreview(key) {
|
|
134
84
|
const meta = this.promptsEditorMeta(key);
|
|
135
85
|
if (!meta) {
|
|
@@ -167,7 +117,6 @@ export function createPromptsEditorMethods() {
|
|
|
167
117
|
},
|
|
168
118
|
|
|
169
119
|
schedulePromptsEditorRefresh(key) {
|
|
170
|
-
this.schedulePromptsHighlight(key);
|
|
171
120
|
this.schedulePromptsPreview(key);
|
|
172
121
|
this.schedulePromptsChangeAxis(key);
|
|
173
122
|
},
|
|
@@ -188,25 +137,12 @@ export function createPromptsEditorMethods() {
|
|
|
188
137
|
added: Number(stats && stats.added) || 0,
|
|
189
138
|
removed: Number(stats && stats.removed) || 0
|
|
190
139
|
};
|
|
191
|
-
this.consumePromptsAxisPendingJump(key);
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
this.clearPromptsAxisPendingJump(key);
|
|
195
|
-
const current = this[meta.contentField];
|
|
196
|
-
const original = this[meta.originalField];
|
|
197
|
-
if (typeof current !== 'string' || current === original) {
|
|
198
|
-
this[meta.axisField] = emptyPromptsChangeAxis();
|
|
199
140
|
return;
|
|
200
141
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
truncated: axis.truncated,
|
|
206
|
-
totalLines: axis.totalLines,
|
|
207
|
-
added: Number(axis.stats && axis.stats.added) || 0,
|
|
208
|
-
removed: Number(axis.stats && axis.stats.removed) || 0
|
|
209
|
-
};
|
|
142
|
+
// Edit mode renders no axis (the axis is a diff-preview-only
|
|
143
|
+
// affordance): keep it empty so the full line-diff cost is only
|
|
144
|
+
// paid while the red/green preview is open.
|
|
145
|
+
this[meta.axisField] = emptyPromptsChangeAxis();
|
|
210
146
|
},
|
|
211
147
|
|
|
212
148
|
schedulePromptsChangeAxis(key) {
|
|
@@ -241,85 +177,144 @@ export function createPromptsEditorMethods() {
|
|
|
241
177
|
}
|
|
242
178
|
return;
|
|
243
179
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const canOpenDiff = typeof this[meta.prepareDiffMethod] === 'function'
|
|
250
|
-
&& !this[meta.loadingField]
|
|
251
|
-
&& !this[meta.savingField]
|
|
252
|
-
&& !this[meta.diffLoadingField];
|
|
253
|
-
if (canOpenDiff) {
|
|
254
|
-
this._promptsAxisPendingJump = { key, startLine: tick.startLine };
|
|
255
|
-
this[meta.prepareDiffMethod]();
|
|
256
|
-
return;
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
setPromptsMobileView(view) {
|
|
183
|
+
if (view === 'edit' || view === 'preview') {
|
|
184
|
+
this.promptsMobileView = view;
|
|
257
185
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
togglePromptsPreviewCollapsed() {
|
|
189
|
+
this.promptsPreviewCollapsed = !this.promptsPreviewCollapsed;
|
|
190
|
+
if (typeof this.persistWebUiPreferences === 'function') {
|
|
191
|
+
this.persistWebUiPreferences({ promptsPreviewCollapsed: this.promptsPreviewCollapsed });
|
|
264
192
|
}
|
|
265
|
-
textarea.scrollTop = computePromptsAxisScrollTop(
|
|
266
|
-
textarea.scrollHeight,
|
|
267
|
-
textarea.clientHeight,
|
|
268
|
-
tick.startLine,
|
|
269
|
-
axis.totalLines
|
|
270
|
-
);
|
|
271
|
-
this.syncPromptsOverlayScroll(key);
|
|
272
193
|
},
|
|
273
194
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
this.
|
|
195
|
+
buildPromptsPathReferenceCacheKey() {
|
|
196
|
+
return [
|
|
197
|
+
(this.projectClaudeMdPath || '').trim(),
|
|
198
|
+
this.sysPromptScope || 'global',
|
|
199
|
+
this.sysPromptMode || 'system'
|
|
200
|
+
].join('|');
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
// Lazy loader for the path-reference dropdown. Fetches the OTHER tabs'
|
|
204
|
+
// real absolute paths via the existing metaOnly RPC contracts
|
|
205
|
+
// (get-agents-file / get-opencode-agents-file / get-claude-md-file
|
|
206
|
+
// return path + exists without content; get-system-prompt returns
|
|
207
|
+
// path + a small SYSTEM.md/APPEND_SYSTEM.md read). Cache key covers the
|
|
208
|
+
// only inputs that change a resolved path: project baseDir, sysPrompt
|
|
209
|
+
// scope and mode. Idempotent per key; concurrent callers share the
|
|
210
|
+
// in-flight promise.
|
|
211
|
+
loadPromptsPathReferences() {
|
|
212
|
+
const cacheKey = this.buildPromptsPathReferenceCacheKey();
|
|
213
|
+
if (this.promptsPathReferenceCacheKey === cacheKey && !this.promptsPathReferenceLoading) {
|
|
214
|
+
return Promise.resolve();
|
|
215
|
+
}
|
|
216
|
+
if (this.promptsPathReferenceLoading && this._promptsPathReferencePromise) {
|
|
217
|
+
return this._promptsPathReferencePromise;
|
|
277
218
|
}
|
|
219
|
+
if (typeof api !== 'function') {
|
|
220
|
+
return Promise.resolve();
|
|
221
|
+
}
|
|
222
|
+
const projectPath = (this.projectClaudeMdPath || '').trim();
|
|
223
|
+
const scope = this.sysPromptScope || 'global';
|
|
224
|
+
const mode = this.sysPromptMode || 'system';
|
|
225
|
+
const fetchEntry = async (action, params) => {
|
|
226
|
+
try {
|
|
227
|
+
const res = await api(action, params);
|
|
228
|
+
if (res && res.error) {
|
|
229
|
+
return { path: '', exists: false, error: String(res.error) };
|
|
230
|
+
}
|
|
231
|
+
return { path: (res && res.path) || '', exists: !!(res && res.exists) };
|
|
232
|
+
} catch (e) {
|
|
233
|
+
return {
|
|
234
|
+
path: '',
|
|
235
|
+
exists: false,
|
|
236
|
+
error: typeof this.t === 'function' ? this.t('prompts.pathReference.loadFailed') : 'load failed'
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
this.promptsPathReferenceLoading = true;
|
|
241
|
+
const promise = Promise.all([
|
|
242
|
+
fetchEntry('get-agents-file', { metaOnly: true }),
|
|
243
|
+
fetchEntry('get-opencode-agents-file', { metaOnly: true }),
|
|
244
|
+
fetchEntry('get-claude-md-file', { metaOnly: true }),
|
|
245
|
+
projectPath
|
|
246
|
+
? fetchEntry('get-claude-md-file', { baseDir: projectPath, metaOnly: true })
|
|
247
|
+
: Promise.resolve(null),
|
|
248
|
+
fetchEntry('get-system-prompt', { scope, mode })
|
|
249
|
+
]).then((results) => {
|
|
250
|
+
this.promptsPathReferencePaths = {
|
|
251
|
+
codex: results[0],
|
|
252
|
+
opencode: results[1],
|
|
253
|
+
claudeGlobal: results[2],
|
|
254
|
+
claudeProject: results[3] || { path: '', exists: false, error: '' },
|
|
255
|
+
system: results[4]
|
|
256
|
+
};
|
|
257
|
+
this.promptsPathReferenceCacheKey = cacheKey;
|
|
258
|
+
}).finally(() => {
|
|
259
|
+
this.promptsPathReferenceLoading = false;
|
|
260
|
+
this._promptsPathReferencePromise = null;
|
|
261
|
+
});
|
|
262
|
+
this._promptsPathReferencePromise = promise;
|
|
263
|
+
return promise;
|
|
278
264
|
},
|
|
279
265
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
266
|
+
promptsPathReferenceOptionList() {
|
|
267
|
+
return buildPromptPathReferenceOptionList({
|
|
268
|
+
currentTab: this.promptsSubTab,
|
|
269
|
+
paths: this.promptsPathReferencePaths || {},
|
|
270
|
+
t: (key, params) => (typeof this.t === 'function' ? this.t(key, params) : key),
|
|
271
|
+
systemFile: (this.sysPromptMode || 'system') === 'append' ? 'APPEND_SYSTEM.md' : 'SYSTEM.md'
|
|
272
|
+
});
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
insertPromptPathReference(entryId, key, event) {
|
|
276
|
+
const select = event && event.target;
|
|
277
|
+
if (select && typeof select.value === 'string') {
|
|
278
|
+
select.value = '';
|
|
284
279
|
}
|
|
285
280
|
const meta = this.promptsEditorMeta(key);
|
|
286
|
-
|
|
287
|
-
|
|
281
|
+
const entry = (this.promptsPathReferencePaths || {})[entryId];
|
|
282
|
+
if (!meta || !entry || !entry.path || entry.error) {
|
|
288
283
|
return;
|
|
289
284
|
}
|
|
290
|
-
|
|
291
|
-
if (!axis || axis.mode !== 'diff' || !axis.ticks.length) {
|
|
285
|
+
if (this[meta.loadingField] || this[meta.savingField] || this[meta.diffVisibleField]) {
|
|
292
286
|
return;
|
|
293
287
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
288
|
+
const sentence = buildPromptPathReferenceSentence(entry.path);
|
|
289
|
+
if (!sentence) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const textarea = typeof this.$refs === 'object' && this.$refs
|
|
293
|
+
? this.$refs[meta.textareaRef]
|
|
294
|
+
: null;
|
|
295
|
+
const content = typeof this[meta.contentField] === 'string' ? this[meta.contentField] : '';
|
|
296
|
+
let start = content.length;
|
|
297
|
+
let end = content.length;
|
|
298
|
+
if (textarea && typeof textarea.selectionStart === 'number') {
|
|
299
|
+
start = textarea.selectionStart;
|
|
300
|
+
end = textarea.selectionEnd;
|
|
301
|
+
}
|
|
302
|
+
const result = insertPromptPathReferenceText(content, start, end, sentence);
|
|
303
|
+
this[meta.contentField] = result.content;
|
|
304
|
+
this.schedulePromptsEditorRefresh(key);
|
|
305
|
+
const restoreCaret = () => {
|
|
306
|
+
if (textarea && typeof textarea.setSelectionRange === 'function') {
|
|
307
|
+
textarea.setSelectionRange(result.caret, result.caret);
|
|
308
|
+
textarea.focus();
|
|
304
309
|
}
|
|
305
310
|
};
|
|
306
311
|
if (typeof this.$nextTick === 'function') {
|
|
307
|
-
this.$nextTick(
|
|
312
|
+
this.$nextTick(restoreCaret);
|
|
308
313
|
} else {
|
|
309
|
-
|
|
314
|
+
restoreCaret();
|
|
310
315
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
setPromptsMobileView(view) {
|
|
314
|
-
if (view === 'edit' || view === 'preview') {
|
|
315
|
-
this.promptsMobileView = view;
|
|
316
|
-
}
|
|
317
|
-
},
|
|
318
|
-
|
|
319
|
-
togglePromptsPreviewCollapsed() {
|
|
320
|
-
this.promptsPreviewCollapsed = !this.promptsPreviewCollapsed;
|
|
321
|
-
if (typeof this.persistWebUiPreferences === 'function') {
|
|
322
|
-
this.persistWebUiPreferences({ promptsPreviewCollapsed: this.promptsPreviewCollapsed });
|
|
316
|
+
if (typeof this.showMessage === 'function') {
|
|
317
|
+
this.showMessage(this.t('prompts.pathReference.toast.inserted'), 'success');
|
|
323
318
|
}
|
|
324
319
|
}
|
|
325
320
|
};
|
|
@@ -114,7 +114,10 @@ function normalizeNavigationSnapshot(vm, source = {}) {
|
|
|
114
114
|
: currentSkillsTargetApp,
|
|
115
115
|
promptTemplatesMode: source.promptTemplatesMode === 'manage' || source.promptTemplatesMode === 'compose'
|
|
116
116
|
? source.promptTemplatesMode
|
|
117
|
-
: currentPromptTemplatesMode
|
|
117
|
+
: currentPromptTemplatesMode,
|
|
118
|
+
pluginsActiveId: typeof source.pluginsActiveId === 'string'
|
|
119
|
+
? source.pluginsActiveId
|
|
120
|
+
: (typeof vm.pluginsActiveId === 'string' ? vm.pluginsActiveId : '')
|
|
118
121
|
};
|
|
119
122
|
}
|
|
120
123
|
|
|
@@ -475,6 +478,9 @@ export function createWebUiPreferencesMethods(options = {}) {
|
|
|
475
478
|
this.settingsTab = this.normalizeSettingsTab(nav.settingsTab);
|
|
476
479
|
}
|
|
477
480
|
if (typeof nav.configMode === 'string') this.configMode = nav.configMode;
|
|
481
|
+
if (typeof nav.pluginsActiveId === 'string' && nav.pluginsActiveId.trim()) {
|
|
482
|
+
this.pluginsActiveId = nav.pluginsActiveId.trim();
|
|
483
|
+
}
|
|
478
484
|
if (typeof nav.mainTab === 'string') {
|
|
479
485
|
if (typeof this.switchMainTab === 'function') {
|
|
480
486
|
this.switchMainTab(nav.mainTab);
|
|
@@ -232,6 +232,17 @@ const en = Object.freeze({
|
|
|
232
232
|
'prompts.subTab.opencode': 'AGENTS.md (OpenCode)',
|
|
233
233
|
'prompts.subTab.project': 'CLAUDE.md',
|
|
234
234
|
'prompts.subTab.system': 'System Prompt (Pi)',
|
|
235
|
+
'prompts.pathReference.title': 'Insert rule reference',
|
|
236
|
+
'prompts.pathReference.placeholder': 'Insert rule reference…',
|
|
237
|
+
'prompts.pathReference.codex': 'AGENTS.md (Codex)',
|
|
238
|
+
'prompts.pathReference.opencode': 'AGENTS.md (OpenCode)',
|
|
239
|
+
'prompts.pathReference.claudeGlobal': 'CLAUDE.md (Global)',
|
|
240
|
+
'prompts.pathReference.claudeProject': 'CLAUDE.md (Project)',
|
|
241
|
+
'prompts.pathReference.system': '{file} (Pi System Prompt)',
|
|
242
|
+
'prompts.pathReference.projectMissing': 'No project path selected',
|
|
243
|
+
'prompts.pathReference.notLoaded': 'Loading path…',
|
|
244
|
+
'prompts.pathReference.loadFailed': 'Failed to load path',
|
|
245
|
+
'prompts.pathReference.toast.inserted': 'Rule reference inserted',
|
|
235
246
|
'prompts.subTab.presets': 'Preset pool',
|
|
236
247
|
'prompts.editor.toolbar': 'Markdown toolbar',
|
|
237
248
|
'prompts.editor.collapsePreview': 'Collapse preview',
|
|
@@ -243,7 +254,6 @@ const en = Object.freeze({
|
|
|
243
254
|
'prompts.editor.previewEmpty': 'Nothing to preview yet',
|
|
244
255
|
'prompts.editor.changeAxis': 'Change navigation axis',
|
|
245
256
|
'prompts.editor.changeAxisTick': 'Line {line} (+{added} / -{removed})',
|
|
246
|
-
'prompts.editor.changeAxisTruncated': 'Too many changed regions; collapsed to summary',
|
|
247
257
|
'prompts.presets.title': 'Presets',
|
|
248
258
|
'prompts.presets.hint': 'Manage presets.',
|
|
249
259
|
'prompts.presets.namePlaceholder': 'Preset name',
|
|
@@ -374,6 +384,17 @@ const en = Object.freeze({
|
|
|
374
384
|
'plugins.catalog.promptTemplates.title': 'Prompt templates',
|
|
375
385
|
'plugins.catalog.promptTemplates.description': 'Standardized, template-driven prompt tools with variables, copy, and export helpers.',
|
|
376
386
|
'plugins.status.standard': 'standard',
|
|
387
|
+
'plugins.catalog.textTools.title': 'Text tools',
|
|
388
|
+
'plugins.catalog.textTools.description': 'A set of lightweight plain-text utilities; the first tool compresses multi-line text into a single line.',
|
|
389
|
+
'plugins.textTools.title': 'Text tools',
|
|
390
|
+
'plugins.textTools.tools.aria': 'Text tool selection',
|
|
391
|
+
'plugins.textTools.tools.compress': 'Compress text',
|
|
392
|
+
'plugins.textTools.compress.inputLabel': 'Input text',
|
|
393
|
+
'plugins.textTools.compress.inputPlaceholder': 'Paste or type the text to compress…',
|
|
394
|
+
'plugins.textTools.compress.inputAria': 'Text to compress',
|
|
395
|
+
'plugins.textTools.compress.outputTitle': 'Compressed result',
|
|
396
|
+
'plugins.textTools.compress.outputAria': 'Compressed text result',
|
|
397
|
+
'plugins.textTools.compress.copy': 'Copy',
|
|
377
398
|
'plugins.main.ariaWorkspace': 'Plugin workspace',
|
|
378
399
|
'plugins.refresh': 'Refresh',
|
|
379
400
|
'plugins.refreshing': 'Refreshing...',
|
|
@@ -233,6 +233,17 @@ const ja = Object.freeze({
|
|
|
233
233
|
'prompts.subTab.opencode': 'AGENTS.md (OpenCode)',
|
|
234
234
|
'prompts.subTab.project': 'CLAUDE.md',
|
|
235
235
|
'prompts.subTab.system': 'System Prompt (Pi)',
|
|
236
|
+
'prompts.pathReference.title': 'ルール参照を挿入',
|
|
237
|
+
'prompts.pathReference.placeholder': 'ルール参照を挿入…',
|
|
238
|
+
'prompts.pathReference.codex': 'AGENTS.md (Codex)',
|
|
239
|
+
'prompts.pathReference.opencode': 'AGENTS.md (OpenCode)',
|
|
240
|
+
'prompts.pathReference.claudeGlobal': 'CLAUDE.md(グローバル)',
|
|
241
|
+
'prompts.pathReference.claudeProject': 'CLAUDE.md(現在のプロジェクト)',
|
|
242
|
+
'prompts.pathReference.system': '{file}(Pi System Prompt)',
|
|
243
|
+
'prompts.pathReference.projectMissing': 'プロジェクトパス未選択',
|
|
244
|
+
'prompts.pathReference.notLoaded': 'パス読み込み中…',
|
|
245
|
+
'prompts.pathReference.loadFailed': 'パスの読み込みに失敗しました',
|
|
246
|
+
'prompts.pathReference.toast.inserted': 'ルール参照を挿入しました',
|
|
236
247
|
'prompts.subTab.presets': 'プリセット',
|
|
237
248
|
'prompts.editor.toolbar': 'Markdown ツールバー',
|
|
238
249
|
'prompts.editor.collapsePreview': 'プレビューを折りたたむ',
|
|
@@ -244,7 +255,6 @@ const ja = Object.freeze({
|
|
|
244
255
|
'prompts.editor.previewEmpty': 'プレビューする内容がありません',
|
|
245
256
|
'prompts.editor.changeAxis': '変更ナビゲーション軸',
|
|
246
257
|
'prompts.editor.changeAxisTick': '{line} 行目(+{added} / -{removed})',
|
|
247
|
-
'prompts.editor.changeAxisTruncated': '変更領域が多すぎるため、統計に折りたたまれました',
|
|
248
258
|
'prompts.presets.title': 'プリセット',
|
|
249
259
|
'prompts.presets.hint': 'プリセットを管理します。',
|
|
250
260
|
'prompts.presets.namePlaceholder': 'プリセット名',
|
|
@@ -376,6 +386,17 @@ const ja = Object.freeze({
|
|
|
376
386
|
'plugins.catalog.promptTemplates.title': 'プロンプトテンプレート',
|
|
377
387
|
'plugins.catalog.promptTemplates.description': '変数、コピー、エクスポートに対応した標準化テンプレート型プロンプトツール。',
|
|
378
388
|
'plugins.status.standard': '標準',
|
|
389
|
+
'plugins.catalog.textTools.title': 'テキストツール',
|
|
390
|
+
'plugins.catalog.textTools.description': '軽量なテキストユーティリティ集。最初のツールは複数行のテキストを 1 行に圧縮します。',
|
|
391
|
+
'plugins.textTools.title': 'テキストツール',
|
|
392
|
+
'plugins.textTools.tools.aria': 'テキストツールの選択',
|
|
393
|
+
'plugins.textTools.tools.compress': 'テキスト圧縮',
|
|
394
|
+
'plugins.textTools.compress.inputLabel': '入力テキスト',
|
|
395
|
+
'plugins.textTools.compress.inputPlaceholder': '圧縮するテキストを貼り付けまたは入力…',
|
|
396
|
+
'plugins.textTools.compress.inputAria': '圧縮するテキスト',
|
|
397
|
+
'plugins.textTools.compress.outputTitle': '圧縮結果',
|
|
398
|
+
'plugins.textTools.compress.outputAria': '圧縮後のテキスト結果',
|
|
399
|
+
'plugins.textTools.compress.copy': 'コピー',
|
|
379
400
|
'plugins.main.ariaWorkspace': 'プラグインワークスペース',
|
|
380
401
|
'plugins.refresh': '更新',
|
|
381
402
|
'plugins.refreshing': '更新中...',
|