@alook/cli 0.0.92 → 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 +542 -154
- package/dist/session-runner.js +63 -28
- package/package.json +3 -3
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
@@ -20002,6 +20037,349 @@ function validatePath(agentWorkdir, requestedPath) {
|
|
|
20002
20037
|
return resolved;
|
|
20003
20038
|
}
|
|
20004
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
|
+
|
|
20005
20383
|
// lib/shell-env.ts
|
|
20006
20384
|
import { execSync as execSync3 } from "child_process";
|
|
20007
20385
|
var PASSTHROUGH_VARS = ["ALOOK_PROJECT_ROOT", "ALOOK_SERVER_URL", "ALOOK_CMD_PREFIX", "ALOOK_HEALTH_PORT"];
|
|
@@ -20036,15 +20414,15 @@ function resolveLoginShellEnv() {
|
|
|
20036
20414
|
}
|
|
20037
20415
|
|
|
20038
20416
|
// daemon/daemon.ts
|
|
20039
|
-
import { existsSync as
|
|
20417
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync8, openSync, closeSync, readdirSync as readdirSync3, statSync as statSync4, unlinkSync as unlinkSync5 } from "fs";
|
|
20040
20418
|
import { readdir as readdir2, readFile as readFile2, unlink, stat as fsStat } from "fs/promises";
|
|
20041
20419
|
import { execSync as execSync4, spawn as spawn5 } from "child_process";
|
|
20042
20420
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
20043
|
-
import { dirname as dirname3, join as
|
|
20044
|
-
var
|
|
20421
|
+
import { dirname as dirname3, join as join11 } from "path";
|
|
20422
|
+
var log9 = createLogger2({ module: "daemon" });
|
|
20045
20423
|
var _dir = dirname3(fileURLToPath2(import.meta.url));
|
|
20046
|
-
var sessionRunnerPath =
|
|
20047
|
-
var meetingRunnerPath =
|
|
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");
|
|
20048
20426
|
function isCommandAvailable2(cmd) {
|
|
20049
20427
|
try {
|
|
20050
20428
|
const check2 = process.platform === "win32" ? `where ${cmd}` : `which ${cmd}`;
|
|
@@ -20059,16 +20437,16 @@ function pruneSessionRunnerLogs() {
|
|
|
20059
20437
|
const logDir = sessionRunnerLogDir();
|
|
20060
20438
|
let entries;
|
|
20061
20439
|
try {
|
|
20062
|
-
entries =
|
|
20440
|
+
entries = readdirSync3(logDir).filter((f) => f.endsWith(".log"));
|
|
20063
20441
|
} catch {
|
|
20064
20442
|
return;
|
|
20065
20443
|
}
|
|
20066
20444
|
if (entries.length <= MAX_SESSION_RUNNER_LOGS)
|
|
20067
20445
|
return;
|
|
20068
20446
|
const withMtime = entries.map((name) => {
|
|
20069
|
-
const full =
|
|
20447
|
+
const full = join11(logDir, name);
|
|
20070
20448
|
try {
|
|
20071
|
-
return { name, mtime:
|
|
20449
|
+
return { name, mtime: statSync4(full).mtimeMs };
|
|
20072
20450
|
} catch {
|
|
20073
20451
|
return { name, mtime: 0 };
|
|
20074
20452
|
}
|
|
@@ -20076,7 +20454,7 @@ function pruneSessionRunnerLogs() {
|
|
|
20076
20454
|
withMtime.sort((a, b) => b.mtime - a.mtime);
|
|
20077
20455
|
for (const entry of withMtime.slice(MAX_SESSION_RUNNER_LOGS)) {
|
|
20078
20456
|
try {
|
|
20079
|
-
unlinkSync5(
|
|
20457
|
+
unlinkSync5(join11(logDir, entry.name));
|
|
20080
20458
|
} catch {}
|
|
20081
20459
|
}
|
|
20082
20460
|
}
|
|
@@ -20117,7 +20495,7 @@ function isValidMarker(data) {
|
|
|
20117
20495
|
var MARKER_STALE_MS = 24 * 60 * 60 * 1000;
|
|
20118
20496
|
var TMP_STALE_MS = 60 * 60 * 1000;
|
|
20119
20497
|
async function reconcilePendingCompletions(workspacesRoot) {
|
|
20120
|
-
const dir =
|
|
20498
|
+
const dir = join11(workspacesRoot, ".pending_completions");
|
|
20121
20499
|
let entries;
|
|
20122
20500
|
try {
|
|
20123
20501
|
entries = await readdir2(dir);
|
|
@@ -20128,15 +20506,15 @@ async function reconcilePendingCompletions(workspacesRoot) {
|
|
|
20128
20506
|
if (!name.endsWith(".tmp"))
|
|
20129
20507
|
continue;
|
|
20130
20508
|
try {
|
|
20131
|
-
const s = await fsStat(
|
|
20509
|
+
const s = await fsStat(join11(dir, name));
|
|
20132
20510
|
if (Date.now() - s.mtimeMs > TMP_STALE_MS) {
|
|
20133
|
-
await unlink(
|
|
20511
|
+
await unlink(join11(dir, name));
|
|
20134
20512
|
}
|
|
20135
20513
|
} catch {}
|
|
20136
20514
|
}
|
|
20137
20515
|
const jsonFiles = entries.filter((f) => f.endsWith(".json"));
|
|
20138
20516
|
for (const name of jsonFiles) {
|
|
20139
|
-
const filePath =
|
|
20517
|
+
const filePath = join11(dir, name);
|
|
20140
20518
|
try {
|
|
20141
20519
|
let raw;
|
|
20142
20520
|
try {
|
|
@@ -20148,14 +20526,14 @@ async function reconcilePendingCompletions(workspacesRoot) {
|
|
|
20148
20526
|
try {
|
|
20149
20527
|
parsed = JSON.parse(raw);
|
|
20150
20528
|
} catch {
|
|
20151
|
-
|
|
20529
|
+
log9.warn(`reconcile: malformed marker ${name}, deleting`);
|
|
20152
20530
|
try {
|
|
20153
20531
|
await unlink(filePath);
|
|
20154
20532
|
} catch {}
|
|
20155
20533
|
continue;
|
|
20156
20534
|
}
|
|
20157
20535
|
if (!isValidMarker(parsed)) {
|
|
20158
|
-
|
|
20536
|
+
log9.warn(`reconcile: invalid marker structure ${name}, deleting`);
|
|
20159
20537
|
try {
|
|
20160
20538
|
await unlink(filePath);
|
|
20161
20539
|
} catch {}
|
|
@@ -20164,7 +20542,7 @@ async function reconcilePendingCompletions(workspacesRoot) {
|
|
|
20164
20542
|
const marker = parsed;
|
|
20165
20543
|
const age = Date.now() - new Date(marker.createdAt).getTime();
|
|
20166
20544
|
if (age > MARKER_STALE_MS) {
|
|
20167
|
-
|
|
20545
|
+
log9.warn(`reconcile: stale marker ${name} (${Math.round(age / 3600000)}h old), deleting`);
|
|
20168
20546
|
try {
|
|
20169
20547
|
await unlink(filePath);
|
|
20170
20548
|
} catch {}
|
|
@@ -20180,7 +20558,7 @@ async function reconcilePendingCompletions(workspacesRoot) {
|
|
|
20180
20558
|
try {
|
|
20181
20559
|
await unlink(filePath);
|
|
20182
20560
|
} catch (delErr) {
|
|
20183
|
-
|
|
20561
|
+
log9.warn(`reconcile: delivered marker ${name} but failed to delete: ${delErr}`);
|
|
20184
20562
|
}
|
|
20185
20563
|
} catch (deliverErr) {
|
|
20186
20564
|
if (isClientError2(deliverErr)) {
|
|
@@ -20188,11 +20566,11 @@ async function reconcilePendingCompletions(workspacesRoot) {
|
|
|
20188
20566
|
await unlink(filePath);
|
|
20189
20567
|
} catch {}
|
|
20190
20568
|
} else {
|
|
20191
|
-
|
|
20569
|
+
log9.debug(`reconcile: delivery failed for ${name}, will retry next cycle`);
|
|
20192
20570
|
}
|
|
20193
20571
|
}
|
|
20194
20572
|
} catch (e) {
|
|
20195
|
-
|
|
20573
|
+
log9.debug(`reconcile: error processing ${name}`, e);
|
|
20196
20574
|
}
|
|
20197
20575
|
}
|
|
20198
20576
|
}
|
|
@@ -20203,7 +20581,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20203
20581
|
}
|
|
20204
20582
|
process.once("exit", () => releaseDaemonPid(profile));
|
|
20205
20583
|
const bailOnUnexpected = (label, err) => {
|
|
20206
|
-
|
|
20584
|
+
log9.error(`${label} — shutting down`, err);
|
|
20207
20585
|
releaseDaemonPid(profile);
|
|
20208
20586
|
process.exit(1);
|
|
20209
20587
|
};
|
|
@@ -20216,21 +20594,21 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20216
20594
|
if (marker) {
|
|
20217
20595
|
clearUpdateMarker(profile);
|
|
20218
20596
|
if (marker === config2.cliVersion) {
|
|
20219
|
-
|
|
20597
|
+
log9.info(`Cleared update marker — now running v${config2.cliVersion}`);
|
|
20220
20598
|
} else {
|
|
20221
|
-
|
|
20599
|
+
log9.info(`Cleared stale update marker (was v${marker}, running v${config2.cliVersion}) — update will be retried`);
|
|
20222
20600
|
}
|
|
20223
20601
|
}
|
|
20224
20602
|
const cliConfig = loadCLIConfigForProfile(profile);
|
|
20225
20603
|
const workspaces = cliConfig.watched_workspaces || [];
|
|
20226
20604
|
if (workspaces.length === 0) {
|
|
20227
|
-
|
|
20605
|
+
log9.error("No watched workspaces configured.");
|
|
20228
20606
|
process.exit(1);
|
|
20229
20607
|
return;
|
|
20230
20608
|
}
|
|
20231
20609
|
const hasPerWorkspaceTokens = workspaces.every((ws) => !!ws.token);
|
|
20232
20610
|
if (!hasPerWorkspaceTokens) {
|
|
20233
|
-
|
|
20611
|
+
log9.error(`Config uses old format. Run '${cmdPrefix()} register --token <token>' for each workspace to upgrade.`);
|
|
20234
20612
|
process.exit(1);
|
|
20235
20613
|
return;
|
|
20236
20614
|
}
|
|
@@ -20250,11 +20628,11 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20250
20628
|
}
|
|
20251
20629
|
}
|
|
20252
20630
|
if (providers.length === 0) {
|
|
20253
|
-
|
|
20631
|
+
log9.error("No agent CLI tools found on PATH.");
|
|
20254
20632
|
process.exit(1);
|
|
20255
20633
|
return;
|
|
20256
20634
|
}
|
|
20257
|
-
|
|
20635
|
+
log9.info(`Detected providers: ${providers.map((p) => `${p.type}@${p.version}`).join(", ")}`);
|
|
20258
20636
|
const workspaceStates = [];
|
|
20259
20637
|
const runtimeIndex = new Map;
|
|
20260
20638
|
for (const ws of workspaces) {
|
|
@@ -20262,7 +20640,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20262
20640
|
type: p.type,
|
|
20263
20641
|
version: p.version
|
|
20264
20642
|
}));
|
|
20265
|
-
|
|
20643
|
+
log9.info(`Registering workspace ${ws.id} (${ws.name ?? "unnamed"}) with ${runtimes.length} runtime(s)...`);
|
|
20266
20644
|
let resp;
|
|
20267
20645
|
try {
|
|
20268
20646
|
resp = await client.register(ws.token, {
|
|
@@ -20275,13 +20653,13 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20275
20653
|
});
|
|
20276
20654
|
} catch (e) {
|
|
20277
20655
|
if (e instanceof Error && e.message.startsWith("HTTP 401")) {
|
|
20278
|
-
|
|
20656
|
+
log9.warn(`Workspace ${ws.id} token invalid — skipping (run '${cmdPrefix()} register --token <token>' to fix)`);
|
|
20279
20657
|
} else {
|
|
20280
|
-
|
|
20658
|
+
log9.error(`Failed to register workspace ${ws.id}, skipping`, e);
|
|
20281
20659
|
}
|
|
20282
20660
|
continue;
|
|
20283
20661
|
}
|
|
20284
|
-
|
|
20662
|
+
log9.info(`Workspace ${ws.id} registered — ${resp.runtimes.length} runtime(s)`);
|
|
20285
20663
|
const runtimeIds = resp.runtimes.map((r) => r.id);
|
|
20286
20664
|
workspaceStates.push({ workspaceId: ws.id, token: ws.token, runtimeIds });
|
|
20287
20665
|
for (let i = 0;i < runtimeIds.length; i++) {
|
|
@@ -20293,13 +20671,13 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20293
20671
|
}
|
|
20294
20672
|
}
|
|
20295
20673
|
if (workspaceStates.length === 0) {
|
|
20296
|
-
|
|
20674
|
+
log9.error("No workspaces registered successfully.");
|
|
20297
20675
|
process.exit(1);
|
|
20298
20676
|
return;
|
|
20299
20677
|
}
|
|
20300
20678
|
const allRuntimeIds = workspaceStates.flatMap((ws) => ws.runtimeIds);
|
|
20301
20679
|
health.setRuntimeCount(allRuntimeIds.length);
|
|
20302
|
-
|
|
20680
|
+
log9.info(`Daemon started — ${allRuntimeIds.length} runtime(s) across ${workspaceStates.length} workspace(s)`);
|
|
20303
20681
|
const activeTasks = new Set;
|
|
20304
20682
|
const knownAgentIds = new Set(workspaces.flatMap((ws) => ws.agent_ids ?? []));
|
|
20305
20683
|
function syncAgentId(agentId, workspaceId) {
|
|
@@ -20334,7 +20712,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20334
20712
|
cfg.watched_workspaces = (cfg.watched_workspaces || []).filter((w) => w.id !== workspaceId);
|
|
20335
20713
|
saveCLIConfigForProfile(profile, cfg);
|
|
20336
20714
|
} catch {}
|
|
20337
|
-
|
|
20715
|
+
log9.info(`Workspace ${workspaceId} deleted server-side — removed from config`);
|
|
20338
20716
|
}
|
|
20339
20717
|
const pollCycle = async () => {
|
|
20340
20718
|
let remaining = config2.maxConcurrentTasks - activeTasks.size;
|
|
@@ -20360,7 +20738,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20360
20738
|
handleCliUpdate(pending_update.version, () => requestRestart(), profile);
|
|
20361
20739
|
}
|
|
20362
20740
|
if (pending_rescan) {
|
|
20363
|
-
|
|
20741
|
+
log9.info("Rescan requested — restarting daemon to re-detect runtimes");
|
|
20364
20742
|
for (const id of evictedIds) {
|
|
20365
20743
|
evictWorkspace(id);
|
|
20366
20744
|
}
|
|
@@ -20373,19 +20751,19 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20373
20751
|
activeTasks.add(task.id);
|
|
20374
20752
|
remaining--;
|
|
20375
20753
|
handleTask(client, config2, runtimeIndex, task, ws.token, activeTasks).catch((e) => {
|
|
20376
|
-
|
|
20754
|
+
log9.error("Task error", e);
|
|
20377
20755
|
activeTasks.delete(task.id);
|
|
20378
20756
|
});
|
|
20379
20757
|
}
|
|
20380
20758
|
if (file_requests) {
|
|
20381
20759
|
for (const req of file_requests) {
|
|
20382
|
-
handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) =>
|
|
20760
|
+
handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) => log9.debug("File request error", e));
|
|
20383
20761
|
}
|
|
20384
20762
|
}
|
|
20385
20763
|
if (meetings) {
|
|
20386
20764
|
for (const m of meetings) {
|
|
20387
|
-
const agentBaseDir =
|
|
20388
|
-
const timelineDir =
|
|
20765
|
+
const agentBaseDir = join11(config2.workspacesRoot, m.workspace_id, m.agent_id, "workdir");
|
|
20766
|
+
const timelineDir = join11(agentBaseDir, ".context_timeline");
|
|
20389
20767
|
spawnMeetingRunner({
|
|
20390
20768
|
meetingId: m.id,
|
|
20391
20769
|
meetingUrl: m.meeting_url,
|
|
@@ -20402,9 +20780,9 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20402
20780
|
}
|
|
20403
20781
|
} catch (e) {
|
|
20404
20782
|
if (e instanceof Error && e.message.startsWith("HTTP 401")) {
|
|
20405
|
-
|
|
20783
|
+
log9.warn(`Workspace ${ws.workspaceId} poll returned 401 — will retry next cycle`);
|
|
20406
20784
|
} else {
|
|
20407
|
-
|
|
20785
|
+
log9.debug("Poll error", e);
|
|
20408
20786
|
}
|
|
20409
20787
|
}
|
|
20410
20788
|
}
|
|
@@ -20412,7 +20790,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20412
20790
|
evictWorkspace(id);
|
|
20413
20791
|
}
|
|
20414
20792
|
if (workspaceStates.length === 0) {
|
|
20415
|
-
|
|
20793
|
+
log9.info("All workspaces evicted — shutting down");
|
|
20416
20794
|
shutdown();
|
|
20417
20795
|
}
|
|
20418
20796
|
};
|
|
@@ -20420,7 +20798,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20420
20798
|
const heartbeatPing = () => {
|
|
20421
20799
|
for (const ws of workspaceStates) {
|
|
20422
20800
|
client.heartbeat(ws.token, config2.daemonId).catch((e) => {
|
|
20423
|
-
|
|
20801
|
+
log9.debug("heartbeat failed", { workspaceId: ws.workspaceId, err: String(e) });
|
|
20424
20802
|
});
|
|
20425
20803
|
}
|
|
20426
20804
|
};
|
|
@@ -20445,7 +20823,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20445
20823
|
syncAgentId(task.agentId, ws.workspaceId);
|
|
20446
20824
|
activeTasks.add(task.id);
|
|
20447
20825
|
handleTask(client, config2, runtimeIndex, task, ws.token, activeTasks).catch((e) => {
|
|
20448
|
-
|
|
20826
|
+
log9.error("WS task error", e);
|
|
20449
20827
|
activeTasks.delete(task.id);
|
|
20450
20828
|
});
|
|
20451
20829
|
}
|
|
@@ -20454,7 +20832,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20454
20832
|
const ws = workspaceStates.find((w) => w.workspaceId === msg.workspaceId);
|
|
20455
20833
|
if (ws) {
|
|
20456
20834
|
for (const req of msg.requests) {
|
|
20457
|
-
handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) =>
|
|
20835
|
+
handleFileRequest(client, config2, ws.workspaceId, req, ws.token).catch((e) => log9.debug("WS file request error", e));
|
|
20458
20836
|
}
|
|
20459
20837
|
}
|
|
20460
20838
|
break;
|
|
@@ -20464,8 +20842,8 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20464
20842
|
const ws = workspaceStates.find((w) => w.workspaceId === m.workspace_id);
|
|
20465
20843
|
if (!ws)
|
|
20466
20844
|
continue;
|
|
20467
|
-
const agentBaseDir =
|
|
20468
|
-
const timelineDir =
|
|
20845
|
+
const agentBaseDir = join11(config2.workspacesRoot, m.workspace_id, m.agent_id, "workdir");
|
|
20846
|
+
const timelineDir = join11(agentBaseDir, ".context_timeline");
|
|
20469
20847
|
spawnMeetingRunner({
|
|
20470
20848
|
meetingId: m.id,
|
|
20471
20849
|
meetingUrl: m.meeting_url,
|
|
@@ -20489,7 +20867,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20489
20867
|
}
|
|
20490
20868
|
break;
|
|
20491
20869
|
case "daemon.rescan":
|
|
20492
|
-
|
|
20870
|
+
log9.info("WS rescan requested — restarting daemon");
|
|
20493
20871
|
requestRestart();
|
|
20494
20872
|
break;
|
|
20495
20873
|
case "daemon.kill": {
|
|
@@ -20517,7 +20895,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20517
20895
|
});
|
|
20518
20896
|
activeTasks.add(killTask.id);
|
|
20519
20897
|
handleTask(client, config2, runtimeIndex, killTask, ws.token, activeTasks).catch((e) => {
|
|
20520
|
-
|
|
20898
|
+
log9.error("WS kill task error", e);
|
|
20521
20899
|
activeTasks.delete(killTask.id);
|
|
20522
20900
|
});
|
|
20523
20901
|
}
|
|
@@ -20531,11 +20909,11 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20531
20909
|
machineToken: firstToken,
|
|
20532
20910
|
onMessage: handleWsPush,
|
|
20533
20911
|
onConnected: () => {
|
|
20534
|
-
|
|
20912
|
+
log9.info("WS connected — switching to low-frequency poll");
|
|
20535
20913
|
updatePollInterval(config2.wsPollInterval);
|
|
20536
20914
|
},
|
|
20537
20915
|
onDisconnected: () => {
|
|
20538
|
-
|
|
20916
|
+
log9.info("WS disconnected — reverting to high-frequency poll");
|
|
20539
20917
|
updatePollInterval(config2.pollInterval);
|
|
20540
20918
|
}
|
|
20541
20919
|
}) : null;
|
|
@@ -20543,16 +20921,25 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20543
20921
|
const sweepTick = async () => {
|
|
20544
20922
|
for (const ws of workspaceStates) {
|
|
20545
20923
|
client.sweep(ws.token, config2.daemonId).catch((e) => {
|
|
20546
|
-
|
|
20924
|
+
log9.debug("sweep ping failed", { workspaceId: ws.workspaceId, err: String(e) });
|
|
20547
20925
|
});
|
|
20548
20926
|
}
|
|
20549
20927
|
try {
|
|
20550
20928
|
await reconcilePendingCompletions(config2.workspacesRoot);
|
|
20551
20929
|
} catch (e) {
|
|
20552
|
-
|
|
20930
|
+
log9.debug("reconciliation error", e);
|
|
20553
20931
|
}
|
|
20554
20932
|
};
|
|
20555
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);
|
|
20556
20943
|
let shuttingDown = false;
|
|
20557
20944
|
let restartRequested = false;
|
|
20558
20945
|
const requestRestart = () => {
|
|
@@ -20563,10 +20950,11 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20563
20950
|
if (shuttingDown)
|
|
20564
20951
|
return;
|
|
20565
20952
|
shuttingDown = true;
|
|
20566
|
-
|
|
20953
|
+
log9.info(restartRequested ? "Restarting..." : "Shutting down...");
|
|
20567
20954
|
clearInterval(pollTimer);
|
|
20568
20955
|
clearInterval(heartbeatTimer);
|
|
20569
20956
|
clearInterval(sweepTimer);
|
|
20957
|
+
stopSkillScanner();
|
|
20570
20958
|
wsClient?.close();
|
|
20571
20959
|
const shutdownMs = restartRequested ? 30000 : Number(process.env.ALOOK_SHUTDOWN_TIMEOUT_MS) || 5000;
|
|
20572
20960
|
const timeout = setTimeout(() => process.exit(1), shutdownMs);
|
|
@@ -20587,10 +20975,10 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20587
20975
|
const logPath = daemonLogFilePath();
|
|
20588
20976
|
let logFd;
|
|
20589
20977
|
try {
|
|
20590
|
-
|
|
20978
|
+
mkdirSync8(dirname3(logPath), { recursive: true, mode: 448 });
|
|
20591
20979
|
logFd = openSync(logPath, "a", 384);
|
|
20592
20980
|
} catch (e) {
|
|
20593
|
-
|
|
20981
|
+
log9.error(`Failed to open daemon log file ${logPath}`, e);
|
|
20594
20982
|
}
|
|
20595
20983
|
const child = spawn5(process.execPath, args, {
|
|
20596
20984
|
detached: true,
|
|
@@ -20600,7 +20988,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20600
20988
|
child.unref();
|
|
20601
20989
|
if (logFd != null)
|
|
20602
20990
|
closeSync(logFd);
|
|
20603
|
-
|
|
20991
|
+
log9.info(`Spawned new daemon (pid=${child.pid}), logs: ${logPath}`);
|
|
20604
20992
|
}
|
|
20605
20993
|
clearTimeout(timeout);
|
|
20606
20994
|
process.exit(0);
|
|
@@ -20611,7 +20999,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20611
20999
|
process.on("SIGHUP", async () => {
|
|
20612
21000
|
if (shuttingDown)
|
|
20613
21001
|
return;
|
|
20614
|
-
|
|
21002
|
+
log9.info("SIGHUP received — reloading config...");
|
|
20615
21003
|
try {
|
|
20616
21004
|
const freshConfig = loadCLIConfigForProfile(profile);
|
|
20617
21005
|
const freshWorkspaces = freshConfig.watched_workspaces || [];
|
|
@@ -20619,7 +21007,7 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20619
21007
|
const newWorkspaces = freshWorkspaces.filter((ws) => ws.token && !existingIds.has(ws.id));
|
|
20620
21008
|
for (const ws of newWorkspaces) {
|
|
20621
21009
|
const runtimes = providers.map((p) => ({ type: p.type, version: p.version }));
|
|
20622
|
-
|
|
21010
|
+
log9.info(`Registering new workspace ${ws.id} (${ws.name ?? "unnamed"})...`);
|
|
20623
21011
|
try {
|
|
20624
21012
|
const resp = await client.register(ws.token, {
|
|
20625
21013
|
workspace_id: ws.id,
|
|
@@ -20638,34 +21026,34 @@ async function startDaemon(profile, serverUrl) {
|
|
|
20638
21026
|
provider: providers[i].type
|
|
20639
21027
|
});
|
|
20640
21028
|
}
|
|
20641
|
-
|
|
21029
|
+
log9.info(`Workspace ${ws.id} added — ${runtimeIds.length} runtime(s)`);
|
|
20642
21030
|
} catch (e) {
|
|
20643
|
-
|
|
21031
|
+
log9.error(`Failed to register new workspace ${ws.id}`, e);
|
|
20644
21032
|
}
|
|
20645
21033
|
}
|
|
20646
21034
|
if (newWorkspaces.length > 0) {
|
|
20647
21035
|
health.setRuntimeCount(workspaceStates.reduce((sum, w) => sum + w.runtimeIds.length, 0));
|
|
20648
|
-
|
|
21036
|
+
log9.info(`Reload complete — now polling ${workspaceStates.length} workspace(s)`);
|
|
20649
21037
|
} else {
|
|
20650
|
-
|
|
21038
|
+
log9.info("Reload complete — no new workspaces found");
|
|
20651
21039
|
}
|
|
20652
21040
|
} catch (e) {
|
|
20653
|
-
|
|
21041
|
+
log9.error("Failed to reload config", e);
|
|
20654
21042
|
}
|
|
20655
21043
|
});
|
|
20656
21044
|
await pollCycle();
|
|
20657
21045
|
}
|
|
20658
21046
|
function spawnSessionRunner(input) {
|
|
20659
21047
|
const logDir = sessionRunnerLogDir();
|
|
20660
|
-
|
|
20661
|
-
const logFilePath =
|
|
21048
|
+
mkdirSync8(logDir, { recursive: true });
|
|
21049
|
+
const logFilePath = join11(logDir, `${input.task.id}.log`);
|
|
20662
21050
|
input.logFilePath = logFilePath;
|
|
20663
21051
|
const encoded = Buffer.from(JSON.stringify(input)).toString("base64");
|
|
20664
21052
|
let fd;
|
|
20665
21053
|
try {
|
|
20666
21054
|
fd = openSync(logFilePath, "a");
|
|
20667
21055
|
} catch (e) {
|
|
20668
|
-
|
|
21056
|
+
log9.error(`Failed to open log file ${logFilePath}`, e);
|
|
20669
21057
|
}
|
|
20670
21058
|
const child = spawn5(process.execPath, [sessionRunnerPath, encoded], {
|
|
20671
21059
|
detached: true,
|
|
@@ -20678,14 +21066,14 @@ function spawnSessionRunner(input) {
|
|
|
20678
21066
|
}
|
|
20679
21067
|
function spawnMeetingRunner(input) {
|
|
20680
21068
|
const logDir = sessionRunnerLogDir();
|
|
20681
|
-
|
|
20682
|
-
const logFilePath =
|
|
21069
|
+
mkdirSync8(logDir, { recursive: true });
|
|
21070
|
+
const logFilePath = join11(logDir, `meeting-${input.meetingId}.log`);
|
|
20683
21071
|
const encoded = Buffer.from(JSON.stringify(input)).toString("base64");
|
|
20684
21072
|
let fd;
|
|
20685
21073
|
try {
|
|
20686
21074
|
fd = openSync(logFilePath, "a");
|
|
20687
21075
|
} catch (e) {
|
|
20688
|
-
|
|
21076
|
+
log9.error(`Failed to open meeting log file ${logFilePath}`, e);
|
|
20689
21077
|
}
|
|
20690
21078
|
const child = spawn5(process.execPath, [meetingRunnerPath, encoded], {
|
|
20691
21079
|
detached: true,
|
|
@@ -20694,11 +21082,11 @@ function spawnMeetingRunner(input) {
|
|
|
20694
21082
|
child.unref();
|
|
20695
21083
|
if (fd != null)
|
|
20696
21084
|
closeSync(fd);
|
|
20697
|
-
|
|
21085
|
+
log9.info(`Spawned meeting runner for ${input.meetingId} (pid=${child.pid})`);
|
|
20698
21086
|
return child;
|
|
20699
21087
|
}
|
|
20700
21088
|
async function handleFileRequest(client, config2, workspaceId, req, token) {
|
|
20701
|
-
const agentWorkdir =
|
|
21089
|
+
const agentWorkdir = join11(config2.workspacesRoot, workspaceId, req.agent_id, "workdir");
|
|
20702
21090
|
const resolved = validatePath(agentWorkdir, req.path);
|
|
20703
21091
|
if (!resolved) {
|
|
20704
21092
|
await client.reportFileData(token, { request_id: req.id, error: "invalid path", path: req.path });
|
|
@@ -20721,7 +21109,7 @@ async function handleFileRequest(client, config2, workspaceId, req, token) {
|
|
|
20721
21109
|
}
|
|
20722
21110
|
}
|
|
20723
21111
|
async function handleTask(client, config2, runtimeIndex, task, token, activeTasks) {
|
|
20724
|
-
|
|
21112
|
+
log9.info(`Task ${task.id} claimed agent=${task.agentId}`);
|
|
20725
21113
|
if (task.type === TASK_TYPES.KILL_TASK) {
|
|
20726
21114
|
const targetTaskId = task.context?.target_task_id;
|
|
20727
21115
|
if (!targetTaskId) {
|
|
@@ -20729,8 +21117,8 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20729
21117
|
activeTasks.delete(task.id);
|
|
20730
21118
|
return;
|
|
20731
21119
|
}
|
|
20732
|
-
const agentBaseDir =
|
|
20733
|
-
const timelineDir =
|
|
21120
|
+
const agentBaseDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
|
|
21121
|
+
const timelineDir = join11(agentBaseDir, ".context_timeline");
|
|
20734
21122
|
const MAX_WAIT_MS = Number(process.env.ALOOK_KILL_TASK_MAX_WAIT_MS) || 15000;
|
|
20735
21123
|
const POLL_MS = Number(process.env.ALOOK_KILL_TASK_POLL_MS) || 200;
|
|
20736
21124
|
const waitStart = Date.now();
|
|
@@ -20750,18 +21138,18 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20750
21138
|
try {
|
|
20751
21139
|
process.kill(pid, "SIGTERM");
|
|
20752
21140
|
await client.failTask(token, task.id, "killed");
|
|
20753
|
-
|
|
21141
|
+
log9.info(`Kill task ${task.id}: sent SIGTERM to pid=${pid} for target=${targetTaskId}`);
|
|
20754
21142
|
} catch (e) {
|
|
20755
21143
|
if (e?.code === "ESRCH") {
|
|
20756
21144
|
await client.failTask(token, task.id, "target process already exited");
|
|
20757
|
-
|
|
21145
|
+
log9.info(`Kill task ${task.id}: target pid=${pid} already exited`);
|
|
20758
21146
|
} else {
|
|
20759
21147
|
await client.failTask(token, task.id, `kill failed: ${e}`);
|
|
20760
21148
|
}
|
|
20761
21149
|
}
|
|
20762
21150
|
} else {
|
|
20763
21151
|
await client.failTask(token, task.id, "target not found in timeline");
|
|
20764
|
-
|
|
21152
|
+
log9.info(`Kill task ${task.id}: target ${targetTaskId} not found in timeline`);
|
|
20765
21153
|
}
|
|
20766
21154
|
activeTasks.delete(task.id);
|
|
20767
21155
|
return;
|
|
@@ -20781,17 +21169,17 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20781
21169
|
}
|
|
20782
21170
|
const provider = runtimeData.provider;
|
|
20783
21171
|
if (task.contextKey) {
|
|
20784
|
-
const agentBaseDir =
|
|
21172
|
+
const agentBaseDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir");
|
|
20785
21173
|
cleanupStaleIntents(agentBaseDir);
|
|
20786
|
-
const timelineDir =
|
|
21174
|
+
const timelineDir = join11(agentBaseDir, ".context_timeline");
|
|
20787
21175
|
const lockAcquired = acquireSteeringLock(agentBaseDir, task.contextKey);
|
|
20788
21176
|
if (!lockAcquired) {
|
|
20789
|
-
|
|
21177
|
+
log9.warn(`Steering lock contention for context_key=${task.contextKey}, proceeding without steering`);
|
|
20790
21178
|
} else {
|
|
20791
21179
|
try {
|
|
20792
21180
|
const predecessor = findRunningEntryByContextKey(timelineDir, task.contextKey, provider);
|
|
20793
21181
|
if (predecessor && predecessor.task_id !== task.id) {
|
|
20794
|
-
|
|
21182
|
+
log9.info(`Steering: task ${task.id} supersedes predecessor ${predecessor.task_id} (context_key=${task.contextKey})`);
|
|
20795
21183
|
if (predecessor.pid != null) {
|
|
20796
21184
|
writeKillIntent(agentBaseDir, {
|
|
20797
21185
|
reason: "superseded",
|
|
@@ -20801,12 +21189,12 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20801
21189
|
});
|
|
20802
21190
|
try {
|
|
20803
21191
|
process.kill(predecessor.pid, "SIGTERM");
|
|
20804
|
-
|
|
21192
|
+
log9.info(`Steering: sent SIGTERM to predecessor pid=${predecessor.pid}`);
|
|
20805
21193
|
} catch (e) {
|
|
20806
21194
|
if (e?.code === "ESRCH") {
|
|
20807
|
-
|
|
21195
|
+
log9.info(`Steering: predecessor pid=${predecessor.pid} already exited`);
|
|
20808
21196
|
} else {
|
|
20809
|
-
|
|
21197
|
+
log9.warn(`Steering: kill failed for pid=${predecessor.pid}`, e);
|
|
20810
21198
|
}
|
|
20811
21199
|
}
|
|
20812
21200
|
const waitStart = Date.now();
|
|
@@ -20819,14 +21207,14 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20819
21207
|
await new Promise((r) => setTimeout(r, POLL_MS));
|
|
20820
21208
|
}
|
|
20821
21209
|
if (findRunningPidByTaskId(timelineDir, predecessor.task_id) != null) {
|
|
20822
|
-
|
|
21210
|
+
log9.warn(`Steering: predecessor pid=${predecessor.pid} did not exit within ${MAX_WAIT_MS}ms, proceeding anyway`);
|
|
20823
21211
|
}
|
|
20824
21212
|
}
|
|
20825
21213
|
try {
|
|
20826
21214
|
await client.supersedeTask(token, predecessor.task_id);
|
|
20827
|
-
|
|
21215
|
+
log9.info(`Steering: predecessor ${predecessor.task_id} marked superseded`);
|
|
20828
21216
|
} catch (e) {
|
|
20829
|
-
|
|
21217
|
+
log9.warn(`Steering: failed to mark predecessor superseded server-side`, e);
|
|
20830
21218
|
}
|
|
20831
21219
|
}
|
|
20832
21220
|
} finally {
|
|
@@ -20854,8 +21242,8 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20854
21242
|
activeTasks.delete(task.id);
|
|
20855
21243
|
if (code !== 0) {
|
|
20856
21244
|
const msg = code === null ? `session-runner killed by signal (task ${task.id})` : `session-runner crashed (exit code ${code}, task ${task.id})`;
|
|
20857
|
-
|
|
20858
|
-
const timelineDir =
|
|
21245
|
+
log9.warn(msg);
|
|
21246
|
+
const timelineDir = join11(config2.workspacesRoot, task.workspaceId, task.agentId, "workdir", ".context_timeline");
|
|
20859
21247
|
updateEntry(timelineDir, task.id, (entry) => {
|
|
20860
21248
|
entry.pid = null;
|
|
20861
21249
|
entry.status = "failed";
|
|
@@ -20865,10 +21253,10 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20865
21253
|
await client.failTask(token, task.id, msg);
|
|
20866
21254
|
} catch (e) {
|
|
20867
21255
|
if (isClientError2(e)) {
|
|
20868
|
-
|
|
21256
|
+
log9.info(`Backstop: task ${task.id} already in terminal state`);
|
|
20869
21257
|
return;
|
|
20870
21258
|
}
|
|
20871
|
-
|
|
21259
|
+
log9.error(`Backstop: failed to report crash for task ${task.id}`, e);
|
|
20872
21260
|
try {
|
|
20873
21261
|
await writeMarkerFile(config2.workspacesRoot, {
|
|
20874
21262
|
taskId: task.id,
|
|
@@ -20882,7 +21270,7 @@ async function handleTask(client, config2, runtimeIndex, task, token, activeTask
|
|
|
20882
21270
|
}
|
|
20883
21271
|
}
|
|
20884
21272
|
});
|
|
20885
|
-
|
|
21273
|
+
log9.info(`Task ${task.id} dispatched to session-runner (pid=${child.pid})`);
|
|
20886
21274
|
}
|
|
20887
21275
|
|
|
20888
21276
|
// commands/daemon.ts
|
|
@@ -20920,7 +21308,7 @@ async function startInBackground(profile, serverUrl) {
|
|
|
20920
21308
|
return;
|
|
20921
21309
|
}
|
|
20922
21310
|
const logPath = daemonLogFilePath();
|
|
20923
|
-
|
|
21311
|
+
mkdirSync9(dirname4(logPath), { recursive: true, mode: 448 });
|
|
20924
21312
|
const logFd = openSync2(logPath, "a", 384);
|
|
20925
21313
|
const child = spawn6(process.execPath, buildChildArgs(profile, serverUrl), {
|
|
20926
21314
|
detached: true,
|
|
@@ -21041,8 +21429,8 @@ function configCommand() {
|
|
|
21041
21429
|
|
|
21042
21430
|
// commands/email.ts
|
|
21043
21431
|
import { Command as Command5 } from "commander";
|
|
21044
|
-
import { writeFileSync as
|
|
21045
|
-
import { basename, join as
|
|
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";
|
|
21046
21434
|
import PostalMime from "postal-mime";
|
|
21047
21435
|
|
|
21048
21436
|
// lib/flags.ts
|
|
@@ -21056,7 +21444,7 @@ function resolveAgentId(opts) {
|
|
|
21056
21444
|
}
|
|
21057
21445
|
|
|
21058
21446
|
// commands/email.ts
|
|
21059
|
-
var
|
|
21447
|
+
var log10 = createLogger2({ module: "email" });
|
|
21060
21448
|
var VALID_STATUSES = ["unread", "read", "archived", "sent"];
|
|
21061
21449
|
var VALID_FOLDERS = ["inbox", "sent", "untrust"];
|
|
21062
21450
|
var EMAIL_BASE = tempDir("alook-emails");
|
|
@@ -21153,7 +21541,7 @@ function emailCommand() {
|
|
|
21153
21541
|
process.exit(1);
|
|
21154
21542
|
}
|
|
21155
21543
|
}
|
|
21156
|
-
const emailDir_base =
|
|
21544
|
+
const emailDir_base = join12(EMAIL_BASE, workspaceId, agentId);
|
|
21157
21545
|
try {
|
|
21158
21546
|
let query = `/api/email?agentId=${agentId}`;
|
|
21159
21547
|
if (opts.status)
|
|
@@ -21173,11 +21561,11 @@ function emailCommand() {
|
|
|
21173
21561
|
printJSON(emails2);
|
|
21174
21562
|
return;
|
|
21175
21563
|
}
|
|
21176
|
-
|
|
21564
|
+
mkdirSync10(emailDir_base, { recursive: true });
|
|
21177
21565
|
const downloadedPaths = [];
|
|
21178
21566
|
for (const email3 of emails2) {
|
|
21179
|
-
const emailDir =
|
|
21180
|
-
|
|
21567
|
+
const emailDir = join12(emailDir_base, email3.id);
|
|
21568
|
+
mkdirSync10(emailDir, { recursive: true });
|
|
21181
21569
|
const metadata = {
|
|
21182
21570
|
id: email3.id,
|
|
21183
21571
|
from: email3.from_email,
|
|
@@ -21189,8 +21577,8 @@ function emailCommand() {
|
|
|
21189
21577
|
in_reply_to: email3.in_reply_to || "",
|
|
21190
21578
|
references: email3.references || ""
|
|
21191
21579
|
};
|
|
21192
|
-
const metadataPath =
|
|
21193
|
-
|
|
21580
|
+
const metadataPath = join12(emailDir, "metadata.json");
|
|
21581
|
+
writeFileSync8(metadataPath, JSON.stringify(metadata, null, 2));
|
|
21194
21582
|
downloadedPaths.push(metadataPath);
|
|
21195
21583
|
let rawMime;
|
|
21196
21584
|
try {
|
|
@@ -21198,25 +21586,25 @@ function emailCommand() {
|
|
|
21198
21586
|
} catch (err) {
|
|
21199
21587
|
const msg = err instanceof Error ? err.message : String(err);
|
|
21200
21588
|
if (msg.includes("404")) {
|
|
21201
|
-
|
|
21589
|
+
log10.warn(`email body not available for ${email3.id}, skipping`);
|
|
21202
21590
|
continue;
|
|
21203
21591
|
}
|
|
21204
21592
|
throw err;
|
|
21205
21593
|
}
|
|
21206
21594
|
const parsed = await new PostalMime().parse(rawMime);
|
|
21207
21595
|
if (parsed.text) {
|
|
21208
|
-
const bodyPath =
|
|
21209
|
-
|
|
21596
|
+
const bodyPath = join12(emailDir, "body.txt");
|
|
21597
|
+
writeFileSync8(bodyPath, parsed.text);
|
|
21210
21598
|
downloadedPaths.push(bodyPath);
|
|
21211
21599
|
}
|
|
21212
21600
|
if (parsed.html) {
|
|
21213
|
-
const htmlPath =
|
|
21214
|
-
|
|
21601
|
+
const htmlPath = join12(emailDir, "body.html");
|
|
21602
|
+
writeFileSync8(htmlPath, parsed.html);
|
|
21215
21603
|
downloadedPaths.push(htmlPath);
|
|
21216
21604
|
}
|
|
21217
21605
|
if (parsed.attachments && parsed.attachments.length > 0) {
|
|
21218
|
-
const attDir =
|
|
21219
|
-
|
|
21606
|
+
const attDir = join12(emailDir, "attachments");
|
|
21607
|
+
mkdirSync10(attDir, { recursive: true });
|
|
21220
21608
|
const usedFilenames = new Set;
|
|
21221
21609
|
for (let i = 0;i < parsed.attachments.length; i++) {
|
|
21222
21610
|
const att = parsed.attachments[i];
|
|
@@ -21225,7 +21613,7 @@ function emailCommand() {
|
|
|
21225
21613
|
filename = `${i}-${filename}`;
|
|
21226
21614
|
}
|
|
21227
21615
|
usedFilenames.add(filename);
|
|
21228
|
-
const attPath =
|
|
21616
|
+
const attPath = join12(attDir, filename);
|
|
21229
21617
|
const content = att.content;
|
|
21230
21618
|
let buf;
|
|
21231
21619
|
if (typeof content === "string") {
|
|
@@ -21235,7 +21623,7 @@ function emailCommand() {
|
|
|
21235
21623
|
} else {
|
|
21236
21624
|
buf = Buffer.from(content);
|
|
21237
21625
|
}
|
|
21238
|
-
|
|
21626
|
+
writeFileSync8(attPath, buf);
|
|
21239
21627
|
downloadedPaths.push(attPath);
|
|
21240
21628
|
}
|
|
21241
21629
|
}
|
|
@@ -21276,7 +21664,7 @@ function emailCommand() {
|
|
|
21276
21664
|
const client = new APIClient(serverUrl, token, workspaceId);
|
|
21277
21665
|
let htmlBody;
|
|
21278
21666
|
try {
|
|
21279
|
-
htmlBody =
|
|
21667
|
+
htmlBody = readFileSync9(opts.bodyFile, "utf-8");
|
|
21280
21668
|
} catch (err) {
|
|
21281
21669
|
console.error(`Error: cannot read body file "${opts.bodyFile}": ${err instanceof Error ? err.message : err}`);
|
|
21282
21670
|
process.exit(1);
|
|
@@ -21292,13 +21680,13 @@ function emailCommand() {
|
|
|
21292
21680
|
let bytes;
|
|
21293
21681
|
let size;
|
|
21294
21682
|
try {
|
|
21295
|
-
bytes =
|
|
21296
|
-
size =
|
|
21683
|
+
bytes = readFileSync9(path2);
|
|
21684
|
+
size = statSync5(path2).size;
|
|
21297
21685
|
} catch (err) {
|
|
21298
21686
|
console.error(`Error: cannot read attachment "${path2}": ${err instanceof Error ? err.message : err}`);
|
|
21299
21687
|
process.exit(1);
|
|
21300
21688
|
}
|
|
21301
|
-
const filename =
|
|
21689
|
+
const filename = basename2(path2);
|
|
21302
21690
|
const contentType = guessContentType(filename);
|
|
21303
21691
|
const form = new FormData;
|
|
21304
21692
|
form.append("file", new Blob([new Uint8Array(bytes)], { type: contentType }), filename);
|
|
@@ -21320,7 +21708,7 @@ function emailCommand() {
|
|
|
21320
21708
|
references = [parentEmail.references, parentEmail.message_id].filter(Boolean).join(" ").trim() || undefined;
|
|
21321
21709
|
}
|
|
21322
21710
|
} catch {
|
|
21323
|
-
|
|
21711
|
+
log10.warn(`could not fetch parent email ${opts.inReplyTo}, sending without threading`);
|
|
21324
21712
|
}
|
|
21325
21713
|
}
|
|
21326
21714
|
const conversationId = process.env.ALOOK_CONVERSATION_ID;
|
|
@@ -21405,13 +21793,13 @@ function emailCommand() {
|
|
|
21405
21793
|
let bytes;
|
|
21406
21794
|
let size;
|
|
21407
21795
|
try {
|
|
21408
|
-
bytes =
|
|
21409
|
-
size =
|
|
21796
|
+
bytes = readFileSync9(path2);
|
|
21797
|
+
size = statSync5(path2).size;
|
|
21410
21798
|
} catch (err) {
|
|
21411
21799
|
console.error(`Error: cannot read attachment "${path2}": ${err instanceof Error ? err.message : err}`);
|
|
21412
21800
|
process.exit(1);
|
|
21413
21801
|
}
|
|
21414
|
-
const filename =
|
|
21802
|
+
const filename = basename2(path2);
|
|
21415
21803
|
const contentType = guessContentType(filename);
|
|
21416
21804
|
const form = new FormData;
|
|
21417
21805
|
form.append("file", new Blob([new Uint8Array(bytes)], { type: contentType }), filename);
|
|
@@ -21752,7 +22140,7 @@ function calendarCommand() {
|
|
|
21752
22140
|
|
|
21753
22141
|
// commands/issue.ts
|
|
21754
22142
|
import { Command as Command7 } from "commander";
|
|
21755
|
-
import { readFileSync as
|
|
22143
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
21756
22144
|
var VALID_STATUSES2 = ["todo", "in_progress", "review", "done", "closed", "canceled", "failed"];
|
|
21757
22145
|
function resolveClientOpts3(command, agentId) {
|
|
21758
22146
|
let root = command;
|
|
@@ -21776,7 +22164,7 @@ function readBody(opts) {
|
|
|
21776
22164
|
process.exit(1);
|
|
21777
22165
|
}
|
|
21778
22166
|
if (opts.bodyFile)
|
|
21779
|
-
return
|
|
22167
|
+
return readFileSync10(opts.bodyFile, "utf-8");
|
|
21780
22168
|
return opts.body ?? "";
|
|
21781
22169
|
}
|
|
21782
22170
|
function printIssue(issue3) {
|
|
@@ -21974,8 +22362,8 @@ ${result.output}`);
|
|
|
21974
22362
|
|
|
21975
22363
|
// commands/sync.ts
|
|
21976
22364
|
import { Command as Command10 } from "commander";
|
|
21977
|
-
import { readFileSync as
|
|
21978
|
-
import { basename as
|
|
22365
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
22366
|
+
import { basename as basename3 } from "path";
|
|
21979
22367
|
var MIME_BY_EXT2 = {
|
|
21980
22368
|
".pdf": "application/pdf",
|
|
21981
22369
|
".png": "image/png",
|
|
@@ -22023,12 +22411,12 @@ function syncCommand() {
|
|
|
22023
22411
|
const client = new APIClient(serverUrl, token, workspaceId);
|
|
22024
22412
|
let bytes;
|
|
22025
22413
|
try {
|
|
22026
|
-
bytes =
|
|
22414
|
+
bytes = readFileSync11(opts.file);
|
|
22027
22415
|
} catch (err) {
|
|
22028
22416
|
console.error(`Error: cannot read file "${opts.file}": ${err.message}`);
|
|
22029
22417
|
process.exit(1);
|
|
22030
22418
|
}
|
|
22031
|
-
const filename =
|
|
22419
|
+
const filename = basename3(opts.file);
|
|
22032
22420
|
const contentType = guessContentType2(filename);
|
|
22033
22421
|
const form = new FormData;
|
|
22034
22422
|
form.append("file", new Blob([new Uint8Array(bytes)], { type: contentType }), filename);
|