@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 +2 -2
- package/dist/cli.js +37 -7
- package/dist/lib.js +37 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
[](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)
|
|
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
|
|
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.
|
|
4
|
-
"description": "AI assistant that runs in your terminal
|
|
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": {
|