Skip to content

Commit 07226b4

Browse files
authored
Merge pull request #106 from SakuraByteCore/pr-106
chore(reset): remove PR prompt flow
2 parents 8a8fab7 + 5da3e5d commit 07226b4

18 files changed

Lines changed: 365 additions & 62 deletions
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { pluginOwnership, templateOwnershipById } from '../ownership.mjs';
2+
3+
export function buildBuiltinCommentPolishTemplate(t) {
4+
const tr = (key, fallback, params = null) => (typeof t === 'function' ? t(key, params) : fallback);
5+
const line1 = tr('plugins.builtin.commentPolish.line1', '轻微收敛以下代码注释');
6+
const timestamp = new Date().toISOString();
7+
const ownership = templateOwnershipById && templateOwnershipById.builtin_comment_polish
8+
? templateOwnershipById.builtin_comment_polish
9+
: pluginOwnership;
10+
return {
11+
id: 'builtin_comment_polish',
12+
name: tr('plugins.builtin.commentPolish.name', '代码注释润色'),
13+
description: tr('plugins.builtin.commentPolish.desc', '轻微收敛以下代码注释 {{code}}'),
14+
template: [
15+
line1,
16+
'',
17+
'{{code}}'
18+
].join('\n'),
19+
createdAt: timestamp,
20+
updatedAt: timestamp,
21+
isBuiltin: true,
22+
createdBy: ownership && typeof ownership.createdBy === 'string' ? ownership.createdBy : '',
23+
maintainers: ownership && Array.isArray(ownership.maintainers) ? ownership.maintainers : []
24+
};
25+
}

plugins/prompt-templates/computed.mjs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,20 @@ function normalizePromptTemplateEntry(item) {
77
const updatedAt = typeof safe.updatedAt === 'string' ? safe.updatedAt : '';
88
const createdAt = typeof safe.createdAt === 'string' ? safe.createdAt : updatedAt;
99
const isBuiltin = safe.isBuiltin === true;
10+
const createdBy = typeof safe.createdBy === 'string' ? safe.createdBy.trim() : '';
11+
const maintainers = Array.isArray(safe.maintainers)
12+
? safe.maintainers.map((m) => (typeof m === 'string' ? m.trim() : '')).filter(Boolean)
13+
: [];
1014
return {
1115
id,
1216
name,
1317
description,
1418
template,
1519
createdAt,
1620
updatedAt,
17-
isBuiltin
21+
isBuiltin,
22+
createdBy,
23+
maintainers
1824
};
1925
}
2026

@@ -104,6 +110,30 @@ export function createPluginsComputed() {
104110
return pluginsRegistry.map((entry) => entry && entry.meta).filter(Boolean);
105111
},
106112

113+
pluginsActiveMeta() {
114+
const id = typeof this.pluginsActiveId === 'string' ? this.pluginsActiveId.trim() : '';
115+
const entry = pluginsRegistry.find((item) => item && item.id === id) || null;
116+
return entry && entry.meta ? entry.meta : null;
117+
},
118+
119+
pluginsActiveAttribution() {
120+
const meta = this.pluginsActiveMeta;
121+
if (!meta || typeof meta !== 'object') return '';
122+
const createdBy = typeof meta.createdBy === 'string' ? meta.createdBy.trim() : '';
123+
const maintainers = Array.isArray(meta.maintainers)
124+
? meta.maintainers.map((m) => (typeof m === 'string' ? m.trim() : '')).filter(Boolean).join(', ')
125+
: '';
126+
if (!createdBy && !maintainers) return '';
127+
if (typeof this.t !== 'function') {
128+
if (createdBy && maintainers) return `Created by ${createdBy} · Maintained by ${maintainers}`;
129+
if (createdBy) return `Created by ${createdBy}`;
130+
return `Maintained by ${maintainers}`;
131+
}
132+
if (createdBy && maintainers) return this.t('plugins.meta.attribution', { createdBy, maintainers });
133+
if (createdBy) return this.t('plugins.meta.createdBy', { createdBy });
134+
return this.t('plugins.meta.maintainedBy', { maintainers });
135+
},
136+
107137
promptTemplatesList() {
108138
const list = Array.isArray(this.promptTemplatesListRaw) ? this.promptTemplatesListRaw : [];
109139
return list
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
export const pluginMeta = {
1+
import { pluginOwnership } from './ownership.mjs';
2+
3+
const baseMeta = {
24
id: 'prompt-templates',
35
title: 'Prompt Templates',
46
description: 'Standardized, template-driven prompts with variables and copy/export helpers.',
57
statusLabel: 'standard',
68
tone: 'configured'
79
};
10+
11+
export const pluginMeta = {
12+
...baseMeta,
13+
createdBy: pluginOwnership && typeof pluginOwnership.createdBy === 'string' ? pluginOwnership.createdBy : '',
14+
maintainers: pluginOwnership && Array.isArray(pluginOwnership.maintainers) ? pluginOwnership.maintainers : []
15+
};

plugins/prompt-templates/methods.mjs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ function normalizePromptTemplateDraft(draft) {
7272
template: typeof safe.template === 'string' ? safe.template : '',
7373
createdAt: typeof safe.createdAt === 'string' ? safe.createdAt : '',
7474
updatedAt: typeof safe.updatedAt === 'string' ? safe.updatedAt : '',
75-
isBuiltin: safe.isBuiltin === true
75+
isBuiltin: safe.isBuiltin === true,
76+
createdBy: typeof safe.createdBy === 'string' ? safe.createdBy : '',
77+
maintainers: Array.isArray(safe.maintainers) ? safe.maintainers : []
7678
};
7779
}
7880

@@ -322,7 +324,9 @@ export function createPluginsMethods() {
322324
template: entry.template,
323325
createdAt: entry.createdAt,
324326
updatedAt: entry.updatedAt,
325-
isBuiltin: entry.isBuiltin === true
327+
isBuiltin: entry.isBuiltin === true,
328+
createdBy: entry.createdBy || '',
329+
maintainers: Array.isArray(entry.maintainers) ? entry.maintainers : []
326330
};
327331
this.promptTemplateVarValuesRaw = {};
328332
},

plugins/prompt-templates/overview.mjs

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,8 @@ import {
22
persistPromptTemplatesToStorage,
33
readPromptTemplatesFromStorage
44
} from './storage.mjs';
5-
6-
function nowIsoPromptTemplatesOverview() {
7-
return new Date().toISOString();
8-
}
9-
10-
function buildBuiltinCommentPolishTemplate(t) {
11-
const tr = (key, fallback, params = null) => (typeof t === 'function' ? t(key, params) : fallback);
12-
const line1 = tr('plugins.builtin.commentPolish.line1', '轻微收敛以下代码注释');
13-
return {
14-
id: 'builtin_comment_polish',
15-
name: tr('plugins.builtin.commentPolish.name', '代码注释润色'),
16-
description: tr('plugins.builtin.commentPolish.desc', '轻微收敛以下代码注释 {{code}}'),
17-
template: [
18-
line1,
19-
'',
20-
'{{code}}'
21-
].join('\n'),
22-
createdAt: nowIsoPromptTemplatesOverview(),
23-
updatedAt: nowIsoPromptTemplatesOverview(),
24-
isBuiltin: true
25-
};
26-
}
5+
import { buildBuiltinCommentPolishTemplate } from './comment-polish/index.mjs';
6+
import { buildBuiltinRuleAckTemplate } from './rule-ack/index.mjs';
277

288
function ensureBuiltinTemplates(rawList, builtins) {
299
const list = Array.isArray(rawList) ? rawList.filter(Boolean) : [];
@@ -48,7 +28,10 @@ export async function loadPromptTemplatesOverview(ctx, options = {}) {
4828

4929
const t = typeof app.t === 'function' ? app.t : null;
5030
const rawList = readPromptTemplatesFromStorage(localStorage);
51-
const normalized = ensureBuiltinTemplates(rawList, [buildBuiltinCommentPolishTemplate(t)]);
31+
const normalized = ensureBuiltinTemplates(rawList, [
32+
buildBuiltinCommentPolishTemplate(t),
33+
buildBuiltinRuleAckTemplate(t)
34+
]);
5235
app.promptTemplatesListRaw = normalized;
5336
persistPromptTemplatesToStorage(normalized, localStorage);
5437

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export const pluginOwnership = {
2+
pluginId: 'prompt-templates',
3+
createdBy: 'ymkiux',
4+
maintainers: ['ymkiux']
5+
};
6+
7+
export const templateOwnershipById = {
8+
builtin_comment_polish: {
9+
templateId: 'builtin_comment_polish',
10+
createdBy: 'ymkiux',
11+
maintainers: ['ymkiux']
12+
},
13+
builtin_rule_ack: {
14+
templateId: 'builtin_rule_ack',
15+
createdBy: 'ymkiux',
16+
maintainers: ['ymkiux']
17+
}
18+
};
19+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { pluginOwnership, templateOwnershipById } from '../ownership.mjs';
2+
3+
export function buildBuiltinRuleAckTemplate(t) {
4+
const tr = (key, fallback, params = null) => (typeof t === 'function' ? t(key, params) : fallback);
5+
const line1 = tr('plugins.builtin.ruleAck.line1', '请根据【{{rule}}】,收到请回复');
6+
const timestamp = new Date().toISOString();
7+
const ownership = templateOwnershipById && templateOwnershipById.builtin_rule_ack
8+
? templateOwnershipById.builtin_rule_ack
9+
: pluginOwnership;
10+
return {
11+
id: 'builtin_rule_ack',
12+
name: tr('plugins.builtin.ruleAck.name', '规则确认回复'),
13+
description: tr('plugins.builtin.ruleAck.desc', '请根据【{{rule}}】,收到请回复'),
14+
template: line1,
15+
createdAt: timestamp,
16+
updatedAt: timestamp,
17+
isBuiltin: true,
18+
createdBy: ownership && typeof ownership.createdBy === 'string' ? ownership.createdBy : '',
19+
maintainers: ownership && Array.isArray(ownership.maintainers) ? ownership.maintainers : []
20+
};
21+
}

plugins/registry.mjs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import { pluginMeta as promptTemplatesMeta } from './prompt-templates/manifest.m
22
import { loadPromptTemplatesOverview } from './prompt-templates/overview.mjs';
33

44
export const pluginsRegistry = [
5-
{
6-
id: promptTemplatesMeta.id,
7-
meta: promptTemplatesMeta,
8-
loadOverview: loadPromptTemplatesOverview
9-
}
5+
{ id: promptTemplatesMeta.id, meta: promptTemplatesMeta, loadOverview: loadPromptTemplatesOverview }
106
];
117

128
export function getFirstPluginId() {
@@ -18,4 +14,3 @@ export function getPluginEntry(id) {
1814
if (!key) return null;
1915
return pluginsRegistry.find((item) => item && item.id === key) || null;
2016
}
21-
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import assert from 'assert';
2+
import fs from 'fs';
3+
import path from 'path';
4+
import { fileURLToPath, pathToFileURL } from 'url';
5+
6+
const __filename = fileURLToPath(import.meta.url);
7+
const __dirname = path.dirname(__filename);
8+
const root = path.join(__dirname, '..', '..');
9+
const pluginsDir = path.join(root, 'plugins');
10+
11+
function listPluginFolders() {
12+
const entries = fs.readdirSync(pluginsDir, { withFileTypes: true });
13+
return entries
14+
.filter((entry) => entry.isDirectory())
15+
.map((entry) => entry.name)
16+
.filter((name) => !name.startsWith('.'))
17+
.sort((a, b) => a.localeCompare(b, 'en-US'));
18+
}
19+
20+
function isPluginFolder(name) {
21+
const manifestPath = path.join(pluginsDir, name, 'manifest.mjs');
22+
const overviewPath = path.join(pluginsDir, name, 'overview.mjs');
23+
return fs.existsSync(manifestPath) && fs.existsSync(overviewPath);
24+
}
25+
26+
test('each builtin plugin has ownership file matched to plugin id', async () => {
27+
const folders = listPluginFolders().filter((name) => isPluginFolder(name));
28+
assert.ok(folders.length > 0, 'expected at least one builtin plugin folder');
29+
30+
for (const folder of folders) {
31+
const ownershipPath = path.join(pluginsDir, folder, 'ownership.mjs');
32+
assert.ok(fs.existsSync(ownershipPath), `missing ownership.mjs for plugin: ${folder}`);
33+
34+
const manifestUrl = pathToFileURL(path.join(pluginsDir, folder, 'manifest.mjs')).href;
35+
const ownershipUrl = pathToFileURL(ownershipPath).href;
36+
const { pluginMeta } = await import(`${manifestUrl}?t=${Date.now()}`);
37+
const mod = await import(`${ownershipUrl}?t=${Date.now()}`);
38+
const pluginOwnership = mod && mod.pluginOwnership ? mod.pluginOwnership : null;
39+
40+
assert.ok(pluginMeta && typeof pluginMeta === 'object', `invalid pluginMeta for plugin: ${folder}`);
41+
assert.strictEqual(pluginMeta.id, folder, `pluginMeta.id must match folder name: ${folder}`);
42+
assert.ok(pluginOwnership && typeof pluginOwnership === 'object', `invalid pluginOwnership for plugin: ${folder}`);
43+
assert.strictEqual(pluginOwnership.pluginId, folder, `ownership pluginId must match folder name: ${folder}`);
44+
assert.ok(typeof pluginOwnership.createdBy === 'string' && pluginOwnership.createdBy.trim(), `ownership createdBy must be a github handle for plugin: ${folder}`);
45+
assert.ok(Array.isArray(pluginOwnership.maintainers) && pluginOwnership.maintainers.length > 0, `ownership maintainers must be non-empty for plugin: ${folder}`);
46+
for (const maintainer of pluginOwnership.maintainers) {
47+
assert.ok(typeof maintainer === 'string' && maintainer.trim(), `ownership maintainer must be a github handle for plugin: ${folder}`);
48+
}
49+
}
50+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import assert from 'assert';
2+
import fs from 'fs';
3+
import path from 'path';
4+
import { fileURLToPath } from 'url';
5+
import { createRequire } from 'module';
6+
7+
const __filename = fileURLToPath(import.meta.url);
8+
const __dirname = path.dirname(__filename);
9+
const require = createRequire(import.meta.url);
10+
11+
const root = path.join(__dirname, '..', '..');
12+
const registryPath = path.join(root, 'plugins', 'registry.mjs');
13+
const generator = require(path.join(root, 'tools', 'dev', 'generate-plugins-registry.js'));
14+
15+
test('plugins registry matches generator output', () => {
16+
const actual = fs.readFileSync(registryPath, 'utf8').replace(/^\uFEFF/u, '');
17+
const expected = String(generator.generatePluginsRegistrySource() || '').replace(/^\uFEFF/u, '');
18+
assert.strictEqual(actual, expected);
19+
});
20+

0 commit comments

Comments
 (0)