@nextclaw/service 0.3.4 → 0.3.6
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/controllers/commands/project/project-command.controller.d.ts +22 -0
- package/dist/controllers/commands/project/project-command.controller.d.ts.map +1 -0
- package/dist/controllers/commands/project/project-command.controller.js +63 -0
- package/dist/controllers/commands/project/project-command.controller.js.map +1 -0
- package/dist/controllers/commands/session/session-command.controller.d.ts +17 -0
- package/dist/controllers/commands/session/session-command.controller.d.ts.map +1 -0
- package/dist/controllers/commands/session/session-command.controller.js +29 -0
- package/dist/controllers/commands/session/session-command.controller.js.map +1 -0
- package/dist/managers/service-command.manager.d.ts +4 -0
- package/dist/managers/service-command.manager.d.ts.map +1 -1
- package/dist/managers/service-command.manager.js +11 -3
- package/dist/managers/service-command.manager.js.map +1 -1
- package/dist/managers/service-restart.manager.d.ts.map +1 -1
- package/dist/managers/service-restart.manager.js +4 -5
- package/dist/managers/service-restart.manager.js.map +1 -1
- package/dist/services/runtime/npm-runtime-update-host.service.d.ts.map +1 -1
- package/dist/services/runtime/npm-runtime-update-host.service.js +38 -34
- package/dist/services/runtime/npm-runtime-update-host.service.js.map +1 -1
- package/dist/types/distribution.types.d.ts +1 -1
- package/dist/types/distribution.types.d.ts.map +1 -1
- package/package.json +26 -26
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NextclawKernel } from "@nextclaw/kernel";
|
|
2
|
+
|
|
3
|
+
//#region src/controllers/commands/project/project-command.controller.d.ts
|
|
4
|
+
type ProjectCommandOptions = {
|
|
5
|
+
json?: boolean;
|
|
6
|
+
};
|
|
7
|
+
type ProjectCreateCommandOptions = ProjectCommandOptions & {
|
|
8
|
+
path?: string;
|
|
9
|
+
template?: "empty" | "knowledge-base";
|
|
10
|
+
};
|
|
11
|
+
declare class ProjectCommands {
|
|
12
|
+
private readonly createKernel;
|
|
13
|
+
constructor(createKernel: () => NextclawKernel);
|
|
14
|
+
list: (options?: ProjectCommandOptions) => Promise<void>;
|
|
15
|
+
templates: (options?: ProjectCommandOptions) => Promise<void>;
|
|
16
|
+
create: (name: string, options?: ProjectCreateCommandOptions) => Promise<void>;
|
|
17
|
+
private printCreatedProject;
|
|
18
|
+
private withKernel;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { ProjectCommandOptions, ProjectCommands, ProjectCreateCommandOptions };
|
|
22
|
+
//# sourceMappingURL=project-command.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-command.controller.d.ts","names":[],"sources":["../../../../src/controllers/commands/project/project-command.controller.ts"],"mappings":";;;KAMY,qBAAA;EACV,IAAA;AAAA;AAAA,KAGU,2BAAA,GAA8B,qBAAA;EACxC,IAAA;EACA,QAAA;AAAA;AAAA,cAGW,eAAA;EAAA,iBACkB,YAAA;cAAA,YAAA,QAAoB,cAAA;EAEjD,IAAA,GAAc,OAAA,GAAS,qBAAA,KAA6B,OAAA;EAiBpD,SAAA,GAAmB,OAAA,GAAS,qBAAA,KAA6B,OAAA;EAazD,MAAA,GACE,IAAA,UACA,OAAA,GAAS,2BAAA,KACR,OAAA;EAAA,QAYK,mBAAA;EAAA,QAQA,UAAA;AAAA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/controllers/commands/project/project-command.controller.ts
|
|
2
|
+
var ProjectCommands = class {
|
|
3
|
+
constructor(createKernel) {
|
|
4
|
+
this.createKernel = createKernel;
|
|
5
|
+
}
|
|
6
|
+
list = async (options = {}) => {
|
|
7
|
+
await this.withKernel(async (kernel) => {
|
|
8
|
+
const projects = await kernel.projectManager.listProjects();
|
|
9
|
+
if (options.json) {
|
|
10
|
+
console.log(JSON.stringify({
|
|
11
|
+
projects,
|
|
12
|
+
total: projects.length
|
|
13
|
+
}, null, 2));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (projects.length === 0) {
|
|
17
|
+
console.log("No projects registered.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
for (const project of projects) console.log(`${project.name}\t${project.template ?? "existing"}\t${project.rootPath}`);
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
templates = async (options = {}) => {
|
|
24
|
+
await this.withKernel(async (kernel) => {
|
|
25
|
+
const templates = kernel.projectManager.listTemplates();
|
|
26
|
+
if (options.json) {
|
|
27
|
+
console.log(JSON.stringify({ templates }, null, 2));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const template of templates) console.log(`${template.id}\t${template.description}`);
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
create = async (name, options = {}) => {
|
|
34
|
+
await this.withKernel(async (kernel) => {
|
|
35
|
+
const input = {
|
|
36
|
+
name,
|
|
37
|
+
...options.path ? { rootPath: options.path } : {},
|
|
38
|
+
...options.template ? { template: options.template } : {}
|
|
39
|
+
};
|
|
40
|
+
const project = await kernel.projectManager.createProject(input);
|
|
41
|
+
this.printCreatedProject(project, Boolean(options.json));
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
printCreatedProject = (project, json) => {
|
|
45
|
+
if (json) {
|
|
46
|
+
console.log(JSON.stringify(project, null, 2));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
console.log(`Created project "${project.name}" at ${project.rootPath}`);
|
|
50
|
+
};
|
|
51
|
+
withKernel = async (action) => {
|
|
52
|
+
const kernel = this.createKernel();
|
|
53
|
+
try {
|
|
54
|
+
return await action(kernel);
|
|
55
|
+
} finally {
|
|
56
|
+
await kernel.dispose();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { ProjectCommands };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=project-command.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-command.controller.js","names":[],"sources":["../../../../src/controllers/commands/project/project-command.controller.ts"],"sourcesContent":["import type {\n CreateProjectInput,\n NextclawKernel,\n ProjectRecord,\n} from \"@nextclaw/kernel\";\n\nexport type ProjectCommandOptions = {\n json?: boolean;\n};\n\nexport type ProjectCreateCommandOptions = ProjectCommandOptions & {\n path?: string;\n template?: \"empty\" | \"knowledge-base\";\n};\n\nexport class ProjectCommands {\n constructor(private readonly createKernel: () => NextclawKernel) {}\n\n list = async (options: ProjectCommandOptions = {}): Promise<void> => {\n await this.withKernel(async (kernel) => {\n const projects = await kernel.projectManager.listProjects();\n if (options.json) {\n console.log(JSON.stringify({ projects, total: projects.length }, null, 2));\n return;\n }\n if (projects.length === 0) {\n console.log(\"No projects registered.\");\n return;\n }\n for (const project of projects) {\n console.log(`${project.name}\\t${project.template ?? \"existing\"}\\t${project.rootPath}`);\n }\n });\n };\n\n templates = async (options: ProjectCommandOptions = {}): Promise<void> => {\n await this.withKernel(async (kernel) => {\n const templates = kernel.projectManager.listTemplates();\n if (options.json) {\n console.log(JSON.stringify({ templates }, null, 2));\n return;\n }\n for (const template of templates) {\n console.log(`${template.id}\\t${template.description}`);\n }\n });\n };\n\n create = async (\n name: string,\n options: ProjectCreateCommandOptions = {},\n ): Promise<void> => {\n await this.withKernel(async (kernel) => {\n const input: CreateProjectInput = {\n name,\n ...(options.path ? { rootPath: options.path } : {}),\n ...(options.template ? { template: options.template } : {}),\n };\n const project = await kernel.projectManager.createProject(input);\n this.printCreatedProject(project, Boolean(options.json));\n });\n };\n\n private printCreatedProject = (project: ProjectRecord, json: boolean): void => {\n if (json) {\n console.log(JSON.stringify(project, null, 2));\n return;\n }\n console.log(`Created project \"${project.name}\" at ${project.rootPath}`);\n };\n\n private withKernel = async <T>(action: (kernel: NextclawKernel) => Promise<T>): Promise<T> => {\n const kernel = this.createKernel();\n try {\n return await action(kernel);\n } finally {\n await kernel.dispose();\n }\n };\n}\n"],"mappings":";AAeA,IAAa,kBAAb,MAA6B;CAC3B,YAAY,cAAqD;AAApC,OAAA,eAAA;;CAE7B,OAAO,OAAO,UAAiC,EAAE,KAAoB;AACnE,QAAM,KAAK,WAAW,OAAO,WAAW;GACtC,MAAM,WAAW,MAAM,OAAO,eAAe,cAAc;AAC3D,OAAI,QAAQ,MAAM;AAChB,YAAQ,IAAI,KAAK,UAAU;KAAE;KAAU,OAAO,SAAS;KAAQ,EAAE,MAAM,EAAE,CAAC;AAC1E;;AAEF,OAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,IAAI,0BAA0B;AACtC;;AAEF,QAAK,MAAM,WAAW,SACpB,SAAQ,IAAI,GAAG,QAAQ,KAAK,IAAI,QAAQ,YAAY,WAAW,IAAI,QAAQ,WAAW;IAExF;;CAGJ,YAAY,OAAO,UAAiC,EAAE,KAAoB;AACxE,QAAM,KAAK,WAAW,OAAO,WAAW;GACtC,MAAM,YAAY,OAAO,eAAe,eAAe;AACvD,OAAI,QAAQ,MAAM;AAChB,YAAQ,IAAI,KAAK,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AACnD;;AAEF,QAAK,MAAM,YAAY,UACrB,SAAQ,IAAI,GAAG,SAAS,GAAG,IAAI,SAAS,cAAc;IAExD;;CAGJ,SAAS,OACP,MACA,UAAuC,EAAE,KACvB;AAClB,QAAM,KAAK,WAAW,OAAO,WAAW;GACtC,MAAM,QAA4B;IAChC;IACA,GAAI,QAAQ,OAAO,EAAE,UAAU,QAAQ,MAAM,GAAG,EAAE;IAClD,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,UAAU,GAAG,EAAE;IAC3D;GACD,MAAM,UAAU,MAAM,OAAO,eAAe,cAAc,MAAM;AAChE,QAAK,oBAAoB,SAAS,QAAQ,QAAQ,KAAK,CAAC;IACxD;;CAGJ,uBAA+B,SAAwB,SAAwB;AAC7E,MAAI,MAAM;AACR,WAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AAC7C;;AAEF,UAAQ,IAAI,oBAAoB,QAAQ,KAAK,OAAO,QAAQ,WAAW;;CAGzE,aAAqB,OAAU,WAA+D;EAC5F,MAAM,SAAS,KAAK,cAAc;AAClC,MAAI;AACF,UAAO,MAAM,OAAO,OAAO;YACnB;AACR,SAAM,OAAO,SAAS"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NextclawKernel } from "@nextclaw/kernel";
|
|
2
|
+
|
|
3
|
+
//#region src/controllers/commands/session/session-command.controller.d.ts
|
|
4
|
+
type SessionCommandOptions = {
|
|
5
|
+
json?: boolean;
|
|
6
|
+
};
|
|
7
|
+
declare class SessionCommands {
|
|
8
|
+
private readonly createKernel;
|
|
9
|
+
constructor(createKernel: () => NextclawKernel);
|
|
10
|
+
rename: (sessionId: string, label: string, options?: SessionCommandOptions) => Promise<void>;
|
|
11
|
+
setProject: (sessionId: string, projectRoot: string, options?: SessionCommandOptions) => Promise<void>;
|
|
12
|
+
clearProject: (sessionId: string, options?: SessionCommandOptions) => Promise<void>;
|
|
13
|
+
private update;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { SessionCommandOptions, SessionCommands };
|
|
17
|
+
//# sourceMappingURL=session-command.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-command.controller.d.ts","names":[],"sources":["../../../../src/controllers/commands/session/session-command.controller.ts"],"mappings":";;;KAEY,qBAAA;EACV,IAAA;AAAA;AAAA,cAGW,eAAA;EAAA,iBACkB,YAAA;cAAA,YAAA,QAAoB,cAAA;EAEjD,MAAA,GACE,SAAA,UACA,KAAA,UACA,OAAA,GAAS,qBAAA,KACR,OAAA;EAIH,UAAA,GACE,SAAA,UACA,WAAA,UACA,OAAA,GAAS,qBAAA,KACR,OAAA;EAIH,YAAA,GACE,SAAA,UACA,OAAA,GAAS,qBAAA,KACR,OAAA;EAAA,QAIK,MAAA;AAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/controllers/commands/session/session-command.controller.ts
|
|
2
|
+
var SessionCommands = class {
|
|
3
|
+
constructor(createKernel) {
|
|
4
|
+
this.createKernel = createKernel;
|
|
5
|
+
}
|
|
6
|
+
rename = async (sessionId, label, options = {}) => {
|
|
7
|
+
await this.update(sessionId, { label }, options);
|
|
8
|
+
};
|
|
9
|
+
setProject = async (sessionId, projectRoot, options = {}) => {
|
|
10
|
+
await this.update(sessionId, { projectRoot }, options);
|
|
11
|
+
};
|
|
12
|
+
clearProject = async (sessionId, options = {}) => {
|
|
13
|
+
await this.update(sessionId, { projectRoot: null }, options);
|
|
14
|
+
};
|
|
15
|
+
update = async (sessionId, patch, options) => {
|
|
16
|
+
const kernel = this.createKernel();
|
|
17
|
+
try {
|
|
18
|
+
const session = await kernel.sessionManager.patchSessionSettings(sessionId, patch);
|
|
19
|
+
if (!session) throw new Error(`Session not found: ${sessionId}`);
|
|
20
|
+
console.log(options.json ? JSON.stringify(session, null, 2) : `Updated session ${session.sessionId}`);
|
|
21
|
+
} finally {
|
|
22
|
+
await kernel.dispose();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { SessionCommands };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=session-command.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-command.controller.js","names":[],"sources":["../../../../src/controllers/commands/session/session-command.controller.ts"],"sourcesContent":["import type { NextclawKernel } from \"@nextclaw/kernel\";\n\nexport type SessionCommandOptions = {\n json?: boolean;\n};\n\nexport class SessionCommands {\n constructor(private readonly createKernel: () => NextclawKernel) {}\n\n rename = async (\n sessionId: string,\n label: string,\n options: SessionCommandOptions = {},\n ): Promise<void> => {\n await this.update(sessionId, { label }, options);\n };\n\n setProject = async (\n sessionId: string,\n projectRoot: string,\n options: SessionCommandOptions = {},\n ): Promise<void> => {\n await this.update(sessionId, { projectRoot }, options);\n };\n\n clearProject = async (\n sessionId: string,\n options: SessionCommandOptions = {},\n ): Promise<void> => {\n await this.update(sessionId, { projectRoot: null }, options);\n };\n\n private update = async (\n sessionId: string,\n patch: { label?: string; projectRoot?: string | null },\n options: SessionCommandOptions,\n ): Promise<void> => {\n const kernel = this.createKernel();\n try {\n const session = await kernel.sessionManager.patchSessionSettings(sessionId, patch);\n if (!session) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n console.log(options.json\n ? JSON.stringify(session, null, 2)\n : `Updated session ${session.sessionId}`);\n } finally {\n await kernel.dispose();\n }\n };\n}\n"],"mappings":";AAMA,IAAa,kBAAb,MAA6B;CAC3B,YAAY,cAAqD;AAApC,OAAA,eAAA;;CAE7B,SAAS,OACP,WACA,OACA,UAAiC,EAAE,KACjB;AAClB,QAAM,KAAK,OAAO,WAAW,EAAE,OAAO,EAAE,QAAQ;;CAGlD,aAAa,OACX,WACA,aACA,UAAiC,EAAE,KACjB;AAClB,QAAM,KAAK,OAAO,WAAW,EAAE,aAAa,EAAE,QAAQ;;CAGxD,eAAe,OACb,WACA,UAAiC,EAAE,KACjB;AAClB,QAAM,KAAK,OAAO,WAAW,EAAE,aAAa,MAAM,EAAE,QAAQ;;CAG9D,SAAiB,OACf,WACA,OACA,YACkB;EAClB,MAAM,SAAS,KAAK,cAAc;AAClC,MAAI;GACF,MAAM,UAAU,MAAM,OAAO,eAAe,qBAAqB,WAAW,MAAM;AAClF,OAAI,CAAC,QACH,OAAM,IAAI,MAAM,sBAAsB,YAAY;AAEpD,WAAQ,IAAI,QAAQ,OAChB,KAAK,UAAU,SAAS,MAAM,EAAE,GAChC,mBAAmB,QAAQ,YAAY;YACnC;AACR,SAAM,OAAO,SAAS"}
|
|
@@ -19,6 +19,8 @@ import { ServiceCommands } from "../controllers/commands/service-command.control
|
|
|
19
19
|
import { StopCommands } from "../controllers/commands/stop-command.controller.js";
|
|
20
20
|
import { UiCommands } from "../controllers/commands/ui-command.controller.js";
|
|
21
21
|
import { LlmUsageCommandService } from "../services/usage/llm-usage-command.service.js";
|
|
22
|
+
import { ProjectCommands } from "../controllers/commands/project/project-command.controller.js";
|
|
23
|
+
import { SessionCommands } from "../controllers/commands/session/session-command.controller.js";
|
|
22
24
|
import { ServiceRestartManager } from "./service-restart.manager.js";
|
|
23
25
|
import { ServiceWorkspaceManager } from "./service-workspace.manager.js";
|
|
24
26
|
import { RemoteRuntimeActions } from "@nextclaw/remote";
|
|
@@ -43,6 +45,8 @@ type NextclawServiceCommands = {
|
|
|
43
45
|
serve: ServeCommands;
|
|
44
46
|
stop: StopCommands;
|
|
45
47
|
usage: LlmUsageCommandService;
|
|
48
|
+
projects: ProjectCommands;
|
|
49
|
+
sessions: SessionCommands;
|
|
46
50
|
};
|
|
47
51
|
type ServiceCommandManagerDeps = {
|
|
48
52
|
logo: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-command.manager.d.ts","names":[],"sources":["../../src/managers/service-command.manager.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"service-command.manager.d.ts","names":[],"sources":["../../src/managers/service-command.manager.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgCY,uBAAA;EACV,MAAA,EAAQ,oBAAA;EACR,MAAA,EAAQ,cAAA;EACR,OAAA,EAAS,eAAA;EACT,MAAA,EAAQ,cAAA;EACR,GAAA,EAAK,WAAA;EACL,OAAA,EAAS,eAAA;EACT,MAAA,EAAQ,aAAA;EACR,QAAA,EAAU,eAAA;EACV,IAAA,EAAM,YAAA;EACN,WAAA,EAAa,mBAAA;EACb,IAAA,EAAM,YAAA;EACN,OAAA,EAAS,eAAA;EACT,EAAA,EAAI,UAAA;EACJ,KAAA,EAAO,aAAA;EACP,OAAA,EAAS,eAAA;EACT,KAAA,EAAO,aAAA;EACP,IAAA,EAAM,YAAA;EACN,KAAA,EAAO,sBAAA;EACP,QAAA,EAAU,eAAA;EACV,QAAA,EAAU,eAAA;AAAA;AAAA,KAGP,yBAAA;EACH,IAAA;EACA,IAAA,GAAO,MAAA;IAAU,MAAA;IAAiB,IAAA;IAAgB,KAAA;EAAA,MAAsB,OAAA;EACxE,cAAA,EAAgB,qBAAA;EAChB,OAAA,EAAS,qBAAA;EACT,SAAA,EAAW,uBAAA;AAAA;AAAA,cAGA,qBAAA;EAAA,iBAKkB,IAAA;EAAA,SAJpB,QAAA,EAAU,uBAAA;EAAA,SACV,YAAA,EAAc,oBAAA;EAAA,SACd,MAAA,EAAQ,cAAA;cAEY,IAAA,EAAM,yBAAA;AAAA"}
|
|
@@ -25,8 +25,10 @@ import { StopCommands } from "../controllers/commands/stop-command.controller.js
|
|
|
25
25
|
import { UiCommands } from "../controllers/commands/ui-command.controller.js";
|
|
26
26
|
import { LlmUsageCommandService } from "../services/usage/llm-usage-command.service.js";
|
|
27
27
|
import "../controllers/commands/usage-command.controller.js";
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
28
|
+
import { ProjectCommands } from "../controllers/commands/project/project-command.controller.js";
|
|
29
|
+
import { SessionCommands } from "../controllers/commands/session/session-command.controller.js";
|
|
30
|
+
import { APP_NAME, getConfigPath, getDataDir } from "@nextclaw/core";
|
|
31
|
+
import { AgentManager, NextclawKernel } from "@nextclaw/kernel";
|
|
30
32
|
import { RemoteRuntimeActions } from "@nextclaw/remote";
|
|
31
33
|
//#region src/managers/service-command.manager.ts
|
|
32
34
|
const FORCED_PUBLIC_UI_HOST = "0.0.0.0";
|
|
@@ -36,6 +38,10 @@ var ServiceCommandManager = class {
|
|
|
36
38
|
remote;
|
|
37
39
|
constructor(deps) {
|
|
38
40
|
this.deps = deps;
|
|
41
|
+
const createKernel = () => new NextclawKernel({
|
|
42
|
+
homeDir: getDataDir(),
|
|
43
|
+
configPath: getConfigPath()
|
|
44
|
+
});
|
|
39
45
|
const start = new StartCommands({
|
|
40
46
|
runtimeCommandService: this.deps.managedService,
|
|
41
47
|
forcedPublicHost: FORCED_PUBLIC_UI_HOST,
|
|
@@ -84,7 +90,9 @@ var ServiceCommandManager = class {
|
|
|
84
90
|
forcedPublicHost: FORCED_PUBLIC_UI_HOST
|
|
85
91
|
}),
|
|
86
92
|
stop: new StopCommands({ runtimeCommandService: this.deps.managedService }),
|
|
87
|
-
usage: new LlmUsageCommandService()
|
|
93
|
+
usage: new LlmUsageCommandService(),
|
|
94
|
+
projects: new ProjectCommands(createKernel),
|
|
95
|
+
sessions: new SessionCommands(createKernel)
|
|
88
96
|
};
|
|
89
97
|
}
|
|
90
98
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-command.manager.js","names":[],"sources":["../../src/managers/service-command.manager.ts"],"sourcesContent":["import { APP_NAME } from \"@nextclaw/core\";\nimport { AgentManager } from \"@nextclaw/kernel\";\nimport { RemoteRuntimeActions } from \"@nextclaw/remote\";\nimport { AgentCommands, runCliAgentCommand } from \"@nextclaw-service/controllers/commands/agent-command.controller.js\";\nimport { ChannelCommands } from \"@nextclaw-service/controllers/commands/channel-command.controller.js\";\nimport { ConfigCommands } from \"@nextclaw-service/controllers/commands/config-command.controller.js\";\nimport { CronCommands } from \"@nextclaw-service/controllers/commands/cron-command.controller.js\";\nimport { DiagnosticsCommands } from \"@nextclaw-service/controllers/commands/diagnostics-command.controller.js\";\nimport { GatewayCommands } from \"@nextclaw-service/controllers/commands/gateway-command.controller.js\";\nimport { LogsCommands } from \"@nextclaw-service/controllers/commands/logs-command.controller.js\";\nimport { SkillsCommands } from \"@nextclaw-service/controllers/commands/marketplace-skill-command.controller.js\";\nimport { McpCommands } from \"@nextclaw-service/controllers/commands/mcp-command.controller.js\";\nimport { PlatformAuthCommands } from \"@nextclaw-service/controllers/commands/platform-auth-command.controller.js\";\nimport { RemoteCommands, hasRunningNextclawManagedService } from \"@nextclaw-service/controllers/commands/remote-command.controller.js\";\nimport { RestartCommands } from \"@nextclaw-service/controllers/commands/restart-command.controller.js\";\nimport { SecretsCommands } from \"@nextclaw-service/controllers/commands/secrets-command.controller.js\";\nimport { ServeCommands } from \"@nextclaw-service/controllers/commands/serve-command.controller.js\";\nimport { ServiceCommands } from \"@nextclaw-service/controllers/commands/service-command.controller.js\";\nimport { StartCommands } from \"@nextclaw-service/controllers/commands/start-command.controller.js\";\nimport { StopCommands } from \"@nextclaw-service/controllers/commands/stop-command.controller.js\";\nimport { UiCommands } from \"@nextclaw-service/controllers/commands/ui-command.controller.js\";\nimport { LlmUsageCommandService } from \"@nextclaw-service/controllers/commands/usage-command.controller.js\";\nimport type { ManagedServiceManager } from \"@nextclaw-service/managers/managed-service.manager.js\";\nimport type { ServiceRestartManager } from \"@nextclaw-service/managers/service-restart.manager.js\";\nimport type { ServiceWorkspaceManager } from \"@nextclaw-service/managers/service-workspace.manager.js\";\n\nconst FORCED_PUBLIC_UI_HOST = \"0.0.0.0\";\n\nexport { runCliAgentCommand };\n\nexport type NextclawServiceCommands = {\n remote: RemoteRuntimeActions;\n skills: SkillsCommands;\n service: ServiceCommands;\n config: ConfigCommands;\n mcp: McpCommands;\n secrets: SecretsCommands;\n agents: AgentCommands;\n channels: ChannelCommands;\n cron: CronCommands;\n diagnostics: DiagnosticsCommands;\n logs: LogsCommands;\n gateway: GatewayCommands;\n ui: UiCommands;\n start: StartCommands;\n restart: RestartCommands;\n serve: ServeCommands;\n stop: StopCommands;\n usage: LlmUsageCommandService;\n};\n\ntype ServiceCommandManagerDeps = {\n logo: string;\n init: (params: { source?: string; auto?: boolean; force?: boolean }) => Promise<void>;\n managedService: ManagedServiceManager;\n restart: ServiceRestartManager;\n workspace: ServiceWorkspaceManager;\n};\n\nexport class ServiceCommandManager {\n readonly commands: NextclawServiceCommands;\n readonly platformAuth: PlatformAuthCommands;\n readonly remote: RemoteCommands;\n\n constructor(private readonly deps: ServiceCommandManagerDeps) {\n const start = new StartCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST,\n init: (params) => this.deps.init(params)\n });\n this.platformAuth = new PlatformAuthCommands();\n this.remote = new RemoteCommands();\n this.commands = {\n remote: new RemoteRuntimeActions({\n appName: APP_NAME,\n initAuto: (source) => this.deps.init({ source, auto: true }),\n remoteCommands: this.remote,\n restartBackgroundService: (reason) => this.deps.restart.restartBackgroundService(reason),\n hasRunningManagedService: hasRunningNextclawManagedService\n }),\n skills: new SkillsCommands(),\n service: new ServiceCommands(),\n config: new ConfigCommands({\n requestRestart: (params) => this.deps.restart.requestRestart(params),\n }),\n mcp: new McpCommands(),\n secrets: new SecretsCommands({\n requestRestart: (params) => this.deps.restart.requestRestart(params),\n }),\n agents: new AgentCommands(new AgentManager(undefined, {\n initializeAgentHomeDirectory: (homeDirectory) =>\n this.deps.workspace.createWorkspaceTemplates(homeDirectory),\n })),\n channels: new ChannelCommands({\n requestRestart: (params) => this.deps.restart.requestRestart(params),\n }),\n cron: new CronCommands(),\n diagnostics: new DiagnosticsCommands({ logo: this.deps.logo }),\n logs: new LogsCommands(),\n gateway: new GatewayCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST\n }),\n ui: new UiCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST\n }),\n start,\n restart: new RestartCommands({\n runtimeCommandService: this.deps.managedService,\n startCommands: start,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST,\n writeRestartSentinelFromExecContext: (reason) => this.deps.restart.writeRestartSentinelFromExecContext(reason)\n }),\n serve: new ServeCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST\n }),\n stop: new StopCommands({\n runtimeCommandService: this.deps.managedService\n }),\n usage: new LlmUsageCommandService(),\n };\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"service-command.manager.js","names":[],"sources":["../../src/managers/service-command.manager.ts"],"sourcesContent":["import { APP_NAME, getConfigPath, getDataDir } from \"@nextclaw/core\";\nimport { AgentManager, NextclawKernel } from \"@nextclaw/kernel\";\nimport { RemoteRuntimeActions } from \"@nextclaw/remote\";\nimport { AgentCommands, runCliAgentCommand } from \"@nextclaw-service/controllers/commands/agent-command.controller.js\";\nimport { ChannelCommands } from \"@nextclaw-service/controllers/commands/channel-command.controller.js\";\nimport { ConfigCommands } from \"@nextclaw-service/controllers/commands/config-command.controller.js\";\nimport { CronCommands } from \"@nextclaw-service/controllers/commands/cron-command.controller.js\";\nimport { DiagnosticsCommands } from \"@nextclaw-service/controllers/commands/diagnostics-command.controller.js\";\nimport { GatewayCommands } from \"@nextclaw-service/controllers/commands/gateway-command.controller.js\";\nimport { LogsCommands } from \"@nextclaw-service/controllers/commands/logs-command.controller.js\";\nimport { SkillsCommands } from \"@nextclaw-service/controllers/commands/marketplace-skill-command.controller.js\";\nimport { McpCommands } from \"@nextclaw-service/controllers/commands/mcp-command.controller.js\";\nimport { PlatformAuthCommands } from \"@nextclaw-service/controllers/commands/platform-auth-command.controller.js\";\nimport { RemoteCommands, hasRunningNextclawManagedService } from \"@nextclaw-service/controllers/commands/remote-command.controller.js\";\nimport { RestartCommands } from \"@nextclaw-service/controllers/commands/restart-command.controller.js\";\nimport { SecretsCommands } from \"@nextclaw-service/controllers/commands/secrets-command.controller.js\";\nimport { ServeCommands } from \"@nextclaw-service/controllers/commands/serve-command.controller.js\";\nimport { ServiceCommands } from \"@nextclaw-service/controllers/commands/service-command.controller.js\";\nimport { StartCommands } from \"@nextclaw-service/controllers/commands/start-command.controller.js\";\nimport { StopCommands } from \"@nextclaw-service/controllers/commands/stop-command.controller.js\";\nimport { UiCommands } from \"@nextclaw-service/controllers/commands/ui-command.controller.js\";\nimport { LlmUsageCommandService } from \"@nextclaw-service/controllers/commands/usage-command.controller.js\";\nimport { ProjectCommands } from \"@nextclaw-service/controllers/commands/project/project-command.controller.js\";\nimport { SessionCommands } from \"@nextclaw-service/controllers/commands/session/session-command.controller.js\";\nimport type { ManagedServiceManager } from \"@nextclaw-service/managers/managed-service.manager.js\";\nimport type { ServiceRestartManager } from \"@nextclaw-service/managers/service-restart.manager.js\";\nimport type { ServiceWorkspaceManager } from \"@nextclaw-service/managers/service-workspace.manager.js\";\n\nconst FORCED_PUBLIC_UI_HOST = \"0.0.0.0\";\n\nexport { runCliAgentCommand };\n\nexport type NextclawServiceCommands = {\n remote: RemoteRuntimeActions;\n skills: SkillsCommands;\n service: ServiceCommands;\n config: ConfigCommands;\n mcp: McpCommands;\n secrets: SecretsCommands;\n agents: AgentCommands;\n channels: ChannelCommands;\n cron: CronCommands;\n diagnostics: DiagnosticsCommands;\n logs: LogsCommands;\n gateway: GatewayCommands;\n ui: UiCommands;\n start: StartCommands;\n restart: RestartCommands;\n serve: ServeCommands;\n stop: StopCommands;\n usage: LlmUsageCommandService;\n projects: ProjectCommands;\n sessions: SessionCommands;\n};\n\ntype ServiceCommandManagerDeps = {\n logo: string;\n init: (params: { source?: string; auto?: boolean; force?: boolean }) => Promise<void>;\n managedService: ManagedServiceManager;\n restart: ServiceRestartManager;\n workspace: ServiceWorkspaceManager;\n};\n\nexport class ServiceCommandManager {\n readonly commands: NextclawServiceCommands;\n readonly platformAuth: PlatformAuthCommands;\n readonly remote: RemoteCommands;\n\n constructor(private readonly deps: ServiceCommandManagerDeps) {\n const createKernel = () => new NextclawKernel({\n homeDir: getDataDir(),\n configPath: getConfigPath(),\n });\n const start = new StartCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST,\n init: (params) => this.deps.init(params)\n });\n this.platformAuth = new PlatformAuthCommands();\n this.remote = new RemoteCommands();\n this.commands = {\n remote: new RemoteRuntimeActions({\n appName: APP_NAME,\n initAuto: (source) => this.deps.init({ source, auto: true }),\n remoteCommands: this.remote,\n restartBackgroundService: (reason) => this.deps.restart.restartBackgroundService(reason),\n hasRunningManagedService: hasRunningNextclawManagedService\n }),\n skills: new SkillsCommands(),\n service: new ServiceCommands(),\n config: new ConfigCommands({\n requestRestart: (params) => this.deps.restart.requestRestart(params),\n }),\n mcp: new McpCommands(),\n secrets: new SecretsCommands({\n requestRestart: (params) => this.deps.restart.requestRestart(params),\n }),\n agents: new AgentCommands(new AgentManager(undefined, {\n initializeAgentHomeDirectory: (homeDirectory) =>\n this.deps.workspace.createWorkspaceTemplates(homeDirectory),\n })),\n channels: new ChannelCommands({\n requestRestart: (params) => this.deps.restart.requestRestart(params),\n }),\n cron: new CronCommands(),\n diagnostics: new DiagnosticsCommands({ logo: this.deps.logo }),\n logs: new LogsCommands(),\n gateway: new GatewayCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST\n }),\n ui: new UiCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST\n }),\n start,\n restart: new RestartCommands({\n runtimeCommandService: this.deps.managedService,\n startCommands: start,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST,\n writeRestartSentinelFromExecContext: (reason) => this.deps.restart.writeRestartSentinelFromExecContext(reason)\n }),\n serve: new ServeCommands({\n runtimeCommandService: this.deps.managedService,\n forcedPublicHost: FORCED_PUBLIC_UI_HOST\n }),\n stop: new StopCommands({\n runtimeCommandService: this.deps.managedService\n }),\n usage: new LlmUsageCommandService(),\n projects: new ProjectCommands(createKernel),\n sessions: new SessionCommands(createKernel),\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAM,wBAAwB;AAmC9B,IAAa,wBAAb,MAAmC;CACjC;CACA;CACA;CAEA,YAAY,MAAkD;AAAjC,OAAA,OAAA;EAC3B,MAAM,qBAAqB,IAAI,eAAe;GAC5C,SAAS,YAAY;GACrB,YAAY,eAAe;GAC5B,CAAC;EACF,MAAM,QAAQ,IAAI,cAAc;GAC9B,uBAAuB,KAAK,KAAK;GACjC,kBAAkB;GAClB,OAAO,WAAW,KAAK,KAAK,KAAK,OAAO;GACzC,CAAC;AACF,OAAK,eAAe,IAAI,sBAAsB;AAC9C,OAAK,SAAS,IAAI,gBAAgB;AAClC,OAAK,WAAW;GACd,QAAQ,IAAI,qBAAqB;IAC/B,SAAS;IACT,WAAW,WAAW,KAAK,KAAK,KAAK;KAAE;KAAQ,MAAM;KAAM,CAAC;IAC5D,gBAAgB,KAAK;IACrB,2BAA2B,WAAW,KAAK,KAAK,QAAQ,yBAAyB,OAAO;IACxF,0BAA0B;IAC3B,CAAC;GACF,QAAQ,IAAI,gBAAgB;GAC5B,SAAS,IAAI,iBAAiB;GAC9B,QAAQ,IAAI,eAAe,EACzB,iBAAiB,WAAW,KAAK,KAAK,QAAQ,eAAe,OAAO,EACrE,CAAC;GACF,KAAK,IAAI,aAAa;GACtB,SAAS,IAAI,gBAAgB,EAC3B,iBAAiB,WAAW,KAAK,KAAK,QAAQ,eAAe,OAAO,EACrE,CAAC;GACF,QAAQ,IAAI,cAAc,IAAI,aAAa,KAAA,GAAW,EACpD,+BAA+B,kBAC7B,KAAK,KAAK,UAAU,yBAAyB,cAAc,EAC9D,CAAC,CAAC;GACH,UAAU,IAAI,gBAAgB,EAC5B,iBAAiB,WAAW,KAAK,KAAK,QAAQ,eAAe,OAAO,EACrE,CAAC;GACF,MAAM,IAAI,cAAc;GACxB,aAAa,IAAI,oBAAoB,EAAE,MAAM,KAAK,KAAK,MAAM,CAAC;GAC9D,MAAM,IAAI,cAAc;GACxB,SAAS,IAAI,gBAAgB;IAC3B,uBAAuB,KAAK,KAAK;IACjC,kBAAkB;IACnB,CAAC;GACF,IAAI,IAAI,WAAW;IACjB,uBAAuB,KAAK,KAAK;IACjC,kBAAkB;IACnB,CAAC;GACF;GACA,SAAS,IAAI,gBAAgB;IAC3B,uBAAuB,KAAK,KAAK;IACjC,eAAe;IACf,kBAAkB;IAClB,sCAAsC,WAAW,KAAK,KAAK,QAAQ,oCAAoC,OAAO;IAC/G,CAAC;GACF,OAAO,IAAI,cAAc;IACvB,uBAAuB,KAAK,KAAK;IACjC,kBAAkB;IACnB,CAAC;GACF,MAAM,IAAI,aAAa,EACrB,uBAAuB,KAAK,KAAK,gBAClC,CAAC;GACF,OAAO,IAAI,wBAAwB;GACnC,UAAU,IAAI,gBAAgB,aAAa;GAC3C,UAAU,IAAI,gBAAgB,aAAa;GAC5C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-restart.manager.d.ts","names":[],"sources":["../../src/managers/service-restart.manager.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"service-restart.manager.d.ts","names":[],"sources":["../../src/managers/service-restart.manager.ts"],"mappings":";;;;KAaK,yBAAA;EACH,cAAA,EAAgB,qBAAA;AAAA;AAAA,cAGL,qBAAA;EAAA,iBAWkB,IAAA;EAAA,iBAVZ,kBAAA;EAAA,QAOT,kBAAA;EAAA,QACA,iBAAA;cAEqB,IAAA,EAAM,yBAAA;EAEnC,cAAA,GAAwB,MAAA,EAAQ,oBAAA,KAAuB,OAAA;EAgDvD,wBAAA,GAAkC,MAAA,aAAiB,OAAA;EAsCnD,mCAAA,GAA6C,MAAA,aAAiB,OAAA;EAAA,QA0BtD,mBAAA;EAAA,QAOA,yBAAA;AAAA"}
|
|
@@ -2,6 +2,7 @@ import { isProcessRunning } from "../utils/cli.utils.js";
|
|
|
2
2
|
import { managedServiceStateStore } from "../stores/managed-service-state.store.js";
|
|
3
3
|
import { resolveCliSubcommandLaunch } from "../utils/marketplace/cli-subcommand-launch.utils.js";
|
|
4
4
|
import { createTopLevelNextclawCommandEnv } from "../utils/top-level-nextclaw-command-env.utils.js";
|
|
5
|
+
import { NextclawDistributionService } from "../services/runtime/nextclaw-distribution.service.js";
|
|
5
6
|
import { writeRestartSentinel } from "../utils/restart-sentinel.utils.js";
|
|
6
7
|
import { pendingRestartStore } from "../stores/pending-restart.store.js";
|
|
7
8
|
import { RestartCoordinator } from "../services/restart/restart-coordinator.service.js";
|
|
@@ -104,8 +105,7 @@ var ServiceRestartManager = class {
|
|
|
104
105
|
}, delayMs);
|
|
105
106
|
};
|
|
106
107
|
armManagedServiceRelaunch = (params) => {
|
|
107
|
-
const { delayMs: requestedDelayMs, reason, strategy
|
|
108
|
-
const strategy = requestedStrategy ?? "background-service-or-manual";
|
|
108
|
+
const { delayMs: requestedDelayMs, reason, strategy = "background-service-or-manual" } = params;
|
|
109
109
|
if (strategy !== "background-service-or-exit" && strategy !== "exit-process") return;
|
|
110
110
|
if (this.selfRelaunchArmed) return;
|
|
111
111
|
const state = managedServiceStateStore.read();
|
|
@@ -113,14 +113,13 @@ var ServiceRestartManager = class {
|
|
|
113
113
|
const uiPort = typeof state.uiPort === "number" && Number.isFinite(state.uiPort) ? state.uiPort : 55667;
|
|
114
114
|
const delayMs = typeof requestedDelayMs === "number" && Number.isFinite(requestedDelayMs) ? Math.max(0, Math.floor(requestedDelayMs)) : 100;
|
|
115
115
|
const launch = resolveCliSubcommandLaunch({
|
|
116
|
-
argvEntry:
|
|
116
|
+
argvEntry: NextclawDistributionService.get().launcherEntrypoint,
|
|
117
117
|
importMetaUrl: import.meta.url,
|
|
118
118
|
cliArgs: [
|
|
119
119
|
"start",
|
|
120
120
|
"--ui-port",
|
|
121
121
|
String(uiPort)
|
|
122
|
-
]
|
|
123
|
-
nodePath: process.execPath
|
|
122
|
+
]
|
|
124
123
|
});
|
|
125
124
|
const serviceStatePath = managedServiceStateStore.path;
|
|
126
125
|
const helperScript = `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-restart.manager.js","names":[],"sources":["../../src/managers/service-restart.manager.ts"],"sourcesContent":["import { APP_NAME } from \"@nextclaw/core\";\nimport { spawn } from \"node:child_process\";\nimport type { ManagedServiceManager } from \"@nextclaw-service/managers/managed-service.manager.js\";\nimport { RestartCoordinator } from \"@nextclaw-service/services/restart/restart-coordinator.service.js\";\nimport { managedServiceStateStore } from \"@nextclaw-service/stores/managed-service-state.store.js\";\nimport { pendingRestartStore } from \"@nextclaw-service/stores/pending-restart.store.js\";\nimport type { RequestRestartParams } from \"@nextclaw-service/types/cli.types.js\";\nimport { isProcessRunning } from \"@nextclaw-service/utils/cli.utils.js\";\nimport { resolveCliSubcommandLaunch } from \"@nextclaw-service/utils/marketplace/cli-subcommand-launch.utils.js\";\nimport { writeRestartSentinel } from \"@nextclaw-service/utils/restart-sentinel.utils.js\";\nimport { createTopLevelNextclawCommandEnv } from \"@nextclaw-service/utils/top-level-nextclaw-command-env.utils.js\";\n\ntype ServiceRestartManagerDeps = {\n managedService: ManagedServiceManager;\n};\n\nexport class ServiceRestartManager {\n private readonly restartCoordinator = new RestartCoordinator({\n readServiceState: managedServiceStateStore.read,\n isProcessRunning,\n currentPid: () => process.pid,\n restartBackgroundService: async (reason) => this.restartBackgroundService(reason),\n scheduleProcessExit: (delayMs, reason) => this.scheduleProcessExit(delayMs, reason),\n });\n private serviceRestartTask: Promise<boolean> | null = null;\n private selfRelaunchArmed = false;\n\n constructor(private readonly deps: ServiceRestartManagerDeps) {}\n\n requestRestart = async (params: RequestRestartParams): Promise<void> => {\n const {\n changedPaths,\n delayMs,\n manualMessage,\n mode,\n reason,\n silentOnServiceRestart,\n strategy\n } = params;\n if (mode === \"notify\") {\n pendingRestartStore.mark({\n changedPaths,\n manualMessage,\n reason\n });\n console.warn(manualMessage);\n return;\n }\n\n this.armManagedServiceRelaunch({\n reason,\n strategy,\n delayMs\n });\n\n const result = await this.restartCoordinator.requestRestart({\n reason,\n strategy,\n delayMs,\n manualMessage\n });\n if (result.status === \"manual-required\" || result.status === \"restart-in-progress\") {\n console.log(result.message);\n return;\n }\n\n pendingRestartStore.clear();\n if (result.status === \"service-restarted\") {\n if (!silentOnServiceRestart) {\n console.log(result.message);\n }\n return;\n }\n\n console.warn(result.message);\n };\n\n restartBackgroundService = async (reason: string): Promise<boolean> => {\n if (this.serviceRestartTask) {\n return this.serviceRestartTask;\n }\n\n this.serviceRestartTask = (async () => {\n const state = managedServiceStateStore.read();\n if (!state || !isProcessRunning(state.pid) || state.pid === process.pid) {\n return false;\n }\n\n const uiPort =\n typeof state.uiPort === \"number\" && Number.isFinite(state.uiPort)\n ? state.uiPort\n : 55667;\n\n console.log(\n `Applying changes (${reason}): restarting ${APP_NAME} background service...`,\n );\n await this.deps.managedService.stopService();\n await this.deps.managedService.startService({\n uiOverrides: {\n enabled: true,\n host: \"0.0.0.0\",\n port: uiPort,\n },\n open: false,\n });\n return true;\n })();\n\n try {\n return await this.serviceRestartTask;\n } finally {\n this.serviceRestartTask = null;\n }\n };\n\n writeRestartSentinelFromExecContext = async (reason: string): Promise<void> => {\n const sessionKeyRaw = process.env.NEXTCLAW_RUNTIME_SESSION_KEY;\n const sessionKey =\n typeof sessionKeyRaw === \"string\" ? sessionKeyRaw.trim() : \"\";\n if (!sessionKey) {\n return;\n }\n\n try {\n await writeRestartSentinel({\n kind: \"restart\",\n status: \"ok\",\n ts: Date.now(),\n sessionKey,\n stats: {\n reason: reason || \"cli.restart\",\n strategy: \"exec-tool\",\n },\n });\n } catch (error) {\n console.warn(\n `Warning: failed to write restart sentinel from exec context: ${String(error)}`,\n );\n }\n };\n\n private scheduleProcessExit = (delayMs: number, reason: string): void => {\n console.warn(`Gateway restart requested (${reason}).`);\n setTimeout(() => {\n process.exit(0);\n }, delayMs);\n };\n\n private armManagedServiceRelaunch = (params: {\n reason: string;\n strategy?: RequestRestartParams[\"strategy\"];\n delayMs?: number;\n }): void => {\n const { delayMs: requestedDelayMs, reason, strategy: requestedStrategy } = params;\n const strategy = requestedStrategy ?? \"background-service-or-manual\";\n if (\n strategy !== \"background-service-or-exit\" &&\n strategy !== \"exit-process\"\n ) {\n return;\n }\n if (this.selfRelaunchArmed) {\n return;\n }\n\n const state = managedServiceStateStore.read();\n if (!state || state.pid !== process.pid) {\n return;\n }\n\n const uiPort =\n typeof state.uiPort === \"number\" && Number.isFinite(state.uiPort)\n ? state.uiPort\n : 55667;\n const delayMs =\n typeof requestedDelayMs === \"number\" && Number.isFinite(requestedDelayMs)\n ? Math.max(0, Math.floor(requestedDelayMs))\n : 100;\n const launch = resolveCliSubcommandLaunch({\n argvEntry: process.argv[1],\n importMetaUrl: import.meta.url,\n cliArgs: [\"start\", \"--ui-port\", String(uiPort)],\n nodePath: process.execPath\n });\n const serviceStatePath = managedServiceStateStore.path;\n const helperScript = `\nconst { spawnSync } = require(\"node:child_process\");\nconst { readFileSync } = require(\"node:fs\");\nconst parentPid = ${process.pid};\nconst delayMs = ${delayMs};\nconst maxWaitMs = 120000;\nconst retryIntervalMs = 1000;\nconst command = ${JSON.stringify(launch.command)};\nconst args = ${JSON.stringify(launch.args)};\nconst serviceStatePath = ${JSON.stringify(serviceStatePath)};\nfunction isRunning(pid) {\n try { process.kill(pid, 0); return true; } catch { return false; }\n}\nfunction hasReplacementService() {\n try {\n const state = JSON.parse(readFileSync(serviceStatePath, \"utf-8\"));\n const pid = Number(state?.pid);\n return Number.isFinite(pid) && pid > 0 && pid !== parentPid && isRunning(pid);\n } catch { return false; }\n}\nfunction tryStart() {\n spawnSync(command, args, { stdio: \"ignore\", env: process.env, timeout: 60000, windowsHide: true });\n}\nsetTimeout(() => {\n const startedAt = Date.now();\n const tick = () => {\n if (hasReplacementService() || Date.now() - startedAt >= maxWaitMs) {\n process.exit(0);\n return;\n }\n tryStart();\n if (hasReplacementService()) {\n process.exit(0);\n return;\n }\n setTimeout(tick, retryIntervalMs);\n };\n tick();\n}, delayMs);\n`.trim();\n\n try {\n const helper = spawn(process.execPath, [\"-e\", helperScript], {\n detached: true,\n stdio: \"ignore\",\n env: createTopLevelNextclawCommandEnv(process.env),\n windowsHide: true\n });\n helper.unref();\n this.selfRelaunchArmed = true;\n console.warn(`Gateway self-restart armed (${reason}).`);\n } catch (error) {\n console.error(`Failed to arm gateway self-restart: ${String(error)}`);\n }\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service-restart.manager.js","names":[],"sources":["../../src/managers/service-restart.manager.ts"],"sourcesContent":["import { APP_NAME } from \"@nextclaw/core\";\nimport { spawn } from \"node:child_process\";\nimport type { ManagedServiceManager } from \"@nextclaw-service/managers/managed-service.manager.js\";\nimport { NextclawDistributionService } from \"@nextclaw-service/services/runtime/nextclaw-distribution.service.js\";\nimport { RestartCoordinator } from \"@nextclaw-service/services/restart/restart-coordinator.service.js\";\nimport { managedServiceStateStore } from \"@nextclaw-service/stores/managed-service-state.store.js\";\nimport { pendingRestartStore } from \"@nextclaw-service/stores/pending-restart.store.js\";\nimport type { RequestRestartParams } from \"@nextclaw-service/types/cli.types.js\";\nimport { isProcessRunning } from \"@nextclaw-service/utils/cli.utils.js\";\nimport { resolveCliSubcommandLaunch } from \"@nextclaw-service/utils/marketplace/cli-subcommand-launch.utils.js\";\nimport { writeRestartSentinel } from \"@nextclaw-service/utils/restart-sentinel.utils.js\";\nimport { createTopLevelNextclawCommandEnv } from \"@nextclaw-service/utils/top-level-nextclaw-command-env.utils.js\";\n\ntype ServiceRestartManagerDeps = {\n managedService: ManagedServiceManager;\n};\n\nexport class ServiceRestartManager {\n private readonly restartCoordinator = new RestartCoordinator({\n readServiceState: managedServiceStateStore.read,\n isProcessRunning,\n currentPid: () => process.pid,\n restartBackgroundService: async (reason) => this.restartBackgroundService(reason),\n scheduleProcessExit: (delayMs, reason) => this.scheduleProcessExit(delayMs, reason),\n });\n private serviceRestartTask: Promise<boolean> | null = null;\n private selfRelaunchArmed = false;\n\n constructor(private readonly deps: ServiceRestartManagerDeps) {}\n\n requestRestart = async (params: RequestRestartParams): Promise<void> => {\n const {\n changedPaths,\n delayMs,\n manualMessage,\n mode,\n reason,\n silentOnServiceRestart,\n strategy\n } = params;\n if (mode === \"notify\") {\n pendingRestartStore.mark({\n changedPaths,\n manualMessage,\n reason\n });\n console.warn(manualMessage);\n return;\n }\n\n this.armManagedServiceRelaunch({\n reason,\n strategy,\n delayMs\n });\n\n const result = await this.restartCoordinator.requestRestart({\n reason,\n strategy,\n delayMs,\n manualMessage\n });\n if (result.status === \"manual-required\" || result.status === \"restart-in-progress\") {\n console.log(result.message);\n return;\n }\n\n pendingRestartStore.clear();\n if (result.status === \"service-restarted\") {\n if (!silentOnServiceRestart) {\n console.log(result.message);\n }\n return;\n }\n\n console.warn(result.message);\n };\n\n restartBackgroundService = async (reason: string): Promise<boolean> => {\n if (this.serviceRestartTask) {\n return this.serviceRestartTask;\n }\n\n this.serviceRestartTask = (async () => {\n const state = managedServiceStateStore.read();\n if (!state || !isProcessRunning(state.pid) || state.pid === process.pid) {\n return false;\n }\n\n const uiPort =\n typeof state.uiPort === \"number\" && Number.isFinite(state.uiPort)\n ? state.uiPort\n : 55667;\n\n console.log(\n `Applying changes (${reason}): restarting ${APP_NAME} background service...`,\n );\n await this.deps.managedService.stopService();\n await this.deps.managedService.startService({\n uiOverrides: {\n enabled: true,\n host: \"0.0.0.0\",\n port: uiPort,\n },\n open: false,\n });\n return true;\n })();\n\n try {\n return await this.serviceRestartTask;\n } finally {\n this.serviceRestartTask = null;\n }\n };\n\n writeRestartSentinelFromExecContext = async (reason: string): Promise<void> => {\n const sessionKeyRaw = process.env.NEXTCLAW_RUNTIME_SESSION_KEY;\n const sessionKey =\n typeof sessionKeyRaw === \"string\" ? sessionKeyRaw.trim() : \"\";\n if (!sessionKey) {\n return;\n }\n\n try {\n await writeRestartSentinel({\n kind: \"restart\",\n status: \"ok\",\n ts: Date.now(),\n sessionKey,\n stats: {\n reason: reason || \"cli.restart\",\n strategy: \"exec-tool\",\n },\n });\n } catch (error) {\n console.warn(\n `Warning: failed to write restart sentinel from exec context: ${String(error)}`,\n );\n }\n };\n\n private scheduleProcessExit = (delayMs: number, reason: string): void => {\n console.warn(`Gateway restart requested (${reason}).`);\n setTimeout(() => {\n process.exit(0);\n }, delayMs);\n };\n\n private armManagedServiceRelaunch = (params: {\n reason: string;\n strategy?: RequestRestartParams[\"strategy\"];\n delayMs?: number;\n }): void => {\n const { delayMs: requestedDelayMs, reason, strategy = \"background-service-or-manual\" } = params;\n if (\n strategy !== \"background-service-or-exit\" &&\n strategy !== \"exit-process\"\n ) {\n return;\n }\n if (this.selfRelaunchArmed) {\n return;\n }\n\n const state = managedServiceStateStore.read();\n if (!state || state.pid !== process.pid) {\n return;\n }\n\n const uiPort =\n typeof state.uiPort === \"number\" && Number.isFinite(state.uiPort)\n ? state.uiPort\n : 55667;\n const delayMs =\n typeof requestedDelayMs === \"number\" && Number.isFinite(requestedDelayMs)\n ? Math.max(0, Math.floor(requestedDelayMs))\n : 100;\n const launch = resolveCliSubcommandLaunch({\n argvEntry: NextclawDistributionService.get().launcherEntrypoint,\n importMetaUrl: import.meta.url,\n cliArgs: [\"start\", \"--ui-port\", String(uiPort)]\n });\n const serviceStatePath = managedServiceStateStore.path;\n const helperScript = `\nconst { spawnSync } = require(\"node:child_process\");\nconst { readFileSync } = require(\"node:fs\");\nconst parentPid = ${process.pid};\nconst delayMs = ${delayMs};\nconst maxWaitMs = 120000;\nconst retryIntervalMs = 1000;\nconst command = ${JSON.stringify(launch.command)};\nconst args = ${JSON.stringify(launch.args)};\nconst serviceStatePath = ${JSON.stringify(serviceStatePath)};\nfunction isRunning(pid) {\n try { process.kill(pid, 0); return true; } catch { return false; }\n}\nfunction hasReplacementService() {\n try {\n const state = JSON.parse(readFileSync(serviceStatePath, \"utf-8\"));\n const pid = Number(state?.pid);\n return Number.isFinite(pid) && pid > 0 && pid !== parentPid && isRunning(pid);\n } catch { return false; }\n}\nfunction tryStart() {\n spawnSync(command, args, { stdio: \"ignore\", env: process.env, timeout: 60000, windowsHide: true });\n}\nsetTimeout(() => {\n const startedAt = Date.now();\n const tick = () => {\n if (hasReplacementService() || Date.now() - startedAt >= maxWaitMs) {\n process.exit(0);\n return;\n }\n tryStart();\n if (hasReplacementService()) {\n process.exit(0);\n return;\n }\n setTimeout(tick, retryIntervalMs);\n };\n tick();\n}, delayMs);\n`.trim();\n\n try {\n const helper = spawn(process.execPath, [\"-e\", helperScript], {\n detached: true,\n stdio: \"ignore\",\n env: createTopLevelNextclawCommandEnv(process.env),\n windowsHide: true\n });\n helper.unref();\n this.selfRelaunchArmed = true;\n console.warn(`Gateway self-restart armed (${reason}).`);\n } catch (error) {\n console.error(`Failed to arm gateway self-restart: ${String(error)}`);\n }\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm-runtime-update-host.service.d.ts","names":[],"sources":["../../../src/services/runtime/npm-runtime-update-host.service.ts"],"mappings":";;;;;;KAyBK,wBAAA;EACH,QAAA,EAAU,QAAA;EACV,cAAA,GAAiB,MAAA,EAAQ,oBAAA,KAAyB,OAAA;EAClD,QAAA,EAAU,IAAA,CAAK,MAAA;EACf,gBAAA;AAAA;AAAA,cAGW,oBAAA,YAAgC,mBAAA;EAAA,iBAWd,IAAA;EAAA,iBAVZ,MAAA;EAAA,iBACA,MAAA;EAAA,iBACA,eAAA;EAAA,iBACA,UAAA;EAAA,iBACA,aAAA;EAAA,iBACA,aAAA;EAAA,QACT,QAAA;EAAA,QACA,UAAA;EAAA,QACA,oBAAA;cAEqB,IAAA,EAAM,wBAAA;EAyBnC,QAAA,QAAqB,OAAA,CAAQ,cAAA;EAK7B,eAAA,QAA4B,OAAA,CAAQ,cAAA;EAIpC,cAAA,QAA2B,OAAA,CAAQ,cAAA;EAInC,qBAAA,QAAkC,OAAA,CAAQ,cAAA;EAkC1C,iBAAA,GAA2B,WAAA,EAAa,OAAA,CAAQ,iBAAA,MAAqB,OAAA,CAAQ,cAAA;EAe7E,aAAA,GAAuB,OAAA,EAAS,cAAA,gBAA4B,OAAA,CAAQ,cAAA;EAAA,QAY5D,kBAAA;EAAA,QAeA,UAAA;EAAA,
|
|
1
|
+
{"version":3,"file":"npm-runtime-update-host.service.d.ts","names":[],"sources":["../../../src/services/runtime/npm-runtime-update-host.service.ts"],"mappings":";;;;;;KAyBK,wBAAA;EACH,QAAA,EAAU,QAAA;EACV,cAAA,GAAiB,MAAA,EAAQ,oBAAA,KAAyB,OAAA;EAClD,QAAA,EAAU,IAAA,CAAK,MAAA;EACf,gBAAA;AAAA;AAAA,cAGW,oBAAA,YAAgC,mBAAA;EAAA,iBAWd,IAAA;EAAA,iBAVZ,MAAA;EAAA,iBACA,MAAA;EAAA,iBACA,eAAA;EAAA,iBACA,UAAA;EAAA,iBACA,aAAA;EAAA,iBACA,aAAA;EAAA,QACT,QAAA;EAAA,QACA,UAAA;EAAA,QACA,oBAAA;cAEqB,IAAA,EAAM,wBAAA;EAyBnC,QAAA,QAAqB,OAAA,CAAQ,cAAA;EAK7B,eAAA,QAA4B,OAAA,CAAQ,cAAA;EAIpC,cAAA,QAA2B,OAAA,CAAQ,cAAA;EAInC,qBAAA,QAAkC,OAAA,CAAQ,cAAA;EAkC1C,iBAAA,GAA2B,WAAA,EAAa,OAAA,CAAQ,iBAAA,MAAqB,OAAA,CAAQ,cAAA;EAe7E,aAAA,GAAuB,OAAA,EAAS,cAAA,gBAA4B,OAAA,CAAQ,cAAA;EAAA,QAY5D,kBAAA;EAAA,QAeA,UAAA;EAAA,QA0BA,aAAA;EAAA,QAsBA,eAAA;EAAA,QAYA,aAAA;EAAA,QAYA,gBAAA;EAAA,QASA,WAAA;AAAA"}
|
|
@@ -108,43 +108,47 @@ var NpmRuntimeUpdateHost = class {
|
|
|
108
108
|
this.startCheck({ autoDownload: state.updatePreferences.autoDownload });
|
|
109
109
|
};
|
|
110
110
|
startCheck = async (options) => {
|
|
111
|
-
if (this.activeTask)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
111
|
+
if (!this.activeTask) {
|
|
112
|
+
this.setSnapshot({
|
|
113
|
+
...this.createManager().getSnapshot(),
|
|
114
|
+
status: "checking",
|
|
115
|
+
progress: null,
|
|
116
|
+
errorMessage: null
|
|
117
|
+
});
|
|
118
|
+
this.activeTask = (async () => {
|
|
119
|
+
try {
|
|
120
|
+
const checkedSnapshot = await this.createManager().checkForUpdate();
|
|
121
|
+
this.setSnapshot(checkedSnapshot);
|
|
122
|
+
if (options.autoDownload && checkedSnapshot.status === "update-available") await this.runDownloadTask();
|
|
123
|
+
} catch (error) {
|
|
124
|
+
this.setSnapshot(this.toFailedSnapshot(error));
|
|
125
|
+
} finally {
|
|
126
|
+
this.activeTask = null;
|
|
127
|
+
}
|
|
128
|
+
})();
|
|
129
|
+
}
|
|
130
|
+
await this.activeTask;
|
|
129
131
|
return this.snapshot;
|
|
130
132
|
};
|
|
131
133
|
startDownload = async () => {
|
|
132
|
-
if (this.activeTask)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
134
|
+
if (!this.activeTask) {
|
|
135
|
+
this.setSnapshot({
|
|
136
|
+
...this.createManager().getSnapshot(),
|
|
137
|
+
status: "downloading",
|
|
138
|
+
progress: INITIAL_DOWNLOAD_PROGRESS,
|
|
139
|
+
errorMessage: null
|
|
140
|
+
});
|
|
141
|
+
this.activeTask = (async () => {
|
|
142
|
+
try {
|
|
143
|
+
await this.runDownloadTask();
|
|
144
|
+
} catch (error) {
|
|
145
|
+
this.setSnapshot(this.toFailedSnapshot(error));
|
|
146
|
+
} finally {
|
|
147
|
+
this.activeTask = null;
|
|
148
|
+
}
|
|
149
|
+
})();
|
|
150
|
+
}
|
|
151
|
+
await this.activeTask;
|
|
148
152
|
return this.snapshot;
|
|
149
153
|
};
|
|
150
154
|
runDownloadTask = async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm-runtime-update-host.service.js","names":[],"sources":["../../../src/services/runtime/npm-runtime-update-host.service.ts"],"sourcesContent":["import type { Config } from \"@nextclaw/core\";\nimport {\n eventKeys,\n type EventBus,\n type UpdatePreferences,\n type UpdateProgress,\n type UpdateSnapshot,\n} from \"@nextclaw/shared\";\nimport type { UiRuntimeUpdateHost } from \"@nextclaw/server\";\nimport { NpmRuntimeBundleLayoutStore } from \"@nextclaw-service/stores/npm-runtime-bundle-layout.store.js\";\nimport { NpmRuntimeBundleService } from \"@nextclaw-service/services/runtime/npm-runtime-bundle.service.js\";\nimport { RuntimeUpdateManager } from \"@nextclaw-service/managers/runtime-update.manager.js\";\nimport { NpmRuntimeUpdateService } from \"@nextclaw-service/services/runtime/npm-runtime-update.service.js\";\nimport { NpmRuntimeUpdateSourceService } from \"@nextclaw-service/services/runtime/npm-runtime-update-source.service.js\";\nimport { NpmRuntimeUpdateStateStore } from \"@nextclaw-service/stores/npm-runtime-update-state.store.js\";\nimport { NextclawDistributionService } from \"@nextclaw-service/services/runtime/nextclaw-distribution.service.js\";\nimport { requestManagedServiceRestart } from \"@nextclaw-service/services/ui/service-remote-access.service.js\";\nimport type { RequestRestartParams } from \"@nextclaw-service/types/cli.types.js\";\n\nconst INITIAL_DOWNLOAD_PROGRESS: UpdateProgress = {\n downloadedBytes: 0,\n totalBytes: null,\n percent: null\n};\n\ntype NpmRuntimeUpdateHostDeps = {\n eventBus: EventBus;\n requestRestart: (params: RequestRestartParams) => Promise<void>;\n uiConfig: Pick<Config[\"ui\"], \"port\">;\n applyRestartMode: \"managed-service-restart\" | \"manual-process-restart\";\n};\n\nexport class NpmRuntimeUpdateHost implements UiRuntimeUpdateHost {\n private readonly source: NpmRuntimeUpdateSourceService;\n private readonly layout: NpmRuntimeBundleLayoutStore;\n private readonly launcherVersion: string;\n private readonly stateStore: NpmRuntimeUpdateStateStore;\n private readonly bundleService: NpmRuntimeBundleService;\n private readonly updateService: NpmRuntimeUpdateService;\n private snapshot: UpdateSnapshot;\n private activeTask: Promise<void> | null = null;\n private automaticSyncStarted = false;\n\n constructor(private readonly deps: NpmRuntimeUpdateHostDeps) {\n const distribution = NextclawDistributionService.get();\n this.source = new NpmRuntimeUpdateSourceService({\n packagedPublicKeyPath: distribution.runtimeUpdatePublicKeyPath\n });\n this.layout = new NpmRuntimeBundleLayoutStore();\n this.launcherVersion = distribution.version;\n this.stateStore = new NpmRuntimeUpdateStateStore(this.layout.getStatePath(), {\n defaultChannel: this.source.resolveChannel(undefined, this.launcherVersion)\n });\n this.bundleService = new NpmRuntimeBundleService({\n layout: this.layout,\n stateStore: this.stateStore,\n launcherVersion: this.launcherVersion\n });\n this.updateService = new NpmRuntimeUpdateService({\n layout: this.layout,\n bundleService: this.bundleService,\n launcherVersion: this.launcherVersion,\n bundlePublicKey: this.source.resolveBundlePublicKey() ?? undefined\n });\n this.snapshot = this.createManager().getSnapshot();\n this.startAutomaticSync();\n }\n\n getState = async (): Promise<UpdateSnapshot> => {\n this.startAutomaticSync();\n return this.snapshot;\n };\n\n checkForUpdates = async (): Promise<UpdateSnapshot> => {\n return this.startCheck({ autoDownload: false });\n };\n\n downloadUpdate = async (): Promise<UpdateSnapshot> => {\n return this.startDownload();\n };\n\n applyDownloadedUpdate = async (): Promise<UpdateSnapshot> => {\n if (this.activeTask) {\n return this.snapshot;\n }\n\n this.setSnapshot({\n ...this.snapshot,\n status: \"applying\",\n progress: null,\n errorMessage: null\n });\n try {\n const snapshot = this.createManager().applyDownloadedUpdate();\n this.setSnapshot(\n this.deps.applyRestartMode === \"managed-service-restart\"\n ? snapshot\n : {\n ...snapshot,\n recoveryCommand: \"Restart this NextClaw process to launch the downloaded runtime.\"\n },\n );\n if (this.deps.applyRestartMode === \"managed-service-restart\") {\n await requestManagedServiceRestart(this.deps.requestRestart, {\n reason: \"runtime update apply\",\n uiPort: this.deps.uiConfig.port\n });\n }\n return this.snapshot;\n } catch (error) {\n this.setSnapshot(this.toFailedSnapshot(error));\n throw error;\n }\n };\n\n updatePreferences = async (preferences: Partial<UpdatePreferences>): Promise<UpdateSnapshot> => {\n const nextState = this.stateStore.update((current) => ({\n ...current,\n updatePreferences: {\n ...current.updatePreferences,\n ...preferences\n }\n }));\n this.setSnapshot(this.createManager(nextState.channel).getSnapshot());\n if (nextState.updatePreferences.automaticChecks) {\n this.startAutomaticSync({ force: true });\n }\n return this.snapshot;\n };\n\n updateChannel = async (channel: UpdateSnapshot[\"channel\"]): Promise<UpdateSnapshot> => {\n const nextState = this.stateStore.update((current) => ({\n ...current,\n channel\n }));\n this.setSnapshot(this.createManager(nextState.channel).getSnapshot());\n if (nextState.updatePreferences.automaticChecks) {\n return this.startCheck({ autoDownload: nextState.updatePreferences.autoDownload });\n }\n return this.snapshot;\n };\n\n private startAutomaticSync = (options: { force?: boolean } = {}): void => {\n if (this.activeTask) {\n return;\n }\n if (this.automaticSyncStarted && !options.force) {\n return;\n }\n this.automaticSyncStarted = true;\n const state = this.stateStore.read();\n if (!state.updatePreferences.automaticChecks || state.downloadedVersion) {\n return;\n }\n void this.startCheck({ autoDownload: state.updatePreferences.autoDownload });\n };\n\n private startCheck = async (options: { autoDownload: boolean }): Promise<UpdateSnapshot> => {\n if (this.activeTask) {\n return this.snapshot;\n }\n\n this.setSnapshot({\n ...this.createManager().getSnapshot(),\n status: \"checking\",\n progress: null,\n errorMessage: null\n });\n this.activeTask = (async () => {\n try {\n const checkedSnapshot = await this.createManager().checkForUpdate();\n this.setSnapshot(checkedSnapshot);\n if (options.autoDownload && checkedSnapshot.status === \"update-available\") {\n await this.runDownloadTask();\n }\n } catch (error) {\n this.setSnapshot(this.toFailedSnapshot(error));\n } finally {\n this.activeTask = null;\n }\n })();\n return this.snapshot;\n };\n\n private startDownload = async (): Promise<UpdateSnapshot> => {\n if (this.activeTask) {\n return this.snapshot;\n }\n\n this.setSnapshot({\n ...this.createManager().getSnapshot(),\n status: \"downloading\",\n progress: INITIAL_DOWNLOAD_PROGRESS,\n errorMessage: null\n });\n this.activeTask = (async () => {\n try {\n await this.runDownloadTask();\n } catch (error) {\n this.setSnapshot(this.toFailedSnapshot(error));\n } finally {\n this.activeTask = null;\n }\n })();\n return this.snapshot;\n };\n\n private runDownloadTask = async (): Promise<void> => {\n const downloadedSnapshot = await this.createManager().downloadUpdate((progress) => {\n this.setSnapshot({\n ...this.snapshot,\n status: \"downloading\",\n progress,\n errorMessage: null\n });\n });\n this.setSnapshot(downloadedSnapshot);\n };\n\n private createManager = (channel = this.stateStore.read().channel): RuntimeUpdateManager => {\n return new RuntimeUpdateManager({\n layout: this.layout,\n stateStore: this.stateStore,\n bundleService: this.bundleService,\n updateService: this.updateService,\n resolveManifestUrl: (resolvedChannel) => this.source.resolveManifestUrl(resolvedChannel),\n launcherVersion: this.launcherVersion,\n channel\n });\n };\n\n private toFailedSnapshot = (error: unknown): UpdateSnapshot => {\n return {\n ...this.createManager().getSnapshot(),\n status: \"failed\",\n progress: null,\n errorMessage: error instanceof Error ? error.message : String(error ?? \"Unknown error\")\n };\n };\n\n private setSnapshot = (snapshot: UpdateSnapshot): UpdateSnapshot => {\n this.snapshot = snapshot;\n this.deps.eventBus.emit(eventKeys.runtimeUpdateSnapshot, snapshot, {\n source: \"backend\"\n });\n return snapshot;\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"npm-runtime-update-host.service.js","names":[],"sources":["../../../src/services/runtime/npm-runtime-update-host.service.ts"],"sourcesContent":["import type { Config } from \"@nextclaw/core\";\nimport {\n eventKeys,\n type EventBus,\n type UpdatePreferences,\n type UpdateProgress,\n type UpdateSnapshot,\n} from \"@nextclaw/shared\";\nimport type { UiRuntimeUpdateHost } from \"@nextclaw/server\";\nimport { NpmRuntimeBundleLayoutStore } from \"@nextclaw-service/stores/npm-runtime-bundle-layout.store.js\";\nimport { NpmRuntimeBundleService } from \"@nextclaw-service/services/runtime/npm-runtime-bundle.service.js\";\nimport { RuntimeUpdateManager } from \"@nextclaw-service/managers/runtime-update.manager.js\";\nimport { NpmRuntimeUpdateService } from \"@nextclaw-service/services/runtime/npm-runtime-update.service.js\";\nimport { NpmRuntimeUpdateSourceService } from \"@nextclaw-service/services/runtime/npm-runtime-update-source.service.js\";\nimport { NpmRuntimeUpdateStateStore } from \"@nextclaw-service/stores/npm-runtime-update-state.store.js\";\nimport { NextclawDistributionService } from \"@nextclaw-service/services/runtime/nextclaw-distribution.service.js\";\nimport { requestManagedServiceRestart } from \"@nextclaw-service/services/ui/service-remote-access.service.js\";\nimport type { RequestRestartParams } from \"@nextclaw-service/types/cli.types.js\";\n\nconst INITIAL_DOWNLOAD_PROGRESS: UpdateProgress = {\n downloadedBytes: 0,\n totalBytes: null,\n percent: null\n};\n\ntype NpmRuntimeUpdateHostDeps = {\n eventBus: EventBus;\n requestRestart: (params: RequestRestartParams) => Promise<void>;\n uiConfig: Pick<Config[\"ui\"], \"port\">;\n applyRestartMode: \"managed-service-restart\" | \"manual-process-restart\";\n};\n\nexport class NpmRuntimeUpdateHost implements UiRuntimeUpdateHost {\n private readonly source: NpmRuntimeUpdateSourceService;\n private readonly layout: NpmRuntimeBundleLayoutStore;\n private readonly launcherVersion: string;\n private readonly stateStore: NpmRuntimeUpdateStateStore;\n private readonly bundleService: NpmRuntimeBundleService;\n private readonly updateService: NpmRuntimeUpdateService;\n private snapshot: UpdateSnapshot;\n private activeTask: Promise<void> | null = null;\n private automaticSyncStarted = false;\n\n constructor(private readonly deps: NpmRuntimeUpdateHostDeps) {\n const distribution = NextclawDistributionService.get();\n this.source = new NpmRuntimeUpdateSourceService({\n packagedPublicKeyPath: distribution.runtimeUpdatePublicKeyPath\n });\n this.layout = new NpmRuntimeBundleLayoutStore();\n this.launcherVersion = distribution.version;\n this.stateStore = new NpmRuntimeUpdateStateStore(this.layout.getStatePath(), {\n defaultChannel: this.source.resolveChannel(undefined, this.launcherVersion)\n });\n this.bundleService = new NpmRuntimeBundleService({\n layout: this.layout,\n stateStore: this.stateStore,\n launcherVersion: this.launcherVersion\n });\n this.updateService = new NpmRuntimeUpdateService({\n layout: this.layout,\n bundleService: this.bundleService,\n launcherVersion: this.launcherVersion,\n bundlePublicKey: this.source.resolveBundlePublicKey() ?? undefined\n });\n this.snapshot = this.createManager().getSnapshot();\n this.startAutomaticSync();\n }\n\n getState = async (): Promise<UpdateSnapshot> => {\n this.startAutomaticSync();\n return this.snapshot;\n };\n\n checkForUpdates = async (): Promise<UpdateSnapshot> => {\n return this.startCheck({ autoDownload: false });\n };\n\n downloadUpdate = async (): Promise<UpdateSnapshot> => {\n return this.startDownload();\n };\n\n applyDownloadedUpdate = async (): Promise<UpdateSnapshot> => {\n if (this.activeTask) {\n return this.snapshot;\n }\n\n this.setSnapshot({\n ...this.snapshot,\n status: \"applying\",\n progress: null,\n errorMessage: null\n });\n try {\n const snapshot = this.createManager().applyDownloadedUpdate();\n this.setSnapshot(\n this.deps.applyRestartMode === \"managed-service-restart\"\n ? snapshot\n : {\n ...snapshot,\n recoveryCommand: \"Restart this NextClaw process to launch the downloaded runtime.\"\n },\n );\n if (this.deps.applyRestartMode === \"managed-service-restart\") {\n await requestManagedServiceRestart(this.deps.requestRestart, {\n reason: \"runtime update apply\",\n uiPort: this.deps.uiConfig.port\n });\n }\n return this.snapshot;\n } catch (error) {\n this.setSnapshot(this.toFailedSnapshot(error));\n throw error;\n }\n };\n\n updatePreferences = async (preferences: Partial<UpdatePreferences>): Promise<UpdateSnapshot> => {\n const nextState = this.stateStore.update((current) => ({\n ...current,\n updatePreferences: {\n ...current.updatePreferences,\n ...preferences\n }\n }));\n this.setSnapshot(this.createManager(nextState.channel).getSnapshot());\n if (nextState.updatePreferences.automaticChecks) {\n this.startAutomaticSync({ force: true });\n }\n return this.snapshot;\n };\n\n updateChannel = async (channel: UpdateSnapshot[\"channel\"]): Promise<UpdateSnapshot> => {\n const nextState = this.stateStore.update((current) => ({\n ...current,\n channel\n }));\n this.setSnapshot(this.createManager(nextState.channel).getSnapshot());\n if (nextState.updatePreferences.automaticChecks) {\n return this.startCheck({ autoDownload: nextState.updatePreferences.autoDownload });\n }\n return this.snapshot;\n };\n\n private startAutomaticSync = (options: { force?: boolean } = {}): void => {\n if (this.activeTask) {\n return;\n }\n if (this.automaticSyncStarted && !options.force) {\n return;\n }\n this.automaticSyncStarted = true;\n const state = this.stateStore.read();\n if (!state.updatePreferences.automaticChecks || state.downloadedVersion) {\n return;\n }\n void this.startCheck({ autoDownload: state.updatePreferences.autoDownload });\n };\n\n private startCheck = async (options: { autoDownload: boolean }): Promise<UpdateSnapshot> => {\n if (!this.activeTask) {\n this.setSnapshot({\n ...this.createManager().getSnapshot(),\n status: \"checking\",\n progress: null,\n errorMessage: null\n });\n this.activeTask = (async () => {\n try {\n const checkedSnapshot = await this.createManager().checkForUpdate();\n this.setSnapshot(checkedSnapshot);\n if (options.autoDownload && checkedSnapshot.status === \"update-available\") {\n await this.runDownloadTask();\n }\n } catch (error) {\n this.setSnapshot(this.toFailedSnapshot(error));\n } finally {\n this.activeTask = null;\n }\n })();\n }\n await this.activeTask;\n return this.snapshot;\n };\n\n private startDownload = async (): Promise<UpdateSnapshot> => {\n if (!this.activeTask) {\n this.setSnapshot({\n ...this.createManager().getSnapshot(),\n status: \"downloading\",\n progress: INITIAL_DOWNLOAD_PROGRESS,\n errorMessage: null\n });\n this.activeTask = (async () => {\n try {\n await this.runDownloadTask();\n } catch (error) {\n this.setSnapshot(this.toFailedSnapshot(error));\n } finally {\n this.activeTask = null;\n }\n })();\n }\n await this.activeTask;\n return this.snapshot;\n };\n\n private runDownloadTask = async (): Promise<void> => {\n const downloadedSnapshot = await this.createManager().downloadUpdate((progress) => {\n this.setSnapshot({\n ...this.snapshot,\n status: \"downloading\",\n progress,\n errorMessage: null\n });\n });\n this.setSnapshot(downloadedSnapshot);\n };\n\n private createManager = (channel = this.stateStore.read().channel): RuntimeUpdateManager => {\n return new RuntimeUpdateManager({\n layout: this.layout,\n stateStore: this.stateStore,\n bundleService: this.bundleService,\n updateService: this.updateService,\n resolveManifestUrl: (resolvedChannel) => this.source.resolveManifestUrl(resolvedChannel),\n launcherVersion: this.launcherVersion,\n channel\n });\n };\n\n private toFailedSnapshot = (error: unknown): UpdateSnapshot => {\n return {\n ...this.createManager().getSnapshot(),\n status: \"failed\",\n progress: null,\n errorMessage: error instanceof Error ? error.message : String(error ?? \"Unknown error\")\n };\n };\n\n private setSnapshot = (snapshot: UpdateSnapshot): UpdateSnapshot => {\n this.snapshot = snapshot;\n this.deps.eventBus.emit(eventKeys.runtimeUpdateSnapshot, snapshot, {\n source: \"backend\"\n });\n return snapshot;\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distribution.types.d.ts","names":[],"sources":["../../src/types/distribution.types.ts"],"mappings":";KAAY,oBAAA;EACV,OAAA;EACA,
|
|
1
|
+
{"version":3,"file":"distribution.types.d.ts","names":[],"sources":["../../src/types/distribution.types.ts"],"mappings":";KAAY,oBAAA;EACV,OAAA;EACA,aAAA;EACA,kBAAA;EACA,SAAA;EACA,0BAAA;AAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/service",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "NextClaw long-running service host and runtime lifecycle.",
|
|
6
6
|
"type": "module",
|
|
@@ -42,31 +42,31 @@
|
|
|
42
42
|
"chokidar": "^3.6.0",
|
|
43
43
|
"commander": "^12.1.0",
|
|
44
44
|
"jszip": "^3.10.1",
|
|
45
|
-
"@nextclaw/channel-extension-
|
|
46
|
-
"@nextclaw/channel-extension-
|
|
47
|
-
"@nextclaw/channel-extension-
|
|
48
|
-
"@nextclaw/channel-extension-
|
|
49
|
-
"@nextclaw/channel-extension-qq": "0.2.
|
|
50
|
-
"@nextclaw/channel-extension-slack": "0.2.
|
|
51
|
-
"@nextclaw/channel-extension-telegram": "0.2.
|
|
52
|
-
"@nextclaw/channel-extension-whatsapp": "0.2.
|
|
53
|
-
"@nextclaw/
|
|
54
|
-
"@nextclaw/channel-extension-weixin": "0.2.
|
|
55
|
-
"@nextclaw/
|
|
56
|
-
"@nextclaw/
|
|
57
|
-
"@nextclaw/
|
|
58
|
-
"@nextclaw/
|
|
59
|
-
"@nextclaw/ncp": "0.
|
|
60
|
-
"@nextclaw/
|
|
61
|
-
"@nextclaw/
|
|
62
|
-
"@nextclaw/ncp-
|
|
63
|
-
"@nextclaw/nextclaw-ncp-runtime-
|
|
64
|
-
"@nextclaw/
|
|
65
|
-
"@nextclaw/nextclaw-
|
|
66
|
-
"@nextclaw/
|
|
67
|
-
"@nextclaw/
|
|
68
|
-
"@nextclaw/server": "0.15.
|
|
69
|
-
"@nextclaw/
|
|
45
|
+
"@nextclaw/channel-extension-discord": "0.2.5",
|
|
46
|
+
"@nextclaw/channel-extension-dingtalk": "0.2.5",
|
|
47
|
+
"@nextclaw/channel-extension-email": "0.2.5",
|
|
48
|
+
"@nextclaw/channel-extension-feishu": "0.2.5",
|
|
49
|
+
"@nextclaw/channel-extension-qq": "0.2.4",
|
|
50
|
+
"@nextclaw/channel-extension-slack": "0.2.5",
|
|
51
|
+
"@nextclaw/channel-extension-telegram": "0.2.5",
|
|
52
|
+
"@nextclaw/channel-extension-whatsapp": "0.2.5",
|
|
53
|
+
"@nextclaw/core": "0.15.5",
|
|
54
|
+
"@nextclaw/channel-extension-weixin": "0.2.5",
|
|
55
|
+
"@nextclaw/client-sdk": "0.5.6",
|
|
56
|
+
"@nextclaw/mcp": "0.3.5",
|
|
57
|
+
"@nextclaw/ncp": "0.7.4",
|
|
58
|
+
"@nextclaw/kernel": "0.6.6",
|
|
59
|
+
"@nextclaw/ncp-agent-runtime": "0.4.4",
|
|
60
|
+
"@nextclaw/nextclaw-hermes-acp-bridge": "0.3.4",
|
|
61
|
+
"@nextclaw/ncp-toolkit": "0.6.5",
|
|
62
|
+
"@nextclaw/ncp-mcp": "0.2.5",
|
|
63
|
+
"@nextclaw/nextclaw-ncp-runtime-http-client": "0.3.4",
|
|
64
|
+
"@nextclaw/runtime": "0.4.5",
|
|
65
|
+
"@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.3.6",
|
|
66
|
+
"@nextclaw/remote": "0.3.6",
|
|
67
|
+
"@nextclaw/shared": "0.4.4",
|
|
68
|
+
"@nextclaw/server": "0.15.6",
|
|
69
|
+
"@nextclaw/channel-extension-wecom": "0.2.5"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^20.17.6",
|