vibe-coding-master 0.0.5 → 0.0.7

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 (42) hide show
  1. package/README.md +168 -63
  2. package/dist/backend/adapters/translation-provider.js +145 -0
  3. package/dist/backend/api/artifact-routes.js +3 -0
  4. package/dist/backend/api/harness-routes.js +22 -0
  5. package/dist/backend/api/project-routes.js +3 -8
  6. package/dist/backend/api/translation-routes.js +70 -0
  7. package/dist/backend/runtime/node-pty-runtime.js +20 -18
  8. package/dist/backend/server.js +31 -1
  9. package/dist/backend/services/app-settings-service.js +128 -0
  10. package/dist/backend/services/artifact-service.js +7 -4
  11. package/dist/backend/services/claude-transcript-service.js +509 -0
  12. package/dist/backend/services/harness-service.js +178 -0
  13. package/dist/backend/services/project-service.js +4 -0
  14. package/dist/backend/services/session-service.js +7 -5
  15. package/dist/backend/services/status-service.js +76 -0
  16. package/dist/backend/services/translation-prompts.js +173 -0
  17. package/dist/backend/services/translation-queue.js +39 -0
  18. package/dist/backend/services/translation-service.js +546 -0
  19. package/dist/backend/templates/handoff.js +32 -0
  20. package/dist/backend/templates/harness/architect-agent.js +12 -0
  21. package/dist/backend/templates/harness/claude-root.js +14 -0
  22. package/dist/backend/templates/harness/coder-agent.js +11 -0
  23. package/dist/backend/templates/harness/project-manager-agent.js +14 -0
  24. package/dist/backend/templates/harness/reviewer-agent.js +13 -0
  25. package/dist/backend/ws/translation-ws.js +35 -0
  26. package/dist/shared/types/harness.js +1 -0
  27. package/dist/shared/types/translation.js +5 -0
  28. package/dist/shared/validation/artifact-check.js +15 -1
  29. package/dist/shared/validation/language-detect.js +46 -0
  30. package/dist-frontend/assets/index-BNASqKEK.css +32 -0
  31. package/dist-frontend/assets/index-Bp49_End.js +58 -0
  32. package/dist-frontend/index.html +2 -2
  33. package/docs/cc-best-practices.md +93 -36
  34. package/docs/product-design.md +313 -1408
  35. package/docs/v1-architecture-design.md +500 -1153
  36. package/docs/v1-implementation-plan.md +783 -1604
  37. package/package.json +3 -1
  38. package/scripts/verify-package.mjs +121 -0
  39. package/dist/backend/templates/role-messaging-context.js +0 -44
  40. package/dist-frontend/assets/index-Bah6k-Ix.css +0 -32
  41. package/dist-frontend/assets/index-EMaQuIB6.js +0 -58
  42. package/docs/v1-message-bus-orchestration-design.md +0 -534
@@ -8,20 +8,28 @@ import { createClaudeAdapter } from "./adapters/claude-adapter.js";
8
8
  import { createCommandRunner } from "./adapters/command-runner.js";
9
9
  import { createCommandDispatcher } from "./services/command-dispatcher.js";
10
10
  import { createGitAdapter } from "./adapters/git-adapter.js";
11
+ import { createAppSettingsService } from "./services/app-settings-service.js";
12
+ import { createClaudeTranscriptService } from "./services/claude-transcript-service.js";
13
+ import { createHarnessService } from "./services/harness-service.js";
11
14
  import { createNodeFileSystemAdapter } from "./adapters/filesystem.js";
12
15
  import { createNodePtyTerminalRuntime } from "./runtime/node-pty-runtime.js";
16
+ import { createOpenAiCompatibleTranslationProvider } from "./adapters/translation-provider.js";
13
17
  import { createProjectService } from "./services/project-service.js";
14
18
  import { createSessionRegistry } from "./runtime/session-registry.js";
15
19
  import { createSessionService } from "./services/session-service.js";
16
20
  import { createMessageService } from "./services/message-service.js";
17
21
  import { createStatusService } from "./services/status-service.js";
18
22
  import { createTaskService } from "./services/task-service.js";
23
+ import { createTranslationService } from "./services/translation-service.js";
19
24
  import { registerArtifactRoutes } from "./api/artifact-routes.js";
25
+ import { registerHarnessRoutes } from "./api/harness-routes.js";
20
26
  import { registerMessageRoutes } from "./api/message-routes.js";
21
27
  import { registerProjectRoutes } from "./api/project-routes.js";
22
28
  import { registerSessionRoutes } from "./api/session-routes.js";
23
29
  import { registerTaskRoutes } from "./api/task-routes.js";
30
+ import { registerTranslationRoutes } from "./api/translation-routes.js";
24
31
  import { registerTerminalWs } from "./ws/terminal-ws.js";
32
+ import { registerTranslationWs } from "./ws/translation-ws.js";
25
33
  import { toVcmError } from "./errors.js";
26
34
  export async function createServer(deps, options = {}) {
27
35
  const app = Fastify({
@@ -38,6 +46,10 @@ export async function createServer(deps, options = {}) {
38
46
  });
39
47
  });
40
48
  registerProjectRoutes(app, { projectService: deps.projectService });
49
+ registerHarnessRoutes(app, {
50
+ projectService: deps.projectService,
51
+ harnessService: deps.harnessService
52
+ });
41
53
  registerTaskRoutes(app, {
42
54
  projectService: deps.projectService,
43
55
  taskService: deps.taskService,
@@ -58,7 +70,13 @@ export async function createServer(deps, options = {}) {
58
70
  taskService: deps.taskService,
59
71
  messageService: deps.messageService
60
72
  });
73
+ registerTranslationRoutes(app, {
74
+ projectService: deps.projectService,
75
+ taskService: deps.taskService,
76
+ translationService: deps.translationService
77
+ });
61
78
  registerTerminalWs(app, { runtime: deps.runtime });
79
+ registerTranslationWs(app, { translationService: deps.translationService });
62
80
  if (options.staticDir) {
63
81
  await app.register(fastifyStatic, {
64
82
  root: options.staticDir,
@@ -90,10 +108,12 @@ export function createDefaultServerDeps(options = {}) {
90
108
  const runner = createCommandRunner();
91
109
  const git = createGitAdapter(runner);
92
110
  const claude = createClaudeAdapter(runner);
111
+ const appSettings = createAppSettingsService({ fs });
93
112
  const runtime = createNodePtyTerminalRuntime({ fs });
94
113
  const registry = createSessionRegistry();
95
114
  const artifactService = createArtifactService(fs);
96
- const projectService = createProjectService({ fs, git, claude });
115
+ const harnessService = createHarnessService({ fs });
116
+ const projectService = createProjectService({ fs, git, claude, appSettings });
97
117
  const taskService = createTaskService({ fs, git, artifactService, projectService });
98
118
  const sessionService = createSessionService({
99
119
  fs,
@@ -123,14 +143,24 @@ export function createDefaultServerDeps(options = {}) {
123
143
  sessionService,
124
144
  taskService
125
145
  });
146
+ const translationService = createTranslationService({
147
+ runtime,
148
+ sessionRegistry: registry,
149
+ transcripts: createClaudeTranscriptService(),
150
+ sessionService,
151
+ appSettings,
152
+ provider: createOpenAiCompatibleTranslationProvider()
153
+ });
126
154
  return {
127
155
  projectService,
128
156
  taskService,
129
157
  sessionService,
130
158
  artifactService,
159
+ harnessService,
131
160
  commandDispatcher,
132
161
  messageService,
133
162
  statusService,
163
+ translationService,
134
164
  runtime
135
165
  };
136
166
  }
@@ -0,0 +1,128 @@
1
+ import path from "node:path";
2
+ import { homedir } from "node:os";
3
+ const MAX_RECENT_REPOSITORIES = 5;
4
+ export function createAppSettingsService(deps) {
5
+ const settingsPath = deps.settingsPath ?? path.join(homedir(), ".vcm", "settings.json");
6
+ const legacySettingsPath = deps.legacySettingsPath
7
+ ?? path.join(homedir(), ".vibe-coding-master", "settings.json");
8
+ const legacyTranslationPath = deps.legacyTranslationPath
9
+ ?? path.join(homedir(), ".vibe-coding-master", "translation.json");
10
+ let cachedSettings = null;
11
+ async function loadSettings() {
12
+ if (cachedSettings) {
13
+ return cachedSettings;
14
+ }
15
+ let raw = {};
16
+ let shouldSave = false;
17
+ if (await deps.fs.pathExists(settingsPath)) {
18
+ raw = await deps.fs.readJson(settingsPath);
19
+ }
20
+ else if (await deps.fs.pathExists(legacySettingsPath)) {
21
+ raw = await deps.fs.readJson(legacySettingsPath);
22
+ shouldSave = true;
23
+ }
24
+ else {
25
+ shouldSave = true;
26
+ }
27
+ if (!raw.translation && await deps.fs.pathExists(legacyTranslationPath)) {
28
+ raw = {
29
+ ...raw,
30
+ translation: normalizeTranslationConfig(await deps.fs.readJson(legacyTranslationPath))
31
+ };
32
+ shouldSave = true;
33
+ }
34
+ cachedSettings = normalizeSettingsFile(raw);
35
+ if (shouldSave) {
36
+ await saveSettings(cachedSettings);
37
+ }
38
+ return cachedSettings;
39
+ }
40
+ async function saveSettings(settings) {
41
+ cachedSettings = settings;
42
+ await deps.fs.writeJsonAtomic(settingsPath, settings);
43
+ }
44
+ return {
45
+ loadSettings,
46
+ async updateTranslationConfig(config) {
47
+ const current = await loadSettings();
48
+ const translation = normalizeTranslationConfig(config) ?? { settings: {}, secrets: {} };
49
+ await saveSettings({
50
+ ...current,
51
+ translation
52
+ });
53
+ return translation;
54
+ },
55
+ async getTranslationConfig() {
56
+ return (await loadSettings()).translation;
57
+ },
58
+ async getRecentRepositoryPaths() {
59
+ return (await loadSettings()).recentRepositoryPaths;
60
+ },
61
+ async recordRecentRepositoryPath(repoRoot) {
62
+ const normalizedPath = repoRoot.trim();
63
+ if (!normalizedPath) {
64
+ return (await loadSettings()).recentRepositoryPaths;
65
+ }
66
+ const current = await loadSettings();
67
+ const recentRepositoryPaths = normalizeRecentRepositoryPaths([
68
+ normalizedPath,
69
+ ...current.recentRepositoryPaths
70
+ ]);
71
+ await saveSettings({
72
+ ...current,
73
+ recentRepositoryPaths
74
+ });
75
+ return recentRepositoryPaths;
76
+ },
77
+ getSettingsPath() {
78
+ return settingsPath;
79
+ }
80
+ };
81
+ }
82
+ function normalizeSettingsFile(input) {
83
+ return {
84
+ version: 1,
85
+ translation: normalizeTranslationConfig(input.translation),
86
+ recentRepositoryPaths: normalizeRecentRepositoryPaths(input.recentRepositoryPaths)
87
+ };
88
+ }
89
+ function normalizeTranslationConfig(input) {
90
+ if (!input || typeof input !== "object") {
91
+ return undefined;
92
+ }
93
+ const candidate = input;
94
+ const rawSettings = isObject(candidate.settings) ? candidate.settings : {};
95
+ const rawSecrets = isObject(candidate.secrets) ? candidate.secrets : {};
96
+ const { apiKey: settingsApiKey, ...settings } = rawSettings;
97
+ const apiKey = rawSecrets.apiKey ?? settingsApiKey;
98
+ return {
99
+ settings,
100
+ secrets: {
101
+ ...rawSecrets,
102
+ ...(apiKey !== undefined ? { apiKey } : {})
103
+ }
104
+ };
105
+ }
106
+ function normalizeRecentRepositoryPaths(input) {
107
+ const paths = Array.isArray(input) ? input : [];
108
+ const seen = new Set();
109
+ const normalized = [];
110
+ for (const value of paths) {
111
+ if (typeof value !== "string") {
112
+ continue;
113
+ }
114
+ const repoPath = value.trim();
115
+ if (!repoPath || seen.has(repoPath)) {
116
+ continue;
117
+ }
118
+ seen.add(repoPath);
119
+ normalized.push(repoPath);
120
+ if (normalized.length >= MAX_RECENT_REPOSITORIES) {
121
+ break;
122
+ }
123
+ }
124
+ return normalized;
125
+ }
126
+ function isObject(value) {
127
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
128
+ }
@@ -3,13 +3,14 @@ import { DISPATCHABLE_ROLES, ROLE_NAMES } from "../../shared/constants.js";
3
3
  import { checkMarkdownArtifact } from "../../shared/validation/artifact-check.js";
4
4
  import { VcmError } from "../errors.js";
5
5
  import { resolveRepoPath } from "../adapters/filesystem.js";
6
- import { renderArchitecturePlanTemplate, renderImplementationLogTemplate, renderReviewReportTemplate, renderValidationLogTemplate } from "../templates/handoff.js";
6
+ import { renderArchitecturePlanTemplate, renderDocsSyncReportTemplate, renderImplementationLogTemplate, renderReviewReportTemplate, renderValidationLogTemplate } from "../templates/handoff.js";
7
7
  import { renderRoleCommandTemplate } from "../templates/role-command.js";
8
8
  const ARTIFACT_PATH_KEYS = [
9
9
  ["architecture-plan", "architecturePlanPath"],
10
10
  ["implementation-log", "implementationLogPath"],
11
11
  ["validation-log", "validationLogPath"],
12
- ["review-report", "reviewReportPath"]
12
+ ["review-report", "reviewReportPath"],
13
+ ["docs-sync-report", "docsSyncReportPath"]
13
14
  ];
14
15
  const ROLE_COMMAND_PLACEHOLDER_PATTERN = /(^|\n)\s*(TBD|status:\s*draft)\s*(\n|$)/i;
15
16
  export function createArtifactService(fs) {
@@ -35,7 +36,8 @@ export function createArtifactService(fs) {
35
36
  architecturePlanPath: path.posix.join(handoffDir, "architecture-plan.md"),
36
37
  implementationLogPath: path.posix.join(handoffDir, "implementation-log.md"),
37
38
  validationLogPath: path.posix.join(handoffDir, "validation-log.md"),
38
- reviewReportPath: path.posix.join(handoffDir, "review-report.md")
39
+ reviewReportPath: path.posix.join(handoffDir, "review-report.md"),
40
+ docsSyncReportPath: path.posix.join(handoffDir, "docs-sync-report.md")
39
41
  };
40
42
  },
41
43
  async ensureHandoffStructure(input) {
@@ -54,7 +56,8 @@ export function createArtifactService(fs) {
54
56
  [paths.architecturePlanPath, renderArchitecturePlanTemplate(input.taskSlug)],
55
57
  [paths.implementationLogPath, renderImplementationLogTemplate(input.taskSlug)],
56
58
  [paths.validationLogPath, renderValidationLogTemplate(input.taskSlug)],
57
- [paths.reviewReportPath, renderReviewReportTemplate(input.taskSlug)]
59
+ [paths.reviewReportPath, renderReviewReportTemplate(input.taskSlug)],
60
+ [paths.docsSyncReportPath, renderDocsSyncReportTemplate(input.taskSlug)]
58
61
  ];
59
62
  const created = [];
60
63
  for (const [artifactPath, content] of files) {