Skip to content

Commit e92b3d5

Browse files
fix(ci): fix score-pr-knowledge import path + build aliases; add Copilot provider and framework selector to site
CI fixes: - score-pr-knowledge.js imported from src/engine.js (doesn't exist) — fix to dist/engine.js - score-pr-knowledge.js hardcoded 4D dimension averaging — fix to use Object.values() for any framework - build.mjs aliases updated from @fluently/scorer to fluently-scorer to match source imports Scorer package (pending changes from previous session): - README: framework-agnostic framing, 4D as bundled default - package.json: updated description to reflect framework-agnostic scope Site — index.html: - Add GitHub Copilot (GitHub Models API) as AI provider in the interactive demo - Add framework selector dropdown to the try-it demo (loaded live from frameworks/index.json) - Filter knowledge entries by selected framework before ranking - Cycle text rendered generically from entry.dimensions keys (works for any framework) Site — frameworks.html: - Expand "Contribute a New Framework" section with two paths: Manual PR and Via Agent - Add YAML template, local validation instructions, and a copy-paste agent prompt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5fb7870 commit e92b3d5

7 files changed

Lines changed: 172 additions & 51 deletions

File tree

packages/cli/build.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ await build({
3737
js: '#!/usr/bin/env node',
3838
},
3939
alias: {
40-
'@fluently/scorer': resolve(root, 'packages/scorer/src/index.ts'),
41-
'@fluently/scorer/schema': resolve(root, 'packages/scorer/src/schema.ts'),
40+
'fluently-scorer': resolve(root, 'packages/scorer/src/index.ts'),
41+
'fluently-scorer/schema': resolve(root, 'packages/scorer/src/schema.ts'),
4242
},
4343
external: ['esbuild'],
4444
});

packages/mcp-server/build.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ const shared = {
3030
target: 'node20',
3131
format: 'cjs',
3232
alias: {
33-
'@fluently/scorer': resolve(root, 'packages/scorer/src/index.ts'),
34-
'@fluently/scorer/schema': resolve(root, 'packages/scorer/src/schema.ts'),
33+
'fluently-scorer': resolve(root, 'packages/scorer/src/index.ts'),
34+
'fluently-scorer/schema': resolve(root, 'packages/scorer/src/schema.ts'),
3535
},
3636
external: ['esbuild'],
3737
};

packages/scorer/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# fluently-scorer
22

3-
**Shared scoring engine for the [Fluently 4D Framework](https://fluently-org.github.io/fluently/).** Validates knowledge YAML against the schema and ranks cycles by keyword similarity for any AI task.
3+
**Shared scoring and validation engine for human-AI collaboration frameworks.** Validates knowledge cycles against their framework schema, ranks them by similarity, and evaluates compliance. Framework-agnostic: works with any framework that defines named dimensions.
44

5-
Used internally by both `fluently-cli` and `fluently-mcp-server`. Expose it in your own tools to build on top of the Fluently knowledge base.
5+
Bundles the [AI Fluency 4D Framework](https://fluently-org.github.io/fluently/) as the default. Any framework registered in the knowledge base is automatically supported.
6+
7+
Used internally by both `fluently-cli` and `fluently-mcp-server`. Import it directly to build on top of the Fluently knowledge base in your own tools.
68

79
[![npm version](https://img.shields.io/npm/v/fluently-scorer.svg)](https://www.npmjs.com/package/fluently-scorer)
810
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](../../LICENSE)
@@ -58,6 +60,7 @@ const results = scoreTask(input, './knowledge');
5860
results.forEach(({ entry, dimensionScores }) => {
5961
console.log(entry.title);
6062
console.log(dimensionScores);
63+
// Dimension keys match the registered framework — e.g. for the 4D Framework:
6164
// { delegation: 80, description: 90, discernment: 70, diligence: 75 }
6265
});
6366
```

packages/scorer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "fluently-scorer",
33
"version": "0.2.3",
4-
"description": "Zero-dependency scoring engine for the Fluently 4D Framework. Validates YAML knowledge cycles with Zod and ranks them by keyword similarity — no API calls, no false-precision scores.",
4+
"description": "Zero-dependency scoring and validation engine for human-AI collaboration frameworks. Validates knowledge cycles, ranks them by similarity, and evaluates framework compliance. Bundles the AI Fluency 4D Framework; any framework with named dimensions can be registered.",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
77
"exports": {

scripts/score-pr-knowledge.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import path from 'path';
55
import YAML from 'js-yaml';
66
import { exec } from 'child_process';
77
import { promisify } from 'util';
8-
import { scoreTask } from '../packages/scorer/src/engine.js';
8+
import { scoreTask } from '../packages/scorer/dist/engine.js';
99
import { fileURLToPath } from 'url';
1010

1111
const execAsync = promisify(exec);
@@ -50,14 +50,12 @@ async function scoreNewEntries() {
5050
KNOWLEDGE_DIR
5151
);
5252

53-
// Calculate overall score from top result's dimensionScores
53+
// Calculate overall score from top result's dimensionScores (any framework)
5454
const topScores = result[0]?.dimensionScores || {};
55-
const avgScore = (
56-
(topScores.delegation || 0) +
57-
(topScores.description || 0) +
58-
(topScores.discernment || 0) +
59-
(topScores.diligence || 0)
60-
) / 4;
55+
const scoreValues = Object.values(topScores);
56+
const avgScore = scoreValues.length
57+
? scoreValues.reduce((a, b) => a + b, 0) / scoreValues.length
58+
: 0;
6159

6260
scores.push(`- **${entry.title}** (${entry.domain}): ${avgScore.toFixed(1)}/100`);
6361
} catch (err) {

site/frameworks.html

Lines changed: 117 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -204,41 +204,117 @@ <h2 class="text-2xl font-bold text-gray-900 mb-2">
204204
HOW TO CONTRIBUTE A FRAMEWORK
205205
════════════════════════════════════════════════════════════════════════ -->
206206
<section class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
207-
<h2 class="text-2xl font-bold text-gray-900 mb-6">
207+
<h2 class="text-2xl font-bold text-gray-900 mb-2">
208208
<i class="fas fa-plus-circle text-green-600 mr-2"></i>Contribute a New Framework
209209
</h2>
210-
<div class="grid sm:grid-cols-3 gap-6">
211-
<div class="bg-white rounded-xl border border-gray-200 p-5">
212-
<div class="text-2xl mb-2">📄</div>
213-
<h3 class="font-bold text-gray-900 mb-1">1. Write a YAML file</h3>
214-
<p class="text-sm text-gray-600">
215-
Create <code class="bg-gray-100 px-1 rounded text-xs">frameworks/your-framework.yaml</code>
216-
with <code class="bg-gray-100 px-1 rounded text-xs">id</code>,
217-
<code class="bg-gray-100 px-1 rounded text-xs">name</code>,
218-
<code class="bg-gray-100 px-1 rounded text-xs">dimensions</code>, and
219-
<code class="bg-gray-100 px-1 rounded text-xs">description</code>.
220-
</p>
210+
<p class="text-gray-600 text-sm mb-8">
211+
Any collaboration framework with named dimensions can be registered. Two paths: submit a PR yourself, or ask your AI agent to build and test it for you.
212+
</p>
213+
214+
<!-- Path A: Manual PR -->
215+
<div class="mb-10">
216+
<div class="flex items-center gap-2 mb-4">
217+
<span class="bg-gray-900 text-white text-xs font-bold px-3 py-1 rounded-full">Path A</span>
218+
<h3 class="text-lg font-bold text-gray-900">Manual PR</h3>
221219
</div>
222-
<div class="bg-white rounded-xl border border-gray-200 p-5">
223-
<div class="text-2xl mb-2"></div>
224-
<h3 class="font-bold text-gray-900 mb-1">2. Validate &amp; index</h3>
225-
<p class="text-sm text-gray-600">
226-
CI runs <code class="bg-gray-100 px-1 rounded text-xs">validate-frameworks.js</code>
227-
and regenerates <code class="bg-gray-100 px-1 rounded text-xs">frameworks/index.json</code>
228-
automatically on merge.
229-
</p>
220+
<div class="grid sm:grid-cols-3 gap-5">
221+
<div class="bg-white rounded-xl border border-gray-200 p-5">
222+
<div class="text-2xl mb-2">📄</div>
223+
<h4 class="font-bold text-gray-900 mb-1">1. Write the YAML</h4>
224+
<p class="text-sm text-gray-600 mb-3">
225+
Fork the repo and create <code class="bg-gray-100 px-1 rounded text-xs">frameworks/your-id.yaml</code>.
226+
Required fields: <code class="bg-gray-100 px-1 rounded text-xs">id</code> (kebab-case),
227+
<code class="bg-gray-100 px-1 rounded text-xs">name</code>,
228+
<code class="bg-gray-100 px-1 rounded text-xs">version</code>,
229+
<code class="bg-gray-100 px-1 rounded text-xs">contributor</code>,
230+
<code class="bg-gray-100 px-1 rounded text-xs">description</code>,
231+
<code class="bg-gray-100 px-1 rounded text-xs">dimensions</code> (array with <code class="bg-gray-100 px-1 rounded text-xs">key</code>, <code class="bg-gray-100 px-1 rounded text-xs">label</code>, <code class="bg-gray-100 px-1 rounded text-xs">description</code>, <code class="bg-gray-100 px-1 rounded text-xs">canonical_order</code>).
232+
</p>
233+
<details class="text-xs">
234+
<summary class="font-bold text-indigo-600 cursor-pointer">Show template</summary>
235+
<pre class="bg-gray-50 border border-gray-200 rounded p-3 mt-2 overflow-x-auto text-gray-700 leading-relaxed">id: my-framework
236+
name: My Framework
237+
version: "1.0.0"
238+
contributor: Your Name
239+
description: >
240+
One-paragraph description of the
241+
framework and its goals.
242+
dimensions:
243+
- key: plan
244+
label: Plan
245+
description: &gt;
246+
What is decided before starting?
247+
canonical_order: 1
248+
- key: execute
249+
label: Execute
250+
description: &gt;
251+
How is the work carried out?
252+
canonical_order: 2
253+
- key: review
254+
label: Review
255+
description: &gt;
256+
How is the output evaluated?
257+
canonical_order: 3</pre>
258+
</details>
259+
</div>
260+
<div class="bg-white rounded-xl border border-gray-200 p-5">
261+
<div class="text-2xl mb-2">🔍</div>
262+
<h4 class="font-bold text-gray-900 mb-1">2. Validate locally</h4>
263+
<p class="text-sm text-gray-600 mb-3">Run the validation script to catch errors before opening a PR:</p>
264+
<pre class="bg-gray-900 text-green-400 rounded p-3 text-xs overflow-x-auto">npm run build --workspace=packages/scorer
265+
node scripts/validate-frameworks.js</pre>
266+
<p class="text-xs text-gray-500 mt-2">CI reruns this automatically on every PR and rejects malformed definitions.</p>
267+
</div>
268+
<div class="bg-white rounded-xl border border-gray-200 p-5">
269+
<div class="text-2xl mb-2">🔗</div>
270+
<h4 class="font-bold text-gray-900 mb-1">3. Open a PR</h4>
271+
<p class="text-sm text-gray-600">Submit your PR. CI validates the schema, regenerates <code class="bg-gray-100 px-1 rounded text-xs">frameworks/index.json</code>, and the new framework appears in the knowledge base and this page after merge.</p>
272+
<div class="mt-3">
273+
<a href="https://github.com/Fluently-Org/fluently/compare"
274+
data-fluently="compare"
275+
target="_blank"
276+
class="inline-flex items-center gap-1 bg-gray-900 hover:bg-gray-700 text-white text-xs font-bold py-1.5 px-3 rounded transition">
277+
<i class="fab fa-github"></i> Open a PR
278+
</a>
279+
</div>
280+
</div>
230281
</div>
231-
<div class="bg-white rounded-xl border border-gray-200 p-5">
232-
<div class="text-2xl mb-2">🔗</div>
233-
<h3 class="font-bold text-gray-900 mb-1">3. Add knowledge cycles</h3>
234-
<p class="text-sm text-gray-600">
235-
Knowledge YAML files tagged with your
236-
<code class="bg-gray-100 px-1 rounded text-xs">framework_id</code>
237-
will be validated against your framework's dimension keys.
238-
</p>
282+
</div>
283+
284+
<!-- Path B: Via Agent -->
285+
<div class="mb-8">
286+
<div class="flex items-center gap-2 mb-4">
287+
<span class="bg-indigo-600 text-white text-xs font-bold px-3 py-1 rounded-full">Path B</span>
288+
<h3 class="text-lg font-bold text-gray-900">Via your AI Agent</h3>
289+
</div>
290+
<p class="text-sm text-gray-600 mb-4">
291+
If you have the Fluently MCP server connected, you can ask your agent to generate a framework YAML, validate it, and open the PR — all in one conversation.
292+
Copy the prompt below and paste it to Claude, Copilot, Cursor, or any MCP-capable agent.
293+
</p>
294+
<div class="bg-gray-900 rounded-xl border border-gray-700 overflow-hidden">
295+
<div class="flex items-center justify-between px-4 py-2 border-b border-gray-700">
296+
<span class="text-xs text-gray-400 font-mono">Agent prompt — paste as-is</span>
297+
<button onclick="copyAgentPrompt()" class="text-xs text-indigo-400 hover:text-indigo-300 font-bold transition">
298+
<i class="fas fa-copy mr-1"></i>Copy
299+
</button>
300+
</div>
301+
<pre id="agentPromptBlock" class="text-green-300 text-xs leading-relaxed px-4 py-4 overflow-x-auto whitespace-pre-wrap">I want to contribute a new collaboration framework to the Fluently knowledge base.
302+
303+
Framework concept: [DESCRIBE YOUR FRAMEWORK HERE — e.g. "a 3-step Research framework: Question, Investigate, Synthesise"]
304+
305+
Please:
306+
1. Use the `get_framework_detail` tool to inspect the existing 4D framework structure as a reference.
307+
2. Generate a valid `frameworks/[id].yaml` file following the same schema (id must be kebab-case, each dimension needs key, label, description, canonical_order).
308+
3. Run `node scripts/validate-frameworks.js` locally to confirm the file is valid.
309+
4. Confirm the YAML is ready to commit and provide the exact file contents.
310+
5. If I approve, create a branch named `feat/framework-[id]`, commit the YAML, and open a GitHub PR with a short description of the framework and its intended use cases.
311+
312+
Do not open the PR without my explicit approval.</pre>
239313
</div>
314+
<p class="text-xs text-gray-500 mt-2">Requires: Fluently MCP server connected + a GitHub MCP server or a PAT in your agent's settings.</p>
240315
</div>
241-
<div class="mt-6 text-center">
316+
317+
<div class="mt-4 text-center">
242318
<a href="https://github.com/Fluently-Org/fluently/blob/main/CONTRIBUTING.md"
243319
data-fluently="contributing"
244320
target="_blank"
@@ -248,6 +324,18 @@ <h3 class="font-bold text-gray-900 mb-1">3. Add knowledge cycles</h3>
248324
</div>
249325
</section>
250326

327+
<script>
328+
function copyAgentPrompt() {
329+
const el = document.getElementById('agentPromptBlock');
330+
navigator.clipboard.writeText(el.textContent.trim()).then(() => {
331+
const btn = event.currentTarget;
332+
btn.innerHTML = '<i class="fas fa-check mr-1"></i>Copied!';
333+
btn.style.color = '#34d399';
334+
setTimeout(() => { btn.innerHTML = '<i class="fas fa-copy mr-1"></i>Copy'; btn.style.color = ''; }, 2000);
335+
});
336+
}
337+
</script>
338+
251339
<!-- ═══════════════════════════════════════════════════════════════════════
252340
FOOTER
253341
════════════════════════════════════════════════════════════════════════ -->

0 commit comments

Comments
 (0)