opencode-supertask 0.1.0 → 0.1.2

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/cli/index.js CHANGED
@@ -4506,7 +4506,7 @@ var init_sql = __esm({
4506
4506
  return new SQL([new StringChunk(str)]);
4507
4507
  }
4508
4508
  sql2.raw = raw2;
4509
- function join3(chunks, separator) {
4509
+ function join4(chunks, separator) {
4510
4510
  const result = [];
4511
4511
  for (const [i, chunk] of chunks.entries()) {
4512
4512
  if (i > 0 && separator !== void 0) {
@@ -4516,7 +4516,7 @@ var init_sql = __esm({
4516
4516
  }
4517
4517
  return new SQL(result);
4518
4518
  }
4519
- sql2.join = join3;
4519
+ sql2.join = join4;
4520
4520
  function identifier(value) {
4521
4521
  return new Name(value);
4522
4522
  }
@@ -7132,7 +7132,7 @@ var init_select2 = __esm({
7132
7132
  return (table, on) => {
7133
7133
  const baseTableName = this.tableName;
7134
7134
  const tableName = getTableLikeName(table);
7135
- if (typeof tableName === "string" && this.config.joins?.some((join3) => join3.alias === tableName)) {
7135
+ if (typeof tableName === "string" && this.config.joins?.some((join4) => join4.alias === tableName)) {
7136
7136
  throw new Error(`Alias "${tableName}" is already used in this query`);
7137
7137
  }
7138
7138
  if (!this.isPartialSelect) {
@@ -7974,7 +7974,7 @@ var init_update = __esm({
7974
7974
  createJoin(joinType) {
7975
7975
  return (table, on) => {
7976
7976
  const tableName = getTableLikeName(table);
7977
- if (typeof tableName === "string" && this.config.joins.some((join3) => join3.alias === tableName)) {
7977
+ if (typeof tableName === "string" && this.config.joins.some((join4) => join4.alias === tableName)) {
7978
7978
  throw new Error(`Alias "${tableName}" is already used in this query`);
7979
7979
  }
7980
7980
  if (typeof on === "function") {
@@ -9236,6 +9236,59 @@ var init_bun_sqlite = __esm({
9236
9236
  }
9237
9237
  });
9238
9238
 
9239
+ // node_modules/drizzle-orm/migrator.js
9240
+ import crypto from "crypto";
9241
+ import fs from "fs";
9242
+ function readMigrationFiles(config) {
9243
+ const migrationFolderTo = config.migrationsFolder;
9244
+ const migrationQueries = [];
9245
+ const journalPath = `${migrationFolderTo}/meta/_journal.json`;
9246
+ if (!fs.existsSync(journalPath)) {
9247
+ throw new Error(`Can't find meta/_journal.json file`);
9248
+ }
9249
+ const journalAsString = fs.readFileSync(`${migrationFolderTo}/meta/_journal.json`).toString();
9250
+ const journal = JSON.parse(journalAsString);
9251
+ for (const journalEntry of journal.entries) {
9252
+ const migrationPath = `${migrationFolderTo}/${journalEntry.tag}.sql`;
9253
+ try {
9254
+ const query = fs.readFileSync(`${migrationFolderTo}/${journalEntry.tag}.sql`).toString();
9255
+ const result = query.split("--> statement-breakpoint").map((it) => {
9256
+ return it;
9257
+ });
9258
+ migrationQueries.push({
9259
+ sql: result,
9260
+ bps: journalEntry.breakpoints,
9261
+ folderMillis: journalEntry.when,
9262
+ hash: crypto.createHash("sha256").update(query).digest("hex")
9263
+ });
9264
+ } catch {
9265
+ throw new Error(`No file ${migrationPath} found in ${migrationFolderTo} folder`);
9266
+ }
9267
+ }
9268
+ return migrationQueries;
9269
+ }
9270
+ var init_migrator = __esm({
9271
+ "node_modules/drizzle-orm/migrator.js"() {
9272
+ "use strict";
9273
+ }
9274
+ });
9275
+
9276
+ // node_modules/drizzle-orm/bun-sqlite/migrator.js
9277
+ var migrator_exports = {};
9278
+ __export(migrator_exports, {
9279
+ migrate: () => migrate
9280
+ });
9281
+ function migrate(db2, config) {
9282
+ const migrations = readMigrationFiles(config);
9283
+ db2.dialect.migrate(migrations, db2.session, config);
9284
+ }
9285
+ var init_migrator2 = __esm({
9286
+ "node_modules/drizzle-orm/bun-sqlite/migrator.js"() {
9287
+ "use strict";
9288
+ init_migrator();
9289
+ }
9290
+ });
9291
+
9239
9292
  // src/core/db/schema.ts
9240
9293
  var schema_exports = {};
9241
9294
  __export(schema_exports, {
@@ -9344,8 +9397,14 @@ import { Database as Database2 } from "bun:sqlite";
9344
9397
  import { existsSync, mkdirSync } from "fs";
9345
9398
  import { homedir } from "os";
9346
9399
  import { join, dirname } from "path";
9400
+ import { fileURLToPath } from "url";
9401
+ function getMigrationsFolder() {
9402
+ const __dirname2 = dirname(fileURLToPath(import.meta.url));
9403
+ return join(__dirname2, "../../drizzle");
9404
+ }
9347
9405
  function initDb() {
9348
9406
  const dataDir = dirname(DB_FILE_PATH);
9407
+ const dbExisted = existsSync(DB_FILE_PATH);
9349
9408
  if (!existsSync(dataDir)) {
9350
9409
  mkdirSync(dataDir, { recursive: true });
9351
9410
  }
@@ -9361,6 +9420,14 @@ function initDb() {
9361
9420
  );
9362
9421
  `);
9363
9422
  _db = drizzle(_sqlite, { schema: schema_exports });
9423
+ if (!_migrationRan) {
9424
+ _migrationRan = true;
9425
+ try {
9426
+ migrate(_db, { migrationsFolder: getMigrationsFolder() });
9427
+ } catch (err) {
9428
+ console.error("[supertask] migration failed:", err instanceof Error ? err.message : String(err));
9429
+ }
9430
+ }
9364
9431
  return _db;
9365
9432
  }
9366
9433
  function getDb() {
@@ -9378,15 +9445,17 @@ function closeDb() {
9378
9445
  _db = null;
9379
9446
  }
9380
9447
  }
9381
- var DB_FILE_PATH, _sqlite, _db, db, sqlite;
9448
+ var DB_FILE_PATH, _sqlite, _db, _migrationRan, db, sqlite;
9382
9449
  var init_db2 = __esm({
9383
9450
  "src/core/db/index.ts"() {
9384
9451
  "use strict";
9385
9452
  init_bun_sqlite();
9453
+ init_migrator2();
9386
9454
  init_schema();
9387
9455
  DB_FILE_PATH = join(homedir(), ".local/share/opencode/tasks.db");
9388
9456
  _sqlite = null;
9389
9457
  _db = null;
9458
+ _migrationRan = false;
9390
9459
  db = new Proxy({}, {
9391
9460
  get(_, prop) {
9392
9461
  const target = getDb();
@@ -19047,59 +19116,6 @@ var init_config = __esm({
19047
19116
  }
19048
19117
  });
19049
19118
 
19050
- // node_modules/drizzle-orm/migrator.js
19051
- import crypto from "crypto";
19052
- import fs from "fs";
19053
- function readMigrationFiles(config) {
19054
- const migrationFolderTo = config.migrationsFolder;
19055
- const migrationQueries = [];
19056
- const journalPath = `${migrationFolderTo}/meta/_journal.json`;
19057
- if (!fs.existsSync(journalPath)) {
19058
- throw new Error(`Can't find meta/_journal.json file`);
19059
- }
19060
- const journalAsString = fs.readFileSync(`${migrationFolderTo}/meta/_journal.json`).toString();
19061
- const journal = JSON.parse(journalAsString);
19062
- for (const journalEntry of journal.entries) {
19063
- const migrationPath = `${migrationFolderTo}/${journalEntry.tag}.sql`;
19064
- try {
19065
- const query = fs.readFileSync(`${migrationFolderTo}/${journalEntry.tag}.sql`).toString();
19066
- const result = query.split("--> statement-breakpoint").map((it) => {
19067
- return it;
19068
- });
19069
- migrationQueries.push({
19070
- sql: result,
19071
- bps: journalEntry.breakpoints,
19072
- folderMillis: journalEntry.when,
19073
- hash: crypto.createHash("sha256").update(query).digest("hex")
19074
- });
19075
- } catch {
19076
- throw new Error(`No file ${migrationPath} found in ${migrationFolderTo} folder`);
19077
- }
19078
- }
19079
- return migrationQueries;
19080
- }
19081
- var init_migrator = __esm({
19082
- "node_modules/drizzle-orm/migrator.js"() {
19083
- "use strict";
19084
- }
19085
- });
19086
-
19087
- // node_modules/drizzle-orm/bun-sqlite/migrator.js
19088
- var migrator_exports = {};
19089
- __export(migrator_exports, {
19090
- migrate: () => migrate
19091
- });
19092
- function migrate(db2, config) {
19093
- const migrations = readMigrationFiles(config);
19094
- db2.dialect.migrate(migrations, db2.session, config);
19095
- }
19096
- var init_migrator2 = __esm({
19097
- "node_modules/drizzle-orm/bun-sqlite/migrator.js"() {
19098
- "use strict";
19099
- init_migrator();
19100
- }
19101
- });
19102
-
19103
19119
  // src/core/services/task-run.service.ts
19104
19120
  var taskRuns2, TaskRunService;
19105
19121
  var init_task_run_service = __esm({
@@ -22717,6 +22733,188 @@ var init_web = __esm({
22717
22733
  }
22718
22734
  });
22719
22735
 
22736
+ // src/daemon/pm2.ts
22737
+ var pm2_exports = {};
22738
+ __export(pm2_exports, {
22739
+ ensureGateway: () => ensureGateway,
22740
+ install: () => install,
22741
+ isGatewayRunning: () => isGatewayRunning,
22742
+ uninstall: () => uninstall
22743
+ });
22744
+ import { execSync, spawnSync } from "child_process";
22745
+ import { join as join3, dirname as dirname3 } from "path";
22746
+ import { fileURLToPath as fileURLToPath2 } from "url";
22747
+ function pm2Bin() {
22748
+ return process.platform === "win32" ? "pm2.cmd" : "pm2";
22749
+ }
22750
+ function isPm2Installed() {
22751
+ try {
22752
+ const cmd = process.platform === "win32" ? "where pm2" : "which pm2";
22753
+ execSync(cmd, { stdio: "pipe" });
22754
+ return true;
22755
+ } catch {
22756
+ return false;
22757
+ }
22758
+ }
22759
+ function installPm2() {
22760
+ console.log("[supertask] Installing pm2...");
22761
+ try {
22762
+ execSync("npm install -g pm2", { stdio: "inherit" });
22763
+ return true;
22764
+ } catch {
22765
+ try {
22766
+ execSync("bun install -g pm2", { stdio: "inherit" });
22767
+ return true;
22768
+ } catch {
22769
+ return false;
22770
+ }
22771
+ }
22772
+ }
22773
+ function pm2Exec(args) {
22774
+ const bin = pm2Bin();
22775
+ try {
22776
+ const result = spawnSync(bin, args, {
22777
+ stdio: ["pipe", "pipe", "pipe"],
22778
+ encoding: "utf-8",
22779
+ shell: process.platform === "win32"
22780
+ });
22781
+ const output = (result.stdout ?? "") + (result.stderr ?? "");
22782
+ return { ok: result.status === 0, output };
22783
+ } catch (err) {
22784
+ return { ok: false, output: err instanceof Error ? err.message : String(err) };
22785
+ }
22786
+ }
22787
+ function pm2JsonList() {
22788
+ const { ok, output } = pm2Exec(["jlist"]);
22789
+ if (!ok) return [];
22790
+ try {
22791
+ return JSON.parse(output);
22792
+ } catch {
22793
+ return [];
22794
+ }
22795
+ }
22796
+ function isGatewayRunning() {
22797
+ const list = pm2JsonList();
22798
+ const proc = list.find((p) => p.name === PROCESS_NAME);
22799
+ if (!proc) return false;
22800
+ return proc.pm2_env?.status === "online";
22801
+ }
22802
+ function install() {
22803
+ if (!isPm2Installed()) {
22804
+ if (!installPm2()) {
22805
+ console.error("[supertask] Failed to install pm2. Please install it manually: npm install -g pm2");
22806
+ process.exit(1);
22807
+ }
22808
+ }
22809
+ console.log("[supertask] pm2 ready");
22810
+ const list = pm2JsonList();
22811
+ const existing = list.find((p) => p.name === PROCESS_NAME);
22812
+ if (existing) {
22813
+ console.log("[supertask] Gateway process already registered, reloading...");
22814
+ const { ok } = pm2Exec(["reload", PROCESS_NAME]);
22815
+ if (!ok) {
22816
+ console.error("[supertask] pm2 reload failed, trying restart...");
22817
+ pm2Exec(["restart", PROCESS_NAME]);
22818
+ }
22819
+ } else {
22820
+ console.log("[supertask] Starting Gateway with pm2...");
22821
+ const bunPath = process.execPath;
22822
+ const { ok, output } = pm2Exec([
22823
+ "start",
22824
+ GATEWAY_ENTRY,
22825
+ "--name",
22826
+ PROCESS_NAME,
22827
+ "--interpreter",
22828
+ bunPath,
22829
+ "--restart-delay",
22830
+ "5000",
22831
+ "--max-restarts",
22832
+ "30"
22833
+ ]);
22834
+ if (!ok) {
22835
+ console.error("[supertask] pm2 start failed:", output);
22836
+ process.exit(1);
22837
+ }
22838
+ }
22839
+ pm2Exec(["save"]);
22840
+ console.log("[supertask] Configuring startup...");
22841
+ const { ok: startupOk, output: startupOutput } = pm2Exec(["startup"]);
22842
+ if (!startupOk) {
22843
+ if (startupOutput.includes("sudo") || startupOutput.includes("run as root")) {
22844
+ console.log("[supertask] pm2 startup requires elevated permissions.");
22845
+ console.log("[supertask] Run the command shown above, or manually execute:");
22846
+ console.log(` pm2 startup`);
22847
+ console.log(` pm2 save`);
22848
+ } else if (process.platform === "win32") {
22849
+ console.log("[supertask] On Windows, use pm2-installer for startup:");
22850
+ console.log(" npm install -g pm2-windows-startup");
22851
+ console.log(" pm2-startup install");
22852
+ }
22853
+ }
22854
+ console.log("\n[supertask] Gateway installed and running!");
22855
+ console.log("[supertask] Manage with: pm2 status / pm2 logs supertask-gateway");
22856
+ }
22857
+ function uninstall() {
22858
+ console.log("[supertask] Stopping Gateway...");
22859
+ pm2Exec(["stop", PROCESS_NAME]);
22860
+ console.log("[supertask] Removing Gateway from pm2...");
22861
+ pm2Exec(["delete", PROCESS_NAME]);
22862
+ pm2Exec(["save"]);
22863
+ console.log("\n[supertask] Gateway removed from pm2.");
22864
+ console.log("[supertask] Note: pm2 startup config was not removed (you may have other pm2 processes).");
22865
+ console.log("[supertask] To fully remove pm2 startup: pm2 unstartup");
22866
+ }
22867
+ function ensureGateway() {
22868
+ try {
22869
+ const list2 = pm2JsonList();
22870
+ const proc = list2.find((p) => p.name === PROCESS_NAME);
22871
+ if (proc && proc.pm2_env?.status === "online") {
22872
+ return;
22873
+ }
22874
+ } catch {
22875
+ }
22876
+ if (!isPm2Installed()) {
22877
+ try {
22878
+ execSync("npm install -g pm2", { stdio: "pipe" });
22879
+ } catch {
22880
+ try {
22881
+ execSync("bun install -g pm2", { stdio: "pipe" });
22882
+ } catch {
22883
+ return;
22884
+ }
22885
+ }
22886
+ }
22887
+ const list = pm2JsonList();
22888
+ const existing = list.find((p) => p.name === PROCESS_NAME);
22889
+ if (existing) {
22890
+ pm2Exec(["restart", PROCESS_NAME]);
22891
+ } else {
22892
+ const bunPath = process.execPath;
22893
+ pm2Exec([
22894
+ "start",
22895
+ GATEWAY_ENTRY,
22896
+ "--name",
22897
+ PROCESS_NAME,
22898
+ "--interpreter",
22899
+ bunPath,
22900
+ "--restart-delay",
22901
+ "5000",
22902
+ "--max-restarts",
22903
+ "30"
22904
+ ]);
22905
+ }
22906
+ pm2Exec(["save"]);
22907
+ }
22908
+ var __dirname, GATEWAY_ENTRY, PROCESS_NAME;
22909
+ var init_pm2 = __esm({
22910
+ "src/daemon/pm2.ts"() {
22911
+ "use strict";
22912
+ __dirname = dirname3(fileURLToPath2(import.meta.url));
22913
+ GATEWAY_ENTRY = join3(__dirname, "../gateway/index.js");
22914
+ PROCESS_NAME = "supertask-gateway";
22915
+ }
22916
+ });
22917
+
22720
22918
  // node_modules/commander/esm.mjs
22721
22919
  var import_index = __toESM(require_commander(), 1);
22722
22920
  var {
@@ -22923,10 +23121,10 @@ program2.command("template").description("\u7BA1\u7406\u4EFB\u52A1\u8C03\u5EA6\u
22923
23121
  program2.command("init").description("Initialize SuperTask (create config + run migrations)").action(async () => withDb(async () => {
22924
23122
  const { existsSync: existsSync4, mkdirSync: mkdirSync3, writeFileSync: writeFileSync2 } = await import("fs");
22925
23123
  const { homedir: homedir3 } = await import("os");
22926
- const { join: join3, dirname: dirname3 } = await import("path");
23124
+ const { join: join4, dirname: dirname4 } = await import("path");
22927
23125
  const { CONFIG_PATH: CONFIG_PATH2 } = await Promise.resolve().then(() => (init_config(), config_exports));
22928
23126
  if (!existsSync4(CONFIG_PATH2)) {
22929
- const dir = dirname3(CONFIG_PATH2);
23127
+ const dir = dirname4(CONFIG_PATH2);
22930
23128
  if (!existsSync4(dir)) mkdirSync3(dir, { recursive: true });
22931
23129
  writeFileSync2(CONFIG_PATH2, JSON.stringify({
22932
23130
  worker: { maxConcurrency: 2, defaultModel: "zhipuai-coding-plan/glm-4.7" },
@@ -22939,18 +23137,18 @@ program2.command("init").description("Initialize SuperTask (create config + run
22939
23137
  const { getDb: getDb2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
22940
23138
  const { migrate: migrate2 } = await Promise.resolve().then(() => (init_migrator2(), migrator_exports));
22941
23139
  const { join: pJoin, dirname: pDirname } = await import("path");
22942
- const { fileURLToPath } = await import("url");
22943
- const __dirname = pDirname(fileURLToPath(import.meta.url));
22944
- migrate2(getDb2(), { migrationsFolder: pJoin(__dirname, "../../drizzle") });
23140
+ const { fileURLToPath: fileURLToPath3 } = await import("url");
23141
+ const __dirname2 = pDirname(fileURLToPath3(import.meta.url));
23142
+ migrate2(getDb2(), { migrationsFolder: pJoin(__dirname2, "../../drizzle") });
22945
23143
  console.log(JSON.stringify({ migrated: true }));
22946
23144
  }));
22947
23145
  program2.command("migrate").description("Run database migrations").action(async () => withDb(async () => {
22948
23146
  const { getDb: getDb2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
22949
23147
  const { migrate: migrate2 } = await Promise.resolve().then(() => (init_migrator2(), migrator_exports));
22950
- const { join: join3, dirname: dirname3 } = await import("path");
22951
- const { fileURLToPath } = await import("url");
22952
- const __dirname = dirname3(fileURLToPath(import.meta.url));
22953
- migrate2(getDb2(), { migrationsFolder: join3(__dirname, "../../drizzle") });
23148
+ const { join: join4, dirname: dirname4 } = await import("path");
23149
+ const { fileURLToPath: fileURLToPath3 } = await import("url");
23150
+ const __dirname2 = dirname4(fileURLToPath3(import.meta.url));
23151
+ migrate2(getDb2(), { migrationsFolder: join4(__dirname2, "../../drizzle") });
22954
23152
  console.log(JSON.stringify({ migrated: true }));
22955
23153
  }));
22956
23154
  program2.command("gateway").description("Start the Gateway process (foreground)").action(async () => {
@@ -22965,5 +23163,13 @@ program2.command("config").description("Show current configuration").action(asyn
22965
23163
  const cfg = loadConfig2();
22966
23164
  console.log(JSON.stringify(cfg, null, 2));
22967
23165
  });
23166
+ program2.command("install").description("Install Gateway as pm2 service (auto-start on boot, crash recovery)").action(async () => {
23167
+ const { install: pm2Install } = await Promise.resolve().then(() => (init_pm2(), pm2_exports));
23168
+ pm2Install();
23169
+ });
23170
+ program2.command("uninstall").description("Stop and remove Gateway pm2 service").action(async () => {
23171
+ const { uninstall: pm2Uninstall } = await Promise.resolve().then(() => (init_pm2(), pm2_exports));
23172
+ pm2Uninstall();
23173
+ });
22968
23174
  program2.parse();
22969
23175
  //# sourceMappingURL=index.js.map