flowcat 1.3.0 → 1.4.4
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/core/addTask.ts +121 -0
- package/core/aliasReconcile.ts +41 -0
- package/core/aliasRepo.ts +92 -0
- package/core/autoCommit.ts +84 -0
- package/core/commitMessage.ts +95 -0
- package/core/config.ts +110 -0
- package/core/constants.ts +8 -0
- package/core/dayAssignments.ts +198 -0
- package/core/edit.ts +59 -0
- package/core/format.ts +63 -0
- package/core/fsm.ts +28 -0
- package/core/git.ts +117 -0
- package/core/gitignore.ts +30 -0
- package/core/id.ts +41 -0
- package/core/json.ts +13 -0
- package/core/lock.ts +31 -0
- package/core/plugin.ts +99 -0
- package/core/pluginErrors.ts +26 -0
- package/core/pluginLoader.ts +222 -0
- package/core/pluginManager.ts +75 -0
- package/core/pluginRunner.ts +217 -0
- package/core/pr.ts +89 -0
- package/core/prWorkflow.ts +185 -0
- package/core/schemas/dayAssignment.ts +11 -0
- package/core/schemas/logEntry.ts +11 -0
- package/core/schemas/pr.ts +29 -0
- package/core/schemas/task.ts +41 -0
- package/core/search.ts +25 -0
- package/core/taskFactory.ts +29 -0
- package/core/taskOperations.ts +104 -0
- package/core/taskRepo.ts +109 -0
- package/core/taskResolver.ts +44 -0
- package/core/taskStore.ts +14 -0
- package/core/time.ts +63 -0
- package/core/types.ts +7 -0
- package/core/workspace.ts +133 -0
- package/dist/index.mjs +5219 -2722
- package/package.json +23 -7
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { access, mkdir } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { configFileExists, resolveGlobalConfigPath, resolveWorkspaceConfigPath } from "./config";
|
|
6
|
+
import { APP_DIR, APP_NAME, LOCK_DIR, PLUGINS_DIR, STATUS_ORDER, TASKS_DIR } from "./constants";
|
|
7
|
+
import { writeJsonAtomic } from "./json";
|
|
8
|
+
|
|
9
|
+
export type WorkspaceKind = "explicit" | "global" | "repo";
|
|
10
|
+
|
|
11
|
+
export type Workspace = {
|
|
12
|
+
root: string;
|
|
13
|
+
kind: WorkspaceKind;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const exists = async (filePath: string): Promise<boolean> => {
|
|
17
|
+
try {
|
|
18
|
+
await access(filePath);
|
|
19
|
+
return true;
|
|
20
|
+
} catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const findGitRoot = async (startDir: string): Promise<string | null> => {
|
|
26
|
+
let current = path.resolve(startDir);
|
|
27
|
+
|
|
28
|
+
while (true) {
|
|
29
|
+
if (await exists(path.join(current, ".git"))) {
|
|
30
|
+
return current;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const parent = path.dirname(current);
|
|
34
|
+
if (parent === current) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
current = parent;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const resolveGlobalWorkspaceRoot = (): string => {
|
|
43
|
+
const dataHome = process.env.XDG_DATA_HOME ?? path.join(homedir(), ".local", "share");
|
|
44
|
+
return path.join(dataHome, APP_NAME);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type WorkspaceOptions = {
|
|
48
|
+
store?: string;
|
|
49
|
+
global?: boolean;
|
|
50
|
+
repo?: boolean;
|
|
51
|
+
cwd?: string;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const resolveWorkspace = async (options: WorkspaceOptions): Promise<Workspace> => {
|
|
55
|
+
if (options.store) {
|
|
56
|
+
return { root: path.resolve(options.store), kind: "explicit" };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const cwd = options.cwd ?? process.cwd();
|
|
60
|
+
const repoRoot = await findGitRoot(cwd);
|
|
61
|
+
|
|
62
|
+
if (options.repo) {
|
|
63
|
+
if (!repoRoot) {
|
|
64
|
+
throw new Error("Not inside a git repository");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { root: path.join(repoRoot, APP_DIR), kind: "repo" };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (options.global) {
|
|
71
|
+
return { root: resolveGlobalWorkspaceRoot(), kind: "global" };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (repoRoot) {
|
|
75
|
+
const repoWorkspace = path.join(repoRoot, APP_DIR);
|
|
76
|
+
if (await exists(repoWorkspace)) {
|
|
77
|
+
return { root: repoWorkspace, kind: "repo" };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { root: resolveGlobalWorkspaceRoot(), kind: "global" };
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const isWorkspaceInitialized = async (workspace: Workspace): Promise<boolean> => {
|
|
85
|
+
const tasksPath = path.join(workspace.root, TASKS_DIR);
|
|
86
|
+
const hasTasksDir = await exists(tasksPath);
|
|
87
|
+
if (!hasTasksDir) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const configPath =
|
|
92
|
+
workspace.kind === "global"
|
|
93
|
+
? resolveGlobalConfigPath()
|
|
94
|
+
: resolveWorkspaceConfigPath(workspace.root);
|
|
95
|
+
return configFileExists(configPath);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const ensureWorkspaceLayout = async (workspaceRoot: string): Promise<void> => {
|
|
99
|
+
await mkdir(path.join(workspaceRoot, TASKS_DIR), { recursive: true });
|
|
100
|
+
await mkdir(path.join(workspaceRoot, LOCK_DIR), { recursive: true });
|
|
101
|
+
await mkdir(path.join(workspaceRoot, PLUGINS_DIR), { recursive: true });
|
|
102
|
+
|
|
103
|
+
await Promise.all(
|
|
104
|
+
STATUS_ORDER.map((status) =>
|
|
105
|
+
mkdir(path.join(workspaceRoot, TASKS_DIR, status), { recursive: true }),
|
|
106
|
+
),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
// Create plugins/package.json if it doesn't exist
|
|
110
|
+
await ensurePluginsPackageJson(workspaceRoot);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Ensure plugins directory has a package.json for TypeScript plugin development
|
|
115
|
+
*/
|
|
116
|
+
export const ensurePluginsPackageJson = async (workspaceRoot: string): Promise<void> => {
|
|
117
|
+
const packageJsonPath = path.join(workspaceRoot, PLUGINS_DIR, "package.json");
|
|
118
|
+
|
|
119
|
+
if (await exists(packageJsonPath)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const packageJson = {
|
|
124
|
+
name: "flowcat-plugins",
|
|
125
|
+
type: "module",
|
|
126
|
+
private: true,
|
|
127
|
+
dependencies: {
|
|
128
|
+
flowcat: "^1.4.0",
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
await writeJsonAtomic(packageJsonPath, packageJson);
|
|
133
|
+
};
|