@ouro.bot/cli 0.1.0-alpha.17 → 0.1.0-alpha.18

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.
@@ -87,6 +87,7 @@ function buildSpecialistSystemPrompt(soulText, identityText, existingBundles, co
87
87
  "- `write_file`: Write a file to disk. Use this to write psyche files and agent.json to the temp directory.",
88
88
  "- `read_file`: Read a file from disk. Useful for reviewing existing agent bundles or migration sources.",
89
89
  "- `list_directory`: List directory contents. Useful for exploring existing agent bundles.",
90
+ "- I also have the normal local harness tools when useful here, including `shell`, task tools like `task_create` and `schedule_reminder`, memory tools, coding tools, and repo helpers.",
90
91
  "- `complete_adoption`: Finalize the bundle. Validates, scaffolds structural dirs, moves to ~/AgentBundles/, writes secrets, plays hatch animation. I call this with `name` (PascalCase) and `handoff_message` (warm message for the human).",
91
92
  "- `final_answer`: End the conversation with a final message. I call this after complete_adoption succeeds.",
92
93
  "",
@@ -63,14 +63,11 @@ const completeAdoptionTool = {
63
63
  },
64
64
  },
65
65
  };
66
- const readFileTool = tools_base_1.baseToolDefinitions.find((d) => d.tool.function.name === "read_file");
67
- const writeFileTool = tools_base_1.baseToolDefinitions.find((d) => d.tool.function.name === "write_file");
68
- const listDirTool = tools_base_1.baseToolDefinitions.find((d) => d.tool.function.name === "list_directory");
69
66
  /**
70
67
  * Returns the specialist's tool schema array.
71
68
  */
72
69
  function getSpecialistTools() {
73
- return [completeAdoptionTool, tools_base_1.finalAnswerTool, readFileTool.tool, writeFileTool.tool, listDirTool.tool];
70
+ return [completeAdoptionTool, tools_base_1.finalAnswerTool, ...tools_base_1.baseToolDefinitions.map((definition) => definition.tool)];
74
71
  }
75
72
  const PSYCHE_FILES = ["SOUL.md", "IDENTITY.md", "LORE.md", "TACIT.md", "ASPIRATIONS.md"];
76
73
  function isPascalCase(name) {
@@ -199,31 +196,14 @@ function createSpecialistExecTool(deps) {
199
196
  if (name === "complete_adoption") {
200
197
  return execCompleteAdoption(args, deps);
201
198
  }
202
- if (name === "read_file") {
199
+ const baseDefinition = tools_base_1.baseToolDefinitions.find((definition) => definition.tool.function.name === name);
200
+ if (baseDefinition) {
201
+ const toolContext = {
202
+ signin: async () => undefined,
203
+ };
203
204
  try {
204
- return fs.readFileSync(args.path, "utf-8");
205
- }
206
- catch (e) {
207
- return `error: ${e instanceof Error ? e.message : /* v8 ignore next -- defensive @preserve */ String(e)}`;
208
- }
209
- }
210
- if (name === "write_file") {
211
- try {
212
- const dir = path.dirname(args.path);
213
- fs.mkdirSync(dir, { recursive: true });
214
- fs.writeFileSync(args.path, args.content, "utf-8");
215
- return `wrote ${args.path}`;
216
- }
217
- catch (e) {
218
- return `error: ${e instanceof Error ? e.message : /* v8 ignore next -- defensive @preserve */ String(e)}`;
219
- }
220
- }
221
- if (name === "list_directory") {
222
- try {
223
- return fs
224
- .readdirSync(args.path, { withFileTypes: true })
225
- .map((e) => `${e.isDirectory() ? "d" : "-"} ${e.name}`)
226
- .join("\n");
205
+ await toolContext.signin("specialist");
206
+ return await baseDefinition.handler(args, toolContext);
227
207
  }
228
208
  catch (e) {
229
209
  return `error: ${e instanceof Error ? e.message : /* v8 ignore next -- defensive @preserve */ String(e)}`;
@@ -46,6 +46,25 @@ const tasks_1 = require("./tasks");
46
46
  const tools_1 = require("./coding/tools");
47
47
  const memory_1 = require("../mind/memory");
48
48
  const postIt = (msg) => `post-it from past you:\n${msg}`;
49
+ function normalizeOptionalText(value) {
50
+ if (typeof value !== "string")
51
+ return null;
52
+ const trimmed = value.trim();
53
+ return trimmed.length > 0 ? trimmed : null;
54
+ }
55
+ function buildTaskCreateInput(args) {
56
+ return {
57
+ title: args.title,
58
+ type: args.type,
59
+ category: args.category,
60
+ body: args.body,
61
+ status: normalizeOptionalText(args.status) ?? undefined,
62
+ validator: normalizeOptionalText(args.validator),
63
+ requester: normalizeOptionalText(args.requester),
64
+ cadence: normalizeOptionalText(args.cadence),
65
+ scheduledAt: normalizeOptionalText(args.scheduledAt),
66
+ };
67
+ }
49
68
  exports.baseToolDefinitions = [
50
69
  {
51
70
  tool: {
@@ -75,7 +94,11 @@ exports.baseToolDefinitions = [
75
94
  },
76
95
  },
77
96
  },
78
- handler: (a) => (fs.writeFileSync(a.path, a.content, "utf-8"), "ok"),
97
+ handler: (a) => {
98
+ fs.mkdirSync(path.dirname(a.path), { recursive: true });
99
+ fs.writeFileSync(a.path, a.content, "utf-8");
100
+ return "ok";
101
+ },
79
102
  },
80
103
  {
81
104
  tool: {
@@ -394,7 +417,7 @@ exports.baseToolDefinitions = [
394
417
  type: "function",
395
418
  function: {
396
419
  name: "task_create",
397
- description: "create a new task in the bundle task system",
420
+ description: "create a new task in the bundle task system. optionally set `scheduledAt` for a one-time reminder or `cadence` for recurring daemon-scheduled work.",
398
421
  parameters: {
399
422
  type: "object",
400
423
  properties: {
@@ -402,18 +425,59 @@ exports.baseToolDefinitions = [
402
425
  type: { type: "string", enum: ["one-shot", "ongoing", "habit"] },
403
426
  category: { type: "string" },
404
427
  body: { type: "string" },
428
+ status: { type: "string" },
429
+ validator: { type: "string" },
430
+ requester: { type: "string" },
431
+ scheduledAt: { type: "string", description: "ISO timestamp for a one-time scheduled run/reminder" },
432
+ cadence: { type: "string", description: "recurrence like 30m, 1h, 1d, or cron" },
405
433
  },
406
434
  required: ["title", "type", "category", "body"],
407
435
  },
408
436
  },
409
437
  },
410
438
  handler: (a) => {
439
+ try {
440
+ const created = (0, tasks_1.getTaskModule)().createTask(buildTaskCreateInput(a));
441
+ return `created: ${created}`;
442
+ }
443
+ catch (error) {
444
+ return `error: ${error instanceof Error ? error.message : String(error)}`;
445
+ }
446
+ },
447
+ },
448
+ {
449
+ tool: {
450
+ type: "function",
451
+ function: {
452
+ name: "schedule_reminder",
453
+ description: "create a scheduled reminder or recurring daemon job. use `scheduledAt` for one-time reminders and `cadence` for recurring reminders. this writes canonical task fields that the daemon reconciles into OS-level jobs.",
454
+ parameters: {
455
+ type: "object",
456
+ properties: {
457
+ title: { type: "string" },
458
+ body: { type: "string" },
459
+ category: { type: "string" },
460
+ scheduledAt: { type: "string", description: "ISO timestamp for a one-time reminder" },
461
+ cadence: { type: "string", description: "recurrence like 30m, 1h, 1d, or cron" },
462
+ },
463
+ required: ["title", "body"],
464
+ },
465
+ },
466
+ },
467
+ handler: (a) => {
468
+ const scheduledAt = normalizeOptionalText(a.scheduledAt);
469
+ const cadence = normalizeOptionalText(a.cadence);
470
+ if (!scheduledAt && !cadence) {
471
+ return "error: provide scheduledAt or cadence";
472
+ }
411
473
  try {
412
474
  const created = (0, tasks_1.getTaskModule)().createTask({
413
475
  title: a.title,
414
- type: a.type,
415
- category: a.category,
476
+ type: cadence ? "habit" : "one-shot",
477
+ category: normalizeOptionalText(a.category) ?? "reminder",
416
478
  body: a.body,
479
+ scheduledAt,
480
+ cadence,
417
481
  });
418
482
  return `created: ${created}`;
419
483
  }
@@ -184,7 +184,9 @@ function summarizeArgs(name, args) {
184
184
  if (name === "load_skill")
185
185
  return summarizeKeyValues(args, ["name"]);
186
186
  if (name === "task_create")
187
- return summarizeKeyValues(args, ["title", "type", "category"]);
187
+ return summarizeKeyValues(args, ["title", "type", "category", "scheduledAt", "cadence"]);
188
+ if (name === "schedule_reminder")
189
+ return summarizeKeyValues(args, ["title", "scheduledAt", "cadence"]);
188
190
  if (name === "task_update_status")
189
191
  return summarizeKeyValues(args, ["name", "status"]);
190
192
  if (name === "task_board_status")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.17",
3
+ "version": "0.1.0-alpha.18",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "ouro": "dist/heart/daemon/ouro-entry.js",