@openape/apes 1.1.0 → 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
@@ -1909,7 +1909,11 @@ function buildBridgeBootstrapBlock(bridge, name) {
1909
1909
  echo "==> Installing bridge stack as ${name} via bun (one-time)\u2026"
1910
1910
  su - ${shQuote(name)} -c '
1911
1911
  set -euo pipefail
1912
- export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$HOME/.bun/install/global/bin"
1912
+ if ! command -v bun >/dev/null 2>&1 && [ ! -x "$HOME/.bun/bin/bun" ]; then
1913
+ echo "==> bun not found \u2014 installing via official installer"
1914
+ curl -fsSL https://bun.sh/install | bash
1915
+ fi
1916
+ export PATH="$HOME/.bun/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$HOME/.bun/install/global/bin"
1913
1917
  bun add -g @openape/chat-bridge @openape/apes
1914
1918
  '
1915
1919
 
@@ -3046,6 +3050,37 @@ function readAuth() {
3046
3050
  if (!parsed.access_token) throw new CliError("auth.json missing access_token");
3047
3051
  return parsed;
3048
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
+ }
3049
3084
  function readTaskSpec(taskId) {
3050
3085
  const path2 = join3(TASK_CACHE_DIR, `${taskId}.json`);
3051
3086
  if (!existsSync5(path2)) {
@@ -3053,6 +3088,15 @@ function readTaskSpec(taskId) {
3053
3088
  }
3054
3089
  return JSON.parse(readFileSync5(path2, "utf8"));
3055
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
+ }
3056
3100
  function readLitellmConfig(model) {
3057
3101
  const envPath = join3(homedir5(), "litellm", ".env");
3058
3102
  const env = {};
@@ -3096,6 +3140,7 @@ var runAgentCommand = defineCommand24({
3096
3140
  const taskId = args["task-id"];
3097
3141
  const auth = readAuth();
3098
3142
  const spec = readTaskSpec(taskId);
3143
+ const agentCfg = readAgentConfig();
3099
3144
  const config = readLitellmConfig(args.model);
3100
3145
  let tools;
3101
3146
  try {
@@ -3109,11 +3154,12 @@ var runAgentCommand = defineCommand24({
3109
3154
  try {
3110
3155
  const result = await runLoop({
3111
3156
  config,
3112
- systemPrompt: spec.systemPrompt,
3113
- // Cron tasks have no prior user message the task fires by
3114
- // schedule. We use a synthetic kick-off message; tasks can
3115
- // ignore it via their system prompt.
3116
- 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,
3117
3163
  tools,
3118
3164
  maxSteps: spec.maxSteps
3119
3165
  });
@@ -3124,6 +3170,16 @@ var runAgentCommand = defineCommand24({
3124
3170
  trace: result.trace
3125
3171
  });
3126
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
+ }
3127
3183
  if (result.status === "error") process.exit(1);
3128
3184
  } catch (err) {
3129
3185
  const message = err?.message ?? String(err);
@@ -3134,6 +3190,16 @@ var runAgentCommand = defineCommand24({
3134
3190
  trace: []
3135
3191
  }).catch(() => {
3136
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
+ }
3137
3203
  throw new CliError(`Run ${runId} crashed: ${message}`);
3138
3204
  }
3139
3205
  }
@@ -3973,8 +4039,16 @@ var syncAgentCommand = defineCommand27({
3973
4039
  ownerEmail: auth.owner_email
3974
4040
  });
3975
4041
  consola24.info(sync.first_sync ? "\u2713 first sync \u2014 agent registered" : "\u2713 presence updated");
3976
- const tasks = await client.listTasks();
4042
+ const { system_prompt: systemPrompt, tasks } = await client.listTasks();
3977
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
+ );
3978
4052
  mkdirSync4(TASK_CACHE_DIR2, { recursive: true });
3979
4053
  for (const task of tasks) {
3980
4054
  const path2 = join8(TASK_CACHE_DIR2, `${task.taskId}.json`);
@@ -5275,7 +5349,7 @@ var mcpCommand = defineCommand36({
5275
5349
  if (transport !== "stdio" && transport !== "sse") {
5276
5350
  throw new Error('Transport must be "stdio" or "sse"');
5277
5351
  }
5278
- const { startMcpServer } = await import("./server-YKLZLQKX.js");
5352
+ const { startMcpServer } = await import("./server-6OLIVAHI.js");
5279
5353
  await startMcpServer(transport, port);
5280
5354
  }
5281
5355
  });
@@ -5913,7 +5987,7 @@ async function bestEffortGrantCount(idp) {
5913
5987
  }
5914
5988
  }
5915
5989
  async function runHealth(args) {
5916
- const version = true ? "1.1.0" : "0.0.0";
5990
+ const version = true ? "1.2.0" : "0.0.0";
5917
5991
  const auth = loadAuth();
5918
5992
  if (!auth) {
5919
5993
  throw new CliError("Not logged in. Run `apes login` first.", 1);
@@ -6186,10 +6260,10 @@ if (shellRewrite) {
6186
6260
  if (shellRewrite.action === "rewrite") {
6187
6261
  process.argv = shellRewrite.argv;
6188
6262
  } else if (shellRewrite.action === "version") {
6189
- console.log(`ape-shell ${"1.1.0"} (OpenApe DDISA shell wrapper)`);
6263
+ console.log(`ape-shell ${"1.2.0"} (OpenApe DDISA shell wrapper)`);
6190
6264
  process.exit(0);
6191
6265
  } else if (shellRewrite.action === "help") {
6192
- console.log(`ape-shell ${"1.1.0"} \u2014 OpenApe DDISA shell wrapper`);
6266
+ console.log(`ape-shell ${"1.2.0"} \u2014 OpenApe DDISA shell wrapper`);
6193
6267
  console.log("");
6194
6268
  console.log("Usage:");
6195
6269
  console.log(" ape-shell Start interactive grant-mediated REPL");
@@ -6247,7 +6321,7 @@ var configCommand = defineCommand48({
6247
6321
  var main = defineCommand48({
6248
6322
  meta: {
6249
6323
  name: "apes",
6250
- version: "1.1.0",
6324
+ version: "1.2.0",
6251
6325
  description: "Unified CLI for OpenApe"
6252
6326
  },
6253
6327
  subCommands: {
@@ -6302,7 +6376,7 @@ async function maybeRefreshAuth() {
6302
6376
  }
6303
6377
  }
6304
6378
  await maybeRefreshAuth();
6305
- await maybeWarnStaleVersion("1.1.0").catch(() => {
6379
+ await maybeWarnStaleVersion("1.2.0").catch(() => {
6306
6380
  });
6307
6381
  runMain(main).catch((err) => {
6308
6382
  if (err instanceof CliExit) {