mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-10-03 21:27:07 +00:00
Add OpenSkill descriptions for human capabilities and OpenProfile discovery
This commit is contained in:
parent
ba69f58243
commit
25e18f0766
31 changed files with 878 additions and 3 deletions
59
apps/logicsrc-web/src/lib/skills.ts
Normal file
59
apps/logicsrc-web/src/lib/skills.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { marked } from "marked";
|
||||
|
||||
// Public concepts only. Read at build time; request paths never select files.
|
||||
export const SKILL_SLUGS = [
|
||||
"branding", "logo-design", "graphic-design", "investing", "investor",
|
||||
"financial-advisor", "accounting", "accountant", "software-development",
|
||||
"developer", "software-engineer", "computer-science", "hardware-architectures",
|
||||
"hardware-architect"
|
||||
] as const;
|
||||
|
||||
const SKILLS_DIR = resolve(process.cwd(), "../../docs/openskill");
|
||||
|
||||
export type SkillSummary = {
|
||||
slug: string;
|
||||
name: string;
|
||||
description: string;
|
||||
kind?: string;
|
||||
domain?: string;
|
||||
aliases?: string;
|
||||
};
|
||||
|
||||
export function readSkill(slug: string): string | null {
|
||||
if (!(SKILL_SLUGS as readonly string[]).includes(slug)) return null;
|
||||
return readFileSync(resolve(SKILLS_DIR, `${slug}.md`), "utf8");
|
||||
}
|
||||
|
||||
// A catalog view of the introduction, not a lossy replacement for the record.
|
||||
// Markdown tokenization keeps headings or bullets inside code fences inert.
|
||||
export function summarizeSkill(markdown: string, slug: string): SkillSummary {
|
||||
const result: SkillSummary = { slug, name: slug, description: "" };
|
||||
const tokens = marked.lexer(markdown);
|
||||
const start = tokens.findIndex((token) => token.type === "heading" && token.depth === 1);
|
||||
if (start < 0) return result;
|
||||
const title = tokens[start];
|
||||
if (title.type === "heading") result.name = title.text;
|
||||
let identity = true;
|
||||
for (const token of tokens.slice(start + 1)) {
|
||||
if (token.type === "heading") break;
|
||||
if (token.type === "space") continue;
|
||||
if (token.type === "list" && identity) {
|
||||
for (const item of token.items) {
|
||||
const match = /^(?:\*\*)?(Kind|Domain|Aliases)(?:\*\*)?:\s*(.+)$/i.exec(item.text);
|
||||
if (!match) continue;
|
||||
const key = match[1].toLowerCase() as "kind" | "domain" | "aliases";
|
||||
result[key] ??= match[2].trim();
|
||||
}
|
||||
} else {
|
||||
identity = false;
|
||||
if (token.type === "paragraph" && !result.description) result.description = token.text;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function listSkills(): SkillSummary[] {
|
||||
return SKILL_SLUGS.map((slug) => summarizeSkill(readSkill(slug)!, slug));
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@ export const FAMILIES: Family[] = [
|
|||
"One Markdown file for a person or an agent, served from their own domain and linked from every platform that has a page for them. The profile carries the identity, the accounts and the topics; the sections carry what a platform needs to match on, so a job board, a booking site or a dating app reads the file instead of asking forty questions again.",
|
||||
specs: [
|
||||
s("openprofile", "OpenProfile.md", "One Markdown file for who you are and where you are, people and agents alike", { status: "0.2" }),
|
||||
s("openskill", "OpenSkill", "Portable descriptions of human skills, knowledge and occupations, linked from OpenProfile", { status: "draft" }),
|
||||
s("openagent", "OpenAgent", "A portable agent profile: identity, owner, skills and requested permissions", { status: "0.1" }),
|
||||
s("openwall", "OpenWall", "Consent-based broadcasts and direct messages across contact networks, with an AT Protocol mapping", { landing: undefined, status: "draft" }),
|
||||
s("openresume", "OpenResume.md", "What you have done, in the same spirit, linked from the profile", { landing: undefined }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue