arkaos 2.19.0 → 2.19.1

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/README.md CHANGED
@@ -161,7 +161,7 @@ ArkaOS doesn't just execute — it **learns, dreams, and researches**.
161
161
  Every solution you implement is captured and indexed. When you need authentication in a new Laravel project, ArkaOS already knows how you did it in the last three projects — with the exact pattern, configuration, and lessons learned.
162
162
 
163
163
  - **Dual-write**: Obsidian (human-readable) + Vector DB (semantic search)
164
- - **Cross-project**: Knowledge from Rockport applies to ClubeFashion
164
+ - **Cross-project**: Knowledge from ClientRetail applies to ClientFashion
165
165
  - **Confidence scoring**: Patterns validated 3+ times become "validated patterns"
166
166
 
167
167
  ### Dreaming (runs at 02:00)
@@ -185,7 +185,7 @@ Pending reflections from Dreaming:
185
185
 
186
186
  2. [technical] Sync retry — improve
187
187
  Fixed backoff can cause thundering herd. Use exponential
188
- backoff with jitter (validated pattern from Rockport).
188
+ backoff with jitter (validated pattern from ClientRetail).
189
189
 
190
190
  Want me to elaborate?
191
191
  ```
@@ -204,11 +204,11 @@ Intelligence Briefing — 2026-04-10
204
204
 
205
205
  ACTION REQUIRED:
206
206
  - Laravel 12.1.3 security patch — SQL injection in whereHas.
207
- Affects: ClubeFashion, Fovory. Fix: composer update laravel/framework.
207
+ Affects: ClientFashion, ClientCommerce. Fix: composer update laravel/framework.
208
208
 
209
209
  OPPORTUNITIES:
210
- - Shopify Winter '26 bulk product API — Fovory sync could be 10x faster.
211
- - Nuxt 4 RC2 migration guide published — start preparing ZugaTV.
210
+ - Shopify Winter '26 bulk product API — ClientCommerce sync could be 10x faster.
211
+ - Nuxt 4 RC2 migration guide published — start preparing ClientVideo.
212
212
 
213
213
  COMPETITOR WATCH:
214
214
  - CrewAI v3 launched memory layer — similar to our Cognitive Layer
@@ -233,9 +233,9 @@ arkaos scheduler logs # View logs
233
233
  ArkaOS manages client projects as **ecosystems** — groups of related projects with dedicated squads.
234
234
 
235
235
  ```
236
- /rockportRockport ecosystem (4 projects: API, frontend, admin, docs)
237
- /fovoryFovory ecosystem (supplier sync + Shopify theme)
238
- /clubefashionClubeFashion (6 projects: CRM, store, API, migration...)
236
+ /client_retailClientRetail ecosystem (4 projects: API, frontend, admin, docs)
237
+ /client_commerceClientCommerce ecosystem (supplier sync + Shopify theme)
238
+ /client_fashionClientFashion (6 projects: CRM, store, API, migration...)
239
239
  /edp → EDP (3 projects: portal, API, analytics)
240
240
  ```
241
241
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.19.0
1
+ 2.19.1
@@ -70,7 +70,7 @@ vector = VectorWriter(os.path.expanduser("~/.arkaos/knowledge.db"))
70
70
 
71
71
  - Compare today's errors with past errors — if same error type appears > 2 times, create Anti-Pattern entry
72
72
  - Compare today's solutions with past solutions — if same pattern appears > 2 times, promote to Validated Pattern
73
- - Detect inconsistencies between projects ("In Rockport used X, in ClubeFashion used Y for same problem")
73
+ - Detect inconsistencies between projects ("In ClientRetail used X, in ClientFashion used Y for same problem")
74
74
 
75
75
  ## Phase 4: Curation and Consolidation
76
76
 
@@ -123,7 +123,7 @@ quality_score: 75
123
123
  entries_created: 4
124
124
  entries_updated: 2
125
125
  insights_generated: 3
126
- projects_active: [fovory, rockport, clubefashion]
126
+ projects_active: [client_commerce, client_retail, client_fashion]
127
127
  ---
128
128
 
129
129
  # Dreaming Report — YYYY-MM-DD
@@ -199,7 +199,7 @@ Write structured metrics to `~/.arkaos/logs/dreaming/YYYY-MM-DD.json`:
199
199
  "entries_updated": 2,
200
200
  "insights_generated": 3,
201
201
  "captures_processed": 15,
202
- "projects_reviewed": ["fovory", "rockport"]
202
+ "projects_reviewed": ["client_commerce", "client_retail"]
203
203
  }
204
204
  ```
205
205
 
@@ -184,14 +184,14 @@ def _discover_projects(arkaos_home: Path, skills_dir: Path) -> list:
184
184
  """
185
185
  del skills_dir # retained for signature stability; unused.
186
186
 
187
- descriptor_dir = resolve_projects_dir()
188
- ecosystems_path = resolve_ecosystems_file()
189
-
190
- # discover_all_projects treats missing paths as empty; pass a stable
191
- # sentinel when the resolver returned None so downstream .exists()
192
- # checks short-circuit cleanly.
193
- descriptor_dir = descriptor_dir or (Path.home() / ".arkaos" / "projects")
194
- ecosystems_path = ecosystems_path or (Path.home() / ".arkaos" / "ecosystems.json")
187
+ # resolve_*() returns None when neither the new nor legacy path exists.
188
+ # `discover_all_projects` requires concrete Path objects but calls
189
+ # `.exists()` internally, so substituting the (non-existent) canonical
190
+ # path keeps the contract: missing returns an empty project list.
191
+ descriptor_dir = resolve_projects_dir() or (Path.home() / ".arkaos" / "projects")
192
+ ecosystems_path = resolve_ecosystems_file() or (
193
+ Path.home() / ".arkaos" / "ecosystems.json"
194
+ )
195
195
 
196
196
  scan_dirs = _load_scan_dirs_from_profile(arkaos_home)
197
197
 
@@ -105,19 +105,20 @@ export default {
105
105
  ];
106
106
 
107
107
  // Statusline — ArkaOS branded status bar
108
+ // Claude Code reads the camelCase "statusLine" key; the lowercase
109
+ // "statusline" variant is silently ignored.
108
110
  const configDir = join(installDir, "config");
109
111
  const statuslineFile = IS_WINDOWS ? "statusline.ps1" : "statusline.sh";
110
112
  const statuslinePath = join(configDir, statuslineFile);
111
113
  if (existsSync(statuslinePath)) {
112
- if (IS_WINDOWS) {
113
- settings.statusline = {
114
- command: `powershell -NoProfile -ExecutionPolicy Bypass -File "${statuslinePath}"`,
115
- };
116
- } else {
117
- settings.statusline = {
118
- command: statuslinePath,
119
- };
120
- }
114
+ const command = IS_WINDOWS
115
+ ? `powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "${statuslinePath}"`
116
+ : statuslinePath;
117
+ settings.statusLine = {
118
+ type: "command",
119
+ command,
120
+ padding: 2,
121
+ };
121
122
  }
122
123
 
123
124
  writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
@@ -259,6 +259,27 @@ export async function install({ runtime, path, force }) {
259
259
  };
260
260
  writeFileSync(join(installDir, "install-manifest.json"), JSON.stringify(manifest, null, 2));
261
261
 
262
+ // Seed sync-state.json so session-start.sh does not read a missing file as
263
+ // version drift and permanently show [arka:update-available] on a fresh
264
+ // install. Schema aligned with core/sync/reporter.py write_sync_state.
265
+ const syncStatePath = join(installDir, "sync-state.json");
266
+ if (!existsSync(syncStatePath)) {
267
+ writeFileSync(
268
+ syncStatePath,
269
+ JSON.stringify(
270
+ {
271
+ version: VERSION,
272
+ last_sync: new Date().toISOString(),
273
+ projects_synced: 0,
274
+ skills_synced: 0,
275
+ errors: [],
276
+ },
277
+ null,
278
+ 2,
279
+ ),
280
+ );
281
+ }
282
+
262
283
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
263
284
 
264
285
  console.log(`
@@ -19,81 +19,16 @@ const LOGS_DIR = join(USER_DATA_ROOT, "logs");
19
19
  * @returns {{ moved: string[], skipped: string[], conflicts: string[], logPath: string|null }}
20
20
  */
21
21
  export function migrateUserData({ dryRun = false } = {}) {
22
- const moved = [];
23
- const skipped = [];
24
- const conflicts = [];
22
+ ensureDataRoot();
25
23
 
26
- if (!existsSync(USER_DATA_ROOT)) {
27
- mkdirSync(USER_DATA_ROOT, { recursive: true });
28
- }
29
- if (!existsSync(NEW_PROJECTS)) {
30
- mkdirSync(NEW_PROJECTS, { recursive: true });
31
- }
24
+ const projectsResult = migrateProjects({ dryRun });
25
+ const ecosystemsResult = migrateEcosystems({ dryRun });
32
26
 
33
- if (existsSync(LEGACY_PROJECTS) && statSync(LEGACY_PROJECTS).isDirectory()) {
34
- for (const entry of readdirSync(LEGACY_PROJECTS)) {
35
- const src = join(LEGACY_PROJECTS, entry);
36
- const dst = join(NEW_PROJECTS, entry);
37
- if (existsSync(dst)) {
38
- conflicts.push(`projects/${entry}: destination already present, left source untouched`);
39
- continue;
40
- }
41
- if (dryRun) {
42
- moved.push(`projects/${entry} (dry-run)`);
43
- } else {
44
- try {
45
- renameSync(src, dst);
46
- moved.push(`projects/${entry}`);
47
- } catch (err) {
48
- conflicts.push(`projects/${entry}: ${err.message}`);
49
- }
50
- }
51
- }
52
- } else {
53
- skipped.push("projects/: legacy directory absent");
54
- }
55
-
56
- if (existsSync(LEGACY_ECOSYSTEMS)) {
57
- if (existsSync(NEW_ECOSYSTEMS)) {
58
- conflicts.push("ecosystems.json: destination already present, left source untouched");
59
- } else if (dryRun) {
60
- moved.push("ecosystems.json (dry-run)");
61
- } else {
62
- try {
63
- renameSync(LEGACY_ECOSYSTEMS, NEW_ECOSYSTEMS);
64
- moved.push("ecosystems.json");
65
- } catch (err) {
66
- conflicts.push(`ecosystems.json: ${err.message}`);
67
- }
68
- }
69
- } else {
70
- skipped.push("ecosystems.json: legacy file absent");
71
- }
72
-
73
- let logPath = null;
74
- if (moved.length > 0 || conflicts.length > 0) {
75
- if (!existsSync(LOGS_DIR)) mkdirSync(LOGS_DIR, { recursive: true });
76
- const stamp = new Date().toISOString().replace(/[:.]/g, "-");
77
- logPath = join(LOGS_DIR, `migration-${stamp}.log`);
78
- const body = [
79
- `ArkaOS user-data migration — ${new Date().toISOString()}`,
80
- `Source: ${LEGACY_SKILLS_ROOT}`,
81
- `Destination: ${USER_DATA_ROOT}`,
82
- `Dry-run: ${dryRun}`,
83
- "",
84
- `Moved (${moved.length}):`,
85
- ...moved.map(m => ` - ${m}`),
86
- "",
87
- `Conflicts (${conflicts.length}):`,
88
- ...conflicts.map(c => ` - ${c}`),
89
- "",
90
- `Skipped (${skipped.length}):`,
91
- ...skipped.map(s => ` - ${s}`),
92
- "",
93
- ].join("\n");
94
- if (!dryRun) writeFileSync(logPath, body);
95
- }
27
+ const moved = [...projectsResult.moved, ...ecosystemsResult.moved];
28
+ const skipped = [...projectsResult.skipped, ...ecosystemsResult.skipped];
29
+ const conflicts = [...projectsResult.conflicts, ...ecosystemsResult.conflicts];
96
30
 
31
+ const logPath = writeReport({ moved, skipped, conflicts, dryRun });
97
32
  return { moved, skipped, conflicts, logPath };
98
33
  }
99
34
 
@@ -108,3 +43,90 @@ export function printMigrationReport(result) {
108
43
  for (const c of conflicts) console.log(` ! ${c}`);
109
44
  if (logPath) console.log(` Log: ${logPath}`);
110
45
  }
46
+
47
+ function ensureDataRoot() {
48
+ if (!existsSync(USER_DATA_ROOT)) mkdirSync(USER_DATA_ROOT, { recursive: true });
49
+ if (!existsSync(NEW_PROJECTS)) mkdirSync(NEW_PROJECTS, { recursive: true });
50
+ }
51
+
52
+ function migrateProjects({ dryRun }) {
53
+ const moved = [];
54
+ const skipped = [];
55
+ const conflicts = [];
56
+
57
+ if (!existsSync(LEGACY_PROJECTS) || !statSync(LEGACY_PROJECTS).isDirectory()) {
58
+ skipped.push("projects/: legacy directory absent");
59
+ return { moved, skipped, conflicts };
60
+ }
61
+
62
+ for (const entry of readdirSync(LEGACY_PROJECTS)) {
63
+ const src = join(LEGACY_PROJECTS, entry);
64
+ const dst = join(NEW_PROJECTS, entry);
65
+ if (existsSync(dst)) {
66
+ conflicts.push(`projects/${entry}: destination already present, left source untouched`);
67
+ continue;
68
+ }
69
+ if (dryRun) {
70
+ moved.push(`projects/${entry} (dry-run)`);
71
+ continue;
72
+ }
73
+ try {
74
+ renameSync(src, dst);
75
+ moved.push(`projects/${entry}`);
76
+ } catch (err) {
77
+ conflicts.push(`projects/${entry}: ${err.message}`);
78
+ }
79
+ }
80
+ return { moved, skipped, conflicts };
81
+ }
82
+
83
+ function migrateEcosystems({ dryRun }) {
84
+ const moved = [];
85
+ const skipped = [];
86
+ const conflicts = [];
87
+
88
+ if (!existsSync(LEGACY_ECOSYSTEMS)) {
89
+ skipped.push("ecosystems.json: legacy file absent");
90
+ return { moved, skipped, conflicts };
91
+ }
92
+ if (existsSync(NEW_ECOSYSTEMS)) {
93
+ conflicts.push("ecosystems.json: destination already present, left source untouched");
94
+ return { moved, skipped, conflicts };
95
+ }
96
+ if (dryRun) {
97
+ moved.push("ecosystems.json (dry-run)");
98
+ return { moved, skipped, conflicts };
99
+ }
100
+ try {
101
+ renameSync(LEGACY_ECOSYSTEMS, NEW_ECOSYSTEMS);
102
+ moved.push("ecosystems.json");
103
+ } catch (err) {
104
+ conflicts.push(`ecosystems.json: ${err.message}`);
105
+ }
106
+ return { moved, skipped, conflicts };
107
+ }
108
+
109
+ function writeReport({ moved, skipped, conflicts, dryRun }) {
110
+ if (moved.length === 0 && conflicts.length === 0) return null;
111
+ if (!existsSync(LOGS_DIR)) mkdirSync(LOGS_DIR, { recursive: true });
112
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
113
+ const logPath = join(LOGS_DIR, `migration-${stamp}.log`);
114
+ const body = [
115
+ `ArkaOS user-data migration — ${new Date().toISOString()}`,
116
+ `Source: ${LEGACY_SKILLS_ROOT}`,
117
+ `Destination: ${USER_DATA_ROOT}`,
118
+ `Dry-run: ${dryRun}`,
119
+ "",
120
+ `Moved (${moved.length}):`,
121
+ ...moved.map(m => ` - ${m}`),
122
+ "",
123
+ `Conflicts (${conflicts.length}):`,
124
+ ...conflicts.map(c => ` - ${c}`),
125
+ "",
126
+ `Skipped (${skipped.length}):`,
127
+ ...skipped.map(s => ` - ${s}`),
128
+ "",
129
+ ].join("\n");
130
+ if (!dryRun) writeFileSync(logPath, body);
131
+ return logPath;
132
+ }
@@ -267,7 +267,7 @@ export async function update() {
267
267
  // main `/arka` skill, so any department skill (arka-dev, arka-brand,
268
268
  // etc.) or sub-skill (arka-code-review, arka-viral, etc.) or agent
269
269
  // persona added after the original install was silently missing on
270
- // upgrade. Discovered during Marlon's bake-in: 233 top-level arka-*
270
+ // upgrade. Discovered during ClientAdvisory's bake-in: 233 top-level arka-*
271
271
  // skills on his WSL (deployed long ago by install.sh) vs 1 skill on
272
272
  // his Windows install (only the main /arka). The Node installer
273
273
  // never deployed anything else.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkaos",
3
- "version": "2.19.0",
3
+ "version": "2.19.1",
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.19.0"
3
+ version = "2.19.1"
4
4
  description = "Core engine for ArkaOS — The Operating System for AI Agent Teams"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}