arkaos 2.68.0 → 2.69.0

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/VERSION CHANGED
@@ -1 +1 @@
1
- 2.68.0
1
+ 2.69.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkaos",
3
- "version": "2.68.0",
3
+ "version": "2.69.0",
4
4
  "description": "The Operating System for AI Agent Teams",
5
5
  "type": "module",
6
6
  "bin": {
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "arkaos-core"
3
- version = "2.68.0"
3
+ version = "2.69.0"
4
4
  description = "Core engine for ArkaOS — The Operating System for AI Agent Teams"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
@@ -0,0 +1,158 @@
1
+ """Export ArkaOS skills as portable Agent Skills (PR51 v2.69.0).
2
+
3
+ Generates marketplace-ready copies of the ten outward-facing skills
4
+ identified in KB note [[2026-04-25-agent-skills-open-standard]]. The
5
+ in-tree skills under ``departments/dev/skills/<name>/`` stay
6
+ ArkaOS-specific; the exported copies under ``marketplace/skills/<name>/``
7
+ conform to the open Agent Skills spec at https://agentskills.io so
8
+ they run inside any compliant runtime (Claude Code, Codex CLI, Cursor,
9
+ VS Code Copilot, Atlassian, Figma…).
10
+
11
+ Transformations applied per skill:
12
+
13
+ 1. Strip the ``<!-- arka:kb-first-prefix begin --> … <!-- arka:kb-first-prefix end -->``
14
+ block — it depends on the Obsidian MCP which is ArkaOS-specific.
15
+ 2. Rewrite the frontmatter ``name`` to drop the ``dev/`` prefix and
16
+ keep just the slug ("code-review" instead of "dev/code-review")
17
+ because the open spec doesn't model department namespaces.
18
+ 3. Drop the ``allowed-tools`` frontmatter field — its grammar is
19
+ Claude Code-specific.
20
+ 4. Strip ArkaOS slash-command references (``/dev …``, ``/arka``) from
21
+ prose so the skill is verb-driven, not invocation-bound.
22
+
23
+ Outputs:
24
+ marketplace/skills/<name>/SKILL.md — one per exported skill
25
+ marketplace/skills/README.md — catalog index
26
+
27
+ Non-destructive — the source skills are never modified.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import re
33
+ from dataclasses import dataclass
34
+ from pathlib import Path
35
+
36
+
37
+ REPO_ROOT = Path(__file__).resolve().parent.parent
38
+ SOURCE_DIR = REPO_ROOT / "departments" / "dev" / "skills"
39
+ EXPORT_DIR = REPO_ROOT / "marketplace" / "skills"
40
+
41
+
42
+ # Per KB note [[2026-04-25-agent-skills-open-standard]] §Angle-C.
43
+ EXPORTABLE_SKILLS: tuple[str, ...] = (
44
+ "code-review",
45
+ "tdd-cycle",
46
+ "runbook",
47
+ "spec",
48
+ "db-design",
49
+ "security-audit",
50
+ "clean-code-review",
51
+ "api-design",
52
+ "refactor-plan",
53
+ "architecture-design",
54
+ )
55
+
56
+
57
+ _KB_PREFIX_PATTERN = re.compile(
58
+ r"<!--\s*arka:kb-first-prefix begin\s*-->.*?"
59
+ r"<!--\s*arka:kb-first-prefix end\s*-->\n*",
60
+ flags=re.DOTALL,
61
+ )
62
+ _SLASH_CMD_PATTERN = re.compile(
63
+ r"\s*—\s*`/(?:dev|arka|mkt|brand|fin|strat|ecom|kb|ops|pm|saas|landing|"
64
+ r"content|community|sales|lead|org)[^`]*`",
65
+ )
66
+ _NAME_FIELD_PATTERN = re.compile(
67
+ r"^name:\s*(?:dev/|arka-dev-|arka-)?(.+)$", flags=re.MULTILINE
68
+ )
69
+ _ALLOWED_TOOLS_PATTERN = re.compile(
70
+ r"^allowed-tools:\s*\[[^\]]*\]\n", flags=re.MULTILINE
71
+ )
72
+
73
+
74
+ @dataclass(frozen=True)
75
+ class ExportResult:
76
+ """One skill's export outcome."""
77
+
78
+ slug: str
79
+ source_path: Path
80
+ output_path: Path
81
+ bytes_before: int
82
+ bytes_after: int
83
+
84
+
85
+ def export_skill(slug: str) -> ExportResult:
86
+ """Export a single skill to the marketplace directory.
87
+
88
+ Raises FileNotFoundError if the source SKILL.md doesn't exist.
89
+ """
90
+ src = SOURCE_DIR / slug / "SKILL.md"
91
+ if not src.exists():
92
+ raise FileNotFoundError(f"source SKILL.md missing for {slug!r}: {src}")
93
+ body = src.read_text(encoding="utf-8")
94
+ converted = _convert(body)
95
+ dst = EXPORT_DIR / slug / "SKILL.md"
96
+ dst.parent.mkdir(parents=True, exist_ok=True)
97
+ dst.write_text(converted, encoding="utf-8")
98
+ return ExportResult(
99
+ slug=slug,
100
+ source_path=src,
101
+ output_path=dst,
102
+ bytes_before=len(body),
103
+ bytes_after=len(converted),
104
+ )
105
+
106
+
107
+ def _convert(body: str) -> str:
108
+ """Apply the four open-spec transformations."""
109
+ out = _KB_PREFIX_PATTERN.sub("", body)
110
+ out = _ALLOWED_TOOLS_PATTERN.sub("", out)
111
+ out = _NAME_FIELD_PATTERN.sub(lambda m: f"name: {m.group(1).strip()}", out)
112
+ out = _SLASH_CMD_PATTERN.sub("", out)
113
+ return out.lstrip()
114
+
115
+
116
+ def export_all() -> list[ExportResult]:
117
+ """Export every skill listed in EXPORTABLE_SKILLS."""
118
+ return [export_skill(slug) for slug in EXPORTABLE_SKILLS]
119
+
120
+
121
+ def write_index(results: list[ExportResult]) -> Path:
122
+ """Write the catalog README pointing at every exported skill."""
123
+ lines = [
124
+ "# ArkaOS — Portable Agent Skills",
125
+ "",
126
+ "Open-spec exports of ArkaOS's outward-facing development skills.",
127
+ "Compatible with any Agent Skills runtime "
128
+ "(see https://agentskills.io).",
129
+ "",
130
+ "## Catalog",
131
+ "",
132
+ ]
133
+ for r in results:
134
+ lines.append(f"- [{r.slug}]({r.slug}/SKILL.md)")
135
+ lines.append("")
136
+ lines.append(
137
+ "These exports are generated by `scripts/marketplace_export.py` "
138
+ "from the in-tree skills under `departments/dev/skills/`. "
139
+ "Do not hand-edit — re-run the export script instead."
140
+ )
141
+ lines.append("")
142
+ out = EXPORT_DIR / "README.md"
143
+ out.parent.mkdir(parents=True, exist_ok=True)
144
+ out.write_text("\n".join(lines), encoding="utf-8")
145
+ return out
146
+
147
+
148
+ def main() -> int:
149
+ results = export_all()
150
+ write_index(results)
151
+ print(f"Exported {len(results)} skill(s) to {EXPORT_DIR}")
152
+ for r in results:
153
+ print(f" {r.slug:24s} {r.bytes_before:>5}B → {r.bytes_after:>5}B")
154
+ return 0
155
+
156
+
157
+ if __name__ == "__main__":
158
+ raise SystemExit(main())