@hasna/conversations 0.2.32 → 0.2.33

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/bin/index.js CHANGED
@@ -14928,7 +14928,7 @@ var init_presence = __esm(() => {
14928
14928
  var require_package = __commonJS((exports, module) => {
14929
14929
  module.exports = {
14930
14930
  name: "@hasna/conversations",
14931
- version: "0.2.32",
14931
+ version: "0.2.33",
14932
14932
  description: "Real-time CLI messaging for AI agents",
14933
14933
  type: "module",
14934
14934
  bin: {
@@ -15071,6 +15071,18 @@ function listProjects(opts) {
15071
15071
  params.push(opts.status);
15072
15072
  }
15073
15073
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
15074
+ let pagination = "";
15075
+ if (typeof opts?.limit === "number" && Number.isFinite(opts.limit) && opts.limit > 0) {
15076
+ pagination += " LIMIT ?";
15077
+ params.push(Math.floor(opts.limit));
15078
+ }
15079
+ if (typeof opts?.offset === "number" && Number.isFinite(opts.offset) && opts.offset >= 0) {
15080
+ if (!pagination.includes("LIMIT")) {
15081
+ pagination += " LIMIT -1";
15082
+ }
15083
+ pagination += " OFFSET ?";
15084
+ params.push(Math.floor(opts.offset));
15085
+ }
15074
15086
  const rows = db2.prepare(`
15075
15087
  SELECT
15076
15088
  p.*,
@@ -15078,6 +15090,7 @@ function listProjects(opts) {
15078
15090
  FROM projects p
15079
15091
  ${where}
15080
15092
  ORDER BY p.name ASC
15093
+ ${pagination}
15081
15094
  `).all(...params);
15082
15095
  return rows.map((row) => ({
15083
15096
  ...parseProject(row),
@@ -49630,6 +49643,11 @@ init_projects();
49630
49643
  init_db();
49631
49644
  init_identity();
49632
49645
  import chalk6 from "chalk";
49646
+ function requireDeleteConfirmation(confirmed) {
49647
+ if (!confirmed) {
49648
+ throw new Error("Project deletion requires --yes confirmation");
49649
+ }
49650
+ }
49633
49651
  function registerProjectCommands(program2) {
49634
49652
  const project = program2.command("project").description("Manage projects");
49635
49653
  project.command("create").description("Create a new project").argument("<name>", "Project name").option("--description <text>", "Project description").option("--path <path>", "Project path on disk").option("--repository <url>", "Repository URL").option("--tags <json>", "JSON array of tags").option("--from <agent>", "Creator agent ID").option("--json", "Output as JSON").action((name, opts) => {
@@ -49676,9 +49694,15 @@ function registerProjectCommands(program2) {
49676
49694
  }
49677
49695
  closeDb();
49678
49696
  });
49679
- project.command("list").description("List all projects").option("--status <status>", "Filter by status (active/archived)").option("--json", "Output as JSON").action((opts) => {
49697
+ project.command("list").description("List all projects").option("--status <status>", "Filter by status (active/archived)").option("--limit <n>", "Limit results", parseInt).option("--offset <n>", "Skip first N results", parseInt).option("--json", "Output as JSON").action((opts) => {
49680
49698
  const status = opts.status === "active" || opts.status === "archived" ? opts.status : undefined;
49681
- const projects = listProjects(status ? { status } : undefined);
49699
+ const limit = Number.isFinite(opts.limit) && opts.limit > 0 ? opts.limit : undefined;
49700
+ const offset = Number.isFinite(opts.offset) && opts.offset >= 0 ? opts.offset : undefined;
49701
+ const projects = listProjects({
49702
+ ...status ? { status } : {},
49703
+ ...limit !== undefined ? { limit } : {},
49704
+ ...offset !== undefined ? { offset } : {}
49705
+ });
49682
49706
  if (opts.json) {
49683
49707
  console.log(JSON.stringify(projects, null, 2));
49684
49708
  } else {
@@ -49755,8 +49779,9 @@ function registerProjectCommands(program2) {
49755
49779
  }
49756
49780
  closeDb();
49757
49781
  });
49758
- project.command("delete").description("Delete a project").argument("<id-or-name>", "Project ID or name").option("--json", "Output as JSON").action((id, opts) => {
49782
+ project.command("delete").description("Delete a project").argument("<id-or-name>", "Project ID or name").option("--yes", "Confirm project deletion").option("--json", "Output as JSON").action((id, opts) => {
49759
49783
  try {
49784
+ requireDeleteConfirmation(opts.yes);
49760
49785
  const isUuid = /^[0-9a-f-]{36}$/i.test(id);
49761
49786
  const resolvedId = isUuid ? id : getProjectByName(id)?.id ?? id;
49762
49787
  const deleted = deleteProject(resolvedId);
@@ -49770,7 +49795,11 @@ function registerProjectCommands(program2) {
49770
49795
  console.log(chalk6.green(`Project deleted.`));
49771
49796
  }
49772
49797
  } catch (e) {
49773
- console.error(chalk6.red(e.message));
49798
+ if (opts.json) {
49799
+ console.log(JSON.stringify({ id, deleted: false, error: e.message }));
49800
+ } else {
49801
+ console.error(chalk6.red(e.message));
49802
+ }
49774
49803
  process.exit(1);
49775
49804
  }
49776
49805
  closeDb();
@@ -49783,6 +49812,26 @@ init_identity();
49783
49812
  init_presence();
49784
49813
  init_projects();
49785
49814
  import chalk7 from "chalk";
49815
+ function buildWhoamiPayload(agent, source, presence, nowMs = Date.now()) {
49816
+ if (!presence) {
49817
+ return {
49818
+ agent,
49819
+ source,
49820
+ online: false,
49821
+ last_seen_at: null,
49822
+ last_seen_ago_seconds: null
49823
+ };
49824
+ }
49825
+ const lastSeenMs = new Date(`${presence.last_seen_at}Z`).getTime();
49826
+ const deltaSeconds = Number.isFinite(lastSeenMs) ? Math.max(0, Math.floor((nowMs - lastSeenMs) / 1000)) : null;
49827
+ return {
49828
+ agent,
49829
+ source,
49830
+ online: presence.online,
49831
+ last_seen_at: presence.last_seen_at,
49832
+ last_seen_ago_seconds: deltaSeconds
49833
+ };
49834
+ }
49786
49835
  function registerAgentCommands(program2) {
49787
49836
  const agents = program2.command("agents").description("Manage agents");
49788
49837
  agents.command("list").description("List all agents with their presence status").option("--online", "Only show online agents").option("--json", "Output as JSON").action((opts) => {
@@ -49927,7 +49976,7 @@ function registerAgentCommands(program2) {
49927
49976
  }
49928
49977
  closeDb();
49929
49978
  });
49930
- program2.command("whoami").description("Show current agent identity and online status").option("--from <agent>", "Explicit agent identity").action((opts) => {
49979
+ program2.command("whoami").description("Show current agent identity and online status").option("--from <agent>", "Explicit agent identity").option("--json", "Output as JSON").action((opts) => {
49931
49980
  const envValue = process.env.CONVERSATIONS_AGENT_ID?.trim();
49932
49981
  const agent = resolveIdentity(opts.from);
49933
49982
  let source;
@@ -49943,11 +49992,15 @@ function registerAgentCommands(program2) {
49943
49992
  source = `auto-generated (${agentIdFile})`;
49944
49993
  }
49945
49994
  const presence = getPresence(agent);
49995
+ const payload = buildWhoamiPayload(agent, source, presence);
49996
+ if (opts.json) {
49997
+ console.log(JSON.stringify(payload, null, 2));
49998
+ closeDb();
49999
+ return;
50000
+ }
49946
50001
  let onlineStatus;
49947
50002
  if (presence && presence.online) {
49948
- const lastSeenMs = new Date(presence.last_seen_at + "Z").getTime();
49949
- const agoMs = Date.now() - lastSeenMs;
49950
- const agoSec = Math.floor(agoMs / 1000);
50003
+ const agoSec = payload.last_seen_ago_seconds ?? 0;
49951
50004
  const agoStr = agoSec < 60 ? `${agoSec}s ago` : `${Math.floor(agoSec / 60)}m ago`;
49952
50005
  onlineStatus = chalk7.green(`yes`) + chalk7.dim(` (last seen ${agoStr})`);
49953
50006
  } else if (presence) {
package/bin/mcp.js CHANGED
@@ -42094,6 +42094,18 @@ function listProjects(opts) {
42094
42094
  params.push(opts.status);
42095
42095
  }
42096
42096
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
42097
+ let pagination = "";
42098
+ if (typeof opts?.limit === "number" && Number.isFinite(opts.limit) && opts.limit > 0) {
42099
+ pagination += " LIMIT ?";
42100
+ params.push(Math.floor(opts.limit));
42101
+ }
42102
+ if (typeof opts?.offset === "number" && Number.isFinite(opts.offset) && opts.offset >= 0) {
42103
+ if (!pagination.includes("LIMIT")) {
42104
+ pagination += " LIMIT -1";
42105
+ }
42106
+ pagination += " OFFSET ?";
42107
+ params.push(Math.floor(opts.offset));
42108
+ }
42097
42109
  const rows = db2.prepare(`
42098
42110
  SELECT
42099
42111
  p.*,
@@ -42101,6 +42113,7 @@ function listProjects(opts) {
42101
42113
  FROM projects p
42102
42114
  ${where}
42103
42115
  ORDER BY p.name ASC
42116
+ ${pagination}
42104
42117
  `).all(...params);
42105
42118
  return rows.map((row) => ({
42106
42119
  ...parseProject(row),
@@ -44256,7 +44269,7 @@ function registerTmuxTools(server) {
44256
44269
  // package.json
44257
44270
  var package_default = {
44258
44271
  name: "@hasna/conversations",
44259
- version: "0.2.32",
44272
+ version: "0.2.33",
44260
44273
  description: "Real-time CLI messaging for AI agents",
44261
44274
  type: "module",
44262
44275
  bin: {
@@ -1,2 +1,15 @@
1
1
  import type { Command } from "commander";
2
+ type PresenceView = {
3
+ online: boolean;
4
+ last_seen_at: string;
5
+ } | null;
6
+ export type WhoamiPayload = {
7
+ agent: string;
8
+ source: string;
9
+ online: boolean;
10
+ last_seen_at: string | null;
11
+ last_seen_ago_seconds: number | null;
12
+ };
13
+ export declare function buildWhoamiPayload(agent: string, source: string, presence: PresenceView, nowMs?: number): WhoamiPayload;
2
14
  export declare function registerAgentCommands(program: Command): void;
15
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,2 +1,3 @@
1
1
  import type { Command } from "commander";
2
+ export declare function requireDeleteConfirmation(confirmed?: boolean): void;
2
3
  export declare function registerProjectCommands(program: Command): void;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -12428,6 +12428,18 @@ function listProjects(opts) {
12428
12428
  params.push(opts.status);
12429
12429
  }
12430
12430
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
12431
+ let pagination = "";
12432
+ if (typeof opts?.limit === "number" && Number.isFinite(opts.limit) && opts.limit > 0) {
12433
+ pagination += " LIMIT ?";
12434
+ params.push(Math.floor(opts.limit));
12435
+ }
12436
+ if (typeof opts?.offset === "number" && Number.isFinite(opts.offset) && opts.offset >= 0) {
12437
+ if (!pagination.includes("LIMIT")) {
12438
+ pagination += " LIMIT -1";
12439
+ }
12440
+ pagination += " OFFSET ?";
12441
+ params.push(Math.floor(opts.offset));
12442
+ }
12431
12443
  const rows = db2.prepare(`
12432
12444
  SELECT
12433
12445
  p.*,
@@ -12435,6 +12447,7 @@ function listProjects(opts) {
12435
12447
  FROM projects p
12436
12448
  ${where}
12437
12449
  ORDER BY p.name ASC
12450
+ ${pagination}
12438
12451
  `).all(...params);
12439
12452
  return rows.map((row) => ({
12440
12453
  ...parseProject(row),
@@ -11,6 +11,8 @@ export declare function createProject(opts: {
11
11
  }): Project;
12
12
  export declare function listProjects(opts?: {
13
13
  status?: "active" | "archived";
14
+ limit?: number;
15
+ offset?: number;
14
16
  }): ProjectInfo[];
15
17
  export declare function getProject(id: string): ProjectInfo | null;
16
18
  export declare function getProjectByName(name: string): ProjectInfo | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.32",
3
+ "version": "0.2.33",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {