@agentprojectcontext/apx 1.32.0 → 1.32.2

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 (219) hide show
  1. package/package.json +6 -1
  2. package/skills/apc-context/SKILL.md +5 -2
  3. package/skills/apx/SKILL.md +3 -3
  4. package/skills/apx-agency-agents/SKILL.md +5 -5
  5. package/skills/apx-agent/SKILL.md +7 -7
  6. package/skills/apx-mcp/SKILL.md +6 -4
  7. package/skills/apx-mcp-builder/SKILL.md +4 -7
  8. package/skills/apx-project/SKILL.md +4 -5
  9. package/skills/apx-routine/SKILL.md +14 -12
  10. package/skills/apx-runtime/SKILL.md +5 -3
  11. package/skills/apx-sessions/SKILL.md +5 -5
  12. package/skills/apx-skill-builder/SKILL.md +10 -6
  13. package/skills/apx-task/SKILL.md +8 -8
  14. package/skills/apx-telegram/SKILL.md +23 -7
  15. package/skills/apx-voice/SKILL.md +8 -6
  16. package/src/core/{agent-system.js → agent/build-agent-system.js} +10 -12
  17. package/src/core/agent/index.js +0 -2
  18. package/src/core/{agent-memory.js → agent/memory.js} +2 -2
  19. package/src/core/agent/model-router.js +21 -43
  20. package/src/core/agent/prompt-builder.js +17 -63
  21. package/src/core/agent/prompts/action-discipline.md +17 -0
  22. package/src/core/agent/prompts/channels/code.md +8 -12
  23. package/src/core/agent/prompts/channels/desktop.md +6 -4
  24. package/src/core/agent/prompts/channels/routine.md +10 -1
  25. package/src/core/agent/prompts/channels/telegram.md +5 -0
  26. package/src/core/agent/prompts/channels/web_code.md +20 -0
  27. package/src/core/agent/prompts/modes/voice.md +2 -2
  28. package/src/core/agent/prompts/super-agent-base.md +2 -2
  29. package/src/core/agent/run-agent.js +37 -35
  30. package/src/core/agent/runtime-bridge.js +42 -0
  31. package/src/core/agent/self-memory.js +19 -9
  32. package/src/core/agent/skills/catalog.js +65 -0
  33. package/src/core/agent/skills/index.js +6 -0
  34. package/src/{host/daemon/skills-loader.js → core/agent/skills/loader.js} +3 -3
  35. package/src/core/agent/skills/rag.js +91 -0
  36. package/src/core/agent/skills/trigger.js +71 -0
  37. package/src/{host/daemon → core/agent}/super-agent.js +5 -5
  38. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/add-project.js +3 -4
  39. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-agent.js +2 -2
  40. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-mcp.js +1 -2
  41. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-runtime.js +10 -11
  42. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/create-task.js +1 -1
  43. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/discover-tools.js +1 -1
  44. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/edit-file.js +1 -2
  45. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/import-agent.js +4 -5
  46. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-agents.js +1 -1
  47. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-skills.js +7 -2
  48. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-tasks.js +1 -1
  49. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-vault-agents.js +1 -1
  50. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/load-skill.js +1 -1
  51. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-agent-memory.js +1 -1
  52. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-self-memory.js +1 -1
  53. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/remember.js +1 -1
  54. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/run-shell.js +1 -2
  55. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-messages.js +1 -1
  56. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-sessions.js +1 -1
  57. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/send-telegram.js +0 -2
  58. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-identity.js +1 -3
  59. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-permission-mode.js +1 -3
  60. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/tail-messages.js +1 -1
  61. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/transcribe-audio.js +1 -1
  62. package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/write-file.js +1 -2
  63. package/src/core/agent/tools/helpers.js +74 -0
  64. package/src/{host/daemon/super-agent-tools → core/agent/tools}/registry-bridge.js +3 -3
  65. package/src/{host/daemon/super-agent-tools/index.js → core/agent/tools/registry.js} +31 -32
  66. package/src/core/apc/agents-vault.js +37 -0
  67. package/src/core/{scaffold.js → apc/scaffold.js} +4 -5
  68. package/src/core/{config.js → config/index.js} +21 -27
  69. package/src/core/config/paths.js +32 -0
  70. package/src/core/constants/actors.js +8 -0
  71. package/src/core/constants/channels.js +19 -0
  72. package/src/core/constants/index.js +5 -0
  73. package/src/core/constants/permissions.js +17 -0
  74. package/src/core/constants/roles.js +9 -0
  75. package/src/core/engines/_streaming.js +63 -0
  76. package/src/core/engines/anthropic.js +11 -22
  77. package/src/core/engines/ollama.js +7 -16
  78. package/src/core/identity/index.js +8 -0
  79. package/src/core/{identity.js → identity/self.js} +5 -5
  80. package/src/core/{telegram-identity.js → identity/telegram.js} +1 -1
  81. package/src/core/logging.js +1 -1
  82. package/src/core/mascot.js +1 -1
  83. package/src/core/memory/active-threads.js +10 -10
  84. package/src/core/memory/broker.js +9 -9
  85. package/src/core/memory/compactor.js +2 -2
  86. package/src/core/memory/index.js +2 -2
  87. package/src/core/memory/indexer.js +1 -1
  88. package/src/core/{code-sessions-store.js → stores/code-sessions.js} +3 -7
  89. package/src/core/{messages-store.js → stores/messages.js} +6 -4
  90. package/src/core/stores/routine-memory.js +71 -0
  91. package/src/core/{routines-store.js → stores/routines.js} +1 -3
  92. package/src/core/stores/runtime-sessions.js +99 -0
  93. package/src/core/{tasks-store.js → stores/tasks.js} +3 -8
  94. package/src/core/update-check.js +1 -1
  95. package/src/core/util/ids.js +14 -0
  96. package/src/core/util/index.js +2 -0
  97. package/src/core/util/text-similarity.js +52 -0
  98. package/src/core/util/time.js +9 -0
  99. package/src/core/voice/tts.js +1 -1
  100. package/src/host/daemon/api/admin-config.js +4 -3
  101. package/src/host/daemon/api/admin.js +1 -1
  102. package/src/host/daemon/api/agents.js +4 -25
  103. package/src/host/daemon/api/artifacts.js +1 -1
  104. package/src/host/daemon/api/code.js +48 -16
  105. package/src/host/daemon/api/confirm.js +1 -1
  106. package/src/host/daemon/api/connections.js +2 -2
  107. package/src/host/daemon/api/conversations.js +2 -2
  108. package/src/host/daemon/api/deck.js +1 -1
  109. package/src/host/daemon/api/desktop.js +1 -1
  110. package/src/host/daemon/api/embeddings.js +4 -4
  111. package/src/host/daemon/api/engines.js +2 -2
  112. package/src/host/daemon/api/exec.js +3 -3
  113. package/src/host/daemon/api/identity.js +1 -1
  114. package/src/host/daemon/api/mcps.js +1 -1
  115. package/src/host/daemon/api/messages.js +1 -1
  116. package/src/host/daemon/api/runtimes.js +9 -8
  117. package/src/host/daemon/api/sessions-search.js +1 -1
  118. package/src/host/daemon/api/sessions.js +2 -2
  119. package/src/host/daemon/api/shared.js +5 -4
  120. package/src/host/daemon/api/skills.js +30 -0
  121. package/src/host/daemon/api/super-agent.js +29 -9
  122. package/src/host/daemon/api/tasks.js +2 -2
  123. package/src/host/daemon/api/telegram.js +1 -1
  124. package/src/host/daemon/api/tools.js +6 -6
  125. package/src/host/daemon/api/tts.js +2 -2
  126. package/src/host/daemon/api/voice.js +14 -12
  127. package/src/host/daemon/api.js +2 -0
  128. package/src/host/daemon/compact.js +1 -1
  129. package/src/host/daemon/db.js +4 -4
  130. package/src/host/daemon/desktop-ws.js +1 -1
  131. package/src/host/daemon/index.js +4 -4
  132. package/src/host/daemon/plugins/{desktop.js → desktop/index.js} +11 -6
  133. package/src/host/daemon/plugins/index.js +2 -2
  134. package/src/host/daemon/plugins/{telegram.js → telegram/index.js} +66 -195
  135. package/src/host/daemon/plugins/telegram/media.js +162 -0
  136. package/src/host/daemon/projects-helpers.js +54 -0
  137. package/src/host/daemon/routines.js +28 -12
  138. package/src/host/daemon/smoke.js +2 -2
  139. package/src/host/daemon/token-store.js +1 -1
  140. package/src/host/daemon/transcription.js +2 -2
  141. package/src/host/daemon/wakeup.js +2 -2
  142. package/src/interfaces/cli/commands/agent.js +3 -3
  143. package/src/interfaces/cli/commands/command.js +1 -1
  144. package/src/interfaces/cli/commands/config.js +3 -2
  145. package/src/interfaces/cli/commands/desktop.js +1 -1
  146. package/src/interfaces/cli/commands/exec.js +2 -1
  147. package/src/interfaces/cli/commands/identity.js +2 -2
  148. package/src/interfaces/cli/commands/init.js +1 -1
  149. package/src/interfaces/cli/commands/mcp.js +1 -1
  150. package/src/interfaces/cli/commands/memory.js +2 -2
  151. package/src/interfaces/cli/commands/model.js +16 -6
  152. package/src/interfaces/cli/commands/project.js +1 -1
  153. package/src/interfaces/cli/commands/routine.js +58 -0
  154. package/src/interfaces/cli/commands/search.js +1 -1
  155. package/src/interfaces/cli/commands/session.js +4 -4
  156. package/src/interfaces/cli/commands/setup.js +4 -3
  157. package/src/interfaces/cli/commands/skills.js +25 -4
  158. package/src/interfaces/cli/commands/status.js +1 -1
  159. package/src/interfaces/cli/commands/sys.js +11 -4
  160. package/src/interfaces/cli/commands/update.js +1 -1
  161. package/src/interfaces/cli/index.js +4 -4
  162. package/src/interfaces/cli/postinstall.js +2 -2
  163. package/src/interfaces/mcp-server/index.js +1 -1
  164. package/src/interfaces/tui/component/prompt/index.tsx +3 -1
  165. package/src/interfaces/tui/context/sdk-apx.tsx +47 -7
  166. package/src/interfaces/tui/context/sync-apx.tsx +20 -2
  167. package/src/interfaces/tui/context/sync.tsx +2 -1
  168. package/src/interfaces/tui/routes/session/index.tsx +151 -136
  169. package/src/interfaces/tui/routes/session/sidebar-apx.tsx +37 -15
  170. package/src/interfaces/tui/run.ts +2 -0
  171. package/src/interfaces/web/dist/assets/index-34U_Mp1M.css +1 -0
  172. package/src/interfaces/web/dist/assets/index-BkybwwRn.js +570 -0
  173. package/src/interfaces/web/dist/assets/index-BkybwwRn.js.map +1 -0
  174. package/src/interfaces/web/dist/index.html +2 -2
  175. package/src/interfaces/web/package-lock.json +3 -3
  176. package/src/interfaces/web/src/App.tsx +51 -32
  177. package/src/interfaces/web/src/components/RobyBubble.tsx +12 -6
  178. package/src/interfaces/web/src/components/UiSelect.tsx +1 -1
  179. package/src/interfaces/web/src/components/chat/SkillPicker.tsx +77 -0
  180. package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +1 -1
  181. package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -18
  182. package/src/interfaces/web/src/components/common/TabLayout.tsx +9 -5
  183. package/src/interfaces/web/src/components/common/TabNav.tsx +3 -3
  184. package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +4 -2
  185. package/src/interfaces/web/src/hooks/useChat.ts +47 -2
  186. package/src/interfaces/web/src/hooks/useNavCollapseCtx.tsx +59 -0
  187. package/src/interfaces/web/src/hooks/usePersonaName.ts +11 -0
  188. package/src/interfaces/web/src/i18n/en.ts +7 -7
  189. package/src/interfaces/web/src/i18n/es.ts +7 -7
  190. package/src/interfaces/web/src/lib/api/skills.ts +25 -0
  191. package/src/interfaces/web/src/lib/api.ts +1 -0
  192. package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +18 -18
  193. package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +5 -18
  194. package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +1 -8
  195. package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +39 -40
  196. package/src/interfaces/web/src/screens/project/ChatTab.tsx +12 -9
  197. package/src/skills/apc-context/SKILL.md +159 -0
  198. package/src/core/agent/ghost-guard.js +0 -24
  199. package/src/core/agent/prompts/channels/terminal.md +0 -16
  200. package/src/host/daemon/apc-runtime-context.js +0 -124
  201. package/src/host/daemon/super-agent-tools/helpers.js +0 -124
  202. package/src/host/daemon/tool-call-parser.js +0 -2
  203. package/src/interfaces/web/dist/assets/index-63P_ji1a.js +0 -571
  204. package/src/interfaces/web/dist/assets/index-63P_ji1a.js.map +0 -1
  205. package/src/interfaces/web/dist/assets/index-DLWy6dYz.css +0 -1
  206. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/ask-questions.js +0 -0
  207. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-files.js +0 -0
  208. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-mcps.js +0 -0
  209. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-projects.js +0 -0
  210. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-file.js +0 -0
  211. /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-files.js +0 -0
  212. /package/src/core/agent/{pseudo-tools.js → tools/pseudo-tools.js} +0 -0
  213. /package/src/core/agent/{tool-call-parser.js → tools/tool-call-parser.js} +0 -0
  214. /package/src/core/{parser.js → apc/parser.js} +0 -0
  215. /package/src/core/{apc-skill-sync.js → apc/skill-sync.js} +0 -0
  216. /package/src/core/{artifacts-store.js → stores/artifacts.js} +0 -0
  217. /package/src/{host/daemon → core/stores}/engine-sessions.js +0 -0
  218. /package/src/core/{session-store.js → stores/sessions.js} +0 -0
  219. /package/src/host/daemon/plugins/{telegram-ask.js → telegram/ask.js} +0 -0
@@ -0,0 +1,54 @@
1
+ // Helpers that need the running daemon's projects registry to do their work
2
+ // (projectMeta + resolveProject). Pure / config-only helpers live in
3
+ // core/agent/tools/helpers.js.
4
+ import path from "node:path";
5
+
6
+ export function projectMeta(projects, entry) {
7
+ const meta = projects.list().find((p) => p.id === entry.id);
8
+ return {
9
+ id: entry.id,
10
+ name: meta?.name || path.basename(entry.path),
11
+ path: entry.path,
12
+ };
13
+ }
14
+
15
+ export function resolveProject(projects, target, { allowMulti = false } = {}) {
16
+ if (target === undefined || target === null || target === "") {
17
+ if (allowMulti) return null;
18
+ const defaultProject = projects.get(0);
19
+ if (defaultProject) return defaultProject;
20
+ const all = projects.list();
21
+ if (all.length === 1) return projects.get(all[0].id);
22
+ throw new Error(`multiple projects registered (${all.length}); specify project=<id|name|path>`);
23
+ }
24
+
25
+ const tgt = String(target);
26
+ if (tgt.toLowerCase() === "default") {
27
+ const defaultProject = projects.get(0);
28
+ if (!defaultProject) throw new Error("default project not available");
29
+ return defaultProject;
30
+ }
31
+
32
+ if (typeof target === "number" || /^\d+$/.test(tgt)) {
33
+ const entry = projects.get(parseInt(tgt, 10));
34
+ if (!entry) throw new Error(`project id ${target} not found`);
35
+ return entry;
36
+ }
37
+
38
+ const all = projects.list();
39
+ const byPath = all.find((p) => p.path === path.resolve(tgt));
40
+ if (byPath) return projects.get(byPath.id);
41
+
42
+ const byName = all.find((p) => p.name === tgt);
43
+ if (byName) return projects.get(byName.id);
44
+
45
+ const tgtLow = tgt.toLowerCase();
46
+ const fuzzy = all.filter(
47
+ (p) => p.name.toLowerCase().includes(tgtLow) || p.path.toLowerCase().includes(tgtLow)
48
+ );
49
+ if (fuzzy.length === 1) return projects.get(fuzzy[0].id);
50
+ if (fuzzy.length > 1) {
51
+ throw new Error(`project "${tgt}" is ambiguous; matches: ${fuzzy.map((p) => p.name).join(", ")}`);
52
+ }
53
+ throw new Error(`project "${tgt}" not found`);
54
+ }
@@ -15,13 +15,15 @@ import { execFile } from "node:child_process";
15
15
  import os from "node:os";
16
16
  import fs from "node:fs";
17
17
  import path from "node:path";
18
- import { callEngine } from "../../core/engines/index.js";
19
- import { runSuperAgent } from "./super-agent.js";
20
- import { computeSuppressedTools } from "../../core/agent/index.js";
21
- import { readAgents } from "../../core/parser.js";
22
- import { buildAgentSystem } from "../../core/agent-system.js";
23
- import { resolveAgentName, SUPERAGENT_ACTOR_ID } from "../../core/identity.js";
24
- import { resolveArtifactRef, ARTIFACTS_SKIP_SIGNAL } from "../../core/artifacts-store.js";
18
+ import { callEngine } from "#core/engines/index.js";
19
+ import { runSuperAgent } from "#core/agent/super-agent.js";
20
+ import { computeSuppressedTools } from "#core/agent/index.js";
21
+ import { readAgents } from "#core/apc/parser.js";
22
+ import { buildAgentSystem } from "#core/agent/build-agent-system.js";
23
+ import { resolveAgentName, SUPERAGENT_ACTOR_ID } from "#core/identity/index.js";
24
+ import { resolveArtifactRef, ARTIFACTS_SKIP_SIGNAL } from "#core/stores/artifacts.js";
25
+ import { ensureRoutineMemory, readRoutineMemoryForPrompt, routineMemoryPath } from "#core/stores/routine-memory.js";
26
+ import { CHANNELS } from "#core/constants/channels.js";
25
27
  import {
26
28
  listRoutines,
27
29
  getRoutine,
@@ -32,7 +34,7 @@ import {
32
34
  getDueRoutines,
33
35
  parseSchedule,
34
36
  computeNextRun,
35
- } from "../../core/routines-store.js";
37
+ } from "#core/stores/routines.js";
36
38
 
37
39
  export {
38
40
  listRoutines,
@@ -89,7 +91,7 @@ async function handleExecAgent(ctx, routine) {
89
91
 
90
92
  project.logMessage({
91
93
  agent_slug: slug,
92
- channel: "routine",
94
+ channel: CHANNELS.ROUTINE,
93
95
  direction: "out",
94
96
  type: "agent",
95
97
  actor_id: slug,
@@ -129,16 +131,30 @@ async function handleSuperAgent(ctx, routine) {
129
131
  plugins,
130
132
  registries,
131
133
  prompt,
132
- channel: "routine",
134
+ channel: CHANNELS.ROUTINE,
133
135
  channelMeta: {
134
136
  routineName: routine.name,
137
+ routineId: routine.id || "",
138
+ routineSchedule: routine.schedule || "",
139
+ routineLastRun: routine.last_run || "",
140
+ routineMemoryPath: (() => {
141
+ try {
142
+ ensureRoutineMemory(project.storagePath || project.path, routine.id, routine.name);
143
+ return routineMemoryPath(project.storagePath || project.path, routine.id);
144
+ } catch { return ""; }
145
+ })(),
146
+ routineMemory: (() => {
147
+ try {
148
+ return readRoutineMemoryForPrompt(project.storagePath || project.path, routine.id);
149
+ } catch { return ""; }
150
+ })(),
135
151
  projectPath: project.path,
136
152
  },
137
153
  suppressTools: suppressTools.length > 0 ? suppressTools : null,
138
154
  });
139
155
 
140
156
  project.logMessage({
141
- channel: "routine",
157
+ channel: CHANNELS.ROUTINE,
142
158
  direction: "out",
143
159
  type: "agent",
144
160
  actor_id: SUPERAGENT_ACTOR_ID,
@@ -346,7 +362,7 @@ export async function runRoutineNow(ctx, routine) {
346
362
  disable: isOnce,
347
363
  });
348
364
  ctx.project.logMessage?.({
349
- channel: "routine",
365
+ channel: CHANNELS.ROUTINE,
350
366
  direction: "out",
351
367
  type: "system",
352
368
  actor_id: "apx:routine",
@@ -8,8 +8,8 @@ import path from "node:path";
8
8
  import fs from "node:fs";
9
9
  import { fileURLToPath } from "node:url";
10
10
  import { ProjectManager } from "./db.js";
11
- import { McpRegistry } from "../../core/mcp/runner.js";
12
- import { readAgents } from "../../core/parser.js";
11
+ import { McpRegistry } from "#core/mcp/runner.js";
12
+ import { readAgents } from "#core/apc/parser.js";
13
13
 
14
14
  const __filename = fileURLToPath(import.meta.url);
15
15
  const __dirname = path.dirname(__filename);
@@ -23,7 +23,7 @@
23
23
  import fs from "node:fs";
24
24
  import path from "node:path";
25
25
  import { randomBytes, randomUUID, createHash } from "node:crypto";
26
- import { APX_HOME } from "../../core/config.js";
26
+ import { APX_HOME } from "#core/config/index.js";
27
27
 
28
28
  export const CLIENTS_PATH = path.join(APX_HOME, "clients.json");
29
29
 
@@ -30,7 +30,7 @@ import fs from "node:fs";
30
30
  import path from "node:path";
31
31
  import { spawn, exec } from "node:child_process";
32
32
  import { fileURLToPath } from "node:url";
33
- import { logInfo, logWarn, logError } from "../../core/logging.js";
33
+ import { logInfo, logWarn, logError } from "#core/logging.js";
34
34
 
35
35
  const __filename = fileURLToPath(import.meta.url);
36
36
  const __dirname = path.dirname(__filename);
@@ -76,7 +76,7 @@ export function resolveTranscriptionLanguage(localCfg, userLang) {
76
76
 
77
77
  async function getConfig() {
78
78
  try {
79
- const { readConfig } = await import("../core/config.js");
79
+ const { readConfig } = await import("#core/config/index.js");
80
80
  const cfg = readConfig() || {};
81
81
  const t = cfg.transcription || {};
82
82
  const openaiKey = cfg.engines?.openai?.api_key || process.env.OPENAI_API_KEY || "";
@@ -1,7 +1,7 @@
1
1
  // Wake-up message — sent via Telegram once per daemon restart (with cooldown).
2
2
  import fetch from "node-fetch";
3
- import { readIdentity, writeIdentity } from "../../core/identity.js";
4
- import { resolveProvider, getAdapter } from "../../core/engines/index.js";
3
+ import { readIdentity, writeIdentity } from "#core/identity/index.js";
4
+ import { resolveProvider, getAdapter } from "#core/engines/index.js";
5
5
 
6
6
  const WAKEUP_COOLDOWN_MS = 30 * 60 * 1000; // 30 min
7
7
 
@@ -1,8 +1,8 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { findApfRoot, readAgents, readVaultAgents, readVaultAgent, VAULT_DIR, SLUG_RE } from "../../../core/parser.js";
4
- import { writeAgentFile, writeVaultAgentFile, removeVaultAgent, restoreVaultAgent, addImportedAgent, ensureAgentDir } from "../../../core/scaffold.js";
5
- import { ensureAgentRuntimeDir, agentMemoryPath } from "../../../core/agent-memory.js";
3
+ import { findApfRoot, readAgents, readVaultAgents, readVaultAgent, VAULT_DIR, SLUG_RE } from "#core/apc/parser.js";
4
+ import { writeAgentFile, writeVaultAgentFile, removeVaultAgent, restoreVaultAgent, addImportedAgent, ensureAgentDir } from "#core/apc/scaffold.js";
5
+ import { ensureAgentRuntimeDir, agentMemoryPath } from "#core/agent/memory.js";
6
6
  import { http } from "../http.js";
7
7
 
8
8
  // ── ANSI ──────────────────────────────────────────────────────────────────────
@@ -1,7 +1,7 @@
1
1
  // apx command — list and show workflow commands from .apc/commands/
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
- import { findApfRoot } from "../../../core/parser.js";
4
+ import { findApfRoot } from "#core/apc/parser.js";
5
5
  import { http } from "../http.js";
6
6
  import { resolveProjectId } from "./project.js";
7
7
 
@@ -1,6 +1,7 @@
1
1
  import { http } from "../http.js";
2
2
  import { resolveProjectId } from "./project.js";
3
- import { readConfig, writeConfig } from "../../../core/config.js";
3
+ import { readConfig, writeConfig } from "#core/config/index.js";
4
+ import { PERMISSION_MODES, DEFAULT_PERMISSION_MODE } from "#core/constants/permissions.js";
4
5
 
5
6
  function parseValue(raw) {
6
7
  // best-effort: try JSON first (covers numbers, bools, objects, arrays, null,
@@ -61,7 +62,7 @@ export function cmdPermission(args = {}) {
61
62
  const cfg = readConfig();
62
63
  cfg.super_agent = cfg.super_agent || {};
63
64
  if (sub === "show" || sub === "get" || sub === "ls") {
64
- console.log(`permission_mode=${cfg.super_agent.permission_mode || "automatico"}`);
65
+ console.log(`permission_mode=${cfg.super_agent.permission_mode || DEFAULT_PERMISSION_MODE}`);
65
66
  console.log(`allowed_tools=${(cfg.super_agent.allowed_tools || []).join(",") || "(none)"}`);
66
67
  return;
67
68
  }
@@ -15,7 +15,7 @@ import {
15
15
  LINUX_DESKTOP_PATH,
16
16
  WIN_RUN_KEY,
17
17
  WIN_RUN_NAME,
18
- } from "../../../core/desktop/autostart.js";
18
+ } from "#core/desktop/autostart.js";
19
19
 
20
20
  // Re-exports — kept so existing tests (tests/desktop-autostart.test.js)
21
21
  // can still import these directly from the CLI module.
@@ -1,5 +1,6 @@
1
1
  import { http } from "../http.js";
2
2
  import { resolveProjectId } from "./project.js";
3
+ import { CHANNELS } from "#core/constants/channels.js";
3
4
 
4
5
  /**
5
6
  * Resolve exec target from CLI args.
@@ -63,7 +64,7 @@ export async function cmdExec(args) {
63
64
  const pid = await resolveProjectId(args?.flags?.project);
64
65
  const body = {
65
66
  prompt,
66
- channel: "cli",
67
+ channel: CHANNELS.CLI,
67
68
  channelMeta: { cwd: process.cwd() },
68
69
  };
69
70
  if (args.flags.model && args.flags.model !== true) body.model = args.flags.model;
@@ -1,5 +1,5 @@
1
1
  import readline from "node:readline";
2
- import { readIdentity, writeIdentity } from "../../../core/identity.js";
2
+ import { readIdentity, writeIdentity } from "#core/identity/index.js";
3
3
 
4
4
  function ask(rl, question, defaultVal) {
5
5
  return new Promise((resolve) => {
@@ -22,7 +22,7 @@ export async function cmdIdentity(args) {
22
22
  console.log("No identity configured. Run: apx identity wizard");
23
23
  return;
24
24
  }
25
- const { readConfig } = await import("../../../core/config.js");
25
+ const { readConfig } = await import("#core/config/index.js");
26
26
  const cfg = readConfig();
27
27
  console.log("");
28
28
  console.log(` Agent name : ${id.agent_name}`);
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { initApf } from "../../../core/scaffold.js";
2
+ import { initApf } from "#core/apc/scaffold.js";
3
3
 
4
4
  export function cmdInit(args) {
5
5
  const dir = args._[0] || ".";
@@ -1,6 +1,6 @@
1
1
  import { http } from "../http.js";
2
2
  import { resolveProjectId } from "./project.js";
3
- import { findApfRoot } from "../../../core/parser.js";
3
+ import { findApfRoot } from "#core/apc/parser.js";
4
4
 
5
5
  const VALID_SCOPES = new Set(["shared", "runtime", "global", "all"]);
6
6
 
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs";
2
- import { findApfRoot } from "../../../core/parser.js";
3
- import { agentMemoryPath, readAgentMemory, writeAgentMemory, ensureAgentRuntimeDir } from "../../../core/agent-memory.js";
2
+ import { findApfRoot } from "#core/apc/parser.js";
3
+ import { agentMemoryPath, readAgentMemory, writeAgentMemory, ensureAgentRuntimeDir } from "#core/agent/memory.js";
4
4
  import { http } from "../http.js";
5
5
 
6
6
  function requireRoot() {
@@ -1,11 +1,22 @@
1
- import { readConfig, writeConfig } from "../../../core/config.js";
1
+ import { readConfig, writeConfig } from "#core/config/index.js";
2
2
  import {
3
3
  probeAllProviders,
4
4
  resolveActiveModel,
5
- fallbackOrder,
6
- modelForProvider,
5
+ fallbackModels,
6
+ parseModelId,
7
7
  DEFAULT_FALLBACK_ORDER,
8
- } from "../../../core/agent/model-router.js";
8
+ } from "#core/agent/model-router.js";
9
+
10
+ function providersFromFallback(cfg) {
11
+ const seen = [];
12
+ for (const m of fallbackModels(cfg)) {
13
+ try {
14
+ const p = parseModelId(m).provider;
15
+ if (!seen.includes(p)) seen.push(p);
16
+ } catch { /* skip malformed */ }
17
+ }
18
+ return seen.length ? seen : [...DEFAULT_FALLBACK_ORDER];
19
+ }
9
20
 
10
21
  function parseValue(raw) {
11
22
  try {
@@ -56,7 +67,7 @@ export async function cmdModel(args = {}) {
56
67
  console.log("Model router");
57
68
  console.log(` primary: ${cfg.super_agent.model || "(not set)"}`);
58
69
  console.log(` fallback: ${cfg.super_agent.model_fallback.enabled !== false ? "on" : "off"}`);
59
- console.log(` order: ${fallbackOrder(cfg).join(" → ")}`);
70
+ console.log(` order: ${providersFromFallback(cfg).join(" → ")}`);
60
71
  if (active) {
61
72
  console.log(` active: ${active.modelId}${active.fromFallback ? " (fallback)" : ""}`);
62
73
  }
@@ -133,4 +144,3 @@ export async function cmdModel(args = {}) {
133
144
  throw new Error(`unknown model subcommand: ${sub}. Try: status | order | key | set | test | enable | disable`);
134
145
  }
135
146
 
136
- export { modelForProvider, fallbackOrder };
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { findApfRoot } from "../../../core/parser.js";
2
+ import { findApfRoot } from "#core/apc/parser.js";
3
3
  import { http } from "../http.js";
4
4
 
5
5
  function requireRoot() {
@@ -1,5 +1,14 @@
1
+ import fs from "node:fs";
1
2
  import { http } from "../http.js";
2
3
  import { resolveProjectId } from "./project.js";
4
+ import { listRoutines } from "#core/stores/routines.js";
5
+ import { projectStorageRoot } from "#core/config/index.js";
6
+ import {
7
+ routineMemoryPath,
8
+ readRoutineMemory,
9
+ appendRoutineMemory,
10
+ ensureRoutineMemory,
11
+ } from "#core/stores/routine-memory.js";
3
12
 
4
13
  function parseSpec(args) {
5
14
  // Build spec from --spec '<json>' or from --K=V pairs
@@ -120,6 +129,55 @@ export async function cmdRoutineRun(args) {
120
129
  console.log(JSON.stringify(r, null, 2));
121
130
  }
122
131
 
132
+ // Resolve a routine by name OR id to its { id, name, storagePath } so the
133
+ // memory subcommand accepts either argument transparently.
134
+ async function resolveRoutineRef(pid, refRaw) {
135
+ const ref = String(refRaw || "").trim();
136
+ if (!ref) throw new Error("missing <name|id>");
137
+ const projects = await http.get("/projects");
138
+ const project = projects.find((p) => String(p.id) === String(pid));
139
+ if (!project) throw new Error(`project #${pid} not found`);
140
+ const storagePath = project.storage_path || projectStorageRoot(project.apx_id);
141
+ const routines = listRoutines(storagePath);
142
+ const match = routines.find((r) => r.id === ref || r.name === ref);
143
+ if (!match) throw new Error(`routine "${ref}" not found in project #${pid}`);
144
+ return { id: match.id, name: match.name, storagePath };
145
+ }
146
+
147
+ export async function cmdRoutineMemory(args) {
148
+ const sub = args._[0];
149
+ const ref = args._[1];
150
+ const pid = await resolveProjectId(args?.flags?.project);
151
+
152
+ if (!sub || (sub !== "show" && sub !== "add" && sub !== "path")) {
153
+ throw new Error("usage: apx routine memory <show|add|path> <name|id> [note]");
154
+ }
155
+
156
+ const { id, name, storagePath } = await resolveRoutineRef(pid, ref);
157
+ const file = routineMemoryPath(storagePath, id);
158
+
159
+ if (sub === "path") {
160
+ console.log(file);
161
+ return;
162
+ }
163
+ if (sub === "show") {
164
+ ensureRoutineMemory(storagePath, id, name);
165
+ const body = readRoutineMemory(storagePath, id);
166
+ if (!body.trim()) {
167
+ console.log(`(empty — ${file})`);
168
+ return;
169
+ }
170
+ process.stdout.write(body);
171
+ if (!body.endsWith("\n")) console.log("");
172
+ return;
173
+ }
174
+ // add
175
+ const note = args._.slice(2).join(" ").trim();
176
+ if (!note) throw new Error("apx routine memory add: missing <note>");
177
+ const result = appendRoutineMemory(storagePath, id, note, { routineName: name });
178
+ console.log(`appended to ${result.path}`);
179
+ }
180
+
123
181
  export async function cmdRoutineHistory(args) {
124
182
  const name = args._[0];
125
183
  if (!name) throw new Error("apx routine history: missing <name>");
@@ -3,7 +3,7 @@
3
3
  // Uses the daemon's tools/search.js module directly (no HTTP roundtrip,
4
4
  // no need to have `apx daemon start` running).
5
5
 
6
- import { webSearch } from "../../../core/tools/search.js";
6
+ import { webSearch } from "#core/tools/search.js";
7
7
 
8
8
  const DIM = "\x1b[2m";
9
9
  const BOLD = "\x1b[1m";
@@ -1,10 +1,10 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { spawn } from "node:child_process";
4
- import { findApfRoot, readAgents } from "../../../core/parser.js";
5
- import { getOrCreateApxId } from "../../../core/scaffold.js";
6
- import { generateSessionId } from "../../../core/session-store.js";
7
- import { projectStorageRoot, ensureProjectStorage } from "../../../core/config.js";
4
+ import { findApfRoot, readAgents } from "#core/apc/parser.js";
5
+ import { getOrCreateApxId } from "#core/apc/scaffold.js";
6
+ import { generateSessionId } from "#core/stores/sessions.js";
7
+ import { projectStorageRoot, ensureProjectStorage } from "#core/config/index.js";
8
8
  import { http } from "../http.js";
9
9
  import { resolveProjectId } from "./project.js";
10
10
  import {
@@ -7,9 +7,10 @@ import https from "node:https";
7
7
  import http from "node:http";
8
8
  import readline from "node:readline";
9
9
  import { spawnSync } from "node:child_process";
10
- import { readConfig, writeConfig } from "../../../core/config.js";
11
- import { mascot } from "../../../core/mascot.js";
10
+ import { readConfig, writeConfig } from "#core/config/index.js";
11
+ import { mascot } from "#core/mascot.js";
12
12
  import { setupClaudePermissions } from "../claude-permissions.js";
13
+ import { PERMISSION_MODES, DEFAULT_PERMISSION_MODE } from "#core/constants/permissions.js";
13
14
 
14
15
  // ── ANSI helpers ──────────────────────────────────────────────────────────────
15
16
  const c = {
@@ -295,7 +296,7 @@ export async function cmdSetup() {
295
296
  cfg.super_agent.enabled = true;
296
297
  cfg.super_agent.model = chosenModel;
297
298
  cfg.super_agent.system = "";
298
- cfg.super_agent.permission_mode = cfg.super_agent.permission_mode || "automatico";
299
+ cfg.super_agent.permission_mode = cfg.super_agent.permission_mode || DEFAULT_PERMISSION_MODE;
299
300
 
300
301
  if (provider.id === "ollama") {
301
302
  cfg.engines.ollama.base_url = ollamaUrl;
@@ -3,14 +3,15 @@ import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import os from "node:os";
5
5
  import readline from "node:readline";
6
- import { findApfRoot } from "../../../core/parser.js";
6
+ import { findApfRoot } from "#core/apc/parser.js";
7
+ import { http } from "../http.js";
7
8
  import {
8
9
  IDE_TARGETS,
9
10
  installIdeSkills,
10
11
  installGlobalSkills,
11
12
  listBundledSkillSlugs,
12
13
  listBundledSkills,
13
- } from "../../../core/scaffold.js";
14
+ } from "#core/apc/scaffold.js";
14
15
 
15
16
  // ---------------------------------------------------------------------------
16
17
  // Prompt helper
@@ -182,7 +183,27 @@ export async function cmdSkillsSync(args) {
182
183
  // apx skills list
183
184
  // ---------------------------------------------------------------------------
184
185
 
185
- export async function cmdSkillsList() {
186
+ export async function cmdSkillsList(args = {}) {
187
+ // --all queries the daemon, which returns project + global + bundled +
188
+ // runtime-skills (same catalog the super-agent sees and the web picker uses).
189
+ // Without --all we only list `.apc/skills/` (what the user installed in
190
+ // THIS project), matching the historical behaviour.
191
+ if (args?.flags?.all) {
192
+ const root = findApfRoot();
193
+ const params = root ? `?project_path=${encodeURIComponent(root)}` : "";
194
+ const out = await http.get(`/skills${params}`);
195
+ if (!out.count) {
196
+ console.log("(no skills available)");
197
+ return;
198
+ }
199
+ console.log(`SLUG`.padEnd(28) + "SOURCE".padEnd(10) + "DESCRIPTION");
200
+ for (const s of out.skills) {
201
+ const desc = (s.description || "").slice(0, 70);
202
+ console.log(s.slug.padEnd(28) + (s.source || "?").padEnd(10) + desc);
203
+ }
204
+ return;
205
+ }
206
+
186
207
  const root = findApfRoot();
187
208
  const skillsDir = root ? path.join(root, ".apc", "skills") : null;
188
209
  const files = skillsDir && fs.existsSync(skillsDir)
@@ -190,7 +211,7 @@ export async function cmdSkillsList() {
190
211
  : [];
191
212
 
192
213
  if (files.length === 0) {
193
- console.log("(no skills installed in .apc/skills/)");
214
+ console.log("(no skills installed in .apc/skills/ — try `apx skills list --all` for the full catalog)");
194
215
  return;
195
216
  }
196
217
  for (const f of files) console.log(f.replace(/\.md$/, ""));
@@ -1,7 +1,7 @@
1
1
  // apx status — show full system status at a glance.
2
2
  // Daemon, super-agent, engines, telegram, projects.
3
3
 
4
- import { readConfig } from "../../../core/config.js";
4
+ import { readConfig } from "#core/config/index.js";
5
5
  import { http } from "../http.js";
6
6
 
7
7
  const R = "\x1b[0m";
@@ -1,8 +1,9 @@
1
1
  import readline from "node:readline";
2
2
  import { http } from "../http.js";
3
3
  import { resolveProjectId } from "./project.js";
4
- import { readConfig } from "../../../core/config.js";
5
- import { readIdentity } from "../../../core/identity.js";
4
+ import { readConfig } from "#core/config/index.js";
5
+ import { readIdentity } from "#core/identity/index.js";
6
+ import { CHANNELS } from "#core/constants/channels.js";
6
7
  import {
7
8
  C,
8
9
  MODES,
@@ -40,12 +41,18 @@ export async function cmdSys(args) {
40
41
  // Launch new Solid.js TUI via bun (runs TS source directly — no esbuild bundle needed)
41
42
  if (existsSync(TUI_SRC)) {
42
43
  const bunBin = process.env.BUN_PATH || "bun";
44
+ // bun must resolve node_modules/tsconfig from the apx package root, so the
45
+ // spawn cwd stays there — but we pass the user's actual working directory
46
+ // (where they ran `apx code`) via --cwd so the TUI shows the real project
47
+ // path + git branch instead of apx/src.
48
+ const userCwd = process.cwd();
43
49
  spawnSync(bunBin, [
44
50
  "--preload", "@opentui/solid/preload",
45
51
  TUI_SRC,
46
52
  "--pid", pid,
47
53
  "--agent", routedAgentSlug || defaultAgentLabel,
48
54
  "--model", cfg.super_agent?.model || "claude-3-5-sonnet",
55
+ "--cwd", userCwd,
49
56
  ], { stdio: "inherit", cwd: resolve(__dirname, "../../..") });
50
57
  return;
51
58
  }
@@ -425,7 +432,7 @@ async function handlePaletteKey(key, pid, cfg, state, renderScreen, close) {
425
432
  !selected.startsWith("No ")
426
433
  ) {
427
434
  state.activeModel = selected;
428
- const configModule = await import("../../../core/config.js");
435
+ const configModule = await import("#core/config/index.js");
429
436
  const currentCfg = configModule.readConfig();
430
437
  if (!currentCfg.super_agent) currentCfg.super_agent = {};
431
438
  currentCfg.super_agent.model = selected;
@@ -704,7 +711,7 @@ async function runPrompt(
704
711
  const currentMode = MODES[state.currentModeIdx];
705
712
  const body = {
706
713
  prompt: `[Mode: ${currentMode}]\n${text}`,
707
- channel: "terminal",
714
+ channel: CHANNELS.CODE,
708
715
  channelMeta: { cwd },
709
716
  previousMessages,
710
717
  model: state.activeModel,
@@ -1,7 +1,7 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import readline from "node:readline";
3
3
  import { fileURLToPath } from "node:url";
4
- import { getLatestVersion } from "../../../core/update-check.js";
4
+ import { getLatestVersion } from "#core/update-check.js";
5
5
 
6
6
  const PACKAGE_NAME = "@agentprojectcontext/apx";
7
7
 
@@ -108,8 +108,8 @@ import { cmdSetup } from "./commands/setup.js";
108
108
  import { cmdStatus } from "./commands/status.js";
109
109
  import { cmdModel } from "./commands/model.js";
110
110
  import { cmdPair, cmdPairWeb, cmdPairList, cmdPairRevoke } from "./commands/pair.js";
111
- import { checkForUpdate } from "../../core/update-check.js";
112
- import { mascot } from "../../core/mascot.js";
111
+ import { checkForUpdate } from "#core/update-check.js";
112
+ import { mascot } from "#core/mascot.js";
113
113
  import {
114
114
  cmdRoutineList,
115
115
  cmdRoutineGet,
@@ -119,6 +119,7 @@ import {
119
119
  cmdRoutineDisable,
120
120
  cmdRoutineRun,
121
121
  cmdRoutineHistory,
122
+ cmdRoutineMemory,
122
123
  } from "./commands/routine.js";
123
124
  import {
124
125
  cmdArtifactCreate,
@@ -1803,7 +1804,6 @@ const HELP_TOPICS = new Map(Object.entries({
1803
1804
  const HELP_ALIASES = new Map(Object.entries({
1804
1805
  "project ls": "project list",
1805
1806
  "project rm": "project remove",
1806
- "sys": "code",
1807
1807
  "agent ls": "agent list",
1808
1808
  "agent show": "agent get",
1809
1809
  "agent vault ls": "agent vault list",
@@ -2406,7 +2406,6 @@ async function dispatch(cmd, rest) {
2406
2406
  break;
2407
2407
 
2408
2408
  case "code":
2409
- case "sys":
2410
2409
  await cmdCode(parseArgs(rest));
2411
2410
  break;
2412
2411
 
@@ -2481,6 +2480,7 @@ async function dispatch(cmd, rest) {
2481
2480
  else if (sub === "disable") await cmdRoutineDisable(a);
2482
2481
  else if (sub === "run") await cmdRoutineRun(a);
2483
2482
  else if (sub === "history" || sub === "hist") await cmdRoutineHistory(a);
2483
+ else if (sub === "memory" || sub === "mem") await cmdRoutineMemory(a);
2484
2484
  else die(`unknown routine subcommand: ${sub}`);
2485
2485
  break;
2486
2486
  }
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  // Runs automatically after `npm install -g apx` and `npm update -g apx`.
3
3
  import os from "node:os";
4
- import { refreshApcContextSkill } from "../../core/apc-skill-sync.js";
5
- import { installGlobalSkills } from "../../core/scaffold.js";
4
+ import { refreshApcContextSkill } from "#core/apc/skill-sync.js";
5
+ import { installGlobalSkills } from "#core/apc/scaffold.js";
6
6
 
7
7
  try {
8
8
  const refresh = process.env.APX_SKIP_SKILL_REFRESH