@agentprojectcontext/apx 1.6.0 → 1.8.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.
Files changed (41) hide show
  1. package/README.md +4 -0
  2. package/package.json +1 -1
  3. package/src/cli/commands/config.js +23 -0
  4. package/src/cli/commands/messages.js +45 -0
  5. package/src/cli/commands/routine.js +27 -2
  6. package/src/cli/commands/setup.js +2 -2
  7. package/src/cli/index.js +969 -3
  8. package/src/core/apc-context-skill.md +3 -0
  9. package/src/core/apx-skill.md +30 -0
  10. package/src/core/config.js +2 -0
  11. package/src/core/mascot.js +5 -7
  12. package/src/core/messages-store.js +94 -20
  13. package/src/core/routines-store.js +3 -1
  14. package/src/daemon/api.js +3 -3
  15. package/src/daemon/index.js +38 -2
  16. package/src/daemon/plugins/telegram.js +32 -2
  17. package/src/daemon/routines.js +64 -2
  18. package/src/daemon/super-agent-tools/helpers.js +120 -0
  19. package/src/daemon/super-agent-tools/index.js +56 -0
  20. package/src/daemon/super-agent-tools/tools/add-project.js +36 -0
  21. package/src/daemon/super-agent-tools/tools/call-agent.js +45 -0
  22. package/src/daemon/super-agent-tools/tools/call-mcp.js +30 -0
  23. package/src/daemon/super-agent-tools/tools/call-runtime.js +107 -0
  24. package/src/daemon/super-agent-tools/tools/edit-file.js +44 -0
  25. package/src/daemon/super-agent-tools/tools/import-agent.js +48 -0
  26. package/src/daemon/super-agent-tools/tools/list-agents.js +36 -0
  27. package/src/daemon/super-agent-tools/tools/list-files.js +38 -0
  28. package/src/daemon/super-agent-tools/tools/list-mcps.js +48 -0
  29. package/src/daemon/super-agent-tools/tools/list-projects.js +20 -0
  30. package/src/daemon/super-agent-tools/tools/list-vault-agents.js +18 -0
  31. package/src/daemon/super-agent-tools/tools/read-agent-memory.js +28 -0
  32. package/src/daemon/super-agent-tools/tools/read-file.js +33 -0
  33. package/src/daemon/super-agent-tools/tools/run-shell.js +86 -0
  34. package/src/daemon/super-agent-tools/tools/search-messages.js +34 -0
  35. package/src/daemon/super-agent-tools/tools/send-telegram.js +30 -0
  36. package/src/daemon/super-agent-tools/tools/set-identity.js +35 -0
  37. package/src/daemon/super-agent-tools/tools/set-permission-mode.js +32 -0
  38. package/src/daemon/super-agent-tools/tools/tail-messages.js +39 -0
  39. package/src/daemon/super-agent-tools/tools/write-file.js +33 -0
  40. package/src/daemon/super-agent-tools.js +1 -539
  41. package/src/daemon/super-agent.js +56 -7
package/README.md CHANGED
@@ -88,6 +88,7 @@ apx exec <slug> "<prompt>" # quick LLM call
88
88
 
89
89
  apx session list <slug> # list past sessions
90
90
  apx messages tail # last 50 messages, all channels
91
+ apx messages chat --channel telegram # chat view with user/agent/system type
91
92
  apx messages tail --channel runtime # only agent invocations
92
93
  ```
93
94
 
@@ -96,6 +97,9 @@ apx messages tail --channel runtime # only agent invocations
96
97
  Activity belongs to APX runtime state, not `.apc/`. Message storage is local to APX, under
97
98
  `~/.apx/`:
98
99
 
100
+ JSONL messages include `type` (`user`, `agent`, `tool`, or `system`) plus `actor_id`, so chat views
101
+ can distinguish Telegram users from APX agents and future subagents.
102
+
99
103
  | Channel | What it captures |
100
104
  |---------|-----------------|
101
105
  | `runtime` | `apx run` invocations (prompt in, response out) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentprojectcontext/apx",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "APX — unified CLI + daemon for the Agent Project Context (APC) standard.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,5 +1,6 @@
1
1
  import { http } from "../http.js";
2
2
  import { resolveProjectId } from "./project.js";
3
+ import { readConfig, writeConfig } from "../../core/config.js";
3
4
 
4
5
  function parseValue(raw) {
5
6
  // best-effort: try JSON first (covers numbers, bools, objects, arrays, null,
@@ -54,3 +55,25 @@ export async function cmdConfigUnset(args) {
54
55
  await http.patch(`/projects/${pid}/config`, { unset: [key] });
55
56
  console.log(`unset ${key}`);
56
57
  }
58
+
59
+ export function cmdPermission(args = {}) {
60
+ const sub = args._[0] || "show";
61
+ const cfg = readConfig();
62
+ cfg.super_agent = cfg.super_agent || {};
63
+ if (sub === "show" || sub === "get" || sub === "ls") {
64
+ console.log(`permission_mode=${cfg.super_agent.permission_mode || "automatico"}`);
65
+ console.log(`allowed_tools=${(cfg.super_agent.allowed_tools || []).join(",") || "(none)"}`);
66
+ return;
67
+ }
68
+ if (sub === "set") {
69
+ const mode = args._[1];
70
+ if (!["total", "automatico", "permiso"].includes(mode)) {
71
+ throw new Error("apx permissions set: mode must be total, automatico, or permiso");
72
+ }
73
+ cfg.super_agent.permission_mode = mode;
74
+ writeConfig(cfg);
75
+ console.log(`permission_mode=${mode}`);
76
+ return;
77
+ }
78
+ throw new Error(`unknown permissions subcommand: ${sub}`);
79
+ }
@@ -46,6 +46,51 @@ export async function cmdMessagesTail(args) {
46
46
  }
47
47
  }
48
48
 
49
+ function chatTimestamp(ts) {
50
+ if (!ts) return "????-??-?? ??:??:??";
51
+ return ts.replace("T", " ").replace(/Z$/, "");
52
+ }
53
+
54
+ function chatActor(row) {
55
+ const type = row.type || (row.direction === "in" ? "user" : "agent");
56
+ const who = row.author || row.actor_id || "";
57
+ return who ? `${type} ${who}` : type;
58
+ }
59
+
60
+ function printChatRows(rows) {
61
+ if (rows.length === 0) {
62
+ console.log("(no messages)");
63
+ return;
64
+ }
65
+ for (const r of rows) {
66
+ const body = String(r.body || "");
67
+ const lines = body.split("\n");
68
+ console.log(`[${chatTimestamp(r.ts)}] ${chatActor(r)}: ${lines[0] || ""}`);
69
+ for (const line of lines.slice(1)) console.log(` ${line}`);
70
+ }
71
+ }
72
+
73
+ export async function cmdMessagesChat(args) {
74
+ const channel = args.flags.channel && args.flags.channel !== true ? args.flags.channel : "telegram";
75
+ const n = args.flags.n || args.flags.last || "50";
76
+ const isGlobal = args.flags.global || isGlobalChannel(channel);
77
+
78
+ if (isGlobal) {
79
+ const params = new URLSearchParams({ limit: String(n) });
80
+ if (channel) params.set("channel", channel);
81
+ const rows = await http.get(`/messages/global?${params}`);
82
+ printChatRows(rows);
83
+ return;
84
+ }
85
+
86
+ const pid = await resolveProjectId(args?.flags?.project);
87
+ const params = new URLSearchParams({ limit: String(n) });
88
+ if (args.flags.agent && args.flags.agent !== true) params.set("agent", args.flags.agent);
89
+ if (channel) params.set("channel", channel);
90
+ const rows = await http.get(`/projects/${pid}/messages?${params}`);
91
+ printChatRows(rows.reverse());
92
+ }
93
+
49
94
  export async function cmdMessagesSearch(args) {
50
95
  const q = args._[0];
51
96
  if (!q) throw new Error("apx messages search: missing <query>");
@@ -12,7 +12,7 @@ function parseSpec(args) {
12
12
  }
13
13
  const spec = {};
14
14
  for (const [k, v] of Object.entries(args.flags)) {
15
- if (["name", "kind", "schedule", "spec", "verbose"].includes(k)) continue;
15
+ if (["name", "kind", "schedule", "spec", "verbose", "permission-mode", "allowed-tools"].includes(k)) continue;
16
16
  if (v === true) continue;
17
17
  // try to JSON-parse the value (numbers, bools), else keep as string
18
18
  let val = v;
@@ -59,8 +59,14 @@ export async function cmdRoutineAdd(args) {
59
59
  if (!kind || !schedule)
60
60
  throw new Error("apx routine add: --kind and --schedule are required");
61
61
  const spec = parseSpec(args);
62
+ const permission_mode = args.flags["permission-mode"] && args.flags["permission-mode"] !== true
63
+ ? args.flags["permission-mode"]
64
+ : undefined;
65
+ const allowed_tools = args.flags["allowed-tools"] && args.flags["allowed-tools"] !== true
66
+ ? String(args.flags["allowed-tools"]).split(",").map((s) => s.trim()).filter(Boolean)
67
+ : undefined;
62
68
  const pid = await resolveProjectId(args?.flags?.project);
63
- const r = await http.post(`/projects/${pid}/routines`, { name, kind, schedule, spec });
69
+ const r = await http.post(`/projects/${pid}/routines`, { name, kind, schedule, spec, permission_mode, allowed_tools });
64
70
  console.log(`added routine "${r.name}" (${r.kind}, ${r.schedule}) → next ${r.next_run_at}`);
65
71
  }
66
72
 
@@ -97,3 +103,22 @@ export async function cmdRoutineRun(args) {
97
103
  const r = await http.post(`/projects/${pid}/routines/${name}/run`);
98
104
  console.log(JSON.stringify(r, null, 2));
99
105
  }
106
+
107
+ export async function cmdRoutineHistory(args) {
108
+ const name = args._[0];
109
+ if (!name) throw new Error("apx routine history: missing <name>");
110
+ const pid = await resolveProjectId(args?.flags?.project);
111
+ const limit = args.flags.n || args.flags.last || "50";
112
+ const rows = await http.get(`/projects/${pid}/messages?channel=routine&limit=${encodeURIComponent(limit)}`);
113
+ const filtered = rows
114
+ .filter((r) => r.meta?.routine === name)
115
+ .reverse();
116
+ if (filtered.length === 0) {
117
+ console.log("(no routine history)");
118
+ return;
119
+ }
120
+ for (const r of filtered) {
121
+ const status = r.meta?.status ? ` ${r.meta.status}` : "";
122
+ console.log(`${r.ts}${status} ${r.author || ""}: ${r.body}`);
123
+ }
124
+ }
@@ -221,8 +221,8 @@ export async function cmdSetup() {
221
221
 
222
222
  cfg.super_agent.enabled = true;
223
223
  cfg.super_agent.model = chosenModel;
224
- // System prompt: language instruction only, no wizard references
225
- cfg.super_agent.system = `Always respond in the user's language: ${language}.`;
224
+ cfg.super_agent.system = "";
225
+ cfg.super_agent.permission_mode = cfg.super_agent.permission_mode || "automatico";
226
226
 
227
227
  if (provider.id === "ollama") {
228
228
  cfg.engines.ollama.base_url = ollamaUrl;