arkaos 2.67.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.67.0
1
+ 2.69.0
@@ -161,6 +161,7 @@ class ArkaScheduler:
161
161
  """
162
162
  if schedule.python_module:
163
163
  return [sys.executable, "-m", schedule.python_module, *schedule.module_args]
164
+ self._warn_metered_billing_cutover(schedule)
164
165
  claude_bin = self._resolve_claude_binary()
165
166
  prompt_path = os.path.expanduser(schedule.prompt_file)
166
167
  prompt_content = Path(prompt_path).read_text(encoding="utf-8")
@@ -171,6 +172,41 @@ class ArkaScheduler:
171
172
  pass # fall back to raw template if profile unavailable
172
173
  return [claude_bin, "-p", prompt_content, "--dangerously-skip-permissions"]
173
174
 
175
+ @staticmethod
176
+ def _warn_metered_billing_cutover(schedule: ScheduleConfig) -> None:
177
+ """Emit a one-time warning for legacy `claude -p` schedules.
178
+
179
+ PR52 v2.68.0 — Anthropic's Agent SDK $200 credit policy takes
180
+ effect 2026-06-15: programmatic Claude usage (`claude -p`,
181
+ Agent SDK, GitHub Actions, third-party harnesses) is metered
182
+ separately from interactive use. Subscriptions previously
183
+ absorbed the burn; after the cutover they no longer do. Operator
184
+ action: migrate this schedule to `python_module` (Dreaming v2)
185
+ or to a direct-API-key invocation with explicit budget alarms.
186
+ """
187
+ marker_dir = Path.home() / ".arkaos" / "telemetry"
188
+ marker = marker_dir / f"metered-billing-warned.{schedule.command}"
189
+ if marker.exists():
190
+ return
191
+ try:
192
+ marker_dir.mkdir(parents=True, exist_ok=True)
193
+ marker.write_text(datetime.now().isoformat(), encoding="utf-8")
194
+ except OSError:
195
+ pass # best-effort marker; warning still fires every time
196
+ msg = (
197
+ "[arkaos] schedule '" + schedule.command + "' uses the legacy "
198
+ "`claude -p` path. From 2026-06-15, programmatic Claude usage "
199
+ "is metered separately from interactive subscription credit "
200
+ "(Pro $20 / Max5x $100 / Max20x $200, no rollover). "
201
+ "Migrate to python_module or direct API key before then. "
202
+ "See: knowledge-anthropic-agent-sdk-credit-policy-2026-06-15"
203
+ )
204
+ try:
205
+ sys.stderr.write(msg + "\n")
206
+ sys.stderr.flush()
207
+ except Exception:
208
+ pass
209
+
174
210
  # ------------------------------------------------------------------
175
211
  # Execution
176
212
  # ------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkaos",
3
- "version": "2.67.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.67.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())