hoomanjs 1.8.0 → 1.9.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hoomanjs",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Bun-powered local AI agent CLI with chat, exec, ACP, MCP, and skills support.",
5
5
  "author": {
6
6
  "name": "Vaibhav Pandey",
@@ -838,7 +838,7 @@ export function ConfigureApp({
838
838
  ),
839
839
  boldSubstring: result.name,
840
840
  value: () => {
841
- const source = result.source || result.slug;
841
+ const source = result.slug || result.source;
842
842
  void runTask(`Installing ${result.name}...`, async () => {
843
843
  await skills.install(source);
844
844
  await refreshSkills("Refreshing installed skills...");
@@ -0,0 +1,89 @@
1
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import type {
4
+ Snapshot,
5
+ SnapshotLocation,
6
+ SnapshotManifest,
7
+ SnapshotStorage,
8
+ } from "@strands-agents/sdk";
9
+
10
+ /**
11
+ * Snapshot storage with a flat per-session layout:
12
+ * `<baseDir>/<sessionId>/snapshot_latest.json`.
13
+ */
14
+ export class FlatFileStorage implements SnapshotStorage {
15
+ constructor(private readonly baseDir: string) {}
16
+
17
+ async saveSnapshot(params: {
18
+ location: SnapshotLocation;
19
+ snapshotId: string;
20
+ isLatest: boolean;
21
+ snapshot: Snapshot;
22
+ }): Promise<void> {
23
+ const path = this.snapshotPath(params.location, params.snapshotId);
24
+ await mkdir(join(this.sessionDir(params.location.sessionId)), {
25
+ recursive: true,
26
+ });
27
+ await writeFile(path, JSON.stringify(params.snapshot, null, 2), "utf8");
28
+ }
29
+
30
+ async loadSnapshot(params: {
31
+ location: SnapshotLocation;
32
+ snapshotId?: string;
33
+ }): Promise<Snapshot | null> {
34
+ const path = this.snapshotPath(params.location, params.snapshotId);
35
+ try {
36
+ const raw = await readFile(path, "utf8");
37
+ return JSON.parse(raw) as Snapshot;
38
+ } catch (error) {
39
+ if (
40
+ error instanceof Error &&
41
+ "code" in error &&
42
+ error.code === "ENOENT"
43
+ ) {
44
+ return null;
45
+ }
46
+ throw error;
47
+ }
48
+ }
49
+
50
+ async listSnapshotIds(): Promise<string[]> {
51
+ // Flat storage only tracks one mutable snapshot.
52
+ return [];
53
+ }
54
+
55
+ async deleteSession(params: { sessionId: string }): Promise<void> {
56
+ await rm(this.sessionDir(params.sessionId), {
57
+ recursive: true,
58
+ force: true,
59
+ });
60
+ }
61
+
62
+ async loadManifest(): Promise<SnapshotManifest> {
63
+ return {
64
+ schemaVersion: "1.0",
65
+ updatedAt: new Date().toISOString(),
66
+ };
67
+ }
68
+
69
+ async saveManifest(): Promise<void> {
70
+ // No-op: flat storage doesn't persist manifest metadata.
71
+ }
72
+
73
+ private sessionDir(sessionId: string): string {
74
+ return join(this.baseDir, sessionId);
75
+ }
76
+
77
+ private snapshotPath(
78
+ location: SnapshotLocation,
79
+ snapshotId?: string,
80
+ ): string {
81
+ if (snapshotId && snapshotId !== "latest") {
82
+ return join(
83
+ this.sessionDir(location.sessionId),
84
+ `snapshot_${snapshotId}.json`,
85
+ );
86
+ }
87
+ return join(this.sessionDir(location.sessionId), "snapshot_latest.json");
88
+ }
89
+ }
@@ -1,9 +1,9 @@
1
1
  import {
2
- FileStorage,
3
2
  SessionManager,
4
3
  SummarizingConversationManager,
5
4
  } from "@strands-agents/sdk";
6
5
  import { sessionsPath } from "../../utils/paths";
6
+ import { FlatFileStorage } from "./flat-file-storage";
7
7
  import { LazySessionManager } from "./lazy-session-manager";
8
8
 
9
9
  export function create(sessionId?: string) {
@@ -11,7 +11,7 @@ export function create(sessionId?: string) {
11
11
  summaryRatio: 0.5,
12
12
  preserveRecentMessages: 5,
13
13
  });
14
- const storage = new FileStorage(sessionsPath());
14
+ const storage = new FlatFileStorage(sessionsPath());
15
15
 
16
16
  if (!sessionId) {
17
17
  return {
@@ -209,7 +209,7 @@ export class Registry {
209
209
  }
210
210
  const data = (await res.json()) as {
211
211
  skills: Array<{
212
- id: string;
212
+ skillId: string;
213
213
  name: string;
214
214
  installs: number;
215
215
  source: string;
@@ -223,7 +223,7 @@ export class Registry {
223
223
  return data.skills
224
224
  .map((skill) => ({
225
225
  name: skill.name,
226
- slug: skill.id,
226
+ slug: `${skill.source.trim()}@${skill.skillId.trim()}`,
227
227
  source: skill.source || "",
228
228
  installs: skill.installs,
229
229
  }))