@agentprojectcontext/apx 1.47.0 → 1.48.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": "@agentprojectcontext/apx",
3
- "version": "1.47.0",
3
+ "version": "1.48.0",
4
4
  "description": "APX — unified CLI + daemon for the Agent Project Context (APC) standard.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -16,9 +16,13 @@ import { collectAllSessions } from "#interfaces/cli/commands/sessions.js";
16
16
 
17
17
  export function register(app, { projects, project }) {
18
18
  // Cross-engine sessions (apx · claude · codex), newest first.
19
+ // Paginated via ?limit & ?offset; the full count is returned in the
20
+ // X-Total-Count header so the UI can compute page counts. The body shape
21
+ // ({ sessions }) is unchanged for backward compatibility.
19
22
  app.get("/sessions", (req, res) => {
20
23
  const engineId = req.query.engine ? String(req.query.engine) : null;
21
24
  const limit = Math.min(parseInt(req.query.limit, 10) || 200, 1000);
25
+ const offset = Math.max(parseInt(req.query.offset, 10) || 0, 0);
22
26
  let rows = [];
23
27
  try {
24
28
  rows = collectAllSessions({}, { engineId });
@@ -26,7 +30,9 @@ export function register(app, { projects, project }) {
26
30
  return res.status(500).json({ error: e.message, sessions: [] });
27
31
  }
28
32
  rows.sort((a, b) => (b.mtime || 0) - (a.mtime || 0));
29
- res.json({ sessions: rows.slice(0, limit) });
33
+ res.set("X-Total-Count", String(rows.length));
34
+ res.set("Access-Control-Expose-Headers", "X-Total-Count");
35
+ res.json({ sessions: rows.slice(offset, offset + limit) });
30
36
  });
31
37
 
32
38
  app.get("/projects/:pid/agents/:slug/sessions", (req, res) => {
@@ -18,9 +18,14 @@ import {
18
18
  } from "#core/stores/tasks.js";
19
19
 
20
20
  export function register(app, { project, projects }) {
21
- // Global tasks across every project.
21
+ // Global tasks across every project, newest first. Paginated via
22
+ // ?limit & ?offset; X-Total-Count carries the full count. Body stays an
23
+ // array for backward compatibility (offset defaults to 0, so callers that
24
+ // omit pagination get the same first-N behavior).
22
25
  app.get("/tasks", (req, res) => {
23
26
  const state = req.query.state || "open";
27
+ const limit = req.query.limit ? Math.min(parseInt(req.query.limit, 10) || 0, 1000) : undefined;
28
+ const offset = Math.max(parseInt(req.query.offset, 10) || 0, 0);
24
29
  const out = [];
25
30
  for (const entry of projects.list()) {
26
31
  const p = projects.get(entry.id);
@@ -29,27 +34,32 @@ export function register(app, { project, projects }) {
29
34
  try {
30
35
  tasks = listTasks(p.storagePath, {
31
36
  state: state === "all" ? undefined : state,
32
- limit: 500,
33
37
  });
34
38
  } catch { /* skip project */ }
35
39
  for (const t of tasks) out.push({ ...t, project_id: entry.id, project_name: entry.name || entry.path });
36
40
  }
37
- res.json(out);
41
+ out.sort((a, b) => (b.created_at || "").localeCompare(a.created_at || ""));
42
+ res.set("X-Total-Count", String(out.length));
43
+ res.set("Access-Control-Expose-Headers", "X-Total-Count");
44
+ res.json(limit != null ? out.slice(offset, offset + limit) : out.slice(offset));
38
45
  });
39
46
 
40
47
  app.get("/projects/:pid/tasks", (req, res) => {
41
48
  const p = project(req, res);
42
49
  if (!p) return;
43
- const { state, tag, agent, due_before, due_after, limit } = req.query;
44
- const out = listTasks(p.storagePath, {
50
+ const { state, tag, agent, due_before, due_after } = req.query;
51
+ const limit = req.query.limit ? Math.min(parseInt(req.query.limit, 10) || 0, 1000) : undefined;
52
+ const offset = Math.max(parseInt(req.query.offset, 10) || 0, 0);
53
+ const all = listTasks(p.storagePath, {
45
54
  state: state || undefined,
46
55
  tag: tag || undefined,
47
56
  agent: agent || undefined,
48
57
  due_before: due_before || undefined,
49
58
  due_after: due_after || undefined,
50
- limit: limit ? Math.min(parseInt(limit, 10) || 0, 1000) : undefined,
51
59
  });
52
- res.json(out);
60
+ res.set("X-Total-Count", String(all.length));
61
+ res.set("Access-Control-Expose-Headers", "X-Total-Count");
62
+ res.json(limit != null ? all.slice(offset, offset + limit) : all.slice(offset));
53
63
  });
54
64
 
55
65
  app.post("/projects/:pid/tasks", (req, res) => {