@speclife/core 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 (69) hide show
  1. package/dist/adapters/claude-cli-adapter.d.ts +57 -0
  2. package/dist/adapters/claude-cli-adapter.d.ts.map +1 -0
  3. package/dist/adapters/claude-cli-adapter.js +161 -0
  4. package/dist/adapters/claude-cli-adapter.js.map +1 -0
  5. package/dist/adapters/claude-sdk-adapter.d.ts +49 -0
  6. package/dist/adapters/claude-sdk-adapter.d.ts.map +1 -0
  7. package/dist/adapters/claude-sdk-adapter.js +278 -0
  8. package/dist/adapters/claude-sdk-adapter.js.map +1 -0
  9. package/dist/adapters/cursor-adapter.d.ts +26 -0
  10. package/dist/adapters/cursor-adapter.d.ts.map +1 -0
  11. package/dist/adapters/cursor-adapter.js +54 -0
  12. package/dist/adapters/cursor-adapter.js.map +1 -0
  13. package/dist/adapters/environment-adapter.d.ts +153 -0
  14. package/dist/adapters/environment-adapter.d.ts.map +1 -0
  15. package/dist/adapters/environment-adapter.js +690 -0
  16. package/dist/adapters/environment-adapter.js.map +1 -0
  17. package/dist/adapters/git-adapter.d.ts +41 -0
  18. package/dist/adapters/git-adapter.d.ts.map +1 -0
  19. package/dist/adapters/git-adapter.js +95 -0
  20. package/dist/adapters/git-adapter.js.map +1 -0
  21. package/dist/adapters/github-adapter.d.ts +39 -0
  22. package/dist/adapters/github-adapter.d.ts.map +1 -0
  23. package/dist/adapters/github-adapter.js +129 -0
  24. package/dist/adapters/github-adapter.js.map +1 -0
  25. package/dist/adapters/index.d.ts +11 -0
  26. package/dist/adapters/index.d.ts.map +1 -0
  27. package/dist/adapters/index.js +13 -0
  28. package/dist/adapters/index.js.map +1 -0
  29. package/dist/adapters/openspec-adapter.d.ts +36 -0
  30. package/dist/adapters/openspec-adapter.d.ts.map +1 -0
  31. package/dist/adapters/openspec-adapter.js +182 -0
  32. package/dist/adapters/openspec-adapter.js.map +1 -0
  33. package/dist/config.d.ts +60 -0
  34. package/dist/config.d.ts.map +1 -0
  35. package/dist/config.js +112 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/index.d.ts +10 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +14 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/types.d.ts +105 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +28 -0
  44. package/dist/types.js.map +1 -0
  45. package/dist/workflows/implement.d.ts +28 -0
  46. package/dist/workflows/implement.d.ts.map +1 -0
  47. package/dist/workflows/implement.js +277 -0
  48. package/dist/workflows/implement.js.map +1 -0
  49. package/dist/workflows/index.d.ts +9 -0
  50. package/dist/workflows/index.d.ts.map +1 -0
  51. package/dist/workflows/index.js +9 -0
  52. package/dist/workflows/index.js.map +1 -0
  53. package/dist/workflows/init.d.ts +55 -0
  54. package/dist/workflows/init.d.ts.map +1 -0
  55. package/dist/workflows/init.js +195 -0
  56. package/dist/workflows/init.js.map +1 -0
  57. package/dist/workflows/merge.d.ts +40 -0
  58. package/dist/workflows/merge.d.ts.map +1 -0
  59. package/dist/workflows/merge.js +90 -0
  60. package/dist/workflows/merge.js.map +1 -0
  61. package/dist/workflows/status.d.ts +34 -0
  62. package/dist/workflows/status.d.ts.map +1 -0
  63. package/dist/workflows/status.js +53 -0
  64. package/dist/workflows/status.js.map +1 -0
  65. package/dist/workflows/submit.d.ts +44 -0
  66. package/dist/workflows/submit.d.ts.map +1 -0
  67. package/dist/workflows/submit.js +143 -0
  68. package/dist/workflows/submit.js.map +1 -0
  69. package/package.json +48 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Submit workflow - commit, push, create PR, and archive change
3
+ */
4
+ import { SpecLifeError, ErrorCodes } from '../types.js';
5
+ /**
6
+ * Submit a change: commit, push, create PR, archive
7
+ */
8
+ export async function submitWorkflow(options, deps, onProgress) {
9
+ const { changeId, draft = false, commitMessage, skipArchive = false } = options;
10
+ const { git, github, openspec, config } = deps;
11
+ const branch = `spec/${changeId}`;
12
+ // Verify we're on the right branch
13
+ const currentBranch = await git.getCurrentBranch();
14
+ if (currentBranch !== branch) {
15
+ throw new SpecLifeError(ErrorCodes.CONFIG_INVALID, `Must be on branch '${branch}' to submit. Currently on '${currentBranch}'`, { expected: branch, actual: currentBranch });
16
+ }
17
+ // Check if change exists
18
+ if (!await openspec.changeExists(changeId)) {
19
+ throw new SpecLifeError(ErrorCodes.CHANGE_NOT_FOUND, `Change '${changeId}' not found`, { changeId });
20
+ }
21
+ // Get git status
22
+ const status = await git.status();
23
+ const hasChanges = status.staged.length > 0 ||
24
+ status.unstaged.length > 0 ||
25
+ status.untracked.length > 0;
26
+ // Read change for PR body
27
+ const change = await openspec.readChange(changeId);
28
+ // Generate commit message from proposal if not provided
29
+ const message = commitMessage ?? generateCommitMessage(changeId, change.proposal.why);
30
+ let commitSha = '';
31
+ if (hasChanges) {
32
+ // Stage all changes
33
+ onProgress?.({ type: 'step_completed', message: 'Staging changes' });
34
+ await git.add(['.']);
35
+ // Commit
36
+ onProgress?.({ type: 'step_completed', message: `Committing: ${message}` });
37
+ commitSha = await git.commit(message);
38
+ }
39
+ else {
40
+ // Get the current commit SHA even if no new changes
41
+ const headStatus = await git.status();
42
+ commitSha = headStatus.current ?? 'HEAD';
43
+ }
44
+ // Push to remote
45
+ onProgress?.({ type: 'step_completed', message: `Pushing to origin/${branch}` });
46
+ await git.push('origin', branch);
47
+ // Check if PR already exists
48
+ let pullRequest = await github.getPullRequestByBranch(branch);
49
+ let prCreated = false;
50
+ let prMarkedReady = false;
51
+ if (!pullRequest) {
52
+ // Create PR
53
+ onProgress?.({ type: 'step_completed', message: 'Creating pull request' });
54
+ const prBody = generatePRBody(change);
55
+ pullRequest = await github.createPullRequest({
56
+ title: generatePRTitle(changeId, change.proposal.why),
57
+ body: prBody,
58
+ head: branch,
59
+ base: config.github.baseBranch,
60
+ draft,
61
+ });
62
+ prCreated = true;
63
+ }
64
+ else {
65
+ onProgress?.({ type: 'step_completed', message: `PR #${pullRequest.number} already exists` });
66
+ // If the existing PR is a draft and we're not creating as draft, mark it ready
67
+ if (pullRequest.draft && !draft) {
68
+ onProgress?.({ type: 'step_completed', message: `Marking PR #${pullRequest.number} ready for review` });
69
+ pullRequest = await github.markPullRequestReady(pullRequest.number);
70
+ prMarkedReady = true;
71
+ }
72
+ }
73
+ // Archive the change
74
+ let archived = false;
75
+ if (!skipArchive) {
76
+ onProgress?.({ type: 'step_completed', message: 'Archiving change' });
77
+ await openspec.archiveChange(changeId);
78
+ // Commit and push the archive
79
+ await git.add(['.']);
80
+ await git.commit(`chore: archive ${changeId} change`);
81
+ await git.push('origin', branch);
82
+ archived = true;
83
+ }
84
+ onProgress?.({ type: 'step_completed', message: 'Submit complete' });
85
+ return {
86
+ commitSha,
87
+ branch,
88
+ pullRequest,
89
+ prCreated,
90
+ prMarkedReady,
91
+ archived,
92
+ };
93
+ }
94
+ /**
95
+ * Generate a commit message from change ID and description
96
+ */
97
+ function generateCommitMessage(changeId, why) {
98
+ // Extract first line/sentence of the why
99
+ const firstLine = why.split('\n')[0].trim();
100
+ const summary = firstLine.length > 50
101
+ ? firstLine.slice(0, 47) + '...'
102
+ : firstLine;
103
+ // Determine conventional commit type from changeId
104
+ let type = 'feat';
105
+ if (changeId.startsWith('fix-'))
106
+ type = 'fix';
107
+ else if (changeId.startsWith('refactor-'))
108
+ type = 'refactor';
109
+ else if (changeId.startsWith('docs-'))
110
+ type = 'docs';
111
+ else if (changeId.startsWith('test-'))
112
+ type = 'test';
113
+ else if (changeId.startsWith('chore-'))
114
+ type = 'chore';
115
+ return `${type}: ${summary}`;
116
+ }
117
+ /**
118
+ * Generate PR title from change
119
+ */
120
+ function generatePRTitle(changeId, why) {
121
+ const firstLine = why.split('\n')[0].trim();
122
+ if (firstLine.length > 72) {
123
+ return firstLine.slice(0, 69) + '...';
124
+ }
125
+ return firstLine || changeId.replace(/-/g, ' ');
126
+ }
127
+ /**
128
+ * Generate PR body from change proposal
129
+ */
130
+ function generatePRBody(change) {
131
+ const lines = [
132
+ '## Why',
133
+ change.proposal.why,
134
+ '',
135
+ '## What Changes',
136
+ ];
137
+ for (const item of change.proposal.whatChanges) {
138
+ lines.push(`- ${item}`);
139
+ }
140
+ lines.push('', '---', '*Created with [SpecLife](https://github.com/malarbase/speclife)*');
141
+ return lines.join('\n');
142
+ }
143
+ //# sourceMappingURL=submit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submit.js","sourceRoot":"","sources":["../../src/workflows/submit.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@speclife/core",
3
+ "version": "0.1.0",
4
+ "description": "Core library for SpecLife - adapters and workflows",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./adapters": {
14
+ "types": "./dist/adapters/index.d.ts",
15
+ "import": "./dist/adapters/index.js"
16
+ },
17
+ "./workflows": {
18
+ "types": "./dist/workflows/index.d.ts",
19
+ "import": "./dist/workflows/index.js"
20
+ }
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "test": "vitest run --passWithNoTests",
25
+ "test:watch": "vitest",
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "dependencies": {
29
+ "@anthropic-ai/sdk": "^0.32.0",
30
+ "@octokit/rest": "^21.0.0",
31
+ "cosmiconfig": "^9.0.0",
32
+ "execa": "^9.0.0",
33
+ "simple-git": "^3.27.0",
34
+ "yaml": "^2.5.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^22.0.0",
38
+ "typescript": "^5.6.0",
39
+ "vitest": "^2.0.0"
40
+ },
41
+ "files": [
42
+ "dist"
43
+ ],
44
+ "publishConfig": {
45
+ "access": "public"
46
+ }
47
+ }
48
+