claude-devloop 1.0.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 (90) hide show
  1. package/README.md +340 -0
  2. package/dist/cli.d.ts +4 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +90 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/config.d.ts +9 -0
  7. package/dist/commands/config.d.ts.map +1 -0
  8. package/dist/commands/config.js +80 -0
  9. package/dist/commands/config.js.map +1 -0
  10. package/dist/commands/continue.d.ts +11 -0
  11. package/dist/commands/continue.d.ts.map +1 -0
  12. package/dist/commands/continue.js +167 -0
  13. package/dist/commands/continue.js.map +1 -0
  14. package/dist/commands/feature.d.ts +7 -0
  15. package/dist/commands/feature.d.ts.map +1 -0
  16. package/dist/commands/feature.js +123 -0
  17. package/dist/commands/feature.js.map +1 -0
  18. package/dist/commands/init.d.ts +8 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/init.js +401 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/run.d.ts +12 -0
  23. package/dist/commands/run.d.ts.map +1 -0
  24. package/dist/commands/run.js +82 -0
  25. package/dist/commands/run.js.map +1 -0
  26. package/dist/commands/shared.d.ts +22 -0
  27. package/dist/commands/shared.d.ts.map +1 -0
  28. package/dist/commands/shared.js +32 -0
  29. package/dist/commands/shared.js.map +1 -0
  30. package/dist/commands/status.d.ts +8 -0
  31. package/dist/commands/status.d.ts.map +1 -0
  32. package/dist/commands/status.js +305 -0
  33. package/dist/commands/status.js.map +1 -0
  34. package/dist/commands/workspace.d.ts +2 -0
  35. package/dist/commands/workspace.d.ts.map +1 -0
  36. package/dist/commands/workspace.js +19 -0
  37. package/dist/commands/workspace.js.map +1 -0
  38. package/dist/constants.d.ts +21 -0
  39. package/dist/constants.d.ts.map +1 -0
  40. package/dist/constants.js +21 -0
  41. package/dist/constants.js.map +1 -0
  42. package/dist/core/claude.d.ts +20 -0
  43. package/dist/core/claude.d.ts.map +1 -0
  44. package/dist/core/claude.js +401 -0
  45. package/dist/core/claude.js.map +1 -0
  46. package/dist/core/commit-format.d.ts +22 -0
  47. package/dist/core/commit-format.d.ts.map +1 -0
  48. package/dist/core/commit-format.js +148 -0
  49. package/dist/core/commit-format.js.map +1 -0
  50. package/dist/core/config.d.ts +30 -0
  51. package/dist/core/config.d.ts.map +1 -0
  52. package/dist/core/config.js +130 -0
  53. package/dist/core/config.js.map +1 -0
  54. package/dist/core/feature-session.d.ts +8 -0
  55. package/dist/core/feature-session.d.ts.map +1 -0
  56. package/dist/core/feature-session.js +58 -0
  57. package/dist/core/feature-session.js.map +1 -0
  58. package/dist/core/git.d.ts +81 -0
  59. package/dist/core/git.d.ts.map +1 -0
  60. package/dist/core/git.js +475 -0
  61. package/dist/core/git.js.map +1 -0
  62. package/dist/core/loop.d.ts +3 -0
  63. package/dist/core/loop.d.ts.map +1 -0
  64. package/dist/core/loop.js +469 -0
  65. package/dist/core/loop.js.map +1 -0
  66. package/dist/core/session.d.ts +7 -0
  67. package/dist/core/session.d.ts.map +1 -0
  68. package/dist/core/session.js +57 -0
  69. package/dist/core/session.js.map +1 -0
  70. package/dist/index.d.ts +3 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +4 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/parser/progress.d.ts +7 -0
  75. package/dist/parser/progress.d.ts.map +1 -0
  76. package/dist/parser/progress.js +132 -0
  77. package/dist/parser/progress.js.map +1 -0
  78. package/dist/parser/requirements.d.ts +6 -0
  79. package/dist/parser/requirements.d.ts.map +1 -0
  80. package/dist/parser/requirements.js +126 -0
  81. package/dist/parser/requirements.js.map +1 -0
  82. package/dist/types/feature.d.ts +15 -0
  83. package/dist/types/feature.d.ts.map +1 -0
  84. package/dist/types/feature.js +2 -0
  85. package/dist/types/feature.js.map +1 -0
  86. package/dist/types/index.d.ts +78 -0
  87. package/dist/types/index.d.ts.map +1 -0
  88. package/dist/types/index.js +3 -0
  89. package/dist/types/index.js.map +1 -0
  90. package/package.json +40 -0
@@ -0,0 +1,130 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ const CONFIG_DIR = path.join(os.homedir(), '.devloop');
5
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
6
+ const DEFAULT_CONFIG = {
7
+ defaultWorkspace: null,
8
+ maxIterations: 10
9
+ };
10
+ export async function ensureConfigDir() {
11
+ try {
12
+ await fs.mkdir(CONFIG_DIR, { recursive: true });
13
+ }
14
+ catch {
15
+ // Directory already exists
16
+ }
17
+ }
18
+ export async function readGlobalConfig() {
19
+ try {
20
+ const content = await fs.readFile(CONFIG_FILE, 'utf-8');
21
+ return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
22
+ }
23
+ catch {
24
+ return DEFAULT_CONFIG;
25
+ }
26
+ }
27
+ export async function writeGlobalConfig(config) {
28
+ await ensureConfigDir();
29
+ await fs.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
30
+ }
31
+ export async function getDefaultWorkspace() {
32
+ const config = await readGlobalConfig();
33
+ return config.defaultWorkspace;
34
+ }
35
+ export async function setDefaultWorkspace(workspacePath) {
36
+ const config = await readGlobalConfig();
37
+ config.defaultWorkspace = path.resolve(workspacePath);
38
+ await writeGlobalConfig(config);
39
+ }
40
+ export async function resolveWorkspace(cliWorkspace) {
41
+ // Priority: CLI flag > config default > current directory
42
+ if (cliWorkspace) {
43
+ return path.resolve(cliWorkspace);
44
+ }
45
+ const defaultWorkspace = await getDefaultWorkspace();
46
+ if (defaultWorkspace) {
47
+ return defaultWorkspace;
48
+ }
49
+ return process.cwd();
50
+ }
51
+ export function getRequirementsPath(workspace) {
52
+ return path.join(workspace, 'requirements.md');
53
+ }
54
+ export function getProgressPath(workspace) {
55
+ return path.join(workspace, 'progress.md');
56
+ }
57
+ export function getSessionPath(workspace) {
58
+ return path.join(workspace, '.devloop', 'session.json');
59
+ }
60
+ /**
61
+ * Validates a feature name to ensure it's a safe filename
62
+ * @throws Error if feature name is invalid
63
+ */
64
+ export function validateFeatureName(feature) {
65
+ // Must be alphanumeric with hyphens or underscores
66
+ if (!/^[a-zA-Z0-9_-]+$/.test(feature)) {
67
+ throw new Error(`Invalid feature name: "${feature}"\n` +
68
+ 'Feature names must be alphanumeric with hyphens or underscores only.\n' +
69
+ 'Example: my-feature or my_feature');
70
+ }
71
+ // Prevent path traversal
72
+ if (feature.includes('..') || feature.includes('/') || feature.includes('\\')) {
73
+ throw new Error(`Invalid feature name: "${feature}" (path traversal not allowed)`);
74
+ }
75
+ }
76
+ /**
77
+ * Resolves feature input to normalized paths
78
+ * Handles both short form (auth) and explicit paths (requirements/auth.md)
79
+ */
80
+ export function resolveFeaturePath(workspace, featureInput) {
81
+ let featureName;
82
+ // Handle explicit path format (requirements/auth.md)
83
+ if (featureInput.includes('/') || featureInput.includes('\\')) {
84
+ const normalized = featureInput.replace(/\\/g, '/');
85
+ const match = normalized.match(/^requirements\/([^/]+)\.md$/);
86
+ if (!match) {
87
+ throw new Error(`Invalid feature path: "${featureInput}"\n` +
88
+ 'Feature paths must be in format: requirements/<name>.md\n' +
89
+ 'Or use short form: <name>');
90
+ }
91
+ featureName = match[1];
92
+ }
93
+ else {
94
+ // Remove .md extension if provided
95
+ featureName = featureInput.replace(/\.md$/, '');
96
+ }
97
+ validateFeatureName(featureName);
98
+ return {
99
+ featureName,
100
+ requirementsPath: getFeatureRequirementsPath(workspace, featureName),
101
+ progressPath: getFeatureProgressPath(workspace, featureName)
102
+ };
103
+ }
104
+ export function getFeatureRequirementsPath(workspace, feature) {
105
+ return path.join(workspace, 'requirements', `${feature}.md`);
106
+ }
107
+ export function getFeatureProgressPath(workspace, feature) {
108
+ return path.join(workspace, 'progress', `${feature}.md`);
109
+ }
110
+ export function getWorkspaceConfigPath(workspace) {
111
+ return path.join(workspace, '.devloop', 'config.json');
112
+ }
113
+ export async function readWorkspaceConfig(workspace) {
114
+ try {
115
+ const configPath = getWorkspaceConfigPath(workspace);
116
+ const content = await fs.readFile(configPath, 'utf-8');
117
+ return JSON.parse(content);
118
+ }
119
+ catch {
120
+ return {};
121
+ }
122
+ }
123
+ export async function writeWorkspaceConfig(workspace, config) {
124
+ const configPath = getWorkspaceConfigPath(workspace);
125
+ const devloopDir = path.dirname(configPath);
126
+ // Ensure .devloop directory exists
127
+ await fs.mkdir(devloopDir, { recursive: true });
128
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
129
+ }
130
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { FeatureSession } from '../types/feature.js';
2
+ import { SessionPhase } from '../types/index.js';
3
+ export declare function readFeatureSession(workspace: string, feature: string): Promise<FeatureSession | null>;
4
+ export declare function writeFeatureSession(workspace: string, session: FeatureSession): Promise<void>;
5
+ export declare function createFeatureSession(workspace: string, feature: string, phase: SessionPhase): Promise<FeatureSession>;
6
+ export declare function updateFeatureSessionIteration(workspace: string, feature: string, iteration: number): Promise<void>;
7
+ export declare function listFeatures(workspace: string): Promise<string[]>;
8
+ //# sourceMappingURL=feature-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-session.d.ts","sourceRoot":"","sources":["../../src/core/feature-session.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOjD,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQ3G;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnG;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,cAAc,CAAC,CAazB;AAED,wBAAsB,6BAA6B,CACjD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAYvE"}
@@ -0,0 +1,58 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import { getFeatureRequirementsPath, getFeatureProgressPath } from './config.js';
4
+ function getFeatureSessionPath(workspace, feature) {
5
+ return path.join(workspace, '.devloop', 'features', `${feature}.json`);
6
+ }
7
+ export async function readFeatureSession(workspace, feature) {
8
+ try {
9
+ const sessionPath = getFeatureSessionPath(workspace, feature);
10
+ const content = await fs.readFile(sessionPath, 'utf-8');
11
+ return JSON.parse(content);
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ export async function writeFeatureSession(workspace, session) {
18
+ const sessionPath = getFeatureSessionPath(workspace, session.feature);
19
+ const sessionDir = path.dirname(sessionPath);
20
+ // Ensure .devloop/features directory exists
21
+ await fs.mkdir(sessionDir, { recursive: true });
22
+ await fs.writeFile(sessionPath, JSON.stringify(session, null, 2), 'utf-8');
23
+ }
24
+ export async function createFeatureSession(workspace, feature, phase) {
25
+ const session = {
26
+ feature,
27
+ phase,
28
+ sessionId: null,
29
+ lastIteration: 0,
30
+ startedAt: new Date().toISOString(),
31
+ requirementsPath: getFeatureRequirementsPath(workspace, feature),
32
+ progressPath: getFeatureProgressPath(workspace, feature)
33
+ };
34
+ await writeFeatureSession(workspace, session);
35
+ return session;
36
+ }
37
+ export async function updateFeatureSessionIteration(workspace, feature, iteration) {
38
+ const session = await readFeatureSession(workspace, feature);
39
+ if (!session) {
40
+ throw new Error(`Feature session not found: ${feature}`);
41
+ }
42
+ session.lastIteration = iteration;
43
+ await writeFeatureSession(workspace, session);
44
+ }
45
+ export async function listFeatures(workspace) {
46
+ const requirementsDir = path.join(workspace, 'requirements');
47
+ try {
48
+ const files = await fs.readdir(requirementsDir);
49
+ return files
50
+ .filter(file => file.endsWith('.md'))
51
+ .map(file => file.replace(/\.md$/, ''))
52
+ .sort();
53
+ }
54
+ catch {
55
+ return [];
56
+ }
57
+ }
58
+ //# sourceMappingURL=feature-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-session.js","sourceRoot":"","sources":["../../src/core/feature-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Format a DevLoop internal commit message using the configured format
3
+ * @param action - What DevLoop is doing (e.g., "Initialize workspace", "Start run")
4
+ */
5
+ export declare function formatDevloopCommit(format: string | undefined, action: string): string;
6
+ /**
7
+ * Get the DevLoop commit message for an action, using workspace config if available
8
+ */
9
+ export declare function getDevloopCommitMessage(workspace: string, action: string): Promise<string>;
10
+ /**
11
+ * Save a DevLoop commit format to workspace config, extracting {action} placeholder if possible
12
+ */
13
+ export declare function saveDevloopCommitFormat(workspace: string, userMessage: string, defaultAction: string): Promise<void>;
14
+ /**
15
+ * Check if git is available on the system
16
+ */
17
+ export declare function isGitAvailable(): Promise<boolean>;
18
+ /**
19
+ * Check if the workspace is inside a git repository
20
+ * Uses git rev-parse to properly detect repos (handles nested dirs, submodules, etc.)
21
+ */
22
+ export declare function isGitRepo(workspace: string): Promise<boolean>;
23
+ /**
24
+ * Get the root directory of the git repository containing the workspace
25
+ */
26
+ export declare function getGitRoot(workspace: string): Promise<string | null>;
27
+ /**
28
+ * Initialize a new git repository in the workspace
29
+ */
30
+ export declare function initGitRepo(workspace: string): Promise<boolean>;
31
+ /**
32
+ * Ensure .gitignore exists with sensible defaults.
33
+ * If .gitignore doesn't exist, creates one.
34
+ * If it exists but is missing critical patterns, appends them.
35
+ * Creates .gitignore at the git root, not necessarily the workspace.
36
+ */
37
+ export declare function ensureGitignore(workspace: string, verbose?: boolean): Promise<boolean>;
38
+ /**
39
+ * Stage all changes and commit with the given message
40
+ * Returns true if commit was made, false if nothing to commit or error
41
+ */
42
+ export declare function gitCommit(workspace: string, message: string, verbose?: boolean): Promise<{
43
+ committed: boolean;
44
+ error?: string;
45
+ isHookFailure?: boolean;
46
+ }>;
47
+ /**
48
+ * Ensure the workspace has a git repository.
49
+ * If git is available and no repo exists, initialize one and commit initial files.
50
+ * Returns info about what was done.
51
+ */
52
+ export declare function ensureGitRepo(workspace: string, verbose?: boolean): Promise<{
53
+ gitAvailable: boolean;
54
+ wasInitialized: boolean;
55
+ initialCommit: boolean;
56
+ }>;
57
+ /**
58
+ * Check if there are uncommitted changes in the workspace
59
+ * Returns the list of changed files if any
60
+ */
61
+ export declare function getUncommittedChanges(workspace: string, ignorePaths?: string[]): Promise<{
62
+ hasChanges: boolean;
63
+ files: string[];
64
+ }>;
65
+ /**
66
+ * Get a diff summary of uncommitted changes
67
+ */
68
+ export declare function getUncommittedDiff(workspace: string): Promise<string | null>;
69
+ /**
70
+ * Commit uncommitted changes from a previous interrupted session
71
+ * This preserves the partial work in git history before starting fresh
72
+ */
73
+ export declare function commitInterruptedWork(workspace: string, taskId?: string, taskTitle?: string, verbose?: boolean): Promise<boolean>;
74
+ /**
75
+ * Commit changes after an iteration
76
+ */
77
+ export declare function commitIteration(workspace: string, iteration: number, taskId: string | null, taskTitle: string | null, success: boolean, verbose?: boolean, featureName?: string): Promise<{
78
+ committed: boolean;
79
+ hookFailure?: boolean;
80
+ }>;
81
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/core/git.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKtF;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhG;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB1H;AAqCD;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAGvD;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGnE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAM1E;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGrE;AAgDD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAoDnG;AAmCD;;;GAGG;AACH,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAoDtK;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe,GAAG,OAAO,CAAC;IACxF,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAuDD;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAiCxI;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBlF;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,OAAe,GACvB,OAAO,CAAC,OAAO,CAAC,CAkClB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,OAAe,EACxB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAmCxD"}