@alook/cli 0.0.102 → 0.0.103
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/index.js +96 -19
- package/dist/session-runner.js +25 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var __export = (target, all) => {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// src/index.ts
|
|
18
|
-
import { Command as
|
|
18
|
+
import { Command as Command12 } from "commander";
|
|
19
19
|
|
|
20
20
|
// commands/register.ts
|
|
21
21
|
import { Command } from "commander";
|
|
@@ -14605,7 +14605,7 @@ var DaemonPushMessageSchema = exports_external.discriminatedUnion("type", [
|
|
|
14605
14605
|
exports_external.object({ type: exports_external.literal("daemon.evict"), workspaceId: exports_external.string() }),
|
|
14606
14606
|
exports_external.object({ type: exports_external.literal("daemon.update"), version: exports_external.string() }),
|
|
14607
14607
|
exports_external.object({ type: exports_external.literal("daemon.rescan") }),
|
|
14608
|
-
exports_external.object({ type: exports_external.literal("daemon.kill"), workspaceId: exports_external.string(), taskId: exports_external.string(), targetTaskId: exports_external.string() })
|
|
14608
|
+
exports_external.object({ type: exports_external.literal("daemon.kill"), workspaceId: exports_external.string(), agentId: exports_external.string().min(1), taskId: exports_external.string(), targetTaskId: exports_external.string() })
|
|
14609
14609
|
]);
|
|
14610
14610
|
var RegisterResponseSchema = exports_external.object({
|
|
14611
14611
|
runtimes: exports_external.array(exports_external.object({ id: exports_external.string() }))
|
|
@@ -14958,6 +14958,13 @@ var CreateStudioRequestSchema = exports_external.object({
|
|
|
14958
14958
|
scenario: exports_external.string().max(50).optional(),
|
|
14959
14959
|
members: exports_external.array(StudioMemberSchema).min(1).max(4)
|
|
14960
14960
|
}).refine((v) => v.members.some((m) => m.role === "leader"), { message: "at least one member must have the leader role" });
|
|
14961
|
+
var RecruitAgentRequestSchema = exports_external.object({
|
|
14962
|
+
instructions: exports_external.string().min(1, "instructions is required"),
|
|
14963
|
+
relationship: exports_external.string().min(1, "relationship is required"),
|
|
14964
|
+
name: exports_external.string().optional(),
|
|
14965
|
+
description: exports_external.string().optional().default(""),
|
|
14966
|
+
model: exports_external.string().max(100).optional()
|
|
14967
|
+
});
|
|
14961
14968
|
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/entity.js
|
|
14962
14969
|
var entityKind = Symbol.for("drizzle:entityKind");
|
|
14963
14970
|
var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
|
|
@@ -16856,9 +16863,6 @@ var agentSkill = sqliteTable("agent_skill", {
|
|
|
16856
16863
|
// ../shared/src/db/queries/task.ts
|
|
16857
16864
|
var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
|
|
16858
16865
|
var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
|
|
16859
|
-
// ../shared/src/db/queries/task-message.ts
|
|
16860
|
-
var HIDDEN_STEP_TYPES = ["status", "log", "tool-result", "text"];
|
|
16861
|
-
var FIXED_PARAMS = 1 + HIDDEN_STEP_TYPES.length;
|
|
16862
16866
|
// ../shared/src/utils/email.ts
|
|
16863
16867
|
var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
|
|
16864
16868
|
var RESERVED_HANDLES = new Set([
|
|
@@ -18831,6 +18835,23 @@ Upload files for your owner to review in the app.
|
|
|
18831
18835
|
When your task includes attachments, their local paths are listed in the prompt JSON under "attachments".
|
|
18832
18836
|
Use your Read tool to open them. Images and PDFs are read visually.
|
|
18833
18837
|
---
|
|
18838
|
+
`;
|
|
18839
|
+
content += `
|
|
18840
|
+
### Agent Management
|
|
18841
|
+
Recruit new colleague agents directly from the CLI. The server auto-generates a name and email handle.
|
|
18842
|
+
- Run '${cmdPrefix()} agent recruit --instructions "<SYSTEM_PROMPT>" --relationship "<DELEGATION_CRITERIA>"'
|
|
18843
|
+
- '--instructions' — the new agent's system prompt (what it does, how it behaves)
|
|
18844
|
+
- '--relationship' — delegation criteria shown in both agents' COLLEAGUES section
|
|
18845
|
+
- '--name <name>' (optional) — preferred name; server generates one if omitted
|
|
18846
|
+
- '--description <text>' (optional) — agent description
|
|
18847
|
+
- '--model <model>' (optional) — model override
|
|
18848
|
+
- '--instructions-file <path>' — alternative: read instructions from a file (mutually exclusive with --instructions)
|
|
18849
|
+
- '--relationship-file <path>' — alternative: read relationship from a file (mutually exclusive with --relationship)
|
|
18850
|
+
- '--json' — output full JSON response
|
|
18851
|
+
- Example: '${cmdPrefix()} agent recruit --instructions "You are a QA engineer..." --relationship "DELEGATE when: code is ready for review"'
|
|
18852
|
+
- Output: 'Recruited Felix (felix@alook.ai) — ag_xK9mPq2z'
|
|
18853
|
+
- The new agent shares your runtime, is automatically linked as your colleague, and receives a welcome task.
|
|
18854
|
+
---
|
|
18834
18855
|
`;
|
|
18835
18856
|
content += `
|
|
18836
18857
|
### Calendar
|
|
@@ -20888,17 +20909,17 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20888
20909
|
break;
|
|
20889
20910
|
case "daemon.kill": {
|
|
20890
20911
|
const ws = workspaceStates.find((w) => w.workspaceId === msg.workspaceId);
|
|
20891
|
-
if (ws) {
|
|
20912
|
+
if (ws && !activeTasks.has(msg.taskId)) {
|
|
20892
20913
|
const killTask = fromApiTask({
|
|
20893
20914
|
id: msg.taskId,
|
|
20894
|
-
agent_id:
|
|
20915
|
+
agent_id: msg.agentId,
|
|
20895
20916
|
runtime_id: "",
|
|
20896
20917
|
conversation_id: "",
|
|
20897
20918
|
workspace_id: ws.workspaceId,
|
|
20898
20919
|
prompt: "",
|
|
20899
|
-
status: "
|
|
20920
|
+
status: "dispatched",
|
|
20900
20921
|
priority: 0,
|
|
20901
|
-
dispatched_at:
|
|
20922
|
+
dispatched_at: new Date().toISOString(),
|
|
20902
20923
|
started_at: null,
|
|
20903
20924
|
completed_at: null,
|
|
20904
20925
|
result: null,
|
|
@@ -21258,9 +21279,16 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
21258
21279
|
child.on("close", async (code) => {
|
|
21259
21280
|
activeTasks.delete(task.id);
|
|
21260
21281
|
if (code !== 0) {
|
|
21282
|
+
const agentBaseDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
|
|
21283
|
+
const killIntent = readKillIntent(agentBaseDir, task.id);
|
|
21284
|
+
if (killIntent) {
|
|
21285
|
+
log9.info(`Task ${task.id} exited due to kill intent — skipping failTask`);
|
|
21286
|
+
clearKillIntent(agentBaseDir, task.id);
|
|
21287
|
+
return;
|
|
21288
|
+
}
|
|
21261
21289
|
const msg = code === null ? `session-runner killed by signal (task ${task.id})` : `session-runner crashed (exit code ${code}, task ${task.id})`;
|
|
21262
21290
|
log9.warn(msg);
|
|
21263
|
-
const timelineDir = join11(
|
|
21291
|
+
const timelineDir = join11(agentBaseDir, ".context_timeline");
|
|
21264
21292
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
21265
21293
|
entry.pid = null;
|
|
21266
21294
|
entry.status = "failed";
|
|
@@ -22315,19 +22343,67 @@ function issueCommand() {
|
|
|
22315
22343
|
return cmd;
|
|
22316
22344
|
}
|
|
22317
22345
|
|
|
22318
|
-
// commands/
|
|
22346
|
+
// commands/agent.ts
|
|
22319
22347
|
import { Command as Command8 } from "commander";
|
|
22348
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
22349
|
+
function readField(opts, inlineName, fileName) {
|
|
22350
|
+
if (opts.inline && opts.file) {
|
|
22351
|
+
console.error(`Error: --${inlineName} and --${fileName} are mutually exclusive`);
|
|
22352
|
+
process.exit(1);
|
|
22353
|
+
}
|
|
22354
|
+
if (opts.file)
|
|
22355
|
+
return readFileSync12(opts.file, "utf-8");
|
|
22356
|
+
return opts.inline ?? null;
|
|
22357
|
+
}
|
|
22358
|
+
function agentCommand() {
|
|
22359
|
+
const cmd = new Command8("agent").description("Manage agents");
|
|
22360
|
+
cmd.command("recruit").description("Recruit a new colleague agent").option("--agent_id <id>", "Agent ID (or set ALOOK_AGENT_ID env var)").option("--instructions <text>", "Instructions for the new agent (system prompt)").option("--instructions-file <path>", "Read instructions from a file").option("--relationship <text>", "Relationship/delegation instruction for the link").option("--relationship-file <path>", "Read relationship from a file").option("--name <name>", "Preferred name for the new agent (auto-generated if omitted)").option("--description <text>", "Agent description").option("--model <model>", "Model override").option("--json", "Output as JSON").action(async (opts, command) => {
|
|
22361
|
+
const instructions = readField({ inline: opts.instructions, file: opts.instructionsFile }, "instructions", "instructions-file");
|
|
22362
|
+
if (!instructions) {
|
|
22363
|
+
console.error("Error: --instructions or --instructions-file is required");
|
|
22364
|
+
process.exit(1);
|
|
22365
|
+
}
|
|
22366
|
+
const relationship = readField({ inline: opts.relationship, file: opts.relationshipFile }, "relationship", "relationship-file");
|
|
22367
|
+
if (!relationship) {
|
|
22368
|
+
console.error("Error: --relationship or --relationship-file is required");
|
|
22369
|
+
process.exit(1);
|
|
22370
|
+
}
|
|
22371
|
+
const agentId = resolveAgentId(opts);
|
|
22372
|
+
const { serverUrl, token, workspaceId } = resolveClientOpts(command, { agentId });
|
|
22373
|
+
const client = new APIClient(serverUrl, token, workspaceId);
|
|
22374
|
+
const body = { instructions, relationship };
|
|
22375
|
+
if (opts.name)
|
|
22376
|
+
body.name = opts.name;
|
|
22377
|
+
if (opts.description)
|
|
22378
|
+
body.description = opts.description;
|
|
22379
|
+
if (opts.model)
|
|
22380
|
+
body.model = opts.model;
|
|
22381
|
+
try {
|
|
22382
|
+
const res = await client.postJSON(`/api/agents/recruit?agentId=${encodeURIComponent(agentId)}`, body);
|
|
22383
|
+
if (opts.json)
|
|
22384
|
+
return printJSON(res);
|
|
22385
|
+
console.log(`Recruited ${res.agent.name} (${res.agent.email}) — ${res.agent.id}`);
|
|
22386
|
+
} catch (err) {
|
|
22387
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
22388
|
+
process.exit(1);
|
|
22389
|
+
}
|
|
22390
|
+
});
|
|
22391
|
+
return cmd;
|
|
22392
|
+
}
|
|
22393
|
+
|
|
22394
|
+
// commands/version.ts
|
|
22395
|
+
import { Command as Command9 } from "commander";
|
|
22320
22396
|
function versionCommand() {
|
|
22321
|
-
const cmd = new
|
|
22397
|
+
const cmd = new Command9("version").description("Show CLI version").action(() => {
|
|
22322
22398
|
console.log(`alook version ${getCurrentVersion()}`);
|
|
22323
22399
|
});
|
|
22324
22400
|
return cmd;
|
|
22325
22401
|
}
|
|
22326
22402
|
|
|
22327
22403
|
// commands/update.ts
|
|
22328
|
-
import { Command as
|
|
22404
|
+
import { Command as Command10 } from "commander";
|
|
22329
22405
|
function updateCommand() {
|
|
22330
|
-
const cmd = new
|
|
22406
|
+
const cmd = new Command10("update").description("Update CLI to the latest version").action(async () => {
|
|
22331
22407
|
const current = getCurrentVersion();
|
|
22332
22408
|
console.log(`Current version: ${current}`);
|
|
22333
22409
|
const latest = await fetchLatestVersion();
|
|
@@ -22361,18 +22437,18 @@ ${result.output}`);
|
|
|
22361
22437
|
}
|
|
22362
22438
|
|
|
22363
22439
|
// commands/sync.ts
|
|
22364
|
-
import { Command as
|
|
22365
|
-
import { readFileSync as
|
|
22440
|
+
import { Command as Command11 } from "commander";
|
|
22441
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
22366
22442
|
import { basename as basename3 } from "path";
|
|
22367
22443
|
function syncCommand() {
|
|
22368
|
-
const cmd = new
|
|
22444
|
+
const cmd = new Command11("sync").description("File sync utilities");
|
|
22369
22445
|
cmd.command("upload-artifact").description("Upload a file artifact to a conversation").option("--agent_id <id>", "Agent ID").requiredOption("--conversation_id <id>", "Conversation ID").requiredOption("--file <path>", "Path to file to upload").action(async (opts, command) => {
|
|
22370
22446
|
const agentId = resolveAgentId(opts);
|
|
22371
22447
|
const { serverUrl, token, workspaceId } = resolveClientOpts(command, { agentId });
|
|
22372
22448
|
const client = new APIClient(serverUrl, token, workspaceId);
|
|
22373
22449
|
let bytes;
|
|
22374
22450
|
try {
|
|
22375
|
-
bytes =
|
|
22451
|
+
bytes = readFileSync13(opts.file);
|
|
22376
22452
|
} catch (err) {
|
|
22377
22453
|
console.error(`Error: cannot read file "${opts.file}": ${err.message}`);
|
|
22378
22454
|
process.exit(1);
|
|
@@ -22395,7 +22471,7 @@ function syncCommand() {
|
|
|
22395
22471
|
}
|
|
22396
22472
|
|
|
22397
22473
|
// src/index.ts
|
|
22398
|
-
var program = new
|
|
22474
|
+
var program = new Command12;
|
|
22399
22475
|
program.name("alook").description("Alook CLI").option("--server <url>", "Server URL").option("--profile <name>", "Profile name");
|
|
22400
22476
|
program.addCommand(registerCommand());
|
|
22401
22477
|
program.addCommand(statusCommand());
|
|
@@ -22403,6 +22479,7 @@ program.addCommand(daemonCommand2());
|
|
|
22403
22479
|
program.addCommand(emailCommand());
|
|
22404
22480
|
program.addCommand(calendarCommand());
|
|
22405
22481
|
program.addCommand(issueCommand());
|
|
22482
|
+
program.addCommand(agentCommand());
|
|
22406
22483
|
program.addCommand(configCommand());
|
|
22407
22484
|
program.addCommand(versionCommand());
|
|
22408
22485
|
program.addCommand(updateCommand());
|
package/dist/session-runner.js
CHANGED
|
@@ -14472,7 +14472,7 @@ var DaemonPushMessageSchema = exports_external.discriminatedUnion("type", [
|
|
|
14472
14472
|
exports_external.object({ type: exports_external.literal("daemon.evict"), workspaceId: exports_external.string() }),
|
|
14473
14473
|
exports_external.object({ type: exports_external.literal("daemon.update"), version: exports_external.string() }),
|
|
14474
14474
|
exports_external.object({ type: exports_external.literal("daemon.rescan") }),
|
|
14475
|
-
exports_external.object({ type: exports_external.literal("daemon.kill"), workspaceId: exports_external.string(), taskId: exports_external.string(), targetTaskId: exports_external.string() })
|
|
14475
|
+
exports_external.object({ type: exports_external.literal("daemon.kill"), workspaceId: exports_external.string(), agentId: exports_external.string().min(1), taskId: exports_external.string(), targetTaskId: exports_external.string() })
|
|
14476
14476
|
]);
|
|
14477
14477
|
var RegisterResponseSchema = exports_external.object({
|
|
14478
14478
|
runtimes: exports_external.array(exports_external.object({ id: exports_external.string() }))
|
|
@@ -14825,6 +14825,13 @@ var CreateStudioRequestSchema = exports_external.object({
|
|
|
14825
14825
|
scenario: exports_external.string().max(50).optional(),
|
|
14826
14826
|
members: exports_external.array(StudioMemberSchema).min(1).max(4)
|
|
14827
14827
|
}).refine((v) => v.members.some((m) => m.role === "leader"), { message: "at least one member must have the leader role" });
|
|
14828
|
+
var RecruitAgentRequestSchema = exports_external.object({
|
|
14829
|
+
instructions: exports_external.string().min(1, "instructions is required"),
|
|
14830
|
+
relationship: exports_external.string().min(1, "relationship is required"),
|
|
14831
|
+
name: exports_external.string().optional(),
|
|
14832
|
+
description: exports_external.string().optional().default(""),
|
|
14833
|
+
model: exports_external.string().max(100).optional()
|
|
14834
|
+
});
|
|
14828
14835
|
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/entity.js
|
|
14829
14836
|
var entityKind = Symbol.for("drizzle:entityKind");
|
|
14830
14837
|
var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
|
|
@@ -16723,9 +16730,6 @@ var agentSkill = sqliteTable("agent_skill", {
|
|
|
16723
16730
|
// ../shared/src/db/queries/task.ts
|
|
16724
16731
|
var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
|
|
16725
16732
|
var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
|
|
16726
|
-
// ../shared/src/db/queries/task-message.ts
|
|
16727
|
-
var HIDDEN_STEP_TYPES = ["status", "log", "tool-result", "text"];
|
|
16728
|
-
var FIXED_PARAMS = 1 + HIDDEN_STEP_TYPES.length;
|
|
16729
16733
|
// ../shared/src/utils/email.ts
|
|
16730
16734
|
var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
|
|
16731
16735
|
var RESERVED_HANDLES = new Set([
|
|
@@ -18169,6 +18173,23 @@ Upload files for your owner to review in the app.
|
|
|
18169
18173
|
When your task includes attachments, their local paths are listed in the prompt JSON under "attachments".
|
|
18170
18174
|
Use your Read tool to open them. Images and PDFs are read visually.
|
|
18171
18175
|
---
|
|
18176
|
+
`;
|
|
18177
|
+
content += `
|
|
18178
|
+
### Agent Management
|
|
18179
|
+
Recruit new colleague agents directly from the CLI. The server auto-generates a name and email handle.
|
|
18180
|
+
- Run '${cmdPrefix()} agent recruit --instructions "<SYSTEM_PROMPT>" --relationship "<DELEGATION_CRITERIA>"'
|
|
18181
|
+
- '--instructions' — the new agent's system prompt (what it does, how it behaves)
|
|
18182
|
+
- '--relationship' — delegation criteria shown in both agents' COLLEAGUES section
|
|
18183
|
+
- '--name <name>' (optional) — preferred name; server generates one if omitted
|
|
18184
|
+
- '--description <text>' (optional) — agent description
|
|
18185
|
+
- '--model <model>' (optional) — model override
|
|
18186
|
+
- '--instructions-file <path>' — alternative: read instructions from a file (mutually exclusive with --instructions)
|
|
18187
|
+
- '--relationship-file <path>' — alternative: read relationship from a file (mutually exclusive with --relationship)
|
|
18188
|
+
- '--json' — output full JSON response
|
|
18189
|
+
- Example: '${cmdPrefix()} agent recruit --instructions "You are a QA engineer..." --relationship "DELEGATE when: code is ready for review"'
|
|
18190
|
+
- Output: 'Recruited Felix (felix@alook.ai) — ag_xK9mPq2z'
|
|
18191
|
+
- The new agent shares your runtime, is automatically linked as your colleague, and receives a welcome task.
|
|
18192
|
+
---
|
|
18172
18193
|
`;
|
|
18173
18194
|
content += `
|
|
18174
18195
|
### Calendar
|