@alook/cli 0.0.102 → 0.0.104

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 CHANGED
@@ -15,12 +15,10 @@ var __export = (target, all) => {
15
15
  };
16
16
 
17
17
  // src/index.ts
18
- import { Command as Command11 } from "commander";
18
+ import { Command as Command13 } from "commander";
19
19
 
20
20
  // commands/register.ts
21
21
  import { Command } from "commander";
22
- import { execSync } from "child_process";
23
- import { hostname as hostname4 } from "os";
24
22
 
25
23
  // lib/client.ts
26
24
  class APIClient {
@@ -106,51 +104,6 @@ class APIClient {
106
104
  }
107
105
  }
108
106
 
109
- // lib/config.ts
110
- import { readFileSync, writeFileSync, mkdirSync } from "fs";
111
- import { join } from "path";
112
- import { homedir } from "os";
113
- function configDir() {
114
- return process.env.ALOOK_PROJECT_ROOT || join(homedir(), ".alook");
115
- }
116
- function configPath() {
117
- return join(configDir(), "config.json");
118
- }
119
- function loadCLIConfig() {
120
- try {
121
- return JSON.parse(readFileSync(configPath(), "utf-8"));
122
- } catch {
123
- return {};
124
- }
125
- }
126
- function loadCLIConfigForProfile(profile) {
127
- const cfg = loadCLIConfig();
128
- const profileName = profile || cfg.default_profile;
129
- if (profileName && cfg.profiles?.[profileName]) {
130
- return cfg.profiles[profileName];
131
- }
132
- return {
133
- server_url: cfg.server_url || "",
134
- watched_workspaces: cfg.watched_workspaces || []
135
- };
136
- }
137
- function saveCLIConfig(cfg) {
138
- mkdirSync(configDir(), { recursive: true, mode: 448 });
139
- writeFileSync(configPath(), JSON.stringify(cfg, null, 2), { mode: 384 });
140
- }
141
- function saveCLIConfigForProfile(profile, profileConfig) {
142
- const cfg = loadCLIConfig();
143
- if (profile) {
144
- if (!cfg.profiles)
145
- cfg.profiles = {};
146
- cfg.profiles[profile] = profileConfig;
147
- } else {
148
- cfg.server_url = profileConfig.server_url;
149
- cfg.watched_workspaces = profileConfig.watched_workspaces;
150
- }
151
- saveCLIConfig(cfg);
152
- }
153
-
154
107
  // ../shared/src/constants.ts
155
108
  var TaskStatus = {
156
109
  QUEUED: "queued",
@@ -14605,7 +14558,7 @@ var DaemonPushMessageSchema = exports_external.discriminatedUnion("type", [
14605
14558
  exports_external.object({ type: exports_external.literal("daemon.evict"), workspaceId: exports_external.string() }),
14606
14559
  exports_external.object({ type: exports_external.literal("daemon.update"), version: exports_external.string() }),
14607
14560
  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() })
14561
+ 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
14562
  ]);
14610
14563
  var RegisterResponseSchema = exports_external.object({
14611
14564
  runtimes: exports_external.array(exports_external.object({ id: exports_external.string() }))
@@ -14958,7 +14911,15 @@ var CreateStudioRequestSchema = exports_external.object({
14958
14911
  scenario: exports_external.string().max(50).optional(),
14959
14912
  members: exports_external.array(StudioMemberSchema).min(1).max(4)
14960
14913
  }).refine((v) => v.members.some((m) => m.role === "leader"), { message: "at least one member must have the leader role" });
14961
- // ../../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
14914
+ var RecruitAgentRequestSchema = exports_external.object({
14915
+ instructions: exports_external.string().min(1, "instructions is required"),
14916
+ relationship: exports_external.string().min(1, "relationship is required"),
14917
+ name: exports_external.string().optional(),
14918
+ description: exports_external.string().optional().default(""),
14919
+ model: exports_external.string().max(100).optional(),
14920
+ context_key: exports_external.string().optional()
14921
+ });
14922
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/entity.js
14962
14923
  var entityKind = Symbol.for("drizzle:entityKind");
14963
14924
  var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
14964
14925
  function is(value, type) {
@@ -14983,10 +14944,10 @@ function is(value, type) {
14983
14944
  return false;
14984
14945
  }
14985
14946
 
14986
- // ../../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/table.utils.js
14947
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/table.utils.js
14987
14948
  var TableName = Symbol.for("drizzle:Name");
14988
14949
 
14989
- // ../../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/table.js
14950
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/table.js
14990
14951
  var Schema = Symbol.for("drizzle:Schema");
14991
14952
  var Columns = Symbol.for("drizzle:Columns");
14992
14953
  var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
@@ -15024,7 +14985,7 @@ class Table {
15024
14985
  }
15025
14986
  }
15026
14987
 
15027
- // ../../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/column.js
14988
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/column.js
15028
14989
  class Column {
15029
14990
  constructor(table, config2) {
15030
14991
  this.table = table;
@@ -15074,7 +15035,7 @@ class Column {
15074
15035
  }
15075
15036
  }
15076
15037
 
15077
- // ../../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/column-builder.js
15038
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/column-builder.js
15078
15039
  class ColumnBuilder {
15079
15040
  static [entityKind] = "ColumnBuilder";
15080
15041
  config;
@@ -15130,17 +15091,17 @@ class ColumnBuilder {
15130
15091
  }
15131
15092
  }
15132
15093
 
15133
- // ../../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/tracing-utils.js
15094
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/tracing-utils.js
15134
15095
  function iife(fn, ...args) {
15135
15096
  return fn(...args);
15136
15097
  }
15137
15098
 
15138
- // ../../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/pg-core/unique-constraint.js
15099
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/pg-core/unique-constraint.js
15139
15100
  function uniqueKeyName(table, columns) {
15140
15101
  return `${table[TableName]}_${columns.join("_")}_unique`;
15141
15102
  }
15142
15103
 
15143
- // ../../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/pg-core/columns/common.js
15104
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/pg-core/columns/common.js
15144
15105
  class PgColumn extends Column {
15145
15106
  constructor(table, config2) {
15146
15107
  if (!config2.uniqueName) {
@@ -15189,7 +15150,7 @@ class ExtraConfigColumn extends PgColumn {
15189
15150
  }
15190
15151
  }
15191
15152
 
15192
- // ../../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/pg-core/columns/enum.js
15153
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/pg-core/columns/enum.js
15193
15154
  class PgEnumObjectColumn extends PgColumn {
15194
15155
  static [entityKind] = "PgEnumObjectColumn";
15195
15156
  enum;
@@ -15219,7 +15180,7 @@ class PgEnumColumn extends PgColumn {
15219
15180
  }
15220
15181
  }
15221
15182
 
15222
- // ../../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/subquery.js
15183
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/subquery.js
15223
15184
  class Subquery {
15224
15185
  static [entityKind] = "Subquery";
15225
15186
  constructor(sql, fields, alias, isWith = false, usedTables = []) {
@@ -15234,10 +15195,10 @@ class Subquery {
15234
15195
  }
15235
15196
  }
15236
15197
 
15237
- // ../../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/version.js
15198
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/version.js
15238
15199
  var version2 = "0.45.2";
15239
15200
 
15240
- // ../../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/tracing.js
15201
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/tracing.js
15241
15202
  var otel;
15242
15203
  var rawTracer;
15243
15204
  var tracer = {
@@ -15264,10 +15225,10 @@ var tracer = {
15264
15225
  }
15265
15226
  };
15266
15227
 
15267
- // ../../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/view-common.js
15228
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/view-common.js
15268
15229
  var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
15269
15230
 
15270
- // ../../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/sql/sql.js
15231
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sql/sql.js
15271
15232
  function isSQLWrapper(value) {
15272
15233
  return value !== null && value !== undefined && typeof value.getSQL === "function";
15273
15234
  }
@@ -15544,7 +15505,7 @@ function sql(strings, ...params) {
15544
15505
  return new SQL([new StringChunk(str)]);
15545
15506
  }
15546
15507
  sql2.raw = raw;
15547
- function join2(chunks, separator) {
15508
+ function join(chunks, separator) {
15548
15509
  const result = [];
15549
15510
  for (const [i, chunk] of chunks.entries()) {
15550
15511
  if (i > 0 && separator !== undefined) {
@@ -15554,7 +15515,7 @@ function sql(strings, ...params) {
15554
15515
  }
15555
15516
  return new SQL(result);
15556
15517
  }
15557
- sql2.join = join2;
15518
+ sql2.join = join;
15558
15519
  function identifier(value) {
15559
15520
  return new Name(value);
15560
15521
  }
@@ -15627,7 +15588,7 @@ Subquery.prototype.getSQL = function() {
15627
15588
  return new SQL([this]);
15628
15589
  };
15629
15590
 
15630
- // ../../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/utils.js
15591
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/utils.js
15631
15592
  function getColumnNameAndConfig(a, b) {
15632
15593
  return {
15633
15594
  name: typeof a === "string" && a.length > 0 ? a : "",
@@ -15636,7 +15597,7 @@ function getColumnNameAndConfig(a, b) {
15636
15597
  }
15637
15598
  var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
15638
15599
 
15639
- // ../../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/sqlite-core/foreign-keys.js
15600
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
15640
15601
  class ForeignKeyBuilder {
15641
15602
  static [entityKind] = "SQLiteForeignKeyBuilder";
15642
15603
  reference;
@@ -15704,7 +15665,7 @@ function foreignKey(config2) {
15704
15665
  return new ForeignKeyBuilder(mappedConfig);
15705
15666
  }
15706
15667
 
15707
- // ../../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/sqlite-core/unique-constraint.js
15668
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
15708
15669
  function uniqueKeyName2(table, columns) {
15709
15670
  return `${table[TableName]}_${columns.join("_")}_unique`;
15710
15671
  }
@@ -15749,7 +15710,7 @@ class UniqueConstraint {
15749
15710
  }
15750
15711
  }
15751
15712
 
15752
- // ../../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/sqlite-core/columns/common.js
15713
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/common.js
15753
15714
  class SQLiteColumnBuilder extends ColumnBuilder {
15754
15715
  static [entityKind] = "SQLiteColumnBuilder";
15755
15716
  foreignKeyConfigs = [];
@@ -15800,7 +15761,7 @@ class SQLiteColumn extends Column {
15800
15761
  static [entityKind] = "SQLiteColumn";
15801
15762
  }
15802
15763
 
15803
- // ../../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/sqlite-core/columns/blob.js
15764
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/blob.js
15804
15765
  class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
15805
15766
  static [entityKind] = "SQLiteBigIntBuilder";
15806
15767
  constructor(name) {
@@ -15888,7 +15849,7 @@ function blob(a, b) {
15888
15849
  return new SQLiteBlobBufferBuilder(name);
15889
15850
  }
15890
15851
 
15891
- // ../../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/sqlite-core/columns/custom.js
15852
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/custom.js
15892
15853
  class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
15893
15854
  static [entityKind] = "SQLiteCustomColumnBuilder";
15894
15855
  constructor(name, fieldConfig, customTypeParams) {
@@ -15929,7 +15890,7 @@ function customType(customTypeParams) {
15929
15890
  };
15930
15891
  }
15931
15892
 
15932
- // ../../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/sqlite-core/columns/integer.js
15893
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/integer.js
15933
15894
  class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
15934
15895
  static [entityKind] = "SQLiteBaseIntegerBuilder";
15935
15896
  constructor(name, dataType, columnType) {
@@ -16031,7 +15992,7 @@ function integer2(a, b) {
16031
15992
  return new SQLiteIntegerBuilder(name);
16032
15993
  }
16033
15994
 
16034
- // ../../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/sqlite-core/columns/numeric.js
15995
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
16035
15996
  class SQLiteNumericBuilder extends SQLiteColumnBuilder {
16036
15997
  static [entityKind] = "SQLiteNumericBuilder";
16037
15998
  constructor(name) {
@@ -16101,7 +16062,7 @@ function numeric(a, b) {
16101
16062
  return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
16102
16063
  }
16103
16064
 
16104
- // ../../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/sqlite-core/columns/real.js
16065
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/real.js
16105
16066
  class SQLiteRealBuilder extends SQLiteColumnBuilder {
16106
16067
  static [entityKind] = "SQLiteRealBuilder";
16107
16068
  constructor(name) {
@@ -16122,7 +16083,7 @@ function real(name) {
16122
16083
  return new SQLiteRealBuilder(name ?? "");
16123
16084
  }
16124
16085
 
16125
- // ../../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/sqlite-core/columns/text.js
16086
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/text.js
16126
16087
  class SQLiteTextBuilder extends SQLiteColumnBuilder {
16127
16088
  static [entityKind] = "SQLiteTextBuilder";
16128
16089
  constructor(name, config2) {
@@ -16177,7 +16138,7 @@ function text(a, b = {}) {
16177
16138
  return new SQLiteTextBuilder(name, config2);
16178
16139
  }
16179
16140
 
16180
- // ../../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/sqlite-core/columns/all.js
16141
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/columns/all.js
16181
16142
  function getSQLiteColumnBuilders() {
16182
16143
  return {
16183
16144
  blob,
@@ -16189,7 +16150,7 @@ function getSQLiteColumnBuilders() {
16189
16150
  };
16190
16151
  }
16191
16152
 
16192
- // ../../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/sqlite-core/table.js
16153
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/table.js
16193
16154
  var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
16194
16155
 
16195
16156
  class SQLiteTable extends Table {
@@ -16223,7 +16184,7 @@ var sqliteTable = (name, columns, extraConfig) => {
16223
16184
  return sqliteTableBase(name, columns, extraConfig);
16224
16185
  };
16225
16186
 
16226
- // ../../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/sqlite-core/indexes.js
16187
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/indexes.js
16227
16188
  class IndexBuilderOn {
16228
16189
  constructor(name, unique2) {
16229
16190
  this.name = name;
@@ -16266,7 +16227,7 @@ function index(name) {
16266
16227
  return new IndexBuilderOn(name, false);
16267
16228
  }
16268
16229
 
16269
- // ../../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/sqlite-core/primary-keys.js
16230
+ // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260524.1_@opentelemetry+api@1.9.1_@typ_f775720d1395b789318c4e4a4fd2c362/node_modules/drizzle-orm/sqlite-core/primary-keys.js
16270
16231
  function primaryKey(...config2) {
16271
16232
  if (config2[0].columns) {
16272
16233
  return new PrimaryKeyBuilder(config2[0].columns, config2[0].name);
@@ -16856,9 +16817,6 @@ var agentSkill = sqliteTable("agent_skill", {
16856
16817
  // ../shared/src/db/queries/task.ts
16857
16818
  var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
16858
16819
  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
16820
  // ../shared/src/utils/email.ts
16863
16821
  var DOMAIN = `@${process.env.ALOOK_DOMAIN || "alook.ai"}`;
16864
16822
  var RESERVED_HANDLES = new Set([
@@ -16931,6 +16889,54 @@ function cmdPrefix() {
16931
16889
  }));
16932
16890
  }
16933
16891
 
16892
+ // lib/activate.ts
16893
+ import { hostname as hostname4 } from "os";
16894
+
16895
+ // lib/config.ts
16896
+ import { readFileSync, writeFileSync, mkdirSync } from "fs";
16897
+ import { join } from "path";
16898
+ import { homedir } from "os";
16899
+ function configDir() {
16900
+ return process.env.ALOOK_PROJECT_ROOT || join(homedir(), ".alook");
16901
+ }
16902
+ function configPath() {
16903
+ return join(configDir(), "config.json");
16904
+ }
16905
+ function loadCLIConfig() {
16906
+ try {
16907
+ return JSON.parse(readFileSync(configPath(), "utf-8"));
16908
+ } catch {
16909
+ return {};
16910
+ }
16911
+ }
16912
+ function loadCLIConfigForProfile(profile) {
16913
+ const cfg = loadCLIConfig();
16914
+ const profileName = profile || cfg.default_profile;
16915
+ if (profileName && cfg.profiles?.[profileName]) {
16916
+ return cfg.profiles[profileName];
16917
+ }
16918
+ return {
16919
+ server_url: cfg.server_url || "",
16920
+ watched_workspaces: cfg.watched_workspaces || []
16921
+ };
16922
+ }
16923
+ function saveCLIConfig(cfg) {
16924
+ mkdirSync(configDir(), { recursive: true, mode: 448 });
16925
+ writeFileSync(configPath(), JSON.stringify(cfg, null, 2), { mode: 384 });
16926
+ }
16927
+ function saveCLIConfigForProfile(profile, profileConfig) {
16928
+ const cfg = loadCLIConfig();
16929
+ if (profile) {
16930
+ if (!cfg.profiles)
16931
+ cfg.profiles = {};
16932
+ cfg.profiles[profile] = profileConfig;
16933
+ } else {
16934
+ cfg.server_url = profileConfig.server_url;
16935
+ cfg.watched_workspaces = profileConfig.watched_workspaces;
16936
+ }
16937
+ saveCLIConfig(cfg);
16938
+ }
16939
+
16934
16940
  // daemon/pidfile.ts
16935
16941
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, unlinkSync, mkdirSync as mkdirSync2 } from "fs";
16936
16942
  import { dirname as dirname2 } from "path";
@@ -17211,7 +17217,8 @@ function releaseDaemonPid(profile) {
17211
17217
  removePidFileIfMatches(process.pid, profile);
17212
17218
  }
17213
17219
 
17214
- // commands/register.ts
17220
+ // lib/runtimes.ts
17221
+ import { execSync } from "child_process";
17215
17222
  function isCommandAvailable(cmd) {
17216
17223
  try {
17217
17224
  const check2 = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
@@ -17234,6 +17241,90 @@ function detectRuntimes() {
17234
17241
  }
17235
17242
  return found;
17236
17243
  }
17244
+
17245
+ // lib/activate.ts
17246
+ async function activateAndSave(opts) {
17247
+ const { token, serverUrl, profile } = opts;
17248
+ console.log("Scanning for AI runtimes...");
17249
+ const runtimes = detectRuntimes();
17250
+ if (runtimes.length === 0) {
17251
+ console.error("Error: no runtimes found. Install claude, codex, or opencode first.");
17252
+ process.exit(1);
17253
+ }
17254
+ console.log(`Found: ${runtimes.map((r) => r.type).join(", ")}`);
17255
+ const host = hostname4();
17256
+ console.log("Registering runtime...");
17257
+ let activateResp;
17258
+ try {
17259
+ const res = await fetch(`${serverUrl}/api/machine-tokens/activate`, {
17260
+ method: "POST",
17261
+ headers: { "Content-Type": "application/json" },
17262
+ body: JSON.stringify({ token, hostname: host, runtimes })
17263
+ });
17264
+ if (!res.ok) {
17265
+ const text2 = await res.text();
17266
+ console.error(`Error: registration failed (${res.status}): ${text2}`);
17267
+ process.exit(1);
17268
+ }
17269
+ activateResp = await res.json();
17270
+ } catch (err) {
17271
+ console.error(`Error: failed to activate: ${err instanceof Error ? err.message : err}`);
17272
+ process.exit(1);
17273
+ }
17274
+ const client = new APIClient(serverUrl, token);
17275
+ let workspaces;
17276
+ try {
17277
+ workspaces = await client.getJSON("/api/workspaces");
17278
+ } catch (err) {
17279
+ console.error(`Error: failed to fetch workspaces: ${err instanceof Error ? err.message : err}`);
17280
+ process.exit(1);
17281
+ }
17282
+ if (!workspaces.length) {
17283
+ console.error("Error: no workspaces found for this user");
17284
+ process.exit(1);
17285
+ }
17286
+ const ws = workspaces.find((w) => w.id === activateResp.workspace_id) || workspaces[0];
17287
+ const wsClient = new APIClient(serverUrl, token, ws.id);
17288
+ let agentIds = [];
17289
+ try {
17290
+ const agents = await wsClient.getJSON(`/api/agents?workspace_id=${ws.id}`);
17291
+ agentIds = agents.map((a) => a.id);
17292
+ } catch {}
17293
+ const existing = loadCLIConfigForProfile(profile);
17294
+ const watched = existing.watched_workspaces || [];
17295
+ const idx = watched.findIndex((w) => w.id === ws.id);
17296
+ if (idx >= 0) {
17297
+ watched[idx] = { id: ws.id, name: ws.name, token, agent_ids: agentIds };
17298
+ } else {
17299
+ watched.push({ id: ws.id, name: ws.name, token, agent_ids: agentIds });
17300
+ }
17301
+ saveCLIConfigForProfile(profile, {
17302
+ server_url: serverUrl,
17303
+ watched_workspaces: watched
17304
+ });
17305
+ const daemonPid = readDaemonPid(profile);
17306
+ if (daemonPid && isProcessAlive(daemonPid)) {
17307
+ try {
17308
+ process.kill(daemonPid, "SIGHUP");
17309
+ console.log(`
17310
+ Daemon (pid ${daemonPid}) notified — workspace will be active shortly.`);
17311
+ } catch {
17312
+ console.log(`
17313
+ Daemon is running but could not be notified. Restart it to pick up the new workspace.`);
17314
+ }
17315
+ } else {
17316
+ const startCmd = isDev() ? `${cmdPrefix()} daemon start --foreground` : `${cmdPrefix()} daemon start`;
17317
+ console.log();
17318
+ console.log(`Run '${startCmd}' to start the daemon.`);
17319
+ }
17320
+ return {
17321
+ workspaceId: ws.id,
17322
+ workspaceName: ws.name,
17323
+ runtimeProviders: activateResp.runtimes.map((r) => r.provider)
17324
+ };
17325
+ }
17326
+
17327
+ // commands/register.ts
17237
17328
  function registerCommand() {
17238
17329
  const cmd = new Command("register").description("Register CLI with your Alook account").requiredOption("--token <token>", "API token (starts with al_)").option("--server <url>", "Server URL").option("--profile <name>", "Profile name").action(async (opts, command) => {
17239
17330
  const token = opts.token;
@@ -17256,89 +17347,182 @@ Usage: ${cmdPrefix()} register --token <token>`);
17256
17347
  console.error(`Error: failed to verify token: ${err instanceof Error ? err.message : err}`);
17257
17348
  process.exit(1);
17258
17349
  }
17259
- console.log("Scanning for AI runtimes...");
17260
- const runtimes = detectRuntimes();
17261
- if (runtimes.length === 0) {
17262
- console.error("Error: no runtimes found. Install claude, codex, or opencode first.");
17263
- process.exit(1);
17350
+ const result = await activateAndSave({ token, serverUrl, profile });
17351
+ console.log(`
17352
+ Registered as ${me.email}`);
17353
+ console.log(`Workspace: ${result.workspaceName} (${result.workspaceId})`);
17354
+ console.log(`Runtimes: ${result.runtimeProviders.join(", ")}`);
17355
+ });
17356
+ return cmd;
17357
+ }
17358
+
17359
+ // commands/login.ts
17360
+ import { Command as Command2 } from "commander";
17361
+ import { fork, spawn } from "child_process";
17362
+ import { fileURLToPath as fileURLToPath2 } from "url";
17363
+ var DEVICE_CLIENT_ID = process.env.ALOOK_DEVICE_CLIENT_ID || "alook-cli";
17364
+ function openBrowser(url2) {
17365
+ try {
17366
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : process.platform === "win32" ? "start" : null;
17367
+ if (cmd) {
17368
+ const args = process.platform === "win32" ? ["", url2] : [url2];
17369
+ spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
17264
17370
  }
17265
- console.log(`Found: ${runtimes.map((r) => r.type).join(", ")}`);
17266
- const host = hostname4();
17267
- console.log("Registering runtime...");
17268
- let activateResp;
17371
+ } catch {}
17372
+ }
17373
+ function sleep(ms) {
17374
+ return new Promise((resolve) => setTimeout(resolve, ms));
17375
+ }
17376
+ async function pollAndActivate(opts) {
17377
+ const { deviceCode, expiresIn, serverUrl, profile } = opts;
17378
+ let interval = opts.interval;
17379
+ const expiresAt = Date.now() + expiresIn * 1000;
17380
+ let tokenResp;
17381
+ while (Date.now() < expiresAt) {
17382
+ await sleep(interval);
17269
17383
  try {
17270
- const res = await fetch(`${serverUrl}/api/machine-tokens/activate`, {
17384
+ const res = await fetch(`${serverUrl}/api/auth/device/token`, {
17271
17385
  method: "POST",
17272
17386
  headers: { "Content-Type": "application/json" },
17273
- body: JSON.stringify({ token, hostname: host, runtimes })
17387
+ body: JSON.stringify({
17388
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
17389
+ device_code: deviceCode,
17390
+ client_id: DEVICE_CLIENT_ID
17391
+ })
17274
17392
  });
17275
- if (!res.ok) {
17276
- const text2 = await res.text();
17277
- console.error(`Error: registration failed (${res.status}): ${text2}`);
17393
+ if (res.ok) {
17394
+ tokenResp = await res.json();
17395
+ break;
17396
+ }
17397
+ const errBody = await res.json();
17398
+ if (errBody.error === "slow_down") {
17399
+ interval += 5000;
17400
+ } else if (errBody.error === "authorization_pending") {} else if (errBody.error === "expired_token") {
17401
+ console.error("Error: device code expired. Please run login again.");
17402
+ process.exit(1);
17403
+ } else if (errBody.error === "access_denied") {
17404
+ console.error("Error: authorization was denied.");
17405
+ process.exit(1);
17406
+ } else {
17407
+ console.error(`Error: unexpected error: ${errBody.error_description || errBody.error}`);
17278
17408
  process.exit(1);
17279
17409
  }
17280
- activateResp = await res.json();
17281
- } catch (err) {
17282
- console.error(`Error: failed to activate: ${err instanceof Error ? err.message : err}`);
17410
+ } catch {
17411
+ console.error("Error: network request failed during polling.");
17283
17412
  process.exit(1);
17284
17413
  }
17285
- let workspaces;
17414
+ }
17415
+ if (!tokenResp) {
17416
+ console.error("Error: device code expired (timed out). Please run login again.");
17417
+ process.exit(1);
17418
+ }
17419
+ const sessionToken = tokenResp.access_token;
17420
+ const client = new APIClient(serverUrl, sessionToken);
17421
+ let email3 = "";
17422
+ try {
17423
+ const me = await client.getJSON("/api/me");
17424
+ email3 = me.email;
17425
+ } catch {}
17426
+ let existingWorkspaceId = "";
17427
+ try {
17428
+ const workspaces = await client.getJSON("/api/workspaces");
17429
+ if (workspaces.length > 0) {
17430
+ existingWorkspaceId = workspaces[0].id;
17431
+ }
17432
+ } catch {}
17433
+ const mtUrl = existingWorkspaceId ? `/api/machine-tokens?workspace_id=${existingWorkspaceId}` : "/api/machine-tokens";
17434
+ let machineToken2;
17435
+ try {
17436
+ const mtResp = await client.postJSON(mtUrl);
17437
+ machineToken2 = mtResp.token;
17438
+ } catch {
17439
+ process.exit(1);
17440
+ }
17441
+ const result = await activateAndSave({ token: machineToken2, serverUrl, profile });
17442
+ if (email3) {
17443
+ console.log(`
17444
+ Logged in as ${email3}`);
17445
+ }
17446
+ console.log(`Workspace: ${result.workspaceName} (${result.workspaceId})`);
17447
+ console.log(`Runtimes: ${result.runtimeProviders.join(", ")}`);
17448
+ }
17449
+ if (process.argv.includes("--__login-poll")) {
17450
+ const idx = process.argv.indexOf("--__login-poll");
17451
+ let data;
17452
+ try {
17453
+ data = JSON.parse(process.argv[idx + 1]);
17454
+ } catch {
17455
+ console.error("Error: invalid poll data");
17456
+ process.exit(1);
17457
+ }
17458
+ pollAndActivate(data).catch(() => process.exit(1));
17459
+ }
17460
+ function loginCommand() {
17461
+ const cmd = new Command2("login").description("Log in to Alook via browser (device code flow)").option("--server <url>", "Server URL").option("--profile <name>", "Profile name").action(async (opts, command) => {
17462
+ const profile = opts.profile || command.parent?.opts().profile;
17463
+ const serverUrl = opts.server || command.parent?.opts().server || process.env.ALOOK_SERVER_URL || "https://alook.ai";
17464
+ console.log("Requesting device code...");
17465
+ let deviceResp;
17286
17466
  try {
17287
- workspaces = await client.getJSON("/api/workspaces");
17467
+ const res = await fetch(`${serverUrl}/api/auth/device/code`, {
17468
+ method: "POST",
17469
+ headers: { "Content-Type": "application/json" },
17470
+ body: JSON.stringify({ client_id: DEVICE_CLIENT_ID })
17471
+ });
17472
+ if (!res.ok) {
17473
+ const text2 = await res.text();
17474
+ console.error(`Error: failed to get device code (${res.status}): ${text2}`);
17475
+ process.exit(1);
17476
+ }
17477
+ deviceResp = await res.json();
17288
17478
  } catch (err) {
17289
- console.error(`Error: failed to fetch workspaces: ${err instanceof Error ? err.message : err}`);
17290
- process.exit(1);
17291
- }
17292
- if (!workspaces.length) {
17293
- console.error("Error: no workspaces found for this user");
17479
+ console.error(`Error: failed to request device code: ${err instanceof Error ? err.message : err}`);
17294
17480
  process.exit(1);
17295
17481
  }
17296
- const ws = workspaces.find((w) => w.id === activateResp.workspace_id) || workspaces[0];
17297
- const wsClient = new APIClient(serverUrl, token, ws.id);
17298
- let agentIds = [];
17299
- try {
17300
- const agents = await wsClient.getJSON(`/api/agents?workspace_id=${ws.id}`);
17301
- agentIds = agents.map((a) => a.id);
17302
- } catch {}
17303
- const existing = loadCLIConfigForProfile(profile);
17304
- const watched = existing.watched_workspaces || [];
17305
- const idx = watched.findIndex((w) => w.id === ws.id);
17306
- if (idx >= 0) {
17307
- watched[idx] = { id: ws.id, name: ws.name, token, agent_ids: agentIds };
17308
- } else {
17309
- watched.push({ id: ws.id, name: ws.name, token, agent_ids: agentIds });
17482
+ const verificationUrl = deviceResp.verification_uri_complete || deviceResp.verification_uri;
17483
+ console.log();
17484
+ console.log(` Open this URL in your browser:`);
17485
+ console.log(` ${verificationUrl}`);
17486
+ console.log();
17487
+ console.log(` Enter code: ${deviceResp.user_code}`);
17488
+ console.log();
17489
+ if (!process.stdout.isTTY) {
17490
+ const pollData = JSON.stringify({
17491
+ deviceCode: deviceResp.device_code,
17492
+ interval: (deviceResp.interval || 5) * 1000,
17493
+ expiresIn: deviceResp.expires_in,
17494
+ serverUrl,
17495
+ profile
17496
+ });
17497
+ const thisFile = fileURLToPath2(import.meta.url);
17498
+ const child = fork(thisFile, ["--__login-poll", pollData], {
17499
+ detached: true,
17500
+ stdio: "ignore"
17501
+ });
17502
+ child.unref();
17503
+ console.log(" Polling for authorization in the background (timeout: 5min).");
17504
+ console.log(" Once approved, run `npx @alook/cli status` to verify.");
17505
+ return;
17310
17506
  }
17311
- saveCLIConfigForProfile(profile, {
17312
- server_url: serverUrl,
17313
- watched_workspaces: watched
17507
+ openBrowser(verificationUrl);
17508
+ console.log(" (Browser opened automatically)");
17509
+ console.log();
17510
+ console.log("Waiting for authorization...");
17511
+ await pollAndActivate({
17512
+ deviceCode: deviceResp.device_code,
17513
+ interval: (deviceResp.interval || 5) * 1000,
17514
+ expiresIn: deviceResp.expires_in,
17515
+ serverUrl,
17516
+ profile
17314
17517
  });
17315
- console.log(`
17316
- Registered as ${me.email}`);
17317
- console.log(`Workspace: ${ws.name} (${ws.id})`);
17318
- console.log(`Runtimes: ${activateResp.runtimes.map((r) => r.provider).join(", ")}`);
17319
- const daemonPid = readDaemonPid(profile);
17320
- if (daemonPid && isProcessAlive(daemonPid)) {
17321
- try {
17322
- process.kill(daemonPid, "SIGHUP");
17323
- console.log(`
17324
- Daemon (pid ${daemonPid}) notified — workspace will be active shortly.`);
17325
- } catch {
17326
- console.log(`
17327
- Daemon is running but could not be notified. Restart it to pick up the new workspace.`);
17328
- }
17329
- } else {
17330
- const startCmd = isDev() ? `${cmdPrefix()} daemon start --foreground` : `${cmdPrefix()} daemon start`;
17331
- console.log();
17332
- console.log(`Run '${startCmd}' to start the daemon.`);
17333
- }
17334
17518
  });
17335
17519
  return cmd;
17336
17520
  }
17337
17521
 
17338
17522
  // commands/status.ts
17339
- import { Command as Command2 } from "commander";
17523
+ import { Command as Command3 } from "commander";
17340
17524
  function statusCommand() {
17341
- const cmd = new Command2("status").description("Show registration status").action((_opts, command) => {
17525
+ const cmd = new Command3("status").description("Show registration status").action((_opts, command) => {
17342
17526
  const profile = command.parent?.opts().profile;
17343
17527
  const cfg = loadCLIConfigForProfile(profile);
17344
17528
  const ws = cfg.watched_workspaces?.[0];
@@ -17355,8 +17539,8 @@ function statusCommand() {
17355
17539
  }
17356
17540
 
17357
17541
  // commands/daemon.ts
17358
- import { Command as Command3 } from "commander";
17359
- import { spawn as spawn6 } from "child_process";
17542
+ import { Command as Command4 } from "commander";
17543
+ import { spawn as spawn7 } from "child_process";
17360
17544
  import { openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync9 } from "fs";
17361
17545
  import { dirname as dirname4 } from "path";
17362
17546
 
@@ -17512,7 +17696,7 @@ function createHealthServer(port = DEFAULT_HEALTH_PORT) {
17512
17696
  }
17513
17697
 
17514
17698
  // daemon/agent/claude.ts
17515
- import { spawn } from "child_process";
17699
+ import { spawn as spawn2 } from "child_process";
17516
17700
  import { createInterface } from "readline";
17517
17701
 
17518
17702
  class ClaudeBackend {
@@ -17540,7 +17724,7 @@ class ClaudeBackend {
17540
17724
  if (options.resumeSessionId) {
17541
17725
  args.push("--resume", options.resumeSessionId);
17542
17726
  }
17543
- const proc = spawn(this.cliPath, args, {
17727
+ const proc = spawn2(this.cliPath, args, {
17544
17728
  cwd: options.cwd,
17545
17729
  stdio: ["pipe", "pipe", "pipe"],
17546
17730
  env: { ...process.env, ...options.env },
@@ -17777,7 +17961,7 @@ function handleControlRequest(proc, event) {
17777
17961
  }
17778
17962
 
17779
17963
  // daemon/agent/codex.ts
17780
- import { spawn as spawn2 } from "child_process";
17964
+ import { spawn as spawn3 } from "child_process";
17781
17965
  import { createInterface as createInterface2 } from "readline";
17782
17966
  var RAW_DETECTION_METHODS = new Set([
17783
17967
  "turn/started",
@@ -17809,7 +17993,7 @@ class CodexBackend {
17809
17993
  this.cliPath = cliPath;
17810
17994
  }
17811
17995
  execute(prompt, options) {
17812
- const proc = spawn2(this.cliPath, ["app-server", "--listen", "stdio://", "--config", "sandbox_mode=danger-full-access"], {
17996
+ const proc = spawn3(this.cliPath, ["app-server", "--listen", "stdio://", "--config", "sandbox_mode=danger-full-access"], {
17813
17997
  cwd: options.cwd,
17814
17998
  stdio: ["pipe", "pipe", "pipe"],
17815
17999
  env: { ...process.env, ...options.env },
@@ -18281,7 +18465,7 @@ class CodexBackend {
18281
18465
  }
18282
18466
 
18283
18467
  // daemon/agent/opencode.ts
18284
- import { spawn as spawn3 } from "child_process";
18468
+ import { spawn as spawn4 } from "child_process";
18285
18469
  import { createInterface as createInterface3 } from "readline";
18286
18470
 
18287
18471
  class OpenCodeBackend {
@@ -18299,7 +18483,7 @@ class OpenCodeBackend {
18299
18483
  args.push("--session", options.resumeSessionId);
18300
18484
  }
18301
18485
  args.push(prompt);
18302
- const proc = spawn3(this.cliPath, args, {
18486
+ const proc = spawn4(this.cliPath, args, {
18303
18487
  cwd: options.cwd,
18304
18488
  stdio: ["ignore", "pipe", "pipe"],
18305
18489
  env: { ...process.env, ...options.env, OPENCODE_PERMISSION: '{"*":"allow"}' },
@@ -18831,6 +19015,23 @@ Upload files for your owner to review in the app.
18831
19015
  When your task includes attachments, their local paths are listed in the prompt JSON under "attachments".
18832
19016
  Use your Read tool to open them. Images and PDFs are read visually.
18833
19017
  ---
19018
+ `;
19019
+ content += `
19020
+ ### Agent Management
19021
+ Recruit new colleague agents directly from the CLI. The server auto-generates a name and email handle.
19022
+ - Run '${cmdPrefix()} agent recruit --instructions "<SYSTEM_PROMPT>" --relationship "<DELEGATION_CRITERIA>"'
19023
+ - '--instructions' — the new agent's system prompt (what it does, how it behaves)
19024
+ - '--relationship' — delegation criteria shown in both agents' COLLEAGUES section
19025
+ - '--name <name>' (optional) — preferred name; server generates one if omitted
19026
+ - '--description <text>' (optional) — agent description
19027
+ - '--model <model>' (optional) — model override
19028
+ - '--instructions-file <path>' — alternative: read instructions from a file (mutually exclusive with --instructions)
19029
+ - '--relationship-file <path>' — alternative: read relationship from a file (mutually exclusive with --relationship)
19030
+ - '--json' — output full JSON response
19031
+ - Example: '${cmdPrefix()} agent recruit --instructions "You are a QA engineer..." --relationship "DELEGATE when: code is ready for review"'
19032
+ - Output: 'Recruited Felix (felix@alook.ai) — ag_xK9mPq2z'
19033
+ - The new agent shares your runtime, is automatically linked as your colleague, and receives a welcome task.
19034
+ ---
18834
19035
  `;
18835
19036
  content += `
18836
19037
  ### Calendar
@@ -19056,7 +19257,7 @@ function localISOString() {
19056
19257
  function lockPathFor(timelineDir, filename) {
19057
19258
  return join7(timelineDir, `.${filename}.lock`);
19058
19259
  }
19059
- function sleep(ms) {
19260
+ function sleep2(ms) {
19060
19261
  return new Promise((resolve) => setTimeout(resolve, ms));
19061
19262
  }
19062
19263
  async function initEntryAsync(timelineDir, entry) {
@@ -19066,7 +19267,7 @@ async function initEntryAsync(timelineDir, entry) {
19066
19267
  try {
19067
19268
  let acquired = acquireLock(lockPath);
19068
19269
  if (!acquired) {
19069
- await sleep(200);
19270
+ await sleep2(200);
19070
19271
  acquired = acquireLock(lockPath);
19071
19272
  }
19072
19273
  if (!acquired) {
@@ -19868,7 +20069,7 @@ class DaemonWsClient {
19868
20069
  import { readFileSync as readFileSync7, writeFileSync as writeFileSync6, unlinkSync as unlinkSync4 } from "fs";
19869
20070
 
19870
20071
  // lib/update.ts
19871
- import { spawn as spawn4 } from "child_process";
20072
+ import { spawn as spawn5 } from "child_process";
19872
20073
  function fetchLatestVersion() {
19873
20074
  return fetch("https://registry.npmjs.org/@alook/cli/latest").then((res) => {
19874
20075
  if (!res.ok)
@@ -19879,7 +20080,7 @@ function fetchLatestVersion() {
19879
20080
  function runNpmUpdate(targetVersion) {
19880
20081
  return new Promise((resolve) => {
19881
20082
  const chunks = [];
19882
- const child = spawn4("npm", ["install", "-g", `@alook/cli@${targetVersion}`], {
20083
+ const child = spawn5("npm", ["install", "-g", `@alook/cli@${targetVersion}`], {
19883
20084
  stdio: ["ignore", "pipe", "pipe"]
19884
20085
  });
19885
20086
  child.stdout?.on("data", (d) => chunks.push(d));
@@ -20432,11 +20633,11 @@ function resolveLoginShellEnv() {
20432
20633
  // daemon/daemon.ts
20433
20634
  import { existsSync as existsSync3, mkdirSync as mkdirSync8, openSync, closeSync, readdirSync as readdirSync3, statSync as statSync4, unlinkSync as unlinkSync5 } from "fs";
20434
20635
  import { readdir as readdir2, readFile as readFile2, unlink, stat as fsStat } from "fs/promises";
20435
- import { execSync as execSync4, spawn as spawn5 } from "child_process";
20436
- import { fileURLToPath as fileURLToPath2 } from "url";
20636
+ import { execSync as execSync4, spawn as spawn6 } from "child_process";
20637
+ import { fileURLToPath as fileURLToPath3 } from "url";
20437
20638
  import { dirname as dirname3, join as join11 } from "path";
20438
20639
  var log9 = createLogger2({ module: "daemon" });
20439
- var _dir = dirname3(fileURLToPath2(import.meta.url));
20640
+ var _dir = dirname3(fileURLToPath3(import.meta.url));
20440
20641
  var sessionRunnerPath = existsSync3(join11(_dir, "session-runner.js")) ? join11(_dir, "session-runner.js") : join11(_dir, "session-runner.ts");
20441
20642
  var meetingRunnerPath = existsSync3(join11(_dir, "meeting-runner.js")) ? join11(_dir, "meeting-runner.js") : join11(_dir, "meeting-runner.ts");
20442
20643
  function isCommandAvailable2(cmd) {
@@ -20888,17 +21089,17 @@ async function startDaemon(profile, serverUrl) {
20888
21089
  break;
20889
21090
  case "daemon.kill": {
20890
21091
  const ws = workspaceStates.find((w) => w.workspaceId === msg.workspaceId);
20891
- if (ws) {
21092
+ if (ws && !activeTasks.has(msg.taskId)) {
20892
21093
  const killTask = fromApiTask({
20893
21094
  id: msg.taskId,
20894
- agent_id: "",
21095
+ agent_id: msg.agentId,
20895
21096
  runtime_id: "",
20896
21097
  conversation_id: "",
20897
21098
  workspace_id: ws.workspaceId,
20898
21099
  prompt: "",
20899
- status: "queued",
21100
+ status: "dispatched",
20900
21101
  priority: 0,
20901
- dispatched_at: null,
21102
+ dispatched_at: new Date().toISOString(),
20902
21103
  started_at: null,
20903
21104
  completed_at: null,
20904
21105
  result: null,
@@ -20997,7 +21198,7 @@ async function startDaemon(profile, serverUrl) {
20997
21198
  } catch (e) {
20998
21199
  log9.error(`Failed to open daemon log file ${logPath}`, e);
20999
21200
  }
21000
- const child = spawn5(process.execPath, args, {
21201
+ const child = spawn6(process.execPath, args, {
21001
21202
  detached: true,
21002
21203
  stdio: logFd != null ? ["ignore", logFd, logFd] : ["ignore", "ignore", "ignore"],
21003
21204
  env: resolveLoginShellEnv()
@@ -21072,7 +21273,7 @@ function spawnSessionRunner(input) {
21072
21273
  } catch (e) {
21073
21274
  log9.error(`Failed to open log file ${logFilePath}`, e);
21074
21275
  }
21075
- const child = spawn5(process.execPath, [sessionRunnerPath, encoded], {
21276
+ const child = spawn6(process.execPath, [sessionRunnerPath, encoded], {
21076
21277
  detached: true,
21077
21278
  stdio: fd != null ? ["ignore", fd, fd] : ["ignore", "ignore", "ignore"]
21078
21279
  });
@@ -21092,7 +21293,7 @@ function spawnMeetingRunner(input) {
21092
21293
  } catch (e) {
21093
21294
  log9.error(`Failed to open meeting log file ${logFilePath}`, e);
21094
21295
  }
21095
- const child = spawn5(process.execPath, [meetingRunnerPath, encoded], {
21296
+ const child = spawn6(process.execPath, [meetingRunnerPath, encoded], {
21096
21297
  detached: true,
21097
21298
  stdio: fd != null ? ["ignore", fd, fd] : ["ignore", "ignore", "ignore"]
21098
21299
  });
@@ -21258,9 +21459,16 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
21258
21459
  child.on("close", async (code) => {
21259
21460
  activeTasks.delete(task.id);
21260
21461
  if (code !== 0) {
21462
+ const agentBaseDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
21463
+ const killIntent = readKillIntent(agentBaseDir, task.id);
21464
+ if (killIntent) {
21465
+ log9.info(`Task ${task.id} exited due to kill intent — skipping failTask`);
21466
+ clearKillIntent(agentBaseDir, task.id);
21467
+ return;
21468
+ }
21261
21469
  const msg = code === null ? `session-runner killed by signal (task ${task.id})` : `session-runner crashed (exit code ${code}, task ${task.id})`;
21262
21470
  log9.warn(msg);
21263
- const timelineDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir", ".context_timeline");
21471
+ const timelineDir = join11(agentBaseDir, ".context_timeline");
21264
21472
  updateEntry(timelineDir, task.id, (entry) => {
21265
21473
  entry.pid = null;
21266
21474
  entry.status = "failed";
@@ -21294,7 +21502,7 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
21294
21502
  var PID_POLL_INTERVAL_MS = 200;
21295
21503
  var PID_POLL_TIMEOUT_MS = 2000;
21296
21504
  var STOP_POLL_INTERVAL_MS = 200;
21297
- function sleep2(ms) {
21505
+ function sleep3(ms) {
21298
21506
  return new Promise((r) => setTimeout(r, ms));
21299
21507
  }
21300
21508
  function buildChildArgs(profile, serverUrl) {
@@ -21313,7 +21521,7 @@ async function waitForPidFile(profile) {
21313
21521
  const pid = readDaemonPid(profile);
21314
21522
  if (pid != null && isProcessAlive(pid))
21315
21523
  return pid;
21316
- await sleep2(PID_POLL_INTERVAL_MS);
21524
+ await sleep3(PID_POLL_INTERVAL_MS);
21317
21525
  }
21318
21526
  return null;
21319
21527
  }
@@ -21327,7 +21535,7 @@ async function startInBackground(profile, serverUrl) {
21327
21535
  const logPath = daemonLogFilePath();
21328
21536
  mkdirSync9(dirname4(logPath), { recursive: true, mode: 448 });
21329
21537
  const logFd = openSync2(logPath, "a", 384);
21330
- const child = spawn6(process.execPath, buildChildArgs(profile, serverUrl), {
21538
+ const child = spawn7(process.execPath, buildChildArgs(profile, serverUrl), {
21331
21539
  detached: true,
21332
21540
  stdio: ["ignore", logFd, logFd],
21333
21541
  env: resolveLoginShellEnv()
@@ -21381,7 +21589,7 @@ async function stopCommand(profile) {
21381
21589
  console.log("Daemon stopped.");
21382
21590
  return;
21383
21591
  }
21384
- await sleep2(STOP_POLL_INTERVAL_MS);
21592
+ await sleep3(STOP_POLL_INTERVAL_MS);
21385
21593
  }
21386
21594
  console.warn(`Daemon did not exit within ${shutdownMs}ms — force killing.`);
21387
21595
  if (!isWindows) {
@@ -21393,7 +21601,7 @@ async function stopCommand(profile) {
21393
21601
  console.log("Daemon stopped.");
21394
21602
  }
21395
21603
  function daemonCommand2() {
21396
- const cmd = new Command3("daemon").description("Manage the Alook daemon");
21604
+ const cmd = new Command4("daemon").description("Manage the Alook daemon");
21397
21605
  cmd.command("start").description("Start the daemon").option("--foreground", "Run in foreground").option("--server <url>", "Server URL override").action(async (opts, command) => {
21398
21606
  const parentOpts = command.parent?.parent?.opts() || {};
21399
21607
  const profile = parentOpts.profile;
@@ -21416,7 +21624,7 @@ function daemonCommand2() {
21416
21624
  }
21417
21625
 
21418
21626
  // commands/config.ts
21419
- import { Command as Command4 } from "commander";
21627
+ import { Command as Command5 } from "commander";
21420
21628
 
21421
21629
  // lib/output.ts
21422
21630
  function printTable(headers, rows) {
@@ -21433,7 +21641,7 @@ function printJSON(data) {
21433
21641
 
21434
21642
  // commands/config.ts
21435
21643
  function configCommand() {
21436
- const cmd = new Command4("config").description("Manage CLI configuration");
21644
+ const cmd = new Command5("config").description("Manage CLI configuration");
21437
21645
  cmd.command("show").description("Show current configuration").action(() => {
21438
21646
  const cfg = loadCLIConfig();
21439
21647
  printJSON(cfg);
@@ -21445,7 +21653,7 @@ function configCommand() {
21445
21653
  }
21446
21654
 
21447
21655
  // commands/email.ts
21448
- import { Command as Command5 } from "commander";
21656
+ import { Command as Command6 } from "commander";
21449
21657
  import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync10, readFileSync as readFileSync11 } from "fs";
21450
21658
  import { join as join12 } from "path";
21451
21659
  import PostalMime from "postal-mime";
@@ -21602,7 +21810,7 @@ var VALID_STATUSES = ["unread", "read", "archived", "sent"];
21602
21810
  var VALID_FOLDERS = ["inbox", "sent", "untrust"];
21603
21811
  var EMAIL_BASE = tempDir("alook-emails");
21604
21812
  function emailCommand() {
21605
- const cmd = new Command5("email").description("Manage agent emails");
21813
+ const cmd = new Command6("email").description("Manage agent emails");
21606
21814
  cmd.command("pull").description("Download and parse emails to /tmp/alook-emails/{workspaceId}/{agentId}/").option("--agent_id <id>", "Agent ID").option("--email_id <id>", "Fetch a single email by ID (mutually exclusive with --status/--folder/--limit/--offset)").option("--status <status>", "Filter by status (unread, read, archived)").option("--folder <folder>", "Email folder (inbox, sent, untrust)").option("--limit <n>", "Maximum number of emails to download").option("--offset <n>", "Number of emails to skip").option("--workspace <id>", "Workspace ID").option("--json", "Output as JSON instead of files").action(async (opts, command) => {
21607
21815
  const agentId = resolveAgentId(opts);
21608
21816
  const { serverUrl, token, workspaceId } = resolveClientOpts(command, { workspace: opts.workspace, agentId });
@@ -21888,7 +22096,7 @@ function emailCommand() {
21888
22096
  process.exit(1);
21889
22097
  }
21890
22098
  });
21891
- const whitelistCmd = new Command5("whitelist").description("Manage email whitelist (allowed senders)");
22099
+ const whitelistCmd = new Command6("whitelist").description("Manage email whitelist (allowed senders)");
21892
22100
  whitelistCmd.command("list").description("List all whitelisted emails for an agent").option("--agent_id <id>", "Agent ID").option("--workspace <id>", "Workspace ID").option("--json", "Output as JSON").action(async (opts, command) => {
21893
22101
  const agentId = resolveAgentId(opts);
21894
22102
  const { serverUrl, token, workspaceId } = resolveClientOpts(command, {
@@ -21962,7 +22170,7 @@ function emailCommand() {
21962
22170
  }
21963
22171
 
21964
22172
  // commands/calendar.ts
21965
- import { Command as Command6 } from "commander";
22173
+ import { Command as Command7 } from "commander";
21966
22174
  function parseLocalDatetime(input) {
21967
22175
  const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2}))?$/.exec(input);
21968
22176
  if (!match) {
@@ -21993,7 +22201,7 @@ function printEventDetail(ev) {
21993
22201
  console.log(ev.description ?? "(no description)");
21994
22202
  }
21995
22203
  function calendarCommand() {
21996
- const cmd = new Command6("calendar").description("Manage scheduled agent events");
22204
+ const cmd = new Command7("calendar").description("Manage scheduled agent events");
21997
22205
  cmd.command("set").description("Create a calendar event").option("--agent_id <id>", "Agent ID").requiredOption("--event_title <title>", "Event title (used as the task prompt)").requiredOption("--datetime <iso>", "Scheduled datetime (YYYY-MM-DDTHH:MM, local time)").option("--description <text>", "Optional longer-form notes for the event").option("--repeat <interval>", "Repeat interval, e.g. 1day, 2hour, 1month").option("--repeat_stop_date <date>", "Stop repeating on or after this date (YYYY-MM-DD, local time)").option("--json", "Output as JSON").action(async (opts, command) => {
21998
22206
  const agentId = resolveAgentId(opts);
21999
22207
  const { serverUrl, token, workspaceId } = resolveClientOpts(command, { agentId });
@@ -22165,7 +22373,7 @@ function calendarCommand() {
22165
22373
  }
22166
22374
 
22167
22375
  // commands/issue.ts
22168
- import { Command as Command7 } from "commander";
22376
+ import { Command as Command8 } from "commander";
22169
22377
  var VALID_STATUSES2 = ["todo", "in_progress", "review", "done", "closed", "canceled", "failed"];
22170
22378
  function printIssue(issue3) {
22171
22379
  console.log(`${issue3.id} ${issue3.status.padEnd(11)} ${issue3.title}`);
@@ -22197,7 +22405,7 @@ comments:`);
22197
22405
  }
22198
22406
  }
22199
22407
  function issueCommand() {
22200
- const cmd = new Command7("issue").description("Manage assigned issues");
22408
+ const cmd = new Command8("issue").description("Manage assigned issues");
22201
22409
  cmd.command("create").description("Create and dispatch an issue to an agent").option("--agent_id <id>", "Agent ID").requiredOption("--title <title>", "Issue title").option("--description <text>", "Issue description").option("--body-file <path>", "Read issue description from a file").option("--json", "Output as JSON").action(async (opts, command) => {
22202
22410
  const agentId = resolveAgentId(opts);
22203
22411
  const { serverUrl, token, workspaceId } = resolveClientOpts(command, { agentId });
@@ -22315,19 +22523,70 @@ function issueCommand() {
22315
22523
  return cmd;
22316
22524
  }
22317
22525
 
22526
+ // commands/agent.ts
22527
+ import { Command as Command9 } from "commander";
22528
+ import { readFileSync as readFileSync12 } from "fs";
22529
+ function readField(opts, inlineName, fileName) {
22530
+ if (opts.inline && opts.file) {
22531
+ console.error(`Error: --${inlineName} and --${fileName} are mutually exclusive`);
22532
+ process.exit(1);
22533
+ }
22534
+ if (opts.file)
22535
+ return readFileSync12(opts.file, "utf-8");
22536
+ return opts.inline ?? null;
22537
+ }
22538
+ function agentCommand() {
22539
+ const cmd = new Command9("agent").description("Manage agents");
22540
+ 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) => {
22541
+ const instructions = readField({ inline: opts.instructions, file: opts.instructionsFile }, "instructions", "instructions-file");
22542
+ if (!instructions) {
22543
+ console.error("Error: --instructions or --instructions-file is required");
22544
+ process.exit(1);
22545
+ }
22546
+ const relationship = readField({ inline: opts.relationship, file: opts.relationshipFile }, "relationship", "relationship-file");
22547
+ if (!relationship) {
22548
+ console.error("Error: --relationship or --relationship-file is required");
22549
+ process.exit(1);
22550
+ }
22551
+ const agentId = resolveAgentId(opts);
22552
+ const { serverUrl, token, workspaceId } = resolveClientOpts(command, { agentId });
22553
+ const client = new APIClient(serverUrl, token, workspaceId);
22554
+ const ctx = gatherContextEnvVars();
22555
+ const body = { instructions, relationship };
22556
+ if (opts.name)
22557
+ body.name = opts.name;
22558
+ if (opts.description)
22559
+ body.description = opts.description;
22560
+ if (opts.model)
22561
+ body.model = opts.model;
22562
+ if (ctx.conversationId)
22563
+ body.context_key = ctx.conversationId;
22564
+ try {
22565
+ const res = await client.postJSON(`/api/agents/recruit?agentId=${encodeURIComponent(agentId)}`, body);
22566
+ if (opts.json)
22567
+ return printJSON(res);
22568
+ console.log(`Recruited ${res.agent.name} (${res.agent.email}) — ${res.agent.id}`);
22569
+ } catch (err) {
22570
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
22571
+ process.exit(1);
22572
+ }
22573
+ });
22574
+ return cmd;
22575
+ }
22576
+
22318
22577
  // commands/version.ts
22319
- import { Command as Command8 } from "commander";
22578
+ import { Command as Command10 } from "commander";
22320
22579
  function versionCommand() {
22321
- const cmd = new Command8("version").description("Show CLI version").action(() => {
22580
+ const cmd = new Command10("version").description("Show CLI version").action(() => {
22322
22581
  console.log(`alook version ${getCurrentVersion()}`);
22323
22582
  });
22324
22583
  return cmd;
22325
22584
  }
22326
22585
 
22327
22586
  // commands/update.ts
22328
- import { Command as Command9 } from "commander";
22587
+ import { Command as Command11 } from "commander";
22329
22588
  function updateCommand() {
22330
- const cmd = new Command9("update").description("Update CLI to the latest version").action(async () => {
22589
+ const cmd = new Command11("update").description("Update CLI to the latest version").action(async () => {
22331
22590
  const current = getCurrentVersion();
22332
22591
  console.log(`Current version: ${current}`);
22333
22592
  const latest = await fetchLatestVersion();
@@ -22361,18 +22620,18 @@ ${result.output}`);
22361
22620
  }
22362
22621
 
22363
22622
  // commands/sync.ts
22364
- import { Command as Command10 } from "commander";
22365
- import { readFileSync as readFileSync12 } from "fs";
22623
+ import { Command as Command12 } from "commander";
22624
+ import { readFileSync as readFileSync13 } from "fs";
22366
22625
  import { basename as basename3 } from "path";
22367
22626
  function syncCommand() {
22368
- const cmd = new Command10("sync").description("File sync utilities");
22627
+ const cmd = new Command12("sync").description("File sync utilities");
22369
22628
  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
22629
  const agentId = resolveAgentId(opts);
22371
22630
  const { serverUrl, token, workspaceId } = resolveClientOpts(command, { agentId });
22372
22631
  const client = new APIClient(serverUrl, token, workspaceId);
22373
22632
  let bytes;
22374
22633
  try {
22375
- bytes = readFileSync12(opts.file);
22634
+ bytes = readFileSync13(opts.file);
22376
22635
  } catch (err) {
22377
22636
  console.error(`Error: cannot read file "${opts.file}": ${err.message}`);
22378
22637
  process.exit(1);
@@ -22395,14 +22654,16 @@ function syncCommand() {
22395
22654
  }
22396
22655
 
22397
22656
  // src/index.ts
22398
- var program = new Command11;
22657
+ var program = new Command13;
22399
22658
  program.name("alook").description("Alook CLI").option("--server <url>", "Server URL").option("--profile <name>", "Profile name");
22400
22659
  program.addCommand(registerCommand());
22660
+ program.addCommand(loginCommand());
22401
22661
  program.addCommand(statusCommand());
22402
22662
  program.addCommand(daemonCommand2());
22403
22663
  program.addCommand(emailCommand());
22404
22664
  program.addCommand(calendarCommand());
22405
22665
  program.addCommand(issueCommand());
22666
+ program.addCommand(agentCommand());
22406
22667
  program.addCommand(configCommand());
22407
22668
  program.addCommand(versionCommand());
22408
22669
  program.addCommand(updateCommand());