@openape/apes 1.1.1 → 1.2.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/dist/cli.js CHANGED
@@ -3050,6 +3050,37 @@ function readAuth() {
3050
3050
  if (!parsed.access_token) throw new CliError("auth.json missing access_token");
3051
3051
  return parsed;
3052
3052
  }
3053
+ async function postRunResultToChat(opts) {
3054
+ const endpoint = (opts.endpoint ?? process.env.APE_CHAT_ENDPOINT ?? "https://chat.openape.ai").replace(/\/$/, "");
3055
+ try {
3056
+ const contactsRes = await fetch(`${endpoint}/api/contacts`, {
3057
+ headers: { Authorization: `Bearer ${opts.authToken}` }
3058
+ });
3059
+ if (!contactsRes.ok) return;
3060
+ const contacts = await contactsRes.json();
3061
+ const ownerLower = opts.ownerEmail.toLowerCase();
3062
+ const ownerRow = contacts.find((c) => c.peerEmail.toLowerCase() === ownerLower && c.connected && c.roomId);
3063
+ if (!ownerRow?.roomId) {
3064
+ consola22.info("chat DM skipped \u2014 no active room with owner (accept the contact request in chat to enable)");
3065
+ return;
3066
+ }
3067
+ const prefix = opts.status === "ok" ? "\u2705" : "\u274C";
3068
+ const msg = opts.finalMessage?.trim() || (opts.status === "ok" ? "(no output)" : "(crashed)");
3069
+ const body = `${prefix} *${opts.taskName}* (${opts.stepCount} steps)
3070
+
3071
+ ${msg}`.slice(0, 9e3);
3072
+ const postRes = await fetch(`${endpoint}/api/rooms/${encodeURIComponent(ownerRow.roomId)}/messages`, {
3073
+ method: "POST",
3074
+ headers: { "Authorization": `Bearer ${opts.authToken}`, "Content-Type": "application/json" },
3075
+ body: JSON.stringify({ body })
3076
+ });
3077
+ if (!postRes.ok) {
3078
+ consola22.warn(`chat DM post failed: ${postRes.status}`);
3079
+ }
3080
+ } catch (err) {
3081
+ consola22.warn(`chat DM error: ${err.message}`);
3082
+ }
3083
+ }
3053
3084
  function readTaskSpec(taskId) {
3054
3085
  const path2 = join3(TASK_CACHE_DIR, `${taskId}.json`);
3055
3086
  if (!existsSync5(path2)) {
@@ -3057,6 +3088,15 @@ function readTaskSpec(taskId) {
3057
3088
  }
3058
3089
  return JSON.parse(readFileSync5(path2, "utf8"));
3059
3090
  }
3091
+ var AGENT_CONFIG_PATH = join3(homedir5(), ".openape", "agent", "agent.json");
3092
+ function readAgentConfig() {
3093
+ if (!existsSync5(AGENT_CONFIG_PATH)) return { systemPrompt: "" };
3094
+ try {
3095
+ return JSON.parse(readFileSync5(AGENT_CONFIG_PATH, "utf8"));
3096
+ } catch {
3097
+ return { systemPrompt: "" };
3098
+ }
3099
+ }
3060
3100
  function readLitellmConfig(model) {
3061
3101
  const envPath = join3(homedir5(), "litellm", ".env");
3062
3102
  const env = {};
@@ -3100,6 +3140,7 @@ var runAgentCommand = defineCommand24({
3100
3140
  const taskId = args["task-id"];
3101
3141
  const auth = readAuth();
3102
3142
  const spec = readTaskSpec(taskId);
3143
+ const agentCfg = readAgentConfig();
3103
3144
  const config = readLitellmConfig(args.model);
3104
3145
  let tools;
3105
3146
  try {
@@ -3113,11 +3154,12 @@ var runAgentCommand = defineCommand24({
3113
3154
  try {
3114
3155
  const result = await runLoop({
3115
3156
  config,
3116
- systemPrompt: spec.systemPrompt,
3117
- // Cron tasks have no prior user message the task fires by
3118
- // schedule. We use a synthetic kick-off message; tasks can
3119
- // ignore it via their system prompt.
3120
- userMessage: "It is time to run this task. Use your tools as needed and report when done.",
3157
+ // Agent persona/behaviour ("you are Igor, …") set at agent level;
3158
+ // the task's userPrompt is the imperative job ("read my mail and
3159
+ // summarise"). The cron firing is the trigger — the message body
3160
+ // is the task itself.
3161
+ systemPrompt: agentCfg.systemPrompt,
3162
+ userMessage: spec.userPrompt,
3121
3163
  tools,
3122
3164
  maxSteps: spec.maxSteps
3123
3165
  });
@@ -3128,6 +3170,16 @@ var runAgentCommand = defineCommand24({
3128
3170
  trace: result.trace
3129
3171
  });
3130
3172
  consola22.success(`Run ${runId} ${result.status} (${result.stepCount} steps)`);
3173
+ if (auth.owner_email) {
3174
+ await postRunResultToChat({
3175
+ authToken: auth.access_token,
3176
+ ownerEmail: auth.owner_email,
3177
+ taskName: spec.name,
3178
+ status: result.status,
3179
+ stepCount: result.stepCount,
3180
+ finalMessage: result.finalMessage
3181
+ });
3182
+ }
3131
3183
  if (result.status === "error") process.exit(1);
3132
3184
  } catch (err) {
3133
3185
  const message = err?.message ?? String(err);
@@ -3138,6 +3190,16 @@ var runAgentCommand = defineCommand24({
3138
3190
  trace: []
3139
3191
  }).catch(() => {
3140
3192
  });
3193
+ if (auth.owner_email) {
3194
+ await postRunResultToChat({
3195
+ authToken: auth.access_token,
3196
+ ownerEmail: auth.owner_email,
3197
+ taskName: spec.name,
3198
+ status: "error",
3199
+ stepCount: 0,
3200
+ finalMessage: message
3201
+ });
3202
+ }
3141
3203
  throw new CliError(`Run ${runId} crashed: ${message}`);
3142
3204
  }
3143
3205
  }
@@ -3977,8 +4039,16 @@ var syncAgentCommand = defineCommand27({
3977
4039
  ownerEmail: auth.owner_email
3978
4040
  });
3979
4041
  consola24.info(sync.first_sync ? "\u2713 first sync \u2014 agent registered" : "\u2713 presence updated");
3980
- const tasks = await client.listTasks();
4042
+ const { system_prompt: systemPrompt, tasks } = await client.listTasks();
3981
4043
  consola24.info(`Pulled ${tasks.length} task${tasks.length === 1 ? "" : "s"}`);
4044
+ const agentDir = join8(homedir10(), ".openape", "agent");
4045
+ mkdirSync4(agentDir, { recursive: true });
4046
+ writeFileSync6(
4047
+ join8(agentDir, "agent.json"),
4048
+ `${JSON.stringify({ systemPrompt }, null, 2)}
4049
+ `,
4050
+ { mode: 384 }
4051
+ );
3982
4052
  mkdirSync4(TASK_CACHE_DIR2, { recursive: true });
3983
4053
  for (const task of tasks) {
3984
4054
  const path2 = join8(TASK_CACHE_DIR2, `${task.taskId}.json`);
@@ -5279,7 +5349,7 @@ var mcpCommand = defineCommand36({
5279
5349
  if (transport !== "stdio" && transport !== "sse") {
5280
5350
  throw new Error('Transport must be "stdio" or "sse"');
5281
5351
  }
5282
- const { startMcpServer } = await import("./server-PZEAFXN6.js");
5352
+ const { startMcpServer } = await import("./server-6OLIVAHI.js");
5283
5353
  await startMcpServer(transport, port);
5284
5354
  }
5285
5355
  });
@@ -5917,7 +5987,7 @@ async function bestEffortGrantCount(idp) {
5917
5987
  }
5918
5988
  }
5919
5989
  async function runHealth(args) {
5920
- const version = true ? "1.1.1" : "0.0.0";
5990
+ const version = true ? "1.2.0" : "0.0.0";
5921
5991
  const auth = loadAuth();
5922
5992
  if (!auth) {
5923
5993
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -6190,10 +6260,10 @@ if (shellRewrite) {
6190
6260
  if (shellRewrite.action === "rewrite") {
6191
6261
  process.argv = shellRewrite.argv;
6192
6262
  } else if (shellRewrite.action === "version") {
6193
- console.log(`ape-shell ${"1.1.1"} (OpenApe DDISA shell wrapper)`);
6263
+ console.log(`ape-shell ${"1.2.0"} (OpenApe DDISA shell wrapper)`);
6194
6264
  process.exit(0);
6195
6265
  } else if (shellRewrite.action === "help") {
6196
- console.log(`ape-shell ${"1.1.1"} \u2014 OpenApe DDISA shell wrapper`);
6266
+ console.log(`ape-shell ${"1.2.0"} \u2014 OpenApe DDISA shell wrapper`);
6197
6267
  console.log("");
6198
6268
  console.log("Usage:");
6199
6269
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -6251,7 +6321,7 @@ var configCommand = defineCommand48({
6251
6321
  var main = defineCommand48({
6252
6322
  meta: {
6253
6323
  name: "apes",
6254
- version: "1.1.1",
6324
+ version: "1.2.0",
6255
6325
  description: "Unified CLI for OpenApe"
6256
6326
  },
6257
6327
  subCommands: {
@@ -6306,7 +6376,7 @@ async function maybeRefreshAuth() {
6306
6376
  }
6307
6377
  }
6308
6378
  await maybeRefreshAuth();
6309
- await maybeWarnStaleVersion("1.1.1").catch(() => {
6379
+ await maybeWarnStaleVersion("1.2.0").catch(() => {
6310
6380
  });
6311
6381
  runMain(main).catch((err) => {
6312
6382
  if (err instanceof CliExit) {