@ericsanchezok/synergy-workbench 0.0.0-stage → 3.1.0

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.
Files changed (153) hide show
  1. package/AGENTS.md +30 -0
  2. package/README.md +16 -2
  3. package/dist/agents.js +11 -0
  4. package/dist/cli-adapter.js +8 -0
  5. package/dist/component.js +65 -0
  6. package/dist/config-schema.js +265 -0
  7. package/dist/execution/activity.js +78 -0
  8. package/dist/execution/content.js +184 -0
  9. package/dist/execution/json-sections.js +231 -0
  10. package/dist/execution/presentation.js +79 -0
  11. package/dist/execution/preview.js +13 -0
  12. package/dist/execution/process.js +125 -0
  13. package/dist/execution/projection.js +327 -0
  14. package/dist/execution/query.js +18 -0
  15. package/dist/execution/routes.js +189 -0
  16. package/dist/execution/schema.js +322 -0
  17. package/dist/execution/service.js +1993 -0
  18. package/dist/features.js +22 -0
  19. package/dist/http.js +65 -0
  20. package/dist/performance/analysis.js +330 -0
  21. package/dist/performance/catalog.js +391 -0
  22. package/dist/performance/dashboard.js +483 -0
  23. package/dist/performance/error.js +15 -0
  24. package/dist/performance/index.js +6 -0
  25. package/dist/performance/inflight.js +43 -0
  26. package/dist/performance/projection.js +138 -0
  27. package/dist/performance/prompt/base.txt +38 -0
  28. package/dist/performance/prompt/builder.js +21 -0
  29. package/dist/performance/routes/performance-route.js +439 -0
  30. package/dist/performance/schema.js +628 -0
  31. package/dist/performance/timeline.js +98 -0
  32. package/dist/performance/trace-detail.js +91 -0
  33. package/dist/presentation/service.js +270 -0
  34. package/dist/presentation/tools/workbench-view.js +65 -0
  35. package/dist/presentation/tools.js +10 -0
  36. package/dist/project/directories.js +363 -0
  37. package/dist/project/git-health.js +498 -0
  38. package/dist/project/ide.js +66 -0
  39. package/dist/project/migration.js +22 -0
  40. package/dist/project/routes/directories.js +89 -0
  41. package/dist/project/routes/git.js +30 -0
  42. package/dist/project/routes/task-defaults.js +42 -0
  43. package/dist/project/session-health.js +9 -0
  44. package/dist/project/startup.js +28 -0
  45. package/dist/project/task-defaults.js +68 -0
  46. package/dist/project/tools/session-control.js +664 -0
  47. package/dist/project/tools/session-control.txt +60 -0
  48. package/dist/project/tools/worktree-archive.js +76 -0
  49. package/dist/project/tools/worktree-enter.js +175 -0
  50. package/dist/project/tools/worktree-leave.js +119 -0
  51. package/dist/project/tools/worktree-list.js +52 -0
  52. package/dist/project/tools.js +26 -0
  53. package/dist/project/vcs-branch-watcher.js +76 -0
  54. package/dist/project/vcs.js +114 -0
  55. package/dist/project/worktree-janitor.js +140 -0
  56. package/dist/project/worktrees.js +98 -0
  57. package/dist/push/bridge.js +171 -0
  58. package/dist/push/index.js +4 -0
  59. package/dist/push/routes/push.js +224 -0
  60. package/dist/push/service.js +93 -0
  61. package/dist/push/store.js +121 -0
  62. package/dist/push/types.js +58 -0
  63. package/dist/review/git.js +226 -0
  64. package/dist/review/routes.js +45 -0
  65. package/dist/review/schema.js +32 -0
  66. package/dist/review/state.js +79 -0
  67. package/dist/stats/aggregator.js +252 -0
  68. package/dist/stats/canonical.js +89 -0
  69. package/dist/stats/cli/stats.js +302 -0
  70. package/dist/stats/engine.js +176 -0
  71. package/dist/stats/index.js +5 -0
  72. package/dist/stats/rollup.js +460 -0
  73. package/dist/stats/routes/stats.js +94 -0
  74. package/dist/stats/routes/usage.js +83 -0
  75. package/dist/stats/storage.js +86 -0
  76. package/dist/stats/types.js +267 -0
  77. package/dist/worker.js +6 -0
  78. package/package.json +232 -4
  79. package/src/agents.ts +15 -0
  80. package/src/cli-adapter.ts +11 -0
  81. package/src/component.ts +73 -0
  82. package/src/config-schema.ts +289 -0
  83. package/src/execution/activity.ts +83 -0
  84. package/src/execution/content.ts +189 -0
  85. package/src/execution/json-sections.ts +230 -0
  86. package/src/execution/presentation.ts +91 -0
  87. package/src/execution/preview.ts +12 -0
  88. package/src/execution/process.ts +118 -0
  89. package/src/execution/projection.ts +330 -0
  90. package/src/execution/query.ts +19 -0
  91. package/src/execution/routes.ts +324 -0
  92. package/src/execution/schema.ts +336 -0
  93. package/src/execution/service.ts +2149 -0
  94. package/src/features.ts +22 -0
  95. package/src/http.ts +75 -0
  96. package/src/performance/analysis.ts +356 -0
  97. package/src/performance/catalog.ts +902 -0
  98. package/src/performance/dashboard.ts +521 -0
  99. package/src/performance/error.ts +32 -0
  100. package/src/performance/index.ts +6 -0
  101. package/src/performance/inflight.ts +46 -0
  102. package/src/performance/projection.ts +143 -0
  103. package/src/performance/prompt/base.txt +38 -0
  104. package/src/performance/prompt/builder.ts +24 -0
  105. package/src/performance/routes/performance-route.ts +541 -0
  106. package/src/performance/schema.ts +695 -0
  107. package/src/performance/timeline.ts +100 -0
  108. package/src/performance/trace-detail.ts +97 -0
  109. package/src/presentation/service.ts +303 -0
  110. package/src/presentation/tools/workbench-view.ts +75 -0
  111. package/src/presentation/tools.ts +11 -0
  112. package/src/project/directories.ts +391 -0
  113. package/src/project/git-health.ts +577 -0
  114. package/src/project/ide.ts +80 -0
  115. package/src/project/migration.ts +24 -0
  116. package/src/project/routes/directories.ts +124 -0
  117. package/src/project/routes/git.ts +42 -0
  118. package/src/project/routes/task-defaults.ts +50 -0
  119. package/src/project/session-health.ts +10 -0
  120. package/src/project/startup.ts +28 -0
  121. package/src/project/task-defaults.ts +70 -0
  122. package/src/project/tools/session-control.ts +725 -0
  123. package/src/project/tools/session-control.txt +60 -0
  124. package/src/project/tools/worktree-archive.ts +92 -0
  125. package/src/project/tools/worktree-enter.ts +227 -0
  126. package/src/project/tools/worktree-leave.ts +140 -0
  127. package/src/project/tools/worktree-list.ts +68 -0
  128. package/src/project/tools.ts +29 -0
  129. package/src/project/vcs-branch-watcher.ts +81 -0
  130. package/src/project/vcs.ts +124 -0
  131. package/src/project/worktree-janitor.ts +153 -0
  132. package/src/project/worktrees.ts +110 -0
  133. package/src/push/bridge.ts +182 -0
  134. package/src/push/index.ts +4 -0
  135. package/src/push/routes/push.ts +267 -0
  136. package/src/push/service.ts +108 -0
  137. package/src/push/store.ts +120 -0
  138. package/src/push/types.ts +67 -0
  139. package/src/review/git.ts +221 -0
  140. package/src/review/routes.ts +65 -0
  141. package/src/review/schema.ts +34 -0
  142. package/src/review/state.ts +77 -0
  143. package/src/stats/aggregator.ts +277 -0
  144. package/src/stats/canonical.ts +93 -0
  145. package/src/stats/cli/stats.ts +348 -0
  146. package/src/stats/engine.ts +197 -0
  147. package/src/stats/index.ts +5 -0
  148. package/src/stats/rollup.ts +522 -0
  149. package/src/stats/routes/stats.ts +107 -0
  150. package/src/stats/routes/usage.ts +103 -0
  151. package/src/stats/storage.ts +78 -0
  152. package/src/stats/types.ts +351 -0
  153. package/src/worker.ts +7 -0
@@ -0,0 +1,30 @@
1
+ import { Hono } from "hono";
2
+ import { describeRoute, validator } from "hono-openapi";
3
+ import { resolver } from "hono-openapi";
4
+ import z from "zod";
5
+ import { Vcs } from "@ericsanchezok/synergy-workbench/project/vcs";
6
+ import { errors } from "@ericsanchezok/synergy-server/server/error";
7
+ export const GitRoute = () => new Hono().post("/init", describeRoute({
8
+ summary: "Initialize git repository",
9
+ description: "Initialize a git repository in the specified directory if one does not already exist.",
10
+ operationId: "global.git.init",
11
+ responses: {
12
+ 200: {
13
+ description: "Git initialization result",
14
+ content: {
15
+ "application/json": {
16
+ schema: resolver(z.object({
17
+ initialized: z.boolean().meta({ description: "Whether a new git repository was initialized" }),
18
+ })),
19
+ },
20
+ },
21
+ },
22
+ ...errors(400),
23
+ },
24
+ }), validator("json", z.object({
25
+ directory: z.string().meta({ description: "Directory path to initialize git in" }),
26
+ })), async (c) => {
27
+ const { directory } = c.req.valid("json");
28
+ const initialized = await Vcs.initIfNeeded(directory);
29
+ return c.json({ initialized });
30
+ });
@@ -0,0 +1,42 @@
1
+ import { Hono } from "hono";
2
+ import { describeRoute, resolver, validator } from "hono-openapi";
3
+ import { ProjectTaskDefaults } from "../task-defaults.js";
4
+ export function ProjectTaskDefaultsRoute() {
5
+ const success = {
6
+ description: "Project task defaults",
7
+ content: { "application/json": { schema: resolver(ProjectTaskDefaults.Result) } },
8
+ };
9
+ return new Hono()
10
+ .get("/", describeRoute({
11
+ summary: "Get project new-task defaults",
12
+ operationId: "project.taskDefaults.get",
13
+ responses: { 200: success },
14
+ }), async (c) => c.json(await ProjectTaskDefaults.get()))
15
+ .patch("/", describeRoute({
16
+ summary: "Save project new-task defaults",
17
+ description: "Updates only Web and Desktop new-task defaults. Existing sessions and runtime creation rules are unchanged.",
18
+ operationId: "project.taskDefaults.update",
19
+ responses: {
20
+ 200: success,
21
+ 400: {
22
+ description: "Invalid defaults",
23
+ content: { "application/json": { schema: resolver(ProjectTaskDefaults.Invalid.Schema) } },
24
+ },
25
+ 409: {
26
+ description: "Concurrent project edit",
27
+ content: { "application/json": { schema: resolver(ProjectTaskDefaults.Conflict.Schema) } },
28
+ },
29
+ },
30
+ }), validator("json", ProjectTaskDefaults.Input), async (c) => {
31
+ try {
32
+ return c.json(await ProjectTaskDefaults.update(c.req.valid("json")));
33
+ }
34
+ catch (error) {
35
+ if (error instanceof ProjectTaskDefaults.Conflict)
36
+ return c.json(error.toObject(), 409);
37
+ if (error instanceof ProjectTaskDefaults.Invalid)
38
+ return c.json(error.toObject(), 400);
39
+ throw error;
40
+ }
41
+ });
42
+ }
@@ -0,0 +1,9 @@
1
+ import { SessionProjectHealth } from "@ericsanchezok/synergy-harness/session/project-health";
2
+ import { GitHealth } from "./git-health.js";
3
+ export function registerProjectSessionHealth() {
4
+ SessionProjectHealth.register({
5
+ isGitRepo: (cwd) => GitHealth.isGitRepo(cwd),
6
+ observeGitHealth: (cwd) => GitHealth.observeCached(cwd),
7
+ invalidateGitHealth: (cwd) => GitHealth.invalidate(cwd),
8
+ });
9
+ }
@@ -0,0 +1,28 @@
1
+ import { ScopeStartup } from "@ericsanchezok/synergy-harness/scope/startup";
2
+ import { Vcs } from "./vcs.js";
3
+ import { startWorktreeJanitor, stopWorktreeJanitor } from "./worktree-janitor.js";
4
+ /**
5
+ * H5 project startup contribution: Vcs.init moves out of scope/runtime.ts.
6
+ * It runs after the file watcher, matching the historical startup sequence.
7
+ */
8
+ export function registerProjectStartup() {
9
+ ScopeStartup.register({
10
+ name: "vcs-init",
11
+ owner: "workspace",
12
+ phase: "surface",
13
+ after: ["file-watcher"],
14
+ init: () => Vcs.init().then(() => { }),
15
+ });
16
+ // The janitor only schedules itself here; its first scan is deferred with an
17
+ // unref'd timer so neither startup latency nor process lifetime depends on it.
18
+ ScopeStartup.register({
19
+ name: "worktree-janitor",
20
+ phase: "surface",
21
+ after: ["command-watcher"],
22
+ init: (scope) => {
23
+ if (scope.type === "project")
24
+ startWorktreeJanitor(scope);
25
+ },
26
+ dispose: (scopeID) => stopWorktreeJanitor(scopeID),
27
+ });
28
+ }
@@ -0,0 +1,68 @@
1
+ import { ProjectDirectories } from "./directories.js";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ import { NamedError } from "@ericsanchezok/synergy-util/error";
5
+ import { Config } from "@ericsanchezok/synergy-harness/config/config";
6
+ import { GlobalBus } from "@ericsanchezok/synergy-harness/bus/global";
7
+ import { ScopeContext } from "@ericsanchezok/synergy-harness/scope/context";
8
+ import { ResourceProfiles } from "@ericsanchezok/synergy-local-runtime/environment/profiles";
9
+ export var ProjectTaskDefaults;
10
+ (function (ProjectTaskDefaults) {
11
+ ProjectTaskDefaults.Defaults = z
12
+ .object({
13
+ defaultSessionWorkspace: z.enum(["main", "worktree"]).optional(),
14
+ defaultSessionEnvironmentProfile: z.string().min(1).nullable().optional(),
15
+ })
16
+ .meta({ ref: "ProjectTaskDefaults" });
17
+ ProjectTaskDefaults.Result = z
18
+ .object({ defaults: ProjectTaskDefaults.Defaults, effective: ProjectTaskDefaults.Defaults, editable: z.boolean() })
19
+ .meta({ ref: "ProjectTaskDefaultsResult" });
20
+ ProjectTaskDefaults.Input = z.object({ defaults: ProjectTaskDefaults.Defaults, expected: ProjectTaskDefaults.Defaults }).meta({ ref: "ProjectTaskDefaultsInput" });
21
+ ProjectTaskDefaults.Conflict = NamedError.create("ProjectTaskDefaultsConflict", z.object({ message: z.string() }));
22
+ ProjectTaskDefaults.Invalid = NamedError.create("ProjectTaskDefaultsInvalid", z.object({ message: z.string() }));
23
+ function root() {
24
+ const scope = ScopeContext.current.scope;
25
+ return scope.type === "project" && scope.local ? path.join(scope.local.directory, ".synergy") : undefined;
26
+ }
27
+ async function get() {
28
+ const directory = root();
29
+ return {
30
+ defaults: directory ? ProjectTaskDefaults.Defaults.parse(await Config.domainGet("general", directory)) : {},
31
+ effective: ProjectTaskDefaults.Defaults.parse(await Config.current()),
32
+ editable: !!directory,
33
+ };
34
+ }
35
+ ProjectTaskDefaults.get = get;
36
+ async function update(input) {
37
+ const parsed = ProjectTaskDefaults.Input.parse(input);
38
+ const directory = root();
39
+ if (!directory)
40
+ throw new ProjectTaskDefaults.Invalid({
41
+ message: "This project inherits global settings because it has no project configuration directory.",
42
+ });
43
+ if (parsed.defaults.defaultSessionWorkspace === "worktree") {
44
+ const folders = await ProjectDirectories.get(ScopeContext.current.scope.id);
45
+ if (!folders.folders.some((folder) => folder.workspaceID === folders.mainWorkspaceID && folder.git))
46
+ throw new ProjectTaskDefaults.Invalid({ message: "Worktree requires a Git main folder." });
47
+ }
48
+ const profile = parsed.defaults.defaultSessionEnvironmentProfile;
49
+ if (profile && !(await ResourceProfiles.list()).environments.some((item) => item.name === profile))
50
+ throw new ProjectTaskDefaults.Invalid({ message: "The selected execution profile is unavailable. Choose a configured location." });
51
+ const { change } = await Config.domainMutateWithChange("general", (current) => {
52
+ if (JSON.stringify(ProjectTaskDefaults.Defaults.parse(current)) !== JSON.stringify(parsed.expected))
53
+ throw new ProjectTaskDefaults.Conflict({ message: "Project defaults changed. Reload them before saving again." });
54
+ delete current.defaultSessionWorkspace;
55
+ delete current.defaultSessionEnvironmentProfile;
56
+ return { ...current, ...parsed.defaults };
57
+ }, { root: directory, mode: "replace-domain" });
58
+ GlobalBus().emit("event", {
59
+ scopeID: ScopeContext.current.scope.id,
60
+ payload: {
61
+ type: Config.Event.Updated.type,
62
+ properties: { scope: "project", changedFields: change.changedFields },
63
+ },
64
+ });
65
+ return get();
66
+ }
67
+ ProjectTaskDefaults.update = update;
68
+ })(ProjectTaskDefaults || (ProjectTaskDefaults = {}));