@rubytech/taskmaster 1.0.13 → 1.0.15

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.
@@ -6,8 +6,8 @@
6
6
  <title>Taskmaster Control</title>
7
7
  <meta name="color-scheme" content="dark light" />
8
8
  <link rel="icon" type="image/png" href="./favicon.png" />
9
- <script type="module" crossorigin src="./assets/index-D8ayJUWC.js"></script>
10
- <link rel="stylesheet" crossorigin href="./assets/index-dMMqL7A5.css">
9
+ <script type="module" crossorigin src="./assets/index-J5yAenad.js"></script>
10
+ <link rel="stylesheet" crossorigin href="./assets/index-CJPjbUly.css">
11
11
  </head>
12
12
  <body>
13
13
  <taskmaster-app></taskmaster-app>
@@ -1,7 +1,7 @@
1
1
  import { loadConfig } from "../../config/config.js";
2
2
  import { resolveTaskmasterPackageRoot } from "../../infra/taskmaster-root.js";
3
3
  import { scheduleGatewaySigusr1Restart } from "../../infra/restart.js";
4
- import { formatDoctorNonInteractiveHint, writeRestartSentinel, } from "../../infra/restart-sentinel.js";
4
+ import { formatDoctorNonInteractiveHint, readRestartSentinel, writeRestartSentinel, } from "../../infra/restart-sentinel.js";
5
5
  import { checkUpdateStatus, compareSemverStrings } from "../../infra/update-check.js";
6
6
  import { normalizeUpdateChannel, resolveEffectiveUpdateChannel, } from "../../infra/update-channels.js";
7
7
  import { runGatewayUpdate } from "../../infra/update-runner.js";
@@ -70,7 +70,37 @@ export const updateHandlers = {
70
70
  }, undefined);
71
71
  }
72
72
  },
73
- "update.run": async ({ params, respond }) => {
73
+ "update.lastResult": async ({ respond }) => {
74
+ try {
75
+ const sentinel = await readRestartSentinel();
76
+ if (!sentinel || sentinel.payload.kind !== "update") {
77
+ respond(true, { ok: true, result: null }, undefined);
78
+ return;
79
+ }
80
+ const p = sentinel.payload;
81
+ const failedStep = p.stats?.steps?.find((s) => s.log?.exitCode != null && s.log.exitCode !== 0);
82
+ respond(true, {
83
+ ok: true,
84
+ result: {
85
+ status: p.status,
86
+ ts: p.ts,
87
+ mode: p.stats?.mode ?? null,
88
+ before: p.stats?.before ?? null,
89
+ after: p.stats?.after ?? null,
90
+ reason: p.stats?.reason ?? null,
91
+ durationMs: p.stats?.durationMs ?? null,
92
+ failedStep: failedStep
93
+ ? { name: failedStep.name, exitCode: failedStep.log?.exitCode ?? null }
94
+ : null,
95
+ currentVersion: VERSION,
96
+ },
97
+ }, undefined);
98
+ }
99
+ catch {
100
+ respond(true, { ok: true, result: null }, undefined);
101
+ }
102
+ },
103
+ "update.run": async ({ params, respond, context }) => {
74
104
  if (!validateUpdateRunParams(params)) {
75
105
  respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid update.run params: ${formatValidationErrors(validateUpdateRunParams.errors)}`));
76
106
  return;
@@ -89,6 +119,26 @@ export const updateHandlers = {
89
119
  const timeoutMs = typeof timeoutMsRaw === "number" && Number.isFinite(timeoutMsRaw)
90
120
  ? Math.max(1000, Math.floor(timeoutMsRaw))
91
121
  : undefined;
122
+ const progress = {
123
+ onStepStart: (step) => {
124
+ context.broadcast("update.progress", {
125
+ phase: "step-start",
126
+ name: step.name,
127
+ index: step.index,
128
+ total: step.total,
129
+ });
130
+ },
131
+ onStepComplete: (step) => {
132
+ context.broadcast("update.progress", {
133
+ phase: "step-done",
134
+ name: step.name,
135
+ index: step.index,
136
+ total: step.total,
137
+ durationMs: step.durationMs,
138
+ ok: step.exitCode === 0 || step.exitCode === null,
139
+ });
140
+ },
141
+ };
92
142
  let result;
93
143
  try {
94
144
  const root = (await resolveTaskmasterPackageRoot({
@@ -100,6 +150,7 @@ export const updateHandlers = {
100
150
  timeoutMs,
101
151
  cwd: root,
102
152
  argv1: process.argv[1],
153
+ progress,
103
154
  });
104
155
  }
105
156
  catch (err) {
@@ -145,6 +196,11 @@ export const updateHandlers = {
145
196
  catch {
146
197
  sentinelPath = null;
147
198
  }
199
+ context.broadcast("update.progress", {
200
+ phase: "complete",
201
+ status: result.status,
202
+ reason: result.reason ?? null,
203
+ });
148
204
  const restart = scheduleGatewaySigusr1Restart({
149
205
  delayMs: restartDelayMs,
150
206
  reason: "update.run",
@@ -3,7 +3,7 @@ import { normalizeControlUiBasePath } from "./control-ui-shared.js";
3
3
  import { resolveHooksConfig } from "./hooks.js";
4
4
  import { isLoopbackHost, resolveGatewayBindHost } from "./net.js";
5
5
  export async function resolveGatewayRuntimeConfig(params) {
6
- const bindMode = params.bind ?? params.cfg.gateway?.bind ?? "loopback";
6
+ const bindMode = params.bind ?? params.cfg.gateway?.bind ?? "lan";
7
7
  const customBindHost = params.cfg.gateway?.customBindHost;
8
8
  const bindHost = params.host ?? (await resolveGatewayBindHost(bindMode, customBindHost));
9
9
  const controlUiEnabled = params.controlUiEnabled ?? params.cfg.gateway?.controlUi?.enabled ?? true;
@@ -224,7 +224,7 @@ timeoutMs = 10_000) {
224
224
  }
225
225
  export async function startGatewayServer(port, opts) {
226
226
  const mod = await serverModulePromise;
227
- return await mod.startGatewayServer(port, opts);
227
+ return await mod.startGatewayServer(port, { bind: "loopback", ...opts });
228
228
  }
229
229
  export async function startServerWithClient(token, opts) {
230
230
  let port = await getFreePort();
@@ -55,10 +55,7 @@ async function main() {
55
55
  defaultRuntime.error(`Invalid --port (${portRaw})`);
56
56
  process.exit(1);
57
57
  }
58
- const bindRaw = argValue(args, "--bind") ??
59
- process.env.TASKMASTER_GATEWAY_BIND ??
60
- cfg.gateway?.bind ??
61
- "loopback";
58
+ const bindRaw = argValue(args, "--bind") ?? process.env.TASKMASTER_GATEWAY_BIND ?? cfg.gateway?.bind ?? "lan";
62
59
  const bind = bindRaw === "loopback" ||
63
60
  bindRaw === "lan" ||
64
61
  bindRaw === "auto" ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/taskmaster",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "AI-powered business assistant for small businesses",
5
5
  "publishConfig": {
6
6
  "access": "public"