@hasna/assistants 1.1.9 → 1.1.10

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
@@ -2,14 +2,14 @@
2
2
 
3
3
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
4
 
5
- A general-purpose AI assistant that runs in your terminal. Built with [Ink](https://github.com/vadimdemedes/ink) and powered by [Claude](https://www.anthropic.com/claude).
5
+ A general-purpose AI assistant that runs in your terminal. Built with [Ink](https://github.com/vadimdemedes/ink).
6
6
 
7
7
  **Not just for coding** - while it excels at development workflows, this assistant helps with research, writing, task management, automation, and any task you need assistance with.
8
8
 
9
9
  ## Features
10
10
 
11
11
  - General-purpose assistant for any task
12
- - Interactive chat with Claude AI
12
+ - Interactive chat with AI
13
13
  - Execute bash commands with approval
14
14
  - Read, write, and edit files
15
15
  - Fetch and search web content
package/dist/cli.js CHANGED
@@ -157410,6 +157410,7 @@ class ChannelStore {
157410
157410
  role TEXT NOT NULL DEFAULT 'member',
157411
157411
  joined_at TEXT NOT NULL,
157412
157412
  last_read_at TEXT,
157413
+ member_type TEXT NOT NULL DEFAULT 'assistant',
157413
157414
  PRIMARY KEY (channel_id, assistant_id)
157414
157415
  );
157415
157416
 
@@ -157427,6 +157428,16 @@ class ChannelStore {
157427
157428
  CREATE INDEX IF NOT EXISTS idx_channel_members_assistant
157428
157429
  ON channel_members(assistant_id);
157429
157430
  `);
157431
+ this.migrateAddMemberType();
157432
+ }
157433
+ migrateAddMemberType() {
157434
+ try {
157435
+ const columns = this.db.prepare("PRAGMA table_info(channel_members)").all();
157436
+ const hasMemberType = columns.some((col) => String(col.name) === "member_type");
157437
+ if (!hasMemberType) {
157438
+ this.db.exec("ALTER TABLE channel_members ADD COLUMN member_type TEXT NOT NULL DEFAULT 'assistant'");
157439
+ }
157440
+ } catch {}
157430
157441
  }
157431
157442
  createChannel(name2, description, createdBy, createdByName) {
157432
157443
  const normalizedName = name2.toLowerCase().replace(/^#/, "").replace(/[^a-z0-9_-]/g, "-");
@@ -157521,12 +157532,12 @@ class ChannelStore {
157521
157532
  const result = stmt.run("archived", now2, id, "active");
157522
157533
  return result.changes > 0;
157523
157534
  }
157524
- addMember(channelId, assistantId, assistantName, role = "member") {
157535
+ addMember(channelId, assistantId, assistantName, role = "member", memberType = "assistant") {
157525
157536
  try {
157526
157537
  const now2 = new Date().toISOString();
157527
- const stmt = this.db.prepare(`INSERT OR IGNORE INTO channel_members (channel_id, assistant_id, assistant_name, role, joined_at)
157528
- VALUES (?, ?, ?, ?, ?)`);
157529
- const result = stmt.run(channelId, assistantId, assistantName, role, now2);
157538
+ const stmt = this.db.prepare(`INSERT OR IGNORE INTO channel_members (channel_id, assistant_id, assistant_name, role, joined_at, member_type)
157539
+ VALUES (?, ?, ?, ?, ?, ?)`);
157540
+ const result = stmt.run(channelId, assistantId, assistantName, role, now2, memberType);
157530
157541
  return result.changes > 0;
157531
157542
  } catch {
157532
157543
  return false;
@@ -157666,7 +157677,8 @@ class ChannelStore {
157666
157677
  assistantName: String(row.assistant_name),
157667
157678
  role: String(row.role),
157668
157679
  joinedAt: String(row.joined_at),
157669
- lastReadAt: row.last_read_at ? String(row.last_read_at) : null
157680
+ lastReadAt: row.last_read_at ? String(row.last_read_at) : null,
157681
+ memberType: row.member_type ? String(row.member_type) : "assistant"
157670
157682
  };
157671
157683
  }
157672
157684
  rowToMessage(row) {
@@ -157751,7 +157763,7 @@ class ChannelsManager {
157751
157763
  this.store.removeMember(channel.id, this.assistantId);
157752
157764
  return { success: true, message: `Left #${channel.name}.`, channelId: channel.id };
157753
157765
  }
157754
- invite(nameOrId, targetId, targetName) {
157766
+ invite(nameOrId, targetId, targetName, memberType = "assistant") {
157755
157767
  const channel = this.store.resolveChannel(nameOrId);
157756
157768
  if (!channel) {
157757
157769
  return { success: false, message: `Channel "${nameOrId}" not found.` };
@@ -157762,7 +157774,7 @@ class ChannelsManager {
157762
157774
  if (this.store.isMember(channel.id, targetId)) {
157763
157775
  return { success: false, message: `${targetName} is already a member of #${channel.name}.` };
157764
157776
  }
157765
- this.store.addMember(channel.id, targetId, targetName);
157777
+ this.store.addMember(channel.id, targetId, targetName, "member", memberType);
157766
157778
  return {
157767
157779
  success: true,
157768
157780
  message: `Invited ${targetName} to #${channel.name}.`,
@@ -157793,6 +157805,24 @@ class ChannelsManager {
157793
157805
  channelId: channel.id
157794
157806
  };
157795
157807
  }
157808
+ sendAs(nameOrId, content, senderId, senderName) {
157809
+ const channel = this.store.resolveChannel(nameOrId);
157810
+ if (!channel) {
157811
+ return { success: false, message: `Channel "${nameOrId}" not found.` };
157812
+ }
157813
+ if (channel.status !== "active") {
157814
+ return { success: false, message: `Channel #${channel.name} is archived.` };
157815
+ }
157816
+ if (!this.store.isMember(channel.id, senderId)) {
157817
+ return { success: false, message: `${senderName} is not a member of #${channel.name}. Join first.` };
157818
+ }
157819
+ const messageId = this.store.sendMessage(channel.id, senderId, senderName, content);
157820
+ return {
157821
+ success: true,
157822
+ message: `Message sent to #${channel.name} (${messageId}).`,
157823
+ channelId: channel.id
157824
+ };
157825
+ }
157796
157826
  readMessages(nameOrId, limit2) {
157797
157827
  const channel = this.store.resolveChannel(nameOrId);
157798
157828
  if (!channel)
package/dist/lib.js CHANGED
@@ -150836,6 +150836,7 @@ class ChannelStore {
150836
150836
  role TEXT NOT NULL DEFAULT 'member',
150837
150837
  joined_at TEXT NOT NULL,
150838
150838
  last_read_at TEXT,
150839
+ member_type TEXT NOT NULL DEFAULT 'assistant',
150839
150840
  PRIMARY KEY (channel_id, assistant_id)
150840
150841
  );
150841
150842
 
@@ -150853,6 +150854,16 @@ class ChannelStore {
150853
150854
  CREATE INDEX IF NOT EXISTS idx_channel_members_assistant
150854
150855
  ON channel_members(assistant_id);
150855
150856
  `);
150857
+ this.migrateAddMemberType();
150858
+ }
150859
+ migrateAddMemberType() {
150860
+ try {
150861
+ const columns = this.db.prepare("PRAGMA table_info(channel_members)").all();
150862
+ const hasMemberType = columns.some((col) => String(col.name) === "member_type");
150863
+ if (!hasMemberType) {
150864
+ this.db.exec("ALTER TABLE channel_members ADD COLUMN member_type TEXT NOT NULL DEFAULT 'assistant'");
150865
+ }
150866
+ } catch {}
150856
150867
  }
150857
150868
  createChannel(name2, description, createdBy, createdByName) {
150858
150869
  const normalizedName = name2.toLowerCase().replace(/^#/, "").replace(/[^a-z0-9_-]/g, "-");
@@ -150947,12 +150958,12 @@ class ChannelStore {
150947
150958
  const result = stmt.run("archived", now2, id, "active");
150948
150959
  return result.changes > 0;
150949
150960
  }
150950
- addMember(channelId, assistantId, assistantName, role = "member") {
150961
+ addMember(channelId, assistantId, assistantName, role = "member", memberType = "assistant") {
150951
150962
  try {
150952
150963
  const now2 = new Date().toISOString();
150953
- const stmt = this.db.prepare(`INSERT OR IGNORE INTO channel_members (channel_id, assistant_id, assistant_name, role, joined_at)
150954
- VALUES (?, ?, ?, ?, ?)`);
150955
- const result = stmt.run(channelId, assistantId, assistantName, role, now2);
150964
+ const stmt = this.db.prepare(`INSERT OR IGNORE INTO channel_members (channel_id, assistant_id, assistant_name, role, joined_at, member_type)
150965
+ VALUES (?, ?, ?, ?, ?, ?)`);
150966
+ const result = stmt.run(channelId, assistantId, assistantName, role, now2, memberType);
150956
150967
  return result.changes > 0;
150957
150968
  } catch {
150958
150969
  return false;
@@ -151092,7 +151103,8 @@ class ChannelStore {
151092
151103
  assistantName: String(row.assistant_name),
151093
151104
  role: String(row.role),
151094
151105
  joinedAt: String(row.joined_at),
151095
- lastReadAt: row.last_read_at ? String(row.last_read_at) : null
151106
+ lastReadAt: row.last_read_at ? String(row.last_read_at) : null,
151107
+ memberType: row.member_type ? String(row.member_type) : "assistant"
151096
151108
  };
151097
151109
  }
151098
151110
  rowToMessage(row) {
@@ -151170,7 +151182,7 @@ class ChannelsManager {
151170
151182
  this.store.removeMember(channel.id, this.assistantId);
151171
151183
  return { success: true, message: `Left #${channel.name}.`, channelId: channel.id };
151172
151184
  }
151173
- invite(nameOrId, targetId, targetName) {
151185
+ invite(nameOrId, targetId, targetName, memberType = "assistant") {
151174
151186
  const channel = this.store.resolveChannel(nameOrId);
151175
151187
  if (!channel) {
151176
151188
  return { success: false, message: `Channel "${nameOrId}" not found.` };
@@ -151181,7 +151193,7 @@ class ChannelsManager {
151181
151193
  if (this.store.isMember(channel.id, targetId)) {
151182
151194
  return { success: false, message: `${targetName} is already a member of #${channel.name}.` };
151183
151195
  }
151184
- this.store.addMember(channel.id, targetId, targetName);
151196
+ this.store.addMember(channel.id, targetId, targetName, "member", memberType);
151185
151197
  return {
151186
151198
  success: true,
151187
151199
  message: `Invited ${targetName} to #${channel.name}.`,
@@ -151212,6 +151224,24 @@ class ChannelsManager {
151212
151224
  channelId: channel.id
151213
151225
  };
151214
151226
  }
151227
+ sendAs(nameOrId, content, senderId, senderName) {
151228
+ const channel = this.store.resolveChannel(nameOrId);
151229
+ if (!channel) {
151230
+ return { success: false, message: `Channel "${nameOrId}" not found.` };
151231
+ }
151232
+ if (channel.status !== "active") {
151233
+ return { success: false, message: `Channel #${channel.name} is archived.` };
151234
+ }
151235
+ if (!this.store.isMember(channel.id, senderId)) {
151236
+ return { success: false, message: `${senderName} is not a member of #${channel.name}. Join first.` };
151237
+ }
151238
+ const messageId = this.store.sendMessage(channel.id, senderId, senderName, content);
151239
+ return {
151240
+ success: true,
151241
+ message: `Message sent to #${channel.name} (${messageId}).`,
151242
+ channelId: channel.id
151243
+ };
151244
+ }
151215
151245
  readMessages(nameOrId, limit2) {
151216
151246
  const channel = this.store.resolveChannel(nameOrId);
151217
151247
  if (!channel)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hasna/assistants",
3
- "version": "1.1.9",
4
- "description": "AI assistant that runs in your terminal - powered by Claude",
3
+ "version": "1.1.10",
4
+ "description": "AI assistant that runs in your terminal",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "exports": {