@alook/cli 0.0.91 → 0.0.93

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
@@ -14923,6 +14923,21 @@ var WorkspaceFileReportSchema = exports_external.object({
14923
14923
  error: exports_external.string().optional(),
14924
14924
  path: exports_external.string()
14925
14925
  });
14926
+ var SkillEntrySchema = exports_external.object({
14927
+ name: exports_external.string(),
14928
+ description: exports_external.string(),
14929
+ isGlobal: exports_external.boolean().optional()
14930
+ });
14931
+ var SkillItemSchema = exports_external.object({
14932
+ name: exports_external.string(),
14933
+ description: exports_external.string()
14934
+ });
14935
+ var SkillSyncRequestSchema = exports_external.object({
14936
+ scope: exports_external.enum(["global", "agent"]),
14937
+ agent_id: exports_external.string().min(1).optional(),
14938
+ runtime: exports_external.enum(["claude", "codex", "opencode"]),
14939
+ skills: exports_external.array(SkillItemSchema)
14940
+ });
14926
14941
  var StudioMemberSchema = exports_external.object({
14927
14942
  name: exports_external.string().optional(),
14928
14943
  role: exports_external.enum(["leader", "researcher", "engineer", "assistant"]),
@@ -14938,7 +14953,7 @@ var CreateStudioRequestSchema = exports_external.object({
14938
14953
  scenario: exports_external.string().max(50).optional(),
14939
14954
  members: exports_external.array(StudioMemberSchema).min(1).max(4)
14940
14955
  }).refine((v) => v.members.some((m) => m.role === "leader"), { message: "at least one member must have the leader role" });
14941
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/entity.js
14956
+ // ../../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
14942
14957
  var entityKind = Symbol.for("drizzle:entityKind");
14943
14958
  var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
14944
14959
  function is(value, type) {
@@ -14963,10 +14978,10 @@ function is(value, type) {
14963
14978
  return false;
14964
14979
  }
14965
14980
 
14966
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/table.utils.js
14981
+ // ../../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
14967
14982
  var TableName = Symbol.for("drizzle:Name");
14968
14983
 
14969
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/table.js
14984
+ // ../../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
14970
14985
  var Schema = Symbol.for("drizzle:Schema");
14971
14986
  var Columns = Symbol.for("drizzle:Columns");
14972
14987
  var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
@@ -15004,7 +15019,7 @@ class Table {
15004
15019
  }
15005
15020
  }
15006
15021
 
15007
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/column.js
15022
+ // ../../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
15008
15023
  class Column {
15009
15024
  constructor(table, config2) {
15010
15025
  this.table = table;
@@ -15054,7 +15069,7 @@ class Column {
15054
15069
  }
15055
15070
  }
15056
15071
 
15057
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/column-builder.js
15072
+ // ../../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
15058
15073
  class ColumnBuilder {
15059
15074
  static [entityKind] = "ColumnBuilder";
15060
15075
  config;
@@ -15110,17 +15125,17 @@ class ColumnBuilder {
15110
15125
  }
15111
15126
  }
15112
15127
 
15113
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/tracing-utils.js
15128
+ // ../../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
15114
15129
  function iife(fn, ...args) {
15115
15130
  return fn(...args);
15116
15131
  }
15117
15132
 
15118
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/pg-core/unique-constraint.js
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/pg-core/unique-constraint.js
15119
15134
  function uniqueKeyName(table, columns) {
15120
15135
  return `${table[TableName]}_${columns.join("_")}_unique`;
15121
15136
  }
15122
15137
 
15123
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/pg-core/columns/common.js
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/columns/common.js
15124
15139
  class PgColumn extends Column {
15125
15140
  constructor(table, config2) {
15126
15141
  if (!config2.uniqueName) {
@@ -15169,7 +15184,7 @@ class ExtraConfigColumn extends PgColumn {
15169
15184
  }
15170
15185
  }
15171
15186
 
15172
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/pg-core/columns/enum.js
15187
+ // ../../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
15173
15188
  class PgEnumObjectColumn extends PgColumn {
15174
15189
  static [entityKind] = "PgEnumObjectColumn";
15175
15190
  enum;
@@ -15199,7 +15214,7 @@ class PgEnumColumn extends PgColumn {
15199
15214
  }
15200
15215
  }
15201
15216
 
15202
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/subquery.js
15217
+ // ../../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
15203
15218
  class Subquery {
15204
15219
  static [entityKind] = "Subquery";
15205
15220
  constructor(sql, fields, alias, isWith = false, usedTables = []) {
@@ -15214,10 +15229,10 @@ class Subquery {
15214
15229
  }
15215
15230
  }
15216
15231
 
15217
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/version.js
15232
+ // ../../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
15218
15233
  var version2 = "0.45.2";
15219
15234
 
15220
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/tracing.js
15235
+ // ../../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
15221
15236
  var otel;
15222
15237
  var rawTracer;
15223
15238
  var tracer = {
@@ -15244,10 +15259,10 @@ var tracer = {
15244
15259
  }
15245
15260
  };
15246
15261
 
15247
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/view-common.js
15262
+ // ../../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
15248
15263
  var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
15249
15264
 
15250
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sql/sql.js
15265
+ // ../../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
15251
15266
  function isSQLWrapper(value) {
15252
15267
  return value !== null && value !== undefined && typeof value.getSQL === "function";
15253
15268
  }
@@ -15607,7 +15622,7 @@ Subquery.prototype.getSQL = function() {
15607
15622
  return new SQL([this]);
15608
15623
  };
15609
15624
 
15610
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/utils.js
15625
+ // ../../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
15611
15626
  function getColumnNameAndConfig(a, b) {
15612
15627
  return {
15613
15628
  name: typeof a === "string" && a.length > 0 ? a : "",
@@ -15616,7 +15631,7 @@ function getColumnNameAndConfig(a, b) {
15616
15631
  }
15617
15632
  var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
15618
15633
 
15619
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
15634
+ // ../../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
15620
15635
  class ForeignKeyBuilder {
15621
15636
  static [entityKind] = "SQLiteForeignKeyBuilder";
15622
15637
  reference;
@@ -15684,7 +15699,7 @@ function foreignKey(config2) {
15684
15699
  return new ForeignKeyBuilder(mappedConfig);
15685
15700
  }
15686
15701
 
15687
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
15702
+ // ../../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
15688
15703
  function uniqueKeyName2(table, columns) {
15689
15704
  return `${table[TableName]}_${columns.join("_")}_unique`;
15690
15705
  }
@@ -15729,7 +15744,7 @@ class UniqueConstraint {
15729
15744
  }
15730
15745
  }
15731
15746
 
15732
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/common.js
15747
+ // ../../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
15733
15748
  class SQLiteColumnBuilder extends ColumnBuilder {
15734
15749
  static [entityKind] = "SQLiteColumnBuilder";
15735
15750
  foreignKeyConfigs = [];
@@ -15780,7 +15795,7 @@ class SQLiteColumn extends Column {
15780
15795
  static [entityKind] = "SQLiteColumn";
15781
15796
  }
15782
15797
 
15783
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/blob.js
15798
+ // ../../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
15784
15799
  class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
15785
15800
  static [entityKind] = "SQLiteBigIntBuilder";
15786
15801
  constructor(name) {
@@ -15868,7 +15883,7 @@ function blob(a, b) {
15868
15883
  return new SQLiteBlobBufferBuilder(name);
15869
15884
  }
15870
15885
 
15871
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/custom.js
15886
+ // ../../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
15872
15887
  class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
15873
15888
  static [entityKind] = "SQLiteCustomColumnBuilder";
15874
15889
  constructor(name, fieldConfig, customTypeParams) {
@@ -15909,7 +15924,7 @@ function customType(customTypeParams) {
15909
15924
  };
15910
15925
  }
15911
15926
 
15912
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/integer.js
15927
+ // ../../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
15913
15928
  class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
15914
15929
  static [entityKind] = "SQLiteBaseIntegerBuilder";
15915
15930
  constructor(name, dataType, columnType) {
@@ -16011,7 +16026,7 @@ function integer2(a, b) {
16011
16026
  return new SQLiteIntegerBuilder(name);
16012
16027
  }
16013
16028
 
16014
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
16029
+ // ../../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
16015
16030
  class SQLiteNumericBuilder extends SQLiteColumnBuilder {
16016
16031
  static [entityKind] = "SQLiteNumericBuilder";
16017
16032
  constructor(name) {
@@ -16081,7 +16096,7 @@ function numeric(a, b) {
16081
16096
  return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
16082
16097
  }
16083
16098
 
16084
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/real.js
16099
+ // ../../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
16085
16100
  class SQLiteRealBuilder extends SQLiteColumnBuilder {
16086
16101
  static [entityKind] = "SQLiteRealBuilder";
16087
16102
  constructor(name) {
@@ -16102,7 +16117,7 @@ function real(name) {
16102
16117
  return new SQLiteRealBuilder(name ?? "");
16103
16118
  }
16104
16119
 
16105
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/text.js
16120
+ // ../../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
16106
16121
  class SQLiteTextBuilder extends SQLiteColumnBuilder {
16107
16122
  static [entityKind] = "SQLiteTextBuilder";
16108
16123
  constructor(name, config2) {
@@ -16157,7 +16172,7 @@ function text(a, b = {}) {
16157
16172
  return new SQLiteTextBuilder(name, config2);
16158
16173
  }
16159
16174
 
16160
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/columns/all.js
16175
+ // ../../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
16161
16176
  function getSQLiteColumnBuilders() {
16162
16177
  return {
16163
16178
  blob,
@@ -16169,7 +16184,7 @@ function getSQLiteColumnBuilders() {
16169
16184
  };
16170
16185
  }
16171
16186
 
16172
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/table.js
16187
+ // ../../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
16173
16188
  var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
16174
16189
 
16175
16190
  class SQLiteTable extends Table {
@@ -16203,7 +16218,7 @@ var sqliteTable = (name, columns, extraConfig) => {
16203
16218
  return sqliteTableBase(name, columns, extraConfig);
16204
16219
  };
16205
16220
 
16206
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/indexes.js
16221
+ // ../../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
16207
16222
  class IndexBuilderOn {
16208
16223
  constructor(name, unique2) {
16209
16224
  this.name = name;
@@ -16246,7 +16261,7 @@ function index(name) {
16246
16261
  return new IndexBuilderOn(name, false);
16247
16262
  }
16248
16263
 
16249
- // ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudflare+workers-types@4.20260517.1_@opentelemetry+api@1.9.1_bun-types@1.3.14_kysely@0.28.17/node_modules/drizzle-orm/sqlite-core/primary-keys.js
16264
+ // ../../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
16250
16265
  function primaryKey(...config2) {
16251
16266
  if (config2[0].columns) {
16252
16267
  return new PrimaryKeyBuilder(config2[0].columns, config2[0].name);
@@ -16815,6 +16830,23 @@ var workspaceFileRequest = sqliteTable("workspace_file_request", {
16815
16830
  }, (t) => [
16816
16831
  index("idx_wfr_workspace_status").on(t.workspaceId, t.status)
16817
16832
  ]);
16833
+ var agentSkill = sqliteTable("agent_skill", {
16834
+ id: text("id").primaryKey().$defaultFn(() => "as_" + nanoid3()),
16835
+ workspaceId: text("workspace_id").notNull().references(() => workspace.id, { onDelete: "cascade" }),
16836
+ agentId: text("agent_id"),
16837
+ runtime: text("runtime").notNull(),
16838
+ name: text("name").notNull(),
16839
+ description: text("description").notNull().default(""),
16840
+ syncedAt: text("synced_at").notNull().$defaultFn(() => new Date().toISOString())
16841
+ }, (t) => [
16842
+ unique("agent_skill_ws_runtime_name_agent").on(t.workspaceId, t.runtime, t.name, t.agentId),
16843
+ index("idx_as_workspace_runtime").on(t.workspaceId, t.runtime),
16844
+ index("idx_as_agent_runtime").on(t.agentId, t.runtime),
16845
+ foreignKey({
16846
+ columns: [t.agentId, t.workspaceId],
16847
+ foreignColumns: [agent.id, agent.workspaceId]
16848
+ }).onDelete("cascade")
16849
+ ]);
16818
16850
  // ../shared/src/db/queries/task.ts
16819
16851
  var DEFAULT_STALE_SECONDS = Number(process.env.ALOOK_STALE_DISPATCH_TIMEOUT_S) || 20;
16820
16852
  var DEFAULT_STALE_RUNNING_SECONDS = Number(process.env.ALOOK_STALE_RUNNING_TIMEOUT_S) || 3600;
@@ -17319,7 +17351,7 @@ function statusCommand() {
17319
17351
  // commands/daemon.ts
17320
17352
  import { Command as Command3 } from "commander";
17321
17353
  import { spawn as spawn6 } from "child_process";
17322
- import { openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync8 } from "fs";
17354
+ import { openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync9 } from "fs";
17323
17355
  import { dirname as dirname4 } from "path";
17324
17356
 
17325
17357
  // daemon/client.ts
@@ -17439,6 +17471,9 @@ class DaemonClient {
17439
17471
  reportFileData(token, body) {
17440
17472
  return this.request("POST", "/api/daemon/workspace/report", token, body);
17441
17473
  }
17474
+ syncSkills(token, body) {
17475
+ return this.request("POST", "/api/daemon/skills/sync", token, body);
17476
+ }
17442
17477
  }
17443
17478
 
17444
17479
  // daemon/health.ts
@@ -18257,6 +18292,9 @@ class OpenCodeBackend {
18257
18292
  if (options.resumeSessionId) {
18258
18293
  args.push("--session", options.resumeSessionId);
18259
18294
  }
18295
+ if (options.cwd) {
18296
+ args.push("--dir", options.cwd);
18297
+ }
18260
18298
  args.push(prompt);
18261
18299
  const proc = spawn3(this.cliPath, args, {
18262
18300
  cwd: options.cwd,
@@ -19999,6 +20037,349 @@ function validatePath(agentWorkdir, requestedPath) {
19999
20037
  return resolved;
20000
20038
  }
20001
20039
 
20040
+ // daemon/skill-scanner.ts
20041
+ import { existsSync as existsSync2, mkdirSync as mkdirSync7, readFileSync as readFileSync8, writeFileSync as writeFileSync7, readdirSync as readdirSync2, statSync as statSync3, realpathSync } from "fs";
20042
+ import { join as join10, basename } from "path";
20043
+ import { homedir as homedir2 } from "os";
20044
+ import { createHash as createHash2 } from "crypto";
20045
+ var log8 = createLogger2({ module: "skill-scanner" });
20046
+ function getCacheDir() {
20047
+ return join10(configDir(), "skills");
20048
+ }
20049
+ function parseFrontmatter(content) {
20050
+ const match = content.match(/^---\s*\n([\s\S]*?)\n---/);
20051
+ if (!match)
20052
+ return null;
20053
+ const block = match[1];
20054
+ const nameMatch = block.match(/^name:\s*(.+)$/m);
20055
+ const descMatch = block.match(/^description:\s*(.+)$/m);
20056
+ if (!nameMatch)
20057
+ return null;
20058
+ return {
20059
+ name: nameMatch[1].trim().replace(/^["']|["']$/g, ""),
20060
+ description: descMatch ? descMatch[1].trim().replace(/^["']|["']$/g, "") : ""
20061
+ };
20062
+ }
20063
+ function safeReadDir(dir) {
20064
+ try {
20065
+ if (!existsSync2(dir))
20066
+ return [];
20067
+ return readdirSync2(dir);
20068
+ } catch {
20069
+ return [];
20070
+ }
20071
+ }
20072
+ function findSkillFiles(baseDir, pattern) {
20073
+ const results = [];
20074
+ if (!existsSync2(baseDir))
20075
+ return results;
20076
+ if (pattern === "*/SKILL.md") {
20077
+ for (const entry of safeReadDir(baseDir)) {
20078
+ const skillPath = join10(baseDir, entry, "SKILL.md");
20079
+ try {
20080
+ if (existsSync2(skillPath) && statSync3(skillPath).isFile()) {
20081
+ results.push(skillPath);
20082
+ }
20083
+ } catch {}
20084
+ }
20085
+ } else if (pattern === "**/skills/*/SKILL.md") {
20086
+ walkForSkills(baseDir, results);
20087
+ } else if (pattern === "*.md") {
20088
+ for (const entry of safeReadDir(baseDir)) {
20089
+ if (entry.endsWith(".md")) {
20090
+ const filePath = join10(baseDir, entry);
20091
+ try {
20092
+ if (statSync3(filePath).isFile()) {
20093
+ results.push(filePath);
20094
+ }
20095
+ } catch {}
20096
+ }
20097
+ }
20098
+ }
20099
+ return results;
20100
+ }
20101
+ function walkForSkills(dir, results, depth = 0) {
20102
+ if (depth > 5)
20103
+ return;
20104
+ try {
20105
+ for (const entry of readdirSync2(dir)) {
20106
+ const full = join10(dir, entry);
20107
+ try {
20108
+ const st = statSync3(full);
20109
+ if (st.isDirectory()) {
20110
+ if (entry === "skills") {
20111
+ for (const skillDir of safeReadDir(full)) {
20112
+ const skillPath = join10(full, skillDir, "SKILL.md");
20113
+ try {
20114
+ if (existsSync2(skillPath) && statSync3(skillPath).isFile()) {
20115
+ results.push(skillPath);
20116
+ }
20117
+ } catch {}
20118
+ }
20119
+ } else {
20120
+ walkForSkills(full, results, depth + 1);
20121
+ }
20122
+ }
20123
+ } catch {}
20124
+ }
20125
+ } catch {}
20126
+ }
20127
+ function scanFrontmatterSkills(paths) {
20128
+ const skills = new Map;
20129
+ for (const filePath of paths) {
20130
+ try {
20131
+ const content = readFileSync8(filePath, "utf-8");
20132
+ const meta3 = parseFrontmatter(content);
20133
+ if (meta3 && !skills.has(meta3.name)) {
20134
+ skills.set(meta3.name, meta3);
20135
+ }
20136
+ } catch {}
20137
+ }
20138
+ return Array.from(skills.values());
20139
+ }
20140
+ function scanClaudeGlobalSkills() {
20141
+ const home = homedir2();
20142
+ const allSkills = [];
20143
+ const directPaths = findSkillFiles(join10(home, ".claude", "skills"), "*/SKILL.md");
20144
+ allSkills.push(...scanFrontmatterSkills(directPaths));
20145
+ const pluginCacheDir = join10(home, ".claude", "plugins", "cache");
20146
+ const pluginPaths = findSkillFiles(pluginCacheDir, "**/skills/*/SKILL.md");
20147
+ const names = new Set(allSkills.map((s) => s.name));
20148
+ for (const filePath of pluginPaths) {
20149
+ try {
20150
+ const content = readFileSync8(filePath, "utf-8");
20151
+ const meta3 = parseFrontmatter(content);
20152
+ if (meta3 && !names.has(meta3.name)) {
20153
+ names.add(meta3.name);
20154
+ allSkills.push(meta3);
20155
+ }
20156
+ } catch {}
20157
+ }
20158
+ return allSkills;
20159
+ }
20160
+ function scanClaudeAgentSkills(workdir) {
20161
+ const paths = findSkillFiles(join10(workdir, ".claude", "skills"), "*/SKILL.md");
20162
+ return scanFrontmatterSkills(paths);
20163
+ }
20164
+ function scanCodexGlobalSkills() {
20165
+ const home = homedir2();
20166
+ const allSkills = [];
20167
+ const paths = [
20168
+ ...findSkillFiles(join10(home, ".agents", "skills"), "*/SKILL.md"),
20169
+ ...findSkillFiles(join10(home, ".codex", "skills", ".system"), "*/SKILL.md")
20170
+ ];
20171
+ allSkills.push(...scanFrontmatterSkills(paths));
20172
+ const codexPluginDir = join10(home, ".codex", "plugins", "cache");
20173
+ const pluginPaths = findSkillFiles(codexPluginDir, "**/skills/*/SKILL.md");
20174
+ const names = new Set(allSkills.map((s) => s.name));
20175
+ for (const filePath of pluginPaths) {
20176
+ try {
20177
+ const content = readFileSync8(filePath, "utf-8");
20178
+ const meta3 = parseFrontmatter(content);
20179
+ if (meta3 && !names.has(meta3.name)) {
20180
+ names.add(meta3.name);
20181
+ allSkills.push(meta3);
20182
+ }
20183
+ } catch {}
20184
+ }
20185
+ return allSkills;
20186
+ }
20187
+ function scanCodexAgentSkills(workdir) {
20188
+ const paths = findSkillFiles(join10(workdir, ".agents", "skills"), "*/SKILL.md");
20189
+ return scanFrontmatterSkills(paths);
20190
+ }
20191
+ function scanOpenCodeMdFiles(dir) {
20192
+ const skills = [];
20193
+ const files = findSkillFiles(dir, "*.md");
20194
+ for (const filePath of files) {
20195
+ try {
20196
+ const content = readFileSync8(filePath, "utf-8");
20197
+ const name = basename(filePath, ".md");
20198
+ const firstLine = content.split(`
20199
+ `).find((l) => l.trim().length > 0) ?? "";
20200
+ skills.push({ name, description: firstLine.replace(/^#\s*/, "").trim() });
20201
+ } catch {}
20202
+ }
20203
+ return skills;
20204
+ }
20205
+ function scanOpenCodeGlobalSkills() {
20206
+ const home = homedir2();
20207
+ const skills = [];
20208
+ const names = new Set;
20209
+ for (const s of scanOpenCodeMdFiles(join10(home, ".config", "opencode", "commands"))) {
20210
+ if (!names.has(s.name)) {
20211
+ names.add(s.name);
20212
+ skills.push(s);
20213
+ }
20214
+ }
20215
+ for (const s of scanOpenCodeMdFiles(join10(home, ".config", "opencode", "skills"))) {
20216
+ if (!names.has(s.name)) {
20217
+ names.add(s.name);
20218
+ skills.push(s);
20219
+ }
20220
+ }
20221
+ return skills;
20222
+ }
20223
+ function scanOpenCodeAgentSkills(workdir) {
20224
+ const skills = [];
20225
+ const names = new Set;
20226
+ for (const s of scanOpenCodeMdFiles(join10(workdir, ".opencode", "commands"))) {
20227
+ if (!names.has(s.name)) {
20228
+ names.add(s.name);
20229
+ skills.push(s);
20230
+ }
20231
+ }
20232
+ for (const s of scanOpenCodeMdFiles(join10(workdir, ".opencode", "skills"))) {
20233
+ if (!names.has(s.name)) {
20234
+ names.add(s.name);
20235
+ skills.push(s);
20236
+ }
20237
+ }
20238
+ return skills;
20239
+ }
20240
+ function computeHash(skills) {
20241
+ return createHash2("md5").update(JSON.stringify(skills)).digest("hex");
20242
+ }
20243
+ function globalCachePath(runtime) {
20244
+ return join10(getCacheDir(), "global", `${runtime}.json`);
20245
+ }
20246
+ function agentCachePath(agentId, runtime) {
20247
+ return join10(getCacheDir(), "agents", agentId, `${runtime}.json`);
20248
+ }
20249
+ function readCacheHash(filePath) {
20250
+ try {
20251
+ if (!existsSync2(filePath))
20252
+ return null;
20253
+ const data = JSON.parse(readFileSync8(filePath, "utf-8"));
20254
+ return data.hash ?? null;
20255
+ } catch {
20256
+ return null;
20257
+ }
20258
+ }
20259
+ function writeCacheFile(filePath, hash2, skills) {
20260
+ const dir = join10(filePath, "..");
20261
+ mkdirSync7(dir, { recursive: true });
20262
+ const data = { hash: hash2, skills };
20263
+ writeFileSync7(filePath, JSON.stringify(data, null, 2), "utf-8");
20264
+ }
20265
+ var scanTimer = null;
20266
+ var scannerConfig = null;
20267
+ var clientRef = null;
20268
+ function discoverTargets() {
20269
+ if (!scannerConfig)
20270
+ return [];
20271
+ const rootExists = existsSync2(scannerConfig.workspacesRoot);
20272
+ const rootReal = rootExists ? realpathSync(scannerConfig.workspacesRoot) : null;
20273
+ const targets = [];
20274
+ for (const ws of scannerConfig.workspaces) {
20275
+ const agentIds = new Set(ws.agentIds);
20276
+ if (rootReal) {
20277
+ const wsDir = join10(scannerConfig.workspacesRoot, ws.workspaceId);
20278
+ try {
20279
+ if (existsSync2(wsDir)) {
20280
+ for (const dir of readdirSync2(wsDir)) {
20281
+ if (existsSync2(join10(wsDir, dir, "workdir")))
20282
+ agentIds.add(dir);
20283
+ }
20284
+ }
20285
+ } catch {}
20286
+ }
20287
+ for (const agentId of agentIds) {
20288
+ let validWorkdir = null;
20289
+ if (rootReal) {
20290
+ const workdir = join10(scannerConfig.workspacesRoot, ws.workspaceId, agentId, "workdir");
20291
+ if (existsSync2(workdir)) {
20292
+ try {
20293
+ if (realpathSync(workdir).startsWith(rootReal))
20294
+ validWorkdir = workdir;
20295
+ } catch {}
20296
+ }
20297
+ }
20298
+ for (const runtime of scannerConfig.runtimes) {
20299
+ targets.push({ agentId, workdir: validWorkdir, runtime, token: ws.token });
20300
+ }
20301
+ }
20302
+ }
20303
+ return targets;
20304
+ }
20305
+ function getGlobalScanner(runtime) {
20306
+ if (runtime === "claude")
20307
+ return scanClaudeGlobalSkills;
20308
+ if (runtime === "codex")
20309
+ return scanCodexGlobalSkills;
20310
+ return scanOpenCodeGlobalSkills;
20311
+ }
20312
+ function getAgentScanner(runtime) {
20313
+ if (runtime === "claude")
20314
+ return scanClaudeAgentSkills;
20315
+ if (runtime === "codex")
20316
+ return scanCodexAgentSkills;
20317
+ return scanOpenCodeAgentSkills;
20318
+ }
20319
+ function runScan() {
20320
+ if (!scannerConfig || !clientRef)
20321
+ return;
20322
+ if (scannerConfig.workspaces.length === 0)
20323
+ return;
20324
+ for (const runtime of scannerConfig.runtimes) {
20325
+ try {
20326
+ const skills = getGlobalScanner(runtime)();
20327
+ const hash2 = computeHash(skills);
20328
+ const prevHash = readCacheHash(globalCachePath(runtime));
20329
+ if (prevHash !== hash2) {
20330
+ const skillItems = skills.map((s) => ({ name: s.name, description: s.description }));
20331
+ log8.info(`Syncing global ${runtime} — ${skills.length} skills`);
20332
+ const syncPromises = scannerConfig.workspaces.map((ws) => clientRef.syncSkills(ws.token, {
20333
+ scope: "global",
20334
+ runtime,
20335
+ skills: skillItems
20336
+ }));
20337
+ Promise.all(syncPromises).then(() => {
20338
+ writeCacheFile(globalCachePath(runtime), hash2, skills);
20339
+ }).catch((e) => log8.debug("Global skill sync failed", e));
20340
+ }
20341
+ } catch (e) {
20342
+ log8.debug(`Global scan error for ${runtime}`, e);
20343
+ }
20344
+ }
20345
+ const targets = discoverTargets();
20346
+ for (const target of targets) {
20347
+ if (!target.workdir)
20348
+ continue;
20349
+ try {
20350
+ const skills = getAgentScanner(target.runtime)(target.workdir);
20351
+ const hash2 = computeHash(skills);
20352
+ const prevHash = readCacheHash(agentCachePath(target.agentId, target.runtime));
20353
+ if (prevHash !== hash2) {
20354
+ const skillItems = skills.map((s) => ({ name: s.name, description: s.description }));
20355
+ log8.info(`Syncing ${target.agentId}:${target.runtime} — ${skills.length} agent skills`);
20356
+ clientRef.syncSkills(target.token, {
20357
+ scope: "agent",
20358
+ agent_id: target.agentId,
20359
+ runtime: target.runtime,
20360
+ skills: skillItems
20361
+ }).then(() => {
20362
+ writeCacheFile(agentCachePath(target.agentId, target.runtime), hash2, skills);
20363
+ }).catch((e) => log8.debug("Agent skill sync failed", e));
20364
+ }
20365
+ } catch (e) {
20366
+ log8.debug(`Agent scan error for ${target.agentId}:${target.runtime}`, e);
20367
+ }
20368
+ }
20369
+ }
20370
+ function startSkillScanner(client, config2, interval = 60000) {
20371
+ clientRef = client;
20372
+ scannerConfig = config2;
20373
+ runScan();
20374
+ scanTimer = setInterval(runScan, interval);
20375
+ }
20376
+ function stopSkillScanner() {
20377
+ if (scanTimer) {
20378
+ clearInterval(scanTimer);
20379
+ scanTimer = null;
20380
+ }
20381
+ }
20382
+
20002
20383
  // lib/shell-env.ts
20003
20384
  import { execSync as execSync3 } from "child_process";
20004
20385
  var PASSTHROUGH_VARS = ["ALOOK_PROJECT_ROOT", "ALOOK_SERVER_URL", "ALOOK_CMD_PREFIX", "ALOOK_HEALTH_PORT"];
@@ -20033,15 +20414,15 @@ function resolveLoginShellEnv() {
20033
20414
  }
20034
20415
 
20035
20416
  // daemon/daemon.ts
20036
- import { existsSync as existsSync2, mkdirSync as mkdirSync7, openSync, closeSync, readdirSync as readdirSync2, statSync as statSync3, unlinkSync as unlinkSync5 } from "fs";
20417
+ import { existsSync as existsSync3, mkdirSync as mkdirSync8, openSync, closeSync, readdirSync as readdirSync3, statSync as statSync4, unlinkSync as unlinkSync5 } from "fs";
20037
20418
  import { readdir as readdir2, readFile as readFile2, unlink, stat as fsStat } from "fs/promises";
20038
20419
  import { execSync as execSync4, spawn as spawn5 } from "child_process";
20039
20420
  import { fileURLToPath as fileURLToPath2 } from "url";
20040
- import { dirname as dirname3, join as join10 } from "path";
20041
- var log8 = createLogger2({ module: "daemon" });
20421
+ import { dirname as dirname3, join as join11 } from "path";
20422
+ var log9 = createLogger2({ module: "daemon" });
20042
20423
  var _dir = dirname3(fileURLToPath2(import.meta.url));
20043
- var sessionRunnerPath = existsSync2(join10(_dir, "session-runner.js")) ? join10(_dir, "session-runner.js") : join10(_dir, "session-runner.ts");
20044
- var meetingRunnerPath = existsSync2(join10(_dir, "meeting-runner.js")) ? join10(_dir, "meeting-runner.js") : join10(_dir, "meeting-runner.ts");
20424
+ var sessionRunnerPath = existsSync3(join11(_dir, "session-runner.js")) ? join11(_dir, "session-runner.js") : join11(_dir, "session-runner.ts");
20425
+ var meetingRunnerPath = existsSync3(join11(_dir, "meeting-runner.js")) ? join11(_dir, "meeting-runner.js") : join11(_dir, "meeting-runner.ts");
20045
20426
  function isCommandAvailable2(cmd) {
20046
20427
  try {
20047
20428
  const check2 = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
@@ -20056,16 +20437,16 @@ function pruneSessionRunnerLogs() {
20056
20437
  const logDir = sessionRunnerLogDir();
20057
20438
  let entries;
20058
20439
  try {
20059
- entries = readdirSync2(logDir).filter((f) => f.endsWith(".log"));
20440
+ entries = readdirSync3(logDir).filter((f) => f.endsWith(".log"));
20060
20441
  } catch {
20061
20442
  return;
20062
20443
  }
20063
20444
  if (entries.length <= MAX_SESSION_RUNNER_LOGS)
20064
20445
  return;
20065
20446
  const withMtime = entries.map((name) => {
20066
- const full = join10(logDir, name);
20447
+ const full = join11(logDir, name);
20067
20448
  try {
20068
- return { name, mtime: statSync3(full).mtimeMs };
20449
+ return { name, mtime: statSync4(full).mtimeMs };
20069
20450
  } catch {
20070
20451
  return { name, mtime: 0 };
20071
20452
  }
@@ -20073,7 +20454,7 @@ function pruneSessionRunnerLogs() {
20073
20454
  withMtime.sort((a, b) => b.mtime - a.mtime);
20074
20455
  for (const entry of withMtime.slice(MAX_SESSION_RUNNER_LOGS)) {
20075
20456
  try {
20076
- unlinkSync5(join10(logDir, entry.name));
20457
+ unlinkSync5(join11(logDir, entry.name));
20077
20458
  } catch {}
20078
20459
  }
20079
20460
  }
@@ -20114,7 +20495,7 @@ function isValidMarker(data) {
20114
20495
  var MARKER_STALE_MS = 24 * 60 * 60 * 1000;
20115
20496
  var TMP_STALE_MS = 60 * 60 * 1000;
20116
20497
  async function reconcilePendingCompletions(workspacesRoot) {
20117
- const dir = join10(workspacesRoot, ".pending_completions");
20498
+ const dir = join11(workspacesRoot, ".pending_completions");
20118
20499
  let entries;
20119
20500
  try {
20120
20501
  entries = await readdir2(dir);
@@ -20125,15 +20506,15 @@ async function reconcilePendingCompletions(workspacesRoot) {
20125
20506
  if (!name.endsWith(".tmp"))
20126
20507
  continue;
20127
20508
  try {
20128
- const s = await fsStat(join10(dir, name));
20509
+ const s = await fsStat(join11(dir, name));
20129
20510
  if (Date.now() - s.mtimeMs > TMP_STALE_MS) {
20130
- await unlink(join10(dir, name));
20511
+ await unlink(join11(dir, name));
20131
20512
  }
20132
20513
  } catch {}
20133
20514
  }
20134
20515
  const jsonFiles = entries.filter((f) => f.endsWith(".json"));
20135
20516
  for (const name of jsonFiles) {
20136
- const filePath = join10(dir, name);
20517
+ const filePath = join11(dir, name);
20137
20518
  try {
20138
20519
  let raw;
20139
20520
  try {
@@ -20145,14 +20526,14 @@ async function reconcilePendingCompletions(workspacesRoot) {
20145
20526
  try {
20146
20527
  parsed = JSON.parse(raw);
20147
20528
  } catch {
20148
- log8.warn(`reconcile: malformed marker ${name}, deleting`);
20529
+ log9.warn(`reconcile: malformed marker ${name}, deleting`);
20149
20530
  try {
20150
20531
  await unlink(filePath);
20151
20532
  } catch {}
20152
20533
  continue;
20153
20534
  }
20154
20535
  if (!isValidMarker(parsed)) {
20155
- log8.warn(`reconcile: invalid marker structure ${name}, deleting`);
20536
+ log9.warn(`reconcile: invalid marker structure ${name}, deleting`);
20156
20537
  try {
20157
20538
  await unlink(filePath);
20158
20539
  } catch {}
@@ -20161,7 +20542,7 @@ async function reconcilePendingCompletions(workspacesRoot) {
20161
20542
  const marker = parsed;
20162
20543
  const age = Date.now() - new Date(marker.createdAt).getTime();
20163
20544
  if (age > MARKER_STALE_MS) {
20164
- log8.warn(`reconcile: stale marker ${name} (${Math.round(age / 3600000)}h old), deleting`);
20545
+ log9.warn(`reconcile: stale marker ${name} (${Math.round(age / 3600000)}h old), deleting`);
20165
20546
  try {
20166
20547
  await unlink(filePath);
20167
20548
  } catch {}
@@ -20177,7 +20558,7 @@ async function reconcilePendingCompletions(workspacesRoot) {
20177
20558
  try {
20178
20559
  await unlink(filePath);
20179
20560
  } catch (delErr) {
20180
- log8.warn(`reconcile: delivered marker ${name} but failed to delete: ${delErr}`);
20561
+ log9.warn(`reconcile: delivered marker ${name} but failed to delete: ${delErr}`);
20181
20562
  }
20182
20563
  } catch (deliverErr) {
20183
20564
  if (isClientError2(deliverErr)) {
@@ -20185,11 +20566,11 @@ async function reconcilePendingCompletions(workspacesRoot) {
20185
20566
  await unlink(filePath);
20186
20567
  } catch {}
20187
20568
  } else {
20188
- log8.debug(`reconcile: delivery failed for ${name}, will retry next cycle`);
20569
+ log9.debug(`reconcile: delivery failed for ${name}, will retry next cycle`);
20189
20570
  }
20190
20571
  }
20191
20572
  } catch (e) {
20192
- log8.debug(`reconcile: error processing ${name}`, e);
20573
+ log9.debug(`reconcile: error processing ${name}`, e);
20193
20574
  }
20194
20575
  }
20195
20576
  }
@@ -20200,7 +20581,7 @@ async function startDaemon(profile, serverUrl) {
20200
20581
  }
20201
20582
  process.once("exit", () => releaseDaemonPid(profile));
20202
20583
  const bailOnUnexpected = (label, err) => {
20203
- log8.error(`${label} — shutting down`, err);
20584
+ log9.error(`${label} — shutting down`, err);
20204
20585
  releaseDaemonPid(profile);
20205
20586
  process.exit(1);
20206
20587
  };
@@ -20213,21 +20594,21 @@ async function startDaemon(profile, serverUrl) {
20213
20594
  if (marker) {
20214
20595
  clearUpdateMarker(profile);
20215
20596
  if (marker === config2.cliVersion) {
20216
- log8.info(`Cleared update marker — now running v${config2.cliVersion}`);
20597
+ log9.info(`Cleared update marker — now running v${config2.cliVersion}`);
20217
20598
  } else {
20218
- log8.info(`Cleared stale update marker (was v${marker}, running v${config2.cliVersion}) — update will be retried`);
20599
+ log9.info(`Cleared stale update marker (was v${marker}, running v${config2.cliVersion}) — update will be retried`);
20219
20600
  }
20220
20601
  }
20221
20602
  const cliConfig = loadCLIConfigForProfile(profile);
20222
20603
  const workspaces = cliConfig.watched_workspaces || [];
20223
20604
  if (workspaces.length === 0) {
20224
- log8.error("No watched workspaces configured.");
20605
+ log9.error("No watched workspaces configured.");
20225
20606
  process.exit(1);
20226
20607
  return;
20227
20608
  }
20228
20609
  const hasPerWorkspaceTokens = workspaces.every((ws) => !!ws.token);
20229
20610
  if (!hasPerWorkspaceTokens) {
20230
- log8.error(`Config uses old format. Run '${cmdPrefix()} register --token <token>' for each workspace to upgrade.`);
20611
+ log9.error(`Config uses old format. Run '${cmdPrefix()} register --token <token>' for each workspace to upgrade.`);
20231
20612
  process.exit(1);
20232
20613
  return;
20233
20614
  }
@@ -20247,11 +20628,11 @@ async function startDaemon(profile, serverUrl) {
20247
20628
  }
20248
20629
  }
20249
20630
  if (providers.length === 0) {
20250
- log8.error("No agent CLI tools found on PATH.");
20631
+ log9.error("No agent CLI tools found on PATH.");
20251
20632
  process.exit(1);
20252
20633
  return;
20253
20634
  }
20254
- log8.info(`Detected providers: ${providers.map((p) => `${p.type}@${p.version}`).join(", ")}`);
20635
+ log9.info(`Detected providers: ${providers.map((p) => `${p.type}@${p.version}`).join(", ")}`);
20255
20636
  const workspaceStates = [];
20256
20637
  const runtimeIndex = new Map;
20257
20638
  for (const ws of workspaces) {
@@ -20259,7 +20640,7 @@ async function startDaemon(profile, serverUrl) {
20259
20640
  type: p.type,
20260
20641
  version: p.version
20261
20642
  }));
20262
- log8.info(`Registering workspace ${ws.id} (${ws.name ?? "unnamed"}) with ${runtimes.length} runtime(s)...`);
20643
+ log9.info(`Registering workspace ${ws.id} (${ws.name ?? "unnamed"}) with ${runtimes.length} runtime(s)...`);
20263
20644
  let resp;
20264
20645
  try {
20265
20646
  resp = await client.register(ws.token, {
@@ -20272,13 +20653,13 @@ async function startDaemon(profile, serverUrl) {
20272
20653
  });
20273
20654
  } catch (e) {
20274
20655
  if (e instanceof Error && e.message.startsWith("HTTP 401")) {
20275
- log8.warn(`Workspace ${ws.id} token invalid — skipping (run '${cmdPrefix()} register --token <token>' to fix)`);
20656
+ log9.warn(`Workspace ${ws.id} token invalid — skipping (run '${cmdPrefix()} register --token <token>' to fix)`);
20276
20657
  } else {
20277
- log8.error(`Failed to register workspace ${ws.id}, skipping`, e);
20658
+ log9.error(`Failed to register workspace ${ws.id}, skipping`, e);
20278
20659
  }
20279
20660
  continue;
20280
20661
  }
20281
- log8.info(`Workspace ${ws.id} registered — ${resp.runtimes.length} runtime(s)`);
20662
+ log9.info(`Workspace ${ws.id} registered — ${resp.runtimes.length} runtime(s)`);
20282
20663
  const runtimeIds = resp.runtimes.map((r) => r.id);
20283
20664
  workspaceStates.push({ workspaceId: ws.id, token: ws.token, runtimeIds });
20284
20665
  for (let i = 0;i < runtimeIds.length; i++) {
@@ -20290,13 +20671,13 @@ async function startDaemon(profile, serverUrl) {
20290
20671
  }
20291
20672
  }
20292
20673
  if (workspaceStates.length === 0) {
20293
- log8.error("No workspaces registered successfully.");
20674
+ log9.error("No workspaces registered successfully.");
20294
20675
  process.exit(1);
20295
20676
  return;
20296
20677
  }
20297
20678
  const allRuntimeIds = workspaceStates.flatMap((ws) => ws.runtimeIds);
20298
20679
  health.setRuntimeCount(allRuntimeIds.length);
20299
- log8.info(`Daemon started — ${allRuntimeIds.length} runtime(s) across ${workspaceStates.length} workspace(s)`);
20680
+ log9.info(`Daemon started — ${allRuntimeIds.length} runtime(s) across ${workspaceStates.length} workspace(s)`);
20300
20681
  const activeTasks = new Set;
20301
20682
  const knownAgentIds = new Set(workspaces.flatMap((ws) => ws.agent_ids ?? []));
20302
20683
  function syncAgentId(agentId, workspaceId) {
@@ -20331,7 +20712,7 @@ async function startDaemon(profile, serverUrl) {
20331
20712
  cfg.watched_workspaces = (cfg.watched_workspaces || []).filter((w) => w.id !== workspaceId);
20332
20713
  saveCLIConfigForProfile(profile, cfg);
20333
20714
  } catch {}
20334
- log8.info(`Workspace ${workspaceId} deleted server-side — removed from config`);
20715
+ log9.info(`Workspace ${workspaceId} deleted server-side — removed from config`);
20335
20716
  }
20336
20717
  const pollCycle = async () => {
20337
20718
  let remaining = config2.maxConcurrentTasks - activeTasks.size;
@@ -20357,7 +20738,7 @@ async function startDaemon(profile, serverUrl) {
20357
20738
  handleCliUpdate(pending_update.version, () => requestRestart(), profile);
20358
20739
  }
20359
20740
  if (pending_rescan) {
20360
- log8.info("Rescan requested — restarting daemon to re-detect runtimes");
20741
+ log9.info("Rescan requested — restarting daemon to re-detect runtimes");
20361
20742
  for (const id of evictedIds) {
20362
20743
  evictWorkspace(id);
20363
20744
  }
@@ -20370,19 +20751,19 @@ async function startDaemon(profile, serverUrl) {
20370
20751
  activeTasks.add(task.id);
20371
20752
  remaining--;
20372
20753
  handleTask(client, config2, runtimeIndex, task, ws.token, activeTasks).catch((e) => {
20373
- log8.error("Task error", e);
20754
+ log9.error("Task error", e);
20374
20755
  activeTasks.delete(task.id);
20375
20756
  });
20376
20757
  }
20377
20758
  if (file_requests) {
20378
20759
  for (const req of file_requests) {
20379
- handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) => log8.debug("File request error", e));
20760
+ handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) => log9.debug("File request error", e));
20380
20761
  }
20381
20762
  }
20382
20763
  if (meetings) {
20383
20764
  for (const m of meetings) {
20384
- const agentBaseDir = join10(config2.workspacesRoot, m.workspace_id, m.agent_id, "workdir");
20385
- const timelineDir = join10(agentBaseDir, ".context_timeline");
20765
+ const agentBaseDir = join11(config2.workspacesRoot, m.workspace_id, m.agent_id, "workdir");
20766
+ const timelineDir = join11(agentBaseDir, ".context_timeline");
20386
20767
  spawnMeetingRunner({
20387
20768
  meetingId: m.id,
20388
20769
  meetingUrl: m.meeting_url,
@@ -20399,9 +20780,9 @@ async function startDaemon(profile, serverUrl) {
20399
20780
  }
20400
20781
  } catch (e) {
20401
20782
  if (e instanceof Error && e.message.startsWith("HTTP 401")) {
20402
- log8.warn(`Workspace ${ws.workspaceId} poll returned 401 — will retry next cycle`);
20783
+ log9.warn(`Workspace ${ws.workspaceId} poll returned 401 — will retry next cycle`);
20403
20784
  } else {
20404
- log8.debug("Poll error", e);
20785
+ log9.debug("Poll error", e);
20405
20786
  }
20406
20787
  }
20407
20788
  }
@@ -20409,7 +20790,7 @@ async function startDaemon(profile, serverUrl) {
20409
20790
  evictWorkspace(id);
20410
20791
  }
20411
20792
  if (workspaceStates.length === 0) {
20412
- log8.info("All workspaces evicted — shutting down");
20793
+ log9.info("All workspaces evicted — shutting down");
20413
20794
  shutdown();
20414
20795
  }
20415
20796
  };
@@ -20417,7 +20798,7 @@ async function startDaemon(profile, serverUrl) {
20417
20798
  const heartbeatPing = () => {
20418
20799
  for (const ws of workspaceStates) {
20419
20800
  client.heartbeat(ws.token, config2.daemonId).catch((e) => {
20420
- log8.debug("heartbeat failed", { workspaceId: ws.workspaceId, err: String(e) });
20801
+ log9.debug("heartbeat failed", { workspaceId: ws.workspaceId, err: String(e) });
20421
20802
  });
20422
20803
  }
20423
20804
  };
@@ -20442,7 +20823,7 @@ async function startDaemon(profile, serverUrl) {
20442
20823
  syncAgentId(task.agentId, ws.workspaceId);
20443
20824
  activeTasks.add(task.id);
20444
20825
  handleTask(client, config2, runtimeIndex, task, ws.token, activeTasks).catch((e) => {
20445
- log8.error("WS task error", e);
20826
+ log9.error("WS task error", e);
20446
20827
  activeTasks.delete(task.id);
20447
20828
  });
20448
20829
  }
@@ -20451,7 +20832,7 @@ async function startDaemon(profile, serverUrl) {
20451
20832
  const ws = workspaceStates.find((w) => w.workspaceId === msg.workspaceId);
20452
20833
  if (ws) {
20453
20834
  for (const req of msg.requests) {
20454
- handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) => log8.debug("WS file request error", e));
20835
+ handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) => log9.debug("WS file request error", e));
20455
20836
  }
20456
20837
  }
20457
20838
  break;
@@ -20461,8 +20842,8 @@ async function startDaemon(profile, serverUrl) {
20461
20842
  const ws = workspaceStates.find((w) => w.workspaceId === m.workspace_id);
20462
20843
  if (!ws)
20463
20844
  continue;
20464
- const agentBaseDir = join10(config2.workspacesRoot, m.workspace_id, m.agent_id, "workdir");
20465
- const timelineDir = join10(agentBaseDir, ".context_timeline");
20845
+ const agentBaseDir = join11(config2.workspacesRoot, m.workspace_id, m.agent_id, "workdir");
20846
+ const timelineDir = join11(agentBaseDir, ".context_timeline");
20466
20847
  spawnMeetingRunner({
20467
20848
  meetingId: m.id,
20468
20849
  meetingUrl: m.meeting_url,
@@ -20486,7 +20867,7 @@ async function startDaemon(profile, serverUrl) {
20486
20867
  }
20487
20868
  break;
20488
20869
  case "daemon.rescan":
20489
- log8.info("WS rescan requested — restarting daemon");
20870
+ log9.info("WS rescan requested — restarting daemon");
20490
20871
  requestRestart();
20491
20872
  break;
20492
20873
  case "daemon.kill": {
@@ -20514,7 +20895,7 @@ async function startDaemon(profile, serverUrl) {
20514
20895
  });
20515
20896
  activeTasks.add(killTask.id);
20516
20897
  handleTask(client, config2, runtimeIndex, killTask, ws.token, activeTasks).catch((e) => {
20517
- log8.error("WS kill task error", e);
20898
+ log9.error("WS kill task error", e);
20518
20899
  activeTasks.delete(killTask.id);
20519
20900
  });
20520
20901
  }
@@ -20528,11 +20909,11 @@ async function startDaemon(profile, serverUrl) {
20528
20909
  machineToken: firstToken,
20529
20910
  onMessage: handleWsPush,
20530
20911
  onConnected: () => {
20531
- log8.info("WS connected — switching to low-frequency poll");
20912
+ log9.info("WS connected — switching to low-frequency poll");
20532
20913
  updatePollInterval(config2.wsPollInterval);
20533
20914
  },
20534
20915
  onDisconnected: () => {
20535
- log8.info("WS disconnected — reverting to high-frequency poll");
20916
+ log9.info("WS disconnected — reverting to high-frequency poll");
20536
20917
  updatePollInterval(config2.pollInterval);
20537
20918
  }
20538
20919
  }) : null;
@@ -20540,16 +20921,25 @@ async function startDaemon(profile, serverUrl) {
20540
20921
  const sweepTick = async () => {
20541
20922
  for (const ws of workspaceStates) {
20542
20923
  client.sweep(ws.token, config2.daemonId).catch((e) => {
20543
- log8.debug("sweep ping failed", { workspaceId: ws.workspaceId, err: String(e) });
20924
+ log9.debug("sweep ping failed", { workspaceId: ws.workspaceId, err: String(e) });
20544
20925
  });
20545
20926
  }
20546
20927
  try {
20547
20928
  await reconcilePendingCompletions(config2.workspacesRoot);
20548
20929
  } catch (e) {
20549
- log8.debug("reconciliation error", e);
20930
+ log9.debug("reconciliation error", e);
20550
20931
  }
20551
20932
  };
20552
20933
  const sweepTimer = setInterval(sweepTick, config2.sweepInterval);
20934
+ startSkillScanner(client, {
20935
+ workspacesRoot: config2.workspacesRoot,
20936
+ workspaces: workspaces.map((ws) => ({
20937
+ workspaceId: ws.id,
20938
+ token: ws.token,
20939
+ agentIds: ws.agent_ids ?? []
20940
+ })),
20941
+ runtimes: providers.map((p) => p.type)
20942
+ }, 60000);
20553
20943
  let shuttingDown = false;
20554
20944
  let restartRequested = false;
20555
20945
  const requestRestart = () => {
@@ -20560,10 +20950,11 @@ async function startDaemon(profile, serverUrl) {
20560
20950
  if (shuttingDown)
20561
20951
  return;
20562
20952
  shuttingDown = true;
20563
- log8.info(restartRequested ? "Restarting..." : "Shutting down...");
20953
+ log9.info(restartRequested ? "Restarting..." : "Shutting down...");
20564
20954
  clearInterval(pollTimer);
20565
20955
  clearInterval(heartbeatTimer);
20566
20956
  clearInterval(sweepTimer);
20957
+ stopSkillScanner();
20567
20958
  wsClient?.close();
20568
20959
  const shutdownMs = restartRequested ? 30000 : Number(process.env.ALOOK_SHUTDOWN_TIMEOUT_MS) || 5000;
20569
20960
  const timeout = setTimeout(() => process.exit(1), shutdownMs);
@@ -20584,10 +20975,10 @@ async function startDaemon(profile, serverUrl) {
20584
20975
  const logPath = daemonLogFilePath();
20585
20976
  let logFd;
20586
20977
  try {
20587
- mkdirSync7(dirname3(logPath), { recursive: true, mode: 448 });
20978
+ mkdirSync8(dirname3(logPath), { recursive: true, mode: 448 });
20588
20979
  logFd = openSync(logPath, "a", 384);
20589
20980
  } catch (e) {
20590
- log8.error(`Failed to open daemon log file ${logPath}`, e);
20981
+ log9.error(`Failed to open daemon log file ${logPath}`, e);
20591
20982
  }
20592
20983
  const child = spawn5(process.execPath, args, {
20593
20984
  detached: true,
@@ -20597,7 +20988,7 @@ async function startDaemon(profile, serverUrl) {
20597
20988
  child.unref();
20598
20989
  if (logFd != null)
20599
20990
  closeSync(logFd);
20600
- log8.info(`Spawned new daemon (pid=${child.pid}), logs: ${logPath}`);
20991
+ log9.info(`Spawned new daemon (pid=${child.pid}), logs: ${logPath}`);
20601
20992
  }
20602
20993
  clearTimeout(timeout);
20603
20994
  process.exit(0);
@@ -20608,7 +20999,7 @@ async function startDaemon(profile, serverUrl) {
20608
20999
  process.on("SIGHUP", async () => {
20609
21000
  if (shuttingDown)
20610
21001
  return;
20611
- log8.info("SIGHUP received — reloading config...");
21002
+ log9.info("SIGHUP received — reloading config...");
20612
21003
  try {
20613
21004
  const freshConfig = loadCLIConfigForProfile(profile);
20614
21005
  const freshWorkspaces = freshConfig.watched_workspaces || [];
@@ -20616,7 +21007,7 @@ async function startDaemon(profile, serverUrl) {
20616
21007
  const newWorkspaces = freshWorkspaces.filter((ws) => ws.token && !existingIds.has(ws.id));
20617
21008
  for (const ws of newWorkspaces) {
20618
21009
  const runtimes = providers.map((p) => ({ type: p.type, version: p.version }));
20619
- log8.info(`Registering new workspace ${ws.id} (${ws.name ?? "unnamed"})...`);
21010
+ log9.info(`Registering new workspace ${ws.id} (${ws.name ?? "unnamed"})...`);
20620
21011
  try {
20621
21012
  const resp = await client.register(ws.token, {
20622
21013
  workspace_id: ws.id,
@@ -20635,34 +21026,34 @@ async function startDaemon(profile, serverUrl) {
20635
21026
  provider: providers[i].type
20636
21027
  });
20637
21028
  }
20638
- log8.info(`Workspace ${ws.id} added — ${runtimeIds.length} runtime(s)`);
21029
+ log9.info(`Workspace ${ws.id} added — ${runtimeIds.length} runtime(s)`);
20639
21030
  } catch (e) {
20640
- log8.error(`Failed to register new workspace ${ws.id}`, e);
21031
+ log9.error(`Failed to register new workspace ${ws.id}`, e);
20641
21032
  }
20642
21033
  }
20643
21034
  if (newWorkspaces.length > 0) {
20644
21035
  health.setRuntimeCount(workspaceStates.reduce((sum, w) => sum + w.runtimeIds.length, 0));
20645
- log8.info(`Reload complete — now polling ${workspaceStates.length} workspace(s)`);
21036
+ log9.info(`Reload complete — now polling ${workspaceStates.length} workspace(s)`);
20646
21037
  } else {
20647
- log8.info("Reload complete — no new workspaces found");
21038
+ log9.info("Reload complete — no new workspaces found");
20648
21039
  }
20649
21040
  } catch (e) {
20650
- log8.error("Failed to reload config", e);
21041
+ log9.error("Failed to reload config", e);
20651
21042
  }
20652
21043
  });
20653
21044
  await pollCycle();
20654
21045
  }
20655
21046
  function spawnSessionRunner(input) {
20656
21047
  const logDir = sessionRunnerLogDir();
20657
- mkdirSync7(logDir, { recursive: true });
20658
- const logFilePath = join10(logDir, `${input.task.id}.log`);
21048
+ mkdirSync8(logDir, { recursive: true });
21049
+ const logFilePath = join11(logDir, `${input.task.id}.log`);
20659
21050
  input.logFilePath = logFilePath;
20660
21051
  const encoded = Buffer.from(JSON.stringify(input)).toString("base64");
20661
21052
  let fd;
20662
21053
  try {
20663
21054
  fd = openSync(logFilePath, "a");
20664
21055
  } catch (e) {
20665
- log8.error(`Failed to open log file ${logFilePath}`, e);
21056
+ log9.error(`Failed to open log file ${logFilePath}`, e);
20666
21057
  }
20667
21058
  const child = spawn5(process.execPath, [sessionRunnerPath, encoded], {
20668
21059
  detached: true,
@@ -20675,14 +21066,14 @@ function spawnSessionRunner(input) {
20675
21066
  }
20676
21067
  function spawnMeetingRunner(input) {
20677
21068
  const logDir = sessionRunnerLogDir();
20678
- mkdirSync7(logDir, { recursive: true });
20679
- const logFilePath = join10(logDir, `meeting-${input.meetingId}.log`);
21069
+ mkdirSync8(logDir, { recursive: true });
21070
+ const logFilePath = join11(logDir, `meeting-${input.meetingId}.log`);
20680
21071
  const encoded = Buffer.from(JSON.stringify(input)).toString("base64");
20681
21072
  let fd;
20682
21073
  try {
20683
21074
  fd = openSync(logFilePath, "a");
20684
21075
  } catch (e) {
20685
- log8.error(`Failed to open meeting log file ${logFilePath}`, e);
21076
+ log9.error(`Failed to open meeting log file ${logFilePath}`, e);
20686
21077
  }
20687
21078
  const child = spawn5(process.execPath, [meetingRunnerPath, encoded], {
20688
21079
  detached: true,
@@ -20691,11 +21082,11 @@ function spawnMeetingRunner(input) {
20691
21082
  child.unref();
20692
21083
  if (fd != null)
20693
21084
  closeSync(fd);
20694
- log8.info(`Spawned meeting runner for ${input.meetingId} (pid=${child.pid})`);
21085
+ log9.info(`Spawned meeting runner for ${input.meetingId} (pid=${child.pid})`);
20695
21086
  return child;
20696
21087
  }
20697
21088
  async function handleFileRequest(client, config2, workspaceId, req, token) {
20698
- const agentWorkdir = join10(config2.workspacesRoot, workspaceId, req.agent_id, "workdir");
21089
+ const agentWorkdir = join11(config2.workspacesRoot, workspaceId, req.agent_id, "workdir");
20699
21090
  const resolved = validatePath(agentWorkdir, req.path);
20700
21091
  if (!resolved) {
20701
21092
  await client.reportFileData(token, { request_id: req.id, error: "invalid path", path: req.path });
@@ -20718,7 +21109,7 @@ async function handleFileRequest(client, config2, workspaceId, req, token) {
20718
21109
  }
20719
21110
  }
20720
21111
  async function handleTask(client, config2, runtimeIndex, task, token, activeTasks) {
20721
- log8.info(`Task ${task.id} claimed agent=${task.agentId}`);
21112
+ log9.info(`Task ${task.id} claimed agent=${task.agentId}`);
20722
21113
  if (task.type === TASK_TYPES.KILL_TASK) {
20723
21114
  const targetTaskId = task.context?.target_task_id;
20724
21115
  if (!targetTaskId) {
@@ -20726,8 +21117,8 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20726
21117
  activeTasks.delete(task.id);
20727
21118
  return;
20728
21119
  }
20729
- const agentBaseDir = join10(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
20730
- const timelineDir = join10(agentBaseDir, ".context_timeline");
21120
+ const agentBaseDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
21121
+ const timelineDir = join11(agentBaseDir, ".context_timeline");
20731
21122
  const MAX_WAIT_MS = Number(process.env.ALOOK_KILL_TASK_MAX_WAIT_MS) || 15000;
20732
21123
  const POLL_MS = Number(process.env.ALOOK_KILL_TASK_POLL_MS) || 200;
20733
21124
  const waitStart = Date.now();
@@ -20747,18 +21138,18 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20747
21138
  try {
20748
21139
  process.kill(pid, "SIGTERM");
20749
21140
  await client.failTask(token, task.id, "killed");
20750
- log8.info(`Kill task ${task.id}: sent SIGTERM to pid=${pid} for target=${targetTaskId}`);
21141
+ log9.info(`Kill task ${task.id}: sent SIGTERM to pid=${pid} for target=${targetTaskId}`);
20751
21142
  } catch (e) {
20752
21143
  if (e?.code === "ESRCH") {
20753
21144
  await client.failTask(token, task.id, "target process already exited");
20754
- log8.info(`Kill task ${task.id}: target pid=${pid} already exited`);
21145
+ log9.info(`Kill task ${task.id}: target pid=${pid} already exited`);
20755
21146
  } else {
20756
21147
  await client.failTask(token, task.id, `kill failed: ${e}`);
20757
21148
  }
20758
21149
  }
20759
21150
  } else {
20760
21151
  await client.failTask(token, task.id, "target not found in timeline");
20761
- log8.info(`Kill task ${task.id}: target ${targetTaskId} not found in timeline`);
21152
+ log9.info(`Kill task ${task.id}: target ${targetTaskId} not found in timeline`);
20762
21153
  }
20763
21154
  activeTasks.delete(task.id);
20764
21155
  return;
@@ -20778,17 +21169,17 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20778
21169
  }
20779
21170
  const provider = runtimeData.provider;
20780
21171
  if (task.contextKey) {
20781
- const agentBaseDir = join10(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
21172
+ const agentBaseDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
20782
21173
  cleanupStaleIntents(agentBaseDir);
20783
- const timelineDir = join10(agentBaseDir, ".context_timeline");
21174
+ const timelineDir = join11(agentBaseDir, ".context_timeline");
20784
21175
  const lockAcquired = acquireSteeringLock(agentBaseDir, task.contextKey);
20785
21176
  if (!lockAcquired) {
20786
- log8.warn(`Steering lock contention for context_key=${task.contextKey}, proceeding without steering`);
21177
+ log9.warn(`Steering lock contention for context_key=${task.contextKey}, proceeding without steering`);
20787
21178
  } else {
20788
21179
  try {
20789
21180
  const predecessor = findRunningEntryByContextKey(timelineDir, task.contextKey, provider);
20790
21181
  if (predecessor && predecessor.task_id !== task.id) {
20791
- log8.info(`Steering: task ${task.id} supersedes predecessor ${predecessor.task_id} (context_key=${task.contextKey})`);
21182
+ log9.info(`Steering: task ${task.id} supersedes predecessor ${predecessor.task_id} (context_key=${task.contextKey})`);
20792
21183
  if (predecessor.pid != null) {
20793
21184
  writeKillIntent(agentBaseDir, {
20794
21185
  reason: "superseded",
@@ -20798,12 +21189,12 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20798
21189
  });
20799
21190
  try {
20800
21191
  process.kill(predecessor.pid, "SIGTERM");
20801
- log8.info(`Steering: sent SIGTERM to predecessor pid=${predecessor.pid}`);
21192
+ log9.info(`Steering: sent SIGTERM to predecessor pid=${predecessor.pid}`);
20802
21193
  } catch (e) {
20803
21194
  if (e?.code === "ESRCH") {
20804
- log8.info(`Steering: predecessor pid=${predecessor.pid} already exited`);
21195
+ log9.info(`Steering: predecessor pid=${predecessor.pid} already exited`);
20805
21196
  } else {
20806
- log8.warn(`Steering: kill failed for pid=${predecessor.pid}`, e);
21197
+ log9.warn(`Steering: kill failed for pid=${predecessor.pid}`, e);
20807
21198
  }
20808
21199
  }
20809
21200
  const waitStart = Date.now();
@@ -20816,14 +21207,14 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20816
21207
  await new Promise((r) => setTimeout(r, POLL_MS));
20817
21208
  }
20818
21209
  if (findRunningPidByTaskId(timelineDir, predecessor.task_id) != null) {
20819
- log8.warn(`Steering: predecessor pid=${predecessor.pid} did not exit within ${MAX_WAIT_MS}ms, proceeding anyway`);
21210
+ log9.warn(`Steering: predecessor pid=${predecessor.pid} did not exit within ${MAX_WAIT_MS}ms, proceeding anyway`);
20820
21211
  }
20821
21212
  }
20822
21213
  try {
20823
21214
  await client.supersedeTask(token, predecessor.task_id);
20824
- log8.info(`Steering: predecessor ${predecessor.task_id} marked superseded`);
21215
+ log9.info(`Steering: predecessor ${predecessor.task_id} marked superseded`);
20825
21216
  } catch (e) {
20826
- log8.warn(`Steering: failed to mark predecessor superseded server-side`, e);
21217
+ log9.warn(`Steering: failed to mark predecessor superseded server-side`, e);
20827
21218
  }
20828
21219
  }
20829
21220
  } finally {
@@ -20851,8 +21242,8 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20851
21242
  activeTasks.delete(task.id);
20852
21243
  if (code !== 0) {
20853
21244
  const msg = code === null ? `session-runner killed by signal (task ${task.id})` : `session-runner crashed (exit code ${code}, task ${task.id})`;
20854
- log8.warn(msg);
20855
- const timelineDir = join10(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir", ".context_timeline");
21245
+ log9.warn(msg);
21246
+ const timelineDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir", ".context_timeline");
20856
21247
  updateEntry(timelineDir, task.id, (entry) => {
20857
21248
  entry.pid = null;
20858
21249
  entry.status = "failed";
@@ -20862,10 +21253,10 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20862
21253
  await client.failTask(token, task.id, msg);
20863
21254
  } catch (e) {
20864
21255
  if (isClientError2(e)) {
20865
- log8.info(`Backstop: task ${task.id} already in terminal state`);
21256
+ log9.info(`Backstop: task ${task.id} already in terminal state`);
20866
21257
  return;
20867
21258
  }
20868
- log8.error(`Backstop: failed to report crash for task ${task.id}`, e);
21259
+ log9.error(`Backstop: failed to report crash for task ${task.id}`, e);
20869
21260
  try {
20870
21261
  await writeMarkerFile(config2.workspacesRoot, {
20871
21262
  taskId: task.id,
@@ -20879,7 +21270,7 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
20879
21270
  }
20880
21271
  }
20881
21272
  });
20882
- log8.info(`Task ${task.id} dispatched to session-runner (pid=${child.pid})`);
21273
+ log9.info(`Task ${task.id} dispatched to session-runner (pid=${child.pid})`);
20883
21274
  }
20884
21275
 
20885
21276
  // commands/daemon.ts
@@ -20917,7 +21308,7 @@ async function startInBackground(profile, serverUrl) {
20917
21308
  return;
20918
21309
  }
20919
21310
  const logPath = daemonLogFilePath();
20920
- mkdirSync8(dirname4(logPath), { recursive: true, mode: 448 });
21311
+ mkdirSync9(dirname4(logPath), { recursive: true, mode: 448 });
20921
21312
  const logFd = openSync2(logPath, "a", 384);
20922
21313
  const child = spawn6(process.execPath, buildChildArgs(profile, serverUrl), {
20923
21314
  detached: true,
@@ -21038,8 +21429,8 @@ function configCommand() {
21038
21429
 
21039
21430
  // commands/email.ts
21040
21431
  import { Command as Command5 } from "commander";
21041
- import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync8, statSync as statSync4 } from "fs";
21042
- import { basename, join as join11 } from "path";
21432
+ import { writeFileSync as writeFileSync8, mkdirSync as mkdirSync10, readFileSync as readFileSync9, statSync as statSync5 } from "fs";
21433
+ import { basename as basename2, join as join12 } from "path";
21043
21434
  import PostalMime from "postal-mime";
21044
21435
 
21045
21436
  // lib/flags.ts
@@ -21053,7 +21444,7 @@ function resolveAgentId(opts) {
21053
21444
  }
21054
21445
 
21055
21446
  // commands/email.ts
21056
- var log9 = createLogger2({ module: "email" });
21447
+ var log10 = createLogger2({ module: "email" });
21057
21448
  var VALID_STATUSES = ["unread", "read", "archived", "sent"];
21058
21449
  var VALID_FOLDERS = ["inbox", "sent", "untrust"];
21059
21450
  var EMAIL_BASE = tempDir("alook-emails");
@@ -21150,7 +21541,7 @@ function emailCommand() {
21150
21541
  process.exit(1);
21151
21542
  }
21152
21543
  }
21153
- const emailDir_base = join11(EMAIL_BASE, workspaceId, agentId);
21544
+ const emailDir_base = join12(EMAIL_BASE, workspaceId, agentId);
21154
21545
  try {
21155
21546
  let query = `/api/email?agentId=${agentId}`;
21156
21547
  if (opts.status)
@@ -21170,11 +21561,11 @@ function emailCommand() {
21170
21561
  printJSON(emails2);
21171
21562
  return;
21172
21563
  }
21173
- mkdirSync9(emailDir_base, { recursive: true });
21564
+ mkdirSync10(emailDir_base, { recursive: true });
21174
21565
  const downloadedPaths = [];
21175
21566
  for (const email3 of emails2) {
21176
- const emailDir = join11(emailDir_base, email3.id);
21177
- mkdirSync9(emailDir, { recursive: true });
21567
+ const emailDir = join12(emailDir_base, email3.id);
21568
+ mkdirSync10(emailDir, { recursive: true });
21178
21569
  const metadata = {
21179
21570
  id: email3.id,
21180
21571
  from: email3.from_email,
@@ -21186,8 +21577,8 @@ function emailCommand() {
21186
21577
  in_reply_to: email3.in_reply_to || "",
21187
21578
  references: email3.references || ""
21188
21579
  };
21189
- const metadataPath = join11(emailDir, "metadata.json");
21190
- writeFileSync7(metadataPath, JSON.stringify(metadata, null, 2));
21580
+ const metadataPath = join12(emailDir, "metadata.json");
21581
+ writeFileSync8(metadataPath, JSON.stringify(metadata, null, 2));
21191
21582
  downloadedPaths.push(metadataPath);
21192
21583
  let rawMime;
21193
21584
  try {
@@ -21195,25 +21586,25 @@ function emailCommand() {
21195
21586
  } catch (err) {
21196
21587
  const msg = err instanceof Error ? err.message : String(err);
21197
21588
  if (msg.includes("404")) {
21198
- log9.warn(`email body not available for ${email3.id}, skipping`);
21589
+ log10.warn(`email body not available for ${email3.id}, skipping`);
21199
21590
  continue;
21200
21591
  }
21201
21592
  throw err;
21202
21593
  }
21203
21594
  const parsed = await new PostalMime().parse(rawMime);
21204
21595
  if (parsed.text) {
21205
- const bodyPath = join11(emailDir, "body.txt");
21206
- writeFileSync7(bodyPath, parsed.text);
21596
+ const bodyPath = join12(emailDir, "body.txt");
21597
+ writeFileSync8(bodyPath, parsed.text);
21207
21598
  downloadedPaths.push(bodyPath);
21208
21599
  }
21209
21600
  if (parsed.html) {
21210
- const htmlPath = join11(emailDir, "body.html");
21211
- writeFileSync7(htmlPath, parsed.html);
21601
+ const htmlPath = join12(emailDir, "body.html");
21602
+ writeFileSync8(htmlPath, parsed.html);
21212
21603
  downloadedPaths.push(htmlPath);
21213
21604
  }
21214
21605
  if (parsed.attachments && parsed.attachments.length > 0) {
21215
- const attDir = join11(emailDir, "attachments");
21216
- mkdirSync9(attDir, { recursive: true });
21606
+ const attDir = join12(emailDir, "attachments");
21607
+ mkdirSync10(attDir, { recursive: true });
21217
21608
  const usedFilenames = new Set;
21218
21609
  for (let i = 0;i < parsed.attachments.length; i++) {
21219
21610
  const att = parsed.attachments[i];
@@ -21222,7 +21613,7 @@ function emailCommand() {
21222
21613
  filename = `${i}-${filename}`;
21223
21614
  }
21224
21615
  usedFilenames.add(filename);
21225
- const attPath = join11(attDir, filename);
21616
+ const attPath = join12(attDir, filename);
21226
21617
  const content = att.content;
21227
21618
  let buf;
21228
21619
  if (typeof content === "string") {
@@ -21232,7 +21623,7 @@ function emailCommand() {
21232
21623
  } else {
21233
21624
  buf = Buffer.from(content);
21234
21625
  }
21235
- writeFileSync7(attPath, buf);
21626
+ writeFileSync8(attPath, buf);
21236
21627
  downloadedPaths.push(attPath);
21237
21628
  }
21238
21629
  }
@@ -21273,7 +21664,7 @@ function emailCommand() {
21273
21664
  const client = new APIClient(serverUrl, token, workspaceId);
21274
21665
  let htmlBody;
21275
21666
  try {
21276
- htmlBody = readFileSync8(opts.bodyFile, "utf-8");
21667
+ htmlBody = readFileSync9(opts.bodyFile, "utf-8");
21277
21668
  } catch (err) {
21278
21669
  console.error(`Error: cannot read body file "${opts.bodyFile}": ${err instanceof Error ? err.message : err}`);
21279
21670
  process.exit(1);
@@ -21289,13 +21680,13 @@ function emailCommand() {
21289
21680
  let bytes;
21290
21681
  let size;
21291
21682
  try {
21292
- bytes = readFileSync8(path2);
21293
- size = statSync4(path2).size;
21683
+ bytes = readFileSync9(path2);
21684
+ size = statSync5(path2).size;
21294
21685
  } catch (err) {
21295
21686
  console.error(`Error: cannot read attachment "${path2}": ${err instanceof Error ? err.message : err}`);
21296
21687
  process.exit(1);
21297
21688
  }
21298
- const filename = basename(path2);
21689
+ const filename = basename2(path2);
21299
21690
  const contentType = guessContentType(filename);
21300
21691
  const form = new FormData;
21301
21692
  form.append("file", new Blob([new Uint8Array(bytes)], { type: contentType }), filename);
@@ -21317,7 +21708,7 @@ function emailCommand() {
21317
21708
  references = [parentEmail.references, parentEmail.message_id].filter(Boolean).join(" ").trim() || undefined;
21318
21709
  }
21319
21710
  } catch {
21320
- log9.warn(`could not fetch parent email ${opts.inReplyTo}, sending without threading`);
21711
+ log10.warn(`could not fetch parent email ${opts.inReplyTo}, sending without threading`);
21321
21712
  }
21322
21713
  }
21323
21714
  const conversationId = process.env.ALOOK_CONVERSATION_ID;
@@ -21402,13 +21793,13 @@ function emailCommand() {
21402
21793
  let bytes;
21403
21794
  let size;
21404
21795
  try {
21405
- bytes = readFileSync8(path2);
21406
- size = statSync4(path2).size;
21796
+ bytes = readFileSync9(path2);
21797
+ size = statSync5(path2).size;
21407
21798
  } catch (err) {
21408
21799
  console.error(`Error: cannot read attachment "${path2}": ${err instanceof Error ? err.message : err}`);
21409
21800
  process.exit(1);
21410
21801
  }
21411
- const filename = basename(path2);
21802
+ const filename = basename2(path2);
21412
21803
  const contentType = guessContentType(filename);
21413
21804
  const form = new FormData;
21414
21805
  form.append("file", new Blob([new Uint8Array(bytes)], { type: contentType }), filename);
@@ -21749,7 +22140,7 @@ function calendarCommand() {
21749
22140
 
21750
22141
  // commands/issue.ts
21751
22142
  import { Command as Command7 } from "commander";
21752
- import { readFileSync as readFileSync9 } from "fs";
22143
+ import { readFileSync as readFileSync10 } from "fs";
21753
22144
  var VALID_STATUSES2 = ["todo", "in_progress", "review", "done", "closed", "canceled", "failed"];
21754
22145
  function resolveClientOpts3(command, agentId) {
21755
22146
  let root = command;
@@ -21773,7 +22164,7 @@ function readBody(opts) {
21773
22164
  process.exit(1);
21774
22165
  }
21775
22166
  if (opts.bodyFile)
21776
- return readFileSync9(opts.bodyFile, "utf-8");
22167
+ return readFileSync10(opts.bodyFile, "utf-8");
21777
22168
  return opts.body ?? "";
21778
22169
  }
21779
22170
  function printIssue(issue3) {
@@ -21971,8 +22362,8 @@ ${result.output}`);
21971
22362
 
21972
22363
  // commands/sync.ts
21973
22364
  import { Command as Command10 } from "commander";
21974
- import { readFileSync as readFileSync10 } from "fs";
21975
- import { basename as basename2 } from "path";
22365
+ import { readFileSync as readFileSync11 } from "fs";
22366
+ import { basename as basename3 } from "path";
21976
22367
  var MIME_BY_EXT2 = {
21977
22368
  ".pdf": "application/pdf",
21978
22369
  ".png": "image/png",
@@ -22020,12 +22411,12 @@ function syncCommand() {
22020
22411
  const client = new APIClient(serverUrl, token, workspaceId);
22021
22412
  let bytes;
22022
22413
  try {
22023
- bytes = readFileSync10(opts.file);
22414
+ bytes = readFileSync11(opts.file);
22024
22415
  } catch (err) {
22025
22416
  console.error(`Error: cannot read file "${opts.file}": ${err.message}`);
22026
22417
  process.exit(1);
22027
22418
  }
22028
- const filename = basename2(opts.file);
22419
+ const filename = basename3(opts.file);
22029
22420
  const contentType = guessContentType2(filename);
22030
22421
  const form = new FormData;
22031
22422
  form.append("file", new Blob([new Uint8Array(bytes)], { type: contentType }), filename);