@vladimirven/openswe 0.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 (117) hide show
  1. package/AGENTS.md +203 -0
  2. package/CLAUDE.md +203 -0
  3. package/README.md +166 -0
  4. package/bun.lock +447 -0
  5. package/bunfig.toml +4 -0
  6. package/package.json +42 -0
  7. package/src/app.tsx +84 -0
  8. package/src/components/App.tsx +526 -0
  9. package/src/components/ConfirmDialog.tsx +88 -0
  10. package/src/components/Footer.tsx +50 -0
  11. package/src/components/HelpModal.tsx +136 -0
  12. package/src/components/IssueSelectorModal.tsx +701 -0
  13. package/src/components/ManualSessionModal.tsx +191 -0
  14. package/src/components/PhaseProgress.tsx +45 -0
  15. package/src/components/Preview.tsx +249 -0
  16. package/src/components/ProviderSwitcherModal.tsx +156 -0
  17. package/src/components/ScrollableText.tsx +120 -0
  18. package/src/components/SessionCard.tsx +60 -0
  19. package/src/components/SessionList.tsx +79 -0
  20. package/src/components/SessionTerminal.tsx +89 -0
  21. package/src/components/StatusBar.tsx +84 -0
  22. package/src/components/ThemeSwitcherModal.tsx +237 -0
  23. package/src/components/index.ts +58 -0
  24. package/src/components/session-utils.ts +337 -0
  25. package/src/components/theme.ts +206 -0
  26. package/src/components/types.ts +215 -0
  27. package/src/config/defaults.ts +44 -0
  28. package/src/config/env.ts +67 -0
  29. package/src/config/global.ts +252 -0
  30. package/src/config/index.ts +171 -0
  31. package/src/config/types.ts +131 -0
  32. package/src/core/.gitkeep +0 -0
  33. package/src/core/index.ts +5 -0
  34. package/src/core/parser.ts +62 -0
  35. package/src/core/process-manager.ts +52 -0
  36. package/src/core/session.ts +423 -0
  37. package/src/core/tmux.ts +206 -0
  38. package/src/git/.gitkeep +0 -0
  39. package/src/git/index.ts +8 -0
  40. package/src/git/repo.ts +443 -0
  41. package/src/git/worktree.ts +317 -0
  42. package/src/github/.gitkeep +0 -0
  43. package/src/github/client.ts +208 -0
  44. package/src/github/index.ts +8 -0
  45. package/src/github/issues.ts +351 -0
  46. package/src/index.ts +369 -0
  47. package/src/prompts/.gitkeep +0 -0
  48. package/src/prompts/index.ts +1 -0
  49. package/src/prompts/swe-system.ts +22 -0
  50. package/src/providers/claude.ts +103 -0
  51. package/src/providers/index.ts +21 -0
  52. package/src/providers/opencode.ts +98 -0
  53. package/src/providers/registry.ts +53 -0
  54. package/src/providers/types.ts +117 -0
  55. package/src/store/buffers.ts +234 -0
  56. package/src/store/db.test.ts +579 -0
  57. package/src/store/db.ts +249 -0
  58. package/src/store/index.ts +101 -0
  59. package/src/store/project.ts +119 -0
  60. package/src/store/schema.sql +71 -0
  61. package/src/store/sessions.ts +454 -0
  62. package/src/store/types.ts +194 -0
  63. package/src/theme/context.tsx +170 -0
  64. package/src/theme/custom.ts +134 -0
  65. package/src/theme/index.ts +58 -0
  66. package/src/theme/loader.ts +264 -0
  67. package/src/theme/themes/aura.json +69 -0
  68. package/src/theme/themes/ayu.json +80 -0
  69. package/src/theme/themes/carbonfox.json +248 -0
  70. package/src/theme/themes/catppuccin-frappe.json +233 -0
  71. package/src/theme/themes/catppuccin-macchiato.json +233 -0
  72. package/src/theme/themes/catppuccin.json +112 -0
  73. package/src/theme/themes/cobalt2.json +228 -0
  74. package/src/theme/themes/cursor.json +249 -0
  75. package/src/theme/themes/dracula.json +219 -0
  76. package/src/theme/themes/everforest.json +241 -0
  77. package/src/theme/themes/flexoki.json +237 -0
  78. package/src/theme/themes/github.json +233 -0
  79. package/src/theme/themes/gruvbox.json +242 -0
  80. package/src/theme/themes/kanagawa.json +77 -0
  81. package/src/theme/themes/lucent-orng.json +237 -0
  82. package/src/theme/themes/material.json +235 -0
  83. package/src/theme/themes/matrix.json +77 -0
  84. package/src/theme/themes/mercury.json +252 -0
  85. package/src/theme/themes/monokai.json +221 -0
  86. package/src/theme/themes/nightowl.json +221 -0
  87. package/src/theme/themes/nord.json +223 -0
  88. package/src/theme/themes/one-dark.json +84 -0
  89. package/src/theme/themes/opencode.json +245 -0
  90. package/src/theme/themes/orng.json +249 -0
  91. package/src/theme/themes/osaka-jade.json +93 -0
  92. package/src/theme/themes/palenight.json +222 -0
  93. package/src/theme/themes/rosepine.json +234 -0
  94. package/src/theme/themes/solarized.json +223 -0
  95. package/src/theme/themes/synthwave84.json +226 -0
  96. package/src/theme/themes/tokyonight.json +243 -0
  97. package/src/theme/themes/vercel.json +245 -0
  98. package/src/theme/themes/vesper.json +218 -0
  99. package/src/theme/themes/zenburn.json +223 -0
  100. package/src/theme/types.ts +225 -0
  101. package/src/types/sql.d.ts +4 -0
  102. package/src/utils/ansi-parser.ts +225 -0
  103. package/src/utils/format.ts +46 -0
  104. package/src/utils/id.ts +15 -0
  105. package/src/utils/logger.ts +112 -0
  106. package/src/utils/prerequisites.ts +118 -0
  107. package/src/utils/shell.ts +9 -0
  108. package/src/wizard/flows.ts +419 -0
  109. package/src/wizard/index.ts +37 -0
  110. package/src/wizard/prompts.ts +190 -0
  111. package/src/workspace/detect.test.ts +51 -0
  112. package/src/workspace/detect.ts +223 -0
  113. package/src/workspace/index.ts +71 -0
  114. package/src/workspace/init.ts +131 -0
  115. package/src/workspace/paths.ts +143 -0
  116. package/src/workspace/project.ts +164 -0
  117. package/tsconfig.json +22 -0
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Project configuration
3
+ *
4
+ * Handles local project-specific state stored in .openswe/project.json.
5
+ * This is separate from the global config (~/.config/openswe/config.toml)
6
+ * and stores project-specific information like linked repo details.
7
+ */
8
+
9
+ import { join } from "path"
10
+ import { getOpenSWEDir } from "./paths"
11
+
12
+ // ============================================================================
13
+ // Types
14
+ // ============================================================================
15
+
16
+ /** Local project configuration stored in .openswe/project.json */
17
+ export interface ProjectConfig {
18
+ /** Full repository name in owner/repo format */
19
+ repoFullName: string
20
+ /** Git remote URL (SSH or HTTPS format) */
21
+ repoUrl: string
22
+ /** ISO timestamp when project was created */
23
+ createdAt: string
24
+ /** ISO timestamp when project was last opened */
25
+ lastOpenedAt: string
26
+ }
27
+
28
+ /** Project config file name */
29
+ const PROJECT_CONFIG_FILE = "project.json"
30
+
31
+ // ============================================================================
32
+ // Path Utilities
33
+ // ============================================================================
34
+
35
+ /**
36
+ * Get the path to the project config file
37
+ * @param projectRoot - Absolute path to the project root
38
+ */
39
+ export function getProjectConfigPath(projectRoot: string): string {
40
+ return join(getOpenSWEDir(projectRoot), PROJECT_CONFIG_FILE)
41
+ }
42
+
43
+ // ============================================================================
44
+ // Load/Save Functions
45
+ // ============================================================================
46
+
47
+ /**
48
+ * Load project configuration from .openswe/project.json
49
+ *
50
+ * @param projectRoot - Absolute path to the project root
51
+ * @returns Project config or null if file doesn't exist or is invalid
52
+ */
53
+ export async function loadProjectConfig(projectRoot: string): Promise<ProjectConfig | null> {
54
+ const configPath = getProjectConfigPath(projectRoot)
55
+
56
+ try {
57
+ const file = Bun.file(configPath)
58
+ if (!(await file.exists())) {
59
+ return null
60
+ }
61
+
62
+ const content = await file.text()
63
+ const parsed = JSON.parse(content) as unknown
64
+
65
+ // Basic validation
66
+ if (!isValidProjectConfig(parsed)) {
67
+ console.warn(`[OpenSWE] Invalid project config at ${configPath}`)
68
+ return null
69
+ }
70
+
71
+ return parsed
72
+ } catch (err) {
73
+ if (err instanceof SyntaxError) {
74
+ console.warn(`[OpenSWE] Failed to parse project config at ${configPath}: Invalid JSON`)
75
+ }
76
+ return null
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Save project configuration to .openswe/project.json
82
+ *
83
+ * @param projectRoot - Absolute path to the project root
84
+ * @param config - Project configuration to save
85
+ */
86
+ export async function saveProjectConfig(
87
+ projectRoot: string,
88
+ config: ProjectConfig
89
+ ): Promise<void> {
90
+ const configPath = getProjectConfigPath(projectRoot)
91
+
92
+ const content = JSON.stringify(config, null, 2)
93
+ await Bun.write(configPath, content)
94
+ }
95
+
96
+ /**
97
+ * Update the lastOpenedAt timestamp in the project config
98
+ *
99
+ * @param projectRoot - Absolute path to the project root
100
+ */
101
+ export async function updateLastOpened(projectRoot: string): Promise<void> {
102
+ const config = await loadProjectConfig(projectRoot)
103
+ if (!config) {
104
+ return // No config to update
105
+ }
106
+
107
+ config.lastOpenedAt = new Date().toISOString()
108
+ await saveProjectConfig(projectRoot, config)
109
+ }
110
+
111
+ /**
112
+ * Create a new project config with default values
113
+ *
114
+ * @param repoFullName - Repository in owner/repo format
115
+ * @param repoUrl - Git remote URL
116
+ * @param options - Optional overrides
117
+ */
118
+ export function createProjectConfig(
119
+ repoFullName: string,
120
+ repoUrl: string,
121
+ ): ProjectConfig {
122
+ const now = new Date().toISOString()
123
+ return {
124
+ repoFullName,
125
+ repoUrl,
126
+ createdAt: now,
127
+ lastOpenedAt: now,
128
+ }
129
+ }
130
+
131
+ // ============================================================================
132
+ // Validation
133
+ // ============================================================================
134
+
135
+ /**
136
+ * Type guard to validate project config structure
137
+ */
138
+ function isValidProjectConfig(value: unknown): value is ProjectConfig {
139
+ if (typeof value !== "object" || value === null) {
140
+ return false
141
+ }
142
+
143
+ const obj = value as Record<string, unknown>
144
+
145
+ return (
146
+ typeof obj.repoFullName === "string" &&
147
+ obj.repoFullName.length > 0 &&
148
+ typeof obj.repoUrl === "string" &&
149
+ obj.repoUrl.length > 0 &&
150
+ typeof obj.createdAt === "string" &&
151
+ typeof obj.lastOpenedAt === "string"
152
+ )
153
+ }
154
+
155
+ /**
156
+ * Check if a project config file exists
157
+ *
158
+ * @param projectRoot - Absolute path to the project root
159
+ */
160
+ export async function projectConfigExists(projectRoot: string): Promise<boolean> {
161
+ const configPath = getProjectConfigPath(projectRoot)
162
+ const file = Bun.file(configPath)
163
+ return file.exists()
164
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/tsconfig",
3
+ "extends": "@tsconfig/bun/tsconfig.json",
4
+ "compilerOptions": {
5
+ "jsx": "preserve",
6
+ "jsxImportSource": "@opentui/solid",
7
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
8
+ "module": "ESNext",
9
+ "target": "ESNext",
10
+ "strict": true,
11
+ "noUncheckedIndexedAccess": true,
12
+ "noFallthroughCasesInSwitch": true,
13
+ "noImplicitOverride": true,
14
+ "skipLibCheck": true,
15
+ "paths": {
16
+ "@/*": ["./src/*"]
17
+ },
18
+ "baseUrl": "."
19
+ },
20
+ "include": ["src/**/*"],
21
+ "exclude": ["node_modules", "dist"]
22
+ }